ttgload.c 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783
  1. /***************************************************************************/
  2. /* */
  3. /* ttgload.c */
  4. /* */
  5. /* TrueType 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 FT_INTERNAL_DEBUG_H
  19. #include FT_INTERNAL_CALC_H
  20. #include FT_INTERNAL_STREAM_H
  21. #include FT_INTERNAL_SFNT_H
  22. #include FT_TRUETYPE_TAGS_H
  23. #include FT_OUTLINE_H
  24. #include "ttgload.h"
  25. #include "tterrors.h"
  26. /*************************************************************************/
  27. /* */
  28. /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
  29. /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
  30. /* messages during execution. */
  31. /* */
  32. #undef FT_COMPONENT
  33. #define FT_COMPONENT trace_ttgload
  34. /*************************************************************************/
  35. /* */
  36. /* Composite font flags. */
  37. /* */
  38. #define ARGS_ARE_WORDS 0x0001
  39. #define ARGS_ARE_XY_VALUES 0x0002
  40. #define ROUND_XY_TO_GRID 0x0004
  41. #define WE_HAVE_A_SCALE 0x0008
  42. /* reserved 0x0010 */
  43. #define MORE_COMPONENTS 0x0020
  44. #define WE_HAVE_AN_XY_SCALE 0x0040
  45. #define WE_HAVE_A_2X2 0x0080
  46. #define WE_HAVE_INSTR 0x0100
  47. #define USE_MY_METRICS 0x0200
  48. #define OVERLAP_COMPOUND 0x0400
  49. #define SCALED_COMPONENT_OFFSET 0x0800
  50. #define UNSCALED_COMPONENT_OFFSET 0x1000
  51. /*************************************************************************/
  52. /* */
  53. /* <Function> */
  54. /* TT_Get_Metrics */
  55. /* */
  56. /* <Description> */
  57. /* Returns the horizontal or vertical metrics in font units for a */
  58. /* given glyph. The metrics are the left side bearing (resp. top */
  59. /* side bearing) and advance width (resp. advance height). */
  60. /* */
  61. /* <Input> */
  62. /* header :: A pointer to either the horizontal or vertical metrics */
  63. /* structure. */
  64. /* */
  65. /* idx :: The glyph index. */
  66. /* */
  67. /* <Output> */
  68. /* bearing :: The bearing, either left side or top side. */
  69. /* */
  70. /* advance :: The advance width resp. advance height. */
  71. /* */
  72. /* <Note> */
  73. /* This function will much probably move to another component in the */
  74. /* near future, but I haven't decided which yet. */
  75. /* */
  76. FT_LOCAL_DEF( void )
  77. TT_Get_Metrics( TT_HoriHeader* header,
  78. FT_UInt idx,
  79. FT_Short* bearing,
  80. FT_UShort* advance )
  81. {
  82. TT_LongMetrics longs_m;
  83. FT_UShort k = header->number_Of_HMetrics;
  84. if ( k == 0 )
  85. {
  86. *bearing = *advance = 0;
  87. return;
  88. }
  89. if ( idx < (FT_UInt)k )
  90. {
  91. longs_m = (TT_LongMetrics )header->long_metrics + idx;
  92. *bearing = longs_m->bearing;
  93. *advance = longs_m->advance;
  94. }
  95. else
  96. {
  97. *bearing = ((TT_ShortMetrics*)header->short_metrics)[idx - k];
  98. *advance = ((TT_LongMetrics )header->long_metrics)[k - 1].advance;
  99. }
  100. }
  101. /*************************************************************************/
  102. /* */
  103. /* Returns the horizontal metrics in font units for a given glyph. If */
  104. /* `check' is true, take care of monospaced fonts by returning the */
  105. /* advance width maximum. */
  106. /* */
  107. static void
  108. Get_HMetrics( TT_Face face,
  109. FT_UInt idx,
  110. FT_Bool check,
  111. FT_Short* lsb,
  112. FT_UShort* aw )
  113. {
  114. TT_Get_Metrics( &face->horizontal, idx, lsb, aw );
  115. if ( check && face->postscript.isFixedPitch )
  116. *aw = face->horizontal.advance_Width_Max;
  117. }
  118. /*************************************************************************/
  119. /* */
  120. /* Returns the advance width table for a given pixel size if it is found */
  121. /* in the font's `hdmx' table (if any). */
  122. /* */
  123. static FT_Byte*
  124. Get_Advance_Widths( TT_Face face,
  125. FT_UShort ppem )
  126. {
  127. FT_UShort n;
  128. for ( n = 0; n < face->hdmx.num_records; n++ )
  129. if ( face->hdmx.records[n].ppem == ppem )
  130. return face->hdmx.records[n].widths;
  131. return NULL;
  132. }
  133. #define cur_to_org( n, zone ) \
  134. FT_MEM_COPY( (zone)->org, (zone)->cur, (n) * sizeof ( FT_Vector ) )
  135. #define org_to_cur( n, zone ) \
  136. FT_MEM_COPY( (zone)->cur, (zone)->org, (n) * sizeof ( FT_Vector ) )
  137. /*************************************************************************/
  138. /* */
  139. /* Translates an array of coordinates. */
  140. /* */
  141. static void
  142. translate_array( FT_UInt n,
  143. FT_Vector* coords,
  144. FT_Pos delta_x,
  145. FT_Pos delta_y )
  146. {
  147. FT_UInt k;
  148. if ( delta_x )
  149. for ( k = 0; k < n; k++ )
  150. coords[k].x += delta_x;
  151. if ( delta_y )
  152. for ( k = 0; k < n; k++ )
  153. coords[k].y += delta_y;
  154. }
  155. static void
  156. tt_prepare_zone( TT_GlyphZone zone,
  157. FT_GlyphLoad load,
  158. FT_UInt start_point,
  159. FT_UInt start_contour )
  160. {
  161. zone->n_points = (FT_UShort)( load->outline.n_points - start_point );
  162. zone->n_contours = (FT_Short) ( load->outline.n_contours - start_contour );
  163. zone->org = load->extra_points + start_point;
  164. zone->cur = load->outline.points + start_point;
  165. zone->tags = (FT_Byte*)load->outline.tags + start_point;
  166. zone->contours = (FT_UShort*)load->outline.contours + start_contour;
  167. }
  168. #undef IS_HINTED
  169. #define IS_HINTED( flags ) ( ( flags & FT_LOAD_NO_HINTING ) == 0 )
  170. /*************************************************************************/
  171. /* */
  172. /* The following functions are used by default with TrueType fonts. */
  173. /* However, they can be replaced by alternatives if we need to support */
  174. /* TrueType-compressed formats (like MicroType) in the future. */
  175. /* */
  176. /*************************************************************************/
  177. FT_CALLBACK_DEF( FT_Error )
  178. TT_Access_Glyph_Frame( TT_Loader loader,
  179. FT_UInt glyph_index,
  180. FT_ULong offset,
  181. FT_UInt byte_count )
  182. {
  183. FT_Error error;
  184. FT_Stream stream = loader->stream;
  185. /* for non-debug mode */
  186. FT_UNUSED( glyph_index );
  187. FT_TRACE5(( "Glyph %ld\n", glyph_index ));
  188. /* the following line sets the `error' variable through macros! */
  189. if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) )
  190. return error;
  191. return TT_Err_Ok;
  192. }
  193. FT_CALLBACK_DEF( void )
  194. TT_Forget_Glyph_Frame( TT_Loader loader )
  195. {
  196. FT_Stream stream = loader->stream;
  197. FT_FRAME_EXIT();
  198. }
  199. FT_CALLBACK_DEF( FT_Error )
  200. TT_Load_Glyph_Header( TT_Loader loader )
  201. {
  202. FT_Stream stream = loader->stream;
  203. FT_Int byte_len = loader->byte_len - 10;
  204. if ( byte_len < 0 )
  205. return TT_Err_Invalid_Outline;
  206. loader->n_contours = FT_GET_SHORT();
  207. loader->bbox.xMin = FT_GET_SHORT();
  208. loader->bbox.yMin = FT_GET_SHORT();
  209. loader->bbox.xMax = FT_GET_SHORT();
  210. loader->bbox.yMax = FT_GET_SHORT();
  211. FT_TRACE5(( " # of contours: %d\n", loader->n_contours ));
  212. FT_TRACE5(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin,
  213. loader->bbox.xMax ));
  214. FT_TRACE5(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin,
  215. loader->bbox.yMax ));
  216. loader->byte_len = byte_len;
  217. return TT_Err_Ok;
  218. }
  219. FT_CALLBACK_DEF( FT_Error )
  220. TT_Load_Simple_Glyph( TT_Loader load )
  221. {
  222. FT_Error error;
  223. FT_Stream stream = load->stream;
  224. FT_GlyphLoader gloader = load->gloader;
  225. FT_Int n_contours = load->n_contours;
  226. FT_Outline* outline;
  227. TT_Face face = (TT_Face)load->face;
  228. TT_GlyphSlot slot = (TT_GlyphSlot)load->glyph;
  229. FT_UShort n_ins;
  230. FT_Int n, n_points;
  231. FT_Int byte_len = load->byte_len;
  232. /* reading the contours endpoints & number of points */
  233. {
  234. short* cur = gloader->current.outline.contours;
  235. short* limit = cur + n_contours;
  236. /* check space for contours array + instructions count */
  237. byte_len -= 2 * ( n_contours + 1 );
  238. if ( byte_len < 0 )
  239. goto Invalid_Outline;
  240. for ( ; cur < limit; cur++ )
  241. cur[0] = FT_GET_USHORT();
  242. n_points = 0;
  243. if ( n_contours > 0 )
  244. n_points = cur[-1] + 1;
  245. error = FT_GlyphLoader_CheckPoints( gloader, n_points + 2, 0 );
  246. if ( error )
  247. goto Fail;
  248. /* we'd better check the contours table right now */
  249. outline = &gloader->current.outline;
  250. for ( cur = outline->contours + 1; cur < limit; cur++ )
  251. if ( cur[-1] >= cur[0] )
  252. goto Invalid_Outline;
  253. }
  254. /* reading the bytecode instructions */
  255. slot->control_len = 0;
  256. slot->control_data = 0;
  257. n_ins = FT_GET_USHORT();
  258. FT_TRACE5(( " Instructions size: %d\n", n_ins ));
  259. if ( n_ins > face->max_profile.maxSizeOfInstructions )
  260. {
  261. FT_TRACE0(( "TT_Load_Simple_Glyph: Too many instructions!\n" ));
  262. error = TT_Err_Too_Many_Hints;
  263. goto Fail;
  264. }
  265. byte_len -= n_ins;
  266. if ( byte_len < 0 )
  267. {
  268. FT_TRACE0(( "TT_Load_Simple_Glyph: Instruction count mismatch!\n" ));
  269. error = TT_Err_Too_Many_Hints;
  270. goto Fail;
  271. }
  272. #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
  273. if ( ( load->load_flags &
  274. ( FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING ) ) == 0 &&
  275. load->instructions )
  276. {
  277. slot->control_len = n_ins;
  278. slot->control_data = load->instructions;
  279. FT_MEM_COPY( load->instructions, stream->cursor, n_ins );
  280. }
  281. #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
  282. stream->cursor += n_ins;
  283. /* reading the point tags */
  284. {
  285. FT_Byte* flag = (FT_Byte*)outline->tags;
  286. FT_Byte* limit = flag + n_points;
  287. FT_Byte c, count;
  288. while ( flag < limit )
  289. {
  290. if ( --byte_len < 0 )
  291. goto Invalid_Outline;
  292. *flag++ = c = FT_GET_BYTE();
  293. if ( c & 8 )
  294. {
  295. if ( --byte_len < 0 )
  296. goto Invalid_Outline;
  297. count = FT_GET_BYTE();
  298. if ( flag + count > limit )
  299. goto Invalid_Outline;
  300. for ( ; count > 0; count-- )
  301. *flag++ = c;
  302. }
  303. }
  304. /* check that there is enough room to load the coordinates */
  305. for ( flag = (FT_Byte*)outline->tags; flag < limit; flag++ )
  306. {
  307. if ( *flag & 2 )
  308. byte_len -= 1;
  309. else if ( ( *flag & 16 ) == 0 )
  310. byte_len -= 2;
  311. if ( *flag & 4 )
  312. byte_len -= 1;
  313. else if ( ( *flag & 32 ) == 0 )
  314. byte_len -= 2;
  315. }
  316. if ( byte_len < 0 )
  317. goto Invalid_Outline;
  318. }
  319. /* reading the X coordinates */
  320. {
  321. FT_Vector* vec = outline->points;
  322. FT_Vector* limit = vec + n_points;
  323. FT_Byte* flag = (FT_Byte*)outline->tags;
  324. FT_Pos x = 0;
  325. for ( ; vec < limit; vec++, flag++ )
  326. {
  327. FT_Pos y = 0;
  328. if ( *flag & 2 )
  329. {
  330. y = FT_GET_BYTE();
  331. if ( ( *flag & 16 ) == 0 )
  332. y = -y;
  333. }
  334. else if ( ( *flag & 16 ) == 0 )
  335. y = FT_GET_SHORT();
  336. x += y;
  337. vec->x = x;
  338. }
  339. }
  340. /* reading the Y coordinates */
  341. {
  342. FT_Vector* vec = gloader->current.outline.points;
  343. FT_Vector* limit = vec + n_points;
  344. FT_Byte* flag = (FT_Byte*)outline->tags;
  345. FT_Pos x = 0;
  346. for ( ; vec < limit; vec++, flag++ )
  347. {
  348. FT_Pos y = 0;
  349. if ( *flag & 4 )
  350. {
  351. y = FT_GET_BYTE();
  352. if ( ( *flag & 32 ) == 0 )
  353. y = -y;
  354. }
  355. else if ( ( *flag & 32 ) == 0 )
  356. y = FT_GET_SHORT();
  357. x += y;
  358. vec->y = x;
  359. }
  360. }
  361. /* clear the touch tags */
  362. for ( n = 0; n < n_points; n++ )
  363. outline->tags[n] &= FT_CURVE_TAG_ON;
  364. outline->n_points = (FT_UShort)n_points;
  365. outline->n_contours = (FT_Short) n_contours;
  366. load->byte_len = byte_len;
  367. Fail:
  368. return error;
  369. Invalid_Outline:
  370. error = TT_Err_Invalid_Outline;
  371. goto Fail;
  372. }
  373. FT_CALLBACK_DEF( FT_Error )
  374. TT_Load_Composite_Glyph( TT_Loader loader )
  375. {
  376. FT_Error error;
  377. FT_Stream stream = loader->stream;
  378. FT_GlyphLoader gloader = loader->gloader;
  379. FT_SubGlyph subglyph;
  380. FT_UInt num_subglyphs;
  381. FT_Int byte_len = loader->byte_len;
  382. num_subglyphs = 0;
  383. do
  384. {
  385. FT_Fixed xx, xy, yy, yx;
  386. /* check that we can load a new subglyph */
  387. error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs + 1 );
  388. if ( error )
  389. goto Fail;
  390. /* check space */
  391. byte_len -= 4;
  392. if ( byte_len < 0 )
  393. goto Invalid_Composite;
  394. subglyph = gloader->current.subglyphs + num_subglyphs;
  395. subglyph->arg1 = subglyph->arg2 = 0;
  396. subglyph->flags = FT_GET_USHORT();
  397. subglyph->index = FT_GET_USHORT();
  398. /* check space */
  399. byte_len -= 2;
  400. if ( subglyph->flags & ARGS_ARE_WORDS )
  401. byte_len -= 2;
  402. if ( subglyph->flags & WE_HAVE_A_SCALE )
  403. byte_len -= 2;
  404. else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
  405. byte_len -= 4;
  406. else if ( subglyph->flags & WE_HAVE_A_2X2 )
  407. byte_len -= 8;
  408. if ( byte_len < 0 )
  409. goto Invalid_Composite;
  410. /* read arguments */
  411. if ( subglyph->flags & ARGS_ARE_WORDS )
  412. {
  413. subglyph->arg1 = FT_GET_SHORT();
  414. subglyph->arg2 = FT_GET_SHORT();
  415. }
  416. else
  417. {
  418. subglyph->arg1 = FT_GET_CHAR();
  419. subglyph->arg2 = FT_GET_CHAR();
  420. }
  421. /* read transform */
  422. xx = yy = 0x10000L;
  423. xy = yx = 0;
  424. if ( subglyph->flags & WE_HAVE_A_SCALE )
  425. {
  426. xx = (FT_Fixed)FT_GET_SHORT() << 2;
  427. yy = xx;
  428. }
  429. else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
  430. {
  431. xx = (FT_Fixed)FT_GET_SHORT() << 2;
  432. yy = (FT_Fixed)FT_GET_SHORT() << 2;
  433. }
  434. else if ( subglyph->flags & WE_HAVE_A_2X2 )
  435. {
  436. xx = (FT_Fixed)FT_GET_SHORT() << 2;
  437. yx = (FT_Fixed)FT_GET_SHORT() << 2;
  438. xy = (FT_Fixed)FT_GET_SHORT() << 2;
  439. yy = (FT_Fixed)FT_GET_SHORT() << 2;
  440. }
  441. subglyph->transform.xx = xx;
  442. subglyph->transform.xy = xy;
  443. subglyph->transform.yx = yx;
  444. subglyph->transform.yy = yy;
  445. num_subglyphs++;
  446. } while ( subglyph->flags & MORE_COMPONENTS );
  447. gloader->current.num_subglyphs = num_subglyphs;
  448. #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
  449. {
  450. /* we must undo the FT_FRAME_ENTER in order to point to the */
  451. /* composite instructions, if we find some. */
  452. /* we will process them later... */
  453. /* */
  454. loader->ins_pos = (FT_ULong)( FT_STREAM_POS() +
  455. stream->cursor - stream->limit );
  456. }
  457. #endif
  458. loader->byte_len = byte_len;
  459. Fail:
  460. return error;
  461. Invalid_Composite:
  462. error = TT_Err_Invalid_Composite;
  463. goto Fail;
  464. }
  465. FT_LOCAL_DEF( void )
  466. TT_Init_Glyph_Loading( TT_Face face )
  467. {
  468. face->access_glyph_frame = TT_Access_Glyph_Frame;
  469. face->read_glyph_header = TT_Load_Glyph_Header;
  470. face->read_simple_glyph = TT_Load_Simple_Glyph;
  471. face->read_composite_glyph = TT_Load_Composite_Glyph;
  472. face->forget_glyph_frame = TT_Forget_Glyph_Frame;
  473. }
  474. /*************************************************************************/
  475. /* */
  476. /* <Function> */
  477. /* TT_Process_Simple_Glyph */
  478. /* */
  479. /* <Description> */
  480. /* Once a simple glyph has been loaded, it needs to be processed. */
  481. /* Usually, this means scaling and hinting through bytecode */
  482. /* interpretation. */
  483. /* */
  484. static FT_Error
  485. TT_Process_Simple_Glyph( TT_Loader load,
  486. FT_Bool debug )
  487. {
  488. FT_GlyphLoader gloader = load->gloader;
  489. FT_Outline* outline = &gloader->current.outline;
  490. FT_UInt n_points = outline->n_points;
  491. #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
  492. FT_UInt n_ins;
  493. #endif
  494. TT_GlyphZone zone = &load->zone;
  495. FT_Error error = TT_Err_Ok;
  496. FT_UNUSED( debug ); /* used by truetype interpreter only */
  497. #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
  498. n_ins = load->glyph->control_len;
  499. #endif
  500. /* add shadow points */
  501. /* Now add the two shadow points at n and n + 1. */
  502. /* We need the left side bearing and advance width. */
  503. {
  504. FT_Vector* pp1;
  505. FT_Vector* pp2;
  506. /* pp1 = xMin - lsb */
  507. pp1 = outline->points + n_points;
  508. pp1->x = load->bbox.xMin - load->left_bearing;
  509. pp1->y = 0;
  510. /* pp2 = pp1 + aw */
  511. pp2 = pp1 + 1;
  512. pp2->x = pp1->x + load->advance;
  513. pp2->y = 0;
  514. outline->tags[n_points ] = 0;
  515. outline->tags[n_points + 1] = 0;
  516. }
  517. /* Note that we return two more points that are not */
  518. /* part of the glyph outline. */
  519. n_points += 2;
  520. /* set up zone for hinting */
  521. tt_prepare_zone( zone, &gloader->current, 0, 0 );
  522. /* eventually scale the glyph */
  523. if ( !( load->load_flags & FT_LOAD_NO_SCALE ) )
  524. {
  525. FT_Vector* vec = zone->cur;
  526. FT_Vector* limit = vec + n_points;
  527. FT_Fixed x_scale = load->size->metrics.x_scale;
  528. FT_Fixed y_scale = load->size->metrics.y_scale;
  529. /* first scale the glyph points */
  530. for ( ; vec < limit; vec++ )
  531. {
  532. vec->x = FT_MulFix( vec->x, x_scale );
  533. vec->y = FT_MulFix( vec->y, y_scale );
  534. }
  535. }
  536. cur_to_org( n_points, zone );
  537. /* eventually hint the glyph */
  538. if ( IS_HINTED( load->load_flags ) )
  539. {
  540. FT_Pos x = zone->org[n_points-2].x;
  541. x = ( ( x + 32 ) & -64 ) - x;
  542. translate_array( n_points, zone->org, x, 0 );
  543. org_to_cur( n_points, zone );
  544. zone->cur[n_points - 1].x = ( zone->cur[n_points - 1].x + 32 ) & -64;
  545. #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
  546. /* now consider hinting */
  547. if ( n_ins > 0 )
  548. {
  549. error = TT_Set_CodeRange( load->exec, tt_coderange_glyph,
  550. load->exec->glyphIns, n_ins );
  551. if ( error )
  552. goto Exit;
  553. load->exec->is_composite = FALSE;
  554. load->exec->pedantic_hinting = (FT_Bool)( load->load_flags &
  555. FT_LOAD_PEDANTIC );
  556. load->exec->pts = *zone;
  557. load->exec->pts.n_points += 2;
  558. error = TT_Run_Context( load->exec, debug );
  559. if ( error && load->exec->pedantic_hinting )
  560. goto Exit;
  561. error = TT_Err_Ok; /* ignore bytecode errors in non-pedantic mode */
  562. }
  563. #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
  564. }
  565. /* save glyph phantom points */
  566. if ( !load->preserve_pps )
  567. {
  568. load->pp1 = zone->cur[n_points - 2];
  569. load->pp2 = zone->cur[n_points - 1];
  570. }
  571. #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
  572. Exit:
  573. #endif
  574. return error;
  575. }
  576. /*************************************************************************/
  577. /* */
  578. /* <Function> */
  579. /* load_truetype_glyph */
  580. /* */
  581. /* <Description> */
  582. /* Loads a given truetype glyph. Handles composites and uses a */
  583. /* TT_Loader object. */
  584. /* */
  585. static FT_Error
  586. load_truetype_glyph( TT_Loader loader,
  587. FT_UInt glyph_index )
  588. {
  589. #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
  590. FT_Stream stream = loader->stream;
  591. #endif
  592. FT_Error error;
  593. TT_Face face = (TT_Face)loader->face;
  594. FT_ULong offset;
  595. FT_Int contours_count;
  596. FT_UInt num_points, count;
  597. FT_Fixed x_scale, y_scale;
  598. FT_GlyphLoader gloader = loader->gloader;
  599. FT_Bool opened_frame = 0;
  600. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  601. struct FT_StreamRec_ inc_stream;
  602. FT_Data glyph_data;
  603. FT_Bool glyph_data_loaded = 0;
  604. #endif
  605. /* check glyph index */
  606. if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
  607. {
  608. error = TT_Err_Invalid_Glyph_Index;
  609. goto Exit;
  610. }
  611. loader->glyph_index = glyph_index;
  612. num_points = 0;
  613. x_scale = 0x10000L;
  614. y_scale = 0x10000L;
  615. if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
  616. {
  617. x_scale = loader->size->metrics.x_scale;
  618. y_scale = loader->size->metrics.y_scale;
  619. }
  620. /* get horizontal metrics */
  621. {
  622. FT_Short left_bearing = 0;
  623. FT_UShort advance_width = 0;
  624. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  625. FT_Bool metrics_found = FALSE;
  626. /* If this is an incrementally loaded font see if there are */
  627. /* overriding metrics for this glyph. */
  628. if ( face->root.internal->incremental_interface &&
  629. face->root.internal->incremental_interface->funcs->get_glyph_metrics )
  630. {
  631. FT_Incremental_MetricsRec m;
  632. error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
  633. face->root.internal->incremental_interface->object,
  634. glyph_index, FALSE, &m, &metrics_found );
  635. if ( error )
  636. goto Exit;
  637. left_bearing = (FT_Short)m.bearing_x;
  638. advance_width = (FT_UShort)m.advance;
  639. }
  640. if ( !metrics_found )
  641. Get_HMetrics( face, glyph_index,
  642. (FT_Bool)!( loader->load_flags &
  643. FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
  644. &left_bearing,
  645. &advance_width );
  646. #else
  647. Get_HMetrics( face, glyph_index,
  648. (FT_Bool)!( loader->load_flags &
  649. FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ),
  650. &left_bearing,
  651. &advance_width );
  652. #endif /* FT_CONFIG_OPTION_INCREMENTAL */
  653. loader->left_bearing = left_bearing;
  654. loader->advance = advance_width;
  655. if ( !loader->linear_def )
  656. {
  657. loader->linear_def = 1;
  658. loader->linear = advance_width;
  659. }
  660. }
  661. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  662. /* Set `offset' to the start of the glyph program relative to the */
  663. /* start of the 'glyf' table, and `count' to the length of the */
  664. /* glyph program in bytes. */
  665. /* */
  666. /* If we are loading glyph data via the incremental interface, set */
  667. /* the loader stream to a memory stream reading the data returned */
  668. /* by the interface. */
  669. if ( face->root.internal->incremental_interface )
  670. {
  671. error = face->root.internal->incremental_interface->funcs->get_glyph_data(
  672. face->root.internal->incremental_interface->object,
  673. glyph_index, &glyph_data );
  674. if ( error )
  675. goto Exit;
  676. glyph_data_loaded = 1;
  677. offset = 0;
  678. count = glyph_data.length;
  679. FT_MEM_ZERO( &inc_stream, sizeof ( inc_stream ) );
  680. FT_Stream_OpenMemory( &inc_stream,
  681. glyph_data.pointer, glyph_data.length );
  682. loader->stream = &inc_stream;
  683. }
  684. else
  685. #endif /* FT_CONFIG_OPTION_INCREMENTAL */
  686. {
  687. offset = face->glyph_locations[glyph_index];
  688. count = 0;
  689. if ( glyph_index < (FT_UInt)face->num_locations - 1 )
  690. count = face->glyph_locations[glyph_index + 1] - offset;
  691. }
  692. if ( count == 0 )
  693. {
  694. /* as described by Frederic Loyer, these are spaces, and */
  695. /* not the unknown glyph. */
  696. loader->bbox.xMin = 0;
  697. loader->bbox.xMax = 0;
  698. loader->bbox.yMin = 0;
  699. loader->bbox.yMax = 0;
  700. loader->pp1.x = 0;
  701. loader->pp2.x = loader->advance;
  702. if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
  703. loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
  704. #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
  705. if ( loader->exec )
  706. loader->exec->glyphSize = 0;
  707. #endif
  708. error = TT_Err_Ok;
  709. goto Exit;
  710. }
  711. loader->byte_len = (FT_Int)count;
  712. offset = loader->glyf_offset + offset;
  713. /* access glyph frame */
  714. error = face->access_glyph_frame( loader, glyph_index, offset, count );
  715. if ( error )
  716. goto Exit;
  717. opened_frame = 1;
  718. /* read first glyph header */
  719. error = face->read_glyph_header( loader );
  720. if ( error )
  721. goto Fail;
  722. contours_count = loader->n_contours;
  723. count -= 10;
  724. loader->pp1.x = loader->bbox.xMin - loader->left_bearing;
  725. loader->pp1.y = 0;
  726. loader->pp2.x = loader->pp1.x + loader->advance;
  727. loader->pp2.y = 0;
  728. if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
  729. {
  730. loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
  731. loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
  732. }
  733. /***********************************************************************/
  734. /***********************************************************************/
  735. /***********************************************************************/
  736. /* if it is a simple glyph, load it */
  737. if ( contours_count >= 0 )
  738. {
  739. /* check that we can add the contours to the glyph */
  740. error = FT_GlyphLoader_CheckPoints( gloader, 0, contours_count );
  741. if ( error )
  742. goto Fail;
  743. error = face->read_simple_glyph( loader );
  744. if ( error )
  745. goto Fail;
  746. #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
  747. {
  748. TT_Size size = (TT_Size)loader->size;
  749. error = TT_Process_Simple_Glyph( loader,
  750. (FT_Bool)( size && size->debug ) );
  751. }
  752. #else
  753. error = TT_Process_Simple_Glyph( loader, 0 );
  754. #endif
  755. if ( error )
  756. goto Fail;
  757. FT_GlyphLoader_Add( gloader );
  758. /* Note: We could have put the simple loader source there */
  759. /* but the code is fat enough already :-) */
  760. }
  761. /***********************************************************************/
  762. /***********************************************************************/
  763. /***********************************************************************/
  764. /* otherwise, load a composite! */
  765. else
  766. {
  767. TT_GlyphSlot glyph = (TT_GlyphSlot)loader->glyph;
  768. FT_UInt start_point;
  769. #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
  770. FT_UInt start_contour;
  771. FT_ULong ins_pos; /* position of composite instructions, if any */
  772. #endif
  773. /* for each subglyph, read composite header */
  774. start_point = gloader->base.outline.n_points;
  775. #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
  776. start_contour = gloader->base.outline.n_contours;
  777. #endif
  778. error = face->read_composite_glyph( loader );
  779. if ( error )
  780. goto Fail;
  781. #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
  782. ins_pos = loader->ins_pos;
  783. #endif
  784. face->forget_glyph_frame( loader );
  785. opened_frame = 0;
  786. /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */
  787. /* `as is' in the glyph slot (the client application will be */
  788. /* responsible for interpreting these data)... */
  789. /* */
  790. if ( loader->load_flags & FT_LOAD_NO_RECURSE )
  791. {
  792. /* set up remaining glyph fields */
  793. FT_GlyphLoader_Add( gloader );
  794. glyph->num_subglyphs = gloader->base.num_subglyphs;
  795. glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
  796. glyph->subglyphs = gloader->base.subglyphs;
  797. goto Exit;
  798. }
  799. /*********************************************************************/
  800. /*********************************************************************/
  801. /*********************************************************************/
  802. /* Now, read each subglyph independently. */
  803. {
  804. FT_Int n, num_base_points, num_new_points;
  805. FT_SubGlyph subglyph = 0;
  806. FT_UInt num_subglyphs = gloader->current.num_subglyphs;
  807. FT_UInt num_base_subgs = gloader->base.num_subglyphs;
  808. FT_GlyphLoader_Add( gloader );
  809. for ( n = 0; n < (FT_Int)num_subglyphs; n++ )
  810. {
  811. FT_Vector pp1, pp2;
  812. FT_Pos x, y;
  813. /* Each time we call load_truetype_glyph in this loop, the */
  814. /* value of `gloader.base.subglyphs' can change due to table */
  815. /* reallocations. We thus need to recompute the subglyph */
  816. /* pointer on each iteration. */
  817. subglyph = gloader->base.subglyphs + num_base_subgs + n;
  818. pp1 = loader->pp1;
  819. pp2 = loader->pp2;
  820. num_base_points = gloader->base.outline.n_points;
  821. error = load_truetype_glyph( loader, subglyph->index );
  822. if ( error )
  823. goto Fail;
  824. /* restore subglyph pointer */
  825. subglyph = gloader->base.subglyphs + num_base_subgs + n;
  826. if ( subglyph->flags & USE_MY_METRICS )
  827. {
  828. pp1 = loader->pp1;
  829. pp2 = loader->pp2;
  830. }
  831. else
  832. {
  833. loader->pp1 = pp1;
  834. loader->pp2 = pp2;
  835. }
  836. num_points = gloader->base.outline.n_points;
  837. num_new_points = num_points - num_base_points;
  838. /* now perform the transform required for this subglyph */
  839. if ( subglyph->flags & ( WE_HAVE_A_SCALE |
  840. WE_HAVE_AN_XY_SCALE |
  841. WE_HAVE_A_2X2 ) )
  842. {
  843. FT_Vector* cur = gloader->base.outline.points +
  844. num_base_points;
  845. FT_Vector* org = gloader->base.extra_points +
  846. num_base_points;
  847. FT_Vector* limit = cur + num_new_points;
  848. for ( ; cur < limit; cur++, org++ )
  849. {
  850. FT_Vector_Transform( cur, &subglyph->transform );
  851. FT_Vector_Transform( org, &subglyph->transform );
  852. }
  853. }
  854. /* apply offset */
  855. if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) )
  856. {
  857. FT_UInt k = subglyph->arg1;
  858. FT_UInt l = subglyph->arg2;
  859. FT_Vector* p1;
  860. FT_Vector* p2;
  861. if ( start_point + k >= (FT_UInt)num_base_points ||
  862. l >= (FT_UInt)num_new_points )
  863. {
  864. error = TT_Err_Invalid_Composite;
  865. goto Fail;
  866. }
  867. l += num_base_points;
  868. p1 = gloader->base.outline.points + start_point + k;
  869. p2 = gloader->base.outline.points + start_point + l;
  870. x = p1->x - p2->x;
  871. y = p1->y - p2->y;
  872. }
  873. else
  874. {
  875. x = subglyph->arg1;
  876. y = subglyph->arg2;
  877. /* Use a default value dependent on */
  878. /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old TT */
  879. /* fonts which don't set the xxx_COMPONENT_OFFSET bit. */
  880. #ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
  881. if ( !( subglyph->flags & UNSCALED_COMPONENT_OFFSET ) &&
  882. #else
  883. if ( ( subglyph->flags & SCALED_COMPONENT_OFFSET ) &&
  884. #endif
  885. ( subglyph->flags & ( WE_HAVE_A_SCALE |
  886. WE_HAVE_AN_XY_SCALE |
  887. WE_HAVE_A_2X2 )) )
  888. {
  889. #if 0
  890. /*************************************************************************/
  891. /* */
  892. /* This algorithm is what Apple documents. But it doesn't work. */
  893. /* */
  894. int a = subglyph->transform.xx > 0 ? subglyph->transform.xx
  895. : -subglyph->transform.xx;
  896. int b = subglyph->transform.yx > 0 ? subglyph->transform.yx
  897. : -subglyph->transform.yx;
  898. int c = subglyph->transform.xy > 0 ? subglyph->transform.xy
  899. : -subglyph->transform.xy;
  900. int d = subglyph->transform.yy > 0 ? subglyph->transform.yy
  901. : -subglyph->transform.yy;
  902. int m = a > b ? a : b;
  903. int n = c > d ? c : d;
  904. if ( a - b <= 33 && a - b >= -33 )
  905. m *= 2;
  906. if ( c - d <= 33 && c - d >= -33 )
  907. n *= 2;
  908. x = FT_MulFix( x, m );
  909. y = FT_MulFix( y, n );
  910. #else /* 0 */
  911. /*************************************************************************/
  912. /* */
  913. /* This algorithm is a guess and works much better than the above. */
  914. /* */
  915. int mac_xscale = FT_SqrtFixed(
  916. FT_MulFix( subglyph->transform.xx,
  917. subglyph->transform.xx ) +
  918. FT_MulFix( subglyph->transform.xy,
  919. subglyph->transform.xy) );
  920. int mac_yscale = FT_SqrtFixed(
  921. FT_MulFix( subglyph->transform.yy,
  922. subglyph->transform.yy ) +
  923. FT_MulFix( subglyph->transform.yx,
  924. subglyph->transform.yx ) );
  925. x = FT_MulFix( x, mac_xscale );
  926. y = FT_MulFix( y, mac_yscale );
  927. #endif /* 0 */
  928. }
  929. if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
  930. {
  931. x = FT_MulFix( x, x_scale );
  932. y = FT_MulFix( y, y_scale );
  933. if ( subglyph->flags & ROUND_XY_TO_GRID )
  934. {
  935. x = ( x + 32 ) & -64;
  936. y = ( y + 32 ) & -64;
  937. }
  938. }
  939. }
  940. if ( x || y )
  941. {
  942. translate_array( num_new_points,
  943. gloader->base.outline.points + num_base_points,
  944. x, y );
  945. translate_array( num_new_points,
  946. gloader->base.extra_points + num_base_points,
  947. x, y );
  948. }
  949. }
  950. /*******************************************************************/
  951. /*******************************************************************/
  952. /*******************************************************************/
  953. /* we have finished loading all sub-glyphs; now, look for */
  954. /* instructions for this composite! */
  955. #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
  956. if ( num_subglyphs > 0 &&
  957. loader->exec &&
  958. ins_pos > 0 &&
  959. subglyph->flags & WE_HAVE_INSTR )
  960. {
  961. FT_UShort n_ins;
  962. TT_ExecContext exec = loader->exec;
  963. TT_GlyphZone pts;
  964. FT_Vector* pp1;
  965. /* read size of instructions */
  966. if ( FT_STREAM_SEEK( ins_pos ) ||
  967. FT_READ_USHORT( n_ins ) )
  968. goto Fail;
  969. FT_TRACE5(( " Instructions size = %d\n", n_ins ));
  970. /* in some fonts? */
  971. if ( n_ins == 0xFFFFU )
  972. n_ins = 0;
  973. /* check it */
  974. if ( n_ins > face->max_profile.maxSizeOfInstructions )
  975. {
  976. FT_TRACE0(( "Too many instructions (%d) in composite glyph %ld\n",
  977. n_ins, subglyph->index ));
  978. error = TT_Err_Too_Many_Hints;
  979. goto Fail;
  980. }
  981. /* read the instructions */
  982. if ( FT_STREAM_READ( exec->glyphIns, n_ins ) )
  983. goto Fail;
  984. glyph->control_data = exec->glyphIns;
  985. glyph->control_len = n_ins;
  986. error = TT_Set_CodeRange( exec,
  987. tt_coderange_glyph,
  988. exec->glyphIns,
  989. n_ins );
  990. if ( error )
  991. goto Fail;
  992. /* prepare the execution context */
  993. tt_prepare_zone( &exec->pts, &gloader->base,
  994. start_point, start_contour );
  995. pts = &exec->pts;
  996. pts->n_points = (short)(num_points + 2);
  997. pts->n_contours = gloader->base.outline.n_contours;
  998. /* add phantom points */
  999. pp1 = pts->cur + num_points;
  1000. pp1[0] = loader->pp1;
  1001. pp1[1] = loader->pp2;
  1002. pts->tags[num_points ] = 0;
  1003. pts->tags[num_points + 1] = 0;
  1004. /* if hinting, round the phantom points */
  1005. if ( IS_HINTED( loader->load_flags ) )
  1006. {
  1007. pp1[0].x = ( ( loader->pp1.x + 32 ) & -64 );
  1008. pp1[1].x = ( ( loader->pp2.x + 32 ) & -64 );
  1009. }
  1010. {
  1011. FT_UInt k;
  1012. for ( k = 0; k < num_points; k++ )
  1013. pts->tags[k] &= FT_CURVE_TAG_ON;
  1014. }
  1015. cur_to_org( num_points + 2, pts );
  1016. /* now consider hinting */
  1017. if ( IS_HINTED( loader->load_flags ) && n_ins > 0 )
  1018. {
  1019. exec->is_composite = TRUE;
  1020. exec->pedantic_hinting =
  1021. (FT_Bool)( loader->load_flags & FT_LOAD_PEDANTIC );
  1022. error = TT_Run_Context( exec, ((TT_Size)loader->size)->debug );
  1023. if ( error && exec->pedantic_hinting )
  1024. goto Fail;
  1025. }
  1026. /* save glyph origin and advance points */
  1027. loader->pp1 = pp1[0];
  1028. loader->pp2 = pp1[1];
  1029. }
  1030. #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
  1031. }
  1032. /* end of composite loading */
  1033. }
  1034. /***********************************************************************/
  1035. /***********************************************************************/
  1036. /***********************************************************************/
  1037. Fail:
  1038. if ( opened_frame )
  1039. face->forget_glyph_frame( loader );
  1040. Exit:
  1041. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  1042. if ( glyph_data_loaded )
  1043. face->root.internal->incremental_interface->funcs->free_glyph_data(
  1044. face->root.internal->incremental_interface->object,
  1045. &glyph_data );
  1046. #endif
  1047. return error;
  1048. }
  1049. static FT_Error
  1050. compute_glyph_metrics( TT_Loader loader,
  1051. FT_UInt glyph_index )
  1052. {
  1053. FT_BBox bbox;
  1054. TT_Face face = (TT_Face)loader->face;
  1055. FT_Fixed y_scale;
  1056. TT_GlyphSlot glyph = loader->glyph;
  1057. TT_Size size = (TT_Size)loader->size;
  1058. y_scale = 0x10000L;
  1059. if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
  1060. y_scale = size->root.metrics.y_scale;
  1061. if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE )
  1062. {
  1063. glyph->outline.flags &= ~FT_OUTLINE_SINGLE_PASS;
  1064. /* copy outline to our glyph slot */
  1065. FT_GlyphLoader_CopyPoints( glyph->internal->loader, loader->gloader );
  1066. glyph->outline = glyph->internal->loader->base.outline;
  1067. /* translate array so that (0,0) is the glyph's origin */
  1068. FT_Outline_Translate( &glyph->outline, -loader->pp1.x, 0 );
  1069. FT_Outline_Get_CBox( &glyph->outline, &bbox );
  1070. if ( IS_HINTED( loader->load_flags ) )
  1071. {
  1072. /* grid-fit the bounding box */
  1073. bbox.xMin &= -64;
  1074. bbox.yMin &= -64;
  1075. bbox.xMax = ( bbox.xMax + 63 ) & -64;
  1076. bbox.yMax = ( bbox.yMax + 63 ) & -64;
  1077. }
  1078. }
  1079. else
  1080. bbox = loader->bbox;
  1081. /* get the device-independent horizontal advance. It is scaled later */
  1082. /* by the base layer. */
  1083. {
  1084. FT_Pos advance = loader->linear;
  1085. /* the flag FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH was introduced to */
  1086. /* correctly support DynaLab fonts, which have an incorrect */
  1087. /* `advance_Width_Max' field! It is used, to my knowledge, */
  1088. /* exclusively in the X-TrueType font server. */
  1089. /* */
  1090. if ( face->postscript.isFixedPitch &&
  1091. ( loader->load_flags & FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH ) == 0 )
  1092. advance = face->horizontal.advance_Width_Max;
  1093. /* we need to return the advance in font units in linearHoriAdvance, */
  1094. /* it will be scaled later by the base layer. */
  1095. glyph->linearHoriAdvance = advance;
  1096. }
  1097. glyph->metrics.horiBearingX = bbox.xMin;
  1098. glyph->metrics.horiBearingY = bbox.yMax;
  1099. glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
  1100. /* don't forget to hint the advance when we need to */
  1101. if ( IS_HINTED( loader->load_flags ) )
  1102. glyph->metrics.horiAdvance = ( glyph->metrics.horiAdvance + 32 ) & -64;
  1103. /* Now take care of vertical metrics. In the case where there is */
  1104. /* no vertical information within the font (relatively common), make */
  1105. /* up some metrics by `hand'... */
  1106. {
  1107. FT_Short top_bearing; /* vertical top side bearing (EM units) */
  1108. FT_UShort advance_height; /* vertical advance height (EM units) */
  1109. FT_Pos left; /* scaled vertical left side bearing */
  1110. FT_Pos top; /* scaled vertical top side bearing */
  1111. FT_Pos advance; /* scaled vertical advance height */
  1112. FT_Bool metrics_found = FALSE;
  1113. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  1114. /* If this is an incrementally loaded font see if there are */
  1115. /* overriding metrics for this glyph. */
  1116. if ( face->root.internal->incremental_interface &&
  1117. face->root.internal->incremental_interface->funcs->get_glyph_metrics )
  1118. {
  1119. FT_Incremental_MetricsRec m;
  1120. FT_Error error =
  1121. face->root.internal->incremental_interface->funcs->get_glyph_metrics(
  1122. face->root.internal->incremental_interface->object,
  1123. glyph_index, TRUE, &m, &metrics_found );
  1124. if ( error )
  1125. return error;
  1126. top_bearing = (FT_Short)m.bearing_y;
  1127. advance_height = (FT_UShort)m.advance;
  1128. }
  1129. #endif /* FT_CONFIG_OPTION_INCREMENTAL */
  1130. /* Get the unscaled top bearing and advance height. */
  1131. if ( !metrics_found && face->vertical_info &&
  1132. face->vertical.number_Of_VMetrics > 0 )
  1133. {
  1134. /* Don't assume that both the vertical header and vertical */
  1135. /* metrics are present in the same font :-) */
  1136. TT_Get_Metrics( (TT_HoriHeader*)&face->vertical,
  1137. glyph_index,
  1138. &top_bearing,
  1139. &advance_height );
  1140. }
  1141. else
  1142. {
  1143. /* Make up the distances from the horizontal header. */
  1144. /* NOTE: The OS/2 values are the only `portable' ones, */
  1145. /* which is why we use them, if there is an OS/2 */
  1146. /* table in the font. Otherwise, we use the */
  1147. /* values defined in the horizontal header. */
  1148. /* */
  1149. /* NOTE2: The sTypoDescender is negative, which is why */
  1150. /* we compute the baseline-to-baseline distance */
  1151. /* here with: */
  1152. /* ascender - descender + linegap */
  1153. /* */
  1154. if ( face->os2.version != 0xFFFFU )
  1155. {
  1156. top_bearing = (FT_Short)( face->os2.sTypoLineGap / 2 );
  1157. advance_height = (FT_UShort)( face->os2.sTypoAscender -
  1158. face->os2.sTypoDescender +
  1159. face->os2.sTypoLineGap );
  1160. }
  1161. else
  1162. {
  1163. top_bearing = (FT_Short)( face->horizontal.Line_Gap / 2 );
  1164. advance_height = (FT_UShort)( face->horizontal.Ascender +
  1165. face->horizontal.Descender +
  1166. face->horizontal.Line_Gap );
  1167. }
  1168. }
  1169. /* We must adjust the top_bearing value from the bounding box given */
  1170. /* in the glyph header to te bounding box calculated with */
  1171. /* FT_Get_Outline_CBox(). */
  1172. /* scale the metrics */
  1173. if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
  1174. {
  1175. top = FT_MulFix( top_bearing + loader->bbox.yMax, y_scale )
  1176. - bbox.yMax;
  1177. advance = FT_MulFix( advance_height, y_scale );
  1178. }
  1179. else
  1180. {
  1181. top = top_bearing + loader->bbox.yMax - bbox.yMax;
  1182. advance = advance_height;
  1183. }
  1184. /* set the advance height in design units. It is scaled later by */
  1185. /* the base layer. */
  1186. glyph->linearVertAdvance = advance_height;
  1187. /* XXX: for now, we have no better algorithm for the lsb, but it */
  1188. /* should work fine. */
  1189. /* */
  1190. left = ( bbox.xMin - bbox.xMax ) / 2;
  1191. /* grid-fit them if necessary */
  1192. if ( IS_HINTED( loader->load_flags ) )
  1193. {
  1194. left &= -64;
  1195. top = ( top + 63 ) & -64;
  1196. advance = ( advance + 32 ) & -64;
  1197. }
  1198. glyph->metrics.vertBearingX = left;
  1199. glyph->metrics.vertBearingY = top;
  1200. glyph->metrics.vertAdvance = advance;
  1201. }
  1202. /* adjust advance width to the value contained in the hdmx table */
  1203. if ( !face->postscript.isFixedPitch && size &&
  1204. IS_HINTED( loader->load_flags ) )
  1205. {
  1206. FT_Byte* widths = Get_Advance_Widths( face,
  1207. size->root.metrics.x_ppem );
  1208. if ( widths )
  1209. glyph->metrics.horiAdvance = widths[glyph_index] << 6;
  1210. }
  1211. /* set glyph dimensions */
  1212. glyph->metrics.width = bbox.xMax - bbox.xMin;
  1213. glyph->metrics.height = bbox.yMax - bbox.yMin;
  1214. return 0;
  1215. }
  1216. /*************************************************************************/
  1217. /* */
  1218. /* <Function> */
  1219. /* TT_Load_Glyph */
  1220. /* */
  1221. /* <Description> */
  1222. /* A function used to load a single glyph within a given glyph slot, */
  1223. /* for a given size. */
  1224. /* */
  1225. /* <Input> */
  1226. /* glyph :: A handle to a target slot object where the glyph */
  1227. /* will be loaded. */
  1228. /* */
  1229. /* size :: A handle to the source face size at which the glyph */
  1230. /* must be scaled/loaded. */
  1231. /* */
  1232. /* glyph_index :: The index of the glyph in the font file. */
  1233. /* */
  1234. /* load_flags :: A flag indicating what to load for this glyph. The */
  1235. /* FT_LOAD_XXX constants can be used to control the */
  1236. /* glyph loading process (e.g., whether the outline */
  1237. /* should be scaled, whether to load bitmaps or not, */
  1238. /* whether to hint the outline, etc). */
  1239. /* */
  1240. /* <Return> */
  1241. /* FreeType error code. 0 means success. */
  1242. /* */
  1243. FT_LOCAL_DEF( FT_Error )
  1244. TT_Load_Glyph( TT_Size size,
  1245. TT_GlyphSlot glyph,
  1246. FT_UShort glyph_index,
  1247. FT_Int32 load_flags )
  1248. {
  1249. SFNT_Service sfnt;
  1250. TT_Face face;
  1251. FT_Stream stream;
  1252. FT_Error error;
  1253. TT_LoaderRec loader;
  1254. face = (TT_Face)glyph->face;
  1255. sfnt = (SFNT_Service)face->sfnt;
  1256. stream = face->root.stream;
  1257. error = 0;
  1258. if ( !size || ( load_flags & FT_LOAD_NO_SCALE ) ||
  1259. ( load_flags & FT_LOAD_NO_RECURSE ) )
  1260. {
  1261. size = NULL;
  1262. load_flags |= FT_LOAD_NO_SCALE |
  1263. FT_LOAD_NO_HINTING |
  1264. FT_LOAD_NO_BITMAP;
  1265. }
  1266. glyph->num_subglyphs = 0;
  1267. #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
  1268. /* try to load embedded bitmap if any */
  1269. /* */
  1270. /* XXX: The convention should be emphasized in */
  1271. /* the documents because it can be confusing. */
  1272. if ( size &&
  1273. size->strike_index != 0xFFFFU &&
  1274. sfnt->load_sbits &&
  1275. ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
  1276. {
  1277. TT_SBit_MetricsRec metrics;
  1278. error = sfnt->load_sbit_image( face,
  1279. size->strike_index,
  1280. glyph_index,
  1281. load_flags,
  1282. stream,
  1283. &glyph->bitmap,
  1284. &metrics );
  1285. if ( !error )
  1286. {
  1287. glyph->outline.n_points = 0;
  1288. glyph->outline.n_contours = 0;
  1289. glyph->metrics.width = (FT_Pos)metrics.width << 6;
  1290. glyph->metrics.height = (FT_Pos)metrics.height << 6;
  1291. glyph->metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6;
  1292. glyph->metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6;
  1293. glyph->metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6;
  1294. glyph->metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6;
  1295. glyph->metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6;
  1296. glyph->metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6;
  1297. glyph->format = FT_GLYPH_FORMAT_BITMAP;
  1298. if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
  1299. {
  1300. glyph->bitmap_left = metrics.vertBearingX;
  1301. glyph->bitmap_top = metrics.vertBearingY;
  1302. }
  1303. else
  1304. {
  1305. glyph->bitmap_left = metrics.horiBearingX;
  1306. glyph->bitmap_top = metrics.horiBearingY;
  1307. }
  1308. return error;
  1309. }
  1310. }
  1311. #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
  1312. /* return immediately if we only want the embedded bitmaps */
  1313. if ( load_flags & FT_LOAD_SBITS_ONLY )
  1314. return FT_Err_Invalid_Argument;
  1315. /* seek to the beginning of the glyph table. For Type 42 fonts */
  1316. /* the table might be accessed from a Postscript stream or something */
  1317. /* else... */
  1318. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  1319. /* Don't look for the glyph table if this is an incremental font. */
  1320. if ( !face->root.internal->incremental_interface )
  1321. #endif
  1322. {
  1323. error = face->goto_table( face, TTAG_glyf, stream, 0 );
  1324. if ( error )
  1325. {
  1326. FT_ERROR(( "TT_Load_Glyph: could not access glyph table\n" ));
  1327. goto Exit;
  1328. }
  1329. }
  1330. FT_MEM_ZERO( &loader, sizeof ( loader ) );
  1331. /* update the glyph zone bounds */
  1332. {
  1333. FT_GlyphLoader gloader = FT_FACE_DRIVER(face)->glyph_loader;
  1334. loader.gloader = gloader;
  1335. FT_GlyphLoader_Rewind( gloader );
  1336. tt_prepare_zone( &loader.zone, &gloader->base, 0, 0 );
  1337. tt_prepare_zone( &loader.base, &gloader->base, 0, 0 );
  1338. }
  1339. #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
  1340. if ( size )
  1341. {
  1342. /* query new execution context */
  1343. loader.exec = size->debug ? size->context : TT_New_Context( face );
  1344. if ( !loader.exec )
  1345. return TT_Err_Could_Not_Find_Context;
  1346. TT_Load_Context( loader.exec, face, size );
  1347. loader.instructions = loader.exec->glyphIns;
  1348. /* load default graphics state - if needed */
  1349. if ( size->GS.instruct_control & 2 )
  1350. loader.exec->GS = tt_default_graphics_state;
  1351. }
  1352. #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
  1353. /* clear all outline flags, except the `owner' one */
  1354. glyph->outline.flags = 0;
  1355. /* let's initialize the rest of our loader now */
  1356. loader.load_flags = load_flags;
  1357. loader.face = (FT_Face)face;
  1358. loader.size = (FT_Size)size;
  1359. loader.glyph = (FT_GlyphSlot)glyph;
  1360. loader.stream = stream;
  1361. #ifdef FT_CONFIG_OPTION_INCREMENTAL
  1362. if ( face->root.internal->incremental_interface )
  1363. loader.glyf_offset = 0;
  1364. else
  1365. #endif
  1366. loader.glyf_offset = FT_STREAM_POS();
  1367. #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
  1368. /* if the cvt program has disabled hinting, the argument */
  1369. /* is ignored. */
  1370. if ( size && ( size->GS.instruct_control & 1 ) )
  1371. loader.load_flags |= FT_LOAD_NO_HINTING;
  1372. #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
  1373. /* Main loading loop */
  1374. glyph->format = FT_GLYPH_FORMAT_OUTLINE;
  1375. glyph->num_subglyphs = 0;
  1376. error = load_truetype_glyph( &loader, glyph_index );
  1377. if ( !error )
  1378. compute_glyph_metrics( &loader, glyph_index );
  1379. #ifdef TT_CONFIG_OPTION_BYTECODE_INTERPRETER
  1380. if ( !size || !size->debug )
  1381. TT_Done_Context( loader.exec );
  1382. #endif /* TT_CONFIG_OPTION_BYTECODE_INTERPRETER */
  1383. /* Set the `high precision' bit flag. */
  1384. /* This is _critical_ to get correct output for monochrome */
  1385. /* TrueType glyphs at all sizes using the bytecode interpreter. */
  1386. /* */
  1387. if ( size && size->root.metrics.y_ppem < 24 )
  1388. glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
  1389. Exit:
  1390. return error;
  1391. }
  1392. /* END */