Add basic support for Type1 charstrings in CFF.
* src/cff/cffgload.c (CFF_Operator, cff_argument_counts): Handle `seac', `sbw', and `setcurrentpoint' opcodes. (cff_compute_bias): Add parameter to indicate the charstring type. Update all callers. (cff_operator_seac): Add parameter for side bearing. (cff_decoder_parse_charstrings): Updated for more Type1 support.
This commit is contained in:
parent
f186ba682d
commit
8821cc5df1
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
||||||
|
2009-11-03 Bram Tassyns <bramt@enfocus.be>
|
||||||
|
|
||||||
|
Add basic support for Type1 charstrings in CFF.
|
||||||
|
|
||||||
|
* src/cff/cffgload.c (CFF_Operator, cff_argument_counts): Handle
|
||||||
|
`seac', `sbw', and `setcurrentpoint' opcodes.
|
||||||
|
(cff_compute_bias): Add parameter to indicate the charstring type.
|
||||||
|
Update all callers.
|
||||||
|
(cff_operator_seac): Add parameter for side bearing.
|
||||||
|
(cff_decoder_parse_charstrings): Updated for more Type1 support.
|
||||||
|
|
||||||
2009-11-03 Werner Lemberg <wl@gnu.org>
|
2009-11-03 Werner Lemberg <wl@gnu.org>
|
||||||
|
|
||||||
Return correct `linearHoriAdvance' value for embedded TT bitmaps too.
|
Return correct `linearHoriAdvance' value for embedded TT bitmaps too.
|
||||||
|
|
|
@ -113,6 +113,9 @@
|
||||||
cff_op_closepath,
|
cff_op_closepath,
|
||||||
cff_op_callothersubr,
|
cff_op_callothersubr,
|
||||||
cff_op_pop,
|
cff_op_pop,
|
||||||
|
cff_op_seac,
|
||||||
|
cff_op_sbw,
|
||||||
|
cff_op_setcurrentpoint,
|
||||||
|
|
||||||
/* do not remove */
|
/* do not remove */
|
||||||
cff_op_max
|
cff_op_max
|
||||||
|
@ -201,7 +204,10 @@
|
||||||
2, /* hsbw */
|
2, /* hsbw */
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
0
|
0,
|
||||||
|
5, /* seac */
|
||||||
|
4, /* sbw */
|
||||||
|
2 /* setcurrentpoint */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -319,17 +325,23 @@
|
||||||
/* subroutines. */
|
/* subroutines. */
|
||||||
/* */
|
/* */
|
||||||
/* <Input> */
|
/* <Input> */
|
||||||
/* num_subrs :: The number of glyph subroutines. */
|
/* in_charstring_type :: The `CharstringType' value of the top DICT */
|
||||||
|
/* dictionary. */
|
||||||
|
/* */
|
||||||
|
/* num_subrs :: The number of glyph subroutines. */
|
||||||
/* */
|
/* */
|
||||||
/* <Return> */
|
/* <Return> */
|
||||||
/* The bias value. */
|
/* The bias value. */
|
||||||
static FT_Int
|
static FT_Int
|
||||||
cff_compute_bias( FT_UInt num_subrs )
|
cff_compute_bias( FT_Int in_charstring_type,
|
||||||
|
FT_UInt num_subrs )
|
||||||
{
|
{
|
||||||
FT_Int result;
|
FT_Int result;
|
||||||
|
|
||||||
|
|
||||||
if ( num_subrs < 1240 )
|
if ( in_charstring_type == 1 )
|
||||||
|
result = 0;
|
||||||
|
else if ( num_subrs < 1240 )
|
||||||
result = 107;
|
result = 107;
|
||||||
else if ( num_subrs < 33900U )
|
else if ( num_subrs < 33900U )
|
||||||
result = 1131;
|
result = 1131;
|
||||||
|
@ -380,9 +392,12 @@
|
||||||
cff_builder_init( &decoder->builder, face, size, slot, hinting );
|
cff_builder_init( &decoder->builder, face, size, slot, hinting );
|
||||||
|
|
||||||
/* initialize Type2 decoder */
|
/* initialize Type2 decoder */
|
||||||
|
decoder->cff = cff;
|
||||||
decoder->num_globals = cff->num_global_subrs;
|
decoder->num_globals = cff->num_global_subrs;
|
||||||
decoder->globals = cff->global_subrs;
|
decoder->globals = cff->global_subrs;
|
||||||
decoder->globals_bias = cff_compute_bias( decoder->num_globals );
|
decoder->globals_bias = cff_compute_bias(
|
||||||
|
cff->top_font.font_dict.charstring_type,
|
||||||
|
decoder->num_globals );
|
||||||
|
|
||||||
decoder->hint_mode = hint_mode;
|
decoder->hint_mode = hint_mode;
|
||||||
}
|
}
|
||||||
|
@ -434,7 +449,9 @@
|
||||||
|
|
||||||
decoder->num_locals = sub->num_local_subrs;
|
decoder->num_locals = sub->num_local_subrs;
|
||||||
decoder->locals = sub->local_subrs;
|
decoder->locals = sub->local_subrs;
|
||||||
decoder->locals_bias = cff_compute_bias( decoder->num_locals );
|
decoder->locals_bias = cff_compute_bias(
|
||||||
|
decoder->cff->top_font.font_dict.charstring_type,
|
||||||
|
decoder->num_locals );
|
||||||
|
|
||||||
decoder->glyph_width = sub->private_dict.default_width;
|
decoder->glyph_width = sub->private_dict.default_width;
|
||||||
decoder->nominal_width = sub->private_dict.nominal_width;
|
decoder->nominal_width = sub->private_dict.nominal_width;
|
||||||
|
@ -693,6 +710,7 @@
|
||||||
|
|
||||||
static FT_Error
|
static FT_Error
|
||||||
cff_operator_seac( CFF_Decoder* decoder,
|
cff_operator_seac( CFF_Decoder* decoder,
|
||||||
|
FT_Pos asb,
|
||||||
FT_Pos adx,
|
FT_Pos adx,
|
||||||
FT_Pos ady,
|
FT_Pos ady,
|
||||||
FT_Int bchar,
|
FT_Int bchar,
|
||||||
|
@ -705,6 +723,7 @@
|
||||||
FT_Vector left_bearing, advance;
|
FT_Vector left_bearing, advance;
|
||||||
FT_Byte* charstring;
|
FT_Byte* charstring;
|
||||||
FT_ULong charstring_len;
|
FT_ULong charstring_len;
|
||||||
|
FT_Pos glyph_width;
|
||||||
|
|
||||||
|
|
||||||
if ( decoder->seac )
|
if ( decoder->seac )
|
||||||
|
@ -713,6 +732,9 @@
|
||||||
return CFF_Err_Syntax_Error;
|
return CFF_Err_Syntax_Error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
adx += decoder->builder.left_bearing.x;
|
||||||
|
ady += decoder->builder.left_bearing.y;
|
||||||
|
|
||||||
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
#ifdef FT_CONFIG_OPTION_INCREMENTAL
|
||||||
/* Incremental fonts don't necessarily have valid charsets. */
|
/* Incremental fonts don't necessarily have valid charsets. */
|
||||||
/* They use the character code, not the glyph index, in this case. */
|
/* They use the character code, not the glyph index, in this case. */
|
||||||
|
@ -795,16 +817,17 @@
|
||||||
cff_free_glyph_data( face, &charstring, charstring_len );
|
cff_free_glyph_data( face, &charstring, charstring_len );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Save the left bearing and width of the base character */
|
/* Save the left bearing, advance and glyph width of the base */
|
||||||
/* as they will be erased by the next load. */
|
/* character as they will be erased by the next load. */
|
||||||
|
|
||||||
left_bearing = builder->left_bearing;
|
left_bearing = builder->left_bearing;
|
||||||
advance = builder->advance;
|
advance = builder->advance;
|
||||||
|
glyph_width = decoder->glyph_width;
|
||||||
|
|
||||||
builder->left_bearing.x = 0;
|
builder->left_bearing.x = 0;
|
||||||
builder->left_bearing.y = 0;
|
builder->left_bearing.y = 0;
|
||||||
|
|
||||||
builder->pos_x = adx;
|
builder->pos_x = adx - asb;
|
||||||
builder->pos_y = ady;
|
builder->pos_y = ady;
|
||||||
|
|
||||||
/* Now load `achar' on top of the base outline. */
|
/* Now load `achar' on top of the base outline. */
|
||||||
|
@ -824,10 +847,11 @@
|
||||||
cff_free_glyph_data( face, &charstring, charstring_len );
|
cff_free_glyph_data( face, &charstring, charstring_len );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Restore the left side bearing and advance width */
|
/* Restore the left side bearing, advance and glyph width */
|
||||||
/* of the base character. */
|
/* of the base character. */
|
||||||
builder->left_bearing = left_bearing;
|
builder->left_bearing = left_bearing;
|
||||||
builder->advance = advance;
|
builder->advance = advance;
|
||||||
|
decoder->glyph_width = glyph_width;
|
||||||
|
|
||||||
builder->pos_x = 0;
|
builder->pos_x = 0;
|
||||||
builder->pos_y = 0;
|
builder->pos_y = 0;
|
||||||
|
@ -869,6 +893,8 @@
|
||||||
FT_Pos x, y;
|
FT_Pos x, y;
|
||||||
FT_Fixed seed;
|
FT_Fixed seed;
|
||||||
FT_Fixed* stack;
|
FT_Fixed* stack;
|
||||||
|
FT_Int charstring_type =
|
||||||
|
decoder->cff->top_font.font_dict.charstring_type;
|
||||||
|
|
||||||
T2_Hints_Funcs hinter;
|
T2_Hints_Funcs hinter;
|
||||||
|
|
||||||
|
@ -958,7 +984,8 @@
|
||||||
( (FT_Int32)ip[2] << 8 ) |
|
( (FT_Int32)ip[2] << 8 ) |
|
||||||
ip[3];
|
ip[3];
|
||||||
ip += 4;
|
ip += 4;
|
||||||
shift = 0;
|
if ( charstring_type == 2 )
|
||||||
|
shift = 0;
|
||||||
}
|
}
|
||||||
if ( decoder->top - stack >= CFF_MAX_OPERANDS )
|
if ( decoder->top - stack >= CFF_MAX_OPERANDS )
|
||||||
goto Stack_Overflow;
|
goto Stack_Overflow;
|
||||||
|
@ -1032,6 +1059,12 @@
|
||||||
case 0:
|
case 0:
|
||||||
op = cff_op_dotsection;
|
op = cff_op_dotsection;
|
||||||
break;
|
break;
|
||||||
|
case 1: /* this is actually the Type1 vstem3 operator */
|
||||||
|
op = cff_op_vstem;
|
||||||
|
break;
|
||||||
|
case 2: /* this is actually the Type1 hstem3 operator */
|
||||||
|
op = cff_op_hstem;
|
||||||
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
op = cff_op_and;
|
op = cff_op_and;
|
||||||
break;
|
break;
|
||||||
|
@ -1041,6 +1074,12 @@
|
||||||
case 5:
|
case 5:
|
||||||
op = cff_op_not;
|
op = cff_op_not;
|
||||||
break;
|
break;
|
||||||
|
case 6:
|
||||||
|
op = cff_op_seac;
|
||||||
|
break;
|
||||||
|
case 7:
|
||||||
|
op = cff_op_sbw;
|
||||||
|
break;
|
||||||
case 8:
|
case 8:
|
||||||
op = cff_op_store;
|
op = cff_op_store;
|
||||||
break;
|
break;
|
||||||
|
@ -1104,6 +1143,9 @@
|
||||||
case 30:
|
case 30:
|
||||||
op = cff_op_roll;
|
op = cff_op_roll;
|
||||||
break;
|
break;
|
||||||
|
case 33:
|
||||||
|
op = cff_op_setcurrentpoint;
|
||||||
|
break;
|
||||||
case 34:
|
case 34:
|
||||||
op = cff_op_hflex;
|
op = cff_op_hflex;
|
||||||
break;
|
break;
|
||||||
|
@ -1171,7 +1213,7 @@
|
||||||
op = cff_op_hvcurveto;
|
op = cff_op_hvcurveto;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( op == cff_op_unknown )
|
if ( op == cff_op_unknown )
|
||||||
|
@ -1886,6 +1928,21 @@
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case cff_op_seac:
|
||||||
|
FT_TRACE4(( " seac\n" ));
|
||||||
|
|
||||||
|
error = cff_operator_seac( decoder,
|
||||||
|
args[0], args[1], args[2],
|
||||||
|
(FT_Int)( args[3] >> 16 ),
|
||||||
|
(FT_Int)( args[4] >> 16 ) );
|
||||||
|
|
||||||
|
/* add current outline to the glyph slot */
|
||||||
|
FT_GlyphLoader_Add( builder->loader );
|
||||||
|
|
||||||
|
/* return now! */
|
||||||
|
FT_TRACE4(( "\n" ));
|
||||||
|
return error;
|
||||||
|
|
||||||
case cff_op_endchar:
|
case cff_op_endchar:
|
||||||
FT_TRACE4(( " endchar\n" ));
|
FT_TRACE4(( " endchar\n" ));
|
||||||
|
|
||||||
|
@ -1895,10 +1952,8 @@
|
||||||
/* Save glyph width so that the subglyphs don't overwrite it. */
|
/* Save glyph width so that the subglyphs don't overwrite it. */
|
||||||
FT_Pos glyph_width = decoder->glyph_width;
|
FT_Pos glyph_width = decoder->glyph_width;
|
||||||
|
|
||||||
|
|
||||||
error = cff_operator_seac( decoder,
|
error = cff_operator_seac( decoder,
|
||||||
args[-4],
|
0L, args[-4], args[-3],
|
||||||
args[-3],
|
|
||||||
(FT_Int)( args[-2] >> 16 ),
|
(FT_Int)( args[-2] >> 16 ),
|
||||||
(FT_Int)( args[-1] >> 16 ) );
|
(FT_Int)( args[-1] >> 16 ) );
|
||||||
|
|
||||||
|
@ -2170,10 +2225,42 @@
|
||||||
|
|
||||||
FT_TRACE4(( " hsbw (invalid op)\n" ));
|
FT_TRACE4(( " hsbw (invalid op)\n" ));
|
||||||
|
|
||||||
decoder->glyph_width = decoder->nominal_width +
|
decoder->glyph_width = decoder->nominal_width + ( args[1] >> 16 );
|
||||||
(args[1] >> 16);
|
|
||||||
x = args[0];
|
decoder->builder.left_bearing.x = args[0];
|
||||||
y = 0;
|
decoder->builder.left_bearing.y = 0;
|
||||||
|
|
||||||
|
x = decoder->builder.pos_x + args[0];
|
||||||
|
y = decoder->builder.pos_y;
|
||||||
|
args = stack;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case cff_op_sbw:
|
||||||
|
/* 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(( " sbw (invalid op)\n" ));
|
||||||
|
|
||||||
|
decoder->glyph_width = decoder->nominal_width + ( args[2] >> 16 );
|
||||||
|
|
||||||
|
decoder->builder.left_bearing.x = args[0];
|
||||||
|
decoder->builder.left_bearing.y = args[1];
|
||||||
|
|
||||||
|
x = decoder->builder.pos_x + args[0];
|
||||||
|
y = decoder->builder.pos_y + args[1];
|
||||||
|
args = stack;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case cff_op_setcurrentpoint:
|
||||||
|
/* 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(( " setcurrentpoint (invalid op)\n" ));
|
||||||
|
|
||||||
|
x = decoder->builder.pos_x + args[0];
|
||||||
|
y = decoder->builder.pos_y + args[1];
|
||||||
args = stack;
|
args = stack;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -2184,8 +2271,10 @@
|
||||||
|
|
||||||
FT_TRACE4(( " callothersubr (invalid op)\n" ));
|
FT_TRACE4(( " callothersubr (invalid op)\n" ));
|
||||||
|
|
||||||
/* don't modify stack; handle the subr as `unknown' so that */
|
/* subsequent `pop' operands should add the arguments, */
|
||||||
/* following `pop' operands use the arguments on stack */
|
/* this is the implementation described for `unknown' other */
|
||||||
|
/* subroutines in the Type1 spec. */
|
||||||
|
args -= 2 + ( args[-2] >> 16 );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case cff_op_pop:
|
case cff_op_pop:
|
||||||
|
|
Loading…
Reference in New Issue