[HarfBuzz] harfbuzz: Branch 'master'
Behdad Esfahbod
behdad at kemper.freedesktop.org
Wed Jul 20 09:37:33 UTC 2016
src/hb-ft.cc | 27 +++++++++++++++++++++++----
src/hb-ot-font.cc | 50 ++++++++++++++++++++++++++++++++++++++------------
2 files changed, 61 insertions(+), 16 deletions(-)
New commits:
commit 34f9aa582c3a03b578c7eae3d2e8860a0bd5cb00
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Jul 20 02:35:54 2016 -0700
Implement symbol cmap in ft and ot fonts
Fixes https://github.com/behdad/harfbuzz/issues/236
Fixes https://bugs.chromium.org/p/chromium/issues/detail?id=627953
diff --git a/src/hb-ft.cc b/src/hb-ft.cc
index 6c6749c..eaa1311 100644
--- a/src/hb-ft.cc
+++ b/src/hb-ft.cc
@@ -70,11 +70,12 @@ struct hb_ft_font_t
{
FT_Face ft_face;
int load_flags;
+ bool symbol; /* Whether selected cmap is symbol cmap. */
bool unref; /* Whether to destroy ft_face when done. */
};
static hb_ft_font_t *
-_hb_ft_font_create (FT_Face ft_face, bool unref)
+_hb_ft_font_create (FT_Face ft_face, bool symbol, bool unref)
{
hb_ft_font_t *ft_font = (hb_ft_font_t *) calloc (1, sizeof (hb_ft_font_t));
@@ -82,6 +83,7 @@ _hb_ft_font_create (FT_Face ft_face, bool unref)
return NULL;
ft_font->ft_face = ft_face;
+ ft_font->symbol = symbol;
ft_font->unref = unref;
ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
@@ -171,7 +173,21 @@ hb_ft_get_nominal_glyph (hb_font_t *font HB_UNUSED,
unsigned int g = FT_Get_Char_Index (ft_font->ft_face, unicode);
if (unlikely (!g))
- return false;
+ {
+ if (unlikely (ft_font->symbol) && unicode <= 0x00FFu)
+ {
+ /* For symbol-encoded OpenType fonts, we duplicate the
+ * U+F000..F0FF range at U+0000..U+00FF. That's what
+ * Windows seems to do, and that's hinted about at:
+ * http://www.microsoft.com/typography/otspec/recom.htm
+ * under "Non-Standard (Symbol) Fonts". */
+ g = FT_Get_Char_Index (ft_font->ft_face, 0xF000u + unicode);
+ if (!g)
+ return false;
+ }
+ else
+ return false;
+ }
*glyph = g;
return true;
@@ -450,9 +466,11 @@ retry:
#endif
};
+ bool symbol = ft_face->charmap && ft_face->charmap->encoding == FT_ENCODING_MS_SYMBOL;
+
hb_font_set_funcs (font,
funcs,
- _hb_ft_font_create (ft_face, unref),
+ _hb_ft_font_create (ft_face, symbol, unref),
(hb_destroy_func_t) _hb_ft_font_destroy);
}
@@ -681,7 +699,8 @@ hb_ft_font_set_funcs (hb_font_t *font)
return;
}
- FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE);
+ if (FT_Select_Charmap (ft_face, FT_ENCODING_UNICODE))
+ FT_Select_Charmap (ft_face, FT_ENCODING_MS_SYMBOL);
FT_Set_Char_Size (ft_face,
abs (font->x_scale), abs (font->y_scale),
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index 39fc849..0b7e31b 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -215,6 +215,28 @@ static inline bool get_glyph_from (const void *obj,
return typed_obj->get_glyph (codepoint, glyph);
}
+template <typename Type>
+static inline bool get_glyph_from_symbol (const void *obj,
+ hb_codepoint_t codepoint,
+ hb_codepoint_t *glyph)
+{
+ const Type *typed_obj = (const Type *) obj;
+ if (likely (typed_obj->get_glyph (codepoint, glyph)))
+ return true;
+
+ if (codepoint <= 0x00FFu)
+ {
+ /* For symbol-encoded OpenType fonts, we duplicate the
+ * U+F000..F0FF range at U+0000..U+00FF. That's what
+ * Windows seems to do, and that's hinted about at:
+ * http://www.microsoft.com/typography/otspec/recom.htm
+ * under "Non-Standard (Symbol) Fonts". */
+ return typed_obj->get_glyph (0xF000u + codepoint, glyph);
+ }
+
+ return false;
+}
+
struct hb_ot_face_cmap_accelerator_t
{
hb_cmap_get_glyph_func_t get_glyph_func;
@@ -231,6 +253,7 @@ struct hb_ot_face_cmap_accelerator_t
const OT::CmapSubtable *subtable = NULL;
const OT::CmapSubtableFormat14 *subtable_uvs = NULL;
+ bool symbol = false;
/* 32-bit subtables. */
if (!subtable) subtable = cmap->find_subtable (3, 10);
if (!subtable) subtable = cmap->find_subtable (0, 6);
@@ -241,7 +264,7 @@ struct hb_ot_face_cmap_accelerator_t
if (!subtable) subtable = cmap->find_subtable (0, 2);
if (!subtable) subtable = cmap->find_subtable (0, 1);
if (!subtable) subtable = cmap->find_subtable (0, 0);
- if (!subtable) subtable = cmap->find_subtable (3, 0);
+ if (!subtable)(subtable = cmap->find_subtable (3, 0)) && (symbol = true);
/* Meh. */
if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
@@ -258,18 +281,21 @@ struct hb_ot_face_cmap_accelerator_t
this->uvs_table = subtable_uvs;
this->get_glyph_data = subtable;
- switch (subtable->u.format) {
- /* Accelerate format 4 and format 12. */
- default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>; break;
- case 12: this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>; break;
- case 4:
- {
- this->format4_accel.init (&subtable->u.format4);
- this->get_glyph_data = &this->format4_accel;
- this->get_glyph_func = this->format4_accel.get_glyph_func;
+ if (unlikely (symbol))
+ this->get_glyph_func = get_glyph_from_symbol<OT::CmapSubtable>;
+ else
+ switch (subtable->u.format) {
+ /* Accelerate format 4 and format 12. */
+ default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>; break;
+ case 12: this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>; break;
+ case 4:
+ {
+ this->format4_accel.init (&subtable->u.format4);
+ this->get_glyph_data = &this->format4_accel;
+ this->get_glyph_func = this->format4_accel.get_glyph_func;
+ }
+ break;
}
- break;
- }
}
inline void fini (void)
More information about the HarfBuzz
mailing list