Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

[Download] [Tutorials] [All Classes] [Grouped Classes]
cffgload.c
Go to the documentation of this file.
1 /***************************************************************************/
2 /* */
3 /* cffgload.c */
4 /* */
5 /* OpenType Glyph Loader (body). */
6 /* */
7 /* Copyright 1996-2013 by */
8 /* David Turner, Robert Wilhelm, and Werner Lemberg. */
9 /* */
10 /* This file is part of the FreeType project, and may only be used, */
11 /* modified, and distributed under the terms of the FreeType project */
12 /* license, LICENSE.TXT. By continuing to use, modify, or distribute */
13 /* this file you indicate that you have read the license and */
14 /* understand and accept it fully. */
15 /* */
16 /***************************************************************************/
17 
18 
19 #include <ft2build.h>
20 #include FT_INTERNAL_DEBUG_H
21 #include FT_INTERNAL_STREAM_H
22 #include FT_INTERNAL_SFNT_H
23 #include FT_OUTLINE_H
24 #include FT_CFF_DRIVER_H
25 
26 #include "cffobjs.h"
27 #include "cffload.h"
28 #include "cffgload.h"
29 #include "cf2ft.h" /* for cf2_decoder_parse_charstrings */
30 
31 #include "cfferrs.h"
32 
33 
34  /*************************************************************************/
35  /* */
36  /* The macro FT_COMPONENT is used in trace mode. It is an implicit */
37  /* parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log */
38  /* messages during execution. */
39  /* */
40 #undef FT_COMPONENT
41 #define FT_COMPONENT trace_cffgload
42 
43 
44  typedef enum CFF_Operator_
45  {
47 
51 
55 
63 
68 
70 
75 
78  cff_op_dotsection, /* deprecated, acts as no-op */
79 
88 
90 
96 
101 
107 
111 
112  /* Type 1 opcodes: invalid but seen in real life */
120 
121  /* do not remove */
123 
124  } CFF_Operator;
125 
126 
127 #define CFF_COUNT_CHECK_WIDTH 0x80
128 #define CFF_COUNT_EXACT 0x40
129 #define CFF_COUNT_CLEAR_STACK 0x20
130 
131  /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are */
132  /* used for checking the width and requested numbers of arguments */
133  /* only; they are set to zero afterwards */
134 
135  /* the other two flags are informative only and unused currently */
136 
137  static const FT_Byte cff_argument_counts[] =
138  {
139  0, /* unknown */
140 
141  2 | CFF_COUNT_CHECK_WIDTH | CFF_COUNT_EXACT, /* rmoveto */
144 
145  0 | CFF_COUNT_CLEAR_STACK, /* rlineto */
148 
149  0 | CFF_COUNT_CLEAR_STACK, /* rrcurveto */
156 
157  13, /* flex */
158  7,
159  9,
160  11,
161 
162  0 | CFF_COUNT_CHECK_WIDTH, /* endchar */
163 
164  2 | CFF_COUNT_CHECK_WIDTH, /* hstem */
168 
169  0 | CFF_COUNT_CHECK_WIDTH, /* hintmask */
170  0 | CFF_COUNT_CHECK_WIDTH, /* cntrmask */
171  0, /* dotsection */
172 
173  1, /* abs */
174  2,
175  2,
176  2,
177  1,
178  0,
179  2,
180  1,
181 
182  1, /* blend */
183 
184  1, /* drop */
185  2,
186  1,
187  2,
188  1,
189 
190  2, /* put */
191  1,
192  4,
193  3,
194 
195  2, /* and */
196  2,
197  1,
198  2,
199  4,
200 
201  1, /* callsubr */
202  1,
203  0,
204 
205  2, /* hsbw */
206  0,
207  0,
208  0,
209  5, /* seac */
210  4, /* sbw */
211  2 /* setcurrentpoint */
212  };
213 
214 
215  /*************************************************************************/
216  /*************************************************************************/
217  /*************************************************************************/
218  /********** *********/
219  /********** *********/
220  /********** GENERIC CHARSTRING PARSING *********/
221  /********** *********/
222  /********** *********/
223  /*************************************************************************/
224  /*************************************************************************/
225  /*************************************************************************/
226 
227 
228  /*************************************************************************/
229  /* */
230  /* <Function> */
231  /* cff_builder_init */
232  /* */
233  /* <Description> */
234  /* Initializes a given glyph builder. */
235  /* */
236  /* <InOut> */
237  /* builder :: A pointer to the glyph builder to initialize. */
238  /* */
239  /* <Input> */
240  /* face :: The current face object. */
241  /* */
242  /* size :: The current size object. */
243  /* */
244  /* glyph :: The current glyph object. */
245  /* */
246  /* hinting :: Whether hinting is active. */
247  /* */
248  static void
249  cff_builder_init( CFF_Builder* builder,
250  TT_Face face,
251  CFF_Size size,
252  CFF_GlyphSlot glyph,
253  FT_Bool hinting )
254  {
255  builder->path_begun = 0;
256  builder->load_points = 1;
257 
258  builder->face = face;
259  builder->glyph = glyph;
260  builder->memory = face->root.memory;
261 
262  if ( glyph )
263  {
264  FT_GlyphLoader loader = glyph->root.internal->loader;
265 
266 
267  builder->loader = loader;
268  builder->base = &loader->base.outline;
269  builder->current = &loader->current.outline;
270  FT_GlyphLoader_Rewind( loader );
271 
272  builder->hints_globals = 0;
273  builder->hints_funcs = 0;
274 
275  if ( hinting && size )
276  {
277  CFF_Internal internal = (CFF_Internal)size->root.internal;
278 
279 
280  builder->hints_globals = (void *)internal->topfont;
281  builder->hints_funcs = glyph->root.internal->glyph_hints;
282  }
283  }
284 
285  builder->pos_x = 0;
286  builder->pos_y = 0;
287 
288  builder->left_bearing.x = 0;
289  builder->left_bearing.y = 0;
290  builder->advance.x = 0;
291  builder->advance.y = 0;
292  }
293 
294 
295  /*************************************************************************/
296  /* */
297  /* <Function> */
298  /* cff_builder_done */
299  /* */
300  /* <Description> */
301  /* Finalizes a given glyph builder. Its contents can still be used */
302  /* after the call, but the function saves important information */
303  /* within the corresponding glyph slot. */
304  /* */
305  /* <Input> */
306  /* builder :: A pointer to the glyph builder to finalize. */
307  /* */
308  static void
309  cff_builder_done( CFF_Builder* builder )
310  {
311  CFF_GlyphSlot glyph = builder->glyph;
312 
313 
314  if ( glyph )
315  glyph->root.outline = *builder->base;
316  }
317 
318 
319  /*************************************************************************/
320  /* */
321  /* <Function> */
322  /* cff_compute_bias */
323  /* */
324  /* <Description> */
325  /* Computes the bias value in dependence of the number of glyph */
326  /* subroutines. */
327  /* */
328  /* <Input> */
329  /* in_charstring_type :: The `CharstringType' value of the top DICT */
330  /* dictionary. */
331  /* */
332  /* num_subrs :: The number of glyph subroutines. */
333  /* */
334  /* <Return> */
335  /* The bias value. */
336  static FT_Int
337  cff_compute_bias( FT_Int in_charstring_type,
338  FT_UInt num_subrs )
339  {
340  FT_Int result;
341 
342 
343  if ( in_charstring_type == 1 )
344  result = 0;
345  else if ( num_subrs < 1240 )
346  result = 107;
347  else if ( num_subrs < 33900U )
348  result = 1131;
349  else
350  result = 32768U;
351 
352  return result;
353  }
354 
355 
356  /*************************************************************************/
357  /* */
358  /* <Function> */
359  /* cff_decoder_init */
360  /* */
361  /* <Description> */
362  /* Initializes a given glyph decoder. */
363  /* */
364  /* <InOut> */
365  /* decoder :: A pointer to the glyph builder to initialize. */
366  /* */
367  /* <Input> */
368  /* face :: The current face object. */
369  /* */
370  /* size :: The current size object. */
371  /* */
372  /* slot :: The current glyph object. */
373  /* */
374  /* hinting :: Whether hinting is active. */
375  /* */
376  /* hint_mode :: The hinting mode. */
377  /* */
378  FT_LOCAL_DEF( void )
380  TT_Face face,
381  CFF_Size size,
382  CFF_GlyphSlot slot,
383  FT_Bool hinting,
384  FT_Render_Mode hint_mode )
385  {
386  CFF_Font cff = (CFF_Font)face->extra.data;
387 
388 
389  /* clear everything */
390  FT_MEM_ZERO( decoder, sizeof ( *decoder ) );
391 
392  /* initialize builder */
393  cff_builder_init( &decoder->builder, face, size, slot, hinting );
394 
395  /* initialize Type2 decoder */
396  decoder->cff = cff;
397  decoder->num_globals = cff->global_subrs_index.count;
398  decoder->globals = cff->global_subrs;
399  decoder->globals_bias = cff_compute_bias(
401  decoder->num_globals );
402 
403  decoder->hint_mode = hint_mode;
404  }
405 
406 
407  /* this function is used to select the subfont */
408  /* and the locals subrs array */
411  CFF_Size size,
412  FT_UInt glyph_index )
413  {
414  CFF_Builder *builder = &decoder->builder;
415  CFF_Font cff = (CFF_Font)builder->face->extra.data;
416  CFF_SubFont sub = &cff->top_font;
418 
419 
420  /* manage CID fonts */
421  if ( cff->num_subfonts )
422  {
423  FT_Byte fd_index = cff_fd_select_get( &cff->fd_select, glyph_index );
424 
425 
426  if ( fd_index >= cff->num_subfonts )
427  {
428  FT_TRACE4(( "cff_decoder_prepare: invalid CID subfont index\n" ));
429  error = FT_THROW( Invalid_File_Format );
430  goto Exit;
431  }
432 
433  FT_TRACE3(( "glyph index %d (subfont %d):\n", glyph_index, fd_index ));
434 
435  sub = cff->subfonts[fd_index];
436 
437  if ( builder->hints_funcs && size )
438  {
439  CFF_Internal internal = (CFF_Internal)size->root.internal;
440 
441 
442  /* for CFFs without subfonts, this value has already been set */
443  builder->hints_globals = (void *)internal->subfonts[fd_index];
444  }
445  }
446 #ifdef FT_DEBUG_LEVEL_TRACE
447  else
448  FT_TRACE3(( "glyph index %d:\n", glyph_index ));
449 #endif
450 
451  decoder->num_locals = sub->local_subrs_index.count;
452  decoder->locals = sub->local_subrs;
453  decoder->locals_bias = cff_compute_bias(
454  decoder->cff->top_font.font_dict.charstring_type,
455  decoder->num_locals );
456 
457  decoder->glyph_width = sub->private_dict.default_width;
458  decoder->nominal_width = sub->private_dict.nominal_width;
459 
460  decoder->current_subfont = sub; /* for Adobe's CFF handler */
461 
462  Exit:
463  return error;
464  }
465 
466 
467  /* check that there is enough space for `count' more points */
470  FT_Int count )
471  {
472  return FT_GLYPHLOADER_CHECK_POINTS( builder->loader, count, 0 );
473  }
474 
475 
476  /* add a new point, do not check space */
477  FT_LOCAL_DEF( void )
479  FT_Pos x,
480  FT_Pos y,
481  FT_Byte flag )
482  {
483  FT_Outline* outline = builder->current;
484 
485 
486  if ( builder->load_points )
487  {
489 
490  FT_Vector* point = outline->points + outline->n_points;
491  FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points;
492 
493 
494  if ( driver->hinting_engine == FT_CFF_HINTING_ADOBE )
495  {
496  /* cf2_decoder_parse_charstrings uses 16.16 coordinates */
497  point->x = x >> 10;
498  point->y = y >> 10;
499  }
500  else
501  {
502  point->x = x >> 16;
503  point->y = y >> 16;
504  }
505  *control = (FT_Byte)( flag ? FT_CURVE_TAG_ON : FT_CURVE_TAG_CUBIC );
506  }
507 
508  outline->n_points++;
509  }
510 
511 
512  /* check space for a new on-curve point, then add it */
515  FT_Pos x,
516  FT_Pos y )
517  {
518  FT_Error error;
519 
520 
521  error = cff_check_points( builder, 1 );
522  if ( !error )
523  cff_builder_add_point( builder, x, y, 1 );
524 
525  return error;
526  }
527 
528 
529  /* check space for a new contour, then add it */
530  static FT_Error
531  cff_builder_add_contour( CFF_Builder* builder )
532  {
533  FT_Outline* outline = builder->current;
534  FT_Error error;
535 
536 
537  if ( !builder->load_points )
538  {
539  outline->n_contours++;
540  return FT_Err_Ok;
541  }
542 
543  error = FT_GLYPHLOADER_CHECK_POINTS( builder->loader, 0, 1 );
544  if ( !error )
545  {
546  if ( outline->n_contours > 0 )
547  outline->contours[outline->n_contours - 1] =
548  (short)( outline->n_points - 1 );
549 
550  outline->n_contours++;
551  }
552 
553  return error;
554  }
555 
556 
557  /* if a path was begun, add its first on-curve point */
560  FT_Pos x,
561  FT_Pos y )
562  {
564 
565 
566  /* test whether we are building a new contour */
567  if ( !builder->path_begun )
568  {
569  builder->path_begun = 1;
570  error = cff_builder_add_contour( builder );
571  if ( !error )
572  error = cff_builder_add_point1( builder, x, y );
573  }
574 
575  return error;
576  }
577 
578 
579  /* close the current contour */
580  FT_LOCAL_DEF( void )
582  {
583  FT_Outline* outline = builder->current;
584  FT_Int first;
585 
586 
587  if ( !outline )
588  return;
589 
590  first = outline->n_contours <= 1
591  ? 0 : outline->contours[outline->n_contours - 2] + 1;
592 
593  /* We must not include the last point in the path if it */
594  /* is located on the first point. */
595  if ( outline->n_points > 1 )
596  {
597  FT_Vector* p1 = outline->points + first;
598  FT_Vector* p2 = outline->points + outline->n_points - 1;
599  FT_Byte* control = (FT_Byte*)outline->tags + outline->n_points - 1;
600 
601 
602  /* `delete' last point only if it coincides with the first */
603  /* point and if it is not a control point (which can happen). */
604  if ( p1->x == p2->x && p1->y == p2->y )
605  if ( *control == FT_CURVE_TAG_ON )
606  outline->n_points--;
607  }
608 
609  if ( outline->n_contours > 0 )
610  {
611  /* Don't add contours only consisting of one point, i.e., */
612  /* check whether begin point and last point are the same. */
613  if ( first == outline->n_points - 1 )
614  {
615  outline->n_contours--;
616  outline->n_points--;
617  }
618  else
619  outline->contours[outline->n_contours - 1] =
620  (short)( outline->n_points - 1 );
621  }
622  }
623 
624 
627  FT_Int charcode )
628  {
629  FT_UInt n;
630  FT_UShort glyph_sid;
631 
632 
633  /* CID-keyed fonts don't have glyph names */
634  if ( !cff->charset.sids )
635  return -1;
636 
637  /* check range of standard char code */
638  if ( charcode < 0 || charcode > 255 )
639  return -1;
640 
641  /* Get code to SID mapping from `cff_standard_encoding'. */
642  glyph_sid = cff_get_standard_encoding( (FT_UInt)charcode );
643 
644  for ( n = 0; n < cff->num_glyphs; n++ )
645  {
646  if ( cff->charset.sids[n] == glyph_sid )
647  return n;
648  }
649 
650  return -1;
651  }
652 
653 
656  FT_UInt glyph_index,
657  FT_Byte** pointer,
658  FT_ULong* length )
659  {
660 #ifdef FT_CONFIG_OPTION_INCREMENTAL
661  /* For incremental fonts get the character data using the */
662  /* callback function. */
663  if ( face->root.internal->incremental_interface )
664  {
665  FT_Data data;
666  FT_Error error =
667  face->root.internal->incremental_interface->funcs->get_glyph_data(
668  face->root.internal->incremental_interface->object,
669  glyph_index, &data );
670 
671 
672  *pointer = (FT_Byte*)data.pointer;
673  *length = data.length;
674 
675  return error;
676  }
677  else
678 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
679 
680  {
681  CFF_Font cff = (CFF_Font)(face->extra.data);
682 
683 
684  return cff_index_access_element( &cff->charstrings_index, glyph_index,
685  pointer, length );
686  }
687  }
688 
689 
690  FT_LOCAL_DEF( void )
692  FT_Byte** pointer,
693  FT_ULong length )
694  {
695 #ifndef FT_CONFIG_OPTION_INCREMENTAL
696  FT_UNUSED( length );
697 #endif
698 
699 #ifdef FT_CONFIG_OPTION_INCREMENTAL
700  /* For incremental fonts get the character data using the */
701  /* callback function. */
702  if ( face->root.internal->incremental_interface )
703  {
704  FT_Data data;
705 
706 
707  data.pointer = *pointer;
708  data.length = length;
709 
710  face->root.internal->incremental_interface->funcs->free_glyph_data(
711  face->root.internal->incremental_interface->object, &data );
712  }
713  else
714 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
715 
716  {
717  CFF_Font cff = (CFF_Font)(face->extra.data);
718 
719 
721  }
722  }
723 
724 
725  static FT_Error
726  cff_operator_seac( CFF_Decoder* decoder,
727  FT_Pos asb,
728  FT_Pos adx,
729  FT_Pos ady,
730  FT_Int bchar,
731  FT_Int achar )
732  {
733  FT_Error error;
734  CFF_Builder* builder = &decoder->builder;
735  FT_Int bchar_index, achar_index;
736  TT_Face face = decoder->builder.face;
737  FT_Vector left_bearing, advance;
738  FT_Byte* charstring;
739  FT_ULong charstring_len;
740  FT_Pos glyph_width;
741 
742 
743  if ( decoder->seac )
744  {
745  FT_ERROR(( "cff_operator_seac: invalid nested seac\n" ));
746  return FT_THROW( Syntax_Error );
747  }
748 
749  adx += decoder->builder.left_bearing.x;
750  ady += decoder->builder.left_bearing.y;
751 
752 #ifdef FT_CONFIG_OPTION_INCREMENTAL
753  /* Incremental fonts don't necessarily have valid charsets. */
754  /* They use the character code, not the glyph index, in this case. */
755  if ( face->root.internal->incremental_interface )
756  {
757  bchar_index = bchar;
758  achar_index = achar;
759  }
760  else
761 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
762  {
763  CFF_Font cff = (CFF_Font)(face->extra.data);
764 
765 
766  bchar_index = cff_lookup_glyph_by_stdcharcode( cff, bchar );
767  achar_index = cff_lookup_glyph_by_stdcharcode( cff, achar );
768  }
769 
770  if ( bchar_index < 0 || achar_index < 0 )
771  {
772  FT_ERROR(( "cff_operator_seac:"
773  " invalid seac character code arguments\n" ));
774  return FT_THROW( Syntax_Error );
775  }
776 
777  /* If we are trying to load a composite glyph, do not load the */
778  /* accent character and return the array of subglyphs. */
779  if ( builder->no_recurse )
780  {
781  FT_GlyphSlot glyph = (FT_GlyphSlot)builder->glyph;
782  FT_GlyphLoader loader = glyph->internal->loader;
783  FT_SubGlyph subg;
784 
785 
786  /* reallocate subglyph array if necessary */
787  error = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
788  if ( error )
789  goto Exit;
790 
791  subg = loader->current.subglyphs;
792 
793  /* subglyph 0 = base character */
794  subg->index = bchar_index;
797  subg->arg1 = 0;
798  subg->arg2 = 0;
799  subg++;
800 
801  /* subglyph 1 = accent character */
802  subg->index = achar_index;
804  subg->arg1 = (FT_Int)( adx >> 16 );
805  subg->arg2 = (FT_Int)( ady >> 16 );
806 
807  /* set up remaining glyph fields */
808  glyph->num_subglyphs = 2;
809  glyph->subglyphs = loader->base.subglyphs;
810  glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
811 
812  loader->current.num_subglyphs = 2;
813  }
814 
815  FT_GlyphLoader_Prepare( builder->loader );
816 
817  /* First load `bchar' in builder */
818  error = cff_get_glyph_data( face, bchar_index,
819  &charstring, &charstring_len );
820  if ( !error )
821  {
822  /* the seac operator must not be nested */
823  decoder->seac = TRUE;
824  error = cff_decoder_parse_charstrings( decoder, charstring,
825  charstring_len );
826  decoder->seac = FALSE;
827 
828  cff_free_glyph_data( face, &charstring, charstring_len );
829 
830  if ( error )
831  goto Exit;
832  }
833 
834  /* Save the left bearing, advance and glyph width of the base */
835  /* character as they will be erased by the next load. */
836 
837  left_bearing = builder->left_bearing;
838  advance = builder->advance;
839  glyph_width = decoder->glyph_width;
840 
841  builder->left_bearing.x = 0;
842  builder->left_bearing.y = 0;
843 
844  builder->pos_x = adx - asb;
845  builder->pos_y = ady;
846 
847  /* Now load `achar' on top of the base outline. */
848  error = cff_get_glyph_data( face, achar_index,
849  &charstring, &charstring_len );
850  if ( !error )
851  {
852  /* the seac operator must not be nested */
853  decoder->seac = TRUE;
854  error = cff_decoder_parse_charstrings( decoder, charstring,
855  charstring_len );
856  decoder->seac = FALSE;
857 
858  cff_free_glyph_data( face, &charstring, charstring_len );
859 
860  if ( error )
861  goto Exit;
862  }
863 
864  /* Restore the left side bearing, advance and glyph width */
865  /* of the base character. */
866  builder->left_bearing = left_bearing;
867  builder->advance = advance;
868  decoder->glyph_width = glyph_width;
869 
870  builder->pos_x = 0;
871  builder->pos_y = 0;
872 
873  Exit:
874  return error;
875  }
876 
877 
878  /*************************************************************************/
879  /* */
880  /* <Function> */
881  /* cff_decoder_parse_charstrings */
882  /* */
883  /* <Description> */
884  /* Parses a given Type 2 charstrings program. */
885  /* */
886  /* <InOut> */
887  /* decoder :: The current Type 1 decoder. */
888  /* */
889  /* <Input> */
890  /* charstring_base :: The base of the charstring stream. */
891  /* */
892  /* charstring_len :: The length in bytes of the charstring stream. */
893  /* */
894  /* <Return> */
895  /* FreeType error code. 0 means success. */
896  /* */
899  FT_Byte* charstring_base,
900  FT_ULong charstring_len )
901  {
902  FT_Error error;
903  CFF_Decoder_Zone* zone;
904  FT_Byte* ip;
905  FT_Byte* limit;
906  CFF_Builder* builder = &decoder->builder;
907  FT_Pos x, y;
908  FT_Fixed seed;
909  FT_Fixed* stack;
910  FT_Int charstring_type =
912 
913  T2_Hints_Funcs hinter;
914 
915 
916  /* set default width */
917  decoder->num_hints = 0;
918  decoder->read_width = 1;
919 
920  /* compute random seed from stack address of parameter */
921  seed = (FT_Fixed)( ( (FT_PtrDist)(char*)&seed ^
922  (FT_PtrDist)(char*)&decoder ^
923  (FT_PtrDist)(char*)&charstring_base ) &
924  FT_ULONG_MAX ) ;
925  seed = ( seed ^ ( seed >> 10 ) ^ ( seed >> 20 ) ) & 0xFFFFL;
926  if ( seed == 0 )
927  seed = 0x7384;
928 
929  /* initialize the decoder */
930  decoder->top = decoder->stack;
931  decoder->zone = decoder->zones;
932  zone = decoder->zones;
933  stack = decoder->top;
934 
935  hinter = (T2_Hints_Funcs)builder->hints_funcs;
936 
937  builder->path_begun = 0;
938 
939  zone->base = charstring_base;
940  limit = zone->limit = charstring_base + charstring_len;
941  ip = zone->cursor = zone->base;
942 
943  error = FT_Err_Ok;
944 
945  x = builder->pos_x;
946  y = builder->pos_y;
947 
948  /* begin hints recording session, if any */
949  if ( hinter )
950  hinter->open( hinter->hints );
951 
952  /* now execute loop */
953  while ( ip < limit )
954  {
955  CFF_Operator op;
956  FT_Byte v;
957 
958 
959  /********************************************************************/
960  /* */
961  /* Decode operator or operand */
962  /* */
963  v = *ip++;
964  if ( v >= 32 || v == 28 )
965  {
966  FT_Int shift = 16;
967  FT_Int32 val;
968 
969 
970  /* this is an operand, push it on the stack */
971 
972  /* if we use shifts, all computations are done with unsigned */
973  /* values; the conversion to a signed value is the last step */
974  if ( v == 28 )
975  {
976  if ( ip + 1 >= limit )
977  goto Syntax_Error;
978  val = (FT_Short)( ( (FT_UShort)ip[0] << 8 ) | ip[1] );
979  ip += 2;
980  }
981  else if ( v < 247 )
982  val = (FT_Int32)v - 139;
983  else if ( v < 251 )
984  {
985  if ( ip >= limit )
986  goto Syntax_Error;
987  val = ( (FT_Int32)v - 247 ) * 256 + *ip++ + 108;
988  }
989  else if ( v < 255 )
990  {
991  if ( ip >= limit )
992  goto Syntax_Error;
993  val = -( (FT_Int32)v - 251 ) * 256 - *ip++ - 108;
994  }
995  else
996  {
997  if ( ip + 3 >= limit )
998  goto Syntax_Error;
999  val = (FT_Int32)( ( (FT_UInt32)ip[0] << 24 ) |
1000  ( (FT_UInt32)ip[1] << 16 ) |
1001  ( (FT_UInt32)ip[2] << 8 ) |
1002  (FT_UInt32)ip[3] );
1003  ip += 4;
1004  if ( charstring_type == 2 )
1005  shift = 0;
1006  }
1007  if ( decoder->top - stack >= CFF_MAX_OPERANDS )
1008  goto Stack_Overflow;
1009 
1010  val = (FT_Int32)( (FT_UInt32)val << shift );
1011  *decoder->top++ = val;
1012 
1013 #ifdef FT_DEBUG_LEVEL_TRACE
1014  if ( !( val & 0xFFFFL ) )
1015  FT_TRACE4(( " %hd", (FT_Short)( (FT_UInt32)val >> 16 ) ));
1016  else
1017  FT_TRACE4(( " %.2f", val / 65536.0 ));
1018 #endif
1019 
1020  }
1021  else
1022  {
1023  /* The specification says that normally arguments are to be taken */
1024  /* from the bottom of the stack. However, this seems not to be */
1025  /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */
1026  /* arguments similar to a PS interpreter. */
1027 
1028  FT_Fixed* args = decoder->top;
1029  FT_Int num_args = (FT_Int)( args - decoder->stack );
1030  FT_Int req_args;
1031 
1032 
1033  /* find operator */
1034  op = cff_op_unknown;
1035 
1036  switch ( v )
1037  {
1038  case 1:
1039  op = cff_op_hstem;
1040  break;
1041  case 3:
1042  op = cff_op_vstem;
1043  break;
1044  case 4:
1045  op = cff_op_vmoveto;
1046  break;
1047  case 5:
1048  op = cff_op_rlineto;
1049  break;
1050  case 6:
1051  op = cff_op_hlineto;
1052  break;
1053  case 7:
1054  op = cff_op_vlineto;
1055  break;
1056  case 8:
1057  op = cff_op_rrcurveto;
1058  break;
1059  case 9:
1060  op = cff_op_closepath;
1061  break;
1062  case 10:
1063  op = cff_op_callsubr;
1064  break;
1065  case 11:
1066  op = cff_op_return;
1067  break;
1068  case 12:
1069  {
1070  if ( ip >= limit )
1071  goto Syntax_Error;
1072  v = *ip++;
1073 
1074  switch ( v )
1075  {
1076  case 0:
1077  op = cff_op_dotsection;
1078  break;
1079  case 1: /* this is actually the Type1 vstem3 operator */
1080  op = cff_op_vstem;
1081  break;
1082  case 2: /* this is actually the Type1 hstem3 operator */
1083  op = cff_op_hstem;
1084  break;
1085  case 3:
1086  op = cff_op_and;
1087  break;
1088  case 4:
1089  op = cff_op_or;
1090  break;
1091  case 5:
1092  op = cff_op_not;
1093  break;
1094  case 6:
1095  op = cff_op_seac;
1096  break;
1097  case 7:
1098  op = cff_op_sbw;
1099  break;
1100  case 8:
1101  op = cff_op_store;
1102  break;
1103  case 9:
1104  op = cff_op_abs;
1105  break;
1106  case 10:
1107  op = cff_op_add;
1108  break;
1109  case 11:
1110  op = cff_op_sub;
1111  break;
1112  case 12:
1113  op = cff_op_div;
1114  break;
1115  case 13:
1116  op = cff_op_load;
1117  break;
1118  case 14:
1119  op = cff_op_neg;
1120  break;
1121  case 15:
1122  op = cff_op_eq;
1123  break;
1124  case 16:
1125  op = cff_op_callothersubr;
1126  break;
1127  case 17:
1128  op = cff_op_pop;
1129  break;
1130  case 18:
1131  op = cff_op_drop;
1132  break;
1133  case 20:
1134  op = cff_op_put;
1135  break;
1136  case 21:
1137  op = cff_op_get;
1138  break;
1139  case 22:
1140  op = cff_op_ifelse;
1141  break;
1142  case 23:
1143  op = cff_op_random;
1144  break;
1145  case 24:
1146  op = cff_op_mul;
1147  break;
1148  case 26:
1149  op = cff_op_sqrt;
1150  break;
1151  case 27:
1152  op = cff_op_dup;
1153  break;
1154  case 28:
1155  op = cff_op_exch;
1156  break;
1157  case 29:
1158  op = cff_op_index;
1159  break;
1160  case 30:
1161  op = cff_op_roll;
1162  break;
1163  case 33:
1165  break;
1166  case 34:
1167  op = cff_op_hflex;
1168  break;
1169  case 35:
1170  op = cff_op_flex;
1171  break;
1172  case 36:
1173  op = cff_op_hflex1;
1174  break;
1175  case 37:
1176  op = cff_op_flex1;
1177  break;
1178  default:
1179  FT_TRACE4(( " unknown op (12, %d)\n", v ));
1180  break;
1181  }
1182  }
1183  break;
1184  case 13:
1185  op = cff_op_hsbw;
1186  break;
1187  case 14:
1188  op = cff_op_endchar;
1189  break;
1190  case 16:
1191  op = cff_op_blend;
1192  break;
1193  case 18:
1194  op = cff_op_hstemhm;
1195  break;
1196  case 19:
1197  op = cff_op_hintmask;
1198  break;
1199  case 20:
1200  op = cff_op_cntrmask;
1201  break;
1202  case 21:
1203  op = cff_op_rmoveto;
1204  break;
1205  case 22:
1206  op = cff_op_hmoveto;
1207  break;
1208  case 23:
1209  op = cff_op_vstemhm;
1210  break;
1211  case 24:
1212  op = cff_op_rcurveline;
1213  break;
1214  case 25:
1215  op = cff_op_rlinecurve;
1216  break;
1217  case 26:
1218  op = cff_op_vvcurveto;
1219  break;
1220  case 27:
1221  op = cff_op_hhcurveto;
1222  break;
1223  case 29:
1224  op = cff_op_callgsubr;
1225  break;
1226  case 30:
1227  op = cff_op_vhcurveto;
1228  break;
1229  case 31:
1230  op = cff_op_hvcurveto;
1231  break;
1232  default:
1233  FT_TRACE4(( " unknown op (%d)\n", v ));
1234  break;
1235  }
1236 
1237  if ( op == cff_op_unknown )
1238  continue;
1239 
1240  /* check arguments */
1241  req_args = cff_argument_counts[op];
1242  if ( req_args & CFF_COUNT_CHECK_WIDTH )
1243  {
1244  if ( num_args > 0 && decoder->read_width )
1245  {
1246  /* If `nominal_width' is non-zero, the number is really a */
1247  /* difference against `nominal_width'. Else, the number here */
1248  /* is truly a width, not a difference against `nominal_width'. */
1249  /* If the font does not set `nominal_width', then */
1250  /* `nominal_width' defaults to zero, and so we can set */
1251  /* `glyph_width' to `nominal_width' plus number on the stack */
1252  /* -- for either case. */
1253 
1254  FT_Int set_width_ok;
1255 
1256 
1257  switch ( op )
1258  {
1259  case cff_op_hmoveto:
1260  case cff_op_vmoveto:
1261  set_width_ok = num_args & 2;
1262  break;
1263 
1264  case cff_op_hstem:
1265  case cff_op_vstem:
1266  case cff_op_hstemhm:
1267  case cff_op_vstemhm:
1268  case cff_op_rmoveto:
1269  case cff_op_hintmask:
1270  case cff_op_cntrmask:
1271  set_width_ok = num_args & 1;
1272  break;
1273 
1274  case cff_op_endchar:
1275  /* If there is a width specified for endchar, we either have */
1276  /* 1 argument or 5 arguments. We like to argue. */
1277  set_width_ok = ( num_args == 5 ) || ( num_args == 1 );
1278  break;
1279 
1280  default:
1281  set_width_ok = 0;
1282  break;
1283  }
1284 
1285  if ( set_width_ok )
1286  {
1287  decoder->glyph_width = decoder->nominal_width +
1288  ( stack[0] >> 16 );
1289 
1290  if ( decoder->width_only )
1291  {
1292  /* we only want the advance width; stop here */
1293  break;
1294  }
1295 
1296  /* Consumed an argument. */
1297  num_args--;
1298  }
1299  }
1300 
1301  decoder->read_width = 0;
1302  req_args = 0;
1303  }
1304 
1305  req_args &= 0x000F;
1306  if ( num_args < req_args )
1307  goto Stack_Underflow;
1308  args -= req_args;
1309  num_args -= req_args;
1310 
1311  /* At this point, `args' points to the first argument of the */
1312  /* operand in case `req_args' isn't zero. Otherwise, we have */
1313  /* to adjust `args' manually. */
1314 
1315  /* Note that we only pop arguments from the stack which we */
1316  /* really need and can digest so that we can continue in case */
1317  /* of superfluous stack elements. */
1318 
1319  switch ( op )
1320  {
1321  case cff_op_hstem:
1322  case cff_op_vstem:
1323  case cff_op_hstemhm:
1324  case cff_op_vstemhm:
1325  /* the number of arguments is always even here */
1326  FT_TRACE4((
1327  op == cff_op_hstem ? " hstem\n" :
1328  ( op == cff_op_vstem ? " vstem\n" :
1329  ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) ));
1330 
1331  if ( hinter )
1332  hinter->stems( hinter->hints,
1333  ( op == cff_op_hstem || op == cff_op_hstemhm ),
1334  num_args / 2,
1335  args - ( num_args & ~1 ) );
1336 
1337  decoder->num_hints += num_args / 2;
1338  args = stack;
1339  break;
1340 
1341  case cff_op_hintmask:
1342  case cff_op_cntrmask:
1343  FT_TRACE4(( op == cff_op_hintmask ? " hintmask" : " cntrmask" ));
1344 
1345  /* implement vstem when needed -- */
1346  /* the specification doesn't say it, but this also works */
1347  /* with the 'cntrmask' operator */
1348  /* */
1349  if ( num_args > 0 )
1350  {
1351  if ( hinter )
1352  hinter->stems( hinter->hints,
1353  0,
1354  num_args / 2,
1355  args - ( num_args & ~1 ) );
1356 
1357  decoder->num_hints += num_args / 2;
1358  }
1359 
1360  /* In a valid charstring there must be at least one byte */
1361  /* after `hintmask' or `cntrmask' (e.g., for a `return' */
1362  /* instruction). Additionally, there must be space for */
1363  /* `num_hints' bits. */
1364 
1365  if ( ( ip + ( ( decoder->num_hints + 7 ) >> 3 ) ) >= limit )
1366  goto Syntax_Error;
1367 
1368  if ( hinter )
1369  {
1370  if ( op == cff_op_hintmask )
1371  hinter->hintmask( hinter->hints,
1372  builder->current->n_points,
1373  decoder->num_hints,
1374  ip );
1375  else
1376  hinter->counter( hinter->hints,
1377  decoder->num_hints,
1378  ip );
1379  }
1380 
1381 #ifdef FT_DEBUG_LEVEL_TRACE
1382  {
1383  FT_UInt maskbyte;
1384 
1385 
1386  FT_TRACE4(( " (maskbytes:" ));
1387 
1388  for ( maskbyte = 0;
1389  maskbyte < (FT_UInt)( ( decoder->num_hints + 7 ) >> 3 );
1390  maskbyte++, ip++ )
1391  FT_TRACE4(( " 0x%02X", *ip ));
1392 
1393  FT_TRACE4(( ")\n" ));
1394  }
1395 #else
1396  ip += ( decoder->num_hints + 7 ) >> 3;
1397 #endif
1398  args = stack;
1399  break;
1400 
1401  case cff_op_rmoveto:
1402  FT_TRACE4(( " rmoveto\n" ));
1403 
1404  cff_builder_close_contour( builder );
1405  builder->path_begun = 0;
1406  x += args[-2];
1407  y += args[-1];
1408  args = stack;
1409  break;
1410 
1411  case cff_op_vmoveto:
1412  FT_TRACE4(( " vmoveto\n" ));
1413 
1414  cff_builder_close_contour( builder );
1415  builder->path_begun = 0;
1416  y += args[-1];
1417  args = stack;
1418  break;
1419 
1420  case cff_op_hmoveto:
1421  FT_TRACE4(( " hmoveto\n" ));
1422 
1423  cff_builder_close_contour( builder );
1424  builder->path_begun = 0;
1425  x += args[-1];
1426  args = stack;
1427  break;
1428 
1429  case cff_op_rlineto:
1430  FT_TRACE4(( " rlineto\n" ));
1431 
1432  if ( cff_builder_start_point( builder, x, y ) ||
1433  cff_check_points( builder, num_args / 2 ) )
1434  goto Fail;
1435 
1436  if ( num_args < 2 )
1437  goto Stack_Underflow;
1438 
1439  args -= num_args & ~1;
1440  while ( args < decoder->top )
1441  {
1442  x += args[0];
1443  y += args[1];
1444  cff_builder_add_point( builder, x, y, 1 );
1445  args += 2;
1446  }
1447  args = stack;
1448  break;
1449 
1450  case cff_op_hlineto:
1451  case cff_op_vlineto:
1452  {
1453  FT_Int phase = ( op == cff_op_hlineto );
1454 
1455 
1456  FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n"
1457  : " vlineto\n" ));
1458 
1459  if ( num_args < 0 )
1460  goto Stack_Underflow;
1461 
1462  /* there exist subsetted fonts (found in PDFs) */
1463  /* which call `hlineto' without arguments */
1464  if ( num_args == 0 )
1465  break;
1466 
1467  if ( cff_builder_start_point( builder, x, y ) ||
1468  cff_check_points( builder, num_args ) )
1469  goto Fail;
1470 
1471  args = stack;
1472  while ( args < decoder->top )
1473  {
1474  if ( phase )
1475  x += args[0];
1476  else
1477  y += args[0];
1478 
1479  if ( cff_builder_add_point1( builder, x, y ) )
1480  goto Fail;
1481 
1482  args++;
1483  phase ^= 1;
1484  }
1485  args = stack;
1486  }
1487  break;
1488 
1489  case cff_op_rrcurveto:
1490  {
1491  FT_Int nargs;
1492 
1493 
1494  FT_TRACE4(( " rrcurveto\n" ));
1495 
1496  if ( num_args < 6 )
1497  goto Stack_Underflow;
1498 
1499  nargs = num_args - num_args % 6;
1500 
1501  if ( cff_builder_start_point( builder, x, y ) ||
1502  cff_check_points( builder, nargs / 2 ) )
1503  goto Fail;
1504 
1505  args -= nargs;
1506  while ( args < decoder->top )
1507  {
1508  x += args[0];
1509  y += args[1];
1510  cff_builder_add_point( builder, x, y, 0 );
1511  x += args[2];
1512  y += args[3];
1513  cff_builder_add_point( builder, x, y, 0 );
1514  x += args[4];
1515  y += args[5];
1516  cff_builder_add_point( builder, x, y, 1 );
1517  args += 6;
1518  }
1519  args = stack;
1520  }
1521  break;
1522 
1523  case cff_op_vvcurveto:
1524  {
1525  FT_Int nargs;
1526 
1527 
1528  FT_TRACE4(( " vvcurveto\n" ));
1529 
1530  if ( num_args < 4 )
1531  goto Stack_Underflow;
1532 
1533  /* if num_args isn't of the form 4n or 4n+1, */
1534  /* we enforce it by clearing the second bit */
1535 
1536  nargs = num_args & ~2;
1537 
1538  if ( cff_builder_start_point( builder, x, y ) )
1539  goto Fail;
1540 
1541  args -= nargs;
1542 
1543  if ( nargs & 1 )
1544  {
1545  x += args[0];
1546  args++;
1547  nargs--;
1548  }
1549 
1550  if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
1551  goto Fail;
1552 
1553  while ( args < decoder->top )
1554  {
1555  y += args[0];
1556  cff_builder_add_point( builder, x, y, 0 );
1557  x += args[1];
1558  y += args[2];
1559  cff_builder_add_point( builder, x, y, 0 );
1560  y += args[3];
1561  cff_builder_add_point( builder, x, y, 1 );
1562  args += 4;
1563  }
1564  args = stack;
1565  }
1566  break;
1567 
1568  case cff_op_hhcurveto:
1569  {
1570  FT_Int nargs;
1571 
1572 
1573  FT_TRACE4(( " hhcurveto\n" ));
1574 
1575  if ( num_args < 4 )
1576  goto Stack_Underflow;
1577 
1578  /* if num_args isn't of the form 4n or 4n+1, */
1579  /* we enforce it by clearing the second bit */
1580 
1581  nargs = num_args & ~2;
1582 
1583  if ( cff_builder_start_point( builder, x, y ) )
1584  goto Fail;
1585 
1586  args -= nargs;
1587  if ( nargs & 1 )
1588  {
1589  y += args[0];
1590  args++;
1591  nargs--;
1592  }
1593 
1594  if ( cff_check_points( builder, 3 * ( nargs / 4 ) ) )
1595  goto Fail;
1596 
1597  while ( args < decoder->top )
1598  {
1599  x += args[0];
1600  cff_builder_add_point( builder, x, y, 0 );
1601  x += args[1];
1602  y += args[2];
1603  cff_builder_add_point( builder, x, y, 0 );
1604  x += args[3];
1605  cff_builder_add_point( builder, x, y, 1 );
1606  args += 4;
1607  }
1608  args = stack;
1609  }
1610  break;
1611 
1612  case cff_op_vhcurveto:
1613  case cff_op_hvcurveto:
1614  {
1615  FT_Int phase;
1616  FT_Int nargs;
1617 
1618 
1619  FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n"
1620  : " hvcurveto\n" ));
1621 
1622  if ( cff_builder_start_point( builder, x, y ) )
1623  goto Fail;
1624 
1625  if ( num_args < 4 )
1626  goto Stack_Underflow;
1627 
1628  /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
1629  /* we enforce it by clearing the second bit */
1630 
1631  nargs = num_args & ~2;
1632 
1633  args -= nargs;
1634  if ( cff_check_points( builder, ( nargs / 4 ) * 3 ) )
1635  goto Stack_Underflow;
1636 
1637  phase = ( op == cff_op_hvcurveto );
1638 
1639  while ( nargs >= 4 )
1640  {
1641  nargs -= 4;
1642  if ( phase )
1643  {
1644  x += args[0];
1645  cff_builder_add_point( builder, x, y, 0 );
1646  x += args[1];
1647  y += args[2];
1648  cff_builder_add_point( builder, x, y, 0 );
1649  y += args[3];
1650  if ( nargs == 1 )
1651  x += args[4];
1652  cff_builder_add_point( builder, x, y, 1 );
1653  }
1654  else
1655  {
1656  y += args[0];
1657  cff_builder_add_point( builder, x, y, 0 );
1658  x += args[1];
1659  y += args[2];
1660  cff_builder_add_point( builder, x, y, 0 );
1661  x += args[3];
1662  if ( nargs == 1 )
1663  y += args[4];
1664  cff_builder_add_point( builder, x, y, 1 );
1665  }
1666  args += 4;
1667  phase ^= 1;
1668  }
1669  args = stack;
1670  }
1671  break;
1672 
1673  case cff_op_rlinecurve:
1674  {
1675  FT_Int num_lines;
1676  FT_Int nargs;
1677 
1678 
1679  FT_TRACE4(( " rlinecurve\n" ));
1680 
1681  if ( num_args < 8 )
1682  goto Stack_Underflow;
1683 
1684  nargs = num_args & ~1;
1685  num_lines = ( nargs - 6 ) / 2;
1686 
1687  if ( cff_builder_start_point( builder, x, y ) ||
1688  cff_check_points( builder, num_lines + 3 ) )
1689  goto Fail;
1690 
1691  args -= nargs;
1692 
1693  /* first, add the line segments */
1694  while ( num_lines > 0 )
1695  {
1696  x += args[0];
1697  y += args[1];
1698  cff_builder_add_point( builder, x, y, 1 );
1699  args += 2;
1700  num_lines--;
1701  }
1702 
1703  /* then the curve */
1704  x += args[0];
1705  y += args[1];
1706  cff_builder_add_point( builder, x, y, 0 );
1707  x += args[2];
1708  y += args[3];
1709  cff_builder_add_point( builder, x, y, 0 );
1710  x += args[4];
1711  y += args[5];
1712  cff_builder_add_point( builder, x, y, 1 );
1713  args = stack;
1714  }
1715  break;
1716 
1717  case cff_op_rcurveline:
1718  {
1719  FT_Int num_curves;
1720  FT_Int nargs;
1721 
1722 
1723  FT_TRACE4(( " rcurveline\n" ));
1724 
1725  if ( num_args < 8 )
1726  goto Stack_Underflow;
1727 
1728  nargs = num_args - 2;
1729  nargs = nargs - nargs % 6 + 2;
1730  num_curves = ( nargs - 2 ) / 6;
1731 
1732  if ( cff_builder_start_point( builder, x, y ) ||
1733  cff_check_points( builder, num_curves * 3 + 2 ) )
1734  goto Fail;
1735 
1736  args -= nargs;
1737 
1738  /* first, add the curves */
1739  while ( num_curves > 0 )
1740  {
1741  x += args[0];
1742  y += args[1];
1743  cff_builder_add_point( builder, x, y, 0 );
1744  x += args[2];
1745  y += args[3];
1746  cff_builder_add_point( builder, x, y, 0 );
1747  x += args[4];
1748  y += args[5];
1749  cff_builder_add_point( builder, x, y, 1 );
1750  args += 6;
1751  num_curves--;
1752  }
1753 
1754  /* then the final line */
1755  x += args[0];
1756  y += args[1];
1757  cff_builder_add_point( builder, x, y, 1 );
1758  args = stack;
1759  }
1760  break;
1761 
1762  case cff_op_hflex1:
1763  {
1764  FT_Pos start_y;
1765 
1766 
1767  FT_TRACE4(( " hflex1\n" ));
1768 
1769  /* adding five more points: 4 control points, 1 on-curve point */
1770  /* -- make sure we have enough space for the start point if it */
1771  /* needs to be added */
1772  if ( cff_builder_start_point( builder, x, y ) ||
1773  cff_check_points( builder, 6 ) )
1774  goto Fail;
1775 
1776  /* record the starting point's y position for later use */
1777  start_y = y;
1778 
1779  /* first control point */
1780  x += args[0];
1781  y += args[1];
1782  cff_builder_add_point( builder, x, y, 0 );
1783 
1784  /* second control point */
1785  x += args[2];
1786  y += args[3];
1787  cff_builder_add_point( builder, x, y, 0 );
1788 
1789  /* join point; on curve, with y-value the same as the last */
1790  /* control point's y-value */
1791  x += args[4];
1792  cff_builder_add_point( builder, x, y, 1 );
1793 
1794  /* third control point, with y-value the same as the join */
1795  /* point's y-value */
1796  x += args[5];
1797  cff_builder_add_point( builder, x, y, 0 );
1798 
1799  /* fourth control point */
1800  x += args[6];
1801  y += args[7];
1802  cff_builder_add_point( builder, x, y, 0 );
1803 
1804  /* ending point, with y-value the same as the start */
1805  x += args[8];
1806  y = start_y;
1807  cff_builder_add_point( builder, x, y, 1 );
1808 
1809  args = stack;
1810  break;
1811  }
1812 
1813  case cff_op_hflex:
1814  {
1815  FT_Pos start_y;
1816 
1817 
1818  FT_TRACE4(( " hflex\n" ));
1819 
1820  /* adding six more points; 4 control points, 2 on-curve points */
1821  if ( cff_builder_start_point( builder, x, y ) ||
1822  cff_check_points( builder, 6 ) )
1823  goto Fail;
1824 
1825  /* record the starting point's y-position for later use */
1826  start_y = y;
1827 
1828  /* first control point */
1829  x += args[0];
1830  cff_builder_add_point( builder, x, y, 0 );
1831 
1832  /* second control point */
1833  x += args[1];
1834  y += args[2];
1835  cff_builder_add_point( builder, x, y, 0 );
1836 
1837  /* join point; on curve, with y-value the same as the last */
1838  /* control point's y-value */
1839  x += args[3];
1840  cff_builder_add_point( builder, x, y, 1 );
1841 
1842  /* third control point, with y-value the same as the join */
1843  /* point's y-value */
1844  x += args[4];
1845  cff_builder_add_point( builder, x, y, 0 );
1846 
1847  /* fourth control point */
1848  x += args[5];
1849  y = start_y;
1850  cff_builder_add_point( builder, x, y, 0 );
1851 
1852  /* ending point, with y-value the same as the start point's */
1853  /* y-value -- we don't add this point, though */
1854  x += args[6];
1855  cff_builder_add_point( builder, x, y, 1 );
1856 
1857  args = stack;
1858  break;
1859  }
1860 
1861  case cff_op_flex1:
1862  {
1863  FT_Pos start_x, start_y; /* record start x, y values for */
1864  /* alter use */
1865  FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */
1866  /* algorithm below */
1867  FT_Int horizontal, count;
1868  FT_Fixed* temp;
1869 
1870 
1871  FT_TRACE4(( " flex1\n" ));
1872 
1873  /* adding six more points; 4 control points, 2 on-curve points */
1874  if ( cff_builder_start_point( builder, x, y ) ||
1875  cff_check_points( builder, 6 ) )
1876  goto Fail;
1877 
1878  /* record the starting point's x, y position for later use */
1879  start_x = x;
1880  start_y = y;
1881 
1882  /* XXX: figure out whether this is supposed to be a horizontal */
1883  /* or vertical flex; the Type 2 specification is vague... */
1884 
1885  temp = args;
1886 
1887  /* grab up to the last argument */
1888  for ( count = 5; count > 0; count-- )
1889  {
1890  dx += temp[0];
1891  dy += temp[1];
1892  temp += 2;
1893  }
1894 
1895  if ( dx < 0 )
1896  dx = -dx;
1897  if ( dy < 0 )
1898  dy = -dy;
1899 
1900  /* strange test, but here it is... */
1901  horizontal = ( dx > dy );
1902 
1903  for ( count = 5; count > 0; count-- )
1904  {
1905  x += args[0];
1906  y += args[1];
1907  cff_builder_add_point( builder, x, y,
1908  (FT_Bool)( count == 3 ) );
1909  args += 2;
1910  }
1911 
1912  /* is last operand an x- or y-delta? */
1913  if ( horizontal )
1914  {
1915  x += args[0];
1916  y = start_y;
1917  }
1918  else
1919  {
1920  x = start_x;
1921  y += args[0];
1922  }
1923 
1924  cff_builder_add_point( builder, x, y, 1 );
1925 
1926  args = stack;
1927  break;
1928  }
1929 
1930  case cff_op_flex:
1931  {
1932  FT_UInt count;
1933 
1934 
1935  FT_TRACE4(( " flex\n" ));
1936 
1937  if ( cff_builder_start_point( builder, x, y ) ||
1938  cff_check_points( builder, 6 ) )
1939  goto Fail;
1940 
1941  for ( count = 6; count > 0; count-- )
1942  {
1943  x += args[0];
1944  y += args[1];
1945  cff_builder_add_point( builder, x, y,
1946  (FT_Bool)( count == 4 || count == 1 ) );
1947  args += 2;
1948  }
1949 
1950  args = stack;
1951  }
1952  break;
1953 
1954  case cff_op_seac:
1955  FT_TRACE4(( " seac\n" ));
1956 
1957  error = cff_operator_seac( decoder,
1958  args[0], args[1], args[2],
1959  (FT_Int)( args[3] >> 16 ),
1960  (FT_Int)( args[4] >> 16 ) );
1961 
1962  /* add current outline to the glyph slot */
1963  FT_GlyphLoader_Add( builder->loader );
1964 
1965  /* return now! */
1966  FT_TRACE4(( "\n" ));
1967  return error;
1968 
1969  case cff_op_endchar:
1970  FT_TRACE4(( " endchar\n" ));
1971 
1972  /* We are going to emulate the seac operator. */
1973  if ( num_args >= 4 )
1974  {
1975  /* Save glyph width so that the subglyphs don't overwrite it. */
1976  FT_Pos glyph_width = decoder->glyph_width;
1977 
1978 
1979  error = cff_operator_seac( decoder,
1980  0L, args[-4], args[-3],
1981  (FT_Int)( args[-2] >> 16 ),
1982  (FT_Int)( args[-1] >> 16 ) );
1983 
1984  decoder->glyph_width = glyph_width;
1985  }
1986  else
1987  {
1988  if ( !error )
1989  error = FT_Err_Ok;
1990 
1991  cff_builder_close_contour( builder );
1992 
1993  /* close hints recording session */
1994  if ( hinter )
1995  {
1996  if ( hinter->close( hinter->hints,
1997  builder->current->n_points ) )
1998  goto Syntax_Error;
1999 
2000  /* apply hints to the loaded glyph outline now */
2001  hinter->apply( hinter->hints,
2002  builder->current,
2003  (PSH_Globals)builder->hints_globals,
2004  decoder->hint_mode );
2005  }
2006 
2007  /* add current outline to the glyph slot */
2008  FT_GlyphLoader_Add( builder->loader );
2009  }
2010 
2011  /* return now! */
2012  FT_TRACE4(( "\n" ));
2013  return error;
2014 
2015  case cff_op_abs:
2016  FT_TRACE4(( " abs\n" ));
2017 
2018  if ( args[0] < 0 )
2019  args[0] = -args[0];
2020  args++;
2021  break;
2022 
2023  case cff_op_add:
2024  FT_TRACE4(( " add\n" ));
2025 
2026  args[0] += args[1];
2027  args++;
2028  break;
2029 
2030  case cff_op_sub:
2031  FT_TRACE4(( " sub\n" ));
2032 
2033  args[0] -= args[1];
2034  args++;
2035  break;
2036 
2037  case cff_op_div:
2038  FT_TRACE4(( " div\n" ));
2039 
2040  args[0] = FT_DivFix( args[0], args[1] );
2041  args++;
2042  break;
2043 
2044  case cff_op_neg:
2045  FT_TRACE4(( " neg\n" ));
2046 
2047  args[0] = -args[0];
2048  args++;
2049  break;
2050 
2051  case cff_op_random:
2052  {
2053  FT_Fixed Rand;
2054 
2055 
2056  FT_TRACE4(( " rand\n" ));
2057 
2058  Rand = seed;
2059  if ( Rand >= 0x8000L )
2060  Rand++;
2061 
2062  args[0] = Rand;
2063  seed = FT_MulFix( seed, 0x10000L - seed );
2064  if ( seed == 0 )
2065  seed += 0x2873;
2066  args++;
2067  }
2068  break;
2069 
2070  case cff_op_mul:
2071  FT_TRACE4(( " mul\n" ));
2072 
2073  args[0] = FT_MulFix( args[0], args[1] );
2074  args++;
2075  break;
2076 
2077  case cff_op_sqrt:
2078  FT_TRACE4(( " sqrt\n" ));
2079 
2080  if ( args[0] > 0 )
2081  {
2082  FT_Int count = 9;
2083  FT_Fixed root = args[0];
2084  FT_Fixed new_root;
2085 
2086 
2087  for (;;)
2088  {
2089  new_root = ( root + FT_DivFix( args[0], root ) + 1 ) >> 1;
2090  if ( new_root == root || count <= 0 )
2091  break;
2092  root = new_root;
2093  }
2094  args[0] = new_root;
2095  }
2096  else
2097  args[0] = 0;
2098  args++;
2099  break;
2100 
2101  case cff_op_drop:
2102  /* nothing */
2103  FT_TRACE4(( " drop\n" ));
2104 
2105  break;
2106 
2107  case cff_op_exch:
2108  {
2109  FT_Fixed tmp;
2110 
2111 
2112  FT_TRACE4(( " exch\n" ));
2113 
2114  tmp = args[0];
2115  args[0] = args[1];
2116  args[1] = tmp;
2117  args += 2;
2118  }
2119  break;
2120 
2121  case cff_op_index:
2122  {
2123  FT_Int idx = (FT_Int)( args[0] >> 16 );
2124 
2125 
2126  FT_TRACE4(( " index\n" ));
2127 
2128  if ( idx < 0 )
2129  idx = 0;
2130  else if ( idx > num_args - 2 )
2131  idx = num_args - 2;
2132  args[0] = args[-( idx + 1 )];
2133  args++;
2134  }
2135  break;
2136 
2137  case cff_op_roll:
2138  {
2139  FT_Int count = (FT_Int)( args[0] >> 16 );
2140  FT_Int idx = (FT_Int)( args[1] >> 16 );
2141 
2142 
2143  FT_TRACE4(( " roll\n" ));
2144 
2145  if ( count <= 0 )
2146  count = 1;
2147 
2148  args -= count;
2149  if ( args < stack )
2150  goto Stack_Underflow;
2151 
2152  if ( idx >= 0 )
2153  {
2154  while ( idx > 0 )
2155  {
2156  FT_Fixed tmp = args[count - 1];
2157  FT_Int i;
2158 
2159 
2160  for ( i = count - 2; i >= 0; i-- )
2161  args[i + 1] = args[i];
2162  args[0] = tmp;
2163  idx--;
2164  }
2165  }
2166  else
2167  {
2168  while ( idx < 0 )
2169  {
2170  FT_Fixed tmp = args[0];
2171  FT_Int i;
2172 
2173 
2174  for ( i = 0; i < count - 1; i++ )
2175  args[i] = args[i + 1];
2176  args[count - 1] = tmp;
2177  idx++;
2178  }
2179  }
2180  args += count;
2181  }
2182  break;
2183 
2184  case cff_op_dup:
2185  FT_TRACE4(( " dup\n" ));
2186 
2187  args[1] = args[0];
2188  args += 2;
2189  break;
2190 
2191  case cff_op_put:
2192  {
2193  FT_Fixed val = args[0];
2194  FT_Int idx = (FT_Int)( args[1] >> 16 );
2195 
2196 
2197  FT_TRACE4(( " put\n" ));
2198 
2199  if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
2200  decoder->buildchar[idx] = val;
2201  }
2202  break;
2203 
2204  case cff_op_get:
2205  {
2206  FT_Int idx = (FT_Int)( args[0] >> 16 );
2207  FT_Fixed val = 0;
2208 
2209 
2210  FT_TRACE4(( " get\n" ));
2211 
2212  if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
2213  val = decoder->buildchar[idx];
2214 
2215  args[0] = val;
2216  args++;
2217  }
2218  break;
2219 
2220  case cff_op_store:
2221  FT_TRACE4(( " store\n"));
2222 
2223  goto Unimplemented;
2224 
2225  case cff_op_load:
2226  FT_TRACE4(( " load\n" ));
2227 
2228  goto Unimplemented;
2229 
2230  case cff_op_dotsection:
2231  /* this operator is deprecated and ignored by the parser */
2232  FT_TRACE4(( " dotsection\n" ));
2233  break;
2234 
2235  case cff_op_closepath:
2236  /* this is an invalid Type 2 operator; however, there */
2237  /* exist fonts which are incorrectly converted from probably */
2238  /* Type 1 to CFF, and some parsers seem to accept it */
2239 
2240  FT_TRACE4(( " closepath (invalid op)\n" ));
2241 
2242  args = stack;
2243  break;
2244 
2245  case cff_op_hsbw:
2246  /* this is an invalid Type 2 operator; however, there */
2247  /* exist fonts which are incorrectly converted from probably */
2248  /* Type 1 to CFF, and some parsers seem to accept it */
2249 
2250  FT_TRACE4(( " hsbw (invalid op)\n" ));
2251 
2252  decoder->glyph_width = decoder->nominal_width + ( args[1] >> 16 );
2253 
2254  decoder->builder.left_bearing.x = args[0];
2255  decoder->builder.left_bearing.y = 0;
2256 
2257  x = decoder->builder.pos_x + args[0];
2258  y = decoder->builder.pos_y;
2259  args = stack;
2260  break;
2261 
2262  case cff_op_sbw:
2263  /* this is an invalid Type 2 operator; however, there */
2264  /* exist fonts which are incorrectly converted from probably */
2265  /* Type 1 to CFF, and some parsers seem to accept it */
2266 
2267  FT_TRACE4(( " sbw (invalid op)\n" ));
2268 
2269  decoder->glyph_width = decoder->nominal_width + ( args[2] >> 16 );
2270 
2271  decoder->builder.left_bearing.x = args[0];
2272  decoder->builder.left_bearing.y = args[1];
2273 
2274  x = decoder->builder.pos_x + args[0];
2275  y = decoder->builder.pos_y + args[1];
2276  args = stack;
2277  break;
2278 
2280  /* this is an invalid Type 2 operator; however, there */
2281  /* exist fonts which are incorrectly converted from probably */
2282  /* Type 1 to CFF, and some parsers seem to accept it */
2283 
2284  FT_TRACE4(( " setcurrentpoint (invalid op)\n" ));
2285 
2286  x = decoder->builder.pos_x + args[0];
2287  y = decoder->builder.pos_y + args[1];
2288  args = stack;
2289  break;
2290 
2291  case cff_op_callothersubr:
2292  /* this is an invalid Type 2 operator; however, there */
2293  /* exist fonts which are incorrectly converted from probably */
2294  /* Type 1 to CFF, and some parsers seem to accept it */
2295 
2296  FT_TRACE4(( " callothersubr (invalid op)\n" ));
2297 
2298  /* subsequent `pop' operands should add the arguments, */
2299  /* this is the implementation described for `unknown' other */
2300  /* subroutines in the Type1 spec. */
2301  /* */
2302  /* XXX Fix return arguments (see discussion below). */
2303  args -= 2 + ( args[-2] >> 16 );
2304  if ( args < stack )
2305  goto Stack_Underflow;
2306  break;
2307 
2308  case cff_op_pop:
2309  /* this is an invalid Type 2 operator; however, there */
2310  /* exist fonts which are incorrectly converted from probably */
2311  /* Type 1 to CFF, and some parsers seem to accept it */
2312 
2313  FT_TRACE4(( " pop (invalid op)\n" ));
2314 
2315  /* XXX Increasing `args' is wrong: After a certain number of */
2316  /* `pop's we get a stack overflow. Reason for doing it is */
2317  /* code like this (actually found in a CFF font): */
2318  /* */
2319  /* 17 1 3 callothersubr */
2320  /* pop */
2321  /* callsubr */
2322  /* */
2323  /* Since we handle `callothersubr' as a no-op, and */
2324  /* `callsubr' needs at least one argument, `pop' can't be a */
2325  /* no-op too as it basically should be. */
2326  /* */
2327  /* The right solution would be to provide real support for */
2328  /* `callothersubr' as done in `t1decode.c', however, given */
2329  /* the fact that CFF fonts with `pop' are invalid, it is */
2330  /* questionable whether it is worth the time. */
2331  args++;
2332  break;
2333 
2334  case cff_op_and:
2335  {
2336  FT_Fixed cond = args[0] && args[1];
2337 
2338 
2339  FT_TRACE4(( " and\n" ));
2340 
2341  args[0] = cond ? 0x10000L : 0;
2342  args++;
2343  }
2344  break;
2345 
2346  case cff_op_or:
2347  {
2348  FT_Fixed cond = args[0] || args[1];
2349 
2350 
2351  FT_TRACE4(( " or\n" ));
2352 
2353  args[0] = cond ? 0x10000L : 0;
2354  args++;
2355  }
2356  break;
2357 
2358  case cff_op_eq:
2359  {
2360  FT_Fixed cond = !args[0];
2361 
2362 
2363  FT_TRACE4(( " eq\n" ));
2364 
2365  args[0] = cond ? 0x10000L : 0;
2366  args++;
2367  }
2368  break;
2369 
2370  case cff_op_ifelse:
2371  {
2372  FT_Fixed cond = ( args[2] <= args[3] );
2373 
2374 
2375  FT_TRACE4(( " ifelse\n" ));
2376 
2377  if ( !cond )
2378  args[0] = args[1];
2379  args++;
2380  }
2381  break;
2382 
2383  case cff_op_callsubr:
2384  {
2385  FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) +
2386  decoder->locals_bias );
2387 
2388 
2389  FT_TRACE4(( " callsubr(%d)\n", idx ));
2390 
2391  if ( idx >= decoder->num_locals )
2392  {
2393  FT_ERROR(( "cff_decoder_parse_charstrings:"
2394  " invalid local subr index\n" ));
2395  goto Syntax_Error;
2396  }
2397 
2398  if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
2399  {
2400  FT_ERROR(( "cff_decoder_parse_charstrings:"
2401  " too many nested subrs\n" ));
2402  goto Syntax_Error;
2403  }
2404 
2405  zone->cursor = ip; /* save current instruction pointer */
2406 
2407  zone++;
2408  zone->base = decoder->locals[idx];
2409  zone->limit = decoder->locals[idx + 1];
2410  zone->cursor = zone->base;
2411 
2412  if ( !zone->base || zone->limit == zone->base )
2413  {
2414  FT_ERROR(( "cff_decoder_parse_charstrings:"
2415  " invoking empty subrs\n" ));
2416  goto Syntax_Error;
2417  }
2418 
2419  decoder->zone = zone;
2420  ip = zone->base;
2421  limit = zone->limit;
2422  }
2423  break;
2424 
2425  case cff_op_callgsubr:
2426  {
2427  FT_UInt idx = (FT_UInt)( ( args[0] >> 16 ) +
2428  decoder->globals_bias );
2429 
2430 
2431  FT_TRACE4(( " callgsubr(%d)\n", idx ));
2432 
2433  if ( idx >= decoder->num_globals )
2434  {
2435  FT_ERROR(( "cff_decoder_parse_charstrings:"
2436  " invalid global subr index\n" ));
2437  goto Syntax_Error;
2438  }
2439 
2440  if ( zone - decoder->zones >= CFF_MAX_SUBRS_CALLS )
2441  {
2442  FT_ERROR(( "cff_decoder_parse_charstrings:"
2443  " too many nested subrs\n" ));
2444  goto Syntax_Error;
2445  }
2446 
2447  zone->cursor = ip; /* save current instruction pointer */
2448 
2449  zone++;
2450  zone->base = decoder->globals[idx];
2451  zone->limit = decoder->globals[idx + 1];
2452  zone->cursor = zone->base;
2453 
2454  if ( !zone->base || zone->limit == zone->base )
2455  {
2456  FT_ERROR(( "cff_decoder_parse_charstrings:"
2457  " invoking empty subrs\n" ));
2458  goto Syntax_Error;
2459  }
2460 
2461  decoder->zone = zone;
2462  ip = zone->base;
2463  limit = zone->limit;
2464  }
2465  break;
2466 
2467  case cff_op_return:
2468  FT_TRACE4(( " return\n" ));
2469 
2470  if ( decoder->zone <= decoder->zones )
2471  {
2472  FT_ERROR(( "cff_decoder_parse_charstrings:"
2473  " unexpected return\n" ));
2474  goto Syntax_Error;
2475  }
2476 
2477  decoder->zone--;
2478  zone = decoder->zone;
2479  ip = zone->cursor;
2480  limit = zone->limit;
2481  break;
2482 
2483  default:
2484  Unimplemented:
2485  FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));
2486 
2487  if ( ip[-1] == 12 )
2488  FT_ERROR(( " %d", ip[0] ));
2489  FT_ERROR(( "\n" ));
2490 
2491  return FT_THROW( Unimplemented_Feature );
2492  }
2493 
2494  decoder->top = args;
2495 
2496  if ( decoder->top - stack >= CFF_MAX_OPERANDS )
2497  goto Stack_Overflow;
2498 
2499  } /* general operator processing */
2500 
2501  } /* while ip < limit */
2502 
2503  FT_TRACE4(( "..end..\n\n" ));
2504 
2505  Fail:
2506  return error;
2507 
2508  Syntax_Error:
2509  FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error\n" ));
2510  return FT_THROW( Invalid_File_Format );
2511 
2512  Stack_Underflow:
2513  FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow\n" ));
2514  return FT_THROW( Too_Few_Arguments );
2515 
2516  Stack_Overflow:
2517  FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow\n" ));
2518  return FT_THROW( Stack_Overflow );
2519  }
2520 
2521 
2522  /*************************************************************************/
2523  /*************************************************************************/
2524  /*************************************************************************/
2525  /********** *********/
2526  /********** *********/
2527  /********** COMPUTE THE MAXIMUM ADVANCE WIDTH *********/
2528  /********** *********/
2529  /********** The following code is in charge of computing *********/
2530  /********** the maximum advance width of the font. It *********/
2531  /********** quickly processes each glyph charstring to *********/
2532  /********** extract the value from either a `sbw' or `seac' *********/
2533  /********** operator. *********/
2534  /********** *********/
2535  /*************************************************************************/
2536  /*************************************************************************/
2537  /*************************************************************************/
2538 
2539 
2540 #if 0 /* unused until we support pure CFF fonts */
2541 
2542 
2544  cff_compute_max_advance( TT_Face face,
2545  FT_Int* max_advance )
2546  {
2548  CFF_Decoder decoder;
2549  FT_Int glyph_index;
2550  CFF_Font cff = (CFF_Font)face->other;
2551 
2552 
2553  *max_advance = 0;
2554 
2555  /* Initialize load decoder */
2556  cff_decoder_init( &decoder, face, 0, 0, 0, 0 );
2557 
2558  decoder.builder.metrics_only = 1;
2559  decoder.builder.load_points = 0;
2560 
2561  /* For each glyph, parse the glyph charstring and extract */
2562  /* the advance width. */
2563  for ( glyph_index = 0; glyph_index < face->root.num_glyphs;
2564  glyph_index++ )
2565  {
2566  FT_Byte* charstring;
2567  FT_ULong charstring_len;
2568 
2569 
2570  /* now get load the unscaled outline */
2571  error = cff_get_glyph_data( face, glyph_index,
2572  &charstring, &charstring_len );
2573  if ( !error )
2574  {
2575  error = cff_decoder_prepare( &decoder, size, glyph_index );
2576  if ( !error )
2577  error = cff_decoder_parse_charstrings( &decoder,
2578  charstring,
2579  charstring_len );
2580 
2581  cff_free_glyph_data( face, &charstring, &charstring_len );
2582  }
2583 
2584  /* ignore the error if one has occurred -- skip to next glyph */
2585  error = FT_Err_Ok;
2586  }
2587 
2588  *max_advance = decoder.builder.advance.x;
2589 
2590  return FT_Err_Ok;
2591  }
2592 
2593 
2594 #endif /* 0 */
2595 
2596 
2599  CFF_Size size,
2600  FT_UInt glyph_index,
2601  FT_Int32 load_flags )
2602  {
2603  FT_Error error;
2604  CFF_Decoder decoder;
2605  TT_Face face = (TT_Face)glyph->root.face;
2606  FT_Bool hinting, scaled, force_scaling;
2607  CFF_Font cff = (CFF_Font)face->extra.data;
2608 
2609  FT_Matrix font_matrix;
2610  FT_Vector font_offset;
2611 
2612 
2613  force_scaling = FALSE;
2614 
2615  /* in a CID-keyed font, consider `glyph_index' as a CID and map */
2616  /* it immediately to the real glyph_index -- if it isn't a */
2617  /* subsetted font, glyph_indices and CIDs are identical, though */
2618  if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&
2619  cff->charset.cids )
2620  {
2621  /* don't handle CID 0 (.notdef) which is directly mapped to GID 0 */
2622  if ( glyph_index != 0 )
2623  {
2624  glyph_index = cff_charset_cid_to_gindex( &cff->charset,
2625  glyph_index );
2626  if ( glyph_index == 0 )
2627  return FT_THROW( Invalid_Argument );
2628  }
2629  }
2630  else if ( glyph_index >= cff->num_glyphs )
2631  return FT_THROW( Invalid_Argument );
2632 
2633  if ( load_flags & FT_LOAD_NO_RECURSE )
2634  load_flags |= FT_LOAD_NO_SCALE | FT_LOAD_NO_HINTING;
2635 
2636  glyph->x_scale = 0x10000L;
2637  glyph->y_scale = 0x10000L;
2638  if ( size )
2639  {
2640  glyph->x_scale = size->root.metrics.x_scale;
2641  glyph->y_scale = size->root.metrics.y_scale;
2642  }
2643 
2644 #ifdef TT_CONFIG_OPTION_EMBEDDED_BITMAPS
2645 
2646  /* try to load embedded bitmap if any */
2647  /* */
2648  /* XXX: The convention should be emphasized in */
2649  /* the documents because it can be confusing. */
2650  if ( size )
2651  {
2652  CFF_Face cff_face = (CFF_Face)size->root.face;
2653  SFNT_Service sfnt = (SFNT_Service)cff_face->sfnt;
2654  FT_Stream stream = cff_face->root.stream;
2655 
2656 
2657  if ( size->strike_index != 0xFFFFFFFFUL &&
2658  sfnt->load_eblc &&
2659  ( load_flags & FT_LOAD_NO_BITMAP ) == 0 )
2660  {
2662 
2663 
2664  error = sfnt->load_sbit_image( face,
2665  size->strike_index,
2666  glyph_index,
2667  (FT_Int)load_flags,
2668  stream,
2669  &glyph->root.bitmap,
2670  &metrics );
2671 
2672  if ( !error )
2673  {
2674  FT_Bool has_vertical_info;
2675  FT_UShort advance;
2676  FT_Short dummy;
2677 
2678 
2679  glyph->root.outline.n_points = 0;
2680  glyph->root.outline.n_contours = 0;
2681 
2682  glyph->root.metrics.width = (FT_Pos)metrics.width << 6;
2683  glyph->root.metrics.height = (FT_Pos)metrics.height << 6;
2684 
2685  glyph->root.metrics.horiBearingX = (FT_Pos)metrics.horiBearingX << 6;
2686  glyph->root.metrics.horiBearingY = (FT_Pos)metrics.horiBearingY << 6;
2687  glyph->root.metrics.horiAdvance = (FT_Pos)metrics.horiAdvance << 6;
2688 
2689  glyph->root.metrics.vertBearingX = (FT_Pos)metrics.vertBearingX << 6;
2690  glyph->root.metrics.vertBearingY = (FT_Pos)metrics.vertBearingY << 6;
2691  glyph->root.metrics.vertAdvance = (FT_Pos)metrics.vertAdvance << 6;
2692 
2693  glyph->root.format = FT_GLYPH_FORMAT_BITMAP;
2694 
2695  if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
2696  {
2697  glyph->root.bitmap_left = metrics.vertBearingX;
2698  glyph->root.bitmap_top = metrics.vertBearingY;
2699  }
2700  else
2701  {
2702  glyph->root.bitmap_left = metrics.horiBearingX;
2703  glyph->root.bitmap_top = metrics.horiBearingY;
2704  }
2705 
2706  /* compute linear advance widths */
2707 
2708  ( (SFNT_Service)face->sfnt )->get_metrics( face, 0,
2709  glyph_index,
2710  &dummy,
2711  &advance );
2712  glyph->root.linearHoriAdvance = advance;
2713 
2714 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
2715  has_vertical_info = FT_BOOL(
2716  face->vertical_info &&
2717  face->vertical.number_Of_VMetrics > 0 &&
2718  face->vertical.long_metrics );
2719 #else
2720  has_vertical_info = FT_BOOL(
2721  face->vertical_info &&
2722  face->vertical.number_Of_VMetrics > 0 );
2723 #endif
2724 
2725  /* get the vertical metrics from the vtmx table if we have one */
2726  if ( has_vertical_info )
2727  {
2728  ( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
2729  glyph_index,
2730  &dummy,
2731  &advance );
2732  glyph->root.linearVertAdvance = advance;
2733  }
2734  else
2735  {
2736  /* make up vertical ones */
2737  if ( face->os2.version != 0xFFFFU )
2738  glyph->root.linearVertAdvance = (FT_Pos)
2739  ( face->os2.sTypoAscender - face->os2.sTypoDescender );
2740  else
2741  glyph->root.linearVertAdvance = (FT_Pos)
2742  ( face->horizontal.Ascender - face->horizontal.Descender );
2743  }
2744 
2745  return error;
2746  }
2747  }
2748  }
2749 
2750 #endif /* TT_CONFIG_OPTION_EMBEDDED_BITMAPS */
2751 
2752  /* return immediately if we only want the embedded bitmaps */
2753  if ( load_flags & FT_LOAD_SBITS_ONLY )
2754  return FT_THROW( Invalid_Argument );
2755 
2756  /* if we have a CID subfont, use its matrix (which has already */
2757  /* been multiplied with the root matrix) */
2758 
2759  /* this scaling is only relevant if the PS hinter isn't active */
2760  if ( cff->num_subfonts )
2761  {
2762  FT_ULong top_upm, sub_upm;
2763  FT_Byte fd_index = cff_fd_select_get( &cff->fd_select,
2764  glyph_index );
2765 
2766 
2767  if ( fd_index >= cff->num_subfonts )
2768  fd_index = (FT_Byte)( cff->num_subfonts - 1 );
2769 
2770  top_upm = cff->top_font.font_dict.units_per_em;
2771  sub_upm = cff->subfonts[fd_index]->font_dict.units_per_em;
2772 
2773 
2774  font_matrix = cff->subfonts[fd_index]->font_dict.font_matrix;
2775  font_offset = cff->subfonts[fd_index]->font_dict.font_offset;
2776 
2777  if ( top_upm != sub_upm )
2778  {
2779  glyph->x_scale = FT_MulDiv( glyph->x_scale, top_upm, sub_upm );
2780  glyph->y_scale = FT_MulDiv( glyph->y_scale, top_upm, sub_upm );
2781 
2782  force_scaling = TRUE;
2783  }
2784  }
2785  else
2786  {
2787  font_matrix = cff->top_font.font_dict.font_matrix;
2788  font_offset = cff->top_font.font_dict.font_offset;
2789  }
2790 
2791  glyph->root.outline.n_points = 0;
2792  glyph->root.outline.n_contours = 0;
2793 
2794  /* top-level code ensures that FT_LOAD_NO_HINTING is set */
2795  /* if FT_LOAD_NO_SCALE is active */
2796  hinting = FT_BOOL( ( load_flags & FT_LOAD_NO_HINTING ) == 0 );
2797  scaled = FT_BOOL( ( load_flags & FT_LOAD_NO_SCALE ) == 0 );
2798 
2799  glyph->hint = hinting;
2800  glyph->scaled = scaled;
2801  glyph->root.format = FT_GLYPH_FORMAT_OUTLINE; /* by default */
2802 
2803  {
2805 
2806  FT_Byte* charstring;
2807  FT_ULong charstring_len;
2808 
2809 
2810  cff_decoder_init( &decoder, face, size, glyph, hinting,
2811  FT_LOAD_TARGET_MODE( load_flags ) );
2812 
2813  if ( load_flags & FT_LOAD_ADVANCE_ONLY )
2814  decoder.width_only = TRUE;
2815 
2816  decoder.builder.no_recurse =
2817  (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE );
2818 
2819  /* now load the unscaled outline */
2820  error = cff_get_glyph_data( face, glyph_index,
2821  &charstring, &charstring_len );
2822  if ( error )
2823  goto Glyph_Build_Finished;
2824 
2825  error = cff_decoder_prepare( &decoder, size, glyph_index );
2826  if ( error )
2827  goto Glyph_Build_Finished;
2828 
2829  /* choose which CFF renderer to use */
2830  if ( driver->hinting_engine == FT_CFF_HINTING_ADOBE )
2832  charstring,
2833  charstring_len );
2834 
2835  /* Adobe's engine uses 16.16 numbers everywhere; */
2836  /* as a consequence, glyphs larger than 2000ppem get rejected */
2837  if ( FT_ERR_EQ( error, Glyph_Too_Big ) ||
2838  driver->hinting_engine == FT_CFF_HINTING_FREETYPE )
2840  charstring,
2841  charstring_len );
2842 
2843  cff_free_glyph_data( face, &charstring, charstring_len );
2844 
2845  if ( error )
2846  goto Glyph_Build_Finished;
2847 
2848 #ifdef FT_CONFIG_OPTION_INCREMENTAL
2849  /* Control data and length may not be available for incremental */
2850  /* fonts. */
2851  if ( face->root.internal->incremental_interface )
2852  {
2853  glyph->root.control_data = 0;
2854  glyph->root.control_len = 0;
2855  }
2856  else
2857 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
2858 
2859  /* We set control_data and control_len if charstrings is loaded. */
2860  /* See how charstring loads at cff_index_access_element() in */
2861  /* cffload.c. */
2862  {
2863  CFF_Index csindex = &cff->charstrings_index;
2864 
2865 
2866  if ( csindex->offsets )
2867  {
2868  glyph->root.control_data = csindex->bytes +
2869  csindex->offsets[glyph_index] - 1;
2870  glyph->root.control_len = charstring_len;
2871  }
2872  }
2873 
2874  Glyph_Build_Finished:
2875  /* save new glyph tables, if no error */
2876  if ( !error )
2877  cff_builder_done( &decoder.builder );
2878  /* XXX: anything to do for broken glyph entry? */
2879  }
2880 
2881 #ifdef FT_CONFIG_OPTION_INCREMENTAL
2882 
2883  /* Incremental fonts can optionally override the metrics. */
2884  if ( !error &&
2885  face->root.internal->incremental_interface &&
2886  face->root.internal->incremental_interface->funcs->get_glyph_metrics )
2887  {
2889 
2890 
2891  metrics.bearing_x = decoder.builder.left_bearing.x;
2892  metrics.bearing_y = 0;
2893  metrics.advance = decoder.builder.advance.x;
2894  metrics.advance_v = decoder.builder.advance.y;
2895 
2896  error = face->root.internal->incremental_interface->funcs->get_glyph_metrics(
2897  face->root.internal->incremental_interface->object,
2898  glyph_index, FALSE, &metrics );
2899 
2900  decoder.builder.left_bearing.x = metrics.bearing_x;
2901  decoder.builder.advance.x = metrics.advance;
2902  decoder.builder.advance.y = metrics.advance_v;
2903  }
2904 
2905 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
2906 
2907  if ( !error )
2908  {
2909  /* Now, set the metrics -- this is rather simple, as */
2910  /* the left side bearing is the xMin, and the top side */
2911  /* bearing the yMax. */
2912 
2913  /* For composite glyphs, return only left side bearing and */
2914  /* advance width. */
2915  if ( load_flags & FT_LOAD_NO_RECURSE )
2916  {
2917  FT_Slot_Internal internal = glyph->root.internal;
2918 
2919 
2920  glyph->root.metrics.horiBearingX = decoder.builder.left_bearing.x;
2921  glyph->root.metrics.horiAdvance = decoder.glyph_width;
2922  internal->glyph_matrix = font_matrix;
2923  internal->glyph_delta = font_offset;
2924  internal->glyph_transformed = 1;
2925  }
2926  else
2927  {
2928  FT_BBox cbox;
2929  FT_Glyph_Metrics* metrics = &glyph->root.metrics;
2930  FT_Vector advance;
2931  FT_Bool has_vertical_info;
2932 
2933 
2934  /* copy the _unscaled_ advance width */
2935  metrics->horiAdvance = decoder.glyph_width;
2936  glyph->root.linearHoriAdvance = decoder.glyph_width;
2937  glyph->root.internal->glyph_transformed = 0;
2938 
2939 #ifdef FT_CONFIG_OPTION_OLD_INTERNALS
2940  has_vertical_info = FT_BOOL( face->vertical_info &&
2941  face->vertical.number_Of_VMetrics > 0 &&
2942  face->vertical.long_metrics );
2943 #else
2944  has_vertical_info = FT_BOOL( face->vertical_info &&
2945  face->vertical.number_Of_VMetrics > 0 );
2946 #endif
2947 
2948  /* get the vertical metrics from the vtmx table if we have one */
2949  if ( has_vertical_info )
2950  {
2951  FT_Short vertBearingY = 0;
2952  FT_UShort vertAdvance = 0;
2953 
2954 
2955  ( (SFNT_Service)face->sfnt )->get_metrics( face, 1,
2956  glyph_index,
2957  &vertBearingY,
2958  &vertAdvance );
2959  metrics->vertBearingY = vertBearingY;
2960  metrics->vertAdvance = vertAdvance;
2961  }
2962  else
2963  {
2964  /* make up vertical ones */
2965  if ( face->os2.version != 0xFFFFU )
2966  metrics->vertAdvance = (FT_Pos)( face->os2.sTypoAscender -
2967  face->os2.sTypoDescender );
2968  else
2969  metrics->vertAdvance = (FT_Pos)( face->horizontal.Ascender -
2970  face->horizontal.Descender );
2971  }
2972 
2973  glyph->root.linearVertAdvance = metrics->vertAdvance;
2974 
2976 
2977  glyph->root.outline.flags = 0;
2978  if ( size && size->root.metrics.y_ppem < 24 )
2980 
2982 
2983  if ( !( font_matrix.xx == 0x10000L &&
2984  font_matrix.yy == 0x10000L &&
2985  font_matrix.xy == 0 &&
2986  font_matrix.yx == 0 ) )
2987  FT_Outline_Transform( &glyph->root.outline, &font_matrix );
2988 
2989  if ( !( font_offset.x == 0 &&
2990  font_offset.y == 0 ) )
2992  font_offset.x, font_offset.y );
2993 
2994  advance.x = metrics->horiAdvance;
2995  advance.y = 0;
2996  FT_Vector_Transform( &advance, &font_matrix );
2997  metrics->horiAdvance = advance.x + font_offset.x;
2998 
2999  advance.x = 0;
3000  advance.y = metrics->vertAdvance;
3001  FT_Vector_Transform( &advance, &font_matrix );
3002  metrics->vertAdvance = advance.y + font_offset.y;
3003 
3004  if ( ( load_flags & FT_LOAD_NO_SCALE ) == 0 || force_scaling )
3005  {
3006  /* scale the outline and the metrics */
3007  FT_Int n;
3008  FT_Outline* cur = &glyph->root.outline;
3009  FT_Vector* vec = cur->points;
3010  FT_Fixed x_scale = glyph->x_scale;
3011  FT_Fixed y_scale = glyph->y_scale;
3012 
3013 
3014  /* First of all, scale the points */
3015  if ( !hinting || !decoder.builder.hints_funcs )
3016  for ( n = cur->n_points; n > 0; n--, vec++ )
3017  {
3018  vec->x = FT_MulFix( vec->x, x_scale );
3019  vec->y = FT_MulFix( vec->y, y_scale );
3020  }
3021 
3022  /* Then scale the metrics */
3023  metrics->horiAdvance = FT_MulFix( metrics->horiAdvance, x_scale );
3024  metrics->vertAdvance = FT_MulFix( metrics->vertAdvance, y_scale );
3025  }
3026 
3027  /* compute the other metrics */
3028  FT_Outline_Get_CBox( &glyph->root.outline, &cbox );
3029 
3030  metrics->width = cbox.xMax - cbox.xMin;
3031  metrics->height = cbox.yMax - cbox.yMin;
3032 
3033  metrics->horiBearingX = cbox.xMin;
3034  metrics->horiBearingY = cbox.yMax;
3035 
3036  if ( has_vertical_info )
3037  metrics->vertBearingX = metrics->horiBearingX -
3038  metrics->horiAdvance / 2;
3039  else
3040  {
3041  if ( load_flags & FT_LOAD_VERTICAL_LAYOUT )
3043  metrics->vertAdvance );
3044  }
3045  }
3046  }
3047 
3048  return error;
3049  }
3050 
3051 
3052 /* END */
GLenum GLuint GLenum GLsizei length
cff_builder_close_contour(CFF_Builder *builder)
Definition: cffgload.c:581
typedefFT_BEGIN_HEADER struct PSH_GlobalsRec_ * PSH_Globals
Definition: pshints.h:41
FT_Face face
Definition: freetype.h:1404
int FT_Error
Definition: fttypes.h:296
cff_get_standard_encoding(FT_UInt charcode)
Definition: cffload.c:183
FT_Outline * base
Definition: cffgload.h:87
FT_Bool metrics_only
Definition: cffgload.h:101
#define FT_LOAD_VERTICAL_LAYOUT
Definition: freetype.h:2553
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:586
GLuint GLuint stream
FT_GlyphLoader loader
Definition: cffgload.h:86
FT_Byte ** globals
Definition: cffgload.h:185
void * sfnt
Definition: tttypes.h:1298
ft_ptrdiff_t FT_PtrDist
Definition: fttypes.h:333
SFNT_Interface * SFNT_Service
Definition: sfnt.h:754
TT_OS2 os2
Definition: tttypes.h:1282
unsigned long FT_ULong
Definition: fttypes.h:249
#define FT_LOAD_SBITS_ONLY
Definition: freetype.h:2568
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:59
FT_Pos nominal_width
Definition: cffgload.h:171
#define CFF_MAX_TRANS_ELEMENTS
Definition: cffgload.h:33
ft_synthesize_vertical_metrics(FT_Glyph_Metrics *metrics, FT_Pos advance)
Definition: ftobjs.c:2542
FT_UShort version
Definition: tttables.h:352
#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES
Definition: freetype.h:3262
cff_get_glyph_data(TT_Face face, FT_UInt glyph_index, FT_Byte **pointer, FT_ULong *length)
Definition: cffgload.c:655
FT_UInt num_locals
Definition: cffgload.h:178
FT_Char horiBearingY
Definition: tttypes.h:441
#define FT_MEM_ZERO(dest, count)
Definition: ftmemory.h:208
#define FT_SUBGLYPH_FLAG_USE_MY_METRICS
Definition: freetype.h:3267
CFF_Builder builder
Definition: cffgload.h:157
#define CFF_MAX_SUBRS_CALLS
Definition: cffgload.h:32
#define FT_CURVE_TAG_CUBIC
Definition: ftimage.h:518
GLint GLint GLint GLint GLint GLint y
FT_Short sTypoDescender
Definition: tttables.h:382
FT_Fixed xy
Definition: fttypes.h:383
FT_ULong strike_index
Definition: cffobjs.h:58
signed int FT_Int
Definition: fttypes.h:216
short n_contours
Definition: ftimage.h:385
GLsizei const GLvoid * pointer
const FT_Byte * pointer
Definition: fttypes.h:404
T2_Hints hints
Definition: pshints.h:658
#define FT_ULONG_MAX
Definition: ftstdlib.h:67
enum FT_Render_Mode_ FT_Render_Mode
FT_Byte horiAdvance
Definition: tttypes.h:442
cff_builder_add_point1(CFF_Builder *builder, FT_Pos x, FT_Pos y)
Definition: cffgload.c:514
FT_Int length
Definition: fttypes.h:405
#define FT_LOAD_NO_HINTING
Definition: freetype.h:2550
return FT_THROW(Missing_Property)
short * contours
Definition: ftimage.h:390
FT_Int num_hints
Definition: cffgload.h:175
TT_Face CFF_Face
Definition: cffobjs.h:44
FT_Fixed stack[CFF_MAX_OPERANDS+1]
Definition: cffgload.h:160
#define FT_UNUSED(arg)
Definition: ftconfig.h:76
char * tags
Definition: ftimage.h:389
FT_Int charstring_type
Definition: cfftypes.h:118
struct CFF_FontRec_ * CFF_Font
JSAMPARRAY JDIMENSION num_lines
Definition: jpeglib.h:939
cff_lookup_glyph_by_stdcharcode(CFF_Font cff, FT_Int charcode)
Definition: cffgload.c:626
#define FT_LOAD_NO_RECURSE
Definition: freetype.h:2558
CFF_SubFont subfonts[CFF_MAX_CID_FONTS]
Definition: cfftypes.h:256
CFF_IndexRec global_subrs_index
Definition: cfftypes.h:234
unsigned int FT_UInt32
Definition: ftconfig.h:133
T2_Hints_StemsFunc stems
Definition: pshints.h:661
FT_Fixed linearHoriAdvance
Definition: freetype.h:1621
GLint GLint GLint GLint GLint x
FT_Int bitmap_top
Definition: freetype.h:1629
return FT_Err_Ok
Definition: ftbbox.c:645
#define FT_LOAD_ADVANCE_ONLY
Definition: freetype.h:2567
FT_Render_Mode hint_mode
Definition: cffgload.h:190
cff_decoder_parse_charstrings(CFF_Decoder *decoder, FT_Byte *charstring_base, FT_ULong charstring_len)
Definition: cffgload.c:898
FT_GlyphSlotRec root
Definition: cffobjs.h:73
FT_Byte * limit
Definition: cffgload.h:149
png_uint_32 i
Definition: png.h:2640
#define FT_FACE_DRIVER(x)
Definition: ftobjs.h:561
FT_BEGIN_HEADER typedef unsigned char FT_Bool
Definition: fttypes.h:104
#define FT_LOAD_NO_SCALE
Definition: freetype.h:2549
FT_Face_Internal internal
Definition: freetype.h:971
FT_Int globals_bias
Definition: cffgload.h:182
FT_Vector font_offset
Definition: cfftypes.h:122
CFF_Decoder_Zone * zone
Definition: cffgload.h:164
GLenum GLuint GLint GLenum face
FT_Pos glyph_width
Definition: cffgload.h:170
FT_Byte * base
Definition: cffgload.h:148
FT_Outline outline
Definition: freetype.h:1631
typedefFT_BEGIN_HEADER struct FT_GlyphLoaderRec_ * FT_GlyphLoader
Definition: ftgloadr.h:43
#define FT_ERROR(varformat)
Definition: ftdebug.h:181
#define FT_CFF_HINTING_FREETYPE
Definition: ftcffdrv.h:108
cff_fd_select_get(CFF_FDSelect fdselect, FT_UInt glyph_index)
Definition: cffload.c:709
unsigned char FT_Byte
Definition: fttypes.h:150
CFF_Operator_
Definition: cffgload.c:44
cff_index_access_element(CFF_Index idx, FT_UInt element, FT_Byte **pbytes, FT_ULong *pbyte_len)
Definition: cffload.c:470
struct CFF_InternalRec_ * CFF_Internal
FT_Size_Internal internal
Definition: freetype.h:1407
#define FT_TRACE4(varformat)
Definition: ftdebug.h:161
FT_Bool no_recurse
Definition: cffgload.h:99
FT_Bool glyph_transformed
Definition: ftobjs.h:415
FT_Short Descender
Definition: tttables.h:184
FT_Outline_Get_CBox(const FT_Outline *outline, FT_BBox *acbox)
Definition: ftoutln.c:468
FT_GlyphLoader_Add(FT_GlyphLoader loader)
Definition: ftgloadr.c:324
FT_Byte ** locals
Definition: cffgload.h:184
FT_Vector left_bearing
Definition: cffgload.h:93
FT_UInt num_subfonts
Definition: cfftypes.h:255
FT_Byte ** global_subrs
Definition: cfftypes.h:247
FT_Bitmap bitmap
Definition: freetype.h:1627
FT_Outline * current
Definition: cffgload.h:88
CFF_FontRecDictRec font_dict
Definition: cfftypes.h:207
FT_Char horiBearingX
Definition: tttypes.h:440
cff_decoder_prepare(CFF_Decoder *decoder, CFF_Size size, FT_UInt glyph_index)
Definition: cffgload.c:410
CFF_Font cff
Definition: cffdrivr.c:454
FT_Outline_Transform(const FT_Outline *outline, const FT_Matrix *matrix)
Definition: ftoutln.c:703
FT_Short Ascender
Definition: tttables.h:183
FT_Pos yMax
Definition: ftimage.h:119
FT_Pos xMin
Definition: ftimage.h:118
cff_decoder_init(CFF_Decoder *decoder, TT_Face face, CFF_Size size, CFF_GlyphSlot slot, FT_Bool hinting, FT_Render_Mode hint_mode)
Definition: cffgload.c:379
struct TT_FaceRec_ * TT_Face
Definition: tttypes.h:951
#define CFF_COUNT_CHECK_WIDTH
Definition: cffgload.c:127
T2_Hints_CounterFunc counter
Definition: pshints.h:663
CFF_FDSelectRec fd_select
Definition: cfftypes.h:258
FT_GlyphLoader_CheckSubGlyphs(FT_GlyphLoader loader, FT_UInt n_subs)
Definition: ftgloadr.c:277
FT_Fixed y_scale
Definition: cffobjs.h:79
FT_UInt idx
Definition: cffcmap.c:127
FT_SizeRec root
Definition: cffobjs.h:57
FT_MulDiv(FT_Long a, FT_Long b, FT_Long c)
Definition: ftcalc.c:412
FT_Error error
Definition: cffdrivr.c:411
FT_Char vertBearingX
Definition: tttypes.h:444
FT_UInt num_subglyphs
Definition: freetype.h:1633
const GLdouble * v
FT_Pos x
Definition: ftimage.h:77
GLsizei GLsizei GLenum GLenum const GLvoid * data
T2_Hints_ApplyFunc apply
Definition: pshints.h:664
FT_UShort number_Of_VMetrics
Definition: tttables.h:325
#define FT_OUTLINE_HIGH_PRECISION
Definition: ftimage.h:482
CFF_Decoder_Zone zones[CFF_MAX_SUBRS_CALLS+1]
Definition: cffgload.h:163
FT_Pos y
Definition: ftimage.h:78
FT_Bool vertical_info
Definition: tttypes.h:1276
CFF_SubFontRec top_font
Definition: cfftypes.h:254
GLuint GLfloat * val
FT_Char vertBearingY
Definition: tttypes.h:445
GLdouble n
#define FT_ERR_EQ(x, e)
Definition: fttypes.h:587
FT_UInt num_globals
Definition: cffgload.h:179
local int root
Definition: enough.c:171
signed int FT_Int32
Definition: ftconfig.h:132
#define CFF_MAX_OPERANDS
Definition: cffgload.h:31
FT_GlyphLoader loader
Definition: ftobjs.h:413
FT_Memory memory
Definition: cffgload.h:83
TT_VertHeader vertical
Definition: tttypes.h:1277
const GLint * first
FT_UShort * cids
Definition: cfftypes.h:97
FT_Vector * vec
Definition: ftbbox.c:566
FT_SubGlyph subglyphs
Definition: freetype.h:1634
void * glyph_hints
Definition: ftobjs.h:418
FT_Bool width_only
Definition: cffgload.h:174
#define CFF_COUNT_CLEAR_STACK
Definition: cffgload.c:129
#define FALSE
Definition: ftobjs.h:57
FT_Pos xMax
Definition: ftimage.h:119
cff_slot_load(CFF_GlyphSlot glyph, CFF_Size size, FT_UInt glyph_index, FT_Int32 load_flags)
Definition: cffgload.c:2598
FT_Bool path_begun
Definition: cffgload.h:97
short n_points
Definition: ftimage.h:386
void * hints_globals
Definition: cffgload.h:104
T2_Hints_OpenFunc open
Definition: pshints.h:659
CFF_GlyphSlot glyph
Definition: cffgload.h:85
signed short FT_Short
Definition: fttypes.h:194
FT_Fixed xx
Definition: fttypes.h:383
#define FT_BOOL(x)
Definition: fttypes.h:574
cff_check_points(CFF_Builder *builder, FT_Int count)
Definition: cffgload.c:469
FT_Pos pos_x
Definition: cffgload.h:90
FT_FaceRec root
Definition: tttypes.h:1260
TT_HoriHeader horizontal
Definition: tttypes.h:1269
CFF_Driver driver
Definition: cffdrivr.c:585
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:485
void * data
Definition: fttypes.h:457
if(!abbox) return FT_THROW(Invalid_Argument)
FT_Fixed buildchar[CFF_MAX_TRANS_ELEMENTS]
Definition: cffgload.h:176
#define FT_TRACE3(varformat)
Definition: ftdebug.h:160
FT_Generic extra
Definition: tttypes.h:1382
FT_Bool scaled
Definition: cffobjs.h:76
int flags
Definition: ftimage.h:392
FT_Fixed yx
Definition: fttypes.h:384
cff_builder_add_point(CFF_Builder *builder, FT_Pos x, FT_Pos y, FT_Byte flag)
Definition: cffgload.c:478
FT_Fixed y_scale
Definition: freetype.h:1373
FT_Bool hint
Definition: cffobjs.h:75
GLdouble GLdouble GLdouble GLdouble top
FT_Vector_Transform(FT_Vector *vec, const FT_Matrix *matrix)
Definition: ftoutln.c:680
signed long FT_Fixed
Definition: fttypes.h:284
FT_Int bitmap_left
Definition: freetype.h:1628
FT_BEGIN_HEADER struct FT_Glyph_Metrics_ FT_Glyph_Metrics
FT_Glyph_Format format
Definition: freetype.h:1625
FT_Bool seac
Definition: cffgload.h:192
FT_Long num_glyphs
Definition: freetype.h:927
FT_Byte * cursor
Definition: cffgload.h:150
GLuint64EXT * result
FT_Short sTypoAscender
Definition: tttables.h:381
typedefFT_BEGIN_HEADER struct CFF_DriverRec_ * CFF_Driver
Definition: cffobjs.h:42
unsigned int FT_UInt
Definition: fttypes.h:227
struct FT_GlyphSlotRec_ * FT_GlyphSlot
Definition: freetype.h:454
FT_ULong units_per_em
Definition: cfftypes.h:121
FT_Matrix font_matrix
Definition: cfftypes.h:119
FT_GlyphLoader_Rewind(FT_GlyphLoader loader)
Definition: ftgloadr.c:88
FT_Slot_Internal internal
Definition: freetype.h:1644
void * control_data
Definition: freetype.h:1636
cff_charset_cid_to_gindex(CFF_Charset charset, FT_UInt cid)
Definition: cffload.c:817
FT_Int locals_bias
Definition: cffgload.h:181
FT_Fixed x_scale
Definition: freetype.h:1372
FT_Fixed linearVertAdvance
Definition: freetype.h:1622
FT_Glyph_Metrics metrics
Definition: freetype.h:1620
TT_Face face
Definition: cffgload.h:84
CFF_Font cff
Definition: cffgload.h:158
FT_Outline_Translate(const FT_Outline *outline, FT_Pos xOffset, FT_Pos yOffset)
Definition: ftoutln.c:518
FT_GlyphLoader_Prepare(FT_GlyphLoader loader)
Definition: ftgloadr.c:308
GLuint GLuint GLsizei count
#define FT_CURVE_TAG_ON
Definition: ftimage.h:516
FT_Fixed * top
Definition: cffgload.h:161
CFF_IndexRec charstrings_index
Definition: cfftypes.h:239
FT_Fixed yy
Definition: fttypes.h:384
#define FT_CFF_HINTING_ADOBE
Definition: ftcffdrv.h:109
FT_Bool read_width
Definition: cffgload.h:173
FT_Vector advance
Definition: cffgload.h:94
GLsizei GLenum const GLvoid GLuint GLsizei GLfloat * metrics
FT_UInt num_glyphs
Definition: cfftypes.h:224
#define FT_LOAD_NO_BITMAP
Definition: freetype.h:2552
png_infop png_uint_32 flag
Definition: png.h:2005
FT_UShort * sids
Definition: cfftypes.h:96
unsigned short FT_UShort
Definition: fttypes.h:205
#define FT_GLYPHLOADER_CHECK_POINTS(_loader, _points, _contours)
Definition: ftgloadr.h:134
FT_Pos yMin
Definition: ftimage.h:118
enum CFF_Operator_ CFF_Operator
FT_Stream stream
Definition: freetype.h:964
FT_Bool load_points
Definition: cffgload.h:98
GLsizeiptr size
cff_free_glyph_data(TT_Face face, FT_Byte **pointer, FT_ULong length)
Definition: cffgload.c:691
#define CFF_COUNT_EXACT
Definition: cffgload.c:128
cf2_decoder_parse_charstrings(CFF_Decoder *decoder, FT_Byte *charstring_base, FT_ULong charstring_len)
Definition: cf2ft.c:267
const struct T2_Hints_FuncsRec_ * T2_Hints_Funcs
Definition: pshints.h:404
#define TRUE
Definition: ftobjs.h:53
FT_Fixed x_scale
Definition: cffobjs.h:78
T2_Hints_CloseFunc close
Definition: pshints.h:660
FT_Vector * points
Definition: ftimage.h:388
FT_UInt cid_registry
Definition: cfftypes.h:135
CFF_CharsetRec charset
Definition: cfftypes.h:237
FT_Module_Constructor FT_GLYPH_FORMAT_OUTLINE
Definition: ftrend1.c:284
FT_Pos pos_y
Definition: cffgload.h:91
GLint limit
FT_Size_Metrics metrics
Definition: freetype.h:1406
FT_Byte vertAdvance
Definition: tttypes.h:446
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:236
cff_index_forget_element(CFF_Index idx, FT_Byte **pbytes)
Definition: cffload.c:568
FT_Memory memory
Definition: freetype.h:963
T2_Hints_MaskFunc hintmask
Definition: pshints.h:662
void * long_metrics
Definition: tttables.h:331
cff_builder_start_point(CFF_Builder *builder, FT_Pos x, FT_Pos y)
Definition: cffgload.c:559
void * hints_funcs
Definition: cffgload.h:103
#define FT_OUTLINE_REVERSE_FILL
Definition: ftimage.h:477
FT_UShort y_ppem
Definition: freetype.h:1370
FT_BEGIN_HEADER struct CFF_IndexRec_ * CFF_Index
#define FT_LOAD_TARGET_MODE(x)
Definition: freetype.h:2655