Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

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