You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

608 rivejä
19 KiB

  1. unit utsFreeType;
  2. {$mode objfpc}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, syncobjs, dynlibs, utsTextSuite;
  6. type
  7. // Simple Types
  8. FT_Error = Integer;
  9. FT_Library = Pointer;
  10. FT_Short = ShortInt;
  11. FT_UShort = Word;
  12. FT_Int = Integer;
  13. FT_Int32 = Integer;
  14. FT_UInt = Cardinal;
  15. FT_Long = LongInt;
  16. FT_ULong = Cardinal;
  17. FT_Fixed = LongInt;
  18. FT_Pos = LongInt;
  19. FT_F26Dot6 = LongInt;
  20. FT_String = AnsiChar;
  21. // Enums
  22. FT_Encoding = Integer;
  23. FT_Glyph_Format = Integer;
  24. // Pointer
  25. FT_Face = ^FT_FaceRec;
  26. FT_GlyphSlot = ^FT_GlyphSlotRec;
  27. FT_Size = ^FT_SizeRec;
  28. FT_CharMap = ^FT_CharMapRec;
  29. PFT_Library = ^FT_Library;
  30. PFT_Face = ^FT_Face;
  31. PFT_String = ^FT_String;
  32. PFT_SfntName = ^FT_SfntName;
  33. PFT_Bitmap = ^FT_Bitmap;
  34. // unneeded
  35. FT_Driver = Pointer;
  36. FT_Memory = Pointer;
  37. FT_Stream = Pointer;
  38. FT_ListNode = Pointer;
  39. FT_Face_Internal = Pointer;
  40. FT_SubGlyph = Pointer;
  41. FT_Slot_Internal = Pointer;
  42. FT_Size_Internal = Pointer;
  43. FT_Generic_Finalizer = procedure(aObject: Pointer);
  44. FT_Generic = record
  45. data: Pointer;
  46. finalizer: FT_Generic_Finalizer;
  47. end;
  48. FT_BBox = record
  49. xMin, yMin, xMax, yMax: FT_Pos;
  50. end;
  51. FT_Vector = record
  52. x, y: FT_Pos;
  53. end;
  54. FT_ListRec = record
  55. head: FT_ListNode;
  56. tail: FT_ListNode;
  57. end;
  58. FT_CharMapRec = record
  59. face: FT_Face;
  60. encoding: FT_Encoding;
  61. platform_id: FT_UShort;
  62. encoding_id: FT_UShort;
  63. end;
  64. FT_Size_Metrics = record
  65. x_ppem: FT_UShort;
  66. y_ppem: FT_UShort;
  67. x_scale: FT_Fixed;
  68. y_scale: FT_Fixed;
  69. ascender: FT_Pos;
  70. descender: FT_Pos;
  71. height: FT_Pos;
  72. max_advance: FT_Pos;
  73. end;
  74. FT_SizeRec = record
  75. face: FT_Face;
  76. generic_: FT_Generic;
  77. metrics: FT_Size_Metrics;
  78. internal: FT_Size_Internal;
  79. end;
  80. FT_Glyph_Metrics = record
  81. width: FT_Pos;
  82. height: FT_Pos;
  83. horiBearingX: FT_Pos;
  84. horiBearingY: FT_Pos;
  85. horiAdvance: FT_Pos;
  86. vertBearingX: FT_Pos;
  87. vertBearingY: FT_Pos;
  88. vertAdvance: FT_Pos;
  89. end;
  90. FT_Bitmap_Size = record
  91. height: FT_Short;
  92. width: FT_Short;
  93. size: FT_Pos;
  94. x_ppem: FT_Pos;
  95. y_ppem: FT_Pos;
  96. end;
  97. FT_Bitmap = record
  98. rows: Integer;
  99. width: Integer;
  100. pitch: Integer;
  101. buffer: PByte;
  102. num_grays: ShortInt;
  103. pixel_mode: Byte;
  104. palette_mode: Byte;
  105. palette: Pointer;
  106. end;
  107. FT_Outline = record
  108. n_contours: ShortInt;
  109. n_points: ShortInt;
  110. points: ^FT_Vector;
  111. tags: PByte;
  112. contours: PShortInt;
  113. flags: Integer;
  114. end;
  115. FT_GlyphSlotRec = record
  116. library_: FT_Library;
  117. face: FT_Face;
  118. next: FT_GlyphSlot;
  119. reserved: FT_UInt;
  120. generic_: FT_Generic;
  121. metrics: FT_Glyph_Metrics;
  122. linearHoriAdvance: FT_Fixed;
  123. linearVertAdvance: FT_Fixed;
  124. advance: FT_Vector;
  125. format: FT_Glyph_Format;
  126. bitmap: FT_Bitmap;
  127. bitmap_left: FT_Int;
  128. bitmap_top: FT_Int;
  129. outline: FT_Outline;
  130. num_subglyphs: FT_UInt;
  131. subglyphs: FT_SubGlyph;
  132. control_data: Pointer;
  133. control_len: LongInt;
  134. lsb_delta: FT_Pos;
  135. rsb_delta: FT_Pos;
  136. other: Pointer;
  137. internal: FT_Slot_Internal;
  138. end;
  139. FT_FaceRec = record
  140. num_faces: FT_Long;
  141. face_index: FT_Long;
  142. face_flags: FT_Long;
  143. style_flags: FT_Long;
  144. num_glyphs: FT_Long;
  145. family_name: PFT_String;
  146. style_name: PFT_String;
  147. num_fixed_sizes: FT_Int;
  148. available_sizes: ^FT_Bitmap_Size;
  149. num_charmaps: FT_Int;
  150. charmaps: ^FT_CharMap;
  151. generic_: FT_Generic;
  152. bbox: FT_BBox;
  153. units_per_EM: FT_UShort;
  154. ascender: FT_Short;
  155. descender: FT_Short;
  156. height: FT_Short;
  157. max_advance_width: FT_Short;
  158. max_advance_height: FT_Short;
  159. underline_position: FT_Short;
  160. underline_thickness: FT_Short;
  161. glyph: FT_GlyphSlot;
  162. size: FT_Size;
  163. charmap: FT_CharMap;
  164. { private }
  165. driver: FT_Driver;
  166. memory: FT_Memory;
  167. stream: FT_Stream;
  168. sizes_list: FT_ListRec;
  169. autohint: FT_Generic;
  170. extensions: Pointer;
  171. internal: FT_Face_Internal;
  172. { private end }
  173. end;
  174. FT_SfntName = record
  175. platform_id: FT_UShort;
  176. encoding_id: FT_UShort;
  177. language_id: FT_UShort;
  178. name_id: FT_UShort;
  179. string_: PByte;
  180. string_len: FT_UInt;
  181. end;
  182. TFT_Init_FreeType = function(aLibrary: PFT_Library): FT_Error;
  183. TFT_Done_FreeType = function(aLibrary: FT_Library): FT_Error;
  184. TFT_New_Face = function(aLibrary: FT_Library; const aFilename: PAnsiChar; aFaceIndex: FT_Long; aFace: PFT_Face): FT_Error;
  185. TFT_Done_Face = function(aFace: FT_Face): FT_Error;
  186. TFT_Get_Sfnt_Name_Count = function(aFace: FT_Face): FT_UInt;
  187. TFT_Get_Sfnt_Name = function(aFace: FT_Face; aIndex: FT_UInt; aName: PFT_SfntName): FT_Error;
  188. TFT_Set_Char_Size = function(aFace: FT_Face; aCharWidth: FT_F26Dot6; aCharHeight: FT_F26Dot6; aHorzDPI: FT_UInt; aVertDPI: FT_UInt): FT_Error;
  189. TFT_Load_Char = function(aFace: FT_Face; aCharCode: FT_ULong; aLoadFlags: FT_Int32): FT_Error;
  190. var
  191. FT_Init_FreeType: TFT_Init_FreeType;
  192. FT_Done_FreeType: TFT_Done_FreeType;
  193. FT_New_Face: TFT_New_Face;
  194. FT_Done_Face: TFT_Done_Face;
  195. FT_Get_Sfnt_Name_Count: TFT_Get_Sfnt_Name_Count;
  196. FT_Get_Sfnt_Name: TFT_Get_Sfnt_Name;
  197. FT_Set_Char_Size: TFT_Set_Char_Size;
  198. FT_Load_Char: TFT_Load_Char;
  199. const
  200. TT_NAME_ID_COPYRIGHT = 0;
  201. TT_NAME_ID_FONT_FAMILY = 1;
  202. TT_NAME_ID_FONT_SUBFAMILY = 2;
  203. TT_NAME_ID_UNIQUE_ID = 3;
  204. TT_NAME_ID_FULL_NAME = 4;
  205. TT_NAME_ID_VERSION_STRING = 5;
  206. TT_NAME_ID_PS_NAME = 6;
  207. TT_NAME_ID_TRADEMARK = 7;
  208. TT_PLATFORM_APPLE_UNICODE = 0;
  209. TT_PLATFORM_MACINTOSH = 1;
  210. TT_PLATFORM_ISO = 2; // deprecated
  211. TT_PLATFORM_MICROSOFT = 3;
  212. TT_PLATFORM_CUSTOM = 4;
  213. TT_PLATFORM_ADOBE = 7; // artificial
  214. TT_ISO_ID_7BIT_ASCII = 0;
  215. TT_ISO_ID_10646 = 1;
  216. TT_ISO_ID_8859_1 = 2;
  217. TT_APPLE_ID_DEFAULT = 0; // Unicode 1.0
  218. TT_APPLE_ID_UNICODE_1_1 = 1; // specify Hangul at U+34xx
  219. TT_APPLE_ID_ISO_10646 = 2; // deprecated
  220. TT_APPLE_ID_UNICODE_2_0 = 3; // or later
  221. TT_APPLE_ID_UNICODE_32 = 4; // 2.0 or later, full repertoire
  222. TT_MAC_ID_ROMAN = 0;
  223. TT_MAC_ID_JAPANESE = 1;
  224. TT_MAC_ID_TRADITIONAL_CHINESE = 2;
  225. TT_MAC_ID_KOREAN = 3;
  226. TT_MAC_ID_ARABIC = 4;
  227. TT_MAC_ID_HEBREW = 5;
  228. TT_MAC_ID_GREEK = 6;
  229. TT_MAC_ID_RUSSIAN = 7;
  230. TT_MAC_ID_RSYMBOL = 8;
  231. TT_MAC_ID_DEVANAGARI = 9;
  232. TT_MAC_ID_GURMUKHI = 10;
  233. TT_MAC_ID_GUJARATI = 11;
  234. TT_MAC_ID_ORIYA = 12;
  235. TT_MAC_ID_BENGALI = 13;
  236. TT_MAC_ID_TAMIL = 14;
  237. TT_MAC_ID_TELUGU = 15;
  238. TT_MAC_ID_KANNADA = 16;
  239. TT_MAC_ID_MALAYALAM = 17;
  240. TT_MAC_ID_SINHALESE = 18;
  241. TT_MAC_ID_BURMESE = 19;
  242. TT_MAC_ID_KHMER = 20;
  243. TT_MAC_ID_THAI = 21;
  244. TT_MAC_ID_LAOTIAN = 22;
  245. TT_MAC_ID_GEORGIAN = 23;
  246. TT_MAC_ID_ARMENIAN = 24;
  247. TT_MAC_ID_MALDIVIAN = 25;
  248. TT_MAC_ID_SIMPLIFIED_CHINESE = 25;
  249. TT_MAC_ID_TIBETAN = 26;
  250. TT_MAC_ID_MONGOLIAN = 27;
  251. TT_MAC_ID_GEEZ = 28;
  252. TT_MAC_ID_SLAVIC = 29;
  253. TT_MAC_ID_VIETNAMESE = 30;
  254. TT_MAC_ID_SINDHI = 31;
  255. TT_MAC_ID_UNINTERP = 32;
  256. FT_LOAD_DEFAULT = 0;
  257. FT_LOAD_NO_SCALE = ( 1 shl 0 );
  258. FT_LOAD_NO_HINTING = ( 1 shl 1 );
  259. FT_LOAD_RENDER = ( 1 shl 2 );
  260. FT_LOAD_NO_BITMAP = ( 1 shl 3 );
  261. FT_LOAD_VERTICAL_LAYOUT = ( 1 shl 4 );
  262. FT_LOAD_FORCE_AUTOHINT = ( 1 shl 5 );
  263. FT_LOAD_CROP_BITMAP = ( 1 shl 6 );
  264. FT_LOAD_PEDANTIC = ( 1 shl 7 );
  265. FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH = ( 1 shl 9 );
  266. FT_LOAD_NO_RECURSE = ( 1 shl 10 );
  267. FT_LOAD_IGNORE_TRANSFORM = ( 1 shl 11 );
  268. FT_LOAD_MONOCHROME = ( 1 shl 12 );
  269. FT_LOAD_LINEAR_DESIGN = ( 1 shl 13 );
  270. FT_LOAD_NO_AUTOHINT = ( 1 shl 15 );
  271. FT_LOAD_COLOR = ( 1 shl 20 );
  272. FT_GLYPH_FORMAT_NONE = 0;
  273. FT_GLYPH_FORMAT_COMPOSITE = (Ord('c') shl 24) or
  274. (Ord('o') shl 16) or
  275. (Ord('m') shl 8) or
  276. (Ord('p'));
  277. FT_GLYPH_FORMAT_BITMAP = (Ord('b') shl 24) or
  278. (Ord('i') shl 16) or
  279. (Ord('t') shl 8) or
  280. (Ord('s'));
  281. FT_GLYPH_FORMAT_OUTLINE = (Ord('o') shl 24) or
  282. (Ord('u') shl 16) or
  283. (Ord('t') shl 8) or
  284. (Ord('l'));
  285. FT_GLYPH_FORMAT_PLOTTER = (Ord('p') shl 24) or
  286. (Ord('l') shl 16) or
  287. (Ord('o') shl 8) or
  288. (Ord('t'));
  289. //FT_PIXEL_MODE_NONE = 0;
  290. FT_PIXEL_MODE_MONO = 0;
  291. FT_PIXEL_MODE_GRAY = 1;
  292. FT_PIXEL_MODE_GRAY2 = 2;
  293. FT_PIXEL_MODE_GRAY4 = 3;
  294. FT_PIXEL_MODE_LCD = 4;
  295. FT_PIXEL_MODE_LCD_V = 5;
  296. FT_PIXEL_MODE_BGRA = 6;
  297. FT_ERR_Ok = $00;
  298. FT_ERR_None = $00;
  299. FT_ERR_Cannot_Open_Resource = $01;
  300. FT_ERR_Unknown_File_Format = $02;
  301. FT_ERR_Invalid_File_Format = $03;
  302. FT_ERR_Invalid_Version = $04;
  303. FT_ERR_Lower_Module_Version = $05;
  304. FT_ERR_Invalid_Argument = $06;
  305. FT_ERR_Unimplemented_Feature = $07;
  306. FT_ERR_Invalid_Table = $08;
  307. FT_ERR_Invalid_Offset = $09;
  308. FT_ERR_Array_Too_Large = $0A;
  309. { glyph/character errors }
  310. FT_ERR_Invalid_Glyph_Index = $10;
  311. FT_ERR_Invalid_Character_Code = $11;
  312. FT_ERR_Invalid_Glyph_Format = $12;
  313. FT_ERR_Cannot_Render_Glyph = $13;
  314. FT_ERR_Invalid_Outline = $14;
  315. FT_ERR_Invalid_Composite = $15;
  316. FT_ERR_Too_Many_Hints = $16;
  317. FT_ERR_Invalid_Pixel_Size = $17;
  318. { handle errors }
  319. FT_ERR_Invalid_Handle = $20;
  320. FT_ERR_Invalid_Library_Handle = $21;
  321. FT_ERR_Invalid_Driver_Handle = $22;
  322. FT_ERR_Invalid_Face_Handle = $23;
  323. FT_ERR_Invalid_Size_Handle = $24;
  324. FT_ERR_Invalid_Slot_Handle = $25;
  325. FT_ERR_Invalid_CharMap_Handle = $26;
  326. FT_ERR_Invalid_Cache_Handle = $27;
  327. FT_ERR_Invalid_Stream_Handle = $28;
  328. { driver errors }
  329. FT_ERR_Too_Many_Drivers = $30;
  330. FT_ERR_Too_Many_Extensions = $31;
  331. { memory errors }
  332. FT_ERR_Out_Of_Memory = $40;
  333. FT_ERR_Unlisted_Object = $41;
  334. { stream errors }
  335. FT_ERR_Cannot_Open_Stream = $51;
  336. FT_ERR_Invalid_Stream_Seek = $52;
  337. FT_ERR_Invalid_Stream_Skip = $53;
  338. FT_ERR_Invalid_Stream_Read = $54;
  339. FT_ERR_Invalid_Stream_Operation = $55;
  340. FT_ERR_Invalid_Frame_Operation = $56;
  341. FT_ERR_Nested_Frame_Access = $57;
  342. FT_ERR_Invalid_Frame_Read = $58;
  343. { raster errors }
  344. FT_ERR_Raster_Uninitialized = $60;
  345. FT_ERR_Raster_Corrupted = $61;
  346. FT_ERR_Raster_Overflow = $62;
  347. FT_ERR_Raster_Negative_Height = $63;
  348. { cache errors }
  349. FT_ERR_Too_Many_Caches = $70;
  350. { TrueType and SFNT errors }
  351. FT_ERR_Invalid_Opcode = $80;
  352. FT_ERR_Too_Few_Arguments = $81;
  353. FT_ERR_Stack_Overflow = $82;
  354. FT_ERR_Code_Overflow = $83;
  355. FT_ERR_Bad_Argument = $84;
  356. FT_ERR_Divide_By_Zero = $85;
  357. FT_ERR_Invalid_Reference = $86;
  358. FT_ERR_Debug_OpCode = $87;
  359. FT_ERR_ENDF_In_Exec_Stream = $88;
  360. FT_ERR_Nested_DEFS = $89;
  361. FT_ERR_Invalid_CodeRange = $8A;
  362. FT_ERR_Execution_Too_Long = $8B;
  363. FT_ERR_Too_Many_Function_Defs = $8C;
  364. FT_ERR_Too_Many_Instruction_Defs = $8D;
  365. FT_ERR_Table_Missing = $8E;
  366. FT_ERR_Horiz_Header_Missing = $8F;
  367. FT_ERR_Locations_Missing = $90;
  368. FT_ERR_Name_Table_Missing = $91;
  369. FT_ERR_CMap_Table_Missing = $92;
  370. FT_ERR_Hmtx_Table_Missing = $93;
  371. FT_ERR_Post_Table_Missing = $94;
  372. FT_ERR_Invalid_Horiz_Metrics = $95;
  373. FT_ERR_Invalid_CharMap_Format = $96;
  374. FT_ERR_Invalid_PPem = $97;
  375. FT_ERR_Invalid_Vert_Metrics = $98;
  376. FT_ERR_Could_Not_Find_Context = $99;
  377. FT_ERR_Invalid_Post_Table_Format = $9A;
  378. FT_ERR_Invalid_Post_Table = $9B;
  379. { CFF CID and Type 1 errors }
  380. FT_ERR_Syntax_Error = $A0;
  381. FT_ERR_Stack_Underflow = $A1;
  382. FT_ERR_Ignore = $A2;
  383. { BDF errors }
  384. FT_ERR_Missing_Startfont_Field = $B0;
  385. FT_ERR_Missing_Font_Field = $B1;
  386. FT_ERR_Missing_Size_Field = $B2;
  387. FT_ERR_Missing_Chars_Field = $B3;
  388. FT_ERR_Missing_Startchar_Field = $B4;
  389. FT_ERR_Missing_Encoding_Field = $B5;
  390. FT_ERR_Missing_Bbx_Field = $B6;
  391. FT_ERR_Bbx_Too_Big = $B7;
  392. FT_ERR_Corrupted_Font_Header = $B8;
  393. FT_ERR_Corrupted_Font_Glyphs = $B9;
  394. FT_STYLE_FLAG_ITALIC = (1 shl 0);
  395. FT_STYLE_FLAG_BOLD = (1 shl 1);
  396. FT_RENDER_MODE_NORMAL = 0;
  397. FT_RENDER_MODE_LIGHT = 1;
  398. FT_RENDER_MODE_MONO = 2;
  399. FT_RENDER_MODE_LCD = 3;
  400. FT_RENDER_MODE_LCD_V = 4;
  401. FT_LOAD_TARGET_NORMAL = FT_RENDER_MODE_NORMAL shl 16;
  402. FT_LOAD_TARGET_LIGHT = FT_RENDER_MODE_LIGHT shl 16;
  403. FT_LOAD_TARGET_MONO = FT_RENDER_MODE_MONO shl 16;
  404. FT_LOAD_TARGET_LCD = FT_RENDER_MODE_LCD shl 16;
  405. FT_LOAD_TARGET_LCD_V = FT_RENDER_MODE_LCD_V shl 16;
  406. function InitFreeType: FT_Library;
  407. procedure QuitFreeType;
  408. implementation
  409. {$IFDEF WINDOWS}
  410. {$IFDEF WIN32}
  411. {$DEFINE TS_FT_WIN32}
  412. {$ELSE}
  413. {$DEFINE TS_FT_WIN64}
  414. {$ENDIF}
  415. {$ELSE}
  416. {$DEFINE TS_FT_LINUX}
  417. {$ENDIF}
  418. const
  419. {$IF DEFINED(TS_FT_WIN32)}
  420. LIB_FREE_TYPE = 'freetype6-x86.dll';
  421. {$ELSEIF DEFINED(TS_FT_WIN64)}
  422. LIB_FREE_TYPE = 'freetype6-x64.dll';
  423. {$ELSEIF DEFINED(TS_FT_LINUX)}
  424. LIB_FREE_TYPE = ???
  425. {$ELSE}
  426. {$ERROR 'unknown/unsupported OS'}
  427. {$IFEND}
  428. var
  429. FreeTypeInitialized: Boolean;
  430. FreeTypeRefCount: Integer;
  431. FreeTypeCritSec: TCriticalSection;
  432. FreeTypeLibHandle: TLibHandle = 0;
  433. ftLibrary: FT_Library;
  434. function InitFreeType: FT_Library;
  435. function GetProcAddr(const aName: String): Pointer;
  436. begin
  437. result := GetProcAddress(FreeTypeLibHandle, aName);
  438. if not Assigned(result) then
  439. raise EtsException.Create('unable to load procedure from library: ' + aName);
  440. end;
  441. var
  442. err: FT_Error;
  443. begin
  444. result := nil;
  445. FreeTypeCritSec.Enter;
  446. try try
  447. inc(FreeTypeRefCount, 1);
  448. if FreeTypeInitialized then
  449. exit;
  450. if (FreeTypeLibHandle = 0) then begin
  451. FreeTypeLibHandle := LoadLibrary(LIB_FREE_TYPE);
  452. if (FreeTypeLibHandle = 0) then
  453. raise EtsException.Create('unable to load free type lib: ' + LIB_FREE_TYPE + ' error=' + IntToStr(GetLastOSError));
  454. end;
  455. FT_Init_FreeType := TFT_Init_FreeType(GetProcAddr('FT_Init_FreeType'));
  456. FT_Done_FreeType := TFT_Done_FreeType(GetProcAddr('FT_Done_FreeType'));
  457. FT_New_Face := TFT_New_Face( GetProcAddr('FT_New_Face'));
  458. FT_Done_Face := TFT_Done_Face( GetProcAddr('FT_Done_Face'));
  459. FT_Get_Sfnt_Name_Count := TFT_Get_Sfnt_Name_Count(GetProcAddr('FT_Get_Sfnt_Name_Count'));
  460. FT_Get_Sfnt_Name := TFT_Get_Sfnt_Name( GetProcAddr('FT_Get_Sfnt_Name'));
  461. FT_Set_Char_Size := TFT_Set_Char_Size(GetProcAddr('FT_Set_Char_Size'));
  462. FT_Load_Char := TFT_Load_Char( GetProcAddr('FT_Load_Char'));
  463. err := FT_Init_FreeType(@ftLibrary);
  464. if (err <> 0) then
  465. raise EtsException.Create('unable to create free type library handle: ' + IntToStr(err));
  466. FreeTypeInitialized := true;
  467. result := ftLibrary;
  468. except
  469. FreeTypeInitialized := false;
  470. end;
  471. finally
  472. FreeTypeCritSec.Leave;
  473. end;
  474. end;
  475. procedure QuitFreeType;
  476. begin
  477. FreeTypeCritSec.Enter;
  478. try
  479. dec(FreeTypeRefCount, 1);
  480. if (FreeTypeRefCount > 0) then
  481. exit;
  482. FT_Done_FreeType(ftLibrary);
  483. FT_Init_FreeType := nil;
  484. FT_Done_FreeType := nil;
  485. if (FreeTypeLibHandle <> 0) then begin
  486. FreeLibrary(FreeTypeLibHandle);
  487. FreeTypeLibHandle := 0;
  488. end;
  489. FreeTypeInitialized := false;
  490. finally
  491. FreeTypeCritSec.Leave;
  492. end;
  493. end;
  494. initialization
  495. FreeTypeRefCount := 0;
  496. FreeTypeInitialized := false;
  497. FreeTypeCritSec := TCriticalSection.Create;
  498. finalization
  499. if FreeTypeInitialized then
  500. QuitFreeType;
  501. FreeAndNil(FreeTypeCritSec);
  502. end.