選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。
 
 
 
 
 

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