summaryrefslogtreecommitdiffstats
path: root/src/cff
diff options
context:
space:
mode:
Diffstat (limited to 'src/cff')
-rw-r--r--src/cff/cffdrivr.c40
-rw-r--r--src/cff/cffgload.c493
-rw-r--r--src/cff/cffgload.h3
-rw-r--r--src/cff/cffload.c9
-rw-r--r--src/cff/cffload.h5
-rw-r--r--src/cff/cffobjs.c243
-rw-r--r--src/cff/cffparse.c13
7 files changed, 463 insertions, 343 deletions
diff --git a/src/cff/cffdrivr.c b/src/cff/cffdrivr.c
index 68de8dc..286c0b3 100644
--- a/src/cff/cffdrivr.c
+++ b/src/cff/cffdrivr.c
@@ -4,7 +4,7 @@
/* */
/* OpenType font driver implementation (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -38,6 +38,7 @@
#include FT_SERVICE_XFREE86_NAME_H
#include FT_SERVICE_GLYPH_DICT_H
+
/*************************************************************************/
/* */
/* The macro FT_COMPONENT is used in trace mode. It is an implicit */
@@ -186,36 +187,39 @@
}
- FT_CALLBACK_DEF(FT_Error)
- cff_get_advances( FT_Face ftface,
+ FT_CALLBACK_DEF( FT_Error )
+ cff_get_advances( FT_Face face,
FT_UInt start,
FT_UInt count,
- FT_UInt flags,
+ FT_Int32 flags,
FT_Fixed* advances )
{
- CFF_Face face = (CFF_Face) ftface;
FT_UInt nn;
- FT_Error error = 0;
- FT_GlyphSlot slot = face->root.glyph;
+ FT_Error error = CFF_Err_Ok;
+ FT_GlyphSlot slot = face->glyph;
+
flags |= FT_LOAD_ADVANCE_ONLY;
- for (nn = 0; nn < count; nn++)
+ for ( nn = 0; nn < count; nn++ )
{
- error = Load_Glyph( slot, face->root.size, start+nn, flags );
- if (error) break;
+ error = Load_Glyph( slot, face->size, start + nn, flags );
+ if ( error )
+ break;
- advances[nn] = (flags & FT_LOAD_VERTICAL_LAYOUT)
- ? slot->advance.y
- : slot->advance.x;
+ advances[nn] = ( flags & FT_LOAD_VERTICAL_LAYOUT )
+ ? slot->linearVertAdvance
+ : slot->linearHoriAdvance;
}
+
return error;
}
- /*
- * GLYPH DICT SERVICE
- *
- */
+
+ /*
+ * GLYPH DICT SERVICE
+ *
+ */
static FT_Error
cff_get_glyph_name( CFF_Face face,
@@ -376,6 +380,7 @@
static const FT_Service_PsInfoRec cff_service_ps_info =
{
(PS_GetFontInfoFunc) cff_ps_get_font_info,
+ (PS_GetFontExtraFunc) NULL,
(PS_HasGlyphNamesFunc) cff_ps_has_glyph_names,
(PS_GetFontPrivateFunc)NULL /* unsupported with CFF fonts */
};
@@ -421,6 +426,7 @@
cmap_info->language = 0;
+ cmap_info->format = 0;
if ( cmap->clazz != &cff_cmap_encoding_class_rec &&
cmap->clazz != &cff_cmap_unicode_class_rec )
diff --git a/src/cff/cffgload.c b/src/cff/cffgload.c
index 3296d12..c64c6f4 100644
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -110,8 +110,11 @@
cff_op_callgsubr,
cff_op_return,
- cff_op_hsbw, /* Type 1 opcode: invalid but seen in real life */
- cff_op_closepath, /* ditto */
+ /* Type 1 opcodes: invalid but seen in real life */
+ cff_op_hsbw,
+ cff_op_closepath,
+ cff_op_callothersubr,
+ cff_op_pop,
/* do not remove */
cff_op_max
@@ -123,6 +126,11 @@
#define CFF_COUNT_EXACT 0x40
#define CFF_COUNT_CLEAR_STACK 0x20
+ /* count values which have the `CFF_COUNT_CHECK_WIDTH' flag set are */
+ /* used for checking the width and requested numbers of arguments */
+ /* only; they are set to zero afterwards */
+
+ /* the other two flags are informative only and unused currently */
static const FT_Byte cff_argument_counts[] =
{
@@ -193,6 +201,8 @@
0,
2, /* hsbw */
+ 0,
+ 0,
0
};
@@ -379,11 +389,6 @@
decoder->hint_mode = hint_mode;
}
- FT_LOCAL_DEF( void )
- cff_decoder_set_width_only( CFF_Decoder* decoder )
- {
- decoder->width_only = 1;
- }
/* this function is used to select the subfont */
/* and the locals subrs array */
@@ -411,7 +416,10 @@
goto Exit;
}
+ FT_TRACE4(( "glyph index %d (subfont %d):\n", glyph_index, fd_index ));
+
sub = cff->subfonts[fd_index];
+
if ( builder->hints_funcs )
{
CFF_Internal internal = (CFF_Internal)size->root.internal;
@@ -421,6 +429,10 @@
builder->hints_globals = (void *)internal->subfonts[fd_index];
}
}
+#ifdef FT_DEBUG_LEVEL_TRACE
+ else
+ FT_TRACE4(( "glyph index %d:\n", glyph_index ));
+#endif
decoder->num_locals = sub->num_local_subrs;
decoder->locals = sub->local_subrs;
@@ -948,6 +960,11 @@
}
else
{
+ /* The specification says that normally arguments are to be taken */
+ /* from the bottom of the stack. However, this seems not to be */
+ /* correct, at least for Acroread 7.0.8 on GNU/Linux: It pops the */
+ /* arguments similar to a PS interpreter. */
+
FT_Fixed* args = decoder->top;
FT_Int num_args = (FT_Int)( args - decoder->stack );
FT_Int req_args;
@@ -1032,6 +1049,12 @@
case 15:
op = cff_op_eq;
break;
+ case 16:
+ op = cff_op_callothersubr;
+ break;
+ case 17:
+ op = cff_op_pop;
+ break;
case 18:
op = cff_op_drop;
break;
@@ -1134,6 +1157,7 @@
default:
;
}
+
if ( op == cff_op_unknown )
goto Syntax_Error;
@@ -1141,8 +1165,6 @@
req_args = cff_argument_counts[op];
if ( req_args & CFF_COUNT_CHECK_WIDTH )
{
- args = stack;
-
if ( num_args > 0 && decoder->read_width )
{
/* If `nominal_width' is non-zero, the number is really a */
@@ -1176,7 +1198,7 @@
case cff_op_endchar:
/* If there is a width specified for endchar, we either have */
/* 1 argument or 5 arguments. We like to argue. */
- set_width_ok = ( ( num_args == 5 ) || ( num_args == 1 ) );
+ set_width_ok = ( num_args == 5 ) || ( num_args == 1 );
break;
default:
@@ -1189,15 +1211,14 @@
decoder->glyph_width = decoder->nominal_width +
( stack[0] >> 16 );
- if (decoder->width_only)
+ if ( decoder->width_only )
{
- /* we only want the advance width, stop here */
+ /* we only want the advance width; stop here */
break;
}
/* Consumed an argument. */
num_args--;
- args++;
}
}
@@ -1211,6 +1232,14 @@
args -= req_args;
num_args -= req_args;
+ /* At this point, `args' points to the first argument of the */
+ /* operand in case `req_args' isn't zero. Otherwise, we have */
+ /* to adjust `args' manually. */
+
+ /* Note that we only pop arguments from the stack which we */
+ /* really need and can digest so that we can continue in case */
+ /* of superfluous stack elements. */
+
switch ( op )
{
case cff_op_hstem:
@@ -1218,15 +1247,16 @@
case cff_op_hstemhm:
case cff_op_vstemhm:
/* the number of arguments is always even here */
- FT_TRACE4(( op == cff_op_hstem ? " hstem" :
- ( op == cff_op_vstem ? " vstem" :
- ( op == cff_op_hstemhm ? " hstemhm" : " vstemhm" ) ) ));
+ FT_TRACE4((
+ op == cff_op_hstem ? " hstem\n" :
+ ( op == cff_op_vstem ? " vstem\n" :
+ ( op == cff_op_hstemhm ? " hstemhm\n" : " vstemhm\n" ) ) ));
if ( hinter )
hinter->stems( hinter->hints,
( op == cff_op_hstem || op == cff_op_hstemhm ),
num_args / 2,
- args );
+ args - ( num_args & ~1 ) );
decoder->num_hints += num_args / 2;
args = stack;
@@ -1246,7 +1276,7 @@
hinter->stems( hinter->hints,
0,
num_args / 2,
- args );
+ args - ( num_args & ~1 ) );
decoder->num_hints += num_args / 2;
}
@@ -1269,12 +1299,14 @@
FT_UInt maskbyte;
- FT_TRACE4(( " " ));
+ FT_TRACE4(( " (maskbytes: " ));
for ( maskbyte = 0;
maskbyte < (FT_UInt)(( decoder->num_hints + 7 ) >> 3);
maskbyte++, ip++ )
FT_TRACE4(( "0x%02X", *ip ));
+
+ FT_TRACE4(( ")\n" ));
}
#else
ip += ( decoder->num_hints + 7 ) >> 3;
@@ -1285,44 +1317,44 @@
break;
case cff_op_rmoveto:
- FT_TRACE4(( " rmoveto" ));
+ FT_TRACE4(( " rmoveto\n" ));
cff_builder_close_contour( builder );
builder->path_begun = 0;
- x += args[0];
- y += args[1];
+ x += args[-2];
+ y += args[-1];
args = stack;
break;
case cff_op_vmoveto:
- FT_TRACE4(( " vmoveto" ));
+ FT_TRACE4(( " vmoveto\n" ));
cff_builder_close_contour( builder );
builder->path_begun = 0;
- y += args[0];
+ y += args[-1];
args = stack;
break;
case cff_op_hmoveto:
- FT_TRACE4(( " hmoveto" ));
+ FT_TRACE4(( " hmoveto\n" ));
cff_builder_close_contour( builder );
builder->path_begun = 0;
- x += args[0];
+ x += args[-1];
args = stack;
break;
case cff_op_rlineto:
- FT_TRACE4(( " rlineto" ));
+ FT_TRACE4(( " rlineto\n" ));
if ( cff_builder_start_point ( builder, x, y ) ||
check_points( builder, num_args / 2 ) )
goto Fail;
- if ( num_args < 2 || num_args & 1 )
+ if ( num_args < 2 )
goto Stack_Underflow;
- args = stack;
+ args -= num_args & ~1;
while ( args < decoder->top )
{
x += args[0];
@@ -1339,8 +1371,11 @@
FT_Int phase = ( op == cff_op_hlineto );
- FT_TRACE4(( op == cff_op_hlineto ? " hlineto"
- : " vlineto" ));
+ FT_TRACE4(( op == cff_op_hlineto ? " hlineto\n"
+ : " vlineto\n" ));
+
+ if ( num_args < 1 )
+ goto Stack_Underflow;
if ( cff_builder_start_point ( builder, x, y ) ||
check_points( builder, num_args ) )
@@ -1365,125 +1400,164 @@
break;
case cff_op_rrcurveto:
- FT_TRACE4(( " rrcurveto" ));
+ {
+ FT_Int nargs;
- /* check number of arguments; must be a multiple of 6 */
- if ( num_args % 6 != 0 )
- goto Stack_Underflow;
- if ( cff_builder_start_point ( builder, x, y ) ||
- check_points( builder, num_args / 2 ) )
- goto Fail;
+ FT_TRACE4(( " rrcurveto\n" ));
- args = stack;
- while ( args < decoder->top )
- {
- x += args[0];
- y += args[1];
- cff_builder_add_point( builder, x, y, 0 );
- x += args[2];
- y += args[3];
- cff_builder_add_point( builder, x, y, 0 );
- x += args[4];
- y += args[5];
- cff_builder_add_point( builder, x, y, 1 );
- args += 6;
+ if ( num_args < 6 )
+ goto Stack_Underflow;
+
+ nargs = num_args - num_args % 6;
+
+ if ( cff_builder_start_point ( builder, x, y ) ||
+ check_points( builder, nargs / 2 ) )
+ goto Fail;
+
+ args -= nargs;
+ while ( args < decoder->top )
+ {
+ x += args[0];
+ y += args[1];
+ cff_builder_add_point( builder, x, y, 0 );
+ x += args[2];
+ y += args[3];
+ cff_builder_add_point( builder, x, y, 0 );
+ x += args[4];
+ y += args[5];
+ cff_builder_add_point( builder, x, y, 1 );
+ args += 6;
+ }
+ args = stack;
}
- args = stack;
break;
case cff_op_vvcurveto:
- FT_TRACE4(( " vvcurveto" ));
+ {
+ FT_Int nargs;
- if ( cff_builder_start_point( builder, x, y ) )
- goto Fail;
- args = stack;
- if ( num_args & 1 )
- {
- x += args[0];
- args++;
- num_args--;
- }
+ FT_TRACE4(( " vvcurveto\n" ));
- if ( num_args % 4 != 0 )
- goto Stack_Underflow;
+ if ( num_args < 4 )
+ goto Stack_Underflow;
- if ( check_points( builder, 3 * ( num_args / 4 ) ) )
- goto Fail;
+ /* if num_args isn't of the form 4n or 4n+1, */
+ /* we reduce it to 4n+1 */
- while ( args < decoder->top )
- {
- y += args[0];
- cff_builder_add_point( builder, x, y, 0 );
- x += args[1];
- y += args[2];
- cff_builder_add_point( builder, x, y, 0 );
- y += args[3];
- cff_builder_add_point( builder, x, y, 1 );
- args += 4;
+ nargs = num_args - num_args % 4;
+ if ( num_args - nargs > 0 )
+ nargs += 1;
+
+ if ( cff_builder_start_point( builder, x, y ) )
+ goto Fail;
+
+ args -= nargs;
+
+ if ( nargs & 1 )
+ {
+ x += args[0];
+ args++;
+ nargs--;
+ }
+
+ if ( check_points( builder, 3 * ( nargs / 4 ) ) )
+ goto Fail;
+
+ while ( args < decoder->top )
+ {
+ y += args[0];
+ cff_builder_add_point( builder, x, y, 0 );
+ x += args[1];
+ y += args[2];
+ cff_builder_add_point( builder, x, y, 0 );
+ y += args[3];
+ cff_builder_add_point( builder, x, y, 1 );
+ args += 4;
+ }
+ args = stack;
}
- args = stack;
break;
case cff_op_hhcurveto:
- FT_TRACE4(( " hhcurveto" ));
+ {
+ FT_Int nargs;
- if ( cff_builder_start_point( builder, x, y ) )
- goto Fail;
- args = stack;
- if ( num_args & 1 )
- {
- y += args[0];
- args++;
- num_args--;
- }
+ FT_TRACE4(( " hhcurveto\n" ));
- if ( num_args % 4 != 0 )
- goto Stack_Underflow;
+ if ( num_args < 4 )
+ goto Stack_Underflow;
- if ( check_points( builder, 3 * ( num_args / 4 ) ) )
- goto Fail;
+ /* if num_args isn't of the form 4n or 4n+1, */
+ /* we reduce it to 4n+1 */
- while ( args < decoder->top )
- {
- x += args[0];
- cff_builder_add_point( builder, x, y, 0 );
- x += args[1];
- y += args[2];
- cff_builder_add_point( builder, x, y, 0 );
- x += args[3];
- cff_builder_add_point( builder, x, y, 1 );
- args += 4;
+ nargs = num_args - num_args % 4;
+ if ( num_args - nargs > 0 )
+ nargs += 1;
+
+ if ( cff_builder_start_point( builder, x, y ) )
+ goto Fail;
+
+ args -= nargs;
+ if ( nargs & 1 )
+ {
+ y += args[0];
+ args++;
+ nargs--;
+ }
+
+ if ( check_points( builder, 3 * ( nargs / 4 ) ) )
+ goto Fail;
+
+ while ( args < decoder->top )
+ {
+ x += args[0];
+ cff_builder_add_point( builder, x, y, 0 );
+ x += args[1];
+ y += args[2];
+ cff_builder_add_point( builder, x, y, 0 );
+ x += args[3];
+ cff_builder_add_point( builder, x, y, 1 );
+ args += 4;
+ }
+ args = stack;
}
- args = stack;
break;
case cff_op_vhcurveto:
case cff_op_hvcurveto:
{
FT_Int phase;
+ FT_Int nargs;
- FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto"
- : " hvcurveto" ));
+ FT_TRACE4(( op == cff_op_vhcurveto ? " vhcurveto\n"
+ : " hvcurveto\n" ));
if ( cff_builder_start_point( builder, x, y ) )
goto Fail;
- args = stack;
- if ( num_args < 4 || ( num_args % 4 ) > 1 )
+ if ( num_args < 4 )
goto Stack_Underflow;
- if ( check_points( builder, ( num_args / 4 ) * 3 ) )
+ /* if num_args isn't of the form 8n, 8n+1, 8n+4, or 8n+5, */
+ /* we reduce it to the largest one which fits */
+
+ nargs = num_args - num_args % 4;
+ if ( num_args - nargs > 0 )
+ nargs += 1;
+
+ args -= nargs;
+ if ( check_points( builder, ( nargs / 4 ) * 3 ) )
goto Stack_Underflow;
phase = ( op == cff_op_hvcurveto );
- while ( num_args >= 4 )
+ while ( nargs >= 4 )
{
- num_args -= 4;
+ nargs -= 4;
if ( phase )
{
x += args[0];
@@ -1492,7 +1566,7 @@
y += args[2];
cff_builder_add_point( builder, x, y, 0 );
y += args[3];
- if ( num_args == 1 )
+ if ( nargs == 1 )
x += args[4];
cff_builder_add_point( builder, x, y, 1 );
}
@@ -1504,7 +1578,7 @@
y += args[2];
cff_builder_add_point( builder, x, y, 0 );
x += args[3];
- if ( num_args == 1 )
+ if ( nargs == 1 )
y += args[4];
cff_builder_add_point( builder, x, y, 1 );
}
@@ -1517,19 +1591,23 @@
case cff_op_rlinecurve:
{
- FT_Int num_lines = ( num_args - 6 ) / 2;
+ FT_Int num_lines;
+ FT_Int nargs;
- FT_TRACE4(( " rlinecurve" ));
+ FT_TRACE4(( " rlinecurve\n" ));
- if ( num_args < 8 || ( num_args - 6 ) & 1 )
+ if ( num_args < 8 )
goto Stack_Underflow;
+ nargs = num_args & ~1;
+ num_lines = ( nargs - 6 ) / 2;
+
if ( cff_builder_start_point( builder, x, y ) ||
check_points( builder, num_lines + 3 ) )
goto Fail;
- args = stack;
+ args -= nargs;
/* first, add the line segments */
while ( num_lines > 0 )
@@ -1557,19 +1635,24 @@
case cff_op_rcurveline:
{
- FT_Int num_curves = ( num_args - 2 ) / 6;
+ FT_Int num_curves;
+ FT_Int nargs;
- FT_TRACE4(( " rcurveline" ));
+ FT_TRACE4(( " rcurveline\n" ));
- if ( num_args < 8 || ( num_args - 2 ) % 6 )
+ if ( num_args < 8 )
goto Stack_Underflow;
+ nargs = num_args - 2;
+ nargs = nargs - nargs % 6 + 2;
+ num_curves = ( nargs - 2 ) / 6;
+
if ( cff_builder_start_point ( builder, x, y ) ||
- check_points( builder, num_curves*3 + 2 ) )
+ check_points( builder, num_curves * 3 + 2 ) )
goto Fail;
- args = stack;
+ args -= nargs;
/* first, add the curves */
while ( num_curves > 0 )
@@ -1600,18 +1683,16 @@
FT_Pos start_y;
- FT_TRACE4(( " hflex1" ));
-
- args = stack;
+ FT_TRACE4(( " hflex1\n" ));
- /* adding five more points; 4 control points, 1 on-curve point */
- /* make sure we have enough space for the start point if it */
+ /* adding five more points: 4 control points, 1 on-curve point */
+ /* -- make sure we have enough space for the start point if it */
/* needs to be added */
if ( cff_builder_start_point( builder, x, y ) ||
check_points( builder, 6 ) )
goto Fail;
- /* Record the starting point's y position for later use */
+ /* record the starting point's y position for later use */
start_y = y;
/* first control point */
@@ -1653,9 +1734,7 @@
FT_Pos start_y;
- FT_TRACE4(( " hflex" ));
-
- args = stack;
+ FT_TRACE4(( " hflex\n" ));
/* adding six more points; 4 control points, 2 on-curve points */
if ( cff_builder_start_point( builder, x, y ) ||
@@ -1700,14 +1779,15 @@
case cff_op_flex1:
{
- FT_Pos start_x, start_y; /* record start x, y values for */
- /* alter use */
- FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */
- /* algorithm below */
- FT_Int horizontal, count;
+ FT_Pos start_x, start_y; /* record start x, y values for */
+ /* alter use */
+ FT_Fixed dx = 0, dy = 0; /* used in horizontal/vertical */
+ /* algorithm below */
+ FT_Int horizontal, count;
+ FT_Fixed* temp;
- FT_TRACE4(( " flex1" ));
+ FT_TRACE4(( " flex1\n" ));
/* adding six more points; 4 control points, 2 on-curve points */
if ( cff_builder_start_point( builder, x, y ) ||
@@ -1721,21 +1801,20 @@
/* XXX: figure out whether this is supposed to be a horizontal */
/* or vertical flex; the Type 2 specification is vague... */
- args = stack;
+ temp = args;
/* grab up to the last argument */
for ( count = 5; count > 0; count-- )
{
- dx += args[0];
- dy += args[1];
- args += 2;
+ dx += temp[0];
+ dy += temp[1];
+ temp += 2;
}
- /* rewind */
- args = stack;
-
- if ( dx < 0 ) dx = -dx;
- if ( dy < 0 ) dy = -dy;
+ if ( dx < 0 )
+ dx = -dx;
+ if ( dy < 0 )
+ dy = -dy;
/* strange test, but here it is... */
horizontal = ( dx > dy );
@@ -1744,7 +1823,8 @@
{
x += args[0];
y += args[1];
- cff_builder_add_point( builder, x, y, (FT_Bool)( count == 3 ) );
+ cff_builder_add_point( builder, x, y,
+ (FT_Bool)( count == 3 ) );
args += 2;
}
@@ -1771,13 +1851,12 @@
FT_UInt count;
- FT_TRACE4(( " flex" ));
+ FT_TRACE4(( " flex\n" ));
if ( cff_builder_start_point( builder, x, y ) ||
check_points( builder, 6 ) )
goto Fail;
- args = stack;
for ( count = 6; count > 0; count-- )
{
x += args[0];
@@ -1792,21 +1871,20 @@
break;
case cff_op_endchar:
- FT_TRACE4(( " endchar" ));
+ FT_TRACE4(( " endchar\n" ));
/* We are going to emulate the seac operator. */
- if ( num_args == 4 )
+ if ( num_args >= 4 )
{
/* Save glyph width so that the subglyphs don't overwrite it. */
FT_Pos glyph_width = decoder->glyph_width;
error = cff_operator_seac( decoder,
- args[0],
- args[1],
- (FT_Int)( args[2] >> 16 ),
- (FT_Int)( args[3] >> 16 ) );
- args += 4;
+ args[-4],
+ args[-3],
+ (FT_Int)( args[-2] >> 16 ),
+ (FT_Int)( args[-1] >> 16 ) );
decoder->glyph_width = glyph_width;
}
@@ -1836,11 +1914,11 @@
}
/* return now! */
- FT_TRACE4(( "\n\n" ));
+ FT_TRACE4(( "\n" ));
return error;
case cff_op_abs:
- FT_TRACE4(( " abs" ));
+ FT_TRACE4(( " abs\n" ));
if ( args[0] < 0 )
args[0] = -args[0];
@@ -1848,28 +1926,28 @@
break;
case cff_op_add:
- FT_TRACE4(( " add" ));
+ FT_TRACE4(( " add\n" ));
args[0] += args[1];
args++;
break;
case cff_op_sub:
- FT_TRACE4(( " sub" ));
+ FT_TRACE4(( " sub\n" ));
args[0] -= args[1];
args++;
break;
case cff_op_div:
- FT_TRACE4(( " div" ));
+ FT_TRACE4(( " div\n" ));
args[0] = FT_DivFix( args[0], args[1] );
args++;
break;
case cff_op_neg:
- FT_TRACE4(( " neg" ));
+ FT_TRACE4(( " neg\n" ));
args[0] = -args[0];
args++;
@@ -1880,7 +1958,7 @@
FT_Fixed Rand;
- FT_TRACE4(( " rand" ));
+ FT_TRACE4(( " rand\n" ));
Rand = seed;
if ( Rand >= 0x8000L )
@@ -1895,14 +1973,14 @@
break;
case cff_op_mul:
- FT_TRACE4(( " mul" ));
+ FT_TRACE4(( " mul\n" ));
args[0] = FT_MulFix( args[0], args[1] );
args++;
break;
case cff_op_sqrt:
- FT_TRACE4(( " sqrt" ));
+ FT_TRACE4(( " sqrt\n" ));
if ( args[0] > 0 )
{
@@ -1927,7 +2005,7 @@
case cff_op_drop:
/* nothing */
- FT_TRACE4(( " drop" ));
+ FT_TRACE4(( " drop\n" ));
break;
@@ -1936,7 +2014,7 @@
FT_Fixed tmp;
- FT_TRACE4(( " exch" ));
+ FT_TRACE4(( " exch\n" ));
tmp = args[0];
args[0] = args[1];
@@ -1950,7 +2028,7 @@
FT_Int idx = (FT_Int)( args[0] >> 16 );
- FT_TRACE4(( " index" ));
+ FT_TRACE4(( " index\n" ));
if ( idx < 0 )
idx = 0;
@@ -1967,7 +2045,7 @@
FT_Int idx = (FT_Int)( args[1] >> 16 );
- FT_TRACE4(( " roll" ));
+ FT_TRACE4(( " roll\n" ));
if ( count <= 0 )
count = 1;
@@ -2009,7 +2087,7 @@
break;
case cff_op_dup:
- FT_TRACE4(( " dup" ));
+ FT_TRACE4(( " dup\n" ));
args[1] = args[0];
args++;
@@ -2021,7 +2099,7 @@
FT_Int idx = (FT_Int)( args[1] >> 16 );
- FT_TRACE4(( " put" ));
+ FT_TRACE4(( " put\n" ));
if ( idx >= 0 && idx < decoder->len_buildchar )
decoder->buildchar[idx] = val;
@@ -2034,7 +2112,7 @@
FT_Fixed val = 0;
- FT_TRACE4(( " get" ));
+ FT_TRACE4(( " get\n" ));
if ( idx >= 0 && idx < decoder->len_buildchar )
val = decoder->buildchar[idx];
@@ -2045,18 +2123,18 @@
break;
case cff_op_store:
- FT_TRACE4(( " store "));
+ FT_TRACE4(( " store\n"));
goto Unimplemented;
case cff_op_load:
- FT_TRACE4(( " load" ));
+ FT_TRACE4(( " load\n" ));
goto Unimplemented;
case cff_op_dotsection:
/* this operator is deprecated and ignored by the parser */
- FT_TRACE4(( " dotsection" ));
+ FT_TRACE4(( " dotsection\n" ));
break;
case cff_op_closepath:
@@ -2064,7 +2142,7 @@
/* exist fonts which are incorrectly converted from probably */
/* Type 1 to CFF, and some parsers seem to accept it */
- FT_TRACE4(( " closepath (invalid op)" ));
+ FT_TRACE4(( " closepath (invalid op)\n" ));
args = stack;
break;
@@ -2074,7 +2152,7 @@
/* exist fonts which are incorrectly converted from probably */
/* Type 1 to CFF, and some parsers seem to accept it */
- FT_TRACE4(( " hsbw (invalid op)" ));
+ FT_TRACE4(( " hsbw (invalid op)\n" ));
decoder->glyph_width = decoder->nominal_width +
(args[1] >> 16);
@@ -2083,12 +2161,33 @@
args = stack;
break;
+ case cff_op_callothersubr:
+ /* this is an invalid Type 2 operator; however, there */
+ /* exist fonts which are incorrectly converted from probably */
+ /* Type 1 to CFF, and some parsers seem to accept it */
+
+ FT_TRACE4(( " callothersubr (invalid op)\n" ));
+
+ /* don't modify stack; handle the subr as `unknown' so that */
+ /* following `pop' operands use the arguments on stack */
+ break;
+
+ case cff_op_pop:
+ /* this is an invalid Type 2 operator; however, there */
+ /* exist fonts which are incorrectly converted from probably */
+ /* Type 1 to CFF, and some parsers seem to accept it */
+
+ FT_TRACE4(( " pop (invalid op)\n" ));
+
+ args++;
+ break;
+
case cff_op_and:
{
FT_Fixed cond = args[0] && args[1];
- FT_TRACE4(( " and" ));
+ FT_TRACE4(( " and\n" ));
args[0] = cond ? 0x10000L : 0;
args++;
@@ -2100,7 +2199,7 @@
FT_Fixed cond = args[0] || args[1];
- FT_TRACE4(( " or" ));
+ FT_TRACE4(( " or\n" ));
args[0] = cond ? 0x10000L : 0;
args++;
@@ -2112,7 +2211,7 @@
FT_Fixed cond = !args[0];
- FT_TRACE4(( " eq" ));
+ FT_TRACE4(( " eq\n" ));
args[0] = cond ? 0x10000L : 0;
args++;
@@ -2124,7 +2223,7 @@
FT_Fixed cond = ( args[2] <= args[3] );
- FT_TRACE4(( " ifelse" ));
+ FT_TRACE4(( " ifelse\n" ));
if ( !cond )
args[0] = args[1];
@@ -2138,7 +2237,7 @@
decoder->locals_bias );
- FT_TRACE4(( " callsubr(%d)", idx ));
+ FT_TRACE4(( " callsubr(%d)\n", idx ));
if ( idx >= decoder->num_locals )
{
@@ -2180,7 +2279,7 @@
decoder->globals_bias );
- FT_TRACE4(( " callgsubr(%d)", idx ));
+ FT_TRACE4(( " callgsubr(%d)\n", idx ));
if ( idx >= decoder->num_globals )
{
@@ -2217,7 +2316,7 @@
break;
case cff_op_return:
- FT_TRACE4(( " return" ));
+ FT_TRACE4(( " return\n" ));
if ( decoder->zone <= decoder->zones )
{
@@ -2255,15 +2354,15 @@
return error;
Syntax_Error:
- FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error!" ));
+ FT_TRACE4(( "cff_decoder_parse_charstrings: syntax error!\n" ));
return CFF_Err_Invalid_File_Format;
Stack_Underflow:
- FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow!" ));
+ FT_TRACE4(( "cff_decoder_parse_charstrings: stack underflow!\n" ));
return CFF_Err_Too_Few_Arguments;
Stack_Overflow:
- FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow!" ));
+ FT_TRACE4(( "cff_decoder_parse_charstrings: stack overflow!\n" ));
return CFF_Err_Stack_Overflow;
}
@@ -2351,13 +2450,14 @@
{
FT_Error error;
CFF_Decoder decoder;
- TT_Face face = (TT_Face)glyph->root.face;
+ TT_Face face = (TT_Face)glyph->root.face;
FT_Bool hinting, force_scaling;
- CFF_Font cff = (CFF_Font)face->extra.data;
+ CFF_Font cff = (CFF_Font)face->extra.data;
FT_Matrix font_matrix;
FT_Vector font_offset;
+
force_scaling = FALSE;
/* in a CID-keyed font, consider `glyph_index' as a CID and map */
@@ -2366,9 +2466,14 @@
if ( cff->top_font.font_dict.cid_registry != 0xFFFFU &&
cff->charset.cids )
{
- glyph_index = cff_charset_cid_to_gindex( &cff->charset, glyph_index );
- if ( glyph_index == 0 )
- return CFF_Err_Invalid_Argument;
+ /* don't handle CID 0 (.notdef) which is directly mapped to GID 0 */
+ if ( glyph_index != 0 )
+ {
+ glyph_index = cff_charset_cid_to_gindex( &cff->charset,
+ glyph_index );
+ if ( glyph_index == 0 )
+ return CFF_Err_Invalid_Argument;
+ }
}
else if ( glyph_index >= cff->num_glyphs )
return CFF_Err_Invalid_Argument;
@@ -2497,11 +2602,11 @@
cff_decoder_init( &decoder, face, size, glyph, hinting,
FT_LOAD_TARGET_MODE( load_flags ) );
- if ((load_flags & FT_LOAD_ADVANCE_ONLY) != 0)
- cff_decoder_set_width_only( &decoder );
+ if ( load_flags & FT_LOAD_ADVANCE_ONLY )
+ decoder.width_only = TRUE;
decoder.builder.no_recurse =
- (FT_Bool)( ( load_flags & FT_LOAD_NO_RECURSE ) != 0 );
+ (FT_Bool)( load_flags & FT_LOAD_NO_RECURSE );
/* now load the unscaled outline */
error = cff_get_glyph_data( face, glyph_index,
@@ -2608,7 +2713,7 @@
has_vertical_info = FT_BOOL( face->vertical_info &&
face->vertical.number_Of_VMetrics > 0 &&
- face->vertical.long_metrics != 0 );
+ face->vertical.long_metrics );
/* get the vertical metrics from the vtmx table if we have one */
if ( has_vertical_info )
diff --git a/src/cff/cffgload.h b/src/cff/cffgload.h
index bf21654..667134e 100644
--- a/src/cff/cffgload.h
+++ b/src/cff/cffgload.h
@@ -169,9 +169,6 @@ FT_BEGIN_HEADER
FT_Bool hinting,
FT_Render_Mode hint_mode );
- FT_LOCAL( void )
- cff_decoder_set_width_only( CFF_Decoder* decoder );
-
FT_LOCAL( FT_Error )
cff_decoder_prepare( CFF_Decoder* decoder,
CFF_Size size,
diff --git a/src/cff/cffload.c b/src/cff/cffload.c
index 9c030cf..0178c81 100644
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -4,7 +4,7 @@
/* */
/* OpenType and CFF data/program tables loader (body). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -31,6 +31,7 @@
#if 1
+
static const FT_UShort cff_isoadobe_charset[229] =
{
0, 1, 2, 3, 4, 5, 6, 7,
@@ -175,6 +176,7 @@
363, 364, 365, 366, 367, 368, 369, 370,
371, 372, 373, 374, 375, 376, 377, 378
};
+
#endif /* 1 */
@@ -1353,7 +1355,8 @@
FT_LOCAL_DEF( FT_Error )
cff_font_load( FT_Stream stream,
FT_Int face_index,
- CFF_Font font )
+ CFF_Font font,
+ FT_Bool pure_cff )
{
static const FT_Frame_Field cff_header_fields[] =
{
@@ -1517,7 +1520,7 @@
/* read the Charset and Encoding tables if available */
if ( font->num_glyphs > 0 )
{
- FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU );
+ FT_Bool invert = FT_BOOL( dict->cid_registry != 0xFFFFU && pure_cff );
error = cff_charset_load( &font->charset, font->num_glyphs, stream,
diff --git a/src/cff/cffload.h b/src/cff/cffload.h
index 068cbb5..02498bd 100644
--- a/src/cff/cffload.h
+++ b/src/cff/cffload.h
@@ -4,7 +4,7 @@
/* */
/* OpenType & CFF data/program tables loader (specification). */
/* */
-/* Copyright 1996-2001, 2002, 2003, 2007 by */
+/* Copyright 1996-2001, 2002, 2003, 2007, 2008 by */
/* David Turner, Robert Wilhelm, and Werner Lemberg. */
/* */
/* This file is part of the FreeType project, and may only be used, */
@@ -60,7 +60,8 @@ FT_BEGIN_HEADER
FT_LOCAL( FT_Error )
cff_font_load( FT_Stream stream,
FT_Int face_index,
- CFF_Font font );
+ CFF_Font font,
+ FT_Bool pure_cff );
FT_LOCAL( void )
cff_font_done( CFF_Font font );
diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c
index 12997a9..3525ea3 100644
--- a/src/cff/cffobjs.c
+++ b/src/cff/cffobjs.c
@@ -101,7 +101,7 @@
/* CFF and Type 1 private dictionaries have slightly different */
- /* structures; we need to synthetize a Type 1 dictionary on the fly */
+ /* structures; we need to synthesize a Type 1 dictionary on the fly */
static void
cff_make_private_dict( CFF_SubFont subfont,
@@ -437,7 +437,7 @@
error = sfnt->init_face( stream, face, face_index, num_params, params );
if ( !error )
{
- if ( face->format_tag != 0x4F54544FL ) /* `OTTO'; OpenType/CFF font */
+ if ( face->format_tag != TTAG_OTTO ) /* `OTTO'; OpenType/CFF font */
{
FT_TRACE2(( "[not a valid OpenType/CFF font]\n" ));
goto Bad_Format;
@@ -465,8 +465,7 @@
pure_cff = 0;
/* load font directory */
- error = sfnt->load_face( stream, face,
- face_index, num_params, params );
+ error = sfnt->load_face( stream, face, 0, num_params, params );
if ( error )
goto Exit;
}
@@ -508,13 +507,15 @@
goto Exit;
face->extra.data = cff;
- error = cff_font_load( stream, face_index, cff );
+ error = cff_font_load( stream, face_index, cff, pure_cff );
if ( error )
goto Exit;
cff->pshinter = pshinter;
cff->psnames = (void*)psnames;
+ cffface->face_index = face_index;
+
/* Complement the root flags with some interesting information. */
/* Note that this is only necessary for pure CFF and CEF fonts; */
/* SFNT based fonts use the `name' table instead. */
@@ -534,6 +535,111 @@
goto Bad_Format;
}
+ if ( !dict->units_per_em )
+ dict->units_per_em = pure_cff ? 1000 : face->root.units_per_EM;
+
+ /* Normalize the font matrix so that `matrix->xx' is 1; the */
+ /* scaling is done with `units_per_em' then (at this point, */
+ /* it already contains the scaling factor, but without */
+ /* normalization of the matrix). */
+ /* */
+ /* Note that the offsets must be expressed in integer font */
+ /* units. */
+
+ {
+ FT_Matrix* matrix = &dict->font_matrix;
+ FT_Vector* offset = &dict->font_offset;
+ FT_ULong* upm = &dict->units_per_em;
+ FT_Fixed temp = FT_ABS( matrix->yy );
+
+
+ if ( temp != 0x10000L )
+ {
+ *upm = FT_DivFix( *upm, temp );
+
+ matrix->xx = FT_DivFix( matrix->xx, temp );
+ matrix->yx = FT_DivFix( matrix->yx, temp );
+ matrix->xy = FT_DivFix( matrix->xy, temp );
+ matrix->yy = FT_DivFix( matrix->yy, temp );
+ offset->x = FT_DivFix( offset->x, temp );
+ offset->y = FT_DivFix( offset->y, temp );
+ }
+
+ offset->x >>= 16;
+ offset->y >>= 16;
+ }
+
+ for ( i = cff->num_subfonts; i > 0; i-- )
+ {
+ CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict;
+ CFF_FontRecDict top = &cff->top_font.font_dict;
+
+ FT_Matrix* matrix;
+ FT_Vector* offset;
+ FT_ULong* upm;
+ FT_Fixed temp;
+
+
+ if ( sub->units_per_em )
+ {
+ FT_Int scaling;
+
+
+ if ( top->units_per_em > 1 && sub->units_per_em > 1 )
+ scaling = FT_MIN( top->units_per_em, sub->units_per_em );
+ else
+ scaling = 1;
+
+ FT_Matrix_Multiply_Scaled( &top->font_matrix,
+ &sub->font_matrix,
+ scaling );
+ FT_Vector_Transform_Scaled( &sub->font_offset,
+ &top->font_matrix,
+ scaling );
+
+ sub->units_per_em = FT_MulDiv( sub->units_per_em,
+ top->units_per_em,
+ scaling );
+ }
+ else
+ {
+ sub->font_matrix = top->font_matrix;
+ sub->font_offset = top->font_offset;
+
+ sub->units_per_em = top->units_per_em;
+ }
+
+ matrix = &sub->font_matrix;
+ offset = &sub->font_offset;
+ upm = &sub->units_per_em;
+ temp = FT_ABS( matrix->yy );
+
+ if ( temp != 0x10000L )
+ {
+ *upm = FT_DivFix( *upm, temp );
+
+ /* if *upm is larger than 100*1000 we divide by 1000 -- */
+ /* this can happen if e.g. there is no top-font FontMatrix */
+ /* and the subfont FontMatrix already contains the complete */
+ /* scaling for the subfont (see section 5.11 of the PLRM) */
+
+ /* 100 is a heuristic value */
+
+ if ( *upm > 100L * 1000L )
+ *upm = ( *upm + 500 ) / 1000;
+
+ matrix->xx = FT_DivFix( matrix->xx, temp );
+ matrix->yx = FT_DivFix( matrix->yx, temp );
+ matrix->xy = FT_DivFix( matrix->xy, temp );
+ matrix->yy = FT_DivFix( matrix->yy, temp );
+ offset->x = FT_DivFix( offset->x, temp );
+ offset->y = FT_DivFix( offset->y, temp );
+ }
+
+ offset->x >>= 16;
+ offset->y >>= 16;
+ }
+
if ( pure_cff )
{
char* style_name = NULL;
@@ -554,10 +660,7 @@
cffface->bbox.xMax = ( dict->font_bbox.xMax + 0xFFFFU ) >> 16;
cffface->bbox.yMax = ( dict->font_bbox.yMax + 0xFFFFU ) >> 16;
- if ( !dict->units_per_em )
- dict->units_per_em = 1000;
-
- cffface->units_per_EM = dict->units_per_em;
+ cffface->units_per_EM = (FT_UShort)( dict->units_per_em );
cffface->ascender = (FT_Short)( cffface->bbox.yMax );
cffface->descender = (FT_Short)( cffface->bbox.yMin );
@@ -711,113 +814,7 @@
cffface->style_flags = flags;
}
- else
- {
- if ( !dict->units_per_em )
- dict->units_per_em = face->root.units_per_EM;
- }
-
- /* Normalize the font matrix so that `matrix->xx' is 1; the */
- /* scaling is done with `units_per_em' then (at this point, */
- /* it already contains the scaling factor, but without */
- /* normalization of the matrix). */
- /* */
- /* Note that the offsets must be expressed in integer font */
- /* units. */
- {
- FT_Matrix* matrix = &dict->font_matrix;
- FT_Vector* offset = &dict->font_offset;
- FT_ULong* upm = &dict->units_per_em;
- FT_Fixed temp = FT_ABS( matrix->yy );
-
-
- if ( temp != 0x10000L )
- {
- *upm = FT_DivFix( *upm, temp );
-
- matrix->xx = FT_DivFix( matrix->xx, temp );
- matrix->yx = FT_DivFix( matrix->yx, temp );
- matrix->xy = FT_DivFix( matrix->xy, temp );
- matrix->yy = FT_DivFix( matrix->yy, temp );
- offset->x = FT_DivFix( offset->x, temp );
- offset->y = FT_DivFix( offset->y, temp );
- }
-
- offset->x >>= 16;
- offset->y >>= 16;
- }
-
- for ( i = cff->num_subfonts; i > 0; i-- )
- {
- CFF_FontRecDict sub = &cff->subfonts[i - 1]->font_dict;
- CFF_FontRecDict top = &cff->top_font.font_dict;
-
- FT_Matrix* matrix;
- FT_Vector* offset;
- FT_ULong* upm;
- FT_Fixed temp;
-
-
- if ( sub->units_per_em )
- {
- FT_Int scaling;
-
-
- if ( top->units_per_em > 1 && sub->units_per_em > 1 )
- scaling = FT_MIN( top->units_per_em, sub->units_per_em );
- else
- scaling = 1;
-
- FT_Matrix_Multiply_Scaled( &top->font_matrix,
- &sub->font_matrix,
- scaling );
- FT_Vector_Transform_Scaled( &sub->font_offset,
- &top->font_matrix,
- scaling );
-
- sub->units_per_em = FT_MulDiv( sub->units_per_em,
- top->units_per_em,
- scaling );
- }
- else
- {
- sub->font_matrix = top->font_matrix;
- sub->font_offset = top->font_offset;
-
- sub->units_per_em = top->units_per_em;
- }
-
- matrix = &sub->font_matrix;
- offset = &sub->font_offset;
- upm = &sub->units_per_em;
- temp = FT_ABS( matrix->yy );
-
- if ( temp != 0x10000L )
- {
- *upm = FT_DivFix( *upm, temp );
-
- /* if *upm is larger than 100*1000 we divide by 1000 -- */
- /* this can happen if e.g. there is no top-font FontMatrix */
- /* and the subfont FontMatrix already contains the complete */
- /* scaling for the subfont (see section 5.11 of the PLRM) */
-
- /* 100 is a heuristic value */
-
- if ( *upm > 100L * 1000L )
- *upm = ( *upm + 500 ) / 1000;
-
- matrix->xx = FT_DivFix( matrix->xx, temp );
- matrix->yx = FT_DivFix( matrix->yx, temp );
- matrix->xy = FT_DivFix( matrix->xy, temp );
- matrix->yy = FT_DivFix( matrix->yy, temp );
- offset->x = FT_DivFix( offset->x, temp );
- offset->y = FT_DivFix( offset->y, temp );
- }
-
- offset->x >>= 16;
- offset->y >>= 16;
- }
#ifndef FT_CONFIG_OPTION_NO_GLYPH_NAMES
/* CID-keyed CFF fonts don't have glyph names -- the SFNT loader */
@@ -826,7 +823,7 @@
cffface->face_flags |= FT_FACE_FLAG_GLYPH_NAMES;
#endif
- if ( dict->cid_registry != 0xFFFFU )
+ if ( dict->cid_registry != 0xFFFFU && pure_cff )
cffface->face_flags |= FT_FACE_FLAG_CID_KEYED;
@@ -835,7 +832,7 @@
/* Compute char maps. */
/* */
- /* Try to synthetize a Unicode charmap if there is none available */
+ /* Try to synthesize a Unicode charmap if there is none available */
/* already. If an OpenType font contains a Unicode "cmap", we */
/* will use it, whatever be in the CFF part of the file. */
{
@@ -922,10 +919,16 @@
FT_LOCAL_DEF( void )
cff_face_done( FT_Face cffface ) /* CFF_Face */
{
- CFF_Face face = (CFF_Face)cffface;
- FT_Memory memory = cffface->memory;
- SFNT_Service sfnt = (SFNT_Service)face->sfnt;
+ CFF_Face face = (CFF_Face)cffface;
+ FT_Memory memory;
+ SFNT_Service sfnt;
+
+
+ if ( !face )
+ return;
+ memory = cffface->memory;
+ sfnt = (SFNT_Service)face->sfnt;
if ( sfnt )
sfnt->done_face( face );
diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
index d6d77dd..524d80c 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -355,6 +355,12 @@
if ( FT_ABS( integer_length ) > 5 )
goto Exit;
+ /* Remove non-significant digits. */
+ if ( integer_length < 0 ) {
+ number /= power_tens[-integer_length];
+ fraction_length += integer_length;
+ }
+
/* Convert into 16.16 format. */
if ( fraction_length > 0 )
{
@@ -406,10 +412,9 @@
cff_parse_fixed_scaled( FT_Byte** d,
FT_Int scaling )
{
- return **d ==
- 30 ? cff_parse_real( d[0], d[1], scaling, NULL )
- : (FT_Fixed)FT_MulFix( cff_parse_integer( d[0], d[1] ) << 16,
- power_tens[scaling] );
+ return **d == 30 ? cff_parse_real( d[0], d[1], scaling, NULL )
+ : ( cff_parse_integer( d[0], d[1] ) *
+ power_tens[scaling] ) << 16;
}