Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.
 
 
 
 
 

334 rader
15 KiB

  1. unit ultsUtils;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils,
  6. uutlGenerics,
  7. ultsTypes,
  8. utsTextSuite;
  9. type
  10. TtsPostProcessorClass = class of TtsPostProcessor;
  11. procedure SetLastError(const aEx: Exception);
  12. procedure SetLastError(const aErrorCode: TltsErrorCode; const aErrorMsg: String);
  13. function CheckIfInitialized: Boolean;
  14. function CheckContextHandle(const aHandle: TltsContextHandle; out aContext: TtsContext): Boolean;
  15. function CheckRendererHandle(const aHandle: TltsContextHandle; out aRenderer: TtsRenderer): Boolean;
  16. function CheckTextBlockHandle(const aHandle: TltsTextBlockHandle; out aTextBlock: TtsTextBlock): Boolean;
  17. function CheckFontHandle(const aHandle: TltsFontHandle; out aFont: TtsFont): Boolean;
  18. function CheckFontCreatorHandle(const aHandle: TltsFontCreatorHandle; out aFontCreator: TtsFontCreator): Boolean;
  19. function CheckImageHandle(const aHandle: TltsImageHandle; out aImage: TtsImage): Boolean;
  20. function CheckCharHandle(const aHandle: TltsCharHandle; out aChar: TtsChar): Boolean;
  21. function CheckPostProcessorHandle(const aHandle: TltsPostProcessorHandle; const aType: TtsPostProcessorClass; out aPostProcessor): Boolean;
  22. procedure AddReference(const aType: TltsObjectType; const aRef: TObject);
  23. procedure DelReference(const aType: TltsObjectType; const aRef: TObject);
  24. procedure DelReference(const aRef: TObject);
  25. function ValidateCodePage(const aValue: TtsCodePage): Boolean;
  26. function ValidateFormat(const aValue: TtsFormat): Boolean;
  27. function ValidateCharRangeUsage(const aValue: TtsCharRangeUsage): Boolean;
  28. procedure Initialize;
  29. procedure Finalize;
  30. type
  31. TltsStreamImpl = class(TStream)
  32. private
  33. fStream: PltsStream;
  34. public
  35. function Read(var Buffer; Count: Longint): Longint; override;
  36. function Seek(Offset: Longint; Origin: Word): Longint; override; overload;
  37. constructor Create(const aStream: PltsStream);
  38. end;
  39. var
  40. LastErrorCode: TltsErrorCode = ltsErrNone;
  41. LastErrorMsg: String;
  42. implementation
  43. type
  44. TtsContextHashSet = specialize TutlHashSet<TtsContext>;
  45. TtsRendererHashSet = specialize TutlHashSet<TtsRenderer>;
  46. TtsTextBlockHashSet = specialize TutlHashSet<TtsTextBlock>;
  47. TtsFontHashSet = specialize TutlHashSet<TtsFont>;
  48. TtsFontCreatorHashSet = specialize TutlHashSet<TtsFontCreator>;
  49. TtsImageHashSet = specialize TutlHashSet<TtsImage>;
  50. TtsPostProcessorHashSet = specialize TutlHashSet<TtsPostProcessor>;
  51. TtsCharHashSet = specialize TutlHashSet<TtsChar>;
  52. var
  53. IsInitilized: Boolean = false;
  54. Contexts: TtsContextHashSet = nil;
  55. Renderers: TtsRendererHashSet = nil;
  56. TextBlocks: TtsTextBlockHashSet = nil;
  57. Fonts: TtsFontHashSet = nil;
  58. FontCreators: TtsFontCreatorHashSet = nil;
  59. Images: TtsImageHashSet = nil;
  60. PostProcessors: TtsPostProcessorHashSet = nil;
  61. Chars: TtsCharHashSet = nil;
  62. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  63. procedure SetLastError(const aEx: Exception);
  64. begin
  65. LastErrorCode := ltsErrUnknown;
  66. LastErrorMsg := aEx.Message;
  67. end;
  68. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  69. procedure SetLastError(const aErrorCode: TltsErrorCode; const aErrorMsg: String);
  70. begin
  71. LastErrorCode := aErrorCode;
  72. LastErrorMsg := aErrorMsg;
  73. end;
  74. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  75. function CheckIfInitialized: Boolean;
  76. begin
  77. result := IsInitilized;
  78. if not result then
  79. SetLastError(ltsErrNotInitialized, 'libTextSuite has not been initialized. call ltsInitialize before using any other methods.');
  80. end;
  81. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  82. function CheckContextHandle(const aHandle: TltsContextHandle; out aContext: TtsContext): Boolean;
  83. begin
  84. result := CheckIfInitialized;
  85. if result then begin
  86. aContext := TtsContext(aHandle);
  87. result := Contexts.Contains(aContext);
  88. if not result then
  89. SetLastError(ltsErrInvalidContextHandle, Format('0x%.16x is not a valid context handle', [{%H-}PtrUInt(aHandle)]));
  90. end;
  91. end;
  92. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  93. function CheckRendererHandle(const aHandle: TltsContextHandle; out aRenderer: TtsRenderer): Boolean;
  94. begin
  95. result := CheckIfInitialized;
  96. if result then begin
  97. aRenderer := TtsRenderer(aHandle);
  98. result := Renderers.Contains(aRenderer);
  99. if not result then
  100. SetLastError(ltsErrInvalidRendererHandle, Format('0x%.16x is not a valid renderer handle', [{%H-}PtrUInt(aHandle)]));
  101. end;
  102. end;
  103. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  104. function CheckTextBlockHandle(const aHandle: TltsTextBlockHandle; out aTextBlock: TtsTextBlock): Boolean;
  105. begin
  106. result := CheckIfInitialized;
  107. if result then begin
  108. aTextBlock := TtsTextBlock(aHandle);
  109. result := TextBlocks.Contains(aTextBlock);
  110. if not result then
  111. SetLastError(ltsErrInvalidTextBlockHandle, Format('0x%.16x is no a valid text block handle', [{%H-}PtrUInt(aHandle)]));
  112. end;
  113. end;
  114. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  115. function CheckFontHandle(const aHandle: TltsFontHandle; out aFont: TtsFont): Boolean;
  116. begin
  117. result := CheckIfInitialized;
  118. if result then begin
  119. aFont := TtsFont(aHandle);
  120. result := Fonts.Contains(aFont);
  121. if not result then
  122. SetLastError(ltsErrInvalidFontHandle, Format('0x%.16x is no a valid font handle', [{%H-}PtrUInt(aHandle)]));
  123. end;
  124. end;
  125. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  126. function CheckFontCreatorHandle(const aHandle: TltsFontCreatorHandle; out aFontCreator: TtsFontCreator): Boolean;
  127. begin
  128. result := CheckIfInitialized;
  129. if result then begin
  130. aFontCreator := TtsFontCreator(aHandle);
  131. result := FontCreators.Contains(aFontCreator);
  132. if not result then
  133. SetLastError(ltsErrInvalidFontCreatorHandle, Format('0x%.16x is no a valid font creator handle', [{%H-}PtrUInt(aHandle)]));
  134. end;
  135. end;
  136. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  137. function CheckImageHandle(const aHandle: TltsImageHandle; out aImage: TtsImage): Boolean;
  138. begin
  139. result := CheckIfInitialized;
  140. if result then begin
  141. aImage := TtsImage(aHandle);
  142. result := Images.Contains(aImage);
  143. if not result then
  144. SetLastError(ltsErrInvalidImageHandle, Format('0x%.16x is no a valid image handle', [{%H-}PtrUInt(aHandle)]));
  145. end;
  146. end;
  147. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  148. function CheckCharHandle(const aHandle: TltsCharHandle; out aChar: TtsChar): Boolean;
  149. begin
  150. result := CheckIfInitialized;
  151. if result then begin
  152. aChar := TtsChar(aHandle);
  153. result := Chars.Contains(aChar);
  154. if not result then
  155. SetLastError(ltsErrInvalidImageHandle, Format('0x%.16x is no a valid char handle', [{%H-}PtrUInt(aHandle)]));
  156. end;
  157. end;
  158. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  159. function CheckPostProcessorHandle(const aHandle: TltsPostProcessorHandle; const aType: TtsPostProcessorClass; out aPostProcessor): Boolean;
  160. begin
  161. result := CheckIfInitialized;
  162. if result then begin
  163. TtsPostProcessor(aPostProcessor) := TtsPostProcessor(aHandle);
  164. result := PostProcessors.Contains(TtsPostProcessor(aPostProcessor));
  165. if not result then begin
  166. SetLastError(ltsErrInvalidPostProcHandle, Format('0x%.16x is no a valid image handle', [{%H-}PtrUInt(aHandle)]));
  167. exit;
  168. end;
  169. result := (TtsPostProcessor(aPostProcessor) is aType);
  170. if not result then begin
  171. SetLastError(ltsErrInvalidType, Format('0x%.16x is no a %s post processor', [{%H-}PtrUInt(aHandle), aType.ClassName]));
  172. exit;
  173. end;
  174. end;
  175. end;
  176. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  177. procedure AddReference(const aType: TltsObjectType; const aRef: TObject);
  178. begin
  179. case aType of
  180. ltsObjTypeContext: Contexts.Add(aRef as TtsContext);
  181. ltsObjTypeRenderer: Renderers.Add(aRef as TtsRenderer);
  182. ltsObjTypeFont: Fonts.Add(aRef as TtsFont);
  183. ltsObjTypeTextBlock: TextBlocks.Add(aRef as TtsTextBlock);
  184. ltsObjTypeFontCreator: FontCreators.Add(aRef as TtsFontCreator);
  185. ltsObjTypeImage: Images.Add(aRef as TtsImage);
  186. ltsObjTypePostProcessor: PostProcessors.Add(aRef as TtsPostProcessor);
  187. ltsObjTypeChar: Chars.Add(aRef as TtsChar);
  188. end;
  189. end;
  190. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  191. procedure DelReference(const aType: TltsObjectType; const aRef: TObject);
  192. begin
  193. case aType of
  194. ltsObjTypeContext: Contexts.Remove(aRef as TtsContext);
  195. ltsObjTypeRenderer: Renderers.Remove(aRef as TtsRenderer);
  196. ltsObjTypeFont: Fonts.Remove(aRef as TtsFont);
  197. ltsObjTypeTextBlock: TextBlocks.Remove(aRef as TtsTextBlock);
  198. ltsObjTypeFontCreator: FontCreators.Remove(aRef as TtsFontCreator);
  199. ltsObjTypeImage: Images.Remove(aRef as TtsImage);
  200. ltsObjTypePostProcessor: PostProcessors.Remove(aRef as TtsPostProcessor);
  201. ltsObjTypeChar: Chars.Remove(aRef as TtsChar);
  202. end;
  203. end;
  204. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  205. procedure DelReference(const aRef: TObject);
  206. begin
  207. if (aRef is TtsRenderer) then
  208. DelReference(ltsObjTypeRenderer, aRef)
  209. else if (aRef is TtsTextBlock) then
  210. DelReference(ltsObjTypeTextBlock, aRef)
  211. else if (aRef is TtsFont) then
  212. DelReference(ltsObjTypeFont, aRef)
  213. else if (aRef is TtsContext) then
  214. DelReference(ltsObjTypeContext, aRef)
  215. else if (aRef is TtsFontCreator) then
  216. DelReference(ltsObjTypeFontCreator, aRef)
  217. else if (aRef is TtsImage) then
  218. DelReference(ltsObjTypeImage, aRef)
  219. else if (aRef is TtsPostProcessor) then
  220. DelReference(ltsObjTypePostProcessor, aRef)
  221. else if (aRef is TtsChar) then
  222. DelReference(ltsObjTypeChar, aRef);
  223. end;
  224. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  225. function ValidateCodePage(const aValue: TtsCodePage): Boolean;
  226. begin
  227. result := (aValue >= Low(TtsCodePage)) and (aValue <= High(TtsCodePage));
  228. if not result then
  229. SetLastError(ltsErrInvalidEnum, Format('%d is not a valid code page value', [aValue]));
  230. end;
  231. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  232. function ValidateFormat(const aValue: TtsFormat): Boolean;
  233. begin
  234. result := (aValue >= Low(TtsFormat)) and (aValue <= High(TtsFormat));
  235. if not result then
  236. SetLastError(ltsErrInvalidEnum, Format('%d is not a valid format value', [aValue]));
  237. end;
  238. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  239. function ValidateCharRangeUsage(const aValue: TtsCharRangeUsage): Boolean;
  240. begin
  241. result := (aValue >= Low(TtsCharRangeUsage)) and (aValue <= High(TtsCharRangeUsage));
  242. if not result then
  243. SetLastError(ltsErrInvalidEnum, Format('%d is not a valid char range usage value', [aValue]));
  244. end;
  245. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  246. procedure Initialize;
  247. begin
  248. Contexts := TtsContextHashSet.Create(true);
  249. Renderers := TtsRendererHashSet.Create(false);
  250. TextBlocks := TtsTextBlockHashSet.Create(false);
  251. FontCreators := TtsFontCreatorHashSet.Create(false);
  252. Fonts := TtsFontHashSet.Create(false);
  253. Images := TtsImageHashSet.Create(false);
  254. PostProcessors := TtsPostProcessorHashSet.Create(false);
  255. Chars := TtsCharHashSet.Create(false);
  256. IsInitilized := true;
  257. end;
  258. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  259. procedure Finalize;
  260. begin
  261. IsInitilized := false;
  262. FreeAndNil(Chars);
  263. FreeAndNil(PostProcessors);
  264. FreeAndNil(Images);
  265. FreeAndNil(TextBlocks);
  266. FreeAndNil(Fonts);
  267. FreeAndNil(FontCreators);
  268. FreeAndNil(Renderers);
  269. FreeAndNil(Contexts);
  270. end;
  271. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  272. //TltsStreamImpl////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  273. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  274. function TltsStreamImpl.Read(var Buffer; Count: Longint): Longint;
  275. begin
  276. if not Assigned(fStream) or not Assigned(fStream^.read)
  277. then result := inherited Read(Buffer, Count)
  278. else result := fStream^.read(fStream^.args, @buffer, Count);
  279. end;
  280. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  281. function TltsStreamImpl.Seek(Offset: Longint; Origin: Word): Longint;
  282. begin
  283. if not Assigned(fStream) or not Assigned(fStream^.seek)
  284. then result := inherited Seek(Offset, Origin)
  285. else result := fStream^.seek(fStream^.args, TltsStreamOrigin(Origin), Offset);
  286. end;
  287. ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  288. constructor TltsStreamImpl.Create(const aStream: PltsStream);
  289. begin
  290. inherited Create;
  291. fStream := aStream;
  292. end;
  293. end.