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 // [Pascal Port History] -----------------------------------------------------
22 //
23 // 23.06.2006-Milano: ptrcomp adjustments
24 // 03.02.2006-Milano: Complete unit port
25 // 02.02.2006-Milano: Unit port establishment
26 //
27 { agg_renderer_outline_image.pas }
28 unit
29 agg_renderer_outline_image ;
30
31 INTERFACE
32
33 {$I agg_mode.inc }
34 {$Q- }
35 {$R- }
36
37 uses
38 Math ,
39 agg_basics ,
40 agg_color ,
41 agg_line_aa_basics ,
42 agg_dda_line ,
43 agg_rendering_buffer ,
44 agg_renderer_base ,
45 agg_renderer_outline_aa ,
46 agg_pattern_filters_rgba ;
47
48 { TYPES DEFINITION }
49 type
50 pixel_source_ptr = ^pixel_source;
51 pixel_source = object
_widthnull52 function _width : unsigned; virtual; abstract;
_heightnull53 function _height : unsigned; virtual; abstract;
54
_width_dnull55 function _width_d : double; virtual;
_height_dnull56 function _height_d : double; virtual;
57
pixelnull58 function pixel(x ,y : int ) : rgba8; virtual; abstract;
59
60 end;
61
62 line_image_scale = object(pixel_source )
63 m_source : pixel_source_ptr;
64 m_height ,
65 m_scale : double;
66
67 constructor Construct(src : pixel_source_ptr; height_ : double );
68
_width_dnull69 function _width_d : double; virtual;
_height_dnull70 function _height_d : double; virtual;
71
pixelnull72 function pixel(x ,y : int ) : rgba8; virtual;
73
74 end;
75
76 line_image_pattern_ptr = ^line_image_pattern;
77 line_image_pattern = object
78 m_buf : rendering_buffer;
79 m_filter : pattern_filter_ptr;
80
81 m_dilation : unsigned;
82 m_dilation_hr : int;
83
84 m_data : aggclr_ptr;
85 m_dt_sz ,
86 m_width ,
87 m_height : unsigned;
88
89 m_width_hr ,
90 m_half_height_hr ,
91 m_offset_y_hr : int;
92
93 constructor Construct(filter_ : pattern_filter_ptr ); overload;
94 constructor Construct(filter_ : pattern_filter_ptr; src : pixel_source_ptr ); overload;
95 destructor Destruct;
96
97 procedure create(src : pixel_source_ptr ); virtual;
98
pattern_widthnull99 function pattern_width : int;
line_widthnull100 function line_width : int;
101
102 procedure pixel(p : aggclr_ptr; x ,y : int ); virtual;
103
104 procedure filter(filter_ : pattern_filter_ptr ); overload;
filternull105 function filter : pattern_filter_ptr; overload;
106
107 end;
108
109 line_image_pattern_pow2 = object(line_image_pattern )
110 m_mask : unsigned;
111
112 constructor Construct(filter_ : pattern_filter_ptr ); overload;
113 constructor Construct(filter_ : pattern_filter_ptr; src : pixel_source_ptr ); overload;
114
115 procedure create(src : pixel_source_ptr ); virtual;
116 procedure pixel (p : aggclr_ptr; x ,y : int ); virtual;
117
118 end;
119
120 distance_interpolator4 = object(distance_interpolator )
121 m_dx ,
122 m_dy ,
123
124 m_dx_start ,
125 m_dy_start ,
126 m_dx_pict ,
127 m_dy_pict ,
128 m_dx_end ,
129 m_dy_end ,
130
131 m_dist ,
132 m_dist_start ,
133 m_dist_pict ,
134 m_dist_end ,
135
136 m_len : int;
137
138 constructor Construct; overload;
139 constructor Construct(x1 ,y1 ,x2 ,y2 ,sx ,sy ,ex ,ey ,len_ : int; scale : double; x ,y : int ); overload;
140
141 procedure inc_x_; virtual;
142 procedure dec_x_; virtual;
143 procedure inc_y_; virtual;
144 procedure dec_y_; virtual;
145
146 procedure inc_x(dy_ : int ); virtual;
147 procedure dec_x(dy_ : int ); virtual;
148 procedure inc_y(dx_ : int ); virtual;
149 procedure dec_y(dx_ : int ); virtual;
150
distnull151 function dist : int; virtual;
dist_startnull152 function dist_start : int; virtual;
dist_pictnull153 function dist_pict : int;
dist_endnull154 function dist_end : int; virtual;
155
dxnull156 function dx : int; virtual;
dynull157 function dy : int; virtual;
dx_startnull158 function dx_start : int; virtual;
dy_startnull159 function dy_start : int; virtual;
dx_pictnull160 function dx_pict : int;
dy_pictnull161 function dy_pict : int;
dx_endnull162 function dx_end : int; virtual;
dy_endnull163 function dy_end : int; virtual;
lennull164 function len : int;
165
166 end;
167
168 renderer_outline_image_ptr = ^renderer_outline_image;
169
170 line_interpolator_image = object //(line_interpolator )
171 m_lp : line_parameters_ptr;
172 m_li : dda2_line_interpolator;
173 m_di : distance_interpolator4;
174 m_ren : renderer_outline_image_ptr;
175
176 m_plen ,
177 m_x ,
178 m_y ,
179
180 m_old_x ,
181 m_old_y ,
182 m_count ,
183 m_width ,
184
185 m_max_extent ,
186
187 m_start ,
188 m_step : int;
189
190 m_dist_pos : array[0..max_half_width + 1 - 1 ] of int;
191 m_colors : array[0..max_half_width * 2 + 4 - 1 ] of aggclr;
192
193 constructor Construct(
194 ren : renderer_outline_image_ptr;
195 lp : line_parameters_ptr;
196 sx ,sy ,ex ,ey ,pattern_start : int;
197 scale_x : double );
198
step_hornull199 function step_hor : boolean;
step_vernull200 function step_ver : boolean;
201
pattern_endnull202 function pattern_end : int;
verticalnull203 function vertical : boolean;
widthnull204 function width : int;
countnull205 function count : int;
206
207 end;
208
209 renderer_outline_image = object(renderer_outline )
210 m_ren : renderer_base_ptr;
211 m_pattern : line_image_pattern_ptr;
212 m_start : int;
213 m_scale_x : double;
214
215 constructor Construct(ren : renderer_base_ptr; patt : line_image_pattern_ptr );
216
217 procedure pattern_(p : line_image_pattern_ptr );
_patternnull218 function _pattern : line_image_pattern_ptr;
219
220 procedure scale_x_(s : double );
_scale_xnull221 function _scale_x : double;
222
223 procedure start_x_(s : double );
_start_xnull224 function _start_x : double;
225
subpixel_widthnull226 function subpixel_width : int; virtual;
_pattern_widthnull227 function _pattern_width : int;
228
229 procedure pixel(p : aggclr_ptr; x ,y : int );
230
231 procedure blend_color_hspan(x ,y : int; len : unsigned; colors : aggclr_ptr );
232 procedure blend_color_vspan(x ,y : int; len : unsigned; colors : aggclr_ptr );
233
accurate_join_onlynull234 function accurate_join_only : boolean; virtual;
235
236 procedure semidot(cmp : cmp_function; xc1 ,yc1 ,xc2 ,yc2 : int ); virtual;
237
238 procedure line0(lp : line_parameters_ptr ); virtual;
239 procedure line1(lp : line_parameters_ptr; sx ,sy : int ); virtual;
240 procedure line2(lp : line_parameters_ptr; ex ,ey : int ); virtual;
241 procedure line3(lp : line_parameters_ptr; sx ,sy ,ex ,ey : int ); virtual;
242
243 end;
244
245 { GLOBAL PROCEDURES }
246
247
248 IMPLEMENTATION
249 { LOCAL VARIABLES & CONSTANTS }
250 { UNIT IMPLEMENTATION }
251 { _WIDTH_D }
pixel_source._width_dnull252 function pixel_source._width_d;
253 begin
254 result:=_width;
255
256 end;
257
258 { _HEIGHT_D }
pixel_source._height_dnull259 function pixel_source._height_d;
260 begin
261 result:=_height;
262
263 end;
264
265 { CONSTRUCT }
266 constructor line_image_scale.Construct;
267 begin
268 m_source:=src;
269 m_height:=height_;
270
271 if height_ <> 0 then
272 m_scale:=src._height / height_
273 else
274 m_scale:=0;
275
276 end;
277
278 { _WIDTH_D }
line_image_scale._width_dnull279 function line_image_scale._width_d;
280 begin
281 result:=m_source._width;
282
283 end;
284
285 { _HEIGHT_D }
line_image_scale._height_dnull286 function line_image_scale._height_d;
287 begin
288 result:=m_height;
289
290 end;
291
292 { PIXEL }
line_image_scale.pixelnull293 function line_image_scale.pixel;
294 var
295 src_y : double;
296
297 h ,y1 ,y2 : int;
298
299 pix1 ,pix2 : aggclr;
300
301 begin
302 src_y:=(y + 0.5 ) * m_scale - 0.5;
303
304 h :=trunc(m_source._height ) - 1;
305 y1:=trunc(src_y );
306 y2:=y1 + 1;
307
308 if y1 < 0 then
309 pix1.Construct
310 else
311 pix1.Construct(m_source.pixel(x ,y1 ) );
312
313 if y2 > h then
314 pix2.Construct
315 else
316 pix2.Construct(m_source.pixel(x ,y2 ) );
317
318 result:=pix1.gradient8(@pix2 ,src_y - y1 );
319
320 end;
321
322 { CONSTRUCT }
323 constructor line_image_pattern.Construct(filter_ : pattern_filter_ptr );
324 begin
325 m_buf.Construct;
326
327 m_filter:=filter_;
328
329 m_dilation :=filter_.dilation + 1;
330 m_dilation_hr:=m_dilation shl line_subpixel_shift;
331
332 m_data :=0;
333 m_dt_sz :=0;
334 m_width :=0;
335 m_height:=0;
336
337 m_width_hr :=0;
338 m_half_height_hr:=0;
339 m_offset_y_hr :=0;
340
341 end;
342
343 { CONSTRUCT }
344 constructor line_image_pattern.Construct(filter_ : pattern_filter_ptr; src : pixel_source_ptr );
345 begin
346 m_buf.Construct;
347
348 m_filter:=filter_;
349
350 m_dilation :=filter_.dilation + 1;
351 m_dilation_hr:=m_dilation shl line_subpixel_shift;
352
353 m_data :=0;
354 m_dt_sz :=0;
355 m_width :=0;
356 m_height:=0;
357
358 m_width_hr :=0;
359 m_half_height_hr:=0;
360 m_offset_y_hr :=0;
361
362 create(src );
363
364 end;
365
366 { DESTRUCT }
367 destructor line_image_pattern.Destruct;
368 begin
369 agg_freemem(pointer(m_data ) ,m_dt_sz );
370
371 m_buf.Destruct;
372
373 end;
374
375 { CREATE }
376 procedure line_image_pattern.create;
377 var
378 x ,y ,h : unsigned;
379
380 d1 ,d2 ,s1 ,s2 : rgba8_ptr;
381
382 begin
383 m_height:=Ceil(src._height_d );
384 m_width :=Ceil(src._width_d );
385
386 m_width_hr :=trunc(src._width_d * line_subpixel_size );
387 m_half_height_hr:=trunc(src._height_d * line_subpixel_size / 2 );
388 m_offset_y_hr :=m_dilation_hr + m_half_height_hr - line_subpixel_size div 2;
389
390 inc(m_half_height_hr ,line_subpixel_size div 2 );
391
392 agg_freemem(pointer(m_data ) ,m_dt_sz );
393
394 m_dt_sz:=(m_width + m_dilation * 2 ) * (m_height + m_dilation * 2 ) * sizeof(rgba8 );
395
396 agg_getmem(pointer(m_data ) ,m_dt_sz );
397
398 m_buf.attach(
399 int8u_ptr(m_data ) ,
400 m_width + m_dilation * 2 ,
401 m_height + m_dilation * 2 ,
402 (m_width + m_dilation * 2 ) * sizeof(rgba8 ) );
403
404 if m_height > 0 then
405 for y:=0 to m_height - 1 do
406 begin
407 d1:=rgba8_ptr(ptrcomp(m_buf.row(y + m_dilation ) ) + m_dilation * sizeof(rgba8 ) );
408
409 for x:=0 to m_width - 1 do
410 begin
411 d1^:=src.pixel(x ,y );
412
413 inc(ptrcomp(d1 ) ,sizeof(rgba8 ) );
414
415 end;
416
417 end;
418
419 for y:=0 to m_dilation - 1 do
420 begin
421 d1:=rgba8_ptr(ptrcomp(m_buf.row(m_dilation + m_height + y ) ) + m_dilation * sizeof(rgba8 ) );
422 d2:=rgba8_ptr(ptrcomp(m_buf.row(m_dilation - y - 1 ) ) + m_dilation * sizeof(rgba8 ) );
423
424 for x:=0 to m_width - 1 do
425 begin
426 d1^.no_color;
427 d2^.no_color;
428
429 inc(ptrcomp(d1 ) ,sizeof(rgba8 ) );
430 inc(ptrcomp(d2 ) ,sizeof(rgba8 ) );
431
432 end;
433
434 end;
435
436 h:=m_height + m_dilation * 2;
437
438 for y:=0 to h - 1 do
439 begin
440 s1:=rgba8_ptr(ptrcomp(m_buf.row(y ) ) + m_dilation * sizeof(rgba8 ) );
441 s2:=rgba8_ptr(ptrcomp(m_buf.row(y ) ) + (m_dilation + m_width ) * sizeof(rgba8 ) );
442 d1:=rgba8_ptr(ptrcomp(m_buf.row(y ) ) + (m_dilation + m_width ) * sizeof(rgba8 ) );
443 d2:=rgba8_ptr(ptrcomp(m_buf.row(y ) ) + m_dilation * sizeof(rgba8 ) );
444
445 for x:=0 to m_dilation - 1 do
446 begin
447 d1^:=s1^;
448
449 inc(ptrcomp(d1 ) ,sizeof(rgba8 ) );
450 inc(ptrcomp(s1 ) ,sizeof(rgba8 ) );
451 dec(ptrcomp(d2 ) ,sizeof(rgba8 ) );
452 dec(ptrcomp(s2 ) ,sizeof(rgba8 ) );
453
454 d2^:=s2^;
455
456 end;
457
458 end;
459
460 end;
461
462 { PATTERN_WIDTH }
line_image_pattern.pattern_widthnull463 function line_image_pattern.pattern_width;
464 begin
465 result:=m_width_hr;
466
467 end;
468
469 { LINE_WIDTH }
line_image_pattern.line_widthnull470 function line_image_pattern.line_width;
471 begin
472 result:=m_half_height_hr;
473
474 end;
475
476 { PIXEL }
477 procedure line_image_pattern.pixel;
478 begin
479 m_filter.pixel_high_res(
480 m_buf.rows ,
481 p ,
482 x mod m_width_hr + m_dilation_hr ,
483 y + m_offset_y_hr );
484
485 end;
486
487 { FILTER }
488 procedure line_image_pattern.filter(filter_ : pattern_filter_ptr );
489 begin
490 m_filter:=filter_;
491
492 end;
493
494 { FILTER }
line_image_pattern.filternull495 function line_image_pattern.filter : pattern_filter_ptr;
496 begin
497 result:=m_filter;
498
499 end;
500
501 { CONSTRUCT }
502 constructor line_image_pattern_pow2.Construct(filter_ : pattern_filter_ptr );
503 begin
504 inherited Construct(filter_ );
505
506 m_mask:=0;
507
508 end;
509
510 { CONSTRUCT }
511 constructor line_image_pattern_pow2.Construct(filter_ : pattern_filter_ptr; src : pixel_source_ptr );
512 begin
513 inherited Construct(filter_ ,src );
514
515 create(src );
516
517 end;
518
519 { CREATE }
520 procedure line_image_pattern_pow2.create;
521 begin
522 inherited create(src );
523
524 m_mask:=1;
525
526 while m_mask < m_width do
527 begin
528 m_mask:=m_mask shl 1;
529 m_mask:=m_mask or 1;
530
531 end;
532
533 m_mask:=m_mask shl (line_subpixel_shift - 1 );
534 m_mask:=m_mask or line_subpixel_mask;
535
536 m_width_hr:=m_mask + 1;
537
538 end;
539
540 { PIXEL }
541 procedure line_image_pattern_pow2.pixel;
542 begin
543 m_filter.pixel_high_res(
544 m_buf.rows ,
545 p ,
546 (x and m_mask ) + m_dilation_hr ,
547 y + m_offset_y_hr );
548
549 end;
550
551 { CONSTRUCT }
552 constructor distance_interpolator4.Construct;
553 begin
554 end;
555
556 { CONSTRUCT }
557 constructor distance_interpolator4.Construct(x1 ,y1 ,x2 ,y2 ,sx ,sy ,ex ,ey ,len_ : int; scale : double; x ,y : int );
558 var
559 d : double;
560
561 dx_ ,dy_ : int;
562
563 begin
564 m_dx:=x2 - x1;
565 m_dy:=y2 - y1;
566
567 m_dx_start:=line_mr(sx ) - line_mr(x1 );
568 m_dy_start:=line_mr(sy ) - line_mr(y1 );
569 m_dx_end :=line_mr(ex ) - line_mr(x2 );
570 m_dy_end :=line_mr(ey ) - line_mr(y2 );
571
572 m_dist:=
573 trunc(
574 (x + line_subpixel_size / 2 - x2 ) * m_dy -
575 (y + line_subpixel_size / 2 - y2 ) * m_dx );
576
577 m_dist_start:=
578 (line_mr(x + line_subpixel_size div 2 ) - line_mr(sx ) ) * m_dy_start -
579 (line_mr(y + line_subpixel_size div 2 ) - line_mr(sy ) ) * m_dx_start;
580
581 m_dist_end:=
582 (line_mr(x + line_subpixel_size div 2) - line_mr(ex ) ) * m_dy_end -
583 (line_mr(y + line_subpixel_size div 2) - line_mr(ey ) ) * m_dx_end;
584
585 if scale <> 0 then
586 m_len:=trunc(len_ / scale )
587 else
588 m_len:=0;
589
590 d:=len_ * scale;
591
592 if d <> 0 then
593 begin
594 dx_:=trunc(((x2 - x1 ) shl line_subpixel_shift ) / d );
595 dy_:=trunc(((y2 - y1 ) shl line_subpixel_shift ) / d );
596
597 end
598 else
599 begin
600 dx_:=0;
601 dy_:=0;
602
603 end;
604
605 m_dx_pict:=-dy_;
606 m_dy_pict:=dx_;
607
608 m_dist_pict:=
609 shr_int32(
610 (x + line_subpixel_size div 2 - (x1 - dy_ ) ) * m_dy_pict -
611 (y + line_subpixel_size div 2 - (y1 + dx_ ) ) * m_dx_pict ,line_subpixel_shift );
612
613 m_dx :=m_dx shl line_subpixel_shift;
614 m_dy :=m_dy shl line_subpixel_shift;
615 m_dx_start:=m_dx_start shl line_mr_subpixel_shift;
616 m_dy_start:=m_dy_start shl line_mr_subpixel_shift;
617 m_dx_end :=m_dx_end shl line_mr_subpixel_shift;
618 m_dy_end :=m_dy_end shl line_mr_subpixel_shift;
619
620 end;
621
622 { INC_X_ }
623 procedure distance_interpolator4.inc_x_;
624 begin
625 inc(m_dist ,m_dy );
626 inc(m_dist_start ,m_dy_start );
627 inc(m_dist_pict ,m_dy_pict );
628 inc(m_dist_end ,m_dy_end );
629
630 end;
631
632 { DEC_X_ }
633 procedure distance_interpolator4.dec_x_;
634 begin
635 dec(m_dist ,m_dy );
636 dec(m_dist_start ,m_dy_start );
637 dec(m_dist_pict ,m_dy_pict );
638 dec(m_dist_end ,m_dy_end );
639
640 end;
641
642 { INC_Y_ }
643 procedure distance_interpolator4.inc_y_;
644 begin
645 dec(m_dist ,m_dx );
646 dec(m_dist_start ,m_dx_start );
647 dec(m_dist_pict ,m_dx_pict );
648 dec(m_dist_end ,m_dx_end );
649
650 end;
651
652 { DEC_Y_ }
653 procedure distance_interpolator4.dec_y_;
654 begin
655 inc(m_dist ,m_dx );
656 inc(m_dist_start ,m_dx_start );
657 inc(m_dist_pict ,m_dx_pict );
658 inc(m_dist_end ,m_dx_end );
659
660 end;
661
662 { INC_X }
663 procedure distance_interpolator4.inc_x;
664 begin
665 inc(m_dist ,m_dy );
666 inc(m_dist_start ,m_dy_start );
667 inc(m_dist_pict ,m_dy_pict );
668 inc(m_dist_end ,m_dy_end );
669
670 if dy_ > 0 then
671 begin
672 dec(m_dist ,m_dx );
673 dec(m_dist_start ,m_dx_start );
674 dec(m_dist_pict ,m_dx_pict );
675 dec(m_dist_end ,m_dx_end );
676
677 end;
678
679 if dy_ < 0 then
680 begin
681 inc(m_dist ,m_dx );
682 inc(m_dist_start ,m_dx_start );
683 inc(m_dist_pict ,m_dx_pict );
684 inc(m_dist_end ,m_dx_end );
685
686 end;
687
688 end;
689
690 { DEC_X }
691 procedure distance_interpolator4.dec_x;
692 begin
693 dec(m_dist ,m_dy );
694 dec(m_dist_start ,m_dy_start );
695 dec(m_dist_pict ,m_dy_pict );
696 dec(m_dist_end ,m_dy_end );
697
698 if dy_ > 0 then
699 begin
700 dec(m_dist ,m_dx );
701 dec(m_dist_start ,m_dx_start );
702 dec(m_dist_pict ,m_dx_pict );
703 dec(m_dist_end ,m_dx_end );
704
705 end;
706
707 if dy_ < 0 then
708 begin
709 inc(m_dist ,m_dx );
710 inc(m_dist_start ,m_dx_start );
711 inc(m_dist_pict ,m_dx_pict );
712 inc(m_dist_end ,m_dx_end );
713
714 end;
715
716 end;
717
718 { INC_Y }
719 procedure distance_interpolator4.inc_y;
720 begin
721 dec(m_dist ,m_dx );
722 dec(m_dist_start ,m_dx_start );
723 dec(m_dist_pict ,m_dx_pict );
724 dec(m_dist_end ,m_dx_end );
725
726 if dx_ > 0 then
727 begin
728 inc(m_dist ,m_dy );
729 inc(m_dist_start ,m_dy_start );
730 inc(m_dist_pict ,m_dy_pict );
731 inc(m_dist_end ,m_dy_end );
732
733 end;
734
735 if dx_ < 0 then
736 begin
737 dec(m_dist ,m_dy );
738 dec(m_dist_start ,m_dy_start );
739 dec(m_dist_pict ,m_dy_pict );
740 dec(m_dist_end ,m_dy_end );
741
742 end;
743
744 end;
745
746 { DEC_Y }
747 procedure distance_interpolator4.dec_y;
748 begin
749 inc(m_dist ,m_dx );
750 inc(m_dist_start ,m_dx_start );
751 inc(m_dist_pict ,m_dx_pict );
752 inc(m_dist_end ,m_dx_end );
753
754 if dx_ > 0 then
755 begin
756 inc(m_dist ,m_dy );
757 inc(m_dist_start ,m_dy_start );
758 inc(m_dist_pict ,m_dy_pict );
759 inc(m_dist_end ,m_dy_end );
760
761 end;
762
763 if dx_ < 0 then
764 begin
765 dec(m_dist ,m_dy );
766 dec(m_dist_start ,m_dy_start );
767 dec(m_dist_pict ,m_dy_pict );
768 dec(m_dist_end ,m_dy_end );
769
770 end;
771
772 end;
773
774 { DIST }
distance_interpolator4.distnull775 function distance_interpolator4.dist;
776 begin
777 result:=m_dist;
778
779 end;
780
781 { DIST_START }
distance_interpolator4.dist_startnull782 function distance_interpolator4.dist_start;
783 begin
784 result:=m_dist_start;
785
786 end;
787
788 { DIST_PICT }
distance_interpolator4.dist_pictnull789 function distance_interpolator4.dist_pict;
790 begin
791 result:=m_dist_pict;
792
793 end;
794
795 { DIST_END }
distance_interpolator4.dist_endnull796 function distance_interpolator4.dist_end;
797 begin
798 result:=m_dist_end;
799
800 end;
801
802 { DX }
distance_interpolator4.dxnull803 function distance_interpolator4.dx;
804 begin
805 result:=m_dx;
806
807 end;
808
809 { DY }
distance_interpolator4.dynull810 function distance_interpolator4.dy;
811 begin
812 result:=m_dy;
813
814 end;
815
816 { DX_START }
distance_interpolator4.dx_startnull817 function distance_interpolator4.dx_start;
818 begin
819 result:=m_dx_start;
820
821 end;
822
823 { DY_START }
distance_interpolator4.dy_startnull824 function distance_interpolator4.dy_start;
825 begin
826 result:=m_dy_start;
827
828 end;
829
830 { DX_PICT }
distance_interpolator4.dx_pictnull831 function distance_interpolator4.dx_pict;
832 begin
833 result:=m_dx_pict;
834
835 end;
836
837 { DY_PICT }
distance_interpolator4.dy_pictnull838 function distance_interpolator4.dy_pict;
839 begin
840 result:=m_dy_pict;
841
842 end;
843
844 { DX_END }
distance_interpolator4.dx_endnull845 function distance_interpolator4.dx_end;
846 begin
847 result:=m_dx_end;
848
849 end;
850
851 { DY_END }
distance_interpolator4.dy_endnull852 function distance_interpolator4.dy_end;
853 begin
854 result:=m_dy_end;
855
856 end;
857
858 { LEN }
distance_interpolator4.lennull859 function distance_interpolator4.len;
860 begin
861 result:=m_len;
862
863 end;
864
865 { CONSTRUCT }
866 constructor line_interpolator_image.Construct;
867 var
868 i : unsigned;
869
870 stop ,dist1_start ,dist2_start ,npix ,dx ,dy : int;
871
872 li : dda2_line_interpolator;
873
874 begin
875 m_lp:=lp;
876
877 if lp.vertical then
878 m_li.Construct(line_dbl_hr(lp.x2 - lp.x1 ) ,Abs(lp.y2 - lp.y1 ) )
879 else
880 m_li.Construct(line_dbl_hr(lp.y2 - lp.y1 ) ,Abs(lp.x2 - lp.x1 ) + 1 );
881
882 m_di.Construct(
883 lp.x1 ,lp.y1 ,lp.x2 ,lp.y2 ,sx ,sy ,ex ,ey ,lp.len ,scale_x ,
884 lp.x1 and not line_subpixel_mask ,
885 lp.y1 and not line_subpixel_mask );
886
887 m_ren:=ren;
888
889 m_x:=shr_int32(lp.x1 ,line_subpixel_shift );
890 m_y:=shr_int32(lp.y1 ,line_subpixel_shift );
891
892 m_old_x:=m_x;
893 m_old_y:=m_y;
894
895 if lp.vertical then
896 m_count:=Abs(shr_int32(lp.y2 ,line_subpixel_shift ) - m_y )
897 else
898 m_count:=Abs(shr_int32(lp.x2 ,line_subpixel_shift ) - m_x );
899
900 m_width :=ren.subpixel_width;
901 m_max_extent:=shr_int32(m_width ,line_subpixel_shift - 2 );
902
903 try
904 m_start:=pattern_start + (m_max_extent + 2 ) * ren._pattern_width;
905 except
906 m_start:=0 + (m_max_extent + 2 ) * ren._pattern_width;
907
908 end;
909
910 m_step :=0;
911
912 if lp.vertical then
913 li.Construct(0 ,lp.dy shl line_subpixel_shift ,lp.len )
914 else
915 li.Construct(0 ,lp.dx shl line_subpixel_shift ,lp.len );
916
917 stop:=m_width + line_subpixel_size * 2;
918 i :=0;
919
920 while i < max_half_width do
921 begin
922 m_dist_pos[i ]:=li._y;
923
924 if m_dist_pos[i ] >= stop then
925 break;
926
927 li.plus_operator;
928
929 inc(i );
930
931 end;
932
933 m_dist_pos[i ]:=$7FFF0000;
934
935 npix:=1;
936
937 if lp.vertical then
938 repeat
939 m_li.minus_operator;
940
941 dec(m_y ,lp.inc_ );
942
943 m_x:=shr_int32(m_lp.x1 + m_li._y ,line_subpixel_shift );
944
945 if lp.inc_ > 0 then
946 m_di.dec_y(m_x - m_old_x )
947 else
948 m_di.inc_y(m_x - m_old_x );
949
950 m_old_x:=m_x;
951
952 dist1_start:=m_di.dist_start;
953 dist2_start:=dist1_start;
954
955 dx:=0;
956
957 if dist1_start < 0 then
958 inc(npix );
959
960 repeat
961 inc(dist1_start ,m_di.dy_start );
962 dec(dist2_start ,m_di.dy_start );
963
964 if dist1_start < 0 then
965 inc(npix );
966
967 if dist2_start < 0 then
968 inc(npix );
969
970 inc(dx );
971
972 until m_dist_pos[dx ] > m_width;
973
974 if npix = 0 then
975 break;
976
977 npix:=0;
978
979 dec(m_step );
980
981 until m_step < -m_max_extent
982 else
983 repeat
984 m_li.minus_operator;
985
986 dec(m_x ,lp.inc_ );
987
988 m_y:=shr_int32(m_lp.y1 + m_li._y ,line_subpixel_shift );
989
990 if lp.inc_ > 0 then
991 m_di.dec_x(m_y - m_old_y )
992 else
993 m_di.inc_x(m_y - m_old_y );
994
995 m_old_y:=m_y;
996
997 dist1_start:=m_di.dist_start;
998 dist2_start:=dist1_start;
999
1000 dy:=0;
1001
1002 if dist1_start < 0 then
1003 inc(npix );
1004
1005 repeat
1006 dec(dist1_start ,m_di.dx_start );
1007 inc(dist2_start ,m_di.dx_start );
1008
1009 if dist1_start < 0 then
1010 inc(npix );
1011
1012 if dist2_start < 0 then
1013 inc(npix );
1014
1015 inc(dy );
1016
1017 until m_dist_pos[dy ] > m_width;
1018
1019 if npix = 0 then
1020 break;
1021
1022 npix:=0;
1023
1024 dec(m_step );
1025
1026 until m_step < -m_max_extent;
1027
1028 m_li.adjust_forward;
1029
1030 dec(m_step ,m_max_extent );
1031
1032 end;
1033
1034 { STEP_HOR }
line_interpolator_image.step_hornull1035 function line_interpolator_image.step_hor;
1036 var
1037 s1 ,s2 ,dist_start ,dist_pict ,dist_end ,dy ,dist ,npix : int;
1038
1039 p0 ,p1 : aggclr_ptr;
1040
1041 begin
1042 m_li.plus_operator;
1043
1044 inc(m_x ,m_lp.inc_ );
1045
1046 m_y:=shr_int32(m_lp.y1 + m_li._y ,line_subpixel_shift );
1047
1048 if m_lp.inc_ > 0 then
1049 m_di.inc_x(m_y - m_old_y )
1050 else
1051 m_di.dec_x(m_y - m_old_y );
1052
1053 m_old_y:=m_y;
1054
1055 s1:=m_di.dist div m_lp.len;
1056 s2:=-s1;
1057
1058 if m_lp.inc_ < 0 then
1059 s1:=-s1;
1060
1061 dist_start:=m_di.dist_start;
1062 dist_pict :=m_di.dist_pict + m_start;
1063 dist_end :=m_di.dist_end;
1064
1065 p0:=aggclr_ptr(ptrcomp(@m_colors[0 ] ) + (max_half_width + 2 ) * sizeof(aggclr ) );
1066 p1:=p0;
1067
1068 npix:=0;
1069
1070 p1.clear;
1071
1072 if dist_end > 0 then
1073 begin
1074 if dist_start <= 0 then
1075 m_ren.pixel(p1 ,dist_pict ,s2 );
1076
1077 inc(npix );
1078
1079 end;
1080
1081 inc(ptrcomp(p1 ) ,sizeof(aggclr ) );
1082
1083 dy :=1;
1084 dist:=m_dist_pos[dy ];
1085
1086 while dist - s1 <= m_width do
1087 begin
1088 dec(dist_start ,m_di.dx_start );
1089 dec(dist_pict ,m_di.dx_pict );
1090 dec(dist_end ,m_di.dx_end );
1091
1092 p1.clear();
1093
1094 if (dist_end > 0 ) and
1095 (dist_start <= 0 ) then
1096 begin
1097 if m_lp.inc_ > 0 then
1098 dist:=-dist;
1099
1100 m_ren.pixel(p1 ,dist_pict ,s2 - dist );
1101
1102 inc(npix );
1103
1104 end;
1105
1106 inc(ptrcomp(p1 ) ,sizeof(aggclr ) );
1107 inc(dy );
1108
1109 dist:=m_dist_pos[dy ];
1110
1111 end;
1112
1113 dy:=1;
1114
1115 dist_start:=m_di.dist_start;
1116 dist_pict :=m_di.dist_pict + m_start;
1117 dist_end :=m_di.dist_end;
1118
1119 dist:=m_dist_pos[dy ];
1120
1121 while dist + s1 <= m_width do
1122 begin
1123 inc(dist_start ,m_di.dx_start );
1124 inc(dist_pict ,m_di.dx_pict );
1125 inc(dist_end ,m_di.dx_end );
1126
1127 dec(ptrcomp(p0 ) ,sizeof(aggclr ) );
1128
1129 p0.clear;
1130
1131 if (dist_end > 0 ) and
1132 (dist_start <= 0 ) then
1133 begin
1134 if m_lp.inc_ > 0 then
1135 dist:=-dist;
1136
1137 m_ren.pixel(p0 ,dist_pict ,s2 + dist );
1138
1139 inc(npix );
1140
1141 end;
1142
1143 inc(dy );
1144
1145 dist:=m_dist_pos[dy ];
1146
1147 end;
1148
1149 m_ren.blend_color_vspan(
1150 m_x ,m_y - dy + 1 ,
1151 unsigned((ptrcomp(p1 ) - ptrcomp(p0 ) ) div sizeof(aggclr ) ) ,
1152 p0 );
1153
1154 inc(m_step );
1155
1156 result:=
1157 (npix <> 0 ) and
1158 (m_step < m_count );
1159
1160 end;
1161
1162 { STEP_VER }
line_interpolator_image.step_vernull1163 function line_interpolator_image.step_ver;
1164 var
1165 s1 ,s2 ,dist_start ,dist_pict ,dist_end ,dx ,dist ,npix : int;
1166
1167 p0 ,p1 : aggclr_ptr;
1168
1169 begin
1170 m_li.plus_operator;
1171
1172 inc(m_y ,m_lp.inc_ );
1173
1174 m_x:=shr_int32(m_lp.x1 + m_li._y ,line_subpixel_shift );
1175
1176 if m_lp.inc_ > 0 then
1177 m_di.inc_y(m_x - m_old_x )
1178 else
1179 m_di.dec_y(m_x - m_old_x );
1180
1181 m_old_x:=m_x;
1182
1183 s1:=m_di.dist div m_lp.len;
1184 s2:=-s1;
1185
1186 if m_lp.inc_ > 0 then
1187 s1:=-s1;
1188
1189 dist_start:=m_di.dist_start;
1190 dist_pict :=m_di.dist_pict + m_start;
1191 dist_end :=m_di.dist_end;
1192
1193 p0:=aggclr_ptr(ptrcomp(@m_colors[0 ] ) + (max_half_width + 2 ) * sizeof(aggclr ) );
1194 p1:=p0;
1195
1196 npix:=0;
1197
1198 p1.clear;
1199
1200 if dist_end > 0 then
1201 begin
1202 if dist_start <= 0 then
1203 m_ren.pixel(p1 ,dist_pict ,s2 );
1204
1205 inc(npix );
1206
1207 end;
1208
1209 inc(ptrcomp(p1 ) ,sizeof(aggclr ) );
1210
1211 dx :=1;
1212 dist:=m_dist_pos[dx ];
1213
1214 while dist - s1 <= m_width do
1215 begin
1216 inc(dist_start ,m_di.dy_start );
1217 inc(dist_pict ,m_di.dy_pict );
1218 inc(dist_end ,m_di.dy_end );
1219
1220 p1.clear;
1221
1222 if (dist_end > 0 ) and
1223 (dist_start <= 0 ) then
1224 begin
1225 if m_lp.inc_ > 0 then
1226 dist:=-dist;
1227
1228 m_ren.pixel(p1 ,dist_pict ,s2 + dist );
1229
1230 inc(npix );
1231
1232 end;
1233
1234 inc(ptrcomp(p1 ) ,sizeof(aggclr ) );
1235 inc(dx );
1236
1237 dist:=m_dist_pos[dx ];
1238
1239 end;
1240
1241 dx:=1;
1242
1243 dist_start:=m_di.dist_start;
1244 dist_pict :=m_di.dist_pict + m_start;
1245 dist_end :=m_di.dist_end;
1246
1247 dist:=m_dist_pos[dx ];
1248
1249 while dist + s1 <= m_width do
1250 begin
1251 dec(dist_start ,m_di.dy_start );
1252 dec(dist_pict ,m_di.dy_pict );
1253 dec(dist_end ,m_di.dy_end );
1254
1255 dec(ptrcomp(p0 ) ,sizeof(aggclr ) );
1256
1257 p0.clear;
1258
1259 if (dist_end > 0 ) and
1260 (dist_start <= 0 ) then
1261 begin
1262 if m_lp.inc_ > 0 then
1263 dist:=-dist;
1264
1265 m_ren.pixel(p0 ,dist_pict ,s2 - dist );
1266
1267 inc(npix );
1268
1269 end;
1270
1271 inc(dx );
1272
1273 dist:=m_dist_pos[dx ];
1274
1275 end;
1276
1277 m_ren.blend_color_hspan(
1278 m_x - dx + 1 ,m_y ,
1279 unsigned((ptrcomp(p1 ) - ptrcomp(p0 ) ) div sizeof(aggclr ) ) ,
1280 p0 );
1281
1282 inc(m_step );
1283
1284 result:=
1285 (npix <> 0 ) and
1286 (m_step < m_count );
1287
1288 end;
1289
1290 { PATTERN_END }
line_interpolator_image.pattern_endnull1291 function line_interpolator_image.pattern_end;
1292 begin
1293 result:=m_start + m_di.len;
1294
1295 end;
1296
1297 { VERTICAL }
line_interpolator_image.verticalnull1298 function line_interpolator_image.vertical;
1299 begin
1300 result:=m_lp.vertical;
1301
1302 end;
1303
1304 { WIDTH }
line_interpolator_image.widthnull1305 function line_interpolator_image.width;
1306 begin
1307 result:=m_width;
1308
1309 end;
1310
1311 { COUNT }
line_interpolator_image.countnull1312 function line_interpolator_image.count;
1313 begin
1314 result:=m_count;
1315
1316 end;
1317
1318 { CONSTRUCT }
1319 constructor renderer_outline_image.Construct;
1320 begin
1321 m_ren :=ren;
1322 m_pattern:=patt;
1323 m_start :=0;
1324 m_scale_x:=1.0;
1325
1326 end;
1327
1328 { PATTERN_ }
1329 procedure renderer_outline_image.pattern_;
1330 begin
1331 m_pattern:=p;
1332
1333 end;
1334
1335 { _PATTERN }
renderer_outline_image._patternnull1336 function renderer_outline_image._pattern;
1337 begin
1338 result:=m_pattern;
1339
1340 end;
1341
1342 { SCALE_X_ }
1343 procedure renderer_outline_image.scale_x_;
1344 begin
1345 m_scale_x:=s;
1346
1347 end;
1348
1349 { _SCALE_X }
renderer_outline_image._scale_xnull1350 function renderer_outline_image._scale_x;
1351 begin
1352 result:=m_scale_x;
1353
1354 end;
1355
1356 { START_X_ }
1357 procedure renderer_outline_image.start_x_;
1358 begin
1359 m_start:=trunc(s * line_subpixel_size );
1360
1361 end;
1362
1363 { _START_X }
renderer_outline_image._start_xnull1364 function renderer_outline_image._start_x;
1365 begin
1366 result:=m_start / line_subpixel_size;
1367
1368 end;
1369
1370 { SUBPIXEL_WIDTH }
renderer_outline_image.subpixel_widthnull1371 function renderer_outline_image.subpixel_width;
1372 begin
1373 result:=m_pattern.line_width;
1374
1375 end;
1376
1377 { _PATTERN_WIDTH }
renderer_outline_image._pattern_widthnull1378 function renderer_outline_image._pattern_width;
1379 begin
1380 result:=m_pattern.pattern_width;
1381
1382 end;
1383
1384 { PIXEL }
1385 procedure renderer_outline_image.pixel;
1386 begin
1387 m_pattern.pixel(p ,x ,y );
1388
1389 end;
1390
1391 { BLEND_COLOR_HSPAN }
1392 procedure renderer_outline_image.blend_color_hspan;
1393 begin
1394 m_ren.blend_color_hspan(x ,y ,len ,colors ,NIL );
1395
1396 end;
1397
1398 { BLEND_COLOR_VSPAN }
1399 procedure renderer_outline_image.blend_color_vspan;
1400 begin
1401 m_ren.blend_color_vspan(x ,y ,len ,colors ,NIL );
1402
1403 end;
1404
1405 { ACCURATE_JOIN_ONLY }
renderer_outline_image.accurate_join_onlynull1406 function renderer_outline_image.accurate_join_only;
1407 begin
1408 result:=true;
1409
1410 end;
1411
1412 { SEMIDOT }
1413 procedure renderer_outline_image.semidot;
1414 begin
1415 end;
1416
1417 { LINE0 }
1418 procedure renderer_outline_image.line0;
1419 begin
1420 end;
1421
1422 { LINE1 }
1423 procedure renderer_outline_image.line1;
1424 begin
1425 end;
1426
1427 { LINE2 }
1428 procedure renderer_outline_image.line2;
1429 begin
1430 end;
1431
1432 { LINE3 }
1433 procedure renderer_outline_image.line3;
1434 var
1435 li : line_interpolator_image;
1436
1437 begin
1438 fix_degenerate_bisectrix_start(lp ,@sx ,@sy );
1439 fix_degenerate_bisectrix_end (lp ,@ex ,@ey );
1440
1441 li.Construct(@self ,lp ,sx ,sy ,ex ,ey ,m_start ,m_scale_x );
1442
1443 if li.vertical then
1444 while li.step_ver do
1445 else
1446 while li.step_hor do;
1447
1448 m_start:=li.pattern_end;
1449
1450 end;
1451
1452 END.
1453
1454