summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh')
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh125
1 files changed, 76 insertions, 49 deletions
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh
index 1db0f1df92..efbb623efc 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout-common.hh
@@ -28,6 +28,7 @@
#define HB_AAT_LAYOUT_COMMON_HH
#include "hb-aat-layout.hh"
+#include "hb-aat-map.hh"
#include "hb-open-type.hh"
namespace OT {
@@ -39,6 +40,43 @@ namespace AAT {
using namespace OT;
+struct ankr;
+
+struct hb_aat_apply_context_t :
+ hb_dispatch_context_t<hb_aat_apply_context_t, bool, HB_DEBUG_APPLY>
+{
+ const char *get_name () { return "APPLY"; }
+ template <typename T>
+ return_t dispatch (const T &obj) { return obj.apply (this); }
+ static return_t default_return_value () { return false; }
+ bool stop_sublookup_iteration (return_t r) const { return r; }
+
+ const hb_ot_shape_plan_t *plan;
+ hb_font_t *font;
+ hb_face_t *face;
+ hb_buffer_t *buffer;
+ hb_sanitize_context_t sanitizer;
+ const ankr *ankr_table;
+ const OT::GDEF *gdef_table;
+ const hb_sorted_vector_t<hb_aat_map_t::range_flags_t> *range_flags = nullptr;
+ hb_mask_t subtable_flags = 0;
+
+ /* Unused. For debug tracing only. */
+ unsigned int lookup_index;
+
+ HB_INTERNAL hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
+ hb_font_t *font_,
+ hb_buffer_t *buffer_,
+ hb_blob_t *blob = const_cast<hb_blob_t *> (&Null (hb_blob_t)));
+
+ HB_INTERNAL ~hb_aat_apply_context_t ();
+
+ HB_INTERNAL void set_ankr_table (const AAT::ankr *ankr_table_);
+
+ void set_lookup_index (unsigned int i) { lookup_index = i; }
+};
+
+
/*
* Lookup Table
*/
@@ -415,18 +453,7 @@ struct Lookup
public:
DEFINE_SIZE_UNION (2, format);
};
-/* Lookup 0 has unbounded size (dependant on num_glyphs). So we need to defined
- * special NULL objects for Lookup<> objects, but since it's template our macros
- * don't work. So we have to hand-code them here. UGLY. */
-} /* Close namespace. */
-/* Ugly hand-coded null objects for template Lookup<> :(. */
-extern HB_INTERNAL const unsigned char _hb_Null_AAT_Lookup[2];
-template <typename T>
-struct Null<AAT::Lookup<T>> {
- static AAT::Lookup<T> const & get_null ()
- { return *reinterpret_cast<const AAT::Lookup<T> *> (_hb_Null_AAT_Lookup); }
-};
-namespace AAT {
+DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (AAT, Lookup, 2);
enum { DELETED_GLYPH = 0xFFFF };
@@ -681,6 +708,13 @@ struct ObsoleteTypes
const void *base,
const T *array)
{
+ /* https://github.com/harfbuzz/harfbuzz/issues/3483 */
+ /* If offset is less than base, return an offset that would
+ * result in an address half a 32bit address-space away,
+ * to make sure sanitize fails even on 32bit builds. */
+ if (unlikely (offset < unsigned ((const char *) array - (const char *) base)))
+ return INT_MAX / T::static_size;
+
/* https://github.com/harfbuzz/harfbuzz/issues/2816 */
return (offset - unsigned ((const char *) array - (const char *) base)) / T::static_size;
}
@@ -744,16 +778,44 @@ struct StateTableDriver
num_glyphs (face_->get_num_glyphs ()) {}
template <typename context_t>
- void drive (context_t *c)
+ void drive (context_t *c, hb_aat_apply_context_t *ac)
{
if (!c->in_place)
buffer->clear_output ();
int state = StateTableT::STATE_START_OF_TEXT;
+ // If there's only one range, we already checked the flag.
+ auto *last_range = ac->range_flags && (ac->range_flags->length > 1) ? &(*ac->range_flags)[0] : nullptr;
for (buffer->idx = 0; buffer->successful;)
{
+ /* This block is copied in NoncontextualSubtable::apply. Keep in sync. */
+ if (last_range)
+ {
+ auto *range = last_range;
+ if (buffer->idx < buffer->len)
+ {
+ unsigned cluster = buffer->cur().cluster;
+ while (cluster < range->cluster_first)
+ range--;
+ while (cluster > range->cluster_last)
+ range++;
+
+
+ last_range = range;
+ }
+ if (!(range->flags & ac->subtable_flags))
+ {
+ if (buffer->idx == buffer->len || unlikely (!buffer->successful))
+ break;
+
+ state = StateTableT::STATE_START_OF_TEXT;
+ (void) buffer->next_glyph ();
+ continue;
+ }
+ }
+
unsigned int klass = buffer->idx < buffer->len ?
- machine.get_class (buffer->info[buffer->idx].codepoint, num_glyphs) :
+ machine.get_class (buffer->cur().codepoint, num_glyphs) :
(unsigned) StateTableT::CLASS_END_OF_TEXT;
DEBUG_MSG (APPLY, nullptr, "c%u at %u", klass, buffer->idx);
const EntryT &entry = machine.get_entry (state, klass);
@@ -849,41 +911,6 @@ struct StateTableDriver
};
-struct ankr;
-
-struct hb_aat_apply_context_t :
- hb_dispatch_context_t<hb_aat_apply_context_t, bool, HB_DEBUG_APPLY>
-{
- const char *get_name () { return "APPLY"; }
- template <typename T>
- return_t dispatch (const T &obj) { return obj.apply (this); }
- static return_t default_return_value () { return false; }
- bool stop_sublookup_iteration (return_t r) const { return r; }
-
- const hb_ot_shape_plan_t *plan;
- hb_font_t *font;
- hb_face_t *face;
- hb_buffer_t *buffer;
- hb_sanitize_context_t sanitizer;
- const ankr *ankr_table;
- const OT::GDEF *gdef_table;
-
- /* Unused. For debug tracing only. */
- unsigned int lookup_index;
-
- HB_INTERNAL hb_aat_apply_context_t (const hb_ot_shape_plan_t *plan_,
- hb_font_t *font_,
- hb_buffer_t *buffer_,
- hb_blob_t *blob = const_cast<hb_blob_t *> (&Null (hb_blob_t)));
-
- HB_INTERNAL ~hb_aat_apply_context_t ();
-
- HB_INTERNAL void set_ankr_table (const AAT::ankr *ankr_table_);
-
- void set_lookup_index (unsigned int i) { lookup_index = i; }
-};
-
-
} /* namespace AAT */