[cff] Add early exit feature for width-only calls. This is for `FT_Get_Advance'. There are 7 places where the spec says the width can be defined: hstem/hstemhm vstem/vstemhm cntrmask/hintmask hmoveto vmoveto rmoveto endchar * src/cff/cf2intrp.c (cf2_doStems): Exit early for width-only calls, if possible. (cf2_interpT2CharString) <cf2_cmdHSTEM>, <cf2_cmdVSTEM>, <cf2_cmdVMOVETO>, <cf2_cmdENDCHAR>, <cf2_cmdHINTMASK>, <cf2_cmdRMOVETO>, <cf2_cmdHMOVETO>: Exit early for width-only calls.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189
diff --git a/ChangeLog b/ChangeLog
index 269d917..afb0060 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,26 @@
+2013-06-06 Dave Arnold <darnold@adobe.com>
+
+ [cff] Add early exit feature for width-only calls.
+
+ This is for `FT_Get_Advance'.
+
+ There are 7 places where the spec says the width can be defined:
+
+ hstem/hstemhm
+ vstem/vstemhm
+ cntrmask/hintmask
+ hmoveto
+ vmoveto
+ rmoveto
+ endchar
+
+ * src/cff/cf2intrp.c (cf2_doStems): Exit early for width-only calls,
+ if possible.
+
+ (cf2_interpT2CharString) <cf2_cmdHSTEM>, <cf2_cmdVSTEM>,
+ <cf2_cmdVMOVETO>, <cf2_cmdENDCHAR>, <cf2_cmdHINTMASK>,
+ <cf2_cmdRMOVETO>, <cf2_cmdHMOVETO>: Exit early for width-only calls.
+
2013-06-06 Werner Lemberg <wl@gnu.org>
Next round of compiler fixes.
diff --git a/src/cff/cf2intrp.c b/src/cff/cf2intrp.c
index 71a15fe..5b73e60 100644
--- a/src/cff/cf2intrp.c
+++ b/src/cff/cf2intrp.c
@@ -292,6 +292,12 @@
/* variable accumulates delta values from operand stack */
CF2_Fixed position = hintOffset;
+ if ( hasWidthArg && ! *haveWidth )
+ *width = cf2_stack_getReal( opStack, 0 ) +
+ cf2_getNominalWidthX( font->decoder );
+
+ if ( font->decoder->width_only )
+ goto exit;
for ( i = hasWidthArg ? 1 : 0; i < count; i += 2 )
{
@@ -311,13 +317,11 @@
cf2_arrstack_push( stemHintArray, &stemhint ); /* defer error check */
}
- if ( hasWidthArg && ! *haveWidth )
- *width = cf2_stack_getReal( opStack, 0 ) +
- cf2_getNominalWidthX( font->decoder );
+ cf2_stack_clear( opStack );
+ exit:
+ /* cf2_doStems must define a width (may be default) */
*haveWidth = TRUE;
-
- cf2_stack_clear( opStack );
}
@@ -507,6 +511,9 @@
* What we implement here uses the first validly specified width, but
* does not detect errors for specifying more than one width.
*
+ * If one of the above operators occurs without explicitly specifying
+ * a width, we assume the default width.
+ *
*/
haveWidth = FALSE;
*width = cf2_getDefaultWidthX( decoder );
@@ -595,6 +602,10 @@
width,
&haveWidth,
0 );
+
+ if ( font->decoder->width_only )
+ goto exit;
+
break;
case cf2_cmdVSTEMHM:
@@ -612,19 +623,28 @@
width,
&haveWidth,
0 );
+
+ if ( font->decoder->width_only )
+ goto exit;
+
break;
case cf2_cmdVMOVETO:
FT_TRACE4(( " vmoveto\n" ));
+ if ( cf2_stack_count( opStack ) > 1 && !haveWidth )
+ *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX;
+
+ /* width is defined or default after this */
+ haveWidth = TRUE;
+
+ if ( font->decoder->width_only )
+ goto exit;
+
curY += cf2_stack_popFixed( opStack );
cf2_glyphpath_moveTo( &glyphPath, curX, curY );
- if ( cf2_stack_count( opStack ) > 0 && !haveWidth )
- *width = cf2_stack_popFixed( opStack ) + nominalWidthX;
-
- haveWidth = TRUE;
break;
case cf2_cmdRLINETO:
@@ -1048,8 +1068,12 @@
*width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX;
}
+ /* width is defined or default after this */
haveWidth = TRUE;
+ if ( font->decoder->width_only )
+ goto exit;
+
/* close path if still open */
cf2_glyphpath_closeOpenPath( &glyphPath );
@@ -1133,6 +1157,9 @@
&haveWidth,
0 );
+ if ( font->decoder->width_only )
+ goto exit;
+
if ( op1 == cf2_cmdHINTMASK )
{
/* consume the hint mask bytes which follow the operator */
@@ -1183,28 +1210,38 @@
case cf2_cmdRMOVETO:
FT_TRACE4(( " rmoveto\n" ));
+ if ( cf2_stack_count( opStack ) > 2 && !haveWidth )
+ *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX;
+
+ /* width is defined or default after this */
+ haveWidth = TRUE;
+
+ if ( font->decoder->width_only )
+ goto exit;
+
curY += cf2_stack_popFixed( opStack );
curX += cf2_stack_popFixed( opStack );
cf2_glyphpath_moveTo( &glyphPath, curX, curY );
- if ( cf2_stack_count( opStack ) > 0 && !haveWidth )
- *width = cf2_stack_popFixed( opStack ) + nominalWidthX;
-
- haveWidth = TRUE;
break;
case cf2_cmdHMOVETO:
FT_TRACE4(( " hmoveto\n" ));
+ if ( cf2_stack_count( opStack ) > 1 && !haveWidth )
+ *width = cf2_stack_getReal( opStack, 0 ) + nominalWidthX;
+
+ /* width is defined or default after this */
+ haveWidth = TRUE;
+
+ if ( font->decoder->width_only )
+ goto exit;
+
curX += cf2_stack_popFixed( opStack );
cf2_glyphpath_moveTo( &glyphPath, curX, curY );
- if ( cf2_stack_count( opStack ) > 0 && !haveWidth )
- *width = cf2_stack_popFixed( opStack ) + nominalWidthX;
-
- haveWidth = TRUE;
break;
case cf2_cmdRLINECURVE: