/src/compiler/android-ndk/jni/freetype/src/cff/cffdrivr.c

http://ftk.googlecode.com/ · C · 691 lines · 399 code · 147 blank · 145 comment · 49 complexity · cc28de1ef125a4e96e1409cbd5ab4c2b MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* cffdrivr.c */
  4. /* */
  5. /* OpenType font driver implementation (body). */
  6. /* */
  7. /* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 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_FREETYPE_H
  19. #include FT_INTERNAL_DEBUG_H
  20. #include FT_INTERNAL_STREAM_H
  21. #include FT_INTERNAL_SFNT_H
  22. #include FT_SERVICE_CID_H
  23. #include FT_SERVICE_POSTSCRIPT_CMAPS_H
  24. #include FT_SERVICE_POSTSCRIPT_INFO_H
  25. #include FT_SERVICE_POSTSCRIPT_NAME_H
  26. #include FT_SERVICE_TT_CMAP_H
  27. #include "cffdrivr.h"
  28. #include "cffgload.h"
  29. #include "cffload.h"
  30. #include "cffcmap.h"
  31. #include "cffparse.h"
  32. #include "cfferrs.h"
  33. #include "cffpic.h"
  34. #include FT_SERVICE_XFREE86_NAME_H
  35. #include FT_SERVICE_GLYPH_DICT_H
  36. /*************************************************************************/
  37. /* */
  38. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  39. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  40. /* messages during execution. */
  41. /* */
  42. #undef FT_COMPONENT
  43. #define FT_COMPONENT trace_cffdriver
  44. /*************************************************************************/
  45. /*************************************************************************/
  46. /*************************************************************************/
  47. /**** ****/
  48. /**** ****/
  49. /**** F A C E S ****/
  50. /**** ****/
  51. /**** ****/
  52. /*************************************************************************/
  53. /*************************************************************************/
  54. /*************************************************************************/
  55. #undef PAIR_TAG
  56. #define PAIR_TAG( left, right ) ( ( (FT_ULong)left << 16 ) | \
  57. (FT_ULong)right )
  58. /*************************************************************************/
  59. /* */
  60. /* <Function> */
  61. /* cff_get_kerning */
  62. /* */
  63. /* <Description> */
  64. /* A driver method used to return the kerning vector between two */
  65. /* glyphs of the same face. */
  66. /* */
  67. /* <Input> */
  68. /* face :: A handle to the source face object. */
  69. /* */
  70. /* left_glyph :: The index of the left glyph in the kern pair. */
  71. /* */
  72. /* right_glyph :: The index of the right glyph in the kern pair. */
  73. /* */
  74. /* <Output> */
  75. /* kerning :: The kerning vector. This is in font units for */
  76. /* scalable formats, and in pixels for fixed-sizes */
  77. /* formats. */
  78. /* */
  79. /* <Return> */
  80. /* FreeType error code. 0 means success. */
  81. /* */
  82. /* <Note> */
  83. /* Only horizontal layouts (left-to-right & right-to-left) are */
  84. /* supported by this function. Other layouts, or more sophisticated */
  85. /* kernings, are out of scope of this method (the basic driver */
  86. /* interface is meant to be simple). */
  87. /* */
  88. /* They can be implemented by format-specific interfaces. */
  89. /* */
  90. FT_CALLBACK_DEF( FT_Error )
  91. cff_get_kerning( FT_Face ttface, /* TT_Face */
  92. FT_UInt left_glyph,
  93. FT_UInt right_glyph,
  94. FT_Vector* kerning )
  95. {
  96. TT_Face face = (TT_Face)ttface;
  97. SFNT_Service sfnt = (SFNT_Service)face->sfnt;
  98. kerning->x = 0;
  99. kerning->y = 0;
  100. if ( sfnt )
  101. kerning->x = sfnt->get_kerning( face, left_glyph, right_glyph );
  102. return CFF_Err_Ok;
  103. }
  104. #undef PAIR_TAG
  105. /*************************************************************************/
  106. /* */
  107. /* <Function> */
  108. /* Load_Glyph */
  109. /* */
  110. /* <Description> */
  111. /* A driver method used to load a glyph within a given glyph slot. */
  112. /* */
  113. /* <Input> */
  114. /* slot :: A handle to the target slot object where the glyph */
  115. /* will be loaded. */
  116. /* */
  117. /* size :: A handle to the source face size at which the glyph */
  118. /* must be scaled, loaded, etc. */
  119. /* */
  120. /* glyph_index :: The index of the glyph in the font file. */
  121. /* */
  122. /* load_flags :: A flag indicating what to load for this glyph. The */
  123. /* FT_LOAD_??? constants can be used to control the */
  124. /* glyph loading process (e.g., whether the outline */
  125. /* should be scaled, whether to load bitmaps or not, */
  126. /* whether to hint the outline, etc). */
  127. /* */
  128. /* <Return> */
  129. /* FreeType error code. 0 means success. */
  130. /* */
  131. FT_CALLBACK_DEF( FT_Error )
  132. Load_Glyph( FT_GlyphSlot cffslot, /* CFF_GlyphSlot */
  133. FT_Size cffsize, /* CFF_Size */
  134. FT_UInt glyph_index,
  135. FT_Int32 load_flags )
  136. {
  137. FT_Error error;
  138. CFF_GlyphSlot slot = (CFF_GlyphSlot)cffslot;
  139. CFF_Size size = (CFF_Size)cffsize;
  140. if ( !slot )
  141. return CFF_Err_Invalid_Slot_Handle;
  142. /* check whether we want a scaled outline or bitmap */
  143. if ( !size )
  144. load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
  145. /* reset the size object if necessary */
  146. if ( load_flags & FT_LOAD_NO_SCALE )
  147. size = NULL;
  148. if ( size )
  149. {
  150. /* these two objects must have the same parent */
  151. if ( cffsize->face != cffslot->face )
  152. return CFF_Err_Invalid_Face_Handle;
  153. }
  154. /* now load the glyph outline if necessary */
  155. error = cff_slot_load( slot, size, glyph_index, load_flags );
  156. /* force drop-out mode to 2 - irrelevant now */
  157. /* slot->outline.dropout_mode = 2; */
  158. return error;
  159. }
  160. FT_CALLBACK_DEF( FT_Error )
  161. cff_get_advances( FT_Face face,
  162. FT_UInt start,
  163. FT_UInt count,
  164. FT_Int32 flags,
  165. FT_Fixed* advances )
  166. {
  167. FT_UInt nn;
  168. FT_Error error = CFF_Err_Ok;
  169. FT_GlyphSlot slot = face->glyph;
  170. flags |= (FT_UInt32)FT_LOAD_ADVANCE_ONLY;
  171. for ( nn = 0; nn < count; nn++ )
  172. {
  173. error = Load_Glyph( slot, face->size, start + nn, flags );
  174. if ( error )
  175. break;
  176. advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
  177. ? slot->linearVertAdvance
  178. : slot->linearHoriAdvance;
  179. }
  180. return error;
  181. }
  182. /*
  183. * GLYPH DICT SERVICE
  184. *
  185. */
  186. static FT_Error
  187. cff_get_glyph_name( CFF_Face face,
  188. FT_UInt glyph_index,
  189. FT_Pointer buffer,
  190. FT_UInt buffer_max )
  191. {
  192. CFF_Font font = (CFF_Font)face->extra.data;
  193. FT_Memory memory = FT_FACE_MEMORY( face );
  194. FT_String* gname;
  195. FT_UShort sid;
  196. FT_Service_PsCMaps psnames;
  197. FT_Error error;
  198. FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
  199. if ( !psnames )
  200. {
  201. FT_ERROR(( "cff_get_glyph_name:"
  202. " cannot get glyph name from CFF & CEF fonts\n"
  203. " "
  204. " without the `PSNames' module\n" ));
  205. error = CFF_Err_Unknown_File_Format;
  206. goto Exit;
  207. }
  208. /* first, locate the sid in the charset table */
  209. sid = font->charset.sids[glyph_index];
  210. /* now, lookup the name itself */
  211. gname = cff_index_get_sid_string( &font->string_index, sid, psnames );
  212. if ( gname )
  213. FT_STRCPYN( buffer, gname, buffer_max );
  214. FT_FREE( gname );
  215. error = CFF_Err_Ok;
  216. Exit:
  217. return error;
  218. }
  219. static FT_UInt
  220. cff_get_name_index( CFF_Face face,
  221. FT_String* glyph_name )
  222. {
  223. CFF_Font cff;
  224. CFF_Charset charset;
  225. FT_Service_PsCMaps psnames;
  226. FT_Memory memory = FT_FACE_MEMORY( face );
  227. FT_String* name;
  228. FT_UShort sid;
  229. FT_UInt i;
  230. FT_Int result;
  231. cff = (CFF_FontRec *)face->extra.data;
  232. charset = &cff->charset;
  233. FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
  234. if ( !psnames )
  235. return 0;
  236. for ( i = 0; i < cff->num_glyphs; i++ )
  237. {
  238. sid = charset->sids[i];
  239. if ( sid > 390 )
  240. name = cff_index_get_name( &cff->string_index, sid - 391 );
  241. else
  242. name = (FT_String *)psnames->adobe_std_strings( sid );
  243. if ( !name )
  244. continue;
  245. result = ft_strcmp( glyph_name, name );
  246. if ( sid > 390 )
  247. FT_FREE( name );
  248. if ( !result )
  249. return i;
  250. }
  251. return 0;
  252. }
  253. FT_DEFINE_SERVICE_GLYPHDICTREC(cff_service_glyph_dict,
  254. (FT_GlyphDict_GetNameFunc) cff_get_glyph_name,
  255. (FT_GlyphDict_NameIndexFunc)cff_get_name_index
  256. )
  257. /*
  258. * POSTSCRIPT INFO SERVICE
  259. *
  260. */
  261. static FT_Int
  262. cff_ps_has_glyph_names( FT_Face face )
  263. {
  264. return ( face->face_flags & FT_FACE_FLAG_GLYPH_NAMES ) > 0;
  265. }
  266. static FT_Error
  267. cff_ps_get_font_info( CFF_Face face,
  268. PS_FontInfoRec* afont_info )
  269. {
  270. CFF_Font cff = (CFF_Font)face->extra.data;
  271. FT_Error error = FT_Err_Ok;
  272. if ( cff && cff->font_info == NULL )
  273. {
  274. CFF_FontRecDict dict = &cff->top_font.font_dict;
  275. PS_FontInfoRec *font_info;
  276. FT_Memory memory = face->root.memory;
  277. FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
  278. if ( FT_ALLOC( font_info, sizeof ( *font_info ) ) )
  279. goto Fail;
  280. font_info->version = cff_index_get_sid_string( &cff->string_index,
  281. dict->version,
  282. psnames );
  283. font_info->notice = cff_index_get_sid_string( &cff->string_index,
  284. dict->notice,
  285. psnames );
  286. font_info->full_name = cff_index_get_sid_string( &cff->string_index,
  287. dict->full_name,
  288. psnames );
  289. font_info->family_name = cff_index_get_sid_string( &cff->string_index,
  290. dict->family_name,
  291. psnames );
  292. font_info->weight = cff_index_get_sid_string( &cff->string_index,
  293. dict->weight,
  294. psnames );
  295. font_info->italic_angle = dict->italic_angle;
  296. font_info->is_fixed_pitch = dict->is_fixed_pitch;
  297. font_info->underline_position = (FT_Short)dict->underline_position;
  298. font_info->underline_thickness = (FT_Short)dict->underline_thickness;
  299. cff->font_info = font_info;
  300. }
  301. if ( cff )
  302. *afont_info = *cff->font_info;
  303. Fail:
  304. return error;
  305. }
  306. FT_DEFINE_SERVICE_PSINFOREC(cff_service_ps_info,
  307. (PS_GetFontInfoFunc) cff_ps_get_font_info,
  308. (PS_GetFontExtraFunc) NULL,
  309. (PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,
  310. (PS_GetFontPrivateFunc)NULL /* unsupported with CFF fonts */
  311. )
  312. /*
  313. * POSTSCRIPT NAME SERVICE
  314. *
  315. */
  316. static const char*
  317. cff_get_ps_name( CFF_Face face )
  318. {
  319. CFF_Font cff = (CFF_Font)face->extra.data;
  320. return (const char*)cff->font_name;
  321. }
  322. FT_DEFINE_SERVICE_PSFONTNAMEREC(cff_service_ps_name,
  323. (FT_PsName_GetFunc)cff_get_ps_name
  324. )
  325. /*
  326. * TT CMAP INFO
  327. *
  328. * If the charmap is a synthetic Unicode encoding cmap or
  329. * a Type 1 standard (or expert) encoding cmap, hide TT CMAP INFO
  330. * service defined in SFNT module.
  331. *
  332. * Otherwise call the service function in the sfnt module.
  333. *
  334. */
  335. static FT_Error
  336. cff_get_cmap_info( FT_CharMap charmap,
  337. TT_CMapInfo *cmap_info )
  338. {
  339. FT_CMap cmap = FT_CMAP( charmap );
  340. FT_Error error = CFF_Err_Ok;
  341. FT_Face face = FT_CMAP_FACE( cmap );
  342. FT_Library library = FT_FACE_LIBRARY( face );
  343. cmap_info->language = 0;
  344. cmap_info->format = 0;
  345. if ( cmap->clazz != &FT_CFF_CMAP_ENCODING_CLASS_REC_GET &&
  346. cmap->clazz != &FT_CFF_CMAP_UNICODE_CLASS_REC_GET )
  347. {
  348. FT_Module sfnt = FT_Get_Module( library, "sfnt" );
  349. FT_Service_TTCMaps service =
  350. (FT_Service_TTCMaps)ft_module_get_service( sfnt,
  351. FT_SERVICE_ID_TT_CMAP );
  352. if ( service && service->get_cmap_info )
  353. error = service->get_cmap_info( charmap, cmap_info );
  354. }
  355. return error;
  356. }
  357. FT_DEFINE_SERVICE_TTCMAPSREC(cff_service_get_cmap_info,
  358. (TT_CMap_Info_GetFunc)cff_get_cmap_info
  359. )
  360. /*
  361. * CID INFO SERVICE
  362. *
  363. */
  364. static FT_Error
  365. cff_get_ros( CFF_Face face,
  366. const char* *registry,
  367. const char* *ordering,
  368. FT_Int *supplement )
  369. {
  370. FT_Error error = CFF_Err_Ok;
  371. CFF_Font cff = (CFF_Font)face->extra.data;
  372. if ( cff )
  373. {
  374. CFF_FontRecDict dict = &cff->top_font.font_dict;
  375. FT_Service_PsCMaps psnames = (FT_Service_PsCMaps)cff->psnames;
  376. if ( dict->cid_registry == 0xFFFFU )
  377. {
  378. error = CFF_Err_Invalid_Argument;
  379. goto Fail;
  380. }
  381. if ( registry )
  382. {
  383. if ( cff->registry == NULL )
  384. cff->registry = cff_index_get_sid_string( &cff->string_index,
  385. dict->cid_registry,
  386. psnames );
  387. *registry = cff->registry;
  388. }
  389. if ( ordering )
  390. {
  391. if ( cff->ordering == NULL )
  392. cff->ordering = cff_index_get_sid_string( &cff->string_index,
  393. dict->cid_ordering,
  394. psnames );
  395. *ordering = cff->ordering;
  396. }
  397. /*
  398. * XXX: According to Adobe TechNote #5176, the supplement in CFF
  399. * can be a real number. We truncate it to fit public API
  400. * since freetype-2.3.6.
  401. */
  402. if ( supplement )
  403. {
  404. if ( dict->cid_supplement < FT_INT_MIN ||
  405. dict->cid_supplement > FT_INT_MAX )
  406. FT_TRACE1(( "cff_get_ros: too large supplement %d is truncated\n",
  407. dict->cid_supplement ));
  408. *supplement = (FT_Int)dict->cid_supplement;
  409. }
  410. }
  411. Fail:
  412. return error;
  413. }
  414. static FT_Error
  415. cff_get_is_cid( CFF_Face face,
  416. FT_Bool *is_cid )
  417. {
  418. FT_Error error = CFF_Err_Ok;
  419. CFF_Font cff = (CFF_Font)face->extra.data;
  420. *is_cid = 0;
  421. if ( cff )
  422. {
  423. CFF_FontRecDict dict = &cff->top_font.font_dict;
  424. if ( dict->cid_registry != 0xFFFFU )
  425. *is_cid = 1;
  426. }
  427. return error;
  428. }
  429. static FT_Error
  430. cff_get_cid_from_glyph_index( CFF_Face face,
  431. FT_UInt glyph_index,
  432. FT_UInt *cid )
  433. {
  434. FT_Error error = CFF_Err_Ok;
  435. CFF_Font cff;
  436. cff = (CFF_Font)face->extra.data;
  437. if ( cff )
  438. {
  439. FT_UInt c;
  440. CFF_FontRecDict dict = &cff->top_font.font_dict;
  441. if ( dict->cid_registry == 0xFFFFU )
  442. {
  443. error = CFF_Err_Invalid_Argument;
  444. goto Fail;
  445. }
  446. if ( glyph_index > cff->num_glyphs )
  447. {
  448. error = CFF_Err_Invalid_Argument;
  449. goto Fail;
  450. }
  451. c = cff->charset.sids[glyph_index];
  452. if ( cid )
  453. *cid = c;
  454. }
  455. Fail:
  456. return error;
  457. }
  458. FT_DEFINE_SERVICE_CIDREC(cff_service_cid_info,
  459. (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros,
  460. (FT_CID_GetIsInternallyCIDKeyedFunc) cff_get_is_cid,
  461. (FT_CID_GetCIDFromGlyphIndexFunc) cff_get_cid_from_glyph_index
  462. )
  463. /*************************************************************************/
  464. /*************************************************************************/
  465. /*************************************************************************/
  466. /**** ****/
  467. /**** ****/
  468. /**** D R I V E R I N T E R F A C E ****/
  469. /**** ****/
  470. /**** ****/
  471. /*************************************************************************/
  472. /*************************************************************************/
  473. /*************************************************************************/
  474. #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
  475. FT_DEFINE_SERVICEDESCREC6(cff_services,
  476. FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF,
  477. FT_SERVICE_ID_POSTSCRIPT_INFO, &FT_CFF_SERVICE_PS_INFO_GET,
  478. FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET,
  479. FT_SERVICE_ID_GLYPH_DICT, &FT_CFF_SERVICE_GLYPH_DICT_GET,
  480. FT_SERVICE_ID_TT_CMAP, &FT_CFF_SERVICE_GET_CMAP_INFO_GET,
  481. FT_SERVICE_ID_CID, &FT_CFF_SERVICE_CID_INFO_GET
  482. )
  483. #else
  484. FT_DEFINE_SERVICEDESCREC5(cff_services,
  485. FT_SERVICE_ID_XF86_NAME, FT_XF86_FORMAT_CFF,
  486. FT_SERVICE_ID_POSTSCRIPT_INFO, &FT_CFF_SERVICE_PS_INFO_GET,
  487. FT_SERVICE_ID_POSTSCRIPT_FONT_NAME, &FT_CFF_SERVICE_PS_NAME_GET,
  488. FT_SERVICE_ID_TT_CMAP, &FT_CFF_SERVICE_GET_CMAP_INFO_GET,
  489. FT_SERVICE_ID_CID, &FT_CFF_SERVICE_CID_INFO_GET
  490. )
  491. #endif
  492. FT_CALLBACK_DEF( FT_Module_Interface )
  493. cff_get_interface( FT_Module driver, /* CFF_Driver */
  494. const char* module_interface )
  495. {
  496. FT_Module sfnt;
  497. FT_Module_Interface result;
  498. result = ft_service_list_lookup( FT_CFF_SERVICES_GET, module_interface );
  499. if ( result != NULL )
  500. return result;
  501. if ( !driver )
  502. return NULL;
  503. /* we pass our request to the `sfnt' module */
  504. sfnt = FT_Get_Module( driver->library, "sfnt" );
  505. return sfnt ? sfnt->clazz->get_interface( sfnt, module_interface ) : 0;
  506. }
  507. /* The FT_DriverInterface structure is defined in ftdriver.h. */
  508. #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
  509. #define CFF_SIZE_SELECT cff_size_select
  510. #else
  511. #define CFF_SIZE_SELECT 0
  512. #endif
  513. FT_DEFINE_DRIVER(cff_driver_class,
  514. FT_MODULE_FONT_DRIVER |
  515. FT_MODULE_DRIVER_SCALABLE |
  516. FT_MODULE_DRIVER_HAS_HINTER,
  517. sizeof( CFF_DriverRec ),
  518. "cff",
  519. 0x10000L,
  520. 0x20000L,
  521. 0, /* module-specific interface */
  522. cff_driver_init,
  523. cff_driver_done,
  524. cff_get_interface,
  525. /* now the specific driver fields */
  526. sizeof( TT_FaceRec ),
  527. sizeof( CFF_SizeRec ),
  528. sizeof( CFF_GlyphSlotRec ),
  529. cff_face_init,
  530. cff_face_done,
  531. cff_size_init,
  532. cff_size_done,
  533. cff_slot_init,
  534. cff_slot_done,
  535. ft_stub_set_char_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */
  536. ft_stub_set_pixel_sizes, /* FT_CONFIG_OPTION_OLD_INTERNALS */
  537. Load_Glyph,
  538. cff_get_kerning,
  539. 0, /* FT_Face_AttachFunc */
  540. cff_get_advances, /* FT_Face_GetAdvancesFunc */
  541. cff_size_request,
  542. CFF_SIZE_SELECT
  543. )
  544. /* END */