Ignore:
Timestamp:
Apr 17, 2019, 12:58:41 AM (5 years ago)
Author:
chronos
Message:
  • Modified: Propagate project build mode options to used packages.
  • Added: Check memory leaks using heaptrc.
  • Modified: Update BGRABitmap package.
Location:
GraphicTest
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • GraphicTest

    • Property svn:ignore
      •  

        old new  
        88GraphicTest.lps
        99GraphicTest.dbg
         10heaptrclog.trc
  • GraphicTest/Packages/bgrabitmap/bgradefaultbitmap.pas

    r494 r521  
    3434uses
    3535  SysUtils, Classes, Types, FPImage, BGRAGraphics, BGRABitmapTypes, FPImgCanv,
    36   BGRACanvas, BGRACanvas2D, BGRAArrow, BGRAPen, BGRATransform;
     36  BGRACanvas, BGRACanvas2D, BGRAArrow, BGRAPen, BGRATransform, BGRATextBidi;
    3737
    3838type
     
    5959      gtype: TGradientType; o1, o2: TPointF; mode: TDrawMode;
    6060      gammaColorCorrection: boolean = True; Sinus: Boolean=False;
    61       ditherAlgo: TDitheringAlgorithm = daFloydSteinberg);
     61      ditherAlgo: TDitheringAlgorithm = daFloydSteinberg); overload;
    6262    procedure GradientFillDithered(x, y, x2, y2: integer; gradient: TBGRACustomGradient;
    6363      gtype: TGradientType; o1, o2: TPointF; mode: TDrawMode;
    6464      Sinus: Boolean=False;
    65       ditherAlgo: TDitheringAlgorithm = daFloydSteinberg);
     65      ditherAlgo: TDitheringAlgorithm = daFloydSteinberg); overload;
    6666  protected
    6767    FRefCount: integer; //reference counter (not related to interface reference counter)
     
    152152    function SimpleStretch(NewWidth, NewHeight: integer): TBGRACustomBitmap;
    153153    function CheckEmpty: boolean; override;
     154    function CheckIsZero: boolean; override;
    154155    function GetHasTransparentPixels: boolean; override;
     156    function GetHasSemiTransparentPixels: boolean; override;
    155157    function GetAverageColor: TColor; override;
    156158    function GetAveragePixel: TBGRAPixel; override;
     
    190192    procedure SetFontRenderer(AValue: TBGRACustomFontRenderer); override;
    191193    function CreateDefaultFontRenderer: TBGRACustomFontRenderer; virtual; abstract;
    192     function GetFontAnchorVerticalOffset: single;
    193     function GetFontAnchorRotatedOffset: TPointF;
    194     function GetFontAnchorRotatedOffset(ACustomOrientation: integer): TPointF;
     194    function GetFontVerticalAnchorOffset: single; override;
     195    function GetFontAnchorRotatedOffset: TPointF; overload;
     196    function GetFontAnchorRotatedOffset(ACustomOrientation: integer): TPointF; overload;
    195197
    196198    function GetClipRect: TRect; override;
     
    201203    function GetArrow: TBGRAArrow;
    202204    procedure InternalTextOutCurved(ACursor: TBGRACustomPathCursor; sUTF8: string; AColor: TBGRAPixel; ATexture: IBGRAScanner; AAlign: TAlignment; ALetterSpacing: single);
     205    procedure InternalCrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadePos: byte; AFadeMask: IBGRAScanner; mode: TDrawMode = dmDrawWithTransparency);
    203206
    204207    function CheckClippedRectBounds(var x,y,x2,y2: integer): boolean;
     
    227230    function GetUnique: TBGRACustomBitmap;
    228231
     232    { ** Allocate xor mask }
     233    procedure NeedXorMask; override;
     234
     235    { ** Free reference to xor mask }
     236    procedure DiscardXorMask; override;
     237
    229238    {==== Constructors ====}
    230239
    231240    {------------------------- Constructors from TFPCustomImage----------------}
    232241    {** Creates a new bitmap, initialize properties and bitmap data }
    233     constructor Create(AWidth, AHeight: integer); override;
     242    constructor Create(AWidth, AHeight: integer); overload; override;
    234243    {** Can only be called with an existing instance of ''TBGRABitmap''.
    235244        Sets the dimensions of an existing ''TBGRABitmap'' instance. }
     
    239248    {** Creates an image of width and height equal to zero. In this case,
    240249        ''Data'' = '''nil''' }
    241     constructor Create; override;
     250    constructor Create; overload; override;
    242251    {** Creates an image by copying the content of a ''TFPCustomImage'' }
    243     constructor Create(AFPImage: TFPCustomImage); override;
     252    constructor Create(AFPImage: TFPCustomImage); overload; override;
    244253    {** Creates an image by copying the content of a ''TBitmap'' }
    245     constructor Create(ABitmap: TBitmap; AUseTransparent: boolean = true); override;
     254    constructor Create(ABitmap: TBitmap; AUseTransparent: boolean = true); overload; override;
    246255    {** Creates an image of dimensions ''AWidth'' and ''AHeight'' and fills it with the opaque color ''Color'' }
    247     constructor Create(AWidth, AHeight: integer; Color: TColor); override;
     256    constructor Create(AWidth, AHeight: integer; Color: TColor); overload; override;
    248257    {** Creates an image of dimensions ''AWidth'' and ''AHeight'' and fills it with ''Color'' }
    249     constructor Create(AWidth, AHeight: integer; Color: TBGRAPixel); override;
     258    constructor Create(AWidth, AHeight: integer; Color: TBGRAPixel); overload; override;
    250259
    251260    {** Creates an image by loading its content from the file ''AFilename''.
    252261        The encoding of the string is the default one for the operating system.
    253262        It is recommended to use the next constructor and UTF8 encoding }
    254     constructor Create(AFilename: string); override;
     263    constructor Create(AFilename: string); overload; override;
    255264
    256265    {** Creates an image by loading its content from the file ''AFilename''.
    257266        The boolean ''AIsUtf8Filename'' specifies if UTF8 encoding is assumed
    258267        for the filename }
    259     constructor Create(AFilename: string; AIsUtf8: boolean); override;
    260     constructor Create(AFilename: string; AIsUtf8: boolean; AOptions: TBGRALoadingOptions); override;
     268    constructor Create(AFilename: string; AIsUtf8: boolean); overload; override;
     269    constructor Create(AFilename: string; AIsUtf8: boolean; AOptions: TBGRALoadingOptions); overload; override;
    261270
    262271    {** Creates an image by loading its content from the stream ''AStream'' }
    263     constructor Create(AStream: TStream); override;
     272    constructor Create(AStream: TStream); overload; override;
    264273    {** Free the object and all its resources }
    265274    destructor Destroy; override;
     
    269278        Creates a new instance with dimensions ''AWidth'' and ''AHeight'',
    270279        containing transparent pixels. }
    271     function NewBitmap(AWidth, AHeight: integer): TBGRACustomBitmap; override;
     280    function NewBitmap(AWidth, AHeight: integer): TBGRACustomBitmap; overload; override;
    272281
    273282    {** Can only be called from an existing instance of ''TBGRABitmap''.
    274283        Creates a new instance with dimensions ''AWidth'' and ''AHeight'',
    275284        and fills it with Color }
    276     function NewBitmap(AWidth, AHeight: integer; Color: TBGRAPixel): TBGRACustomBitmap; override;
     285    function NewBitmap(AWidth, AHeight: integer; Color: TBGRAPixel): TBGRACustomBitmap; overload; override;
    277286
    278287    {** Can only be called from an existing instance of ''TBGRABitmap''.
     
    280289        from the file ''Filename''. The encoding of the string
    281290        is the default one for the operating system }
    282     function NewBitmap(Filename: string): TBGRACustomBitmap; override;
     291    function NewBitmap(Filename: string): TBGRACustomBitmap; overload; override;
    283292
    284293    {** Can only be called from an existing instance of ''TBGRABitmap''.
    285294        Creates a new instance with by loading its content
    286295        from the file ''Filename'' }
    287     function NewBitmap(Filename: string; AIsUtf8: boolean): TBGRACustomBitmap; override;
    288     function NewBitmap(Filename: string; AIsUtf8: boolean; AOptions: TBGRALoadingOptions): TBGRACustomBitmap; override;
     296    function NewBitmap(Filename: string; AIsUtf8: boolean): TBGRACustomBitmap; overload; override;
     297    function NewBitmap(Filename: string; AIsUtf8: boolean; AOptions: TBGRALoadingOptions): TBGRACustomBitmap; overload; override;
    289298
    290299    {** Can only be called from an existing instance of ''TBGRABitmap''.
    291300        Creates an image by copying the content of a ''TFPCustomImage'' }
    292     function NewBitmap(AFPImage: TFPCustomImage): TBGRACustomBitmap; override;
     301    function NewBitmap(AFPImage: TFPCustomImage): TBGRACustomBitmap; overload; override;
    293302
    294303    {** Load image from a stream. The specified image reader is used }
    295     procedure LoadFromStream(Str: TStream; Handler: TFPCustomImageReader; AOptions: TBGRALoadingOptions); override;
     304    procedure LoadFromStream(Str: TStream; Handler: TFPCustomImageReader; AOptions: TBGRALoadingOptions); overload; override;
     305
     306    {** Load image from an embedded Lazarus resource. Format is detected automatically }
     307    procedure LoadFromResource(AFilename: string; AOptions: TBGRALoadingOptions); overload; override;
    296308
    297309    {** Assign the content of the specified ''Source''. It can be a ''TBGRACustomBitmap'' or
    298310        a ''TFPCustomImage'' }
    299     procedure Assign(Source: TPersistent); override;
     311    procedure Assign(Source: TPersistent); overload; override;
    300312    procedure Assign(Source: TBitmap; AUseTransparent: boolean); overload;
    301313    {** Stores the image in the stream without compression nor header }
     
    322334    {** Sets the pixel by replacing the content at (''x'',''y'') with the specified color.
    323335        Alpha value is set to 255 (opaque) }
    324     procedure SetPixel(x, y: int32or64; c: TColor); override;
     336    procedure SetPixel(x, y: int32or64; c: TColor); overload; override;
    325337    {** Sets the pixel at (''x'',''y'') with the specified content }
    326     procedure SetPixel(x, y: int32or64; c: TBGRAPixel); override;
     338    procedure SetPixel(x, y: int32or64; c: TBGRAPixel); overload; override;
    327339    {** Applies a logical '''xor''' to the content of the pixel with the specified value.
    328340        This includes the alpha channel, so if you want to preserve the opacity, provide
     
    371383      * ''AResampleFilter'' specifies how pixels must be interpolated. Accepted
    372384        values are ''rfBox'', ''rfLinear'', ''rfHalfCosine'' and ''rfCosine'' }
    373     function GetPixelCycle(x, y: single; AResampleFilter: TResampleFilter = rfLinear): TBGRAPixel; override;
     385    function GetPixelCycle(x, y: single; AResampleFilter: TResampleFilter = rfLinear): TBGRAPixel; overload; override;
    374386    {** Similar to previous ''GetPixel'' function, but the fractional part of
    375387        the coordinate is supplied with a number from 0 to 255. The actual
    376388        coordinate is (''x'' + ''fracX256''/256, ''y'' + ''fracY256''/256) }
    377     function GetPixelCycle256(x, y, fracX256,fracY256: int32or64; AResampleFilter: TResampleFilter = rfLinear): TBGRAPixel; override;
     389    function GetPixelCycle256(x, y, fracX256,fracY256: int32or64; AResampleFilter: TResampleFilter = rfLinear): TBGRAPixel; overload; override;
    378390    {** Computes the value of the pixel at a floating point coordiante
    379391        by interpolating the values of the pixels around it. ''repeatX'' and
     
    381393      * ''AResampleFilter'' specifies how pixels must be interpolated. Accepted
    382394        values are ''rfBox'', ''rfLinear'', ''rfHalfCosine'' and ''rfCosine'' }
    383     function GetPixelCycle(x, y: single; AResampleFilter: TResampleFilter; repeatX: boolean; repeatY: boolean): TBGRAPixel; override;
     395    function GetPixelCycle(x, y: single; AResampleFilter: TResampleFilter; repeatX: boolean; repeatY: boolean): TBGRAPixel; overload; override;
    384396    {** Similar to previous ''GetPixel'' function, but the fractional part of
    385397        the coordinate is supplied with a number from 0 to 255. The actual
    386398        coordinate is (''x'' + ''fracX256''/256, ''y'' + ''fracY256''/256) }
    387     function GetPixelCycle256(x, y, fracX256,fracY256: int32or64; AResampleFilter: TResampleFilter; repeatX: boolean; repeatY: boolean): TBGRAPixel; override;
     399    function GetPixelCycle256(x, y, fracX256,fracY256: int32or64; AResampleFilter: TResampleFilter; repeatX: boolean; repeatY: boolean): TBGRAPixel; overload; override;
    388400
    389401    {==== Drawing lines and polylines (integer coordinates) ====}
     
    452464    {** Draws an antialiased line from (x1,y1) to (x2,y2) using an improved version of Bresenham's algorithm
    453465        ''c'' specifies the color. ''DrawLastPixel'' specifies if (x2,y2) must be drawn }
    454     procedure DrawLineAntialias(x1, y1, x2, y2: integer; c: TBGRAPixel; DrawLastPixel: boolean); override;
     466    procedure DrawLineAntialias(x1, y1, x2, y2: integer; c: TBGRAPixel; DrawLastPixel: boolean); overload; override;
    455467    {** Draws an antialiased line with two colors ''c1'' and ''c2'' as dashes of lenght ''dashLen'' }
    456     procedure DrawLineAntialias(x1, y1, x2, y2: integer; c1, c2: TBGRAPixel; dashLen: integer; DrawLastPixel: boolean); override;
     468    procedure DrawLineAntialias(x1, y1, x2, y2: integer; c1, c2: TBGRAPixel; dashLen: integer; DrawLastPixel: boolean); overload; override;
    457469    {** Draws an antialiased line with two colors ''c1'' and ''c2'' as dashes of lenght ''dashLen''.
    458470        ''DashPos'' can be used to specify the start dash position and to retrieve the dash position at the end
     
    477489
    478490    {** Draws a line from (x1,y1) to (x2,y2) using current pen style/cap/join }
    479     procedure DrawLineAntialias(x1, y1, x2, y2: single; c: TBGRAPixel; w: single); override;
     491    procedure DrawLineAntialias(x1, y1, x2, y2: single; c: TBGRAPixel; w: single); overload; override;
    480492    {** Draws a line from (x1,y1) to (x2,y2) using current pen style/cap/join.
    481493        ''texture'' specifies the source color to use when filling the line }
    482     procedure DrawLineAntialias(x1, y1, x2, y2: single; texture: IBGRAScanner; w: single); override;
     494    procedure DrawLineAntialias(x1, y1, x2, y2: single; texture: IBGRAScanner; w: single); overload; override;
    483495    {** Draws a line from (x1,y1) to (x2,y2) using current pen style/cap/join.
    484496        ''Closed'' specifies if the end of the line is closed. If it is not closed,
    485497        a space is left so that the next line can fit }
    486     procedure DrawLineAntialias(x1, y1, x2, y2: single; c: TBGRAPixel; w: single; ClosedCap: boolean); override;
     498    procedure DrawLineAntialias(x1, y1, x2, y2: single; c: TBGRAPixel; w: single; ClosedCap: boolean); overload; override;
    487499    {** Same as above with ''texture'' specifying the source color to use when filling the line }
    488     procedure DrawLineAntialias(x1, y1, x2, y2: single; texture: IBGRAScanner; w: single; ClosedCap: boolean); override;
     500    procedure DrawLineAntialias(x1, y1, x2, y2: single; texture: IBGRAScanner; w: single; ClosedCap: boolean); overload; override;
    489501
    490502    {** Draws a polyline using current pen style/cap/join }
    491     procedure DrawPolyLineAntialias(const points: array of TPointF; c: TBGRAPixel; w: single); override;
     503    procedure DrawPolyLineAntialias(const points: array of TPointF; c: TBGRAPixel; w: single); overload; override;
    492504    {** Draws a polyline using current pen style/cap/join.
    493505        ''texture'' specifies the source color to use when filling the line }
    494     procedure DrawPolyLineAntialias(const points: array of TPointF; texture: IBGRAScanner; w: single); override;
     506    procedure DrawPolyLineAntialias(const points: array of TPointF; texture: IBGRAScanner; w: single); overload; override;
    495507    {** Draws a polyline using current pen style/cap/join.
    496508        ''Closed'' specifies if the end of the line is closed. If it is not closed,
    497509        a space is left so that the next line can fit }
    498     procedure DrawPolyLineAntialias(const points: array of TPointF; c: TBGRAPixel; w: single; ClosedCap: boolean); override;
    499     procedure DrawPolyLineAntialias(const points: array of TPointF; texture: IBGRAScanner; w: single; ClosedCap: boolean); override;
     510    procedure DrawPolyLineAntialias(const points: array of TPointF; c: TBGRAPixel; w: single; ClosedCap: boolean); overload; override;
     511    procedure DrawPolyLineAntialias(const points: array of TPointF; texture: IBGRAScanner; w: single; ClosedCap: boolean); overload; override;
    500512    {** Draws a polyline using current pen style/cap/join.
    501513        ''fillcolor'' specifies a color to fill the polygon formed by the points }
    502     procedure DrawPolyLineAntialias(const points: array of TPointF; c: TBGRAPixel; w: single; fillcolor: TBGRAPixel); override;
     514    procedure DrawPolyLineAntialias(const points: array of TPointF; c: TBGRAPixel; w: single; fillcolor: TBGRAPixel); overload; override;
    503515    {** Draws a polyline using current pen style/cap/join.
    504516        The last point considered as a join with the first point if it has
     
    509521        The polygon is always closed. You don't need to set the last point
    510522        to be the same as the first point }
    511     procedure DrawPolygonAntialias(const points: array of TPointF; c: TBGRAPixel; w: single); override;
     523    procedure DrawPolygonAntialias(const points: array of TPointF; c: TBGRAPixel; w: single); overload; override;
    512524    {** Draws a polygon using current pen style/cap/join.
    513525        The polygon is always closed. You don't need to set the last point
    514526        to be the same as the first point }
    515     procedure DrawPolygonAntialias(const points: array of TPointF; texture: IBGRAScanner; w: single); override;
     527    procedure DrawPolygonAntialias(const points: array of TPointF; texture: IBGRAScanner; w: single); overload; override;
    516528    {** Draws a filled polygon using current pen style/cap/join.
    517529        The polygon is always closed. You don't need to set the last point
    518530        to be the same as the first point. }
    519     procedure DrawPolygonAntialias(const points: array of TPointF; c: TBGRAPixel; w: single; fillcolor: TBGRAPixel); override;
     531    procedure DrawPolygonAntialias(const points: array of TPointF; c: TBGRAPixel; w: single; fillcolor: TBGRAPixel); overload; override;
    520532
    521533    {** Erases a line from (x1,y1) to (x2,y2) using current pen style/cap/join }
     
    538550    {** Draw a size border of a rectangle,
    539551        using the specified ''mode'' }
    540     procedure Rectangle(x, y, x2, y2: integer; c: TBGRAPixel; mode: TDrawMode); override;
     552    procedure Rectangle(x, y, x2, y2: integer; c: TBGRAPixel; mode: TDrawMode); overload; override;
    541553    {** Draw a filled rectangle with a border of color ''BorderColor'',
    542554        using the specified ''mode'' }
    543     procedure Rectangle(x, y, x2, y2: integer; BorderColor, FillColor: TBGRAPixel; mode: TDrawMode); override;
     555    procedure Rectangle(x, y, x2, y2: integer; BorderColor, FillColor: TBGRAPixel; mode: TDrawMode); overload; override;
    544556    {** Fills completely a rectangle, without any border, with the specified ''mode'' }
    545     procedure FillRect(x, y, x2, y2: integer; c: TBGRAPixel; mode: TDrawMode); override; overload;
     557    procedure FillRect(x, y, x2, y2: integer; c: TBGRAPixel; mode: TDrawMode); overload; override;
    546558    {** Fills completely a rectangle, without any border, with the specified ''texture'' and
    547559        with the specified ''mode'' }
    548     procedure FillRect(x, y, x2, y2: integer; texture: IBGRAScanner; mode: TDrawMode; AScanOffset: TPoint); override; overload;
    549     procedure FillRect(x, y, x2, y2: integer; texture: IBGRAScanner; mode: TDrawMode; AScanOffset: TPoint; ditheringAlgorithm: TDitheringAlgorithm); override; overload;
     560    procedure FillRect(x, y, x2, y2: integer; texture: IBGRAScanner; mode: TDrawMode; AScanOffset: TPoint); overload; override;
     561    procedure FillRect(x, y, x2, y2: integer; texture: IBGRAScanner; mode: TDrawMode; AScanOffset: TPoint; ditheringAlgorithm: TDitheringAlgorithm); overload; override;
    550562    {** Sets the alpha value within the specified rectangle }
    551563    procedure AlphaFillRect(x, y, x2, y2: integer; alpha: byte); override;
     
    554566    {** Draws a round rectangle, with corners having an elliptical diameter of ''DX'' and ''DY'' }
    555567    procedure RoundRect(X1, Y1, X2, Y2: integer; DX, DY: integer; BorderColor: TBGRAPixel; ADrawMode: TDrawMode = dmDrawWithTransparency); override;
     568    procedure FillRoundRect(X1, Y1, X2, Y2: integer; DX, DY: integer; FillTexture: IBGRAScanner; ADrawMode: TDrawMode = dmDrawWithTransparency); override; overload;
    556569
    557570    {==== Rectangles and ellipses (floating point coordinates) ====}
     
    572585    {** Fills a rectangle with antialiasing. For example (-0.5,-0.5,0.5,0.5)
    573586        fills one pixel }
    574     procedure FillRectAntialias(x, y, x2, y2: single; c: TBGRAPixel; pixelCenteredCoordinates: boolean = true); override;
     587    procedure FillRectAntialias(x, y, x2, y2: single; c: TBGRAPixel; pixelCenteredCoordinates: boolean = true); overload; override;
    575588    {** Fills a rectangle with a texture }
    576     procedure FillRectAntialias(x, y, x2, y2: single; texture: IBGRAScanner; pixelCenteredCoordinates: boolean = true); override;
     589    procedure FillRectAntialias(x, y, x2, y2: single; texture: IBGRAScanner; pixelCenteredCoordinates: boolean = true); overload; override;
    577590    {** Erases the content of a rectangle with antialiasing }
    578591    procedure EraseRectAntialias(x, y, x2, y2: single; alpha: byte; pixelCenteredCoordinates: boolean = true); override;
     
    581594        elliptical radius of ''rx'' and ''ry''. ''options'' specifies how to
    582595        draw the corners. See [[BGRABitmap Geometry types|geometry types]] }
    583     procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; c: TBGRAPixel; w: single; options: TRoundRectangleOptions = []); override;
     596    procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; c: TBGRAPixel; w: single; options: TRoundRectangleOptions = []); overload; override;
    584597    {** Draws a rounded rectangle border with the specified texture.
    585598        The corners have an elliptical radius of ''rx'' and ''ry''.
    586599        ''options'' specifies how to draw the corners.
    587600        See [[BGRABitmap Geometry types|geometry types]] }
    588     procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; texture: IBGRAScanner; w: single; options: TRoundRectangleOptions = []); override;
     601    procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; texture: IBGRAScanner; w: single; options: TRoundRectangleOptions = []); overload; override;
    589602    {** Draws and fills a round rectangle }
    590     procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; pencolor: TBGRAPixel; w: single; fillcolor: TBGRAPixel; options: TRoundRectangleOptions = []); override;
     603    procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; pencolor: TBGRAPixel; w: single; fillcolor: TBGRAPixel; options: TRoundRectangleOptions = []); overload; override;
    591604    {** Draws and fills a round rectangle with textures }
    592     procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; penTexture: IBGRAScanner; w: single; fillTexture: IBGRAScanner; options: TRoundRectangleOptions = []); override;
     605    procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; penTexture: IBGRAScanner; w: single; fillTexture: IBGRAScanner; options: TRoundRectangleOptions = []); overload; override;
    593606
    594607    {** Fills a rounded rectangle with antialiasing. The corners have an
    595608        elliptical radius of ''rx'' and ''ry''. ''options'' specifies how to
    596609        draw the corners. See [[BGRABitmap Geometry types|geometry types]] }
    597     procedure FillRoundRectAntialias(x,y,x2,y2,rx,ry: single; c: TBGRAPixel; options: TRoundRectangleOptions = []; pixelCenteredCoordinates: boolean = true); override;
     610    procedure FillRoundRectAntialias(x,y,x2,y2,rx,ry: single; c: TBGRAPixel; options: TRoundRectangleOptions = []; pixelCenteredCoordinates: boolean = true); overload; override;
    598611    {** Fills a rounded rectangle with a texture }
    599     procedure FillRoundRectAntialias(x,y,x2,y2,rx,ry: single; texture: IBGRAScanner; options: TRoundRectangleOptions = []; pixelCenteredCoordinates: boolean = true); override;
     612    procedure FillRoundRectAntialias(x,y,x2,y2,rx,ry: single; texture: IBGRAScanner; options: TRoundRectangleOptions = []; pixelCenteredCoordinates: boolean = true); overload; override;
    600613    {** Erases the content of a rounded rectangle with a texture }
    601     procedure EraseRoundRectAntialias(x,y,x2,y2,rx,ry: single; alpha: byte; options: TRoundRectangleOptions = []; pixelCenteredCoordinates: boolean = true); override;
    602 
     614    procedure EraseRoundRectAntialias(x,y,x2,y2,rx,ry: single; alpha: byte; options: TRoundRectangleOptions = []; pixelCenteredCoordinates: boolean = true); overload; override;
     615
     616    {** Draws an ellipse without antialising. ''rx'' is the horizontal radius and
     617        ''ry'' the vertical radius }
     618    procedure Ellipse(x, y, rx, ry: single; c: TBGRAPixel; w: single; ADrawMode: TDrawMode); overload; override;
     619    procedure Ellipse(AOrigin, AXAxis, AYAxis: TPointF; c: TBGRAPixel; w: single; ADrawMode: TDrawMode); overload; override;
    603620    {** Draws an ellipse with antialising. ''rx'' is the horizontal radius and
    604621        ''ry'' the vertical radius }
    605     procedure EllipseAntialias(x, y, rx, ry: single; c: TBGRAPixel; w: single); override;
     622    procedure EllipseAntialias(x, y, rx, ry: single; c: TBGRAPixel; w: single); overload; override;
     623    procedure EllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; c: TBGRAPixel; w: single); overload; override;
    606624    {** Draws an ellipse border with a ''texture'' }
    607     procedure EllipseAntialias(x, y, rx, ry: single; texture: IBGRAScanner; w: single); override;
     625    procedure EllipseAntialias(x, y, rx, ry: single; texture: IBGRAScanner; w: single); overload; override;
     626    procedure EllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; texture: IBGRAScanner; w: single); overload; override;
    608627    {** Draws and fills an ellipse }
    609     procedure EllipseAntialias(x, y, rx, ry: single; c: TBGRAPixel; w: single; back: TBGRAPixel); override;
     628    procedure EllipseAntialias(x, y, rx, ry: single; c: TBGRAPixel; w: single; back: TBGRAPixel); overload; override;
     629    procedure EllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; c: TBGRAPixel; w: single; back: TBGRAPixel); overload; override;
    610630    {** Fills an ellipse }
    611     procedure FillEllipseAntialias(x, y, rx, ry: single; c: TBGRAPixel); override;
     631    procedure FillEllipseAntialias(x, y, rx, ry: single; c: TBGRAPixel); overload; override;
     632    procedure FillEllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; c: TBGRAPixel); overload; override;
    612633    {** Fills an ellipse with a ''texture'' }
    613     procedure FillEllipseAntialias(x, y, rx, ry: single; texture: IBGRAScanner); override;
     634    procedure FillEllipseAntialias(x, y, rx, ry: single; texture: IBGRAScanner); overload; override;
     635    procedure FillEllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; texture: IBGRAScanner); overload; override;
    614636    {** Fills an ellipse with a gradient of color. ''outercolor'' specifies
    615637        the end color of the gradient on the border of the ellipse and
    616638        ''innercolor'' the end color of the gradient at the center of the
    617639        ellipse }
    618     procedure FillEllipseLinearColorAntialias(x, y, rx, ry: single; outercolor, innercolor: TBGRAPixel); override;
     640    procedure FillEllipseLinearColorAntialias(x, y, rx, ry: single; outercolor, innercolor: TBGRAPixel); overload; override;
     641    procedure FillEllipseLinearColorAntialias(AOrigin, AXAxis, AYAxis: TPointF; outercolor, innercolor: TBGRAPixel); overload; override;
    619642    {** Erases the content of an ellipse }
    620     procedure EraseEllipseAntialias(x, y, rx, ry: single; alpha: byte); override;
     643    procedure EraseEllipseAntialias(x, y, rx, ry: single; alpha: byte); overload; override;
     644    procedure EraseEllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; alpha: byte); overload; override;
    621645
    622646    {==== Polygons and path ====}
    623     procedure FillPoly(const points: array of TPointF; c: TBGRAPixel; drawmode: TDrawMode); override;
    624     procedure FillPoly(const points: array of TPointF; texture: IBGRAScanner; drawmode: TDrawMode); override;
    625     procedure FillPolyAntialias(const points: array of TPointF; c: TBGRAPixel); override;
    626     procedure FillPolyAntialias(const points: array of TPointF; texture: IBGRAScanner); override;
    627     procedure ErasePoly(const points: array of TPointF; alpha: byte); override;
    628     procedure ErasePolyAntialias(const points: array of TPointF; alpha: byte); override;
     647    procedure FillPoly(const points: array of TPointF; c: TBGRAPixel; drawmode: TDrawMode; APixelCenteredCoordinates: boolean = true); overload; override;
     648    procedure FillPoly(const points: array of TPointF; texture: IBGRAScanner; drawmode: TDrawMode; APixelCenteredCoordinates: boolean = true); overload; override;
     649    procedure FillPolyAntialias(const points: array of TPointF; c: TBGRAPixel; APixelCenteredCoordinates: boolean = true); overload; override;
     650    procedure FillPolyAntialias(const points: array of TPointF; texture: IBGRAScanner; APixelCenteredCoordinates: boolean = true); overload; override;
     651    procedure ErasePoly(const points: array of TPointF; alpha: byte; APixelCenteredCoordinates: boolean = true); override;
     652    procedure ErasePolyAntialias(const points: array of TPointF; alpha: byte; APixelCenteredCoordinates: boolean = true); override;
    629653
    630654    procedure FillTriangleLinearColor(pt1,pt2,pt3: TPointF; c1,c2,c3: TBGRAPixel); override;
     
    652676    procedure FillPolyPerspectiveMappingLightness(const points: array of TPointF; const pointsZ: array of single; texture: IBGRAScanner; texCoords: array of TPointF; lightnesses: array of word; TextureInterpolation: Boolean; zbuffer: psingle = nil); override;
    653677
    654     procedure FillShape(shape: TBGRACustomFillInfo; c: TBGRAPixel; drawmode: TDrawMode); override;
    655     procedure FillShape(shape: TBGRACustomFillInfo; texture: IBGRAScanner; drawmode: TDrawMode); override;
    656     procedure FillShapeAntialias(shape: TBGRACustomFillInfo; c: TBGRAPixel); override;
    657     procedure FillShapeAntialias(shape: TBGRACustomFillInfo; texture: IBGRAScanner); override;
     678    procedure FillShape(shape: TBGRACustomFillInfo; c: TBGRAPixel; drawmode: TDrawMode); overload; override;
     679    procedure FillShape(shape: TBGRACustomFillInfo; texture: IBGRAScanner; drawmode: TDrawMode); overload; override;
     680    procedure FillShapeAntialias(shape: TBGRACustomFillInfo; c: TBGRAPixel); overload; override;
     681    procedure FillShapeAntialias(shape: TBGRACustomFillInfo; texture: IBGRAScanner); overload; override;
    658682    procedure EraseShape(shape: TBGRACustomFillInfo; alpha: byte); override;
    659683    procedure EraseShapeAntialias(shape: TBGRACustomFillInfo; alpha: byte); override;
    660684
    661     procedure DrawPath(APath: IBGRAPath; AStrokeColor: TBGRAPixel; AWidth: single; AFillColor: TBGRAPixel); override;
    662     procedure DrawPath(APath: IBGRAPath; AStrokeTexture: IBGRAScanner; AWidth: single; AFillColor: TBGRAPixel); override;
    663     procedure DrawPath(APath: IBGRAPath; AStrokeColor: TBGRAPixel; AWidth: single; AFillTexture: IBGRAScanner); override;
    664     procedure DrawPath(APath: IBGRAPath; AStrokeTexture: IBGRAScanner; AWidth: single; AFillTexture: IBGRAScanner); override;
    665     procedure DrawPath(APath: IBGRAPath; AStrokeColor: TBGRAPixel; AWidth: single); override;
    666     procedure DrawPath(APath: IBGRAPath; AStrokeTexture: IBGRAScanner; AWidth: single); override;
    667     procedure FillPath(APath: IBGRAPath; AFillColor: TBGRAPixel); override;
    668     procedure FillPath(APath: IBGRAPath; AFillTexture: IBGRAScanner); override;
    669     procedure ErasePath(APath: IBGRAPath; alpha: byte); override;
    670 
    671     procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeColor: TBGRAPixel; AWidth: single; AFillColor: TBGRAPixel); override;
    672     procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeTexture: IBGRAScanner; AWidth: single; AFillColor: TBGRAPixel); override;
    673     procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeColor: TBGRAPixel; AWidth: single; AFillTexture: IBGRAScanner); override;
    674     procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeTexture: IBGRAScanner; AWidth: single; AFillTexture: IBGRAScanner); override;
    675     procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeColor: TBGRAPixel; AWidth: single); override;
    676     procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeTexture: IBGRAScanner; AWidth: single); override;
    677     procedure FillPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AFillColor: TBGRAPixel); override;
    678     procedure FillPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AFillTexture: IBGRAScanner); override;
    679     procedure ErasePath(APath: IBGRAPath; AMatrix: TAffineMatrix; alpha: byte); override;
     685    procedure DrawPath(APath: IBGRAPath; AStrokeColor: TBGRAPixel; AWidth: single; AFillColor: TBGRAPixel); overload; override;
     686    procedure DrawPath(APath: IBGRAPath; AStrokeTexture: IBGRAScanner; AWidth: single; AFillColor: TBGRAPixel); overload; override;
     687    procedure DrawPath(APath: IBGRAPath; AStrokeColor: TBGRAPixel; AWidth: single; AFillTexture: IBGRAScanner); overload; override;
     688    procedure DrawPath(APath: IBGRAPath; AStrokeTexture: IBGRAScanner; AWidth: single; AFillTexture: IBGRAScanner); overload; override;
     689    procedure DrawPath(APath: IBGRAPath; AStrokeColor: TBGRAPixel; AWidth: single); overload; override;
     690    procedure DrawPath(APath: IBGRAPath; AStrokeTexture: IBGRAScanner; AWidth: single); overload; override;
     691    procedure FillPath(APath: IBGRAPath; AFillColor: TBGRAPixel); overload; override;
     692    procedure FillPath(APath: IBGRAPath; AFillTexture: IBGRAScanner); overload; override;
     693    procedure ErasePath(APath: IBGRAPath; alpha: byte); overload; override;
     694
     695    procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeColor: TBGRAPixel; AWidth: single; AFillColor: TBGRAPixel); overload; override;
     696    procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeTexture: IBGRAScanner; AWidth: single; AFillColor: TBGRAPixel); overload; override;
     697    procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeColor: TBGRAPixel; AWidth: single; AFillTexture: IBGRAScanner); overload; override;
     698    procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeTexture: IBGRAScanner; AWidth: single; AFillTexture: IBGRAScanner); overload; override;
     699    procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeColor: TBGRAPixel; AWidth: single); overload; override;
     700    procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeTexture: IBGRAScanner; AWidth: single); overload; override;
     701    procedure FillPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AFillColor: TBGRAPixel); overload; override;
     702    procedure FillPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AFillTexture: IBGRAScanner); overload; override;
     703    procedure ErasePath(APath: IBGRAPath; AMatrix: TAffineMatrix; alpha: byte); overload; override;
    680704
    681705    procedure ArrowStartAsNone; override;
     
    694718      If align is taRightJustify, (x,y) is the top-right corner.
    695719      The value of FontOrientation is taken into account, so that the text may be rotated. }
    696     procedure TextOut(x, y: single; sUTF8: string; c: TBGRAPixel; align: TAlignment); override; overload;
     720    procedure TextOut(x, y: single; sUTF8: string; c: TBGRAPixel; align: TAlignment; ARightToLeft: boolean); overload; override;
    697721
    698722    { Same as above functions, except that the text is filled using texture.
    699723      The value of FontOrientation is taken into account, so that the text may be rotated. }
    700     procedure TextOut(x, y: single; sUTF8: string; texture: IBGRAScanner; align: TAlignment); override; overload;
     724    procedure TextOut(x, y: single; sUTF8: string; texture: IBGRAScanner; align: TAlignment; ARightToLeft: boolean); overload; override;
    701725
    702726    { Same as above, except that the orientation is specified, overriding the value of the property FontOrientation. }
    703     procedure TextOutAngle(x, y: single; orientationTenthDegCCW: integer; sUTF8: string; c: TBGRAPixel; align: TAlignment); override; overload;
    704     procedure TextOutAngle(x, y: single; orientationTenthDegCCW: integer; sUTF8: string; texture: IBGRAScanner; align: TAlignment); override; overload;
    705 
    706     procedure TextOutCurved(ACursor: TBGRACustomPathCursor; sUTF8: string; AColor: TBGRAPixel; AAlign: TAlignment; ALetterSpacing: single); override; overload;
    707     procedure TextOutCurved(ACursor: TBGRACustomPathCursor; sUTF8: string; ATexture: IBGRAScanner; AAlign: TAlignment; ALetterSpacing: single); override; overload;
     727    procedure TextOutAngle(x, y: single; orientationTenthDegCCW: integer; sUTF8: string; c: TBGRAPixel; align: TAlignment); overload; override;
     728    procedure TextOutAngle(x, y: single; orientationTenthDegCCW: integer; sUTF8: string; texture: IBGRAScanner; align: TAlignment); overload; override;
     729
     730    procedure TextOutCurved(ACursor: TBGRACustomPathCursor; sUTF8: string; AColor: TBGRAPixel; AAlign: TAlignment; ALetterSpacing: single); overload; override;
     731    procedure TextOutCurved(ACursor: TBGRACustomPathCursor; sUTF8: string; ATexture: IBGRAScanner; AAlign: TAlignment; ALetterSpacing: single); overload; override;
     732
     733    procedure TextMultiline(ALeft,ATop,AWidth: single; sUTF8: string; c: TBGRAPixel; AAlign: TBidiTextAlignment = btaNatural; AVertAlign: TTextLayout = tlTop; AParagraphSpacing: single = 0); overload; override;
     734    procedure TextMultiline(ALeft,ATop,AWidth: single; sUTF8: string; ATexture: IBGRAScanner; AAlign: TBidiTextAlignment = btaNatural; AVertAlign: TTextLayout = tlTop; AParagraphSpacing: single = 0); overload; override;
    708735
    709736    { Draw the UTF8 encoded string at the coordinate (x,y), clipped inside the rectangle ARect.
    710737      Additional style information is provided by the style parameter.
    711738      The color c or texture is used to fill the text. No rotation is applied. }
    712     procedure TextRect(ARect: TRect; x, y: integer; sUTF8: string; style: TTextStyle; c: TBGRAPixel); override; overload;
    713     procedure TextRect(ARect: TRect; x, y: integer; sUTF8: string; style: TTextStyle; texture: IBGRAScanner); override; overload;
     739    procedure TextRect(ARect: TRect; x, y: integer; sUTF8: string; style: TTextStyle; c: TBGRAPixel); overload; override;
     740    procedure TextRect(ARect: TRect; x, y: integer; sUTF8: string; style: TTextStyle; texture: IBGRAScanner); overload; override;
    714741
    715742    { Returns the total size of the string provided using the current font.
    716       Orientation is not taken into account, so that the width is along the text. }
     743      Orientation is not taken into account, so that the width is along the text. End of lines are stripped from the string. }
    717744    function TextSize(sUTF8: string): TSize; override;
     745
     746    { Returns the affine box of the string provided using the current font.
     747      Orientation is taken into account. End of lines are stripped from the string. }
     748    function TextAffineBox(sUTF8: string): TAffineBox; override;
     749
     750    { Returns the total size of a paragraph i.e. with word break }
     751    function TextSize(sUTF8: string; AMaxWidth: integer): TSize; override;
     752    function TextSize(sUTF8: string; AMaxWidth: integer; ARightToLeft: boolean): TSize; override;
     753    function TextFitInfo(sUTF8: string; AMaxWidth: integer): integer; override;
    718754
    719755    {Spline}
     
    721757    function ComputeOpenedSpline(const APoints: array of TPointF; AStyle: TSplineStyle): ArrayOfTPointF; override;
    722758
    723     function ComputeBezierCurve(const ACurve: TCubicBezierCurve): ArrayOfTPointF; override;
    724     function ComputeBezierCurve(const ACurve: TQuadraticBezierCurve): ArrayOfTPointF; override;
    725     function ComputeBezierSpline(const ASpline: array of TCubicBezierCurve): ArrayOfTPointF; override;
    726     function ComputeBezierSpline(const ASpline: array of TQuadraticBezierCurve): ArrayOfTPointF; override;
    727 
    728     function ComputeWidePolyline(const points: array of TPointF; w: single): ArrayOfTPointF; override;
    729     function ComputeWidePolyline(const points: array of TPointF; w: single; ClosedCap: boolean): ArrayOfTPointF; override;
    730     function ComputeWidePolygon(const points: array of TPointF; w: single): ArrayOfTPointF; override;
    731 
    732     function ComputeEllipseContour(x,y,rx,ry: single; quality: single = 1): ArrayOfTPointF; override;
    733     function ComputeEllipseBorder(x,y,rx,ry,w: single; quality: single = 1): ArrayOfTPointF; override;
     759    function ComputeBezierCurve(const ACurve: TCubicBezierCurve): ArrayOfTPointF; overload; override;
     760    function ComputeBezierCurve(const ACurve: TQuadraticBezierCurve): ArrayOfTPointF; overload; override;
     761    function ComputeBezierSpline(const ASpline: array of TCubicBezierCurve): ArrayOfTPointF; overload; override;
     762    function ComputeBezierSpline(const ASpline: array of TQuadraticBezierCurve): ArrayOfTPointF; overload; override;
     763
     764    function ComputeWidePolyline(const points: array of TPointF; w: single): ArrayOfTPointF; overload; override;
     765    function ComputeWidePolyline(const points: array of TPointF; w: single; ClosedCap: boolean): ArrayOfTPointF; overload; override;
     766    function ComputeWidePolygon(const points: array of TPointF; w: single): ArrayOfTPointF; overload; override;
     767
     768    function ComputeEllipseContour(x,y,rx,ry: single; quality: single = 1): ArrayOfTPointF;  overload; override;
     769    function ComputeEllipseContour(AOrigin, AXAxis, AYAxis: TPointF; quality: single = 1): ArrayOfTPointF;  overload; override;
     770    function ComputeEllipseBorder(x,y,rx,ry,w: single; quality: single = 1): ArrayOfTPointF; overload; override;
     771    function ComputeEllipseBorder(AOrigin, AXAxis, AYAxis: TPointF; w: single; quality: single = 1): ArrayOfTPointF; override; overload;
    734772    function ComputeArc65536(x,y,rx,ry: single; start65536,end65536: word; quality: single = 1): ArrayOfTPointF; override;
    735773    function ComputeArcRad(x,y,rx,ry: single; startRad,endRad: single; quality: single = 1): ArrayOfTPointF; override;
    736     function ComputeRoundRect(x1,y1,x2,y2,rx,ry: single; quality: single = 1): ArrayOfTPointF; override;
    737     function ComputeRoundRect(x1,y1,x2,y2,rx,ry: single; options: TRoundRectangleOptions; quality: single = 1): ArrayOfTPointF; override;
     774    function ComputeRoundRect(x1,y1,x2,y2,rx,ry: single; quality: single = 1): ArrayOfTPointF; overload; override;
     775    function ComputeRoundRect(x1,y1,x2,y2,rx,ry: single; options: TRoundRectangleOptions; quality: single = 1): ArrayOfTPointF; overload; override;
    738776    function ComputePie65536(x,y,rx,ry: single; start65536,end65536: word; quality: single = 1): ArrayOfTPointF; override;
    739777    function ComputePieRad(x,y,rx,ry: single; startRad,endRad: single; quality: single = 1): ArrayOfTPointF; override;
     
    741779    {Filling}
    742780    procedure NoClip; override;
    743     procedure Fill(texture: IBGRAScanner; mode: TDrawMode); override;
    744     procedure Fill(texture: IBGRAScanner); override;
    745     procedure Fill(c: TBGRAPixel; start, Count: integer); override;
     781    procedure Fill(texture: IBGRAScanner; mode: TDrawMode); overload; override;
     782    procedure Fill(texture: IBGRAScanner); overload; override;
     783    procedure Fill(c: TBGRAPixel; start, Count: integer); overload; override;
    746784    procedure DrawPixels(c: TBGRAPixel; start, Count: integer); override;
    747785    procedure AlphaFill(alpha: byte; start, Count: integer); override;
    748786    procedure FillMask(x,y: integer; AMask: TBGRACustomBitmap; color: TBGRAPixel; ADrawMode: TDrawMode); override;
    749787    procedure FillMask(x,y: integer; AMask: TBGRACustomBitmap; texture: IBGRAScanner; ADrawMode: TDrawMode; AOpacity: byte = 255); override;
     788    procedure EraseMask(x,y: integer; AMask: TBGRACustomBitmap; alpha: byte=255); override;
    750789    procedure FillClearTypeMask(x,y: integer; xThird: integer; AMask: TBGRACustomBitmap; color: TBGRAPixel; ARGBOrder: boolean = true); override;
    751790    procedure FillClearTypeMask(x,y: integer; xThird: integer; AMask: TBGRACustomBitmap; texture: IBGRAScanner; ARGBOrder: boolean = true); override;
     
    775814
    776815    {Canvas drawing functions}
    777     procedure Draw(ACanvas: TCanvas; x, y: integer; Opaque: boolean = True); override;
    778     procedure Draw(ACanvas: TCanvas; Rect: TRect; Opaque: boolean = True); override;
     816    procedure Draw(ACanvas: TCanvas; x, y: integer; Opaque: boolean = True); overload; override;
     817    procedure Draw(ACanvas: TCanvas; Rect: TRect; Opaque: boolean = True); overload; override;
    779818    procedure InvalidateBitmap; override;         //call if you modify with Scanline
    780819    procedure LoadFromBitmapIfNeeded; override;   //call to ensure that bitmap data is up to date
    781820
    782821    {BGRA bitmap functions}
    783     procedure CrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadePosition: byte; mode: TDrawMode = dmDrawWithTransparency); override;
    784     procedure CrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadeMask: IBGRAScanner; mode: TDrawMode = dmDrawWithTransparency); override;
    785     procedure PutImage(x, y: integer; Source: TBGRACustomBitmap; mode: TDrawMode; AOpacity: byte = 255); override;
    786     procedure PutImageAffine(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; AOutputBounds: TRect; AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte=255); override; overload;
    787     function GetImageAffineBounds(AMatrix: TAffineMatrix; ASourceBounds: TRect; AClipOutput: boolean = true): TRect; override; overload;
    788     function IsAffineRoughlyTranslation(AMatrix: TAffineMatrix; ASourceBounds: TRect): boolean; override;
     822    procedure CrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadePosition: byte; mode: TDrawMode = dmDrawWithTransparency); overload; override;
     823    procedure CrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadeMask: IBGRAScanner; mode: TDrawMode = dmDrawWithTransparency); overload; override;
     824    procedure PutImage(x, y: integer; Source: TBGRACustomBitmap; mode: TDrawMode; AOpacity: byte = 255); overload; override;
     825    procedure PutImageAffine(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; AOutputBounds: TRect; AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte=255); overload; override;
     826    function GetImageAffineBounds(AMatrix: TAffineMatrix; ASourceBounds: TRect; AClipOutput: boolean = true): TRect; overload; override;
     827    class function IsAffineRoughlyTranslation(AMatrix: TAffineMatrix; ASourceBounds: TRect): boolean; override;
    789828
    790829    procedure StretchPutImage(ARect: TRect; Source: TBGRACustomBitmap; mode: TDrawMode; AOpacity: byte = 255); override;
     
    796835    function GetPart(ARect: TRect): TBGRACustomBitmap; override;
    797836    function GetPtrBitmap(Top,Bottom: Integer): TBGRACustomBitmap; override;
    798     function Duplicate(DuplicateProperties: Boolean = False) : TBGRACustomBitmap; override;
     837    function Duplicate(DuplicateProperties: Boolean = False; DuplicateXorMask: Boolean = False) : TBGRACustomBitmap; override;
    799838    procedure CopyPropertiesTo(ABitmap: TBGRADefaultBitmap);
    800     function Equals(comp: TBGRACustomBitmap): boolean; override;
    801     function Equals(comp: TBGRAPixel): boolean; override;
     839    function Equals(comp: TBGRACustomBitmap): boolean; overload; override;
     840    function Equals(comp: TBGRAPixel): boolean; overload; override;
    802841    function GetDifferenceBounds(ABitmap: TBGRACustomBitmap): TRect; override;
    803842    function MakeBitmapCopy(BackgroundColor: TColor): TBitmap; override;
     
    805844    function Resample(newWidth, newHeight: integer;
    806845      mode: TResampleMode = rmFineResample): TBGRACustomBitmap; override;
    807     procedure VerticalFlip(ARect: TRect); override; overload;
    808     procedure HorizontalFlip(ARect: TRect); override; overload;
     846    procedure VerticalFlip(ARect: TRect); overload; override;
     847    procedure HorizontalFlip(ARect: TRect); overload; override;
    809848    function RotateCW: TBGRACustomBitmap; override;
    810849    function RotateCCW: TBGRACustomBitmap; override;
     
    813852    procedure LinearNegative; override;
    814853    procedure LinearNegativeRect(ABounds: TRect); override;
    815     procedure InplaceGrayscale(AGammaCorrection: boolean = true); override;
    816     procedure InplaceGrayscale(ABounds: TRect; AGammaCorrection: boolean = true); override;
    817     procedure InplaceNormalize(AEachChannel: boolean = True); override;
    818     procedure InplaceNormalize(ABounds: TRect; AEachChannel: boolean = True); override;
     854    procedure InplaceGrayscale(AGammaCorrection: boolean = true); overload; override;
     855    procedure InplaceGrayscale(ABounds: TRect; AGammaCorrection: boolean = true); overload; override;
     856    procedure InplaceNormalize(AEachChannel: boolean = True); overload; override;
     857    procedure InplaceNormalize(ABounds: TRect; AEachChannel: boolean = True); overload; override;
    819858    procedure SwapRedBlue; override;
    820859    procedure SwapRedBlue(ARect: TRect); override;
    821860    procedure GrayscaleToAlpha; override;
    822861    procedure AlphaToGrayscale; override;
    823     procedure ApplyMask(mask: TBGRACustomBitmap; ARect: TRect; AMaskRectTopLeft: TPoint); override; overload;
     862    procedure ApplyMask(mask: TBGRACustomBitmap; ARect: TRect; AMaskRectTopLeft: TPoint); overload; override;
     863    function GetMaskFromAlpha: TBGRACustomBitmap; override;
    824864    procedure ApplyGlobalOpacity(alpha: byte); override;
    825865    procedure ApplyGlobalOpacity(ABounds: TRect; alpha: byte); override;
    826866    procedure ConvertToLinearRGB; override;
    827867    procedure ConvertFromLinearRGB; override;
    828     procedure DrawCheckers(ARect: TRect; AColorEven,AColorOdd: TBGRAPixel);
     868    procedure DrawCheckers(ARect: TRect; AColorEven,AColorOdd: TBGRAPixel); override;
    829869
    830870    {Filters}
     
    832872    function FilterMedian(Option: TMedianOption): TBGRACustomBitmap; override;
    833873    function FilterSmooth: TBGRACustomBitmap; override;
    834     function FilterSharpen(Amount: single = 1): TBGRACustomBitmap; override;
    835     function FilterSharpen(ABounds: TRect; Amount: single = 1): TBGRACustomBitmap; override;
     874    function FilterSharpen(Amount: single = 1): TBGRACustomBitmap; overload; override;
     875    function FilterSharpen(ABounds: TRect; Amount: single = 1): TBGRACustomBitmap; overload; override;
    836876    function FilterContour: TBGRACustomBitmap; override;
    837877    function FilterPixelate(pixelSize: integer; useResample: boolean; filter: TResampleFilter = rfLinear): TBGRACustomBitmap; override;
    838     function FilterBlurRadial(radius: single; blurType: TRadialBlurType): TBGRACustomBitmap; override;
    839     function FilterBlurRadial(ABounds: TRect; radius: single; blurType: TRadialBlurType): TBGRACustomBitmap; override;
    840     function FilterBlurRadial(radiusX, radiusY: single; blurType: TRadialBlurType): TBGRACustomBitmap; override;
    841     function FilterBlurRadial(ABounds: TRect; radiusX, radiusY: single; blurType: TRadialBlurType): TBGRACustomBitmap; override;
    842     function FilterBlurMotion(distance: single; angle: single; oriented: boolean): TBGRACustomBitmap; override;
    843     function FilterBlurMotion(ABounds: TRect; distance: single; angle: single; oriented: boolean): TBGRACustomBitmap; override;
    844     function FilterCustomBlur(mask: TBGRACustomBitmap): TBGRACustomBitmap; override;
    845     function FilterCustomBlur(ABounds: TRect; mask: TBGRACustomBitmap): TBGRACustomBitmap; override;
    846     function FilterEmboss(angle: single; AStrength: integer= 64; AOptions: TEmbossOptions = []): TBGRACustomBitmap; override;
    847     function FilterEmboss(angle: single; ABounds: TRect; AStrength: integer= 64; AOptions: TEmbossOptions = []): TBGRACustomBitmap; override;
    848     function FilterEmbossHighlight(FillSelection: boolean): TBGRACustomBitmap; override;
    849     function FilterEmbossHighlight(FillSelection: boolean; BorderColor: TBGRAPixel): TBGRACustomBitmap; override;
    850     function FilterEmbossHighlight(FillSelection: boolean; BorderColor: TBGRAPixel; var Offset: TPoint): TBGRACustomBitmap; override;
    851     function FilterGrayscale: TBGRACustomBitmap; override;
    852     function FilterGrayscale(ABounds: TRect): TBGRACustomBitmap; override;
    853     function FilterNormalize(eachChannel: boolean = True): TBGRACustomBitmap; override;
    854     function FilterNormalize(ABounds: TRect; eachChannel: boolean = True): TBGRACustomBitmap; override;
     878    function FilterBlurRadial(radius: single; blurType: TRadialBlurType): TBGRACustomBitmap; overload; override;
     879    function FilterBlurRadial(ABounds: TRect; radius: single; blurType: TRadialBlurType): TBGRACustomBitmap; overload; override;
     880    function FilterBlurRadial(radiusX, radiusY: single; blurType: TRadialBlurType): TBGRACustomBitmap; overload; override;
     881    function FilterBlurRadial(ABounds: TRect; radiusX, radiusY: single; blurType: TRadialBlurType): TBGRACustomBitmap; overload; override;
     882    function FilterBlurMotion(distance: single; angle: single; oriented: boolean): TBGRACustomBitmap; overload; override;
     883    function FilterBlurMotion(ABounds: TRect; distance: single; angle: single; oriented: boolean): TBGRACustomBitmap; overload; override;
     884    function FilterCustomBlur(mask: TBGRACustomBitmap): TBGRACustomBitmap; overload; override;
     885    function FilterCustomBlur(ABounds: TRect; mask: TBGRACustomBitmap): TBGRACustomBitmap; overload; override;
     886    function FilterEmboss(angle: single; AStrength: integer= 64; AOptions: TEmbossOptions = []): TBGRACustomBitmap; overload; override;
     887    function FilterEmboss(angle: single; ABounds: TRect; AStrength: integer= 64; AOptions: TEmbossOptions = []): TBGRACustomBitmap; overload; override;
     888    function FilterEmbossHighlight(FillSelection: boolean): TBGRACustomBitmap; overload; override;
     889    function FilterEmbossHighlight(FillSelection: boolean; BorderColor: TBGRAPixel): TBGRACustomBitmap; overload; override;
     890    function FilterEmbossHighlight(FillSelection: boolean; BorderColor: TBGRAPixel; var Offset: TPoint): TBGRACustomBitmap; overload; override;
     891    function FilterGrayscale: TBGRACustomBitmap; overload; override;
     892    function FilterGrayscale(ABounds: TRect): TBGRACustomBitmap; overload; override;
     893    function FilterNormalize(eachChannel: boolean = True): TBGRACustomBitmap; overload; override;
     894    function FilterNormalize(ABounds: TRect; eachChannel: boolean = True): TBGRACustomBitmap; overload; override;
    855895    function FilterRotate(origin: TPointF; angle: single; correctBlur: boolean = false): TBGRACustomBitmap; override;
    856896    function FilterAffine(AMatrix: TAffineMatrix; correctBlur: boolean = false): TBGRACustomBitmap; override;
    857897    function FilterSphere: TBGRACustomBitmap; override;
    858     function FilterTwirl(ACenter: TPoint; ARadius: Single; ATurn: Single=1; AExponent: Single=3): TBGRACustomBitmap; override;
    859     function FilterTwirl(ABounds: TRect; ACenter: TPoint; ARadius: Single; ATurn: Single=1; AExponent: Single=3): TBGRACustomBitmap; override;
     898    function FilterTwirl(ACenter: TPoint; ARadius: Single; ATurn: Single=1; AExponent: Single=3): TBGRACustomBitmap; overload; override;
     899    function FilterTwirl(ABounds: TRect; ACenter: TPoint; ARadius: Single; ATurn: Single=1; AExponent: Single=3): TBGRACustomBitmap; overload; override;
    860900    function FilterCylinder: TBGRACustomBitmap; override;
    861901    function FilterPlane: TBGRACustomBitmap; override;
     
    880920  public
    881921    constructor Create(AWidth, AHeight: integer; AData: Pointer); overload;
    882     function Duplicate(DuplicateProperties: Boolean = False): TBGRACustomBitmap; override;
     922    function Duplicate(DuplicateProperties: Boolean = False; DuplicateXorMask: Boolean = False): TBGRACustomBitmap; override;
    883923    procedure SetDataPtr(AData: Pointer);
    884924    property LineOrder: TRawImageLineOrder Read GetLineOrder Write SetLineOrder;
     
    893933    procedure TakeScreenshot({%H-}ARect: TRect); override;
    894934    procedure TakeScreenshotOfPrimaryMonitor; override;
    895     procedure LoadFromDevice({%H-}DC: System.THandle); override;
    896     procedure LoadFromDevice({%H-}DC: System.THandle; {%H-}ARect: TRect); override;
     935    procedure LoadFromDevice({%H-}DC: HDC); override;
     936    procedure LoadFromDevice({%H-}DC: HDC; {%H-}ARect: TRect); override;
    897937  end;
    898938
     
    935975begin
    936976  if FUser <> nil then
     977  begin
    937978    FUser.FBitmapModified := True;
     979    FUser.FAlphaCorrectionNeeded := true;
     980  end;
    938981  inherited Changed(Sender);
    939982end;
     
    9661009end;
    9671010
     1011function TBGRADefaultBitmap.CheckIsZero: boolean;
     1012var
     1013  i: integer;
     1014  p: PBGRAPixel;
     1015begin
     1016  p := Data;
     1017  for i := (NbPixels shr 1) - 1 downto 0 do
     1018  begin
     1019    if PInt64(p)^ <> 0 then
     1020    begin
     1021      Result := False;
     1022      exit;
     1023    end;
     1024    Inc(p,2);
     1025  end;
     1026  if Odd(NbPixels) and (PDWord(p)^ <> 0) then
     1027  begin
     1028    Result := false;
     1029    exit;
     1030  end;
     1031  Result := True;
     1032end;
     1033
    9681034function TBGRADefaultBitmap.GetCanvasAlphaCorrection: boolean;
    9691035begin
     
    10551121procedure TBGRADefaultBitmap.SetArrowEndSize(AValue: TPointF);
    10561122begin
     1123  {$PUSH}{$OPTIMIZATION OFF}
    10571124  GetArrow.EndSize := AValue;
     1125  {$POP}
    10581126end;
    10591127
    10601128procedure TBGRADefaultBitmap.SetArrowStartSize(AValue: TPointF);
    10611129begin
     1130  {$PUSH}{$OPTIMIZATION OFF}
    10621131  GetArrow.StartSize := AValue;
     1132  {$POP}
    10631133end;
    10641134
     
    11481218end;
    11491219
    1150 function TBGRADefaultBitmap.GetFontAnchorVerticalOffset: single;
     1220function TBGRADefaultBitmap.GetFontVerticalAnchorOffset: single;
    11511221begin
    11521222  case FontVerticalAnchor of
     
    11731243  ACustomOrientation: integer): TPointF;
    11741244begin
    1175   result := PointF(0, GetFontAnchorVerticalOffset);
     1245  result := PointF(0, GetFontVerticalAnchorOffset);
    11761246  if ACustomOrientation <> 0 then
    11771247    result := AffineMatrixRotationDeg(-ACustomOrientation*0.1)*result;
     
    12051275function TBGRADefaultBitmap.NewReference: TBGRACustomBitmap;
    12061276begin
    1207   Inc(FRefCount);
     1277  if self <> nil then Inc(FRefCount);
    12081278  Result := self;
    12091279end;
     
    12391309end;
    12401310
     1311procedure TBGRADefaultBitmap.NeedXorMask;
     1312begin
     1313  if FXorMask = nil then
     1314    FXorMask := BGRABitmapFactory.Create(Width,Height);
     1315end;
     1316
     1317procedure TBGRADefaultBitmap.DiscardXorMask;
     1318begin
     1319  if Assigned(FXorMask) then
     1320  begin
     1321    if FXorMask is TBGRADefaultBitmap then
     1322    begin
     1323      TBGRADefaultBitmap(FXorMask).FreeReference;
     1324      FXorMask := nil;
     1325    end else
     1326      FreeAndNil(FXorMask);
     1327  end;
     1328end;
     1329
    12411330{ Creates a new bitmap with dimensions AWidth and AHeight and filled with
    12421331  transparent pixels. Internally, it uses the same type so that if you
     
    13091398  OldJpegPerf: TJPEGReadPerformance;
    13101399begin
     1400  DiscardXorMask;
    13111401  if (loBmpAutoOpaque in AOptions) and (Handler is TBGRAReaderBMP) then
    13121402  begin
     
    13241414  end else
    13251415    inherited LoadFromStream(Str, Handler, AOptions);
     1416end;
     1417
     1418procedure TBGRADefaultBitmap.LoadFromResource(AFilename: string;
     1419  AOptions: TBGRALoadingOptions);
     1420var
     1421  stream: TStream;
     1422  format: TBGRAImageFormat;
     1423  reader: TFPCustomImageReader;
     1424  magic: array[1..2] of char;
     1425  startPos: Int64;
     1426  ext: String;
     1427begin
     1428  stream := BGRAResource.GetResourceStream(AFilename);
     1429  try
     1430    ext := Uppercase(ExtractFileExt(AFilename));
     1431    if (ext = '.BMP') and BGRAResource.IsWinResource(AFilename) then
     1432    begin
     1433      reader := TBGRAReaderBMP.Create;
     1434      TBGRAReaderBMP(reader).Subformat := bsfHeaderless;
     1435    end else
     1436    begin
     1437      format := DetectFileFormat(stream, ext);
     1438      reader := CreateBGRAImageReader(format);
     1439    end;
     1440    try
     1441      LoadFromStream(stream, reader, AOptions);
     1442    finally
     1443      reader.Free;
     1444    end;
     1445  finally
     1446    stream.Free;
     1447  end;
    13261448end;
    13271449
     
    13571479  ReallocData;
    13581480  NoClip;
     1481  DiscardXorMask;
    13591482end;
    13601483
     
    14121535destructor TBGRADefaultBitmap.Destroy;
    14131536begin
     1537  DiscardXorMask;
    14141538  FPenStroker.Free;
    14151539  FFontRenderer.Free;
     
    14991623    SetSize(TBGRACustomBitmap(Source).Width, TBGRACustomBitmap(Source).Height);
    15001624    PutImage(0, 0, TBGRACustomBitmap(Source), dmSet);
     1625    if Source is TBGRADefaultBitmap then
     1626    begin
     1627      HotSpot := TBGRADefaultBitmap(Source).HotSpot;
     1628      if XorMask <> TBGRADefaultBitmap(Source).XorMask then
     1629      begin
     1630        DiscardXorMask;
     1631        if TBGRADefaultBitmap(Source).XorMask is TBGRADefaultBitmap then
     1632          FXorMask := TBGRADefaultBitmap(TBGRADefaultBitmap(Source).XorMask).NewReference as TBGRADefaultBitmap
     1633        else
     1634          FXorMask := TBGRADefaultBitmap(Source).XorMask.Duplicate;
     1635      end;
     1636    end;
    15011637  end else
    15021638  if Source is TFPCustomImage then
     
    19642100function TBGRADefaultBitmap.GetCanvas: TCanvas;
    19652101begin
    1966   Result := Bitmap.Canvas;
     2102  if FDataModified or (FBitmap = nil) then
     2103  begin
     2104    RebuildBitmap;
     2105    FDataModified := False;
     2106  end;
     2107  Result := FBitmap.Canvas;
    19672108end;
    19682109
     
    19902131
    19912132procedure TBGRADefaultBitmap.CrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadePosition: byte; mode: TDrawMode = dmDrawWithTransparency);
    1992 var constScanner: TBGRAConstantScanner;
    19932133begin
    19942134  if AFadePosition = 0 then
     
    19962136  if AFadePosition = 255 then
    19972137    FillRect(ARect, Source2, mode) else
    1998   begin
    1999     constScanner := TBGRAConstantScanner.Create(BGRA(AFadePosition,AFadePosition,AFadePosition,255));
    2000     CrossFade(ARect, Source1,Source2, constScanner, mode);
    2001     constScanner.Free;
    2002   end;
     2138    InternalCrossFade(ARect, Source1,Source2, AFadePosition,nil, mode);
    20032139end;
    20042140
    20052141procedure TBGRADefaultBitmap.CrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadeMask: IBGRAScanner; mode: TDrawMode = dmDrawWithTransparency);
    2006 var xb,yb: NativeInt;
    2007   pdest: PBGRAPixel;
    2008   c: TBGRAPixel;
    2009   fadePos: byte;
    2010 begin
    2011   if not IntersectRect(ARect,ARect,ClipRect) then exit;
    2012   for yb := ARect.top to ARect.Bottom-1 do
    2013   begin
    2014     pdest := GetScanlineFast(yb)+ARect.Left;
    2015     Source1.ScanMoveTo(ARect.left, yb);
    2016     Source2.ScanMoveTo(ARect.left, yb);
    2017     AFadeMask.ScanMoveTo(ARect.left, yb);
    2018     for xb := ARect.left to ARect.Right-1 do
    2019     begin
    2020       fadePos := AFadeMask.ScanNextPixel.green;
    2021       c := MergeBGRAWithGammaCorrection(Source1.ScanNextPixel,not fadePos,Source2.ScanNextPixel,fadePos);
    2022       case mode of
    2023       dmSet: pdest^ := c;
    2024       dmDrawWithTransparency: DrawPixelInlineWithAlphaCheck(pdest, c);
    2025       dmLinearBlend: FastBlendPixelInline(pdest,c);
    2026       dmSetExceptTransparent: if c.alpha = 255 then pdest^ := c;
    2027       end;
    2028       inc(pdest);
    2029     end;
    2030   end;
    2031   InvalidateBitmap;
     2142begin
     2143  InternalCrossFade(ARect, Source1,Source2, 0,AFadeMask, mode);
    20322144end;
    20332145
     
    23842496end;
    23852497
     2498procedure TBGRADefaultBitmap.InternalCrossFade(ARect: TRect; Source1,
     2499  Source2: IBGRAScanner; AFadePos: byte; AFadeMask: IBGRAScanner; mode: TDrawMode);
     2500var xb,yb: NativeInt;
     2501  pdest: PBGRAPixel;
     2502  c: TBGRAPixel;
     2503  buf1,buf2: ArrayOfTBGRAPixel;
     2504begin
     2505  if not IntersectRect(ARect,ARect,ClipRect) then exit;
     2506  setlength(buf1, ARect.Width);
     2507  setlength(buf2, ARect.Width);
     2508  for yb := ARect.top to ARect.Bottom-1 do
     2509  begin
     2510    pdest := GetScanlineFast(yb)+ARect.Left;
     2511    Source1.ScanMoveTo(ARect.left, yb);
     2512    Source1.ScanPutPixels(@buf1[0], length(buf1), dmSet);
     2513    Source2.ScanMoveTo(ARect.left, yb);
     2514    Source2.ScanPutPixels(@buf2[0], length(buf2), dmSet);
     2515    if AFadeMask<>nil then AFadeMask.ScanMoveTo(ARect.left, yb);
     2516    for xb := 0 to ARect.Right-ARect.left-1 do
     2517    begin
     2518      if AFadeMask<>nil then AFadePos := AFadeMask.ScanNextPixel.green;
     2519      c := MergeBGRAWithGammaCorrection(buf1[xb],not AFadePos,buf2[xb],AFadePos);
     2520      case mode of
     2521      dmSet: pdest^ := c;
     2522      dmDrawWithTransparency: DrawPixelInlineWithAlphaCheck(pdest, c);
     2523      dmLinearBlend: FastBlendPixelInline(pdest,c);
     2524      dmSetExceptTransparent: if c.alpha = 255 then pdest^ := c;
     2525      end;
     2526      inc(pdest);
     2527    end;
     2528  end;
     2529  InvalidateBitmap;
     2530end;
     2531
    23862532procedure TBGRADefaultBitmap.InternalArc(cx, cy, rx, ry: single; StartAngleRad,
    23872533  EndAngleRad: Single; ABorderColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel; AOptions: TArcOptions;
     
    24412587end;
    24422588
    2443 function TBGRADefaultBitmap.IsAffineRoughlyTranslation(AMatrix: TAffineMatrix; ASourceBounds: TRect): boolean;
     2589class function TBGRADefaultBitmap.IsAffineRoughlyTranslation(AMatrix: TAffineMatrix; ASourceBounds: TRect): boolean;
    24442590const oneOver512 = 1/512;
    24452591var Orig,HAxis,VAxis: TPointF;
     
    26532799  tempPath := TBGRAPath.Create(APath);
    26542800  multi := TBGRAMultishapeFiller.Create;
     2801  multi.FillMode := FillMode;
    26552802  multi.PolygonOrder := poLastOnTop;
    26562803  multi.AddPathFill(tempPath,AMatrix,AFillColor);
     
    26682815  tempPath := TBGRAPath.Create(APath);
    26692816  multi := TBGRAMultishapeFiller.Create;
     2817  multi.FillMode := FillMode;
    26702818  multi.PolygonOrder := poLastOnTop;
    26712819  multi.AddPathFill(tempPath,AMatrix,AFillColor);
     
    26832831  tempPath := TBGRAPath.Create(APath);
    26842832  multi := TBGRAMultishapeFiller.Create;
     2833  multi.FillMode := FillMode;
    26852834  multi.PolygonOrder := poLastOnTop;
    26862835  multi.AddPathFill(tempPath,AMatrix,AFillTexture);
     
    26992848  tempPath := TBGRAPath.Create(APath);
    27002849  multi := TBGRAMultishapeFiller.Create;
     2850  multi.FillMode := FillMode;
    27012851  multi.PolygonOrder := poLastOnTop;
    27022852  multi.AddPathFill(tempPath,AMatrix,AFillTexture);
     
    30383188
    30393189procedure TBGRADefaultBitmap.FillPoly(const points: array of TPointF;
    3040   c: TBGRAPixel; drawmode: TDrawMode);
    3041 begin
    3042   BGRAPolygon.FillPolyAliased(self, points, c, FEraseMode, FillMode = fmWinding, drawmode);
     3190  c: TBGRAPixel; drawmode: TDrawMode; APixelCenteredCoordinates: boolean);
     3191begin
     3192  BGRAPolygon.FillPolyAliased(self, points, c, FEraseMode, FillMode = fmWinding, drawmode, APixelCenteredCoordinates);
    30433193end;
    30443194
    30453195procedure TBGRADefaultBitmap.FillPoly(const points: array of TPointF;
    3046   texture: IBGRAScanner; drawmode: TDrawMode);
    3047 begin
    3048   BGRAPolygon.FillPolyAliasedWithTexture(self, points, texture, FillMode = fmWinding, drawmode);
     3196  texture: IBGRAScanner; drawmode: TDrawMode; APixelCenteredCoordinates: boolean);
     3197begin
     3198  BGRAPolygon.FillPolyAliasedWithTexture(self, points, texture, FillMode = fmWinding, drawmode, APixelCenteredCoordinates);
    30493199end;
    30503200
     
    30573207end;
    30583208
    3059 procedure TBGRADefaultBitmap.FillPolyAntialias(const points: array of TPointF; c: TBGRAPixel);
    3060 begin
    3061   BGRAPolygon.FillPolyAntialias(self, points, c, FEraseMode, FillMode = fmWinding, LinearAntialiasing);
     3209procedure TBGRADefaultBitmap.FillPolyAntialias(const points: array of TPointF; c: TBGRAPixel; APixelCenteredCoordinates: boolean);
     3210begin
     3211  BGRAPolygon.FillPolyAntialias(self, points, c, FEraseMode, FillMode = fmWinding, LinearAntialiasing, APixelCenteredCoordinates);
    30623212end;
    30633213
    30643214procedure TBGRADefaultBitmap.FillPolyAntialias(const points: array of TPointF;
    3065   texture: IBGRAScanner);
    3066 begin
    3067   BGRAPolygon.FillPolyAntialiasWithTexture(self, points, texture, FillMode = fmWinding, LinearAntialiasing);
     3215  texture: IBGRAScanner; APixelCenteredCoordinates: boolean);
     3216begin
     3217  BGRAPolygon.FillPolyAntialiasWithTexture(self, points, texture, FillMode = fmWinding, LinearAntialiasing, APixelCenteredCoordinates);
    30683218end;
    30693219
    30703220procedure TBGRADefaultBitmap.ErasePoly(const points: array of TPointF;
    3071   alpha: byte);
    3072 begin
    3073   BGRAPolygon.FillPolyAliased(self, points, BGRA(0, 0, 0, alpha), True, FillMode = fmWinding, dmDrawWithTransparency);
    3074 end;
    3075 
    3076 procedure TBGRADefaultBitmap.ErasePolyAntialias(const points: array of TPointF; alpha: byte);
     3221  alpha: byte; APixelCenteredCoordinates: boolean);
     3222begin
     3223  BGRAPolygon.FillPolyAliased(self, points, BGRA(0, 0, 0, alpha), True, FillMode = fmWinding, dmDrawWithTransparency, APixelCenteredCoordinates);
     3224end;
     3225
     3226procedure TBGRADefaultBitmap.ErasePolyAntialias(const points: array of TPointF; alpha: byte; APixelCenteredCoordinates: boolean);
    30773227begin
    30783228  FEraseMode := True;
    3079   FillPolyAntialias(points, BGRA(0, 0, 0, alpha));
     3229  FillPolyAntialias(points, BGRA(0, 0, 0, alpha), APixelCenteredCoordinates);
    30803230  FEraseMode := False;
    30813231end;
     
    31553305  c: TBGRAPixel; w: single);
    31563306begin
    3157   if (PenStyle = psClear) or (c.alpha = 0) then exit;
     3307  if (PenStyle = psClear) or (c.alpha = 0) or (w = 0) then exit;
    31583308  if (PenStyle = psSolid) then
    31593309    BGRAPolygon.BorderEllipseAntialias(self, x, y, rx, ry, w, c, FEraseMode, LinearAntialiasing)
     
    31623312end;
    31633313
     3314procedure TBGRADefaultBitmap.EllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF;
     3315  c: TBGRAPixel; w: single);
     3316begin
     3317  if (PenStyle = psClear) or (c.alpha = 0) or (w = 0) then exit;
     3318  DrawPolygonAntialias(ComputeEllipseContour(AOrigin, AXAxis, AYAxis),c,w);
     3319end;
     3320
    31643321procedure TBGRADefaultBitmap.EllipseAntialias(x, y, rx, ry: single;
    31653322  texture: IBGRAScanner; w: single);
    31663323begin
    3167   if (PenStyle = psClear) then exit;
     3324  if (PenStyle = psClear) or (w = 0) then exit;
    31683325  if (PenStyle = psSolid) then
    31693326    BGRAPolygon.BorderEllipseAntialiasWithTexture(self, x, y, rx, ry, w, texture, LinearAntialiasing)
     
    31723329end;
    31733330
     3331procedure TBGRADefaultBitmap.EllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF;
     3332  texture: IBGRAScanner; w: single);
     3333begin
     3334  if (PenStyle = psClear) or (w = 0) then exit;
     3335  DrawPolygonAntialias(ComputeEllipseContour(AOrigin, AXAxis, AYAxis),texture,w);
     3336end;
     3337
    31743338procedure TBGRADefaultBitmap.EllipseAntialias(x, y, rx, ry: single;
    31753339  c: TBGRAPixel; w: single; back: TBGRAPixel);
     
    31773341    hw: single;
    31783342begin
    3179   if w=0 then exit;
     3343  if (w=0) or (PenStyle = psClear) or (c.alpha = 0) then
     3344  begin
     3345    FillEllipseAntialias(x, y, rx, ry, back);
     3346    exit;
     3347  end;
    31803348  rx := abs(rx);
    31813349  ry := abs(ry);
     
    31883356  { use multishape filler for fine junction between polygons }
    31893357  multi := TBGRAMultishapeFiller.Create;
    3190   if not (PenStyle = psClear) and (c.alpha <> 0) then
    3191   begin
    3192     if (PenStyle = psSolid) then
    3193     begin
    3194       multi.AddEllipse(x,y,rx-hw,ry-hw,back);
    3195       multi.AddEllipseBorder(x,y,rx,ry,w,c)
    3196     end
    3197     else
    3198     begin
    3199       multi.AddEllipse(x,y,rx,ry,back);
    3200       multi.AddPolygon(ComputeWidePolygon(ComputeEllipseContour(x,y,rx,ry),w),c);
    3201       multi.PolygonOrder := poLastOnTop;
    3202     end;
    3203   end;
     3358  if (PenStyle = psSolid) then
     3359  begin
     3360    if back.alpha <> 0 then multi.AddEllipse(x,y,rx-hw,ry-hw,back);
     3361    multi.AddEllipseBorder(x,y,rx,ry,w,c)
     3362  end
     3363  else
     3364  begin
     3365    if back.alpha <> 0 then multi.AddEllipse(x,y,rx,ry,back);
     3366    multi.AddPolygon(ComputeWidePolygon(ComputeEllipseContour(x,y,rx,ry),w),c);
     3367  end;
     3368  multi.PolygonOrder := poLastOnTop;
    32043369  multi.Draw(self);
    32053370  multi.Free;
    32063371end;
    32073372
     3373procedure TBGRADefaultBitmap.EllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF;
     3374  c: TBGRAPixel; w: single; back: TBGRAPixel);
     3375var multi: TBGRAMultishapeFiller;
     3376    pts: ArrayOfTPointF;
     3377begin
     3378  if (w=0) or (PenStyle = psClear) or (c.alpha = 0) then
     3379  begin
     3380    FillEllipseAntialias(AOrigin, AXAxis, AYAxis, back);
     3381    exit;
     3382  end;
     3383  { use multishape filler for fine junction between polygons }
     3384  multi := TBGRAMultishapeFiller.Create;
     3385  pts := ComputeEllipseContour(AOrigin, AXAxis, AYAxis);
     3386  if back.alpha <> 0 then multi.AddPolygon(pts, back);
     3387  pts := ComputeWidePolygon(pts,w);
     3388  multi.AddPolygon(pts,c);
     3389  multi.PolygonOrder := poLastOnTop;
     3390  multi.Draw(self);
     3391  multi.Free;
     3392end;
     3393
    32083394procedure TBGRADefaultBitmap.FillEllipseAntialias(x, y, rx, ry: single; c: TBGRAPixel);
    32093395begin
    32103396  BGRAPolygon.FillEllipseAntialias(self, x, y, rx, ry, c, FEraseMode, LinearAntialiasing);
     3397end;
     3398
     3399procedure TBGRADefaultBitmap.FillEllipseAntialias(AOrigin, AXAxis,
     3400  AYAxis: TPointF; c: TBGRAPixel);
     3401var
     3402  pts: array of TPointF;
     3403begin
     3404  if c.alpha = 0 then exit;
     3405  pts := ComputeEllipseContour(AOrigin,AXAxis,AYAxis);
     3406  FillPolyAntialias(pts, c);
    32113407end;
    32123408
     
    32153411begin
    32163412  BGRAPolygon.FillEllipseAntialiasWithTexture(self, x, y, rx, ry, texture, LinearAntialiasing);
     3413end;
     3414
     3415procedure TBGRADefaultBitmap.FillEllipseAntialias(AOrigin, AXAxis,
     3416  AYAxis: TPointF; texture: IBGRAScanner);
     3417var
     3418  pts: array of TPointF;
     3419begin
     3420  pts := ComputeEllipseContour(AOrigin,AXAxis,AYAxis);
     3421  FillPolyAntialias(pts, texture);
    32173422end;
    32183423
     
    32413446end;
    32423447
     3448procedure TBGRADefaultBitmap.FillEllipseLinearColorAntialias(AOrigin, AXAxis,
     3449  AYAxis: TPointF; outercolor, innercolor: TBGRAPixel);
     3450var
     3451  grad: TBGRAGradientScanner;
     3452  affine: TBGRAAffineScannerTransform;
     3453begin
     3454  grad := TBGRAGradientScanner.Create(innercolor,outercolor,gtRadial,PointF(0,0),PointF(1,0),True);
     3455  affine := TBGRAAffineScannerTransform.Create(grad);
     3456  affine.Fit(AOrigin,AXAxis,AYAxis);
     3457  FillEllipseAntialias(AOrigin,AXAxis,AYAxis,affine);
     3458  affine.Free;
     3459  grad.Free;
     3460end;
     3461
    32433462procedure TBGRADefaultBitmap.EraseEllipseAntialias(x, y, rx, ry: single; alpha: byte);
    32443463begin
    32453464  FEraseMode := True;
    32463465  FillEllipseAntialias(x, y, rx, ry, BGRA(0, 0, 0, alpha));
     3466  FEraseMode := False;
     3467end;
     3468
     3469procedure TBGRADefaultBitmap.EraseEllipseAntialias(AOrigin, AXAxis,
     3470  AYAxis: TPointF; alpha: byte);
     3471begin
     3472  FEraseMode := True;
     3473  FillEllipseAntialias(AOrigin, AXAxis, AYAxis, BGRA(0, 0, 0, alpha));
    32473474  FEraseMode := False;
    32483475end;
     
    37073934  c: TBGRAPixel; options: TRoundRectangleOptions; pixelCenteredCoordinates: boolean);
    37083935begin
    3709   if not pixelCenteredCoordinates then
    3710   begin
    3711     x -= 0.5;
    3712     y -= 0.5;
    3713     x2 -= 0.5;
    3714     y2 -= 0.5;
    3715   end;
    3716   BGRAPolygon.FillRoundRectangleAntialias(self,x,y,x2,y2,rx,ry,options,c,False, LinearAntialiasing);
     3936  BGRAPolygon.FillRoundRectangleAntialias(self,x,y,x2,y2,rx,ry,options,c,False, LinearAntialiasing, pixelCenteredCoordinates);
    37173937end;
    37183938
     
    37203940  ry: single; texture: IBGRAScanner; options: TRoundRectangleOptions; pixelCenteredCoordinates: boolean);
    37213941begin
    3722   if not pixelCenteredCoordinates then
    3723   begin
    3724     x -= 0.5;
    3725     y -= 0.5;
    3726     x2 -= 0.5;
    3727     y2 -= 0.5;
    3728   end;
    3729   BGRAPolygon.FillRoundRectangleAntialiasWithTexture(self,x,y,x2,y2,rx,ry,options,texture, LinearAntialiasing);
     3942  BGRAPolygon.FillRoundRectangleAntialiasWithTexture(self,x,y,x2,y2,rx,ry,options,texture, LinearAntialiasing, pixelCenteredCoordinates);
    37303943end;
    37313944
     
    37333946  ry: single; alpha: byte; options: TRoundRectangleOptions; pixelCenteredCoordinates: boolean);
    37343947begin
    3735   if not pixelCenteredCoordinates then
    3736   begin
    3737     x -= 0.5;
    3738     y -= 0.5;
    3739     x2 -= 0.5;
    3740     y2 -= 0.5;
    3741   end;
    3742   BGRAPolygon.FillRoundRectangleAntialias(self,x,y,x2,y2,rx,ry,options,BGRA(0,0,0,alpha),True, LinearAntialiasing);
     3948  BGRAPolygon.FillRoundRectangleAntialias(self,x,y,x2,y2,rx,ry,options,BGRA(0,0,0,alpha),True, LinearAntialiasing, pixelCenteredCoordinates);
     3949end;
     3950
     3951procedure TBGRADefaultBitmap.Ellipse(x, y, rx, ry: single; c: TBGRAPixel;
     3952  w: single; ADrawMode: TDrawMode);
     3953begin
     3954  if (PenStyle = psClear) or (c.alpha = 0) or (w = 0) then exit;
     3955  if (PenStyle = psSolid) then
     3956    BGRAPolygon.BorderEllipse(self, x, y, rx, ry, w, c, FEraseMode, ADrawMode)
     3957  else
     3958    FillPoly(ComputeWidePolygon(ComputeEllipseContour(x,y,rx,ry),w),c, ADrawMode);
     3959end;
     3960
     3961procedure TBGRADefaultBitmap.Ellipse(AOrigin, AXAxis, AYAxis: TPointF;
     3962  c: TBGRAPixel; w: single; ADrawMode: TDrawMode);
     3963begin
     3964  if (PenStyle = psClear) or (c.alpha = 0) or (w = 0) then exit;
     3965  FillPoly(ComputeWidePolygon(ComputeEllipseContour(AOrigin, AXAxis, AYAxis),w),c,ADrawMode);
    37433966end;
    37443967
     
    37553978end;
    37563979
     3980procedure TBGRADefaultBitmap.FillRoundRect(X1, Y1, X2, Y2: integer; DX,
     3981  DY: integer; FillTexture: IBGRAScanner; ADrawMode: TDrawMode);
     3982begin
     3983  BGRAFillRoundRectAliased(self,X1,Y1,X2,Y2,DX,DY,BGRAPixelTransparent,FillTexture,ADrawMode);
     3984end;
     3985
    37573986{------------------------- Text functions ---------------------------------------}
    37583987
     
    37814010end;
    37824011
     4012procedure TBGRADefaultBitmap.TextMultiline(ALeft, ATop, AWidth: single; sUTF8: string;
     4013  c: TBGRAPixel; AAlign: TBidiTextAlignment; AVertAlign: TTextLayout; AParagraphSpacing: single);
     4014var
     4015  layout: TBidiTextLayout;
     4016  i: Integer;
     4017begin
     4018  if FontBidiMode = fbmAuto then
     4019    layout := TBidiTextLayout.Create(FontRenderer, sUTF8)
     4020  else
     4021    layout := TBidiTextLayout.Create(FontRenderer, sUTF8, GetFontRightToLeftFor(sUTF8));
     4022  for i := 0 to layout.ParagraphCount-1 do
     4023    layout.ParagraphAlignment[i] := AAlign;
     4024  layout.ParagraphSpacingBelow:= AParagraphSpacing;
     4025  layout.AvailableWidth := AWidth;
     4026  case AVertAlign of
     4027    tlBottom: layout.TopLeft := PointF(ALeft,ATop-layout.TotalTextHeight);
     4028    tlCenter: layout.TopLeft := PointF(ALeft,ATop-layout.TotalTextHeight/2);
     4029    else layout.TopLeft := PointF(ALeft,ATop);
     4030  end;
     4031  layout.DrawText(self, c);
     4032  layout.Free;
     4033end;
     4034
     4035procedure TBGRADefaultBitmap.TextMultiline(ALeft, ATop, AWidth: single;
     4036  sUTF8: string; ATexture: IBGRAScanner; AAlign: TBidiTextAlignment;
     4037  AVertAlign: TTextLayout; AParagraphSpacing: single);
     4038var
     4039  layout: TBidiTextLayout;
     4040  i: Integer;
     4041begin
     4042  if FontBidiMode = fbmAuto then
     4043    layout := TBidiTextLayout.Create(FontRenderer, sUTF8)
     4044  else
     4045    layout := TBidiTextLayout.Create(FontRenderer, sUTF8, GetFontRightToLeftFor(sUTF8));
     4046  for i := 0 to layout.ParagraphCount-1 do
     4047    layout.ParagraphAlignment[i] := AAlign;
     4048  layout.ParagraphSpacingBelow:= AParagraphSpacing;
     4049  layout.AvailableWidth := AWidth;
     4050  case AVertAlign of
     4051    tlBottom: layout.TopLeft := PointF(ALeft,ATop-layout.TotalTextHeight);
     4052    tlCenter: layout.TopLeft := PointF(ALeft,ATop-layout.TotalTextHeight/2);
     4053    else layout.TopLeft := PointF(ALeft,ATop);
     4054  end;
     4055  layout.DrawText(self, ATexture);
     4056  layout.Free;
     4057end;
     4058
    37834059procedure TBGRADefaultBitmap.TextOut(x, y: single; sUTF8: string;
    3784   texture: IBGRAScanner; align: TAlignment);
    3785 begin
    3786   FontRenderer.TextOut(self,x,y,CleanTextOutString(sUTF8),texture,align);
     4060  texture: IBGRAScanner; align: TAlignment; ARightToLeft: boolean);
     4061begin
     4062  FontRenderer.TextOut(self,x,y,CleanTextOutString(sUTF8),texture,align, ARightToLeft);
    37874063end;
    37884064
    37894065procedure TBGRADefaultBitmap.TextOut(x, y: single; sUTF8: string;
    3790   c: TBGRAPixel; align: TAlignment);
     4066  c: TBGRAPixel; align: TAlignment; ARightToLeft: boolean);
    37914067begin
    37924068  with (PointF(x,y)-GetFontAnchorRotatedOffset) do
    3793     FontRenderer.TextOut(self,x,y,CleanTextOutString(sUTF8),c,align);
     4069    FontRenderer.TextOut(self,x,y,CleanTextOutString(sUTF8),c,align, ARightToLeft);
    37944070end;
    37954071
     
    38124088function TBGRADefaultBitmap.TextSize(sUTF8: string): TSize;
    38134089begin
    3814   result := FontRenderer.TextSize(sUTF8);
     4090  result := FontRenderer.TextSize(CleanTextOutString(sUTF8));
     4091end;
     4092
     4093function TBGRADefaultBitmap.TextAffineBox(sUTF8: string): TAffineBox;
     4094var size: TSize;
     4095  m: TAffineMatrix;
     4096  dy: single;
     4097begin
     4098  dy := GetFontVerticalAnchorOffset;
     4099  size := FontRenderer.TextSizeAngle(sUTF8, FontOrientation);
     4100  m := AffineMatrixRotationDeg(-FontOrientation*0.1);
     4101  result := TAffineBox.AffineBox(PointF(0,-dy), m*PointF(size.cx,-dy), m*PointF(0,size.cy-dy));
     4102end;
     4103
     4104function TBGRADefaultBitmap.TextSize(sUTF8: string; AMaxWidth: integer): TSize;
     4105begin
     4106  result := FontRenderer.TextSize(sUTF8, AMaxWidth, GetFontRightToLeftFor(sUTF8));
     4107end;
     4108
     4109function TBGRADefaultBitmap.TextSize(sUTF8: string; AMaxWidth: integer;
     4110  ARightToLeft: boolean): TSize;
     4111begin
     4112  result := FontRenderer.TextSize(sUTF8, AMaxWidth, ARightToLeft);
     4113end;
     4114
     4115function TBGRADefaultBitmap.TextFitInfo(sUTF8: string; AMaxWidth: integer
     4116  ): integer;
     4117begin
     4118  result := FontRenderer.TextFitInfo(sUTF8, AMaxWidth);
    38154119end;
    38164120
     
    38744178end;
    38754179
     4180function TBGRADefaultBitmap.ComputeEllipseContour(AOrigin, AXAxis,
     4181  AYAxis: TPointF; quality: single): ArrayOfTPointF;
     4182begin
     4183  result := BGRAPath.ComputeEllipse(AOrigin,AXAxis,AYAxis, quality);
     4184end;
     4185
    38764186function TBGRADefaultBitmap.ComputeEllipseBorder(x, y, rx, ry, w: single; quality: single): ArrayOfTPointF;
    38774187begin
    38784188  result := ComputeWidePolygon(ComputeEllipseContour(x,y,rx,ry, quality),w);
     4189end;
     4190
     4191function TBGRADefaultBitmap.ComputeEllipseBorder(AOrigin, AXAxis,
     4192  AYAxis: TPointF; w: single; quality: single): ArrayOfTPointF;
     4193begin
     4194  result := ComputeWidePolygon(ComputeEllipseContour(AOrigin,AXAxis,AYAxis, quality),w);
    38794195end;
    38804196
     
    39804296  self.FillRect(X,Y,X+AMask.Width,Y+AMask.Height,scan,ADrawMode);
    39814297  scan.Free;
     4298end;
     4299
     4300procedure TBGRADefaultBitmap.EraseMask(x, y: integer; AMask: TBGRACustomBitmap;
     4301  alpha: byte);
     4302var
     4303  x0,y0,x2, y2, yb,xb, tx, delta: integer;
     4304  p, psrc: PBGRAPixel;
     4305begin
     4306  if (AMask = nil) or (alpha = 0) then exit;
     4307  x0 := x;
     4308  y0 := y;
     4309  x2 := x+AMask.Width;
     4310  y2 := y+AMask.Height;
     4311  if not CheckClippedRectBounds(x,y,x2,y2) then exit;
     4312  tx := x2 - x;
     4313  Dec(x2);
     4314  Dec(y2);
     4315
     4316  p := Scanline[y] + x;
     4317  if FLineOrder = riloBottomToTop then
     4318    delta := -Width
     4319  else
     4320    delta := Width;
     4321
     4322  for yb := y to y2 do
     4323  begin
     4324    psrc := AMask.ScanLine[yb-y0]+(x-x0);
     4325    if alpha = 255 then
     4326    begin
     4327      for xb := tx-1 downto 0 do
     4328      begin
     4329        ErasePixelInline(p, psrc^.green);
     4330        inc(p);
     4331        inc(psrc);
     4332      end;
     4333    end else
     4334    begin
     4335      for xb := tx-1 downto 0 do
     4336      begin
     4337        ErasePixelInline(p, ApplyOpacity(psrc^.green,alpha));
     4338        inc(p);
     4339        inc(psrc);
     4340      end;
     4341    end;
     4342    dec(p, tx);
     4343    Inc(p, delta);
     4344  end;
     4345
     4346  InvalidateBitmap;
    39824347end;
    39834348
     
    41754540      exit;
    41764541    StartMask := $FFFFFFFF shl (X1 and 31);
    4177     if X2 and 31 = 31 then
    4178       EndMask := $FFFFFFFF
     4542    case X2 and 31 of
     4543    31: EndMask := $FFFFFFFF;
     4544    30: EndMask := $7FFFFFFF;
    41794545    else
    41804546      EndMask := 1 shl ((X2 and 31) + 1) - 1;
     4547    end;
    41814548    StartPos := X1 shr 5 + AY * VisitedLineSize;
    41824549    EndPos := X2 shr 5 + AY * VisitedLineSize;
     
    46535020      end;
    46545021      InvalidateBitmap;
     5022      if (Source is TBGRADefaultBitmap) and Assigned(TBGRADefaultBitmap(Source).XorMask) then
     5023        PutImage(x,y,TBGRADefaultBitmap(Source).XorMask,dmXor,AOpacity);
    46555024    end;
    46565025    dmDrawWithTransparency:
     
    46805049      end;
    46815050      InvalidateBitmap;
     5051      if (Source is TBGRADefaultBitmap) and Assigned(TBGRADefaultBitmap(Source).XorMask) then
     5052        PutImage(x,y,TBGRADefaultBitmap(Source).XorMask,dmXor,AOpacity);
    46825053    end;
    46835054    dmFastBlend:
     
    47065077      end;
    47075078      InvalidateBitmap;
     5079      if (Source is TBGRADefaultBitmap) and Assigned(TBGRADefaultBitmap(Source).XorMask) then
     5080        PutImage(x,y,TBGRADefaultBitmap(Source).XorMask,dmXor,AOpacity);
    47085081    end;
    47095082    dmXor:
     
    48755248procedure TBGRADefaultBitmap.StretchPutImage(ARect: TRect;
    48765249  Source: TBGRACustomBitmap; mode: TDrawMode; AOpacity: byte);
     5250var noTransition: boolean;
    48775251begin
    48785252  If (Source = nil) or (AOpacity = 0) then exit;
     
    48805254     PutImage(ARect.Left,ARect.Top,Source,mode,AOpacity)
    48815255  else
    4882      BGRAResample.StretchPutImage(Source, ARect.Right-ARect.Left, ARect.Bottom-ARect.Top, self, ARect.left,ARect.Top, mode, AOpacity);
     5256  begin
     5257     noTransition:= (mode = dmXor) or ((mode in [dmDrawWithTransparency,dmFastBlend,dmSetExceptTransparent]) and
     5258                                       (Source is TBGRADefaultBitmap) and
     5259                                       Assigned(TBGRADefaultBitmap(Source).XorMask));
     5260     BGRAResample.StretchPutImage(Source, ARect.Right-ARect.Left, ARect.Bottom-ARect.Top, self, ARect.left,ARect.Top, mode, AOpacity, noTransition);
     5261    if (mode in [dmDrawWithTransparency,dmFastBlend,dmSetExceptTransparent]) and Assigned(TBGRADefaultBitmap(Source).XorMask) then
     5262      BGRAResample.StretchPutImage(TBGRADefaultBitmap(Source).XorMask, ARect.Right-ARect.Left, ARect.Bottom-ARect.Top, self, ARect.left,ARect.Top, dmXor, AOpacity, noTransition);
     5263  end;
    48835264end;
    48845265
    48855266{ Duplicate bitmap content. Optionally, bitmap properties can be also duplicated }
    4886 function TBGRADefaultBitmap.Duplicate(DuplicateProperties: Boolean = False): TBGRACustomBitmap;
     5267function TBGRADefaultBitmap.Duplicate(DuplicateProperties: Boolean = False; DuplicateXorMask: Boolean = False): TBGRACustomBitmap;
    48875268var Temp: TBGRADefaultBitmap;
    48885269begin
     
    48935274  if DuplicateProperties then
    48945275    CopyPropertiesTo(Temp);
     5276  if DuplicateXorMask and Assigned(XorMask) then
     5277    Temp.FXorMask := FXorMask.Duplicate(True) as TBGRADefaultBitmap;
    48955278  Result := Temp;
    48965279end;
     
    49085291  ABitmap.FontAntialias := FontAntialias;
    49095292  ABitmap.FontOrientation := FontOrientation;
     5293  ABitmap.FontBidiMode:= FontBidiMode;
    49105294  ABitmap.LineCap := LineCap;
    49115295  ABitmap.JoinStyle := JoinStyle;
    49125296  ABitmap.FillMode := FillMode;
    49135297  ABitmap.ClipRect := ClipRect;
     5298  ABitmap.HotSpot := HotSpot;
    49145299end;
    49155300
     
    51855570end;
    51865571
     5572function TBGRADefaultBitmap.GetHasSemiTransparentPixels: boolean;
     5573var
     5574  n: integer;
     5575  p: PBGRAPixel;
     5576begin
     5577  p := Data;
     5578  for n := NbPixels - 1 downto 0 do
     5579  begin
     5580    if (p^.alpha > 0) and (p^.alpha < 255) then
     5581    begin
     5582      result := true;
     5583      exit;
     5584    end;
     5585    inc(p);
     5586  end;
     5587  result := false;
     5588end;
     5589
    51875590function TBGRADefaultBitmap.GetAverageColor: TColor;
    51885591var
     
    53185721  freemem(line);
    53195722  InvalidateBitmap;
     5723
     5724  if Assigned(XorMask) then XorMask.VerticalFlip(ARect);
    53205725end;
    53215726
     
    53515756  end;
    53525757  InvalidateBitmap;
     5758
     5759  if Assigned(XorMask) then XorMask.HorizontalFlip(ARect);
    53535760end;
    53545761
     
    53775784    end;
    53785785  end;
     5786
     5787  if Assigned(XorMask) then TBGRADefaultBitmap(result).FXorMask := self.XorMask.RotateCW;
    53795788end;
    53805789
     
    54035812    end;
    54045813  end;
     5814
     5815  if Assigned(XorMask) then TBGRADefaultBitmap(result).FXorMask := self.XorMask.RotateCCW;
    54055816end;
    54065817
     
    55495960  end;
    55505961  InvalidateBitmap;
     5962end;
     5963
     5964function TBGRADefaultBitmap.GetMaskFromAlpha: TBGRACustomBitmap;
     5965var y,x: integer;
     5966  psrc, pdest: PBGRAPixel;
     5967begin
     5968  result := BGRABitmapFactory.Create(Width,Height);
     5969  for y := 0 to self.Height-1 do
     5970  begin
     5971    psrc := self.ScanLine[y];
     5972    pdest := result.ScanLine[y];
     5973    for x := 0 to self.Width-1 do
     5974    begin
     5975      pdest^ := BGRA(psrc^.alpha,psrc^.alpha,psrc^.alpha);
     5976      inc(psrc);
     5977      inc(pdest);
     5978    end;
     5979  end;
    55515980end;
    55525981
     
    59636392end;
    59646393
    5965 function TBGRAPtrBitmap.Duplicate(DuplicateProperties: Boolean = False): TBGRACustomBitmap;
     6394function TBGRAPtrBitmap.Duplicate(DuplicateProperties: Boolean = False; DuplicateXorMask: Boolean = False): TBGRACustomBitmap;
    59666395begin
    59676396  Result := NewBitmap(Width, Height);
    59686397  if DuplicateProperties then CopyPropertiesTo(TBGRADefaultBitmap(Result));
     6398  if DuplicateXorMask and Assigned(XorMask) then
     6399    TBGRADefaultBitmap(Result).FXorMask := FXorMask.Duplicate(True);
    59696400end;
    59706401
     
    60076438end;
    60086439
    6009 procedure TBGRAPtrBitmap.LoadFromDevice(DC: System.THandle);
    6010 begin
    6011   CannotResize;
    6012 end;
    6013 
    6014 procedure TBGRAPtrBitmap.LoadFromDevice(DC: System.THandle; ARect: TRect);
    6015 begin
    6016   CannotResize;
     6440procedure TBGRAPtrBitmap.LoadFromDevice(DC: HDC);
     6441begin
     6442  NotImplemented;
     6443end;
     6444
     6445procedure TBGRAPtrBitmap.LoadFromDevice(DC: HDC; ARect: TRect);
     6446begin
     6447  NotImplemented;
    60176448end;
    60186449
Note: See TracChangeset for help on using the changeset viewer.