In function cff_parse_font_matrix, added logic to get the units_per_EM from the FontMatrix. Added a new function (cff_parse_fixed_thousand) that gets a real number fromt he CFF font, but multiplies by 1000 (this is to avoid rounding errors when placing this real number into a 16.16 fixed number). In function cff_parse_real, added code so that the integer part is moved into the high sixtenn bits of the 16.16 fixed number.
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
diff --git a/src/cff/cffparse.c b/src/cff/cffparse.c
index 51f9c12..7ba385b 100644
--- a/src/cff/cffparse.c
+++ b/src/cff/cffparse.c
@@ -267,8 +267,12 @@
power_ten++;
}
+ /* Move the integer part into the high 16 bits. */
+ result <<= 16;
+
+ /* Place the decimal part into the low 16 bits. */
if ( num )
- result += FT_DivFix( num, divider );
+ result |= FT_DivFix( num, divider );
if ( sign )
result = -result;
@@ -299,6 +303,14 @@
: cff_parse_integer( d[0], d[1] ) << 16 );
}
+ /* read a floating point number, either integer or real, */
+ /* but return 1000 times the number read in. */
+ static
+ FT_Fixed cff_parse_fixed_thousand( FT_Byte** d )
+ {
+ return ( **d == 30 ? cff_parse_real ( d[0], d[1], 3 )
+ : (FT_Fixed)FT_MulFix ( cff_parse_integer( d[0], d[1] ) << 16, 1000 ) );
+ }
static
FT_Error cff_parse_font_matrix( CFF_Parser* parser )
@@ -306,6 +318,7 @@
CFF_Font_Dict* dict = (CFF_Font_Dict*)parser->object;
FT_Matrix* matrix = &dict->font_matrix;
FT_Vector* offset = &dict->font_offset;
+ FT_UShort* upm = &dict->units_per_em;
FT_Byte** data = parser->stack;
FT_Error error;
FT_Fixed temp;
@@ -315,15 +328,18 @@
if ( parser->top >= parser->stack + 6 )
{
- matrix->xx = cff_parse_fixed( data++ );
- matrix->yx = cff_parse_fixed( data++ );
- matrix->xy = cff_parse_fixed( data++ );
- matrix->yy = cff_parse_fixed( data++ );
- offset->x = cff_parse_fixed( data++ );
- offset->y = cff_parse_fixed( data );
+ matrix->xx = cff_parse_fixed_thousand( data++ );
+ matrix->yx = cff_parse_fixed_thousand( data++ );
+ matrix->xy = cff_parse_fixed_thousand( data++ );
+ matrix->yy = cff_parse_fixed_thousand( data++ );
+ offset->x = cff_parse_fixed_thousand( data++ );
+ offset->y = cff_parse_fixed_thousand( data );
temp = ABS( matrix->yy );
+ *upm = (FT_UShort)FT_DivFix( 0x10000L, FT_DivFix( temp, 1000 ) );
+ fprintf (stderr, "cff_parse_font_matrix: matrix->xx = %08lX, upm = %d\n", matrix->xx, *upm) ;
+
if ( temp != 0x10000L )
{
matrix->xx = FT_DivFix( matrix->xx, temp );