*** src/truetype/ttgxvar.c~ 2004-04-12 09:35:32.000000000 -0700 --- src/truetype/ttgxvar.c 2004-04-12 09:35:32.000000000 -0700 *************** *** 79,84 **** --- 79,88 ---- #define ALL_POINTS (FT_UShort *) (-1) + enum { + GX_PT_POINTS_ARE_WORDS = 0x80, + GX_PT_POINT_RUN_COUNT_MASK = 0x7f + }; /*************************************************************************/ /* */ /* */ *************** *** 117,124 **** if ( n==0 ) return( ALL_POINTS ); ! if ( n&0x80 ) ! n = FT_GET_BYTE()|((n&0x7f)<<8); if ( FT_NEW_ARRAY(points,n)) return( NULL ); --- 121,128 ---- if ( n==0 ) return( ALL_POINTS ); ! if ( n&GX_PT_POINTS_ARE_WORDS ) ! n = FT_GET_BYTE()|((n&GX_PT_POINT_RUN_COUNT_MASK)<<8); if ( FT_NEW_ARRAY(points,n)) return( NULL ); *************** *** 126,134 **** i = 0; while ( i */ *************** *** 183,207 **** i = 0; while ( igoto_table( face, TTAG_gvar, stream, &table_len )) ) --- 316,322 ---- FT_Int i, j; FT_ULong table_len; FT_ULong gvar_start; ! FT_ULong OffsetToCoord, OffsetToData; FT_Int flag; if ( (error = face->goto_table( face, TTAG_gvar, stream, &table_len )) ) *************** *** 316,328 **** goto Exit; gvar_start = FT_Stream_FTell( stream ); ! version = FT_GET_LONG(); ! axis_cnt = FT_GET_USHORT(); ! blend->tuplecount = FT_GET_USHORT(); ! coord_start = gvar_start + FT_GET_LONG(); ! blend->gv_glyphcnt= FT_GET_USHORT(); flag = FT_GET_USHORT(); ! glyphs_start = gvar_start + FT_GET_LONG(); if ( version!=0x00010000L || axis_cnt != blend->mmvar->num_axis ) { --- 325,337 ---- goto Exit; gvar_start = FT_Stream_FTell( stream ); ! version = FT_GET_LONG(); ! axis_cnt = FT_GET_USHORT(); ! blend->tuplecount = FT_GET_USHORT(); ! OffsetToCoord = gvar_start + FT_GET_LONG(); ! blend->gv_glyphcnt = FT_GET_USHORT(); flag = FT_GET_USHORT(); ! OffsetToData = gvar_start + FT_GET_LONG(); if ( version!=0x00010000L || axis_cnt != blend->mmvar->num_axis ) { *************** *** 336,353 **** if ( flag&1 ) { /* Long offsets (one more offset than glyph, to mark size of last) */ for ( i=0; i<=blend->gv_glyphcnt; ++i ) ! blend->glyphoffsets[i] = glyphs_start + FT_GET_LONG(); } else { /* Short offsets (one more offset than glyph, to mark size of last) */ for ( i=0; i<=blend->gv_glyphcnt; ++i ) ! blend->glyphoffsets[i] = glyphs_start + FT_GET_USHORT()*2; /* Undocumented *2 */ } if ( blend->tuplecount!=0 ) { if ( FT_NEW_ARRAY( blend->tuplecoords, axis_cnt*blend->tuplecount ) ) goto FExit; for ( i=0; ituplecount; ++i ) for ( j=0 ; jtuplecoords[ i*axis_cnt + j ] = FT_GET_SHORT()<<2; /* convert to FT_Fixed */ --- 345,363 ---- if ( flag&1 ) { /* Long offsets (one more offset than glyph, to mark size of last) */ for ( i=0; i<=blend->gv_glyphcnt; ++i ) ! blend->glyphoffsets[i] = OffsetToData + FT_GET_LONG(); } else { /* Short offsets (one more offset than glyph, to mark size of last) */ for ( i=0; i<=blend->gv_glyphcnt; ++i ) ! blend->glyphoffsets[i] = OffsetToData + FT_GET_USHORT()*2; /* Undocumented *2 */ } if ( blend->tuplecount!=0 ) { if ( FT_NEW_ARRAY( blend->tuplecoords, axis_cnt*blend->tuplecount ) ) goto FExit; + FT_Stream_SeekSet( stream, OffsetToCoord ); for ( i=0; ituplecount; ++i ) for ( j=0 ; jtuplecoords[ i*axis_cnt + j ] = FT_GET_SHORT()<<2; /* convert to FT_Fixed */ *************** *** 413,419 **** apply = 0; break; } ! else if ( !(tupleIndex&0x4000 ) ) /* Not an intermediate tuple */ apply = FT_MulDiv(apply, (blend->normalizedcoords[i]>0 ? --- 423,429 ---- apply = 0; break; } ! else if ( !(tupleIndex&GX_TI_INTERMEDIATE_TUPLE ) ) /* Not an intermediate tuple */ apply = FT_MulDiv(apply, (blend->normalizedcoords[i]>0 ? *************** *** 527,533 **** if ( FT_ALLOC( face->blend, sizeof(GX_BlendRec))) goto FExit; - FT_MEM_ZERO( face->blend, sizeof(GX_BlendRec)); /* GWW: Is this needed? */ face->blend->mmvar_len = sizeof(FT_MM_Var) + axis_cnt*sizeof(FT_Var_Axis) + --- 537,542 ---- *************** *** 607,619 **** { a->name = next_name; /* Standard PostScript names for some standard apple tags */ ! if ( a->tag == FT_MAKE_TAG( 'w', 'g', 'h', 't' ) ) a->name = "Weight"; ! else if ( a->tag == FT_MAKE_TAG( 'w', 'd', 't', 'h' ) ) a->name = "Width"; ! else if ( a->tag == FT_MAKE_TAG( 'o', 'p', 's', 'z' ) ) a->name = "OpticalSize"; ! else if ( a->tag == FT_MAKE_TAG( 's', 'l', 'n', 't' ) ) a->name = "Slant"; next_name += 5; ++a; --- 616,628 ---- { a->name = next_name; /* Standard PostScript names for some standard apple tags */ ! if ( a->tag == TTAG_wght ) a->name = "Weight"; ! else if ( a->tag == TTAG_wdth ) a->name = "Width"; ! else if ( a->tag == TTAG_opsz ) a->name = "OpticalSize"; ! else if ( a->tag == TTAG_slnt ) a->name = "Slant"; next_name += 5; ++a; *************** *** 863,869 **** FT_ULong table_start; FT_ULong table_len; FT_Int tupleCount; ! FT_ULong data_pos; FT_ULong here; FT_Int i,j; FT_Fixed *tuple_coords = NULL; --- 872,878 ---- FT_ULong table_start; FT_ULong table_len; FT_Int tupleCount; ! FT_ULong OffsetToData; FT_ULong here; FT_Int i,j; FT_Fixed *tuple_coords = NULL; *************** *** 925,932 **** FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) goto FExit; ! tupleCount = FT_GET_USHORT(); ! data_pos = table_start + FT_GET_USHORT(); /* The documentation implies there are flags packed into the tuplecount */ /* but John Jenkins tells me that shared points don't apply to cvar */ /* and no other flags are defined */ --- 934,941 ---- FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) goto FExit; ! tupleCount = FT_GET_USHORT(); ! OffsetToData = table_start + FT_GET_USHORT(); /* The documentation implies there are flags packed into the tuplecount */ /* but John Jenkins tells me that shared points don't apply to cvar */ /* and no other flags are defined */ *************** *** 939,945 **** tupleIndex = FT_GET_USHORT(); /* there is no provision here for a global tuple coordinate section */ /* so John says there are no tuple indeces. Just embedded tuples */ ! if ( tupleIndex & 0x8000 ) { for ( j=0; jnum_axis; ++j ) tuple_coords[j] = FT_GET_SHORT()<<2; /* Convert from short frac to fixed */ --- 948,954 ---- tupleIndex = FT_GET_USHORT(); /* there is no provision here for a global tuple coordinate section */ /* so John says there are no tuple indeces. Just embedded tuples */ ! if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) { for ( j=0; jnum_axis; ++j ) tuple_coords[j] = FT_GET_SHORT()<<2; /* Convert from short frac to fixed */ *************** *** 947,959 **** else { /* Skip this tuple, it makes no sense */ ! if ( tupleIndex&0x4000 ) for ( j=0; j<2*blend->num_axis; ++j ) (void) FT_GET_SHORT(); ! data_pos += tupleDataSize; continue; } ! if ( tupleIndex & 0x4000 ) { for ( j=0; jnum_axis; ++j ) im_start_coords[j] = FT_GET_SHORT()<<2; --- 956,968 ---- else { /* Skip this tuple, it makes no sense */ ! if ( tupleIndex&GX_TI_INTERMEDIATE_TUPLE ) for ( j=0; j<2*blend->num_axis; ++j ) (void) FT_GET_SHORT(); ! OffsetToData += tupleDataSize; continue; } ! if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) { for ( j=0; jnum_axis; ++j ) im_start_coords[j] = FT_GET_SHORT()<<2; *************** *** 966,980 **** im_start_coords, im_end_coords); if ( apply==0 || /* tuple isn't active for our blend */ ! !(tupleIndex&0x2000) ) /* global points not allowed, if they aren't local, makes no sense */ { ! data_pos += tupleDataSize; continue; } here = FT_Stream_FTell(stream); ! FT_Stream_SeekSet( stream, data_pos ); localpoints = ft_var_readpackedpoints( stream, &point_count ); deltas = ft_var_readpackeddeltas( stream, point_count==0 ? face->cvt_size : point_count ); --- 975,989 ---- im_start_coords, im_end_coords); if ( apply==0 || /* tuple isn't active for our blend */ ! !(tupleIndex&GX_TI_PRIVATE_POINT_NUMBERS) ) /* global points not allowed, if they aren't local, makes no sense */ { ! OffsetToData += tupleDataSize; continue; } here = FT_Stream_FTell(stream); ! FT_Stream_SeekSet( stream, OffsetToData ); localpoints = ft_var_readpackedpoints( stream, &point_count ); deltas = ft_var_readpackeddeltas( stream, point_count==0 ? face->cvt_size : point_count ); *************** *** 994,1000 **** FT_FREE( localpoints ); FT_FREE( deltas ); ! data_pos += tupleDataSize; FT_Stream_SeekSet( stream, here ); } --- 1003,1009 ---- FT_FREE( localpoints ); FT_FREE( deltas ); ! OffsetToData += tupleDataSize; FT_Stream_SeekSet( stream, here ); } *************** *** 1046,1052 **** FT_Error error; FT_ULong glyph_start; FT_Int tupleCount; ! FT_ULong data_pos; FT_ULong here; FT_Int i,j; FT_Fixed *tuple_coords = NULL; --- 1055,1061 ---- FT_Error error; FT_ULong glyph_start; FT_Int tupleCount; ! FT_ULong OffsetToData; FT_ULong here; FT_Int i,j; FT_Fixed *tuple_coords = NULL; *************** *** 1063,1069 **** if ( (error = FT_NEW_ARRAY(delta_xy, n_points)) ) goto Fail; - FT_MEM_ZERO( delta_xy, n_points*sizeof(FT_Vector)); *_delta_xy = delta_xy; if ( glyph_index >= blend->gv_glyphcnt || --- 1072,1077 ---- *************** *** 1085,1114 **** FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) goto Exit; ! tupleCount = FT_GET_USHORT(); ! data_pos = glyph_start + FT_GET_USHORT(); ! if ( tupleCount & 0x8000 ) { FT_ULong here = FT_Stream_FTell( stream ); ! FT_Stream_SeekSet( stream, data_pos ); ! sharedpoints = ft_var_readpackedpoints( stream, &spoint_count ); ! data_pos = FT_Stream_FTell( stream ); FT_Stream_SeekSet( stream, here ); } ! for ( i=0; i<(tupleCount&0xfff); ++i ) { FT_Int tupleDataSize; FT_Int tupleIndex; FT_Fixed apply; tupleDataSize = FT_GET_USHORT(); tupleIndex = FT_GET_USHORT(); ! if ( tupleIndex & 0x8000 ) { for ( j=0; jnum_axis; ++j ) tuple_coords[j] = FT_GET_SHORT()<<2; /* Convert from short frac to fixed */ } ! else if ( (tupleIndex&0xfff) >= blend->tuplecount ) { error = TT_Err_Invalid_Table; goto Fail; --- 1093,1122 ---- FT_NEW_ARRAY( im_end_coords, blend->num_axis ) ) goto Exit; ! tupleCount = FT_GET_USHORT(); ! OffsetToData = glyph_start + FT_GET_USHORT(); ! if ( tupleCount & GX_TC_TUPLES_SHARE_POINT_NUMBERS ) { FT_ULong here = FT_Stream_FTell( stream ); ! FT_Stream_SeekSet( stream, OffsetToData ); ! sharedpoints = ft_var_readpackedpoints( stream, &spoint_count ); ! OffsetToData = FT_Stream_FTell( stream ); FT_Stream_SeekSet( stream, here ); } ! for ( i=0; i<(tupleCount&GX_TC_TUPLE_COUNT_MASK); ++i ) { FT_Int tupleDataSize; FT_Int tupleIndex; FT_Fixed apply; tupleDataSize = FT_GET_USHORT(); tupleIndex = FT_GET_USHORT(); ! if ( tupleIndex & GX_TI_EMBEDDED_TUPLE_COORD ) { for ( j=0; jnum_axis; ++j ) tuple_coords[j] = FT_GET_SHORT()<<2; /* Convert from short frac to fixed */ } ! else if ( (tupleIndex&GX_TI_TUPLE_INDEX_MASK) >= blend->tuplecount ) { error = TT_Err_Invalid_Table; goto Fail; *************** *** 1118,1124 **** FT_MEM_COPY( tuple_coords, &blend->tuplecoords[(tupleIndex&0xfff)*blend->num_axis], blend->num_axis*sizeof(FT_Fixed)); } ! if ( tupleIndex & 0x4000 ) { for ( j=0; jnum_axis; ++j ) im_start_coords[j] = FT_GET_SHORT()<<2; --- 1126,1132 ---- FT_MEM_COPY( tuple_coords, &blend->tuplecoords[(tupleIndex&0xfff)*blend->num_axis], blend->num_axis*sizeof(FT_Fixed)); } ! if ( tupleIndex & GX_TI_INTERMEDIATE_TUPLE ) { for ( j=0; jnum_axis; ++j ) im_start_coords[j] = FT_GET_SHORT()<<2; *************** *** 1132,1145 **** im_end_coords); if ( apply==0 ) /* tuple isn't active for our blend */ { ! data_pos += tupleDataSize; continue; } here = FT_Stream_FTell(stream); ! if ( tupleIndex&0x2000 ) { ! FT_Stream_SeekSet( stream, data_pos ); localpoints = ft_var_readpackedpoints( stream, &point_count ); points = localpoints; } --- 1140,1153 ---- im_end_coords); if ( apply==0 ) /* tuple isn't active for our blend */ { ! OffsetToData += tupleDataSize; continue; } here = FT_Stream_FTell(stream); ! if ( tupleIndex&GX_TI_PRIVATE_POINT_NUMBERS ) { ! FT_Stream_SeekSet( stream, OffsetToData ); localpoints = ft_var_readpackedpoints( stream, &point_count ); points = localpoints; } *************** *** 1175,1181 **** FT_FREE( deltas_x ); FT_FREE( deltas_y ); ! data_pos += tupleDataSize; FT_Stream_SeekSet( stream, here ); } --- 1183,1189 ---- FT_FREE( deltas_x ); FT_FREE( deltas_y ); ! OffsetToData += tupleDataSize; FT_Stream_SeekSet( stream, here ); } *** src/truetype/ttgxvar.h~ 2004-04-12 09:35:32.000000000 -0700 --- src/truetype/ttgxvar.h 2004-04-12 09:36:05.000000000 -0700 *************** *** 87,92 **** --- 87,132 ---- + /*************************************************************************/ + /* */ + /* */ + /* GX_TupleCountFlags */ + /* */ + /* */ + /* Flags used within the TupleCount field of gvar. */ + /* */ + /*************************************************************************/ + typedef enum + { + GX_TC_TUPLES_SHARE_POINT_NUMBERS = 0x8000, + GX_TC_RESERVED_TUPLE_FLAGS = 0x7000, + GX_TC_TUPLE_COUNT_MASK = 0x0FFF + } GX_TupleCountFlags ; + + + /*************************************************************************/ + /* */ + /* */ + /* GX_TupleIndexFlags */ + /* */ + /* */ + /* Flags used within the TupleIndex field of gvar/cvar. */ + /* */ + /*************************************************************************/ + typedef enum + { + GX_TI_EMBEDDED_TUPLE_COORD = 0x8000, + GX_TI_INTERMEDIATE_TUPLE = 0x4000, + GX_TI_PRIVATE_POINT_NUMBERS = 0x2000, + GX_TI_RESERVED_TUPLE_FLAG = 0x1000, + GX_TI_TUPLE_INDEX_MASK = 0x0FFF + } GX_TupleIndexFlags ; + + + #define TTAG_wght FT_MAKE_TAG( 'w', 'g', 'h', 't' ) + #define TTAG_wdth FT_MAKE_TAG( 'w', 'd', 't', 'h' ) + #define TTAG_opsz FT_MAKE_TAG( 'o', 'p', 's', 'z' ) + #define TTAG_slnt FT_MAKE_TAG( 's', 'l', 'n', 't' ) FT_LOCAL_DEF( FT_Error ) TT_Set_MM_Blend( TT_Face face,