1 | {
|
---|
2 | /**************************************************************************\
|
---|
3 | bgradefaultbitmap.pas
|
---|
4 | ---------------------
|
---|
5 | This unit defines basic operations on bitmaps.
|
---|
6 | It should NOT be added to the 'uses' clause.
|
---|
7 | Some operations may be slow, so there are
|
---|
8 | accelerated versions for some routines.
|
---|
9 |
|
---|
10 | ****************************************************************************
|
---|
11 | * *
|
---|
12 | * This file is part of BGRABitmap library which is distributed under the *
|
---|
13 | * modified LGPL. *
|
---|
14 | * *
|
---|
15 | * See the file COPYING.modifiedLGPL.txt, included in this distribution, *
|
---|
16 | * for details about the copyright. *
|
---|
17 | * *
|
---|
18 | * This program is distributed in the hope that it will be useful, *
|
---|
19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
---|
20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
|
---|
21 | * *
|
---|
22 | ****************************************************************************
|
---|
23 | }
|
---|
24 |
|
---|
25 | unit BGRADefaultBitmap;
|
---|
26 |
|
---|
27 | {$mode objfpc}{$H+}
|
---|
28 |
|
---|
29 | interface
|
---|
30 |
|
---|
31 | { This unit contains TBGRADefaultBitmap class. This class contains basic drawing routines,
|
---|
32 | and call functions from other units to perform advanced drawing functions. }
|
---|
33 |
|
---|
34 | uses
|
---|
35 | SysUtils, Classes, Types, FPImage, BGRAGraphics, BGRABitmapTypes, FPImgCanv,
|
---|
36 | BGRACanvas, BGRACanvas2D, BGRAArrow, BGRAPen, BGRATransform, BGRATextBidi;
|
---|
37 |
|
---|
38 | type
|
---|
39 | TBGRAPtrBitmap = class;
|
---|
40 | {=== TBGRABitmap reference ===}
|
---|
41 | { TBGRADefaultBitmap }
|
---|
42 | {* This class is the base for all ''TBGRABitmap'' classes. It implements most
|
---|
43 | function to the exception from implementations specific to the
|
---|
44 | widgetset }{ in the doc, it is presented as
|
---|
45 | TBGRABitmap = class(TBGRACustomBitmap)
|
---|
46 | }
|
---|
47 | TBGRADefaultBitmap = class(TBGRACustomBitmap)
|
---|
48 | private
|
---|
49 | { Bounds checking which are shared by drawing functions. These functions check
|
---|
50 | if the coordinates are visible and return true if it is the case, swap
|
---|
51 | coordinates if necessary and make them fit into the clipping rectangle }
|
---|
52 | function CheckHorizLineBounds(var x, y, x2: int32or64): boolean; inline;
|
---|
53 | function CheckVertLineBounds(var x, y, y2: int32or64; out delta: int32or64): boolean; inline;
|
---|
54 | function CheckRectBounds(var x,y,x2,y2: integer; minsize: integer): boolean; inline;
|
---|
55 | function CheckAntialiasRectBounds(var x,y,x2,y2: single; w: single): boolean;
|
---|
56 | function GetCanvasBGRA: TBGRACanvas;
|
---|
57 | function GetCanvas2D: TBGRACanvas2D;
|
---|
58 | procedure GradientFillDithered(x, y, x2, y2: integer; c1, c2: TBGRAPixel;
|
---|
59 | gtype: TGradientType; o1, o2: TPointF; mode: TDrawMode;
|
---|
60 | gammaColorCorrection: boolean = True; Sinus: Boolean=False;
|
---|
61 | ditherAlgo: TDitheringAlgorithm = daFloydSteinberg); overload;
|
---|
62 | procedure GradientFillDithered(x, y, x2, y2: integer; gradient: TBGRACustomGradient;
|
---|
63 | gtype: TGradientType; o1, o2: TPointF; mode: TDrawMode;
|
---|
64 | Sinus: Boolean=False;
|
---|
65 | ditherAlgo: TDitheringAlgorithm = daFloydSteinberg); overload;
|
---|
66 | protected
|
---|
67 | FRefCount: integer; //reference counter (not related to interface reference counter)
|
---|
68 |
|
---|
69 | //Pixel data
|
---|
70 | FData: PBGRAPixel; //pointer to pixels
|
---|
71 | FWidth, FHeight, FNbPixels: integer; //dimensions
|
---|
72 | FScanWidth, FScanHeight: integer; //possibility to reduce the zone being scanned
|
---|
73 | FDataModified: boolean; //if data image has changed so TBitmap should be updated
|
---|
74 | FLineOrder: TRawImageLineOrder;
|
---|
75 | FClipRect: TRect; //clipping (can be the whole image if there is no clipping)
|
---|
76 |
|
---|
77 | //Scan
|
---|
78 | FScanPtr : PBGRAPixel; //current scan address
|
---|
79 | FScanCurX,FScanCurY: integer; //current scan coordinates
|
---|
80 |
|
---|
81 | //GUI bitmap object
|
---|
82 | FBitmap: TBitmap;
|
---|
83 | FBitmapModified: boolean; //if TBitmap has changed so pixel data should be updated
|
---|
84 | FCanvasOpacity: byte; //opacity used with standard canvas functions
|
---|
85 | FAlphaCorrectionNeeded: boolean; //the alpha channel is not correct because standard functions do not
|
---|
86 | //take it into account
|
---|
87 |
|
---|
88 | //FreePascal drawing routines
|
---|
89 | FCanvasFP: TFPImageCanvas;
|
---|
90 | FCanvasDrawModeFP: TDrawMode;
|
---|
91 | FCanvasPixelProcFP: procedure(x, y: int32or64; col: TBGRAPixel) of object;
|
---|
92 |
|
---|
93 | //canvas-like with antialiasing and texturing
|
---|
94 | FCanvasBGRA: TBGRACanvas;
|
---|
95 | FCanvas2D: TBGRACanvas2D;
|
---|
96 |
|
---|
97 | //drawing options
|
---|
98 | FEraseMode: boolean; //when polygons are erased instead of drawn
|
---|
99 | FFontHeight: integer;
|
---|
100 | FFontRenderer: TBGRACustomFontRenderer;
|
---|
101 |
|
---|
102 | FPenStroker: TBGRAPenStroker;
|
---|
103 |
|
---|
104 | //Pixel data
|
---|
105 | function GetRefCount: integer; override;
|
---|
106 | function GetScanLine(y: integer): PBGRAPixel; override; //don't forget to call InvalidateBitmap after modifications
|
---|
107 | function LoadFromRawImage(ARawImage: TRawImage; DefaultOpacity: byte;
|
---|
108 | AlwaysReplaceAlpha: boolean = False; RaiseErrorOnInvalidPixelFormat: boolean = True): boolean; virtual; abstract;
|
---|
109 | function GetDataPtr: PBGRAPixel; override;
|
---|
110 | procedure ClearTransparentPixels; override;
|
---|
111 | function GetScanlineFast(y: integer): PBGRAPixel; inline;
|
---|
112 | function GetLineOrder: TRawImageLineOrder; override;
|
---|
113 | procedure SetLineOrder(AValue: TRawImageLineOrder); virtual;
|
---|
114 | function GetNbPixels: integer; override;
|
---|
115 | function GetWidth: integer; override;
|
---|
116 | function GetHeight: integer; override;
|
---|
117 |
|
---|
118 | //GUI bitmap object
|
---|
119 | function GetBitmap: TBitmap; override;
|
---|
120 | function GetCanvas: TCanvas; override;
|
---|
121 | procedure DiscardBitmapChange; inline;
|
---|
122 | procedure DoAlphaCorrection;
|
---|
123 | procedure SetCanvasOpacity(AValue: byte); override;
|
---|
124 | function GetCanvasOpacity: byte; override;
|
---|
125 | function GetCanvasAlphaCorrection: boolean; override;
|
---|
126 | procedure SetCanvasAlphaCorrection(const AValue: boolean); override;
|
---|
127 | procedure DoLoadFromBitmap; virtual;
|
---|
128 |
|
---|
129 | //FreePascal drawing routines
|
---|
130 | function GetCanvasFP: TFPImageCanvas; override;
|
---|
131 | procedure SetCanvasDrawModeFP(const AValue: TDrawMode); override;
|
---|
132 | function GetCanvasDrawModeFP: TDrawMode; override;
|
---|
133 |
|
---|
134 | {Allocation routines}
|
---|
135 | procedure ReallocData; virtual;
|
---|
136 | procedure FreeData; virtual;
|
---|
137 | function CreatePtrBitmap(AWidth,AHeight: integer; AData: PBGRAPixel): TBGRAPtrBitmap; virtual;
|
---|
138 |
|
---|
139 | procedure RebuildBitmap; virtual; abstract;
|
---|
140 | procedure FreeBitmap; virtual;
|
---|
141 |
|
---|
142 | procedure Init; virtual;
|
---|
143 |
|
---|
144 | {TFPCustomImage}
|
---|
145 | procedure SetInternalColor(x, y: integer; const Value: TFPColor); override;
|
---|
146 | function GetInternalColor(x, y: integer): TFPColor; override;
|
---|
147 | procedure SetInternalPixel(x, y: integer; Value: integer); override;
|
---|
148 | function GetInternalPixel(x, y: integer): integer; override;
|
---|
149 |
|
---|
150 | {Image functions}
|
---|
151 | function FineResample(NewWidth, NewHeight: integer): TBGRACustomBitmap;
|
---|
152 | function SimpleStretch(NewWidth, NewHeight: integer): TBGRACustomBitmap;
|
---|
153 | function CheckEmpty: boolean; override;
|
---|
154 | function CheckIsZero: boolean; override;
|
---|
155 | function GetHasTransparentPixels: boolean; override;
|
---|
156 | function GetHasSemiTransparentPixels: boolean; override;
|
---|
157 | function GetAverageColor: TColor; override;
|
---|
158 | function GetAveragePixel: TBGRAPixel; override;
|
---|
159 |
|
---|
160 | //drawing
|
---|
161 | function GetPenJoinStyle: TPenJoinStyle; override;
|
---|
162 | procedure SetPenJoinStyle(const AValue: TPenJoinStyle); override;
|
---|
163 | function GetPenMiterLimit: single; override;
|
---|
164 | procedure SetPenMiterLimit(const AValue: single); override;
|
---|
165 | function GetCustomPenStyle: TBGRAPenStyle; override;
|
---|
166 | procedure SetCustomPenStyle(const AValue: TBGRAPenStyle); override;
|
---|
167 | procedure SetPenStyle(const AValue: TPenStyle); override;
|
---|
168 | function GetPenStyle: TPenStyle; override;
|
---|
169 | function GetLineCap: TPenEndCap; override;
|
---|
170 | procedure SetLineCap(AValue: TPenEndCap); override;
|
---|
171 | function GetPenStroker: TBGRACustomPenStroker; override;
|
---|
172 |
|
---|
173 | function GetArrowEndSize: TPointF; override;
|
---|
174 | function GetArrowStartSize: TPointF; override;
|
---|
175 | procedure SetArrowEndSize(AValue: TPointF); override;
|
---|
176 | procedure SetArrowStartSize(AValue: TPointF); override;
|
---|
177 | function GetArrowEndOffset: single; override;
|
---|
178 | function GetArrowStartOffset: single; override;
|
---|
179 | procedure SetArrowEndOffset(AValue: single); override;
|
---|
180 | procedure SetArrowStartOffset(AValue: single); override;
|
---|
181 | function GetArrowEndRepeat: integer; override;
|
---|
182 | function GetArrowStartRepeat: integer; override;
|
---|
183 | procedure SetArrowEndRepeat(AValue: integer); override;
|
---|
184 | procedure SetArrowStartRepeat(AValue: integer); override;
|
---|
185 |
|
---|
186 | function GetFontHeight: integer; override;
|
---|
187 | procedure SetFontHeight(AHeight: integer); override;
|
---|
188 | function GetFontFullHeight: integer; override;
|
---|
189 | procedure SetFontFullHeight(AHeight: integer); override;
|
---|
190 | function GetFontPixelMetric: TFontPixelMetric; override;
|
---|
191 | function GetFontRenderer: TBGRACustomFontRenderer; override;
|
---|
192 | procedure SetFontRenderer(AValue: TBGRACustomFontRenderer); override;
|
---|
193 | function CreateDefaultFontRenderer: TBGRACustomFontRenderer; virtual; abstract;
|
---|
194 | function GetFontVerticalAnchorOffset: single; override;
|
---|
195 | function GetFontAnchorRotatedOffset: TPointF; overload;
|
---|
196 | function GetFontAnchorRotatedOffset(ACustomOrientation: integer): TPointF; overload;
|
---|
197 |
|
---|
198 | function GetClipRect: TRect; override;
|
---|
199 | procedure SetClipRect(const AValue: TRect); override;
|
---|
200 |
|
---|
201 | function InternalGetPixelCycle256(ix,iy: int32or64; iFactX,iFactY: int32or64): TBGRAPixel;
|
---|
202 | function InternalGetPixel256(ix,iy: int32or64; iFactX,iFactY: int32or64; smoothBorder: boolean): TBGRAPixel;
|
---|
203 | function GetArrow: TBGRAArrow;
|
---|
204 | procedure InternalTextOutCurved(ACursor: TBGRACustomPathCursor; sUTF8: string; AColor: TBGRAPixel; ATexture: IBGRAScanner; AAlign: TAlignment; ALetterSpacing: single);
|
---|
205 | procedure InternalCrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadePos: byte; AFadeMask: IBGRAScanner; mode: TDrawMode = dmDrawWithTransparency);
|
---|
206 |
|
---|
207 | function CheckClippedRectBounds(var x,y,x2,y2: integer): boolean;
|
---|
208 | procedure InternalArc(cx,cy,rx,ry: single; StartAngleRad,EndAngleRad: Single; ABorderColor: TBGRAPixel; w: single;
|
---|
209 | AFillColor: TBGRAPixel; AOptions: TArcOptions; ADrawChord: boolean = false; ATexture: IBGRAScanner = nil); override;
|
---|
210 |
|
---|
211 | public
|
---|
212 | {** Provides a canvas with opacity and antialiasing }
|
---|
213 | property CanvasBGRA: TBGRACanvas read GetCanvasBGRA;
|
---|
214 | {** Provides a canvas with 2d transformation and similar to HTML5. }
|
---|
215 | property Canvas2D: TBGRACanvas2D read GetCanvas2D;
|
---|
216 | {** For more properties, see parent class [[TBGRACustomBitmap and IBGRAScanner#TBGRACustomBitmap|TBGRACustomBitmap]] }
|
---|
217 |
|
---|
218 | {==== Reference counting ====}
|
---|
219 |
|
---|
220 | {** Adds a reference (this reference count is not the same as
|
---|
221 | the reference count of an interface, it changes only by
|
---|
222 | explicit calls }
|
---|
223 | function NewReference: TBGRACustomBitmap;
|
---|
224 | {** Free a reference. When the resulting reference count gets
|
---|
225 | to zero, the image is freed. The initial reference count
|
---|
226 | is equal to 1 }
|
---|
227 | procedure FreeReference;
|
---|
228 | {** Returns an object with a reference count equal to 1. Duplicate
|
---|
229 | this bitmap if necessary }
|
---|
230 | function GetUnique: TBGRACustomBitmap;
|
---|
231 |
|
---|
232 | { ** Allocate xor mask }
|
---|
233 | procedure NeedXorMask; override;
|
---|
234 |
|
---|
235 | { ** Free reference to xor mask }
|
---|
236 | procedure DiscardXorMask; override;
|
---|
237 |
|
---|
238 | {==== Constructors ====}
|
---|
239 |
|
---|
240 | {------------------------- Constructors from TFPCustomImage----------------}
|
---|
241 | {** Creates a new bitmap, initialize properties and bitmap data }
|
---|
242 | constructor Create(AWidth, AHeight: integer); overload; override;
|
---|
243 | {** Can only be called with an existing instance of ''TBGRABitmap''.
|
---|
244 | Sets the dimensions of an existing ''TBGRABitmap'' instance. }
|
---|
245 | procedure SetSize(AWidth, AHeight: integer); override;
|
---|
246 |
|
---|
247 | {------------------------- Constructors from TBGRACustomBitmap-------------}
|
---|
248 | {** Creates an image of width and height equal to zero. In this case,
|
---|
249 | ''Data'' = '''nil''' }
|
---|
250 | constructor Create; overload; override;
|
---|
251 | {** Creates an image by copying the content of a ''TFPCustomImage'' }
|
---|
252 | constructor Create(AFPImage: TFPCustomImage); overload; override;
|
---|
253 | {** Creates an image by copying the content of a ''TBitmap'' }
|
---|
254 | constructor Create(ABitmap: TBitmap; AUseTransparent: boolean = true); overload; override;
|
---|
255 | {** Creates an image of dimensions ''AWidth'' and ''AHeight'' and fills it with the opaque color ''Color'' }
|
---|
256 | constructor Create(AWidth, AHeight: integer; Color: TColor); overload; override;
|
---|
257 | {** Creates an image of dimensions ''AWidth'' and ''AHeight'' and fills it with ''Color'' }
|
---|
258 | constructor Create(AWidth, AHeight: integer; Color: TBGRAPixel); overload; override;
|
---|
259 |
|
---|
260 | {** Creates an image by loading its content from the file ''AFilename''.
|
---|
261 | The encoding of the string is the default one for the operating system.
|
---|
262 | It is recommended to use the next constructor and UTF8 encoding }
|
---|
263 | constructor Create(AFilename: string); overload; override;
|
---|
264 |
|
---|
265 | {** Creates an image by loading its content from the file ''AFilename''.
|
---|
266 | The boolean ''AIsUtf8Filename'' specifies if UTF8 encoding is assumed
|
---|
267 | for the filename }
|
---|
268 | constructor Create(AFilename: string; AIsUtf8: boolean); overload; override;
|
---|
269 | constructor Create(AFilename: string; AIsUtf8: boolean; AOptions: TBGRALoadingOptions); overload; override;
|
---|
270 |
|
---|
271 | {** Creates an image by loading its content from the stream ''AStream'' }
|
---|
272 | constructor Create(AStream: TStream); overload; override;
|
---|
273 | {** Free the object and all its resources }
|
---|
274 | destructor Destroy; override;
|
---|
275 |
|
---|
276 | {------------------------- Quasi-constructors -----------------------------}
|
---|
277 | {** Can only be called from an existing instance of ''TBGRABitmap''.
|
---|
278 | Creates a new instance with dimensions ''AWidth'' and ''AHeight'',
|
---|
279 | containing transparent pixels. }
|
---|
280 | function NewBitmap(AWidth, AHeight: integer): TBGRACustomBitmap; overload; override;
|
---|
281 |
|
---|
282 | {** Can only be called from an existing instance of ''TBGRABitmap''.
|
---|
283 | Creates a new instance with dimensions ''AWidth'' and ''AHeight'',
|
---|
284 | and fills it with Color }
|
---|
285 | function NewBitmap(AWidth, AHeight: integer; Color: TBGRAPixel): TBGRACustomBitmap; overload; override;
|
---|
286 |
|
---|
287 | {** Can only be called from an existing instance of ''TBGRABitmap''.
|
---|
288 | Creates a new instance with by loading its content
|
---|
289 | from the file ''Filename''. The encoding of the string
|
---|
290 | is the default one for the operating system }
|
---|
291 | function NewBitmap(Filename: string): TBGRACustomBitmap; overload; override;
|
---|
292 |
|
---|
293 | {** Can only be called from an existing instance of ''TBGRABitmap''.
|
---|
294 | Creates a new instance with by loading its content
|
---|
295 | from the file ''Filename'' }
|
---|
296 | function NewBitmap(Filename: string; AIsUtf8: boolean): TBGRACustomBitmap; overload; override;
|
---|
297 | function NewBitmap(Filename: string; AIsUtf8: boolean; AOptions: TBGRALoadingOptions): TBGRACustomBitmap; overload; override;
|
---|
298 |
|
---|
299 | {** Can only be called from an existing instance of ''TBGRABitmap''.
|
---|
300 | Creates an image by copying the content of a ''TFPCustomImage'' }
|
---|
301 | function NewBitmap(AFPImage: TFPCustomImage): TBGRACustomBitmap; overload; override;
|
---|
302 |
|
---|
303 | {** Load image from a stream. The specified image reader is used }
|
---|
304 | procedure LoadFromStream(Str: TStream; Handler: TFPCustomImageReader; AOptions: TBGRALoadingOptions); overload; override;
|
---|
305 |
|
---|
306 | {** Load image from an embedded Lazarus resource. Format is detected automatically }
|
---|
307 | procedure LoadFromResource(AFilename: string; AOptions: TBGRALoadingOptions); overload; override;
|
---|
308 |
|
---|
309 | {** Assign the content of the specified ''Source''. It can be a ''TBGRACustomBitmap'' or
|
---|
310 | a ''TFPCustomImage'' }
|
---|
311 | procedure Assign(Source: TPersistent); overload; override;
|
---|
312 | procedure Assign(Source: TBitmap; AUseTransparent: boolean); overload;
|
---|
313 | {** Stores the image in the stream without compression nor header }
|
---|
314 | procedure Serialize(AStream: TStream); override;
|
---|
315 | {** Reads the image in a stream that was previously serialized }
|
---|
316 | procedure Deserialize(AStream: TStream); override;
|
---|
317 | {** Stores an empty image (of size zero) }
|
---|
318 | class procedure SerializeEmpty(AStream: TStream);
|
---|
319 |
|
---|
320 | {* Example:
|
---|
321 | <syntaxhighlight>
|
---|
322 | * var bmp1, bmp2: TBGRABitmap;
|
---|
323 | * begin
|
---|
324 | * bmp1 := TBGRABitmap.Create(100,100);
|
---|
325 | * bmp2 := bmp1.NewBitmap(100,100) as TBGRABitmap;
|
---|
326 | * ...
|
---|
327 | * end;</syntaxhighlight>
|
---|
328 | See tutorial 2 on [[BGRABitmap_tutorial_2|how to load and display an image]].
|
---|
329 | * See reference on [[TBGRACustomBitmap_and_IBGRAScanner#Load_and_save_files|loading and saving files]] }
|
---|
330 |
|
---|
331 | {==== Pixel functions ====}
|
---|
332 | {** Checks if the specified point is in the clipping rectangle ''ClipRect'' }
|
---|
333 | function PtInClipRect(x, y: int32or64): boolean; inline;
|
---|
334 | {** Sets the pixel by replacing the content at (''x'',''y'') with the specified color.
|
---|
335 | Alpha value is set to 255 (opaque) }
|
---|
336 | procedure SetPixel(x, y: int32or64; c: TColor); overload; override;
|
---|
337 | {** Sets the pixel at (''x'',''y'') with the specified content }
|
---|
338 | procedure SetPixel(x, y: int32or64; c: TBGRAPixel); overload; override;
|
---|
339 | {** Applies a logical '''xor''' to the content of the pixel with the specified value.
|
---|
340 | This includes the alpha channel, so if you want to preserve the opacity, provide
|
---|
341 | a color ''c'' with alpha channel equal to zero }
|
---|
342 | procedure XorPixel(x, y: int32or64; c: TBGRAPixel); override;
|
---|
343 | {** Draws a pixel with gamma correction at (''x'',''y''). Pixel is supplied
|
---|
344 | in sRGB colorspace }
|
---|
345 | procedure DrawPixel(x, y: int32or64; c: TBGRAPixel); override;
|
---|
346 | {** Draws a pixel with the specified ''ADrawMode'' at (''x'',''y'').
|
---|
347 | Pixel is supplied in sRGB colorspace. Gamma correction may be applied
|
---|
348 | depending on the draw mode }{inherited
|
---|
349 | procedure DrawPixel(x, y: int32or64; c: TBGRAPixel; ADrawMode: TDrawMode); overload;
|
---|
350 | }{** Draws a pixel with gamma correction at (''x'',''y''). Pixel is supplied
|
---|
351 | in gamma expanded colorspace }
|
---|
352 | procedure DrawPixel(x, y: int32or64; ec: TExpandedPixel); override;
|
---|
353 | {** Draws a pixel without gamma correction at (''x'',''y''). Pixel is supplied
|
---|
354 | in sRGB colorspace }
|
---|
355 | procedure FastBlendPixel(x, y: int32or64; c: TBGRAPixel); override;
|
---|
356 | {** Erase the content of the pixel by reducing the value of the
|
---|
357 | alpha channel. ''alpha'' specifies how much to decrease.
|
---|
358 | If the resulting alpha reaches zero, the content
|
---|
359 | is replaced by ''BGRAPixelTransparent'' }
|
---|
360 | procedure ErasePixel(x, y: int32or64; alpha: byte); override;
|
---|
361 | {** Sets the alpha value at (''x'',''y''). If ''alpha'' = 0, the
|
---|
362 | pixel is replaced by ''BGRAPixelTransparent'' }
|
---|
363 | procedure AlphaPixel(x, y: int32or64; alpha: byte); override;
|
---|
364 | {** Returns the content of the specified pixel. If it is out of the
|
---|
365 | bounds of the picture, the result is ''BGRAPixelTransparent'' }
|
---|
366 | function GetPixel(x, y: int32or64): TBGRAPixel; override;
|
---|
367 | {** Computes the value of the pixel at a floating point coordiante
|
---|
368 | by interpolating the values of the pixels around it.
|
---|
369 | * There is a one pixel wide margin around the pixel where the pixels are
|
---|
370 | still considered inside. If ''smoothBorder'' is set to true, pixel fade
|
---|
371 | to transparent.
|
---|
372 | * If it is more out of the bounds, the result is ''BGRAPixelTransparent''.
|
---|
373 | * ''AResampleFilter'' specifies how pixels must be interpolated. Accepted
|
---|
374 | values are ''rfBox'', ''rfLinear'', ''rfHalfCosine'' and ''rfCosine'' }
|
---|
375 | function GetPixel(x, y: single; AResampleFilter: TResampleFilter = rfLinear; smoothBorder: boolean = true): TBGRAPixel; override;
|
---|
376 | {** Similar to previous ''GetPixel'' function, but the fractional part of
|
---|
377 | the coordinate is supplied with a number from 0 to 255. The actual
|
---|
378 | coordinate is (''x'' + ''fracX256''/256, ''y'' + ''fracY256''/256) }
|
---|
379 | function GetPixel256(x, y, fracX256,fracY256: int32or64; AResampleFilter: TResampleFilter = rfLinear; smoothBorder: boolean = true): TBGRAPixel; override;
|
---|
380 | {** Computes the value of the pixel at a floating point coordiante
|
---|
381 | by interpolating the values of the pixels around it. If the pixel
|
---|
382 | is out of bounds, the image is repeated.
|
---|
383 | * ''AResampleFilter'' specifies how pixels must be interpolated. Accepted
|
---|
384 | values are ''rfBox'', ''rfLinear'', ''rfHalfCosine'' and ''rfCosine'' }
|
---|
385 | function GetPixelCycle(x, y: single; AResampleFilter: TResampleFilter = rfLinear): TBGRAPixel; overload; override;
|
---|
386 | {** Similar to previous ''GetPixel'' function, but the fractional part of
|
---|
387 | the coordinate is supplied with a number from 0 to 255. The actual
|
---|
388 | coordinate is (''x'' + ''fracX256''/256, ''y'' + ''fracY256''/256) }
|
---|
389 | function GetPixelCycle256(x, y, fracX256,fracY256: int32or64; AResampleFilter: TResampleFilter = rfLinear): TBGRAPixel; overload; override;
|
---|
390 | {** Computes the value of the pixel at a floating point coordiante
|
---|
391 | by interpolating the values of the pixels around it. ''repeatX'' and
|
---|
392 | ''repeatY'' specifies if the image is to be repeated or not.
|
---|
393 | * ''AResampleFilter'' specifies how pixels must be interpolated. Accepted
|
---|
394 | values are ''rfBox'', ''rfLinear'', ''rfHalfCosine'' and ''rfCosine'' }
|
---|
395 | function GetPixelCycle(x, y: single; AResampleFilter: TResampleFilter; repeatX: boolean; repeatY: boolean): TBGRAPixel; overload; override;
|
---|
396 | {** Similar to previous ''GetPixel'' function, but the fractional part of
|
---|
397 | the coordinate is supplied with a number from 0 to 255. The actual
|
---|
398 | coordinate is (''x'' + ''fracX256''/256, ''y'' + ''fracY256''/256) }
|
---|
399 | function GetPixelCycle256(x, y, fracX256,fracY256: int32or64; AResampleFilter: TResampleFilter; repeatX: boolean; repeatY: boolean): TBGRAPixel; overload; override;
|
---|
400 |
|
---|
401 | {==== Drawing lines and polylines (integer coordinates) ====}
|
---|
402 | {* These functions do not take into account current pen style/cap/join.
|
---|
403 | See [[BGRABitmap tutorial 13|coordinate system]]. }
|
---|
404 |
|
---|
405 | {** Replaces the content of the pixels at line ''y'' and
|
---|
406 | at columns ''x'' to ''x2'' included, using specified color }
|
---|
407 | procedure SetHorizLine(x, y, x2: int32or64; c: TBGRAPixel); override;
|
---|
408 | {** Applies xor to the pixels at line ''y'' and
|
---|
409 | at columns ''x'' to ''x2'' included, using specified color.
|
---|
410 | This includes the alpha channel, so if you want to preserve the
|
---|
411 | opacity, provide a color ''c'' with alpha channel equal to zero }
|
---|
412 | procedure XorHorizLine(x, y, x2: int32or64; c: TBGRAPixel); override;
|
---|
413 | {** Draws an horizontal line with gamma correction at line ''y'' and
|
---|
414 | at columns ''x'' to ''x2'' included, using specified color }
|
---|
415 | procedure DrawHorizLine(x, y, x2: int32or64; c: TBGRAPixel); override;
|
---|
416 | {** Draws an horizontal line with gamma correction at line ''y'' and
|
---|
417 | at columns ''x'' to ''x2'' included, using specified color }
|
---|
418 | procedure DrawHorizLine(x, y, x2: int32or64; ec: TExpandedPixel); override;
|
---|
419 | {** Draws an horizontal line with gamma correction at line ''y'' and
|
---|
420 | at columns ''x'' to ''x2'' included, using specified scanner
|
---|
421 | to get the source colors }{inherited
|
---|
422 | procedure DrawHorizLine(x, y, x2: int32or64; texture: IBGRAScanner); overload;
|
---|
423 | }{** Draws an horizontal line without gamma correction at line ''y'' and
|
---|
424 | at columns ''x'' to ''x2'' included, using specified color }
|
---|
425 | procedure FastBlendHorizLine(x, y, x2: int32or64; c: TBGRAPixel); override;
|
---|
426 | {** Draws an horizontal line at line ''y'' and
|
---|
427 | at columns ''x'' to ''x2'' included, using specified scanner
|
---|
428 | and the specified ''ADrawMode'' }
|
---|
429 | procedure HorizLine(x, y, x2: int32or64; texture: IBGRAScanner; ADrawMode : TDrawMode); override;
|
---|
430 | {** Draws an horizontal line at line ''y'' and
|
---|
431 | at columns ''x'' to ''x2'' included, using specified color
|
---|
432 | and the specified ''ADrawMode'' }{inherited
|
---|
433 | procedure HorizLine(x,y,x2: Int32or64; c: TBGRAPixel; ADrawMode: TDrawMode); overload;
|
---|
434 | }
|
---|
435 | {** Replaces the alpha value of the pixels at line ''y'' and
|
---|
436 | at columns ''x'' to ''x2'' included }
|
---|
437 | procedure AlphaHorizLine(x, y, x2: int32or64; alpha: byte); override;
|
---|
438 | {** Draws an horizontal line with gamma correction at line ''y'' and
|
---|
439 | at columns ''x'' to ''x2'' included, using specified color,
|
---|
440 | and with a transparency that increases with the color difference
|
---|
441 | with ''compare''. If the difference is greater than ''maxDiff'',
|
---|
442 | pixels are not changed }
|
---|
443 | procedure DrawHorizLineDiff(x, y, x2: int32or64; c, compare: TBGRAPixel;
|
---|
444 | maxDiff: byte); override;
|
---|
445 |
|
---|
446 | {** Replaces a vertical line at column ''x'' and at row ''y'' to ''y2'' }
|
---|
447 | procedure SetVertLine(x, y, y2: int32or64; c: TBGRAPixel); override;
|
---|
448 | {** Xors a vertical line at column ''x'' and at row ''y'' to ''y2'' }
|
---|
449 | procedure XorVertLine(x, y, y2: int32or64; c: TBGRAPixel); override;
|
---|
450 | {** Draws a vertical line with gamma correction at column ''x'' and at row ''y'' to ''y2'' }
|
---|
451 | procedure DrawVertLine(x, y, y2: int32or64; c: TBGRAPixel); override;
|
---|
452 | {** Draws a vertical line without gamma correction at column ''x'' and at row ''y'' to ''y2'' }
|
---|
453 | procedure FastBlendVertLine(x, y, y2: int32or64; c: TBGRAPixel); override;
|
---|
454 | {** Replace alpha values in a vertical line at column ''x'' and at row ''y'' to ''y2'' }
|
---|
455 | procedure AlphaVertLine(x, y, y2: int32or64; alpha: byte); override;
|
---|
456 | {** Draws a vertical line with the specified draw mode at column ''x'' and at row ''y'' to ''y2'' }{inherited
|
---|
457 | procedure VertLine(x,y,y2: Int32or64; c: TBGRAPixel; ADrawMode: TDrawMode);
|
---|
458 | }
|
---|
459 |
|
---|
460 | {** Draws an aliased line from (x1,y1) to (x2,y2) using Bresenham's algorithm
|
---|
461 | ''c'' specifies the color. ''DrawLastPixel'' specifies if (x2,y2) must be drawn.
|
---|
462 | ''ADrawMode'' specifies the mode to use when drawing the pixels }
|
---|
463 | procedure DrawLine(x1, y1, x2, y2: integer; c: TBGRAPixel; DrawLastPixel: boolean; ADrawMode: TDrawMode = dmDrawWithTransparency); override;
|
---|
464 | {** Draws an antialiased line from (x1,y1) to (x2,y2) using an improved version of Bresenham's algorithm
|
---|
465 | ''c'' specifies the color. ''DrawLastPixel'' specifies if (x2,y2) must be drawn }
|
---|
466 | procedure DrawLineAntialias(x1, y1, x2, y2: integer; c: TBGRAPixel; DrawLastPixel: boolean); overload; override;
|
---|
467 | {** Draws an antialiased line with two colors ''c1'' and ''c2'' as dashes of lenght ''dashLen'' }
|
---|
468 | procedure DrawLineAntialias(x1, y1, x2, y2: integer; c1, c2: TBGRAPixel; dashLen: integer; DrawLastPixel: boolean); overload; override;
|
---|
469 | {** Draws an antialiased line with two colors ''c1'' and ''c2'' as dashes of lenght ''dashLen''.
|
---|
470 | ''DashPos'' can be used to specify the start dash position and to retrieve the dash position at the end
|
---|
471 | of the line, in order to draw a polyline with consistent dashes }
|
---|
472 | procedure DrawLineAntialias(x1, y1, x2, y2: integer; c1, c2: TBGRAPixel; dashLen: integer; DrawLastPixel: boolean; var DashPos: integer); override;
|
---|
473 |
|
---|
474 | {** Erases the line from (x1,y1) to (x2,y2) using Bresenham's algorithm.
|
---|
475 | ''alpha'' specifies how much to decrease. If ''alpha'' = 0, nothing
|
---|
476 | is changed and if ''alpha'' = 255, all pixels become transparent.
|
---|
477 | ''DrawListPixel'' specifies if (x2,y2) must be changed }
|
---|
478 | procedure EraseLine(x1, y1, x2, y2: integer; alpha: byte; DrawLastPixel: boolean); override;
|
---|
479 | {** Erases the line from (x1,y1) to (x2,y2) width antialiasing.
|
---|
480 | ''alpha'' specifies how much to decrease. If ''alpha'' = 0, nothing
|
---|
481 | is changed and if ''alpha'' = 255, all pixels become transparent.
|
---|
482 | ''DrawListPixel'' specifies if (x2,y2) must be changed }
|
---|
483 | procedure EraseLineAntialias(x1, y1, x2, y2: integer; alpha: byte; DrawLastPixel: boolean); override;
|
---|
484 |
|
---|
485 | {==== Drawing lines and polylines (floating point coordinates) ====}
|
---|
486 | {* These functions use the current pen style/cap/join. The parameter ''w''
|
---|
487 | specifies the width of the line and the base unit for dashes.
|
---|
488 | See [[BGRABitmap tutorial 13|coordinate system]]. }
|
---|
489 |
|
---|
490 | {** Draws a line from (x1,y1) to (x2,y2) using current pen style/cap/join }
|
---|
491 | procedure DrawLineAntialias(x1, y1, x2, y2: single; c: TBGRAPixel; w: single); overload; override;
|
---|
492 | {** Draws a line from (x1,y1) to (x2,y2) using current pen style/cap/join.
|
---|
493 | ''texture'' specifies the source color to use when filling the line }
|
---|
494 | procedure DrawLineAntialias(x1, y1, x2, y2: single; texture: IBGRAScanner; w: single); overload; override;
|
---|
495 | {** Draws a line from (x1,y1) to (x2,y2) using current pen style/cap/join.
|
---|
496 | ''Closed'' specifies if the end of the line is closed. If it is not closed,
|
---|
497 | a space is left so that the next line can fit }
|
---|
498 | procedure DrawLineAntialias(x1, y1, x2, y2: single; c: TBGRAPixel; w: single; ClosedCap: boolean); overload; override;
|
---|
499 | {** Same as above with ''texture'' specifying the source color to use when filling the line }
|
---|
500 | procedure DrawLineAntialias(x1, y1, x2, y2: single; texture: IBGRAScanner; w: single; ClosedCap: boolean); overload; override;
|
---|
501 |
|
---|
502 | {** Draws a polyline using current pen style/cap/join }
|
---|
503 | procedure DrawPolyLineAntialias(const points: array of TPointF; c: TBGRAPixel; w: single); overload; override;
|
---|
504 | {** Draws a polyline using current pen style/cap/join.
|
---|
505 | ''texture'' specifies the source color to use when filling the line }
|
---|
506 | procedure DrawPolyLineAntialias(const points: array of TPointF; texture: IBGRAScanner; w: single); overload; override;
|
---|
507 | {** Draws a polyline using current pen style/cap/join.
|
---|
508 | ''Closed'' specifies if the end of the line is closed. If it is not closed,
|
---|
509 | a space is left so that the next line can fit }
|
---|
510 | procedure DrawPolyLineAntialias(const points: array of TPointF; c: TBGRAPixel; w: single; ClosedCap: boolean); overload; override;
|
---|
511 | procedure DrawPolyLineAntialias(const points: array of TPointF; texture: IBGRAScanner; w: single; ClosedCap: boolean); overload; override;
|
---|
512 | {** Draws a polyline using current pen style/cap/join.
|
---|
513 | ''fillcolor'' specifies a color to fill the polygon formed by the points }
|
---|
514 | procedure DrawPolyLineAntialias(const points: array of TPointF; c: TBGRAPixel; w: single; fillcolor: TBGRAPixel); overload; override;
|
---|
515 | {** Draws a polyline using current pen style/cap/join.
|
---|
516 | The last point considered as a join with the first point if it has
|
---|
517 | the same coordinate }
|
---|
518 | procedure DrawPolyLineAntialiasAutocycle(const points: array of TPointF; c: TBGRAPixel; w: single); override;
|
---|
519 | procedure DrawPolyLineAntialiasAutocycle(const points: array of TPointF; texture: IBGRAScanner; w: single); override;
|
---|
520 | {** Draws a polygon using current pen style/cap/join.
|
---|
521 | The polygon is always closed. You don't need to set the last point
|
---|
522 | to be the same as the first point }
|
---|
523 | procedure DrawPolygonAntialias(const points: array of TPointF; c: TBGRAPixel; w: single); overload; override;
|
---|
524 | {** Draws a polygon using current pen style/cap/join.
|
---|
525 | The polygon is always closed. You don't need to set the last point
|
---|
526 | to be the same as the first point }
|
---|
527 | procedure DrawPolygonAntialias(const points: array of TPointF; texture: IBGRAScanner; w: single); overload; override;
|
---|
528 | {** Draws a filled polygon using current pen style/cap/join.
|
---|
529 | The polygon is always closed. You don't need to set the last point
|
---|
530 | to be the same as the first point. }
|
---|
531 | procedure DrawPolygonAntialias(const points: array of TPointF; c: TBGRAPixel; w: single; fillcolor: TBGRAPixel); overload; override;
|
---|
532 |
|
---|
533 | {** Erases a line from (x1,y1) to (x2,y2) using current pen style/cap/join }
|
---|
534 | procedure EraseLineAntialias(x1, y1, x2, y2: single; alpha: byte; w: single); override;
|
---|
535 | {** Erases a line from (x1,y1) to (x2,y2) using current pen style/cap/join.
|
---|
536 | ''Closed'' specifies if the end of the line is closed. If it is not closed,
|
---|
537 | a space is left so that the next line can fit }
|
---|
538 | procedure EraseLineAntialias(x1, y1, x2, y2: single; alpha: byte; w: single; Closed: boolean); override;
|
---|
539 | {** Erases a polyline using current pen style/cap/join }
|
---|
540 | procedure ErasePolyLineAntialias(const points: array of TPointF; alpha: byte; w: single); override;
|
---|
541 |
|
---|
542 | {==== Rectangles (integer coordinates) ====}
|
---|
543 | {* The integer coordinates of rectangles interpreted such that
|
---|
544 | that the bottom/right pixels are not drawn. The width is equal
|
---|
545 | to x2-x, and pixels are drawn from x to x2-1. If x = x2, then nothing
|
---|
546 | is drawn. See [[BGRABitmap tutorial 13|coordinate system]].
|
---|
547 | * These functions do not take into account current pen style/cap/join.
|
---|
548 | They draw a continuous 1-pixel width border }
|
---|
549 |
|
---|
550 | {** Draw a size border of a rectangle,
|
---|
551 | using the specified ''mode'' }
|
---|
552 | procedure Rectangle(x, y, x2, y2: integer; c: TBGRAPixel; mode: TDrawMode); overload; override;
|
---|
553 | {** Draw a filled rectangle with a border of color ''BorderColor'',
|
---|
554 | using the specified ''mode'' }
|
---|
555 | procedure Rectangle(x, y, x2, y2: integer; BorderColor, FillColor: TBGRAPixel; mode: TDrawMode); overload; override;
|
---|
556 | {** Fills completely a rectangle, without any border, with the specified ''mode'' }
|
---|
557 | procedure FillRect(x, y, x2, y2: integer; c: TBGRAPixel; mode: TDrawMode); overload; override;
|
---|
558 | {** Fills completely a rectangle, without any border, with the specified ''texture'' and
|
---|
559 | with the specified ''mode'' }
|
---|
560 | procedure FillRect(x, y, x2, y2: integer; texture: IBGRAScanner; mode: TDrawMode; AScanOffset: TPoint); overload; override;
|
---|
561 | procedure FillRect(x, y, x2, y2: integer; texture: IBGRAScanner; mode: TDrawMode; AScanOffset: TPoint; ditheringAlgorithm: TDitheringAlgorithm); overload; override;
|
---|
562 | {** Sets the alpha value within the specified rectangle }
|
---|
563 | procedure AlphaFillRect(x, y, x2, y2: integer; alpha: byte); override;
|
---|
564 | {** Draws a filled round rectangle, with corners having an elliptical diameter of ''DX'' and ''DY'' }
|
---|
565 | procedure RoundRect(X1, Y1, X2, Y2: integer; DX, DY: integer; BorderColor, FillColor: TBGRAPixel; ADrawMode: TDrawMode = dmDrawWithTransparency); override;
|
---|
566 | {** Draws a round rectangle, with corners having an elliptical diameter of ''DX'' and ''DY'' }
|
---|
567 | procedure RoundRect(X1, Y1, X2, Y2: integer; DX, DY: integer; BorderColor: TBGRAPixel; ADrawMode: TDrawMode = dmDrawWithTransparency); override;
|
---|
568 | procedure FillRoundRect(X1, Y1, X2, Y2: integer; DX, DY: integer; FillTexture: IBGRAScanner; ADrawMode: TDrawMode = dmDrawWithTransparency); override; overload;
|
---|
569 |
|
---|
570 | {==== Rectangles and ellipses (floating point coordinates) ====}
|
---|
571 | {* These functions use the current pen style/cap/join. The parameter ''w''
|
---|
572 | specifies the width of the line and the base unit for dashes
|
---|
573 | * The coordinates are pixel-centered, so that when filling a rectangle,
|
---|
574 | if the supplied values are integers, the border will be half transparent.
|
---|
575 | If you want the border to be completely filled, you can subtract/add
|
---|
576 | 0.5 to the coordinates to include the remaining thin border.
|
---|
577 | See [[BGRABitmap tutorial 13|coordinate system]]. }
|
---|
578 |
|
---|
579 | {** Draws a rectangle with antialiasing and fills it with color ''back''.
|
---|
580 | Note that the pixel (x2,y2) is included contrary to integer coordinates }
|
---|
581 | procedure RectangleAntialias(x, y, x2, y2: single; c: TBGRAPixel; w: single; back: TBGRAPixel); override;
|
---|
582 | {** Draws a rectangle with antialiasing. Note that the pixel (x2,y2) is
|
---|
583 | included contrary to integer coordinates }
|
---|
584 | procedure RectangleAntialias(x, y, x2, y2: single; texture: IBGRAScanner; w: single); override;
|
---|
585 | {** Fills a rectangle with antialiasing. For example (-0.5,-0.5,0.5,0.5)
|
---|
586 | fills one pixel }
|
---|
587 | procedure FillRectAntialias(x, y, x2, y2: single; c: TBGRAPixel; pixelCenteredCoordinates: boolean = true); overload; override;
|
---|
588 | {** Fills a rectangle with a texture }
|
---|
589 | procedure FillRectAntialias(x, y, x2, y2: single; texture: IBGRAScanner; pixelCenteredCoordinates: boolean = true); overload; override;
|
---|
590 | {** Erases the content of a rectangle with antialiasing }
|
---|
591 | procedure EraseRectAntialias(x, y, x2, y2: single; alpha: byte; pixelCenteredCoordinates: boolean = true); override;
|
---|
592 |
|
---|
593 | {** Draws a rounded rectangle border with antialiasing. The corners have an
|
---|
594 | elliptical radius of ''rx'' and ''ry''. ''options'' specifies how to
|
---|
595 | draw the corners. See [[BGRABitmap Geometry types|geometry types]] }
|
---|
596 | procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; c: TBGRAPixel; w: single; options: TRoundRectangleOptions = []); overload; override;
|
---|
597 | {** Draws a rounded rectangle border with the specified texture.
|
---|
598 | The corners have an elliptical radius of ''rx'' and ''ry''.
|
---|
599 | ''options'' specifies how to draw the corners.
|
---|
600 | See [[BGRABitmap Geometry types|geometry types]] }
|
---|
601 | procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; texture: IBGRAScanner; w: single; options: TRoundRectangleOptions = []); overload; override;
|
---|
602 | {** Draws and fills a round rectangle }
|
---|
603 | procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; pencolor: TBGRAPixel; w: single; fillcolor: TBGRAPixel; options: TRoundRectangleOptions = []); overload; override;
|
---|
604 | {** Draws and fills a round rectangle with textures }
|
---|
605 | procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; penTexture: IBGRAScanner; w: single; fillTexture: IBGRAScanner; options: TRoundRectangleOptions = []); overload; override;
|
---|
606 |
|
---|
607 | {** Fills a rounded rectangle with antialiasing. The corners have an
|
---|
608 | elliptical radius of ''rx'' and ''ry''. ''options'' specifies how to
|
---|
609 | draw the corners. See [[BGRABitmap Geometry types|geometry types]] }
|
---|
610 | procedure FillRoundRectAntialias(x,y,x2,y2,rx,ry: single; c: TBGRAPixel; options: TRoundRectangleOptions = []; pixelCenteredCoordinates: boolean = true); overload; override;
|
---|
611 | {** Fills a rounded rectangle with a texture }
|
---|
612 | procedure FillRoundRectAntialias(x,y,x2,y2,rx,ry: single; texture: IBGRAScanner; options: TRoundRectangleOptions = []; pixelCenteredCoordinates: boolean = true); overload; override;
|
---|
613 | {** Erases the content of a rounded rectangle with a texture }
|
---|
614 | procedure EraseRoundRectAntialias(x,y,x2,y2,rx,ry: single; alpha: byte; options: TRoundRectangleOptions = []; pixelCenteredCoordinates: boolean = true); overload; override;
|
---|
615 |
|
---|
616 | {** Draws an ellipse without antialising. ''rx'' is the horizontal radius and
|
---|
617 | ''ry'' the vertical radius }
|
---|
618 | procedure Ellipse(x, y, rx, ry: single; c: TBGRAPixel; w: single; ADrawMode: TDrawMode); overload; override;
|
---|
619 | procedure Ellipse(AOrigin, AXAxis, AYAxis: TPointF; c: TBGRAPixel; w: single; ADrawMode: TDrawMode); overload; override;
|
---|
620 | {** Draws an ellipse with antialising. ''rx'' is the horizontal radius and
|
---|
621 | ''ry'' the vertical radius }
|
---|
622 | procedure EllipseAntialias(x, y, rx, ry: single; c: TBGRAPixel; w: single); overload; override;
|
---|
623 | procedure EllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; c: TBGRAPixel; w: single); overload; override;
|
---|
624 | {** Draws an ellipse border with a ''texture'' }
|
---|
625 | procedure EllipseAntialias(x, y, rx, ry: single; texture: IBGRAScanner; w: single); overload; override;
|
---|
626 | procedure EllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; texture: IBGRAScanner; w: single); overload; override;
|
---|
627 | {** Draws and fills an ellipse }
|
---|
628 | procedure EllipseAntialias(x, y, rx, ry: single; c: TBGRAPixel; w: single; back: TBGRAPixel); overload; override;
|
---|
629 | procedure EllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; c: TBGRAPixel; w: single; back: TBGRAPixel); overload; override;
|
---|
630 | {** Fills an ellipse }
|
---|
631 | procedure FillEllipseAntialias(x, y, rx, ry: single; c: TBGRAPixel); overload; override;
|
---|
632 | procedure FillEllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; c: TBGRAPixel); overload; override;
|
---|
633 | {** Fills an ellipse with a ''texture'' }
|
---|
634 | procedure FillEllipseAntialias(x, y, rx, ry: single; texture: IBGRAScanner); overload; override;
|
---|
635 | procedure FillEllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; texture: IBGRAScanner); overload; override;
|
---|
636 | {** Fills an ellipse with a gradient of color. ''outercolor'' specifies
|
---|
637 | the end color of the gradient on the border of the ellipse and
|
---|
638 | ''innercolor'' the end color of the gradient at the center of the
|
---|
639 | ellipse }
|
---|
640 | procedure FillEllipseLinearColorAntialias(x, y, rx, ry: single; outercolor, innercolor: TBGRAPixel); overload; override;
|
---|
641 | procedure FillEllipseLinearColorAntialias(AOrigin, AXAxis, AYAxis: TPointF; outercolor, innercolor: TBGRAPixel); overload; override;
|
---|
642 | {** Erases the content of an ellipse }
|
---|
643 | procedure EraseEllipseAntialias(x, y, rx, ry: single; alpha: byte); overload; override;
|
---|
644 | procedure EraseEllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; alpha: byte); overload; override;
|
---|
645 |
|
---|
646 | {==== Polygons and path ====}
|
---|
647 | procedure FillPoly(const points: array of TPointF; c: TBGRAPixel; drawmode: TDrawMode; APixelCenteredCoordinates: boolean = true); overload; override;
|
---|
648 | procedure FillPoly(const points: array of TPointF; texture: IBGRAScanner; drawmode: TDrawMode; APixelCenteredCoordinates: boolean = true); overload; override;
|
---|
649 | procedure FillPolyAntialias(const points: array of TPointF; c: TBGRAPixel; APixelCenteredCoordinates: boolean = true); overload; override;
|
---|
650 | procedure FillPolyAntialias(const points: array of TPointF; texture: IBGRAScanner; APixelCenteredCoordinates: boolean = true); overload; override;
|
---|
651 | procedure ErasePoly(const points: array of TPointF; alpha: byte; APixelCenteredCoordinates: boolean = true); override;
|
---|
652 | procedure ErasePolyAntialias(const points: array of TPointF; alpha: byte; APixelCenteredCoordinates: boolean = true); override;
|
---|
653 |
|
---|
654 | procedure FillTriangleLinearColor(pt1,pt2,pt3: TPointF; c1,c2,c3: TBGRAPixel); override;
|
---|
655 | procedure FillTriangleLinearColorAntialias(pt1,pt2,pt3: TPointF; c1,c2,c3: TBGRAPixel); override;
|
---|
656 | procedure FillTriangleLinearMapping(pt1,pt2,pt3: TPointF; texture: IBGRAScanner; tex1, tex2, tex3: TPointF; TextureInterpolation: Boolean= True); override;
|
---|
657 | procedure FillTriangleLinearMappingLightness(pt1,pt2,pt3: TPointF; texture: IBGRAScanner; tex1, tex2, tex3: TPointF; light1,light2,light3: word; TextureInterpolation: Boolean= True); override;
|
---|
658 | procedure FillTriangleLinearMappingAntialias(pt1,pt2,pt3: TPointF; texture: IBGRAScanner; tex1, tex2, tex3: TPointF); override;
|
---|
659 |
|
---|
660 | procedure FillQuadLinearColor(pt1,pt2,pt3,pt4: TPointF; c1,c2,c3,c4: TBGRAPixel); override;
|
---|
661 | procedure FillQuadLinearColorAntialias(pt1,pt2,pt3,pt4: TPointF; c1,c2,c3,c4: TBGRAPixel); override;
|
---|
662 | procedure FillQuadLinearMapping(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; TextureInterpolation: Boolean= True; ACulling: TFaceCulling = fcNone); override;
|
---|
663 | procedure FillQuadLinearMappingLightness(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; light1,light2,light3,light4: word; TextureInterpolation: Boolean= True); override;
|
---|
664 | procedure FillQuadLinearMappingAntialias(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; ACulling: TFaceCulling = fcNone); override;
|
---|
665 | procedure FillQuadPerspectiveMapping(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; ADrawMode: TDrawMode = dmDrawWithTransparency); override;
|
---|
666 | procedure FillQuadPerspectiveMapping(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; ACleanBorders: TRect; ADrawMode: TDrawMode = dmDrawWithTransparency); override;
|
---|
667 | procedure FillQuadPerspectiveMappingAntialias(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF); override;
|
---|
668 | procedure FillQuadPerspectiveMappingAntialias(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; ACleanBorders: TRect); override;
|
---|
669 | procedure FillQuadAffineMapping(Orig,HAxis,VAxis: TPointF; AImage: TBGRACustomBitmap; APixelCenteredCoordinates: boolean = true; ADrawMode: TDrawMode = dmDrawWithTransparency; AOpacity: byte = 255); override;
|
---|
670 | procedure FillQuadAffineMappingAntialias(Orig,HAxis,VAxis: TPointF; AImage: TBGRACustomBitmap; APixelCenteredCoordinates: boolean = true; AOpacity: byte = 255); override;
|
---|
671 |
|
---|
672 | procedure FillPolyLinearMapping(const points: array of TPointF; texture: IBGRAScanner; texCoords: array of TPointF; TextureInterpolation: Boolean); override;
|
---|
673 | procedure FillPolyLinearMappingLightness(const points: array of TPointF; texture: IBGRAScanner; texCoords: array of TPointF; lightnesses: array of word; TextureInterpolation: Boolean); override;
|
---|
674 | procedure FillPolyLinearColor(const points: array of TPointF; AColors: array of TBGRAPixel); override;
|
---|
675 | procedure FillPolyPerspectiveMapping(const points: array of TPointF; const pointsZ: array of single; texture: IBGRAScanner; texCoords: array of TPointF; TextureInterpolation: Boolean; zbuffer: psingle = nil); override;
|
---|
676 | procedure FillPolyPerspectiveMappingLightness(const points: array of TPointF; const pointsZ: array of single; texture: IBGRAScanner; texCoords: array of TPointF; lightnesses: array of word; TextureInterpolation: Boolean; zbuffer: psingle = nil); override;
|
---|
677 |
|
---|
678 | procedure FillShape(shape: TBGRACustomFillInfo; c: TBGRAPixel; drawmode: TDrawMode); overload; override;
|
---|
679 | procedure FillShape(shape: TBGRACustomFillInfo; texture: IBGRAScanner; drawmode: TDrawMode); overload; override;
|
---|
680 | procedure FillShapeAntialias(shape: TBGRACustomFillInfo; c: TBGRAPixel); overload; override;
|
---|
681 | procedure FillShapeAntialias(shape: TBGRACustomFillInfo; texture: IBGRAScanner); overload; override;
|
---|
682 | procedure EraseShape(shape: TBGRACustomFillInfo; alpha: byte); override;
|
---|
683 | procedure EraseShapeAntialias(shape: TBGRACustomFillInfo; alpha: byte); override;
|
---|
684 |
|
---|
685 | procedure DrawPath(APath: IBGRAPath; AStrokeColor: TBGRAPixel; AWidth: single; AFillColor: TBGRAPixel); overload; override;
|
---|
686 | procedure DrawPath(APath: IBGRAPath; AStrokeTexture: IBGRAScanner; AWidth: single; AFillColor: TBGRAPixel); overload; override;
|
---|
687 | procedure DrawPath(APath: IBGRAPath; AStrokeColor: TBGRAPixel; AWidth: single; AFillTexture: IBGRAScanner); overload; override;
|
---|
688 | procedure DrawPath(APath: IBGRAPath; AStrokeTexture: IBGRAScanner; AWidth: single; AFillTexture: IBGRAScanner); overload; override;
|
---|
689 | procedure DrawPath(APath: IBGRAPath; AStrokeColor: TBGRAPixel; AWidth: single); overload; override;
|
---|
690 | procedure DrawPath(APath: IBGRAPath; AStrokeTexture: IBGRAScanner; AWidth: single); overload; override;
|
---|
691 | procedure FillPath(APath: IBGRAPath; AFillColor: TBGRAPixel); overload; override;
|
---|
692 | procedure FillPath(APath: IBGRAPath; AFillTexture: IBGRAScanner); overload; override;
|
---|
693 | procedure ErasePath(APath: IBGRAPath; alpha: byte); overload; override;
|
---|
694 |
|
---|
695 | procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeColor: TBGRAPixel; AWidth: single; AFillColor: TBGRAPixel); overload; override;
|
---|
696 | procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeTexture: IBGRAScanner; AWidth: single; AFillColor: TBGRAPixel); overload; override;
|
---|
697 | procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeColor: TBGRAPixel; AWidth: single; AFillTexture: IBGRAScanner); overload; override;
|
---|
698 | procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeTexture: IBGRAScanner; AWidth: single; AFillTexture: IBGRAScanner); overload; override;
|
---|
699 | procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeColor: TBGRAPixel; AWidth: single); overload; override;
|
---|
700 | procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeTexture: IBGRAScanner; AWidth: single); overload; override;
|
---|
701 | procedure FillPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AFillColor: TBGRAPixel); overload; override;
|
---|
702 | procedure FillPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AFillTexture: IBGRAScanner); overload; override;
|
---|
703 | procedure ErasePath(APath: IBGRAPath; AMatrix: TAffineMatrix; alpha: byte); overload; override;
|
---|
704 |
|
---|
705 | procedure ArrowStartAsNone; override;
|
---|
706 | procedure ArrowStartAsClassic(AFlipped: boolean = false; ACut: boolean = false; ARelativePenWidth: single = 1); override;
|
---|
707 | procedure ArrowStartAsTriangle(ABackOffset: single = 0; ARounded: boolean = false; AHollow: boolean = false; AHollowPenWidth: single = 0.5); override;
|
---|
708 | procedure ArrowStartAsTail; override;
|
---|
709 |
|
---|
710 | procedure ArrowEndAsNone; override;
|
---|
711 | procedure ArrowEndAsClassic(AFlipped: boolean = false; ACut: boolean = false; ARelativePenWidth: single = 1); override;
|
---|
712 | procedure ArrowEndAsTriangle(ABackOffset: single = 0; ARounded: boolean = false; AHollow: boolean = false; AHollowPenWidth: single = 0.5); override;
|
---|
713 | procedure ArrowEndAsTail; override;
|
---|
714 |
|
---|
715 | { Draws the UTF8 encoded string, with color c.
|
---|
716 | If align is taLeftJustify, (x,y) is the top-left corner.
|
---|
717 | If align is taCenter, (x,y) is at the top and middle of the text.
|
---|
718 | If align is taRightJustify, (x,y) is the top-right corner.
|
---|
719 | The value of FontOrientation is taken into account, so that the text may be rotated. }
|
---|
720 | procedure TextOut(x, y: single; sUTF8: string; c: TBGRAPixel; align: TAlignment; ARightToLeft: boolean); overload; override;
|
---|
721 |
|
---|
722 | { Same as above functions, except that the text is filled using texture.
|
---|
723 | The value of FontOrientation is taken into account, so that the text may be rotated. }
|
---|
724 | procedure TextOut(x, y: single; sUTF8: string; texture: IBGRAScanner; align: TAlignment; ARightToLeft: boolean); overload; override;
|
---|
725 |
|
---|
726 | { Same as above, except that the orientation is specified, overriding the value of the property FontOrientation. }
|
---|
727 | procedure TextOutAngle(x, y: single; orientationTenthDegCCW: integer; sUTF8: string; c: TBGRAPixel; align: TAlignment); overload; override;
|
---|
728 | procedure TextOutAngle(x, y: single; orientationTenthDegCCW: integer; sUTF8: string; texture: IBGRAScanner; align: TAlignment); overload; override;
|
---|
729 |
|
---|
730 | procedure TextOutCurved(ACursor: TBGRACustomPathCursor; sUTF8: string; AColor: TBGRAPixel; AAlign: TAlignment; ALetterSpacing: single); overload; override;
|
---|
731 | procedure TextOutCurved(ACursor: TBGRACustomPathCursor; sUTF8: string; ATexture: IBGRAScanner; AAlign: TAlignment; ALetterSpacing: single); overload; override;
|
---|
732 |
|
---|
733 | procedure TextMultiline(ALeft,ATop,AWidth: single; sUTF8: string; c: TBGRAPixel; AAlign: TBidiTextAlignment = btaNatural; AVertAlign: TTextLayout = tlTop; AParagraphSpacing: single = 0); overload; override;
|
---|
734 | procedure TextMultiline(ALeft,ATop,AWidth: single; sUTF8: string; ATexture: IBGRAScanner; AAlign: TBidiTextAlignment = btaNatural; AVertAlign: TTextLayout = tlTop; AParagraphSpacing: single = 0); overload; override;
|
---|
735 |
|
---|
736 | { Draw the UTF8 encoded string at the coordinate (x,y), clipped inside the rectangle ARect.
|
---|
737 | Additional style information is provided by the style parameter.
|
---|
738 | The color c or texture is used to fill the text. No rotation is applied. }
|
---|
739 | procedure TextRect(ARect: TRect; x, y: integer; sUTF8: string; style: TTextStyle; c: TBGRAPixel); overload; override;
|
---|
740 | procedure TextRect(ARect: TRect; x, y: integer; sUTF8: string; style: TTextStyle; texture: IBGRAScanner); overload; override;
|
---|
741 |
|
---|
742 | { Returns the total size of the string provided using the current font.
|
---|
743 | Orientation is not taken into account, so that the width is along the text. End of lines are stripped from the string. }
|
---|
744 | function TextSize(sUTF8: string): TSize; override;
|
---|
745 |
|
---|
746 | { Returns the affine box of the string provided using the current font.
|
---|
747 | Orientation is taken into account. End of lines are stripped from the string. }
|
---|
748 | function TextAffineBox(sUTF8: string): TAffineBox; override;
|
---|
749 |
|
---|
750 | { Returns the total size of a paragraph i.e. with word break }
|
---|
751 | function TextSize(sUTF8: string; AMaxWidth: integer): TSize; override;
|
---|
752 | function TextSize(sUTF8: string; AMaxWidth: integer; ARightToLeft: boolean): TSize; override;
|
---|
753 | function TextFitInfo(sUTF8: string; AMaxWidth: integer): integer; override;
|
---|
754 |
|
---|
755 | {Spline}
|
---|
756 | function ComputeClosedSpline(const APoints: array of TPointF; AStyle: TSplineStyle): ArrayOfTPointF; override;
|
---|
757 | function ComputeOpenedSpline(const APoints: array of TPointF; AStyle: TSplineStyle): ArrayOfTPointF; override;
|
---|
758 |
|
---|
759 | function ComputeBezierCurve(const ACurve: TCubicBezierCurve): ArrayOfTPointF; overload; override;
|
---|
760 | function ComputeBezierCurve(const ACurve: TQuadraticBezierCurve): ArrayOfTPointF; overload; override;
|
---|
761 | function ComputeBezierSpline(const ASpline: array of TCubicBezierCurve): ArrayOfTPointF; overload; override;
|
---|
762 | function ComputeBezierSpline(const ASpline: array of TQuadraticBezierCurve): ArrayOfTPointF; overload; override;
|
---|
763 |
|
---|
764 | function ComputeWidePolyline(const points: array of TPointF; w: single): ArrayOfTPointF; overload; override;
|
---|
765 | function ComputeWidePolyline(const points: array of TPointF; w: single; ClosedCap: boolean): ArrayOfTPointF; overload; override;
|
---|
766 | function ComputeWidePolygon(const points: array of TPointF; w: single): ArrayOfTPointF; overload; override;
|
---|
767 |
|
---|
768 | function ComputeEllipseContour(x,y,rx,ry: single; quality: single = 1): ArrayOfTPointF; overload; override;
|
---|
769 | function ComputeEllipseContour(AOrigin, AXAxis, AYAxis: TPointF; quality: single = 1): ArrayOfTPointF; overload; override;
|
---|
770 | function ComputeEllipseBorder(x,y,rx,ry,w: single; quality: single = 1): ArrayOfTPointF; overload; override;
|
---|
771 | function ComputeEllipseBorder(AOrigin, AXAxis, AYAxis: TPointF; w: single; quality: single = 1): ArrayOfTPointF; override; overload;
|
---|
772 | function ComputeArc65536(x,y,rx,ry: single; start65536,end65536: word; quality: single = 1): ArrayOfTPointF; override;
|
---|
773 | function ComputeArcRad(x,y,rx,ry: single; startRad,endRad: single; quality: single = 1): ArrayOfTPointF; override;
|
---|
774 | function ComputeRoundRect(x1,y1,x2,y2,rx,ry: single; quality: single = 1): ArrayOfTPointF; overload; override;
|
---|
775 | function ComputeRoundRect(x1,y1,x2,y2,rx,ry: single; options: TRoundRectangleOptions; quality: single = 1): ArrayOfTPointF; overload; override;
|
---|
776 | function ComputePie65536(x,y,rx,ry: single; start65536,end65536: word; quality: single = 1): ArrayOfTPointF; override;
|
---|
777 | function ComputePieRad(x,y,rx,ry: single; startRad,endRad: single; quality: single = 1): ArrayOfTPointF; override;
|
---|
778 |
|
---|
779 | {Filling}
|
---|
780 | procedure NoClip; override;
|
---|
781 | procedure Fill(texture: IBGRAScanner; mode: TDrawMode); overload; override;
|
---|
782 | procedure Fill(texture: IBGRAScanner); overload; override;
|
---|
783 | procedure Fill(c: TBGRAPixel; start, Count: integer); overload; override;
|
---|
784 | procedure DrawPixels(c: TBGRAPixel; start, Count: integer); override;
|
---|
785 | procedure AlphaFill(alpha: byte; start, Count: integer); override;
|
---|
786 | procedure FillMask(x,y: integer; AMask: TBGRACustomBitmap; color: TBGRAPixel; ADrawMode: TDrawMode); override;
|
---|
787 | procedure FillMask(x,y: integer; AMask: TBGRACustomBitmap; texture: IBGRAScanner; ADrawMode: TDrawMode; AOpacity: byte = 255); override;
|
---|
788 | procedure EraseMask(x,y: integer; AMask: TBGRACustomBitmap; alpha: byte=255); override;
|
---|
789 | procedure FillClearTypeMask(x,y: integer; xThird: integer; AMask: TBGRACustomBitmap; color: TBGRAPixel; ARGBOrder: boolean = true); override;
|
---|
790 | procedure FillClearTypeMask(x,y: integer; xThird: integer; AMask: TBGRACustomBitmap; texture: IBGRAScanner; ARGBOrder: boolean = true); override;
|
---|
791 | procedure ReplaceColor(before, after: TColor); override;
|
---|
792 | procedure ReplaceColor(before, after: TBGRAPixel); override;
|
---|
793 | procedure ReplaceColor(ABounds: TRect; before, after: TColor); override;
|
---|
794 | procedure ReplaceColor(ABounds: TRect; before, after: TBGRAPixel); override;
|
---|
795 | procedure ReplaceTransparent(after: TBGRAPixel); override;
|
---|
796 | procedure ReplaceTransparent(ABounds: TRect; after: TBGRAPixel); override;
|
---|
797 | procedure ParallelFloodFill(X, Y: integer; Dest: TBGRACustomBitmap; Color: TBGRAPixel;
|
---|
798 | mode: TFloodfillMode; Tolerance: byte = 0); override;
|
---|
799 | procedure GradientFill(x, y, x2, y2: integer; c1, c2: TBGRAPixel;
|
---|
800 | gtype: TGradientType; o1, o2: TPointF; mode: TDrawMode;
|
---|
801 | gammaColorCorrection: boolean = True; Sinus: Boolean=False;
|
---|
802 | ditherAlgo: TDitheringAlgorithm = daNearestNeighbor); override;
|
---|
803 | procedure GradientFill(x, y, x2, y2: integer; gradient: TBGRACustomGradient;
|
---|
804 | gtype: TGradientType; o1, o2: TPointF; mode: TDrawMode;
|
---|
805 | Sinus: Boolean=False; ditherAlgo: TDitheringAlgorithm = daNearestNeighbor); override;
|
---|
806 | function CreateBrushTexture(ABrushStyle: TBrushStyle; APatternColor, ABackgroundColor: TBGRAPixel;
|
---|
807 | AWidth: integer = 8; AHeight: integer = 8; APenWidth: single = 1): TBGRACustomBitmap; override;
|
---|
808 | function ScanAtInteger(X,Y: integer): TBGRAPixel; override;
|
---|
809 | procedure ScanMoveTo(X,Y: Integer); override;
|
---|
810 | function ScanNextPixel: TBGRAPixel; override;
|
---|
811 | function ScanAt(X,Y: Single): TBGRAPixel; override;
|
---|
812 | function IsScanPutPixelsDefined: boolean; override;
|
---|
813 | procedure ScanPutPixels(pdest: PBGRAPixel; count: integer; mode: TDrawMode); override;
|
---|
814 |
|
---|
815 | {Canvas drawing functions}
|
---|
816 | procedure Draw(ACanvas: TCanvas; x, y: integer; Opaque: boolean = True); overload; override;
|
---|
817 | procedure Draw(ACanvas: TCanvas; Rect: TRect; Opaque: boolean = True); overload; override;
|
---|
818 | procedure InvalidateBitmap; override; //call if you modify with Scanline
|
---|
819 | procedure LoadFromBitmapIfNeeded; override; //call to ensure that bitmap data is up to date
|
---|
820 |
|
---|
821 | {BGRA bitmap functions}
|
---|
822 | procedure CrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadePosition: byte; mode: TDrawMode = dmDrawWithTransparency); overload; override;
|
---|
823 | procedure CrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadeMask: IBGRAScanner; mode: TDrawMode = dmDrawWithTransparency); overload; override;
|
---|
824 | procedure PutImage(x, y: integer; Source: TBGRACustomBitmap; mode: TDrawMode; AOpacity: byte = 255); overload; override;
|
---|
825 | procedure PutImageAffine(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; AOutputBounds: TRect; AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte=255); overload; override;
|
---|
826 | function GetImageAffineBounds(AMatrix: TAffineMatrix; ASourceBounds: TRect; AClipOutput: boolean = true): TRect; overload; override;
|
---|
827 | class function IsAffineRoughlyTranslation(AMatrix: TAffineMatrix; ASourceBounds: TRect): boolean; override;
|
---|
828 |
|
---|
829 | procedure StretchPutImage(ARect: TRect; Source: TBGRACustomBitmap; mode: TDrawMode; AOpacity: byte = 255); override;
|
---|
830 |
|
---|
831 | procedure BlendImage(x, y: integer; Source: TBGRACustomBitmap; operation: TBlendOperation); override;
|
---|
832 | procedure BlendImageOver(x, y: integer; Source: TBGRACustomBitmap; operation: TBlendOperation; AOpacity: byte = 255;
|
---|
833 | ALinearBlend: boolean = false); override;
|
---|
834 |
|
---|
835 | function GetPart(ARect: TRect): TBGRACustomBitmap; override;
|
---|
836 | function GetPtrBitmap(Top,Bottom: Integer): TBGRACustomBitmap; override;
|
---|
837 | function Duplicate(DuplicateProperties: Boolean = False; DuplicateXorMask: Boolean = False) : TBGRACustomBitmap; override;
|
---|
838 | procedure CopyPropertiesTo(ABitmap: TBGRADefaultBitmap);
|
---|
839 | function Equals(comp: TBGRACustomBitmap): boolean; overload; override;
|
---|
840 | function Equals(comp: TBGRAPixel): boolean; overload; override;
|
---|
841 | function GetDifferenceBounds(ABitmap: TBGRACustomBitmap): TRect; override;
|
---|
842 | function MakeBitmapCopy(BackgroundColor: TColor): TBitmap; override;
|
---|
843 |
|
---|
844 | function Resample(newWidth, newHeight: integer;
|
---|
845 | mode: TResampleMode = rmFineResample): TBGRACustomBitmap; override;
|
---|
846 | procedure VerticalFlip(ARect: TRect); overload; override;
|
---|
847 | procedure HorizontalFlip(ARect: TRect); overload; override;
|
---|
848 | function RotateCW: TBGRACustomBitmap; override;
|
---|
849 | function RotateCCW: TBGRACustomBitmap; override;
|
---|
850 | procedure Negative; override;
|
---|
851 | procedure NegativeRect(ABounds: TRect); override;
|
---|
852 | procedure LinearNegative; override;
|
---|
853 | procedure LinearNegativeRect(ABounds: TRect); override;
|
---|
854 | procedure InplaceGrayscale(AGammaCorrection: boolean = true); overload; override;
|
---|
855 | procedure InplaceGrayscale(ABounds: TRect; AGammaCorrection: boolean = true); overload; override;
|
---|
856 | procedure InplaceNormalize(AEachChannel: boolean = True); overload; override;
|
---|
857 | procedure InplaceNormalize(ABounds: TRect; AEachChannel: boolean = True); overload; override;
|
---|
858 | procedure SwapRedBlue; override;
|
---|
859 | procedure SwapRedBlue(ARect: TRect); override;
|
---|
860 | procedure GrayscaleToAlpha; override;
|
---|
861 | procedure AlphaToGrayscale; override;
|
---|
862 | procedure ApplyMask(mask: TBGRACustomBitmap; ARect: TRect; AMaskRectTopLeft: TPoint); overload; override;
|
---|
863 | function GetMaskFromAlpha: TBGRACustomBitmap; override;
|
---|
864 | procedure ApplyGlobalOpacity(alpha: byte); override;
|
---|
865 | procedure ApplyGlobalOpacity(ABounds: TRect; alpha: byte); override;
|
---|
866 | procedure ConvertToLinearRGB; override;
|
---|
867 | procedure ConvertFromLinearRGB; override;
|
---|
868 | procedure DrawCheckers(ARect: TRect; AColorEven,AColorOdd: TBGRAPixel); override;
|
---|
869 |
|
---|
870 | {Filters}
|
---|
871 | function FilterSmartZoom3(Option: TMedianOption): TBGRACustomBitmap; override;
|
---|
872 | function FilterMedian(Option: TMedianOption): TBGRACustomBitmap; override;
|
---|
873 | function FilterSmooth: TBGRACustomBitmap; override;
|
---|
874 | function FilterSharpen(Amount: single = 1): TBGRACustomBitmap; overload; override;
|
---|
875 | function FilterSharpen(ABounds: TRect; Amount: single = 1): TBGRACustomBitmap; overload; override;
|
---|
876 | function FilterContour: TBGRACustomBitmap; override;
|
---|
877 | function FilterPixelate(pixelSize: integer; useResample: boolean; filter: TResampleFilter = rfLinear): TBGRACustomBitmap; override;
|
---|
878 | function FilterBlurRadial(radius: single; blurType: TRadialBlurType): TBGRACustomBitmap; overload; override;
|
---|
879 | function FilterBlurRadial(ABounds: TRect; radius: single; blurType: TRadialBlurType): TBGRACustomBitmap; overload; override;
|
---|
880 | function FilterBlurRadial(radiusX, radiusY: single; blurType: TRadialBlurType): TBGRACustomBitmap; overload; override;
|
---|
881 | function FilterBlurRadial(ABounds: TRect; radiusX, radiusY: single; blurType: TRadialBlurType): TBGRACustomBitmap; overload; override;
|
---|
882 | function FilterBlurMotion(distance: single; angle: single; oriented: boolean): TBGRACustomBitmap; overload; override;
|
---|
883 | function FilterBlurMotion(ABounds: TRect; distance: single; angle: single; oriented: boolean): TBGRACustomBitmap; overload; override;
|
---|
884 | function FilterCustomBlur(mask: TBGRACustomBitmap): TBGRACustomBitmap; overload; override;
|
---|
885 | function FilterCustomBlur(ABounds: TRect; mask: TBGRACustomBitmap): TBGRACustomBitmap; overload; override;
|
---|
886 | function FilterEmboss(angle: single; AStrength: integer= 64; AOptions: TEmbossOptions = []): TBGRACustomBitmap; overload; override;
|
---|
887 | function FilterEmboss(angle: single; ABounds: TRect; AStrength: integer= 64; AOptions: TEmbossOptions = []): TBGRACustomBitmap; overload; override;
|
---|
888 | function FilterEmbossHighlight(FillSelection: boolean): TBGRACustomBitmap; overload; override;
|
---|
889 | function FilterEmbossHighlight(FillSelection: boolean; BorderColor: TBGRAPixel): TBGRACustomBitmap; overload; override;
|
---|
890 | function FilterEmbossHighlight(FillSelection: boolean; BorderColor: TBGRAPixel; var Offset: TPoint): TBGRACustomBitmap; overload; override;
|
---|
891 | function FilterGrayscale: TBGRACustomBitmap; overload; override;
|
---|
892 | function FilterGrayscale(ABounds: TRect): TBGRACustomBitmap; overload; override;
|
---|
893 | function FilterNormalize(eachChannel: boolean = True): TBGRACustomBitmap; overload; override;
|
---|
894 | function FilterNormalize(ABounds: TRect; eachChannel: boolean = True): TBGRACustomBitmap; overload; override;
|
---|
895 | function FilterRotate(origin: TPointF; angle: single; correctBlur: boolean = false): TBGRACustomBitmap; override;
|
---|
896 | function FilterAffine(AMatrix: TAffineMatrix; correctBlur: boolean = false): TBGRACustomBitmap; override;
|
---|
897 | function FilterSphere: TBGRACustomBitmap; override;
|
---|
898 | function FilterTwirl(ACenter: TPoint; ARadius: Single; ATurn: Single=1; AExponent: Single=3): TBGRACustomBitmap; overload; override;
|
---|
899 | function FilterTwirl(ABounds: TRect; ACenter: TPoint; ARadius: Single; ATurn: Single=1; AExponent: Single=3): TBGRACustomBitmap; overload; override;
|
---|
900 | function FilterCylinder: TBGRACustomBitmap; override;
|
---|
901 | function FilterPlane: TBGRACustomBitmap; override;
|
---|
902 | end;
|
---|
903 |
|
---|
904 | { TBGRAPtrBitmap }
|
---|
905 |
|
---|
906 | TBGRAPtrBitmap = class(TBGRADefaultBitmap)
|
---|
907 | protected
|
---|
908 | function GetLineOrder: TRawImageLineOrder; override;
|
---|
909 | procedure SetLineOrder(AValue: TRawImageLineOrder); override;
|
---|
910 | procedure ReallocData; override;
|
---|
911 | procedure FreeData; override;
|
---|
912 | procedure CannotResize;
|
---|
913 | procedure NotImplemented;
|
---|
914 | procedure RebuildBitmap; override;
|
---|
915 |
|
---|
916 | function CreateDefaultFontRenderer: TBGRACustomFontRenderer; override; //to override
|
---|
917 | function LoadFromRawImage({%H-}ARawImage: TRawImage; {%H-}DefaultOpacity: byte;
|
---|
918 | {%H-}AlwaysReplaceAlpha: boolean=False; {%H-}RaiseErrorOnInvalidPixelFormat: boolean
|
---|
919 | =True): boolean; override; //to override
|
---|
920 | public
|
---|
921 | constructor Create(AWidth, AHeight: integer; AData: Pointer); overload;
|
---|
922 | function Duplicate(DuplicateProperties: Boolean = False; DuplicateXorMask: Boolean = False): TBGRACustomBitmap; override;
|
---|
923 | procedure SetDataPtr(AData: Pointer);
|
---|
924 | property LineOrder: TRawImageLineOrder Read GetLineOrder Write SetLineOrder;
|
---|
925 |
|
---|
926 | procedure DataDrawTransparent({%H-}ACanvas: TCanvas; {%H-}Rect: TRect; {%H-}AData: Pointer;
|
---|
927 | {%H-}ALineOrder: TRawImageLineOrder; {%H-}AWidth, {%H-}AHeight: integer); override; //to override
|
---|
928 | procedure DataDrawOpaque({%H-}ACanvas: TCanvas; {%H-}Rect: TRect; {%H-}AData: Pointer;
|
---|
929 | {%H-}ALineOrder: TRawImageLineOrder; {%H-}AWidth, {%H-}AHeight: integer); override; //to override
|
---|
930 | procedure GetImageFromCanvas({%H-}CanvasSource: TCanvas; {%H-}x, {%H-}y: integer); override; //to override
|
---|
931 |
|
---|
932 | procedure Assign({%H-}Source: TPersistent); override;
|
---|
933 | procedure TakeScreenshot({%H-}ARect: TRect); override;
|
---|
934 | procedure TakeScreenshotOfPrimaryMonitor; override;
|
---|
935 | procedure LoadFromDevice({%H-}DC: HDC); override;
|
---|
936 | procedure LoadFromDevice({%H-}DC: HDC; {%H-}ARect: TRect); override;
|
---|
937 | end;
|
---|
938 |
|
---|
939 | var
|
---|
940 | DefaultTextStyle: TTextStyle;
|
---|
941 |
|
---|
942 | procedure BGRAGradientFill(bmp: TBGRACustomBitmap; x, y, x2, y2: integer;
|
---|
943 | c1, c2: TBGRAPixel; gtype: TGradientType; o1, o2: TPointF; mode: TDrawMode;
|
---|
944 | gammaColorCorrection: boolean = True; Sinus: Boolean=False);
|
---|
945 |
|
---|
946 | type
|
---|
947 |
|
---|
948 | { TBitmapTracker }
|
---|
949 |
|
---|
950 | TBitmapTracker = class(TBitmap)
|
---|
951 | protected
|
---|
952 | FUser: TBGRADefaultBitmap;
|
---|
953 | procedure Changed(Sender: TObject); override;
|
---|
954 | public
|
---|
955 | constructor Create(AUser: TBGRADefaultBitmap); overload;
|
---|
956 | end;
|
---|
957 |
|
---|
958 | implementation
|
---|
959 |
|
---|
960 | uses Math, BGRAUTF8, BGRABlend, BGRAFilters, BGRAGradientScanner,
|
---|
961 | BGRAResample, BGRAPolygon, BGRAPolygonAliased,
|
---|
962 | BGRAPath, FPReadPcx, FPWritePcx, FPReadXPM, FPWriteXPM,
|
---|
963 | BGRAReadBMP, BGRAReadJpeg,
|
---|
964 | BGRADithering, BGRAFilterScanner;
|
---|
965 |
|
---|
966 | { TBitmapTracker }
|
---|
967 |
|
---|
968 | constructor TBitmapTracker.Create(AUser: TBGRADefaultBitmap);
|
---|
969 | begin
|
---|
970 | FUser := AUser;
|
---|
971 | inherited Create;
|
---|
972 | end;
|
---|
973 |
|
---|
974 | procedure TBitmapTracker.Changed(Sender: TObject);
|
---|
975 | begin
|
---|
976 | if FUser <> nil then
|
---|
977 | begin
|
---|
978 | FUser.FBitmapModified := True;
|
---|
979 | FUser.FAlphaCorrectionNeeded := true;
|
---|
980 | end;
|
---|
981 | inherited Changed(Sender);
|
---|
982 | end;
|
---|
983 |
|
---|
984 | { TBGRADefaultBitmap }
|
---|
985 |
|
---|
986 | function TBGRADefaultBitmap.CheckEmpty: boolean;
|
---|
987 | const
|
---|
988 | alphaMask = $ff shl TBGRAPixel_AlphaShift;
|
---|
989 | var
|
---|
990 | i: integer;
|
---|
991 | p: PBGRAPixel;
|
---|
992 | begin
|
---|
993 | p := Data;
|
---|
994 | for i := (NbPixels shr 1) - 1 downto 0 do
|
---|
995 | begin
|
---|
996 | if PInt64(p)^ and (alphaMask or (alphaMask shl 32)) <> 0 then
|
---|
997 | begin
|
---|
998 | Result := False;
|
---|
999 | exit;
|
---|
1000 | end;
|
---|
1001 | Inc(p,2);
|
---|
1002 | end;
|
---|
1003 | if Odd(NbPixels) and (p^.alpha <> 0) then
|
---|
1004 | begin
|
---|
1005 | Result := false;
|
---|
1006 | exit;
|
---|
1007 | end;
|
---|
1008 | Result := True;
|
---|
1009 | end;
|
---|
1010 |
|
---|
1011 | function TBGRADefaultBitmap.CheckIsZero: boolean;
|
---|
1012 | var
|
---|
1013 | i: integer;
|
---|
1014 | p: PBGRAPixel;
|
---|
1015 | begin
|
---|
1016 | p := Data;
|
---|
1017 | for i := (NbPixels shr 1) - 1 downto 0 do
|
---|
1018 | begin
|
---|
1019 | if PInt64(p)^ <> 0 then
|
---|
1020 | begin
|
---|
1021 | Result := False;
|
---|
1022 | exit;
|
---|
1023 | end;
|
---|
1024 | Inc(p,2);
|
---|
1025 | end;
|
---|
1026 | if Odd(NbPixels) and (PDWord(p)^ <> 0) then
|
---|
1027 | begin
|
---|
1028 | Result := false;
|
---|
1029 | exit;
|
---|
1030 | end;
|
---|
1031 | Result := True;
|
---|
1032 | end;
|
---|
1033 |
|
---|
1034 | function TBGRADefaultBitmap.GetCanvasAlphaCorrection: boolean;
|
---|
1035 | begin
|
---|
1036 | Result := (FCanvasOpacity <> 0);
|
---|
1037 | end;
|
---|
1038 |
|
---|
1039 | function TBGRADefaultBitmap.GetCustomPenStyle: TBGRAPenStyle;
|
---|
1040 | begin
|
---|
1041 | result := DuplicatePenStyle(FPenStroker.CustomPenStyle);
|
---|
1042 | end;
|
---|
1043 |
|
---|
1044 | procedure TBGRADefaultBitmap.SetCanvasAlphaCorrection(const AValue: boolean);
|
---|
1045 | begin
|
---|
1046 | if AValue then
|
---|
1047 | begin
|
---|
1048 | if FCanvasOpacity = 0 then
|
---|
1049 | FCanvasOpacity := 255;
|
---|
1050 | end
|
---|
1051 | else
|
---|
1052 | FCanvasOpacity := 0;
|
---|
1053 | end;
|
---|
1054 |
|
---|
1055 | procedure TBGRADefaultBitmap.DoLoadFromBitmap;
|
---|
1056 | begin
|
---|
1057 | //nothing
|
---|
1058 | end;
|
---|
1059 |
|
---|
1060 | procedure TBGRADefaultBitmap.SetCanvasDrawModeFP(const AValue: TDrawMode);
|
---|
1061 | begin
|
---|
1062 | FCanvasDrawModeFP := AValue;
|
---|
1063 | Case AValue of
|
---|
1064 | dmLinearBlend: FCanvasPixelProcFP := @FastBlendPixel;
|
---|
1065 | dmDrawWithTransparency: FCanvasPixelProcFP := @DrawPixel;
|
---|
1066 | dmXor: FCanvasPixelProcFP:= @XorPixel;
|
---|
1067 | else FCanvasPixelProcFP := @SetPixel;
|
---|
1068 | end;
|
---|
1069 | end;
|
---|
1070 |
|
---|
1071 | function TBGRADefaultBitmap.GetCanvasDrawModeFP: TDrawMode;
|
---|
1072 | begin
|
---|
1073 | Result:= FCanvasDrawModeFP;
|
---|
1074 | end;
|
---|
1075 |
|
---|
1076 | procedure TBGRADefaultBitmap.SetCustomPenStyle(const AValue: TBGRAPenStyle);
|
---|
1077 | begin
|
---|
1078 | FPenStroker.CustomPenStyle := DuplicatePenStyle(AValue);
|
---|
1079 | end;
|
---|
1080 |
|
---|
1081 | procedure TBGRADefaultBitmap.SetPenStyle(const AValue: TPenStyle);
|
---|
1082 | begin
|
---|
1083 | FPenStroker.Style := AValue;
|
---|
1084 | end;
|
---|
1085 |
|
---|
1086 | function TBGRADefaultBitmap.GetPenStyle: TPenStyle;
|
---|
1087 | begin
|
---|
1088 | Result:= FPenStroker.Style;
|
---|
1089 | end;
|
---|
1090 |
|
---|
1091 | function TBGRADefaultBitmap.GetLineCap: TPenEndCap;
|
---|
1092 | begin
|
---|
1093 | result := FPenStroker.LineCap;
|
---|
1094 | end;
|
---|
1095 |
|
---|
1096 | procedure TBGRADefaultBitmap.SetLineCap(AValue: TPenEndCap);
|
---|
1097 | begin
|
---|
1098 | if AValue <> FPenStroker.LineCap then
|
---|
1099 | begin
|
---|
1100 | FPenStroker.LineCap := AValue;
|
---|
1101 | if Assigned(FPenStroker.Arrow) then
|
---|
1102 | FPenStroker.Arrow.LineCap := AValue;
|
---|
1103 | end;
|
---|
1104 | end;
|
---|
1105 |
|
---|
1106 | function TBGRADefaultBitmap.GetPenStroker: TBGRACustomPenStroker;
|
---|
1107 | begin
|
---|
1108 | result := FPenStroker;
|
---|
1109 | end;
|
---|
1110 |
|
---|
1111 | function TBGRADefaultBitmap.GetArrowEndSize: TPointF;
|
---|
1112 | begin
|
---|
1113 | result := GetArrow.EndSize;
|
---|
1114 | end;
|
---|
1115 |
|
---|
1116 | function TBGRADefaultBitmap.GetArrowStartSize: TPointF;
|
---|
1117 | begin
|
---|
1118 | result := GetArrow.StartSize;
|
---|
1119 | end;
|
---|
1120 |
|
---|
1121 | procedure TBGRADefaultBitmap.SetArrowEndSize(AValue: TPointF);
|
---|
1122 | begin
|
---|
1123 | {$PUSH}{$OPTIMIZATION OFF}
|
---|
1124 | GetArrow.EndSize := AValue;
|
---|
1125 | {$POP}
|
---|
1126 | end;
|
---|
1127 |
|
---|
1128 | procedure TBGRADefaultBitmap.SetArrowStartSize(AValue: TPointF);
|
---|
1129 | begin
|
---|
1130 | {$PUSH}{$OPTIMIZATION OFF}
|
---|
1131 | GetArrow.StartSize := AValue;
|
---|
1132 | {$POP}
|
---|
1133 | end;
|
---|
1134 |
|
---|
1135 | function TBGRADefaultBitmap.GetArrowEndOffset: single;
|
---|
1136 | begin
|
---|
1137 | result := GetArrow.EndOffsetX;
|
---|
1138 | end;
|
---|
1139 |
|
---|
1140 | function TBGRADefaultBitmap.GetArrowStartOffset: single;
|
---|
1141 | begin
|
---|
1142 | result := GetArrow.StartOffsetX;
|
---|
1143 | end;
|
---|
1144 |
|
---|
1145 | procedure TBGRADefaultBitmap.SetArrowEndOffset(AValue: single);
|
---|
1146 | begin
|
---|
1147 | GetArrow.EndOffsetX := AValue;
|
---|
1148 | end;
|
---|
1149 |
|
---|
1150 | procedure TBGRADefaultBitmap.SetArrowStartOffset(AValue: single);
|
---|
1151 | begin
|
---|
1152 | GetArrow.StartOffsetX := AValue;
|
---|
1153 | end;
|
---|
1154 |
|
---|
1155 | function TBGRADefaultBitmap.GetArrowEndRepeat: integer;
|
---|
1156 | begin
|
---|
1157 | result := GetArrow.EndRepeatCount;
|
---|
1158 | end;
|
---|
1159 |
|
---|
1160 | function TBGRADefaultBitmap.GetArrowStartRepeat: integer;
|
---|
1161 | begin
|
---|
1162 | result := GetArrow.StartRepeatCount;
|
---|
1163 | end;
|
---|
1164 |
|
---|
1165 | procedure TBGRADefaultBitmap.SetArrowEndRepeat(AValue: integer);
|
---|
1166 | begin
|
---|
1167 | GetArrow.EndRepeatCount := AValue;
|
---|
1168 | end;
|
---|
1169 |
|
---|
1170 | procedure TBGRADefaultBitmap.SetArrowStartRepeat(AValue: integer);
|
---|
1171 | begin
|
---|
1172 | GetArrow.StartRepeatCount := AValue;
|
---|
1173 | end;
|
---|
1174 |
|
---|
1175 | procedure TBGRADefaultBitmap.SetFontHeight(AHeight: integer);
|
---|
1176 | begin
|
---|
1177 | FFontHeight := AHeight;
|
---|
1178 | end;
|
---|
1179 |
|
---|
1180 | function TBGRADefaultBitmap.GetFontFullHeight: integer;
|
---|
1181 | begin
|
---|
1182 | if FontHeight < 0 then
|
---|
1183 | result := -FontHeight
|
---|
1184 | else
|
---|
1185 | result := TextSize('Hg').cy;
|
---|
1186 | end;
|
---|
1187 |
|
---|
1188 | procedure TBGRADefaultBitmap.SetFontFullHeight(AHeight: integer);
|
---|
1189 | begin
|
---|
1190 | if AHeight > 0 then
|
---|
1191 | FontHeight := -AHeight
|
---|
1192 | else
|
---|
1193 | FontHeight := 1;
|
---|
1194 | end;
|
---|
1195 |
|
---|
1196 | function TBGRADefaultBitmap.GetFontPixelMetric: TFontPixelMetric;
|
---|
1197 | begin
|
---|
1198 | result := FontRenderer.GetFontPixelMetric;
|
---|
1199 | end;
|
---|
1200 |
|
---|
1201 | function TBGRADefaultBitmap.GetFontRenderer: TBGRACustomFontRenderer;
|
---|
1202 | begin
|
---|
1203 | if FFontRenderer = nil then FFontRenderer := CreateDefaultFontRenderer;
|
---|
1204 | if FFontRenderer = nil then raise exception.Create('No font renderer');
|
---|
1205 | result := FFontRenderer;
|
---|
1206 | result.FontName := FontName;
|
---|
1207 | result.FontStyle := FontStyle;
|
---|
1208 | result.FontQuality := FontQuality;
|
---|
1209 | result.FontOrientation := FontOrientation;
|
---|
1210 | result.FontEmHeight := FFontHeight;
|
---|
1211 | end;
|
---|
1212 |
|
---|
1213 | procedure TBGRADefaultBitmap.SetFontRenderer(AValue: TBGRACustomFontRenderer);
|
---|
1214 | begin
|
---|
1215 | if AValue = FFontRenderer then exit;
|
---|
1216 | FFontRenderer.Free;
|
---|
1217 | FFontRenderer := AValue
|
---|
1218 | end;
|
---|
1219 |
|
---|
1220 | function TBGRADefaultBitmap.GetFontVerticalAnchorOffset: single;
|
---|
1221 | begin
|
---|
1222 | case FontVerticalAnchor of
|
---|
1223 | fvaTop: result := 0;
|
---|
1224 | fvaCenter: result := FontFullHeight*0.5;
|
---|
1225 | fvaCapLine: result := FontPixelMetric.CapLine;
|
---|
1226 | fvaCapCenter: result := (FontPixelMetric.CapLine+FontPixelMetric.Baseline)*0.5;
|
---|
1227 | fvaXLine: result := FontPixelMetric.xLine;
|
---|
1228 | fvaXCenter: result := (FontPixelMetric.xLine+FontPixelMetric.Baseline)*0.5;
|
---|
1229 | fvaBaseline: result := FontPixelMetric.Baseline;
|
---|
1230 | fvaDescentLine: result := FontPixelMetric.DescentLine;
|
---|
1231 | fvaBottom: result := FontFullHeight;
|
---|
1232 | else
|
---|
1233 | result := 0;
|
---|
1234 | end;
|
---|
1235 | end;
|
---|
1236 |
|
---|
1237 | function TBGRADefaultBitmap.GetFontAnchorRotatedOffset: TPointF;
|
---|
1238 | begin
|
---|
1239 | result := GetFontAnchorRotatedOffset(FontOrientation);
|
---|
1240 | end;
|
---|
1241 |
|
---|
1242 | function TBGRADefaultBitmap.GetFontAnchorRotatedOffset(
|
---|
1243 | ACustomOrientation: integer): TPointF;
|
---|
1244 | begin
|
---|
1245 | result := PointF(0, GetFontVerticalAnchorOffset);
|
---|
1246 | if ACustomOrientation <> 0 then
|
---|
1247 | result := AffineMatrixRotationDeg(-ACustomOrientation*0.1)*result;
|
---|
1248 | end;
|
---|
1249 |
|
---|
1250 | { Get scanline without checking bounds nor updated from TBitmap }
|
---|
1251 | function TBGRADefaultBitmap.GetScanlineFast(y: integer): PBGRAPixel; inline;
|
---|
1252 | begin
|
---|
1253 | Result := FData;
|
---|
1254 | if FLineOrder = riloBottomToTop then
|
---|
1255 | y := FHeight - 1 - y;
|
---|
1256 | Inc(Result, FWidth * y);
|
---|
1257 | end;
|
---|
1258 |
|
---|
1259 | function TBGRADefaultBitmap.GetScanLine(y: integer): PBGRAPixel;
|
---|
1260 | begin
|
---|
1261 | if (y < 0) or (y >= Height) then
|
---|
1262 | raise ERangeError.Create('Scanline: out of bounds')
|
---|
1263 | else
|
---|
1264 | begin
|
---|
1265 | LoadFromBitmapIfNeeded;
|
---|
1266 | Result := GetScanLineFast(y);
|
---|
1267 | end;
|
---|
1268 | end;
|
---|
1269 |
|
---|
1270 | {------------------------- Reference counter functions ------------------------}
|
---|
1271 | { These functions are not related to reference counting for interfaces :
|
---|
1272 | a reference must be explicitely freed with FreeReference }
|
---|
1273 |
|
---|
1274 | { Add a new reference and gives a pointer to it }
|
---|
1275 | function TBGRADefaultBitmap.NewReference: TBGRACustomBitmap;
|
---|
1276 | begin
|
---|
1277 | if self <> nil then Inc(FRefCount);
|
---|
1278 | Result := self;
|
---|
1279 | end;
|
---|
1280 |
|
---|
1281 | { Free the current reference, and free the bitmap if necessary }
|
---|
1282 | procedure TBGRADefaultBitmap.FreeReference;
|
---|
1283 | begin
|
---|
1284 | if self = nil then
|
---|
1285 | exit;
|
---|
1286 |
|
---|
1287 | if FRefCount > 0 then
|
---|
1288 | begin
|
---|
1289 | Dec(FRefCount);
|
---|
1290 | if FRefCount = 0 then
|
---|
1291 | begin
|
---|
1292 | self.Destroy;
|
---|
1293 | end;
|
---|
1294 | end;
|
---|
1295 | end;
|
---|
1296 |
|
---|
1297 | { Make sure there is only one copy of the bitmap and return
|
---|
1298 | the new pointer for it. If the bitmap is already unique,
|
---|
1299 | then it does nothing }
|
---|
1300 | function TBGRADefaultBitmap.GetUnique: TBGRACustomBitmap;
|
---|
1301 | begin
|
---|
1302 | if FRefCount > 1 then
|
---|
1303 | begin
|
---|
1304 | Dec(FRefCount);
|
---|
1305 | Result := self.Duplicate;
|
---|
1306 | end
|
---|
1307 | else
|
---|
1308 | Result := self;
|
---|
1309 | end;
|
---|
1310 |
|
---|
1311 | procedure TBGRADefaultBitmap.NeedXorMask;
|
---|
1312 | begin
|
---|
1313 | if FXorMask = nil then
|
---|
1314 | FXorMask := BGRABitmapFactory.Create(Width,Height);
|
---|
1315 | end;
|
---|
1316 |
|
---|
1317 | procedure TBGRADefaultBitmap.DiscardXorMask;
|
---|
1318 | begin
|
---|
1319 | if Assigned(FXorMask) then
|
---|
1320 | begin
|
---|
1321 | if FXorMask is TBGRADefaultBitmap then
|
---|
1322 | begin
|
---|
1323 | TBGRADefaultBitmap(FXorMask).FreeReference;
|
---|
1324 | FXorMask := nil;
|
---|
1325 | end else
|
---|
1326 | FreeAndNil(FXorMask);
|
---|
1327 | end;
|
---|
1328 | end;
|
---|
1329 |
|
---|
1330 | { Creates a new bitmap with dimensions AWidth and AHeight and filled with
|
---|
1331 | transparent pixels. Internally, it uses the same type so that if you
|
---|
1332 | use an optimized version, you get a new bitmap with the same optimizations }
|
---|
1333 | function TBGRADefaultBitmap.NewBitmap(AWidth, AHeight: integer): TBGRACustomBitmap;
|
---|
1334 | var
|
---|
1335 | BGRAClass: TBGRABitmapAny;
|
---|
1336 | begin
|
---|
1337 | BGRAClass := TBGRABitmapAny(self.ClassType);
|
---|
1338 | if BGRAClass = TBGRAPtrBitmap then
|
---|
1339 | BGRAClass := TBGRADefaultBitmap;
|
---|
1340 | Result := BGRAClass.Create(AWidth, AHeight);
|
---|
1341 | end;
|
---|
1342 |
|
---|
1343 | { Can only be called from an existing instance of TBGRABitmap.
|
---|
1344 | Creates a new instance with dimensions AWidth and AHeight,
|
---|
1345 | and fills it with Color. }
|
---|
1346 | function TBGRADefaultBitmap.NewBitmap(AWidth, AHeight: integer;
|
---|
1347 | Color: TBGRAPixel): TBGRACustomBitmap;
|
---|
1348 | var
|
---|
1349 | BGRAClass: TBGRABitmapAny;
|
---|
1350 | begin
|
---|
1351 | BGRAClass := TBGRABitmapAny(self.ClassType);
|
---|
1352 | if BGRAClass = TBGRAPtrBitmap then
|
---|
1353 | BGRAClass := TBGRADefaultBitmap;
|
---|
1354 | Result := BGRAClass.Create(AWidth, AHeight, Color);
|
---|
1355 | end;
|
---|
1356 |
|
---|
1357 | { Creates a new bitmap and loads it contents from a file.
|
---|
1358 | The encoding of the string is the default one for the operating system.
|
---|
1359 | It is recommended to use the next function and UTF8 encoding }
|
---|
1360 | function TBGRADefaultBitmap.NewBitmap(Filename: string): TBGRACustomBitmap;
|
---|
1361 | var
|
---|
1362 | BGRAClass: TBGRABitmapAny;
|
---|
1363 | begin
|
---|
1364 | BGRAClass := TBGRABitmapAny(self.ClassType);
|
---|
1365 | Result := BGRAClass.Create(Filename);
|
---|
1366 | end;
|
---|
1367 |
|
---|
1368 | { Creates a new bitmap and loads it contents from a file.
|
---|
1369 | It is recommended to use UTF8 encoding }
|
---|
1370 | function TBGRADefaultBitmap.NewBitmap(Filename: string; AIsUtf8: boolean): TBGRACustomBitmap;
|
---|
1371 | var
|
---|
1372 | BGRAClass: TBGRABitmapAny;
|
---|
1373 | begin
|
---|
1374 | BGRAClass := TBGRABitmapAny(self.ClassType);
|
---|
1375 | Result := BGRAClass.Create(Filename,AIsUtf8);
|
---|
1376 | end;
|
---|
1377 |
|
---|
1378 | function TBGRADefaultBitmap.NewBitmap(Filename: string; AIsUtf8: boolean;
|
---|
1379 | AOptions: TBGRALoadingOptions): TBGRACustomBitmap;
|
---|
1380 | var
|
---|
1381 | BGRAClass: TBGRABitmapAny;
|
---|
1382 | begin
|
---|
1383 | BGRAClass := TBGRABitmapAny(self.ClassType);
|
---|
1384 | Result := BGRAClass.Create(Filename,AIsUtf8,AOptions);
|
---|
1385 | end;
|
---|
1386 |
|
---|
1387 | function TBGRADefaultBitmap.NewBitmap(AFPImage: TFPCustomImage): TBGRACustomBitmap;
|
---|
1388 | var
|
---|
1389 | BGRAClass: TBGRABitmapAny;
|
---|
1390 | begin
|
---|
1391 | BGRAClass := TBGRABitmapAny(self.ClassType);
|
---|
1392 | Result := BGRAClass.Create(AFPImage);
|
---|
1393 | end;
|
---|
1394 |
|
---|
1395 | procedure TBGRADefaultBitmap.LoadFromStream(Str: TStream;
|
---|
1396 | Handler: TFPCustomImageReader; AOptions: TBGRALoadingOptions);
|
---|
1397 | var OldBmpOption: TBMPTransparencyOption;
|
---|
1398 | OldJpegPerf: TJPEGReadPerformance;
|
---|
1399 | begin
|
---|
1400 | DiscardXorMask;
|
---|
1401 | if (loBmpAutoOpaque in AOptions) and (Handler is TBGRAReaderBMP) then
|
---|
1402 | begin
|
---|
1403 | OldBmpOption := TBGRAReaderBMP(Handler).TransparencyOption;
|
---|
1404 | TBGRAReaderBMP(Handler).TransparencyOption := toAuto;
|
---|
1405 | inherited LoadFromStream(Str, Handler, AOptions);
|
---|
1406 | TBGRAReaderBMP(Handler).TransparencyOption := OldBmpOption;
|
---|
1407 | end else
|
---|
1408 | if (loJpegQuick in AOptions) and (Handler is TBGRAReaderJpeg) then
|
---|
1409 | begin
|
---|
1410 | OldJpegPerf := TBGRAReaderJpeg(Handler).Performance;
|
---|
1411 | TBGRAReaderJpeg(Handler).Performance := jpBestSpeed;
|
---|
1412 | inherited LoadFromStream(Str, Handler, AOptions);
|
---|
1413 | TBGRAReaderJpeg(Handler).Performance := OldJpegPerf;
|
---|
1414 | end else
|
---|
1415 | inherited LoadFromStream(Str, Handler, AOptions);
|
---|
1416 | end;
|
---|
1417 |
|
---|
1418 | procedure TBGRADefaultBitmap.LoadFromResource(AFilename: string;
|
---|
1419 | AOptions: TBGRALoadingOptions);
|
---|
1420 | var
|
---|
1421 | stream: TStream;
|
---|
1422 | format: TBGRAImageFormat;
|
---|
1423 | reader: TFPCustomImageReader;
|
---|
1424 | magic: array[1..2] of char;
|
---|
1425 | startPos: Int64;
|
---|
1426 | ext: String;
|
---|
1427 | begin
|
---|
1428 | stream := BGRAResource.GetResourceStream(AFilename);
|
---|
1429 | try
|
---|
1430 | ext := Uppercase(ExtractFileExt(AFilename));
|
---|
1431 | if (ext = '.BMP') and BGRAResource.IsWinResource(AFilename) then
|
---|
1432 | begin
|
---|
1433 | reader := TBGRAReaderBMP.Create;
|
---|
1434 | TBGRAReaderBMP(reader).Subformat := bsfHeaderless;
|
---|
1435 | end else
|
---|
1436 | begin
|
---|
1437 | format := DetectFileFormat(stream, ext);
|
---|
1438 | reader := CreateBGRAImageReader(format);
|
---|
1439 | end;
|
---|
1440 | try
|
---|
1441 | LoadFromStream(stream, reader, AOptions);
|
---|
1442 | finally
|
---|
1443 | reader.Free;
|
---|
1444 | end;
|
---|
1445 | finally
|
---|
1446 | stream.Free;
|
---|
1447 | end;
|
---|
1448 | end;
|
---|
1449 |
|
---|
1450 | {----------------------- TFPCustomImage override ------------------------------}
|
---|
1451 |
|
---|
1452 | { Creates a new bitmap, initialize properties and bitmap data }
|
---|
1453 | constructor TBGRADefaultBitmap.Create(AWidth, AHeight: integer);
|
---|
1454 | begin
|
---|
1455 | Init;
|
---|
1456 | inherited Create(AWidth, AHeight);
|
---|
1457 | if FData <> nil then
|
---|
1458 | FillTransparent;
|
---|
1459 | end;
|
---|
1460 |
|
---|
1461 | { Set the size of the current bitmap. All data is lost during the process }
|
---|
1462 | procedure TBGRADefaultBitmap.SetSize(AWidth, AHeight: integer);
|
---|
1463 | begin
|
---|
1464 | if (AWidth = Width) and (AHeight = Height) then
|
---|
1465 | exit;
|
---|
1466 | inherited SetSize(AWidth, AHeight);
|
---|
1467 | if AWidth < 0 then
|
---|
1468 | AWidth := 0;
|
---|
1469 | if AHeight < 0 then
|
---|
1470 | AHeight := 0;
|
---|
1471 | FWidth := AWidth;
|
---|
1472 | FHeight := AHeight;
|
---|
1473 | FScanWidth := FWidth;
|
---|
1474 | FScanHeight:= FHeight;
|
---|
1475 | FNbPixels := AWidth * AHeight;
|
---|
1476 | if FNbPixels < 0 then // 2 Go limit
|
---|
1477 | raise EOutOfMemory.Create('Image too big');
|
---|
1478 | FreeBitmap;
|
---|
1479 | ReallocData;
|
---|
1480 | NoClip;
|
---|
1481 | DiscardXorMask;
|
---|
1482 | end;
|
---|
1483 |
|
---|
1484 | {---------------------- Constructors ---------------------------------}
|
---|
1485 |
|
---|
1486 | { Creates an image of width and height equal to zero. }
|
---|
1487 | constructor TBGRADefaultBitmap.Create;
|
---|
1488 | begin
|
---|
1489 | Init;
|
---|
1490 | inherited Create(0, 0);
|
---|
1491 | end;
|
---|
1492 |
|
---|
1493 | constructor TBGRADefaultBitmap.Create(AFPImage: TFPCustomImage);
|
---|
1494 | begin
|
---|
1495 | Init;
|
---|
1496 | inherited Create(AFPImage.Width, AFPImage.Height);
|
---|
1497 | Assign(AFPImage);
|
---|
1498 | end;
|
---|
1499 |
|
---|
1500 | { Creates an image of dimensions AWidth and AHeight and filled with transparent pixels. }
|
---|
1501 | constructor TBGRADefaultBitmap.Create(ABitmap: TBitmap; AUseTransparent: boolean);
|
---|
1502 | begin
|
---|
1503 | Init;
|
---|
1504 | inherited Create(ABitmap.Width, ABitmap.Height);
|
---|
1505 | Assign(ABitmap, AUseTransparent);
|
---|
1506 | end;
|
---|
1507 |
|
---|
1508 | { Creates an image of dimensions AWidth and AHeight and fills it with the opaque color Color. }
|
---|
1509 | constructor TBGRADefaultBitmap.Create(AWidth, AHeight: integer; Color: TColor);
|
---|
1510 | begin
|
---|
1511 | Init;
|
---|
1512 | inherited Create(AWidth, AHeight);
|
---|
1513 | Fill(Color);
|
---|
1514 | end;
|
---|
1515 |
|
---|
1516 | { Creates an image of dimensions AWidth and AHeight and fills it with Color. }
|
---|
1517 | constructor TBGRADefaultBitmap.Create(AWidth, AHeight: integer; Color: TBGRAPixel);
|
---|
1518 | begin
|
---|
1519 | Init;
|
---|
1520 | inherited Create(AWidth, AHeight);
|
---|
1521 | Fill(Color);
|
---|
1522 | end;
|
---|
1523 |
|
---|
1524 | { Creates an image by loading its content from the file AFilename.
|
---|
1525 | The encoding of the string is the default one for the operating system.
|
---|
1526 | It is recommended to use the next constructor and UTF8 encoding. }
|
---|
1527 | constructor TBGRADefaultBitmap.Create(AFilename: string);
|
---|
1528 | begin
|
---|
1529 | Init;
|
---|
1530 | inherited Create(0, 0);
|
---|
1531 | LoadFromFile(Afilename);
|
---|
1532 | end;
|
---|
1533 |
|
---|
1534 | { Free the object and all its resources }
|
---|
1535 | destructor TBGRADefaultBitmap.Destroy;
|
---|
1536 | begin
|
---|
1537 | DiscardXorMask;
|
---|
1538 | FPenStroker.Free;
|
---|
1539 | FFontRenderer.Free;
|
---|
1540 | FCanvasFP.Free;
|
---|
1541 | FCanvasBGRA.Free;
|
---|
1542 | FCanvas2D.Free;
|
---|
1543 | FreeData;
|
---|
1544 | FreeBitmap;
|
---|
1545 | inherited Destroy;
|
---|
1546 | end;
|
---|
1547 |
|
---|
1548 | {------------------------- Loading functions ----------------------------------}
|
---|
1549 |
|
---|
1550 | { Creates an image by loading its content from the file AFilename.
|
---|
1551 | The boolean AIsUtf8Filename specifies if UTF8 encoding is assumed for the filename. }
|
---|
1552 | constructor TBGRADefaultBitmap.Create(AFilename: string; AIsUtf8: boolean);
|
---|
1553 | begin
|
---|
1554 | Init;
|
---|
1555 | inherited Create(0, 0);
|
---|
1556 | if AIsUtf8 then
|
---|
1557 | LoadFromFileUTF8(Afilename)
|
---|
1558 | else
|
---|
1559 | LoadFromFile(Afilename);
|
---|
1560 | end;
|
---|
1561 |
|
---|
1562 | constructor TBGRADefaultBitmap.Create(AFilename: string; AIsUtf8: boolean;
|
---|
1563 | AOptions: TBGRALoadingOptions);
|
---|
1564 | begin
|
---|
1565 | Init;
|
---|
1566 | inherited Create(0, 0);
|
---|
1567 | if AIsUtf8 then
|
---|
1568 | LoadFromFileUTF8(Afilename, AOptions)
|
---|
1569 | else
|
---|
1570 | LoadFromFile(Afilename, AOptions);
|
---|
1571 | end;
|
---|
1572 |
|
---|
1573 | { Creates an image by loading its content from the stream AStream. }
|
---|
1574 | constructor TBGRADefaultBitmap.Create(AStream: TStream);
|
---|
1575 | begin
|
---|
1576 | Init;
|
---|
1577 | inherited Create(0, 0);
|
---|
1578 | LoadFromStream(AStream);
|
---|
1579 | end;
|
---|
1580 |
|
---|
1581 | procedure TBGRADefaultBitmap.Serialize(AStream: TStream);
|
---|
1582 | var lWidth,lHeight,y: integer;
|
---|
1583 | begin
|
---|
1584 | lWidth := NtoLE(Width);
|
---|
1585 | lHeight := NtoLE(Height);
|
---|
1586 | AStream.Write(lWidth,sizeof(lWidth));
|
---|
1587 | AStream.Write(lHeight,sizeof(lHeight));
|
---|
1588 | If TBGRAPixel_RGBAOrder then TBGRAFilterScannerSwapRedBlue.ComputeFilterAt(FData,FData,FNbPixels,False);
|
---|
1589 | for y := 0 to Height-1 do
|
---|
1590 | AStream.Write(ScanLine[y]^, Width*sizeof(TBGRAPixel));
|
---|
1591 | If TBGRAPixel_RGBAOrder then TBGRAFilterScannerSwapRedBlue.ComputeFilterAt(FData,FData,FNbPixels,False);
|
---|
1592 | end;
|
---|
1593 |
|
---|
1594 | procedure TBGRADefaultBitmap.Deserialize(AStream: TStream);
|
---|
1595 | var lWidth,lHeight,y: integer;
|
---|
1596 | begin
|
---|
1597 | AStream.Read({%H-}lWidth,sizeof(lWidth));
|
---|
1598 | AStream.Read({%H-}lHeight,sizeof(lHeight));
|
---|
1599 | lWidth := LEtoN(lWidth);
|
---|
1600 | lHeight := LEtoN(lHeight);
|
---|
1601 | SetSize(lWidth,lHeight);
|
---|
1602 | for y := 0 to Height-1 do
|
---|
1603 | AStream.Read(ScanLine[y]^, Width*sizeof(TBGRAPixel));
|
---|
1604 | If TBGRAPixel_RGBAOrder then TBGRAFilterScannerSwapRedBlue.ComputeFilterAt(FData,FData,FNbPixels,False);
|
---|
1605 | InvalidateBitmap;
|
---|
1606 | end;
|
---|
1607 |
|
---|
1608 | class procedure TBGRADefaultBitmap.SerializeEmpty(AStream: TStream);
|
---|
1609 | var zero: integer;
|
---|
1610 | begin
|
---|
1611 | zero := 0;
|
---|
1612 | AStream.Write(zero,sizeof(zero));
|
---|
1613 | AStream.Write(zero,sizeof(zero));
|
---|
1614 | end;
|
---|
1615 |
|
---|
1616 | procedure TBGRADefaultBitmap.Assign(Source: TPersistent);
|
---|
1617 | var pdest: PBGRAPixel;
|
---|
1618 | x,y: NativeInt;
|
---|
1619 | begin
|
---|
1620 | if Source is TBGRACustomBitmap then
|
---|
1621 | begin
|
---|
1622 | DiscardBitmapChange;
|
---|
1623 | SetSize(TBGRACustomBitmap(Source).Width, TBGRACustomBitmap(Source).Height);
|
---|
1624 | PutImage(0, 0, TBGRACustomBitmap(Source), dmSet);
|
---|
1625 | if Source is TBGRADefaultBitmap then
|
---|
1626 | begin
|
---|
1627 | HotSpot := TBGRADefaultBitmap(Source).HotSpot;
|
---|
1628 | if XorMask <> TBGRADefaultBitmap(Source).XorMask then
|
---|
1629 | begin
|
---|
1630 | DiscardXorMask;
|
---|
1631 | if TBGRADefaultBitmap(Source).XorMask is TBGRADefaultBitmap then
|
---|
1632 | FXorMask := TBGRADefaultBitmap(TBGRADefaultBitmap(Source).XorMask).NewReference as TBGRADefaultBitmap
|
---|
1633 | else
|
---|
1634 | FXorMask := TBGRADefaultBitmap(Source).XorMask.Duplicate;
|
---|
1635 | end;
|
---|
1636 | end;
|
---|
1637 | end else
|
---|
1638 | if Source is TFPCustomImage then
|
---|
1639 | begin
|
---|
1640 | DiscardBitmapChange;
|
---|
1641 | SetSize(TFPCustomImage(Source).Width, TFPCustomImage(Source).Height);
|
---|
1642 | for y := 0 to TFPCustomImage(Source).Height-1 do
|
---|
1643 | begin
|
---|
1644 | pdest := ScanLine[y];
|
---|
1645 | for x := 0 to TFPCustomImage(Source).Width-1 do
|
---|
1646 | begin
|
---|
1647 | pdest^ := FPColorToBGRA(TFPCustomImage(Source).Colors[x,y]);
|
---|
1648 | inc(pdest);
|
---|
1649 | end;
|
---|
1650 | end;
|
---|
1651 | end else
|
---|
1652 | inherited Assign(Source);
|
---|
1653 | end;
|
---|
1654 |
|
---|
1655 | procedure TBGRADefaultBitmap.Assign(Source: TBitmap; AUseTransparent: boolean);
|
---|
1656 | var
|
---|
1657 | transpColor: TBGRAPixel;
|
---|
1658 | begin
|
---|
1659 | Assign(Source);
|
---|
1660 | if AUseTransparent and TBitmap(Source).Transparent then
|
---|
1661 | begin
|
---|
1662 | if TBitmap(Source).TransparentMode = tmFixed then
|
---|
1663 | transpColor := ColorToBGRA(TBitmap(Source).TransparentColor)
|
---|
1664 | else
|
---|
1665 | transpColor := GetPixel(0,Height-1);
|
---|
1666 | ReplaceColor(transpColor, BGRAPixelTransparent);
|
---|
1667 | end;
|
---|
1668 | end;
|
---|
1669 |
|
---|
1670 | {------------------------- Clipping -------------------------------}
|
---|
1671 |
|
---|
1672 | { Check if a point is in the clipping rectangle }
|
---|
1673 | function TBGRADefaultBitmap.PtInClipRect(x, y: int32or64): boolean;
|
---|
1674 | begin
|
---|
1675 | result := (x >= FClipRect.Left) and (y >= FClipRect.Top) and (x < FClipRect.Right) and (y < FClipRect.Bottom);
|
---|
1676 | end;
|
---|
1677 |
|
---|
1678 | procedure TBGRADefaultBitmap.NoClip;
|
---|
1679 | begin
|
---|
1680 | FClipRect := rect(0,0,FWidth,FHeight);
|
---|
1681 | end;
|
---|
1682 |
|
---|
1683 | procedure TBGRADefaultBitmap.Fill(texture: IBGRAScanner; mode: TDrawMode);
|
---|
1684 | begin
|
---|
1685 | FillRect(FClipRect.Left,FClipRect.Top,FClipRect.Right,FClipRect.Bottom,texture,mode);
|
---|
1686 | end;
|
---|
1687 |
|
---|
1688 | function TBGRADefaultBitmap.GetClipRect: TRect;
|
---|
1689 | begin
|
---|
1690 | Result:= FClipRect;
|
---|
1691 | end;
|
---|
1692 |
|
---|
1693 | procedure TBGRADefaultBitmap.SetClipRect(const AValue: TRect);
|
---|
1694 | begin
|
---|
1695 | IntersectRect(FClipRect,AValue,Rect(0,0,FWidth,FHeight));
|
---|
1696 | end;
|
---|
1697 |
|
---|
1698 | function TBGRADefaultBitmap.InternalGetPixelCycle256(ix, iy: int32or64; iFactX,
|
---|
1699 | iFactY: int32or64): TBGRAPixel;
|
---|
1700 | var
|
---|
1701 | ixMod2: int32or64;
|
---|
1702 | pUpLeft, pUpRight, pDownLeft, pDownRight: PBGRAPixel;
|
---|
1703 | scan: PBGRAPixel;
|
---|
1704 | begin
|
---|
1705 | scan := GetScanlineFast(iy);
|
---|
1706 |
|
---|
1707 | pUpLeft := (scan + ix);
|
---|
1708 | ixMod2 := ix+1;
|
---|
1709 | if ixMod2=Width then ixMod2 := 0;
|
---|
1710 | pUpRight := (scan + ixMod2);
|
---|
1711 |
|
---|
1712 | Inc(iy);
|
---|
1713 | if iy = Height then iy := 0;
|
---|
1714 | scan := GetScanlineFast(iy);
|
---|
1715 | pDownLeft := (scan + ix);
|
---|
1716 | pDownRight := (scan + ixMod2);
|
---|
1717 |
|
---|
1718 | InterpolateBilinear(pUpLeft, pUpRight, pDownLeft,
|
---|
1719 | pDownRight, iFactX, iFactY, @result);
|
---|
1720 | end;
|
---|
1721 |
|
---|
1722 | function TBGRADefaultBitmap.InternalGetPixel256(ix, iy: int32or64; iFactX,
|
---|
1723 | iFactY: int32or64; smoothBorder: boolean): TBGRAPixel;
|
---|
1724 | var
|
---|
1725 | pUpLeft, pUpRight, pDownLeft, pDownRight: PBGRAPixel;
|
---|
1726 | scan: PBGRAPixel;
|
---|
1727 | begin
|
---|
1728 | if (iy >= 0) and (iy < Height) then
|
---|
1729 | begin
|
---|
1730 | scan := GetScanlineFast(iy);
|
---|
1731 |
|
---|
1732 | if (ix >= 0) and (ix < Width) then
|
---|
1733 | pUpLeft := scan+ix
|
---|
1734 | else if smoothBorder then
|
---|
1735 | pUpLeft := @BGRAPixelTransparent
|
---|
1736 | else
|
---|
1737 | pUpLeft := nil;
|
---|
1738 |
|
---|
1739 | if (ix+1 >= 0) and (ix+1 < Width) then
|
---|
1740 | pUpRight := scan+(ix+1)
|
---|
1741 | else if smoothBorder then
|
---|
1742 | pUpRight := @BGRAPixelTransparent
|
---|
1743 | else
|
---|
1744 | pUpRight := nil;
|
---|
1745 | end else
|
---|
1746 | if smoothBorder then
|
---|
1747 | begin
|
---|
1748 | pUpLeft := @BGRAPixelTransparent;
|
---|
1749 | pUpRight := @BGRAPixelTransparent;
|
---|
1750 | end else
|
---|
1751 | begin
|
---|
1752 | pUpLeft := nil;
|
---|
1753 | pUpRight := nil;
|
---|
1754 | end;
|
---|
1755 |
|
---|
1756 | if (iy+1 >= 0) and (iy+1 < Height) then
|
---|
1757 | begin
|
---|
1758 | scan := GetScanlineFast(iy+1);
|
---|
1759 |
|
---|
1760 | if (ix >= 0) and (ix < Width) then
|
---|
1761 | pDownLeft := scan+ix
|
---|
1762 | else if smoothBorder then
|
---|
1763 | pDownLeft := @BGRAPixelTransparent
|
---|
1764 | else
|
---|
1765 | pDownLeft := nil;
|
---|
1766 |
|
---|
1767 | if (ix+1 >= 0) and (ix+1 < Width) then
|
---|
1768 | pDownRight := scan+(ix+1)
|
---|
1769 | else if smoothBorder then
|
---|
1770 | pDownRight := @BGRAPixelTransparent
|
---|
1771 | else
|
---|
1772 | pDownRight := nil;
|
---|
1773 | end else
|
---|
1774 | if smoothBorder then
|
---|
1775 | begin
|
---|
1776 | pDownLeft := @BGRAPixelTransparent;
|
---|
1777 | pDownRight := @BGRAPixelTransparent;
|
---|
1778 | end else
|
---|
1779 | begin
|
---|
1780 | pDownLeft := nil;
|
---|
1781 | pDownRight := nil;
|
---|
1782 | end;
|
---|
1783 |
|
---|
1784 | InterpolateBilinear(pUpLeft, pUpRight, pDownLeft,
|
---|
1785 | pDownRight, iFactX, iFactY, @result);
|
---|
1786 | end;
|
---|
1787 |
|
---|
1788 | function TBGRADefaultBitmap.GetArrow: TBGRAArrow;
|
---|
1789 | begin
|
---|
1790 | if FPenStroker.Arrow = nil then
|
---|
1791 | begin
|
---|
1792 | FPenStroker.Arrow := TBGRAArrow.Create;
|
---|
1793 | FPenStroker.Arrow.LineCap := LineCap;
|
---|
1794 | FPenStroker.ArrowOwned := true;
|
---|
1795 | end;
|
---|
1796 | result := FPenStroker.Arrow as TBGRAArrow;
|
---|
1797 | end;
|
---|
1798 |
|
---|
1799 | {-------------------------- Pixel functions -----------------------------------}
|
---|
1800 |
|
---|
1801 | procedure TBGRADefaultBitmap.SetPixel(x, y: int32or64; c: TBGRAPixel);
|
---|
1802 | begin
|
---|
1803 | if not PtInClipRect(x,y) then exit;
|
---|
1804 | LoadFromBitmapIfNeeded;
|
---|
1805 | (GetScanlineFast(y) +x)^ := c;
|
---|
1806 | InvalidateBitmap;
|
---|
1807 | end;
|
---|
1808 |
|
---|
1809 | procedure TBGRADefaultBitmap.XorPixel(x, y: int32or64; c: TBGRAPixel);
|
---|
1810 | var
|
---|
1811 | p : PDWord;
|
---|
1812 | begin
|
---|
1813 | if not PtInClipRect(x,y) then exit;
|
---|
1814 | LoadFromBitmapIfNeeded;
|
---|
1815 | p := PDWord(GetScanlineFast(y) +x);
|
---|
1816 | p^ := p^ xor DWord(c);
|
---|
1817 | InvalidateBitmap;
|
---|
1818 | end;
|
---|
1819 |
|
---|
1820 | procedure TBGRADefaultBitmap.SetPixel(x, y: int32or64; c: TColor);
|
---|
1821 | var
|
---|
1822 | p: PBGRAPixel;
|
---|
1823 | begin
|
---|
1824 | if not PtInClipRect(x,y) then exit;
|
---|
1825 | LoadFromBitmapIfNeeded;
|
---|
1826 | p := GetScanlineFast(y) + x;
|
---|
1827 | RedGreenBlue(c, p^.red,p^.green,p^.blue);
|
---|
1828 | p^.alpha := 255;
|
---|
1829 | InvalidateBitmap;
|
---|
1830 | end;
|
---|
1831 |
|
---|
1832 | procedure TBGRADefaultBitmap.DrawPixel(x, y: int32or64; c: TBGRAPixel);
|
---|
1833 | begin
|
---|
1834 | if not PtInClipRect(x,y) then exit;
|
---|
1835 | LoadFromBitmapIfNeeded;
|
---|
1836 | DrawPixelInlineWithAlphaCheck(GetScanlineFast(y) + x, c);
|
---|
1837 | InvalidateBitmap;
|
---|
1838 | end;
|
---|
1839 |
|
---|
1840 | procedure TBGRADefaultBitmap.DrawPixel(x, y: int32or64; ec: TExpandedPixel);
|
---|
1841 | begin
|
---|
1842 | if not PtInClipRect(x,y) then exit;
|
---|
1843 | LoadFromBitmapIfNeeded;
|
---|
1844 | DrawExpandedPixelInlineWithAlphaCheck(GetScanlineFast(y) + x, ec);
|
---|
1845 | InvalidateBitmap;
|
---|
1846 | end;
|
---|
1847 |
|
---|
1848 | procedure TBGRADefaultBitmap.FastBlendPixel(x, y: int32or64; c: TBGRAPixel);
|
---|
1849 | begin
|
---|
1850 | if not PtInClipRect(x,y) then exit;
|
---|
1851 | LoadFromBitmapIfNeeded;
|
---|
1852 | FastBlendPixelInline(GetScanlineFast(y) + x, c);
|
---|
1853 | InvalidateBitmap;
|
---|
1854 | end;
|
---|
1855 |
|
---|
1856 | procedure TBGRADefaultBitmap.ErasePixel(x, y: int32or64; alpha: byte);
|
---|
1857 | begin
|
---|
1858 | if not PtInClipRect(x,y) then exit;
|
---|
1859 | LoadFromBitmapIfNeeded;
|
---|
1860 | ErasePixelInline(GetScanlineFast(y) + x, alpha);
|
---|
1861 | InvalidateBitmap;
|
---|
1862 | end;
|
---|
1863 |
|
---|
1864 | procedure TBGRADefaultBitmap.AlphaPixel(x, y: int32or64; alpha: byte);
|
---|
1865 | begin
|
---|
1866 | if not PtInClipRect(x,y) then exit;
|
---|
1867 | LoadFromBitmapIfNeeded;
|
---|
1868 | if alpha = 0 then
|
---|
1869 | (GetScanlineFast(y) +x)^ := BGRAPixelTransparent
|
---|
1870 | else
|
---|
1871 | (GetScanlineFast(y) +x)^.alpha := alpha;
|
---|
1872 | InvalidateBitmap;
|
---|
1873 | end;
|
---|
1874 |
|
---|
1875 | function TBGRADefaultBitmap.GetPixel(x, y: int32or64): TBGRAPixel;
|
---|
1876 | begin
|
---|
1877 | if (x < 0) or (x >= Width) or (y < 0) or (y >= Height) then //it is possible to read pixels outside of the cliprect
|
---|
1878 | Result := BGRAPixelTransparent
|
---|
1879 | else
|
---|
1880 | begin
|
---|
1881 | LoadFromBitmapIfNeeded;
|
---|
1882 | Result := (GetScanlineFast(y) + x)^;
|
---|
1883 | end;
|
---|
1884 | end;
|
---|
1885 |
|
---|
1886 | function TBGRADefaultBitmap.GetPixel256(x, y, fracX256, fracY256: int32or64;
|
---|
1887 | AResampleFilter: TResampleFilter; smoothBorder: boolean = true): TBGRAPixel;
|
---|
1888 | begin
|
---|
1889 | if (fracX256 = 0) and (fracY256 = 0) then
|
---|
1890 | result := GetPixel(x,y)
|
---|
1891 | else if AResampleFilter = rfBox then
|
---|
1892 | begin
|
---|
1893 | if fracX256 >= 128 then inc(x);
|
---|
1894 | if fracY256 >= 128 then inc(y);
|
---|
1895 | result := GetPixel(x,y);
|
---|
1896 | end else
|
---|
1897 | begin
|
---|
1898 | LoadFromBitmapIfNeeded;
|
---|
1899 | result := InternalGetPixel256(x,y,FineInterpolation256(fracX256,AResampleFilter),FineInterpolation256(fracY256,AResampleFilter),smoothBorder);
|
---|
1900 | end;
|
---|
1901 | end;
|
---|
1902 |
|
---|
1903 | {$hints off}
|
---|
1904 | { This function compute an interpolated pixel at floating point coordinates }
|
---|
1905 | function TBGRADefaultBitmap.GetPixel(x, y: single; AResampleFilter: TResampleFilter = rfLinear; smoothBorder: boolean = true): TBGRAPixel;
|
---|
1906 | var
|
---|
1907 | ix, iy: Int32or64;
|
---|
1908 | iFactX,iFactY: Int32or64;
|
---|
1909 | begin
|
---|
1910 | ix := round(x*256);
|
---|
1911 | if (ix<= -256) or (ix>=Width shl 8) then
|
---|
1912 | begin
|
---|
1913 | result := BGRAPixelTransparent;
|
---|
1914 | exit;
|
---|
1915 | end;
|
---|
1916 | iy := round(y*256);
|
---|
1917 | if (iy<= -256) or (iy>=Height shl 8) then
|
---|
1918 | begin
|
---|
1919 | result := BGRAPixelTransparent;
|
---|
1920 | exit;
|
---|
1921 | end;
|
---|
1922 |
|
---|
1923 | iFactX := ix and 255; //distance from integer coordinate
|
---|
1924 | iFactY := iy and 255;
|
---|
1925 | if ix<0 then ix := -1 else ix := ix shr 8;
|
---|
1926 | if iy<0 then iy := -1 else iy := iy shr 8;
|
---|
1927 |
|
---|
1928 | //if the coordinate is integer, then call standard GetPixel function
|
---|
1929 | if (iFactX = 0) and (iFactY = 0) then
|
---|
1930 | begin
|
---|
1931 | Result := (GetScanlineFast(iy)+ix)^;
|
---|
1932 | exit;
|
---|
1933 | end;
|
---|
1934 |
|
---|
1935 | LoadFromBitmapIfNeeded;
|
---|
1936 | result := InternalGetPixel256(ix,iy,FineInterpolation256(iFactX,AResampleFilter),FineInterpolation256(iFactY,AResampleFilter),smoothBorder);
|
---|
1937 | end;
|
---|
1938 |
|
---|
1939 | { Same as GetPixel(single,single,TResampleFilter) but with coordinate cycle, supposing the image repeats itself in both directions }
|
---|
1940 | function TBGRADefaultBitmap.GetPixelCycle(x, y: single; AResampleFilter: TResampleFilter = rfLinear): TBGRAPixel;
|
---|
1941 | var
|
---|
1942 | ix, iy: Int32or64;
|
---|
1943 | iFactX,iFactY: Int32or64;
|
---|
1944 | begin
|
---|
1945 | if FData = nil then
|
---|
1946 | begin
|
---|
1947 | result := BGRAPixelTransparent;
|
---|
1948 | exit;
|
---|
1949 | end;
|
---|
1950 | LoadFromBitmapIfNeeded;
|
---|
1951 | ix := round(x*256);
|
---|
1952 | iy := round(y*256);
|
---|
1953 | iFactX := ix and 255;
|
---|
1954 | iFactY := iy and 255;
|
---|
1955 | ix := PositiveMod(ix, FWidth shl 8) shr 8;
|
---|
1956 | iy := PositiveMod(iy, FHeight shl 8) shr 8;
|
---|
1957 | if (iFactX = 0) and (iFactY = 0) then
|
---|
1958 | begin
|
---|
1959 | result := (GetScanlineFast(iy)+ix)^;
|
---|
1960 | exit;
|
---|
1961 | end;
|
---|
1962 | if ScanInterpolationFilter <> rfLinear then
|
---|
1963 | begin
|
---|
1964 | iFactX := FineInterpolation256( iFactX, ScanInterpolationFilter );
|
---|
1965 | iFactY := FineInterpolation256( iFactY, ScanInterpolationFilter );
|
---|
1966 | end;
|
---|
1967 | result := InternalGetPixelCycle256(ix,iy, iFactX,iFactY);
|
---|
1968 | end;
|
---|
1969 |
|
---|
1970 | function TBGRADefaultBitmap.GetPixelCycle(x, y: single;
|
---|
1971 | AResampleFilter: TResampleFilter; repeatX: boolean; repeatY: boolean
|
---|
1972 | ): TBGRAPixel;
|
---|
1973 | var
|
---|
1974 | ix, iy: Int32or64;
|
---|
1975 | iFactX,iFactY: Int32or64;
|
---|
1976 | begin
|
---|
1977 | if FData = nil then
|
---|
1978 | begin
|
---|
1979 | result := BGRAPixelTransparent;
|
---|
1980 | exit;
|
---|
1981 | end;
|
---|
1982 | ix := round(x*256);
|
---|
1983 | iy := round(y*256);
|
---|
1984 | iFactX := ix and 255;
|
---|
1985 | iFactY := iy and 255;
|
---|
1986 | if ix < 0 then ix := -((iFactX-ix) shr 8)
|
---|
1987 | else ix := ix shr 8;
|
---|
1988 | if iy < 0 then iy := -((iFactY-iy) shr 8)
|
---|
1989 | else iy := iy shr 8;
|
---|
1990 | result := GetPixelCycle256(ix,iy,iFactX,iFactY,AResampleFilter,repeatX,repeatY);
|
---|
1991 | end;
|
---|
1992 |
|
---|
1993 | function TBGRADefaultBitmap.GetPixelCycle256(x, y, fracX256,
|
---|
1994 | fracY256: int32or64; AResampleFilter: TResampleFilter): TBGRAPixel;
|
---|
1995 | begin
|
---|
1996 | if (fracX256 = 0) and (fracY256 = 0) then
|
---|
1997 | result := GetPixelCycle(x,y)
|
---|
1998 | else if AResampleFilter = rfBox then
|
---|
1999 | begin
|
---|
2000 | if fracX256 >= 128 then inc(x);
|
---|
2001 | if fracY256 >= 128 then inc(y);
|
---|
2002 | result := GetPixelCycle(x,y);
|
---|
2003 | end else
|
---|
2004 | begin
|
---|
2005 | LoadFromBitmapIfNeeded;
|
---|
2006 | result := InternalGetPixelCycle256(PositiveMod(x,FWidth),PositiveMod(y,FHeight),FineInterpolation256(fracX256,AResampleFilter),FineInterpolation256(fracY256,AResampleFilter));
|
---|
2007 | end;
|
---|
2008 | end;
|
---|
2009 |
|
---|
2010 | function TBGRADefaultBitmap.GetPixelCycle256(x, y, fracX256,
|
---|
2011 | fracY256: int32or64; AResampleFilter: TResampleFilter; repeatX: boolean;
|
---|
2012 | repeatY: boolean): TBGRAPixel;
|
---|
2013 | begin
|
---|
2014 | if not repeatX and not repeatY then
|
---|
2015 | result := GetPixel256(x,y,fracX256,fracY256,AResampleFilter)
|
---|
2016 | else if repeatX and repeatY then
|
---|
2017 | result := GetPixelCycle256(x,y,fracX256,fracY256,AResampleFilter)
|
---|
2018 | else
|
---|
2019 | begin
|
---|
2020 | if not repeatX then
|
---|
2021 | begin
|
---|
2022 | if x < 0 then
|
---|
2023 | begin
|
---|
2024 | if x < -1 then
|
---|
2025 | begin
|
---|
2026 | result := BGRAPixelTransparent;
|
---|
2027 | exit;
|
---|
2028 | end;
|
---|
2029 | result := GetPixelCycle256(0,y,0,fracY256,AResampleFilter);
|
---|
2030 | result.alpha:= result.alpha*fracX256 shr 8;
|
---|
2031 | if result.alpha = 0 then
|
---|
2032 | result := BGRAPixelTransparent;
|
---|
2033 | exit;
|
---|
2034 | end;
|
---|
2035 | if x >= FWidth-1 then
|
---|
2036 | begin
|
---|
2037 | if x >= FWidth then
|
---|
2038 | begin
|
---|
2039 | result := BGRAPixelTransparent;
|
---|
2040 | exit;
|
---|
2041 | end;
|
---|
2042 | result := GetPixelCycle256(FWidth-1,y,0,fracY256,AResampleFilter);
|
---|
2043 | result.alpha:= result.alpha*(256-fracX256) shr 8;
|
---|
2044 | if result.alpha = 0 then
|
---|
2045 | result := BGRAPixelTransparent;
|
---|
2046 | exit;
|
---|
2047 | end;
|
---|
2048 | end else
|
---|
2049 | begin
|
---|
2050 | if y < 0 then
|
---|
2051 | begin
|
---|
2052 | if y < -1 then
|
---|
2053 | begin
|
---|
2054 | result := BGRAPixelTransparent;
|
---|
2055 | exit;
|
---|
2056 | end;
|
---|
2057 | result := GetPixelCycle256(x,0,fracX256,0,AResampleFilter);
|
---|
2058 | result.alpha:= result.alpha*fracY256 shr 8;
|
---|
2059 | if result.alpha = 0 then
|
---|
2060 | result := BGRAPixelTransparent;
|
---|
2061 | exit;
|
---|
2062 | end;
|
---|
2063 | if y >= FHeight-1 then
|
---|
2064 | begin
|
---|
2065 | if y >= FHeight then
|
---|
2066 | begin
|
---|
2067 | result := BGRAPixelTransparent;
|
---|
2068 | exit;
|
---|
2069 | end;
|
---|
2070 | result := GetPixelCycle256(x,FHeight-1,fracX256,0,AResampleFilter);
|
---|
2071 | result.alpha:= result.alpha*(256-fracY256) shr 8;
|
---|
2072 | if result.alpha = 0 then
|
---|
2073 | result := BGRAPixelTransparent;
|
---|
2074 | exit;
|
---|
2075 | end;
|
---|
2076 | end;
|
---|
2077 | result := GetPixelCycle256(x,y,fracX256,fracY256,AResampleFilter);
|
---|
2078 | end;
|
---|
2079 | end;
|
---|
2080 |
|
---|
2081 | {$hints on}
|
---|
2082 |
|
---|
2083 | procedure TBGRADefaultBitmap.InvalidateBitmap;
|
---|
2084 | begin
|
---|
2085 | FDataModified := True;
|
---|
2086 | end;
|
---|
2087 |
|
---|
2088 | function TBGRADefaultBitmap.GetBitmap: TBitmap;
|
---|
2089 | begin
|
---|
2090 | if FAlphaCorrectionNeeded and CanvasAlphaCorrection then
|
---|
2091 | LoadFromBitmapIfNeeded;
|
---|
2092 | if FDataModified or (FBitmap = nil) then
|
---|
2093 | begin
|
---|
2094 | RebuildBitmap;
|
---|
2095 | FDataModified := False;
|
---|
2096 | end;
|
---|
2097 | Result := FBitmap;
|
---|
2098 | end;
|
---|
2099 |
|
---|
2100 | function TBGRADefaultBitmap.GetCanvas: TCanvas;
|
---|
2101 | begin
|
---|
2102 | if FDataModified or (FBitmap = nil) then
|
---|
2103 | begin
|
---|
2104 | RebuildBitmap;
|
---|
2105 | FDataModified := False;
|
---|
2106 | end;
|
---|
2107 | Result := FBitmap.Canvas;
|
---|
2108 | end;
|
---|
2109 |
|
---|
2110 | function TBGRADefaultBitmap.GetCanvasFP: TFPImageCanvas;
|
---|
2111 | begin
|
---|
2112 | {$warnings off}
|
---|
2113 | if FCanvasFP = nil then
|
---|
2114 | FCanvasFP := TFPImageCanvas.Create(self);
|
---|
2115 | {$warnings on}
|
---|
2116 | result := FCanvasFP;
|
---|
2117 | end;
|
---|
2118 |
|
---|
2119 | procedure TBGRADefaultBitmap.LoadFromBitmapIfNeeded;
|
---|
2120 | begin
|
---|
2121 | if FBitmapModified then
|
---|
2122 | begin
|
---|
2123 | DoLoadFromBitmap;
|
---|
2124 | DiscardBitmapChange;
|
---|
2125 | end;
|
---|
2126 | if FAlphaCorrectionNeeded then
|
---|
2127 | begin
|
---|
2128 | DoAlphaCorrection;
|
---|
2129 | end;
|
---|
2130 | end;
|
---|
2131 |
|
---|
2132 | procedure TBGRADefaultBitmap.CrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadePosition: byte; mode: TDrawMode = dmDrawWithTransparency);
|
---|
2133 | begin
|
---|
2134 | if AFadePosition = 0 then
|
---|
2135 | FillRect(ARect, Source1, mode) else
|
---|
2136 | if AFadePosition = 255 then
|
---|
2137 | FillRect(ARect, Source2, mode) else
|
---|
2138 | InternalCrossFade(ARect, Source1,Source2, AFadePosition,nil, mode);
|
---|
2139 | end;
|
---|
2140 |
|
---|
2141 | procedure TBGRADefaultBitmap.CrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadeMask: IBGRAScanner; mode: TDrawMode = dmDrawWithTransparency);
|
---|
2142 | begin
|
---|
2143 | InternalCrossFade(ARect, Source1,Source2, 0,AFadeMask, mode);
|
---|
2144 | end;
|
---|
2145 |
|
---|
2146 | procedure TBGRADefaultBitmap.DiscardBitmapChange; inline;
|
---|
2147 | begin
|
---|
2148 | FBitmapModified := False;
|
---|
2149 | end;
|
---|
2150 |
|
---|
2151 | { Initialize properties }
|
---|
2152 | procedure TBGRADefaultBitmap.Init;
|
---|
2153 | begin
|
---|
2154 | FRefCount := 1;
|
---|
2155 | FBitmap := nil;
|
---|
2156 | FCanvasFP := nil;
|
---|
2157 | FCanvasBGRA := nil;
|
---|
2158 | CanvasDrawModeFP := dmDrawWithTransparency;
|
---|
2159 | FData := nil;
|
---|
2160 | FWidth := 0;
|
---|
2161 | FHeight := 0;
|
---|
2162 | FScanWidth := FWidth;
|
---|
2163 | FScanHeight:= FHeight;
|
---|
2164 | FLineOrder := riloTopToBottom;
|
---|
2165 | FCanvasOpacity := 255;
|
---|
2166 | FAlphaCorrectionNeeded := False;
|
---|
2167 | FEraseMode := False;
|
---|
2168 | FillMode := fmWinding;
|
---|
2169 |
|
---|
2170 | FontName := 'Arial';
|
---|
2171 | FontStyle := [];
|
---|
2172 | FontAntialias := False;
|
---|
2173 | FontVerticalAnchor:= fvaTop;
|
---|
2174 | FFontHeight := 20;
|
---|
2175 |
|
---|
2176 | ResampleFilter := rfHalfCosine;
|
---|
2177 | ScanInterpolationFilter := rfLinear;
|
---|
2178 | ScanOffset := Point(0,0);
|
---|
2179 |
|
---|
2180 | FPenStroker := TBGRAPenStroker.Create;
|
---|
2181 | FPenStroker.Arrow := TBGRAArrow.Create;
|
---|
2182 | FPenStroker.Arrow.LineCap := LineCap;
|
---|
2183 | FPenStroker.ArrowOwned := true;
|
---|
2184 | end;
|
---|
2185 |
|
---|
2186 | procedure TBGRADefaultBitmap.SetInternalColor(x, y: integer; const Value: TFPColor);
|
---|
2187 | begin
|
---|
2188 | FCanvasPixelProcFP(x,y, FPColorToBGRA(Value));
|
---|
2189 | end;
|
---|
2190 |
|
---|
2191 | function TBGRADefaultBitmap.GetInternalColor(x, y: integer): TFPColor;
|
---|
2192 | begin
|
---|
2193 | if (x < 0) or (y < 0) or (x >= Width) or (y >= Height) then
|
---|
2194 | result := colTransparent
|
---|
2195 | else
|
---|
2196 | result := BGRAToFPColor((Scanline[y] + x)^);
|
---|
2197 | end;
|
---|
2198 |
|
---|
2199 | procedure TBGRADefaultBitmap.SetInternalPixel(x, y: integer; Value: integer);
|
---|
2200 | var
|
---|
2201 | c: TFPColor;
|
---|
2202 | begin
|
---|
2203 | if not PtInClipRect(x,y) then exit;
|
---|
2204 | c := Palette.Color[Value];
|
---|
2205 | (Scanline[y] + x)^ := FPColorToBGRA(c);
|
---|
2206 | InvalidateBitmap;
|
---|
2207 | end;
|
---|
2208 |
|
---|
2209 | function TBGRADefaultBitmap.GetInternalPixel(x, y: integer): integer;
|
---|
2210 | var
|
---|
2211 | c: TFPColor;
|
---|
2212 | begin
|
---|
2213 | if (x < 0) or (y < 0) or (x >= Width) or (y >= Height) then
|
---|
2214 | result := 0
|
---|
2215 | else
|
---|
2216 | begin
|
---|
2217 | c := BGRAToFPColor((Scanline[y] + x)^);
|
---|
2218 | Result := palette.IndexOf(c);
|
---|
2219 | end;
|
---|
2220 | end;
|
---|
2221 |
|
---|
2222 | procedure TBGRADefaultBitmap.Draw(ACanvas: TCanvas; x, y: integer; Opaque: boolean);
|
---|
2223 | begin
|
---|
2224 | if (self = nil) or (Width = 0) or (Height = 0) then exit;
|
---|
2225 | if Opaque then
|
---|
2226 | DataDrawOpaque(ACanvas, Rect(X, Y, X + Width, Y + Height), Data,
|
---|
2227 | FLineOrder, FWidth, FHeight)
|
---|
2228 | else
|
---|
2229 | begin
|
---|
2230 | LoadFromBitmapIfNeeded;
|
---|
2231 | if Empty then
|
---|
2232 | exit;
|
---|
2233 | ACanvas.Draw(X, Y, Bitmap);
|
---|
2234 | end;
|
---|
2235 | end;
|
---|
2236 |
|
---|
2237 | procedure TBGRADefaultBitmap.Draw(ACanvas: TCanvas; Rect: TRect; Opaque: boolean);
|
---|
2238 | begin
|
---|
2239 | if (self = nil) or (Width = 0) or (Height = 0) then exit;
|
---|
2240 | if Opaque then
|
---|
2241 | DataDrawOpaque(ACanvas, Rect, Data, FLineOrder, FWidth, FHeight)
|
---|
2242 | else
|
---|
2243 | begin
|
---|
2244 | LoadFromBitmapIfNeeded;
|
---|
2245 | ACanvas.StretchDraw(Rect, Bitmap);
|
---|
2246 | end;
|
---|
2247 | end;
|
---|
2248 |
|
---|
2249 | {---------------------------- Line primitives ---------------------------------}
|
---|
2250 |
|
---|
2251 | function TBGRADefaultBitmap.CheckHorizLineBounds(var x,y,x2: int32or64): boolean; inline;
|
---|
2252 | var
|
---|
2253 | temp: int32or64;
|
---|
2254 | begin
|
---|
2255 | if (x2 < x) then
|
---|
2256 | begin
|
---|
2257 | temp := x;
|
---|
2258 | x := x2;
|
---|
2259 | x2 := temp;
|
---|
2260 | end;
|
---|
2261 | if (x >= FClipRect.Right) or (x2 < FClipRect.Left) or (y < FClipRect.Top) or (y >= FClipRect.Bottom) then
|
---|
2262 | begin
|
---|
2263 | result := false;
|
---|
2264 | exit;
|
---|
2265 | end;
|
---|
2266 | if x < FClipRect.Left then
|
---|
2267 | x := FClipRect.Left;
|
---|
2268 | if x2 >= FClipRect.Right then
|
---|
2269 | x2 := FClipRect.Right - 1;
|
---|
2270 | result := true;
|
---|
2271 | end;
|
---|
2272 |
|
---|
2273 | procedure TBGRADefaultBitmap.SetHorizLine(x, y, x2: int32or64; c: TBGRAPixel);
|
---|
2274 | begin
|
---|
2275 | if not CheckHorizLineBounds(x,y,x2) then exit;
|
---|
2276 | FillInline(scanline[y] + x, c, x2 - x + 1);
|
---|
2277 | InvalidateBitmap;
|
---|
2278 | end;
|
---|
2279 |
|
---|
2280 | procedure TBGRADefaultBitmap.XorHorizLine(x, y, x2: int32or64; c: TBGRAPixel);
|
---|
2281 | begin
|
---|
2282 | if not CheckHorizLineBounds(x,y,x2) then exit;
|
---|
2283 | XorInline(scanline[y] + x, c, x2 - x + 1);
|
---|
2284 | InvalidateBitmap;
|
---|
2285 | end;
|
---|
2286 |
|
---|
2287 | procedure TBGRADefaultBitmap.DrawHorizLine(x, y, x2: int32or64; c: TBGRAPixel);
|
---|
2288 | begin
|
---|
2289 | if not CheckHorizLineBounds(x,y,x2) then exit;
|
---|
2290 | DrawPixelsInline(scanline[y] + x, c, x2 - x + 1);
|
---|
2291 | InvalidateBitmap;
|
---|
2292 | end;
|
---|
2293 |
|
---|
2294 | procedure TBGRADefaultBitmap.DrawHorizLine(x, y, x2: int32or64; ec: TExpandedPixel
|
---|
2295 | );
|
---|
2296 | begin
|
---|
2297 | if not CheckHorizLineBounds(x,y,x2) then exit;
|
---|
2298 | DrawExpandedPixelsInline(scanline[y] + x, ec, x2 - x + 1);
|
---|
2299 | InvalidateBitmap;
|
---|
2300 | end;
|
---|
2301 |
|
---|
2302 | procedure TBGRADefaultBitmap.HorizLine(x, y, x2: int32or64;
|
---|
2303 | texture: IBGRAScanner; ADrawMode : TDrawMode);
|
---|
2304 | begin
|
---|
2305 | if not CheckHorizLineBounds(x,y,x2) then exit;
|
---|
2306 | texture.ScanMoveTo(x,y);
|
---|
2307 | ScannerPutPixels(texture,scanline[y] + x, x2 - x + 1,ADrawMode);
|
---|
2308 | InvalidateBitmap;
|
---|
2309 | end;
|
---|
2310 |
|
---|
2311 | procedure TBGRADefaultBitmap.FastBlendHorizLine(x, y, x2: int32or64; c: TBGRAPixel);
|
---|
2312 | begin
|
---|
2313 | if not CheckHorizLineBounds(x,y,x2) then exit;
|
---|
2314 | FastBlendPixelsInline(scanline[y] + x, c, x2 - x + 1);
|
---|
2315 | InvalidateBitmap;
|
---|
2316 | end;
|
---|
2317 |
|
---|
2318 | procedure TBGRADefaultBitmap.AlphaHorizLine(x, y, x2: int32or64; alpha: byte);
|
---|
2319 | begin
|
---|
2320 | if alpha = 0 then
|
---|
2321 | begin
|
---|
2322 | SetHorizLine(x, y, x2, BGRAPixelTransparent);
|
---|
2323 | exit;
|
---|
2324 | end;
|
---|
2325 | if not CheckHorizLineBounds(x,y,x2) then exit;
|
---|
2326 | AlphaFillInline(scanline[y] + x, alpha, x2 - x + 1);
|
---|
2327 | InvalidateBitmap;
|
---|
2328 | end;
|
---|
2329 |
|
---|
2330 | function TBGRADefaultBitmap.CheckVertLineBounds(var x,y,y2: int32or64; out delta: int32or64): boolean; inline;
|
---|
2331 | var
|
---|
2332 | temp: int32or64;
|
---|
2333 | begin
|
---|
2334 | if FLineOrder = riloBottomToTop then
|
---|
2335 | delta := -Width
|
---|
2336 | else
|
---|
2337 | delta := Width;
|
---|
2338 |
|
---|
2339 | if (y2 < y) then
|
---|
2340 | begin
|
---|
2341 | temp := y;
|
---|
2342 | y := y2;
|
---|
2343 | y2 := temp;
|
---|
2344 | end;
|
---|
2345 |
|
---|
2346 | if y < FClipRect.Top then
|
---|
2347 | y := FClipRect.Top;
|
---|
2348 | if y2 >= FClipRect.Bottom then
|
---|
2349 | y2 := FClipRect.Bottom - 1;
|
---|
2350 |
|
---|
2351 | if (y >= FClipRect.Bottom) or (y2 < FClipRect.Top) or (x < FClipRect.Left) or (x >= FClipRect.Right) then
|
---|
2352 | begin
|
---|
2353 | result := false;
|
---|
2354 | exit;
|
---|
2355 | end;
|
---|
2356 |
|
---|
2357 | result := true;
|
---|
2358 | end;
|
---|
2359 |
|
---|
2360 | procedure TBGRADefaultBitmap.SetVertLine(x, y, y2: int32or64; c: TBGRAPixel);
|
---|
2361 | var
|
---|
2362 | n, delta: int32or64;
|
---|
2363 | p: PBGRAPixel;
|
---|
2364 | begin
|
---|
2365 | if not CheckVertLineBounds(x,y,y2,delta) then exit;
|
---|
2366 | p := scanline[y] + x;
|
---|
2367 | for n := y2 - y downto 0 do
|
---|
2368 | begin
|
---|
2369 | p^ := c;
|
---|
2370 | Inc(p, delta);
|
---|
2371 | end;
|
---|
2372 | InvalidateBitmap;
|
---|
2373 | end;
|
---|
2374 |
|
---|
2375 | procedure TBGRADefaultBitmap.XorVertLine(x, y, y2: int32or64; c: TBGRAPixel);
|
---|
2376 | var
|
---|
2377 | n, delta: int32or64;
|
---|
2378 | p: PBGRAPixel;
|
---|
2379 | begin
|
---|
2380 | if not CheckVertLineBounds(x,y,y2,delta) then exit;
|
---|
2381 | p := scanline[y] + x;
|
---|
2382 | for n := y2 - y downto 0 do
|
---|
2383 | begin
|
---|
2384 | PDword(p)^ := PDword(p)^ xor DWord(c);
|
---|
2385 | Inc(p, delta);
|
---|
2386 | end;
|
---|
2387 | InvalidateBitmap;
|
---|
2388 | end;
|
---|
2389 |
|
---|
2390 | procedure TBGRADefaultBitmap.DrawVertLine(x, y, y2: int32or64; c: TBGRAPixel);
|
---|
2391 | var
|
---|
2392 | n, delta: int32or64;
|
---|
2393 | p: PBGRAPixel;
|
---|
2394 | begin
|
---|
2395 | if c.alpha = 255 then
|
---|
2396 | begin
|
---|
2397 | SetVertLine(x,y,y2,c);
|
---|
2398 | exit;
|
---|
2399 | end;
|
---|
2400 | if not CheckVertLineBounds(x,y,y2,delta) or (c.alpha=0) then exit;
|
---|
2401 | p := scanline[y] + x;
|
---|
2402 | for n := y2 - y downto 0 do
|
---|
2403 | begin
|
---|
2404 | DrawPixelInlineNoAlphaCheck(p, c);
|
---|
2405 | Inc(p, delta);
|
---|
2406 | end;
|
---|
2407 | InvalidateBitmap;
|
---|
2408 | end;
|
---|
2409 |
|
---|
2410 | procedure TBGRADefaultBitmap.AlphaVertLine(x, y, y2: int32or64; alpha: byte);
|
---|
2411 | var
|
---|
2412 | n, delta: int32or64;
|
---|
2413 | p: PBGRAPixel;
|
---|
2414 | begin
|
---|
2415 | if alpha = 0 then
|
---|
2416 | begin
|
---|
2417 | SetVertLine(x, y, y2, BGRAPixelTransparent);
|
---|
2418 | exit;
|
---|
2419 | end;
|
---|
2420 | if not CheckVertLineBounds(x,y,y2,delta) then exit;
|
---|
2421 | p := scanline[y] + x;
|
---|
2422 | for n := y2 - y downto 0 do
|
---|
2423 | begin
|
---|
2424 | p^.alpha := alpha;
|
---|
2425 | Inc(p, delta);
|
---|
2426 | end;
|
---|
2427 | InvalidateBitmap;
|
---|
2428 | end;
|
---|
2429 |
|
---|
2430 | procedure TBGRADefaultBitmap.FastBlendVertLine(x, y, y2: int32or64; c: TBGRAPixel);
|
---|
2431 | var
|
---|
2432 | n, delta: int32or64;
|
---|
2433 | p: PBGRAPixel;
|
---|
2434 | begin
|
---|
2435 | if not CheckVertLineBounds(x,y,y2,delta) then exit;
|
---|
2436 | p := scanline[y] + x;
|
---|
2437 | for n := y2 - y downto 0 do
|
---|
2438 | begin
|
---|
2439 | FastBlendPixelInline(p, c);
|
---|
2440 | Inc(p, delta);
|
---|
2441 | end;
|
---|
2442 | InvalidateBitmap;
|
---|
2443 | end;
|
---|
2444 |
|
---|
2445 | procedure TBGRADefaultBitmap.DrawHorizLineDiff(x, y, x2: int32or64;
|
---|
2446 | c, compare: TBGRAPixel; maxDiff: byte);
|
---|
2447 | begin
|
---|
2448 | if not CheckHorizLineBounds(x,y,x2) then exit;
|
---|
2449 | DrawPixelsInlineDiff(scanline[y] + x, c, x2 - x + 1, compare, maxDiff);
|
---|
2450 | InvalidateBitmap;
|
---|
2451 | end;
|
---|
2452 |
|
---|
2453 | procedure TBGRADefaultBitmap.InternalTextOutCurved(
|
---|
2454 | ACursor: TBGRACustomPathCursor; sUTF8: string; AColor: TBGRAPixel;
|
---|
2455 | ATexture: IBGRAScanner; AAlign: TAlignment; ALetterSpacing: single);
|
---|
2456 | var
|
---|
2457 | pstr: pchar;
|
---|
2458 | left,charlen: integer;
|
---|
2459 | nextchar: string;
|
---|
2460 | charwidth, angle, textlen: single;
|
---|
2461 | begin
|
---|
2462 | if (ATexture = nil) and (AColor.alpha = 0) then exit;
|
---|
2463 | sUTF8 := CleanTextOutString(sUTF8);
|
---|
2464 | if sUTF8 = '' then exit;
|
---|
2465 | pstr := @sUTF8[1];
|
---|
2466 | left := length(sUTF8);
|
---|
2467 | if AALign<> taLeftJustify then
|
---|
2468 | begin
|
---|
2469 | textlen := TextSize(sUTF8).cx + (UTF8Length(sUTF8)-1)*ALetterSpacing;
|
---|
2470 | case AAlign of
|
---|
2471 | taCenter: ACursor.MoveBackward(textlen*0.5);
|
---|
2472 | taRightJustify: ACursor.MoveBackward(textlen);
|
---|
2473 | end;
|
---|
2474 | end;
|
---|
2475 | while left > 0 do
|
---|
2476 | begin
|
---|
2477 | charlen := UTF8CharacterLength(pstr);
|
---|
2478 | setlength(nextchar, charlen);
|
---|
2479 | move(pstr^, nextchar[1], charlen);
|
---|
2480 | inc(pstr,charlen);
|
---|
2481 | dec(left,charlen);
|
---|
2482 | charwidth := TextSize(nextchar).cx;
|
---|
2483 | ACursor.MoveForward(charwidth);
|
---|
2484 | ACursor.MoveBackward(charwidth, false);
|
---|
2485 | ACursor.MoveForward(charwidth*0.5);
|
---|
2486 | with ACursor.CurrentTangent do angle := arctan2(y,x);
|
---|
2487 | with ACursor.CurrentCoordinate do
|
---|
2488 | begin
|
---|
2489 | if ATexture = nil then
|
---|
2490 | TextOutAngle(x,y, system.round(-angle*1800/Pi), nextchar, AColor, taCenter)
|
---|
2491 | else
|
---|
2492 | TextOutAngle(x,y, system.round(-angle*1800/Pi), nextchar, ATexture, taCenter);
|
---|
2493 | end;
|
---|
2494 | ACursor.MoveForward(charwidth*0.5 + ALetterSpacing);
|
---|
2495 | end;
|
---|
2496 | end;
|
---|
2497 |
|
---|
2498 | procedure TBGRADefaultBitmap.InternalCrossFade(ARect: TRect; Source1,
|
---|
2499 | Source2: IBGRAScanner; AFadePos: byte; AFadeMask: IBGRAScanner; mode: TDrawMode);
|
---|
2500 | var xb,yb: NativeInt;
|
---|
2501 | pdest: PBGRAPixel;
|
---|
2502 | c: TBGRAPixel;
|
---|
2503 | buf1,buf2: ArrayOfTBGRAPixel;
|
---|
2504 | begin
|
---|
2505 | if not IntersectRect(ARect,ARect,ClipRect) then exit;
|
---|
2506 | setlength(buf1, ARect.Width);
|
---|
2507 | setlength(buf2, ARect.Width);
|
---|
2508 | for yb := ARect.top to ARect.Bottom-1 do
|
---|
2509 | begin
|
---|
2510 | pdest := GetScanlineFast(yb)+ARect.Left;
|
---|
2511 | Source1.ScanMoveTo(ARect.left, yb);
|
---|
2512 | Source1.ScanPutPixels(@buf1[0], length(buf1), dmSet);
|
---|
2513 | Source2.ScanMoveTo(ARect.left, yb);
|
---|
2514 | Source2.ScanPutPixels(@buf2[0], length(buf2), dmSet);
|
---|
2515 | if AFadeMask<>nil then AFadeMask.ScanMoveTo(ARect.left, yb);
|
---|
2516 | for xb := 0 to ARect.Right-ARect.left-1 do
|
---|
2517 | begin
|
---|
2518 | if AFadeMask<>nil then AFadePos := AFadeMask.ScanNextPixel.green;
|
---|
2519 | c := MergeBGRAWithGammaCorrection(buf1[xb],not AFadePos,buf2[xb],AFadePos);
|
---|
2520 | case mode of
|
---|
2521 | dmSet: pdest^ := c;
|
---|
2522 | dmDrawWithTransparency: DrawPixelInlineWithAlphaCheck(pdest, c);
|
---|
2523 | dmLinearBlend: FastBlendPixelInline(pdest,c);
|
---|
2524 | dmSetExceptTransparent: if c.alpha = 255 then pdest^ := c;
|
---|
2525 | end;
|
---|
2526 | inc(pdest);
|
---|
2527 | end;
|
---|
2528 | end;
|
---|
2529 | InvalidateBitmap;
|
---|
2530 | end;
|
---|
2531 |
|
---|
2532 | procedure TBGRADefaultBitmap.InternalArc(cx, cy, rx, ry: single; StartAngleRad,
|
---|
2533 | EndAngleRad: Single; ABorderColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel; AOptions: TArcOptions;
|
---|
2534 | ADrawChord: boolean; ATexture: IBGRAScanner);
|
---|
2535 | var
|
---|
2536 | pts, ptsFill: array of TPointF;
|
---|
2537 | temp: single;
|
---|
2538 | multi: TBGRAMultishapeFiller;
|
---|
2539 | begin
|
---|
2540 | if (rx = 0) or (ry = 0) then exit;
|
---|
2541 | if ADrawChord then AOptions := AOptions+[aoClosePath];
|
---|
2542 | if not (aoFillPath in AOptions) then
|
---|
2543 | AFillColor := BGRAPixelTransparent;
|
---|
2544 |
|
---|
2545 | if (ABorderColor.alpha = 0) and (AFillColor.alpha = 0) then exit;
|
---|
2546 |
|
---|
2547 | if abs(StartAngleRad-EndAngleRad) >= 2*PI - 1e-6 then
|
---|
2548 | begin
|
---|
2549 | if aoPie in AOptions then
|
---|
2550 | EndAngleRad:= StartAngleRad+2*PI
|
---|
2551 | else
|
---|
2552 | EllipseAntialias(cx,cy,rx,ry,ABorderColor,w,AFillColor);
|
---|
2553 | exit;
|
---|
2554 | end;
|
---|
2555 |
|
---|
2556 | if EndAngleRad < StartAngleRad then
|
---|
2557 | begin
|
---|
2558 | temp := StartAngleRad;
|
---|
2559 | StartAngleRad:= EndAngleRad;
|
---|
2560 | EndAngleRad:= temp;
|
---|
2561 | end;
|
---|
2562 |
|
---|
2563 | pts := ComputeArcRad(cx,cy,rx,ry,StartAngleRad,EndAngleRad);
|
---|
2564 | if aoPie in AOptions then pts := ConcatPointsF([PointsF([PointF(cx,cy)]),pts]);
|
---|
2565 |
|
---|
2566 | multi := TBGRAMultishapeFiller.Create;
|
---|
2567 | multi.PolygonOrder := poLastOnTop;
|
---|
2568 | if AFillColor.alpha <> 0 then
|
---|
2569 | begin
|
---|
2570 | if not (aoPie in AOptions) and (length(pts)>=2) then ptsFill := ConcatPointsF([PointsF([(pts[0]+pts[high(pts)])*0.5]),pts])
|
---|
2571 | else ptsFill := pts;
|
---|
2572 | if ATexture <> nil then
|
---|
2573 | multi.AddPolygon(ptsFill, ATexture)
|
---|
2574 | else
|
---|
2575 | multi.AddPolygon(ptsFill, AFillColor);
|
---|
2576 | end;
|
---|
2577 | if ABorderColor.alpha <> 0 then
|
---|
2578 | begin
|
---|
2579 | if [aoPie,aoClosePath]*AOptions <> [] then
|
---|
2580 | multi.AddPolygon(ComputeWidePolygon(pts,w), ABorderColor)
|
---|
2581 | else
|
---|
2582 | multi.AddPolygon(ComputeWidePolyline(pts,w), ABorderColor);
|
---|
2583 | end;
|
---|
2584 | multi.Antialiasing := true;
|
---|
2585 | multi.Draw(self);
|
---|
2586 | multi.Free;
|
---|
2587 | end;
|
---|
2588 |
|
---|
2589 | class function TBGRADefaultBitmap.IsAffineRoughlyTranslation(AMatrix: TAffineMatrix; ASourceBounds: TRect): boolean;
|
---|
2590 | const oneOver512 = 1/512;
|
---|
2591 | var Orig,HAxis,VAxis: TPointF;
|
---|
2592 | begin
|
---|
2593 | Orig := AMatrix*PointF(ASourceBounds.Left,ASourceBounds.Top);
|
---|
2594 | if (abs(Orig.x-round(Orig.x)) > oneOver512) or
|
---|
2595 | (abs(Orig.y-round(Orig.y)) > oneOver512) then
|
---|
2596 | begin
|
---|
2597 | result := false;
|
---|
2598 | exit;
|
---|
2599 | end;
|
---|
2600 | HAxis := AMatrix*PointF(ASourceBounds.Right-1,ASourceBounds.Top);
|
---|
2601 | if (abs(HAxis.x - (round(Orig.x)+ASourceBounds.Right-1 - ASourceBounds.Left)) > oneOver512) or
|
---|
2602 | (abs(HAxis.y - round(Orig.y)) > oneOver512) then
|
---|
2603 | begin
|
---|
2604 | result := false;
|
---|
2605 | exit;
|
---|
2606 | end;
|
---|
2607 | VAxis := AMatrix*PointF(ASourceBounds.Left,ASourceBounds.Bottom-1);
|
---|
2608 | if (abs(VAxis.y - (round(Orig.y)+ASourceBounds.Bottom-1 - ASourceBounds.Top)) > oneOver512) or
|
---|
2609 | (abs(VAxis.x - round(Orig.x)) > oneOver512) then
|
---|
2610 | begin
|
---|
2611 | result := false;
|
---|
2612 | exit;
|
---|
2613 | end;
|
---|
2614 | result := true;
|
---|
2615 | end;
|
---|
2616 |
|
---|
2617 | {---------------------------- Lines ---------------------------------}
|
---|
2618 | { Call appropriate functions }
|
---|
2619 |
|
---|
2620 | procedure TBGRADefaultBitmap.DrawLine(x1, y1, x2, y2: integer;
|
---|
2621 | c: TBGRAPixel; DrawLastPixel: boolean; ADrawMode: TDrawMode);
|
---|
2622 | begin
|
---|
2623 | BGRADrawLineAliased(self,x1,y1,x2,y2,c,DrawLastPixel,ADrawMode);
|
---|
2624 | end;
|
---|
2625 |
|
---|
2626 | procedure TBGRADefaultBitmap.DrawLineAntialias(x1, y1, x2, y2: integer;
|
---|
2627 | c: TBGRAPixel; DrawLastPixel: boolean);
|
---|
2628 | begin
|
---|
2629 | BGRADrawLineAntialias(self,x1,y1,x2,y2,c,DrawLastPixel,LinearAntialiasing);
|
---|
2630 | end;
|
---|
2631 |
|
---|
2632 | procedure TBGRADefaultBitmap.DrawLineAntialias(x1, y1, x2, y2: integer;
|
---|
2633 | c1, c2: TBGRAPixel; dashLen: integer; DrawLastPixel: boolean);
|
---|
2634 | var DashPos: integer;
|
---|
2635 | begin
|
---|
2636 | DashPos := 0;
|
---|
2637 | BGRADrawLineAntialias(self,x1,y1,x2,y2,c1,c2,dashLen,DrawLastPixel,DashPos,LinearAntialiasing);
|
---|
2638 | end;
|
---|
2639 |
|
---|
2640 | procedure TBGRADefaultBitmap.DrawLineAntialias(x1, y1, x2, y2: integer; c1,
|
---|
2641 | c2: TBGRAPixel; dashLen: integer; DrawLastPixel: boolean; var DashPos: integer);
|
---|
2642 | begin
|
---|
2643 | BGRADrawLineAntialias(self,x1,y1,x2,y2,c1,c2,dashLen,DrawLastPixel,DashPos,LinearAntialiasing);
|
---|
2644 | end;
|
---|
2645 |
|
---|
2646 | procedure TBGRADefaultBitmap.DrawLineAntialias(x1, y1, x2, y2: single;
|
---|
2647 | c: TBGRAPixel; w: single);
|
---|
2648 | begin
|
---|
2649 | FillPolyAntialias( FPenStroker.ComputePolyline([PointF(x1,y1),PointF(x2,y2)],w,c), c);
|
---|
2650 | end;
|
---|
2651 |
|
---|
2652 | procedure TBGRADefaultBitmap.DrawLineAntialias(x1, y1, x2, y2: single;
|
---|
2653 | texture: IBGRAScanner; w: single);
|
---|
2654 | begin
|
---|
2655 | FillPolyAntialias( FPenStroker.ComputePolyline([PointF(x1,y1),PointF(x2,y2)],w), texture);
|
---|
2656 | end;
|
---|
2657 |
|
---|
2658 | procedure TBGRADefaultBitmap.DrawLineAntialias(x1, y1, x2, y2: single;
|
---|
2659 | c: TBGRAPixel; w: single; ClosedCap: boolean);
|
---|
2660 | begin
|
---|
2661 | FillPolyAntialias( FPenStroker.ComputePolyline([PointF(x1,y1),PointF(x2,y2)],w,c,ClosedCap), c);
|
---|
2662 | end;
|
---|
2663 |
|
---|
2664 | procedure TBGRADefaultBitmap.DrawLineAntialias(x1, y1, x2, y2: single;
|
---|
2665 | texture: IBGRAScanner; w: single; ClosedCap: boolean);
|
---|
2666 | begin
|
---|
2667 | FillPolyAntialias( FPenStroker.ComputePolyline([PointF(x1,y1),PointF(x2,y2)],w,ClosedCap), texture);
|
---|
2668 | end;
|
---|
2669 |
|
---|
2670 | procedure TBGRADefaultBitmap.DrawPolyLineAntialias(const points: array of TPointF;
|
---|
2671 | c: TBGRAPixel; w: single);
|
---|
2672 | begin
|
---|
2673 | FillPolyAntialias( FPenStroker.ComputePolyline(points,w,c), c);
|
---|
2674 | end;
|
---|
2675 |
|
---|
2676 | procedure TBGRADefaultBitmap.DrawPolyLineAntialias(
|
---|
2677 | const points: array of TPointF; texture: IBGRAScanner; w: single);
|
---|
2678 | begin
|
---|
2679 | FillPolyAntialias( FPenStroker.ComputePolyline(points,w), texture);
|
---|
2680 | end;
|
---|
2681 |
|
---|
2682 | procedure TBGRADefaultBitmap.DrawPolyLineAntialias(const points: array of TPointF;
|
---|
2683 | c: TBGRAPixel; w: single; ClosedCap: boolean);
|
---|
2684 | begin
|
---|
2685 | FillPolyAntialias( FPenStroker.ComputePolyline(points,w,c,ClosedCap), c);
|
---|
2686 | end;
|
---|
2687 |
|
---|
2688 | procedure TBGRADefaultBitmap.DrawPolyLineAntialias(
|
---|
2689 | const points: array of TPointF; texture: IBGRAScanner; w: single;
|
---|
2690 | ClosedCap: boolean);
|
---|
2691 | begin
|
---|
2692 | FillPolyAntialias( FPenStroker.ComputePolyline(points,w,ClosedCap), texture);
|
---|
2693 | end;
|
---|
2694 |
|
---|
2695 | procedure TBGRADefaultBitmap.DrawPolyLineAntialias(
|
---|
2696 | const points: array of TPointF; c: TBGRAPixel; w: single;
|
---|
2697 | fillcolor: TBGRAPixel);
|
---|
2698 | var multi: TBGRAMultishapeFiller;
|
---|
2699 | begin
|
---|
2700 | multi := TBGRAMultishapeFiller.Create;
|
---|
2701 | multi.PolygonOrder := poLastOnTop;
|
---|
2702 | multi.AddPolygon(points,fillcolor);
|
---|
2703 | multi.AddPolygon(ComputeWidePolyline(points,w),c);
|
---|
2704 | if LinearAntialiasing then
|
---|
2705 | multi.Draw(self,dmLinearBlend)
|
---|
2706 | else
|
---|
2707 | multi.Draw(self,dmDrawWithTransparency);
|
---|
2708 | multi.Free;
|
---|
2709 | end;
|
---|
2710 |
|
---|
2711 | procedure TBGRADefaultBitmap.DrawPolyLineAntialiasAutocycle(
|
---|
2712 | const points: array of TPointF; c: TBGRAPixel; w: single);
|
---|
2713 | begin
|
---|
2714 | FillPolyAntialias( FPenStroker.ComputePolylineAutocycle(points,w), c);
|
---|
2715 | end;
|
---|
2716 |
|
---|
2717 | procedure TBGRADefaultBitmap.DrawPolyLineAntialiasAutocycle(
|
---|
2718 | const points: array of TPointF; texture: IBGRAScanner; w: single);
|
---|
2719 | begin
|
---|
2720 | FillPolyAntialias( FPenStroker.ComputePolylineAutocycle(points,w), texture);
|
---|
2721 | end;
|
---|
2722 |
|
---|
2723 | procedure TBGRADefaultBitmap.DrawPolygonAntialias(const points: array of TPointF;
|
---|
2724 | c: TBGRAPixel; w: single);
|
---|
2725 | begin
|
---|
2726 | FillPolyAntialias( FPenStroker.ComputePolygon(points,w), c);
|
---|
2727 | end;
|
---|
2728 |
|
---|
2729 | procedure TBGRADefaultBitmap.DrawPolygonAntialias(
|
---|
2730 | const points: array of TPointF; texture: IBGRAScanner; w: single);
|
---|
2731 | begin
|
---|
2732 | FillPolyAntialias( FPenStroker.ComputePolygon(points,w), texture);
|
---|
2733 | end;
|
---|
2734 |
|
---|
2735 | procedure TBGRADefaultBitmap.DrawPolygonAntialias(
|
---|
2736 | const points: array of TPointF; c: TBGRAPixel; w: single;
|
---|
2737 | fillcolor: TBGRAPixel);
|
---|
2738 | var multi: TBGRAMultishapeFiller;
|
---|
2739 | begin
|
---|
2740 | multi := TBGRAMultishapeFiller.Create;
|
---|
2741 | multi.PolygonOrder := poLastOnTop;
|
---|
2742 | multi.AddPolygon(points,fillcolor);
|
---|
2743 | multi.AddPolygon(ComputeWidePolygon(points,w),c);
|
---|
2744 | if LinearAntialiasing then
|
---|
2745 | multi.Draw(self,dmLinearBlend)
|
---|
2746 | else
|
---|
2747 | multi.Draw(self,dmDrawWithTransparency);
|
---|
2748 | multi.Free;
|
---|
2749 | end;
|
---|
2750 |
|
---|
2751 | procedure TBGRADefaultBitmap.EraseLine(x1, y1, x2, y2: integer; alpha: byte;
|
---|
2752 | DrawLastPixel: boolean);
|
---|
2753 | begin
|
---|
2754 | BGRAEraseLineAliased(self,x1,y1,x2,y2,alpha,DrawLastPixel);
|
---|
2755 | end;
|
---|
2756 |
|
---|
2757 | procedure TBGRADefaultBitmap.EraseLineAntialias(x1, y1, x2, y2: integer;
|
---|
2758 | alpha: byte; DrawLastPixel: boolean);
|
---|
2759 | begin
|
---|
2760 | BGRAEraseLineAntialias(self,x1,y1,x2,y2,alpha,DrawLastPixel);
|
---|
2761 | end;
|
---|
2762 |
|
---|
2763 | procedure TBGRADefaultBitmap.EraseLineAntialias(x1, y1, x2, y2: single;
|
---|
2764 | alpha: byte; w: single; Closed: boolean);
|
---|
2765 | begin
|
---|
2766 | FEraseMode := True;
|
---|
2767 | DrawLineAntialias(x1, y1, x2, y2, BGRA(0, 0, 0, alpha), w, Closed);
|
---|
2768 | FEraseMode := False;
|
---|
2769 | end;
|
---|
2770 |
|
---|
2771 | procedure TBGRADefaultBitmap.ErasePolyLineAntialias(const points: array of TPointF;
|
---|
2772 | alpha: byte; w: single);
|
---|
2773 | begin
|
---|
2774 | FEraseMode := True;
|
---|
2775 | DrawPolyLineAntialias(points, BGRA(0,0,0,alpha),w);
|
---|
2776 | FEraseMode := False;
|
---|
2777 | end;
|
---|
2778 |
|
---|
2779 | procedure TBGRADefaultBitmap.FillPath(APath: IBGRAPath; AFillColor: TBGRAPixel);
|
---|
2780 | begin
|
---|
2781 | FillPolyAntialias(APath.getPoints,AFillColor);
|
---|
2782 | end;
|
---|
2783 |
|
---|
2784 | procedure TBGRADefaultBitmap.FillPath(APath: IBGRAPath; AFillTexture: IBGRAScanner);
|
---|
2785 | begin
|
---|
2786 | FillPolyAntialias(APath.getPoints,AFillTexture);
|
---|
2787 | end;
|
---|
2788 |
|
---|
2789 | procedure TBGRADefaultBitmap.ErasePath(APath: IBGRAPath; alpha: byte);
|
---|
2790 | begin
|
---|
2791 | ErasePolyAntialias(APath.getPoints,alpha);
|
---|
2792 | end;
|
---|
2793 |
|
---|
2794 | procedure TBGRADefaultBitmap.DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix;
|
---|
2795 | AStrokeColor: TBGRAPixel; AWidth: single; AFillColor: TBGRAPixel);
|
---|
2796 | var tempPath: TBGRAPath;
|
---|
2797 | multi: TBGRAMultishapeFiller;
|
---|
2798 | begin
|
---|
2799 | tempPath := TBGRAPath.Create(APath);
|
---|
2800 | multi := TBGRAMultishapeFiller.Create;
|
---|
2801 | multi.FillMode := FillMode;
|
---|
2802 | multi.PolygonOrder := poLastOnTop;
|
---|
2803 | multi.AddPathFill(tempPath,AMatrix,AFillColor);
|
---|
2804 | multi.AddPathStroke(tempPath,AMatrix,AStrokeColor,AWidth,FPenStroker);
|
---|
2805 | multi.Draw(self);
|
---|
2806 | multi.Free;
|
---|
2807 | tempPath.Free;
|
---|
2808 | end;
|
---|
2809 |
|
---|
2810 | procedure TBGRADefaultBitmap.DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix;
|
---|
2811 | AStrokeTexture: IBGRAScanner; AWidth: single; AFillColor: TBGRAPixel);
|
---|
2812 | var tempPath: TBGRAPath;
|
---|
2813 | multi: TBGRAMultishapeFiller;
|
---|
2814 | begin
|
---|
2815 | tempPath := TBGRAPath.Create(APath);
|
---|
2816 | multi := TBGRAMultishapeFiller.Create;
|
---|
2817 | multi.FillMode := FillMode;
|
---|
2818 | multi.PolygonOrder := poLastOnTop;
|
---|
2819 | multi.AddPathFill(tempPath,AMatrix,AFillColor);
|
---|
2820 | multi.AddPathStroke(tempPath,AMatrix,AStrokeTexture,AWidth,FPenStroker);
|
---|
2821 | multi.Draw(self);
|
---|
2822 | multi.Free;
|
---|
2823 | tempPath.Free;
|
---|
2824 | end;
|
---|
2825 |
|
---|
2826 | procedure TBGRADefaultBitmap.DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix;
|
---|
2827 | AStrokeColor: TBGRAPixel; AWidth: single; AFillTexture: IBGRAScanner);
|
---|
2828 | var tempPath: TBGRAPath;
|
---|
2829 | multi: TBGRAMultishapeFiller;
|
---|
2830 | begin
|
---|
2831 | tempPath := TBGRAPath.Create(APath);
|
---|
2832 | multi := TBGRAMultishapeFiller.Create;
|
---|
2833 | multi.FillMode := FillMode;
|
---|
2834 | multi.PolygonOrder := poLastOnTop;
|
---|
2835 | multi.AddPathFill(tempPath,AMatrix,AFillTexture);
|
---|
2836 | multi.AddPathStroke(tempPath,AMatrix,AStrokeColor,AWidth,FPenStroker);
|
---|
2837 | multi.Draw(self);
|
---|
2838 | multi.Free;
|
---|
2839 | tempPath.Free;
|
---|
2840 | end;
|
---|
2841 |
|
---|
2842 | procedure TBGRADefaultBitmap.DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix;
|
---|
2843 | AStrokeTexture: IBGRAScanner; AWidth: single; AFillTexture: IBGRAScanner);
|
---|
2844 | var
|
---|
2845 | tempPath: TBGRAPath;
|
---|
2846 | multi: TBGRAMultishapeFiller;
|
---|
2847 | begin
|
---|
2848 | tempPath := TBGRAPath.Create(APath);
|
---|
2849 | multi := TBGRAMultishapeFiller.Create;
|
---|
2850 | multi.FillMode := FillMode;
|
---|
2851 | multi.PolygonOrder := poLastOnTop;
|
---|
2852 | multi.AddPathFill(tempPath,AMatrix,AFillTexture);
|
---|
2853 | multi.AddPathStroke(tempPath,AMatrix,AStrokeTexture,AWidth,FPenStroker);
|
---|
2854 | multi.Draw(self);
|
---|
2855 | multi.Free;
|
---|
2856 | tempPath.Free;
|
---|
2857 | end;
|
---|
2858 |
|
---|
2859 | procedure TBGRADefaultBitmap.DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix;
|
---|
2860 | AStrokeColor: TBGRAPixel; AWidth: single);
|
---|
2861 | var tempPath: TBGRAPath;
|
---|
2862 | begin
|
---|
2863 | tempPath := TBGRAPath.Create(APath);
|
---|
2864 | tempPath.stroke(self, AMatrix, AStrokeColor, AWidth);
|
---|
2865 | tempPath.Free;
|
---|
2866 | end;
|
---|
2867 |
|
---|
2868 | procedure TBGRADefaultBitmap.DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix;
|
---|
2869 | AStrokeTexture: IBGRAScanner; AWidth: single);
|
---|
2870 | var tempPath: TBGRAPath;
|
---|
2871 | begin
|
---|
2872 | tempPath := TBGRAPath.Create(APath);
|
---|
2873 | tempPath.stroke(self, AMatrix, AStrokeTexture, AWidth);
|
---|
2874 | tempPath.Free;
|
---|
2875 | end;
|
---|
2876 |
|
---|
2877 | procedure TBGRADefaultBitmap.FillPath(APath: IBGRAPath; AMatrix: TAffineMatrix;
|
---|
2878 | AFillColor: TBGRAPixel);
|
---|
2879 | begin
|
---|
2880 | FillPolyAntialias(APath.getPoints(AMatrix),AFillColor);
|
---|
2881 | end;
|
---|
2882 |
|
---|
2883 | procedure TBGRADefaultBitmap.FillPath(APath: IBGRAPath; AMatrix: TAffineMatrix;
|
---|
2884 | AFillTexture: IBGRAScanner);
|
---|
2885 | begin
|
---|
2886 | FillPolyAntialias(APath.getPoints(AMatrix),AFillTexture);
|
---|
2887 | end;
|
---|
2888 |
|
---|
2889 | procedure TBGRADefaultBitmap.ErasePath(APath: IBGRAPath;
|
---|
2890 | AMatrix: TAffineMatrix; alpha: byte);
|
---|
2891 | begin
|
---|
2892 | ErasePolyAntialias(APath.getPoints(AMatrix),alpha);
|
---|
2893 | end;
|
---|
2894 |
|
---|
2895 | procedure TBGRADefaultBitmap.ArrowStartAsNone;
|
---|
2896 | begin
|
---|
2897 | GetArrow.StartAsNone;
|
---|
2898 | end;
|
---|
2899 |
|
---|
2900 | procedure TBGRADefaultBitmap.ArrowStartAsClassic(AFlipped: boolean;
|
---|
2901 | ACut: boolean; ARelativePenWidth: single);
|
---|
2902 | begin
|
---|
2903 | GetArrow.StartAsClassic(AFlipped,ACut,ARelativePenWidth);
|
---|
2904 | end;
|
---|
2905 |
|
---|
2906 | procedure TBGRADefaultBitmap.ArrowStartAsTriangle(ABackOffset: single;
|
---|
2907 | ARounded: boolean; AHollow: boolean; AHollowPenWidth: single);
|
---|
2908 | begin
|
---|
2909 | GetArrow.StartAsTriangle(ABackOffset,ARounded,AHollow,AHollowPenWidth);
|
---|
2910 | end;
|
---|
2911 |
|
---|
2912 | procedure TBGRADefaultBitmap.ArrowStartAsTail;
|
---|
2913 | begin
|
---|
2914 | GetArrow.StartAsTail;
|
---|
2915 | end;
|
---|
2916 |
|
---|
2917 | procedure TBGRADefaultBitmap.ArrowEndAsNone;
|
---|
2918 | begin
|
---|
2919 | GetArrow.EndAsNone;
|
---|
2920 | end;
|
---|
2921 |
|
---|
2922 | procedure TBGRADefaultBitmap.ArrowEndAsClassic(AFlipped: boolean;
|
---|
2923 | ACut: boolean; ARelativePenWidth: single);
|
---|
2924 | begin
|
---|
2925 | GetArrow.EndAsClassic(AFlipped,ACut,ARelativePenWidth);
|
---|
2926 | end;
|
---|
2927 |
|
---|
2928 | procedure TBGRADefaultBitmap.ArrowEndAsTriangle(ABackOffset: single;
|
---|
2929 | ARounded: boolean; AHollow: boolean; AHollowPenWidth: single);
|
---|
2930 | begin
|
---|
2931 | GetArrow.EndAsTriangle(ABackOffset,ARounded,AHollow,AHollowPenWidth);
|
---|
2932 | end;
|
---|
2933 |
|
---|
2934 | procedure TBGRADefaultBitmap.ArrowEndAsTail;
|
---|
2935 | begin
|
---|
2936 | GetArrow.EndAsTail;
|
---|
2937 | end;
|
---|
2938 |
|
---|
2939 | {------------------------ Shapes ----------------------------------------------}
|
---|
2940 | { Call appropriate functions }
|
---|
2941 |
|
---|
2942 | procedure TBGRADefaultBitmap.FillTriangleLinearColor(pt1, pt2, pt3: TPointF;
|
---|
2943 | c1, c2, c3: TBGRAPixel);
|
---|
2944 | begin
|
---|
2945 | FillPolyLinearColor([pt1,pt2,pt3],[c1,c2,c3]);
|
---|
2946 | end;
|
---|
2947 |
|
---|
2948 | procedure TBGRADefaultBitmap.FillTriangleLinearColorAntialias(pt1, pt2,
|
---|
2949 | pt3: TPointF; c1, c2, c3: TBGRAPixel);
|
---|
2950 | var
|
---|
2951 | grad: TBGRAGradientTriangleScanner;
|
---|
2952 | begin
|
---|
2953 | grad := TBGRAGradientTriangleScanner.Create(pt1,pt2,pt3, c1,c2,c3);
|
---|
2954 | FillPolyAntialias([pt1,pt2,pt3],grad);
|
---|
2955 | grad.Free;
|
---|
2956 | end;
|
---|
2957 |
|
---|
2958 | procedure TBGRADefaultBitmap.FillTriangleLinearMapping(pt1, pt2, pt3: TPointF;
|
---|
2959 | texture: IBGRAScanner; tex1, tex2, tex3: TPointF; TextureInterpolation: Boolean= True);
|
---|
2960 | begin
|
---|
2961 | FillPolyLinearMapping([pt1,pt2,pt3],texture,[tex1,tex2,tex3],TextureInterpolation);
|
---|
2962 | end;
|
---|
2963 |
|
---|
2964 | procedure TBGRADefaultBitmap.FillTriangleLinearMappingLightness(pt1, pt2,
|
---|
2965 | pt3: TPointF; texture: IBGRAScanner; tex1, tex2, tex3: TPointF; light1,
|
---|
2966 | light2, light3: word; TextureInterpolation: Boolean);
|
---|
2967 | begin
|
---|
2968 | FillPolyLinearMappingLightness([pt1,pt2,pt3],texture,[tex1,tex2,tex3],[light1,light2,light3],TextureInterpolation);
|
---|
2969 | end;
|
---|
2970 |
|
---|
2971 | procedure TBGRADefaultBitmap.FillTriangleLinearMappingAntialias(pt1, pt2,
|
---|
2972 | pt3: TPointF; texture: IBGRAScanner; tex1, tex2, tex3: TPointF);
|
---|
2973 | var
|
---|
2974 | mapping: TBGRATriangleLinearMapping;
|
---|
2975 | begin
|
---|
2976 | mapping := TBGRATriangleLinearMapping.Create(texture, pt1,pt2,pt3, tex1, tex2, tex3);
|
---|
2977 | FillPolyAntialias([pt1,pt2,pt3],mapping);
|
---|
2978 | mapping.Free;
|
---|
2979 | end;
|
---|
2980 |
|
---|
2981 | procedure TBGRADefaultBitmap.FillQuadLinearColor(pt1, pt2, pt3, pt4: TPointF;
|
---|
2982 | c1, c2, c3, c4: TBGRAPixel);
|
---|
2983 | var
|
---|
2984 | center: TPointF;
|
---|
2985 | centerColor: TBGRAPixel;
|
---|
2986 | multi: TBGRAMultishapeFiller;
|
---|
2987 | begin
|
---|
2988 | if not IsConvex([pt1,pt2,pt3,pt4]) then //need to merge colors
|
---|
2989 | begin
|
---|
2990 | multi := TBGRAMultishapeFiller.Create;
|
---|
2991 | multi.AddQuadLinearColor(pt1,pt2,pt3,pt4,c1,c2,c3,c4);
|
---|
2992 | multi.Antialiasing:= false;
|
---|
2993 | multi.Draw(self);
|
---|
2994 | multi.Free;
|
---|
2995 | exit;
|
---|
2996 | end;
|
---|
2997 | center := (pt1+pt2+pt3+pt4)*(1/4);
|
---|
2998 | centerColor := GammaCompression( MergeBGRA(MergeBGRA(GammaExpansion(c1),GammaExpansion(c2)),
|
---|
2999 | MergeBGRA(GammaExpansion(c3),GammaExpansion(c4))) );
|
---|
3000 | FillTriangleLinearColor(pt1,pt2,center, c1,c2,centerColor);
|
---|
3001 | FillTriangleLinearColor(pt2,pt3,center, c2,c3,centerColor);
|
---|
3002 | FillTriangleLinearColor(pt3,pt4,center, c3,c4,centerColor);
|
---|
3003 | FillTriangleLinearColor(pt4,pt1,center, c4,c1,centerColor);
|
---|
3004 | end;
|
---|
3005 |
|
---|
3006 | procedure TBGRADefaultBitmap.FillQuadLinearColorAntialias(pt1, pt2, pt3,
|
---|
3007 | pt4: TPointF; c1, c2, c3, c4: TBGRAPixel);
|
---|
3008 | var multi : TBGRAMultishapeFiller;
|
---|
3009 | begin
|
---|
3010 | multi := TBGRAMultishapeFiller.Create;
|
---|
3011 | multi.AddQuadLinearColor(pt1, pt2, pt3, pt4, c1, c2, c3, c4);
|
---|
3012 | multi.Draw(self);
|
---|
3013 | multi.free;
|
---|
3014 | end;
|
---|
3015 |
|
---|
3016 | procedure TBGRADefaultBitmap.FillQuadLinearMapping(pt1, pt2, pt3, pt4: TPointF;
|
---|
3017 | texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF;
|
---|
3018 | TextureInterpolation: Boolean; ACulling: TFaceCulling);
|
---|
3019 | var
|
---|
3020 | scan: TBGRAQuadLinearScanner;
|
---|
3021 | begin
|
---|
3022 | if ((abs(pt1.y-pt2.y)<1e-6) and (abs(pt3.y-pt4.y)<1e-6)) or
|
---|
3023 | ((abs(pt3.y-pt2.y)<1e-6) and (abs(pt1.y-pt4.y)<1e-6)) then
|
---|
3024 | FillPolyLinearMapping([pt1,pt2,pt3,pt4], texture,
|
---|
3025 | [tex1,tex2,tex3,tex4], TextureInterpolation)
|
---|
3026 | else
|
---|
3027 | begin
|
---|
3028 | scan := TBGRAQuadLinearScanner.Create(texture,
|
---|
3029 | [tex1,tex2,tex3,tex4],
|
---|
3030 | [pt1,pt2,pt3,pt4],TextureInterpolation);
|
---|
3031 | scan.Culling := ACulling;
|
---|
3032 | FillPoly([pt1,pt2,pt3,pt4],scan,dmDrawWithTransparency);
|
---|
3033 | scan.Free;
|
---|
3034 | end;
|
---|
3035 | end;
|
---|
3036 |
|
---|
3037 | procedure TBGRADefaultBitmap.FillQuadLinearMappingLightness(pt1, pt2, pt3,
|
---|
3038 | pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; light1,
|
---|
3039 | light2, light3, light4: word; TextureInterpolation: Boolean);
|
---|
3040 | var
|
---|
3041 | center: TPointF;
|
---|
3042 | centerTex: TPointF;
|
---|
3043 | centerLight: word;
|
---|
3044 | begin
|
---|
3045 | center := (pt1+pt2+pt3+pt4)*(1/4);
|
---|
3046 | centerTex := (tex1+tex2+tex3+tex4)*(1/4);
|
---|
3047 | centerLight := (light1+light2+light3+light4) div 4;
|
---|
3048 | FillTriangleLinearMappingLightness(pt1,pt2,center, texture,tex1,tex2,centerTex, light1,light2,centerLight, TextureInterpolation);
|
---|
3049 | FillTriangleLinearMappingLightness(pt2,pt3,center, texture,tex2,tex3,centerTex, light2,light3,centerLight, TextureInterpolation);
|
---|
3050 | FillTriangleLinearMappingLightness(pt3,pt4,center, texture,tex3,tex4,centerTex, light3,light4,centerLight, TextureInterpolation);
|
---|
3051 | FillTriangleLinearMappingLightness(pt4,pt1,center, texture,tex4,tex1,centerTex, light4,light1,centerLight, TextureInterpolation);
|
---|
3052 | end;
|
---|
3053 |
|
---|
3054 | procedure TBGRADefaultBitmap.FillQuadLinearMappingAntialias(pt1, pt2, pt3,
|
---|
3055 | pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF;
|
---|
3056 | ACulling: TFaceCulling);
|
---|
3057 | var multi : TBGRAMultishapeFiller;
|
---|
3058 | begin
|
---|
3059 | multi := TBGRAMultishapeFiller.Create;
|
---|
3060 | multi.AddQuadLinearMapping(pt1, pt2, pt3, pt4, texture, tex1,tex2,tex3,tex4, ACulling);
|
---|
3061 | multi.Draw(self);
|
---|
3062 | multi.free;
|
---|
3063 | end;
|
---|
3064 |
|
---|
3065 | procedure TBGRADefaultBitmap.FillQuadPerspectiveMapping(pt1, pt2, pt3,
|
---|
3066 | pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF;
|
---|
3067 | ADrawMode: TDrawMode);
|
---|
3068 | var
|
---|
3069 | persp: TBGRAPerspectiveScannerTransform;
|
---|
3070 | begin
|
---|
3071 | persp := TBGRAPerspectiveScannerTransform.Create(texture,[tex1,tex2,tex3,tex4],[pt1,pt2,pt3,pt4]);
|
---|
3072 | FillPoly([pt1,pt2,pt3,pt4],persp,ADrawMode);
|
---|
3073 | persp.Free;
|
---|
3074 | end;
|
---|
3075 |
|
---|
3076 | procedure TBGRADefaultBitmap.FillQuadPerspectiveMapping(pt1, pt2, pt3,
|
---|
3077 | pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF;
|
---|
3078 | ACleanBorders: TRect; ADrawMode: TDrawMode);
|
---|
3079 | var
|
---|
3080 | persp: TBGRAPerspectiveScannerTransform;
|
---|
3081 | clean: TBGRAExtendedBorderScanner;
|
---|
3082 | begin
|
---|
3083 | clean := TBGRAExtendedBorderScanner.Create(texture,ACleanBorders);
|
---|
3084 | persp := TBGRAPerspectiveScannerTransform.Create(clean,[tex1,tex2,tex3,tex4],[pt1,pt2,pt3,pt4]);
|
---|
3085 | FillPoly([pt1,pt2,pt3,pt4],persp,ADrawMode);
|
---|
3086 | persp.Free;
|
---|
3087 | clean.Free;
|
---|
3088 | end;
|
---|
3089 |
|
---|
3090 | procedure TBGRADefaultBitmap.FillQuadPerspectiveMappingAntialias(pt1, pt2, pt3,
|
---|
3091 | pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF);
|
---|
3092 | var
|
---|
3093 | persp: TBGRAPerspectiveScannerTransform;
|
---|
3094 | begin
|
---|
3095 | persp := TBGRAPerspectiveScannerTransform.Create(texture,[tex1,tex2,tex3,tex4],[pt1,pt2,pt3,pt4]);
|
---|
3096 | FillPolyAntialias([pt1,pt2,pt3,pt4],persp);
|
---|
3097 | persp.Free;
|
---|
3098 | end;
|
---|
3099 |
|
---|
3100 | procedure TBGRADefaultBitmap.FillQuadPerspectiveMappingAntialias(pt1, pt2, pt3,
|
---|
3101 | pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF;
|
---|
3102 | ACleanBorders: TRect);
|
---|
3103 | var
|
---|
3104 | persp: TBGRAPerspectiveScannerTransform;
|
---|
3105 | clean: TBGRAExtendedBorderScanner;
|
---|
3106 | begin
|
---|
3107 | clean := TBGRAExtendedBorderScanner.Create(texture,ACleanBorders);
|
---|
3108 | persp := TBGRAPerspectiveScannerTransform.Create(clean,[tex1,tex2,tex3,tex4],[pt1,pt2,pt3,pt4]);
|
---|
3109 | FillPolyAntialias([pt1,pt2,pt3,pt4],persp);
|
---|
3110 | persp.Free;
|
---|
3111 | clean.Free;
|
---|
3112 | end;
|
---|
3113 |
|
---|
3114 | procedure TBGRADefaultBitmap.FillQuadAffineMapping(Orig, HAxis, VAxis: TPointF;
|
---|
3115 | AImage: TBGRACustomBitmap; APixelCenteredCoordinates: boolean; ADrawMode: TDrawMode; AOpacity: byte);
|
---|
3116 | var pts3: TPointF;
|
---|
3117 | affine: TBGRAAffineBitmapTransform;
|
---|
3118 | begin
|
---|
3119 | if not APixelCenteredCoordinates then
|
---|
3120 | begin
|
---|
3121 | Orig -= PointF(0.5,0.5);
|
---|
3122 | HAxis -= PointF(0.5,0.5);
|
---|
3123 | VAxis -= PointF(0.5,0.5);
|
---|
3124 | end;
|
---|
3125 | pts3 := HAxis+(VAxis-Orig);
|
---|
3126 | affine := TBGRAAffineBitmapTransform.Create(AImage,False,AImage.ScanInterpolationFilter,not APixelCenteredCoordinates);
|
---|
3127 | affine.GlobalOpacity:= AOpacity;
|
---|
3128 | affine.Fit(Orig,HAxis,VAxis);
|
---|
3129 | FillPoly([Orig,HAxis,pts3,VAxis],affine,ADrawMode);
|
---|
3130 | affine.Free;
|
---|
3131 | end;
|
---|
3132 |
|
---|
3133 | procedure TBGRADefaultBitmap.FillQuadAffineMappingAntialias(Orig, HAxis,
|
---|
3134 | VAxis: TPointF; AImage: TBGRACustomBitmap; APixelCenteredCoordinates: boolean; AOpacity: byte);
|
---|
3135 | var pts3: TPointF;
|
---|
3136 | affine: TBGRAAffineBitmapTransform;
|
---|
3137 | begin
|
---|
3138 | if not APixelCenteredCoordinates then
|
---|
3139 | begin
|
---|
3140 | Orig -= PointF(0.5,0.5);
|
---|
3141 | HAxis -= PointF(0.5,0.5);
|
---|
3142 | VAxis -= PointF(0.5,0.5);
|
---|
3143 | end;
|
---|
3144 | pts3 := HAxis+(VAxis-Orig);
|
---|
3145 | affine := TBGRAAffineBitmapTransform.Create(AImage,False,AImage.ScanInterpolationFilter,not APixelCenteredCoordinates);
|
---|
3146 | affine.GlobalOpacity:= AOpacity;
|
---|
3147 | affine.Fit(Orig,HAxis,VAxis);
|
---|
3148 | FillPolyAntialias([Orig,HAxis,pts3,VAxis],affine);
|
---|
3149 | affine.Free;
|
---|
3150 | end;
|
---|
3151 |
|
---|
3152 | procedure TBGRADefaultBitmap.FillPolyLinearMapping(const points: array of TPointF;
|
---|
3153 | texture: IBGRAScanner; texCoords: array of TPointF;
|
---|
3154 | TextureInterpolation: Boolean);
|
---|
3155 | begin
|
---|
3156 | PolygonLinearTextureMappingAliased(self,points,texture,texCoords,TextureInterpolation, FillMode = fmWinding);
|
---|
3157 | end;
|
---|
3158 |
|
---|
3159 | procedure TBGRADefaultBitmap.FillPolyLinearMappingLightness(
|
---|
3160 | const points: array of TPointF; texture: IBGRAScanner;
|
---|
3161 | texCoords: array of TPointF; lightnesses: array of word;
|
---|
3162 | TextureInterpolation: Boolean);
|
---|
3163 | begin
|
---|
3164 | PolygonLinearTextureMappingAliasedWithLightness(self,points,texture,texCoords,TextureInterpolation,lightnesses,FillMode = fmWinding);
|
---|
3165 | end;
|
---|
3166 |
|
---|
3167 | procedure TBGRADefaultBitmap.FillPolyLinearColor(
|
---|
3168 | const points: array of TPointF; AColors: array of TBGRAPixel);
|
---|
3169 | begin
|
---|
3170 | PolygonLinearColorGradientAliased(self,points,AColors, FillMode = fmWinding);
|
---|
3171 | end;
|
---|
3172 |
|
---|
3173 | procedure TBGRADefaultBitmap.FillPolyPerspectiveMapping(
|
---|
3174 | const points: array of TPointF; const pointsZ: array of single;
|
---|
3175 | texture: IBGRAScanner; texCoords: array of TPointF;
|
---|
3176 | TextureInterpolation: Boolean; zbuffer: psingle);
|
---|
3177 | begin
|
---|
3178 | PolygonPerspectiveTextureMappingAliased(self,points,pointsZ,texture,texCoords,TextureInterpolation, FillMode = fmWinding, zbuffer);
|
---|
3179 | end;
|
---|
3180 |
|
---|
3181 | procedure TBGRADefaultBitmap.FillPolyPerspectiveMappingLightness(
|
---|
3182 | const points: array of TPointF; const pointsZ: array of single;
|
---|
3183 | texture: IBGRAScanner; texCoords: array of TPointF;
|
---|
3184 | lightnesses: array of word; TextureInterpolation: Boolean; zbuffer: psingle);
|
---|
3185 | begin
|
---|
3186 | PolygonPerspectiveTextureMappingAliasedWithLightness(self,points,pointsZ,texture,texCoords,TextureInterpolation,lightnesses, FillMode = fmWinding, zbuffer);
|
---|
3187 | end;
|
---|
3188 |
|
---|
3189 | procedure TBGRADefaultBitmap.FillPoly(const points: array of TPointF;
|
---|
3190 | c: TBGRAPixel; drawmode: TDrawMode; APixelCenteredCoordinates: boolean);
|
---|
3191 | begin
|
---|
3192 | BGRAPolygon.FillPolyAliased(self, points, c, FEraseMode, FillMode = fmWinding, drawmode, APixelCenteredCoordinates);
|
---|
3193 | end;
|
---|
3194 |
|
---|
3195 | procedure TBGRADefaultBitmap.FillPoly(const points: array of TPointF;
|
---|
3196 | texture: IBGRAScanner; drawmode: TDrawMode; APixelCenteredCoordinates: boolean);
|
---|
3197 | begin
|
---|
3198 | BGRAPolygon.FillPolyAliasedWithTexture(self, points, texture, FillMode = fmWinding, drawmode, APixelCenteredCoordinates);
|
---|
3199 | end;
|
---|
3200 |
|
---|
3201 | procedure TBGRADefaultBitmap.EraseLineAntialias(x1, y1, x2, y2: single;
|
---|
3202 | alpha: byte; w: single);
|
---|
3203 | begin
|
---|
3204 | FEraseMode := True;
|
---|
3205 | DrawLineAntialias(x1,y1,x2,y2, BGRA(0,0,0,alpha),w);
|
---|
3206 | FEraseMode := False;
|
---|
3207 | end;
|
---|
3208 |
|
---|
3209 | procedure TBGRADefaultBitmap.FillPolyAntialias(const points: array of TPointF; c: TBGRAPixel; APixelCenteredCoordinates: boolean);
|
---|
3210 | begin
|
---|
3211 | BGRAPolygon.FillPolyAntialias(self, points, c, FEraseMode, FillMode = fmWinding, LinearAntialiasing, APixelCenteredCoordinates);
|
---|
3212 | end;
|
---|
3213 |
|
---|
3214 | procedure TBGRADefaultBitmap.FillPolyAntialias(const points: array of TPointF;
|
---|
3215 | texture: IBGRAScanner; APixelCenteredCoordinates: boolean);
|
---|
3216 | begin
|
---|
3217 | BGRAPolygon.FillPolyAntialiasWithTexture(self, points, texture, FillMode = fmWinding, LinearAntialiasing, APixelCenteredCoordinates);
|
---|
3218 | end;
|
---|
3219 |
|
---|
3220 | procedure TBGRADefaultBitmap.ErasePoly(const points: array of TPointF;
|
---|
3221 | alpha: byte; APixelCenteredCoordinates: boolean);
|
---|
3222 | begin
|
---|
3223 | BGRAPolygon.FillPolyAliased(self, points, BGRA(0, 0, 0, alpha), True, FillMode = fmWinding, dmDrawWithTransparency, APixelCenteredCoordinates);
|
---|
3224 | end;
|
---|
3225 |
|
---|
3226 | procedure TBGRADefaultBitmap.ErasePolyAntialias(const points: array of TPointF; alpha: byte; APixelCenteredCoordinates: boolean);
|
---|
3227 | begin
|
---|
3228 | FEraseMode := True;
|
---|
3229 | FillPolyAntialias(points, BGRA(0, 0, 0, alpha), APixelCenteredCoordinates);
|
---|
3230 | FEraseMode := False;
|
---|
3231 | end;
|
---|
3232 |
|
---|
3233 | procedure TBGRADefaultBitmap.FillShape(shape: TBGRACustomFillInfo; c: TBGRAPixel;
|
---|
3234 | drawmode: TDrawMode);
|
---|
3235 | begin
|
---|
3236 | BGRAPolygon.FillShapeAliased(self, shape, c, FEraseMode, nil, FillMode = fmWinding, drawmode);
|
---|
3237 | end;
|
---|
3238 |
|
---|
3239 | procedure TBGRADefaultBitmap.FillShape(shape: TBGRACustomFillInfo;
|
---|
3240 | texture: IBGRAScanner; drawmode: TDrawMode);
|
---|
3241 | begin
|
---|
3242 | BGRAPolygon.FillShapeAliased(self, shape, BGRAPixelTransparent, false, texture, FillMode = fmWinding, drawmode);
|
---|
3243 | end;
|
---|
3244 |
|
---|
3245 | procedure TBGRADefaultBitmap.FillShapeAntialias(shape: TBGRACustomFillInfo;
|
---|
3246 | c: TBGRAPixel);
|
---|
3247 | begin
|
---|
3248 | BGRAPolygon.FillShapeAntialias(self, shape, c, FEraseMode, nil, FillMode = fmWinding, LinearAntialiasing);
|
---|
3249 | end;
|
---|
3250 |
|
---|
3251 | procedure TBGRADefaultBitmap.FillShapeAntialias(shape: TBGRACustomFillInfo;
|
---|
3252 | texture: IBGRAScanner);
|
---|
3253 | begin
|
---|
3254 | BGRAPolygon.FillShapeAntialiasWithTexture(self, shape, texture, FillMode = fmWinding, LinearAntialiasing);
|
---|
3255 | end;
|
---|
3256 |
|
---|
3257 | procedure TBGRADefaultBitmap.EraseShape(shape: TBGRACustomFillInfo; alpha: byte);
|
---|
3258 | begin
|
---|
3259 | BGRAPolygon.FillShapeAliased(self, shape, BGRA(0, 0, 0, alpha), True, nil, FillMode = fmWinding, dmDrawWithTransparency);
|
---|
3260 | end;
|
---|
3261 |
|
---|
3262 | procedure TBGRADefaultBitmap.EraseShapeAntialias(shape: TBGRACustomFillInfo;
|
---|
3263 | alpha: byte);
|
---|
3264 | begin
|
---|
3265 | FEraseMode := True;
|
---|
3266 | FillShapeAntialias(shape, BGRA(0, 0, 0, alpha));
|
---|
3267 | FEraseMode := False;
|
---|
3268 | end;
|
---|
3269 |
|
---|
3270 | procedure TBGRADefaultBitmap.DrawPath(APath: IBGRAPath;
|
---|
3271 | AStrokeColor: TBGRAPixel; AWidth: single; AFillColor: TBGRAPixel);
|
---|
3272 | begin
|
---|
3273 | DrawPath(APath,AffineMatrixIdentity,AStrokeColor,AWidth,AFillColor);
|
---|
3274 | end;
|
---|
3275 |
|
---|
3276 | procedure TBGRADefaultBitmap.DrawPath(APath: IBGRAPath;
|
---|
3277 | AStrokeTexture: IBGRAScanner; AWidth: single; AFillColor: TBGRAPixel);
|
---|
3278 | begin
|
---|
3279 | DrawPath(APath,AffineMatrixIdentity,AStrokeTexture,AWidth,AFillColor);
|
---|
3280 | end;
|
---|
3281 |
|
---|
3282 | procedure TBGRADefaultBitmap.DrawPath(APath: IBGRAPath;
|
---|
3283 | AStrokeColor: TBGRAPixel; AWidth: single; AFillTexture: IBGRAScanner);
|
---|
3284 | begin
|
---|
3285 | DrawPath(APath,AffineMatrixIdentity,AStrokeColor,AWidth,AFillTexture);
|
---|
3286 | end;
|
---|
3287 |
|
---|
3288 | procedure TBGRADefaultBitmap.DrawPath(APath: IBGRAPath;
|
---|
3289 | AStrokeTexture: IBGRAScanner; AWidth: single; AFillTexture: IBGRAScanner);
|
---|
3290 | begin
|
---|
3291 | DrawPath(APath,AffineMatrixIdentity,AStrokeTexture,AWidth,AFillTexture);
|
---|
3292 | end;
|
---|
3293 |
|
---|
3294 | procedure TBGRADefaultBitmap.DrawPath(APath: IBGRAPath; AStrokeColor: TBGRAPixel; AWidth: single);
|
---|
3295 | begin
|
---|
3296 | DrawPath(APath, AffineMatrixIdentity, AStrokeColor, AWidth);
|
---|
3297 | end;
|
---|
3298 |
|
---|
3299 | procedure TBGRADefaultBitmap.DrawPath(APath: IBGRAPath; AStrokeTexture: IBGRAScanner; AWidth: single);
|
---|
3300 | begin
|
---|
3301 | DrawPath(APath, AffineMatrixIdentity, AStrokeTexture, AWidth);
|
---|
3302 | end;
|
---|
3303 |
|
---|
3304 | procedure TBGRADefaultBitmap.EllipseAntialias(x, y, rx, ry: single;
|
---|
3305 | c: TBGRAPixel; w: single);
|
---|
3306 | begin
|
---|
3307 | if (PenStyle = psClear) or (c.alpha = 0) or (w = 0) then exit;
|
---|
3308 | if (PenStyle = psSolid) then
|
---|
3309 | BGRAPolygon.BorderEllipseAntialias(self, x, y, rx, ry, w, c, FEraseMode, LinearAntialiasing)
|
---|
3310 | else
|
---|
3311 | DrawPolygonAntialias(ComputeEllipseContour(x,y,rx,ry),c,w);
|
---|
3312 | end;
|
---|
3313 |
|
---|
3314 | procedure TBGRADefaultBitmap.EllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF;
|
---|
3315 | c: TBGRAPixel; w: single);
|
---|
3316 | begin
|
---|
3317 | if (PenStyle = psClear) or (c.alpha = 0) or (w = 0) then exit;
|
---|
3318 | DrawPolygonAntialias(ComputeEllipseContour(AOrigin, AXAxis, AYAxis),c,w);
|
---|
3319 | end;
|
---|
3320 |
|
---|
3321 | procedure TBGRADefaultBitmap.EllipseAntialias(x, y, rx, ry: single;
|
---|
3322 | texture: IBGRAScanner; w: single);
|
---|
3323 | begin
|
---|
3324 | if (PenStyle = psClear) or (w = 0) then exit;
|
---|
3325 | if (PenStyle = psSolid) then
|
---|
3326 | BGRAPolygon.BorderEllipseAntialiasWithTexture(self, x, y, rx, ry, w, texture, LinearAntialiasing)
|
---|
3327 | else
|
---|
3328 | DrawPolygonAntialias(ComputeEllipseContour(x,y,rx,ry),texture,w);
|
---|
3329 | end;
|
---|
3330 |
|
---|
3331 | procedure TBGRADefaultBitmap.EllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF;
|
---|
3332 | texture: IBGRAScanner; w: single);
|
---|
3333 | begin
|
---|
3334 | if (PenStyle = psClear) or (w = 0) then exit;
|
---|
3335 | DrawPolygonAntialias(ComputeEllipseContour(AOrigin, AXAxis, AYAxis),texture,w);
|
---|
3336 | end;
|
---|
3337 |
|
---|
3338 | procedure TBGRADefaultBitmap.EllipseAntialias(x, y, rx, ry: single;
|
---|
3339 | c: TBGRAPixel; w: single; back: TBGRAPixel);
|
---|
3340 | var multi: TBGRAMultishapeFiller;
|
---|
3341 | hw: single;
|
---|
3342 | begin
|
---|
3343 | if (w=0) or (PenStyle = psClear) or (c.alpha = 0) then
|
---|
3344 | begin
|
---|
3345 | FillEllipseAntialias(x, y, rx, ry, back);
|
---|
3346 | exit;
|
---|
3347 | end;
|
---|
3348 | rx := abs(rx);
|
---|
3349 | ry := abs(ry);
|
---|
3350 | hw := w/2;
|
---|
3351 | if (rx <= hw) or (ry <= hw) then
|
---|
3352 | begin
|
---|
3353 | FillEllipseAntialias(x,y,rx+hw,ry+hw,c);
|
---|
3354 | exit;
|
---|
3355 | end;
|
---|
3356 | { use multishape filler for fine junction between polygons }
|
---|
3357 | multi := TBGRAMultishapeFiller.Create;
|
---|
3358 | if (PenStyle = psSolid) then
|
---|
3359 | begin
|
---|
3360 | if back.alpha <> 0 then multi.AddEllipse(x,y,rx-hw,ry-hw,back);
|
---|
3361 | multi.AddEllipseBorder(x,y,rx,ry,w,c)
|
---|
3362 | end
|
---|
3363 | else
|
---|
3364 | begin
|
---|
3365 | if back.alpha <> 0 then multi.AddEllipse(x,y,rx,ry,back);
|
---|
3366 | multi.AddPolygon(ComputeWidePolygon(ComputeEllipseContour(x,y,rx,ry),w),c);
|
---|
3367 | end;
|
---|
3368 | multi.PolygonOrder := poLastOnTop;
|
---|
3369 | multi.Draw(self);
|
---|
3370 | multi.Free;
|
---|
3371 | end;
|
---|
3372 |
|
---|
3373 | procedure TBGRADefaultBitmap.EllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF;
|
---|
3374 | c: TBGRAPixel; w: single; back: TBGRAPixel);
|
---|
3375 | var multi: TBGRAMultishapeFiller;
|
---|
3376 | pts: ArrayOfTPointF;
|
---|
3377 | begin
|
---|
3378 | if (w=0) or (PenStyle = psClear) or (c.alpha = 0) then
|
---|
3379 | begin
|
---|
3380 | FillEllipseAntialias(AOrigin, AXAxis, AYAxis, back);
|
---|
3381 | exit;
|
---|
3382 | end;
|
---|
3383 | { use multishape filler for fine junction between polygons }
|
---|
3384 | multi := TBGRAMultishapeFiller.Create;
|
---|
3385 | pts := ComputeEllipseContour(AOrigin, AXAxis, AYAxis);
|
---|
3386 | if back.alpha <> 0 then multi.AddPolygon(pts, back);
|
---|
3387 | pts := ComputeWidePolygon(pts,w);
|
---|
3388 | multi.AddPolygon(pts,c);
|
---|
3389 | multi.PolygonOrder := poLastOnTop;
|
---|
3390 | multi.Draw(self);
|
---|
3391 | multi.Free;
|
---|
3392 | end;
|
---|
3393 |
|
---|
3394 | procedure TBGRADefaultBitmap.FillEllipseAntialias(x, y, rx, ry: single; c: TBGRAPixel);
|
---|
3395 | begin
|
---|
3396 | BGRAPolygon.FillEllipseAntialias(self, x, y, rx, ry, c, FEraseMode, LinearAntialiasing);
|
---|
3397 | end;
|
---|
3398 |
|
---|
3399 | procedure TBGRADefaultBitmap.FillEllipseAntialias(AOrigin, AXAxis,
|
---|
3400 | AYAxis: TPointF; c: TBGRAPixel);
|
---|
3401 | var
|
---|
3402 | pts: array of TPointF;
|
---|
3403 | begin
|
---|
3404 | if c.alpha = 0 then exit;
|
---|
3405 | pts := ComputeEllipseContour(AOrigin,AXAxis,AYAxis);
|
---|
3406 | FillPolyAntialias(pts, c);
|
---|
3407 | end;
|
---|
3408 |
|
---|
3409 | procedure TBGRADefaultBitmap.FillEllipseAntialias(x, y, rx, ry: single;
|
---|
3410 | texture: IBGRAScanner);
|
---|
3411 | begin
|
---|
3412 | BGRAPolygon.FillEllipseAntialiasWithTexture(self, x, y, rx, ry, texture, LinearAntialiasing);
|
---|
3413 | end;
|
---|
3414 |
|
---|
3415 | procedure TBGRADefaultBitmap.FillEllipseAntialias(AOrigin, AXAxis,
|
---|
3416 | AYAxis: TPointF; texture: IBGRAScanner);
|
---|
3417 | var
|
---|
3418 | pts: array of TPointF;
|
---|
3419 | begin
|
---|
3420 | pts := ComputeEllipseContour(AOrigin,AXAxis,AYAxis);
|
---|
3421 | FillPolyAntialias(pts, texture);
|
---|
3422 | end;
|
---|
3423 |
|
---|
3424 | procedure TBGRADefaultBitmap.FillEllipseLinearColorAntialias(x, y, rx,
|
---|
3425 | ry: single; outercolor, innercolor: TBGRAPixel);
|
---|
3426 | var
|
---|
3427 | grad: TBGRAGradientScanner;
|
---|
3428 | affine: TBGRAAffineScannerTransform;
|
---|
3429 | begin
|
---|
3430 | if (rx=0) or (ry=0) then exit;
|
---|
3431 | if rx=ry then
|
---|
3432 | begin
|
---|
3433 | grad := TBGRAGradientScanner.Create(innercolor,outercolor,gtRadial,PointF(x,y),PointF(x+rx,y),True);
|
---|
3434 | FillEllipseAntialias(x,y,rx,ry,grad);
|
---|
3435 | grad.Free;
|
---|
3436 | end else
|
---|
3437 | begin
|
---|
3438 | grad := TBGRAGradientScanner.Create(innercolor,outercolor,gtRadial,PointF(0,0),PointF(1,0),True);
|
---|
3439 | affine := TBGRAAffineScannerTransform.Create(grad);
|
---|
3440 | affine.Scale(rx,ry);
|
---|
3441 | affine.Translate(x,y);
|
---|
3442 | FillEllipseAntialias(x,y,rx,ry,affine);
|
---|
3443 | affine.Free;
|
---|
3444 | grad.Free;
|
---|
3445 | end;
|
---|
3446 | end;
|
---|
3447 |
|
---|
3448 | procedure TBGRADefaultBitmap.FillEllipseLinearColorAntialias(AOrigin, AXAxis,
|
---|
3449 | AYAxis: TPointF; outercolor, innercolor: TBGRAPixel);
|
---|
3450 | var
|
---|
3451 | grad: TBGRAGradientScanner;
|
---|
3452 | affine: TBGRAAffineScannerTransform;
|
---|
3453 | begin
|
---|
3454 | grad := TBGRAGradientScanner.Create(innercolor,outercolor,gtRadial,PointF(0,0),PointF(1,0),True);
|
---|
3455 | affine := TBGRAAffineScannerTransform.Create(grad);
|
---|
3456 | affine.Fit(AOrigin,AXAxis,AYAxis);
|
---|
3457 | FillEllipseAntialias(AOrigin,AXAxis,AYAxis,affine);
|
---|
3458 | affine.Free;
|
---|
3459 | grad.Free;
|
---|
3460 | end;
|
---|
3461 |
|
---|
3462 | procedure TBGRADefaultBitmap.EraseEllipseAntialias(x, y, rx, ry: single; alpha: byte);
|
---|
3463 | begin
|
---|
3464 | FEraseMode := True;
|
---|
3465 | FillEllipseAntialias(x, y, rx, ry, BGRA(0, 0, 0, alpha));
|
---|
3466 | FEraseMode := False;
|
---|
3467 | end;
|
---|
3468 |
|
---|
3469 | procedure TBGRADefaultBitmap.EraseEllipseAntialias(AOrigin, AXAxis,
|
---|
3470 | AYAxis: TPointF; alpha: byte);
|
---|
3471 | begin
|
---|
3472 | FEraseMode := True;
|
---|
3473 | FillEllipseAntialias(AOrigin, AXAxis, AYAxis, BGRA(0, 0, 0, alpha));
|
---|
3474 | FEraseMode := False;
|
---|
3475 | end;
|
---|
3476 |
|
---|
3477 | procedure TBGRADefaultBitmap.RectangleAntialias(x, y, x2, y2: single;
|
---|
3478 | c: TBGRAPixel; w: single; back: TBGRAPixel);
|
---|
3479 | var
|
---|
3480 | bevel: single;
|
---|
3481 | multi: TBGRAMultishapeFiller;
|
---|
3482 | hw: single;
|
---|
3483 | begin
|
---|
3484 | if (PenStyle = psClear) or (c.alpha=0) or (w=0) then
|
---|
3485 | begin
|
---|
3486 | if back <> BGRAPixelTransparent then
|
---|
3487 | FillRectAntialias(x,y,x2,y2,back);
|
---|
3488 | exit;
|
---|
3489 | end;
|
---|
3490 |
|
---|
3491 | hw := w/2;
|
---|
3492 | if not CheckAntialiasRectBounds(x,y,x2,y2,w) then
|
---|
3493 | begin
|
---|
3494 | if JoinStyle = pjsBevel then
|
---|
3495 | begin
|
---|
3496 | bevel := (2-sqrt(2))*hw;
|
---|
3497 | FillRoundRectAntialias(x - hw, y - hw, x2 + hw, y2 + hw, bevel,bevel, c, [rrTopLeftBevel, rrTopRightBevel, rrBottomLeftBevel, rrBottomRightBevel]);
|
---|
3498 | end else
|
---|
3499 | if JoinStyle = pjsRound then
|
---|
3500 | FillRoundRectAntialias(x - hw, y - hw, x2 + hw, y2 + hw, hw,hw, c)
|
---|
3501 | else
|
---|
3502 | FillRectAntialias(x - hw, y - hw, x2 + hw, y2 + hw, c);
|
---|
3503 | exit;
|
---|
3504 | end;
|
---|
3505 |
|
---|
3506 | { use multishape filler for fine junction between polygons }
|
---|
3507 | multi := TBGRAMultishapeFiller.Create;
|
---|
3508 | multi.FillMode := FillMode;
|
---|
3509 | if (JoinStyle = pjsMiter) and (PenStyle = psSolid) then
|
---|
3510 | multi.AddRectangleBorder(x,y,x2,y2,w,c)
|
---|
3511 | else
|
---|
3512 | multi.AddPolygon(ComputeWidePolygon([Pointf(x,y),Pointf(x2,y),Pointf(x2,y2),Pointf(x,y2)],w),c);
|
---|
3513 |
|
---|
3514 | if (frac(x + hw) = 0.5) and (frac(y + hw)=0.5) and (frac(x2 - hw)=0.5) and (frac(y2 - hw)=0.5) then
|
---|
3515 | FillRect(ceil(x + hw), ceil(y + hw), ceil(x2 - hw), ceil(y2 - hw), back, dmDrawWithTransparency)
|
---|
3516 | else
|
---|
3517 | multi.AddRectangle(x + hw, y + hw, x2 - hw, y2 - hw, back);
|
---|
3518 | multi.Draw(self);
|
---|
3519 | multi.Free;
|
---|
3520 | end;
|
---|
3521 |
|
---|
3522 | procedure TBGRADefaultBitmap.RectangleAntialias(x, y, x2, y2: single;
|
---|
3523 | texture: IBGRAScanner; w: single);
|
---|
3524 | var
|
---|
3525 | bevel,hw: single;
|
---|
3526 | multi: TBGRAMultishapeFiller;
|
---|
3527 | begin
|
---|
3528 | if (PenStyle = psClear) or (w=0) then exit;
|
---|
3529 |
|
---|
3530 | hw := w/2;
|
---|
3531 | if not CheckAntialiasRectBounds(x,y,x2,y2,w) then
|
---|
3532 | begin
|
---|
3533 | if JoinStyle = pjsBevel then
|
---|
3534 | begin
|
---|
3535 | bevel := (2-sqrt(2))*hw;
|
---|
3536 | FillRoundRectAntialias(x - hw, y - hw, x2 + hw, y2 + hw, bevel,bevel, texture, [rrTopLeftBevel, rrTopRightBevel, rrBottomLeftBevel, rrBottomRightBevel]);
|
---|
3537 | end else
|
---|
3538 | if JoinStyle = pjsRound then
|
---|
3539 | FillRoundRectAntialias(x - hw, y - hw, x2 + hw, y2 + hw, hw,hw, texture)
|
---|
3540 | else
|
---|
3541 | FillRectAntialias(x - hw, y - hw, x2 + hw, y2 + hw, texture);
|
---|
3542 | exit;
|
---|
3543 | end;
|
---|
3544 |
|
---|
3545 | { use multishape filler for fine junction between polygons }
|
---|
3546 | multi := TBGRAMultishapeFiller.Create;
|
---|
3547 | multi.FillMode := FillMode;
|
---|
3548 | if (JoinStyle = pjsMiter) and (PenStyle = psSolid) then
|
---|
3549 | multi.AddRectangleBorder(x,y,x2,y2,w, texture)
|
---|
3550 | else
|
---|
3551 | multi.AddPolygon(ComputeWidePolygon([Pointf(x,y),Pointf(x2,y),Pointf(x2,y2),Pointf(x,y2)],w), texture);
|
---|
3552 | multi.Draw(self);
|
---|
3553 | multi.Free;
|
---|
3554 | end;
|
---|
3555 |
|
---|
3556 | procedure TBGRADefaultBitmap.RoundRectAntialias(x, y, x2, y2, rx, ry: single;
|
---|
3557 | c: TBGRAPixel; w: single; options: TRoundRectangleOptions);
|
---|
3558 | begin
|
---|
3559 | if (PenStyle = psClear) or (c.alpha = 0) then exit;
|
---|
3560 | if (PenStyle = psSolid) then
|
---|
3561 | BGRAPolygon.BorderRoundRectangleAntialias(self,x,y,x2,y2,rx,ry,w,options,c,False, LinearAntialiasing)
|
---|
3562 | else
|
---|
3563 | DrawPolygonAntialias(BGRAPath.ComputeRoundRect(x,y,x2,y2,rx,ry,options),c,w);
|
---|
3564 | end;
|
---|
3565 |
|
---|
3566 | procedure TBGRADefaultBitmap.RoundRectAntialias(x, y, x2, y2, rx, ry: single;
|
---|
3567 | pencolor: TBGRAPixel; w: single; fillcolor: TBGRAPixel;
|
---|
3568 | options: TRoundRectangleOptions);
|
---|
3569 | var
|
---|
3570 | multi: TBGRAMultishapeFiller;
|
---|
3571 | begin
|
---|
3572 | if (PenStyle = psClear) or (pencolor.alpha = 0) then
|
---|
3573 | begin
|
---|
3574 | FillRoundRectAntialias(x,y,x2,y2,rx,ry,fillColor,options);
|
---|
3575 | exit;
|
---|
3576 | end;
|
---|
3577 | if (PenStyle = psSolid) then
|
---|
3578 | BGRAPolygon.BorderAndFillRoundRectangleAntialias(self,x,y,x2,y2,rx,ry,w,options,pencolor,fillcolor,nil,nil,False)
|
---|
3579 | else
|
---|
3580 | begin
|
---|
3581 | multi := TBGRAMultishapeFiller.Create;
|
---|
3582 | multi.PolygonOrder := poLastOnTop;
|
---|
3583 | multi.AddRoundRectangle(x,y,x2,y2,rx,ry,fillColor,options);
|
---|
3584 | multi.AddPolygon(ComputeWidePolygon(BGRAPath.ComputeRoundRect(x,y,x2,y2,rx,ry,options),w),pencolor);
|
---|
3585 | multi.Draw(self);
|
---|
3586 | multi.Free;
|
---|
3587 | end;
|
---|
3588 | end;
|
---|
3589 |
|
---|
3590 | procedure TBGRADefaultBitmap.RoundRectAntialias(x, y, x2, y2, rx, ry: single;
|
---|
3591 | penTexture: IBGRAScanner; w: single; fillTexture: IBGRAScanner;
|
---|
3592 | options: TRoundRectangleOptions);
|
---|
3593 | var
|
---|
3594 | multi: TBGRAMultishapeFiller;
|
---|
3595 | begin
|
---|
3596 | if (PenStyle = psClear) then
|
---|
3597 | begin
|
---|
3598 | FillRoundRectAntialias(x,y,x2,y2,rx,ry,fillTexture,options);
|
---|
3599 | exit;
|
---|
3600 | end else
|
---|
3601 | if (PenStyle = psSolid) then
|
---|
3602 | BGRAPolygon.BorderAndFillRoundRectangleAntialias(self,x,y,x2,y2,rx,ry,w,options,BGRAPixelTransparent,BGRAPixelTransparent,pentexture,filltexture,False)
|
---|
3603 | else
|
---|
3604 | begin
|
---|
3605 | multi := TBGRAMultishapeFiller.Create;
|
---|
3606 | multi.PolygonOrder := poLastOnTop;
|
---|
3607 | multi.AddRoundRectangle(x,y,x2,y2,rx,ry,fillTexture,options);
|
---|
3608 | multi.AddPolygon(ComputeWidePolygon(ComputeRoundRect(x,y,x2,y2,rx,ry,options),w),penTexture);
|
---|
3609 | multi.Draw(self);
|
---|
3610 | multi.Free;
|
---|
3611 | end;
|
---|
3612 | end;
|
---|
3613 |
|
---|
3614 | procedure TBGRADefaultBitmap.RoundRectAntialias(x, y, x2, y2, rx, ry: single;
|
---|
3615 | texture: IBGRAScanner; w: single; options: TRoundRectangleOptions);
|
---|
3616 | begin
|
---|
3617 | if (PenStyle = psClear) then exit;
|
---|
3618 | if (PenStyle = psSolid) then
|
---|
3619 | BGRAPolygon.BorderRoundRectangleAntialiasWithTexture(self,x,y,x2,y2,rx,ry,w,options,texture, LinearAntialiasing)
|
---|
3620 | else
|
---|
3621 | DrawPolygonAntialias(BGRAPath.ComputeRoundRect(x,y,x2,y2,rx,ry,options),texture,w);
|
---|
3622 | end;
|
---|
3623 |
|
---|
3624 | function TBGRADefaultBitmap.CheckRectBounds(var x, y, x2, y2: integer; minsize: integer): boolean; inline;
|
---|
3625 | var
|
---|
3626 | temp: integer;
|
---|
3627 | begin
|
---|
3628 | //swap coordinates if needed
|
---|
3629 | if (x > x2) then
|
---|
3630 | begin
|
---|
3631 | temp := x;
|
---|
3632 | x := x2;
|
---|
3633 | x2 := temp;
|
---|
3634 | end;
|
---|
3635 | if (y > y2) then
|
---|
3636 | begin
|
---|
3637 | temp := y;
|
---|
3638 | y := y2;
|
---|
3639 | y2 := temp;
|
---|
3640 | end;
|
---|
3641 | if (x2 - x <= minsize) or (y2 - y <= minsize) then
|
---|
3642 | begin
|
---|
3643 | result := false;
|
---|
3644 | exit;
|
---|
3645 | end else
|
---|
3646 | result := true;
|
---|
3647 | end;
|
---|
3648 |
|
---|
3649 | procedure TBGRADefaultBitmap.Rectangle(x, y, x2, y2: integer;
|
---|
3650 | c: TBGRAPixel; mode: TDrawMode);
|
---|
3651 | begin
|
---|
3652 | if not CheckRectBounds(x,y,x2,y2,1) then exit;
|
---|
3653 | case mode of
|
---|
3654 | dmFastBlend:
|
---|
3655 | begin
|
---|
3656 | FastBlendHorizLine(x, y, x2 - 1, c);
|
---|
3657 | FastBlendHorizLine(x, y2 - 1, x2 - 1, c);
|
---|
3658 | if y2 - y > 2 then
|
---|
3659 | begin
|
---|
3660 | FastBlendVertLine(x, y + 1, y2 - 2, c);
|
---|
3661 | FastBlendVertLine(x2 - 1, y + 1, y2 - 2, c);
|
---|
3662 | end;
|
---|
3663 | end;
|
---|
3664 | dmDrawWithTransparency:
|
---|
3665 | begin
|
---|
3666 | DrawHorizLine(x, y, x2 - 1, c);
|
---|
3667 | DrawHorizLine(x, y2 - 1, x2 - 1, c);
|
---|
3668 | if y2 - y > 2 then
|
---|
3669 | begin
|
---|
3670 | DrawVertLine(x, y + 1, y2 - 2, c);
|
---|
3671 | DrawVertLine(x2 - 1, y + 1, y2 - 2, c);
|
---|
3672 | end;
|
---|
3673 | end;
|
---|
3674 | dmSet:
|
---|
3675 | begin
|
---|
3676 | SetHorizLine(x, y, x2 - 1, c);
|
---|
3677 | SetHorizLine(x, y2 - 1, x2 - 1, c);
|
---|
3678 | if y2 - y > 2 then
|
---|
3679 | begin
|
---|
3680 | SetVertLine(x, y + 1, y2 - 2, c);
|
---|
3681 | SetVertLine(x2 - 1, y + 1, y2 - 2, c);
|
---|
3682 | end;
|
---|
3683 | end;
|
---|
3684 | dmXor:
|
---|
3685 | begin
|
---|
3686 | XorHorizLine(x, y, x2 - 1, c);
|
---|
3687 | XorHorizLine(x, y2 - 1, x2 - 1, c);
|
---|
3688 | if y2 - y > 2 then
|
---|
3689 | begin
|
---|
3690 | XorVertLine(x, y + 1, y2 - 2, c);
|
---|
3691 | XorVertLine(x2 - 1, y + 1, y2 - 2, c);
|
---|
3692 | end;
|
---|
3693 | end;
|
---|
3694 | dmSetExceptTransparent: if (c.alpha = 255) then
|
---|
3695 | Rectangle(x, y, x2, y2, c, dmSet);
|
---|
3696 | end;
|
---|
3697 | end;
|
---|
3698 |
|
---|
3699 | procedure TBGRADefaultBitmap.Rectangle(x, y, x2, y2: integer;
|
---|
3700 | BorderColor, FillColor: TBGRAPixel; mode: TDrawMode);
|
---|
3701 | begin
|
---|
3702 | if not CheckRectBounds(x,y,x2,y2,1) then exit;
|
---|
3703 | Rectangle(x, y, x2, y2, BorderColor, mode);
|
---|
3704 | FillRect(x + 1, y + 1, x2 - 1, y2 - 1, FillColor, mode);
|
---|
3705 | end;
|
---|
3706 |
|
---|
3707 | function TBGRADefaultBitmap.CheckClippedRectBounds(var x, y, x2, y2: integer): boolean; inline;
|
---|
3708 | var
|
---|
3709 | temp: integer;
|
---|
3710 | begin
|
---|
3711 | if (x > x2) then
|
---|
3712 | begin
|
---|
3713 | temp := x;
|
---|
3714 | x := x2;
|
---|
3715 | x2 := temp;
|
---|
3716 | end;
|
---|
3717 | if (y > y2) then
|
---|
3718 | begin
|
---|
3719 | temp := y;
|
---|
3720 | y := y2;
|
---|
3721 | y2 := temp;
|
---|
3722 | end;
|
---|
3723 | if (x >= FClipRect.Right) or (x2 <= FClipRect.Left) or (y >= FClipRect.Bottom) or (y2 <= FClipRect.Top) then
|
---|
3724 | begin
|
---|
3725 | result := false;
|
---|
3726 | exit;
|
---|
3727 | end;
|
---|
3728 | if x < FClipRect.Left then
|
---|
3729 | x := FClipRect.Left;
|
---|
3730 | if x2 > FClipRect.Right then
|
---|
3731 | x2 := FClipRect.Right;
|
---|
3732 | if y < FClipRect.Top then
|
---|
3733 | y := FClipRect.Top;
|
---|
3734 | if y2 > FClipRect.Bottom then
|
---|
3735 | y2 := FClipRect.Bottom;
|
---|
3736 | if (x2 - x <= 0) or (y2 - y <= 0) then
|
---|
3737 | begin
|
---|
3738 | result := false;
|
---|
3739 | exit;
|
---|
3740 | end else
|
---|
3741 | result := true;
|
---|
3742 | end;
|
---|
3743 |
|
---|
3744 | procedure TBGRADefaultBitmap.FillRect(x, y, x2, y2: integer; c: TBGRAPixel;
|
---|
3745 | mode: TDrawMode);
|
---|
3746 | var
|
---|
3747 | yb, tx, delta: integer;
|
---|
3748 | p: PBGRAPixel;
|
---|
3749 | begin
|
---|
3750 | if not CheckClippedRectBounds(x,y,x2,y2) then exit;
|
---|
3751 | tx := x2 - x;
|
---|
3752 | Dec(x2);
|
---|
3753 | Dec(y2);
|
---|
3754 |
|
---|
3755 | if mode = dmSetExceptTransparent then
|
---|
3756 | begin
|
---|
3757 | if (c.alpha = 255) then
|
---|
3758 | FillRect(x, y, x2, y2, c, dmSet);
|
---|
3759 | end else
|
---|
3760 | begin
|
---|
3761 | if (mode <> dmSet) and (mode <> dmXor) and (c.alpha = 0) then exit;
|
---|
3762 |
|
---|
3763 | p := Scanline[y] + x;
|
---|
3764 | if FLineOrder = riloBottomToTop then
|
---|
3765 | delta := -Width
|
---|
3766 | else
|
---|
3767 | delta := Width;
|
---|
3768 |
|
---|
3769 | case mode of
|
---|
3770 | dmFastBlend:
|
---|
3771 | for yb := y2 - y downto 0 do
|
---|
3772 | begin
|
---|
3773 | FastBlendPixelsInline(p, c, tx);
|
---|
3774 | Inc(p, delta);
|
---|
3775 | end;
|
---|
3776 | dmDrawWithTransparency:
|
---|
3777 | for yb := y2 - y downto 0 do
|
---|
3778 | begin
|
---|
3779 | DrawPixelsInline(p, c, tx);
|
---|
3780 | Inc(p, delta);
|
---|
3781 | end;
|
---|
3782 | dmSet:
|
---|
3783 | for yb := y2 - y downto 0 do
|
---|
3784 | begin
|
---|
3785 | FillInline(p, c, tx);
|
---|
3786 | Inc(p, delta);
|
---|
3787 | end;
|
---|
3788 | dmXor:
|
---|
3789 | if DWord(c) = 0 then exit
|
---|
3790 | else
|
---|
3791 | for yb := y2 - y downto 0 do
|
---|
3792 | begin
|
---|
3793 | XorInline(p, c, tx);
|
---|
3794 | Inc(p, delta);
|
---|
3795 | end;
|
---|
3796 | end;
|
---|
3797 |
|
---|
3798 | InvalidateBitmap;
|
---|
3799 | end;
|
---|
3800 | end;
|
---|
3801 |
|
---|
3802 | procedure TBGRADefaultBitmap.FillRect(x, y, x2, y2: integer;
|
---|
3803 | texture: IBGRAScanner; mode: TDrawMode; AScanOffset: TPoint);
|
---|
3804 | var
|
---|
3805 | yb, tx, delta: integer;
|
---|
3806 | p: PBGRAPixel;
|
---|
3807 | begin
|
---|
3808 | if not CheckClippedRectBounds(x,y,x2,y2) then exit;
|
---|
3809 | tx := x2 - x;
|
---|
3810 | Dec(x2);
|
---|
3811 | Dec(y2);
|
---|
3812 |
|
---|
3813 | p := Scanline[y] + x;
|
---|
3814 | if FLineOrder = riloBottomToTop then
|
---|
3815 | delta := -Width
|
---|
3816 | else
|
---|
3817 | delta := Width;
|
---|
3818 |
|
---|
3819 | for yb := y to y2 do
|
---|
3820 | begin
|
---|
3821 | texture.ScanMoveTo(x+AScanOffset.X,yb+AScanOffset.Y);
|
---|
3822 | ScannerPutPixels(texture, p, tx, mode);
|
---|
3823 | Inc(p, delta);
|
---|
3824 | end;
|
---|
3825 |
|
---|
3826 | InvalidateBitmap;
|
---|
3827 | end;
|
---|
3828 |
|
---|
3829 | procedure TBGRADefaultBitmap.FillRect(x, y, x2, y2: integer;
|
---|
3830 | texture: IBGRAScanner; mode: TDrawMode; AScanOffset: TPoint; ditheringAlgorithm: TDitheringAlgorithm);
|
---|
3831 | var dither: TDitheringTask;
|
---|
3832 | begin
|
---|
3833 | if not CheckClippedRectBounds(x,y,x2,y2) then exit;
|
---|
3834 | dither := CreateDitheringTask(ditheringAlgorithm, texture, self, rect(x,y,x2,y2));
|
---|
3835 | dither.ScanOffset := AScanOffset;
|
---|
3836 | dither.DrawMode := mode;
|
---|
3837 | dither.Execute;
|
---|
3838 | dither.Free;
|
---|
3839 | end;
|
---|
3840 |
|
---|
3841 | procedure TBGRADefaultBitmap.AlphaFillRect(x, y, x2, y2: integer; alpha: byte);
|
---|
3842 | var
|
---|
3843 | yb, tx, delta: integer;
|
---|
3844 | p: PBGRAPixel;
|
---|
3845 | begin
|
---|
3846 | if alpha = 0 then
|
---|
3847 | begin
|
---|
3848 | FillRect(x, y, x2, y2, BGRAPixelTransparent, dmSet);
|
---|
3849 | exit;
|
---|
3850 | end;
|
---|
3851 |
|
---|
3852 | if not CheckClippedRectBounds(x,y,x2,y2) then exit;
|
---|
3853 | tx := x2 - x;
|
---|
3854 | Dec(x2);
|
---|
3855 | Dec(y2);
|
---|
3856 |
|
---|
3857 | p := Scanline[y] + x;
|
---|
3858 | if FLineOrder = riloBottomToTop then
|
---|
3859 | delta := -Width
|
---|
3860 | else
|
---|
3861 | delta := Width;
|
---|
3862 | for yb := y2 - y downto 0 do
|
---|
3863 | begin
|
---|
3864 | AlphaFillInline(p, alpha, tx);
|
---|
3865 | Inc(p, delta);
|
---|
3866 | end;
|
---|
3867 | InvalidateBitmap;
|
---|
3868 | end;
|
---|
3869 |
|
---|
3870 | procedure TBGRADefaultBitmap.FillRectAntialias(x, y, x2, y2: single; c: TBGRAPixel; pixelCenteredCoordinates: boolean);
|
---|
3871 | var tx,ty: single;
|
---|
3872 | begin
|
---|
3873 | if not pixelCenteredCoordinates then
|
---|
3874 | begin
|
---|
3875 | x -= 0.5;
|
---|
3876 | y -= 0.5;
|
---|
3877 | x2 -= 0.5;
|
---|
3878 | y2 -= 0.5;
|
---|
3879 | end;
|
---|
3880 |
|
---|
3881 | tx := x2-x;
|
---|
3882 | ty := y2-y;
|
---|
3883 | if (abs(tx)<1e-3) or (abs(ty)<1e-3) then exit;
|
---|
3884 | if (abs(tx) > 2) and (abs(ty) > 2) then
|
---|
3885 | begin
|
---|
3886 | if (tx < 0) then
|
---|
3887 | begin
|
---|
3888 | tx := -tx;
|
---|
3889 | x := x2;
|
---|
3890 | x2 := x+tx;
|
---|
3891 | end;
|
---|
3892 | if (ty < 0) then
|
---|
3893 | begin
|
---|
3894 | ty := -ty;
|
---|
3895 | y := y2;
|
---|
3896 | y2 := y+ty;
|
---|
3897 | end;
|
---|
3898 | FillRectAntialias(x,y,x2,ceil(y)+0.5,c);
|
---|
3899 | FillRectAntialias(x,ceil(y)+0.5,ceil(x)+0.5,floor(y2)-0.5,c);
|
---|
3900 | FillRectAntialias(floor(x2)-0.5,ceil(y)+0.5,x2,floor(y2)-0.5,c);
|
---|
3901 | FillRectAntialias(x,floor(y2)-0.5,x2,y2,c);
|
---|
3902 | FillRect(ceil(x)+1,ceil(y)+1,floor(x2),floor(y2),c,dmDrawWithTransparency);
|
---|
3903 | end else
|
---|
3904 | FillPolyAntialias([pointf(x, y), pointf(x2, y), pointf(x2, y2), pointf(x, y2)], c);
|
---|
3905 | end;
|
---|
3906 |
|
---|
3907 | procedure TBGRADefaultBitmap.EraseRectAntialias(x, y, x2, y2: single;
|
---|
3908 | alpha: byte; pixelCenteredCoordinates: boolean);
|
---|
3909 | begin
|
---|
3910 | if not pixelCenteredCoordinates then
|
---|
3911 | begin
|
---|
3912 | x -= 0.5;
|
---|
3913 | y -= 0.5;
|
---|
3914 | x2 -= 0.5;
|
---|
3915 | y2 -= 0.5;
|
---|
3916 | end;
|
---|
3917 | ErasePolyAntialias([pointf(x, y), pointf(x2, y), pointf(x2, y2), pointf(x, y2)], alpha);
|
---|
3918 | end;
|
---|
3919 |
|
---|
3920 | procedure TBGRADefaultBitmap.FillRectAntialias(x, y, x2, y2: single;
|
---|
3921 | texture: IBGRAScanner; pixelCenteredCoordinates: boolean);
|
---|
3922 | begin
|
---|
3923 | if not pixelCenteredCoordinates then
|
---|
3924 | begin
|
---|
3925 | x -= 0.5;
|
---|
3926 | y -= 0.5;
|
---|
3927 | x2 -= 0.5;
|
---|
3928 | y2 -= 0.5;
|
---|
3929 | end;
|
---|
3930 | FillPolyAntialias([pointf(x, y), pointf(x2, y), pointf(x2, y2), pointf(x, y2)], texture);
|
---|
3931 | end;
|
---|
3932 |
|
---|
3933 | procedure TBGRADefaultBitmap.FillRoundRectAntialias(x, y, x2, y2, rx,ry: single;
|
---|
3934 | c: TBGRAPixel; options: TRoundRectangleOptions; pixelCenteredCoordinates: boolean);
|
---|
3935 | begin
|
---|
3936 | BGRAPolygon.FillRoundRectangleAntialias(self,x,y,x2,y2,rx,ry,options,c,False, LinearAntialiasing, pixelCenteredCoordinates);
|
---|
3937 | end;
|
---|
3938 |
|
---|
3939 | procedure TBGRADefaultBitmap.FillRoundRectAntialias(x, y, x2, y2, rx,
|
---|
3940 | ry: single; texture: IBGRAScanner; options: TRoundRectangleOptions; pixelCenteredCoordinates: boolean);
|
---|
3941 | begin
|
---|
3942 | BGRAPolygon.FillRoundRectangleAntialiasWithTexture(self,x,y,x2,y2,rx,ry,options,texture, LinearAntialiasing, pixelCenteredCoordinates);
|
---|
3943 | end;
|
---|
3944 |
|
---|
3945 | procedure TBGRADefaultBitmap.EraseRoundRectAntialias(x, y, x2, y2, rx,
|
---|
3946 | ry: single; alpha: byte; options: TRoundRectangleOptions; pixelCenteredCoordinates: boolean);
|
---|
3947 | begin
|
---|
3948 | BGRAPolygon.FillRoundRectangleAntialias(self,x,y,x2,y2,rx,ry,options,BGRA(0,0,0,alpha),True, LinearAntialiasing, pixelCenteredCoordinates);
|
---|
3949 | end;
|
---|
3950 |
|
---|
3951 | procedure TBGRADefaultBitmap.Ellipse(x, y, rx, ry: single; c: TBGRAPixel;
|
---|
3952 | w: single; ADrawMode: TDrawMode);
|
---|
3953 | begin
|
---|
3954 | if (PenStyle = psClear) or (c.alpha = 0) or (w = 0) then exit;
|
---|
3955 | if (PenStyle = psSolid) then
|
---|
3956 | BGRAPolygon.BorderEllipse(self, x, y, rx, ry, w, c, FEraseMode, ADrawMode)
|
---|
3957 | else
|
---|
3958 | FillPoly(ComputeWidePolygon(ComputeEllipseContour(x,y,rx,ry),w),c, ADrawMode);
|
---|
3959 | end;
|
---|
3960 |
|
---|
3961 | procedure TBGRADefaultBitmap.Ellipse(AOrigin, AXAxis, AYAxis: TPointF;
|
---|
3962 | c: TBGRAPixel; w: single; ADrawMode: TDrawMode);
|
---|
3963 | begin
|
---|
3964 | if (PenStyle = psClear) or (c.alpha = 0) or (w = 0) then exit;
|
---|
3965 | FillPoly(ComputeWidePolygon(ComputeEllipseContour(AOrigin, AXAxis, AYAxis),w),c,ADrawMode);
|
---|
3966 | end;
|
---|
3967 |
|
---|
3968 | procedure TBGRADefaultBitmap.RoundRect(X1, Y1, X2, Y2: integer;
|
---|
3969 | DX, DY: integer; BorderColor, FillColor: TBGRAPixel; ADrawMode: TDrawMode = dmDrawWithTransparency);
|
---|
3970 | begin
|
---|
3971 | BGRARoundRectAliased(self,X1,Y1,X2,Y2,DX,DY,BorderColor,FillColor,nil,ADrawMode);
|
---|
3972 | end;
|
---|
3973 |
|
---|
3974 | procedure TBGRADefaultBitmap.RoundRect(X1, Y1, X2, Y2: integer; DX,
|
---|
3975 | DY: integer; BorderColor: TBGRAPixel; ADrawMode: TDrawMode);
|
---|
3976 | begin
|
---|
3977 | BGRARoundRectAliased(self,X1,Y1,X2,Y2,DX,DY,BorderColor,BGRAPixelTransparent,nil,ADrawMode,true);
|
---|
3978 | end;
|
---|
3979 |
|
---|
3980 | procedure TBGRADefaultBitmap.FillRoundRect(X1, Y1, X2, Y2: integer; DX,
|
---|
3981 | DY: integer; FillTexture: IBGRAScanner; ADrawMode: TDrawMode);
|
---|
3982 | begin
|
---|
3983 | BGRAFillRoundRectAliased(self,X1,Y1,X2,Y2,DX,DY,BGRAPixelTransparent,FillTexture,ADrawMode);
|
---|
3984 | end;
|
---|
3985 |
|
---|
3986 | {------------------------- Text functions ---------------------------------------}
|
---|
3987 |
|
---|
3988 | procedure TBGRADefaultBitmap.TextOutAngle(x, y: single; orientationTenthDegCCW: integer;
|
---|
3989 | sUTF8: string; c: TBGRAPixel; align: TAlignment);
|
---|
3990 | begin
|
---|
3991 | with (PointF(x,y)-GetFontAnchorRotatedOffset(orientationTenthDegCCW)) do
|
---|
3992 | FontRenderer.TextOutAngle(self,x,y,orientationTenthDegCCW,CleanTextOutString(sUTF8),c,align);
|
---|
3993 | end;
|
---|
3994 |
|
---|
3995 | procedure TBGRADefaultBitmap.TextOutAngle(x, y: single; orientationTenthDegCCW: integer;
|
---|
3996 | sUTF8: string; texture: IBGRAScanner; align: TAlignment);
|
---|
3997 | begin
|
---|
3998 | with (PointF(x,y)-GetFontAnchorRotatedOffset(orientationTenthDegCCW)) do
|
---|
3999 | FontRenderer.TextOutAngle(self,x,y,orientationTenthDegCCW,CleanTextOutString(sUTF8),texture,align);
|
---|
4000 | end;
|
---|
4001 |
|
---|
4002 | procedure TBGRADefaultBitmap.TextOutCurved(ACursor: TBGRACustomPathCursor; sUTF8: string; AColor: TBGRAPixel; AAlign: TAlignment; ALetterSpacing: single);
|
---|
4003 | begin
|
---|
4004 | InternalTextOutCurved(ACursor, sUTF8, AColor, nil, AAlign, ALetterSpacing);
|
---|
4005 | end;
|
---|
4006 |
|
---|
4007 | procedure TBGRADefaultBitmap.TextOutCurved(ACursor: TBGRACustomPathCursor; sUTF8: string; ATexture: IBGRAScanner; AAlign: TAlignment; ALetterSpacing: single);
|
---|
4008 | begin
|
---|
4009 | InternalTextOutCurved(ACursor, sUTF8, BGRAPixelTransparent, ATexture, AAlign, ALetterSpacing);
|
---|
4010 | end;
|
---|
4011 |
|
---|
4012 | procedure TBGRADefaultBitmap.TextMultiline(ALeft, ATop, AWidth: single; sUTF8: string;
|
---|
4013 | c: TBGRAPixel; AAlign: TBidiTextAlignment; AVertAlign: TTextLayout; AParagraphSpacing: single);
|
---|
4014 | var
|
---|
4015 | layout: TBidiTextLayout;
|
---|
4016 | i: Integer;
|
---|
4017 | begin
|
---|
4018 | if FontBidiMode = fbmAuto then
|
---|
4019 | layout := TBidiTextLayout.Create(FontRenderer, sUTF8)
|
---|
4020 | else
|
---|
4021 | layout := TBidiTextLayout.Create(FontRenderer, sUTF8, GetFontRightToLeftFor(sUTF8));
|
---|
4022 | for i := 0 to layout.ParagraphCount-1 do
|
---|
4023 | layout.ParagraphAlignment[i] := AAlign;
|
---|
4024 | layout.ParagraphSpacingBelow:= AParagraphSpacing;
|
---|
4025 | layout.AvailableWidth := AWidth;
|
---|
4026 | case AVertAlign of
|
---|
4027 | tlBottom: layout.TopLeft := PointF(ALeft,ATop-layout.TotalTextHeight);
|
---|
4028 | tlCenter: layout.TopLeft := PointF(ALeft,ATop-layout.TotalTextHeight/2);
|
---|
4029 | else layout.TopLeft := PointF(ALeft,ATop);
|
---|
4030 | end;
|
---|
4031 | layout.DrawText(self, c);
|
---|
4032 | layout.Free;
|
---|
4033 | end;
|
---|
4034 |
|
---|
4035 | procedure TBGRADefaultBitmap.TextMultiline(ALeft, ATop, AWidth: single;
|
---|
4036 | sUTF8: string; ATexture: IBGRAScanner; AAlign: TBidiTextAlignment;
|
---|
4037 | AVertAlign: TTextLayout; AParagraphSpacing: single);
|
---|
4038 | var
|
---|
4039 | layout: TBidiTextLayout;
|
---|
4040 | i: Integer;
|
---|
4041 | begin
|
---|
4042 | if FontBidiMode = fbmAuto then
|
---|
4043 | layout := TBidiTextLayout.Create(FontRenderer, sUTF8)
|
---|
4044 | else
|
---|
4045 | layout := TBidiTextLayout.Create(FontRenderer, sUTF8, GetFontRightToLeftFor(sUTF8));
|
---|
4046 | for i := 0 to layout.ParagraphCount-1 do
|
---|
4047 | layout.ParagraphAlignment[i] := AAlign;
|
---|
4048 | layout.ParagraphSpacingBelow:= AParagraphSpacing;
|
---|
4049 | layout.AvailableWidth := AWidth;
|
---|
4050 | case AVertAlign of
|
---|
4051 | tlBottom: layout.TopLeft := PointF(ALeft,ATop-layout.TotalTextHeight);
|
---|
4052 | tlCenter: layout.TopLeft := PointF(ALeft,ATop-layout.TotalTextHeight/2);
|
---|
4053 | else layout.TopLeft := PointF(ALeft,ATop);
|
---|
4054 | end;
|
---|
4055 | layout.DrawText(self, ATexture);
|
---|
4056 | layout.Free;
|
---|
4057 | end;
|
---|
4058 |
|
---|
4059 | procedure TBGRADefaultBitmap.TextOut(x, y: single; sUTF8: string;
|
---|
4060 | texture: IBGRAScanner; align: TAlignment; ARightToLeft: boolean);
|
---|
4061 | begin
|
---|
4062 | FontRenderer.TextOut(self,x,y,CleanTextOutString(sUTF8),texture,align, ARightToLeft);
|
---|
4063 | end;
|
---|
4064 |
|
---|
4065 | procedure TBGRADefaultBitmap.TextOut(x, y: single; sUTF8: string;
|
---|
4066 | c: TBGRAPixel; align: TAlignment; ARightToLeft: boolean);
|
---|
4067 | begin
|
---|
4068 | with (PointF(x,y)-GetFontAnchorRotatedOffset) do
|
---|
4069 | FontRenderer.TextOut(self,x,y,CleanTextOutString(sUTF8),c,align, ARightToLeft);
|
---|
4070 | end;
|
---|
4071 |
|
---|
4072 | procedure TBGRADefaultBitmap.TextRect(ARect: TRect; x, y: integer;
|
---|
4073 | sUTF8: string; style: TTextStyle; c: TBGRAPixel);
|
---|
4074 | begin
|
---|
4075 | with (PointF(x,y)-GetFontAnchorRotatedOffset(0)) do
|
---|
4076 | FontRenderer.TextRect(self,ARect,system.round(x),system.round(y),sUTF8,style,c);
|
---|
4077 | end;
|
---|
4078 |
|
---|
4079 | procedure TBGRADefaultBitmap.TextRect(ARect: TRect; x, y: integer; sUTF8: string;
|
---|
4080 | style: TTextStyle; texture: IBGRAScanner);
|
---|
4081 | begin
|
---|
4082 | with (PointF(x,y)-GetFontAnchorRotatedOffset(0)) do
|
---|
4083 | FontRenderer.TextRect(self,ARect,system.round(x),system.round(y),sUTF8,style,texture);
|
---|
4084 | end;
|
---|
4085 |
|
---|
4086 | { Returns the total size of the string provided using the current font.
|
---|
4087 | Orientation is not taken into account, so that the width is along the text. }
|
---|
4088 | function TBGRADefaultBitmap.TextSize(sUTF8: string): TSize;
|
---|
4089 | begin
|
---|
4090 | result := FontRenderer.TextSize(CleanTextOutString(sUTF8));
|
---|
4091 | end;
|
---|
4092 |
|
---|
4093 | function TBGRADefaultBitmap.TextAffineBox(sUTF8: string): TAffineBox;
|
---|
4094 | var size: TSize;
|
---|
4095 | m: TAffineMatrix;
|
---|
4096 | dy: single;
|
---|
4097 | begin
|
---|
4098 | dy := GetFontVerticalAnchorOffset;
|
---|
4099 | size := FontRenderer.TextSizeAngle(sUTF8, FontOrientation);
|
---|
4100 | m := AffineMatrixRotationDeg(-FontOrientation*0.1);
|
---|
4101 | result := TAffineBox.AffineBox(PointF(0,-dy), m*PointF(size.cx,-dy), m*PointF(0,size.cy-dy));
|
---|
4102 | end;
|
---|
4103 |
|
---|
4104 | function TBGRADefaultBitmap.TextSize(sUTF8: string; AMaxWidth: integer): TSize;
|
---|
4105 | begin
|
---|
4106 | result := FontRenderer.TextSize(sUTF8, AMaxWidth, GetFontRightToLeftFor(sUTF8));
|
---|
4107 | end;
|
---|
4108 |
|
---|
4109 | function TBGRADefaultBitmap.TextSize(sUTF8: string; AMaxWidth: integer;
|
---|
4110 | ARightToLeft: boolean): TSize;
|
---|
4111 | begin
|
---|
4112 | result := FontRenderer.TextSize(sUTF8, AMaxWidth, ARightToLeft);
|
---|
4113 | end;
|
---|
4114 |
|
---|
4115 | function TBGRADefaultBitmap.TextFitInfo(sUTF8: string; AMaxWidth: integer
|
---|
4116 | ): integer;
|
---|
4117 | begin
|
---|
4118 | result := FontRenderer.TextFitInfo(sUTF8, AMaxWidth);
|
---|
4119 | end;
|
---|
4120 |
|
---|
4121 | {---------------------------- Curves ----------------------------------------}
|
---|
4122 |
|
---|
4123 | function TBGRADefaultBitmap.ComputeClosedSpline(const APoints: array of TPointF; AStyle: TSplineStyle): ArrayOfTPointF;
|
---|
4124 | begin
|
---|
4125 | result := BGRAPath.ComputeClosedSpline(APoints, AStyle);
|
---|
4126 | end;
|
---|
4127 |
|
---|
4128 | function TBGRADefaultBitmap.ComputeOpenedSpline(const APoints: array of TPointF; AStyle: TSplineStyle): ArrayOfTPointF;
|
---|
4129 | begin
|
---|
4130 | result := BGRAPath.ComputeOpenedSpline(APoints, AStyle);
|
---|
4131 | end;
|
---|
4132 |
|
---|
4133 | function TBGRADefaultBitmap.ComputeBezierCurve(const ACurve: TCubicBezierCurve
|
---|
4134 | ): ArrayOfTPointF;
|
---|
4135 | begin
|
---|
4136 | Result:= BGRAPath.ComputeBezierCurve(ACurve);
|
---|
4137 | end;
|
---|
4138 |
|
---|
4139 | function TBGRADefaultBitmap.ComputeBezierCurve(
|
---|
4140 | const ACurve: TQuadraticBezierCurve): ArrayOfTPointF;
|
---|
4141 | begin
|
---|
4142 | Result:= BGRAPath.ComputeBezierCurve(ACurve);
|
---|
4143 | end;
|
---|
4144 |
|
---|
4145 | function TBGRADefaultBitmap.ComputeBezierSpline(
|
---|
4146 | const ASpline: array of TCubicBezierCurve): ArrayOfTPointF;
|
---|
4147 | begin
|
---|
4148 | Result:= BGRAPath.ComputeBezierSpline(ASpline);
|
---|
4149 | end;
|
---|
4150 |
|
---|
4151 | function TBGRADefaultBitmap.ComputeBezierSpline(
|
---|
4152 | const ASpline: array of TQuadraticBezierCurve): ArrayOfTPointF;
|
---|
4153 | begin
|
---|
4154 | Result:= BGRAPath.ComputeBezierSpline(ASpline);
|
---|
4155 | end;
|
---|
4156 |
|
---|
4157 | function TBGRADefaultBitmap.ComputeWidePolyline(const points: array of TPointF;
|
---|
4158 | w: single): ArrayOfTPointF;
|
---|
4159 | begin
|
---|
4160 | result := FPenStroker.ComputePolyline(points,w);
|
---|
4161 | end;
|
---|
4162 |
|
---|
4163 | function TBGRADefaultBitmap.ComputeWidePolyline(const points: array of TPointF;
|
---|
4164 | w: single; ClosedCap: boolean): ArrayOfTPointF;
|
---|
4165 | begin
|
---|
4166 | result := FPenStroker.ComputePolyline(points,w,ClosedCap);
|
---|
4167 | end;
|
---|
4168 |
|
---|
4169 | function TBGRADefaultBitmap.ComputeWidePolygon(const points: array of TPointF;
|
---|
4170 | w: single): ArrayOfTPointF;
|
---|
4171 | begin
|
---|
4172 | result := FPenStroker.ComputePolygon(points,w);
|
---|
4173 | end;
|
---|
4174 |
|
---|
4175 | function TBGRADefaultBitmap.ComputeEllipseContour(x, y, rx, ry: single; quality: single): ArrayOfTPointF;
|
---|
4176 | begin
|
---|
4177 | result := BGRAPath.ComputeEllipse(x,y,rx,ry, quality);
|
---|
4178 | end;
|
---|
4179 |
|
---|
4180 | function TBGRADefaultBitmap.ComputeEllipseContour(AOrigin, AXAxis,
|
---|
4181 | AYAxis: TPointF; quality: single): ArrayOfTPointF;
|
---|
4182 | begin
|
---|
4183 | result := BGRAPath.ComputeEllipse(AOrigin,AXAxis,AYAxis, quality);
|
---|
4184 | end;
|
---|
4185 |
|
---|
4186 | function TBGRADefaultBitmap.ComputeEllipseBorder(x, y, rx, ry, w: single; quality: single): ArrayOfTPointF;
|
---|
4187 | begin
|
---|
4188 | result := ComputeWidePolygon(ComputeEllipseContour(x,y,rx,ry, quality),w);
|
---|
4189 | end;
|
---|
4190 |
|
---|
4191 | function TBGRADefaultBitmap.ComputeEllipseBorder(AOrigin, AXAxis,
|
---|
4192 | AYAxis: TPointF; w: single; quality: single): ArrayOfTPointF;
|
---|
4193 | begin
|
---|
4194 | result := ComputeWidePolygon(ComputeEllipseContour(AOrigin,AXAxis,AYAxis, quality),w);
|
---|
4195 | end;
|
---|
4196 |
|
---|
4197 | function TBGRADefaultBitmap.ComputeArc65536(x, y, rx, ry: single; start65536,
|
---|
4198 | end65536: word; quality: single): ArrayOfTPointF;
|
---|
4199 | begin
|
---|
4200 | result := BGRAPath.ComputeArc65536(x,y,rx,ry,start65536,end65536,quality);
|
---|
4201 | end;
|
---|
4202 |
|
---|
4203 | function TBGRADefaultBitmap.ComputeArcRad(x, y, rx, ry: single; startRad,
|
---|
4204 | endRad: single; quality: single): ArrayOfTPointF;
|
---|
4205 | begin
|
---|
4206 | result := BGRAPath.ComputeArcRad(x,y,rx,ry,startRad,endRad,quality);
|
---|
4207 | end;
|
---|
4208 |
|
---|
4209 | function TBGRADefaultBitmap.ComputeRoundRect(x1, y1, x2, y2, rx, ry: single; quality: single): ArrayOfTPointF;
|
---|
4210 | begin
|
---|
4211 | result := BGRAPath.ComputeRoundRect(x1,y1,x2,y2,rx,ry,quality);
|
---|
4212 | end;
|
---|
4213 |
|
---|
4214 | function TBGRADefaultBitmap.ComputeRoundRect(x1, y1, x2, y2, rx, ry: single;
|
---|
4215 | options: TRoundRectangleOptions; quality: single): ArrayOfTPointF;
|
---|
4216 | begin
|
---|
4217 | Result:= BGRAPath.ComputeRoundRect(x1,y1,x2,y2,rx,ry,options,quality);
|
---|
4218 | end;
|
---|
4219 |
|
---|
4220 | function TBGRADefaultBitmap.ComputePie65536(x, y, rx, ry: single; start65536,
|
---|
4221 | end65536: word; quality: single): ArrayOfTPointF;
|
---|
4222 | begin
|
---|
4223 | result := BGRAPath.ComputeArc65536(x,y,rx,ry,start65536,end65536,quality);
|
---|
4224 | if (start65536 <> end65536) then
|
---|
4225 | begin
|
---|
4226 | setlength(result,length(result)+1);
|
---|
4227 | result[high(result)] := PointF(x,y);
|
---|
4228 | end;
|
---|
4229 | end;
|
---|
4230 |
|
---|
4231 | function TBGRADefaultBitmap.ComputePieRad(x, y, rx, ry: single; startRad,
|
---|
4232 | endRad: single; quality: single): ArrayOfTPointF;
|
---|
4233 | begin
|
---|
4234 | result := self.ComputePie65536(x,y,rx,ry,round(startRad*32768/Pi),round(endRad*32768/Pi),quality);
|
---|
4235 | end;
|
---|
4236 |
|
---|
4237 | {---------------------------------- Fill ---------------------------------}
|
---|
4238 |
|
---|
4239 | procedure TBGRADefaultBitmap.Fill(texture: IBGRAScanner);
|
---|
4240 | begin
|
---|
4241 | FillRect(FClipRect.Left,FClipRect.Top,FClipRect.Right,FClipRect.Bottom,texture,dmSet);
|
---|
4242 | end;
|
---|
4243 |
|
---|
4244 | procedure TBGRADefaultBitmap.Fill(c: TBGRAPixel; start, Count: integer);
|
---|
4245 | begin
|
---|
4246 | if start < 0 then
|
---|
4247 | begin
|
---|
4248 | Count += start;
|
---|
4249 | start := 0;
|
---|
4250 | end;
|
---|
4251 | if start >= nbPixels then
|
---|
4252 | exit;
|
---|
4253 | if start + Count > nbPixels then
|
---|
4254 | Count := nbPixels - start;
|
---|
4255 |
|
---|
4256 | FillInline(Data + start, c, Count);
|
---|
4257 | InvalidateBitmap;
|
---|
4258 | end;
|
---|
4259 |
|
---|
4260 | procedure TBGRADefaultBitmap.AlphaFill(alpha: byte; start, Count: integer);
|
---|
4261 | begin
|
---|
4262 | if alpha = 0 then
|
---|
4263 | Fill(BGRAPixelTransparent, start, Count);
|
---|
4264 | if start < 0 then
|
---|
4265 | begin
|
---|
4266 | Count += start;
|
---|
4267 | start := 0;
|
---|
4268 | end;
|
---|
4269 | if start >= nbPixels then
|
---|
4270 | exit;
|
---|
4271 | if start + Count > nbPixels then
|
---|
4272 | Count := nbPixels - start;
|
---|
4273 |
|
---|
4274 | AlphaFillInline(Data + start, alpha, Count);
|
---|
4275 | InvalidateBitmap;
|
---|
4276 | end;
|
---|
4277 |
|
---|
4278 | procedure TBGRADefaultBitmap.FillMask(x, y: integer; AMask: TBGRACustomBitmap;
|
---|
4279 | color: TBGRAPixel; ADrawMode: TDrawMode);
|
---|
4280 | var
|
---|
4281 | scan: TBGRACustomScanner;
|
---|
4282 | begin
|
---|
4283 | if (AMask = nil) or (color.alpha = 0) then exit;
|
---|
4284 | scan := TBGRASolidColorMaskScanner.Create(AMask,Point(-X,-Y),color);
|
---|
4285 | self.FillRect(X,Y,X+AMask.Width,Y+AMask.Height,scan,ADrawMode);
|
---|
4286 | scan.Free;
|
---|
4287 | end;
|
---|
4288 |
|
---|
4289 | procedure TBGRADefaultBitmap.FillMask(x, y: integer; AMask: TBGRACustomBitmap;
|
---|
4290 | texture: IBGRAScanner; ADrawMode: TDrawMode; AOpacity: byte);
|
---|
4291 | var
|
---|
4292 | scan: TBGRACustomScanner;
|
---|
4293 | begin
|
---|
4294 | if AMask = nil then exit;
|
---|
4295 | scan := TBGRATextureMaskScanner.Create(AMask,Point(-X,-Y),texture, AOpacity);
|
---|
4296 | self.FillRect(X,Y,X+AMask.Width,Y+AMask.Height,scan,ADrawMode);
|
---|
4297 | scan.Free;
|
---|
4298 | end;
|
---|
4299 |
|
---|
4300 | procedure TBGRADefaultBitmap.EraseMask(x, y: integer; AMask: TBGRACustomBitmap;
|
---|
4301 | alpha: byte);
|
---|
4302 | var
|
---|
4303 | x0,y0,x2, y2, yb,xb, tx, delta: integer;
|
---|
4304 | p, psrc: PBGRAPixel;
|
---|
4305 | begin
|
---|
4306 | if (AMask = nil) or (alpha = 0) then exit;
|
---|
4307 | x0 := x;
|
---|
4308 | y0 := y;
|
---|
4309 | x2 := x+AMask.Width;
|
---|
4310 | y2 := y+AMask.Height;
|
---|
4311 | if not CheckClippedRectBounds(x,y,x2,y2) then exit;
|
---|
4312 | tx := x2 - x;
|
---|
4313 | Dec(x2);
|
---|
4314 | Dec(y2);
|
---|
4315 |
|
---|
4316 | p := Scanline[y] + x;
|
---|
4317 | if FLineOrder = riloBottomToTop then
|
---|
4318 | delta := -Width
|
---|
4319 | else
|
---|
4320 | delta := Width;
|
---|
4321 |
|
---|
4322 | for yb := y to y2 do
|
---|
4323 | begin
|
---|
4324 | psrc := AMask.ScanLine[yb-y0]+(x-x0);
|
---|
4325 | if alpha = 255 then
|
---|
4326 | begin
|
---|
4327 | for xb := tx-1 downto 0 do
|
---|
4328 | begin
|
---|
4329 | ErasePixelInline(p, psrc^.green);
|
---|
4330 | inc(p);
|
---|
4331 | inc(psrc);
|
---|
4332 | end;
|
---|
4333 | end else
|
---|
4334 | begin
|
---|
4335 | for xb := tx-1 downto 0 do
|
---|
4336 | begin
|
---|
4337 | ErasePixelInline(p, ApplyOpacity(psrc^.green,alpha));
|
---|
4338 | inc(p);
|
---|
4339 | inc(psrc);
|
---|
4340 | end;
|
---|
4341 | end;
|
---|
4342 | dec(p, tx);
|
---|
4343 | Inc(p, delta);
|
---|
4344 | end;
|
---|
4345 |
|
---|
4346 | InvalidateBitmap;
|
---|
4347 | end;
|
---|
4348 |
|
---|
4349 | procedure TBGRADefaultBitmap.FillClearTypeMask(x, y: integer; xThird: integer;
|
---|
4350 | AMask: TBGRACustomBitmap; color: TBGRAPixel; ARGBOrder: boolean);
|
---|
4351 | begin
|
---|
4352 | BGRAFillClearTypeMask(self,x, y, xThird, AMask, color, nil, ARGBOrder);
|
---|
4353 | end;
|
---|
4354 |
|
---|
4355 | procedure TBGRADefaultBitmap.FillClearTypeMask(x, y: integer; xThird: integer;
|
---|
4356 | AMask: TBGRACustomBitmap; texture: IBGRAScanner; ARGBOrder: boolean);
|
---|
4357 | begin
|
---|
4358 | BGRAFillClearTypeMask(self,x, y, xThird, AMask, BGRAPixelTransparent, texture, ARGBOrder);
|
---|
4359 | end;
|
---|
4360 |
|
---|
4361 | { Replace color without taking alpha channel into account }
|
---|
4362 | procedure TBGRADefaultBitmap.ReplaceColor(before, after: TColor);
|
---|
4363 | var
|
---|
4364 | p: PLongWord;
|
---|
4365 | n: integer;
|
---|
4366 | colorMask,beforeBGR, afterBGR: longword;
|
---|
4367 | rAfter,gAfter,bAfter,rBefore,gBefore,bBefore: byte;
|
---|
4368 | begin
|
---|
4369 | colorMask := LongWord(BGRA(255,255,255,0));
|
---|
4370 | RedGreenBlue(before, rBefore,gBefore,bBefore);
|
---|
4371 | RedGreenBlue(after, rAfter,gAfter,bAfter);
|
---|
4372 | beforeBGR := LongWord(BGRA(rBefore,gBefore,bBefore,0));
|
---|
4373 | afterBGR := LongWord(BGRA(rAfter,gAfter,bAfter,0));
|
---|
4374 |
|
---|
4375 | p := PLongWord(Data);
|
---|
4376 | for n := NbPixels - 1 downto 0 do
|
---|
4377 | begin
|
---|
4378 | if p^ and colorMask = beforeBGR then
|
---|
4379 | p^ := (p^ and not ColorMask) or afterBGR;
|
---|
4380 | Inc(p);
|
---|
4381 | end;
|
---|
4382 | InvalidateBitmap;
|
---|
4383 | end;
|
---|
4384 |
|
---|
4385 | procedure TBGRADefaultBitmap.ReplaceColor(before, after: TBGRAPixel);
|
---|
4386 | var
|
---|
4387 | p: PBGRAPixel;
|
---|
4388 | n: integer;
|
---|
4389 | begin
|
---|
4390 | if before.alpha = 0 then
|
---|
4391 | begin
|
---|
4392 | ReplaceTransparent(after);
|
---|
4393 | exit;
|
---|
4394 | end;
|
---|
4395 | p := Data;
|
---|
4396 | for n := NbPixels - 1 downto 0 do
|
---|
4397 | begin
|
---|
4398 | if PDWord(p)^ = DWord(before) then
|
---|
4399 | p^ := after;
|
---|
4400 | Inc(p);
|
---|
4401 | end;
|
---|
4402 | InvalidateBitmap;
|
---|
4403 | end;
|
---|
4404 |
|
---|
4405 | procedure TBGRADefaultBitmap.ReplaceColor(ABounds: TRect; before, after: TColor);
|
---|
4406 | var p: PLongWord;
|
---|
4407 | xb,yb,xcount: integer;
|
---|
4408 |
|
---|
4409 | colorMask,beforeBGR, afterBGR: longword;
|
---|
4410 | rAfter,gAfter,bAfter,rBefore,gBefore,bBefore: byte;
|
---|
4411 | begin
|
---|
4412 | colorMask := LongWord(BGRA(255,255,255,0));
|
---|
4413 | RedGreenBlue(before, rBefore,gBefore,bBefore);
|
---|
4414 | RedGreenBlue(after, rAfter,gAfter,bAfter);
|
---|
4415 | beforeBGR := LongWord(BGRA(rBefore,gBefore,bBefore,0));
|
---|
4416 | afterBGR := LongWord(BGRA(rAfter,gAfter,bAfter,0));
|
---|
4417 |
|
---|
4418 | if not IntersectRect(ABounds,ABounds,ClipRect) then exit;
|
---|
4419 | xcount := ABounds.Right-ABounds.Left;
|
---|
4420 | for yb := ABounds.Top to ABounds.Bottom-1 do
|
---|
4421 | begin
|
---|
4422 | p := PLongWord(ScanLine[yb]+ABounds.Left);
|
---|
4423 | for xb := xcount-1 downto 0 do
|
---|
4424 | begin
|
---|
4425 | if p^ and colorMask = beforeBGR then
|
---|
4426 | p^ := (p^ and not ColorMask) or afterBGR;
|
---|
4427 | Inc(p);
|
---|
4428 | end;
|
---|
4429 | end;
|
---|
4430 | InvalidateBitmap;
|
---|
4431 | end;
|
---|
4432 |
|
---|
4433 | procedure TBGRADefaultBitmap.ReplaceColor(ABounds: TRect; before,
|
---|
4434 | after: TBGRAPixel);
|
---|
4435 | var p: PBGRAPixel;
|
---|
4436 | xb,yb,xcount: integer;
|
---|
4437 | begin
|
---|
4438 | if before.alpha = 0 then
|
---|
4439 | begin
|
---|
4440 | ReplaceTransparent(ABounds,after);
|
---|
4441 | exit;
|
---|
4442 | end;
|
---|
4443 | if not IntersectRect(ABounds,ABounds,ClipRect) then exit;
|
---|
4444 | xcount := ABounds.Right-ABounds.Left;
|
---|
4445 | for yb := ABounds.Top to ABounds.Bottom-1 do
|
---|
4446 | begin
|
---|
4447 | p := ScanLine[yb]+ABounds.Left;
|
---|
4448 | for xb := xcount-1 downto 0 do
|
---|
4449 | begin
|
---|
4450 | if PDWord(p)^ = DWord(before) then
|
---|
4451 | p^ := after;
|
---|
4452 | Inc(p);
|
---|
4453 | end;
|
---|
4454 | end;
|
---|
4455 | InvalidateBitmap;
|
---|
4456 | end;
|
---|
4457 |
|
---|
4458 | { Replace transparent pixels by the specified color }
|
---|
4459 | procedure TBGRADefaultBitmap.ReplaceTransparent(after: TBGRAPixel);
|
---|
4460 | var
|
---|
4461 | p: PBGRAPixel;
|
---|
4462 | n: integer;
|
---|
4463 | begin
|
---|
4464 | p := Data;
|
---|
4465 | for n := NbPixels - 1 downto 0 do
|
---|
4466 | begin
|
---|
4467 | if p^.alpha = 0 then
|
---|
4468 | p^ := after;
|
---|
4469 | Inc(p);
|
---|
4470 | end;
|
---|
4471 | InvalidateBitmap;
|
---|
4472 | end;
|
---|
4473 |
|
---|
4474 | procedure TBGRADefaultBitmap.ReplaceTransparent(ABounds: TRect;
|
---|
4475 | after: TBGRAPixel);
|
---|
4476 | var p: PBGRAPixel;
|
---|
4477 | xb,yb,xcount: integer;
|
---|
4478 | begin
|
---|
4479 | if not IntersectRect(ABounds,ABounds,ClipRect) then exit;
|
---|
4480 | xcount := ABounds.Right-ABounds.Left;
|
---|
4481 | for yb := ABounds.Top to ABounds.Bottom-1 do
|
---|
4482 | begin
|
---|
4483 | p := ScanLine[yb]+ABounds.Left;
|
---|
4484 | for xb := xcount-1 downto 0 do
|
---|
4485 | begin
|
---|
4486 | if p^.alpha = 0 then
|
---|
4487 | p^ := after;
|
---|
4488 | Inc(p);
|
---|
4489 | end;
|
---|
4490 | end;
|
---|
4491 | InvalidateBitmap;
|
---|
4492 | end;
|
---|
4493 |
|
---|
4494 | { General purpose FloodFill. It can be used to fill inplace or to
|
---|
4495 | fill a destination bitmap according to the content of the current bitmap.
|
---|
4496 |
|
---|
4497 | The first pixel encountered is taken as a reference, further pixels
|
---|
4498 | are compared to this pixel. If the distance between next colors and
|
---|
4499 | the first color is lower than the tolerance, then the floodfill continues.
|
---|
4500 |
|
---|
4501 | It uses an array of bits to store visited places to avoid filling twice
|
---|
4502 | the same area. It also uses a stack of positions to remember where
|
---|
4503 | to continue after a place is completely filled.
|
---|
4504 |
|
---|
4505 | The first direction to be checked is horizontal, then
|
---|
4506 | it checks pixels on the line above and on the line below. }
|
---|
4507 | procedure TBGRADefaultBitmap.ParallelFloodFill(X, Y: integer;
|
---|
4508 | Dest: TBGRACustomBitmap; Color: TBGRAPixel; mode: TFloodfillMode;
|
---|
4509 | Tolerance: byte);
|
---|
4510 | var
|
---|
4511 | S: TBGRAPixel;
|
---|
4512 | SX, EX, I: integer;
|
---|
4513 | Added: boolean;
|
---|
4514 |
|
---|
4515 | Visited: array of longword;
|
---|
4516 | VisitedLineSize: integer;
|
---|
4517 |
|
---|
4518 | Stack: array of integer;
|
---|
4519 | StackCount: integer;
|
---|
4520 |
|
---|
4521 | function CheckPixel(AX, AY: integer): boolean; inline;
|
---|
4522 | var
|
---|
4523 | ComparedColor: TBGRAPixel;
|
---|
4524 | begin
|
---|
4525 | if Visited[AX shr 5 + AY * VisitedLineSize] and (1 shl (AX and 31)) <> 0 then
|
---|
4526 | Result := False
|
---|
4527 | else
|
---|
4528 | begin
|
---|
4529 | ComparedColor := GetPixel(AX, AY);
|
---|
4530 | Result := BGRADiff(ComparedColor, S) <= Tolerance;
|
---|
4531 | end;
|
---|
4532 | end;
|
---|
4533 |
|
---|
4534 | procedure SetVisited(X1, AY, X2: integer);
|
---|
4535 | var
|
---|
4536 | StartMask, EndMask: longword;
|
---|
4537 | StartPos, EndPos: integer;
|
---|
4538 | begin
|
---|
4539 | if X2 < X1 then
|
---|
4540 | exit;
|
---|
4541 | StartMask := $FFFFFFFF shl (X1 and 31);
|
---|
4542 | case X2 and 31 of
|
---|
4543 | 31: EndMask := $FFFFFFFF;
|
---|
4544 | 30: EndMask := $7FFFFFFF;
|
---|
4545 | else
|
---|
4546 | EndMask := 1 shl ((X2 and 31) + 1) - 1;
|
---|
4547 | end;
|
---|
4548 | StartPos := X1 shr 5 + AY * VisitedLineSize;
|
---|
4549 | EndPos := X2 shr 5 + AY * VisitedLineSize;
|
---|
4550 | if StartPos = EndPos then
|
---|
4551 | Visited[StartPos] := Visited[StartPos] or (StartMask and EndMask)
|
---|
4552 | else
|
---|
4553 | begin
|
---|
4554 | Visited[StartPos] := Visited[StartPos] or StartMask;
|
---|
4555 | Visited[EndPos] := Visited[EndPos] or EndMask;
|
---|
4556 | if EndPos - StartPos > 1 then
|
---|
4557 | FillDWord(Visited[StartPos + 1], EndPos - StartPos - 1, $FFFFFFFF);
|
---|
4558 | end;
|
---|
4559 | end;
|
---|
4560 |
|
---|
4561 | procedure Push(AX, AY: integer); inline;
|
---|
4562 | begin
|
---|
4563 | if StackCount + 1 >= High(Stack) then
|
---|
4564 | SetLength(Stack, Length(Stack) shl 1);
|
---|
4565 |
|
---|
4566 | Stack[StackCount] := AX;
|
---|
4567 | Inc(StackCount);
|
---|
4568 | Stack[StackCount] := AY;
|
---|
4569 | Inc(StackCount);
|
---|
4570 | end;
|
---|
4571 |
|
---|
4572 | procedure Pop(var AX, AY: integer); inline;
|
---|
4573 | begin
|
---|
4574 | Dec(StackCount);
|
---|
4575 | AY := Stack[StackCount];
|
---|
4576 | Dec(StackCount);
|
---|
4577 | AX := Stack[StackCount];
|
---|
4578 | end;
|
---|
4579 |
|
---|
4580 | begin
|
---|
4581 | if PtInClipRect(X,Y) then
|
---|
4582 | begin
|
---|
4583 | S := GetPixel(X, Y);
|
---|
4584 |
|
---|
4585 | VisitedLineSize := (Width + 31) shr 5;
|
---|
4586 | SetLength(Visited, VisitedLineSize * Height);
|
---|
4587 | FillDWord(Visited[0], Length(Visited), 0);
|
---|
4588 |
|
---|
4589 | SetLength(Stack, 2);
|
---|
4590 | StackCount := 0;
|
---|
4591 |
|
---|
4592 | Push(X, Y);
|
---|
4593 | repeat
|
---|
4594 | Pop(X, Y);
|
---|
4595 | if not CheckPixel(X, Y) then
|
---|
4596 | Continue;
|
---|
4597 |
|
---|
4598 | SX := X;
|
---|
4599 | while (SX > FClipRect.Left) and CheckPixel(Pred(SX), Y) do
|
---|
4600 | Dec(SX);
|
---|
4601 | EX := X;
|
---|
4602 | while (EX < Pred(FClipRect.Right)) and CheckPixel(Succ(EX), Y) do
|
---|
4603 | Inc(EX);
|
---|
4604 |
|
---|
4605 | SetVisited(SX, Y, EX);
|
---|
4606 | if mode = fmSet then
|
---|
4607 | dest.SetHorizLine(SX, Y, EX, Color)
|
---|
4608 | else
|
---|
4609 | if mode = fmDrawWithTransparency then
|
---|
4610 | dest.DrawHorizLine(SX, Y, EX, Color)
|
---|
4611 | else
|
---|
4612 | dest.DrawHorizLineDiff(SX, Y, EX, Color, S, Tolerance);
|
---|
4613 |
|
---|
4614 | Added := False;
|
---|
4615 | if Y > FClipRect.Top then
|
---|
4616 | for I := SX to EX do
|
---|
4617 | if CheckPixel(I, Pred(Y)) then
|
---|
4618 | begin
|
---|
4619 | if Added then //do not add twice the same segment
|
---|
4620 | Continue;
|
---|
4621 | Push(I, Pred(Y));
|
---|
4622 | Added := True;
|
---|
4623 | end
|
---|
4624 | else
|
---|
4625 | Added := False;
|
---|
4626 |
|
---|
4627 | Added := False;
|
---|
4628 | if Y < Pred(FClipRect.Bottom) then
|
---|
4629 | for I := SX to EX do
|
---|
4630 | if CheckPixel(I, Succ(Y)) then
|
---|
4631 | begin
|
---|
4632 | if Added then //do not add twice the same segment
|
---|
4633 | Continue;
|
---|
4634 | Push(I, Succ(Y));
|
---|
4635 | Added := True;
|
---|
4636 | end
|
---|
4637 | else
|
---|
4638 | Added := False;
|
---|
4639 | until StackCount <= 0;
|
---|
4640 | end;
|
---|
4641 | end;
|
---|
4642 |
|
---|
4643 | procedure TBGRADefaultBitmap.GradientFill(x, y, x2, y2: integer;
|
---|
4644 | c1, c2: TBGRAPixel; gtype: TGradientType; o1, o2: TPointF; mode: TDrawMode;
|
---|
4645 | gammaColorCorrection: boolean; Sinus: Boolean; ditherAlgo: TDitheringAlgorithm);
|
---|
4646 | var
|
---|
4647 | scanner: TBGRAGradientScanner;
|
---|
4648 | begin
|
---|
4649 | if (c1.alpha = 0) and (c2.alpha = 0) then
|
---|
4650 | FillRect(x, y, x2, y2, BGRAPixelTransparent, mode)
|
---|
4651 | else
|
---|
4652 | if ditherAlgo <> daNearestNeighbor then
|
---|
4653 | GradientFillDithered(x,y,x2,y2,c1,c2,gtype,o1,o2,mode,gammaColorCorrection,sinus,ditherAlgo)
|
---|
4654 | else
|
---|
4655 | begin
|
---|
4656 | scanner := TBGRAGradientScanner.Create(c1,c2,gtype,o1,o2,gammaColorCorrection,Sinus);
|
---|
4657 | FillRect(x,y,x2,y2,scanner,mode);
|
---|
4658 | scanner.Free;
|
---|
4659 | end;
|
---|
4660 | end;
|
---|
4661 |
|
---|
4662 | procedure TBGRADefaultBitmap.GradientFill(x, y, x2, y2: integer;
|
---|
4663 | gradient: TBGRACustomGradient; gtype: TGradientType; o1, o2: TPointF;
|
---|
4664 | mode: TDrawMode; Sinus: Boolean; ditherAlgo: TDitheringAlgorithm);
|
---|
4665 | var
|
---|
4666 | scanner: TBGRAGradientScanner;
|
---|
4667 | begin
|
---|
4668 | if ditherAlgo <> daNearestNeighbor then
|
---|
4669 | GradientFillDithered(x,y,x2,y2,gradient,gtype,o1,o2,mode,sinus,ditherAlgo)
|
---|
4670 | else
|
---|
4671 | begin
|
---|
4672 | scanner := TBGRAGradientScanner.Create(gradient,gtype,o1,o2,sinus);
|
---|
4673 | FillRect(x,y,x2,y2,scanner,mode);
|
---|
4674 | scanner.Free;
|
---|
4675 | end;
|
---|
4676 | end;
|
---|
4677 |
|
---|
4678 | procedure TBGRADefaultBitmap.GradientFillDithered(x, y, x2, y2: integer; c1,
|
---|
4679 | c2: TBGRAPixel; gtype: TGradientType; o1, o2: TPointF;
|
---|
4680 | mode: TDrawMode; gammaColorCorrection: boolean; Sinus: Boolean;
|
---|
4681 | ditherAlgo: TDitheringAlgorithm);
|
---|
4682 | var
|
---|
4683 | scanner: TBGRAGradientScanner;
|
---|
4684 | begin
|
---|
4685 | if (c1.alpha = 0) and (c2.alpha = 0) then
|
---|
4686 | FillRect(x, y, x2, y2, BGRAPixelTransparent, dmSet)
|
---|
4687 | else
|
---|
4688 | begin
|
---|
4689 | scanner := TBGRAGradientScanner.Create(c1,c2,gtype,o1,o2,gammaColorCorrection,Sinus);
|
---|
4690 | FillRect(x,y,x2,y2,scanner,mode,ditherAlgo);
|
---|
4691 | scanner.Free;
|
---|
4692 | end;
|
---|
4693 | end;
|
---|
4694 |
|
---|
4695 | procedure TBGRADefaultBitmap.GradientFillDithered(x, y, x2, y2: integer;
|
---|
4696 | gradient: TBGRACustomGradient; gtype: TGradientType; o1, o2: TPointF;
|
---|
4697 | mode: TDrawMode; Sinus: Boolean; ditherAlgo: TDitheringAlgorithm);
|
---|
4698 | var
|
---|
4699 | scanner: TBGRAGradientScanner;
|
---|
4700 | begin
|
---|
4701 | scanner := TBGRAGradientScanner.Create(gradient,gtype,o1,o2,sinus);
|
---|
4702 | FillRect(x,y,x2,y2,scanner,mode,ditherAlgo);
|
---|
4703 | scanner.Free;
|
---|
4704 | end;
|
---|
4705 |
|
---|
4706 | function TBGRADefaultBitmap.CreateBrushTexture(ABrushStyle: TBrushStyle; APatternColor, ABackgroundColor: TBGRAPixel;
|
---|
4707 | AWidth: integer = 8; AHeight: integer = 8; APenWidth: single = 1): TBGRACustomBitmap;
|
---|
4708 | begin
|
---|
4709 | result := BGRAPen.CreateBrushTexture(self,ABrushStyle,APatternColor,ABackgroundColor,AWidth,AHeight,APenWidth);
|
---|
4710 | end;
|
---|
4711 |
|
---|
4712 | function TBGRADefaultBitmap.ScanAtInteger(X, Y: integer): TBGRAPixel;
|
---|
4713 | begin
|
---|
4714 | if (FScanWidth <> 0) and (FScanHeight <> 0) then
|
---|
4715 | result := (GetScanlineFast(PositiveMod(Y+ScanOffset.Y, FScanHeight))+PositiveMod(X+ScanOffset.X, FScanWidth))^
|
---|
4716 | else
|
---|
4717 | result := BGRAPixelTransparent;
|
---|
4718 | end;
|
---|
4719 |
|
---|
4720 | { Scanning procedures for IBGRAScanner interface }
|
---|
4721 | procedure TBGRADefaultBitmap.ScanMoveTo(X, Y: Integer);
|
---|
4722 | begin
|
---|
4723 | if (FScanWidth = 0) or (FScanHeight = 0) then exit;
|
---|
4724 | LoadFromBitmapIfNeeded;
|
---|
4725 | FScanCurX := PositiveMod(X+ScanOffset.X, FScanWidth);
|
---|
4726 | FScanCurY := PositiveMod(Y+ScanOffset.Y, FScanHeight);
|
---|
4727 | FScanPtr := ScanLine[FScanCurY];
|
---|
4728 | end;
|
---|
4729 |
|
---|
4730 | function TBGRADefaultBitmap.ScanNextPixel: TBGRAPixel;
|
---|
4731 | begin
|
---|
4732 | if (FScanWidth <> 0) and (FScanHeight <> 0) then
|
---|
4733 | begin
|
---|
4734 | result := (FScanPtr+FScanCurX)^;
|
---|
4735 | inc(FScanCurX);
|
---|
4736 | if FScanCurX = FScanWidth then //cycle
|
---|
4737 | FScanCurX := 0;
|
---|
4738 | end
|
---|
4739 | else
|
---|
4740 | result := BGRAPixelTransparent;
|
---|
4741 | end;
|
---|
4742 |
|
---|
4743 | function TBGRADefaultBitmap.ScanAt(X, Y: Single): TBGRAPixel;
|
---|
4744 | var
|
---|
4745 | ix, iy: Int32or64;
|
---|
4746 | iFactX,iFactY: Int32or64;
|
---|
4747 | begin
|
---|
4748 | if (FScanWidth = 0) or (FScanHeight = 0) then
|
---|
4749 | begin
|
---|
4750 | result := BGRAPixelTransparent;
|
---|
4751 | exit;
|
---|
4752 | end;
|
---|
4753 | LoadFromBitmapIfNeeded;
|
---|
4754 | ix := round(x*256);
|
---|
4755 | iy := round(y*256);
|
---|
4756 | if ScanInterpolationFilter = rfBox then
|
---|
4757 | begin
|
---|
4758 | ix := PositiveMod((ix+128)+(ScanOffset.X shl 8), FScanWidth shl 8) shr 8;
|
---|
4759 | iy := PositiveMod((iy+128)+(ScanOffset.Y shl 8), FScanHeight shl 8) shr 8;
|
---|
4760 | result := (GetScanlineFast(iy)+ix)^;
|
---|
4761 | exit;
|
---|
4762 | end;
|
---|
4763 | iFactX := ix and 255;
|
---|
4764 | iFactY := iy and 255;
|
---|
4765 | ix := PositiveMod(ix+(ScanOffset.X shl 8), FScanWidth shl 8) shr 8;
|
---|
4766 | iy := PositiveMod(iy+(ScanOffset.Y shl 8), FScanHeight shl 8) shr 8;
|
---|
4767 | if (iFactX = 0) and (iFactY = 0) then
|
---|
4768 | begin
|
---|
4769 | result := (GetScanlineFast(iy)+ix)^;
|
---|
4770 | exit;
|
---|
4771 | end;
|
---|
4772 | if ScanInterpolationFilter <> rfLinear then
|
---|
4773 | begin
|
---|
4774 | iFactX := FineInterpolation256( iFactX, ScanInterpolationFilter );
|
---|
4775 | iFactY := FineInterpolation256( iFactY, ScanInterpolationFilter );
|
---|
4776 | end;
|
---|
4777 | result := InternalGetPixelCycle256(ix,iy, iFactX,iFactY);
|
---|
4778 | end;
|
---|
4779 |
|
---|
4780 | function TBGRADefaultBitmap.IsScanPutPixelsDefined: boolean;
|
---|
4781 | begin
|
---|
4782 | Result:= true;
|
---|
4783 | end;
|
---|
4784 |
|
---|
4785 | procedure TBGRADefaultBitmap.ScanPutPixels(pdest: PBGRAPixel; count: integer;
|
---|
4786 | mode: TDrawMode);
|
---|
4787 | var
|
---|
4788 | i,nbCopy: Integer;
|
---|
4789 | c: TBGRAPixel;
|
---|
4790 | begin
|
---|
4791 | if (FScanWidth <= 0) or (FScanHeight <= 0) then
|
---|
4792 | begin
|
---|
4793 | if mode = dmSet then
|
---|
4794 | FillDWord(pdest^, count, DWord(BGRAPixelTransparent));
|
---|
4795 | exit;
|
---|
4796 | end;
|
---|
4797 | case mode of
|
---|
4798 | dmLinearBlend:
|
---|
4799 | for i := 0 to count-1 do
|
---|
4800 | begin
|
---|
4801 | FastBlendPixelInline(pdest, ScanNextPixel);
|
---|
4802 | inc(pdest);
|
---|
4803 | end;
|
---|
4804 | dmDrawWithTransparency:
|
---|
4805 | for i := 0 to count-1 do
|
---|
4806 | begin
|
---|
4807 | DrawPixelInlineWithAlphaCheck(pdest, ScanNextPixel);
|
---|
4808 | inc(pdest);
|
---|
4809 | end;
|
---|
4810 | dmSet:
|
---|
4811 | while count > 0 do
|
---|
4812 | begin
|
---|
4813 | nbCopy := FScanWidth-FScanCurX;
|
---|
4814 | if count < nbCopy then nbCopy := count;
|
---|
4815 | move((FScanPtr+FScanCurX)^,pdest^,nbCopy*sizeof(TBGRAPixel));
|
---|
4816 | inc(pdest,nbCopy);
|
---|
4817 | inc(FScanCurX,nbCopy);
|
---|
4818 | if FScanCurX = FScanWidth then FScanCurX := 0;
|
---|
4819 | dec(count,nbCopy);
|
---|
4820 | end;
|
---|
4821 | dmSetExceptTransparent:
|
---|
4822 | for i := 0 to count-1 do
|
---|
4823 | begin
|
---|
4824 | c := ScanNextPixel;
|
---|
4825 | if c.alpha = 255 then pdest^ := c;
|
---|
4826 | inc(pdest);
|
---|
4827 | end;
|
---|
4828 | dmXor:
|
---|
4829 | for i := 0 to count-1 do
|
---|
4830 | begin
|
---|
4831 | PDWord(pdest)^ := PDWord(pdest)^ xor DWord(ScanNextPixel);
|
---|
4832 | inc(pdest);
|
---|
4833 | end;
|
---|
4834 | end;
|
---|
4835 | end;
|
---|
4836 |
|
---|
4837 | { General purpose pixel drawing function }
|
---|
4838 | procedure TBGRADefaultBitmap.DrawPixels(c: TBGRAPixel; start, Count: integer);
|
---|
4839 | var
|
---|
4840 | p: PBGRAPixel;
|
---|
4841 | begin
|
---|
4842 | if c.alpha = 0 then
|
---|
4843 | exit;
|
---|
4844 | if c.alpha = 255 then
|
---|
4845 | begin
|
---|
4846 | Fill(c,start,Count);
|
---|
4847 | exit;
|
---|
4848 | end;
|
---|
4849 |
|
---|
4850 | if start < 0 then
|
---|
4851 | begin
|
---|
4852 | Count += start;
|
---|
4853 | start := 0;
|
---|
4854 | end;
|
---|
4855 | if start >= nbPixels then
|
---|
4856 | exit;
|
---|
4857 | if start + Count > nbPixels then
|
---|
4858 | Count := nbPixels - start;
|
---|
4859 |
|
---|
4860 | p := Data + start;
|
---|
4861 | DrawPixelsInline(p,c,Count);
|
---|
4862 | InvalidateBitmap;
|
---|
4863 | end;
|
---|
4864 |
|
---|
4865 | {------------------------- End fill ------------------------------}
|
---|
4866 |
|
---|
4867 | procedure TBGRADefaultBitmap.DoAlphaCorrection;
|
---|
4868 | var
|
---|
4869 | p: PBGRAPixel;
|
---|
4870 | n: integer;
|
---|
4871 | colormask: longword;
|
---|
4872 | begin
|
---|
4873 | if CanvasAlphaCorrection then
|
---|
4874 | begin
|
---|
4875 | p := FData;
|
---|
4876 | colormask := longword(BGRA(255,255,255,0));
|
---|
4877 | for n := NbPixels - 1 downto 0 do
|
---|
4878 | begin
|
---|
4879 | if (longword(p^) and colormask <> 0) and (p^.alpha = 0) then
|
---|
4880 | p^.alpha := FCanvasOpacity;
|
---|
4881 | Inc(p);
|
---|
4882 | end;
|
---|
4883 | end;
|
---|
4884 | FAlphaCorrectionNeeded := False;
|
---|
4885 | InvalidateBitmap;
|
---|
4886 | end;
|
---|
4887 |
|
---|
4888 | { Ensure that transparent pixels have all channels to zero }
|
---|
4889 | procedure TBGRADefaultBitmap.ClearTransparentPixels;
|
---|
4890 | var
|
---|
4891 | p: PBGRAPixel;
|
---|
4892 | n: integer;
|
---|
4893 | begin
|
---|
4894 | p := FData;
|
---|
4895 | for n := NbPixels - 1 downto 0 do
|
---|
4896 | begin
|
---|
4897 | if (p^.alpha = 0) then
|
---|
4898 | p^ := BGRAPixelTransparent;
|
---|
4899 | Inc(p);
|
---|
4900 | end;
|
---|
4901 | InvalidateBitmap;
|
---|
4902 | end;
|
---|
4903 |
|
---|
4904 | function TBGRADefaultBitmap.CheckAntialiasRectBounds(var x, y, x2, y2: single;
|
---|
4905 | w: single): boolean;
|
---|
4906 | var
|
---|
4907 | temp: Single;
|
---|
4908 | begin
|
---|
4909 | if (x > x2) then
|
---|
4910 | begin
|
---|
4911 | temp := x;
|
---|
4912 | x := x2;
|
---|
4913 | x2 := temp;
|
---|
4914 | end;
|
---|
4915 | if (y > y2) then
|
---|
4916 | begin
|
---|
4917 | temp := y;
|
---|
4918 | y := y2;
|
---|
4919 | y2 := temp;
|
---|
4920 | end;
|
---|
4921 |
|
---|
4922 | result := (x2 - x > w) and (y2 - y > w);
|
---|
4923 | end;
|
---|
4924 |
|
---|
4925 | function TBGRADefaultBitmap.GetCanvasBGRA: TBGRACanvas;
|
---|
4926 | begin
|
---|
4927 | if FCanvasBGRA = nil then
|
---|
4928 | FCanvasBGRA := TBGRACanvas.Create(self);
|
---|
4929 | result := FCanvasBGRA;
|
---|
4930 | end;
|
---|
4931 |
|
---|
4932 | function TBGRADefaultBitmap.GetCanvas2D: TBGRACanvas2D;
|
---|
4933 | begin
|
---|
4934 | if FCanvas2D = nil then
|
---|
4935 | FCanvas2D := TBGRACanvas2D.Create(self);
|
---|
4936 | result := FCanvas2D;
|
---|
4937 | end;
|
---|
4938 |
|
---|
4939 | procedure TBGRADefaultBitmap.PutImage(x, y: integer; Source: TBGRACustomBitmap;
|
---|
4940 | mode: TDrawMode; AOpacity: byte);
|
---|
4941 | var
|
---|
4942 | yb, minxb, minyb, maxxb, maxyb, ignoreleft, copycount, sourcewidth,
|
---|
4943 | i, delta_source, delta_dest: integer;
|
---|
4944 | psource, pdest: PBGRAPixel;
|
---|
4945 | tempPixel: TBGRAPixel;
|
---|
4946 |
|
---|
4947 | begin
|
---|
4948 | if (source = nil) or (AOpacity = 0) then exit;
|
---|
4949 | sourcewidth := Source.Width;
|
---|
4950 |
|
---|
4951 | if not CheckPutImageBounds(x,y,sourcewidth,source.height,minxb,minyb,maxxb,maxyb,ignoreleft,FClipRect) then exit;
|
---|
4952 |
|
---|
4953 | copycount := maxxb - minxb + 1;
|
---|
4954 |
|
---|
4955 | psource := Source.ScanLine[minyb - y] + ignoreleft;
|
---|
4956 | if Source.LineOrder = riloBottomToTop then
|
---|
4957 | delta_source := -sourcewidth
|
---|
4958 | else
|
---|
4959 | delta_source := sourcewidth;
|
---|
4960 |
|
---|
4961 | pdest := Scanline[minyb] + minxb;
|
---|
4962 | if FLineOrder = riloBottomToTop then
|
---|
4963 | delta_dest := -Width
|
---|
4964 | else
|
---|
4965 | delta_dest := Width;
|
---|
4966 |
|
---|
4967 | case mode of
|
---|
4968 | dmSet:
|
---|
4969 | begin
|
---|
4970 | if AOpacity <> 255 then
|
---|
4971 | begin
|
---|
4972 | for yb := minyb to maxyb do
|
---|
4973 | begin
|
---|
4974 | CopyPixelsWithOpacity(pdest, psource, AOpacity, copycount);
|
---|
4975 | Inc(psource, delta_source);
|
---|
4976 | Inc(pdest, delta_dest);
|
---|
4977 | end;
|
---|
4978 | end
|
---|
4979 | else
|
---|
4980 | begin
|
---|
4981 | copycount *= sizeof(TBGRAPixel);
|
---|
4982 | for yb := minyb to maxyb do
|
---|
4983 | begin
|
---|
4984 | move(psource^, pdest^, copycount);
|
---|
4985 | Inc(psource, delta_source);
|
---|
4986 | Inc(pdest, delta_dest);
|
---|
4987 | end;
|
---|
4988 | end;
|
---|
4989 | InvalidateBitmap;
|
---|
4990 | end;
|
---|
4991 | dmSetExceptTransparent:
|
---|
4992 | begin
|
---|
4993 | Dec(delta_source, copycount);
|
---|
4994 | Dec(delta_dest, copycount);
|
---|
4995 | for yb := minyb to maxyb do
|
---|
4996 | begin
|
---|
4997 | if AOpacity <> 255 then
|
---|
4998 | begin
|
---|
4999 | for i := copycount - 1 downto 0 do
|
---|
5000 | begin
|
---|
5001 | if psource^.alpha = 255 then
|
---|
5002 | begin
|
---|
5003 | tempPixel := psource^;
|
---|
5004 | tempPixel.alpha := ApplyOpacity(tempPixel.alpha,AOpacity);
|
---|
5005 | FastBlendPixelInline(pdest,tempPixel);
|
---|
5006 | end;
|
---|
5007 | Inc(pdest);
|
---|
5008 | Inc(psource);
|
---|
5009 | end;
|
---|
5010 | end else
|
---|
5011 | for i := copycount - 1 downto 0 do
|
---|
5012 | begin
|
---|
5013 | if psource^.alpha = 255 then
|
---|
5014 | pdest^ := psource^;
|
---|
5015 | Inc(pdest);
|
---|
5016 | Inc(psource);
|
---|
5017 | end;
|
---|
5018 | Inc(psource, delta_source);
|
---|
5019 | Inc(pdest, delta_dest);
|
---|
5020 | end;
|
---|
5021 | InvalidateBitmap;
|
---|
5022 | if (Source is TBGRADefaultBitmap) and Assigned(TBGRADefaultBitmap(Source).XorMask) then
|
---|
5023 | PutImage(x,y,TBGRADefaultBitmap(Source).XorMask,dmXor,AOpacity);
|
---|
5024 | end;
|
---|
5025 | dmDrawWithTransparency:
|
---|
5026 | begin
|
---|
5027 | Dec(delta_source, copycount);
|
---|
5028 | Dec(delta_dest, copycount);
|
---|
5029 | for yb := minyb to maxyb do
|
---|
5030 | begin
|
---|
5031 | if AOpacity <> 255 then
|
---|
5032 | begin
|
---|
5033 | for i := copycount - 1 downto 0 do
|
---|
5034 | begin
|
---|
5035 | DrawPixelInlineWithAlphaCheck(pdest, psource^, AOpacity);
|
---|
5036 | Inc(pdest);
|
---|
5037 | Inc(psource);
|
---|
5038 | end;
|
---|
5039 | end
|
---|
5040 | else
|
---|
5041 | for i := copycount - 1 downto 0 do
|
---|
5042 | begin
|
---|
5043 | DrawPixelInlineWithAlphaCheck(pdest, psource^);
|
---|
5044 | Inc(pdest);
|
---|
5045 | Inc(psource);
|
---|
5046 | end;
|
---|
5047 | Inc(psource, delta_source);
|
---|
5048 | Inc(pdest, delta_dest);
|
---|
5049 | end;
|
---|
5050 | InvalidateBitmap;
|
---|
5051 | if (Source is TBGRADefaultBitmap) and Assigned(TBGRADefaultBitmap(Source).XorMask) then
|
---|
5052 | PutImage(x,y,TBGRADefaultBitmap(Source).XorMask,dmXor,AOpacity);
|
---|
5053 | end;
|
---|
5054 | dmFastBlend:
|
---|
5055 | begin
|
---|
5056 | Dec(delta_source, copycount);
|
---|
5057 | Dec(delta_dest, copycount);
|
---|
5058 | for yb := minyb to maxyb do
|
---|
5059 | begin
|
---|
5060 | if AOpacity <> 255 then
|
---|
5061 | begin
|
---|
5062 | for i := copycount - 1 downto 0 do
|
---|
5063 | begin
|
---|
5064 | FastBlendPixelInline(pdest, psource^, AOpacity);
|
---|
5065 | Inc(pdest);
|
---|
5066 | Inc(psource);
|
---|
5067 | end;
|
---|
5068 | end else
|
---|
5069 | for i := copycount - 1 downto 0 do
|
---|
5070 | begin
|
---|
5071 | FastBlendPixelInline(pdest, psource^);
|
---|
5072 | Inc(pdest);
|
---|
5073 | Inc(psource);
|
---|
5074 | end;
|
---|
5075 | Inc(psource, delta_source);
|
---|
5076 | Inc(pdest, delta_dest);
|
---|
5077 | end;
|
---|
5078 | InvalidateBitmap;
|
---|
5079 | if (Source is TBGRADefaultBitmap) and Assigned(TBGRADefaultBitmap(Source).XorMask) then
|
---|
5080 | PutImage(x,y,TBGRADefaultBitmap(Source).XorMask,dmXor,AOpacity);
|
---|
5081 | end;
|
---|
5082 | dmXor:
|
---|
5083 | begin
|
---|
5084 | if AOpacity <> 255 then
|
---|
5085 | begin
|
---|
5086 | Dec(delta_source, copycount);
|
---|
5087 | Dec(delta_dest, copycount);
|
---|
5088 | for yb := minyb to maxyb do
|
---|
5089 | begin
|
---|
5090 | for i := copycount - 1 downto 0 do
|
---|
5091 | begin
|
---|
5092 | FastBlendPixelInline(pdest, TBGRAPixel(PDWord(pdest)^ xor PDword(psource)^), AOpacity);
|
---|
5093 | Inc(pdest);
|
---|
5094 | Inc(psource);
|
---|
5095 | end;
|
---|
5096 | Inc(psource, delta_source);
|
---|
5097 | Inc(pdest, delta_dest);
|
---|
5098 | end;
|
---|
5099 | end else
|
---|
5100 | begin
|
---|
5101 | for yb := minyb to maxyb do
|
---|
5102 | begin
|
---|
5103 | XorPixels(pdest, psource, copycount);
|
---|
5104 | Inc(psource, delta_source);
|
---|
5105 | Inc(pdest, delta_dest);
|
---|
5106 | end;
|
---|
5107 | end;
|
---|
5108 | InvalidateBitmap;
|
---|
5109 | end;
|
---|
5110 | end;
|
---|
5111 | end;
|
---|
5112 |
|
---|
5113 | procedure TBGRADefaultBitmap.BlendImage(x, y: integer; Source: TBGRACustomBitmap;
|
---|
5114 | operation: TBlendOperation);
|
---|
5115 | var
|
---|
5116 | yb, minxb, minyb, maxxb, maxyb, ignoreleft, copycount, sourcewidth,
|
---|
5117 | delta_source, delta_dest: integer;
|
---|
5118 | psource, pdest: PBGRAPixel;
|
---|
5119 | begin
|
---|
5120 | sourcewidth := Source.Width;
|
---|
5121 |
|
---|
5122 | if not CheckPutImageBounds(x,y,sourcewidth,source.height,minxb,minyb,maxxb,maxyb,ignoreleft,FClipRect) then exit;
|
---|
5123 |
|
---|
5124 | copycount := maxxb - minxb + 1;
|
---|
5125 |
|
---|
5126 | psource := Source.ScanLine[minyb - y] + ignoreleft;
|
---|
5127 | if Source.LineOrder = riloBottomToTop then
|
---|
5128 | delta_source := -sourcewidth
|
---|
5129 | else
|
---|
5130 | delta_source := sourcewidth;
|
---|
5131 |
|
---|
5132 | pdest := Scanline[minyb] + minxb;
|
---|
5133 | if FLineOrder = riloBottomToTop then
|
---|
5134 | delta_dest := -Width
|
---|
5135 | else
|
---|
5136 | delta_dest := Width;
|
---|
5137 |
|
---|
5138 | for yb := minyb to maxyb do
|
---|
5139 | begin
|
---|
5140 | BlendPixels(pdest, psource, operation, copycount);
|
---|
5141 | Inc(psource, delta_source);
|
---|
5142 | Inc(pdest, delta_dest);
|
---|
5143 | end;
|
---|
5144 | InvalidateBitmap;
|
---|
5145 | end;
|
---|
5146 |
|
---|
5147 | procedure TBGRADefaultBitmap.BlendImageOver(x, y: integer;
|
---|
5148 | Source: TBGRACustomBitmap; operation: TBlendOperation; AOpacity: byte; ALinearBlend: boolean);
|
---|
5149 | var
|
---|
5150 | yb, minxb, minyb, maxxb, maxyb, ignoreleft, copycount, sourcewidth,
|
---|
5151 | delta_source, delta_dest: integer;
|
---|
5152 | psource, pdest: PBGRAPixel;
|
---|
5153 | begin
|
---|
5154 | sourcewidth := Source.Width;
|
---|
5155 |
|
---|
5156 | if not CheckPutImageBounds(x,y,sourcewidth,source.height,minxb,minyb,maxxb,maxyb,ignoreleft,FClipRect) then exit;
|
---|
5157 |
|
---|
5158 | copycount := maxxb - minxb + 1;
|
---|
5159 |
|
---|
5160 | psource := Source.ScanLine[minyb - y] + ignoreleft;
|
---|
5161 | if Source.LineOrder = riloBottomToTop then
|
---|
5162 | delta_source := -sourcewidth
|
---|
5163 | else
|
---|
5164 | delta_source := sourcewidth;
|
---|
5165 |
|
---|
5166 | pdest := Scanline[minyb] + minxb;
|
---|
5167 | if FLineOrder = riloBottomToTop then
|
---|
5168 | delta_dest := -Width
|
---|
5169 | else
|
---|
5170 | delta_dest := Width;
|
---|
5171 |
|
---|
5172 | for yb := minyb to maxyb do
|
---|
5173 | begin
|
---|
5174 | BlendPixelsOver(pdest, psource, operation, copycount, AOpacity, ALinearBlend);
|
---|
5175 | Inc(psource, delta_source);
|
---|
5176 | Inc(pdest, delta_dest);
|
---|
5177 | end;
|
---|
5178 | InvalidateBitmap;
|
---|
5179 | end;
|
---|
5180 |
|
---|
5181 | { Draw an image with an affine transformation (rotation, scale, translate).
|
---|
5182 | Parameters are the bitmap origin, the end of the horizontal axis and the end of the vertical axis.
|
---|
5183 | The output bounds correspond to the pixels that will be affected in the destination. }
|
---|
5184 | procedure TBGRADefaultBitmap.PutImageAffine(AMatrix: TAffineMatrix;
|
---|
5185 | Source: TBGRACustomBitmap; AOutputBounds: TRect;
|
---|
5186 | AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte);
|
---|
5187 | var affine: TBGRAAffineBitmapTransform;
|
---|
5188 | sourceBounds: TRect;
|
---|
5189 | begin
|
---|
5190 | if (Source = nil) or (Source.Width = 0) or (Source.Height = 0) or (AOpacity = 0) then exit;
|
---|
5191 | IntersectRect(AOutputBounds,AOutputBounds,ClipRect);
|
---|
5192 | if IsRectEmpty(AOutputBounds) then exit;
|
---|
5193 |
|
---|
5194 | if IsAffineRoughlyTranslation(AMatrix, rect(0,0,Source.Width,Source.Height)) then
|
---|
5195 | begin
|
---|
5196 | sourceBounds := AOutputBounds;
|
---|
5197 | OffsetRect(sourceBounds, -round(AMatrix[1,3]),-round(AMatrix[2,3]));
|
---|
5198 | IntersectRect(sourceBounds,sourceBounds,rect(0,0,Source.Width,Source.Height));
|
---|
5199 | PutImagePart(round(AMatrix[1,3])+sourceBounds.Left,round(AMatrix[2,3])+sourceBounds.Top,Source,sourceBounds,AMode,AOpacity);
|
---|
5200 | end else
|
---|
5201 | begin
|
---|
5202 | affine := TBGRAAffineBitmapTransform.Create(Source, false, AResampleFilter);
|
---|
5203 | affine.GlobalOpacity := AOpacity;
|
---|
5204 | affine.ViewMatrix := AMatrix;
|
---|
5205 | FillRect(AOutputBounds,affine,AMode);
|
---|
5206 | affine.Free;
|
---|
5207 | end;
|
---|
5208 | end;
|
---|
5209 |
|
---|
5210 | function TBGRADefaultBitmap.GetImageAffineBounds(AMatrix: TAffineMatrix;
|
---|
5211 | ASourceBounds: TRect; AClipOutput: boolean): TRect;
|
---|
5212 | const pointMargin = 0.5 - 1/512;
|
---|
5213 |
|
---|
5214 | procedure FirstPoint(pt: TPointF);
|
---|
5215 | begin
|
---|
5216 | result.Left := round(pt.X);
|
---|
5217 | result.Top := round(pt.Y);
|
---|
5218 | result.Right := round(pt.X)+1;
|
---|
5219 | result.Bottom := round(pt.Y)+1;
|
---|
5220 | end;
|
---|
5221 |
|
---|
5222 | //include specified point in the bounds
|
---|
5223 | procedure IncludePoint(pt: TPointF);
|
---|
5224 | begin
|
---|
5225 | if round(pt.X) < result.Left then result.Left := round(pt.X);
|
---|
5226 | if round(pt.Y) < result.Top then result.Top := round(pt.Y);
|
---|
5227 | if round(pt.X)+1 > result.Right then result.Right := round(pt.X)+1;
|
---|
5228 | if round(pt.Y)+1 > result.Bottom then result.Bottom := round(pt.Y)+1;
|
---|
5229 | end;
|
---|
5230 |
|
---|
5231 | begin
|
---|
5232 | result := EmptyRect;
|
---|
5233 | if IsRectEmpty(ASourceBounds) then exit;
|
---|
5234 | if IsAffineRoughlyTranslation(AMatrix,ASourceBounds) then
|
---|
5235 | begin
|
---|
5236 | result := ASourceBounds;
|
---|
5237 | OffsetRect(result,round(AMatrix[1,3]),round(AMatrix[2,3]));
|
---|
5238 | end else
|
---|
5239 | begin
|
---|
5240 | FirstPoint(AMatrix*PointF(ASourceBounds.Left-pointMargin,ASourceBounds.Top-pointMargin));
|
---|
5241 | IncludePoint(AMatrix*PointF(ASourceBounds.Right-1+pointMargin,ASourceBounds.Top-pointMargin));
|
---|
5242 | IncludePoint(AMatrix*PointF(ASourceBounds.Left-pointMargin,ASourceBounds.Bottom-1+pointMargin));
|
---|
5243 | IncludePoint(AMatrix*PointF(ASourceBounds.Right-1+pointMargin,ASourceBounds.Bottom-1+pointMargin));
|
---|
5244 | end;
|
---|
5245 | if AClipOutput then IntersectRect(result,result,ClipRect);
|
---|
5246 | end;
|
---|
5247 |
|
---|
5248 | procedure TBGRADefaultBitmap.StretchPutImage(ARect: TRect;
|
---|
5249 | Source: TBGRACustomBitmap; mode: TDrawMode; AOpacity: byte);
|
---|
5250 | var noTransition: boolean;
|
---|
5251 | begin
|
---|
5252 | If (Source = nil) or (AOpacity = 0) then exit;
|
---|
5253 | if (ARect.Right-ARect.Left = Source.Width) and (ARect.Bottom-ARect.Top = Source.Height) then
|
---|
5254 | PutImage(ARect.Left,ARect.Top,Source,mode,AOpacity)
|
---|
5255 | else
|
---|
5256 | begin
|
---|
5257 | noTransition:= (mode = dmXor) or ((mode in [dmDrawWithTransparency,dmFastBlend,dmSetExceptTransparent]) and
|
---|
5258 | (Source is TBGRADefaultBitmap) and
|
---|
5259 | Assigned(TBGRADefaultBitmap(Source).XorMask));
|
---|
5260 | BGRAResample.StretchPutImage(Source, ARect.Right-ARect.Left, ARect.Bottom-ARect.Top, self, ARect.left,ARect.Top, mode, AOpacity, noTransition);
|
---|
5261 | if (mode in [dmDrawWithTransparency,dmFastBlend,dmSetExceptTransparent]) and Assigned(TBGRADefaultBitmap(Source).XorMask) then
|
---|
5262 | BGRAResample.StretchPutImage(TBGRADefaultBitmap(Source).XorMask, ARect.Right-ARect.Left, ARect.Bottom-ARect.Top, self, ARect.left,ARect.Top, dmXor, AOpacity, noTransition);
|
---|
5263 | end;
|
---|
5264 | end;
|
---|
5265 |
|
---|
5266 | { Duplicate bitmap content. Optionally, bitmap properties can be also duplicated }
|
---|
5267 | function TBGRADefaultBitmap.Duplicate(DuplicateProperties: Boolean = False; DuplicateXorMask: Boolean = False): TBGRACustomBitmap;
|
---|
5268 | var Temp: TBGRADefaultBitmap;
|
---|
5269 | begin
|
---|
5270 | LoadFromBitmapIfNeeded;
|
---|
5271 | Temp := NewBitmap(Width, Height) as TBGRADefaultBitmap;
|
---|
5272 | Temp.PutImage(0, 0, self, dmSet);
|
---|
5273 | Temp.Caption := self.Caption;
|
---|
5274 | if DuplicateProperties then
|
---|
5275 | CopyPropertiesTo(Temp);
|
---|
5276 | if DuplicateXorMask and Assigned(XorMask) then
|
---|
5277 | Temp.FXorMask := FXorMask.Duplicate(True) as TBGRADefaultBitmap;
|
---|
5278 | Result := Temp;
|
---|
5279 | end;
|
---|
5280 |
|
---|
5281 | { Copy properties only }
|
---|
5282 | procedure TBGRADefaultBitmap.CopyPropertiesTo(ABitmap: TBGRADefaultBitmap);
|
---|
5283 | begin
|
---|
5284 | ABitmap.CanvasOpacity := CanvasOpacity;
|
---|
5285 | ABitmap.CanvasDrawModeFP := CanvasDrawModeFP;
|
---|
5286 | ABitmap.PenStyle := PenStyle;
|
---|
5287 | ABitmap.CustomPenStyle := CustomPenStyle;
|
---|
5288 | ABitmap.FontHeight := FontHeight;
|
---|
5289 | ABitmap.FontName := FontName;
|
---|
5290 | ABitmap.FontStyle := FontStyle;
|
---|
5291 | ABitmap.FontAntialias := FontAntialias;
|
---|
5292 | ABitmap.FontOrientation := FontOrientation;
|
---|
5293 | ABitmap.FontBidiMode:= FontBidiMode;
|
---|
5294 | ABitmap.LineCap := LineCap;
|
---|
5295 | ABitmap.JoinStyle := JoinStyle;
|
---|
5296 | ABitmap.FillMode := FillMode;
|
---|
5297 | ABitmap.ClipRect := ClipRect;
|
---|
5298 | ABitmap.HotSpot := HotSpot;
|
---|
5299 | end;
|
---|
5300 |
|
---|
5301 | { Check if two bitmaps have the same content }
|
---|
5302 | function TBGRADefaultBitmap.Equals(comp: TBGRACustomBitmap): boolean;
|
---|
5303 | var
|
---|
5304 | yb, xb: integer;
|
---|
5305 | pself, pcomp: PBGRAPixel;
|
---|
5306 | begin
|
---|
5307 | if comp = nil then
|
---|
5308 | Result := False
|
---|
5309 | else
|
---|
5310 | if (comp.Width <> Width) or (comp.Height <> Height) then
|
---|
5311 | Result := False
|
---|
5312 | else
|
---|
5313 | begin
|
---|
5314 | Result := True;
|
---|
5315 | for yb := 0 to Height - 1 do
|
---|
5316 | begin
|
---|
5317 | pself := ScanLine[yb];
|
---|
5318 | pcomp := comp.Scanline[yb];
|
---|
5319 | for xb := 0 to Width - 1 do
|
---|
5320 | begin
|
---|
5321 | if pself^ <> pcomp^ then
|
---|
5322 | begin
|
---|
5323 | Result := False;
|
---|
5324 | exit;
|
---|
5325 | end;
|
---|
5326 | Inc(pself);
|
---|
5327 | Inc(pcomp);
|
---|
5328 | end;
|
---|
5329 | end;
|
---|
5330 | end;
|
---|
5331 | end;
|
---|
5332 |
|
---|
5333 | { Check if a bitmap is filled wih the specified color }
|
---|
5334 | function TBGRADefaultBitmap.Equals(comp: TBGRAPixel): boolean;
|
---|
5335 | var
|
---|
5336 | i: integer;
|
---|
5337 | p: PBGRAPixel;
|
---|
5338 | begin
|
---|
5339 | p := Data;
|
---|
5340 | for i := NbPixels - 1 downto 0 do
|
---|
5341 | begin
|
---|
5342 | if p^ <> comp then
|
---|
5343 | begin
|
---|
5344 | Result := False;
|
---|
5345 | exit;
|
---|
5346 | end;
|
---|
5347 | Inc(p);
|
---|
5348 | end;
|
---|
5349 | Result := True;
|
---|
5350 | end;
|
---|
5351 |
|
---|
5352 | {----------------------------- Filters -----------------------------------------}
|
---|
5353 | { Call the appropriate function }
|
---|
5354 |
|
---|
5355 | function TBGRADefaultBitmap.FilterSmartZoom3(Option: TMedianOption): TBGRACustomBitmap;
|
---|
5356 | begin
|
---|
5357 | Result := BGRAFilters.FilterSmartZoom3(self, Option);
|
---|
5358 | end;
|
---|
5359 |
|
---|
5360 | function TBGRADefaultBitmap.FilterMedian(Option: TMedianOption): TBGRACustomBitmap;
|
---|
5361 | begin
|
---|
5362 | Result := BGRAFilters.FilterMedian(self, option);
|
---|
5363 | end;
|
---|
5364 |
|
---|
5365 | function TBGRADefaultBitmap.FilterSmooth: TBGRACustomBitmap;
|
---|
5366 | begin
|
---|
5367 | Result := BGRAFilters.FilterBlurRadial(self, 3, rbPrecise);
|
---|
5368 | end;
|
---|
5369 |
|
---|
5370 | function TBGRADefaultBitmap.FilterSphere: TBGRACustomBitmap;
|
---|
5371 | begin
|
---|
5372 | Result := BGRAFilters.FilterSphere(self);
|
---|
5373 | end;
|
---|
5374 |
|
---|
5375 | function TBGRADefaultBitmap.FilterTwirl(ACenter: TPoint; ARadius: Single; ATurn: Single=1; AExponent: Single=3): TBGRACustomBitmap;
|
---|
5376 | begin
|
---|
5377 | Result := BGRAFilters.FilterTwirl(self, ACenter, ARadius, ATurn, AExponent);
|
---|
5378 | end;
|
---|
5379 |
|
---|
5380 | function TBGRADefaultBitmap.FilterTwirl(ABounds: TRect; ACenter: TPoint;
|
---|
5381 | ARadius: Single; ATurn: Single; AExponent: Single): TBGRACustomBitmap;
|
---|
5382 | begin
|
---|
5383 | result := BGRAFilters.FilterTwirl(self, ABounds, ACenter, ARadius, ATurn, AExponent);
|
---|
5384 | end;
|
---|
5385 |
|
---|
5386 | function TBGRADefaultBitmap.FilterCylinder: TBGRACustomBitmap;
|
---|
5387 | begin
|
---|
5388 | Result := BGRAFilters.FilterCylinder(self);
|
---|
5389 | end;
|
---|
5390 |
|
---|
5391 | function TBGRADefaultBitmap.FilterPlane: TBGRACustomBitmap;
|
---|
5392 | begin
|
---|
5393 | Result := BGRAFilters.FilterPlane(self);
|
---|
5394 | end;
|
---|
5395 |
|
---|
5396 | function TBGRADefaultBitmap.FilterSharpen(Amount: single = 1): TBGRACustomBitmap;
|
---|
5397 | begin
|
---|
5398 | Result := BGRAFilters.FilterSharpen(self,round(Amount*256));
|
---|
5399 | end;
|
---|
5400 |
|
---|
5401 | function TBGRADefaultBitmap.FilterSharpen(ABounds: TRect; Amount: single
|
---|
5402 | ): TBGRACustomBitmap;
|
---|
5403 | begin
|
---|
5404 | Result := BGRAFilters.FilterSharpen(self,ABounds,round(Amount*256));
|
---|
5405 | end;
|
---|
5406 |
|
---|
5407 | function TBGRADefaultBitmap.FilterContour: TBGRACustomBitmap;
|
---|
5408 | begin
|
---|
5409 | Result := BGRAFilters.FilterContour(self);
|
---|
5410 | end;
|
---|
5411 |
|
---|
5412 | function TBGRADefaultBitmap.FilterBlurRadial(radius: single;
|
---|
5413 | blurType: TRadialBlurType): TBGRACustomBitmap;
|
---|
5414 | begin
|
---|
5415 | Result := BGRAFilters.FilterBlurRadial(self, radius, blurType);
|
---|
5416 | end;
|
---|
5417 |
|
---|
5418 | function TBGRADefaultBitmap.FilterBlurRadial(ABounds: TRect; radius: single;
|
---|
5419 | blurType: TRadialBlurType): TBGRACustomBitmap;
|
---|
5420 | var task: TFilterTask;
|
---|
5421 | begin
|
---|
5422 | task := BGRAFilters.CreateRadialBlurTask(self, ABounds, radius, blurType);
|
---|
5423 | try
|
---|
5424 | result := task.Execute;
|
---|
5425 | finally
|
---|
5426 | task.Free;
|
---|
5427 | end;
|
---|
5428 | end;
|
---|
5429 |
|
---|
5430 | function TBGRADefaultBitmap.FilterBlurRadial(radiusX, radiusY: single;
|
---|
5431 | blurType: TRadialBlurType): TBGRACustomBitmap;
|
---|
5432 | begin
|
---|
5433 | Result := BGRAFilters.FilterBlurRadial(self, radiusX,radiusY, blurType);
|
---|
5434 | end;
|
---|
5435 |
|
---|
5436 | function TBGRADefaultBitmap.FilterBlurRadial(ABounds: TRect; radiusX,
|
---|
5437 | radiusY: single; blurType: TRadialBlurType): TBGRACustomBitmap;
|
---|
5438 | var task: TFilterTask;
|
---|
5439 | begin
|
---|
5440 | task := BGRAFilters.CreateRadialBlurTask(self, ABounds, radiusX,radiusY, blurType);
|
---|
5441 | try
|
---|
5442 | result := task.Execute;
|
---|
5443 | finally
|
---|
5444 | task.Free;
|
---|
5445 | end;
|
---|
5446 | end;
|
---|
5447 |
|
---|
5448 | function TBGRADefaultBitmap.FilterPixelate(pixelSize: integer;
|
---|
5449 | useResample: boolean; filter: TResampleFilter): TBGRACustomBitmap;
|
---|
5450 | begin
|
---|
5451 | Result:= BGRAFilters.FilterPixelate(self, pixelSize, useResample, filter);
|
---|
5452 | end;
|
---|
5453 |
|
---|
5454 | function TBGRADefaultBitmap.FilterBlurMotion(distance: single;
|
---|
5455 | angle: single; oriented: boolean): TBGRACustomBitmap;
|
---|
5456 | begin
|
---|
5457 | Result := BGRAFilters.FilterBlurMotion(self, distance, angle, oriented);
|
---|
5458 | end;
|
---|
5459 |
|
---|
5460 | function TBGRADefaultBitmap.FilterBlurMotion(ABounds: TRect; distance: single;
|
---|
5461 | angle: single; oriented: boolean): TBGRACustomBitmap;
|
---|
5462 | var task: TFilterTask;
|
---|
5463 | begin
|
---|
5464 | task := BGRAFilters.CreateMotionBlurTask(self,ABounds,distance,angle,oriented);
|
---|
5465 | try
|
---|
5466 | Result := task.Execute;
|
---|
5467 | finally
|
---|
5468 | task.Free;
|
---|
5469 | end;
|
---|
5470 | end;
|
---|
5471 |
|
---|
5472 | function TBGRADefaultBitmap.FilterCustomBlur(mask: TBGRACustomBitmap):
|
---|
5473 | TBGRACustomBitmap;
|
---|
5474 | begin
|
---|
5475 | Result := BGRAFilters.FilterBlur(self, mask);
|
---|
5476 | end;
|
---|
5477 |
|
---|
5478 | function TBGRADefaultBitmap.FilterCustomBlur(ABounds: TRect;
|
---|
5479 | mask: TBGRACustomBitmap): TBGRACustomBitmap;
|
---|
5480 | var task: TFilterTask;
|
---|
5481 | begin
|
---|
5482 | task := BGRAFilters.CreateBlurTask(self, ABounds, mask);
|
---|
5483 | try
|
---|
5484 | result := task.Execute;
|
---|
5485 | finally
|
---|
5486 | task.Free;
|
---|
5487 | end;
|
---|
5488 | end;
|
---|
5489 |
|
---|
5490 | function TBGRADefaultBitmap.FilterEmboss(angle: single;
|
---|
5491 | AStrength: integer; AOptions: TEmbossOptions): TBGRACustomBitmap;
|
---|
5492 | begin
|
---|
5493 | Result := BGRAFilters.FilterEmboss(self, angle, AStrength, AOptions);
|
---|
5494 | end;
|
---|
5495 |
|
---|
5496 | function TBGRADefaultBitmap.FilterEmboss(angle: single; ABounds: TRect;
|
---|
5497 | AStrength: integer; AOptions: TEmbossOptions): TBGRACustomBitmap;
|
---|
5498 | begin
|
---|
5499 | Result := BGRAFilters.FilterEmboss(self, angle, ABounds, AStrength, AOptions);
|
---|
5500 | end;
|
---|
5501 |
|
---|
5502 | function TBGRADefaultBitmap.FilterEmbossHighlight(FillSelection: boolean):
|
---|
5503 | TBGRACustomBitmap;
|
---|
5504 | begin
|
---|
5505 | Result := BGRAFilters.FilterEmbossHighlight(self, FillSelection, BGRAPixelTransparent);
|
---|
5506 | end;
|
---|
5507 |
|
---|
5508 | function TBGRADefaultBitmap.FilterEmbossHighlight(FillSelection: boolean;
|
---|
5509 | BorderColor: TBGRAPixel): TBGRACustomBitmap;
|
---|
5510 | begin
|
---|
5511 | Result := BGRAFilters.FilterEmbossHighlight(self, FillSelection, BorderColor);
|
---|
5512 | end;
|
---|
5513 |
|
---|
5514 | function TBGRADefaultBitmap.FilterEmbossHighlight(FillSelection: boolean;
|
---|
5515 | BorderColor: TBGRAPixel; var Offset: TPoint): TBGRACustomBitmap;
|
---|
5516 | begin
|
---|
5517 | Result := BGRAFilters.FilterEmbossHighlightOffset(self, FillSelection, BorderColor, Offset);
|
---|
5518 | end;
|
---|
5519 |
|
---|
5520 | function TBGRADefaultBitmap.FilterGrayscale: TBGRACustomBitmap;
|
---|
5521 | begin
|
---|
5522 | Result := BGRAFilters.FilterGrayscale(self);
|
---|
5523 | end;
|
---|
5524 |
|
---|
5525 | function TBGRADefaultBitmap.FilterGrayscale(ABounds: TRect): TBGRACustomBitmap;
|
---|
5526 | begin
|
---|
5527 | Result := BGRAFilters.FilterGrayscale(self, ABounds);
|
---|
5528 | end;
|
---|
5529 |
|
---|
5530 | function TBGRADefaultBitmap.FilterNormalize(eachChannel: boolean = True):
|
---|
5531 | TBGRACustomBitmap;
|
---|
5532 | begin
|
---|
5533 | Result := BGRAFilters.FilterNormalize(self, eachChannel);
|
---|
5534 | end;
|
---|
5535 |
|
---|
5536 | function TBGRADefaultBitmap.FilterNormalize(ABounds: TRect; eachChannel: boolean): TBGRACustomBitmap;
|
---|
5537 | begin
|
---|
5538 | Result := BGRAFilters.FilterNormalize(self, ABounds, eachChannel);
|
---|
5539 | end;
|
---|
5540 |
|
---|
5541 | function TBGRADefaultBitmap.FilterRotate(origin: TPointF;
|
---|
5542 | angle: single; correctBlur: boolean): TBGRACustomBitmap;
|
---|
5543 | begin
|
---|
5544 | Result := BGRAFilters.FilterRotate(self, origin, angle, correctBlur);
|
---|
5545 | end;
|
---|
5546 |
|
---|
5547 | function TBGRADefaultBitmap.FilterAffine(AMatrix: TAffineMatrix;
|
---|
5548 | correctBlur: boolean): TBGRACustomBitmap;
|
---|
5549 | begin
|
---|
5550 | Result := NewBitmap(Width,Height);
|
---|
5551 | Result.PutImageAffine(AMatrix,self,255,correctBlur);
|
---|
5552 | end;
|
---|
5553 |
|
---|
5554 | function TBGRADefaultBitmap.GetHasTransparentPixels: boolean;
|
---|
5555 | var
|
---|
5556 | p: PBGRAPixel;
|
---|
5557 | n: integer;
|
---|
5558 | begin
|
---|
5559 | p := Data;
|
---|
5560 | for n := NbPixels - 1 downto 0 do
|
---|
5561 | begin
|
---|
5562 | if p^.alpha <> 255 then
|
---|
5563 | begin
|
---|
5564 | Result := True;
|
---|
5565 | exit;
|
---|
5566 | end;
|
---|
5567 | Inc(p);
|
---|
5568 | end;
|
---|
5569 | Result := False;
|
---|
5570 | end;
|
---|
5571 |
|
---|
5572 | function TBGRADefaultBitmap.GetHasSemiTransparentPixels: boolean;
|
---|
5573 | var
|
---|
5574 | n: integer;
|
---|
5575 | p: PBGRAPixel;
|
---|
5576 | begin
|
---|
5577 | p := Data;
|
---|
5578 | for n := NbPixels - 1 downto 0 do
|
---|
5579 | begin
|
---|
5580 | if (p^.alpha > 0) and (p^.alpha < 255) then
|
---|
5581 | begin
|
---|
5582 | result := true;
|
---|
5583 | exit;
|
---|
5584 | end;
|
---|
5585 | inc(p);
|
---|
5586 | end;
|
---|
5587 | result := false;
|
---|
5588 | end;
|
---|
5589 |
|
---|
5590 | function TBGRADefaultBitmap.GetAverageColor: TColor;
|
---|
5591 | var
|
---|
5592 | pix: TBGRAPixel;
|
---|
5593 | begin
|
---|
5594 | pix := GetAveragePixel;
|
---|
5595 | {$hints off}
|
---|
5596 | if pix.alpha = 0 then
|
---|
5597 | result := clNone else
|
---|
5598 | result := RGBToColor(pix.red,pix.green,pix.blue);
|
---|
5599 | {$hints on}
|
---|
5600 | end;
|
---|
5601 |
|
---|
5602 | function TBGRADefaultBitmap.GetAveragePixel: TBGRAPixel;
|
---|
5603 | var
|
---|
5604 | n: integer;
|
---|
5605 | p: PBGRAPixel;
|
---|
5606 | r, g, b, sum: double;
|
---|
5607 | alpha: double;
|
---|
5608 | begin
|
---|
5609 | sum := 0;
|
---|
5610 | r := 0;
|
---|
5611 | g := 0;
|
---|
5612 | b := 0;
|
---|
5613 | p := Data;
|
---|
5614 | for n := NbPixels - 1 downto 0 do
|
---|
5615 | begin
|
---|
5616 | alpha := p^.alpha / 255;
|
---|
5617 | sum += alpha;
|
---|
5618 | r += p^.red * alpha;
|
---|
5619 | g += p^.green * alpha;
|
---|
5620 | b += p^.blue * alpha;
|
---|
5621 | Inc(p);
|
---|
5622 | end;
|
---|
5623 | if sum = 0 then
|
---|
5624 | Result := BGRAPixelTransparent
|
---|
5625 | else
|
---|
5626 | Result := BGRA(round(r / sum),round(g / sum),round(b / sum),round(sum*255/NbPixels));
|
---|
5627 | end;
|
---|
5628 |
|
---|
5629 | function TBGRADefaultBitmap.GetPenJoinStyle: TPenJoinStyle;
|
---|
5630 | begin
|
---|
5631 | result := FPenStroker.JoinStyle;
|
---|
5632 | end;
|
---|
5633 |
|
---|
5634 | procedure TBGRADefaultBitmap.SetPenJoinStyle(const AValue: TPenJoinStyle);
|
---|
5635 | begin
|
---|
5636 | FPenStroker.JoinStyle := AValue;
|
---|
5637 | end;
|
---|
5638 |
|
---|
5639 | function TBGRADefaultBitmap.GetPenMiterLimit: single;
|
---|
5640 | begin
|
---|
5641 | result := FPenStroker.MiterLimit;
|
---|
5642 | end;
|
---|
5643 |
|
---|
5644 | procedure TBGRADefaultBitmap.SetPenMiterLimit(const AValue: single);
|
---|
5645 | begin
|
---|
5646 | FPenStroker.MiterLimit := AValue;
|
---|
5647 | end;
|
---|
5648 |
|
---|
5649 | procedure TBGRADefaultBitmap.SetCanvasOpacity(AValue: byte);
|
---|
5650 | begin
|
---|
5651 | LoadFromBitmapIfNeeded;
|
---|
5652 | FCanvasOpacity := AValue;
|
---|
5653 | end;
|
---|
5654 |
|
---|
5655 | function TBGRADefaultBitmap.GetDataPtr: PBGRAPixel;
|
---|
5656 | begin
|
---|
5657 | LoadFromBitmapIfNeeded;
|
---|
5658 | Result := FData;
|
---|
5659 | end;
|
---|
5660 |
|
---|
5661 | {----------------------------- Resample ---------------------------------------}
|
---|
5662 |
|
---|
5663 | function TBGRADefaultBitmap.FineResample(NewWidth, NewHeight: integer):
|
---|
5664 | TBGRACustomBitmap;
|
---|
5665 | begin
|
---|
5666 | Result := BGRAResample.FineResample(self, NewWidth, NewHeight, ResampleFilter);
|
---|
5667 | end;
|
---|
5668 |
|
---|
5669 | function TBGRADefaultBitmap.SimpleStretch(NewWidth, NewHeight: integer):
|
---|
5670 | TBGRACustomBitmap;
|
---|
5671 | begin
|
---|
5672 | Result := BGRAResample.SimpleStretch(self, NewWidth, NewHeight);
|
---|
5673 | end;
|
---|
5674 |
|
---|
5675 | function TBGRADefaultBitmap.Resample(newWidth, newHeight: integer;
|
---|
5676 | mode: TResampleMode): TBGRACustomBitmap;
|
---|
5677 | begin
|
---|
5678 | case mode of
|
---|
5679 | rmFineResample: Result := FineResample(newWidth, newHeight);
|
---|
5680 | rmSimpleStretch: Result := SimpleStretch(newWidth, newHeight);
|
---|
5681 | else
|
---|
5682 | Result := nil;
|
---|
5683 | end;
|
---|
5684 | end;
|
---|
5685 |
|
---|
5686 | {-------------------------------- Data functions ------------------------}
|
---|
5687 |
|
---|
5688 | { Flip vertically the bitmap. Use a temporary line to store top line,
|
---|
5689 | assign bottom line to top line, then assign temporary line to bottom line.
|
---|
5690 |
|
---|
5691 | It is an involution, i.e it does nothing when applied twice }
|
---|
5692 | procedure TBGRADefaultBitmap.VerticalFlip(ARect: TRect);
|
---|
5693 | var
|
---|
5694 | yb,h2: integer;
|
---|
5695 | line: PBGRAPixel;
|
---|
5696 | linesize, delta: integer;
|
---|
5697 | PStart: PBGRAPixel;
|
---|
5698 | PEnd: PBGRAPixel;
|
---|
5699 | begin
|
---|
5700 | if FData = nil then
|
---|
5701 | exit;
|
---|
5702 |
|
---|
5703 | if (ARect.Right <= ARect.Left) or (ARect.Bottom <= ARect.Top) then exit;
|
---|
5704 | if not IntersectRect(ARect, ARect, rect(0,0,Width,Height)) then exit;
|
---|
5705 | LoadFromBitmapIfNeeded;
|
---|
5706 | linesize := (ARect.Right-ARect.Left) * sizeof(TBGRAPixel);
|
---|
5707 | line := nil;
|
---|
5708 | getmem(line, linesize);
|
---|
5709 | PStart := GetScanlineFast(ARect.Top)+ARect.Left;
|
---|
5710 | PEnd := GetScanlineFast(ARect.Bottom-1)+ARect.Left;
|
---|
5711 | h2 := (ARect.Bottom-ARect.Top) div 2;
|
---|
5712 | if LineOrder = riloTopToBottom then delta := +Width else delta := -Width;
|
---|
5713 | for yb := h2-1 downto 0 do
|
---|
5714 | begin
|
---|
5715 | move(PStart^, line^, linesize);
|
---|
5716 | move(PEnd^, PStart^, linesize);
|
---|
5717 | move(line^, PEnd^, linesize);
|
---|
5718 | Inc(PStart, delta);
|
---|
5719 | Dec(PEnd, delta);
|
---|
5720 | end;
|
---|
5721 | freemem(line);
|
---|
5722 | InvalidateBitmap;
|
---|
5723 |
|
---|
5724 | if Assigned(XorMask) then XorMask.VerticalFlip(ARect);
|
---|
5725 | end;
|
---|
5726 |
|
---|
5727 | { Flip horizontally. Swap left pixels with right pixels on each line.
|
---|
5728 |
|
---|
5729 | It is an involution, i.e it does nothing when applied twice}
|
---|
5730 | procedure TBGRADefaultBitmap.HorizontalFlip(ARect: TRect);
|
---|
5731 | var
|
---|
5732 | yb, xb, w: integer;
|
---|
5733 | PStart: PBGRAPixel;
|
---|
5734 | PEnd: PBGRAPixel;
|
---|
5735 | temp: TBGRAPixel;
|
---|
5736 | begin
|
---|
5737 | if FData = nil then
|
---|
5738 | exit;
|
---|
5739 |
|
---|
5740 | if (ARect.Right <= ARect.Left) or (ARect.Bottom <= ARect.Top) then exit;
|
---|
5741 | if not IntersectRect(ARect, ARect, rect(0,0,Width,Height)) then exit;
|
---|
5742 | w := ARect.Right-ARect.Left;
|
---|
5743 | LoadFromBitmapIfNeeded;
|
---|
5744 | for yb := ARect.Top to ARect.Bottom-1 do
|
---|
5745 | begin
|
---|
5746 | PStart := GetScanlineFast(yb)+ARect.Left;
|
---|
5747 | PEnd := PStart + w;
|
---|
5748 | for xb := 0 to (w div 2) - 1 do
|
---|
5749 | begin
|
---|
5750 | Dec(PEnd);
|
---|
5751 | temp := PStart^;
|
---|
5752 | PStart^ := PEnd^;
|
---|
5753 | PEnd^ := temp;
|
---|
5754 | Inc(PStart);
|
---|
5755 | end;
|
---|
5756 | end;
|
---|
5757 | InvalidateBitmap;
|
---|
5758 |
|
---|
5759 | if Assigned(XorMask) then XorMask.HorizontalFlip(ARect);
|
---|
5760 | end;
|
---|
5761 |
|
---|
5762 | { Return a new bitmap rotated in a clock wise direction. }
|
---|
5763 | function TBGRADefaultBitmap.RotateCW: TBGRACustomBitmap;
|
---|
5764 | var
|
---|
5765 | psrc, pdest: PBGRAPixel;
|
---|
5766 | yb, xb: integer;
|
---|
5767 | delta: integer;
|
---|
5768 | begin
|
---|
5769 | LoadFromBitmapIfNeeded;
|
---|
5770 | Result := NewBitmap(Height, Width);
|
---|
5771 | if Result.LineOrder = riloTopToBottom then
|
---|
5772 | delta := Result.Width
|
---|
5773 | else
|
---|
5774 | delta := -Result.Width;
|
---|
5775 | for yb := 0 to Height - 1 do
|
---|
5776 | begin
|
---|
5777 | psrc := Scanline[yb];
|
---|
5778 | pdest := Result.Scanline[0] + (Height - 1 - yb);
|
---|
5779 | for xb := 0 to Width - 1 do
|
---|
5780 | begin
|
---|
5781 | pdest^ := psrc^;
|
---|
5782 | Inc(psrc);
|
---|
5783 | Inc(pdest, delta);
|
---|
5784 | end;
|
---|
5785 | end;
|
---|
5786 |
|
---|
5787 | if Assigned(XorMask) then TBGRADefaultBitmap(result).FXorMask := self.XorMask.RotateCW;
|
---|
5788 | end;
|
---|
5789 |
|
---|
5790 | { Return a new bitmap rotated in a counter clock wise direction. }
|
---|
5791 | function TBGRADefaultBitmap.RotateCCW: TBGRACustomBitmap;
|
---|
5792 | var
|
---|
5793 | psrc, pdest: PBGRAPixel;
|
---|
5794 | yb, xb: integer;
|
---|
5795 | delta: integer;
|
---|
5796 | begin
|
---|
5797 | LoadFromBitmapIfNeeded;
|
---|
5798 | Result := NewBitmap(Height, Width);
|
---|
5799 | if Result.LineOrder = riloTopToBottom then
|
---|
5800 | delta := Result.Width
|
---|
5801 | else
|
---|
5802 | delta := -Result.Width;
|
---|
5803 | for yb := 0 to Height - 1 do
|
---|
5804 | begin
|
---|
5805 | psrc := Scanline[yb];
|
---|
5806 | pdest := Result.Scanline[Width - 1] + yb;
|
---|
5807 | for xb := 0 to Width - 1 do
|
---|
5808 | begin
|
---|
5809 | pdest^ := psrc^;
|
---|
5810 | Inc(psrc);
|
---|
5811 | Dec(pdest, delta);
|
---|
5812 | end;
|
---|
5813 | end;
|
---|
5814 |
|
---|
5815 | if Assigned(XorMask) then TBGRADefaultBitmap(result).FXorMask := self.XorMask.RotateCCW;
|
---|
5816 | end;
|
---|
5817 |
|
---|
5818 | { Compute negative with gamma correction. A negative contains
|
---|
5819 | complentary colors (black becomes white etc.).
|
---|
5820 |
|
---|
5821 | It is NOT EXACTLY an involution, when applied twice, some color information is lost }
|
---|
5822 | procedure TBGRADefaultBitmap.Negative;
|
---|
5823 | begin
|
---|
5824 | TBGRAFilterScannerNegative.ComputeFilterInplace(self, rect(0,0,FWidth,FHeight), True);
|
---|
5825 | end;
|
---|
5826 |
|
---|
5827 | procedure TBGRADefaultBitmap.NegativeRect(ABounds: TRect);
|
---|
5828 | begin
|
---|
5829 | if not IntersectRect(ABounds,ABounds,ClipRect) then exit;
|
---|
5830 | TBGRAFilterScannerNegative.ComputeFilterInplace(self, ABounds, True);
|
---|
5831 | end;
|
---|
5832 |
|
---|
5833 | { Compute negative without gamma correction.
|
---|
5834 |
|
---|
5835 | It is an involution, i.e it does nothing when applied twice }
|
---|
5836 | procedure TBGRADefaultBitmap.LinearNegative;
|
---|
5837 | begin
|
---|
5838 | TBGRAFilterScannerNegative.ComputeFilterInplace(self, rect(0,0,FWidth,FHeight), False);
|
---|
5839 | end;
|
---|
5840 |
|
---|
5841 | procedure TBGRADefaultBitmap.LinearNegativeRect(ABounds: TRect);
|
---|
5842 | begin
|
---|
5843 | if not IntersectRect(ABounds,ABounds,ClipRect) then exit;
|
---|
5844 | TBGRAFilterScannerNegative.ComputeFilterInplace(self, ABounds, False);
|
---|
5845 | end;
|
---|
5846 |
|
---|
5847 | procedure TBGRADefaultBitmap.InplaceGrayscale(AGammaCorrection: boolean = true);
|
---|
5848 | begin
|
---|
5849 | TBGRAFilterScannerGrayscale.ComputeFilterInplace(self, rect(0,0,FWidth,FHeight), AGammaCorrection);
|
---|
5850 | end;
|
---|
5851 |
|
---|
5852 | procedure TBGRADefaultBitmap.InplaceGrayscale(ABounds: TRect; AGammaCorrection: boolean = true);
|
---|
5853 | begin
|
---|
5854 | if not IntersectRect(ABounds,ABounds,ClipRect) then exit;
|
---|
5855 | TBGRAFilterScannerGrayscale.ComputeFilterInplace(self, ABounds, AGammaCorrection);
|
---|
5856 | end;
|
---|
5857 |
|
---|
5858 | procedure TBGRADefaultBitmap.InplaceNormalize(AEachChannel: boolean);
|
---|
5859 | begin
|
---|
5860 | InplaceNormalize(rect(0,0,Width,Height),AEachChannel);
|
---|
5861 | end;
|
---|
5862 |
|
---|
5863 | procedure TBGRADefaultBitmap.InplaceNormalize(ABounds: TRect;
|
---|
5864 | AEachChannel: boolean);
|
---|
5865 | var scanner: TBGRAFilterScannerNormalize;
|
---|
5866 | begin
|
---|
5867 | if not IntersectRect(ABounds,ABounds,ClipRect) then exit;
|
---|
5868 | scanner := TBGRAFilterScannerNormalize.Create(self,Point(0,0),ABounds,AEachChannel);
|
---|
5869 | FillRect(ABounds,scanner,dmSet);
|
---|
5870 | scanner.Free;
|
---|
5871 | end;
|
---|
5872 |
|
---|
5873 | { Swap red and blue channels. Useful when RGB order is swapped.
|
---|
5874 |
|
---|
5875 | It is an involution, i.e it does nothing when applied twice }
|
---|
5876 | procedure TBGRADefaultBitmap.SwapRedBlue;
|
---|
5877 | begin
|
---|
5878 | TBGRAFilterScannerSwapRedBlue.ComputeFilterInplace(self, rect(0,0,FWidth,FHeight), False);
|
---|
5879 | end;
|
---|
5880 |
|
---|
5881 | procedure TBGRADefaultBitmap.SwapRedBlue(ARect: TRect);
|
---|
5882 | begin
|
---|
5883 | if not CheckClippedRectBounds(ARect.Left,ARect.Top,ARect.Right,ARect.Bottom) then exit;
|
---|
5884 | TBGRAFilterScannerSwapRedBlue.ComputeFilterInplace(self, ARect, False);
|
---|
5885 | end;
|
---|
5886 |
|
---|
5887 | { Convert a grayscale image into a black image with alpha value }
|
---|
5888 | procedure TBGRADefaultBitmap.GrayscaleToAlpha;
|
---|
5889 | var
|
---|
5890 | n: integer;
|
---|
5891 | p: PLongword;
|
---|
5892 | begin
|
---|
5893 | LoadFromBitmapIfNeeded;
|
---|
5894 | p := PLongword(Data);
|
---|
5895 | n := NbPixels;
|
---|
5896 | if n = 0 then
|
---|
5897 | exit;
|
---|
5898 | repeat
|
---|
5899 | p^ := (p^ shr TBGRAPixel_RedShift and $FF) shl TBGRAPixel_AlphaShift;
|
---|
5900 | Inc(p);
|
---|
5901 | Dec(n);
|
---|
5902 | until n = 0;
|
---|
5903 | InvalidateBitmap;
|
---|
5904 | end;
|
---|
5905 |
|
---|
5906 | procedure TBGRADefaultBitmap.AlphaToGrayscale;
|
---|
5907 | var
|
---|
5908 | n: integer;
|
---|
5909 | temp: longword;
|
---|
5910 | p: PLongword;
|
---|
5911 | begin
|
---|
5912 | LoadFromBitmapIfNeeded;
|
---|
5913 | p := PLongword(Data);
|
---|
5914 | n := NbPixels;
|
---|
5915 | if n = 0 then
|
---|
5916 | exit;
|
---|
5917 | repeat
|
---|
5918 | temp := (p^ shr TBGRAPixel_AlphaShift) and $ff;
|
---|
5919 | p^ := (temp shl TBGRAPixel_RedShift) or (temp shl TBGRAPixel_GreenShift)
|
---|
5920 | or (temp shl TBGRAPixel_BlueShift) or ($ff shl TBGRAPixel_AlphaShift);
|
---|
5921 | Inc(p);
|
---|
5922 | Dec(n);
|
---|
5923 | until n = 0;
|
---|
5924 | InvalidateBitmap;
|
---|
5925 | end;
|
---|
5926 |
|
---|
5927 | { Apply a mask to the bitmap. It means that alpha channel is
|
---|
5928 | changed according to grayscale values of the mask.
|
---|
5929 |
|
---|
5930 | See : http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_5 }
|
---|
5931 | procedure TBGRADefaultBitmap.ApplyMask(mask: TBGRACustomBitmap; ARect: TRect; AMaskRectTopLeft: TPoint);
|
---|
5932 | var
|
---|
5933 | p, pmask: PBGRAPixel;
|
---|
5934 | yb, xb: integer;
|
---|
5935 | MaskOffsetX,MaskOffsetY,w: integer;
|
---|
5936 | opacity: NativeUint;
|
---|
5937 | begin
|
---|
5938 | if (ARect.Right <= ARect.Left) or (ARect.Bottom <= ARect.Top) then exit;
|
---|
5939 | IntersectRect(ARect, ARect, rect(0,0,Width,Height));
|
---|
5940 | MaskOffsetX := AMaskRectTopLeft.x - ARect.Left;
|
---|
5941 | MaskOffsetY := AMaskRectTopLeft.y - ARect.Top;
|
---|
5942 | OffsetRect(ARect, MaskOffsetX, MaskOffsetY);
|
---|
5943 | IntersectRect(ARect, ARect, rect(0,0,mask.Width,mask.Height));
|
---|
5944 | OffsetRect(ARect, -MaskOffsetX, -MaskOffsetY);
|
---|
5945 |
|
---|
5946 | LoadFromBitmapIfNeeded;
|
---|
5947 | w := ARect.Right-ARect.Left-1;
|
---|
5948 | for yb := ARect.Top to ARect.Bottom - 1 do
|
---|
5949 | begin
|
---|
5950 | p := Scanline[yb]+ARect.Left;
|
---|
5951 | pmask := Mask.Scanline[yb+MaskOffsetY]+ARect.Left+MaskOffsetX;
|
---|
5952 | for xb := w downto 0 do
|
---|
5953 | begin
|
---|
5954 | opacity := ApplyOpacity(p^.alpha, pmask^.red);
|
---|
5955 | if opacity = 0 then p^ := BGRAPixelTransparent
|
---|
5956 | else p^.alpha := opacity;
|
---|
5957 | Inc(p);
|
---|
5958 | Inc(pmask);
|
---|
5959 | end;
|
---|
5960 | end;
|
---|
5961 | InvalidateBitmap;
|
---|
5962 | end;
|
---|
5963 |
|
---|
5964 | function TBGRADefaultBitmap.GetMaskFromAlpha: TBGRACustomBitmap;
|
---|
5965 | var y,x: integer;
|
---|
5966 | psrc, pdest: PBGRAPixel;
|
---|
5967 | begin
|
---|
5968 | result := BGRABitmapFactory.Create(Width,Height);
|
---|
5969 | for y := 0 to self.Height-1 do
|
---|
5970 | begin
|
---|
5971 | psrc := self.ScanLine[y];
|
---|
5972 | pdest := result.ScanLine[y];
|
---|
5973 | for x := 0 to self.Width-1 do
|
---|
5974 | begin
|
---|
5975 | pdest^ := BGRA(psrc^.alpha,psrc^.alpha,psrc^.alpha);
|
---|
5976 | inc(psrc);
|
---|
5977 | inc(pdest);
|
---|
5978 | end;
|
---|
5979 | end;
|
---|
5980 | end;
|
---|
5981 |
|
---|
5982 | procedure TBGRADefaultBitmap.ApplyGlobalOpacity(alpha: byte);
|
---|
5983 | var
|
---|
5984 | p: PBGRAPixel;
|
---|
5985 | i: integer;
|
---|
5986 | begin
|
---|
5987 | if alpha = 0 then
|
---|
5988 | FillTransparent
|
---|
5989 | else
|
---|
5990 | if alpha <> 255 then
|
---|
5991 | begin
|
---|
5992 | p := Data;
|
---|
5993 | for i := NbPixels - 1 downto 0 do
|
---|
5994 | begin
|
---|
5995 | p^.alpha := ApplyOpacity(p^.alpha, alpha);
|
---|
5996 | Inc(p);
|
---|
5997 | end;
|
---|
5998 | end;
|
---|
5999 | end;
|
---|
6000 |
|
---|
6001 | procedure TBGRADefaultBitmap.ApplyGlobalOpacity(ABounds: TRect; alpha: byte);
|
---|
6002 | var p: PBGRAPixel;
|
---|
6003 | xb,yb,xcount: integer;
|
---|
6004 | begin
|
---|
6005 | if not IntersectRect(ABounds,ABounds,ClipRect) then exit;
|
---|
6006 | xcount := ABounds.Right-ABounds.Left;
|
---|
6007 | for yb := ABounds.Top to ABounds.Bottom-1 do
|
---|
6008 | begin
|
---|
6009 | p := ScanLine[yb]+ABounds.Left;
|
---|
6010 | for xb := xcount-1 downto 0 do
|
---|
6011 | begin
|
---|
6012 | p^.alpha := ApplyOpacity(p^.alpha, alpha);
|
---|
6013 | Inc(p);
|
---|
6014 | end;
|
---|
6015 | end;
|
---|
6016 | InvalidateBitmap;
|
---|
6017 | end;
|
---|
6018 |
|
---|
6019 | procedure TBGRADefaultBitmap.ConvertToLinearRGB;
|
---|
6020 | var p: PBGRAPixel;
|
---|
6021 | n: integer;
|
---|
6022 | begin
|
---|
6023 | p := Data;
|
---|
6024 | for n := NbPixels-1 downto 0 do
|
---|
6025 | begin
|
---|
6026 | p^.red := GammaExpansionTab[p^.red] shr 8;
|
---|
6027 | p^.green := GammaExpansionTab[p^.green] shr 8;
|
---|
6028 | p^.blue := GammaExpansionTab[p^.blue] shr 8;
|
---|
6029 | inc(p);
|
---|
6030 | end;
|
---|
6031 | end;
|
---|
6032 |
|
---|
6033 | procedure TBGRADefaultBitmap.ConvertFromLinearRGB;
|
---|
6034 | var p: PBGRAPixel;
|
---|
6035 | n: integer;
|
---|
6036 | begin
|
---|
6037 | p := Data;
|
---|
6038 | for n := NbPixels-1 downto 0 do
|
---|
6039 | begin
|
---|
6040 | p^.red := GammaCompressionTab[p^.red shl 8 + p^.red];
|
---|
6041 | p^.green := GammaCompressionTab[p^.green shl 8 + p^.green];
|
---|
6042 | p^.blue := GammaCompressionTab[p^.blue shl 8 + p^.blue];
|
---|
6043 | inc(p);
|
---|
6044 | end;
|
---|
6045 | end;
|
---|
6046 |
|
---|
6047 | procedure TBGRADefaultBitmap.DrawCheckers(ARect: TRect; AColorEven,
|
---|
6048 | AColorOdd: TBGRAPixel);
|
---|
6049 | const tx = 8; ty = 8; //must be a power of 2
|
---|
6050 | xMask = tx*2-1;
|
---|
6051 | var xcount,patY,w,n,patY1,patY2m1,patX,patX1: NativeInt;
|
---|
6052 | pdest: PBGRAPixel;
|
---|
6053 | delta: PtrInt;
|
---|
6054 | actualRect: TRect;
|
---|
6055 | begin
|
---|
6056 | actualRect := ARect;
|
---|
6057 | IntersectRect(actualRect, ARect, self.ClipRect);
|
---|
6058 | w := actualRect.Right-actualRect.Left;
|
---|
6059 | if (w <= 0) or (actualRect.Bottom <= actualRect.Top) then exit;
|
---|
6060 | delta := self.Width;
|
---|
6061 | if self.LineOrder = riloBottomToTop then delta := -delta;
|
---|
6062 | delta := (delta-w)*SizeOf(TBGRAPixel);
|
---|
6063 | pdest := self.ScanLine[actualRect.Top]+actualRect.left;
|
---|
6064 | patY1 := actualRect.Top - ARect.Top;
|
---|
6065 | patY2m1 := actualRect.Bottom - ARect.Top-1;
|
---|
6066 | patX1 := (actualRect.Left - ARect.Left) and xMask;
|
---|
6067 | for patY := patY1 to patY2m1 do
|
---|
6068 | begin
|
---|
6069 | xcount := w;
|
---|
6070 | if patY and ty = 0 then
|
---|
6071 | patX := patX1
|
---|
6072 | else
|
---|
6073 | patX := (patX1+tx) and xMask;
|
---|
6074 | while xcount > 0 do
|
---|
6075 | begin
|
---|
6076 | if patX and tx = 0 then
|
---|
6077 | begin
|
---|
6078 | n := 8-patX;
|
---|
6079 | if n > xcount then n := xcount;
|
---|
6080 | FillDWord(pdest^,n,DWord(AColorEven));
|
---|
6081 | dec(xcount,n);
|
---|
6082 | inc(pdest,n);
|
---|
6083 | patX := tx;
|
---|
6084 | end else
|
---|
6085 | begin
|
---|
6086 | n := 16-patX;
|
---|
6087 | if n > xcount then n := xcount;
|
---|
6088 | FillDWord(pdest^,n,DWord(AColorOdd));
|
---|
6089 | dec(xcount,n);
|
---|
6090 | inc(pdest,n);
|
---|
6091 | patX := 0;
|
---|
6092 | end;
|
---|
6093 | end;
|
---|
6094 | inc(pbyte(pdest),delta);
|
---|
6095 | end;
|
---|
6096 | self.InvalidateBitmap;
|
---|
6097 | end;
|
---|
6098 |
|
---|
6099 | function TBGRADefaultBitmap.GetDifferenceBounds(ABitmap: TBGRACustomBitmap): TRect;
|
---|
6100 | var
|
---|
6101 | minx, miny, maxx, maxy: integer;
|
---|
6102 | xb, yb: integer;
|
---|
6103 | p, p2: PBGRAPixel;
|
---|
6104 | begin
|
---|
6105 | if (ABitmap.Width <> Width) or (ABitmap.Height <> Height) then
|
---|
6106 | begin
|
---|
6107 | result := rect(0,0,Width,Height);
|
---|
6108 | if ABitmap.Width > result.Right then result.Right := ABitmap.Width;
|
---|
6109 | if ABitmap.Height > result.bottom then result.bottom := ABitmap.Height;
|
---|
6110 | exit;
|
---|
6111 | end;
|
---|
6112 | maxx := -1;
|
---|
6113 | maxy := -1;
|
---|
6114 | minx := self.Width;
|
---|
6115 | miny := self.Height;
|
---|
6116 | for yb := 0 to self.Height - 1 do
|
---|
6117 | begin
|
---|
6118 | p := self.ScanLine[yb];
|
---|
6119 | p2 := ABitmap.ScanLine[yb];
|
---|
6120 | for xb := 0 to self.Width - 1 do
|
---|
6121 | begin
|
---|
6122 | if p^ <> p2^ then
|
---|
6123 | begin
|
---|
6124 | if xb < minx then
|
---|
6125 | minx := xb;
|
---|
6126 | if yb < miny then
|
---|
6127 | miny := yb;
|
---|
6128 | if xb > maxx then
|
---|
6129 | maxx := xb;
|
---|
6130 | if yb > maxy then
|
---|
6131 | maxy := yb;
|
---|
6132 | end;
|
---|
6133 | Inc(p);
|
---|
6134 | Inc(p2);
|
---|
6135 | end;
|
---|
6136 | end;
|
---|
6137 | if minx > maxx then
|
---|
6138 | begin
|
---|
6139 | Result.left := 0;
|
---|
6140 | Result.top := 0;
|
---|
6141 | Result.right := 0;
|
---|
6142 | Result.bottom := 0;
|
---|
6143 | end
|
---|
6144 | else
|
---|
6145 | begin
|
---|
6146 | Result.left := minx;
|
---|
6147 | Result.top := miny;
|
---|
6148 | Result.right := maxx + 1;
|
---|
6149 | Result.bottom := maxy + 1;
|
---|
6150 | end;
|
---|
6151 | end;
|
---|
6152 |
|
---|
6153 | { Make a copy of the transparent bitmap to a TBitmap with a background color
|
---|
6154 | instead of transparency }
|
---|
6155 | function TBGRADefaultBitmap.MakeBitmapCopy(BackgroundColor: TColor): TBitmap;
|
---|
6156 | var
|
---|
6157 | opaqueCopy: TBGRACustomBitmap;
|
---|
6158 | begin
|
---|
6159 | Result := TBitmap.Create;
|
---|
6160 | Result.Width := Width;
|
---|
6161 | Result.Height := Height;
|
---|
6162 | opaqueCopy := NewBitmap(Width, Height);
|
---|
6163 | opaqueCopy.Fill(ColorToRGB(BackgroundColor));
|
---|
6164 | opaqueCopy.PutImage(0, 0, self, dmDrawWithTransparency);
|
---|
6165 | opaqueCopy.Draw(Result.canvas, 0, 0, True);
|
---|
6166 | opaqueCopy.Free;
|
---|
6167 | end;
|
---|
6168 |
|
---|
6169 | { Get a part of the image with repetition in both directions. It means
|
---|
6170 | that if the bounds are within the image, the result is just that part
|
---|
6171 | of the image, but if the bounds are bigger than the image, the image
|
---|
6172 | is tiled. }
|
---|
6173 | function TBGRADefaultBitmap.GetPart(ARect: TRect): TBGRACustomBitmap;
|
---|
6174 | var
|
---|
6175 | copywidth, copyheight, widthleft, heightleft, curxin, curyin, xdest,
|
---|
6176 | ydest, tx, ty: integer;
|
---|
6177 | begin
|
---|
6178 | tx := ARect.Right - ARect.Left;
|
---|
6179 | ty := ARect.Bottom - ARect.Top;
|
---|
6180 |
|
---|
6181 | if (tx <= 0) or (ty <= 0) then
|
---|
6182 | begin
|
---|
6183 | result := nil;
|
---|
6184 | exit;
|
---|
6185 | end;
|
---|
6186 |
|
---|
6187 | LoadFromBitmapIfNeeded;
|
---|
6188 | if ARect.Left >= Width then
|
---|
6189 | ARect.Left := ARect.Left mod Width
|
---|
6190 | else
|
---|
6191 | if ARect.Left < 0 then
|
---|
6192 | ARect.Left := Width - ((-ARect.Left) mod Width);
|
---|
6193 | ARect.Right := ARect.Left + tx;
|
---|
6194 |
|
---|
6195 | if ARect.Top >= Height then
|
---|
6196 | ARect.Top := ARect.Top mod Height
|
---|
6197 | else
|
---|
6198 | if ARect.Top < 0 then
|
---|
6199 | ARect.Top := Height - ((-ARect.Top) mod Height);
|
---|
6200 | ARect.Bottom := ARect.Top + ty;
|
---|
6201 |
|
---|
6202 | if (ARect.Left = 0) and (ARect.Top = 0) and
|
---|
6203 | (ARect.Right = Width) and
|
---|
6204 | (ARect.Bottom = Height) then
|
---|
6205 | begin
|
---|
6206 | result := Duplicate;
|
---|
6207 | exit;
|
---|
6208 | end;
|
---|
6209 |
|
---|
6210 | result := NewBitmap(tx, ty);
|
---|
6211 | heightleft := result.Height;
|
---|
6212 | curyin := ARect.Top;
|
---|
6213 | ydest := -ARect.Top;
|
---|
6214 | while heightleft > 0 do
|
---|
6215 | begin
|
---|
6216 | if curyin + heightleft > Height then
|
---|
6217 | copyheight := Height - curyin
|
---|
6218 | else
|
---|
6219 | copyheight := heightleft;
|
---|
6220 |
|
---|
6221 | widthleft := result.Width;
|
---|
6222 | curxin := ARect.Left;
|
---|
6223 | xdest := -ARect.Left;
|
---|
6224 | while widthleft > 0 do
|
---|
6225 | begin
|
---|
6226 | if curxin + widthleft > Width then
|
---|
6227 | copywidth := Width - curxin
|
---|
6228 | else
|
---|
6229 | copywidth := widthleft;
|
---|
6230 |
|
---|
6231 | result.PutImage(xdest, ydest, self, dmSet);
|
---|
6232 |
|
---|
6233 | curxin := 0;
|
---|
6234 | Dec(widthleft, copywidth);
|
---|
6235 | Inc(xdest, Width);
|
---|
6236 | end;
|
---|
6237 | curyin := 0;
|
---|
6238 | Dec(heightleft, copyheight);
|
---|
6239 | Inc(ydest, Height);
|
---|
6240 | end;
|
---|
6241 | end;
|
---|
6242 |
|
---|
6243 | function TBGRADefaultBitmap.GetPtrBitmap(Top, Bottom: Integer
|
---|
6244 | ): TBGRACustomBitmap;
|
---|
6245 | var temp: integer;
|
---|
6246 | ptrbmp: TBGRAPtrBitmap;
|
---|
6247 | begin
|
---|
6248 | if Top > Bottom then
|
---|
6249 | begin
|
---|
6250 | temp := Top;
|
---|
6251 | Top := Bottom;
|
---|
6252 | Bottom := Temp;
|
---|
6253 | end;
|
---|
6254 | if Top < 0 then Top := 0;
|
---|
6255 | if Bottom > Height then Bottom := Height;
|
---|
6256 | if Top >= Bottom then
|
---|
6257 | result := nil
|
---|
6258 | else
|
---|
6259 | begin
|
---|
6260 | if LineOrder = riloTopToBottom then
|
---|
6261 | ptrbmp := CreatePtrBitmap(Width,Bottom-Top,ScanLine[Top]) else
|
---|
6262 | ptrbmp := CreatePtrBitmap(Width,Bottom-Top,ScanLine[Bottom-1]);
|
---|
6263 | ptrbmp.LineOrder := LineOrder;
|
---|
6264 | result := ptrbmp;
|
---|
6265 | end;
|
---|
6266 | end;
|
---|
6267 |
|
---|
6268 | {-------------------------- Allocation routines -------------------------------}
|
---|
6269 |
|
---|
6270 | procedure TBGRADefaultBitmap.ReallocData;
|
---|
6271 | begin
|
---|
6272 | FreeBitmap;
|
---|
6273 | ReAllocMem(FData, NbPixels * sizeof(TBGRAPixel));
|
---|
6274 | if (NbPixels > 0) and (FData = nil) then
|
---|
6275 | raise EOutOfMemory.Create('TBGRADefaultBitmap: Not enough memory');
|
---|
6276 | InvalidateBitmap;
|
---|
6277 | FScanPtr := nil;
|
---|
6278 | end;
|
---|
6279 |
|
---|
6280 | procedure TBGRADefaultBitmap.FreeData;
|
---|
6281 | begin
|
---|
6282 | freemem(FData);
|
---|
6283 | FData := nil;
|
---|
6284 | end;
|
---|
6285 |
|
---|
6286 | function TBGRADefaultBitmap.CreatePtrBitmap(AWidth, AHeight: integer;
|
---|
6287 | AData: PBGRAPixel): TBGRAPtrBitmap;
|
---|
6288 | begin
|
---|
6289 | result := TBGRAPtrBitmap.Create(AWidth,AHeight,AData);
|
---|
6290 | end;
|
---|
6291 |
|
---|
6292 | procedure TBGRADefaultBitmap.FreeBitmap;
|
---|
6293 | begin
|
---|
6294 | FreeAndNil(FBitmap);
|
---|
6295 | end;
|
---|
6296 |
|
---|
6297 | function TBGRADefaultBitmap.GetNbPixels: integer;
|
---|
6298 | begin
|
---|
6299 | result := FNbPixels;
|
---|
6300 | end;
|
---|
6301 |
|
---|
6302 | function TBGRADefaultBitmap.GetWidth: integer;
|
---|
6303 | begin
|
---|
6304 | Result := FWidth;
|
---|
6305 | end;
|
---|
6306 |
|
---|
6307 | function TBGRADefaultBitmap.GetHeight: integer;
|
---|
6308 | begin
|
---|
6309 | Result:= FHeight;
|
---|
6310 | end;
|
---|
6311 |
|
---|
6312 | function TBGRADefaultBitmap.GetRefCount: integer;
|
---|
6313 | begin
|
---|
6314 | result := FRefCount;
|
---|
6315 | end;
|
---|
6316 |
|
---|
6317 | function TBGRADefaultBitmap.GetLineOrder: TRawImageLineOrder;
|
---|
6318 | begin
|
---|
6319 | result := FLineOrder;
|
---|
6320 | end;
|
---|
6321 |
|
---|
6322 | procedure TBGRADefaultBitmap.SetLineOrder(AValue: TRawImageLineOrder);
|
---|
6323 | begin
|
---|
6324 | FLineOrder := AValue;
|
---|
6325 | end;
|
---|
6326 |
|
---|
6327 | function TBGRADefaultBitmap.GetCanvasOpacity: byte;
|
---|
6328 | begin
|
---|
6329 | result:= FCanvasOpacity;
|
---|
6330 | end;
|
---|
6331 |
|
---|
6332 | function TBGRADefaultBitmap.GetFontHeight: integer;
|
---|
6333 | begin
|
---|
6334 | result := FFontHeight;
|
---|
6335 | end;
|
---|
6336 |
|
---|
6337 | { TBGRAPtrBitmap }
|
---|
6338 |
|
---|
6339 | function TBGRAPtrBitmap.GetLineOrder: TRawImageLineOrder;
|
---|
6340 | begin
|
---|
6341 | result := inherited GetLineOrder;
|
---|
6342 | end;
|
---|
6343 |
|
---|
6344 | procedure TBGRAPtrBitmap.SetLineOrder(AValue: TRawImageLineOrder);
|
---|
6345 | begin
|
---|
6346 | inherited SetLineOrder(AValue);
|
---|
6347 | end;
|
---|
6348 |
|
---|
6349 | procedure TBGRAPtrBitmap.ReallocData;
|
---|
6350 | begin
|
---|
6351 | //nothing
|
---|
6352 | end;
|
---|
6353 |
|
---|
6354 | procedure TBGRAPtrBitmap.FreeData;
|
---|
6355 | begin
|
---|
6356 | FData := nil;
|
---|
6357 | end;
|
---|
6358 |
|
---|
6359 | procedure TBGRAPtrBitmap.CannotResize;
|
---|
6360 | begin
|
---|
6361 | raise exception.Create('A pointer bitmap cannot be resized');
|
---|
6362 | end;
|
---|
6363 |
|
---|
6364 | procedure TBGRAPtrBitmap.NotImplemented;
|
---|
6365 | begin
|
---|
6366 | raise exception.Create('Not implemented');
|
---|
6367 | end;
|
---|
6368 |
|
---|
6369 | procedure TBGRAPtrBitmap.RebuildBitmap;
|
---|
6370 | begin
|
---|
6371 | NotImplemented;
|
---|
6372 | end;
|
---|
6373 |
|
---|
6374 | function TBGRAPtrBitmap.CreateDefaultFontRenderer: TBGRACustomFontRenderer;
|
---|
6375 | begin
|
---|
6376 | result := nil;
|
---|
6377 | NotImplemented;
|
---|
6378 | end;
|
---|
6379 |
|
---|
6380 | function TBGRAPtrBitmap.LoadFromRawImage(ARawImage: TRawImage;
|
---|
6381 | DefaultOpacity: byte; AlwaysReplaceAlpha: boolean;
|
---|
6382 | RaiseErrorOnInvalidPixelFormat: boolean): boolean;
|
---|
6383 | begin
|
---|
6384 | result := false;
|
---|
6385 | NotImplemented;
|
---|
6386 | end;
|
---|
6387 |
|
---|
6388 | constructor TBGRAPtrBitmap.Create(AWidth, AHeight: integer; AData: Pointer);
|
---|
6389 | begin
|
---|
6390 | inherited Create(AWidth, AHeight);
|
---|
6391 | SetDataPtr(AData);
|
---|
6392 | end;
|
---|
6393 |
|
---|
6394 | function TBGRAPtrBitmap.Duplicate(DuplicateProperties: Boolean = False; DuplicateXorMask: Boolean = False): TBGRACustomBitmap;
|
---|
6395 | begin
|
---|
6396 | Result := NewBitmap(Width, Height);
|
---|
6397 | if DuplicateProperties then CopyPropertiesTo(TBGRADefaultBitmap(Result));
|
---|
6398 | if DuplicateXorMask and Assigned(XorMask) then
|
---|
6399 | TBGRADefaultBitmap(Result).FXorMask := FXorMask.Duplicate(True);
|
---|
6400 | end;
|
---|
6401 |
|
---|
6402 | procedure TBGRAPtrBitmap.SetDataPtr(AData: Pointer);
|
---|
6403 | begin
|
---|
6404 | FData := AData;
|
---|
6405 | end;
|
---|
6406 |
|
---|
6407 | procedure TBGRAPtrBitmap.DataDrawTransparent(ACanvas: TCanvas; Rect: TRect;
|
---|
6408 | AData: Pointer; ALineOrder: TRawImageLineOrder; AWidth, AHeight: integer);
|
---|
6409 | begin
|
---|
6410 | NotImplemented;
|
---|
6411 | end;
|
---|
6412 |
|
---|
6413 | procedure TBGRAPtrBitmap.DataDrawOpaque(ACanvas: TCanvas; Rect: TRect;
|
---|
6414 | AData: Pointer; ALineOrder: TRawImageLineOrder; AWidth, AHeight: integer);
|
---|
6415 | begin
|
---|
6416 | NotImplemented;
|
---|
6417 | end;
|
---|
6418 |
|
---|
6419 | procedure TBGRAPtrBitmap.GetImageFromCanvas(CanvasSource: TCanvas; x, y: integer
|
---|
6420 | );
|
---|
6421 | begin
|
---|
6422 | NotImplemented;
|
---|
6423 | end;
|
---|
6424 |
|
---|
6425 | procedure TBGRAPtrBitmap.Assign(Source: TPersistent);
|
---|
6426 | begin
|
---|
6427 | CannotResize;
|
---|
6428 | end;
|
---|
6429 |
|
---|
6430 | procedure TBGRAPtrBitmap.TakeScreenshot(ARect: TRect);
|
---|
6431 | begin
|
---|
6432 | CannotResize;
|
---|
6433 | end;
|
---|
6434 |
|
---|
6435 | procedure TBGRAPtrBitmap.TakeScreenshotOfPrimaryMonitor;
|
---|
6436 | begin
|
---|
6437 | CannotResize;
|
---|
6438 | end;
|
---|
6439 |
|
---|
6440 | procedure TBGRAPtrBitmap.LoadFromDevice(DC: HDC);
|
---|
6441 | begin
|
---|
6442 | NotImplemented;
|
---|
6443 | end;
|
---|
6444 |
|
---|
6445 | procedure TBGRAPtrBitmap.LoadFromDevice(DC: HDC; ARect: TRect);
|
---|
6446 | begin
|
---|
6447 | NotImplemented;
|
---|
6448 | end;
|
---|
6449 |
|
---|
6450 | procedure BGRAGradientFill(bmp: TBGRACustomBitmap; x, y, x2, y2: integer;
|
---|
6451 | c1, c2: TBGRAPixel; gtype: TGradientType; o1, o2: TPointF; mode: TDrawMode;
|
---|
6452 | gammaColorCorrection: boolean = True; Sinus: Boolean=False);
|
---|
6453 | begin
|
---|
6454 | bmp.GradientFill(x,y,x2,y2,c1,c2,gtype,o1,o2,mode,gammaColorCorrection,sinus);
|
---|
6455 | end;
|
---|
6456 |
|
---|
6457 | initialization
|
---|
6458 |
|
---|
6459 | with DefaultTextStyle do
|
---|
6460 | begin
|
---|
6461 | Alignment := taLeftJustify;
|
---|
6462 | Layout := tlTop;
|
---|
6463 | WordBreak := True;
|
---|
6464 | SingleLine := True;
|
---|
6465 | Clipping := True;
|
---|
6466 | ShowPrefix := False;
|
---|
6467 | Opaque := False;
|
---|
6468 | end;
|
---|
6469 |
|
---|
6470 | end.
|
---|
6471 |
|
---|