Allow disabling of TrueType kerning

Responds to the same feature tag that GPOS kerning does:
'kern' for horizontal and 'vkrn' for vertical.
This commit is contained in:
Behdad Esfahbod 2013-02-15 07:41:07 -05:00
parent 398238a252
commit 038c98f686
2 changed files with 33 additions and 20 deletions

2
TODO
View File

@ -7,8 +7,6 @@ General fixes:
- Disable 'vert' if 'vrt2' is available (eg. Motoya fonts with arrow chars). - Disable 'vert' if 'vrt2' is available (eg. Motoya fonts with arrow chars).
- Fix TT 'kern' on/off and GPOS interaction (move kerning before GPOS).
- Implement 'rand' feature. - Implement 'rand' feature.
- mask propagation? (when ligation, "or" the masks). - mask propagation? (when ligation, "or" the masks).

View File

@ -105,10 +105,14 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
if (HB_DIRECTION_IS_HORIZONTAL (props->direction)) if (HB_DIRECTION_IS_HORIZONTAL (props->direction))
for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++) for (unsigned int i = 0; i < ARRAY_LENGTH (horizontal_features); i++)
map->add_global_bool_feature (horizontal_features[i]); map->add_feature (horizontal_features[i], 1, F_GLOBAL |
(horizontal_features[i] == HB_TAG('k','e','r','n') ?
F_HAS_FALLBACK : F_NONE));
else else
for (unsigned int i = 0; i < ARRAY_LENGTH (vertical_features); i++) for (unsigned int i = 0; i < ARRAY_LENGTH (vertical_features); i++)
map->add_global_bool_feature (vertical_features[i]); map->add_feature (vertical_features[i], 1, F_GLOBAL |
(vertical_features[i] == HB_TAG('v','k','r','n') ?
F_HAS_FALLBACK : F_NONE));
if (planner->shaper->override_features) if (planner->shaper->override_features)
planner->shaper->override_features (planner); planner->shaper->override_features (planner);
@ -491,25 +495,36 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
static inline void static inline void
hb_ot_truetype_kern (hb_ot_shape_context_t *c) hb_ot_truetype_kern (hb_ot_shape_context_t *c)
{ {
/* TODO Check for kern=0 */
unsigned int count = c->buffer->len; unsigned int count = c->buffer->len;
for (unsigned int i = 1; i < count; i++) { hb_mask_t kern_mask = c->plan->map.get_1_mask (HB_DIRECTION_IS_HORIZONTAL (c->buffer->props.direction) ?
hb_position_t x_kern, y_kern, kern1, kern2; HB_TAG ('k','e','r','n') : HB_TAG ('v','k','r','n'));
c->font->get_glyph_kerning_for_direction (c->buffer->info[i - 1].codepoint, c->buffer->info[i].codepoint,
c->buffer->props.direction,
&x_kern, &y_kern);
kern1 = x_kern >> 1; if (unlikely (!count)) return;
kern2 = x_kern - kern1;
c->buffer->pos[i - 1].x_advance += kern1;
c->buffer->pos[i].x_advance += kern2;
c->buffer->pos[i].x_offset += kern2;
kern1 = y_kern >> 1; bool enabled = c->buffer->info[0].mask & kern_mask;
kern2 = y_kern - kern1; for (unsigned int i = 1; i < count; i++)
c->buffer->pos[i - 1].y_advance += kern1; {
c->buffer->pos[i].y_advance += kern2; bool next = c->buffer->info[i].mask & kern_mask;
c->buffer->pos[i].y_offset += kern2; if (enabled && next)
{
hb_position_t x_kern, y_kern, kern1, kern2;
c->font->get_glyph_kerning_for_direction (c->buffer->info[i - 1].codepoint, c->buffer->info[i].codepoint,
c->buffer->props.direction,
&x_kern, &y_kern);
kern1 = x_kern >> 1;
kern2 = x_kern - kern1;
c->buffer->pos[i - 1].x_advance += kern1;
c->buffer->pos[i].x_advance += kern2;
c->buffer->pos[i].x_offset += kern2;
kern1 = y_kern >> 1;
kern2 = y_kern - kern1;
c->buffer->pos[i - 1].y_advance += kern1;
c->buffer->pos[i].y_advance += kern2;
c->buffer->pos[i].y_offset += kern2;
}
enabled = next;
} }
} }