< prev index next >
src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-cmap-table.hh
Print this page
*** 25,60 ****
*/
#ifndef HB_OT_CMAP_TABLE_HH
#define HB_OT_CMAP_TABLE_HH
! #include "hb-open-type-private.hh"
! #include "hb-set-private.hh"
! #include "hb-subset-plan.hh"
/*
* cmap -- Character to Glyph Index Mapping
* https://docs.microsoft.com/en-us/typography/opentype/spec/cmap
*/
#define HB_OT_TAG_cmap HB_TAG('c','m','a','p')
-
namespace OT {
struct CmapSubtableFormat0
{
! inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
{
hb_codepoint_t gid = codepoint < 256 ? glyphIdArray[codepoint] : 0;
if (!gid)
return false;
*glyph = gid;
return true;
}
! inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
--- 25,64 ----
*/
#ifndef HB_OT_CMAP_TABLE_HH
#define HB_OT_CMAP_TABLE_HH
! #include "hb-open-type.hh"
! #include "hb-set.hh"
/*
* cmap -- Character to Glyph Index Mapping
* https://docs.microsoft.com/en-us/typography/opentype/spec/cmap
*/
#define HB_OT_TAG_cmap HB_TAG('c','m','a','p')
namespace OT {
struct CmapSubtableFormat0
{
! bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
{
hb_codepoint_t gid = codepoint < 256 ? glyphIdArray[codepoint] : 0;
if (!gid)
return false;
*glyph = gid;
return true;
}
+ void collect_unicodes (hb_set_t *out) const
+ {
+ for (unsigned int i = 0; i < 256; i++)
+ if (glyphIdArray[i])
+ out->add (i);
+ }
! bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
*** 86,112 ****
if (unlikely (!c->extend_min (*this))) return_trace (false);
this->format.set (4);
this->length.set (get_sub_table_size (segments));
! this->segCountX2.set (segments.len * 2);
! this->entrySelector.set (MAX (1u, _hb_bit_storage (segments.len)) - 1);
this->searchRange.set (2 * (1u << this->entrySelector));
! this->rangeShift.set (segments.len * 2 > this->searchRange
! ? 2 * segments.len - this->searchRange
: 0);
! HBUINT16 *end_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len);
c->allocate_size<HBUINT16> (HBUINT16::static_size); // 2 bytes of padding.
! HBUINT16 *start_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len);
! HBINT16 *id_delta = c->allocate_size<HBINT16> (HBUINT16::static_size * segments.len);
! HBUINT16 *id_range_offset = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len);
if (id_range_offset == nullptr)
return_trace (false);
! for (unsigned int i = 0; i < segments.len; i++)
{
end_count[i].set (segments[i].end_code);
start_count[i].set (segments[i].start_code);
if (segments[i].use_delta)
{
--- 90,116 ----
if (unlikely (!c->extend_min (*this))) return_trace (false);
this->format.set (4);
this->length.set (get_sub_table_size (segments));
! this->segCountX2.set (segments.length * 2);
! this->entrySelector.set (MAX (1u, hb_bit_storage (segments.length)) - 1);
this->searchRange.set (2 * (1u << this->entrySelector));
! this->rangeShift.set (segments.length * 2 > this->searchRange
! ? 2 * segments.length - this->searchRange
: 0);
! HBUINT16 *end_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.length);
c->allocate_size<HBUINT16> (HBUINT16::static_size); // 2 bytes of padding.
! HBUINT16 *start_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.length);
! HBINT16 *id_delta = c->allocate_size<HBINT16> (HBUINT16::static_size * segments.length);
! HBUINT16 *id_range_offset = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.length);
if (id_range_offset == nullptr)
return_trace (false);
! for (unsigned int i = 0; i < segments.length; i++)
{
end_count[i].set (segments[i].end_code);
start_count[i].set (segments[i].start_code);
if (segments[i].use_delta)
{
*** 148,161 ****
}
return_trace (true);
}
! static inline size_t get_sub_table_size (const hb_vector_t<segment_plan> &segments)
{
size_t segment_size = 0;
! for (unsigned int i = 0; i < segments.len; i++)
{
// Parallel array entries
segment_size +=
2 // end count
+ 2 // start count
--- 152,165 ----
}
return_trace (true);
}
! static size_t get_sub_table_size (const hb_vector_t<segment_plan> &segments)
{
size_t segment_size = 0;
! for (unsigned int i = 0; i < segments.length; i++)
{
// Parallel array entries
segment_size +=
2 // end count
+ 2 // start count
*** 170,180 ****
return min_size
+ 2 // Padding
+ segment_size;
}
! static inline bool create_sub_table_plan (const hb_subset_plan_t *plan,
hb_vector_t<segment_plan> *segments)
{
segment_plan *segment = nullptr;
hb_codepoint_t last_gid = 0;
--- 174,184 ----
return min_size
+ 2 // Padding
+ segment_size;
}
! static bool create_sub_table_plan (const hb_subset_plan_t *plan,
hb_vector_t<segment_plan> *segments)
{
segment_plan *segment = nullptr;
hb_codepoint_t last_gid = 0;
*** 185,201 ****
{
DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp);
return false;
}
! if (cp > 0xFFFF) {
! // We are now outside of unicode BMP, stop adding to this cmap.
! break;
! }
! if (!segment
! || cp != segment->end_code + 1u)
{
segment = segments->push ();
segment->start_code.set (cp);
segment->end_code.set (cp);
segment->use_delta = true;
--- 189,203 ----
{
DEBUG_MSG(SUBSET, nullptr, "Unable to find new gid for %04x", cp);
return false;
}
! /* Stop adding to cmap if we are now outside of unicode BMP. */
! if (cp > 0xFFFF) break;
! if (!segment ||
! cp != segment->end_code + 1u)
{
segment = segments->push ();
segment->start_code.set (cp);
segment->end_code.set (cp);
segment->use_delta = true;
*** 222,254 ****
return true;
}
struct accelerator_t
{
! inline void init (const CmapSubtableFormat4 *subtable)
{
segCount = subtable->segCountX2 / 2;
! endCount = subtable->values;
startCount = endCount + segCount + 1;
idDelta = startCount + segCount;
idRangeOffset = idDelta + segCount;
glyphIdArray = idRangeOffset + segCount;
glyphIdArrayLength = (subtable->length - 16 - 8 * segCount) / 2;
}
! static inline bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph)
{
- const accelerator_t *thiz = (const accelerator_t *) obj;
-
/* Custom two-array bsearch. */
! int min = 0, max = (int) thiz->segCount - 1;
! const HBUINT16 *startCount = thiz->startCount;
! const HBUINT16 *endCount = thiz->endCount;
unsigned int i;
while (min <= max)
{
! int mid = (min + max) / 2;
if (codepoint < startCount[mid])
max = mid - 1;
else if (codepoint > endCount[mid])
min = mid + 1;
else
--- 224,259 ----
return true;
}
struct accelerator_t
{
! accelerator_t () {}
! accelerator_t (const CmapSubtableFormat4 *subtable) { init (subtable); }
! ~accelerator_t () { fini (); }
!
! void init (const CmapSubtableFormat4 *subtable)
{
segCount = subtable->segCountX2 / 2;
! endCount = subtable->values.arrayZ;
startCount = endCount + segCount + 1;
idDelta = startCount + segCount;
idRangeOffset = idDelta + segCount;
glyphIdArray = idRangeOffset + segCount;
glyphIdArrayLength = (subtable->length - 16 - 8 * segCount) / 2;
}
+ void fini () {}
! bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
{
/* Custom two-array bsearch. */
! int min = 0, max = (int) this->segCount - 1;
! const HBUINT16 *startCount = this->startCount;
! const HBUINT16 *endCount = this->endCount;
unsigned int i;
while (min <= max)
{
! int mid = ((unsigned int) min + (unsigned int) max) / 2;
if (codepoint < startCount[mid])
max = mid - 1;
else if (codepoint > endCount[mid])
min = mid + 1;
else
*** 259,295 ****
}
return false;
found:
hb_codepoint_t gid;
! unsigned int rangeOffset = thiz->idRangeOffset[i];
if (rangeOffset == 0)
! gid = codepoint + thiz->idDelta[i];
else
{
/* Somebody has been smoking... */
! unsigned int index = rangeOffset / 2 + (codepoint - thiz->startCount[i]) + i - thiz->segCount;
! if (unlikely (index >= thiz->glyphIdArrayLength))
return false;
! gid = thiz->glyphIdArray[index];
if (unlikely (!gid))
return false;
! gid += thiz->idDelta[i];
}
!
! *glyph = gid & 0xFFFFu;
return true;
}
!
! static inline void get_all_codepoints_func (const void *obj, hb_set_t *out)
{
! const accelerator_t *thiz = (const accelerator_t *) obj;
! for (unsigned int i = 0; i < thiz->segCount; i++)
{
! if (thiz->startCount[i] != 0xFFFFu
! || thiz->endCount[i] != 0xFFFFu) // Skip the last segment (0xFFFF)
! hb_set_add_range (out, thiz->startCount[i], thiz->endCount[i]);
}
}
const HBUINT16 *endCount;
const HBUINT16 *startCount;
--- 264,322 ----
}
return false;
found:
hb_codepoint_t gid;
! unsigned int rangeOffset = this->idRangeOffset[i];
if (rangeOffset == 0)
! gid = codepoint + this->idDelta[i];
else
{
/* Somebody has been smoking... */
! unsigned int index = rangeOffset / 2 + (codepoint - this->startCount[i]) + i - this->segCount;
! if (unlikely (index >= this->glyphIdArrayLength))
return false;
! gid = this->glyphIdArray[index];
if (unlikely (!gid))
return false;
! gid += this->idDelta[i];
}
! gid &= 0xFFFFu;
! if (!gid)
! return false;
! *glyph = gid;
return true;
}
! static bool get_glyph_func (const void *obj, hb_codepoint_t codepoint, hb_codepoint_t *glyph)
! {
! return ((const accelerator_t *) obj)->get_glyph (codepoint, glyph);
! }
! void collect_unicodes (hb_set_t *out) const
{
! unsigned int count = this->segCount;
! if (count && this->startCount[count - 1] == 0xFFFFu)
! count--; /* Skip sentinel segment. */
! for (unsigned int i = 0; i < count; i++)
{
! unsigned int rangeOffset = this->idRangeOffset[i];
! if (rangeOffset == 0)
! out->add_range (this->startCount[i], this->endCount[i]);
! else
! {
! for (hb_codepoint_t codepoint = this->startCount[i];
! codepoint <= this->endCount[i];
! codepoint++)
! {
! unsigned int index = rangeOffset / 2 + (codepoint - this->startCount[i]) + i - this->segCount;
! if (unlikely (index >= this->glyphIdArrayLength))
! break;
! hb_codepoint_t gid = this->glyphIdArray[index];
! if (unlikely (!gid))
! continue;
! out->add (codepoint);
! }
! }
}
}
const HBUINT16 *endCount;
const HBUINT16 *startCount;
*** 298,315 ****
const HBUINT16 *glyphIdArray;
unsigned int segCount;
unsigned int glyphIdArrayLength;
};
! inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
{
! accelerator_t accel;
! accel.init (this);
return accel.get_glyph_func (&accel, codepoint, glyph);
}
! inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this)))
return_trace (false);
--- 325,346 ----
const HBUINT16 *glyphIdArray;
unsigned int segCount;
unsigned int glyphIdArrayLength;
};
! bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
{
! accelerator_t accel (this);
return accel.get_glyph_func (&accel, codepoint, glyph);
}
+ void collect_unicodes (hb_set_t *out) const
+ {
+ accelerator_t accel (this);
+ accel.collect_unicodes (out);
+ }
! bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (unlikely (!c->check_struct (this)))
return_trace (false);
*** 338,356 ****
HBUINT16 segCountX2; /* 2 x segCount. */
HBUINT16 searchRange; /* 2 * (2**floor(log2(segCount))) */
HBUINT16 entrySelector; /* log2(searchRange/2) */
HBUINT16 rangeShift; /* 2 x segCount - searchRange */
! HBUINT16 values[VAR];
#if 0
HBUINT16 endCount[segCount]; /* End characterCode for each segment,
* last=0xFFFFu. */
HBUINT16 reservedPad; /* Set to 0. */
HBUINT16 startCount[segCount]; /* Start character code for each segment. */
HBINT16 idDelta[segCount]; /* Delta for all character codes in segment. */
HBUINT16 idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */
! HBUINT16 glyphIdArray[VAR]; /* Glyph index array (arbitrary length) */
#endif
public:
DEFINE_SIZE_ARRAY (14, values);
};
--- 369,389 ----
HBUINT16 segCountX2; /* 2 x segCount. */
HBUINT16 searchRange; /* 2 * (2**floor(log2(segCount))) */
HBUINT16 entrySelector; /* log2(searchRange/2) */
HBUINT16 rangeShift; /* 2 x segCount - searchRange */
! UnsizedArrayOf<HBUINT16>
! values;
#if 0
HBUINT16 endCount[segCount]; /* End characterCode for each segment,
* last=0xFFFFu. */
HBUINT16 reservedPad; /* Set to 0. */
HBUINT16 startCount[segCount]; /* Start character code for each segment. */
HBINT16 idDelta[segCount]; /* Delta for all character codes in segment. */
HBUINT16 idRangeOffset[segCount];/* Offsets into glyphIdArray or 0 */
! UnsizedArrayOf<HBUINT16>
! glyphIdArray; /* Glyph index array (arbitrary length) */
#endif
public:
DEFINE_SIZE_ARRAY (14, values);
};
*** 368,378 ****
if (codepoint < startCharCode) return -1;
if (codepoint > endCharCode) return +1;
return 0;
}
! inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
--- 401,411 ----
if (codepoint < startCharCode) return -1;
if (codepoint > endCharCode) return +1;
return 0;
}
! bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
*** 382,406 ****
HBUINT32 glyphID; /* Glyph index; interpretation depends on
* subtable format. */
public:
DEFINE_SIZE_STATIC (12);
};
template <typename UINT>
struct CmapSubtableTrimmed
{
! inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
{
/* Rely on our implicit array bound-checking. */
hb_codepoint_t gid = glyphIdArray[codepoint - startCharCode];
if (!gid)
return false;
*glyph = gid;
return true;
}
! inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && glyphIdArray.sanitize (c));
}
--- 415,448 ----
HBUINT32 glyphID; /* Glyph index; interpretation depends on
* subtable format. */
public:
DEFINE_SIZE_STATIC (12);
};
+ DECLARE_NULL_NAMESPACE_BYTES (OT, CmapSubtableLongGroup);
template <typename UINT>
struct CmapSubtableTrimmed
{
! bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
{
/* Rely on our implicit array bound-checking. */
hb_codepoint_t gid = glyphIdArray[codepoint - startCharCode];
if (!gid)
return false;
*glyph = gid;
return true;
}
+ void collect_unicodes (hb_set_t *out) const
+ {
+ hb_codepoint_t start = startCharCode;
+ unsigned int count = glyphIdArray.len;
+ for (unsigned int i = 0; i < count; i++)
+ if (glyphIdArray[i])
+ out->add (start + i);
+ }
! bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && glyphIdArray.sanitize (c));
}
*** 422,462 ****
template <typename T>
struct CmapSubtableLongSegmented
{
friend struct cmap;
! inline bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
{
! int i = groups.bsearch (codepoint);
! if (i == -1)
return false;
! *glyph = T::group_get_glyph (groups[i], codepoint);
return true;
}
! inline void get_all_codepoints (hb_set_t *out) const
{
for (unsigned int i = 0; i < this->groups.len; i++) {
! hb_set_add_range (out,
! this->groups[i].startCharCode,
! this->groups[i].endCharCode);
}
}
! inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && groups.sanitize (c));
}
! inline bool serialize (hb_serialize_context_t *c,
const hb_vector_t<CmapSubtableLongGroup> &group_data)
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return_trace (false);
! Supplier<CmapSubtableLongGroup> supplier (group_data.arrayZ, group_data.len);
! if (unlikely (!groups.serialize (c, supplier, group_data.len))) return_trace (false);
return true;
}
protected:
HBUINT16 format; /* Subtable format; set to 12. */
--- 464,503 ----
template <typename T>
struct CmapSubtableLongSegmented
{
friend struct cmap;
! bool get_glyph (hb_codepoint_t codepoint, hb_codepoint_t *glyph) const
{
! hb_codepoint_t gid = T::group_get_glyph (groups.bsearch (codepoint), codepoint);
! if (!gid)
return false;
! *glyph = gid;
return true;
}
! void collect_unicodes (hb_set_t *out) const
{
for (unsigned int i = 0; i < this->groups.len; i++) {
! out->add_range (this->groups[i].startCharCode,
! MIN ((hb_codepoint_t) this->groups[i].endCharCode,
! (hb_codepoint_t) HB_UNICODE_MAX));
}
}
! bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && groups.sanitize (c));
}
! bool serialize (hb_serialize_context_t *c,
const hb_vector_t<CmapSubtableLongGroup> &group_data)
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return_trace (false);
! if (unlikely (!groups.serialize (c, group_data.as_array ()))) return_trace (false);
return true;
}
protected:
HBUINT16 format; /* Subtable format; set to 12. */
*** 469,481 ****
DEFINE_SIZE_ARRAY (16, groups);
};
struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
{
! static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
hb_codepoint_t u)
! { return group.glyphID + (u - group.startCharCode); }
bool serialize (hb_serialize_context_t *c,
const hb_vector_t<CmapSubtableLongGroup> &groups)
{
--- 510,523 ----
DEFINE_SIZE_ARRAY (16, groups);
};
struct CmapSubtableFormat12 : CmapSubtableLongSegmented<CmapSubtableFormat12>
{
! static hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
hb_codepoint_t u)
! { return likely (group.startCharCode <= group.endCharCode) ?
! group.glyphID + (u - group.startCharCode) : 0; }
bool serialize (hb_serialize_context_t *c,
const hb_vector_t<CmapSubtableLongGroup> &groups)
{
*** 486,501 ****
this->length.set (get_sub_table_size (groups));
return CmapSubtableLongSegmented<CmapSubtableFormat12>::serialize (c, groups);
}
! static inline size_t get_sub_table_size (const hb_vector_t<CmapSubtableLongGroup> &groups)
{
! return 16 + 12 * groups.len;
}
! static inline bool create_sub_table_plan (const hb_subset_plan_t *plan,
hb_vector_t<CmapSubtableLongGroup> *groups)
{
CmapSubtableLongGroup *group = nullptr;
hb_codepoint_t cp = HB_SET_VALUE_INVALID;
--- 528,543 ----
this->length.set (get_sub_table_size (groups));
return CmapSubtableLongSegmented<CmapSubtableFormat12>::serialize (c, groups);
}
! static size_t get_sub_table_size (const hb_vector_t<CmapSubtableLongGroup> &groups)
{
! return 16 + 12 * groups.length;
}
! static bool create_sub_table_plan (const hb_subset_plan_t *plan,
hb_vector_t<CmapSubtableLongGroup> *groups)
{
CmapSubtableLongGroup *group = nullptr;
hb_codepoint_t cp = HB_SET_VALUE_INVALID;
*** 511,537 ****
{
group = groups->push ();
group->startCharCode.set (cp);
group->endCharCode.set (cp);
group->glyphID.set (new_gid);
- } else
- {
- group->endCharCode.set (cp);
}
}
DEBUG_MSG(SUBSET, nullptr, "cmap");
! for (unsigned int i = 0; i < groups->len; i++) {
CmapSubtableLongGroup& group = (*groups)[i];
DEBUG_MSG(SUBSET, nullptr, " %d: U+%04X-U+%04X, gid %d-%d", i, (uint32_t) group.startCharCode, (uint32_t) group.endCharCode, (uint32_t) group.glyphID, (uint32_t) group.glyphID + ((uint32_t) group.endCharCode - (uint32_t) group.startCharCode));
}
return true;
}
private:
! static inline bool _is_gid_consecutive (CmapSubtableLongGroup *group,
hb_codepoint_t cp,
hb_codepoint_t new_gid)
{
return (cp - 1 == group->endCharCode) &&
new_gid == group->glyphID + (cp - group->startCharCode);
--- 553,577 ----
{
group = groups->push ();
group->startCharCode.set (cp);
group->endCharCode.set (cp);
group->glyphID.set (new_gid);
}
+ else group->endCharCode.set (cp);
}
DEBUG_MSG(SUBSET, nullptr, "cmap");
! for (unsigned int i = 0; i < groups->length; i++) {
CmapSubtableLongGroup& group = (*groups)[i];
DEBUG_MSG(SUBSET, nullptr, " %d: U+%04X-U+%04X, gid %d-%d", i, (uint32_t) group.startCharCode, (uint32_t) group.endCharCode, (uint32_t) group.glyphID, (uint32_t) group.glyphID + ((uint32_t) group.endCharCode - (uint32_t) group.startCharCode));
}
return true;
}
private:
! static bool _is_gid_consecutive (CmapSubtableLongGroup *group,
hb_codepoint_t cp,
hb_codepoint_t new_gid)
{
return (cp - 1 == group->endCharCode) &&
new_gid == group->glyphID + (cp - group->startCharCode);
*** 539,549 ****
};
struct CmapSubtableFormat13 : CmapSubtableLongSegmented<CmapSubtableFormat13>
{
! static inline hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
hb_codepoint_t u HB_UNUSED)
{ return group.glyphID; }
};
typedef enum
--- 579,589 ----
};
struct CmapSubtableFormat13 : CmapSubtableLongSegmented<CmapSubtableFormat13>
{
! static hb_codepoint_t group_get_glyph (const CmapSubtableLongGroup &group,
hb_codepoint_t u HB_UNUSED)
{ return group.glyphID; }
};
typedef enum
*** 553,570 ****
GLYPH_VARIANT_USE_DEFAULT = 2
} glyph_variant_t;
struct UnicodeValueRange
{
! inline int cmp (const hb_codepoint_t &codepoint) const
{
if (codepoint < startUnicodeValue) return -1;
if (codepoint > startUnicodeValue + additionalCount) return +1;
return 0;
}
! inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
--- 593,610 ----
GLYPH_VARIANT_USE_DEFAULT = 2
} glyph_variant_t;
struct UnicodeValueRange
{
! int cmp (const hb_codepoint_t &codepoint) const
{
if (codepoint < startUnicodeValue) return -1;
if (codepoint > startUnicodeValue + additionalCount) return +1;
return 0;
}
! bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
*** 573,592 ****
* range. */
public:
DEFINE_SIZE_STATIC (4);
};
! typedef SortedArrayOf<UnicodeValueRange, HBUINT32> DefaultUVS;
struct UVSMapping
{
! inline int cmp (const hb_codepoint_t &codepoint) const
{
return unicodeValue.cmp (codepoint);
}
! inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
--- 613,648 ----
* range. */
public:
DEFINE_SIZE_STATIC (4);
};
! struct DefaultUVS : SortedArrayOf<UnicodeValueRange, HBUINT32>
! {
! void collect_unicodes (hb_set_t *out) const
! {
! unsigned int count = len;
! for (unsigned int i = 0; i < count; i++)
! {
! hb_codepoint_t first = arrayZ[i].startUnicodeValue;
! hb_codepoint_t last = MIN ((hb_codepoint_t) (first + arrayZ[i].additionalCount),
! (hb_codepoint_t) HB_UNICODE_MAX);
! out->add_range (first, last);
! }
! }
!
! public:
! DEFINE_SIZE_ARRAY (4, *this);
! };
struct UVSMapping
{
! int cmp (const hb_codepoint_t &codepoint) const
{
return unicodeValue.cmp (codepoint);
}
! bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this));
}
*** 594,632 ****
GlyphID glyphID; /* Glyph ID of the UVS */
public:
DEFINE_SIZE_STATIC (5);
};
! typedef SortedArrayOf<UVSMapping, HBUINT32> NonDefaultUVS;
struct VariationSelectorRecord
{
! inline glyph_variant_t get_glyph (hb_codepoint_t codepoint,
hb_codepoint_t *glyph,
const void *base) const
{
! int i;
! const DefaultUVS &defaults = base+defaultUVS;
! i = defaults.bsearch (codepoint);
! if (i != -1)
return GLYPH_VARIANT_USE_DEFAULT;
! const NonDefaultUVS &nonDefaults = base+nonDefaultUVS;
! i = nonDefaults.bsearch (codepoint);
! if (i != -1)
{
! *glyph = nonDefaults[i].glyphID;
return GLYPH_VARIANT_FOUND;
}
return GLYPH_VARIANT_NOT_FOUND;
}
! inline int cmp (const hb_codepoint_t &variation_selector) const
{
return varSelector.cmp (variation_selector);
}
! inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
defaultUVS.sanitize (c, base) &&
nonDefaultUVS.sanitize (c, base));
--- 650,701 ----
GlyphID glyphID; /* Glyph ID of the UVS */
public:
DEFINE_SIZE_STATIC (5);
};
! struct NonDefaultUVS : SortedArrayOf<UVSMapping, HBUINT32>
! {
! void collect_unicodes (hb_set_t *out) const
! {
! unsigned int count = len;
! for (unsigned int i = 0; i < count; i++)
! out->add (arrayZ[i].glyphID);
! }
!
! public:
! DEFINE_SIZE_ARRAY (4, *this);
! };
struct VariationSelectorRecord
{
! glyph_variant_t get_glyph (hb_codepoint_t codepoint,
hb_codepoint_t *glyph,
const void *base) const
{
! if ((base+defaultUVS).bfind (codepoint))
return GLYPH_VARIANT_USE_DEFAULT;
! const UVSMapping &nonDefault = (base+nonDefaultUVS).bsearch (codepoint);
! if (nonDefault.glyphID)
{
! *glyph = nonDefault.glyphID;
return GLYPH_VARIANT_FOUND;
}
return GLYPH_VARIANT_NOT_FOUND;
}
! void collect_unicodes (hb_set_t *out, const void *base) const
! {
! (base+defaultUVS).collect_unicodes (out);
! (base+nonDefaultUVS).collect_unicodes (out);
! }
!
! int cmp (const hb_codepoint_t &variation_selector) const
{
return varSelector.cmp (variation_selector);
}
! bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
defaultUVS.sanitize (c, base) &&
nonDefaultUVS.sanitize (c, base));
*** 641,658 ****
DEFINE_SIZE_STATIC (11);
};
struct CmapSubtableFormat14
{
! inline glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint,
hb_codepoint_t variation_selector,
hb_codepoint_t *glyph) const
{
! return record[record.bsearch(variation_selector)].get_glyph (codepoint, glyph, this);
}
! inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
record.sanitize (c, this));
}
--- 710,739 ----
DEFINE_SIZE_STATIC (11);
};
struct CmapSubtableFormat14
{
! glyph_variant_t get_glyph_variant (hb_codepoint_t codepoint,
hb_codepoint_t variation_selector,
hb_codepoint_t *glyph) const
{
! return record.bsearch (variation_selector).get_glyph (codepoint, glyph, this);
}
! void collect_variation_selectors (hb_set_t *out) const
! {
! unsigned int count = record.len;
! for (unsigned int i = 0; i < count; i++)
! out->add (record.arrayZ[i].varSelector);
! }
! void collect_variation_unicodes (hb_codepoint_t variation_selector,
! hb_set_t *out) const
! {
! record.bsearch (variation_selector).collect_unicodes (out, this);
! }
!
! bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
record.sanitize (c, this));
}
*** 669,679 ****
struct CmapSubtable
{
/* Note: We intentionally do NOT implement subtable formats 2 and 8. */
! inline bool get_glyph (hb_codepoint_t codepoint,
hb_codepoint_t *glyph) const
{
switch (u.format) {
case 0: return u.format0 .get_glyph (codepoint, glyph);
case 4: return u.format4 .get_glyph (codepoint, glyph);
--- 750,760 ----
struct CmapSubtable
{
/* Note: We intentionally do NOT implement subtable formats 2 and 8. */
! bool get_glyph (hb_codepoint_t codepoint,
hb_codepoint_t *glyph) const
{
switch (u.format) {
case 0: return u.format0 .get_glyph (codepoint, glyph);
case 4: return u.format4 .get_glyph (codepoint, glyph);
*** 683,694 ****
case 13: return u.format13.get_glyph (codepoint, glyph);
case 14:
default: return false;
}
}
! inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return_trace (false);
switch (u.format) {
case 0: return_trace (u.format0 .sanitize (c));
--- 764,788 ----
case 13: return u.format13.get_glyph (codepoint, glyph);
case 14:
default: return false;
}
}
+ void collect_unicodes (hb_set_t *out) const
+ {
+ switch (u.format) {
+ case 0: u.format0 .collect_unicodes (out); return;
+ case 4: u.format4 .collect_unicodes (out); return;
+ case 6: u.format6 .collect_unicodes (out); return;
+ case 10: u.format10.collect_unicodes (out); return;
+ case 12: u.format12.collect_unicodes (out); return;
+ case 13: u.format13.collect_unicodes (out); return;
+ case 14:
+ default: return;
+ }
+ }
! bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (!u.format.sanitize (c)) return_trace (false);
switch (u.format) {
case 0: return_trace (u.format0 .sanitize (c));
*** 718,738 ****
};
struct EncodingRecord
{
! inline int cmp (const EncodingRecord &other) const
{
int ret;
ret = platformID.cmp (other.platformID);
if (ret) return ret;
ret = encodingID.cmp (other.encodingID);
if (ret) return ret;
return 0;
}
! inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
subtable.sanitize (c, base));
}
--- 812,832 ----
};
struct EncodingRecord
{
! int cmp (const EncodingRecord &other) const
{
int ret;
ret = platformID.cmp (other.platformID);
if (ret) return ret;
ret = encodingID.cmp (other.encodingID);
if (ret) return ret;
return 0;
}
! bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
subtable.sanitize (c, base));
}
*** 745,849 ****
DEFINE_SIZE_STATIC (8);
};
struct cmap
{
! static const hb_tag_t tableTag = HB_OT_TAG_cmap;
! struct subset_plan {
! subset_plan(void)
{
! format4_segments.init();
! format12_groups.init();
! }
!
! ~subset_plan(void)
! {
! format4_segments.fini();
! format12_groups.fini();
! }
!
! inline size_t final_size() const
{
return 4 // header
+ 8 * 3 // 3 EncodingRecord
+ CmapSubtableFormat4::get_sub_table_size (this->format4_segments)
+ CmapSubtableFormat12::get_sub_table_size (this->format12_groups);
}
- // Format 4
hb_vector_t<CmapSubtableFormat4::segment_plan> format4_segments;
- // Format 12
hb_vector_t<CmapSubtableLongGroup> format12_groups;
};
! inline bool sanitize (hb_sanitize_context_t *c) const
! {
! TRACE_SANITIZE (this);
! return_trace (c->check_struct (this) &&
! likely (version == 0) &&
! encodingRecord.sanitize (c, this));
! }
!
! inline bool _create_plan (const hb_subset_plan_t *plan,
subset_plan *cmap_plan) const
{
! if (unlikely( !CmapSubtableFormat4::create_sub_table_plan (plan, &cmap_plan->format4_segments)))
return false;
return CmapSubtableFormat12::create_sub_table_plan (plan, &cmap_plan->format12_groups);
}
! inline bool _subset (const hb_subset_plan_t *plan,
const subset_plan &cmap_subset_plan,
size_t dest_sz,
void *dest) const
{
hb_serialize_context_t c (dest, dest_sz);
! OT::cmap *cmap = c.start_serialize<OT::cmap> ();
! if (unlikely (!c.extend_min (*cmap)))
{
return false;
}
! cmap->version.set (0);
! if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 3)))
return false;
// TODO(grieger): Convert the below to a for loop
// Format 4, Plat 0 Encoding Record
! EncodingRecord &format4_plat0_rec = cmap->encodingRecord[0];
format4_plat0_rec.platformID.set (0); // Unicode
format4_plat0_rec.encodingID.set (3);
// Format 4, Plat 3 Encoding Record
! EncodingRecord &format4_plat3_rec = cmap->encodingRecord[1];
format4_plat3_rec.platformID.set (3); // Windows
format4_plat3_rec.encodingID.set (1); // Unicode BMP
// Format 12 Encoding Record
! EncodingRecord &format12_rec = cmap->encodingRecord[2];
format12_rec.platformID.set (3); // Windows
format12_rec.encodingID.set (10); // Unicode UCS-4
// Write out format 4 sub table
{
! CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, cmap);
format4_plat3_rec.subtable.set (format4_plat0_rec.subtable);
subtable.u.format.set (4);
CmapSubtableFormat4 &format4 = subtable.u.format4;
if (unlikely (!format4.serialize (&c, plan, cmap_subset_plan.format4_segments)))
return false;
}
// Write out format 12 sub table.
{
! CmapSubtable &subtable = format12_rec.subtable.serialize (&c, cmap);
subtable.u.format.set (12);
CmapSubtableFormat12 &format12 = subtable.u.format12;
if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups)))
return false;
--- 839,922 ----
DEFINE_SIZE_STATIC (8);
};
struct cmap
{
! static constexpr hb_tag_t tableTag = HB_OT_TAG_cmap;
! struct subset_plan
{
! size_t final_size () const
{
return 4 // header
+ 8 * 3 // 3 EncodingRecord
+ CmapSubtableFormat4::get_sub_table_size (this->format4_segments)
+ CmapSubtableFormat12::get_sub_table_size (this->format12_groups);
}
hb_vector_t<CmapSubtableFormat4::segment_plan> format4_segments;
hb_vector_t<CmapSubtableLongGroup> format12_groups;
};
! bool _create_plan (const hb_subset_plan_t *plan,
subset_plan *cmap_plan) const
{
! if (unlikely (!CmapSubtableFormat4::create_sub_table_plan (plan, &cmap_plan->format4_segments)))
return false;
return CmapSubtableFormat12::create_sub_table_plan (plan, &cmap_plan->format12_groups);
}
! bool _subset (const hb_subset_plan_t *plan,
const subset_plan &cmap_subset_plan,
size_t dest_sz,
void *dest) const
{
hb_serialize_context_t c (dest, dest_sz);
! cmap *table = c.start_serialize<cmap> ();
! if (unlikely (!c.extend_min (*table)))
{
return false;
}
! table->version.set (0);
! if (unlikely (!table->encodingRecord.serialize (&c, /* numTables */ 3)))
return false;
// TODO(grieger): Convert the below to a for loop
// Format 4, Plat 0 Encoding Record
! EncodingRecord &format4_plat0_rec = table->encodingRecord[0];
format4_plat0_rec.platformID.set (0); // Unicode
format4_plat0_rec.encodingID.set (3);
// Format 4, Plat 3 Encoding Record
! EncodingRecord &format4_plat3_rec = table->encodingRecord[1];
format4_plat3_rec.platformID.set (3); // Windows
format4_plat3_rec.encodingID.set (1); // Unicode BMP
// Format 12 Encoding Record
! EncodingRecord &format12_rec = table->encodingRecord[2];
format12_rec.platformID.set (3); // Windows
format12_rec.encodingID.set (10); // Unicode UCS-4
// Write out format 4 sub table
{
! CmapSubtable &subtable = format4_plat0_rec.subtable.serialize (&c, table);
format4_plat3_rec.subtable.set (format4_plat0_rec.subtable);
subtable.u.format.set (4);
CmapSubtableFormat4 &format4 = subtable.u.format4;
if (unlikely (!format4.serialize (&c, plan, cmap_subset_plan.format4_segments)))
return false;
}
// Write out format 12 sub table.
{
! CmapSubtable &subtable = format12_rec.subtable.serialize (&c, table);
subtable.u.format.set (12);
CmapSubtableFormat12 &format12 = subtable.u.format12;
if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups)))
return false;
*** 852,873 ****
c.end_serialize ();
return true;
}
! inline bool subset (hb_subset_plan_t *plan) const
{
subset_plan cmap_subset_plan;
if (unlikely (!_create_plan (plan, &cmap_subset_plan)))
{
DEBUG_MSG(SUBSET, nullptr, "Failed to generate a cmap subsetting plan.");
return false;
}
// We now know how big our blob needs to be
! size_t dest_sz = cmap_subset_plan.final_size();
void *dest = malloc (dest_sz);
if (unlikely (!dest)) {
DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for cmap subset output", (unsigned long) dest_sz);
return false;
}
--- 925,946 ----
c.end_serialize ();
return true;
}
! bool subset (hb_subset_plan_t *plan) const
{
subset_plan cmap_subset_plan;
if (unlikely (!_create_plan (plan, &cmap_subset_plan)))
{
DEBUG_MSG(SUBSET, nullptr, "Failed to generate a cmap subsetting plan.");
return false;
}
// We now know how big our blob needs to be
! size_t dest_sz = cmap_subset_plan.final_size ();
void *dest = malloc (dest_sz);
if (unlikely (!dest)) {
DEBUG_MSG(SUBSET, nullptr, "Unable to alloc %lu for cmap subset output", (unsigned long) dest_sz);
return false;
}
*** 878,1028 ****
free (dest);
return false;
}
// all done, write the blob into dest
! hb_blob_t *cmap_prime = hb_blob_create ((const char *)dest,
dest_sz,
HB_MEMORY_MODE_READONLY,
dest,
free);
bool result = plan->add_table (HB_OT_TAG_cmap, cmap_prime);
hb_blob_destroy (cmap_prime);
return result;
}
! struct accelerator_t
{
! inline void init (hb_face_t *face)
! {
! this->blob = OT::Sanitizer<OT::cmap>().sanitize (face->reference_table (HB_OT_TAG_cmap));
! const OT::cmap *cmap = this->blob->as<OT::cmap> ();
! const OT::CmapSubtable *subtable = nullptr;
! const OT::CmapSubtableFormat14 *subtable_uvs = nullptr;
- bool symbol = false;
/* 32-bit subtables. */
! if (!subtable) subtable = cmap->find_subtable (3, 10);
! if (!subtable) subtable = cmap->find_subtable (0, 6);
! if (!subtable) subtable = cmap->find_subtable (0, 4);
/* 16-bit subtables. */
! if (!subtable) subtable = cmap->find_subtable (3, 1);
! if (!subtable) subtable = cmap->find_subtable (0, 3);
! if (!subtable) subtable = cmap->find_subtable (0, 2);
! if (!subtable) subtable = cmap->find_subtable (0, 1);
! if (!subtable) subtable = cmap->find_subtable (0, 0);
! if (!subtable)
{
! subtable = cmap->find_subtable (3, 0);
! if (subtable) symbol = true;
}
/* Meh. */
! if (!subtable) subtable = &Null(OT::CmapSubtable);
! /* UVS subtable. */
! if (!subtable_uvs)
{
! const OT::CmapSubtable *st = cmap->find_subtable (0, 5);
if (st && st->u.format == 14)
subtable_uvs = &st->u.format14;
}
- /* Meh. */
- if (!subtable_uvs) subtable_uvs = &Null(OT::CmapSubtableFormat14);
-
- this->uvs_table = subtable_uvs;
this->get_glyph_data = subtable;
if (unlikely (symbol))
{
! this->get_glyph_func = get_glyph_from_symbol<OT::CmapSubtable>;
! this->get_all_codepoints_func = null_get_all_codepoints_func;
} else {
switch (subtable->u.format) {
/* Accelerate format 4 and format 12. */
default:
! this->get_glyph_func = get_glyph_from<OT::CmapSubtable>;
! this->get_all_codepoints_func = null_get_all_codepoints_func;
break;
case 12:
! this->get_glyph_func = get_glyph_from<OT::CmapSubtableFormat12>;
! this->get_all_codepoints_func = get_all_codepoints_from<OT::CmapSubtableFormat12>;
break;
case 4:
{
this->format4_accel.init (&subtable->u.format4);
this->get_glyph_data = &this->format4_accel;
! this->get_glyph_func = this->format4_accel.get_glyph_func;
! this->get_all_codepoints_func = this->format4_accel.get_all_codepoints_func;
}
break;
}
}
}
! inline void fini (void)
{
! hb_blob_destroy (this->blob);
}
! inline bool get_nominal_glyph (hb_codepoint_t unicode,
! hb_codepoint_t *glyph) const
{
! return this->get_glyph_func (this->get_glyph_data, unicode, glyph);
}
! inline bool get_variation_glyph (hb_codepoint_t unicode,
hb_codepoint_t variation_selector,
hb_codepoint_t *glyph) const
{
! switch (this->uvs_table->get_glyph_variant (unicode,
variation_selector,
glyph))
{
! case OT::GLYPH_VARIANT_NOT_FOUND: return false;
! case OT::GLYPH_VARIANT_FOUND: return true;
! case OT::GLYPH_VARIANT_USE_DEFAULT: break;
}
return get_nominal_glyph (unicode, glyph);
}
! inline void get_all_codepoints (hb_set_t *out) const
{
! this->get_all_codepoints_func (get_glyph_data, out);
}
protected:
typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj,
hb_codepoint_t codepoint,
hb_codepoint_t *glyph);
- typedef void (*hb_cmap_get_all_codepoints_func_t) (const void *obj,
- hb_set_t *out);
-
- static inline void null_get_all_codepoints_func (const void *obj, hb_set_t *out)
- {
- // NOOP
- }
template <typename Type>
! static inline bool get_glyph_from (const void *obj,
hb_codepoint_t codepoint,
hb_codepoint_t *glyph)
{
const Type *typed_obj = (const Type *) obj;
return typed_obj->get_glyph (codepoint, glyph);
}
template <typename Type>
! static inline void get_all_codepoints_from (const void *obj,
! hb_set_t *out)
! {
! const Type *typed_obj = (const Type *) obj;
! typed_obj->get_all_codepoints (out);
! }
!
! template <typename Type>
! static inline bool get_glyph_from_symbol (const void *obj,
hb_codepoint_t codepoint,
hb_codepoint_t *glyph)
{
const Type *typed_obj = (const Type *) obj;
if (likely (typed_obj->get_glyph (codepoint, glyph)))
--- 951,1113 ----
free (dest);
return false;
}
// all done, write the blob into dest
! hb_blob_t *cmap_prime = hb_blob_create ((const char *) dest,
dest_sz,
HB_MEMORY_MODE_READONLY,
dest,
free);
bool result = plan->add_table (HB_OT_TAG_cmap, cmap_prime);
hb_blob_destroy (cmap_prime);
return result;
}
! const CmapSubtable *find_best_subtable (bool *symbol = nullptr) const
{
! if (symbol) *symbol = false;
!
! const CmapSubtable *subtable;
/* 32-bit subtables. */
! if ((subtable = this->find_subtable (3, 10))) return subtable;
! if ((subtable = this->find_subtable (0, 6))) return subtable;
! if ((subtable = this->find_subtable (0, 4))) return subtable;
!
/* 16-bit subtables. */
! if ((subtable = this->find_subtable (3, 1))) return subtable;
! if ((subtable = this->find_subtable (0, 3))) return subtable;
! if ((subtable = this->find_subtable (0, 2))) return subtable;
! if ((subtable = this->find_subtable (0, 1))) return subtable;
! if ((subtable = this->find_subtable (0, 0))) return subtable;
!
! /* Symbol subtable. */
! if ((subtable = this->find_subtable (3, 0)))
{
! if (symbol) *symbol = true;
! return subtable;
}
+
/* Meh. */
! return &Null (CmapSubtable);
! }
! struct accelerator_t
! {
! void init (hb_face_t *face)
! {
! this->table = hb_sanitize_context_t ().reference_table<cmap> (face);
! bool symbol;
! this->subtable = table->find_best_subtable (&symbol);
! this->subtable_uvs = &Null (CmapSubtableFormat14);
{
! const CmapSubtable *st = table->find_subtable (0, 5);
if (st && st->u.format == 14)
subtable_uvs = &st->u.format14;
}
this->get_glyph_data = subtable;
if (unlikely (symbol))
{
! this->get_glyph_funcZ = get_glyph_from_symbol<CmapSubtable>;
} else {
switch (subtable->u.format) {
/* Accelerate format 4 and format 12. */
default:
! this->get_glyph_funcZ = get_glyph_from<CmapSubtable>;
break;
case 12:
! this->get_glyph_funcZ = get_glyph_from<CmapSubtableFormat12>;
break;
case 4:
{
this->format4_accel.init (&subtable->u.format4);
this->get_glyph_data = &this->format4_accel;
! this->get_glyph_funcZ = this->format4_accel.get_glyph_func;
}
break;
}
}
}
! void fini () { this->table.destroy (); }
!
! bool get_nominal_glyph (hb_codepoint_t unicode,
! hb_codepoint_t *glyph) const
{
! if (unlikely (!this->get_glyph_funcZ)) return false;
! return this->get_glyph_funcZ (this->get_glyph_data, unicode, glyph);
}
+ unsigned int get_nominal_glyphs (unsigned int count,
+ const hb_codepoint_t *first_unicode,
+ unsigned int unicode_stride,
+ hb_codepoint_t *first_glyph,
+ unsigned int glyph_stride) const
+ {
+ if (unlikely (!this->get_glyph_funcZ)) return 0;
! hb_cmap_get_glyph_func_t get_glyph_funcZ = this->get_glyph_funcZ;
! const void *get_glyph_data = this->get_glyph_data;
!
! unsigned int done;
! for (done = 0;
! done < count && get_glyph_funcZ (get_glyph_data, *first_unicode, first_glyph);
! done++)
{
! first_unicode = &StructAtOffsetUnaligned<hb_codepoint_t> (first_unicode, unicode_stride);
! first_glyph = &StructAtOffsetUnaligned<hb_codepoint_t> (first_glyph, glyph_stride);
! }
! return done;
}
! bool get_variation_glyph (hb_codepoint_t unicode,
hb_codepoint_t variation_selector,
hb_codepoint_t *glyph) const
{
! switch (this->subtable_uvs->get_glyph_variant (unicode,
variation_selector,
glyph))
{
! case GLYPH_VARIANT_NOT_FOUND: return false;
! case GLYPH_VARIANT_FOUND: return true;
! case GLYPH_VARIANT_USE_DEFAULT: break;
}
return get_nominal_glyph (unicode, glyph);
}
! void collect_unicodes (hb_set_t *out) const
! {
! subtable->collect_unicodes (out);
! }
! void collect_variation_selectors (hb_set_t *out) const
{
! subtable_uvs->collect_variation_selectors (out);
! }
! void collect_variation_unicodes (hb_codepoint_t variation_selector,
! hb_set_t *out) const
! {
! subtable_uvs->collect_variation_unicodes (variation_selector, out);
}
protected:
typedef bool (*hb_cmap_get_glyph_func_t) (const void *obj,
hb_codepoint_t codepoint,
hb_codepoint_t *glyph);
template <typename Type>
! static bool get_glyph_from (const void *obj,
hb_codepoint_t codepoint,
hb_codepoint_t *glyph)
{
const Type *typed_obj = (const Type *) obj;
return typed_obj->get_glyph (codepoint, glyph);
}
template <typename Type>
! static bool get_glyph_from_symbol (const void *obj,
hb_codepoint_t codepoint,
hb_codepoint_t *glyph)
{
const Type *typed_obj = (const Type *) obj;
if (likely (typed_obj->get_glyph (codepoint, glyph)))
*** 1040,1086 ****
return false;
}
private:
! hb_cmap_get_glyph_func_t get_glyph_func;
const void *get_glyph_data;
- hb_cmap_get_all_codepoints_func_t get_all_codepoints_func;
! OT::CmapSubtableFormat4::accelerator_t format4_accel;
! const OT::CmapSubtableFormat14 *uvs_table;
! hb_blob_t *blob;
};
protected:
! inline const CmapSubtable *find_subtable (unsigned int platform_id,
unsigned int encoding_id) const
{
EncodingRecord key;
key.platformID.set (platform_id);
key.encodingID.set (encoding_id);
! /* Note: We can use bsearch, but since it has no performance
! * implications, we use lsearch and as such accept fonts with
! * unsorted subtable list. */
! int result = encodingRecord./*bsearch*/lsearch (key);
! if (result == -1 || !encodingRecord[result].subtable)
return nullptr;
! return &(this+encodingRecord[result].subtable);
}
protected:
HBUINT16 version; /* Table version number (0). */
SortedArrayOf<EncodingRecord>
encodingRecord; /* Encoding tables. */
public:
DEFINE_SIZE_ARRAY (4, encodingRecord);
};
} /* namespace OT */
#endif /* HB_OT_CMAP_TABLE_HH */
--- 1125,1180 ----
return false;
}
private:
! hb_nonnull_ptr_t<const CmapSubtable> subtable;
! hb_nonnull_ptr_t<const CmapSubtableFormat14> subtable_uvs;
!
! hb_cmap_get_glyph_func_t get_glyph_funcZ;
const void *get_glyph_data;
! CmapSubtableFormat4::accelerator_t format4_accel;
! hb_blob_ptr_t<cmap> table;
};
protected:
! const CmapSubtable *find_subtable (unsigned int platform_id,
unsigned int encoding_id) const
{
EncodingRecord key;
key.platformID.set (platform_id);
key.encodingID.set (encoding_id);
! const EncodingRecord &result = encodingRecord.bsearch (key);
! if (!result.subtable)
return nullptr;
! return &(this+result.subtable);
! }
!
! public:
!
! bool sanitize (hb_sanitize_context_t *c) const
! {
! TRACE_SANITIZE (this);
! return_trace (c->check_struct (this) &&
! likely (version == 0) &&
! encodingRecord.sanitize (c, this));
}
protected:
HBUINT16 version; /* Table version number (0). */
SortedArrayOf<EncodingRecord>
encodingRecord; /* Encoding tables. */
public:
DEFINE_SIZE_ARRAY (4, encodingRecord);
};
+ struct cmap_accelerator_t : cmap::accelerator_t {};
} /* namespace OT */
#endif /* HB_OT_CMAP_TABLE_HH */
< prev index next >