[cff] Partially handle `load' and `store' ops in old CFF engine.

Now all glyphs of MM CFFs like `ITCGaramondMM-It.otf' can be
displayed.

* src/cff/cffgload.c (cff_decoder_parse_charstrings) <cff_op_store,
cff_op_load>: Partially implement it.

* src/cff/cffparse.c (cff_parser_init): Add new parameter to pass
the number of Multiple Master axes.
Update all callers.
(cff_parse_multiple_master): Get number of axes.
(cff_parser_run) <opcode 31>: Updated.
* src/cff/cffparse.h: Updated.
(CFF_ParserRec): Add `num_axes' field.

* src/cff/cffload.c: Updated.

* src/cff/cfftypes.h (CFF_FontRecDictRec): Add `num_axes' field.
This commit is contained in:
Werner Lemberg 2016-02-15 20:41:58 +01:00
parent 658f530ef5
commit 8ed9eaf1cc
6 changed files with 86 additions and 20 deletions

View File

@ -1,3 +1,25 @@
2016-02-15 Werner Lemberg <wl@gnu.org>
[cff] Partially handle `load' and `store' ops in old CFF engine.
Now all glyphs of MM CFFs like `ITCGaramondMM-It.otf' can be
displayed.
* src/cff/cffgload.c (cff_decoder_parse_charstrings) <cff_op_store,
cff_op_load>: Partially implement it.
* src/cff/cffparse.c (cff_parser_init): Add new parameter to pass
the number of Multiple Master axes.
Update all callers.
(cff_parse_multiple_master): Get number of axes.
(cff_parser_run) <opcode 31>: Updated.
* src/cff/cffparse.h: Updated.
(CFF_ParserRec): Add `num_axes' field.
* src/cff/cffload.c: Updated.
* src/cff/cfftypes.h (CFF_FontRecDictRec): Add `num_axes' field.
2016-02-15 Werner Lemberg <wl@gnu.org>
[cff] Correctly trace SIDs that contain NULL bytes.

View File

@ -919,6 +919,8 @@
decoder->cff->top_font.font_dict.charstring_type;
FT_UShort num_designs =
decoder->cff->top_font.font_dict.num_designs;
FT_UShort num_axes =
decoder->cff->top_font.font_dict.num_axes;
T2_Hints_Funcs hinter;
@ -2248,6 +2250,10 @@
FT_TRACE4(( " put\n" ));
/* the Type2 specification before version 16-March-2000 */
/* didn't give a hard-coded size limit of the temporary */
/* storage array; instead, an argument of the */
/* `MultipleMaster' operator set the size */
if ( idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS )
decoder->buildchar[idx] = val;
}
@ -2272,16 +2278,43 @@
case cff_op_store:
/* this operator was removed from the Type2 specification */
/* in version 16-March-2000 */
FT_TRACE4(( " store\n"));
goto Unimplemented;
/* since we currently don't handle interpolation of multiple */
/* master fonts, this is a no-op */
FT_TRACE4(( " store\n"));
break;
case cff_op_load:
/* this operator was removed from the Type2 specification */
/* in version 16-March-2000 */
FT_TRACE4(( " load\n" ));
{
FT_Int reg_idx = (FT_Int)args[0];
FT_Int idx = (FT_Int)args[1];
FT_Int count = (FT_Int)args[2];
goto Unimplemented;
FT_TRACE4(( " load\n" ));
/* since we currently don't handle interpolation of multiple */
/* master fonts, we store a vector [1 0 0 ...] in the */
/* temporary storage array regardless of the Registry index */
if ( reg_idx >= 0 && reg_idx <= 2 &&
idx >= 0 && idx < CFF_MAX_TRANS_ELEMENTS &&
count >= 0 && count <= num_axes )
{
FT_Int end, i;
end = FT_MIN( idx + count, CFF_MAX_TRANS_ELEMENTS );
if ( idx < end )
decoder->buildchar[idx] = 1 << 16;
for ( i = idx + 1; i < end; i++ )
decoder->buildchar[i] = 0;
}
}
break;
case cff_op_blend:
/* this operator was removed from the Type2 specification */
@ -2577,7 +2610,6 @@
break;
default:
Unimplemented:
FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));
if ( ip[-1] == 12 )

View File

@ -1325,6 +1325,7 @@
CFF_CODE_TOPDICT,
&font->font_dict,
library,
0,
0 );
/* set defaults */
@ -1383,7 +1384,8 @@
CFF_CODE_PRIVATE,
priv,
library,
top->num_designs );
top->num_designs,
top->num_axes );
if ( FT_STREAM_SEEK( base_offset + font->font_dict.private_offset ) ||
FT_FRAME_ENTER( font->font_dict.private_size ) )

View File

@ -41,7 +41,8 @@
FT_UInt code,
void* object,
FT_Library library,
FT_UShort num_designs )
FT_UShort num_designs,
FT_UShort num_axes )
{
FT_MEM_ZERO( parser, sizeof ( *parser ) );
@ -50,6 +51,7 @@
parser->object = object;
parser->library = library;
parser->num_designs = num_designs;
parser->num_axes = num_axes;
}
@ -682,7 +684,11 @@
else
{
dict->num_designs = (FT_UShort)num_designs;
dict->num_axes = (FT_UShort)( parser->top - parser->stack - 4 );
parser->num_designs = dict->num_designs;
parser->num_axes = dict->num_axes;
error = FT_Err_Ok;
}
}
@ -1075,6 +1081,7 @@
FT_MEM_ZERO( &cff_rec, sizeof ( cff_rec ) );
cff_rec.top_font.font_dict.num_designs = parser->num_designs;
cff_rec.top_font.font_dict.num_axes = parser->num_axes;
decoder.cff = &cff_rec;
error = cff_decoder_parse_charstrings( &decoder,

View File

@ -36,18 +36,19 @@ FT_BEGIN_HEADER
typedef struct CFF_ParserRec_
{
FT_Library library;
FT_Byte* start;
FT_Byte* limit;
FT_Byte* cursor;
FT_Library library;
FT_Byte* start;
FT_Byte* limit;
FT_Byte* cursor;
FT_Byte* stack[CFF_MAX_STACK_DEPTH + 1];
FT_Byte** top;
FT_Byte* stack[CFF_MAX_STACK_DEPTH + 1];
FT_Byte** top;
FT_UInt object_code;
void* object;
FT_UInt object_code;
void* object;
FT_UShort num_designs; /* a copy of `CFF_FontRecDict->num_designs' */
FT_UShort num_designs; /* a copy of `CFF_FontRecDict->num_designs' */
FT_UShort num_axes; /* a copy of `CFF_FontRecDict->num_axes' */
} CFF_ParserRec, *CFF_Parser;
@ -57,7 +58,8 @@ FT_BEGIN_HEADER
FT_UInt code,
void* object,
FT_Library library,
FT_UShort num_designs );
FT_UShort num_designs,
FT_UShort num_axes );
FT_LOCAL( FT_Error )
cff_parser_run( CFF_Parser parser,

View File

@ -145,10 +145,11 @@ FT_BEGIN_HEADER
FT_ULong cid_fd_select_offset;
FT_UInt cid_font_name;
/* the next field comes from the data of the deprecated */
/* `MultipleMaster' operator; it is needed to parse the (also */
/* deprecated) `blend' operator in Type 2 charstrings */
/* the next fields come from the data of the deprecated */
/* `MultipleMaster' operator; they are needed to parse the (also */
/* deprecated) `blend' operator in Type 2 charstrings */
FT_UShort num_designs;
FT_UShort num_axes;
} CFF_FontRecDictRec, *CFF_FontRecDict;