summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMasamichi Hosoda <trueroad@trueroad.jp>2016-06-25 10:52:44 +0900
committerMasamichi Hosoda <trueroad@trueroad.jp>2016-07-04 21:46:34 +0900
commitfa2596b6ec273e7d82907f97acf0c65559b3c1b4 (patch)
tree4dbfaf4cbb35177715c0435fd8b3bb3c85580d74
parent6acce8f4c900bee88c85a45b9ed1b29983891469 (diff)
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.
-rw-r--r--lily/include/open-type-font.hh1
-rw-r--r--lily/open-type-font.cc77
2 files changed, 78 insertions, 0 deletions
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 <cstdio>
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<string>(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<const FT_Byte*>
+ (static_cast<const void*>(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)
{