t1gload.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /***************************************************************************/
  2. /* */
  3. /* t1gload.c */
  4. /* */
  5. /* Type 1 Glyph Loader (body). */
  6. /* */
  7. /* Copyright 1996-2001, 2002 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 "t1gload.h"
  19. #include FT_INTERNAL_DEBUG_H
  20. #include FT_INTERNAL_STREAM_H
  21. #include FT_OUTLINE_H
  22. #include FT_INTERNAL_POSTSCRIPT_AUX_H
  23. #include "t1errors.h"
  24. /*************************************************************************/
  25. /* */
  26. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  27. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  28. /* messages during execution. */
  29. /* */
  30. #undef FT_COMPONENT
  31. #define FT_COMPONENT trace_t1gload
  32. /*************************************************************************/
  33. /*************************************************************************/
  34. /*************************************************************************/
  35. /********** *********/
  36. /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
  37. /********** *********/
  38. /********** The following code is in charge of computing *********/
  39. /********** the maximum advance width of the font. It *********/
  40. /********** quickly processes each glyph charstring to *********/
  41. /********** extract the value from either a `sbw' or `seac' *********/
  42. /********** operator. *********/
  43. /********** *********/
  44. /*************************************************************************/
  45. /*************************************************************************/
  46. /*************************************************************************/
  47. FT_LOCAL_DEF( FT_Error )
  48. T1_Parse_Glyph_And_Get_Char_String( T1_Decoder decoder,
  49. FT_UInt glyph_index,
  50. FT_Data* char_string )
  51. {
  52. T1_Face face = (T1_Face)decoder->builder.face;
  53. T1_Font type1 = &face->type1;
  54. FT_Error error = 0;
  55. decoder->font_matrix = type1->font_matrix;
  56. decoder->font_offset = type1->font_offset;
  57. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  58. /* For incremental fonts get the character data using the */
  59. /* callback function. */
  60. if ( face->root.internal->incremental_interface )
  61. error = face->root.internal->incremental_interface->funcs->get_glyph_data(
  62. face->root.internal->incremental_interface->object,
  63. glyph_index, char_string );
  64. else
  65. #endif
  66. /* For ordinary fonts get the character data stored in the face record. */
  67. {
  68. char_string->pointer = type1->charstrings[glyph_index];
  69. char_string->length = type1->charstrings_len[glyph_index];
  70. }
  71. if ( !error )
  72. error = decoder->funcs.parse_charstrings(
  73. decoder, (FT_Byte*)char_string->pointer,
  74. char_string->length );
  75. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  76. /* Incremental fonts can optionally override the metrics. */
  77. if ( !error && face->root.internal->incremental_interface &&
  78. face->root.internal->incremental_interface->funcs->get_glyph_metrics )
  79. {
  80. FT_Bool found = FALSE;
  81. FT_Incremental_MetricsRec metrics;
  82. error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
  83. face->root.internal->incremental_interface->object,
  84. glyph_index, FALSE, &metrics, &found );
  85. if ( found )
  86. {
  87. decoder->builder.left_bearing.x = metrics.bearing_x;
  88. decoder->builder.left_bearing.y = metrics.bearing_y;
  89. decoder->builder.advance.x = metrics.advance;
  90. decoder->builder.advance.y = 0;
  91. }
  92. }
  93. #endif
  94. return error;
  95. }
  96. FT_CALLBACK_DEF( FT_Error )
  97. T1_Parse_Glyph( T1_Decoder decoder,
  98. FT_UInt glyph_index )
  99. {
  100. FT_Data glyph_data;
  101. FT_Error error = T1_Parse_Glyph_And_Get_Char_String(
  102. decoder, glyph_index, &glyph_data );
  103. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  104. if ( !error )
  105. {
  106. T1_Face face = (T1_Face)decoder->builder.face;
  107. if ( face->root.internal->incremental_interface )
  108. face->root.internal->incremental_interface->funcs->free_glyph_data(
  109. face->root.internal->incremental_interface->object,
  110. &glyph_data );
  111. }
  112. #endif
  113. return error;
  114. }
  115. FT_LOCAL_DEF( FT_Error )
  116. T1_Compute_Max_Advance( T1_Face face,
  117. FT_Int* max_advance )
  118. {
  119. FT_Error error;
  120. T1_DecoderRec decoder;
  121. FT_Int glyph_index;
  122. T1_Font type1 = &face->type1;
  123. PSAux_Service psaux = (PSAux_Service)face->psaux;
  124. *max_advance = 0;
  125. /* initialize load decoder */
  126. error = psaux->t1_decoder_funcs->init( &decoder,
  127. (FT_Face)face,
  128. 0, /* size */
  129. 0, /* glyph slot */
  130. (FT_Byte**)type1->glyph_names,
  131. face->blend,
  132. 0,
  133. FT_RENDER_MODE_NORMAL,
  134. T1_Parse_Glyph );
  135. if ( error )
  136. return error;
  137. decoder.builder.metrics_only = 1;
  138. decoder.builder.load_points = 0;
  139. decoder.num_subrs = type1->num_subrs;
  140. decoder.subrs = type1->subrs;
  141. decoder.subrs_len = type1->subrs_len;
  142. *max_advance = 0;
  143. /* for each glyph, parse the glyph charstring and extract */
  144. /* the advance width */
  145. for ( glyph_index = 0; glyph_index < type1->num_glyphs; glyph_index++ )
  146. {
  147. /* now get load the unscaled outline */
  148. error = T1_Parse_Glyph( &decoder, glyph_index );
  149. if ( glyph_index == 0 || decoder.builder.advance.x > *max_advance )
  150. *max_advance = decoder.builder.advance.x;
  151. /* ignore the error if one occured - skip to next glyph */
  152. }
  153. return T1_Err_Ok;
  154. }
  155. /*************************************************************************/
  156. /*************************************************************************/
  157. /*************************************************************************/
  158. /********** *********/
  159. /********** UNHINTED GLYPH LOADER *********/
  160. /********** *********/
  161. /********** The following code is in charge of loading a *********/
  162. /********** single outline. It completely ignores hinting *********/
  163. /********** and is used when FT_LOAD_NO_HINTING is set. *********/
  164. /********** *********/
  165. /********** The Type 1 hinter is located in `t1hint.c' *********/
  166. /********** *********/
  167. /*************************************************************************/
  168. /*************************************************************************/
  169. /*************************************************************************/
  170. FT_LOCAL_DEF( FT_Error )
  171. T1_Load_Glyph( T1_GlyphSlot glyph,
  172. T1_Size size,
  173. FT_UInt glyph_index,
  174. FT_Int32 load_flags )
  175. {
  176. FT_Error error;
  177. T1_DecoderRec decoder;
  178. T1_Face face = (T1_Face)glyph->root.face;
  179. FT_Bool hinting;
  180. T1_Font type1 = &face->type1;
  181. PSAux_Service psaux = (PSAux_Service)face->psaux;
  182. const T1_Decoder_Funcs decoder_funcs = psaux->t1_decoder_funcs;
  183. FT_Matrix font_matrix;
  184. FT_Vector font_offset;
  185. FT_Data glyph_data;
  186. FT_Bool glyph_data_loaded = 0;
  187. if ( load_flags & FT_LOAD_NO_RECURSE )
  188. load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
  189. glyph->x_scale = size->root.metrics.x_scale;
  190. glyph->y_scale = size->root.metrics.y_scale;
  191. glyph->root.outline.n_points = 0;
  192. glyph->root.outline.n_contours = 0;
  193. hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 &&
  194. ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
  195. glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
  196. error = decoder_funcs->init( &decoder,
  197. (FT_Face)face,
  198. (FT_Size)size,
  199. (FT_GlyphSlot)glyph,
  200. (FT_Byte**)type1->glyph_names,
  201. face->blend,
  202. FT_BOOL( hinting ),
  203. FT_LOAD_TARGET_MODE(load_flags),
  204. T1_Parse_Glyph );
  205. if ( error )
  206. goto Exit;
  207. decoder.builder.no_recurse = FT_BOOL(
  208. ( load_flags & FT_LOAD_NO_RECURSE ) != 0 );
  209. decoder.num_subrs = type1->num_subrs;
  210. decoder.subrs = type1->subrs;
  211. decoder.subrs_len = type1->subrs_len;
  212. /* now load the unscaled outline */
  213. error = T1_Parse_Glyph_And_Get_Char_String( &decoder, glyph_index,
  214. &glyph_data );
  215. if ( error )
  216. goto Exit;
  217. glyph_data_loaded = 1;
  218. font_matrix = decoder.font_matrix;
  219. font_offset = decoder.font_offset;
  220. /* save new glyph tables */
  221. decoder_funcs->done( &decoder );
  222. /* now, set the metrics -- this is rather simple, as */
  223. /* the left side bearing is the xMin, and the top side */
  224. /* bearing the yMax */
  225. if ( !error )
  226. {
  227. glyph->root.outline.flags &= FT_OUTLINE_OWNER;
  228. glyph->root.outline.flags |= FT_OUTLINE_REVERSE_FILL;
  229. /* for composite glyphs, return only left side bearing and */
  230. /* advance width */
  231. if ( load_flags & FT_LOAD_NO_RECURSE )
  232. {
  233. FT_Slot_Internal internal = glyph->root.internal;
  234. glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x;
  235. glyph->root.metrics.horiAdvance = decoder.builder.advance.x;
  236. internal->glyph_matrix = font_matrix;
  237. internal->glyph_delta = font_offset;
  238. internal->glyph_transformed = 1;
  239. }
  240. else
  241. {
  242. FT_BBox cbox;
  243. FT_Glyph_Metrics* metrics = &glyph->root.metrics;
  244. /* copy the _unscaled_ advance width */
  245. metrics->horiAdvance = decoder.builder.advance.x;
  246. glyph->root.linearHoriAdvance = decoder.builder.advance.x;
  247. glyph->root.internal->glyph_transformed = 0;
  248. /* make up vertical metrics */
  249. metrics->vertBearingX = 0;
  250. metrics->vertBearingY = 0;
  251. metrics->vertAdvance = 0;
  252. glyph->root.linearVertAdvance = 0;
  253. glyph->root.format = FT_GLYPH_FORMAT_OUTLINE;
  254. if ( size && size->root.metrics.y_ppem < 24 )
  255. glyph->root.outline.flags |= FT_OUTLINE_HIGH_PRECISION;
  256. #if 1
  257. /* apply the font matrix, if any */
  258. FT_Outline_Transform( &glyph->root.outline, &font_matrix );
  259. FT_Outline_Translate( &glyph->root.outline,
  260. font_offset.x,
  261. font_offset.y );
  262. #endif
  263. if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 )
  264. {
  265. /* scale the outline and the metrics */
  266. FT_Int n;
  267. FT_Outline* cur = decoder.builder.base;
  268. FT_Vector* vec = cur->points;
  269. FT_Fixed x_scale = glyph->x_scale;
  270. FT_Fixed y_scale = glyph->y_scale;
  271. /* First of all, scale the points, if we are not hinting */
  272. if ( !hinting )
  273. for ( n = cur->n_points; n > 0; n--, vec++ )
  274. {
  275. vec->x = FT_MulFix( vec->x, x_scale );
  276. vec->y = FT_MulFix( vec->y, y_scale );
  277. }
  278. FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
  279. /* Then scale the metrics */
  280. metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
  281. metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
  282. metrics->vertBearingX = FT_MulFix( metrics->vertBearingX, x_scale );
  283. metrics->vertBearingY = FT_MulFix( metrics->vertBearingY, y_scale );
  284. if ( hinting )
  285. {
  286. metrics->horiAdvance = ( metrics->horiAdvance + 32 ) & -64;
  287. metrics->vertAdvance = ( metrics->vertAdvance + 32 ) & -64;
  288. metrics->vertBearingX = ( metrics->vertBearingX + 32 ) & -64;
  289. metrics->vertBearingY = ( metrics->vertBearingY + 32 ) & -64;
  290. }
  291. }
  292. /* compute the other metrics */
  293. FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
  294. /* grid fit the bounding box if necessary */
  295. if ( hinting )
  296. {
  297. cbox.xMin &= -64;
  298. cbox.yMin &= -64;
  299. cbox.xMax = ( cbox.xMax+63 ) & -64;
  300. cbox.yMax = ( cbox.yMax+63 ) & -64;
  301. }
  302. metrics->width = cbox.xMax - cbox.xMin;
  303. metrics->height = cbox.yMax - cbox.yMin;
  304. metrics->horiBearingX = cbox.xMin;
  305. metrics->horiBearingY = cbox.yMax;
  306. }
  307. /* Set control data to the glyph charstrings. Note that this is */
  308. /* _not_ zero-terminated. */
  309. glyph->root.control_data = (FT_Byte*)glyph_data.pointer;
  310. glyph->root.control_len = glyph_data.length;
  311. }
  312. Exit:
  313. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  314. if ( glyph_data_loaded && face->root.internal->incremental_interface )
  315. {
  316. face->root.internal->incremental_interface->funcs->free_glyph_data(
  317. face->root.internal->incremental_interface->object,
  318. &glyph_data );
  319. /* Set the control data to null - it is no longer available if */
  320. /* loaded incrementally. */
  321. glyph->root.control_data = 0;
  322. glyph->root.control_len = 0;
  323. }
  324. #endif
  325. return error;
  326. }
  327. /* END */