truetype.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671
  1. /*******************************************************************************
  2. * TrueType font-related functions for Wine PostScript driver. Currently just
  3. * uses FreeType to read font metrics.
  4. *
  5. * Copyright 2001 Ian Pilcher
  6. *
  7. * This library is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * This library is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this library; if not, write to the Free Software
  19. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  20. *
  21. * NOTE: Many of the functions in this file can return either fatal errors
  22. * (memory allocation failure or unexpected FreeType error) or non-fatal
  23. * errors (unusable font file). Fatal errors are indicated by returning
  24. * FALSE; see individual function descriptions for how they indicate non-
  25. * fatal errors.
  26. *
  27. */
  28. #include "config.h"
  29. #include "wine/port.h"
  30. #ifdef HAVE_FREETYPE
  31. /*
  32. * These stupid #ifdefs should work for FreeType 2.0.1 and 2.0.2. Beyond that
  33. * is anybody's guess.
  34. */
  35. #ifdef HAVE_FT2BUILD_H
  36. #include <ft2build.h>
  37. #endif
  38. #ifdef HAVE_FREETYPE_FREETYPE_H
  39. #include <freetype/freetype.h>
  40. #endif
  41. #ifdef HAVE_FREETYPE_FTGLYPH_H
  42. #include <freetype/ftglyph.h>
  43. #endif
  44. #ifdef HAVE_FREETYPE_TTTABLES_H
  45. #include <freetype/tttables.h>
  46. #endif
  47. #ifdef HAVE_FREETYPE_FTSNAMES_H
  48. #include <freetype/ftsnames.h>
  49. #else
  50. # ifdef HAVE_FREETYPE_FTNAMES_H
  51. # include <freetype/ftnames.h>
  52. # endif
  53. #endif
  54. #ifdef HAVE_FREETYPE_TTNAMEID_H
  55. #include <freetype/ttnameid.h>
  56. #endif
  57. #include <sys/types.h>
  58. #include <dirent.h>
  59. #include <string.h>
  60. #include <stdarg.h>
  61. #include <stdio.h>
  62. #include <errno.h>
  63. #include "windef.h"
  64. #include "winbase.h"
  65. #include "winerror.h"
  66. #include "winreg.h"
  67. #include "psdrv.h"
  68. #include "wine/debug.h"
  69. WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
  70. #define REQUIRED_FACE_FLAGS ( FT_FACE_FLAG_SCALABLE | \
  71. FT_FACE_FLAG_HORIZONTAL | \
  72. FT_FACE_FLAG_SFNT | \
  73. FT_FACE_FLAG_GLYPH_NAMES )
  74. #define GLYPH_LOAD_FLAGS ( FT_LOAD_NO_SCALE | \
  75. FT_LOAD_IGNORE_TRANSFORM | \
  76. FT_LOAD_LINEAR_DESIGN )
  77. #ifndef SONAME_LIBFREETYPE
  78. #define SONAME_LIBFREETYPE "libfreetype.so"
  79. #endif
  80. static void *ft_handle = NULL;
  81. #define MAKE_FUNCPTR(f) static typeof(f) * p##f = NULL;
  82. MAKE_FUNCPTR(FT_Done_Face)
  83. MAKE_FUNCPTR(FT_Done_FreeType)
  84. MAKE_FUNCPTR(FT_Get_Char_Index)
  85. MAKE_FUNCPTR(FT_Get_Glyph_Name)
  86. MAKE_FUNCPTR(FT_Get_Sfnt_Name)
  87. MAKE_FUNCPTR(FT_Get_Sfnt_Name_Count)
  88. MAKE_FUNCPTR(FT_Get_Sfnt_Table)
  89. MAKE_FUNCPTR(FT_Init_FreeType)
  90. MAKE_FUNCPTR(FT_Load_Glyph)
  91. MAKE_FUNCPTR(FT_New_Face)
  92. MAKE_FUNCPTR(FT_Set_Charmap)
  93. #undef MAKE_FUNCPTR
  94. /*******************************************************************************
  95. * FindCharMap
  96. *
  97. * Finds Windows character map and creates "EncodingScheme" string. Returns
  98. * FALSE to indicate memory allocation or FreeType error; sets *p_charmap to
  99. * NULL if no Windows encoding is present.
  100. *
  101. * Returns Unicode character map if present; otherwise uses the first Windows
  102. * character map found.
  103. *
  104. */
  105. static const LPCSTR encoding_names[7] =
  106. {
  107. "WindowsSymbol", /* TT_MS_ID_SYMBOL_CS */
  108. "WindowsUnicode", /* TT_MS_ID_UNICODE_CS */
  109. "WindowsShiftJIS", /* TT_MS_ID_SJIS */
  110. "WindowsPRC", /* TT_MS_ID_GB2312 */
  111. "WindowsBig5", /* TT_MS_ID_BIG_5 */
  112. "WindowsWansung", /* TT_MS_ID_WANSUNG */
  113. "WindowsJohab" /* TT_MS_ID_JOHAB */
  114. /* "WindowsUnknown65535" is the longest possible (encoding_id is a UShort) */
  115. };
  116. static BOOL FindCharMap(FT_Face face, FT_CharMap *p_charmap, LPSTR *p_sz)
  117. {
  118. FT_Int i;
  119. FT_Error error;
  120. FT_CharMap charmap = NULL;
  121. for (i = 0; i < face->num_charmaps; ++i)
  122. {
  123. if (face->charmaps[i]->platform_id != TT_PLATFORM_MICROSOFT)
  124. continue;
  125. if (face->charmaps[i]->encoding_id == TT_MS_ID_UNICODE_CS)
  126. {
  127. charmap = face->charmaps[i];
  128. break;
  129. }
  130. if (charmap == NULL)
  131. charmap = face->charmaps[i];
  132. }
  133. *p_charmap = charmap;
  134. if (charmap == NULL)
  135. {
  136. WARN("No Windows character map found\n");
  137. return TRUE;
  138. }
  139. error = pFT_Set_Charmap(face, charmap);
  140. if (error != FT_Err_Ok)
  141. {
  142. ERR("%s returned %i\n", "FT_Set_Charmap", error);
  143. return FALSE;
  144. }
  145. *p_sz = HeapAlloc(PSDRV_Heap, 0, sizeof("WindowsUnknown65535"));
  146. if (*p_sz == NULL)
  147. return FALSE;
  148. if (charmap->encoding_id < 7)
  149. strcpy(*p_sz, encoding_names[charmap->encoding_id]);
  150. else
  151. sprintf(*p_sz, "%s%u", "WindowsUnknown", charmap->encoding_id);
  152. return TRUE;
  153. }
  154. /*******************************************************************************
  155. * MSTTStrToSz
  156. *
  157. * Converts a string in the TrueType NAME table to a null-terminated ASCII
  158. * character string. Space for the string is allocated from the driver heap.
  159. * Only handles platform_id = 3 (TT_PLATFORM_MICROSOFT) strings (16-bit, big
  160. * endian). It also only handles ASCII character codes (< 128).
  161. *
  162. * Sets *p_sz to NULL if string cannot be converted; only returns FALSE for
  163. * memory allocation failure.
  164. *
  165. */
  166. static BOOL MSTTStrToSz(const FT_SfntName *name, LPSTR *p_sz)
  167. {
  168. FT_UShort i;
  169. INT len;
  170. BYTE *wsz;
  171. LPSTR sz;
  172. len = name->string_len / 2; /* # of 16-bit chars */
  173. *p_sz = sz = HeapAlloc(PSDRV_Heap, 0, len + 1);
  174. if (sz == NULL)
  175. return FALSE;
  176. wsz = (BYTE *)name->string;
  177. for (i = 0; i < len; ++i, ++sz)
  178. {
  179. USHORT wc = (wsz[0] << 8) + wsz[1];
  180. wsz += 2;
  181. if (wc > 127)
  182. {
  183. WARN("Non-ASCII character 0x%.4x\n", wc);
  184. HeapFree(PSDRV_Heap, 0, *p_sz);
  185. *p_sz = NULL;
  186. return TRUE;
  187. }
  188. *sz = (CHAR)wc;
  189. }
  190. *sz = '\0';
  191. return TRUE;
  192. }
  193. /*******************************************************************************
  194. * FindMSTTString
  195. *
  196. * Finds the requested Microsoft platform string in the TrueType NAME table and
  197. * converts it to a null-terminated ASCII string. Currently looks for U.S.
  198. * English names only.
  199. *
  200. * Sets string to NULL if not present or cannot be converted; returns FALSE
  201. * only for memory allocation failure.
  202. *
  203. */
  204. static BOOL FindMSTTString(FT_Face face, FT_CharMap charmap, FT_UShort name_id,
  205. LPSTR *p_sz)
  206. {
  207. FT_UInt num_strings, string_index;
  208. FT_SfntName name;
  209. FT_Error error;
  210. num_strings = pFT_Get_Sfnt_Name_Count(face);
  211. for (string_index = 0; string_index < num_strings; ++string_index)
  212. {
  213. error = pFT_Get_Sfnt_Name(face, string_index, &name);
  214. if (error != FT_Err_Ok)
  215. {
  216. ERR("%s returned %i\n", "FT_Get_Sfnt_Name", error);
  217. return FALSE;
  218. }
  219. /* FIXME - Handle other languages? */
  220. if (name.platform_id != TT_PLATFORM_MICROSOFT ||
  221. name.language_id != TT_MS_LANGID_ENGLISH_UNITED_STATES)
  222. continue;
  223. if (name.platform_id != charmap->platform_id ||
  224. name.encoding_id != charmap->encoding_id)
  225. continue;
  226. if (name.name_id != name_id)
  227. continue;
  228. return MSTTStrToSz(&name, p_sz);
  229. }
  230. *p_sz = NULL; /* didn't find it */
  231. return TRUE;
  232. }
  233. /*******************************************************************************
  234. * PSUnits
  235. *
  236. * Convert TrueType font units (relative to font em square) to PostScript
  237. * units.
  238. *
  239. */
  240. inline static float PSUnits(LONG x, USHORT em_size)
  241. {
  242. return 1000.0 * (float)x / (float)em_size;
  243. }
  244. /*******************************************************************************
  245. * StartAFM
  246. *
  247. * Allocates space for the AFM on the driver heap and reads basic font metrics
  248. * from the HEAD, POST, HHEA, and OS/2 tables. Returns FALSE for memory
  249. * allocation error; sets *p_afm to NULL if required information is missing.
  250. *
  251. */
  252. static BOOL StartAFM(FT_Face face, AFM **p_afm)
  253. {
  254. TT_Header *head;
  255. TT_Postscript *post;
  256. TT_OS2 *os2;
  257. TT_HoriHeader *hhea;
  258. USHORT em_size;
  259. AFM *afm;
  260. head = pFT_Get_Sfnt_Table(face, ft_sfnt_head);
  261. post = pFT_Get_Sfnt_Table(face, ft_sfnt_post);
  262. os2 = pFT_Get_Sfnt_Table(face, ft_sfnt_os2);
  263. hhea = pFT_Get_Sfnt_Table(face, ft_sfnt_hhea);
  264. if (head == NULL || post == NULL || os2 == NULL || hhea == NULL ||
  265. os2->version == 0xffff) /* old Macintosh font */
  266. {
  267. WARN("Required table(s) missing\n");
  268. *p_afm = NULL;
  269. return TRUE;
  270. }
  271. *p_afm = afm = HeapAlloc(PSDRV_Heap, 0, sizeof(*afm));
  272. if (afm == NULL)
  273. return FALSE;
  274. afm->WinMetrics.usUnitsPerEm = em_size = head->Units_Per_EM;
  275. afm->WinMetrics.sAscender = hhea->Ascender;
  276. afm->WinMetrics.sDescender = hhea->Descender;
  277. afm->WinMetrics.sLineGap = hhea->Line_Gap;
  278. afm->WinMetrics.sTypoAscender = os2->sTypoAscender;
  279. afm->WinMetrics.sTypoDescender = os2->sTypoDescender;
  280. afm->WinMetrics.sTypoLineGap = os2->sTypoLineGap;
  281. afm->WinMetrics.usWinAscent = os2->usWinAscent;
  282. afm->WinMetrics.usWinDescent = os2->usWinDescent;
  283. afm->WinMetrics.sAvgCharWidth = os2->xAvgCharWidth;
  284. afm->Weight = os2->usWeightClass;
  285. afm->ItalicAngle = ((float)(post->italicAngle)) / 65536.0;
  286. afm->IsFixedPitch = (post-> isFixedPitch == 0) ? FALSE : TRUE;
  287. afm->UnderlinePosition = PSUnits(post->underlinePosition, em_size);
  288. afm->UnderlineThickness = PSUnits(post->underlineThickness, em_size);
  289. afm->FontBBox.llx = PSUnits(head->xMin, em_size);
  290. afm->FontBBox.lly = PSUnits(head->yMin, em_size);
  291. afm->FontBBox.urx = PSUnits(head->xMax, em_size);
  292. afm->FontBBox.ury = PSUnits(head->yMax, em_size);
  293. afm->Ascender = PSUnits(os2->sTypoAscender, em_size);
  294. afm->Descender = PSUnits(os2->sTypoDescender, em_size);
  295. return TRUE;
  296. }
  297. /*******************************************************************************
  298. * ReadCharMetrics
  299. *
  300. * Reads metrics for each glyph in a TrueType font. Returns false for memory
  301. * allocation or FreeType error; sets *p_metrics to NULL for non-fatal error.
  302. *
  303. */
  304. static BOOL ReadCharMetrics(FT_Face face, AFM *afm, AFMMETRICS **p_metrics)
  305. {
  306. FT_ULong charcode, index;
  307. AFMMETRICS *metrics;
  308. USHORT em_size = afm->WinMetrics.usUnitsPerEm;
  309. for (charcode = 0, index = 0; charcode < 65536; ++charcode)
  310. if (pFT_Get_Char_Index(face, charcode) != 0)
  311. ++index; /* count # of glyphs */
  312. afm->NumofMetrics = index;
  313. *p_metrics = metrics = HeapAlloc(PSDRV_Heap, 0, index * sizeof(*metrics));
  314. if (metrics == NULL)
  315. return FALSE;
  316. for (charcode = 0, index = 0; charcode < 65536; ++charcode)
  317. {
  318. FT_UInt glyph_index = pFT_Get_Char_Index(face, charcode);
  319. FT_Error error;
  320. CHAR buffer[128]; /* for glyph names */
  321. if (glyph_index == 0)
  322. continue;
  323. error = pFT_Load_Glyph(face, glyph_index, GLYPH_LOAD_FLAGS);
  324. if (error != FT_Err_Ok)
  325. {
  326. ERR("%s returned %i\n", "FT_Load_Glyph", error);
  327. goto cleanup;
  328. }
  329. error = pFT_Get_Glyph_Name(face, glyph_index, buffer, sizeof(buffer));
  330. if (error != FT_Err_Ok)
  331. {
  332. ERR("%s returned %i\n", "FT_Get_Glyph_Name", error);
  333. goto cleanup;
  334. }
  335. metrics[index].N = PSDRV_GlyphName(buffer);
  336. if (metrics[index].N == NULL)
  337. goto cleanup;
  338. metrics[index].C = metrics[index].UV = charcode;
  339. metrics[index].WX = PSUnits(face->glyph->metrics.horiAdvance, em_size);
  340. ++index;
  341. }
  342. if (afm->WinMetrics.sAvgCharWidth == 0)
  343. afm->WinMetrics.sAvgCharWidth = PSDRV_CalcAvgCharWidth(afm);
  344. return TRUE;
  345. cleanup:
  346. HeapFree(PSDRV_Heap, 0, metrics);
  347. return FALSE;
  348. }
  349. /*******************************************************************************
  350. * BuildTrueTypeAFM
  351. *
  352. * Builds the AFM for a TrueType font and adds it to the driver font list.
  353. * Returns FALSE only on an unexpected error (memory allocation failure or
  354. * FreeType error).
  355. *
  356. */
  357. static BOOL BuildTrueTypeAFM(FT_Face face)
  358. {
  359. AFM *afm;
  360. AFMMETRICS *metrics;
  361. LPSTR font_name, full_name, family_name, encoding_scheme;
  362. FT_CharMap charmap;
  363. BOOL retval, added;
  364. retval = StartAFM(face, &afm);
  365. if (retval == FALSE || afm == NULL)
  366. return retval;
  367. retval = FindCharMap(face, &charmap, &encoding_scheme);
  368. if (retval == FALSE || charmap == NULL)
  369. goto cleanup_afm;
  370. retval = FindMSTTString(face, charmap, TT_NAME_ID_PS_NAME, &font_name);
  371. if (retval == FALSE || font_name == NULL)
  372. goto cleanup_encoding_scheme;
  373. retval = FindMSTTString(face, charmap, TT_NAME_ID_FULL_NAME, &full_name);
  374. if (retval == FALSE || full_name == NULL)
  375. goto cleanup_font_name;
  376. retval = FindMSTTString(face, charmap, TT_NAME_ID_FONT_FAMILY,
  377. &family_name);
  378. if (retval == FALSE || family_name == NULL)
  379. goto cleanup_full_name;
  380. retval = ReadCharMetrics(face, afm, &metrics);
  381. if (retval == FALSE || metrics == NULL)
  382. goto cleanup_family_name;
  383. afm->EncodingScheme = encoding_scheme; afm->FontName = font_name;
  384. afm->FullName = full_name; afm->FamilyName = family_name;
  385. afm->Metrics = metrics;
  386. retval = PSDRV_AddAFMtoList(&PSDRV_AFMFontList, afm, &added);
  387. if (retval == FALSE || added == FALSE)
  388. goto cleanup_family_name;
  389. return TRUE;
  390. /* clean up after fatal or non-fatal errors */
  391. cleanup_family_name:
  392. HeapFree(PSDRV_Heap, 0, family_name);
  393. cleanup_full_name:
  394. HeapFree(PSDRV_Heap, 0, full_name);
  395. cleanup_font_name:
  396. HeapFree(PSDRV_Heap, 0, font_name);
  397. cleanup_encoding_scheme:
  398. HeapFree(PSDRV_Heap, 0, encoding_scheme);
  399. cleanup_afm:
  400. HeapFree(PSDRV_Heap, 0, afm);
  401. return retval;
  402. }
  403. /*******************************************************************************
  404. * ReadTrueTypeFile
  405. *
  406. * Reads font metrics from TrueType font file. Only returns FALSE for
  407. * unexpected errors (memory allocation failure or FreeType error).
  408. *
  409. */
  410. static BOOL ReadTrueTypeFile(FT_Library library, LPCSTR filename)
  411. {
  412. FT_Error error;
  413. FT_Face face;
  414. TRACE("%s\n", filename);
  415. error = pFT_New_Face(library, filename, 0, &face);
  416. if (error != FT_Err_Ok)
  417. {
  418. WARN("FreeType error %i opening %s\n", error, filename);
  419. return TRUE;
  420. }
  421. if ((face->face_flags & REQUIRED_FACE_FLAGS) == REQUIRED_FACE_FLAGS)
  422. {
  423. if (BuildTrueTypeAFM(face) == FALSE)
  424. {
  425. pFT_Done_Face(face);
  426. return FALSE;
  427. }
  428. }
  429. else
  430. {
  431. WARN("Required information missing from %s\n", filename);
  432. }
  433. error = pFT_Done_Face(face);
  434. if (error != FT_Err_Ok)
  435. {
  436. ERR("%s returned %i\n", "FT_Done_Face", error);
  437. return FALSE;
  438. }
  439. return TRUE;
  440. }
  441. /*******************************************************************************
  442. * ReadTrueTypeDir
  443. *
  444. * Reads all TrueType font files in a directory.
  445. *
  446. */
  447. static BOOL ReadTrueTypeDir(FT_Library library, LPCSTR dirname)
  448. {
  449. struct dirent *dent;
  450. DIR *dir;
  451. CHAR filename[256];
  452. dir = opendir(dirname);
  453. if (dir == NULL)
  454. {
  455. WARN("'%s' opening %s\n", strerror(errno), dirname);
  456. return TRUE;
  457. }
  458. while ((dent = readdir(dir)) != NULL)
  459. {
  460. CHAR *file_extension = strrchr(dent->d_name, '.');
  461. int fn_len;
  462. if (file_extension == NULL || strcasecmp(file_extension, ".ttf") != 0)
  463. continue;
  464. fn_len = snprintf(filename, 256, "%s/%s", dirname, dent->d_name);
  465. if (fn_len < 0 || fn_len > sizeof(filename) - 1)
  466. {
  467. WARN("Path '%s/%s' is too long\n", dirname, dent->d_name);
  468. continue;
  469. }
  470. if (ReadTrueTypeFile(library, filename) == FALSE)
  471. {
  472. closedir(dir);
  473. return FALSE;
  474. }
  475. }
  476. closedir(dir);
  477. return TRUE;
  478. }
  479. /*******************************************************************************
  480. * PSDRV_GetTrueTypeMetrics
  481. *
  482. * Reads font metrics from TrueType font files in directories listed in the
  483. * [TrueType Font Directories] section of the Wine configuration file.
  484. *
  485. * If this function fails (returns FALSE), the driver will fail to initialize
  486. * and the driver heap will be destroyed, so it's not necessary to HeapFree
  487. * everything in that event.
  488. *
  489. */
  490. BOOL PSDRV_GetTrueTypeMetrics(void)
  491. {
  492. CHAR name_buf[256], value_buf[256];
  493. INT i = 0;
  494. FT_Error error;
  495. FT_Library library;
  496. HKEY hkey;
  497. DWORD type, name_len, value_len;
  498. if (RegOpenKeyExA(HKEY_LOCAL_MACHINE,
  499. "Software\\Wine\\Wine\\Config\\TrueType Font Directories",
  500. 0, KEY_READ, &hkey) != ERROR_SUCCESS)
  501. return TRUE;
  502. ft_handle = wine_dlopen(SONAME_LIBFREETYPE, RTLD_NOW, NULL, 0);
  503. if(!ft_handle) {
  504. WINE_MESSAGE(
  505. "Wine cannot find the FreeType font library. To enable Wine to\n"
  506. "use TrueType fonts please install a version of FreeType greater than\n"
  507. "or equal to 2.0.5.\n"
  508. "http://www.freetype.org\n");
  509. return TRUE;
  510. }
  511. #define LOAD_FUNCPTR(f) if((p##f = wine_dlsym(ft_handle, #f, NULL, 0)) == NULL) goto sym_not_found;
  512. LOAD_FUNCPTR(FT_Done_Face)
  513. LOAD_FUNCPTR(FT_Done_FreeType)
  514. LOAD_FUNCPTR(FT_Get_Char_Index)
  515. LOAD_FUNCPTR(FT_Get_Glyph_Name)
  516. LOAD_FUNCPTR(FT_Get_Sfnt_Name)
  517. LOAD_FUNCPTR(FT_Get_Sfnt_Name_Count)
  518. LOAD_FUNCPTR(FT_Get_Sfnt_Table)
  519. LOAD_FUNCPTR(FT_Init_FreeType)
  520. LOAD_FUNCPTR(FT_Load_Glyph)
  521. LOAD_FUNCPTR(FT_New_Face)
  522. LOAD_FUNCPTR(FT_Set_Charmap)
  523. #undef LOAD_FUNCPTR
  524. error = pFT_Init_FreeType(&library);
  525. if (error != FT_Err_Ok)
  526. {
  527. ERR("%s returned %i\n", "FT_Init_FreeType", error);
  528. wine_dlclose(ft_handle, NULL, 0);
  529. RegCloseKey(hkey);
  530. return FALSE;
  531. }
  532. name_len = sizeof(name_buf);
  533. value_len = sizeof(value_buf);
  534. while (RegEnumValueA(hkey, i++, name_buf, &name_len, NULL, &type, value_buf,
  535. &value_len) == ERROR_SUCCESS)
  536. {
  537. value_buf[sizeof(value_buf) - 1] = '\0';
  538. if (ReadTrueTypeDir(library, value_buf) == FALSE)
  539. {
  540. RegCloseKey(hkey);
  541. pFT_Done_FreeType(library);
  542. return FALSE;
  543. }
  544. /* initialize lengths for new iteration */
  545. name_len = sizeof(name_buf);
  546. value_len = sizeof(value_buf);
  547. }
  548. RegCloseKey(hkey);
  549. pFT_Done_FreeType(library);
  550. wine_dlclose(ft_handle, NULL, 0);
  551. ft_handle = NULL;
  552. return TRUE;
  553. sym_not_found:
  554. WINE_MESSAGE(
  555. "Wine cannot find certain functions that it needs inside the FreeType\n"
  556. "font library. To enable Wine to use TrueType fonts please upgrade\n"
  557. "FreeType to at least version 2.0.5.\n"
  558. "http://www.freetype.org\n");
  559. wine_dlclose(ft_handle, NULL, 0);
  560. ft_handle = NULL;
  561. return TRUE;
  562. }
  563. #endif /* HAVE_FREETYPE */