ReactOS 0.4.16-dev-981-g80eb313
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 FT_INTERNAL_DEBUG_H
41#include FT_SERVICE_CFF_TABLE_LOAD_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 )
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 {
210 cf2_cmdCLOSEPATH, /* 9 T1 only */
213 cf2_cmdESC, /* 12 */
214 cf2_cmdHSBW, /* 13 T1 only */
217 cf2_cmdBLEND, /* 16 */
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 */
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,
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 =
313 position = ADD_INT32( position,
314 cf2_stack_getReal( opStack, i ) );
315 stemhint.max =
316 position = ADD_INT32( position,
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];
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
418 cf2_doBlend( const CFF_Blend blend,
419 CF2_Stack opStack,
420 CF2_UInt numBlends )
421 {
422 CF2_UInt delta;
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 )
474 const FT_Vector* translation,
475 FT_Bool doingSeac,
476 CF2_Fixed curX,
477 CF2_Fixed curY,
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#ifdef __REACTOS__
529 CF2_GlyphPathRec *glyphPath_allocated = malloc(sizeof(*glyphPath_allocated));
530 if (!glyphPath_allocated) return;
531/* Ugly but it allows us to reduce the diff */
532#define glyphPath (*glyphPath_allocated)
533#else
534 CF2_GlyphPathRec glyphPath;
535#endif
536
537 FT_ZERO( &storage );
538 FT_ZERO( &results );
539 FT_ZERO( &flexStore );
540
541 /* initialize the remaining objects */
542 cf2_arrstack_init( &subrStack,
543 memory,
544 error,
545 sizeof ( CF2_BufferRec ) );
546 cf2_arrstack_init( &hStemHintArray,
547 memory,
548 error,
549 sizeof ( CF2_StemHintRec ) );
550 cf2_arrstack_init( &vStemHintArray,
551 memory,
552 error,
553 sizeof ( CF2_StemHintRec ) );
554
555 /* initialize CF2_StemHint arrays */
556 cf2_hintmask_init( &hintMask, error );
557
558 /* initialize path map to manage drawing operations */
559
560 /* Note: last 4 params are used to handle `MoveToPermissive', which */
561 /* may need to call `hintMap.Build' */
562 /* TODO: MoveToPermissive is gone; are these still needed? */
563 cf2_glyphpath_init( &glyphPath,
564 font,
565 callbacks,
566 scaleY,
567 /* hShift, */
568 &hStemHintArray,
569 &vStemHintArray,
570 &hintMask,
571 hintOriginY,
572 &font->blues,
573 translation );
574
575 /*
576 * Initialize state for width parsing. From the CFF Spec:
577 *
578 * The first stack-clearing operator, which must be one of hstem,
579 * hstemhm, vstem, vstemhm, cntrmask, hintmask, hmoveto, vmoveto,
580 * rmoveto, or endchar, takes an additional argument - the width (as
581 * described earlier), which may be expressed as zero or one numeric
582 * argument.
583 *
584 * What we implement here uses the first validly specified width, but
585 * does not detect errors for specifying more than one width.
586 *
587 * If one of the above operators occurs without explicitly specifying
588 * a width, we assume the default width.
589 *
590 * CFF2 charstrings always return the default width (0).
591 *
592 */
593 haveWidth = font->isCFF2 ? TRUE : FALSE;
595
596 /*
597 * Note: At this point, all pointers to resources must be NULL
598 * and all local objects must be initialized.
599 * There must be no branches to `exit:' above this point.
600 *
601 */
602
603 /* allocate an operand stack */
604 stackSize = font->isCFF2 ? cf2_getMaxstack( decoder )
606 opStack = cf2_stack_init( memory, error, stackSize );
607
608 if ( !opStack )
609 {
610 lastError = FT_THROW( Out_Of_Memory );
611 goto exit;
612 }
613
614 /* initialize subroutine stack by placing top level charstring as */
615 /* first element (max depth plus one for the charstring) */
616 /* Note: Caller owns and must finalize the first charstring. */
617 /* Our copy of it does not change that requirement. */
618 cf2_arrstack_setCount( &subrStack, CF2_MAX_SUBR + 1 );
619
620 charstring = (CF2_Buffer)cf2_arrstack_getBuffer( &subrStack );
621
622 /* catch errors so far */
623 if ( *error )
624 goto exit;
625
626 *charstring = *buf; /* structure copy */
627 charstringIndex = 0; /* entry is valid now */
628
629 /* main interpreter loop */
630 while ( 1 )
631 {
632 if ( font->isT1 )
633 FT_ASSERT( known_othersubr_result_cnt == 0 ||
634 result_cnt == 0 );
635
636 if ( cf2_buf_isEnd( charstring ) )
637 {
638 /* If we've reached the end of the charstring, simulate a */
639 /* cf2_cmdRETURN or cf2_cmdENDCHAR. */
640 /* We do this for both CFF and CFF2. */
641 if ( charstringIndex )
642 op1 = cf2_cmdRETURN; /* end of buffer for subroutine */
643 else
644 op1 = cf2_cmdENDCHAR; /* end of buffer for top level charstring */
645 }
646 else
647 {
648 op1 = (FT_Byte)cf2_buf_readByte( charstring );
649
650 /* Explicit RETURN and ENDCHAR in CFF2 should be ignored. */
651 /* Note: Trace message will report 0 instead of 11 or 14. */
652 if ( ( op1 == cf2_cmdRETURN || op1 == cf2_cmdENDCHAR ) &&
653 font->isCFF2 )
654 op1 = cf2_cmdRESERVED_0;
655 }
656
657 if ( font->isT1 )
658 {
659 if ( !initial_map_ready &&
660 !( op1 == cf2_cmdHSTEM ||
661 op1 == cf2_cmdVSTEM ||
662 op1 == cf2_cmdHSBW ||
663 op1 == cf2_cmdCALLSUBR ||
664 op1 == cf2_cmdRETURN ||
665 op1 == cf2_cmdESC ||
666 op1 == cf2_cmdENDCHAR ||
667 op1 >= 32 /* Numbers */ ) )
668 {
669 /* Skip outline commands first time round. */
670 /* `endchar' will trigger initial hintmap build */
671 /* and rewind the charstring. */
672 FT_TRACE4(( " <outline command skipped>\n" ));
673 cf2_stack_clear( opStack );
674 continue;
675 }
676
677 if ( result_cnt > 0 &&
678 !( op1 == cf2_cmdCALLSUBR ||
679 op1 == cf2_cmdRETURN ||
680 op1 == cf2_cmdESC ||
681 op1 >= 32 /* Numbers */ ) )
682 {
683 /* all operands have been transferred by previous pops */
684 result_cnt = 0;
685 }
686
687 if ( large_int && !( op1 >= 32 || op1 == cf2_escDIV ) )
688 {
689 FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
690 " no `div' after large integer\n" ));
691
692 large_int = FALSE;
693 }
694 }
695
696 /* check for errors once per loop */
697 if ( *error )
698 goto exit;
699
700 instructionLimit--;
701 if ( instructionLimit == 0 )
702 {
703 lastError = FT_THROW( Invalid_Glyph_Format );
704 goto exit;
705 }
706
707 switch( op1 )
708 {
712 /* we may get here if we have a prior error */
713 FT_TRACE4(( " unknown op (%d)\n", op1 ));
714 break;
715
716 case cf2_cmdVSINDEX:
717 FT_TRACE4(( " vsindex\n" ));
718
719 if ( !font->isCFF2 )
720 break; /* clear stack & ignore */
721
722 if ( font->blend.usedBV )
723 {
724 /* vsindex not allowed after blend */
725 lastError = FT_THROW( Invalid_Glyph_Format );
726 goto exit;
727 }
728
729 {
730 FT_Int temp = cf2_stack_popInt( opStack );
731
732
733 if ( temp >= 0 )
734 font->vsindex = (FT_UInt)temp;
735 }
736 break;
737
738 case cf2_cmdBLEND:
739 {
740 FT_UInt numBlends;
741
742
743 FT_TRACE4(( " blend\n" ));
744
745 if ( !font->isCFF2 )
746 break; /* clear stack & ignore */
747
748 /* do we have a `blend' op in a non-variant font? */
749 if ( !font->blend.font )
750 {
751 lastError = FT_THROW( Invalid_Glyph_Format );
752 goto exit;
753 }
754
755 /* check cached blend vector */
756 if ( font->cffload->blend_check_vector( &font->blend,
757 font->vsindex,
758 font->lenNDV,
759 font->NDV ) )
760 {
761 lastError = font->cffload->blend_build_vector( &font->blend,
762 font->vsindex,
763 font->lenNDV,
764 font->NDV );
765 if ( lastError )
766 goto exit;
767 }
768
769 /* do the blend */
770 numBlends = (FT_UInt)cf2_stack_popInt( opStack );
771 if ( numBlends > stackSize )
772 {
773 lastError = FT_THROW( Invalid_Glyph_Format );
774 goto exit;
775 }
776
777 cf2_doBlend( &font->blend, opStack, numBlends );
778
779 font->blend.usedBV = TRUE;
780 }
781 continue; /* do not clear the stack */
782
783 case cf2_cmdHSTEMHM:
784 case cf2_cmdHSTEM:
785 FT_TRACE4(( "%s\n", op1 == cf2_cmdHSTEMHM ? " hstemhm"
786 : " hstem" ));
787
788 if ( !font->isT1 )
789 {
790 /* never add hints after the mask is computed */
791 /* except if in Type 1 mode (no hintmask op) */
792 if ( cf2_hintmask_isValid( &hintMask ) )
793 {
794 FT_TRACE4(( "cf2_interpT2CharString:"
795 " invalid horizontal hint mask\n" ));
796 break;
797 }
798 }
799
800 /* add left-sidebearing correction in Type 1 mode */
802 opStack,
803 &hStemHintArray,
804 width,
805 &haveWidth,
806 font->isT1 ? decoder->builder.left_bearing->y
807 : 0 );
808
809 if ( decoder->width_only )
810 goto exit;
811
812 break;
813
814 case cf2_cmdVSTEMHM:
815 case cf2_cmdVSTEM:
816 FT_TRACE4(( "%s\n", op1 == cf2_cmdVSTEMHM ? " vstemhm"
817 : " vstem" ));
818
819 if ( !font->isT1 )
820 {
821 /* never add hints after the mask is computed */
822 /* except if in Type 1 mode (no hintmask op) */
823 if ( cf2_hintmask_isValid( &hintMask ) )
824 {
825 FT_TRACE4(( "cf2_interpT2CharString:"
826 " invalid vertical hint mask\n" ));
827 break;
828 }
829 }
830
831 /* add left-sidebearing correction in Type 1 mode */
833 opStack,
834 &vStemHintArray,
835 width,
836 &haveWidth,
837 font->isT1 ? decoder->builder.left_bearing->x
838 : 0 );
839
840 if ( decoder->width_only )
841 goto exit;
842
843 break;
844
845 case cf2_cmdVMOVETO:
846 FT_TRACE4(( " vmoveto\n" ));
847
848 if ( font->isT1 && !decoder->flex_state && !haveWidth )
849 FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
850 " No width. Use hsbw/sbw as first op\n" ));
851
852 if ( cf2_stack_count( opStack ) > 1 && !haveWidth )
853 *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ),
854 nominalWidthX );
855
856 /* width is defined or default after this */
857 haveWidth = TRUE;
858
859 if ( decoder->width_only )
860 goto exit;
861
862 curY = ADD_INT32( curY, cf2_stack_popFixed( opStack ) );
863
864 if ( !decoder->flex_state )
865 cf2_glyphpath_moveTo( &glyphPath, curX, curY );
866
867 break;
868
869 case cf2_cmdRLINETO:
870 {
872 CF2_UInt count = cf2_stack_count( opStack );
873
874
875 FT_TRACE4(( " rlineto\n" ));
876
877 for ( idx = 0; idx < count; idx += 2 )
878 {
879 curX = ADD_INT32( curX, cf2_stack_getReal( opStack,
880 idx + 0 ) );
881 curY = ADD_INT32( curY, cf2_stack_getReal( opStack,
882 idx + 1 ) );
883
884 cf2_glyphpath_lineTo( &glyphPath, curX, curY );
885 }
886
887 cf2_stack_clear( opStack );
888 }
889 continue; /* no need to clear stack again */
890
891 case cf2_cmdHLINETO:
892 case cf2_cmdVLINETO:
893 {
895 CF2_UInt count = cf2_stack_count( opStack );
896
897 FT_Bool isX = FT_BOOL( op1 == cf2_cmdHLINETO );
898
899
900 FT_TRACE4(( "%s\n", isX ? " hlineto" : " vlineto" ));
901
902 for ( idx = 0; idx < count; idx++ )
903 {
904 CF2_Fixed v = cf2_stack_getReal( opStack, idx );
905
906
907 if ( isX )
908 curX = ADD_INT32( curX, v );
909 else
910 curY = ADD_INT32( curY, v );
911
912 isX = !isX;
913
914 cf2_glyphpath_lineTo( &glyphPath, curX, curY );
915 }
916
917 cf2_stack_clear( opStack );
918 }
919 continue;
920
922 case cf2_cmdRRCURVETO:
923 {
924 CF2_UInt count = cf2_stack_count( opStack );
925 CF2_UInt idx = 0;
926
927
928 FT_TRACE4(( "%s\n", op1 == cf2_cmdRCURVELINE ? " rcurveline"
929 : " rrcurveto" ));
930
931 while ( idx + 6 <= count )
932 {
933 CF2_Fixed x1, y1, x2, y2, x3, y3;
934
935
936 x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX );
937 y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), curY );
938 x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), x1 );
939 y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y1 );
940 x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), x2 );
941 y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 5 ), y2 );
942
943 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
944
945 curX = x3;
946 curY = y3;
947 idx += 6;
948 }
949
950 if ( op1 == cf2_cmdRCURVELINE )
951 {
952 curX = ADD_INT32( curX, cf2_stack_getReal( opStack,
953 idx + 0 ) );
954 curY = ADD_INT32( curY, cf2_stack_getReal( opStack,
955 idx + 1 ) );
956
957 cf2_glyphpath_lineTo( &glyphPath, curX, curY );
958 }
959
960 cf2_stack_clear( opStack );
961 }
962 continue; /* no need to clear stack again */
963
964 case cf2_cmdCLOSEPATH:
965 if ( !font->isT1 )
966 FT_TRACE4(( " unknown op (%d)\n", op1 ));
967 else
968 {
969 FT_TRACE4(( " closepath\n" ));
970
971 /* if there is no path, `closepath' is a no-op */
972 cf2_glyphpath_closeOpenPath( &glyphPath );
973
974 haveWidth = TRUE;
975 }
976 break;
977
978 case cf2_cmdCALLGSUBR:
979 case cf2_cmdCALLSUBR:
980 {
981 CF2_Int subrNum;
982
983
984 FT_TRACE4(( "%s", op1 == cf2_cmdCALLGSUBR ? " callgsubr"
985 : " callsubr" ));
986
987 if ( ( !font->isT1 && charstringIndex > CF2_MAX_SUBR ) ||
988 ( font->isT1 && charstringIndex > T1_MAX_SUBRS_CALLS ) )
989 {
990 /* max subr plus one for charstring */
991 lastError = FT_THROW( Invalid_Glyph_Format );
992 goto exit; /* overflow of stack */
993 }
994
995 /* push our current CFF charstring region on subrStack */
996 charstring = (CF2_Buffer)
998 &subrStack,
999 (size_t)charstringIndex + 1 );
1000
1001 /* set up the new CFF region and pointer */
1002 subrNum = cf2_stack_popInt( opStack );
1003
1004 if ( font->isT1 && decoder->locals_hash )
1005 {
1006 size_t* val = ft_hash_num_lookup( subrNum,
1007 decoder->locals_hash );
1008
1009
1010 if ( val )
1011 subrNum = *val;
1012 else
1013 subrNum = -1;
1014 }
1015
1016 switch ( op1 )
1017 {
1018 case cf2_cmdCALLGSUBR:
1019 FT_TRACE4(( " (idx %d, entering level %d)\n",
1020 subrNum + decoder->globals_bias,
1021 charstringIndex + 1 ));
1022
1024 subrNum,
1025 charstring ) )
1026 {
1027 lastError = FT_THROW( Invalid_Glyph_Format );
1028 goto exit; /* subroutine lookup or stream error */
1029 }
1030 break;
1031
1032 default:
1033 /* cf2_cmdCALLSUBR */
1034 FT_TRACE4(( " (idx %d, entering level %d)\n",
1035 subrNum + decoder->locals_bias,
1036 charstringIndex + 1 ));
1037
1039 subrNum,
1040 charstring ) )
1041 {
1042 lastError = FT_THROW( Invalid_Glyph_Format );
1043 goto exit; /* subroutine lookup or stream error */
1044 }
1045 }
1046
1047 charstringIndex += 1; /* entry is valid now */
1048 }
1049 continue; /* do not clear the stack */
1050
1051 case cf2_cmdRETURN:
1052 FT_TRACE4(( " return (leaving level %d)\n", charstringIndex ));
1053
1054 if ( charstringIndex < 1 )
1055 {
1056 /* Note: cannot return from top charstring */
1057 lastError = FT_THROW( Invalid_Glyph_Format );
1058 goto exit; /* underflow of stack */
1059 }
1060
1061 /* restore position in previous charstring */
1062 charstring = (CF2_Buffer)
1064 &subrStack,
1065 (CF2_UInt)--charstringIndex );
1066 continue; /* do not clear the stack */
1067
1068 case cf2_cmdESC:
1069 {
1070 FT_Byte op2 = (FT_Byte)cf2_buf_readByte( charstring );
1071
1072
1073 /* first switch for 2-byte operators handles CFF2 */
1074 /* and opcodes that are reserved for both CFF and CFF2 */
1075 switch ( op2 )
1076 {
1077 case cf2_escHFLEX:
1078 {
1079 static const FT_Bool readFromStack[12] =
1080 {
1081 TRUE /* dx1 */, FALSE /* dy1 */,
1082 TRUE /* dx2 */, TRUE /* dy2 */,
1083 TRUE /* dx3 */, FALSE /* dy3 */,
1084 TRUE /* dx4 */, FALSE /* dy4 */,
1085 TRUE /* dx5 */, FALSE /* dy5 */,
1086 TRUE /* dx6 */, FALSE /* dy6 */
1087 };
1088
1089
1090 FT_TRACE4(( " hflex\n" ));
1091
1092 cf2_doFlex( opStack,
1093 &curX,
1094 &curY,
1095 &glyphPath,
1096 readFromStack,
1097 FALSE /* doConditionalLastRead */ );
1098 }
1099 continue;
1100
1101 case cf2_escFLEX:
1102 {
1103 static const FT_Bool readFromStack[12] =
1104 {
1105 TRUE /* dx1 */, TRUE /* dy1 */,
1106 TRUE /* dx2 */, TRUE /* dy2 */,
1107 TRUE /* dx3 */, TRUE /* dy3 */,
1108 TRUE /* dx4 */, TRUE /* dy4 */,
1109 TRUE /* dx5 */, TRUE /* dy5 */,
1110 TRUE /* dx6 */, TRUE /* dy6 */
1111 };
1112
1113
1114 FT_TRACE4(( " flex\n" ));
1115
1116 cf2_doFlex( opStack,
1117 &curX,
1118 &curY,
1119 &glyphPath,
1120 readFromStack,
1121 FALSE /* doConditionalLastRead */ );
1122 }
1123 break; /* TODO: why is this not a continue? */
1124
1125 case cf2_escHFLEX1:
1126 {
1127 static const FT_Bool readFromStack[12] =
1128 {
1129 TRUE /* dx1 */, TRUE /* dy1 */,
1130 TRUE /* dx2 */, TRUE /* dy2 */,
1131 TRUE /* dx3 */, FALSE /* dy3 */,
1132 TRUE /* dx4 */, FALSE /* dy4 */,
1133 TRUE /* dx5 */, TRUE /* dy5 */,
1134 TRUE /* dx6 */, FALSE /* dy6 */
1135 };
1136
1137
1138 FT_TRACE4(( " hflex1\n" ));
1139
1140 cf2_doFlex( opStack,
1141 &curX,
1142 &curY,
1143 &glyphPath,
1144 readFromStack,
1145 FALSE /* doConditionalLastRead */ );
1146 }
1147 continue;
1148
1149 case cf2_escFLEX1:
1150 {
1151 static const FT_Bool readFromStack[12] =
1152 {
1153 TRUE /* dx1 */, TRUE /* dy1 */,
1154 TRUE /* dx2 */, TRUE /* dy2 */,
1155 TRUE /* dx3 */, TRUE /* dy3 */,
1156 TRUE /* dx4 */, TRUE /* dy4 */,
1157 TRUE /* dx5 */, TRUE /* dy5 */,
1158 FALSE /* dx6 */, FALSE /* dy6 */
1159 };
1160
1161
1162 FT_TRACE4(( " flex1\n" ));
1163
1164 cf2_doFlex( opStack,
1165 &curX,
1166 &curY,
1167 &glyphPath,
1168 readFromStack,
1169 TRUE /* doConditionalLastRead */ );
1170 }
1171 continue;
1172
1173 /* these opcodes are always reserved */
1174 case cf2_escRESERVED_8:
1175 case cf2_escRESERVED_13:
1176 case cf2_escRESERVED_19:
1177 case cf2_escRESERVED_25:
1178 case cf2_escRESERVED_31:
1179 case cf2_escRESERVED_32:
1180 FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
1181 break;
1182
1183 default:
1184 {
1185 if ( font->isCFF2 || op2 >= cf2_escRESERVED_38 )
1186 FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
1187 else if ( font->isT1 && result_cnt > 0 && op2 != cf2_escPOP )
1188 {
1189 /* all operands have been transferred by previous pops */
1190 result_cnt = 0;
1191 }
1192 else
1193 {
1194 /* second switch for 2-byte operators handles */
1195 /* CFF and Type 1 */
1196 switch ( op2 )
1197 {
1198
1199 case cf2_escDOTSECTION:
1200 /* something about `flip type of locking' -- ignore it */
1201 FT_TRACE4(( " dotsection\n" ));
1202
1203 break;
1204
1205 case cf2_escVSTEM3:
1206 case cf2_escHSTEM3:
1207 /*
1208 * Type 1: Type 2:
1209 * x0 dx0 x1 dx1 x2 dx2 vstem3 x dx {dxa dxb}* vstem
1210 * y0 dy0 y1 dy1 y2 dy2 hstem3 y dy {dya dyb}* hstem
1211 * relative to lsb point relative to zero
1212 *
1213 */
1214 {
1215 if ( !font->isT1 )
1216 FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
1217 else
1218 {
1219 CF2_F16Dot16 v0, v1, v2;
1220
1221 FT_Bool isV = FT_BOOL( op2 == cf2_escVSTEM3 );
1222
1223
1224 FT_TRACE4(( "%s\n", isV ? " vstem3"
1225 : " hstem3" ));
1226
1227 FT_ASSERT( cf2_stack_count( opStack ) == 6 );
1228
1229 v0 = cf2_stack_getReal( opStack, 0 );
1230 v1 = cf2_stack_getReal( opStack, 2 );
1231 v2 = cf2_stack_getReal( opStack, 4 );
1232
1234 opStack, 2,
1235 SUB_INT32( SUB_INT32( v1, v0 ),
1236 cf2_stack_getReal( opStack, 1 ) ) );
1238 opStack, 4,
1239 SUB_INT32( SUB_INT32( v2, v1 ),
1240 cf2_stack_getReal( opStack, 3 ) ) );
1241
1242 /* add left-sidebearing correction */
1244 opStack,
1245 isV ? &vStemHintArray : &hStemHintArray,
1246 width,
1247 &haveWidth,
1248 isV ? decoder->builder.left_bearing->x
1249 : decoder->builder.left_bearing->y );
1250
1251 if ( decoder->width_only )
1252 goto exit;
1253 }
1254 }
1255 break;
1256
1257 case cf2_escAND:
1258 {
1261
1262
1263 FT_TRACE4(( " and\n" ));
1264
1265 arg2 = cf2_stack_popFixed( opStack );
1266 arg1 = cf2_stack_popFixed( opStack );
1267
1268 cf2_stack_pushInt( opStack, arg1 && arg2 );
1269 }
1270 continue; /* do not clear the stack */
1271
1272 case cf2_escOR:
1273 {
1276
1277
1278 FT_TRACE4(( " or\n" ));
1279
1280 arg2 = cf2_stack_popFixed( opStack );
1281 arg1 = cf2_stack_popFixed( opStack );
1282
1283 cf2_stack_pushInt( opStack, arg1 || arg2 );
1284 }
1285 continue; /* do not clear the stack */
1286
1287 case cf2_escNOT:
1288 {
1290
1291
1292 FT_TRACE4(( " not\n" ));
1293
1294 arg = cf2_stack_popFixed( opStack );
1295
1296 cf2_stack_pushInt( opStack, !arg );
1297 }
1298 continue; /* do not clear the stack */
1299
1300 case cf2_escSEAC:
1301 if ( !font->isT1 )
1302 FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
1303 else
1304 {
1306 CF2_Int bchar_index, achar_index;
1307 FT_Vector left_bearing, advance;
1308
1309#ifdef FT_CONFIG_OPTION_INCREMENTAL
1310 T1_Face face = (T1_Face)decoder->builder.face;
1311#endif
1312 CF2_BufferRec component;
1313 CF2_Fixed dummyWidth;
1314
1315 CF2_Int achar = cf2_stack_popInt( opStack );
1316 CF2_Int bchar = cf2_stack_popInt( opStack );
1317
1318 FT_Pos ady = cf2_stack_popFixed ( opStack );
1319 FT_Pos adx = cf2_stack_popFixed ( opStack );
1320 FT_Pos asb = cf2_stack_popFixed ( opStack );
1321
1322
1323 FT_TRACE4(( " seac\n" ));
1324
1325 if ( doingSeac )
1326 {
1327 FT_ERROR(( " nested seac\n" ));
1328 lastError = FT_THROW( Invalid_Glyph_Format );
1329 goto exit; /* nested seac */
1330 }
1331
1332 if ( decoder->builder.metrics_only )
1333 {
1334 FT_ERROR(( " unexpected seac\n" ));
1335 lastError = FT_THROW( Invalid_Glyph_Format );
1336 goto exit; /* unexpected seac */
1337 }
1338
1339 /* `glyph_names' is set to 0 for CID fonts which do */
1340 /* not include an encoding. How can we deal with */
1341 /* these? */
1342#ifdef FT_CONFIG_OPTION_INCREMENTAL
1343 if ( decoder->glyph_names == 0 &&
1344 !face->root.internal->incremental_interface )
1345#else
1346 if ( decoder->glyph_names == 0 )
1347#endif /* FT_CONFIG_OPTION_INCREMENTAL */
1348 {
1349 FT_ERROR((
1350 "cf2_interpT2CharString: (Type 1 seac)"
1351 " glyph names table not available in this font\n" ));
1352 lastError = FT_THROW( Invalid_Glyph_Format );
1353 goto exit;
1354 }
1355
1356 /* seac weirdness */
1357 adx += decoder->builder.left_bearing->x;
1358
1359#ifdef FT_CONFIG_OPTION_INCREMENTAL
1360 if ( face->root.internal->incremental_interface )
1361 {
1362 /* the caller must handle the font encoding also */
1363 bchar_index = bchar;
1364 achar_index = achar;
1365 }
1366 else
1367#endif
1368 {
1370 decoder, bchar );
1372 decoder, achar );
1373 }
1374
1375 if ( bchar_index < 0 || achar_index < 0 )
1376 {
1377 FT_ERROR((
1378 "cf2_interpT2CharString: (Type 1 seac)"
1379 " invalid seac character code arguments\n" ));
1380 lastError = FT_THROW( Invalid_Glyph_Format );
1381 goto exit;
1382 }
1383
1384 /* if we are trying to load a composite glyph, */
1385 /* do not load the accent character and return */
1386 /* the array of subglyphs. */
1387 if ( decoder->builder.no_recurse )
1388 {
1389 FT_GlyphSlot glyph = (FT_GlyphSlot)decoder->builder.glyph;
1390 FT_GlyphLoader loader = glyph->internal->loader;
1391 FT_SubGlyph subg;
1392
1393
1394 /* reallocate subglyph array if necessary */
1396 if ( error2 )
1397 {
1398 lastError = error2; /* pass FreeType error through */
1399 goto exit;
1400 }
1401
1402 subg = loader->current.subglyphs;
1403
1404 /* subglyph 0 = base character */
1405 subg->index = bchar_index;
1408 subg->arg1 = 0;
1409 subg->arg2 = 0;
1410 subg++;
1411
1412 /* subglyph 1 = accent character */
1413 subg->index = achar_index;
1415 subg->arg1 = (FT_Int)FIXED_TO_INT( adx - asb );
1416 subg->arg2 = (FT_Int)FIXED_TO_INT( ady );
1417
1418 /* set up remaining glyph fields */
1419 glyph->num_subglyphs = 2;
1420 glyph->subglyphs = loader->base.subglyphs;
1421 glyph->format = FT_GLYPH_FORMAT_COMPOSITE;
1422
1423 loader->current.num_subglyphs = 2;
1424
1425 goto exit;
1426 }
1427
1428 /* First load `bchar' in builder */
1429 /* now load the unscaled outline */
1430
1431 /* prepare loader */
1432 FT_GlyphLoader_Prepare( decoder->builder.loader );
1433
1435 (FT_UInt)bchar_index,
1436 &component );
1437 if ( error2 )
1438 {
1439 lastError = error2; /* pass FreeType error through */
1440 goto exit;
1441 }
1443 &component,
1444 callbacks,
1445 translation,
1446 TRUE,
1447 0,
1448 0,
1449 &dummyWidth );
1450 cf2_freeT1SeacComponent( decoder, &component );
1451
1452 /* save the left bearing and width of the base */
1453 /* character as they will be erased by the next load */
1454
1455 left_bearing = *decoder->builder.left_bearing;
1456 advance = *decoder->builder.advance;
1457
1458 decoder->builder.left_bearing->x = 0;
1459 decoder->builder.left_bearing->y = 0;
1460
1461 /* Now load `achar' on top of */
1462 /* the base outline */
1463
1465 (FT_UInt)achar_index,
1466 &component );
1467 if ( error2 )
1468 {
1469 lastError = error2; /* pass FreeType error through */
1470 goto exit;
1471 }
1473 &component,
1474 callbacks,
1475 translation,
1476 TRUE,
1477 adx - asb,
1478 ady,
1479 &dummyWidth );
1480 cf2_freeT1SeacComponent( decoder, &component );
1481
1482 /* restore the left side bearing and */
1483 /* advance width of the base character */
1484
1485 *decoder->builder.left_bearing = left_bearing;
1486 *decoder->builder.advance = advance;
1487
1488 goto exit;
1489 }
1490 break;
1491
1492 case cf2_escSBW:
1493 if ( !font->isT1 )
1494 FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
1495 else
1496 {
1497 CF2_Fixed lsb_x, lsb_y;
1498 PS_Builder* builder;
1499
1500
1501 FT_TRACE4(( " sbw" ));
1502
1503 builder = &decoder->builder;
1504
1505 builder->advance->y = cf2_stack_popFixed( opStack );
1506 builder->advance->x = cf2_stack_popFixed( opStack );
1507
1508 lsb_y = cf2_stack_popFixed( opStack );
1509 lsb_x = cf2_stack_popFixed( opStack );
1510
1511 builder->left_bearing->x =
1512 ADD_INT32( builder->left_bearing->x, lsb_x );
1513 builder->left_bearing->y =
1514 ADD_INT32( builder->left_bearing->y, lsb_y );
1515
1516 haveWidth = TRUE;
1517
1518 /* the `metrics_only' indicates that we only want */
1519 /* to compute the glyph's metrics (lsb + advance */
1520 /* width), not load the rest of it; so exit */
1521 /* immediately */
1522 if ( builder->metrics_only )
1523 goto exit;
1524
1525 if ( initial_map_ready )
1526 {
1527 curX = ADD_INT32( curX, lsb_x );
1528 curY = ADD_INT32( curY, lsb_y );
1529 }
1530 }
1531 break;
1532
1533 case cf2_escABS:
1534 {
1536
1537
1538 FT_TRACE4(( " abs\n" ));
1539
1540 arg = cf2_stack_popFixed( opStack );
1541
1542 if ( arg < -CF2_FIXED_MAX )
1544 else
1545 cf2_stack_pushFixed( opStack, FT_ABS( arg ) );
1546 }
1547 continue; /* do not clear the stack */
1548
1549 case cf2_escADD:
1550 {
1551 CF2_F16Dot16 summand1;
1552 CF2_F16Dot16 summand2;
1553
1554
1555 FT_TRACE4(( " add\n" ));
1556
1557 summand2 = cf2_stack_popFixed( opStack );
1558 summand1 = cf2_stack_popFixed( opStack );
1559
1560 cf2_stack_pushFixed( opStack,
1561 ADD_INT32( summand1,
1562 summand2 ) );
1563 }
1564 continue; /* do not clear the stack */
1565
1566 case cf2_escSUB:
1567 {
1568 CF2_F16Dot16 minuend;
1569 CF2_F16Dot16 subtrahend;
1570
1571
1572 FT_TRACE4(( " sub\n" ));
1573
1574 subtrahend = cf2_stack_popFixed( opStack );
1575 minuend = cf2_stack_popFixed( opStack );
1576
1577 cf2_stack_pushFixed( opStack,
1578 SUB_INT32( minuend, subtrahend ) );
1579 }
1580 continue; /* do not clear the stack */
1581
1582 case cf2_escDIV:
1583 {
1584 CF2_F16Dot16 dividend;
1586
1587
1588 FT_TRACE4(( " div\n" ));
1589
1590 if ( font->isT1 && large_int )
1591 {
1593 dividend = (CF2_F16Dot16)cf2_stack_popInt( opStack );
1594
1595 large_int = FALSE;
1596 }
1597 else
1598 {
1599 divisor = cf2_stack_popFixed( opStack );
1600 dividend = cf2_stack_popFixed( opStack );
1601 }
1602
1603 cf2_stack_pushFixed( opStack,
1604 FT_DivFix( dividend, divisor ) );
1605
1606 }
1607 continue; /* do not clear the stack */
1608
1609 case cf2_escNEG:
1610 {
1612
1613
1614 FT_TRACE4(( " neg\n" ));
1615
1616 arg = cf2_stack_popFixed( opStack );
1617
1618 if ( arg < -CF2_FIXED_MAX )
1620 else
1621 cf2_stack_pushFixed( opStack, -arg );
1622 }
1623 continue; /* do not clear the stack */
1624
1625 case cf2_escEQ:
1626 {
1629
1630
1631 FT_TRACE4(( " eq\n" ));
1632
1633 arg2 = cf2_stack_popFixed( opStack );
1634 arg1 = cf2_stack_popFixed( opStack );
1635
1636 cf2_stack_pushInt( opStack, arg1 == arg2 );
1637 }
1638 continue; /* do not clear the stack */
1639
1641 if ( !font->isT1 )
1642 FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
1643 else
1644 {
1645 CF2_Int subr_no;
1648 CF2_UInt opIdx = 0;
1649
1650
1651 FT_TRACE4(( " callothersubr\n" ));
1652
1653 subr_no = cf2_stack_popInt( opStack );
1654 arg_cnt = cf2_stack_popInt( opStack );
1655
1656 /********************************************************
1657 *
1658 * remove all operands to callothersubr from the stack
1659 *
1660 * for handled othersubrs, where we know the number of
1661 * arguments, we increase the stack by the value of
1662 * known_othersubr_result_cnt
1663 *
1664 * for unhandled othersubrs the following pops adjust
1665 * the stack pointer as necessary
1666 */
1667
1668 count = cf2_stack_count( opStack );
1670
1671 opIdx += count - (CF2_UInt)arg_cnt;
1672
1673 known_othersubr_result_cnt = 0;
1674 result_cnt = 0;
1675
1676 /* XXX TODO: The checks to `arg_count == <whatever>' */
1677 /* might not be correct; an othersubr expects a */
1678 /* certain number of operands on the PostScript stack */
1679 /* (as opposed to the T1 stack) but it doesn't have to */
1680 /* put them there by itself; previous othersubrs might */
1681 /* have left the operands there if they were not */
1682 /* followed by an appropriate number of pops */
1683 /* */
1684 /* On the other hand, Adobe Reader 7.0.8 for Linux */
1685 /* doesn't accept a font that contains charstrings */
1686 /* like */
1687 /* */
1688 /* 100 200 2 20 callothersubr */
1689 /* 300 1 20 callothersubr pop */
1690 /* */
1691 /* Perhaps this is the reason why BuildCharArray */
1692 /* exists. */
1693
1694 switch ( subr_no )
1695 {
1696 case 0: /* end flex feature */
1697 if ( arg_cnt != 3 )
1698 goto Unexpected_OtherSubr;
1699
1700 if ( initial_map_ready &&
1701 ( !decoder->flex_state ||
1702 decoder->num_flex_vectors != 7 ) )
1703 {
1704 FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
1705 " unexpected flex end\n" ));
1706 lastError = FT_THROW( Invalid_Glyph_Format );
1707 goto exit;
1708 }
1709
1710 /* the two `results' are popped */
1711 /* by the following setcurrentpoint */
1712 cf2_stack_pushFixed( opStack, curX );
1713 cf2_stack_pushFixed( opStack, curY );
1714 known_othersubr_result_cnt = 2;
1715 break;
1716
1717 case 1: /* start flex feature */
1718 if ( arg_cnt != 0 )
1719 goto Unexpected_OtherSubr;
1720
1721 if ( !initial_map_ready )
1722 break;
1723
1724 if ( ps_builder_check_points( &decoder->builder, 6 ) )
1725 goto exit;
1726
1727 decoder->flex_state = 1;
1728 decoder->num_flex_vectors = 0;
1729 break;
1730
1731 case 2: /* add flex vectors */
1732 {
1733 FT_Int idx;
1734 FT_Int idx2;
1735
1736
1737 if ( arg_cnt != 0 )
1738 goto Unexpected_OtherSubr;
1739
1740 if ( !initial_map_ready )
1741 break;
1742
1743 if ( !decoder->flex_state )
1744 {
1745 FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
1746 " missing flex start\n" ));
1747 lastError = FT_THROW( Invalid_Glyph_Format );
1748 goto exit;
1749 }
1750
1751 /* note that we should not add a point for */
1752 /* index 0; this will move our current position */
1753 /* to the flex point without adding any point */
1754 /* to the outline */
1755 idx = decoder->num_flex_vectors++;
1756 if ( idx > 0 && idx < 7 )
1757 {
1758 /* in malformed fonts it is possible to have */
1759 /* other opcodes in the middle of a flex (which */
1760 /* don't increase `num_flex_vectors'); we thus */
1761 /* have to check whether we can add a point */
1762
1763 if ( ps_builder_check_points( &decoder->builder,
1764 1 ) )
1765 {
1766 lastError = FT_THROW( Invalid_Glyph_Format );
1767 goto exit;
1768 }
1769
1770 /* map: 1->2 2->4 3->6 4->2 5->4 6->6 */
1771 idx2 = ( idx > 3 ? idx - 3 : idx ) * 2;
1772
1773 flexStore[idx2 - 2] = curX;
1774 flexStore[idx2 - 1] = curY;
1775
1776 if ( idx == 3 || idx == 6 )
1777 cf2_glyphpath_curveTo( &glyphPath,
1778 flexStore[0],
1779 flexStore[1],
1780 flexStore[2],
1781 flexStore[3],
1782 flexStore[4],
1783 flexStore[5] );
1784 }
1785 }
1786 break;
1787
1788 case 3: /* change hints */
1789 if ( arg_cnt != 1 )
1790 goto Unexpected_OtherSubr;
1791
1792 if ( initial_map_ready )
1793 {
1794 /* do not clear hints if initial hintmap */
1795 /* is not ready - we need to collate all */
1796 cf2_arrstack_clear( &vStemHintArray );
1797 cf2_arrstack_clear( &hStemHintArray );
1798
1799 cf2_hintmask_init( &hintMask, error );
1800 hintMask.isValid = FALSE;
1801 hintMask.isNew = TRUE;
1802 }
1803
1804 known_othersubr_result_cnt = 1;
1805 break;
1806
1807 case 12:
1808 case 13:
1809 /* counter control hints, clear stack */
1810 cf2_stack_clear( opStack );
1811 break;
1812
1813 case 14:
1814 case 15:
1815 case 16:
1816 case 17:
1817 case 18: /* multiple masters */
1818 {
1819 PS_Blend blend = decoder->blend;
1820 FT_UInt num_points, nn, mm;
1821 CF2_UInt delta;
1823
1824
1825 if ( !blend )
1826 {
1827 FT_ERROR((
1828 "cf2_interpT2CharString:"
1829 " unexpected multiple masters operator\n" ));
1830 lastError = FT_THROW( Invalid_Glyph_Format );
1831 goto exit;
1832 }
1833
1834 num_points = (FT_UInt)subr_no - 13 +
1835 ( subr_no == 18 );
1836 if ( arg_cnt != (FT_Int)( num_points *
1837 blend->num_designs ) )
1838 {
1839 FT_ERROR((
1840 "cf2_interpT2CharString:"
1841 " incorrect number of multiple masters arguments\n" ));
1842 lastError = FT_THROW( Invalid_Glyph_Format );
1843 goto exit;
1844 }
1845
1846 /* We want to compute */
1847 /* */
1848 /* a0*w0 + a1*w1 + ... + ak*wk */
1849 /* */
1850 /* but we only have a0, a1-a0, a2-a0, ..., ak-a0. */
1851 /* */
1852 /* However, given that w0 + w1 + ... + wk == 1, we */
1853 /* can rewrite it easily as */
1854 /* */
1855 /* a0 + (a1-a0)*w1 + (a2-a0)*w2 + ... + (ak-a0)*wk */
1856 /* */
1857 /* where k == num_designs-1. */
1858 /* */
1859 /* I guess that's why it's written in this `compact' */
1860 /* form. */
1861 /* */
1862 delta = opIdx + num_points;
1863 values = opIdx;
1864 for ( nn = 0; nn < num_points; nn++ )
1865 {
1866 CF2_Fixed tmp = cf2_stack_getReal( opStack,
1867 values );
1868
1869
1870 for ( mm = 1; mm < blend->num_designs; mm++ )
1871 tmp = ADD_INT32( tmp,
1872 FT_MulFix(
1873 cf2_stack_getReal( opStack,
1874 delta++ ),
1875 blend->weight_vector[mm] ) );
1876
1877 cf2_stack_setReal( opStack, values++, tmp );
1878 }
1879 cf2_stack_pop( opStack,
1880 (CF2_UInt)arg_cnt - num_points );
1881
1882 known_othersubr_result_cnt = (FT_Int)num_points;
1883 break;
1884 }
1885
1886 case 19:
1887 /* <idx> 1 19 callothersubr */
1888 /* ==> replace elements starting from index */
1889 /* cvi( <idx> ) of BuildCharArray with */
1890 /* WeightVector */
1891 {
1892 FT_Int idx;
1893 PS_Blend blend = decoder->blend;
1894
1895
1896 if ( arg_cnt != 1 || !blend )
1897 goto Unexpected_OtherSubr;
1898
1899 idx = cf2_stack_popInt( opStack );
1900
1901 if ( idx < 0 ||
1902 (FT_UInt)idx + blend->num_designs >
1903 decoder->len_buildchar )
1904 goto Unexpected_OtherSubr;
1905
1906 ft_memcpy( &decoder->buildchar[idx],
1907 blend->weight_vector,
1908 blend->num_designs *
1909 sizeof ( blend->weight_vector[0] ) );
1910 }
1911 break;
1912
1913 case 20:
1914 /* <arg1> <arg2> 2 20 callothersubr pop */
1915 /* ==> push <arg1> + <arg2> onto T1 stack */
1916 {
1917 CF2_F16Dot16 summand1;
1918 CF2_F16Dot16 summand2;
1919
1920
1921 if ( arg_cnt != 2 )
1922 goto Unexpected_OtherSubr;
1923
1924 summand2 = cf2_stack_popFixed( opStack );
1925 summand1 = cf2_stack_popFixed( opStack );
1926
1927 cf2_stack_pushFixed( opStack,
1928 ADD_INT32( summand1,
1929 summand2 ) );
1930 known_othersubr_result_cnt = 1;
1931 }
1932 break;
1933
1934 case 21:
1935 /* <arg1> <arg2> 2 21 callothersubr pop */
1936 /* ==> push <arg1> - <arg2> onto T1 stack */
1937 {
1938 CF2_F16Dot16 minuend;
1939 CF2_F16Dot16 subtrahend;
1940
1941
1942 if ( arg_cnt != 2 )
1943 goto Unexpected_OtherSubr;
1944
1945 subtrahend = cf2_stack_popFixed( opStack );
1946 minuend = cf2_stack_popFixed( opStack );
1947
1948 cf2_stack_pushFixed( opStack,
1949 SUB_INT32( minuend,
1950 subtrahend ) );
1951 known_othersubr_result_cnt = 1;
1952 }
1953 break;
1954
1955 case 22:
1956 /* <arg1> <arg2> 2 22 callothersubr pop */
1957 /* ==> push <arg1> * <arg2> onto T1 stack */
1958 {
1959 CF2_F16Dot16 factor1;
1960 CF2_F16Dot16 factor2;
1961
1962
1963 if ( arg_cnt != 2 )
1964 goto Unexpected_OtherSubr;
1965
1966 factor2 = cf2_stack_popFixed( opStack );
1967 factor1 = cf2_stack_popFixed( opStack );
1968
1969 cf2_stack_pushFixed( opStack,
1970 FT_MulFix( factor1, factor2 ) );
1971 known_othersubr_result_cnt = 1;
1972 }
1973 break;
1974
1975 case 23:
1976 /* <arg1> <arg2> 2 23 callothersubr pop */
1977 /* ==> push <arg1> / <arg2> onto T1 stack */
1978 {
1979 CF2_F16Dot16 dividend;
1981
1982
1983 if ( arg_cnt != 2 )
1984 goto Unexpected_OtherSubr;
1985
1986 divisor = cf2_stack_popFixed( opStack );
1987 dividend = cf2_stack_popFixed( opStack );
1988
1989 if ( divisor == 0 )
1990 goto Unexpected_OtherSubr;
1991
1992 cf2_stack_pushFixed( opStack,
1993 FT_DivFix( dividend,
1994 divisor ) );
1995 known_othersubr_result_cnt = 1;
1996 }
1997 break;
1998
1999 case 24:
2000 /* <val> <idx> 2 24 callothersubr */
2001 /* ==> set BuildCharArray[cvi( <idx> )] = <val> */
2002 {
2003 CF2_Int idx;
2004 PS_Blend blend = decoder->blend;
2005
2006
2007 if ( arg_cnt != 2 || !blend )
2008 goto Unexpected_OtherSubr;
2009
2010 idx = cf2_stack_popInt( opStack );
2011
2012 if ( idx < 0 ||
2013 (FT_UInt)idx >= decoder->len_buildchar )
2014 goto Unexpected_OtherSubr;
2015
2016 decoder->buildchar[idx] =
2017 cf2_stack_popFixed( opStack );
2018 }
2019 break;
2020
2021 case 25:
2022 /* <idx> 1 25 callothersubr pop */
2023 /* ==> push BuildCharArray[cvi( idx )] */
2024 /* onto T1 stack */
2025 {
2026 CF2_Int idx;
2027 PS_Blend blend = decoder->blend;
2028
2029
2030 if ( arg_cnt != 1 || !blend )
2031 goto Unexpected_OtherSubr;
2032
2033 idx = cf2_stack_popInt( opStack );
2034
2035 if ( idx < 0 ||
2036 (FT_UInt)idx >= decoder->len_buildchar )
2037 goto Unexpected_OtherSubr;
2038
2039 cf2_stack_pushFixed( opStack,
2040 decoder->buildchar[idx] );
2041 known_othersubr_result_cnt = 1;
2042 }
2043 break;
2044
2045#if 0
2046 case 26:
2047 /* <val> mark <idx> */
2048 /* ==> set BuildCharArray[cvi( <idx> )] = <val>, */
2049 /* leave mark on T1 stack */
2050 /* <val> <idx> */
2051 /* ==> set BuildCharArray[cvi( <idx> )] = <val> */
2052 XXX which routine has left its mark on the
2053 XXX (PostScript) stack?;
2054 break;
2055#endif
2056
2057 case 27:
2058 /* <res1> <res2> <val1> <val2> 4 27 callothersubr pop */
2059 /* ==> push <res1> onto T1 stack if <val1> <= <val2>, */
2060 /* otherwise push <res2> */
2061 {
2064 CF2_F16Dot16 cond1;
2065 CF2_F16Dot16 cond2;
2066
2067
2068 if ( arg_cnt != 4 )
2069 goto Unexpected_OtherSubr;
2070
2071 cond2 = cf2_stack_popFixed( opStack );
2072 cond1 = cf2_stack_popFixed( opStack );
2073 arg2 = cf2_stack_popFixed( opStack );
2074 arg1 = cf2_stack_popFixed( opStack );
2075
2076 cf2_stack_pushFixed( opStack,
2077 cond1 <= cond2 ? arg1 : arg2 );
2078 known_othersubr_result_cnt = 1;
2079 }
2080 break;
2081
2082 case 28:
2083 /* 0 28 callothersubr pop */
2084 /* ==> push random value from interval [0, 1) */
2085 /* onto stack */
2086 {
2088
2089
2090 if ( arg_cnt != 0 )
2091 goto Unexpected_OtherSubr;
2092
2093 /* only use the lower 16 bits of `random' */
2094 /* to generate a number in the range (0;1] */
2095 r = (CF2_F16Dot16)
2096 ( ( decoder->current_subfont->random & 0xFFFF ) + 1 );
2097
2098 decoder->current_subfont->random =
2099 cff_random( decoder->current_subfont->random );
2100
2101 cf2_stack_pushFixed( opStack, r );
2102 known_othersubr_result_cnt = 1;
2103 }
2104 break;
2105
2106 default:
2107 if ( arg_cnt >= 0 && subr_no >= 0 )
2108 {
2109 FT_Int i;
2110
2111
2112 FT_ERROR((
2113 "cf2_interpT2CharString (Type 1 mode):"
2114 " unknown othersubr [%d %d], wish me luck\n",
2115 arg_cnt, subr_no ));
2116
2117 /* store the unused args */
2118 /* for this unhandled OtherSubr */
2119
2120 if ( arg_cnt > PS_STORAGE_SIZE )
2122 result_cnt = arg_cnt;
2123
2124 for ( i = 1; i <= arg_cnt; i++ )
2125 results[result_cnt - i] =
2126 cf2_stack_popFixed( opStack );
2127
2128 break;
2129 }
2130 /* fall through */
2131
2132 Unexpected_OtherSubr:
2133 FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
2134 " invalid othersubr [%d %d]\n",
2135 arg_cnt, subr_no ));
2136 lastError = FT_THROW( Invalid_Glyph_Format );
2137 goto exit;
2138 }
2139 }
2140 continue; /* do not clear the stack */
2141
2142 case cf2_escPOP:
2143 if ( !font->isT1 )
2144 FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
2145 else
2146 {
2147 FT_TRACE4(( " pop" ));
2148
2149 if ( known_othersubr_result_cnt > 0 )
2150 {
2151 known_othersubr_result_cnt--;
2152 /* ignore, we pushed the operands ourselves */
2153 continue;
2154 }
2155
2156 if ( result_cnt == 0 )
2157 {
2158 FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
2159 " no more operands for othersubr\n" ));
2160 lastError = FT_THROW( Invalid_Glyph_Format );
2161 goto exit;
2162 }
2163
2164 result_cnt--;
2165 cf2_stack_pushFixed( opStack, results[result_cnt] );
2166 }
2167 continue; /* do not clear the stack */
2168
2169 case cf2_escDROP:
2170 FT_TRACE4(( " drop\n" ));
2171
2172 (void)cf2_stack_popFixed( opStack );
2173 continue; /* do not clear the stack */
2174
2175 case cf2_escPUT:
2176 {
2178 CF2_Int idx;
2179
2180
2181 FT_TRACE4(( " put\n" ));
2182
2183 idx = cf2_stack_popInt( opStack );
2184 val = cf2_stack_popFixed( opStack );
2185
2186 if ( idx >= 0 && idx < CF2_STORAGE_SIZE )
2187 storage[idx] = val;
2188 }
2189 continue; /* do not clear the stack */
2190
2191 case cf2_escGET:
2192 {
2193 CF2_Int idx;
2194
2195
2196 FT_TRACE4(( " get\n" ));
2197
2198 idx = cf2_stack_popInt( opStack );
2199
2200 if ( idx >= 0 && idx < CF2_STORAGE_SIZE )
2201 cf2_stack_pushFixed( opStack, storage[idx] );
2202 }
2203 continue; /* do not clear the stack */
2204
2205 case cf2_escIFELSE:
2206 {
2209 CF2_F16Dot16 cond1;
2210 CF2_F16Dot16 cond2;
2211
2212
2213 FT_TRACE4(( " ifelse\n" ));
2214
2215 cond2 = cf2_stack_popFixed( opStack );
2216 cond1 = cf2_stack_popFixed( opStack );
2217 arg2 = cf2_stack_popFixed( opStack );
2218 arg1 = cf2_stack_popFixed( opStack );
2219
2220 cf2_stack_pushFixed( opStack,
2221 cond1 <= cond2 ? arg1 : arg2 );
2222 }
2223 continue; /* do not clear the stack */
2224
2225 case cf2_escRANDOM: /* in spec */
2226 {
2228
2229
2230 FT_TRACE4(( " random\n" ));
2231
2232 /* only use the lower 16 bits of `random' */
2233 /* to generate a number in the range (0;1] */
2234 r = (CF2_F16Dot16)
2235 ( ( decoder->current_subfont->random & 0xFFFF ) + 1 );
2236
2237 decoder->current_subfont->random =
2238 cff_random( decoder->current_subfont->random );
2239
2240 cf2_stack_pushFixed( opStack, r );
2241 }
2242 continue; /* do not clear the stack */
2243
2244 case cf2_escMUL:
2245 {
2246 CF2_F16Dot16 factor1;
2247 CF2_F16Dot16 factor2;
2248
2249
2250 FT_TRACE4(( " mul\n" ));
2251
2252 factor2 = cf2_stack_popFixed( opStack );
2253 factor1 = cf2_stack_popFixed( opStack );
2254
2255 cf2_stack_pushFixed( opStack,
2256 FT_MulFix( factor1, factor2 ) );
2257 }
2258 continue; /* do not clear the stack */
2259
2260 case cf2_escSQRT:
2261 {
2263
2264
2265 FT_TRACE4(( " sqrt\n" ));
2266
2267 arg = cf2_stack_popFixed( opStack );
2268 if ( arg > 0 )
2269 {
2270 /* use a start value that doesn't make */
2271 /* the algorithm's addition overflow */
2272 FT_Fixed root = arg < 10 ? arg : arg >> 1;
2273 FT_Fixed new_root;
2274
2275
2276 /* Babylonian method */
2277 for (;;)
2278 {
2279 new_root = ( root + FT_DivFix( arg, root ) + 1 ) >> 1;
2280 if ( new_root == root )
2281 break;
2282 root = new_root;
2283 }
2284 arg = new_root;
2285 }
2286 else
2287 arg = 0;
2288
2289 cf2_stack_pushFixed( opStack, arg );
2290 }
2291 continue; /* do not clear the stack */
2292
2293 case cf2_escDUP:
2294 {
2296
2297
2298 FT_TRACE4(( " dup\n" ));
2299
2300 arg = cf2_stack_popFixed( opStack );
2301
2302 cf2_stack_pushFixed( opStack, arg );
2303 cf2_stack_pushFixed( opStack, arg );
2304 }
2305 continue; /* do not clear the stack */
2306
2307 case cf2_escEXCH:
2308 {
2311
2312
2313 FT_TRACE4(( " exch\n" ));
2314
2315 arg2 = cf2_stack_popFixed( opStack );
2316 arg1 = cf2_stack_popFixed( opStack );
2317
2318 cf2_stack_pushFixed( opStack, arg2 );
2319 cf2_stack_pushFixed( opStack, arg1 );
2320 }
2321 continue; /* do not clear the stack */
2322
2323 case cf2_escINDEX:
2324 {
2325 CF2_Int idx;
2326 CF2_UInt size;
2327
2328
2329 FT_TRACE4(( " index\n" ));
2330
2331 idx = cf2_stack_popInt( opStack );
2332 size = cf2_stack_count( opStack );
2333
2334 if ( size > 0 )
2335 {
2336 /* for `cf2_stack_getReal', */
2337 /* index 0 is bottom of stack */
2338 CF2_UInt gr_idx;
2339
2340
2341 if ( idx < 0 )
2342 gr_idx = size - 1;
2343 else if ( (CF2_UInt)idx >= size )
2344 gr_idx = 0;
2345 else
2346 gr_idx = size - 1 - (CF2_UInt)idx;
2347
2348 cf2_stack_pushFixed( opStack,
2349 cf2_stack_getReal( opStack,
2350 gr_idx ) );
2351 }
2352 }
2353 continue; /* do not clear the stack */
2354
2355 case cf2_escROLL:
2356 {
2357 CF2_Int idx;
2358 CF2_Int count;
2359
2360
2361 FT_TRACE4(( " roll\n" ));
2362
2363 idx = cf2_stack_popInt( opStack );
2364 count = cf2_stack_popInt( opStack );
2365
2366 cf2_stack_roll( opStack, count, idx );
2367 }
2368 continue; /* do not clear the stack */
2369
2371 if ( !font->isT1 )
2372 FT_TRACE4(( " unknown op (12, %d)\n", op2 ));
2373 else
2374 {
2375 FT_TRACE4(( " setcurrentpoint" ));
2376
2377 if ( !initial_map_ready )
2378 break;
2379
2380 /* From the T1 specification, section 6.4: */
2381 /* */
2382 /* The setcurrentpoint command is used only in */
2383 /* conjunction with results from OtherSubrs */
2384 /* procedures. */
2385
2386 /* known_othersubr_result_cnt != 0 is already handled */
2387 /* above. */
2388
2389 /* Note, however, that both Ghostscript and Adobe */
2390 /* Distiller handle this situation by silently */
2391 /* ignoring the inappropriate `setcurrentpoint' */
2392 /* instruction. So we do the same. */
2393#if 0
2394
2395 if ( decoder->flex_state != 1 )
2396 {
2397 FT_ERROR(( "cf2_interpT2CharString:"
2398 " unexpected `setcurrentpoint'\n" ));
2399 goto Syntax_Error;
2400 }
2401 else
2402 ...
2403#endif
2404
2405 curY = cf2_stack_popFixed( opStack );
2406 curX = cf2_stack_popFixed( opStack );
2407
2408 decoder->flex_state = 0;
2409 }
2410 break;
2411
2412 } /* end of 2nd switch checking op2 */
2413 }
2414 }
2415 } /* end of 1st switch checking op2 */
2416 } /* case cf2_cmdESC */
2417
2418 break;
2419
2420 case cf2_cmdHSBW:
2421 if ( !font->isT1 )
2422 FT_TRACE4(( " unknown op (%d)\n", op1 ));
2423 else
2424 {
2425 CF2_Fixed lsb_x;
2426 PS_Builder* builder;
2427
2428
2429 FT_TRACE4(( " hsbw\n" ));
2430
2431 builder = &decoder->builder;
2432
2433 builder->advance->x = cf2_stack_popFixed( opStack );
2434 builder->advance->y = 0;
2435
2436 lsb_x = cf2_stack_popFixed( opStack );
2437
2438 builder->left_bearing->x = ADD_INT32( builder->left_bearing->x,
2439 lsb_x );
2440
2441 haveWidth = TRUE;
2442
2443 /* the `metrics_only' indicates that we only want to compute */
2444 /* the glyph's metrics (lsb + advance width), not load the */
2445 /* rest of it; so exit immediately */
2446 if ( builder->metrics_only )
2447 goto exit;
2448
2449 if ( initial_map_ready )
2450 curX = ADD_INT32( curX, lsb_x );
2451 }
2452 break;
2453
2454 case cf2_cmdENDCHAR:
2455 FT_TRACE4(( " endchar\n" ));
2456
2457 if ( font->isT1 && !initial_map_ready )
2458 {
2459 FT_TRACE5(( "cf2_interpT2CharString (Type 1 mode): "
2460 "Build initial hintmap, rewinding...\n" ));
2461
2462 /* trigger initial hintmap build */
2463 cf2_glyphpath_moveTo( &glyphPath, curX, curY );
2464
2465 initial_map_ready = TRUE;
2466
2467 /* change hints routine - clear for rewind */
2468 cf2_arrstack_clear( &vStemHintArray );
2469 cf2_arrstack_clear( &hStemHintArray );
2470
2471 cf2_hintmask_init( &hintMask, error );
2472 hintMask.isValid = FALSE;
2473 hintMask.isNew = TRUE;
2474
2475 /* rewind charstring */
2476 /* some charstrings use endchar from a final subroutine call */
2477 /* without returning, detect these and exit to the top level */
2478 /* charstring */
2479 while ( charstringIndex > 0 )
2480 {
2481 FT_TRACE4(( " return (leaving level %d)\n", charstringIndex ));
2482
2483 /* restore position in previous charstring */
2484 charstring = (CF2_Buffer)
2486 &subrStack,
2487 (CF2_UInt)--charstringIndex );
2488 }
2489 charstring->ptr = charstring->start;
2490
2491 break;
2492 }
2493
2494 if ( cf2_stack_count( opStack ) == 1 ||
2495 cf2_stack_count( opStack ) == 5 )
2496 {
2497 if ( !haveWidth )
2498 *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ),
2499 nominalWidthX );
2500 }
2501
2502 /* width is defined or default after this */
2503 haveWidth = TRUE;
2504
2505 if ( decoder->width_only )
2506 goto exit;
2507
2508 /* close path if still open */
2509 cf2_glyphpath_closeOpenPath( &glyphPath );
2510
2511 /* disable seac for CFF2 and Type1 */
2512 /* (charstring ending with args on stack) */
2513 if ( !font->isCFF2 && !font->isT1 && cf2_stack_count( opStack ) > 1 )
2514 {
2515 /* must be either 4 or 5 -- */
2516 /* this is a (deprecated) implied `seac' operator */
2517
2518 CF2_Int achar;
2519 CF2_Int bchar;
2520 CF2_BufferRec component;
2521 CF2_Fixed dummyWidth; /* ignore component width */
2523
2524
2525 if ( doingSeac )
2526 {
2527 lastError = FT_THROW( Invalid_Glyph_Format );
2528 goto exit; /* nested seac */
2529 }
2530
2531 achar = cf2_stack_popInt( opStack );
2532 bchar = cf2_stack_popInt( opStack );
2533
2534 curY = cf2_stack_popFixed( opStack );
2535 curX = cf2_stack_popFixed( opStack );
2536
2537 error2 = cf2_getSeacComponent( decoder, achar, &component );
2538 if ( error2 )
2539 {
2540 lastError = error2; /* pass FreeType error through */
2541 goto exit;
2542 }
2544 &component,
2545 callbacks,
2546 translation,
2547 TRUE,
2548 curX,
2549 curY,
2550 &dummyWidth );
2551 cf2_freeSeacComponent( decoder, &component );
2552
2553 error2 = cf2_getSeacComponent( decoder, bchar, &component );
2554 if ( error2 )
2555 {
2556 lastError = error2; /* pass FreeType error through */
2557 goto exit;
2558 }
2560 &component,
2561 callbacks,
2562 translation,
2563 TRUE,
2564 0,
2565 0,
2566 &dummyWidth );
2567 cf2_freeSeacComponent( decoder, &component );
2568 }
2569 goto exit;
2570
2571 case cf2_cmdCNTRMASK:
2572 case cf2_cmdHINTMASK:
2573 /* the final \n in the tracing message gets added in */
2574 /* `cf2_hintmask_read' (which also traces the mask bytes) */
2575 FT_TRACE4(( "%s", op1 == cf2_cmdCNTRMASK ? " cntrmask" : " hintmask" ));
2576
2577 /* never add hints after the mask is computed */
2578 if ( cf2_stack_count( opStack ) > 1 &&
2579 cf2_hintmask_isValid( &hintMask ) )
2580 {
2581 FT_TRACE4(( "cf2_interpT2CharString: invalid hint mask\n" ));
2582 break;
2583 }
2584
2585 /* if there are arguments on the stack, there this is an */
2586 /* implied cf2_cmdVSTEMHM */
2588 opStack,
2589 &vStemHintArray,
2590 width,
2591 &haveWidth,
2592 0 );
2593
2594 if ( decoder->width_only )
2595 goto exit;
2596
2597 if ( op1 == cf2_cmdHINTMASK )
2598 {
2599 /* consume the hint mask bytes which follow the operator */
2600 cf2_hintmask_read( &hintMask,
2601 charstring,
2602 cf2_arrstack_size( &hStemHintArray ) +
2603 cf2_arrstack_size( &vStemHintArray ) );
2604 }
2605 else
2606 {
2607 /*
2608 * Consume the counter mask bytes which follow the operator:
2609 * Build a temporary hint map, just to place and lock those
2610 * stems participating in the counter mask. These are most
2611 * likely the dominant hstems, and are grouped together in a
2612 * few counter groups, not necessarily in correspondence
2613 * with the hint groups. This reduces the chances of
2614 * conflicts between hstems that are initially placed in
2615 * separate hint groups and then brought together. The
2616 * positions are copied back to `hStemHintArray', so we can
2617 * discard `counterMask' and `counterHintMap'.
2618 *
2619 */
2620#ifdef __REACTOS__
2621 CF2_HintMapRec *counterHintMap_allocated = malloc(sizeof(*counterHintMap_allocated));
2622 CF2_HintMaskRec counterMask;
2623 if (!counterHintMap_allocated)
2624 {
2625 lastError = FT_Err_Out_Of_Memory;
2626 goto exit;
2627 }
2628/* Ugly but it allows us to reduce the diff */
2629#define counterHintMap (*counterHintMap_allocated)
2630#else
2631 CF2_HintMapRec counterHintMap;
2632 CF2_HintMaskRec counterMask;
2633#endif
2634
2635
2636 cf2_hintmap_init( &counterHintMap,
2637 font,
2638 &glyphPath.initialHintMap,
2639 &glyphPath.hintMoves,
2640 scaleY );
2641 cf2_hintmask_init( &counterMask, error );
2642
2643 cf2_hintmask_read( &counterMask,
2644 charstring,
2645 cf2_arrstack_size( &hStemHintArray ) +
2646 cf2_arrstack_size( &vStemHintArray ) );
2647 cf2_hintmap_build( &counterHintMap,
2648 &hStemHintArray,
2649 &vStemHintArray,
2650 &counterMask,
2651 0,
2652 FALSE );
2653#ifdef __REACTOS__
2654 free(counterHintMap_allocated);
2655#undef counterHintMap
2656#endif
2657 }
2658 break;
2659
2660 case cf2_cmdRMOVETO:
2661 FT_TRACE4(( " rmoveto\n" ));
2662
2663 if ( font->isT1 && !decoder->flex_state && !haveWidth )
2664 FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
2665 " No width. Use hsbw/sbw as first op\n" ));
2666
2667 if ( cf2_stack_count( opStack ) > 2 && !haveWidth )
2668 *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ),
2669 nominalWidthX );
2670
2671 /* width is defined or default after this */
2672 haveWidth = TRUE;
2673
2674 if ( decoder->width_only )
2675 goto exit;
2676
2677 curY = ADD_INT32( curY, cf2_stack_popFixed( opStack ) );
2678 curX = ADD_INT32( curX, cf2_stack_popFixed( opStack ) );
2679
2680 if ( !decoder->flex_state )
2681 cf2_glyphpath_moveTo( &glyphPath, curX, curY );
2682
2683 break;
2684
2685 case cf2_cmdHMOVETO:
2686 FT_TRACE4(( " hmoveto\n" ));
2687
2688 if ( font->isT1 && !decoder->flex_state && !haveWidth )
2689 FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
2690 " No width. Use hsbw/sbw as first op\n" ));
2691
2692 if ( cf2_stack_count( opStack ) > 1 && !haveWidth )
2693 *width = ADD_INT32( cf2_stack_getReal( opStack, 0 ),
2694 nominalWidthX );
2695
2696 /* width is defined or default after this */
2697 haveWidth = TRUE;
2698
2699 if ( decoder->width_only )
2700 goto exit;
2701
2702 curX = ADD_INT32( curX, cf2_stack_popFixed( opStack ) );
2703
2704 if ( !decoder->flex_state )
2705 cf2_glyphpath_moveTo( &glyphPath, curX, curY );
2706
2707 break;
2708
2709 case cf2_cmdRLINECURVE:
2710 {
2711 CF2_UInt count = cf2_stack_count( opStack );
2712 CF2_UInt idx = 0;
2713
2714
2715 FT_TRACE4(( " rlinecurve\n" ));
2716
2717 while ( idx + 6 < count )
2718 {
2719 curX = ADD_INT32( curX, cf2_stack_getReal( opStack,
2720 idx + 0 ) );
2721 curY = ADD_INT32( curY, cf2_stack_getReal( opStack,
2722 idx + 1 ) );
2723
2724 cf2_glyphpath_lineTo( &glyphPath, curX, curY );
2725 idx += 2;
2726 }
2727
2728 while ( idx < count )
2729 {
2730 CF2_Fixed x1, y1, x2, y2, x3, y3;
2731
2732
2733 x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX );
2734 y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), curY );
2735 x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), x1 );
2736 y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y1 );
2737 x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), x2 );
2738 y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 5 ), y2 );
2739
2740 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
2741
2742 curX = x3;
2743 curY = y3;
2744 idx += 6;
2745 }
2746
2747 cf2_stack_clear( opStack );
2748 }
2749 continue; /* no need to clear stack again */
2750
2751 case cf2_cmdVVCURVETO:
2752 {
2753 CF2_UInt count, count1 = cf2_stack_count( opStack );
2754 CF2_UInt idx = 0;
2755
2756
2757 /* if `cf2_stack_count' isn't of the form 4n or 4n+1, */
2758 /* we enforce it by clearing the second bit */
2759 /* (and sorting the stack indexing to suit) */
2760 count = count1 & ~2U;
2761 idx += count1 - count;
2762
2763 FT_TRACE4(( " vvcurveto\n" ));
2764
2765 while ( idx < count )
2766 {
2767 CF2_Fixed x1, y1, x2, y2, x3, y3;
2768
2769
2770 if ( ( count - idx ) & 1 )
2771 {
2772 x1 = ADD_INT32( cf2_stack_getReal( opStack, idx ), curX );
2773
2774 idx++;
2775 }
2776 else
2777 x1 = curX;
2778
2779 y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curY );
2780 x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 );
2781 y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 );
2782 x3 = x2;
2783 y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y2 );
2784
2785 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
2786
2787 curX = x3;
2788 curY = y3;
2789 idx += 4;
2790 }
2791
2792 cf2_stack_clear( opStack );
2793 }
2794 continue; /* no need to clear stack again */
2795
2796 case cf2_cmdHHCURVETO:
2797 {
2798 CF2_UInt count, count1 = cf2_stack_count( opStack );
2799 CF2_UInt idx = 0;
2800
2801
2802 /* if `cf2_stack_count' isn't of the form 4n or 4n+1, */
2803 /* we enforce it by clearing the second bit */
2804 /* (and sorting the stack indexing to suit) */
2805 count = count1 & ~2U;
2806 idx += count1 - count;
2807
2808 FT_TRACE4(( " hhcurveto\n" ));
2809
2810 while ( idx < count )
2811 {
2812 CF2_Fixed x1, y1, x2, y2, x3, y3;
2813
2814
2815 if ( ( count - idx ) & 1 )
2816 {
2817 y1 = ADD_INT32( cf2_stack_getReal( opStack, idx ), curY );
2818
2819 idx++;
2820 }
2821 else
2822 y1 = curY;
2823
2824 x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX );
2825 x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 );
2826 y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 );
2827 x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), x2 );
2828 y3 = y2;
2829
2830 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
2831
2832 curX = x3;
2833 curY = y3;
2834 idx += 4;
2835 }
2836
2837 cf2_stack_clear( opStack );
2838 }
2839 continue; /* no need to clear stack again */
2840
2841 case cf2_cmdVHCURVETO:
2842 case cf2_cmdHVCURVETO:
2843 {
2844 CF2_UInt count, count1 = cf2_stack_count( opStack );
2845 CF2_UInt idx = 0;
2846
2847 FT_Bool alternate = FT_BOOL( op1 == cf2_cmdHVCURVETO );
2848
2849
2850 /* if `cf2_stack_count' isn't of the form 8n, 8n+1, */
2851 /* 8n+4, or 8n+5, we enforce it by clearing the */
2852 /* second bit */
2853 /* (and sorting the stack indexing to suit) */
2854 count = count1 & ~2U;
2855 idx += count1 - count;
2856
2857 FT_TRACE4(( "%s\n", alternate ? " hvcurveto" : " vhcurveto" ));
2858
2859 while ( idx < count )
2860 {
2861 CF2_Fixed x1, x2, x3, y1, y2, y3;
2862
2863
2864 if ( alternate )
2865 {
2866 x1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curX );
2867 y1 = curY;
2868 x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 );
2869 y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 );
2870 y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), y2 );
2871
2872 if ( count - idx == 5 )
2873 {
2874 x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), x2 );
2875
2876 idx++;
2877 }
2878 else
2879 x3 = x2;
2880
2881 alternate = FALSE;
2882 }
2883 else
2884 {
2885 x1 = curX;
2886 y1 = ADD_INT32( cf2_stack_getReal( opStack, idx + 0 ), curY );
2887 x2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 1 ), x1 );
2888 y2 = ADD_INT32( cf2_stack_getReal( opStack, idx + 2 ), y1 );
2889 x3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 3 ), x2 );
2890
2891 if ( count - idx == 5 )
2892 {
2893 y3 = ADD_INT32( cf2_stack_getReal( opStack, idx + 4 ), y2 );
2894
2895 idx++;
2896 }
2897 else
2898 y3 = y2;
2899
2900 alternate = TRUE;
2901 }
2902
2903 cf2_glyphpath_curveTo( &glyphPath, x1, y1, x2, y2, x3, y3 );
2904
2905 curX = x3;
2906 curY = y3;
2907 idx += 4;
2908 }
2909
2910 cf2_stack_clear( opStack );
2911 }
2912 continue; /* no need to clear stack again */
2913
2915 {
2916 CF2_Int v;
2917
2918 CF2_Int byte1 = cf2_buf_readByte( charstring );
2919 CF2_Int byte2 = cf2_buf_readByte( charstring );
2920
2921
2922 v = (FT_Short)( ( byte1 << 8 ) |
2923 byte2 );
2924
2925 FT_TRACE4(( " %d", v ));
2926
2927 cf2_stack_pushInt( opStack, v );
2928 }
2929 continue;
2930
2931 default:
2932 /* numbers */
2933 {
2934 if ( /* op1 >= 32 && */ op1 <= 246 )
2935 {
2936 CF2_Int v;
2937
2938
2939 v = op1 - 139;
2940
2941 FT_TRACE4(( " %d", v ));
2942
2943 /* -107 .. 107 */
2944 cf2_stack_pushInt( opStack, v );
2945 }
2946
2947 else if ( /* op1 >= 247 && */ op1 <= 250 )
2948 {
2949 CF2_Int v;
2950
2951
2952 v = op1;
2953 v -= 247;
2954 v *= 256;
2955 v += cf2_buf_readByte( charstring );
2956 v += 108;
2957
2958 FT_TRACE4(( " %d", v ));
2959
2960 /* 108 .. 1131 */
2961 cf2_stack_pushInt( opStack, v );
2962 }
2963
2964 else if ( /* op1 >= 251 && */ op1 <= 254 )
2965 {
2966 CF2_Int v;
2967
2968
2969 v = op1;
2970 v -= 251;
2971 v *= 256;
2972 v += cf2_buf_readByte( charstring );
2973 v = -v - 108;
2974
2975 FT_TRACE4(( " %d", v ));
2976
2977 /* -1131 .. -108 */
2978 cf2_stack_pushInt( opStack, v );
2979 }
2980
2981 else /* op1 == 255 */
2982 {
2983 CF2_Fixed v;
2984
2985 FT_UInt32 byte1 = (FT_UInt32)cf2_buf_readByte( charstring );
2986 FT_UInt32 byte2 = (FT_UInt32)cf2_buf_readByte( charstring );
2987 FT_UInt32 byte3 = (FT_UInt32)cf2_buf_readByte( charstring );
2988 FT_UInt32 byte4 = (FT_UInt32)cf2_buf_readByte( charstring );
2989
2990
2991 v = (CF2_Fixed)( ( byte1 << 24 ) |
2992 ( byte2 << 16 ) |
2993 ( byte3 << 8 ) |
2994 byte4 );
2995
2996 /*
2997 * For Type 1:
2998 *
2999 * According to the specification, values > 32000 or < -32000
3000 * must be followed by a `div' operator to make the result be
3001 * in the range [-32000;32000]. We expect that the second
3002 * argument of `div' is not a large number. Additionally, we
3003 * don't handle stuff like `<large1> <large2> <num> div <num>
3004 * div' or <large1> <large2> <num> div div'. This is probably
3005 * not allowed anyway.
3006 *
3007 * <large> <num> <num>+ div is not checked but should not be
3008 * allowed as the large value remains untouched.
3009 *
3010 */
3011 if ( font->isT1 )
3012 {
3013 if ( v > 32000 || v < -32000 )
3014 {
3015 if ( large_int )
3016 FT_ERROR(( "cf2_interpT2CharString (Type 1 mode):"
3017 " no `div' after large integer\n" ));
3018 else
3019 large_int = TRUE;
3020 }
3021
3022 FT_TRACE4(( " %d", v ));
3023
3024 cf2_stack_pushInt( opStack, (CF2_Int)v );
3025 }
3026 else
3027 {
3028 FT_TRACE4(( " %.5fF", v / 65536.0 ));
3029
3030 cf2_stack_pushFixed( opStack, v );
3031 }
3032 }
3033 }
3034 continue; /* don't clear stack */
3035
3036 } /* end of switch statement checking `op1' */
3037
3038 cf2_stack_clear( opStack );
3039
3040 } /* end of main interpreter loop */
3041
3042 /* we get here if the charstring ends without cf2_cmdENDCHAR */
3043 FT_TRACE4(( "cf2_interpT2CharString:"
3044 " charstring ends without ENDCHAR\n" ));
3045
3046 exit:
3047 /* check whether last error seen is also the first one */
3048 cf2_setError( error, lastError );
3049
3050 if ( *error )
3051 FT_TRACE4(( "charstring error %d\n", *error ));
3052
3053 /* free resources from objects we've used */
3054 cf2_glyphpath_finalize( &glyphPath );
3055 cf2_arrstack_finalize( &vStemHintArray );
3056 cf2_arrstack_finalize( &hStemHintArray );
3057 cf2_arrstack_finalize( &subrStack );
3058 cf2_stack_free( opStack );
3059
3060 FT_TRACE4(( "\n" ));
3061
3062#ifdef __REACTOS__
3063 free(glyphPath_allocated);
3064#undef glyphPath
3065#endif
3066
3067 return;
3068 }
3069
3070
3071/* END */
static struct _test_info results[8]
Definition: SetCursorPos.c:31
_STLP_MOVE_TO_STD_NAMESPACE void _STLP_CALL advance(_InputIterator &__i, _Distance __n)
#define free
Definition: debug_ros.c:5
#define malloc
Definition: debug_ros.c:4
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
unsigned int idx
Definition: utils.c:41
FT_DivFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:608
#define FT_SUBGLYPH_FLAG_USE_MY_METRICS
Definition: freetype.h:3967
struct FT_GlyphSlotRec_ * FT_GlyphSlot
Definition: freetype.h:548
#define FT_SUBGLYPH_FLAG_ARGS_ARE_XY_VALUES
Definition: freetype.h:3962
FT_MulFix(FT_Long a, FT_Long b)
Definition: ftcalc.c:509
return FT_Err_Ok
Definition: ftbbox.c:527
#define FIXED_TO_INT(x)
Definition: ftcalc.h:450
#define SUB_INT32(a, b)
Definition: ftcalc.h:484
#define ADD_INT32(a, b)
Definition: ftcalc.h:482
#define FT_LOCAL_DEF(x)
Definition: ftconfig.h:387
#define FT_ASSERT(condition)
Definition: ftdebug.h:239
#define FT_ERROR(varformat)
Definition: ftdebug.h:209
#define FT_TRACE5(varformat)
Definition: ftdebug.h:190
#define FT_THROW(e)
Definition: ftdebug.h:241
#define FT_TRACE4(varformat)
Definition: ftdebug.h:189
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_GlyphLoader_Prepare(FT_GlyphLoader loader)
Definition: ftgloadr.c:312
FT_GlyphLoader_CheckSubGlyphs(FT_GlyphLoader loader, FT_UInt n_subs)
Definition: ftgloadr.c:281
size_t * ft_hash_num_lookup(FT_Int num, FT_Hash hash)
Definition: fthash.c:327
FT_BEGIN_HEADER typedef signed long FT_Pos
Definition: ftimage.h:58
#define FT_ZERO(p)
Definition: ftmemory.h:237
#define FT_ABS(a)
Definition: ftobjs.h:73
#define T1_MAX_SUBRS_CALLS
Definition: ftoption.h:752
#define ft_memcpy
Definition: ftstdlib.h:82
typedefFT_BEGIN_HEADER struct FT_MemoryRec_ * FT_Memory
Definition: ftsystem.h:65
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
const GLdouble * v
Definition: gl.h:2040
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLint GLint GLsizei width
Definition: gl.h:1546
GLsizeiptr size
Definition: glext.h:5919
GLuint GLuint GLuint GLuint arg1
Definition: glext.h:9513
GLenum GLint GLuint mask
Definition: glext.h:6028
GLdouble GLdouble GLdouble GLdouble top
Definition: glext.h:10859
GLuint GLuint GLuint GLuint GLuint GLuint GLuint arg2
Definition: glext.h:9514
GLenum GLuint GLint GLenum face
Definition: glext.h:7025
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLint left
Definition: glext.h:7726
GLuint divisor
Definition: glext.h:6313
GLboolean GLenum GLenum GLvoid * values
Definition: glext.h:5666
GLuint GLfloat * val
Definition: glext.h:7180
GLfloat v0
Definition: glext.h:6061
GLfloat GLfloat v1
Definition: glext.h:6062
GLfloat GLfloat GLfloat v2
Definition: glext.h:6063
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint GLint GLint j
Definition: glfuncs.h:250
int jpeg_marker_parser_method routine
Definition: jpeglib.h:1093
#define CF2_UInt
Definition: pstypes.h:64
#define CF2_Int
Definition: pstypes.h:65
FT_Int32 CF2_F16Dot16
Definition: pstypes.h:69
#define error(str)
Definition: mkdosfs.c:1605
static char memory[1024 *256]
Definition: process.c:116
Definition: mk_font.cpp:20
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:109
#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_initLocalRegionBuffer(PS_Decoder *decoder, CF2_Int subrNum, CF2_Buffer buf)
Definition: psft.c:798
cf2_getNominalWidthX(PS_Decoder *decoder)
Definition: psft.c:860
cf2_initGlobalRegionBuffer(PS_Decoder *decoder, CF2_Int subrNum, CF2_Buffer buf)
Definition: psft.c:632
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_getSeacComponent(PS_Decoder *decoder, CF2_Int code, CF2_Buffer buf)
Definition: psft.c:660
cf2_glyphpath_moveTo(CF2_GlyphPath glyphpath, CF2_Fixed x, CF2_Fixed y)
Definition: pshints.c:1678
cf2_glyphpath_finalize(CF2_GlyphPath glyphpath)
Definition: pshints.c:1151
cf2_hintmap_build(CF2_HintMap hintmap, CF2_ArrStack hStemHintArray, CF2_ArrStack vStemHintArray, CF2_HintMask hintMask, CF2_Fixed hintOrigin, FT_Bool initialMap)
Definition: pshints.c:805
cf2_glyphpath_curveTo(CF2_GlyphPath glyphpath, CF2_Fixed x1, CF2_Fixed y1, CF2_Fixed x2, CF2_Fixed y2, CF2_Fixed x3, CF2_Fixed y3)
Definition: pshints.c:1814
cf2_glyphpath_closeOpenPath(CF2_GlyphPath glyphpath)
Definition: pshints.c:1904
cf2_glyphpath_lineTo(CF2_GlyphPath glyphpath, CF2_Fixed x, CF2_Fixed y)
Definition: pshints.c:1708
cf2_hintmap_init(CF2_HintMap hintmap, CF2_Font font, CF2_HintMap initialMap, CF2_ArrStack hintMoves, CF2_Fixed scale)
Definition: pshints.c:274
cf2_glyphpath_init(CF2_GlyphPath glyphpath, CF2_Font font, CF2_OutlineCallbacks callbacks, CF2_Fixed scaleY, CF2_ArrStack hStemHintArray, CF2_ArrStack vStemHintArray, CF2_HintMask hintMask, CF2_Fixed hintOriginY, const CF2_Blues blues, const FT_Vector *fractionalTranslation)
Definition: pshints.c:1080
cf2_hintmask_isNew(const CF2_HintMask hintmask)
Definition: psintrp.c:83
static void cf2_doFlex(CF2_Stack opStack, CF2_Fixed *curX, CF2_Fixed *curY, CF2_GlyphPath glyphPath, const FT_Bool *readFromStack, FT_Bool doConditionalLastRead)
Definition: psintrp.c:335
cf2_hintmask_getMaskPtr(CF2_HintMask hintmask)
Definition: psintrp.c:101
static size_t cf2_hintmask_setCounts(CF2_HintMask hintmask, size_t bitCount)
Definition: psintrp.c:108
static void cf2_doStems(const CF2_Font font, CF2_Stack opStack, CF2_ArrStack stemHintArray, CF2_Fixed *width, FT_Bool *haveWidth, CF2_Fixed hintOffset)
Definition: psintrp.c:281
cf2_hintmask_setAll(CF2_HintMask hintmask, size_t bitCount)
Definition: psintrp.c:173
@ 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
#define PS_STORAGE_SIZE
static void cf2_doBlend(const CFF_Blend blend, CF2_Stack opStack, CF2_UInt numBlends)
Definition: psintrp.c:418
static void cf2_hintmask_read(CF2_HintMask hintmask, CF2_Buffer charstring, size_t bitCount)
Definition: psintrp.c:131
@ 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_interpT2CharString(CF2_Font font, CF2_Buffer buf, CF2_OutlineCallbacks callbacks, const FT_Vector *translation, FT_Bool doingSeac, CF2_Fixed curX, CF2_Fixed curY, CF2_Fixed *width)
Definition: psintrp.c:471
cf2_hintmask_setNew(CF2_HintMask hintmask, FT_Bool val)
Definition: psintrp.c:90
cff_random(FT_UInt32 r)
Definition: psobjs.c:2588
ps_builder_check_points(PS_Builder *builder, FT_Int count)
Definition: psobjs.c:2208
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, CF2_Int val)
Definition: psstack.c:107
cf2_stack_popFixed(CF2_Stack stack)
Definition: psstack.c:162
cf2_stack_count(CF2_Stack stack)
Definition: psstack.c:100
cf2_stack_setReal(CF2_Stack stack, CF2_UInt idx, CF2_Fixed val)
Definition: psstack.c:212
cf2_stack_clear(CF2_Stack stack)
Definition: psstack.c:325
cf2_stack_popInt(CF2_Stack stack)
Definition: psstack.c:140
cf2_stack_pop(CF2_Stack stack, CF2_UInt num)
Definition: psstack.c:229
cf2_stack_free(CF2_Stack stack)
Definition: psstack.c:84
cf2_stack_roll(CF2_Stack stack, CF2_Int count, CF2_Int shift)
Definition: psstack.c:242
cf2_stack_init(FT_Memory memory, FT_Error *e, FT_UInt stackSize)
Definition: psstack.c:53
cf2_stack_pushFixed(CF2_Stack stack, CF2_Fixed val)
Definition: psstack.c:123
cf2_stack_getReal(CF2_Stack stack, CF2_UInt idx)
Definition: psstack.c:187
static int sum(int x_, int y_)
Definition: ptr2_test.cpp:35
static calc_node_t temp
Definition: rpn_ieee.c:38
#define error2(s, a, b)
Definition: debug.h:126
#define exit(n)
Definition: config.h:202
weight
Definition: sortkey.c:157
@ CF2_MAX_HINTS
Definition: pshints.h:47
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_Error * error
Definition: pshints.h:72
FT_Bool isValid
Definition: pshints.h:74
size_t bitCount
Definition: pshints.h:77
FT_Byte mask[(CF2_MAX_HINTS+7)/8]
Definition: pshints.h:80
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_UInt lenBV
Definition: cfftypes.h:179
FT_Int32 * BV
Definition: cfftypes.h:180
FT_SubGlyph subglyphs
Definition: freetype.h:1899
FT_UInt num_subglyphs
Definition: freetype.h:1898
FT_Slot_Internal internal
Definition: freetype.h:1909
FT_Glyph_Format format
Definition: freetype.h:1890
FT_GlyphLoader loader
Definition: ftobjs.h:427
FT_Pos x
Definition: ftimage.h:78
FT_Pos y
Definition: ftimage.h:79
FT_UInt num_designs
Definition: t1tables.h:298
FT_Fixed * weight_vector
Definition: t1tables.h:305
FT_Vector * advance
Definition: psaux.h:577
FT_Vector * left_bearing
Definition: psaux.h:576
FT_Bool metrics_only
Definition: psaux.h:584
Definition: format.c:80
t1_lookup_glyph_by_stdcharcode_ps(PS_Decoder *decoder, FT_Int charcode)
Definition: t1decode.c:133
struct T1_FaceRec_ * T1_Face
Definition: t1types.h:199
static unsigned arg_cnt(const DISPPARAMS *dp)
Definition: vbscript.h:162
static GLenum which
Definition: wgl_font.c:159
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG x2
Definition: winddi.h:3710
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG y1
Definition: winddi.h:3709
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG x1
Definition: winddi.h:3708
_In_ CLIPOBJ _In_ BRUSHOBJ _In_ LONG _In_ LONG _In_ LONG _In_ LONG y2
Definition: winddi.h:3711
void * arg
Definition: msvc.h:10
ActualNumberDriverObjects * sizeof(PDRIVER_OBJECT)) PDRIVER_OBJECT *DriverObjectList
static int callbacks
Definition: xmllint.c:838
#define const
Definition: zconf.h:233