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

http://ftk.googlecode.com/ · C · 968 lines · 626 code · 224 blank · 118 comment · 118 complexity · 98a99027526df6a17afca392dccfc0e8 MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* cffobjs.c */
  4. /* */
  5. /* OpenType objects manager (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_INTERNAL_DEBUG_H
  19. #include FT_INTERNAL_CALC_H
  20. #include FT_INTERNAL_STREAM_H
  21. #include FT_ERRORS_H
  22. #include FT_TRUETYPE_IDS_H
  23. #include FT_TRUETYPE_TAGS_H
  24. #include FT_INTERNAL_SFNT_H
  25. #include FT_SERVICE_POSTSCRIPT_CMAPS_H
  26. #include FT_INTERNAL_POSTSCRIPT_HINTS_H
  27. #include "cffobjs.h"
  28. #include "cffload.h"
  29. #include "cffcmap.h"
  30. #include "cfferrs.h"
  31. #include "cffpic.h"
  32. /*************************************************************************/
  33. /* */
  34. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  35. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  36. /* messages during execution. */
  37. /* */
  38. #undef FT_COMPONENT
  39. #define FT_COMPONENT trace_cffobjs
  40. /*************************************************************************/
  41. /* */
  42. /* SIZE FUNCTIONS */
  43. /* */
  44. /* Note that we store the global hints in the size's `internal' root */
  45. /* field. */
  46. /* */
  47. /*************************************************************************/
  48. static PSH_Globals_Funcs
  49. cff_size_get_globals_funcs( CFF_Size size )
  50. {
  51. CFF_Face face = (CFF_Face)size->root.face;
  52. CFF_Font font = (CFF_Font)face->extra.data;
  53. PSHinter_Service pshinter = (PSHinter_Service)font->pshinter;
  54. FT_Module module;
  55. module = FT_Get_Module( size->root.face->driver->root.library,
  56. "pshinter" );
  57. return ( module && pshinter && pshinter->get_globals_funcs )
  58. ? pshinter->get_globals_funcs( module )
  59. : 0;
  60. }
  61. FT_LOCAL_DEF( void )
  62. cff_size_done( FT_Size cffsize ) /* CFF_Size */
  63. {
  64. CFF_Size size = (CFF_Size)cffsize;
  65. CFF_Face face = (CFF_Face)size->root.face;
  66. CFF_Font font = (CFF_Font)face->extra.data;
  67. CFF_Internal internal = (CFF_Internal)cffsize->internal;
  68. if ( internal )
  69. {
  70. PSH_Globals_Funcs funcs;
  71. funcs = cff_size_get_globals_funcs( size );
  72. if ( funcs )
  73. {
  74. FT_UInt i;
  75. funcs->destroy( internal->topfont );
  76. for ( i = font->num_subfonts; i > 0; i-- )
  77. funcs->destroy( internal->subfonts[i - 1] );
  78. }
  79. /* `internal' is freed by destroy_size (in ftobjs.c) */
  80. }
  81. }
  82. /* CFF and Type 1 private dictionaries have slightly different */
  83. /* structures; we need to synthesize a Type 1 dictionary on the fly */
  84. static void
  85. cff_make_private_dict( CFF_SubFont subfont,
  86. PS_Private priv )
  87. {
  88. CFF_Private cpriv = &subfont->private_dict;
  89. FT_UInt n, count;
  90. FT_MEM_ZERO( priv, sizeof ( *priv ) );
  91. count = priv->num_blue_values = cpriv->num_blue_values;
  92. for ( n = 0; n < count; n++ )
  93. priv->blue_values[n] = (FT_Short)cpriv->blue_values[n];
  94. count = priv->num_other_blues = cpriv->num_other_blues;
  95. for ( n = 0; n < count; n++ )
  96. priv->other_blues[n] = (FT_Short)cpriv->other_blues[n];
  97. count = priv->num_family_blues = cpriv->num_family_blues;
  98. for ( n = 0; n < count; n++ )
  99. priv->family_blues[n] = (FT_Short)cpriv->family_blues[n];
  100. count = priv->num_family_other_blues = cpriv->num_family_other_blues;
  101. for ( n = 0; n < count; n++ )
  102. priv->family_other_blues[n] = (FT_Short)cpriv->family_other_blues[n];
  103. priv->blue_scale = cpriv->blue_scale;
  104. priv->blue_shift = (FT_Int)cpriv->blue_shift;
  105. priv->blue_fuzz = (FT_Int)cpriv->blue_fuzz;
  106. priv->standard_width[0] = (FT_UShort)cpriv->standard_width;
  107. priv->standard_height[0] = (FT_UShort)cpriv->standard_height;
  108. count = priv->num_snap_widths = cpriv->num_snap_widths;
  109. for ( n = 0; n < count; n++ )
  110. priv->snap_widths[n] = (FT_Short)cpriv->snap_widths[n];
  111. count = priv->num_snap_heights = cpriv->num_snap_heights;
  112. for ( n = 0; n < count; n++ )
  113. priv->snap_heights[n] = (FT_Short)cpriv->snap_heights[n];
  114. priv->force_bold = cpriv->force_bold;
  115. priv->language_group = cpriv->language_group;
  116. priv->lenIV = cpriv->lenIV;
  117. }
  118. FT_LOCAL_DEF( FT_Error )
  119. cff_size_init( FT_Size cffsize ) /* CFF_Size */
  120. {
  121. CFF_Size size = (CFF_Size)cffsize;
  122. FT_Error error = CFF_Err_Ok;
  123. PSH_Globals_Funcs funcs = cff_size_get_globals_funcs( size );
  124. if ( funcs )
  125. {
  126. CFF_Face face = (CFF_Face)cffsize->face;
  127. CFF_Font font = (CFF_Font)face->extra.data;
  128. CFF_Internal internal;
  129. PS_PrivateRec priv;
  130. FT_Memory memory = cffsize->face->memory;
  131. FT_UInt i;
  132. if ( FT_NEW( internal ) )
  133. goto Exit;
  134. cff_make_private_dict( &font->top_font, &priv );
  135. error = funcs->create( cffsize->face->memory, &priv,
  136. &internal->topfont );
  137. if ( error )
  138. goto Exit;
  139. for ( i = font->num_subfonts; i > 0; i-- )
  140. {
  141. CFF_SubFont sub = font->subfonts[i - 1];
  142. cff_make_private_dict( sub, &priv );
  143. error = funcs->create( cffsize->face->memory, &priv,
  144. &internal->subfonts[i - 1] );
  145. if ( error )
  146. goto Exit;
  147. }
  148. cffsize->internal = (FT_Size_Internal)(void*)internal;
  149. }
  150. size->strike_index = 0xFFFFFFFFUL;
  151. Exit:
  152. return error;
  153. }
  154. #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
  155. FT_LOCAL_DEF( FT_Error )
  156. cff_size_select( FT_Size size,
  157. FT_ULong strike_index )
  158. {
  159. CFF_Size cffsize = (CFF_Size)size;
  160. PSH_Globals_Funcs funcs;
  161. cffsize->strike_index = strike_index;
  162. FT_Select_Metrics( size->face, strike_index );
  163. funcs = cff_size_get_globals_funcs( cffsize );
  164. if ( funcs )
  165. {
  166. CFF_Face face = (CFF_Face)size->face;
  167. CFF_Font font = (CFF_Font)face->extra.data;
  168. CFF_Internal internal = (CFF_Internal)size->internal;
  169. FT_ULong top_upm = font->top_font.font_dict.units_per_em;
  170. FT_UInt i;
  171. funcs->set_scale( internal->topfont,
  172. size->metrics.x_scale, size->metrics.y_scale,
  173. 0, 0 );
  174. for ( i = font->num_subfonts; i > 0; i-- )
  175. {
  176. CFF_SubFont sub = font->subfonts[i - 1];
  177. FT_ULong sub_upm = sub->font_dict.units_per_em;
  178. FT_Pos x_scale, y_scale;
  179. if ( top_upm != sub_upm )
  180. {
  181. x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );
  182. y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );
  183. }
  184. else
  185. {
  186. x_scale = size->metrics.x_scale;
  187. y_scale = size->metrics.y_scale;
  188. }
  189. funcs->set_scale( internal->subfonts[i - 1],
  190. x_scale, y_scale, 0, 0 );
  191. }
  192. }
  193. return CFF_Err_Ok;
  194. }
  195. #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
  196. FT_LOCAL_DEF( FT_Error )
  197. cff_size_request( FT_Size size,
  198. FT_Size_Request req )
  199. {
  200. CFF_Size cffsize = (CFF_Size)size;
  201. PSH_Globals_Funcs funcs;
  202. #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
  203. if ( FT_HAS_FIXED_SIZES( size->face ) )
  204. {
  205. CFF_Face cffface = (CFF_Face)size->face;
  206. SFNT_Service sfnt = (SFNT_Service)cffface->sfnt;
  207. FT_ULong strike_index;
  208. if ( sfnt->set_sbit_strike( cffface, req, &strike_index ) )
  209. cffsize->strike_index = 0xFFFFFFFFUL;
  210. else
  211. return cff_size_select( size, strike_index );
  212. }
  213. #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
  214. FT_Request_Metrics( size->face, req );
  215. funcs = cff_size_get_globals_funcs( cffsize );
  216. if ( funcs )
  217. {
  218. CFF_Face cffface = (CFF_Face)size->face;
  219. CFF_Font font = (CFF_Font)cffface->extra.data;
  220. CFF_Internal internal = (CFF_Internal)size->internal;
  221. FT_ULong top_upm = font->top_font.font_dict.units_per_em;
  222. FT_UInt i;
  223. funcs->set_scale( internal->topfont,
  224. size->metrics.x_scale, size->metrics.y_scale,
  225. 0, 0 );
  226. for ( i = font->num_subfonts; i > 0; i-- )
  227. {
  228. CFF_SubFont sub = font->subfonts[i - 1];
  229. FT_ULong sub_upm = sub->font_dict.units_per_em;
  230. FT_Pos x_scale, y_scale;
  231. if ( top_upm != sub_upm )
  232. {
  233. x_scale = FT_MulDiv( size->metrics.x_scale, top_upm, sub_upm );
  234. y_scale = FT_MulDiv( size->metrics.y_scale, top_upm, sub_upm );
  235. }
  236. else
  237. {
  238. x_scale = size->metrics.x_scale;
  239. y_scale = size->metrics.y_scale;
  240. }
  241. funcs->set_scale( internal->subfonts[i - 1],
  242. x_scale, y_scale, 0, 0 );
  243. }
  244. }
  245. return CFF_Err_Ok;
  246. }
  247. /*************************************************************************/
  248. /* */
  249. /* SLOT FUNCTIONS */
  250. /* */
  251. /*************************************************************************/
  252. FT_LOCAL_DEF( void )
  253. cff_slot_done( FT_GlyphSlot slot )
  254. {
  255. slot->internal->glyph_hints = 0;
  256. }
  257. FT_LOCAL_DEF( FT_Error )
  258. cff_slot_init( FT_GlyphSlot slot )
  259. {
  260. CFF_Face face = (CFF_Face)slot->face;
  261. CFF_Font font = (CFF_Font)face->extra.data;
  262. PSHinter_Service pshinter = (PSHinter_Service)font->pshinter;
  263. if ( pshinter )
  264. {
  265. FT_Module module;
  266. module = FT_Get_Module( slot->face->driver->root.library,
  267. "pshinter" );
  268. if ( module )
  269. {
  270. T2_Hints_Funcs funcs;
  271. funcs = pshinter->get_t2_funcs( module );
  272. slot->internal->glyph_hints = (void*)funcs;
  273. }
  274. }
  275. return CFF_Err_Ok;
  276. }
  277. /*************************************************************************/
  278. /* */
  279. /* FACE FUNCTIONS */
  280. /* */
  281. /*************************************************************************/
  282. static FT_String*
  283. cff_strcpy( FT_Memory memory,
  284. const FT_String* source )
  285. {
  286. FT_Error error;
  287. FT_String* result;
  288. (void)FT_STRDUP( result, source );
  289. FT_UNUSED( error );
  290. return result;
  291. }
  292. FT_LOCAL_DEF( FT_Error )
  293. cff_face_init( FT_Stream stream,
  294. FT_Face cffface, /* CFF_Face */
  295. FT_Int face_index,
  296. FT_Int num_params,
  297. FT_Parameter* params )
  298. {
  299. CFF_Face face = (CFF_Face)cffface;
  300. FT_Error error;
  301. SFNT_Service sfnt;
  302. FT_Service_PsCMaps psnames;
  303. PSHinter_Service pshinter;
  304. FT_Bool pure_cff = 1;
  305. FT_Bool sfnt_format = 0;
  306. FT_Library library = cffface->driver->root.library;
  307. #if 0
  308. FT_FACE_FIND_GLOBAL_SERVICE( face, sfnt, SFNT );
  309. FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_NAMES );
  310. FT_FACE_FIND_GLOBAL_SERVICE( face, pshinter, POSTSCRIPT_HINTER );
  311. if ( !sfnt )
  312. goto Bad_Format;
  313. #else
  314. sfnt = (SFNT_Service)FT_Get_Module_Interface(
  315. library, "sfnt" );
  316. if ( !sfnt )
  317. goto Bad_Format;
  318. FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
  319. pshinter = (PSHinter_Service)FT_Get_Module_Interface(
  320. library, "pshinter" );
  321. #endif
  322. /* create input stream from resource */
  323. if ( FT_STREAM_SEEK( 0 ) )
  324. goto Exit;
  325. /* check whether we have a valid OpenType file */
  326. error = sfnt->init_face( stream, face, face_index, num_params, params );
  327. if ( !error )
  328. {
  329. if ( face->format_tag != TTAG_OTTO ) /* `OTTO'; OpenType/CFF font */
  330. {
  331. FT_TRACE2(( "[not a valid OpenType/CFF font]\n" ));
  332. goto Bad_Format;
  333. }
  334. /* if we are performing a simple font format check, exit immediately */
  335. if ( face_index < 0 )
  336. return CFF_Err_Ok;
  337. /* UNDOCUMENTED! A CFF in an SFNT can have only a single font. */
  338. if ( face_index > 0 )
  339. {
  340. FT_ERROR(( "cff_face_init: invalid face index\n" ));
  341. error = CFF_Err_Invalid_Argument;
  342. goto Exit;
  343. }
  344. sfnt_format = 1;
  345. /* now, the font can be either an OpenType/CFF font, or an SVG CEF */
  346. /* font; in the latter case it doesn't have a `head' table */
  347. error = face->goto_table( face, TTAG_head, stream, 0 );
  348. if ( !error )
  349. {
  350. pure_cff = 0;
  351. /* load font directory */
  352. error = sfnt->load_face( stream, face, 0, num_params, params );
  353. if ( error )
  354. goto Exit;
  355. }
  356. else
  357. {
  358. /* load the `cmap' table explicitly */
  359. error = sfnt->load_cmap( face, stream );
  360. if ( error )
  361. goto Exit;
  362. /* XXX: we don't load the GPOS table, as OpenType Layout */
  363. /* support will be added later to a layout library on top of */
  364. /* FreeType 2 */
  365. }
  366. /* now load the CFF part of the file */
  367. error = face->goto_table( face, TTAG_CFF, stream, 0 );
  368. if ( error )
  369. goto Exit;
  370. }
  371. else
  372. {
  373. /* rewind to start of file; we are going to load a pure-CFF font */
  374. if ( FT_STREAM_SEEK( 0 ) )
  375. goto Exit;
  376. error = CFF_Err_Ok;
  377. }
  378. /* now load and parse the CFF table in the file */
  379. {
  380. CFF_Font cff;
  381. CFF_FontRecDict dict;
  382. FT_Memory memory = cffface->memory;
  383. FT_Int32 flags;
  384. FT_UInt i;
  385. if ( FT_NEW( cff ) )
  386. goto Exit;
  387. face->extra.data = cff;
  388. error = cff_font_load( library, stream, face_index, cff, pure_cff );
  389. if ( error )
  390. goto Exit;
  391. cff->pshinter = pshinter;
  392. cff->psnames = (void*)psnames;
  393. cffface->face_index = face_index;
  394. /* Complement the root flags with some interesting information. */
  395. /* Note that this is only necessary for pure CFF and CEF fonts; */
  396. /* SFNT based fonts use the `name' table instead. */
  397. cffface->num_glyphs = cff->num_glyphs;
  398. dict = &cff->top_font.font_dict;
  399. /* we need the `PSNames' module for CFF and CEF formats */
  400. /* which aren't CID-keyed */
  401. if ( dict->cid_registry == 0xFFFFU && !psnames )
  402. {
  403. FT_ERROR(( "cff_face_init:"
  404. " cannot open CFF & CEF fonts\n"
  405. " "
  406. " without the `PSNames' module\n" ));
  407. goto Bad_Format;
  408. }
  409. if ( !dict->units_per_em )
  410. dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM;
  411. /* Normalize the font matrix so that `matrix->xx' is 1; the */
  412. /* scaling is done with `units_per_em' then (at this point, */
  413. /* it already contains the scaling factor, but without */
  414. /* normalization of the matrix). */
  415. /* */
  416. /* Note that the offsets must be expressed in integer font */
  417. /* units. */
  418. {
  419. FT_Matrix* matrix = &dict->font_matrix;
  420. FT_Vector* offset = &dict->font_offset;
  421. FT_ULong* upm = &dict->units_per_em;
  422. FT_Fixed temp = FT_ABS( matrix->yy );
  423. if ( temp != 0x10000L )
  424. {
  425. *upm = FT_DivFix( *upm, temp );
  426. matrix->xx = FT_DivFix( matrix->xx, temp );
  427. matrix->yx = FT_DivFix( matrix->yx, temp );
  428. matrix->xy = FT_DivFix( matrix->xy, temp );
  429. matrix->yy = FT_DivFix( matrix->yy, temp );
  430. offset->x = FT_DivFix( offset->x, temp );
  431. offset->y = FT_DivFix( offset->y, temp );
  432. }
  433. offset->x >>= 16;
  434. offset->y >>= 16;
  435. }
  436. for ( i = cff->num_subfonts; i > 0; i-- )
  437. {
  438. CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict;
  439. CFF_FontRecDict top = &cff->top_font.font_dict;
  440. FT_Matrix* matrix;
  441. FT_Vector* offset;
  442. FT_ULong* upm;
  443. FT_Fixed temp;
  444. if ( sub->units_per_em )
  445. {
  446. FT_Long scaling;
  447. if ( top->units_per_em > 1 && sub->units_per_em > 1 )
  448. scaling = FT_MIN( top->units_per_em, sub->units_per_em );
  449. else
  450. scaling = 1;
  451. FT_Matrix_Multiply_Scaled( &top->font_matrix,
  452. &sub->font_matrix,
  453. scaling );
  454. FT_Vector_Transform_Scaled( &sub->font_offset,
  455. &top->font_matrix,
  456. scaling );
  457. sub->units_per_em = FT_MulDiv( sub->units_per_em,
  458. top->units_per_em,
  459. scaling );
  460. }
  461. else
  462. {
  463. sub->font_matrix = top->font_matrix;
  464. sub->font_offset = top->font_offset;
  465. sub->units_per_em = top->units_per_em;
  466. }
  467. matrix = &sub->font_matrix;
  468. offset = &sub->font_offset;
  469. upm = &sub->units_per_em;
  470. temp = FT_ABS( matrix->yy );
  471. if ( temp != 0x10000L )
  472. {
  473. *upm = FT_DivFix( *upm, temp );
  474. /* if *upm is larger than 100*1000 we divide by 1000 -- */
  475. /* this can happen if e.g. there is no top-font FontMatrix */
  476. /* and the subfont FontMatrix already contains the complete */
  477. /* scaling for the subfont (see section 5.11 of the PLRM) */
  478. /* 100 is a heuristic value */
  479. if ( *upm > 100L * 1000L )
  480. *upm = ( *upm + 500 ) / 1000;
  481. matrix->xx = FT_DivFix( matrix->xx, temp );
  482. matrix->yx = FT_DivFix( matrix->yx, temp );
  483. matrix->xy = FT_DivFix( matrix->xy, temp );
  484. matrix->yy = FT_DivFix( matrix->yy, temp );
  485. offset->x = FT_DivFix( offset->x, temp );
  486. offset->y = FT_DivFix( offset->y, temp );
  487. }
  488. offset->x >>= 16;
  489. offset->y >>= 16;
  490. }
  491. if ( pure_cff )
  492. {
  493. char* style_name = NULL;
  494. /* set up num_faces */
  495. cffface->num_faces = cff->num_faces;
  496. /* compute number of glyphs */
  497. if ( dict->cid_registry != 0xFFFFU )
  498. cffface->num_glyphs = cff->charset.max_cid;
  499. else
  500. cffface->num_glyphs = cff->charstrings_index.count;
  501. /* set global bbox, as well as EM size */
  502. cffface->bbox.xMin = dict->font_bbox.xMin >> 16;
  503. cffface->bbox.yMin = dict->font_bbox.yMin >> 16;
  504. /* no `U' suffix here to 0xFFFF! */
  505. cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFF ) >> 16;
  506. cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFF ) >> 16;
  507. cffface->units_per_EM = (FT_UShort)( dict->units_per_em );
  508. cffface->ascender = (FT_Short)( cffface->bbox.yMax );
  509. cffface->descender = (FT_Short)( cffface->bbox.yMin );
  510. cffface->height = (FT_Short)( ( cffface->units_per_EM * 12 ) / 10 );
  511. if ( cffface->height < cffface->ascender - cffface->descender )
  512. cffface->height = (FT_Short)( cffface->ascender - cffface->descender );
  513. cffface->underline_position =
  514. (FT_Short)( dict->underline_position >> 16 );
  515. cffface->underline_thickness =
  516. (FT_Short)( dict->underline_thickness >> 16 );
  517. /* retrieve font family & style name */
  518. cffface->family_name = cff_index_get_name( &cff->name_index,
  519. face_index );
  520. if ( cffface->family_name )
  521. {
  522. char* full = cff_index_get_sid_string( &cff->string_index,
  523. dict->full_name,
  524. psnames );
  525. char* fullp = full;
  526. char* family = cffface->family_name;
  527. char* family_name = 0;
  528. if ( dict->family_name )
  529. {
  530. family_name = cff_index_get_sid_string( &cff->string_index,
  531. dict->family_name,
  532. psnames);
  533. if ( family_name )
  534. family = family_name;
  535. }
  536. /* We try to extract the style name from the full name. */
  537. /* We need to ignore spaces and dashes during the search. */
  538. if ( full && family )
  539. {
  540. while ( *fullp )
  541. {
  542. /* skip common characters at the start of both strings */
  543. if ( *fullp == *family )
  544. {
  545. family++;
  546. fullp++;
  547. continue;
  548. }
  549. /* ignore spaces and dashes in full name during comparison */
  550. if ( *fullp == ' ' || *fullp == '-' )
  551. {
  552. fullp++;
  553. continue;
  554. }
  555. /* ignore spaces and dashes in family name during comparison */
  556. if ( *family == ' ' || *family == '-' )
  557. {
  558. family++;
  559. continue;
  560. }
  561. if ( !*family && *fullp )
  562. {
  563. /* The full name begins with the same characters as the */
  564. /* family name, with spaces and dashes removed. In this */
  565. /* case, the remaining string in `fullp' will be used as */
  566. /* the style name. */
  567. style_name = cff_strcpy( memory, fullp );
  568. }
  569. break;
  570. }
  571. if ( family_name )
  572. FT_FREE( family_name );
  573. FT_FREE( full );
  574. }
  575. }
  576. else
  577. {
  578. char *cid_font_name =
  579. cff_index_get_sid_string( &cff->string_index,
  580. dict->cid_font_name,
  581. psnames );
  582. /* do we have a `/FontName' for a CID-keyed font? */
  583. if ( cid_font_name )
  584. cffface->family_name = cid_font_name;
  585. }
  586. if ( style_name )
  587. cffface->style_name = style_name;
  588. else
  589. /* assume "Regular" style if we don't know better */
  590. cffface->style_name = cff_strcpy( memory, (char *)"Regular" );
  591. /*******************************************************************/
  592. /* */
  593. /* Compute face flags. */
  594. /* */
  595. flags = (FT_UInt32)( FT_FACE_FLAG_SCALABLE | /* scalable outlines */
  596. FT_FACE_FLAG_HORIZONTAL | /* horizontal data */
  597. FT_FACE_FLAG_HINTER ); /* has native hinter */
  598. if ( sfnt_format )
  599. flags |= (FT_UInt32)FT_FACE_FLAG_SFNT;
  600. /* fixed width font? */
  601. if ( dict->is_fixed_pitch )
  602. flags |= (FT_UInt32)FT_FACE_FLAG_FIXED_WIDTH;
  603. /* XXX: WE DO NOT SUPPORT KERNING METRICS IN THE GPOS TABLE FOR NOW */
  604. #if 0
  605. /* kerning available? */
  606. if ( face->kern_pairs )
  607. flags |= (FT_UInt32)FT_FACE_FLAG_KERNING;
  608. #endif
  609. cffface->face_flags = flags;
  610. /*******************************************************************/
  611. /* */
  612. /* Compute style flags. */
  613. /* */
  614. flags = 0;
  615. if ( dict->italic_angle )
  616. flags |= FT_STYLE_FLAG_ITALIC;
  617. {
  618. char *weight = cff_index_get_sid_string( &cff->string_index,
  619. dict->weight,
  620. psnames );
  621. if ( weight )
  622. if ( !ft_strcmp( weight, "Bold" ) ||
  623. !ft_strcmp( weight, "Black" ) )
  624. flags |= FT_STYLE_FLAG_BOLD;
  625. FT_FREE( weight );
  626. }
  627. /* double check */
  628. if ( !(flags & FT_STYLE_FLAG_BOLD) && cffface->style_name )
  629. if ( !ft_strncmp( cffface->style_name, "Bold", 4 ) ||
  630. !ft_strncmp( cffface->style_name, "Black", 5 ) )
  631. flags |= FT_STYLE_FLAG_BOLD;
  632. cffface->style_flags = flags;
  633. }
  634. #ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
  635. /* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */
  636. /* has unset this flag because of the 3.0 `post' table. */
  637. if ( dict->cid_registry == 0xFFFFU )
  638. cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;
  639. #endif
  640. if ( dict->cid_registry != 0xFFFFU && pure_cff )
  641. cffface->face_flags |= FT_FACE_FLAG_CID_KEYED;
  642. /*******************************************************************/
  643. /* */
  644. /* Compute char maps. */
  645. /* */
  646. /* Try to synthesize a Unicode charmap if there is none available */
  647. /* already. If an OpenType font contains a Unicode "cmap", we */
  648. /* will use it, whatever be in the CFF part of the file. */
  649. {
  650. FT_CharMapRec cmaprec;
  651. FT_CharMap cmap;
  652. FT_UInt nn;
  653. CFF_Encoding encoding = &cff->encoding;
  654. for ( nn = 0; nn < (FT_UInt)cffface->num_charmaps; nn++ )
  655. {
  656. cmap = cffface->charmaps[nn];
  657. /* Windows Unicode (3,1)? */
  658. if ( cmap->platform_id == 3 && cmap->encoding_id == 1 )
  659. goto Skip_Unicode;
  660. /* Deprecated Unicode platform id? */
  661. if ( cmap->platform_id == 0 )
  662. goto Skip_Unicode; /* Standard Unicode (deprecated) */
  663. }
  664. /* since CID-keyed fonts don't contain glyph names, we can't */
  665. /* construct a cmap */
  666. if ( pure_cff && cff->top_font.font_dict.cid_registry != 0xFFFFU )
  667. goto Exit;
  668. /* we didn't find a Unicode charmap -- synthesize one */
  669. cmaprec.face = cffface;
  670. cmaprec.platform_id = 3;
  671. cmaprec.encoding_id = 1;
  672. cmaprec.encoding = FT_ENCODING_UNICODE;
  673. nn = (FT_UInt)cffface->num_charmaps;
  674. FT_CMap_New( &FT_CFF_CMAP_UNICODE_CLASS_REC_GET, NULL, &cmaprec, NULL );
  675. /* if no Unicode charmap was previously selected, select this one */
  676. if ( cffface->charmap == NULL && nn != (FT_UInt)cffface->num_charmaps )
  677. cffface->charmap = cffface->charmaps[nn];
  678. Skip_Unicode:
  679. if ( encoding->count > 0 )
  680. {
  681. FT_CMap_Class clazz;
  682. cmaprec.face = cffface;
  683. cmaprec.platform_id = 7; /* Adobe platform id */
  684. if ( encoding->offset == 0 )
  685. {
  686. cmaprec.encoding_id = TT_ADOBE_ID_STANDARD;
  687. cmaprec.encoding = FT_ENCODING_ADOBE_STANDARD;
  688. clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
  689. }
  690. else if ( encoding->offset == 1 )
  691. {
  692. cmaprec.encoding_id = TT_ADOBE_ID_EXPERT;
  693. cmaprec.encoding = FT_ENCODING_ADOBE_EXPERT;
  694. clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
  695. }
  696. else
  697. {
  698. cmaprec.encoding_id = TT_ADOBE_ID_CUSTOM;
  699. cmaprec.encoding = FT_ENCODING_ADOBE_CUSTOM;
  700. clazz = &FT_CFF_CMAP_ENCODING_CLASS_REC_GET;
  701. }
  702. FT_CMap_New( clazz, NULL, &cmaprec, NULL );
  703. }
  704. }
  705. }
  706. Exit:
  707. return error;
  708. Bad_Format:
  709. error = CFF_Err_Unknown_File_Format;
  710. goto Exit;
  711. }
  712. FT_LOCAL_DEF( void )
  713. cff_face_done( FT_Face cffface ) /* CFF_Face */
  714. {
  715. CFF_Face face = (CFF_Face)cffface;
  716. FT_Memory memory;
  717. SFNT_Service sfnt;
  718. if ( !face )
  719. return;
  720. memory = cffface->memory;
  721. sfnt = (SFNT_Service)face->sfnt;
  722. if ( sfnt )
  723. sfnt->done_face( face );
  724. {
  725. CFF_Font cff = (CFF_Font)face->extra.data;
  726. if ( cff )
  727. {
  728. cff_font_done( cff );
  729. FT_FREE( face->extra.data );
  730. }
  731. }
  732. }
  733. FT_LOCAL_DEF( FT_Error )
  734. cff_driver_init( FT_Module module )
  735. {
  736. FT_UNUSED( module );
  737. return CFF_Err_Ok;
  738. }
  739. FT_LOCAL_DEF( void )
  740. cff_driver_done( FT_Module module )
  741. {
  742. FT_UNUSED( module );
  743. }
  744. /* END */