Merge branch 'master' into cff-subset

This commit is contained in:
Michiharu Ariza 2018-09-17 13:07:29 -07:00
commit d050ab8d3e
18 changed files with 306 additions and 105 deletions

View File

@ -761,11 +761,16 @@ endif ()
if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
install(TARGETS harfbuzz
EXPORT harfbuzzConfig
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
FRAMEWORK DESTINATION Library/Frameworks
)
install(EXPORT harfbuzzConfig
NAMESPACE harfbuzz::
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/harfbuzz
)
if (HB_BUILD_UTILS)
install(TARGETS hb-view
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}

View File

@ -243,7 +243,7 @@ struct LookupSegmentArray
GlyphID last; /* Last GlyphID in this segment */
GlyphID first; /* First GlyphID in this segment */
OffsetTo<UnsizedArrayOf<T> >
OffsetTo<UnsizedArrayOf<T>, HBUINT16, false>
valuesZ; /* A 16-bit offset from the start of
* the table to the data. */
public:
@ -439,10 +439,23 @@ struct Entry<void>
template <typename Extra>
struct StateTable
{
enum State
{
STATE_START_OF_TEXT = 0,
STATE_START_OF_LINE = 1,
};
enum Class
{
CLASS_END_OF_TEXT = 0,
CLASS_OUT_OF_BOUNDS = 1,
CLASS_DELETED_GLYPH = 2,
CLASS_END_OF_LINE = 3,
};
inline unsigned int get_class (hb_codepoint_t glyph_id, unsigned int num_glyphs) const
{
const HBUINT16 *v = (this+classTable).get_value (glyph_id, num_glyphs);
return v ? *v : 1;
return v ? (unsigned) *v : (unsigned) CLASS_OUT_OF_BOUNDS;
}
inline const Entry<Extra> *get_entries () const
@ -509,11 +522,11 @@ struct StateTable
protected:
HBUINT32 nClasses; /* Number of classes, which is the number of indices
* in a single line in the state array. */
LOffsetTo<Lookup<HBUINT16> >
LOffsetTo<Lookup<HBUINT16>, false>
classTable; /* Offset to the class table. */
LOffsetTo<UnsizedArrayOf<HBUINT16> >
LOffsetTo<UnsizedArrayOf<HBUINT16>, false>
stateArrayTable;/* Offset to the state array. */
LOffsetTo<UnsizedArrayOf<Entry<Extra> > >
LOffsetTo<UnsizedArrayOf<Entry<Extra> >, false>
entryTable; /* Offset to the entry array. */
public:
@ -538,13 +551,13 @@ struct StateTableDriver
if (!c->in_place)
buffer->clear_output ();
unsigned int state = 0;
unsigned int state = StateTable<EntryData>::STATE_START_OF_TEXT;
bool last_was_dont_advance = false;
for (buffer->idx = 0;;)
{
unsigned int klass = buffer->idx < buffer->len ?
machine.get_class (info[buffer->idx].codepoint, num_glyphs) :
0 /* End of text */;
(unsigned) StateTable<EntryData>::CLASS_END_OF_TEXT;
const Entry<EntryData> *entry = machine.get_entryZ (state, klass);
if (unlikely (!entry))
break;

View File

@ -78,7 +78,7 @@ struct FeatureName
protected:
HBUINT16 feature; /* Feature type. */
HBUINT16 nSettings; /* The number of records in the setting name array. */
LOffsetTo<UnsizedArrayOf<SettingName> >
LOffsetTo<UnsizedArrayOf<SettingName>, false>
settingTable; /* Offset in bytes from the beginning of this table to
* this feature's setting name array. The actual type of
* record this offset refers to will depend on the

View File

@ -50,7 +50,8 @@ struct RearrangementSubtable
struct driver_context_t
{
static const bool in_place = true;
enum Flags {
enum Flags
{
MarkFirst = 0x8000, /* If set, make the current glyph the first
* glyph to be rearranged. */
DontAdvance = 0x4000, /* If set, don't advance to the next glyph
@ -196,7 +197,8 @@ struct ContextualSubtable
struct driver_context_t
{
static const bool in_place = true;
enum Flags {
enum Flags
{
SetMark = 0x8000, /* If set, make the current glyph the marked glyph. */
DontAdvance = 0x4000, /* If set, don't advance to the next glyph before
* going to the new state. */
@ -309,7 +311,7 @@ struct ContextualSubtable
protected:
StateTable<EntryData>
machine;
LOffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32> >
LOffsetTo<UnsizedOffsetListOf<Lookup<GlyphID>, HBUINT32>, false>
substitutionTables;
public:
DEFINE_SIZE_STATIC (20);
@ -329,7 +331,8 @@ struct LigatureSubtable
struct driver_context_t
{
static const bool in_place = false;
enum Flags {
enum Flags
{
SetComponent = 0x8000, /* Push this glyph onto the component stack for
* eventual processing. */
DontAdvance = 0x4000, /* Leave the glyph pointer at this glyph for the
@ -338,7 +341,8 @@ struct LigatureSubtable
* group. */
Reserved = 0x1FFF, /* These bits are reserved and should be set to 0. */
};
enum LigActionFlags {
enum LigActionFlags
{
LigActionLast = 0x80000000, /* This is the last action in the list. This also
* implies storage. */
LigActionStore = 0x40000000, /* Store the ligature at the current cumulated index
@ -469,11 +473,11 @@ struct LigatureSubtable
protected:
StateTable<EntryData>
machine;
LOffsetTo<UnsizedArrayOf<HBUINT32> >
LOffsetTo<UnsizedArrayOf<HBUINT32>, false>
ligAction; /* Offset to the ligature action table. */
LOffsetTo<UnsizedArrayOf<HBUINT16> >
LOffsetTo<UnsizedArrayOf<HBUINT16>, false>
component; /* Offset to the component table. */
LOffsetTo<UnsizedArrayOf<GlyphID> >
LOffsetTo<UnsizedArrayOf<GlyphID>, false>
ligature; /* Offset to the actual ligature lists. */
public:
DEFINE_SIZE_STATIC (28);
@ -517,19 +521,186 @@ struct NoncontextualSubtable
struct InsertionSubtable
{
struct EntryData
{
HBUINT16 currentInsertIndex; /* Zero-based index into the insertion glyph table.
* The number of glyphs to be inserted is contained
* in the currentInsertCount field in the flags.
* A value of 0xFFFF indicates no insertion is to
* be done. */
HBUINT16 markedInsertIndex; /* Zero-based index into the insertion glyph table.
* The number of glyphs to be inserted is contained
* in the markedInsertCount field in the flags.
* A value of 0xFFFF indicates no insertion is to
* be done. */
public:
DEFINE_SIZE_STATIC (4);
};
struct driver_context_t
{
static const bool in_place = false;
enum Flags
{
SetMark = 0x8000, /* If set, mark the current glyph. */
DontAdvance = 0x4000, /* If set, don't advance to the next glyph before
* going to the new state. This does not mean
* that the glyph pointed to is the same one as
* before. If you've made insertions immediately
* downstream of the current glyph, the next glyph
* processed would in fact be the first one
* inserted. */
CurrentIsKashidaLike= 0x2000, /* If set, and the currentInsertList is nonzero,
* then the specified glyph list will be inserted
* as a kashida-like insertion, either before or
* after the current glyph (depending on the state
* of the currentInsertBefore flag). If clear, and
* the currentInsertList is nonzero, then the
* specified glyph list will be inserted as a
* split-vowel-like insertion, either before or
* after the current glyph (depending on the state
* of the currentInsertBefore flag). */
MarkedIsKashidaLike= 0x1000, /* If set, and the markedInsertList is nonzero,
* then the specified glyph list will be inserted
* as a kashida-like insertion, either before or
* after the marked glyph (depending on the state
* of the markedInsertBefore flag). If clear, and
* the markedInsertList is nonzero, then the
* specified glyph list will be inserted as a
* split-vowel-like insertion, either before or
* after the marked glyph (depending on the state
* of the markedInsertBefore flag). */
CurrentInsertBefore= 0x0800, /* If set, specifies that insertions are to be made
* to the left of the current glyph. If clear,
* they're made to the right of the current glyph. */
MarkedInsertBefore= 0x0400, /* If set, specifies that insertions are to be
* made to the left of the marked glyph. If clear,
* they're made to the right of the marked glyph. */
CurrentInsertCount= 0x3E0, /* This 5-bit field is treated as a count of the
* number of glyphs to insert at the current
* position. Since zero means no insertions, the
* largest number of insertions at any given
* current location is 31 glyphs. */
MarkedInsertCount= 0x001F, /* This 5-bit field is treated as a count of the
* number of glyphs to insert at the marked
* position. Since zero means no insertions, the
* largest number of insertions at any given
* marked location is 31 glyphs. */
};
inline driver_context_t (const InsertionSubtable *table,
hb_aat_apply_context_t *c_) :
ret (false),
c (c_),
mark_set (false),
mark (0),
insertionAction (table+table->insertionAction) {}
inline bool is_actionable (StateTableDriver<EntryData> *driver,
const Entry<EntryData> *entry)
{
return (entry->flags & (CurrentInsertCount | MarkedInsertCount)) &&
(entry->data.currentInsertIndex != 0xFFFF ||entry->data.markedInsertIndex != 0xFFFF);
}
inline bool transition (StateTableDriver<EntryData> *driver,
const Entry<EntryData> *entry)
{
hb_buffer_t *buffer = driver->buffer;
unsigned int flags = entry->flags;
if (entry->data.markedInsertIndex != 0xFFFF)
{
unsigned int count = (entry->flags & MarkedInsertCount);
unsigned int start = entry->data.markedInsertIndex;
const GlyphID *glyphs = &insertionAction[start];
if (unlikely (!c->sanitizer.check_array (glyphs, count))) return false;
bool before = entry->flags & MarkedInsertBefore;
if (unlikely (!mark_set)) return false;
unsigned int end = buffer->out_len;
buffer->move_to (mark);
if (!before)
buffer->copy_glyph ();
/* TODO We ignore KashidaLike setting. */
for (unsigned int i = 0; i < count; i++)
buffer->output_glyph (glyphs[i]);
if (!before)
buffer->skip_glyph ();
buffer->move_to (end + count);
}
if (entry->data.currentInsertIndex != 0xFFFF)
{
unsigned int count = (entry->flags & CurrentInsertCount) >> 5;
unsigned int start = entry->data.currentInsertIndex;
const GlyphID *glyphs = &insertionAction[start];
if (unlikely (!c->sanitizer.check_array (glyphs, count))) return false;
bool before = entry->flags & CurrentInsertBefore;
unsigned int end = buffer->out_len;
if (!before)
buffer->copy_glyph ();
/* TODO We ignore KashidaLike setting. */
for (unsigned int i = 0; i < count; i++)
buffer->output_glyph (glyphs[i]);
if (!before)
buffer->skip_glyph ();
buffer->move_to (end);
}
if (flags & SetMark)
{
mark_set = true;
mark = buffer->out_len;
}
return true;
}
public:
bool ret;
private:
hb_aat_apply_context_t *c;
bool mark_set;
unsigned int mark;
const UnsizedArrayOf<GlyphID> &insertionAction;
};
inline bool apply (hb_aat_apply_context_t *c) const
{
TRACE_APPLY (this);
/* TODO */
return_trace (false);
driver_context_t dc (this, c);
StateTableDriver<EntryData> driver (machine, c->buffer, c->face);
driver.drive (&dc);
return_trace (dc.ret);
}
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
/* TODO */
return_trace (true);
/* The rest of array sanitizations are done at run-time. */
return_trace (c->check_struct (this) && machine.sanitize (c) &&
insertionAction);
}
protected:
StateTable<EntryData>
machine;
LOffsetTo<UnsizedArrayOf<GlyphID>, false>
insertionAction; /* Byte offset from stateHeader to the start of
* the insertion glyph table. */
public:
DEFINE_SIZE_STATIC (20);
};
@ -561,7 +732,8 @@ struct ChainSubtable
inline unsigned int get_size (void) const { return length; }
inline unsigned int get_type (void) const { return coverage & 0xFF; }
enum Type {
enum Type
{
Rearrangement = 0,
Contextual = 1,
Ligature = 2,
@ -569,11 +741,6 @@ struct ChainSubtable
Insertion = 5
};
inline void apply (hb_aat_apply_context_t *c) const
{
dispatch (c);
}
template <typename context_t>
inline typename context_t::return_t dispatch (context_t *c) const
{
@ -619,28 +786,45 @@ struct Chain
{
inline void apply (hb_aat_apply_context_t *c) const
{
uint32_t flags = defaultFlags;
{
/* Compute applicable flags. TODO Should move this to planning
* stage and take user-requested features into account. */
unsigned int count = featureCount;
for (unsigned i = 0; i < count; i++)
{
const Feature &feature = featureZ[i];
if (false) /* XXX Check if feature enabled... */
{
flags &= feature.disableFlags;
flags |= feature.enableFlags;
}
}
}
const ChainSubtable *subtable = &StructAtOffset<ChainSubtable> (&featureZ, featureZ[0].static_size * featureCount);
unsigned int count = subtableCount;
for (unsigned int i = 0; i < count; i++)
{
if (!c->buffer->message (c->font, "start chain subtable %d", c->lookup_index))
{
c->set_lookup_index (c->lookup_index + 1);
continue;
}
if (!(subtable->subFeatureFlags & flags))
goto skip;
subtable->apply (c);
subtable = &StructAfter<ChainSubtable> (*subtable);
if (!c->buffer->message (c->font, "start chain subtable %d", c->lookup_index))
goto skip;
subtable->dispatch (c);
(void) c->buffer->message (c->font, "end chain subtable %d", c->lookup_index);
skip:
subtable = &StructAfter<ChainSubtable> (*subtable);
c->set_lookup_index (c->lookup_index + 1);
}
}
inline unsigned int get_size (void) const { return length; }
inline bool sanitize (hb_sanitize_context_t *c, unsigned int major) const
inline bool sanitize (hb_sanitize_context_t *c, unsigned int version) const
{
TRACE_SANITIZE (this);
if (!length.sanitize (c) ||
@ -671,7 +855,7 @@ struct Chain
UnsizedArrayOf<Feature> featureZ; /* Features. */
/*ChainSubtable firstSubtable;*//* Subtables. */
/*subtableGlyphCoverageArray*/ /* Only if major == 3. */
/*subtableGlyphCoverageArray*/ /* Only if version >= 3. We don't use. */
public:
DEFINE_SIZE_MIN (16);
@ -701,8 +885,7 @@ struct morx
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (!version.sanitize (c) ||
(version.major >> (sizeof (HBUINT32) == 4 ? 1 : 0)) != 1 ||
if (!version.sanitize (c) || version < 2 ||
!chainCount.sanitize (c))
return_trace (false);
@ -710,7 +893,7 @@ struct morx
unsigned int count = chainCount;
for (unsigned int i = 0; i < count; i++)
{
if (!chain->sanitize (c, version.major))
if (!chain->sanitize (c, version))
return_trace (false);
chain = &StructAfter<Chain> (*chain);
}
@ -719,8 +902,9 @@ struct morx
}
protected:
FixedVersion<>version; /* Version number of the glyph metamorphosis table.
* 1 for mort, 2 or 3 for morx. */
HBUINT16 version; /* Version number of the glyph metamorphosis table.
* 2 or 3. */
HBUINT16 unused; /* Set to 0. */
HBUINT32 chainCount; /* Number of metamorphosis chains contained in this
* table. */
Chain firstChain; /* Chains. */

View File

@ -68,7 +68,7 @@ struct TrackTableEntry
protected:
Fixed track; /* Track value for this record. */
NameID trackNameID; /* The 'name' table index for this track */
OffsetTo<UnsizedArrayOf<FWORD> >
OffsetTo<UnsizedArrayOf<FWORD>, HBUINT16, false>
valuesZ; /* Offset from start of tracking table to
* per-size tracking values for this track. */
@ -134,7 +134,7 @@ struct TrackData
protected:
HBUINT16 nTracks; /* Number of separate tracks included in this table. */
HBUINT16 nSizes; /* Number of point sizes included in this table. */
LOffsetTo<UnsizedArrayOf<Fixed> >
LOffsetTo<UnsizedArrayOf<Fixed>, false>
sizeTable; /* Offset to array[nSizes] of size values. */
UnsizedArrayOf<TrackTableEntry>
trackTable; /* Array[nTracks] of TrackTableEntry records. */

View File

@ -46,7 +46,7 @@ struct FTStringRange
}
protected:
OffsetTo<UnsizedArrayOf<HBUINT8> >
OffsetTo<UnsizedArrayOf<HBUINT8>, HBUINT16, false>
tag; /* Offset from the start of the table to
* the beginning of the string */
HBUINT16 length; /* String length (in bytes) */

View File

@ -531,7 +531,6 @@ hb_script_get_horizontal_direction (hb_script_t script)
/* Unicode-8.0 additions */
case HB_SCRIPT_HATRAN:
case HB_SCRIPT_OLD_HUNGARIAN:
/* Unicode-9.0 additions */
case HB_SCRIPT_ADLAM:
@ -545,6 +544,7 @@ hb_script_get_horizontal_direction (hb_script_t script)
/* https://github.com/harfbuzz/harfbuzz/issues/1000 */
case HB_SCRIPT_OLD_HUNGARIAN:
case HB_SCRIPT_OLD_ITALIC:
case HB_SCRIPT_RUNIC:

View File

@ -73,19 +73,6 @@ static_assert (true, "Just so we take semicolon after.")
#define DEFINE_NULL_INSTANCE(Type) \
const Type _hb_Null_##Type
/* Specializaiton to disallow Null objects. */
#define DECLARE_NULL_DISALLOW(Type) \
template <> inline const Type& Null<Type> (void)
#define DECLARE_NULL_NAMSPACE_DISALLOW(Namespace, Type) \
} /* Close namespace. */ \
template <> \
/*static*/ inline const Namespace::Type& Null<Namespace::Type> (void) { \
extern void *_hb_undefined; \
return *reinterpret_cast<const Namespace::Type *> (_hb_undefined); \
} \
namespace Namespace { \
static_assert (true, "Just so we take semicolon after.")
/* Global writable pool. Enlarge as necessary. */
/* To be fully correct, CrapPool must be thread_local. However, we do not rely on CrapPool

View File

@ -348,7 +348,7 @@ struct ResourceTypeRecord
protected:
Tag tag; /* Resource type. */
HBUINT16 resCountM1; /* Number of resources minus 1. */
OffsetTo<UnsizedArrayOf<ResourceRecord> >
OffsetTo<UnsizedArrayOf<ResourceRecord>, HBUINT16, false>
resourcesZ; /* Offset from beginning of resource type list
* to reference item list for this type. */
public:
@ -387,10 +387,9 @@ struct ResourceMap
inline bool sanitize (hb_sanitize_context_t *c, const void *data_base) const
{
TRACE_SANITIZE (this);
const void *type_base = &(this+typeList);
return_trace (c->check_struct (this) &&
typeList.sanitize (c, this,
type_base,
&(this+typeList),
data_base));
}
@ -405,7 +404,7 @@ struct ResourceMap
HBUINT32 reserved1; /* Reserved for handle to next resource map */
HBUINT16 resreved2; /* Reserved for file reference number */
HBUINT16 attrs; /* Resource fork attribute */
OffsetTo<ArrayOfM1<ResourceTypeRecord> >
OffsetTo<ArrayOfM1<ResourceTypeRecord>, HBUINT16, false>
typeList; /* Offset from beginning of map to
* resource type list */
Offset16 nameList; /* Offset from beginning of map to
@ -437,10 +436,10 @@ struct ResourceForkHeader
}
protected:
LOffsetTo<UnsizedArrayOf<HBUINT8> >
LOffsetTo<UnsizedArrayOf<HBUINT8>, false>
data; /* Offset from beginning of resource fork
* to resource data */
LOffsetTo<ResourceMap>
LOffsetTo<ResourceMap, false>
map; /* Offset from beginning of resource fork
* to resource map */
HBUINT32 dataLen; /* Length of resource data */

View File

@ -226,9 +226,14 @@ struct FixedVersion
* Use: (base+offset)
*/
template <typename Type, bool has_null_> struct assert_has_min_size { static_assert (Type::min_size > 0, ""); };
template <typename Type> struct assert_has_min_size<Type, false> {};
template <typename Type, typename OffsetType=HBUINT16, bool has_null=true>
struct OffsetTo : Offset<OffsetType, has_null>
{
static_assert (sizeof (assert_has_min_size<Type, has_null>) || true, "");
inline const Type& operator () (const void *base) const
{
if (unlikely (this->is_null ())) return Null(Type);
@ -311,7 +316,7 @@ struct OffsetTo : Offset<OffsetType, has_null>
}
DEFINE_SIZE_STATIC (sizeof(OffsetType));
};
template <typename Type> struct LOffsetTo : OffsetTo<Type, HBUINT32> {};
template <typename Type, bool has_null=true> struct LOffsetTo : OffsetTo<Type, HBUINT32, has_null> {};
template <typename Base, typename OffsetType, bool has_null, typename Type>
static inline const Type& operator + (const Base &base, const OffsetTo<Type, OffsetType, has_null> &offset) { return offset (base); }
template <typename Base, typename OffsetType, bool has_null, typename Type>

View File

@ -264,8 +264,6 @@ struct IndexSubtableArray
protected:
UnsizedArrayOf<IndexSubtableRecord> indexSubtablesZ;
public:
DEFINE_SIZE_ARRAY(0, indexSubtablesZ);
};
struct BitmapSizeTable
@ -289,7 +287,7 @@ struct BitmapSizeTable
}
protected:
LOffsetTo<IndexSubtableArray>
LOffsetTo<IndexSubtableArray, false>
indexSubtableArrayOffset;
HBUINT32 indexTablesSize;
HBUINT32 numberOfIndexSubtables;

View File

@ -129,9 +129,9 @@ struct COLR
protected:
HBUINT16 version; /* Table version number */
HBUINT16 numBaseGlyphs; /* Number of Base Glyph Records */
LOffsetTo<UnsizedArrayOf<BaseGlyphRecord> >
LOffsetTo<UnsizedArrayOf<BaseGlyphRecord>, false>
baseGlyphsZ; /* Offset to Base Glyph records. */
LOffsetTo<UnsizedArrayOf<LayerRecord> >
LOffsetTo<UnsizedArrayOf<LayerRecord>, false>
layersZ; /* Offset to Layer Records */
HBUINT16 numLayers; /* Number of Layer Records */
public:

View File

@ -118,15 +118,15 @@ struct CPALV1Tail
}
protected:
LOffsetTo<UnsizedArrayOf<HBUINT32> >
LOffsetTo<UnsizedArrayOf<HBUINT32>, false>
paletteFlagsZ; /* Offset from the beginning of CPAL table to
* the Palette Type Array. Set to 0 if no array
* is provided. */
LOffsetTo<UnsizedArrayOf<HBUINT16> >
LOffsetTo<UnsizedArrayOf<HBUINT16>, false>
paletteLabelZ; /* Offset from the beginning of CPAL table to
* the Palette Labels Array. Set to 0 if no
* array is provided. */
LOffsetTo<UnsizedArrayOf<HBUINT16> >
LOffsetTo<UnsizedArrayOf<HBUINT16>, false>
paletteEntryLabelZ; /* Offset from the beginning of CPAL table to
* the Palette Entry Label Array. Set to 0
* if no array is provided. */
@ -207,7 +207,7 @@ struct CPAL
HBUINT16 numPalettes; /* Number of palettes in the table. */
HBUINT16 numColorRecords; /* Total number of color records, combined for
* all palettes. */
LOffsetTo<UnsizedArrayOf<BGRAColor> >
LOffsetTo<UnsizedArrayOf<BGRAColor>, false>
colorRecordsZ; /* Offset from the beginning of CPAL table to
* the first ColorRecord. */
UnsizedArrayOf<HBUINT16>

View File

@ -54,7 +54,7 @@ struct SVGDocumentIndexEntry
* this index entry. */
HBUINT16 endGlyphID; /* The last glyph ID in the range described by
* this index entry. Must be >= startGlyphID. */
LOffsetTo<UnsizedArrayOf<HBUINT8> >
LOffsetTo<UnsizedArrayOf<HBUINT8>, false>
svgDoc; /* Offset from the beginning of the SVG Document Index
* to an SVG document. Must be non-zero. */
HBUINT32 svgDocLength; /* Length of the SVG document.

View File

@ -70,6 +70,11 @@ namespace OT {
* Script, ScriptList, LangSys, Feature, FeatureList, Lookup, LookupList
*/
struct Record_sanitize_closure_t {
hb_tag_t tag;
const void *list_base;
};
template <typename Type>
struct Record
{
@ -77,14 +82,10 @@ struct Record
return tag.cmp (a);
}
struct sanitize_closure_t {
hb_tag_t tag;
const void *list_base;
};
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
const sanitize_closure_t closure = {tag, base};
const Record_sanitize_closure_t closure = {tag, base};
return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure));
}
@ -240,7 +241,7 @@ struct LangSys
}
inline bool sanitize (hb_sanitize_context_t *c,
const Record<LangSys>::sanitize_closure_t * = nullptr) const
const Record_sanitize_closure_t * = nullptr) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && featureIndex.sanitize (c));
@ -291,7 +292,7 @@ struct Script
}
inline bool sanitize (hb_sanitize_context_t *c,
const Record<Script>::sanitize_closure_t * = nullptr) const
const Record_sanitize_closure_t * = nullptr) const
{
TRACE_SANITIZE (this);
return_trace (defaultLangSys.sanitize (c, this) && langSys.sanitize (c, this));
@ -526,6 +527,7 @@ struct FeatureParams
FeatureParamsStylisticSet stylisticSet;
FeatureParamsCharacterVariants characterVariants;
} u;
public:
DEFINE_SIZE_STATIC (17);
};
@ -553,7 +555,7 @@ struct Feature
}
inline bool sanitize (hb_sanitize_context_t *c,
const Record<Feature>::sanitize_closure_t *closure = nullptr) const
const Record_sanitize_closure_t *closure = nullptr) const
{
TRACE_SANITIZE (this);
if (unlikely (!(c->check_struct (this) && lookupIndex.sanitize (c))))

View File

@ -124,7 +124,7 @@ struct JstfPriority
struct JstfLangSys : OffsetListOf<JstfPriority>
{
inline bool sanitize (hb_sanitize_context_t *c,
const Record<JstfLangSys>::sanitize_closure_t * = nullptr) const
const Record_sanitize_closure_t * = nullptr) const
{
TRACE_SANITIZE (this);
return_trace (OffsetListOf<JstfPriority>::sanitize (c));
@ -165,7 +165,7 @@ struct JstfScript
inline const JstfLangSys& get_default_lang_sys (void) const { return this+defaultLangSys; }
inline bool sanitize (hb_sanitize_context_t *c,
const Record<JstfScript>::sanitize_closure_t * = nullptr) const
const Record_sanitize_closure_t * = nullptr) const
{
TRACE_SANITIZE (this);
return_trace (extenderGlyphs.sanitize (c, this) &&

View File

@ -245,7 +245,7 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer)
props |= UPROPS_MASK_HIDDEN;
}
}
else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL (gen_cat)))
else if (unlikely (HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK (gen_cat)))
{
/* The above check is just an optimization to let in only things we need further
* processing on. */
@ -263,17 +263,7 @@ _hb_glyph_info_set_unicode_props (hb_glyph_info_t *info, hb_buffer_t *buffer)
* Also, all Mn's that are Default_Ignorable, have ccc=0, hence
* the "else if".
*/
props |= unicode->modified_combining_class (info->codepoint)<<8;
/* Recategorize emoji skin-tone modifiers as Unicode mark, so they
* behave correctly in non-native directionality. They originally
* are MODIFIER_SYMBOL. Fixes:
* https://github.com/harfbuzz/harfbuzz/issues/169
*/
if (unlikely (hb_in_range (u, 0x1F3FBu, 0x1F3FFu)))
{
props = gen_cat = HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK;
}
props |= unicode->modified_combining_class (u)<<8;
}
}

