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
// [Pascal Port History] -----------------------------------------------------
23
// 31.10.2006-Milano: Unit port establishment
25
{ agg_line_aa_basics.pas }
38
line_subpixel_shift = 8; //----line_subpixel_shift
39
line_subpixel_size = 1 shl line_subpixel_shift; //----line_subpixel_size
40
line_subpixel_mask = line_subpixel_size - 1; //----line_subpixel_mask
42
line_mr_subpixel_shift = 4; //----line_mr_subpixel_shift
43
line_mr_subpixel_size = 1 shl line_mr_subpixel_shift; //----line_mr_subpixel_size
44
line_mr_subpixel_mask = line_mr_subpixel_size - 1; //----line_mr_subpixel_mask
47
line_parameters_ptr = ^line_parameters;
48
line_parameters = object
49
x1, y1, x2, y2, dx, dy, sx, sy : int;
53
inc_ ,len ,octant : int;
55
constructor Construct; overload;
56
constructor Construct(x1_ ,y1_ ,x2_ ,y2_ ,len_ : int ); overload;
58
function orthogonal_quadrant : unsigned;
59
function diagonal_quadrant : unsigned;
61
function same_orthogonal_quadrant(lp : line_parameters_ptr ) : boolean;
62
function same_diagonal_quadrant (lp : line_parameters_ptr ) : boolean;
67
function line_mr(x : int ) : int;
68
function line_hr(x : int ) : int;
70
function line_dbl_hr(x : int ) : int;
71
function line_coord (x : double ) : int;
73
procedure bisectrix(l1 ,l2 : line_parameters_ptr; x ,y : int_ptr );
75
procedure fix_degenerate_bisectrix_start(lp : line_parameters_ptr; x ,y : int_ptr );
76
procedure fix_degenerate_bisectrix_end (lp : line_parameters_ptr; x ,y : int_ptr );
80
{ LOCAL VARIABLES & CONSTANTS }
82
// The number of the octant is determined as a 3-bit value as follows:
83
// bit 0 = vertical flag
87
// [N] shows the number of the orthogonal quadrant
88
// <M> shows the number of the diagonal quadrant
91
// . (3)011 | 001(1) .
96
// <2> ----------.+.----------- <0>
97
// (6)110 . | . 100(4)
104
// 0 ,1 ,2 ,3 ,4 ,5 ,6 ,7
105
s_orthogonal_quadrant : array[0..7 ] of int8u = (0 ,0 ,1 ,1 ,3 ,3 ,2 ,2 );
106
s_diagonal_quadrant : array[0..7 ] of int8u = (0 ,1 ,2 ,1 ,0 ,3 ,2 ,3 );
108
{ UNIT IMPLEMENTATION }
110
constructor line_parameters.Construct;
115
constructor line_parameters.Construct(x1_ ,y1_ ,x2_ ,y2_ ,len_ : int );
143
octant:=(sy and 4 ) or (sx and 2 ) or int(vertical );
147
{ ORTHOGONAL_QUADRANT }
148
function line_parameters.orthogonal_quadrant;
150
result:=s_orthogonal_quadrant[octant ];
154
{ DIAGONAL_QUADRANT }
155
function line_parameters.diagonal_quadrant;
157
result:=s_diagonal_quadrant[octant ];
161
{ SAME_ORTHOGONAL_QUADRANT }
162
function line_parameters.same_orthogonal_quadrant;
164
result:=s_orthogonal_quadrant[octant ] = s_orthogonal_quadrant[lp.octant ];
168
{ SAME_DIAGONAL_QUADRANT }
169
function line_parameters.same_diagonal_quadrant;
171
result:=s_diagonal_quadrant[octant ] = s_diagonal_quadrant[lp.octant ];
178
result:=shr_int32(x ,line_subpixel_shift - line_mr_subpixel_shift );
185
result:=x shl (line_subpixel_shift - line_mr_subpixel_shift );
190
function line_dbl_hr;
192
result:=x shl line_subpixel_shift;
199
result:=trunc(x * line_subpixel_size );
206
k ,tx ,ty ,dx ,dy : double;
210
tx:=l2.x2 - (l2.x1 - l1.x1 ) * k;
211
ty:=l2.y2 - (l2.y1 - l1.y1 ) * k;
213
//All bisectrices must be on the right of the line
214
//If the next point is on the left (l1 => l2.2)
215
//then the bisectix should be rotated by 180 degrees.
216
if intdbl(l2.x2 - l2.x1 ) * intdbl(l2.y1 - l1.y1 ) <
217
intdbl(l2.y2 - l2.y1 ) * intdbl(l2.x1 - l1.x1 ) + 100.0 then
219
tx:=tx - ((tx - l2.x1 ) * 2.0 );
220
ty:=ty - ((ty - l2.y1 ) * 2.0 );
224
// Check if the bisectrix is too short
228
if trunc(Sqrt(dx * dx + dy * dy ) ) < line_subpixel_size then
230
x^:=shr_int32(l2.x1 + l2.x1 + (l2.y1 - l1.y1 ) + (l2.y2 - l2.y1 ) ,1 );
231
y^:=shr_int32(l2.y1 + l2.y1 - (l2.x1 - l1.x1 ) - (l2.x2 - l2.x1 ) ,1 );
242
{ FIX_DEGENERATE_BISECTRIX_START }
243
procedure fix_degenerate_bisectrix_start;
249
(intdbl(x^ - lp.x2 ) * intdbl(lp.y2 - lp.y1 ) -
250
intdbl(y^ - lp.y2 ) * intdbl(lp.x2 - lp.x1 ) ) / lp.len );
252
if d < line_subpixel_size then
254
x^:=lp.x1 + (lp.y2 - lp.y1 );
255
y^:=lp.y1 - (lp.x2 - lp.x1 );
261
{ FIX_DEGENERATE_BISECTRIX_END }
262
procedure fix_degenerate_bisectrix_end;
268
(intdbl(x^ - lp.x2 ) * intdbl(lp.y2 - lp.y1 ) -
269
intdbl(y^ - lp.y2 ) * intdbl(lp.x2 - lp.x1 ) ) / lp.len );
271
if d < line_subpixel_size then
273
x^:=lp.x2 + (lp.y2 - lp.y1 );
274
y^:=lp.y2 - (lp.x2 - lp.x1 );