On Wed, Mar 11, 2009 at 7:40 AM, Werner LEMBERG <w...@gnu.org> wrote: > >> [...] Another would be the one that I have ended up implementing by >> adding two methods to the cid service interface (pardon my FT >> vocabular -- I haven't spent more that one or two days in the source >> by now). One method to tell me whether a given font really is a CID >> keyed font, in the sense that we've agreed upon in the above. And >> one method to map unicodes to cids for a given font. The mapping >> information is already present in the charset.sids array on the >> internal cff font class, as far as I can tell. So I just had to >> make sure that the sids array wasn't free'd too early and make >> export the mapping via my the cid service. > > This sounds like the right solution to me. Can you post patches?
I've included the diff below. One technical detail that I have been struggling with: It seems that the CID API functions (until my change there was only one function in the API) are not exported when using the Visual project on Windows. Besides from having to include ftcid.c in the project, it seems I have to add "#include FT_CID_H" to ftcid.c to have effect of the __declspec(dllexport) that I have in my ftoption.h file. Another remark. Since the two new functions are in the CID service, they will return a non-zero error value if the driver doesn't support the CID service. This is a bit clumsy if one just wants to know whether a given font in "internally" CID keyed or not... ============ diff -ruN freetype-2.3.8/include/freetype/ftcid.h freetype-2.3.8.new/include/freetype/ftcid.h --- freetype-2.3.8/include/freetype/ftcid.h 2008-06-26 11:50:03.000000000 +0200 +++ freetype-2.3.8.new/include/freetype/ftcid.h 2009-03-09 16:06:05.956707000 +0100 @@ -88,6 +88,72 @@ const char* *ordering, FT_Int *supplement); + /********************************************************************** + * + * @function: + * FT_Get_CID_Is_Internally_CID_Keyed + * + * @description: + * Retrieve the type of the input face, CID keyed or not. In + * constrast to the FT_IS_CID_KEYED macro this function will return + * also for CID keyed fonts in an snft wrapper. + * + * @input: + * face :: + * A handle to the input face. + * + * @output: + * is_cid :: + * The type of the face as an FT_Bool + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces and OpenType fonts, + * returning an error otherwise. + * + * @since: + * 2.3.8-cci + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_Is_Internally_CID_Keyed( FT_Face face, + FT_Bool *is_cid); + + /********************************************************************** + * + * @function: + * FT_Get_CID_From_Glyph_Index + * + * @description: + * Retrieve the CID of the input glyph index. + * + * @input: + * face :: + * A handle to the input face. + * + * glyph_index :: + * The input glyph index. + * + * @output: + * cid :: + * The CID as an FT_UInt. + * + * @return: + * FreeType error code. 0~means success. + * + * @note: + * This function only works with CID faces and OpenType fonts, + * returning an error otherwise. + * + * @since: + * 2.3.8-cci + */ + FT_EXPORT( FT_Error ) + FT_Get_CID_From_Glyph_Index( FT_Face face, + FT_UInt glyph_index, + FT_UInt *cid); + /* */ FT_END_HEADER diff -ruN freetype-2.3.8/include/freetype/internal/services/svcid.h freetype-2.3.8.new/include/freetype/internal/services/svcid.h --- freetype-2.3.8/include/freetype/internal/services/svcid.h 2007-07-16 22:25:34.000000000 +0200 +++ freetype-2.3.8.new/include/freetype/internal/services/svcid.h 2009-03-10 15:27:45.232459000 +0100 @@ -31,10 +31,19 @@ const char* *registry, const char* *ordering, FT_Int *supplement ); + typedef FT_Error + (*FT_CID_GetIsInternallyCIDKeyedFunc)( FT_Face face, + FT_Bool *is_cid); + typedef FT_Error + (*FT_CID_GetCIDFromGlyphIndexFunc)( FT_Face face, + FT_UInt glyph_index, + FT_UInt *cid); FT_DEFINE_SERVICE( CID ) { FT_CID_GetRegistryOrderingSupplementFunc get_ros; + FT_CID_GetIsInternallyCIDKeyedFunc get_is_cid; + FT_CID_GetCIDFromGlyphIndexFunc get_cid_from_glyph_index; }; /* */ diff -ruN freetype-2.3.8/src/base/ftcid.c freetype-2.3.8.new/src/base/ftcid.c --- freetype-2.3.8/src/base/ftcid.c 2008-01-04 08:17:47.000000000 +0100 +++ freetype-2.3.8.new/src/base/ftcid.c 2009-03-11 13:09:02.060507000 +0100 @@ -16,6 +16,7 @@ #include <ft2build.h> +#include FT_CID_H #include FT_INTERNAL_OBJECTS_H #include FT_SERVICE_CID_H @@ -59,5 +60,60 @@ return error; } + FT_EXPORT_DEF( FT_Error ) + FT_Get_CID_Is_Internally_CID_Keyed( FT_Face face, + FT_Bool *is_cid) + { + FT_Error error; + FT_Bool ic = 0; + + + error = FT_Err_Invalid_Argument; + + if ( face ) + { + FT_Service_CID service; + + + FT_FACE_FIND_SERVICE( face, service, CID ); + + if ( service && service->get_is_cid ) + error = service->get_is_cid( face, &ic); + } + + if (is_cid) + *is_cid = ic; + + return error; + } + + FT_EXPORT_DEF( FT_Error ) + FT_Get_CID_From_Glyph_Index( FT_Face face, + FT_UInt glyph_index, + FT_UInt *cid) + { + FT_Error error; + FT_UInt c = 0; + + + error = FT_Err_Invalid_Argument; + + if ( face ) + { + FT_Service_CID service; + + + FT_FACE_FIND_SERVICE( face, service, CID ); + + if ( service && service->get_cid_from_glyph_index ) + error = service->get_cid_from_glyph_index( face, glyph_index, &c); + } + + if (cid) + *cid = c; + + return error; + } + /* END */ diff -ruN freetype-2.3.8/src/cff/cffdrivr.c freetype-2.3.8.new/src/cff/cffdrivr.c --- freetype-2.3.8/src/cff/cffdrivr.c 2009-01-11 11:55:03.000000000 +0100 +++ freetype-2.3.8.new/src/cff/cffdrivr.c 2009-03-10 09:40:34.031409000 +0100 @@ -505,10 +505,71 @@ return error; } + static FT_Error + cff_get_is_cid( CFF_Face face, + FT_Bool *is_cid ) + { + FT_Error error = CFF_Err_Ok; + CFF_Font cff = (CFF_Font)face->extra.data; + + + *is_cid = 0; + + if ( cff ) + { + CFF_FontRecDict dict = &cff->top_font.font_dict; + + + if ( dict->cid_registry != 0xFFFFU ) + *is_cid = 1; + } + + return error; + } + + static FT_Error + cff_get_cid_from_glyph_index( CFF_Face face, + FT_UInt glyph_index, + FT_UInt *cid) + { + FT_Error error = CFF_Err_Ok; + CFF_Font cff; + + + cff = (CFF_Font)face->extra.data; + + if ( cff ) + { + FT_UInt c; + CFF_FontRecDict dict = &cff->top_font.font_dict; + + if ( dict->cid_registry == 0xFFFFU ) + { + error = CFF_Err_Invalid_Argument; + goto Fail; + } + + if (glyph_index > cff->num_glyphs) + { + error = CFF_Err_Invalid_Argument; + goto Fail; + } + + c = cff->charset.sids[glyph_index]; + + if (cid) + *cid = c; + } + + Fail: + return error; + } static const FT_Service_CIDRec cff_service_cid_info = { - (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros + (FT_CID_GetRegistryOrderingSupplementFunc)cff_get_ros, + (FT_CID_GetIsInternallyCIDKeyedFunc)cff_get_is_cid, + (FT_CID_GetCIDFromGlyphIndexFunc)cff_get_cid_from_glyph_index }; diff -ruN freetype-2.3.8/src/cff/cffload.c freetype-2.3.8.new/src/cff/cffload.c --- freetype-2.3.8/src/cff/cffload.c 2008-07-16 07:42:25.000000000 +0200 +++ freetype-2.3.8.new/src/cff/cffload.c 2009-03-10 10:55:55.979309000 +0100 @@ -1541,8 +1541,12 @@ goto Exit; } else - /* CID-keyed fonts only need CIDs */ - FT_FREE( font->charset.sids ); + { + /* CID-keyed fonts only need CIDs */ + /* I need sids! + FT_FREE( font->charset.sids ); + arrray is free'd later as part of cff_font_done() */ + } } /* get the font name (/CIDFontName for CID-keyed fonts, */ diff -ruN freetype-2.3.8/src/cid/cidriver.c freetype-2.3.8.new/src/cid/cidriver.c --- freetype-2.3.8/src/cid/cidriver.c 2008-03-30 11:54:55.000000000 +0200 +++ freetype-2.3.8.new/src/cid/cidriver.c 2009-03-10 11:44:08.247531000 +0100 @@ -112,9 +112,36 @@ } + static FT_Error + cid_get_is_cid( CID_Face face, + FT_Bool *is_cid ) + { + FT_Error error = CID_Err_Ok; + + if (is_cid) + *is_cid = 1; /* cid driver is only used for CID keyed fonts */ + + return error; + } + + static FT_Error + cid_get_cid_from_glyph_index( CID_Face face, + FT_UInt glyph_index, + FT_UInt *cid) + { + FT_Error error = CID_Err_Ok; + + if (cid) + *cid = glyph_index; /* identity mapping */ + + return error; + } + static const FT_Service_CIDRec cid_service_cid_info = { - (FT_CID_GetRegistryOrderingSupplementFunc)cid_get_ros + (FT_CID_GetRegistryOrderingSupplementFunc)cid_get_ros, + (FT_CID_GetIsInternallyCIDKeyedFunc)cid_get_is_cid, + (FT_CID_GetCIDFromGlyphIndexFunc)cid_get_cid_from_glyph_index }; _______________________________________________ Freetype-devel mailing list Freetype-devel@nongnu.org http://lists.nongnu.org/mailman/listinfo/freetype-devel