1 // Copyright (c) 2007 - 2008
2 //
3 // Permission to copy, use, modify, sell and distribute this software
4 // is granted provided this copyright notice appears in all copies.
5 // This software is provided "as is" without express or implied
6 // warranty, and with no claim as to its suitability for any purpose.
7 //
8 //
9 //
10 unit agg_fpimage;
11
12
13 {$mode objfpc}{$H+}
14
15 interface
16
17 {$IFDEF LINUX}
18 {$DEFINE AGG2D_USE_FREETYPE}
19 {$ENDIF}
20 {$IFDEF FREEBSD}
21 {$DEFINE AGG2D_USE_FREETYPE}
22 {$ENDIF}
23 {$IFDEF WINDOWS}
24 {$DEFINE AGG2D_USE_WINFONTS}
25 {$ENDIF}
26 {$IFNDEF AGG2D_USE_WINFONTS}
27 {$IFNDEF AGG2D_USE_FREETYPE}
28 {$DEFINE AGG2D_NO_FONT}
29 {$ENDIF}
30 {$ENDIF}
31
32 uses
33 agg_basics ,
34 agg_array ,
35 agg_trans_affine ,
36 agg_trans_viewport ,
37 agg_path_storage ,
38 agg_conv_stroke ,
39 agg_conv_transform ,
40 agg_conv_curve ,
41 agg_rendering_buffer ,
42 agg_renderer_base ,
43 agg_renderer_scanline ,
44 agg_span_gradient ,
45 agg_span_image_filter_rgba ,
46 agg_span_image_resample_rgba ,
47 agg_span_converter ,
48 agg_span_interpolator_linear ,
49 agg_span_allocator ,
50 agg_rasterizer_scanline_aa ,
51 agg_gamma_functions ,
52 agg_scanline_u ,
53 agg_scanline,
54 agg_arc ,
55 agg_bezier_arc ,
56 agg_rounded_rect ,
57 agg_font_engine ,
58 agg_font_cache_manager ,
59 agg_pixfmt ,
60 agg_pixfmt_rgb ,
61 agg_pixfmt_rgba ,
62 agg_color ,
63 agg_math_stroke ,
64 agg_image_filters ,
65 agg_vertex_source ,
66 agg_render_scanlines ,
67
68 {$IFDEF AGG2D_USE_FREETYPE}
69 agg_font_freetype,
70 {$ENDIF }
71 {$IFDEF AGG2D_USE_WINFONTS}
72 agg_font_win32_tt,
73 {$ENDIF }
74
75 Math, types ,
76 {$IFDEF WINDOWS}
77 Windows ,
78 {$ENDIF}
79
80 Classes, SysUtils, FPimage, FPCanvas;
81
82 { GLOBAL VARIABLES & CONSTANTS }
83 const
84 // LineJoin
85 AGG_JoinMiter = miter_join;
86 AGG_JoinRound = round_join;
87 AGG_JoinBevel = bevel_join;
88
89 // LineCap
90 AGG_CapButt = butt_cap;
91 AGG_CapSquare = square_cap;
92 AGG_CapRound = round_cap;
93
94 // TextAlignment
95 AGG_AlignLeft = 0;
96 AGG_AlignRight = 1;
97 AGG_AlignCenter = 2;
98 AGG_AlignTop = AGG_AlignRight;
99 AGG_AlignBottom = AGG_AlignLeft;
100
101 // BlendMode
102 AGG_BlendAlpha = end_of_comp_op_e;
103 AGG_BlendClear = comp_op_clear;
104 AGG_BlendSrc = comp_op_src;
105 AGG_BlendDst = comp_op_dst;
106 AGG_BlendSrcOver = comp_op_src_over;
107 AGG_BlendDstOver = comp_op_dst_over;
108 AGG_BlendSrcIn = comp_op_src_in;
109 AGG_BlendDstIn = comp_op_dst_in;
110 AGG_BlendSrcOut = comp_op_src_out;
111 AGG_BlendDstOut = comp_op_dst_out;
112 AGG_BlendSrcAtop = comp_op_src_atop;
113 AGG_BlendDstAtop = comp_op_dst_atop;
114 AGG_BlendXor = comp_op_xor;
115 AGG_BlendAdd = comp_op_plus;
116 AGG_BlendSub = comp_op_minus;
117 AGG_BlendMultiply = comp_op_multiply;
118 AGG_BlendScreen = comp_op_screen;
119 AGG_BlendOverlay = comp_op_overlay;
120 AGG_BlendDarken = comp_op_darken;
121 AGG_BlendLighten = comp_op_lighten;
122 AGG_BlendColorDodge = comp_op_color_dodge;
123 AGG_BlendColorBurn = comp_op_color_burn;
124 AGG_BlendHardLight = comp_op_hard_light;
125 AGG_BlendSoftLight = comp_op_soft_light;
126 AGG_BlendDifference = comp_op_difference;
127 AGG_BlendExclusion = comp_op_exclusion;
128 AGG_BlendContrast = comp_op_contrast;
129
130 { TYPES DEFINITION }
131 type
132 PAggColor = ^TAggColor;
133 TAggColor = rgba8;
134
135 TAggRectD = agg_basics.rect_d;
136
137 TAggAffine = trans_affine;
138 PAggAffine = trans_affine_ptr;
139
140 TAggFontRasterizer = gray8_adaptor_type;
141 PAggFontRasterizer = gray8_adaptor_type_ptr;
142
143 TAggFontScanline = gray8_scanline_type;
144 PAggFontScanline = gray8_scanline_type_ptr;
145
146 {$IFDEF AGG2D_USE_FREETYPE }
147 TAggFontEngine = font_engine_freetype_int32;
148 {$ENDIF}
149 {$IFDEF AGG2D_USE_WINFONTS }
150 TAggFontEngine = font_engine_win32_tt_int32;
151
152 {$ENDIF }
153
154 TAggGradient = (
155 AGG_Solid ,
156 AGG_Linear ,
157 AGG_Radial );
158 TAggDirection = (
159 AGG_CW,
160 AGG_CCW );
161
162 TAggLineJoin = int;
163 TAggLineCap = int;
164 TAggBlendMode = comp_op_e;
165
166 TAggTextAlignment = int;
167
168 TAggDrawPathFlag = (
169 AGG_FillOnly ,
170 AGG_StrokeOnly ,
171 AGG_FillAndStroke ,
172 AGG_FillWithLineColor );
173
174 TAggViewportOption = (
175 AGG_Anisotropic ,
176 AGG_XMinYMin ,
177 AGG_XMidYMin ,
178 AGG_XMaxYMin ,
179 AGG_XMinYMid ,
180 AGG_XMidYMid ,
181 AGG_XMaxYMid ,
182 AGG_XMinYMax ,
183 AGG_XMidYMax ,
184 AGG_XMaxYMax );
185
186 TAggImageFilter = (
187 AGG_NoFilter ,
188 AGG_Bilinear ,
189 AGG_Hanning ,
190 AGG_Hermite ,
191 AGG_Quadric ,
192 AGG_Bicubic ,
193 AGG_Catrom ,
194 AGG_Spline16 ,
195 AGG_Spline36 ,
196 AGG_Blackman144 );
197
198 TAggImageResample = (
199 AGG_NoResample ,
200 AGG_ResampleAlways ,
201 AGG_ResampleOnZoomOut );
202
203 TAggFontCacheType = (
204 AGG_RasterFontCache ,
205 AGG_VectorFontCache );
206
207 PAggTransformations = ^TAggTransformations;
208 TAggTransformations = record
209 affineMatrix : array[0..5 ] of double;
210 end;
211
212 { TAggRasterizerGamma }
213
214 TAggRasterizerGamma = object(vertex_source )
215 m_alpha : gamma_multiply;
216 m_gamma : gamma_power;
217
218 constructor Construct(alpha ,gamma : double );
219
func_operator_gammanull220 function func_operator_gamma(x : double ) : double; virtual;
operator_arraynull221 function operator_array(i: unsigned): unsigned; virtual;
222 end;
223
224 { TAggFP_renderer_scanline_aa }
225
226 TAggFP_renderer_scanline_aa = object(renderer_scanline_aa)
227 procedure add_path(vs: vertex_source_ptr; path_id: unsigned=0); virtual;
228 procedure add_vertex(x, y: double; cmd: unsigned); virtual;
229 procedure clip_box(x1, y1, x2, y2: double); virtual;
230 procedure color_(c: aggclr_ptr); virtual;
231 procedure filling_rule(filling_rule_: filling_rule_e); virtual;
232 procedure gamma(gamma_function: vertex_source_ptr); virtual;
233 procedure reset; virtual;
_max_xnull234 function _max_x: int; virtual;
_max_ynull235 function _max_y: int; virtual;
_min_xnull236 function _min_x: int; virtual;
_min_ynull237 function _min_y: int; virtual;
hit_testnull238 function hit_test(tx, ty: int): boolean; virtual;
sweep_scanlinenull239 function sweep_scanline(sl: scanline_ptr): boolean; virtual;
sweep_scanline_emnull240 function sweep_scanline_em(sl: scanline_ptr): boolean; virtual;
rewind_scanlinesnull241 function rewind_scanlines: boolean; virtual;
242 procedure sort; virtual;
243 end;
244
245 type
246 TAggFPImage = class;
247
248 TAggFPImgPixelFormat = (
249 afpimRGB24,
250 afpimRGBA32
251 );
252
253 TAggFPImgOperation = (
254 afpioResized,
255 afpioPixelFormatChanged,
256 afpioDestroying
257 );
258 TAggFPImgEvent = procedure(TheImage: TAggFPImage;
259 Operation: TAggFPImgOperation) of object;
260
261 { TAggFPImage }
262
263 TAggFPImage = class(TFPCustomImage)
264 private
265 FData: PByte;
266 FListeners: array of TAggFPImgEvent;
267 FPixelFormat: TAggFPImgPixelFormat;
268 protected
269 procedure SetInternalColor(x, y: integer; const Value: TFPColor); override;
GetInternalColornull270 function GetInternalColor(x, y: integer): TFPColor; override;
GetInternalPixelnull271 function GetInternalPixel(x, y: integer): integer; override;
272 procedure SetInternalPixel(x, y: integer; Value: integer); override;
273 procedure SetPixelFormat(const AValue: TAggFPImgPixelFormat); virtual;
274 procedure SetUsePalette(Value: boolean); override;
275 procedure ReallocData; virtual;
276 public
277 RenderingBuffer: rendering_buffer;
278 constructor Create(AWidth, AHeight: integer); override;
279 destructor Destroy; override;
280 procedure Assign(Source: TPersistent); override;
281 procedure SetSize(AWidth, AHeight: integer); override;
282 procedure AddListener(Event: TAggFPImgEvent);
283 procedure RemoveListener(Event: TAggFPImgEvent);
284 procedure NotifyListeners(Operation: TAggFPImgOperation);
285 property PixelFormat: TAggFPImgPixelFormat read FPixelFormat write SetPixelFormat;
286 property Data: PByte read FData;
DataSizenull287 function DataSize: PtrUInt; // total size of Data in bytes
LineSizenull288 function LineSize: PtrUInt; // size of a line in bytes including padding
289 end;
290
291 { TAggFPBrush }
292
293 TAggFPBrush = class(TFPCustomBrush)
294 private
295 FAggColor: TAggColor;
296 FAggFillEvenOdd: boolean;
297 protected
298 procedure SetFPColor(const AValue: TFPColor); override;
299 procedure SetAggColor(const AValue: TAggColor); virtual;
300 procedure SetStyle(AValue: TFPBrushStyle); override;
301 procedure SetAggFillEvenOdd(const AValue: boolean); virtual;
302 procedure DoCopyProps(From: TFPCanvasHelper); override;
303 public
304 property AggColor: TAggColor read FAggColor write SetAggColor;
305 property AggFillEvenOdd: boolean read FAggFillEvenOdd write SetAggFillEvenOdd;
306 property Pattern; // not supported, always 0
307 property Image; // not supported, always nil
308 property Style; // not supported, always bsSolid
309 end;
310
311 { TAggFPPen }
312
313 TAggFPPen = class(TFPCustomPen)
314 private
315 FAggColor: TAggColor;
316 FAggLineCap: TAggLineCap;
317 FAggLineJoin: TAggLineJoin;
318 FAggLineWidth: double;
319 protected
320 procedure SetAggLineCap(const AValue: TAggLineCap); virtual;
321 procedure SetAggLineJoin(const AValue: TAggLineJoin); virtual;
322 procedure SetAggLineWidth(const AValue: double); virtual;
323 procedure SetWidth(AValue: Integer); override;
324 procedure SetFPColor(const AValue: TFPColor); override;
325 procedure SetAggColor(const AValue: TAggColor); virtual;
326 procedure DoCopyProps(From: TFPCanvasHelper); override;
327 public
328 constructor Create; override;
329 property AggLineCap: TAggLineCap read FAggLineCap write SetAggLineCap default AGG_CapRound;
330 property AggLineJoin: TAggLineJoin read FAggLineJoin write SetAggLineJoin default AGG_JoinRound;
331 property AggLineWidth: double read FAggLineWidth write SetAggLineWidth;
332 property AggColor: TAggColor read FAggColor write SetAggColor;
333 property Pattern; // not supported, always 0
334 property Style; // not supported, always psSolid
335 property Mode; // not supported, always pmBlack
336 end;
337
338 { TAggFPFont }
339
340 TAggFPFont = class(TFPCustomFont)
341 private
342 FAggAlignX: TAggTextAlignment;
343 FAggAlignY: TAggTextAlignment;
344 FAggAngle: double;
345 FAggCache: TAggFontCacheType;
346 FAggColor: TAggColor;
347 FAggFlipY: boolean;
348 FAggHeight: double;
349 FAggHinting: boolean;
350 FAggUseOnlyFont: boolean;
351 protected
352 procedure DoCopyProps(From: TFPCanvasHelper); override;
353 procedure SetFPColor(const AValue: TFPColor); override;
354 procedure SetAggColor(const AValue: TAggColor); virtual;
355 procedure SetAggAlignX(const AValue: TAggTextAlignment); virtual;
356 procedure SetAggAlignY(const AValue: TAggTextAlignment); virtual;
357 procedure SetAggAngle(const AValue: double); virtual;
358 procedure SetAggFlipY(const AValue: boolean); virtual;
359 procedure SetAggHeight(const AValue: double); virtual;
360 procedure SetAggHinting(const AValue: boolean); virtual;
361 procedure SetSize(AValue: integer); override;
362 public
363 constructor Create; override;
364 procedure LoadFromFile(aFilename : String;
365 const NewHeight: double = 10.0;
366 const NewBold: boolean = false;
367 const NewItalic: boolean = false;
368 const NewCache : TAggFontCacheType = AGG_VectorFontCache;
369 const NewAngle : double = 0.0 ;
370 const NewHinting: boolean = true);
AggHeightToSizenull371 function AggHeightToSize(const h: double): double; virtual;
SizeToAggHeightnull372 function SizeToAggHeight(const s: double): double; virtual;
373 property AggColor: TAggColor read FAggColor write SetAggColor;
374 property AggAlignX: TAggTextAlignment read FAggAlignX write SetAggAlignX default AGG_AlignLeft;
375 property AggAlignY: TAggTextAlignment read FAggAlignY write SetAggAlignY default AGG_AlignBottom;
376 property AggHinting: boolean read FAggHinting write SetAggHinting default True;// only freetype
377 property AggAngle: double read FAggAngle write SetAggAngle;
378 property AggCache: TAggFontCacheType read FAggCache;
379 property AggHeight: double read FAggHeight write SetAggHeight;
380 property AggFlipY: boolean read FAggFlipY write SetAggFlipY;
381 property AggUseOnlyFont: boolean read FAggUseOnlyFont write FAggUseOnlyFont default True;// do not use Pen and Brush
382 property Bold; // only windows
383 property Italic; // only windows
384 property Underline; // not supported
385 {$IF (FPC_FULLVERSION<=20600) or (FPC_FULLVERSION=20602)}
386 property StrikeTrough; //old version with typo
387 {$ELSE}
388 property StrikeThrough;
389 {$ENDIF}
390 end;
391
392 { TAggFPPath }
393
394 TAggFPPath = class(TFPCanvasHelper)
395 private
396 FAggColor: TAggColor;
397 procedure SetAggColor(const AValue: TAggColor);
398 protected
399 procedure DoCopyProps(From: TFPCanvasHelper); override;
400 public
401 m_path: path_storage;
402 m_convCurve: conv_curve;
403 constructor Create; override;
404 destructor Destroy; override;
405 property AggColor: TAggColor read FAggColor write SetAggColor;
406 end;
407
408 { TAggFPCanvas }
409
410 TAggFPCanvas = class(TFPCustomCanvas)
411 protected
412 FAggBrush: TAggFPBrush;
413 FAggFont: TAggFPFont;
414 FAggPen: TAggFPPen;
415 FAggPath: TAggFPPath;
416 FImage: TAggFPImage;
417 FUseUTF8: boolean;
418
419 m_rbuf : rendering_buffer;
420
421 m_pixFormat ,m_pixFormatComp ,m_pixFormatPre ,m_pixFormatCompPre : pixel_formats;
422 m_renBase ,m_renBaseComp ,m_renBasePre ,m_renBaseCompPre : renderer_base;
423
424 m_renSolid ,m_renSolidComp : renderer_scanline_aa_solid;
425
426 m_allocator : span_allocator;
427 m_clipBox : TAggRectD;
428
429 m_blendMode ,m_imageBlendMode : TAggBlendMode;
430
431 m_imageBlendColor : TAggColor;
432
433 m_scanline : scanline_u8;
434 m_rasterizer : rasterizer_scanline_aa;
435
436 m_masterAlpha ,m_antiAliasGamma : double;
437
438 m_fillGradient ,m_lineGradient : pod_auto_array;
439
440 m_fillGradientFlag ,m_lineGradientFlag : TAggGradient;
441
442 m_fillGradientMatrix ,m_lineGradientMatrix : trans_affine;
443
444 m_fillGradientD1 ,
445 m_lineGradientD1 ,
446 m_fillGradientD2 ,
447 m_lineGradientD2 : double;
448
449 m_imageFilter : TAggImageFilter;
450 m_imageResample : TAggImageResample;
451 m_imageFilterLut : image_filter_lut;
452
453 m_fillGradientInterpolator ,
454 m_lineGradientInterpolator : span_interpolator_linear;
455
456 m_linearGradientFunction : gradient_x;
457 m_radialGradientFunction : gradient_circle;
458
459 m_evenOddFlag : boolean;
460
461 m_transform : trans_affine;
462
463 m_convStroke : conv_stroke;
464
465 m_pathTransform ,m_strokeTransform : conv_transform;
466
467 {$IFDEF AGG2D_USE_WINFONTS }
468 m_fontDC : HDC;
469 {$ENDIF }
470
471 {$IFNDEF AGG2D_NO_FONT}
472 m_fontEngine : TAggFontEngine;
473 m_fontCacheManager : font_cache_manager;
474 {$ENDIF}
475
476 // Other Pascal-specific members
477 m_gammaNone : gamma_none;
478 m_gammaAgg2D : TAggRasterizerGamma;
479
480 m_ifBilinear : image_filter_bilinear;
481 m_ifHanning : image_filter_hanning;
482 m_ifHermite : image_filter_hermite;
483 m_ifQuadric : image_filter_quadric;
484 m_ifBicubic : image_filter_bicubic;
485 m_ifCatrom : image_filter_catrom;
486 m_ifSpline16 : image_filter_spline16;
487 m_ifSpline36 : image_filter_spline36;
488 m_ifBlackman144 : image_filter_blackman144;
489
490 procedure Agg2DRenderer_render(renBase: renderer_base_ptr;
491 renSolid: renderer_scanline_aa_solid_ptr; fillColor_, UseFont: boolean);
492 procedure Agg2DRenderer_render(
493 renBase : renderer_base_ptr;
494 renSolid : renderer_scanline_aa_solid_ptr;
495 ras : gray8_adaptor_type_ptr;
496 sl : gray8_scanline_type_ptr;
497 UseFont: boolean );
498 procedure addLine(const x1 ,y1 ,x2 ,y2 : double );
GetAggTransformationsnull499 function GetAggTransformations: TAggTransformations;
500
501 procedure render(fillColor_: boolean; UseFont: boolean = false);
502 procedure render(ras : PAggFontRasterizer; sl : PAggFontScanline );
503 procedure Agg2DRenderer_renderImage(
504 img : TAggFPImage;
505 renBase : renderer_base_ptr;
506 interpolator : span_interpolator_linear_ptr );
507
508 procedure SetAggTransformations(const AValue: TAggTransformations);
509 procedure SetAntiAliasGamma(const AValue: double);
510 procedure SetBlendMode(const AValue: TAggBlendMode);
511 procedure SetImageFilter(const AValue: TAggImageFilter);
512 procedure SetImageResample(const AValue: TAggImageResample);
513 procedure SetMasterAlpha(const AValue: double);
514 procedure UpdateRasterizerGamma;
515
516 protected
517 procedure DoCopyRect(DstX, DstY: integer; SrcCanvas: TFPCustomCanvas;
518 const SourceRect: TRect); override;
DoCreateDefaultBrushnull519 function DoCreateDefaultBrush: TFPCustomBrush; override;
DoCreateDefaultFontnull520 function DoCreateDefaultFont: TFPCustomFont; override;
DoCreateDefaultPennull521 function DoCreateDefaultPen: TFPCustomPen; override;
DoCreateDefaultPathnull522 function DoCreateDefaultPath: TAggFPPath; virtual;
DoCreateDefaultImagenull523 function DoCreateDefaultImage: TAggFPImage; virtual;
524 procedure DoDraw(x, y: integer; const SrcImage: TFPCustomImage); override;
525 procedure DoEllipse(const Bounds: TRect); override;
526 procedure DoEllipseFill(const Bounds: TRect); override;
527 procedure DoFloodFill(x, y: integer); override;
DoGetTextHeightnull528 function DoGetTextHeight(str: string): integer; override;
529 procedure DoGetTextSize(str: string; var w, h: integer); override;
DoGetTextWidthnull530 function DoGetTextWidth(str: string): integer; override;
531 procedure DoLine(x1, y1, x2, y2: integer); override;
532 procedure DoPolygon(const points: array of TPoint); override;
533 procedure DoPolygonFill(const points: array of TPoint); override;
534 procedure DoPolyline(const points: array of TPoint); override;
535 procedure DoRectangle(const Bounds: TRect); override;
536 procedure DoRectangleFill(const Bounds: TRect); override;
537 procedure DoTextOut(x, y: integer; str: string); override;
GetColornull538 function GetColor(x, y: integer): TFPColor; override;
GetHeightnull539 function GetHeight: integer; override;
GetWidthnull540 function GetWidth: integer; override;
541 procedure SetColor(x, y: integer; const Value: TFPColor); override;
542 procedure SetHeight(AValue: integer); override;
543 procedure SetWidth(AValue: integer); override;
544 procedure OnImageOperation(Img: TAggFPImage; Operation: TAggFPImgOperation); virtual;
545 public
546 constructor Create;
547 destructor Destroy; override;
548 procedure ClearSettings; virtual;
549
550 procedure AggClearAll(const c : TAggColor );
551 procedure AggClearAll(const r ,g ,b : byte; a : byte = 255 );
552
553 property Image: TAggFPImage read FImage;
554 property Pen: TAggFPPen read FAggPen;
555 property Brush: TAggFPBrush read FAggBrush;
556 property Font: TAggFPFont read FAggFont;
557 property Path: TAggFPPath read FAggPath;
558
559 procedure Erase; override;
560
561 // special AggPas functions, prefixed with Agg to avoid name clashing
562
563 property AggBlendMode: TAggBlendMode read m_blendMode write SetBlendMode;
564 property AggMasterAlpha: double read m_masterAlpha write SetMasterAlpha;
565 property AggAntiAliasGamma: double read m_antiAliasGamma write SetAntiAliasGamma;
566
567 // Basic AggPas Shapes
568 procedure AggLine (const x1 ,y1 ,x2 ,y2 : double );
569 procedure AggTriangle (const x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double );
570 procedure AggRectangle(const x1 ,y1 ,x2 ,y2 : double );
571
572 procedure AggRoundedRect(const x1 ,y1 ,x2 ,y2 ,r : double );
573 procedure AggRoundedRect(const x1 ,y1 ,x2 ,y2 ,rx ,ry : double );
574 procedure AggRoundedRect(const x1 ,y1 ,x2 ,y2 ,
575 rxBottom ,ryBottom ,
576 rxTop ,ryTop : double );
577
578 procedure AggEllipse(const cx ,cy ,rx ,ry : double );
579
580 procedure AggArc (const cx ,cy ,rx ,ry ,start ,endangle : double ); // start: 0 at 3'o clock, clockwise in rad: 180deg = 1pi
581 procedure AggStar(const cx, cy, r1, r2, startAngle: double; numRays: integer);
582
583 procedure AggCurve(const x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double );
584 procedure AggCurve(const x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,x4 ,y4 : double );
585
586 procedure AggPolygon (const xy : PDouble; numPoints : integer );
587 procedure AggPolyline(const xy : PDouble; numPoints : integer );
588
589 procedure AggFillLinearGradient(const x1 ,y1 ,x2 ,y2 : double; c1 ,c2 : TAggColor; profile : double = 1.0 );
590 procedure AggLineLinearGradient(const x1 ,y1 ,x2 ,y2 : double; c1 ,c2 : TAggColor; profile : double = 1.0 );
591
592 procedure AggFillRadialGradient(const x ,y ,r : double; c1 ,c2 : TAggColor; profile : double = 1.0 );
593 procedure AggLineRadialGradient(const x ,y ,r : double; c1 ,c2 : TAggColor; profile : double = 1.0 );
594
595 procedure AggFillRadialGradient(const x ,y ,r : double; c1 ,c2 ,c3 : TAggColor );
596 procedure AggLineRadialGradient(const x ,y ,r : double; c1 ,c2 ,c3 : TAggColor );
597
598 procedure AggFillRadialGradient(const x ,y ,r : double );
599 procedure AggLineRadialGradient(const x ,y ,r : double );
600
601 // Path Commands
602 procedure AggResetPath;
603
604 procedure AggMoveTo (const x ,y : double );
605 procedure AggMoveRel(const dx ,dy : double );
606
607 procedure AggLineTo (const x ,y : double );
608 procedure AggLineRel(const dx ,dy : double );
609
610 procedure AggHorLineTo (const x : double );
611 procedure AggHorLineRel(const dx : double );
612
613 procedure AggVerLineTo (const y : double );
614 procedure AggVerLineRel(const dy : double );
615
616 procedure AggArcTo(const
617 rx ,ry ,angle : double;
618 largeArcFlag ,sweepFlag : boolean;
619 const x ,y : double );
620
621 procedure AggArcRel(const
622 rx ,ry ,angle : double;
623 largeArcFlag ,sweepFlag : boolean;
624 const dx ,dy : double );
625
626 procedure AggQuadricCurveTo (const xCtrl ,yCtrl ,xTo ,yTo : double );
627 procedure AggQuadricCurveRel(const dxCtrl ,dyCtrl ,dxTo ,dyTo : double );
628 procedure AggQuadricCurveTo (const xTo ,yTo : double );
629 procedure AggQuadricCurveRel(const dxTo ,dyTo : double );
630
631 procedure AggCubicCurveTo (const xCtrl1 ,yCtrl1 ,xCtrl2 ,yCtrl2 ,xTo ,yTo : double );
632 procedure AggCubicCurveRel(const dxCtrl1 ,dyCtrl1 ,dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo : double );
633 procedure AggCubicCurveTo (const xCtrl2 ,yCtrl2 ,xTo ,yTo : double );
634 procedure AggCubicCurveRel(const dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo : double );
635
636 procedure AggAddEllipse(const cx ,cy ,rx ,ry : double; dir : TAggDirection );
637
638 procedure AggClosePolygon;
639 procedure AggDrawPath(flag: TAggDrawPathFlag = AGG_FillAndStroke;
640 UseFont: boolean = false);
641
642 // Clipping
643 procedure AggSetClipBox(const x1 ,y1 ,x2 ,y2 : double );
644 function AggGetClipBox : TAggRectD;
645 procedure AggClearClipBox(const c : TAggColor );
646 procedure AggClearClipBox(r ,g ,b : byte; a : byte = 255 );
647 function AggInClipBox(const worldX ,worldY : double ) : boolean;
648
649 // Affine Transformations
650 property AggTransformations: TAggTransformations read GetAggTransformations
651 write SetAggTransformations;
652 procedure AggResetTransformations;
653
654 procedure AggAffine(const tr : PAggAffine );
655 procedure AggAffine(const tr : PAggTransformations );
656
657 procedure AggRotate (const angle : double );
658 procedure AggScale (const sx ,sy : double );
659 procedure AggSkew (const sx ,sy : double );
660 procedure AggTranslate(const x ,y : double );
661
662 procedure AggParallelogram(const x1 ,y1 ,x2 ,y2 : double; para : PDouble );
663
664 procedure AggViewport(const
665 worldX1 ,worldY1 ,worldX2 ,worldY2 ,
666 screenX1 ,screenY1 ,screenX2 ,screenY2 : double;
667 const opt : TAggViewportOption = AGG_XMidYMid );
668
669 // Coordinates Conversions
670 procedure AggWorldToScreen(x ,y : PDouble );
671 procedure AggScreenToWorld(x ,y : PDouble );
672 function AggWorldToScreen(const scalar : double ) : double;
673 function AggScreenToWorld(const scalar : double ) : double;
674
675 procedure AggAlignPoint(x ,y : PDouble );
676
677 // Image Rendering
678 property AggImageFilter: TAggImageFilter read m_imageFilter write SetImageFilter;
679 property AggImageResample: TAggImageResample read m_imageResample write SetImageResample;
680
681 procedure AggRenderImage(
682 img : TAggFPImage;
683 x1 ,y1 ,x2 ,y2 : integer;
684 parl : PDouble );
685
686 procedure AggTransformImage(
687 SrcImage: TAggFPImage;
688 const imgX1 ,imgY1 ,imgX2 ,imgY2 : integer;
689 const dstX1 ,dstY1 ,dstX2 ,dstY2 : double );
690
691 procedure AggTransformImage(
692 SrcImage: TAggFPImage;
693 const dstX1 ,dstY1 ,dstX2 ,dstY2 : double );
694
695 procedure AggTransformImage(
696 SrcImage: TAggFPImage;
697 imgX1 ,imgY1 ,imgX2 ,imgY2 : integer;
698 parallelo : PDouble );
699
700 procedure AggTransformImage(SrcImage: TAggFPImage; parallelo : PDouble );
701
702 procedure AggTransformImagePath(
703 SrcImage: TAggFPImage;
704 const imgX1 ,imgY1 ,imgX2 ,imgY2 : integer;
705 const dstX1 ,dstY1 ,dstX2 ,dstY2 : double );
706
707 procedure AggTransformImagePath(
708 SrcImage: TAggFPImage;
709 const dstX1 ,dstY1 ,dstX2 ,dstY2 : double );
710
711 procedure AggTransformImagePath(
712 SrcImage: TAggFPImage;
713 const imgX1 ,imgY1 ,imgX2 ,imgY2 : integer;
714 const parallelo : PDouble );
715
716 procedure AggTransformImagePath(SrcImage: TAggFPImage; parallelo : PDouble );
717
718 procedure AggCopyImage(
719 SrcImage: TAggFPImage;
720 const imgX1 ,imgY1 ,imgX2 ,imgY2 : integer;
721 const dstX ,dstY : double );
722
723 procedure AggCopyImage(SrcImage: TAggFPImage; const dstX ,dstY: double);
724
725 // text
726 function AggTextWidth(str : AnsiString ) : double; virtual;
727 function AggTextHeight(str : AnsiString ) : double; virtual;
728 procedure AggTextOut(
729 const x ,y : double;
730 str : AnsiString;
731 roundOff : boolean = false;
732 const ddx : double = 0.0;
733 const ddy : double = 0.0 ); virtual;
734 property UseUTF8: boolean read FUseUTF8 write FUseUTF8;
735 end;
736
737 function FPToAggColor(const c: TFPColor): TAggColor;
738 function AggToFPColor(const c: TAggColor): TFPColor;
739
740 function AggUTF8CharToUnicode(p: PChar; out CharLen: int): int32u;
741
742 implementation
743
744 const
745 PixelSize: array [TAggFPImgPixelFormat] of Integer = (3, 4);
746
747 var
748 g_approxScale : double = 2.0;
749
750 type
751 //PAggSpanConvImageBlend = ^TAggSpanConvImageBlend;
752
753 { TAggSpanConvImageBlend }
754
755 TAggSpanConvImageBlend = object(span_convertor )
756 private
757 m_mode : TAggBlendMode;
758 m_color : TAggColor;
759 m_pixel : pixel_formats_ptr; // m_pixFormatCompPre
760 public
761 constructor Construct(m : TAggBlendMode; c : TAggColor; p : pixel_formats_ptr );
762 procedure convert(span : aggclr_ptr; x ,y : int; len : unsigned ); virtual;
763 end;
764
765 { TAggSpanConvImageBlend }
766
767 constructor TAggSpanConvImageBlend.Construct(m: TAggBlendMode; c: TAggColor;
768 p: pixel_formats_ptr);
769 begin
770 m_mode :=m;
771 m_color:=c;
772 m_pixel:=p;
773 end;
774
775 procedure TAggSpanConvImageBlend.convert(span: aggclr_ptr; x, y: int;
776 len: unsigned);
777 var
778 l2 ,a : unsigned;
779 s2 : PAggColor;
780 begin
781 if (m_mode <> AGG_BlendDst ) and
782 (m_pixel <> NIL ) then
783 begin{!}
784 l2:=len;
785 s2:=PAggColor(span );
786
787 repeat
788 comp_op_adaptor_clip_to_dst_rgba_pre(
789 m_pixel ,
790 unsigned(m_mode ) ,
791 int8u_ptr(s2 ) ,
792 m_color.r ,
793 m_color.g ,
794 m_color.b ,
795 base_mask ,
796 cover_full );
797
798 inc(ptrcomp(s2 ) ,sizeof(aggclr ) );
799 dec(l2 );
800
801 until l2 = 0;
802
803 end;
804
805 if m_color.a < base_mask then
806 begin
807 l2:=len;
808 s2:=PAggColor(span );
809 a :=m_color.a;
810
811 repeat
812 s2^.r:=(s2^.r * a ) shr base_shift;
813 s2^.g:=(s2^.g * a ) shr base_shift;
814 s2^.b:=(s2^.b * a ) shr base_shift;
815 s2^.a:=(s2^.a * a ) shr base_shift;
816
817 inc(ptrcomp(s2 ) ,sizeof(aggclr ) );
818 dec(l2 );
819
820 until l2 = 0;
821
822 end;
823 end;
824
825 function FPToAggColor(const c: TFPColor): TAggColor;
826 begin
827 Result.r:=c.red shr 8;
828 Result.g:=c.green shr 8;
829 Result.b:=c.blue shr 8;
830 Result.a:=c.alpha shr 8;
831 end;
832
833 function AggToFPColor(const c: TAggColor): TFPColor;
834 begin
835 Result.red:=c.r or (c.r shl 8);
836 Result.green:=c.g or (c.g shl 8);
837 Result.blue:=c.b or (c.b shl 8);
838 Result.alpha:=c.a or (c.a shl 8);
839 end;
840
841 function AggUTF8CharToUnicode(p: PChar; out CharLen: int): int32u;
842 begin
843 if p=nil then begin
844 Result:=0;
845 CharLen:=0;
846 exit;
847 end;
848 if ord(p^)<%11000000 then begin
849 // regular single byte character (#0 is a normal char, this is pascal ;)
850 end
851 else if ((ord(p^) and %11100000) = %11000000) then begin
852 // could be double byte character
853 if (ord(p[1]) and %11000000) = %10000000 then begin
854 Result:=((ord(p^) and %00011111) shl 6)
855 or (ord(p[1]) and %00111111);
856 CharLen:=2;
857 exit;
858 end;
859 end
860 else if ((ord(p^) and %11110000) = %11100000) then begin
861 // could be triple byte character
862 if ((ord(p[1]) and %11000000) = %10000000)
863 and ((ord(p[2]) and %11000000) = %10000000) then begin
864 Result:=((ord(p^) and %00011111) shl 12)
865 or ((ord(p[1]) and %00111111) shl 6)
866 or (ord(p[2]) and %00111111);
867 CharLen:=3;
868 exit;
869 end;
870 end
871 else if ((ord(p^) and %11111000) = %11110000) then begin
872 // could be 4 byte character
873 if ((ord(p[1]) and %11000000) = %10000000)
874 and ((ord(p[2]) and %11000000) = %10000000)
875 and ((ord(p[3]) and %11000000) = %10000000) then begin
876 Result:=((ord(p^) and %00001111) shl 18)
877 or ((ord(p[1]) and %00111111) shl 12)
878 or ((ord(p[2]) and %00111111) shl 6)
879 or (ord(p[3]) and %00111111);
880 CharLen:=4;
881 exit;
882 end;
883 end
884 else begin
885 // invalid character
886 end;
887 Result:=ord(p^);
888 CharLen:=1;
889 end;
890
891
892 { TAggFPImage }
893
894 procedure TAggFPImage.SetPixelFormat(const AValue: TAggFPImgPixelFormat);
895 begin
896 if FPixelFormat=AValue then exit;
897 FPixelFormat:=AValue;
898 ReallocData;
899 NotifyListeners(afpioPixelFormatChanged);
900 end;
901
902 procedure TAggFPImage.SetUsePalette(Value: boolean);
903 begin
904 if Value then
905 raise Exception.Create('palette not supported by '+ClassName);
906 end;
907
908 procedure TAggFPImage.ReallocData;
909 begin
910 ReAllocMem(fData,DataSize);
911 RenderingBuffer.Destruct;
912 RenderingBuffer.Construct(FData, Width, Height, LineSize);
913 end;
914
915 constructor TAggFPImage.Create(AWidth, AHeight: integer);
916 begin
917 RenderingBuffer.Construct;
918 inherited Create(AWidth, AHeight);
919 end;
920
921 procedure TAggFPImage.SetInternalColor(x, y: integer; const Value: TFPColor);
922 var
923 p: PByte;
924 begin
925 if (x>=0) and (y>=0) and (x<Width) and (y<Height) then begin
926 p:=@FData[(y*Width+x) * PixelSize[PixelFormat]];
927 case PixelFormat of
928 afpimRGB24:
929 begin
930 p[0]:=Value.red shr 8;
931 p[1]:=Value.green shr 8;
932 p[2]:=Value.blue shr 8;
933 end;
934 afpimRGBA32:
935 begin
936 p[0]:=Value.red shr 8;
937 p[1]:=Value.green shr 8;
938 p[2]:=Value.blue shr 8;
939 p[3]:=Value.alpha shr 8;
940 end;
941 end;
942 end;
943 end;
944
GetInternalColornull945 function TAggFPImage.GetInternalColor(x, y: integer): TFPColor;
946 var
947 p: PByte;
948 begin
949 if (x>=0) and (y>=0) and (x<Width) and (y<Height) then begin
950 p:=@FData[(y*Width+x) * PixelSize[PixelFormat]];
951 case PixelFormat of
952 afpimRGB24:
953 begin
954 Result.red:=p[0];
955 Result.red:=Result.red or (Result.red shl 8);
956 Result.green:=p[1];
957 Result.green:=Result.green or (Result.green shl 8);
958 Result.blue:=p[2];
959 Result.blue:=Result.blue or (Result.blue shl 8);
960 Result.alpha:=alphaOpaque;
961 end;
962 afpimRGBA32:
963 begin
964 Result.red:=p[0];
965 Result.red:=Result.red or (Result.red shl 8);
966 Result.green:=p[1];
967 Result.green:=Result.green or (Result.green shl 8);
968 Result.blue:=p[2];
969 Result.blue:=Result.blue or (Result.blue shl 8);
970 Result.alpha:=p[3];
971 Result.alpha:=Result.alpha or (Result.alpha shl 8);
972 end;
973 end;
974 end;
975 end;
976
GetInternalPixelnull977 function TAggFPImage.GetInternalPixel(x, y: integer): integer;
978 var
979 p: PByte;
980 begin
981 p:=@FData[(y*Width+x) * PixelSize[PixelFormat]];
982 case PixelFormat of
983 afpimRGB24:
984 begin
985 Result:=PInteger(p)^;
986 {$IFDEF ENDIAN_LITTLE}
987 Result:=Result and $ffffff;
988 {$ELSE}
989 Result:=Result shr 8;
990 {$ENDIF}
991 end;
992 afpimRGBA32: Result:=PInteger(p)^;
993 end;
994 end;
995
996 procedure TAggFPImage.SetInternalPixel(x, y: integer; Value: integer);
997 var
998 p: PByte;
999 begin
1000 p:=@FData[(y*Width+x) * PixelSize[PixelFormat]];
1001 case PixelFormat of
1002 afpimRGB24:
1003 begin
1004 {$IFDEF ENDIAN_LITTLE}
1005 // ToDo
1006 {$ELSE}
1007 // ToDo
1008 {$ENDIF}
1009 end;
1010 afpimRGBA32: PInteger(p)^:=Value;
1011 end;
1012 end;
1013
1014 destructor TAggFPImage.Destroy;
1015 begin
1016 NotifyListeners(afpioDestroying);
1017 ReAllocMem(FData,0);
1018 inherited Destroy;
1019 RenderingBuffer.Destruct;
1020 end;
1021
1022 procedure TAggFPImage.Assign(Source: TPersistent);
1023 var
1024 Src: TAggFPImage;
1025 begin
1026 if Source is TAggFPImage then begin
1027 Src:=TAggFPImage(Source);
1028 SetSize(0,0);
1029 PixelFormat:=Src.PixelFormat;
1030 SetSize(Src.Width,Src.Height);
1031 System.Move(Src.Data^,FData^,DataSize);
1032 end else
1033 inherited Assign(Source);
1034 end;
1035
1036 procedure TAggFPImage.SetSize(AWidth, AHeight: integer);
1037 begin
1038 if (Width=AWidth) and (Height=AHeight) then exit;
1039 inherited SetSize(AWidth, AHeight);
1040 ReallocData;
1041 NotifyListeners(afpioResized);
1042 end;
1043
1044 procedure TAggFPImage.AddListener(Event: TAggFPImgEvent);
1045 begin
1046 SetLength(FListeners,length(FListeners)+1);
1047 FListeners[length(FListeners)-1]:=Event;
1048 end;
1049
1050 procedure TAggFPImage.RemoveListener(Event: TAggFPImgEvent);
1051 var
1052 i: Integer;
1053 begin
1054 for i:=length(FListeners)-1 downto 0 do begin
1055 // compare Code and Data, do not use =
1056 if CompareMem(@FListeners[i],@Event,SizeOf(TAggFPImgEvent)) then begin
1057 // delete
1058 if i<length(FListeners) then
1059 System.Move(FListeners[i+1],FListeners[i],
1060 SizeOf(TAggFPImgEvent)*(length(FListeners)-i-1));
1061 SetLength(FListeners,length(FListeners)-1);
1062 end;
1063 end;
1064 end;
1065
1066 procedure TAggFPImage.NotifyListeners(Operation: TAggFPImgOperation);
1067 var
1068 i: Integer;
1069 begin
1070 for i:=length(FListeners)-1 downto 0 do
1071 FListeners[i](Self,Operation);
1072 end;
1073
DataSizenull1074 function TAggFPImage.DataSize: PtrUInt;
1075 begin
1076 Result:=Width*Height*PixelSize[PixelFormat];
1077 end;
1078
LineSizenull1079 function TAggFPImage.LineSize: PtrUInt;
1080 begin
1081 Result:=Width*PixelSize[PixelFormat];
1082 end;
1083
1084 { TAggFPCanvas }
1085
1086 procedure TAggFPCanvas.render(fillColor_: boolean; UseFont: boolean);
1087 begin
1088 if (m_blendMode = AGG_BlendAlpha ) or
1089 (Image.FPixelFormat = afpimRGB24 )
1090 then
1091 Agg2DRenderer_render(@m_renBase ,@m_renSolid ,fillColor_, UseFont )
1092 else
1093 Agg2DRenderer_render(@m_renBaseComp ,@m_renSolidComp ,fillColor_, UseFont );
1094 end;
1095
1096 procedure TAggFPCanvas.render(ras: PAggFontRasterizer; sl: PAggFontScanline);
1097 begin
1098 if (m_blendMode = AGG_BlendAlpha ) or
1099 (Image.PixelFormat = afpimRGB24 ) then
1100 Agg2DRenderer_render(@m_renBase ,@m_renSolid ,ras ,sl, Font.AggUseOnlyFont )
1101 else
1102 Agg2DRenderer_render(@m_renBaseComp ,@m_renSolidComp ,ras ,sl, Font.AggUseOnlyFont);
1103 end;
1104
1105 procedure TAggFPCanvas.SetAggTransformations(const AValue: TAggTransformations);
1106 begin
1107 m_transform.load_from(@AValue.affineMatrix[0 ] );
1108
1109 Path.m_convCurve.approximation_scale_ (AggWorldToScreen(1.0 ) * g_approxScale );
1110 m_convStroke.approximation_scale_(AggWorldToScreen(1.0 ) * g_approxScale );
1111 end;
1112
1113 procedure TAggFPCanvas.SetAntiAliasGamma(const AValue: double);
1114 begin
1115 if m_antiAliasGamma=AValue then exit;
1116 m_antiAliasGamma:=AValue;
1117 UpdateRasterizerGamma;
1118 end;
1119
1120 procedure TAggFPCanvas.SetBlendMode(const AValue: TAggBlendMode);
1121 begin
1122 if m_blendMode=AValue then exit;
1123 m_blendMode:=AValue;
1124 m_pixFormatComp.comp_op_ (unsigned(m_blendMode ) );
1125 m_pixFormatCompPre.comp_op_(unsigned(m_blendMode ) );
1126 end;
1127
1128 procedure TAggFPCanvas.SetImageFilter(const AValue: TAggImageFilter);
1129 begin
1130 if AValue=m_imageFilter then exit;
1131 m_imageFilter:=AValue;
1132 case m_imageFilter of
1133 AGG_Bilinear :
1134 m_imageFilterLut.calculate(@m_ifBilinear ,true );
1135
1136 AGG_Hanning :
1137 m_imageFilterLut.calculate(@m_ifHanning ,true );
1138
1139 AGG_Hermite :
1140 m_imageFilterLut.calculate(@m_ifHermite ,true );
1141
1142 AGG_Quadric :
1143 m_imageFilterLut.calculate(@m_ifQuadric ,true );
1144
1145 AGG_Bicubic :
1146 m_imageFilterLut.calculate(@m_ifBicubic ,true );
1147
1148 AGG_Catrom :
1149 m_imageFilterLut.calculate(@m_ifCatrom ,true );
1150
1151 AGG_Spline16 :
1152 m_imageFilterLut.calculate(@m_ifSpline16 ,true );
1153
1154 AGG_Spline36 :
1155 m_imageFilterLut.calculate(@m_ifSpline36 ,true );
1156
1157 AGG_Blackman144 :
1158 m_imageFilterLut.calculate(@m_ifBlackman144 ,true );
1159
1160 end;
1161 end;
1162
1163 procedure TAggFPCanvas.SetImageResample(const AValue: TAggImageResample);
1164 begin
1165 if AValue=m_imageResample then exit;
1166 m_imageResample:=AValue;
1167 end;
1168
1169 procedure TAggFPCanvas.SetMasterAlpha(const AValue: double);
1170 begin
1171 if AValue=m_masterAlpha then exit;
1172 m_masterAlpha:=AValue;
1173 UpdateRasterizerGamma;
1174 end;
1175
1176 procedure TAggFPCanvas.ClearSettings;
1177 begin
1178 m_renBase.reset_clipping (true );
1179 m_renBaseComp.reset_clipping (true );
1180 m_renBasePre.reset_clipping (true );
1181 m_renBaseCompPre.reset_clipping(true );
1182
1183 AggResetTransformations;
1184
1185 Pen.AggLineWidth:=1.0;
1186 Pen.FPColor:=colBlack;
1187 Pen.AggLineCap:=AGG_CapRound;
1188 Pen.AggLineJoin:=AGG_JoinRound;
1189
1190 Brush.FPColor:=colWhite;
1191 m_fillGradientFlag:=AGG_Solid;
1192
1193 AggSetClipBox (0 ,0 ,Width ,Height );
1194
1195 AggImageFilter:=AGG_Bilinear;
1196 AggImageResample:=AGG_NoResample;
1197
1198 m_masterAlpha :=1.0;
1199 m_antiAliasGamma:=1.0;
1200
1201 m_rasterizer.gamma(@m_gammaNone );
1202
1203 m_blendMode:=AGG_BlendAlpha;
1204
1205 Brush.AggFillEvenOdd:=false;
1206
1207 m_blendMode:=AGG_BlendClear;
1208 AggBlendMode:=AGG_BlendAlpha;
1209
1210 //TextAlignment(AGG_AlignLeft ,AGG_AlignBottom );
1211 //FlipText(false );
1212
1213 AggResetPath;
1214 end;
1215
1216 procedure TAggFPCanvas.AggClearAll(const c: TAggColor);
1217 var
1218 clr : aggclr;
1219 begin
1220 clr.Construct (c );
1221 m_renBase.clear(@clr );
1222 end;
1223
1224 procedure TAggFPCanvas.AggClearAll(const r, g, b: byte; a: byte);
1225 var
1226 clr : TAggColor;
1227 begin
1228 clr.Construct(r ,g ,b ,a );
1229 AggClearAll (clr );
1230 end;
1231
1232 procedure TAggFPCanvas.Erase;
1233 begin
1234 AggClearAll(FPToAggColor(colTransparent));
1235 end;
1236
1237 procedure TAggFPCanvas.UpdateRasterizerGamma;
1238 begin
1239 m_gammaAgg2D.Construct(m_masterAlpha ,m_antiAliasGamma );
1240 m_rasterizer.gamma (@m_gammaAgg2D );
1241 end;
1242
1243 procedure TAggFPCanvas.DoCopyRect(DstX, DstY: integer;
1244 SrcCanvas: TFPCustomCanvas; const SourceRect: TRect);
1245 var
1246 y: LongInt;
1247 x: LongInt;
1248 dx: Integer;
1249 dy: Integer;
1250 r: TRect;
1251 begin
1252 if SrcCanvas is TAggFPCanvas then begin
1253 AggCopyImage(TAggFPCanvas(SrcCanvas).Image,
1254 SourceRect.Left,SourceRect.Top,SourceRect.Right,SourceRect.Bottom,
1255 DstX+0.5,DstY+0.5);
1256 end else begin
1257 dx:=DstX-SourceRect.Left;
1258 dy:=DstY-SourceRect.Top;
1259 r:=SourceRect;
1260 r.Left:=Max(r.Left,0);
1261 r.Left:=Max(r.Left+dx,0)-dx;
1262 r.Top:=Max(r.Top,0);
1263 r.Top:=Max(r.Top+dy,0)-dy;
1264 r.Right:=Min(r.Right,SrcCanvas.Width);
1265 r.Right:=Min(r.Right+dx,Width)-dx;
1266 r.Bottom:=Min(r.Bottom,SrcCanvas.Height);
1267 r.Bottom:=Min(r.Bottom+dy,Height)-dy;
1268 for y:=r.Top to r.Bottom-1 do begin
1269 for x:=r.Left to r.Right-1 do begin
1270 Image.Colors[x+dx,y+dy]:=SrcCanvas.Colors[x,y];
1271 end;
1272 end;
1273 end;
1274 end;
1275
DoCreateDefaultBrushnull1276 function TAggFPCanvas.DoCreateDefaultBrush: TFPCustomBrush;
1277 begin
1278 Result:=TAggFPBrush.Create;
1279 end;
1280
DoCreateDefaultFontnull1281 function TAggFPCanvas.DoCreateDefaultFont: TFPCustomFont;
1282 begin
1283 Result:=TAggFPFont.Create;
1284 end;
1285
DoCreateDefaultPennull1286 function TAggFPCanvas.DoCreateDefaultPen: TFPCustomPen;
1287 begin
1288 Result:=TAggFPPen.Create;
1289 end;
1290
DoCreateDefaultPathnull1291 function TAggFPCanvas.DoCreateDefaultPath: TAggFPPath;
1292 begin
1293 Result:=TAggFPPath.Create;
1294 end;
1295
DoCreateDefaultImagenull1296 function TAggFPCanvas.DoCreateDefaultImage: TAggFPImage;
1297 begin
1298 Result:=TAggFPImage.Create(0,0);
1299 end;
1300
1301 procedure TAggFPCanvas.DoDraw(x, y: integer; const SrcImage: TFPCustomImage);
1302 var
1303 r: TRect;
1304 SrcY: LongInt;
1305 SrcX: LongInt;
1306 begin
1307 if SrcImage is TAggFPImage then begin
1308 AggCopyImage(TAggFPImage(SrcImage),x+0.5,y+0.5);
1309 end else begin
1310 r:=Classes.Rect(0,0,SrcImage.Width,SrcImage.Height);
1311 r.Left:=Max(r.Left+x,0)-x;
1312 r.Top:=Max(r.Top+y,0)-y;
1313 r.Right:=Min(r.Right+x,Width)-x;
1314 r.Bottom:=Min(r.Bottom+y,Height)-y;
1315 for SrcY:=r.Top to r.Bottom-1 do begin
1316 for SrcX:=r.Left to r.Right-1 do begin
1317 Image.Colors[SrcX+x,SrcY+y]:=SrcImage.Colors[SrcX,SrcY];
1318 end;
1319 end;
1320 end;
1321 end;
1322
1323 procedure TAggFPCanvas.DoEllipse(const Bounds: TRect);
1324 var
1325 el : bezier_arc;
1326 cx: Integer;
1327 cy: Integer;
1328 rx: Integer;
1329 ry: Integer;
1330 begin
1331 Path.m_path.remove_all;
1332
1333 cx:=(Bounds.Left+Bounds.Right) div 2;
1334 cy:=(Bounds.Top+Bounds.Bottom) div 2;
1335 rx:=Abs(Bounds.Right-Bounds.Left) div 2;
1336 ry:=Abs(Bounds.Bottom-Bounds.Top) div 2;
1337 el.Construct(cx+0.5 ,cy+0.5 ,rx ,ry ,0 ,2 * pi );
1338
1339 Path.m_path.add_path(@el ,0 ,false );
1340 Path.m_path.close_polygon;
1341
1342 AggDrawPath(AGG_StrokeOnly);
1343 end;
1344
1345 procedure TAggFPCanvas.DoEllipseFill(const Bounds: TRect);
1346 var
1347 el : bezier_arc;
1348 cx: Integer;
1349 cy: Integer;
1350 rx: Integer;
1351 ry: Integer;
1352 begin
1353 Path.m_path.remove_all;
1354
1355 cx:=(Bounds.Left+Bounds.Right) div 2;
1356 cy:=(Bounds.Top+Bounds.Bottom) div 2;
1357 rx:=Abs(Bounds.Right-Bounds.Left) div 2;
1358 ry:=Abs(Bounds.Bottom-Bounds.Top) div 2;
1359 el.Construct(cx+0.5 ,cy+0.5 ,rx ,ry ,0 ,2 * pi );
1360
1361 Path.m_path.add_path(@el ,0 ,false );
1362 Path.m_path.close_polygon;
1363
1364 AggDrawPath(AGG_FillOnly);
1365 end;
1366
1367 procedure TAggFPCanvas.DoFloodFill(x, y: integer);
1368 begin
1369 raise Exception.Create('TAggFPCanvas.DoFloodFill not supported by AggPas');
1370 end;
1371
DoGetTextHeightnull1372 function TAggFPCanvas.DoGetTextHeight(str: string): integer;
1373 begin
1374 Result:=ceil(AggTextHeight(str));
1375 end;
1376
1377 procedure TAggFPCanvas.DoGetTextSize(str: string; var w, h: integer);
1378 begin
1379 w:=DoGetTextWidth(str);
1380 h:=DoGetTextHeight(str);
1381 end;
1382
DoGetTextWidthnull1383 function TAggFPCanvas.DoGetTextWidth(str: string): integer;
1384 begin
1385 Result:=ceil(AggTextWidth(str));
1386 end;
1387
1388 procedure TAggFPCanvas.DoLine(x1, y1, x2, y2: integer);
1389 begin
1390 Path.m_path.remove_all;
1391 Path.m_path.move_to(x1+0.5 ,y1+0.5 );
1392 Path.m_path.line_to(x2+0.5 ,y2+0.5 );
1393 AggDrawPath(AGG_StrokeOnly );
1394 end;
1395
1396 procedure TAggFPCanvas.DoPolygon(const points: array of TPoint);
1397 var
1398 p: TPoint;
1399 i: Integer;
1400 begin
1401 if length(Points)<=1 then exit;
1402 Path.m_path.remove_all;
1403 i:=low(points);
1404 p:=points[i];
1405 Path.m_path.move_to(p.x+0.5 ,p.y+0.5 );
1406 inc(i);
1407 while i<=high(points) do begin
1408 p:=points[i];
1409 Path.m_path.line_to(p.x+0.5,p.y+0.5);
1410 inc(i);
1411 end;
1412 AggClosePolygon;
1413 AggDrawPath(AGG_StrokeOnly );
1414 end;
1415
1416 procedure TAggFPCanvas.DoPolygonFill(const points: array of TPoint);
1417 var
1418 p: TPoint;
1419 i: Integer;
1420 begin
1421 if length(Points)<=1 then exit;
1422 Path.m_path.remove_all;
1423 i:=low(points);
1424 p:=points[i];
1425 Path.m_path.move_to(p.x+0.5 ,p.y+0.5 );
1426 inc(i);
1427 while i<=high(points) do begin
1428 p:=points[i];
1429 Path.m_path.line_to(p.x+0.5,p.y+0.5);
1430 inc(i);
1431 end;
1432 AggClosePolygon;
1433 AggDrawPath(AGG_FillOnly );
1434 end;
1435
1436 procedure TAggFPCanvas.DoPolyline(const points: array of TPoint);
1437 var
1438 p: TPoint;
1439 i: Integer;
1440 begin
1441 if length(Points)<=1 then exit;
1442 Path.m_path.remove_all;
1443 i:=low(points);
1444 p:=points[i];
1445 Path.m_path.move_to(p.x+0.5 ,p.y+0.5 );
1446 inc(i);
1447 while i<=high(points) do begin
1448 p:=points[i];
1449 Path.m_path.line_to(p.x+0.5,p.y+0.5);
1450 inc(i);
1451 end;
1452 AggDrawPath(AGG_StrokeOnly );
1453 end;
1454
1455 procedure TAggFPCanvas.DoRectangle(const Bounds: TRect);
1456 begin
1457 Path.m_path.remove_all;
1458 Path.m_path.move_to(Bounds.Left+0.5,Bounds.Top+0.5);
1459 Path.m_path.line_to(Bounds.Right+0.5,Bounds.Top+0.5);
1460 Path.m_path.line_to(Bounds.Right+0.5,Bounds.Bottom+0.5);
1461 Path.m_path.line_to(Bounds.Left+0.5,Bounds.Bottom+0.5);
1462 AggClosePolygon;
1463 AggDrawPath(AGG_StrokeOnly);
1464 end;
1465
1466 procedure TAggFPCanvas.DoRectangleFill(const Bounds: TRect);
1467 begin
1468 Path.m_path.remove_all;
1469 Path.m_path.move_to(Bounds.Left+0.5,Bounds.Top+0.5);
1470 Path.m_path.line_to(Bounds.Right+0.5,Bounds.Top+0.5);
1471 Path.m_path.line_to(Bounds.Right+0.5,Bounds.Bottom+0.5);
1472 Path.m_path.line_to(Bounds.Left+0.5,Bounds.Bottom+0.5);
1473 AggClosePolygon;
1474 AggDrawPath(AGG_FillAndStroke);
1475 end;
1476
1477 procedure TAggFPCanvas.DoTextOut(x, y: integer; str: string);
1478 begin
1479 AggTextOut(x+0.5,y+0.5,str);
1480 end;
1481
GetColornull1482 function TAggFPCanvas.GetColor(x, y: integer): TFPColor;
1483 begin
1484 Result:=FImage.Colors[x,y];
1485 end;
1486
GetHeightnull1487 function TAggFPCanvas.GetHeight: integer;
1488 begin
1489 Result:=FImage.Height;
1490 end;
1491
GetWidthnull1492 function TAggFPCanvas.GetWidth: integer;
1493 begin
1494 Result:=FImage.Width;
1495 end;
1496
1497 procedure TAggFPCanvas.SetColor(x, y: integer; const Value: TFPColor);
1498 begin
1499 FImage.Colors[x,y]:=Value;
1500 end;
1501
1502 procedure TAggFPCanvas.SetHeight(AValue: integer);
1503 begin
1504 FImage.Height:=AValue;
1505 end;
1506
1507 procedure TAggFPCanvas.SetWidth(AValue: integer);
1508 begin
1509 FImage.Width:=AValue;
1510 end;
1511
1512 procedure TAggFPCanvas.OnImageOperation(Img: TAggFPImage;
1513 Operation: TAggFPImgOperation);
1514 begin
1515 if Img<>Image then exit;
1516 case Operation of
1517 afpioResized,afpioPixelFormatChanged:
1518 begin
1519 // Todo: shrink buffer (m_rbuf.attach only grows)
1520 if (Image.Width>0) and (Image.Height>0) then begin
1521 //writeln('TAggFPCanvas.OnImageOperation ',Image.Width,',',Image.Height,' ',Image.LineSize);
1522 m_rbuf.attach(
1523 Image.Data ,
1524 Image.Width ,
1525 Image.Height ,
1526 Image.LineSize);
1527 case Image.PixelFormat of
1528 afpimRGB24:
1529 begin
1530 pixfmt_rgb24(m_pixFormat ,@m_rbuf );
1531 pixfmt_rgb24(m_pixFormatPre ,@m_rbuf );
1532 end;
1533
1534 afpimRGBA32:
1535 begin
1536 pixfmt_rgba32 (m_pixFormat ,@m_rbuf );
1537 pixfmt_custom_blend_rgba(m_pixFormatComp ,@m_rbuf ,
1538 @comp_op_adaptor_rgba ,rgba_order );
1539 pixfmt_rgba32 (m_pixFormatPre ,@m_rbuf );
1540 pixfmt_custom_blend_rgba(m_pixFormatCompPre ,@m_rbuf ,
1541 @comp_op_adaptor_rgba ,rgba_order );
1542 end;
1543 end;
1544
1545 { Reset state }
1546 m_renBase.reset_clipping (true );
1547 m_renBaseComp.reset_clipping (true );
1548 m_renBasePre.reset_clipping (true );
1549 m_renBaseCompPre.reset_clipping(true );
1550
1551 AggSetClipBox (0 ,0 ,Width ,Height );
1552 end;
1553 end;
1554 afpioDestroying:
1555 begin
1556 FImage:=nil;
1557 end;
1558 end;
1559 end;
1560
1561 constructor TAggFPCanvas.Create;
1562 begin
1563 inherited Create;
1564
1565 FUseUTF8:=true;
1566
1567 FAggFont := TAggFPFont(inherited Font);
1568 FAggPen := TAggFPPen(inherited Pen);
1569 FAggBrush := TAggFPBrush(inherited Brush);
1570 FAggPath := DoCreateDefaultPath;
1571 FAggPath.AllocateResources(Self);
1572
1573 FImage:=DoCreateDefaultImage;
1574 FImage.AddListener(@OnImageOperation);
1575
1576 m_rbuf.Construct;
1577
1578 pixfmt_rgba32 (m_pixFormat ,@m_rbuf );
1579 pixfmt_custom_blend_rgba(m_pixFormatComp ,@m_rbuf ,@comp_op_adaptor_rgba ,rgba_order );
1580 pixfmt_rgba32 (m_pixFormatPre ,@m_rbuf );
1581 pixfmt_custom_blend_rgba(m_pixFormatCompPre ,@m_rbuf ,@comp_op_adaptor_rgba ,rgba_order );
1582
1583 m_renBase.Construct (@m_pixFormat );
1584 m_renBaseComp.Construct (@m_pixFormatComp );
1585 m_renBasePre.Construct (@m_pixFormatPre );
1586 m_renBaseCompPre.Construct(@m_pixFormatCompPre );
1587
1588 m_renSolid.Construct (@m_renBase );
1589 m_renSolidComp.Construct(@m_renBaseComp );
1590
1591 m_allocator.Construct;
1592 m_clipBox.Construct(0 ,0 ,0 ,0 );
1593
1594 m_blendMode :=AGG_BlendAlpha;
1595 m_imageBlendMode:=AGG_BlendDst;
1596
1597 m_imageBlendColor.Construct(0 ,0 ,0 );
1598
1599 m_scanline.Construct;
1600 m_rasterizer.Construct;
1601
1602 m_masterAlpha :=1.0;
1603 m_antiAliasGamma:=1.0;
1604
1605 m_fillGradient.Construct(256 ,sizeof(aggclr ) );
1606 m_lineGradient.Construct(256 ,sizeof(aggclr ) );
1607
1608 m_fillGradientFlag:=AGG_Solid;
1609 m_lineGradientFlag:=AGG_Solid;
1610
1611 m_fillGradientMatrix.Construct;
1612 m_lineGradientMatrix.Construct;
1613
1614 m_fillGradientD1:=0.0;
1615 m_lineGradientD1:=0.0;
1616 m_fillGradientD2:=100.0;
1617 m_lineGradientD2:=100.0;
1618
1619 m_imageFilter :=AGG_Bilinear;
1620 m_imageResample:=AGG_NoResample;
1621
1622 m_gammaNone.Construct;
1623
1624 m_ifBilinear.Construct;
1625 m_ifHanning.Construct;
1626 m_ifHermite.Construct;
1627 m_ifQuadric.Construct;
1628 m_ifBicubic.Construct;
1629 m_ifCatrom.Construct;
1630 m_ifSpline16.Construct;
1631 m_ifSpline36.Construct;
1632 m_ifBlackman144.Construct;
1633
1634 m_imageFilterLut.Construct(@m_ifBilinear ,true );
1635
1636 m_linearGradientFunction.Construct;
1637 m_radialGradientFunction.Construct;
1638
1639 m_fillGradientInterpolator.Construct(@m_fillGradientMatrix );
1640 m_lineGradientInterpolator.Construct(@m_lineGradientMatrix );
1641
1642 Pen.FAggLineWidth:=1;
1643 m_evenOddFlag:=false;
1644
1645 m_transform.Construct;
1646
1647 m_convStroke.Construct(@Path.m_convCurve );
1648
1649 m_pathTransform.Construct (@Path.m_convCurve ,@m_transform );
1650 m_strokeTransform.Construct(@m_convStroke ,@m_transform );
1651
1652 {$IFDEF AGG2D_USE_FREETYPE }
1653 m_fontEngine.Construct;
1654 {$ENDIF }
1655 {$IFDEF AGG2D_USE_WINFONTS}
1656 m_fontDC:=GetDC(0);
1657 m_fontEngine.Construct(m_fontDC);
1658 {$ENDIF }
1659 {$IFNDEF AGG2D_NO_FONT}
1660 m_fontCacheManager.Construct(@m_fontEngine);
1661 {$ENDIF}
1662
1663 m_convStroke.line_cap_(Pen.AggLineCap);
1664 m_convStroke.line_join_(Pen.AggLineJoin);
1665
1666 ClearSettings;
1667 end;
1668
1669 destructor TAggFPCanvas.Destroy;
1670 begin
1671 m_rbuf.Destruct;
1672
1673 m_allocator.Destruct;
1674
1675 m_scanline.Destruct;
1676 m_rasterizer.Destruct;
1677
1678 m_fillGradient.Destruct;
1679 m_lineGradient.Destruct;
1680
1681 m_imageFilterLut.Destruct;
1682
1683 m_convStroke.Destruct;
1684
1685 {$IFNDEF AGG2D_NO_FONT}
1686 m_fontEngine.Destruct;
1687 m_fontCacheManager.Destruct;
1688 {$ENDIF}
1689
1690 {$IFDEF AGG2D_USE_WINFONTS}
1691 ReleaseDC(0,m_fontDC);
1692 {$ENDIF }
1693
1694 FAggPath.DeallocateResources;
1695 FreeAndNil(FAggPath);
1696
1697 FreeAndNil(FImage);
1698 inherited Destroy;
1699 // set resources to nil, so that dangling pointers are spotted early
1700 FAggFont:=nil;
1701 FAggPen:=nil;
1702 FAggBrush:=nil;
1703 end;
1704
1705 procedure TAggFPCanvas.AggResetPath;
1706 begin
1707 Path.m_path.remove_all;
1708 Path.m_path.move_to(0,0);
1709 end;
1710
1711 procedure TAggFPCanvas.AggMoveTo(const x, y: double);
1712 begin
1713 Path.m_path.move_to(x ,y );
1714 end;
1715
1716 procedure TAggFPCanvas.AggMoveRel(const dx, dy: double);
1717 begin
1718 Path.m_path.move_rel(dx ,dy );
1719 end;
1720
1721 procedure TAggFPCanvas.AggLineTo(const x, y: double);
1722 begin
1723 Path.m_path.line_to(x ,y );
1724 end;
1725
1726 procedure TAggFPCanvas.AggLineRel(const dx, dy: double);
1727 begin
1728 Path.m_path.line_rel(dx ,dy );
1729 end;
1730
1731 procedure TAggFPCanvas.AggHorLineTo(const x: double);
1732 begin
1733 Path.m_path.hline_to(x );
1734 end;
1735
1736 procedure TAggFPCanvas.AggHorLineRel(const dx: double);
1737 begin
1738 Path.m_path.hline_rel(dx );
1739 end;
1740
1741 procedure TAggFPCanvas.AggVerLineTo(const y: double);
1742 begin
1743 Path.m_path.vline_to(y );
1744 end;
1745
1746 procedure TAggFPCanvas.AggVerLineRel(const dy: double);
1747 begin
1748 Path.m_path.vline_rel(dy );
1749 end;
1750
1751 procedure TAggFPCanvas.AggArcTo(const rx, ry, angle: double; largeArcFlag,
1752 sweepFlag: boolean; const x, y: double);
1753 begin
1754 Path.m_path.arc_to(rx ,ry ,angle ,largeArcFlag ,sweepFlag ,x ,y );
1755 end;
1756
1757 procedure TAggFPCanvas.AggArcRel(const rx, ry, angle: double; largeArcFlag,
1758 sweepFlag: boolean; const dx, dy: double);
1759 begin
1760 Path.m_path.arc_rel(rx ,ry ,angle ,largeArcFlag ,sweepFlag ,dx ,dy );
1761 end;
1762
1763 procedure TAggFPCanvas.AggQuadricCurveTo(const xCtrl, yCtrl, xTo, yTo: double);
1764 begin
1765 Path.m_path.curve3(xCtrl ,yCtrl ,xTo ,yTo );
1766 end;
1767
1768 procedure TAggFPCanvas.AggQuadricCurveRel(const dxCtrl, dyCtrl, dxTo,
1769 dyTo: double);
1770 begin
1771 Path.m_path.curve3_rel(dxCtrl ,dyCtrl ,dxTo ,dyTo );
1772 end;
1773
1774 procedure TAggFPCanvas.AggQuadricCurveTo(const xTo, yTo: double);
1775 begin
1776 Path.m_path.curve3(xTo ,yTo );
1777 end;
1778
1779 procedure TAggFPCanvas.AggQuadricCurveRel(const dxTo, dyTo: double);
1780 begin
1781 Path.m_path.curve3_rel(dxTo ,dyTo );
1782 end;
1783
1784 procedure TAggFPCanvas.AggCubicCurveTo(const xCtrl1, yCtrl1, xCtrl2, yCtrl2,
1785 xTo, yTo: double);
1786 begin
1787 Path.m_path.curve4(xCtrl1 ,yCtrl1 ,xCtrl2 ,yCtrl2 ,xTo ,yTo );
1788 end;
1789
1790 procedure TAggFPCanvas.AggCubicCurveRel(const dxCtrl1, dyCtrl1, dxCtrl2,
1791 dyCtrl2, dxTo, dyTo: double);
1792 begin
1793 Path.m_path.curve4_rel(dxCtrl1 ,dyCtrl1 ,dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo );
1794 end;
1795
1796 procedure TAggFPCanvas.AggCubicCurveTo(const xCtrl2, yCtrl2, xTo, yTo: double);
1797 begin
1798 Path.m_path.curve4(xCtrl2 ,yCtrl2 ,xTo ,yTo );
1799 end;
1800
1801 procedure TAggFPCanvas.AggCubicCurveRel(const dxCtrl2, dyCtrl2, dxTo,
1802 dyTo: double);
1803 begin
1804 Path.m_path.curve4_rel(dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo );
1805 end;
1806
1807 procedure TAggFPCanvas.AggAddEllipse(const cx, cy, rx, ry: double;
1808 dir: TAggDirection);
1809 var
1810 ar : bezier_arc;
1811 begin
1812 if dir = AGG_CCW then
1813 ar.Construct(cx ,cy ,rx ,ry ,0 ,2 * pi )
1814 else
1815 ar.Construct(cx ,cy ,rx ,ry ,0 ,-2 * pi );
1816
1817 Path.m_path.add_path(@ar ,0 ,false );
1818 AggClosePolygon;
1819 end;
1820
1821 procedure TAggFPCanvas.AggClosePolygon;
1822 begin
1823 Path.m_path.close_polygon;
1824 end;
1825
1826 procedure TAggFPCanvas.AggDrawPath(flag: TAggDrawPathFlag; UseFont: boolean);
1827 begin
1828 m_rasterizer.reset;
1829 if flag in [AGG_FillOnly,AGG_FillAndStroke] then begin
1830 if (not UseFont and (Brush.FAggColor.a <> 0))
1831 or (UseFont and (Font.FAggColor.a <> 0)) then
1832 begin
1833 m_rasterizer.add_path(@m_pathTransform );
1834 render(true,UseFont);
1835 end;
1836 end;
1837 if flag in [AGG_StrokeOnly,AGG_FillAndStroke] then begin
1838 if (not UseFont and (Pen.FAggColor.a <> 0 ) and (Pen.FAggLineWidth > 0.0 ))
1839 or (UseFont and (Font.FAggColor.a<>0)) then
1840 begin
1841 m_rasterizer.add_path(@m_strokeTransform );
1842 render(false,UseFont);
1843 end;
1844 end;
1845 if flag=AGG_FillWithLineColor then begin
1846 if (not UseFont and (Pen.FAggColor.a <> 0))
1847 or (UseFont and (Font.FAggColor.a<>0)) then
1848 begin
1849 m_rasterizer.add_path(@m_pathTransform);
1850 render(false,UseFont);
1851 end;
1852 end;
1853 end;
1854
1855 procedure TAggFPCanvas.AggLine(const x1, y1, x2, y2: double);
1856 begin
1857 Path.m_path.remove_all;
1858
1859 addLine (x1 ,y1 ,x2 ,y2 );
1860 AggDrawPath(AGG_StrokeOnly );
1861 end;
1862
1863 procedure TAggFPCanvas.AggTriangle(const x1, y1, x2, y2, x3, y3: double);
1864 begin
1865 Path.m_path.remove_all;
1866 Path.m_path.move_to(x1 ,y1 );
1867 Path.m_path.line_to(x2 ,y2 );
1868 Path.m_path.line_to(x3 ,y3 );
1869 Path.m_path.close_polygon;
1870
1871 AggDrawPath(AGG_FillAndStroke );
1872 end;
1873
1874 procedure TAggFPCanvas.AggRectangle(const x1, y1, x2, y2: double);
1875 begin
1876 Path.m_path.remove_all;
1877 Path.m_path.move_to(x1 ,y1 );
1878 Path.m_path.line_to(x2 ,y1 );
1879 Path.m_path.line_to(x2 ,y2 );
1880 Path.m_path.line_to(x1 ,y2 );
1881 Path.m_path.close_polygon;
1882
1883 AggDrawPath(AGG_FillAndStroke );
1884 end;
1885
1886 procedure TAggFPCanvas.AggRoundedRect(const x1, y1, x2, y2, r: double);
1887 var
1888 rc : rounded_rect;
1889 begin
1890 Path.m_path.remove_all;
1891 rc.Construct(x1 ,y1 ,x2 ,y2 ,r );
1892
1893 rc.normalize_radius;
1894 rc.approximation_scale_(AggWorldToScreen(1.0 ) * g_approxScale );
1895
1896 Path.m_path.add_path(@rc ,0 ,false );
1897
1898 AggDrawPath(AGG_FillAndStroke );
1899 end;
1900
1901 procedure TAggFPCanvas.AggRoundedRect(const x1, y1, x2, y2, rx, ry: double);
1902 var
1903 rc : rounded_rect;
1904 begin
1905 Path.m_path.remove_all;
1906 rc.Construct;
1907
1908 rc.rect (x1 ,y1 ,x2 ,y2 );
1909 rc.radius(rx ,ry );
1910 rc.normalize_radius;
1911
1912 Path.m_path.add_path(@rc ,0 ,false );
1913
1914 AggDrawPath(AGG_FillAndStroke );
1915 end;
1916
1917 procedure TAggFPCanvas.AggRoundedRect(const x1, y1, x2, y2, rxBottom, ryBottom,
1918 rxTop, ryTop: double);
1919 var
1920 rc : rounded_rect;
1921 begin
1922 Path.m_path.remove_all;
1923 rc.Construct;
1924
1925 rc.rect (x1 ,y1 ,x2 ,y2 );
1926 rc.radius(rxBottom ,ryBottom ,rxTop ,ryTop );
1927 rc.normalize_radius;
1928
1929 rc.approximation_scale_(AggWorldToScreen(1.0 ) * g_approxScale );
1930
1931 Path.m_path.add_path(@rc ,0 ,false );
1932
1933 AggDrawPath(AGG_FillAndStroke );
1934 end;
1935
1936 procedure TAggFPCanvas.AggEllipse(const cx, cy, rx, ry: double);
1937 var
1938 el : bezier_arc;
1939 begin
1940 Path.m_path.remove_all;
1941
1942 el.Construct(cx ,cy ,rx ,ry ,0 ,2 * pi );
1943
1944 Path.m_path.add_path(@el ,0 ,false );
1945 AggClosePolygon;
1946
1947 AggDrawPath(AGG_FillAndStroke );
1948 end;
1949
1950 procedure TAggFPCanvas.AggArc(const cx, cy, rx, ry, start, endangle: double);
1951 var
1952 ar : agg_arc.arc;
1953 begin
1954 Path.m_path.remove_all;
1955
1956 ar.Construct(cx ,cy ,rx ,ry ,endangle ,start ,false );
1957
1958 Path.m_path.add_path(@ar ,0 ,false );
1959
1960 AggDrawPath(AGG_StrokeOnly );
1961 end;
1962
1963 procedure TAggFPCanvas.AggStar(const cx, cy, r1, r2, startAngle: double;
1964 numRays: integer);
1965 var
1966 da, a, x, y: double;
1967 i : int;
1968 begin
1969 Path.m_path.remove_all;
1970
1971 da:=pi / numRays;
1972 a :=startAngle;
1973
1974 i:=0;
1975
1976 while i < numRays do begin
1977 x:=Cos(a) * r2 + cx;
1978 y:=Sin(a) * r2 + cy;
1979
1980 if i <> 0 then
1981 Path.m_path.line_to(x ,y)
1982 else
1983 Path.m_path.move_to(x ,y);
1984
1985 a:=a + da;
1986
1987 Path.m_path.line_to(Cos(a ) * r1 + cx ,Sin(a ) * r1 + cy);
1988
1989 a:=a + da;
1990
1991 inc(i);
1992 end;
1993
1994 AggClosePolygon;
1995 AggDrawPath(AGG_FillAndStroke );
1996 end;
1997
1998 procedure TAggFPCanvas.AggCurve(const x1, y1, x2, y2, x3, y3: double);
1999 begin
2000 Path.m_path.remove_all;
2001 Path.m_path.move_to(x1 ,y1 );
2002 Path.m_path.curve3 (x2 ,y2 ,x3 ,y3 );
2003
2004 AggDrawPath(AGG_StrokeOnly );
2005 end;
2006
2007 procedure TAggFPCanvas.AggCurve(const x1, y1, x2, y2, x3, y3, x4, y4: double);
2008 begin
2009 Path.m_path.remove_all;
2010 Path.m_path.move_to(x1 ,y1 );
2011 Path.m_path.curve4 (x2 ,y2 ,x3 ,y3 ,x4 ,y4 );
2012
2013 AggDrawPath(AGG_StrokeOnly );
2014 end;
2015
2016 procedure TAggFPCanvas.AggPolygon(const xy: PDouble; numPoints: integer);
2017 begin
2018 Path.m_path.remove_all;
2019 Path.m_path.add_poly(double_2_ptr(xy ) ,numPoints );
2020
2021 AggClosePolygon;
2022 AggDrawPath(AGG_FillAndStroke );
2023 end;
2024
2025 procedure TAggFPCanvas.AggPolyline(const xy: PDouble; numPoints: integer);
2026 begin
2027 Path.m_path.remove_all;
2028 Path.m_path.add_poly(double_2_ptr(xy ) ,numPoints );
2029
2030 AggDrawPath(AGG_StrokeOnly );
2031 end;
2032
2033 procedure TAggFPCanvas.AggFillLinearGradient(const x1, y1, x2, y2: double; c1,
2034 c2: TAggColor; profile: double);
2035 var
2036 i ,startGradient ,endGradient : int;
2037
2038 k ,angle : double;
2039
2040 c : TAggColor;
2041
2042 clr : aggclr;
2043 tar : trans_affine_rotation;
2044 tat : trans_affine_translation;
2045 begin
2046 startGradient:=128 - Trunc(profile * 127.0 );
2047 endGradient :=128 + Trunc(profile * 127.0 );
2048
2049 if endGradient <= startGradient then
2050 endGradient:=startGradient + 1;
2051
2052 k:=1.0 / (endGradient - startGradient );
2053 i:=0;
2054
2055 while i < startGradient do
2056 begin
2057 clr.Construct(c1 );
2058
2059 move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
2060 inc (i );
2061 end;
2062
2063 while i < endGradient do
2064 begin
2065 c:=c1.gradient(c2 ,(i - startGradient ) * k );
2066
2067 clr.Construct(c );
2068
2069 move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
2070 inc (i );
2071 end;
2072
2073 while i < 256 do
2074 begin
2075 clr.Construct(c2 );
2076
2077 move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
2078 inc (i );
2079 end;
2080
2081 angle:=ArcTan2(y2 - y1 ,x2 - x1 );
2082
2083 m_fillGradientMatrix.reset;
2084
2085 tar.Construct(angle );
2086
2087 m_fillGradientMatrix.multiply(@tar );
2088
2089 tat.Construct(x1 ,y1 );
2090
2091 m_fillGradientMatrix.multiply(@tat );
2092 m_fillGradientMatrix.multiply(@m_transform );
2093 m_fillGradientMatrix.invert;
2094
2095 m_fillGradientD1 :=0.0;
2096 m_fillGradientD2 :=Sqrt((x2 - x1 ) * (x2 - x1 ) + (y2 - y1 ) * (y2 - y1 ) );
2097 m_fillGradientFlag:=AGG_Linear;
2098 end;
2099
2100 procedure TAggFPCanvas.AggLineLinearGradient(const x1, y1, x2, y2: double; c1,
2101 c2: TAggColor; profile: double);
2102 var
2103 i ,startGradient ,endGradient : int;
2104
2105 k ,angle : double;
2106
2107 c : TAggColor;
2108
2109 clr : aggclr;
2110 tar : trans_affine_rotation;
2111 tat : trans_affine_translation;
2112
2113 begin
2114 startGradient:=128 - Trunc(profile * 128.0 );
2115 endGradient :=128 + Trunc(profile * 128.0 );
2116
2117 if endGradient <= startGradient then
2118 endGradient:=startGradient + 1;
2119
2120 k:=1.0 / (endGradient - startGradient );
2121 i:=0;
2122
2123 while i < startGradient do
2124 begin
2125 clr.Construct(c1 );
2126
2127 move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
2128 inc (i );
2129 end;
2130
2131 while i < endGradient do
2132 begin
2133 c:=c1.gradient(c2 ,(i - startGradient) * k );
2134
2135 clr.Construct(c );
2136
2137 move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
2138 inc (i );
2139 end;
2140
2141 while i < 256 do
2142 begin
2143 clr.Construct(c2 );
2144
2145 move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
2146 inc (i );
2147 end;
2148
2149 angle:=ArcTan2(y2 - y1 ,x2 - x1 );
2150
2151 m_lineGradientMatrix.reset;
2152
2153 tar.Construct(angle );
2154
2155 m_lineGradientMatrix.multiply(@tar );
2156
2157 tat.Construct(x1 ,y1 );
2158
2159 m_lineGradientMatrix.multiply(@tat );
2160 m_lineGradientMatrix.multiply(@m_transform );
2161 m_lineGradientMatrix.invert;
2162
2163 m_lineGradientD1 :=0.0;
2164 m_lineGradientD2 :=Sqrt((x2 - x1 ) * (x2 - x1 ) + (y2 - y1 ) * (y2 - y1 ) );
2165 m_lineGradientFlag:=AGG_Linear;
2166
2167 Pen.FPColor:=colBlack; // Set some real color
2168 end;
2169
2170 procedure TAggFPCanvas.AggFillRadialGradient(const x, y, r: double; c1,
2171 c2: TAggColor; profile: double);
2172 var
2173 i ,startGradient ,endGradient : int;
2174
2175 k : double;
2176 c : TAggColor;
2177
2178 clr : aggclr;
2179 tat : trans_affine_translation;
2180
2181 begin
2182 startGradient:=128 - Trunc(profile * 127.0 );
2183 endGradient :=128 + Trunc(profile * 127.0 );
2184
2185 if endGradient <= startGradient then
2186 endGradient:=startGradient + 1;
2187
2188 k:=1.0 / (endGradient - startGradient );
2189 i:=0;
2190
2191 while i < startGradient do
2192 begin
2193 clr.Construct(c1 );
2194
2195 move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
2196 inc (i );
2197 end;
2198
2199 while i < endGradient do
2200 begin
2201 c:=c1.gradient(c2 ,(i - startGradient ) * k );
2202
2203 clr.Construct(c );
2204
2205 move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
2206 inc (i );
2207 end;
2208
2209 while i < 256 do
2210 begin
2211 clr.Construct(c2 );
2212
2213 move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
2214 inc (i );
2215 end;
2216
2217 m_fillGradientD2:=AggWorldToScreen(r );
2218
2219 AggWorldToScreen(@x ,@y );
2220
2221 m_fillGradientMatrix.reset;
2222
2223 tat.Construct(x ,y );
2224
2225 m_fillGradientMatrix.multiply(@tat );
2226 m_fillGradientMatrix.invert;
2227
2228 m_fillGradientD1 :=0;
2229 m_fillGradientFlag:=AGG_Radial;
2230 end;
2231
2232 procedure TAggFPCanvas.AggLineRadialGradient(const x, y, r: double; c1,
2233 c2: TAggColor; profile: double);
2234 var
2235 i ,startGradient ,endGradient : int;
2236
2237 k : double;
2238 c : TAggColor;
2239
2240 clr : aggclr;
2241 tat : trans_affine_translation;
2242
2243 begin
2244 startGradient:=128 - Trunc(profile * 128.0 );
2245 endGradient :=128 + Trunc(profile * 128.0 );
2246
2247 if endGradient <= startGradient then
2248 endGradient:=startGradient + 1;
2249
2250 k:=1.0 / (endGradient - startGradient );
2251 i:=0;
2252
2253 while i < startGradient do
2254 begin
2255 clr.Construct(c1 );
2256
2257 move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
2258 inc (i );
2259 end;
2260
2261 while i < endGradient do
2262 begin
2263 c:=c1.gradient(c2 ,(i - startGradient ) * k );
2264
2265 clr.Construct(c );
2266
2267 move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
2268 inc (i );
2269 end;
2270
2271 while i < 256 do
2272 begin
2273 clr.Construct(c2 );
2274
2275 move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
2276 inc (i );
2277 end;
2278
2279 m_lineGradientD2:=AggWorldToScreen(r );
2280
2281 AggWorldToScreen(@x ,@y );
2282
2283 m_lineGradientMatrix.reset;
2284
2285 tat.Construct(x ,y );
2286
2287 m_lineGradientMatrix.multiply(@tat );
2288 m_lineGradientMatrix.invert;
2289
2290 m_lineGradientD1 :=0;
2291 m_lineGradientFlag:=AGG_Radial;
2292
2293 Pen.FPColor:=colBlack; // Set some real color
2294 end;
2295
2296 procedure TAggFPCanvas.AggFillRadialGradient(const x, y, r: double; c1, c2,
2297 c3: TAggColor);
2298 var
2299 i : int;
2300 c : TAggColor;
2301
2302 clr : aggclr;
2303 tat : trans_affine_translation;
2304
2305 begin
2306 i:=0;
2307
2308 while i < 128 do
2309 begin
2310 c:=c1.gradient(c2 ,i / 127.0 );
2311
2312 clr.Construct(c );
2313
2314 move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
2315 inc (i );
2316 end;
2317
2318 while i < 256 do
2319 begin
2320 c:=c2.gradient(c3 ,(i - 128 ) / 127.0 );
2321
2322 clr.Construct(c );
2323
2324 move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
2325 inc (i );
2326 end;
2327
2328 m_fillGradientD2:=AggWorldToScreen(r );
2329
2330 AggWorldToScreen(@x ,@y );
2331
2332 m_fillGradientMatrix.reset;
2333
2334 tat.Construct(x ,y );
2335
2336 m_fillGradientMatrix.multiply(@tat );
2337 m_fillGradientMatrix.invert;
2338
2339 m_fillGradientD1 :=0;
2340 m_fillGradientFlag:=AGG_Radial;
2341 end;
2342
2343 procedure TAggFPCanvas.AggLineRadialGradient(const x, y, r: double; c1, c2,
2344 c3: TAggColor);
2345 var
2346 i : int;
2347 c : TAggColor;
2348
2349 clr : aggclr;
2350 tat : trans_affine_translation;
2351
2352 begin
2353 i:=0;
2354
2355 while i < 128 do
2356 begin
2357 c:=c1.gradient(c2 ,i / 127.0 );
2358
2359 clr.Construct(c );
2360
2361 move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
2362 inc (i );
2363 end;
2364
2365 while i < 256 do
2366 begin
2367 c:=c2.gradient(c3 ,(i - 128 ) / 127.0 );
2368
2369 clr.Construct(c );
2370
2371 move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
2372 inc (i );
2373 end;
2374
2375 m_lineGradientD2:=AggWorldToScreen(r );
2376
2377 AggWorldToScreen(@x ,@y );
2378
2379 m_lineGradientMatrix.reset;
2380
2381 tat.Construct(x ,y );
2382
2383 m_lineGradientMatrix.multiply(@tat );
2384 m_lineGradientMatrix.invert;
2385
2386 m_lineGradientD1 :=0;
2387 m_lineGradientFlag:=AGG_Radial;
2388
2389 Pen.FPColor:=colBlack; // Set some real color
2390 end;
2391
2392 procedure TAggFPCanvas.AggFillRadialGradient(const x, y, r: double);
2393 var
2394 tat : trans_affine_translation;
2395
2396 begin
2397 m_fillGradientD2:=AggWorldToScreen(r );
2398
2399 AggWorldToScreen(@x ,@y );
2400
2401 m_fillGradientMatrix.reset;
2402
2403 tat.Construct(x ,y );
2404
2405 m_fillGradientMatrix.multiply(@tat );
2406 m_fillGradientMatrix.invert;
2407
2408 m_fillGradientD1:=0;
2409 end;
2410
2411 procedure TAggFPCanvas.AggLineRadialGradient(const x, y, r: double);
2412 var
2413 tat : trans_affine_translation;
2414
2415 begin
2416 m_lineGradientD2:=AggWorldToScreen(r );
2417
2418 AggWorldToScreen(@x ,@y );
2419
2420 m_lineGradientMatrix.reset;
2421
2422 tat.Construct(x ,y );
2423
2424 m_lineGradientMatrix.multiply(@tat );
2425 m_lineGradientMatrix.invert;
2426
2427 m_lineGradientD1:=0;
2428 end;
2429
2430 procedure TAggFPCanvas.AggSetClipBox(const x1, y1, x2, y2: double);
2431 var
2432 rx1 ,ry1 ,rx2 ,ry2 : int;
2433 begin
2434 m_clipBox.Construct(x1 ,y1 ,x2 ,y2 );
2435
2436 rx1:=Trunc(x1 );
2437 ry1:=Trunc(y1 );
2438 rx2:=Trunc(x2 );
2439 ry2:=Trunc(y2 );
2440
2441 m_renBase.clip_box_ (rx1 ,ry1 ,rx2 ,ry2 );
2442 m_renBaseComp.clip_box_ (rx1 ,ry1 ,rx2 ,ry2 );
2443 m_renBasePre.clip_box_ (rx1 ,ry1 ,rx2 ,ry2 );
2444 m_renBaseCompPre.clip_box_(rx1 ,ry1 ,rx2 ,ry2 );
2445
2446 m_rasterizer.clip_box(x1 ,y1 ,x2 ,y2 );
2447 end;
2448
AggGetClipBoxnull2449 function TAggFPCanvas.AggGetClipBox: TAggRectD;
2450 begin
2451 result:=m_clipBox;
2452 end;
2453
2454 procedure TAggFPCanvas.AggClearClipBox(const c: TAggColor);
2455 var
2456 clr : aggclr;
2457 begin
2458 clr.Construct(c );
2459 m_renBase.copy_bar(0 ,0 ,m_renBase.width ,m_renBase.height ,@clr );
2460 end;
2461
2462 procedure TAggFPCanvas.AggClearClipBox(r, g, b: byte; a: byte);
2463 var
2464 clr : TAggColor;
2465 begin
2466 clr.Construct(r ,g ,b ,a );
2467 AggClearClipBox (clr );
2468 end;
2469
AggInClipBoxnull2470 function TAggFPCanvas.AggInClipBox(const worldX, worldY: double): boolean;
2471 begin
2472 AggWorldToScreen(@worldX ,@worldY );
2473 result:=m_renBase.inbox(Trunc(worldX ) ,Trunc(worldY ) );
2474 end;
2475
2476 procedure TAggFPCanvas.AggResetTransformations;
2477 begin
2478 m_transform.reset;
2479 end;
2480
2481 procedure TAggFPCanvas.AggAffine(const tr: PAggAffine);
2482 begin
2483 m_transform.multiply(tr);
2484
2485 Path.m_convCurve.approximation_scale_ (AggWorldToScreen(1.0 ) * g_approxScale );
2486 m_convStroke.approximation_scale_(AggWorldToScreen(1.0 ) * g_approxScale );
2487 end;
2488
2489 procedure TAggFPCanvas.AggAffine(const tr: PAggTransformations);
2490 var
2491 ta : trans_affine;
2492 begin
2493 ta.Construct(
2494 tr^.affineMatrix[0 ] ,tr^.affineMatrix[1 ] ,tr^.affineMatrix[2 ] ,
2495 tr^.affineMatrix[3 ] ,tr^.affineMatrix[4 ] ,tr^.affineMatrix[5 ] );
2496
2497 AggAffine(PAggAffine(@ta ) );
2498 end;
2499
2500 procedure TAggFPCanvas.AggRotate(const angle: double);
2501 var
2502 tar : trans_affine_rotation;
2503 begin
2504 tar.Construct(angle );
2505 m_transform.multiply(@tar );
2506 end;
2507
2508 procedure TAggFPCanvas.AggScale(const sx, sy: double);
2509 var
2510 tas : trans_affine_scaling;
2511 begin
2512 tas.Construct(sx ,sy );
2513
2514 m_transform.multiply(@tas );
2515
2516 Path.m_convCurve.approximation_scale_ (AggWorldToScreen(1.0 ) * g_approxScale );
2517 m_convStroke.approximation_scale_(AggWorldToScreen(1.0 ) * g_approxScale );
2518 end;
2519
2520 procedure TAggFPCanvas.AggSkew(const sx, sy: double);
2521 var
2522 tas : trans_affine_skewing;
2523 begin
2524 tas.Construct(sx ,sy );
2525 m_transform.multiply(@tas );
2526 end;
2527
2528 procedure TAggFPCanvas.AggTranslate(const x, y: double);
2529 var
2530 tat : trans_affine_translation;
2531 begin
2532 tat.Construct(x ,y );
2533 m_transform.multiply(@tat );
2534 end;
2535
2536 procedure TAggFPCanvas.AggParallelogram(const x1, y1, x2, y2: double; para: PDouble);
2537 var
2538 ta : trans_affine;
2539 begin
2540 ta.Construct(x1 ,y1 ,x2 ,y2 ,parallelo_ptr(para ) );
2541
2542 m_transform.multiply(@ta );
2543
2544 Path.m_convCurve.approximation_scale_ (AggWorldToScreen(1.0 ) * g_approxScale );
2545 m_convStroke.approximation_scale_(AggWorldToScreen(1.0 ) * g_approxScale );
2546 end;
2547
2548 procedure TAggFPCanvas.AggViewport(const worldX1, worldY1, worldX2, worldY2,
2549 screenX1, screenY1, screenX2, screenY2: double; const opt: TAggViewportOption
2550 );
2551 var
2552 vp : trans_viewport;
2553 mx : trans_affine;
2554
2555 begin
2556 vp.Construct;
2557
2558 case opt of
2559 AGG_Anisotropic :
2560 vp.preserve_aspect_ratio(0.0 ,0.0 ,aspect_ratio_stretch );
2561
2562 AGG_XMinYMin :
2563 vp.preserve_aspect_ratio(0.0 ,0.0 ,aspect_ratio_meet );
2564
2565 AGG_XMidYMin :
2566 vp.preserve_aspect_ratio(0.5 ,0.0 ,aspect_ratio_meet );
2567
2568 AGG_XMaxYMin :
2569 vp.preserve_aspect_ratio(1.0 ,0.0 ,aspect_ratio_meet );
2570
2571 AGG_XMinYMid :
2572 vp.preserve_aspect_ratio(0.0 ,0.5 ,aspect_ratio_meet );
2573
2574 AGG_XMidYMid :
2575 vp.preserve_aspect_ratio(0.5 ,0.5 ,aspect_ratio_meet );
2576
2577 AGG_XMaxYMid :
2578 vp.preserve_aspect_ratio(1.0 ,0.5 ,aspect_ratio_meet );
2579
2580 AGG_XMinYMax :
2581 vp.preserve_aspect_ratio(0.0 ,1.0 ,aspect_ratio_meet );
2582
2583 AGG_XMidYMax :
2584 vp.preserve_aspect_ratio(0.5 ,1.0 ,aspect_ratio_meet );
2585
2586 AGG_XMaxYMax :
2587 vp.preserve_aspect_ratio(1.0 ,1.0 ,aspect_ratio_meet );
2588
2589 end;
2590
2591 vp.world_viewport (worldX1 ,worldY1 ,worldX2 ,worldY2 );
2592 vp.device_viewport(screenX1 ,screenY1 ,screenX2 ,screenY2 );
2593
2594 mx.Construct;
2595
2596 vp.to_affine (@mx );
2597 m_transform.multiply(@mx );
2598
2599 Path.m_convCurve.approximation_scale_ (AggWorldToScreen(1.0 ) * g_approxScale );
2600 m_convStroke.approximation_scale_(AggWorldToScreen(1.0 ) * g_approxScale );
2601 end;
2602
2603 procedure TAggFPCanvas.AggWorldToScreen(x, y: PDouble);
2604 begin
2605 m_transform.transform(@m_transform ,double_ptr(x ) ,double_ptr(y ) );
2606 end;
2607
2608 procedure TAggFPCanvas.AggScreenToWorld(x, y: PDouble);
2609 begin
2610 m_transform.inverse_transform(@m_transform ,double_ptr(x ) ,double_ptr(y ) );
2611 end;
2612
AggWorldToScreennull2613 function TAggFPCanvas.AggWorldToScreen(const scalar: double): double;
2614 var
2615 x1 ,y1 ,x2 ,y2 : double;
2616 begin
2617 x1:=0;
2618 y1:=0;
2619 x2:=scalar;
2620 y2:=scalar;
2621
2622 AggWorldToScreen(@x1 ,@y1 );
2623 AggWorldToScreen(@x2 ,@y2 );
2624
2625 result:=Sqrt((x2 - x1 ) * (x2 - x1 ) + (y2 - y1 ) * (y2 - y1 ) ) * 0.7071068;
2626 end;
2627
AggScreenToWorldnull2628 function TAggFPCanvas.AggScreenToWorld(const scalar: double): double;
2629 var
2630 x1 ,y1 ,x2 ,y2 : double;
2631 begin
2632 x1:=0;
2633 y1:=0;
2634 x2:=scalar;
2635 y2:=scalar;
2636
2637 AggScreenToWorld(@x1 ,@y1 );
2638 AggScreenToWorld(@x2 ,@y2 );
2639
2640 result:=Sqrt((x2 - x1 ) * (x2 - x1 ) + (y2 - y1 ) * (y2 - y1 ) ) * 0.7071068;
2641 end;
2642
2643 procedure TAggFPCanvas.AggAlignPoint(x, y: PDouble);
2644 begin
2645 AggWorldToScreen(x ,y );
2646
2647 x^:=Floor(x^ ) + 0.5;
2648 y^:=Floor(y^ ) + 0.5;
2649
2650 AggScreenToWorld(x ,y );
2651 end;
2652
2653 procedure TAggFPCanvas.AggRenderImage(img: TAggFPImage; x1, y1, x2,
2654 y2: integer; parl: PDouble);
2655 var
2656 mtx : trans_affine;
2657 interpolator : span_interpolator_linear;
2658 begin
2659 mtx.Construct(x1 ,y1 ,x2 ,y2 ,parallelo_ptr(parl ) );
2660 mtx.multiply (@m_transform );
2661 mtx.invert;
2662
2663 m_rasterizer.reset;
2664 m_rasterizer.add_path(@m_pathTransform );
2665
2666 interpolator.Construct(@mtx );
2667
2668 if (m_blendMode = AGG_BlendAlpha ) or
2669 (Image.PixelFormat = afpimRGB24 ) then
2670 Agg2DRenderer_renderImage(img ,@m_renBasePre ,@interpolator )
2671 else
2672 Agg2DRenderer_renderImage(img ,@m_renBaseCompPre ,@interpolator );
2673 end;
2674
2675 procedure TAggFPCanvas.AggTransformImage(SrcImage: TAggFPImage; const imgX1,
2676 imgY1, imgX2, imgY2: integer; const dstX1, dstY1, dstX2, dstY2: double);
2677 var
2678 parall : array[0..5 ] of double;
2679 begin
2680 AggResetPath;
2681 AggMoveTo(dstX1 ,dstY1 );
2682 AggLineTo(dstX2 ,dstY1 );
2683 AggLineTo(dstX2 ,dstY2 );
2684 AggLineTo(dstX1 ,dstY2 );
2685 AggClosePolygon;
2686
2687 parall[0 ]:=dstX1;
2688 parall[1 ]:=dstY1;
2689 parall[2 ]:=dstX2;
2690 parall[3 ]:=dstY1;
2691 parall[4 ]:=dstX2;
2692 parall[5 ]:=dstY2;
2693
2694 AggRenderImage(SrcImage ,imgX1 ,imgY1 ,imgX2 ,imgY2 ,@parall[0 ] );
2695 end;
2696
2697 procedure TAggFPCanvas.AggTransformImage(SrcImage: TAggFPImage; const dstX1,
2698 dstY1, dstX2, dstY2: double);
2699 var
2700 parall : array[0..5 ] of double;
2701 begin
2702 AggResetPath;
2703 AggMoveTo(dstX1 ,dstY1 );
2704 AggLineTo(dstX2 ,dstY1 );
2705 AggLineTo(dstX2 ,dstY2 );
2706 AggLineTo(dstX1 ,dstY2 );
2707 AggClosePolygon;
2708
2709 parall[0 ]:=dstX1;
2710 parall[1 ]:=dstY1;
2711 parall[2 ]:=dstX2;
2712 parall[3 ]:=dstY1;
2713 parall[4 ]:=dstX2;
2714 parall[5 ]:=dstY2;
2715
2716 AggRenderImage(SrcImage ,0 ,0 ,SrcImage.Width ,SrcImage.Height ,@parall[0 ] );
2717 end;
2718
2719 procedure TAggFPCanvas.AggTransformImage(SrcImage: TAggFPImage; imgX1, imgY1,
2720 imgX2, imgY2: integer; parallelo: PDouble);
2721 begin
2722 AggResetPath;
2723
2724 AggMoveTo(
2725 PDouble(ptrcomp(parallelo ) + 0 * sizeof(double ) )^ ,
2726 PDouble(ptrcomp(parallelo ) + 1 * sizeof(double ) )^ );
2727
2728 AggLineTo(
2729 PDouble(ptrcomp(parallelo ) + 2 * sizeof(double ) )^ ,
2730 PDouble(ptrcomp(parallelo ) + 3 * sizeof(double ) )^ );
2731
2732 AggLineTo(
2733 PDouble(ptrcomp(parallelo ) + 4 * sizeof(double ) )^ ,
2734 PDouble(ptrcomp(parallelo ) + 5 * sizeof(double ) )^ );
2735
2736 AggLineTo(
2737 PDouble(ptrcomp(parallelo ) + 0 * sizeof(double ) )^ +
2738 PDouble(ptrcomp(parallelo ) + 4 * sizeof(double ) )^ -
2739 PDouble(ptrcomp(parallelo ) + 2 * sizeof(double ) )^ ,
2740 PDouble(ptrcomp(parallelo ) + 1 * sizeof(double ) )^ +
2741 PDouble(ptrcomp(parallelo ) + 5 * sizeof(double ) )^ -
2742 PDouble(ptrcomp(parallelo ) + 3 * sizeof(double ) )^ );
2743
2744 AggClosePolygon;
2745
2746 AggRenderImage(SrcImage ,imgX1 ,imgY1 ,imgX2 ,imgY2 ,parallelo );
2747 end;
2748
2749 procedure TAggFPCanvas.AggTransformImage(SrcImage: TAggFPImage; parallelo: PDouble);
2750 begin
2751 AggResetPath;
2752
2753 AggMoveTo(
2754 PDouble(ptrcomp(parallelo ) + 0 * sizeof(double ) )^ ,
2755 PDouble(ptrcomp(parallelo ) + 1 * sizeof(double ) )^ );
2756
2757 AggLineTo(
2758 PDouble(ptrcomp(parallelo ) + 2 * sizeof(double ) )^ ,
2759 PDouble(ptrcomp(parallelo ) + 3 * sizeof(double ) )^ );
2760
2761 AggLineTo(
2762 PDouble(ptrcomp(parallelo ) + 4 * sizeof(double ) )^ ,
2763 PDouble(ptrcomp(parallelo ) + 5 * sizeof(double ) )^ );
2764
2765 AggLineTo(
2766 PDouble(ptrcomp(parallelo ) + 0 * sizeof(double ) )^ +
2767 PDouble(ptrcomp(parallelo ) + 4 * sizeof(double ) )^ -
2768 PDouble(ptrcomp(parallelo ) + 2 * sizeof(double ) )^ ,
2769 PDouble(ptrcomp(parallelo ) + 1 * sizeof(double ) )^ +
2770 PDouble(ptrcomp(parallelo ) + 5 * sizeof(double ) )^ -
2771 PDouble(ptrcomp(parallelo ) + 3 * sizeof(double ) )^ );
2772
2773 AggClosePolygon;
2774
2775 AggRenderImage(SrcImage ,0 ,0 ,SrcImage.Width ,SrcImage.Height ,parallelo );
2776 end;
2777
2778 procedure TAggFPCanvas.AggTransformImagePath(SrcImage: TAggFPImage; const imgX1,
2779 imgY1, imgX2, imgY2: integer; const dstX1, dstY1, dstX2, dstY2: double);
2780 var
2781 parall : array[0..5 ] of double;
2782 begin
2783 parall[0 ]:=dstX1;
2784 parall[1 ]:=dstY1;
2785 parall[2 ]:=dstX2;
2786 parall[3 ]:=dstY1;
2787 parall[4 ]:=dstX2;
2788 parall[5 ]:=dstY2;
2789
2790 AggRenderImage(SrcImage ,imgX1 ,imgY1 ,imgX2 ,imgY2 ,@parall[0 ] );
2791 end;
2792
2793 procedure TAggFPCanvas.AggTransformImagePath(SrcImage: TAggFPImage; const dstX1,
2794 dstY1, dstX2, dstY2: double);
2795 var
2796 parall : array[0..5 ] of double;
2797 begin
2798 parall[0 ]:=dstX1;
2799 parall[1 ]:=dstY1;
2800 parall[2 ]:=dstX2;
2801 parall[3 ]:=dstY1;
2802 parall[4 ]:=dstX2;
2803 parall[5 ]:=dstY2;
2804
2805 AggRenderImage(SrcImage ,0 ,0 ,SrcImage.Width ,SrcImage.Height ,@parall[0 ] );
2806 end;
2807
2808 procedure TAggFPCanvas.AggTransformImagePath(SrcImage: TAggFPImage; const imgX1,
2809 imgY1, imgX2, imgY2: integer; const parallelo: PDouble);
2810 begin
2811 AggRenderImage(SrcImage ,imgX1 ,imgY1 ,imgX2 ,imgY2 ,parallelo );
2812 end;
2813
2814 procedure TAggFPCanvas.AggTransformImagePath(SrcImage: TAggFPImage;
2815 parallelo: PDouble);
2816 begin
2817 AggRenderImage(SrcImage ,0 ,0 ,SrcImage.Width ,SrcImage.Height ,parallelo );
2818 end;
2819
2820 procedure TAggFPCanvas.AggCopyImage(SrcImage: TAggFPImage; const imgX1, imgY1,
2821 imgX2, imgY2: integer; const dstX, dstY: double);
2822 var
2823 r: agg_basics.rect;
2824 begin
2825 AggWorldToScreen(@dstX ,@dstY );
2826 r.Construct (imgX1 ,imgY1 ,imgX2 ,imgY2 );
2827
2828 m_renBase.copy_from(@SrcImage.RenderingBuffer ,@r ,
2829 Trunc(dstX ) - imgX1 ,Trunc(dstY ) - imgY1 );
2830 end;
2831
2832 procedure TAggFPCanvas.AggCopyImage(SrcImage: TAggFPImage; const dstX,
2833 dstY: double);
2834 begin
2835 AggWorldToScreen(@dstX ,@dstY );
2836 m_renBase.copy_from(@SrcImage.RenderingBuffer ,NIL ,Trunc(dstX ) ,Trunc(dstY ) );
2837 end;
2838
AggTextWidthnull2839 function TAggFPCanvas.AggTextWidth(str: AnsiString): double;
2840 {$IFDEF AGG2D_NO_FONT}
2841 begin
2842
2843 end;
2844 {$ELSE}
2845 var
2846 x ,y : double;
2847 first : boolean;
2848 glyph : glyph_cache_ptr;
2849 str_ : PChar;
2850 charlen: int;
2851 char_id: int32u;
2852 begin
2853 if str='' then exit(0);
2854 x:=0;
2855 y:=0;
2856
2857 first:=true;
2858 str_ :=@str[1 ];
2859
2860 while str_^ <> #0 do
2861 begin
2862 if UseUTF8 then
2863 begin
2864 char_id:=AggUTF8CharToUnicode(str_,charlen);
2865 inc(str_,charlen);
2866 end else begin
2867 char_id:=int32u(char_ptr(str_)^);
2868 inc(str_,sizeof(char));
2869 end;
2870 glyph:=m_fontCacheManager.glyph(char_id);
2871
2872 if glyph <> NIL then
2873 begin
2874 if not first then
2875 m_fontCacheManager.add_kerning(@x ,@y );
2876
2877 x:=x + glyph^.advance_x;
2878 y:=y + glyph^.advance_y;
2879
2880 first:=false;
2881 end;
2882
2883 end;
2884
2885 if Font.FAggCache = AGG_VectorFontCache then
2886 result:=x
2887 else
2888 result:=AggScreenToWorld(x );
2889 end;
2890 {$ENDIF}
2891
AggTextHeightnull2892 function TAggFPCanvas.AggTextHeight(str: AnsiString): double;
2893 begin
2894 {$IFDEF AGG2D_NO_FONT}
2895 Result:=0;
2896 {$ELSE}
2897 Result:=m_fontEngine._height;
2898 {$ENDIF}
2899 end;
2900
2901 procedure TAggFPCanvas.AggTextOut(const x, y: double; str: AnsiString;
2902 roundOff: boolean; const ddx: double; const ddy: double);
2903 {$IFDEF AGG2D_NO_FONT}
2904 begin
2905
2906 end;
2907 {$ELSE}
2908 var
2909 dx ,dy ,asc ,start_x ,start_y : double;
2910
2911 glyph : glyph_cache_ptr;
2912
2913 mtx : trans_affine;
2914 str_ : PChar;
2915
2916 tat : trans_affine_translation;
2917 tar : trans_affine_rotation;
2918
2919 tr : conv_transform;
2920 charlen: int;
2921 char_id: int32u;
2922 First: Boolean;
2923
2924 begin
2925 if Str='' then exit;
2926
2927 dx:=0.0;
2928 dy:=0.0;
2929
2930 case Font.AggAlignX of
2931 AGG_AlignCenter :
2932 dx:=-AggTextWidth(str ) * 0.5;
2933
2934 AGG_AlignRight :
2935 dx:=-AggTextWidth(str );
2936
2937 end;
2938
2939 asc :=Font.AggHeight;
2940 glyph:=m_fontCacheManager.glyph(int32u('H' ) );
2941
2942 if glyph <> NIL then
2943 asc:=glyph^.bounds.y2 - glyph^.bounds.y1;
2944
2945 if Font.FAggCache = AGG_RasterFontCache then
2946 asc:=AggScreenToWorld(asc );
2947
2948 case Font.AggAlignY of
2949 AGG_AlignCenter :
2950 dy:=-asc * 0.5;
2951
2952 AGG_AlignTop :
2953 dy:=-asc;
2954
2955 end;
2956
2957 if m_fontEngine._flip_y then
2958 dy:=-dy;
2959
2960 mtx.Construct;
2961
2962 start_x:=x + dx;
2963 start_y:=y + dy;
2964
2965 if roundOff then
2966 begin
2967 start_x:=Trunc(start_x );
2968 start_y:=Trunc(start_y );
2969 end;
2970
2971 start_x:=start_x + ddx;
2972 start_y:=start_y + ddy;
2973
2974 tat.Construct(-x ,-y );
2975 mtx.multiply (@tat );
2976
2977 tar.Construct(Font.AggAngle );
2978 mtx.multiply (@tar );
2979
2980 tat.Construct(x ,y );
2981 mtx.multiply (@tat );
2982
2983 tr.Construct(m_fontCacheManager.path_adaptor ,@mtx );
2984
2985 if Font.FAggCache = AGG_RasterFontCache then
2986 AggWorldToScreen(@start_x ,@start_y );
2987
2988 str_:=@str[1 ];
2989 First:=true;
2990
2991 while str_^ <> #0 do
2992 begin
2993 if UseUTF8 then
2994 begin
2995 char_id:=AggUTF8CharToUnicode(str_,charlen);
2996 inc(str_,charlen);
2997 end else begin
2998 char_id:=int32u(char_ptr(str_)^);
2999 inc(str_,sizeof(char));
3000 end;
3001 glyph:=m_fontCacheManager.glyph(char_id);
3002
3003 if glyph <> NIL then
3004 begin
3005 if First then
3006 begin
3007 m_fontCacheManager.add_kerning(@x ,@y );
3008 First:=false;
3009 end;
3010
3011 m_fontCacheManager.init_embedded_adaptors(glyph ,start_x ,start_y );
3012
3013 if glyph^.data_type = glyph_data_outline then
3014 begin
3015 Path.m_path.remove_all;
3016 Path.m_path.add_path(@tr ,0 ,false );
3017
3018 if Font.AggUseOnlyFont then
3019 AggDrawPath(AGG_FillOnly,true)
3020 else
3021 AggDrawPath(AGG_FillAndStroke,true);
3022 end;
3023
3024 if glyph^.data_type = glyph_data_gray8 then
3025 begin
3026 Render(
3027 m_fontCacheManager.gray8_adaptor ,
3028 m_fontCacheManager.gray8_scanline );
3029 end;
3030
3031 start_x:=start_x + glyph^.advance_x;
3032 start_y:=start_y + glyph^.advance_y;
3033 end;
3034 end;
3035 end;
3036 {$ENDIF}
3037
3038 { AGG2DRENDERER_RENDER }
3039 procedure TAggFPCanvas.Agg2DRenderer_render(
3040 renBase : renderer_base_ptr;
3041 renSolid : renderer_scanline_aa_solid_ptr;
3042 fillColor_ , UseFont: boolean );
3043 var
3044 span : span_gradient;
3045 ren : TAggFP_renderer_scanline_aa;
3046 clr : aggclr;
3047
3048 begin
3049 if (fillColor_ and
3050 (m_fillGradientFlag = AGG_Linear ) ) or
3051 (not fillColor_ and
3052 (m_lineGradientFlag = AGG_Linear ) ) then
3053 if fillColor_ then
3054 begin
3055 span.Construct(
3056 @m_allocator ,
3057 @m_fillGradientInterpolator ,
3058 @m_linearGradientFunction ,
3059 @m_fillGradient ,
3060 m_fillGradientD1 ,
3061 m_fillGradientD2 );
3062
3063 ren.Construct (renBase ,@span );
3064 render_scanlines(@m_rasterizer ,@m_scanline ,@ren );
3065
3066 end
3067 else
3068 begin
3069 span.Construct(
3070 @m_allocator ,
3071 @m_lineGradientInterpolator ,
3072 @m_linearGradientFunction ,
3073 @m_lineGradient ,
3074 m_lineGradientD1 ,
3075 m_lineGradientD2 );
3076
3077 ren.Construct (renBase ,@span );
3078 render_scanlines(@m_rasterizer ,@m_scanline ,@ren );
3079
3080 end
3081 else
3082 if (fillColor_ and
3083 (m_fillGradientFlag = AGG_Radial ) ) or
3084 (not fillColor_ and
3085 (m_lineGradientFlag = AGG_Radial ) ) then
3086 begin
3087 if fillColor_ then
3088 begin
3089 span.Construct(
3090 @m_allocator ,
3091 @m_fillGradientInterpolator ,
3092 @m_radialGradientFunction ,
3093 @m_fillGradient ,
3094 m_fillGradientD1 ,
3095 m_fillGradientD2 );
3096
3097 ren.Construct (renBase ,@span );
3098 render_scanlines(@m_rasterizer ,@m_scanline ,@ren );
3099
3100 end
3101 else
3102 begin
3103 span.Construct(
3104 @m_allocator ,
3105 @m_lineGradientInterpolator ,
3106 @m_radialGradientFunction ,
3107 @m_lineGradient ,
3108 m_lineGradientD1 ,
3109 m_lineGradientD2 );
3110
3111 ren.Construct (renBase ,@span );
3112 render_scanlines(@m_rasterizer ,@m_scanline ,@ren );
3113
3114 end;
3115 end
3116 else
3117 begin
3118 if UseFont then
3119 clr.Construct(Font.FAggColor )
3120 else if fillColor_ then
3121 clr.Construct(Brush.FAggColor )
3122 else
3123 clr.Construct(Pen.FAggColor );
3124
3125 renSolid^.color_ (@clr );
3126 render_scanlines(@m_rasterizer ,@m_scanline ,renSolid );
3127 end;
3128 end;
3129
3130 procedure TAggFPCanvas.Agg2DRenderer_render(
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 UseFont: boolean);
3136 var
3137 span : span_gradient;
3138 ren : renderer_scanline_aa;
3139 clr : aggclr;
3140
3141 begin
3142 if UseFont then
3143 begin
3144 clr.Construct(Brush.fAggColor );
3145 renSolid^.color_ (@clr );
3146 render_scanlines(ras ,sl ,renSolid );
3147 end
3148 else if m_fillGradientFlag = AGG_Linear then
3149 begin
3150 span.Construct(
3151 @m_allocator ,
3152 @m_fillGradientInterpolator ,
3153 @m_linearGradientFunction ,
3154 @m_fillGradient ,
3155 m_fillGradientD1 ,
3156 m_fillGradientD2 );
3157
3158 ren.Construct (renBase ,@span );
3159 render_scanlines(ras ,sl ,@ren );
3160
3161 end
3162 else
3163 if m_fillGradientFlag = AGG_Radial then
3164 begin
3165 span.Construct(
3166 @m_allocator ,
3167 @m_fillGradientInterpolator ,
3168 @m_radialGradientFunction ,
3169 @m_fillGradient ,
3170 m_fillGradientD1 ,
3171 m_fillGradientD2 );
3172
3173 ren.Construct (renBase ,@span );
3174 render_scanlines(ras ,sl ,@ren );
3175
3176 end
3177 else
3178 begin
3179 clr.Construct(Brush.fAggColor );
3180 renSolid^.color_ (@clr );
3181 render_scanlines(ras ,sl ,renSolid );
3182 end;
3183 end;
3184
3185 procedure TAggFPCanvas.addLine(const x1, y1, x2, y2: double);
3186 begin
3187 Path.m_path.move_to(x1 ,y1 );
3188 Path.m_path.line_to(x2 ,y2 );
3189 end;
3190
GetAggTransformationsnull3191 function TAggFPCanvas.GetAggTransformations: TAggTransformations;
3192 begin
3193 m_transform.store_to(@result.affineMatrix[0]);
3194 end;
3195
3196 procedure TAggFPCanvas.Agg2DRenderer_renderImage(
3197 img : TAggFPImage;
3198 renBase : renderer_base_ptr;
3199 interpolator : span_interpolator_linear_ptr );
3200 var
3201 blend : TAggSpanConvImageBlend;
3202
3203 si : span_image_filter_rgba;
3204 sg : span_image_filter_rgba_nn;
3205 sb : span_image_filter_rgba_bilinear;
3206 s2 : span_image_filter_rgba_2x2;
3207 sa : span_image_resample_rgba_affine;
3208 sc : span_converter;
3209 ri : renderer_scanline_aa;
3210
3211 clr : aggclr;
3212
3213 resample : boolean;
3214
3215 sx ,sy : double;
3216
3217 begin
3218 case Image.PixelFormat of
3219 afpimRGBA32 :
3220 blend.Construct(m_imageBlendMode ,m_imageBlendColor ,@m_pixFormatCompPre );
3221
3222 else
3223 blend.Construct(m_imageBlendMode ,m_imageBlendColor ,NIL );
3224
3225 end;
3226
3227 if m_imageFilter = AGG_NoFilter then
3228 begin
3229 clr.ConstrInt(0 ,0 ,0 ,0 );
3230 sg.Construct (@m_allocator ,@img.RenderingBuffer ,@clr ,interpolator ,rgba_order );
3231 sc.Construct (@sg ,@blend );
3232 ri.Construct (renBase ,@sc );
3233
3234 render_scanlines(@m_rasterizer ,@m_scanline ,@ri );
3235
3236 end
3237 else
3238 begin
3239 resample:=m_imageResample = AGG_ResampleAlways;
3240
3241 if m_imageResample = AGG_ResampleOnZoomOut then
3242 begin
3243 interpolator^._transformer^.scaling_abs(@sx ,@sy );
3244
3245 if (sx > 1.125 ) or
3246 (sy > 1.125 ) then
3247 resample:=true;
3248
3249 end;
3250
3251 if resample then
3252 begin
3253 clr.ConstrInt(0 ,0 ,0 ,0 );
3254 sa.Construct(
3255 @m_allocator ,
3256 @img.RenderingBuffer ,
3257 @clr ,
3258 interpolator ,
3259 @m_imageFilterLut ,
3260 rgba_order );
3261
3262 sc.Construct(@sa ,@blend );
3263 ri.Construct(renBase ,@sc );
3264
3265 render_scanlines(@m_rasterizer ,@m_scanline ,@ri );
3266
3267 end
3268 else
3269 if m_imageFilter = AGG_Bilinear then
3270 begin
3271 clr.ConstrInt(0 ,0 ,0 ,0 );
3272 sb.Construct(
3273 @m_allocator ,
3274 @img.RenderingBuffer ,
3275 @clr ,
3276 interpolator ,
3277 rgba_order );
3278
3279 sc.Construct(@sb ,@blend );
3280 ri.Construct(renBase ,@sc );
3281
3282 render_scanlines(@m_rasterizer ,@m_scanline ,@ri );
3283
3284 end
3285 else
3286 if m_imageFilterLut.diameter = 2 then
3287 begin
3288 clr.ConstrInt(0 ,0 ,0 ,0 );
3289 s2.Construct(
3290 @m_allocator ,
3291 @img.RenderingBuffer ,
3292 @clr ,
3293 interpolator,
3294 @m_imageFilterLut ,
3295 rgba_order );
3296
3297 sc.Construct(@s2 ,@blend );
3298 ri.Construct(renBase ,@sc );
3299
3300 render_scanlines(@m_rasterizer ,@m_scanline ,@ri );
3301
3302 end
3303 else
3304 begin
3305 clr.ConstrInt(0 ,0 ,0 ,0 );
3306 si.Construct(
3307 @m_allocator ,
3308 @img.RenderingBuffer ,
3309 @clr ,
3310 interpolator ,
3311 @m_imageFilterLut ,
3312 rgba_order );
3313
3314 sc.Construct(@si ,@blend );
3315 ri.Construct(renBase ,@sc );
3316
3317 render_scanlines(@m_rasterizer ,@m_scanline ,@ri );
3318
3319 end;
3320
3321 end;
3322
3323 end;
3324
3325 { TAggFPPen }
3326
3327 procedure TAggFPPen.SetFPColor(const AValue: TFPColor);
3328 begin
3329 if FPColor=AValue then exit;
3330 inherited SetFPColor(AValue);
3331 FAggColor:=FPToAggColor(AValue);
3332 end;
3333
3334 procedure TAggFPPen.SetAggColor(const AValue: TAggColor);
3335 begin
3336 FPColor:=AggToFPColor(AValue);
3337 end;
3338
3339 procedure TAggFPPen.DoCopyProps(From: TFPCanvasHelper);
3340 var
3341 Src: TAggFPPen;
3342 begin
3343 inherited DoCopyProps(From);
3344 if From is TAggFPPen then begin
3345 Src:=TAggFPPen(From);
3346 FAggColor:=Src.FAggColor;
3347 AggLineCap:=Src.AggLineCap;
3348 AggLineJoin:=Src.AggLineJoin;
3349 AggLineWidth:=Src.AggLineWidth;
3350 end;
3351 end;
3352
3353 constructor TAggFPPen.Create;
3354 begin
3355 inherited Create;
3356 FAggLineCap:=AGG_CapRound;
3357 FAggLineJoin:=AGG_JoinRound;
3358 FAggLineWidth:=1.0;
3359 end;
3360
3361 procedure TAggFPPen.SetAggLineCap(const AValue: TAggLineCap);
3362 begin
3363 if FAggLineCap=AValue then exit;
3364 FAggLineCap:=AValue;
3365 TAggFPCanvas(Canvas).m_convStroke.line_cap_(FAggLineCap);
3366 end;
3367
3368 procedure TAggFPPen.SetAggLineJoin(const AValue: TAggLineJoin);
3369 begin
3370 if FAggLineJoin=AValue then exit;
3371 FAggLineJoin:=AValue;
3372 TAggFPCanvas(Canvas).m_convStroke.line_join_(FAggLineJoin);
3373 end;
3374
3375 procedure TAggFPPen.SetAggLineWidth(const AValue: double);
3376 begin
3377 if FAggLineWidth=AValue then exit;
3378 FAggLineWidth:=AValue;
3379 inherited SetWidth(round(AValue));
3380 TAggFPCanvas(Canvas).m_convStroke.width_(FAggLineWidth);
3381 end;
3382
3383 procedure TAggFPPen.SetWidth(AValue: Integer);
3384 var
3385 NewWidth: Double;
3386 begin
3387 NewWidth:=double(AValue);
3388 if NewWidth=AggLineWidth then exit;
3389 inherited SetWidth(AValue);
3390 AggLineWidth:=NewWidth;
3391 end;
3392
3393 { CONSTRUCT }
3394 constructor TAggRasterizerGamma.Construct(alpha ,gamma : double );
3395 begin
3396 m_alpha.Construct(alpha );
3397 m_gamma.Construct(gamma );
3398 end;
3399
3400 { FUNC_OPERATOR_GAMMA }
func_operator_gammanull3401 function TAggRasterizerGamma.func_operator_gamma(x : double ) : double;
3402 begin
3403 result:=m_alpha.func_operator_gamma(m_gamma.func_operator_gamma(x ) );
3404 end;
3405
operator_arraynull3406 function TAggRasterizerGamma.operator_array(i: unsigned): unsigned;
3407 begin
3408 Result:=i;
3409 end;
3410
3411 { TAggFPBrush }
3412
3413 procedure TAggFPBrush.SetAggFillEvenOdd(const AValue: boolean);
3414 begin
3415 if FAggFillEvenOdd=AValue then exit;
3416 FAggFillEvenOdd:=AValue;
3417
3418 if FAggFillEvenOdd then
3419 TAggFPCanvas(Canvas).m_rasterizer.filling_rule(fill_even_odd )
3420 else
3421 TAggFPCanvas(Canvas).m_rasterizer.filling_rule(fill_non_zero );
3422 end;
3423
3424 procedure TAggFPBrush.DoCopyProps(From: TFPCanvasHelper);
3425 var
3426 Src: TAggFPBrush;
3427 begin
3428 inherited DoCopyProps(From);
3429 if From is TAggFPBrush then begin
3430 Src:=TAggFPBrush(From);
3431 FAggColor:=Src.FAggColor;
3432 AggFillEvenOdd:=Src.AggFillEvenOdd;
3433 end;
3434 end;
3435
3436 procedure TAggFPBrush.SetFPColor(const AValue: TFPColor);
3437 begin
3438 if FPColor=AValue then exit;
3439 inherited SetFPColor(AValue);
3440 FAggColor:=FPToAggColor(AValue);
3441 end;
3442
3443 procedure TAggFPBrush.SetAggColor(const AValue: TAggColor);
3444 begin
3445 FPColor:=AggToFPColor(AValue);
3446 end;
3447
3448 procedure TAggFPBrush.SetStyle(AValue: TFPBrushStyle);
3449 begin
3450 if Style=AValue then exit;
3451 inherited SetStyle(AValue);
3452 // not supported by aggpas
3453 end;
3454
3455 { TAggFPFont }
3456
3457 procedure TAggFPFont.SetAggAlignX(const AValue: TAggTextAlignment);
3458 begin
3459 if FAggAlignX=AValue then exit;
3460 FAggAlignX:=AValue;
3461 end;
3462
3463 procedure TAggFPFont.SetAggAlignY(const AValue: TAggTextAlignment);
3464 begin
3465 if FAggAlignY=AValue then exit;
3466 FAggAlignY:=AValue;
3467 end;
3468
3469 procedure TAggFPFont.SetAggAngle(const AValue: double);
3470 begin
3471 if FAggAngle=AValue then exit;
3472 FAggAngle:=AValue;
3473 end;
3474
3475 procedure TAggFPFont.SetAggFlipY(const AValue: boolean);
3476 begin
3477 if FAggFlipY=AValue then exit;
3478 FAggFlipY:=AValue;
3479 {$IFNDEF AGG2D_NO_FONT}
3480 TAggFPCanvas(Canvas).m_fontEngine.flip_y_(not FAggFlipY);
3481 {$ENDIF}
3482 end;
3483
3484 procedure TAggFPFont.SetAggHeight(const AValue: double);
3485 {$IFDEF AGG2D_USE_FREETYPE}
3486 var
3487 c: TAggFPCanvas;
3488 {$ENDIF}
3489 begin
3490 if FAggHeight=AValue then exit;
3491 FAggHeight:=AValue;
3492 inherited SetSize(round(AggHeightToSize(FAggHeight)));
3493 {$IFDEF AGG2D_USE_FREETYPE}
3494 c:=TAggFPCanvas(Canvas);
3495 if FAggCache = AGG_VectorFontCache then
3496 c.m_fontEngine.height_(FAggHeight )
3497 else
3498 c.m_fontEngine.height_(c.AggWorldToScreen(FAggHeight ) );
3499 {$ELSE}
3500 // ToDo
3501 {$ENDIF}
3502 end;
3503
3504 procedure TAggFPFont.SetAggHinting(const AValue: boolean);
3505 begin
3506 if FAggHinting=AValue then exit;
3507 FAggHinting:=AValue;
3508 {$IFDEF AGG2D_USE_FREETYPE}
3509 TAggFPCanvas(Canvas).m_fontEngine.hinting_(FAggHinting );
3510 {$ENDIF}
3511 end;
3512
3513 procedure TAggFPFont.SetSize(AValue: integer);
3514 begin
3515 AggHeight:=SizeToAggHeight(AValue);
3516 end;
3517
AggHeightToSizenull3518 function TAggFPFont.AggHeightToSize(const h: double): double;
3519 begin
3520 Result:=h;
3521 end;
3522
SizeToAggHeightnull3523 function TAggFPFont.SizeToAggHeight(const s: double): double;
3524 begin
3525 Result:=s;
3526 end;
3527
3528 procedure TAggFPFont.SetFPColor(const AValue: TFPColor);
3529 begin
3530 if FPColor=AValue then exit;
3531 inherited SetFPColor(AValue);
3532 FAggColor:=FPToAggColor(AValue);
3533 end;
3534
3535 procedure TAggFPFont.SetAggColor(const AValue: TAggColor);
3536 begin
3537 FPColor:=AggToFPColor(AValue);
3538 end;
3539
3540 procedure TAggFPFont.DoCopyProps(From: TFPCanvasHelper);
3541 var
3542 Src: TAggFPFont;
3543 begin
3544 inherited DoCopyProps(From);
3545 if From is TAggFPFont then begin
3546 Src:=TAggFPFont(From);
3547 FAggColor:=Src.FAggColor;
3548 AggAlignX:=Src.AggAlignX;
3549 AggAlignY:=Src.AggAlignY;
3550 AggAngle:=Src.AggAngle;
3551 AggHinting:=Src.AggHinting;
3552 FAggHeight:=Src.AggHeight;
3553 end;
3554 end;
3555
3556 constructor TAggFPFont.Create;
3557 begin
3558 inherited Create;
3559 FAggAlignX:=AGG_AlignLeft;
3560 FAggAlignY:=AGG_AlignBottom;
3561 FAggHinting:=true;
3562 FAggUseOnlyFont:=true;
3563 end;
3564
3565 procedure TAggFPFont.LoadFromFile(aFilename: String; const NewHeight: double;
3566 const NewBold: boolean; const NewItalic: boolean;
3567 const NewCache: TAggFontCacheType; const NewAngle: double;
3568 const NewHinting: boolean);
3569 {$IFDEF AGG2D_USE_WINFONTS }
3570 var
3571 b : int;
3572 {$ENDIF}
3573 var
3574 c: TAggFPCanvas;
3575 begin
3576 FAggAngle:=NewAngle;
3577 FAggHeight:=NewHeight;
3578 inherited SetSize(round(FAggHeight));
3579 FAggCache:=NewCache;
3580 FAggHinting:=NewHinting;
3581 inherited SetFlags(5,NewBold); // Bold
3582 inherited SetFlags(6,NewItalic); // Italic
3583 inherited SetFlags(7,false); // Underline
3584 inherited SetFlags(8,false); // StrikeThrough
3585
3586 c:=TAggFPCanvas(Canvas);
3587
3588 {$IFDEF AGG2D_USE_FREETYPE }
3589 if FAggCache = AGG_VectorFontCache then
3590 c.m_fontEngine.load_font(PChar(@AFileName[1 ] ) ,0 ,glyph_ren_outline )
3591 else
3592 c.m_fontEngine.load_font(PChar(@AFileName[1 ] ) ,0 ,glyph_ren_agg_gray8 );
3593
3594 c.m_fontEngine.hinting_(FAggHinting );
3595
3596 if FAggCache = AGG_VectorFontCache then
3597 c.m_fontEngine.height_(FAggHeight )
3598 else
3599 c.m_fontEngine.height_(c.AggWorldToScreen(FAggHeight ) );
3600
3601 {$ENDIF }
3602 {$IFDEF AGG2D_USE_WINFONTS}
3603
3604 c.m_fontEngine.hinting_(FAggHinting );
3605
3606 if Bold then
3607 b:=700
3608 else
3609 b:=400;
3610
3611 if FAggCache = AGG_VectorFontCache then
3612 c.m_fontEngine.create_font_(PChar(@AFileName[1 ] ) ,glyph_ren_outline ,
3613 FAggHeight ,0.0 ,b ,Italic )
3614 else
3615 c.m_fontEngine.create_font_(PChar(@AFileName[1 ] ) ,glyph_ren_agg_gray8 ,
3616 c.AggWorldToScreen(FAggHeight) ,0.0 ,b ,Italic );
3617 {$ENDIF }
3618
3619 {$IFNDEF AGG2D_NO_FONT}
3620 TAggFPCanvas(Canvas).m_fontEngine.flip_y_(not FAggFlipY);
3621 {$ENDIF}
3622 end;
3623
3624 { TAggFP_renderer_scanline_aa }
3625
3626 procedure TAggFP_renderer_scanline_aa.add_path(vs: vertex_source_ptr;
3627 path_id: unsigned);
3628 begin
3629 raise Exception.Create('not usable');
3630 end;
3631
3632 procedure TAggFP_renderer_scanline_aa.add_vertex(x, y: double; cmd: unsigned);
3633 begin
3634 raise Exception.Create('not usable');
3635 end;
3636
3637 procedure TAggFP_renderer_scanline_aa.clip_box(x1, y1, x2, y2: double);
3638 begin
3639 raise Exception.Create('not usable');
3640 end;
3641
3642 procedure TAggFP_renderer_scanline_aa.color_(c: aggclr_ptr);
3643 begin
3644 raise Exception.Create('not usable');
3645 end;
3646
3647 procedure TAggFP_renderer_scanline_aa.filling_rule(filling_rule_: filling_rule_e);
3648 begin
3649 raise Exception.Create('not usable');
3650 end;
3651
3652 procedure TAggFP_renderer_scanline_aa.gamma(gamma_function: vertex_source_ptr);
3653 begin
3654 raise Exception.Create('not usable');
3655 end;
3656
3657 procedure TAggFP_renderer_scanline_aa.reset;
3658 begin
3659 raise Exception.Create('not usable');
3660 end;
3661
_max_ynull3662 function TAggFP_renderer_scanline_aa._max_y: int;
3663 begin
3664 raise Exception.Create('not usable');
3665 Result:=0;
3666 end;
3667
_max_xnull3668 function TAggFP_renderer_scanline_aa._max_x: int;
3669 begin
3670 raise Exception.Create('not usable');
3671 Result:=0;
3672 end;
3673
_min_xnull3674 function TAggFP_renderer_scanline_aa._min_x: int;
3675 begin
3676 raise Exception.Create('not usable');
3677 Result:=0;
3678 end;
3679
_min_ynull3680 function TAggFP_renderer_scanline_aa._min_y: int;
3681 begin
3682 raise Exception.Create('not usable');
3683 Result:=0;
3684 end;
3685
hit_testnull3686 function TAggFP_renderer_scanline_aa.hit_test(tx, ty: int): boolean;
3687 begin
3688 raise Exception.Create('not usable');
3689 Result:=false;
3690 end;
3691
sweep_scanlinenull3692 function TAggFP_renderer_scanline_aa.sweep_scanline(sl: scanline_ptr): boolean;
3693 begin
3694 raise Exception.Create('not usable');
3695 Result:=false;
3696 end;
3697
sweep_scanline_emnull3698 function TAggFP_renderer_scanline_aa.sweep_scanline_em(sl: scanline_ptr
3699 ): boolean;
3700 begin
3701 raise Exception.Create('not usable');
3702 Result:=false;
3703 end;
3704
rewind_scanlinesnull3705 function TAggFP_renderer_scanline_aa.rewind_scanlines: boolean;
3706 begin
3707 raise Exception.Create('not usable');
3708 Result:=false;
3709 end;
3710
3711 procedure TAggFP_renderer_scanline_aa.sort;
3712 begin
3713 raise Exception.Create('not usable');
3714 end;
3715
3716 { TAggFPPath }
3717
3718 procedure TAggFPPath.SetAggColor(const AValue: TAggColor);
3719 begin
3720 FPColor:=AggToFPColor(AValue);
3721 end;
3722
3723 procedure TAggFPPath.DoCopyProps(From: TFPCanvasHelper);
3724 var
3725 Src: TAggFPPath;
3726 begin
3727 inherited DoCopyProps(From);
3728 if From is TAggFPPath then begin
3729 Src:=TAggFPPath(From);
3730 FAggColor:=Src.FAggColor;
3731 end;
3732 end;
3733
3734 constructor TAggFPPath.Create;
3735 begin
3736 inherited Create;
3737 m_path.Construct;
3738 m_convCurve.Construct (@m_path );
3739 end;
3740
3741 destructor TAggFPPath.Destroy;
3742 begin
3743 m_convCurve.Destruct;
3744 m_path.Destruct;
3745 inherited Destroy;
3746 end;
3747
3748 end.
3749
3750