diff --git a/src/Makefile.sources b/src/Makefile.sources index 561fbed6d..2cada4bbc 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -16,6 +16,7 @@ HB_BASE_sources = \ hb-font.hh \ hb-font.cc \ hb-iter.hh \ + hb-kern.hh \ hb-map.hh \ hb-map.cc \ hb-machinery.hh \ diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh index 995e01387..11d7f5c76 100644 --- a/src/hb-aat-layout-kerx-table.hh +++ b/src/hb-aat-layout-kerx-table.hh @@ -28,10 +28,7 @@ #ifndef HB_AAT_LAYOUT_KERX_TABLE_HH #define HB_AAT_LAYOUT_KERX_TABLE_HH -#include "hb-open-type.hh" -#include "hb-aat-layout-common.hh" -#include "hb-ot-layout-gpos-table.hh" -#include "hb-ot-kern-table.hh" +#include "hb-kern.hh" /* * kerx -- Extended Kerning diff --git a/src/hb-kern.hh b/src/hb-kern.hh new file mode 100644 index 000000000..de7269600 --- /dev/null +++ b/src/hb-kern.hh @@ -0,0 +1,153 @@ +/* + * Copyright © 2017 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_KERN_HH +#define HB_KERN_HH + +#include "hb-open-type.hh" +#include "hb-aat-layout-common.hh" +#include "hb-ot-layout-gpos-table.hh" + + +namespace OT { + + +template +struct hb_kern_machine_t +{ + hb_kern_machine_t (const Driver &driver_) : driver (driver_) {} + + HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW + inline void kern (hb_font_t *font, + hb_buffer_t *buffer, + hb_mask_t kern_mask, + bool scale = true) const + { + OT::hb_ot_apply_context_t c (1, font, buffer); + 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); + + + if (likely (!kern)) + goto skip; + + + if (horizontal) + { + if (scale) + kern = font->em_scale_x (kern); + hb_position_t kern1 = kern >> 1; + hb_position_t kern2 = kern - kern1; + pos[i].x_advance += kern1; + pos[j].x_advance += kern2; + pos[j].x_offset += kern2; + } + else + { + if (scale) + kern = font->em_scale_y (kern); + hb_position_t kern1 = kern >> 1; + hb_position_t kern2 = kern - kern1; + pos[i].y_advance += kern1; + pos[j].y_advance += kern2; + pos[j].y_offset += kern2; + } + + buffer->unsafe_to_break (i, j + 1); + + skip: + idx = skippy_iter.idx; + } + } + + const Driver &driver; +}; + + +struct hb_glyph_pair_t +{ + hb_codepoint_t left; + hb_codepoint_t right; +}; + +struct KernPair +{ + inline int get_kerning (void) const + { return value; } + + inline int cmp (const hb_glyph_pair_t &o) const + { + int ret = left.cmp (o.left); + if (ret) return ret; + return right.cmp (o.right); + } + + inline bool sanitize (hb_sanitize_context_t *c) const + { + TRACE_SANITIZE (this); + return_trace (c->check_struct (this)); + } + + protected: + GlyphID left; + GlyphID right; + FWORD value; + public: + DEFINE_SIZE_STATIC (6); +}; + + +} /* namespace OT */ + + +#endif /* HB_KERN_HH */ diff --git a/src/hb-ot-kern-table.hh b/src/hb-ot-kern-table.hh index 33e682714..40d36a336 100644 --- a/src/hb-ot-kern-table.hh +++ b/src/hb-ot-kern-table.hh @@ -27,89 +27,8 @@ #ifndef HB_OT_KERN_TABLE_HH #define HB_OT_KERN_TABLE_HH -#include "hb-open-type.hh" +#include "hb-kern.hh" #include "hb-ot-shape.hh" -#include "hb-ot-layout-gsubgpos.hh" -#include "hb-aat-layout-common.hh" - - -template -struct hb_kern_machine_t -{ - hb_kern_machine_t (const Driver &driver_) : driver (driver_) {} - - HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW - inline void kern (hb_font_t *font, - hb_buffer_t *buffer, - hb_mask_t kern_mask, - bool scale = true) const - { - OT::hb_ot_apply_context_t c (1, font, buffer); - 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); - - - if (likely (!kern)) - goto skip; - - - if (horizontal) - { - if (scale) - kern = font->em_scale_x (kern); - hb_position_t kern1 = kern >> 1; - hb_position_t kern2 = kern - kern1; - pos[i].x_advance += kern1; - pos[j].x_advance += kern2; - pos[j].x_offset += kern2; - } - else - { - if (scale) - kern = font->em_scale_y (kern); - hb_position_t kern1 = kern >> 1; - hb_position_t kern2 = kern - kern1; - pos[i].y_advance += kern1; - pos[j].y_advance += kern2; - pos[j].y_offset += kern2; - } - - buffer->unsafe_to_break (i, j + 1); - - skip: - idx = skippy_iter.idx; - } - } - - const Driver &driver; -}; /* @@ -123,38 +42,6 @@ struct hb_kern_machine_t namespace OT { -struct hb_glyph_pair_t -{ - hb_codepoint_t left; - hb_codepoint_t right; -}; - -struct KernPair -{ - inline int get_kerning (void) const - { return value; } - - inline int cmp (const hb_glyph_pair_t &o) const - { - int ret = left.cmp (o.left); - if (ret) return ret; - return right.cmp (o.right); - } - - inline bool sanitize (hb_sanitize_context_t *c) const - { - TRACE_SANITIZE (this); - return_trace (c->check_struct (this)); - } - - protected: - GlyphID left; - GlyphID right; - FWORD value; - public: - DEFINE_SIZE_STATIC (6); -}; - template struct KernSubTableFormat0 { diff --git a/src/hb-ot-shape-fallback.cc b/src/hb-ot-shape-fallback.cc index 766efe20d..3742d6704 100644 --- a/src/hb-ot-shape-fallback.cc +++ b/src/hb-ot-shape-fallback.cc @@ -465,7 +465,7 @@ _hb_ot_shape_fallback_kern (const hb_ot_shape_plan_t *plan, !font->has_glyph_v_kerning_func ()) return; hb_ot_shape_fallback_kern_driver_t driver (font, buffer); - hb_kern_machine_t machine (driver); + OT::hb_kern_machine_t machine (driver); machine.kern (font, buffer, plan->kern_mask, false); }