/src/compiler/android-ndk/jni/freetype/src/sfnt/sfdriver.c

http://ftk.googlecode.com/ · C · 651 lines · 426 code · 156 blank · 69 comment · 45 complexity · fbd920b6a47e07f3fe2c7d15e159689f MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* sfdriver.c */
  4. /* */
  5. /* High-level SFNT driver interface (body). */
  6. /* */
  7. /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2009 by */
  8. /* David Turner, Robert Wilhelm, and Werner Lemberg. */
  9. /* */
  10. /* This file is part of the FreeType project, and may only be used, */
  11. /* modified, and distributed under the terms of the FreeType project */
  12. /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
  13. /* this file you indicate that you have read the license and */
  14. /* understand and accept it fully. */
  15. /* */
  16. /***************************************************************************/
  17. #include <ft2build.h>
  18. #include FT_INTERNAL_DEBUG_H
  19. #include FT_INTERNAL_SFNT_H
  20. #include FT_INTERNAL_OBJECTS_H
  21. #include "sfdriver.h"
  22. #include "ttload.h"
  23. #include "sfobjs.h"
  24. #include "sfntpic.h"
  25. #include "sferrors.h"
  26. #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
  27. #include "ttsbit.h"
  28. #endif
  29. #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
  30. #include "ttpost.h"
  31. #endif
  32. #ifdef TT_CONFIG_OPTION_BDF
  33. #include "ttbdf.h"
  34. #include FT_SERVICE_BDF_H
  35. #endif
  36. #include "ttcmap.h"
  37. #include "ttkern.h"
  38. #include "ttmtx.h"
  39. #include FT_SERVICE_GLYPH_DICT_H
  40. #include FT_SERVICE_POSTSCRIPT_NAME_H
  41. #include FT_SERVICE_SFNT_H
  42. #include FT_SERVICE_TT_CMAP_H
  43. /*************************************************************************/
  44. /* */
  45. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  46. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  47. /* messages during execution. */
  48. /* */
  49. #undef FT_COMPONENT
  50. #define FT_COMPONENT trace_sfdriver
  51. /*
  52. * SFNT TABLE SERVICE
  53. *
  54. */
  55. static void*
  56. get_sfnt_table( TT_Face face,
  57. FT_Sfnt_Tag tag )
  58. {
  59. void* table;
  60. switch ( tag )
  61. {
  62. case ft_sfnt_head:
  63. table = &face->header;
  64. break;
  65. case ft_sfnt_hhea:
  66. table = &face->horizontal;
  67. break;
  68. case ft_sfnt_vhea:
  69. table = face->vertical_info ? &face->vertical : 0;
  70. break;
  71. case ft_sfnt_os2:
  72. table = face->os2.version == 0xFFFFU ? 0 : &face->os2;
  73. break;
  74. case ft_sfnt_post:
  75. table = &face->postscript;
  76. break;
  77. case ft_sfnt_maxp:
  78. table = &face->max_profile;
  79. break;
  80. case ft_sfnt_pclt:
  81. table = face->pclt.Version ? &face->pclt : 0;
  82. break;
  83. default:
  84. table = 0;
  85. }
  86. return table;
  87. }
  88. static FT_Error
  89. sfnt_table_info( TT_Face face,
  90. FT_UInt idx,
  91. FT_ULong *tag,
  92. FT_ULong *offset,
  93. FT_ULong *length )
  94. {
  95. if ( !tag || !offset || !length )
  96. return SFNT_Err_Invalid_Argument;
  97. if ( idx >= face->num_tables )
  98. return SFNT_Err_Table_Missing;
  99. *tag = face->dir_tables[idx].Tag;
  100. *offset = face->dir_tables[idx].Offset;
  101. *length = face->dir_tables[idx].Length;
  102. return SFNT_Err_Ok;
  103. }
  104. FT_DEFINE_SERVICE_SFNT_TABLEREC(sfnt_service_sfnt_table,
  105. (FT_SFNT_TableLoadFunc)tt_face_load_any,
  106. (FT_SFNT_TableGetFunc) get_sfnt_table,
  107. (FT_SFNT_TableInfoFunc)sfnt_table_info
  108. )
  109. #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
  110. /*
  111. * GLYPH DICT SERVICE
  112. *
  113. */
  114. static FT_Error
  115. sfnt_get_glyph_name( TT_Face face,
  116. FT_UInt glyph_index,
  117. FT_Pointer buffer,
  118. FT_UInt buffer_max )
  119. {
  120. FT_String* gname;
  121. FT_Error error;
  122. error = tt_face_get_ps_name( face, glyph_index, &gname );
  123. if ( !error )
  124. FT_STRCPYN( buffer, gname, buffer_max );
  125. return error;
  126. }
  127. static FT_UInt
  128. sfnt_get_name_index( TT_Face face,
  129. FT_String* glyph_name )
  130. {
  131. FT_Face root = &face->root;
  132. FT_UInt i, max_gid = FT_UINT_MAX;
  133. if ( root->num_glyphs < 0 )
  134. return 0;
  135. else if ( ( FT_ULong ) root->num_glyphs < FT_UINT_MAX )
  136. max_gid = ( FT_UInt ) root->num_glyphs;
  137. else
  138. FT_TRACE0(( "Ignore glyph names for invalid GID 0x%08x - 0x%08x\n",
  139. FT_UINT_MAX, root->num_glyphs ));
  140. for ( i = 0; i < max_gid; i++ )
  141. {
  142. FT_String* gname;
  143. FT_Error error = tt_face_get_ps_name( face, i, &gname );
  144. if ( error )
  145. continue;
  146. if ( !ft_strcmp( glyph_name, gname ) )
  147. return i;
  148. }
  149. return 0;
  150. }
  151. FT_DEFINE_SERVICE_GLYPHDICTREC(sfnt_service_glyph_dict,
  152. (FT_GlyphDict_GetNameFunc) sfnt_get_glyph_name,
  153. (FT_GlyphDict_NameIndexFunc)sfnt_get_name_index
  154. )
  155. #endif /* TT_CONFIG_OPTION_POSTSCRIPT_NAMES */
  156. /*
  157. * POSTSCRIPT NAME SERVICE
  158. *
  159. */
  160. static const char*
  161. sfnt_get_ps_name( TT_Face face )
  162. {
  163. FT_Int n, found_win, found_apple;
  164. const char* result = NULL;
  165. /* shouldn't happen, but just in case to avoid memory leaks */
  166. if ( face->postscript_name )
  167. return face->postscript_name;
  168. /* scan the name table to see whether we have a Postscript name here, */
  169. /* either in Macintosh or Windows platform encodings */
  170. found_win = -1;
  171. found_apple = -1;
  172. for ( n = 0; n < face->num_names; n++ )
  173. {
  174. TT_NameEntryRec* name = face->name_table.names + n;
  175. if ( name->nameID == 6 && name->stringLength > 0 )
  176. {
  177. if ( name->platformID == 3 &&
  178. name->encodingID == 1 &&
  179. name->languageID == 0x409 )
  180. found_win = n;
  181. if ( name->platformID == 1 &&
  182. name->encodingID == 0 &&
  183. name->languageID == 0 )
  184. found_apple = n;
  185. }
  186. }
  187. if ( found_win != -1 )
  188. {
  189. FT_Memory memory = face->root.memory;
  190. TT_NameEntryRec* name = face->name_table.names + found_win;
  191. FT_UInt len = name->stringLength / 2;
  192. FT_Error error = SFNT_Err_Ok;
  193. FT_UNUSED( error );
  194. if ( !FT_ALLOC( result, name->stringLength + 1 ) )
  195. {
  196. FT_Stream stream = face->name_table.stream;
  197. FT_String* r = (FT_String*)result;
  198. FT_Byte* p = (FT_Byte*)name->string;
  199. if ( FT_STREAM_SEEK( name->stringOffset ) ||
  200. FT_FRAME_ENTER( name->stringLength ) )
  201. {
  202. FT_FREE( result );
  203. name->stringLength = 0;
  204. name->stringOffset = 0;
  205. FT_FREE( name->string );
  206. goto Exit;
  207. }
  208. p = (FT_Byte*)stream->cursor;
  209. for ( ; len > 0; len--, p += 2 )
  210. {
  211. if ( p[0] == 0 && p[1] >= 32 && p[1] < 128 )
  212. *r++ = p[1];
  213. }
  214. *r = '\0';
  215. FT_FRAME_EXIT();
  216. }
  217. goto Exit;
  218. }
  219. if ( found_apple != -1 )
  220. {
  221. FT_Memory memory = face->root.memory;
  222. TT_NameEntryRec* name = face->name_table.names + found_apple;
  223. FT_UInt len = name->stringLength;
  224. FT_Error error = SFNT_Err_Ok;
  225. FT_UNUSED( error );
  226. if ( !FT_ALLOC( result, len + 1 ) )
  227. {
  228. FT_Stream stream = face->name_table.stream;
  229. if ( FT_STREAM_SEEK( name->stringOffset ) ||
  230. FT_STREAM_READ( result, len ) )
  231. {
  232. name->stringOffset = 0;
  233. name->stringLength = 0;
  234. FT_FREE( name->string );
  235. FT_FREE( result );
  236. goto Exit;
  237. }
  238. ((char*)result)[len] = '\0';
  239. }
  240. }
  241. Exit:
  242. face->postscript_name = result;
  243. return result;
  244. }
  245. FT_DEFINE_SERVICE_PSFONTNAMEREC(sfnt_service_ps_name,
  246. (FT_PsName_GetFunc)sfnt_get_ps_name
  247. )
  248. /*
  249. * TT CMAP INFO
  250. */
  251. FT_DEFINE_SERVICE_TTCMAPSREC(tt_service_get_cmap_info,
  252. (TT_CMap_Info_GetFunc)tt_get_cmap_info
  253. )
  254. #ifdef TT_CONFIG_OPTION_BDF
  255. static FT_Error
  256. sfnt_get_charset_id( TT_Face face,
  257. const char* *acharset_encoding,
  258. const char* *acharset_registry )
  259. {
  260. BDF_PropertyRec encoding, registry;
  261. FT_Error error;
  262. /* XXX: I don't know whether this is correct, since
  263. * tt_face_find_bdf_prop only returns something correct if we have
  264. * previously selected a size that is listed in the BDF table.
  265. * Should we change the BDF table format to include single offsets
  266. * for `CHARSET_REGISTRY' and `CHARSET_ENCODING'?
  267. */
  268. error = tt_face_find_bdf_prop( face, "CHARSET_REGISTRY", &registry );
  269. if ( !error )
  270. {
  271. error = tt_face_find_bdf_prop( face, "CHARSET_ENCODING", &encoding );
  272. if ( !error )
  273. {
  274. if ( registry.type == BDF_PROPERTY_TYPE_ATOM &&
  275. encoding.type == BDF_PROPERTY_TYPE_ATOM )
  276. {
  277. *acharset_encoding = encoding.u.atom;
  278. *acharset_registry = registry.u.atom;
  279. }
  280. else
  281. error = FT_Err_Invalid_Argument;
  282. }
  283. }
  284. return error;
  285. }
  286. FT_DEFINE_SERVICE_BDFRec(sfnt_service_bdf,
  287. (FT_BDF_GetCharsetIdFunc) sfnt_get_charset_id,
  288. (FT_BDF_GetPropertyFunc) tt_face_find_bdf_prop
  289. )
  290. #endif /* TT_CONFIG_OPTION_BDF */
  291. /*
  292. * SERVICE LIST
  293. */
  294. #if defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES && defined TT_CONFIG_OPTION_BDF
  295. FT_DEFINE_SERVICEDESCREC5(sfnt_services,
  296. FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
  297. FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
  298. FT_SERVICE_ID_GLYPH_DICT, &FT_SFNT_SERVICE_GLYPH_DICT_GET,
  299. FT_SERVICE_ID_BDF, &FT_SFNT_SERVICE_BDF_GET,
  300. FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
  301. )
  302. #elif defined TT_CONFIG_OPTION_POSTSCRIPT_NAMES
  303. FT_DEFINE_SERVICEDESCREC4(sfnt_services,
  304. FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
  305. FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
  306. FT_SERVICE_ID_GLYPH_DICT, &FT_SFNT_SERVICE_GLYPH_DICT_GET,
  307. FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
  308. )
  309. #elif defined TT_CONFIG_OPTION_BDF
  310. FT_DEFINE_SERVICEDESCREC4(sfnt_services,
  311. FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
  312. FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
  313. FT_SERVICE_ID_BDF, &FT_SFNT_SERVICE_BDF_GET,
  314. FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
  315. )
  316. #else
  317. FT_DEFINE_SERVICEDESCREC3(sfnt_services,
  318. FT_SERVICE_ID_SFNT_TABLE, &FT_SFNT_SERVICE_SFNT_TABLE_GET,
  319. FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_SFNT_SERVICE_PS_NAME_GET,
  320. FT_SERVICE_ID_TT_CMAP, &FT_TT_SERVICE_GET_CMAP_INFO_GET
  321. )
  322. #endif
  323. FT_CALLBACK_DEF( FT_Module_Interface )
  324. sfnt_get_interface( FT_Module module,
  325. const char* module_interface )
  326. {
  327. FT_UNUSED( module );
  328. return ft_service_list_lookup( FT_SFNT_SERVICES_GET, module_interface );
  329. }
  330. #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
  331. FT_CALLBACK_DEF( FT_Error )
  332. tt_face_load_sfnt_header_stub( TT_Face face,
  333. FT_Stream stream,
  334. FT_Long face_index,
  335. SFNT_Header header )
  336. {
  337. FT_UNUSED( face );
  338. FT_UNUSED( stream );
  339. FT_UNUSED( face_index );
  340. FT_UNUSED( header );
  341. return FT_Err_Unimplemented_Feature;
  342. }
  343. FT_CALLBACK_DEF( FT_Error )
  344. tt_face_load_directory_stub( TT_Face face,
  345. FT_Stream stream,
  346. SFNT_Header header )
  347. {
  348. FT_UNUSED( face );
  349. FT_UNUSED( stream );
  350. FT_UNUSED( header );
  351. return FT_Err_Unimplemented_Feature;
  352. }
  353. FT_CALLBACK_DEF( FT_Error )
  354. tt_face_load_hdmx_stub( TT_Face face,
  355. FT_Stream stream )
  356. {
  357. FT_UNUSED( face );
  358. FT_UNUSED( stream );
  359. return FT_Err_Unimplemented_Feature;
  360. }
  361. FT_CALLBACK_DEF( void )
  362. tt_face_free_hdmx_stub( TT_Face face )
  363. {
  364. FT_UNUSED( face );
  365. }
  366. FT_CALLBACK_DEF( FT_Error )
  367. tt_face_set_sbit_strike_stub( TT_Face face,
  368. FT_UInt x_ppem,
  369. FT_UInt y_ppem,
  370. FT_ULong* astrike_index )
  371. {
  372. /*
  373. * We simply forge a FT_Size_Request and call the real function
  374. * that does all the work.
  375. *
  376. * This stub might be called by libXfont in the X.Org Xserver,
  377. * compiled against version 2.1.8 or newer.
  378. */
  379. FT_Size_RequestRec req;
  380. req.type = FT_SIZE_REQUEST_TYPE_NOMINAL;
  381. req.width = (FT_F26Dot6)x_ppem;
  382. req.height = (FT_F26Dot6)y_ppem;
  383. req.horiResolution = 0;
  384. req.vertResolution = 0;
  385. *astrike_index = 0x7FFFFFFFUL;
  386. return tt_face_set_sbit_strike( face, &req, astrike_index );
  387. }
  388. FT_CALLBACK_DEF( FT_Error )
  389. tt_face_load_sbit_stub( TT_Face face,
  390. FT_Stream stream )
  391. {
  392. FT_UNUSED( face );
  393. FT_UNUSED( stream );
  394. /*
  395. * This function was originally implemented to load the sbit table.
  396. * However, it has been replaced by `tt_face_load_eblc', and this stub
  397. * is only there for some rogue clients which would want to call it
  398. * directly (which doesn't make much sense).
  399. */
  400. return FT_Err_Unimplemented_Feature;
  401. }
  402. FT_CALLBACK_DEF( void )
  403. tt_face_free_sbit_stub( TT_Face face )
  404. {
  405. /* nothing to do in this stub */
  406. FT_UNUSED( face );
  407. }
  408. FT_CALLBACK_DEF( FT_Error )
  409. tt_face_load_charmap_stub( TT_Face face,
  410. void* cmap,
  411. FT_Stream input )
  412. {
  413. FT_UNUSED( face );
  414. FT_UNUSED( cmap );
  415. FT_UNUSED( input );
  416. return FT_Err_Unimplemented_Feature;
  417. }
  418. FT_CALLBACK_DEF( FT_Error )
  419. tt_face_free_charmap_stub( TT_Face face,
  420. void* cmap )
  421. {
  422. FT_UNUSED( face );
  423. FT_UNUSED( cmap );
  424. return 0;
  425. }
  426. #endif /* FT_CONFIG_OPTION_OLD_INTERNALS */
  427. #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
  428. #define PUT_EMBEDDED_BITMAPS(a) a
  429. #else
  430. #define PUT_EMBEDDED_BITMAPS(a) 0
  431. #endif
  432. #ifdef TT_CONFIG_OPTION_POSTSCRIPT_NAMES
  433. #define PUT_PS_NAMES(a) a
  434. #else
  435. #define PUT_PS_NAMES(a) 0
  436. #endif
  437. FT_DEFINE_SFNT_INTERFACE(sfnt_interface,
  438. tt_face_goto_table,
  439. sfnt_init_face,
  440. sfnt_load_face,
  441. sfnt_done_face,
  442. sfnt_get_interface,
  443. tt_face_load_any,
  444. tt_face_load_sfnt_header_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
  445. tt_face_load_directory_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
  446. tt_face_load_head,
  447. tt_face_load_hhea,
  448. tt_face_load_cmap,
  449. tt_face_load_maxp,
  450. tt_face_load_os2,
  451. tt_face_load_post,
  452. tt_face_load_name,
  453. tt_face_free_name,
  454. tt_face_load_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
  455. tt_face_free_hdmx_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
  456. tt_face_load_kern,
  457. tt_face_load_gasp,
  458. tt_face_load_pclt,
  459. /* see `ttload.h' */
  460. PUT_EMBEDDED_BITMAPS(tt_face_load_bhed),
  461. tt_face_set_sbit_strike_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
  462. tt_face_load_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
  463. tt_find_sbit_image, /* FT_CONFIG_OPTION_OLD_INTERNALS */
  464. tt_load_sbit_metrics, /* FT_CONFIG_OPTION_OLD_INTERNALS */
  465. PUT_EMBEDDED_BITMAPS(tt_face_load_sbit_image),
  466. tt_face_free_sbit_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
  467. /* see `ttpost.h' */
  468. PUT_PS_NAMES(tt_face_get_ps_name),
  469. PUT_PS_NAMES(tt_face_free_ps_names),
  470. tt_face_load_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
  471. tt_face_free_charmap_stub, /* FT_CONFIG_OPTION_OLD_INTERNALS */
  472. /* since version 2.1.8 */
  473. tt_face_get_kerning,
  474. /* since version 2.2 */
  475. tt_face_load_font_dir,
  476. tt_face_load_hmtx,
  477. /* see `ttsbit.h' and `sfnt.h' */
  478. PUT_EMBEDDED_BITMAPS(tt_face_load_eblc),
  479. PUT_EMBEDDED_BITMAPS(tt_face_free_eblc),
  480. PUT_EMBEDDED_BITMAPS(tt_face_set_sbit_strike),
  481. PUT_EMBEDDED_BITMAPS(tt_face_load_strike_metrics),
  482. tt_face_get_metrics
  483. )
  484. FT_DEFINE_MODULE(sfnt_module_class,
  485. 0, /* not a font driver or renderer */
  486. sizeof( FT_ModuleRec ),
  487. "sfnt", /* driver name */
  488. 0x10000L, /* driver version 1.0 */
  489. 0x20000L, /* driver requires FreeType 2.0 or higher */
  490. (const void*)&FT_SFNT_INTERFACE_GET, /* module specific interface */
  491. (FT_Module_Constructor)0,
  492. (FT_Module_Destructor) 0,
  493. (FT_Module_Requester) sfnt_get_interface
  494. )
  495. /* END */