w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

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