Index: third_party/harfbuzz-ng/src/hb-ot-layout-common-private.hh |
diff --git a/third_party/harfbuzz-ng/src/hb-ot-layout-common-private.hh b/third_party/harfbuzz-ng/src/hb-ot-layout-common-private.hh |
index 5d19e08fba9a4d1d53c2471a45f836187751e802..2943a7f672c3ec99a3e8ec2c6cb7e993895eac45 100644 |
--- a/third_party/harfbuzz-ng/src/hb-ot-layout-common-private.hh |
+++ b/third_party/harfbuzz-ng/src/hb-ot-layout-common-private.hh |
@@ -1,6 +1,6 @@ |
/* |
* Copyright © 2007,2008,2009 Red Hat, Inc. |
- * Copyright © 2010 Google, Inc. |
+ * Copyright © 2010,2012 Google, Inc. |
* |
* This is part of HarfBuzz, a text shaping library. |
* |
@@ -30,11 +30,10 @@ |
#define HB_OT_LAYOUT_COMMON_PRIVATE_HH |
#include "hb-ot-layout-private.hh" |
- |
#include "hb-open-type-private.hh" |
+#include "hb-set-private.hh" |
-#define NO_CONTEXT ((unsigned int) 0x110000) |
#define NOT_COVERED ((unsigned int) 0x110000) |
#define MAX_NESTING_LEVEL 8 |
@@ -60,8 +59,7 @@ struct Record |
inline bool sanitize (hb_sanitize_context_t *c, void *base) { |
TRACE_SANITIZE (); |
- return c->check_struct (this) |
- && offset.sanitize (c, base); |
+ return TRACE_RETURN (c->check_struct (this) && offset.sanitize (c, base)); |
} |
Tag tag; /* 4-byte Tag identifier */ |
@@ -115,7 +113,7 @@ struct RecordListOf : RecordArrayOf<Type> |
inline bool sanitize (hb_sanitize_context_t *c) { |
TRACE_SANITIZE (); |
- return RecordArrayOf<Type>::sanitize (c, this); |
+ return TRACE_RETURN (RecordArrayOf<Type>::sanitize (c, this)); |
} |
}; |
@@ -129,7 +127,11 @@ struct RangeRecord |
inline bool sanitize (hb_sanitize_context_t *c) { |
TRACE_SANITIZE (); |
- return c->check_struct (this); |
+ return TRACE_RETURN (c->check_struct (this)); |
+ } |
+ |
+ inline bool intersects (const hb_set_t *glyphs) const { |
+ return glyphs->intersects (start, end); |
} |
GlyphID start; /* First GlyphID in the range */ |
@@ -184,8 +186,7 @@ struct LangSys |
inline bool sanitize (hb_sanitize_context_t *c) { |
TRACE_SANITIZE (); |
- return c->check_struct (this) |
- && featureIndex.sanitize (c); |
+ return TRACE_RETURN (c->check_struct (this) && featureIndex.sanitize (c)); |
} |
Offset lookupOrder; /* = Null (reserved for an offset to a |
@@ -223,8 +224,7 @@ struct Script |
inline bool sanitize (hb_sanitize_context_t *c) { |
TRACE_SANITIZE (); |
- return defaultLangSys.sanitize (c, this) |
- && langSys.sanitize (c, this); |
+ return TRACE_RETURN (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this)); |
} |
private: |
@@ -254,8 +254,7 @@ struct Feature |
inline bool sanitize (hb_sanitize_context_t *c) { |
TRACE_SANITIZE (); |
- return c->check_struct (this) |
- && lookupIndex.sanitize (c); |
+ return TRACE_RETURN (c->check_struct (this) && lookupIndex.sanitize (c)); |
} |
Offset featureParams; /* Offset to Feature Parameters table (if one |
@@ -272,7 +271,7 @@ typedef RecordListOf<Feature> FeatureList; |
struct LookupFlag : USHORT |
{ |
- enum { |
+ enum Flags { |
RightToLeft = 0x0001u, |
IgnoreBaseGlyphs = 0x0002u, |
IgnoreLigatures = 0x0004u, |
@@ -309,14 +308,13 @@ struct Lookup |
inline bool sanitize (hb_sanitize_context_t *c) { |
TRACE_SANITIZE (); |
/* Real sanitize of the subtables is done by GSUB/GPOS/... */ |
- if (!(c->check_struct (this) |
- && subTable.sanitize (c))) return false; |
+ if (!(c->check_struct (this) && subTable.sanitize (c))) return TRACE_RETURN (false); |
if (unlikely (lookupFlag & LookupFlag::UseMarkFilteringSet)) |
{ |
USHORT &markFilteringSet = StructAfter<USHORT> (subTable); |
- if (!markFilteringSet.sanitize (c)) return false; |
+ if (!markFilteringSet.sanitize (c)) return TRACE_RETURN (false); |
} |
- return true; |
+ return TRACE_RETURN (true); |
} |
USHORT lookupType; /* Different enumerations for GSUB and GPOS */ |
@@ -352,9 +350,25 @@ struct CoverageFormat1 |
inline bool sanitize (hb_sanitize_context_t *c) { |
TRACE_SANITIZE (); |
- return glyphArray.sanitize (c); |
+ return TRACE_RETURN (glyphArray.sanitize (c)); |
} |
+ inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { |
+ return glyphs->has (glyphArray[index]); |
+ } |
+ |
+ struct Iter { |
+ inline void init (const struct CoverageFormat1 &c_) { c = &c_; i = 0; }; |
+ inline bool more (void) { return i < c->glyphArray.len; } |
+ inline void next (void) { i++; } |
+ inline uint16_t get_glyph (void) { return c->glyphArray[i]; } |
+ inline uint16_t get_coverage (void) { return i; } |
+ |
+ private: |
+ const struct CoverageFormat1 *c; |
+ unsigned int i; |
+ }; |
+ |
private: |
USHORT coverageFormat; /* Format identifier--format = 1 */ |
SortedArrayOf<GlyphID> |
@@ -380,9 +394,50 @@ struct CoverageFormat2 |
inline bool sanitize (hb_sanitize_context_t *c) { |
TRACE_SANITIZE (); |
- return rangeRecord.sanitize (c); |
+ return TRACE_RETURN (rangeRecord.sanitize (c)); |
+ } |
+ |
+ inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { |
+ unsigned int i; |
+ unsigned int count = rangeRecord.len; |
+ for (i = 0; i < count; i++) { |
+ const RangeRecord &range = rangeRecord[i]; |
+ if (range.value <= index && |
+ index < (unsigned int) range.value + (range.end - range.start) && |
+ range.intersects (glyphs)) |
+ return true; |
+ else if (index < range.value) |
+ return false; |
+ } |
+ return false; |
} |
+ struct Iter { |
+ inline void init (const CoverageFormat2 &c_) { |
+ c = &c_; |
+ coverage = 0; |
+ i = 0; |
+ j = c->rangeRecord.len ? c_.rangeRecord[0].start : 0; |
+ } |
+ inline bool more (void) { return i < c->rangeRecord.len; } |
+ inline void next (void) { |
+ coverage++; |
+ if (j == c->rangeRecord[i].end) { |
+ i++; |
+ if (more ()) |
+ j = c->rangeRecord[i].start; |
+ return; |
+ } |
+ j++; |
+ } |
+ inline uint16_t get_glyph (void) { return j; } |
+ inline uint16_t get_coverage (void) { return coverage; } |
+ |
+ private: |
+ const struct CoverageFormat2 *c; |
+ unsigned int i, j, coverage; |
+ }; |
+ |
private: |
USHORT coverageFormat; /* Format identifier--format = 2 */ |
SortedArrayOf<RangeRecord> |
@@ -408,14 +463,79 @@ struct Coverage |
inline bool sanitize (hb_sanitize_context_t *c) { |
TRACE_SANITIZE (); |
- if (!u.format.sanitize (c)) return false; |
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
+ switch (u.format) { |
+ case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
+ case 2: return TRACE_RETURN (u.format2.sanitize (c)); |
+ default:return TRACE_RETURN (true); |
+ } |
+ } |
+ |
+ inline bool intersects (const hb_set_t *glyphs) const { |
+ /* TODO speed this up */ |
+ Coverage::Iter iter; |
+ for (iter.init (*this); iter.more (); iter.next ()) { |
+ if (glyphs->has (iter.get_glyph ())) |
+ return true; |
+ } |
+ return false; |
+ } |
+ |
+ inline bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const { |
switch (u.format) { |
- case 1: return u.format1.sanitize (c); |
- case 2: return u.format2.sanitize (c); |
- default:return true; |
+ case 1: return u.format1.intersects_coverage (glyphs, index); |
+ case 2: return u.format2.intersects_coverage (glyphs, index); |
+ default:return false; |
} |
} |
+ struct Iter { |
+ Iter (void) : format (0) {}; |
+ inline void init (const Coverage &c_) { |
+ format = c_.u.format; |
+ switch (format) { |
+ case 1: return u.format1.init (c_.u.format1); |
+ case 2: return u.format2.init (c_.u.format2); |
+ default:return; |
+ } |
+ } |
+ inline bool more (void) { |
+ switch (format) { |
+ case 1: return u.format1.more (); |
+ case 2: return u.format2.more (); |
+ default:return true; |
+ } |
+ } |
+ inline void next (void) { |
+ switch (format) { |
+ case 1: u.format1.next (); break; |
+ case 2: u.format2.next (); break; |
+ default: break; |
+ } |
+ } |
+ inline uint16_t get_glyph (void) { |
+ switch (format) { |
+ case 1: return u.format1.get_glyph (); |
+ case 2: return u.format2.get_glyph (); |
+ default:return true; |
+ } |
+ } |
+ inline uint16_t get_coverage (void) { |
+ switch (format) { |
+ case 1: return u.format1.get_coverage (); |
+ case 2: return u.format2.get_coverage (); |
+ default:return true; |
+ } |
+ } |
+ |
+ private: |
+ unsigned int format; |
+ union { |
+ CoverageFormat1::Iter format1; |
+ CoverageFormat2::Iter format2; |
+ } u; |
+ }; |
+ |
private: |
union { |
USHORT format; /* Format identifier */ |
@@ -445,8 +565,15 @@ struct ClassDefFormat1 |
inline bool sanitize (hb_sanitize_context_t *c) { |
TRACE_SANITIZE (); |
- return c->check_struct (this) |
- && classValue.sanitize (c); |
+ return TRACE_RETURN (c->check_struct (this) && classValue.sanitize (c)); |
+ } |
+ |
+ inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { |
+ unsigned int count = classValue.len; |
+ for (unsigned int i = 0; i < count; i++) |
+ if (classValue[i] == klass && glyphs->has (startGlyph + i)) |
+ return true; |
+ return false; |
} |
USHORT classFormat; /* Format identifier--format = 1 */ |
@@ -472,7 +599,15 @@ struct ClassDefFormat2 |
inline bool sanitize (hb_sanitize_context_t *c) { |
TRACE_SANITIZE (); |
- return rangeRecord.sanitize (c); |
+ return TRACE_RETURN (rangeRecord.sanitize (c)); |
+ } |
+ |
+ inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { |
+ unsigned int count = rangeRecord.len; |
+ for (unsigned int i = 0; i < count; i++) |
+ if (rangeRecord[i].value == klass && rangeRecord[i].intersects (glyphs)) |
+ return true; |
+ return false; |
} |
USHORT classFormat; /* Format identifier--format = 2 */ |
@@ -498,11 +633,19 @@ struct ClassDef |
inline bool sanitize (hb_sanitize_context_t *c) { |
TRACE_SANITIZE (); |
- if (!u.format.sanitize (c)) return false; |
+ if (!u.format.sanitize (c)) return TRACE_RETURN (false); |
+ switch (u.format) { |
+ case 1: return TRACE_RETURN (u.format1.sanitize (c)); |
+ case 2: return TRACE_RETURN (u.format2.sanitize (c)); |
+ default:return TRACE_RETURN (true); |
+ } |
+ } |
+ |
+ inline bool intersects_class (const hb_set_t *glyphs, unsigned int klass) const { |
switch (u.format) { |
- case 1: return u.format1.sanitize (c); |
- case 2: return u.format2.sanitize (c); |
- default:return true; |
+ case 1: return u.format1.intersects_class (glyphs, klass); |
+ case 2: return u.format2.intersects_class (glyphs, klass); |
+ default:return false; |
} |
} |
@@ -574,8 +717,7 @@ struct Device |
inline bool sanitize (hb_sanitize_context_t *c) { |
TRACE_SANITIZE (); |
- return c->check_struct (this) |
- && c->check_range (this, this->get_size ()); |
+ return TRACE_RETURN (c->check_struct (this) && c->check_range (this, this->get_size ())); |
} |
private: |