From: Masamichi Hosoda Date: Sat, 25 Jun 2016 01:52:44 +0000 (+0900) Subject: Issue 4876/1: Add fontname replacing function for CFF (OTF/OTC) fonts X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=fa2596b6ec273e7d82907f97acf0c65559b3c1b4;p=lilypond.git Issue 4876/1: Add fontname replacing function for CFF (OTF/OTC) fonts For CFF (OTF/OTC) fonts, FT_Get_Postscript_Name () in FreeType 2.6+ gets the name in 'name' table. However, we want the name in 'CFF' table instead of in 'name' table because output postscript file is embedded only 'CFF' table of the font. They are inconsistent for some OpenType/CFF Collection fonts (OTC). This function can get the name in 'CFF' table. TODO: Check conflicts between fonts which have same name in 'CFF' table but different name in 'name' table. --- diff --git a/lily/include/open-type-font.hh b/lily/include/open-type-font.hh index f08d4fa71c..bf36071e91 100644 --- a/lily/include/open-type-font.hh +++ b/lily/include/open-type-font.hh @@ -65,5 +65,6 @@ public: string get_otf_table (FT_Face face, const string &tag); FT_Face open_ft_face (const string&, FT_Long idx); +string get_postscript_name (FT_Face face); #endif /* OPEN_TYPE_FONT_HH */ diff --git a/lily/open-type-font.cc b/lily/open-type-font.cc index 3038df4331..e4fb5d5d98 100644 --- a/lily/open-type-font.cc +++ b/lily/open-type-font.cc @@ -20,6 +20,15 @@ #include "open-type-font.hh" #include "freetype.hh" +#ifdef FT_FONT_FORMATS_H +/* FreeType 2.6+ */ +#include FT_FONT_FORMATS_H +#else +/* FreeType 2.5.5 and earlier */ +#include FT_XFREE86_H +#define FT_Get_Font_Format FT_Get_X11_Font_Format +#endif + #include using namespace std; @@ -120,6 +129,74 @@ open_ft_face (const string &str, FT_Long idx) return face; } +string +get_postscript_name (FT_Face face) +{ + string face_ps_name; + const char *psname = FT_Get_Postscript_Name (face); + if (psname) + face_ps_name = psname; + else + { + warning (_ ("cannot get postscript name")); + return ""; + } + + const char *fmt = FT_Get_Font_Format (face); + if (fmt) + { + if (static_cast(fmt) != "CFF") + return face_ps_name; // For non-CFF font, pass it through. + } + else + { + warning (_f ("cannot get font %s format", face_ps_name.c_str ())); + return face_ps_name; + } + + // For OTF and OTC fonts, we use data from the font's 'CFF' table only + // because other tables are not embedded in the output PS file. + string cff_table = get_otf_table (face, "CFF "); + + FT_Open_Args args; + args.flags = FT_OPEN_MEMORY; + args.memory_base = static_cast + (static_cast(cff_table.data ())); + args.memory_size = cff_table.size (); + + FT_Face cff_face; + // According to OpenType Specification ver 1.7, + // the CFF (derived from OTF and OTC) has only one name. + // So we use zero as the font index. + FT_Error error_code = FT_Open_Face (freetype2_library, &args, + 0 /* font index */, + &cff_face); + if (error_code) + { + warning (_f ("cannot read CFF %s: %s", + face_ps_name, + freetype_error_string (error_code).c_str ())); + return face_ps_name; + } + + string ret; + const char *cffname = FT_Get_Postscript_Name (cff_face); + if (cffname) + ret = cffname; + else + { + warning (_f ("cannot get font %s CFF name", face_ps_name.c_str ())); + ret = face_ps_name; + } + + debug_output (_f ("Replace font name from %s to %s.", + face_ps_name.c_str (), ret.c_str ())); + + FT_Done_Face (cff_face); + + return ret; +} + SCM Open_type_font::make_otf (const string &str) {