/modules/freetype2/src/type42/t42objs.c

http://github.com/zpao/v8monkey · C · 652 lines · 432 code · 146 blank · 74 comment · 59 complexity · 04c7ce75c6e172df003a4fd881d36771 MD5 · raw file

  1. /***************************************************************************/
  2. /* */
  3. /* t42objs.c */
  4. /* */
  5. /* Type 42 objects manager (body). */
  6. /* */
  7. /* Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 */
  8. /* by Roberto Alameda. */
  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 "t42objs.h"
  18. #include "t42parse.h"
  19. #include "t42error.h"
  20. #include FT_INTERNAL_DEBUG_H
  21. #include FT_LIST_H
  22. #include FT_TRUETYPE_IDS_H
  23. #undef FT_COMPONENT
  24. #define FT_COMPONENT trace_t42
  25. static FT_Error
  26. T42_Open_Face( T42_Face face )
  27. {
  28. T42_LoaderRec loader;
  29. T42_Parser parser;
  30. T1_Font type1 = &face->type1;
  31. FT_Memory memory = face->root.memory;
  32. FT_Error error;
  33. PSAux_Service psaux = (PSAux_Service)face->psaux;
  34. t42_loader_init( &loader, face );
  35. parser = &loader.parser;
  36. if ( FT_ALLOC( face->ttf_data, 12 ) )
  37. goto Exit;
  38. error = t42_parser_init( parser,
  39. face->root.stream,
  40. memory,
  41. psaux);
  42. if ( error )
  43. goto Exit;
  44. error = t42_parse_dict( face, &loader,
  45. parser->base_dict, parser->base_len );
  46. if ( error )
  47. goto Exit;
  48. if ( type1->font_type != 42 )
  49. {
  50. error = T42_Err_Unknown_File_Format;
  51. goto Exit;
  52. }
  53. /* now, propagate the charstrings and glyphnames tables */
  54. /* to the Type1 data */
  55. type1->num_glyphs = loader.num_glyphs;
  56. if ( !loader.charstrings.init )
  57. {
  58. FT_ERROR(( "T42_Open_Face: no charstrings array in face\n" ));
  59. error = T42_Err_Invalid_File_Format;
  60. }
  61. loader.charstrings.init = 0;
  62. type1->charstrings_block = loader.charstrings.block;
  63. type1->charstrings = loader.charstrings.elements;
  64. type1->charstrings_len = loader.charstrings.lengths;
  65. /* we copy the glyph names `block' and `elements' fields; */
  66. /* the `lengths' field must be released later */
  67. type1->glyph_names_block = loader.glyph_names.block;
  68. type1->glyph_names = (FT_String**)loader.glyph_names.elements;
  69. loader.glyph_names.block = 0;
  70. loader.glyph_names.elements = 0;
  71. /* we must now build type1.encoding when we have a custom array */
  72. if ( type1->encoding_type == T1_ENCODING_TYPE_ARRAY )
  73. {
  74. FT_Int charcode, idx, min_char, max_char;
  75. FT_Byte* char_name;
  76. FT_Byte* glyph_name;
  77. /* OK, we do the following: for each element in the encoding */
  78. /* table, look up the index of the glyph having the same name */
  79. /* as defined in the CharStrings array. */
  80. /* The index is then stored in type1.encoding.char_index, and */
  81. /* the name in type1.encoding.char_name */
  82. min_char = 0;
  83. max_char = 0;
  84. charcode = 0;
  85. for ( ; charcode < loader.encoding_table.max_elems; charcode++ )
  86. {
  87. type1->encoding.char_index[charcode] = 0;
  88. type1->encoding.char_name [charcode] = (char *)".notdef";
  89. char_name = loader.encoding_table.elements[charcode];
  90. if ( char_name )
  91. for ( idx = 0; idx < type1->num_glyphs; idx++ )
  92. {
  93. glyph_name = (FT_Byte*)type1->glyph_names[idx];
  94. if ( ft_strcmp( (const char*)char_name,
  95. (const char*)glyph_name ) == 0 )
  96. {
  97. type1->encoding.char_index[charcode] = (FT_UShort)idx;
  98. type1->encoding.char_name [charcode] = (char*)glyph_name;
  99. /* Change min/max encoded char only if glyph name is */
  100. /* not /.notdef */
  101. if ( ft_strcmp( (const char*)".notdef",
  102. (const char*)glyph_name ) != 0 )
  103. {
  104. if ( charcode < min_char )
  105. min_char = charcode;
  106. if ( charcode >= max_char )
  107. max_char = charcode + 1;
  108. }
  109. break;
  110. }
  111. }
  112. }
  113. type1->encoding.code_first = min_char;
  114. type1->encoding.code_last = max_char;
  115. type1->encoding.num_chars = loader.num_chars;
  116. }
  117. Exit:
  118. t42_loader_done( &loader );
  119. return error;
  120. }
  121. /***************** Driver Functions *************/
  122. FT_LOCAL_DEF( FT_Error )
  123. T42_Face_Init( FT_Stream stream,
  124. T42_Face face,
  125. FT_Int face_index,
  126. FT_Int num_params,
  127. FT_Parameter* params )
  128. {
  129. FT_Error error;
  130. FT_Service_PsCMaps psnames;
  131. PSAux_Service psaux;
  132. FT_Face root = (FT_Face)&face->root;
  133. T1_Font type1 = &face->type1;
  134. PS_FontInfo info = &type1->font_info;
  135. FT_UNUSED( num_params );
  136. FT_UNUSED( params );
  137. FT_UNUSED( face_index );
  138. FT_UNUSED( stream );
  139. face->ttf_face = NULL;
  140. face->root.num_faces = 1;
  141. FT_FACE_FIND_GLOBAL_SERVICE( face, psnames, POSTSCRIPT_CMAPS );
  142. face->psnames = psnames;
  143. face->psaux = FT_Get_Module_Interface( FT_FACE_LIBRARY( face ),
  144. "psaux" );
  145. psaux = (PSAux_Service)face->psaux;
  146. /* open the tokenizer, this will also check the font format */
  147. error = T42_Open_Face( face );
  148. if ( error )
  149. goto Exit;
  150. /* if we just wanted to check the format, leave successfully now */
  151. if ( face_index < 0 )
  152. goto Exit;
  153. /* check the face index */
  154. if ( face_index > 0 )
  155. {
  156. FT_ERROR(( "T42_Face_Init: invalid face index\n" ));
  157. error = T42_Err_Invalid_Argument;
  158. goto Exit;
  159. }
  160. /* Now load the font program into the face object */
  161. /* Init the face object fields */
  162. /* Now set up root face fields */
  163. root->num_glyphs = type1->num_glyphs;
  164. root->num_charmaps = 0;
  165. root->face_index = 0;
  166. root->face_flags = FT_FACE_FLAG_SCALABLE |
  167. FT_FACE_FLAG_HORIZONTAL |
  168. FT_FACE_FLAG_GLYPH_NAMES;
  169. if ( info->is_fixed_pitch )
  170. root->face_flags |= FT_FACE_FLAG_FIXED_WIDTH;
  171. /* We only set this flag if we have the patented bytecode interpreter. */
  172. /* There are no known `tricky' Type42 fonts that could be loaded with */
  173. /* the unpatented interpreter. */
  174. #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
  175. root->face_flags |= FT_FACE_FLAG_HINTER;
  176. #endif
  177. /* XXX: TODO -- add kerning with .afm support */
  178. /* get style name -- be careful, some broken fonts only */
  179. /* have a `/FontName' dictionary entry! */
  180. root->family_name = info->family_name;
  181. /* assume "Regular" style if we don't know better */
  182. root->style_name = (char *)"Regular";
  183. if ( root->family_name )
  184. {
  185. char* full = info->full_name;
  186. char* family = root->family_name;
  187. if ( full )
  188. {
  189. while ( *full )
  190. {
  191. if ( *full == *family )
  192. {
  193. family++;
  194. full++;
  195. }
  196. else
  197. {
  198. if ( *full == ' ' || *full == '-' )
  199. full++;
  200. else if ( *family == ' ' || *family == '-' )
  201. family++;
  202. else
  203. {
  204. if ( !*family )
  205. root->style_name = full;
  206. break;
  207. }
  208. }
  209. }
  210. }
  211. }
  212. else
  213. {
  214. /* do we have a `/FontName'? */
  215. if ( type1->font_name )
  216. root->family_name = type1->font_name;
  217. }
  218. /* no embedded bitmap support */
  219. root->num_fixed_sizes = 0;
  220. root->available_sizes = 0;
  221. /* Load the TTF font embedded in the T42 font */
  222. {
  223. FT_Open_Args args;
  224. args.flags = FT_OPEN_MEMORY;
  225. args.memory_base = face->ttf_data;
  226. args.memory_size = face->ttf_size;
  227. if ( num_params )
  228. {
  229. args.flags |= FT_OPEN_PARAMS;
  230. args.num_params = num_params;
  231. args.params = params;
  232. }
  233. error = FT_Open_Face( FT_FACE_LIBRARY( face ),
  234. &args, 0, &face->ttf_face );
  235. }
  236. if ( error )
  237. goto Exit;
  238. FT_Done_Size( face->ttf_face->size );
  239. /* Ignore info in FontInfo dictionary and use the info from the */
  240. /* loaded TTF font. The PostScript interpreter also ignores it. */
  241. root->bbox = face->ttf_face->bbox;
  242. root->units_per_EM = face->ttf_face->units_per_EM;
  243. root->ascender = face->ttf_face->ascender;
  244. root->descender = face->ttf_face->descender;
  245. root->height = face->ttf_face->height;
  246. root->max_advance_width = face->ttf_face->max_advance_width;
  247. root->max_advance_height = face->ttf_face->max_advance_height;
  248. root->underline_position = (FT_Short)info->underline_position;
  249. root->underline_thickness = (FT_Short)info->underline_thickness;
  250. /* compute style flags */
  251. root->style_flags = 0;
  252. if ( info->italic_angle )
  253. root->style_flags |= FT_STYLE_FLAG_ITALIC;
  254. if ( face->ttf_face->style_flags & FT_STYLE_FLAG_BOLD )
  255. root->style_flags |= FT_STYLE_FLAG_BOLD;
  256. if ( face->ttf_face->face_flags & FT_FACE_FLAG_VERTICAL )
  257. root->face_flags |= FT_FACE_FLAG_VERTICAL;
  258. {
  259. if ( psnames && psaux )
  260. {
  261. FT_CharMapRec charmap;
  262. T1_CMap_Classes cmap_classes = psaux->t1_cmap_classes;
  263. FT_CMap_Class clazz;
  264. charmap.face = root;
  265. /* first of all, try to synthesize a Unicode charmap */
  266. charmap.platform_id = TT_PLATFORM_MICROSOFT;
  267. charmap.encoding_id = TT_MS_ID_UNICODE_CS;
  268. charmap.encoding = FT_ENCODING_UNICODE;
  269. error = FT_CMap_New( cmap_classes->unicode, NULL, &charmap, NULL );
  270. if ( error && FT_Err_No_Unicode_Glyph_Name != error )
  271. goto Exit;
  272. error = FT_Err_Ok;
  273. /* now, generate an Adobe Standard encoding when appropriate */
  274. charmap.platform_id = TT_PLATFORM_ADOBE;
  275. clazz = NULL;
  276. switch ( type1->encoding_type )
  277. {
  278. case T1_ENCODING_TYPE_STANDARD:
  279. charmap.encoding = FT_ENCODING_ADOBE_STANDARD;
  280. charmap.encoding_id = TT_ADOBE_ID_STANDARD;
  281. clazz = cmap_classes->standard;
  282. break;
  283. case T1_ENCODING_TYPE_EXPERT:
  284. charmap.encoding = FT_ENCODING_ADOBE_EXPERT;
  285. charmap.encoding_id = TT_ADOBE_ID_EXPERT;
  286. clazz = cmap_classes->expert;
  287. break;
  288. case T1_ENCODING_TYPE_ARRAY:
  289. charmap.encoding = FT_ENCODING_ADOBE_CUSTOM;
  290. charmap.encoding_id = TT_ADOBE_ID_CUSTOM;
  291. clazz = cmap_classes->custom;
  292. break;
  293. case T1_ENCODING_TYPE_ISOLATIN1:
  294. charmap.encoding = FT_ENCODING_ADOBE_LATIN_1;
  295. charmap.encoding_id = TT_ADOBE_ID_LATIN_1;
  296. clazz = cmap_classes->unicode;
  297. break;
  298. default:
  299. ;
  300. }
  301. if ( clazz )
  302. error = FT_CMap_New( clazz, NULL, &charmap, NULL );
  303. #if 0
  304. /* Select default charmap */
  305. if ( root->num_charmaps )
  306. root->charmap = root->charmaps[0];
  307. #endif
  308. }
  309. }
  310. Exit:
  311. return error;
  312. }
  313. FT_LOCAL_DEF( void )
  314. T42_Face_Done( T42_Face face )
  315. {
  316. T1_Font type1;
  317. PS_FontInfo info;
  318. FT_Memory memory;
  319. if ( !face )
  320. return;
  321. type1 = &face->type1;
  322. info = &type1->font_info;
  323. memory = face->root.memory;
  324. /* delete internal ttf face prior to freeing face->ttf_data */
  325. if ( face->ttf_face )
  326. FT_Done_Face( face->ttf_face );
  327. /* release font info strings */
  328. FT_FREE( info->version );
  329. FT_FREE( info->notice );
  330. FT_FREE( info->full_name );
  331. FT_FREE( info->family_name );
  332. FT_FREE( info->weight );
  333. /* release top dictionary */
  334. FT_FREE( type1->charstrings_len );
  335. FT_FREE( type1->charstrings );
  336. FT_FREE( type1->glyph_names );
  337. FT_FREE( type1->charstrings_block );
  338. FT_FREE( type1->glyph_names_block );
  339. FT_FREE( type1->encoding.char_index );
  340. FT_FREE( type1->encoding.char_name );
  341. FT_FREE( type1->font_name );
  342. FT_FREE( face->ttf_data );
  343. #if 0
  344. /* release afm data if present */
  345. if ( face->afm_data )
  346. T1_Done_AFM( memory, (T1_AFM*)face->afm_data );
  347. #endif
  348. /* release unicode map, if any */
  349. FT_FREE( face->unicode_map.maps );
  350. face->unicode_map.num_maps = 0;
  351. face->root.family_name = 0;
  352. face->root.style_name = 0;
  353. }
  354. /*************************************************************************/
  355. /* */
  356. /* <Function> */
  357. /* T42_Driver_Init */
  358. /* */
  359. /* <Description> */
  360. /* Initializes a given Type 42 driver object. */
  361. /* */
  362. /* <Input> */
  363. /* driver :: A handle to the target driver object. */
  364. /* */
  365. /* <Return> */
  366. /* FreeType error code. 0 means success. */
  367. /* */
  368. FT_LOCAL_DEF( FT_Error )
  369. T42_Driver_Init( T42_Driver driver )
  370. {
  371. FT_Module ttmodule;
  372. ttmodule = FT_Get_Module( FT_MODULE(driver)->library, "truetype" );
  373. driver->ttclazz = (FT_Driver_Class)ttmodule->clazz;
  374. return T42_Err_Ok;
  375. }
  376. FT_LOCAL_DEF( void )
  377. T42_Driver_Done( T42_Driver driver )
  378. {
  379. FT_UNUSED( driver );
  380. }
  381. FT_LOCAL_DEF( FT_Error )
  382. T42_Size_Init( T42_Size size )
  383. {
  384. FT_Face face = size->root.face;
  385. T42_Face t42face = (T42_Face)face;
  386. FT_Size ttsize;
  387. FT_Error error = T42_Err_Ok;
  388. error = FT_New_Size( t42face->ttf_face, &ttsize );
  389. size->ttsize = ttsize;
  390. FT_Activate_Size( ttsize );
  391. return error;
  392. }
  393. FT_LOCAL_DEF( FT_Error )
  394. T42_Size_Request( T42_Size size,
  395. FT_Size_Request req )
  396. {
  397. T42_Face face = (T42_Face)size->root.face;
  398. FT_Error error;
  399. FT_Activate_Size( size->ttsize );
  400. error = FT_Request_Size( face->ttf_face, req );
  401. if ( !error )
  402. ( (FT_Size)size )->metrics = face->ttf_face->size->metrics;
  403. return error;
  404. }
  405. FT_LOCAL_DEF( FT_Error )
  406. T42_Size_Select( T42_Size size,
  407. FT_ULong strike_index )
  408. {
  409. T42_Face face = (T42_Face)size->root.face;
  410. FT_Error error;
  411. FT_Activate_Size( size->ttsize );
  412. error = FT_Select_Size( face->ttf_face, (FT_Int)strike_index );
  413. if ( !error )
  414. ( (FT_Size)size )->metrics = face->ttf_face->size->metrics;
  415. return error;
  416. }
  417. FT_LOCAL_DEF( void )
  418. T42_Size_Done( T42_Size size )
  419. {
  420. FT_Face face = size->root.face;
  421. T42_Face t42face = (T42_Face)face;
  422. FT_ListNode node;
  423. node = FT_List_Find( &t42face->ttf_face->sizes_list, size->ttsize );
  424. if ( node )
  425. {
  426. FT_Done_Size( size->ttsize );
  427. size->ttsize = NULL;
  428. }
  429. }
  430. FT_LOCAL_DEF( FT_Error )
  431. T42_GlyphSlot_Init( T42_GlyphSlot slot )
  432. {
  433. FT_Face face = slot->root.face;
  434. T42_Face t42face = (T42_Face)face;
  435. FT_GlyphSlot ttslot;
  436. FT_Error error = T42_Err_Ok;
  437. if ( face->glyph == NULL )
  438. {
  439. /* First glyph slot for this face */
  440. slot->ttslot = t42face->ttf_face->glyph;
  441. }
  442. else
  443. {
  444. error = FT_New_GlyphSlot( t42face->ttf_face, &ttslot );
  445. slot->ttslot = ttslot;
  446. }
  447. return error;
  448. }
  449. FT_LOCAL_DEF( void )
  450. T42_GlyphSlot_Done( T42_GlyphSlot slot )
  451. {
  452. FT_Done_GlyphSlot( slot->ttslot );
  453. }
  454. static void
  455. t42_glyphslot_clear( FT_GlyphSlot slot )
  456. {
  457. /* free bitmap if needed */
  458. ft_glyphslot_free_bitmap( slot );
  459. /* clear all public fields in the glyph slot */
  460. FT_ZERO( &slot->metrics );
  461. FT_ZERO( &slot->outline );
  462. FT_ZERO( &slot->bitmap );
  463. slot->bitmap_left = 0;
  464. slot->bitmap_top = 0;
  465. slot->num_subglyphs = 0;
  466. slot->subglyphs = 0;
  467. slot->control_data = 0;
  468. slot->control_len = 0;
  469. slot->other = 0;
  470. slot->format = FT_GLYPH_FORMAT_NONE;
  471. slot->linearHoriAdvance = 0;
  472. slot->linearVertAdvance = 0;
  473. }
  474. FT_LOCAL_DEF( FT_Error )
  475. T42_GlyphSlot_Load( FT_GlyphSlot glyph,
  476. FT_Size size,
  477. FT_UInt glyph_index,
  478. FT_Int32 load_flags )
  479. {
  480. FT_Error error;
  481. T42_GlyphSlot t42slot = (T42_GlyphSlot)glyph;
  482. T42_Size t42size = (T42_Size)size;
  483. FT_Driver_Class ttclazz = ((T42_Driver)glyph->face->driver)->ttclazz;
  484. t42_glyphslot_clear( t42slot->ttslot );
  485. error = ttclazz->load_glyph( t42slot->ttslot,
  486. t42size->ttsize,
  487. glyph_index,
  488. load_flags | FT_LOAD_NO_BITMAP );
  489. if ( !error )
  490. {
  491. glyph->metrics = t42slot->ttslot->metrics;
  492. glyph->linearHoriAdvance = t42slot->ttslot->linearHoriAdvance;
  493. glyph->linearVertAdvance = t42slot->ttslot->linearVertAdvance;
  494. glyph->format = t42slot->ttslot->format;
  495. glyph->outline = t42slot->ttslot->outline;
  496. glyph->bitmap = t42slot->ttslot->bitmap;
  497. glyph->bitmap_left = t42slot->ttslot->bitmap_left;
  498. glyph->bitmap_top = t42slot->ttslot->bitmap_top;
  499. glyph->num_subglyphs = t42slot->ttslot->num_subglyphs;
  500. glyph->subglyphs = t42slot->ttslot->subglyphs;
  501. glyph->control_data = t42slot->ttslot->control_data;
  502. glyph->control_len = t42slot->ttslot->control_len;
  503. }
  504. return error;
  505. }
  506. /* END */