source: trunk/Packages/bgrabitmap/bgracustomtextfx.pas

Last change on this file was 2, checked in by chronos, 5 years ago
File size: 18.7 KB
Line 
1unit BGRACustomTextFX;
2
3{$mode objfpc}{$H+}
4
5interface
6
7uses
8 Classes, SysUtils, Types, BGRABitmapTypes, BGRAPhongTypes;
9
10const DefaultOutlineWidth = 3;
11
12type
13 { TBGRACustomTextEffect }
14
15 TBGRACustomTextEffect = class
16 private
17 function GetBounds: TRect;
18 function GetMaskHeight: integer;
19 class function GetOutlineWidth: integer; static;
20 function GetShadowBounds(ARadius: integer): TRect;
21 function GetMaskWidth: integer;
22 function GetTextHeight: integer;
23 function GetTextWidth: integer;
24 procedure SetShadowQuality(AValue: TRadialBlurType);
25 protected
26 FShadowQuality: TRadialBlurType;
27 FTextMask: TBGRACustomBitmap;
28 FShadowRadius: integer;
29 FOutlineMask, FShadowMask, FShadingMask : TBGRACustomBitmap;
30 FShadingAltitude: integer;
31 FShadingRounded: boolean;
32 FTextSize: TSize;
33 FOffset: TPoint;
34 function DrawMaskMulticolored(ADest: TBGRACustomBitmap; AMask: TBGRACustomBitmap; X,Y: Integer; const AColors: array of TBGRAPixel): TRect;
35 function DrawMask(ADest: TBGRACustomBitmap; AMask: TBGRACustomBitmap; X,Y: Integer; AColor: TBGRAPixel): TRect; overload;
36 function DrawMask(ADest: TBGRACustomBitmap; AMask: TBGRACustomBitmap; X,Y: Integer; ATexture: IBGRAScanner): TRect; overload;
37 function InternalDrawShaded(ADest: TBGRACustomBitmap; X,Y: integer; Shader: TCustomPhongShading; Altitude: integer; AColor: TBGRAPixel; ATexture: IBGRAScanner; ARounded: Boolean): TRect;
38 public
39 constructor Create(AMask: TBGRACustomBitmap; AMaskOwner: boolean; AWidth,AHeight: integer; AOffset: TPoint);
40 procedure ApplySphere;
41 procedure ApplyVerticalCylinder;
42 procedure ApplyHorizontalCylinder;
43 function Draw(ADest: TBGRACustomBitmap; X,Y: integer; AColor: TBGRAPixel): TRect; overload;
44 function Draw(ADest: TBGRACustomBitmap; X,Y: integer; ATexture: IBGRAScanner): TRect; overload;
45 function Draw(ADest: TBGRACustomBitmap; X, Y: integer; AColor: TBGRAPixel; AAlign: TAlignment): TRect; overload;
46 function Draw(ADest: TBGRACustomBitmap; X, Y: integer; ATexture: IBGRAScanner; AAlign: TAlignment): TRect; overload;
47
48 function DrawShaded(ADest: TBGRACustomBitmap; X,Y: integer; Shader: TCustomPhongShading; Altitude: integer; AColor: TBGRAPixel; ARounded: Boolean = true): TRect; overload;
49 function DrawShaded(ADest: TBGRACustomBitmap; X,Y: integer; Shader: TCustomPhongShading; Altitude: integer; ATexture: IBGRAScanner; ARounded: Boolean = true): TRect; overload;
50 function DrawShaded(ADest: TBGRACustomBitmap; X, Y: integer; Shader: TCustomPhongShading; Altitude: integer; AColor: TBGRAPixel; AAlign: TAlignment; ARounded: Boolean = true): TRect; overload;
51 function DrawShaded(ADest: TBGRACustomBitmap; X, Y: integer; Shader: TCustomPhongShading; Altitude: integer; ATexture: IBGRAScanner; AAlign: TAlignment; ARounded: Boolean = true): TRect; overload;
52
53 function DrawMulticolored(ADest: TBGRACustomBitmap; X,Y: integer; const AColors: array of TBGRAPixel): TRect; overload;
54 function DrawMulticolored(ADest: TBGRACustomBitmap; X,Y: integer; const AColors: array of TBGRAPixel; AAlign: TAlignment): TRect; overload;
55 function DrawOutline(ADest: TBGRACustomBitmap; X,Y: integer; AColor: TBGRAPixel): TRect; overload;
56 function DrawOutline(ADest: TBGRACustomBitmap; X,Y: integer; ATexture: IBGRAScanner): TRect; overload;
57 function DrawOutline(ADest: TBGRACustomBitmap; X,Y: integer; AColor: TBGRAPixel; AAlign: TAlignment): TRect; overload;
58 function DrawOutline(ADest: TBGRACustomBitmap; X,Y: integer; ATexture: IBGRAScanner; AAlign: TAlignment): TRect; overload;
59 function DrawShadow(ADest: TBGRACustomBitmap; X,Y,Radius: integer; AColor: TBGRAPixel): TRect; overload;
60 function DrawShadow(ADest: TBGRACustomBitmap; X,Y,Radius: integer; AColor: TBGRAPixel; AAlign: TAlignment): TRect; overload;
61 destructor Destroy; override;
62 property TextMask: TBGRACustomBitmap read FTextMask;
63 property TextMaskOffset: TPoint read FOffset;
64 property Width: integer read GetTextWidth; deprecated;
65 property Height: integer read GetTextHeight; deprecated;
66 property MaskWidth: integer read GetMaskWidth;
67 property MaskHeight: integer read GetMaskHeight;
68 property TextSize: TSize read FTextSize;
69 property TextWidth: integer read GetTextWidth;
70 property TextHeight: integer read GetTextHeight;
71 property Bounds: TRect read GetBounds;
72 property ShadowBounds[ARadius: integer]: TRect read GetShadowBounds;
73 property ShadowQuality: TRadialBlurType read FShadowQuality write SetShadowQuality;
74 class property OutlineWidth: integer read GetOutlineWidth;
75 end;
76
77implementation
78
79uses Math, BGRAGradientScanner;
80
81procedure BGRACustomReplace(var Destination: TBGRACustomBitmap; Temp: TObject);
82begin
83 Destination.Free;
84 Destination := Temp as TBGRACustomBitmap;
85end;
86
87{ TBGRACustomTextEffect }
88
89function TBGRACustomTextEffect.GetBounds: TRect;
90begin
91 if TextMask = nil then
92 result := EmptyRect else
93 with TextMaskOffset do
94 result := rect(X,Y,X+TextMask.Width,Y+TextMask.Height);
95end;
96
97function TBGRACustomTextEffect.GetMaskHeight: integer;
98begin
99 if FTextMask = nil then
100 result := 0
101 else
102 result := FTextMask.Height;
103end;
104
105class function TBGRACustomTextEffect.GetOutlineWidth: integer; static;
106begin
107 result := DefaultOutlineWidth;
108end;
109
110function TBGRACustomTextEffect.GetShadowBounds(ARadius: integer): TRect;
111begin
112 result := Bounds;
113 if (ARadius > 0) and not IsRectEmpty(result) then
114 begin
115 result.left -= ARadius;
116 result.top -= ARadius;
117 result.right += ARadius;
118 result.bottom += ARadius;
119 end;
120end;
121
122function TBGRACustomTextEffect.GetMaskWidth: integer;
123begin
124 if FTextMask = nil then
125 result := 0
126 else
127 result := FTextMask.Width;
128end;
129
130function TBGRACustomTextEffect.GetTextHeight: integer;
131begin
132 result := FTextSize.cy;
133end;
134
135function TBGRACustomTextEffect.GetTextWidth: integer;
136begin
137 result := FTextSize.cx;
138end;
139
140procedure TBGRACustomTextEffect.SetShadowQuality(AValue: TRadialBlurType);
141begin
142 if FShadowQuality=AValue then Exit;
143 FShadowQuality:=AValue;
144 FreeAndNil(FShadowMask);
145end;
146
147function TBGRACustomTextEffect.DrawMaskMulticolored(ADest: TBGRACustomBitmap;
148 AMask: TBGRACustomBitmap; X, Y: Integer; const AColors: array of TBGRAPixel
149 ): TRect;
150var
151 scan: TBGRASolidColorMaskScanner;
152 xb,yb,startX,numColor: integer;
153 p0,p: PBGRAPixel;
154 emptyCol, nextCol: boolean;
155begin
156 if (AMask = nil) or (length(AColors)=0) then
157 begin
158 result := EmptyRect;
159 exit;
160 end;
161 if (length(AColors)=0) then
162 begin
163 result := DrawMask(ADest,AMask,X,Y,AColors[0]);
164 exit;
165 end;
166 scan := TBGRASolidColorMaskScanner.Create(AMask,Point(-X,-Y),AColors[0]);
167 numColor := 0;
168 startX := -1;
169 p0 := AMask.data;
170 for xb := 0 to AMask.Width-1 do
171 begin
172 p := p0;
173
174 if startX=-1 then
175 begin
176 emptyCol := true;
177 for yb := AMask.Height-1 downto 0 do
178 begin
179 if (p^<>BGRABlack) then
180 begin
181 emptyCol := false;
182 break;
183 end;
184 inc(p, AMask.Width);
185 end;
186
187 if not emptyCol then
188 begin
189 if startX=-1 then
190 startX := xb;
191 end else
192 begin
193 if startX<>-1 then
194 begin
195 ADest.FillRect(X+startX,Y,X+xb,Y+AMask.Height,scan,dmDrawWithTransparency);
196 inc(numColor);
197 if numColor = length(AColors) then
198 numColor := 0;
199 scan.Color := AColors[numColor];
200 startX := -1;
201 end;
202 end;
203
204 end else
205 begin
206 emptyCol := true;
207 nextCol := true;
208 for yb := AMask.Height-1 downto 0 do
209 begin
210 if (p^<>BGRABlack) then
211 begin
212 emptyCol := false;
213 if ((p-1)^<>BGRABlack) then
214 begin
215 nextCol := false;
216 break;
217 end;
218 end;
219 inc(p, AMask.Width);
220 end;
221 if nextCol or emptyCol then
222 begin
223 ADest.FillRect(X+startX,Y,X+xb,Y+AMask.Height,scan,dmDrawWithTransparency);
224 inc(numColor);
225 if numColor = length(AColors) then
226 numColor := 0;
227 scan.Color := AColors[numColor];
228 if emptyCol then startX := -1
229 else startX := xb;
230 end;
231 end;
232
233 inc(p0);
234 end;
235 if startX<>-1 then
236 ADest.FillRect(X+startX,Y,X+AMask.Width,Y+AMask.Height,scan,dmDrawWithTransparency);
237 scan.Free;
238 result := rect(X,Y,X+AMask.Width,Y+AMask.Height);
239end;
240
241function TBGRACustomTextEffect.DrawMask(ADest: TBGRACustomBitmap;
242 AMask: TBGRACustomBitmap; X, Y: Integer; AColor: TBGRAPixel): TRect;
243var
244 scan: TBGRACustomScanner;
245begin
246 if AMask = nil then
247 begin
248 result := EmptyRect;
249 exit;
250 end;
251 scan := TBGRASolidColorMaskScanner.Create(AMask,Point(-X,-Y),AColor);
252 ADest.FillRect(X,Y,X+AMask.Width,Y+AMask.Height,scan,dmDrawWithTransparency);
253 scan.Free;
254 result := rect(X,Y,X+AMask.Width,Y+AMask.Height);
255end;
256
257function TBGRACustomTextEffect.DrawMask(ADest: TBGRACustomBitmap;
258 AMask: TBGRACustomBitmap; X, Y: Integer; ATexture: IBGRAScanner): TRect;
259var
260 scan: TBGRACustomScanner;
261begin
262 if AMask = nil then
263 begin
264 result := EmptyRect;
265 exit;
266 end;
267 scan := TBGRATextureMaskScanner.Create(AMask,Point(-X,-Y),ATexture);
268 ADest.FillRect(X,Y,X+AMask.Width,Y+AMask.Height,scan,dmDrawWithTransparency);
269 scan.Free;
270 result := rect(X,Y,X+AMask.Width,Y+AMask.Height);
271end;
272
273function TBGRACustomTextEffect.InternalDrawShaded(ADest: TBGRACustomBitmap; X,
274 Y: integer; Shader: TCustomPhongShading; Altitude: integer;
275 AColor: TBGRAPixel; ATexture: IBGRAScanner; ARounded: Boolean): TRect;
276var
277 WithMargin,Map: TBGRACustomBitmap;
278 p: PBGRAPixel;
279 n,maxv: integer;
280 v,blurRadius: single;
281 iBlurRadius: integer;
282begin
283 if (FTextMask = nil) or (FTextMask.Width = 0) or (FTextMask.Height = 0) then
284 begin
285 result := EmptyRect;
286 exit;
287 end;
288
289 if (FShadingMask <> nil) and ((FShadingAltitude <> Altitude) or (FShadingRounded <> ARounded)) then
290 FreeAndNil(FShadingMask);
291
292 if FShadingMask = nil then
293 begin
294 FShadingRounded := ARounded;
295 FShadingAltitude := Altitude;
296
297 if ARounded then blurRadius := Altitude
298 else blurRadius := Altitude*0.5;
299
300 iBlurRadius := ceil(blurRadius);
301
302 WithMargin := BGRABitmapFactory.Create(FTextMask.Width+iBlurRadius*2, FTextMask.Height+iBlurRadius*2,BGRABlack);
303 WithMargin.PutImage(iBlurRadius,iBlurRadius,FTextMask,dmSet);
304 if (iBlurRadius <> blurRadius) and (blurRadius < 3) then
305 Map := WithMargin.FilterBlurRadial(round(blurRadius*10),rbPrecise)
306 else
307 Map := WithMargin.FilterBlurRadial(iBlurRadius,rbFast);
308
309 p := Map.Data;
310 maxv := 0;
311 for n := Map.NbPixels-1 downto 0 do
312 begin
313 if p^.green > maxv then
314 maxv := p^.green;
315 inc(p);
316 end;
317
318 if maxv > 0 then
319 begin
320 p := Map.Data;
321 for n := Map.NbPixels-1 downto 0 do
322 begin
323 v := p^.green/maxv;
324 if ARounded then
325 begin
326 if v <= 0.5 then
327 v := v*v*2 else
328 v := 1-(1-v)*(1-v)*2;
329 end;
330 p^ := MapHeightToBGRA( v, p^.alpha);
331 inc(p);
332 end;
333 end;
334
335 Map.ApplyMask(WithMargin);
336 WithMargin.Free;
337 BGRACustomReplace(Map, Map.GetPart(rect(iBlurRadius,iBlurRadius,Map.Width-iBlurRadius,Map.Height-iBlurRadius)));
338 FShadingMask := Map;
339 end;
340
341 inc(X, FOffset.X);
342 Inc(Y, FOffset.Y);
343 if ATexture <> nil then
344 Shader.DrawScan(ADest,FShadingMask,Altitude,X,Y, ATexture)
345 else
346 Shader.Draw(ADest,FShadingMask,Altitude,X,Y, AColor);
347 result := rect(X,Y, X+FShadingMask.Width,Y+FShadingMask.Height);
348end;
349
350function TBGRACustomTextEffect.Draw(ADest: TBGRACustomBitmap; X, Y: integer;
351 AColor: TBGRAPixel; AAlign: TAlignment): TRect;
352begin
353 Case AAlign of
354 taRightJustify: result := Draw(ADest,X-TextSize.cx,Y,AColor);
355 taCenter: result := Draw(ADest,X-TextSize.cx div 2,Y,AColor);
356 else result := Draw(ADest,X,Y,AColor);
357 end;
358end;
359
360function TBGRACustomTextEffect.Draw(ADest: TBGRACustomBitmap; X, Y: integer;
361 ATexture: IBGRAScanner; AAlign: TAlignment): TRect;
362begin
363 Case AAlign of
364 taRightJustify: result := Draw(ADest,X-TextSize.cx,Y,ATexture);
365 taCenter: result := Draw(ADest,X-TextSize.cx div 2,Y,ATexture);
366 else result := Draw(ADest,X,Y,ATexture);
367 end;
368end;
369
370function TBGRACustomTextEffect.DrawShaded(ADest: TBGRACustomBitmap; X, Y: integer;
371 Shader: TCustomPhongShading; Altitude: integer; AColor: TBGRAPixel;
372 ARounded: Boolean): TRect;
373begin
374 result := InternalDrawShaded(ADest,X,Y,Shader,Altitude,AColor,nil,ARounded);
375end;
376
377function TBGRACustomTextEffect.DrawShaded(ADest: TBGRACustomBitmap; X, Y: integer;
378 Shader: TCustomPhongShading; Altitude: integer; ATexture: IBGRAScanner;
379 ARounded: Boolean): TRect;
380begin
381 result := InternalDrawShaded(ADest,X,Y,Shader,Altitude,BGRAPixelTransparent,ATexture,ARounded);
382end;
383
384function TBGRACustomTextEffect.DrawShaded(ADest: TBGRACustomBitmap; X, Y: integer;
385 Shader: TCustomPhongShading; Altitude: integer; AColor: TBGRAPixel;
386 AAlign: TAlignment; ARounded: Boolean): TRect;
387begin
388 Case AAlign of
389 taLeftJustify: result := DrawShaded(ADest,X,Y,Shader,Altitude,AColor,ARounded);
390 taRightJustify: result := DrawShaded(ADest,X-TextSize.cx,Y,Shader,Altitude,AColor,ARounded);
391 taCenter: result := DrawShaded(ADest,X-TextSize.cx div 2,Y,Shader,Altitude,AColor,ARounded);
392 else
393 result := EmptyRect;
394 end;
395end;
396
397function TBGRACustomTextEffect.DrawShaded(ADest: TBGRACustomBitmap; X, Y: integer;
398 Shader: TCustomPhongShading; Altitude: integer; ATexture: IBGRAScanner;
399 AAlign: TAlignment; ARounded: Boolean): TRect;
400begin
401 Case AAlign of
402 taLeftJustify: result := DrawShaded(ADest,X,Y,Shader,Altitude,ATexture,ARounded);
403 taRightJustify: result := DrawShaded(ADest,X-TextSize.cx,Y,Shader,Altitude,ATexture,ARounded);
404 taCenter: result := DrawShaded(ADest,X-TextSize.cx div 2,Y,Shader,Altitude,ATexture,ARounded);
405 else
406 result := EmptyRect;
407 end;
408end;
409
410constructor TBGRACustomTextEffect.Create(AMask: TBGRACustomBitmap; AMaskOwner: boolean; AWidth,
411 AHeight: integer; AOffset: TPoint);
412begin
413 FTextSize := Size(AWidth,AHeight);
414 FOffset := AOffset;
415 if not AMaskOwner then
416 FTextMask := AMask.Duplicate()
417 else
418 FTextMask := AMask;
419 FShadowQuality:= rbFast;
420end;
421
422procedure TBGRACustomTextEffect.ApplySphere;
423var sphere: TBGRACustomBitmap;
424begin
425 if FTextMask = nil then exit;
426 FreeAndNil(FOutlineMask);
427 FreeAndNil(FShadowMask);
428 FShadowRadius := 0;
429 sphere := FTextMask.FilterSphere;
430 FTextMask.Fill(BGRABlack);
431 FTextMask.PutImage(0,0,sphere,dmDrawWithTransparency);
432 sphere.Free;
433end;
434
435procedure TBGRACustomTextEffect.ApplyVerticalCylinder;
436begin
437 if FTextMask = nil then exit;
438 FreeAndNil(FOutlineMask);
439 FreeAndNil(FShadowMask);
440 FShadowRadius := 0;
441 BGRACustomReplace(FTextMask,FTextMask.FilterCylinder);
442end;
443
444procedure TBGRACustomTextEffect.ApplyHorizontalCylinder;
445begin
446 if FTextMask = nil then exit;
447 FreeAndNil(FOutlineMask);
448 FreeAndNil(FShadowMask);
449 FShadowRadius := 0;
450 BGRACustomReplace(FTextMask,FTextMask.RotateCW);
451 BGRACustomReplace(FTextMask,FTextMask.FilterCylinder);
452 BGRACustomReplace(FTextMask,FTextMask.RotateCCW);
453end;
454
455function TBGRACustomTextEffect.Draw(ADest: TBGRACustomBitmap; X, Y: integer;
456 AColor: TBGRAPixel): TRect;
457begin
458 result := DrawMask(ADest,FTextMask,X+FOffset.X,Y+FOffset.Y,AColor);
459end;
460
461function TBGRACustomTextEffect.Draw(ADest: TBGRACustomBitmap; X, Y: integer;
462 ATexture: IBGRAScanner): TRect;
463begin
464 result := DrawMask(ADest,FTextMask,X+FOffset.X,Y+FOffset.Y,ATexture);
465end;
466
467function TBGRACustomTextEffect.DrawMulticolored(ADest: TBGRACustomBitmap; X,
468 Y: integer; const AColors: array of TBGRAPixel): TRect;
469begin
470 result := DrawMaskMulticolored(ADest,FTextMask,X+FOffset.X,Y+FOffset.Y,AColors);
471end;
472
473function TBGRACustomTextEffect.DrawMulticolored(ADest: TBGRACustomBitmap; X,
474 Y: integer; const AColors: array of TBGRAPixel; AAlign: TAlignment): TRect;
475begin
476 Case AAlign of
477 taRightJustify: result := DrawMulticolored(ADest,X-TextSize.cx,Y,AColors);
478 taCenter: result := DrawMulticolored(ADest,X-TextSize.cx div 2,Y,AColors);
479 else result := DrawMulticolored(ADest,X,Y,AColors);
480 end;
481end;
482
483function TBGRACustomTextEffect.DrawOutline(ADest: TBGRACustomBitmap; X, Y: integer;
484 AColor: TBGRAPixel): TRect;
485begin
486 if (FTextMask = nil) or (FTextMask.Width = 0) or (FTextMask.Height = 0) then
487 begin
488 result := EmptyRect;
489 exit;
490 end;
491 if FOutlineMask = nil then
492 begin
493 FOutlineMask := FTextMask.FilterContour;
494 FOutlineMask.LinearNegative;
495 end;
496 result := DrawMask(ADest,FOutlineMask,X+FOffset.X,Y+FOffset.Y,AColor);
497end;
498
499function TBGRACustomTextEffect.DrawOutline(ADest: TBGRACustomBitmap; X, Y: integer;
500 ATexture: IBGRAScanner): TRect;
501begin
502 if (FTextMask = nil) or (FTextMask.Width = 0) or (FTextMask.Height = 0) then
503 begin
504 result := EmptyRect;
505 exit;
506 end;
507 if FOutlineMask = nil then
508 begin
509 FOutlineMask := FTextMask.FilterContour;
510 FOutlineMask.LinearNegative;
511 end;
512 result := DrawMask(ADest,FOutlineMask,X+FOffset.X,Y+FOffset.Y,ATexture);
513end;
514
515function TBGRACustomTextEffect.DrawOutline(ADest: TBGRACustomBitmap; X, Y: integer;
516 AColor: TBGRAPixel; AAlign: TAlignment): TRect;
517begin
518 Case AAlign of
519 taRightJustify: result := DrawOutline(ADest,X-TextSize.cx,Y,AColor);
520 taCenter: result := DrawOutline(ADest,X-TextSize.cx div 2,Y,AColor);
521 else result := DrawOutline(ADest,X,Y,AColor);
522 end;
523end;
524
525function TBGRACustomTextEffect.DrawOutline(ADest: TBGRACustomBitmap; X, Y: integer;
526 ATexture: IBGRAScanner; AAlign: TAlignment): TRect;
527begin
528 Case AAlign of
529 taRightJustify: result := DrawOutline(ADest,X-TextSize.cx,Y,ATexture);
530 taCenter: result := DrawOutline(ADest,X-TextSize.cx div 2,Y,ATexture);
531 else result := DrawOutline(ADest,X,Y,ATexture);
532 end;
533end;
534
535function TBGRACustomTextEffect.DrawShadow(ADest: TBGRACustomBitmap; X, Y,
536 Radius: integer; AColor: TBGRAPixel): TRect;
537begin
538 if (Radius <= 0) or (FTextMask = nil) or (FTextMask.Width = 0) or (FTextMask.Height = 0) then
539 begin
540 result := Draw(ADest,X,Y,AColor);
541 exit;
542 end;
543 if (FShadowRadius <> Radius) or (FShadowMask = nil) then
544 begin
545 FShadowRadius := Radius;
546 FreeAndNil(FShadowMask);
547 FShadowMask := BGRABitmapFactory.Create(FTextMask.Width+Radius*2,FTextMask.Height+Radius*2,BGRABlack);
548 FShadowMask.PutImage(Radius,Radius,FTextMask,dmSet);
549 BGRACustomReplace(FShadowMask, FShadowMask.FilterBlurRadial(Radius,ShadowQuality));
550 end;
551 Inc(X,FOffset.X-Radius);
552 Inc(Y,FOffset.Y-Radius);
553 DrawMask(ADest,FShadowMask,X,Y,AColor);
554 result := rect(X,Y,X+FShadowMask.Width,Y+FShadowMask.Height);
555end;
556
557function TBGRACustomTextEffect.DrawShadow(ADest: TBGRACustomBitmap; X, Y,
558 Radius: integer; AColor: TBGRAPixel; AAlign: TAlignment): TRect;
559begin
560 Case AAlign of
561 taRightJustify: result := DrawShadow(ADest,X-TextSize.cx,Y,Radius,AColor);
562 taCenter: result := DrawShadow(ADest,X-TextSize.cx div 2,Y,Radius,AColor);
563 else result := DrawShadow(ADest,X,Y,Radius,AColor);
564 end;
565end;
566
567destructor TBGRACustomTextEffect.Destroy;
568begin
569 FShadowMask.free;
570 textMask.Free;
571 FOutlineMask.Free;
572 FShadingMask.Free;
573 inherited Destroy;
574end;
575
576end.
577
Note: See TracBrowser for help on using the repository browser.