1
//----------------------------------------------------------------------------
2
// Anti-Grain Geometry - Version 2.4 (Public License)
3
// Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
5
// Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
6
// Pascal Port By: Milan Marusinec alias Milano
8
// http://www.aggpas.org
9
// Copyright (c) 2005-2006
11
// Permission to copy, use, modify, sell and distribute this software
12
// is granted provided this copyright notice appears in all copies.
13
// This software is provided "as is" without express or implied
14
// warranty, and with no claim as to its suitability for any purpose.
16
//----------------------------------------------------------------------------
17
// Contact: mcseem@antigrain.com
18
// mcseemagg@yahoo.com
19
// http://www.antigrain.com
21
//----------------------------------------------------------------------------
23
// Viewport transformer - simple orthogonal conversions from world coordinates
24
// to screen (device) ones
26
// [Pascal Port History] -----------------------------------------------------
28
// 27.09.2005-Milano: Complete unit port
30
{ agg_trans_viewport.pas }
44
aspect_ratio_e = (aspect_ratio_stretch ,aspect_ratio_meet ,aspect_ratio_slice );
46
//----------------------------------------------------------trans_viewport
47
trans_viewport_ptr = ^trans_viewport;
48
trans_viewport = object(trans_affine )
59
m_aspect : aspect_ratio_e;
75
constructor Construct;
77
procedure preserve_aspect_ratio(alignx ,aligny : double; aspect : aspect_ratio_e );
79
procedure device_viewport (x1 ,y1 ,x2 ,y2 : double );
80
procedure device_viewport_ex(var x1 ,y1 ,x2 ,y2 : double );
82
procedure world_viewport (x1 ,y1 ,x2 ,y2 : double );
83
procedure world_viewport_ex(var x1 ,y1 ,x2 ,y2 : double );
85
procedure world_viewport_actual(var x1 ,y1 ,x2 ,y2 : double );
87
function is_valid : boolean;
88
function align_x : double;
89
function align_y : double;
90
function aspect_ratio : aspect_ratio_e;
92
procedure inverse_transform_scale_only(x ,y : double_ptr );
94
function device_dx : double;
95
function device_dy : double;
96
function scale_x : double;
97
function scale_y : double;
98
function scale : double;
100
procedure to_affine (mtx : trans_affine_ptr );
101
procedure to_affine_scale_only(mtx : trans_affine_ptr );
103
function byte_size : unsigned;
104
procedure serialize (ptr : int8u_ptr );
105
procedure deserialize(ptr : int8u_ptr);
111
{ GLOBAL VARIABLES & CONSTANTS }
112
{ GLOBAL PROCEDURES }
116
{ UNIT IMPLEMENTATION }
118
procedure _transform(this : trans_viewport_ptr; x ,y : double_ptr );
125
{ _inverse_transform }
126
procedure _inverse_transform(this : trans_viewport_ptr; x ,y : double_ptr );
128
x^:=(x^ - this.m_dx1 ) / this.m_kx + this.m_wx1;
129
y^:=(y^ - this.m_dy1 ) / this.m_ky + this.m_wy1;
134
constructor trans_viewport.Construct;
138
transform :=@_transform;
139
inverse_transform:=@_inverse_transform;
151
m_aspect :=aspect_ratio_stretch;
169
{ preserve_aspect_ratio }
170
procedure trans_viewport.preserve_aspect_ratio;
181
procedure trans_viewport.device_viewport;
192
{ device_viewport_ex }
193
procedure trans_viewport.device_viewport_ex;
203
procedure trans_viewport.world_viewport;
214
{ world_viewport_ex }
215
procedure trans_viewport.world_viewport_ex;
224
{ world_viewport_actual }
225
procedure trans_viewport.world_viewport_actual;
235
function trans_viewport.is_valid;
242
function trans_viewport.align_x;
249
function trans_viewport.align_y;
256
function trans_viewport.aspect_ratio;
262
{ inverse_transform_scale_only }
263
procedure trans_viewport.inverse_transform_scale_only;
271
function trans_viewport.device_dx;
273
result:=m_dx1 - m_wx1 * m_kx;
278
function trans_viewport.device_dy;
280
result:=m_dy1 - m_wy1 * m_ky;
285
function trans_viewport.scale_x;
292
function trans_viewport.scale_y;
299
function trans_viewport.scale;
301
result:=(m_kx + m_ky ) * 0.5;
306
procedure trans_viewport.to_affine;
309
t : trans_affine_translation;
310
s : trans_affine_scaling;
313
m.Construct(-m_wx1 ,-m_wy1 );
314
s.Construct(m_kx ,m_ky );
316
t.Construct(m_dx1 ,m_dy1 );
323
{ to_affine_scale_only }
324
procedure trans_viewport.to_affine_scale_only;
326
s : trans_affine_scaling;
329
s.Construct(m_kx ,m_ky );
336
function trans_viewport.byte_size;
338
result:=sizeof(self );
343
procedure trans_viewport.serialize;
345
move(self ,ptr^ ,sizeof(self ) );
350
procedure trans_viewport.deserialize;
352
move(ptr^ ,self ,sizeof(self ) );
357
procedure trans_viewport.update;
359
epsilon : double = 1e-30;
375
if (Abs(m_world_x1 - m_world_x2 ) < epsilon ) or
376
(Abs(m_world_y1 - m_world_y2 ) < epsilon ) or
377
(Abs(m_device_x1 - m_device_x2 ) < epsilon ) or
378
(Abs(m_device_y1 - m_device_y2 ) < epsilon ) then
382
m_wx2:=m_world_x1 + 1;
383
m_wy2:=m_world_y2 + 1;
394
world_x1 :=m_world_x1;
395
world_y1 :=m_world_y1;
396
world_x2 :=m_world_x2;
397
world_y2 :=m_world_y2;
398
device_x1:=m_device_x1;
399
device_y1:=m_device_y1;
400
device_x2:=m_device_x2;
401
device_y2:=m_device_y2;
403
if not (m_aspect = aspect_ratio_stretch ) then
405
m_kx:=(device_x2 - device_x1 ) / (world_x2 - world_x1 );
406
m_ky:=(device_y2 - device_y1 ) / (world_y2 - world_y1 );
408
if (m_aspect = aspect_ratio_meet ) = (m_kx < m_ky ) then
410
d:=(world_y2 - world_y1 ) * m_ky / m_kx;
412
world_y1:=world_y1 + ((world_y2 - world_y1 - d ) * m_align_y );
413
world_y2:=world_y1 + d;
418
d:=(world_x2 - world_x1 ) * m_kx / m_ky;
420
world_x1:=world_x1 + ((world_x2 - world_x1 - d ) * m_align_x );
421
world_x2:=world_x1 + d;
433
m_kx :=(device_x2 - device_x1 ) / (world_x2 - world_x1 );
434
m_ky :=(device_y2 - device_y1 ) / (world_y2 - world_y1 );