diff --git a/ChangeLog b/ChangeLog index e2a62d702..f5094ae2d 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,43 @@ +2015-08-13 Werner Lemberg + + [truetype] Introduce named instance access to GX fonts. + + For functions querying a face, bits 16-30 of the face index can hold + the named instance index if we have a GX font. The indices start + with value 1; value 0 indicates font access without GX variation + data. + + * include/freetype/freetype.h (FT_FaceRec): Update documentation. + * include/freetype/internal/sfnt.h: Ditto. + + * src/sfnt/sfobjs.c (sfnt_init_face) + [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: Get number of named instances and + do argument checks. + (sfnt_load_face): Updated. + + * src/truetype/ttobjs.c (tt_face_init) + [TT_CONFIG_OPTION_GX_VAR_SUPPORT]: Use named instance, overwriting + the style name. + + * src/base/ftobjs.c (open_face_from_buffer, + open_face_PS_from_sfnt_stream): Updated. + * src/bdf/bdfdrivr.c (BDF_Face_Init): Updated. + * src/cff/cffload.c (cff_font_load): Updated. + + * src/cff/cffobjs.c (cff_face_init): Make function exit early for + pure CFF fonts if `font_index < 0'. + Updated. + + * src/cid/cidobjs.c (cid_face_init): Updated. + * src/pcf/pcfdrivr.c (PCF_Face_Init): Updated. + * src/pfr/pfrobjs.c (pfr_face_init): Updated. + * src/type1/t1objs.c (T1_Face_Init): Updated. + * src/type42/t42objs.c (T42_Face_Init): Updated. + * src/winfonts/winfnt.c (fnt_face_get_dll_font, FNT_Face_Init): + Updated. + + * docs/CHANGES: Updated. + 2015-08-12 Alexei Podtelezhnikov [type1,cff,cid] Streamline font matrix application. diff --git a/docs/CHANGES b/docs/CHANGES index 022e6b4e7..ec417c658 100644 --- a/docs/CHANGES +++ b/docs/CHANGES @@ -33,6 +33,19 @@ CHANGES BETWEEN 2.6 and 2.6.1 don't need any change to the source code. + - Simple access to named instances in GX variation fonts is now + available (in addition to the previous method via FreeType's MM + interface). In the FT_Face structure, bits 16-30 of the + `face_index' field hold the current named instance index for the + given face index, and bits 16-30 of `style_flags' contain the + number of instances for the given face index. `FT_Open_Face' + and friends also understand the extended bits of the face index + parameter. + + You need to enable TT_CONFIG_OPTION_GX_VAR_SUPPORT for this new + feature. Otherwise, bits 16-30 of the two fields are zero (or + are ignored). + III. MISCELLANEOUS diff --git a/include/freetype/freetype.h b/include/freetype/freetype.h index 31f9e11f4..f3a9d6fd7 100644 --- a/include/freetype/freetype.h +++ b/include/freetype/freetype.h @@ -876,17 +876,36 @@ FT_BEGIN_HEADER /* font formats can have multiple faces in */ /* a font file. */ /* */ - /* face_index :: The index of the face in the font file. It */ - /* is set to~0 if there is only one face in */ + /* face_index :: This field holds two different values. */ + /* Bits 0-15 are the index of the face in the */ + /* font file (starting with value~0). They */ + /* are set to~0 if there is only one face in */ /* the font file. */ /* */ + /* Bits 16-30 are relevant to GX variation */ + /* fonts only, holding the named instance */ + /* index for the current face index (starting */ + /* with value~1; value~0 indicates font access */ + /* without GX variation data). For non-GX */ + /* fonts, bits 16-30 are ignored. If we have */ + /* the third named instance of face~4, say, */ + /* `face_index' is set to 0x00030004. */ + /* */ + /* Bit 31 is always zero (this is, */ + /* `face_index' is always a positive value). */ + /* */ /* face_flags :: A set of bit flags that give important */ /* information about the face; see */ /* @FT_FACE_FLAG_XXX for the details. */ /* */ - /* style_flags :: A set of bit flags indicating the style of */ - /* the face; see @FT_STYLE_FLAG_XXX for the */ - /* details. */ + /* style_flags :: The lower 16~bits contain a set of bit */ + /* flags indicating the style of the face; see */ + /* @FT_STYLE_FLAG_XXX for the details. Bits */ + /* 16-30 hold the number of named instances */ + /* available for the current face if we have a */ + /* GX variation (sub)font. Bit 31 is always */ + /* zero (this is, `style_flags' is always a */ + /* positive value). */ /* */ /* num_glyphs :: The number of glyphs in the face. If the */ /* face is scalable and has sbits (see */ @@ -1392,7 +1411,7 @@ FT_BEGIN_HEADER /* FT_STYLE_FLAG_XXX */ /* */ /* */ - /* A list of bit-flags used to indicate the style of a given face. */ + /* A list of bit flags used to indicate the style of a given face. */ /* These are used in the `style_flags' field of @FT_FaceRec. */ /* */ /* */ @@ -1824,7 +1843,7 @@ FT_BEGIN_HEADER /* FT_OPEN_XXX */ /* */ /* */ - /* A list of bit-field constants used within the `flags' field of the */ + /* A list of bit field constants used within the `flags' field of the */ /* @FT_Open_Args structure. */ /* */ /* */ @@ -1971,13 +1990,12 @@ FT_BEGIN_HEADER /* */ /* pathname :: A path to the font file. */ /* */ - /* face_index :: The index of the face within the font. The first */ - /* face has index~0. */ + /* face_index :: See @FT_Open_Face for a detailed description of this */ + /* parameter. */ /* */ /* */ /* aface :: A handle to a new face object. If `face_index' is */ /* greater than or equal to zero, it must be non-NULL. */ - /* See @FT_Open_Face for more details. */ /* */ /* */ /* FreeType error code. 0~means success. */ @@ -2010,13 +2028,12 @@ FT_BEGIN_HEADER /* */ /* file_size :: The size of the memory chunk used by the font data. */ /* */ - /* face_index :: The index of the face within the font. The first */ - /* face has index~0. */ + /* face_index :: See @FT_Open_Face for a detailed description of this */ + /* parameter. */ /* */ /* */ /* aface :: A handle to a new face object. If `face_index' is */ /* greater than or equal to zero, it must be non-NULL. */ - /* See @FT_Open_Face for more details. */ /* */ /* */ /* FreeType error code. 0~means success. */ @@ -2048,13 +2065,43 @@ FT_BEGIN_HEADER /* args :: A pointer to an `FT_Open_Args' structure that must */ /* be filled by the caller. */ /* */ - /* face_index :: The index of the face within the font. The first */ - /* face has index~0. */ + /* face_index :: This field holds two different values. Bits 0-15 */ + /* are the index of the face in the font file (starting */ + /* with value~0). Set it to~0 if there is only one */ + /* face in the font file. */ + /* */ + /* Bits 16-30 are relevant to GX variation fonts only, */ + /* specifying the named instance index for the current */ + /* face index (starting with value~1; value~0 makes */ + /* FreeType ignore named instances). For non-GX fonts, */ + /* bits 16-30 are ignored. Assuming that you want to */ + /* access the third named instance in face~4, */ + /* `face_index' should be set to 0x00030004. If you */ + /* want to access face~4 without GX variation handling, */ + /* simply set `face_index' to value~4. */ + /* */ + /* FT_Open_Face and its siblings can be used to quickly */ + /* check whether the font format of a given font */ + /* resource is supported by FreeType. In general, if */ + /* the `face_index' argument is negative, the */ + /* function's return value is~0 if the font format is */ + /* recognized, or non-zero otherwise. The function */ + /* allocates a more or less empty face handle in */ + /* `*aface' (if `aface' isn't NULL); the only two */ + /* useful fields in this special case are */ + /* `face->num_faces' and `face->style_flags'. For any */ + /* negative value of `face_index', `face->num_faces' */ + /* gives the number of faces within the font file. For */ + /* the negative value `-(N+1)' (with `N' a 16-bit */ + /* value), bits 16-30 in `face->style_flags' give the */ + /* number of named instances in face `N' if we have a */ + /* GX variation font (or zero otherwise). After */ + /* examination, the returned @FT_Face structure should */ + /* be deallocated with a call to @FT_Done_Face. */ /* */ /* */ /* aface :: A handle to a new face object. If `face_index' is */ /* greater than or equal to zero, it must be non-NULL. */ - /* See note below. */ /* */ /* */ /* FreeType error code. 0~means success. */ @@ -2064,16 +2111,6 @@ FT_BEGIN_HEADER /* slot for the face object that can be accessed directly through */ /* `face->glyph'. */ /* */ - /* FT_Open_Face can be used to quickly check whether the font */ - /* format of a given font resource is supported by FreeType. If the */ - /* `face_index' field is negative, the function's return value is~0 */ - /* if the font format is recognized, or non-zero otherwise; */ - /* the function returns a more or less empty face handle in `*aface' */ - /* (if `aface' isn't NULL). The only useful field in this special */ - /* case is `face->num_faces' that gives the number of faces within */ - /* the font file. After examination, the returned @FT_Face structure */ - /* should be deallocated with a call to @FT_Done_Face. */ - /* */ /* Each new face object created with this function also owns a */ /* default @FT_Size object, accessible as `face->size'. */ /* */ @@ -2084,6 +2121,74 @@ FT_BEGIN_HEADER /* See the discussion of reference counters in the description of */ /* @FT_Reference_Face. */ /* */ + /* To loop over all faces, use code similar to the following snippet */ + /* (omitting the error handling). */ + /* */ + /* { */ + /* ... */ + /* FT_Face face; */ + /* FT_Long i, num_faces; */ + /* */ + /* */ + /* error = FT_Open_Face( library, args, -1, &face ); */ + /* if ( error ) { ... } */ + /* */ + /* num_faces = face->num_faces; */ + /* FT_Done_Face( face ); */ + /* */ + /* for ( i = 0; i < num_faces; i++ ) */ + /* { */ + /* ... */ + /* error = FT_Open_Face( library, args, i, &face ); */ + /* ... */ + /* FT_Done_Face( face ); */ + /* ... */ + /* } */ + /* } */ + /* */ + /* To loop over all valid values for `face_index', use something */ + /* similar to the following snippet, again without error handling. */ + /* The code accesses all faces immediately (thus only a single call */ + /* of `FT_Open_Face' within the do-loop), with and without named */ + /* instances. */ + /* */ + /* { */ + /* ... */ + /* FT_Face face; */ + /* */ + /* FT_Long num_faces = 0; */ + /* FT_Long num_instances = 0; */ + /* */ + /* FT_Long face_idx = 0; */ + /* FT_Long instance_idx = 0; */ + /* */ + /* */ + /* do */ + /* { */ + /* FT_Long id = ( instance_idx << 16 ) + face_idx; */ + /* */ + /* */ + /* error = FT_Open_Face( library, args, id, &face ); */ + /* if ( error ) { ... } */ + /* */ + /* num_faces = face->num_faces; */ + /* num_instances = face->style_flags >> 16; */ + /* */ + /* ... */ + /* */ + /* FT_Done_Face( face ); */ + /* */ + /* if ( instance_idx < num_instances ) */ + /* instance_idx++; */ + /* else */ + /* { */ + /* face_idx++; */ + /* instance_idx = 0; */ + /* } */ + /* */ + /* } while ( face_idx < num_faces ) */ + /* } */ + /* */ FT_EXPORT( FT_Error ) FT_Open_Face( FT_Library library, const FT_Open_Args* args, @@ -2521,7 +2626,7 @@ FT_BEGIN_HEADER * FT_LOAD_XXX * * @description: - * A list of bit-field constants used with @FT_Load_Glyph to indicate + * A list of bit field constants used with @FT_Load_Glyph to indicate * what kind of operations to perform during glyph loading. * * @values: diff --git a/include/freetype/internal/sfnt.h b/include/freetype/internal/sfnt.h index bcaa3a0fb..30f53bf09 100644 --- a/include/freetype/internal/sfnt.h +++ b/include/freetype/internal/sfnt.h @@ -44,7 +44,9 @@ FT_BEGIN_HEADER /* face :: A handle to the target face object. */ /* */ /* face_index :: The index of the TrueType font, if we are opening a */ - /* collection. */ + /* collection, in bits 0-15. The numbered instance */ + /* index~+~1 of a GX (sub)font, if applicable, in bits */ + /* 16-30. */ /* */ /* num_params :: The number of additional parameters. */ /* */ @@ -87,7 +89,9 @@ FT_BEGIN_HEADER /* face :: A handle to the target face object. */ /* */ /* face_index :: The index of the TrueType font, if we are opening a */ - /* collection. */ + /* collection, in bits 0-15. The numbered instance */ + /* index~+~1 of a GX (sub)font, if applicable, in bits */ + /* 16-30. */ /* */ /* num_params :: The number of additional parameters. */ /* */ diff --git a/src/base/ftobjs.c b/src/base/ftobjs.c index 4fa05933d..926ac0adb 100644 --- a/src/base/ftobjs.c +++ b/src/base/ftobjs.c @@ -1375,13 +1375,13 @@ } #ifdef FT_MACINTOSH - /* At this point, face_index has served its purpose; */ + /* At this point, the face index has served its purpose; */ /* whoever calls this function has already used it to */ /* locate the correct font data. We should not propagate */ /* this index to FT_Open_Face() (unless it is negative). */ if ( face_index > 0 ) - face_index = 0; + face_index &= 0x7FFF0000L; /* retain GX data */ #endif error = FT_Open_Face( library, &args, face_index, aface ); @@ -1495,6 +1495,10 @@ FT_UNUSED( params ); + /* ignore GX stuff */ + if ( face_index > 0 ) + face_index &= 0xFFFFL; + pos = FT_STREAM_POS(); error = ft_lookup_PS_in_sfnt_stream( stream, @@ -1737,7 +1741,7 @@ /* The resource header says we've got resource_cnt `sfnt' */ /* (TrueType/OpenType) resources in this file. Look through */ /* them for the one indicated by face_index, load it into mem, */ - /* pass it on the the truetype driver and return it. */ + /* pass it on to the truetype driver, and return it. */ /* */ static FT_Error Mac_Read_sfnt_Resource( FT_Library library, diff --git a/src/bdf/bdfdrivr.c b/src/bdf/bdfdrivr.c index 8bd9eeb8f..404af517e 100644 --- a/src/bdf/bdfdrivr.c +++ b/src/bdf/bdfdrivr.c @@ -379,7 +379,8 @@ THE SOFTWARE. * an invalid argument error when the font could be * opened by the specified driver. */ - if ( face_index > 0 ) { + if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 ) + { FT_ERROR(( "BDF_Face_Init: invalid face index\n" )); BDF_Face_Done( bdfface ); return FT_THROW( Invalid_Argument ); diff --git a/src/cff/cffload.c b/src/cff/cffload.c index fcb7348e8..c61222d65 100644 --- a/src/cff/cffload.c +++ b/src/cff/cffload.c @@ -1495,9 +1495,9 @@ if ( pure_cff ) { /* well, we don't really forget the `disabled' fonts... */ - subfont_index = (FT_UInt)face_index; + subfont_index = (FT_UInt)( face_index & 0xFFFF ); - if ( subfont_index >= font->name_index.count ) + if ( face_index > 0 && subfont_index >= font->name_index.count ) { FT_ERROR(( "cff_font_load:" " invalid subfont index for pure CFF font (%d)\n", diff --git a/src/cff/cffobjs.c b/src/cff/cffobjs.c index bdc5d2ab5..0e0d5b034 100644 --- a/src/cff/cffobjs.c +++ b/src/cff/cffobjs.c @@ -583,10 +583,15 @@ if ( error ) goto Exit; + /* if we are performing a simple font format check, exit immediately */ + /* (this is here for pure CFF) */ + if ( face_index < 0 ) + return FT_Err_Ok; + cff->pshinter = pshinter; cff->psnames = psnames; - cffface->face_index = face_index; + cffface->face_index = face_index & 0xFFFF; /* Complement the root flags with some interesting information. */ /* Note that this is only necessary for pure CFF and CEF fonts; */ @@ -765,8 +770,9 @@ (FT_Short)( dict->underline_thickness >> 16 ); /* retrieve font family & style name */ - cffface->family_name = cff_index_get_name( cff, - (FT_UInt)face_index ); + cffface->family_name = cff_index_get_name( + cff, + (FT_UInt)( face_index & 0xFFFF ) ); if ( cffface->family_name ) { char* full = cff_index_get_sid_string( cff, diff --git a/src/cid/cidobjs.c b/src/cid/cidobjs.c index a3d6895c9..bf1519bc6 100644 --- a/src/cid/cidobjs.c +++ b/src/cid/cidobjs.c @@ -334,7 +334,7 @@ /* check the face index */ /* XXX: handle CID fonts with more than a single face */ - if ( face_index != 0 ) + if ( ( face_index & 0xFFFF ) != 0 ) { FT_ERROR(( "cid_face_init: invalid face index\n" )); error = FT_THROW( Invalid_Argument ); @@ -354,7 +354,7 @@ cidface->num_glyphs = (FT_Long)cid->cid_count; cidface->num_charmaps = 0; - cidface->face_index = face_index; + cidface->face_index = face_index & 0xFFFF; cidface->face_flags |= FT_FACE_FLAG_SCALABLE | /* scalable outlines */ FT_FACE_FLAG_HORIZONTAL | /* horizontal data */ diff --git a/src/pcf/pcfdrivr.c b/src/pcf/pcfdrivr.c index 5984adc7b..8d2ed7cf4 100644 --- a/src/pcf/pcfdrivr.c +++ b/src/pcf/pcfdrivr.c @@ -345,13 +345,14 @@ THE SOFTWARE. #endif } - /* PCF could not have multiple face in single font file. - * XXX: non-zero face_index is already invalid argument, but - * Type1, Type42 driver has a convention to return + /* PCF cannot have multiple faces in a single font file. + * XXX: A non-zero face_index is already an invalid argument, but + * Type1, Type42 drivers have a convention to return * an invalid argument error when the font could be * opened by the specified driver. */ - if ( face_index > 0 ) { + if ( face_index > 0 && ( face_index & 0xFFFF ) > 0 ) + { FT_ERROR(( "PCF_Face_Init: invalid face index\n" )); PCF_Face_Done( pcfface ); return FT_THROW( Invalid_Argument ); diff --git a/src/pfr/pfrobjs.c b/src/pfr/pfrobjs.c index aababf4a2..b854b00ba 100644 --- a/src/pfr/pfrobjs.c +++ b/src/pfr/pfrobjs.c @@ -109,7 +109,7 @@ if ( face_index < 0 ) goto Exit; - if ( face_index >= pfrface->num_faces ) + if ( ( face_index & 0xFFFF ) >= pfrface->num_faces ) { FT_ERROR(( "pfr_face_init: invalid face index\n" )); error = FT_THROW( Invalid_Argument ); @@ -118,7 +118,7 @@ /* load the face */ error = pfr_log_font_load( - &face->log_font, stream, (FT_UInt)face_index, + &face->log_font, stream, (FT_UInt)( face_index & 0xFFFF ), face->header.log_dir_offset, FT_BOOL( face->header.phy_font_max_size_high != 0 ) ); if ( error ) @@ -136,7 +136,7 @@ PFR_PhyFont phy_font = &face->phy_font; - pfrface->face_index = face_index; + pfrface->face_index = face_index & 0xFFFF; pfrface->num_glyphs = (FT_Long)phy_font->num_chars + 1; pfrface->face_flags |= FT_FACE_FLAG_SCALABLE; diff --git a/src/sfnt/sfobjs.c b/src/sfnt/sfobjs.c index 9a4ec1f83..14d3adef2 100644 --- a/src/sfnt/sfobjs.c +++ b/src/sfnt/sfobjs.c @@ -821,13 +821,14 @@ FT_LOCAL_DEF( FT_Error ) sfnt_init_face( FT_Stream stream, TT_Face face, - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ) { - FT_Error error; - FT_Library library = face->root.driver->root.library; - SFNT_Service sfnt; + FT_Error error; + FT_Library library = face->root.driver->root.library; + SFNT_Service sfnt; + FT_Int face_index; /* for now, parameters are unused */ @@ -860,22 +861,65 @@ /* Stream may have changed in sfnt_open_font. */ stream = face->root.stream; - FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_index )); + FT_TRACE2(( "sfnt_init_face: %08p, %ld\n", face, face_instance_index )); - if ( face_index < 0 ) - face_index = 0; + face_index = FT_ABS( face_instance_index ) & 0xFFFF; if ( face_index >= face->ttc_header.count ) - return FT_THROW( Invalid_Argument ); + { + if ( face_instance_index >= 0 ) + return FT_THROW( Invalid_Argument ); + else + face_index = 0; + } if ( FT_STREAM_SEEK( face->ttc_header.offsets[face_index] ) ) return error; - /* check that we have a valid TrueType file */ + /* check whether we have a valid TrueType file */ error = sfnt->load_font_dir( face, stream ); if ( error ) return error; +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + { + FT_ULong fvar_len; + FT_UShort num_instances; + FT_Int instance_index; + + + instance_index = FT_ABS( face_instance_index ) >> 16; + + /* test whether current face is a GX font with named instances */ + if ( face->goto_table( face, TTAG_fvar, stream, &fvar_len ) || + fvar_len < 20 || + FT_STREAM_SKIP( 12 ) || + FT_READ_USHORT( num_instances ) ) + num_instances = 0; + + /* we support at most 2^15 - 1 instances */ + if ( num_instances >= ( 1U << 15 ) - 1 ) + { + if ( face_instance_index >= 0 ) + return FT_THROW( Invalid_Argument ); + else + num_instances = 0; + } + + /* instance indices in `face_instance_index' start with index 1, */ + /* thus `>' and not `>=' */ + if ( instance_index > num_instances ) + { + if ( face_instance_index >= 0 ) + return FT_THROW( Invalid_Argument ); + else + num_instances = 0; + } + + face->root.style_flags = (FT_Long)num_instances << 16; + } +#endif + face->root.num_faces = face->ttc_header.count; face->root.face_index = face_index; @@ -928,7 +972,7 @@ FT_LOCAL_DEF( FT_Error ) sfnt_load_face( FT_Stream stream, TT_Face face, - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ) { @@ -944,7 +988,7 @@ SFNT_Service sfnt = (SFNT_Service)face->sfnt; - FT_UNUSED( face_index ); + FT_UNUSED( face_instance_index ); /* Check parameters */ @@ -1266,7 +1310,7 @@ flags |= FT_STYLE_FLAG_ITALIC; } - root->style_flags = flags; + root->style_flags |= flags; /*********************************************************************/ /* */ diff --git a/src/sfnt/sfobjs.h b/src/sfnt/sfobjs.h index 323780d8b..455f86772 100644 --- a/src/sfnt/sfobjs.h +++ b/src/sfnt/sfobjs.h @@ -31,14 +31,14 @@ FT_BEGIN_HEADER FT_LOCAL( FT_Error ) sfnt_init_face( FT_Stream stream, TT_Face face, - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ); FT_LOCAL( FT_Error ) sfnt_load_face( FT_Stream stream, TT_Face face, - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ); diff --git a/src/truetype/ttobjs.c b/src/truetype/ttobjs.c index 202aa046f..af4425945 100644 --- a/src/truetype/ttobjs.c +++ b/src/truetype/ttobjs.c @@ -490,7 +490,10 @@ /* */ /* stream :: The source font stream. */ /* */ - /* face_index :: The index of the font face in the resource. */ + /* face_index :: The index of the TrueType font, if we are opening a */ + /* collection, in bits 0-15. The numbered instance */ + /* index~+~1 of a GX (sub)font, if applicable, in bits */ + /* 16-30. */ /* */ /* num_params :: Number of additional generic parameters. Ignored. */ /* */ @@ -599,7 +602,7 @@ ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; } -#else +#else /* !FT_CONFIG_OPTION_INCREMENTAL */ if ( !error ) error = tt_face_load_loca( face, stream ); @@ -623,10 +626,56 @@ ttface->face_flags &= ~FT_FACE_FLAG_SCALABLE; } -#endif +#endif /* !FT_CONFIG_OPTION_INCREMENTAL */ } +#ifdef TT_CONFIG_OPTION_GX_VAR_SUPPORT + + { + FT_Int instance_index = face_index >> 16; + + + if ( FT_HAS_MULTIPLE_MASTERS( ttface ) && + instance_index > 0 ) + { + error = TT_Get_MM_Var( face, NULL ); + if ( error ) + goto Exit; + + if ( face->blend->mmvar->namedstyle ) + { + FT_Memory memory = ttface->memory; + + FT_Var_Named_Style* named_style; + FT_String* style_name; + + + /* in `face_index', the instance index starts with value 1 */ + named_style = face->blend->mmvar->namedstyle + instance_index - 1; + error = sfnt->get_name( face, + (FT_UShort)named_style->strid, + &style_name ); + if ( error ) + goto Exit; + + /* set style name; if already set, replace it */ + if ( face->root.style_name ) + FT_FREE( face->root.style_name ); + face->root.style_name = style_name; + + /* finally, select the named instance */ + error = TT_Set_Var_Design( face, + face->blend->mmvar->num_axis, + named_style->coords ); + if ( error ) + goto Exit; + } + } + } + +#endif /* TT_CONFIG_OPTION_GX_VAR_SUPPORT */ + #if defined( TT_CONFIG_OPTION_UNPATENTED_HINTING ) && \ !defined( TT_CONFIG_OPTION_BYTECODE_INTERPRETER ) diff --git a/src/type1/t1objs.c b/src/type1/t1objs.c index af8988855..3506e4e3e 100644 --- a/src/type1/t1objs.c +++ b/src/type1/t1objs.c @@ -345,7 +345,7 @@ goto Exit; /* check the face index */ - if ( face_index > 0 ) + if ( ( face_index & 0xFFFF ) > 0 ) { FT_ERROR(( "T1_Face_Init: invalid face index\n" )); error = FT_THROW( Invalid_Argument ); diff --git a/src/type42/t42objs.c b/src/type42/t42objs.c index 01b271f8c..430871ace 100644 --- a/src/type42/t42objs.c +++ b/src/type42/t42objs.c @@ -208,7 +208,7 @@ goto Exit; /* check the face index */ - if ( face_index > 0 ) + if ( ( face_index & 0xFFFF ) > 0 ) { FT_ERROR(( "T42_Face_Init: invalid face index\n" )); error = FT_THROW( Invalid_Argument ); diff --git a/src/winfonts/winfnt.c b/src/winfonts/winfnt.c index 06f1861af..36e3eb0c2 100644 --- a/src/winfonts/winfnt.c +++ b/src/winfonts/winfnt.c @@ -269,16 +269,19 @@ static FT_Error fnt_face_get_dll_font( FNT_Face face, - FT_Int face_index ) + FT_Int face_instance_index ) { FT_Error error; FT_Stream stream = FT_FACE( face )->stream; FT_Memory memory = FT_FACE( face )->memory; WinMZ_HeaderRec mz_header; + FT_Long face_index; face->font = NULL; + face_index = FT_ABS( face_instance_index ) & 0xFFFF; + /* does it begin with an MZ header? */ if ( FT_STREAM_SEEK( 0 ) || FT_STREAM_READ_FIELDS( winmz_header_fields, &mz_header ) ) @@ -359,13 +362,14 @@ face->root.num_faces = font_count; + if ( face_instance_index < 0 ) + goto Exit; + if ( face_index >= font_count ) { error = FT_THROW( Invalid_Argument ); goto Exit; } - else if ( face_index < 0 ) - goto Exit; if ( FT_NEW( face->font ) ) goto Exit; @@ -689,13 +693,14 @@ static FT_Error FNT_Face_Init( FT_Stream stream, FT_Face fntface, /* FNT_Face */ - FT_Int face_index, + FT_Int face_instance_index, FT_Int num_params, FT_Parameter* params ) { FNT_Face face = (FNT_Face)fntface; FT_Error error; FT_Memory memory = FT_FACE_MEMORY( face ); + FT_Int face_index; FT_UNUSED( num_params ); FT_UNUSED( params ); @@ -703,9 +708,11 @@ FT_TRACE2(( "Windows FNT driver\n" )); + face_index = FT_ABS( face_instance_index ) & 0xFFFF; + /* try to load font from a DLL */ - error = fnt_face_get_dll_font( face, face_index ); - if ( !error && face_index < 0 ) + error = fnt_face_get_dll_font( face, face_instance_index ); + if ( !error && face_instance_index < 0 ) goto Exit; if ( FT_ERR_EQ( error, Unknown_File_Format ) ) @@ -726,10 +733,11 @@ if ( !error ) { + if ( face_instance_index < 0 ) + goto Exit; + if ( face_index > 0 ) error = FT_THROW( Invalid_Argument ); - else if ( face_index < 0 ) - goto Exit; } }