1 //----------------------------------------------------------------------------
2 // Anti-Grain Geometry - Version 2.4 (Public License)
3 // Copyright (C) 2002-2005 Maxim Shemanarev (http://www.antigrain.com)
4 //
5 // Anti-Grain Geometry - Version 2.4 Release Milano 3 (AggPas 2.4 RM3)
6 // Pascal Port By: Milan Marusinec alias Milano
7 //                 milan@marusinec.sk
8 //                 http://www.aggpas.org
9 // Copyright (c) 2005-2006
10 //
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.
15 //
16 //----------------------------------------------------------------------------
17 // Contact: mcseem@antigrain.com
18 //          mcseemagg@yahoo.com
19 //          http://www.antigrain.com
20 //
21 //----------------------------------------------------------------------------
22 //
23 // classes dda_line_interpolator, dda2_line_interpolator
24 //
25 // [Pascal Port History] -----------------------------------------------------
26 //
27 // 27.01.2006-Milano: dda_line_interpolator
28 // 16.01.2006-Milano: Unit port establishment
29 //
30 { agg_dda_line.pas }
31 unit
32  agg_dda_line ;
33 
34 INTERFACE
35 
36 {$I agg_mode.inc }
37 {$Q- }
38 {$R- }
39 uses
40  agg_basics ;
41 
42 { TYPES DEFINITION }
43 const
44  subpixel_shift = 8;
45  subpixel_size  = 1 shl subpixel_shift;
46  subpixel_mask  = subpixel_size - 1;
47 
48 type
49 //===================================================dda_line_interpolator
50  dda_line_interpolator = object
51    m_y ,m_inc ,m_dy ,
52 
53    FractionShift ,YShift : int;
54 
55    constructor Construct(FS : int; YS : int = 0 ); overload;
56    constructor Construct(y1 ,y2 : int; count : unsigned; FS : int; YS : int = 0 ); overload;
57 
58    procedure plus_operator;
59    procedure minus_operator;
60    procedure inc_operator(n : int );
61    procedure dec_operator(n : int );
62 
_ynull63    function  _y : int;
_dynull64    function  _dy : int;
65 
66   end;
67 
68 //---------------------------------------------line_bresenham_interpolator
69  dda2_line_interpolator = object
70    m_cnt ,
71    m_lft ,
72    m_rem ,
73    m_mod ,
74    m_y   : int;
75 
76    constructor Construct(y1 ,y2 ,count : int ); overload;  // Forward-adjusted line
77    constructor Construct(y ,count : int ); overload;       // Backward-adjusted line
78 
79    procedure plus_operator;
80    procedure minus_operator;
81 
_modnull82    function  _mod : int;
_remnull83    function  _rem : int;
_lftnull84    function  _lft : int;
_ynull85    function  _y : int;
86 
87    procedure adjust_forward;
88    procedure adjust_backward;
89 
90   end;
91 
92  line_bresenham_interpolator = object
93    m_x1_lr ,
94    m_y1_lr ,
95    m_x2_lr ,
96    m_y2_lr : int;
97 
98    m_ver : boolean;
99    m_len : unsigned;
100    m_inc : int;
101 
102    m_interpolator : dda2_line_interpolator;
103 
104    constructor Construct(x1 ,y1 ,x2 ,y2 : int );
105 
line_lrnull106    function  line_lr(v : int ) : int;
107 
_is_vernull108    function _is_ver : boolean;
_lennull109    function _len : unsigned;
_incnull110    function _inc : int;
111 
112    procedure hstep;
113    procedure vstep;
114 
_x1null115    function _x1 : int;
_y1null116    function _y1 : int;
_x2null117    function _x2 : int;
_y2null118    function _y2 : int;
_x2_hrnull119    function _x2_hr : int;
_y2_hrnull120    function _y2_hr : int;
121 
122   end;
123 
124 { GLOBAL PROCEDURES }
125 
126 
127 IMPLEMENTATION
128 { LOCAL VARIABLES & CONSTANTS }
129 { UNIT IMPLEMENTATION }
130 { CONSTRUCT }
131 constructor dda_line_interpolator.Construct(FS : int; YS : int = 0 );
132 begin
133  FractionShift:=FS;
134 
135  YShift:=YS;
136 
137 end;
138 
139 { CONSTRUCT }
140 constructor dda_line_interpolator.Construct(y1 ,y2 : int; count : unsigned; FS : int; YS : int = 0 );
141 begin
142  Construct(FS ,YS );
143 
144  m_y  :=y1;
145  m_inc:=((y2 - y1 ) shl FractionShift ) div count;
146  m_dy :=0;
147 
148 end;
149 
150 { PLUS_OPERATOR }
151 procedure dda_line_interpolator.plus_operator;
152 begin
153  inc(m_dy ,m_inc );
154 
155 end;
156 
157 { MINUS_OPERATOR }
158 procedure dda_line_interpolator.minus_operator;
159 begin
160  dec(m_dy ,m_inc );
161 
162 end;
163 
164 { INC_OPERATOR }
165 procedure dda_line_interpolator.inc_operator;
166 begin
167  inc(m_dy ,m_inc * n );
168 
169 end;
170 
171 { DEC_OPERATOR }
172 procedure dda_line_interpolator.dec_operator;
173 begin
174  dec(m_dy ,m_inc * n );
175 
176 end;
177 
178 { _Y }
dda_line_interpolator._ynull179 function dda_line_interpolator._y;
180 begin
181  result:=m_y + (shr_int32(m_dy ,FractionShift - YShift ) );
182 
183 end;
184 
185 { _DY }
dda_line_interpolator._dynull186 function dda_line_interpolator._dy;
187 begin
188  result:=m_dy;
189 
190 end;
191 
192 { CONSTRUCT }
193 constructor dda2_line_interpolator.Construct(y1 ,y2 ,count : int );
194 begin
195  if count <= 0 then
196   m_cnt:=1
197  else
198   m_cnt:=count;
199 
200  m_lft:=trunc((y2 - y1 ) / m_cnt );
201  m_rem:=trunc((y2 - y1 ) mod m_cnt );
202  m_mod:=m_rem;
203  m_y  :=y1;
204 
205  if m_mod <= 0 then
206   begin
207    m_mod:=m_mod + count;
208    m_rem:=m_rem + count;
209 
210    dec(m_lft );
211 
212   end;
213 
214  m_mod:=m_mod - count;
215 
216 end;
217 
218 { CONSTRUCT }
219 constructor dda2_line_interpolator.Construct(y ,count : int );
220 begin
221  if count <= 0 then
222   m_cnt:=1
223  else
224   m_cnt:=count;
225 
226  m_lft:=y div m_cnt;
227  m_rem:=y mod m_cnt;
228  m_mod:=m_rem;
229  m_y  :=0;
230 
231  if m_mod <= 0 then
232   begin
233    inc(m_mod ,count );
234    inc(m_rem ,count );
235    dec(m_lft );
236 
237   end;
238 
239 end;
240 
241 { PLUS_OPERATOR }
242 procedure dda2_line_interpolator.plus_operator;
243 begin
244  inc(m_mod ,m_rem );
245  inc(m_y ,m_lft );
246 
247  if m_mod > 0 then
248   begin
249    dec(m_mod ,m_cnt );
250    inc(m_y );
251 
252   end;
253 
254 end;
255 
256 { MINUS_OPERATOR }
257 procedure dda2_line_interpolator.minus_operator;
258 begin
259  if m_mod <= m_rem then
260   begin
261    inc(m_mod ,m_cnt );
262    dec(m_y );
263 
264   end;
265 
266  dec(m_mod ,m_rem );
267  dec(m_y ,m_lft );
268 
269 end;
270 
271 { _MOD }
dda2_line_interpolator._modnull272 function dda2_line_interpolator._mod;
273 begin
274  result:=m_mod;
275 
276 end;
277 
278 { _REM }
dda2_line_interpolator._remnull279 function dda2_line_interpolator._rem;
280 begin
281  result:=m_rem;
282 
283 end;
284 
285 { _LFT }
dda2_line_interpolator._lftnull286 function dda2_line_interpolator._lft;
287 begin
288  result:=m_lft;
289 
290 end;
291 
292 { _Y }
dda2_line_interpolator._ynull293 function dda2_line_interpolator._y;
294 begin
295  result:=m_y;
296 
297 end;
298 
299 { ADJUST_FORWARD }
300 procedure dda2_line_interpolator.adjust_forward;
301 begin
302  dec(m_mod ,m_cnt );
303 
304 end;
305 
306 { ADJUST_BACKWARD }
307 procedure dda2_line_interpolator.adjust_backward;
308 begin
309  inc(m_mod ,m_cnt );
310 
311 end;
312 
313 { CONSTRUCT }
314 constructor line_bresenham_interpolator.Construct;
315 begin
316  m_x1_lr:=line_lr(x1 );
317  m_y1_lr:=line_lr(y1 );
318  m_x2_lr:=line_lr(x2 );
319  m_y2_lr:=line_lr(y2 );
320 
321  m_ver:=Abs(m_x2_lr - m_x1_lr ) < Abs(m_y2_lr - m_y1_lr );
322 
323  if m_ver then
324   m_len:=Abs(m_y2_lr - m_y1_lr )
325  else
326   m_len:=Abs(m_x2_lr - m_x1_lr );
327 
328  if m_ver then
329   if y2 > y1 then
330    m_inc:=1
331   else
332    m_inc:=-1
333  else
334   if x2 > x1 then
335    m_inc:=1
336   else
337    m_inc:=-1;
338 
339  if m_ver then
340   m_interpolator.Construct(x1 ,x2 ,m_len )
341  else
342   m_interpolator.Construct(y1 ,y2 ,m_len );
343 
344 end;
345 
346 { LINE_LR }
line_bresenham_interpolator.line_lrnull347 function line_bresenham_interpolator.line_lr;
348 begin
349  result:=shr_int32(v ,subpixel_shift );
350 
351 end;
352 
353 { _IS_VER }
line_bresenham_interpolator._is_vernull354 function line_bresenham_interpolator._is_ver;
355 begin
356  result:=m_ver;
357 
358 end;
359 
360 { _LEN }
line_bresenham_interpolator._lennull361 function line_bresenham_interpolator._len;
362 begin
363  result:=m_len;
364 
365 end;
366 
367 { _INC }
line_bresenham_interpolator._incnull368 function line_bresenham_interpolator._inc;
369 begin
370  result:=m_inc;
371 
372 end;
373 
374 { HSTEP }
375 procedure line_bresenham_interpolator.hstep;
376 begin
377  m_interpolator.plus_operator;
378 
379  m_x1_lr:=m_x1_lr + m_inc;
380 
381 end;
382 
383 { VSTEP }
384 procedure line_bresenham_interpolator.vstep;
385 begin
386  m_interpolator.plus_operator;
387 
388  m_y1_lr:=m_y1_lr + m_inc;
389 
390 end;
391 
392 { _X1 }
line_bresenham_interpolator._x1null393 function line_bresenham_interpolator._x1;
394 begin
395  result:=m_x1_lr;
396 
397 end;
398 
399 { _Y1 }
line_bresenham_interpolator._y1null400 function line_bresenham_interpolator._y1;
401 begin
402  result:=m_y1_lr;
403 
404 end;
405 
406 { _X2 }
line_bresenham_interpolator._x2null407 function line_bresenham_interpolator._x2;
408 begin
409  result:=line_lr(m_interpolator._y );
410 
411 end;
412 
413 { _Y2 }
line_bresenham_interpolator._y2null414 function line_bresenham_interpolator._y2;
415 begin
416  result:=line_lr(m_interpolator._y );
417 
418 end;
419 
420 { _X2_HR }
line_bresenham_interpolator._x2_hrnull421 function line_bresenham_interpolator._x2_hr;
422 begin
423  result:=m_interpolator._y;
424 
425 end;
426 
427 { _Y2_HR }
line_bresenham_interpolator._y2_hrnull428 function line_bresenham_interpolator._y2_hr;
429 begin
430  result:=m_interpolator._y;
431 
432 end;
433 
434 END.
435 
436 
437