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)  

psintrp.c
Go to the documentation of this file.
1 /****************************************************************************
2  *
3  * psintrp.c
4  *
5  * Adobe's CFF Interpreter (body).
6  *
7  * Copyright 2007-2014 Adobe Systems Incorporated.
8  *
9  * This software, and all works of authorship, whether in source or
10  * object code form as indicated by the copyright notice(s) included
11  * herein (collectively, the "Work") is made available, and may only be
12  * used, modified, and distributed under the FreeType Project License,
13  * LICENSE.TXT. Additionally, subject to the terms and conditions of the
14  * FreeType Project License, each contributor to the Work hereby grants
15  * to any individual or legal entity exercising permissions granted by
16  * the FreeType Project License and this section (hereafter, "You" or
17  * "Your") a perpetual, worldwide, non-exclusive, no-charge,
18  * royalty-free, irrevocable (except as stated in this section) patent
19  * license to make, have made, use, offer to sell, sell, import, and
20  * otherwise transfer the Work, where such license applies only to those
21  * patent claims licensable by such contributor that are necessarily
22  * infringed by their contribution(s) alone or by combination of their
23  * contribution(s) with the Work to which such contribution(s) was
24  * submitted. If You institute patent litigation against any entity
25  * (including a cross-claim or counterclaim in a lawsuit) alleging that
26  * the Work or a contribution incorporated within the Work constitutes
27  * direct or contributory patent infringement, then any patent licenses
28  * granted to You under this License for that Work shall terminate as of
29  * the date such litigation is filed.
30  *
31  * By using, modifying, or distributing the Work you indicate that you
32  * have read and understood the terms and conditions of the
33  * FreeType Project License as well as those provided in this section,
34  * and you accept them fully.
35  *
36  */
37 
38 
39 #include "psft.h"
40 #include <freetype/internal/ftdebug.h>
41 #include <freetype/internal/services/svcfftl.h>
42 
43 #include "psglue.h"
44 #include "psfont.h"
45 #include "psstack.h"
46 #include "pshints.h"
47 #include "psintrp.h"
48 
49 #include "pserror.h"
50 
51 #include "psobjs.h" /* for cff_random */
52 #include "t1decode.h" /* for t1 seac */
53 
54 
55  /**************************************************************************
56  *
57  * The macro FT_COMPONENT is used in trace mode. It is an implicit
58  * parameter of the FT_TRACE() and FT_ERROR() macros, used to print/log
59  * messages during execution.
60  */
61 #undef FT_COMPONENT
62 #define FT_COMPONENT cf2interp
63 
64 
65  FT_LOCAL_DEF( void )
67  FT_Error* error )
68  {
69  FT_ZERO( hintmask );
70 
71  hintmask->error = error;
72  }
73 
74 
77  {
78  return hintmask->isValid;
79  }
80 
81 
84  {
85  return hintmask->isNew;
86  }
87 
88 
89  FT_LOCAL_DEF( void )
91  FT_Bool val )
92  {
93  hintmask->isNew = val;
94  }
95 
96 
97  /* clients call `getMaskPtr' in order to iterate */
98  /* through hint mask */
99 
102  {
103  return hintmask->mask;
104  }
105 
106 
107  static size_t
109  size_t bitCount )
110  {
111  if ( bitCount > CF2_MAX_HINTS )
112  {
113  /* total of h and v stems must be <= 96 */
114  CF2_SET_ERROR( hintmask->error, Invalid_Glyph_Format );
115  return 0;
116  }
117 
118  hintmask->bitCount = bitCount;
119  hintmask->byteCount = ( hintmask->bitCount + 7 ) / 8;
120 
121  hintmask->isValid = TRUE;
122  hintmask->isNew = TRUE;
123 
124  return bitCount;
125  }
126 
127 
128  /* consume the hintmask bytes from the charstring, advancing the src */
129  /* pointer */
130  static void
132  CF2_Buffer charstring,
133  size_t bitCount )
134  {
135  size_t i;
136 
137 #ifndef CF2_NDEBUG
138  /* these are the bits in the final mask byte that should be zero */
139  /* Note: this variable is only used in an assert expression below */
140  /* and then only if CF2_NDEBUG is not defined */
141  CF2_UInt mask = ( 1 << ( -(CF2_Int)bitCount & 7 ) ) - 1;
142 #endif
143 
144 
145  /* initialize counts and isValid */
146  if ( cf2_hintmask_setCounts( hintmask, bitCount ) == 0 )
147  return;
148 
149  FT_ASSERT( hintmask->byteCount > 0 );
150 
151  FT_TRACE4(( " (maskbytes:" ));
152 
153  /* set mask and advance interpreter's charstring pointer */
154  for ( i = 0; i < hintmask->byteCount; i++ )
155  {
156  hintmask->mask[i] = (FT_Byte)cf2_buf_readByte( charstring );
157  FT_TRACE4(( " 0x%02X", hintmask->mask[i] ));
158  }
159 
160  FT_TRACE4(( ")\n" ));
161 
162  /* assert any unused bits in last byte are zero unless there's a prior */
163  /* error */
164  /* bitCount -> mask, 0 -> 0, 1 -> 7f, 2 -> 3f, ... 6 -> 3, 7 -> 1 */
165 #ifndef CF2_NDEBUG
166  FT_ASSERT( ( hintmask->mask[hintmask->byteCount - 1] & mask ) == 0 ||
167  *hintmask->error );
168 #endif
169  }
170 
171 
172  FT_LOCAL_DEF( void )
174  size_t bitCount )
175  {
176  size_t i;
177  CF2_UInt mask = ( 1 << ( -(CF2_Int)bitCount & 7 ) ) - 1;
178 
179 
180  /* initialize counts and isValid */
181  if ( cf2_hintmask_setCounts( hintmask, bitCount ) == 0 )
182  return;
183 
184  FT_ASSERT( hintmask->byteCount > 0 );
185  FT_ASSERT( hintmask->byteCount <=
186  sizeof ( hintmask->mask ) / sizeof ( hintmask->mask[0] ) );
187 
188  /* set mask to all ones */
189  for ( i = 0; i < hintmask->byteCount; i++ )
190  hintmask->mask[i] = 0xFF;
191 
192  /* clear unused bits */
193  /* bitCount -> mask, 0 -> 0, 1 -> 7f, 2 -> 3f, ... 6 -> 3, 7 -> 1 */
194  hintmask->mask[hintmask->byteCount - 1] &= ~mask;
195  }
196 
197 
198  /* Type2 charstring opcodes */
199  enum
200  {
202  cf2_cmdHSTEM, /* 1 */
204  cf2_cmdVSTEM, /* 3 */
205  cf2_cmdVMOVETO, /* 4 */
206  cf2_cmdRLINETO, /* 5 */
207  cf2_cmdHLINETO, /* 6 */
208  cf2_cmdVLINETO, /* 7 */
210  cf2_cmdCLOSEPATH, /* 9 T1 only */
211  cf2_cmdCALLSUBR, /* 10 */
212  cf2_cmdRETURN, /* 11 */
213  cf2_cmdESC, /* 12 */
214  cf2_cmdHSBW, /* 13 T1 only */
215  cf2_cmdENDCHAR, /* 14 */
216  cf2_cmdVSINDEX, /* 15 */
217  cf2_cmdBLEND, /* 16 */
219  cf2_cmdHSTEMHM, /* 18 */
220  cf2_cmdHINTMASK, /* 19 */
221  cf2_cmdCNTRMASK, /* 20 */
222  cf2_cmdRMOVETO, /* 21 */
223  cf2_cmdHMOVETO, /* 22 */
224  cf2_cmdVSTEMHM, /* 23 */
232  cf2_cmdHVCURVETO /* 31 */
233  };
234 
235  enum
236  {
238  cf2_escVSTEM3, /* 1 T1 only */
239  cf2_escHSTEM3, /* 2 T1 only */
240  cf2_escAND, /* 3 */
241  cf2_escOR, /* 4 */
242  cf2_escNOT, /* 5 */
243  cf2_escSEAC, /* 6 T1 only */
244  cf2_escSBW, /* 7 T1 only */
246  cf2_escABS, /* 9 */
247  cf2_escADD, /* 10 like otherADD */
248  cf2_escSUB, /* 11 like otherSUB */
249  cf2_escDIV, /* 12 */
251  cf2_escNEG, /* 14 */
252  cf2_escEQ, /* 15 */
253  cf2_escCALLOTHERSUBR,/* 16 T1 only */
254  cf2_escPOP, /* 17 T1 only */
255  cf2_escDROP, /* 18 */
257  cf2_escPUT, /* 20 like otherPUT */
258  cf2_escGET, /* 21 like otherGET */
259  cf2_escIFELSE, /* 22 like otherIFELSE */
260  cf2_escRANDOM, /* 23 like otherRANDOM */
261  cf2_escMUL, /* 24 like otherMUL */
263  cf2_escSQRT, /* 26 */
264  cf2_escDUP, /* 27 like otherDUP */
265  cf2_escEXCH, /* 28 like otherEXCH */
266  cf2_escINDEX, /* 29 */
267  cf2_escROLL, /* 30 */
270  cf2_escSETCURRENTPT, /* 33 T1 only */
271  cf2_escHFLEX, /* 34 */
272  cf2_escFLEX, /* 35 */
273  cf2_escHFLEX1, /* 36 */
274  cf2_escFLEX1, /* 37 */
275  cf2_escRESERVED_38 /* 38 & all higher */
276  };
277 
278 
279  /* `stemHintArray' does not change once we start drawing the outline. */
280  static void
282  CF2_Stack opStack,
283  CF2_ArrStack stemHintArray,
284  CF2_Fixed* width,
285  FT_Bool* haveWidth,
286  CF2_Fixed hintOffset )
287  {
288  CF2_UInt i;
289  CF2_UInt count = cf2_stack_count( opStack );
290  FT_Bool hasWidthArg = FT_BOOL( count & 1 );
291 
292  /* variable accumulates delta values from operand stack */
293  CF2_Fixed position = hintOffset;
294 
295  if ( font->isT1 && !font->decoder->flex_state && !*haveWidth )
296  FT_ERROR(( "cf2_doStems (Type 1 mode):"
297  " No width. Use hsbw/sbw as first op\n" ));
298 
299  if ( !font->isT1 && hasWidthArg && !*haveWidth )
300  *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ),
301  cf2_getNominalWidthX( font->decoder ) );
302 
303  if ( font->decoder->width_only )
304  goto exit;
305 
306  for ( i = hasWidthArg ? 1 : 0; i < count; i += 2 )
307  {
308  /* construct a CF2_StemHint and push it onto the list */
309  CF2_StemHintRec stemhint;
310 
311 
312  stemhint.min =
314  cf2_stack_getReal( opStack, i ) );
315  stemhint.max =
317  cf2_stack_getReal( opStack, i + 1 ) );
318 
319  stemhint.used = FALSE;
320  stemhint.maxDS =
321  stemhint.minDS = 0;
322 
323  cf2_arrstack_push( stemHintArray, &stemhint ); /* defer error check */
324  }
325 
326  cf2_stack_clear( opStack );
327 
328  exit:
329  /* cf2_doStems must define a width (may be default) */
330  *haveWidth = TRUE;
331  }
332 
333 
334  static void
336  CF2_Fixed* curX,
337  CF2_Fixed* curY,
338  CF2_GlyphPath glyphPath,
339  const FT_Bool* readFromStack,
340  FT_Bool doConditionalLastRead )
341  {
342  CF2_Fixed vals[14];
343  CF2_UInt idx;
344  FT_Bool isHFlex;
345  CF2_Int top, i, j;
346 
347 
348  vals[0] = *curX;
349  vals[1] = *curY;
350  idx = 0;
351  isHFlex = FT_BOOL( readFromStack[9] == FALSE );
352  top = isHFlex ? 9 : 10;
353 
354  for ( i = 0; i < top; i++ )
355  {
356  vals[i + 2] = vals[i];
357  if ( readFromStack[i] )
358  vals[i + 2] = ADD_INT32( vals[i + 2], cf2_stack_getReal( opStack,
359  idx++ ) );
360  }
361 
362  if ( isHFlex )
363  vals[9 + 2] = *curY;
364 
365  if ( doConditionalLastRead )
366  {
367  FT_Bool lastIsX = FT_BOOL(
368  cf2_fixedAbs( SUB_INT32( vals[10], *curX ) ) >
369  cf2_fixedAbs( SUB_INT32( vals[11], *curY ) ) );
370  CF2_Fixed lastVal = cf2_stack_getReal( opStack, idx );
371 
372 
373  if ( lastIsX )
374  {
375  vals[12] = ADD_INT32( vals[10], lastVal );
376  vals[13] = *curY;
377  }
378  else
379  {
380  vals[12] = *curX;
381  vals[13] = ADD_INT32( vals[11], lastVal );
382  }
383  }
384  else
385  {
386  if ( readFromStack[10] )
387  vals[12] = ADD_INT32( vals[10],
388  cf2_stack_getReal( opStack, idx++ ) );
389  else
390  vals[12] = *curX;
391 
392  if ( readFromStack[11] )
393  vals[13] = ADD_INT32( vals[11],
394  cf2_stack_getReal( opStack, idx ) );
395  else
396  vals[13] = *curY;
397  }
398 
399  for ( j = 0; j < 2; j++ )
400  cf2_glyphpath_curveTo( glyphPath, vals[j * 6 + 2],
401  vals[j * 6 + 3],
402  vals[j * 6 + 4],
403  vals[j * 6 + 5],
404  vals[j * 6 + 6],
405  vals[j * 6 + 7] );
406 
407  cf2_stack_clear( opStack );
408 
409  *curX = vals[12];
410  *curY = vals[13];
411  }
412 
413 
414  /* Blend numOperands on the stack, */
415  /* store results into the first numBlends values, */
416  /* then pop remaining arguments. */
417  static void
419  CF2_Stack opStack,
420  CF2_UInt numBlends )
421  {
422  CF2_UInt delta;
423  CF2_UInt base;
424  CF2_UInt i, j;
425  CF2_UInt numOperands = (CF2_UInt)( numBlends * blend->lenBV );
426 
427 
428  base = cf2_stack_count( opStack ) - numOperands;
429  delta = base + numBlends;
430 
431  for ( i = 0; i < numBlends; i++ )
432  {
433  const CF2_Fixed* weight = &blend->BV[1];
434 
435  /* start with first term */
436  CF2_Fixed sum = cf2_stack_getReal( opStack, i + base );
437 
438 
439  for ( j = 1; j < blend->lenBV; j++ )
440  sum = ADD_INT32( sum,
441  FT_MulFix( *weight++,
442  cf2_stack_getReal( opStack,
443  delta++ ) ) );
444 
445  /* store blended result */
446  cf2_stack_setReal( opStack, i + base, sum );
447  }
448 
449  /* leave only `numBlends' results on stack */
450  cf2_stack_pop( opStack, numOperands - numBlends );
451  }
452 
453 
454  /*
455  * `error' is a shared error code used by many objects in this
456  * routine. Before the code continues from an error, it must check and
457  * record the error in `*error'. The idea is that this shared
458  * error code will record the first error encountered. If testing
459  * for an error anyway, the cost of `goto exit' is small, so we do it,
460  * even if continuing would be safe. In this case, `lastError' is
461  * set, so the testing and storing can be done in one place, at `exit'.
462  *
463  * Continuing after an error is intended for objects which do their own
464  * testing of `*error', e.g., array stack functions. This allows us to
465  * avoid an extra test after the call.
466  *
467  * Unimplemented opcodes are ignored.
468  *
469  */
470  FT_LOCAL_DEF( void )
472  CF2_Buffer buf,
473  CF2_OutlineCallbacks callbacks,
474  const FT_Vector* translation,
475  FT_Bool doingSeac,
476  CF2_Fixed curX,
477  CF2_Fixed curY,
478  CF2_Fixed* width )
479  {
480  /* lastError is used for errors that are immediately tested */
481  FT_Error lastError = FT_Err_Ok;
482 
483  /* pointer to parsed font object */
484  PS_Decoder* decoder = font->decoder;
485 
486  FT_Error* error = &font->error;
487  FT_Memory memory = font->memory;
488 
489  CF2_Fixed scaleY = font->innerTransform.d;
490  CF2_Fixed nominalWidthX = cf2_getNominalWidthX( decoder );
491 
492  /* stuff for Type 1 */
493  FT_Int known_othersubr_result_cnt = 0;
494  FT_Bool large_int = FALSE;
495  FT_Bool initial_map_ready = FALSE;
496 
497 #define PS_STORAGE_SIZE 3
498  CF2_F16Dot16 results[PS_STORAGE_SIZE]; /* for othersubr results */
499  FT_Int result_cnt = 0;
500 
501  /* save this for hinting seac accents */
502  CF2_Fixed hintOriginY = curY;
503 
504  CF2_Stack opStack = NULL;
505  FT_UInt stackSize;
506  FT_Byte op1; /* first opcode byte */
507 
508  CF2_F16Dot16 storage[CF2_STORAGE_SIZE]; /* for `put' and `get' */
509  CF2_F16Dot16 flexStore[6]; /* for Type 1 flex */
510 
511  /* instruction limit; 20,000,000 matches Avalon */
512  FT_UInt32 instructionLimit = 20000000UL;
513 
514  CF2_ArrStackRec subrStack;
515 
516  FT_Bool haveWidth;
517  CF2_Buffer charstring = NULL;
518 
519  CF2_Int charstringIndex = -1; /* initialize to empty */
520 
521  /* TODO: placeholders for hint structures */
522 
523  /* objects used for hinting */
524  CF2_ArrStackRec hStemHintArray;
525  CF2_ArrStackRec vStemHintArray;
526 
527  CF2_HintMaskRec hintMask;
528  CF2_GlyphPathRec glyphPath;
529 
530 
531  FT_ZERO( &storage );
532  FT_ZERO( &results );
533  FT_ZERO( &flexStore );
534 
535  /* initialize the remaining objects */
536  cf2_arrstack_init( &subrStack,
537  memory,
538  error,
539  sizeof ( CF2_BufferRec ) );
540  cf2_arrstack_init( &hStemHintArray,
541  memory,
542  error,
543  sizeof ( CF2_StemHintRec ) );
544  cf2_arrstack_init( &vStemHintArray,
545  memory,
546  error,
547  sizeof ( CF2_StemHintRec ) );
548 
549  /* initialize CF2_StemHint arrays */
550  cf2_hintmask_init( &hintMask, error );
551 
552  /* initialize path map to manage drawing operations */
553 
554  /* Note: last 4 params are used to handle `MoveToPermissive', which */
555  /* may need to call `hintMap.Build' */
556  /* TODO: MoveToPermissive is gone; are these still needed? */
557  cf2_glyphpath_init( &glyphPath,
558  font,
559  callbacks,
560  scaleY,
561  /* hShift, */
562  &hStemHintArray,
563  &vStemHintArray,
564  &hintMask,
565  hintOriginY,
566  &font->blues,
567  translation );
568 
569  /*
570  * Initialize state for width parsing. From the CFF Spec:
571  *
572  * The first stack-clearing operator, which must be one of hstem,
573  * hstemhm, vstem, vstemhm, cntrmask, hintmask, hmoveto, vmoveto,
574  * rmoveto, or endchar, takes an additional argument - the width (as
575  * described earlier), which may be expressed as zero or one numeric
576  * argument.
577  *
578  * What we implement here uses the first validly specified width, but
579  * does not detect errors for specifying more than one width.
580  *
581  * If one of the above operators occurs without explicitly specifying
582  * a width, we assume the default width.
583  *
584  * CFF2 charstrings always return the default width (0).
585  *
586  */
587  haveWidth = font->isCFF2 ? TRUE : FALSE;
588  *width = cf2_getDefaultWidthX( decoder );
589 
590  /*
591  * Note: At this point, all pointers to resources must be NULL
592  * and all local objects must be initialized.
593  * There must be no branches to `exit:' above this point.
594  *
595  */
596 
597  /* allocate an operand stack */
598  stackSize = font->isCFF2 ? cf2_getMaxstack( decoder )
600  opStack = cf2_stack_init( memory, error, stackSize );
601 
602  if ( !opStack )
603  {
604  lastError = FT_THROW( Out_Of_Memory );
605  goto exit;
606  }
607 
608  /* initialize subroutine stack by placing top level charstring as */
609  /* first element (max depth plus one for the charstring) */
610  /* Note: Caller owns and must finalize the first charstring. */
611  /* Our copy of it does not change that requirement. */
612  cf2_arrstack_setCount( &subrStack, CF2_MAX_SUBR + 1 );
613 
614  charstring = (CF2_Buffer)cf2_arrstack_getBuffer( &subrStack );
615 
616  /* catch errors so far */
617  if ( *error )
618  goto exit;
619 
620  *charstring = *buf; /* structure copy */
621  charstringIndex = 0; /* entry is valid now */
622 
623  /* main interpreter loop */
624  while ( 1 )
625  {
626  if ( font->isT1 )
627  FT_ASSERT( known_othersubr_result_cnt == 0 ||
628  result_cnt == 0 );
629 
630  if ( cf2_buf_isEnd( charstring ) )
631  {
632  /* If we've reached the end of the charstring, simulate a */
633  /* cf2_cmdRETURN or cf2_cmdENDCHAR. */
634  /* We do this for both CFF and CFF2. */
635  if ( charstringIndex )
636  op1 = cf2_cmdRETURN; /* end of buffer for subroutine */
637  else
638  op1 = cf2_cmdENDCHAR; /* end of buffer for top level charstring */
639  }
640  else
641  {
642  op1 = (FT_Byte)cf2_buf_readByte( charstring );
643 
644  /* Explicit RETURN and ENDCHAR in CFF2 should be ignored. */
645  /* Note: Trace message will report 0 instead of 11 or 14. */
646  if ( ( op1 == cf2_cmdRETURN || op1 == cf2_cmdENDCHAR ) &&
647  font->isCFF2 )
648  op1 = cf2_cmdRESERVED_0;
649  }
650 
651  if ( font->isT1 )
652  {
653  if ( !initial_map_ready &&
654  !( op1 == cf2_cmdHSTEM ||
655  op1 == cf2_cmdVSTEM ||
656  op1 == cf2_cmdHSBW ||
657  op1 == cf2_cmdCALLSUBR ||
658  op1 == cf2_cmdRETURN ||
659  op1 == cf2_cmdESC ||
660  op1 == cf2_cmdENDCHAR ||
661  op1 >= 32 /* Numbers */ ) )
662  {
663  /* Skip outline commands first time round. */
664  /* `endchar' will trigger initial hintmap build */
665  /* and rewind the charstring. */
666  FT_TRACE4(( " <outline command skipped>\n" ));
667  cf2_stack_clear( opStack );
668  continue;
669  }
670 
671  if ( result_cnt > 0 &&
672  !( op1 == cf2_cmdCALLSUBR ||
673  op1 == cf2_cmdRETURN ||
674  op1 == cf2_cmdESC ||
675  op1 >= 32 /* Numbers */ ) )
676  {
677  /* all operands have been transferred by previous pops */
678  result_cnt = 0;
679  }
680 
681  if ( large_int && !( op1 >= 32 || op1 == cf2_escDIV ) )
682  {
683  FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
684  " no `div' after large integer\n" ));
685 
686  large_int = FALSE;
687  }
688  }
689 
690  /* check for errors once per loop */
691  if ( *error )
692  goto exit;
693 
694  instructionLimit--;
695  if ( instructionLimit == 0 )
696  {
697  lastError = FT_THROW( Invalid_Glyph_Format );
698  goto exit;
699  }
700 
701  switch( op1 )
702  {
703  case cf2_cmdRESERVED_0:
704  case cf2_cmdRESERVED_2:
705  case cf2_cmdRESERVED_17:
706  /* we may get here if we have a prior error */
707  FT_TRACE4(( " unknown op (%d)\n", op1 ));
708  break;
709 
710  case cf2_cmdVSINDEX:
711  FT_TRACE4(( " vsindex\n" ));
712 
713  if ( !font->isCFF2 )
714  break; /* clear stack & ignore */
715 
716  if ( font->blend.usedBV )
717  {
718  /* vsindex not allowed after blend */
719  lastError = FT_THROW( Invalid_Glyph_Format );
720  goto exit;
721  }
722 
723  {
724  FT_Int temp = cf2_stack_popInt( opStack );
725 
726 
727  if ( temp >= 0 )
728  font->vsindex = (FT_UInt)temp;
729  }
730  break;
731 
732  case cf2_cmdBLEND:
733  {
734  FT_UInt numBlends;
735 
736 
737  FT_TRACE4(( " blend\n" ));
738 
739  if ( !font->isCFF2 )
740  break; /* clear stack & ignore */
741 
742  /* do we have a `blend' op in a non-variant font? */
743  if ( !font->blend.font )
744  {
745  lastError = FT_THROW( Invalid_Glyph_Format );
746  goto exit;
747  }
748 
749  /* check cached blend vector */
750  if ( font->cffload->blend_check_vector( &font->blend,
751  font->vsindex,
752  font->lenNDV,
753  font->NDV ) )
754  {
755  lastError = font->cffload->blend_build_vector( &font->blend,
756  font->vsindex,
757  font->lenNDV,
758  font->NDV );
759  if ( lastError )
760  goto exit;
761  }
762 
763  /* do the blend */
764  numBlends = (FT_UInt)cf2_stack_popInt( opStack );
765  if ( numBlends > stackSize )
766  {
767  lastError = FT_THROW( Invalid_Glyph_Format );
768  goto exit;
769  }
770 
771  cf2_doBlend( &font->blend, opStack, numBlends );
772 
773  font->blend.usedBV = TRUE;
774  }
775  continue; /* do not clear the stack */
776 
777  case cf2_cmdHSTEMHM:
778  case cf2_cmdHSTEM:
779  FT_TRACE4(( "%s\n", op1 == cf2_cmdHSTEMHM ? " hstemhm"
780  : " hstem" ));
781 
782  if ( !font->isT1 )
783  {
784  /* never add hints after the mask is computed */
785  /* except if in Type 1 mode (no hintmask op) */
786  if ( cf2_hintmask_isValid( &hintMask ) )
787  {
788  FT_TRACE4(( "cf2_interpT2CharString:"
789  " invalid horizontal hint mask\n" ));
790  break;
791  }
792  }
793 
794  /* add left-sidebearing correction in Type 1 mode */
795  cf2_doStems( font,
796  opStack,
797  &hStemHintArray,
798  width,
799  &haveWidth,
800  font->isT1 ? decoder->builder.left_bearing->y
801  : 0 );
802 
803  if ( decoder->width_only )
804  goto exit;
805 
806  break;
807 
808  case cf2_cmdVSTEMHM:
809  case cf2_cmdVSTEM:
810  FT_TRACE4(( "%s\n", op1 == cf2_cmdVSTEMHM ? " vstemhm"
811  : " vstem" ));
812 
813  if ( !font->isT1 )
814  {
815  /* never add hints after the mask is computed */
816  /* except if in Type 1 mode (no hintmask op) */
817  if ( cf2_hintmask_isValid( &hintMask ) )
818  {
819  FT_TRACE4(( "cf2_interpT2CharString:"
820  " invalid vertical hint mask\n" ));
821  break;
822  }
823  }
824 
825  /* add left-sidebearing correction in Type 1 mode */
826  cf2_doStems( font,
827  opStack,
828  &vStemHintArray,
829  width,
830  &haveWidth,
831  font->isT1 ? decoder->builder.left_bearing->x
832  : 0 );
833 
834  if ( decoder->width_only )
835  goto exit;
836 
837  break;
838 
839  case cf2_cmdVMOVETO:
840  FT_TRACE4(( " vmoveto\n" ));
841 
842  if ( font->isT1 && !decoder->flex_state && !haveWidth )
843  FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
844  " No width. Use hsbw/sbw as first op\n" ));
845 
846  if ( cf2_stack_count( opStack ) > 1 && !haveWidth )
847  *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ),
848  nominalWidthX );
849 
850  /* width is defined or default after this */
851  haveWidth = TRUE;
852 
853  if ( decoder->width_only )
854  goto exit;
855 
856  curY = ADD_INT32( curY, cf2_stack_popFixed( opStack ) );
857 
858  if ( !decoder->flex_state )
859  cf2_glyphpath_moveTo( &glyphPath, curX, curY );
860 
861  break;
862 
863  case cf2_cmdRLINETO:
864  {
865  CF2_UInt idx;
866  CF2_UInt count = cf2_stack_count( opStack );
867 
868 
869  FT_TRACE4(( " rlineto\n" ));
870 
871  for ( idx = 0; idx < count; idx += 2 )
872  {
873  curX = ADD_INT32( curX, cf2_stack_getReal( opStack,
874  idx + 0 ) );
875  curY = ADD_INT32( curY, cf2_stack_getReal( opStack,
876  idx + 1 ) );
877 
878  cf2_glyphpath_lineTo( &glyphPath, curX, curY );
879  }
880 
881  cf2_stack_clear( opStack );
882  }
883  continue; /* no need to clear stack again */
884 
885  case cf2_cmdHLINETO:
886  case cf2_cmdVLINETO:
887  {
888  CF2_UInt idx;
889  CF2_UInt count = cf2_stack_count( opStack );
890 
891  FT_Bool isX = FT_BOOL( op1 == cf2_cmdHLINETO );
892 
893 
894  FT_TRACE4(( "%s\n", isX ? " hlineto" : " vlineto" ));
895 
896  for ( idx = 0; idx < count; idx++ )
897  {
898  CF2_Fixed v = cf2_stack_getReal( opStack, idx );
899 
900 
901  if ( isX )
902  curX = ADD_INT32( curX, v );
903  else
904  curY = ADD_INT32( curY, v );
905 
906  isX = !isX;
907 
908  cf2_glyphpath_lineTo( &glyphPath, curX, curY );
909  }
910 
911  cf2_stack_clear( opStack );
912  }
913  continue;
914 
915  case cf2_cmdRCURVELINE:
916  case cf2_cmdRRCURVETO:
917  {
918  CF2_UInt count = cf2_stack_count( opStack );
919  CF2_UInt idx = 0;
920 
921 
922  FT_TRACE4(( "%s\n", op1 == cf2_cmdRCURVELINE ? " rcurveline"
923  : " rrcurveto" ));
924 
925  while ( idx + 6 <= count )
926  {
927  CF2_Fixed x1, y1, x2, y2, x3, y3;
928 
929 
930  x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX );
931  y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), curY );
932  x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), x1 );
933  y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y1 );
934  x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), x2 );
935  y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 5 ), y2 );
936 
937  cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
938 
939  curX = x3;
940  curY = y3;
941  idx += 6;
942  }
943 
944  if ( op1 == cf2_cmdRCURVELINE )
945  {
946  curX = ADD_INT32( curX, cf2_stack_getReal( opStack,
947  idx + 0 ) );
948  curY = ADD_INT32( curY, cf2_stack_getReal( opStack,
949  idx + 1 ) );
950 
951  cf2_glyphpath_lineTo( &glyphPath, curX, curY );
952  }
953 
954  cf2_stack_clear( opStack );
955  }
956  continue; /* no need to clear stack again */
957 
958  case cf2_cmdCLOSEPATH:
959  if ( !font->isT1 )
960  FT_TRACE4(( " unknown op (%d)\n", op1 ));
961  else
962  {
963  FT_TRACE4(( " closepath\n" ));
964 
965  /* if there is no path, `closepath' is a no-op */
966  cf2_glyphpath_closeOpenPath( &glyphPath );
967 
968  haveWidth = TRUE;
969  }
970  break;
971 
972  case cf2_cmdCALLGSUBR:
973  case cf2_cmdCALLSUBR:
974  {
975  CF2_Int subrNum;
976 
977 
978  FT_TRACE4(( "%s", op1 == cf2_cmdCALLGSUBR ? " callgsubr"
979  : " callsubr" ));
980 
981  if ( ( !font->isT1 && charstringIndex > CF2_MAX_SUBR ) ||
982  ( font->isT1 && charstringIndex > T1_MAX_SUBRS_CALLS ) )
983  {
984  /* max subr plus one for charstring */
985  lastError = FT_THROW( Invalid_Glyph_Format );
986  goto exit; /* overflow of stack */
987  }
988 
989  /* push our current CFF charstring region on subrStack */
990  charstring = (CF2_Buffer)
992  &subrStack,
993  (size_t)charstringIndex + 1 );
994 
995  /* set up the new CFF region and pointer */
996  subrNum = cf2_stack_popInt( opStack );
997 
998  if ( font->isT1 && decoder->locals_hash )
999  {
1000  size_t* val = ft_hash_num_lookup( subrNum,
1001  decoder->locals_hash );
1002 
1003 
1004  if ( val )
1005  subrNum = *val;
1006  else
1007  subrNum = -1;
1008  }
1009 
1010  switch ( op1 )
1011  {
1012  case cf2_cmdCALLGSUBR:
1013  FT_TRACE4(( " (idx %d, entering level %d)\n",
1014  subrNum + decoder->globals_bias,
1015  charstringIndex + 1 ));
1016 
1017  if ( cf2_initGlobalRegionBuffer( decoder,
1018  subrNum,
1019  charstring ) )
1020  {
1021  lastError = FT_THROW( Invalid_Glyph_Format );
1022  goto exit; /* subroutine lookup or stream error */
1023  }
1024  break;
1025 
1026  default:
1027  /* cf2_cmdCALLSUBR */
1028  FT_TRACE4(( " (idx %d, entering level %d)\n",
1029  subrNum + decoder->locals_bias,
1030  charstringIndex + 1 ));
1031 
1032  if ( cf2_initLocalRegionBuffer( decoder,
1033  subrNum,
1034  charstring ) )
1035  {
1036  lastError = FT_THROW( Invalid_Glyph_Format );
1037  goto exit; /* subroutine lookup or stream error */
1038  }
1039  }
1040 
1041  charstringIndex += 1; /* entry is valid now */
1042  }
1043  continue; /* do not clear the stack */
1044 
1045  case cf2_cmdRETURN:
1046  FT_TRACE4(( " return (leaving level %d)\n", charstringIndex ));
1047 
1048  if ( charstringIndex < 1 )
1049  {
1050  /* Note: cannot return from top charstring */
1051  lastError = FT_THROW( Invalid_Glyph_Format );
1052  goto exit; /* underflow of stack */
1053  }
1054 
1055  /* restore position in previous charstring */
1056  charstring = (CF2_Buffer)
1058  &subrStack,
1059  (CF2_UInt)--charstringIndex );
1060  continue; /* do not clear the stack */
1061 
1062  case cf2_cmdESC:
1063  {
1064  FT_Byte op2 = (FT_Byte)cf2_buf_readByte( charstring );
1065 
1066 
1067  /* first switch for 2-byte operators handles CFF2 */
1068  /* and opcodes that are reserved for both CFF and CFF2 */
1069  switch ( op2 )
1070  {
1071  case cf2_escHFLEX:
1072  {
1073  static const FT_Bool readFromStack[12] =
1074  {
1075  TRUE /* dx1 */, FALSE /* dy1 */,
1076  TRUE /* dx2 */, TRUE /* dy2 */,
1077  TRUE /* dx3 */, FALSE /* dy3 */,
1078  TRUE /* dx4 */, FALSE /* dy4 */,
1079  TRUE /* dx5 */, FALSE /* dy5 */,
1080  TRUE /* dx6 */, FALSE /* dy6 */
1081  };
1082 
1083 
1084  FT_TRACE4(( " hflex\n" ));
1085 
1086  cf2_doFlex( opStack,
1087  &curX,
1088  &curY,
1089  &glyphPath,
1090  readFromStack,
1091  FALSE /* doConditionalLastRead */ );
1092  }
1093  continue;
1094 
1095  case cf2_escFLEX:
1096  {
1097  static const FT_Bool readFromStack[12] =
1098  {
1099  TRUE /* dx1 */, TRUE /* dy1 */,
1100  TRUE /* dx2 */, TRUE /* dy2 */,
1101  TRUE /* dx3 */, TRUE /* dy3 */,
1102  TRUE /* dx4 */, TRUE /* dy4 */,
1103  TRUE /* dx5 */, TRUE /* dy5 */,
1104  TRUE /* dx6 */, TRUE /* dy6 */
1105  };
1106 
1107 
1108  FT_TRACE4(( " flex\n" ));
1109 
1110  cf2_doFlex( opStack,
1111  &curX,
1112  &curY,
1113  &glyphPath,
1114  readFromStack,
1115  FALSE /* doConditionalLastRead */ );
1116  }
1117  break; /* TODO: why is this not a continue? */
1118 
1119  case cf2_escHFLEX1:
1120  {
1121  static const FT_Bool readFromStack[12] =
1122  {
1123  TRUE /* dx1 */, TRUE /* dy1 */,
1124  TRUE /* dx2 */, TRUE /* dy2 */,
1125  TRUE /* dx3 */, FALSE /* dy3 */,
1126  TRUE /* dx4 */, FALSE /* dy4 */,
1127  TRUE /* dx5 */, TRUE /* dy5 */,
1128  TRUE /* dx6 */, FALSE /* dy6 */
1129  };
1130 
1131 
1132  FT_TRACE4(( " hflex1\n" ));
1133 
1134  cf2_doFlex( opStack,
1135  &curX,
1136  &curY,
1137  &glyphPath,
1138  readFromStack,
1139  FALSE /* doConditionalLastRead */ );
1140  }
1141  continue;
1142 
1143  case cf2_escFLEX1:
1144  {
1145  static const FT_Bool readFromStack[12] =
1146  {
1147  TRUE /* dx1 */, TRUE /* dy1 */,
1148  TRUE /* dx2 */, TRUE /* dy2 */,
1149  TRUE /* dx3 */, TRUE /* dy3 */,
1150  TRUE /* dx4 */, TRUE /* dy4 */,
1151  TRUE /* dx5 */, TRUE /* dy5 */,
1152  FALSE /* dx6 */, FALSE /* dy6 */
1153  };
1154 
1155 
1156  FT_TRACE4(( " flex1\n" ));
1157 
1158  cf2_doFlex( opStack,
1159  &curX,
1160  &curY,
1161  &glyphPath,
1162  readFromStack,
1163  TRUE /* doConditionalLastRead */ );
1164  }
1165  continue;
1166 
1167  /* these opcodes are always reserved */
1168  case cf2_escRESERVED_8:
1169  case cf2_escRESERVED_13:
1170  case cf2_escRESERVED_19:
1171  case cf2_escRESERVED_25:
1172  case cf2_escRESERVED_31:
1173  case cf2_escRESERVED_32:
1174  FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
1175  break;
1176 
1177  default:
1178  {
1179  if ( font->isCFF2 || op2 >= cf2_escRESERVED_38 )
1180  FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
1181  else if ( font->isT1 && result_cnt > 0 && op2 != cf2_escPOP )
1182  {
1183  /* all operands have been transferred by previous pops */
1184  result_cnt = 0;
1185  }
1186  else
1187  {
1188  /* second switch for 2-byte operators handles */
1189  /* CFF and Type 1 */
1190  switch ( op2 )
1191  {
1192 
1193  case cf2_escDOTSECTION:
1194  /* something about `flip type of locking' -- ignore it */
1195  FT_TRACE4(( " dotsection\n" ));
1196 
1197  break;
1198 
1199  case cf2_escVSTEM3:
1200  case cf2_escHSTEM3:
1201  /*
1202  * Type 1: Type 2:
1203  * x0 dx0 x1 dx1 x2 dx2 vstem3 x dx {dxa dxb}* vstem
1204  * y0 dy0 y1 dy1 y2 dy2 hstem3 y dy {dya dyb}* hstem
1205  * relative to lsb point relative to zero
1206  *
1207  */
1208  {
1209  if ( !font->isT1 )
1210  FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
1211  else
1212  {
1213  CF2_F16Dot16 v0, v1, v2;
1214 
1215  FT_Bool isV = FT_BOOL( op2 == cf2_escVSTEM3 );
1216 
1217 
1218  FT_TRACE4(( "%s\n", isV ? " vstem3"
1219  : " hstem3" ));
1220 
1221  FT_ASSERT( cf2_stack_count( opStack ) == 6 );
1222 
1223  v0 = cf2_stack_getReal( opStack, 0 );
1224  v1 = cf2_stack_getReal( opStack, 2 );
1225  v2 = cf2_stack_getReal( opStack, 4 );
1226 
1228  opStack, 2,
1229  SUB_INT32( SUB_INT32( v1, v0 ),
1230  cf2_stack_getReal( opStack, 1 ) ) );
1232  opStack, 4,
1233  SUB_INT32( SUB_INT32( v2, v1 ),
1234  cf2_stack_getReal( opStack, 3 ) ) );
1235 
1236  /* add left-sidebearing correction */
1237  cf2_doStems( font,
1238  opStack,
1239  isV ? &vStemHintArray : &hStemHintArray,
1240  width,
1241  &haveWidth,
1242  isV ? decoder->builder.left_bearing->x
1243  : decoder->builder.left_bearing->y );
1244 
1245  if ( decoder->width_only )
1246  goto exit;
1247  }
1248  }
1249  break;
1250 
1251  case cf2_escAND:
1252  {
1254  CF2_F16Dot16 arg2;
1255 
1256 
1257  FT_TRACE4(( " and\n" ));
1258 
1259  arg2 = cf2_stack_popFixed( opStack );
1260  arg1 = cf2_stack_popFixed( opStack );
1261 
1262  cf2_stack_pushInt( opStack, arg1 && arg2 );
1263  }
1264  continue; /* do not clear the stack */
1265 
1266  case cf2_escOR:
1267  {
1269  CF2_F16Dot16 arg2;
1270 
1271 
1272  FT_TRACE4(( " or\n" ));
1273 
1274  arg2 = cf2_stack_popFixed( opStack );
1275  arg1 = cf2_stack_popFixed( opStack );
1276 
1277  cf2_stack_pushInt( opStack, arg1 || arg2 );
1278  }
1279  continue; /* do not clear the stack */
1280 
1281  case cf2_escNOT:
1282  {
1283  CF2_F16Dot16 arg;
1284 
1285 
1286  FT_TRACE4(( " not\n" ));
1287 
1288  arg = cf2_stack_popFixed( opStack );
1289 
1290  cf2_stack_pushInt( opStack, !arg );
1291  }
1292  continue; /* do not clear the stack */
1293 
1294  case cf2_escSEAC:
1295  if ( !font->isT1 )
1296  FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
1297  else
1298  {
1299  FT_Error error2;
1300  CF2_Int bchar_index, achar_index;
1301  FT_Vector left_bearing, advance;
1302 
1303 #ifdef FT_CONFIG_OPTION_INCREMENTAL
1304  T1_Face face = (T1_Face)decoder->builder.face;
1305 #endif
1306  CF2_BufferRec component;
1307  CF2_Fixed dummyWidth;
1308 
1309  CF2_Int achar = cf2_stack_popInt( opStack );
1310  CF2_Int bchar = cf2_stack_popInt( opStack );
1311 
1312  FT_Pos ady = cf2_stack_popFixed ( opStack );
1313  FT_Pos adx = cf2_stack_popFixed ( opStack );
1314  FT_Pos asb = cf2_stack_popFixed ( opStack );
1315 
1316 
1317  FT_TRACE4(( " seac\n" ));
1318 
1319  if ( doingSeac )
1320  {
1321  FT_ERROR(( " nested seac\n" ));
1322  lastError = FT_THROW( Invalid_Glyph_Format );
1323  goto exit; /* nested seac */
1324  }
1325 
1326  if ( decoder->builder.metrics_only )
1327  {
1328  FT_ERROR(( " unexpected seac\n" ));
1329  lastError = FT_THROW( Invalid_Glyph_Format );
1330  goto exit; /* unexpected seac */
1331  }
1332 
1333  /* `glyph_names' is set to 0 for CID fonts which do */
1334  /* not include an encoding. How can we deal with */
1335  /* these? */
1336 #ifdef FT_CONFIG_OPTION_INCREMENTAL
1337  if ( decoder->glyph_names == 0 &&
1338  !face->root.internal->incremental_interface )
1339 #else
1340  if ( decoder->glyph_names == 0 )
1341 #endif /* FT_CONFIG_OPTION_INCREMENTAL */
1342  {
1343  FT_ERROR((
1344  "cf2_interpT2CharString: (Type 1 seac)"
1345  " glyph names table not available in this font\n" ));
1346  lastError = FT_THROW( Invalid_Glyph_Format );
1347  goto exit;
1348  }
1349 
1350  /* seac weirdness */
1351  adx += decoder->builder.left_bearing->x;
1352 
1353 #ifdef FT_CONFIG_OPTION_INCREMENTAL
1354  if ( face->root.internal->incremental_interface )
1355  {
1356  /* the caller must handle the font encoding also */
1357  bchar_index = bchar;
1358  achar_index = achar;
1359  }
1360  else
1361 #endif
1362  {
1363  bchar_index = t1_lookup_glyph_by_stdcharcode_ps(
1364  decoder, bchar );
1365  achar_index = t1_lookup_glyph_by_stdcharcode_ps(
1366  decoder, achar );
1367  }
1368 
1369  if ( bchar_index < 0 || achar_index < 0 )
1370  {
1371  FT_ERROR((
1372  "cf2_interpT2CharString: (Type 1 seac)"
1373  " invalid seac character code arguments\n" ));
1374  lastError = FT_THROW( Invalid_Glyph_Format );
1375  goto exit;
1376  }
1377 
1378  /* if we are trying to load a composite glyph, */
1379  /* do not load the accent character and return */
1380  /* the array of subglyphs. */
1381  if ( decoder->builder.no_recurse )
1382  {
1384  FT_GlyphLoader loader = glyph->internal->loader;
1385  FT_SubGlyph subg;
1386 
1387 
1388  /* reallocate subglyph array if necessary */
1389  error2 = FT_GlyphLoader_CheckSubGlyphs( loader, 2 );
1390  if ( error2 )
1391  {
1392  lastError = error2; /* pass FreeType error through */
1393  goto exit;
1394  }
1395 
1396  subg = loader->current.subglyphs;
1397 
1398  /* subglyph 0 = base character */
1399  subg->index = bchar_index;
1400  subg->flags = FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES |
1402  subg->arg1 = 0;
1403  subg->arg2 = 0;
1404  subg++;
1405 
1406  /* subglyph 1 = accent character */
1407  subg->index = achar_index;
1409  subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb );
1410  subg->arg2 = (FT_Int)FIXED_TO_INT( ady );
1411 
1412  /* set up remaining glyph fields */
1413  glyph->num_subglyphs = 2;
1414  glyph->subglyphs = loader->base.subglyphs;
1415  glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
1416 
1417  loader->current.num_subglyphs = 2;
1418 
1419  goto exit;
1420  }
1421 
1422  /* First load `bchar' in builder */
1423  /* now load the unscaled outline */
1424 
1425  /* prepare loader */
1427 
1428  error2 = cf2_getT1SeacComponent( decoder,
1429  (FT_UInt)bchar_index,
1430  &component );
1431  if ( error2 )
1432  {
1433  lastError = error2; /* pass FreeType error through */
1434  goto exit;
1435  }
1436 
1437  /* save the left bearing and width of the SEAC */
1438  /* glyph as they will be erased by the next load */
1439 
1440  left_bearing = *decoder->builder.left_bearing;
1441  advance = *decoder->builder.advance;
1442 
1444  &component,
1445  callbacks,
1446  translation,
1447  TRUE,
1448  0,
1449  0,
1450  &dummyWidth );
1451  cf2_freeT1SeacComponent( decoder, &component );
1452 
1453  /* If the SEAC glyph doesn't have a (H)SBW of its */
1454  /* own use the values from the base glyph. */
1455 
1456  if ( !haveWidth )
1457  {
1458  left_bearing = *decoder->builder.left_bearing;
1459  advance = *decoder->builder.advance;
1460  }
1461 
1462  decoder->builder.left_bearing->x = 0;
1463  decoder->builder.left_bearing->y = 0;
1464 
1465  /* Now load `achar' on top of */
1466  /* the base outline */
1467 
1468  error2 = cf2_getT1SeacComponent( decoder,
1469  (FT_UInt)achar_index,
1470  &component );
1471  if ( error2 )
1472  {
1473  lastError = error2; /* pass FreeType error through */
1474  goto exit;
1475  }
1477  &component,
1478  callbacks,
1479  translation,
1480  TRUE,
1481  adx - asb,
1482  ady,
1483  &dummyWidth );
1484  cf2_freeT1SeacComponent( decoder, &component );
1485 
1486  /* restore the left side bearing and advance width */
1487  /* of the SEAC glyph or base character (saved above) */
1488 
1489  *decoder->builder.left_bearing = left_bearing;
1490  *decoder->builder.advance = advance;
1491 
1492  goto exit;
1493  }
1494  break;
1495 
1496  case cf2_escSBW:
1497  if ( !font->isT1 )
1498  FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
1499  else
1500  {
1501  CF2_Fixed lsb_x, lsb_y;
1502  PS_Builder* builder;
1503 
1504 
1505  FT_TRACE4(( " sbw" ));
1506 
1507  builder = &decoder->builder;
1508 
1509  builder->advance->y = cf2_stack_popFixed( opStack );
1510  builder->advance->x = cf2_stack_popFixed( opStack );
1511 
1512  lsb_y = cf2_stack_popFixed( opStack );
1513  lsb_x = cf2_stack_popFixed( opStack );
1514 
1515  builder->left_bearing->x =
1516  ADD_INT32( builder->left_bearing->x, lsb_x );
1517  builder->left_bearing->y =
1518  ADD_INT32( builder->left_bearing->y, lsb_y );
1519 
1520  haveWidth = TRUE;
1521 
1522  /* the `metrics_only' indicates that we only want */
1523  /* to compute the glyph's metrics (lsb + advance */
1524  /* width), not load the rest of it; so exit */
1525  /* immediately */
1526  if ( builder->metrics_only )
1527  goto exit;
1528 
1529  if ( initial_map_ready )
1530  {
1531  curX = ADD_INT32( curX, lsb_x );
1532  curY = ADD_INT32( curY, lsb_y );
1533  }
1534  }
1535  break;
1536 
1537  case cf2_escABS:
1538  {
1539  CF2_F16Dot16 arg;
1540 
1541 
1542  FT_TRACE4(( " abs\n" ));
1543 
1544  arg = cf2_stack_popFixed( opStack );
1545 
1546  if ( arg < -CF2_FIXED_MAX )
1547  cf2_stack_pushFixed( opStack, CF2_FIXED_MAX );
1548  else
1549  cf2_stack_pushFixed( opStack, FT_ABS( arg ) );
1550  }
1551  continue; /* do not clear the stack */
1552 
1553  case cf2_escADD:
1554  {
1555  CF2_F16Dot16 summand1;
1556  CF2_F16Dot16 summand2;
1557 
1558 
1559  FT_TRACE4(( " add\n" ));
1560 
1561  summand2 = cf2_stack_popFixed( opStack );
1562  summand1 = cf2_stack_popFixed( opStack );
1563 
1564  cf2_stack_pushFixed( opStack,
1565  ADD_INT32( summand1,
1566  summand2 ) );
1567  }
1568  continue; /* do not clear the stack */
1569 
1570  case cf2_escSUB:
1571  {
1572  CF2_F16Dot16 minuend;
1573  CF2_F16Dot16 subtrahend;
1574 
1575 
1576  FT_TRACE4(( " sub\n" ));
1577 
1578  subtrahend = cf2_stack_popFixed( opStack );
1579  minuend = cf2_stack_popFixed( opStack );
1580 
1581  cf2_stack_pushFixed( opStack,
1582  SUB_INT32( minuend, subtrahend ) );
1583  }
1584  continue; /* do not clear the stack */
1585 
1586  case cf2_escDIV:
1587  {
1588  CF2_F16Dot16 dividend;
1589  CF2_F16Dot16 divisor;
1590 
1591 
1592  FT_TRACE4(( " div\n" ));
1593 
1594  if ( font->isT1 && large_int )
1595  {
1596  divisor = (CF2_F16Dot16)cf2_stack_popInt( opStack );
1597  dividend = (CF2_F16Dot16)cf2_stack_popInt( opStack );
1598 
1599  large_int = FALSE;
1600  }
1601  else
1602  {
1603  divisor = cf2_stack_popFixed( opStack );
1604  dividend = cf2_stack_popFixed( opStack );
1605  }
1606 
1607  cf2_stack_pushFixed( opStack,
1608  FT_DivFix( dividend, divisor ) );
1609 
1610  }
1611  continue; /* do not clear the stack */
1612 
1613  case cf2_escNEG:
1614  {
1615  CF2_F16Dot16 arg;
1616 
1617 
1618  FT_TRACE4(( " neg\n" ));
1619 
1620  arg = cf2_stack_popFixed( opStack );
1621 
1622  if ( arg < -CF2_FIXED_MAX )
1623  cf2_stack_pushFixed( opStack, CF2_FIXED_MAX );
1624  else
1625  cf2_stack_pushFixed( opStack, -arg );
1626  }
1627  continue; /* do not clear the stack */
1628 
1629  case cf2_escEQ:
1630  {
1632  CF2_F16Dot16 arg2;
1633 
1634 
1635  FT_TRACE4(( " eq\n" ));
1636 
1637  arg2 = cf2_stack_popFixed( opStack );
1638  arg1 = cf2_stack_popFixed( opStack );
1639 
1640  cf2_stack_pushInt( opStack, arg1 == arg2 );
1641  }
1642  continue; /* do not clear the stack */
1643 
1644  case cf2_escCALLOTHERSUBR:
1645  if ( !font->isT1 )
1646  FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
1647  else
1648  {
1649  CF2_Int subr_no;
1650  CF2_Int arg_cnt;
1651  CF2_UInt count;
1652  CF2_UInt opIdx = 0;
1653 
1654 
1655  FT_TRACE4(( " callothersubr\n" ));
1656 
1657  subr_no = cf2_stack_popInt( opStack );
1658  arg_cnt = cf2_stack_popInt( opStack );
1659 
1660  /********************************************************
1661  *
1662  * remove all operands to callothersubr from the stack
1663  *
1664  * for handled othersubrs, where we know the number of
1665  * arguments, we increase the stack by the value of
1666  * known_othersubr_result_cnt
1667  *
1668  * for unhandled othersubrs the following pops adjust
1669  * the stack pointer as necessary
1670  */
1671 
1672  count = cf2_stack_count( opStack );
1673  FT_ASSERT( (CF2_UInt)arg_cnt <= count );
1674 
1675  opIdx += count - (CF2_UInt)arg_cnt;
1676 
1677  known_othersubr_result_cnt = 0;
1678  result_cnt = 0;
1679 
1680  /* XXX TODO: The checks to `arg_count == <whatever>' */
1681  /* might not be correct; an othersubr expects a */
1682  /* certain number of operands on the PostScript stack */
1683  /* (as opposed to the T1 stack) but it doesn't have to */
1684  /* put them there by itself; previous othersubrs might */
1685  /* have left the operands there if they were not */
1686  /* followed by an appropriate number of pops */
1687  /* */
1688  /* On the other hand, Adobe Reader 7.0.8 for Linux */
1689  /* doesn't accept a font that contains charstrings */
1690  /* like */
1691  /* */
1692  /* 100 200 2 20 callothersubr */
1693  /* 300 1 20 callothersubr pop */
1694  /* */
1695  /* Perhaps this is the reason why BuildCharArray */
1696  /* exists. */
1697 
1698  switch ( subr_no )
1699  {
1700  case 0: /* end flex feature */
1701  if ( arg_cnt != 3 )
1702  goto Unexpected_OtherSubr;
1703 
1704  if ( initial_map_ready &&
1705  ( !decoder->flex_state ||
1706  decoder->num_flex_vectors != 7 ) )
1707  {
1708  FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
1709  " unexpected flex end\n" ));
1710  lastError = FT_THROW( Invalid_Glyph_Format );
1711  goto exit;
1712  }
1713 
1714  /* the two `results' are popped */
1715  /* by the following setcurrentpoint */
1716  cf2_stack_pushFixed( opStack, curX );
1717  cf2_stack_pushFixed( opStack, curY );
1718  known_othersubr_result_cnt = 2;
1719  break;
1720 
1721  case 1: /* start flex feature */
1722  if ( arg_cnt != 0 )
1723  goto Unexpected_OtherSubr;
1724 
1725  if ( !initial_map_ready )
1726  break;
1727 
1728  if ( ps_builder_check_points( &decoder->builder, 6 ) )
1729  goto exit;
1730 
1731  decoder->flex_state = 1;
1732  decoder->num_flex_vectors = 0;
1733  break;
1734 
1735  case 2: /* add flex vectors */
1736  {
1737  FT_Int idx;
1738  FT_Int idx2;
1739 
1740 
1741  if ( arg_cnt != 0 )
1742  goto Unexpected_OtherSubr;
1743 
1744  if ( !initial_map_ready )
1745  break;
1746 
1747  if ( !decoder->flex_state )
1748  {
1749  FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
1750  " missing flex start\n" ));
1751  lastError = FT_THROW( Invalid_Glyph_Format );
1752  goto exit;
1753  }
1754 
1755  /* note that we should not add a point for */
1756  /* index 0; this will move our current position */
1757  /* to the flex point without adding any point */
1758  /* to the outline */
1759  idx = decoder->num_flex_vectors++;
1760  if ( idx > 0 && idx < 7 )
1761  {
1762  /* in malformed fonts it is possible to have */
1763  /* other opcodes in the middle of a flex (which */
1764  /* don't increase `num_flex_vectors'); we thus */
1765  /* have to check whether we can add a point */
1766 
1767  if ( ps_builder_check_points( &decoder->builder,
1768  1 ) )
1769  {
1770  lastError = FT_THROW( Invalid_Glyph_Format );
1771  goto exit;
1772  }
1773 
1774  /* map: 1->2 2->4 3->6 4->2 5->4 6->6 */
1775  idx2 = ( idx > 3 ? idx - 3 : idx ) * 2;
1776 
1777  flexStore[idx2 - 2] = curX;
1778  flexStore[idx2 - 1] = curY;
1779 
1780  if ( idx == 3 || idx == 6 )
1781  cf2_glyphpath_curveTo( &glyphPath,
1782  flexStore[0],
1783  flexStore[1],
1784  flexStore[2],
1785  flexStore[3],
1786  flexStore[4],
1787  flexStore[5] );
1788  }
1789  }
1790  break;
1791 
1792  case 3: /* change hints */
1793  if ( arg_cnt != 1 )
1794  goto Unexpected_OtherSubr;
1795 
1796  if ( initial_map_ready )
1797  {
1798  /* do not clear hints if initial hintmap */
1799  /* is not ready - we need to collate all */
1800  cf2_arrstack_clear( &vStemHintArray );
1801  cf2_arrstack_clear( &hStemHintArray );
1802 
1803  cf2_hintmask_init( &hintMask, error );
1804  hintMask.isValid = FALSE;
1805  hintMask.isNew = TRUE;
1806  }
1807 
1808  known_othersubr_result_cnt = 1;
1809  break;
1810 
1811  case 12:
1812  case 13:
1813  /* counter control hints, clear stack */
1814  cf2_stack_clear( opStack );
1815  break;
1816 
1817  case 14:
1818  case 15:
1819  case 16:
1820  case 17:
1821  case 18: /* multiple masters */
1822  {
1823  PS_Blend blend = decoder->blend;
1824  FT_UInt num_points, nn, mm;
1825  CF2_UInt delta;
1826  CF2_UInt values;
1827 
1828 
1829  if ( !blend )
1830  {
1831  FT_ERROR((
1832  "cf2_interpT2CharString:"
1833  " unexpected multiple masters operator\n" ));
1834  lastError = FT_THROW( Invalid_Glyph_Format );
1835  goto exit;
1836  }
1837 
1838  num_points = (FT_UInt)subr_no - 13 +
1839  ( subr_no == 18 );
1840  if ( arg_cnt != (FT_Int)( num_points *
1841  blend->num_designs ) )
1842  {
1843  FT_ERROR((
1844  "cf2_interpT2CharString:"
1845  " incorrect number of multiple masters arguments\n" ));
1846  lastError = FT_THROW( Invalid_Glyph_Format );
1847  goto exit;
1848  }
1849 
1850  /* We want to compute */
1851  /* */
1852  /* a0*w0 + a1*w1 + ... + ak*wk */
1853  /* */
1854  /* but we only have a0, a1-a0, a2-a0, ..., ak-a0. */
1855  /* */
1856  /* However, given that w0 + w1 + ... + wk == 1, we */
1857  /* can rewrite it easily as */
1858  /* */
1859  /* a0 + (a1-a0)*w1 + (a2-a0)*w2 + ... + (ak-a0)*wk */
1860  /* */
1861  /* where k == num_designs-1. */
1862  /* */
1863  /* I guess that's why it's written in this `compact' */
1864  /* form. */
1865  /* */
1866  delta = opIdx + num_points;
1867  values = opIdx;
1868  for ( nn = 0; nn < num_points; nn++ )
1869  {
1870  CF2_Fixed tmp = cf2_stack_getReal( opStack,
1871  values );
1872 
1873 
1874  for ( mm = 1; mm < blend->num_designs; mm++ )
1875  tmp = ADD_INT32( tmp,
1876  FT_MulFix(
1877  cf2_stack_getReal( opStack,
1878  delta++ ),
1879  blend->weight_vector[mm] ) );
1880 
1881  cf2_stack_setReal( opStack, values++, tmp );
1882  }
1883  cf2_stack_pop( opStack,
1884  (CF2_UInt)arg_cnt - num_points );
1885 
1886  known_othersubr_result_cnt = (FT_Int)num_points;
1887  break;
1888  }
1889 
1890  case 19:
1891  /* <idx> 1 19 callothersubr */
1892  /* ==> replace elements starting from index */
1893  /* cvi( <idx> ) of BuildCharArray with */
1894  /* WeightVector */
1895  {
1896  FT_Int idx;
1897  PS_Blend blend = decoder->blend;
1898 
1899 
1900  if ( arg_cnt != 1 || !blend )
1901  goto Unexpected_OtherSubr;
1902 
1903  idx = cf2_stack_popInt( opStack );
1904 
1905  if ( idx < 0 ||
1906  (FT_UInt)idx + blend->num_designs >
1907  decoder->len_buildchar )
1908  goto Unexpected_OtherSubr;
1909 
1910  ft_memcpy( &decoder->buildchar[idx],
1911  blend->weight_vector,
1912  blend->num_designs *
1913  sizeof ( blend->weight_vector[0] ) );
1914  }
1915  break;
1916 
1917  case 20:
1918  /* <arg1> <arg2> 2 20 callothersubr pop */
1919  /* ==> push <arg1> + <arg2> onto T1 stack */
1920  {
1921  CF2_F16Dot16 summand1;
1922  CF2_F16Dot16 summand2;
1923 
1924 
1925  if ( arg_cnt != 2 )
1926  goto Unexpected_OtherSubr;
1927 
1928  summand2 = cf2_stack_popFixed( opStack );
1929  summand1 = cf2_stack_popFixed( opStack );
1930 
1931  cf2_stack_pushFixed( opStack,
1932  ADD_INT32( summand1,
1933  summand2 ) );
1934  known_othersubr_result_cnt = 1;
1935  }
1936  break;
1937 
1938  case 21:
1939  /* <arg1> <arg2> 2 21 callothersubr pop */
1940  /* ==> push <arg1> - <arg2> onto T1 stack */
1941  {
1942  CF2_F16Dot16 minuend;
1943  CF2_F16Dot16 subtrahend;
1944 
1945 
1946  if ( arg_cnt != 2 )
1947  goto Unexpected_OtherSubr;
1948 
1949  subtrahend = cf2_stack_popFixed( opStack );
1950  minuend = cf2_stack_popFixed( opStack );
1951 
1952  cf2_stack_pushFixed( opStack,
1953  SUB_INT32( minuend,
1954  subtrahend ) );
1955  known_othersubr_result_cnt = 1;
1956  }
1957  break;
1958 
1959  case 22:
1960  /* <arg1> <arg2> 2 22 callothersubr pop */
1961  /* ==> push <arg1> * <arg2> onto T1 stack */
1962  {
1963  CF2_F16Dot16 factor1;
1964  CF2_F16Dot16 factor2;
1965 
1966 
1967  if ( arg_cnt != 2 )
1968  goto Unexpected_OtherSubr;
1969 
1970  factor2 = cf2_stack_popFixed( opStack );
1971  factor1 = cf2_stack_popFixed( opStack );
1972 
1973  cf2_stack_pushFixed( opStack,
1974  FT_MulFix( factor1, factor2 ) );
1975  known_othersubr_result_cnt = 1;
1976  }
1977  break;
1978 
1979  case 23:
1980  /* <arg1> <arg2> 2 23 callothersubr pop */
1981  /* ==> push <arg1> / <arg2> onto T1 stack */
1982  {
1983  CF2_F16Dot16 dividend;
1984  CF2_F16Dot16 divisor;
1985 
1986 
1987  if ( arg_cnt != 2 )
1988  goto Unexpected_OtherSubr;
1989 
1990  divisor = cf2_stack_popFixed( opStack );
1991  dividend = cf2_stack_popFixed( opStack );
1992 
1993  if ( divisor == 0 )
1994  goto Unexpected_OtherSubr;
1995 
1996  cf2_stack_pushFixed( opStack,
1997  FT_DivFix( dividend,
1998  divisor ) );
1999  known_othersubr_result_cnt = 1;
2000  }
2001  break;
2002 
2003  case 24:
2004  /* <val> <idx> 2 24 callothersubr */
2005  /* ==> set BuildCharArray[cvi( <idx> )] = <val> */
2006  {
2007  CF2_Int idx;
2008  PS_Blend blend = decoder->blend;
2009 
2010 
2011  if ( arg_cnt != 2 || !blend )
2012  goto Unexpected_OtherSubr;
2013 
2014  idx = cf2_stack_popInt( opStack );
2015 
2016  if ( idx < 0 ||
2017  (FT_UInt)idx >= decoder->len_buildchar )
2018  goto Unexpected_OtherSubr;
2019 
2020  decoder->buildchar[idx] =
2021  cf2_stack_popFixed( opStack );
2022  }
2023  break;
2024 
2025  case 25:
2026  /* <idx> 1 25 callothersubr pop */
2027  /* ==> push BuildCharArray[cvi( idx )] */
2028  /* onto T1 stack */
2029  {
2030  CF2_Int idx;
2031  PS_Blend blend = decoder->blend;
2032 
2033 
2034  if ( arg_cnt != 1 || !blend )
2035  goto Unexpected_OtherSubr;
2036 
2037  idx = cf2_stack_popInt( opStack );
2038 
2039  if ( idx < 0 ||
2040  (FT_UInt)idx >= decoder->len_buildchar )
2041  goto Unexpected_OtherSubr;
2042 
2043  cf2_stack_pushFixed( opStack,
2044  decoder->buildchar[idx] );
2045  known_othersubr_result_cnt = 1;
2046  }
2047  break;
2048 
2049 #if 0
2050  case 26:
2051  /* <val> mark <idx> */
2052  /* ==> set BuildCharArray[cvi( <idx> )] = <val>, */
2053  /* leave mark on T1 stack */
2054  /* <val> <idx> */
2055  /* ==> set BuildCharArray[cvi( <idx> )] = <val> */
2056  XXX which routine has left its mark on the
2057  XXX (PostScript) stack?;
2058  break;
2059 #endif
2060 
2061  case 27:
2062  /* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */
2063  /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */
2064  /* otherwise push <res2> */
2065  {
2067  CF2_F16Dot16 arg2;
2068  CF2_F16Dot16 cond1;
2069  CF2_F16Dot16 cond2;
2070 
2071 
2072  if ( arg_cnt != 4 )
2073  goto Unexpected_OtherSubr;
2074 
2075  cond2 = cf2_stack_popFixed( opStack );
2076  cond1 = cf2_stack_popFixed( opStack );
2077  arg2 = cf2_stack_popFixed( opStack );
2078  arg1 = cf2_stack_popFixed( opStack );
2079 
2080  cf2_stack_pushFixed( opStack,
2081  cond1 <= cond2 ? arg1 : arg2 );
2082  known_othersubr_result_cnt = 1;
2083  }
2084  break;
2085 
2086  case 28:
2087  /* 0 28 callothersubr pop */
2088  /* ==> push random value from interval [0, 1) */
2089  /* onto stack */
2090  {
2091  CF2_F16Dot16 r;
2092 
2093 
2094  if ( arg_cnt != 0 )
2095  goto Unexpected_OtherSubr;
2096 
2097  /* only use the lower 16 bits of `random' */
2098  /* to generate a number in the range (0;1] */
2099  r = (CF2_F16Dot16)
2100  ( ( decoder->current_subfont->random & 0xFFFF ) + 1 );
2101 
2102  decoder->current_subfont->random =
2103  cff_random( decoder->current_subfont->random );
2104 
2105  cf2_stack_pushFixed( opStack, r );
2106  known_othersubr_result_cnt = 1;
2107  }
2108  break;
2109 
2110  default:
2111  if ( arg_cnt >= 0 && subr_no >= 0 )
2112  {
2113  FT_Int i;
2114 
2115 
2116  FT_ERROR((
2117  "cf2_interpT2CharString (Type 1 mode):"
2118  " unknown othersubr [%d %d], wish me luck\n",
2119  arg_cnt, subr_no ));
2120 
2121  /* store the unused args */
2122  /* for this unhandled OtherSubr */
2123 
2124  if ( arg_cnt > PS_STORAGE_SIZE )
2125  arg_cnt = PS_STORAGE_SIZE;
2126  result_cnt = arg_cnt;
2127 
2128  for ( i = 1; i <= arg_cnt; i++ )
2129  results[result_cnt - i] =
2130  cf2_stack_popFixed( opStack );
2131 
2132  break;
2133  }
2134  /* fall through */
2135 
2136  Unexpected_OtherSubr:
2137  FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
2138  " invalid othersubr [%d %d]\n",
2139  arg_cnt, subr_no ));
2140  lastError = FT_THROW( Invalid_Glyph_Format );
2141  goto exit;
2142  }
2143  }
2144  continue; /* do not clear the stack */
2145 
2146  case cf2_escPOP:
2147  if ( !font->isT1 )
2148  FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
2149  else
2150  {
2151  FT_TRACE4(( " pop" ));
2152 
2153  if ( known_othersubr_result_cnt > 0 )
2154  {
2155  known_othersubr_result_cnt--;
2156  /* ignore, we pushed the operands ourselves */
2157  continue;
2158  }
2159 
2160  if ( result_cnt == 0 )
2161  {
2162  FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
2163  " no more operands for othersubr\n" ));
2164  lastError = FT_THROW( Invalid_Glyph_Format );
2165  goto exit;
2166  }
2167 
2168  result_cnt--;
2169  cf2_stack_pushFixed( opStack, results[result_cnt] );
2170  }
2171  continue; /* do not clear the stack */
2172 
2173  case cf2_escDROP:
2174  FT_TRACE4(( " drop\n" ));
2175 
2176  (void)cf2_stack_popFixed( opStack );
2177  continue; /* do not clear the stack */
2178 
2179  case cf2_escPUT:
2180  {
2181  CF2_F16Dot16 val;
2182  CF2_Int idx;
2183 
2184 
2185  FT_TRACE4(( " put\n" ));
2186 
2187  idx = cf2_stack_popInt( opStack );
2188  val = cf2_stack_popFixed( opStack );
2189 
2190  if ( idx >= 0 && idx < CF2_STORAGE_SIZE )
2191  storage[idx] = val;
2192  }
2193  continue; /* do not clear the stack */
2194 
2195  case cf2_escGET:
2196  {
2197  CF2_Int idx;
2198 
2199 
2200  FT_TRACE4(( " get\n" ));
2201 
2202  idx = cf2_stack_popInt( opStack );
2203 
2204  if ( idx >= 0 && idx < CF2_STORAGE_SIZE )
2205  cf2_stack_pushFixed( opStack, storage[idx] );
2206  }
2207  continue; /* do not clear the stack */
2208 
2209  case cf2_escIFELSE:
2210  {
2212  CF2_F16Dot16 arg2;
2213  CF2_F16Dot16 cond1;
2214  CF2_F16Dot16 cond2;
2215 
2216 
2217  FT_TRACE4(( " ifelse\n" ));
2218 
2219  cond2 = cf2_stack_popFixed( opStack );
2220  cond1 = cf2_stack_popFixed( opStack );
2221  arg2 = cf2_stack_popFixed( opStack );
2222  arg1 = cf2_stack_popFixed( opStack );
2223 
2224  cf2_stack_pushFixed( opStack,
2225  cond1 <= cond2 ? arg1 : arg2 );
2226  }
2227  continue; /* do not clear the stack */
2228 
2229  case cf2_escRANDOM: /* in spec */
2230  {
2231  CF2_F16Dot16 r;
2232 
2233 
2234  FT_TRACE4(( " random\n" ));
2235 
2236  /* only use the lower 16 bits of `random' */
2237  /* to generate a number in the range (0;1] */
2238  r = (CF2_F16Dot16)
2239  ( ( decoder->current_subfont->random & 0xFFFF ) + 1 );
2240 
2241  decoder->current_subfont->random =
2242  cff_random( decoder->current_subfont->random );
2243 
2244  cf2_stack_pushFixed( opStack, r );
2245  }
2246  continue; /* do not clear the stack */
2247 
2248  case cf2_escMUL:
2249  {
2250  CF2_F16Dot16 factor1;
2251  CF2_F16Dot16 factor2;
2252 
2253 
2254  FT_TRACE4(( " mul\n" ));
2255 
2256  factor2 = cf2_stack_popFixed( opStack );
2257  factor1 = cf2_stack_popFixed( opStack );
2258 
2259  cf2_stack_pushFixed( opStack,
2260  FT_MulFix( factor1, factor2 ) );
2261  }
2262  continue; /* do not clear the stack */
2263 
2264  case cf2_escSQRT:
2265  {
2266  CF2_F16Dot16 arg;
2267 
2268 
2269  FT_TRACE4(( " sqrt\n" ));
2270 
2271  arg = cf2_stack_popFixed( opStack );
2272  if ( arg > 0 )
2273  {
2274  /* use a start value that doesn't make */
2275  /* the algorithm's addition overflow */
2276  FT_Fixed root = arg < 10 ? arg : arg >> 1;
2277  FT_Fixed new_root;
2278 
2279 
2280  /* Babylonian method */
2281  for (;;)
2282  {
2283  new_root = ( root + FT_DivFix( arg, root ) + 1 ) >> 1;
2284  if ( new_root == root )
2285  break;
2286  root = new_root;
2287  }
2288  arg = new_root;
2289  }
2290  else
2291  arg = 0;
2292 
2293  cf2_stack_pushFixed( opStack, arg );
2294  }
2295  continue; /* do not clear the stack */
2296 
2297  case cf2_escDUP:
2298  {
2299  CF2_F16Dot16 arg;
2300 
2301 
2302  FT_TRACE4(( " dup\n" ));
2303 
2304  arg = cf2_stack_popFixed( opStack );
2305 
2306  cf2_stack_pushFixed( opStack, arg );
2307  cf2_stack_pushFixed( opStack, arg );
2308  }
2309  continue; /* do not clear the stack */
2310 
2311  case cf2_escEXCH:
2312  {
2314  CF2_F16Dot16 arg2;
2315 
2316 
2317  FT_TRACE4(( " exch\n" ));
2318 
2319  arg2 = cf2_stack_popFixed( opStack );
2320  arg1 = cf2_stack_popFixed( opStack );
2321 
2322  cf2_stack_pushFixed( opStack, arg2 );
2323  cf2_stack_pushFixed( opStack, arg1 );
2324  }
2325  continue; /* do not clear the stack */
2326 
2327  case cf2_escINDEX:
2328  {
2329  CF2_Int idx;
2330  CF2_UInt size;
2331 
2332 
2333  FT_TRACE4(( " index\n" ));
2334 
2335  idx = cf2_stack_popInt( opStack );
2336  size = cf2_stack_count( opStack );
2337 
2338  if ( size > 0 )
2339  {
2340  /* for `cf2_stack_getReal', */
2341  /* index 0 is bottom of stack */
2342  CF2_UInt gr_idx;
2343 
2344 
2345  if ( idx < 0 )
2346  gr_idx = size - 1;
2347  else if ( (CF2_UInt)idx >= size )
2348  gr_idx = 0;
2349  else
2350  gr_idx = size - 1 - (CF2_UInt)idx;
2351 
2352  cf2_stack_pushFixed( opStack,
2353  cf2_stack_getReal( opStack,
2354  gr_idx ) );
2355  }
2356  }
2357  continue; /* do not clear the stack */
2358 
2359  case cf2_escROLL:
2360  {
2361  CF2_Int idx;
2362  CF2_Int count;
2363 
2364 
2365  FT_TRACE4(( " roll\n" ));
2366 
2367  idx = cf2_stack_popInt( opStack );
2368  count = cf2_stack_popInt( opStack );
2369 
2370  cf2_stack_roll( opStack, count, idx );
2371  }
2372  continue; /* do not clear the stack */
2373 
2374  case cf2_escSETCURRENTPT:
2375  if ( !font->isT1 )
2376  FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
2377  else
2378  {
2379  FT_TRACE4(( " setcurrentpoint" ));
2380 
2381  if ( !initial_map_ready )
2382  break;
2383 
2384  /* From the T1 specification, section 6.4: */
2385  /* */
2386  /* The setcurrentpoint command is used only in */
2387  /* conjunction with results from OtherSubrs */
2388  /* procedures. */
2389 
2390  /* known_othersubr_result_cnt != 0 is already handled */
2391  /* above. */
2392 
2393  /* Note, however, that both Ghostscript and Adobe */
2394  /* Distiller handle this situation by silently */
2395  /* ignoring the inappropriate `setcurrentpoint' */
2396  /* instruction. So we do the same. */
2397 #if 0
2398 
2399  if ( decoder->flex_state != 1 )
2400  {
2401  FT_ERROR(( "cf2_interpT2CharString:"
2402  " unexpected `setcurrentpoint'\n" ));
2403  goto Syntax_Error;
2404  }
2405  else
2406  ...
2407 #endif
2408 
2409  curY = cf2_stack_popFixed( opStack );
2410  curX = cf2_stack_popFixed( opStack );
2411 
2412  decoder->flex_state = 0;
2413  }
2414  break;
2415 
2416  } /* end of 2nd switch checking op2 */
2417  }
2418  }
2419  } /* end of 1st switch checking op2 */
2420  } /* case cf2_cmdESC */
2421 
2422  break;
2423 
2424  case cf2_cmdHSBW:
2425  if ( !font->isT1 )
2426  FT_TRACE4(( " unknown op (%d)\n", op1 ));
2427  else
2428  {
2429  CF2_Fixed lsb_x;
2430  PS_Builder* builder;
2431 
2432 
2433  FT_TRACE4(( " hsbw\n" ));
2434 
2435  builder = &decoder->builder;
2436 
2437  builder->advance->x = cf2_stack_popFixed( opStack );
2438  builder->advance->y = 0;
2439 
2440  lsb_x = cf2_stack_popFixed( opStack );
2441 
2442  builder->left_bearing->x = ADD_INT32( builder->left_bearing->x,
2443  lsb_x );
2444 
2445  haveWidth = TRUE;
2446 
2447  /* the `metrics_only' indicates that we only want to compute */
2448  /* the glyph's metrics (lsb + advance width), not load the */
2449  /* rest of it; so exit immediately */
2450  if ( builder->metrics_only )
2451  goto exit;
2452 
2453  if ( initial_map_ready )
2454  curX = ADD_INT32( curX, lsb_x );
2455  }
2456  break;
2457 
2458  case cf2_cmdENDCHAR:
2459  FT_TRACE4(( " endchar\n" ));
2460 
2461  if ( font->isT1 && !initial_map_ready )
2462  {
2463  FT_TRACE5(( "cf2_interpT2CharString (Type 1 mode): "
2464  "Build initial hintmap, rewinding...\n" ));
2465 
2466  /* trigger initial hintmap build */
2467  cf2_glyphpath_moveTo( &glyphPath, curX, curY );
2468 
2469  initial_map_ready = TRUE;
2470 
2471  /* change hints routine - clear for rewind */
2472  cf2_arrstack_clear( &vStemHintArray );
2473  cf2_arrstack_clear( &hStemHintArray );
2474 
2475  cf2_hintmask_init( &hintMask, error );
2476  hintMask.isValid = FALSE;
2477  hintMask.isNew = TRUE;
2478 
2479  /* rewind charstring */
2480  /* some charstrings use endchar from a final subroutine call */
2481  /* without returning, detect these and exit to the top level */
2482  /* charstring */
2483  while ( charstringIndex > 0 )
2484  {
2485  FT_TRACE4(( " return (leaving level %d)\n", charstringIndex ));
2486 
2487  /* restore position in previous charstring */
2488  charstring = (CF2_Buffer)
2490  &subrStack,
2491  (CF2_UInt)--charstringIndex );
2492  }
2493  charstring->ptr = charstring->start;
2494 
2495  break;
2496  }
2497 
2498  if ( cf2_stack_count( opStack ) == 1 ||
2499  cf2_stack_count( opStack ) == 5 )
2500  {
2501  if ( !haveWidth )
2502  *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ),
2503  nominalWidthX );
2504  }
2505 
2506  /* width is defined or default after this */
2507  haveWidth = TRUE;
2508 
2509  if ( decoder->width_only )
2510  goto exit;
2511 
2512  /* close path if still open */
2513  cf2_glyphpath_closeOpenPath( &glyphPath );
2514 
2515  /* disable seac for CFF2 and Type1 */
2516  /* (charstring ending with args on stack) */
2517  if ( !font->isCFF2 && !font->isT1 && cf2_stack_count( opStack ) > 1 )
2518  {
2519  /* must be either 4 or 5 -- */
2520  /* this is a (deprecated) implied `seac' operator */
2521 
2522  CF2_Int achar;
2523  CF2_Int bchar;
2524  CF2_BufferRec component;
2525  CF2_Fixed dummyWidth; /* ignore component width */
2526  FT_Error error2;
2527 
2528 
2529  if ( doingSeac )
2530  {
2531  lastError = FT_THROW( Invalid_Glyph_Format );
2532  goto exit; /* nested seac */
2533  }
2534 
2535  achar = cf2_stack_popInt( opStack );
2536  bchar = cf2_stack_popInt( opStack );
2537 
2538  curY = cf2_stack_popFixed( opStack );
2539  curX = cf2_stack_popFixed( opStack );
2540 
2541  error2 = cf2_getSeacComponent( decoder, achar, &component );
2542  if ( error2 )
2543  {
2544  lastError = error2; /* pass FreeType error through */
2545  goto exit;
2546  }
2548  &component,
2549  callbacks,
2550  translation,
2551  TRUE,
2552  curX,
2553  curY,
2554  &dummyWidth );
2555  cf2_freeSeacComponent( decoder, &component );
2556 
2557  error2 = cf2_getSeacComponent( decoder, bchar, &component );
2558  if ( error2 )
2559  {
2560  lastError = error2; /* pass FreeType error through */
2561  goto exit;
2562  }
2564  &component,
2565  callbacks,
2566  translation,
2567  TRUE,
2568  0,
2569  0,
2570  &dummyWidth );
2571  cf2_freeSeacComponent( decoder, &component );
2572  }
2573  goto exit;
2574 
2575  case cf2_cmdCNTRMASK:
2576  case cf2_cmdHINTMASK:
2577  /* the final \n in the tracing message gets added in */
2578  /* `cf2_hintmask_read' (which also traces the mask bytes) */
2579  FT_TRACE4(( "%s", op1 == cf2_cmdCNTRMASK ? " cntrmask" : " hintmask" ));
2580 
2581  /* never add hints after the mask is computed */
2582  if ( cf2_stack_count( opStack ) > 1 &&
2583  cf2_hintmask_isValid( &hintMask ) )
2584  {
2585  FT_TRACE4(( "cf2_interpT2CharString: invalid hint mask\n" ));
2586  break;
2587  }
2588 
2589  /* if there are arguments on the stack, there this is an */
2590  /* implied cf2_cmdVSTEMHM */
2591  cf2_doStems( font,
2592  opStack,
2593  &vStemHintArray,
2594  width,
2595  &haveWidth,
2596  0 );
2597 
2598  if ( decoder->width_only )
2599  goto exit;
2600 
2601  if ( op1 == cf2_cmdHINTMASK )
2602  {
2603  /* consume the hint mask bytes which follow the operator */
2604  cf2_hintmask_read( &hintMask,
2605  charstring,
2606  cf2_arrstack_size( &hStemHintArray ) +
2607  cf2_arrstack_size( &vStemHintArray ) );
2608  }
2609  else
2610  {
2611  /*
2612  * Consume the counter mask bytes which follow the operator:
2613  * Build a temporary hint map, just to place and lock those
2614  * stems participating in the counter mask. These are most
2615  * likely the dominant hstems, and are grouped together in a
2616  * few counter groups, not necessarily in correspondence
2617  * with the hint groups. This reduces the chances of
2618  * conflicts between hstems that are initially placed in
2619  * separate hint groups and then brought together. The
2620  * positions are copied back to `hStemHintArray', so we can
2621  * discard `counterMask' and `counterHintMap'.
2622  *
2623  */
2624  CF2_HintMapRec counterHintMap;
2625  CF2_HintMaskRec counterMask;
2626 
2627 
2628  cf2_hintmap_init( &counterHintMap,
2629  font,
2630  &glyphPath.initialHintMap,
2631  &glyphPath.hintMoves,
2632  scaleY );
2633  cf2_hintmask_init( &counterMask, error );
2634 
2635  cf2_hintmask_read( &counterMask,
2636  charstring,
2637  cf2_arrstack_size( &hStemHintArray ) +
2638  cf2_arrstack_size( &vStemHintArray ) );
2639  cf2_hintmap_build( &counterHintMap,
2640  &hStemHintArray,
2641  &vStemHintArray,
2642  &counterMask,
2643  0,
2644  FALSE );
2645  }
2646  break;
2647 
2648  case cf2_cmdRMOVETO:
2649  FT_TRACE4(( " rmoveto\n" ));
2650 
2651  if ( font->isT1 && !decoder->flex_state && !haveWidth )
2652  FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
2653  " No width. Use hsbw/sbw as first op\n" ));
2654 
2655  if ( cf2_stack_count( opStack ) > 2 && !haveWidth )
2656  *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ),
2657  nominalWidthX );
2658 
2659  /* width is defined or default after this */
2660  haveWidth = TRUE;
2661 
2662  if ( decoder->width_only )
2663  goto exit;
2664 
2665  curY = ADD_INT32( curY, cf2_stack_popFixed( opStack ) );
2666  curX = ADD_INT32( curX, cf2_stack_popFixed( opStack ) );
2667 
2668  if ( !decoder->flex_state )
2669  cf2_glyphpath_moveTo( &glyphPath, curX, curY );
2670 
2671  break;
2672 
2673  case cf2_cmdHMOVETO:
2674  FT_TRACE4(( " hmoveto\n" ));
2675 
2676  if ( font->isT1 && !decoder->flex_state && !haveWidth )
2677  FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
2678  " No width. Use hsbw/sbw as first op\n" ));
2679 
2680  if ( cf2_stack_count( opStack ) > 1 && !haveWidth )
2681  *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ),
2682  nominalWidthX );
2683 
2684  /* width is defined or default after this */
2685  haveWidth = TRUE;
2686 
2687  if ( decoder->width_only )
2688  goto exit;
2689 
2690  curX = ADD_INT32( curX, cf2_stack_popFixed( opStack ) );
2691 
2692  if ( !decoder->flex_state )
2693  cf2_glyphpath_moveTo( &glyphPath, curX, curY );
2694 
2695  break;
2696 
2697  case cf2_cmdRLINECURVE:
2698  {
2699  CF2_UInt count = cf2_stack_count( opStack );
2700  CF2_UInt idx = 0;
2701 
2702 
2703  FT_TRACE4(( " rlinecurve\n" ));
2704 
2705  while ( idx + 6 < count )
2706  {
2707  curX = ADD_INT32( curX, cf2_stack_getReal( opStack,
2708  idx + 0 ) );
2709  curY = ADD_INT32( curY, cf2_stack_getReal( opStack,
2710  idx + 1 ) );
2711 
2712  cf2_glyphpath_lineTo( &glyphPath, curX, curY );
2713  idx += 2;
2714  }
2715 
2716  while ( idx < count )
2717  {
2718  CF2_Fixed x1, y1, x2, y2, x3, y3;
2719 
2720 
2721  x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX );
2722  y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), curY );
2723  x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), x1 );
2724  y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y1 );
2725  x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), x2 );
2726  y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 5 ), y2 );
2727 
2728  cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
2729 
2730  curX = x3;
2731  curY = y3;
2732  idx += 6;
2733  }
2734 
2735  cf2_stack_clear( opStack );
2736  }
2737  continue; /* no need to clear stack again */
2738 
2739  case cf2_cmdVVCURVETO:
2740  {
2741  CF2_UInt count, count1 = cf2_stack_count( opStack );
2742  CF2_UInt idx = 0;
2743 
2744 
2745  /* if `cf2_stack_count' isn't of the form 4n or 4n+1, */
2746  /* we enforce it by clearing the second bit */
2747  /* (and sorting the stack indexing to suit) */
2748  count = count1 & ~2U;
2749  idx += count1 - count;
2750 
2751  FT_TRACE4(( " vvcurveto\n" ));
2752 
2753  while ( idx < count )
2754  {
2755  CF2_Fixed x1, y1, x2, y2, x3, y3;
2756 
2757 
2758  if ( ( count - idx ) & 1 )
2759  {
2760  x1 = ADD_INT32( cf2_stack_getReal( opStack, idx ), curX );
2761 
2762  idx++;
2763  }
2764  else
2765  x1 = curX;
2766 
2767  y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curY );
2768  x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 );
2769  y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 );
2770  x3 = x2;
2771  y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y2 );
2772 
2773  cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
2774 
2775  curX = x3;
2776  curY = y3;
2777  idx += 4;
2778  }
2779 
2780  cf2_stack_clear( opStack );
2781  }
2782  continue; /* no need to clear stack again */
2783 
2784  case cf2_cmdHHCURVETO:
2785  {
2786  CF2_UInt count, count1 = cf2_stack_count( opStack );
2787  CF2_UInt idx = 0;
2788 
2789 
2790  /* if `cf2_stack_count' isn't of the form 4n or 4n+1, */
2791  /* we enforce it by clearing the second bit */
2792  /* (and sorting the stack indexing to suit) */
2793  count = count1 & ~2U;
2794  idx += count1 - count;
2795 
2796  FT_TRACE4(( " hhcurveto\n" ));
2797 
2798  while ( idx < count )
2799  {
2800  CF2_Fixed x1, y1, x2, y2, x3, y3;
2801 
2802 
2803  if ( ( count - idx ) & 1 )
2804  {
2805  y1 = ADD_INT32( cf2_stack_getReal( opStack, idx ), curY );
2806 
2807  idx++;
2808  }
2809  else
2810  y1 = curY;
2811 
2812  x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX );
2813  x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 );
2814  y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 );
2815  x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), x2 );
2816  y3 = y2;
2817 
2818  cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
2819 
2820  curX = x3;
2821  curY = y3;
2822  idx += 4;
2823  }
2824 
2825  cf2_stack_clear( opStack );
2826  }
2827  continue; /* no need to clear stack again */
2828 
2829  case cf2_cmdVHCURVETO:
2830  case cf2_cmdHVCURVETO:
2831  {
2832  CF2_UInt count, count1 = cf2_stack_count( opStack );
2833  CF2_UInt idx = 0;
2834 
2835  FT_Bool alternate = FT_BOOL( op1 == cf2_cmdHVCURVETO );
2836 
2837 
2838  /* if `cf2_stack_count' isn't of the form 8n, 8n+1, */
2839  /* 8n+4, or 8n+5, we enforce it by clearing the */
2840  /* second bit */
2841  /* (and sorting the stack indexing to suit) */
2842  count = count1 & ~2U;
2843  idx += count1 - count;
2844 
2845  FT_TRACE4(( "%s\n", alternate ? " hvcurveto" : " vhcurveto" ));
2846 
2847  while ( idx < count )
2848  {
2849  CF2_Fixed x1, x2, x3, y1, y2, y3;
2850 
2851 
2852  if ( alternate )
2853  {
2854  x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX );
2855  y1 = curY;
2856  x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 );
2857  y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 );
2858  y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y2 );
2859 
2860  if ( count - idx == 5 )
2861  {
2862  x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), x2 );
2863 
2864  idx++;
2865  }
2866  else
2867  x3 = x2;
2868 
2869  alternate = FALSE;
2870  }
2871  else
2872  {
2873  x1 = curX;
2874  y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curY );
2875  x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 );
2876  y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 );
2877  x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), x2 );
2878 
2879  if ( count - idx == 5 )
2880  {
2881  y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), y2 );
2882 
2883  idx++;
2884  }
2885  else
2886  y3 = y2;
2887 
2888  alternate = TRUE;
2889  }
2890 
2891  cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
2892 
2893  curX = x3;
2894  curY = y3;
2895  idx += 4;
2896  }
2897 
2898  cf2_stack_clear( opStack );
2899  }
2900  continue; /* no need to clear stack again */
2901 
2902  case cf2_cmdEXTENDEDNMBR:
2903  {
2904  CF2_Int v;
2905 
2906  CF2_Int byte1 = cf2_buf_readByte( charstring );
2907  CF2_Int byte2 = cf2_buf_readByte( charstring );
2908 
2909 
2910  v = (FT_Short)( ( byte1 << 8 ) |
2911  byte2 );
2912 
2913  FT_TRACE4(( " %d", v ));
2914 
2915  cf2_stack_pushInt( opStack, v );
2916  }
2917  continue;
2918 
2919  default:
2920  /* numbers */
2921  {
2922  if ( /* op1 >= 32 && */ op1 <= 246 )
2923  {
2924  CF2_Int v;
2925 
2926 
2927  v = op1 - 139;
2928 
2929  FT_TRACE4(( " %d", v ));
2930 
2931  /* -107 .. 107 */
2932  cf2_stack_pushInt( opStack, v );
2933  }
2934 
2935  else if ( /* op1 >= 247 && */ op1 <= 250 )
2936  {
2937  CF2_Int v;
2938 
2939 
2940  v = op1;
2941  v -= 247;
2942  v *= 256;
2943  v += cf2_buf_readByte( charstring );
2944  v += 108;
2945 
2946  FT_TRACE4(( " %d", v ));
2947 
2948  /* 108 .. 1131 */
2949  cf2_stack_pushInt( opStack, v );
2950  }
2951 
2952  else if ( /* op1 >= 251 && */ op1 <= 254 )
2953  {
2954  CF2_Int v;
2955 
2956 
2957  v = op1;
2958  v -= 251;
2959  v *= 256;
2960  v += cf2_buf_readByte( charstring );
2961  v = -v - 108;
2962 
2963  FT_TRACE4(( " %d", v ));
2964 
2965  /* -1131 .. -108 */
2966  cf2_stack_pushInt( opStack, v );
2967  }
2968 
2969  else /* op1 == 255 */
2970  {
2971  CF2_Fixed v;
2972 
2973  FT_UInt32 byte1 = (FT_UInt32)cf2_buf_readByte( charstring );
2974  FT_UInt32 byte2 = (FT_UInt32)cf2_buf_readByte( charstring );
2975  FT_UInt32 byte3 = (FT_UInt32)cf2_buf_readByte( charstring );
2976  FT_UInt32 byte4 = (FT_UInt32)cf2_buf_readByte( charstring );
2977 
2978 
2979  v = (CF2_Fixed)( ( byte1 << 24 ) |
2980  ( byte2 << 16 ) |
2981  ( byte3 << 8 ) |
2982  byte4 );
2983 
2984  /*
2985  * For Type 1:
2986  *
2987  * According to the specification, values > 32000 or < -32000
2988  * must be followed by a `div' operator to make the result be
2989  * in the range [-32000;32000]. We expect that the second
2990  * argument of `div' is not a large number. Additionally, we
2991  * don't handle stuff like `<large1> <large2> <num> div <num>
2992  * div' or <large1> <large2> <num> div div'. This is probably
2993  * not allowed anyway.
2994  *
2995  * <large> <num> <num>+ div is not checked but should not be
2996  * allowed as the large value remains untouched.
2997  *
2998  */
2999  if ( font->isT1 )
3000  {
3001  if ( v > 32000 || v < -32000 )
3002  {
3003  if ( large_int )
3004  FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
3005  " no `div' after large integer\n" ));
3006  else
3007  large_int = TRUE;
3008  }
3009 
3010  FT_TRACE4(( " %d", v ));
3011 
3012  cf2_stack_pushInt( opStack, (CF2_Int)v );
3013  }
3014  else
3015  {
3016  FT_TRACE4(( " %.5fF", v / 65536.0 ));
3017 
3018  cf2_stack_pushFixed( opStack, v );
3019  }
3020  }
3021  }
3022  continue; /* don't clear stack */
3023 
3024  } /* end of switch statement checking `op1' */
3025 
3026  cf2_stack_clear( opStack );
3027 
3028  } /* end of main interpreter loop */
3029 
3030  /* we get here if the charstring ends without cf2_cmdENDCHAR */
3031  FT_TRACE4(( "cf2_interpT2CharString:"
3032  " charstring ends without ENDCHAR\n" ));
3033 
3034  exit:
3035  /* check whether last error seen is also the first one */
3036  cf2_setError( error, lastError );
3037 
3038  if ( *error )
3039  FT_TRACE4(( "charstring error %d\n", *error ));
3040 
3041  /* free resources from objects we've used */
3042  cf2_glyphpath_finalize( &glyphPath );
3043  cf2_arrstack_finalize( &vStemHintArray );
3044  cf2_arrstack_finalize( &hStemHintArray );
3045  cf2_arrstack_finalize( &subrStack );
3046  cf2_stack_free( opStack );
3047 
3048  FT_TRACE4(( "\n" ));
3049 
3050  return;
3051  }
3052 
3053 
3054 /* END */
#define the
Definition: aptex-macros.h:490
#define width(a)
Definition: aptex-macros.h:198
#define mark
Definition: aptex-macros.h:374
#define x3
#define count(a)
Definition: aptex-macros.h:781
#define advance
Definition: aptex-macros.h:464
#define y3
@ FALSE
Definition: dd.h:101
@ TRUE
Definition: dd.h:102
int v
Definition: dviconv.c:10
char * temp
Definition: dvidvi.c:137
#define error(a)
Definition: dviinfo.c:48
static void
Definition: fpif.c:118
#define v0
#define v1
#define v2
int base
Definition: gsftopk.c:1502
#define T1_MAX_SUBRS_CALLS
Definition: ftoption.h:756
#define ft_memcpy
Definition: ftstdlib.h:82
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:607
#define FT_SUBGLYPH_FLAG_USE_MY_METRICS
Definition: freetype.h:3960
struct FT_GlyphSlotRec_ * FT_GlyphSlot
Definition: freetype.h:532
#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES
Definition: freetype.h:3955
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:508
cannot open resource broken file module version is too low unimplemented feature broken offset within table missing module invalid glyph index unsupported glyph image format invalid outline too many hints invalid object handle invalid module handle invalid size handle invalid charmap handle invalid stream handle too many extensions unlisted object invalid stream seek invalid stream read invalid frame operation invalid frame read raster corrupted negative height while rastering invalid opcode stack overflow bad argument invalid reference found ENDF opcode in execution stream invalid code range too many function definitions SFNT font table missing name table missing horizontal PostScript(post) table missing" ) FT_ERRORDEF_( Invalid_Horiz_Metrics
@ FT_GLYPH_FORMAT_COMPOSITE
Definition: ftimage.h:747
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:57
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 char FT_Byte
Definition: fttypes.h:154
signed long FT_Fixed
Definition: fttypes.h:287
int FT_Error
Definition: fttypes.h:299
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_LOCAL_DEF(x)
#define FIXED_TO_INT(x)
Definition: ftcalc.h:450
#define SUB_INT32(a, b)
Definition: ftcalc.h:483
#define ADD_INT32(a, b)
Definition: ftcalc.h:481
#define FT_ASSERT(condition)
Definition: ftdebug.h:241
#define FT_ERROR(varformat)
Definition: ftdebug.h:211
#define FT_TRACE5(varformat)
Definition: ftdebug.h:192
#define FT_THROW(e)
Definition: ftdebug.h:243
#define FT_TRACE4(varformat)
Definition: ftdebug.h:191
FT_GlyphLoader_Prepare(FT_GlyphLoader loader)
Definition: ftgloadr.c:324
FT_GlyphLoader_CheckSubGlyphs(FT_GlyphLoader loader, FT_UInt n_subs)
Definition: ftgloadr.c:293
size_t * ft_hash_num_lookup(FT_Int num, FT_Hash hash)
Definition: fthash.c:326
#define FT_ZERO(p)
Definition: ftmemory.h:246
#define NULL
Definition: ftobjs.h:61
#define FT_ABS(a)
Definition: ftobjs.h:73
struct T1_FaceRec_ * T1_Face
Definition: t1types.h:198
small capitals from c petite p scientific i
Definition: afcover.h:80
sizeof(AF_ModuleRec)
return FT_Err_Ok
Definition: ftbbox.c:526
FT_UInt idx
Definition: cffcmap.c:135
FT_Face face
Definition: cffdrivr.c:659
#define const
Definition: ftzconf.h:91
void exit()
cf2_arrstack_getPointer(const CF2_ArrStack arrstack, size_t idx)
Definition: psarrst.c:187
cf2_arrstack_setCount(CF2_ArrStack arrstack, size_t numElements)
Definition: psarrst.c:140
cf2_arrstack_push(CF2_ArrStack arrstack, const void *ptr)
Definition: psarrst.c:212
cf2_arrstack_finalize(CF2_ArrStack arrstack)
Definition: psarrst.c:76
cf2_arrstack_init(CF2_ArrStack arrstack, FT_Memory memory, FT_Error *error, size_t sizeItem)
Definition: psarrst.c:56
cf2_arrstack_getBuffer(const CF2_ArrStack arrstack)
Definition: psarrst.c:177
cf2_arrstack_clear(CF2_ArrStack arrstack)
Definition: psarrst.c:158
cf2_arrstack_size(const CF2_ArrStack arrstack)
Definition: psarrst.c:168
FT_BEGIN_HEADER struct CF2_ArrStackRec_ * CF2_ArrStack
FT_BEGIN_HEADER struct CF2_ArrStackRec_ CF2_ArrStackRec
cf2_setError(FT_Error *error, FT_Error value)
Definition: pserror.c:44
#define CF2_SET_ERROR(error, e)
Definition: pserror.h:110
#define CF2_Fixed
Definition: psfixed.h:48
#define CF2_FIXED_MAX
Definition: psfixed.h:52
#define cf2_fixedAbs(x)
Definition: psfixed.h:68
#define CF2_OPERAND_STACK_SIZE
Definition: psfont.h:52
#define CF2_MAX_SUBR
Definition: psfont.h:53
#define CF2_STORAGE_SIZE
Definition: psfont.h:59
cf2_freeSeacComponent(PS_Decoder *decoder, CF2_Buffer buf)
Definition: psft.c:708
cf2_freeT1SeacComponent(PS_Decoder *decoder, CF2_Buffer buf)
Definition: psft.c:767
cf2_initGlobalRegionBuffer(PS_Decoder *decoder, FT_Fast subrNum, CF2_Buffer buf)
Definition: psft.c:632
cf2_getNominalWidthX(PS_Decoder *decoder)
Definition: psft.c:860
cf2_getSeacComponent(PS_Decoder *decoder, FT_Fast code, CF2_Buffer buf)
Definition: psft.c:660
cf2_initLocalRegionBuffer(PS_Decoder *decoder, FT_Fast subrNum, CF2_Buffer buf)
Definition: psft.c:798
cf2_getT1SeacComponent(PS_Decoder *decoder, FT_UInt glyph_index, CF2_Buffer buf)
Definition: psft.c:721
cf2_getMaxstack(PS_Decoder *decoder)
Definition: psft.c:468
cf2_getDefaultWidthX(PS_Decoder *decoder)
Definition: psft.c:850
cf2_glyphpath_init(CF2_GlyphPath glyphpath, CF2_Font font, CF2_OutlineCallbacks callbacks, CF2_F16Dot16 scaleY, CF2_ArrStack hStemHintArray, CF2_ArrStack vStemHintArray, CF2_HintMask hintMask, CF2_F16Dot16 hintOriginY, const CF2_Blues blues, const FT_Vector *fractionalTranslation)
Definition: pshints.c:1080
cf2_glyphpath_moveTo(CF2_GlyphPath glyphpath, CF2_F16Dot16 x, CF2_F16Dot16 y)
Definition: pshints.c:1678
cf2_glyphpath_curveTo(CF2_GlyphPath glyphpath, CF2_F16Dot16 x1, CF2_F16Dot16 y1, CF2_F16Dot16 x2, CF2_F16Dot16 y2, CF2_F16Dot16 x3, CF2_F16Dot16 y3)
Definition: pshints.c:1814
cf2_glyphpath_finalize(CF2_GlyphPath glyphpath)
Definition: pshints.c:1151
cf2_glyphpath_closeOpenPath(CF2_GlyphPath glyphpath)
Definition: pshints.c:1904
cf2_glyphpath_lineTo(CF2_GlyphPath glyphpath, CF2_F16Dot16 x, CF2_F16Dot16 y)
Definition: pshints.c:1708
cf2_hintmap_build(CF2_HintMap hintmap, CF2_ArrStack hStemHintArray, CF2_ArrStack vStemHintArray, CF2_HintMask hintMask, CF2_F16Dot16 hintOrigin, FT_Bool initialMap)
Definition: pshints.c:805
cf2_hintmap_init(CF2_HintMap hintmap, CF2_Font font, CF2_HintMap initialMap, CF2_ArrStack hintMoves, CF2_F16Dot16 scale)
Definition: pshints.c:274
@ CF2_MAX_HINTS
Definition: pshints.h:47
cf2_interpT2CharString(CF2_Font font, CF2_Buffer buf, CF2_OutlineCallbacks callbacks, const FT_Vector *translation, FT_Bool doingSeac, CF2_F16Dot16 curX, CF2_F16Dot16 curY, CF2_F16Dot16 *width)
Definition: psintrp.c:471
cf2_hintmask_isNew(const CF2_HintMask hintmask)
Definition: psintrp.c:83
@ cf2_escSBW
Definition: psintrp.c:244
@ cf2_escROLL
Definition: psintrp.c:267
@ cf2_escDUP
Definition: psintrp.c:264
@ cf2_escPOP
Definition: psintrp.c:254
@ cf2_escOR
Definition: psintrp.c:241
@ cf2_escEQ
Definition: psintrp.c:252
@ cf2_escRESERVED_19
Definition: psintrp.c:256
@ cf2_escINDEX
Definition: psintrp.c:266
@ cf2_escVSTEM3
Definition: psintrp.c:238
@ cf2_escRESERVED_13
Definition: psintrp.c:250
@ cf2_escFLEX1
Definition: psintrp.c:274
@ cf2_escRESERVED_8
Definition: psintrp.c:245
@ cf2_escHSTEM3
Definition: psintrp.c:239
@ cf2_escCALLOTHERSUBR
Definition: psintrp.c:253
@ cf2_escSETCURRENTPT
Definition: psintrp.c:270
@ cf2_escPUT
Definition: psintrp.c:257
@ cf2_escRESERVED_31
Definition: psintrp.c:268
@ cf2_escRANDOM
Definition: psintrp.c:260
@ cf2_escRESERVED_32
Definition: psintrp.c:269
@ cf2_escDIV
Definition: psintrp.c:249
@ cf2_escSUB
Definition: psintrp.c:248
@ cf2_escRESERVED_38
Definition: psintrp.c:275
@ cf2_escDROP
Definition: psintrp.c:255
@ cf2_escABS
Definition: psintrp.c:246
@ cf2_escSQRT
Definition: psintrp.c:263
@ cf2_escNEG
Definition: psintrp.c:251
@ cf2_escFLEX
Definition: psintrp.c:272
@ cf2_escSEAC
Definition: psintrp.c:243
@ cf2_escMUL
Definition: psintrp.c:261
@ cf2_escRESERVED_25
Definition: psintrp.c:262
@ cf2_escHFLEX
Definition: psintrp.c:271
@ cf2_escIFELSE
Definition: psintrp.c:259
@ cf2_escHFLEX1
Definition: psintrp.c:273
@ cf2_escDOTSECTION
Definition: psintrp.c:237
@ cf2_escAND
Definition: psintrp.c:240
@ cf2_escGET
Definition: psintrp.c:258
@ cf2_escADD
Definition: psintrp.c:247
@ cf2_escEXCH
Definition: psintrp.c:265
@ cf2_escNOT
Definition: psintrp.c:242
cf2_hintmask_getMaskPtr(CF2_HintMask hintmask)
Definition: psintrp.c:101
cf2_hintmask_setAll(CF2_HintMask hintmask, size_t bitCount)
Definition: psintrp.c:173
@ cf2_cmdVSTEMHM
Definition: psintrp.c:224
@ cf2_cmdRESERVED_2
Definition: psintrp.c:203
@ cf2_cmdVLINETO
Definition: psintrp.c:208
@ cf2_cmdHLINETO
Definition: psintrp.c:207
@ cf2_cmdBLEND
Definition: psintrp.c:217
@ cf2_cmdRLINETO
Definition: psintrp.c:206
@ cf2_cmdRETURN
Definition: psintrp.c:212
@ cf2_cmdENDCHAR
Definition: psintrp.c:215
@ cf2_cmdHVCURVETO
Definition: psintrp.c:232
@ cf2_cmdRCURVELINE
Definition: psintrp.c:225
@ cf2_cmdVMOVETO
Definition: psintrp.c:205
@ cf2_cmdCALLSUBR
Definition: psintrp.c:211
@ cf2_cmdHSTEMHM
Definition: psintrp.c:219
@ cf2_cmdHSTEM
Definition: psintrp.c:202
@ cf2_cmdEXTENDEDNMBR
Definition: psintrp.c:229
@ cf2_cmdRESERVED_17
Definition: psintrp.c:218
@ cf2_cmdHHCURVETO
Definition: psintrp.c:228
@ cf2_cmdVSTEM
Definition: psintrp.c:204
@ cf2_cmdRRCURVETO
Definition: psintrp.c:209
@ cf2_cmdRESERVED_0
Definition: psintrp.c:201
@ cf2_cmdRLINECURVE
Definition: psintrp.c:226
@ cf2_cmdVVCURVETO
Definition: psintrp.c:227
@ cf2_cmdVSINDEX
Definition: psintrp.c:216
@ cf2_cmdCLOSEPATH
Definition: psintrp.c:210
@ cf2_cmdRMOVETO
Definition: psintrp.c:222
@ cf2_cmdHINTMASK
Definition: psintrp.c:220
@ cf2_cmdCNTRMASK
Definition: psintrp.c:221
@ cf2_cmdESC
Definition: psintrp.c:213
@ cf2_cmdHMOVETO
Definition: psintrp.c:223
@ cf2_cmdVHCURVETO
Definition: psintrp.c:231
@ cf2_cmdCALLGSUBR
Definition: psintrp.c:230
@ cf2_cmdHSBW
Definition: psintrp.c:214
cf2_hintmask_isValid(const CF2_HintMask hintmask)
Definition: psintrp.c:76
cf2_hintmask_init(CF2_HintMask hintmask, FT_Error *error)
Definition: psintrp.c:66
cf2_hintmask_setNew(CF2_HintMask hintmask, FT_Bool val)
Definition: psintrp.c:90
cff_random(FT_UInt32 r)
Definition: psobjs.c:2587
ps_builder_check_points(PS_Builder *builder, FT_Int count)
Definition: psobjs.c:2207
cf2_buf_readByte(CF2_Buffer buf)
Definition: psread.c:80
cf2_buf_isEnd(CF2_Buffer buf)
Definition: psread.c:106
FT_BEGIN_HEADER struct CF2_BufferRec_ CF2_BufferRec
FT_BEGIN_HEADER struct CF2_BufferRec_ * CF2_Buffer
cf2_stack_pushInt(CF2_Stack stack, FT_Fast val)
Definition: psstack.c:107
cf2_stack_pushFixed(CF2_Stack stack, CF2_F16Dot16 val)
Definition: psstack.c:123
cf2_stack_popFixed(CF2_Stack stack)
Definition: psstack.c:162
cf2_stack_count(CF2_Stack stack)
Definition: psstack.c:100
cf2_stack_pop(CF2_Stack stack, FT_UFast num)
Definition: psstack.c:229
cf2_stack_clear(CF2_Stack stack)
Definition: psstack.c:325
cf2_stack_popInt(CF2_Stack stack)
Definition: psstack.c:140
cf2_stack_setReal(CF2_Stack stack, FT_UFast idx, CF2_F16Dot16 val)
Definition: psstack.c:212
cf2_stack_free(CF2_Stack stack)
Definition: psstack.c:84
cf2_stack_init(FT_Memory memory, FT_Error *e, FT_UInt stackSize)
Definition: psstack.c:53
cf2_stack_getReal(CF2_Stack stack, FT_UFast idx)
Definition: psstack.c:187
cf2_stack_roll(CF2_Stack stack, FT_Fast count, FT_Fast shift)
Definition: psstack.c:242
#define CF2_UInt
Definition: pstypes.h:63
#define CF2_Int
Definition: pstypes.h:64
FT_Int32 CF2_F16Dot16
Definition: pstypes.h:68
t1_lookup_glyph_by_stdcharcode_ps(PS_Decoder *decoder, FT_Int charcode)
Definition: t1decode.c:132
int int double double double char double char * top
Definition: gdfx.h:19
#define buf
#define root
Definition: ctangleboot.c:69
unsigned bchar
static int delta
Definition: pbmtolj.c:36
void results()
static void blend(struct RGBColour *src, struct RGBColour *dst)
Definition: picttoppm.c:1294
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
integer nn[24]
Definition: pmxab.c:90
static char storage
Definition: pnmtosgi.c:48
static int size
Definition: ppmlabel.c:24
int r
Definition: ppmqvga.c:68
#define x1
#define y1
#define y2
#define x2
static void cf2_doBlend(const CFF_Blend blend, CF2_Stack opStack, FT_UFast numBlends)
Definition: psintrp.c:418
static size_t cf2_hintmask_setCounts(CF2_HintMask hintmask, size_t bitCount)
Definition: psintrp.c:108
#define PS_STORAGE_SIZE
static void cf2_doFlex(CF2_Stack opStack, CF2_F16Dot16 *curX, CF2_F16Dot16 *curY, CF2_GlyphPath glyphPath, const FT_Bool *readFromStack, FT_Bool doConditionalLastRead)
Definition: psintrp.c:335
static void cf2_hintmask_read(CF2_HintMask hintmask, CF2_Buffer charstring, size_t bitCount)
Definition: psintrp.c:131
static void cf2_doStems(const CF2_Font font, CF2_Stack opStack, CF2_ArrStack stemHintArray, CF2_F16Dot16 *width, FT_Bool *haveWidth, CF2_F16Dot16 hintOffset)
Definition: psintrp.c:281
#define arg1(arg)
#define isV(u)
#define mask(n)
Definition: lbitlib.c:93
CF2_ArrStackRec hintMoves
Definition: pshints.h:193
CF2_HintMapRec initialHintMap
Definition: pshints.h:191
FT_Bool isNew
Definition: pshints.h:75
size_t byteCount
Definition: pshints.h:78
FT_Byte mask[(CF2_MAX_HINTS+7)/8]
Definition: pshints.h:80
FT_Bool isValid
Definition: pshints.h:74
size_t bitCount
Definition: pshints.h:77
FT_Error * error
Definition: pshints.h:72
CF2_Fixed maxDS
Definition: pshints.h:93
CF2_Fixed min
Definition: pshints.h:89
CF2_Fixed max
Definition: pshints.h:90
FT_Bool used
Definition: pshints.h:87
CF2_Fixed minDS
Definition: pshints.h:92
FT_UInt32 random
Definition: cfftypes.h:329
FT_Face_Internal internal
Definition: freetype.h:1080
FT_Pos x
Definition: ftimage.h:77
FT_Pos y
Definition: ftimage.h:78
FT_Vector * left_bearing
Definition: psaux.h:575
CFF_GlyphSlot glyph
Definition: psaux.h:567
FT_Vector * advance
Definition: psaux.h:576
FT_Bool no_recurse
Definition: psaux.h:581
FT_GlyphLoader loader
Definition: psaux.h:568
FT_Face face
Definition: psaux.h:566
FT_Bool metrics_only
Definition: psaux.h:583
FT_Int num_flex_vectors
Definition: psaux.h:641
FT_Long * buildchar
Definition: psaux.h:683
FT_Hash locals_hash
Definition: psaux.h:676
CFF_SubFont current_subfont
Definition: psaux.h:645
FT_UInt len_buildchar
Definition: psaux.h:684
FT_Int flex_state
Definition: psaux.h:640
FT_Int globals_bias
Definition: psaux.h:656
FT_Bool width_only
Definition: psaux.h:649
PS_Builder builder
Definition: psaux.h:632
PS_Blend blend
Definition: psaux.h:681
FT_Int locals_bias
Definition: psaux.h:655
FT_Byte ** glyph_names
Definition: psaux.h:661
Definition: pbmfont.h:11
Definition: pbmfont.h:4
Definition: spc_misc.c:56
Definition: strexpr.c:21
int j
Definition: t4ht.c:1589
val
Definition: tex4ht.c:3227
Definition: sd.h:149