1 //----------------------------------------------------------------------------
2 // Agg2D - Version 1.0
3 // Based on Anti-Grain Geometry
4 // Copyright (C) 2005 Maxim Shemanarev (http://www.antigrain.com)
5 //
6 // Agg2D - Version 1.0 Release Milano 3 (AggPas 2.4 RM3)
7 // Pascal Port By: Milan Marusinec alias Milano
8 //                 milan@marusinec.sk
9 //                 http://www.aggpas.org
10 // Copyright (c) 2007 - 2008
11 //
12 // Permission to copy, use, modify, sell and distribute this software
13 // is granted provided this copyright notice appears in all copies.
14 // This software is provided "as is" without express or implied
15 // warranty, and with no claim as to its suitability for any purpose.
16 //
17 
18 unit
19  agg_2D ;
20 
21 INTERFACE
22 
23 {$I agg_mode.inc }
24 
25 // With this define uncommented you can use FreeType font engine
26 { $DEFINE AGG2D_USE_FREETYPE }
27 
28 uses
29  agg_basics ,
30  agg_array ,
31  agg_trans_affine ,
32  agg_trans_viewport ,
33  agg_path_storage ,
34  agg_conv_stroke ,
35  agg_conv_transform ,
36  agg_conv_curve ,
37  agg_rendering_buffer ,
38  agg_renderer_base ,
39  agg_renderer_scanline ,
40  agg_span_gradient ,
41  agg_span_image_filter_rgba ,
42  agg_span_image_resample_rgba ,
43  agg_span_converter ,
44  agg_span_interpolator_linear ,
45  agg_span_allocator ,
46  agg_rasterizer_scanline_aa ,
47  agg_gamma_functions ,
48  agg_scanline_u ,
49  agg_arc ,
50  agg_bezier_arc ,
51  agg_rounded_rect ,
52  agg_font_engine ,
53  agg_font_cache_manager ,
54  agg_pixfmt ,
55  agg_pixfmt_rgba ,
56  agg_color ,
57  agg_math_stroke ,
58  agg_image_filters ,
59  agg_vertex_source ,
60  agg_render_scanlines ,
61 
62 {$IFDEF AGG2D_USE_FREETYPE }
63  agg_font_freetype ,
64 {$ENDIF }
65 {$IFDEF AGG2D_USE_WINFONTS}
66  agg_font_win32_tt ,
67  Windows ,
68 {$ENDIF }
69 
70  Math ;
71 
72 { GLOBAL VARIABLES & CONSTANTS }
73 const
74 // LineJoin
75  JoinMiter = miter_join;
76  JoinRound = round_join;
77  JoinBevel = bevel_join;
78 
79 // LineCap
80  CapButt   = butt_cap;
81  CapSquare = square_cap;
82  CapRound  = round_cap;
83 
84 // TextAlignment
85  AlignLeft   = 0;
86  AlignRight  = 1;
87  AlignCenter = 2;
88  AlignTop    = AlignRight;
89  AlignBottom = AlignLeft;
90 
91 // BlendMode
92  BlendAlpha      = end_of_comp_op_e;
93  BlendClear      = comp_op_clear;
94  BlendSrc        = comp_op_src;
95  BlendDst        = comp_op_dst;
96  BlendSrcOver    = comp_op_src_over;
97  BlendDstOver    = comp_op_dst_over;
98  BlendSrcIn      = comp_op_src_in;
99  BlendDstIn      = comp_op_dst_in;
100  BlendSrcOut     = comp_op_src_out;
101  BlendDstOut     = comp_op_dst_out;
102  BlendSrcAtop    = comp_op_src_atop;
103  BlendDstAtop    = comp_op_dst_atop;
104  BlendXor        = comp_op_xor;
105  BlendAdd        = comp_op_plus;
106  BlendSub        = comp_op_minus;
107  BlendMultiply   = comp_op_multiply;
108  BlendScreen     = comp_op_screen;
109  BlendOverlay    = comp_op_overlay;
110  BlendDarken     = comp_op_darken;
111  BlendLighten    = comp_op_lighten;
112  BlendColorDodge = comp_op_color_dodge;
113  BlendColorBurn  = comp_op_color_burn;
114  BlendHardLight  = comp_op_hard_light;
115  BlendSoftLight  = comp_op_soft_light;
116  BlendDifference = comp_op_difference;
117  BlendExclusion  = comp_op_exclusion;
118  BlendContrast   = comp_op_contrast;
119 
120 { TYPES DEFINITION }
121 type
122  Color_ptr = ^Color;
123  Color     = rgba8;
124 
125  Rect_ = agg_basics.rect;
126  RectD = agg_basics.rect_d;
127 
128  Affine     = trans_affine;
129  Affine_ptr = trans_affine_ptr;
130 
131  FontRasterizer     = gray8_adaptor_type;
132  FontRasterizer_ptr = gray8_adaptor_type_ptr;
133 
134  FontScanline     = gray8_scanline_type;
135  FontScanline_ptr = gray8_scanline_type_ptr;
136 
137 {$IFDEF AGG2D_USE_FREETYPE }
138  FontEngine = font_engine_freetype_int32;
139 {$ENDIF }
140 {$IFDEF AGG2D_USE_WINFONTS}
141  FontEngine = font_engine_win32_tt_int32;
142 {$ENDIF }
143 
144  Gradient  = (Solid ,Linear ,Radial );
145  Direction = (CW, CCW );
146 
147  LineJoin_  = int;
148  LineCap_   = int;
149  BlendMode_ = comp_op_e;
150 
151  TextAlignment = int;
152 
153  DrawPathFlag = (
154   FillOnly ,
155   StrokeOnly ,
156   FillAndStroke ,
157   FillWithLineColor );
158 
159  ViewportOption = (
160   Anisotropic ,
161   XMinYMin ,
162   XMidYMin ,
163   XMaxYMin ,
164   XMinYMid ,
165   XMidYMid ,
166   XMaxYMid ,
167   XMinYMax ,
168   XMidYMax ,
169   XMaxYMax );
170 
171  ImageFilter_ = (
172   NoFilter ,
173   Bilinear ,
174   Hanning ,
175   Hermite ,
176   Quadric ,
177   Bicubic ,
178   Catrom ,
179   Spline16 ,
180   Spline36 ,
181   Blackman144 );
182 
183  ImageResample_ = (
184   NoResample ,
185   ResampleAlways ,
186   ResampleOnZoomOut );
187 
188  FontCacheType = (
189   RasterFontCache ,
190   VectorFontCache );
191 
192  Transformations_ptr = ^Transformations_;
193  Transformations_ = record
194    affineMatrix : array[0..5 ] of double;
195 
196   end;
197 
198  Image_ptr = ^Image;
199  Image = object
200    renBuf : rendering_buffer;
201 
202    constructor Construct; overload;
203    constructor Construct(buf : int8u_ptr; width_ ,height_ : unsigned; stride : int ); overload;
204    destructor  Destruct;
205 
206    procedure attach(buf : int8u_ptr; width_ ,height_ : unsigned; stride : int );
207 
widthnull208    function  width : int;
heightnull209    function  height : int;
210 
211    procedure premultiply;
212    procedure demultiply;
213 
214   end;
215 
216  Agg2DRasterizerGamma = object(vertex_source )
217    m_alpha : gamma_multiply;
218    m_gamma : gamma_power;
219 
220    constructor Construct(alpha ,gamma : double );
221 
func_operator_gammanull222    function func_operator_gamma(x : double ) : double; virtual;
223 
224   end;
225 
226  Agg2D_ptr = ^Agg2D;
227  Agg2D = object
228   private
229    m_rbuf : rendering_buffer;
230 
231    m_pixFormat ,m_pixFormatComp ,m_pixFormatPre ,m_pixFormatCompPre : pixel_formats;
232    m_renBase   ,m_renBaseComp   ,m_renBasePre   ,m_renBaseCompPre   : renderer_base;
233 
234    m_renSolid ,m_renSolidComp : renderer_scanline_aa_solid;
235 
236    m_allocator : span_allocator;
237    m_clipBox   : RectD;
238 
239    m_blendMode ,m_imageBlendMode : BlendMode_;
240 
241    m_imageBlendColor : Color;
242 
243    m_scanline   : scanline_u8;
244    m_rasterizer : rasterizer_scanline_aa;
245 
246    m_masterAlpha ,m_antiAliasGamma : double;
247 
248    m_fillColor ,m_lineColor : Color;
249 
250    m_fillGradient ,m_lineGradient : pod_auto_array;
251 
252    m_lineCap  : LineCap_;
253    m_lineJoin : LineJoin_;
254 
255    m_fillGradientFlag ,m_lineGradientFlag : Gradient;
256 
257    m_fillGradientMatrix ,m_lineGradientMatrix : trans_affine;
258 
259    m_fillGradientD1 ,
260    m_lineGradientD1 ,
261    m_fillGradientD2 ,
262    m_lineGradientD2 ,
263    m_textAngle      : double;
264    m_textAlignX     ,
265    m_textAlignY     : TextAlignment;
266    m_textHints      : boolean;
267    m_fontHeight     ,
268    m_fontAscent     ,
269    m_fontDescent    : double;
270    m_fontCacheType  : FontCacheType;
271 
272    m_imageFilter    : ImageFilter_;
273    m_imageResample  : ImageResample_;
274    m_imageFilterLut : image_filter_lut;
275 
276    m_fillGradientInterpolator ,
277    m_lineGradientInterpolator : span_interpolator_linear;
278 
279    m_linearGradientFunction : gradient_x;
280    m_radialGradientFunction : gradient_circle;
281 
282    m_lineWidth   : double;
283    m_evenOddFlag : boolean;
284 
285    m_path      : path_storage;
286    m_transform : trans_affine;
287 
288    m_convCurve  : conv_curve;
289    m_convStroke : conv_stroke;
290 
291    m_pathTransform ,m_strokeTransform : conv_transform;
292 
293   {$IFNDEF AGG2D_NO_FONT}
294    m_fontEngine       : FontEngine;
295    m_fontCacheManager : font_cache_manager;
296   {$ENDIF}
297   {$IFDEF AGG2D_USE_WINFONTS }
298    m_fontDC : HDC;
299   {$ENDIF }
300 
301   // Other Pascal-specific members
302    m_gammaNone  : gamma_none;
303    m_gammaAgg2D : Agg2DRasterizerGamma;
304 
305    m_ifBilinear    : image_filter_bilinear;
306    m_ifHanning     : image_filter_hanning;
307    m_ifHermite     : image_filter_hermite;
308    m_ifQuadric     : image_filter_quadric;
309    m_ifBicubic     : image_filter_bicubic;
310    m_ifCatrom      : image_filter_catrom;
311    m_ifSpline16    : image_filter_spline16;
312    m_ifSpline36    : image_filter_spline36;
313    m_ifBlackman144 : image_filter_blackman144;
314 
315   public
316    constructor Construct;
317    destructor  Destruct;
318 
319   // Setup
320    procedure attach(buf : int8u_ptr; width_ ,height_ : unsigned; stride : int ); overload;
321    procedure attach(img : Image_ptr ); overload;
322 
323    procedure clipBox(x1 ,y1 ,x2 ,y2 : double ); overload;
clipBoxnull324    function  clipBox : RectD; overload;
325 
326    procedure clearAll(c : Color ); overload;
327    procedure clearAll(r ,g ,b : unsigned; a : unsigned = 255 ); overload;
328    procedure FillAll(c: Color); overload;
329    procedure FillAll(r, g, b: byte; a: byte = 255); overload;
330 
331    procedure clearClipBox(c : Color ); overload;
332    procedure clearClipBox(r ,g ,b : unsigned; a : unsigned = 255 ); overload;
333 
334   // Conversions
335    procedure worldToScreen(x ,y : double_ptr ); overload;
336    procedure screenToWorld(x ,y : double_ptr ); overload;
worldToScreennull337    function  worldToScreen(scalar : double ) : double; overload;
screenToWorldnull338    function  screenToWorld(scalar : double ) : double; overload;
339 
340    procedure alignPoint(x ,y : double_ptr );
341 
inBoxnull342    function  inBox(worldX ,worldY : double ) : boolean;
343 
344   // General Attributes
345    procedure blendMode(m : BlendMode_ ); overload;
blendModenull346    function  blendMode : BlendMode_; overload;
347 
348    procedure imageBlendMode(m : BlendMode_ ); overload;
imageBlendModenull349    function  imageBlendMode : BlendMode_; overload;
350 
351    procedure imageBlendColor(c : Color ); overload;
352    procedure imageBlendColor(r ,g ,b : unsigned; a : unsigned = 255 ); overload;
imageBlendColornull353    function  imageBlendColor : Color; overload;
354 
355    procedure masterAlpha(a : double ); overload;
masterAlphanull356    function  masterAlpha : double; overload;
357 
358    procedure antiAliasGamma(g : double ); overload;
antiAliasGammanull359    function  antiAliasGamma : double; overload;
360 
361    procedure fillColor(c : Color ); overload;
362    procedure fillColor(r ,g ,b : unsigned; a : unsigned = 255 ); overload;
363    procedure noFill;
364 
365    procedure lineColor(c : Color ); overload;
366    procedure lineColor(r ,g ,b : unsigned; a : unsigned = 255 ); overload;
367    procedure noLine;
368 
fillColornull369    function  fillColor : Color; overload;
lineColornull370    function  lineColor : Color; overload;
371 
372    procedure fillLinearGradient(x1 ,y1 ,x2 ,y2 : double; c1 ,c2 : Color; profile : double = 1.0 );
373    procedure lineLinearGradient(x1 ,y1 ,x2 ,y2 : double; c1 ,c2 : Color; profile : double = 1.0 );
374 
375    procedure fillRadialGradient(x ,y ,r : double; c1 ,c2 : Color; profile : double = 1.0 ); overload;
376    procedure lineRadialGradient(x ,y ,r : double; c1 ,c2 : Color; profile : double = 1.0 ); overload;
377 
378    procedure fillRadialGradient(x ,y ,r : double; c1 ,c2 ,c3 : Color ); overload;
379    procedure lineRadialGradient(x ,y ,r : double; c1 ,c2 ,c3 : Color ); overload;
380 
381    procedure fillRadialGradient(x ,y ,r : double ); overload;
382    procedure lineRadialGradient(x ,y ,r : double ); overload;
383 
384    procedure lineWidth (w : double );
lineWidth_null385    function  lineWidth_(w : double ) : double;
386 
387    procedure lineCap(cap : LineCap_ ); overload;
lineCapnull388    function  lineCap : LineCap_; overload;
389 
390    procedure lineJoin(join : LineJoin_ ); overload;
lineJoinnull391    function  lineJoin : LineJoin_; overload;
392 
393    procedure fillEvenOdd(evenOddFlag : boolean ); overload;
fillEvenOddnull394    function  fillEvenOdd : boolean; overload;
395 
396   // Transformations
transformationsnull397    function  transformations : Transformations_; overload;
398    procedure transformations(tr : Transformations_ptr ); overload;
399    procedure resetTransformations;
400 
401    procedure affine(tr : Affine_ptr ); overload;
402    procedure affine(tr : Transformations_ptr ); overload;
403 
404    procedure rotate   (angle : double );
405    procedure scale    (sx ,sy : double );
406    procedure skew     (sx ,sy : double );
407    procedure translate(x ,y : double );
408 
409    procedure parallelogram(x1 ,y1 ,x2 ,y2 : double; para : double_ptr );
410 
411    procedure viewport(
412               worldX1  ,worldY1  ,worldX2  ,worldY2 ,
413               screenX1 ,screenY1 ,screenX2 ,screenY2 : double;
414               opt : ViewportOption = XMidYMid );
415 
416   // Basic Shapes
417    procedure line     (x1 ,y1 ,x2 ,y2 : double );
418    procedure triangle (x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double );
419    procedure rectangle(x1 ,y1 ,x2 ,y2 : double );
420 
421    procedure roundedRect(x1 ,y1 ,x2 ,y2 ,r : double ); overload;
422    procedure roundedRect(x1 ,y1 ,x2 ,y2 ,rx ,ry : double ); overload;
423    procedure roundedRect(
424               x1 ,y1 ,x2 ,y2 ,
425               rxBottom ,ryBottom ,
426               rxTop ,ryTop : double ); overload;
427 
428    procedure ellipse(cx ,cy ,rx ,ry : double );
429 
430    procedure arc (cx ,cy ,rx ,ry ,start ,sweep : double );
431    procedure star(cx ,cy ,r1 ,r2 ,startAngle : double; numRays : int );
432 
433    procedure curve(x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double ); overload;
434    procedure curve(x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,x4 ,y4 : double ); overload;
435 
436    procedure polygon (xy : double_ptr; numPoints : int );
437    procedure polyline(xy : double_ptr; numPoints : int );
438 
439   // Text
440    procedure flipText(flip : boolean );
441 
442    procedure font(
443               fileName : char_ptr; height : double;
444               bold : boolean = false;
445               italic : boolean = false;
446               ch : FontCacheType = RasterFontCache;
447               angle : double = 0.0 );
448 
fontHeightnull449    function  fontHeight : double;
450 
451    procedure textAlignment(alignX ,alignY : TextAlignment );
452 
textHintsnull453    function  textHints : boolean; overload;
454    procedure textHints(hints : boolean ); overload;
textWidthnull455    function  textWidth(str : char_ptr ) : double;
456 
457    procedure text(
458               x ,y : double; str : char_ptr;
459               roundOff : boolean = false;
460               ddx : double = 0.0;
461               ddy : double = 0.0 );
462 
463   // Path commands
464    procedure resetPath;
465 
466    procedure moveTo (x ,y : double );
467    procedure moveRel(dx ,dy : double );
468 
469    procedure lineTo (x ,y : double );
470    procedure lineRel(dx ,dy : double );
471 
472    procedure horLineTo (x : double );
473    procedure horLineRel(dx : double );
474 
475    procedure verLineTo (y : double );
476    procedure verLineRel(dy : double );
477 
478    procedure arcTo(
479               rx ,ry ,angle : double;
480               largeArcFlag ,sweepFlag : boolean;
481               x ,y : double );
482 
483    procedure arcRel(
484               rx ,ry ,angle : double;
485               largeArcFlag ,sweepFlag : boolean;
486               dx ,dy : double );
487 
488    procedure quadricCurveTo (xCtrl ,yCtrl ,xTo ,yTo : double ); overload;
489    procedure quadricCurveRel(dxCtrl ,dyCtrl ,dxTo ,dyTo : double ); overload;
490    procedure quadricCurveTo (xTo ,yTo : double ); overload;
491    procedure quadricCurveRel(dxTo ,dyTo : double ); overload;
492 
493    procedure cubicCurveTo (xCtrl1 ,yCtrl1 ,xCtrl2 ,yCtrl2 ,xTo ,yTo : double ); overload;
494    procedure cubicCurveRel(dxCtrl1 ,dyCtrl1 ,dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo : double ); overload;
495    procedure cubicCurveTo (xCtrl2 ,yCtrl2 ,xTo ,yTo : double ); overload;
496    procedure cubicCurveRel(xCtrl2 ,yCtrl2 ,xTo ,yTo : double ); overload;
497 
498    procedure addEllipse(cx ,cy ,rx ,ry : double; dir : Direction );
499    procedure closePolygon;
500 
501    procedure drawPath(flag : DrawPathFlag = FillAndStroke );
502 
503    procedure drawPathNoTransform(flag : DrawPathFlag = FillAndStroke );
504 
505   // Image Transformations
506    procedure imageFilter(f : ImageFilter_ ); overload;
imageFilternull507    function  imageFilter : ImageFilter_; overload;
508 
509    procedure imageResample(f : ImageResample_ ); overload;
imageResamplenull510    function  imageResample : ImageResample_; overload;
511 
512    procedure transformImage(
513               img : Image_ptr;
514               imgX1 ,imgY1 ,imgX2 ,imgY2 : int;
515               dstX1 ,dstY1 ,dstX2 ,dstY2 : double ); overload;
516 
517    procedure transformImage(
518               img : Image_ptr;
519               dstX1 ,dstY1 ,dstX2 ,dstY2 : double ); overload;
520 
521    procedure transformImage(
522               img : Image_ptr;
523               imgX1 ,imgY1 ,imgX2 ,imgY2 : int;
524               parallelogram_ : double_ptr ); overload;
525 
526    procedure transformImage(img : Image_ptr; parallelogram_ : double_ptr ); overload;
527 
528    procedure transformImagePath(
529               img : Image_ptr;
530               imgX1 ,imgY1 ,imgX2 ,imgY2 : int;
531               dstX1 ,dstY1 ,dstX2 ,dstY2 : double ); overload;
532 
533    procedure transformImagePath(
534               img : Image_ptr;
535               dstX1 ,dstY1 ,dstX2 ,dstY2 : double ); overload;
536 
537    procedure transformImagePath(
538               img : Image_ptr;
539               imgX1 ,imgY1 ,imgX2 ,imgY2 : int;
540               parallelogram_ : double_ptr ); overload;
541 
542    procedure transformImagePath(img : Image_ptr; parallelogram_ : double_ptr ); overload;
543 
544   // Image Blending (no transformations available)
545    procedure blendImage(
546               img : Image_ptr;
547               imgX1 ,imgY1 ,imgX2 ,imgY2 : int;
548               dstX ,dstY : double; alpha : unsigned = 255 ); overload;
549 
550    procedure blendImage(img : Image_ptr; dstX ,dstY : double; alpha : unsigned = 255 ); overload;
551 
552   // Copy image directly, together with alpha-channel
553    procedure copyImage(
554               img : Image_ptr;
555               imgX1 ,imgY1 ,imgX2 ,imgY2 : int;
556               dstX ,dstY : double ); overload;
557 
558    procedure copyImage(img : Image_ptr; dstX ,dstY : double ); overload;
559 
560   private
561    procedure render(fillColor_ : boolean ); overload;
562    procedure render(ras : FontRasterizer_ptr; sl : FontScanline_ptr ); overload;
563 
564    procedure addLine(x1 ,y1 ,x2 ,y2 : double );
565    procedure updateRasterizerGamma;
566    procedure renderImage(
567               img : Image_ptr;
568               x1 ,y1 ,x2 ,y2 : int;
569               parl : double_ptr );
570 
571   end;
572 
573  SpanConvImageBlend_ptr = ^SpanConvImageBlend;
574  SpanConvImageBlend = object(span_convertor )
575   private
576    m_mode  : BlendMode_;
577    m_color : Color;
578    m_pixel : pixel_formats_ptr; // m_pixFormatCompPre
579 
580   public
581    constructor Construct(m : BlendMode_; c : Color; p : pixel_formats_ptr );
582 
583    procedure convert(span : aggclr_ptr; x ,y : int; len : unsigned ); virtual;
584 
585   end;
586 
587 { GLOBAL PROCEDURES }
588 // Auxiliary
pinull589  function  pi : double;
deg2Radnull590  function  deg2Rad(v : double ) : double;
rad2Degnull591  function  rad2Deg(v : double ) : double;
592 
operator_is_equalnull593  function  operator_is_equal    (c1 ,c2 : Color_ptr ) : boolean;
operator_is_not_equalnull594  function  operator_is_not_equal(c1 ,c2 : Color_ptr ) : boolean;
595 
596  procedure Agg2DRenderer_render(
597             gr : Agg2D_ptr;
598             renBase : renderer_base_ptr;
599             renSolid : renderer_scanline_aa_solid_ptr;
600             fillColor_ : boolean ); overload;
601 
602  procedure Agg2DRenderer_render(
603             gr : Agg2D_ptr;
604             renBase : renderer_base_ptr;
605             renSolid : renderer_scanline_aa_solid_ptr;
606             ras : gray8_adaptor_type_ptr;
607             sl : gray8_scanline_type_ptr ); overload;
608 
609  procedure Agg2DRenderer_renderImage(
610             gr : Agg2D_ptr;
611             img : Image_ptr;
612             renBase : renderer_base_ptr;
613             interpolator : span_interpolator_linear_ptr );
614 
Agg2DUsesFreeTypenull615  function  Agg2DUsesFreeType : boolean;
Agg2DUsesWin32TrueTypenull616  function  Agg2DUsesWin32TrueType : boolean;
617 
618 IMPLEMENTATION
619 { LOCAL VARIABLES & CONSTANTS }
620 var
621  g_approxScale : double = 2.0;
622 
623 { UNIT IMPLEMENTATION }
624 { CONSTRUCT }
625 constructor Image.Construct;
626 begin
627 end;
628 
629 { CONSTRUCT }
630 constructor Image.Construct(buf : int8u_ptr; width_ ,height_ : unsigned; stride : int );
631 begin
632  renBuf.Construct(buf ,width_ ,height_ ,stride );
633 
634 end;
635 
636 { DESTRUCT }
637 destructor Image.Destruct;
638 begin
639  renBuf.Destruct;
640 
641 end;
642 
643 { ATTACH }
644 procedure Image.attach(buf : int8u_ptr; width_ ,height_ : unsigned; stride : int );
645 begin
646  renBuf.attach(buf ,width_ ,height_ ,stride );
647 
648 end;
649 
650 { WIDTH }
Image.widthnull651 function Image.width : int;
652 begin
653  result:=renBuf._width;
654 
655 end;
656 
657 { HEIGHT }
Image.heightnull658 function Image.height : int;
659 begin
660  result:=renBuf._height;
661 
662 end;
663 
664 { PREMULTIPLY }
665 procedure Image.premultiply;
666 //var
667  //pixf : pixel_formats;
668 
669 begin
670 { pixfmt_rgba32(pixf ,@renBuf );
671 
672  pixf.premultiply; }
673 
674 end;
675 
676 { DEMULTIPLY }
677 procedure Image.demultiply;
678 //var
679  //pixf : pixel_formats;
680 
681 begin
682 { pixfmt_rgba32(pixf ,@renBuf );
683 
684  pixf.demultiply; }
685 
686 end;
687 
688 { CONSTRUCT }
689 constructor Agg2DRasterizerGamma.Construct(alpha ,gamma : double );
690 begin
691  m_alpha.Construct(alpha );
692  m_gamma.Construct(gamma );
693 
694 end;
695 
696 { FUNC_OPERATOR_GAMMA }
Agg2DRasterizerGamma.func_operator_gammanull697 function Agg2DRasterizerGamma.func_operator_gamma(x : double ) : double;
698 begin
699  result:=m_alpha.func_operator_gamma(m_gamma.func_operator_gamma(x ) );
700 
701 end;
702 
703 { CONSTRUCT }
704 constructor Agg2D.Construct;
705 begin
706  m_rbuf.Construct;
707 
708  pixfmt_rgba32           (m_pixFormat ,@m_rbuf );
709  pixfmt_custom_blend_rgba(m_pixFormatComp ,@m_rbuf ,@comp_op_adaptor_rgba ,rgba_order );
710  pixfmt_rgba32           (m_pixFormatPre ,@m_rbuf );
711  pixfmt_custom_blend_rgba(m_pixFormatCompPre ,@m_rbuf ,@comp_op_adaptor_rgba ,rgba_order );
712 
713  m_renBase.Construct       (@m_pixFormat );
714  m_renBaseComp.Construct   (@m_pixFormatComp );
715  m_renBasePre.Construct    (@m_pixFormatPre );
716  m_renBaseCompPre.Construct(@m_pixFormatCompPre );
717 
718  m_renSolid.Construct    (@m_renBase );
719  m_renSolidComp.Construct(@m_renBaseComp );
720 
721  m_allocator.Construct;
722  m_clipBox.Construct(0 ,0 ,0 ,0 );
723 
724  m_blendMode     :=BlendAlpha;
725  m_imageBlendMode:=BlendDst;
726 
727  m_imageBlendColor.Construct(0 ,0 ,0 );
728 
729  m_scanline.Construct;
730  m_rasterizer.Construct;
731 
732  m_masterAlpha   :=1.0;
733  m_antiAliasGamma:=1.0;
734 
735  m_fillColor.Construct(255 ,255 ,255 );
736  m_lineColor.Construct(0   ,0   ,0 );
737 
738  m_fillGradient.Construct(256 ,sizeof(aggclr ) );
739  m_lineGradient.Construct(256 ,sizeof(aggclr ) );
740 
741  m_lineCap :=CapRound;
742  m_lineJoin:=JoinRound;
743 
744  m_fillGradientFlag:=Solid;
745  m_lineGradientFlag:=Solid;
746 
747  m_fillGradientMatrix.Construct;
748  m_lineGradientMatrix.Construct;
749 
750  m_fillGradientD1:=0.0;
751  m_lineGradientD1:=0.0;
752  m_fillGradientD2:=100.0;
753  m_lineGradientD2:=100.0;
754 
755  m_textAngle  :=0.0;
756  m_textAlignX :=AlignLeft;
757  m_textAlignY :=AlignBottom;
758  m_textHints  :=true;
759  m_fontHeight :=0.0;
760  m_fontAscent :=0.0;
761  m_fontDescent:=0.0;
762 
763  m_fontCacheType:=RasterFontCache;
764  m_imageFilter  :=Bilinear;
765  m_imageResample:=NoResample;
766 
767  m_gammaNone.Construct;
768 
769  m_ifBilinear.Construct;
770  m_ifHanning.Construct;
771  m_ifHermite.Construct;
772  m_ifQuadric.Construct;
773  m_ifBicubic.Construct;
774  m_ifCatrom.Construct;
775  m_ifSpline16.Construct;
776  m_ifSpline36.Construct;
777  m_ifBlackman144.Construct;
778 
779  m_imageFilterLut.Construct(@m_ifBilinear ,true );
780 
781  m_linearGradientFunction.Construct;
782  m_radialGradientFunction.Construct;
783 
784  m_fillGradientInterpolator.Construct(@m_fillGradientMatrix );
785  m_lineGradientInterpolator.Construct(@m_lineGradientMatrix );
786 
787  m_lineWidth  :=1;
788  m_evenOddFlag:=false;
789 
790  m_path.Construct;
791  m_transform.Construct;
792 
793  m_convCurve.Construct (@m_path );
794  m_convStroke.Construct(@m_convCurve );
795 
796  m_pathTransform.Construct  (@m_convCurve ,@m_transform );
797  m_strokeTransform.Construct(@m_convStroke ,@m_transform );
798 
799 {$IFDEF AGG2D_USE_FREETYPE }
800  m_fontEngine.Construct;
801 {$ENDIF }
802 {$IFDEF AGG2D_USE_WINFONTS}
803  m_fontDC:=GetDC(0 );
804  m_fontEngine.Construct(m_fontDC );
805 {$ENDIF }
806 {$IFNDEF AGG2D_NO_FONT}
807  m_fontCacheManager.Construct(@m_fontEngine );
808 {$ENDIF}
809 
810  lineCap (m_lineCap );
811  lineJoin(m_lineJoin );
812 
813 end;
814 
815 { DESTRUCT }
816 destructor Agg2D.Destruct;
817 begin
818  m_rbuf.Destruct;
819 
820  m_allocator.Destruct;
821 
822  m_scanline.Destruct;
823  m_rasterizer.Destruct;
824 
825  m_fillGradient.Destruct;
826  m_lineGradient.Destruct;
827 
828  m_imageFilterLut.Destruct;
829  m_path.Destruct;
830 
831  m_convCurve.Destruct;
832  m_convStroke.Destruct;
833 
834 {$IFNDEF AGG2D_NO_FONT}
835  m_fontEngine.Destruct;
836  m_fontCacheManager.Destruct;
837 {$ENDIF}
838 {$IFDEF AGG2D_USE_WINFONTS }
839  ReleaseDC(0 ,m_fontDC );
840 {$ENDIF }
841 
842 end;
843 
844 { ATTACH }
845 procedure Agg2D.attach(buf : int8u_ptr; width_ ,height_ : unsigned; stride : int );
846 begin
847  m_rbuf.attach(buf ,width_ ,height_ ,stride );
848 
849  m_renBase.reset_clipping       (true );
850  m_renBaseComp.reset_clipping   (true );
851  m_renBasePre.reset_clipping    (true );
852  m_renBaseCompPre.reset_clipping(true );
853 
854  resetTransformations;
855 
856  lineWidth(1.0 );
857  lineColor(0   ,0   ,0 );
858  fillColor(255 ,255 ,255 );
859 
860  textAlignment(AlignLeft ,AlignBottom );
861 
862  clipBox (0 ,0 ,width_ ,height_ );
863  lineCap (CapRound );
864  lineJoin(JoinRound );
865  flipText(false );
866 
867  imageFilter  (Bilinear );
868  imageResample(NoResample );
869 
870  m_masterAlpha   :=1.0;
871  m_antiAliasGamma:=1.0;
872 
873  m_rasterizer.gamma(@m_gammaNone );
874 
875  m_blendMode:=BlendAlpha;
876 
877 end;
878 
879 { ATTACH }
880 procedure Agg2D.attach(img : Image_ptr );
881 begin
882  attach(img.renBuf._buf ,img.renBuf._width ,img.renBuf._height ,img.renBuf._stride );
883 
884 end;
885 
886 { CLIPBOX }
887 procedure Agg2D.clipBox(x1 ,y1 ,x2 ,y2 : double );
888 var
889  rx1 ,ry1 ,rx2 ,ry2 : int;
890 
891 begin
892  m_clipBox.Construct(x1 ,y1 ,x2 ,y2 );
893 
894  rx1:=Trunc(x1 );
895  ry1:=Trunc(y1 );
896  rx2:=Trunc(x2 );
897  ry2:=Trunc(y2 );
898 
899  m_renBase.clip_box_       (rx1 ,ry1 ,rx2 ,ry2 );
900  m_renBaseComp.clip_box_   (rx1 ,ry1 ,rx2 ,ry2 );
901  m_renBasePre.clip_box_    (rx1 ,ry1 ,rx2 ,ry2 );
902  m_renBaseCompPre.clip_box_(rx1 ,ry1 ,rx2 ,ry2 );
903 
904  m_rasterizer.clip_box(x1 ,y1 ,x2 ,y2 );
905 
906 end;
907 
908 { CLIPBOX }
Agg2D.clipBoxnull909 function Agg2D.clipBox : RectD;
910 begin
911  result:=m_clipBox;
912 
913 end;
914 
915 { CLEARALL }
916 procedure Agg2D.clearAll(c : Color );
917 var
918  clr : aggclr;
919 
920 begin
921  clr.Construct  (c );
922  m_renBase.clear(@clr );
923 
924 end;
925 
926 { CLEARALL }
927 procedure Agg2D.clearAll(r ,g ,b : unsigned; a : unsigned = 255 );
928 var
929  clr : Color;
930 
931 begin
932  clr.Construct(r ,g ,b ,a );
933  clearAll     (clr );
934 
935 end;
936 
937 procedure Agg2D.FillAll(c: Color);
938 var
939   clr: aggclr;
940 begin
941   clr.Construct  (c );
942   m_renBase.fill(@clr );
943 end;
944 
945 procedure Agg2D.FillAll(r, g, b: byte; a: byte);
946 var
947   clr: Color;
948 begin
949   clr.Construct(r, g, b, a);
950   FillAll(clr);
951 end;
952 
953 { CLEARCLIPBOX }
954 procedure Agg2D.clearClipBox(c : Color );
955 var
956  clr : aggclr;
957 
958 begin
959  clr.Construct(c );
960 
961  m_renBase.copy_bar(0 ,0 ,m_renBase.width ,m_renBase.height ,@clr );
962 
963 end;
964 
965 { CLEARCLIPBOX }
966 procedure Agg2D.clearClipBox(r ,g ,b : unsigned; a : unsigned = 255 );
967 var
968  clr : Color;
969 
970 begin
971  clr.Construct(r ,g ,b ,a );
972  clearClipBox (clr );
973 
974 end;
975 
976 { WORLDTOSCREEN }
977 procedure Agg2D.worldToScreen(x ,y : double_ptr );
978 begin
979  m_transform.transform(@m_transform ,x ,y );
980 
981 end;
982 
983 { SCREENTOWORLD }
984 procedure Agg2D.screenToWorld(x ,y : double_ptr );
985 begin
986  m_transform.inverse_transform(@m_transform ,x ,y );
987 
988 end;
989 
990 { WORLDTOSCREEN }
Agg2D.worldToScreennull991 function Agg2D.worldToScreen(scalar : double ) : double;
992 var
993  x1 ,y1 ,x2 ,y2 : double;
994 
995 begin
996  x1:=0;
997  y1:=0;
998  x2:=scalar;
999  y2:=scalar;
1000 
1001  worldToScreen(@x1 ,@y1 );
1002  worldToScreen(@x2 ,@y2 );
1003 
1004  result:=Sqrt((x2 - x1 ) * (x2 - x1 ) + (y2 - y1 ) * (y2 - y1 ) ) * 0.7071068;
1005 
1006 end;
1007 
1008 { SCREENTOWORLD }
Agg2D.screenToWorldnull1009 function Agg2D.screenToWorld(scalar : double ) : double;
1010 var
1011  x1 ,y1 ,x2 ,y2 : double;
1012 
1013 begin
1014  x1:=0;
1015  y1:=0;
1016  x2:=scalar;
1017  y2:=scalar;
1018 
1019  screenToWorld(@x1 ,@y1 );
1020  screenToWorld(@x2 ,@y2 );
1021 
1022  result:=Sqrt((x2 - x1 ) * (x2 - x1 ) + (y2 - y1 ) * (y2 - y1 ) ) * 0.7071068;
1023 
1024 end;
1025 
1026 { ALIGNPOINT }
1027 procedure Agg2D.alignPoint(x ,y : double_ptr );
1028 begin
1029  worldToScreen(x ,y );
1030 
1031  x^:=Floor(x^ ) + 0.5;
1032  y^:=Floor(y^ ) + 0.5;
1033 
1034  screenToWorld(x ,y );
1035 
1036 end;
1037 
1038 { INBOX }
Agg2D.inBoxnull1039 function Agg2D.inBox(worldX ,worldY : double ) : boolean;
1040 begin
1041  worldToScreen(@worldX ,@worldY );
1042 
1043  result:=m_renBase.inbox(Trunc(worldX ) ,Trunc(worldY ) );
1044 
1045 end;
1046 
1047 { BLENDMODE }
1048 procedure Agg2D.blendMode(m : BlendMode_ );
1049 begin
1050  m_blendMode:=m;
1051 
1052  m_pixFormatComp.comp_op_   (unsigned(m ) );
1053  m_pixFormatCompPre.comp_op_(unsigned(m ) );
1054 
1055 end;
1056 
1057 { BLENDMODE }
Agg2D.blendModenull1058 function Agg2D.blendMode : BlendMode_;
1059 begin
1060  result:=m_blendMode;
1061 
1062 end;
1063 
1064 { IMAGEBLENDMODE }
1065 procedure Agg2D.imageBlendMode(m : BlendMode_ );
1066 begin
1067  m_imageBlendMode:=m;
1068 
1069 end;
1070 
1071 { IMAGEBLENDMODE }
Agg2D.imageBlendModenull1072 function Agg2D.imageBlendMode : BlendMode_;
1073 begin
1074  result:=m_imageBlendMode;
1075 
1076 end;
1077 
1078 { IMAGEBLENDCOLOR }
1079 procedure Agg2D.imageBlendColor(c : Color );
1080 begin
1081  m_imageBlendColor:=c;
1082 
1083 end;
1084 
1085 { IMAGEBLENDCOLOR }
1086 procedure Agg2D.imageBlendColor(r ,g ,b : unsigned; a : unsigned = 255 );
1087 var
1088  clr : Color;
1089 
1090 begin
1091  clr.Construct  (r ,g ,b ,a );
1092  imageBlendColor(clr );
1093 
1094 end;
1095 
1096 { IMAGEBLENDCOLOR }
Agg2D.imageBlendColornull1097 function Agg2D.imageBlendColor : Color;
1098 begin
1099  result:=m_imageBlendColor;
1100 
1101 end;
1102 
1103 { MASTERALPHA }
1104 procedure Agg2D.masterAlpha(a : double );
1105 begin
1106  m_masterAlpha:=a;
1107 
1108  updateRasterizerGamma;
1109 
1110 end;
1111 
1112 { MASTERALPHA }
Agg2D.masterAlphanull1113 function Agg2D.masterAlpha : double;
1114 begin
1115  result:=m_masterAlpha;
1116 
1117 end;
1118 
1119 { ANTIALIASGAMMA }
1120 procedure Agg2D.antiAliasGamma(g : double );
1121 begin
1122  m_antiAliasGamma:=g;
1123 
1124  updateRasterizerGamma;
1125 
1126 end;
1127 
1128 { ANTIALIASGAMMA }
Agg2D.antiAliasGammanull1129 function Agg2D.antiAliasGamma : double;
1130 begin
1131  result:=m_antiAliasGamma;
1132 
1133 end;
1134 
1135 { FILLCOLOR }
1136 procedure Agg2D.fillColor(c : Color );
1137 begin
1138  m_fillColor       :=c;
1139  m_fillGradientFlag:=Solid;
1140 
1141 end;
1142 
1143 { FILLCOLOR }
1144 procedure Agg2D.fillColor(r ,g ,b : unsigned; a : unsigned = 255 );
1145 var
1146  clr : Color;
1147 
1148 begin
1149  clr.Construct(r ,g ,b ,a );
1150  fillColor    (clr );
1151 
1152 end;
1153 
1154 { NOFILL }
1155 procedure Agg2D.noFill;
1156 var
1157  clr : Color;
1158 
1159 begin
1160  clr.Construct(0 ,0 ,0 ,0 );
1161  fillColor    (clr );
1162 
1163 end;
1164 
1165 { LINECOLOR }
1166 procedure Agg2D.lineColor(c : Color );
1167 begin
1168  m_lineColor       :=c;
1169  m_lineGradientFlag:=Solid;
1170 
1171 end;
1172 
1173 { LINECOLOR }
1174 procedure Agg2D.lineColor(r ,g ,b : unsigned; a : unsigned = 255 );
1175 var
1176  clr : Color;
1177 
1178 begin
1179  clr.Construct(r ,g ,b ,a );
1180  lineColor    (clr );
1181 
1182 end;
1183 
1184 { NOLINE }
1185 procedure Agg2D.noLine;
1186 var
1187  clr : Color;
1188 
1189 begin
1190  clr.Construct(0 ,0 ,0 ,0 );
1191  lineColor    (clr );
1192 
1193 end;
1194 
1195 { FILLCOLOR }
Agg2D.fillColornull1196 function Agg2D.fillColor : Color;
1197 begin
1198  result:=m_fillColor;
1199 
1200 end;
1201 
1202 { LINECOLOR }
Agg2D.lineColornull1203 function Agg2D.lineColor : Color;
1204 begin
1205  result:=m_lineColor;
1206 
1207 end;
1208 
1209 { FILLLINEARGRADIENT }
1210 procedure Agg2D.fillLinearGradient(x1 ,y1 ,x2 ,y2 : double; c1 ,c2 : Color; profile : double = 1.0 );
1211 var
1212  i ,startGradient ,endGradient : int;
1213 
1214  k ,angle : double;
1215 
1216  c : Color;
1217 
1218  clr : aggclr;
1219  tar : trans_affine_rotation;
1220  tat : trans_affine_translation;
1221 
1222 begin
1223  startGradient:=128 - Trunc(profile * 127.0 );
1224  endGradient  :=128 + Trunc(profile * 127.0 );
1225 
1226  if endGradient <= startGradient then
1227   endGradient:=startGradient + 1;
1228 
1229  k:=1.0 / (endGradient - startGradient );
1230  i:=0;
1231 
1232  while i < startGradient do
1233   begin
1234    clr.Construct(c1 );
1235 
1236    move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
1237    inc (i );
1238 
1239   end;
1240 
1241  while i < endGradient do
1242   begin
1243    c:=c1.gradient(c2 ,(i - startGradient ) * k );
1244 
1245    clr.Construct(c );
1246 
1247    move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
1248    inc (i );
1249 
1250   end;
1251 
1252  while i < 256 do
1253   begin
1254    clr.Construct(c2 );
1255 
1256    move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
1257    inc (i );
1258 
1259   end;
1260 
1261  angle:=ArcTan2(y2 - y1 ,x2 - x1 );
1262 
1263  m_fillGradientMatrix.reset;
1264 
1265  tar.Construct(angle );
1266 
1267  m_fillGradientMatrix.multiply(@tar );
1268 
1269  tat.Construct(x1 ,y1 );
1270 
1271  m_fillGradientMatrix.multiply(@tat );
1272  m_fillGradientMatrix.multiply(@m_transform );
1273  m_fillGradientMatrix.invert;
1274 
1275  m_fillGradientD1  :=0.0;
1276  m_fillGradientD2  :=Sqrt((x2 - x1 ) * (x2 - x1 ) + (y2 - y1 ) * (y2 - y1 ) );
1277  m_fillGradientFlag:=Linear;
1278 
1279  m_fillColor.Construct(0 ,0 ,0 );  // Set some real color
1280 
1281 end;
1282 
1283 { LINELINEARGRADIENT }
1284 procedure Agg2D.lineLinearGradient(x1 ,y1 ,x2 ,y2 : double; c1 ,c2 : Color; profile : double = 1.0 );
1285 var
1286  i ,startGradient ,endGradient : int;
1287 
1288  k ,angle : double;
1289 
1290  c : Color;
1291 
1292  clr : aggclr;
1293  tar : trans_affine_rotation;
1294  tat : trans_affine_translation;
1295 
1296 begin
1297  startGradient:=128 - Trunc(profile * 128.0 );
1298  endGradient  :=128 + Trunc(profile * 128.0 );
1299 
1300  if endGradient <= startGradient then
1301   endGradient:=startGradient + 1;
1302 
1303  k:=1.0 / (endGradient - startGradient );
1304  i:=0;
1305 
1306  while i < startGradient do
1307   begin
1308    clr.Construct(c1 );
1309 
1310    move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
1311    inc (i );
1312 
1313   end;
1314 
1315  while i < endGradient do
1316   begin
1317    c:=c1.gradient(c2 ,(i - startGradient) * k );
1318 
1319    clr.Construct(c );
1320 
1321    move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
1322    inc (i );
1323 
1324   end;
1325 
1326  while i < 256 do
1327   begin
1328    clr.Construct(c2 );
1329 
1330    move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
1331    inc (i );
1332 
1333   end;
1334 
1335  angle:=ArcTan2(y2 - y1 ,x2 - x1 );
1336 
1337  m_lineGradientMatrix.reset;
1338 
1339  tar.Construct(angle );
1340 
1341  m_lineGradientMatrix.multiply(@tar );
1342 
1343  tat.Construct(x1 ,y1 );
1344 
1345  m_lineGradientMatrix.multiply(@tat );
1346  m_lineGradientMatrix.multiply(@m_transform ); {!}
1347  m_lineGradientMatrix.invert;
1348 
1349  m_lineGradientD1  :=0.0;
1350  m_lineGradientD2  :=Sqrt((x2 - x1 ) * (x2 - x1 ) + (y2 - y1 ) * (y2 - y1 ) );
1351  m_lineGradientFlag:=Linear;
1352 
1353  m_lineColor.Construct(0 ,0 ,0 );  // Set some real color
1354 
1355 end;
1356 
1357 { FILLRADIALGRADIENT }
1358 procedure Agg2D.fillRadialGradient(x ,y ,r : double; c1 ,c2 : Color; profile : double = 1.0 );
1359 var
1360  i ,startGradient ,endGradient : int;
1361 
1362  k : double;
1363  c : Color;
1364 
1365  clr : aggclr;
1366  tat : trans_affine_translation;
1367 
1368 begin
1369  startGradient:=128 - Trunc(profile * 127.0 );
1370  endGradient  :=128 + Trunc(profile * 127.0 );
1371 
1372  if endGradient <= startGradient then
1373   endGradient:=startGradient + 1;
1374 
1375  k:=1.0 / (endGradient - startGradient );
1376  i:=0;
1377 
1378  while i < startGradient do
1379   begin
1380    clr.Construct(c1 );
1381 
1382    move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
1383    inc (i );
1384 
1385   end;
1386 
1387  while i < endGradient do
1388   begin
1389    c:=c1.gradient(c2 ,(i - startGradient ) * k );
1390 
1391    clr.Construct(c );
1392 
1393    move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
1394    inc (i );
1395 
1396   end;
1397 
1398  while i < 256 do
1399   begin
1400    clr.Construct(c2 );
1401 
1402    move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
1403    inc (i );
1404 
1405   end;
1406 
1407  m_fillGradientD2:=worldToScreen(r );
1408 
1409  worldToScreen(@x ,@y );
1410 
1411  m_fillGradientMatrix.reset;
1412 
1413  tat.Construct(x ,y );
1414 
1415  m_fillGradientMatrix.multiply(@tat );
1416  m_fillGradientMatrix.invert;
1417 
1418  m_fillGradientD1  :=0;
1419  m_fillGradientFlag:=Radial;
1420 
1421  m_fillColor.Construct(0 ,0 ,0 );  // Set some real color
1422 
1423 end;
1424 
1425 { LINERADIALGRADIENT }
1426 procedure Agg2D.lineRadialGradient(x ,y ,r : double; c1 ,c2 : Color; profile : double = 1.0 );
1427 var
1428  i ,startGradient ,endGradient : int;
1429 
1430  k : double;
1431  c : Color;
1432 
1433  clr : aggclr;
1434  tat : trans_affine_translation;
1435 
1436 begin
1437  startGradient:=128 - Trunc(profile * 128.0 );
1438  endGradient  :=128 + Trunc(profile * 128.0 );
1439 
1440  if endGradient <= startGradient then
1441   endGradient:=startGradient + 1;
1442 
1443  k:=1.0 / (endGradient - startGradient );
1444  i:=0;
1445 
1446  while i < startGradient do
1447   begin
1448    clr.Construct(c1 );
1449 
1450    move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
1451    inc (i );
1452 
1453   end;
1454 
1455  while i < endGradient do
1456   begin
1457    c:=c1.gradient(c2 ,(i - startGradient ) * k );
1458 
1459    clr.Construct(c );
1460 
1461    move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
1462    inc (i );
1463 
1464   end;
1465 
1466  while i < 256 do
1467   begin
1468    clr.Construct(c2 );
1469 
1470    move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
1471    inc (i );
1472 
1473   end;
1474 
1475  m_lineGradientD2:=worldToScreen(r );
1476 
1477  worldToScreen(@x ,@y );
1478 
1479  m_lineGradientMatrix.reset;
1480 
1481  tat.Construct(x ,y );
1482 
1483  m_lineGradientMatrix.multiply(@tat );
1484  m_lineGradientMatrix.invert;
1485 
1486  m_lineGradientD1  :=0;
1487  m_lineGradientFlag:=Radial;
1488 
1489  m_lineColor.Construct(0 ,0 ,0 );  // Set some real color
1490 
1491 end;
1492 
1493 { FILLRADIALGRADIENT }
1494 procedure Agg2D.fillRadialGradient(x ,y ,r : double; c1 ,c2 ,c3 : Color );
1495 var
1496  i : int;
1497  c : Color;
1498 
1499  clr : aggclr;
1500  tat : trans_affine_translation;
1501 
1502 begin
1503  i:=0;
1504 
1505  while i < 128 do
1506   begin
1507    c:=c1.gradient(c2 ,i / 127.0 );
1508 
1509    clr.Construct(c );
1510 
1511    move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
1512    inc (i );
1513 
1514   end;
1515 
1516  while i < 256 do
1517   begin
1518    c:=c2.gradient(c3 ,(i - 128 ) / 127.0 );
1519 
1520    clr.Construct(c );
1521 
1522    move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
1523    inc (i );
1524 
1525   end;
1526 
1527  m_fillGradientD2:=worldToScreen(r );
1528 
1529  worldToScreen(@x ,@y );
1530 
1531  m_fillGradientMatrix.reset;
1532 
1533  tat.Construct(x ,y );
1534 
1535  m_fillGradientMatrix.multiply(@tat );
1536  m_fillGradientMatrix.invert;
1537 
1538  m_fillGradientD1  :=0;
1539  m_fillGradientFlag:=Radial;
1540 
1541  m_fillColor.Construct(0 ,0 ,0 ); // Set some real color
1542 
1543 end;
1544 
1545 { LINERADIALGRADIENT }
1546 procedure Agg2D.lineRadialGradient(x ,y ,r : double; c1 ,c2 ,c3 : Color );
1547 var
1548  i : int;
1549  c : Color;
1550 
1551  clr : aggclr;
1552  tat : trans_affine_translation;
1553 
1554 begin
1555  i:=0;
1556 
1557  while i < 128 do
1558   begin
1559    c:=c1.gradient(c2 ,i / 127.0 );
1560 
1561    clr.Construct(c );
1562 
1563    move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
1564    inc (i );
1565 
1566   end;
1567 
1568  while i < 256 do
1569   begin
1570    c:=c2.gradient(c3 ,(i - 128 ) / 127.0 );
1571 
1572    clr.Construct(c );
1573 
1574    move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
1575    inc (i );
1576 
1577   end;
1578 
1579  m_lineGradientD2:=worldToScreen(r );
1580 
1581  worldToScreen(@x ,@y );
1582 
1583  m_lineGradientMatrix.reset;
1584 
1585  tat.Construct(x ,y );
1586 
1587  m_lineGradientMatrix.multiply(@tat );
1588  m_lineGradientMatrix.invert;
1589 
1590  m_lineGradientD1  :=0;
1591  m_lineGradientFlag:=Radial;
1592 
1593  m_lineColor.Construct(0 ,0 ,0 ); // Set some real color
1594 
1595 end;
1596 
1597 { FILLRADIALGRADIENT }
1598 procedure Agg2D.fillRadialGradient(x ,y ,r : double );
1599 var
1600  tat : trans_affine_translation;
1601 
1602 begin
1603  m_fillGradientD2:=worldToScreen(r );
1604 
1605  worldToScreen(@x ,@y );
1606 
1607  m_fillGradientMatrix.reset;
1608 
1609  tat.Construct(x ,y );
1610 
1611  m_fillGradientMatrix.multiply(@tat );
1612  m_fillGradientMatrix.invert;
1613 
1614  m_fillGradientD1:=0;
1615 
1616 end;
1617 
1618 { LINERADIALGRADIENT }
1619 procedure Agg2D.lineRadialGradient(x ,y ,r : double );
1620 var
1621  tat : trans_affine_translation;
1622 
1623 begin
1624  m_lineGradientD2:=worldToScreen(r );
1625 
1626  worldToScreen(@x ,@y );
1627 
1628  m_lineGradientMatrix.reset;
1629 
1630  tat.Construct(x ,y );
1631 
1632  m_lineGradientMatrix.multiply(@tat );
1633  m_lineGradientMatrix.invert;
1634 
1635  m_lineGradientD1:=0;
1636 
1637 end;
1638 
1639 { LINEWIDTH }
1640 procedure Agg2D.lineWidth(w : double );
1641 begin
1642  m_lineWidth:=w;
1643 
1644  m_convStroke.width_(w );
1645 
1646 end;
1647 
1648 { LINEWIDTH_ }
Agg2D.lineWidth_null1649 function Agg2D.lineWidth_(w : double ) : double;
1650 begin
1651  result:=m_lineWidth;
1652 
1653 end;
1654 
1655 { LINECAP }
1656 procedure Agg2D.lineCap(cap : LineCap_ );
1657 begin
1658  m_lineCap:=cap;
1659 
1660  m_convStroke.line_cap_(cap );
1661 
1662 end;
1663 
1664 { LINECAP }
Agg2D.lineCapnull1665 function Agg2D.lineCap : LineCap_;
1666 begin
1667  result:=m_lineCap;
1668 
1669 end;
1670 
1671 { LINEJOIN }
1672 procedure Agg2D.lineJoin(join : LineJoin_ );
1673 begin
1674  m_lineJoin:=join;
1675 
1676  m_convStroke.line_join_(join );
1677 
1678 end;
1679 
1680 { LINEJOIN }
Agg2D.lineJoinnull1681 function Agg2D.lineJoin : LineJoin_;
1682 begin
1683  result:=m_lineJoin;
1684 
1685 end;
1686 
1687 { FILLEVENODD }
1688 procedure Agg2D.fillEvenOdd(evenOddFlag : boolean );
1689 begin
1690  m_evenOddFlag:=evenOddFlag;
1691 
1692  if evenOddFlag then
1693   m_rasterizer.filling_rule(fill_even_odd )
1694  else
1695   m_rasterizer.filling_rule(fill_non_zero );
1696 
1697 end;
1698 
1699 { FILLEVENODD }
Agg2D.fillEvenOddnull1700 function Agg2D.fillEvenOdd : boolean;
1701 begin
1702  result:=m_evenOddFlag;
1703 
1704 end;
1705 
1706 { TRANSFORMATIONS }
Agg2D.transformationsnull1707 function Agg2D.transformations : Transformations_;
1708 begin
1709  m_transform.store_to(@result.affineMatrix[0 ] );
1710 
1711 end;
1712 
1713 { TRANSFORMATIONS }
1714 procedure Agg2D.transformations(tr : Transformations_ptr );
1715 begin
1716  m_transform.load_from(@tr.affineMatrix[0 ] );
1717 
1718  m_convCurve.approximation_scale_ (worldToScreen(1.0 ) * g_approxScale );
1719  m_convStroke.approximation_scale_(worldToScreen(1.0 ) * g_approxScale );
1720 
1721 end;
1722 
1723 { RESETTRANSFORMATIONS }
1724 procedure Agg2D.resetTransformations;
1725 begin
1726  m_transform.reset;
1727 
1728 end;
1729 
1730 { AFFINE }
1731 procedure Agg2D.affine(tr : Affine_ptr );
1732 begin
1733  m_transform.multiply(tr );
1734 
1735  m_convCurve.approximation_scale_ (worldToScreen(1.0 ) * g_approxScale );
1736  m_convStroke.approximation_scale_(worldToScreen(1.0 ) * g_approxScale );
1737 
1738 end;
1739 
1740 { AFFINE }
1741 procedure Agg2D.affine(tr : Transformations_ptr );
1742 var
1743  ta : trans_affine;
1744 
1745 begin
1746  ta.Construct(
1747   tr.affineMatrix[0 ] ,tr.affineMatrix[1 ] ,tr.affineMatrix[2 ] ,
1748   tr.affineMatrix[3 ] ,tr.affineMatrix[4 ] ,tr.affineMatrix[5 ] );
1749 
1750  affine(Affine_ptr(@ta ) );
1751 
1752 end;
1753 
1754 { ROTATE }
1755 procedure Agg2D.rotate(angle : double );
1756 var
1757  tar : trans_affine_rotation;
1758 
1759 begin
1760  tar.Construct(angle );
1761 
1762  m_transform.multiply(@tar );
1763 
1764 end;
1765 
1766 { SCALE }
1767 procedure Agg2D.scale(sx ,sy : double );
1768 var
1769  tas : trans_affine_scaling;
1770 
1771 begin
1772  tas.Construct(sx ,sy );
1773 
1774  m_transform.multiply(@tas );
1775 
1776  m_convCurve.approximation_scale_ (worldToScreen(1.0 ) * g_approxScale );
1777  m_convStroke.approximation_scale_(worldToScreen(1.0 ) * g_approxScale );
1778 
1779 end;
1780 
1781 { SKEW }
1782 procedure Agg2D.skew(sx ,sy : double );
1783 var
1784  tas : trans_affine_skewing;
1785 
1786 begin
1787  tas.Construct(sx ,sy );
1788 
1789  m_transform.multiply(@tas );
1790 
1791 end;
1792 
1793 { TRANSLATE }
1794 procedure Agg2D.translate(x ,y : double );
1795 var
1796  tat : trans_affine_translation;
1797 
1798 begin
1799  tat.Construct(x ,y );
1800 
1801  m_transform.multiply(@tat );
1802 
1803 end;
1804 
1805 { PARALLELOGRAM }
1806 procedure Agg2D.parallelogram(x1 ,y1 ,x2 ,y2 : double; para : double_ptr );
1807 var
1808  ta : trans_affine;
1809 
1810 begin
1811  ta.Construct(x1 ,y1 ,x2 ,y2 ,parallelo_ptr(para ) );
1812 
1813  m_transform.multiply(@ta );
1814 
1815  m_convCurve.approximation_scale_ (worldToScreen(1.0 ) * g_approxScale );
1816  m_convStroke.approximation_scale_(worldToScreen(1.0 ) * g_approxScale );
1817 
1818 end;
1819 
1820 { VIEWPORT }
1821 procedure Agg2D.viewport(
1822            worldX1  ,worldY1  ,worldX2  ,worldY2 ,
1823            screenX1 ,screenY1 ,screenX2 ,screenY2 : double;
1824            opt : ViewportOption = XMidYMid );
1825 var
1826  vp : trans_viewport;
1827  mx : trans_affine;
1828 
1829 begin
1830  vp.Construct;
1831 
1832  case opt of
1833   Anisotropic :
1834    vp.preserve_aspect_ratio(0.0 ,0.0 ,aspect_ratio_stretch );
1835 
1836   XMinYMin :
1837    vp.preserve_aspect_ratio(0.0 ,0.0 ,aspect_ratio_meet );
1838 
1839   XMidYMin :
1840    vp.preserve_aspect_ratio(0.5 ,0.0 ,aspect_ratio_meet );
1841 
1842   XMaxYMin :
1843    vp.preserve_aspect_ratio(1.0 ,0.0 ,aspect_ratio_meet );
1844 
1845   XMinYMid :
1846    vp.preserve_aspect_ratio(0.0 ,0.5 ,aspect_ratio_meet );
1847 
1848   XMidYMid :
1849    vp.preserve_aspect_ratio(0.5 ,0.5 ,aspect_ratio_meet );
1850 
1851   XMaxYMid :
1852    vp.preserve_aspect_ratio(1.0 ,0.5 ,aspect_ratio_meet );
1853 
1854   XMinYMax :
1855    vp.preserve_aspect_ratio(0.0 ,1.0 ,aspect_ratio_meet );
1856 
1857   XMidYMax :
1858    vp.preserve_aspect_ratio(0.5 ,1.0 ,aspect_ratio_meet );
1859 
1860   XMaxYMax :
1861    vp.preserve_aspect_ratio(1.0 ,1.0 ,aspect_ratio_meet );
1862 
1863  end;
1864 
1865  vp.world_viewport (worldX1  ,worldY1  ,worldX2  ,worldY2 );
1866  vp.device_viewport(screenX1 ,screenY1 ,screenX2 ,screenY2 );
1867 
1868  mx.Construct;
1869 
1870  vp.to_affine        (@mx );
1871  m_transform.multiply(@mx );
1872 
1873  m_convCurve.approximation_scale_ (worldToScreen(1.0 ) * g_approxScale );
1874  m_convStroke.approximation_scale_(worldToScreen(1.0 ) * g_approxScale );
1875 
1876 end;
1877 
1878 { LINE }
1879 procedure Agg2D.line(x1 ,y1 ,x2 ,y2 : double );
1880 begin
1881  m_path.remove_all;
1882 
1883  addLine (x1 ,y1 ,x2 ,y2 );
1884  drawPath(StrokeOnly );
1885 
1886 end;
1887 
1888 { TRIANGLE }
1889 procedure Agg2D.triangle(x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double );
1890 begin
1891  m_path.remove_all;
1892  m_path.move_to(x1 ,y1 );
1893  m_path.line_to(x2 ,y2 );
1894  m_path.line_to(x3 ,y3 );
1895  m_path.close_polygon;
1896 
1897  drawPath(FillAndStroke );
1898 
1899 end;
1900 
1901 { RECTANGLE }
1902 procedure Agg2D.rectangle(x1 ,y1 ,x2 ,y2 : double );
1903 begin
1904  m_path.remove_all;
1905  m_path.move_to(x1 ,y1 );
1906  m_path.line_to(x2 ,y1 );
1907  m_path.line_to(x2 ,y2 );
1908  m_path.line_to(x1 ,y2 );
1909  m_path.close_polygon;
1910 
1911  drawPath(FillAndStroke );
1912 
1913 end;
1914 
1915 { ROUNDEDRECT }
1916 procedure Agg2D.roundedRect(x1 ,y1 ,x2 ,y2 ,r : double );
1917 var
1918  rc : rounded_rect;
1919 
1920 begin
1921  m_path.remove_all;
1922  rc.Construct(x1 ,y1 ,x2 ,y2 ,r );
1923 
1924  rc.normalize_radius;
1925  rc.approximation_scale_(worldToScreen(1.0 ) * g_approxScale );
1926 
1927  m_path.add_path(@rc ,0 ,false );
1928 
1929  drawPath(FillAndStroke );
1930 
1931 end;
1932 
1933 { ROUNDEDRECT }
1934 procedure Agg2D.roundedRect(x1 ,y1 ,x2 ,y2 ,rx ,ry : double );
1935 var
1936  rc : rounded_rect;
1937 
1938 begin
1939  m_path.remove_all;
1940  rc.Construct;
1941 
1942  rc.rect  (x1 ,y1 ,x2 ,y2 );
1943  rc.radius(rx ,ry );
1944  rc.normalize_radius;
1945 
1946  m_path.add_path(@rc ,0 ,false );
1947 
1948  drawPath(FillAndStroke );
1949 
1950 end;
1951 
1952 { ROUNDEDRECT }
1953 procedure Agg2D.roundedRect(
1954            x1 ,y1 ,x2 ,y2 ,
1955            rxBottom ,ryBottom ,
1956            rxTop ,ryTop : double );
1957 var
1958  rc : rounded_rect;
1959 
1960 begin
1961  m_path.remove_all;
1962  rc.Construct;
1963 
1964  rc.rect  (x1 ,y1 ,x2 ,y2 );
1965  rc.radius(rxBottom ,ryBottom ,rxTop ,ryTop );
1966  rc.normalize_radius;
1967 
1968  rc.approximation_scale_(worldToScreen(1.0 ) * g_approxScale );
1969 
1970  m_path.add_path(@rc ,0 ,false );
1971 
1972  drawPath(FillAndStroke );
1973 
1974 end;
1975 
1976 { ELLIPSE }
1977 procedure Agg2D.ellipse(cx ,cy ,rx ,ry : double );
1978 var
1979  el : bezier_arc;
1980 
1981 begin
1982  m_path.remove_all;
1983 
1984  el.Construct(cx ,cy ,rx ,ry ,0 ,2 * pi );
1985 
1986  m_path.add_path(@el ,0 ,false );
1987  m_path.close_polygon;
1988 
1989  drawPath(FillAndStroke );
1990 
1991 end;
1992 
1993 { ARC }
1994 procedure Agg2D.arc(cx ,cy ,rx ,ry ,start ,sweep : double );
1995 var
1996  ar : {bezier_}agg_arc.arc;
1997 
1998 begin
1999  m_path.remove_all;
2000 
2001  ar.Construct(cx ,cy ,rx ,ry ,start ,sweep ,false );
2002 
2003  m_path.add_path(@ar ,0 ,false );
2004 
2005  drawPath(StrokeOnly );
2006 
2007 end;
2008 
2009 { STAR }
2010 procedure Agg2D.star(cx ,cy ,r1 ,r2 ,startAngle : double; numRays : int );
2011 var
2012  da ,a ,x ,y : double;
2013 
2014  i : int;
2015 
2016 begin
2017  m_path.remove_all;
2018 
2019  da:=pi / numRays;
2020  a :=startAngle;
2021 
2022  i:=0;
2023 
2024  while i < numRays do
2025   begin
2026    x:=Cos(a ) * r2 + cx;
2027    y:=Sin(a ) * r2 + cy;
2028 
2029    if i <> 0 then
2030     m_path.line_to(x ,y )
2031    else
2032     m_path.move_to(x ,y );
2033 
2034    a:=a + da;
2035 
2036    m_path.line_to(Cos(a ) * r1 + cx ,Sin(a ) * r1 + cy );
2037 
2038    a:=a + da;
2039 
2040    inc(i );
2041 
2042   end;
2043 
2044  closePolygon;
2045  drawPath(FillAndStroke );
2046 
2047 end;
2048 
2049 { CURVE }
2050 procedure Agg2D.curve(x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double );
2051 begin
2052  m_path.remove_all;
2053  m_path.move_to(x1 ,y1 );
2054  m_path.curve3 (x2 ,y2 ,x3 ,y3 );
2055 
2056  drawPath(StrokeOnly );
2057 
2058 end;
2059 
2060 { CURVE }
2061 procedure Agg2D.curve(x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,x4 ,y4 : double );
2062 begin
2063  m_path.remove_all;
2064  m_path.move_to(x1 ,y1 );
2065  m_path.curve4 (x2 ,y2 ,x3 ,y3 ,x4 ,y4 );
2066 
2067  drawPath(StrokeOnly );
2068 
2069 end;
2070 
2071 { POLYGON }
2072 procedure Agg2D.polygon(xy : double_ptr; numPoints : int );
2073 begin
2074  m_path.remove_all;
2075  m_path.add_poly(double_2_ptr(xy ) ,numPoints );
2076 
2077  closePolygon;
2078  drawPath(FillAndStroke );
2079 
2080 end;
2081 
2082 { POLYLINE }
2083 procedure Agg2D.polyline(xy : double_ptr; numPoints : int );
2084 begin
2085  m_path.remove_all;
2086  m_path.add_poly(double_2_ptr(xy ) ,numPoints );
2087 
2088  drawPath(StrokeOnly );
2089 
2090 end;
2091 
2092 { FLIPTEXT }
2093 procedure Agg2D.flipText(flip : boolean );
2094 begin
2095  {$IFNDEF AGG2D_NO_FONT}
2096  m_fontEngine.flip_y_(flip );
2097  {$ENDIF}
2098 end;
2099 
2100 { FONT }
2101 procedure Agg2D.font(
2102            fileName : char_ptr; height : double;
2103            bold : boolean = false;
2104            italic : boolean = false;
2105            ch : FontCacheType = RasterFontCache;
2106            angle : double = 0.0 );
2107 {$IFDEF AGG2D_USE_WINFONTS}
2108 var
2109  b : int;
2110 {$ENDIF}
2111 
2112 begin
2113  m_textAngle    :=angle;
2114  m_fontHeight   :=height;
2115  m_fontCacheType:=ch;
2116 
2117 {$IFDEF AGG2D_USE_FREETYPE }
2118  if ch = VectorFontCache then
2119   m_fontEngine.load_font(PChar(fileName ) ,0 ,glyph_ren_outline )
2120  else
2121   m_fontEngine.load_font(PChar(fileName ) ,0 ,glyph_ren_agg_gray8 );
2122 
2123  m_fontEngine.hinting_(m_textHints );
2124 
2125  if ch = VectorFontCache then
2126   m_fontEngine.height_(height )
2127  else
2128   m_fontEngine.height_(worldToScreen(height ) );
2129 {$ENDIF }
2130 {$IFDEF AGG2D_USE_WINFONTS}
2131  m_fontEngine.hinting_(m_textHints );
2132 
2133  if bold then
2134   b:=700
2135  else
2136   b:=400;
2137 
2138  if ch = VectorFontCache then
2139   m_fontEngine.create_font_(PChar(fileName ) ,glyph_ren_outline ,height ,0.0 ,b ,italic )
2140  else
2141   m_fontEngine.create_font_(PChar(fileName ) ,glyph_ren_agg_gray8 ,worldToScreen(height) ,0.0 ,b ,italic );
2142 {$ENDIF }
2143 
2144 end;
2145 
2146 { FONTHEIGHT }
Agg2D.fontHeightnull2147 function Agg2D.fontHeight : double;
2148 begin
2149  result:=m_fontHeight;
2150 
2151 end;
2152 
2153 { TEXTALIGNMENT }
2154 procedure Agg2D.textAlignment(alignX ,alignY : TextAlignment );
2155 begin
2156  m_textAlignX:=alignX;
2157  m_textAlignY:=alignY;
2158 
2159 end;
2160 
2161 { TEXTHINTS }
Agg2D.textHintsnull2162 function Agg2D.textHints : boolean;
2163 begin
2164  result:=m_textHints;
2165 
2166 end;
2167 
2168 { TEXTHINTS }
2169 procedure Agg2D.textHints(hints : boolean );
2170 begin
2171  m_textHints:=hints;
2172 
2173 end;
2174 
2175 { TEXTWIDTH }
Agg2D.textWidthnull2176 function Agg2D.textWidth(str : char_ptr ) : double;
2177 {$IFDEF AGG2D_NO_FONT}
2178 begin
2179   Result:=0;
2180 end;
2181 {$ELSE}
2182 var
2183  x ,y  : double;
2184  first : boolean;
2185  glyph : glyph_cache_ptr;
2186 
2187 begin
2188  x:=0;
2189  y:=0;
2190 
2191  first:=true;
2192 
2193  while str^ <> #0 do
2194   begin
2195    glyph:=m_fontCacheManager.glyph(int32u(str^ ) );
2196 
2197    if glyph <> NIL then
2198     begin
2199      if not first then
2200       m_fontCacheManager.add_kerning(@x ,@y );
2201 
2202      x:=x + glyph.advance_x;
2203      y:=y + glyph.advance_y;
2204 
2205      first:=false; {!}
2206 
2207     end;
2208 
2209    inc(ptrcomp(str ) );
2210 
2211   end;
2212 
2213  if m_fontCacheType = VectorFontCache then
2214   result:=x
2215  else
2216   result:=screenToWorld(x );
2217 
2218 end;
2219 {$ENDIF}
2220 
2221 { TEXT }
2222 procedure Agg2D.text(
2223            x ,y : double; str : char_ptr;
2224            roundOff : boolean = false;
2225            ddx : double = 0.0;
2226            ddy : double = 0.0 );
2227 {$IFDEF AGG2D_NO_FONT}
2228 begin
2229 
2230 end;
2231 {$ELSE}
2232 var
2233  dx ,dy ,asc ,start_x ,start_y : double;
2234 
2235  glyph : glyph_cache_ptr;
2236 
2237  mtx : trans_affine;
2238 
2239  i : int;
2240 
2241  tat : trans_affine_translation;
2242  tar : trans_affine_rotation;
2243 
2244  tr : conv_transform;
2245 
2246 begin
2247  dx:=0.0;
2248  dy:=0.0;
2249 
2250  case m_textAlignX of
2251   AlignCenter :
2252    dx:=-textWidth(str ) * 0.5;
2253 
2254   AlignRight :
2255    dx:=-textWidth(str );
2256 
2257  end;
2258 
2259  asc  :=fontHeight;
2260  glyph:=m_fontCacheManager.glyph(int32u('H' ) );
2261 
2262  if glyph <> NIL then
2263   asc:=glyph.bounds.y2 - glyph.bounds.y1;
2264 
2265  if m_fontCacheType = RasterFontCache then
2266   asc:=screenToWorld(asc );
2267 
2268  case m_textAlignY of
2269   AlignCenter :
2270    dy:=-asc * 0.5;
2271 
2272   AlignTop :
2273    dy:=-asc;
2274 
2275  end;
2276 
2277  if m_fontEngine._flip_y then
2278   dy:=-dy;
2279 
2280  mtx.Construct;
2281 
2282  start_x:=x + dx;
2283  start_y:=y + dy;
2284 
2285  if roundOff then
2286   begin
2287    start_x:=Trunc(start_x );
2288    start_y:=Trunc(start_y );
2289 
2290   end;
2291 
2292  start_x:=start_x + ddx;
2293  start_y:=start_y + ddy;
2294 
2295  tat.Construct(-x ,-y );
2296  mtx.multiply (@tat );
2297 
2298  tar.Construct(m_textAngle );
2299  mtx.multiply (@tar );
2300 
2301  tat.Construct(x ,y );
2302  mtx.multiply (@tat );
2303 
2304  tr.Construct(m_fontCacheManager.path_adaptor ,@mtx );
2305 
2306  if m_fontCacheType = RasterFontCache then
2307   worldToScreen(@start_x ,@start_y );
2308 
2309  i:=0;
2310 
2311  while char_ptr(ptrcomp(str ) + i * sizeof(char ) )^ <> #0 do
2312   begin
2313    glyph:=m_fontCacheManager.glyph(int32u(char_ptr(ptrcomp(str ) + i * sizeof(char ) )^ ) );
2314 
2315    if glyph <> NIL then
2316     begin
2317      if i <> 0 then
2318       m_fontCacheManager.add_kerning(@x ,@y );
2319 
2320      m_fontCacheManager.init_embedded_adaptors(glyph ,start_x ,start_y );
2321 
2322      if glyph.data_type = glyph_data_outline then
2323       begin
2324        m_path.remove_all;
2325        m_path.add_path(@tr ,0 ,false );
2326 
2327        drawPath;
2328 
2329       end;
2330 
2331      if glyph.data_type = glyph_data_gray8 then
2332       begin
2333        render(
2334         m_fontCacheManager.gray8_adaptor ,
2335         m_fontCacheManager.gray8_scanline );
2336 
2337       end;
2338 
2339      start_x:=start_x + glyph.advance_x;
2340      start_y:=start_y + glyph.advance_y;
2341 
2342     end;
2343 
2344    inc(i );
2345 
2346   end;
2347 
2348 end;
2349 {$ENDIF}
2350 
2351 { RESETPATH }
2352 procedure Agg2D.resetPath;
2353 begin
2354  m_path.remove_all;
2355 
2356 end;
2357 
2358 { MOVETO }
2359 procedure Agg2D.moveTo(x ,y : double );
2360 begin
2361  m_path.move_to(x ,y );
2362 
2363 end;
2364 
2365 { MOVEREL }
2366 procedure Agg2D.moveRel(dx ,dy : double );
2367 begin
2368  m_path.move_rel(dx ,dy );
2369 
2370 end;
2371 
2372 { LINETO }
2373 procedure Agg2D.lineTo(x ,y : double );
2374 begin
2375  m_path.line_to(x ,y );
2376 
2377 end;
2378 
2379 { LINEREL }
2380 procedure Agg2D.lineRel(dx ,dy : double );
2381 begin
2382  m_path.line_rel(dx ,dy );
2383 
2384 end;
2385 
2386 { HORLINETO }
2387 procedure Agg2D.horLineTo(x : double );
2388 begin
2389  m_path.hline_to(x );
2390 
2391 end;
2392 
2393 { HORLINEREL }
2394 procedure Agg2D.horLineRel(dx : double );
2395 begin
2396  m_path.hline_rel(dx );
2397 
2398 end;
2399 
2400 { VERLINETO }
2401 procedure Agg2D.verLineTo(y : double );
2402 begin
2403  m_path.vline_to(y );
2404 
2405 end;
2406 
2407 { VERLINEREL }
2408 procedure Agg2D.verLineRel(dy : double );
2409 begin
2410  m_path.vline_rel(dy );
2411 
2412 end;
2413 
2414 { ARCTO }
2415 procedure Agg2D.arcTo(
2416            rx ,ry ,angle : double;
2417            largeArcFlag ,sweepFlag : boolean;
2418            x ,y : double );
2419 begin
2420  m_path.arc_to(rx ,ry ,angle ,largeArcFlag ,sweepFlag ,x ,y );
2421 
2422 end;
2423 
2424 { ARCREL }
2425 procedure Agg2D.arcRel(
2426            rx ,ry ,angle : double;
2427            largeArcFlag ,sweepFlag : boolean;
2428            dx ,dy : double );
2429 begin
2430  m_path.arc_rel(rx ,ry ,angle ,largeArcFlag ,sweepFlag ,dx ,dy );
2431 
2432 end;
2433 
2434 { QUADRICCURVETO }
2435 procedure Agg2D.quadricCurveTo (xCtrl ,yCtrl ,xTo ,yTo : double );
2436 begin
2437  m_path.curve3(xCtrl ,yCtrl ,xTo ,yTo );
2438 
2439 end;
2440 
2441 { QUADRICCURVEREL }
2442 procedure Agg2D.quadricCurveRel(dxCtrl ,dyCtrl ,dxTo ,dyTo : double );
2443 begin
2444  m_path.curve3_rel(dxCtrl ,dyCtrl ,dxTo ,dyTo );
2445 
2446 end;
2447 
2448 { QUADRICCURVETO }
2449 procedure Agg2D.quadricCurveTo (xTo ,yTo : double );
2450 begin
2451  m_path.curve3(xTo ,yTo );
2452 
2453 end;
2454 
2455 { QUADRICCURVEREL }
2456 procedure Agg2D.quadricCurveRel(dxTo ,dyTo : double );
2457 begin
2458  m_path.curve3_rel(dxTo ,dyTo );
2459 
2460 end;
2461 
2462 { CUBICCURVETO }
2463 procedure Agg2D.cubicCurveTo (xCtrl1 ,yCtrl1 ,xCtrl2 ,yCtrl2 ,xTo ,yTo : double );
2464 begin
2465  m_path.curve4(xCtrl1 ,yCtrl1 ,xCtrl2 ,yCtrl2 ,xTo ,yTo );
2466 
2467 end;
2468 
2469 { CUBICCURVEREL }
2470 procedure Agg2D.cubicCurveRel(dxCtrl1 ,dyCtrl1 ,dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo : double );
2471 begin
2472  m_path.curve4_rel(dxCtrl1 ,dyCtrl1 ,dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo );
2473 
2474 end;
2475 
2476 { CUBICCURVETO }
2477 procedure Agg2D.cubicCurveTo (xCtrl2 ,yCtrl2 ,xTo ,yTo : double );
2478 begin
2479  m_path.curve4(xCtrl2 ,yCtrl2 ,xTo ,yTo );
2480 
2481 end;
2482 
2483 { CUBICCURVEREL }
2484 procedure Agg2D.cubicCurveRel(xCtrl2 ,yCtrl2 ,xTo ,yTo : double );
2485 begin
2486  m_path.curve4_rel(xCtrl2 ,yCtrl2 ,xTo ,yTo );
2487 
2488 end;
2489 
2490 { ADDELLIPSE }
2491 procedure Agg2D.addEllipse(cx ,cy ,rx ,ry : double; dir : Direction );
2492 var
2493  ar : bezier_arc;
2494 
2495 begin
2496  if dir = CCW then
2497   ar.Construct(cx ,cy ,rx ,ry ,0 ,2 * pi )
2498  else
2499   ar.Construct(cx ,cy ,rx ,ry ,0 ,-2 * pi );
2500 
2501  m_path.add_path(@ar ,0 ,false );
2502  m_path.close_polygon;
2503 
2504 end;
2505 
2506 { CLOSEPOLYGON }
2507 procedure Agg2D.closePolygon;
2508 begin
2509  m_path.close_polygon;
2510 
2511 end;
2512 
2513 { DRAWPATH }
2514 procedure Agg2D.drawPath(flag : DrawPathFlag = FillAndStroke );
2515 begin
2516  m_rasterizer.reset;
2517 
2518  case flag of
2519   FillOnly :
2520    if m_fillColor.a <> 0 then
2521     begin
2522      m_rasterizer.add_path(@m_pathTransform );
2523 
2524      render(true );
2525 
2526     end;
2527 
2528   StrokeOnly :
2529    if (m_lineColor.a <> 0 ) and
2530       (m_lineWidth > 0.0 ) then
2531     begin
2532      m_rasterizer.add_path(@m_strokeTransform );
2533 
2534      render(false );
2535 
2536     end;
2537 
2538   FillAndStroke :
2539    begin
2540     if m_fillColor.a <> 0 then
2541      begin
2542       m_rasterizer.add_path(@m_pathTransform );
2543 
2544       render(true );
2545 
2546      end;
2547 
2548     if (m_lineColor.a <> 0 ) and
2549        (m_lineWidth > 0.0 ) then
2550      begin
2551       m_rasterizer.add_path(@m_strokeTransform );
2552 
2553       render(false );
2554 
2555      end;
2556 
2557    end;
2558 
2559   FillWithLineColor :
2560    if m_lineColor.a <> 0 then
2561     begin
2562      m_rasterizer.add_path(@m_pathTransform );
2563 
2564      render(false );
2565 
2566     end;
2567 
2568  end;
2569 
2570 end;
2571 
2572 { DRAWPATHNOTRANSFORM }
2573 procedure Agg2D.drawPathNoTransform(flag : DrawPathFlag = FillAndStroke );
2574 begin
2575 end;
2576 
2577 { IMAGEFILTER }
2578 procedure Agg2D.imageFilter(f : ImageFilter_ );
2579 begin
2580  m_imageFilter:=f;
2581 
2582  case f of
2583   Bilinear :
2584    m_imageFilterLut.calculate(@m_ifBilinear ,true );
2585 
2586   Hanning :
2587    m_imageFilterLut.calculate(@m_ifHanning ,true );
2588 
2589   Hermite :
2590    m_imageFilterLut.calculate(@m_ifHermite ,true );
2591 
2592   Quadric :
2593    m_imageFilterLut.calculate(@m_ifQuadric ,true );
2594 
2595   Bicubic :
2596    m_imageFilterLut.calculate(@m_ifBicubic ,true );
2597 
2598   Catrom :
2599    m_imageFilterLut.calculate(@m_ifCatrom ,true );
2600 
2601   Spline16 :
2602    m_imageFilterLut.calculate(@m_ifSpline16 ,true );
2603 
2604   Spline36 :
2605    m_imageFilterLut.calculate(@m_ifSpline36 ,true );
2606 
2607   Blackman144 :
2608    m_imageFilterLut.calculate(@m_ifBlackman144 ,true );
2609 
2610  end;
2611 
2612 end;
2613 
2614 { IMAGEFILTER }
Agg2D.imageFilternull2615 function Agg2D.imageFilter : ImageFilter_;
2616 begin
2617  result:=m_imageFilter;
2618 
2619 end;
2620 
2621 { IMAGERESAMPLE }
2622 procedure Agg2D.imageResample(f : ImageResample_ );
2623 begin
2624  m_imageResample:=f;
2625 
2626 end;
2627 
2628 { IMAGERESAMPLE }
Agg2D.imageResamplenull2629 function Agg2D.imageResample : ImageResample_;
2630 begin
2631  result:=m_imageResample;
2632 
2633 end;
2634 
2635 { TRANSFORMIMAGE }
2636 procedure Agg2D.transformImage(
2637            img : Image_ptr;
2638            imgX1 ,imgY1 ,imgX2 ,imgY2 : int;
2639            dstX1 ,dstY1 ,dstX2 ,dstY2 : double );
2640 var
2641  parall : array[0..5 ] of double;
2642 
2643 begin
2644  resetPath;
2645  moveTo(dstX1 ,dstY1 );
2646  lineTo(dstX2 ,dstY1 );
2647  lineTo(dstX2 ,dstY2 );
2648  lineTo(dstX1 ,dstY2 );
2649  closePolygon;
2650 
2651  parall[0 ]:=dstX1;
2652  parall[1 ]:=dstY1;
2653  parall[2 ]:=dstX2;
2654  parall[3 ]:=dstY1;
2655  parall[4 ]:=dstX2;
2656  parall[5 ]:=dstY2;
2657 
2658  renderImage(img ,imgX1 ,imgY1 ,imgX2 ,imgY2 ,@parall[0 ] );
2659 
2660 end;
2661 
2662 { TRANSFORMIMAGE }
2663 procedure Agg2D.transformImage(
2664            img : Image_ptr;
2665            dstX1 ,dstY1 ,dstX2 ,dstY2 : double );
2666 var
2667  parall : array[0..5 ] of double;
2668 
2669 begin
2670  resetPath;
2671  moveTo(dstX1 ,dstY1 );
2672  lineTo(dstX2 ,dstY1 );
2673  lineTo(dstX2 ,dstY2 );
2674  lineTo(dstX1 ,dstY2 );
2675  closePolygon;
2676 
2677  parall[0 ]:=dstX1;
2678  parall[1 ]:=dstY1;
2679  parall[2 ]:=dstX2;
2680  parall[3 ]:=dstY1;
2681  parall[4 ]:=dstX2;
2682  parall[5 ]:=dstY2;
2683 
2684  renderImage(img ,0 ,0 ,img.renBuf._width ,img.renBuf._height ,@parall[0 ] );
2685 
2686 end;
2687 
2688 { TRANSFORMIMAGE }
2689 procedure Agg2D.transformImage(
2690            img : Image_ptr;
2691            imgX1 ,imgY1 ,imgX2 ,imgY2 : int;
2692            parallelogram_ : double_ptr );
2693 begin
2694  resetPath;
2695 
2696  moveTo(
2697   double_ptr(ptrcomp(parallelogram_ ) + 0 * sizeof(double ) )^ ,
2698   double_ptr(ptrcomp(parallelogram_ ) + 1 * sizeof(double ) )^ );
2699 
2700  lineTo(
2701   double_ptr(ptrcomp(parallelogram_ ) + 2 * sizeof(double ) )^ ,
2702   double_ptr(ptrcomp(parallelogram_ ) + 3 * sizeof(double ) )^ );
2703 
2704  lineTo(
2705   double_ptr(ptrcomp(parallelogram_ ) + 4 * sizeof(double ) )^ ,
2706   double_ptr(ptrcomp(parallelogram_ ) + 5 * sizeof(double ) )^ );
2707 
2708  lineTo(
2709   double_ptr(ptrcomp(parallelogram_ ) + 0 * sizeof(double ) )^ +
2710   double_ptr(ptrcomp(parallelogram_ ) + 4 * sizeof(double ) )^ -
2711   double_ptr(ptrcomp(parallelogram_ ) + 2 * sizeof(double ) )^ ,
2712   double_ptr(ptrcomp(parallelogram_ ) + 1 * sizeof(double ) )^ +
2713   double_ptr(ptrcomp(parallelogram_ ) + 5 * sizeof(double ) )^ -
2714   double_ptr(ptrcomp(parallelogram_ ) + 3 * sizeof(double ) )^ );
2715 
2716  closePolygon;
2717 
2718  renderImage(img ,imgX1 ,imgY1 ,imgX2 ,imgY2 ,parallelogram_ );
2719 
2720 end;
2721 
2722 { TRANSFORMIMAGE }
2723 procedure Agg2D.transformImage(img : Image_ptr; parallelogram_ : double_ptr );
2724 begin
2725  resetPath;
2726 
2727  moveTo(
2728   double_ptr(ptrcomp(parallelogram_ ) + 0 * sizeof(double ) )^ ,
2729   double_ptr(ptrcomp(parallelogram_ ) + 1 * sizeof(double ) )^ );
2730 
2731  lineTo(
2732   double_ptr(ptrcomp(parallelogram_ ) + 2 * sizeof(double ) )^ ,
2733   double_ptr(ptrcomp(parallelogram_ ) + 3 * sizeof(double ) )^ );
2734 
2735  lineTo(
2736   double_ptr(ptrcomp(parallelogram_ ) + 4 * sizeof(double ) )^ ,
2737   double_ptr(ptrcomp(parallelogram_ ) + 5 * sizeof(double ) )^ );
2738 
2739  lineTo(
2740   double_ptr(ptrcomp(parallelogram_ ) + 0 * sizeof(double ) )^ +
2741   double_ptr(ptrcomp(parallelogram_ ) + 4 * sizeof(double ) )^ -
2742   double_ptr(ptrcomp(parallelogram_ ) + 2 * sizeof(double ) )^ ,
2743   double_ptr(ptrcomp(parallelogram_ ) + 1 * sizeof(double ) )^ +
2744   double_ptr(ptrcomp(parallelogram_ ) + 5 * sizeof(double ) )^ -
2745   double_ptr(ptrcomp(parallelogram_ ) + 3 * sizeof(double ) )^ );
2746 
2747  closePolygon;
2748 
2749  renderImage(img ,0 ,0 ,img.renBuf._width ,img.renBuf._height ,parallelogram_ );
2750 
2751 end;
2752 
2753 { TRANSFORMIMAGEPATH }
2754 procedure Agg2D.transformImagePath(
2755            img : Image_ptr;
2756            imgX1 ,imgY1 ,imgX2 ,imgY2 : int;
2757            dstX1 ,dstY1 ,dstX2 ,dstY2 : double );
2758 var
2759  parall : array[0..5 ] of double;
2760 
2761 begin
2762  parall[0 ]:=dstX1;
2763  parall[1 ]:=dstY1;
2764  parall[2 ]:=dstX2;
2765  parall[3 ]:=dstY1;
2766  parall[4 ]:=dstX2;
2767  parall[5 ]:=dstY2;
2768 
2769  renderImage(img ,imgX1 ,imgY1 ,imgX2 ,imgY2 ,@parall[0 ] );
2770 
2771 end;
2772 
2773 { TRANSFORMIMAGEPATH }
2774 procedure Agg2D.transformImagePath(
2775            img : Image_ptr;
2776            dstX1 ,dstY1 ,dstX2 ,dstY2 : double );
2777 var
2778  parall : array[0..5 ] of double;
2779 
2780 begin
2781  parall[0 ]:=dstX1;
2782  parall[1 ]:=dstY1;
2783  parall[2 ]:=dstX2;
2784  parall[3 ]:=dstY1;
2785  parall[4 ]:=dstX2;
2786  parall[5 ]:=dstY2;
2787 
2788  renderImage(img ,0 ,0 ,img.renBuf._width ,img.renBuf._height ,@parall[0 ] );
2789 
2790 end;
2791 
2792 { TRANSFORMIMAGEPATH }
2793 procedure Agg2D.transformImagePath(
2794            img : Image_ptr;
2795            imgX1 ,imgY1 ,imgX2 ,imgY2 : int;
2796            parallelogram_ : double_ptr );
2797 begin
2798  renderImage(img ,imgX1 ,imgY1 ,imgX2 ,imgY2 ,parallelogram_ );
2799 
2800 end;
2801 
2802 { TRANSFORMIMAGEPATH }
2803 procedure Agg2D.transformImagePath(img : Image_ptr; parallelogram_ : double_ptr );
2804 begin
2805  renderImage(img ,0 ,0 ,img.renBuf._width ,img.renBuf._height ,parallelogram_ );
2806 
2807 end;
2808 
2809 { BLENDIMAGE }
2810 procedure Agg2D.blendImage(
2811            img : Image_ptr;
2812            imgX1 ,imgY1 ,imgX2 ,imgY2 : int;
2813            dstX ,dstY : double; alpha : unsigned = 255 );
2814 var
2815  pixF : pixel_formats;
2816 
2817  r : agg_basics.rect;
2818 
2819 begin
2820  worldToScreen(@dstX ,@dstY );
2821  pixfmt_rgba32(pixF ,@img.renBuf );
2822  r.Construct  (imgX1 ,imgY1 ,imgX2 ,imgY2 );
2823 
2824  if m_blendMode = BlendAlpha then
2825   m_renBasePre.blend_from(@pixF ,@r ,Trunc(dstX ) - imgX1 ,Trunc(dstY ) - imgY1 ,alpha )
2826  else
2827   m_renBaseCompPre.blend_from(@pixF ,@r ,Trunc(dstX ) - imgX1 ,Trunc(dstY ) - imgY1 ,alpha );
2828 
2829 end;
2830 
2831 { BLENDIMAGE }
2832 procedure Agg2D.blendImage(img : Image_ptr; dstX ,dstY : double; alpha : unsigned = 255 );
2833 var
2834  pixF : pixel_formats;
2835 
2836 begin
2837  worldToScreen(@dstX ,@dstY );
2838  pixfmt_rgba32(pixF ,@img.renBuf );
2839 
2840  m_renBasePre.blend_from(@pixF ,NIL ,Trunc(dstX ) ,Trunc(dstY ) ,alpha );
2841 
2842  if m_blendMode = BlendAlpha then
2843   m_renBasePre.blend_from(@pixF ,NIL ,Trunc(dstX ) ,Trunc(dstY ) ,alpha )
2844  else
2845   m_renBaseCompPre.blend_from(@pixF ,NIL ,Trunc(dstX ) ,Trunc(dstY ) ,alpha );
2846 
2847 end;
2848 
2849 { COPYIMAGE }
2850 procedure Agg2D.copyImage(
2851            img : Image_ptr;
2852            imgX1 ,imgY1 ,imgX2 ,imgY2 : int;
2853            dstX ,dstY : double );
2854 var
2855  r : agg_basics.rect;
2856 
2857 begin
2858  worldToScreen(@dstX ,@dstY );
2859  r.Construct  (imgX1 ,imgY1 ,imgX2 ,imgY2 );
2860 
2861  m_renBase.copy_from(@img.renBuf ,@r ,Trunc(dstX ) - imgX1 ,Trunc(dstY ) - imgY1 );
2862 
2863 end;
2864 
2865 { COPYIMAGE }
2866 procedure Agg2D.copyImage(img : Image_ptr; dstX ,dstY : double );
2867 begin
2868  worldToScreen(@dstX ,@dstY );
2869 
2870  m_renBase.copy_from(@img.renBuf ,NIL ,Trunc(dstX ) ,Trunc(dstY ) );
2871 
2872 end;
2873 
2874 { RENDER }
2875 procedure Agg2D.render(fillColor_ : boolean );
2876 begin
2877  if m_blendMode = BlendAlpha then
2878   Agg2DRenderer_render(@self ,@m_renBase ,@m_renSolid ,fillColor_ )
2879  else
2880   Agg2DRenderer_render(@self ,@m_renBaseComp ,@m_renSolidComp ,fillColor_ );
2881 
2882 end;
2883 
2884 { RENDER }
2885 procedure Agg2D.render(ras : FontRasterizer_ptr; sl : FontScanline_ptr );
2886 begin
2887  if m_blendMode = BlendAlpha then
2888   Agg2DRenderer_render(@self ,@m_renBase ,@m_renSolid ,ras ,sl )
2889  else
2890   Agg2DRenderer_render(@self ,@m_renBaseComp ,@m_renSolidComp ,ras ,sl );
2891 
2892 end;
2893 
2894 { ADDLINE }
2895 procedure Agg2D.addLine(x1 ,y1 ,x2 ,y2 : double );
2896 begin
2897  m_path.move_to(x1 ,y1 );
2898  m_path.line_to(x2 ,y2 );
2899 
2900 end;
2901 
2902 { UPDATERASTERIZERGAMMA }
2903 procedure Agg2D.updateRasterizerGamma;
2904 begin
2905  m_gammaAgg2D.Construct(m_masterAlpha ,m_antiAliasGamma );
2906  m_rasterizer.gamma    (@m_gammaAgg2D );
2907 
2908 end;
2909 
2910 { RENDERIMAGE }
2911 procedure Agg2D.renderImage(
2912            img : Image_ptr;
2913            x1 ,y1 ,x2 ,y2 : int;
2914            parl : double_ptr );
2915 var
2916  mtx : trans_affine;
2917 
2918  interpolator : span_interpolator_linear;
2919 
2920 begin
2921  mtx.Construct(x1 ,y1 ,x2 ,y2 ,parallelo_ptr(parl ) );
2922  mtx.multiply (@m_transform );
2923  mtx.invert;
2924 
2925  m_rasterizer.reset;
2926  m_rasterizer.add_path(@m_pathTransform );
2927 
2928  interpolator.Construct(@mtx );
2929 
2930  if m_blendMode = BlendAlpha then
2931   Agg2DRenderer_renderImage(@self ,img ,@m_renBasePre ,@interpolator )
2932  else
2933   Agg2DRenderer_renderImage(@self ,img ,@m_renBaseCompPre ,@interpolator );
2934 
2935 end;
2936 
2937 { CONSTRUCT }
2938 constructor SpanConvImageBlend.Construct(m : BlendMode_; c : Color; p : pixel_formats_ptr );
2939 begin
2940  m_mode :=m;
2941  m_color:=c;
2942  m_pixel:=p;
2943 
2944 end;
2945 
2946 { CONVERT }
2947 procedure SpanConvImageBlend.convert(span : aggclr_ptr; x ,y : int; len : unsigned );
2948 var
2949  l2 ,a : unsigned;
2950 
2951  s2 : Color_ptr;
2952 
2953 begin
2954  if m_mode <> BlendDst then
2955   begin
2956    l2:=len;
2957    s2:=Color_ptr(span );
2958 
2959    repeat
2960     comp_op_adaptor_clip_to_dst_rgba_pre(
2961      m_pixel ,
2962      unsigned(m_mode ) ,
2963      int8u_ptr(s2 ) ,
2964      m_color.r ,
2965      m_color.g ,
2966      m_color.b ,
2967      base_mask ,
2968      cover_full );
2969 
2970     inc(ptrcomp(s2 ) ,sizeof(Color ) );
2971     dec(l2 );
2972 
2973    until l2 = 0;
2974 
2975   end;
2976 
2977  if m_color.a < base_mask then
2978   begin
2979    l2:=len;
2980    s2:=Color_ptr(span );
2981    a :=m_color.a;
2982 
2983    repeat
2984     s2.r:=(s2.r * a ) shr base_shift;
2985     s2.g:=(s2.g * a ) shr base_shift;
2986     s2.b:=(s2.b * a ) shr base_shift;
2987     s2.a:=(s2.a * a ) shr base_shift;
2988 
2989     inc(ptrcomp(s2 ) ,sizeof(Color ) );
2990     dec(l2 );
2991 
2992    until l2 = 0;
2993 
2994   end;
2995 
2996 end;
2997 
2998 { PI }
pinull2999 function pi : double;
3000 begin
3001  result:=agg_basics.pi;
3002 
3003 end;
3004 
3005 { DEG2RAD }
deg2Radnull3006 function deg2Rad(v : double ) : double;
3007 begin
3008  result:=v * agg_basics.pi / 180.0;
3009 
3010 end;
3011 
3012 { RAD2DEG }
rad2Degnull3013 function rad2Deg(v : double ) : double;
3014 begin
3015  result:=v * 180.0 / agg_basics.pi;
3016 
3017 end;
3018 
3019 { OPERATOR_IS_EQUAL }
operator_is_equalnull3020 function operator_is_equal(c1 ,c2 : Color_ptr ) : boolean;
3021 begin
3022  result:=
3023   (c1.r = c2.r ) and
3024   (c1.g = c2.g ) and
3025   (c1.b = c2.b ) and
3026   (c1.a = c2.a );
3027 
3028 end;
3029 
3030 { OPERATOR_IS_NOT_EQUAL }
operator_is_not_equalnull3031 function operator_is_not_equal(c1 ,c2 : Color_ptr ) : boolean;
3032 begin
3033  result:=not operator_is_equal(c1 ,c2 );
3034 
3035 end;
3036 
3037 { AGG2DRENDERER_RENDER }
3038 procedure Agg2DRenderer_render(
3039            gr : Agg2D_ptr;
3040            renBase : renderer_base_ptr;
3041            renSolid : renderer_scanline_aa_solid_ptr;
3042            fillColor_ : boolean );
3043 var
3044  span : span_gradient;
3045  ren  : renderer_scanline_aa;
3046  clr  : aggclr;
3047 
3048 begin
3049  if (fillColor_ and
3050      (gr.m_fillGradientFlag = Linear ) ) or
3051     (not fillColor_ and
3052      (gr.m_lineGradientFlag = Linear ) ) then
3053   if fillColor_ then
3054    begin
3055     span.Construct(
3056      @gr.m_allocator ,
3057      @gr.m_fillGradientInterpolator ,
3058      @gr.m_linearGradientFunction ,
3059      @gr.m_fillGradient ,
3060      gr.m_fillGradientD1 ,
3061      gr.m_fillGradientD2 );
3062 
3063     ren.Construct   (renBase ,@span );
3064     render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ren );
3065 
3066    end
3067   else
3068    begin
3069     span.Construct(
3070      @gr.m_allocator ,
3071      @gr.m_lineGradientInterpolator ,
3072      @gr.m_linearGradientFunction ,
3073      @gr.m_lineGradient ,
3074      gr.m_lineGradientD1 ,
3075      gr.m_lineGradientD2 );
3076 
3077     ren.Construct   (renBase ,@span );
3078     render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ren );
3079 
3080    end
3081  else
3082   if (fillColor_ and
3083       (gr.m_fillGradientFlag = Radial ) ) or
3084      (not fillColor_ and
3085       (gr.m_lineGradientFlag = Radial ) ) then
3086    if fillColor_ then
3087     begin
3088      span.Construct(
3089       @gr.m_allocator ,
3090       @gr.m_fillGradientInterpolator ,
3091       @gr.m_radialGradientFunction ,
3092       @gr.m_fillGradient ,
3093       gr.m_fillGradientD1 ,
3094       gr.m_fillGradientD2 );
3095 
3096       ren.Construct   (renBase ,@span );
3097       render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ren );
3098 
3099     end
3100    else
3101     begin
3102      span.Construct(
3103       @gr.m_allocator ,
3104       @gr.m_lineGradientInterpolator ,
3105       @gr.m_radialGradientFunction ,
3106       @gr.m_lineGradient ,
3107       gr.m_lineGradientD1 ,
3108       gr.m_lineGradientD2 );
3109 
3110      ren.Construct   (renBase ,@span );
3111      render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ren );
3112 
3113     end
3114   else
3115    begin
3116     if fillColor_ then
3117      clr.Construct(gr.m_fillColor )
3118     else
3119      clr.Construct(gr.m_lineColor );
3120 
3121     renSolid.color_ (@clr );
3122     render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,renSolid );
3123 
3124    end;
3125 
3126 end;
3127 
3128 { AGG2DRENDERER_RENDER }
3129 procedure Agg2DRenderer_render(
3130            gr : Agg2D_ptr;
3131            renBase : renderer_base_ptr;
3132            renSolid : renderer_scanline_aa_solid_ptr;
3133            ras : gray8_adaptor_type_ptr;
3134            sl : gray8_scanline_type_ptr );
3135 var
3136  span : span_gradient;
3137  ren  : renderer_scanline_aa;
3138  clr  : aggclr;
3139 
3140 begin
3141  if gr.m_fillGradientFlag = Linear then
3142   begin
3143    span.Construct(
3144     @gr.m_allocator ,
3145     @gr.m_fillGradientInterpolator ,
3146     @gr.m_linearGradientFunction ,
3147     @gr.m_fillGradient ,
3148     gr.m_fillGradientD1 ,
3149     gr.m_fillGradientD2 );
3150 
3151    ren.Construct   (renBase ,@span );
3152    render_scanlines(ras ,sl ,@ren );
3153 
3154   end
3155  else
3156   if gr.m_fillGradientFlag = Radial then
3157    begin
3158     span.Construct(
3159      @gr.m_allocator ,
3160      @gr.m_fillGradientInterpolator ,
3161      @gr.m_radialGradientFunction ,
3162      @gr.m_fillGradient ,
3163      gr.m_fillGradientD1 ,
3164      gr.m_fillGradientD2 );
3165 
3166     ren.Construct   (renBase ,@span );
3167     render_scanlines(ras ,sl ,@ren );
3168 
3169    end
3170   else
3171    begin
3172     clr.Construct   (gr.m_fillColor );
3173     renSolid.color_ (@clr );
3174     render_scanlines(ras ,sl ,renSolid );
3175 
3176    end;
3177 
3178 end;
3179 
3180 { AGG2DRENDERER_RENDERIMAGE }
3181 procedure Agg2DRenderer_renderImage(
3182            gr : Agg2D_ptr;
3183            img : Image_ptr;
3184            renBase : renderer_base_ptr;
3185            interpolator : span_interpolator_linear_ptr );
3186 var
3187  blend : SpanConvImageBlend;
3188 
3189  si : span_image_filter_rgba;
3190  sg : span_image_filter_rgba_nn;
3191  sb : span_image_filter_rgba_bilinear;
3192  s2 : span_image_filter_rgba_2x2;
3193  sa : span_image_resample_rgba_affine;
3194  sc : span_converter;
3195  ri : renderer_scanline_aa;
3196 
3197  clr : aggclr;
3198 
3199  resample : boolean;
3200 
3201  sx ,sy : double;
3202 
3203 begin
3204  blend.Construct(gr.m_imageBlendMode ,gr.m_imageBlendColor ,@gr.m_pixFormatCompPre );
3205 
3206  if gr.m_imageFilter = NoFilter then
3207   begin
3208    clr.ConstrInt(0 ,0 ,0 ,0 );
3209    sg.Construct (@gr.m_allocator ,@img.renBuf ,@clr ,interpolator ,rgba_order );
3210    sc.Construct (@sg ,@blend );
3211    ri.Construct (renBase ,@sc );
3212 
3213    render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ri );
3214 
3215   end
3216  else
3217   begin
3218    resample:=gr.m_imageResample = ResampleAlways;
3219 
3220    if gr.m_imageResample = ResampleOnZoomOut then
3221     begin
3222      interpolator._transformer.scaling_abs(@sx ,@sy );
3223 
3224      if (sx > 1.125 ) or
3225         (sy > 1.125 ) then
3226       resample:=true;
3227 
3228     end;
3229 
3230    if resample then
3231     begin
3232      clr.ConstrInt(0 ,0 ,0 ,0 );
3233      sa.Construct(
3234       @gr.m_allocator ,
3235       @img.renBuf ,
3236       @clr ,
3237       interpolator ,
3238       @gr.m_imageFilterLut ,
3239       rgba_order );
3240 
3241      sc.Construct(@sa ,@blend );
3242      ri.Construct(renBase ,@sc );
3243 
3244      render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ri );
3245 
3246     end
3247    else
3248     if gr.m_imageFilter = Bilinear then
3249      begin
3250       clr.ConstrInt(0 ,0 ,0 ,0 );
3251       sb.Construct(
3252        @gr.m_allocator ,
3253        @img.renBuf ,
3254        @clr ,
3255        interpolator ,
3256        rgba_order );
3257 
3258       sc.Construct(@sb ,@blend );
3259       ri.Construct(renBase ,@sc );
3260 
3261       render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ri );
3262 
3263      end
3264     else
3265      if gr.m_imageFilterLut.diameter = 2 then
3266       begin
3267        clr.ConstrInt(0 ,0 ,0 ,0 );
3268        s2.Construct(
3269         @gr.m_allocator ,
3270         @img.renBuf ,
3271         @clr ,
3272         interpolator,
3273         @gr.m_imageFilterLut ,
3274         rgba_order );
3275 
3276        sc.Construct(@s2 ,@blend );
3277        ri.Construct(renBase ,@sc );
3278 
3279        render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ri );
3280 
3281       end
3282      else
3283       begin
3284        clr.ConstrInt(0 ,0 ,0 ,0 );
3285        si.Construct(
3286         @gr.m_allocator ,
3287         @img.renBuf ,
3288         @clr ,
3289         interpolator ,
3290         @gr.m_imageFilterLut ,
3291         rgba_order );
3292 
3293        sc.Construct(@si ,@blend );
3294        ri.Construct(renBase ,@sc );
3295 
3296        render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ri );
3297 
3298       end;
3299 
3300   end;
3301 
3302 end;
3303 
3304 { AGG2DUSESFREETYPE }
Agg2DUsesFreeTypenull3305 function Agg2DUsesFreeType : boolean;
3306 begin
3307 {$IFDEF AGG2D_USE_FREETYPE }
3308  result:=true;
3309 {$ELSE }
3310  result:=false;
3311 {$ENDIF }
3312 
3313 end;
3314 
Agg2DUsesWin32TrueTypenull3315 function Agg2DUsesWin32TrueType: boolean;
3316 begin
3317 {$IFDEF AGG2D_USE_WINFONTS }
3318  result:=true;
3319 {$ELSE }
3320  result:=false;
3321 {$ENDIF }
3322 end;
3323 
3324 end.
3325 
3326