[HarfBuzz] harfbuzz: Branch 'master' - 7 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Thu Oct 11 05:23:32 UTC 2018
src/hb-aat-layout-ankr-table.hh | 25 +++++-
src/hb-aat-layout-common.hh | 11 ++
src/hb-aat-layout-kerx-table.hh | 154 ++++++++++++++++++++++++++++++++++++++--
src/hb-aat-layout.cc | 20 ++++-
src/hb-ot-layout-gpos-table.hh | 4 -
5 files changed, 198 insertions(+), 16 deletions(-)
New commits:
commit fbbd926dba163d9a2a6a62f380951f03363c2b14
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 11 01:22:29 2018 -0400
[kerx] Implement Format4 action_type=1 contour-point-based attachment
Untested.
This concludes kerx table support!
diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index a54e2978..cd112912 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -354,7 +354,22 @@ struct KerxSubTableFormat4
return false;
HB_UNUSED unsigned int markControlPoint = *data++;
HB_UNUSED unsigned int currControlPoint = *data++;
- /* TODO */
+ hb_position_t markX = 0;
+ hb_position_t markY = 0;
+ hb_position_t currX = 0;
+ hb_position_t currY = 0;
+ if (!c->font->get_glyph_contour_point_for_origin (c->buffer->info[mark].codepoint,
+ markControlPoint,
+ HB_DIRECTION_LTR /*XXX*/,
+ &markX, &markY) ||
+ !c->font->get_glyph_contour_point_for_origin (c->buffer->cur ().codepoint,
+ currControlPoint,
+ HB_DIRECTION_LTR /*XXX*/,
+ &currX, &currY))
+ return true; /* True, such that the machine continues. */
+
+ o.x_offset = markX - currX;
+ o.y_offset = markY - currY;
}
break;
commit b6bc0d4ff62e4509643db3b304306a72bbcb2c38
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 11 01:17:57 2018 -0400
[kerx] Implement Format4 action_type=2 coordinate-based attachment
Untested.
diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index 019efd57..a54e2978 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -343,6 +343,7 @@ struct KerxSubTableFormat4
if (mark_set && entry->data.ankrActionIndex != 0xFFFF)
{
+ hb_glyph_position_t &o = buffer->cur_pos();
switch (action_type)
{
case 0: /* Control Point Actions.*/
@@ -373,12 +374,9 @@ struct KerxSubTableFormat4
currAnchorPoint,
c->face->get_num_glyphs (),
c->ankr_end);
- hb_glyph_position_t &o = buffer->cur_pos();
+
o.x_offset = c->font->em_scale_x (markAnchor.xCoordinate) - c->font->em_scale_x (currAnchor.xCoordinate);
o.y_offset = c->font->em_scale_y (markAnchor.yCoordinate) - c->font->em_scale_y (currAnchor.yCoordinate);
- o.attach_type() = ATTACH_TYPE_MARK;
- o.attach_chain() = (int) mark - (int) buffer->idx;
- buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
}
break;
@@ -387,14 +385,19 @@ struct KerxSubTableFormat4
const FWORD *data = (const FWORD *) &ankrData[entry->data.ankrActionIndex];
if (!c->sanitizer.check_array (data, 4))
return false;
- HB_UNUSED int markX = *data++;
- HB_UNUSED int markY = *data++;
- HB_UNUSED int currX = *data++;
- HB_UNUSED int currY = *data++;
- /* TODO */
+ int markX = *data++;
+ int markY = *data++;
+ int currX = *data++;
+ int currY = *data++;
+
+ o.x_offset = c->font->em_scale_x (markX) - c->font->em_scale_x (currX);
+ o.y_offset = c->font->em_scale_y (markY) - c->font->em_scale_y (currY);
}
break;
}
+ o.attach_type() = ATTACH_TYPE_MARK;
+ o.attach_chain() = (int) mark - (int) buffer->idx;
+ buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
}
if (flags & Mark)
commit 1622ba5943d14b2d50d45dc17fb723f4c9ddb0bb
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 11 01:14:18 2018 -0400
[kerx] Implement Format4 'ankr'-based mark attachment
Tested with Kannada MN:
$ HB_OPTIONS=aat ./hb-shape Kannada\ MN.ttc -u 0CCD,0C95,0CD6
[kn_ka.vattu=0+230|kn_ai_length_mark=1 at 326,0+607]
diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh
index dada9c7a..78de04fa 100644
--- a/src/hb-aat-layout-common.hh
+++ b/src/hb-aat-layout-common.hh
@@ -531,6 +531,7 @@ struct hb_aat_apply_context_t :
hb_buffer_t *buffer;
hb_sanitize_context_t sanitizer;
const ankr &ankr_table;
+ const char *ankr_end;
/* Unused. For debug tracing only. */
unsigned int lookup_index;
@@ -540,9 +541,12 @@ struct hb_aat_apply_context_t :
hb_font_t *font_,
hb_buffer_t *buffer_,
hb_blob_t *table,
- const ankr &ankr_table_ = Null(ankr)) :
+ const ankr &ankr_table_ = Null(ankr),
+ const char *ankr_end_ = nullptr) :
plan (plan_), font (font_), face (font->face), buffer (buffer_),
- sanitizer (), ankr_table (ankr_table_), lookup_index (0), debug_depth (0)
+ sanitizer (),
+ ankr_table (ankr_table_), ankr_end (ankr_end_),
+ lookup_index (0), debug_depth (0)
{
sanitizer.init (table);
sanitizer.set_num_glyphs (face->get_num_glyphs ());
diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index c109d003..019efd57 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -30,6 +30,7 @@
#include "hb-open-type.hh"
#include "hb-aat-layout-common.hh"
+#include "hb-ot-layout-gpos-table.hh"
#include "hb-ot-kern-table.hh"
/*
@@ -362,9 +363,22 @@ struct KerxSubTableFormat4
const HBUINT16 *data = &ankrData[entry->data.ankrActionIndex];
if (!c->sanitizer.check_array (data, 2))
return false;
- HB_UNUSED unsigned int markAnchorPoint = *data++;
- HB_UNUSED unsigned int currAnchorPoint = *data++;
- /* TODO */
+ unsigned int markAnchorPoint = *data++;
+ unsigned int currAnchorPoint = *data++;
+ const Anchor markAnchor = c->ankr_table.get_anchor (c->buffer->info[mark].codepoint,
+ markAnchorPoint,
+ c->face->get_num_glyphs (),
+ c->ankr_end);
+ const Anchor currAnchor = c->ankr_table.get_anchor (c->buffer->cur ().codepoint,
+ currAnchorPoint,
+ c->face->get_num_glyphs (),
+ c->ankr_end);
+ hb_glyph_position_t &o = buffer->cur_pos();
+ o.x_offset = c->font->em_scale_x (markAnchor.xCoordinate) - c->font->em_scale_x (currAnchor.xCoordinate);
+ o.y_offset = c->font->em_scale_y (markAnchor.yCoordinate) - c->font->em_scale_y (currAnchor.yCoordinate);
+ o.attach_type() = ATTACH_TYPE_MARK;
+ o.attach_chain() = (int) mark - (int) buffer->idx;
+ buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
}
break;
diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc
index 47462ad7..73ab06d3 100644
--- a/src/hb-aat-layout.cc
+++ b/src/hb-aat-layout.cc
@@ -69,10 +69,18 @@ _get_kerx (hb_face_t *face, hb_blob_t **blob = nullptr)
return kerx;
}
static inline const AAT::ankr&
-_get_ankr (hb_face_t *face)
+_get_ankr (hb_face_t *face, hb_blob_t **blob = nullptr)
{
- if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(AAT::ankr);
- return *(hb_ot_face_data (face)->ankr.get ());
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face)))
+ {
+ if (blob)
+ *blob = hb_blob_get_empty ();
+ return Null(AAT::ankr);
+ }
+ const AAT::ankr& ankr = *(hb_ot_face_data (face)->ankr.get ());
+ if (blob)
+ *blob = hb_ot_face_data (face)->ankr.get_blob ();
+ return ankr;
}
@@ -109,6 +117,10 @@ hb_aat_layout_position (hb_ot_shape_plan_t *plan,
hb_blob_t *blob;
const AAT::kerx& kerx = _get_kerx (font->face, &blob);
- AAT::hb_aat_apply_context_t c (plan, font, buffer, blob, _get_ankr (font->face));
+ hb_blob_t *ankr_blob;
+ const AAT::ankr& ankr = _get_ankr (font->face, &ankr_blob);
+
+ AAT::hb_aat_apply_context_t c (plan, font, buffer, blob,
+ ankr, ankr_blob->data + ankr_blob->length);
kerx.apply (&c);
}
diff --git a/src/hb-ot-layout-gpos-table.hh b/src/hb-ot-layout-gpos-table.hh
index 1a96609d..746c2462 100644
--- a/src/hb-ot-layout-gpos-table.hh
+++ b/src/hb-ot-layout-gpos-table.hh
@@ -1755,10 +1755,6 @@ template <typename context_t>
struct GPOS_accelerator_t : GPOS::accelerator_t {};
-#undef attach_chain
-#undef attach_type
-
-
} /* namespace OT */
commit 7bb4da7d9538f3d4b1d28030d43e0c3d720d821b
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 11 00:52:07 2018 -0400
[aat] Wire up 'ankr' table to apply context
diff --git a/src/hb-aat-layout-common.hh b/src/hb-aat-layout-common.hh
index 37ab5353..dada9c7a 100644
--- a/src/hb-aat-layout-common.hh
+++ b/src/hb-aat-layout-common.hh
@@ -514,6 +514,7 @@ struct StateTableDriver
};
+struct ankr;
struct hb_aat_apply_context_t :
hb_dispatch_context_t<hb_aat_apply_context_t, bool, HB_DEBUG_APPLY>
@@ -529,6 +530,7 @@ struct hb_aat_apply_context_t :
hb_face_t *face;
hb_buffer_t *buffer;
hb_sanitize_context_t sanitizer;
+ const ankr &ankr_table;
/* Unused. For debug tracing only. */
unsigned int lookup_index;
@@ -537,9 +539,10 @@ struct hb_aat_apply_context_t :
inline hb_aat_apply_context_t (hb_ot_shape_plan_t *plan_,
hb_font_t *font_,
hb_buffer_t *buffer_,
- hb_blob_t *table) :
+ hb_blob_t *table,
+ const ankr &ankr_table_ = Null(ankr)) :
plan (plan_), font (font_), face (font->face), buffer (buffer_),
- sanitizer (), lookup_index (0), debug_depth (0)
+ sanitizer (), ankr_table (ankr_table_), lookup_index (0), debug_depth (0)
{
sanitizer.init (table);
sanitizer.set_num_glyphs (face->get_num_glyphs ());
diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc
index 3fd4f9f8..47462ad7 100644
--- a/src/hb-aat-layout.cc
+++ b/src/hb-aat-layout.cc
@@ -68,6 +68,12 @@ _get_kerx (hb_face_t *face, hb_blob_t **blob = nullptr)
*blob = hb_ot_face_data (face)->kerx.get_blob ();
return kerx;
}
+static inline const AAT::ankr&
+_get_ankr (hb_face_t *face)
+{
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return Null(AAT::ankr);
+ return *(hb_ot_face_data (face)->ankr.get ());
+}
hb_bool_t
@@ -103,6 +109,6 @@ hb_aat_layout_position (hb_ot_shape_plan_t *plan,
hb_blob_t *blob;
const AAT::kerx& kerx = _get_kerx (font->face, &blob);
- AAT::hb_aat_apply_context_t c (plan, font, buffer, blob);
+ AAT::hb_aat_apply_context_t c (plan, font, buffer, blob, _get_ankr (font->face));
kerx.apply (&c);
}
commit 28f0367aab648c486d6e8d0e13dbbb2af1b65dcc
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Thu Oct 11 00:12:49 2018 -0400
[kerx] Flesh out Format4
Doesn't apply actions yet.
diff --git a/src/hb-aat-layout-kerx-table.hh b/src/hb-aat-layout-kerx-table.hh
index a96bad17..c109d003 100644
--- a/src/hb-aat-layout-kerx-table.hh
+++ b/src/hb-aat-layout-kerx-table.hh
@@ -293,11 +293,121 @@ struct KerxSubTableFormat2
struct KerxSubTableFormat4
{
+ struct EntryData
+ {
+ HBUINT16 ankrActionIndex;/* Either 0xFFFF (for no action) or the index of
+ * the action to perform. */
+ public:
+ DEFINE_SIZE_STATIC (2);
+ };
+
+ struct driver_context_t
+ {
+ static const bool in_place = true;
+ enum Flags
+ {
+ Mark = 0x8000, /* If set, remember this glyph as the marked glyph. */
+ DontAdvance = 0x4000, /* If set, don't advance to the next glyph before
+ * going to the new state. */
+ Reserved = 0x3FFF, /* Not used; set to 0. */
+ };
+
+ enum SubTableFlags
+ {
+ ActionType = 0xC0000000, /* A two-bit field containing the action type. */
+ Unused = 0x3F000000, /* Unused - must be zero. */
+ Offset = 0x00FFFFFF, /* Masks the offset in bytes from the beginning
+ * of the subtable to the beginning of the control
+ * point table. */
+ };
+
+ inline driver_context_t (const KerxSubTableFormat4 *table,
+ hb_aat_apply_context_t *c_) :
+ c (c_),
+ action_type ((table->flags & ActionType) >> 30),
+ ankrData ((HBUINT16 *) ((const char *) &table->machine + (table->flags & Offset))),
+ mark_set (false),
+ mark (0) {}
+
+ inline bool is_actionable (StateTableDriver<EntryData> *driver,
+ const Entry<EntryData> *entry)
+ {
+ return entry->data.ankrActionIndex != 0xFFFF;
+ }
+ inline bool transition (StateTableDriver<EntryData> *driver,
+ const Entry<EntryData> *entry)
+ {
+ hb_buffer_t *buffer = driver->buffer;
+ unsigned int flags = entry->flags;
+
+ if (mark_set && entry->data.ankrActionIndex != 0xFFFF)
+ {
+ switch (action_type)
+ {
+ case 0: /* Control Point Actions.*/
+ {
+ /* indexed into glyph outline. */
+ const HBUINT16 *data = &ankrData[entry->data.ankrActionIndex];
+ if (!c->sanitizer.check_array (data, 2))
+ return false;
+ HB_UNUSED unsigned int markControlPoint = *data++;
+ HB_UNUSED unsigned int currControlPoint = *data++;
+ /* TODO */
+ }
+ break;
+
+ case 1: /* Anchor Point Actions. */
+ {
+ /* Indexed into 'ankr' table. */
+ const HBUINT16 *data = &ankrData[entry->data.ankrActionIndex];
+ if (!c->sanitizer.check_array (data, 2))
+ return false;
+ HB_UNUSED unsigned int markAnchorPoint = *data++;
+ HB_UNUSED unsigned int currAnchorPoint = *data++;
+ /* TODO */
+ }
+ break;
+
+ case 2: /* Control Point Coordinate Actions. */
+ {
+ const FWORD *data = (const FWORD *) &ankrData[entry->data.ankrActionIndex];
+ if (!c->sanitizer.check_array (data, 4))
+ return false;
+ HB_UNUSED int markX = *data++;
+ HB_UNUSED int markY = *data++;
+ HB_UNUSED int currX = *data++;
+ HB_UNUSED int currY = *data++;
+ /* TODO */
+ }
+ break;
+ }
+ }
+
+ if (flags & Mark)
+ {
+ mark_set = true;
+ mark = buffer->idx;
+ }
+
+ return true;
+ }
+
+ private:
+ hb_aat_apply_context_t *c;
+ unsigned int action_type;
+ const HBUINT16 *ankrData;
+ bool mark_set;
+ unsigned int mark;
+ };
+
inline bool apply (hb_aat_apply_context_t *c) const
{
TRACE_APPLY (this);
- /* TODO */
+ driver_context_t dc (this, c);
+
+ StateTableDriver<EntryData> driver (machine, c->buffer, c->font->face);
+ driver.drive (&dc);
return_trace (true);
}
@@ -306,14 +416,18 @@ struct KerxSubTableFormat4
{
TRACE_SANITIZE (this);
- /* TODO */
- return_trace (likely (c->check_struct (this)));
+ /* The rest of array sanitizations are done at run-time. */
+ return_trace (c->check_struct (this) &&
+ machine.sanitize (c) &&
+ flags.sanitize (c));
}
protected:
KerxSubTableHeader header;
+ StateTable<EntryData> machine;
+ HBUINT32 flags;
public:
- DEFINE_SIZE_STATIC (12);
+ DEFINE_SIZE_STATIC (32);
};
struct KerxSubTableFormat6
commit 947962a287d9aca2cb509c11f44cb5150aa6daf1
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Oct 10 23:07:03 2018 -0400
[ankr] Implement table access
diff --git a/src/hb-aat-layout-ankr-table.hh b/src/hb-aat-layout-ankr-table.hh
index cc92ee29..3eac473a 100644
--- a/src/hb-aat-layout-ankr-table.hh
+++ b/src/hb-aat-layout-ankr-table.hh
@@ -45,16 +45,32 @@ struct Anchor
return_trace (c->check_struct (this));
}
+ public:
FWORD xCoordinate;
FWORD yCoordinate;
public:
DEFINE_SIZE_STATIC (4);
};
+typedef LArrayOf<Anchor> GlyphAnchors;
+
struct ankr
{
static const hb_tag_t tableTag = HB_AAT_TAG_ankr;
+ inline const Anchor &get_anchor (hb_codepoint_t glyph_id,
+ unsigned int i,
+ unsigned int num_glyphs,
+ const char *end) const
+ {
+ unsigned int offset = (this+lookupTable).get_value_or_null (glyph_id, num_glyphs);
+ const GlyphAnchors &anchors = StructAtOffset<GlyphAnchors> (&(this+anchorData), offset);
+ /* TODO Use sanitizer; to avoid overflows and more. */
+ if (unlikely ((const char *) &anchors + anchors.get_size () > end))
+ return Null(Anchor);
+ return anchors[i];
+ }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
commit 7281cb3eeb00091c6e6085895afd4a38a0516f35
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Oct 10 22:56:52 2018 -0400
[ankr] Start fixing
diff --git a/src/hb-aat-layout-ankr-table.hh b/src/hb-aat-layout-ankr-table.hh
index a197cec8..cc92ee29 100644
--- a/src/hb-aat-layout-ankr-table.hh
+++ b/src/hb-aat-layout-ankr-table.hh
@@ -60,17 +60,16 @@ struct ankr
TRACE_SANITIZE (this);
return_trace (likely (c->check_struct (this) &&
version == 0 &&
- lookupTable.sanitize (c, this) &&
- anchors.sanitize (c, this)));
+ lookupTable.sanitize (c, this)));
}
protected:
HBUINT16 version; /* Version number (set to zero) */
HBUINT16 flags; /* Flags (currently unused; set to zero) */
- LOffsetTo<Lookup<HBUINT16> >
+ LOffsetTo<Lookup<Offset<HBUINT16, false> > >
lookupTable; /* Offset to the table's lookup table */
- LOffsetTo<LArrayOf<Anchor> >
- anchors; /* Offset to the glyph data table */
+ LOffsetTo<HBUINT8>
+ anchorData; /* Offset to the glyph data table */
public:
DEFINE_SIZE_STATIC (12);
More information about the HarfBuzz
mailing list