[kern] Abstract away kerning machine
This commit is contained in:
parent
fb4f438381
commit
683c3a9533
|
@ -502,8 +502,8 @@ struct hb_font_t
|
|||
hb_position_t *x, hb_position_t *y)
|
||||
{
|
||||
if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) {
|
||||
*x = get_glyph_h_kerning (first_glyph, second_glyph);
|
||||
*y = 0;
|
||||
*x = get_glyph_h_kerning (first_glyph, second_glyph);
|
||||
} else {
|
||||
*x = 0;
|
||||
*y = get_glyph_v_kerning (first_glyph, second_glyph);
|
||||
|
|
|
@ -28,6 +28,77 @@
|
|||
#define HB_OT_KERN_TABLE_HH
|
||||
|
||||
#include "hb-open-type.hh"
|
||||
#include "hb-ot-shape.hh"
|
||||
#include "hb-ot-layout-gsubgpos.hh"
|
||||
|
||||
|
||||
template <typename Driver>
|
||||
struct hb_kern_machine_t
|
||||
{
|
||||
hb_kern_machine_t (Driver &driver_) : driver (driver_) {}
|
||||
|
||||
inline void kern (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer) const
|
||||
{
|
||||
if (!plan->kerning_requested) return;
|
||||
|
||||
OT::hb_ot_apply_context_t c (1, font, buffer);
|
||||
hb_mask_t kern_mask = plan->kern_mask;
|
||||
c.set_lookup_mask (kern_mask);
|
||||
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
|
||||
OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input;
|
||||
skippy_iter.init (&c);
|
||||
|
||||
bool horizontal = HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction);
|
||||
unsigned int count = buffer->len;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
hb_glyph_position_t *pos = buffer->pos;
|
||||
for (unsigned int idx = 0; idx < count;)
|
||||
{
|
||||
if (!(info[idx].mask & kern_mask))
|
||||
{
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
|
||||
skippy_iter.reset (idx, 1);
|
||||
if (!skippy_iter.next ())
|
||||
{
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned int i = idx;
|
||||
unsigned int j = skippy_iter.idx;
|
||||
hb_position_t kern = driver.get_kerning (info[i].codepoint,
|
||||
info[j].codepoint);
|
||||
|
||||
hb_position_t kern1 = kern >> 1;
|
||||
hb_position_t kern2 = kern - kern1;
|
||||
|
||||
if (horizontal)
|
||||
{
|
||||
pos[i].x_advance += kern1;
|
||||
pos[j].x_advance += kern2;
|
||||
pos[j].x_offset += kern2;
|
||||
}
|
||||
else
|
||||
{
|
||||
pos[i].y_advance += kern1;
|
||||
pos[j].y_advance += kern2;
|
||||
pos[j].y_offset += kern2;
|
||||
}
|
||||
|
||||
buffer->unsafe_to_break (i, j + 1);
|
||||
|
||||
idx = skippy_iter.idx;
|
||||
}
|
||||
}
|
||||
|
||||
Driver &driver;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* kern -- Kerning
|
||||
|
|
|
@ -25,7 +25,7 @@
|
|||
*/
|
||||
|
||||
#include "hb-ot-shape-fallback.hh"
|
||||
#include "hb-ot-layout-gsubgpos.hh"
|
||||
#include "hb-ot-kern-table.hh"
|
||||
|
||||
static unsigned int
|
||||
recategorize_combining_class (hb_codepoint_t u,
|
||||
|
@ -435,67 +435,34 @@ _hb_ot_shape_fallback_position (const hb_ot_shape_plan_t *plan,
|
|||
}
|
||||
|
||||
|
||||
/* Performs old-style TrueType kerning. */
|
||||
/* Performs font-assisted kerning. */
|
||||
void
|
||||
_hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan,
|
||||
hb_font_t *font,
|
||||
hb_buffer_t *buffer)
|
||||
{
|
||||
if (!plan->kerning_requested) return;
|
||||
|
||||
OT::hb_ot_apply_context_t c (1, font, buffer);
|
||||
hb_mask_t kern_mask = plan->kern_mask;
|
||||
c.set_lookup_mask (kern_mask);
|
||||
c.set_lookup_props (OT::LookupFlag::IgnoreMarks);
|
||||
OT::hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c.iter_input;
|
||||
skippy_iter.init (&c);
|
||||
|
||||
unsigned int count = buffer->len;
|
||||
hb_glyph_info_t *info = buffer->info;
|
||||
hb_glyph_position_t *pos = buffer->pos;
|
||||
for (unsigned int idx = 0; idx < count;)
|
||||
struct driver_t
|
||||
{
|
||||
if (!(info[idx].mask & kern_mask))
|
||||
driver_t (hb_font_t *font_,
|
||||
hb_buffer_t *buffer) :
|
||||
font (font_), direction (buffer->props.direction) {}
|
||||
|
||||
hb_position_t get_kerning (hb_codepoint_t first, hb_codepoint_t second)
|
||||
{
|
||||
idx++;
|
||||
continue;
|
||||
hb_position_t kern = 0;
|
||||
font->get_glyph_kerning_for_direction (first, second,
|
||||
direction,
|
||||
&kern, &kern);
|
||||
return kern;
|
||||
}
|
||||
|
||||
skippy_iter.reset (idx, 1);
|
||||
if (!skippy_iter.next ())
|
||||
{
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
hb_font_t *font;
|
||||
hb_direction_t direction;
|
||||
} driver (font, buffer);
|
||||
|
||||
hb_position_t x_kern, y_kern;
|
||||
font->get_glyph_kerning_for_direction (info[idx].codepoint,
|
||||
info[skippy_iter.idx].codepoint,
|
||||
buffer->props.direction,
|
||||
&x_kern, &y_kern);
|
||||
hb_kern_machine_t<driver_t> machine (driver);
|
||||
|
||||
if (x_kern)
|
||||
{
|
||||
hb_position_t kern1 = x_kern >> 1;
|
||||
hb_position_t kern2 = x_kern - kern1;
|
||||
pos[idx].x_advance += kern1;
|
||||
pos[skippy_iter.idx].x_advance += kern2;
|
||||
pos[skippy_iter.idx].x_offset += kern2;
|
||||
buffer->unsafe_to_break (idx, skippy_iter.idx + 1);
|
||||
}
|
||||
|
||||
if (y_kern)
|
||||
{
|
||||
hb_position_t kern1 = y_kern >> 1;
|
||||
hb_position_t kern2 = y_kern - kern1;
|
||||
pos[idx].y_advance += kern1;
|
||||
pos[skippy_iter.idx].y_advance += kern2;
|
||||
pos[skippy_iter.idx].y_offset += kern2;
|
||||
buffer->unsafe_to_break (idx, skippy_iter.idx + 1);
|
||||
}
|
||||
|
||||
idx = skippy_iter.idx;
|
||||
}
|
||||
machine.kern (plan, font, buffer);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue