/src/freetype/src/type1/t1objs.c

https://bitbucket.org/cabalistic/ogredeps/ · C · 615 lines · 350 code · 135 blank · 130 comment · 53 complexity · faa51e64ebd85f2d73bdbbd2531bf245 MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* t1objs.c */
  4. /* */
  5. /* Type 1 objects manager (body). */
  6. /* */
  7. /* Copyright 1996-2009, 2011 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_CALC_H
  19. #include FT_INTERNAL_DEBUG_H
  20. #include FT_INTERNAL_STREAM_H
  21. #include FT_TRUETYPE_IDS_H
  22. #include "t1gload.h"
  23. #include "t1load.h"
  24. #include "t1errors.h"
  25. #ifndef T1_CONFIG_OPTION_NO_AFM
  26. #include "t1afm.h"
  27. #endif
  28. #include FT_SERVICE_POSTSCRIPT_CMAPS_H
  29. #include FT_INTERNAL_POSTSCRIPT_AUX_H
  30. /*************************************************************************/
  31. /* */
  32. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  33. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  34. /* messages during execution. */
  35. /* */
  36. #undef FT_COMPONENT
  37. #define FT_COMPONENT trace_t1objs
  38. /*************************************************************************/
  39. /* */
  40. /* SIZE FUNCTIONS */
  41. /* */
  42. /* note that we store the global hints in the size's "internal" root */
  43. /* field */
  44. /* */
  45. /*************************************************************************/
  46. static PSH_Globals_Funcs
  47. T1_Size_Get_Globals_Funcs( T1_Size size )
  48. {
  49. T1_Face face = (T1_Face)size->root.face;
  50. PSHinter_Service pshinter = (PSHinter_Service)face->pshinter;
  51. FT_Module module;
  52. module = FT_Get_Module( size->root.face->driver->root.library,
  53. "pshinter" );
  54. return ( module && pshinter && pshinter->get_globals_funcs )
  55. ? pshinter->get_globals_funcs( module )
  56. : 0 ;
  57. }
  58. FT_LOCAL_DEF( void )
  59. T1_Size_Done( FT_Size t1size ) /* T1_Size */
  60. {
  61. T1_Size size = (T1_Size)t1size;
  62. if ( size->root.internal )
  63. {
  64. PSH_Globals_Funcs funcs;
  65. funcs = T1_Size_Get_Globals_Funcs( size );
  66. if ( funcs )
  67. funcs->destroy( (PSH_Globals)size->root.internal );
  68. size->root.internal = 0;
  69. }
  70. }
  71. FT_LOCAL_DEF( FT_Error )
  72. T1_Size_Init( FT_Size t1size ) /* T1_Size */
  73. {
  74. T1_Size size = (T1_Size)t1size;
  75. FT_Error error = T1_Err_Ok;
  76. PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size );
  77. if ( funcs )
  78. {
  79. PSH_Globals globals;
  80. T1_Face face = (T1_Face)size->root.face;
  81. error = funcs->create( size->root.face->memory,
  82. &face->type1.private_dict, &globals );
  83. if ( !error )
  84. size->root.internal = (FT_Size_Internal)(void*)globals;
  85. }
  86. return error;
  87. }
  88. FT_LOCAL_DEF( FT_Error )
  89. T1_Size_Request( FT_Size t1size, /* T1_Size */
  90. FT_Size_Request req )
  91. {
  92. T1_Size size = (T1_Size)t1size;
  93. PSH_Globals_Funcs funcs = T1_Size_Get_Globals_Funcs( size );
  94. FT_Request_Metrics( size->root.face, req );
  95. if ( funcs )
  96. funcs->set_scale( (PSH_Globals)size->root.internal,
  97. size->root.metrics.x_scale,
  98. size->root.metrics.y_scale,
  99. 0, 0 );
  100. return T1_Err_Ok;
  101. }
  102. /*************************************************************************/
  103. /* */
  104. /* SLOT FUNCTIONS */
  105. /* */
  106. /*************************************************************************/
  107. FT_LOCAL_DEF( void )
  108. T1_GlyphSlot_Done( FT_GlyphSlot slot )
  109. {
  110. slot->internal->glyph_hints = 0;
  111. }
  112. FT_LOCAL_DEF( FT_Error )
  113. T1_GlyphSlot_Init( FT_GlyphSlot slot )
  114. {
  115. T1_Face face;
  116. PSHinter_Service pshinter;
  117. face = (T1_Face)slot->face;
  118. pshinter = (PSHinter_Service)face->pshinter;
  119. if ( pshinter )
  120. {
  121. FT_Module module;
  122. module = FT_Get_Module( slot->face->driver->root.library,
  123. "pshinter" );
  124. if ( module )
  125. {
  126. T1_Hints_Funcs funcs;
  127. funcs = pshinter->get_t1_funcs( module );
  128. slot->internal->glyph_hints = (void*)funcs;
  129. }
  130. }
  131. return 0;
  132. }
  133. /*************************************************************************/
  134. /* */
  135. /* FACE FUNCTIONS */
  136. /* */
  137. /*************************************************************************/
  138. /*************************************************************************/
  139. /* */
  140. /* <Function> */
  141. /* T1_Face_Done */
  142. /* */
  143. /* <Description> */
  144. /* The face object destructor. */
  145. /* */
  146. /* <Input> */
  147. /* face :: A typeless pointer to the face object to destroy. */
  148. /* */
  149. FT_LOCAL_DEF( void )
  150. T1_Face_Done( FT_Face t1face ) /* T1_Face */
  151. {
  152. T1_Face face = (T1_Face)t1face;
  153. FT_Memory memory;
  154. T1_Font type1;
  155. if ( !face )
  156. return;
  157. memory = face->root.memory;
  158. type1 = &face->type1;
  159. #ifndef T1_CONFIG_OPTION_NO_MM_SUPPORT
  160. /* release multiple masters information */
  161. FT_ASSERT( ( face->len_buildchar == 0 ) == ( face->buildchar == NULL ) );
  162. if ( face->buildchar )
  163. {
  164. FT_FREE( face->buildchar );
  165. face->buildchar = NULL;
  166. face->len_buildchar = 0;
  167. }
  168. T1_Done_Blend( face );
  169. face->blend = 0;
  170. #endif
  171. /* release font info strings */
  172. {
  173. PS_FontInfo info = &type1->font_info;
  174. FT_FREE( info->version );
  175. FT_FREE( info->notice );
  176. FT_FREE( info->full_name );
  177. FT_FREE( info->family_name );
  178. FT_FREE( info->weight );
  179. }
  180. /* release top dictionary */
  181. FT_FREE( type1->charstrings_len );
  182. FT_FREE( type1->charstrings );
  183. FT_FREE( type1->glyph_names );
  184. FT_FREE( type1->subrs );
  185. FT_FREE( type1->subrs_len );
  186. FT_FREE( type1->subrs_block );
  187. FT_FREE( type1->charstrings_block );
  188. FT_FREE( type1->glyph_names_block );
  189. FT_FREE( type1->encoding.char_index );
  190. FT_FREE( type1->encoding.char_name );
  191. FT_FREE( type1->font_name );
  192. #ifndef T1_CONFIG_OPTION_NO_AFM
  193. /* release afm data if present */
  194. if ( face->afm_data )
  195. T1_Done_Metrics( memory, (AFM_FontInfo)face->afm_data );
  196. #endif
  197. /* release unicode map, if any */
  198. #if 0
  199. FT_FREE( face->unicode_map_rec.maps );
  200. face->unicode_map_rec.num_maps = 0;
  201. face->unicode_map = NULL;
  202. #endif
  203. face->root.family_name = NULL;
  204. face->root.style_name = NULL;
  205. }
  206. /*************************************************************************/
  207. /* */
  208. /* <Function> */
  209. /* T1_Face_Init */
  210. /* */
  211. /* <Description> */
  212. /* The face object constructor. */
  213. /* */
  214. /* <Input> */
  215. /* stream :: input stream where to load font data. */
  216. /* */
  217. /* face_index :: The index of the font face in the resource. */
  218. /* */
  219. /* num_params :: Number of additional generic parameters. Ignored. */
  220. /* */
  221. /* params :: Additional generic parameters. Ignored. */
  222. /* */
  223. /* <InOut> */
  224. /* face :: The face record to build. */
  225. /* */
  226. /* <Return> */
  227. /* FreeType error code. 0 means success. */
  228. /* */
  229. FT_LOCAL_DEF( FT_Error )
  230. T1_Face_Init( FT_Stream stream,
  231. FT_Face t1face, /* T1_Face */
  232. FT_Int face_index,
  233. FT_Int num_params,
  234. FT_Parameter* params )
  235. {
  236. T1_Face face = (T1_Face)t1face;
  237. FT_Error error;
  238. FT_Service_PsCMaps psnames;
  239. PSAux_Service psaux;
  240. T1_Font type1 = &face->type1;
  241. PS_FontInfo info = &type1->font_info;
  242. FT_UNUSED( num_params );
  243. FT_UNUSED( params );
  244. FT_UNUSED( stream );
  245. face->root.num_faces = 1;
  246. FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
  247. face->psnames = psnames;
  248. face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
  249. "psaux" );
  250. psaux = (PSAux_Service)face->psaux;
  251. if ( !psaux )
  252. {
  253. FT_ERROR(( "T1_Face_Init: cannot access `psaux' module\n" ));
  254. error = T1_Err_Missing_Module;
  255. goto Exit;
  256. }
  257. face->pshinter = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
  258. "pshinter" );
  259. FT_TRACE2(( "Type 1 driver\n" ));
  260. /* open the tokenizer; this will also check the font format */
  261. error = T1_Open_Face( face );
  262. if ( error )
  263. goto Exit;
  264. /* if we just wanted to check the format, leave successfully now */
  265. if ( face_index < 0 )
  266. goto Exit;
  267. /* check the face index */
  268. if ( face_index > 0 )
  269. {
  270. FT_ERROR(( "T1_Face_Init: invalid face index\n" ));
  271. error = T1_Err_Invalid_Argument;
  272. goto Exit;
  273. }
  274. /* now load the font program into the face object */
  275. /* initialize the face object fields */
  276. /* set up root face fields */
  277. {
  278. FT_Face root = (FT_Face)&face->root;
  279. root->num_glyphs = type1->num_glyphs;
  280. root->face_index = 0;
  281. root->face_flags = FT_FACE_FLAG_SCALABLE |
  282. FT_FACE_FLAG_HORIZONTAL |
  283. FT_FACE_FLAG_GLYPH_NAMES |
  284. FT_FACE_FLAG_HINTER;
  285. if ( info->is_fixed_pitch )
  286. root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
  287. if ( face->blend )
  288. root->face_flags |= FT_FACE_FLAG_MULTIPLE_MASTERS;
  289. /* XXX: TODO -- add kerning with .afm support */
  290. /* The following code to extract the family and the style is very */
  291. /* simplistic and might get some things wrong. For a full-featured */
  292. /* algorithm you might have a look at the whitepaper given at */
  293. /* */
  294. /* http://blogs.msdn.com/text/archive/2007/04/23/wpf-font-selection-model.aspx */
  295. /* get style name -- be careful, some broken fonts only */
  296. /* have a `/FontName' dictionary entry! */
  297. root->family_name = info->family_name;
  298. root->style_name = NULL;
  299. if ( root->family_name )
  300. {
  301. char* full = info->full_name;
  302. char* family = root->family_name;
  303. if ( full )
  304. {
  305. FT_Bool the_same = TRUE;
  306. while ( *full )
  307. {
  308. if ( *full == *family )
  309. {
  310. family++;
  311. full++;
  312. }
  313. else
  314. {
  315. if ( *full == ' ' || *full == '-' )
  316. full++;
  317. else if ( *family == ' ' || *family == '-' )
  318. family++;
  319. else
  320. {
  321. the_same = FALSE;
  322. if ( !*family )
  323. root->style_name = full;
  324. break;
  325. }
  326. }
  327. }
  328. if ( the_same )
  329. root->style_name = (char *)"Regular";
  330. }
  331. }
  332. else
  333. {
  334. /* do we have a `/FontName'? */
  335. if ( type1->font_name )
  336. root->family_name = type1->font_name;
  337. }
  338. if ( !root->style_name )
  339. {
  340. if ( info->weight )
  341. root->style_name = info->weight;
  342. else
  343. /* assume `Regular' style because we don't know better */
  344. root->style_name = (char *)"Regular";
  345. }
  346. /* compute style flags */
  347. root->style_flags = 0;
  348. if ( info->italic_angle )
  349. root->style_flags |= FT_STYLE_FLAG_ITALIC;
  350. if ( info->weight )
  351. {
  352. if ( !ft_strcmp( info->weight, "Bold" ) ||
  353. !ft_strcmp( info->weight, "Black" ) )
  354. root->style_flags |= FT_STYLE_FLAG_BOLD;
  355. }
  356. /* no embedded bitmap support */
  357. root->num_fixed_sizes = 0;
  358. root->available_sizes = 0;
  359. root->bbox.xMin = type1->font_bbox.xMin >> 16;
  360. root->bbox.yMin = type1->font_bbox.yMin >> 16;
  361. /* no `U' suffix here to 0xFFFF! */
  362. root->bbox.xMax = ( type1->font_bbox.xMax + 0xFFFF ) >> 16;
  363. root->bbox.yMax = ( type1->font_bbox.yMax + 0xFFFF ) >> 16;
  364. /* Set units_per_EM if we didn't set it in t1_parse_font_matrix. */
  365. if ( !root->units_per_EM )
  366. root->units_per_EM = 1000;
  367. root->ascender = (FT_Short)( root->bbox.yMax );
  368. root->descender = (FT_Short)( root->bbox.yMin );
  369. root->height = (FT_Short)( ( root->units_per_EM * 12 ) / 10 );
  370. if ( root->height < root->ascender - root->descender )
  371. root->height = (FT_Short)( root->ascender - root->descender );
  372. /* now compute the maximum advance width */
  373. root->max_advance_width =
  374. (FT_Short)( root->bbox.xMax );
  375. {
  376. FT_Pos max_advance;
  377. error = T1_Compute_Max_Advance( face, &max_advance );
  378. /* in case of error, keep the standard width */
  379. if ( !error )
  380. root->max_advance_width = (FT_Short)FIXED_TO_INT( max_advance );
  381. else
  382. error = T1_Err_Ok; /* clear error */
  383. }
  384. root->max_advance_height = root->height;
  385. root->underline_position = (FT_Short)info->underline_position;
  386. root->underline_thickness = (FT_Short)info->underline_thickness;
  387. }
  388. {
  389. FT_Face root = &face->root;
  390. if ( psnames )
  391. {
  392. FT_CharMapRec charmap;
  393. T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes;
  394. FT_CMap_Class clazz;
  395. charmap.face = root;
  396. /* first of all, try to synthesize a Unicode charmap */
  397. charmap.platform_id = TT_PLATFORM_MICROSOFT;
  398. charmap.encoding_id = TT_MS_ID_UNICODE_CS;
  399. charmap.encoding = FT_ENCODING_UNICODE;
  400. error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL );
  401. if ( error && FT_Err_No_Unicode_Glyph_Name != error )
  402. goto Exit;
  403. error = FT_Err_Ok;
  404. /* now, generate an Adobe Standard encoding when appropriate */
  405. charmap.platform_id = TT_PLATFORM_ADOBE;
  406. clazz = NULL;
  407. switch ( type1->encoding_type )
  408. {
  409. case T1_ENCODING_TYPE_STANDARD:
  410. charmap.encoding = FT_ENCODING_ADOBE_STANDARD;
  411. charmap.encoding_id = TT_ADOBE_ID_STANDARD;
  412. clazz = cmap_classes->standard;
  413. break;
  414. case T1_ENCODING_TYPE_EXPERT:
  415. charmap.encoding = FT_ENCODING_ADOBE_EXPERT;
  416. charmap.encoding_id = TT_ADOBE_ID_EXPERT;
  417. clazz = cmap_classes->expert;
  418. break;
  419. case T1_ENCODING_TYPE_ARRAY:
  420. charmap.encoding = FT_ENCODING_ADOBE_CUSTOM;
  421. charmap.encoding_id = TT_ADOBE_ID_CUSTOM;
  422. clazz = cmap_classes->custom;
  423. break;
  424. case T1_ENCODING_TYPE_ISOLATIN1:
  425. charmap.encoding = FT_ENCODING_ADOBE_LATIN_1;
  426. charmap.encoding_id = TT_ADOBE_ID_LATIN_1;
  427. clazz = cmap_classes->unicode;
  428. break;
  429. default:
  430. ;
  431. }
  432. if ( clazz )
  433. error = FT_CMap_New( clazz, NULL, &charmap, NULL );
  434. #if 0
  435. /* Select default charmap */
  436. if (root->num_charmaps)
  437. root->charmap = root->charmaps[0];
  438. #endif
  439. }
  440. }
  441. Exit:
  442. return error;
  443. }
  444. /*************************************************************************/
  445. /* */
  446. /* <Function> */
  447. /* T1_Driver_Init */
  448. /* */
  449. /* <Description> */
  450. /* Initializes a given Type 1 driver object. */
  451. /* */
  452. /* <Input> */
  453. /* driver :: A handle to the target driver object. */
  454. /* */
  455. /* <Return> */
  456. /* FreeType error code. 0 means success. */
  457. /* */
  458. FT_LOCAL_DEF( FT_Error )
  459. T1_Driver_Init( FT_Module driver )
  460. {
  461. FT_UNUSED( driver );
  462. return T1_Err_Ok;
  463. }
  464. /*************************************************************************/
  465. /* */
  466. /* <Function> */
  467. /* T1_Driver_Done */
  468. /* */
  469. /* <Description> */
  470. /* Finalizes a given Type 1 driver. */
  471. /* */
  472. /* <Input> */
  473. /* driver :: A handle to the target Type 1 driver. */
  474. /* */
  475. FT_LOCAL_DEF( void )
  476. T1_Driver_Done( FT_Module driver )
  477. {
  478. FT_UNUSED( driver );
  479. }
  480. /* END */