source: trunk/Packages/bgrabitmap/bgracustombitmap.inc

Last change on this file was 2, checked in by chronos, 5 years ago
File size: 122.9 KB
Line 
1{=== TBGRACustomBitmap and IBGRAScanner ===}
2{$IFDEF INCLUDE_SCANNER_INTERFACE}
3{$UNDEF INCLUDE_SCANNER_INTERFACE}
4type
5 TBGRACustomBitmap = class;
6
7{==== IBGRAScanner ====}
8 {* Interface for a scanner. A scanner is like an image, but its content
9 has no limit and it can be calculated on the fly. It is like a
10 infinite readonly image.
11 *
12 * Note: it must not implement reference counting even if it is an interface
13 *
14 * ''TBGRACustomBitmap'' implements this interface and the content is repeated
15 horizontally and vertically. There are also various classes
16 in ''BGRAGradientScanner'' unit that generate gradients on the fly and
17 in ''BGRATransform'' unit that provide geometrical transformations of images }
18 IBGRAScanner = interface
19 {** Move to the position (''X'',''Y'') for the next call to ''ScanNextPixel'' }
20 procedure ScanMoveTo(X,Y: Integer);
21 {** Scan the pixel at the current location and increments ''X'' }
22 function ScanNextPixel: TBGRAPixel;
23 function ScanNextExpandedPixel: TExpandedPixel;
24 {** Scan at any location using floating point coordinates }
25 function ScanAt(X,Y: Single): TBGRAPixel;
26 function ScanAtExpanded(X,Y: Single): TExpandedPixel;
27 {** Scan at any location using integer coordinates }
28 function ScanAtInteger(X,Y: integer): TBGRAPixel;
29 function ScanAtIntegerExpanded(X,Y: integer): TExpandedPixel;
30 {** Copy a row of pixels from ''X'' to ''X''+''count''-1 to a specified destination
31 ''pdest''. ''mode'' indicates how to combine with existing data }
32 procedure ScanPutPixels(pdest: PBGRAPixel; count: integer; mode: TDrawMode);
33 {** Returns True if the function ''ScanPutPixels'' is available. Otherwise
34 you need to call ''ScanNextPixel'' and combine pixels for example
35 with ''SetPixel'' }
36 function IsScanPutPixelsDefined: boolean;
37 {** Returns the corresponding OpenGL texture. The value is ''nil'' if no texture is associated. **}
38 function GetTextureGL: IUnknown;
39 function GetImageBoundsWithin(const ARect: TRect; Channel: TChannel = cAlpha; ANothingValue: Byte = 0): TRect; overload;
40 function GetImageBoundsWithin(const ARect: TRect; Channels: TChannels; ANothingValue: Byte = 0): TRect; overload;
41 function ProvidesScanline(ARect: TRect): boolean;
42 function GetScanlineAt(X,Y: integer): PBGRAPixel;
43 end;
44
45 {** A type of function of a scanner that returns the content at floating point coordinates }
46 TScanAtFunction = function (X,Y: Single): TBGRAPixel of object;
47 {** A type of function of a scanner that returns the content at integer coordinates }
48 TScanAtIntegerFunction = function (X,Y: Integer): TBGRAPixel of object;
49 {** A type of function of a scanner that returns the next pixel }
50 TScanNextPixelFunction = function: TBGRAPixel of object;
51
52 { TBGRACustomScanner }
53 {* Base class for implementing ''IBGRAScanner'' interface }
54 TBGRACustomScanner = class(IBGRAScanner)
55 private
56 FCurX,FCurY: integer;
57 public
58 function ScanAtInteger(X,Y: integer): TBGRAPixel; virtual;
59 function ScanAtIntegerExpanded(X,Y: integer): TExpandedPixel; virtual;
60 procedure ScanMoveTo(X,Y: Integer); virtual;
61 function ScanNextPixel: TBGRAPixel; virtual;
62 function ScanNextExpandedPixel: TExpandedPixel; virtual;
63 function ScanAt(X,Y: Single): TBGRAPixel; virtual; abstract;
64 function ScanAtExpanded(X,Y: Single): TExpandedPixel; virtual;
65 procedure ScanPutPixels(pdest: PBGRAPixel; count: integer; mode: TDrawMode); virtual;
66 function IsScanPutPixelsDefined: boolean; virtual;
67 function GetTextureGL: IUnknown; virtual;
68 function GetImageBoundsWithin(const ARect: TRect; Channel: TChannel = cAlpha; ANothingValue: Byte = 0): TRect; overload; virtual;
69 function GetImageBoundsWithin(const ARect: TRect; Channels: TChannels; ANothingValue: Byte = 0): TRect; overload; virtual;
70 function ProvidesScanline({%H-}ARect: TRect): boolean; virtual;
71 function GetScanlineAt({%H-}X,{%H-}Y: integer): PBGRAPixel; virtual;
72 protected
73 function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} IID: TGUID; out Obj): HResult; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND};
74 function _AddRef: Integer; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND};
75 function _Release: Integer; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND};
76 end;
77{$ENDIF}
78
79{$IFDEF INCLUDE_INTERFACE}
80{$UNDEF INCLUDE_INTERFACE}
81type
82{==== TBGRACustomBitmap ====}
83
84 { TBGRACustomBitmap }
85 {* This is the base class for ''TBGRABitmap''. It is the direct parent of
86 ''TBGRADefaultBitmap'' class, which is the parent of the diverse
87 implementations. A bitmap can be used as a scanner using the interface
88 ''IBGRAScanner'' }
89 TBGRACustomBitmap = class(TFPCustomImage,IBGRAScanner)
90 private
91 function GetFontAntialias: Boolean;
92 procedure SetFontAntialias(const AValue: Boolean);
93 protected
94 FXorMask: TBGRACustomBitmap;
95
96 { accessors to properies }
97 function GetArrowEndRepeat: integer; virtual; abstract;
98 function GetArrowStartRepeat: integer; virtual; abstract;
99 procedure SetArrowEndRepeat(AValue: integer); virtual; abstract;
100 procedure SetArrowStartRepeat(AValue: integer); virtual; abstract;
101 function GetArrowEndOffset: single; virtual; abstract;
102 function GetArrowStartOffset: single; virtual; abstract;
103 procedure SetArrowEndOffset(AValue: single); virtual; abstract;
104 procedure SetArrowStartOffset(AValue: single); virtual; abstract;
105 function GetArrowEndSize: TPointF; virtual; abstract;
106 function GetArrowStartSize: TPointF; virtual; abstract;
107 procedure SetArrowEndSize(AValue: TPointF); virtual; abstract;
108 procedure SetArrowStartSize(AValue: TPointF); virtual; abstract;
109 function GetLineCap: TPenEndCap; virtual; abstract;
110 procedure SetLineCap(AValue: TPenEndCap); virtual; abstract;
111 function GetFontRenderer: TBGRACustomFontRenderer; virtual; abstract;
112 procedure SetFontRenderer(AValue: TBGRACustomFontRenderer); virtual; abstract;
113 function GetHeight: integer; virtual; abstract;
114 function GetWidth: integer; virtual; abstract;
115 function GetDataPtr: PBGRAPixel; virtual; abstract;
116 function GetNbPixels: integer; virtual; abstract;
117 function CheckEmpty: boolean; virtual; abstract;
118 function CheckIsZero: boolean; virtual; abstract;
119 function GetHasTransparentPixels: boolean; virtual; abstract;
120 function GetHasSemiTransparentPixels: boolean; virtual; abstract;
121 function GetAverageColor: TColor; virtual; abstract;
122 function GetAveragePixel: TBGRAPixel; virtual; abstract;
123 procedure SetCanvasOpacity(AValue: byte); virtual; abstract;
124 function GetScanLine(y: integer): PBGRAPixel; virtual; abstract;
125 function GetRefCount: integer; virtual; abstract;
126 function GetBitmap: TBitmap; virtual; abstract;
127 function GetLineOrder: TRawImageLineOrder; virtual; abstract;
128 function GetCanvasFP: TFPImageCanvas; virtual; abstract;
129 function GetCanvasDrawModeFP: TDrawMode; virtual; abstract;
130 procedure SetCanvasDrawModeFP(const AValue: TDrawMode); virtual; abstract;
131 function GetCanvas: TCanvas; virtual; abstract;
132 function GetCanvasOpacity: byte; virtual; abstract;
133 function GetCanvasAlphaCorrection: boolean; virtual; abstract;
134 procedure SetCanvasAlphaCorrection(const AValue: boolean); virtual; abstract;
135 function GetFontHeight: integer; virtual; abstract;
136 procedure SetFontHeight(AHeight: integer); virtual; abstract;
137 function GetFontFullHeight: integer; virtual; abstract;
138 procedure SetFontFullHeight(AHeight: integer); virtual; abstract;
139 function GetFontVerticalAnchorOffset: single; virtual; abstract;
140 function GetPenJoinStyle: TPenJoinStyle; virtual; abstract;
141 procedure SetPenJoinStyle(const AValue: TPenJoinStyle); virtual; abstract;
142 function GetPenMiterLimit: single; virtual; abstract;
143 procedure SetPenMiterLimit(const AValue: single); virtual; abstract;
144 function GetPenStyle: TPenStyle; virtual; abstract;
145 procedure SetPenStyle(const AValue: TPenStyle); virtual; abstract;
146 function GetCustomPenStyle: TBGRAPenStyle; virtual; abstract;
147 procedure SetCustomPenStyle(const AValue: TBGRAPenStyle); virtual; abstract;
148 function GetPenStroker: TBGRACustomPenStroker; virtual; abstract;
149 function GetClipRect: TRect; virtual; abstract;
150 procedure SetClipRect(const AValue: TRect); virtual; abstract;
151 function GetFontPixelMetric: TFontPixelMetric; virtual; abstract;
152 procedure ClearTransparentPixels; virtual; abstract;
153
154 procedure InternalArc(cx,cy,rx,ry: single; const StartPoint,EndPoint: TPointF; ABorderColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel; AOptions: TArcOptions; ADrawChord: boolean = false; ATexture: IBGRAScanner = nil); overload;
155 procedure InternalArc(cx,cy,rx,ry: single; StartAngleRad,EndAngleRad: Single; ABorderColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel; AOptions: TArcOptions; ADrawChord: boolean = false; ATexture: IBGRAScanner = nil); overload; virtual; abstract;
156 procedure InternalArcInRect(r: TRect; StartAngleRad,EndAngleRad: Single; ABorderColor : TBGRAPixel; w: single; AFillColor: TBGRAPixel; AOptions: TArcOptions; ADrawChord: boolean = false; ATexture: IBGRAScanner = nil);
157 procedure InternalFillArcInRect(r: TRect; StartAngleRad,EndAngleRad: Single; AFillColor: TBGRAPixel; AOptions: TArcOptions; ATexture: IBGRAScanner = nil);
158
159 function GetTextureGL: IUnknown; virtual;
160 function GetFontRightToLeftFor(AText: string): boolean;
161
162 public
163 {** User defined caption. It does not appear on the image }
164 Caption: string;
165
166 {** Method to use when filling polygons (winding or alternate).
167 See [[BGRABitmap Types imported from Graphics|BGRAGraphics]] }
168 FillMode: TFillMode;
169
170 {** Specifies if linear antialiasing must be used when drawing
171 antialiased shapes }
172 LinearAntialiasing: boolean;
173
174 {** Resample filter is used when resizing the bitmap. See [[BGRABitmap Miscellaneous types#Images and resampling|resampling types]] }
175 ResampleFilter : TResampleFilter;
176
177 {** Scan interpolation filter is used when the bitmap is used
178 as a scanner (interface ''IBGRAScanner'') }
179 ScanInterpolationFilter: TResampleFilter;
180 {** Offset to apply when the image is scanned using ''IBGRAScanner'' interface }
181 ScanOffset: TPoint;
182
183 {** Cursor position for mouse pointer }
184 HotSpot: TPoint;
185
186 { ** Free reference to xor mask }
187 procedure DiscardXorMask; virtual; abstract;
188
189 { ** Allocate xor mask }
190 procedure NeedXorMask; virtual; abstract;
191
192 {** Xor mask to be applied when image is drawn }
193 property XorMask: TBGRACustomBitmap read FXorMask;
194
195 {** Width of the image in pixels }
196 property Width: integer Read GetWidth;
197 {** Height of the image in pixels }
198 property Height: integer Read GetHeight;
199
200 {** Clipping rectangle for all drawing functions }
201 property ClipRect: TRect read GetClipRect write SetClipRect;
202
203 {** Total number of pixels. It is always true that ''NbPixels'' = ''Width'' * ''Height'' }
204 property NbPixels: integer Read GetNbPixels;
205
206 {** Returns the address of the left-most pixel of any line.
207 The parameter y ranges from 0 to Height-1 }
208 property ScanLine[y: integer]: PBGRAPixel Read GetScanLine;
209
210 {** Indicates the order in which lines are stored in memory.
211 If it is equal to ''riloTopToBottom'', the first line is the top line.
212 If it is equal to ''riloBottomToTop'', the first line is the bottom line.
213 See [[BGRABitmap Miscellaneous types|miscellaneous types]] }
214 property LineOrder: TRawImageLineOrder Read GetLineOrder;
215
216 {** Provides a pointer to the first pixel in memory.
217 Depending on the ''LineOrder'' property, this can be the top-left pixel or the bottom-left pixel.
218 There is no padding between scanlines, so the start of the next line is at the address ''Data'' + ''Width''.
219 See [[BGRABitmap tutorial 4]] }
220 property Data: PBGRAPixel Read GetDataPtr;
221
222 {** Number of references to this image. It is increased by the function
223 ''NewReference'' and decreased by the function ''FreeReference'' }
224 property RefCount: integer Read GetRefCount;
225
226 {** Returns True if the bitmap only contains transparent pixels or has a size of zero }
227 property Empty: boolean Read CheckEmpty;
228 property IsZero: boolean Read CheckIsZero;
229
230 {** Returns True if there are transparent or semitransparent pixels,
231 and so if the image would be stored with an alpha channel }
232 property HasTransparentPixels: boolean Read GetHasTransparentPixels;
233 property HasSemiTransparentPixels: boolean Read GetHasSemiTransparentPixels;
234
235 {** Average color of the image }
236 property AverageColor: TColor Read GetAverageColor;
237 {** Average color (including alpha) of the image }
238 property AveragePixel: TBGRAPixel Read GetAveragePixel;
239
240 {** Canvas compatible with FreePascal }
241 property CanvasFP: TFPImageCanvas read GetCanvasFP;
242 {** Draw mode to used when image is access using FreePascal functions
243 and ''Colors'' property }
244 property CanvasDrawModeFP: TDrawMode read GetCanvasDrawModeFP write SetCanvasDrawModeFP;
245
246 {** Bitmap in a format compatible with the current GUI.
247 Don't forget to call ''InvalidateBitmap'' before using it
248 if you changed something with direct pixel access (''Scanline''
249 and ''Data'') }
250 property Bitmap: TBitmap Read GetBitmap;
251 {** Canvas provided by the GUI }
252 property Canvas: TCanvas Read GetCanvas;
253 {** Opacity to apply to changes made using GUI functions, provided
254 ''CanvasAlphaCorrection'' is set to ''True'' }
255 property CanvasOpacity: byte Read GetCanvasOpacity Write SetCanvasOpacity;
256 {** Specifies if the alpha values must be corrected after GUI access
257 to the bitmap }
258 property CanvasAlphaCorrection: boolean Read GetCanvasAlphaCorrection Write SetCanvasAlphaCorrection;
259
260 public {----------- pen style ----------------}
261 {** How to join segments. See [[BGRABitmap Types imported from Graphics|BGRAGraphics]] }
262 property JoinStyle: TPenJoinStyle read GetPenJoinStyle Write SetPenJoinStyle;
263 {** Limit for the extension of the segments when joining them
264 with ''pjsMiter'' join style, expressed in multiples of the width
265 of the pen }
266 property JoinMiterLimit: single read GetPenMiterLimit Write SetPenMiterLimit;
267 {** Pen style. See [[BGRABitmap Types imported from Graphics|BGRAGraphics]] }
268 property PenStyle: TPenStyle read GetPenStyle Write SetPenStyle;
269 {** Custom pen style. See [[BGRABitmap Geometry types|geometric types]] }
270 property CustomPenStyle: TBGRAPenStyle read GetCustomPenStyle write SetCustomPenStyle;
271 {** How to draw the ends of a line }
272 property LineCap: TPenEndCap read GetLineCap write SetLineCap;
273 {** You can use this class to generate strokes polygonal representations }
274 property Pen: TBGRACustomPenStroker read GetPenStroker;
275
276 {** Size of arrows at the start of the line }
277 property ArrowStartSize: TPointF read GetArrowStartSize write SetArrowStartSize;
278 {** Size of arrows at the end of the line }
279 property ArrowEndSize: TPointF read GetArrowEndSize write SetArrowEndSize;
280 {** Offset of the arrow from the start of the line }
281 property ArrowStartOffset: single read GetArrowStartOffset write SetArrowStartOffset;
282 {** Offset of the arrow from the end of the line }
283 property ArrowEndOffset: single read GetArrowEndOffset write SetArrowEndOffset;
284 {** Number of times to repeat the starting arrow }
285 property ArrowStartRepeat: integer read GetArrowStartRepeat write SetArrowStartRepeat;
286 {** Number of times to repeat the ending arrow }
287 property ArrowEndRepeat: integer read GetArrowEndRepeat write SetArrowEndRepeat;
288
289 public {-------------------font style------------------------}
290 {** Specifies the font to use. Unless the font renderer accept otherwise,
291 the name is in human readable form, like 'Arial', 'Times New Roman', ... }
292 FontName: string;
293 {** Specifies the set of styles to be applied to the font.
294 These can be ''fsBold'', ''fsItalic'', ''fsStrikeOut'', ''fsUnderline''.
295 So the value [''fsBold'',''fsItalic''] means that the font must be bold and italic.
296 See [[BGRABitmap Miscellaneous types|miscellaneous types]] }
297 FontStyle: TFontStyles;
298
299 {** Specifies the quality of rendering. Default value is ''fqSystem''.
300 See [[BGRABitmap Miscellaneous types|miscellaneous types]] }
301 FontQuality : TBGRAFontQuality;
302
303 {** Specifies the rotation of the text, for functions that support text rotation.
304 It is expressed in tenth of degrees, positive values going counter-clockwise. }
305 FontOrientation: integer;
306
307 {** Specifies how the font is vertically aligned relative to the start coordinate.
308 See [[BGRABitmap Miscellaneous types|miscellaneous types]]}
309 FontVerticalAnchor: TFontVerticalAnchor;
310
311 {** Specifies the base direction of the text (cf Unicode). By default, it is
312 automatically determined by the first strongly oriented character.
313 You can specify another base direction here however it is not taken
314 into account by the LCL on Linux. }
315 FontBidiMode: TFontBidiMode;
316
317 {** Specifies the height of the font in pixels without taking into account
318 additional line spacing. A negative value means that it is the
319 full height instead (see below) }
320 property FontHeight: integer Read GetFontHeight Write SetFontHeight;
321
322 {** Specifies the height of the font in pixels, taking into account the
323 additional line spacing defined for the font }
324 property FontFullHeight: integer read GetFontFullHeight write SetFontFullHeight;
325
326 {** Simplified property to specify the quality (see ''FontQuality'') }
327 property FontAntialias: Boolean read GetFontAntialias write SetFontAntialias;
328
329 property FontVerticalAnchorOffset: single read GetFontVerticalAnchorOffset;
330
331 {** Returns measurement for the current font in pixels }
332 property FontPixelMetric: TFontPixelMetric read GetFontPixelMetric;
333
334 {** Specifies the font renderer. When working with the LCL,
335 by default it is an instance of ''TLCLFontRenderer'' of
336 unit ''BGRAText''. Other renderers are provided in ''BGRATextFX''
337 unit and ''BGRAVectorize'' unit. Additionally, ''BGRAFreeType''
338 provides a renderer independent from the LCL.
339 *
340 * Once you assign a renderer, it will automatically be freed when
341 the bitmap is freed. The renderers may provide additional styling
342 for the font, not accessible with the properties in this class
343 *
344 * See [[BGRABitmap tutorial Font rendering|font rendering]]}
345 property FontRenderer: TBGRACustomFontRenderer read GetFontRenderer write SetFontRenderer;
346
347 public
348 constructor Create; overload; virtual; abstract;
349 constructor Create(AFPImage: TFPCustomImage); overload; virtual; abstract;
350 constructor Create(ABitmap: TBitmap; AUseTransparent: boolean = true); overload; virtual; abstract;
351 constructor Create(AWidth, AHeight: integer; Color: TColor); overload; virtual; abstract;
352 constructor Create(AWidth, AHeight: integer; Color: TBGRAPixel); overload; virtual; abstract;
353 constructor Create(AFilename: string); overload; virtual; abstract;
354 constructor Create(AFilename: string; AIsUtf8Filename: boolean); overload; virtual; abstract;
355 constructor Create(AFilename: string; AIsUtf8Filename: boolean; AOptions: TBGRALoadingOptions); overload; virtual; abstract;
356 constructor Create(AStream: TStream); overload; virtual; abstract;
357
358 function NewBitmap(AWidth, AHeight: integer): TBGRACustomBitmap; overload; virtual; abstract;
359 function NewBitmap(AWidth, AHeight: integer; Color: TBGRAPixel): TBGRACustomBitmap; overload; virtual; abstract;
360 function NewBitmap(Filename: string): TBGRACustomBitmap; overload; virtual; abstract;
361 function NewBitmap(Filename: string; AIsUtf8: boolean): TBGRACustomBitmap; overload; virtual; abstract;
362 function NewBitmap(Filename: string; AIsUtf8: boolean; AOptions: TBGRALoadingOptions): TBGRACustomBitmap; overload; virtual; abstract;
363 function NewBitmap(AFPImage: TFPCustomImage): TBGRACustomBitmap; overload; virtual; abstract;
364
365 //there are UTF8 functions that are different from standard function as those
366 //depend on TFPCustomImage that does not clearly handle UTF8
367 {==== Load and save files ====}
368 {** Load image from a file. ''filename'' is an ANSI string }
369 procedure LoadFromFile(const filename: string); overload; virtual;
370 procedure LoadFromFile(const filename: string; AOptions: TBGRALoadingOptions); overload; virtual;
371 {** Load image from a file with the specified image reader. ''filename'' is an ANSI string }
372 procedure LoadFromFile(const filename:String; Handler:TFPCustomImageReader); overload; virtual;
373 procedure LoadFromFile(const filename:String; Handler:TFPCustomImageReader; AOptions: TBGRALoadingOptions); overload; virtual;
374 {** Load image from a file. ''filename'' is an UTF8 string }
375 procedure LoadFromFileUTF8(const filenameUTF8: string; AOptions: TBGRALoadingOptions = []); overload; virtual;
376 {** Load image from a file with the specified image reader. ''filename'' is an UTF8 string }
377 procedure LoadFromFileUTF8(const filenameUTF8: string; AHandler: TFPCustomImageReader; AOptions: TBGRALoadingOptions = []); overload; virtual;
378 {** Load image from a stream. Format is detected automatically }
379 procedure LoadFromStream(Str: TStream);overload; virtual;
380 procedure LoadFromStream(Str: TStream; AOptions: TBGRALoadingOptions);overload; virtual;
381 {** Load image from a stream. The specified image reader is used }
382 procedure LoadFromStream(Str: TStream; Handler: TFPCustomImageReader);overload; virtual;
383 procedure LoadFromStream(Str: TStream; Handler: TFPCustomImageReader; AOptions: TBGRALoadingOptions);overload; virtual;
384 {** Load image from an embedded Lazarus resource. Format is detected automatically }
385 procedure LoadFromResource(AFilename: string); overload; virtual;
386 procedure LoadFromResource(AFilename: string; AOptions: TBGRALoadingOptions); overload; virtual; abstract;
387 {** Load image from an embedded Lazarus resource. The specified image reader is used }
388 procedure LoadFromResource(AFilename: string; Handler: TFPCustomImageReader); overload; virtual;
389 procedure LoadFromResource(AFilename: string; Handler: TFPCustomImageReader; AOptions: TBGRALoadingOptions); overload; virtual;
390
391 {** Save image to a file. The format is guessed from the file extension. ''filename'' is an ANSI string }
392 procedure SaveToFile(const filename: string);overload; virtual;
393 {** Save image to a file with the specified image writer. ''filename'' is an ANSI string }
394 procedure SaveToFile(const filename: string; Handler:TFPCustomImageWriter);overload; virtual;
395 {** Save image to a file. The format is guessed from the file extension. ''filename'' is an ANSI string }
396 procedure SaveToFileUTF8(const filenameUTF8: string);overload; virtual;
397 {** Save image to a file with the specified image writer. ''filename'' is an UTF8 string }
398 procedure SaveToFileUTF8(const filenameUTF8: string; Handler:TFPCustomImageWriter);overload; virtual;
399
400 {** Save image to a stream with the specified image writer }{inherited
401 procedure SaveToStream (Str:TStream; Handler:TFPCustomImageWriter);
402 }{** Save image to a stream in the specified image format }
403 procedure SaveToStreamAs(Str: TStream; AFormat: TBGRAImageFormat); virtual;
404 {** Save image to a stream in PNG format }
405 procedure SaveToStreamAsPng(Str: TStream); virtual;
406
407 procedure Serialize(AStream: TStream); virtual; abstract;
408 procedure Deserialize(AStream: TStream); virtual; abstract;
409
410 {** Gets the content of the specified device context }
411 procedure LoadFromDevice(DC: HDC); overload; virtual; abstract;
412 {** Gets the content from the specified rectangular area of a device context }
413 procedure LoadFromDevice(DC: HDC; ARect: TRect); overload; virtual; abstract;
414 {** Fills the content with a screenshot of the primary monitor }
415 procedure TakeScreenshotOfPrimaryMonitor; virtual; abstract;
416 {** Fills the content with a screenshot of the specified rectangular area of the desktop
417 (it can be from any screen) }
418 procedure TakeScreenshot(ARect: TRect); virtual; abstract;
419 {** For more methods, see derived class [[TBGRABitmap class|TBGRABitmap]] }
420
421 {Pixel functions}
422 procedure SetPixel(x, y: int32or64; c: TColor); overload; virtual; abstract;
423 procedure XorPixel(x, y: int32or64; c: TBGRAPixel); overload; virtual; abstract;
424 procedure SetPixel(x, y: int32or64; c: TBGRAPixel); overload; virtual; abstract;
425 procedure DrawPixel(x, y: int32or64; c: TBGRAPixel); overload; virtual; abstract;
426 procedure DrawPixel(x, y: int32or64; c: TBGRAPixel; ADrawMode: TDrawMode); overload;
427 procedure DrawPixel(x, y: int32or64; ec: TExpandedPixel); overload; virtual; abstract;
428 procedure FastBlendPixel(x, y: int32or64; c: TBGRAPixel); virtual; abstract;
429 procedure ErasePixel(x, y: int32or64; alpha: byte); virtual; abstract;
430 procedure AlphaPixel(x, y: int32or64; alpha: byte); virtual; abstract;
431 function GetPixel(x, y: int32or64): TBGRAPixel; overload; virtual; abstract;
432 function GetPixel256(x, y, fracX256,fracY256: int32or64; AResampleFilter: TResampleFilter = rfLinear; smoothBorder: boolean = true): TBGRAPixel; virtual; abstract;
433 function GetPixel(x, y: single; AResampleFilter: TResampleFilter = rfLinear; smoothBorder: boolean = true): TBGRAPixel; overload; virtual; abstract;
434 function GetPixelCycle(x, y: int32or64): TBGRAPixel;overload; virtual;
435 function GetPixelCycle(x, y: single; AResampleFilter: TResampleFilter = rfLinear): TBGRAPixel; overload; virtual; abstract;
436 function GetPixelCycle(x, y: single; AResampleFilter: TResampleFilter; repeatX: boolean; repeatY: boolean): TBGRAPixel; overload; virtual; abstract;
437 function GetPixelCycle256(x, y, fracX256,fracY256: int32or64; AResampleFilter: TResampleFilter = rfLinear): TBGRAPixel; overload; virtual; abstract;
438 function GetPixelCycle256(x, y, fracX256,fracY256: int32or64; AResampleFilter: TResampleFilter; repeatX: boolean; repeatY: boolean): TBGRAPixel; overload; virtual; abstract;
439
440 {Line primitives}
441 procedure SetHorizLine(x, y, x2: int32or64; c: TBGRAPixel); virtual; abstract;
442 procedure XorHorizLine(x, y, x2: int32or64; c: TBGRAPixel); virtual; abstract;
443 procedure DrawHorizLine(x, y, x2: int32or64; c: TBGRAPixel); overload; virtual; abstract;
444 procedure DrawHorizLine(x, y, x2: int32or64; ec: TExpandedPixel); overload; virtual; abstract;
445 procedure DrawHorizLine(x, y, x2: int32or64; texture: IBGRAScanner); overload;
446 procedure FastBlendHorizLine(x, y, x2: int32or64; c: TBGRAPixel); virtual; abstract;
447 procedure HorizLine(x,y,x2: Int32or64; c: TBGRAPixel; ADrawMode: TDrawMode); overload;
448 procedure HorizLine(x,y,x2: Int32or64; texture: IBGRAScanner; ADrawMode: TDrawMode); overload; virtual; abstract;
449 procedure DrawHorizLineDiff(x, y, x2: int32or64; c, compare: TBGRAPixel; maxDiff: byte); virtual; abstract;
450 procedure AlphaHorizLine(x, y, x2: int32or64; alpha: byte); virtual; abstract;
451
452 procedure SetVertLine(x, y, y2: int32or64; c: TBGRAPixel); virtual; abstract;
453 procedure XorVertLine(x, y, y2: int32or64; c: TBGRAPixel); virtual; abstract;
454 procedure DrawVertLine(x, y, y2: int32or64; c: TBGRAPixel); virtual; abstract;
455 procedure AlphaVertLine(x, y, y2: int32or64; alpha: byte); virtual; abstract;
456 procedure FastBlendVertLine(x, y, y2: int32or64; c: TBGRAPixel); virtual; abstract;
457 procedure VertLine(x,y,y2: Int32or64; c: TBGRAPixel; ADrawMode: TDrawMode);
458
459 {Shapes}
460 procedure DrawPath(APath: IBGRAPath; AStrokeColor: TBGRAPixel; AWidth: single; AFillColor: TBGRAPixel); overload; virtual; abstract;
461 procedure DrawPath(APath: IBGRAPath; AStrokeTexture: IBGRAScanner; AWidth: single; AFillColor: TBGRAPixel); overload; virtual; abstract;
462 procedure DrawPath(APath: IBGRAPath; AStrokeColor: TBGRAPixel; AWidth: single; AFillTexture: IBGRAScanner); overload; virtual; abstract;
463 procedure DrawPath(APath: IBGRAPath; AStrokeTexture: IBGRAScanner; AWidth: single; AFillTexture: IBGRAScanner); overload; virtual; abstract;
464 procedure DrawPath(APath: IBGRAPath; AStrokeColor: TBGRAPixel; AWidth: single); overload; virtual; abstract;
465 procedure DrawPath(APath: IBGRAPath; AStrokeTexture: IBGRAScanner; AWidth: single); overload; virtual; abstract;
466
467 procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeColor: TBGRAPixel; AWidth: single; AFillColor: TBGRAPixel); overload; virtual; abstract;
468 procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeTexture: IBGRAScanner; AWidth: single; AFillColor: TBGRAPixel); overload; virtual; abstract;
469 procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeColor: TBGRAPixel; AWidth: single; AFillTexture: IBGRAScanner); overload; virtual; abstract;
470 procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeTexture: IBGRAScanner; AWidth: single; AFillTexture: IBGRAScanner); overload; virtual; abstract;
471 procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeColor: TBGRAPixel; AWidth: single); overload; virtual; abstract;
472 procedure DrawPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AStrokeTexture: IBGRAScanner; AWidth: single); overload; virtual; abstract;
473
474 procedure ArrowStartAsNone; virtual; abstract;
475 procedure ArrowStartAsClassic(AFlipped: boolean = false; ACut: boolean = false; ARelativePenWidth: single = 1); virtual; abstract;
476 procedure ArrowStartAsTriangle(ABackOffset: single = 0; ARounded: boolean = false; AHollow: boolean = false; AHollowPenWidth: single = 0.5); virtual; abstract;
477 procedure ArrowStartAsTail; virtual; abstract;
478
479 procedure ArrowEndAsNone; virtual; abstract;
480 procedure ArrowEndAsClassic(AFlipped: boolean = false; ACut: boolean = false; ARelativePenWidth: single = 1); virtual; abstract;
481 procedure ArrowEndAsTriangle(ABackOffset: single = 0; ARounded: boolean = false; AHollow: boolean = false; AHollowPenWidth: single = 0.5); virtual; abstract;
482 procedure ArrowEndAsTail; virtual; abstract;
483
484 procedure DrawLine(x1, y1, x2, y2: integer; c: TBGRAPixel; DrawLastPixel: boolean; ADrawMode: TDrawMode= dmDrawWithTransparency); virtual; abstract;
485 procedure DrawLineAntialias(x1, y1, x2, y2: integer; c: TBGRAPixel; DrawLastPixel: boolean); overload; virtual; abstract;
486 procedure DrawLineAntialias(x1, y1, x2, y2: integer; c1, c2: TBGRAPixel; dashLen: integer; DrawLastPixel: boolean); overload; virtual; abstract;
487 procedure DrawLineAntialias(x1, y1, x2, y2: integer; c1, c2: TBGRAPixel; dashLen: integer; DrawLastPixel: boolean; var DashPos: integer); overload; virtual; abstract;
488 procedure DrawLineAntialias(x1, y1, x2, y2: single; c: TBGRAPixel; w: single); overload; virtual; abstract;
489 procedure DrawLineAntialias(x1, y1, x2, y2: single; texture: IBGRAScanner; w: single); overload; virtual; abstract;
490 procedure DrawLineAntialias(x1, y1, x2, y2: single; c: TBGRAPixel; w: single; ClosedCap: boolean); overload; virtual; abstract;
491 procedure DrawLineAntialias(x1, y1, x2, y2: single; texture: IBGRAScanner; w: single; ClosedCap: boolean); overload; virtual; abstract;
492
493 procedure DrawPolyLine(const points: array of TPoint; c: TBGRAPixel; DrawLastPixel: boolean; ADrawMode: TDrawMode=dmDrawWithTransparency);
494 procedure DrawPolyLineAntialias(const points: array of TPoint; c: TBGRAPixel; DrawLastPixel: boolean);overload; virtual;
495 procedure DrawPolyLineAntialias(const points: array of TPoint; c1, c2: TBGRAPixel; dashLen: integer; DrawLastPixel: boolean);overload; virtual;
496 procedure DrawPolyLineAntialias(const points: array of TPointF; c: TBGRAPixel; w: single); overload; virtual; abstract;
497 procedure DrawPolyLineAntialias(const points: array of TPointF; texture: IBGRAScanner; w: single); overload; virtual; abstract;
498 procedure DrawPolyLineAntialias(const points: array of TPointF; c: TBGRAPixel; w: single; ClosedCap: boolean); overload; virtual; abstract;
499 procedure DrawPolyLineAntialias(const points: array of TPointF; texture: IBGRAScanner; w: single; ClosedCap: boolean); overload; virtual; abstract;
500 procedure DrawPolyLineAntialias(const points: array of TPointF; c: TBGRAPixel; w: single; fillcolor: TBGRAPixel); overload; virtual; abstract;
501 procedure DrawPolyLineAntialiasAutocycle(const points: array of TPointF; c: TBGRAPixel; w: single); overload; virtual; abstract;
502 procedure DrawPolyLineAntialiasAutocycle(const points: array of TPointF; texture: IBGRAScanner; w: single); overload; virtual; abstract;
503 procedure DrawPolygon(const points: array of TPoint; c: TBGRAPixel; ADrawMode: TDrawMode=dmDrawWithTransparency);
504 procedure DrawPolygonAntialias(const points: array of TPoint; c: TBGRAPixel); overload;
505 procedure DrawPolygonAntialias(const points: array of TPoint; c1, c2: TBGRAPixel; dashLen: integer); overload;
506 procedure DrawPolygonAntialias(const points: array of TPointF; c: TBGRAPixel; w: single); overload; virtual; abstract;
507 procedure DrawPolygonAntialias(const points: array of TPointF; texture: IBGRAScanner; w: single); overload; virtual; abstract;
508 procedure DrawPolygonAntialias(const points: array of TPointF; c: TBGRAPixel; w: single; fillcolor: TBGRAPixel); overload; virtual; abstract;
509
510 procedure EraseLine(x1, y1, x2, y2: integer; alpha: byte; DrawLastPixel: boolean); virtual; abstract;
511 procedure EraseLineAntialias(x1, y1, x2, y2: integer; alpha: byte; DrawLastPixel: boolean); overload; virtual; abstract;
512 procedure EraseLineAntialias(x1, y1, x2, y2: single; alpha: byte; w: single); overload; virtual; abstract;
513 procedure EraseLineAntialias(x1, y1, x2, y2: single; alpha: byte; w: single; Closed: boolean); overload; virtual; abstract;
514 procedure ErasePolyLine(const points: array of TPoint; alpha: byte; DrawLastPixel: boolean);
515 procedure ErasePolyLineAntialias(const points: array of TPoint; alpha: byte; DrawLastPixel: boolean); overload;
516 procedure ErasePolyLineAntialias(const points: array of TPointF; alpha: byte; w: single); overload; virtual; abstract;
517 procedure ErasePolygonOutline(const points: array of TPoint; alpha: byte);
518 procedure ErasePolygonOutlineAntialias(const points: array of TPoint; alpha: byte);
519
520 procedure FillPath(APath: IBGRAPath; c: TBGRAPixel); overload; virtual; abstract;
521 procedure FillPath(APath: IBGRAPath; texture: IBGRAScanner); overload; virtual; abstract;
522 procedure ErasePath(APath: IBGRAPath; alpha: byte); overload; virtual; abstract;
523
524 procedure FillPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AFillColor: TBGRAPixel); overload; virtual; abstract;
525 procedure FillPath(APath: IBGRAPath; AMatrix: TAffineMatrix; AFillTexture: IBGRAScanner); overload; virtual; abstract;
526 procedure ErasePath(APath: IBGRAPath; AMatrix: TAffineMatrix; alpha: byte); overload; virtual; abstract;
527
528 procedure FillTriangleLinearColor(pt1,pt2,pt3: TPointF; c1,c2,c3: TBGRAPixel); overload; virtual; abstract;
529 procedure FillTriangleLinearColorAntialias(pt1,pt2,pt3: TPointF; c1,c2,c3: TBGRAPixel); overload; virtual; abstract;
530 procedure FillTriangleLinearMapping(pt1,pt2,pt3: TPointF; texture: IBGRAScanner; tex1, tex2, tex3: TPointF; TextureInterpolation: Boolean= True); overload; virtual; abstract;
531 procedure FillTriangleLinearMappingLightness(pt1,pt2,pt3: TPointF; texture: IBGRAScanner; tex1, tex2, tex3: TPointF; light1,light2,light3: word; TextureInterpolation: Boolean= True); overload; virtual; abstract;
532 procedure FillTriangleLinearMappingAntialias(pt1,pt2,pt3: TPointF; texture: IBGRAScanner; tex1, tex2, tex3: TPointF); overload; virtual; abstract;
533
534 procedure FillQuadLinearColor(pt1,pt2,pt3,pt4: TPointF; c1,c2,c3,c4: TBGRAPixel); overload; virtual; abstract;
535 procedure FillQuadLinearColorAntialias(pt1,pt2,pt3,pt4: TPointF; c1,c2,c3,c4: TBGRAPixel); overload; virtual; abstract;
536 procedure FillQuadLinearMapping(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; TextureInterpolation: Boolean= True; ACulling: TFaceCulling = fcNone); overload; virtual; abstract;
537 procedure FillQuadLinearMappingLightness(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; light1,light2,light3,light4: word; TextureInterpolation: Boolean= True); overload; virtual; abstract;
538 procedure FillQuadLinearMappingAntialias(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; ACulling: TFaceCulling = fcNone); overload; virtual; abstract;
539 procedure FillQuadPerspectiveMapping(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; ADrawMode: TDrawMode = dmDrawWithTransparency); overload; virtual; abstract;
540 procedure FillQuadPerspectiveMapping(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; ACleanBorders: TRect; ADrawMode: TDrawMode = dmDrawWithTransparency); overload; virtual; abstract;
541 procedure FillQuadPerspectiveMappingAntialias(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF); overload; virtual; abstract;
542 procedure FillQuadPerspectiveMappingAntialias(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; ACleanBorders: TRect); overload; virtual; abstract;
543 procedure FillQuadAffineMapping(Orig,HAxis,VAxis: TPointF; AImage: TBGRACustomBitmap; APixelCenteredCoordinates: boolean = true; ADrawMode: TDrawMode = dmDrawWithTransparency; AOpacity: byte = 255); virtual; abstract;
544 procedure FillQuadAffineMappingAntialias(Orig,HAxis,VAxis: TPointF; AImage: TBGRACustomBitmap; APixelCenteredCoordinates: boolean = true; AOpacity: byte = 255); virtual; abstract;
545
546 procedure FillPolyLinearColor(const points: array of TPointF; AColors: array of TBGRAPixel); overload; virtual; abstract;
547 procedure FillPolyLinearMapping(const points: array of TPointF; texture: IBGRAScanner; texCoords: array of TPointF; TextureInterpolation: Boolean); overload; virtual; abstract;
548 procedure FillPolyLinearMappingLightness(const points: array of TPointF; texture: IBGRAScanner; texCoords: array of TPointF; lightnesses: array of word; TextureInterpolation: Boolean); overload; virtual; abstract;
549 procedure FillPolyPerspectiveMapping(const points: array of TPointF; const pointsZ: array of single; texture: IBGRAScanner; texCoords: array of TPointF; TextureInterpolation: Boolean; zbuffer: psingle = nil); overload; virtual; abstract;
550 procedure FillPolyPerspectiveMappingLightness(const points: array of TPointF; const pointsZ: array of single; texture: IBGRAScanner; texCoords: array of TPointF; lightnesses: array of word; TextureInterpolation: Boolean; zbuffer: psingle = nil); overload; virtual; abstract;
551
552 procedure FillPoly(const points: array of TPointF; c: TBGRAPixel; drawmode: TDrawMode; APixelCenteredCoordinates: boolean = true); overload; virtual; abstract;
553 procedure FillPoly(const points: array of TPointF; texture: IBGRAScanner; drawmode: TDrawMode; APixelCenteredCoordinates: boolean = true); overload; virtual; abstract;
554 procedure FillPolyAntialias(const points: array of TPointF; c: TBGRAPixel; APixelCenteredCoordinates: boolean = true); overload; virtual; abstract;
555 procedure FillPolyAntialias(const points: array of TPointF; texture: IBGRAScanner; APixelCenteredCoordinates: boolean = true); overload; virtual; abstract;
556 procedure ErasePoly(const points: array of TPointF; alpha: byte; APixelCenteredCoordinates: boolean = true); virtual; abstract;
557 procedure ErasePolyAntialias(const points: array of TPointF; alpha: byte; APixelCenteredCoordinates: boolean = true); virtual; abstract;
558
559 procedure FillShape(shape: TBGRACustomFillInfo; c: TBGRAPixel; drawmode: TDrawMode); overload; virtual; abstract;
560 procedure FillShape(shape: TBGRACustomFillInfo; texture: IBGRAScanner; drawmode: TDrawMode); overload; virtual; abstract;
561 procedure FillShapeAntialias(shape: TBGRACustomFillInfo; c: TBGRAPixel); overload; virtual; abstract;
562 procedure FillShapeAntialias(shape: TBGRACustomFillInfo; texture: IBGRAScanner); overload; virtual; abstract;
563 procedure EraseShape(shape: TBGRACustomFillInfo; alpha: byte); overload; virtual; abstract;
564 procedure EraseShapeAntialias(shape: TBGRACustomFillInfo; alpha: byte); virtual; abstract;
565
566 procedure Ellipse(x, y, rx, ry: single; c: TBGRAPixel; w: single; ADrawMode: TDrawMode); overload; virtual; abstract;
567 procedure Ellipse(AOrigin, AXAxis, AYAxis: TPointF; c: TBGRAPixel; w: single; ADrawMode: TDrawMode); overload; virtual; abstract;
568 procedure EllipseAntialias(x, y, rx, ry: single; c: TBGRAPixel; w: single); overload; virtual; abstract;
569 procedure EllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; c: TBGRAPixel; w: single); overload; virtual; abstract;
570 procedure EllipseAntialias(x, y, rx, ry: single; texture: IBGRAScanner; w: single); overload; virtual; abstract;
571 procedure EllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; texture: IBGRAScanner; w: single); overload; virtual; abstract;
572 procedure EllipseAntialias(x, y, rx, ry: single; c: TBGRAPixel; w: single; back: TBGRAPixel); overload; virtual; abstract;
573 procedure EllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; c: TBGRAPixel; w: single; back: TBGRAPixel); overload; virtual; abstract;
574 procedure FillEllipseAntialias(x, y, rx, ry: single; c: TBGRAPixel); overload; virtual; abstract;
575 procedure FillEllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; c: TBGRAPixel); overload; virtual; abstract;
576 procedure FillEllipseAntialias(x, y, rx, ry: single; texture: IBGRAScanner); overload; virtual; abstract;
577 procedure FillEllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; texture: IBGRAScanner); overload; virtual; abstract;
578 procedure FillEllipseLinearColorAntialias(x, y, rx, ry: single; outercolor, innercolor: TBGRAPixel); overload; virtual; abstract;
579 procedure FillEllipseLinearColorAntialias(AOrigin, AXAxis, AYAxis: TPointF; outercolor, innercolor: TBGRAPixel); overload; virtual; abstract;
580 procedure EraseEllipseAntialias(x, y, rx, ry: single; alpha: byte); overload; virtual; abstract;
581 procedure EraseEllipseAntialias(AOrigin, AXAxis, AYAxis: TPointF; alpha: byte); overload; virtual; abstract;
582
583 procedure Arc(cx,cy,rx,ry: single; const StartPoint,EndPoint: TPointF; AColor: TBGRAPixel; w: single; ADrawChord: boolean; AFillColor: TBGRAPixel); overload;
584 procedure Arc(cx,cy,rx,ry: single; StartAngleRad,EndAngleRad: Single; AColor: TBGRAPixel; w: single; ADrawChord: boolean; AFillColor: TBGRAPixel); overload;
585 procedure FillChord(cx,cy,rx,ry: single; const StartPoint,EndPoint: TPointF; AFillColor: TBGRAPixel); overload;
586 procedure FillChord(cx,cy,rx,ry: single; StartAngleRad,EndAngleRad: Single; AFillColor: TBGRAPixel); overload;
587 procedure FillChord(cx,cy,rx,ry: single; const StartPoint,EndPoint: TPointF; texture: IBGRAScanner); overload;
588 procedure FillChord(cx,cy,rx,ry: single; StartAngleRad,EndAngleRad: Single; texture: IBGRAScanner); overload;
589 procedure FillChordInRect(const ARect: TRect; StartAngleRad,EndAngleRad: Single; AFillColor: TBGRAPixel); overload;
590 procedure FillChordInRect(const ARect: TRect; StartAngleRad,EndAngleRad: Single; texture: IBGRAScanner); overload;
591
592 procedure Pie(cx,cy,rx,ry: single; const StartPoint,EndPoint: TPointF; AColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel); overload;
593 procedure Pie(cx,cy,rx,ry: single; StartAngleRad,EndAngleRad: Single; AColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel); overload;
594 procedure FillPie(cx,cy,rx,ry: single; const StartPoint,EndPoint: TPointF; AFillColor: TBGRAPixel); overload;
595 procedure FillPie(cx,cy,rx,ry: single; StartAngleRad,EndAngleRad: Single; AFillColor: TBGRAPixel); overload;
596 procedure FillPie(cx,cy,rx,ry: single; const StartPoint,EndPoint: TPointF; texture: IBGRAScanner); overload;
597 procedure FillPie(cx,cy,rx,ry: single; StartAngleRad,EndAngleRad: Single; texture: IBGRAScanner); overload;
598 procedure FillPieInRect(const ARect: TRect; StartAngleRad,EndAngleRad: Single; AFillColor: TBGRAPixel); overload;
599 procedure FillPieInRect(const ARect: TRect; StartAngleRad,EndAngleRad: Single; texture: IBGRAScanner); overload;
600
601 procedure Rectangle(x, y, x2, y2: integer; c: TBGRAPixel; mode: TDrawMode); overload; virtual; abstract;
602 procedure Rectangle(x, y, x2, y2: integer; BorderColor, FillColor: TBGRAPixel; mode: TDrawMode); overload; virtual; abstract;
603 procedure Rectangle(x, y, x2, y2: integer; c: TColor); overload; virtual;
604 procedure Rectangle(r: TRect; c: TBGRAPixel; mode: TDrawMode); overload; virtual;
605 procedure Rectangle(r: TRect; BorderColor, FillColor: TBGRAPixel; mode: TDrawMode); overload; virtual;
606 procedure Rectangle(r: TRect; c: TColor); overload; virtual;
607 procedure RectangleAntialias(x, y, x2, y2: single; c: TBGRAPixel; w: single); overload; virtual;
608 procedure RectangleAntialias(x, y, x2, y2: single; c: TBGRAPixel; w: single; back: TBGRAPixel); overload; virtual; abstract;
609 procedure RectangleAntialias(x, y, x2, y2: single; texture: IBGRAScanner; w: single); overload; virtual; abstract;
610 procedure RectangleWithin(x1,y1,x2,y2: single; ABorderColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel; APixelCenteredCoordinates: boolean = true); overload;
611 procedure RectangleWithin(r: TRect; ABorderColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel); overload;
612
613 procedure RoundRect(X1, Y1, X2, Y2: integer; DX, DY: integer; BorderColor, FillColor: TBGRAPixel; ADrawMode: TDrawMode = dmDrawWithTransparency); overload; virtual; abstract;
614 procedure RoundRect(X1, Y1, X2, Y2: integer; DX, DY: integer; BorderColor: TBGRAPixel; ADrawMode: TDrawMode = dmDrawWithTransparency); overload; virtual; abstract;
615 procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; c: TBGRAPixel; w: single; options: TRoundRectangleOptions = []); overload; virtual; abstract;
616 procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; pencolor: TBGRAPixel; w: single; fillcolor: TBGRAPixel; options: TRoundRectangleOptions = []); overload; virtual; abstract;
617 procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; penTexture: IBGRAScanner; w: single; fillTexture: IBGRAScanner; options: TRoundRectangleOptions = []); overload; virtual; abstract;
618 procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; texture: IBGRAScanner; w: single; options: TRoundRectangleOptions = []); overload; virtual; abstract;
619 procedure FillRoundRect(X1, Y1, X2, Y2: integer; DX, DY: integer; FillColor: TBGRAPixel; ADrawMode: TDrawMode = dmDrawWithTransparency); overload; virtual;
620 procedure FillRoundRect(X1, Y1, X2, Y2: integer; DX, DY: integer; FillTexture: IBGRAScanner; ADrawMode: TDrawMode = dmDrawWithTransparency); overload; virtual; abstract;
621 procedure FillRoundRectAntialias(x,y,x2,y2,rx,ry: single; c: TBGRAPixel; options: TRoundRectangleOptions = []; pixelCenteredCoordinates: boolean = true); overload; virtual; abstract;
622 procedure FillRoundRectAntialias(x,y,x2,y2,rx,ry: single; texture: IBGRAScanner; options: TRoundRectangleOptions = []; pixelCenteredCoordinates: boolean = true); overload; virtual; abstract;
623 procedure EraseRoundRectAntialias(x,y,x2,y2,rx,ry: single; alpha: byte; options: TRoundRectangleOptions = []; pixelCenteredCoordinates: boolean = true); virtual; abstract;
624
625 procedure EllipseInRect(r: TRect; BorderColor: TBGRAPixel; ADrawMode: TDrawMode = dmDrawWithTransparency); overload; virtual;
626 procedure EllipseInRect(r: TRect; BorderColor,FillColor: TBGRAPixel; ADrawMode: TDrawMode = dmDrawWithTransparency); overload; virtual;
627 procedure FillEllipseInRect(r: TRect; FillColor: TBGRAPixel; ADrawMode: TDrawMode = dmDrawWithTransparency); overload; virtual;
628 procedure FillEllipseInRect(r: TRect; FillTexture: IBGRAScanner; ADrawMode: TDrawMode = dmDrawWithTransparency); overload; virtual;
629
630 procedure FillRect(r: TRect; c: TColor); overload; virtual;
631 procedure FillRect(r: TRect; c: TBGRAPixel; mode: TDrawMode); overload; virtual;
632 procedure FillRect(r: TRect; texture: IBGRAScanner; mode: TDrawMode); overload; virtual;
633 procedure FillRect(r: TRect; texture: IBGRAScanner; mode: TDrawMode; AScanOffset: TPoint); overload; virtual;
634 procedure FillRect(r: TRect; texture: IBGRAScanner; mode: TDrawMode; ditheringAlgorithm: TDitheringAlgorithm); overload; virtual;
635 procedure FillRect(r: TRect; texture: IBGRAScanner; mode: TDrawMode; AScanOffset: TPoint; ditheringAlgorithm: TDitheringAlgorithm); overload; virtual;
636 procedure FillRect(x, y, x2, y2: integer; c: TColor); overload; virtual;
637 procedure FillRect(x, y, x2, y2: integer; c: TBGRAPixel; mode: TDrawMode); overload; virtual; abstract;
638 procedure FillRect(x, y, x2, y2: integer; texture: IBGRAScanner; mode: TDrawMode); overload; virtual;
639 procedure FillRect(x, y, x2, y2: integer; texture: IBGRAScanner; mode: TDrawMode; AScanOffset: TPoint); overload; virtual; abstract;
640 procedure FillRect(x, y, x2, y2: integer; texture: IBGRAScanner; mode: TDrawMode; ditheringAlgorithm: TDitheringAlgorithm); overload; virtual;
641 procedure FillRect(x, y, x2, y2: integer; texture: IBGRAScanner; mode: TDrawMode; AScanOffset: TPoint; ditheringAlgorithm: TDitheringAlgorithm); overload; virtual; abstract;
642 procedure FillRectAntialias(x, y, x2, y2: single; c: TBGRAPixel; pixelCenteredCoordinates: boolean = true); overload; virtual; abstract;
643 procedure FillRectAntialias(x, y, x2, y2: single; texture: IBGRAScanner; pixelCenteredCoordinates: boolean = true); overload; virtual; abstract;
644 procedure FillRectAntialias(ARect: TRectF; c: TBGRAPixel; pixelCenteredCoordinates: boolean = true); overload;
645 procedure FillRectAntialias(ARect: TRectF; texture: IBGRAScanner; pixelCenteredCoordinates: boolean = true); overload;
646 procedure EraseRectAntialias(x, y, x2, y2: single; alpha: byte; pixelCenteredCoordinates: boolean = true); virtual; abstract;
647 procedure AlphaFillRect(x, y, x2, y2: integer; alpha: byte); virtual; abstract;
648
649 procedure TextOut(x, y: single; sUTF8: string; c: TBGRAPixel; align: TAlignment; ARightToLeft: boolean); overload; virtual; abstract;
650 procedure TextOut(x, y: single; sUTF8: string; texture: IBGRAScanner; align: TAlignment; ARightToLeft: boolean); overload; virtual; abstract;
651 procedure TextOutCurved(ACursor: TBGRACustomPathCursor; sUTF8: string; AColor: TBGRAPixel; AAlign: TAlignment; ALetterSpacing: single); overload; virtual; abstract;
652 procedure TextOutCurved(ACursor: TBGRACustomPathCursor; sUTF8: string; ATexture: IBGRAScanner; AAlign: TAlignment; ALetterSpacing: single); overload; virtual; abstract;
653 procedure TextOutCurved(APath: IBGRAPath; sUTF8: string; AColor: TBGRAPixel; AAlign: TAlignment; ALetterSpacing: single); overload; virtual;
654 procedure TextOutCurved(APath: IBGRAPath; sUTF8: string; ATexture: IBGRAScanner; AAlign: TAlignment; ALetterSpacing: single); overload; virtual;
655 procedure TextOutAngle(x, y: single; orientationTenthDegCCW: integer; sUTF8: string; c: TBGRAPixel; align: TAlignment); overload; virtual; abstract;
656 procedure TextOutAngle(x, y: single; orientationTenthDegCCW: integer; sUTF8: string; texture: IBGRAScanner; align: TAlignment); overload; virtual; abstract;
657 procedure TextRect(ARect: TRect; x, y: integer; sUTF8: string; style: TTextStyle; c: TBGRAPixel); overload; virtual; abstract;
658 procedure TextRect(ARect: TRect; x, y: integer; sUTF8: string; style: TTextStyle; texture: IBGRAScanner); overload; virtual; abstract;
659 procedure TextMultiline(x,y: single; sUTF8: string; c: TBGRAPixel; AAlign: TBidiTextAlignment = btaLeftJustify; AVertAlign: TTextLayout = tlTop; AParagraphSpacing: single = 0); overload;
660 procedure TextMultiline(x,y: single; sUTF8: string; ATexture: IBGRAScanner; AAlign: TBidiTextAlignment = btaLeftJustify; AVertAlign: TTextLayout = tlTop; AParagraphSpacing: single = 0); overload;
661 procedure TextMultiline(ALeft,ATop,AWidth: single; sUTF8: string; c: TBGRAPixel; AAlign: TBidiTextAlignment = btaNatural; AVertAlign: TTextLayout = tlTop; AParagraphSpacing: single = 0); overload; virtual; abstract;
662 procedure TextMultiline(ALeft,ATop,AWidth: single; sUTF8: string; ATexture: IBGRAScanner; AAlign: TBidiTextAlignment = btaNatural; AVertAlign: TTextLayout = tlTop; AParagraphSpacing: single = 0); overload; virtual; abstract;
663 function TextSize(sUTF8: string): TSize; overload; virtual; abstract;
664 function TextAffineBox(sUTF8: string): TAffineBox; virtual; abstract;
665 function TextSize(sUTF8: string; AMaxWidth: integer): TSize; overload; virtual; abstract;
666 function TextSize(sUTF8: string; AMaxWidth: integer; ARightToLeft: boolean): TSize; overload; virtual; abstract;
667 function TextFitInfo(sUTF8: string; AMaxWidth: integer): integer; virtual; abstract;
668
669 { Draw the UTF8 encoded string, (x,y) being the top-left corner. The color c or texture is used to fill the text.
670 The value of FontOrientation is taken into account, so that the text may be rotated. }
671 procedure TextOut(x, y: single; sUTF8: string; c: TBGRAPixel; align: TAlignment); overload; virtual;
672 procedure TextOut(x, y: single; sUTF8: string; texture: IBGRAScanner; align: TAlignment); overload; virtual;
673 procedure TextOut(x, y: single; sUTF8: string; c: TBGRAPixel); overload; virtual;
674 procedure TextOut(x, y: single; sUTF8: string; c: TBGRAPixel; ARightToLeft: boolean); overload; virtual;
675 procedure TextOut(x, y: single; sUTF8: string; c: TColor); overload; virtual;
676 procedure TextOut(x, y: single; sUTF8: string; c: TColor; ARightToLeft: boolean); overload; virtual;
677 procedure TextOut(x, y: single; sUTF8: string; texture: IBGRAScanner); overload; virtual;
678 procedure TextOut(x, y: single; sUTF8: string; texture: IBGRAScanner; ARightToLeft: boolean); overload; virtual;
679
680 { Draw the UTF8 encoded string in the rectangle ARect. Text is wrapped if necessary.
681 The position depends on the specified horizontal alignment halign and vertical alignement valign.
682 The color c or texture is used to fill the text. No rotation is applied. }
683 procedure TextRect(ARect: TRect; sUTF8: string; halign: TAlignment; valign: TTextLayout; c: TBGRAPixel); overload; virtual;
684 procedure TextRect(ARect: TRect; sUTF8: string; halign: TAlignment; valign: TTextLayout; texture: IBGRAScanner); overload; virtual;
685
686 {Spline}
687 function ComputeClosedSpline(const APoints: array of TPointF; AStyle: TSplineStyle): ArrayOfTPointF; virtual; abstract;
688 function ComputeOpenedSpline(const APoints: array of TPointF; AStyle: TSplineStyle): ArrayOfTPointF; virtual; abstract;
689 function ComputeBezierCurve(const curve: TCubicBezierCurve): ArrayOfTPointF; overload; virtual; abstract;
690 function ComputeBezierCurve(const curve: TQuadraticBezierCurve): ArrayOfTPointF; overload; virtual; abstract;
691 function ComputeBezierSpline(const spline: array of TCubicBezierCurve): ArrayOfTPointF; overload; virtual; abstract;
692 function ComputeBezierSpline(const spline: array of TQuadraticBezierCurve): ArrayOfTPointF; overload; virtual; abstract;
693
694 function ComputeWidePolyline(const points: array of TPointF; w: single): ArrayOfTPointF; overload; virtual; abstract;
695 function ComputeWidePolyline(const points: array of TPointF; w: single; ClosedCap: boolean): ArrayOfTPointF; overload; virtual; abstract;
696 function ComputeWidePolygon(const points: array of TPointF; w: single): ArrayOfTPointF; virtual; abstract;
697
698 function ComputeEllipse(x,y,rx,ry: single): ArrayOfTPointF; overload; deprecated;
699 function ComputeEllipse(x,y,rx,ry,w: single): ArrayOfTPointF; overload; deprecated;
700 function ComputeEllipseContour(x,y,rx,ry: single; quality: single = 1): ArrayOfTPointF; overload; virtual; abstract;
701 function ComputeEllipseContour(AOrigin, AXAxis, AYAxis: TPointF; quality: single = 1): ArrayOfTPointF; overload; virtual; abstract;
702 function ComputeEllipseBorder(x,y,rx,ry,w: single; quality: single = 1): ArrayOfTPointF; overload; virtual; abstract;
703 function ComputeEllipseBorder(AOrigin, AXAxis, AYAxis: TPointF; w: single; quality: single = 1): ArrayOfTPointF; overload; virtual; abstract;
704 function ComputeArc65536(x,y,rx,ry: single; start65536,end65536: word; quality: single = 1): ArrayOfTPointF; virtual; abstract;
705 function ComputeArcRad(x,y,rx,ry: single; startRad,endRad: single; quality: single = 1): ArrayOfTPointF; virtual; abstract;
706 function ComputeRoundRect(x1,y1,x2,y2,rx,ry: single; quality: single = 1): ArrayOfTPointF; overload; virtual; abstract;
707 function ComputeRoundRect(x1,y1,x2,y2,rx,ry: single; options: TRoundRectangleOptions; quality: single = 1): ArrayOfTPointF; overload; virtual; abstract;
708 function ComputePie65536(x,y,rx,ry: single; start65536,end65536: word; quality: single = 1): ArrayOfTPointF; virtual; abstract;
709 function ComputePieRad(x,y,rx,ry: single; startRad,endRad: single; quality: single = 1): ArrayOfTPointF; virtual; abstract;
710
711 {Filling}
712 procedure FillTransparent; virtual;
713 procedure NoClip; virtual; abstract;
714 procedure ApplyGlobalOpacity(alpha: byte); overload; virtual; abstract;
715 procedure ApplyGlobalOpacity(ARect: TRect; alpha: byte); overload; virtual; abstract;
716 procedure Fill(c: TColor); overload; virtual;
717 procedure Fill(c: TBGRAPixel); overload; virtual;
718 procedure Fill(texture: IBGRAScanner; mode: TDrawMode); overload; virtual; abstract;
719 procedure Fill(texture: IBGRAScanner); overload; virtual; abstract;
720 procedure Fill(c: TBGRAPixel; start, Count: integer); overload; virtual; abstract;
721 procedure DrawPixels(c: TBGRAPixel; start, Count: integer); virtual; abstract;
722 procedure AlphaFill(alpha: byte); overload; virtual;
723 procedure AlphaFill(alpha: byte; start, Count: integer); overload; virtual; abstract;
724 procedure FillMask(x,y: integer; AMask: TBGRACustomBitmap; color: TBGRAPixel); overload; virtual;
725 procedure FillMask(x,y: integer; AMask: TBGRACustomBitmap; texture: IBGRAScanner); overload; virtual;
726 procedure FillMask(x,y: integer; AMask: TBGRACustomBitmap; color: TBGRAPixel; ADrawMode: TDrawMode); overload; virtual; abstract;
727 procedure FillMask(x,y: integer; AMask: TBGRACustomBitmap; texture: IBGRAScanner; ADrawMode: TDrawMode; AOpacity: byte = 255); overload; virtual; abstract;
728 procedure EraseMask(x,y: integer; AMask: TBGRACustomBitmap; alpha: byte=255); virtual; abstract;
729 procedure FillClearTypeMask(x,y: integer; xThird: integer; AMask: TBGRACustomBitmap; color: TBGRAPixel; ARGBOrder: boolean = true); overload; virtual; abstract;
730 procedure FillClearTypeMask(x,y: integer; xThird: integer; AMask: TBGRACustomBitmap; texture: IBGRAScanner; ARGBOrder: boolean = true); overload; virtual; abstract;
731 procedure ReplaceColor(before, after: TColor); overload; virtual; abstract;
732 procedure ReplaceColor(before, after: TBGRAPixel); overload; virtual; abstract;
733 procedure ReplaceColor(ARect: TRect; before, after: TColor); overload; virtual; abstract;
734 procedure ReplaceColor(ARect: TRect; before, after: TBGRAPixel); overload; virtual; abstract;
735 procedure ReplaceTransparent(after: TBGRAPixel); overload; virtual; abstract;
736 procedure ReplaceTransparent(ABounds: TRect; after: TBGRAPixel); overload; virtual; abstract;
737 procedure FloodFill(X, Y: integer; Color: TBGRAPixel;
738 mode: TFloodfillMode; Tolerance: byte = 0); virtual;
739 procedure ParallelFloodFill(X, Y: integer; Dest: TBGRACustomBitmap; Color: TBGRAPixel;
740 mode: TFloodfillMode; Tolerance: byte = 0); virtual; abstract;
741 procedure GradientFill(x, y, x2, y2: integer; c1, c2: TBGRAPixel;
742 gtype: TGradientType; o1, o2: TPointF; mode: TDrawMode;
743 gammaColorCorrection: boolean = True; Sinus: Boolean=False;
744 ditherAlgo: TDitheringAlgorithm = daNearestNeighbor); overload; virtual; abstract;
745 procedure GradientFill(x, y, x2, y2: integer; gradient: TBGRACustomGradient;
746 gtype: TGradientType; o1, o2: TPointF; mode: TDrawMode;
747 Sinus: Boolean=False;
748 ditherAlgo: TDitheringAlgorithm = daNearestNeighbor); overload; virtual; abstract;
749 function CreateBrushTexture(ABrushStyle: TBrushStyle; APatternColor, ABackgroundColor: TBGRAPixel;
750 AWidth: integer = 8; AHeight: integer = 8; APenWidth: single = 1): TBGRACustomBitmap; virtual; abstract;
751
752 {Canvas drawing functions}
753 procedure DataDrawTransparent(ACanvas: TCanvas; Rect: TRect;
754 AData: Pointer; ALineOrder: TRawImageLineOrder; AWidth, AHeight: integer); virtual; abstract;
755 procedure DataDrawOpaque(ACanvas: TCanvas; ARect: TRect; AData: Pointer;
756 ALineOrder: TRawImageLineOrder; AWidth, AHeight: integer); virtual; abstract;
757 procedure GetImageFromCanvas(CanvasSource: TCanvas; x, y: integer); virtual; abstract;
758 procedure Draw(ACanvas: TCanvas; x, y: integer; Opaque: boolean = True); overload; virtual; abstract;
759 procedure Draw(ACanvas: TCanvas; Rect: TRect; Opaque: boolean = True); overload; virtual; abstract;
760 procedure DrawPart(ARect: TRect; ACanvas: TCanvas; x, y: integer; Opaque: boolean); virtual;
761 function GetPart(ARect: TRect): TBGRACustomBitmap; virtual; abstract;
762 function GetPtrBitmap(Top,Bottom: Integer): TBGRACustomBitmap; virtual; abstract;
763 procedure InvalidateBitmap; virtual; abstract; //call if you modify with Scanline
764 procedure LoadFromBitmapIfNeeded; virtual; abstract; //call to ensure that bitmap data is up to date
765
766 {BGRA bitmap functions}
767 procedure CrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadePosition: byte; mode: TDrawMode = dmDrawWithTransparency); overload; virtual; abstract;
768 procedure CrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadeMask: IBGRAScanner; mode: TDrawMode = dmDrawWithTransparency); overload; virtual; abstract;
769 procedure PutImage(x, y: integer; Source: TBGRACustomBitmap; mode: TDrawMode; AOpacity: byte = 255); overload; virtual; abstract;
770 procedure PutImage(x, y: integer; Source: TBitmap; mode: TDrawMode; AOpacity: byte = 255); overload;
771 procedure StretchPutImage(ARect: TRect; Source: TBGRACustomBitmap; mode: TDrawMode; AOpacity: byte = 255); virtual; abstract;
772 procedure StretchPutImageProportionally(ARect: TRect; AHorizAlign: TAlignment; AVertAlign: TTextLayout; Source: TBGRACustomBitmap; mode: TDrawMode; AOpacity: byte = 255);
773 procedure PutImageSubpixel(x, y: single; Source: TBGRACustomBitmap; AOpacity: byte = 255);
774 procedure PutImagePart(x,y: integer; Source: TBGRACustomBitmap; SourceRect: TRect; mode: TDrawMode; AOpacity: byte = 255);
775 procedure PutImageAffine(Origin,HAxis,VAxis: TPointF; Source: TBGRACustomBitmap; AOpacity: Byte=255; ACorrectBlur: Boolean = false); overload;
776 procedure PutImageAffine(Origin,HAxis,VAxis: TPointF; Source: TBGRACustomBitmap; AResampleFilter: TResampleFilter; AOpacity: Byte=255); overload;
777 procedure PutImageAffine(Origin,HAxis,VAxis: TPointF; Source: TBGRACustomBitmap; AOutputBounds: TRect; AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte=255); overload;
778 procedure PutImageAffine(Origin,HAxis,VAxis: TPointF; Source: TBGRACustomBitmap; AOutputBounds: TRect; AOpacity: Byte=255; ACorrectBlur: Boolean = false); overload;
779 procedure PutImageAffine(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; AOpacity: Byte=255; ACorrectBlur: Boolean = false); overload;
780 procedure PutImageAffine(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; AResampleFilter: TResampleFilter; AOpacity: Byte=255); overload;
781 procedure PutImageAffine(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte=255); overload;
782 procedure PutImageAffine(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; AOutputBounds: TRect; AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte=255); overload; virtual; abstract;
783 procedure PutImageAffine(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap; AOutputBounds: TRect; AOpacity: Byte=255; ACorrectBlur: Boolean = false); overload;
784 function GetImageAffineBounds(Origin,HAxis,VAxis: TPointF; Source: TBGRACustomBitmap): TRect; overload;
785 function GetImageAffineBounds(Origin,HAxis,VAxis: TPointF; ASourceWidth, ASourceHeight: integer; const ASourceBounds: TRect; AClipOutput: boolean = true): TRect; overload;
786 function GetImageAffineBounds(AMatrix: TAffineMatrix; Source: TBGRACustomBitmap): TRect; overload;
787 function GetImageAffineBounds(AMatrix: TAffineMatrix; ASourceBounds: TRect; AClipOutput: boolean = true): TRect; overload; virtual; abstract;
788 class function IsAffineRoughlyTranslation(AMatrix: TAffineMatrix; ASourceBounds: TRect): boolean; virtual; abstract;
789 procedure PutImageAngle(x,y: single; Source: TBGRACustomBitmap; angle: single; AOutputBounds: TRect; imageCenterX: single = 0; imageCenterY: single = 0; AOpacity: Byte=255; ARestoreOffsetAfterRotation: boolean = false; ACorrectBlur: Boolean = false); overload;
790 procedure PutImageAngle(x,y: single; Source: TBGRACustomBitmap; angle: single; imageCenterX: single = 0; imageCenterY: single = 0; AOpacity: Byte=255; ARestoreOffsetAfterRotation: boolean = false; ACorrectBlur: Boolean = false); overload;
791 procedure PutImageAngle(x,y: single; Source: TBGRACustomBitmap; angle: single; AOutputBounds: TRect; AResampleFilter: TResampleFilter; imageCenterX: single = 0; imageCenterY: single = 0; AOpacity: Byte=255; ARestoreOffsetAfterRotation: boolean = false); overload;
792 procedure PutImageAngle(x,y: single; Source: TBGRACustomBitmap; angle: single; AResampleFilter: TResampleFilter; imageCenterX: single = 0; imageCenterY: single = 0; AOpacity: Byte=255; ARestoreOffsetAfterRotation: boolean = false); overload;
793 procedure ComputeImageAngleAxes(x,y,w,h,angle: single; imageCenterX,imageCenterY: single; ARestoreOffsetAfterRotation: boolean;
794 out Origin,HAxis,VAxis: TPointF);
795 function GetImageAngleBounds(x,y: single; Source: TBGRACustomBitmap; angle: single; imageCenterX: single = 0; imageCenterY: single = 0; ARestoreOffsetAfterRotation: boolean = false): TRect;
796 procedure BlendImage(x, y: integer; Source: TBGRACustomBitmap; operation: TBlendOperation); virtual; abstract;
797 procedure BlendImageOver(x, y: integer; Source: TBGRACustomBitmap; operation: TBlendOperation; AOpacity: byte = 255;
798 ALinearBlend: boolean = false); virtual; abstract;
799 function Duplicate(DuplicateProperties: Boolean = False; DuplicateXorMask: Boolean = False): TBGRACustomBitmap; virtual; abstract;
800 function Equals(comp: TBGRACustomBitmap): boolean; overload; virtual; abstract;
801 function Equals(comp: TBGRAPixel): boolean; overload; virtual; abstract;
802 function Resample(newWidth, newHeight: integer;
803 mode: TResampleMode = rmFineResample): TBGRACustomBitmap; virtual; abstract;
804 procedure VerticalFlip; overload; virtual;
805 procedure VerticalFlip(ARect: TRect); overload; virtual; abstract;
806 procedure HorizontalFlip; overload; virtual;
807 procedure HorizontalFlip(ARect: TRect); overload; virtual; abstract;
808 function RotateCW: TBGRACustomBitmap; virtual; abstract;
809 function RotateCCW: TBGRACustomBitmap; virtual; abstract;
810 procedure Negative; virtual; abstract;
811 procedure NegativeRect(ABounds: TRect); virtual; abstract;
812 procedure LinearNegative; virtual; abstract;
813 procedure LinearNegativeRect(ABounds: TRect); virtual; abstract;
814 procedure InplaceGrayscale(AGammaCorrection: boolean = true); overload; virtual; abstract;
815 procedure InplaceGrayscale(ABounds: TRect; AGammaCorrection: boolean = true); overload; virtual; abstract;
816 procedure InplaceNormalize(AEachChannel: boolean = True); overload; virtual; abstract;
817 procedure InplaceNormalize(ABounds: TRect; AEachChannel: boolean = True); overload; virtual; abstract;
818 procedure ConvertToLinearRGB; virtual; abstract;
819 procedure ConvertFromLinearRGB; virtual; abstract;
820 procedure DrawCheckers(ARect: TRect; AColorEven,AColorOdd: TBGRAPixel); virtual; abstract;
821 procedure SwapRedBlue; overload; virtual; abstract;
822 procedure SwapRedBlue(ARect: TRect); overload; virtual; abstract;
823 procedure GrayscaleToAlpha; virtual; abstract;
824 procedure AlphaToGrayscale; virtual; abstract;
825 procedure ApplyMask(mask: TBGRACustomBitmap); overload;
826 procedure ApplyMask(mask: TBGRACustomBitmap; ARect: TRect); overload;
827 procedure ApplyMask(mask: TBGRACustomBitmap; ARect: TRect; AMaskRectTopLeft: TPoint); overload; virtual; abstract;
828 function GetMaskFromAlpha: TBGRACustomBitmap; virtual; abstract;
829 function GetImageBounds(Channel: TChannel = cAlpha; ANothingValue: Byte = 0): TRect; overload; virtual;
830 function GetImageBounds(Channels: TChannels; ANothingValue: Byte = 0): TRect; overload; virtual;
831 function GetImageBoundsWithin(const ARect: TRect; Channel: TChannel = cAlpha; ANothingValue: Byte = 0): TRect; overload; virtual;
832 function GetImageBoundsWithin(const ARect: TRect; Channels: TChannels; ANothingValue: Byte = 0): TRect; overload; virtual;
833 function GetDifferenceBounds(ABitmap: TBGRACustomBitmap): TRect; virtual; abstract;
834 function MakeBitmapCopy(BackgroundColor: TColor): TBitmap; virtual; abstract;
835
836 {Filters}
837 function FilterSmartZoom3(Option: TMedianOption): TBGRACustomBitmap; virtual; abstract;
838 function FilterMedian(Option: TMedianOption): TBGRACustomBitmap; virtual; abstract;
839 function FilterSmooth: TBGRACustomBitmap; virtual; abstract;
840 function FilterSharpen(Amount: single = 1): TBGRACustomBitmap; overload; virtual; abstract;
841 function FilterSharpen(ABounds: TRect; Amount: single = 1): TBGRACustomBitmap; overload; virtual; abstract;
842 function FilterContour: TBGRACustomBitmap; virtual; abstract;
843 function FilterPixelate(pixelSize: integer; useResample: boolean; filter: TResampleFilter = rfLinear): TBGRACustomBitmap; virtual; abstract;
844 function FilterBlurRadial(radius: single; blurType: TRadialBlurType): TBGRACustomBitmap; overload; virtual; abstract;
845 function FilterBlurRadial(ABounds: TRect; radius: single; blurType: TRadialBlurType): TBGRACustomBitmap; overload; virtual; abstract;
846 function FilterBlurRadial(radiusX, radiusY: single; blurType: TRadialBlurType): TBGRACustomBitmap; overload; virtual; abstract;
847 function FilterBlurRadial(ABounds: TRect; radiusX, radiusY: single; blurType: TRadialBlurType): TBGRACustomBitmap; overload; virtual; abstract;
848 function FilterBlurMotion(distance: single; angle: single; oriented: boolean): TBGRACustomBitmap; overload; virtual; abstract;
849 function FilterBlurMotion(ABounds: TRect; distance: single; angle: single; oriented: boolean): TBGRACustomBitmap; overload; virtual; abstract;
850 function FilterCustomBlur(mask: TBGRACustomBitmap): TBGRACustomBitmap; overload; virtual; abstract;
851 function FilterCustomBlur(ABounds: TRect; mask: TBGRACustomBitmap): TBGRACustomBitmap; overload; virtual; abstract;
852 function FilterEmboss(angle: single; AStrength: integer= 64; AOptions: TEmbossOptions = []): TBGRACustomBitmap; overload; virtual; abstract;
853 function FilterEmboss(angle: single; ABounds: TRect; AStrength: integer= 64; AOptions: TEmbossOptions = []): TBGRACustomBitmap; overload; virtual; abstract;
854 function FilterEmbossHighlight(FillSelection: boolean): TBGRACustomBitmap; overload; virtual; abstract;
855 function FilterEmbossHighlight(FillSelection: boolean; BorderColor: TBGRAPixel): TBGRACustomBitmap; overload; virtual; abstract;
856 function FilterEmbossHighlight(FillSelection: boolean; BorderColor: TBGRAPixel; var Offset: TPoint): TBGRACustomBitmap; overload; virtual; abstract;
857 function FilterGrayscale: TBGRACustomBitmap; overload; virtual; abstract;
858 function FilterGrayscale(ABounds: TRect): TBGRACustomBitmap; overload; virtual; abstract;
859 function FilterNormalize(eachChannel: boolean = True): TBGRACustomBitmap; overload; virtual; abstract;
860 function FilterNormalize(ABounds: TRect; eachChannel: boolean = True): TBGRACustomBitmap; overload; virtual; abstract;
861 function FilterRotate(origin: TPointF; angle: single; correctBlur: boolean = false): TBGRACustomBitmap; virtual; abstract;
862 function FilterAffine(AMatrix: TAffineMatrix; correctBlur: boolean = false): TBGRACustomBitmap; virtual; abstract;
863 function FilterSphere: TBGRACustomBitmap; virtual; abstract;
864 function FilterTwirl(ACenter: TPoint; ARadius: Single; ATurn: Single=1; AExponent: Single=3): TBGRACustomBitmap; overload; virtual; abstract;
865 function FilterTwirl(ABounds: TRect; ACenter: TPoint; ARadius: Single; ATurn: Single=1; AExponent: Single=3): TBGRACustomBitmap; overload; virtual; abstract;
866 function FilterCylinder: TBGRACustomBitmap; virtual; abstract;
867 function FilterPlane: TBGRACustomBitmap; virtual; abstract;
868
869 //IBGRAScanner
870 function ScanAtInteger(X,Y: integer): TBGRAPixel; virtual; abstract;
871 function ScanAtIntegerExpanded(X,Y: integer): TExpandedPixel; virtual;
872 procedure ScanMoveTo(X,Y: Integer); virtual; abstract;
873 function ScanNextPixel: TBGRAPixel; virtual; abstract;
874 function ScanNextExpandedPixel: TExpandedPixel; virtual;
875 function ScanAt(X,Y: Single): TBGRAPixel; virtual; abstract;
876 function ScanAtExpanded(X,Y: Single): TExpandedPixel; virtual;
877 procedure ScanPutPixels(pdest: PBGRAPixel; count: integer; mode: TDrawMode); virtual;
878 function IsScanPutPixelsDefined: boolean; virtual;
879 function ProvidesScanline(ARect: TRect): boolean; virtual;
880 function GetScanlineAt(X, Y: integer): PBGRAPixel; virtual;
881 protected
882 //interface
883 function QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} IID: TGUID; out Obj): HResult; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND};
884 function _AddRef: Integer; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND};
885 function _Release: Integer; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND};
886
887 end;
888
889type
890 TBGRABitmapAny = class of TBGRACustomBitmap; //used to create instances of the same type (see NewBitmap)
891
892var
893 BGRABitmapFactory : TBGRABitmapAny;
894{$ENDIF}
895
896{$IFDEF INCLUDE_IMPLEMENTATION}
897{$UNDEF INCLUDE_IMPLEMENTATION}
898function InternalGetImageBoundsWithin(ASourceBitmap: TBGRACustomBitmap; ASourceTexture: IBGRAScanner;
899 const ARect: TRect; Channels: TChannels; ANothingValue: Byte): TRect;
900var
901 minx, miny, maxx, maxy: integer;
902 xb, xb2, yb: integer;
903 p: PDWord;
904 colorMask, colorZeros: DWord;
905 actualRect: TRect;
906 pixelBuffer: TBGRAPixelBuffer;
907begin
908 pixelBuffer := nil;
909 if ASourceBitmap <> nil then
910 begin
911 actualRect := EmptyRect;
912 IntersectRect(actualRect,ARect,rect(0,0,ASourceBitmap.Width,ASourceBitmap.Height))
913 end
914 else if ASourceTexture <> nil then
915 begin
916 actualRect := ARect;
917 AllocateBGRAPixelBuffer(pixelBuffer, ARect.Right-ARect.Left)
918 end
919 else
920 begin
921 result := EmptyRect;
922 exit;
923 end;
924 maxx := actualRect.Left-1;
925 maxy := actualRect.Top-1;
926 minx := actualRect.Right;
927 miny := actualRect.Bottom;
928 colorMask := 0;
929 colorZeros := 0;
930 if cBlue in Channels then
931 begin
932 colorMask := colorMask or longword(BGRA(0,0,255,0));
933 colorZeros:= colorZeros or longword(BGRA(0,0,ANothingValue,0));
934 end;
935 if cGreen in Channels then
936 begin
937 colorMask := colorMask or longword(BGRA(0,255,0,0));
938 colorZeros:= colorZeros or longword(BGRA(0,ANothingValue,0,0));
939 end;
940 if cRed in Channels then
941 begin
942 colorMask := colorMask or longword(BGRA(255,0,0,0));
943 colorZeros:= colorZeros or longword(BGRA(ANothingValue,0,0,0));
944 end;
945 if cAlpha in Channels then
946 begin
947 colorMask := colorMask or longword(BGRA(0,0,0,255));
948 colorZeros:= colorZeros or longword(BGRA(0,0,0,ANothingValue));
949 end;
950 colorMask := NtoLE(colorMask);
951 colorZeros := NtoLE(colorZeros);
952 for yb := actualRect.Top to actualRect.Bottom-1 do
953 begin
954 if ASourceBitmap <> nil then
955 p := PDWord(ASourceBitmap.ScanLine[yb])+actualRect.Left
956 else
957 begin
958 p := @pixelBuffer[0];
959 ASourceTexture.ScanMoveTo(actualRect.Left,actualRect.Top);
960 ASourceTexture.ScanPutPixels(PBGRAPixel(p),ARect.Right-ARect.Left, dmSet);
961 end;
962 for xb := actualRect.Left to actualRect.Right - 1 do
963 begin
964 if (p^ and colorMask) <> colorZeros then
965 begin
966 if xb < minx then
967 minx := xb;
968 if yb < miny then
969 miny := yb;
970 if xb > maxx then
971 maxx := xb;
972 if yb > maxy then
973 maxy := yb;
974
975 inc(p, actualRect.Right-1-xb);
976 for xb2 := actualRect.Right-1 downto xb+1 do
977 begin
978 if (p^ and colorMask) <> colorZeros then
979 begin
980 if xb2 > maxx then
981 maxx := xb2;
982 break;
983 end;
984 dec(p);
985 end;
986 break;
987 end;
988 Inc(p);
989 end;
990 end;
991 if minx > maxx then
992 begin
993 Result.left := 0;
994 Result.top := 0;
995 Result.right := 0;
996 Result.bottom := 0;
997 end
998 else
999 begin
1000 Result.left := minx;
1001 Result.top := miny;
1002 Result.right := maxx + 1;
1003 Result.bottom := maxy + 1;
1004 end;
1005end;
1006
1007{ TBGRACustomScanner }
1008{ The abstract class record the position so that a derived class
1009 need only to redefine ScanAt }
1010
1011function TBGRACustomScanner.ScanAtInteger(X, Y: integer): TBGRAPixel;
1012begin
1013 result := ScanAt(X,Y);
1014end;
1015
1016function TBGRACustomScanner.ScanAtIntegerExpanded(X, Y: integer
1017 ): TExpandedPixel;
1018begin
1019 result := GammaExpansion(ScanAtInteger(X,Y));
1020end;
1021
1022procedure TBGRACustomScanner.ScanMoveTo(X, Y: Integer);
1023begin
1024 FCurX := X;
1025 FCurY := Y;
1026end;
1027
1028{ Call ScanAt to determine pixel value }
1029function TBGRACustomScanner.ScanNextPixel: TBGRAPixel;
1030begin
1031 result := ScanAt(FCurX,FCurY);
1032 Inc(FCurX);
1033end;
1034
1035function TBGRACustomScanner.ScanNextExpandedPixel: TExpandedPixel;
1036begin
1037 result := GammaExpansion(ScanNextPixel);
1038end;
1039
1040function TBGRACustomScanner.ScanAtExpanded(X, Y: Single): TExpandedPixel;
1041begin
1042 result := GammaExpansion(ScanAt(X,Y));
1043end;
1044
1045{$hints off}
1046procedure TBGRACustomScanner.ScanPutPixels(pdest: PBGRAPixel; count: integer;
1047 mode: TDrawMode);
1048begin
1049 //do nothing
1050end;
1051{$hints on}
1052
1053function TBGRACustomScanner.IsScanPutPixelsDefined: boolean;
1054begin
1055 result := false;
1056end;
1057
1058function TBGRACustomScanner.GetTextureGL: IUnknown;
1059begin
1060 result := nil;
1061end;
1062
1063function TBGRACustomScanner.GetImageBoundsWithin(const ARect: TRect;
1064 Channel: TChannel; ANothingValue: Byte): TRect;
1065begin
1066 result := InternalGetImageBoundsWithin(nil,self,ARect,[Channel],ANothingValue);
1067end;
1068
1069function TBGRACustomScanner.GetImageBoundsWithin(const ARect: TRect;
1070 Channels: TChannels; ANothingValue: Byte): TRect;
1071begin
1072 result := InternalGetImageBoundsWithin(nil,self,ARect,Channels,ANothingValue);
1073end;
1074
1075function TBGRACustomScanner.ProvidesScanline(ARect: TRect): boolean;
1076begin
1077 result := false;
1078end;
1079
1080function TBGRACustomScanner.GetScanlineAt(X, Y: integer): PBGRAPixel;
1081begin
1082 result := nil;
1083end;
1084
1085{ Interface gateway }
1086function TBGRACustomScanner.QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} IID: TGUID; out Obj): HResult; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND};
1087begin
1088 if GetInterface(iid, obj) then
1089 Result := S_OK
1090 else
1091 Result := longint(E_NOINTERFACE);
1092end;
1093
1094{ There is no automatic reference counting, but it is compulsory to define these functions }
1095function TBGRACustomScanner._AddRef: Integer; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND};
1096begin
1097 result := 0;
1098end;
1099
1100function TBGRACustomScanner._Release: Integer; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND};
1101begin
1102 result := 0;
1103end;
1104
1105{********************** End of TBGRACustomScanner **************************}
1106
1107{ TBGRACustomBitmap }
1108
1109function TBGRACustomBitmap.GetFontAntialias: Boolean;
1110begin
1111 result := FontQuality <> fqSystem;
1112end;
1113
1114procedure TBGRACustomBitmap.SetFontAntialias(const AValue: Boolean);
1115begin
1116 if AValue and not FontAntialias then
1117 FontQuality := fqFineAntialiasing
1118 else if not AValue and (FontQuality <> fqSystem) then
1119 FontQuality := fqSystem;
1120end;
1121
1122function TBGRACustomBitmap.GetTextureGL: IUnknown;
1123begin
1124 result := nil;
1125end;
1126
1127function TBGRACustomBitmap.GetFontRightToLeftFor(AText: string): boolean;
1128begin
1129 case FontBidiMode of
1130 fbmAuto: result := IsRightToLeftUTF8(AText);
1131 fbmRightToLeft: result := true;
1132 else
1133 {fbmLeftToRight}
1134 result := false;
1135 end;
1136end;
1137
1138procedure TBGRACustomBitmap.InternalArc(cx, cy, rx, ry: single;
1139 const StartPoint, EndPoint: TPointF; ABorderColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel; AOptions: TArcOptions;
1140 ADrawChord: boolean; ATexture: IBGRAScanner);
1141var angle1,angle2: single;
1142begin
1143 if (rx = 0) or (ry = 0) then exit;
1144 angle1 := arctan2(-(StartPoint.y-cy)/ry,(StartPoint.x-cx)/rx);
1145 angle2 := arctan2(-(EndPoint.y-cy)/ry,(EndPoint.x-cx)/rx);
1146 if angle1 = angle2 then angle2 := angle1+2*Pi;
1147 InternalArc(cx,cy,rx,ry, angle1,angle2,
1148 ABorderColor,w,AFillColor, AOptions, ADrawChord, ATexture);
1149end;
1150
1151procedure TBGRACustomBitmap.InternalArcInRect(r: TRect; StartAngleRad,
1152 EndAngleRad: Single; ABorderColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel; AOptions: TArcOptions;
1153 ADrawChord: boolean; ATexture: IBGRAScanner);
1154var
1155 temp: LongInt;
1156begin
1157 if r.right = r.left then exit;
1158 if r.bottom = r.top then exit;
1159 if r.right < r.left then
1160 begin
1161 temp := r.left;
1162 r.left := r.right;
1163 r.right := temp;
1164 end;
1165 if r.Bottom < r.Top then
1166 begin
1167 temp := r.Top;
1168 r.Top := r.Bottom;
1169 r.Bottom := temp;
1170 end;
1171 InternalArc((r.left+r.right-1)/2,(r.top+r.bottom-1)/2,
1172 (r.right-r.left-1)/2,(r.bottom-r.top-1)/2,
1173 StartAngleRad,EndAngleRad,
1174 ABorderColor,w,AFillColor,
1175 AOptions, ADrawChord, ATexture);
1176end;
1177
1178procedure TBGRACustomBitmap.InternalFillArcInRect(r: TRect; StartAngleRad,
1179 EndAngleRad: Single; AFillColor: TBGRAPixel; AOptions: TArcOptions;
1180 ATexture: IBGRAScanner);
1181var
1182 temp: LongInt;
1183begin
1184 if r.right = r.left then exit;
1185 if r.bottom = r.top then exit;
1186 if r.right < r.left then
1187 begin
1188 temp := r.left;
1189 r.left := r.right;
1190 r.right := temp;
1191 end;
1192 if r.Bottom < r.Top then
1193 begin
1194 temp := r.Top;
1195 r.Top := r.Bottom;
1196 r.Bottom := temp;
1197 end;
1198 InternalArc((r.left+r.right-1)/2,(r.top+r.bottom-1)/2,
1199 (r.right-r.left)/2,(r.bottom-r.top)/2,
1200 StartAngleRad,EndAngleRad,
1201 BGRAPixelTransparent,0,AFillColor,
1202 AOptions, False, ATexture);
1203end;
1204
1205{ These declaration make sure that these methods are virtual }
1206procedure TBGRACustomBitmap.LoadFromFile(const filename: string);
1207begin
1208 LoadFromFileUTF8(SysToUtf8(filename));
1209end;
1210
1211procedure TBGRACustomBitmap.LoadFromFile(const filename: string;
1212 AOptions: TBGRALoadingOptions);
1213begin
1214 LoadFromFileUTF8(SysToUtf8(filename), AOptions);
1215end;
1216
1217procedure TBGRACustomBitmap.LoadFromFile(const filename: String;
1218 Handler: TFPCustomImageReader);
1219begin
1220 LoadFromFileUTF8(SysToUtf8(filename),Handler);
1221end;
1222
1223procedure TBGRACustomBitmap.LoadFromFile(const filename: String;
1224 Handler: TFPCustomImageReader; AOptions: TBGRALoadingOptions);
1225begin
1226 LoadFromFileUTF8(SysToUtf8(filename),Handler,AOptions);
1227end;
1228
1229procedure TBGRACustomBitmap.LoadFromFileUTF8(const filenameUTF8: string; AOptions: TBGRALoadingOptions);
1230var
1231 Stream: TStream;
1232 format: TBGRAImageFormat;
1233 reader: TFPCustomImageReader;
1234begin
1235 stream := TFileStreamUTF8.Create(filenameUTF8,fmOpenRead or fmShareDenyWrite);
1236 try
1237 format := DetectFileFormat(Stream, ExtractFileExt(filenameUTF8));
1238 reader := CreateBGRAImageReader(format);
1239 try
1240 LoadFromStream(stream, reader, AOptions);
1241 finally
1242 reader.Free;
1243 end;
1244 finally
1245 stream.Free;
1246 end;
1247end;
1248
1249procedure TBGRACustomBitmap.LoadFromFileUTF8(const filenameUTF8: string;
1250 AHandler: TFPCustomImageReader; AOptions: TBGRALoadingOptions);
1251var
1252 Stream: TStream;
1253begin
1254 stream := TFileStreamUTF8.Create(filenameUTF8,fmOpenRead or fmShareDenyWrite);
1255 try
1256 LoadFromStream(stream, AHandler, AOptions);
1257 finally
1258 stream.Free;
1259 end;
1260end;
1261
1262procedure TBGRACustomBitmap.SaveToFile(const filename: string);
1263begin
1264 SaveToFileUTF8(SysToUtf8(filename));
1265end;
1266
1267procedure TBGRACustomBitmap.SaveToFileUTF8(const filenameUTF8: string);
1268var
1269 writer: TFPCustomImageWriter;
1270 format: TBGRAImageFormat;
1271begin
1272 format := SuggestImageFormat(filenameUTF8);
1273 if (format = ifXPixMap) and (Width*Height > 32768) then //xpm is slow so avoid big images
1274 raise exception.Create('Image is too big to be saved as XPM');
1275 writer := CreateBGRAImageWriter(Format, HasTransparentPixels);
1276 try
1277 SaveToFileUTF8(filenameUTF8, writer);
1278 finally
1279 writer.free;
1280 end;
1281end;
1282
1283procedure TBGRACustomBitmap.SaveToFile(const filename: string;
1284 Handler: TFPCustomImageWriter);
1285begin
1286 SaveToFileUTF8(SysToUtf8(filename),Handler);
1287end;
1288
1289procedure TBGRACustomBitmap.SaveToFileUTF8(const filenameUTF8: string;
1290 Handler: TFPCustomImageWriter);
1291var
1292 stream: TFileStreamUTF8;
1293begin
1294 stream := TFileStreamUTF8.Create(filenameUTF8,fmCreate);
1295 try
1296 SaveToStream(stream, Handler);
1297 finally
1298 stream.Free;
1299 end;
1300end;
1301
1302procedure TBGRACustomBitmap.SaveToStreamAsPng(Str: TStream);
1303var writer: TFPCustomImageWriter;
1304begin
1305 writer := CreateBGRAImageWriter(ifPNG, HasTransparentPixels);
1306 SaveToStream(Str,writer);
1307 writer.Free;
1308end;
1309
1310procedure TBGRACustomBitmap.SaveToStreamAs(Str: TStream;
1311 AFormat: TBGRAImageFormat);
1312var handler: TFPCustomImageWriter;
1313begin
1314 handler := CreateBGRAImageWriter(AFormat, HasTransparentPixels);
1315 try
1316 SaveToStream(Str, handler)
1317 finally
1318 handler.Free;
1319 end;
1320end;
1321
1322procedure TBGRACustomBitmap.DrawPixel(x, y: int32or64; c: TBGRAPixel;
1323 ADrawMode: TDrawMode);
1324begin
1325 case ADrawMode of
1326 dmSet: SetPixel(x,y,c);
1327 dmSetExceptTransparent: if c.alpha = 255 then SetPixel(x,y,c);
1328 dmLinearBlend: FastBlendPixel(x,y,c);
1329 dmDrawWithTransparency: DrawPixel(x,y,c);
1330 dmXor: XorPixel(x,y,c);
1331 end;
1332end;
1333
1334procedure TBGRACustomBitmap.LoadFromStream(Str: TStream);
1335begin
1336 LoadFromStream(Str, [loKeepTransparentRGB]);
1337end;
1338
1339procedure TBGRACustomBitmap.LoadFromStream(Str: TStream;
1340 AOptions: TBGRALoadingOptions);
1341var
1342 format: TBGRAImageFormat;
1343 reader: TFPCustomImageReader;
1344begin
1345 format := DetectFileFormat(Str);
1346 reader := CreateBGRAImageReader(format);
1347 try
1348 LoadFromStream(Str,reader,AOptions);
1349 finally
1350 reader.Free;
1351 end;
1352end;
1353
1354{ LoadFromStream uses TFPCustomImage routine, which uses
1355 Colors property to access pixels. That's why the
1356 FP drawing mode is temporarily changed to load
1357 bitmaps properly }
1358procedure TBGRACustomBitmap.LoadFromStream(Str: TStream;
1359 Handler: TFPCustomImageReader);
1360begin
1361 LoadFromStream(Str, Handler, [loKeepTransparentRGB]);
1362end;
1363
1364procedure TBGRACustomBitmap.LoadFromStream(Str: TStream;
1365 Handler: TFPCustomImageReader; AOptions: TBGRALoadingOptions);
1366var
1367 OldDrawMode: TDrawMode;
1368begin
1369 OldDrawMode := CanvasDrawModeFP;
1370 CanvasDrawModeFP := dmSet;
1371 try
1372 inherited LoadFromStream(Str, Handler);
1373 if not (loKeepTransparentRGB in AOptions) then
1374 ClearTransparentPixels;
1375 finally
1376 CanvasDrawModeFP := OldDrawMode;
1377 end;
1378end;
1379
1380procedure TBGRACustomBitmap.LoadFromResource(AFilename: string);
1381begin
1382 LoadFromResource(AFilename, [loKeepTransparentRGB]);
1383end;
1384
1385procedure TBGRACustomBitmap.LoadFromResource(AFilename: string;
1386 Handler: TFPCustomImageReader);
1387begin
1388 LoadFromResource(AFilename, Handler, [loKeepTransparentRGB]);
1389end;
1390
1391procedure TBGRACustomBitmap.LoadFromResource(AFilename: string;
1392 Handler: TFPCustomImageReader; AOptions: TBGRALoadingOptions);
1393var
1394 stream: TStream;
1395begin
1396 stream := BGRAResource.GetResourceStream(AFilename);
1397 try
1398 LoadFromStream(stream,Handler,AOptions);
1399 finally
1400 stream.Free;
1401 end;
1402end;
1403
1404{ Look for a pixel considering the bitmap is repeated in both directions }
1405function TBGRACustomBitmap.GetPixelCycle(x, y: int32or64): TBGRAPixel;
1406begin
1407 if (Width = 0) or (Height = 0) then
1408 Result := BGRAPixelTransparent
1409 else
1410 Result := (Scanline[PositiveMod(y,Height)] + PositiveMod(x,Width))^;
1411end;
1412
1413procedure TBGRACustomBitmap.DrawHorizLine(x, y, x2: int32or64;
1414 texture: IBGRAScanner);
1415begin
1416 HorizLine(x,y,x2,texture,dmDrawWithTransparency);
1417end;
1418
1419procedure TBGRACustomBitmap.HorizLine(x, y, x2: Int32or64; c: TBGRAPixel;
1420 ADrawMode: TDrawMode);
1421begin
1422 case ADrawMode of
1423 dmSet: SetHorizLine(x,y,x2,c);
1424 dmSetExceptTransparent: if c.alpha = 255 then SetHorizLine(x,y,x2,c);
1425 dmXor: XorHorizLine(x,y,x2,c);
1426 dmLinearBlend: FastBlendHorizLine(x,y,x2,c);
1427 dmDrawWithTransparency: DrawHorizLine(x,y,x2,c);
1428 end;
1429end;
1430
1431procedure TBGRACustomBitmap.VertLine(x, y, y2: Int32or64; c: TBGRAPixel;
1432 ADrawMode: TDrawMode);
1433begin
1434 case ADrawMode of
1435 dmSet: SetVertLine(x,y,y2,c);
1436 dmSetExceptTransparent: if c.alpha = 255 then SetVertLine(x,y,y2,c);
1437 dmXor: XorVertLine(x,y,y2,c);
1438 dmLinearBlend: FastBlendVertLine(x,y,y2,c);
1439 dmDrawWithTransparency: DrawVertLine(x,y,y2,c);
1440 end;
1441end;
1442
1443procedure TBGRACustomBitmap.DrawPolyLine(const points: array of TPoint;
1444 c: TBGRAPixel; DrawLastPixel: boolean; ADrawMode: TDrawMode);
1445var i,start: integer;
1446begin
1447 start := 0;
1448 for i := 0 to high(points) do
1449 if IsEmptyPoint(points[i]) then start := i+1 else
1450 begin
1451 if (i = high(points)) or IsEmptyPoint(points[i+1]) then
1452 begin
1453 if (i = start) and DrawLastPixel then DrawPixel(points[i].x,points[i].y,c,ADrawMode);
1454 end else
1455 DrawLine(points[i].x,points[i].Y,points[i+1].x,points[i+1].y, c,
1456 DrawLastPixel and ((i=high(points)-1) or IsEmptyPoint(points[i+2])), ADrawMode);
1457 end;
1458end;
1459
1460{ Pixel polylines are constructed by concatenation }
1461procedure TBGRACustomBitmap.DrawPolyLineAntialias(const points: array of TPoint;
1462 c: TBGRAPixel; DrawLastPixel: boolean);
1463var i,start: integer;
1464begin
1465 start := 0;
1466 for i := 0 to high(points) do
1467 if IsEmptyPoint(points[i]) then start := i+1 else
1468 begin
1469 if (i = high(points)) or IsEmptyPoint(points[i+1]) then
1470 begin
1471 if (i = start) and DrawLastPixel then DrawLineAntialias(points[i].x,points[i].y,points[i].x,points[i].y,c,true);
1472 end else
1473 DrawLineAntialias(points[i].x,points[i].Y,points[i+1].x,points[i+1].y, c,
1474 DrawLastPixel and ((i=high(points)-1) or IsEmptyPoint(points[i+2])));
1475 end;
1476end;
1477
1478procedure TBGRACustomBitmap.DrawPolyLineAntialias(const points: array of TPoint; c1,
1479 c2: TBGRAPixel; dashLen: integer; DrawLastPixel: boolean);
1480var i,start,dashPos: integer;
1481begin
1482 start := 0;
1483 dashPos := 0;
1484 for i := 0 to high(points) do
1485 if IsEmptyPoint(points[i]) then
1486 begin
1487 start := i+1;
1488 dashPos := 0;
1489 end else
1490 begin
1491 if (i = high(points)) or IsEmptyPoint(points[i+1]) then
1492 begin
1493 if (i = start) and DrawLastPixel then DrawPixel(points[i].x,points[i].y, c1);
1494 end else
1495 DrawLineAntialias(points[i].x,points[i].Y,points[i+1].x,points[i+1].y, c1,c2, dashLen,
1496 DrawLastPixel and ((i=high(points)-1) or IsEmptyPoint(points[i+2])), dashPos);
1497 end;
1498end;
1499
1500procedure TBGRACustomBitmap.DrawPolygon(const points: array of TPoint;
1501 c: TBGRAPixel; ADrawMode: TDrawMode);
1502var i,start: integer;
1503begin
1504 start := 0;
1505 for i := 0 to high(points) do
1506 if IsEmptyPoint(points[i]) then start := i+1 else
1507 begin
1508 if (i = high(points)) or IsEmptyPoint(points[i+1]) then
1509 begin
1510 if i = start then DrawPixel(points[i].x,points[i].y,c,ADrawMode)
1511 else if (i > start) then
1512 DrawLine(points[i].x,points[i].Y,points[start].x,points[start].y, c, false, ADrawMode);
1513 end else
1514 DrawLine(points[i].x,points[i].Y,points[i+1].x,points[i+1].y, c, false, ADrawMode);
1515 end;
1516end;
1517
1518procedure TBGRACustomBitmap.DrawPolygonAntialias(const points: array of TPoint;
1519 c: TBGRAPixel);
1520var i,start: integer;
1521begin
1522 start := 0;
1523 for i := 0 to high(points) do
1524 if IsEmptyPoint(points[i]) then start := i+1 else
1525 begin
1526 if (i = high(points)) or IsEmptyPoint(points[i+1]) then
1527 begin
1528 if i = start then DrawLineAntialias(points[i].x,points[i].y,points[i].x,points[i].y, c, true)
1529 else if (i > start) then
1530 DrawLineAntialias(points[i].x,points[i].Y,points[start].x,points[start].y, c, false);
1531 end else
1532 DrawLineAntialias(points[i].x,points[i].Y,points[i+1].x,points[i+1].y, c, false);
1533 end;
1534end;
1535
1536procedure TBGRACustomBitmap.DrawPolygonAntialias(const points: array of TPoint;
1537 c1, c2: TBGRAPixel; dashLen: integer);
1538var i,start,dashPos: integer;
1539begin
1540 start := 0;
1541 dashPos:= 0;
1542 for i := 0 to high(points) do
1543 if IsEmptyPoint(points[i]) then
1544 begin
1545 start := i+1;
1546 dashPos:= 0;
1547 end else
1548 begin
1549 if (i = high(points)) or IsEmptyPoint(points[i+1]) then
1550 begin
1551 if i = start then DrawLineAntialias(points[i].x,points[i].y,points[i].x,points[i].y, c1, true)
1552 else if (i > start) then
1553 DrawLineAntialias(points[i].x,points[i].Y,points[start].x,points[start].y, c1,c2,dashLen, false, dashPos);
1554 end else
1555 DrawLineAntialias(points[i].x,points[i].Y,points[i+1].x,points[i+1].y, c1,c2,dashLen, false, dashPos);
1556 end;
1557end;
1558
1559procedure TBGRACustomBitmap.ErasePolyLine(const points: array of TPoint; alpha: byte;
1560 DrawLastPixel: boolean);
1561var i,start: integer;
1562begin
1563 start := 0;
1564 for i := 0 to high(points) do
1565 if IsEmptyPoint(points[i]) then start := i+1 else
1566 begin
1567 if (i = high(points)) or IsEmptyPoint(points[i+1]) then
1568 begin
1569 if (i = start) and DrawLastPixel then ErasePixel(points[i].x,points[i].y,alpha);
1570 end else
1571 EraseLine(points[i].x,points[i].Y,points[i+1].x,points[i+1].y, alpha,
1572 DrawLastPixel and ((i=high(points)-1) or IsEmptyPoint(points[i+2])));
1573 end;
1574end;
1575
1576procedure TBGRACustomBitmap.ErasePolyLineAntialias(
1577 const points: array of TPoint; alpha: byte; DrawLastPixel: boolean);
1578var i,start: integer;
1579begin
1580 start := 0;
1581 for i := 0 to high(points) do
1582 if IsEmptyPoint(points[i]) then start := i+1 else
1583 begin
1584 if (i = high(points)) or IsEmptyPoint(points[i+1]) then
1585 begin
1586 if (i = start) and DrawLastPixel then ErasePixel(points[i].x,points[i].y, alpha);
1587 end else
1588 EraseLineAntialias(points[i].x,points[i].Y,points[i+1].x,points[i+1].y, alpha,
1589 DrawLastPixel and ((i=high(points)-1) or IsEmptyPoint(points[i+2])));
1590 end;
1591end;
1592
1593procedure TBGRACustomBitmap.ErasePolygonOutline(const points: array of TPoint;
1594 alpha: byte);
1595var i,start: integer;
1596begin
1597 start := 0;
1598 for i := 0 to high(points) do
1599 if IsEmptyPoint(points[i]) then start := i+1 else
1600 begin
1601 if (i = high(points)) or IsEmptyPoint(points[i+1]) then
1602 begin
1603 if i = start then ErasePixel(points[i].x,points[i].y, alpha)
1604 else if (i > start) then
1605 EraseLine(points[i].x,points[i].Y,points[start].x,points[start].y, alpha, false);
1606 end else
1607 EraseLine(points[i].x,points[i].Y,points[i+1].x,points[i+1].y, alpha, false);
1608 end;
1609end;
1610
1611procedure TBGRACustomBitmap.ErasePolygonOutlineAntialias(
1612 const points: array of TPoint; alpha: byte);
1613var i,start: integer;
1614begin
1615 start := 0;
1616 for i := 0 to high(points) do
1617 if IsEmptyPoint(points[i]) then start := i+1 else
1618 begin
1619 if (i = high(points)) or IsEmptyPoint(points[i+1]) then
1620 begin
1621 if i = start then ErasePixel(points[i].x,points[i].y, alpha)
1622 else if (i > start) then
1623 EraseLineAntialias(points[i].x,points[i].Y,points[start].x,points[start].y, alpha, false);
1624 end else
1625 EraseLineAntialias(points[i].x,points[i].Y,points[i+1].x,points[i+1].y, alpha, false);
1626 end;
1627end;
1628
1629procedure TBGRACustomBitmap.Arc(cx, cy, rx, ry: single; const StartPoint,
1630 EndPoint: TPointF; AColor: TBGRAPixel; w: single; ADrawChord: boolean;
1631 AFillColor: TBGRAPixel);
1632begin
1633 InternalArc(cx,cy,rx,ry,StartPoint,EndPoint,AColor,w,AFillColor,[aoFillPath],ADrawChord);
1634end;
1635
1636procedure TBGRACustomBitmap.Arc(cx, cy, rx, ry: single; StartAngleRad,
1637 EndAngleRad: Single; AColor: TBGRAPixel; w: single; ADrawChord: boolean;
1638 AFillColor: TBGRAPixel);
1639begin
1640 InternalArc(cx,cy,rx,ry,StartAngleRad,EndAngleRad,AColor,w,AFillColor,[aoFillPath],ADrawChord);
1641end;
1642
1643procedure TBGRACustomBitmap.FillChord(cx, cy, rx, ry: single; const StartPoint,
1644 EndPoint: TPointF; AFillColor: TBGRAPixel);
1645begin
1646 InternalArc(cx,cy,rx,ry,StartPoint,EndPoint,BGRAPixelTransparent,0,AFillColor,[aoFillPath]);
1647end;
1648
1649procedure TBGRACustomBitmap.FillChord(cx, cy, rx, ry: single; StartAngleRad,
1650 EndAngleRad: Single; AFillColor: TBGRAPixel);
1651begin
1652 InternalArc(cx,cy,rx,ry,StartAngleRad,EndAngleRad,BGRAPixelTransparent,0,AFillColor,[aoFillPath]);
1653end;
1654
1655procedure TBGRACustomBitmap.FillChord(cx, cy, rx, ry: single; const StartPoint,
1656 EndPoint: TPointF; texture: IBGRAScanner);
1657begin
1658 InternalArc(cx,cy,rx,ry,StartPoint,EndPoint,BGRAPixelTransparent,0,BGRAWhite,[aoFillPath],False,texture);
1659end;
1660
1661procedure TBGRACustomBitmap.FillChord(cx, cy, rx, ry: single; StartAngleRad,
1662 EndAngleRad: Single; texture: IBGRAScanner);
1663begin
1664 InternalArc(cx,cy,rx,ry,StartAngleRad,EndAngleRad,BGRAPixelTransparent,0,BGRAWhite,[aoFillPath],False,texture);
1665end;
1666
1667procedure TBGRACustomBitmap.FillChordInRect(const ARect: TRect; StartAngleRad,
1668 EndAngleRad: Single; AFillColor: TBGRAPixel);
1669begin
1670 InternalFillArcInRect(ARect,StartAngleRad,EndAngleRad,AFillColor,[aoFillPath]);
1671end;
1672
1673procedure TBGRACustomBitmap.FillChordInRect(const ARect: TRect; StartAngleRad,
1674 EndAngleRad: Single; texture: IBGRAScanner);
1675begin
1676 InternalFillArcInRect(ARect,StartAngleRad,EndAngleRad,BGRAWhite,[aoFillPath],texture);
1677end;
1678
1679procedure TBGRACustomBitmap.Pie(cx, cy, rx, ry: single; const StartPoint,
1680 EndPoint: TPointF; AColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel);
1681begin
1682 InternalArc(cx,cy,rx,ry,StartPoint,EndPoint,AColor,w,AFillColor,[aoFillPath,aoPie]);
1683end;
1684
1685procedure TBGRACustomBitmap.Pie(cx, cy, rx, ry: single; StartAngleRad,
1686 EndAngleRad: Single; AColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel);
1687begin
1688 InternalArc(cx,cy,rx,ry,StartAngleRad,EndAngleRad,AColor,w,AFillColor,[aoFillPath,aoPie]);
1689end;
1690
1691procedure TBGRACustomBitmap.FillPie(cx, cy, rx, ry: single; const StartPoint,
1692 EndPoint: TPointF; AFillColor: TBGRAPixel);
1693begin
1694 InternalArc(cx,cy,rx,ry,StartPoint,EndPoint,BGRAPixelTransparent,0,AFillColor,[aoFillPath,aoPie]);
1695end;
1696
1697procedure TBGRACustomBitmap.FillPie(cx, cy, rx, ry: single; StartAngleRad,
1698 EndAngleRad: Single; AFillColor: TBGRAPixel);
1699begin
1700 InternalArc(cx,cy,rx,ry,StartAngleRad,EndAngleRad,BGRAPixelTransparent,0,AFillColor,[aoFillPath,aoPie]);
1701end;
1702
1703procedure TBGRACustomBitmap.FillPie(cx, cy, rx, ry: single; const StartPoint,
1704 EndPoint: TPointF; texture: IBGRAScanner);
1705begin
1706 InternalArc(cx,cy,rx,ry,StartPoint,EndPoint,BGRAPixelTransparent,0,BGRAWhite,[aoFillPath,aoPie],False,texture);
1707end;
1708
1709procedure TBGRACustomBitmap.FillPie(cx, cy, rx, ry: single; StartAngleRad,
1710 EndAngleRad: Single; texture: IBGRAScanner);
1711begin
1712 InternalArc(cx,cy,rx,ry,StartAngleRad,EndAngleRad,BGRAPixelTransparent,0,BGRAWhite,[aoFillPath,aoPie],False,texture);
1713end;
1714
1715procedure TBGRACustomBitmap.FillPieInRect(const ARect: TRect; StartAngleRad,
1716 EndAngleRad: Single; AFillColor: TBGRAPixel);
1717begin
1718 InternalFillArcInRect(ARect,StartAngleRad,EndAngleRad,AFillColor,[aoFillPath,aoPie]);
1719end;
1720
1721procedure TBGRACustomBitmap.FillPieInRect(const ARect: TRect; StartAngleRad,
1722 EndAngleRad: Single; texture: IBGRAScanner);
1723begin
1724 InternalFillArcInRect(ARect,StartAngleRad,EndAngleRad,BGRAWhite,[aoFillPath,aoPie],texture);
1725end;
1726
1727{ Following functions are defined for convenience }
1728procedure TBGRACustomBitmap.Rectangle(x, y, x2, y2: integer; c: TColor);
1729begin
1730 Rectangle(x, y, x2, y2, ColorToBGRA(c), dmSet);
1731end;
1732
1733procedure TBGRACustomBitmap.Rectangle(r: TRect; c: TBGRAPixel; mode: TDrawMode
1734 );
1735begin
1736 Rectangle(r.left, r.top, r.right, r.bottom, c, mode);
1737end;
1738
1739procedure TBGRACustomBitmap.Rectangle(r: TRect; BorderColor,
1740 FillColor: TBGRAPixel; mode: TDrawMode);
1741begin
1742 Rectangle(r.left, r.top, r.right, r.bottom, BorderColor, FillColor, mode);
1743end;
1744
1745procedure TBGRACustomBitmap.Rectangle(r: TRect; c: TColor);
1746begin
1747 Rectangle(r.left, r.top, r.right, r.bottom, c);
1748end;
1749
1750procedure TBGRACustomBitmap.RectangleAntialias(x, y, x2, y2: single;
1751 c: TBGRAPixel; w: single);
1752begin
1753 RectangleAntialias(x, y, x2, y2, c, w, BGRAPixelTransparent);
1754end;
1755
1756procedure TBGRACustomBitmap.RectangleWithin(x1, y1, x2, y2: single;
1757 ABorderColor: TBGRAPixel; w: single; AFillColor: TBGRAPixel;
1758 APixelCenteredCoordinates: boolean);
1759begin
1760 if not APixelCenteredCoordinates then
1761 begin
1762 x1 -= 0.5;
1763 y1 -= 0.5;
1764 x2 -= 0.5;
1765 y2 -= 0.5;
1766 end;
1767 RectangleAntialias(x1+w*0.5,y1+w*0.5,x2-w*0.5,y2-w*0.5, ABorderColor, w, AFillColor);
1768end;
1769
1770procedure TBGRACustomBitmap.RectangleWithin(r: TRect; ABorderColor: TBGRAPixel;
1771 w: single; AFillColor: TBGRAPixel);
1772begin
1773 RectangleWithin(r.left,r.top,r.right,r.bottom,ABorderColor,w,AFillColor,false);
1774end;
1775
1776procedure TBGRACustomBitmap.FillRoundRect(X1, Y1, X2, Y2: integer; DX,
1777 DY: integer; FillColor: TBGRAPixel; ADrawMode: TDrawMode);
1778begin
1779 RoundRect(X1,Y1,X2,Y2,DX,DY,FillColor,FillColor,ADrawMode);
1780end;
1781
1782procedure TBGRACustomBitmap.EllipseInRect(r: TRect; BorderColor: TBGRAPixel;
1783 ADrawMode: TDrawMode);
1784begin
1785 RoundRect(r.left,r.top,r.right,r.bottom,abs(r.right-r.left),abs(r.bottom-r.top),BorderColor,ADrawMode);
1786end;
1787
1788procedure TBGRACustomBitmap.EllipseInRect(r: TRect; BorderColor,
1789 FillColor: TBGRAPixel; ADrawMode: TDrawMode);
1790begin
1791 RoundRect(r.left,r.top,r.right,r.bottom,abs(r.right-r.left),abs(r.bottom-r.top),BorderColor,FillColor,ADrawMode);
1792end;
1793
1794procedure TBGRACustomBitmap.FillEllipseInRect(r: TRect; FillColor: TBGRAPixel;
1795 ADrawMode: TDrawMode);
1796begin
1797 FillRoundRect(r.left,r.top,r.right,r.bottom,abs(r.right-r.left),abs(r.bottom-r.top),FillColor,ADrawMode);
1798end;
1799
1800procedure TBGRACustomBitmap.FillEllipseInRect(r: TRect;
1801 FillTexture: IBGRAScanner; ADrawMode: TDrawMode);
1802begin
1803 FillRoundRect(r.left,r.top,r.right,r.bottom,abs(r.right-r.left),abs(r.bottom-r.top),FillTexture,ADrawMode);
1804end;
1805
1806procedure TBGRACustomBitmap.FillRect(r: TRect; c: TColor);
1807begin
1808 FillRect(r.Left, r.top, r.right, r.bottom, c);
1809end;
1810
1811procedure TBGRACustomBitmap.FillRect(r: TRect; c: TBGRAPixel; mode: TDrawMode);
1812begin
1813 FillRect(r.Left, r.top, r.right, r.bottom, c, mode);
1814end;
1815
1816procedure TBGRACustomBitmap.FillRect(r: TRect; texture: IBGRAScanner;
1817 mode: TDrawMode);
1818begin
1819 FillRect(r.Left, r.top, r.right, r.bottom, texture, mode);
1820end;
1821
1822procedure TBGRACustomBitmap.FillRect(r: TRect; texture: IBGRAScanner;
1823 mode: TDrawMode; AScanOffset: TPoint);
1824begin
1825 FillRect(r.Left,r.Top,r.Right,r.Bottom, texture, mode, AScanOffset);
1826end;
1827
1828procedure TBGRACustomBitmap.FillRect(r: TRect; texture: IBGRAScanner;
1829 mode: TDrawMode; ditheringAlgorithm: TDitheringAlgorithm);
1830begin
1831 FillRect(r.Left,r.Top,r.Right,r.Bottom, texture, mode, ditheringAlgorithm);
1832end;
1833
1834procedure TBGRACustomBitmap.FillRect(r: TRect; texture: IBGRAScanner;
1835 mode: TDrawMode; AScanOffset: TPoint; ditheringAlgorithm: TDitheringAlgorithm);
1836begin
1837 FillRect(r.Left,r.Top,r.Right,r.Bottom, texture, mode, AScanOffset, ditheringAlgorithm);
1838end;
1839
1840procedure TBGRACustomBitmap.FillRect(x, y, x2, y2: integer; c: TColor);
1841begin
1842 FillRect(x, y, x2, y2, ColorToBGRA(c), dmSet);
1843end;
1844
1845procedure TBGRACustomBitmap.FillRect(x, y, x2, y2: integer;
1846 texture: IBGRAScanner; mode: TDrawMode);
1847begin
1848 FillRect(x,y,x2,y2,texture,mode,Point(0,0));
1849end;
1850
1851procedure TBGRACustomBitmap.FillRect(x, y, x2, y2: integer;
1852 texture: IBGRAScanner; mode: TDrawMode;
1853 ditheringAlgorithm: TDitheringAlgorithm);
1854begin
1855 FillRect(x,y,x2,y2,texture,mode,Point(0,0),ditheringAlgorithm);
1856end;
1857
1858procedure TBGRACustomBitmap.FillRectAntialias(ARect: TRectF; c: TBGRAPixel;
1859 pixelCenteredCoordinates: boolean);
1860begin
1861 FillRectAntialias(ARect.Left,ARect.Top,ARect.Right,ARect.Bottom, c, pixelCenteredCoordinates);
1862end;
1863
1864procedure TBGRACustomBitmap.FillRectAntialias(ARect: TRectF;
1865 texture: IBGRAScanner; pixelCenteredCoordinates: boolean);
1866begin
1867 FillRectAntialias(ARect.Left,ARect.Top,ARect.Right,ARect.Bottom, texture, pixelCenteredCoordinates);
1868end;
1869
1870procedure TBGRACustomBitmap.TextOutCurved(APath: IBGRAPath; sUTF8: string;
1871 AColor: TBGRAPixel; AAlign: TAlignment; ALetterSpacing: single);
1872var cursor: TBGRACustomPathCursor;
1873begin
1874 cursor := APath.getCursor;
1875 if cursor = nil then exit;
1876 case AAlign of
1877 taCenter: cursor.Position := cursor.PathLength*0.5;
1878 taRightJustify: cursor.Position:= cursor.PathLength;
1879 end;
1880 TextOutCurved(cursor, sUTF8, AColor, AAlign, ALetterSpacing);
1881 cursor.free;
1882end;
1883
1884procedure TBGRACustomBitmap.TextOutCurved(APath: IBGRAPath; sUTF8: string;
1885 ATexture: IBGRAScanner; AAlign: TAlignment; ALetterSpacing: single);
1886var cursor: TBGRACustomPathCursor;
1887begin
1888 cursor := APath.getCursor;
1889 if cursor = nil then exit;
1890 case AAlign of
1891 taCenter: cursor.Position := cursor.PathLength*0.5;
1892 taRightJustify: cursor.Position:= cursor.PathLength;
1893 end;
1894 TextOutCurved(cursor, sUTF8, ATexture, AAlign, ALetterSpacing);
1895 cursor.free;
1896end;
1897
1898procedure TBGRACustomBitmap.TextMultiline(x, y: single; sUTF8: string;
1899 c: TBGRAPixel; AAlign: TBidiTextAlignment; AVertAlign: TTextLayout; AParagraphSpacing: single);
1900begin
1901 TextMultiline(x, y, EmptySingle, sUTF8, c, AAlign, AVertAlign, AParagraphSpacing);
1902end;
1903
1904procedure TBGRACustomBitmap.TextMultiline(x, y: single; sUTF8: string;
1905 ATexture: IBGRAScanner; AAlign: TBidiTextAlignment; AVertAlign: TTextLayout; AParagraphSpacing: single);
1906begin
1907 TextMultiline(x, y, EmptySingle, sUTF8, ATexture, AAlign, AVertAlign, AParagraphSpacing);
1908end;
1909
1910procedure TBGRACustomBitmap.TextOut(x, y: single; sUTF8: string; c: TBGRAPixel;
1911 align: TAlignment);
1912begin
1913 TextOut(x,y,sUTF8,c,align, GetFontRightToLeftFor(sUTF8));
1914end;
1915
1916procedure TBGRACustomBitmap.TextOut(x, y: single; sUTF8: string;
1917 texture: IBGRAScanner; align: TAlignment);
1918begin
1919 TextOut(x,y,sUTF8,texture,align, GetFontRightToLeftFor(sUTF8));
1920end;
1921
1922{ Draw the UTF8 encoded string, (x,y) being the top-left corner. The color c is used to fill the text.
1923 The value of FontOrientation is taken into account, so that the text may be rotated. }
1924procedure TBGRACustomBitmap.TextOut(x, y: single; sUTF8: string; c: TBGRAPixel);
1925begin
1926 TextOut(x, y, sUTF8, c, taLeftJustify);
1927end;
1928
1929procedure TBGRACustomBitmap.TextOut(x, y: single; sUTF8: string; c: TBGRAPixel;
1930 ARightToLeft: boolean);
1931begin
1932 TextOut(x, y, sUTF8, c, taLeftJustify, ARightToLeft);
1933end;
1934
1935{ Draw the UTF8 encoded string, (x,y) being the top-left corner. The color c is used to fill the text.
1936 The value of FontOrientation is taken into account, so that the text may be rotated. }
1937procedure TBGRACustomBitmap.TextOut(x, y: single; sUTF8: string; c: TColor);
1938begin
1939 TextOut(x, y, sUTF8, ColorToBGRA(c));
1940end;
1941
1942procedure TBGRACustomBitmap.TextOut(x, y: single; sUTF8: string; c: TColor;
1943 ARightToLeft: boolean);
1944begin
1945 TextOut(x, y, sUTF8, ColorToBGRA(c), ARightToLeft);
1946end;
1947
1948{ Draw the UTF8 encoded string, (x,y) being the top-left corner. The texture is used to fill the text.
1949 The value of FontOrientation is taken into account, so that the text may be rotated. }
1950procedure TBGRACustomBitmap.TextOut(x, y: single; sUTF8: string;
1951 texture: IBGRAScanner);
1952begin
1953 TextOut(x, y, sUTF8, texture, taLeftJustify);
1954end;
1955
1956procedure TBGRACustomBitmap.TextOut(x, y: single; sUTF8: string;
1957 texture: IBGRAScanner; ARightToLeft: boolean);
1958begin
1959 TextOut(x, y, sUTF8, texture, taLeftJustify, ARightToLeft);
1960end;
1961
1962{ Draw the UTF8 encoded string in the rectangle ARect. Text is wrapped if necessary.
1963 The position depends on the specified horizontal alignment halign and vertical alignement valign.
1964 The color c is used to fill the text. No rotation is applied. }
1965procedure TBGRACustomBitmap.TextRect(ARect: TRect; sUTF8: string;
1966 halign: TAlignment; valign: TTextLayout; c: TBGRAPixel);
1967var
1968 style: TTextStyle;
1969begin
1970 {$hints off}
1971 FillChar(style,sizeof(style),0);
1972 {$hints on}
1973 style.Alignment := halign;
1974 style.Layout := valign;
1975 style.Wordbreak := true;
1976 style.ShowPrefix := false;
1977 style.Clipping := false;
1978 style.RightToLeft := GetFontRightToLeftFor(sUTF8);
1979 if FontBidiMode = fbmAuto then sUTF8 := AddParagraphBidiUTF8(sUTF8, style.RightToLeft);
1980 TextRect(ARect,ARect.Left,ARect.Top,sUTF8,style,c);
1981end;
1982
1983{ Draw the UTF8 encoded string in the rectangle ARect. Text is wrapped if necessary.
1984 The position depends on the specified horizontal alignment halign and vertical alignement valign.
1985 The texture is used to fill the text. No rotation is applied. }
1986procedure TBGRACustomBitmap.TextRect(ARect: TRect; sUTF8: string;
1987 halign: TAlignment; valign: TTextLayout; texture: IBGRAScanner);
1988var
1989 style: TTextStyle;
1990begin
1991 {$hints off}
1992 FillChar(style,sizeof(style),0);
1993 {$hints on}
1994 style.Alignment := halign;
1995 style.Layout := valign;
1996 style.Wordbreak := true;
1997 style.ShowPrefix := false;
1998 style.Clipping := false;
1999 style.RightToLeft := GetFontRightToLeftFor(sUTF8);
2000 if FontBidiMode = fbmAuto then sUTF8 := AddParagraphBidiUTF8(sUTF8, style.RightToLeft);
2001 TextRect(ARect,ARect.Left,ARect.Top,sUTF8,style,texture);
2002end;
2003
2004function TBGRACustomBitmap.ComputeEllipse(x, y, rx, ry: single): ArrayOfTPointF;
2005begin
2006 result := ComputeEllipseContour(x,y,rx,ry);
2007end;
2008
2009function TBGRACustomBitmap.ComputeEllipse(x, y, rx, ry, w: single
2010 ): ArrayOfTPointF;
2011begin
2012 result := ComputeEllipseBorder(x,y,rx,ry,w);
2013end;
2014
2015procedure TBGRACustomBitmap.FillTransparent;
2016begin
2017 Fill(BGRAPixelTransparent);
2018end;
2019
2020procedure TBGRACustomBitmap.Fill(c: TColor);
2021var bgraColor: TBGRAPixel;
2022begin
2023 bgraColor := ColorToBGRA(c);
2024 Fill(bgraColor);
2025end;
2026
2027procedure TBGRACustomBitmap.Fill(c: TBGRAPixel);
2028begin
2029 Fill(c, 0, NbPixels);
2030end;
2031
2032procedure TBGRACustomBitmap.AlphaFill(alpha: byte);
2033begin
2034 AlphaFill(alpha, 0, NbPixels);
2035end;
2036
2037procedure TBGRACustomBitmap.FillMask(x, y: integer; AMask: TBGRACustomBitmap;
2038 color: TBGRAPixel);
2039begin
2040 FillMask(x,y, AMask, color, dmDrawWithTransparency);
2041end;
2042
2043procedure TBGRACustomBitmap.FillMask(x, y: integer; AMask: TBGRACustomBitmap;
2044 texture: IBGRAScanner);
2045begin
2046 FillMask(x,y, AMask, texture, dmDrawWithTransparency);
2047end;
2048
2049procedure TBGRACustomBitmap.FloodFill(X, Y: integer; Color: TBGRAPixel;
2050 mode: TFloodfillMode; Tolerance: byte);
2051begin
2052 ParallelFloodFill(X,Y,Self,Color,mode,Tolerance);
2053end;
2054
2055procedure TBGRACustomBitmap.DrawPart(ARect: TRect; ACanvas: TCanvas; x,
2056 y: integer; Opaque: boolean);
2057var
2058 partial: TBGRACustomBitmap;
2059begin
2060 if (ARect.Left = 0) and (ARect.Top = 0) and (ARect.Right = Width) and (ARect.Bottom = Height) then
2061 Draw(ACanvas, x,y, Opaque)
2062 else
2063 begin
2064 partial := GetPart(ARect);
2065 if partial <> nil then
2066 begin
2067 partial.Draw(ACanvas, x, y, Opaque);
2068 partial.Free;
2069 end;
2070 end;
2071end;
2072
2073procedure TBGRACustomBitmap.PutImage(x, y: integer; Source: TBitmap;
2074 mode: TDrawMode; AOpacity: byte);
2075var bgra: TBGRACustomBitmap;
2076begin
2077 bgra := BGRABitmapFactory.create(Source);
2078 PutImage(x,y, bgra, mode, AOpacity);
2079 bgra.free;
2080end;
2081
2082procedure TBGRACustomBitmap.StretchPutImageProportionally(ARect: TRect;
2083 AHorizAlign: TAlignment; AVertAlign: TTextLayout; Source: TBGRACustomBitmap;
2084 mode: TDrawMode; AOpacity: byte);
2085var
2086 ratio: single;
2087 imgRect: TRect;
2088begin
2089 if (Source.Width = 0) or (Source.Height = 0) then exit;
2090 if (ARect.Width <= 0) or (ARect.Height <= 0) then exit;
2091
2092 ratio := min(ARect.Width/Source.Width, ARect.Height/Source.Height);
2093 imgRect := RectWithSize(ARect.Left,ARect.Top, round(Source.Width*ratio), round(Source.Height*ratio));
2094 case AHorizAlign of
2095 taCenter: OffsetRect(imgRect, (ARect.Width-imgRect.Width) div 2, 0);
2096 taRightJustify: OffsetRect(imgRect, ARect.Width-imgRect.Width, 0);
2097 end;
2098 case AVertAlign of
2099 tlCenter: OffsetRect(imgRect, 0,(ARect.Height-imgRect.Height) div 2);
2100 tlBottom: OffsetRect(imgRect, 0,ARect.Height-imgRect.Height);
2101 end;
2102 StretchPutImage(imgRect, Source, mode, AOpacity);
2103end;
2104
2105procedure TBGRACustomBitmap.PutImageSubpixel(x, y: single; Source: TBGRACustomBitmap; AOpacity: byte);
2106begin
2107 PutImageAngle(x,y,source,0,0,0,AOpacity);
2108end;
2109
2110procedure TBGRACustomBitmap.PutImagePart(x, y: integer;
2111 Source: TBGRACustomBitmap; SourceRect: TRect; mode: TDrawMode; AOpacity: byte);
2112var w,h,sourcex,sourcey,nx,ny,xb,yb,destx,desty: integer;
2113 oldClip,newClip: TRect;
2114begin
2115 if (Source = nil) or (AOpacity = 0) then exit;
2116 w := SourceRect.Right-SourceRect.Left;
2117 h := SourceRect.Bottom-SourceRect.Top;
2118 if (w <= 0) or (h <= 0) or (Source.Width = 0) or (Source.Height = 0) then exit;
2119 sourcex := PositiveMod(SourceRect.Left, Source.Width);
2120 sourcey := PositiveMod(SourceRect.Top, Source.Height);
2121 nx := (sourceX+w + Source.Width-1) div Source.Width;
2122 ny := (sourceY+h + Source.Height-1) div Source.Height;
2123
2124 oldClip := ClipRect;
2125 newClip := rect(x,y,x+w,y+h);
2126 if not IntersectRect(newClip,newClip,oldClip) then exit;
2127
2128 ClipRect := newClip;
2129
2130 desty := y-sourcey;
2131 for yb := 0 to ny-1 do
2132 begin
2133 destx := x-sourcex;
2134 for xb := 0 to nx-1 do
2135 begin
2136 self.PutImage(destx,desty,Source,mode,AOpacity);
2137 inc(destx,Source.Width);
2138 end;
2139 inc(desty,Source.Height);
2140 end;
2141
2142 ClipRect := oldClip;
2143end;
2144
2145procedure TBGRACustomBitmap.PutImageAffine(Origin, HAxis, VAxis: TPointF;
2146 Source: TBGRACustomBitmap; AOpacity: Byte; ACorrectBlur: Boolean);
2147begin
2148 if ACorrectBlur then
2149 PutImageAffine(Origin,HAxis,VAxis,Source,rfCosine,AOpacity)
2150 else
2151 PutImageAffine(Origin,HAxis,VAxis,Source,rfLinear,AOpacity);
2152end;
2153
2154procedure TBGRACustomBitmap.PutImageAffine(Origin, HAxis, VAxis: TPointF;
2155 Source: TBGRACustomBitmap; AResampleFilter: TResampleFilter; AOpacity: Byte);
2156begin
2157 if (Source = nil) or (Source.Width = 0) or (Source.Height = 0) or (AOpacity = 0) then exit;
2158 PutImageAffine(Origin,HAxis,VAxis,Source,GetImageAffineBounds(Origin,HAxis,VAxis,Source),AResampleFilter,dmDrawWithTransparency,AOpacity);
2159end;
2160
2161procedure TBGRACustomBitmap.PutImageAffine(Origin, HAxis, VAxis: TPointF;
2162 Source: TBGRACustomBitmap; AOutputBounds: TRect;
2163 AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte);
2164var m: TAffineMatrix; w,h: integer;
2165begin
2166 if (Source = nil) or (Source.Width = 0) or (Source.Height = 0) or (AOpacity = 0) then exit;
2167 if Source.Width < 2 then w := 2 else w := Source.Width; //avoid actual size of zero
2168 if Source.Height < 2 then h := 2 else h := Source.Height;
2169 m[1,1] := (HAxis.x-Origin.x)/(w-1); m[1,2] := (VAxis.x-Origin.x)/(h-1); m[1,3] := Origin.x;
2170 m[2,1] := (HAxis.y-Origin.y)/(w-1); m[2,2] := (VAxis.y-Origin.y)/(h-1); m[2,3] := Origin.y;
2171 PutImageAffine(m,Source,AOutputBounds,AResampleFilter,AMode,AOpacity);
2172end;
2173
2174procedure TBGRACustomBitmap.PutImageAffine(Origin, HAxis, VAxis: TPointF;
2175 Source: TBGRACustomBitmap; AOutputBounds: TRect; AOpacity: Byte;
2176 ACorrectBlur: Boolean);
2177begin
2178 if ACorrectBlur then
2179 PutImageAffine(Origin,HAxis,VAxis,Source,AOutputBounds,rfCosine,dmDrawWithTransparency,AOpacity)
2180 else
2181 PutImageAffine(Origin,HAxis,VAxis,Source,AOutputBounds,rfLinear,dmDrawWithTransparency,AOpacity);
2182end;
2183
2184procedure TBGRACustomBitmap.PutImageAffine(AMatrix: TAffineMatrix;
2185 Source: TBGRACustomBitmap; AOpacity: Byte; ACorrectBlur: Boolean);
2186begin
2187 if ACorrectBlur then
2188 PutImageAffine(AMatrix,Source,rfCosine,AOpacity)
2189 else
2190 PutImageAffine(AMatrix,Source,rfLinear,AOpacity);
2191end;
2192
2193procedure TBGRACustomBitmap.PutImageAffine(AMatrix: TAffineMatrix;
2194 Source: TBGRACustomBitmap; AResampleFilter: TResampleFilter; AOpacity: Byte);
2195begin
2196 PutImageAffine(AMatrix, Source, AResampleFilter, dmDrawWithTransparency, AOpacity);
2197end;
2198
2199procedure TBGRACustomBitmap.PutImageAffine(AMatrix: TAffineMatrix;
2200 Source: TBGRACustomBitmap; AResampleFilter: TResampleFilter;
2201 AMode: TDrawMode; AOpacity: Byte);
2202begin
2203 if (Source = nil) or (Source.Width = 0) or (Source.Height = 0) or (AOpacity = 0) then exit;
2204 PutImageAffine(AMatrix, Source, GetImageAffineBounds(AMatrix,Source),
2205 AResampleFilter,AMode,AOpacity);
2206end;
2207
2208procedure TBGRACustomBitmap.PutImageAffine(AMatrix: TAffineMatrix;
2209 Source: TBGRACustomBitmap; AOutputBounds: TRect; AOpacity: Byte;
2210 ACorrectBlur: Boolean);
2211begin
2212 if ACorrectBlur then
2213 PutImageAffine(AMatrix,Source,AOutputBounds,rfCosine,dmDrawWithTransparency,AOpacity)
2214 else
2215 PutImageAffine(AMatrix,Source,AOutputBounds,rfLinear,dmDrawWithTransparency,AOpacity);
2216end;
2217
2218{ Returns the area that contains the affine transformed image }
2219function TBGRACustomBitmap.GetImageAffineBounds(Origin, HAxis, VAxis: TPointF;
2220 Source: TBGRACustomBitmap): TRect;
2221begin
2222 if Source = nil then
2223 result := EmptyRect
2224 else
2225 result := GetImageAffineBounds(Origin,HAxis,VAxis,Source.Width,Source.Height,Source.GetImageBounds);
2226end;
2227
2228function TBGRACustomBitmap.GetImageAffineBounds(Origin, HAxis, VAxis: TPointF;
2229 ASourceWidth, ASourceHeight: integer; const ASourceBounds: TRect; AClipOutput: boolean): TRect;
2230var m: TAffineMatrix;
2231begin
2232 if (ASourceWidth = 0) or (ASourceHeight = 0) then
2233 result := EmptyRect
2234 else
2235 begin
2236 if ASourceWidth < 2 then ASourceWidth := 2; //avoid division by zero by supposing a pixel size of 2
2237 if ASourceHeight < 2 then ASourceHeight := 2; //i.e. an actual size of 1 (cf pixel centered coordinates)
2238 m[1,1] := (HAxis.x-Origin.x)/(ASourceWidth-1); m[1,2] := (VAxis.x-Origin.x)/(ASourceHeight-1); m[1,3] := Origin.x;
2239 m[2,1] := (HAxis.y-Origin.y)/(ASourceWidth-1); m[2,2] := (VAxis.y-Origin.y)/(ASourceHeight-1); m[2,3] := Origin.y;
2240 result := GetImageAffineBounds(m, ASourceBounds, AClipOutput);
2241 end;
2242end;
2243
2244function TBGRACustomBitmap.GetImageAffineBounds(AMatrix: TAffineMatrix;
2245 Source: TBGRACustomBitmap): TRect;
2246begin
2247 result := GetImageAffineBounds(AMatrix, Source.GetImageBounds);
2248end;
2249
2250procedure TBGRACustomBitmap.PutImageAngle(x, y: single;
2251 Source: TBGRACustomBitmap; angle: single; AOutputBounds: TRect;
2252 imageCenterX: single; imageCenterY: single; AOpacity: Byte;
2253 ARestoreOffsetAfterRotation: boolean; ACorrectBlur: Boolean);
2254begin
2255 if ACorrectBlur then
2256 PutImageAngle(x,y,Source,angle,AOutputBounds,rfCosine,imageCenterX,imageCenterY,AOpacity,ARestoreOffsetAfterRotation)
2257 else
2258 PutImageAngle(x,y,Source,angle,AOutputBounds,rfLinear,imageCenterX,imageCenterY,AOpacity,ARestoreOffsetAfterRotation);
2259end;
2260
2261procedure TBGRACustomBitmap.PutImageAngle(x, y: single;
2262 Source: TBGRACustomBitmap; angle: single; imageCenterX: single;
2263 imageCenterY: single; AOpacity: Byte; ARestoreOffsetAfterRotation: boolean; ACorrectBlur: Boolean);
2264begin
2265 if ACorrectBlur then
2266 PutImageAngle(x,y,Source,angle,rfCosine,imageCenterX,imageCenterY,AOpacity,ARestoreOffsetAfterRotation)
2267 else
2268 PutImageAngle(x,y,Source,angle,rfLinear,imageCenterX,imageCenterY,AOpacity,ARestoreOffsetAfterRotation);
2269end;
2270
2271procedure TBGRACustomBitmap.PutImageAngle(x, y: single;
2272 Source: TBGRACustomBitmap; angle: single; AOutputBounds: TRect;
2273 AResampleFilter: TResampleFilter; imageCenterX: single; imageCenterY: single; AOpacity: Byte;
2274 ARestoreOffsetAfterRotation: boolean);
2275var
2276 Origin,HAxis,VAxis: TPointF;
2277begin
2278 if (source = nil) or (AOpacity=0) then exit;
2279 ComputeImageAngleAxes(x,y,source.Width,source.Height,angle,imageCenterX,imageCenterY,ARestoreOffsetAfterRotation,
2280 Origin,HAxis,VAxis);
2281 PutImageAffine(Origin,HAxis,VAxis,source,AOutputBounds,AResampleFilter,dmDrawWithTransparency,AOpacity);
2282end;
2283
2284procedure TBGRACustomBitmap.PutImageAngle(x, y: single;
2285 Source: TBGRACustomBitmap; angle: single; AResampleFilter: TResampleFilter;
2286 imageCenterX: single; imageCenterY: single; AOpacity: Byte;
2287 ARestoreOffsetAfterRotation: boolean);
2288var
2289 Origin,HAxis,VAxis: TPointF;
2290begin
2291 if (source = nil) or (AOpacity=0) then exit;
2292 ComputeImageAngleAxes(x,y,source.Width,source.Height,angle,imageCenterX,imageCenterY,ARestoreOffsetAfterRotation,
2293 Origin,HAxis,VAxis);
2294 PutImageAffine(Origin,HAxis,VAxis,source,AResampleFilter,AOpacity);
2295end;
2296
2297procedure TBGRACustomBitmap.ComputeImageAngleAxes(x, y, w, h,
2298 angle: single; imageCenterX, imageCenterY: single;
2299 ARestoreOffsetAfterRotation: boolean; out Origin, HAxis, VAxis: TPointF);
2300var
2301 cosa,sina: single;
2302
2303 { Compute rotated coordinates }
2304 function Coord(relX,relY: single): TPointF;
2305 begin
2306 relX -= imageCenterX;
2307 relY -= imageCenterY;
2308 result.x := relX*cosa-relY*sina+x;
2309 result.y := relY*cosa+relX*sina+y;
2310 if ARestoreOffsetAfterRotation then
2311 begin
2312 result.x += imageCenterX;
2313 result.y += imageCenterY;
2314 end;
2315 end;
2316
2317begin
2318 cosa := cos(-angle*Pi/180);
2319 sina := -sin(-angle*Pi/180);
2320 Origin := Coord(0,0);
2321 if w < 2 then w := 2; //when pixel size is 1, actual size is zero, so avoid that
2322 if h < 2 then h := 2;
2323 HAxis := Coord(w-1,0);
2324 VAxis := Coord(0,h-1);
2325end;
2326
2327function TBGRACustomBitmap.GetImageAngleBounds(x, y: single;
2328 Source: TBGRACustomBitmap; angle: single; imageCenterX: single;
2329 imageCenterY: single; ARestoreOffsetAfterRotation: boolean): TRect;
2330var
2331 cosa,sina: single;
2332
2333 { Compute rotated coordinates }
2334 function Coord(relX,relY: single): TPointF;
2335 begin
2336 relX -= imageCenterX;
2337 relY -= imageCenterY;
2338 result.x := relX*cosa-relY*sina+x;
2339 result.y := relY*cosa+relX*sina+y;
2340 if ARestoreOffsetAfterRotation then
2341 begin
2342 result.x += imageCenterX;
2343 result.y += imageCenterY;
2344 end;
2345 end;
2346
2347begin
2348 if (source = nil) then
2349 begin
2350 result := EmptyRect;
2351 exit;
2352 end;
2353 cosa := cos(-angle*Pi/180);
2354 sina := -sin(-angle*Pi/180);
2355 result := GetImageAffineBounds(Coord(0,0),Coord(source.Width,0),Coord(0,source.Height),source);
2356end;
2357
2358procedure TBGRACustomBitmap.VerticalFlip;
2359begin
2360 VerticalFlip(rect(0,0,Width,Height));
2361end;
2362
2363procedure TBGRACustomBitmap.HorizontalFlip;
2364begin
2365 HorizontalFlip(rect(0,0,Width,Height));
2366end;
2367
2368procedure TBGRACustomBitmap.ApplyMask(mask: TBGRACustomBitmap);
2369begin
2370 ApplyMask(mask, Rect(0,0,Width,Height), Point(0,0));
2371end;
2372
2373procedure TBGRACustomBitmap.ApplyMask(mask: TBGRACustomBitmap; ARect: TRect);
2374begin
2375 ApplyMask(mask, ARect, ARect.TopLeft);
2376end;
2377
2378function TBGRACustomBitmap.GetImageBounds(Channel: TChannel; ANothingValue: Byte
2379 ): TRect;
2380begin
2381 result := InternalGetImageBoundsWithin(self,nil,rect(0,0,Width,Height),[Channel],ANothingValue);
2382end;
2383
2384function TBGRACustomBitmap.GetImageBounds(Channels: TChannels;
2385 ANothingValue: Byte): TRect;
2386begin
2387 result := InternalGetImageBoundsWithin(self,nil,rect(0,0,Width,Height),Channels,ANothingValue);
2388end;
2389
2390function TBGRACustomBitmap.GetImageBoundsWithin(const ARect: TRect;
2391 Channel: TChannel; ANothingValue: Byte): TRect;
2392begin
2393 result := InternalGetImageBoundsWithin(self,nil,ARect,[Channel],ANothingValue);
2394end;
2395
2396function TBGRACustomBitmap.GetImageBoundsWithin(const ARect: TRect;
2397 Channels: TChannels; ANothingValue: Byte): TRect;
2398begin
2399 result := InternalGetImageBoundsWithin(self,nil,ARect,Channels,ANothingValue);
2400end;
2401
2402function TBGRACustomBitmap.ScanAtIntegerExpanded(X, Y: integer): TExpandedPixel;
2403begin
2404 result := GammaExpansion(ScanAtInteger(X,Y));
2405end;
2406
2407function TBGRACustomBitmap.ScanNextExpandedPixel: TExpandedPixel;
2408begin
2409 result := GammaExpansion(ScanNextPixel);
2410end;
2411
2412function TBGRACustomBitmap.ScanAtExpanded(X, Y: Single): TExpandedPixel;
2413begin
2414 result := GammaExpansion(ScanAt(X,Y));
2415end;
2416
2417{ Interface gateway }
2418function TBGRACustomBitmap.QueryInterface({$IFDEF FPC_HAS_CONSTREF}constref{$ELSE}const{$ENDIF} IID: TGUID; out Obj): HResult; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND};
2419begin
2420 if GetInterface(iid, obj) then
2421 Result := S_OK
2422 else
2423 Result := longint(E_NOINTERFACE);
2424end;
2425
2426{ There is no automatic reference counting, but it is compulsory to define these functions }
2427function TBGRACustomBitmap._AddRef: Integer; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND};
2428begin
2429 result := 0;
2430end;
2431
2432function TBGRACustomBitmap._Release: Integer; {$IF (not defined(WINDOWS)) AND (FPC_FULLVERSION>=20501)}cdecl{$ELSE}stdcall{$IFEND};
2433begin
2434 result := 0;
2435end;
2436
2437{$hints off}
2438procedure TBGRACustomBitmap.ScanPutPixels(pdest: PBGRAPixel; count: integer;
2439 mode: TDrawMode);
2440begin
2441 //do nothing
2442end;
2443{$hints on}
2444
2445function TBGRACustomBitmap.IsScanPutPixelsDefined: boolean;
2446begin
2447 result := False;
2448end;
2449
2450function TBGRACustomBitmap.ProvidesScanline(ARect: TRect): boolean;
2451begin
2452 result := (ARect.Left+ScanOffset.x >= 0) and (ARect.Top+ScanOffset.y >= 0) and
2453 (ARect.Right+ScanOffset.x <= Width) and (ARect.Bottom+ScanOffset.y <= Height);
2454end;
2455
2456function TBGRACustomBitmap.GetScanlineAt(X, Y: integer): PBGRAPixel;
2457begin
2458 result := ScanLine[y+ScanOffset.y]+x+ScanOffset.x;
2459end;
2460
2461{$ENDIF}
Note: See TracBrowser for help on using the repository browser.