[ot-font] Implement TrueType v_origin

Fixes https://github.com/harfbuzz/harfbuzz/issues/537
This commit is contained in:
Behdad Esfahbod 2018-10-15 01:09:05 -07:00
parent 6e07076fd0
commit 8dc6296818
3 changed files with 59 additions and 17 deletions

View File

@ -126,6 +126,35 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data,
} }
} }
static hb_bool_t
hb_ot_get_glyph_v_origin (hb_font_t *font,
void *font_data,
hb_codepoint_t glyph,
hb_position_t *x,
hb_position_t *y,
void *user_data HB_UNUSED)
{
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
*x = font->get_glyph_h_advance (glyph) / 2;
hb_glyph_extents_t extents = {0};
bool ret = ot_face->glyf->get_extents (glyph, &extents);
if (ret)
{
const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx.get ();
hb_position_t tsb = vmtx.get_side_bearing (glyph);
*y = font->em_scale_y (extents.y_bearing + tsb);
return true;
}
hb_font_extents_t font_extents;
font->get_h_extents_with_fallback (&font_extents);
*y = font_extents.ascender;
return true;
}
static hb_bool_t static hb_bool_t
hb_ot_get_glyph_extents (hb_font_t *font, hb_ot_get_glyph_extents (hb_font_t *font,
void *font_data, void *font_data,
@ -215,7 +244,7 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot
hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ot_get_glyph_h_advances, nullptr, nullptr); hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ot_get_glyph_h_advances, nullptr, nullptr);
hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr); hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr);
//hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr); //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr);
//hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr); hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr); hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr);
//hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr); //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr);
hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr); hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr);

View File

@ -48,7 +48,7 @@ namespace OT {
struct LongMetric struct LongMetric
{ {
UFWORD advance; /* Advance width/height. */ UFWORD advance; /* Advance width/height. */
FWORD lsb; /* Leading (left/top) side bearing. */ FWORD sb; /* Leading (left/top) side bearing. */
public: public:
DEFINE_SIZE_STATIC (4); DEFINE_SIZE_STATIC (4);
}; };
@ -134,8 +134,8 @@ struct hmtxvmtx
} }
else else
{ {
/* dest just lsb */ /* dest just sb */
*((FWORD *) dest_pos) = src_metric->lsb; *((FWORD *) dest_pos) = src_metric->sb;
} }
} }
else else
@ -147,18 +147,18 @@ struct hmtxvmtx
failed = true; failed = true;
break; break;
} }
FWORD src_lsb = *(lsbs + gids[i] - _mtx.num_advances); FWORD src_sb = *(lsbs + gids[i] - _mtx.num_advances);
if (i < num_advances) if (i < num_advances)
{ {
/* dest needs a full LongMetric */ /* dest needs a full LongMetric */
LongMetric *metric = (LongMetric *)dest_pos; LongMetric *metric = (LongMetric *)dest_pos;
metric->advance = src_metric->advance; metric->advance = src_metric->advance;
metric->lsb = src_lsb; metric->sb = src_sb;
} }
else else
{ {
/* dest just needs an lsb */ /* dest just needs an sb */
*((FWORD *) dest_pos) = src_lsb; *((FWORD *) dest_pos) = src_sb;
} }
} }
dest_pos += (i < num_advances ? 4 : 2); dest_pos += (i < num_advances ? 4 : 2);
@ -249,17 +249,30 @@ struct hmtxvmtx
hb_blob_destroy (var_blob); hb_blob_destroy (var_blob);
} }
/* TODO Add variations version. */
inline unsigned int get_side_bearing (hb_codepoint_t glyph) const
{
if (glyph < num_advances)
return table->longMetricZ[glyph].sb;
if (unlikely (glyph > num_metrics))
return 0;
const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_advances];
return bearings[glyph - num_advances];
}
inline unsigned int get_advance (hb_codepoint_t glyph) const inline unsigned int get_advance (hb_codepoint_t glyph) const
{ {
if (unlikely (glyph >= num_metrics)) if (unlikely (glyph >= num_metrics))
{ {
/* If num_metrics is zero, it means we don't have the metrics table /* If num_metrics is zero, it means we don't have the metrics table
* for this direction: return default advance. Otherwise, it means that the * for this direction: return default advance. Otherwise, it means that the
* glyph index is out of bound: return zero. */ * glyph index is out of bound: return zero. */
if (num_metrics) if (num_metrics)
return 0; return 0;
else else
return default_advance; return default_advance;
} }
return table->longMetricZ[MIN (glyph, (uint32_t) num_advances - 1)].advance; return table->longMetricZ[MIN (glyph, (uint32_t) num_advances - 1)].advance;
@ -271,7 +284,7 @@ struct hmtxvmtx
unsigned int advance = get_advance (glyph); unsigned int advance = get_advance (glyph);
if (likely(glyph < num_metrics)) if (likely(glyph < num_metrics))
{ {
advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?! advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?!
} }
return advance; return advance;
} }

View File

@ -1,3 +1,3 @@
../fonts/191826b9643e3f124d865d617ae609db6a2ce203.ttf:--direction=t --font-funcs=ft:U+300C:[uni300C.vert=0@-512,-578+0,-1024] ../fonts/191826b9643e3f124d865d617ae609db6a2ce203.ttf:--direction=t --font-funcs=ft:U+300C:[uni300C.vert=0@-512,-578+0,-1024]
../fonts/f9b1dd4dcb515e757789a22cb4241107746fd3d0.ttf:--direction=t --font-funcs=ft:U+0041,U+0042:[gid1=0@-654,-2128+0,-2789|gid2=1@-665,-2125+0,-2789] ../fonts/f9b1dd4dcb515e757789a22cb4241107746fd3d0.ttf:--direction=t --font-funcs=ft:U+0041,U+0042:[gid1=0@-654,-2128+0,-2789|gid2=1@-665,-2125+0,-2789]
../fonts/f9b1dd4dcb515e757789a22cb4241107746fd3d0.ttf:--direction=t --font-funcs=ot:U+0041,U+0042:[gid1=0@-654,-2189+0,-2048|gid2=1@-665,-2189+0,-2048] ../fonts/f9b1dd4dcb515e757789a22cb4241107746fd3d0.ttf:--direction=t --font-funcs=ot:U+0041,U+0042:[gid1=0@-654,-1468+0,-2048|gid2=1@-665,-1462+0,-2048]