Non puoi selezionare più di 25 argomenti Gli argomenti devono iniziare con una lettera o un numero, possono includere trattini ('-') e possono essere lunghi fino a 35 caratteri.

262 righe
9.2 KiB

  1. unit utsPostProcess;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, utsTextSuite, utsTypes;
  6. type
  7. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  8. TtsPostProcessFillColor = class(TtsPostProcessStep)
  9. private
  10. fColor: TtsColor4f;
  11. fModes: TtsImageModes;
  12. fChannels: TtsColorChannels;
  13. protected
  14. procedure Execute(const aChar: TtsChar; const aCharImage: TtsImage); override;
  15. public
  16. constructor Create(const aColor: TtsColor4f;
  17. const aModes: TtsImageModes; const aChannels: TtsColorChannels);
  18. end;
  19. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  20. TtsPostProcessFillPattern = class(TtsPostProcessStep)
  21. private
  22. fPattern: TtsImage;
  23. fOwnsPattern: Boolean;
  24. fX, fY: Integer;
  25. fModes: TtsImageModes;
  26. fChannels: TtsColorChannels;
  27. protected
  28. procedure Execute(const aChar: TtsChar; const aCharImage: TtsImage); override;
  29. public
  30. constructor Create(const aPattern: TtsImage; const aOwnsPattern: Boolean; const X, Y: Integer;
  31. const aModes: TtsImageModes; const aChannels: TtsColorChannels);
  32. destructor Destroy; override;
  33. end;
  34. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  35. TtsPostProcessBorder = class(TtsPostProcessStep)
  36. private
  37. fKernel: TtsKernel2D;
  38. fColor: TtsColor4f;
  39. fUpdateCharSize: Boolean;
  40. public
  41. procedure Execute(const aChar: TtsChar; const aCharImage: TtsImage); override;
  42. public
  43. constructor Create(const aWidth, aStrength: Single; const aColor: TtsColor4f;
  44. const aUpdateCharSize: Boolean = false);
  45. destructor Destroy; override;
  46. end;
  47. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  48. TtsPostProcessShadow = class(TtsPostProcessStep)
  49. private
  50. fKernel: TtsKernel1D;
  51. fColor: TtsColor4f;
  52. fX, fY: Integer;
  53. protected
  54. procedure Execute(const aChar: TtsChar; const aCharImage: TtsImage); override;
  55. public
  56. constructor Create(const aRadius, aStrength: Single; const X, Y: Integer; const aColor: TtsColor4f);
  57. destructor Destroy; override;
  58. end;
  59. implementation
  60. uses
  61. Math;
  62. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  63. //TtsPostProcessFillColor///////////////////////////////////////////////////////////////////////////////////////////////
  64. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  65. procedure TtsPostProcessFillColor.Execute(const aChar: TtsChar; const aCharImage: TtsImage);
  66. begin
  67. if Assigned(aCharImage) then
  68. aCharImage.FillColor(fColor, fChannels, fModes);
  69. end;
  70. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  71. constructor TtsPostProcessFillColor.Create(const aColor: TtsColor4f; const aModes: TtsImageModes; const aChannels: TtsColorChannels);
  72. begin
  73. inherited Create;
  74. fColor := aColor;
  75. fModes := aModes;
  76. fChannels := aChannels;
  77. end;
  78. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  79. //TtsPostProcessFillPattern/////////////////////////////////////////////////////////////////////////////////////////////
  80. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  81. procedure TtsPostProcessFillPattern.Execute(const aChar: TtsChar; const aCharImage: TtsImage);
  82. begin
  83. if Assigned(aCharImage) then
  84. aCharImage.FillPattern(fPattern, fX, fY, fChannels, fModes);
  85. end;
  86. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  87. constructor TtsPostProcessFillPattern.Create(const aPattern: TtsImage; const aOwnsPattern: Boolean; const X,
  88. Y: Integer; const aModes: TtsImageModes; const aChannels: TtsColorChannels);
  89. begin
  90. inherited Create;
  91. fPattern := aPattern;
  92. fOwnsPattern := aOwnsPattern;
  93. fX := X;
  94. fY := Y;
  95. fModes := aModes;
  96. fChannels := aChannels;
  97. end;
  98. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  99. destructor TtsPostProcessFillPattern.Destroy;
  100. begin
  101. if fOwnsPattern then
  102. FreeAndNil(fPattern);
  103. inherited Destroy;
  104. end;
  105. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  106. //TtsPostProcessBorder//////////////////////////////////////////////////////////////////////////////////////////////////
  107. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  108. procedure TtsPostProcessBorder.Execute(const aChar: TtsChar; const aCharImage: TtsImage);
  109. var
  110. orig: TtsImage;
  111. x, y: Integer;
  112. dst: PByte;
  113. function BorderLookup: TtsColor4f;
  114. var
  115. i: Integer;
  116. c: TtsColor4f;
  117. s: Single;
  118. chan: TtsColorChannel;
  119. mask: TtsColorChannels;
  120. tmpX, tmpY: Integer;
  121. begin
  122. mask := TS_CHANNELS_RGBA;
  123. result := tsColor4f(0, 0, 0, 0);
  124. for i := 0 to fKernel.ItemCount-1 do begin
  125. tmpX := x + fKernel.Items[i].OffsetX;
  126. tmpY := y + fKernel.Items[i].OffsetY;
  127. if (tmpX >= 0) and (tmpX < orig.Width) and
  128. (tmpY >= 0) and (tmpY < orig.Height) and
  129. orig.GetPixelAt(tmpX, tmpY, c) then
  130. begin
  131. for chan in mask do begin
  132. s := c.arr[Integer(chan)] * fColor.arr[Integer(chan)] * fKernel.Items[i].Value;
  133. if (s > result.arr[Integer(chan)]) then begin
  134. result.arr[Integer(chan)] := s;
  135. if (s >= 1.0) then begin
  136. Exclude(mask, chan);
  137. if (mask = []) then
  138. exit;
  139. end;
  140. end;
  141. end;
  142. end;
  143. end;
  144. end;
  145. begin
  146. if not Assigned(aCharImage) then
  147. exit;
  148. aCharImage.Resize(
  149. aCharImage.Width + 2 * fKernel.SizeX,
  150. aCharImage.Height + 2 * fKernel.SizeY,
  151. fKernel.SizeX, fKernel.SizeY);
  152. orig := TtsImage.Create;
  153. try
  154. orig.Assign(aCharImage);
  155. aCharImage.FillColor(fColor, TS_CHANNELS_RGBA, TS_MODES_REPLACE_ALL);
  156. for y := 0 to orig.Height-1 do begin
  157. dst := aCharImage.Scanline[y];
  158. for x := 0 to orig.Width-1 do
  159. tsFormatMap(aCharImage.Format, dst, BorderLookup);
  160. end;
  161. aCharImage.Blend(orig, 0, 0, @tsBlendFundAdditiveAlpha);
  162. finally
  163. FreeAndNil(orig);
  164. end;
  165. if fUpdateCharSize then begin
  166. aChar.GlyphRect := tsRect(
  167. aChar.GlyphRect.Left + fKernel.SizeX - fKernel.MidSizeX,
  168. aChar.GlyphRect.Top + fKernel.SizeY - fKernel.MidSizeY,
  169. aChar.GlyphRect.Right + fKernel.SizeX + fKernel.MidSizeX,
  170. aChar.GlyphRect.Bottom + fKernel.SizeY + fKernel.MidSizeY);
  171. aChar.GlyphOrigin := tsPosition(
  172. aChar.GlyphOrigin.x + fKernel.MidSizeX,
  173. aChar.GlyphOrigin.y + fKernel.MidSizeY);
  174. aChar.Advance := aChar.Advance + fKernel.MidSizeX ;
  175. end;
  176. end;
  177. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  178. constructor TtsPostProcessBorder.Create(const aWidth, aStrength: Single; const aColor: TtsColor4f;
  179. const aUpdateCharSize: Boolean);
  180. begin
  181. inherited Create;
  182. fKernel := TtsKernel2D.Create(aWidth, aStrength);
  183. fColor := aColor;
  184. fUpdateCharSize := aUpdateCharSize;
  185. end;
  186. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  187. destructor TtsPostProcessBorder.Destroy;
  188. begin
  189. FreeAndNil(fKernel);
  190. inherited Destroy;
  191. end;
  192. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  193. //TtsPostProcessShadow//////////////////////////////////////////////////////////////////////////////////////////////////
  194. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  195. procedure TtsPostProcessShadow.Execute(const aChar: TtsChar; const aCharImage: TtsImage);
  196. var
  197. orig: TtsImage;
  198. tmpX, tmpY: Integer;
  199. begin
  200. orig := TtsImage.Create;
  201. try
  202. orig.Assign(aCharImage);
  203. aCharImage.Resize(
  204. aCharImage.Width + 2 * fKernel.Size,
  205. aCharImage.Height + 2 * fKernel.Size,
  206. fKernel.Size, fKernel.Size);
  207. aCharImage.FillColor(fColor, TS_CHANNELS_RGBA, TS_MODES_MODULATE_ALPHA);
  208. aCharImage.Blur(fKernel, fKernel, [tsChannelAlpha]);
  209. tmpX := fKernel.Size - fX;
  210. tmpY := fKernel.Size - fY;
  211. aCharImage.Blend(orig, tmpX, tmpY, @tsBlendFundAlpha);
  212. finally
  213. FreeAndNil(orig);
  214. end;
  215. end;
  216. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  217. constructor TtsPostProcessShadow.Create(const aRadius, aStrength: Single; const X, Y: Integer; const aColor: TtsColor4f);
  218. begin
  219. inherited Create;
  220. fKernel := TtsKernel1D.Create(aRadius, aStrength);
  221. fX := X;
  222. fY := Y;
  223. fColor := aColor;
  224. end;
  225. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  226. destructor TtsPostProcessShadow.Destroy;
  227. begin
  228. FreeAndNil(fKernel);
  229. inherited Destroy;
  230. end;
  231. end.