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
This commit is contained in:
parent
6363d7df28
commit
34f9aa582c
27
src/hb-ft.cc
27
src/hb-ft.cc
|
@ -70,11 +70,12 @@ struct hb_ft_font_t
|
||||||
{
|
{
|
||||||
FT_Face ft_face;
|
FT_Face ft_face;
|
||||||
int load_flags;
|
int load_flags;
|
||||||
|
bool symbol; /* Whether selected cmap is symbol cmap. */
|
||||||
bool unref; /* Whether to destroy ft_face when done. */
|
bool unref; /* Whether to destroy ft_face when done. */
|
||||||
};
|
};
|
||||||
|
|
||||||
static hb_ft_font_t *
|
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));
|
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;
|
return NULL;
|
||||||
|
|
||||||
ft_font->ft_face = ft_face;
|
ft_font->ft_face = ft_face;
|
||||||
|
ft_font->symbol = symbol;
|
||||||
ft_font->unref = unref;
|
ft_font->unref = unref;
|
||||||
|
|
||||||
ft_font->load_flags = FT_LOAD_DEFAULT | FT_LOAD_NO_HINTING;
|
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);
|
unsigned int g = FT_Get_Char_Index (ft_font->ft_face, unicode);
|
||||||
|
|
||||||
if (unlikely (!g))
|
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;
|
*glyph = g;
|
||||||
return true;
|
return true;
|
||||||
|
@ -450,9 +466,11 @@ retry:
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool symbol = ft_face->charmap && ft_face->charmap->encoding == FT_ENCODING_MS_SYMBOL;
|
||||||
|
|
||||||
hb_font_set_funcs (font,
|
hb_font_set_funcs (font,
|
||||||
funcs,
|
funcs,
|
||||||
_hb_ft_font_create (ft_face, unref),
|
_hb_ft_font_create (ft_face, symbol, unref),
|
||||||
(hb_destroy_func_t) _hb_ft_font_destroy);
|
(hb_destroy_func_t) _hb_ft_font_destroy);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -681,7 +699,8 @@ hb_ft_font_set_funcs (hb_font_t *font)
|
||||||
return;
|
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,
|
FT_Set_Char_Size (ft_face,
|
||||||
abs (font->x_scale), abs (font->y_scale),
|
abs (font->x_scale), abs (font->y_scale),
|
||||||
|
|
|
@ -215,6 +215,28 @@ static inline bool get_glyph_from (const void *obj,
|
||||||
return typed_obj->get_glyph (codepoint, glyph);
|
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
|
struct hb_ot_face_cmap_accelerator_t
|
||||||
{
|
{
|
||||||
hb_cmap_get_glyph_func_t get_glyph_func;
|
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::CmapSubtable *subtable = NULL;
|
||||||
const OT::CmapSubtableFormat14 *subtable_uvs = NULL;
|
const OT::CmapSubtableFormat14 *subtable_uvs = NULL;
|
||||||
|
|
||||||
|
bool symbol = false;
|
||||||
/* 32-bit subtables. */
|
/* 32-bit subtables. */
|
||||||
if (!subtable) subtable = cmap->find_subtable (3, 10);
|
if (!subtable) subtable = cmap->find_subtable (3, 10);
|
||||||
if (!subtable) subtable = cmap->find_subtable (0, 6);
|
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, 2);
|
||||||
if (!subtable) subtable = cmap->find_subtable (0, 1);
|
if (!subtable) subtable = cmap->find_subtable (0, 1);
|
||||||
if (!subtable) subtable = cmap->find_subtable (0, 0);
|
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. */
|
/* Meh. */
|
||||||
if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
|
if (!subtable) subtable = &OT::Null(OT::CmapSubtable);
|
||||||
|
|
||||||
|
@ -258,18 +281,21 @@ struct hb_ot_face_cmap_accelerator_t
|
||||||
this->uvs_table = subtable_uvs;
|
this->uvs_table = subtable_uvs;
|
||||||
|
|
||||||
this->get_glyph_data = subtable;
|
this->get_glyph_data = subtable;
|
||||||
switch (subtable->u.format) {
|
if (unlikely (symbol))
|
||||||
/* Accelerate format 4 and format 12. */
|
this->get_glyph_func = get_glyph_from_symbol<OT::CmapSubtable>;
|
||||||
default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>; break;
|
else
|
||||||
case 12: this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>; break;
|
switch (subtable->u.format) {
|
||||||
case 4:
|
/* Accelerate format 4 and format 12. */
|
||||||
{
|
default: this->get_glyph_func = get_glyph_from<OT::CmapSubtable>; break;
|
||||||
this->format4_accel.init (&subtable->u.format4);
|
case 12: this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>; break;
|
||||||
this->get_glyph_data = &this->format4_accel;
|
case 4:
|
||||||
this->get_glyph_func = this->format4_accel.get_glyph_func;
|
{
|
||||||
|
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)
|
inline void fini (void)
|
||||||
|
|
Loading…
Reference in New Issue