ref: 8ed9eaf1cccd3112870939fbb932dd31fca95589
parent: 658f530ef54d973b0741df73b0939d906f0f68a1
author: Werner Lemberg <[email protected]>
date: Mon Feb 15 15:41:58 EST 2016
[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.
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,27 @@
2016-02-15 Werner Lemberg <[email protected]>
+ [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 <[email protected]>
+
[cff] Correctly trace SIDs that contain NULL bytes.
We need this to properly trace Multiple Master CFFs, which contain
--- a/src/cff/cffgload.c
+++ b/src/cff/cffgload.c
@@ -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,17 +2278,44 @@
case cff_op_store:
/* this operator was removed from the Type2 specification */
/* in version 16-March-2000 */
+
+ /* since we currently don't handle interpolation of multiple */
+ /* master fonts, this is a no-op */
FT_TRACE4(( " store\n"));
+ break;
- goto Unimplemented;
-
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 */
/* in version 16-March-2000 */
@@ -2577,7 +2610,6 @@
break;
default:
- Unimplemented:
FT_ERROR(( "Unimplemented opcode: %d", ip[-1] ));
if ( ip[-1] == 12 )
--- a/src/cff/cffload.c
+++ b/src/cff/cffload.c
@@ -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 ) )
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -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,
--- a/src/cff/cffparse.h
+++ b/src/cff/cffparse.h
@@ -36,18 +36,19 @@
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_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,
--- a/src/cff/cfftypes.h
+++ b/src/cff/cfftypes.h
@@ -145,10 +145,11 @@
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;