Changeset 472 for GraphicTest/Packages/bgrabitmap/bgradefaultbitmap.pas
- Timestamp:
- Apr 9, 2015, 9:58:36 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GraphicTest/Packages/bgrabitmap/bgradefaultbitmap.pas
r452 r472 33 33 34 34 uses 35 Classes, SysUtils, Types, FPImage, Graphics, BGRABitmapTypes, GraphType, FPImgCanv, BGRACanvas, BGRACanvas2D, FPWritePng; 35 Classes, SysUtils, Types, FPImage, Graphics, BGRABitmapTypes, GraphType, FPImgCanv, 36 BGRACanvas, BGRACanvas2D, FPWritePng, BGRAArrow, BGRAPen; 36 37 37 38 type … … 43 44 if the coordinates are visible and return true if it is the case, swap 44 45 coordinates if necessary and make them fit into the clipping rectangle } 45 function CheckHorizLineBounds(var x, y, x2: int eger): boolean; inline;46 function CheckVertLineBounds(var x, y, y2: int eger; out delta: integer): boolean; inline;46 function CheckHorizLineBounds(var x, y, x2: int32or64): boolean; inline; 47 function CheckVertLineBounds(var x, y, y2: int32or64; out delta: int32or64): boolean; inline; 47 48 function CheckRectBounds(var x,y,x2,y2: integer; minsize: integer): boolean; inline; 48 49 function CheckClippedRectBounds(var x,y,x2,y2: integer): boolean; inline; 49 function CheckPutImageBounds(x, y, tx, ty: integer; out minxb, minyb, maxxb, maxyb, ignoreleft: integer): boolean; inline;50 50 function CheckAntialiasRectBounds(var x,y,x2,y2: single; w: single): boolean; 51 51 function GetCanvasBGRA: TBGRACanvas; … … 75 75 FCanvasFP: TFPImageCanvas; 76 76 FCanvasDrawModeFP: TDrawMode; 77 FCanvasPixelProcFP: procedure(x, y: int eger; col: TBGRAPixel) of object;77 FCanvasPixelProcFP: procedure(x, y: int32or64; col: TBGRAPixel) of object; 78 78 79 79 //canvas-like with antialiasing and texturing … … 83 83 //drawing options 84 84 FEraseMode: boolean; //when polygons are erased instead of drawn 85 FFont: TFont; //font parameters86 85 FFontHeight: integer; 87 FFont HeightSign: integer; //sign correction86 FFontRenderer: TBGRACustomFontRenderer; 88 87 89 88 { Pen style can be defined by PenStyle property of by CustomPenStyle property. … … 92 91 FCustomPenStyle: TBGRAPenStyle; 93 92 FPenStyle: TPenStyle; 93 FArrow: TBGRAArrow; 94 FLineCap: TPenEndCap; 94 95 95 96 //Pixel data … … 99 100 AlwaysReplaceAlpha: boolean = False; RaiseErrorOnInvalidPixelFormat: boolean = True): boolean; 100 101 function GetDataPtr: PBGRAPixel; override; 101 procedure ClearTransparentPixels; 102 procedure ClearTransparentPixels; override; 102 103 function GetScanlineFast(y: integer): PBGRAPixel; inline; 103 104 function GetLineOrder: TRawImageLineOrder; override; … … 144 145 function GetAveragePixel: TBGRAPixel; override; 145 146 function CreateAdaptedPngWriter: TFPWriterPNG; 146 function LoadAsBmp32(Str: TStream): boolean; override;147 147 148 148 //drawing … … 151 151 procedure SetPenStyle(const AValue: TPenStyle); override; 152 152 function GetPenStyle: TPenStyle; override; 153 154 procedure UpdateFont; 153 function GetLineCap: TPenEndCap; override; 154 procedure SetLineCap(AValue: TPenEndCap); override; 155 function GetArrowEndSize: TPointF; override; 156 function GetArrowStartSize: TPointF; override; 157 procedure SetArrowEndSize(AValue: TPointF); override; 158 procedure SetArrowStartSize(AValue: TPointF); override; 159 function GetArrowEndOffset: single; override; 160 function GetArrowStartOffset: single; override; 161 procedure SetArrowEndOffset(AValue: single); override; 162 procedure SetArrowStartOffset(AValue: single); override; 163 function GetArrowEndRepeat: integer; override; 164 function GetArrowStartRepeat: integer; override; 165 procedure SetArrowEndRepeat(AValue: integer); override; 166 procedure SetArrowStartRepeat(AValue: integer); override; 167 155 168 function GetFontHeight: integer; override; 156 169 procedure SetFontHeight(AHeight: integer); override; … … 158 171 procedure SetFontFullHeight(AHeight: integer); override; 159 172 function GetFontPixelMetric: TFontPixelMetric; override; 173 function GetFontRenderer: TBGRACustomFontRenderer; override; 174 procedure SetFontRenderer(AValue: TBGRACustomFontRenderer); override; 160 175 161 176 function GetClipRect: TRect; override; 162 177 procedure SetClipRect(const AValue: TRect); override; 163 178 164 function GetPixelCycleInline(ix,iy: integer; iFactX,iFactY: integer): TBGRAPixel; inline; 179 function InternalGetPixelCycle256(ix,iy: int32or64; iFactX,iFactY: int32or64): TBGRAPixel; 180 function InternalGetPixel256(ix,iy: int32or64; iFactX,iFactY: int32or64; smoothBorder: boolean): TBGRAPixel; 181 function GetPolyLineOption: TBGRAPolyLineOptions; 182 function GetArrow: TBGRAArrow; 183 procedure SetArrowStart(AStyle: TBGRAArrowStyle; ATipStyle: TPenJoinStyle = pjsMiter; ARelativePenWidth: single = 1; ATriangleBackOffset: single = 0); override; 184 procedure SetArrowEnd(AStyle: TBGRAArrowStyle; ATipStyle: TPenJoinStyle = pjsMiter; ARelativePenWidth: single = 1; ATriangleBackOffset: single = 0); override; 165 185 166 186 public … … 170 190 function GetUnique: TBGRACustomBitmap; 171 191 172 {TFPCustomImage override} 173 constructor Create(AWidth, AHeight: integer); override; 174 procedure SetSize(AWidth, AHeight: integer); override; 175 176 {Constructors} 177 constructor Create; override; 178 constructor Create(ABitmap: TBitmap); override; 179 constructor Create(AWidth, AHeight: integer; Color: TColor); override; 180 constructor Create(AWidth, AHeight: integer; Color: TBGRAPixel); override; 181 constructor Create(AFilename: string); override; 182 constructor Create(AStream: TStream); override; 183 destructor Destroy; override; 184 185 {Loading functions} 186 function NewBitmap(AWidth, AHeight: integer): TBGRACustomBitmap; override; 187 function NewBitmap(AWidth, AHeight: integer; Color: TBGRAPixel): TBGRACustomBitmap; override; 188 function NewBitmap(Filename: string): TBGRACustomBitmap; override; 189 190 procedure LoadFromFile(const filename: string); override; 192 {------------------------- Constructors from TFPCustomImage----------------} 193 constructor Create(AWidth, AHeight: integer); override; //Creates a new bitmap, initialize properties and bitmap data 194 procedure SetSize(AWidth, AHeight: integer); override; //Can only be called with an existing instance of TBGRABitmap. 195 //Sets the dimensions of an existing TBGRABitmap instance. 196 197 {------------------------- Constructors from TBGRACustomBitmap-------------} 198 constructor Create; override; //Creates an image of width and height equal to zero. 199 constructor Create(ABitmap: TBitmap); override; //Creates an image of dimensions AWidth and AHeight and filled with transparent pixels. 200 constructor Create(AWidth, AHeight: integer; Color: TColor); override; //Creates an image of dimensions AWidth and AHeight and fills it with the opaque color Color. 201 constructor Create(AWidth, AHeight: integer; Color: TBGRAPixel); override; //Creates an image of dimensions AWidth and AHeight and fills it with Color. 202 203 constructor Create(AFilename: string); override; // Creates an image by loading its content from the file AFilename. 204 // The encoding of the string is the default one for the operating system. 205 // It is recommended to use the next constructor and UTF8 encoding. 206 207 constructor Create(AFilename: string; AIsUtf8: boolean); override; //Creates an image by loading its content from the file AFilename. 208 //The boolean AIsUtf8Filename specifies if UTF8 encoding is assumed for the filename. 209 210 constructor Create(AStream: TStream); override; // Creates an image by loading its content from the stream AStream. 211 destructor Destroy; override; // Free the object and all its resources 212 213 {------------------------- Quasi-constructors -----------------------------} 214 function NewBitmap(AWidth, AHeight: integer): TBGRACustomBitmap; override; //Can only be called from an existing instance of TBGRABitmap. 215 //Creates a new instance with dimensions AWidth and AHeight, 216 //containing transparent pixels. 217 218 function NewBitmap(AWidth, AHeight: integer; Color: TBGRAPixel): TBGRACustomBitmap; override; //Can only be called from an existing instance of TBGRABitmap. 219 //Creates a new instance with dimensions AWidth and AHeight, 220 //and fills it with Color. 221 222 function NewBitmap(Filename: string): TBGRACustomBitmap; override; //Can only be called from an existing instance of TBGRABitmap. 223 //Creates a new instance with by loading its content 224 //from the file Filename. The encoding of the string 225 //is the default one for the operating system. 226 227 function NewBitmap(Filename: string; AIsUtf8: boolean): TBGRACustomBitmap; override; //Can only be called from an existing instance of TBGRABitmap. 228 //Creates a new instance with by loading its content 229 //from the file Filename. 230 191 231 procedure SaveToFile(const filename: string); override; 192 232 procedure SaveToStreamAsPng(Str: TStream); override; 193 procedure Assign(A Bitmap: TBitmap); override; overload;233 procedure Assign(ARaster: TRasterImage); override; overload; 194 234 procedure Assign(MemBitmap: TBGRACustomBitmap);override; overload; 195 235 procedure Serialize(AStream: TStream); override; … … 198 238 199 239 {Pixel functions} 200 function PtInClipRect(x, y: integer): boolean; inline; 201 procedure SetPixel(x, y: integer; c: TColor); override; 202 procedure SetPixel(x, y: integer; c: TBGRAPixel); override; 203 procedure XorPixel(x, y: integer; c: TBGRAPixel); override; 204 procedure DrawPixel(x, y: integer; c: TBGRAPixel); override; 205 procedure DrawPixel(x, y: integer; ec: TExpandedPixel); override; 206 procedure FastBlendPixel(x, y: integer; c: TBGRAPixel); override; 207 procedure ErasePixel(x, y: integer; alpha: byte); override; 208 procedure AlphaPixel(x, y: integer; alpha: byte); override; 209 function GetPixel(x, y: integer): TBGRAPixel; override; 210 function GetPixel(x, y: single; AResampleFilter: TResampleFilter = rfLinear): TBGRAPixel; override; 240 function PtInClipRect(x, y: int32or64): boolean; inline; 241 procedure SetPixel(x, y: int32or64; c: TColor); override; 242 procedure SetPixel(x, y: int32or64; c: TBGRAPixel); override; 243 procedure XorPixel(x, y: int32or64; c: TBGRAPixel); override; 244 procedure DrawPixel(x, y: int32or64; c: TBGRAPixel); override; 245 procedure DrawPixel(x, y: int32or64; ec: TExpandedPixel); override; 246 procedure FastBlendPixel(x, y: int32or64; c: TBGRAPixel); override; 247 procedure ErasePixel(x, y: int32or64; alpha: byte); override; 248 procedure AlphaPixel(x, y: int32or64; alpha: byte); override; 249 function GetPixel(x, y: int32or64): TBGRAPixel; override; 250 function GetPixel256(x, y, fracX256,fracY256: int32or64; AResampleFilter: TResampleFilter = rfLinear; smoothBorder: boolean = true): TBGRAPixel; override; 251 function GetPixel(x, y: single; AResampleFilter: TResampleFilter = rfLinear; smoothBorder: boolean = true): TBGRAPixel; override; 211 252 function GetPixelCycle(x, y: single; AResampleFilter: TResampleFilter = rfLinear): TBGRAPixel; override; 212 function GetPixelCycle(x, y: single; AResampleFilter: TResampleFilter; 213 repeatX: boolean; repeatY: boolean): TBGRAPixel; override; overload; 253 function GetPixelCycle(x, y: single; AResampleFilter: TResampleFilter; repeatX: boolean; repeatY: boolean): TBGRAPixel; override; 254 function GetPixelCycle256(x, y, fracX256,fracY256: int32or64; AResampleFilter: TResampleFilter = rfLinear): TBGRAPixel; override; 255 function GetPixelCycle256(x, y, fracX256,fracY256: int32or64; AResampleFilter: TResampleFilter; repeatX: boolean; repeatY: boolean): TBGRAPixel; override; 214 256 215 257 {Line primitives} 216 procedure SetHorizLine(x, y, x2: integer; c: TBGRAPixel); override; 217 procedure XorHorizLine(x, y, x2: integer; c: TBGRAPixel); override; 218 procedure DrawHorizLine(x, y, x2: integer; c: TBGRAPixel); override; 219 procedure DrawHorizLine(x, y, x2: integer; ec: TExpandedPixel); override; 220 procedure DrawHorizLine(x, y, x2: integer; texture: IBGRAScanner); override; 221 procedure FastBlendHorizLine(x, y, x2: integer; c: TBGRAPixel); override; 222 procedure AlphaHorizLine(x, y, x2: integer; alpha: byte); override; 223 procedure SetVertLine(x, y, y2: integer; c: TBGRAPixel); override; 224 procedure XorVertLine(x, y, y2: integer; c: TBGRAPixel); override; 225 procedure DrawVertLine(x, y, y2: integer; c: TBGRAPixel); override; 226 procedure AlphaVertLine(x, y, y2: integer; alpha: byte); override; 227 procedure FastBlendVertLine(x, y, y2: integer; c: TBGRAPixel); override; 228 procedure DrawHorizLineDiff(x, y, x2: integer; c, compare: TBGRAPixel; 258 procedure SetHorizLine(x, y, x2: int32or64; c: TBGRAPixel); override; 259 procedure XorHorizLine(x, y, x2: int32or64; c: TBGRAPixel); override; 260 procedure DrawHorizLine(x, y, x2: int32or64; c: TBGRAPixel); override; 261 procedure DrawHorizLine(x, y, x2: int32or64; ec: TExpandedPixel); override; 262 procedure HorizLine(x, y, x2: int32or64; texture: IBGRAScanner; ADrawMode : TDrawMode); override; 263 264 procedure FastBlendHorizLine(x, y, x2: int32or64; c: TBGRAPixel); override; 265 procedure AlphaHorizLine(x, y, x2: int32or64; alpha: byte); override; 266 procedure SetVertLine(x, y, y2: int32or64; c: TBGRAPixel); override; 267 procedure XorVertLine(x, y, y2: int32or64; c: TBGRAPixel); override; 268 procedure DrawVertLine(x, y, y2: int32or64; c: TBGRAPixel); override; 269 procedure AlphaVertLine(x, y, y2: int32or64; alpha: byte); override; 270 procedure FastBlendVertLine(x, y, y2: int32or64; c: TBGRAPixel); override; 271 procedure DrawHorizLineDiff(x, y, x2: int32or64; c, compare: TBGRAPixel; 229 272 maxDiff: byte); override; 230 273 231 274 {Shapes} 232 procedure DrawLine(x1, y1, x2, y2: integer; c: TBGRAPixel; DrawLastPixel: boolean); override; 275 procedure DrawPath(APath: IBGRAPath; c: TBGRAPixel; w: single); override; 276 procedure DrawPath(APath: IBGRAPath; texture: IBGRAScanner; w: single); override; 277 278 procedure DrawLine(x1, y1, x2, y2: integer; c: TBGRAPixel; DrawLastPixel: boolean; ADrawMode: TDrawMode = dmDrawWithTransparency); override; 233 279 procedure DrawLineAntialias(x1, y1, x2, y2: integer; c: TBGRAPixel; DrawLastPixel: boolean); override; 234 280 procedure DrawLineAntialias(x1, y1, x2, y2: integer; c1, c2: TBGRAPixel; dashLen: integer; DrawLastPixel: boolean); override; … … 242 288 procedure DrawPolyLineAntialias(const points: array of TPointF; texture: IBGRAScanner; w: single); override; 243 289 procedure DrawPolyLineAntialias(const points: array of TPointF; c: TBGRAPixel; w: single; Closed: boolean); override; 290 procedure DrawPolyLineAntialias(const points: array of TPointF; c: TBGRAPixel; w: single; fillcolor: TBGRAPixel); override; 244 291 procedure DrawPolygonAntialias(const points: array of TPointF; c: TBGRAPixel; w: single); override; 245 292 procedure DrawPolygonAntialias(const points: array of TPointF; texture: IBGRAScanner; w: single); override; 293 procedure DrawPolygonAntialias(const points: array of TPointF; c: TBGRAPixel; w: single; fillcolor: TBGRAPixel); override; 246 294 247 295 procedure EraseLine(x1, y1, x2, y2: integer; alpha: byte; DrawLastPixel: boolean); override; … … 250 298 procedure EraseLineAntialias(x1, y1, x2, y2: single; alpha: byte; w: single; Closed: boolean); override; 251 299 procedure ErasePolyLineAntialias(const points: array of TPointF; alpha: byte; w: single); override; 300 301 procedure FillPath(APath: IBGRAPath; c: TBGRAPixel); override; 302 procedure FillPath(APath: IBGRAPath; texture: IBGRAScanner); override; 252 303 253 304 procedure FillTriangleLinearColor(pt1,pt2,pt3: TPointF; c1,c2,c3: TBGRAPixel); override; … … 263 314 procedure FillQuadLinearMappingAntialias(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF); override; 264 315 procedure FillQuadPerspectiveMapping(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF); override; 316 procedure FillQuadPerspectiveMapping(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; ACleanBorders: TRect); override; 265 317 procedure FillQuadPerspectiveMappingAntialias(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF); override; 318 procedure FillQuadPerspectiveMappingAntialias(pt1,pt2,pt3,pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; ACleanBorders: TRect); override; 266 319 267 320 procedure FillPolyLinearMapping(const points: array of TPointF; texture: IBGRAScanner; texCoords: array of TPointF; TextureInterpolation: Boolean); override; … … 270 323 procedure FillPolyPerspectiveMapping(const points: array of TPointF; const pointsZ: array of single; texture: IBGRAScanner; texCoords: array of TPointF; TextureInterpolation: Boolean; zbuffer: psingle = nil); override; 271 324 procedure FillPolyPerspectiveMappingLightness(const points: array of TPointF; const pointsZ: array of single; texture: IBGRAScanner; texCoords: array of TPointF; lightnesses: array of word; TextureInterpolation: Boolean; zbuffer: psingle = nil); override; 325 272 326 procedure FillPoly(const points: array of TPointF; c: TBGRAPixel; drawmode: TDrawMode); override; 273 327 procedure FillPoly(const points: array of TPointF; texture: IBGRAScanner; drawmode: TDrawMode); override; … … 276 330 procedure ErasePoly(const points: array of TPointF; alpha: byte); override; 277 331 procedure ErasePolyAntialias(const points: array of TPointF; alpha: byte); override; 332 333 procedure FillShape(shape: TBGRACustomFillInfo; c: TBGRAPixel; drawmode: TDrawMode); override; 334 procedure FillShape(shape: TBGRACustomFillInfo; texture: IBGRAScanner; drawmode: TDrawMode); override; 335 procedure FillShapeAntialias(shape: TBGRACustomFillInfo; c: TBGRAPixel); override; 336 procedure FillShapeAntialias(shape: TBGRACustomFillInfo; texture: IBGRAScanner); override; 337 procedure EraseShape(shape: TBGRACustomFillInfo; alpha: byte); override; 338 procedure EraseShapeAntialias(shape: TBGRACustomFillInfo; alpha: byte); override; 278 339 279 340 procedure EllipseAntialias(x, y, rx, ry: single; c: TBGRAPixel; w: single); override; … … 295 356 procedure RoundRectAntialias(x,y,x2,y2,rx,ry: single; penTexture: IBGRAScanner; w: single; fillTexture: IBGRAScanner; options: TRoundRectangleOptions = []); override; 296 357 297 procedure FillRect(x, y, x2, y2: integer; c: TBGRAPixel; mode: TDrawMode); override; 298 procedure FillRect(x, y, x2, y2: integer; texture: IBGRAScanner; mode: TDrawMode); override; 358 procedure FillRect(x, y, x2, y2: integer; c: TBGRAPixel; mode: TDrawMode); override; overload; 359 procedure FillRect(x, y, x2, y2: integer; texture: IBGRAScanner; mode: TDrawMode); override; overload; 299 360 procedure FillRectAntialias(x, y, x2, y2: single; c: TBGRAPixel); override; 300 361 procedure EraseRectAntialias(x, y, x2, y2: single; alpha: byte); override; … … 305 366 procedure AlphaFillRect(x, y, x2, y2: integer; alpha: byte); override; 306 367 procedure RoundRect(X1, Y1, X2, Y2: integer; DX, DY: integer; 307 BorderColor, FillColor: TBGRAPixel); override; 308 309 procedure TextOutAngle(x, y: single; orientation: integer; s: string; c: TBGRAPixel; align: TAlignment); override; 310 procedure TextOutAngle(x, y: single; orientation: integer; s: string; texture: IBGRAScanner; align: TAlignment); override; 311 procedure TextOut(x, y: single; s: string; texture: IBGRAScanner; align: TAlignment); override; 312 procedure TextOut(x, y: single; s: string; c: TBGRAPixel; align: TAlignment); override; 313 procedure TextRect(ARect: TRect; x, y: integer; s: string; style: TTextStyle; c: TBGRAPixel); override; 314 procedure TextRect(ARect: TRect; x, y: integer; s: string; style: TTextStyle; texture: IBGRAScanner); override; 315 function TextSize(s: string): TSize; override; 368 BorderColor, FillColor: TBGRAPixel; ADrawMode: TDrawMode = dmDrawWithTransparency); override; 369 procedure RoundRect(X1, Y1, X2, Y2: integer; DX, DY: integer; 370 BorderColor: TBGRAPixel; ADrawMode: TDrawMode = dmDrawWithTransparency); override; 371 372 { Draws the UTF8 encoded string, with color c. 373 If align is taLeftJustify, (x,y) is the top-left corner. 374 If align is taCenter, (x,y) is at the top and middle of the text. 375 If align is taRightJustify, (x,y) is the top-right corner. 376 The value of FontOrientation is taken into account, so that the text may be rotated. } 377 procedure TextOut(x, y: single; sUTF8: string; c: TBGRAPixel; align: TAlignment); override; overload; 378 379 { Same as above functions, except that the text is filled using texture. 380 The value of FontOrientation is taken into account, so that the text may be rotated. } 381 procedure TextOut(x, y: single; sUTF8: string; texture: IBGRAScanner; align: TAlignment); override; overload; 382 383 { Same as above, except that the orientation is specified, overriding the value of the property FontOrientation. } 384 procedure TextOutAngle(x, y: single; orientationTenthDegCCW: integer; sUTF8: string; c: TBGRAPixel; align: TAlignment); override; overload; 385 procedure TextOutAngle(x, y: single; orientationTenthDegCCW: integer; sUTF8: string; texture: IBGRAScanner; align: TAlignment); override; overload; 386 387 { Draw the UTF8 encoded string at the coordinate (x,y), clipped inside the rectangle ARect. 388 Additional style information is provided by the style parameter. 389 The color c or texture is used to fill the text. No rotation is applied. } 390 procedure TextRect(ARect: TRect; x, y: integer; sUTF8: string; style: TTextStyle; c: TBGRAPixel); override; overload; 391 procedure TextRect(ARect: TRect; x, y: integer; sUTF8: string; style: TTextStyle; texture: IBGRAScanner); override; overload; 392 393 { Returns the total size of the string provided using the current font. 394 Orientation is not taken into account, so that the width is along the text. } 395 function TextSize(sUTF8: string): TSize; override; 316 396 317 397 {Spline} … … 344 424 procedure DrawPixels(c: TBGRAPixel; start, Count: integer); override; 345 425 procedure AlphaFill(alpha: byte; start, Count: integer); override; 346 procedure FillMask(x,y: integer; AMask: TBGRACustomBitmap; color: TBGRAPixel ); override;347 procedure FillMask(x,y: integer; AMask: TBGRACustomBitmap; texture: IBGRAScanner ); override;426 procedure FillMask(x,y: integer; AMask: TBGRACustomBitmap; color: TBGRAPixel; ADrawMode: TDrawMode); override; 427 procedure FillMask(x,y: integer; AMask: TBGRACustomBitmap; texture: IBGRAScanner; ADrawMode: TDrawMode); override; 348 428 procedure FillClearTypeMask(x,y: integer; xThird: integer; AMask: TBGRACustomBitmap; color: TBGRAPixel; ARGBOrder: boolean = true); override; 349 429 procedure FillClearTypeMask(x,y: integer; xThird: integer; AMask: TBGRACustomBitmap; texture: IBGRAScanner; ARGBOrder: boolean = true); override; … … 380 460 381 461 {BGRA bitmap functions} 462 procedure CrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadePosition: byte; mode: TDrawMode = dmDrawWithTransparency); override; 463 procedure CrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadeMask: IBGRAScanner; mode: TDrawMode = dmDrawWithTransparency); override; 382 464 procedure PutImage(x, y: integer; Source: TBGRACustomBitmap; mode: TDrawMode; AOpacity: byte = 255); override; 383 procedure PutImageAngle(x,y: single; Source: TBGRACustomBitmap; angle: single; imageCenterX: single = 0; imageCenterY: single = 0; AOpacity: Byte=255; ARestoreOffsetAfterRotation: boolean = false); override; 384 procedure PutImageAffine(Origin,HAxis,VAxis: TPointF; Source: TBGRACustomBitmap; AOpacity: Byte=255); override; 465 procedure PutImageAffine(Origin,HAxis,VAxis: TPointF; Source: TBGRACustomBitmap; AOutputBounds: TRect; AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte=255); override; 466 procedure StretchPutImage(ARect: TRect; Source: TBGRACustomBitmap; mode: TDrawMode; AOpacity: byte = 255); override; 467 385 468 procedure BlendImage(x, y: integer; Source: TBGRACustomBitmap; operation: TBlendOperation); override; 386 469 procedure BlendImageOver(x, y: integer; Source: TBGRACustomBitmap; operation: TBlendOperation; AOpacity: byte = 255; … … 394 477 function Equals(comp: TBGRAPixel): boolean; override; 395 478 function GetImageBounds(Channel: TChannel = cAlpha; ANothingValue: Byte = 0): TRect; override; 396 function GetImageBounds(Channels: TChannels ): TRect; override;479 function GetImageBounds(Channels: TChannels; ANothingValue: Byte = 0): TRect; override; 397 480 function GetDifferenceBounds(ABitmap: TBGRACustomBitmap): TRect; override; 398 481 function MakeBitmapCopy(BackgroundColor: TColor): TBitmap; override; … … 400 483 function Resample(newWidth, newHeight: integer; 401 484 mode: TResampleMode = rmFineResample): TBGRACustomBitmap; override; 402 procedure VerticalFlip ; override;403 procedure HorizontalFlip ; override;485 procedure VerticalFlip(ARect: TRect); override; 486 procedure HorizontalFlip(ARect: TRect); override; 404 487 function RotateCW: TBGRACustomBitmap; override; 405 488 function RotateCCW: TBGRACustomBitmap; override; 406 489 procedure Negative; override; 490 procedure NegativeRect(ABounds: TRect); override; 407 491 procedure LinearNegative; override; 492 procedure LinearNegativeRect(ABounds: TRect); override; 493 procedure InplaceGrayscale; override; 494 procedure InplaceGrayscale(ABounds: TRect); override; 408 495 procedure SwapRedBlue; override; 409 496 procedure GrayscaleToAlpha; override; 410 497 procedure AlphaToGrayscale; override; 411 procedure ApplyMask(mask: TBGRACustomBitmap ); override;498 procedure ApplyMask(mask: TBGRACustomBitmap; ARect: TRect; AMaskRectTopLeft: TPoint); override; 412 499 procedure ApplyGlobalOpacity(alpha: byte); override; 413 500 procedure ConvertToLinearRGB; override; 414 501 procedure ConvertFromLinearRGB; override; 502 procedure DrawCheckers(ARect: TRect; AColorEven,AColorOdd: TBGRAPixel); 415 503 416 504 {Filters} … … 418 506 function FilterMedian(Option: TMedianOption): TBGRACustomBitmap; override; 419 507 function FilterSmooth: TBGRACustomBitmap; override; 420 function FilterSharpen: TBGRACustomBitmap; override; 508 function FilterSharpen(Amount: single = 1): TBGRACustomBitmap; override; 509 function FilterSharpen(ABounds: TRect; Amount: single = 1): TBGRACustomBitmap; override; 421 510 function FilterContour: TBGRACustomBitmap; override; 511 function FilterPixelate(pixelSize: integer; useResample: boolean; filter: TResampleFilter = rfLinear): TBGRACustomBitmap; override; 422 512 function FilterBlurRadial(radius: integer; 423 513 blurType: TRadialBlurType): TBGRACustomBitmap; override; 424 function FilterPixelate(pixelSize: integer; useResample: boolean; filter: TResampleFilter = rfLinear): TBGRACustomBitmap; override; 514 function FilterBlurRadial(ABounds: TRect; radius: integer; 515 blurType: TRadialBlurType): TBGRACustomBitmap; override; 425 516 function FilterBlurMotion(distance: integer; angle: single; 426 517 oriented: boolean): TBGRACustomBitmap; override; 518 function FilterBlurMotion(ABounds: TRect; distance: integer; angle: single; 519 oriented: boolean): TBGRACustomBitmap; override; 427 520 function FilterCustomBlur(mask: TBGRACustomBitmap): TBGRACustomBitmap; override; 521 function FilterCustomBlur(ABounds: TRect; mask: TBGRACustomBitmap): TBGRACustomBitmap; override; 428 522 function FilterEmboss(angle: single): TBGRACustomBitmap; override; 523 function FilterEmboss(angle: single; ABounds: TRect): TBGRACustomBitmap; override; 429 524 function FilterEmbossHighlight(FillSelection: boolean): TBGRACustomBitmap; override; 430 525 function FilterEmbossHighlight(FillSelection: boolean; BorderColor: TBGRAPixel): TBGRACustomBitmap; override; 431 526 function FilterEmbossHighlight(FillSelection: boolean; BorderColor: TBGRAPixel; var Offset: TPoint): TBGRACustomBitmap; override; 432 527 function FilterGrayscale: TBGRACustomBitmap; override; 528 function FilterGrayscale(ABounds: TRect): TBGRACustomBitmap; override; 433 529 function FilterNormalize(eachChannel: boolean = True): TBGRACustomBitmap; override; 434 function FilterRotate(origin: TPointF; angle: single): TBGRACustomBitmap; override; 530 function FilterNormalize(ABounds: TRect; eachChannel: boolean = True): TBGRACustomBitmap; override; 531 function FilterRotate(origin: TPointF; angle: single; correctBlur: boolean = false): TBGRACustomBitmap; override; 435 532 function FilterSphere: TBGRACustomBitmap; override; 436 533 function FilterTwirl(ACenter: TPoint; ARadius: Single; ATurn: Single=1; AExponent: Single=3): TBGRACustomBitmap; override; 534 function FilterTwirl(ABounds: TRect; ACenter: TPoint; ARadius: Single; ATurn: Single=1; AExponent: Single=3): TBGRACustomBitmap; override; 437 535 function FilterCylinder: TBGRACustomBitmap; override; 438 536 function FilterPlane: TBGRACustomBitmap; override; … … 465 563 466 564 uses Math, LCLIntf, LCLType, 467 BGRABlend, BGRAFilters, BGRA Pen, BGRAText, BGRATextFX, BGRAGradientScanner,565 BGRABlend, BGRAFilters, BGRAText, BGRATextFX, BGRAGradientScanner, 468 566 BGRAResample, BGRATransform, BGRAPolygon, BGRAPolygonAliased, 469 567 BGRAPath, FPReadPcx, FPWritePcx, FPReadXPM, FPWriteXPM; … … 486 584 procedure TBitmapTracker.Changed(Sender: TObject); 487 585 begin 488 FUser.FBitmapModified := True; 586 if FUser <> nil then 587 FUser.FBitmapModified := True; 489 588 inherited Changed(Sender); 490 589 end; … … 570 669 end; 571 670 572 { Update font properties to internal TFont object } 573 procedure TBGRADefaultBitmap.UpdateFont; 574 begin 575 if FFont.Name <> FontName then 576 FFont.Name := FontName; 577 if FFont.Style <> FontStyle then 578 FFont.Style := FontStyle; 579 if FFont.Height <> FFontHeight * FFontHeightSign then 580 FFont.Height := FFontHeight * FFontHeightSign; 581 if FFont.Orientation <> FontOrientation then 582 FFont.Orientation := FontOrientation; 583 if FontQuality = fqSystemClearType then 584 FFont.Quality := fqCleartype 585 else 586 FFont.Quality := FontDefaultQuality; 671 function TBGRADefaultBitmap.GetLineCap: TPenEndCap; 672 begin 673 result := FLineCap; 674 end; 675 676 procedure TBGRADefaultBitmap.SetLineCap(AValue: TPenEndCap); 677 begin 678 if AValue <> FLineCap then 679 begin 680 FLineCap:= AValue; 681 if Assigned(FArrow) then FArrow.LineCap := AValue; 682 end; 683 end; 684 685 function TBGRADefaultBitmap.GetArrowEndSize: TPointF; 686 begin 687 result := GetArrow.EndSize; 688 end; 689 690 function TBGRADefaultBitmap.GetArrowStartSize: TPointF; 691 begin 692 result := GetArrow.StartSize; 693 end; 694 695 procedure TBGRADefaultBitmap.SetArrowEndSize(AValue: TPointF); 696 begin 697 GetArrow.EndSize := AValue; 698 end; 699 700 procedure TBGRADefaultBitmap.SetArrowStartSize(AValue: TPointF); 701 begin 702 GetArrow.StartSize := AValue; 703 end; 704 705 function TBGRADefaultBitmap.GetArrowEndOffset: single; 706 begin 707 result := GetArrow.EndOffsetX; 708 end; 709 710 function TBGRADefaultBitmap.GetArrowStartOffset: single; 711 begin 712 result := GetArrow.StartOffsetX; 713 end; 714 715 procedure TBGRADefaultBitmap.SetArrowEndOffset(AValue: single); 716 begin 717 GetArrow.EndOffsetX := AValue; 718 end; 719 720 procedure TBGRADefaultBitmap.SetArrowStartOffset(AValue: single); 721 begin 722 GetArrow.StartOffsetX := AValue; 723 end; 724 725 function TBGRADefaultBitmap.GetArrowEndRepeat: integer; 726 begin 727 result := GetArrow.EndRepeatCount; 728 end; 729 730 function TBGRADefaultBitmap.GetArrowStartRepeat: integer; 731 begin 732 result := GetArrow.StartRepeatCount; 733 end; 734 735 procedure TBGRADefaultBitmap.SetArrowEndRepeat(AValue: integer); 736 begin 737 GetArrow.EndRepeatCount := AValue; 738 end; 739 740 procedure TBGRADefaultBitmap.SetArrowStartRepeat(AValue: integer); 741 begin 742 GetArrow.StartRepeatCount := AValue; 587 743 end; 588 744 … … 609 765 610 766 function TBGRADefaultBitmap.GetFontPixelMetric: TFontPixelMetric; 611 var fxFont: TFont; 612 begin 613 UpdateFont; 614 if FontQuality = fqSystem then 615 result := BGRAText.GetFontPixelMetric(FFont) 616 else 617 begin 618 FxFont := TFont.Create; 619 FxFont.Assign(FFont); 620 FxFont.Height := fxFont.Height*FontAntialiasingLevel; 621 Result:= BGRAText.GetFontPixelMetric(FxFont); 622 if Result.Baseline <> -1 then Result.Baseline:= round((Result.Baseline-1)/FontAntialiasingLevel); 623 if Result.CapLine <> -1 then Result.CapLine:= round(Result.CapLine/FontAntialiasingLevel); 624 if Result.DescentLine <> -1 then Result.DescentLine:= round((Result.DescentLine-1)/FontAntialiasingLevel); 625 if Result.Lineheight <> -1 then Result.Lineheight:= round(Result.Lineheight/FontAntialiasingLevel); 626 if Result.xLine <> -1 then Result.xLine:= round(Result.xLine/FontAntialiasingLevel); 627 end; 767 begin 768 result := FontRenderer.GetFontPixelMetric; 769 end; 770 771 function TBGRADefaultBitmap.GetFontRenderer: TBGRACustomFontRenderer; 772 begin 773 if FFontRenderer = nil then FFontRenderer := TLCLFontRenderer.Create; 774 result := FFontRenderer; 775 result.FontName := FontName; 776 result.FontStyle := FontStyle; 777 result.FontQuality := FontQuality; 778 result.FontOrientation := FontOrientation; 779 result.FontEmHeight := FFontHeight; 780 end; 781 782 procedure TBGRADefaultBitmap.SetFontRenderer(AValue: TBGRACustomFontRenderer); 783 begin 784 if AValue = FFontRenderer then exit; 785 FFontRenderer.Free; 786 FFontRenderer := AValue 628 787 end; 629 788 … … 689 848 end; 690 849 691 { Creates a new bitmap. Internally, it uses the same type so that if you 850 { Creates a new bitmap with dimensions AWidth and AHeight and filled with 851 transparent pixels. Internally, it uses the same type so that if you 692 852 use an optimized version, you get a new bitmap with the same optimizations } 693 853 function TBGRADefaultBitmap.NewBitmap(AWidth, AHeight: integer): TBGRACustomBitmap; … … 701 861 end; 702 862 863 { Can only be called from an existing instance of TBGRABitmap. 864 Creates a new instance with dimensions AWidth and AHeight, 865 and fills it with Color. } 703 866 function TBGRADefaultBitmap.NewBitmap(AWidth, AHeight: integer; 704 867 Color: TBGRAPixel): TBGRACustomBitmap; … … 712 875 end; 713 876 714 { Creates a new bitmap and loads it contents from a file } 877 { Creates a new bitmap and loads it contents from a file. 878 The encoding of the string is the default one for the operating system. 879 It is recommended to use the next function and UTF8 encoding } 715 880 function TBGRADefaultBitmap.NewBitmap(Filename: string): TBGRACustomBitmap; 716 881 var … … 719 884 BGRAClass := TBGRABitmapAny(self.ClassType); 720 885 Result := BGRAClass.Create(Filename); 886 end; 887 888 { Creates a new bitmap and loads it contents from a file. 889 It is recommended to use UTF8 encoding } 890 function TBGRADefaultBitmap.NewBitmap(Filename: string; AIsUtf8: boolean): TBGRACustomBitmap; 891 var 892 BGRAClass: TBGRABitmapAny; 893 begin 894 BGRAClass := TBGRABitmapAny(self.ClassType); 895 Result := BGRAClass.Create(Filename,AIsUtf8); 721 896 end; 722 897 … … 754 929 {---------------------- Constructors ---------------------------------} 755 930 931 { Creates an image of width and height equal to zero. } 756 932 constructor TBGRADefaultBitmap.Create; 757 933 begin … … 760 936 end; 761 937 938 { Creates an image of dimensions AWidth and AHeight and filled with transparent pixels. } 762 939 constructor TBGRADefaultBitmap.Create(ABitmap: TBitmap); 763 940 begin … … 767 944 end; 768 945 946 { Creates an image of dimensions AWidth and AHeight and fills it with the opaque color Color. } 769 947 constructor TBGRADefaultBitmap.Create(AWidth, AHeight: integer; Color: TColor); 770 948 begin … … 774 952 end; 775 953 954 { Creates an image of dimensions AWidth and AHeight and fills it with Color. } 776 955 constructor TBGRADefaultBitmap.Create(AWidth, AHeight: integer; Color: TBGRAPixel); 777 956 begin … … 781 960 end; 782 961 962 { Creates an image by loading its content from the file AFilename. 963 The encoding of the string is the default one for the operating system. 964 It is recommended to use the next constructor and UTF8 encoding. } 965 constructor TBGRADefaultBitmap.Create(AFilename: string); 966 begin 967 Init; 968 inherited Create(0, 0); 969 LoadFromFile(Afilename); 970 end; 971 972 { Free the object and all its resources } 783 973 destructor TBGRADefaultBitmap.Destroy; 784 974 begin 785 975 FreeData; 786 FFont .Free;976 FFontRenderer.Free; 787 977 FBitmap.Free; 788 978 FCanvasFP.Free; 789 979 FCanvasBGRA.Free; 790 980 FCanvas2D.Free; 981 FArrow.Free; 791 982 inherited Destroy; 792 983 end; … … 794 985 {------------------------- Loading functions ----------------------------------} 795 986 796 constructor TBGRADefaultBitmap.Create(AFilename: string); 987 { Creates an image by loading its content from the file AFilename. 988 The boolean AIsUtf8Filename specifies if UTF8 encoding is assumed for the filename. } 989 constructor TBGRADefaultBitmap.Create(AFilename: string; AIsUtf8: boolean); 797 990 begin 798 991 Init; 799 inherited Create(0, 0); 800 LoadFromFile(Afilename); 801 end; 802 992 inherited Create(0, 0); 993 if AIsUtf8 then 994 LoadFromFileUTF8(Afilename) 995 else 996 LoadFromFile(Afilename); 997 end; 998 999 { Creates an image by loading its content from the stream AStream. } 803 1000 constructor TBGRADefaultBitmap.Create(AStream: TStream); 804 1001 begin … … 808 1005 end; 809 1006 810 procedure TBGRADefaultBitmap.Assign(A Bitmap: TBitmap);1007 procedure TBGRADefaultBitmap.Assign(ARaster: TRasterImage); 811 1008 var TempBmp: TBitmap; 812 1009 ConvertOk: boolean; 813 1010 begin 814 1011 DiscardBitmapChange; 815 SetSize(ABitmap.Width, ABitmap.Height); 816 if not LoadFromRawImage(ABitmap.RawImage,0,False,False) then 1012 SetSize(ARaster.Width, ARaster.Height); 1013 if not LoadFromRawImage(ARaster.RawImage,0,False,False) then 1014 if ARaster is TBitmap then 817 1015 begin //try to convert 818 1016 TempBmp := TBitmap.Create; 819 TempBmp.Width := A Bitmap.Width;820 TempBmp.Height := A Bitmap.Height;821 TempBmp.Canvas.Draw(0,0,A Bitmap);1017 TempBmp.Width := ARaster.Width; 1018 TempBmp.Height := ARaster.Height; 1019 TempBmp.Canvas.Draw(0,0,ARaster); 822 1020 ConvertOk := LoadFromRawImage(TempBmp.RawImage,0,False,False); 823 1021 TempBmp.Free; 824 1022 if not ConvertOk then 825 1023 raise Exception.Create('Unable to convert image to 24 bit'); 826 end; 1024 end else 1025 raise Exception.Create('Unable to convert image to 24 bit'); 827 1026 If Empty then AlphaFill(255); // if bitmap seems to be empty, assume 828 1027 // it is an opaque bitmap without alpha channel … … 837 1036 838 1037 procedure TBGRADefaultBitmap.Serialize(AStream: TStream); 839 var lWidth,lHeight : integer;1038 var lWidth,lHeight,y: integer; 840 1039 begin 841 1040 lWidth := NtoLE(Width); … … 843 1042 AStream.Write(lWidth,sizeof(lWidth)); 844 1043 AStream.Write(lHeight,sizeof(lHeight)); 845 AStream.Write(Data^, NbPixels*sizeof(TBGRAPixel)); 1044 for y := 0 to Height-1 do 1045 AStream.Write(ScanLine[y]^, Width*sizeof(TBGRAPixel)); 846 1046 end; 847 1047 848 1048 {$hints off} 849 1049 procedure TBGRADefaultBitmap.Deserialize(AStream: TStream); 850 var lWidth,lHeight : integer;1050 var lWidth,lHeight,y: integer; 851 1051 begin 852 1052 AStream.Read(lWidth,sizeof(lWidth)); … … 855 1055 lHeight := LEtoN(lHeight); 856 1056 SetSize(lWidth,lHeight); 857 AStream.Read(Data^, NbPixels*sizeof(TBGRAPixel)); 1057 for y := 0 to Height-1 do 1058 AStream.Read(ScanLine[y]^, Width*sizeof(TBGRAPixel)); 858 1059 end; 859 1060 {$hints on} … … 865 1066 AStream.Write(zero,sizeof(zero)); 866 1067 AStream.Write(zero,sizeof(zero)); 867 end;868 869 procedure TBGRADefaultBitmap.LoadFromFile(const filename: string);870 var871 OldDrawMode: TDrawMode;872 begin873 OldDrawMode := CanvasDrawModeFP;874 CanvasDrawModeFP := dmSet;875 ClipRect := rect(0,0,Width,Height);876 try877 inherited LoadFromfile(filename);878 finally879 CanvasDrawModeFP := OldDrawMode;880 ClearTransparentPixels;881 end;882 1068 end; 883 1069 … … 918 1104 919 1105 { Check if a point is in the clipping rectangle } 920 function TBGRADefaultBitmap.PtInClipRect(x, y: int eger): boolean;1106 function TBGRADefaultBitmap.PtInClipRect(x, y: int32or64): boolean; 921 1107 begin 922 1108 result := (x >= FClipRect.Left) and (y >= FClipRect.Top) and (x < FClipRect.Right) and (y < FClipRect.Bottom); … … 943 1129 end; 944 1130 945 function TBGRADefaultBitmap. GetPixelCycleInline(ix, iy: integer; iFactX,946 iFactY: int eger): TBGRAPixel;947 var 948 ixMod1,ixMod2: int eger;949 w1,w2,w3,w4,alphaW: cardinal;950 bSum, gSum, rSum: cardinal;951 aSum: cardinal;1131 function TBGRADefaultBitmap.InternalGetPixelCycle256(ix, iy: int32or64; iFactX, 1132 iFactY: int32or64): TBGRAPixel; 1133 var 1134 ixMod1,ixMod2: int32or64; 1135 w1,w2,w3,w4,alphaW: UInt32or64; 1136 bSum, gSum, rSum: UInt32or64; 1137 aSum: UInt32or64; 952 1138 953 1139 c: TBGRAPixel; … … 964 1150 aSum := 0; 965 1151 966 scan := GetScanlineFast( PositiveMod(iy,Height));967 968 ixMod1 := PositiveMod(ix,Width); //apply cycle969 c := (scan + ix Mod1)^;1152 scan := GetScanlineFast(iy); 1153 1154 ixMod1 := ix; 1155 c := (scan + ix)^; 970 1156 alphaW := c.alpha * w1; 971 1157 aSum += alphaW; … … 975 1161 bSum += c.blue * alphaW; 976 1162 977 Inc(ix);978 i xMod2 := PositiveMod(ix,Width); //apply cycle1163 ixMod2 := ix+1; 1164 if ixMod2=Width then ixMod2 := 0; 979 1165 c := (scan + ixMod2)^; 980 1166 alphaW := c.alpha * w2; … … 986 1172 987 1173 Inc(iy); 988 scan := GetScanlineFast(PositiveMod(iy,Height)); 1174 if iy = Height then iy := 0; 1175 scan := GetScanlineFast(iy); 989 1176 990 1177 c := (scan + ixMod2)^; … … 1014 1201 end; 1015 1202 end; 1203 1204 function TBGRADefaultBitmap.InternalGetPixel256(ix, iy: int32or64; iFactX, 1205 iFactY: int32or64; smoothBorder: boolean): TBGRAPixel; 1206 var 1207 w1,w2,w3,w4,alphaW: cardinal; 1208 rSum, gSum, bSum: cardinal; //rgbDiv = aSum 1209 aSum, aDiv: cardinal; 1210 c: TBGRAPixel; 1211 scan: PBGRAPixel; 1212 begin 1213 rSum := 0; 1214 gSum := 0; 1215 bSum := 0; 1216 aSum := 0; 1217 aDiv := 0; 1218 1219 w4 := (iFactX*iFactY+127) shr 8; 1220 w3 := iFactY-w4; 1221 {$PUSH}{$HINTS OFF} 1222 w1 := (256-iFactX)-w3; 1223 {$POP} 1224 w2 := iFactX-w4; 1225 1226 { For each pixel around the coordinate, compute 1227 the weight for it and multiply values by it before 1228 adding to the sum } 1229 if (iy >= 0) and (iy < Height) then 1230 begin 1231 scan := GetScanlineFast(iy); 1232 1233 if (ix >= 0) and (ix < Width) then 1234 begin 1235 c := (scan + ix)^; 1236 alphaW := c.alpha * w1; 1237 aDiv += w1; 1238 aSum += alphaW; 1239 rSum += c.red * alphaW; 1240 gSum += c.green * alphaW; 1241 bSum += c.blue * alphaW; 1242 end; 1243 1244 Inc(ix); 1245 if (ix >= 0) and (ix < Width) then 1246 begin 1247 c := (scan + ix)^; 1248 alphaW := c.alpha * w2; 1249 aDiv += w2; 1250 aSum += alphaW; 1251 rSum += c.red * alphaW; 1252 gSum += c.green * alphaW; 1253 bSum += c.blue * alphaW; 1254 end; 1255 end 1256 else 1257 begin 1258 Inc(ix); 1259 end; 1260 1261 Inc(iy); 1262 if (iy >= 0) and (iy < Height) then 1263 begin 1264 scan := GetScanlineFast(iy); 1265 1266 if (ix >= 0) and (ix < Width) then 1267 begin 1268 c := (scan + ix)^; 1269 alphaW := c.alpha * w4; 1270 aDiv += w4; 1271 aSum += alphaW; 1272 rSum += c.red * alphaW; 1273 gSum += c.green * alphaW; 1274 bSum += c.blue * alphaW; 1275 end; 1276 1277 Dec(ix); 1278 if (ix >= 0) and (ix < Width) then 1279 begin 1280 c := (scan + ix)^; 1281 alphaW := c.alpha * w3; 1282 aDiv += w3; 1283 aSum += alphaW; 1284 rSum += c.red * alphaW; 1285 gSum += c.green * alphaW; 1286 bSum += c.blue * alphaW; 1287 end; 1288 end; 1289 1290 if aSum < 128 then //if there is no alpha 1291 Result := BGRAPixelTransparent 1292 else 1293 begin 1294 Result.red := (rSum + aSum shr 1) div aSum; 1295 Result.green := (gSum + aSum shr 1) div aSum; 1296 Result.blue := (bSum + aSum shr 1) div aSum; 1297 if smoothBorder or (aDiv = 256) then 1298 Result.alpha := (aSum + 128) shr 8 1299 else 1300 Result.alpha := (aSum + aDiv shr 1) div aDiv; 1301 end; 1302 end; 1303 1304 function TBGRADefaultBitmap.GetPolyLineOption: TBGRAPolyLineOptions; 1305 begin 1306 result := []; 1307 if Assigned(FArrow) and FArrow.IsStartDefined then result += [plNoStartCap]; 1308 if Assigned(FArrow) and FArrow.IsEndDefined then result += [plNoEndCap]; 1309 end; 1310 1311 function TBGRADefaultBitmap.GetArrow: TBGRAArrow; 1312 begin 1313 if FArrow = nil then 1314 begin 1315 FArrow := TBGRAArrow.Create; 1316 FArrow.LineCap := LineCap; 1317 end; 1318 result := FArrow; 1319 end; 1320 1016 1321 {-------------------------- Pixel functions -----------------------------------} 1017 1322 1018 procedure TBGRADefaultBitmap.SetPixel(x, y: int eger; c: TBGRAPixel);1323 procedure TBGRADefaultBitmap.SetPixel(x, y: int32or64; c: TBGRAPixel); 1019 1324 begin 1020 1325 if not PtInClipRect(x,y) then exit; … … 1024 1329 end; 1025 1330 1026 procedure TBGRADefaultBitmap.XorPixel(x, y: int eger; c: TBGRAPixel);1331 procedure TBGRADefaultBitmap.XorPixel(x, y: int32or64; c: TBGRAPixel); 1027 1332 var 1028 1333 p : PDWord; … … 1035 1340 end; 1036 1341 1037 procedure TBGRADefaultBitmap.SetPixel(x, y: int eger; c: TColor);1342 procedure TBGRADefaultBitmap.SetPixel(x, y: int32or64; c: TColor); 1038 1343 var 1039 1344 p: PByte; … … 1052 1357 end; 1053 1358 1054 procedure TBGRADefaultBitmap.DrawPixel(x, y: int eger; c: TBGRAPixel);1359 procedure TBGRADefaultBitmap.DrawPixel(x, y: int32or64; c: TBGRAPixel); 1055 1360 begin 1056 1361 if not PtInClipRect(x,y) then exit; … … 1060 1365 end; 1061 1366 1062 procedure TBGRADefaultBitmap.DrawPixel(x, y: int eger; ec: TExpandedPixel);1367 procedure TBGRADefaultBitmap.DrawPixel(x, y: int32or64; ec: TExpandedPixel); 1063 1368 begin 1064 1369 if not PtInClipRect(x,y) then exit; … … 1068 1373 end; 1069 1374 1070 procedure TBGRADefaultBitmap.FastBlendPixel(x, y: int eger; c: TBGRAPixel);1375 procedure TBGRADefaultBitmap.FastBlendPixel(x, y: int32or64; c: TBGRAPixel); 1071 1376 begin 1072 1377 if not PtInClipRect(x,y) then exit; … … 1076 1381 end; 1077 1382 1078 procedure TBGRADefaultBitmap.ErasePixel(x, y: int eger; alpha: byte);1383 procedure TBGRADefaultBitmap.ErasePixel(x, y: int32or64; alpha: byte); 1079 1384 begin 1080 1385 if not PtInClipRect(x,y) then exit; … … 1084 1389 end; 1085 1390 1086 procedure TBGRADefaultBitmap.AlphaPixel(x, y: int eger; alpha: byte);1391 procedure TBGRADefaultBitmap.AlphaPixel(x, y: int32or64; alpha: byte); 1087 1392 begin 1088 1393 if not PtInClipRect(x,y) then exit; … … 1095 1400 end; 1096 1401 1097 function TBGRADefaultBitmap.GetPixel(x, y: int eger): TBGRAPixel;1402 function TBGRADefaultBitmap.GetPixel(x, y: int32or64): TBGRAPixel; 1098 1403 begin 1099 1404 if (x < 0) or (x >= Width) or (y < 0) or (y >= Height) then //it is possible to read pixels outside of the cliprect … … 1106 1411 end; 1107 1412 1413 function TBGRADefaultBitmap.GetPixel256(x, y, fracX256, fracY256: int32or64; 1414 AResampleFilter: TResampleFilter; smoothBorder: boolean = true): TBGRAPixel; 1415 begin 1416 if (fracX256 = 0) and (fracY256 = 0) then 1417 result := GetPixel(x,y) 1418 else if AResampleFilter = rfBox then 1419 begin 1420 if fracX256 >= 128 then inc(x); 1421 if fracY256 >= 128 then inc(y); 1422 result := GetPixel(x,y); 1423 end else 1424 begin 1425 LoadFromBitmapIfNeeded; 1426 result := InternalGetPixel256(x,y,FineInterpolation256(fracX256,AResampleFilter),FineInterpolation256(fracY256,AResampleFilter),smoothBorder); 1427 end; 1428 end; 1429 1108 1430 {$hints off} 1109 1431 { This function compute an interpolated pixel at floating point coordinates } 1110 function TBGRADefaultBitmap.GetPixel(x, y: single; AResampleFilter: TResampleFilter = rfLinear): TBGRAPixel; 1111 var 1112 ix, iy: integer; 1113 w1,w2,w3,w4,alphaW: cardinal; 1114 rSum, gSum, bSum: cardinal; //rgbDiv = aSum 1115 aSum: cardinal; 1116 c: TBGRAPixel; 1117 scan: PBGRAPixel; 1118 factX,factY: single; 1119 iFactX,iFactY: integer; 1120 begin 1121 ix := floor(x); 1122 iy := floor(y); 1123 factX := x-ix; //distance from integer coordinate 1124 factY := y-iy; 1432 function TBGRADefaultBitmap.GetPixel(x, y: single; AResampleFilter: TResampleFilter = rfLinear; smoothBorder: boolean = true): TBGRAPixel; 1433 var 1434 ix, iy: Int32or64; 1435 iFactX,iFactY: Int32or64; 1436 begin 1437 ix := round(x*256); 1438 if (ix<= -256) or (ix>=Width shl 8) then 1439 begin 1440 result := BGRAPixelTransparent; 1441 exit; 1442 end; 1443 iy := round(y*256); 1444 if (iy<= -256) or (iy>=Height shl 8) then 1445 begin 1446 result := BGRAPixelTransparent; 1447 exit; 1448 end; 1449 1450 iFactX := ix and 255; //distance from integer coordinate 1451 iFactY := iy and 255; 1452 if ix<0 then ix := -1 else ix := ix shr 8; 1453 if iy<0 then iy := -1 else iy := iy shr 8; 1125 1454 1126 1455 //if the coordinate is integer, then call standard GetPixel function 1127 if ( factX = 0) and (factY = 0) then1128 begin 1129 Result := GetPixel(ix, iy);1456 if (iFactX = 0) and (iFactY = 0) then 1457 begin 1458 Result := (GetScanlineFast(iy)+ix)^; 1130 1459 exit; 1131 1460 end; 1461 1132 1462 LoadFromBitmapIfNeeded; 1133 1134 rSum := 0; 1135 gSum := 0; 1136 bSum := 0; 1137 aSum := 0; 1138 1139 //apply interpolation filter 1140 factX := FineInterpolation( factX, AResampleFilter ); 1141 factY := FineInterpolation( factY, AResampleFilter ); 1142 1143 iFactX := round(factX*256); //integer values for fractionnal part 1144 iFactY := round(factY*256); 1145 1146 w4 := (iFactX*iFactY+127) shr 8; 1147 w3 := iFactY-w4; 1148 w1 := (256-iFactX)-w3; 1149 w2 := iFactX-w4; 1150 1151 { For each pixel around the coordinate, compute 1152 the weight for it and multiply values by it before 1153 adding to the sum } 1154 if (iy >= 0) and (iy < Height) then 1155 begin 1156 scan := GetScanlineFast(iy); 1157 1158 if (ix >= 0) and (ix < Width) then 1159 begin 1160 c := (scan + ix)^; 1161 alphaW := c.alpha * w1; 1162 aSum += alphaW; 1163 rSum += c.red * alphaW; 1164 gSum += c.green * alphaW; 1165 bSum += c.blue * alphaW; 1166 end; 1167 1168 Inc(ix); 1169 if (ix >= 0) and (ix < Width) then 1170 begin 1171 c := (scan + ix)^; 1172 alphaW := c.alpha * w2; 1173 aSum += alphaW; 1174 rSum += c.red * alphaW; 1175 gSum += c.green * alphaW; 1176 bSum += c.blue * alphaW; 1177 end; 1178 end 1179 else 1180 begin 1181 Inc(ix); 1182 end; 1183 1184 Inc(iy); 1185 if (iy >= 0) and (iy < Height) then 1186 begin 1187 scan := GetScanlineFast(iy); 1188 1189 if (ix >= 0) and (ix < Width) then 1190 begin 1191 c := (scan + ix)^; 1192 alphaW := c.alpha * w4; 1193 aSum += alphaW; 1194 rSum += c.red * alphaW; 1195 gSum += c.green * alphaW; 1196 bSum += c.blue * alphaW; 1197 end; 1198 1199 Dec(ix); 1200 if (ix >= 0) and (ix < Width) then 1201 begin 1202 c := (scan + ix)^; 1203 alphaW := c.alpha * w3; 1204 aSum += alphaW; 1205 rSum += c.red * alphaW; 1206 gSum += c.green * alphaW; 1207 bSum += c.blue * alphaW; 1208 end; 1209 end; 1210 1211 if aSum < 128 then //if there is no alpha 1212 Result := BGRAPixelTransparent 1213 else 1214 begin 1215 Result.red := (rSum + aSum shr 1) div aSum; 1216 Result.green := (gSum + aSum shr 1) div aSum; 1217 Result.blue := (bSum + aSum shr 1) div aSum; 1218 Result.alpha := (aSum + 128) shr 8; 1219 end; 1463 result := InternalGetPixel256(ix,iy,FineInterpolation256(iFactX,AResampleFilter),FineInterpolation256(iFactY,AResampleFilter),smoothBorder); 1220 1464 end; 1221 1465 … … 1223 1467 function TBGRADefaultBitmap.GetPixelCycle(x, y: single; AResampleFilter: TResampleFilter = rfLinear): TBGRAPixel; 1224 1468 var 1225 ix, iy: integer; 1226 iFactX,iFactY: integer; 1227 begin 1469 ix, iy: Int32or64; 1470 iFactX,iFactY: Int32or64; 1471 begin 1472 if FData = nil then 1473 begin 1474 result := BGRAPixelTransparent; 1475 exit; 1476 end; 1228 1477 LoadFromBitmapIfNeeded; 1229 iFactX := round(x*256); 1230 iFactY := round(y*256); 1231 ix := (iFactX shr 8)+ScanOffset.X; 1232 iy := (iFactY shr 8)+ScanOffset.Y; 1233 iFactX := iFactX and 255; 1234 iFactY := iFactY and 255; 1235 1478 ix := round(x*256); 1479 iy := round(y*256); 1480 iFactX := ix and 255; 1481 iFactY := iy and 255; 1482 ix := PositiveMod(ix, FWidth shl 8) shr 8; 1483 iy := PositiveMod(iy, FHeight shl 8) shr 8; 1236 1484 if (iFactX = 0) and (iFactY = 0) then 1237 1485 begin 1238 result := ( ScanLine[PositiveMod(iy, FHeight)]+PositiveMod(ix, FWidth))^;1486 result := (GetScanlineFast(iy)+ix)^; 1239 1487 exit; 1240 1488 end; 1241 1242 1489 if ScanInterpolationFilter <> rfLinear then 1243 1490 begin … … 1245 1492 iFactY := FineInterpolation256( iFactY, ScanInterpolationFilter ); 1246 1493 end; 1247 1248 result := GetPixelCycleInline(ix,iy, iFactX,iFactY); 1494 result := InternalGetPixelCycle256(ix,iy, iFactX,iFactY); 1249 1495 end; 1250 1496 … … 1253 1499 ): TBGRAPixel; 1254 1500 var 1255 alpha: byte; 1256 begin 1257 alpha := 255; 1258 if not repeatX then 1259 begin 1260 if (x < -0.5) or (x > Width-0.5) then 1261 begin 1262 result := BGRAPixelTransparent; 1263 exit; 1501 ix, iy: Int32or64; 1502 iFactX,iFactY: Int32or64; 1503 begin 1504 if FData = nil then 1505 begin 1506 result := BGRAPixelTransparent; 1507 exit; 1508 end; 1509 ix := round(x*256); 1510 iy := round(y*256); 1511 iFactX := ix and 255; 1512 iFactY := iy and 255; 1513 if ix < 0 then ix := -((iFactX-ix) shr 8) 1514 else ix := ix shr 8; 1515 if iy < 0 then iy := -((iFactY-iy) shr 8) 1516 else iy := iy shr 8; 1517 result := GetPixelCycle256(ix,iy,iFactX,iFactY,AResampleFilter,repeatX,repeatY); 1518 end; 1519 1520 function TBGRADefaultBitmap.GetPixelCycle256(x, y, fracX256, 1521 fracY256: int32or64; AResampleFilter: TResampleFilter): TBGRAPixel; 1522 begin 1523 if (fracX256 = 0) and (fracY256 = 0) then 1524 result := GetPixelCycle(x,y) 1525 else if AResampleFilter = rfBox then 1526 begin 1527 if fracX256 >= 128 then inc(x); 1528 if fracY256 >= 128 then inc(y); 1529 result := GetPixelCycle(x,y); 1530 end else 1531 begin 1532 LoadFromBitmapIfNeeded; 1533 result := InternalGetPixelCycle256(PositiveMod(x,FWidth),PositiveMod(y,FHeight),FineInterpolation256(fracX256,AResampleFilter),FineInterpolation256(fracY256,AResampleFilter)); 1534 end; 1535 end; 1536 1537 function TBGRADefaultBitmap.GetPixelCycle256(x, y, fracX256, 1538 fracY256: int32or64; AResampleFilter: TResampleFilter; repeatX: boolean; 1539 repeatY: boolean): TBGRAPixel; 1540 begin 1541 if not repeatX and not repeatY then 1542 result := GetPixel256(x,y,fracX256,fracY256,AResampleFilter) 1543 else if repeatX and repeatY then 1544 result := GetPixelCycle256(x,y,fracX256,fracY256,AResampleFilter) 1545 else 1546 begin 1547 if not repeatX then 1548 begin 1549 if x < 0 then 1550 begin 1551 if x < -1 then 1552 begin 1553 result := BGRAPixelTransparent; 1554 exit; 1555 end; 1556 result := GetPixelCycle256(0,y,0,fracY256,AResampleFilter); 1557 result.alpha:= result.alpha*fracX256 shr 8; 1558 if result.alpha = 0 then 1559 result := BGRAPixelTransparent; 1560 exit; 1561 end; 1562 if x >= FWidth-1 then 1563 begin 1564 if x >= FWidth then 1565 begin 1566 result := BGRAPixelTransparent; 1567 exit; 1568 end; 1569 result := GetPixelCycle256(FWidth-1,y,0,fracY256,AResampleFilter); 1570 result.alpha:= result.alpha*(256-fracX256) shr 8; 1571 if result.alpha = 0 then 1572 result := BGRAPixelTransparent; 1573 exit; 1574 end; 1575 end else 1576 begin 1577 if y < 0 then 1578 begin 1579 if y < -1 then 1580 begin 1581 result := BGRAPixelTransparent; 1582 exit; 1583 end; 1584 result := GetPixelCycle256(x,0,fracX256,0,AResampleFilter); 1585 result.alpha:= result.alpha*fracY256 shr 8; 1586 if result.alpha = 0 then 1587 result := BGRAPixelTransparent; 1588 exit; 1589 end; 1590 if y >= FHeight-1 then 1591 begin 1592 if y >= FHeight then 1593 begin 1594 result := BGRAPixelTransparent; 1595 exit; 1596 end; 1597 result := GetPixelCycle256(x,FHeight-1,fracX256,0,AResampleFilter); 1598 result.alpha:= result.alpha*(256-fracY256) shr 8; 1599 if result.alpha = 0 then 1600 result := BGRAPixelTransparent; 1601 exit; 1602 end; 1264 1603 end; 1265 if x < 0 then 1266 begin 1267 alpha := round((0.5+x)*510); 1268 x := 0; 1269 end 1270 else 1271 if x > Width-1 then 1272 begin 1273 alpha := round((Width-0.5-x)*510); 1274 x := Width-1; 1275 end; 1276 end; 1277 if not repeatY then 1278 begin 1279 if (y < -0.5) or (y > Height-0.5) then 1280 begin 1281 result := BGRAPixelTransparent; 1282 exit; 1283 end; 1284 if y < 0 then 1285 begin 1286 alpha := round((0.5+y)*2*alpha); 1287 y := 0; 1288 end 1289 else 1290 if y > Height-1 then 1291 begin 1292 alpha := round((Height-0.5-y)*2*alpha); 1293 y := Height-1; 1294 end; 1295 end; 1296 result := GetPixelCycle(x,y,AResampleFilter); 1297 if alpha<>255 then 1298 result.alpha := ApplyOpacity(result.alpha,alpha); 1604 result := GetPixelCycle256(x,y,fracX256,fracY256,AResampleFilter); 1605 end; 1299 1606 end; 1300 1607 … … 1540 1847 (ARawImage.Description.BlueShift = 8) and 1541 1848 (ARawImage.Description.ByteOrder = riboMSBFirst)) then 1542 mustSwapRedBlue:= true 1849 begin 1850 mustSwapRedBlue:= true; 1851 mustReverse32 := false; 1852 end 1543 1853 else 1544 1854 begin … … 1655 1965 end; 1656 1966 1967 procedure TBGRADefaultBitmap.CrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadePosition: byte; mode: TDrawMode = dmDrawWithTransparency); 1968 var constScanner: TBGRAConstantScanner; 1969 begin 1970 if AFadePosition = 0 then 1971 FillRect(ARect, Source1, mode) else 1972 if AFadePosition = 255 then 1973 FillRect(ARect, Source2, mode) else 1974 begin 1975 constScanner := TBGRAConstantScanner.Create(BGRA(AFadePosition,AFadePosition,AFadePosition,255)); 1976 CrossFade(ARect, Source1,Source2, constScanner, mode); 1977 constScanner.Free; 1978 end; 1979 end; 1980 1981 procedure TBGRADefaultBitmap.CrossFade(ARect: TRect; Source1, Source2: IBGRAScanner; AFadeMask: IBGRAScanner; mode: TDrawMode = dmDrawWithTransparency); 1982 var xb,yb: NativeInt; 1983 pdest: PBGRAPixel; 1984 c: TBGRAPixel; 1985 fadePos: byte; 1986 begin 1987 if not IntersectRect(ARect,ARect,ClipRect) then exit; 1988 for yb := ARect.top to ARect.Bottom-1 do 1989 begin 1990 pdest := GetScanlineFast(yb)+ARect.Left; 1991 Source1.ScanMoveTo(ARect.left, yb); 1992 Source2.ScanMoveTo(ARect.left, yb); 1993 AFadeMask.ScanMoveTo(ARect.left, yb); 1994 for xb := ARect.left to ARect.Right-1 do 1995 begin 1996 fadePos := AFadeMask.ScanNextPixel.green; 1997 c := MergeBGRAWithGammaCorrection(Source1.ScanNextPixel,not fadePos,Source2.ScanNextPixel,fadePos); 1998 case mode of 1999 dmSet: pdest^ := c; 2000 dmDrawWithTransparency: DrawPixelInlineWithAlphaCheck(pdest, c); 2001 dmLinearBlend: FastBlendPixelInline(pdest,c); 2002 dmSetExceptTransparent: if c.alpha = 255 then pdest^ := c; 2003 end; 2004 inc(pdest); 2005 end; 2006 end; 2007 InvalidateBitmap; 2008 end; 2009 1657 2010 procedure TBGRADefaultBitmap.DiscardBitmapChange; inline; 1658 2011 begin … … 1677 2030 FillMode := fmWinding; 1678 2031 1679 FFont := TFont.Create;1680 2032 FontName := 'Arial'; 1681 2033 FontStyle := []; 1682 2034 FontAntialias := False; 1683 2035 FFontHeight := 20; 1684 FFontHeightSign := GetFontHeightSign(FFont);1685 2036 1686 2037 PenStyle := psSolid; … … 1756 2107 {---------------------------- Line primitives ---------------------------------} 1757 2108 1758 function TBGRADefaultBitmap.CheckHorizLineBounds(var x,y,x2: int eger): boolean; inline;1759 var 1760 temp: int eger;2109 function TBGRADefaultBitmap.CheckHorizLineBounds(var x,y,x2: int32or64): boolean; inline; 2110 var 2111 temp: int32or64; 1761 2112 begin 1762 2113 if (x2 < x) then … … 1778 2129 end; 1779 2130 1780 procedure TBGRADefaultBitmap.SetHorizLine(x, y, x2: int eger; c: TBGRAPixel);2131 procedure TBGRADefaultBitmap.SetHorizLine(x, y, x2: int32or64; c: TBGRAPixel); 1781 2132 begin 1782 2133 if not CheckHorizLineBounds(x,y,x2) then exit; … … 1785 2136 end; 1786 2137 1787 procedure TBGRADefaultBitmap.XorHorizLine(x, y, x2: int eger; c: TBGRAPixel);2138 procedure TBGRADefaultBitmap.XorHorizLine(x, y, x2: int32or64; c: TBGRAPixel); 1788 2139 begin 1789 2140 if not CheckHorizLineBounds(x,y,x2) then exit; … … 1792 2143 end; 1793 2144 1794 procedure TBGRADefaultBitmap.DrawHorizLine(x, y, x2: int eger; c: TBGRAPixel);2145 procedure TBGRADefaultBitmap.DrawHorizLine(x, y, x2: int32or64; c: TBGRAPixel); 1795 2146 begin 1796 2147 if not CheckHorizLineBounds(x,y,x2) then exit; … … 1799 2150 end; 1800 2151 1801 procedure TBGRADefaultBitmap.DrawHorizLine(x, y, x2: int eger; ec: TExpandedPixel2152 procedure TBGRADefaultBitmap.DrawHorizLine(x, y, x2: int32or64; ec: TExpandedPixel 1802 2153 ); 1803 2154 begin … … 1807 2158 end; 1808 2159 1809 procedure TBGRADefaultBitmap. DrawHorizLine(x, y, x2: integer;1810 texture: IBGRAScanner );2160 procedure TBGRADefaultBitmap.HorizLine(x, y, x2: int32or64; 2161 texture: IBGRAScanner; ADrawMode : TDrawMode); 1811 2162 begin 1812 2163 if not CheckHorizLineBounds(x,y,x2) then exit; 1813 2164 texture.ScanMoveTo(x,y); 1814 ScannerPutPixels(texture,scanline[y] + x, x2 - x + 1, dmDrawWithTransparency);2165 ScannerPutPixels(texture,scanline[y] + x, x2 - x + 1,ADrawMode); 1815 2166 InvalidateBitmap; 1816 2167 end; 1817 2168 1818 procedure TBGRADefaultBitmap.FastBlendHorizLine(x, y, x2: int eger; c: TBGRAPixel);2169 procedure TBGRADefaultBitmap.FastBlendHorizLine(x, y, x2: int32or64; c: TBGRAPixel); 1819 2170 begin 1820 2171 if not CheckHorizLineBounds(x,y,x2) then exit; … … 1823 2174 end; 1824 2175 1825 procedure TBGRADefaultBitmap.AlphaHorizLine(x, y, x2: int eger; alpha: byte);2176 procedure TBGRADefaultBitmap.AlphaHorizLine(x, y, x2: int32or64; alpha: byte); 1826 2177 begin 1827 2178 if alpha = 0 then … … 1835 2186 end; 1836 2187 1837 function TBGRADefaultBitmap.CheckVertLineBounds(var x,y,y2: int eger; out delta: integer): boolean; inline;1838 var 1839 temp: int eger;2188 function TBGRADefaultBitmap.CheckVertLineBounds(var x,y,y2: int32or64; out delta: int32or64): boolean; inline; 2189 var 2190 temp: int32or64; 1840 2191 begin 1841 2192 if FLineOrder = riloBottomToTop then … … 1865 2216 end; 1866 2217 1867 procedure TBGRADefaultBitmap.SetVertLine(x, y, y2: int eger; c: TBGRAPixel);1868 var 1869 n, delta: int eger;2218 procedure TBGRADefaultBitmap.SetVertLine(x, y, y2: int32or64; c: TBGRAPixel); 2219 var 2220 n, delta: int32or64; 1870 2221 p: PBGRAPixel; 1871 2222 begin … … 1880 2231 end; 1881 2232 1882 procedure TBGRADefaultBitmap.XorVertLine(x, y, y2: int eger; c: TBGRAPixel);1883 var 1884 n, delta: int eger;2233 procedure TBGRADefaultBitmap.XorVertLine(x, y, y2: int32or64; c: TBGRAPixel); 2234 var 2235 n, delta: int32or64; 1885 2236 p: PBGRAPixel; 1886 2237 begin … … 1895 2246 end; 1896 2247 1897 procedure TBGRADefaultBitmap.DrawVertLine(x, y, y2: int eger; c: TBGRAPixel);1898 var 1899 n, delta: int eger;2248 procedure TBGRADefaultBitmap.DrawVertLine(x, y, y2: int32or64; c: TBGRAPixel); 2249 var 2250 n, delta: int32or64; 1900 2251 p: PBGRAPixel; 1901 2252 begin … … 1915 2266 end; 1916 2267 1917 procedure TBGRADefaultBitmap.AlphaVertLine(x, y, y2: int eger; alpha: byte);1918 var 1919 n, delta: int eger;2268 procedure TBGRADefaultBitmap.AlphaVertLine(x, y, y2: int32or64; alpha: byte); 2269 var 2270 n, delta: int32or64; 1920 2271 p: PBGRAPixel; 1921 2272 begin … … 1935 2286 end; 1936 2287 1937 procedure TBGRADefaultBitmap.FastBlendVertLine(x, y, y2: int eger; c: TBGRAPixel);1938 var 1939 n, delta: int eger;2288 procedure TBGRADefaultBitmap.FastBlendVertLine(x, y, y2: int32or64; c: TBGRAPixel); 2289 var 2290 n, delta: int32or64; 1940 2291 p: PBGRAPixel; 1941 2292 begin … … 1950 2301 end; 1951 2302 1952 procedure TBGRADefaultBitmap.DrawHorizLineDiff(x, y, x2: int eger;2303 procedure TBGRADefaultBitmap.DrawHorizLineDiff(x, y, x2: int32or64; 1953 2304 c, compare: TBGRAPixel; maxDiff: byte); 1954 2305 begin … … 1958 2309 end; 1959 2310 2311 procedure TBGRADefaultBitmap.SetArrowStart(AStyle: TBGRAArrowStyle; 2312 ATipStyle: TPenJoinStyle; ARelativePenWidth: single; ATriangleBackOffset: single); 2313 begin 2314 GetArrow.SetStart(AStyle,ATipStyle,ARelativePenWidth,ATriangleBackOffset); 2315 end; 2316 2317 procedure TBGRADefaultBitmap.SetArrowEnd(AStyle: TBGRAArrowStyle; 2318 ATipStyle: TPenJoinStyle; ARelativePenWidth: single; ATriangleBackOffset: single); 2319 begin 2320 GetArrow.SetEnd(AStyle,ATipStyle,ARelativePenWidth,ATriangleBackOffset); 2321 end; 2322 2323 procedure TBGRADefaultBitmap.DrawPath(APath: IBGRAPath; c: TBGRAPixel; w: single); 2324 var tempCanvas: TBGRACanvas2D; 2325 begin 2326 tempCanvas:= TBGRACanvas2D.Create(self); 2327 tempCanvas.strokeStyle(c); 2328 tempCanvas.lineWidth := w; 2329 tempCanvas.lineStyle(CustomPenStyle); 2330 tempCanvas.lineCapLCL := LineCap; 2331 tempCanvas.lineJoinLCL := JoinStyle; 2332 tempCanvas.path(APath); 2333 tempCanvas.stroke; 2334 tempCanvas.Free; 2335 end; 2336 2337 procedure TBGRADefaultBitmap.DrawPath(APath: IBGRAPath; texture: IBGRAScanner; w: single); 2338 var tempCanvas: TBGRACanvas2D; 2339 begin 2340 tempCanvas:= TBGRACanvas2D.Create(self); 2341 tempCanvas.strokeStyle(texture); 2342 tempCanvas.lineWidth := w; 2343 tempCanvas.lineStyle(CustomPenStyle); 2344 tempCanvas.lineCapLCL := LineCap; 2345 tempCanvas.lineJoinLCL := JoinStyle; 2346 tempCanvas.path(APath); 2347 tempCanvas.stroke; 2348 tempCanvas.Free; 2349 end; 2350 1960 2351 {---------------------------- Lines ---------------------------------} 1961 2352 { Call appropriate functions } 1962 2353 1963 2354 procedure TBGRADefaultBitmap.DrawLine(x1, y1, x2, y2: integer; 1964 c: TBGRAPixel; DrawLastPixel: boolean );1965 begin 1966 BGRADrawLineAliased(self,x1,y1,x2,y2,c,DrawLastPixel );2355 c: TBGRAPixel; DrawLastPixel: boolean; ADrawMode: TDrawMode); 2356 begin 2357 BGRADrawLineAliased(self,x1,y1,x2,y2,c,DrawLastPixel,ADrawMode); 1967 2358 end; 1968 2359 … … 1970 2361 c: TBGRAPixel; DrawLastPixel: boolean); 1971 2362 begin 1972 BGRADrawLineAntialias(self,x1,y1,x2,y2,c,DrawLastPixel );2363 BGRADrawLineAntialias(self,x1,y1,x2,y2,c,DrawLastPixel,LinearAntialiasing); 1973 2364 end; 1974 2365 … … 1978 2369 begin 1979 2370 DashPos := 0; 1980 BGRADrawLineAntialias(self,x1,y1,x2,y2,c1,c2,dashLen,DrawLastPixel,DashPos );2371 BGRADrawLineAntialias(self,x1,y1,x2,y2,c1,c2,dashLen,DrawLastPixel,DashPos,LinearAntialiasing); 1981 2372 end; 1982 2373 … … 1984 2375 c2: TBGRAPixel; dashLen: integer; DrawLastPixel: boolean; var DashPos: integer); 1985 2376 begin 1986 BGRADrawLineAntialias(self,x1,y1,x2,y2,c1,c2,dashLen,DrawLastPixel,DashPos );2377 BGRADrawLineAntialias(self,x1,y1,x2,y2,c1,c2,dashLen,DrawLastPixel,DashPos,LinearAntialiasing); 1987 2378 end; 1988 2379 … … 1990 2381 c: TBGRAPixel; w: single); 1991 2382 begin 1992 BGRAPolyLine(self,[PointF(x1,y1),PointF(x2,y2)],w,c,LineCap,JoinStyle,FCustomPenStyle,[],nil,JoinMiterLimit); 2383 if Assigned(FArrow) then 2384 BGRAPen.BGRAPolyLine(self,[PointF(x1,y1),PointF(x2,y2)],w,c,LineCap,JoinStyle,FCustomPenStyle,GetPolyLineOption,nil,JoinMiterLimit,@FArrow.ComputeStartAt,FArrow.StartOffsetX,@FArrow.ComputeEndAt,FArrow.EndOffsetX) 2385 else 2386 BGRAPen.BGRAPolyLine(self,[PointF(x1,y1),PointF(x2,y2)],w,c,LineCap,JoinStyle,FCustomPenStyle,GetPolyLineOption,nil,JoinMiterLimit); 1993 2387 end; 1994 2388 … … 1996 2390 texture: IBGRAScanner; w: single); 1997 2391 begin 1998 BGRAPolyLine(self,[PointF(x1,y1),PointF(x2,y2)],w,BGRAPixelTransparent,LineCap,JoinStyle,FCustomPenStyle,[],texture,JoinMiterLimit); 2392 if Assigned(FArrow) then 2393 BGRAPen.BGRAPolyLine(self,[PointF(x1,y1),PointF(x2,y2)],w,BGRAPixelTransparent,LineCap,JoinStyle,FCustomPenStyle,GetPolyLineOption,texture,JoinMiterLimit,@FArrow.ComputeStartAt,FArrow.StartOffsetX,@FArrow.ComputeEndAt,FArrow.EndOffsetX) 2394 else 2395 BGRAPen.BGRAPolyLine(self,[PointF(x1,y1),PointF(x2,y2)],w,BGRAPixelTransparent,LineCap,JoinStyle,FCustomPenStyle,GetPolyLineOption,texture,JoinMiterLimit); 1999 2396 end; 2000 2397 2001 2398 procedure TBGRADefaultBitmap.DrawLineAntialias(x1, y1, x2, y2: single; 2002 c: TBGRAPixel; w: single; closed: boolean);2399 c: TBGRAPixel; w: single; Closed: boolean); 2003 2400 var 2004 2401 options: TBGRAPolyLineOptions; 2005 2402 begin 2006 2403 if not closed then options := [plRoundCapOpen] else options := []; 2007 BGRAPolyLine(self,[PointF(x1,y1),PointF(x2,y2)],w,c,pecRound,pjsRound,FCustomPenStyle,options,nil,JoinMiterLimit); 2404 options += GetPolyLineOption; 2405 if Assigned(FArrow) then 2406 BGRAPen.BGRAPolyLine(self,[PointF(x1,y1),PointF(x2,y2)],w,c,pecRound,pjsRound,FCustomPenStyle,options,nil,JoinMiterLimit,@FArrow.ComputeStartAt,FArrow.StartOffsetX,@FArrow.ComputeEndAt,FArrow.EndOffsetX) 2407 else 2408 BGRAPen.BGRAPolyLine(self,[PointF(x1,y1),PointF(x2,y2)],w,c,pecRound,pjsRound,FCustomPenStyle,options,nil,JoinMiterLimit) 2008 2409 end; 2009 2410 … … 2023 2424 c := BGRAPixelTransparent; 2024 2425 end; 2025 BGRAPolyLine(self,[PointF(x1,y1),PointF(x2,y2)],w,c,pecRound,pjsRound,FCustomPenStyle,options,texture,JoinMiterLimit); 2426 options += GetPolyLineOption; 2427 if Assigned(FArrow) then 2428 BGRAPen.BGRAPolyLine(self,[PointF(x1,y1),PointF(x2,y2)],w,c,pecRound,pjsRound,FCustomPenStyle,options,texture,JoinMiterLimit,@FArrow.ComputeStartAt,FArrow.StartOffsetX,@FArrow.ComputeEndAt,FArrow.EndOffsetX) 2429 else 2430 BGRAPen.BGRAPolyLine(self,[PointF(x1,y1),PointF(x2,y2)],w,c,pecRound,pjsRound,FCustomPenStyle,options,texture,JoinMiterLimit); 2026 2431 end; 2027 2432 … … 2029 2434 c: TBGRAPixel; w: single); 2030 2435 begin 2031 BGRAPolyLine(self,points,w,c,LineCap,JoinStyle,FCustomPenStyle,[],nil,JoinMiterLimit); 2436 if Assigned(FArrow) then 2437 BGRAPen.BGRAPolyLine(self,points,w,c,LineCap,JoinStyle,FCustomPenStyle,GetPolyLineOption,nil,JoinMiterLimit,@FArrow.ComputeStartAt,FArrow.StartOffsetX,@FArrow.ComputeEndAt,FArrow.EndOffsetX) 2438 else 2439 BGRAPen.BGRAPolyLine(self,points,w,c,LineCap,JoinStyle,FCustomPenStyle,GetPolyLineOption,nil,JoinMiterLimit) 2032 2440 end; 2033 2441 … … 2035 2443 const points: array of TPointF; texture: IBGRAScanner; w: single); 2036 2444 begin 2037 BGRAPolyLine(self,points,w,BGRAPixelTransparent,LineCap,JoinStyle,FCustomPenStyle,[],texture,JoinMiterLimit); 2445 if Assigned(FArrow) then 2446 BGRAPen.BGRAPolyLine(self,points,w,BGRAPixelTransparent,LineCap,JoinStyle,FCustomPenStyle,GetPolyLineOption,texture,JoinMiterLimit,@FArrow.ComputeStartAt,FArrow.StartOffsetX,@FArrow.ComputeEndAt,FArrow.EndOffsetX) 2447 else 2448 BGRAPen.BGRAPolyLine(self,points,w,BGRAPixelTransparent,LineCap,JoinStyle,FCustomPenStyle,GetPolyLineOption,texture,JoinMiterLimit); 2038 2449 end; 2039 2450 … … 2044 2455 begin 2045 2456 if not closed then options := [plRoundCapOpen] else options := []; 2046 BGRAPolyLine(self,points,w,c,pecRound,JoinStyle,FCustomPenStyle,options,nil,JoinMiterLimit); 2457 options += GetPolyLineOption; 2458 if Assigned(FArrow) then 2459 BGRAPen.BGRAPolyLine(self,points,w,c,pecRound,JoinStyle,FCustomPenStyle,options,nil,JoinMiterLimit,@FArrow.ComputeStartAt,FArrow.StartOffsetX,@FArrow.ComputeEndAt,FArrow.EndOffsetX) 2460 else 2461 BGRAPen.BGRAPolyLine(self,points,w,c,pecRound,JoinStyle,FCustomPenStyle,options,nil,JoinMiterLimit); 2462 end; 2463 2464 procedure TBGRADefaultBitmap.DrawPolyLineAntialias( 2465 const points: array of TPointF; c: TBGRAPixel; w: single; 2466 fillcolor: TBGRAPixel); 2467 var multi: TBGRAMultishapeFiller; 2468 begin 2469 multi := TBGRAMultishapeFiller.Create; 2470 multi.PolygonOrder := poLastOnTop; 2471 multi.AddPolygon(points,fillcolor); 2472 multi.AddPolygon(ComputeWidePolyline(points,w),c); 2473 if LinearAntialiasing then 2474 multi.Draw(self,dmLinearBlend) 2475 else 2476 multi.Draw(self,dmDrawWithTransparency); 2477 multi.Free; 2047 2478 end; 2048 2479 … … 2050 2481 c: TBGRAPixel; w: single); 2051 2482 begin 2052 2483 BGRAPolyLine(self,points,w,c,LineCap,JoinStyle,FCustomPenStyle,[plCycle],nil,JoinMiterLimit); 2053 2484 end; 2054 2485 … … 2057 2488 begin 2058 2489 BGRAPolyLine(self,points,w,BGRAPixelTransparent,LineCap,JoinStyle,FCustomPenStyle,[plCycle],texture,JoinMiterLimit); 2490 end; 2491 2492 procedure TBGRADefaultBitmap.DrawPolygonAntialias( 2493 const points: array of TPointF; c: TBGRAPixel; w: single; 2494 fillcolor: TBGRAPixel); 2495 var multi: TBGRAMultishapeFiller; 2496 begin 2497 multi := TBGRAMultishapeFiller.Create; 2498 multi.PolygonOrder := poLastOnTop; 2499 multi.AddPolygon(points,fillcolor); 2500 multi.AddPolygon(ComputeWidePolygon(points,w),c); 2501 if LinearAntialiasing then 2502 multi.Draw(self,dmLinearBlend) 2503 else 2504 multi.Draw(self,dmDrawWithTransparency); 2505 multi.Free; 2059 2506 end; 2060 2507 … … 2085 2532 DrawPolyLineAntialias(points, BGRA(0,0,0,alpha),w); 2086 2533 FEraseMode := False; 2534 end; 2535 2536 procedure TBGRADefaultBitmap.FillPath(APath: IBGRAPath; c: TBGRAPixel); 2537 var tempCanvas: TBGRACanvas2D; 2538 begin 2539 tempCanvas:= TBGRACanvas2D.Create(self); 2540 tempCanvas.fillStyle(c); 2541 tempCanvas.path(APath); 2542 tempCanvas.fill; 2543 tempCanvas.Free; 2544 end; 2545 2546 procedure TBGRADefaultBitmap.FillPath(APath: IBGRAPath; texture: IBGRAScanner); 2547 var tempCanvas: TBGRACanvas2D; 2548 begin 2549 tempCanvas:= TBGRACanvas2D.Create(self); 2550 tempCanvas.fillStyle(texture); 2551 tempCanvas.path(APath); 2552 tempCanvas.fill; 2553 tempCanvas.Free; 2087 2554 end; 2088 2555 … … 2215 2682 end; 2216 2683 2684 procedure TBGRADefaultBitmap.FillQuadPerspectiveMapping(pt1, pt2, pt3, 2685 pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; 2686 ACleanBorders: TRect); 2687 var 2688 persp: TBGRAPerspectiveScannerTransform; 2689 clean: TBGRAExtendedBorderScanner; 2690 begin 2691 clean := TBGRAExtendedBorderScanner.Create(texture,ACleanBorders); 2692 persp := TBGRAPerspectiveScannerTransform.Create(clean,[tex1,tex2,tex3,tex4],[pt1,pt2,pt3,pt4]); 2693 FillPoly([pt1,pt2,pt3,pt4],persp,dmDrawWithTransparency); 2694 persp.Free; 2695 clean.Free; 2696 end; 2697 2217 2698 procedure TBGRADefaultBitmap.FillQuadPerspectiveMappingAntialias(pt1, pt2, pt3, 2218 2699 pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF); … … 2223 2704 FillPolyAntialias([pt1,pt2,pt3,pt4],persp); 2224 2705 persp.Free; 2706 end; 2707 2708 procedure TBGRADefaultBitmap.FillQuadPerspectiveMappingAntialias(pt1, pt2, pt3, 2709 pt4: TPointF; texture: IBGRAScanner; tex1, tex2, tex3, tex4: TPointF; 2710 ACleanBorders: TRect); 2711 var 2712 persp: TBGRAPerspectiveScannerTransform; 2713 clean: TBGRAExtendedBorderScanner; 2714 begin 2715 clean := TBGRAExtendedBorderScanner.Create(texture,ACleanBorders); 2716 persp := TBGRAPerspectiveScannerTransform.Create(clean,[tex1,tex2,tex3,tex4],[pt1,pt2,pt3,pt4]); 2717 FillPolyAntialias([pt1,pt2,pt3,pt4],persp); 2718 persp.Free; 2719 clean.Free; 2225 2720 end; 2226 2721 … … 2284 2779 procedure TBGRADefaultBitmap.FillPolyAntialias(const points: array of TPointF; c: TBGRAPixel); 2285 2780 begin 2286 BGRAPolygon.FillPolyAntialias(self, points, c, FEraseMode, FillMode = fmWinding );2781 BGRAPolygon.FillPolyAntialias(self, points, c, FEraseMode, FillMode = fmWinding, LinearAntialiasing); 2287 2782 end; 2288 2783 … … 2290 2785 texture: IBGRAScanner); 2291 2786 begin 2292 BGRAPolygon.FillPolyAntialiasWithTexture(self, points, texture, FillMode = fmWinding );2787 BGRAPolygon.FillPolyAntialiasWithTexture(self, points, texture, FillMode = fmWinding, LinearAntialiasing); 2293 2788 end; 2294 2789 … … 2306 2801 end; 2307 2802 2803 procedure TBGRADefaultBitmap.FillShape(shape: TBGRACustomFillInfo; c: TBGRAPixel; 2804 drawmode: TDrawMode); 2805 begin 2806 BGRAPolygon.FillShapeAliased(self, shape, c, FEraseMode, nil, FillMode = fmWinding, drawmode); 2807 end; 2808 2809 procedure TBGRADefaultBitmap.FillShape(shape: TBGRACustomFillInfo; 2810 texture: IBGRAScanner; drawmode: TDrawMode); 2811 begin 2812 BGRAPolygon.FillShapeAliased(self, shape, BGRAPixelTransparent, false, texture, FillMode = fmWinding, drawmode); 2813 end; 2814 2815 procedure TBGRADefaultBitmap.FillShapeAntialias(shape: TBGRACustomFillInfo; 2816 c: TBGRAPixel); 2817 begin 2818 BGRAPolygon.FillShapeAntialias(self, shape, c, FEraseMode, nil, FillMode = fmWinding, LinearAntialiasing); 2819 end; 2820 2821 procedure TBGRADefaultBitmap.FillShapeAntialias(shape: TBGRACustomFillInfo; 2822 texture: IBGRAScanner); 2823 begin 2824 BGRAPolygon.FillShapeAntialiasWithTexture(self, shape, texture, FillMode = fmWinding, LinearAntialiasing); 2825 end; 2826 2827 procedure TBGRADefaultBitmap.EraseShape(shape: TBGRACustomFillInfo; alpha: byte); 2828 begin 2829 BGRAPolygon.FillShapeAliased(self, shape, BGRA(0, 0, 0, alpha), True, nil, FillMode = fmWinding, dmDrawWithTransparency); 2830 end; 2831 2832 procedure TBGRADefaultBitmap.EraseShapeAntialias(shape: TBGRACustomFillInfo; 2833 alpha: byte); 2834 begin 2835 FEraseMode := True; 2836 FillShapeAntialias(shape, BGRA(0, 0, 0, alpha)); 2837 FEraseMode := False; 2838 end; 2839 2308 2840 procedure TBGRADefaultBitmap.EllipseAntialias(x, y, rx, ry: single; 2309 2841 c: TBGRAPixel; w: single); … … 2311 2843 if IsClearPenStyle(FCustomPenStyle) or (c.alpha = 0) then exit; 2312 2844 if IsSolidPenStyle(FCustomPenStyle) then 2313 BGRAPolygon.BorderEllipseAntialias(self, x, y, rx, ry, w, c, FEraseMode )2845 BGRAPolygon.BorderEllipseAntialias(self, x, y, rx, ry, w, c, FEraseMode, LinearAntialiasing) 2314 2846 else 2315 2847 DrawPolygonAntialias(ComputeEllipseContour(x,y,rx,ry),c,w); … … 2321 2853 if IsClearPenStyle(FCustomPenStyle) then exit; 2322 2854 if IsSolidPenStyle(FCustomPenStyle) then 2323 BGRAPolygon.BorderEllipseAntialiasWithTexture(self, x, y, rx, ry, w, texture )2855 BGRAPolygon.BorderEllipseAntialiasWithTexture(self, x, y, rx, ry, w, texture, LinearAntialiasing) 2324 2856 else 2325 2857 DrawPolygonAntialias(ComputeEllipseContour(x,y,rx,ry),texture,w); … … 2362 2894 procedure TBGRADefaultBitmap.FillEllipseAntialias(x, y, rx, ry: single; c: TBGRAPixel); 2363 2895 begin 2364 BGRAPolygon.FillEllipseAntialias(self, x, y, rx, ry, c, FEraseMode );2896 BGRAPolygon.FillEllipseAntialias(self, x, y, rx, ry, c, FEraseMode, LinearAntialiasing); 2365 2897 end; 2366 2898 … … 2368 2900 texture: IBGRAScanner); 2369 2901 begin 2370 BGRAPolygon.FillEllipseAntialiasWithTexture(self, x, y, rx, ry, texture );2902 BGRAPolygon.FillEllipseAntialiasWithTexture(self, x, y, rx, ry, texture, LinearAntialiasing); 2371 2903 end; 2372 2904 … … 2486 3018 if IsClearPenStyle(FCustomPenStyle) or (c.alpha = 0) then exit; 2487 3019 if IsSolidPenStyle(FCustomPenStyle) then 2488 BGRAPolygon.BorderRoundRectangleAntialias(self,x,y,x2,y2,rx,ry,w,options,c,False )3020 BGRAPolygon.BorderRoundRectangleAntialias(self,x,y,x2,y2,rx,ry,w,options,c,False, LinearAntialiasing) 2489 3021 else 2490 3022 DrawPolygonAntialias(BGRAPath.ComputeRoundRect(x,y,x2,y2,rx,ry,options),c,w); … … 2544 3076 if IsClearPenStyle(FCustomPenStyle) then exit; 2545 3077 if IsSolidPenStyle(FCustomPenStyle) then 2546 BGRAPolygon.BorderRoundRectangleAntialiasWithTexture(self,x,y,x2,y2,rx,ry,w,options,texture )3078 BGRAPolygon.BorderRoundRectangleAntialiasWithTexture(self,x,y,x2,y2,rx,ry,w,options,texture, LinearAntialiasing) 2547 3079 else 2548 3080 DrawPolygonAntialias(BGRAPath.ComputeRoundRect(x,y,x2,y2,rx,ry,options),texture,w); … … 2686 3218 end else 2687 3219 begin 2688 if (mode <> dmSet) and ( c.alpha = 0) then exit;3220 if (mode <> dmSet) and (mode <> dmXor) and (c.alpha = 0) then exit; 2689 3221 2690 3222 p := Scanline[y] + x; … … 2714 3246 end; 2715 3247 dmXor: 3248 if DWord(c) = 0 then exit 3249 else 2716 3250 for yb := y2 - y downto 0 do 2717 3251 begin … … 2825 3359 c: TBGRAPixel; options: TRoundRectangleOptions); 2826 3360 begin 2827 BGRAPolygon.FillRoundRectangleAntialias(self,x,y,x2,y2,rx,ry,options,c,False );3361 BGRAPolygon.FillRoundRectangleAntialias(self,x,y,x2,y2,rx,ry,options,c,False, LinearAntialiasing); 2828 3362 end; 2829 3363 … … 2831 3365 ry: single; texture: IBGRAScanner; options: TRoundRectangleOptions); 2832 3366 begin 2833 BGRAPolygon.FillRoundRectangleAntialiasWithTexture(self,x,y,x2,y2,rx,ry,options,texture );3367 BGRAPolygon.FillRoundRectangleAntialiasWithTexture(self,x,y,x2,y2,rx,ry,options,texture, LinearAntialiasing); 2834 3368 end; 2835 3369 … … 2837 3371 ry: single; alpha: byte; options: TRoundRectangleOptions); 2838 3372 begin 2839 BGRAPolygon.FillRoundRectangleAntialias(self,x,y,x2,y2,rx,ry,options,BGRA(0,0,0,alpha),True );3373 BGRAPolygon.FillRoundRectangleAntialias(self,x,y,x2,y2,rx,ry,options,BGRA(0,0,0,alpha),True, LinearAntialiasing); 2840 3374 end; 2841 3375 2842 3376 procedure TBGRADefaultBitmap.RoundRect(X1, Y1, X2, Y2: integer; 2843 DX, DY: integer; BorderColor, FillColor: TBGRAPixel); 2844 begin 2845 BGRARoundRectAliased(self,X1,Y1,X2,Y2,DX,DY,BorderColor,FillColor); 3377 DX, DY: integer; BorderColor, FillColor: TBGRAPixel; ADrawMode: TDrawMode = dmDrawWithTransparency); 3378 begin 3379 BGRARoundRectAliased(self,X1,Y1,X2,Y2,DX,DY,BorderColor,FillColor,nil,ADrawMode); 3380 end; 3381 3382 procedure TBGRADefaultBitmap.RoundRect(X1, Y1, X2, Y2: integer; DX, 3383 DY: integer; BorderColor: TBGRAPixel; ADrawMode: TDrawMode); 3384 begin 3385 BGRARoundRectAliased(self,X1,Y1,X2,Y2,DX,DY,BorderColor,BGRAPixelTransparent,nil,ADrawMode,true); 2846 3386 end; 2847 3387 2848 3388 {------------------------- Text functions ---------------------------------------} 2849 3389 2850 procedure TBGRADefaultBitmap.TextOutAngle(x, y: single; orientation: integer; 2851 s: string; c: TBGRAPixel; align: TAlignment); 2852 begin 2853 UpdateFont; 2854 BGRAText.BGRATextOutAngle(self,FFont,FontQuality,x,y,orientation,s,c,nil,align); 2855 end; 2856 2857 procedure TBGRADefaultBitmap.TextOutAngle(x, y: single; orientation: integer; 2858 s: string; texture: IBGRAScanner; align: TAlignment); 2859 begin 2860 UpdateFont; 2861 BGRAText.BGRATextOutAngle(self,FFont,FontQuality,x,y,orientation,s,BGRAPixelTransparent,texture,align); 2862 end; 2863 2864 procedure TBGRADefaultBitmap.TextOut(x, y: single; s: string; 3390 procedure TBGRADefaultBitmap.TextOutAngle(x, y: single; orientationTenthDegCCW: integer; 3391 sUTF8: string; c: TBGRAPixel; align: TAlignment); 3392 begin 3393 FontRenderer.TextOutAngle(self,x,y,orientationTenthDegCCW,CleanTextOutString(sUTF8),c,align); 3394 end; 3395 3396 procedure TBGRADefaultBitmap.TextOutAngle(x, y: single; orientationTenthDegCCW: integer; 3397 sUTF8: string; texture: IBGRAScanner; align: TAlignment); 3398 begin 3399 FontRenderer.TextOutAngle(self,x,y,orientationTenthDegCCW,CleanTextOutString(sUTF8),texture,align); 3400 end; 3401 3402 procedure TBGRADefaultBitmap.TextOut(x, y: single; sUTF8: string; 2865 3403 texture: IBGRAScanner; align: TAlignment); 2866 3404 begin 2867 UpdateFont; 2868 2869 if (FontQuality in[fqFineAntialiasing,fqFineClearTypeBGR,fqFineClearTypeRGB]) and (FFont.Orientation mod 3600 = 0) then 2870 BGRATextFX.BGRATextOutImproveReadability(self,FFont,x,y,s,BGRAPixelTransparent,texture,align, 2871 FontQuality in[fqFineClearTypeRGB,fqFineClearTypeBGR], FontQuality = fqFineClearTypeRGB) else 2872 2873 BGRAText.BGRATextOut(self,FFont,FontQuality,x,y,s,BGRAPixelTransparent,texture,align); 2874 end; 2875 2876 procedure TBGRADefaultBitmap.TextOut(x, y: single; s: string; 3405 FontRenderer.TextOut(self,x,y,CleanTextOutString(sUTF8),texture,align); 3406 end; 3407 3408 procedure TBGRADefaultBitmap.TextOut(x, y: single; sUTF8: string; 2877 3409 c: TBGRAPixel; align: TAlignment); 2878 3410 begin 2879 UpdateFont; 2880 2881 if (FontQuality in[fqFineAntialiasing,fqFineClearTypeBGR,fqFineClearTypeRGB]) and (FFont.Orientation mod 3600 = 0) then 2882 BGRATextFX.BGRATextOutImproveReadability(self,FFont,x,y,s,c,nil,align, 2883 FontQuality in[fqFineClearTypeRGB,fqFineClearTypeBGR], FontQuality = fqFineClearTypeRGB) else 2884 2885 BGRAText.BGRATextOut(self,FFont,FontQuality,x,y,s,c,nil,align); 3411 FontRenderer.TextOut(self,x,y,CleanTextOutString(sUTF8),c,align); 2886 3412 end; 2887 3413 2888 3414 procedure TBGRADefaultBitmap.TextRect(ARect: TRect; x, y: integer; 2889 s: string; style: TTextStyle; c: TBGRAPixel); 2890 begin 2891 UpdateFont; 2892 BGRAText.BGRATextRect(self,FFont,FontQuality,ARect,x,y,s,style,c,nil); 2893 end; 2894 2895 procedure TBGRADefaultBitmap.TextRect(ARect: TRect; x, y: integer; s: string; 3415 sUTF8: string; style: TTextStyle; c: TBGRAPixel); 3416 begin 3417 FontRenderer.TextRect(self,ARect,x,y,sUTF8,style,c); 3418 end; 3419 3420 procedure TBGRADefaultBitmap.TextRect(ARect: TRect; x, y: integer; sUTF8: string; 2896 3421 style: TTextStyle; texture: IBGRAScanner); 2897 3422 begin 2898 UpdateFont; 2899 BGRAText.BGRATextRect(self,FFont,FontQuality,ARect,x,y,s,style,BGRAPixelTransparent,texture); 2900 end; 2901 2902 function TBGRADefaultBitmap.TextSize(s: string): TSize; 2903 begin 2904 UpdateFont; 2905 result := BGRAText.BGRATextSize(FFont,FontQuality,s,FontAntialiasingLevel); 2906 if (result.cy >= 24) and FontAntialias then 2907 result := BGRAText.BGRATextSize(FFont,FontQuality,s,4); 3423 FontRenderer.TextRect(self,ARect,x,y,sUTF8,style,texture); 3424 end; 3425 3426 { Returns the total size of the string provided using the current font. 3427 Orientation is not taken into account, so that the width is along the text. } 3428 function TBGRADefaultBitmap.TextSize(sUTF8: string): TSize; 3429 begin 3430 result := FontRenderer.TextSize(sUTF8); 2908 3431 end; 2909 3432 … … 2947 3470 w: single): ArrayOfTPointF; 2948 3471 begin 2949 Result:= BGRAPen.ComputeWidePolylinePoints(points,w,BGRAWhite,LineCap,JoinStyle,FCustomPenStyle,[],JoinMiterLimit); 3472 if Assigned(FArrow) then 3473 Result:= BGRAPen.ComputeWidePolylinePoints(points,w,BGRAWhite,LineCap,JoinStyle,FCustomPenStyle,GetPolyLineOption,JoinMiterLimit,@FArrow.ComputeStartAt,FArrow.StartOffsetX,@FArrow.ComputeEndAt,FArrow.EndOffsetX) 3474 else 3475 Result:= BGRAPen.ComputeWidePolylinePoints(points,w,BGRAWhite,LineCap,JoinStyle,FCustomPenStyle,GetPolyLineOption,JoinMiterLimit) 2950 3476 end; 2951 3477 … … 2956 3482 begin 2957 3483 if not closed then options := [plRoundCapOpen] else options := []; 2958 Result:= BGRAPen.ComputeWidePolylinePoints(points,w,BGRAWhite,pecRound,pjsRound,FCustomPenStyle,options,JoinMiterLimit); 3484 options += GetPolyLineOption; 3485 if Assigned(FArrow) then 3486 Result:= BGRAPen.ComputeWidePolylinePoints(points,w,BGRAWhite,pecRound,pjsRound,FCustomPenStyle,options,JoinMiterLimit,@FArrow.ComputeStartAt,FArrow.StartOffsetX,@FArrow.ComputeEndAt,FArrow.EndOffsetX) 3487 else 3488 Result:= BGRAPen.ComputeWidePolylinePoints(points,w,BGRAWhite,pecRound,pjsRound,FCustomPenStyle,options,JoinMiterLimit); 2959 3489 end; 2960 3490 … … 2962 3492 w: single): ArrayOfTPointF; 2963 3493 begin 2964 Result:= BGRAPen.ComputeWidePolylinePoints(points,w,BGRAWhite,LineCap,JoinStyle,FCustomPenStyle, [plCycle],JoinMiterLimit);3494 Result:= BGRAPen.ComputeWidePolylinePoints(points,w,BGRAWhite,LineCap,JoinStyle,FCustomPenStyle,GetPolyLineOption+[plCycle],JoinMiterLimit); 2965 3495 end; 2966 3496 … … 2984 3514 endRad: single; quality: single): ArrayOfTPointF; 2985 3515 begin 2986 result := BGRAPath.ComputeArc 65536(x,y,rx,ry,round(startRad*32768/Pi),round(endRad*32768/Pi),quality);3516 result := BGRAPath.ComputeArcRad(x,y,rx,ry,startRad,endRad,quality); 2987 3517 end; 2988 3518 … … 3057 3587 3058 3588 procedure TBGRADefaultBitmap.FillMask(x, y: integer; AMask: TBGRACustomBitmap; 3059 color: TBGRAPixel );3589 color: TBGRAPixel; ADrawMode: TDrawMode); 3060 3590 var 3061 3591 scan: TBGRACustomScanner; … … 3063 3593 if (AMask = nil) or (color.alpha = 0) then exit; 3064 3594 scan := TBGRASolidColorMaskScanner.Create(AMask,Point(-X,-Y),color); 3065 self.FillRect(X,Y,X+AMask.Width,Y+AMask.Height,scan, dmDrawWithTransparency);3595 self.FillRect(X,Y,X+AMask.Width,Y+AMask.Height,scan,ADrawMode); 3066 3596 scan.Free; 3067 3597 end; 3068 3598 3069 3599 procedure TBGRADefaultBitmap.FillMask(x, y: integer; AMask: TBGRACustomBitmap; 3070 texture: IBGRAScanner );3600 texture: IBGRAScanner; ADrawMode: TDrawMode); 3071 3601 var 3072 3602 scan: TBGRACustomScanner; … … 3074 3604 if AMask = nil then exit; 3075 3605 scan := TBGRATextureMaskScanner.Create(AMask,Point(-X,-Y),texture); 3076 self.FillRect(X,Y,X+AMask.Width,Y+AMask.Height,scan, dmDrawWithTransparency);3606 self.FillRect(X,Y,X+AMask.Width,Y+AMask.Height,scan,ADrawMode); 3077 3607 scan.Free; 3078 3608 end; … … 3351 3881 function TBGRADefaultBitmap.ScanAt(X, Y: Single): TBGRAPixel; 3352 3882 var 3353 ix, iy: integer;3354 iFactX,iFactY: integer;3883 ix, iy: Int32or64; 3884 iFactX,iFactY: Int32or64; 3355 3885 begin 3356 3886 if FData = nil then … … 3359 3889 exit; 3360 3890 end; 3361 iFactX := round(x*256);3362 i FactY := round(y*256);3363 i x := (iFactX shr 8)+ScanOffset.X;3364 i y := (iFactY shr 8)+ScanOffset.Y;3365 iFact X := iFactXand 255;3366 i FactY := iFactY and 255;3367 3891 LoadFromBitmapIfNeeded; 3892 ix := round(x*256); 3893 iy := round(y*256); 3894 iFactX := ix and 255; 3895 iFactY := iy and 255; 3896 ix := PositiveMod(ix+(ScanOffset.X shl 8), FWidth shl 8) shr 8; 3897 iy := PositiveMod(iy+(ScanOffset.Y shl 8), FHeight shl 8) shr 8; 3368 3898 if (iFactX = 0) and (iFactY = 0) then 3369 3899 begin 3370 result := (GetScanlineFast( PositiveMod(iy, FHeight))+PositiveMod(ix, FWidth))^;3900 result := (GetScanlineFast(iy)+ix)^; 3371 3901 exit; 3372 3902 end; 3373 3374 3903 if ScanInterpolationFilter <> rfLinear then 3375 3904 begin … … 3377 3906 iFactY := FineInterpolation256( iFactY, ScanInterpolationFilter ); 3378 3907 end; 3379 3380 result := GetPixelCycleInline(ix,iy, iFactX,iFactY); 3908 result := InternalGetPixelCycle256(ix,iy, iFactX,iFactY); 3381 3909 end; 3382 3910 … … 3497 4025 end; 3498 4026 3499 function TBGRADefaultBitmap.CheckPutImageBounds(x,y,tx,ty: integer; out minxb,minyb,maxxb,maxyb,ignoreleft: integer): boolean inline;3500 var x2,y2: integer;3501 begin3502 if (x >= FClipRect.Right) or (y >= FClipRect.Bottom) or (x <= FClipRect.Left-tx) or3503 (y <= FClipRect.Top-ty) or (Height = 0) or (ty = 0) or (tx = 0) then3504 begin3505 result := false;3506 exit;3507 end;3508 3509 x2 := x + tx - 1;3510 y2 := y + ty - 1;3511 3512 if y < FClipRect.Top then3513 minyb := FClipRect.Top3514 else3515 minyb := y;3516 if y2 >= FClipRect.Bottom then3517 maxyb := FClipRect.Bottom - 13518 else3519 maxyb := y2;3520 3521 if x < FClipRect.Left then3522 begin3523 ignoreleft := FClipRect.Left-x;3524 minxb := FClipRect.Left;3525 end3526 else3527 begin3528 ignoreleft := 0;3529 minxb := x;3530 end;3531 if x2 >= FClipRect.Right then3532 maxxb := FClipRect.Right - 13533 else3534 maxxb := x2;3535 3536 result := true;3537 end;3538 3539 4027 function TBGRADefaultBitmap.CheckAntialiasRectBounds(var x, y, x2, y2: single; 3540 4028 w: single): boolean; … … 3584 4072 sourcewidth := Source.Width; 3585 4073 3586 if not CheckPutImageBounds(x,y,sourcewidth,source.height,minxb,minyb,maxxb,maxyb,ignoreleft ) then exit;4074 if not CheckPutImageBounds(x,y,sourcewidth,source.height,minxb,minyb,maxxb,maxyb,ignoreleft,FClipRect) then exit; 3587 4075 3588 4076 copycount := maxxb - minxb + 1; … … 3749 4237 sourcewidth := Source.Width; 3750 4238 3751 if not CheckPutImageBounds(x,y,sourcewidth,source.height,minxb,minyb,maxxb,maxyb,ignoreleft ) then exit;4239 if not CheckPutImageBounds(x,y,sourcewidth,source.height,minxb,minyb,maxxb,maxyb,ignoreleft,FClipRect) then exit; 3752 4240 3753 4241 copycount := maxxb - minxb + 1; … … 3783 4271 sourcewidth := Source.Width; 3784 4272 3785 if not CheckPutImageBounds(x,y,sourcewidth,source.height,minxb,minyb,maxxb,maxyb,ignoreleft ) then exit;4273 if not CheckPutImageBounds(x,y,sourcewidth,source.height,minxb,minyb,maxxb,maxyb,ignoreleft,FClipRect) then exit; 3786 4274 3787 4275 copycount := maxxb - minxb + 1; … … 3808 4296 end; 3809 4297 3810 { Draw an image wih an angle. Use an affine transformation to do this. }3811 procedure TBGRADefaultBitmap.PutImageAngle(x, y: single;3812 Source: TBGRACustomBitmap; angle: single; imageCenterX: single;3813 imageCenterY: single; AOpacity: Byte; ARestoreOffsetAfterRotation: boolean);3814 var3815 cosa,sina: single;3816 3817 { Compute rotated coordinates }3818 function Coord(relX,relY: single): TPointF;3819 begin3820 relX -= imageCenterX;3821 relY -= imageCenterY;3822 result.x := relX*cosa-relY*sina+x;3823 result.y := relY*cosa+relX*sina+y;3824 if ARestoreOffsetAfterRotation then3825 begin3826 result.x += imageCenterX;3827 result.y += imageCenterY;3828 end;3829 end;3830 3831 begin3832 cosa := cos(-angle*Pi/180);3833 sina := -sin(-angle*Pi/180);3834 PutImageAffine(Coord(0,0),Coord(source.Width,0),Coord(0,source.Height),source,AOpacity);3835 end;3836 3837 4298 { Draw an image with an affine transformation (rotation, scale, translate). 3838 Parameters are the bitmap origin, the end of the horizontal axis and the end of the vertical axis. } 3839 procedure TBGRADefaultBitmap.PutImageAffine(Origin,HAxis,VAxis: TPointF; Source: TBGRACustomBitmap; AOpacity: Byte); 4299 Parameters are the bitmap origin, the end of the horizontal axis and the end of the vertical axis. 4300 The output bounds correspond to the pixels that will be affected in the destination. } 4301 procedure TBGRADefaultBitmap.PutImageAffine(Origin, HAxis, VAxis: TPointF; 4302 Source: TBGRACustomBitmap; AOutputBounds: TRect; AResampleFilter: TResampleFilter; AMode: TDrawMode; AOpacity: Byte); 3840 4303 var affine: TBGRAAffineBitmapTransform; 3841 minx,miny,maxx,maxy: integer; 3842 pt4: TPointF; 3843 3844 //include specified point in the bounds 3845 procedure Include(pt: TPointF); 3846 begin 3847 if floor(pt.X) < minx then minx := floor(pt.X); 3848 if floor(pt.Y) < miny then miny := floor(pt.Y); 3849 if ceil(pt.X) > maxx then maxx := ceil(pt.X); 3850 if ceil(pt.Y) > maxy then maxy := ceil(pt.Y); 3851 end; 3852 3853 begin 4304 SourceBounds: TRect; 4305 begin 4306 if (Source = nil) or (AOpacity = 0) then exit; 4307 IntersectRect(AOutputBounds,AOutputBounds,ClipRect); 4308 if IsRectEmpty(AOutputBounds) then exit; 4309 3854 4310 if (abs(Origin.x-round(Origin.x))<1e-6) and (abs(Origin.y-round(Origin.Y))<1e-6) and 3855 4311 (abs(HAxis.x-(Origin.x+Source.Width))<1e-6) and (abs(HAxis.y-origin.y)<1e-6) and 3856 4312 (abs(VAxis.x-Origin.x)<1e-6) and (abs(VAxis.y-(Origin.y+Source.Height))<1e-6) then 3857 4313 begin 3858 PutImage(round(origin.x),round(origin.y),Source,dmDrawWithTransparency,AOpacity); 4314 SourceBounds := AOutputBounds; 4315 OffsetRect(SourceBounds, -round(origin.x),-round(origin.y)); 4316 IntersectRect(SourceBounds,SourceBounds,rect(0,0,Source.Width,Source.Height)); 4317 PutImagePart(round(origin.x)+SourceBounds.Left,round(origin.y)+SourceBounds.Top,Source,SourceBounds,AMode,AOpacity); 3859 4318 exit; 3860 4319 end; 3861 4320 3862 4321 { Create affine transformation } 3863 affine := TBGRAAffineBitmapTransform.Create(Source );4322 affine := TBGRAAffineBitmapTransform.Create(Source, false, AResampleFilter); 3864 4323 affine.GlobalOpacity := AOpacity; 3865 4324 affine.Fit(Origin,HAxis,VAxis); 3866 3867 { Compute bounds } 3868 pt4.x := VAxis.x+HAxis.x-Origin.x; 3869 pt4.y := VAxis.y+HAxis.y-Origin.y; 3870 minx := floor(Origin.X); 3871 miny := floor(Origin.Y); 3872 maxx := ceil(Origin.X); 3873 maxy := ceil(Origin.Y); 3874 Include(HAxis); 3875 Include(VAxis); 3876 Include(pt4); 3877 3878 { Use the affine transformation as a scanner } 3879 FillRect(minx,miny,maxx+1,maxy+1,affine,dmDrawWithTransparency); 4325 FillRect(AOutputBounds,affine,AMode); 3880 4326 affine.Free; 4327 end; 4328 4329 procedure TBGRADefaultBitmap.StretchPutImage(ARect: TRect; 4330 Source: TBGRACustomBitmap; mode: TDrawMode; AOpacity: byte); 4331 begin 4332 If (Source = nil) or (AOpacity = 0) then exit; 4333 if (ARect.Right-ARect.Left = Source.Width) and (ARect.Bottom-ARect.Top = Source.Height) then 4334 PutImage(ARect.Left,ARect.Top,Source,mode,AOpacity) 4335 else 4336 BGRAResample.StretchPutImage(Source, ARect.Right-ARect.Left, ARect.Bottom-ARect.Top, self, ARect.left,ARect.Top, mode, AOpacity); 3881 4337 end; 3882 4338 … … 3991 4447 end; 3992 4448 4449 function TBGRADefaultBitmap.FilterTwirl(ABounds: TRect; ACenter: TPoint; 4450 ARadius: Single; ATurn: Single; AExponent: Single): TBGRACustomBitmap; 4451 begin 4452 result := BGRAFilters.FilterTwirl(self, ABounds, ACenter, ARadius, ATurn, AExponent); 4453 end; 4454 3993 4455 function TBGRADefaultBitmap.FilterCylinder: TBGRACustomBitmap; 3994 4456 begin … … 4001 4463 end; 4002 4464 4003 function TBGRADefaultBitmap.FilterSharpen: TBGRACustomBitmap; 4004 begin 4005 Result := BGRAFilters.FilterSharpen(self); 4465 function TBGRADefaultBitmap.FilterSharpen(Amount: single = 1): TBGRACustomBitmap; 4466 begin 4467 Result := BGRAFilters.FilterSharpen(self,round(Amount*256)); 4468 end; 4469 4470 function TBGRADefaultBitmap.FilterSharpen(ABounds: TRect; Amount: single 4471 ): TBGRACustomBitmap; 4472 begin 4473 Result := BGRAFilters.FilterSharpen(self,ABounds,round(Amount*256)); 4006 4474 end; 4007 4475 … … 4017 4485 end; 4018 4486 4487 function TBGRADefaultBitmap.FilterBlurRadial(ABounds: TRect; radius: integer; 4488 blurType: TRadialBlurType): TBGRACustomBitmap; 4489 var task: TFilterTask; 4490 begin 4491 task := BGRAFilters.CreateRadialBlurTask(self, ABounds, radius, blurType); 4492 try 4493 result := task.Execute; 4494 finally 4495 task.Free; 4496 end; 4497 end; 4498 4019 4499 function TBGRADefaultBitmap.FilterPixelate(pixelSize: integer; 4020 4500 useResample: boolean; filter: TResampleFilter): TBGRACustomBitmap; … … 4029 4509 end; 4030 4510 4511 function TBGRADefaultBitmap.FilterBlurMotion(ABounds: TRect; distance: integer; 4512 angle: single; oriented: boolean): TBGRACustomBitmap; 4513 var task: TFilterTask; 4514 begin 4515 task := BGRAFilters.CreateMotionBlurTask(self,ABounds,distance,angle,oriented); 4516 try 4517 Result := task.Execute; 4518 finally 4519 task.Free; 4520 end; 4521 end; 4522 4031 4523 function TBGRADefaultBitmap.FilterCustomBlur(mask: TBGRACustomBitmap): 4032 4524 TBGRACustomBitmap; … … 4035 4527 end; 4036 4528 4529 function TBGRADefaultBitmap.FilterCustomBlur(ABounds: TRect; 4530 mask: TBGRACustomBitmap): TBGRACustomBitmap; 4531 var task: TFilterTask; 4532 begin 4533 task := BGRAFilters.CreateBlurTask(self, ABounds, mask); 4534 try 4535 result := task.Execute; 4536 finally 4537 task.Free; 4538 end; 4539 end; 4540 4037 4541 function TBGRADefaultBitmap.FilterEmboss(angle: single): TBGRACustomBitmap; 4038 4542 begin 4039 4543 Result := BGRAFilters.FilterEmboss(self, angle); 4544 end; 4545 4546 function TBGRADefaultBitmap.FilterEmboss(angle: single; ABounds: TRect): TBGRACustomBitmap; 4547 begin 4548 Result := BGRAFilters.FilterEmboss(self, angle, ABounds); 4040 4549 end; 4041 4550 … … 4063 4572 end; 4064 4573 4574 function TBGRADefaultBitmap.FilterGrayscale(ABounds: TRect): TBGRACustomBitmap; 4575 begin 4576 Result := BGRAFilters.FilterGrayscale(self, ABounds); 4577 end; 4578 4065 4579 function TBGRADefaultBitmap.FilterNormalize(eachChannel: boolean = True): 4066 4580 TBGRACustomBitmap; … … 4069 4583 end; 4070 4584 4585 function TBGRADefaultBitmap.FilterNormalize(ABounds: TRect; eachChannel: boolean): TBGRACustomBitmap; 4586 begin 4587 Result := BGRAFilters.FilterNormalize(self, ABounds, eachChannel); 4588 end; 4589 4071 4590 function TBGRADefaultBitmap.FilterRotate(origin: TPointF; 4072 angle: single ): TBGRACustomBitmap;4073 begin 4074 Result := BGRAFilters.FilterRotate(self, origin, angle );4591 angle: single; correctBlur: boolean): TBGRACustomBitmap; 4592 begin 4593 Result := BGRAFilters.FilterRotate(self, origin, angle, correctBlur); 4075 4594 end; 4076 4595 … … 4140 4659 end; 4141 4660 4142 {$hints off}4143 function TBGRADefaultBitmap.LoadAsBmp32(Str: TStream): boolean;4144 var OldPos: int64;4145 fileHeader: TBitmapFileHeader;4146 infoHeader: TBitmapInfoHeader;4147 dataSize: integer;4148 begin4149 OldPos := Str.Position;4150 result := false;4151 try4152 if Str.Read(fileHeader,sizeof(fileHeader)) <> sizeof(fileHeader) then4153 raise exception.Create('Inuable to read file header');4154 if fileHeader.bfType = $4D42 then4155 begin4156 if Str.Read(infoHeader,sizeof(infoHeader)) <> sizeof(infoHeader) then4157 raise exception.Create('Inuable to read info header');4158 4159 if (infoHeader.biPlanes = 1) and (infoHeader.biBitCount = 32) and (infoHeader.biCompression = 0) then4160 begin4161 SetSize(infoHeader.biWidth,infoHeader.biHeight);4162 Str.Position := OldPos+fileHeader.bfOffBits;4163 dataSize := NbPixels*sizeof(TBGRAPixel);4164 if Str.Read(Data^, dataSize) <> dataSize then4165 Begin4166 SetSize(0,0);4167 raise exception.Create('Unable to read data');4168 end;4169 result := true;4170 end;4171 end;4172 4173 except4174 on ex:exception do4175 begin4176 4177 end;4178 end;4179 Str.Position := OldPos;4180 4181 end;4182 {$hints on}4183 4184 4661 procedure TBGRADefaultBitmap.SetCanvasOpacity(AValue: byte); 4185 4662 begin … … 4225 4702 4226 4703 It is an involution, i.e it does nothing when applied twice } 4227 procedure TBGRADefaultBitmap.VerticalFlip ;4228 var 4229 yb : integer;4704 procedure TBGRADefaultBitmap.VerticalFlip(ARect: TRect); 4705 var 4706 yb,h2: integer; 4230 4707 line: PBGRAPixel; 4231 linesize : integer;4708 linesize, delta: integer; 4232 4709 PStart: PBGRAPixel; 4233 4710 PEnd: PBGRAPixel; … … 4236 4713 exit; 4237 4714 4715 if (ARect.Right <= ARect.Left) or (ARect.Bottom <= ARect.Top) then exit; 4716 if not IntersectRect(ARect, ARect, rect(0,0,Width,Height)) then exit; 4238 4717 LoadFromBitmapIfNeeded; 4239 linesize := Width* sizeof(TBGRAPixel);4718 linesize := (ARect.Right-ARect.Left) * sizeof(TBGRAPixel); 4240 4719 line := nil; 4241 4720 getmem(line, linesize); 4242 PStart := Data; 4243 PEnd := Data + (Height - 1) * Width; 4244 for yb := 0 to (Height div 2) - 1 do 4721 PStart := GetScanlineFast(ARect.Top)+ARect.Left; 4722 PEnd := GetScanlineFast(ARect.Bottom-1)+ARect.Left; 4723 h2 := (ARect.Bottom-ARect.Top) div 2; 4724 if LineOrder = riloTopToBottom then delta := +Width else delta := -Width; 4725 for yb := h2-1 downto 0 do 4245 4726 begin 4246 4727 move(PStart^, line^, linesize); 4247 4728 move(PEnd^, PStart^, linesize); 4248 4729 move(line^, PEnd^, linesize); 4249 Inc(PStart, Width);4250 Dec(PEnd, Width);4730 Inc(PStart, delta); 4731 Dec(PEnd, delta); 4251 4732 end; 4252 4733 freemem(line); … … 4257 4738 4258 4739 It is an involution, i.e it does nothing when applied twice} 4259 procedure TBGRADefaultBitmap.HorizontalFlip ;4260 var 4261 yb, xb : integer;4740 procedure TBGRADefaultBitmap.HorizontalFlip(ARect: TRect); 4741 var 4742 yb, xb, w: integer; 4262 4743 PStart: PBGRAPixel; 4263 4744 PEnd: PBGRAPixel; … … 4267 4748 exit; 4268 4749 4750 if (ARect.Right <= ARect.Left) or (ARect.Bottom <= ARect.Top) then exit; 4751 if not IntersectRect(ARect, ARect, rect(0,0,Width,Height)) then exit; 4752 w := ARect.Right-ARect.Left; 4269 4753 LoadFromBitmapIfNeeded; 4270 for yb := 0 to Height -1 do4271 begin 4272 PStart := Scanline[yb];4273 PEnd := PStart + Width;4274 for xb := 0 to ( Widthdiv 2) - 1 do4754 for yb := ARect.Top to ARect.Bottom-1 do 4755 begin 4756 PStart := GetScanlineFast(yb)+ARect.Left; 4757 PEnd := PStart + w; 4758 for xb := 0 to (w div 2) - 1 do 4275 4759 begin 4276 4760 Dec(PEnd); … … 4339 4823 complentary colors (black becomes white etc.). 4340 4824 4341 It is an involution, i.e it does nothing when applied twice}4825 It is NOT EXACTLY an involution, when applied twice, some color information is lost } 4342 4826 procedure TBGRADefaultBitmap.Negative; 4343 4827 var … … 4360 4844 end; 4361 4845 4846 procedure TBGRADefaultBitmap.NegativeRect(ABounds: TRect); 4847 var p: PBGRAPixel; 4848 xb,yb,xcount: integer; 4849 begin 4850 if not IntersectRect(ABounds,ABounds,ClipRect) then exit; 4851 xcount := ABounds.Right-ABounds.Left; 4852 for yb := ABounds.Top to ABounds.Bottom-1 do 4853 begin 4854 p := ScanLine[yb]+ABounds.Left; 4855 for xb := xcount-1 downto 0 do 4856 begin 4857 if p^.alpha <> 0 then 4858 begin 4859 p^.red := GammaCompressionTab[not GammaExpansionTab[p^.red]]; 4860 p^.green := GammaCompressionTab[not GammaExpansionTab[p^.green]]; 4861 p^.blue := GammaCompressionTab[not GammaExpansionTab[p^.blue]]; 4862 end; 4863 Inc(p); 4864 end; 4865 end; 4866 end; 4867 4362 4868 { Compute negative without gamma correction. 4363 4869 … … 4381 4887 end; 4382 4888 InvalidateBitmap; 4889 end; 4890 4891 procedure TBGRADefaultBitmap.LinearNegativeRect(ABounds: TRect); 4892 var p: PBGRAPixel; 4893 xb,yb,xcount: integer; 4894 begin 4895 if not IntersectRect(ABounds,ABounds,ClipRect) then exit; 4896 xcount := ABounds.Right-ABounds.Left; 4897 for yb := ABounds.Top to ABounds.Bottom-1 do 4898 begin 4899 p := ScanLine[yb]+ABounds.Left; 4900 for xb := xcount-1 downto 0 do 4901 begin 4902 if p^.alpha <> 0 then 4903 begin 4904 p^.red := not p^.red; 4905 p^.green := not p^.green; 4906 p^.blue := not p^.blue; 4907 end; 4908 Inc(p); 4909 end; 4910 end; 4911 end; 4912 4913 procedure TBGRADefaultBitmap.InplaceGrayscale; 4914 begin 4915 InplaceGrayscale(rect(0,0,Width,Height)); 4916 end; 4917 4918 procedure TBGRADefaultBitmap.InplaceGrayscale(ABounds: TRect); 4919 var 4920 task: TFilterTask; 4921 begin 4922 task := CreateGrayscaleTask(self, ABounds); 4923 task.Destination := self; 4924 task.Execute; 4925 task.Free; 4383 4926 end; 4384 4927 … … 4452 4995 4453 4996 See : http://wiki.lazarus.freepascal.org/BGRABitmap_tutorial_5 } 4454 procedure TBGRADefaultBitmap.ApplyMask(mask: TBGRACustomBitmap );4997 procedure TBGRADefaultBitmap.ApplyMask(mask: TBGRACustomBitmap; ARect: TRect; AMaskRectTopLeft: TPoint); 4455 4998 var 4456 4999 p, pmask: PBGRAPixel; 4457 5000 yb, xb: integer; 4458 begin 4459 if (Mask.Width <> Width) or (Mask.Height <> Height) then 4460 exit; 5001 MaskOffsetX,MaskOffsetY,w: integer; 5002 opacity: NativeUint; 5003 begin 5004 if (ARect.Right <= ARect.Left) or (ARect.Bottom <= ARect.Top) then exit; 5005 IntersectRect(ARect, ARect, rect(0,0,Width,Height)); 5006 MaskOffsetX := AMaskRectTopLeft.x - ARect.Left; 5007 MaskOffsetY := AMaskRectTopLeft.y - ARect.Top; 5008 OffsetRect(ARect, MaskOffsetX, MaskOffsetY); 5009 IntersectRect(ARect, ARect, rect(0,0,mask.Width,mask.Height)); 5010 OffsetRect(ARect, -MaskOffsetX, -MaskOffsetY); 4461 5011 4462 5012 LoadFromBitmapIfNeeded; 4463 for yb := 0 to Height - 1 do 4464 begin 4465 p := Scanline[yb]; 4466 pmask := Mask.Scanline[yb]; 4467 for xb := Width - 1 downto 0 do 4468 begin 4469 p^.alpha := ApplyOpacity(p^.alpha, pmask^.red); 5013 w := ARect.Right-ARect.Left-1; 5014 for yb := ARect.Top to ARect.Bottom - 1 do 5015 begin 5016 p := Scanline[yb]+ARect.Left; 5017 pmask := Mask.Scanline[yb+MaskOffsetY]+ARect.Left+MaskOffsetX; 5018 for xb := w downto 0 do 5019 begin 5020 opacity := ApplyOpacity(p^.alpha, pmask^.red); 5021 if opacity = 0 then p^ := BGRAPixelTransparent 5022 else p^.alpha := opacity; 4470 5023 Inc(p); 4471 5024 Inc(pmask); … … 4522 5075 end; 4523 5076 5077 procedure TBGRADefaultBitmap.DrawCheckers(ARect: TRect; AColorEven, 5078 AColorOdd: TBGRAPixel); 5079 const tx = 8; ty = 8; //must be a power of 2 5080 xMask = tx*2-1; 5081 var xcount,patY,w,n,patY1,patY2m1,patX,patX1: NativeInt; 5082 pdest: PBGRAPixel; 5083 delta: PtrInt; 5084 actualRect: TRect; 5085 begin 5086 actualRect := ARect; 5087 IntersectRect(actualRect, ARect, self.ClipRect); 5088 w := actualRect.Right-actualRect.Left; 5089 if (w <= 0) or (actualRect.Bottom <= actualRect.Top) then exit; 5090 delta := self.Width; 5091 if self.LineOrder = riloBottomToTop then delta := -delta; 5092 delta := (delta-w)*SizeOf(TBGRAPixel); 5093 pdest := self.ScanLine[actualRect.Top]+actualRect.left; 5094 patY1 := actualRect.Top - ARect.Top; 5095 patY2m1 := actualRect.Bottom - ARect.Top-1; 5096 patX1 := (actualRect.Left - ARect.Left) and xMask; 5097 for patY := patY1 to patY2m1 do 5098 begin 5099 xcount := w; 5100 if patY and ty = 0 then 5101 patX := patX1 5102 else 5103 patX := (patX1+tx) and xMask; 5104 while xcount > 0 do 5105 begin 5106 if patX and tx = 0 then 5107 begin 5108 n := 8-patX; 5109 if n > xcount then n := xcount; 5110 FillDWord(pdest^,n,DWord(AColorEven)); 5111 dec(xcount,n); 5112 inc(pdest,n); 5113 patX := tx; 5114 end else 5115 begin 5116 n := 16-patX; 5117 if n > xcount then n := xcount; 5118 FillDWord(pdest^,n,DWord(AColorOdd)); 5119 dec(xcount,n); 5120 inc(pdest,n); 5121 patX := 0; 5122 end; 5123 end; 5124 inc(pbyte(pdest),delta); 5125 end; 5126 self.InvalidateBitmap; 5127 end; 5128 4524 5129 { Get bounds of non zero values of specified channel } 4525 5130 function TBGRADefaultBitmap.GetImageBounds(Channel: TChannel = cAlpha; ANothingValue: Byte = 0): TRect; 5131 begin 5132 result := GetImageBounds([Channel], ANothingValue); 5133 end; 5134 5135 function TBGRADefaultBitmap.GetImageBounds(Channels: TChannels; ANothingValue: Byte = 0): TRect; 4526 5136 var 4527 5137 minx, miny, maxx, maxy: integer; 4528 xb, yb: integer;4529 p: pbyte;4530 offset: integer;5138 xb, xb2, yb: integer; 5139 p: PDWord; 5140 colorMask, colorZeros: DWord; 4531 5141 begin 4532 5142 maxx := -1; … … 4534 5144 minx := self.Width; 4535 5145 miny := self.Height; 4536 case Channel of 4537 cBlue: offset := 0; 4538 cGreen: offset := 1; 4539 cRed: offset := 2; 4540 else 4541 offset := 3; 4542 end; 5146 colorMask := 0; 5147 colorZeros := 0; 5148 if cBlue in Channels then 5149 begin 5150 colorMask := colorMask or $ff; 5151 colorZeros:= colorZeros or ANothingValue; 5152 end; 5153 if cGreen in Channels then 5154 begin 5155 colorMask := colorMask or $ff00; 5156 colorZeros:= colorZeros or (ANothingValue shl 8); 5157 end; 5158 if cRed in Channels then 5159 begin 5160 colorMask := colorMask or $ff0000; 5161 colorZeros:= colorZeros or (ANothingValue shl 16); 5162 end; 5163 if cAlpha in Channels then 5164 begin 5165 colorMask := colorMask or $ff000000; 5166 colorZeros:= colorZeros or (ANothingValue shl 24); 5167 end; 5168 colorMask := NtoLE(colorMask); 5169 colorZeros := NtoLE(colorZeros); 4543 5170 for yb := 0 to self.Height - 1 do 4544 5171 begin 4545 p := P Byte(self.ScanLine[yb]) + offset;5172 p := PDWord(self.ScanLine[yb]); 4546 5173 for xb := 0 to self.Width - 1 do 4547 5174 begin 4548 if p^ <> ANothingValuethen5175 if (p^ and colorMask) <> colorZeros then 4549 5176 begin 4550 5177 if xb < minx then … … 4556 5183 if yb > maxy then 4557 5184 maxy := yb; 5185 5186 inc(p, self.width-1-xb); 5187 for xb2 := self.Width-1 downto xb+1 do 5188 begin 5189 if (p^ and colorMask) <> colorZeros then 5190 begin 5191 if xb2 > maxx then 5192 maxx := xb2; 5193 break; 5194 end; 5195 dec(p); 5196 end; 5197 break; 4558 5198 end; 4559 Inc(p , sizeof(TBGRAPixel));5199 Inc(p); 4560 5200 end; 4561 5201 end; … … 4574 5214 Result.bottom := maxy + 1; 4575 5215 end; 4576 end;4577 4578 function TBGRADefaultBitmap.GetImageBounds(Channels: TChannels): TRect;4579 var c: TChannel;4580 begin4581 result := rect(0,0,0,0);4582 for c := low(TChannel) to high(TChannel) do4583 if c in Channels then4584 UnionRect(result,result,GetImageBounds(c));4585 5216 end; 4586 5217
Note:
See TracChangeset
for help on using the changeset viewer.