ReactOS  0.4.14-dev-77-gd9e7c48
ttgload.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* ttgload.c */
4 /* */
5 /* TrueType Glyph Loader (body). */
6 /* */
7 /* Copyright 1996-2018 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 
18 
19 #include <ft2build.h>
20 #include FT_INTERNAL_DEBUG_H
21 #include FT_CONFIG_CONFIG_H
22 #include FT_INTERNAL_CALC_H
23 #include FT_INTERNAL_STREAM_H
24 #include FT_INTERNAL_SFNT_H
25 #include FT_TRUETYPE_TAGS_H
26 #include FT_OUTLINE_H
27 #include FT_DRIVER_H
28 #include FT_LIST_H
29 
30 #include "ttgload.h"
31 #include "ttpload.h"
32 
33 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
34 #include "ttgxvar.h"
35 #endif
36 
37 #include "tterrors.h"
38 #include "ttsubpix.h"
39 
40 
41  /*************************************************************************/
42  /* */
43  /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
44  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
45  /* messages during execution. */
46  /* */
47 #undef FT_COMPONENT
48 #define FT_COMPONENT trace_ttgload
49 
50 
51  /*************************************************************************/
52  /* */
53  /* Composite glyph flags. */
54  /* */
55 #define ARGS_ARE_WORDS 0x0001
56 #define ARGS_ARE_XY_VALUES 0x0002
57 #define ROUND_XY_TO_GRID 0x0004
58 #define WE_HAVE_A_SCALE 0x0008
59 /* reserved 0x0010 */
60 #define MORE_COMPONENTS 0x0020
61 #define WE_HAVE_AN_XY_SCALE 0x0040
62 #define WE_HAVE_A_2X2 0x0080
63 #define WE_HAVE_INSTR 0x0100
64 #define USE_MY_METRICS 0x0200
65 #define OVERLAP_COMPOUND 0x0400
66 #define SCALED_COMPONENT_OFFSET 0x0800
67 #define UNSCALED_COMPONENT_OFFSET 0x1000
68 
69 
70  /*************************************************************************/
71  /* */
72  /* Return the horizontal metrics in font units for a given glyph. */
73  /* */
74  FT_LOCAL_DEF( void )
76  FT_UInt idx,
77  FT_Short* lsb,
78  FT_UShort* aw )
79  {
80  ( (SFNT_Service)face->sfnt )->get_metrics( face, 0, idx, lsb, aw );
81 
82  FT_TRACE5(( " advance width (font units): %d\n", *aw ));
83  FT_TRACE5(( " left side bearing (font units): %d\n", *lsb ));
84  }
85 
86 
87  /*************************************************************************/
88  /* */
89  /* Return the vertical metrics in font units for a given glyph. */
90  /* See function `tt_loader_set_pp' below for explanations. */
91  /* */
92  FT_LOCAL_DEF( void )
94  FT_UInt idx,
95  FT_Pos yMax,
96  FT_Short* tsb,
97  FT_UShort* ah )
98  {
99  if ( face->vertical_info )
100  ( (SFNT_Service)face->sfnt )->get_metrics( face, 1, idx, tsb, ah );
101 
102  else if ( face->os2.version != 0xFFFFU )
103  {
104  *tsb = (FT_Short)( face->os2.sTypoAscender - yMax );
105  *ah = (FT_UShort)FT_ABS( face->os2.sTypoAscender -
106  face->os2.sTypoDescender );
107  }
108 
109  else
110  {
111  *tsb = (FT_Short)( face->horizontal.Ascender - yMax );
112  *ah = (FT_UShort)FT_ABS( face->horizontal.Ascender -
113  face->horizontal.Descender );
114  }
115 
116  FT_TRACE5(( " advance height (font units): %d\n", *ah ));
117  FT_TRACE5(( " top side bearing (font units): %d\n", *tsb ));
118  }
119 
120 
121  static FT_Error
123  FT_UInt glyph_index )
124  {
125  TT_Face face = loader->face;
126 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
128 #endif
129 
130  FT_Error error;
131  FT_Stream stream = loader->stream;
132 
133  FT_Short left_bearing = 0, top_bearing = 0;
134  FT_UShort advance_width = 0, advance_height = 0;
135 
136  /* we must preserve the stream position */
137  /* (which gets altered by the metrics functions) */
139 
140 
141  TT_Get_HMetrics( face, glyph_index,
142  &left_bearing,
143  &advance_width );
144  TT_Get_VMetrics( face, glyph_index,
145  loader->bbox.yMax,
146  &top_bearing,
147  &advance_height );
148 
149  if ( FT_STREAM_SEEK( pos ) )
150  return error;
151 
152  loader->left_bearing = left_bearing;
153  loader->advance = advance_width;
154  loader->top_bearing = top_bearing;
155  loader->vadvance = advance_height;
156 
157 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
158  if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
159  loader->exec )
160  {
161  loader->exec->sph_tweak_flags = 0;
162 
163  /* This may not be the right place for this, but it works... */
164  /* Note that we have to unconditionally load the tweaks since */
165  /* it is possible that glyphs individually switch ClearType's */
166  /* backward compatibility mode on and off. */
167  sph_set_tweaks( loader, glyph_index );
168  }
169 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
170 
171  if ( !loader->linear_def )
172  {
173  loader->linear_def = 1;
174  loader->linear = advance_width;
175  }
176 
177  return FT_Err_Ok;
178  }
179 
180 
181 #ifdef FT_CONFIG_OPTION_INCREMENTAL
182 
183  static void
184  tt_get_metrics_incr_overrides( TT_Loader loader,
185  FT_UInt glyph_index )
186  {
187  TT_Face face = loader->face;
188 
189  FT_Short left_bearing = 0, top_bearing = 0;
190  FT_UShort advance_width = 0, advance_height = 0;
191 
192 
193  /* If this is an incrementally loaded font check whether there are */
194  /* overriding metrics for this glyph. */
195  if ( face->root.internal->incremental_interface &&
196  face->root.internal->incremental_interface->funcs->get_glyph_metrics )
197  {
198  FT_Incremental_MetricsRec incr_metrics;
199  FT_Error error;
200 
201 
202  incr_metrics.bearing_x = loader->left_bearing;
203  incr_metrics.bearing_y = 0;
204  incr_metrics.advance = loader->advance;
205  incr_metrics.advance_v = 0;
206 
207  error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
208  face->root.internal->incremental_interface->object,
209  glyph_index, FALSE, &incr_metrics );
210  if ( error )
211  goto Exit;
212 
213  left_bearing = (FT_Short)incr_metrics.bearing_x;
214  advance_width = (FT_UShort)incr_metrics.advance;
215 
216 #if 0
217 
218  /* GWW: Do I do the same for vertical metrics? */
219  incr_metrics.bearing_x = 0;
220  incr_metrics.bearing_y = loader->top_bearing;
221  incr_metrics.advance = loader->vadvance;
222 
223  error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
224  face->root.internal->incremental_interface->object,
225  glyph_index, TRUE, &incr_metrics );
226  if ( error )
227  goto Exit;
228 
229  top_bearing = (FT_Short)incr_metrics.bearing_y;
230  advance_height = (FT_UShort)incr_metrics.advance;
231 
232 #endif /* 0 */
233 
234  loader->left_bearing = left_bearing;
235  loader->advance = advance_width;
236  loader->top_bearing = top_bearing;
237  loader->vadvance = advance_height;
238 
239  if ( !loader->linear_def )
240  {
241  loader->linear_def = 1;
242  loader->linear = advance_width;
243  }
244  }
245 
246  Exit:
247  return;
248  }
249 
250 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
251 
252 
253  /*************************************************************************/
254  /* */
255  /* The following functions are used by default with TrueType fonts. */
256  /* However, they can be replaced by alternatives if we need to support */
257  /* TrueType-compressed formats (like MicroType) in the future. */
258  /* */
259  /*************************************************************************/
260 
263  FT_UInt glyph_index,
265  FT_UInt byte_count )
266  {
267  FT_Error error;
268  FT_Stream stream = loader->stream;
269 
270  /* for non-debug mode */
271  FT_UNUSED( glyph_index );
272 
273 
274  FT_TRACE4(( "Glyph %ld\n", glyph_index ));
275 
276  /* the following line sets the `error' variable through macros! */
277  if ( FT_STREAM_SEEK( offset ) || FT_FRAME_ENTER( byte_count ) )
278  return error;
279 
280  loader->cursor = stream->cursor;
281  loader->limit = stream->limit;
282 
283  return FT_Err_Ok;
284  }
285 
286 
287  FT_CALLBACK_DEF( void )
289  {
290  FT_Stream stream = loader->stream;
291 
292 
293  FT_FRAME_EXIT();
294  }
295 
296 
299  {
300  FT_Byte* p = loader->cursor;
301  FT_Byte* limit = loader->limit;
302 
303 
304  if ( p + 10 > limit )
305  return FT_THROW( Invalid_Outline );
306 
307  loader->n_contours = FT_NEXT_SHORT( p );
308 
309  loader->bbox.xMin = FT_NEXT_SHORT( p );
310  loader->bbox.yMin = FT_NEXT_SHORT( p );
311  loader->bbox.xMax = FT_NEXT_SHORT( p );
312  loader->bbox.yMax = FT_NEXT_SHORT( p );
313 
314  FT_TRACE5(( " # of contours: %d\n", loader->n_contours ));
315  FT_TRACE5(( " xMin: %4d xMax: %4d\n", loader->bbox.xMin,
316  loader->bbox.xMax ));
317  FT_TRACE5(( " yMin: %4d yMax: %4d\n", loader->bbox.yMin,
318  loader->bbox.yMax ));
319  loader->cursor = p;
320 
321  return FT_Err_Ok;
322  }
323 
324 
327  {
328  FT_Error error;
329  FT_Byte* p = load->cursor;
330  FT_Byte* limit = load->limit;
331  FT_GlyphLoader gloader = load->gloader;
332  FT_Int n_contours = load->n_contours;
334  FT_UShort n_ins;
335  FT_Int n_points;
336 
337  FT_Byte *flag, *flag_limit;
338  FT_Byte c, count;
339  FT_Vector *vec, *vec_limit;
340  FT_Pos x;
341  FT_Short *cont, *cont_limit, prev_cont;
342  FT_Int xy_size = 0;
343 
344 
345  /* check that we can add the contours to the glyph */
346  error = FT_GLYPHLOADER_CHECK_POINTS( gloader, 0, n_contours );
347  if ( error )
348  goto Fail;
349 
350  /* reading the contours' endpoints & number of points */
351  cont = gloader->current.outline.contours;
352  cont_limit = cont + n_contours;
353 
354  /* check space for contours array + instructions count */
355  if ( n_contours >= 0xFFF || p + ( n_contours + 1 ) * 2 > limit )
356  goto Invalid_Outline;
357 
358  prev_cont = FT_NEXT_SHORT( p );
359 
360  if ( n_contours > 0 )
361  cont[0] = prev_cont;
362 
363  if ( prev_cont < 0 )
364  goto Invalid_Outline;
365 
366  for ( cont++; cont < cont_limit; cont++ )
367  {
368  cont[0] = FT_NEXT_SHORT( p );
369  if ( cont[0] <= prev_cont )
370  {
371  /* unordered contours: this is invalid */
372  goto Invalid_Outline;
373  }
374  prev_cont = cont[0];
375  }
376 
377  n_points = 0;
378  if ( n_contours > 0 )
379  {
380  n_points = cont[-1] + 1;
381  if ( n_points < 0 )
382  goto Invalid_Outline;
383  }
384 
385  /* note that we will add four phantom points later */
386  error = FT_GLYPHLOADER_CHECK_POINTS( gloader, n_points + 4, 0 );
387  if ( error )
388  goto Fail;
389 
390  /* reading the bytecode instructions */
391  load->glyph->control_len = 0;
392  load->glyph->control_data = NULL;
393 
394  if ( p + 2 > limit )
395  goto Invalid_Outline;
396 
397  n_ins = FT_NEXT_USHORT( p );
398 
399  FT_TRACE5(( " Instructions size: %u\n", n_ins ));
400 
401 #ifdef TT_USE_BYTECODE_INTERPRETER
402 
403  if ( IS_HINTED( load->load_flags ) )
404  {
405  FT_ULong tmp;
406 
407 
408  /* check instructions size */
409  if ( ( limit - p ) < n_ins )
410  {
411  FT_TRACE1(( "TT_Load_Simple_Glyph: instruction count mismatch\n" ));
412  error = FT_THROW( Too_Many_Hints );
413  goto Fail;
414  }
415 
416  /* we don't trust `maxSizeOfInstructions' in the `maxp' table */
417  /* and thus update the bytecode array size by ourselves */
418 
419  tmp = load->exec->glyphSize;
420  error = Update_Max( load->exec->memory,
421  &tmp,
422  sizeof ( FT_Byte ),
423  (void*)&load->exec->glyphIns,
424  n_ins );
425 
426  load->exec->glyphSize = (FT_UShort)tmp;
427  if ( error )
428  return error;
429 
430  load->glyph->control_len = n_ins;
431  load->glyph->control_data = load->exec->glyphIns;
432 
433  if ( n_ins )
434  FT_MEM_COPY( load->exec->glyphIns, p, (FT_Long)n_ins );
435  }
436 
437 #endif /* TT_USE_BYTECODE_INTERPRETER */
438 
439  p += n_ins;
440 
441  outline = &gloader->current.outline;
442 
443  /* reading the point tags */
444  flag = (FT_Byte*)outline->tags;
445  flag_limit = flag + n_points;
446 
447  FT_ASSERT( flag );
448 
449  while ( flag < flag_limit )
450  {
451  if ( p + 1 > limit )
452  goto Invalid_Outline;
453 
454  *flag++ = c = FT_NEXT_BYTE( p );
455  if ( c & 8 )
456  {
457  if ( p + 1 > limit )
458  goto Invalid_Outline;
459 
460  count = FT_NEXT_BYTE( p );
461  if ( flag + (FT_Int)count > flag_limit )
462  goto Invalid_Outline;
463 
464  for ( ; count > 0; count-- )
465  *flag++ = c;
466  }
467  }
468 
469  /* reading the X coordinates */
470 
471  vec = outline->points;
472  vec_limit = vec + n_points;
473  flag = (FT_Byte*)outline->tags;
474  x = 0;
475 
476  if ( p + xy_size > limit )
477  goto Invalid_Outline;
478 
479  for ( ; vec < vec_limit; vec++, flag++ )
480  {
481  FT_Pos y = 0;
482  FT_Byte f = *flag;
483 
484 
485  if ( f & 2 )
486  {
487  if ( p + 1 > limit )
488  goto Invalid_Outline;
489 
490  y = (FT_Pos)FT_NEXT_BYTE( p );
491  if ( ( f & 16 ) == 0 )
492  y = -y;
493  }
494  else if ( ( f & 16 ) == 0 )
495  {
496  if ( p + 2 > limit )
497  goto Invalid_Outline;
498 
499  y = (FT_Pos)FT_NEXT_SHORT( p );
500  }
501 
502  x += y;
503  vec->x = x;
504  /* the cast is for stupid compilers */
505  *flag = (FT_Byte)( f & ~( 2 | 16 ) );
506  }
507 
508  /* reading the Y coordinates */
509 
510  vec = gloader->current.outline.points;
511  vec_limit = vec + n_points;
512  flag = (FT_Byte*)outline->tags;
513  x = 0;
514 
515  for ( ; vec < vec_limit; vec++, flag++ )
516  {
517  FT_Pos y = 0;
518  FT_Byte f = *flag;
519 
520 
521  if ( f & 4 )
522  {
523  if ( p + 1 > limit )
524  goto Invalid_Outline;
525 
526  y = (FT_Pos)FT_NEXT_BYTE( p );
527  if ( ( f & 32 ) == 0 )
528  y = -y;
529  }
530  else if ( ( f & 32 ) == 0 )
531  {
532  if ( p + 2 > limit )
533  goto Invalid_Outline;
534 
535  y = (FT_Pos)FT_NEXT_SHORT( p );
536  }
537 
538  x += y;
539  vec->y = x;
540  /* the cast is for stupid compilers */
541  *flag = (FT_Byte)( f & FT_CURVE_TAG_ON );
542  }
543 
544  outline->n_points = (FT_Short)n_points;
545  outline->n_contours = (FT_Short)n_contours;
546 
547  load->cursor = p;
548 
549  Fail:
550  return error;
551 
552  Invalid_Outline:
553  error = FT_THROW( Invalid_Outline );
554  goto Fail;
555  }
556 
557 
560  {
561  FT_Error error;
562  FT_Byte* p = loader->cursor;
563  FT_Byte* limit = loader->limit;
564  FT_GlyphLoader gloader = loader->gloader;
565  FT_SubGlyph subglyph;
566  FT_UInt num_subglyphs;
567 
568 
569  num_subglyphs = 0;
570 
571  do
572  {
573  FT_Fixed xx, xy, yy, yx;
574  FT_UInt count;
575 
576 
577  /* check that we can load a new subglyph */
578  error = FT_GlyphLoader_CheckSubGlyphs( gloader, num_subglyphs + 1 );
579  if ( error )
580  goto Fail;
581 
582  /* check space */
583  if ( p + 4 > limit )
584  goto Invalid_Composite;
585 
586  subglyph = gloader->current.subglyphs + num_subglyphs;
587 
588  subglyph->arg1 = subglyph->arg2 = 0;
589 
590  subglyph->flags = FT_NEXT_USHORT( p );
591  subglyph->index = FT_NEXT_USHORT( p );
592 
593  /* check space */
594  count = 2;
595  if ( subglyph->flags & ARGS_ARE_WORDS )
596  count += 2;
597  if ( subglyph->flags & WE_HAVE_A_SCALE )
598  count += 2;
599  else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
600  count += 4;
601  else if ( subglyph->flags & WE_HAVE_A_2X2 )
602  count += 8;
603 
604  if ( p + count > limit )
605  goto Invalid_Composite;
606 
607  /* read arguments */
608  if ( subglyph->flags & ARGS_ARE_XY_VALUES )
609  {
610  if ( subglyph->flags & ARGS_ARE_WORDS )
611  {
612  subglyph->arg1 = FT_NEXT_SHORT( p );
613  subglyph->arg2 = FT_NEXT_SHORT( p );
614  }
615  else
616  {
617  subglyph->arg1 = FT_NEXT_CHAR( p );
618  subglyph->arg2 = FT_NEXT_CHAR( p );
619  }
620  }
621  else
622  {
623  if ( subglyph->flags & ARGS_ARE_WORDS )
624  {
625  subglyph->arg1 = (FT_Int)FT_NEXT_USHORT( p );
626  subglyph->arg2 = (FT_Int)FT_NEXT_USHORT( p );
627  }
628  else
629  {
630  subglyph->arg1 = (FT_Int)FT_NEXT_BYTE( p );
631  subglyph->arg2 = (FT_Int)FT_NEXT_BYTE( p );
632  }
633  }
634 
635  /* read transform */
636  xx = yy = 0x10000L;
637  xy = yx = 0;
638 
639  if ( subglyph->flags & WE_HAVE_A_SCALE )
640  {
641  xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
642  yy = xx;
643  }
644  else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
645  {
646  xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
647  yy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
648  }
649  else if ( subglyph->flags & WE_HAVE_A_2X2 )
650  {
651  xx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
652  yx = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
653  xy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
654  yy = (FT_Fixed)FT_NEXT_SHORT( p ) * 4;
655  }
656 
657  subglyph->transform.xx = xx;
658  subglyph->transform.xy = xy;
659  subglyph->transform.yx = yx;
660  subglyph->transform.yy = yy;
661 
662  num_subglyphs++;
663 
664  } while ( subglyph->flags & MORE_COMPONENTS );
665 
666  gloader->current.num_subglyphs = num_subglyphs;
667  FT_TRACE5(( " %d component%s\n",
668  num_subglyphs,
669  num_subglyphs > 1 ? "s" : "" ));
670 
671 #ifdef FT_DEBUG_LEVEL_TRACE
672  {
673  FT_UInt i;
674 
675 
676  subglyph = gloader->current.subglyphs;
677 
678  for ( i = 0; i < num_subglyphs; i++ )
679  {
680  if ( num_subglyphs > 1 )
681  FT_TRACE7(( " subglyph %d:\n", i ));
682 
683  FT_TRACE7(( " glyph index: %d\n", subglyph->index ));
684 
685  if ( subglyph->flags & ARGS_ARE_XY_VALUES )
686  FT_TRACE7(( " offset: x=%d, y=%d\n",
687  subglyph->arg1,
688  subglyph->arg2 ));
689  else
690  FT_TRACE7(( " matching points: base=%d, component=%d\n",
691  subglyph->arg1,
692  subglyph->arg2 ));
693 
694  if ( subglyph->flags & WE_HAVE_A_SCALE )
695  FT_TRACE7(( " scaling: %f\n",
696  subglyph->transform.xx / 65536.0 ));
697  else if ( subglyph->flags & WE_HAVE_AN_XY_SCALE )
698  FT_TRACE7(( " scaling: x=%f, y=%f\n",
699  subglyph->transform.xx / 65536.0,
700  subglyph->transform.yy / 65536.0 ));
701  else if ( subglyph->flags & WE_HAVE_A_2X2 )
702  FT_TRACE7(( " scaling: xx=%f, yx=%f\n"
703  " xy=%f, yy=%f\n",
704  subglyph->transform.xx / 65536.0,
705  subglyph->transform.yx / 65536.0,
706  subglyph->transform.xy / 65536.0,
707  subglyph->transform.yy / 65536.0 ));
708 
709  subglyph++;
710  }
711  }
712 #endif /* FT_DEBUG_LEVEL_TRACE */
713 
714 #ifdef TT_USE_BYTECODE_INTERPRETER
715 
716  {
717  FT_Stream stream = loader->stream;
718 
719 
720  /* we must undo the FT_FRAME_ENTER in order to point */
721  /* to the composite instructions, if we find some. */
722  /* We will process them later. */
723  /* */
724  loader->ins_pos = (FT_ULong)( FT_STREAM_POS() +
725  p - limit );
726  }
727 
728 #endif
729 
730  loader->cursor = p;
731 
732  Fail:
733  return error;
734 
735  Invalid_Composite:
736  error = FT_THROW( Invalid_Composite );
737  goto Fail;
738  }
739 
740 
741  FT_LOCAL_DEF( void )
743  {
744  face->access_glyph_frame = TT_Access_Glyph_Frame;
745  face->read_glyph_header = TT_Load_Glyph_Header;
746  face->read_simple_glyph = TT_Load_Simple_Glyph;
747  face->read_composite_glyph = TT_Load_Composite_Glyph;
748  face->forget_glyph_frame = TT_Forget_Glyph_Frame;
749  }
750 
751 
752  static void
755  FT_UInt start_point,
756  FT_UInt start_contour )
757  {
758  zone->n_points = (FT_UShort)load->outline.n_points -
759  (FT_UShort)start_point;
760  zone->n_contours = load->outline.n_contours -
761  (FT_Short)start_contour;
762  zone->org = load->extra_points + start_point;
763  zone->cur = load->outline.points + start_point;
764  zone->orus = load->extra_points2 + start_point;
765  zone->tags = (FT_Byte*)load->outline.tags + start_point;
766  zone->contours = (FT_UShort*)load->outline.contours + start_contour;
767  zone->first_point = (FT_UShort)start_point;
768  }
769 
770 
771  /*************************************************************************/
772  /* */
773  /* <Function> */
774  /* TT_Hint_Glyph */
775  /* */
776  /* <Description> */
777  /* Hint the glyph using the zone prepared by the caller. Note that */
778  /* the zone is supposed to include four phantom points. */
779  /* */
780  static FT_Error
782  FT_Bool is_composite )
783  {
784 #if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
785  defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
786  TT_Face face = loader->face;
788 #endif
789 
790  TT_GlyphZone zone = &loader->zone;
791 
792 #ifdef TT_USE_BYTECODE_INTERPRETER
793  FT_Long n_ins;
794 #else
795  FT_UNUSED( is_composite );
796 #endif
797 
798 
799 #ifdef TT_USE_BYTECODE_INTERPRETER
800  if ( loader->glyph->control_len > 0xFFFFL )
801  {
802  FT_TRACE1(( "TT_Hint_Glyph: too long instructions" ));
803  FT_TRACE1(( " (0x%lx byte) is truncated\n",
804  loader->glyph->control_len ));
805  }
806  n_ins = loader->glyph->control_len;
807 
808  /* save original point position in org */
809  if ( n_ins > 0 )
810  FT_ARRAY_COPY( zone->org, zone->cur, zone->n_points );
811 
812  /* Reset graphics state. */
813  loader->exec->GS = loader->size->GS;
814 
815  /* XXX: UNDOCUMENTED! Hinting instructions of a composite glyph */
816  /* completely refer to the (already) hinted subglyphs. */
817  if ( is_composite )
818  {
819  loader->exec->metrics.x_scale = 1 << 16;
820  loader->exec->metrics.y_scale = 1 << 16;
821 
822  FT_ARRAY_COPY( zone->orus, zone->cur, zone->n_points );
823  }
824  else
825  {
826  loader->exec->metrics.x_scale = loader->size->metrics->x_scale;
827  loader->exec->metrics.y_scale = loader->size->metrics->y_scale;
828  }
829 #endif
830 
831  /* round phantom points */
832  zone->cur[zone->n_points - 4].x =
833  FT_PIX_ROUND( zone->cur[zone->n_points - 4].x );
834  zone->cur[zone->n_points - 3].x =
835  FT_PIX_ROUND( zone->cur[zone->n_points - 3].x );
836  zone->cur[zone->n_points - 2].y =
837  FT_PIX_ROUND( zone->cur[zone->n_points - 2].y );
838  zone->cur[zone->n_points - 1].y =
839  FT_PIX_ROUND( zone->cur[zone->n_points - 1].y );
840 
841 #ifdef TT_USE_BYTECODE_INTERPRETER
842 
843  if ( n_ins > 0 )
844  {
845  FT_Error error;
846 
847  FT_GlyphLoader gloader = loader->gloader;
848  FT_Outline current_outline = gloader->current.outline;
849 
850 
851  TT_Set_CodeRange( loader->exec, tt_coderange_glyph,
852  loader->exec->glyphIns, n_ins );
853 
854  loader->exec->is_composite = is_composite;
855  loader->exec->pts = *zone;
856 
857  error = TT_Run_Context( loader->exec );
858  if ( error && loader->exec->pedantic_hinting )
859  return error;
860 
861  /* store drop-out mode in bits 5-7; set bit 2 also as a marker */
862  current_outline.tags[0] |=
863  ( loader->exec->GS.scan_type << 5 ) | FT_CURVE_TAG_HAS_SCANMODE;
864  }
865 
866 #endif
867 
868 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
869  /* Save possibly modified glyph phantom points unless in v40 backward */
870  /* compatibility mode, where no movement on the x axis means no reason */
871  /* to change bearings or advance widths. */
872  if ( !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
873  loader->exec->backward_compatibility ) )
874  {
875 #endif
876  loader->pp1 = zone->cur[zone->n_points - 4];
877  loader->pp2 = zone->cur[zone->n_points - 3];
878  loader->pp3 = zone->cur[zone->n_points - 2];
879  loader->pp4 = zone->cur[zone->n_points - 1];
880 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
881  }
882 #endif
883 
884 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
885  if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
886  {
887  if ( loader->exec->sph_tweak_flags & SPH_TWEAK_DEEMBOLDEN )
888  FT_Outline_EmboldenXY( &loader->gloader->current.outline, -24, 0 );
889 
890  else if ( loader->exec->sph_tweak_flags & SPH_TWEAK_EMBOLDEN )
891  FT_Outline_EmboldenXY( &loader->gloader->current.outline, 24, 0 );
892  }
893 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
894 
895  return FT_Err_Ok;
896  }
897 
898 
899  /*************************************************************************/
900  /* */
901  /* <Function> */
902  /* TT_Process_Simple_Glyph */
903  /* */
904  /* <Description> */
905  /* Once a simple glyph has been loaded, it needs to be processed. */
906  /* Usually, this means scaling and hinting through bytecode */
907  /* interpretation. */
908  /* */
909  static FT_Error
911  {
912  FT_GlyphLoader gloader = loader->gloader;
915  FT_Int n_points;
916 
917 
918  outline = &gloader->current.outline;
919  n_points = outline->n_points;
920 
921  /* set phantom points */
922 
923  outline->points[n_points ] = loader->pp1;
924  outline->points[n_points + 1] = loader->pp2;
925  outline->points[n_points + 2] = loader->pp3;
926  outline->points[n_points + 3] = loader->pp4;
927 
928  outline->tags[n_points ] = 0;
929  outline->tags[n_points + 1] = 0;
930  outline->tags[n_points + 2] = 0;
931  outline->tags[n_points + 3] = 0;
932 
933  n_points += 4;
934 
935 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
936 
937  if ( FT_IS_NAMED_INSTANCE( FT_FACE( loader->face ) ) ||
938  FT_IS_VARIATION( FT_FACE( loader->face ) ) )
939  {
940  /* Deltas apply to the unscaled data. */
941  error = TT_Vary_Apply_Glyph_Deltas( loader->face,
942  loader->glyph_index,
943  outline,
944  (FT_UInt)n_points );
945 
946  /* recalculate linear horizontal and vertical advances */
947  /* if we don't have HVAR and VVAR, respectively */
948  if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
949  loader->linear = outline->points[n_points - 3].x -
950  outline->points[n_points - 4].x;
951  if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
952  loader->vadvance = outline->points[n_points - 1].x -
953  outline->points[n_points - 2].x;
954 
955  if ( error )
956  return error;
957  }
958 
959 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
960 
961  if ( IS_HINTED( loader->load_flags ) )
962  {
963  tt_prepare_zone( &loader->zone, &gloader->current, 0, 0 );
964 
965  FT_ARRAY_COPY( loader->zone.orus, loader->zone.cur,
966  loader->zone.n_points + 4 );
967  }
968 
969  {
970 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
971  TT_Face face = loader->face;
973 
974  FT_String* family = face->root.family_name;
975  FT_UInt ppem = loader->size->metrics->x_ppem;
976  FT_String* style = face->root.style_name;
977  FT_UInt x_scale_factor = 1000;
978 #endif
979 
980  FT_Vector* vec = outline->points;
981  FT_Vector* limit = outline->points + n_points;
982 
983  FT_Fixed x_scale = 0; /* pacify compiler */
984  FT_Fixed y_scale = 0;
985 
986  FT_Bool do_scale = FALSE;
987 
988 
989 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
990 
991  if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
992  {
993  /* scale, but only if enabled and only if TT hinting is being used */
994  if ( IS_HINTED( loader->load_flags ) )
995  x_scale_factor = sph_test_tweak_x_scaling( face,
996  family,
997  ppem,
998  style,
999  loader->glyph_index );
1000  /* scale the glyph */
1001  if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 ||
1002  x_scale_factor != 1000 )
1003  {
1004  x_scale = FT_MulDiv( loader->size->metrics->x_scale,
1005  (FT_Long)x_scale_factor, 1000 );
1006  y_scale = loader->size->metrics->y_scale;
1007 
1008  /* compensate for any scaling by de/emboldening; */
1009  /* the amount was determined via experimentation */
1010  if ( x_scale_factor != 1000 && ppem > 11 )
1012  FT_MulFix( 1280 * ppem,
1013  1000 - x_scale_factor ),
1014  0 );
1015  do_scale = TRUE;
1016  }
1017  }
1018  else
1019 
1020 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
1021 
1022  {
1023  /* scale the glyph */
1024  if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1025  {
1026  x_scale = loader->size->metrics->x_scale;
1027  y_scale = loader->size->metrics->y_scale;
1028 
1029  do_scale = TRUE;
1030  }
1031  }
1032 
1033  if ( do_scale )
1034  {
1035  for ( ; vec < limit; vec++ )
1036  {
1037  vec->x = FT_MulFix( vec->x, x_scale );
1038  vec->y = FT_MulFix( vec->y, y_scale );
1039  }
1040  }
1041 
1042 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1043  /* if we have a HVAR table, `pp1' and/or `pp2' are already adjusted */
1044  if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) ||
1045  !IS_HINTED( loader->load_flags ) )
1046 #endif
1047  {
1048  loader->pp1 = outline->points[n_points - 4];
1049  loader->pp2 = outline->points[n_points - 3];
1050  }
1051 
1052 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1053  /* if we have a VVAR table, `pp3' and/or `pp4' are already adjusted */
1054  if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) ||
1055  !IS_HINTED( loader->load_flags ) )
1056 #endif
1057  {
1058  loader->pp3 = outline->points[n_points - 2];
1059  loader->pp4 = outline->points[n_points - 1];
1060  }
1061  }
1062 
1063  if ( IS_HINTED( loader->load_flags ) )
1064  {
1065  loader->zone.n_points += 4;
1066 
1067  error = TT_Hint_Glyph( loader, 0 );
1068  }
1069 
1070  return error;
1071  }
1072 
1073 
1074  /*************************************************************************/
1075  /* */
1076  /* <Function> */
1077  /* TT_Process_Composite_Component */
1078  /* */
1079  /* <Description> */
1080  /* Once a composite component has been loaded, it needs to be */
1081  /* processed. Usually, this means transforming and translating. */
1082  /* */
1083  static FT_Error
1085  FT_SubGlyph subglyph,
1086  FT_UInt start_point,
1087  FT_UInt num_base_points )
1088  {
1089  FT_GlyphLoader gloader = loader->gloader;
1091  FT_Bool have_scale;
1092  FT_Pos x, y;
1093 
1094 
1095  current.points = gloader->base.outline.points +
1096  num_base_points;
1097  current.n_points = gloader->base.outline.n_points -
1098  (short)num_base_points;
1099 
1100  have_scale = FT_BOOL( subglyph->flags & ( WE_HAVE_A_SCALE |
1102  WE_HAVE_A_2X2 ) );
1103 
1104  /* perform the transform required for this subglyph */
1105  if ( have_scale )
1106  FT_Outline_Transform( &current, &subglyph->transform );
1107 
1108  /* get offset */
1109  if ( !( subglyph->flags & ARGS_ARE_XY_VALUES ) )
1110  {
1111  FT_UInt num_points = (FT_UInt)gloader->base.outline.n_points;
1112  FT_UInt k = (FT_UInt)subglyph->arg1;
1113  FT_UInt l = (FT_UInt)subglyph->arg2;
1114  FT_Vector* p1;
1115  FT_Vector* p2;
1116 
1117 
1118  /* match l-th point of the newly loaded component to the k-th point */
1119  /* of the previously loaded components. */
1120 
1121  /* change to the point numbers used by our outline */
1122  k += start_point;
1123  l += num_base_points;
1124  if ( k >= num_base_points ||
1125  l >= num_points )
1126  return FT_THROW( Invalid_Composite );
1127 
1128  p1 = gloader->base.outline.points + k;
1129  p2 = gloader->base.outline.points + l;
1130 
1131  x = p1->x - p2->x;
1132  y = p1->y - p2->y;
1133  }
1134  else
1135  {
1136  x = subglyph->arg1;
1137  y = subglyph->arg2;
1138 
1139  if ( !x && !y )
1140  return FT_Err_Ok;
1141 
1142  /* Use a default value dependent on */
1143  /* TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED. This is useful for old */
1144  /* TT fonts which don't set the xxx_COMPONENT_OFFSET bit. */
1145 
1146  if ( have_scale &&
1147 #ifdef TT_CONFIG_OPTION_COMPONENT_OFFSET_SCALED
1148  !( subglyph->flags & UNSCALED_COMPONENT_OFFSET ) )
1149 #else
1150  ( subglyph->flags & SCALED_COMPONENT_OFFSET ) )
1151 #endif
1152  {
1153 
1154 #if 0
1155 
1156  /*******************************************************************/
1157  /* */
1158  /* This algorithm is what Apple documents. But it doesn't work. */
1159  /* */
1160  int a = subglyph->transform.xx > 0 ? subglyph->transform.xx
1161  : -subglyph->transform.xx;
1162  int b = subglyph->transform.yx > 0 ? subglyph->transform.yx
1163  : -subglyph->transform.yx;
1164  int c = subglyph->transform.xy > 0 ? subglyph->transform.xy
1165  : -subglyph->transform.xy;
1166  int d = subglyph->transform.yy > 0 ? subglyph->transform.yy
1167  : -subglyph->transform.yy;
1168  int m = a > b ? a : b;
1169  int n = c > d ? c : d;
1170 
1171 
1172  if ( a - b <= 33 && a - b >= -33 )
1173  m *= 2;
1174  if ( c - d <= 33 && c - d >= -33 )
1175  n *= 2;
1176  x = FT_MulFix( x, m );
1177  y = FT_MulFix( y, n );
1178 
1179 #else /* 1 */
1180 
1181  /*******************************************************************/
1182  /* */
1183  /* This algorithm is a guess and works much better than the above. */
1184  /* */
1185  FT_Fixed mac_xscale = FT_Hypot( subglyph->transform.xx,
1186  subglyph->transform.xy );
1187  FT_Fixed mac_yscale = FT_Hypot( subglyph->transform.yy,
1188  subglyph->transform.yx );
1189 
1190 
1191  x = FT_MulFix( x, mac_xscale );
1192  y = FT_MulFix( y, mac_yscale );
1193 
1194 #endif /* 1 */
1195 
1196  }
1197 
1198  if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
1199  {
1200  FT_Fixed x_scale = loader->size->metrics->x_scale;
1201  FT_Fixed y_scale = loader->size->metrics->y_scale;
1202 
1203 
1204  x = FT_MulFix( x, x_scale );
1205  y = FT_MulFix( y, y_scale );
1206 
1207  if ( subglyph->flags & ROUND_XY_TO_GRID )
1208  {
1209  TT_Face face = loader->face;
1211 
1212 
1213  if ( IS_HINTED( loader->load_flags ) )
1214  {
1215  /*
1216  * We round the horizontal offset only if there is hinting along
1217  * the x axis; this corresponds to integer advance width values.
1218  *
1219  * Theoretically, a glyph's bytecode can toggle ClearType's
1220  * `backward compatibility' mode, which would allow modification
1221  * of the advance width. In reality, however, applications
1222  * neither allow nor expect modified advance widths if sub-pixel
1223  * rendering is active.
1224  *
1225  */
1226  if ( driver->interpreter_version == TT_INTERPRETER_VERSION_35 )
1227  x = FT_PIX_ROUND( x );
1228 
1229  y = FT_PIX_ROUND( y );
1230  }
1231  }
1232  }
1233  }
1234 
1235  if ( x || y )
1237 
1238  return FT_Err_Ok;
1239  }
1240 
1241 
1242  /*************************************************************************/
1243  /* */
1244  /* <Function> */
1245  /* TT_Process_Composite_Glyph */
1246  /* */
1247  /* <Description> */
1248  /* This is slightly different from TT_Process_Simple_Glyph, in that */
1249  /* its sole purpose is to hint the glyph. Thus this function is */
1250  /* only available when bytecode interpreter is enabled. */
1251  /* */
1252  static FT_Error
1254  FT_UInt start_point,
1255  FT_UInt start_contour )
1256  {
1257  FT_Error error;
1259  FT_UInt i;
1260 
1261 
1262  outline = &loader->gloader->base.outline;
1263 
1264  /* make room for phantom points */
1266  outline->n_points + 4,
1267  0 );
1268  if ( error )
1269  return error;
1270 
1271  outline->points[outline->n_points ] = loader->pp1;
1272  outline->points[outline->n_points + 1] = loader->pp2;
1273  outline->points[outline->n_points + 2] = loader->pp3;
1274  outline->points[outline->n_points + 3] = loader->pp4;
1275 
1276  outline->tags[outline->n_points ] = 0;
1277  outline->tags[outline->n_points + 1] = 0;
1278  outline->tags[outline->n_points + 2] = 0;
1279  outline->tags[outline->n_points + 3] = 0;
1280 
1281 #ifdef TT_USE_BYTECODE_INTERPRETER
1282 
1283  {
1284  FT_Stream stream = loader->stream;
1285  FT_UShort n_ins, max_ins;
1286  FT_ULong tmp;
1287 
1288 
1289  /* TT_Load_Composite_Glyph only gives us the offset of instructions */
1290  /* so we read them here */
1291  if ( FT_STREAM_SEEK( loader->ins_pos ) ||
1292  FT_READ_USHORT( n_ins ) )
1293  return error;
1294 
1295  FT_TRACE5(( " Instructions size = %d\n", n_ins ));
1296 
1297  /* check it */
1298  max_ins = loader->face->max_profile.maxSizeOfInstructions;
1299  if ( n_ins > max_ins )
1300  {
1301  /* don't trust `maxSizeOfInstructions'; */
1302  /* only do a rough safety check */
1303  if ( (FT_Int)n_ins > loader->byte_len )
1304  {
1305  FT_TRACE1(( "TT_Process_Composite_Glyph:"
1306  " too many instructions (%d) for glyph with length %d\n",
1307  n_ins, loader->byte_len ));
1308  return FT_THROW( Too_Many_Hints );
1309  }
1310 
1311  tmp = loader->exec->glyphSize;
1312  error = Update_Max( loader->exec->memory,
1313  &tmp,
1314  sizeof ( FT_Byte ),
1315  (void*)&loader->exec->glyphIns,
1316  n_ins );
1317 
1318  loader->exec->glyphSize = (FT_UShort)tmp;
1319  if ( error )
1320  return error;
1321  }
1322  else if ( n_ins == 0 )
1323  return FT_Err_Ok;
1324 
1325  if ( FT_STREAM_READ( loader->exec->glyphIns, n_ins ) )
1326  return error;
1327 
1328  loader->glyph->control_data = loader->exec->glyphIns;
1329  loader->glyph->control_len = n_ins;
1330  }
1331 
1332 #endif
1333 
1334  tt_prepare_zone( &loader->zone, &loader->gloader->base,
1335  start_point, start_contour );
1336 
1337  /* Some points are likely touched during execution of */
1338  /* instructions on components. So let's untouch them. */
1339  for ( i = 0; i < loader->zone.n_points; i++ )
1340  loader->zone.tags[i] &= ~FT_CURVE_TAG_TOUCH_BOTH;
1341 
1342  loader->zone.n_points += 4;
1343 
1344  return TT_Hint_Glyph( loader, 1 );
1345  }
1346 
1347 
1348  /*
1349  * Calculate the phantom points
1350  *
1351  * Defining the right side bearing (rsb) as
1352  *
1353  * rsb = aw - (lsb + xmax - xmin)
1354  *
1355  * (with `aw' the advance width, `lsb' the left side bearing, and `xmin'
1356  * and `xmax' the glyph's minimum and maximum x value), the OpenType
1357  * specification defines the initial position of horizontal phantom points
1358  * as
1359  *
1360  * pp1 = (round(xmin - lsb), 0) ,
1361  * pp2 = (round(pp1 + aw), 0) .
1362  *
1363  * Note that the rounding to the grid (in the device space) is not
1364  * documented currently in the specification.
1365  *
1366  * However, the specification lacks the precise definition of vertical
1367  * phantom points. Greg Hitchcock provided the following explanation.
1368  *
1369  * - a `vmtx' table is present
1370  *
1371  * For any glyph, the minimum and maximum y values (`ymin' and `ymax')
1372  * are given in the `glyf' table, the top side bearing (tsb) and advance
1373  * height (ah) are given in the `vmtx' table. The bottom side bearing
1374  * (bsb) is then calculated as
1375  *
1376  * bsb = ah - (tsb + ymax - ymin) ,
1377  *
1378  * and the initial position of vertical phantom points is
1379  *
1380  * pp3 = (x, round(ymax + tsb)) ,
1381  * pp4 = (x, round(pp3 - ah)) .
1382  *
1383  * See below for value `x'.
1384  *
1385  * - no `vmtx' table in the font
1386  *
1387  * If there is an `OS/2' table, we set
1388  *
1389  * DefaultAscender = sTypoAscender ,
1390  * DefaultDescender = sTypoDescender ,
1391  *
1392  * otherwise we use data from the `hhea' table:
1393  *
1394  * DefaultAscender = Ascender ,
1395  * DefaultDescender = Descender .
1396  *
1397  * With these two variables we can now set
1398  *
1399  * ah = DefaultAscender - sDefaultDescender ,
1400  * tsb = DefaultAscender - yMax ,
1401  *
1402  * and proceed as if a `vmtx' table was present.
1403  *
1404  * Usually we have
1405  *
1406  * x = aw / 2 , (1)
1407  *
1408  * but there is one compatibility case where it can be set to
1409  *
1410  * x = -DefaultDescender -
1411  * ((DefaultAscender - DefaultDescender - aw) / 2) . (2)
1412  *
1413  * and another one with
1414  *
1415  * x = 0 . (3)
1416  *
1417  * In Windows, the history of those values is quite complicated,
1418  * depending on the hinting engine (that is, the graphics framework).
1419  *
1420  * framework from to formula
1421  * ----------------------------------------------------------
1422  * GDI Windows 98 current (1)
1423  * (Windows 2000 for NT)
1424  * GDI+ Windows XP Windows 7 (2)
1425  * GDI+ Windows 8 current (3)
1426  * DWrite Windows 7 current (3)
1427  *
1428  * For simplicity, FreeType uses (1) for grayscale subpixel hinting and
1429  * (3) for everything else.
1430  *
1431  */
1432  static void
1434  {
1435  FT_Bool subpixel_hinting = 0;
1436  FT_Bool grayscale = 0;
1437  FT_Bool use_aw_2 = 0;
1438 
1439 #ifdef TT_CONFIG_OPTION_SUBPIXEL_HINTING
1441 #endif
1442 
1443 
1444 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
1445  if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
1446  {
1447  subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting
1448  : 0;
1449  grayscale = loader->exec ? loader->exec->grayscale
1450  : 0;
1451  }
1452 #endif
1453 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
1454  if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
1455  {
1456  subpixel_hinting = loader->exec ? loader->exec->subpixel_hinting_lean
1457  : 0;
1458  grayscale = loader->exec ? loader->exec->grayscale_cleartype
1459  : 0;
1460  }
1461 #endif
1462 
1463  use_aw_2 = (FT_Bool)( subpixel_hinting && grayscale );
1464 
1465  loader->pp1.x = loader->bbox.xMin - loader->left_bearing;
1466  loader->pp1.y = 0;
1467  loader->pp2.x = loader->pp1.x + loader->advance;
1468  loader->pp2.y = 0;
1469 
1470  loader->pp3.x = use_aw_2 ? loader->advance / 2 : 0;
1471  loader->pp3.y = loader->bbox.yMax + loader->top_bearing;
1472  loader->pp4.x = use_aw_2 ? loader->advance / 2 : 0;
1473  loader->pp4.y = loader->pp3.y - loader->vadvance;
1474  }
1475 
1476 
1477  /* a utility function to retrieve i-th node from given FT_List */
1478  static FT_ListNode
1480  FT_UInt idx )
1481  {
1482  FT_ListNode cur;
1483 
1484 
1485  if ( !list )
1486  return NULL;
1487 
1488  for ( cur = list->head; cur; cur = cur->next )
1489  {
1490  if ( !idx )
1491  return cur;
1492 
1493  idx--;
1494  }
1495 
1496  return NULL;
1497  }
1498 
1499 
1500  /*************************************************************************/
1501  /* */
1502  /* <Function> */
1503  /* load_truetype_glyph */
1504  /* */
1505  /* <Description> */
1506  /* Loads a given truetype glyph. Handles composites and uses a */
1507  /* TT_Loader object. */
1508  /* */
1509  static FT_Error
1511  FT_UInt glyph_index,
1512  FT_UInt recurse_count,
1513  FT_Bool header_only )
1514  {
1516  FT_Fixed x_scale, y_scale;
1517  FT_ULong offset;
1518  TT_Face face = loader->face;
1519  FT_GlyphLoader gloader = loader->gloader;
1520  FT_Bool opened_frame = 0;
1521 
1522 #ifdef FT_CONFIG_OPTION_INCREMENTAL
1523  FT_StreamRec inc_stream;
1524  FT_Data glyph_data;
1525  FT_Bool glyph_data_loaded = 0;
1526 #endif
1527 
1528 
1529 #ifdef FT_DEBUG_LEVEL_TRACE
1530  if ( recurse_count )
1531  FT_TRACE5(( " nesting level: %d\n", recurse_count ));
1532 #endif
1533 
1534  /* some fonts have an incorrect value of `maxComponentDepth' */
1535  if ( recurse_count > face->max_profile.maxComponentDepth )
1536  {
1537  FT_TRACE1(( "load_truetype_glyph: maxComponentDepth set to %d\n",
1538  recurse_count ));
1539  face->max_profile.maxComponentDepth = (FT_UShort)recurse_count;
1540  }
1541 
1542 #ifndef FT_CONFIG_OPTION_INCREMENTAL
1543  /* check glyph index */
1544  if ( glyph_index >= (FT_UInt)face->root.num_glyphs )
1545  {
1546  error = FT_THROW( Invalid_Glyph_Index );
1547  goto Exit;
1548  }
1549 #endif
1550 
1551  loader->glyph_index = glyph_index;
1552 
1553  if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1554  {
1555  x_scale = loader->size->metrics->x_scale;
1556  y_scale = loader->size->metrics->y_scale;
1557  }
1558  else
1559  {
1560  x_scale = 0x10000L;
1561  y_scale = 0x10000L;
1562  }
1563 
1564  /* Set `offset' to the start of the glyph relative to the start of */
1565  /* the `glyf' table, and `byte_len' to the length of the glyph in */
1566  /* bytes. */
1567 
1568 #ifdef FT_CONFIG_OPTION_INCREMENTAL
1569 
1570  /* If we are loading glyph data via the incremental interface, set */
1571  /* the loader stream to a memory stream reading the data returned */
1572  /* by the interface. */
1573  if ( face->root.internal->incremental_interface )
1574  {
1575  error = face->root.internal->incremental_interface->funcs->get_glyph_data(
1576  face->root.internal->incremental_interface->object,
1577  glyph_index, &glyph_data );
1578  if ( error )
1579  goto Exit;
1580 
1581  glyph_data_loaded = 1;
1582  offset = 0;
1583  loader->byte_len = glyph_data.length;
1584 
1585  FT_ZERO( &inc_stream );
1586  FT_Stream_OpenMemory( &inc_stream,
1587  glyph_data.pointer,
1588  (FT_ULong)glyph_data.length );
1589 
1590  loader->stream = &inc_stream;
1591  }
1592  else
1593 
1594 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
1595 
1596  offset = tt_face_get_location( face, glyph_index,
1597  (FT_UInt*)&loader->byte_len );
1598 
1599  if ( loader->byte_len > 0 )
1600  {
1601 #ifdef FT_CONFIG_OPTION_INCREMENTAL
1602  /* for the incremental interface, `glyf_offset' is always zero */
1603  if ( !face->glyf_offset &&
1604  !face->root.internal->incremental_interface )
1605 #else
1606  if ( !face->glyf_offset )
1607 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
1608  {
1609  FT_TRACE2(( "no `glyf' table but non-zero `loca' entry\n" ));
1610  error = FT_THROW( Invalid_Table );
1611  goto Exit;
1612  }
1613 
1614  error = face->access_glyph_frame( loader, glyph_index,
1615  face->glyf_offset + offset,
1616  (FT_UInt)loader->byte_len );
1617  if ( error )
1618  goto Exit;
1619 
1620  opened_frame = 1;
1621 
1622  /* read glyph header first */
1623  error = face->read_glyph_header( loader );
1624  if ( error )
1625  goto Exit;
1626 
1627  /* the metrics must be computed after loading the glyph header */
1628  /* since we need the glyph's `yMax' value in case the vertical */
1629  /* metrics must be emulated */
1630  error = tt_get_metrics( loader, glyph_index );
1631  if ( error )
1632  goto Exit;
1633 
1634  if ( header_only )
1635  goto Exit;
1636  }
1637 
1638  if ( loader->byte_len == 0 || loader->n_contours == 0 )
1639  {
1640  loader->bbox.xMin = 0;
1641  loader->bbox.xMax = 0;
1642  loader->bbox.yMin = 0;
1643  loader->bbox.yMax = 0;
1644 
1645  error = tt_get_metrics( loader, glyph_index );
1646  if ( error )
1647  goto Exit;
1648 
1649  if ( header_only )
1650  goto Exit;
1651 
1652  /* must initialize points before (possibly) overriding */
1653  /* glyph metrics from the incremental interface */
1654  tt_loader_set_pp( loader );
1655 
1656 #ifdef FT_CONFIG_OPTION_INCREMENTAL
1657  tt_get_metrics_incr_overrides( loader, glyph_index );
1658 #endif
1659 
1660 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1661 
1662  if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
1663  FT_IS_VARIATION( FT_FACE( face ) ) )
1664  {
1665  /* a small outline structure with four elements for */
1666  /* communication with `TT_Vary_Apply_Glyph_Deltas' */
1667  FT_Vector points[4];
1668  char tags[4] = { 1, 1, 1, 1 };
1669  short contours[4] = { 0, 1, 2, 3 };
1671 
1672 
1673  points[0].x = loader->pp1.x;
1674  points[0].y = loader->pp1.y;
1675  points[1].x = loader->pp2.x;
1676  points[1].y = loader->pp2.y;
1677 
1678  points[2].x = loader->pp3.x;
1679  points[2].y = loader->pp3.y;
1680  points[3].x = loader->pp4.x;
1681  points[3].y = loader->pp4.y;
1682 
1683  outline.n_points = 4;
1684  outline.n_contours = 4;
1685  outline.points = points;
1686  outline.tags = tags;
1687  outline.contours = contours;
1688 
1689  /* this must be done before scaling */
1690  error = TT_Vary_Apply_Glyph_Deltas( loader->face,
1691  glyph_index,
1692  &outline,
1693  (FT_UInt)outline.n_points );
1694  if ( error )
1695  goto Exit;
1696 
1697  loader->pp1.x = points[0].x;
1698  loader->pp1.y = points[0].y;
1699  loader->pp2.x = points[1].x;
1700  loader->pp2.y = points[1].y;
1701 
1702  loader->pp3.x = points[2].x;
1703  loader->pp3.y = points[2].y;
1704  loader->pp4.x = points[3].x;
1705  loader->pp4.y = points[3].y;
1706 
1707 
1708  /* recalculate linear horizontal and vertical advances */
1709  /* if we don't have HVAR and VVAR, respectively */
1710  if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
1711  loader->linear = loader->pp2.x - loader->pp1.x;
1712  if ( !( loader->face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
1713  loader->vadvance = loader->pp4.x - loader->pp3.x;
1714  }
1715 
1716 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
1717 
1718  /* scale phantom points, if necessary; */
1719  /* they get rounded in `TT_Hint_Glyph' */
1720  if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1721  {
1722  loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
1723  loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
1724  /* pp1.y and pp2.y are always zero */
1725 
1726  loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale );
1727  loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
1728  loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale );
1729  loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
1730  }
1731 
1732  error = FT_Err_Ok;
1733  goto Exit;
1734  }
1735 
1736  /* must initialize phantom points before (possibly) overriding */
1737  /* glyph metrics from the incremental interface */
1738  tt_loader_set_pp( loader );
1739 
1740 #ifdef FT_CONFIG_OPTION_INCREMENTAL
1741  tt_get_metrics_incr_overrides( loader, glyph_index );
1742 #endif
1743 
1744  /***********************************************************************/
1745  /***********************************************************************/
1746  /***********************************************************************/
1747 
1748  /* if it is a simple glyph, load it */
1749 
1750  if ( loader->n_contours > 0 )
1751  {
1752  error = face->read_simple_glyph( loader );
1753  if ( error )
1754  goto Exit;
1755 
1756  /* all data have been read */
1757  face->forget_glyph_frame( loader );
1758  opened_frame = 0;
1759 
1760  error = TT_Process_Simple_Glyph( loader );
1761  if ( error )
1762  goto Exit;
1763 
1764  FT_GlyphLoader_Add( gloader );
1765  }
1766 
1767  /***********************************************************************/
1768  /***********************************************************************/
1769  /***********************************************************************/
1770 
1771  /* otherwise, load a composite! */
1772  else if ( loader->n_contours < 0 )
1773  {
1774  FT_Memory memory = face->root.memory;
1775 
1776  FT_UInt start_point;
1777  FT_UInt start_contour;
1778  FT_ULong ins_pos; /* position of composite instructions, if any */
1779 
1780  FT_ListNode node, node2;
1781 
1782 
1783  /* normalize the `n_contours' value */
1784  loader->n_contours = -1;
1785 
1786  /*
1787  * We store the glyph index directly in the `node->data' pointer,
1788  * following the glib solution (cf. macro `GUINT_TO_POINTER') with a
1789  * double cast to make this portable. Note, however, that this needs
1790  * pointers with a width of at least 32 bits.
1791  */
1792 
1793 
1794  /* clear the nodes filled by sibling chains */
1795  node = ft_list_get_node_at( &loader->composites, recurse_count );
1796  for ( node2 = node; node2; node2 = node2->next )
1797  node2->data = (void*)FT_ULONG_MAX;
1798 
1799  /* check whether we already have a composite glyph with this index */
1800  if ( FT_List_Find( &loader->composites,
1801  FT_UINT_TO_POINTER( glyph_index ) ) )
1802  {
1803  FT_TRACE1(( "TT_Load_Composite_Glyph:"
1804  " infinite recursion detected\n" ));
1805  error = FT_THROW( Invalid_Composite );
1806  goto Exit;
1807  }
1808 
1809  else if ( node )
1810  node->data = FT_UINT_TO_POINTER( glyph_index );
1811 
1812  else
1813  {
1814  if ( FT_NEW( node ) )
1815  goto Exit;
1816  node->data = FT_UINT_TO_POINTER( glyph_index );
1817  FT_List_Add( &loader->composites, node );
1818  }
1819 
1820  start_point = (FT_UInt)gloader->base.outline.n_points;
1821  start_contour = (FT_UInt)gloader->base.outline.n_contours;
1822 
1823  /* for each subglyph, read composite header */
1824  error = face->read_composite_glyph( loader );
1825  if ( error )
1826  goto Exit;
1827 
1828  /* store the offset of instructions */
1829  ins_pos = loader->ins_pos;
1830 
1831  /* all data we need are read */
1832  face->forget_glyph_frame( loader );
1833  opened_frame = 0;
1834 
1835 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
1836 
1837  if ( FT_IS_NAMED_INSTANCE( FT_FACE( face ) ) ||
1838  FT_IS_VARIATION( FT_FACE( face ) ) )
1839  {
1840  short i, limit;
1841  FT_SubGlyph subglyph;
1842 
1844  FT_Vector* points = NULL;
1845  char* tags = NULL;
1846  short* contours = NULL;
1847 
1848 
1849  limit = (short)gloader->current.num_subglyphs;
1850 
1851  /* construct an outline structure for */
1852  /* communication with `TT_Vary_Apply_Glyph_Deltas' */
1853  outline.n_points = (short)( gloader->current.num_subglyphs + 4 );
1854  outline.n_contours = outline.n_points;
1855 
1856  outline.points = NULL;
1857  outline.tags = NULL;
1858  outline.contours = NULL;
1859 
1860  if ( FT_NEW_ARRAY( points, outline.n_points ) ||
1861  FT_NEW_ARRAY( tags, outline.n_points ) ||
1862  FT_NEW_ARRAY( contours, outline.n_points ) )
1863  goto Exit1;
1864 
1865  subglyph = gloader->current.subglyphs;
1866 
1867  for ( i = 0; i < limit; i++, subglyph++ )
1868  {
1869  /* applying deltas for anchor points doesn't make sense, */
1870  /* but we don't have to specially check this since */
1871  /* unused delta values are zero anyways */
1872  points[i].x = subglyph->arg1;
1873  points[i].y = subglyph->arg2;
1874  tags[i] = 1;
1875  contours[i] = i;
1876  }
1877 
1878  points[i].x = loader->pp1.x;
1879  points[i].y = loader->pp1.y;
1880  tags[i] = 1;
1881  contours[i] = i;
1882 
1883  i++;
1884  points[i].x = loader->pp2.x;
1885  points[i].y = loader->pp2.y;
1886  tags[i] = 1;
1887  contours[i] = i;
1888 
1889  i++;
1890  points[i].x = loader->pp3.x;
1891  points[i].y = loader->pp3.y;
1892  tags[i] = 1;
1893  contours[i] = i;
1894 
1895  i++;
1896  points[i].x = loader->pp4.x;
1897  points[i].y = loader->pp4.y;
1898  tags[i] = 1;
1899  contours[i] = i;
1900 
1901  outline.points = points;
1902  outline.tags = tags;
1903  outline.contours = contours;
1904 
1905  /* this call provides additional offsets */
1906  /* for each component's translation */
1907  if ( FT_SET_ERROR( TT_Vary_Apply_Glyph_Deltas(
1908  face,
1909  glyph_index,
1910  &outline,
1911  (FT_UInt)outline.n_points ) ) )
1912  goto Exit1;
1913 
1914  subglyph = gloader->current.subglyphs;
1915 
1916  for ( i = 0; i < limit; i++, subglyph++ )
1917  {
1918  if ( subglyph->flags & ARGS_ARE_XY_VALUES )
1919  {
1920  subglyph->arg1 = (FT_Int16)points[i].x;
1921  subglyph->arg2 = (FT_Int16)points[i].y;
1922  }
1923  }
1924 
1925  loader->pp1.x = points[i + 0].x;
1926  loader->pp1.y = points[i + 0].y;
1927  loader->pp2.x = points[i + 1].x;
1928  loader->pp2.y = points[i + 1].y;
1929 
1930  loader->pp3.x = points[i + 2].x;
1931  loader->pp3.y = points[i + 2].y;
1932  loader->pp4.x = points[i + 3].x;
1933  loader->pp4.y = points[i + 3].y;
1934 
1935  /* recalculate linear horizontal and vertical advances */
1936  /* if we don't have HVAR and VVAR, respectively */
1937  if ( !( face->variation_support & TT_FACE_FLAG_VAR_HADVANCE ) )
1938  loader->linear = loader->pp2.x - loader->pp1.x;
1939  if ( !( face->variation_support & TT_FACE_FLAG_VAR_VADVANCE ) )
1940  loader->vadvance = loader->pp4.x - loader->pp3.x;
1941 
1942  Exit1:
1943  FT_FREE( outline.points );
1944  FT_FREE( outline.tags );
1945  FT_FREE( outline.contours );
1946 
1947  if ( error )
1948  goto Exit;
1949  }
1950 
1951 #endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */
1952 
1953  /* scale phantom points, if necessary; */
1954  /* they get rounded in `TT_Hint_Glyph' */
1955  if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
1956  {
1957  loader->pp1.x = FT_MulFix( loader->pp1.x, x_scale );
1958  loader->pp2.x = FT_MulFix( loader->pp2.x, x_scale );
1959  /* pp1.y and pp2.y are always zero */
1960 
1961  loader->pp3.x = FT_MulFix( loader->pp3.x, x_scale );
1962  loader->pp3.y = FT_MulFix( loader->pp3.y, y_scale );
1963  loader->pp4.x = FT_MulFix( loader->pp4.x, x_scale );
1964  loader->pp4.y = FT_MulFix( loader->pp4.y, y_scale );
1965  }
1966 
1967  /* if the flag FT_LOAD_NO_RECURSE is set, we return the subglyph */
1968  /* `as is' in the glyph slot (the client application will be */
1969  /* responsible for interpreting these data)... */
1970  if ( loader->load_flags & FT_LOAD_NO_RECURSE )
1971  {
1972  FT_GlyphLoader_Add( gloader );
1973  loader->glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
1974 
1975  goto Exit;
1976  }
1977 
1978  /*********************************************************************/
1979  /*********************************************************************/
1980  /*********************************************************************/
1981 
1982  {
1983  FT_UInt n, num_base_points;
1984  FT_SubGlyph subglyph = NULL;
1985 
1986  FT_UInt num_points = start_point;
1987  FT_UInt num_subglyphs = gloader->current.num_subglyphs;
1988  FT_UInt num_base_subgs = gloader->base.num_subglyphs;
1989 
1990  FT_Stream old_stream = loader->stream;
1991  FT_Int old_byte_len = loader->byte_len;
1992 
1993 
1994  FT_GlyphLoader_Add( gloader );
1995 
1996  /* read each subglyph independently */
1997  for ( n = 0; n < num_subglyphs; n++ )
1998  {
1999  FT_Vector pp[4];
2000 
2001  FT_Int linear_hadvance;
2002  FT_Int linear_vadvance;
2003 
2004 
2005  /* Each time we call load_truetype_glyph in this loop, the */
2006  /* value of `gloader.base.subglyphs' can change due to table */
2007  /* reallocations. We thus need to recompute the subglyph */
2008  /* pointer on each iteration. */
2009  subglyph = gloader->base.subglyphs + num_base_subgs + n;
2010 
2011  pp[0] = loader->pp1;
2012  pp[1] = loader->pp2;
2013  pp[2] = loader->pp3;
2014  pp[3] = loader->pp4;
2015 
2016  linear_hadvance = loader->linear;
2017  linear_vadvance = loader->vadvance;
2018 
2019  num_base_points = (FT_UInt)gloader->base.outline.n_points;
2020 
2021  error = load_truetype_glyph( loader,
2022  (FT_UInt)subglyph->index,
2023  recurse_count + 1,
2024  FALSE );
2025  if ( error )
2026  goto Exit;
2027 
2028  /* restore subglyph pointer */
2029  subglyph = gloader->base.subglyphs + num_base_subgs + n;
2030 
2031  /* restore phantom points if necessary */
2032  if ( !( subglyph->flags & USE_MY_METRICS ) )
2033  {
2034  loader->pp1 = pp[0];
2035  loader->pp2 = pp[1];
2036  loader->pp3 = pp[2];
2037  loader->pp4 = pp[3];
2038 
2039  loader->linear = linear_hadvance;
2040  loader->vadvance = linear_vadvance;
2041  }
2042 
2043  num_points = (FT_UInt)gloader->base.outline.n_points;
2044 
2045  if ( num_points == num_base_points )
2046  continue;
2047 
2048  /* gloader->base.outline consists of three parts: */
2049  /* 0 -(1)-> start_point -(2)-> num_base_points -(3)-> n_points. */
2050  /* */
2051  /* (1): exists from the beginning */
2052  /* (2): components that have been loaded so far */
2053  /* (3): the newly loaded component */
2055  subglyph,
2056  start_point,
2057  num_base_points );
2058  if ( error )
2059  goto Exit;
2060  }
2061 
2062  loader->stream = old_stream;
2063  loader->byte_len = old_byte_len;
2064 
2065  /* process the glyph */
2066  loader->ins_pos = ins_pos;
2067  if ( IS_HINTED( loader->load_flags ) &&
2069  subglyph->flags & WE_HAVE_INSTR &&
2070 #endif
2071  num_points > start_point )
2072  {
2074  start_point,
2075  start_contour );
2076  if ( error )
2077  goto Exit;
2078  }
2079  }
2080  }
2081 
2082  /***********************************************************************/
2083  /***********************************************************************/
2084  /***********************************************************************/
2085 
2086  Exit:
2087 
2088  if ( opened_frame )
2089  face->forget_glyph_frame( loader );
2090 
2091 #ifdef FT_CONFIG_OPTION_INCREMENTAL
2092 
2093  if ( glyph_data_loaded )
2094  face->root.internal->incremental_interface->funcs->free_glyph_data(
2095  face->root.internal->incremental_interface->object,
2096  &glyph_data );
2097 
2098 #endif
2099 
2100  return error;
2101  }
2102 
2103 
2104  static FT_Error
2106  FT_UInt glyph_index )
2107  {
2108  TT_Face face = loader->face;
2109 #if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
2110  defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
2112 #endif
2113 
2114  FT_BBox bbox;
2115  FT_Fixed y_scale;
2116  TT_GlyphSlot glyph = loader->glyph;
2117  TT_Size size = loader->size;
2118 
2119 
2120  y_scale = 0x10000L;
2121  if ( ( loader->load_flags & FT_LOAD_NO_SCALE ) == 0 )
2122  y_scale = size->metrics->y_scale;
2123 
2124  if ( glyph->format != FT_GLYPH_FORMAT_COMPOSITE )
2125  FT_Outline_Get_CBox( &glyph->outline, &bbox );
2126  else
2127  bbox = loader->bbox;
2128 
2129  /* get the device-independent horizontal advance; it is scaled later */
2130  /* by the base layer. */
2131  glyph->linearHoriAdvance = loader->linear;
2132 
2133  glyph->metrics.horiBearingX = bbox.xMin;
2134  glyph->metrics.horiBearingY = bbox.yMax;
2135  glyph->metrics.horiAdvance = loader->pp2.x - loader->pp1.x;
2136 
2137  /* Adjust advance width to the value contained in the hdmx table */
2138  /* unless FT_LOAD_COMPUTE_METRICS is set or backward compatibility */
2139  /* mode of the v40 interpreter is active. See `ttinterp.h' for */
2140  /* details on backward compatibility mode. */
2141  if (
2143  !( driver->interpreter_version == TT_INTERPRETER_VERSION_40 &&
2144  ( loader->exec && loader->exec->backward_compatibility ) ) &&
2145 #endif
2146  !face->postscript.isFixedPitch &&
2147  IS_HINTED( loader->load_flags ) &&
2148  !( loader->load_flags & FT_LOAD_COMPUTE_METRICS ) )
2149  {
2150  FT_Byte* widthp;
2151 
2152 
2153  widthp = tt_face_get_device_metrics( face,
2154  size->metrics->x_ppem,
2155  glyph_index );
2156 
2157 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
2158 
2159  if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
2160  {
2161  FT_Bool ignore_x_mode;
2162 
2163 
2164  ignore_x_mode = FT_BOOL( FT_LOAD_TARGET_MODE( loader->load_flags ) !=
2166 
2167  if ( widthp &&
2168  ( ( ignore_x_mode && loader->exec->compatible_widths ) ||
2169  !ignore_x_mode ||
2170  SPH_OPTION_BITMAP_WIDTHS ) )
2171  glyph->metrics.horiAdvance = *widthp * 64;
2172  }
2173  else
2174 
2175 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
2176 
2177  {
2178  if ( widthp )
2179  glyph->metrics.horiAdvance = *widthp * 64;
2180  }
2181  }
2182 
2183  /* set glyph dimensions */
2184  glyph->metrics.width = SUB_LONG( bbox.xMax, bbox.xMin );
2185  glyph->metrics.height = SUB_LONG( bbox.yMax, bbox.yMin );
2186 
2187  /* Now take care of vertical metrics. In the case where there is */
2188  /* no vertical information within the font (relatively common), */
2189  /* create some metrics manually */
2190  {
2191  FT_Pos top; /* scaled vertical top side bearing */
2192  FT_Pos advance; /* scaled vertical advance height */
2193 
2194 
2195  /* Get the unscaled top bearing and advance height. */
2196  if ( face->vertical_info &&
2197  face->vertical.number_Of_VMetrics > 0 )
2198  {
2199  top = (FT_Short)FT_DivFix( loader->pp3.y - bbox.yMax,
2200  y_scale );
2201 
2202  if ( loader->pp3.y <= loader->pp4.y )
2203  advance = 0;
2204  else
2205  advance = (FT_UShort)FT_DivFix( loader->pp3.y - loader->pp4.y,
2206  y_scale );
2207  }
2208  else
2209  {
2210  FT_Pos height;
2211 
2212 
2213  /* XXX Compute top side bearing and advance height in */
2214  /* Get_VMetrics instead of here. */
2215 
2216  /* NOTE: The OS/2 values are the only `portable' ones, */
2217  /* which is why we use them, if there is an OS/2 */
2218  /* table in the font. Otherwise, we use the */
2219  /* values defined in the horizontal header. */
2220 
2222  bbox.yMin ),
2223  y_scale );
2224  if ( face->os2.version != 0xFFFFU )
2225  advance = (FT_Pos)( face->os2.sTypoAscender -
2226  face->os2.sTypoDescender );
2227  else
2228  advance = (FT_Pos)( face->horizontal.Ascender -
2229  face->horizontal.Descender );
2230 
2231  top = ( advance - height ) / 2;
2232  }
2233 
2234 #ifdef FT_CONFIG_OPTION_INCREMENTAL
2235  {
2237  FT_Incremental_MetricsRec incr_metrics;
2238  FT_Error error;
2239 
2240 
2241  incr = face->root.internal->incremental_interface;
2242 
2243  /* If this is an incrementally loaded font see if there are */
2244  /* overriding metrics for this glyph. */
2245  if ( incr && incr->funcs->get_glyph_metrics )
2246  {
2247  incr_metrics.bearing_x = 0;
2248  incr_metrics.bearing_y = top;
2249  incr_metrics.advance = advance;
2250 
2251  error = incr->funcs->get_glyph_metrics( incr->object,
2252  glyph_index,
2253  TRUE,
2254  &incr_metrics );
2255  if ( error )
2256  return error;
2257 
2258  top = incr_metrics.bearing_y;
2259  advance = incr_metrics.advance;
2260  }
2261  }
2262 
2263  /* GWW: Do vertical metrics get loaded incrementally too? */
2264 
2265 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
2266 
2267  glyph->linearVertAdvance = advance;
2268 
2269  /* scale the metrics */
2270  if ( !( loader->load_flags & FT_LOAD_NO_SCALE ) )
2271  {
2272  top = FT_MulFix( top, y_scale );
2273  advance = FT_MulFix( advance, y_scale );
2274  }
2275 
2276  /* XXX: for now, we have no better algorithm for the lsb, but it */
2277  /* should work fine. */
2278  /* */
2279  glyph->metrics.vertBearingX = glyph->metrics.horiBearingX -
2280  glyph->metrics.horiAdvance / 2;
2281  glyph->metrics.vertBearingY = top;
2282  glyph->metrics.vertAdvance = advance;
2283  }
2284 
2285  return 0;
2286  }
2287 
2288 
2289 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
2290 
2291  static FT_Error
2292  load_sbit_image( TT_Size size,
2293  TT_GlyphSlot glyph,
2294  FT_UInt glyph_index,
2295  FT_Int32 load_flags )
2296  {
2297  TT_Face face;
2299  FT_Stream stream;
2300  FT_Error error;
2301  TT_SBit_MetricsRec sbit_metrics;
2302 
2303 
2304  face = (TT_Face)glyph->face;
2305  sfnt = (SFNT_Service)face->sfnt;
2306  stream = face->root.stream;
2307 
2309  size->strike_index,
2310  glyph_index,
2311  (FT_UInt)load_flags,
2312  stream,
2313  &glyph->bitmap,
2314  &sbit_metrics );
2315  if ( !error )
2316  {
2317  glyph->outline.n_points = 0;
2318  glyph->outline.n_contours = 0;
2319 
2320  glyph->metrics.width = (FT_Pos)sbit_metrics.width * 64;
2321  glyph->metrics.height = (FT_Pos)sbit_metrics.height * 64;
2322 
2323  glyph->metrics.horiBearingX = (FT_Pos)sbit_metrics.horiBearingX * 64;
2324  glyph->metrics.horiBearingY = (FT_Pos)sbit_metrics.horiBearingY * 64;
2325  glyph->metrics.horiAdvance = (FT_Pos)sbit_metrics.horiAdvance * 64;
2326 
2327  glyph->metrics.vertBearingX = (FT_Pos)sbit_metrics.vertBearingX * 64;
2328  glyph->metrics.vertBearingY = (FT_Pos)sbit_metrics.vertBearingY * 64;
2329  glyph->metrics.vertAdvance = (FT_Pos)sbit_metrics.vertAdvance * 64;
2330 
2331  glyph->format = FT_GLYPH_FORMAT_BITMAP;
2332 
2333  if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
2334  {
2335  glyph->bitmap_left = sbit_metrics.vertBearingX;
2336  glyph->bitmap_top = sbit_metrics.vertBearingY;
2337  }
2338  else
2339  {
2340  glyph->bitmap_left = sbit_metrics.horiBearingX;
2341  glyph->bitmap_top = sbit_metrics.horiBearingY;
2342  }
2343  }
2344 
2345  return error;
2346  }
2347 
2348 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
2349 
2350 
2351  static FT_Error
2353  TT_Size size,
2354  TT_GlyphSlot glyph,
2355  FT_Int32 load_flags,
2356  FT_Bool glyf_table_only )
2357  {
2358  TT_Face face;
2359  FT_Stream stream;
2360 
2361 #ifdef TT_USE_BYTECODE_INTERPRETER
2362  FT_Error error;
2363  FT_Bool pedantic = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
2364 #if defined TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY || \
2365  defined TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
2367 #endif
2368 #endif
2369 
2370 
2371  face = (TT_Face)glyph->face;
2372  stream = face->root.stream;
2373 
2374  FT_ZERO( loader );
2375 
2376 #ifdef TT_USE_BYTECODE_INTERPRETER
2377 
2378  /* load execution context */
2379  if ( IS_HINTED( load_flags ) && !glyf_table_only )
2380  {
2381  TT_ExecContext exec;
2382  FT_Bool grayscale = TRUE;
2383 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
2384  FT_Bool subpixel_hinting_lean;
2385  FT_Bool grayscale_cleartype;
2386 #endif
2387 
2388 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
2389  FT_Bool subpixel_hinting = FALSE;
2390 
2391 #if 0
2392  /* not used yet */
2393  FT_Bool compatible_widths;
2394  FT_Bool symmetrical_smoothing;
2395  FT_Bool bgr;
2396  FT_Bool vertical_lcd;
2397  FT_Bool subpixel_positioned;
2398  FT_Bool gray_cleartype;
2399 #endif
2400 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
2401 
2402  FT_Bool reexecute = FALSE;
2403 
2404 
2405  if ( size->bytecode_ready < 0 || size->cvt_ready < 0 )
2406  {
2407  error = tt_size_ready_bytecode( size, pedantic );
2408  if ( error )
2409  return error;
2410  }
2411  else if ( size->bytecode_ready )
2412  return size->bytecode_ready;
2413  else if ( size->cvt_ready )
2414  return size->cvt_ready;
2415 
2416  /* query new execution context */
2417  exec = size->context;
2418  if ( !exec )
2419  return FT_THROW( Could_Not_Find_Context );
2420 
2421 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
2422  if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
2423  {
2424  subpixel_hinting_lean =
2425  FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2427  grayscale_cleartype =
2428  FT_BOOL( subpixel_hinting_lean &&
2429  !( ( load_flags &
2430  FT_LOAD_TARGET_LCD ) ||
2431  ( load_flags &
2432  FT_LOAD_TARGET_LCD_V ) ) );
2433  exec->vertical_lcd_lean =
2434  FT_BOOL( subpixel_hinting_lean &&
2435  ( load_flags &
2437  }
2438  else
2439  {
2440  subpixel_hinting_lean = FALSE;
2441  grayscale_cleartype = FALSE;
2442  exec->vertical_lcd_lean = FALSE;
2443  }
2444 #endif
2445 
2446 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
2447 
2448  if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
2449  {
2450  subpixel_hinting = FT_BOOL( ( FT_LOAD_TARGET_MODE( load_flags ) !=
2451  FT_RENDER_MODE_MONO ) &&
2452  SPH_OPTION_SET_SUBPIXEL );
2453 
2454  if ( subpixel_hinting )
2455  grayscale = FALSE;
2456  else if ( SPH_OPTION_SET_GRAYSCALE )
2457  {
2458  grayscale = TRUE;
2459  subpixel_hinting = FALSE;
2460  }
2461  else
2462  grayscale = FALSE;
2463 
2464  if ( FT_IS_TRICKY( glyph->face ) )
2465  subpixel_hinting = FALSE;
2466 
2467  exec->ignore_x_mode = subpixel_hinting || grayscale;
2468  exec->rasterizer_version = SPH_OPTION_SET_RASTERIZER_VERSION;
2469  if ( exec->sph_tweak_flags & SPH_TWEAK_RASTERIZER_35 )
2470  exec->rasterizer_version = TT_INTERPRETER_VERSION_35;
2471 
2472 #if 1
2473  exec->compatible_widths = SPH_OPTION_SET_COMPATIBLE_WIDTHS;
2474  exec->symmetrical_smoothing = TRUE;
2475  exec->bgr = FALSE;
2476  exec->vertical_lcd = FALSE;
2477  exec->subpixel_positioned = TRUE;
2478  exec->gray_cleartype = FALSE;
2479 #else /* 0 */
2480  exec->compatible_widths =
2481  FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2482  TT_LOAD_COMPATIBLE_WIDTHS );
2483  exec->symmetrical_smoothing =
2484  FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2485  TT_LOAD_SYMMETRICAL_SMOOTHING );
2486  exec->bgr =
2487  FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2488  TT_LOAD_BGR );
2489  exec->vertical_lcd =
2490  FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2491  TT_LOAD_VERTICAL_LCD );
2492  exec->subpixel_positioned =
2493  FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2494  TT_LOAD_SUBPIXEL_POSITIONED );
2495  exec->gray_cleartype =
2496  FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2497  TT_LOAD_GRAY_CLEARTYPE );
2498 #endif /* 0 */
2499 
2500  }
2501  else
2502 
2503 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
2504 
2505 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
2506  if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
2507  grayscale = FT_BOOL( !subpixel_hinting_lean &&
2508  FT_LOAD_TARGET_MODE( load_flags ) !=
2510  else
2511 #endif
2512  grayscale = FT_BOOL( FT_LOAD_TARGET_MODE( load_flags ) !=
2514 
2515  error = TT_Load_Context( exec, face, size );
2516  if ( error )
2517  return error;
2518 
2519 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
2520 
2521  if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 )
2522  {
2523  /* a change from mono to subpixel rendering (and vice versa) */
2524  /* requires a re-execution of the CVT program */
2525  if ( subpixel_hinting != exec->subpixel_hinting )
2526  {
2527  FT_TRACE4(( "tt_loader_init: subpixel hinting change,"
2528  " re-executing `prep' table\n" ));
2529 
2530  exec->subpixel_hinting = subpixel_hinting;
2531  reexecute = TRUE;
2532  }
2533 
2534  /* a change from mono to grayscale rendering (and vice versa) */
2535  /* requires a re-execution of the CVT program */
2536  if ( grayscale != exec->grayscale )
2537  {
2538  FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
2539  " re-executing `prep' table\n" ));
2540 
2541  exec->grayscale = grayscale;
2542  reexecute = TRUE;
2543  }
2544  }
2545  else
2546 
2547 #endif /* TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY */
2548 
2549  {
2550 
2551 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
2552  if ( driver->interpreter_version == TT_INTERPRETER_VERSION_40 )
2553  {
2554  /* a change from mono to subpixel rendering (and vice versa) */
2555  /* requires a re-execution of the CVT program */
2556  if ( subpixel_hinting_lean != exec->subpixel_hinting_lean )
2557  {
2558  FT_TRACE4(( "tt_loader_init: subpixel hinting change,"
2559  " re-executing `prep' table\n" ));
2560 
2561  exec->subpixel_hinting_lean = subpixel_hinting_lean;
2562  reexecute = TRUE;
2563  }
2564 
2565  /* a change from colored to grayscale subpixel rendering (and */
2566  /* vice versa) requires a re-execution of the CVT program */
2567  if ( grayscale_cleartype != exec->grayscale_cleartype )
2568  {
2569  FT_TRACE4(( "tt_loader_init: grayscale subpixel hinting change,"
2570  " re-executing `prep' table\n" ));
2571 
2572  exec->grayscale_cleartype = grayscale_cleartype;
2573  reexecute = TRUE;
2574  }
2575  }
2576 #endif
2577 
2578  /* a change from mono to grayscale rendering (and vice versa) */
2579  /* requires a re-execution of the CVT program */
2580  if ( grayscale != exec->grayscale )
2581  {
2582  FT_TRACE4(( "tt_loader_init: grayscale hinting change,"
2583  " re-executing `prep' table\n" ));
2584 
2585  exec->grayscale = grayscale;
2586  reexecute = TRUE;
2587  }
2588  }
2589 
2590  if ( reexecute )
2591  {
2592  FT_UInt i;
2593 
2594 
2595  for ( i = 0; i < size->cvt_size; i++ )
2596  size->cvt[i] = FT_MulFix( face->cvt[i], size->ttmetrics.scale );
2597  error = tt_size_run_prep( size, pedantic );
2598  if ( error )
2599  return error;
2600  }
2601 
2602  /* check whether the cvt program has disabled hinting */
2603  if ( exec->GS.instruct_control & 1 )
2604  load_flags |= FT_LOAD_NO_HINTING;
2605 
2606  /* load default graphics state -- if needed */
2607  if ( exec->GS.instruct_control & 2 )
2608  exec->GS = tt_default_graphics_state;
2609 
2610 #ifdef TT_SUPPORT_SUBPIXEL_HINTING_INFINALITY
2611  /* check whether we have a font hinted for ClearType -- */
2612  /* note that this flag can also be modified in a glyph's bytecode */
2613  if ( driver->interpreter_version == TT_INTERPRETER_VERSION_38 &&
2614  exec->GS.instruct_control & 4 )
2615  exec->ignore_x_mode = 0;
2616 #endif
2617 
2618  exec->pedantic_hinting = FT_BOOL( load_flags & FT_LOAD_PEDANTIC );
2619  loader->exec = exec;
2620  loader->instructions = exec->glyphIns;
2621  }
2622 
2623 #endif /* TT_USE_BYTECODE_INTERPRETER */
2624 
2625  /* get face's glyph loader */
2626  if ( !glyf_table_only )
2627  {
2628  FT_GlyphLoader gloader = glyph->internal->loader;
2629 
2630 
2631  FT_GlyphLoader_Rewind( gloader );
2632  loader->gloader = gloader;
2633  }
2634 
2635  loader->load_flags = (FT_ULong)load_flags;
2636 
2637  loader->face = face;
2638  loader->size = size;
2639  loader->glyph = (FT_GlyphSlot)glyph;
2640  loader->stream = stream;
2641 
2642  loader->composites.head = NULL;
2643  loader->composites.tail = NULL;
2644 
2645  return FT_Err_Ok;
2646  }
2647 
2648 
2649  static void
2651  {
2652  FT_List_Finalize( &loader->composites,
2653  NULL,
2654  loader->face->root.memory,
2655  NULL );
2656  }
2657 
2658 
2659  /*************************************************************************/
2660  /* */
2661  /* <Function> */
2662  /* TT_Load_Glyph */
2663  /* */
2664  /* <Description> */
2665  /* A function used to load a single glyph within a given glyph slot, */
2666  /* for a given size. */
2667  /* */
2668  /* <Input> */
2669  /* glyph :: A handle to a target slot object where the glyph */
2670  /* will be loaded. */
2671  /* */
2672  /* size :: A handle to the source face size at which the glyph */
2673  /* must be scaled/loaded. */
2674  /* */
2675  /* glyph_index :: The index of the glyph in the font file. */
2676  /* */
2677  /* load_flags :: A flag indicating what to load for this glyph. The */
2678  /* FT_LOAD_XXX constants can be used to control the */
2679  /* glyph loading process (e.g., whether the outline */
2680  /* should be scaled, whether to load bitmaps or not, */
2681  /* whether to hint the outline, etc). */
2682  /* */
2683  /* <Return> */
2684  /* FreeType error code. 0 means success. */
2685  /* */
2688  TT_GlyphSlot glyph,
2689  FT_UInt glyph_index,
2690  FT_Int32 load_flags )
2691  {
2692  FT_Error error;
2693  TT_LoaderRec loader;
2694 
2695 #ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT
2696 #define IS_DEFAULT_INSTANCE ( !( FT_IS_NAMED_INSTANCE( glyph->face ) || \
2697  FT_IS_VARIATION( glyph->face ) ) )
2698 #else
2699 #define IS_DEFAULT_INSTANCE 1
2700 #endif
2701 
2702 
2703  FT_TRACE1(( "TT_Load_Glyph: glyph index %d\n", glyph_index ));
2704 
2705 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
2706 
2707  /* try to load embedded bitmap (if any) */
2708  if ( size->strike_index != 0xFFFFFFFFUL &&
2709  ( load_flags & FT_LOAD_NO_BITMAP ) == 0 &&
2711  {
2712  error = load_sbit_image( size, glyph, glyph_index, load_flags );
2713  if ( FT_ERR_EQ( error, Missing_Bitmap ) )
2714  {
2715  /* the bitmap strike is incomplete and misses the requested glyph; */
2716  /* if we have a bitmap-only font, return an empty glyph */
2717  if ( !FT_IS_SCALABLE( glyph->face ) )
2718  {
2719  TT_Face face = (TT_Face)glyph->face;
2720  FT_Short left_bearing = 0, top_bearing = 0;
2721  FT_UShort advance_width = 0, advance_height = 0;
2722 
2723 
2724  /* to return an empty glyph, however, we need metrics data */
2725  /* from the `hmtx' (or `vmtx') table; the assumption is that */
2726  /* empty glyphs are missing intentionally, representing */
2727  /* whitespace - not having at least horizontal metrics is */
2728  /* thus considered an error */
2729  if ( !face->horz_metrics_size )
2730  return error;
2731 
2732  /* we now construct an empty bitmap glyph */
2733  TT_Get_HMetrics( face, glyph_index,
2734  &left_bearing,
2735  &advance_width );
2736  TT_Get_VMetrics( face, glyph_index,
2737  0,
2738  &top_bearing,
2739  &advance_height );
2740 
2741  glyph->outline.n_points = 0;
2742  glyph->outline.n_contours = 0;
2743 
2744  glyph->metrics.width = 0;
2745  glyph->metrics.height = 0;
2746 
2747  glyph->metrics.horiBearingX = left_bearing;
2748  glyph->metrics.horiBearingY = 0;
2749  glyph->metrics.horiAdvance = advance_width;
2750 
2751  glyph->metrics.vertBearingX = 0;
2752  glyph->metrics.vertBearingY = top_bearing;
2753  glyph->metrics.vertAdvance = advance_height;
2754 
2755  glyph->format = FT_GLYPH_FORMAT_BITMAP;
2756  glyph->bitmap.pixel_mode = FT_PIXEL_MODE_MONO;
2757 
2758  glyph->bitmap_left = 0;
2759  glyph->bitmap_top = 0;
2760 
2761  return FT_Err_Ok;
2762  }
2763  }
2764  else if ( error )
2765  {
2766  /* return error if font is not scalable */
2767  if ( !FT_IS_SCALABLE( glyph->face ) )
2768  return error;
2769  }
2770  else
2771  {
2772  if ( FT_IS_SCALABLE( glyph->face ) )
2773  {
2774  /* for the bbox we need the header only */
2775  (void)tt_loader_init( &loader, size, glyph, load_flags, TRUE );
2776  (void)load_truetype_glyph( &loader, glyph_index, 0, TRUE );
2777  tt_loader_done( &loader );
2778  glyph->linearHoriAdvance = loader.linear;
2779  glyph->linearVertAdvance = loader.vadvance;
2780 
2781  /* sanity checks: if `xxxAdvance' in the sbit metric */
2782  /* structure isn't set, use `linearXXXAdvance' */
2783  if ( !glyph->metrics.horiAdvance && glyph->linearHoriAdvance )
2784  glyph->metrics.horiAdvance =
2785  FT_MulFix( glyph->linearHoriAdvance,
2786  size->metrics->x_scale );
2787  if ( !glyph->metrics.vertAdvance && glyph->linearVertAdvance )
2788  glyph->metrics.vertAdvance =
2789  FT_MulFix( glyph->linearVertAdvance,
2790  size->metrics->y_scale );
2791  }
2792 
2793  return FT_Err_Ok;
2794  }
2795  }
2796 
2797 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
2798 
2799  /* if FT_LOAD_NO_SCALE is not set, `ttmetrics' must be valid */
2800  if ( !( load_flags & FT_LOAD_NO_SCALE ) && !size->ttmetrics.valid )
2801  {
2802  error = FT_THROW( Invalid_Size_Handle );
2803  goto Exit;
2804  }
2805 
2806  if ( load_flags & FT_LOAD_SBITS_ONLY )
2807  {
2808  error = FT_THROW( Invalid_Argument );
2809  goto Exit;
2810  }
2811 
2812  error = tt_loader_init( &loader, size, glyph, load_flags, FALSE );
2813  if ( error )
2814  goto Exit;
2815 
2816  glyph->format = FT_GLYPH_FORMAT_OUTLINE;
2817  glyph->num_subglyphs = 0;
2818  glyph->outline.flags = 0;
2819 
2820  /* main loading loop */
2821  error = load_truetype_glyph( &loader, glyph_index, 0, FALSE );
2822  if ( !error )
2823  {
2824  if ( glyph->format == FT_GLYPH_FORMAT_COMPOSITE )
2825  {
2826  glyph->num_subglyphs = loader.gloader->base.num_subglyphs;
2827  glyph->subglyphs = loader.gloader->base.subglyphs;
2828  }
2829  else
2830  {
2831  glyph->outline = loader.gloader->base.outline;
2832  glyph->outline.flags &= ~FT_OUTLINE_SINGLE_PASS;
2833 
2834  /* Translate array so that (0,0) is the glyph's origin. Note */
2835  /* that this behaviour is independent on the value of bit 1 of */
2836  /* the `flags' field in the `head' table -- at least major */
2837  /* applications like Acroread indicate that. */
2838  if ( loader.pp1.x )
2839  FT_Outline_Translate( &glyph->outline, -loader.pp1.x, 0 );
2840  }
2841 
2842 #ifdef TT_USE_BYTECODE_INTERPRETER
2843 
2844  if ( IS_HINTED( load_flags ) )
2845  {
2846  if ( loader.exec->GS.scan_control )
2847  {
2848  /* convert scan conversion mode to FT_OUTLINE_XXX flags */
2849  switch ( loader.exec->GS.scan_type )
2850  {
2851  case 0: /* simple drop-outs including stubs */
2852  glyph->outline.flags |= FT_OUTLINE_INCLUDE_STUBS;
2853  break;
2854  case 1: /* simple drop-outs excluding stubs */
2855  /* nothing; it's the default rendering mode */
2856  break;
2857  case 4: /* smart drop-outs including stubs */
2858  glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS |
2860  break;
2861  case 5: /* smart drop-outs excluding stubs */
2862  glyph->outline.flags |= FT_OUTLINE_SMART_DROPOUTS;
2863  break;
2864 
2865  default: /* no drop-out control */
2866  glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS;
2867  break;
2868  }
2869  }
2870  else
2871  glyph->outline.flags |= FT_OUTLINE_IGNORE_DROPOUTS;
2872  }
2873 
2874 #endif /* TT_USE_BYTECODE_INTERPRETER */
2875 
2876  error = compute_glyph_metrics( &loader, glyph_index );
2877  }
2878 
2879  tt_loader_done( &loader );
2880 
2881  /* Set the `high precision' bit flag. */
2882  /* This is _critical_ to get correct output for monochrome */
2883  /* TrueType glyphs at all sizes using the bytecode interpreter. */
2884  /* */
2885  if ( !( load_flags & FT_LOAD_NO_SCALE ) &&
2886  size->metrics->y_ppem < 24 )
2887  glyph->outline.flags |= FT_OUTLINE_HIGH_PRECISION;
2888 
2889  Exit:
2890 #ifdef FT_DEBUG_LEVEL_TRACE
2891  if ( error )
2892  FT_TRACE1(( " failed (error code 0x%x)\n",
2893  error ));
2894 #endif
2895 
2896  return error;
2897  }
2898 
2899 
2900 /* END */
#define UNSCALED_COMPONENT_OFFSET
Definition: ttgload.c:67
const TT_GraphicsState tt_default_graphics_state
TT_Load_Glyph_Header(TT_Loader loader)
Definition: ttgload.c:298
FT_Int arg2
Definition: ftgloadr.h:44
FT_Int length
Definition: fttypes.h:409
static FT_Error tt_get_metrics(TT_Loader loader, FT_UInt glyph_index)
Definition: ttgload.c:122
#define FT_OUTLINE_SINGLE_PASS
Definition: ftimage.h:436
FT_Int vadvance
Definition: tttypes.h:1670
int FT_Error
Definition: fttypes.h:300
#define FT_LOAD_VERTICAL_LAYOUT
Definition: freetype.h:3013
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:608
FT_UShort height
Definition: tttypes.h:461
FT_Vector pp4
Definition: tttypes.h:1672
#define TT_FACE_FLAG_VAR_HADVANCE
Definition: tttypes.h:1113
FT_Pos y
Definition: ftimage.h:77
FT_Int scan_type
Definition: ttobjs.h:92
signed long FT_Long
Definition: fttypes.h:242
#define TRUE
Definition: types.h:120
SFNT_Interface * SFNT_Service
Definition: sfnt.h:628
const char * tags[7 *8]
Definition: apphelp.c:214
char * tags
Definition: ftimage.h:340
unsigned long FT_ULong
Definition: fttypes.h:253
FT_UShort vertAdvance
Definition: tttypes.h:470
#define FT_LOAD_SBITS_ONLY
Definition: freetype.h:3032
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
struct png_info_def **typedef void(__cdecl typeof(png_destroy_read_struct))(struct png_struct_def **
Definition: typeof.h:49
#define error(str)
Definition: mkdosfs.c:1605
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
#define IS_DEFAULT_INSTANCE
FT_ListNode next
Definition: fttypes.h:547
FT_Matrix transform
Definition: ftgloadr.h:45
FT_Pos x
Definition: ftimage.h:76
FT_ListNode tail
Definition: fttypes.h:570
FT_UShort x_ppem
Definition: freetype.h:1640
FT_Int top_bearing
Definition: tttypes.h:1669
#define FT_OUTLINE_IGNORE_DROPOUTS
Definition: ftimage.h:431
signed int FT_Int
Definition: fttypes.h:220
FT_Vector * orus
Definition: tttypes.h:1609
#define FT_ARRAY_COPY(dest, source, count)
Definition: ftmemory.h:244
FT_Fixed y_scale
Definition: freetype.h:1644
SFNT_Service sfnt
Definition: ttdriver.c:206
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define FT_ABS(a)
Definition: ftobjs.h:74
FT_Bool grayscale
Definition: ttinterp.h:251
FT_BBox bbox
Definition: ftbbox.c:446
#define SCALED_COMPONENT_OFFSET
Definition: ttgload.c:66
#define FT_CURVE_TAG_TOUCH_BOTH
Definition: ftimage.h:462
FT_Glyph_Metrics metrics
Definition: freetype.h:1916
#define FT_ULONG_MAX
Definition: ftstdlib.h:68
FT_Int arg1
Definition: ftgloadr.h:43
GLintptr offset
Definition: glext.h:5920
FT_Fixed linearHoriAdvance
Definition: freetype.h:1917
#define FT_LOAD_NO_HINTING
Definition: freetype.h:3010
FT_List_Finalize(FT_List list, FT_List_Destructor destroy, FT_Memory memory, void *user)
Definition: ftutil.c:413
GLdouble n
Definition: glext.h:7729
FT_SubGlyph subglyphs
Definition: ftgloadr.h:56
#define FT_NEXT_BYTE(buffer)
Definition: ftstream.h:220
FT_Bool is_composite
Definition: ttinterp.h:229
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
void * data
Definition: fttypes.h:548
#define FT_LOAD_NO_RECURSE
Definition: freetype.h:3018
#define FT_LOAD_PEDANTIC
Definition: freetype.h:3016
FT_Int linear
Definition: tttypes.h:1652
TT_Init_Glyph_Loading(TT_Face face)
Definition: ttgload.c:742
FT_ListNode head
Definition: fttypes.h:569
FT_Fixed linearVertAdvance
Definition: freetype.h:1918
const FT_Byte * pointer
Definition: fttypes.h:408
static void tt_loader_done(TT_Loader loader)
Definition: ttgload.c:2650
FT_Byte instruct_control
Definition: ttobjs.h:86
FT_UShort width
Definition: tttypes.h:462
WORD face[3]
Definition: mesh.c:4747
#define TT_INTERPRETER_VERSION_38
Definition: ftdriver.h:748
typedefFT_BEGIN_HEADER struct TT_DriverRec_ * TT_Driver
Definition: ttobjs.h:39
return FT_Err_Ok
Definition: ftbbox.c:511
static char memory[1024 *256]
Definition: process.c:116
#define FT_READ_USHORT(var)
Definition: ftstream.h:309
FT_Short vertBearingX
Definition: tttypes.h:468
tt_face_get_device_metrics(TT_Face face, FT_UInt ppem, FT_UInt gindex)
Definition: ttpload.c:619
GLvoid * data
Definition: dlist.c:359
const GLfloat * m
Definition: glext.h:10848
#define ARGS_ARE_XY_VALUES
Definition: ttgload.c:56
#define ARGS_ARE_WORDS
Definition: ttgload.c:55
FT_GlyphLoadRec base
Definition: ftgloadr.h:69
GLint limit
Definition: glext.h:10326
#define FT_FACE_DRIVER(x)
Definition: ftobjs.h:634
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:108
#define FT_LOAD_NO_SCALE
Definition: freetype.h:3009
FT_Byte * instructions
Definition: tttypes.h:1662
struct node node
unsigned short(__cdecl typeof(TIFFCurrentDirectory))(struct tiff *)
Definition: typeof.h:93
#define FT_TRACE1(varformat)
Definition: ftdebug.h:158
#define FT_CURVE_TAG_HAS_SCANMODE
Definition: ftimage.h:457
FT_Vector * points
Definition: ftimage.h:339
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
TT_MaxProfile max_profile
Definition: tttypes.h:1404
FT_Fixed xx
Definition: fttypes.h:387
#define USE_MY_METRICS
Definition: ttgload.c:64
FT_Outline outline
Definition: ftgloadr.h:52
unsigned char FT_Byte
Definition: fttypes.h:154
#define FT_LOAD_TARGET_LCD
Definition: freetype.h:3123
FT_GlyphLoader loader
Definition: ftobjs.h:467
#define FT_ASSERT(condition)
Definition: ftdebug.h:211
#define FT_THROW(e)
Definition: ftdebug.h:213
#define TT_SUPPORT_SUBPIXEL_HINTING_MINIMAL
Definition: ftoption.h:887
#define TT_INTERPRETER_VERSION_35
Definition: ftdriver.h:747
#define a
Definition: ke_i.h:78
TT_Get_VMetrics(TT_Face face, FT_UInt idx, FT_Pos yMax, FT_Short *tsb, FT_UShort *ah)
Definition: ttgload.c:93
#define FT_LOAD_COMPUTE_METRICS
Definition: freetype.h:3025
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
TT_Forget_Glyph_Frame(TT_Loader loader)
Definition: ttgload.c:288
TT_Size size
Definition: tttypes.h:1638
#define TT_FACE_FLAG_VAR_VADVANCE
Definition: tttypes.h:1118
#define FT_UINT_TO_POINTER(x)
Definition: ftconfig.h:341
#define pp
Definition: hlsl.yy.c:978
struct @1605::@1606 driver
unsigned int idx
Definition: utils.c:41
FT_Outline_Get_CBox(const FT_Outline *outline, FT_BBox *acbox)
Definition: ftoutln.c:478
FT_GlyphLoader_Add(FT_GlyphLoader loader)
Definition: ftgloadr.c:328
#define MORE_COMPONENTS
Definition: ttgload.c:60
FT_ListRec composites
Definition: tttypes.h:1679
TT_Load_Composite_Glyph(TT_Loader loader)
Definition: ttgload.c:559
smooth NULL
Definition: ftsmooth.c:416
TT_ExecContext exec
Definition: tttypes.h:1661
FT_Pos yMax
Definition: ftimage.h:118
FT_Int bitmap_left
Definition: freetype.h:1924
FT_Memory memory
Definition: ttinterp.h:153
#define FT_FREE(ptr)
Definition: ftmemory.h:329
FT_Outline_Transform(const FT_Outline *outline, const FT_Matrix *matrix)
Definition: ftoutln.c:711
static FT_Error TT_Process_Composite_Glyph(TT_Loader loader, FT_UInt start_point, FT_UInt start_contour)
Definition: ttgload.c:1253
static void tt_loader_set_pp(TT_Loader loader)
Definition: ttgload.c:1433
FT_Bool scan_control
Definition: ttobjs.h:91
FT_UInt num_subglyphs
Definition: ftgloadr.h:55
FT_UShort horiAdvance
Definition: tttypes.h:466
FT_Int bitmap_top
Definition: freetype.h:1925
FT_BBox bbox
Definition: tttypes.h:1649
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:388
void * control_data
Definition: freetype.h:1932
struct TT_FaceRec_ * TT_Face
Definition: tttypes.h:973
#define b
Definition: ke_i.h:79
#define WE_HAVE_AN_XY_SCALE
Definition: ttgload.c:61
FT_Int index
Definition: ftgloadr.h:41
FT_GlyphLoader_CheckSubGlyphs(FT_GlyphLoader loader, FT_UInt n_subs)
Definition: ftgloadr.c:281
r l[0]
Definition: byte_order.h:167
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:416
FT_Vector * cur
Definition: tttypes.h:1608
#define FT_IS_NAMED_INSTANCE(face)
Definition: freetype.h:1424
FT_Int left_bearing
Definition: tttypes.h:1650
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
TT_Get_HMetrics(TT_Face face, FT_UInt idx, FT_Short *lsb, FT_UShort *aw)
Definition: ttgload.c:75
char FT_String
Definition: fttypes.h:187
#define FT_OUTLINE_HIGH_PRECISION
Definition: ftimage.h:435
GLsizeiptr size
Definition: glext.h:5919
#define FT_ZERO(p)
Definition: ftmemory.h:237
FT_BEGIN_HEADER FT_List_Find(FT_List list, void *data)
Definition: ftutil.c:244
signed short FT_Int16
Definition: ftconfig.h:170
#define d
Definition: ke_i.h:81
TT_Load_Simple_Glyph(TT_Loader load)
Definition: ttgload.c:326
smooth FT_Module_Constructor FT_Module_Destructor FT_Module_Requester FT_GLYPH_FORMAT_OUTLINE
Definition: ftsmooth.c:416
FT_Pos xMin
Definition: ftimage.h:117
if(!(yy_init))
Definition: macro.lex.yy.c:714
#define FT_IS_TRICKY(face)
Definition: freetype.h:1474
static void Exit(void)
Definition: sock.c:1331
#define FT_IS_VARIATION(face)
Definition: freetype.h:1442
#define FT_TRACE2(varformat)
Definition: ftdebug.h:159
#define FT_ERR_EQ(x, e)
Definition: fttypes.h:591
const GLubyte * c
Definition: glext.h:8905
static FT_Error TT_Process_Composite_Component(TT_Loader loader, FT_SubGlyph subglyph, FT_UInt start_point, FT_UInt num_base_points)
Definition: ttgload.c:1084
FT_Pos xMax
Definition: ftimage.h:118
int xx
Definition: npserver.c:29
#define for
Definition: utility.h:88
#define FT_TRACE7(varformat)
Definition: ftdebug.h:164
#define WE_HAVE_A_2X2
Definition: ttgload.c:62
FT_Size_Metrics * metrics
Definition: ttobjs.h:281
static void tt_prepare_zone(TT_GlyphZone zone, FT_GlyphLoad load, FT_UInt start_point, FT_UInt start_contour)
Definition: ttgload.c:753
FT_Short horiBearingY
Definition: tttypes.h:465
FT_Short vertBearingY
Definition: tttypes.h:469
FT_Incremental_GetGlyphMetricsFunc get_glyph_metrics
Definition: ftincrem.h:274
FT_Stream stream
Definition: tttypes.h:1645
FT_Vector * vec
Definition: ftbbox.c:448
#define FT_CALLBACK_DEF(x)
Definition: ftconfig.h:533
GLsizei const GLfloat * points
Definition: glext.h:8112
FT_Outline_EmboldenXY(FT_Outline *outline, FT_Pos xstrength, FT_Pos ystrength)
Definition: ftoutln.c:909
FT_Vector pp2
Definition: tttypes.h:1655
static const WCHAR L[]
Definition: oid.c:1250
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
Definition: parse.h:22
GLuint GLuint stream
Definition: glext.h:7522
FT_GlyphLoadRec current
Definition: ftgloadr.h:70
int flags
Definition: ftimage.h:343
signed short FT_Short
Definition: fttypes.h:198
FT_Outline outline
Definition: freetype.h:1927
#define FT_LOAD_TARGET_LCD_V
Definition: freetype.h:3124
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:66
FT_List_Add(FT_List list, FT_ListNode node)
Definition: ftutil.c:269
static FT_Error compute_glyph_metrics(TT_Loader loader, FT_UInt glyph_index)
Definition: ttgload.c:2105
Definition: _list.h:228
FT_ULong load_flags
Definition: tttypes.h:1642
#define FT_BOOL(x)
Definition: fttypes.h:578
FT_Short horiBearingX
Definition: tttypes.h:464
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
FT_ULong ins_pos
Definition: tttypes.h:1663
FT_FaceRec root
Definition: tttypes.h:1393
FT_UShort n_points
Definition: tttypes.h:1604
FT_Bitmap bitmap
Definition: freetype.h:1923
#define FT_OUTLINE_INCLUDE_STUBS
Definition: ftimage.h:433
#define FT_FRAME_EXIT()
Definition: ftstream.h:517
#define FT_NEW_ARRAY(ptr, count)
Definition: ftmemory.h:333
Definition: mesh.c:5329
#define FT_STREAM_SEEK(position)
Definition: ftstream.h:489
TT_GraphicsState GS
Definition: ttinterp.h:177
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:509
#define FT_NEXT_USHORT(buffer)
Definition: ftstream.h:226
GLint GLint GLsizei GLsizei height
Definition: gl.h:1546
FT_UShort maxSizeOfInstructions
Definition: tttables.h:581
Definition: hiveinit.c:368
#define FT_STREAM_POS()
Definition: ftstream.h:486
DWORD zone
Definition: sec_mgr.c:1760
FT_Int byte_len
Definition: tttypes.h:1646
FT_Glyph_Format format
Definition: freetype.h:1921
FT_Size_Metrics metrics
Definition: ttinterp.h:174
#define ROUND_XY_TO_GRID
Definition: ttgload.c:57
signed long FT_Fixed
Definition: fttypes.h:288
short n_points
Definition: ftimage.h:337
FT_Vector pp3
Definition: tttypes.h:1671
#define FT_FACE(x)
Definition: ftobjs.h:630
#define FT_SET_ERROR(expression)
Definition: ftmemory.h:42
static FT_Error TT_Process_Simple_Glyph(TT_Loader loader)
Definition: ttgload.c:910
FT_Fixed x_scale
Definition: freetype.h:1643
short * contours
Definition: ftimage.h:341
unsigned int FT_UInt
Definition: fttypes.h:231
struct FT_GlyphSlotRec_ * FT_GlyphSlot
Definition: freetype.h:554
static FT_Error load_truetype_glyph(TT_Loader loader, FT_UInt glyph_index, FT_UInt recurse_count, FT_Bool header_only)
Definition: ttgload.c:1510
FT_Fixed xy
Definition: fttypes.h:387
FT_GlyphLoader_Rewind(FT_GlyphLoader loader)
Definition: ftgloadr.c:88
FT_Pos yMin
Definition: ftimage.h:117
int pedantic
Definition: widl.c:113
#define FT_TRACE5(varformat)
Definition: ftdebug.h:162
FT_Byte * tags
Definition: tttypes.h:1611
TT_Face face
Definition: tttypes.h:1637
FT_GlyphSlot glyph
Definition: tttypes.h:1639
#define TT_INTERPRETER_VERSION_40
Definition: ftdriver.h:749
#define FT_OUTLINE_SMART_DROPOUTS
Definition: ftimage.h:432
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
TT_Load_SBit_Image_Func load_sbit_image
Definition: sfnt.h:595
#define TT_USE_BYTECODE_INTERPRETER
Definition: ftoption.h:879
FT_Outline_Translate(const FT_Outline *outline, FT_Pos xOffset, FT_Pos yOffset)
Definition: ftoutln.c:528
FT_UShort flags
Definition: ftgloadr.h:42
FT_Stream_OpenMemory(FT_Stream stream, const FT_Byte *base, FT_ULong size)
Definition: ftstream.c:35
#define FT_CURVE_TAG_ON
Definition: ftimage.h:453
FT_Slot_Internal internal
Definition: freetype.h:1940
#define FT_FRAME_ENTER(size)
Definition: ftstream.h:512
#define c
Definition: ke_i.h:80
#define WE_HAVE_A_SCALE
Definition: ttgload.c:58
#define FT_NEW(ptr)
Definition: ftmemory.h:331
int load
Definition: msacm.c:1353
#define SUB_LONG(a, b)
Definition: ftcalc.h:422
#define FT_MEM_COPY(dest, source, count)
Definition: ftmemory.h:228
#define WE_HAVE_INSTR
Definition: ttgload.c:63
FT_UInt glyphSize
Definition: ttinterp.h:192
#define FT_NEXT_SHORT(buffer)
Definition: ftstream.h:223
#define FT_LOAD_NO_BITMAP
Definition: freetype.h:3012
TT_Access_Glyph_Frame(TT_Loader loader, FT_UInt glyph_index, FT_ULong offset, FT_UInt byte_count)
Definition: ttgload.c:262
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
FT_Bool linear_def
Definition: tttypes.h:1653
FT_Fixed yx
Definition: fttypes.h:388
FT_Fixed yy
Definition: fttypes.h:388
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
static FT_ListNode ft_list_get_node_at(FT_List list, FT_UInt idx)
Definition: ttgload.c:1479
TT_Load_Glyph(TT_Size size, TT_GlyphSlot glyph, FT_UInt glyph_index, FT_Int32 load_flags)
Definition: ttgload.c:2687
GLfloat GLfloat p
Definition: glext.h:8902
unsigned short FT_UShort
Definition: fttypes.h:209
TT_GlyphZoneRec zone
Definition: tttypes.h:1659
#define FT_GLYPHLOADER_CHECK_POINTS(_loader, _points, _contours)
Definition: ftgloadr.h:118
FT_UInt glyph_index
Definition: tttypes.h:1643
static FT_Error tt_loader_init(TT_Loader loader, TT_Size size, TT_GlyphSlot glyph, FT_Int32 load_flags, FT_Bool glyf_table_only)
Definition: ttgload.c:2352
Arabic default style
Definition: afstyles.h:93
#define FT_IS_SCALABLE(face)
Definition: freetype.h:1312
FT_Hypot(FT_Fixed x, FT_Fixed y)
Definition: ftcalc.c:155
FT_Bool pedantic_hinting
Definition: ttinterp.h:230
#define FT_STREAM_READ(buffer, count)
Definition: ftstream.h:497
#define FT_UNUSED(arg)
Definition: ftconfig.h:101
short n_contours
Definition: ftimage.h:336
#define FT_NEXT_CHAR(buffer)
Definition: ftstream.h:217
FT_Memory memory
Definition: freetype.h:1112
TT_GlyphZoneRec pts
Definition: ttinterp.h:167
int k
Definition: mpi.c:3369
FT_Vector pp1
Definition: tttypes.h:1654
const FT_Incremental_FuncsRec * funcs
Definition: ftincrem.h:317
#define FT_PIX_ROUND(x)
Definition: ftobjs.h:93
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
FT_Int advance
Definition: tttypes.h:1651
tt_face_get_location(TT_Face face, FT_UInt gindex, FT_UInt *asize)
Definition: ttpload.c:195
struct task_struct * current
Definition: linux.c:32
FT_Byte * glyphIns
Definition: ttinterp.h:193
FT_Short n_contours
Definition: tttypes.h:1648
static FT_Error TT_Hint_Glyph(TT_Loader loader, FT_Bool is_composite)
Definition: ttgload.c:781
Definition: dlist.c:348
#define IS_HINTED(flags)
Definition: ttobjs.h:417
#define FT_LOAD_TARGET_MODE(x)
Definition: freetype.h:3137
FT_GlyphLoader gloader
Definition: tttypes.h:1640