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