diff options
Diffstat (limited to 'src/corelib/render/software/Agg2D.pas')
-rw-r--r-- | src/corelib/render/software/Agg2D.pas | 6806 |
1 files changed, 3403 insertions, 3403 deletions
diff --git a/src/corelib/render/software/Agg2D.pas b/src/corelib/render/software/Agg2D.pas index cdbd9ba7..e78cdd3e 100644 --- a/src/corelib/render/software/Agg2D.pas +++ b/src/corelib/render/software/Agg2D.pas @@ -1,3403 +1,3403 @@ -//----------------------------------------------------------------------------
-// Agg2D - Version 1.0
-// Based on Anti-Grain Geometry
-// Copyright (C) 2005 Maxim Shemanarev (http://www.antigrain.com)
-//
-// TAgg2D - Version 1.0 Release Milano 3 (AggPas 2.4 RM3)
-// Pascal Port By: Milan Marusinec alias Milano
-// milan@marusinec.sk
-// http://www.aggpas.org
-// Copyright (c) 2007 - 2008
-//
-// Permission to copy, use, modify, sell and distribute this software
-// is granted provided this copyright notice appears in all copies.
-// This software is provided "as is" without express or implied
-// warranty, and with no claim as to its suitability for any purpose.
-//
-//----------------------------------------------------------------------------
-// Contact: mcseem@antigrain.com
-// mcseemagg@yahoo.com
-// http://www.antigrain.com
-//
-// [Pascal Port History] -----------------------------------------------------
-//
-// 22.11.2007-Milano: Unit port establishment
-// 23.11.2007-Milano: Porting
-// 11.12.2007-Milano: -"-
-// 13.12.2007-Milano: -"-
-// 13.01.2008-Milano: Finished OK
-//
-{ Agg2D.pas }
-unit
- Agg2D ;
-
-INTERFACE
-
-{$I agg_mode.inc }
-
-// With this define you can switch use of FreeType or Win32 TrueType font engine
-{DEFINE AGG2D_USE_FREETYPE }
-
-uses
- agg_basics ,
- agg_array ,
- agg_trans_affine ,
- agg_trans_viewport ,
- agg_path_storage ,
- agg_conv_stroke ,
- agg_conv_transform ,
- agg_conv_curve ,
- agg_rendering_buffer ,
- agg_renderer_base ,
- agg_renderer_scanline ,
- agg_span_gradient ,
- agg_span_image_filter_rgba ,
- agg_span_image_resample_rgba ,
- agg_span_converter ,
- agg_span_interpolator_linear ,
- agg_span_allocator ,
- agg_rasterizer_scanline_aa ,
- agg_gamma_functions ,
- agg_scanline_u ,
- agg_arc ,
- agg_bezier_arc ,
- agg_rounded_rect ,
- agg_font_engine ,
- agg_font_cache_manager ,
- agg_pixfmt ,
- agg_pixfmt_rgb ,
- agg_pixfmt_rgba ,
- agg_color ,
- agg_math_stroke ,
- agg_image_filters ,
- agg_vertex_source ,
- agg_render_scanlines ,
-
-{$IFDEF AGG2D_USE_FREETYPE }
- agg_font_freetype ,
-
-{$ELSE }
- agg_font_win32_tt ,
-
-{$ENDIF }
-
- Math ,Windows ,Classes ,Graphics ;
-
-{ GLOBAL VARIABLES & CONSTANTS }
-const
-// LineJoin
- AGG_JoinMiter = miter_join;
- AGG_JoinRound = round_join;
- AGG_JoinBevel = bevel_join;
-
-// LineCap
- AGG_CapButt = butt_cap;
- AGG_CapSquare = square_cap;
- AGG_CapRound = round_cap;
-
-// TextAlignment
- AGG_AlignLeft = 0;
- AGG_AlignRight = 1;
- AGG_AlignCenter = 2;
- AGG_AlignTop = AGG_AlignRight;
- AGG_AlignBottom = AGG_AlignLeft;
-
-// BlendMode
- AGG_BlendAlpha = end_of_comp_op_e;
- AGG_BlendClear = comp_op_clear;
- AGG_BlendSrc = comp_op_src;
- AGG_BlendDst = comp_op_dst;
- AGG_BlendSrcOver = comp_op_src_over;
- AGG_BlendDstOver = comp_op_dst_over;
- AGG_BlendSrcIn = comp_op_src_in;
- AGG_BlendDstIn = comp_op_dst_in;
- AGG_BlendSrcOut = comp_op_src_out;
- AGG_BlendDstOut = comp_op_dst_out;
- AGG_BlendSrcAtop = comp_op_src_atop;
- AGG_BlendDstAtop = comp_op_dst_atop;
- AGG_BlendXor = comp_op_xor;
- AGG_BlendAdd = comp_op_plus;
- AGG_BlendSub = comp_op_minus;
- AGG_BlendMultiply = comp_op_multiply;
- AGG_BlendScreen = comp_op_screen;
- AGG_BlendOverlay = comp_op_overlay;
- AGG_BlendDarken = comp_op_darken;
- AGG_BlendLighten = comp_op_lighten;
- AGG_BlendColorDodge = comp_op_color_dodge;
- AGG_BlendColorBurn = comp_op_color_burn;
- AGG_BlendHardLight = comp_op_hard_light;
- AGG_BlendSoftLight = comp_op_soft_light;
- AGG_BlendDifference = comp_op_difference;
- AGG_BlendExclusion = comp_op_exclusion;
- AGG_BlendContrast = comp_op_contrast;
-
-{ TYPES DEFINITION }
-type
- PDouble = ^double;
-
- PAggColor = ^TAggColor;
- TAggColor = rgba8;
-
- TAggRectD = agg_basics.rect_d;
-
- TAggAffine = trans_affine;
- PAggAffine = trans_affine_ptr;
-
- TAggFontRasterizer = gray8_adaptor_type;
- PAggFontRasterizer = gray8_adaptor_type_ptr;
-
- TAggFontScanline = gray8_scanline_type;
- PAggFontScanline = gray8_scanline_type_ptr;
-
-{$IFDEF AGG2D_USE_FREETYPE }
- TAggFontEngine = font_engine_freetype_int32;
-
-{$ELSE }
- TAggFontEngine = font_engine_win32_tt_int32;
-
-{$ENDIF }
-
- TAggGradient = (AGG_Solid ,AGG_Linear ,AGG_Radial );
- TAggDirection = (AGG_CW, AGG_CCW );
-
- TAggLineJoin = int;
- TAggLineCap = int;
- TAggBlendMode = comp_op_e;
-
- TAggTextAlignment = int;
-
- TAggDrawPathFlag = (
- AGG_FillOnly ,
- AGG_StrokeOnly ,
- AGG_FillAndStroke ,
- AGG_FillWithLineColor );
-
- TAggViewportOption = (
- AGG_Anisotropic ,
- AGG_XMinYMin ,
- AGG_XMidYMin ,
- AGG_XMaxYMin ,
- AGG_XMinYMid ,
- AGG_XMidYMid ,
- AGG_XMaxYMid ,
- AGG_XMinYMax ,
- AGG_XMidYMax ,
- AGG_XMaxYMax );
-
- TAggImageFilter = (
- AGG_NoFilter ,
- AGG_Bilinear ,
- AGG_Hanning ,
- AGG_Hermite ,
- AGG_Quadric ,
- AGG_Bicubic ,
- AGG_Catrom ,
- AGG_Spline16 ,
- AGG_Spline36 ,
- AGG_Blackman144 );
-
- TAggImageResample = (
- AGG_NoResample ,
- AGG_ResampleAlways ,
- AGG_ResampleOnZoomOut );
-
- TAggFontCacheType = (
- AGG_RasterFontCache ,
- AGG_VectorFontCache );
-
- PAggTransformations = ^TAggTransformations;
- TAggTransformations = record
- affineMatrix : array[0..5 ] of double;
-
- end;
-
- TAggRasterizerGamma = object(vertex_source )
- m_alpha : gamma_multiply;
- m_gamma : gamma_power;
-
- constructor Construct(alpha ,gamma : double );
-
- function func_operator_gamma(x : double ) : double; virtual;
-
- end;
-
- PAggImage = ^TAggImage;
- TAggImage = object
- renBuf : rendering_buffer;
-
- constructor Construct;
- destructor Destruct;
-
- function attach(bitmap : TBitmap; flip : boolean ) : boolean;
-
- function width : int;
- function height : int;
-
- end;
-
- TAgg2D = class
- private
- m_rbuf : rendering_buffer;
- m_pixf : TPixelFormat;
-
- m_pixFormat ,m_pixFormatComp ,m_pixFormatPre ,m_pixFormatCompPre : pixel_formats;
- m_renBase ,m_renBaseComp ,m_renBasePre ,m_renBaseCompPre : renderer_base;
-
- m_renSolid ,m_renSolidComp : renderer_scanline_aa_solid;
-
- m_allocator : span_allocator;
- m_clipBox : TAggRectD;
-
- m_blendMode ,m_imageBlendMode : TAggBlendMode;
-
- m_imageBlendColor : TAggColor;
-
- m_scanline : scanline_u8;
- m_rasterizer : rasterizer_scanline_aa;
-
- m_masterAlpha ,m_antiAliasGamma : double;
-
- m_fillColor ,m_lineColor : TAggColor;
-
- m_fillGradient ,m_lineGradient : pod_auto_array;
-
- m_lineCap : TAggLineCap;
- m_lineJoin : TAggLineJoin;
-
- m_fillGradientFlag ,m_lineGradientFlag : TAggGradient;
-
- m_fillGradientMatrix ,m_lineGradientMatrix : trans_affine;
-
- m_fillGradientD1 ,
- m_lineGradientD1 ,
- m_fillGradientD2 ,
- m_lineGradientD2 ,
- m_textAngle : double;
- m_textAlignX ,
- m_textAlignY : TAggTextAlignment;
- m_textHints : boolean;
- m_fontHeight ,
- m_fontAscent ,
- m_fontDescent : double;
- m_fontCacheType : TAggFontCacheType;
-
- m_imageFilter : TAggImageFilter;
- m_imageResample : TAggImageResample;
- m_imageFilterLut : image_filter_lut;
-
- m_fillGradientInterpolator ,
- m_lineGradientInterpolator : span_interpolator_linear;
-
- m_linearGradientFunction : gradient_x;
- m_radialGradientFunction : gradient_circle;
-
- m_lineWidth : double;
- m_evenOddFlag : boolean;
-
- m_path : path_storage;
- m_transform : trans_affine;
-
- m_convCurve : conv_curve;
- m_convStroke : conv_stroke;
-
- m_pathTransform ,m_strokeTransform : conv_transform;
-
- m_imageFlip : boolean;
-
- {$IFNDEF AGG2D_USE_FREETYPE }
- m_fontDC : HDC;
-
- {$ENDIF }
-
- m_fontEngine : TAggFontEngine;
- m_fontCacheManager : font_cache_manager;
-
- // Other Pascal-specific members
- m_gammaNone : gamma_none;
- m_gammaAgg2D : TAggRasterizerGamma;
-
- m_ifBilinear : image_filter_bilinear;
- m_ifHanning : image_filter_hanning;
- m_ifHermite : image_filter_hermite;
- m_ifQuadric : image_filter_quadric;
- m_ifBicubic : image_filter_bicubic;
- m_ifCatrom : image_filter_catrom;
- m_ifSpline16 : image_filter_spline16;
- m_ifSpline36 : image_filter_spline36;
- m_ifBlackman144 : image_filter_blackman144;
-
- public
- constructor Create;
- destructor Destroy; override;
-
- // Vector Graphics Engine Initialization
- function Attach(bitmap : TBitmap; flip_y : boolean = false ) : boolean;
-
- procedure ClearAll(c : TAggColor ); overload;
- procedure ClearAll(r ,g ,b : byte; a : byte = 255 ); overload;
-
- // Master Rendering Properties
- procedure BlendMode(m : TAggBlendMode ); overload;
- function BlendMode : TAggBlendMode; overload;
-
- procedure MasterAlpha(a : double ); overload;
- function MasterAlpha : double; overload;
-
- procedure AntiAliasGamma(g : double ); overload;
- function AntiAliasGamma : double; overload;
-
- procedure FillColor(c : TAggColor ); overload;
- procedure FillColor(r ,g ,b : byte; a : byte = 255 ); overload;
- procedure NoFill;
-
- procedure LineColor(c : TAggColor ); overload;
- procedure LineColor(r ,g ,b : byte; a : byte = 255 ); overload;
- procedure NoLine;
-
- function FillColor : TAggColor; overload;
- function LineColor : TAggColor; overload;
-
- procedure FillLinearGradient(x1 ,y1 ,x2 ,y2 : double; c1 ,c2 : TAggColor; profile : double = 1.0 );
- procedure LineLinearGradient(x1 ,y1 ,x2 ,y2 : double; c1 ,c2 : TAggColor; profile : double = 1.0 );
-
- procedure FillRadialGradient(x ,y ,r : double; c1 ,c2 : TAggColor; profile : double = 1.0 ); overload;
- procedure LineRadialGradient(x ,y ,r : double; c1 ,c2 : TAggColor; profile : double = 1.0 ); overload;
-
- procedure FillRadialGradient(x ,y ,r : double; c1 ,c2 ,c3 : TAggColor ); overload;
- procedure LineRadialGradient(x ,y ,r : double; c1 ,c2 ,c3 : TAggColor ); overload;
-
- procedure FillRadialGradient(x ,y ,r : double ); overload;
- procedure LineRadialGradient(x ,y ,r : double ); overload;
-
- procedure LineWidth(w : double ); overload;
- function LineWidth : double; overload;
-
- procedure LineCap(cap : TAggLineCap ); overload;
- function LineCap : TAggLineCap; overload;
-
- procedure LineJoin(join : TAggLineJoin ); overload;
- function LineJoin : TAggLineJoin; overload;
-
- procedure FillEvenOdd(evenOddFlag : boolean ); overload;
- function FillEvenOdd : boolean; overload;
-
- // Affine Transformations
- function Transformations : TAggTransformations; overload;
- procedure Transformations(tr : PAggTransformations ); overload;
- procedure ResetTransformations;
-
- procedure Affine(tr : PAggAffine ); overload;
- procedure Affine(tr : PAggTransformations ); overload;
-
- procedure Rotate (angle : double );
- procedure Scale (sx ,sy : double );
- procedure Skew (sx ,sy : double );
- procedure Translate(x ,y : double );
-
- procedure Parallelogram(x1 ,y1 ,x2 ,y2 : double; para : PDouble );
-
- procedure Viewport(
- worldX1 ,worldY1 ,worldX2 ,worldY2 ,
- screenX1 ,screenY1 ,screenX2 ,screenY2 : double;
- opt : TAggViewportOption = AGG_XMidYMid );
-
- // Coordinates Conversions
- procedure WorldToScreen(x ,y : PDouble ); overload;
- procedure ScreenToWorld(x ,y : PDouble ); overload;
- function WorldToScreen(scalar : double ) : double; overload;
- function ScreenToWorld(scalar : double ) : double; overload;
-
- procedure AlignPoint(x ,y : PDouble );
-
- // Clipping
- procedure ClipBox(x1 ,y1 ,x2 ,y2 : double ); overload;
- function ClipBox : TAggRectD; overload;
-
- procedure ClearClipBox(c : TAggColor ); overload;
- procedure ClearClipBox(r ,g ,b : byte; a : byte = 255 ); overload;
-
- function InBox(worldX ,worldY : double ) : boolean;
-
- // Basic Shapes
- procedure Line (x1 ,y1 ,x2 ,y2 : double );
- procedure Triangle (x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double );
- procedure Rectangle(x1 ,y1 ,x2 ,y2 : double );
-
- procedure RoundedRect(x1 ,y1 ,x2 ,y2 ,r : double ); overload;
- procedure RoundedRect(x1 ,y1 ,x2 ,y2 ,rx ,ry : double ); overload;
- procedure RoundedRect(
- x1 ,y1 ,x2 ,y2 ,
- rxBottom ,ryBottom ,
- rxTop ,ryTop : double ); overload;
-
- procedure Ellipse(cx ,cy ,rx ,ry : double );
-
- procedure Arc (cx ,cy ,rx ,ry ,start ,sweep : double );
- procedure Star(cx ,cy ,r1 ,r2 ,startAngle : double; numRays : integer );
-
- procedure Curve(x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double ); overload;
- procedure Curve(x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,x4 ,y4 : double ); overload;
-
- procedure Polygon (xy : PDouble; numPoints : integer );
- procedure Polyline(xy : PDouble; numPoints : integer );
-
- // Path Commands
- procedure ResetPath;
-
- procedure MoveTo (x ,y : double );
- procedure MoveRel(dx ,dy : double );
-
- procedure LineTo (x ,y : double );
- procedure LineRel(dx ,dy : double );
-
- procedure HorLineTo (x : double );
- procedure HorLineRel(dx : double );
-
- procedure VerLineTo (y : double );
- procedure VerLineRel(dy : double );
-
- procedure ArcTo(
- rx ,ry ,angle : double;
- largeArcFlag ,sweepFlag : boolean;
- x ,y : double );
-
- procedure ArcRel(
- rx ,ry ,angle : double;
- largeArcFlag ,sweepFlag : boolean;
- dx ,dy : double );
-
- procedure QuadricCurveTo (xCtrl ,yCtrl ,xTo ,yTo : double ); overload;
- procedure QuadricCurveRel(dxCtrl ,dyCtrl ,dxTo ,dyTo : double ); overload;
- procedure QuadricCurveTo (xTo ,yTo : double ); overload;
- procedure QuadricCurveRel(dxTo ,dyTo : double ); overload;
-
- procedure CubicCurveTo (xCtrl1 ,yCtrl1 ,xCtrl2 ,yCtrl2 ,xTo ,yTo : double ); overload;
- procedure CubicCurveRel(dxCtrl1 ,dyCtrl1 ,dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo : double ); overload;
- procedure CubicCurveTo (xCtrl2 ,yCtrl2 ,xTo ,yTo : double ); overload;
- procedure CubicCurveRel(dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo : double ); overload;
-
- procedure AddEllipse(cx ,cy ,rx ,ry : double; dir : TAggDirection );
- procedure ClosePolygon;
-
- procedure DrawPath(flag : TAggDrawPathFlag = AGG_FillAndStroke );
-
- // Text Rendering
- procedure FlipText(flip : boolean );
-
- procedure Font(
- fileName : AnsiString; height : double;
- bold : boolean = false;
- italic : boolean = false;
- cache : TAggFontCacheType = AGG_VectorFontCache;
- angle : double = 0.0 );
-
- function FontHeight : double;
-
- procedure TextAlignment(alignX ,alignY : TAggTextAlignment );
-
- function TextHints : boolean; overload;
- procedure TextHints(hints : boolean ); overload;
- function TextWidth(str : AnsiString ) : double;
-
- procedure Text(
- x ,y : double; str : AnsiString;
- roundOff : boolean = false;
- ddx : double = 0.0;
- ddy : double = 0.0 );
-
- // Image Rendering
- procedure ImageFilter(f : TAggImageFilter ); overload;
- function ImageFilter : TAggImageFilter; overload;
-
- procedure ImageResample(f : TAggImageResample ); overload;
- function ImageResample : TAggImageResample; overload;
-
- procedure ImageFlip(f : boolean );
-
- procedure TransformImage(
- bitmap : TBitmap;
- imgX1 ,imgY1 ,imgX2 ,imgY2 : integer;
- dstX1 ,dstY1 ,dstX2 ,dstY2 : double ); overload;
-
- procedure TransformImage(
- bitmap : TBitmap;
- dstX1 ,dstY1 ,dstX2 ,dstY2 : double ); overload;
-
- procedure TransformImage(
- bitmap : TBitmap;
- imgX1 ,imgY1 ,imgX2 ,imgY2 : integer;
- parallelo : PDouble ); overload;
-
- procedure TransformImage(bitmap : TBitmap; parallelo : PDouble ); overload;
-
- procedure TransformImagePath(
- bitmap : TBitmap;
- imgX1 ,imgY1 ,imgX2 ,imgY2 : integer;
- dstX1 ,dstY1 ,dstX2 ,dstY2 : double ); overload;
-
- procedure TransformImagePath(
- bitmap : TBitmap;
- dstX1 ,dstY1 ,dstX2 ,dstY2 : double ); overload;
-
- procedure TransformImagePath(
- bitmap : TBitmap;
- imgX1 ,imgY1 ,imgX2 ,imgY2 : integer;
- parallelo : PDouble ); overload;
-
- procedure TransformImagePath(bitmap : TBitmap; parallelo : PDouble ); overload;
-
- procedure CopyImage(
- bitmap : TBitmap;
- imgX1 ,imgY1 ,imgX2 ,imgY2 : integer;
- dstX ,dstY : double ); overload;
-
- procedure CopyImage(bitmap : TBitmap; dstX ,dstY : double ); overload;
-
- private
- procedure render(fillColor_ : boolean ); overload;
- procedure render(ras : PAggFontRasterizer; sl : PAggFontScanline ); overload;
-
- procedure addLine(x1 ,y1 ,x2 ,y2 : double );
- procedure updateRasterizerGamma;
- procedure renderImage(
- img : PAggImage;
- x1 ,y1 ,x2 ,y2 : integer;
- parl : PDouble );
-
- end;
-
-{ GLOBAL PROCEDURES }
-// Standalone API
- function Deg2Rad(v : double ) : double;
- function Rad2Deg(v : double ) : double;
-
- function Agg2DUsesFreeType : boolean;
-
- function BitmapAlphaTransparency(bitmap : TBitmap; alpha : byte ) : boolean;
-
-
-IMPLEMENTATION
-{ LOCAL VARIABLES & CONSTANTS }
-var
- g_approxScale : double = 2.0;
-
-type
- PAggSpanConvImageBlend = ^TAggSpanConvImageBlend;
- TAggSpanConvImageBlend = object(span_convertor )
- private
- m_mode : TAggBlendMode;
- m_color : TAggColor;
- m_pixel : pixel_formats_ptr; // m_pixFormatCompPre
-
- public
- constructor Construct(m : TAggBlendMode; c : TAggColor; p : pixel_formats_ptr );
-
- procedure convert(span : aggclr_ptr; x ,y : int; len : unsigned ); virtual;
-
- end;
-
-{ OPERATOR_IS_EQUAL }
-function operator_is_equal(c1 ,c2 : PAggColor ) : boolean;
-begin
- result:=
- (c1.r = c2.r ) and
- (c1.g = c2.g ) and
- (c1.b = c2.b ) and
- (c1.a = c2.a );
-
-end;
-
-{ OPERATOR_IS_NOT_EQUAL }
-function operator_is_not_equal(c1 ,c2 : PAggColor ) : boolean;
-begin
- result:=not operator_is_equal(c1 ,c2 );
-
-end;
-
-{ AGG2DRENDERER_RENDER }
-procedure Agg2DRenderer_render(
- gr : TAgg2D;
- renBase : renderer_base_ptr;
- renSolid : renderer_scanline_aa_solid_ptr;
- fillColor_ : boolean ); overload;
-var
- span : span_gradient;
- ren : renderer_scanline_aa;
- clr : aggclr;
-
-begin
- if (fillColor_ and
- (gr.m_fillGradientFlag = AGG_Linear ) ) or
- (not fillColor_ and
- (gr.m_lineGradientFlag = AGG_Linear ) ) then
- if fillColor_ then
- begin
- span.Construct(
- @gr.m_allocator ,
- @gr.m_fillGradientInterpolator ,
- @gr.m_linearGradientFunction ,
- @gr.m_fillGradient ,
- gr.m_fillGradientD1 ,
- gr.m_fillGradientD2 );
-
- ren.Construct (renBase ,@span );
- render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ren );
-
- end
- else
- begin
- span.Construct(
- @gr.m_allocator ,
- @gr.m_lineGradientInterpolator ,
- @gr.m_linearGradientFunction ,
- @gr.m_lineGradient ,
- gr.m_lineGradientD1 ,
- gr.m_lineGradientD2 );
-
- ren.Construct (renBase ,@span );
- render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ren );
-
- end
- else
- if (fillColor_ and
- (gr.m_fillGradientFlag = AGG_Radial ) ) or
- (not fillColor_ and
- (gr.m_lineGradientFlag = AGG_Radial ) ) then
- if fillColor_ then
- begin
- span.Construct(
- @gr.m_allocator ,
- @gr.m_fillGradientInterpolator ,
- @gr.m_radialGradientFunction ,
- @gr.m_fillGradient ,
- gr.m_fillGradientD1 ,
- gr.m_fillGradientD2 );
-
- ren.Construct (renBase ,@span );
- render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ren );
-
- end
- else
- begin
- span.Construct(
- @gr.m_allocator ,
- @gr.m_lineGradientInterpolator ,
- @gr.m_radialGradientFunction ,
- @gr.m_lineGradient ,
- gr.m_lineGradientD1 ,
- gr.m_lineGradientD2 );
-
- ren.Construct (renBase ,@span );
- render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ren );
-
- end
- else
- begin
- if fillColor_ then
- clr.Construct(gr.m_fillColor )
- else
- clr.Construct(gr.m_lineColor );
-
- renSolid.color_ (@clr );
- render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,renSolid );
-
- end;
-
-end;
-
-{ AGG2DRENDERER_RENDER }
-procedure Agg2DRenderer_render(
- gr : TAgg2D;
- renBase : renderer_base_ptr;
- renSolid : renderer_scanline_aa_solid_ptr;
- ras : gray8_adaptor_type_ptr;
- sl : gray8_scanline_type_ptr ); overload;
-var
- span : span_gradient;
- ren : renderer_scanline_aa;
- clr : aggclr;
-
-begin
- if gr.m_fillGradientFlag = AGG_Linear then
- begin
- span.Construct(
- @gr.m_allocator ,
- @gr.m_fillGradientInterpolator ,
- @gr.m_linearGradientFunction ,
- @gr.m_fillGradient ,
- gr.m_fillGradientD1 ,
- gr.m_fillGradientD2 );
-
- ren.Construct (renBase ,@span );
- render_scanlines(ras ,sl ,@ren );
-
- end
- else
- if gr.m_fillGradientFlag = AGG_Radial then
- begin
- span.Construct(
- @gr.m_allocator ,
- @gr.m_fillGradientInterpolator ,
- @gr.m_radialGradientFunction ,
- @gr.m_fillGradient ,
- gr.m_fillGradientD1 ,
- gr.m_fillGradientD2 );
-
- ren.Construct (renBase ,@span );
- render_scanlines(ras ,sl ,@ren );
-
- end
- else
- begin
- clr.Construct (gr.m_fillColor );
- renSolid.color_ (@clr );
- render_scanlines(ras ,sl ,renSolid );
-
- end;
-
-end;
-
-{ AGG2DRENDERER_RENDERIMAGE }
-procedure Agg2DRenderer_renderImage(
- gr : TAgg2D;
- img : PAggImage;
- renBase : renderer_base_ptr;
- interpolator : span_interpolator_linear_ptr );
-var
- blend : TAggSpanConvImageBlend;
-
- si : span_image_filter_rgba;
- sg : span_image_filter_rgba_nn;
- sb : span_image_filter_rgba_bilinear;
- s2 : span_image_filter_rgba_2x2;
- sa : span_image_resample_rgba_affine;
- sc : span_converter;
- ri : renderer_scanline_aa;
-
- clr : aggclr;
-
- resample : boolean;
-
- sx ,sy : double;
-
-begin
- case gr.m_pixf of
- pf32bit :
- blend.Construct(gr.m_imageBlendMode ,gr.m_imageBlendColor ,@gr.m_pixFormatCompPre );
-
- else
- blend.Construct(gr.m_imageBlendMode ,gr.m_imageBlendColor ,NIL );
-
- end;
-
- if gr.m_imageFilter = AGG_NoFilter then
- begin
- clr.ConstrInt(0 ,0 ,0 ,0 );
- sg.Construct (@gr.m_allocator ,@img.renBuf ,@clr ,interpolator ,rgba_order );
- sc.Construct (@sg ,@blend );
- ri.Construct (renBase ,@sc );
-
- render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ri );
-
- end
- else
- begin
- resample:=gr.m_imageResample = AGG_ResampleAlways;
-
- if gr.m_imageResample = AGG_ResampleOnZoomOut then
- begin
- interpolator._transformer.scaling_abs(@sx ,@sy );
-
- if (sx > 1.125 ) or
- (sy > 1.125 ) then
- resample:=true;
-
- end;
-
- if resample then
- begin
- clr.ConstrInt(0 ,0 ,0 ,0 );
- sa.Construct(
- @gr.m_allocator ,
- @img.renBuf ,
- @clr ,
- interpolator ,
- @gr.m_imageFilterLut ,
- rgba_order );
-
- sc.Construct(@sa ,@blend );
- ri.Construct(renBase ,@sc );
-
- render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ri );
-
- end
- else
- if gr.m_imageFilter = AGG_Bilinear then
- begin
- clr.ConstrInt(0 ,0 ,0 ,0 );
- sb.Construct(
- @gr.m_allocator ,
- @img.renBuf ,
- @clr ,
- interpolator ,
- rgba_order );
-
- sc.Construct(@sb ,@blend );
- ri.Construct(renBase ,@sc );
-
- render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ri );
-
- end
- else
- if gr.m_imageFilterLut.diameter = 2 then
- begin
- clr.ConstrInt(0 ,0 ,0 ,0 );
- s2.Construct(
- @gr.m_allocator ,
- @img.renBuf ,
- @clr ,
- interpolator,
- @gr.m_imageFilterLut ,
- rgba_order );
-
- sc.Construct(@s2 ,@blend );
- ri.Construct(renBase ,@sc );
-
- render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ri );
-
- end
- else
- begin
- clr.ConstrInt(0 ,0 ,0 ,0 );
- si.Construct(
- @gr.m_allocator ,
- @img.renBuf ,
- @clr ,
- interpolator ,
- @gr.m_imageFilterLut ,
- rgba_order );
-
- sc.Construct(@si ,@blend );
- ri.Construct(renBase ,@sc );
-
- render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ri );
-
- end;
-
- end;
-
-end;
-
-{ AGG2DUSESFREETYPE }
-function Agg2DUsesFreeType : boolean;
-begin
-{$IFDEF AGG2D_USE_FREETYPE }
- result:=true;
-
-{$ELSE }
- result:=false;
-
-{$ENDIF }
-
-end;
-
-{ CONSTRUCT }
-constructor TAggSpanConvImageBlend.Construct(m : TAggBlendMode; c : TAggColor; p : pixel_formats_ptr );
-begin
- m_mode :=m;
- m_color:=c;
- m_pixel:=p;
-
-end;
-
-{ CONVERT }
-procedure TAggSpanConvImageBlend.convert(span : aggclr_ptr; x ,y : int; len : unsigned );
-var
- l2 ,a : unsigned;
-
- s2 : PAggColor;
-
-begin
- if (m_mode <> AGG_BlendDst ) and
- (m_pixel <> NIL ) then
- begin{!}
- l2:=len;
- s2:=PAggColor(span );
-
- repeat
- comp_op_adaptor_clip_to_dst_rgba_pre(
- m_pixel ,
- unsigned(m_mode ) ,
- int8u_ptr(s2 ) ,
- m_color.r ,
- m_color.g ,
- m_color.b ,
- base_mask ,
- cover_full );
-
- inc(ptrcomp(s2 ) ,sizeof(aggclr ) );
- dec(l2 );
-
- until l2 = 0;
-
- end;
-
- if m_color.a < base_mask then
- begin
- l2:=len;
- s2:=PAggColor(span );
- a :=m_color.a;
-
- repeat
- s2.r:=(s2.r * a ) shr base_shift;
- s2.g:=(s2.g * a ) shr base_shift;
- s2.b:=(s2.b * a ) shr base_shift;
- s2.a:=(s2.a * a ) shr base_shift;
-
- inc(ptrcomp(s2 ) ,sizeof(aggclr ) );
- dec(l2 );
-
- until l2 = 0;
-
- end;
-
-end;
-
-{ DEG2RAD }
-function deg2Rad(v : double ) : double;
-begin
- result:=v * agg_basics.pi / 180.0;
-
-end;
-
-{ RAD2DEG }
-function rad2Deg(v : double ) : double;
-begin
- result:=v * 180.0 / agg_basics.pi;
-
-end;
-
-{ UNIT IMPLEMENTATION }
-{ CONSTRUCT }
-constructor TAggImage.Construct;
-begin
- renBuf.Construct;
-
-end;
-
-{ DESTRUCT }
-destructor TAggImage.Destruct;
-begin
- renBuf.Destruct;
-
-end;
-
-{ ATTACH }
-function TAggImage.attach(bitmap : TBitmap; flip : boolean ) : boolean;
-var
- buffer : pointer;
- stride : integer;
-
-begin
- result:=false;
-
- if Assigned(bitmap ) and
- not bitmap.Empty then
- case bitmap.PixelFormat of
- pf32bit :
- begin
- { Rendering Buffer }
- stride:=integer(bitmap.ScanLine[1 ] ) - integer(bitmap.ScanLine[0 ] );
-
- if stride < 0 then
- buffer:=bitmap.ScanLine[bitmap.Height - 1 ]
- else
- buffer:=bitmap.ScanLine[0 ];
-
- if flip then
- stride:=stride * -1;
-
- renBuf.attach(
- buffer ,
- bitmap.Width ,
- bitmap.Height ,
- stride );
-
- { OK }
- result:=true;
-
- end;
-
- end;
-
-end;
-
-{ WIDTH }
-function TAggImage.width : int;
-begin
- result:=renBuf._width;
-
-end;
-
-{ HEIGHT }
-function TAggImage.height : int;
-begin
- result:=renBuf._height;
-
-end;
-
-{ CONSTRUCT }
-constructor TAggRasterizerGamma.Construct(alpha ,gamma : double );
-begin
- m_alpha.Construct(alpha );
- m_gamma.Construct(gamma );
-
-end;
-
-{ FUNC_OPERATOR_GAMMA }
-function TAggRasterizerGamma.func_operator_gamma(x : double ) : double;
-begin
- result:=m_alpha.func_operator_gamma(m_gamma.func_operator_gamma(x ) );
-
-end;
-
-{ CREATE }
-constructor TAgg2D.Create;
-begin
- m_rbuf.Construct;
-
- m_pixf:=pf32bit;
-
- pixfmt_rgba32 (m_pixFormat ,@m_rbuf );
- pixfmt_custom_blend_rgba(m_pixFormatComp ,@m_rbuf ,@comp_op_adaptor_rgba ,rgba_order );
- pixfmt_rgba32 (m_pixFormatPre ,@m_rbuf );
- pixfmt_custom_blend_rgba(m_pixFormatCompPre ,@m_rbuf ,@comp_op_adaptor_rgba ,rgba_order );
-
- m_renBase.Construct (@m_pixFormat );
- m_renBaseComp.Construct (@m_pixFormatComp );
- m_renBasePre.Construct (@m_pixFormatPre );
- m_renBaseCompPre.Construct(@m_pixFormatCompPre );
-
- m_renSolid.Construct (@m_renBase );
- m_renSolidComp.Construct(@m_renBaseComp );
-
- m_allocator.Construct;
- m_clipBox.Construct(0 ,0 ,0 ,0 );
-
- m_blendMode :=AGG_BlendAlpha;
- m_imageBlendMode:=AGG_BlendDst;
-
- m_imageBlendColor.Construct(0 ,0 ,0 );
-
- m_scanline.Construct;
- m_rasterizer.Construct;
-
- m_masterAlpha :=1.0;
- m_antiAliasGamma:=1.0;
-
- m_fillColor.Construct(255 ,255 ,255 );
- m_lineColor.Construct(0 ,0 ,0 );
-
- m_fillGradient.Construct(256 ,sizeof(aggclr ) );
- m_lineGradient.Construct(256 ,sizeof(aggclr ) );
-
- m_lineCap :=AGG_CapRound;
- m_lineJoin:=AGG_JoinRound;
-
- m_fillGradientFlag:=AGG_Solid;
- m_lineGradientFlag:=AGG_Solid;
-
- m_fillGradientMatrix.Construct;
- m_lineGradientMatrix.Construct;
-
- m_fillGradientD1:=0.0;
- m_lineGradientD1:=0.0;
- m_fillGradientD2:=100.0;
- m_lineGradientD2:=100.0;
-
- m_textAngle :=0.0;
- m_textAlignX :=AGG_AlignLeft;
- m_textAlignY :=AGG_AlignBottom;
- m_textHints :=true;
- m_fontHeight :=0.0;
- m_fontAscent :=0.0;
- m_fontDescent:=0.0;
-
- m_fontCacheType:=AGG_RasterFontCache;
- m_imageFilter :=AGG_Bilinear;
- m_imageResample:=AGG_NoResample;
-
- m_gammaNone.Construct;
-
- m_ifBilinear.Construct;
- m_ifHanning.Construct;
- m_ifHermite.Construct;
- m_ifQuadric.Construct;
- m_ifBicubic.Construct;
- m_ifCatrom.Construct;
- m_ifSpline16.Construct;
- m_ifSpline36.Construct;
- m_ifBlackman144.Construct;
-
- m_imageFilterLut.Construct(@m_ifBilinear ,true );
-
- m_linearGradientFunction.Construct;
- m_radialGradientFunction.Construct;
-
- m_fillGradientInterpolator.Construct(@m_fillGradientMatrix );
- m_lineGradientInterpolator.Construct(@m_lineGradientMatrix );
-
- m_lineWidth :=1;
- m_evenOddFlag:=false;
-
- m_imageFlip:=false;
-
- m_path.Construct;
- m_transform.Construct;
-
- m_convCurve.Construct (@m_path );
- m_convStroke.Construct(@m_convCurve );
-
- m_pathTransform.Construct (@m_convCurve ,@m_transform );
- m_strokeTransform.Construct(@m_convStroke ,@m_transform );
-
-{$IFDEF AGG2D_USE_FREETYPE }
- m_fontEngine.Construct;
-
-{$ELSE }
- m_fontDC:=GetDC(0 );
-
- m_fontEngine.Construct(m_fontDC );
-
-{$ENDIF }
-
- m_fontCacheManager.Construct(@m_fontEngine );
-
- LineCap (m_lineCap );
- LineJoin(m_lineJoin );
-
-end;
-
-{ DESTROY }
-destructor TAgg2D.Destroy;
-begin
- m_rbuf.Destruct;
-
- m_allocator.Destruct;
-
- m_scanline.Destruct;
- m_rasterizer.Destruct;
-
- m_fillGradient.Destruct;
- m_lineGradient.Destruct;
-
- m_imageFilterLut.Destruct;
- m_path.Destruct;
-
- m_convCurve.Destruct;
- m_convStroke.Destruct;
-
- m_fontEngine.Destruct;
- m_fontCacheManager.Destruct;
-
-{$IFNDEF AGG2D_USE_FREETYPE }
- ReleaseDC(0 ,m_fontDC );
-
-{$ENDIF }
-
-end;
-
-{ ATTACH }
-function TAgg2D.Attach(bitmap : TBitmap; flip_y : boolean = false ) : boolean;
-var
- buffer : pointer;
- stride : integer;
-
-begin
- result:=false;
-
- if Assigned(bitmap ) and
- not bitmap.Empty then
- case bitmap.PixelFormat of
- pf24bit ,pf32bit :
- begin
- { Rendering Buffer }
- stride:=integer(bitmap.ScanLine[1 ] ) - integer(bitmap.ScanLine[0 ] );
-
- if stride < 0 then
- buffer:=bitmap.ScanLine[bitmap.Height - 1 ]
- else
- buffer:=bitmap.ScanLine[0 ];
-
- if flip_y then
- stride:=stride * -1;
-
- m_rbuf.attach(
- buffer ,
- bitmap.Width ,
- bitmap.Height ,
- stride );
-
- { Pixel Format }
- m_pixf:=bitmap.PixelFormat;
-
- case m_pixf of
- pf24bit :
- begin
- pixfmt_rgb24(m_pixFormat ,@m_rbuf );
- pixfmt_rgb24(m_pixFormatPre ,@m_rbuf );
-
- end;
-
- pf32bit :
- begin
- pixfmt_rgba32 (m_pixFormat ,@m_rbuf );
- pixfmt_custom_blend_rgba(m_pixFormatComp ,@m_rbuf ,@comp_op_adaptor_rgba ,rgba_order );
- pixfmt_rgba32 (m_pixFormatPre ,@m_rbuf );
- pixfmt_custom_blend_rgba(m_pixFormatCompPre ,@m_rbuf ,@comp_op_adaptor_rgba ,rgba_order );
-
- end;
-
- end;
-
- { Reset state }
- m_renBase.reset_clipping (true );
- m_renBaseComp.reset_clipping (true );
- m_renBasePre.reset_clipping (true );
- m_renBaseCompPre.reset_clipping(true );
-
- ResetTransformations;
-
- LineWidth(1.0 );
- LineColor(0 ,0 ,0 );
- FillColor(255 ,255 ,255 );
-
- TextAlignment(AGG_AlignLeft ,AGG_AlignBottom );
-
- ClipBox (0 ,0 ,bitmap.Width ,bitmap.Height );
- LineCap (AGG_CapRound );
- LineJoin(AGG_JoinRound );
- FlipText(false );
-
- ImageFilter (AGG_Bilinear );
- ImageResample(AGG_NoResample );
- ImageFlip (false );
-
- m_masterAlpha :=1.0;
- m_antiAliasGamma:=1.0;
-
- m_rasterizer.gamma(@m_gammaNone );
-
- m_blendMode:=AGG_BlendAlpha;
-
- FillEvenOdd(false );
- BlendMode (AGG_BlendAlpha );
-
- FlipText(false );
- ResetPath;
-
- ImageFilter (AGG_Bilinear );
- ImageResample(AGG_NoResample );
-
- { OK }
- result:=true;
-
- end;
-
- end;
-
-end;
-
-{ CLIPBOX }
-procedure TAgg2D.ClipBox(x1 ,y1 ,x2 ,y2 : double );
-var
- rx1 ,ry1 ,rx2 ,ry2 : int;
-
-begin
- m_clipBox.Construct(x1 ,y1 ,x2 ,y2 );
-
- rx1:=Trunc(x1 );
- ry1:=Trunc(y1 );
- rx2:=Trunc(x2 );
- ry2:=Trunc(y2 );
-
- m_renBase.clip_box_ (rx1 ,ry1 ,rx2 ,ry2 );
- m_renBaseComp.clip_box_ (rx1 ,ry1 ,rx2 ,ry2 );
- m_renBasePre.clip_box_ (rx1 ,ry1 ,rx2 ,ry2 );
- m_renBaseCompPre.clip_box_(rx1 ,ry1 ,rx2 ,ry2 );
-
- m_rasterizer.clip_box(x1 ,y1 ,x2 ,y2 );
-
-end;
-
-{ CLIPBOX }
-function TAgg2D.ClipBox : TAggRectD;
-begin
- result:=m_clipBox;
-
-end;
-
-{ CLEARALL }
-procedure TAgg2D.ClearAll(c : TAggColor );
-var
- clr : aggclr;
-
-begin
- clr.Construct (c );
- m_renBase.clear(@clr );
-
-end;
-
-{ CLEARALL }
-procedure TAgg2D.ClearAll(r ,g ,b : byte; a : byte = 255 );
-var
- clr : TAggColor;
-
-begin
- clr.Construct(r ,g ,b ,a );
- ClearAll (clr );
-
-end;
-
-{ CLEARCLIPBOX }
-procedure TAgg2D.ClearClipBox(c : TAggColor );
-var
- clr : aggclr;
-
-begin
- clr.Construct(c );
-
- m_renBase.copy_bar(0 ,0 ,m_renBase.width ,m_renBase.height ,@clr );
-
-end;
-
-{ CLEARCLIPBOX }
-procedure TAgg2D.ClearClipBox(r ,g ,b : byte; a : byte = 255 );
-var
- clr : TAggColor;
-
-begin
- clr.Construct(r ,g ,b ,a );
- ClearClipBox (clr );
-
-end;
-
-{ WORLDTOSCREEN }
-procedure TAgg2D.WorldToScreen(x ,y : PDouble );
-begin
- m_transform.transform(@m_transform ,double_ptr(x ) ,double_ptr(y ) );
-
-end;
-
-{ SCREENTOWORLD }
-procedure TAgg2D.ScreenToWorld(x ,y : PDouble );
-begin
- m_transform.inverse_transform(@m_transform ,double_ptr(x ) ,double_ptr(y ) );
-
-end;
-
-{ WORLDTOSCREEN }
-function TAgg2D.WorldToScreen(scalar : double ) : double;
-var
- x1 ,y1 ,x2 ,y2 : double;
-
-begin
- x1:=0;
- y1:=0;
- x2:=scalar;
- y2:=scalar;
-
- WorldToScreen(@x1 ,@y1 );
- WorldToScreen(@x2 ,@y2 );
-
- result:=Sqrt((x2 - x1 ) * (x2 - x1 ) + (y2 - y1 ) * (y2 - y1 ) ) * 0.7071068;
-
-end;
-
-{ SCREENTOWORLD }
-function TAgg2D.ScreenToWorld(scalar : double ) : double;
-var
- x1 ,y1 ,x2 ,y2 : double;
-
-begin
- x1:=0;
- y1:=0;
- x2:=scalar;
- y2:=scalar;
-
- ScreenToWorld(@x1 ,@y1 );
- ScreenToWorld(@x2 ,@y2 );
-
- result:=Sqrt((x2 - x1 ) * (x2 - x1 ) + (y2 - y1 ) * (y2 - y1 ) ) * 0.7071068;
-
-end;
-
-{ ALIGNPOINT }
-procedure TAgg2D.AlignPoint(x ,y : PDouble );
-begin
- WorldToScreen(x ,y );
-
- x^:=Floor(x^ ) + 0.5;
- y^:=Floor(y^ ) + 0.5;
-
- ScreenToWorld(x ,y );
-
-end;
-
-{ INBOX }
-function TAgg2D.InBox(worldX ,worldY : double ) : boolean;
-begin
- WorldToScreen(@worldX ,@worldY );
-
- result:=m_renBase.inbox(Trunc(worldX ) ,Trunc(worldY ) );
-
-end;
-
-{ BLENDMODE }
-procedure TAgg2D.BlendMode(m : TAggBlendMode );
-begin
- m_blendMode:=m;
-
- m_pixFormatComp.comp_op_ (unsigned(m ) );
- m_pixFormatCompPre.comp_op_(unsigned(m ) );
-
-end;
-
-{ BLENDMODE }
-function TAgg2D.BlendMode : TAggBlendMode;
-begin
- result:=m_blendMode;
-
-end;
-
-{ MASTERALPHA }
-procedure TAgg2D.MasterAlpha(a : double );
-begin
- m_masterAlpha:=a;
-
- UpdateRasterizerGamma;
-
-end;
-
-{ MASTERALPHA }
-function TAgg2D.MasterAlpha : double;
-begin
- result:=m_masterAlpha;
-
-end;
-
-{ ANTIALIASGAMMA }
-procedure TAgg2D.AntiAliasGamma(g : double );
-begin
- m_antiAliasGamma:=g;
-
- UpdateRasterizerGamma;
-
-end;
-
-{ ANTIALIASGAMMA }
-function TAgg2D.AntiAliasGamma : double;
-begin
- result:=m_antiAliasGamma;
-
-end;
-
-{ FILLCOLOR }
-procedure TAgg2D.FillColor(c : TAggColor );
-begin
- m_fillColor :=c;
- m_fillGradientFlag:=AGG_Solid;
-
-end;
-
-{ FILLCOLOR }
-procedure TAgg2D.FillColor(r ,g ,b : byte; a : byte = 255 );
-var
- clr : TAggColor;
-
-begin
- clr.Construct(r ,g ,b ,a );
- FillColor (clr );
-
-end;
-
-{ NOFILL }
-procedure TAgg2D.NoFill;
-var
- clr : TAggColor;
-
-begin
- clr.Construct(0 ,0 ,0 ,0 );
- FillColor (clr );
-
-end;
-
-{ LINECOLOR }
-procedure TAgg2D.LineColor(c : TAggColor );
-begin
- m_lineColor :=c;
- m_lineGradientFlag:=AGG_Solid;
-
-end;
-
-{ LINECOLOR }
-procedure TAgg2D.LineColor(r ,g ,b : byte; a : byte = 255 );
-var
- clr : TAggColor;
-
-begin
- clr.Construct(r ,g ,b ,a );
- LineColor (clr );
-
-end;
-
-{ NOLINE }
-procedure TAgg2D.NoLine;
-var
- clr : TAggColor;
-
-begin
- clr.Construct(0 ,0 ,0 ,0 );
- LineColor (clr );
-
-end;
-
-{ FILLCOLOR }
-function TAgg2D.FillColor : TAggColor;
-begin
- result:=m_fillColor;
-
-end;
-
-{ LINECOLOR }
-function TAgg2D.LineColor : TAggColor;
-begin
- result:=m_lineColor;
-
-end;
-
-{ FILLLINEARGRADIENT }
-procedure TAgg2D.FillLinearGradient(x1 ,y1 ,x2 ,y2 : double; c1 ,c2 : TAggColor; profile : double = 1.0 );
-var
- i ,startGradient ,endGradient : int;
-
- k ,angle : double;
-
- c : TAggColor;
-
- clr : aggclr;
- tar : trans_affine_rotation;
- tat : trans_affine_translation;
-
-begin
- startGradient:=128 - Trunc(profile * 127.0 );
- endGradient :=128 + Trunc(profile * 127.0 );
-
- if endGradient <= startGradient then
- endGradient:=startGradient + 1;
-
- k:=1.0 / (endGradient - startGradient );
- i:=0;
-
- while i < startGradient do
- begin
- clr.Construct(c1 );
-
- move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
- inc (i );
-
- end;
-
- while i < endGradient do
- begin
- c:=c1.gradient(c2 ,(i - startGradient ) * k );
-
- clr.Construct(c );
-
- move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
- inc (i );
-
- end;
-
- while i < 256 do
- begin
- clr.Construct(c2 );
-
- move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
- inc (i );
-
- end;
-
- angle:=ArcTan2(y2 - y1 ,x2 - x1 );
-
- m_fillGradientMatrix.reset;
-
- tar.Construct(angle );
-
- m_fillGradientMatrix.multiply(@tar );
-
- tat.Construct(x1 ,y1 );
-
- m_fillGradientMatrix.multiply(@tat );
- m_fillGradientMatrix.multiply(@m_transform );
- m_fillGradientMatrix.invert;
-
- m_fillGradientD1 :=0.0;
- m_fillGradientD2 :=Sqrt((x2 - x1 ) * (x2 - x1 ) + (y2 - y1 ) * (y2 - y1 ) );
- m_fillGradientFlag:=AGG_Linear;
-
- m_fillColor.Construct(0 ,0 ,0 ); // Set some real color
-
-end;
-
-{ LINELINEARGRADIENT }
-procedure TAgg2D.LineLinearGradient(x1 ,y1 ,x2 ,y2 : double; c1 ,c2 : TAggColor; profile : double = 1.0 );
-var
- i ,startGradient ,endGradient : int;
-
- k ,angle : double;
-
- c : TAggColor;
-
- clr : aggclr;
- tar : trans_affine_rotation;
- tat : trans_affine_translation;
-
-begin
- startGradient:=128 - Trunc(profile * 128.0 );
- endGradient :=128 + Trunc(profile * 128.0 );
-
- if endGradient <= startGradient then
- endGradient:=startGradient + 1;
-
- k:=1.0 / (endGradient - startGradient );
- i:=0;
-
- while i < startGradient do
- begin
- clr.Construct(c1 );
-
- move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
- inc (i );
-
- end;
-
- while i < endGradient do
- begin
- c:=c1.gradient(c2 ,(i - startGradient) * k );
-
- clr.Construct(c );
-
- move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
- inc (i );
-
- end;
-
- while i < 256 do
- begin
- clr.Construct(c2 );
-
- move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
- inc (i );
-
- end;
-
- angle:=ArcTan2(y2 - y1 ,x2 - x1 );
-
- m_lineGradientMatrix.reset;
-
- tar.Construct(angle );
-
- m_lineGradientMatrix.multiply(@tar );
-
- tat.Construct(x1 ,y1 );
-
- m_lineGradientMatrix.multiply(@tat );
- m_lineGradientMatrix.multiply(@m_transform );
- m_lineGradientMatrix.invert;
-
- m_lineGradientD1 :=0.0;
- m_lineGradientD2 :=Sqrt((x2 - x1 ) * (x2 - x1 ) + (y2 - y1 ) * (y2 - y1 ) );
- m_lineGradientFlag:=AGG_Linear;
-
- m_lineColor.Construct(0 ,0 ,0 ); // Set some real color
-
-end;
-
-{ FILLRADIALGRADIENT }
-procedure TAgg2D.FillRadialGradient(x ,y ,r : double; c1 ,c2 : TAggColor; profile : double = 1.0 );
-var
- i ,startGradient ,endGradient : int;
-
- k : double;
- c : TAggColor;
-
- clr : aggclr;
- tat : trans_affine_translation;
-
-begin
- startGradient:=128 - Trunc(profile * 127.0 );
- endGradient :=128 + Trunc(profile * 127.0 );
-
- if endGradient <= startGradient then
- endGradient:=startGradient + 1;
-
- k:=1.0 / (endGradient - startGradient );
- i:=0;
-
- while i < startGradient do
- begin
- clr.Construct(c1 );
-
- move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
- inc (i );
-
- end;
-
- while i < endGradient do
- begin
- c:=c1.gradient(c2 ,(i - startGradient ) * k );
-
- clr.Construct(c );
-
- move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
- inc (i );
-
- end;
-
- while i < 256 do
- begin
- clr.Construct(c2 );
-
- move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
- inc (i );
-
- end;
-
- m_fillGradientD2:=worldToScreen(r );
-
- WorldToScreen(@x ,@y );
-
- m_fillGradientMatrix.reset;
-
- tat.Construct(x ,y );
-
- m_fillGradientMatrix.multiply(@tat );
- m_fillGradientMatrix.invert;
-
- m_fillGradientD1 :=0;
- m_fillGradientFlag:=AGG_Radial;
-
- m_fillColor.Construct(0 ,0 ,0 ); // Set some real color
-
-end;
-
-{ LINERADIALGRADIENT }
-procedure TAgg2D.LineRadialGradient(x ,y ,r : double; c1 ,c2 : TAggColor; profile : double = 1.0 );
-var
- i ,startGradient ,endGradient : int;
-
- k : double;
- c : TAggColor;
-
- clr : aggclr;
- tat : trans_affine_translation;
-
-begin
- startGradient:=128 - Trunc(profile * 128.0 );
- endGradient :=128 + Trunc(profile * 128.0 );
-
- if endGradient <= startGradient then
- endGradient:=startGradient + 1;
-
- k:=1.0 / (endGradient - startGradient );
- i:=0;
-
- while i < startGradient do
- begin
- clr.Construct(c1 );
-
- move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
- inc (i );
-
- end;
-
- while i < endGradient do
- begin
- c:=c1.gradient(c2 ,(i - startGradient ) * k );
-
- clr.Construct(c );
-
- move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
- inc (i );
-
- end;
-
- while i < 256 do
- begin
- clr.Construct(c2 );
-
- move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
- inc (i );
-
- end;
-
- m_lineGradientD2:=worldToScreen(r );
-
- WorldToScreen(@x ,@y );
-
- m_lineGradientMatrix.reset;
-
- tat.Construct(x ,y );
-
- m_lineGradientMatrix.multiply(@tat );
- m_lineGradientMatrix.invert;
-
- m_lineGradientD1 :=0;
- m_lineGradientFlag:=AGG_Radial;
-
- m_lineColor.Construct(0 ,0 ,0 ); // Set some real color
-
-end;
-
-{ FILLRADIALGRADIENT }
-procedure TAgg2D.FillRadialGradient(x ,y ,r : double; c1 ,c2 ,c3 : TAggColor );
-var
- i : int;
- c : TAggColor;
-
- clr : aggclr;
- tat : trans_affine_translation;
-
-begin
- i:=0;
-
- while i < 128 do
- begin
- c:=c1.gradient(c2 ,i / 127.0 );
-
- clr.Construct(c );
-
- move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
- inc (i );
-
- end;
-
- while i < 256 do
- begin
- c:=c2.gradient(c3 ,(i - 128 ) / 127.0 );
-
- clr.Construct(c );
-
- move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) );
- inc (i );
-
- end;
-
- m_fillGradientD2:=worldToScreen(r );
-
- WorldToScreen(@x ,@y );
-
- m_fillGradientMatrix.reset;
-
- tat.Construct(x ,y );
-
- m_fillGradientMatrix.multiply(@tat );
- m_fillGradientMatrix.invert;
-
- m_fillGradientD1 :=0;
- m_fillGradientFlag:=AGG_Radial;
-
- m_fillColor.Construct(0 ,0 ,0 ); // Set some real color
-
-end;
-
-{ LINERADIALGRADIENT }
-procedure TAgg2D.LineRadialGradient(x ,y ,r : double; c1 ,c2 ,c3 : TAggColor );
-var
- i : int;
- c : TAggColor;
-
- clr : aggclr;
- tat : trans_affine_translation;
-
-begin
- i:=0;
-
- while i < 128 do
- begin
- c:=c1.gradient(c2 ,i / 127.0 );
-
- clr.Construct(c );
-
- move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
- inc (i );
-
- end;
-
- while i < 256 do
- begin
- c:=c2.gradient(c3 ,(i - 128 ) / 127.0 );
-
- clr.Construct(c );
-
- move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) );
- inc (i );
-
- end;
-
- m_lineGradientD2:=worldToScreen(r );
-
- WorldToScreen(@x ,@y );
-
- m_lineGradientMatrix.reset;
-
- tat.Construct(x ,y );
-
- m_lineGradientMatrix.multiply(@tat );
- m_lineGradientMatrix.invert;
-
- m_lineGradientD1 :=0;
- m_lineGradientFlag:=AGG_Radial;
-
- m_lineColor.Construct(0 ,0 ,0 ); // Set some real color
-
-end;
-
-{ FILLRADIALGRADIENT }
-procedure TAgg2D.FillRadialGradient(x ,y ,r : double );
-var
- tat : trans_affine_translation;
-
-begin
- m_fillGradientD2:=worldToScreen(r );
-
- WorldToScreen(@x ,@y );
-
- m_fillGradientMatrix.reset;
-
- tat.Construct(x ,y );
-
- m_fillGradientMatrix.multiply(@tat );
- m_fillGradientMatrix.invert;
-
- m_fillGradientD1:=0;
-
-end;
-
-{ LINERADIALGRADIENT }
-procedure TAgg2D.LineRadialGradient(x ,y ,r : double );
-var
- tat : trans_affine_translation;
-
-begin
- m_lineGradientD2:=worldToScreen(r );
-
- WorldToScreen(@x ,@y );
-
- m_lineGradientMatrix.reset;
-
- tat.Construct(x ,y );
-
- m_lineGradientMatrix.multiply(@tat );
- m_lineGradientMatrix.invert;
-
- m_lineGradientD1:=0;
-
-end;
-
-{ LINEWIDTH }
-procedure TAgg2D.LineWidth(w : double );
-begin
- m_lineWidth:=w;
-
- m_convStroke.width_(w );
-
-end;
-
-{ LINEWIDTH }
-function TAgg2D.LineWidth : double;
-begin
- result:=m_lineWidth;
-
-end;
-
-{ LINECAP }
-procedure TAgg2D.LineCap(cap : TAggLineCap );
-begin
- m_lineCap:=cap;
-
- m_convStroke.line_cap_(cap );
-
-end;
-
-{ LINECAP }
-function TAgg2D.LineCap : TAggLineCap;
-begin
- result:=m_lineCap;
-
-end;
-
-{ LINEJOIN }
-procedure TAgg2D.LineJoin(join : TAggLineJoin );
-begin
- m_lineJoin:=join;
-
- m_convStroke.line_join_(join );
-
-end;
-
-{ LINEJOIN }
-function TAgg2D.LineJoin : TAggLineJoin;
-begin
- result:=m_lineJoin;
-
-end;
-
-{ FILLEVENODD }
-procedure TAgg2D.FillEvenOdd(evenOddFlag : boolean );
-begin
- m_evenOddFlag:=evenOddFlag;
-
- if evenOddFlag then
- m_rasterizer.filling_rule(fill_even_odd )
- else
- m_rasterizer.filling_rule(fill_non_zero );
-
-end;
-
-{ FILLEVENODD }
-function TAgg2D.FillEvenOdd : boolean;
-begin
- result:=m_evenOddFlag;
-
-end;
-
-{ TRANSFORMATIONS }
-function TAgg2D.Transformations : TAggTransformations;
-begin
- m_transform.store_to(@result.affineMatrix[0 ] );
-
-end;
-
-{ TRANSFORMATIONS }
-procedure TAgg2D.Transformations(tr : PAggTransformations );
-begin
- m_transform.load_from(@tr.affineMatrix[0 ] );
-
- m_convCurve.approximation_scale_ (worldToScreen(1.0 ) * g_approxScale );
- m_convStroke.approximation_scale_(worldToScreen(1.0 ) * g_approxScale );
-
-end;
-
-{ RESETTRANSFORMATIONS }
-procedure TAgg2D.ResetTransformations;
-begin
- m_transform.reset;
-
-end;
-
-{ AFFINE }
-procedure TAgg2D.Affine(tr : PAggAffine );
-begin
- m_transform.multiply(tr );
-
- m_convCurve.approximation_scale_ (WorldToScreen(1.0 ) * g_approxScale );
- m_convStroke.approximation_scale_(WorldToScreen(1.0 ) * g_approxScale );
-
-end;
-
-{ AFFINE }
-procedure TAgg2D.Affine(tr : PAggTransformations );
-var
- ta : trans_affine;
-
-begin
- ta.Construct(
- tr.affineMatrix[0 ] ,tr.affineMatrix[1 ] ,tr.affineMatrix[2 ] ,
- tr.affineMatrix[3 ] ,tr.affineMatrix[4 ] ,tr.affineMatrix[5 ] );
-
- affine(PAggAffine(@ta ) );
-
-end;
-
-{ ROTATE }
-procedure TAgg2D.Rotate(angle : double );
-var
- tar : trans_affine_rotation;
-
-begin
- tar.Construct(angle );
-
- m_transform.multiply(@tar );
-
-end;
-
-{ SCALE }
-procedure TAgg2D.Scale(sx ,sy : double );
-var
- tas : trans_affine_scaling;
-
-begin
- tas.Construct(sx ,sy );
-
- m_transform.multiply(@tas );
-
- m_convCurve.approximation_scale_ (worldToScreen(1.0 ) * g_approxScale );
- m_convStroke.approximation_scale_(worldToScreen(1.0 ) * g_approxScale );
-
-end;
-
-{ SKEW }
-procedure TAgg2D.Skew(sx ,sy : double );
-var
- tas : trans_affine_skewing;
-
-begin
- tas.Construct(sx ,sy );
-
- m_transform.multiply(@tas );
-
-end;
-
-{ TRANSLATE }
-procedure TAgg2D.Translate(x ,y : double );
-var
- tat : trans_affine_translation;
-
-begin
- tat.Construct(x ,y );
-
- m_transform.multiply(@tat );
-
-end;
-
-{ PARALLELOGRAM }
-procedure TAgg2D.Parallelogram(x1 ,y1 ,x2 ,y2 : double; para : PDouble );
-var
- ta : trans_affine;
-
-begin
- ta.Construct(x1 ,y1 ,x2 ,y2 ,parallelo_ptr(para ) );
-
- m_transform.multiply(@ta );
-
- m_convCurve.approximation_scale_ (worldToScreen(1.0 ) * g_approxScale );
- m_convStroke.approximation_scale_(worldToScreen(1.0 ) * g_approxScale );
-
-end;
-
-{ VIEWPORT }
-procedure TAgg2D.Viewport(
- worldX1 ,worldY1 ,worldX2 ,worldY2 ,
- screenX1 ,screenY1 ,screenX2 ,screenY2 : double;
- opt : TAggViewportOption = AGG_XMidYMid );
-var
- vp : trans_viewport;
- mx : trans_affine;
-
-begin
- vp.Construct;
-
- case opt of
- AGG_Anisotropic :
- vp.preserve_aspect_ratio(0.0 ,0.0 ,aspect_ratio_stretch );
-
- AGG_XMinYMin :
- vp.preserve_aspect_ratio(0.0 ,0.0 ,aspect_ratio_meet );
-
- AGG_XMidYMin :
- vp.preserve_aspect_ratio(0.5 ,0.0 ,aspect_ratio_meet );
-
- AGG_XMaxYMin :
- vp.preserve_aspect_ratio(1.0 ,0.0 ,aspect_ratio_meet );
-
- AGG_XMinYMid :
- vp.preserve_aspect_ratio(0.0 ,0.5 ,aspect_ratio_meet );
-
- AGG_XMidYMid :
- vp.preserve_aspect_ratio(0.5 ,0.5 ,aspect_ratio_meet );
-
- AGG_XMaxYMid :
- vp.preserve_aspect_ratio(1.0 ,0.5 ,aspect_ratio_meet );
-
- AGG_XMinYMax :
- vp.preserve_aspect_ratio(0.0 ,1.0 ,aspect_ratio_meet );
-
- AGG_XMidYMax :
- vp.preserve_aspect_ratio(0.5 ,1.0 ,aspect_ratio_meet );
-
- AGG_XMaxYMax :
- vp.preserve_aspect_ratio(1.0 ,1.0 ,aspect_ratio_meet );
-
- end;
-
- vp.world_viewport (worldX1 ,worldY1 ,worldX2 ,worldY2 );
- vp.device_viewport(screenX1 ,screenY1 ,screenX2 ,screenY2 );
-
- mx.Construct;
-
- vp.to_affine (@mx );
- m_transform.multiply(@mx );
-
- m_convCurve.approximation_scale_ (WorldToScreen(1.0 ) * g_approxScale );
- m_convStroke.approximation_scale_(WorldToScreen(1.0 ) * g_approxScale );
-
-end;
-
-{ LINE }
-procedure TAgg2D.Line(x1 ,y1 ,x2 ,y2 : double );
-begin
- m_path.remove_all;
-
- addLine (x1 ,y1 ,x2 ,y2 );
- DrawPath(AGG_StrokeOnly );
-
-end;
-
-{ TRIANGLE }
-procedure TAgg2D.Triangle(x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double );
-begin
- m_path.remove_all;
- m_path.move_to(x1 ,y1 );
- m_path.line_to(x2 ,y2 );
- m_path.line_to(x3 ,y3 );
- m_path.close_polygon;
-
- DrawPath(AGG_FillAndStroke );
-
-end;
-
-{ RECTANGLE }
-procedure TAgg2D.Rectangle(x1 ,y1 ,x2 ,y2 : double );
-begin
- m_path.remove_all;
- m_path.move_to(x1 ,y1 );
- m_path.line_to(x2 ,y1 );
- m_path.line_to(x2 ,y2 );
- m_path.line_to(x1 ,y2 );
- m_path.close_polygon;
-
- DrawPath(AGG_FillAndStroke );
-
-end;
-
-{ ROUNDEDRECT }
-procedure TAgg2D.RoundedRect(x1 ,y1 ,x2 ,y2 ,r : double );
-var
- rc : rounded_rect;
-
-begin
- m_path.remove_all;
- rc.Construct(x1 ,y1 ,x2 ,y2 ,r );
-
- rc.normalize_radius;
- rc.approximation_scale_(worldToScreen(1.0 ) * g_approxScale );
-
- m_path.add_path(@rc ,0 ,false );
-
- DrawPath(AGG_FillAndStroke );
-
-end;
-
-{ ROUNDEDRECT }
-procedure TAgg2D.RoundedRect(x1 ,y1 ,x2 ,y2 ,rx ,ry : double );
-var
- rc : rounded_rect;
-
-begin
- m_path.remove_all;
- rc.Construct;
-
- rc.rect (x1 ,y1 ,x2 ,y2 );
- rc.radius(rx ,ry );
- rc.normalize_radius;
-
- m_path.add_path(@rc ,0 ,false );
-
- DrawPath(AGG_FillAndStroke );
-
-end;
-
-{ ROUNDEDRECT }
-procedure TAgg2D.RoundedRect(
- x1 ,y1 ,x2 ,y2 ,
- rxBottom ,ryBottom ,
- rxTop ,ryTop : double );
-var
- rc : rounded_rect;
-
-begin
- m_path.remove_all;
- rc.Construct;
-
- rc.rect (x1 ,y1 ,x2 ,y2 );
- rc.radius(rxBottom ,ryBottom ,rxTop ,ryTop );
- rc.normalize_radius;
-
- rc.approximation_scale_(worldToScreen(1.0 ) * g_approxScale );
-
- m_path.add_path(@rc ,0 ,false );
-
- DrawPath(AGG_FillAndStroke );
-
-end;
-
-{ ELLIPSE }
-procedure TAgg2D.Ellipse(cx ,cy ,rx ,ry : double );
-var
- el : bezier_arc;
-
-begin
- m_path.remove_all;
-
- el.Construct(cx ,cy ,rx ,ry ,0 ,2 * pi );
-
- m_path.add_path(@el ,0 ,false );
- m_path.close_polygon;
-
- DrawPath(AGG_FillAndStroke );
-
-end;
-
-{ ARC }
-procedure TAgg2D.Arc(cx ,cy ,rx ,ry ,start ,sweep : double );
-var
- ar : {bezier_}agg_arc.arc;
-
-begin
- m_path.remove_all;
-
- ar.Construct(cx ,cy ,rx ,ry ,sweep ,start ,false );
-
- m_path.add_path(@ar ,0 ,false );
-
- DrawPath(AGG_StrokeOnly );
-
-end;
-
-{ STAR }
-procedure TAgg2D.Star(cx ,cy ,r1 ,r2 ,startAngle : double; numRays : integer );
-var
- da ,a ,x ,y : double;
-
- i : int;
-
-begin
- m_path.remove_all;
-
- da:=pi / numRays;
- a :=startAngle;
-
- i:=0;
-
- while i < numRays do
- begin
- x:=Cos(a ) * r2 + cx;
- y:=Sin(a ) * r2 + cy;
-
- if i <> 0 then
- m_path.line_to(x ,y )
- else
- m_path.move_to(x ,y );
-
- a:=a + da;
-
- m_path.line_to(Cos(a ) * r1 + cx ,Sin(a ) * r1 + cy );
-
- a:=a + da;
-
- inc(i );
-
- end;
-
- ClosePolygon;
- DrawPath(AGG_FillAndStroke );
-
-end;
-
-{ CURVE }
-procedure TAgg2D.Curve(x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double );
-begin
- m_path.remove_all;
- m_path.move_to(x1 ,y1 );
- m_path.curve3 (x2 ,y2 ,x3 ,y3 );
-
- DrawPath(AGG_StrokeOnly );
-
-end;
-
-{ CURVE }
-procedure TAgg2D.Curve(x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,x4 ,y4 : double );
-begin
- m_path.remove_all;
- m_path.move_to(x1 ,y1 );
- m_path.curve4 (x2 ,y2 ,x3 ,y3 ,x4 ,y4 );
-
- DrawPath(AGG_StrokeOnly );
-
-end;
-
-{ POLYGON }
-procedure TAgg2D.Polygon(xy : PDouble; numPoints : integer );
-begin
- m_path.remove_all;
- m_path.add_poly(double_2_ptr(xy ) ,numPoints );
-
- ClosePolygon;
- DrawPath(AGG_FillAndStroke );
-
-end;
-
-{ POLYLINE }
-procedure TAgg2D.Polyline(xy : PDouble; numPoints : integer );
-begin
- m_path.remove_all;
- m_path.add_poly(double_2_ptr(xy ) ,numPoints );
-
- DrawPath(AGG_StrokeOnly );
-
-end;
-
-{ FLIPTEXT }
-procedure TAgg2D.FlipText(flip : boolean );
-begin
- m_fontEngine.flip_y_(not flip );
-
-end;
-
-{ FONT }
-procedure TAgg2D.Font(
- fileName : AnsiString; height : double;
- bold : boolean = false;
- italic : boolean = false;
- cache : TAggFontCacheType = AGG_VectorFontCache;
- angle : double = 0.0 );
-var
- b : int;
-
-begin
- m_textAngle :=angle;
- m_fontHeight :=height;
- m_fontCacheType:=cache;
-
-{$IFDEF AGG2D_USE_FREETYPE }
- if cache = AGG_VectorFontCache then
- m_fontEngine.load_font(PChar(@fileName[1 ] ) ,0 ,glyph_ren_outline )
- else
- m_fontEngine.load_font(PChar(@fileName[1 ] ) ,0 ,glyph_ren_agg_gray8 );
-
- m_fontEngine.hinting_(m_textHints );
-
- if cahce = AGG_VectorFontCache then
- m_fontEngine.height_(height )
- else
- m_fontEngine.height_(worldToScreen(height ) );
-
-{$ELSE }
- m_fontEngine.hinting_(m_textHints );
-
- if bold then
- b:=700
- else
- b:=400;
-
- if cache = AGG_VectorFontCache then
- m_fontEngine.create_font_(PChar(@fileName[1 ] ) ,glyph_ren_outline ,height ,0.0 ,b ,italic )
- else
- m_fontEngine.create_font_(PChar(@fileName[1 ] ) ,glyph_ren_agg_gray8 ,worldToScreen(height) ,0.0 ,b ,italic );
-
-{$ENDIF }
-
-end;
-
-{ FONTHEIGHT }
-function TAgg2D.FontHeight : double;
-begin
- result:=m_fontHeight;
-
-end;
-
-{ TEXTALIGNMENT }
-procedure TAgg2D.TextAlignment(alignX ,alignY : TAggTextAlignment );
-begin
- m_textAlignX:=alignX;
- m_textAlignY:=alignY;
-
-end;
-
-{ TEXTHINTS }
-function TAgg2D.TextHints : boolean;
-begin
- result:=m_textHints;
-
-end;
-
-{ TEXTHINTS }
-procedure TAgg2D.TextHints(hints : boolean );
-begin
- m_textHints:=hints;
-
-end;
-
-{ TEXTWIDTH }
-function TAgg2D.TextWidth(str : AnsiString ) : double;
-var
- x ,y : double;
- first : boolean;
- glyph : glyph_cache_ptr;
- str_ : PChar;
-
-begin
- x:=0;
- y:=0;
-
- first:=true;
- str_ :=@str[1 ];
-
- while str_^ <> #0 do
- begin
- glyph:=m_fontCacheManager.glyph(int32u(str_^ ) );
-
- if glyph <> NIL then
- begin
- if not first then
- m_fontCacheManager.add_kerning(@x ,@y );
-
- x:=x + glyph.advance_x;
- y:=y + glyph.advance_y;
-
- first:=false;
-
- end;
-
- inc(ptrcomp(str_ ) );
-
- end;
-
- if m_fontCacheType = AGG_VectorFontCache then
- result:=x
- else
- result:=ScreenToWorld(x );
-
-end;
-
-{ TEXT }
-procedure TAgg2D.Text(
- x ,y : double; str : AnsiString;
- roundOff : boolean = false;
- ddx : double = 0.0;
- ddy : double = 0.0 );
-var
- dx ,dy ,asc ,start_x ,start_y : double;
-
- glyph : glyph_cache_ptr;
-
- mtx : trans_affine;
- str_ : PChar;
-
- i : int;
-
- tat : trans_affine_translation;
- tar : trans_affine_rotation;
-
- tr : conv_transform;
-
-begin
- dx:=0.0;
- dy:=0.0;
-
- case m_textAlignX of
- AGG_AlignCenter :
- dx:=-textWidth(str ) * 0.5;
-
- AGG_AlignRight :
- dx:=-textWidth(str );
-
- end;
-
- asc :=fontHeight;
- glyph:=m_fontCacheManager.glyph(int32u('H' ) );
-
- if glyph <> NIL then
- asc:=glyph.bounds.y2 - glyph.bounds.y1;
-
- if m_fontCacheType = AGG_RasterFontCache then
- asc:=screenToWorld(asc );
-
- case m_textAlignY of
- AGG_AlignCenter :
- dy:=-asc * 0.5;
-
- AGG_AlignTop :
- dy:=-asc;
-
- end;
-
- if m_fontEngine._flip_y then
- dy:=-dy;
-
- mtx.Construct;
-
- start_x:=x + dx;
- start_y:=y + dy;
-
- if roundOff then
- begin
- start_x:=Trunc(start_x );
- start_y:=Trunc(start_y );
-
- end;
-
- start_x:=start_x + ddx;
- start_y:=start_y + ddy;
-
- tat.Construct(-x ,-y );
- mtx.multiply (@tat );
-
- tar.Construct(m_textAngle );
- mtx.multiply (@tar );
-
- tat.Construct(x ,y );
- mtx.multiply (@tat );
-
- tr.Construct(m_fontCacheManager.path_adaptor ,@mtx );
-
- if m_fontCacheType = AGG_RasterFontCache then
- WorldToScreen(@start_x ,@start_y );
-
- i:=0;
-
- str_:=@str[1 ];
-
- while char_ptr(ptrcomp(str_ ) + i * sizeof(char ) )^ <> #0 do
- begin
- glyph:=m_fontCacheManager.glyph(int32u(char_ptr(ptrcomp(str_ ) + i * sizeof(char ) )^ ) );
-
- if glyph <> NIL then
- begin
- if i <> 0 then
- m_fontCacheManager.add_kerning(@x ,@y );
-
- m_fontCacheManager.init_embedded_adaptors(glyph ,start_x ,start_y );
-
- if glyph.data_type = glyph_data_outline then
- begin
- m_path.remove_all;
- m_path.add_path(@tr ,0 ,false );
-
- drawPath;
-
- end;
-
- if glyph.data_type = glyph_data_gray8 then
- begin
- render(
- m_fontCacheManager.gray8_adaptor ,
- m_fontCacheManager.gray8_scanline );
-
- end;
-
- start_x:=start_x + glyph.advance_x;
- start_y:=start_y + glyph.advance_y;
-
- end;
-
- inc(i );
-
- end;
-
-end;
-
-{ RESETPATH }
-procedure TAgg2D.ResetPath;
-begin
- m_path.remove_all;
- m_path.move_to(0 ,0 );
-
-end;
-
-{ MOVETO }
-procedure TAgg2D.MoveTo(x ,y : double );
-begin
- m_path.move_to(x ,y );
-
-end;
-
-{ MOVEREL }
-procedure TAgg2D.MoveRel(dx ,dy : double );
-begin
- m_path.move_rel(dx ,dy );
-
-end;
-
-{ LINETO }
-procedure TAgg2D.LineTo(x ,y : double );
-begin
- m_path.line_to(x ,y );
-
-end;
-
-{ LINEREL }
-procedure TAgg2D.LineRel(dx ,dy : double );
-begin
- m_path.line_rel(dx ,dy );
-
-end;
-
-{ HORLINETO }
-procedure TAgg2D.HorLineTo(x : double );
-begin
- m_path.hline_to(x );
-
-end;
-
-{ HORLINEREL }
-procedure TAgg2D.HorLineRel(dx : double );
-begin
- m_path.hline_rel(dx );
-
-end;
-
-{ VERLINETO }
-procedure TAgg2D.VerLineTo(y : double );
-begin
- m_path.vline_to(y );
-
-end;
-
-{ VERLINEREL }
-procedure TAgg2D.VerLineRel(dy : double );
-begin
- m_path.vline_rel(dy );
-
-end;
-
-{ ARCTO }
-procedure TAgg2D.ArcTo(
- rx ,ry ,angle : double;
- largeArcFlag ,sweepFlag : boolean;
- x ,y : double );
-begin
- m_path.arc_to(rx ,ry ,angle ,largeArcFlag ,sweepFlag ,x ,y );
-
-end;
-
-{ ARCREL }
-procedure TAgg2D.ArcRel(
- rx ,ry ,angle : double;
- largeArcFlag ,sweepFlag : boolean;
- dx ,dy : double );
-begin
- m_path.arc_rel(rx ,ry ,angle ,largeArcFlag ,sweepFlag ,dx ,dy );
-
-end;
-
-{ QUADRICCURVETO }
-procedure TAgg2D.QuadricCurveTo (xCtrl ,yCtrl ,xTo ,yTo : double );
-begin
- m_path.curve3(xCtrl ,yCtrl ,xTo ,yTo );
-
-end;
-
-{ QUADRICCURVEREL }
-procedure TAgg2D.QuadricCurveRel(dxCtrl ,dyCtrl ,dxTo ,dyTo : double );
-begin
- m_path.curve3_rel(dxCtrl ,dyCtrl ,dxTo ,dyTo );
-
-end;
-
-{ QUADRICCURVETO }
-procedure TAgg2D.QuadricCurveTo (xTo ,yTo : double );
-begin
- m_path.curve3(xTo ,yTo );
-
-end;
-
-{ QUADRICCURVEREL }
-procedure TAgg2D.QuadricCurveRel(dxTo ,dyTo : double );
-begin
- m_path.curve3_rel(dxTo ,dyTo );
-
-end;
-
-{ CUBICCURVETO }
-procedure TAgg2D.CubicCurveTo (xCtrl1 ,yCtrl1 ,xCtrl2 ,yCtrl2 ,xTo ,yTo : double );
-begin
- m_path.curve4(xCtrl1 ,yCtrl1 ,xCtrl2 ,yCtrl2 ,xTo ,yTo );
-
-end;
-
-{ CUBICCURVEREL }
-procedure TAgg2D.CubicCurveRel(dxCtrl1 ,dyCtrl1 ,dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo : double );
-begin
- m_path.curve4_rel(dxCtrl1 ,dyCtrl1 ,dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo );
-
-end;
-
-{ CUBICCURVETO }
-procedure TAgg2D.CubicCurveTo (xCtrl2 ,yCtrl2 ,xTo ,yTo : double );
-begin
- m_path.curve4(xCtrl2 ,yCtrl2 ,xTo ,yTo );
-
-end;
-
-{ CUBICCURVEREL }
-procedure TAgg2D.CubicCurveRel(dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo : double );
-begin
- m_path.curve4_rel(dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo );
-
-end;
-
-{ ADDELLIPSE }
-procedure TAgg2D.AddEllipse(cx ,cy ,rx ,ry : double; dir : TAggDirection );
-var
- ar : bezier_arc;
-
-begin
- if dir = AGG_CCW then
- ar.Construct(cx ,cy ,rx ,ry ,0 ,2 * pi )
- else
- ar.Construct(cx ,cy ,rx ,ry ,0 ,-2 * pi );
-
- m_path.add_path(@ar ,0 ,false );
- m_path.close_polygon;
-
-end;
-
-{ CLOSEPOLYGON }
-procedure TAgg2D.ClosePolygon;
-begin
- m_path.close_polygon;
-
-end;
-
-{ DRAWPATH }
-procedure TAgg2D.DrawPath(flag : TAggDrawPathFlag = AGG_FillAndStroke );
-begin
- m_rasterizer.reset;
-
- case flag of
- AGG_FillOnly :
- if m_fillColor.a <> 0 then
- begin
- m_rasterizer.add_path(@m_pathTransform );
-
- render(true );
-
- end;
-
- AGG_StrokeOnly :
- if (m_lineColor.a <> 0 ) and
- (m_lineWidth > 0.0 ) then
- begin
- m_rasterizer.add_path(@m_strokeTransform );
-
- render(false );
-
- end;
-
- AGG_FillAndStroke :
- begin
- if m_fillColor.a <> 0 then
- begin
- m_rasterizer.add_path(@m_pathTransform );
-
- render(true );
-
- end;
-
- if (m_lineColor.a <> 0 ) and
- (m_lineWidth > 0.0 ) then
- begin
- m_rasterizer.add_path(@m_strokeTransform );
-
- render(false );
-
- end;
-
- end;
-
- AGG_FillWithLineColor :
- if m_lineColor.a <> 0 then
- begin
- m_rasterizer.add_path(@m_pathTransform );
-
- render(false );
-
- end;
-
- end;
-
-end;
-
-{ IMAGEFILTER }
-procedure TAgg2D.ImageFilter(f : TAggImageFilter );
-begin
- m_imageFilter:=f;
-
- case f of
- AGG_Bilinear :
- m_imageFilterLut.calculate(@m_ifBilinear ,true );
-
- AGG_Hanning :
- m_imageFilterLut.calculate(@m_ifHanning ,true );
-
- AGG_Hermite :
- m_imageFilterLut.calculate(@m_ifHermite ,true );
-
- AGG_Quadric :
- m_imageFilterLut.calculate(@m_ifQuadric ,true );
-
- AGG_Bicubic :
- m_imageFilterLut.calculate(@m_ifBicubic ,true );
-
- AGG_Catrom :
- m_imageFilterLut.calculate(@m_ifCatrom ,true );
-
- AGG_Spline16 :
- m_imageFilterLut.calculate(@m_ifSpline16 ,true );
-
- AGG_Spline36 :
- m_imageFilterLut.calculate(@m_ifSpline36 ,true );
-
- AGG_Blackman144 :
- m_imageFilterLut.calculate(@m_ifBlackman144 ,true );
-
- end;
-
-end;
-
-{ IMAGEFILTER }
-function TAgg2D.ImageFilter : TAggImageFilter;
-begin
- result:=m_imageFilter;
-
-end;
-
-{ IMAGERESAMPLE }
-procedure TAgg2D.ImageResample(f : TAggImageResample );
-begin
- m_imageResample:=f;
-
-end;
-
-{ IMAGEFLIP }
-procedure TAgg2D.ImageFlip(f : boolean );
-begin
- m_imageFlip:=f;
-
-end;
-
-{ IMAGERESAMPLE }
-function TAgg2D.ImageResample : TAggImageResample;
-begin
- result:=m_imageResample;
-
-end;
-
-{ TRANSFORMIMAGE }
-procedure TAgg2D.TransformImage(
- bitmap : TBitmap;
- imgX1 ,imgY1 ,imgX2 ,imgY2 : integer;
- dstX1 ,dstY1 ,dstX2 ,dstY2 : double );
-var
- parall : array[0..5 ] of double;
- image : TAggImage;
-
-begin
- image.Construct;
-
- if image.attach(bitmap ,m_imageFlip ) then
- begin
- resetPath;
- moveTo(dstX1 ,dstY1 );
- lineTo(dstX2 ,dstY1 );
- lineTo(dstX2 ,dstY2 );
- lineTo(dstX1 ,dstY2 );
- closePolygon;
-
- parall[0 ]:=dstX1;
- parall[1 ]:=dstY1;
- parall[2 ]:=dstX2;
- parall[3 ]:=dstY1;
- parall[4 ]:=dstX2;
- parall[5 ]:=dstY2;
-
- renderImage(@image ,imgX1 ,imgY1 ,imgX2 ,imgY2 ,@parall[0 ] );
-
- image.Destruct;
-
- end;
-
-end;
-
-{ TRANSFORMIMAGE }
-procedure TAgg2D.TransformImage(
- bitmap : TBitmap;
- dstX1 ,dstY1 ,dstX2 ,dstY2 : double );
-var
- parall : array[0..5 ] of double;
- image : TAggImage;
-
-begin
- image.Construct;
-
- if image.attach(bitmap ,m_imageFlip ) then
- begin
- ResetPath;
- MoveTo(dstX1 ,dstY1 );
- LineTo(dstX2 ,dstY1 );
- LineTo(dstX2 ,dstY2 );
- LineTo(dstX1 ,dstY2 );
- ClosePolygon;
-
- parall[0 ]:=dstX1;
- parall[1 ]:=dstY1;
- parall[2 ]:=dstX2;
- parall[3 ]:=dstY1;
- parall[4 ]:=dstX2;
- parall[5 ]:=dstY2;
-
- renderImage(@image ,0 ,0 ,image.renBuf._width ,image.renBuf._height ,@parall[0 ] );
-
- image.Destruct;
-
- end;
-
-end;
-
-{ TRANSFORMIMAGE }
-procedure TAgg2D.TransformImage(
- bitmap : TBitmap;
- imgX1 ,imgY1 ,imgX2 ,imgY2 : integer;
- parallelo : PDouble );
-var
- image : TAggImage;
-
-begin
- image.Construct;
-
- if image.attach(bitmap ,m_imageFlip ) then
- begin
- ResetPath;
-
- MoveTo(
- PDouble(ptrcomp(parallelo ) + 0 * sizeof(double ) )^ ,
- PDouble(ptrcomp(parallelo ) + 1 * sizeof(double ) )^ );
-
- LineTo(
- PDouble(ptrcomp(parallelo ) + 2 * sizeof(double ) )^ ,
- PDouble(ptrcomp(parallelo ) + 3 * sizeof(double ) )^ );
-
- LineTo(
- PDouble(ptrcomp(parallelo ) + 4 * sizeof(double ) )^ ,
- PDouble(ptrcomp(parallelo ) + 5 * sizeof(double ) )^ );
-
- LineTo(
- PDouble(ptrcomp(parallelo ) + 0 * sizeof(double ) )^ +
- PDouble(ptrcomp(parallelo ) + 4 * sizeof(double ) )^ -
- PDouble(ptrcomp(parallelo ) + 2 * sizeof(double ) )^ ,
- PDouble(ptrcomp(parallelo ) + 1 * sizeof(double ) )^ +
- PDouble(ptrcomp(parallelo ) + 5 * sizeof(double ) )^ -
- PDouble(ptrcomp(parallelo ) + 3 * sizeof(double ) )^ );
-
- ClosePolygon;
-
- renderImage(@image ,imgX1 ,imgY1 ,imgX2 ,imgY2 ,parallelo );
-
- image.Destruct;
-
- end;
-
-end;
-
-{ TRANSFORMIMAGE }
-procedure TAgg2D.TransformImage(bitmap : TBitmap; parallelo : PDouble );
-var
- image : TAggImage;
-
-begin
- image.Construct;
-
- if image.attach(bitmap ,m_imageFlip ) then
- begin
- ResetPath;
-
- MoveTo(
- PDouble(ptrcomp(parallelo ) + 0 * sizeof(double ) )^ ,
- PDouble(ptrcomp(parallelo ) + 1 * sizeof(double ) )^ );
-
- LineTo(
- PDouble(ptrcomp(parallelo ) + 2 * sizeof(double ) )^ ,
- PDouble(ptrcomp(parallelo ) + 3 * sizeof(double ) )^ );
-
- LineTo(
- PDouble(ptrcomp(parallelo ) + 4 * sizeof(double ) )^ ,
- PDouble(ptrcomp(parallelo ) + 5 * sizeof(double ) )^ );
-
- LineTo(
- PDouble(ptrcomp(parallelo ) + 0 * sizeof(double ) )^ +
- PDouble(ptrcomp(parallelo ) + 4 * sizeof(double ) )^ -
- PDouble(ptrcomp(parallelo ) + 2 * sizeof(double ) )^ ,
- PDouble(ptrcomp(parallelo ) + 1 * sizeof(double ) )^ +
- PDouble(ptrcomp(parallelo ) + 5 * sizeof(double ) )^ -
- PDouble(ptrcomp(parallelo ) + 3 * sizeof(double ) )^ );
-
- ClosePolygon;
-
- renderImage(@image ,0 ,0 ,image.renBuf._width ,image.renBuf._height ,parallelo );
-
- image.Destruct;
-
- end;
-
-end;
-
-{ TRANSFORMIMAGEPATH }
-procedure TAgg2D.TransformImagePath(
- bitmap : TBitmap;
- imgX1 ,imgY1 ,imgX2 ,imgY2 : integer;
- dstX1 ,dstY1 ,dstX2 ,dstY2 : double );
-var
- parall : array[0..5 ] of double;
- image : TAggImage;
-
-begin
- image.Construct;
-
- if image.attach(bitmap ,m_imageFlip ) then
- begin
- parall[0 ]:=dstX1;
- parall[1 ]:=dstY1;
- parall[2 ]:=dstX2;
- parall[3 ]:=dstY1;
- parall[4 ]:=dstX2;
- parall[5 ]:=dstY2;
-
- renderImage(@image ,imgX1 ,imgY1 ,imgX2 ,imgY2 ,@parall[0 ] );
-
- image.Destruct;
-
- end;
-
-end;
-
-{ TRANSFORMIMAGEPATH }
-procedure TAgg2D.TransformImagePath(
- bitmap : TBitmap;
- dstX1 ,dstY1 ,dstX2 ,dstY2 : double );
-var
- parall : array[0..5 ] of double;
- image : TAggImage;
-
-begin
- image.Construct;
-
- if image.attach(bitmap ,m_imageFlip ) then
- begin
- parall[0 ]:=dstX1;
- parall[1 ]:=dstY1;
- parall[2 ]:=dstX2;
- parall[3 ]:=dstY1;
- parall[4 ]:=dstX2;
- parall[5 ]:=dstY2;
-
- renderImage(@image ,0 ,0 ,image.renBuf._width ,image.renBuf._height ,@parall[0 ] );
-
- image.Destruct;
-
- end;
-
-end;
-
-{ TRANSFORMIMAGEPATH }
-procedure TAgg2D.TransformImagePath(
- bitmap : TBitmap;
- imgX1 ,imgY1 ,imgX2 ,imgY2 : integer;
- parallelo : PDouble );
-var
- image : TAggImage;
-
-begin
- image.Construct;
-
- if image.attach(bitmap ,m_imageFlip ) then
- begin
- renderImage(@image ,imgX1 ,imgY1 ,imgX2 ,imgY2 ,parallelo );
-
- image.Destruct;
-
- end;
-
-end;
-
-{ TRANSFORMIMAGEPATH }
-procedure TAgg2D.TransformImagePath(bitmap : TBitmap; parallelo : PDouble );
-var
- image : TAggImage;
-
-begin
- image.Construct;
-
- if image.attach(bitmap ,m_imageFlip ) then
- begin
- renderImage(@image ,0 ,0 ,image.renBuf._width ,image.renBuf._height ,parallelo );
-
- image.Destruct;
-
- end;
-
-end;
-
-{ COPYIMAGE }
-procedure TAgg2D.CopyImage(
- bitmap : TBitmap;
- imgX1 ,imgY1 ,imgX2 ,imgY2 : integer;
- dstX ,dstY : double );
-var
- r : agg_basics.rect;
- image : TAggImage;
-
-begin
- image.Construct;
-
- if image.attach(bitmap ,m_imageFlip ) then
- begin
- WorldToScreen(@dstX ,@dstY );
- r.Construct (imgX1 ,imgY1 ,imgX2 ,imgY2 );
-
- m_renBase.copy_from(@image.renBuf ,@r ,Trunc(dstX ) - imgX1 ,Trunc(dstY ) - imgY1 );
-
- image.Destruct;
-
- end;
-
-end;
-
-{ COPYIMAGE }
-procedure TAgg2D.CopyImage(bitmap : TBitmap; dstX ,dstY : double );
-var
- image : TAggImage;
-
-begin
- image.Construct;
-
- if image.attach(bitmap ,m_imageFlip ) then
- begin
- WorldToScreen(@dstX ,@dstY );
-
- m_renBase.copy_from(@image.renBuf ,NIL ,Trunc(dstX ) ,Trunc(dstY ) );
-
- image.Destruct;
-
- end;
-
-end;
-
-{ RENDER }
-procedure TAgg2D.render(fillColor_ : boolean );
-begin
- if (m_blendMode = AGG_BlendAlpha ) or
- (m_pixf = pf24bit ) then
- Agg2DRenderer_render(self ,@m_renBase ,@m_renSolid ,fillColor_ )
- else
- Agg2DRenderer_render(self ,@m_renBaseComp ,@m_renSolidComp ,fillColor_ );
-
-end;
-
-{ RENDER }
-procedure TAgg2D.render(ras : PAggFontRasterizer; sl : PAggFontScanline );
-begin
- if (m_blendMode = AGG_BlendAlpha ) or
- (m_pixf = pf24bit ) then
- Agg2DRenderer_render(self ,@m_renBase ,@m_renSolid ,ras ,sl )
- else
- Agg2DRenderer_render(self ,@m_renBaseComp ,@m_renSolidComp ,ras ,sl );
-
-end;
-
-{ ADDLINE }
-procedure TAgg2D.addLine(x1 ,y1 ,x2 ,y2 : double );
-begin
- m_path.move_to(x1 ,y1 );
- m_path.line_to(x2 ,y2 );
-
-end;
-
-{ UPDATERASTERIZERGAMMA }
-procedure TAgg2D.updateRasterizerGamma;
-begin
- m_gammaAgg2D.Construct(m_masterAlpha ,m_antiAliasGamma );
- m_rasterizer.gamma (@m_gammaAgg2D );
-
-end;
-
-{ RENDERIMAGE }
-procedure TAgg2D.renderImage(
- img : PAggImage;
- x1 ,y1 ,x2 ,y2 : integer;
- parl : PDouble );
-var
- mtx : trans_affine;
-
- interpolator : span_interpolator_linear;
-
-begin
- mtx.Construct(x1 ,y1 ,x2 ,y2 ,parallelo_ptr(parl ) );
- mtx.multiply (@m_transform );
- mtx.invert;
-
- m_rasterizer.reset;
- m_rasterizer.add_path(@m_pathTransform );
-
- interpolator.Construct(@mtx );
-
- if (m_blendMode = AGG_BlendAlpha ) or
- (m_pixf = pf24bit ) then
- Agg2DRenderer_renderImage(self ,img ,@m_renBasePre ,@interpolator )
- else
- Agg2DRenderer_renderImage(self ,img ,@m_renBaseCompPre ,@interpolator );
-
-end;
-
-{ BITMAPALPHATRANSPARENCY }
-function BitmapAlphaTransparency(bitmap : TBitmap; alpha : byte ) : boolean;
-var
- fcx ,fcy : integer;
- transp : ^byte;
-
-begin
- result:=false;
-
- if Assigned(bitmap ) and
- not bitmap.Empty and
- (bitmap.PixelFormat = pf32bit ) then
- begin
- for fcy:=0 to bitmap.Height - 1 do
- begin
- transp:=pointer(ptrcomp(bitmap.ScanLine[fcy ] ) + 3 );
-
- for fcx:=0 to bitmap.Width - 1 do
- begin
- transp^:=alpha;
-
- inc(ptrcomp(transp ) ,4 );
-
- end;
-
- end;
-
- { OK }
- result:=true;
-
- end;
-
-end;
-
-END.
-
-{*}
-{!}{ To look At }
-
-
+//---------------------------------------------------------------------------- +// Agg2D - Version 1.0 +// Based on Anti-Grain Geometry +// Copyright (C) 2005 Maxim Shemanarev (http://www.antigrain.com) +// +// TAgg2D - Version 1.0 Release Milano 3 (AggPas 2.4 RM3) +// Pascal Port By: Milan Marusinec alias Milano +// milan@marusinec.sk +// http://www.aggpas.org +// Copyright (c) 2007 - 2008 +// +// Permission to copy, use, modify, sell and distribute this software +// is granted provided this copyright notice appears in all copies. +// This software is provided "as is" without express or implied +// warranty, and with no claim as to its suitability for any purpose. +// +//---------------------------------------------------------------------------- +// Contact: mcseem@antigrain.com +// mcseemagg@yahoo.com +// http://www.antigrain.com +// +// [Pascal Port History] ----------------------------------------------------- +// +// 22.11.2007-Milano: Unit port establishment +// 23.11.2007-Milano: Porting +// 11.12.2007-Milano: -"- +// 13.12.2007-Milano: -"- +// 13.01.2008-Milano: Finished OK +// +{ Agg2D.pas } +unit + Agg2D ; + +INTERFACE + +{$I agg_mode.inc } + +// With this define you can switch use of FreeType or Win32 TrueType font engine +{DEFINE AGG2D_USE_FREETYPE } + +uses + agg_basics , + agg_array , + agg_trans_affine , + agg_trans_viewport , + agg_path_storage , + agg_conv_stroke , + agg_conv_transform , + agg_conv_curve , + agg_rendering_buffer , + agg_renderer_base , + agg_renderer_scanline , + agg_span_gradient , + agg_span_image_filter_rgba , + agg_span_image_resample_rgba , + agg_span_converter , + agg_span_interpolator_linear , + agg_span_allocator , + agg_rasterizer_scanline_aa , + agg_gamma_functions , + agg_scanline_u , + agg_arc , + agg_bezier_arc , + agg_rounded_rect , + agg_font_engine , + agg_font_cache_manager , + agg_pixfmt , + agg_pixfmt_rgb , + agg_pixfmt_rgba , + agg_color , + agg_math_stroke , + agg_image_filters , + agg_vertex_source , + agg_render_scanlines , + +{$IFDEF AGG2D_USE_FREETYPE } + agg_font_freetype , + +{$ELSE } + agg_font_win32_tt , + +{$ENDIF } + + Math ,Windows ,Classes ,Graphics ; + +{ GLOBAL VARIABLES & CONSTANTS } +const +// LineJoin + AGG_JoinMiter = miter_join; + AGG_JoinRound = round_join; + AGG_JoinBevel = bevel_join; + +// LineCap + AGG_CapButt = butt_cap; + AGG_CapSquare = square_cap; + AGG_CapRound = round_cap; + +// TextAlignment + AGG_AlignLeft = 0; + AGG_AlignRight = 1; + AGG_AlignCenter = 2; + AGG_AlignTop = AGG_AlignRight; + AGG_AlignBottom = AGG_AlignLeft; + +// BlendMode + AGG_BlendAlpha = end_of_comp_op_e; + AGG_BlendClear = comp_op_clear; + AGG_BlendSrc = comp_op_src; + AGG_BlendDst = comp_op_dst; + AGG_BlendSrcOver = comp_op_src_over; + AGG_BlendDstOver = comp_op_dst_over; + AGG_BlendSrcIn = comp_op_src_in; + AGG_BlendDstIn = comp_op_dst_in; + AGG_BlendSrcOut = comp_op_src_out; + AGG_BlendDstOut = comp_op_dst_out; + AGG_BlendSrcAtop = comp_op_src_atop; + AGG_BlendDstAtop = comp_op_dst_atop; + AGG_BlendXor = comp_op_xor; + AGG_BlendAdd = comp_op_plus; + AGG_BlendSub = comp_op_minus; + AGG_BlendMultiply = comp_op_multiply; + AGG_BlendScreen = comp_op_screen; + AGG_BlendOverlay = comp_op_overlay; + AGG_BlendDarken = comp_op_darken; + AGG_BlendLighten = comp_op_lighten; + AGG_BlendColorDodge = comp_op_color_dodge; + AGG_BlendColorBurn = comp_op_color_burn; + AGG_BlendHardLight = comp_op_hard_light; + AGG_BlendSoftLight = comp_op_soft_light; + AGG_BlendDifference = comp_op_difference; + AGG_BlendExclusion = comp_op_exclusion; + AGG_BlendContrast = comp_op_contrast; + +{ TYPES DEFINITION } +type + PDouble = ^double; + + PAggColor = ^TAggColor; + TAggColor = rgba8; + + TAggRectD = agg_basics.rect_d; + + TAggAffine = trans_affine; + PAggAffine = trans_affine_ptr; + + TAggFontRasterizer = gray8_adaptor_type; + PAggFontRasterizer = gray8_adaptor_type_ptr; + + TAggFontScanline = gray8_scanline_type; + PAggFontScanline = gray8_scanline_type_ptr; + +{$IFDEF AGG2D_USE_FREETYPE } + TAggFontEngine = font_engine_freetype_int32; + +{$ELSE } + TAggFontEngine = font_engine_win32_tt_int32; + +{$ENDIF } + + TAggGradient = (AGG_Solid ,AGG_Linear ,AGG_Radial ); + TAggDirection = (AGG_CW, AGG_CCW ); + + TAggLineJoin = int; + TAggLineCap = int; + TAggBlendMode = comp_op_e; + + TAggTextAlignment = int; + + TAggDrawPathFlag = ( + AGG_FillOnly , + AGG_StrokeOnly , + AGG_FillAndStroke , + AGG_FillWithLineColor ); + + TAggViewportOption = ( + AGG_Anisotropic , + AGG_XMinYMin , + AGG_XMidYMin , + AGG_XMaxYMin , + AGG_XMinYMid , + AGG_XMidYMid , + AGG_XMaxYMid , + AGG_XMinYMax , + AGG_XMidYMax , + AGG_XMaxYMax ); + + TAggImageFilter = ( + AGG_NoFilter , + AGG_Bilinear , + AGG_Hanning , + AGG_Hermite , + AGG_Quadric , + AGG_Bicubic , + AGG_Catrom , + AGG_Spline16 , + AGG_Spline36 , + AGG_Blackman144 ); + + TAggImageResample = ( + AGG_NoResample , + AGG_ResampleAlways , + AGG_ResampleOnZoomOut ); + + TAggFontCacheType = ( + AGG_RasterFontCache , + AGG_VectorFontCache ); + + PAggTransformations = ^TAggTransformations; + TAggTransformations = record + affineMatrix : array[0..5 ] of double; + + end; + + TAggRasterizerGamma = object(vertex_source ) + m_alpha : gamma_multiply; + m_gamma : gamma_power; + + constructor Construct(alpha ,gamma : double ); + + function func_operator_gamma(x : double ) : double; virtual; + + end; + + PAggImage = ^TAggImage; + TAggImage = object + renBuf : rendering_buffer; + + constructor Construct; + destructor Destruct; + + function attach(bitmap : TBitmap; flip : boolean ) : boolean; + + function width : int; + function height : int; + + end; + + TAgg2D = class + private + m_rbuf : rendering_buffer; + m_pixf : TPixelFormat; + + m_pixFormat ,m_pixFormatComp ,m_pixFormatPre ,m_pixFormatCompPre : pixel_formats; + m_renBase ,m_renBaseComp ,m_renBasePre ,m_renBaseCompPre : renderer_base; + + m_renSolid ,m_renSolidComp : renderer_scanline_aa_solid; + + m_allocator : span_allocator; + m_clipBox : TAggRectD; + + m_blendMode ,m_imageBlendMode : TAggBlendMode; + + m_imageBlendColor : TAggColor; + + m_scanline : scanline_u8; + m_rasterizer : rasterizer_scanline_aa; + + m_masterAlpha ,m_antiAliasGamma : double; + + m_fillColor ,m_lineColor : TAggColor; + + m_fillGradient ,m_lineGradient : pod_auto_array; + + m_lineCap : TAggLineCap; + m_lineJoin : TAggLineJoin; + + m_fillGradientFlag ,m_lineGradientFlag : TAggGradient; + + m_fillGradientMatrix ,m_lineGradientMatrix : trans_affine; + + m_fillGradientD1 , + m_lineGradientD1 , + m_fillGradientD2 , + m_lineGradientD2 , + m_textAngle : double; + m_textAlignX , + m_textAlignY : TAggTextAlignment; + m_textHints : boolean; + m_fontHeight , + m_fontAscent , + m_fontDescent : double; + m_fontCacheType : TAggFontCacheType; + + m_imageFilter : TAggImageFilter; + m_imageResample : TAggImageResample; + m_imageFilterLut : image_filter_lut; + + m_fillGradientInterpolator , + m_lineGradientInterpolator : span_interpolator_linear; + + m_linearGradientFunction : gradient_x; + m_radialGradientFunction : gradient_circle; + + m_lineWidth : double; + m_evenOddFlag : boolean; + + m_path : path_storage; + m_transform : trans_affine; + + m_convCurve : conv_curve; + m_convStroke : conv_stroke; + + m_pathTransform ,m_strokeTransform : conv_transform; + + m_imageFlip : boolean; + + {$IFNDEF AGG2D_USE_FREETYPE } + m_fontDC : HDC; + + {$ENDIF } + + m_fontEngine : TAggFontEngine; + m_fontCacheManager : font_cache_manager; + + // Other Pascal-specific members + m_gammaNone : gamma_none; + m_gammaAgg2D : TAggRasterizerGamma; + + m_ifBilinear : image_filter_bilinear; + m_ifHanning : image_filter_hanning; + m_ifHermite : image_filter_hermite; + m_ifQuadric : image_filter_quadric; + m_ifBicubic : image_filter_bicubic; + m_ifCatrom : image_filter_catrom; + m_ifSpline16 : image_filter_spline16; + m_ifSpline36 : image_filter_spline36; + m_ifBlackman144 : image_filter_blackman144; + + public + constructor Create; + destructor Destroy; override; + + // Vector Graphics Engine Initialization + function Attach(bitmap : TBitmap; flip_y : boolean = false ) : boolean; + + procedure ClearAll(c : TAggColor ); overload; + procedure ClearAll(r ,g ,b : byte; a : byte = 255 ); overload; + + // Master Rendering Properties + procedure BlendMode(m : TAggBlendMode ); overload; + function BlendMode : TAggBlendMode; overload; + + procedure MasterAlpha(a : double ); overload; + function MasterAlpha : double; overload; + + procedure AntiAliasGamma(g : double ); overload; + function AntiAliasGamma : double; overload; + + procedure FillColor(c : TAggColor ); overload; + procedure FillColor(r ,g ,b : byte; a : byte = 255 ); overload; + procedure NoFill; + + procedure LineColor(c : TAggColor ); overload; + procedure LineColor(r ,g ,b : byte; a : byte = 255 ); overload; + procedure NoLine; + + function FillColor : TAggColor; overload; + function LineColor : TAggColor; overload; + + procedure FillLinearGradient(x1 ,y1 ,x2 ,y2 : double; c1 ,c2 : TAggColor; profile : double = 1.0 ); + procedure LineLinearGradient(x1 ,y1 ,x2 ,y2 : double; c1 ,c2 : TAggColor; profile : double = 1.0 ); + + procedure FillRadialGradient(x ,y ,r : double; c1 ,c2 : TAggColor; profile : double = 1.0 ); overload; + procedure LineRadialGradient(x ,y ,r : double; c1 ,c2 : TAggColor; profile : double = 1.0 ); overload; + + procedure FillRadialGradient(x ,y ,r : double; c1 ,c2 ,c3 : TAggColor ); overload; + procedure LineRadialGradient(x ,y ,r : double; c1 ,c2 ,c3 : TAggColor ); overload; + + procedure FillRadialGradient(x ,y ,r : double ); overload; + procedure LineRadialGradient(x ,y ,r : double ); overload; + + procedure LineWidth(w : double ); overload; + function LineWidth : double; overload; + + procedure LineCap(cap : TAggLineCap ); overload; + function LineCap : TAggLineCap; overload; + + procedure LineJoin(join : TAggLineJoin ); overload; + function LineJoin : TAggLineJoin; overload; + + procedure FillEvenOdd(evenOddFlag : boolean ); overload; + function FillEvenOdd : boolean; overload; + + // Affine Transformations + function Transformations : TAggTransformations; overload; + procedure Transformations(tr : PAggTransformations ); overload; + procedure ResetTransformations; + + procedure Affine(tr : PAggAffine ); overload; + procedure Affine(tr : PAggTransformations ); overload; + + procedure Rotate (angle : double ); + procedure Scale (sx ,sy : double ); + procedure Skew (sx ,sy : double ); + procedure Translate(x ,y : double ); + + procedure Parallelogram(x1 ,y1 ,x2 ,y2 : double; para : PDouble ); + + procedure Viewport( + worldX1 ,worldY1 ,worldX2 ,worldY2 , + screenX1 ,screenY1 ,screenX2 ,screenY2 : double; + opt : TAggViewportOption = AGG_XMidYMid ); + + // Coordinates Conversions + procedure WorldToScreen(x ,y : PDouble ); overload; + procedure ScreenToWorld(x ,y : PDouble ); overload; + function WorldToScreen(scalar : double ) : double; overload; + function ScreenToWorld(scalar : double ) : double; overload; + + procedure AlignPoint(x ,y : PDouble ); + + // Clipping + procedure ClipBox(x1 ,y1 ,x2 ,y2 : double ); overload; + function ClipBox : TAggRectD; overload; + + procedure ClearClipBox(c : TAggColor ); overload; + procedure ClearClipBox(r ,g ,b : byte; a : byte = 255 ); overload; + + function InBox(worldX ,worldY : double ) : boolean; + + // Basic Shapes + procedure Line (x1 ,y1 ,x2 ,y2 : double ); + procedure Triangle (x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double ); + procedure Rectangle(x1 ,y1 ,x2 ,y2 : double ); + + procedure RoundedRect(x1 ,y1 ,x2 ,y2 ,r : double ); overload; + procedure RoundedRect(x1 ,y1 ,x2 ,y2 ,rx ,ry : double ); overload; + procedure RoundedRect( + x1 ,y1 ,x2 ,y2 , + rxBottom ,ryBottom , + rxTop ,ryTop : double ); overload; + + procedure Ellipse(cx ,cy ,rx ,ry : double ); + + procedure Arc (cx ,cy ,rx ,ry ,start ,sweep : double ); + procedure Star(cx ,cy ,r1 ,r2 ,startAngle : double; numRays : integer ); + + procedure Curve(x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double ); overload; + procedure Curve(x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,x4 ,y4 : double ); overload; + + procedure Polygon (xy : PDouble; numPoints : integer ); + procedure Polyline(xy : PDouble; numPoints : integer ); + + // Path Commands + procedure ResetPath; + + procedure MoveTo (x ,y : double ); + procedure MoveRel(dx ,dy : double ); + + procedure LineTo (x ,y : double ); + procedure LineRel(dx ,dy : double ); + + procedure HorLineTo (x : double ); + procedure HorLineRel(dx : double ); + + procedure VerLineTo (y : double ); + procedure VerLineRel(dy : double ); + + procedure ArcTo( + rx ,ry ,angle : double; + largeArcFlag ,sweepFlag : boolean; + x ,y : double ); + + procedure ArcRel( + rx ,ry ,angle : double; + largeArcFlag ,sweepFlag : boolean; + dx ,dy : double ); + + procedure QuadricCurveTo (xCtrl ,yCtrl ,xTo ,yTo : double ); overload; + procedure QuadricCurveRel(dxCtrl ,dyCtrl ,dxTo ,dyTo : double ); overload; + procedure QuadricCurveTo (xTo ,yTo : double ); overload; + procedure QuadricCurveRel(dxTo ,dyTo : double ); overload; + + procedure CubicCurveTo (xCtrl1 ,yCtrl1 ,xCtrl2 ,yCtrl2 ,xTo ,yTo : double ); overload; + procedure CubicCurveRel(dxCtrl1 ,dyCtrl1 ,dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo : double ); overload; + procedure CubicCurveTo (xCtrl2 ,yCtrl2 ,xTo ,yTo : double ); overload; + procedure CubicCurveRel(dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo : double ); overload; + + procedure AddEllipse(cx ,cy ,rx ,ry : double; dir : TAggDirection ); + procedure ClosePolygon; + + procedure DrawPath(flag : TAggDrawPathFlag = AGG_FillAndStroke ); + + // Text Rendering + procedure FlipText(flip : boolean ); + + procedure Font( + fileName : AnsiString; height : double; + bold : boolean = false; + italic : boolean = false; + cache : TAggFontCacheType = AGG_VectorFontCache; + angle : double = 0.0 ); + + function FontHeight : double; + + procedure TextAlignment(alignX ,alignY : TAggTextAlignment ); + + function TextHints : boolean; overload; + procedure TextHints(hints : boolean ); overload; + function TextWidth(str : AnsiString ) : double; + + procedure Text( + x ,y : double; str : AnsiString; + roundOff : boolean = false; + ddx : double = 0.0; + ddy : double = 0.0 ); + + // Image Rendering + procedure ImageFilter(f : TAggImageFilter ); overload; + function ImageFilter : TAggImageFilter; overload; + + procedure ImageResample(f : TAggImageResample ); overload; + function ImageResample : TAggImageResample; overload; + + procedure ImageFlip(f : boolean ); + + procedure TransformImage( + bitmap : TBitmap; + imgX1 ,imgY1 ,imgX2 ,imgY2 : integer; + dstX1 ,dstY1 ,dstX2 ,dstY2 : double ); overload; + + procedure TransformImage( + bitmap : TBitmap; + dstX1 ,dstY1 ,dstX2 ,dstY2 : double ); overload; + + procedure TransformImage( + bitmap : TBitmap; + imgX1 ,imgY1 ,imgX2 ,imgY2 : integer; + parallelo : PDouble ); overload; + + procedure TransformImage(bitmap : TBitmap; parallelo : PDouble ); overload; + + procedure TransformImagePath( + bitmap : TBitmap; + imgX1 ,imgY1 ,imgX2 ,imgY2 : integer; + dstX1 ,dstY1 ,dstX2 ,dstY2 : double ); overload; + + procedure TransformImagePath( + bitmap : TBitmap; + dstX1 ,dstY1 ,dstX2 ,dstY2 : double ); overload; + + procedure TransformImagePath( + bitmap : TBitmap; + imgX1 ,imgY1 ,imgX2 ,imgY2 : integer; + parallelo : PDouble ); overload; + + procedure TransformImagePath(bitmap : TBitmap; parallelo : PDouble ); overload; + + procedure CopyImage( + bitmap : TBitmap; + imgX1 ,imgY1 ,imgX2 ,imgY2 : integer; + dstX ,dstY : double ); overload; + + procedure CopyImage(bitmap : TBitmap; dstX ,dstY : double ); overload; + + private + procedure render(fillColor_ : boolean ); overload; + procedure render(ras : PAggFontRasterizer; sl : PAggFontScanline ); overload; + + procedure addLine(x1 ,y1 ,x2 ,y2 : double ); + procedure updateRasterizerGamma; + procedure renderImage( + img : PAggImage; + x1 ,y1 ,x2 ,y2 : integer; + parl : PDouble ); + + end; + +{ GLOBAL PROCEDURES } +// Standalone API + function Deg2Rad(v : double ) : double; + function Rad2Deg(v : double ) : double; + + function Agg2DUsesFreeType : boolean; + + function BitmapAlphaTransparency(bitmap : TBitmap; alpha : byte ) : boolean; + + +IMPLEMENTATION +{ LOCAL VARIABLES & CONSTANTS } +var + g_approxScale : double = 2.0; + +type + PAggSpanConvImageBlend = ^TAggSpanConvImageBlend; + TAggSpanConvImageBlend = object(span_convertor ) + private + m_mode : TAggBlendMode; + m_color : TAggColor; + m_pixel : pixel_formats_ptr; // m_pixFormatCompPre + + public + constructor Construct(m : TAggBlendMode; c : TAggColor; p : pixel_formats_ptr ); + + procedure convert(span : aggclr_ptr; x ,y : int; len : unsigned ); virtual; + + end; + +{ OPERATOR_IS_EQUAL } +function operator_is_equal(c1 ,c2 : PAggColor ) : boolean; +begin + result:= + (c1.r = c2.r ) and + (c1.g = c2.g ) and + (c1.b = c2.b ) and + (c1.a = c2.a ); + +end; + +{ OPERATOR_IS_NOT_EQUAL } +function operator_is_not_equal(c1 ,c2 : PAggColor ) : boolean; +begin + result:=not operator_is_equal(c1 ,c2 ); + +end; + +{ AGG2DRENDERER_RENDER } +procedure Agg2DRenderer_render( + gr : TAgg2D; + renBase : renderer_base_ptr; + renSolid : renderer_scanline_aa_solid_ptr; + fillColor_ : boolean ); overload; +var + span : span_gradient; + ren : renderer_scanline_aa; + clr : aggclr; + +begin + if (fillColor_ and + (gr.m_fillGradientFlag = AGG_Linear ) ) or + (not fillColor_ and + (gr.m_lineGradientFlag = AGG_Linear ) ) then + if fillColor_ then + begin + span.Construct( + @gr.m_allocator , + @gr.m_fillGradientInterpolator , + @gr.m_linearGradientFunction , + @gr.m_fillGradient , + gr.m_fillGradientD1 , + gr.m_fillGradientD2 ); + + ren.Construct (renBase ,@span ); + render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ren ); + + end + else + begin + span.Construct( + @gr.m_allocator , + @gr.m_lineGradientInterpolator , + @gr.m_linearGradientFunction , + @gr.m_lineGradient , + gr.m_lineGradientD1 , + gr.m_lineGradientD2 ); + + ren.Construct (renBase ,@span ); + render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ren ); + + end + else + if (fillColor_ and + (gr.m_fillGradientFlag = AGG_Radial ) ) or + (not fillColor_ and + (gr.m_lineGradientFlag = AGG_Radial ) ) then + if fillColor_ then + begin + span.Construct( + @gr.m_allocator , + @gr.m_fillGradientInterpolator , + @gr.m_radialGradientFunction , + @gr.m_fillGradient , + gr.m_fillGradientD1 , + gr.m_fillGradientD2 ); + + ren.Construct (renBase ,@span ); + render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ren ); + + end + else + begin + span.Construct( + @gr.m_allocator , + @gr.m_lineGradientInterpolator , + @gr.m_radialGradientFunction , + @gr.m_lineGradient , + gr.m_lineGradientD1 , + gr.m_lineGradientD2 ); + + ren.Construct (renBase ,@span ); + render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ren ); + + end + else + begin + if fillColor_ then + clr.Construct(gr.m_fillColor ) + else + clr.Construct(gr.m_lineColor ); + + renSolid.color_ (@clr ); + render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,renSolid ); + + end; + +end; + +{ AGG2DRENDERER_RENDER } +procedure Agg2DRenderer_render( + gr : TAgg2D; + renBase : renderer_base_ptr; + renSolid : renderer_scanline_aa_solid_ptr; + ras : gray8_adaptor_type_ptr; + sl : gray8_scanline_type_ptr ); overload; +var + span : span_gradient; + ren : renderer_scanline_aa; + clr : aggclr; + +begin + if gr.m_fillGradientFlag = AGG_Linear then + begin + span.Construct( + @gr.m_allocator , + @gr.m_fillGradientInterpolator , + @gr.m_linearGradientFunction , + @gr.m_fillGradient , + gr.m_fillGradientD1 , + gr.m_fillGradientD2 ); + + ren.Construct (renBase ,@span ); + render_scanlines(ras ,sl ,@ren ); + + end + else + if gr.m_fillGradientFlag = AGG_Radial then + begin + span.Construct( + @gr.m_allocator , + @gr.m_fillGradientInterpolator , + @gr.m_radialGradientFunction , + @gr.m_fillGradient , + gr.m_fillGradientD1 , + gr.m_fillGradientD2 ); + + ren.Construct (renBase ,@span ); + render_scanlines(ras ,sl ,@ren ); + + end + else + begin + clr.Construct (gr.m_fillColor ); + renSolid.color_ (@clr ); + render_scanlines(ras ,sl ,renSolid ); + + end; + +end; + +{ AGG2DRENDERER_RENDERIMAGE } +procedure Agg2DRenderer_renderImage( + gr : TAgg2D; + img : PAggImage; + renBase : renderer_base_ptr; + interpolator : span_interpolator_linear_ptr ); +var + blend : TAggSpanConvImageBlend; + + si : span_image_filter_rgba; + sg : span_image_filter_rgba_nn; + sb : span_image_filter_rgba_bilinear; + s2 : span_image_filter_rgba_2x2; + sa : span_image_resample_rgba_affine; + sc : span_converter; + ri : renderer_scanline_aa; + + clr : aggclr; + + resample : boolean; + + sx ,sy : double; + +begin + case gr.m_pixf of + pf32bit : + blend.Construct(gr.m_imageBlendMode ,gr.m_imageBlendColor ,@gr.m_pixFormatCompPre ); + + else + blend.Construct(gr.m_imageBlendMode ,gr.m_imageBlendColor ,NIL ); + + end; + + if gr.m_imageFilter = AGG_NoFilter then + begin + clr.ConstrInt(0 ,0 ,0 ,0 ); + sg.Construct (@gr.m_allocator ,@img.renBuf ,@clr ,interpolator ,rgba_order ); + sc.Construct (@sg ,@blend ); + ri.Construct (renBase ,@sc ); + + render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ri ); + + end + else + begin + resample:=gr.m_imageResample = AGG_ResampleAlways; + + if gr.m_imageResample = AGG_ResampleOnZoomOut then + begin + interpolator._transformer.scaling_abs(@sx ,@sy ); + + if (sx > 1.125 ) or + (sy > 1.125 ) then + resample:=true; + + end; + + if resample then + begin + clr.ConstrInt(0 ,0 ,0 ,0 ); + sa.Construct( + @gr.m_allocator , + @img.renBuf , + @clr , + interpolator , + @gr.m_imageFilterLut , + rgba_order ); + + sc.Construct(@sa ,@blend ); + ri.Construct(renBase ,@sc ); + + render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ri ); + + end + else + if gr.m_imageFilter = AGG_Bilinear then + begin + clr.ConstrInt(0 ,0 ,0 ,0 ); + sb.Construct( + @gr.m_allocator , + @img.renBuf , + @clr , + interpolator , + rgba_order ); + + sc.Construct(@sb ,@blend ); + ri.Construct(renBase ,@sc ); + + render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ri ); + + end + else + if gr.m_imageFilterLut.diameter = 2 then + begin + clr.ConstrInt(0 ,0 ,0 ,0 ); + s2.Construct( + @gr.m_allocator , + @img.renBuf , + @clr , + interpolator, + @gr.m_imageFilterLut , + rgba_order ); + + sc.Construct(@s2 ,@blend ); + ri.Construct(renBase ,@sc ); + + render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ri ); + + end + else + begin + clr.ConstrInt(0 ,0 ,0 ,0 ); + si.Construct( + @gr.m_allocator , + @img.renBuf , + @clr , + interpolator , + @gr.m_imageFilterLut , + rgba_order ); + + sc.Construct(@si ,@blend ); + ri.Construct(renBase ,@sc ); + + render_scanlines(@gr.m_rasterizer ,@gr.m_scanline ,@ri ); + + end; + + end; + +end; + +{ AGG2DUSESFREETYPE } +function Agg2DUsesFreeType : boolean; +begin +{$IFDEF AGG2D_USE_FREETYPE } + result:=true; + +{$ELSE } + result:=false; + +{$ENDIF } + +end; + +{ CONSTRUCT } +constructor TAggSpanConvImageBlend.Construct(m : TAggBlendMode; c : TAggColor; p : pixel_formats_ptr ); +begin + m_mode :=m; + m_color:=c; + m_pixel:=p; + +end; + +{ CONVERT } +procedure TAggSpanConvImageBlend.convert(span : aggclr_ptr; x ,y : int; len : unsigned ); +var + l2 ,a : unsigned; + + s2 : PAggColor; + +begin + if (m_mode <> AGG_BlendDst ) and + (m_pixel <> NIL ) then + begin{!} + l2:=len; + s2:=PAggColor(span ); + + repeat + comp_op_adaptor_clip_to_dst_rgba_pre( + m_pixel , + unsigned(m_mode ) , + int8u_ptr(s2 ) , + m_color.r , + m_color.g , + m_color.b , + base_mask , + cover_full ); + + inc(ptrcomp(s2 ) ,sizeof(aggclr ) ); + dec(l2 ); + + until l2 = 0; + + end; + + if m_color.a < base_mask then + begin + l2:=len; + s2:=PAggColor(span ); + a :=m_color.a; + + repeat + s2.r:=(s2.r * a ) shr base_shift; + s2.g:=(s2.g * a ) shr base_shift; + s2.b:=(s2.b * a ) shr base_shift; + s2.a:=(s2.a * a ) shr base_shift; + + inc(ptrcomp(s2 ) ,sizeof(aggclr ) ); + dec(l2 ); + + until l2 = 0; + + end; + +end; + +{ DEG2RAD } +function deg2Rad(v : double ) : double; +begin + result:=v * agg_basics.pi / 180.0; + +end; + +{ RAD2DEG } +function rad2Deg(v : double ) : double; +begin + result:=v * 180.0 / agg_basics.pi; + +end; + +{ UNIT IMPLEMENTATION } +{ CONSTRUCT } +constructor TAggImage.Construct; +begin + renBuf.Construct; + +end; + +{ DESTRUCT } +destructor TAggImage.Destruct; +begin + renBuf.Destruct; + +end; + +{ ATTACH } +function TAggImage.attach(bitmap : TBitmap; flip : boolean ) : boolean; +var + buffer : pointer; + stride : integer; + +begin + result:=false; + + if Assigned(bitmap ) and + not bitmap.Empty then + case bitmap.PixelFormat of + pf32bit : + begin + { Rendering Buffer } + stride:=integer(bitmap.ScanLine[1 ] ) - integer(bitmap.ScanLine[0 ] ); + + if stride < 0 then + buffer:=bitmap.ScanLine[bitmap.Height - 1 ] + else + buffer:=bitmap.ScanLine[0 ]; + + if flip then + stride:=stride * -1; + + renBuf.attach( + buffer , + bitmap.Width , + bitmap.Height , + stride ); + + { OK } + result:=true; + + end; + + end; + +end; + +{ WIDTH } +function TAggImage.width : int; +begin + result:=renBuf._width; + +end; + +{ HEIGHT } +function TAggImage.height : int; +begin + result:=renBuf._height; + +end; + +{ CONSTRUCT } +constructor TAggRasterizerGamma.Construct(alpha ,gamma : double ); +begin + m_alpha.Construct(alpha ); + m_gamma.Construct(gamma ); + +end; + +{ FUNC_OPERATOR_GAMMA } +function TAggRasterizerGamma.func_operator_gamma(x : double ) : double; +begin + result:=m_alpha.func_operator_gamma(m_gamma.func_operator_gamma(x ) ); + +end; + +{ CREATE } +constructor TAgg2D.Create; +begin + m_rbuf.Construct; + + m_pixf:=pf32bit; + + pixfmt_rgba32 (m_pixFormat ,@m_rbuf ); + pixfmt_custom_blend_rgba(m_pixFormatComp ,@m_rbuf ,@comp_op_adaptor_rgba ,rgba_order ); + pixfmt_rgba32 (m_pixFormatPre ,@m_rbuf ); + pixfmt_custom_blend_rgba(m_pixFormatCompPre ,@m_rbuf ,@comp_op_adaptor_rgba ,rgba_order ); + + m_renBase.Construct (@m_pixFormat ); + m_renBaseComp.Construct (@m_pixFormatComp ); + m_renBasePre.Construct (@m_pixFormatPre ); + m_renBaseCompPre.Construct(@m_pixFormatCompPre ); + + m_renSolid.Construct (@m_renBase ); + m_renSolidComp.Construct(@m_renBaseComp ); + + m_allocator.Construct; + m_clipBox.Construct(0 ,0 ,0 ,0 ); + + m_blendMode :=AGG_BlendAlpha; + m_imageBlendMode:=AGG_BlendDst; + + m_imageBlendColor.Construct(0 ,0 ,0 ); + + m_scanline.Construct; + m_rasterizer.Construct; + + m_masterAlpha :=1.0; + m_antiAliasGamma:=1.0; + + m_fillColor.Construct(255 ,255 ,255 ); + m_lineColor.Construct(0 ,0 ,0 ); + + m_fillGradient.Construct(256 ,sizeof(aggclr ) ); + m_lineGradient.Construct(256 ,sizeof(aggclr ) ); + + m_lineCap :=AGG_CapRound; + m_lineJoin:=AGG_JoinRound; + + m_fillGradientFlag:=AGG_Solid; + m_lineGradientFlag:=AGG_Solid; + + m_fillGradientMatrix.Construct; + m_lineGradientMatrix.Construct; + + m_fillGradientD1:=0.0; + m_lineGradientD1:=0.0; + m_fillGradientD2:=100.0; + m_lineGradientD2:=100.0; + + m_textAngle :=0.0; + m_textAlignX :=AGG_AlignLeft; + m_textAlignY :=AGG_AlignBottom; + m_textHints :=true; + m_fontHeight :=0.0; + m_fontAscent :=0.0; + m_fontDescent:=0.0; + + m_fontCacheType:=AGG_RasterFontCache; + m_imageFilter :=AGG_Bilinear; + m_imageResample:=AGG_NoResample; + + m_gammaNone.Construct; + + m_ifBilinear.Construct; + m_ifHanning.Construct; + m_ifHermite.Construct; + m_ifQuadric.Construct; + m_ifBicubic.Construct; + m_ifCatrom.Construct; + m_ifSpline16.Construct; + m_ifSpline36.Construct; + m_ifBlackman144.Construct; + + m_imageFilterLut.Construct(@m_ifBilinear ,true ); + + m_linearGradientFunction.Construct; + m_radialGradientFunction.Construct; + + m_fillGradientInterpolator.Construct(@m_fillGradientMatrix ); + m_lineGradientInterpolator.Construct(@m_lineGradientMatrix ); + + m_lineWidth :=1; + m_evenOddFlag:=false; + + m_imageFlip:=false; + + m_path.Construct; + m_transform.Construct; + + m_convCurve.Construct (@m_path ); + m_convStroke.Construct(@m_convCurve ); + + m_pathTransform.Construct (@m_convCurve ,@m_transform ); + m_strokeTransform.Construct(@m_convStroke ,@m_transform ); + +{$IFDEF AGG2D_USE_FREETYPE } + m_fontEngine.Construct; + +{$ELSE } + m_fontDC:=GetDC(0 ); + + m_fontEngine.Construct(m_fontDC ); + +{$ENDIF } + + m_fontCacheManager.Construct(@m_fontEngine ); + + LineCap (m_lineCap ); + LineJoin(m_lineJoin ); + +end; + +{ DESTROY } +destructor TAgg2D.Destroy; +begin + m_rbuf.Destruct; + + m_allocator.Destruct; + + m_scanline.Destruct; + m_rasterizer.Destruct; + + m_fillGradient.Destruct; + m_lineGradient.Destruct; + + m_imageFilterLut.Destruct; + m_path.Destruct; + + m_convCurve.Destruct; + m_convStroke.Destruct; + + m_fontEngine.Destruct; + m_fontCacheManager.Destruct; + +{$IFNDEF AGG2D_USE_FREETYPE } + ReleaseDC(0 ,m_fontDC ); + +{$ENDIF } + +end; + +{ ATTACH } +function TAgg2D.Attach(bitmap : TBitmap; flip_y : boolean = false ) : boolean; +var + buffer : pointer; + stride : integer; + +begin + result:=false; + + if Assigned(bitmap ) and + not bitmap.Empty then + case bitmap.PixelFormat of + pf24bit ,pf32bit : + begin + { Rendering Buffer } + stride:=integer(bitmap.ScanLine[1 ] ) - integer(bitmap.ScanLine[0 ] ); + + if stride < 0 then + buffer:=bitmap.ScanLine[bitmap.Height - 1 ] + else + buffer:=bitmap.ScanLine[0 ]; + + if flip_y then + stride:=stride * -1; + + m_rbuf.attach( + buffer , + bitmap.Width , + bitmap.Height , + stride ); + + { Pixel Format } + m_pixf:=bitmap.PixelFormat; + + case m_pixf of + pf24bit : + begin + pixfmt_rgb24(m_pixFormat ,@m_rbuf ); + pixfmt_rgb24(m_pixFormatPre ,@m_rbuf ); + + end; + + pf32bit : + begin + pixfmt_rgba32 (m_pixFormat ,@m_rbuf ); + pixfmt_custom_blend_rgba(m_pixFormatComp ,@m_rbuf ,@comp_op_adaptor_rgba ,rgba_order ); + pixfmt_rgba32 (m_pixFormatPre ,@m_rbuf ); + pixfmt_custom_blend_rgba(m_pixFormatCompPre ,@m_rbuf ,@comp_op_adaptor_rgba ,rgba_order ); + + end; + + end; + + { Reset state } + m_renBase.reset_clipping (true ); + m_renBaseComp.reset_clipping (true ); + m_renBasePre.reset_clipping (true ); + m_renBaseCompPre.reset_clipping(true ); + + ResetTransformations; + + LineWidth(1.0 ); + LineColor(0 ,0 ,0 ); + FillColor(255 ,255 ,255 ); + + TextAlignment(AGG_AlignLeft ,AGG_AlignBottom ); + + ClipBox (0 ,0 ,bitmap.Width ,bitmap.Height ); + LineCap (AGG_CapRound ); + LineJoin(AGG_JoinRound ); + FlipText(false ); + + ImageFilter (AGG_Bilinear ); + ImageResample(AGG_NoResample ); + ImageFlip (false ); + + m_masterAlpha :=1.0; + m_antiAliasGamma:=1.0; + + m_rasterizer.gamma(@m_gammaNone ); + + m_blendMode:=AGG_BlendAlpha; + + FillEvenOdd(false ); + BlendMode (AGG_BlendAlpha ); + + FlipText(false ); + ResetPath; + + ImageFilter (AGG_Bilinear ); + ImageResample(AGG_NoResample ); + + { OK } + result:=true; + + end; + + end; + +end; + +{ CLIPBOX } +procedure TAgg2D.ClipBox(x1 ,y1 ,x2 ,y2 : double ); +var + rx1 ,ry1 ,rx2 ,ry2 : int; + +begin + m_clipBox.Construct(x1 ,y1 ,x2 ,y2 ); + + rx1:=Trunc(x1 ); + ry1:=Trunc(y1 ); + rx2:=Trunc(x2 ); + ry2:=Trunc(y2 ); + + m_renBase.clip_box_ (rx1 ,ry1 ,rx2 ,ry2 ); + m_renBaseComp.clip_box_ (rx1 ,ry1 ,rx2 ,ry2 ); + m_renBasePre.clip_box_ (rx1 ,ry1 ,rx2 ,ry2 ); + m_renBaseCompPre.clip_box_(rx1 ,ry1 ,rx2 ,ry2 ); + + m_rasterizer.clip_box(x1 ,y1 ,x2 ,y2 ); + +end; + +{ CLIPBOX } +function TAgg2D.ClipBox : TAggRectD; +begin + result:=m_clipBox; + +end; + +{ CLEARALL } +procedure TAgg2D.ClearAll(c : TAggColor ); +var + clr : aggclr; + +begin + clr.Construct (c ); + m_renBase.clear(@clr ); + +end; + +{ CLEARALL } +procedure TAgg2D.ClearAll(r ,g ,b : byte; a : byte = 255 ); +var + clr : TAggColor; + +begin + clr.Construct(r ,g ,b ,a ); + ClearAll (clr ); + +end; + +{ CLEARCLIPBOX } +procedure TAgg2D.ClearClipBox(c : TAggColor ); +var + clr : aggclr; + +begin + clr.Construct(c ); + + m_renBase.copy_bar(0 ,0 ,m_renBase.width ,m_renBase.height ,@clr ); + +end; + +{ CLEARCLIPBOX } +procedure TAgg2D.ClearClipBox(r ,g ,b : byte; a : byte = 255 ); +var + clr : TAggColor; + +begin + clr.Construct(r ,g ,b ,a ); + ClearClipBox (clr ); + +end; + +{ WORLDTOSCREEN } +procedure TAgg2D.WorldToScreen(x ,y : PDouble ); +begin + m_transform.transform(@m_transform ,double_ptr(x ) ,double_ptr(y ) ); + +end; + +{ SCREENTOWORLD } +procedure TAgg2D.ScreenToWorld(x ,y : PDouble ); +begin + m_transform.inverse_transform(@m_transform ,double_ptr(x ) ,double_ptr(y ) ); + +end; + +{ WORLDTOSCREEN } +function TAgg2D.WorldToScreen(scalar : double ) : double; +var + x1 ,y1 ,x2 ,y2 : double; + +begin + x1:=0; + y1:=0; + x2:=scalar; + y2:=scalar; + + WorldToScreen(@x1 ,@y1 ); + WorldToScreen(@x2 ,@y2 ); + + result:=Sqrt((x2 - x1 ) * (x2 - x1 ) + (y2 - y1 ) * (y2 - y1 ) ) * 0.7071068; + +end; + +{ SCREENTOWORLD } +function TAgg2D.ScreenToWorld(scalar : double ) : double; +var + x1 ,y1 ,x2 ,y2 : double; + +begin + x1:=0; + y1:=0; + x2:=scalar; + y2:=scalar; + + ScreenToWorld(@x1 ,@y1 ); + ScreenToWorld(@x2 ,@y2 ); + + result:=Sqrt((x2 - x1 ) * (x2 - x1 ) + (y2 - y1 ) * (y2 - y1 ) ) * 0.7071068; + +end; + +{ ALIGNPOINT } +procedure TAgg2D.AlignPoint(x ,y : PDouble ); +begin + WorldToScreen(x ,y ); + + x^:=Floor(x^ ) + 0.5; + y^:=Floor(y^ ) + 0.5; + + ScreenToWorld(x ,y ); + +end; + +{ INBOX } +function TAgg2D.InBox(worldX ,worldY : double ) : boolean; +begin + WorldToScreen(@worldX ,@worldY ); + + result:=m_renBase.inbox(Trunc(worldX ) ,Trunc(worldY ) ); + +end; + +{ BLENDMODE } +procedure TAgg2D.BlendMode(m : TAggBlendMode ); +begin + m_blendMode:=m; + + m_pixFormatComp.comp_op_ (unsigned(m ) ); + m_pixFormatCompPre.comp_op_(unsigned(m ) ); + +end; + +{ BLENDMODE } +function TAgg2D.BlendMode : TAggBlendMode; +begin + result:=m_blendMode; + +end; + +{ MASTERALPHA } +procedure TAgg2D.MasterAlpha(a : double ); +begin + m_masterAlpha:=a; + + UpdateRasterizerGamma; + +end; + +{ MASTERALPHA } +function TAgg2D.MasterAlpha : double; +begin + result:=m_masterAlpha; + +end; + +{ ANTIALIASGAMMA } +procedure TAgg2D.AntiAliasGamma(g : double ); +begin + m_antiAliasGamma:=g; + + UpdateRasterizerGamma; + +end; + +{ ANTIALIASGAMMA } +function TAgg2D.AntiAliasGamma : double; +begin + result:=m_antiAliasGamma; + +end; + +{ FILLCOLOR } +procedure TAgg2D.FillColor(c : TAggColor ); +begin + m_fillColor :=c; + m_fillGradientFlag:=AGG_Solid; + +end; + +{ FILLCOLOR } +procedure TAgg2D.FillColor(r ,g ,b : byte; a : byte = 255 ); +var + clr : TAggColor; + +begin + clr.Construct(r ,g ,b ,a ); + FillColor (clr ); + +end; + +{ NOFILL } +procedure TAgg2D.NoFill; +var + clr : TAggColor; + +begin + clr.Construct(0 ,0 ,0 ,0 ); + FillColor (clr ); + +end; + +{ LINECOLOR } +procedure TAgg2D.LineColor(c : TAggColor ); +begin + m_lineColor :=c; + m_lineGradientFlag:=AGG_Solid; + +end; + +{ LINECOLOR } +procedure TAgg2D.LineColor(r ,g ,b : byte; a : byte = 255 ); +var + clr : TAggColor; + +begin + clr.Construct(r ,g ,b ,a ); + LineColor (clr ); + +end; + +{ NOLINE } +procedure TAgg2D.NoLine; +var + clr : TAggColor; + +begin + clr.Construct(0 ,0 ,0 ,0 ); + LineColor (clr ); + +end; + +{ FILLCOLOR } +function TAgg2D.FillColor : TAggColor; +begin + result:=m_fillColor; + +end; + +{ LINECOLOR } +function TAgg2D.LineColor : TAggColor; +begin + result:=m_lineColor; + +end; + +{ FILLLINEARGRADIENT } +procedure TAgg2D.FillLinearGradient(x1 ,y1 ,x2 ,y2 : double; c1 ,c2 : TAggColor; profile : double = 1.0 ); +var + i ,startGradient ,endGradient : int; + + k ,angle : double; + + c : TAggColor; + + clr : aggclr; + tar : trans_affine_rotation; + tat : trans_affine_translation; + +begin + startGradient:=128 - Trunc(profile * 127.0 ); + endGradient :=128 + Trunc(profile * 127.0 ); + + if endGradient <= startGradient then + endGradient:=startGradient + 1; + + k:=1.0 / (endGradient - startGradient ); + i:=0; + + while i < startGradient do + begin + clr.Construct(c1 ); + + move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) ); + inc (i ); + + end; + + while i < endGradient do + begin + c:=c1.gradient(c2 ,(i - startGradient ) * k ); + + clr.Construct(c ); + + move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) ); + inc (i ); + + end; + + while i < 256 do + begin + clr.Construct(c2 ); + + move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) ); + inc (i ); + + end; + + angle:=ArcTan2(y2 - y1 ,x2 - x1 ); + + m_fillGradientMatrix.reset; + + tar.Construct(angle ); + + m_fillGradientMatrix.multiply(@tar ); + + tat.Construct(x1 ,y1 ); + + m_fillGradientMatrix.multiply(@tat ); + m_fillGradientMatrix.multiply(@m_transform ); + m_fillGradientMatrix.invert; + + m_fillGradientD1 :=0.0; + m_fillGradientD2 :=Sqrt((x2 - x1 ) * (x2 - x1 ) + (y2 - y1 ) * (y2 - y1 ) ); + m_fillGradientFlag:=AGG_Linear; + + m_fillColor.Construct(0 ,0 ,0 ); // Set some real color + +end; + +{ LINELINEARGRADIENT } +procedure TAgg2D.LineLinearGradient(x1 ,y1 ,x2 ,y2 : double; c1 ,c2 : TAggColor; profile : double = 1.0 ); +var + i ,startGradient ,endGradient : int; + + k ,angle : double; + + c : TAggColor; + + clr : aggclr; + tar : trans_affine_rotation; + tat : trans_affine_translation; + +begin + startGradient:=128 - Trunc(profile * 128.0 ); + endGradient :=128 + Trunc(profile * 128.0 ); + + if endGradient <= startGradient then + endGradient:=startGradient + 1; + + k:=1.0 / (endGradient - startGradient ); + i:=0; + + while i < startGradient do + begin + clr.Construct(c1 ); + + move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) ); + inc (i ); + + end; + + while i < endGradient do + begin + c:=c1.gradient(c2 ,(i - startGradient) * k ); + + clr.Construct(c ); + + move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) ); + inc (i ); + + end; + + while i < 256 do + begin + clr.Construct(c2 ); + + move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) ); + inc (i ); + + end; + + angle:=ArcTan2(y2 - y1 ,x2 - x1 ); + + m_lineGradientMatrix.reset; + + tar.Construct(angle ); + + m_lineGradientMatrix.multiply(@tar ); + + tat.Construct(x1 ,y1 ); + + m_lineGradientMatrix.multiply(@tat ); + m_lineGradientMatrix.multiply(@m_transform ); + m_lineGradientMatrix.invert; + + m_lineGradientD1 :=0.0; + m_lineGradientD2 :=Sqrt((x2 - x1 ) * (x2 - x1 ) + (y2 - y1 ) * (y2 - y1 ) ); + m_lineGradientFlag:=AGG_Linear; + + m_lineColor.Construct(0 ,0 ,0 ); // Set some real color + +end; + +{ FILLRADIALGRADIENT } +procedure TAgg2D.FillRadialGradient(x ,y ,r : double; c1 ,c2 : TAggColor; profile : double = 1.0 ); +var + i ,startGradient ,endGradient : int; + + k : double; + c : TAggColor; + + clr : aggclr; + tat : trans_affine_translation; + +begin + startGradient:=128 - Trunc(profile * 127.0 ); + endGradient :=128 + Trunc(profile * 127.0 ); + + if endGradient <= startGradient then + endGradient:=startGradient + 1; + + k:=1.0 / (endGradient - startGradient ); + i:=0; + + while i < startGradient do + begin + clr.Construct(c1 ); + + move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) ); + inc (i ); + + end; + + while i < endGradient do + begin + c:=c1.gradient(c2 ,(i - startGradient ) * k ); + + clr.Construct(c ); + + move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) ); + inc (i ); + + end; + + while i < 256 do + begin + clr.Construct(c2 ); + + move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) ); + inc (i ); + + end; + + m_fillGradientD2:=worldToScreen(r ); + + WorldToScreen(@x ,@y ); + + m_fillGradientMatrix.reset; + + tat.Construct(x ,y ); + + m_fillGradientMatrix.multiply(@tat ); + m_fillGradientMatrix.invert; + + m_fillGradientD1 :=0; + m_fillGradientFlag:=AGG_Radial; + + m_fillColor.Construct(0 ,0 ,0 ); // Set some real color + +end; + +{ LINERADIALGRADIENT } +procedure TAgg2D.LineRadialGradient(x ,y ,r : double; c1 ,c2 : TAggColor; profile : double = 1.0 ); +var + i ,startGradient ,endGradient : int; + + k : double; + c : TAggColor; + + clr : aggclr; + tat : trans_affine_translation; + +begin + startGradient:=128 - Trunc(profile * 128.0 ); + endGradient :=128 + Trunc(profile * 128.0 ); + + if endGradient <= startGradient then + endGradient:=startGradient + 1; + + k:=1.0 / (endGradient - startGradient ); + i:=0; + + while i < startGradient do + begin + clr.Construct(c1 ); + + move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) ); + inc (i ); + + end; + + while i < endGradient do + begin + c:=c1.gradient(c2 ,(i - startGradient ) * k ); + + clr.Construct(c ); + + move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) ); + inc (i ); + + end; + + while i < 256 do + begin + clr.Construct(c2 ); + + move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) ); + inc (i ); + + end; + + m_lineGradientD2:=worldToScreen(r ); + + WorldToScreen(@x ,@y ); + + m_lineGradientMatrix.reset; + + tat.Construct(x ,y ); + + m_lineGradientMatrix.multiply(@tat ); + m_lineGradientMatrix.invert; + + m_lineGradientD1 :=0; + m_lineGradientFlag:=AGG_Radial; + + m_lineColor.Construct(0 ,0 ,0 ); // Set some real color + +end; + +{ FILLRADIALGRADIENT } +procedure TAgg2D.FillRadialGradient(x ,y ,r : double; c1 ,c2 ,c3 : TAggColor ); +var + i : int; + c : TAggColor; + + clr : aggclr; + tat : trans_affine_translation; + +begin + i:=0; + + while i < 128 do + begin + c:=c1.gradient(c2 ,i / 127.0 ); + + clr.Construct(c ); + + move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) ); + inc (i ); + + end; + + while i < 256 do + begin + c:=c2.gradient(c3 ,(i - 128 ) / 127.0 ); + + clr.Construct(c ); + + move(clr ,m_fillGradient.array_operator(i )^ ,sizeof(aggclr ) ); + inc (i ); + + end; + + m_fillGradientD2:=worldToScreen(r ); + + WorldToScreen(@x ,@y ); + + m_fillGradientMatrix.reset; + + tat.Construct(x ,y ); + + m_fillGradientMatrix.multiply(@tat ); + m_fillGradientMatrix.invert; + + m_fillGradientD1 :=0; + m_fillGradientFlag:=AGG_Radial; + + m_fillColor.Construct(0 ,0 ,0 ); // Set some real color + +end; + +{ LINERADIALGRADIENT } +procedure TAgg2D.LineRadialGradient(x ,y ,r : double; c1 ,c2 ,c3 : TAggColor ); +var + i : int; + c : TAggColor; + + clr : aggclr; + tat : trans_affine_translation; + +begin + i:=0; + + while i < 128 do + begin + c:=c1.gradient(c2 ,i / 127.0 ); + + clr.Construct(c ); + + move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) ); + inc (i ); + + end; + + while i < 256 do + begin + c:=c2.gradient(c3 ,(i - 128 ) / 127.0 ); + + clr.Construct(c ); + + move(clr ,m_lineGradient.array_operator(i )^ ,sizeof(aggclr ) ); + inc (i ); + + end; + + m_lineGradientD2:=worldToScreen(r ); + + WorldToScreen(@x ,@y ); + + m_lineGradientMatrix.reset; + + tat.Construct(x ,y ); + + m_lineGradientMatrix.multiply(@tat ); + m_lineGradientMatrix.invert; + + m_lineGradientD1 :=0; + m_lineGradientFlag:=AGG_Radial; + + m_lineColor.Construct(0 ,0 ,0 ); // Set some real color + +end; + +{ FILLRADIALGRADIENT } +procedure TAgg2D.FillRadialGradient(x ,y ,r : double ); +var + tat : trans_affine_translation; + +begin + m_fillGradientD2:=worldToScreen(r ); + + WorldToScreen(@x ,@y ); + + m_fillGradientMatrix.reset; + + tat.Construct(x ,y ); + + m_fillGradientMatrix.multiply(@tat ); + m_fillGradientMatrix.invert; + + m_fillGradientD1:=0; + +end; + +{ LINERADIALGRADIENT } +procedure TAgg2D.LineRadialGradient(x ,y ,r : double ); +var + tat : trans_affine_translation; + +begin + m_lineGradientD2:=worldToScreen(r ); + + WorldToScreen(@x ,@y ); + + m_lineGradientMatrix.reset; + + tat.Construct(x ,y ); + + m_lineGradientMatrix.multiply(@tat ); + m_lineGradientMatrix.invert; + + m_lineGradientD1:=0; + +end; + +{ LINEWIDTH } +procedure TAgg2D.LineWidth(w : double ); +begin + m_lineWidth:=w; + + m_convStroke.width_(w ); + +end; + +{ LINEWIDTH } +function TAgg2D.LineWidth : double; +begin + result:=m_lineWidth; + +end; + +{ LINECAP } +procedure TAgg2D.LineCap(cap : TAggLineCap ); +begin + m_lineCap:=cap; + + m_convStroke.line_cap_(cap ); + +end; + +{ LINECAP } +function TAgg2D.LineCap : TAggLineCap; +begin + result:=m_lineCap; + +end; + +{ LINEJOIN } +procedure TAgg2D.LineJoin(join : TAggLineJoin ); +begin + m_lineJoin:=join; + + m_convStroke.line_join_(join ); + +end; + +{ LINEJOIN } +function TAgg2D.LineJoin : TAggLineJoin; +begin + result:=m_lineJoin; + +end; + +{ FILLEVENODD } +procedure TAgg2D.FillEvenOdd(evenOddFlag : boolean ); +begin + m_evenOddFlag:=evenOddFlag; + + if evenOddFlag then + m_rasterizer.filling_rule(fill_even_odd ) + else + m_rasterizer.filling_rule(fill_non_zero ); + +end; + +{ FILLEVENODD } +function TAgg2D.FillEvenOdd : boolean; +begin + result:=m_evenOddFlag; + +end; + +{ TRANSFORMATIONS } +function TAgg2D.Transformations : TAggTransformations; +begin + m_transform.store_to(@result.affineMatrix[0 ] ); + +end; + +{ TRANSFORMATIONS } +procedure TAgg2D.Transformations(tr : PAggTransformations ); +begin + m_transform.load_from(@tr.affineMatrix[0 ] ); + + m_convCurve.approximation_scale_ (worldToScreen(1.0 ) * g_approxScale ); + m_convStroke.approximation_scale_(worldToScreen(1.0 ) * g_approxScale ); + +end; + +{ RESETTRANSFORMATIONS } +procedure TAgg2D.ResetTransformations; +begin + m_transform.reset; + +end; + +{ AFFINE } +procedure TAgg2D.Affine(tr : PAggAffine ); +begin + m_transform.multiply(tr ); + + m_convCurve.approximation_scale_ (WorldToScreen(1.0 ) * g_approxScale ); + m_convStroke.approximation_scale_(WorldToScreen(1.0 ) * g_approxScale ); + +end; + +{ AFFINE } +procedure TAgg2D.Affine(tr : PAggTransformations ); +var + ta : trans_affine; + +begin + ta.Construct( + tr.affineMatrix[0 ] ,tr.affineMatrix[1 ] ,tr.affineMatrix[2 ] , + tr.affineMatrix[3 ] ,tr.affineMatrix[4 ] ,tr.affineMatrix[5 ] ); + + affine(PAggAffine(@ta ) ); + +end; + +{ ROTATE } +procedure TAgg2D.Rotate(angle : double ); +var + tar : trans_affine_rotation; + +begin + tar.Construct(angle ); + + m_transform.multiply(@tar ); + +end; + +{ SCALE } +procedure TAgg2D.Scale(sx ,sy : double ); +var + tas : trans_affine_scaling; + +begin + tas.Construct(sx ,sy ); + + m_transform.multiply(@tas ); + + m_convCurve.approximation_scale_ (worldToScreen(1.0 ) * g_approxScale ); + m_convStroke.approximation_scale_(worldToScreen(1.0 ) * g_approxScale ); + +end; + +{ SKEW } +procedure TAgg2D.Skew(sx ,sy : double ); +var + tas : trans_affine_skewing; + +begin + tas.Construct(sx ,sy ); + + m_transform.multiply(@tas ); + +end; + +{ TRANSLATE } +procedure TAgg2D.Translate(x ,y : double ); +var + tat : trans_affine_translation; + +begin + tat.Construct(x ,y ); + + m_transform.multiply(@tat ); + +end; + +{ PARALLELOGRAM } +procedure TAgg2D.Parallelogram(x1 ,y1 ,x2 ,y2 : double; para : PDouble ); +var + ta : trans_affine; + +begin + ta.Construct(x1 ,y1 ,x2 ,y2 ,parallelo_ptr(para ) ); + + m_transform.multiply(@ta ); + + m_convCurve.approximation_scale_ (worldToScreen(1.0 ) * g_approxScale ); + m_convStroke.approximation_scale_(worldToScreen(1.0 ) * g_approxScale ); + +end; + +{ VIEWPORT } +procedure TAgg2D.Viewport( + worldX1 ,worldY1 ,worldX2 ,worldY2 , + screenX1 ,screenY1 ,screenX2 ,screenY2 : double; + opt : TAggViewportOption = AGG_XMidYMid ); +var + vp : trans_viewport; + mx : trans_affine; + +begin + vp.Construct; + + case opt of + AGG_Anisotropic : + vp.preserve_aspect_ratio(0.0 ,0.0 ,aspect_ratio_stretch ); + + AGG_XMinYMin : + vp.preserve_aspect_ratio(0.0 ,0.0 ,aspect_ratio_meet ); + + AGG_XMidYMin : + vp.preserve_aspect_ratio(0.5 ,0.0 ,aspect_ratio_meet ); + + AGG_XMaxYMin : + vp.preserve_aspect_ratio(1.0 ,0.0 ,aspect_ratio_meet ); + + AGG_XMinYMid : + vp.preserve_aspect_ratio(0.0 ,0.5 ,aspect_ratio_meet ); + + AGG_XMidYMid : + vp.preserve_aspect_ratio(0.5 ,0.5 ,aspect_ratio_meet ); + + AGG_XMaxYMid : + vp.preserve_aspect_ratio(1.0 ,0.5 ,aspect_ratio_meet ); + + AGG_XMinYMax : + vp.preserve_aspect_ratio(0.0 ,1.0 ,aspect_ratio_meet ); + + AGG_XMidYMax : + vp.preserve_aspect_ratio(0.5 ,1.0 ,aspect_ratio_meet ); + + AGG_XMaxYMax : + vp.preserve_aspect_ratio(1.0 ,1.0 ,aspect_ratio_meet ); + + end; + + vp.world_viewport (worldX1 ,worldY1 ,worldX2 ,worldY2 ); + vp.device_viewport(screenX1 ,screenY1 ,screenX2 ,screenY2 ); + + mx.Construct; + + vp.to_affine (@mx ); + m_transform.multiply(@mx ); + + m_convCurve.approximation_scale_ (WorldToScreen(1.0 ) * g_approxScale ); + m_convStroke.approximation_scale_(WorldToScreen(1.0 ) * g_approxScale ); + +end; + +{ LINE } +procedure TAgg2D.Line(x1 ,y1 ,x2 ,y2 : double ); +begin + m_path.remove_all; + + addLine (x1 ,y1 ,x2 ,y2 ); + DrawPath(AGG_StrokeOnly ); + +end; + +{ TRIANGLE } +procedure TAgg2D.Triangle(x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double ); +begin + m_path.remove_all; + m_path.move_to(x1 ,y1 ); + m_path.line_to(x2 ,y2 ); + m_path.line_to(x3 ,y3 ); + m_path.close_polygon; + + DrawPath(AGG_FillAndStroke ); + +end; + +{ RECTANGLE } +procedure TAgg2D.Rectangle(x1 ,y1 ,x2 ,y2 : double ); +begin + m_path.remove_all; + m_path.move_to(x1 ,y1 ); + m_path.line_to(x2 ,y1 ); + m_path.line_to(x2 ,y2 ); + m_path.line_to(x1 ,y2 ); + m_path.close_polygon; + + DrawPath(AGG_FillAndStroke ); + +end; + +{ ROUNDEDRECT } +procedure TAgg2D.RoundedRect(x1 ,y1 ,x2 ,y2 ,r : double ); +var + rc : rounded_rect; + +begin + m_path.remove_all; + rc.Construct(x1 ,y1 ,x2 ,y2 ,r ); + + rc.normalize_radius; + rc.approximation_scale_(worldToScreen(1.0 ) * g_approxScale ); + + m_path.add_path(@rc ,0 ,false ); + + DrawPath(AGG_FillAndStroke ); + +end; + +{ ROUNDEDRECT } +procedure TAgg2D.RoundedRect(x1 ,y1 ,x2 ,y2 ,rx ,ry : double ); +var + rc : rounded_rect; + +begin + m_path.remove_all; + rc.Construct; + + rc.rect (x1 ,y1 ,x2 ,y2 ); + rc.radius(rx ,ry ); + rc.normalize_radius; + + m_path.add_path(@rc ,0 ,false ); + + DrawPath(AGG_FillAndStroke ); + +end; + +{ ROUNDEDRECT } +procedure TAgg2D.RoundedRect( + x1 ,y1 ,x2 ,y2 , + rxBottom ,ryBottom , + rxTop ,ryTop : double ); +var + rc : rounded_rect; + +begin + m_path.remove_all; + rc.Construct; + + rc.rect (x1 ,y1 ,x2 ,y2 ); + rc.radius(rxBottom ,ryBottom ,rxTop ,ryTop ); + rc.normalize_radius; + + rc.approximation_scale_(worldToScreen(1.0 ) * g_approxScale ); + + m_path.add_path(@rc ,0 ,false ); + + DrawPath(AGG_FillAndStroke ); + +end; + +{ ELLIPSE } +procedure TAgg2D.Ellipse(cx ,cy ,rx ,ry : double ); +var + el : bezier_arc; + +begin + m_path.remove_all; + + el.Construct(cx ,cy ,rx ,ry ,0 ,2 * pi ); + + m_path.add_path(@el ,0 ,false ); + m_path.close_polygon; + + DrawPath(AGG_FillAndStroke ); + +end; + +{ ARC } +procedure TAgg2D.Arc(cx ,cy ,rx ,ry ,start ,sweep : double ); +var + ar : {bezier_}agg_arc.arc; + +begin + m_path.remove_all; + + ar.Construct(cx ,cy ,rx ,ry ,sweep ,start ,false ); + + m_path.add_path(@ar ,0 ,false ); + + DrawPath(AGG_StrokeOnly ); + +end; + +{ STAR } +procedure TAgg2D.Star(cx ,cy ,r1 ,r2 ,startAngle : double; numRays : integer ); +var + da ,a ,x ,y : double; + + i : int; + +begin + m_path.remove_all; + + da:=pi / numRays; + a :=startAngle; + + i:=0; + + while i < numRays do + begin + x:=Cos(a ) * r2 + cx; + y:=Sin(a ) * r2 + cy; + + if i <> 0 then + m_path.line_to(x ,y ) + else + m_path.move_to(x ,y ); + + a:=a + da; + + m_path.line_to(Cos(a ) * r1 + cx ,Sin(a ) * r1 + cy ); + + a:=a + da; + + inc(i ); + + end; + + ClosePolygon; + DrawPath(AGG_FillAndStroke ); + +end; + +{ CURVE } +procedure TAgg2D.Curve(x1 ,y1 ,x2 ,y2 ,x3 ,y3 : double ); +begin + m_path.remove_all; + m_path.move_to(x1 ,y1 ); + m_path.curve3 (x2 ,y2 ,x3 ,y3 ); + + DrawPath(AGG_StrokeOnly ); + +end; + +{ CURVE } +procedure TAgg2D.Curve(x1 ,y1 ,x2 ,y2 ,x3 ,y3 ,x4 ,y4 : double ); +begin + m_path.remove_all; + m_path.move_to(x1 ,y1 ); + m_path.curve4 (x2 ,y2 ,x3 ,y3 ,x4 ,y4 ); + + DrawPath(AGG_StrokeOnly ); + +end; + +{ POLYGON } +procedure TAgg2D.Polygon(xy : PDouble; numPoints : integer ); +begin + m_path.remove_all; + m_path.add_poly(double_2_ptr(xy ) ,numPoints ); + + ClosePolygon; + DrawPath(AGG_FillAndStroke ); + +end; + +{ POLYLINE } +procedure TAgg2D.Polyline(xy : PDouble; numPoints : integer ); +begin + m_path.remove_all; + m_path.add_poly(double_2_ptr(xy ) ,numPoints ); + + DrawPath(AGG_StrokeOnly ); + +end; + +{ FLIPTEXT } +procedure TAgg2D.FlipText(flip : boolean ); +begin + m_fontEngine.flip_y_(not flip ); + +end; + +{ FONT } +procedure TAgg2D.Font( + fileName : AnsiString; height : double; + bold : boolean = false; + italic : boolean = false; + cache : TAggFontCacheType = AGG_VectorFontCache; + angle : double = 0.0 ); +var + b : int; + +begin + m_textAngle :=angle; + m_fontHeight :=height; + m_fontCacheType:=cache; + +{$IFDEF AGG2D_USE_FREETYPE } + if cache = AGG_VectorFontCache then + m_fontEngine.load_font(PChar(@fileName[1 ] ) ,0 ,glyph_ren_outline ) + else + m_fontEngine.load_font(PChar(@fileName[1 ] ) ,0 ,glyph_ren_agg_gray8 ); + + m_fontEngine.hinting_(m_textHints ); + + if cahce = AGG_VectorFontCache then + m_fontEngine.height_(height ) + else + m_fontEngine.height_(worldToScreen(height ) ); + +{$ELSE } + m_fontEngine.hinting_(m_textHints ); + + if bold then + b:=700 + else + b:=400; + + if cache = AGG_VectorFontCache then + m_fontEngine.create_font_(PChar(@fileName[1 ] ) ,glyph_ren_outline ,height ,0.0 ,b ,italic ) + else + m_fontEngine.create_font_(PChar(@fileName[1 ] ) ,glyph_ren_agg_gray8 ,worldToScreen(height) ,0.0 ,b ,italic ); + +{$ENDIF } + +end; + +{ FONTHEIGHT } +function TAgg2D.FontHeight : double; +begin + result:=m_fontHeight; + +end; + +{ TEXTALIGNMENT } +procedure TAgg2D.TextAlignment(alignX ,alignY : TAggTextAlignment ); +begin + m_textAlignX:=alignX; + m_textAlignY:=alignY; + +end; + +{ TEXTHINTS } +function TAgg2D.TextHints : boolean; +begin + result:=m_textHints; + +end; + +{ TEXTHINTS } +procedure TAgg2D.TextHints(hints : boolean ); +begin + m_textHints:=hints; + +end; + +{ TEXTWIDTH } +function TAgg2D.TextWidth(str : AnsiString ) : double; +var + x ,y : double; + first : boolean; + glyph : glyph_cache_ptr; + str_ : PChar; + +begin + x:=0; + y:=0; + + first:=true; + str_ :=@str[1 ]; + + while str_^ <> #0 do + begin + glyph:=m_fontCacheManager.glyph(int32u(str_^ ) ); + + if glyph <> NIL then + begin + if not first then + m_fontCacheManager.add_kerning(@x ,@y ); + + x:=x + glyph.advance_x; + y:=y + glyph.advance_y; + + first:=false; + + end; + + inc(ptrcomp(str_ ) ); + + end; + + if m_fontCacheType = AGG_VectorFontCache then + result:=x + else + result:=ScreenToWorld(x ); + +end; + +{ TEXT } +procedure TAgg2D.Text( + x ,y : double; str : AnsiString; + roundOff : boolean = false; + ddx : double = 0.0; + ddy : double = 0.0 ); +var + dx ,dy ,asc ,start_x ,start_y : double; + + glyph : glyph_cache_ptr; + + mtx : trans_affine; + str_ : PChar; + + i : int; + + tat : trans_affine_translation; + tar : trans_affine_rotation; + + tr : conv_transform; + +begin + dx:=0.0; + dy:=0.0; + + case m_textAlignX of + AGG_AlignCenter : + dx:=-textWidth(str ) * 0.5; + + AGG_AlignRight : + dx:=-textWidth(str ); + + end; + + asc :=fontHeight; + glyph:=m_fontCacheManager.glyph(int32u('H' ) ); + + if glyph <> NIL then + asc:=glyph.bounds.y2 - glyph.bounds.y1; + + if m_fontCacheType = AGG_RasterFontCache then + asc:=screenToWorld(asc ); + + case m_textAlignY of + AGG_AlignCenter : + dy:=-asc * 0.5; + + AGG_AlignTop : + dy:=-asc; + + end; + + if m_fontEngine._flip_y then + dy:=-dy; + + mtx.Construct; + + start_x:=x + dx; + start_y:=y + dy; + + if roundOff then + begin + start_x:=Trunc(start_x ); + start_y:=Trunc(start_y ); + + end; + + start_x:=start_x + ddx; + start_y:=start_y + ddy; + + tat.Construct(-x ,-y ); + mtx.multiply (@tat ); + + tar.Construct(m_textAngle ); + mtx.multiply (@tar ); + + tat.Construct(x ,y ); + mtx.multiply (@tat ); + + tr.Construct(m_fontCacheManager.path_adaptor ,@mtx ); + + if m_fontCacheType = AGG_RasterFontCache then + WorldToScreen(@start_x ,@start_y ); + + i:=0; + + str_:=@str[1 ]; + + while char_ptr(ptrcomp(str_ ) + i * sizeof(char ) )^ <> #0 do + begin + glyph:=m_fontCacheManager.glyph(int32u(char_ptr(ptrcomp(str_ ) + i * sizeof(char ) )^ ) ); + + if glyph <> NIL then + begin + if i <> 0 then + m_fontCacheManager.add_kerning(@x ,@y ); + + m_fontCacheManager.init_embedded_adaptors(glyph ,start_x ,start_y ); + + if glyph.data_type = glyph_data_outline then + begin + m_path.remove_all; + m_path.add_path(@tr ,0 ,false ); + + drawPath; + + end; + + if glyph.data_type = glyph_data_gray8 then + begin + render( + m_fontCacheManager.gray8_adaptor , + m_fontCacheManager.gray8_scanline ); + + end; + + start_x:=start_x + glyph.advance_x; + start_y:=start_y + glyph.advance_y; + + end; + + inc(i ); + + end; + +end; + +{ RESETPATH } +procedure TAgg2D.ResetPath; +begin + m_path.remove_all; + m_path.move_to(0 ,0 ); + +end; + +{ MOVETO } +procedure TAgg2D.MoveTo(x ,y : double ); +begin + m_path.move_to(x ,y ); + +end; + +{ MOVEREL } +procedure TAgg2D.MoveRel(dx ,dy : double ); +begin + m_path.move_rel(dx ,dy ); + +end; + +{ LINETO } +procedure TAgg2D.LineTo(x ,y : double ); +begin + m_path.line_to(x ,y ); + +end; + +{ LINEREL } +procedure TAgg2D.LineRel(dx ,dy : double ); +begin + m_path.line_rel(dx ,dy ); + +end; + +{ HORLINETO } +procedure TAgg2D.HorLineTo(x : double ); +begin + m_path.hline_to(x ); + +end; + +{ HORLINEREL } +procedure TAgg2D.HorLineRel(dx : double ); +begin + m_path.hline_rel(dx ); + +end; + +{ VERLINETO } +procedure TAgg2D.VerLineTo(y : double ); +begin + m_path.vline_to(y ); + +end; + +{ VERLINEREL } +procedure TAgg2D.VerLineRel(dy : double ); +begin + m_path.vline_rel(dy ); + +end; + +{ ARCTO } +procedure TAgg2D.ArcTo( + rx ,ry ,angle : double; + largeArcFlag ,sweepFlag : boolean; + x ,y : double ); +begin + m_path.arc_to(rx ,ry ,angle ,largeArcFlag ,sweepFlag ,x ,y ); + +end; + +{ ARCREL } +procedure TAgg2D.ArcRel( + rx ,ry ,angle : double; + largeArcFlag ,sweepFlag : boolean; + dx ,dy : double ); +begin + m_path.arc_rel(rx ,ry ,angle ,largeArcFlag ,sweepFlag ,dx ,dy ); + +end; + +{ QUADRICCURVETO } +procedure TAgg2D.QuadricCurveTo (xCtrl ,yCtrl ,xTo ,yTo : double ); +begin + m_path.curve3(xCtrl ,yCtrl ,xTo ,yTo ); + +end; + +{ QUADRICCURVEREL } +procedure TAgg2D.QuadricCurveRel(dxCtrl ,dyCtrl ,dxTo ,dyTo : double ); +begin + m_path.curve3_rel(dxCtrl ,dyCtrl ,dxTo ,dyTo ); + +end; + +{ QUADRICCURVETO } +procedure TAgg2D.QuadricCurveTo (xTo ,yTo : double ); +begin + m_path.curve3(xTo ,yTo ); + +end; + +{ QUADRICCURVEREL } +procedure TAgg2D.QuadricCurveRel(dxTo ,dyTo : double ); +begin + m_path.curve3_rel(dxTo ,dyTo ); + +end; + +{ CUBICCURVETO } +procedure TAgg2D.CubicCurveTo (xCtrl1 ,yCtrl1 ,xCtrl2 ,yCtrl2 ,xTo ,yTo : double ); +begin + m_path.curve4(xCtrl1 ,yCtrl1 ,xCtrl2 ,yCtrl2 ,xTo ,yTo ); + +end; + +{ CUBICCURVEREL } +procedure TAgg2D.CubicCurveRel(dxCtrl1 ,dyCtrl1 ,dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo : double ); +begin + m_path.curve4_rel(dxCtrl1 ,dyCtrl1 ,dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo ); + +end; + +{ CUBICCURVETO } +procedure TAgg2D.CubicCurveTo (xCtrl2 ,yCtrl2 ,xTo ,yTo : double ); +begin + m_path.curve4(xCtrl2 ,yCtrl2 ,xTo ,yTo ); + +end; + +{ CUBICCURVEREL } +procedure TAgg2D.CubicCurveRel(dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo : double ); +begin + m_path.curve4_rel(dxCtrl2 ,dyCtrl2 ,dxTo ,dyTo ); + +end; + +{ ADDELLIPSE } +procedure TAgg2D.AddEllipse(cx ,cy ,rx ,ry : double; dir : TAggDirection ); +var + ar : bezier_arc; + +begin + if dir = AGG_CCW then + ar.Construct(cx ,cy ,rx ,ry ,0 ,2 * pi ) + else + ar.Construct(cx ,cy ,rx ,ry ,0 ,-2 * pi ); + + m_path.add_path(@ar ,0 ,false ); + m_path.close_polygon; + +end; + +{ CLOSEPOLYGON } +procedure TAgg2D.ClosePolygon; +begin + m_path.close_polygon; + +end; + +{ DRAWPATH } +procedure TAgg2D.DrawPath(flag : TAggDrawPathFlag = AGG_FillAndStroke ); +begin + m_rasterizer.reset; + + case flag of + AGG_FillOnly : + if m_fillColor.a <> 0 then + begin + m_rasterizer.add_path(@m_pathTransform ); + + render(true ); + + end; + + AGG_StrokeOnly : + if (m_lineColor.a <> 0 ) and + (m_lineWidth > 0.0 ) then + begin + m_rasterizer.add_path(@m_strokeTransform ); + + render(false ); + + end; + + AGG_FillAndStroke : + begin + if m_fillColor.a <> 0 then + begin + m_rasterizer.add_path(@m_pathTransform ); + + render(true ); + + end; + + if (m_lineColor.a <> 0 ) and + (m_lineWidth > 0.0 ) then + begin + m_rasterizer.add_path(@m_strokeTransform ); + + render(false ); + + end; + + end; + + AGG_FillWithLineColor : + if m_lineColor.a <> 0 then + begin + m_rasterizer.add_path(@m_pathTransform ); + + render(false ); + + end; + + end; + +end; + +{ IMAGEFILTER } +procedure TAgg2D.ImageFilter(f : TAggImageFilter ); +begin + m_imageFilter:=f; + + case f of + AGG_Bilinear : + m_imageFilterLut.calculate(@m_ifBilinear ,true ); + + AGG_Hanning : + m_imageFilterLut.calculate(@m_ifHanning ,true ); + + AGG_Hermite : + m_imageFilterLut.calculate(@m_ifHermite ,true ); + + AGG_Quadric : + m_imageFilterLut.calculate(@m_ifQuadric ,true ); + + AGG_Bicubic : + m_imageFilterLut.calculate(@m_ifBicubic ,true ); + + AGG_Catrom : + m_imageFilterLut.calculate(@m_ifCatrom ,true ); + + AGG_Spline16 : + m_imageFilterLut.calculate(@m_ifSpline16 ,true ); + + AGG_Spline36 : + m_imageFilterLut.calculate(@m_ifSpline36 ,true ); + + AGG_Blackman144 : + m_imageFilterLut.calculate(@m_ifBlackman144 ,true ); + + end; + +end; + +{ IMAGEFILTER } +function TAgg2D.ImageFilter : TAggImageFilter; +begin + result:=m_imageFilter; + +end; + +{ IMAGERESAMPLE } +procedure TAgg2D.ImageResample(f : TAggImageResample ); +begin + m_imageResample:=f; + +end; + +{ IMAGEFLIP } +procedure TAgg2D.ImageFlip(f : boolean ); +begin + m_imageFlip:=f; + +end; + +{ IMAGERESAMPLE } +function TAgg2D.ImageResample : TAggImageResample; +begin + result:=m_imageResample; + +end; + +{ TRANSFORMIMAGE } +procedure TAgg2D.TransformImage( + bitmap : TBitmap; + imgX1 ,imgY1 ,imgX2 ,imgY2 : integer; + dstX1 ,dstY1 ,dstX2 ,dstY2 : double ); +var + parall : array[0..5 ] of double; + image : TAggImage; + +begin + image.Construct; + + if image.attach(bitmap ,m_imageFlip ) then + begin + resetPath; + moveTo(dstX1 ,dstY1 ); + lineTo(dstX2 ,dstY1 ); + lineTo(dstX2 ,dstY2 ); + lineTo(dstX1 ,dstY2 ); + closePolygon; + + parall[0 ]:=dstX1; + parall[1 ]:=dstY1; + parall[2 ]:=dstX2; + parall[3 ]:=dstY1; + parall[4 ]:=dstX2; + parall[5 ]:=dstY2; + + renderImage(@image ,imgX1 ,imgY1 ,imgX2 ,imgY2 ,@parall[0 ] ); + + image.Destruct; + + end; + +end; + +{ TRANSFORMIMAGE } +procedure TAgg2D.TransformImage( + bitmap : TBitmap; + dstX1 ,dstY1 ,dstX2 ,dstY2 : double ); +var + parall : array[0..5 ] of double; + image : TAggImage; + +begin + image.Construct; + + if image.attach(bitmap ,m_imageFlip ) then + begin + ResetPath; + MoveTo(dstX1 ,dstY1 ); + LineTo(dstX2 ,dstY1 ); + LineTo(dstX2 ,dstY2 ); + LineTo(dstX1 ,dstY2 ); + ClosePolygon; + + parall[0 ]:=dstX1; + parall[1 ]:=dstY1; + parall[2 ]:=dstX2; + parall[3 ]:=dstY1; + parall[4 ]:=dstX2; + parall[5 ]:=dstY2; + + renderImage(@image ,0 ,0 ,image.renBuf._width ,image.renBuf._height ,@parall[0 ] ); + + image.Destruct; + + end; + +end; + +{ TRANSFORMIMAGE } +procedure TAgg2D.TransformImage( + bitmap : TBitmap; + imgX1 ,imgY1 ,imgX2 ,imgY2 : integer; + parallelo : PDouble ); +var + image : TAggImage; + +begin + image.Construct; + + if image.attach(bitmap ,m_imageFlip ) then + begin + ResetPath; + + MoveTo( + PDouble(ptrcomp(parallelo ) + 0 * sizeof(double ) )^ , + PDouble(ptrcomp(parallelo ) + 1 * sizeof(double ) )^ ); + + LineTo( + PDouble(ptrcomp(parallelo ) + 2 * sizeof(double ) )^ , + PDouble(ptrcomp(parallelo ) + 3 * sizeof(double ) )^ ); + + LineTo( + PDouble(ptrcomp(parallelo ) + 4 * sizeof(double ) )^ , + PDouble(ptrcomp(parallelo ) + 5 * sizeof(double ) )^ ); + + LineTo( + PDouble(ptrcomp(parallelo ) + 0 * sizeof(double ) )^ + + PDouble(ptrcomp(parallelo ) + 4 * sizeof(double ) )^ - + PDouble(ptrcomp(parallelo ) + 2 * sizeof(double ) )^ , + PDouble(ptrcomp(parallelo ) + 1 * sizeof(double ) )^ + + PDouble(ptrcomp(parallelo ) + 5 * sizeof(double ) )^ - + PDouble(ptrcomp(parallelo ) + 3 * sizeof(double ) )^ ); + + ClosePolygon; + + renderImage(@image ,imgX1 ,imgY1 ,imgX2 ,imgY2 ,parallelo ); + + image.Destruct; + + end; + +end; + +{ TRANSFORMIMAGE } +procedure TAgg2D.TransformImage(bitmap : TBitmap; parallelo : PDouble ); +var + image : TAggImage; + +begin + image.Construct; + + if image.attach(bitmap ,m_imageFlip ) then + begin + ResetPath; + + MoveTo( + PDouble(ptrcomp(parallelo ) + 0 * sizeof(double ) )^ , + PDouble(ptrcomp(parallelo ) + 1 * sizeof(double ) )^ ); + + LineTo( + PDouble(ptrcomp(parallelo ) + 2 * sizeof(double ) )^ , + PDouble(ptrcomp(parallelo ) + 3 * sizeof(double ) )^ ); + + LineTo( + PDouble(ptrcomp(parallelo ) + 4 * sizeof(double ) )^ , + PDouble(ptrcomp(parallelo ) + 5 * sizeof(double ) )^ ); + + LineTo( + PDouble(ptrcomp(parallelo ) + 0 * sizeof(double ) )^ + + PDouble(ptrcomp(parallelo ) + 4 * sizeof(double ) )^ - + PDouble(ptrcomp(parallelo ) + 2 * sizeof(double ) )^ , + PDouble(ptrcomp(parallelo ) + 1 * sizeof(double ) )^ + + PDouble(ptrcomp(parallelo ) + 5 * sizeof(double ) )^ - + PDouble(ptrcomp(parallelo ) + 3 * sizeof(double ) )^ ); + + ClosePolygon; + + renderImage(@image ,0 ,0 ,image.renBuf._width ,image.renBuf._height ,parallelo ); + + image.Destruct; + + end; + +end; + +{ TRANSFORMIMAGEPATH } +procedure TAgg2D.TransformImagePath( + bitmap : TBitmap; + imgX1 ,imgY1 ,imgX2 ,imgY2 : integer; + dstX1 ,dstY1 ,dstX2 ,dstY2 : double ); +var + parall : array[0..5 ] of double; + image : TAggImage; + +begin + image.Construct; + + if image.attach(bitmap ,m_imageFlip ) then + begin + parall[0 ]:=dstX1; + parall[1 ]:=dstY1; + parall[2 ]:=dstX2; + parall[3 ]:=dstY1; + parall[4 ]:=dstX2; + parall[5 ]:=dstY2; + + renderImage(@image ,imgX1 ,imgY1 ,imgX2 ,imgY2 ,@parall[0 ] ); + + image.Destruct; + + end; + +end; + +{ TRANSFORMIMAGEPATH } +procedure TAgg2D.TransformImagePath( + bitmap : TBitmap; + dstX1 ,dstY1 ,dstX2 ,dstY2 : double ); +var + parall : array[0..5 ] of double; + image : TAggImage; + +begin + image.Construct; + + if image.attach(bitmap ,m_imageFlip ) then + begin + parall[0 ]:=dstX1; + parall[1 ]:=dstY1; + parall[2 ]:=dstX2; + parall[3 ]:=dstY1; + parall[4 ]:=dstX2; + parall[5 ]:=dstY2; + + renderImage(@image ,0 ,0 ,image.renBuf._width ,image.renBuf._height ,@parall[0 ] ); + + image.Destruct; + + end; + +end; + +{ TRANSFORMIMAGEPATH } +procedure TAgg2D.TransformImagePath( + bitmap : TBitmap; + imgX1 ,imgY1 ,imgX2 ,imgY2 : integer; + parallelo : PDouble ); +var + image : TAggImage; + +begin + image.Construct; + + if image.attach(bitmap ,m_imageFlip ) then + begin + renderImage(@image ,imgX1 ,imgY1 ,imgX2 ,imgY2 ,parallelo ); + + image.Destruct; + + end; + +end; + +{ TRANSFORMIMAGEPATH } +procedure TAgg2D.TransformImagePath(bitmap : TBitmap; parallelo : PDouble ); +var + image : TAggImage; + +begin + image.Construct; + + if image.attach(bitmap ,m_imageFlip ) then + begin + renderImage(@image ,0 ,0 ,image.renBuf._width ,image.renBuf._height ,parallelo ); + + image.Destruct; + + end; + +end; + +{ COPYIMAGE } +procedure TAgg2D.CopyImage( + bitmap : TBitmap; + imgX1 ,imgY1 ,imgX2 ,imgY2 : integer; + dstX ,dstY : double ); +var + r : agg_basics.rect; + image : TAggImage; + +begin + image.Construct; + + if image.attach(bitmap ,m_imageFlip ) then + begin + WorldToScreen(@dstX ,@dstY ); + r.Construct (imgX1 ,imgY1 ,imgX2 ,imgY2 ); + + m_renBase.copy_from(@image.renBuf ,@r ,Trunc(dstX ) - imgX1 ,Trunc(dstY ) - imgY1 ); + + image.Destruct; + + end; + +end; + +{ COPYIMAGE } +procedure TAgg2D.CopyImage(bitmap : TBitmap; dstX ,dstY : double ); +var + image : TAggImage; + +begin + image.Construct; + + if image.attach(bitmap ,m_imageFlip ) then + begin + WorldToScreen(@dstX ,@dstY ); + + m_renBase.copy_from(@image.renBuf ,NIL ,Trunc(dstX ) ,Trunc(dstY ) ); + + image.Destruct; + + end; + +end; + +{ RENDER } +procedure TAgg2D.render(fillColor_ : boolean ); +begin + if (m_blendMode = AGG_BlendAlpha ) or + (m_pixf = pf24bit ) then + Agg2DRenderer_render(self ,@m_renBase ,@m_renSolid ,fillColor_ ) + else + Agg2DRenderer_render(self ,@m_renBaseComp ,@m_renSolidComp ,fillColor_ ); + +end; + +{ RENDER } +procedure TAgg2D.render(ras : PAggFontRasterizer; sl : PAggFontScanline ); +begin + if (m_blendMode = AGG_BlendAlpha ) or + (m_pixf = pf24bit ) then + Agg2DRenderer_render(self ,@m_renBase ,@m_renSolid ,ras ,sl ) + else + Agg2DRenderer_render(self ,@m_renBaseComp ,@m_renSolidComp ,ras ,sl ); + +end; + +{ ADDLINE } +procedure TAgg2D.addLine(x1 ,y1 ,x2 ,y2 : double ); +begin + m_path.move_to(x1 ,y1 ); + m_path.line_to(x2 ,y2 ); + +end; + +{ UPDATERASTERIZERGAMMA } +procedure TAgg2D.updateRasterizerGamma; +begin + m_gammaAgg2D.Construct(m_masterAlpha ,m_antiAliasGamma ); + m_rasterizer.gamma (@m_gammaAgg2D ); + +end; + +{ RENDERIMAGE } +procedure TAgg2D.renderImage( + img : PAggImage; + x1 ,y1 ,x2 ,y2 : integer; + parl : PDouble ); +var + mtx : trans_affine; + + interpolator : span_interpolator_linear; + +begin + mtx.Construct(x1 ,y1 ,x2 ,y2 ,parallelo_ptr(parl ) ); + mtx.multiply (@m_transform ); + mtx.invert; + + m_rasterizer.reset; + m_rasterizer.add_path(@m_pathTransform ); + + interpolator.Construct(@mtx ); + + if (m_blendMode = AGG_BlendAlpha ) or + (m_pixf = pf24bit ) then + Agg2DRenderer_renderImage(self ,img ,@m_renBasePre ,@interpolator ) + else + Agg2DRenderer_renderImage(self ,img ,@m_renBaseCompPre ,@interpolator ); + +end; + +{ BITMAPALPHATRANSPARENCY } +function BitmapAlphaTransparency(bitmap : TBitmap; alpha : byte ) : boolean; +var + fcx ,fcy : integer; + transp : ^byte; + +begin + result:=false; + + if Assigned(bitmap ) and + not bitmap.Empty and + (bitmap.PixelFormat = pf32bit ) then + begin + for fcy:=0 to bitmap.Height - 1 do + begin + transp:=pointer(ptrcomp(bitmap.ScanLine[fcy ] ) + 3 ); + + for fcx:=0 to bitmap.Width - 1 do + begin + transp^:=alpha; + + inc(ptrcomp(transp ) ,4 ); + + end; + + end; + + { OK } + result:=true; + + end; + +end; + +END. + +{*} +{!}{ To look At } + + |