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