1892 lines
97 KiB
PHP
1892 lines
97 KiB
PHP
// SPDX-License-Identifier: LGPL-3.0-linking-exception
|
|
{$IFDEF INCLUDE_INTERFACE}
|
|
{$UNDEF INCLUDE_INTERFACE}
|
|
type
|
|
{=== TBGRACustomBitmap ===}
|
|
|
|
{ TBGRACustomBitmap }
|
|
{* @abstract(Base class for TBGRABitmap.)
|
|
|
|
It is the direct parent of TBGRADefaultBitmap class, which is the parent of the diverse
|
|
implementations. A bitmap can be used as a scanner using the IBGRAScanner interface.
|
|
}
|
|
TBGRACustomBitmap = class(specialize TGenericUniversalBitmap<TBGRAPixel,TBGRAPixelColorspace>,IBGRAScanner)
|
|
protected
|
|
FXorMask: TBGRACustomBitmap;
|
|
|
|
{ accessors to properies }
|
|
procedure SetXorMask(AValue: TBGRACustomBitmap);
|
|
|
|
function GetAverageColor: TColor; virtual; abstract;
|
|
function GetAveragePixel: TBGRAPixel; virtual; abstract;
|
|
|
|
//FreePascal drawing routines
|
|
{$IFDEF BGRABITMAP_USE_FPCANVAS}function GetCanvasFP: TFPImageCanvas; virtual; abstract;{$ENDIF}
|
|
function GetCanvasDrawModeFP: TDrawMode; virtual; abstract;
|
|
procedure SetCanvasDrawModeFP(const AValue: TDrawMode); virtual; abstract;
|
|
|
|
//GUI bitmap object
|
|
function GetBitmap: TBitmap; virtual; abstract;
|
|
function GetCanvas: TCanvas; virtual; abstract;
|
|
function GetCanvasOpacity: byte; virtual; abstract;
|
|
procedure SetCanvasOpacity(AValue: byte); virtual; abstract;
|
|
function GetCanvasAlphaCorrection: boolean; virtual; abstract;
|
|
procedure SetCanvasAlphaCorrection(const AValue: boolean); virtual; abstract;
|
|
|
|
procedure Init; override;
|
|
function InternalNew: TBGRACustomBitmap; override;
|
|
|
|
procedure InternalArc(cx,cy,rx,ry: single; const StartPoint,EndPoint: TPointF; ABorderColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel; AOptions: TArcOptions; ADrawChord: boolean = false; ATexture: IBGRAScanner = nil); overload;
|
|
procedure InternalArc(cx,cy,rx,ry: single; StartAngleRad,EndAngleRad: Single; ABorderColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel; AOptions: TArcOptions; ADrawChord: boolean = false; ATexture: IBGRAScanner = nil); overload; virtual; abstract;
|
|
procedure InternalArcInRect(r: TRect; StartAngleRad,EndAngleRad: Single; ABorderColor : TBGRAPixel; w: single; AFillColor: TBGRAPixel; AOptions: TArcOptions; ADrawChord: boolean = false; ATexture: IBGRAScanner = nil);
|
|
procedure InternalFillArcInRect(r: TRect; StartAngleRad,EndAngleRad: Single; AFillColor: TBGRAPixel; AOptions: TArcOptions; ATexture: IBGRAScanner = nil);
|
|
|
|
public
|
|
{** Resample filter is used when resizing the bitmap. See [[BGRABitmap Miscellaneous types#Images and resampling|resampling types]] }
|
|
ResampleFilter : TResampleFilter;
|
|
|
|
{** Scan interpolation filter is used when the bitmap is used
|
|
as a scanner (interface ''IBGRAScanner'') }
|
|
ScanInterpolationFilter: TResampleFilter;
|
|
ScanMaskChannel: TChannel;
|
|
|
|
{** Cursor position for mouse pointer }
|
|
HotSpot: TPoint;
|
|
|
|
{ ** Free reference to xor mask }
|
|
procedure DiscardXorMask; virtual;
|
|
{ ** Allocate xor mask }
|
|
procedure NeedXorMask; virtual;
|
|
{** Xor mask to be applied when image is drawn }
|
|
property XorMask: TBGRACustomBitmap read FXorMask write SetXorMask;
|
|
|
|
{** Average color of the image }
|
|
property AverageColor: TColor Read GetAverageColor;
|
|
{** Average color (including alpha) of the image }
|
|
property AveragePixel: TBGRAPixel Read GetAveragePixel;
|
|
|
|
{** Canvas compatible with FreePascal }
|
|
{$IFDEF BGRABITMAP_USE_FPCANVAS}property CanvasFP: TFPImageCanvas read GetCanvasFP;{$ENDIF}
|
|
|
|
{** Draw mode to used when image is access using FreePascal functions
|
|
and ''Colors'' property }
|
|
property CanvasDrawModeFP: TDrawMode read GetCanvasDrawModeFP write SetCanvasDrawModeFP;
|
|
|
|
{** Bitmap in a format compatible with the current GUI.
|
|
Don't forget to call ''InvalidateBitmap'' before using it
|
|
if you changed something with direct pixel access (''Scanline''
|
|
and ''Data'') }
|
|
property Bitmap: TBitmap Read GetBitmap;
|
|
{** Canvas provided by the GUI }
|
|
property Canvas: TCanvas Read GetCanvas;
|
|
{** Opacity to apply to changes made using GUI functions, provided
|
|
''CanvasAlphaCorrection'' is set to ''True'' }
|
|
property CanvasOpacity: byte Read GetCanvasOpacity Write SetCanvasOpacity;
|
|
{** Specifies if the alpha values must be corrected after GUI access
|
|
to the bitmap }
|
|
property CanvasAlphaCorrection: boolean Read GetCanvasAlphaCorrection Write SetCanvasAlphaCorrection;
|
|
|
|
protected {----------- pen style accessors ----------------}
|
|
function GetPenJoinStyle: TPenJoinStyle; virtual; abstract;
|
|
procedure SetPenJoinStyle(const AValue: TPenJoinStyle); virtual; abstract;
|
|
function GetPenMiterLimit: single; virtual; abstract;
|
|
procedure SetPenMiterLimit(const AValue: single); virtual; abstract;
|
|
function GetPenStyle: TPenStyle; virtual; abstract;
|
|
procedure SetPenStyle(const AValue: TPenStyle); virtual; abstract;
|
|
function GetCustomPenStyle: TBGRAPenStyle; virtual; abstract;
|
|
procedure SetCustomPenStyle(const AValue: TBGRAPenStyle); virtual; abstract;
|
|
|
|
function GetArrowEndRepeat: integer; virtual; abstract;
|
|
function GetArrowStartRepeat: integer; virtual; abstract;
|
|
procedure SetArrowEndRepeat(AValue: integer); virtual; abstract;
|
|
procedure SetArrowStartRepeat(AValue: integer); virtual; abstract;
|
|
function GetArrowEndOffset: single; virtual; abstract;
|
|
function GetArrowStartOffset: single; virtual; abstract;
|
|
procedure SetArrowEndOffset(AValue: single); virtual; abstract;
|
|
procedure SetArrowStartOffset(AValue: single); virtual; abstract;
|
|
function GetArrowEndSize: TPointF; virtual; abstract;
|
|
function GetArrowStartSize: TPointF; virtual; abstract;
|
|
procedure SetArrowEndSize(AValue: TPointF); virtual; abstract;
|
|
procedure SetArrowStartSize(AValue: TPointF); virtual; abstract;
|
|
|
|
public {----------- pen style ----------------}
|
|
{** How to join segments. See [[BGRABitmap Types imported from Graphics|BGRAGraphics]] }
|
|
property JoinStyle: TPenJoinStyle read GetPenJoinStyle Write SetPenJoinStyle;
|
|
{** Limit for the extension of the segments when joining them
|
|
with ''pjsMiter'' join style, expressed in multiples of the width
|
|
of the pen }
|
|
property JoinMiterLimit: single read GetPenMiterLimit Write SetPenMiterLimit;
|
|
{** Pen style. See [[BGRABitmap Types imported from Graphics|BGRAGraphics]] }
|
|
property PenStyle: TPenStyle read GetPenStyle Write SetPenStyle;
|
|
{** Custom pen style. See [[BGRABitmap Geometry types|geometric types]] }
|
|
property CustomPenStyle: TBGRAPenStyle read GetCustomPenStyle write SetCustomPenStyle;
|
|
|
|
{** Size of arrows at the start of the line }
|
|
property ArrowStartSize: TPointF read GetArrowStartSize write SetArrowStartSize;
|
|
{** Size of arrows at the end of the line }
|
|
property ArrowEndSize: TPointF read GetArrowEndSize write SetArrowEndSize;
|
|
{** Offset of the arrow from the start of the line }
|
|
property ArrowStartOffset: single read GetArrowStartOffset write SetArrowStartOffset;
|
|
{** Offset of the arrow from the end of the line }
|
|
property ArrowEndOffset: single read GetArrowEndOffset write SetArrowEndOffset;
|
|
{** Number of times to repeat the starting arrow }
|
|
property ArrowStartRepeat: integer read GetArrowStartRepeat write SetArrowStartRepeat;
|
|
{** Number of times to repeat the ending arrow }
|
|
property ArrowEndRepeat: integer read GetArrowEndRepeat write SetArrowEndRepeat;
|
|
|
|
procedure ArrowStartAsNone; virtual; abstract;
|
|
procedure ArrowStartAsClassic(AFlipped: boolean = false; ACut: boolean = false; ARelativePenWidth: single = 1); virtual; abstract;
|
|
procedure ArrowStartAsTriangle(ABackOffset: single = 0; ARounded: boolean = false; AHollow: boolean = false; AHollowPenWidth: single = 0.5); virtual; abstract;
|
|
procedure ArrowStartAsTail; virtual; abstract;
|
|
|
|
procedure ArrowEndAsNone; virtual; abstract;
|
|
procedure ArrowEndAsClassic(AFlipped: boolean = false; ACut: boolean = false; ARelativePenWidth: single = 1); virtual; abstract;
|
|
procedure ArrowEndAsTriangle(ABackOffset: single = 0; ARounded: boolean = false; AHollow: boolean = false; AHollowPenWidth: single = 0.5); virtual; abstract;
|
|
procedure ArrowEndAsTail; virtual; abstract;
|
|
|
|
protected {-------------------font style accessors------------------------}
|
|
function GetFontAntialias: Boolean;
|
|
procedure SetFontAntialias(const AValue: Boolean);
|
|
function GetFontRenderer: TBGRACustomFontRenderer; virtual; abstract;
|
|
procedure SetFontRenderer(AValue: TBGRACustomFontRenderer); virtual; abstract;
|
|
function GetFontHeight: integer; virtual; abstract;
|
|
procedure SetFontHeight(AHeight: integer); virtual; abstract;
|
|
function GetFontFullHeight: integer; virtual; abstract;
|
|
procedure SetFontFullHeight(AHeight: integer); virtual; abstract;
|
|
function GetFontVerticalAnchorOffset: single; virtual; abstract;
|
|
function GetFontPixelMetric: TFontPixelMetric; virtual; abstract;
|
|
|
|
function GetFontRightToLeftFor(AText: string): boolean;
|
|
|
|
public {-------------------font style------------------------}
|
|
{** Specifies the font to use. Unless the font renderer accept otherwise,
|
|
the name is in human readable form, like 'Arial', 'Times New Roman', ... }
|
|
FontName: string;
|
|
{** Specifies the set of styles to be applied to the font.
|
|
These can be ''fsBold'', ''fsItalic'', ''fsStrikeOut'', ''fsUnderline''.
|
|
So the value [''fsBold'',''fsItalic''] means that the font must be bold and italic.
|
|
See [[BGRABitmap Miscellaneous types|miscellaneous types]] }
|
|
FontStyle: TFontStyles;
|
|
|
|
{** Specifies the quality of rendering. Default value is ''fqSystem''.
|
|
See [[BGRABitmap Miscellaneous types|miscellaneous types]] }
|
|
FontQuality : TBGRAFontQuality;
|
|
|
|
{** Specifies the rotation of the text, for functions that support text rotation.
|
|
It is expressed in tenth of degrees, positive values going counter-clockwise. }
|
|
FontOrientation: integer;
|
|
|
|
{** Specifies how the font is vertically aligned relative to the start coordinate.
|
|
See [[BGRABitmap Miscellaneous types|miscellaneous types]]}
|
|
FontVerticalAnchor: TFontVerticalAnchor;
|
|
|
|
{** Specifies the base direction of the text (cf Unicode). By default, it is
|
|
automatically determined by the first strongly oriented character.
|
|
You can specify another base direction here however it is not taken
|
|
into account by the LCL on Linux. }
|
|
FontBidiMode: TFontBidiMode;
|
|
|
|
{** Specifies the height of the font in pixels without taking into account
|
|
additional line spacing. A negative value means that it is the
|
|
full height instead (see below) }
|
|
property FontHeight: integer Read GetFontHeight Write SetFontHeight;
|
|
|
|
{** Specifies the height of the font in pixels, taking into account the
|
|
additional line spacing defined for the font }
|
|
property FontFullHeight: integer read GetFontFullHeight write SetFontFullHeight;
|
|
|
|
{** Simplified property to specify the quality (see ''FontQuality'') }
|
|
property FontAntialias: Boolean read GetFontAntialias write SetFontAntialias;
|
|
|
|
property FontVerticalAnchorOffset: single read GetFontVerticalAnchorOffset;
|
|
|
|
{** Returns measurement for the current font in pixels }
|
|
property FontPixelMetric: TFontPixelMetric read GetFontPixelMetric;
|
|
|
|
{** Specifies the font renderer. When working with the LCL,
|
|
by default it is an instance of ''TLCLFontRenderer'' of
|
|
unit ''BGRAText''. Other renderers are provided in ''BGRATextFX''
|
|
unit and ''BGRAVectorize'' unit. Additionally, ''BGRAFreeType''
|
|
provides a renderer independent from the LCL.
|
|
*
|
|
* Once you assign a renderer, it will automatically be freed when
|
|
the bitmap is freed. The renderers may provide additional styling
|
|
for the font, not accessible with the properties in this class
|
|
*
|
|
* See [[BGRABitmap tutorial Font rendering|font rendering]]}
|
|
property FontRenderer: TBGRACustomFontRenderer read GetFontRenderer write SetFontRenderer;
|
|
|
|
public
|
|
constructor Create(AFPImage: TFPCustomImage; ACopyProperties: Boolean=False); overload; virtual; abstract;
|
|
constructor Create(ABitmap: TBitmap); overload; virtual; abstract;
|
|
constructor Create(ABitmap: TBitmap; AUseTransparent: boolean); overload; virtual; abstract;
|
|
constructor Create(AFilename: string); overload; virtual; abstract;
|
|
constructor Create(AFilename: string; AIsUtf8Filename: boolean); overload; virtual; abstract;
|
|
constructor Create(AFilename: string; AIsUtf8Filename: boolean; AOptions: TBGRALoadingOptions); overload; virtual; abstract;
|
|
constructor Create(AStream: TStream); overload; virtual; abstract;
|
|
|
|
function NewBitmap: TBGRACustomBitmap; overload; override;
|
|
function NewBitmap(AWidth, AHeight: integer): TBGRACustomBitmap; overload; override;
|
|
function NewBitmap(AWidth, AHeight: integer; const Color: TBGRAPixel): TBGRACustomBitmap; overload; override;
|
|
function NewBitmap(AWidth, AHeight: integer; AColor: Pointer): TBGRACustomBitmap; overload; override;
|
|
function NewBitmap(Filename: string): TBGRACustomBitmap; overload; virtual; abstract;
|
|
function NewBitmap(Filename: string; AIsUtf8: boolean): TBGRACustomBitmap; overload; virtual; abstract;
|
|
function NewBitmap(Filename: string; AIsUtf8: boolean; AOptions: TBGRALoadingOptions): TBGRACustomBitmap; overload; virtual; abstract;
|
|
function NewBitmap(AFPImage: TFPCustomImage): TBGRACustomBitmap; overload; virtual; abstract;
|
|
|
|
procedure LoadFromStream(AStream: TStream; AHandler: TFPCustomImageReader; AOptions: TBGRALoadingOptions); override;
|
|
|
|
{==== Reference counting ====}
|
|
|
|
{** Adds a reference (this reference count is not the same as
|
|
the reference count of an interface, it changes only by
|
|
explicit calls) }
|
|
function NewReference: TBGRACustomBitmap; override;
|
|
{** Returns an object with a reference count equal to 1. Duplicate
|
|
this bitmap if necessary }
|
|
function GetUnique: TBGRACustomBitmap; override;
|
|
function Duplicate(DuplicateProperties: Boolean = False): TBGRACustomBitmap; overload; override;
|
|
function Duplicate(DuplicateProperties, DuplicateXorMask: Boolean): TBGRACustomBitmap; overload; virtual;
|
|
procedure CopyPropertiesTo(ABitmap: TCustomUniversalBitmap); override;
|
|
function GetPart(const ARect: TRect; ACopyProperties: Boolean=False): TBGRACustomBitmap; override;
|
|
|
|
function CreateBrushTexture(ABrushStyle: TBrushStyle; APatternColor, ABackgroundColor: TBGRAPixel;
|
|
AWidth: integer = 8; AHeight: integer = 8; APenWidth: single = 1): TBGRACustomBitmap; override;
|
|
|
|
{** Can only be called with an existing instance of ''TBGRACustomBitmap''.
|
|
Sets the dimensions of an existing ''TBGRACustomBitmap'' instance. }
|
|
procedure SetSize(AWidth, AHeight: integer); override;
|
|
|
|
{==== Retrieve image from system ====}
|
|
|
|
{** Gets the content of the specified device context }
|
|
procedure LoadFromDevice(DC: HDC); overload; virtual; abstract;
|
|
{** Gets the content from the specified rectangular area of a device context }
|
|
procedure LoadFromDevice(DC: HDC; ARect: TRect); overload; virtual; abstract;
|
|
{** Fills the content with a screenshot of the primary monitor }
|
|
procedure TakeScreenshotOfPrimaryMonitor; virtual; abstract;
|
|
{** Fills the content with a screenshot of the specified rectangular area of the desktop
|
|
(it can be from any screen) }
|
|
procedure TakeScreenshot(ARect: TRect); virtual; abstract;
|
|
{** For more methods, see derived class [[TBGRABitmap class|TBGRABitmap]] }
|
|
|
|
{==== Drawing functions ====}
|
|
|
|
{Pixel functions}
|
|
procedure SetPixel(x, y: int32or64; c: TColor); overload; virtual; abstract;
|
|
procedure XorPixel(x, y: int32or64; const c: TBGRAPixel); overload; virtual; abstract;
|
|
procedure DrawPixel(x, y: int32or64; const c: TBGRAPixel; ADrawMode: TDrawMode); overload; override;
|
|
procedure FastBlendPixel(x, y: int32or64; const c: TBGRAPixel); virtual; abstract;
|
|
function GetPixel256(x, y, fracX256,fracY256: int32or64; AResampleFilter: TResampleFilter = rfLinear; smoothBorder: boolean = true): TBGRAPixel; virtual; abstract;
|
|
function GetPixel(x, y: single; AResampleFilter: TResampleFilter = rfLinear; smoothBorder: boolean = true): TBGRAPixel; overload; virtual; abstract;
|
|
function GetPixelCycle(x, y: single; AResampleFilter: TResampleFilter = rfLinear): TBGRAPixel; overload; virtual; abstract;
|
|
function GetPixelCycle(x, y: single; AResampleFilter: TResampleFilter; repeatX: boolean; repeatY: boolean): TBGRAPixel; overload; virtual; abstract;
|
|
function GetPixelCycle256(x, y, fracX256,fracY256: int32or64; AResampleFilter: TResampleFilter = rfLinear): TBGRAPixel; overload; virtual; abstract;
|
|
function GetPixelCycle256(x, y, fracX256,fracY256: int32or64; AResampleFilter: TResampleFilter; repeatX: boolean; repeatY: boolean): TBGRAPixel; overload; virtual; abstract;
|
|
|
|
{Line primitives}
|
|
procedure XorHorizLine(x, y, x2: int32or64; c: TBGRAPixel); virtual; abstract;
|
|
procedure DrawHorizLine(x, y, x2: int32or64; ec: TExpandedPixel); overload; virtual; abstract;
|
|
procedure DrawHorizLine(x, y, x2: int32or64; texture: IBGRAScanner); overload;
|
|
procedure FastBlendHorizLine(x, y, x2: int32or64; c: TBGRAPixel); virtual; abstract;
|
|
procedure DrawHorizLineDiff(x, y, x2: int32or64; c, compare: TBGRAPixel; maxDiff: byte); virtual; abstract;
|
|
procedure HorizLineDiff(x, y, x2: int32or64; const ABrush: TUniversalBrush; ACompare: TBGRAPixel; AMaxDiffW: word); virtual; abstract;
|
|
|
|
procedure XorVertLine(x, y, y2: int32or64; c: TBGRAPixel); virtual; abstract;
|
|
procedure DrawVertLine(x, y, y2: int32or64; c: TBGRAPixel); virtual; abstract;
|
|
procedure FastBlendVertLine(x, y, y2: int32or64; c: TBGRAPixel); virtual; abstract;
|
|
|
|
{==== Rectangles, ellipses and path (floating point coordinates) ====}
|
|
{* These functions use the current pen style/cap/join. The parameter ''w''
|
|
specifies the width of the line and the base unit for dashes
|
|
* The coordinates are pixel-centered, so that when filling a rectangle,
|
|
if the supplied values are integers, the border will be half transparent.
|
|
If you want the border to be completely filled, you can subtract/add
|
|
0.5 to the coordinates to include the remaining thin border.
|
|
See [[BGRABitmap tutorial 13|coordinate system]]. }
|
|
|
|
{==== Multi-shape fill ====}
|
|
|
|
{** Draws and fill a polyline using current pen style/cap/join in one go.
|
|
The stroke is stricly over the fill even if partially transparent.
|
|
''fillcolor'' specifies a color to fill the polygon formed by the points }
|
|
procedure DrawPolyLineAntialias(const points: array of TPointF; c: TBGRAPixel; w: single; fillcolor: TBGRAPixel); overload; virtual; abstract;
|
|
{** Draws a filled polygon using current pen style/cap/join in one go.
|
|
The stroke is stricly over the fill even if partially transparent.
|
|
The polygon is always closed. You don't need to set the last point
|
|
to be the same as the first point. }
|
|
procedure DrawPolygonAntialias(const points: array of TPointF; c: TBGRAPixel; w: single; fillcolor: TBGRAPixel); overload; virtual; abstract;
|
|
|
|
procedure EllipseAntialias(x, y, rx, ry: single; c: TBGRAPixel; w: single; back: TBGRAPixel); overload; virtual; abstract;
|
|
procedure EllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; c: TBGRAPixel; w: single; back: TBGRAPixel); overload; virtual; abstract;
|
|
|
|
procedure DrawPath(APath: IBGRAPath; AStrokeColor: TBGRAPixel; AWidth: single; AFillColor: TBGRAPixel); overload; virtual; abstract;
|
|
procedure DrawPath(APath: IBGRAPath; AStrokeTexture: IBGRAScanner; AWidth: single; AFillColor: TBGRAPixel); overload; virtual; abstract;
|
|
procedure DrawPath(APath: IBGRAPath; AStrokeColor: TBGRAPixel; AWidth: single; AFillTexture: IBGRAScanner); overload; virtual; abstract;
|
|
procedure DrawPath(APath: IBGRAPath; AStrokeTexture: IBGRAScanner; AWidth: single; AFillTexture: IBGRAScanner); overload; virtual; abstract;
|
|
|
|
procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeColor: TBGRAPixel; AWidth: single; AFillColor: TBGRAPixel); overload; virtual; abstract;
|
|
procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeTexture: IBGRAScanner; AWidth: single; AFillColor: TBGRAPixel); overload; virtual; abstract;
|
|
procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeColor: TBGRAPixel; AWidth: single; AFillTexture: IBGRAScanner); overload; virtual; abstract;
|
|
procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeTexture: IBGRAScanner; AWidth: single; AFillTexture: IBGRAScanner); overload; virtual; abstract;
|
|
|
|
{==== Gradient/textured polygons ====}
|
|
|
|
procedure FillTriangleLinearColor(pt1,pt2,pt3: TPointF; c1,c2,c3: TBGRAPixel); overload; virtual; abstract;
|
|
procedure FillTriangleLinearColorAntialias(pt1,pt2,pt3: TPointF; c1,c2,c3: TBGRAPixel); overload; virtual; abstract;
|
|
procedure FillTriangleLinearMapping(pt1,pt2,pt3: TPointF; texture: IBGRAScanner; tex1, tex2, tex3: TPointF; TextureInterpolation: Boolean= True); overload; virtual; abstract;
|
|
{$IFNDEF BGRABITMAP_CORE}{ Fills a triangle with linear mapping of a texture and lightness }
|
|
procedure FillTriangleLinearMappingLightness(pt1,pt2,pt3: TPointF; texture: IBGRAScanner;
|
|
tex1, tex2, tex3: TPointF; light1,light2,light3: word;
|
|
TextureInterpolation: Boolean= True); overload; virtual; abstract; {$ENDIF}
|
|
procedure FillTriangleLinearMappingAntialias(pt1,pt2,pt3: TPointF; texture: IBGRAScanner; tex1, tex2, tex3: TPointF); overload; virtual; abstract;
|
|
|
|
procedure FillQuadLinearColor(pt1,pt2,pt3,pt4: TPointF; c1,c2,c3,c4: TBGRAPixel); overload; virtual; abstract;
|
|
procedure FillQuadLinearColorAntialias(pt1,pt2,pt3,pt4: TPointF; c1,c2,c3,c4: TBGRAPixel); overload; virtual; abstract;
|
|
procedure FillQuadLinearMapping(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; TextureInterpolation: Boolean= True; ACulling: TFaceCulling = fcNone; ACropToPolygon: boolean = true); overload; virtual; abstract;
|
|
{$IFNDEF BGRABITMAP_CORE}{ Fills a quadrilateral with linear mapping and lightness }
|
|
procedure FillQuadLinearMappingLightness(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner;
|
|
tex1, tex2, tex3, tex4: TPointF; light1,light2,light3,light4: word;
|
|
TextureInterpolation: Boolean= True); overload; virtual; abstract;{$ENDIF}
|
|
procedure FillQuadLinearMappingAntialias(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; ACulling: TFaceCulling = fcNone); overload; virtual; abstract;
|
|
procedure FillQuadPerspectiveMapping(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; ADrawMode: TDrawMode = dmDrawWithTransparency); overload; virtual; abstract;
|
|
procedure FillQuadPerspectiveMapping(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; ACleanBorders: TRect; ADrawMode: TDrawMode = dmDrawWithTransparency); overload; virtual; abstract;
|
|
procedure FillQuadPerspectiveMappingAntialias(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF); overload; virtual; abstract;
|
|
procedure FillQuadPerspectiveMappingAntialias(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; ACleanBorders: TRect); overload; virtual; abstract;
|
|
procedure FillQuadAffineMapping(Orig,HAxis,VAxis: TPointF; AImage: TBGRACustomBitmap; APixelCenteredCoordinates: boolean = true; ADrawMode: TDrawMode = dmDrawWithTransparency; AOpacity: byte = 255); virtual; abstract;
|
|
procedure FillQuadAffineMappingAntialias(Orig,HAxis,VAxis: TPointF; AImage: TBGRACustomBitmap; APixelCenteredCoordinates: boolean = true; AOpacity: byte = 255); virtual; abstract;
|
|
|
|
procedure FillEllipseLinearColorAntialias(x, y, rx, ry: single; outercolor, innercolor: TBGRAPixel); overload; virtual; abstract;
|
|
procedure FillEllipseLinearColorAntialias(AOrigin, AXAxis, AYAxis: TPointF; outercolor, innercolor: TBGRAPixel); overload; virtual; abstract;
|
|
|
|
{$IFNDEF BGRABITMAP_CORE}
|
|
procedure FillPolyLinearColor(const points: array of TPointF; AColors: array of TBGRAPixel); overload; virtual; abstract;
|
|
procedure FillPolyLinearMapping(const points: array of TPointF; texture: IBGRAScanner; texCoords: array of TPointF; TextureInterpolation: Boolean); overload; virtual; abstract;
|
|
procedure FillPolyLinearMappingLightness(const points: array of TPointF; texture: IBGRAScanner; texCoords: array of TPointF; lightnesses: array of word; TextureInterpolation: Boolean); overload; virtual; abstract;
|
|
procedure FillPolyPerspectiveMapping(const points: array of TPointF; const pointsZ: array of single; texture: IBGRAScanner; texCoords: array of TPointF; TextureInterpolation: Boolean; zbuffer: psingle = nil); overload; virtual; abstract;
|
|
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); overload; virtual; abstract;
|
|
{$ENDIF}
|
|
|
|
procedure Arc(cx,cy,rx,ry: single; const StartPoint,EndPoint: TPointF; AColor: TBGRAPixel; w: single; ADrawChord: boolean; AFillColor: TBGRAPixel); overload;
|
|
procedure Arc(cx,cy,rx,ry: single; StartAngleRad,EndAngleRad: Single; AColor: TBGRAPixel; w: single; ADrawChord: boolean; AFillColor: TBGRAPixel); overload;
|
|
procedure FillChord(cx,cy,rx,ry: single; const StartPoint,EndPoint: TPointF; AFillColor: TBGRAPixel); overload;
|
|
procedure FillChord(cx,cy,rx,ry: single; StartAngleRad,EndAngleRad: Single; AFillColor: TBGRAPixel); overload;
|
|
procedure FillChord(cx,cy,rx,ry: single; const StartPoint,EndPoint: TPointF; texture: IBGRAScanner); overload;
|
|
procedure FillChord(cx,cy,rx,ry: single; StartAngleRad,EndAngleRad: Single; texture: IBGRAScanner); overload;
|
|
procedure FillChordInRect(const ARect: TRect; StartAngleRad,EndAngleRad: Single; AFillColor: TBGRAPixel); overload;
|
|
procedure FillChordInRect(const ARect: TRect; StartAngleRad,EndAngleRad: Single; texture: IBGRAScanner); overload;
|
|
|
|
procedure Pie(cx,cy,rx,ry: single; const StartPoint,EndPoint: TPointF; AColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel); overload;
|
|
procedure Pie(cx,cy,rx,ry: single; StartAngleRad,EndAngleRad: Single; AColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel); overload;
|
|
procedure FillPie(cx,cy,rx,ry: single; const StartPoint,EndPoint: TPointF; AFillColor: TBGRAPixel); overload;
|
|
procedure FillPie(cx,cy,rx,ry: single; StartAngleRad,EndAngleRad: Single; AFillColor: TBGRAPixel); overload;
|
|
procedure FillPie(cx,cy,rx,ry: single; const StartPoint,EndPoint: TPointF; texture: IBGRAScanner); overload;
|
|
procedure FillPie(cx,cy,rx,ry: single; StartAngleRad,EndAngleRad: Single; texture: IBGRAScanner); overload;
|
|
procedure FillPieInRect(const ARect: TRect; StartAngleRad,EndAngleRad: Single; AFillColor: TBGRAPixel); overload;
|
|
procedure FillPieInRect(const ARect: TRect; StartAngleRad,EndAngleRad: Single; texture: IBGRAScanner); overload;
|
|
|
|
procedure RectangleAntialias(x, y, x2, y2: single; c: TBGRAPixel; w: single; back: TBGRAPixel); overload; virtual; abstract;
|
|
procedure RectangleWithin(x1,y1,x2,y2: single; ABorderColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel; APixelCenteredCoordinates: boolean = true); overload;
|
|
procedure RectangleWithin(r: TRect; ABorderColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel); overload;
|
|
|
|
procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; c: TBGRAPixel; w: single; options: TRoundRectangleOptions = []); overload; virtual; abstract;
|
|
procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; pencolor: TBGRAPixel; w: single; fillcolor: TBGRAPixel; options: TRoundRectangleOptions = []); overload; virtual; abstract;
|
|
procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; penTexture: IBGRAScanner; w: single; fillTexture: IBGRAScanner; options: TRoundRectangleOptions = []); overload; virtual; abstract;
|
|
procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; texture: IBGRAScanner; w: single; options: TRoundRectangleOptions = []); overload; virtual; abstract;
|
|
|
|
{** Fills completely a rectangle, without any border, with the
|
|
specified ''texture'' and with the specified ''mode'' and optional dithering algorithm }
|
|
procedure FillRect(r: TRect; texture: IBGRAScanner; mode: TDrawMode; ditheringAlgorithm: TDitheringAlgorithm); overload; virtual;
|
|
procedure FillRect(r: TRect; texture: IBGRAScanner; mode: TDrawMode; AScanOffset: TPoint; ditheringAlgorithm: TDitheringAlgorithm); overload; virtual;
|
|
procedure FillRect(x, y, x2, y2: integer; texture: IBGRAScanner; mode: TDrawMode; ditheringAlgorithm: TDitheringAlgorithm); overload; virtual;
|
|
procedure FillRect(x, y, x2, y2: integer; texture: IBGRAScanner; mode: TDrawMode; AScanOffset: TPoint; ditheringAlgorithm: TDitheringAlgorithm); overload; virtual; abstract;
|
|
|
|
procedure TextOutCurved(ACursor: TBGRACustomPathCursor; const sUTF8: string; AColor: TBGRAPixel; AAlign: TAlignment; ALetterSpacing: single); overload; virtual; abstract;
|
|
procedure TextOutCurved(ACursor: TBGRACustomPathCursor; const sUTF8: string; ATexture: IBGRAScanner; AAlign: TAlignment; ALetterSpacing: single); overload; virtual; abstract;
|
|
procedure TextOutCurved(APath: IBGRAPath; const sUTF8: string; AColor: TBGRAPixel; AAlign: TAlignment; ALetterSpacing: single); overload; virtual;
|
|
procedure TextOutCurved(APath: IBGRAPath; const sUTF8: string; ATexture: IBGRAScanner; AAlign: TAlignment; ALetterSpacing: single); overload; virtual;
|
|
procedure TextRect(ARect: TRect; x, y: integer; const sUTF8: string; style: TTextStyle; c: TBGRAPixel); overload; virtual; abstract;
|
|
procedure TextRect(ARect: TRect; x, y: integer; const sUTF8: string; style: TTextStyle; texture: IBGRAScanner); overload; virtual; abstract;
|
|
|
|
{$IFNDEF BGRABITMAP_CORE}
|
|
{ Draw text taking into account line endings, filling it with a solid color }
|
|
procedure TextMultiline(x,y: single; const sUTF8: string; c: TBGRAPixel;
|
|
AAlign: TBidiTextAlignment = btaLeftJustify; AVertAlign: TTextLayout = tlTop; AParagraphSpacing: single = 0); overload;
|
|
{ Draw text taking into account line endings, filling it with a texture }
|
|
procedure TextMultiline(x,y: single; const sUTF8: string; ATexture: IBGRAScanner;
|
|
AAlign: TBidiTextAlignment = btaLeftJustify; AVertAlign: TTextLayout = tlTop; AParagraphSpacing: single = 0); overload;
|
|
{ Draw text with line breaks, filling it with a solid color }
|
|
procedure TextMultiline(ALeft,ATop,AWidth: single; const sUTF8: string; c: TBGRAPixel;
|
|
AAlign: TBidiTextAlignment = btaNatural; AVertAlign: TTextLayout = tlTop; AParagraphSpacing: single = 0); overload; virtual; abstract;
|
|
{ Draw text with line breaks, filling it with a texture }
|
|
procedure TextMultiline(ALeft,ATop,AWidth: single; const sUTF8: string; ATexture: IBGRAScanner;
|
|
AAlign: TBidiTextAlignment = btaNatural; AVertAlign: TTextLayout = tlTop; AParagraphSpacing: single = 0); overload; virtual; abstract;
|
|
{$ENDIF}
|
|
|
|
function TextSize(const sUTF8: string): TSize; overload; virtual; abstract;
|
|
function TextAffineBox(const sUTF8: string): TAffineBox; virtual; abstract;
|
|
function TextSize(const sUTF8: string; AMaxWidth: integer): TSize; overload; virtual; abstract;
|
|
function TextSize(const sUTF8: string; AMaxWidth: integer; ARightToLeft: boolean): TSize; overload; virtual; abstract;
|
|
function TextFitInfo(const sUTF8: string; AMaxWidth: integer): integer; virtual; abstract;
|
|
{$IFNDEF BGRABITMAP_CORE}{ Returns the total size of the string provided using the current font
|
|
and taking into account line breaks. }
|
|
function TextSizeMultiline(const sUTF8: string; AMaxWidth: single = EmptySingle;
|
|
AParagraphSpacing: single = 0): TSize; virtual; abstract;{$ENDIF}
|
|
|
|
{ Draw the UTF8 encoded string, (x,y) being the top-left corner by default. The color c or texture is used to fill the text.
|
|
The value of FontOrientation is taken into account, so that the text may be rotated. }
|
|
procedure TextOut(x, y: single; const sUTF8: string; c: TBGRAPixel; align: TAlignment); overload; virtual;
|
|
procedure TextOut(x, y: single; const sUTF8: string; texture: IBGRAScanner; align: TAlignment); overload; virtual;
|
|
procedure TextOut(x, y: single; const sUTF8: string; c: TBGRAPixel); overload; virtual;
|
|
procedure TextOut(x, y: single; const sUTF8: string; c: TBGRAPixel; ARightToLeft: boolean); overload; virtual;
|
|
procedure TextOut(x, y: single; const sUTF8: string; c: TColor); overload; virtual;
|
|
procedure TextOut(x, y: single; const sUTF8: string; c: TColor; ARightToLeft: boolean); overload; virtual;
|
|
procedure TextOut(x, y: single; const sUTF8: string; texture: IBGRAScanner); overload; virtual;
|
|
procedure TextOut(x, y: single; const sUTF8: string; texture: IBGRAScanner; ARightToLeft: boolean); overload; virtual;
|
|
procedure TextOut(x, y: single; const sUTF8: string; c: TBGRAPixel; align: TAlignment; ARightToLeft: boolean); overload; virtual; abstract;
|
|
procedure TextOut(x, y: single; const sUTF8: string; texture: IBGRAScanner; align: TAlignment; ARightToLeft: boolean); overload; virtual; abstract;
|
|
procedure TextOut(x, y: single; const sUTF8: string; AColor: TBGRAPixel; AAlign: TAlignment; ALetterSpacing: single); overload; virtual; abstract;
|
|
procedure TextOut(x, y: single; const sUTF8: string; ATexture: IBGRAScanner; AAlign: TAlignment; ALetterSpacing: single); overload; virtual; abstract;
|
|
|
|
{ Overrides the font orientation with the parameter orientationTenthDegCCW }
|
|
procedure TextOutAngle(x, y: single; orientationTenthDegCCW: integer; const sUTF8: string; c: TBGRAPixel); overload; virtual;
|
|
procedure TextOutAngle(x, y: single; orientationTenthDegCCW: integer; const sUTF8: string; c: TBGRAPixel; align: TAlignment); overload; virtual;
|
|
procedure TextOutAngle(x, y: single; orientationTenthDegCCW: integer; const sUTF8: string; c: TBGRAPixel; align: TAlignment; ARightToLeft: boolean); overload; virtual; abstract;
|
|
procedure TextOutAngle(x, y: single; orientationTenthDegCCW: integer; const sUTF8: string; texture: IBGRAScanner); overload; virtual;
|
|
procedure TextOutAngle(x, y: single; orientationTenthDegCCW: integer; const sUTF8: string; texture: IBGRAScanner; align: TAlignment); overload; virtual;
|
|
procedure TextOutAngle(x, y: single; orientationTenthDegCCW: integer; const sUTF8: string; texture: IBGRAScanner; align: TAlignment; ARightToLeft: boolean); overload; virtual; abstract;
|
|
|
|
{ Draw the UTF8 encoded string in the rectangle ARect. Text is wrapped if necessary.
|
|
The position depends on the specified horizontal alignment halign and vertical alignement valign.
|
|
The color c or texture is used to fill the text. No rotation is applied. }
|
|
procedure TextRect(ARect: TRect; const sUTF8: string; halign: TAlignment; valign: TTextLayout; c: TBGRAPixel); overload; virtual;
|
|
procedure TextRect(ARect: TRect; const sUTF8: string; halign: TAlignment; valign: TTextLayout; texture: IBGRAScanner); overload; virtual;
|
|
|
|
//-------------------------- computing path ------------------------------------
|
|
|
|
{Spline}
|
|
function ComputeClosedSpline(const APoints: array of TPointF; AStyle: TSplineStyle): ArrayOfTPointF; virtual; abstract;
|
|
function ComputeOpenedSpline(const APoints: array of TPointF; AStyle: TSplineStyle): ArrayOfTPointF; virtual; abstract;
|
|
function ComputeBezierCurve(const curve: TCubicBezierCurve): ArrayOfTPointF; overload; virtual; abstract;
|
|
function ComputeBezierCurve(const curve: TQuadraticBezierCurve): ArrayOfTPointF; overload; virtual; abstract;
|
|
function ComputeBezierSpline(const spline: array of TCubicBezierCurve): ArrayOfTPointF; overload; virtual; abstract;
|
|
function ComputeBezierSpline(const spline: array of TQuadraticBezierCurve): ArrayOfTPointF; overload; virtual; abstract;
|
|
|
|
{can be accessed via Pen property}
|
|
function ComputeWidePolyline(const points: array of TPointF; w: single): ArrayOfTPointF; overload; virtual; abstract;
|
|
function ComputeWidePolyline(const points: array of TPointF; w: single; ClosedCap: boolean): ArrayOfTPointF; overload; virtual; abstract;
|
|
function ComputeWidePolygon(const points: array of TPointF; w: single): ArrayOfTPointF; virtual; abstract;
|
|
|
|
function ComputeEllipse(x,y,rx,ry: single): ArrayOfTPointF; overload; deprecated;
|
|
function ComputeEllipse(x,y,rx,ry,w: single): ArrayOfTPointF; overload; deprecated;
|
|
function ComputeEllipseContour(x,y,rx,ry: single; quality: single = 1): ArrayOfTPointF; overload; virtual; abstract;
|
|
function ComputeEllipseContour(AOrigin, AXAxis, AYAxis: TPointF; quality: single = 1): ArrayOfTPointF; overload; virtual; abstract;
|
|
function ComputeEllipseBorder(x,y,rx,ry,w: single; quality: single = 1): ArrayOfTPointF; overload; virtual; abstract;
|
|
function ComputeEllipseBorder(AOrigin, AXAxis, AYAxis: TPointF; w: single; quality: single = 1): ArrayOfTPointF; overload; virtual; abstract;
|
|
function ComputeArc65536(x,y,rx,ry: single; start65536,end65536: word; quality: single = 1): ArrayOfTPointF; virtual; abstract;
|
|
function ComputeArcRad(x,y,rx,ry: single; startRad,endRad: single; quality: single = 1): ArrayOfTPointF; virtual; abstract;
|
|
function ComputeRoundRect(x1,y1,x2,y2,rx,ry: single; quality: single = 1): ArrayOfTPointF; overload; virtual; abstract;
|
|
function ComputeRoundRect(x1,y1,x2,y2,rx,ry: single; options: TRoundRectangleOptions; quality: single = 1): ArrayOfTPointF; overload; virtual; abstract;
|
|
function ComputePie65536(x,y,rx,ry: single; start65536,end65536: word; quality: single = 1): ArrayOfTPointF; virtual; abstract;
|
|
function ComputePieRad(x,y,rx,ry: single; startRad,endRad: single; quality: single = 1): ArrayOfTPointF; virtual; abstract;
|
|
|
|
{Filling}
|
|
|
|
// compatibility: take into account ClipRect
|
|
procedure Fill(texture: IBGRAScanner); overload; virtual;
|
|
procedure Fill(texture: IBGRAScanner; mode: TDrawMode); overload; override;
|
|
|
|
procedure Fill(c: TBGRAPixel; start, Count: integer); overload; virtual; abstract;
|
|
procedure DrawPixels(c: TBGRAPixel; start, Count: integer); virtual; abstract;
|
|
procedure AlphaFill(alpha: byte; start, Count: integer); overload; virtual; abstract;
|
|
procedure ReplaceColor(before, after: TColor); overload; virtual; abstract;
|
|
procedure ReplaceColor(ARect: TRect; before, after: TColor); overload; virtual; abstract;
|
|
procedure FloodFill(X, Y: integer; Color: TBGRAPixel;
|
|
mode: TFloodfillMode; Tolerance: byte = 0); overload; virtual;
|
|
procedure FloodFill(X, Y: integer; const Brush: TUniversalBrush;
|
|
Progressive: boolean; ToleranceW: Word = $00ff); overload; virtual;
|
|
procedure ParallelFloodFill(X, Y: integer; Dest: TCustomUniversalBitmap; Color: TBGRAPixel;
|
|
mode: TFloodfillMode; Tolerance: byte = 0; DestOfsX: integer = 0; DestOfsY: integer = 0); overload; virtual; abstract;
|
|
procedure ParallelFloodFill(X, Y: integer; Dest: TCustomUniversalBitmap; const Brush: TUniversalBrush;
|
|
Progressive: boolean; ToleranceW: Word = $00ff; DestOfsX: integer = 0; DestOfsY: integer = 0); overload; virtual; abstract;
|
|
procedure GradientFill(x, y, x2, y2: integer; c1, c2: TBGRAPixel;
|
|
gtype: TGradientType; o1, o2: TPointF; mode: TDrawMode;
|
|
gammaColorCorrection: boolean = True; Sinus: Boolean=False;
|
|
ditherAlgo: TDitheringAlgorithm = daNearestNeighbor); overload; virtual; abstract;
|
|
procedure GradientFill(x, y, x2, y2: integer; gradient: TBGRACustomGradient;
|
|
gtype: TGradientType; o1, o2: TPointF; mode: TDrawMode;
|
|
Sinus: Boolean=False;
|
|
ditherAlgo: TDitheringAlgorithm = daNearestNeighbor); overload; virtual; abstract;
|
|
|
|
{Canvas drawing functions}
|
|
procedure DataDrawTransparent(ACanvas: TCanvas; Rect: TRect;
|
|
AData: Pointer; ALineOrder: TRawImageLineOrder; AWidth, AHeight: integer); virtual; abstract;
|
|
procedure DataDrawOpaque(ACanvas: TCanvas; ARect: TRect; AData: Pointer;
|
|
ALineOrder: TRawImageLineOrder; AWidth, AHeight: integer); virtual; abstract;
|
|
procedure GetImageFromCanvas(CanvasSource: TCanvas; x, y: integer); virtual; abstract;
|
|
procedure Draw(ACanvas: TCanvas; x, y: integer; Opaque: boolean = True); overload; virtual; abstract;
|
|
procedure Draw(ACanvas: TCanvas; Rect: TRect; Opaque: boolean = True); overload; virtual; abstract;
|
|
procedure DrawPart(ARect: TRect; ACanvas: TCanvas; x, y: integer; Opaque: boolean); overload; virtual;
|
|
procedure DrawPart(ARect: TRect; ACanvas: TCanvas; ATargetRect: TRect; Opaque: boolean); overload; virtual;
|
|
function GetPtrBitmap(Top,Bottom: Integer): TBGRACustomBitmap; virtual; abstract;
|
|
function MakeBitmapCopy(BackgroundColor: TColor; AMasked: boolean = False): TBitmap; virtual; abstract;
|
|
|
|
{BGRA bitmap functions}
|
|
procedure CrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadePosition: byte; mode: TDrawMode = dmDrawWithTransparency); overload; virtual; abstract;
|
|
procedure CrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadeMask: IBGRAScanner; mode: TDrawMode = dmDrawWithTransparency); overload; virtual; abstract;
|
|
procedure PutImage(x, y: integer; Source: TBitmap; mode: TDrawMode; AOpacity: byte = 255); overload;
|
|
procedure StretchPutImage(ARect: TRect; Source: TBitmap; mode: TDrawMode; AOpacity: byte = 255); overload;
|
|
procedure StretchPutImage(ARect: TRect; Source: TBGRACustomBitmap; mode: TDrawMode; AOpacity: byte = 255); overload; virtual; abstract;
|
|
procedure StretchPutImageProportionally(ARect: TRect; AHorizAlign: TAlignment; AVertAlign: TTextLayout;
|
|
Source: TBGRACustomBitmap; mode: TDrawMode; AOpacity: byte = 255; ACover: boolean = false);
|
|
procedure PutImageSubpixel(x, y: single; Source: TBGRACustomBitmap; AOpacity: byte = 255);
|
|
procedure PutImagePart(x,y: integer; Source: TBGRACustomBitmap; SourceRect: TRect; mode: TDrawMode; AOpacity: byte = 255);
|
|
procedure PutImageAffine(Origin,HAxis,VAxis: TPointF; Source: TBGRACustomBitmap; AOpacity: Byte=255; ACorrectBlur: Boolean = false); overload;
|
|
procedure PutImageAffine(Origin,HAxis,VAxis: TPointF; Source: TBGRACustomBitmap; AResampleFilter: TResampleFilter; AOpacity: Byte=255); overload;
|
|
procedure PutImageAffine(Origin,HAxis,VAxis: TPointF; Source: TBGRACustomBitmap; AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte=255); overload;
|
|
procedure PutImageAffine(Origin,HAxis,VAxis: TPointF; Source: TBGRACustomBitmap; AOutputBounds: TRect; AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte=255); overload;
|
|
procedure PutImageAffine(Origin,HAxis,VAxis: TPointF; Source: TBGRACustomBitmap; AOutputBounds: TRect; AOpacity: Byte=255; ACorrectBlur: Boolean = false); overload;
|
|
procedure PutImageAffine(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; AOpacity: Byte=255; ACorrectBlur: Boolean = false; APixelCenteredCoords: boolean = true); overload;
|
|
procedure PutImageAffine(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; AResampleFilter: TResampleFilter; AOpacity: Byte=255; APixelCenteredCoords: boolean = true); overload;
|
|
procedure PutImageAffine(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte=255; APixelCenteredCoords: boolean = true); overload;
|
|
procedure PutImageAffine(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; AOutputBounds: TRect; AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte=255; APixelCenteredCoords: boolean = true); overload; virtual; abstract;
|
|
procedure PutImageAffine(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; AOutputBounds: TRect; AOpacity: Byte=255; ACorrectBlur: Boolean = false; APixelCenteredCoords: boolean = true); overload;
|
|
function GetImageAffineBounds(Origin,HAxis,VAxis: TPointF; Source: TBGRACustomBitmap): TRect; overload;
|
|
function GetImageAffineBounds(Origin,HAxis,VAxis: TPointF; ASourceWidth, ASourceHeight: integer; const ASourceBounds: TRect; AClipOutput: boolean = true): TRect; overload;
|
|
function GetImageAffineBounds(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; APixelCenteredCoords: boolean = true): TRect; overload;
|
|
function GetImageAffineBounds(AMatrix: TAffineMatrix; ASourceBounds: TRect; AClipOutput: boolean = true; APixelCenteredCoords: boolean = true): TRect; overload; virtual; abstract;
|
|
class function IsAffineRoughlyTranslation(AMatrix: TAffineMatrix; ASourceBounds: TRect): boolean; virtual; abstract;
|
|
procedure PutImageAngle(x,y: single; Source: TBGRACustomBitmap; angle: single; AOutputBounds: TRect; imageCenterX: single = 0; imageCenterY: single = 0; AOpacity: Byte=255; ARestoreOffsetAfterRotation: boolean = false; ACorrectBlur: Boolean = false); overload;
|
|
procedure PutImageAngle(x,y: single; Source: TBGRACustomBitmap; angle: single; imageCenterX: single = 0; imageCenterY: single = 0; AOpacity: Byte=255; ARestoreOffsetAfterRotation: boolean = false; ACorrectBlur: Boolean = false); overload;
|
|
procedure PutImageAngle(x,y: single; Source: TBGRACustomBitmap; angle: single; AOutputBounds: TRect; AResampleFilter: TResampleFilter; imageCenterX: single = 0; imageCenterY: single = 0; AOpacity: Byte=255; ARestoreOffsetAfterRotation: boolean = false); overload;
|
|
procedure PutImageAngle(x,y: single; Source: TBGRACustomBitmap; angle: single; AResampleFilter: TResampleFilter; imageCenterX: single = 0; imageCenterY: single = 0; AOpacity: Byte=255; ARestoreOffsetAfterRotation: boolean = false); overload;
|
|
procedure ComputeImageAngleAxes(x,y,w,h,angle: single; imageCenterX,imageCenterY: single; ARestoreOffsetAfterRotation: boolean;
|
|
out Origin,HAxis,VAxis: TPointF);
|
|
function GetImageAngleBounds(x,y: single; Source: TBGRACustomBitmap; angle: single; imageCenterX: single = 0; imageCenterY: single = 0; ARestoreOffsetAfterRotation: boolean = false): TRect;
|
|
procedure Blend(AColor: TBGRAPixel; AOperation: TBlendOperation; AIgnoreDestAlpha: boolean = false); virtual;
|
|
procedure BlendOver(AColor: TBGRAPixel; AOperation: TBlendOperation; AOpacity: byte = 255; ALinearBlend: boolean = false; AIgnoreDestAlpha: boolean = false); virtual;
|
|
procedure BlendRect(ADest: TRect; AColor: TBGRAPixel; AOperation: TBlendOperation; AIgnoreDestAlpha: boolean = false); overload;
|
|
procedure BlendRect(ADest: TRect; AColor: TBGRAPixel; AOperation: TBlendOperation; AExcludeChannels: TChannels); overload; virtual; abstract;
|
|
procedure BlendRectOver(ADest: TRect; AColor: TBGRAPixel; AOperation: TBlendOperation; AOpacity: byte = 255; ALinearBlend: boolean = false; AIgnoreDestAlpha: boolean = false); overload;
|
|
procedure BlendRectOver(ADest: TRect; AColor: TBGRAPixel; AOperation: TBlendOperation; AOpacity: byte; ALinearBlend: boolean; AExcludeChannels: TChannels); overload; virtual; abstract;
|
|
procedure BlendImage(x, y: integer; ASource: TBGRACustomBitmap; AOperation: TBlendOperation); overload; virtual; abstract;
|
|
procedure BlendImage(ADest: TRect; ASource: IBGRAScanner; AOffsetX, AOffsetY: integer; AOperation: TBlendOperation); overload; virtual; abstract;
|
|
procedure BlendImageOver(x, y: integer; ASource: TBGRACustomBitmap; AOperation: TBlendOperation; AOpacity: byte = 255; ALinearBlend: boolean = false); overload; virtual; abstract;
|
|
procedure BlendImageOver(ADest: TRect; ASource: IBGRAScanner; AOffsetX, AOffsetY: integer; AOperation: TBlendOperation; AOpacity: byte = 255; ALinearBlend: boolean = false); overload; virtual; abstract;
|
|
function Resample(newWidth, newHeight: integer;
|
|
mode: TResampleMode = rmFineResample; ACopyProperties: Boolean=False): TBGRACustomBitmap; virtual; abstract;
|
|
|
|
//masks
|
|
procedure FillMask(x,y: integer; AMask: TCustomUniversalBitmap; ATexture: IBGRAScanner; ADrawMode: TDrawMode); overload; override;
|
|
procedure FillMask(x,y: integer; AMask: TCustomUniversalBitmap; ATexture: IBGRAScanner; ADrawMode: TDrawMode; AOpacity: byte); overload; virtual; abstract;
|
|
procedure EraseMask(x,y: integer; AMask: TBGRACustomBitmap; alpha: byte=255); virtual; abstract;
|
|
procedure FillClearTypeMask(x,y: integer; xThird: integer; AMask: TBGRACustomBitmap; color: TBGRAPixel; ARGBOrder: boolean = true); overload; virtual; abstract;
|
|
procedure FillClearTypeMask(x,y: integer; xThird: integer; AMask: TBGRACustomBitmap; texture: IBGRAScanner; ARGBOrder: boolean = true); overload; virtual; abstract;
|
|
function GetMaskFromAlpha: TBGRACustomBitmap; virtual; abstract;
|
|
function GetImageBoundsWithin(const ARect: TRect; Channel: TChannel = cAlpha; ANothingValue: Byte = 0): TRect; overload; override;
|
|
function GetImageBoundsWithin(const ARect: TRect; Channels: TChannels; ANothingValue: Byte = 0): TRect; overload; override;
|
|
|
|
{inplace filters}
|
|
procedure Negative; virtual; abstract;
|
|
procedure NegativeRect(ABounds: TRect); virtual; abstract;
|
|
procedure LinearNegative; virtual; abstract;
|
|
procedure LinearNegativeRect(ABounds: TRect); virtual; abstract;
|
|
procedure InplaceGrayscale(AGammaCorrection: boolean = true); overload; virtual; abstract;
|
|
procedure InplaceGrayscale(ABounds: TRect; AGammaCorrection: boolean = true); overload; virtual; abstract;
|
|
procedure InplaceNormalize(AEachChannel: boolean = True); overload; virtual; abstract;
|
|
procedure InplaceNormalize(ABounds: TRect; AEachChannel: boolean = True); overload; virtual; abstract;
|
|
procedure ConvertToLinearRGB; virtual; abstract;
|
|
procedure ConvertFromLinearRGB; virtual; abstract;
|
|
procedure SwapRedBlue; overload; virtual; abstract;
|
|
procedure SwapRedBlue(ARect: TRect); overload; virtual; abstract;
|
|
procedure GrayscaleToAlpha; virtual; abstract;
|
|
procedure AlphaToGrayscale; virtual; abstract;
|
|
procedure VerticalFlip(ARect: TRect); overload; override;
|
|
procedure HorizontalFlip(ARect: TRect); overload; override;
|
|
procedure RotateUDInplace(ARect: TRect); overload; override;
|
|
|
|
{Filters}
|
|
function RotateCW(ACopyProperties: Boolean=False): TBGRACustomBitmap; override;
|
|
function RotateCCW(ACopyProperties: Boolean=False): TBGRACustomBitmap; override;
|
|
function RotateUD(ACopyProperties: Boolean=False): TBGRACustomBitmap; override;
|
|
{$IFNDEF BGRABITMAP_CORE}
|
|
function FilterSmartZoom3(Option: TMedianOption; ACopyProperties: Boolean=False): TBGRACustomBitmap; virtual; abstract;
|
|
function FilterMedian(Option: TMedianOption; ACopyProperties: Boolean=False): TBGRACustomBitmap; virtual; abstract;
|
|
function FilterSmooth(ACopyProperties: Boolean=False): TBGRACustomBitmap; virtual; abstract;
|
|
function FilterSharpen(Amount: single = 1; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; virtual; abstract;
|
|
function FilterSharpen(ABounds: TRect; Amount: single = 1; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; virtual; abstract;
|
|
function FilterContour(AGammaCorrection: boolean = false; ACopyProperties: Boolean=False): TBGRACustomBitmap; virtual; abstract;
|
|
function FilterPixelate(pixelSize: integer; useResample: boolean; filter: TResampleFilter = rfLinear; ACopyProperties: Boolean=False): TBGRACustomBitmap; virtual; abstract;
|
|
function FilterBlurRadial(radius: single; blurType: TRadialBlurType; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; override;
|
|
function FilterBlurRadial(const ABounds: TRect; radius: single; blurType: TRadialBlurType; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; override;
|
|
function FilterBlurRadial(radiusX, radiusY: single; blurType: TRadialBlurType; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; override;
|
|
function FilterBlurRadial(const ABounds: TRect; radiusX, radiusY: single; blurType: TRadialBlurType; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; override;
|
|
function FilterBlurMotion(distance: single; angle: single; oriented: boolean; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; override;
|
|
function FilterBlurMotion(const ABounds: TRect; distance: single; angle: single; oriented: boolean; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; override;
|
|
function FilterCustomBlur(mask: TCustomUniversalBitmap; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; override;
|
|
function FilterCustomBlur(const ABounds: TRect; mask: TCustomUniversalBitmap; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; override;
|
|
function FilterEmboss(angle: single; AStrength: integer= 64; AOptions: TEmbossOptions = []; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; virtual; abstract;
|
|
function FilterEmboss(angle: single; ABounds: TRect; AStrength: integer= 64; AOptions: TEmbossOptions = []; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; virtual; abstract;
|
|
function FilterEmbossHighlight(FillSelection: boolean; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; virtual; abstract;
|
|
function FilterEmbossHighlight(FillSelection: boolean; BorderColor: TBGRAPixel; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; virtual; abstract;
|
|
function FilterEmbossHighlight(FillSelection: boolean; BorderColor: TBGRAPixel; var Offset: TPoint; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; virtual; abstract;
|
|
function FilterGrayscale(ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; virtual; abstract;
|
|
function FilterGrayscale(ABounds: TRect; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; virtual; abstract;
|
|
function FilterNormalize(eachChannel: boolean = True; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; virtual; abstract;
|
|
function FilterNormalize(ABounds: TRect; eachChannel: boolean = True; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; virtual; abstract;
|
|
function FilterRotate(origin: TPointF; angle: single; correctBlur: boolean = false; ACopyProperties: Boolean=False): TBGRACustomBitmap; virtual; abstract;
|
|
function FilterAffine(AMatrix: TAffineMatrix; correctBlur: boolean = false; ACopyProperties: Boolean=False): TBGRACustomBitmap; virtual; abstract;
|
|
function FilterSphere(ACopyProperties: Boolean=False): TBGRACustomBitmap; virtual; abstract;
|
|
function FilterTwirl(ACenter: TPoint; ARadius: Single; ATurn: Single=1; AExponent: Single=3; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; virtual; abstract;
|
|
function FilterTwirl(ABounds: TRect; ACenter: TPoint; ARadius: Single; ATurn: Single=1; AExponent: Single=3; ACopyProperties: Boolean=False): TBGRACustomBitmap; overload; virtual; abstract;
|
|
function FilterCylinder(ACopyProperties: Boolean=False): TBGRACustomBitmap; virtual; abstract;
|
|
function FilterPlane(ACopyProperties: Boolean=False): TBGRACustomBitmap; virtual; abstract;
|
|
{$ENDIF}
|
|
|
|
//IBGRAScanner
|
|
function ScanAtIntegerExpanded(X,Y: integer): TExpandedPixel; override;
|
|
function ScanNextExpandedPixel: TExpandedPixel; override;
|
|
function ScanAtExpanded(X,Y: Single): TExpandedPixel; override;
|
|
function ProvidesScanline(ARect: TRect): boolean; override;
|
|
function GetScanlineAt(X, Y: integer): PBGRAPixel; override;
|
|
procedure ScanNextMaskChunk(var ACount: integer; out AMask: PByteMask; out AStride: integer); override;
|
|
function ScanAtIntegerMask(X,Y: integer): TByteMask; override;
|
|
function ScanAtMask(X,Y: Single): TByteMask; override;
|
|
end;
|
|
|
|
type
|
|
TBGRABitmapAny = class of TBGRACustomBitmap; //used to create instances of the same type (see NewBitmap)
|
|
|
|
var
|
|
BGRABitmapFactory : TBGRABitmapAny;
|
|
{$ENDIF}
|
|
|
|
{$IFDEF INCLUDE_IMPLEMENTATION}
|
|
{$UNDEF INCLUDE_IMPLEMENTATION}
|
|
function InternalGetImageBoundsWithin(ASourceBitmap: TBGRACustomBitmap; ASourceTexture: IBGRAScanner;
|
|
const ARect: TRect; Channels: TChannels; ANothingValue: Byte): TRect;
|
|
var
|
|
minx, miny, maxx, maxy: integer;
|
|
xb, xb2, yb: integer;
|
|
p: PLongWord;
|
|
colorMask, colorZeros: LongWord;
|
|
actualRect: TRect;
|
|
pixelBuffer: TBGRAPixelBuffer;
|
|
begin
|
|
pixelBuffer := nil;
|
|
if ASourceBitmap <> nil then
|
|
begin
|
|
actualRect := TRect.Intersect(ARect, rect(0,0,ASourceBitmap.Width,ASourceBitmap.Height));
|
|
end
|
|
else if ASourceTexture <> nil then
|
|
begin
|
|
actualRect := ARect;
|
|
AllocateBGRAPixelBuffer(pixelBuffer, ARect.Right-ARect.Left)
|
|
end
|
|
else
|
|
begin
|
|
result := EmptyRect;
|
|
exit;
|
|
end;
|
|
maxx := actualRect.Left-1;
|
|
maxy := actualRect.Top-1;
|
|
minx := actualRect.Right;
|
|
miny := actualRect.Bottom;
|
|
colorMask := 0;
|
|
colorZeros := 0;
|
|
if cBlue in Channels then
|
|
begin
|
|
colorMask := colorMask or LongWord(BGRA(0,0,255,0));
|
|
colorZeros:= colorZeros or LongWord(BGRA(0,0,ANothingValue,0));
|
|
end;
|
|
if cGreen in Channels then
|
|
begin
|
|
colorMask := colorMask or LongWord(BGRA(0,255,0,0));
|
|
colorZeros:= colorZeros or LongWord(BGRA(0,ANothingValue,0,0));
|
|
end;
|
|
if cRed in Channels then
|
|
begin
|
|
colorMask := colorMask or LongWord(BGRA(255,0,0,0));
|
|
colorZeros:= colorZeros or LongWord(BGRA(ANothingValue,0,0,0));
|
|
end;
|
|
if cAlpha in Channels then
|
|
begin
|
|
colorMask := colorMask or LongWord(BGRA(0,0,0,255));
|
|
colorZeros:= colorZeros or LongWord(BGRA(0,0,0,ANothingValue));
|
|
end;
|
|
colorMask := NtoLE(colorMask);
|
|
colorZeros := NtoLE(colorZeros);
|
|
for yb := actualRect.Top to actualRect.Bottom-1 do
|
|
begin
|
|
if ASourceBitmap <> nil then
|
|
p := PLongWord(ASourceBitmap.ScanLine[yb])+actualRect.Left
|
|
else
|
|
begin
|
|
p := @pixelBuffer[0];
|
|
ASourceTexture.ScanMoveTo(actualRect.Left,actualRect.Top);
|
|
ASourceTexture.ScanPutPixels(PBGRAPixel(p),ARect.Right-ARect.Left, dmSet);
|
|
end;
|
|
for xb := actualRect.Left to actualRect.Right - 1 do
|
|
begin
|
|
if (p^ and colorMask) <> colorZeros then
|
|
begin
|
|
if xb < minx then
|
|
minx := xb;
|
|
if yb < miny then
|
|
miny := yb;
|
|
if xb > maxx then
|
|
maxx := xb;
|
|
if yb > maxy then
|
|
maxy := yb;
|
|
|
|
inc(p, actualRect.Right-1-xb);
|
|
for xb2 := actualRect.Right-1 downto xb+1 do
|
|
begin
|
|
if (p^ and colorMask) <> colorZeros then
|
|
begin
|
|
if xb2 > maxx then
|
|
maxx := xb2;
|
|
break;
|
|
end;
|
|
dec(p);
|
|
end;
|
|
break;
|
|
end;
|
|
Inc(p);
|
|
end;
|
|
end;
|
|
if minx > maxx then
|
|
begin
|
|
Result.left := 0;
|
|
Result.top := 0;
|
|
Result.right := 0;
|
|
Result.bottom := 0;
|
|
end
|
|
else
|
|
begin
|
|
Result.left := minx;
|
|
Result.top := miny;
|
|
Result.right := maxx + 1;
|
|
Result.bottom := maxy + 1;
|
|
end;
|
|
end;
|
|
|
|
{ TBGRACustomBitmap }
|
|
|
|
function TBGRACustomBitmap.GetFontAntialias: Boolean;
|
|
begin
|
|
result := FontQuality <> fqSystem;
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.SetFontAntialias(const AValue: Boolean);
|
|
begin
|
|
if AValue and not FontAntialias then
|
|
FontQuality := fqFineAntialiasing
|
|
else if not AValue and (FontQuality <> fqSystem) then
|
|
FontQuality := fqSystem;
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.SetXorMask(AValue: TBGRACustomBitmap);
|
|
begin
|
|
if FXorMask=AValue then Exit;
|
|
if (AValue.Width <> Width) or (AValue.Height <> Height) then
|
|
raise exception.Create('Dimension mismatch');
|
|
DiscardXorMask;
|
|
FXorMask:=AValue;
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.Init;
|
|
begin
|
|
inherited Init;
|
|
ScanMaskChannel:= cGreen;
|
|
end;
|
|
|
|
function TBGRACustomBitmap.GetFontRightToLeftFor(AText: string): boolean;
|
|
begin
|
|
case FontBidiMode of
|
|
fbmAuto: result := IsRightToLeftUTF8(AText);
|
|
fbmRightToLeft: result := true;
|
|
else
|
|
{fbmLeftToRight}
|
|
result := false;
|
|
end;
|
|
end;
|
|
|
|
function TBGRACustomBitmap.NewBitmap: TBGRACustomBitmap;
|
|
begin
|
|
Result:=inherited NewBitmap as TBGRACustomBitmap;
|
|
end;
|
|
|
|
function TBGRACustomBitmap.NewBitmap(AWidth, AHeight: integer): TBGRACustomBitmap;
|
|
begin
|
|
Result:=inherited NewBitmap(AWidth, AHeight) as TBGRACustomBitmap;
|
|
end;
|
|
|
|
function TBGRACustomBitmap.NewBitmap(AWidth, AHeight: integer;
|
|
const Color: TBGRAPixel): TBGRACustomBitmap;
|
|
begin
|
|
Result:=inherited NewBitmap(AWidth, AHeight, Color) as TBGRACustomBitmap;
|
|
end;
|
|
|
|
function TBGRACustomBitmap.NewBitmap(AWidth, AHeight: integer; AColor: Pointer
|
|
): TBGRACustomBitmap;
|
|
begin
|
|
Result:=inherited NewBitmap(AWidth, AHeight, AColor) as TBGRACustomBitmap;
|
|
end;
|
|
|
|
function TBGRACustomBitmap.InternalNew: TBGRACustomBitmap;
|
|
begin
|
|
Result:= BGRABitmapFactory.Create;
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.DiscardXorMask;
|
|
begin
|
|
if Assigned(FXorMask) then
|
|
begin
|
|
if FXorMask is TBGRACustomBitmap then
|
|
begin
|
|
TBGRACustomBitmap(FXorMask).FreeReference;
|
|
FXorMask := nil;
|
|
end else
|
|
FreeAndNil(FXorMask);
|
|
end;
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.NeedXorMask;
|
|
begin
|
|
if FXorMask = nil then
|
|
FXorMask := BGRABitmapFactory.Create(Width,Height);
|
|
end;
|
|
|
|
function TBGRACustomBitmap.NewReference: TBGRACustomBitmap;
|
|
begin
|
|
result := TBGRACustomBitmap(inherited NewReference);
|
|
end;
|
|
|
|
function TBGRACustomBitmap.GetUnique: TBGRACustomBitmap;
|
|
begin
|
|
result := TBGRACustomBitmap(inherited GetUnique);
|
|
end;
|
|
|
|
function TBGRACustomBitmap.Duplicate(DuplicateProperties: Boolean): TBGRACustomBitmap;
|
|
begin
|
|
result := TBGRACustomBitmap(inherited Duplicate(DuplicateProperties));
|
|
end;
|
|
|
|
function TBGRACustomBitmap.Duplicate(DuplicateProperties,
|
|
DuplicateXorMask: Boolean): TBGRACustomBitmap;
|
|
begin
|
|
result := Duplicate(DuplicateProperties);
|
|
if DuplicateXorMask and Assigned(XorMask) then
|
|
result.XorMask := FXorMask.Duplicate(True);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.CopyPropertiesTo(ABitmap: TCustomUniversalBitmap);
|
|
var
|
|
other: TBGRACustomBitmap;
|
|
begin
|
|
inherited CopyPropertiesTo(ABitmap);
|
|
if ABitmap is TBGRACustomBitmap then
|
|
begin
|
|
other := TBGRACustomBitmap(ABitmap);
|
|
other.CanvasOpacity := CanvasOpacity;
|
|
other.CanvasDrawModeFP := CanvasDrawModeFP;
|
|
other.PenStyle := PenStyle;
|
|
other.CustomPenStyle := CustomPenStyle;
|
|
other.FontName := FontName;
|
|
other.FontHeight := FontHeight;
|
|
other.FontStyle := FontStyle;
|
|
other.FontQuality := FontQuality;
|
|
other.FontOrientation := FontOrientation;
|
|
other.FontVerticalAnchor:= FontVerticalAnchor;
|
|
other.FontBidiMode:= FontBidiMode;
|
|
other.LineCap := LineCap;
|
|
other.JoinStyle := JoinStyle;
|
|
other.ResampleFilter := ResampleFilter;
|
|
other.ScanInterpolationFilter:= ScanInterpolationFilter;
|
|
other.HotSpot := HotSpot;
|
|
end;
|
|
end;
|
|
|
|
function TBGRACustomBitmap.GetPart(const ARect: TRect; ACopyProperties: Boolean=False): TBGRACustomBitmap;
|
|
begin
|
|
result := TBGRACustomBitmap(inherited GetPart(ARect, ACopyProperties));
|
|
end;
|
|
|
|
function TBGRACustomBitmap.CreateBrushTexture(ABrushStyle: TBrushStyle;
|
|
APatternColor, ABackgroundColor: TBGRAPixel; AWidth: integer;
|
|
AHeight: integer; APenWidth: single): TBGRACustomBitmap;
|
|
begin
|
|
result := TBGRACustomBitmap(inherited CreateBrushTexture(ABrushStyle, APatternColor, ABackgroundColor, AWidth,AHeight,APenWidth));
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.SetSize(AWidth, AHeight: integer);
|
|
begin
|
|
if (AWidth <> Width) or (AHeight <> Height) then
|
|
begin
|
|
inherited SetSize(AWidth, AHeight);
|
|
DiscardXorMask;
|
|
end;
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.InternalArc(cx, cy, rx, ry: single;
|
|
const StartPoint, EndPoint: TPointF; ABorderColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel; AOptions: TArcOptions;
|
|
ADrawChord: boolean; ATexture: IBGRAScanner);
|
|
var angle1,angle2: single;
|
|
begin
|
|
if (rx = 0) or (ry = 0) then exit;
|
|
angle1 := arctan2(-(StartPoint.y-cy)/ry,(StartPoint.x-cx)/rx);
|
|
angle2 := arctan2(-(EndPoint.y-cy)/ry,(EndPoint.x-cx)/rx);
|
|
if angle1 = angle2 then angle2 := angle1+2*Pi;
|
|
InternalArc(cx,cy,rx,ry, angle1,angle2,
|
|
ABorderColor,w,AFillColor, AOptions, ADrawChord, ATexture);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.InternalArcInRect(r: TRect; StartAngleRad,
|
|
EndAngleRad: Single; ABorderColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel; AOptions: TArcOptions;
|
|
ADrawChord: boolean; ATexture: IBGRAScanner);
|
|
var
|
|
temp: LongInt;
|
|
begin
|
|
if r.right = r.left then exit;
|
|
if r.bottom = r.top then exit;
|
|
if r.right < r.left then
|
|
begin
|
|
temp := r.left;
|
|
r.left := r.right;
|
|
r.right := temp;
|
|
end;
|
|
if r.Bottom < r.Top then
|
|
begin
|
|
temp := r.Top;
|
|
r.Top := r.Bottom;
|
|
r.Bottom := temp;
|
|
end;
|
|
InternalArc((r.left+r.right-1)/2,(r.top+r.bottom-1)/2,
|
|
(r.right-r.left-1)/2,(r.bottom-r.top-1)/2,
|
|
StartAngleRad,EndAngleRad,
|
|
ABorderColor,w,AFillColor,
|
|
AOptions, ADrawChord, ATexture);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.InternalFillArcInRect(r: TRect; StartAngleRad,
|
|
EndAngleRad: Single; AFillColor: TBGRAPixel; AOptions: TArcOptions;
|
|
ATexture: IBGRAScanner);
|
|
var
|
|
temp: LongInt;
|
|
begin
|
|
if r.right = r.left then exit;
|
|
if r.bottom = r.top then exit;
|
|
if r.right < r.left then
|
|
begin
|
|
temp := r.left;
|
|
r.left := r.right;
|
|
r.right := temp;
|
|
end;
|
|
if r.Bottom < r.Top then
|
|
begin
|
|
temp := r.Top;
|
|
r.Top := r.Bottom;
|
|
r.Bottom := temp;
|
|
end;
|
|
InternalArc((r.left+r.right-1)/2,(r.top+r.bottom-1)/2,
|
|
(r.right-r.left)/2,(r.bottom-r.top)/2,
|
|
StartAngleRad,EndAngleRad,
|
|
BGRAPixelTransparent,0,AFillColor,
|
|
AOptions, False, ATexture);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.DrawPixel(x, y: int32or64; const c: TBGRAPixel;
|
|
ADrawMode: TDrawMode);
|
|
begin
|
|
case ADrawMode of
|
|
dmSet: SetPixel(x,y,c);
|
|
dmSetExceptTransparent: if c.alpha = 255 then SetPixel(x,y,c);
|
|
dmLinearBlend: FastBlendPixel(x,y,c);
|
|
dmDrawWithTransparency: DrawPixel(x,y,c);
|
|
dmXor: XorPixel(x,y,c);
|
|
end;
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.LoadFromStream(AStream: TStream;
|
|
AHandler: TFPCustomImageReader; AOptions: TBGRALoadingOptions);
|
|
var
|
|
OldDrawMode: TDrawMode;
|
|
begin
|
|
{ LoadFromStream uses TFPCustomImage routine, which uses
|
|
Colors property to access pixels. That's why the
|
|
FP drawing mode is temporarily changed to load
|
|
bitmaps properly }
|
|
OldDrawMode := CanvasDrawModeFP;
|
|
CanvasDrawModeFP := dmSet;
|
|
DiscardXorMask;
|
|
try
|
|
inherited LoadFromStream(AStream, AHandler, AOptions);
|
|
finally
|
|
CanvasDrawModeFP := OldDrawMode;
|
|
end;
|
|
end;
|
|
|
|
{ Look for a pixel considering the bitmap is repeated in both directions }
|
|
procedure TBGRACustomBitmap.DrawHorizLine(x, y, x2: int32or64;
|
|
texture: IBGRAScanner);
|
|
begin
|
|
HorizLine(x,y,x2,texture,dmDrawWithTransparency);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.Arc(cx, cy, rx, ry: single; const StartPoint,
|
|
EndPoint: TPointF; AColor: TBGRAPixel; w: single; ADrawChord: boolean;
|
|
AFillColor: TBGRAPixel);
|
|
begin
|
|
InternalArc(cx,cy,rx,ry,StartPoint,EndPoint,AColor,w,AFillColor,[aoFillPath],ADrawChord);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.Arc(cx, cy, rx, ry: single; StartAngleRad,
|
|
EndAngleRad: Single; AColor: TBGRAPixel; w: single; ADrawChord: boolean;
|
|
AFillColor: TBGRAPixel);
|
|
begin
|
|
InternalArc(cx,cy,rx,ry,StartAngleRad,EndAngleRad,AColor,w,AFillColor,[aoFillPath],ADrawChord);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.FillChord(cx, cy, rx, ry: single; const StartPoint,
|
|
EndPoint: TPointF; AFillColor: TBGRAPixel);
|
|
begin
|
|
InternalArc(cx,cy,rx,ry,StartPoint,EndPoint,BGRAPixelTransparent,0,AFillColor,[aoFillPath]);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.FillChord(cx, cy, rx, ry: single; StartAngleRad,
|
|
EndAngleRad: Single; AFillColor: TBGRAPixel);
|
|
begin
|
|
InternalArc(cx,cy,rx,ry,StartAngleRad,EndAngleRad,BGRAPixelTransparent,0,AFillColor,[aoFillPath]);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.FillChord(cx, cy, rx, ry: single; const StartPoint,
|
|
EndPoint: TPointF; texture: IBGRAScanner);
|
|
begin
|
|
InternalArc(cx,cy,rx,ry,StartPoint,EndPoint,BGRAPixelTransparent,0,BGRAWhite,[aoFillPath],False,texture);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.FillChord(cx, cy, rx, ry: single; StartAngleRad,
|
|
EndAngleRad: Single; texture: IBGRAScanner);
|
|
begin
|
|
InternalArc(cx,cy,rx,ry,StartAngleRad,EndAngleRad,BGRAPixelTransparent,0,BGRAWhite,[aoFillPath],False,texture);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.FillChordInRect(const ARect: TRect; StartAngleRad,
|
|
EndAngleRad: Single; AFillColor: TBGRAPixel);
|
|
begin
|
|
InternalFillArcInRect(ARect,StartAngleRad,EndAngleRad,AFillColor,[aoFillPath]);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.FillChordInRect(const ARect: TRect; StartAngleRad,
|
|
EndAngleRad: Single; texture: IBGRAScanner);
|
|
begin
|
|
InternalFillArcInRect(ARect,StartAngleRad,EndAngleRad,BGRAWhite,[aoFillPath],texture);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.Pie(cx, cy, rx, ry: single; const StartPoint,
|
|
EndPoint: TPointF; AColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel);
|
|
begin
|
|
InternalArc(cx,cy,rx,ry,StartPoint,EndPoint,AColor,w,AFillColor,[aoFillPath,aoPie]);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.Pie(cx, cy, rx, ry: single; StartAngleRad,
|
|
EndAngleRad: Single; AColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel);
|
|
begin
|
|
InternalArc(cx,cy,rx,ry,StartAngleRad,EndAngleRad,AColor,w,AFillColor,[aoFillPath,aoPie]);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.FillPie(cx, cy, rx, ry: single; const StartPoint,
|
|
EndPoint: TPointF; AFillColor: TBGRAPixel);
|
|
begin
|
|
InternalArc(cx,cy,rx,ry,StartPoint,EndPoint,BGRAPixelTransparent,0,AFillColor,[aoFillPath,aoPie]);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.FillPie(cx, cy, rx, ry: single; StartAngleRad,
|
|
EndAngleRad: Single; AFillColor: TBGRAPixel);
|
|
begin
|
|
InternalArc(cx,cy,rx,ry,StartAngleRad,EndAngleRad,BGRAPixelTransparent,0,AFillColor,[aoFillPath,aoPie]);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.FillPie(cx, cy, rx, ry: single; const StartPoint,
|
|
EndPoint: TPointF; texture: IBGRAScanner);
|
|
begin
|
|
InternalArc(cx,cy,rx,ry,StartPoint,EndPoint,BGRAPixelTransparent,0,BGRAWhite,[aoFillPath,aoPie],False,texture);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.FillPie(cx, cy, rx, ry: single; StartAngleRad,
|
|
EndAngleRad: Single; texture: IBGRAScanner);
|
|
begin
|
|
InternalArc(cx,cy,rx,ry,StartAngleRad,EndAngleRad,BGRAPixelTransparent,0,BGRAWhite,[aoFillPath,aoPie],False,texture);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.FillPieInRect(const ARect: TRect; StartAngleRad,
|
|
EndAngleRad: Single; AFillColor: TBGRAPixel);
|
|
begin
|
|
InternalFillArcInRect(ARect,StartAngleRad,EndAngleRad,AFillColor,[aoFillPath,aoPie]);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.FillPieInRect(const ARect: TRect; StartAngleRad,
|
|
EndAngleRad: Single; texture: IBGRAScanner);
|
|
begin
|
|
InternalFillArcInRect(ARect,StartAngleRad,EndAngleRad,BGRAWhite,[aoFillPath,aoPie],texture);
|
|
end;
|
|
|
|
{ Following functions are defined for convenience }
|
|
procedure TBGRACustomBitmap.RectangleWithin(x1, y1, x2, y2: single;
|
|
ABorderColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel;
|
|
APixelCenteredCoordinates: boolean);
|
|
begin
|
|
if not APixelCenteredCoordinates then
|
|
begin
|
|
DecF(x1, 0.5);
|
|
DecF(y1, 0.5);
|
|
DecF(x2, 0.5);
|
|
DecF(y2, 0.5);
|
|
end;
|
|
RectangleAntialias(x1+w*0.5,y1+w*0.5,x2-w*0.5,y2-w*0.5, ABorderColor, w, AFillColor);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.RectangleWithin(r: TRect; ABorderColor: TBGRAPixel;
|
|
w: single; AFillColor: TBGRAPixel);
|
|
begin
|
|
RectangleWithin(r.left,r.top,r.right,r.bottom,ABorderColor,w,AFillColor,false);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.FillRect(r: TRect; texture: IBGRAScanner;
|
|
mode: TDrawMode; ditheringAlgorithm: TDitheringAlgorithm);
|
|
begin
|
|
FillRect(r.Left,r.Top,r.Right,r.Bottom, texture, mode, ditheringAlgorithm);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.FillRect(r: TRect; texture: IBGRAScanner;
|
|
mode: TDrawMode; AScanOffset: TPoint; ditheringAlgorithm: TDitheringAlgorithm);
|
|
begin
|
|
FillRect(r.Left,r.Top,r.Right,r.Bottom, texture, mode, AScanOffset, ditheringAlgorithm);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.FillRect(x, y, x2, y2: integer;
|
|
texture: IBGRAScanner; mode: TDrawMode;
|
|
ditheringAlgorithm: TDitheringAlgorithm);
|
|
begin
|
|
FillRect(x,y,x2,y2,texture,mode,Point(0,0),ditheringAlgorithm);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.TextOutCurved(APath: IBGRAPath; const sUTF8: string;
|
|
AColor: TBGRAPixel; AAlign: TAlignment; ALetterSpacing: single);
|
|
var cursor: TBGRACustomPathCursor;
|
|
begin
|
|
cursor := APath.getCursor;
|
|
if cursor = nil then exit;
|
|
case AAlign of
|
|
taCenter: cursor.Position := cursor.PathLength*0.5;
|
|
taRightJustify: cursor.Position:= cursor.PathLength;
|
|
end;
|
|
TextOutCurved(cursor, sUTF8, AColor, AAlign, ALetterSpacing);
|
|
cursor.free;
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.TextOutCurved(APath: IBGRAPath; const sUTF8: string;
|
|
ATexture: IBGRAScanner; AAlign: TAlignment; ALetterSpacing: single);
|
|
var cursor: TBGRACustomPathCursor;
|
|
begin
|
|
cursor := APath.getCursor;
|
|
if cursor = nil then exit;
|
|
case AAlign of
|
|
taCenter: cursor.Position := cursor.PathLength*0.5;
|
|
taRightJustify: cursor.Position:= cursor.PathLength;
|
|
end;
|
|
TextOutCurved(cursor, sUTF8, ATexture, AAlign, ALetterSpacing);
|
|
cursor.free;
|
|
end;
|
|
|
|
{$IFNDEF BGRABITMAP_CORE}procedure TBGRACustomBitmap.TextMultiline(x, y: single; const sUTF8: string;
|
|
c: TBGRAPixel; AAlign: TBidiTextAlignment; AVertAlign: TTextLayout; AParagraphSpacing: single);
|
|
begin
|
|
TextMultiline(x, y, EmptySingle, sUTF8, c, AAlign, AVertAlign, AParagraphSpacing);
|
|
end;{$ENDIF}
|
|
|
|
{$IFNDEF BGRABITMAP_CORE}procedure TBGRACustomBitmap.TextMultiline(x, y: single; const sUTF8: string;
|
|
ATexture: IBGRAScanner; AAlign: TBidiTextAlignment; AVertAlign: TTextLayout; AParagraphSpacing: single);
|
|
begin
|
|
TextMultiline(x, y, EmptySingle, sUTF8, ATexture, AAlign, AVertAlign, AParagraphSpacing);
|
|
end;{$ENDIF}
|
|
|
|
procedure TBGRACustomBitmap.TextOut(x, y: single; const sUTF8: string; c: TBGRAPixel;
|
|
align: TAlignment);
|
|
begin
|
|
TextOut(x,y,sUTF8,c,align, GetFontRightToLeftFor(sUTF8));
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.TextOut(x, y: single; const sUTF8: string;
|
|
texture: IBGRAScanner; align: TAlignment);
|
|
begin
|
|
TextOut(x,y,sUTF8,texture,align, GetFontRightToLeftFor(sUTF8));
|
|
end;
|
|
|
|
{ Draw the UTF8 encoded string, (x,y) being the top-left corner. The color c is used to fill the text.
|
|
The value of FontOrientation is taken into account, so that the text may be rotated. }
|
|
procedure TBGRACustomBitmap.TextOut(x, y: single; const sUTF8: string; c: TBGRAPixel);
|
|
begin
|
|
TextOut(x, y, sUTF8, c, taLeftJustify);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.TextOut(x, y: single; const sUTF8: string; c: TBGRAPixel;
|
|
ARightToLeft: boolean);
|
|
begin
|
|
TextOut(x, y, sUTF8, c, taLeftJustify, ARightToLeft);
|
|
end;
|
|
|
|
{ Draw the UTF8 encoded string, (x,y) being the top-left corner. The color c is used to fill the text.
|
|
The value of FontOrientation is taken into account, so that the text may be rotated. }
|
|
procedure TBGRACustomBitmap.TextOut(x, y: single; const sUTF8: string; c: TColor);
|
|
begin
|
|
TextOut(x, y, sUTF8, ColorToBGRA(c));
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.TextOut(x, y: single; const sUTF8: string; c: TColor;
|
|
ARightToLeft: boolean);
|
|
begin
|
|
TextOut(x, y, sUTF8, ColorToBGRA(c), ARightToLeft);
|
|
end;
|
|
|
|
{ Draw the UTF8 encoded string, (x,y) being the top-left corner. The texture is used to fill the text.
|
|
The value of FontOrientation is taken into account, so that the text may be rotated. }
|
|
procedure TBGRACustomBitmap.TextOut(x, y: single; const sUTF8: string;
|
|
texture: IBGRAScanner);
|
|
begin
|
|
TextOut(x, y, sUTF8, texture, taLeftJustify);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.TextOut(x, y: single; const sUTF8: string;
|
|
texture: IBGRAScanner; ARightToLeft: boolean);
|
|
begin
|
|
TextOut(x, y, sUTF8, texture, taLeftJustify, ARightToLeft);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.TextOutAngle(x, y: single;
|
|
orientationTenthDegCCW: integer; const sUTF8: string; c: TBGRAPixel);
|
|
begin
|
|
TextOutAngle(x,y, orientationTenthDegCCW, sUTF8,c,taLeftJustify);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.TextOutAngle(x, y: single;
|
|
orientationTenthDegCCW: integer; const sUTF8: string; c: TBGRAPixel;
|
|
align: TAlignment);
|
|
begin
|
|
TextOutAngle(x,y, orientationTenthDegCCW, sUTF8,c,align, GetFontRightToLeftFor(sUTF8));
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.TextOutAngle(x, y: single;
|
|
orientationTenthDegCCW: integer; const sUTF8: string; texture: IBGRAScanner);
|
|
begin
|
|
TextOutAngle(x,y, orientationTenthDegCCW, sUTF8,texture,taLeftJustify);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.TextOutAngle(x, y: single;
|
|
orientationTenthDegCCW: integer; const sUTF8: string; texture: IBGRAScanner;
|
|
align: TAlignment);
|
|
begin
|
|
TextOutAngle(x,y, orientationTenthDegCCW, sUTF8,texture,align, GetFontRightToLeftFor(sUTF8));
|
|
end;
|
|
|
|
{ Draw the UTF8 encoded string in the rectangle ARect. Text is wrapped if necessary.
|
|
The position depends on the specified horizontal alignment halign and vertical alignement valign.
|
|
The color c is used to fill the text. No rotation is applied. }
|
|
procedure TBGRACustomBitmap.TextRect(ARect: TRect; const sUTF8: string;
|
|
halign: TAlignment; valign: TTextLayout; c: TBGRAPixel);
|
|
var
|
|
style: TTextStyle;
|
|
sUTF8bidi: String;
|
|
begin
|
|
{$hints off}
|
|
FillChar(style,sizeof(style),0);
|
|
{$hints on}
|
|
style.Alignment := halign;
|
|
style.Layout := valign;
|
|
style.Wordbreak := true;
|
|
style.ShowPrefix := false;
|
|
style.Clipping := false;
|
|
style.RightToLeft := GetFontRightToLeftFor(sUTF8);
|
|
if FontBidiMode = fbmAuto then
|
|
sUTF8bidi := AddParagraphBidiUTF8(sUTF8, style.RightToLeft)
|
|
else sUTF8bidi := sUTF8;
|
|
TextRect(ARect, ARect.Left, ARect.Top, sUTF8bidi, style, c);
|
|
end;
|
|
|
|
{ Draw the UTF8 encoded string in the rectangle ARect. Text is wrapped if necessary.
|
|
The position depends on the specified horizontal alignment halign and vertical alignement valign.
|
|
The texture is used to fill the text. No rotation is applied. }
|
|
procedure TBGRACustomBitmap.TextRect(ARect: TRect; const sUTF8: string;
|
|
halign: TAlignment; valign: TTextLayout; texture: IBGRAScanner);
|
|
var
|
|
style: TTextStyle;
|
|
sUTF8bidi: String;
|
|
begin
|
|
{$hints off}
|
|
FillChar(style,sizeof(style),0);
|
|
{$hints on}
|
|
style.Alignment := halign;
|
|
style.Layout := valign;
|
|
style.Wordbreak := true;
|
|
style.ShowPrefix := false;
|
|
style.Clipping := false;
|
|
style.RightToLeft := GetFontRightToLeftFor(sUTF8);
|
|
if FontBidiMode = fbmAuto then
|
|
sUTF8bidi := AddParagraphBidiUTF8(sUTF8, style.RightToLeft)
|
|
else sUTF8bidi := sUTF8;
|
|
TextRect(ARect,ARect.Left,ARect.Top,sUTF8bidi,style,texture);
|
|
end;
|
|
|
|
function TBGRACustomBitmap.ComputeEllipse(x, y, rx, ry: single): ArrayOfTPointF;
|
|
begin
|
|
result := ComputeEllipseContour(x,y,rx,ry);
|
|
end;
|
|
|
|
function TBGRACustomBitmap.ComputeEllipse(x, y, rx, ry, w: single
|
|
): ArrayOfTPointF;
|
|
begin
|
|
result := ComputeEllipseBorder(x,y,rx,ry,w);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.Fill(texture: IBGRAScanner);
|
|
begin
|
|
FillRect(ClipRect, texture, dmSet);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.Fill(texture: IBGRAScanner; mode: TDrawMode);
|
|
begin
|
|
FillRect(ClipRect, texture, mode);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.FloodFill(X, Y: integer; Color: TBGRAPixel;
|
|
mode: TFloodfillMode; Tolerance: byte);
|
|
begin
|
|
ParallelFloodFill(X,Y, Self, Color, mode, Tolerance);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.FloodFill(X, Y: integer;
|
|
const Brush: TUniversalBrush; Progressive: boolean; ToleranceW: Word);
|
|
begin
|
|
ParallelFloodFill(X,Y, Self, Brush, Progressive, ToleranceW);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.DrawPart(ARect: TRect; ACanvas: TCanvas; x,
|
|
y: integer; Opaque: boolean);
|
|
var
|
|
partial: TBGRACustomBitmap;
|
|
begin
|
|
if (ARect.Left = 0) and (ARect.Top = 0) and (ARect.Right = Width) and (ARect.Bottom = Height) then
|
|
Draw(ACanvas, x,y, Opaque)
|
|
else
|
|
begin
|
|
partial := GetPart(ARect);
|
|
if partial <> nil then
|
|
begin
|
|
partial.Draw(ACanvas, x, y, Opaque);
|
|
partial.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.DrawPart(ARect: TRect; ACanvas: TCanvas;
|
|
ATargetRect: TRect; Opaque: boolean);
|
|
var
|
|
partial: TBGRACustomBitmap;
|
|
begin
|
|
if (ARect.Left = 0) and (ARect.Top = 0) and (ARect.Right = Width) and (ARect.Bottom = Height) then
|
|
Draw(ACanvas, ATargetRect, Opaque)
|
|
else
|
|
begin
|
|
partial := GetPart(ARect);
|
|
if partial <> nil then
|
|
begin
|
|
partial.Draw(ACanvas, ATargetRect, Opaque);
|
|
partial.Free;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.PutImage(x, y: integer; Source: TBitmap;
|
|
mode: TDrawMode; AOpacity: byte);
|
|
var bgra: TBGRACustomBitmap;
|
|
begin
|
|
bgra := BGRABitmapFactory.create(Source);
|
|
PutImage(x,y, bgra, mode, AOpacity);
|
|
bgra.free;
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.StretchPutImage(ARect: TRect; Source: TBitmap;
|
|
mode: TDrawMode; AOpacity: byte);
|
|
var bgra: TBGRACustomBitmap;
|
|
begin
|
|
bgra := BGRABitmapFactory.create(Source);
|
|
StretchPutImage(ARect, bgra, mode, AOpacity);
|
|
bgra.free;
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.StretchPutImageProportionally(ARect: TRect;
|
|
AHorizAlign: TAlignment; AVertAlign: TTextLayout; Source: TBGRACustomBitmap;
|
|
mode: TDrawMode; AOpacity: byte; ACover: boolean);
|
|
var
|
|
ratio: single;
|
|
imgRect: TRect;
|
|
begin
|
|
if (Source.Width = 0) or (Source.Height = 0) then exit;
|
|
if (ARect.Width <= 0) or (ARect.Height <= 0) then exit;
|
|
|
|
if ACover then
|
|
ratio := max(ARect.Width/Source.Width, ARect.Height/Source.Height)
|
|
else
|
|
ratio := min(ARect.Width/Source.Width, ARect.Height/Source.Height);
|
|
imgRect := RectWithSize(ARect.Left,ARect.Top, round(Source.Width*ratio), round(Source.Height*ratio));
|
|
case AHorizAlign of
|
|
taCenter: imgRect.Offset((ARect.Width-imgRect.Width) div 2, 0);
|
|
taRightJustify: imgRect.Offset(ARect.Width-imgRect.Width, 0);
|
|
end;
|
|
case AVertAlign of
|
|
tlCenter: imgRect.Offset(0,(ARect.Height-imgRect.Height) div 2);
|
|
tlBottom: imgRect.Offset(0,ARect.Height-imgRect.Height);
|
|
end;
|
|
StretchPutImage(imgRect, Source, mode, AOpacity);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.PutImageSubpixel(x, y: single; Source: TBGRACustomBitmap; AOpacity: byte);
|
|
begin
|
|
PutImageAngle(x,y,source,0,0,0,AOpacity);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.PutImagePart(x, y: integer;
|
|
Source: TBGRACustomBitmap; SourceRect: TRect; mode: TDrawMode; AOpacity: byte);
|
|
var w,h,sourcex,sourcey,nx,ny,xb,yb,destx,desty: integer;
|
|
oldClip,newClip: TRect;
|
|
begin
|
|
if (Source = nil) or (AOpacity = 0) then exit;
|
|
w := SourceRect.Right-SourceRect.Left;
|
|
h := SourceRect.Bottom-SourceRect.Top;
|
|
if (w <= 0) or (h <= 0) or (Source.Width = 0) or (Source.Height = 0) then exit;
|
|
sourcex := PositiveMod(SourceRect.Left, Source.Width);
|
|
sourcey := PositiveMod(SourceRect.Top, Source.Height);
|
|
nx := (sourceX+w + Source.Width-1) div Source.Width;
|
|
ny := (sourceY+h + Source.Height-1) div Source.Height;
|
|
|
|
oldClip := ClipRect;
|
|
newClip := rect(x,y,x+w,y+h);
|
|
newClip.Intersect(oldClip);
|
|
if newClip.IsEmpty then exit;
|
|
|
|
ClipRect := newClip;
|
|
|
|
desty := y-sourcey;
|
|
for yb := 0 to ny-1 do
|
|
begin
|
|
destx := x-sourcex;
|
|
for xb := 0 to nx-1 do
|
|
begin
|
|
self.PutImage(destx,desty,Source,mode,AOpacity);
|
|
inc(destx,Source.Width);
|
|
end;
|
|
inc(desty,Source.Height);
|
|
end;
|
|
|
|
ClipRect := oldClip;
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.PutImageAffine(Origin, HAxis, VAxis: TPointF;
|
|
Source: TBGRACustomBitmap; AOpacity: Byte; ACorrectBlur: Boolean);
|
|
begin
|
|
if ACorrectBlur then
|
|
PutImageAffine(Origin,HAxis,VAxis,Source,rfCosine,AOpacity)
|
|
else
|
|
PutImageAffine(Origin,HAxis,VAxis,Source,rfLinear,AOpacity);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.PutImageAffine(Origin, HAxis, VAxis: TPointF;
|
|
Source: TBGRACustomBitmap; AResampleFilter: TResampleFilter; AOpacity: Byte);
|
|
begin
|
|
if (Source = nil) or (Source.Width = 0) or (Source.Height = 0) or (AOpacity = 0) then exit;
|
|
PutImageAffine(Origin,HAxis,VAxis,Source,GetImageAffineBounds(Origin,HAxis,VAxis,Source),AResampleFilter,dmDrawWithTransparency,AOpacity);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.PutImageAffine(Origin, HAxis, VAxis: TPointF;
|
|
Source: TBGRACustomBitmap; AResampleFilter: TResampleFilter;
|
|
AMode: TDrawMode; AOpacity: Byte);
|
|
begin
|
|
if (Source = nil) or (Source.Width = 0) or (Source.Height = 0) or (AOpacity = 0) then exit;
|
|
PutImageAffine(Origin,HAxis,VAxis,Source,GetImageAffineBounds(Origin,HAxis,VAxis,Source),AResampleFilter,AMode,AOpacity);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.PutImageAffine(Origin, HAxis, VAxis: TPointF;
|
|
Source: TBGRACustomBitmap; AOutputBounds: TRect;
|
|
AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte);
|
|
var m: TAffineMatrix; w,h: integer;
|
|
begin
|
|
if (Source = nil) or (Source.Width = 0) or (Source.Height = 0) or (AOpacity = 0) then exit;
|
|
if Source.Width < 2 then w := 2 else w := Source.Width; //avoid actual size of zero
|
|
if Source.Height < 2 then h := 2 else h := Source.Height;
|
|
m[1,1] := (HAxis.x-Origin.x)/(w-1); m[1,2] := (VAxis.x-Origin.x)/(h-1); m[1,3] := Origin.x;
|
|
m[2,1] := (HAxis.y-Origin.y)/(w-1); m[2,2] := (VAxis.y-Origin.y)/(h-1); m[2,3] := Origin.y;
|
|
PutImageAffine(m,Source,AOutputBounds,AResampleFilter,AMode,AOpacity);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.PutImageAffine(Origin, HAxis, VAxis: TPointF;
|
|
Source: TBGRACustomBitmap; AOutputBounds: TRect; AOpacity: Byte;
|
|
ACorrectBlur: Boolean);
|
|
begin
|
|
if ACorrectBlur then
|
|
PutImageAffine(Origin,HAxis,VAxis,Source,AOutputBounds,rfCosine,dmDrawWithTransparency,AOpacity)
|
|
else
|
|
PutImageAffine(Origin,HAxis,VAxis,Source,AOutputBounds,rfLinear,dmDrawWithTransparency,AOpacity);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.PutImageAffine(AMatrix: TAffineMatrix;
|
|
Source: TBGRACustomBitmap; AOpacity: Byte; ACorrectBlur: Boolean; APixelCenteredCoords: boolean);
|
|
begin
|
|
if ACorrectBlur then
|
|
PutImageAffine(AMatrix,Source,rfCosine,AOpacity,APixelCenteredCoords)
|
|
else
|
|
PutImageAffine(AMatrix,Source,rfLinear,AOpacity,APixelCenteredCoords);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.PutImageAffine(AMatrix: TAffineMatrix;
|
|
Source: TBGRACustomBitmap; AResampleFilter: TResampleFilter; AOpacity: Byte; APixelCenteredCoords: boolean);
|
|
begin
|
|
PutImageAffine(AMatrix, Source, AResampleFilter, dmDrawWithTransparency, AOpacity, APixelCenteredCoords);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.PutImageAffine(AMatrix: TAffineMatrix;
|
|
Source: TBGRACustomBitmap; AResampleFilter: TResampleFilter;
|
|
AMode: TDrawMode; AOpacity: Byte; APixelCenteredCoords: boolean);
|
|
begin
|
|
if (Source = nil) or (Source.Width = 0) or (Source.Height = 0) or (AOpacity = 0) then exit;
|
|
PutImageAffine(AMatrix, Source, GetImageAffineBounds(AMatrix,Source),
|
|
AResampleFilter,AMode,AOpacity,APixelCenteredCoords);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.PutImageAffine(AMatrix: TAffineMatrix;
|
|
Source: TBGRACustomBitmap; AOutputBounds: TRect; AOpacity: Byte;
|
|
ACorrectBlur: Boolean; APixelCenteredCoords: boolean);
|
|
begin
|
|
if ACorrectBlur then
|
|
PutImageAffine(AMatrix,Source,AOutputBounds,rfCosine,dmDrawWithTransparency,AOpacity,APixelCenteredCoords)
|
|
else
|
|
PutImageAffine(AMatrix,Source,AOutputBounds,rfLinear,dmDrawWithTransparency,AOpacity,APixelCenteredCoords);
|
|
end;
|
|
|
|
{ Returns the area that contains the affine transformed image }
|
|
function TBGRACustomBitmap.GetImageAffineBounds(Origin, HAxis, VAxis: TPointF;
|
|
Source: TBGRACustomBitmap): TRect;
|
|
begin
|
|
if Source = nil then
|
|
result := EmptyRect
|
|
else
|
|
result := GetImageAffineBounds(Origin,HAxis,VAxis,Source.Width,Source.Height,Source.GetImageBounds);
|
|
end;
|
|
|
|
function TBGRACustomBitmap.GetImageAffineBounds(Origin, HAxis, VAxis: TPointF;
|
|
ASourceWidth, ASourceHeight: integer; const ASourceBounds: TRect; AClipOutput: boolean): TRect;
|
|
var m: TAffineMatrix;
|
|
begin
|
|
if (ASourceWidth = 0) or (ASourceHeight = 0) then
|
|
result := EmptyRect
|
|
else
|
|
begin
|
|
if ASourceWidth < 2 then ASourceWidth := 2; //avoid division by zero by supposing a pixel size of 2
|
|
if ASourceHeight < 2 then ASourceHeight := 2; //i.e. an actual size of 1 (cf pixel centered coordinates)
|
|
m[1,1] := (HAxis.x-Origin.x)/(ASourceWidth-1); m[1,2] := (VAxis.x-Origin.x)/(ASourceHeight-1); m[1,3] := Origin.x;
|
|
m[2,1] := (HAxis.y-Origin.y)/(ASourceWidth-1); m[2,2] := (VAxis.y-Origin.y)/(ASourceHeight-1); m[2,3] := Origin.y;
|
|
result := GetImageAffineBounds(m, ASourceBounds, AClipOutput);
|
|
end;
|
|
end;
|
|
|
|
function TBGRACustomBitmap.GetImageAffineBounds(AMatrix: TAffineMatrix;
|
|
Source: TBGRACustomBitmap; APixelCenteredCoords: boolean): TRect;
|
|
begin
|
|
result := GetImageAffineBounds(AMatrix, Source.GetImageBounds, true, APixelCenteredCoords);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.PutImageAngle(x, y: single;
|
|
Source: TBGRACustomBitmap; angle: single; AOutputBounds: TRect;
|
|
imageCenterX: single; imageCenterY: single; AOpacity: Byte;
|
|
ARestoreOffsetAfterRotation: boolean; ACorrectBlur: Boolean);
|
|
begin
|
|
if ACorrectBlur then
|
|
PutImageAngle(x,y,Source,angle,AOutputBounds,rfCosine,imageCenterX,imageCenterY,AOpacity,ARestoreOffsetAfterRotation)
|
|
else
|
|
PutImageAngle(x,y,Source,angle,AOutputBounds,rfLinear,imageCenterX,imageCenterY,AOpacity,ARestoreOffsetAfterRotation);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.PutImageAngle(x, y: single;
|
|
Source: TBGRACustomBitmap; angle: single; imageCenterX: single;
|
|
imageCenterY: single; AOpacity: Byte; ARestoreOffsetAfterRotation: boolean; ACorrectBlur: Boolean);
|
|
begin
|
|
if ACorrectBlur then
|
|
PutImageAngle(x,y,Source,angle,rfCosine,imageCenterX,imageCenterY,AOpacity,ARestoreOffsetAfterRotation)
|
|
else
|
|
PutImageAngle(x,y,Source,angle,rfLinear,imageCenterX,imageCenterY,AOpacity,ARestoreOffsetAfterRotation);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.PutImageAngle(x, y: single;
|
|
Source: TBGRACustomBitmap; angle: single; AOutputBounds: TRect;
|
|
AResampleFilter: TResampleFilter; imageCenterX: single; imageCenterY: single; AOpacity: Byte;
|
|
ARestoreOffsetAfterRotation: boolean);
|
|
var
|
|
Origin,HAxis,VAxis: TPointF;
|
|
begin
|
|
if (source = nil) or (AOpacity=0) then exit;
|
|
ComputeImageAngleAxes(x,y,source.Width,source.Height,angle,imageCenterX,imageCenterY,ARestoreOffsetAfterRotation,
|
|
Origin,HAxis,VAxis);
|
|
PutImageAffine(Origin,HAxis,VAxis,source,AOutputBounds,AResampleFilter,dmDrawWithTransparency,AOpacity);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.PutImageAngle(x, y: single;
|
|
Source: TBGRACustomBitmap; angle: single; AResampleFilter: TResampleFilter;
|
|
imageCenterX: single; imageCenterY: single; AOpacity: Byte;
|
|
ARestoreOffsetAfterRotation: boolean);
|
|
var
|
|
Origin,HAxis,VAxis: TPointF;
|
|
begin
|
|
if (source = nil) or (AOpacity=0) then exit;
|
|
ComputeImageAngleAxes(x,y,source.Width,source.Height,angle,imageCenterX,imageCenterY,ARestoreOffsetAfterRotation,
|
|
Origin,HAxis,VAxis);
|
|
PutImageAffine(Origin,HAxis,VAxis,source,AResampleFilter,AOpacity);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.ComputeImageAngleAxes(x, y, w, h,
|
|
angle: single; imageCenterX, imageCenterY: single;
|
|
ARestoreOffsetAfterRotation: boolean; out Origin, HAxis, VAxis: TPointF);
|
|
var
|
|
cosa,sina: single;
|
|
|
|
{ Compute rotated coordinates }
|
|
function Coord(relX,relY: single): TPointF;
|
|
begin
|
|
DecF(relX, imageCenterX);
|
|
DecF(relY, imageCenterY);
|
|
result.x := relX*cosa - relY*sina+ x;
|
|
result.y := relY*cosa + relX*sina+ y;
|
|
if ARestoreOffsetAfterRotation then
|
|
result.Offset(imageCenterX,imageCenterY);
|
|
end;
|
|
|
|
begin
|
|
cosa := cos(-angle*Pi/180);
|
|
sina := -sin(-angle*Pi/180);
|
|
Origin := Coord(0,0);
|
|
if w < 2 then w := 2; //when pixel size is 1, actual size is zero, so avoid that
|
|
if h < 2 then h := 2;
|
|
HAxis := Coord(w-1,0);
|
|
VAxis := Coord(0,h-1);
|
|
end;
|
|
|
|
function TBGRACustomBitmap.GetImageAngleBounds(x, y: single;
|
|
Source: TBGRACustomBitmap; angle: single; imageCenterX: single;
|
|
imageCenterY: single; ARestoreOffsetAfterRotation: boolean): TRect;
|
|
var
|
|
cosa,sina: single;
|
|
|
|
{ Compute rotated coordinates }
|
|
function Coord(relX,relY: single): TPointF;
|
|
begin
|
|
DecF(relX, imageCenterX);
|
|
DecF(relY, imageCenterY);
|
|
result.x := relX*cosa - relY*sina + x;
|
|
result.y := relY*cosa + relX*sina + y;
|
|
if ARestoreOffsetAfterRotation then
|
|
result.Offset(imageCenterX,imageCenterY);
|
|
end;
|
|
|
|
begin
|
|
if (source = nil) then
|
|
begin
|
|
result := EmptyRect;
|
|
exit;
|
|
end;
|
|
cosa := cos(-angle*Pi/180);
|
|
sina := -sin(-angle*Pi/180);
|
|
result := GetImageAffineBounds(Coord(0,0),Coord(source.Width,0),Coord(0,source.Height),source);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.Blend(AColor: TBGRAPixel;
|
|
AOperation: TBlendOperation; AIgnoreDestAlpha: boolean);
|
|
begin
|
|
BlendRect(ClipRect, AColor, AOperation, AIgnoreDestAlpha);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.BlendOver(AColor: TBGRAPixel;
|
|
AOperation: TBlendOperation; AOpacity: byte; ALinearBlend: boolean; AIgnoreDestAlpha: boolean);
|
|
begin
|
|
BlendRectOver(ClipRect, AColor, AOperation, AOpacity, ALinearBlend, AIgnoreDestAlpha);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.BlendRect(ADest: TRect; AColor: TBGRAPixel;
|
|
AOperation: TBlendOperation; AIgnoreDestAlpha: boolean);
|
|
begin
|
|
if AIgnoreDestAlpha then
|
|
BlendRect(ADest, AColor, AOperation, [cAlpha])
|
|
else BlendRect(ADest, AColor, AOperation, []);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.BlendRectOver(ADest: TRect; AColor: TBGRAPixel;
|
|
AOperation: TBlendOperation; AOpacity: byte; ALinearBlend: boolean;
|
|
AIgnoreDestAlpha: boolean);
|
|
begin
|
|
if AIgnoreDestAlpha then
|
|
BlendRectOver(ADest, AColor, AOperation, AOpacity, ALinearBlend,[cAlpha])
|
|
else BlendRectOver(ADest, AColor, AOperation, AOpacity, ALinearBlend, []);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.FillMask(x, y: integer;
|
|
AMask: TCustomUniversalBitmap; ATexture: IBGRAScanner; ADrawMode: TDrawMode);
|
|
begin
|
|
FillMask(x, y, AMask, ATexture, ADrawMode, 255);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.VerticalFlip(ARect: TRect);
|
|
begin
|
|
inherited VerticalFlip(ARect);
|
|
if Assigned(XorMask) then XorMask.VerticalFlip(ARect);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.HorizontalFlip(ARect: TRect);
|
|
begin
|
|
inherited HorizontalFlip(ARect);
|
|
if Assigned(XorMask) then XorMask.HorizontalFlip(ARect);
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.RotateUDInplace(ARect: TRect);
|
|
begin
|
|
inherited RotateUDInplace(ARect);
|
|
if Assigned(XorMask) then XorMask.RotateUDInplace(ARect);
|
|
end;
|
|
|
|
function TBGRACustomBitmap.RotateCW(ACopyProperties: Boolean=False): TBGRACustomBitmap;
|
|
begin
|
|
result := TBGRACustomBitmap(Inherited RotateCW(ACopyProperties));
|
|
if Assigned(XorMask) then result.FXorMask := self.XorMask.RotateCW(ACopyProperties);
|
|
end;
|
|
|
|
function TBGRACustomBitmap.RotateCCW(ACopyProperties: Boolean=False): TBGRACustomBitmap;
|
|
begin
|
|
result := TBGRACustomBitmap(Inherited RotateCCW(ACopyProperties));
|
|
if Assigned(XorMask) then result.FXorMask := self.XorMask.RotateCCW(ACopyProperties);
|
|
end;
|
|
|
|
function TBGRACustomBitmap.RotateUD(ACopyProperties: Boolean=False): TBGRACustomBitmap;
|
|
begin
|
|
result := TBGRACustomBitmap(Inherited RotateUD(ACopyProperties));
|
|
if Assigned(XorMask) then result.FXorMask := self.XorMask.RotateUD(ACopyProperties);
|
|
end;
|
|
|
|
{$IFNDEF BGRABITMAP_CORE}function TBGRACustomBitmap.FilterBlurRadial(radius: single;
|
|
blurType: TRadialBlurType; ACopyProperties: Boolean=False): TBGRACustomBitmap;
|
|
begin
|
|
result := TBGRACustomBitmap(inherited FilterBlurRadial(radius, blurType, ACopyProperties));
|
|
end;{$ENDIF}
|
|
|
|
{$IFNDEF BGRABITMAP_CORE}function TBGRACustomBitmap.FilterBlurRadial(const ABounds: TRect; radius: single;
|
|
blurType: TRadialBlurType; ACopyProperties: Boolean=False): TBGRACustomBitmap;
|
|
begin
|
|
result := TBGRACustomBitmap(inherited FilterBlurRadial(ABounds, radius, blurType, ACopyProperties));
|
|
end;{$ENDIF}
|
|
|
|
{$IFNDEF BGRABITMAP_CORE}function TBGRACustomBitmap.FilterBlurRadial(radiusX, radiusY: single;
|
|
blurType: TRadialBlurType; ACopyProperties: Boolean=False): TBGRACustomBitmap;
|
|
begin
|
|
result := TBGRACustomBitmap(inherited FilterBlurRadial(radiusX,radiusY, blurType, ACopyProperties));
|
|
end;{$ENDIF}
|
|
|
|
{$IFNDEF BGRABITMAP_CORE}function TBGRACustomBitmap.FilterBlurRadial(const ABounds: TRect; radiusX,
|
|
radiusY: single; blurType: TRadialBlurType; ACopyProperties: Boolean=False): TBGRACustomBitmap;
|
|
begin
|
|
result := TBGRACustomBitmap(inherited FilterBlurRadial(ABounds, radiusX,radiusY, blurType, ACopyProperties));
|
|
end;{$ENDIF}
|
|
|
|
{$IFNDEF BGRABITMAP_CORE}function TBGRACustomBitmap.FilterBlurMotion(distance: single; angle: single;
|
|
oriented: boolean; ACopyProperties: Boolean=False): TBGRACustomBitmap;
|
|
begin
|
|
result := TBGRACustomBitmap(inherited FilterBlurMotion(distance, angle, oriented, ACopyProperties));
|
|
end;{$ENDIF}
|
|
|
|
{$IFNDEF BGRABITMAP_CORE}function TBGRACustomBitmap.FilterBlurMotion(const ABounds: TRect; distance: single;
|
|
angle: single; oriented: boolean; ACopyProperties: Boolean=False): TBGRACustomBitmap;
|
|
begin
|
|
result := TBGRACustomBitmap(inherited FilterBlurMotion(ABounds, distance, angle, oriented, ACopyProperties));
|
|
end;{$ENDIF}
|
|
|
|
{$IFNDEF BGRABITMAP_CORE}function TBGRACustomBitmap.FilterCustomBlur(mask: TCustomUniversalBitmap; ACopyProperties: Boolean=False): TBGRACustomBitmap;
|
|
begin
|
|
result := TBGRACustomBitmap(inherited FilterCustomBlur(mask, ACopyProperties));
|
|
end;{$ENDIF}
|
|
|
|
{$IFNDEF BGRABITMAP_CORE}function TBGRACustomBitmap.FilterCustomBlur(const ABounds: TRect;
|
|
mask: TCustomUniversalBitmap; ACopyProperties: Boolean=False): TBGRACustomBitmap;
|
|
begin
|
|
result := TBGRACustomBitmap(inherited FilterCustomBlur(ABounds,mask, ACopyProperties));
|
|
end;{$ENDIF}
|
|
|
|
function TBGRACustomBitmap.GetImageBoundsWithin(const ARect: TRect;
|
|
Channel: TChannel; ANothingValue: Byte): TRect;
|
|
begin
|
|
result := InternalGetImageBoundsWithin(self,nil,ARect,[Channel],ANothingValue);
|
|
end;
|
|
|
|
function TBGRACustomBitmap.GetImageBoundsWithin(const ARect: TRect;
|
|
Channels: TChannels; ANothingValue: Byte): TRect;
|
|
begin
|
|
result := InternalGetImageBoundsWithin(self,nil,ARect,Channels,ANothingValue);
|
|
end;
|
|
|
|
function TBGRACustomBitmap.ScanAtIntegerExpanded(X, Y: integer): TExpandedPixel;
|
|
begin
|
|
result := GammaExpansion(ScanAtInteger(X,Y));
|
|
end;
|
|
|
|
function TBGRACustomBitmap.ScanNextExpandedPixel: TExpandedPixel;
|
|
begin
|
|
result := GammaExpansion(ScanNextPixel);
|
|
end;
|
|
|
|
function TBGRACustomBitmap.ScanAtExpanded(X, Y: Single): TExpandedPixel;
|
|
begin
|
|
result := GammaExpansion(ScanAt(X,Y));
|
|
end;
|
|
|
|
function TBGRACustomBitmap.ProvidesScanline(ARect: TRect): boolean;
|
|
begin
|
|
result := (ARect.Left+ScanOffset.x >= 0) and (ARect.Top+ScanOffset.y >= 0) and
|
|
(ARect.Right+ScanOffset.x <= Width) and (ARect.Bottom+ScanOffset.y <= Height);
|
|
end;
|
|
|
|
function TBGRACustomBitmap.GetScanlineAt(X, Y: integer): PBGRAPixel;
|
|
begin
|
|
result := ScanLine[y+ScanOffset.y]+x+ScanOffset.x;
|
|
end;
|
|
|
|
procedure TBGRACustomBitmap.ScanNextMaskChunk(var ACount: integer; out AMask: PByteMask; out AStride: integer);
|
|
var
|
|
PPixels: Pointer;
|
|
begin
|
|
ScanNextCustomChunk(ACount, PPixels);
|
|
AMask := (PByteMask(PPixels)+TBGRAPixel_ChannelByteOffset[ScanMaskChannel]);
|
|
AStride := sizeof(TBGRAPixel);
|
|
end;
|
|
|
|
function TBGRACustomBitmap.ScanAtIntegerMask(X,Y: integer): TByteMask;
|
|
var
|
|
c: TBGRAPixel;
|
|
begin
|
|
c := ScanAtInteger(X,Y);
|
|
Byte(result) := (PByte(@c)+TBGRAPixel_ChannelByteOffset[ScanMaskChannel])^;
|
|
end;
|
|
|
|
function TBGRACustomBitmap.ScanAtMask(X,Y: Single): TByteMask;
|
|
var
|
|
c: TBGRAPixel;
|
|
begin
|
|
c := ScanAt(X,Y);
|
|
Byte(result) := (PByte(@c)+TBGRAPixel_ChannelByteOffset[ScanMaskChannel])^;
|
|
end;
|
|
|
|
{$ENDIF}
|