[HarfBuzz] harfbuzz: Branch 'master' - 6 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Thu Feb 8 03:42:24 UTC 2018
src/Makefile.am | 2 -
src/hb-open-file-private.hh | 50 ++++++++++++++++++++++++++++++++++++++++-
src/hb-open-type-private.hh | 33 ++++++++++++++++++++++-----
src/hb-ot-map-private.hh | 10 ++++----
src/hb-private.hh | 20 ++++++++++------
src/hb-set-private.hh | 12 ++++-----
src/hb-subset.cc | 53 ++++++++++++++++++++++++++++++++++++++------
test/api/test-subset.c | 9 +++++--
8 files changed, 154 insertions(+), 35 deletions(-)
New commits:
commit 931f8b7eb5e740ce81e5be6bfec60dbe3ac7ebc4
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Feb 7 21:42:03 2018 -0600
Fix another thinko
diff --git a/src/hb-open-file-private.hh b/src/hb-open-file-private.hh
index 63172399..c2e1f7de 100644
--- a/src/hb-open-file-private.hh
+++ b/src/hb-open-file-private.hh
@@ -145,7 +145,7 @@ typedef struct OffsetTable
rec.checkSum.set_for_data (hb_blob_get_data (blob, nullptr), rec.length);
rec.offset.serialize (c, this);
void *p = c->allocate_size<void> (rec.length);
- if (unlikely (!p)) return false;
+ if (unlikely (!p)) {return false;}
memcpy (p, hb_blob_get_data (blob, nullptr), rec.length);
if (rec.length % 4)
p = c->allocate_size<void> (4 - rec.length % 4);
diff --git a/src/hb-private.hh b/src/hb-private.hh
index 118f2924..59d732af 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -383,7 +383,7 @@ _hb_unsigned_int_mul_overflows (unsigned int count, unsigned int size)
static inline unsigned int
_hb_ceil_to_4 (unsigned int v)
{
- return ((v - 1) & 3) + 1;
+ return ((v - 1) | 3) + 1;
}
commit 39b86695cf56736170c772424c9a8b75bca0254c
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Feb 7 21:37:03 2018 -0600
[subset] Fix thinko
diff --git a/src/hb-subset.cc b/src/hb-subset.cc
index ed4394da..8c1e43f7 100644
--- a/src/hb-subset.cc
+++ b/src/hb-subset.cc
@@ -221,7 +221,7 @@ hb_subset_face_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob)
hb_subset_face_data_t *data = (hb_subset_face_data_t *) face->user_data;
- hb_subset_face_data_t::table_entry_t *entry = data->tables.lsearch (tag);
+ hb_subset_face_data_t::table_entry_t *entry = data->tables.push ();
if (unlikely (!entry))
return false;
commit eeffabc87572193a9e95f22647e80ae44e5a0089
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Feb 7 21:34:05 2018 -0600
Build
diff --git a/src/Makefile.am b/src/Makefile.am
index 59ca6482..e450ea73 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -14,7 +14,7 @@ DISTCHECK_CONFIGURE_FLAGS = --enable-introspection
#AM_CXXFLAGS =
# Convenience targets:
-lib: $(BUILT_SOURCES) libharfbuzz.la
+lib: $(BUILT_SOURCES) libharfbuzz.la libharfbuzz-subset.la
fuzzing: $(BUILT_SOURCES) libharfbuzz-fuzzing.la
lib_LTLIBRARIES = libharfbuzz.la
commit c479a59988b0cf3e557e22e97e1977962c803fa7
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Feb 7 21:13:10 2018 -0600
[subset] Assemble font
diff --git a/src/hb-open-file-private.hh b/src/hb-open-file-private.hh
index 762783f3..63172399 100644
--- a/src/hb-open-file-private.hh
+++ b/src/hb-open-file-private.hh
@@ -56,6 +56,13 @@ typedef struct TableRecord
int cmp (Tag t) const
{ return t.cmp (tag); }
+ static int cmp (const void *pa, const void *pb)
+ {
+ const TableRecord *a = (const TableRecord *) pa;
+ const TableRecord *b = (const TableRecord *) pb;
+ return b->cmp (a->tag);
+ }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -64,7 +71,7 @@ typedef struct TableRecord
Tag tag; /* 4-byte identifier. */
CheckSum checkSum; /* CheckSum for this table. */
- HBUINT32 offset; /* Offset from beginning of TrueType font
+ Offset32 offset; /* Offset from beginning of TrueType font
* file. */
HBUINT32 length; /* Length of this table. */
public:
@@ -118,6 +125,35 @@ typedef struct OffsetTable
}
public:
+
+ inline bool serialize (hb_serialize_context_t *c,
+ hb_tag_t sfnt_tag,
+ Supplier<hb_tag_t> &tags,
+ Supplier<hb_blob_t *> &blobs,
+ unsigned int table_count)
+ {
+ TRACE_SERIALIZE (this);
+ if (unlikely (!c->extend_min (*this))) return_trace (false);
+ sfnt_version.set (sfnt_tag);
+ if (unlikely (!tables.serialize (c, table_count))) return_trace (false);
+ for (unsigned int i = 0; i < table_count; i++)
+ {
+ TableRecord &rec = tables.array[i];
+ hb_blob_t *blob = blobs[i];
+ rec.tag.set (tags[0]);
+ rec.length.set (hb_blob_get_length (blob));
+ rec.checkSum.set_for_data (hb_blob_get_data (blob, nullptr), rec.length);
+ rec.offset.serialize (c, this);
+ void *p = c->allocate_size<void> (rec.length);
+ if (unlikely (!p)) return false;
+ memcpy (p, hb_blob_get_data (blob, nullptr), rec.length);
+ if (rec.length % 4)
+ p = c->allocate_size<void> (4 - rec.length % 4);
+ }
+ tables.qsort ();
+ return_trace (true);
+ }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -249,6 +285,18 @@ struct OpenTypeFontFile
}
}
+ inline bool serialize_single (hb_serialize_context_t *c,
+ hb_tag_t sfnt_tag,
+ Supplier<hb_tag_t> &tags,
+ Supplier<hb_blob_t *> &blobs,
+ unsigned int table_count)
+ {
+ TRACE_SERIALIZE (this);
+ assert (sfnt_tag != TTCTag);
+ if (unlikely (!c->extend_min (*this))) return_trace (false);
+ return_trace (u.fontFace.serialize (c, sfnt_tag, tags, blobs, table_count));
+ }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh
index 04e4a4e1..be3ecb49 100644
--- a/src/hb-open-type-private.hh
+++ b/src/hb-open-type-private.hh
@@ -499,15 +499,16 @@ struct hb_serialize_context_t
template <typename Type>
struct Supplier
{
- inline Supplier (const Type *array, unsigned int len_)
+ inline Supplier (const Type *array, unsigned int len_, unsigned int stride_=sizeof(Type))
{
head = array;
len = len_;
+ stride = stride_;
}
inline const Type operator [] (unsigned int i) const
{
if (unlikely (i >= len)) return Type ();
- return head[i];
+ return * (const Type *) ((const char *) head + stride * i);
}
inline void advance (unsigned int count)
@@ -515,7 +516,7 @@ struct Supplier
if (unlikely (count > len))
count = len;
len -= count;
- head += count;
+ head = (const Type *) ((const char *) head + stride * count);
}
private:
@@ -523,6 +524,7 @@ struct Supplier
inline Supplier<Type>& operator= (const Supplier<Type> &); /* Disallow copy */
unsigned int len;
+ unsigned int stride;
const Type *head;
};
@@ -717,6 +719,13 @@ struct Offset : Type
inline bool is_null (void) const { return 0 == *this; }
public:
DEFINE_SIZE_STATIC (sizeof(Type));
+
+ inline void *serialize (hb_serialize_context_t *c, const void *base)
+ {
+ void *t = c->start_embed<void> ();
+ this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */
+ return t;
+ }
};
typedef Offset<HBUINT16> Offset16;
@@ -786,9 +795,7 @@ struct OffsetTo : Offset<OffsetType>
inline Type& serialize (hb_serialize_context_t *c, const void *base)
{
- Type *t = c->start_embed<Type> ();
- this->set ((char *) t - (char *) base); /* TODO(serialize) Overflow? */
- return *t;
+ return * (Type *) Offset<OffsetType>::serialize (c, base);
}
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
@@ -928,6 +935,11 @@ struct ArrayOf
return -1;
}
+ inline void qsort (void)
+ {
+ ::qsort (array, len, sizeof (Type), Type::cmp);
+ }
+
private:
inline bool sanitize_shallow (hb_sanitize_context_t *c) const
{
@@ -1072,6 +1084,15 @@ struct BinSearchHeader
return_trace (c->check_struct (this));
}
+ inline void set (unsigned int v)
+ {
+ len.set (v);
+ assert (len == v);
+ entrySelectorZ.set (MAX (1u, _hb_bit_storage (v)) - 1);
+ searchRangeZ.set (16 * (1u << entrySelectorZ));
+ rangeShiftZ.set (16 * MAX (0, (int) v - searchRangeZ));
+ }
+
protected:
HBUINT16 len;
HBUINT16 searchRangeZ;
diff --git a/src/hb-ot-map-private.hh b/src/hb-ot-map-private.hh
index a80ac720..e6bd8ea5 100644
--- a/src/hb-ot-map-private.hh
+++ b/src/hb-ot-map-private.hh
@@ -84,28 +84,28 @@ struct hb_ot_map_t
inline hb_mask_t get_global_mask (void) const { return global_mask; }
inline hb_mask_t get_mask (hb_tag_t feature_tag, unsigned int *shift = nullptr) const {
- const feature_map_t *map = features.bsearch (&feature_tag);
+ const feature_map_t *map = features.bsearch (feature_tag);
if (shift) *shift = map ? map->shift : 0;
return map ? map->mask : 0;
}
inline bool needs_fallback (hb_tag_t feature_tag) const {
- const feature_map_t *map = features.bsearch (&feature_tag);
+ const feature_map_t *map = features.bsearch (feature_tag);
return map ? map->needs_fallback : false;
}
inline hb_mask_t get_1_mask (hb_tag_t feature_tag) const {
- const feature_map_t *map = features.bsearch (&feature_tag);
+ const feature_map_t *map = features.bsearch (feature_tag);
return map ? map->_1_mask : 0;
}
inline unsigned int get_feature_index (unsigned int table_index, hb_tag_t feature_tag) const {
- const feature_map_t *map = features.bsearch (&feature_tag);
+ const feature_map_t *map = features.bsearch (feature_tag);
return map ? map->index[table_index] : HB_OT_LAYOUT_NO_FEATURE_INDEX;
}
inline unsigned int get_feature_stage (unsigned int table_index, hb_tag_t feature_tag) const {
- const feature_map_t *map = features.bsearch (&feature_tag);
+ const feature_map_t *map = features.bsearch (feature_tag);
return map ? map->stage[table_index] : (unsigned int) -1;
}
diff --git a/src/hb-private.hh b/src/hb-private.hh
index 75cc38f7..118f2924 100644
--- a/src/hb-private.hh
+++ b/src/hb-private.hh
@@ -380,6 +380,12 @@ _hb_unsigned_int_mul_overflows (unsigned int count, unsigned int size)
return (size > 0) && (count >= ((unsigned int) -1) / size);
}
+static inline unsigned int
+_hb_ceil_to_4 (unsigned int v)
+{
+ return ((v - 1) & 3) + 1;
+}
+
/* arrays and maps */
@@ -493,34 +499,34 @@ struct hb_prealloced_array_t
}
template <typename T>
- inline Type *lsearch (T *x)
+ inline Type *lsearch (const T &x)
{
for (unsigned int i = 0; i < len; i++)
- if (0 == this->array[i].cmp (x))
+ if (0 == this->array[i].cmp (&x))
return &array[i];
return nullptr;
}
template <typename T>
- inline Type *bsearch (T *x)
+ inline Type *bsearch (const T &x)
{
unsigned int i;
return bfind (x, &i) ? &array[i] : nullptr;
}
template <typename T>
- inline const Type *bsearch (T *x) const
+ inline const Type *bsearch (const T &x) const
{
unsigned int i;
return bfind (x, &i) ? &array[i] : nullptr;
}
template <typename T>
- inline bool bfind (T *x, unsigned int *i) const
+ inline bool bfind (const T &x, unsigned int *i) const
{
int min = 0, max = (int) this->len - 1;
while (min <= max)
{
int mid = (min + max) / 2;
- int c = this->array[mid].cmp (x);
+ int c = this->array[mid].cmp (&x);
if (c < 0)
max = mid - 1;
else if (c > 0)
@@ -531,7 +537,7 @@ struct hb_prealloced_array_t
return true;
}
}
- if (max < 0 || (max < (int) this->len && this->array[max].cmp (x) > 0))
+ if (max < 0 || (max < (int) this->len && this->array[max].cmp (&x) > 0))
max++;
*i = max;
return false;
diff --git a/src/hb-set-private.hh b/src/hb-set-private.hh
index 54dd610e..d71d4122 100644
--- a/src/hb-set-private.hh
+++ b/src/hb-set-private.hh
@@ -470,7 +470,7 @@ struct hb_set_t
page_map_t map = {get_major (*codepoint), 0};
unsigned int i;
- page_map.bfind (&map, &i);
+ page_map.bfind (map, &i);
if (i < page_map.len)
{
if (pages[page_map[i].index].next (codepoint))
@@ -541,7 +541,7 @@ struct hb_set_t
{
page_map_t map = {get_major (g), pages.len};
unsigned int i;
- if (!page_map.bfind (&map, &i))
+ if (!page_map.bfind (map, &i))
{
if (!resize (pages.len + 1))
return nullptr;
@@ -555,7 +555,7 @@ struct hb_set_t
inline page_t *page_for (hb_codepoint_t g)
{
page_map_t key = {get_major (g)};
- const page_map_t *found = page_map.bsearch (&key);
+ const page_map_t *found = page_map.bsearch (key);
if (found)
return &pages[found->index];
return nullptr;
@@ -563,7 +563,7 @@ struct hb_set_t
inline const page_t *page_for (hb_codepoint_t g) const
{
page_map_t key = {get_major (g)};
- const page_map_t *found = page_map.bsearch (&key);
+ const page_map_t *found = page_map.bsearch (key);
if (found)
return &pages[found->index];
return nullptr;
diff --git a/src/hb-subset.cc b/src/hb-subset.cc
index f9119c37..ed4394da 100644
--- a/src/hb-subset.cc
+++ b/src/hb-subset.cc
@@ -32,6 +32,7 @@
#include "hb-subset-private.hh"
#include "hb-subset-plan.hh"
+#include "hb-open-file-private.hh"
#include "hb-ot-glyf-table.hh"
@@ -142,21 +143,59 @@ _hb_subset_face_data_destroy (void *user_data)
{
hb_subset_face_data_t *data = (hb_subset_face_data_t *) user_data;
+ data->tables.finish ();
+
free (data);
}
static hb_blob_t *
-_hb_subset_face_reference_table (hb_face_t *face, hb_tag_t tag, void *user_data)
+_hb_subset_face_data_reference_blob (hb_subset_face_data_t *data)
{
- hb_subset_face_data_t *data = (hb_subset_face_data_t *) user_data;
- if (!tag)
+ unsigned int table_count = data->tables.len;
+ unsigned int face_length = table_count * 16 + 12;
+
+ for (unsigned int i = 0; i < table_count; i++)
+ face_length += _hb_ceil_to_4 (hb_blob_get_length (data->tables.array[i].blob));
+
+ char *buf = (char *) malloc (face_length);
+ if (unlikely (!buf))
+ return nullptr;
+
+ OT::hb_serialize_context_t c (buf, face_length);
+ OT::OpenTypeFontFile *f = c.start_serialize<OT::OpenTypeFontFile> ();
+
+ bool is_cff = data->tables.lsearch (HB_TAG ('C','F','F',' ')) || data->tables.lsearch (HB_TAG ('C','F','F','2'));
+ hb_tag_t sfnt_tag = is_cff ? OT::OpenTypeFontFile::CFFTag : OT::OpenTypeFontFile::TrueTypeTag;
+
+ OT::Supplier<hb_tag_t> tags_supplier (&data->tables[0].tag, table_count, sizeof (data->tables[0]));
+ OT::Supplier<hb_blob_t *> blobs_supplier (&data->tables[0].blob, table_count, sizeof (data->tables[0]));
+ bool ret = f->serialize_single (&c,
+ sfnt_tag,
+ tags_supplier,
+ blobs_supplier,
+ table_count);
+
+ c.end_serialize ();
+
+ if (unlikely (!ret))
{
- /* TODO Compile face blob... */
+ free (buf);
return nullptr;
}
- hb_subset_face_data_t::table_entry_t *entry = data->tables.lsearch (&tag);
+ return hb_blob_create (buf, face_length, HB_MEMORY_MODE_WRITABLE, buf, free);
+}
+
+static hb_blob_t *
+_hb_subset_face_reference_table (hb_face_t *face, hb_tag_t tag, void *user_data)
+{
+ hb_subset_face_data_t *data = (hb_subset_face_data_t *) user_data;
+
+ if (!tag)
+ return _hb_subset_face_data_reference_blob (data);
+
+ hb_subset_face_data_t::table_entry_t *entry = data->tables.lsearch (tag);
if (entry)
return hb_blob_reference (entry->blob);
@@ -182,7 +221,7 @@ hb_subset_face_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob)
hb_subset_face_data_t *data = (hb_subset_face_data_t *) face->user_data;
- hb_subset_face_data_t::table_entry_t *entry = data->tables.lsearch (&tag);
+ hb_subset_face_data_t::table_entry_t *entry = data->tables.lsearch (tag);
if (unlikely (!entry))
return false;
diff --git a/test/api/test-subset.c b/test/api/test-subset.c
index db4bbe92..866a8333 100644
--- a/test/api/test-subset.c
+++ b/test/api/test-subset.c
@@ -32,7 +32,12 @@
/* Unit tests for hb-subset.h */
-static const char test_data[] = { 0, 0, 1, 0 };
+static const char test_data[] = { 0, 1, 0, 0, /* sfntVersion */
+ 0, 0, /* numTables */
+ 0, 0x10, /* searchRange */
+ 0, 0, /* entrySelector */
+ 0, 0, /* rangeShift */
+ };
static void
test_subset (void)
@@ -51,7 +56,7 @@ test_subset (void)
unsigned int output_length;
const char *output_data = hb_blob_get_data(output, &output_length);
- g_assert_cmpmem(test_data, 4, output_data, output_length);
+ g_assert_cmpmem (test_data, sizeof (test_data), output_data, output_length);
hb_blob_destroy(output);
hb_subset_input_destroy(input);
commit 34ac3548b7c9dbc57f277cf9a7a337cd1a8a04bb
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Feb 7 18:07:45 2018 -0600
[set] Respect stride
Ouch!
diff --git a/src/hb-set-private.hh b/src/hb-set-private.hh
index 576c169e..54dd610e 100644
--- a/src/hb-set-private.hh
+++ b/src/hb-set-private.hh
@@ -273,7 +273,7 @@ struct hb_set_t
{
page->add (g);
- array++;
+ array = (const T *) ((const char *) array + stride);
count--;
}
while (count && (g = *array, start <= g && g < end));
@@ -302,7 +302,7 @@ struct hb_set_t
last_g = g;
page->add (g);
- array++;
+ array = (const T *) ((const char *) array + stride);
count--;
}
while (count && (g = *array, g < end));
commit 577becaf7b5ccd9de8ba533447f944427b9e4452
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Wed Feb 7 17:38:40 2018 -0600
[subset] Fixup
diff --git a/src/hb-subset.cc b/src/hb-subset.cc
index 61f38a0a..f9119c37 100644
--- a/src/hb-subset.cc
+++ b/src/hb-subset.cc
@@ -216,7 +216,7 @@ hb_subset (hb_face_t *source,
hb_tag_t table_tags[32];
unsigned int offset = 0, count;
do {
- count == ARRAY_LENGTH (table_tags);
+ count = ARRAY_LENGTH (table_tags);
hb_face_get_table_tags (source, offset, &count, table_tags);
for (unsigned int i = 0; i < count; i++)
{
More information about the HarfBuzz
mailing list