Nie możesz wybrać więcej, niż 25 tematów Tematy muszą się zaczynać od litery lub cyfry, mogą zawierać myślniki ('-') i mogą mieć do 35 znaków.

399 wiersze
9.1 KiB

  1. {
  2. TextSuite (C) Steffen Xonna (aka Lossy eX)
  3. http://www.opengl24.de/
  4. -----------------------------------------------------------------------
  5. For copyright informations see file copyright.txt.
  6. }
  7. {$I TextSuiteOptions.inc}
  8. unit TextSuitePostProcess;
  9. interface
  10. uses
  11. TextSuite,
  12. TextSuiteClasses;
  13. type
  14. // ** Post Processing FillColor **
  15. TtsPostFillColor = class(TtsPostProcessStep)
  16. protected
  17. fRed: Single;
  18. fGreen: Single;
  19. fBlue: Single;
  20. fAlpha: Single;
  21. fLuminance: Single;
  22. fChannelMask: tsBitmask;
  23. fModes: TtsImageModes;
  24. procedure PostProcess(const CharImage: TtsImage; const Char: TtsChar); override;
  25. public
  26. constructor Create(Red, Green, Blue, Alpha: Single; ChannelMask: tsBitmask; Modes: TtsImageModes);
  27. end;
  28. // ** Post Processing FillPattern **
  29. TtsPostFillPattern = class(TtsPostProcessStep)
  30. protected
  31. fPattern: TtsImage;
  32. fX: Integer;
  33. fY: Integer;
  34. fChannelMask: tsBitmask;
  35. fModes: TtsImageModes;
  36. procedure PostProcess(const CharImage: TtsImage; const Char: TtsChar); override;
  37. public
  38. constructor Create(Pattern: TtsImage; X, Y: Integer; ChannelMask: tsBitmask; Modes: TtsImageModes);
  39. end;
  40. // ** Post Processing Border **
  41. TtsPostBorderLookupFuncData = record
  42. Kernel: TtsKernel2D;
  43. XPos, YPos, XMax, YMax: Integer;
  44. pData: pByte;
  45. end;
  46. TtsPostBorder = class(TtsPostProcessStep)
  47. protected
  48. fKernel: TtsKernel2D;
  49. fRed: Single;
  50. fGreen: Single;
  51. fBlue: Single;
  52. fAlpha: Single;
  53. procedure PostProcess(const CharImage: TtsImage; const Char: TtsChar); override;
  54. public
  55. constructor Create(Width, Strength: Single; Red, Green, Blue, Alpha: Single);
  56. destructor Destroy; override;
  57. end;
  58. // ** Post Processing Kerning **
  59. TtsPostKerning = class(TtsPostProcessStep)
  60. protected
  61. procedure PostProcess(const CharImage: TtsImage; const Char: TtsChar); override;
  62. end;
  63. // ** Post Processing Shadow **
  64. TtsPostShadow = class(TtsPostProcessStep)
  65. protected
  66. fKernel: TtsKernel1D;
  67. fX: Integer;
  68. fY: Integer;
  69. fRed: Single;
  70. fGreen: Single;
  71. fBlue: Single;
  72. fAlpha: Single;
  73. procedure PostProcess(const CharImage: TtsImage; const Char: TtsChar); override;
  74. public
  75. constructor Create(Radius: Single; X, Y: Integer; Red, Green, Blue, Alpha: Single);
  76. destructor Destroy; override;
  77. end;
  78. // ** Post Processing Custom **
  79. TtsPostCustom = class(TtsPostProcessStep)
  80. protected
  81. fContext: TtsContext;
  82. fPostProcessProc: tsPostProcessProc;
  83. fData: Pointer;
  84. procedure PostProcess(const CharImage: TtsImage; const Char: TtsChar); override;
  85. public
  86. constructor Create(Context: TtsContext; PostProcessProc: tsPostProcessProc; Data: Pointer);
  87. end;
  88. implementation
  89. //uses
  90. // TextSuiteImageUtils;
  91. { TtsPostFillColor }
  92. constructor TtsPostFillColor.Create(Red, Green, Blue, Alpha: Single; ChannelMask: tsBitmask; Modes: TtsImageModes);
  93. begin
  94. inherited Create;
  95. fRed := Red;
  96. fGreen := Green;
  97. fBlue := Blue;
  98. fAlpha := Alpha;
  99. fChannelMask := ChannelMask;
  100. fModes := Modes;
  101. end;
  102. procedure TtsPostFillColor.PostProcess(const CharImage: TtsImage; const Char: TtsChar);
  103. begin
  104. if CharImage <> nil then
  105. CharImage.FillColor(fRed, fGreen, fBlue, fAlpha, fChannelMask, fModes);
  106. end;
  107. { TtsPostFillPattern }
  108. constructor TtsPostFillPattern.Create(Pattern: TtsImage; X, Y: Integer; ChannelMask: tsBitmask; Modes: TtsImageModes);
  109. begin
  110. inherited Create;
  111. fPattern := Pattern;
  112. fX := X;
  113. fY := Y;
  114. fChannelMask := ChannelMask;
  115. fModes := Modes;
  116. end;
  117. procedure TtsPostFillPattern.PostProcess(const CharImage: TtsImage; const Char: TtsChar);
  118. begin
  119. if CharImage <> nil then
  120. CharImage.FillPattern(fPattern, fX, fY, fChannelMask, fModes);
  121. end;
  122. { TtsPostBorder }
  123. constructor TtsPostBorder.Create(Width, Strength, Red, Green, Blue, Alpha: Single);
  124. begin
  125. inherited Create;
  126. fKernel := TtsKernel2D.Create(Width, Strength);
  127. fRed := Red;
  128. fGreen := Green;
  129. fBlue := Blue;
  130. fAlpha := Alpha;
  131. end;
  132. function BorderLookupMax(var Data: TtsPostBorderLookupFuncData): Byte;
  133. var
  134. Idx: Integer;
  135. Temp, TempValue: Single;
  136. pTempData: pByte;
  137. begin
  138. TempValue := 0;
  139. with Data, Data.Kernel do begin
  140. for Idx := 0 to ItemCount - 1 do
  141. with Items[Idx] do
  142. if ((XPos + OffsetX >= 0) and (XPos + OffsetX < XMax) and
  143. (YPos + OffsetY >= 0) and (YPos + OffsetY < YMax)) then begin
  144. pTempData := pData;
  145. Inc(pTempData, DataOffset);
  146. // there is no value
  147. if pTempData^ = $00 then
  148. Continue;
  149. // calculate pixel
  150. Temp := pTempData^ * Value;
  151. if (Temp > TempValue) then
  152. TempValue := Temp;
  153. // there is nothing greater than this
  154. if pTempData^ = $FF then
  155. Break;
  156. end;
  157. end;
  158. Result := Round(TempValue);
  159. end;
  160. destructor TtsPostBorder.Destroy;
  161. begin
  162. fKernel.Free;
  163. inherited;
  164. end;
  165. procedure TtsPostBorder.PostProcess(const CharImage: TtsImage; const Char: TtsChar);
  166. var
  167. OriginalImage: TtsImage;
  168. X, Y: Integer;
  169. pSource, pDest: ptsColor;
  170. Data: TtsPostBorderLookupFuncData;
  171. begin
  172. if CharImage <> nil then begin
  173. // Make image geater
  174. CharImage.Resize(CharImage.Width + fKernel.SizeX * 2, CharImage.Height + fKernel.SizeY * 2, fKernel.SizeX, fKernel.SizeY);
  175. // Create copy of Image
  176. OriginalImage := TtsImage.Create;
  177. try
  178. OriginalImage.AssignFrom(CharImage);
  179. CharImage.FillColor(fRed, fGreen, fBlue, fAlpha, TS_CHANNELS_RGBA, cModesReplace);
  180. fKernel.UpdateDataOffset(4, OriginalImage.Width * 4);
  181. Data.Kernel := fKernel;
  182. Data.XMax := OriginalImage.Width;
  183. Data.YMax := OriginalImage.Height;
  184. for Y := 0 to OriginalImage.Height - 1 do begin
  185. pSource := OriginalImage.ScanLine[Y];
  186. pDest := CharImage.ScanLine[Y];
  187. Data.pData := @(pSource^.Alpha);
  188. Data.YPos := Y;
  189. for X := 0 to OriginalImage.Width - 1 do begin
  190. Data.XPos := X;
  191. pDest^.Alpha := Round(fAlpha * BorderLookupMax(Data));
  192. Inc(Data.pData, 4);
  193. Inc(pDest);
  194. end;
  195. end;
  196. // Blend OriginalImage over CharImage (shadow)
  197. CharImage.BlendImage(OriginalImage, 0, 0);
  198. finally
  199. OriginalImage.Free;
  200. end;
  201. end;
  202. // Set Char Data
  203. Char.GlyphRect.Left := Char.GlyphRect.Left + fKernel.SizeX - fKernel.MidSizeX;
  204. Char.GlyphRect.Right := Char.GlyphRect.Right + fKernel.SizeX + fKernel.MidSizeX;
  205. Char.GlyphRect.Top := Char.GlyphRect.Top + fKernel.SizeY - fKernel.MidSizeY;
  206. Char.GlyphRect.Bottom := Char.GlyphRect.Bottom + fKernel.SizeY + fKernel.MidSizeY;
  207. Char.GlyphOriginY := Char.GlyphOriginY + fKernel.MidSizeY;
  208. Char.Advance := Char.Advance + fKernel.MidSizeX;
  209. end;
  210. { TtsPostKerning }
  211. procedure TtsPostKerning.PostProcess(const CharImage: TtsImage; const Char: TtsChar);
  212. begin
  213. // if CharImage <> nil then
  214. // Char.CalculateKerningData(CharImage);
  215. end;
  216. { TtsPostShadow }
  217. constructor TtsPostShadow.Create(Radius: Single; X, Y: Integer; Red, Green, Blue, Alpha: Single);
  218. begin
  219. inherited Create;
  220. fKernel := TtsKernel1D.Create(Radius, 0);
  221. fX := X;
  222. fY := Y;
  223. fRed := Red;
  224. fGreen := Green;
  225. fBlue := Blue;
  226. fAlpha := Alpha;
  227. end;
  228. destructor TtsPostShadow.Destroy;
  229. begin
  230. fKernel.Free;
  231. inherited;
  232. end;
  233. procedure TtsPostShadow.PostProcess(const CharImage: TtsImage; const Char: TtsChar);
  234. var
  235. OriginalImage: TtsImage;
  236. TempX, TempY: Integer;
  237. begin
  238. if CharImage <> nil then begin
  239. OriginalImage := TtsImage.Create;
  240. try
  241. // backup to original
  242. OriginalImage.AssignFrom(CharImage);
  243. // Resizing image
  244. CharImage.Resize(CharImage.Width + fKernel.Size * 2, CharImage.Height + fKernel.Size * 2, fKernel.Size, fKernel.Size);
  245. // fill char image with color
  246. CharImage.FillColor(fRed, fGreen, fBlue, fAlpha, TS_CHANNELS_RGBA, cModesNormal);
  247. // blur charimage
  248. CharImage.Blur(fKernel, fKernel, TS_CHANNEL_ALPHA);
  249. TempX := fKernel.Size - fX;
  250. TempY := fKernel.Size - fY;
  251. // Blend OriginalImage over CharImage (shadow)
  252. CharImage.BlendImage(OriginalImage, TempX, TempY);
  253. // Set Chardimension
  254. with Char.GlyphRect do begin
  255. if TempX > 0 then begin
  256. Left := Left + TempX;
  257. Right := Right + TempX;
  258. end;
  259. if TempY > 0 then begin
  260. Top := Top + TempY;
  261. Bottom := Bottom + TempY;
  262. end;
  263. end;
  264. finally
  265. OriginalImage.Free;
  266. end;
  267. end;
  268. end;
  269. { TtsPostCustom }
  270. constructor TtsPostCustom.Create(Context: TtsContext; PostProcessProc: tsPostProcessProc; Data: Pointer);
  271. begin
  272. inherited Create;
  273. fContext := Context;
  274. fPostProcessProc := PostProcessProc;
  275. fData := Data;
  276. end;
  277. procedure TtsPostCustom.PostProcess(const CharImage: TtsImage; const Char: TtsChar);
  278. var
  279. ImageID: tsImageID;
  280. begin
  281. if CharImage <> nil then begin
  282. if fContext <> nil then begin
  283. // temporary Add Image
  284. ImageID := fContext.ImageAdd(CharImage);
  285. try
  286. fPostProcessProc(ImageID, Char.CharCode, fData);
  287. finally
  288. fContext.ImageDelete(ImageID);
  289. end;
  290. end;
  291. end
  292. // call without an ImageID
  293. else fPostProcessProc(0, Char.CharCode, fData);
  294. end;
  295. end.