View File

@ -102,23 +102,42 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE
}
inline hb_unicode_general_category_t
modified_general_category (hb_codepoint_t u)
{
hb_unicode_general_category_t cat = general_category (u);
if (unlikely (cat == HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL))
{
/* Recategorize emoji skin-tone modifiers as Unicode mark, so they
* behave correctly in non-native directionality. They originally
* are MODIFIER_SYMBOL. Fixes:
* https://github.com/harfbuzz/harfbuzz/issues/169
*/
if (unlikely (hb_in_range<hb_codepoint_t> (u, 0x1F3FBu, 0x1F3FFu)))
cat = HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK;
}
return cat;
}
inline unsigned int
modified_combining_class (hb_codepoint_t unicode)
modified_combining_class (hb_codepoint_t u)
{
/* XXX This hack belongs to the Myanmar shaper. */
if (unlikely (unicode == 0x1037u)) unicode = 0x103Au;
if (unlikely (u == 0x1037u)) u = 0x103Au;
/* XXX This hack belongs to the USE shaper (for Tai Tham):
* Reorder SAKOT to ensure it comes after any tone marks. */
if (unlikely (unicode == 0x1A60u)) return 254;
if (unlikely (u == 0x1A60u)) return 254;
/* XXX This hack belongs to the Tibetan shaper:
* Reorder PADMA to ensure it comes after any vowel marks. */
if (unlikely (unicode == 0x0FC6u)) return 254;
if (unlikely (u == 0x0FC6u)) return 254;
/* Reorder TSA -PHRU to reorder before U+0F74 */
if (unlikely (unicode == 0x0F39u)) return 127;
if (unlikely (u == 0x0F39u)) return 127;
return _hb_modified_combining_class[combining_class (unicode)];
return _hb_modified_combining_class[combining_class (u)];
}
static inline hb_bool_t
@ -360,10 +379,9 @@ DECLARE_NULL_INSTANCE (hb_unicode_funcs_t);
FLAG (HB_UNICODE_GENERAL_CATEGORY_ENCLOSING_MARK) | \
FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
#define HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK_OR_MODIFIER_SYMBOL(gen_cat) \
#define HB_UNICODE_GENERAL_CATEGORY_IS_NON_ENCLOSING_MARK(gen_cat) \
(FLAG_UNSAFE (gen_cat) & \
(FLAG (HB_UNICODE_GENERAL_CATEGORY_SPACING_MARK) | \
FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK) | \
FLAG (HB_UNICODE_GENERAL_CATEGORY_MODIFIER_SYMBOL)))
FLAG (HB_UNICODE_GENERAL_CATEGORY_NON_SPACING_MARK)))
#endif /* HB_UNICODE_HH */