Changeset 472 for GraphicTest/Packages/bgrabitmap/bgratextfx.pas
- Timestamp:
- Apr 9, 2015, 9:58:36 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
GraphicTest/Packages/bgrabitmap/bgratextfx.pas
r452 r472 3 3 {$mode objfpc}{$H+} 4 4 5 { 6 Font rendering units : BGRAText, BGRATextFX, BGRAVectorize, BGRAFreeType 7 8 This unit provide text effects. The simplest way to render effects is to use TBGRATextEffectFontRenderer class. 9 To do this, create an instance of this class and assign it to a TBGRABitmap.FontRenderer property. Now functions 10 to draw text like TBGRABitmap.TextOut will use the chosen renderer. To set the effects, keep a variable containing 11 the TBGRATextEffectFontRenderer class and modify ShadowVisible and other effects parameters. 12 13 The TBGRATextEffectFontRenderer class makes use of other classes depending on the situation. For example, 14 TBGRATextEffect, which is also in this unit, provides effects on a text mask. But the renderer also uses 15 BGRAVectorize unit in order to have big texts or to rotate them at will. 16 17 Note that you may need TBGRATextEffect if you want to have more control over text effects, especially 18 if you always draw the same text. Keeping the same TBGRATextEffect object will avoid creating the text 19 mask over and over again. 20 21 TextShadow function is a simple function to compute an image containing a text with shadow. 22 23 } 24 5 25 interface 6 26 7 27 uses 8 Classes, SysUtils, Graphics, Types, BGRABitmapTypes, BGRAPhongTypes ;28 Classes, SysUtils, Graphics, Types, BGRABitmapTypes, BGRAPhongTypes, BGRAText, BGRAVectorize; 9 29 10 30 type 31 TBGRATextEffect = class; 32 33 { TBGRATextEffectFontRenderer } 34 35 TBGRATextEffectFontRenderer = class(TCustomLCLFontRenderer) 36 private 37 function GetShaderLightPosition: TPoint; 38 function GetVectorizedRenderer: TBGRAVectorizedFontRenderer; 39 procedure SetShaderLightPosition(AValue: TPoint); 40 protected 41 FShaderOwner: boolean; 42 FShader: TCustomPhongShading; 43 FVectorizedRenderer: TBGRAVectorizedFontRenderer; 44 function ShadowActuallyVisible :boolean; 45 function ShaderActuallyActive: boolean; 46 function OutlineActuallyVisible: boolean; 47 procedure Init; 48 function VectorizedFontNeeded: boolean; 49 procedure InternalTextOut(ADest: TBGRACustomBitmap; x, y: single; s: string; c: TBGRAPixel; texture: IBGRAScanner; align: TAlignment); 50 public 51 ShaderActive: boolean; 52 53 ShadowVisible: boolean; 54 ShadowColor: TBGRAPixel; 55 ShadowRadius: integer; 56 ShadowOffset: TPoint; 57 ShadowQuality: TRadialBlurType; 58 59 OutlineColor: TBGRAPixel; 60 OutlineWidth: single; 61 OutlineVisible,OuterOutlineOnly: boolean; 62 OutlineTexture: IBGRAScanner; 63 constructor Create; 64 constructor Create(AShader: TCustomPhongShading; AShaderOwner: boolean); 65 destructor Destroy; override; 66 procedure TextOutAngle(ADest: TBGRACustomBitmap; x, y: single; orientation: integer; 67 s: string; texture: IBGRAScanner; align: TAlignment); override; 68 procedure TextOutAngle(ADest: TBGRACustomBitmap; x, y: single; orientation: integer; 69 s: string; c: TBGRAPixel; align: TAlignment); override; 70 procedure TextOut(ADest: TBGRACustomBitmap; x, y: single; s: string; 71 texture: IBGRAScanner; align: TAlignment); override; 72 procedure TextOut(ADest: TBGRACustomBitmap; x, y: single; s: string; c: TBGRAPixel; 73 align: TAlignment); override; 74 function TextSize(sUTF8: string): TSize; override; 75 property Shader: TCustomPhongShading read FShader; 76 property ShaderLightPosition: TPoint read GetShaderLightPosition write SetShaderLightPosition; 77 property VectorizedFontRenderer: TBGRAVectorizedFontRenderer read GetVectorizedRenderer; 78 end; 11 79 12 80 { TBGRATextEffect } … … 14 82 TBGRATextEffect = class 15 83 private 84 FShadowQuality: TRadialBlurType; 16 85 function GetBounds: TRect; 17 function GetHeight: integer; 86 function GetMaskHeight: integer; 87 class function GetOutlineWidth: integer; static; 18 88 function GetShadowBounds(ARadius: integer): TRect; 19 function GetWidth: integer; 89 function GetMaskWidth: integer; 90 function GetTextHeight: integer; 91 function GetTextWidth: integer; 92 procedure SetShadowQuality(AValue: TRadialBlurType); 20 93 protected 21 94 FTextMask: TBGRACustomBitmap; … … 24 97 FShadingAltitude: integer; 25 98 FShadingRounded: boolean; 26 F Width,FHeight: integer;99 FTextSize: TSize; 27 100 FOffset: TPoint; 28 procedure DrawMaskMulticolored(ADest: TBGRACustomBitmap; AMask: TBGRACustomBitmap; X,Y: Integer; const AColors: array of TBGRAPixel);29 procedure DrawMask(ADest: TBGRACustomBitmap; AMask: TBGRACustomBitmap; X,Y: Integer; AColor: TBGRAPixel);30 procedure DrawMask(ADest: TBGRACustomBitmap; AMask: TBGRACustomBitmap; X,Y: Integer; ATexture: IBGRAScanner);101 function DrawMaskMulticolored(ADest: TBGRACustomBitmap; AMask: TBGRACustomBitmap; X,Y: Integer; const AColors: array of TBGRAPixel): TRect; 102 function DrawMask(ADest: TBGRACustomBitmap; AMask: TBGRACustomBitmap; X,Y: Integer; AColor: TBGRAPixel): TRect; 103 function DrawMask(ADest: TBGRACustomBitmap; AMask: TBGRACustomBitmap; X,Y: Integer; ATexture: IBGRAScanner): TRect; 31 104 function InternalDrawShaded(ADest: TBGRACustomBitmap; X,Y: integer; Shader: TCustomPhongShading; Altitude: integer; AColor: TBGRAPixel; ATexture: IBGRAScanner; ARounded: Boolean): TRect; 105 procedure InitImproveReadability(AText: string; Font: TFont; SubOffsetX,SubOffsetY: single); 32 106 procedure Init(AText: string; Font: TFont; Antialiasing: boolean; SubOffsetX,SubOffsetY: single; GrainX, GrainY: Integer); 107 procedure InitWithFontName(AText: string; AFontName: string; AFullHeight: integer; AStyle: TFontStyles; Antialiasing: boolean; SubOffsetX,SubOffsetY: single); 33 108 public 34 109 constructor Create(AText: string; Font: TFont; Antialiasing: boolean); 35 110 constructor Create(AText: string; Font: TFont; Antialiasing: boolean; SubOffsetX,SubOffsetY: single); 36 111 constructor Create(AText: string; Font: TFont; Antialiasing: boolean; SubOffsetX,SubOffsetY: single; GrainX, GrainY: Integer); 112 constructor Create(AText: string; AFontName: string; AFullHeight: integer; Antialiasing: boolean); 113 constructor Create(AText: string; AFontName: string; AFullHeight: integer; Antialiasing: boolean; SubOffsetX,SubOffsetY: single); 114 constructor Create(AText: string; AFontName: string; AFullHeight: integer; AStyle: TFontStyles; Antialiasing: boolean); 115 constructor Create(AText: string; AFontName: string; AFullHeight: integer; AStyle: TFontStyles; Antialiasing: boolean; SubOffsetX,SubOffsetY: single); 116 constructor Create(AMask: TBGRACustomBitmap; AMaskOwner: boolean; AWidth,AHeight: integer; AOffset: TPoint); 37 117 procedure ApplySphere; 38 118 procedure ApplyVerticalCylinder; 39 119 procedure ApplyHorizontalCylinder; 40 procedure Draw(ADest: TBGRACustomBitmap; X,Y: integer; AColor: TBGRAPixel);41 procedure Draw(ADest: TBGRACustomBitmap; X,Y: integer; ATexture: IBGRAScanner);42 procedure Draw(ADest: TBGRACustomBitmap; X, Y: integer; AColor: TBGRAPixel; AAlign: TAlignment);43 procedure Draw(ADest: TBGRACustomBitmap; X, Y: integer; ATexture: IBGRAScanner; AAlign: TAlignment);120 function Draw(ADest: TBGRACustomBitmap; X,Y: integer; AColor: TBGRAPixel): TRect; 121 function Draw(ADest: TBGRACustomBitmap; X,Y: integer; ATexture: IBGRAScanner): TRect; 122 function Draw(ADest: TBGRACustomBitmap; X, Y: integer; AColor: TBGRAPixel; AAlign: TAlignment): TRect; 123 function Draw(ADest: TBGRACustomBitmap; X, Y: integer; ATexture: IBGRAScanner; AAlign: TAlignment): TRect; 44 124 45 125 function DrawShaded(ADest: TBGRACustomBitmap; X,Y: integer; Shader: TCustomPhongShading; Altitude: integer; AColor: TBGRAPixel; ARounded: Boolean = true): TRect; … … 48 128 function DrawShaded(ADest: TBGRACustomBitmap; X, Y: integer; Shader: TCustomPhongShading; Altitude: integer; ATexture: IBGRAScanner; AAlign: TAlignment; ARounded: Boolean = true): TRect; 49 129 50 procedure DrawMulticolored(ADest: TBGRACustomBitmap; X,Y: integer; const AColors: array of TBGRAPixel);51 procedure DrawMulticolored(ADest: TBGRACustomBitmap; X,Y: integer; const AColors: array of TBGRAPixel; AAlign: TAlignment);52 procedure DrawOutline(ADest: TBGRACustomBitmap; X,Y: integer; AColor: TBGRAPixel);53 procedure DrawOutline(ADest: TBGRACustomBitmap; X,Y: integer; ATexture: IBGRAScanner);54 procedure DrawOutline(ADest: TBGRACustomBitmap; X,Y: integer; AColor: TBGRAPixel; AAlign: TAlignment);55 procedure DrawOutline(ADest: TBGRACustomBitmap; X,Y: integer; ATexture: IBGRAScanner; AAlign: TAlignment);56 procedure DrawShadow(ADest: TBGRACustomBitmap; X,Y,Radius: integer; AColor: TBGRAPixel);57 procedure DrawShadow(ADest: TBGRACustomBitmap; X,Y,Radius: integer; AColor: TBGRAPixel; AAlign: TAlignment);130 function DrawMulticolored(ADest: TBGRACustomBitmap; X,Y: integer; const AColors: array of TBGRAPixel): TRect; 131 function DrawMulticolored(ADest: TBGRACustomBitmap; X,Y: integer; const AColors: array of TBGRAPixel; AAlign: TAlignment): TRect; 132 function DrawOutline(ADest: TBGRACustomBitmap; X,Y: integer; AColor: TBGRAPixel): TRect; 133 function DrawOutline(ADest: TBGRACustomBitmap; X,Y: integer; ATexture: IBGRAScanner): TRect; 134 function DrawOutline(ADest: TBGRACustomBitmap; X,Y: integer; AColor: TBGRAPixel; AAlign: TAlignment): TRect; 135 function DrawOutline(ADest: TBGRACustomBitmap; X,Y: integer; ATexture: IBGRAScanner; AAlign: TAlignment): TRect; 136 function DrawShadow(ADest: TBGRACustomBitmap; X,Y,Radius: integer; AColor: TBGRAPixel): TRect; 137 function DrawShadow(ADest: TBGRACustomBitmap; X,Y,Radius: integer; AColor: TBGRAPixel; AAlign: TAlignment): TRect; 58 138 destructor Destroy; override; 59 139 property TextMask: TBGRACustomBitmap read FTextMask; 60 140 property TextMaskOffset: TPoint read FOffset; 61 property Width: integer read GetWidth; 62 property Height: integer read GetHeight; 141 property Width: integer read GetTextWidth; deprecated; 142 property Height: integer read GetTextHeight; deprecated; 143 property MaskWidth: integer read GetMaskWidth; 144 property MaskHeight: integer read GetMaskHeight; 145 property TextSize: TSize read FTextSize; 146 property TextWidth: integer read GetTextWidth; 147 property TextHeight: integer read GetTextHeight; 63 148 property Bounds: TRect read GetBounds; 64 149 property ShadowBounds[ARadius: integer]: TRect read GetShadowBounds; 150 property ShadowQuality: TRadialBlurType read FShadowQuality write SetShadowQuality; 151 class property OutlineWidth: integer read GetOutlineWidth; 65 152 end; 66 153 … … 68 155 AOffSetX,AOffSetY: Integer; ARadius: Integer = 0; AFontStyle: TFontStyles = []; AFontName: String = 'Default'; AShowText: Boolean = True; AFontQuality: TBGRAFontQuality = fqFineAntialiasing): TBGRACustomBitmap; 69 156 70 procedure BGRATextOutImproveReadability(bmp: TBGRACustomBitmap; AFont: TFont; xf,yf: single; text: string; color: TBGRAPixel; tex: IBGRAScanner; align: TAlignment; useClearType: boolean; ClearTypeRGBOrder: boolean);157 procedure BGRATextOutImproveReadability(bmp: TBGRACustomBitmap; AFont: TFont; xf,yf: single; text: string; color: TBGRAPixel; tex: IBGRAScanner; align: TAlignment; mode : TBGRATextOutImproveReadabilityMode); 71 158 72 159 implementation 73 160 74 uses BGRAGradientScanner, BGRAText, GraphType, Math; 75 76 procedure BGRATextOutImproveReadability(bmp: TBGRACustomBitmap; AFont: TFont; xf,yf: single; text: string; color: TBGRAPixel; tex: IBGRAScanner; align: TAlignment; useClearType: boolean; ClearTypeRGBOrder: boolean); 161 uses BGRAGradientScanner, GraphType, Math, BGRAGrayscaleMask; 162 163 const DefaultOutlineWidth = 3; 164 165 procedure BGRATextOutImproveReadability(bmp: TBGRACustomBitmap; AFont: TFont; xf,yf: single; text: string; color: TBGRAPixel; tex: IBGRAScanner; align: TAlignment; mode : TBGRATextOutImproveReadabilityMode); 77 166 var 167 useClearType,clearTypeRGBOrder: boolean; 78 168 metric: TFontPixelMetric; 79 169 deltaX: single; … … 81 171 toAdd: integer; 82 172 lines: array[0..3] of integer; 83 parts: array[0..3] of T BGRACustomBitmap;84 n,nbLines ,v: integer;85 alphaMax: byte;173 parts: array[0..3] of TGrayscaleMask; 174 n,nbLines: integer; 175 alphaMax: NativeUint; 86 176 ptrPart: TBGRACustomBitmap; 87 pmask: PB GRAPixel;177 pmask: PByte; 88 178 fx: TBGRATextEffect; 89 179 FxFont: TFont; … … 92 182 93 183 begin 184 useClearType:= mode in[irClearTypeRGB,irClearTypeBGR]; 185 clearTypeRGBOrder := mode <> irClearTypeBGR; 94 186 deltaX := xf-floor(xf); 95 187 x := round(floor(xf)); … … 105 197 begin 106 198 if ClearTypeRGBOrder then 107 BGRATextOut(bmp, AFont, fqFineClearTypeRGB, xf,yf, text, color, tex, align) else 199 BGRATextOut(bmp, AFont, fqFineClearTypeRGB, xf,yf, text, color, tex, align) 200 else 108 201 BGRATextOut(bmp, AFont, fqFineClearTypeBGR, xf,yf, text, color, tex, align) 109 202 end else … … 144 237 fx := TBGRATextEffect.Create(text,FxFont,False,deltaX*FontAntialiasingLevel,0,FontAntialiasingLevel,FontAntialiasingLevel) else 145 238 fx := TBGRATextEffect.Create(text,FxFont,False,0,0,3,0); 239 240 if fx.TextMask = nil then 241 begin 242 fx.Free; 243 FxFont.Free; 244 exit; 245 end; 146 246 alphaMax := 0; 147 247 prevCenter := 0; … … 156 256 ptrPart := fx.TextMask.GetPtrBitmap(fromy,lines[yb]); 157 257 if useClearType then 158 parts[yb] := ptrPart.Resample(round(ptrPart.Width/FontAntialiasingLevel*3),round(ptrPart.Height/FontAntialiasingLevel),rmSimpleStretch)258 parts[yb] := TGrayscaleMask.CreateDownSample(ptrPart,round(ptrPart.Width/FontAntialiasingLevel*3),round(ptrPart.Height/FontAntialiasingLevel)) 159 259 else 160 parts[yb] := ptrPart.Resample(round(ptrPart.Width/FontAntialiasingLevel),round(ptrPart.Height/FontAntialiasingLevel),rmSimpleStretch);260 parts[yb] := TGrayscaleMask.CreateDownSample(ptrPart,round(ptrPart.Width/FontAntialiasingLevel),round(ptrPart.Height/FontAntialiasingLevel)); 161 261 ptrPart.Free; 162 262 163 263 if alphaMax < 255 then 164 264 begin 165 pmask := parts[yb]. data;265 pmask := parts[yb].Data; 166 266 for n := parts[yb].NbPixels-1 downto 0 do 167 267 begin 168 v := pmask^.green; 169 if v > alphaMax then alphaMax := v; 268 if pmask^ > alphaMax then alphaMax := pmask^; 170 269 inc(pmask); 171 270 end; … … 194 293 begin 195 294 case align of 196 taCenter: xThird:= xThird+round(((fx.TextMaskOffset.x-fx. Width/2)/FontAntialiasingLevel+deltaX)*3);197 taRightJustify: xThird:= xThird+round(((fx.TextMaskOffset.x-fx. Width)/FontAntialiasingLevel+deltaX)*3);295 taCenter: xThird:= xThird+round(((fx.TextMaskOffset.x-fx.TextWidth/2)/FontAntialiasingLevel+deltaX)*3); 296 taRightJustify: xThird:= xThird+round(((fx.TextMaskOffset.x-fx.TextWidth)/FontAntialiasingLevel+deltaX)*3); 198 297 else xThird:= xThird+round((fx.TextMaskOffset.x/FontAntialiasingLevel+deltaX)*3); 199 298 end; … … 201 300 begin 202 301 case align of 203 taCenter: x:= x+round((fx.TextMaskOffset.x-fx. Width/2)/FontAntialiasingLevel);204 taRightJustify: x:= x+round((fx.TextMaskOffset.x-fx. Width)/FontAntialiasingLevel);302 taCenter: x:= x+round((fx.TextMaskOffset.x-fx.TextWidth/2)/FontAntialiasingLevel); 303 taRightJustify: x:= x+round((fx.TextMaskOffset.x-fx.TextWidth)/FontAntialiasingLevel); 205 304 else x:= x+round(fx.TextMaskOffset.x/FontAntialiasingLevel); 206 305 end; … … 215 314 for n := parts[yb].NbPixels-1 downto 0 do 216 315 begin 217 v := integer(pmask^.green)*255 div alphaMax; 218 if v > 255 then v := 255; 219 pmask^.green := v; 220 pmask^.red := v; 221 pmask^.blue := v; 316 pmask^ := pmask^*255 div alphaMax; 222 317 inc(pmask); 223 318 end; 224 319 end; 225 320 if useClearType then 321 BGRAFillClearTypeGrayscaleMask(bmp,x,cury,xThird,parts[yb],color,tex,ClearTypeRGBOrder) 322 else if mode = irMask then 323 parts[yb].Draw(bmp,x,cury) 324 else 226 325 begin 227 326 if tex <> nil then 228 bmp.FillClearTypeMask(x,cury,xThird,parts[yb],tex,ClearTypeRGBOrder) else 229 bmp.FillClearTypeMask(x,cury,xThird,parts[yb],color,ClearTypeRGBOrder); 230 end else 231 begin 232 if tex <> nil then 233 bmp.FillMask(x,cury,parts[yb],tex) else 234 bmp.FillMask(x,cury,parts[yb],color); 327 parts[yb].DrawAsAlpha(bmp,x,cury,tex) else 328 parts[yb].DrawAsAlpha(bmp,x,cury,color); 235 329 end; 236 330 inc(cury,parts[yb].Height); … … 249 343 250 344 function TextShadow(AWidth,AHeight: Integer; AText: String; AFontHeight: Integer; ATextColor,AShadowColor: TBGRAPixel; 251 AOffSetX,AOffSetY: Integer; ARadius: Integer = 0; AFontStyle: TFontStyles = []; AFontName: String = 'Default'; AShowText: Boolean = True; AFontQuality: TBGRAFontQuality = fqFineAntialiasing): TBGRACustomBitmap; 345 AOffSetX,AOffSetY: Integer; ARadius: Integer = 0; AFontStyle: TFontStyles = []; AFontName: String = 'Default'; AShowText: Boolean = True; 346 AFontQuality: TBGRAFontQuality = fqFineAntialiasing): TBGRACustomBitmap; 252 347 var 253 348 bmpOut,bmpSdw: TBGRACustomBitmap; OutTxtSize: TSize; OutX,OutY: Integer; … … 281 376 end; 282 377 378 { TBGRATextEffectFontRenderer } 379 380 function TBGRATextEffectFontRenderer.GetShaderLightPosition: TPoint; 381 begin 382 if FShader = nil then 383 result := point(0,0) 384 else 385 result := FShader.LightPosition; 386 end; 387 388 function TBGRATextEffectFontRenderer.GetVectorizedRenderer: TBGRAVectorizedFontRenderer; 389 begin 390 FVectorizedRenderer.FontEmHeight := FontEmHeight; 391 FVectorizedRenderer.FontName := FontName; 392 FVectorizedRenderer.FontOrientation:= FontOrientation; 393 FVectorizedRenderer.FontQuality := FontQuality; 394 FVectorizedRenderer.FontStyle:= FontStyle; 395 396 FVectorizedRenderer.ShadowColor := ShadowColor; 397 FVectorizedRenderer.ShadowVisible := ShadowVisible; 398 FVectorizedRenderer.ShadowOffset := ShadowOffset; 399 FVectorizedRenderer.ShadowRadius := ShadowRadius; 400 401 FVectorizedRenderer.OutlineColor := OutlineColor; 402 FVectorizedRenderer.OutlineVisible := OutlineVisible; 403 FVectorizedRenderer.OutlineWidth := OutlineWidth; 404 FVectorizedRenderer.OutlineTexture := OutlineTexture; 405 FVectorizedRenderer.OuterOutlineOnly := OuterOutlineOnly; 406 result := FVectorizedRenderer; 407 end; 408 409 procedure TBGRATextEffectFontRenderer.SetShaderLightPosition(AValue: TPoint); 410 begin 411 if FShader <> nil then 412 FShader.LightPosition := AValue; 413 end; 414 415 function TBGRATextEffectFontRenderer.ShadowActuallyVisible: boolean; 416 begin 417 result := ShadowVisible and (ShadowColor.alpha <> 0); 418 end; 419 420 function TBGRATextEffectFontRenderer.ShaderActuallyActive: boolean; 421 begin 422 result := (FShader <> nil) and ShaderActive; 423 end; 424 425 function TBGRATextEffectFontRenderer.OutlineActuallyVisible: boolean; 426 begin 427 result := (OutlineWidth <> 0) and ((OutlineTexture <> nil) or (OutlineColor.alpha <> 0)) and OutlineVisible; 428 end; 429 430 procedure TBGRATextEffectFontRenderer.Init; 431 begin 432 ShaderActive := true; 433 434 ShadowColor := BGRABlack; 435 ShadowVisible := false; 436 ShadowOffset := Point(5,5); 437 ShadowRadius := 5; 438 ShadowQuality:= rbFast; 439 440 OutlineColor := BGRAPixelTransparent; 441 OutlineVisible := True; 442 OutlineWidth:= DefaultOutlineWidth; 443 OuterOutlineOnly:= false; 444 FVectorizedRenderer := TBGRAVectorizedFontRenderer.Create; 445 end; 446 447 function TBGRATextEffectFontRenderer.VectorizedFontNeeded: boolean; 448 var bAntialiasing, bBigFont, bSpecialOutline, bOriented, bEffectVectorizedSupported: boolean; 449 textsz: TSize; 450 begin 451 bAntialiasing := FontQuality in [fqFineAntialiasing,fqFineClearTypeRGB,fqFineClearTypeBGR]; 452 textsz := inherited TextSize('Hg'); 453 bBigFont := (not OutlineActuallyVisible and (textsz.cy >= 24)) or 454 (OutlineActuallyVisible and (textsz.cy > 42)); 455 bSpecialOutline:= OutlineActuallyVisible and (abs(OutlineWidth) <> DefaultOutlineWidth); 456 bOriented := FontOrientation <> 0; 457 bEffectVectorizedSupported := OutlineActuallyVisible or ShadowActuallyVisible; 458 if ShaderActuallyActive and (FontOrientation = 0) then 459 result := false //shader not supported by vectorized font 460 else 461 result := bSpecialOutline or 462 (bAntialiasing and bBigFont) or 463 (bOriented and bEffectVectorizedSupported); 464 end; 465 466 procedure TBGRATextEffectFontRenderer.InternalTextOut(ADest: TBGRACustomBitmap; 467 x, y: single; s: string; c: TBGRAPixel; texture: IBGRAScanner; 468 align: TAlignment); 469 var fx: TBGRATextEffect; 470 procedure DoOutline; 471 begin 472 if OutlineActuallyVisible then 473 begin 474 if OutlineTexture <> nil then 475 fx.DrawOutline(ADest,round(x),round(y), OutlineTexture, align) 476 else 477 fx.DrawOutline(ADest,round(x),round(y), OutlineColor, align); 478 end; 479 end; 480 begin 481 UpdateFont; 482 if (FFont.Orientation <> 0) or (not ShaderActuallyActive and not ShadowActuallyVisible and not OutlineActuallyVisible) then 483 begin 484 if texture <> nil then 485 inherited TextOut(ADest,x,y,s,texture,align) 486 else 487 inherited TextOut(ADest,x,y,s,c,align); 488 exit; 489 end; 490 fx := TBGRATextEffect.Create(s, FFont, FontQuality in[fqFineAntialiasing,fqFineClearTypeBGR,fqFineClearTypeRGB], x-floor(x),y-floor(y)); 491 if ShadowActuallyVisible then 492 begin 493 fx.ShadowQuality := ShadowQuality; 494 fx.DrawShadow(ADest,round(x)+ShadowOffset.X,round(y)+ShadowOffset.Y,ShadowRadius,ShadowColor, align); 495 end; 496 if OuterOutlineOnly then DoOutline; 497 if texture <> nil then 498 begin 499 if ShaderActuallyActive then 500 fx.DrawShaded(ADest,floor(x),floor(y), Shader, round(fx.TextSize.cy*0.05), texture, align) 501 else 502 fx.Draw(ADest,round(x),round(y), texture, align); 503 end else 504 begin 505 if ShaderActuallyActive then 506 fx.DrawShaded(ADest,floor(x),floor(y), Shader, round(fx.TextSize.cy*0.05), c, align) 507 else 508 fx.Draw(ADest,round(x),round(y), c, align); 509 end; 510 if not OuterOutlineOnly then DoOutline; 511 fx.Free; 512 end; 513 514 constructor TBGRATextEffectFontRenderer.Create; 515 begin 516 inherited Create; 517 FShader := nil; 518 FShaderOwner:= false; 519 Init; 520 end; 521 522 constructor TBGRATextEffectFontRenderer.Create(AShader: TCustomPhongShading; 523 AShaderOwner: boolean); 524 begin 525 inherited Create; 526 Init; 527 FShader := AShader; 528 FShaderOwner := AShaderOwner; 529 end; 530 531 destructor TBGRATextEffectFontRenderer.Destroy; 532 begin 533 if FShaderOwner then FShader.Free; 534 FVectorizedRenderer.Free; 535 inherited Destroy; 536 end; 537 538 procedure TBGRATextEffectFontRenderer.TextOutAngle(ADest: TBGRACustomBitmap; x, 539 y: single; orientation: integer; s: string; texture: IBGRAScanner; 540 align: TAlignment); 541 begin 542 VectorizedFontRenderer.TextOutAngle(ADest, x, y, orientation, s, texture, align); 543 end; 544 545 procedure TBGRATextEffectFontRenderer.TextOutAngle(ADest: TBGRACustomBitmap; x, 546 y: single; orientation: integer; s: string; c: TBGRAPixel; align: TAlignment); 547 begin 548 VectorizedFontRenderer.TextOutAngle(ADest, x, y, orientation, s, c, align); 549 end; 550 551 procedure TBGRATextEffectFontRenderer.TextOut(ADest: TBGRACustomBitmap; x, 552 y: single; s: string; texture: IBGRAScanner; align: TAlignment); 553 begin 554 if VectorizedFontNeeded then 555 VectorizedFontRenderer.TextOut(ADest,x,y,s,texture,align) 556 else 557 InternalTextOut(ADest,x,y,s,BGRAPixelTransparent,texture,align); 558 end; 559 560 procedure TBGRATextEffectFontRenderer.TextOut(ADest: TBGRACustomBitmap; x, 561 y: single; s: string; c: TBGRAPixel; align: TAlignment); 562 begin 563 if VectorizedFontNeeded then 564 VectorizedFontRenderer.TextOut(ADest,x,y,s,c,align) 565 else 566 InternalTextOut(ADest,x,y,s,c,nil,align); 567 end; 568 569 function TBGRATextEffectFontRenderer.TextSize(sUTF8: string): TSize; 570 begin 571 if VectorizedFontNeeded then 572 result := VectorizedFontRenderer.TextSize(sUTF8) 573 else 574 begin 575 result := inherited TextSize(sUTF8); 576 end; 577 end; 578 283 579 { TBGRATextEffect } 284 580 … … 291 587 end; 292 588 293 function TBGRATextEffect.GetHeight: integer; 294 begin 295 result := FHeight; 589 function TBGRATextEffect.GetMaskHeight: integer; 590 begin 591 if FTextMask = nil then 592 result := 0 593 else 594 result := FTextMask.Height; 595 end; 596 597 class function TBGRATextEffect.GetOutlineWidth: integer; static; 598 begin 599 result := DefaultOutlineWidth; 296 600 end; 297 601 … … 308 612 end; 309 613 310 function TBGRATextEffect.GetWidth: integer; 311 begin 312 result := FWidth; 313 end; 314 315 procedure TBGRATextEffect.DrawMaskMulticolored(ADest: TBGRACustomBitmap; 316 AMask: TBGRACustomBitmap; X, Y: Integer; const AColors: array of TBGRAPixel); 614 function TBGRATextEffect.GetMaskWidth: integer; 615 begin 616 if FTextMask = nil then 617 result := 0 618 else 619 result := FTextMask.Width; 620 end; 621 622 function TBGRATextEffect.GetTextHeight: integer; 623 begin 624 result := FTextSize.cy; 625 end; 626 627 function TBGRATextEffect.GetTextWidth: integer; 628 begin 629 result := FTextSize.cx; 630 end; 631 632 procedure TBGRATextEffect.SetShadowQuality(AValue: TRadialBlurType); 633 begin 634 if FShadowQuality=AValue then Exit; 635 FShadowQuality:=AValue; 636 FreeAndNil(FShadowMask); 637 end; 638 639 function TBGRATextEffect.DrawMaskMulticolored(ADest: TBGRACustomBitmap; 640 AMask: TBGRACustomBitmap; X, Y: Integer; const AColors: array of TBGRAPixel 641 ): TRect; 317 642 var 318 643 scan: TBGRASolidColorMaskScanner; … … 321 646 emptyCol, nextCol: boolean; 322 647 begin 323 if (AMask = nil) or (length(AColors)=0) then exit; 648 if (AMask = nil) or (length(AColors)=0) then 649 begin 650 result := EmptyRect; 651 exit; 652 end; 324 653 if (length(AColors)=0) then 325 654 begin 326 DrawMask(ADest,AMask,X,Y,AColors[0]);655 result := DrawMask(ADest,AMask,X,Y,AColors[0]); 327 656 exit; 328 657 end; … … 399 728 ADest.FillRect(X+startX,Y,X+AMask.Width,Y+AMask.Height,scan,dmDrawWithTransparency); 400 729 scan.Free; 401 end; 402 403 procedure TBGRATextEffect.DrawMask(ADest: TBGRACustomBitmap; AMask: TBGRACustomBitmap; X, 404 Y: Integer; AColor: TBGRAPixel); 730 result := rect(X,Y,X+AMask.Width,Y+AMask.Height); 731 end; 732 733 function TBGRATextEffect.DrawMask(ADest: TBGRACustomBitmap; 734 AMask: TBGRACustomBitmap; X, Y: Integer; AColor: TBGRAPixel): TRect; 405 735 var 406 736 scan: TBGRACustomScanner; 407 737 begin 408 if AMask = nil then exit; 738 if AMask = nil then 739 begin 740 result := EmptyRect; 741 exit; 742 end; 409 743 scan := TBGRASolidColorMaskScanner.Create(AMask,Point(-X,-Y),AColor); 410 744 ADest.FillRect(X,Y,X+AMask.Width,Y+AMask.Height,scan,dmDrawWithTransparency); 411 745 scan.Free; 412 end; 413 414 procedure TBGRATextEffect.DrawMask(ADest: TBGRACustomBitmap; AMask: TBGRACustomBitmap; X, 415 Y: Integer; ATexture: IBGRAScanner); 746 result := rect(X,Y,X+AMask.Width,Y+AMask.Height); 747 end; 748 749 function TBGRATextEffect.DrawMask(ADest: TBGRACustomBitmap; 750 AMask: TBGRACustomBitmap; X, Y: Integer; ATexture: IBGRAScanner): TRect; 416 751 var 417 752 scan: TBGRACustomScanner; 418 753 begin 419 if AMask = nil then exit; 754 if AMask = nil then 755 begin 756 result := EmptyRect; 757 exit; 758 end; 420 759 scan := TBGRATextureMaskScanner.Create(AMask,Point(-X,-Y),ATexture); 421 760 ADest.FillRect(X,Y,X+AMask.Width,Y+AMask.Height,scan,dmDrawWithTransparency); 422 761 scan.Free; 762 result := rect(X,Y,X+AMask.Width,Y+AMask.Height); 423 763 end; 424 764 … … 433 773 iBlurRadius: integer; 434 774 begin 435 if FTextMask = nilthen775 if (FTextMask = nil) or (FTextMask.Width = 0) or (FTextMask.Height = 0) then 436 776 begin 437 777 result := EmptyRect; … … 491 831 end; 492 832 833 inc(X, FOffset.X); 834 Inc(Y, FOffset.Y); 493 835 if ATexture <> nil then 494 Shader.DrawScan(ADest,FShadingMask,Altitude,X +FOffset.X,Y+FOffset.Y, ATexture)836 Shader.DrawScan(ADest,FShadingMask,Altitude,X,Y, ATexture) 495 837 else 496 Shader.Draw(ADest,FShadingMask,Altitude,X+FOffset.X,Y+FOffset.Y, AColor); 497 result := rect(X+FOffset.X,Y+FOffset.Y, X+FOffset.X+FShadingMask.Width,Y+FOffset.Y+FShadingMask.Height); 498 end; 499 500 procedure TBGRATextEffect.Draw(ADest: TBGRACustomBitmap; X, Y: integer; 501 AColor: TBGRAPixel; AAlign: TAlignment); 838 Shader.Draw(ADest,FShadingMask,Altitude,X,Y, AColor); 839 result := rect(X,Y, X+FShadingMask.Width,Y+FShadingMask.Height); 840 end; 841 842 procedure TBGRATextEffect.InitImproveReadability(AText: string; Font: TFont; 843 SubOffsetX, SubOffsetY: single); 844 var size: TSize; 845 overhang: integer; 846 begin 847 if SubOffsetX < 0 then SubOffsetX := 0; 848 if SubOffsetY < 0 then SubOffsetY := 0; 849 size := BGRATextSize(Font, fqFineAntialiasing, AText, FontAntialiasingLevel); 850 FTextSize := size; 851 if size.cy = 0 then FTextSize.cy := BGRATextSize(Font, fqFineAntialiasing, 'Hg', FontAntialiasingLevel).cy; 852 overhang := size.cy div 2; 853 size.cx += 2*overhang + ceil(SubOffsetX); 854 size.cy += 2 + ceil(SubOffsetY); 855 856 FOffset := Point(-overhang,-1); //include overhang 857 FTextMask := BGRABitmapFactory.Create(size.cx,size.cy,BGRABlack); 858 BGRATextOutImproveReadability(FTextMask, Font, overhang+SubOffsetX,1+SubOffsetY, AText, BGRAWhite, nil, taLeftJustify, irMask); 859 end; 860 861 function TBGRATextEffect.Draw(ADest: TBGRACustomBitmap; X, Y: integer; 862 AColor: TBGRAPixel; AAlign: TAlignment): TRect; 502 863 begin 503 864 Case AAlign of 504 ta LeftJustify: Draw(ADest,X,Y,AColor);505 ta RightJustify: Draw(ADest,X-Width,Y,AColor);506 taCenter: Draw(ADest,X-Width div 2,Y,AColor);507 end; 508 end; 509 510 procedureTBGRATextEffect.Draw(ADest: TBGRACustomBitmap; X, Y: integer;511 ATexture: IBGRAScanner; AAlign: TAlignment) ;865 taRightJustify: result := Draw(ADest,X-TextSize.cx,Y,AColor); 866 taCenter: result := Draw(ADest,X-TextSize.cx div 2,Y,AColor); 867 else result := Draw(ADest,X,Y,AColor); 868 end; 869 end; 870 871 function TBGRATextEffect.Draw(ADest: TBGRACustomBitmap; X, Y: integer; 872 ATexture: IBGRAScanner; AAlign: TAlignment): TRect; 512 873 begin 513 874 Case AAlign of 514 ta LeftJustify: Draw(ADest,X,Y,ATexture);515 ta RightJustify: Draw(ADest,X-Width,Y,ATexture);516 taCenter: Draw(ADest,X-Width div 2,Y,ATexture);875 taRightJustify: result := Draw(ADest,X-TextSize.cx,Y,ATexture); 876 taCenter: result := Draw(ADest,X-TextSize.cx div 2,Y,ATexture); 877 else result := Draw(ADest,X,Y,ATexture); 517 878 end; 518 879 end; … … 538 899 Case AAlign of 539 900 taLeftJustify: result := DrawShaded(ADest,X,Y,Shader,Altitude,AColor,ARounded); 540 taRightJustify: result := DrawShaded(ADest,X- Width,Y,Shader,Altitude,AColor,ARounded);541 taCenter: result := DrawShaded(ADest,X- Widthdiv 2,Y,Shader,Altitude,AColor,ARounded);901 taRightJustify: result := DrawShaded(ADest,X-TextSize.cx,Y,Shader,Altitude,AColor,ARounded); 902 taCenter: result := DrawShaded(ADest,X-TextSize.cx div 2,Y,Shader,Altitude,AColor,ARounded); 542 903 else 543 904 result := EmptyRect; … … 551 912 Case AAlign of 552 913 taLeftJustify: result := DrawShaded(ADest,X,Y,Shader,Altitude,ATexture,ARounded); 553 taRightJustify: result := DrawShaded(ADest,X- Width,Y,Shader,Altitude,ATexture,ARounded);554 taCenter: result := DrawShaded(ADest,X- Widthdiv 2,Y,Shader,Altitude,ATexture,ARounded);914 taRightJustify: result := DrawShaded(ADest,X-TextSize.cx,Y,Shader,Altitude,ATexture,ARounded); 915 taCenter: result := DrawShaded(ADest,X-TextSize.cx div 2,Y,Shader,Altitude,ATexture,ARounded); 555 916 else 556 917 result := EmptyRect; … … 571 932 end; 572 933 573 procedure TBGRATextEffect.Init(AText: string; Font: TFont; 574 Antialiasing: boolean; SubOffsetX,SubOffsetY: single; GrainX, GrainY: Integer); 934 constructor TBGRATextEffect.Create(AText: string; AFontName: string; 935 AFullHeight: integer; Antialiasing: boolean); 936 begin 937 InitWithFontName(AText, AFontName, AFullHeight, [], Antialiasing, 0, 0); 938 end; 939 940 constructor TBGRATextEffect.Create(AText: string; AFontName: string; 941 AFullHeight: integer; Antialiasing: boolean; SubOffsetX, SubOffsetY: single); 942 begin 943 InitWithFontName(AText, AFontName, AFullHeight, [], Antialiasing, SubOffsetX, SubOffsetY); 944 end; 945 946 constructor TBGRATextEffect.Create(AText: string; AFontName: string; 947 AFullHeight: integer; AStyle: TFontStyles; Antialiasing: boolean); 948 begin 949 InitWithFontName(AText, AFontName, AFullHeight, AStyle, Antialiasing, 0, 0); 950 end; 951 952 constructor TBGRATextEffect.Create(AText: string; AFontName: string; 953 AFullHeight: integer; AStyle: TFontStyles; Antialiasing: boolean; SubOffsetX, 954 SubOffsetY: single); 955 begin 956 InitWithFontName(AText, AFontName, AFullHeight, AStyle, Antialiasing, SubOffsetX, SubOffsetY); 957 end; 958 959 constructor TBGRATextEffect.Create(AMask: TBGRACustomBitmap; AMaskOwner: boolean; AWidth, 960 AHeight: integer; AOffset: TPoint); 961 begin 962 FTextSize := Size(AWidth,AHeight); 963 FOffset := AOffset; 964 if not AMaskOwner then 965 FTextMask := AMask.Duplicate() 966 else 967 FTextMask := AMask; 968 end; 969 970 procedure TBGRATextEffect.Init(AText: string; Font: TFont; Antialiasing: boolean; SubOffsetX,SubOffsetY: single; GrainX, GrainY: Integer); 971 const FXAntialiasingLevel = FontAntialiasingLevel; 575 972 var temp: TBGRACustomBitmap; 576 973 size: TSize; … … 583 980 iSubX,iSubY: integer; 584 981 begin 982 FShadowQuality := rbFast; 983 if Antialiasing and Assigned(BGRATextOutImproveReadabilityProc) then 984 begin 985 InitImproveReadability(AText, Font, SubOffsetX,SubOffsetY); 986 exit; 987 end; 585 988 if Antialiasing then 586 989 quality := fqFineAntialiasing 587 990 else 588 991 quality := fqSystem; 589 size := BGRAOriginalTextSize(Font,quality,AText,F ontAntialiasingLevel);992 size := BGRAOriginalTextSize(Font,quality,AText,FXAntialiasingLevel); 590 993 if (size.cx = 0) or (size.cy = 0) then 591 994 begin 592 size := BGRATextSize(Font,quality,'Hg',F ontAntialiasingLevel);593 F Width:= 0;594 F Height:= size.cy;995 size := BGRATextSize(Font,quality,'Hg',FXAntialiasingLevel); 996 FTextSize.cx := 0; 997 FTextSize.cy := size.cy; 595 998 FOffset := Point(0,0); 596 999 exit; 597 1000 end; 1001 FTextSize := size; 598 1002 599 1003 sizeX := size.cx+size.cy; … … 607 1011 if Antialiasing then 608 1012 begin 609 sizeX := (sizeX + F ontAntialiasingLevel-1);610 sizeX -= sizeX mod F ontAntialiasingLevel;611 612 sizeY := (sizeY + F ontAntialiasingLevel-1);613 sizeY -= sizeY mod F ontAntialiasingLevel;1013 sizeX := (sizeX + FXAntialiasingLevel-1); 1014 sizeX -= sizeX mod FXAntialiasingLevel; 1015 1016 sizeY := (sizeY + FXAntialiasingLevel-1); 1017 sizeY -= sizeY mod FXAntialiasingLevel; 614 1018 615 1019 if SubOffsetX <> 0 then 616 1020 begin 617 sizeX += ceil(SubOffsetX*F ontAntialiasingLevel);618 iSubX := round(SubOffsetX*F ontAntialiasingLevel);1021 sizeX += ceil(SubOffsetX*FXAntialiasingLevel); 1022 iSubX := round(SubOffsetX*FXAntialiasingLevel); 619 1023 end; 620 1024 if SubOffsetY <> 0 then 621 1025 begin 622 sizeY += ceil(SubOffsetY*F ontAntialiasingLevel);623 iSubY := round(SubOffsetY*F ontAntialiasingLevel);624 end; 625 626 OnePixel := F ontAntialiasingLevel;1026 sizeY += ceil(SubOffsetY*FXAntialiasingLevel); 1027 iSubY := round(SubOffsetY*FXAntialiasingLevel); 1028 end; 1029 1030 OnePixel := FXAntialiasingLevel; 627 1031 end else 628 1032 begin … … 662 1066 if Antialiasing then 663 1067 begin 664 F Width := round(size.cx/FontAntialiasingLevel);665 F Height := round(size.cy/FontAntialiasingLevel);666 FOffset := Point(round(FOffset.X/F ontAntialiasingLevel),round(FOffset.Y/FontAntialiasingLevel));667 668 FTextMask := temp.Resample(round(temp.width/F ontAntialiasingLevel),round(temp.Height/FontAntialiasingLevel),rmSimpleStretch);1068 FTextSize.cx := round(FTextSize.cx/FXAntialiasingLevel); 1069 FTextSize.cy := round(FTextSize.cy/FXAntialiasingLevel); 1070 FOffset := Point(round(FOffset.X/FXAntialiasingLevel),round(FOffset.Y/FXAntialiasingLevel)); 1071 1072 FTextMask := temp.Resample(round(temp.width/FXAntialiasingLevel),round(temp.Height/FXAntialiasingLevel),rmSimpleStretch); 669 1073 670 1074 maxAlpha := 0; … … 692 1096 else 693 1097 begin 694 FWidth := size.cx;695 FHeight := size.cy;696 697 1098 FTextMask := temp; 698 1099 p := FTextMask.data; … … 705 1106 end; 706 1107 end; 1108 end; 1109 1110 procedure TBGRATextEffect.InitWithFontName(AText: string; AFontName: string; 1111 AFullHeight: integer; AStyle: TFontStyles; Antialiasing: boolean; SubOffsetX, SubOffsetY: single); 1112 var lFont: TFont; 1113 begin 1114 lFont := TFont.Create; 1115 lFont.Name := AFontName; 1116 lFont.Height := AFullHeight * FontFullHeightSign; 1117 lFont.Style := AStyle; 1118 Init(AText, lFont, Antialiasing, SubOffsetX, SubOffsetY, 0,0); 1119 lFont.Free; 707 1120 end; 708 1121 … … 746 1159 end; 747 1160 748 procedure TBGRATextEffect.Draw(ADest: TBGRACustomBitmap; X, Y: integer; 749 AColor: TBGRAPixel); 750 begin 751 if FTextMask = nil then exit; 752 DrawMask(ADest,FTextMask,X+FOffset.X,Y+FOffset.Y,AColor); 753 end; 754 755 procedure TBGRATextEffect.Draw(ADest: TBGRACustomBitmap; X, Y: integer; 756 ATexture: IBGRAScanner); 757 begin 758 if FTextMask = nil then exit; 759 DrawMask(ADest,FTextMask,X+FOffset.X,Y+FOffset.Y,ATexture); 760 end; 761 762 procedure TBGRATextEffect.DrawMulticolored(ADest: TBGRACustomBitmap; X, Y: integer; 763 const AColors: array of TBGRAPixel); 764 begin 765 if FTextMask = nil then exit; 766 DrawMaskMulticolored(ADest,FTextMask,X+FOffset.X,Y+FOffset.Y,AColors); 767 end; 768 769 procedure TBGRATextEffect.DrawMulticolored(ADest: TBGRACustomBitmap; X, 770 Y: integer; const AColors: array of TBGRAPixel; AAlign: TAlignment); 1161 function TBGRATextEffect.Draw(ADest: TBGRACustomBitmap; X, Y: integer; 1162 AColor: TBGRAPixel): TRect; 1163 begin 1164 result := DrawMask(ADest,FTextMask,X+FOffset.X,Y+FOffset.Y,AColor); 1165 end; 1166 1167 function TBGRATextEffect.Draw(ADest: TBGRACustomBitmap; X, Y: integer; 1168 ATexture: IBGRAScanner): TRect; 1169 begin 1170 result := DrawMask(ADest,FTextMask,X+FOffset.X,Y+FOffset.Y,ATexture); 1171 end; 1172 1173 function TBGRATextEffect.DrawMulticolored(ADest: TBGRACustomBitmap; X, 1174 Y: integer; const AColors: array of TBGRAPixel): TRect; 1175 begin 1176 result := DrawMaskMulticolored(ADest,FTextMask,X+FOffset.X,Y+FOffset.Y,AColors); 1177 end; 1178 1179 function TBGRATextEffect.DrawMulticolored(ADest: TBGRACustomBitmap; X, 1180 Y: integer; const AColors: array of TBGRAPixel; AAlign: TAlignment): TRect; 771 1181 begin 772 1182 Case AAlign of 773 taLeftJustify: DrawMulticolored(ADest,X,Y,AColors); 774 taRightJustify: DrawMulticolored(ADest,X-Width,Y,AColors); 775 taCenter: DrawMulticolored(ADest,X-Width div 2,Y,AColors); 776 end; 777 end; 778 779 procedure TBGRATextEffect.DrawOutline(ADest: TBGRACustomBitmap; X, Y: integer; 780 AColor: TBGRAPixel); 781 begin 782 if FTextMask = nil then exit; 1183 taRightJustify: result := DrawMulticolored(ADest,X-TextSize.cx,Y,AColors); 1184 taCenter: result := DrawMulticolored(ADest,X-TextSize.cx div 2,Y,AColors); 1185 else result := DrawMulticolored(ADest,X,Y,AColors); 1186 end; 1187 end; 1188 1189 function TBGRATextEffect.DrawOutline(ADest: TBGRACustomBitmap; X, Y: integer; 1190 AColor: TBGRAPixel): TRect; 1191 begin 1192 if (FTextMask = nil) or (FTextMask.Width = 0) or (FTextMask.Height = 0) then 1193 begin 1194 result := EmptyRect; 1195 exit; 1196 end; 783 1197 if FOutlineMask = nil then 784 1198 begin … … 786 1200 FOutlineMask.LinearNegative; 787 1201 end; 788 DrawMask(ADest,FOutlineMask,X+FOffset.X,Y+FOffset.Y,AColor); 789 end; 790 791 procedure TBGRATextEffect.DrawOutline(ADest: TBGRACustomBitmap; X, Y: integer; 792 ATexture: IBGRAScanner); 793 begin 794 if FTextMask = nil then exit; 1202 result := DrawMask(ADest,FOutlineMask,X+FOffset.X,Y+FOffset.Y,AColor); 1203 end; 1204 1205 function TBGRATextEffect.DrawOutline(ADest: TBGRACustomBitmap; X, Y: integer; 1206 ATexture: IBGRAScanner): TRect; 1207 begin 1208 if (FTextMask = nil) or (FTextMask.Width = 0) or (FTextMask.Height = 0) then 1209 begin 1210 result := EmptyRect; 1211 exit; 1212 end; 795 1213 if FOutlineMask = nil then 796 1214 begin … … 798 1216 FOutlineMask.LinearNegative; 799 1217 end; 800 DrawMask(ADest,FOutlineMask,X+FOffset.X,Y+FOffset.Y,ATexture);801 end; 802 803 procedureTBGRATextEffect.DrawOutline(ADest: TBGRACustomBitmap; X, Y: integer;804 AColor: TBGRAPixel; AAlign: TAlignment) ;1218 result := DrawMask(ADest,FOutlineMask,X+FOffset.X,Y+FOffset.Y,ATexture); 1219 end; 1220 1221 function TBGRATextEffect.DrawOutline(ADest: TBGRACustomBitmap; X, Y: integer; 1222 AColor: TBGRAPixel; AAlign: TAlignment): TRect; 805 1223 begin 806 1224 Case AAlign of 807 ta LeftJustify: DrawOutline(ADest,X,Y,AColor);808 ta RightJustify: DrawOutline(ADest,X-Width,Y,AColor);809 taCenter: DrawOutline(ADest,X-Width div 2,Y,AColor);810 end; 811 end; 812 813 procedureTBGRATextEffect.DrawOutline(ADest: TBGRACustomBitmap; X, Y: integer;814 ATexture: IBGRAScanner; AAlign: TAlignment) ;1225 taRightJustify: result := DrawOutline(ADest,X-TextSize.cx,Y,AColor); 1226 taCenter: result := DrawOutline(ADest,X-TextSize.cx div 2,Y,AColor); 1227 else result := DrawOutline(ADest,X,Y,AColor); 1228 end; 1229 end; 1230 1231 function TBGRATextEffect.DrawOutline(ADest: TBGRACustomBitmap; X, Y: integer; 1232 ATexture: IBGRAScanner; AAlign: TAlignment): TRect; 815 1233 begin 816 1234 Case AAlign of 817 ta LeftJustify: DrawOutline(ADest,X,Y,ATexture);818 ta RightJustify: DrawOutline(ADest,X-Width,Y,ATexture);819 taCenter: DrawOutline(ADest,X-Width div 2,Y,ATexture);820 end; 821 end; 822 823 procedure TBGRATextEffect.DrawShadow(ADest: TBGRACustomBitmap; X, Y,Radius: integer; 824 AColor: TBGRAPixel);825 begin 826 if Radius <= 0then827 begin 828 Draw(ADest,X,Y,AColor);1235 taRightJustify: result := DrawOutline(ADest,X-TextSize.cx,Y,ATexture); 1236 taCenter: result := DrawOutline(ADest,X-TextSize.cx div 2,Y,ATexture); 1237 else result := DrawOutline(ADest,X,Y,ATexture); 1238 end; 1239 end; 1240 1241 function TBGRATextEffect.DrawShadow(ADest: TBGRACustomBitmap; X, Y, 1242 Radius: integer; AColor: TBGRAPixel): TRect; 1243 begin 1244 if (Radius <= 0) or (FTextMask = nil) or (FTextMask.Width = 0) or (FTextMask.Height = 0) then 1245 begin 1246 result := Draw(ADest,X,Y,AColor); 829 1247 exit; 830 1248 end; 831 if FTextMask = nil then exit; 832 if FShadowRadius <> Radius then 1249 if (FShadowRadius <> Radius) or (FShadowMask = nil) then 833 1250 begin 834 1251 FShadowRadius := Radius; … … 836 1253 FShadowMask := BGRABitmapFactory.Create(FTextMask.Width+Radius*2,FTextMask.Height+Radius*2,BGRABlack); 837 1254 FShadowMask.PutImage(Radius,Radius,FTextMask,dmSet); 838 BGRAReplace(FShadowMask, FShadowMask.FilterBlurRadial(Radius,rbFast)); 839 end; 840 DrawMask(ADest,FShadowMask,X-Radius+FOffset.X,Y-Radius+FOffset.Y,AColor) 841 end; 842 843 procedure TBGRATextEffect.DrawShadow(ADest: TBGRACustomBitmap; X, Y, 844 Radius: integer; AColor: TBGRAPixel; AAlign: TAlignment); 1255 BGRAReplace(FShadowMask, FShadowMask.FilterBlurRadial(Radius,ShadowQuality)); 1256 end; 1257 Inc(X,FOffset.X-Radius); 1258 Inc(Y,FOffset.Y-Radius); 1259 DrawMask(ADest,FShadowMask,X,Y,AColor); 1260 result := rect(X,Y,X+FShadowMask.Width,Y+FShadowMask.Height); 1261 end; 1262 1263 function TBGRATextEffect.DrawShadow(ADest: TBGRACustomBitmap; X, Y, 1264 Radius: integer; AColor: TBGRAPixel; AAlign: TAlignment): TRect; 845 1265 begin 846 1266 Case AAlign of 847 ta LeftJustify: DrawShadow(ADest,X,Y,Radius,AColor);848 ta RightJustify: DrawShadow(ADest,X-Width,Y,Radius,AColor);849 taCenter: DrawShadow(ADest,X-Width div 2,Y,Radius,AColor);1267 taRightJustify: result := DrawShadow(ADest,X-TextSize.cx,Y,Radius,AColor); 1268 taCenter: result := DrawShadow(ADest,X-TextSize.cx div 2,Y,Radius,AColor); 1269 else result := DrawShadow(ADest,X,Y,Radius,AColor); 850 1270 end; 851 1271 end; … … 860 1280 end; 861 1281 1282 initialization 1283 1284 BGRATextOutImproveReadabilityProc := @BGRATextOutImproveReadability; 1285 862 1286 end. 863 1287
Note:
See TracChangeset
for help on using the changeset viewer.