summaryrefslogtreecommitdiff
path: root/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh
diff options
context:
space:
mode:
Diffstat (limited to 'Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh')
-rw-r--r--Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh55
1 files changed, 38 insertions, 17 deletions
diff --git a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh
index f08fe39d8be..d406e3e21cd 100644
--- a/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh
+++ b/Build/source/libs/harfbuzz/harfbuzz-src/src/hb-ot-hdmx-table.hh
@@ -28,40 +28,51 @@
#define HB_OT_HDMX_TABLE_HH
#include "hb-open-type-private.hh"
-
-namespace OT {
-
+#include "hb-subset-plan.hh"
/*
- * hdmx - Horizontal Device Metric
+ * hdmx -- Horizontal Device Metrics
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/hdmx
*/
-
#define HB_OT_TAG_hdmx HB_TAG('h','d','m','x')
+
+namespace OT {
+
+
struct DeviceRecord
{
struct SubsetView
{
const DeviceRecord *source_device_record;
+ unsigned int size_device_record;
hb_subset_plan_t *subset_plan;
inline void init(const DeviceRecord *source_device_record,
+ unsigned int size_device_record,
hb_subset_plan_t *subset_plan)
{
this->source_device_record = source_device_record;
+ this->size_device_record = size_device_record;
this->subset_plan = subset_plan;
}
inline unsigned int len () const
{
- return this->subset_plan->gids_to_retain_sorted.len;
+ return this->subset_plan->glyphs.len;
}
- inline const HBUINT8& operator [] (unsigned int i) const
+ inline const HBUINT8* operator [] (unsigned int i) const
{
- if (unlikely (i >= len())) return Null(HBUINT8);
- hb_codepoint_t gid = this->subset_plan->gids_to_retain_sorted [i];
- return this->source_device_record->widths[gid];
+ if (unlikely (i >= len())) return nullptr;
+ hb_codepoint_t gid = this->subset_plan->glyphs [i];
+
+ const HBUINT8* width = &(this->source_device_record->widths[gid]);
+
+ if (width < ((const HBUINT8 *) this->source_device_record) + size_device_record)
+ return width;
+ else
+ return nullptr;
}
};
@@ -85,7 +96,15 @@ struct DeviceRecord
this->max_width.set (subset_view.source_device_record->max_width);
for (unsigned int i = 0; i < subset_view.len(); i++)
- widths[i].set (subset_view[i]);
+ {
+ const HBUINT8 *width = subset_view[i];
+ if (!width)
+ {
+ DEBUG_MSG(SUBSET, nullptr, "HDMX width for new gid %d is missing.", i);
+ return_trace (false);
+ }
+ widths[i].set (*width);
+ }
return_trace (true);
}
@@ -117,7 +136,7 @@ struct hdmx
inline const DeviceRecord& operator [] (unsigned int i) const
{
if (unlikely (i >= num_records)) return Null(DeviceRecord);
- return StructAtOffset<DeviceRecord> (this, min_size + i * size_device_record);
+ return StructAtOffset<DeviceRecord> (this->data, i * size_device_record);
}
inline bool serialize (hb_serialize_context_t *c, const hdmx *source_hdmx, hb_subset_plan_t *plan)
@@ -128,14 +147,15 @@ struct hdmx
this->version.set (source_hdmx->version);
this->num_records.set (source_hdmx->num_records);
- this->size_device_record.set (DeviceRecord::get_size (plan->gids_to_retain_sorted.len));
+ this->size_device_record.set (DeviceRecord::get_size (plan->glyphs.len));
for (unsigned int i = 0; i < source_hdmx->num_records; i++)
{
DeviceRecord::SubsetView subset_view;
- subset_view.init (&(*source_hdmx)[i], plan);
+ subset_view.init (&(*source_hdmx)[i], source_hdmx->size_device_record, plan);
- c->start_embed<DeviceRecord> ()->serialize (c, subset_view);
+ if (!c->start_embed<DeviceRecord> ()->serialize (c, subset_view))
+ return_trace (false);
}
return_trace (true);
@@ -143,7 +163,7 @@ struct hdmx
static inline size_t get_subsetted_size (hb_subset_plan_t *plan)
{
- return min_size + DeviceRecord::get_size (plan->gids_to_retain_sorted.len);
+ return min_size + DeviceRecord::get_size (plan->glyphs.len);
}
inline bool subset (hb_subset_plan_t *plan) const
@@ -169,7 +189,7 @@ struct hdmx
HB_MEMORY_MODE_READONLY,
dest,
free);
- bool result = hb_subset_plan_add_table (plan, HB_OT_TAG_hdmx, hdmx_prime_blob);
+ bool result = plan->add_table (HB_OT_TAG_hdmx, hdmx_prime_blob);
hb_blob_destroy (hdmx_prime_blob);
return result;
@@ -180,6 +200,7 @@ struct hdmx
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && version == 0 &&
!_hb_unsigned_int_mul_overflows (num_records, size_device_record) &&
+ size_device_record >= DeviceRecord::min_size &&
c->check_range (this, get_size()));
}