summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2023-06-01 07:53:31 +0200
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@qt.io>2023-06-06 14:09:03 +0000
commitd390ac99f2c2a0f70319df5f6ed3068cc5cbd6fe (patch)
tree1c0251b2ab390410e5ddb47dd3d049d4192cf490 /src
parent79436bd34ddf2dc39d42ed9b80a54f4d581c44d9 (diff)
Upgrade Harfbuzz to 7.3.0
Fixes: QTBUG-114098 Pick-to: 6.2 6.5 6.6 Change-Id: I7bc766e6edada6f964c2dc40f18ff710249fb159 Reviewed-by: Tor Arne Vestbø <tor.arne.vestbo@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/3rdparty/harfbuzz-ng/CMakeLists.txt1
-rw-r--r--src/3rdparty/harfbuzz-ng/NEWS21
-rw-r--r--src/3rdparty/harfbuzz-ng/qt_attribution.json4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh8
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/Coverage.hh23
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat2.hh17
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/RangeRecord.hh12
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh24
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePosFormat1.hh4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/GPOS.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh6
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh27
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairSet.hh4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/Ligature.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh62
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SingleSubst.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/CompositeGlyph.hh36
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh93
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/SimpleGlyph.hh33
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/VarCompositeGlyph.hh244
-rw-r--r--src/3rdparty/harfbuzz-ng/src/OT/glyf/path-builder.hh8
-rw-r--r--src/3rdparty/harfbuzz-ng/src/graph/graph.hh64
-rw-r--r--src/3rdparty/harfbuzz-ng/src/graph/markbasepos-graph.hh5
-rw-r--r--src/3rdparty/harfbuzz-ng/src/graph/serialize.hh4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-aat-layout.cc8
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-algs.hh6
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-array.hh34
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-bit-set.hh7
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer.cc2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-buffer.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-config.hh40
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-map.hh3
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-null.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc32
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh31
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh48
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc22
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.cc2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc15
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic-machine.hh14
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-var-common.hh3
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-var-cvar-table.hh1
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh111
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-set-digest.hh12
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-accelerator.hh2
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc31
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-input.hh1
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-plan-member-list.hh128
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc94
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh90
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset.cc8
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-subset.h3
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-vector.hh4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb-version.h4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/hb.hh4
-rw-r--r--src/3rdparty/harfbuzz-ng/src/main.cc532
-rw-r--r--src/3rdparty/harfbuzz-ng/src/test.cc95
61 files changed, 982 insertions, 1129 deletions
diff --git a/src/3rdparty/harfbuzz-ng/CMakeLists.txt b/src/3rdparty/harfbuzz-ng/CMakeLists.txt
index c761bda388..96e21941b2 100644
--- a/src/3rdparty/harfbuzz-ng/CMakeLists.txt
+++ b/src/3rdparty/harfbuzz-ng/CMakeLists.txt
@@ -58,6 +58,7 @@ qt_internal_add_3rdparty_library(BundledHarfbuzz
src/hb-subset-input.cc
src/hb-subset-instancer-solver.cc
src/hb-subset-plan.cc
+ src/hb-subset-plan-member-list.hh
src/hb-subset-repacker.cc src/hb-subset-repacker.h
src/hb-unicode.cc src/hb-unicode.h src/hb-unicode.hh
src/hb-utf.hh
diff --git a/src/3rdparty/harfbuzz-ng/NEWS b/src/3rdparty/harfbuzz-ng/NEWS
index e53a244f1b..ff35843192 100644
--- a/src/3rdparty/harfbuzz-ng/NEWS
+++ b/src/3rdparty/harfbuzz-ng/NEWS
@@ -1,3 +1,24 @@
+Overview of changes leading to 7.3.0
+Tuesday, May 9, 2023
+====================================
+- Speedup applying glyph variation in VarComposites fonts (over 40% speedup).
+ (Behdad Esfahbod)
+- Speedup instancing some fonts (over 20% speedup in instancing RobotoFlex).
+ (Behdad Esfahbod)
+- Speedup shaping some fonts (over 30% speedup in shaping Roboto).
+ (Behdad Esfahbod)
+- Support subsetting VarComposites and beyond-64k fonts. (Behdad Esfahbod)
+- New configuration macro HB_MINIMIZE_MEMORY_USAGE to favor optimizing memory
+ usage over speed. (Behdad Esfahbod)
+- Supporting setting the mapping between old and new glyph indices during
+ subsetting. (Garret Rieger)
+- Various fixes and improvements.
+ (Behdad Esfahbod, Denis Rochette, Garret Rieger, Han Seung Min, Qunxin Liu)
+
+- New API:
++hb_subset_input_old_to_new_glyph_mapping()
+
+
Overview of changes leading to 7.2.0
Thursday, April 27, 2023
====================================
diff --git a/src/3rdparty/harfbuzz-ng/qt_attribution.json b/src/3rdparty/harfbuzz-ng/qt_attribution.json
index b1ca7db332..f2b53ef7d6 100644
--- a/src/3rdparty/harfbuzz-ng/qt_attribution.json
+++ b/src/3rdparty/harfbuzz-ng/qt_attribution.json
@@ -7,8 +7,8 @@
"Description": "HarfBuzz is an OpenType text shaping engine.",
"Homepage": "http://harfbuzz.org",
- "Version": "7.2.0",
- "DownloadLocation": "https://github.com/harfbuzz/harfbuzz/releases/tag/7.2.0",
+ "Version": "7.3.0",
+ "DownloadLocation": "https://github.com/harfbuzz/harfbuzz/releases/tag/7.3.0",
"License": "MIT License",
"LicenseId": "MIT",
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh b/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh
index 191812f48e..2a47984294 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Color/COLR/COLR.hh
@@ -1514,10 +1514,10 @@ struct ClipBoxFormat2 : Variable<ClipBoxFormat1>
value.get_clip_box(clip_box, instancer);
if (instancer)
{
- clip_box.xMin += _hb_roundf (instancer (varIdxBase, 0));
- clip_box.yMin += _hb_roundf (instancer (varIdxBase, 1));
- clip_box.xMax += _hb_roundf (instancer (varIdxBase, 2));
- clip_box.yMax += _hb_roundf (instancer (varIdxBase, 3));
+ clip_box.xMin += roundf (instancer (varIdxBase, 0));
+ clip_box.yMin += roundf (instancer (varIdxBase, 1));
+ clip_box.xMax += roundf (instancer (varIdxBase, 2));
+ clip_box.yMax += roundf (instancer (varIdxBase, 3));
}
}
};
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/Coverage.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/Coverage.hh
index d35654e245..9ca88f788a 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/Coverage.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/Coverage.hh
@@ -113,22 +113,33 @@ struct Coverage
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (this))) return_trace (false);
- unsigned count = 0;
+ unsigned count = hb_len (glyphs);
unsigned num_ranges = 0;
hb_codepoint_t last = (hb_codepoint_t) -2;
+ hb_codepoint_t max = 0;
+ bool unsorted = false;
for (auto g: glyphs)
{
+ if (last != (hb_codepoint_t) -2 && g < last)
+ unsorted = true;
if (last + 1 != g)
- num_ranges++;
+ num_ranges++;
last = g;
- count++;
+ if (g > max) max = g;
}
- u.format = count <= num_ranges * 3 ? 1 : 2;
+ u.format = !unsorted && count <= num_ranges * 3 ? 1 : 2;
#ifndef HB_NO_BEYOND_64K
- if (count && last > 0xFFFFu)
+ if (max > 0xFFFFu)
u.format += 2;
+ if (unlikely (max > 0xFFFFFFu))
+#else
+ if (unlikely (max > 0xFFFFu))
#endif
+ {
+ c->check_success (false, HB_SERIALIZE_ERROR_INT_OVERFLOW);
+ return_trace (false);
+ }
switch (u.format)
{
@@ -148,8 +159,8 @@ struct Coverage
auto it =
+ iter ()
| hb_take (c->plan->source->get_num_glyphs ())
- | hb_filter (c->plan->glyph_map_gsub)
| hb_map_retains_sorting (c->plan->glyph_map_gsub)
+ | hb_filter ([] (hb_codepoint_t glyph) { return glyph != HB_MAP_VALUE_INVALID; })
;
// Cache the iterator result as it will be iterated multiple times
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat2.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat2.hh
index d7fcc35202..fa501d659d 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat2.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/CoverageFormat2.hh
@@ -95,19 +95,26 @@ struct CoverageFormat2_4
unsigned count = 0;
unsigned range = (unsigned) -1;
last = (hb_codepoint_t) -2;
+ unsigned unsorted = false;
for (auto g: glyphs)
{
if (last + 1 != g)
{
+ if (unlikely (last != (hb_codepoint_t) -2 && last + 1 > g))
+ unsorted = true;
+
range++;
- rangeRecord[range].first = g;
- rangeRecord[range].value = count;
+ rangeRecord.arrayZ[range].first = g;
+ rangeRecord.arrayZ[range].value = count;
}
- rangeRecord[range].last = g;
+ rangeRecord.arrayZ[range].last = g;
last = g;
count++;
}
+ if (unlikely (unsorted))
+ rangeRecord.as_array ().qsort (RangeRecord<Types>::cmp_range);
+
return_trace (true);
}
@@ -185,8 +192,8 @@ struct CoverageFormat2_4
if (__more__ ())
{
unsigned int old = coverage;
- j = c->rangeRecord[i].first;
- coverage = c->rangeRecord[i].value;
+ j = c->rangeRecord.arrayZ[i].first;
+ coverage = c->rangeRecord.arrayZ[i].value;
if (unlikely (coverage != old + 1))
{
/* Broken table. Skip. Important to avoid DoS.
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/RangeRecord.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/RangeRecord.hh
index a62629fad3..85aacace9a 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/RangeRecord.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/Common/RangeRecord.hh
@@ -51,6 +51,18 @@ struct RangeRecord
int cmp (hb_codepoint_t g) const
{ return g < first ? -1 : g <= last ? 0 : +1; }
+ HB_INTERNAL static int cmp_range (const void *pa, const void *pb) {
+ const RangeRecord *a = (const RangeRecord *) pa;
+ const RangeRecord *b = (const RangeRecord *) pb;
+ if (a->first < b->first) return -1;
+ if (a->first > b->first) return +1;
+ if (a->last < b->last) return -1;
+ if (a->last > b->last) return +1;
+ if (a->value < b->value) return -1;
+ if (a->value > b->value) return +1;
+ return 0;
+ }
+
unsigned get_population () const
{
if (unlikely (last < first)) return 0;
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh
index 0551fcf812..c1ff796199 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GDEF/GDEF.hh
@@ -32,6 +32,7 @@
#include "../../../hb-ot-layout-common.hh"
#include "../../../hb-font.hh"
+#include "../../../hb-cache.hh"
namespace OT {
@@ -861,7 +862,30 @@ struct GDEF
}
~accelerator_t () { table.destroy (); }
+ unsigned int get_glyph_props (hb_codepoint_t glyph) const
+ {
+ unsigned v;
+
+#ifndef HB_NO_GDEF_CACHE
+ if (glyph_props_cache.get (glyph, &v))
+ return v;
+#endif
+
+ v = table->get_glyph_props (glyph);
+
+#ifndef HB_NO_GDEF_CACHE
+ if (likely (table.get_blob ())) // Don't try setting if we are the null instance!
+ glyph_props_cache.set (glyph, v);
+#endif
+
+ return v;
+
+ }
+
hb_blob_ptr_t<GDEF> table;
+#ifndef HB_NO_GDEF_CACHE
+ mutable hb_cache_t<21, 3, 8> glyph_props_cache;
+#endif
};
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePosFormat1.hh
index ff255e090a..b8773ba0aa 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePosFormat1.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/CursivePosFormat1.hh
@@ -122,9 +122,9 @@ struct CursivePosFormat1
if (!this_record.entryAnchor) return_trace (false);
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.reset (buffer->idx, 1);
+ skippy_iter.reset_fast (buffer->idx, 1);
unsigned unsafe_from;
- if (!skippy_iter.prev (&unsafe_from))
+ if (unlikely (!skippy_iter.prev (&unsafe_from)))
{
buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
return_trace (false);
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/GPOS.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/GPOS.hh
index 9493ec987e..f4af98b25f 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/GPOS.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/GPOS.hh
@@ -156,7 +156,7 @@ GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
{
for (unsigned i = 0; i < len; i++)
if (unlikely (pos[i].y_offset))
- pos[i].x_offset += _hb_roundf (font->slant_xy * pos[i].y_offset);
+ pos[i].x_offset += roundf (font->slant_xy * pos[i].y_offset);
}
}
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
index fbcebb8044..9dae5ce5da 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
@@ -100,16 +100,16 @@ struct MarkMarkPosFormat1_2
/* now we search backwards for a suitable mark glyph until a non-mark glyph */
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.reset (buffer->idx, 1);
+ skippy_iter.reset_fast (buffer->idx, 1);
skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags);
unsigned unsafe_from;
- if (!skippy_iter.prev (&unsafe_from))
+ if (unlikely (!skippy_iter.prev (&unsafe_from)))
{
buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
return_trace (false);
}
- if (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx]))
+ if (likely (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])))
{
buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
return_trace (false);
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh
index 4dada1c830..714b4bec72 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat1.hh
@@ -110,9 +110,9 @@ struct PairPosFormat1_3
if (likely (index == NOT_COVERED)) return_trace (false);
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.reset (buffer->idx, 1);
+ skippy_iter.reset_fast (buffer->idx, 1);
unsigned unsafe_to;
- if (!skippy_iter.next (&unsafe_to))
+ if (unlikely (!skippy_iter.next (&unsafe_to)))
{
buffer->unsafe_to_concat (buffer->idx, unsafe_to);
return_trace (false);
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh
index de15a29e3c..31329dfcb5 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairPosFormat2.hh
@@ -50,11 +50,10 @@ struct PairPosFormat2_4
unsigned int len1 = valueFormat1.get_len ();
unsigned int len2 = valueFormat2.get_len ();
unsigned int stride = HBUINT16::static_size * (len1 + len2);
- unsigned int record_size = valueFormat1.get_size () + valueFormat2.get_size ();
unsigned int count = (unsigned int) class1Count * (unsigned int) class2Count;
return_trace (c->check_range ((const void *) values,
count,
- record_size) &&
+ stride) &&
valueFormat1.sanitize_values_stride_unsafe (c, this, &values[0], count, stride) &&
valueFormat2.sanitize_values_stride_unsafe (c, this, &values[len1], count, stride));
}
@@ -131,26 +130,32 @@ struct PairPosFormat2_4
if (likely (index == NOT_COVERED)) return_trace (false);
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
- skippy_iter.reset (buffer->idx, 1);
+ skippy_iter.reset_fast (buffer->idx, 1);
unsigned unsafe_to;
- if (!skippy_iter.next (&unsafe_to))
+ if (unlikely (!skippy_iter.next (&unsafe_to)))
{
buffer->unsafe_to_concat (buffer->idx, unsafe_to);
return_trace (false);
}
- unsigned int len1 = valueFormat1.get_len ();
- unsigned int len2 = valueFormat2.get_len ();
- unsigned int record_len = len1 + len2;
+ unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
+ if (!klass2)
+ {
+ buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
+ return_trace (false);
+ }
unsigned int klass1 = (this+classDef1).get_class (buffer->cur().codepoint);
- unsigned int klass2 = (this+classDef2).get_class (buffer->info[skippy_iter.idx].codepoint);
if (unlikely (klass1 >= class1Count || klass2 >= class2Count))
{
buffer->unsafe_to_concat (buffer->idx, skippy_iter.idx + 1);
return_trace (false);
}
+ unsigned int len1 = valueFormat1.get_len ();
+ unsigned int len2 = valueFormat2.get_len ();
+ unsigned int record_len = len1 + len2;
+
const Value *v = &values[record_len * (klass1 * class2Count + klass2)];
bool applied_first = false, applied_second = false;
@@ -164,7 +169,7 @@ struct PairPosFormat2_4
* https://github.com/harfbuzz/harfbuzz/pull/3235#issuecomment-1029814978
*/
#ifndef HB_SPLIT_KERN
- if (0)
+ if (false)
#endif
{
if (!len2)
@@ -224,8 +229,8 @@ struct PairPosFormat2_4
c->buffer->idx, skippy_iter.idx);
}
- applied_first = valueFormat1.apply_value (c, this, v, buffer->cur_pos());
- applied_second = valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
+ applied_first = len1 && valueFormat1.apply_value (c, this, v, buffer->cur_pos());
+ applied_second = len2 && valueFormat2.apply_value (c, this, v + len1, buffer->pos[skippy_iter.idx]);
if (applied_first || applied_second)
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairSet.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairSet.hh
index 147b8e00ea..9faff49909 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairSet.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GPOS/PairSet.hh
@@ -120,8 +120,8 @@ struct PairSet
c->buffer->idx, pos);
}
- bool applied_first = valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
- bool applied_second = valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
+ bool applied_first = len1 && valueFormats[0].apply_value (c, this, &record->values[0], buffer->cur_pos());
+ bool applied_second = len2 && valueFormats[1].apply_value (c, this, &record->values[len1], buffer->pos[pos]);
if (applied_first || applied_second)
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/Ligature.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/Ligature.hh
index 38057cb60c..8674a52fb5 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/Ligature.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/Ligature.hh
@@ -10,7 +10,7 @@ namespace GSUB_impl {
template <typename Types>
struct Ligature
{
- protected:
+ public:
typename Types::HBGlyphID
ligGlyph; /* GlyphID of ligature to substitute */
HeadlessArrayOf<typename Types::HBGlyphID>
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh
index 9db25cf567..0ba262e901 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/LigatureSet.hh
@@ -72,15 +72,73 @@ struct LigatureSet
;
}
+ static bool match_always (hb_glyph_info_t &info HB_UNUSED, unsigned value HB_UNUSED, const void *data HB_UNUSED)
+ {
+ return true;
+ }
+
bool apply (hb_ot_apply_context_t *c) const
{
TRACE_APPLY (this);
+
unsigned int num_ligs = ligature.len;
+
+#ifndef HB_NO_OT_LIGATURES_FAST_PATH
+ if (HB_OPTIMIZE_SIZE_VAL || num_ligs <= 2)
+#endif
+ {
+ slow:
+ for (unsigned int i = 0; i < num_ligs; i++)
+ {
+ const auto &lig = this+ligature.arrayZ[i];
+ if (lig.apply (c)) return_trace (true);
+ }
+ return_trace (false);
+ }
+
+ /* This version is optimized for speed by matching the first component
+ * of the ligature here, instead of calling into the ligation code. */
+
+ hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+ skippy_iter.reset (c->buffer->idx, 1);
+ skippy_iter.set_match_func (match_always, nullptr);
+ skippy_iter.set_glyph_data ((HBUINT16 *) nullptr);
+ unsigned unsafe_to;
+ hb_codepoint_t first = (unsigned) -1;
+ bool matched = skippy_iter.next (&unsafe_to);
+ if (likely (matched))
+ {
+ first = c->buffer->info[skippy_iter.idx].codepoint;
+ unsafe_to = skippy_iter.idx + 1;
+
+ if (skippy_iter.may_skip (c->buffer->info[skippy_iter.idx]))
+ {
+ /* Can't use the fast path if eg. the next char is a default-ignorable
+ * or other skippable. */
+ goto slow;
+ }
+ }
+
+ bool unsafe_to_concat = false;
+
for (unsigned int i = 0; i < num_ligs; i++)
{
- const auto &lig = this+ligature[i];
- if (lig.apply (c)) return_trace (true);
+ const auto &lig = this+ligature.arrayZ[i];
+ if (unlikely (lig.component.lenP1 <= 1) ||
+ lig.component[1] == first)
+ {
+ if (lig.apply (c))
+ {
+ if (unsafe_to_concat)
+ c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
+ return_trace (true);
+ }
+ }
+ else if (likely (lig.component.lenP1 > 1))
+ unsafe_to_concat = true;
}
+ if (likely (unsafe_to_concat))
+ c->buffer->unsafe_to_concat (c->buffer->idx, unsafe_to);
return_trace (false);
}
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SingleSubst.hh b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SingleSubst.hh
index 4529927ba6..181c9e52e5 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SingleSubst.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/Layout/GSUB/SingleSubst.hh
@@ -57,7 +57,7 @@ struct SingleSubst
#ifndef HB_NO_BEYOND_64K
if (+ glyphs
- | hb_map_retains_sorting (hb_first)
+ | hb_map_retains_sorting (hb_second)
| hb_filter ([] (hb_codepoint_t gid) { return gid > 0xFFFFu; }))
{
format += 2;
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/CompositeGlyph.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/CompositeGlyph.hh
index 94e00d3aea..d81fadf7c8 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/CompositeGlyph.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/glyf/CompositeGlyph.hh
@@ -87,19 +87,42 @@ struct CompositeGlyphRecord
}
}
- void transform_points (contour_point_vector_t &points,
+ static void transform (const float (&matrix)[4],
+ hb_array_t<contour_point_t> points)
+ {
+ auto arrayZ = points.arrayZ;
+ unsigned count = points.length;
+
+ if (matrix[0] != 1.f || matrix[1] != 0.f ||
+ matrix[2] != 0.f || matrix[3] != 1.f)
+ for (unsigned i = 0; i < count; i++)
+ arrayZ[i].transform (matrix);
+ }
+
+ static void translate (const contour_point_t &trans,
+ hb_array_t<contour_point_t> points)
+ {
+ auto arrayZ = points.arrayZ;
+ unsigned count = points.length;
+
+ if (trans.x != 0.f || trans.y != 0.f)
+ for (unsigned i = 0; i < count; i++)
+ arrayZ[i].translate (trans);
+ }
+
+ void transform_points (hb_array_t<contour_point_t> points,
const float (&matrix)[4],
const contour_point_t &trans) const
{
if (scaled_offsets ())
{
- points.translate (trans);
- points.transform (matrix);
+ translate (trans, points);
+ transform (matrix, points);
}
else
{
- points.transform (matrix);
- points.translate (trans);
+ transform (matrix, points);
+ translate (trans, points);
}
}
@@ -108,8 +131,9 @@ struct CompositeGlyphRecord
float matrix[4];
contour_point_t trans;
get_transformation (matrix, trans);
+ points.alloc (points.length + 4); // For phantom points
if (unlikely (!points.resize (points.length + 1))) return false;
- points[points.length - 1] = trans;
+ points.arrayZ[points.length - 1] = trans;
return true;
}
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh
index 9e15a6e6d0..2bd5fe8206 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/glyf/Glyph.hh
@@ -155,24 +155,28 @@ struct Glyph
{
xMin = xMax = all_points[0].x;
yMin = yMax = all_points[0].y;
- }
- for (unsigned i = 1; i < all_points.length - 4; i++)
- {
- float x = all_points[i].x;
- float y = all_points[i].y;
- xMin = hb_min (xMin, x);
- xMax = hb_max (xMax, x);
- yMin = hb_min (yMin, y);
- yMax = hb_max (yMax, y);
+ unsigned count = all_points.length - 4;
+ for (unsigned i = 1; i < count; i++)
+ {
+ float x = all_points[i].x;
+ float y = all_points[i].y;
+ xMin = hb_min (xMin, x);
+ xMax = hb_max (xMax, x);
+ yMin = hb_min (yMin, y);
+ yMax = hb_max (yMax, y);
+ }
}
- update_mtx (plan, roundf (xMin), roundf (xMax), roundf (yMin), roundf (yMax), all_points);
-
- int rounded_xMin = roundf (xMin);
- int rounded_xMax = roundf (xMax);
- int rounded_yMin = roundf (yMin);
- int rounded_yMax = roundf (yMax);
+
+ // These are destined for storage in a 16 bit field to clamp the values to
+ // fit into a 16 bit signed integer.
+ int rounded_xMin = hb_clamp (roundf (xMin), -32768.0f, 32767.0f);
+ int rounded_xMax = hb_clamp (roundf (xMax), -32768.0f, 32767.0f);
+ int rounded_yMin = hb_clamp (roundf (yMin), -32768.0f, 32767.0f);
+ int rounded_yMax = hb_clamp (roundf (yMax), -32768.0f, 32767.0f);
+
+ update_mtx (plan, rounded_xMin, rounded_xMax, rounded_yMin, rounded_yMax, all_points);
if (type != EMPTY)
{
@@ -295,7 +299,7 @@ struct Glyph
if (!edge_count) edge_count = &stack_edge_count;
if (unlikely (*edge_count > HB_GLYF_MAX_EDGE_COUNT)) return false;
(*edge_count)++;
-
+
if (head_maxp_info)
{
head_maxp_info->maxComponentDepth = hb_max (head_maxp_info->maxComponentDepth, depth);
@@ -305,9 +309,8 @@ struct Glyph
coords = hb_array (font->coords, font->num_coords);
contour_point_vector_t stack_points;
- bool inplace = type == SIMPLE && all_points.length == 0;
- /* Load into all_points if it's empty, as an optimization. */
- contour_point_vector_t &points = inplace ? all_points : stack_points;
+ contour_point_vector_t &points = type == SIMPLE ? all_points : stack_points;
+ unsigned old_length = points.length;
switch (type) {
case SIMPLE:
@@ -315,7 +318,7 @@ struct Glyph
head_maxp_info->maxContours = hb_max (head_maxp_info->maxContours, (unsigned) header->numberOfContours);
if (depth > 0 && composite_contours)
*composite_contours += (unsigned) header->numberOfContours;
- if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (points, phantom_only)))
+ if (unlikely (!SimpleGlyph (*header, bytes).get_contour_points (all_points, phantom_only)))
return false;
break;
case COMPOSITE:
@@ -329,6 +332,7 @@ struct Glyph
{
for (auto &item : get_var_composite_iterator ())
if (unlikely (!item.get_points (points))) return false;
+ break;
}
#endif
case EMPTY:
@@ -367,7 +371,7 @@ struct Glyph
#ifndef HB_NO_VAR
glyf_accelerator.gvar->apply_deltas_to_points (gid,
coords,
- points.as_array ());
+ points.as_array ().sub_array (old_length));
#endif
// mainly used by CompositeGlyph calculating new X/Y offset value so no need to extend it
@@ -381,21 +385,20 @@ struct Glyph
switch (type) {
case SIMPLE:
if (depth == 0 && head_maxp_info)
- head_maxp_info->maxPoints = hb_max (head_maxp_info->maxPoints, points.length - 4);
- if (!inplace)
- all_points.extend (points.as_array ());
+ head_maxp_info->maxPoints = hb_max (head_maxp_info->maxPoints, all_points.length - old_length - 4);
break;
case COMPOSITE:
{
- contour_point_vector_t comp_points;
unsigned int comp_index = 0;
for (auto &item : get_composite_iterator ())
{
- comp_points.reset ();
- if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
+ unsigned old_count = all_points.length;
+
+ if (unlikely ((!phantom_only || (use_my_metrics && item.is_use_my_metrics ())) &&
+ !glyf_accelerator.glyph_for_gid (item.get_gid ())
.get_points (font,
glyf_accelerator,
- comp_points,
+ all_points,
points_with_deltas,
head_maxp_info,
composite_contours,
@@ -407,6 +410,8 @@ struct Glyph
edge_count)))
return false;
+ auto comp_points = all_points.as_array ().sub_array (old_count);
+
/* Copy phantom points from component if USE_MY_METRICS flag set */
if (use_my_metrics && item.is_use_my_metrics ())
for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
@@ -429,11 +434,11 @@ struct Glyph
delta.init (all_points[p1].x - comp_points[p2].x,
all_points[p1].y - comp_points[p2].y);
- comp_points.translate (delta);
+ item.translate (delta, comp_points);
}
}
- all_points.extend (comp_points.as_array ().sub_array (0, comp_points.length - PHANTOM_COUNT));
+ all_points.resize (all_points.length - PHANTOM_COUNT);
if (all_points.length > HB_GLYF_MAX_POINTS)
return false;
@@ -453,14 +458,12 @@ struct Glyph
#ifndef HB_NO_VAR_COMPOSITES
case VAR_COMPOSITE:
{
- contour_point_vector_t comp_points;
hb_array_t<contour_point_t> points_left = points.as_array ();
for (auto &item : get_var_composite_iterator ())
{
unsigned item_num_points = item.get_num_points ();
hb_array_t<contour_point_t> record_points = points_left.sub_array (0, item_num_points);
-
- comp_points.reset ();
+ assert (record_points.length == item_num_points);
auto component_coords = coords;
if (item.is_reset_unspecified_axes ())
@@ -469,10 +472,13 @@ struct Glyph
coord_setter_t coord_setter (component_coords);
item.set_variations (coord_setter, record_points);
- if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
+ unsigned old_count = all_points.length;
+
+ if (unlikely ((!phantom_only || (use_my_metrics && item.is_use_my_metrics ())) &&
+ !glyf_accelerator.glyph_for_gid (item.get_gid ())
.get_points (font,
glyf_accelerator,
- comp_points,
+ all_points,
points_with_deltas,
head_maxp_info,
nullptr,
@@ -484,15 +490,18 @@ struct Glyph
edge_count)))
return false;
+ auto comp_points = all_points.as_array ().sub_array (old_count);
+
/* Apply component transformation */
- item.transform_points (record_points, comp_points);
+ if (comp_points) // Empty in case of phantom_only
+ item.transform_points (record_points, comp_points);
/* Copy phantom points from component if USE_MY_METRICS flag set */
if (use_my_metrics && item.is_use_my_metrics ())
for (unsigned int i = 0; i < PHANTOM_COUNT; i++)
phantoms[i] = comp_points[comp_points.length - PHANTOM_COUNT + i];
- all_points.extend (comp_points.as_array ().sub_array (0, comp_points.length - PHANTOM_COUNT));
+ all_points.resize (all_points.length - PHANTOM_COUNT);
if (all_points.length > HB_GLYF_MAX_POINTS)
return false;
@@ -512,9 +521,10 @@ struct Glyph
/* Undocumented rasterizer behavior:
* Shift points horizontally by the updated left side bearing
*/
- contour_point_t delta;
- delta.init (-phantoms[PHANTOM_LEFT].x, 0.f);
- if (delta.x) all_points.translate (delta);
+ int v = -phantoms[PHANTOM_LEFT].x;
+ if (v)
+ for (auto &point : all_points)
+ point.x += v;
}
return !all_points.in_error ();
@@ -545,10 +555,11 @@ struct Glyph
int num_contours = header->numberOfContours;
if (unlikely (num_contours == 0)) type = EMPTY;
else if (num_contours > 0) type = SIMPLE;
+ else if (num_contours == -1) type = COMPOSITE;
#ifndef HB_NO_VAR_COMPOSITES
else if (num_contours == -2) type = VAR_COMPOSITE;
#endif
- else type = COMPOSITE; /* negative numbers */
+ else type = EMPTY; // Spec deviation; Spec says COMPOSITE, but not seen in the wild.
}
protected:
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/SimpleGlyph.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/SimpleGlyph.hh
index b6679b2dae..555bcee346 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/SimpleGlyph.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/glyf/SimpleGlyph.hh
@@ -124,7 +124,7 @@ struct SimpleGlyph
}
static bool read_flags (const HBUINT8 *&p /* IN/OUT */,
- contour_point_vector_t &points_ /* IN/OUT */,
+ hb_array_t<contour_point_t> points_ /* IN/OUT */,
const HBUINT8 *end)
{
unsigned count = points_.length;
@@ -146,7 +146,7 @@ struct SimpleGlyph
}
static bool read_points (const HBUINT8 *&p /* IN/OUT */,
- contour_point_vector_t &points_ /* IN/OUT */,
+ hb_array_t<contour_point_t> points_ /* IN/OUT */,
const HBUINT8 *end,
float contour_point_t::*m,
const simple_glyph_flag_t short_flag,
@@ -157,7 +157,7 @@ struct SimpleGlyph
unsigned count = points_.length;
for (unsigned i = 0; i < count; i++)
{
- unsigned flag = points_[i].flag;
+ unsigned flag = points_.arrayZ[i].flag;
if (flag & short_flag)
{
if (unlikely (p + 1 > end)) return false;
@@ -180,18 +180,21 @@ struct SimpleGlyph
return true;
}
- bool get_contour_points (contour_point_vector_t &points_ /* OUT */,
+ bool get_contour_points (contour_point_vector_t &points /* OUT */,
bool phantom_only = false) const
{
const HBUINT16 *endPtsOfContours = &StructAfter<HBUINT16> (header);
int num_contours = header.numberOfContours;
- assert (num_contours);
+ assert (num_contours > 0);
/* One extra item at the end, for the instruction-count below. */
if (unlikely (!bytes.check_range (&endPtsOfContours[num_contours]))) return false;
unsigned int num_points = endPtsOfContours[num_contours - 1] + 1;
- points_.alloc (num_points + 4, true); // Allocate for phantom points, to avoid a possible copy
- if (!points_.resize (num_points)) return false;
+ unsigned old_length = points.length;
+ points.alloc (points.length + num_points + 4, true); // Allocate for phantom points, to avoid a possible copy
+ if (!points.resize (points.length + num_points, false)) return false;
+ auto points_ = points.as_array ().sub_array (old_length);
+ hb_memset (points_.arrayZ, 0, sizeof (contour_point_t) * num_points);
if (phantom_only) return true;
for (int i = 0; i < num_contours; i++)
@@ -214,7 +217,7 @@ struct SimpleGlyph
}
static void encode_coord (int value,
- uint8_t &flag,
+ unsigned &flag,
const simple_glyph_flag_t short_flag,
const simple_glyph_flag_t same_flag,
hb_vector_t<uint8_t> &coords /* OUT */)
@@ -239,9 +242,9 @@ struct SimpleGlyph
}
}
- static void encode_flag (uint8_t &flag,
- uint8_t &repeat,
- uint8_t lastflag,
+ static void encode_flag (unsigned flag,
+ unsigned &repeat,
+ unsigned lastflag,
hb_vector_t<uint8_t> &flags /* OUT */)
{
if (flag == lastflag && repeat != 255)
@@ -262,7 +265,7 @@ struct SimpleGlyph
else
{
repeat = 0;
- flags.push (flag);
+ flags.arrayZ[flags.length++] = flag;
}
}
@@ -282,13 +285,13 @@ struct SimpleGlyph
if (unlikely (!x_coords.alloc (2*num_points, true))) return false;
if (unlikely (!y_coords.alloc (2*num_points, true))) return false;
- uint8_t lastflag = 255, repeat = 0;
+ unsigned lastflag = 255, repeat = 0;
int prev_x = 0, prev_y = 0;
for (unsigned i = 0; i < num_points; i++)
{
- uint8_t flag = all_points.arrayZ[i].flag;
- flag &= FLAG_ON_CURVE + FLAG_OVERLAP_SIMPLE;
+ unsigned flag = all_points.arrayZ[i].flag;
+ flag &= FLAG_ON_CURVE | FLAG_OVERLAP_SIMPLE | FLAG_CUBIC;
int cur_x = roundf (all_points.arrayZ[i].x);
int cur_y = roundf (all_points.arrayZ[i].y);
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/VarCompositeGlyph.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/VarCompositeGlyph.hh
index 309ec473aa..6dc6fd9ded 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/VarCompositeGlyph.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/glyf/VarCompositeGlyph.hh
@@ -36,24 +36,21 @@ struct VarCompositeGlyphRecord
unsigned int get_size () const
{
+ unsigned fl = flags;
unsigned int size = min_size;
- unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 4 : 3;
+ unsigned axis_width = (fl & AXIS_INDICES_ARE_SHORT) ? 4 : 3;
size += numAxes * axis_width;
- // gid
- size += 2;
- if (flags & GID_IS_24BIT) size += 1;
+ if (fl & GID_IS_24BIT) size += 1;
- if (flags & HAVE_TRANSLATE_X) size += 2;
- if (flags & HAVE_TRANSLATE_Y) size += 2;
- if (flags & HAVE_ROTATION) size += 2;
- if (flags & HAVE_SCALE_X) size += 2;
- if (flags & HAVE_SCALE_Y) size += 2;
- if (flags & HAVE_SKEW_X) size += 2;
- if (flags & HAVE_SKEW_Y) size += 2;
- if (flags & HAVE_TCENTER_X) size += 2;
- if (flags & HAVE_TCENTER_Y) size += 2;
+ // 2 bytes each for the following flags
+ fl = fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y |
+ HAVE_ROTATION |
+ HAVE_SCALE_X | HAVE_SCALE_Y |
+ HAVE_SKEW_X | HAVE_SKEW_Y |
+ HAVE_TCENTER_X | HAVE_TCENTER_Y);
+ size += hb_popcount (fl) * 2;
return size;
}
@@ -66,17 +63,17 @@ struct VarCompositeGlyphRecord
hb_codepoint_t get_gid () const
{
if (flags & GID_IS_24BIT)
- return StructAfter<const HBGlyphID24> (numAxes);
+ return * (const HBGlyphID24 *) &pad;
else
- return StructAfter<const HBGlyphID16> (numAxes);
+ return * (const HBGlyphID16 *) &pad;
}
void set_gid (hb_codepoint_t gid)
{
if (flags & GID_IS_24BIT)
- StructAfter<HBGlyphID24> (numAxes) = gid;
+ * (HBGlyphID24 *) &pad = gid;
else
- StructAfter<HBGlyphID16> (numAxes) = gid;
+ * (HBGlyphID16 *) &pad = gid;
}
unsigned get_numAxes () const
@@ -86,26 +83,44 @@ struct VarCompositeGlyphRecord
unsigned get_num_points () const
{
+ unsigned fl = flags;
unsigned num = 0;
- if (flags & AXES_HAVE_VARIATION) num += numAxes;
- if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y)) num++;
- if (flags & HAVE_ROTATION) num++;
- if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y)) num++;
- if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y)) num++;
- if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y)) num++;
+ if (fl & AXES_HAVE_VARIATION) num += numAxes;
+
+ /* Hopefully faster code, relying on the value of the flags. */
+ fl = (((fl & (HAVE_TRANSLATE_Y | HAVE_SCALE_Y | HAVE_SKEW_Y | HAVE_TCENTER_Y)) >> 1) | fl) &
+ (HAVE_TRANSLATE_X | HAVE_ROTATION | HAVE_SCALE_X | HAVE_SKEW_X | HAVE_TCENTER_X);
+ num += hb_popcount (fl);
+ return num;
+
+ /* Slower but more readable code. */
+ if (fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y)) num++;
+ if (fl & HAVE_ROTATION) num++;
+ if (fl & (HAVE_SCALE_X | HAVE_SCALE_Y)) num++;
+ if (fl & (HAVE_SKEW_X | HAVE_SKEW_Y)) num++;
+ if (fl & (HAVE_TCENTER_X | HAVE_TCENTER_Y)) num++;
return num;
}
- void transform_points (hb_array_t<contour_point_t> record_points,
- contour_point_vector_t &points) const
+ void transform_points (hb_array_t<const contour_point_t> record_points,
+ hb_array_t<contour_point_t> points) const
{
float matrix[4];
contour_point_t trans;
- get_transformation_from_points (record_points, matrix, trans);
+ get_transformation_from_points (record_points.arrayZ, matrix, trans);
+
+ auto arrayZ = points.arrayZ;
+ unsigned count = points.length;
- points.transform (matrix);
- points.translate (trans);
+ if (matrix[0] != 1.f || matrix[1] != 0.f ||
+ matrix[2] != 0.f || matrix[3] != 1.f)
+ for (unsigned i = 0; i < count; i++)
+ arrayZ[i].transform (matrix);
+
+ if (trans.x != 0.f || trans.y != 0.f)
+ for (unsigned i = 0; i < count; i++)
+ arrayZ[i].translate (trans);
}
static inline void transform (float (&matrix)[4], contour_point_t &trans,
@@ -136,26 +151,41 @@ struct VarCompositeGlyphRecord
static void translate (float (&matrix)[4], contour_point_t &trans,
float translateX, float translateY)
{
- // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L213
- float other[6] = {1.f, 0.f, 0.f, 1.f, translateX, translateY};
- transform (matrix, trans, other);
+ if (!translateX && !translateY)
+ return;
+
+ trans.x += matrix[0] * translateX + matrix[2] * translateY;
+ trans.y += matrix[1] * translateX + matrix[3] * translateY;
}
static void scale (float (&matrix)[4], contour_point_t &trans,
float scaleX, float scaleY)
{
- // https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L224
- float other[6] = {scaleX, 0.f, 0.f, scaleY, 0.f, 0.f};
- transform (matrix, trans, other);
+ if (scaleX == 1.f && scaleY == 1.f)
+ return;
+
+ matrix[0] *= scaleX;
+ matrix[1] *= scaleX;
+ matrix[2] *= scaleY;
+ matrix[3] *= scaleY;
}
static void rotate (float (&matrix)[4], contour_point_t &trans,
float rotation)
{
+ if (!rotation)
+ return;
+
// https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L240
rotation = rotation * HB_PI;
- float c = cosf (rotation);
- float s = sinf (rotation);
+ float c;
+ float s;
+#ifdef HAVE_SINCOSF
+ sincosf (rotation, &s, &c);
+#else
+ c = cosf (rotation);
+ s = sinf (rotation);
+#endif
float other[6] = {c, s, -s, c, 0.f, 0.f};
transform (matrix, trans, other);
}
@@ -163,101 +193,100 @@ struct VarCompositeGlyphRecord
static void skew (float (&matrix)[4], contour_point_t &trans,
float skewX, float skewY)
{
+ if (!skewX && !skewY)
+ return;
+
// https://github.com/fonttools/fonttools/blob/f66ee05f71c8b57b5f519ee975e95edcd1466e14/Lib/fontTools/misc/transform.py#L255
skewX = skewX * HB_PI;
skewY = skewY * HB_PI;
- float other[6] = {1.f, tanf (skewY), tanf (skewX), 1.f, 0.f, 0.f};
+ float other[6] = {1.f,
+ skewY ? tanf (skewY) : 0.f,
+ skewX ? tanf (skewX) : 0.f,
+ 1.f,
+ 0.f, 0.f};
transform (matrix, trans, other);
}
bool get_points (contour_point_vector_t &points) const
{
- float translateX = 0.f;
- float translateY = 0.f;
- float rotation = 0.f;
- float scaleX = 1.f * (1 << 10);
- float scaleY = 1.f * (1 << 10);
- float skewX = 0.f;
- float skewY = 0.f;
- float tCenterX = 0.f;
- float tCenterY = 0.f;
-
unsigned num_points = get_num_points ();
- if (unlikely (!points.resize (points.length + num_points))) return false;
+ points.alloc (points.length + num_points + 4); // For phantom points
+ if (unlikely (!points.resize (points.length + num_points, false))) return false;
+ contour_point_t *rec_points = points.arrayZ + (points.length - num_points);
+ memset (rec_points, 0, num_points * sizeof (rec_points[0]));
- unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
- unsigned axes_size = numAxes * axis_width;
+ unsigned fl = flags;
- const F2DOT14 *q = (const F2DOT14 *) (axes_size +
- (flags & GID_IS_24BIT ? 3 : 2) +
- &StructAfter<const HBUINT8> (numAxes));
+ unsigned num_axes = numAxes;
+ unsigned axis_width = (fl & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
+ unsigned axes_size = num_axes * axis_width;
- hb_array_t<contour_point_t> rec_points = points.as_array ().sub_array (points.length - num_points);
+ const F2DOT14 *q = (const F2DOT14 *) (axes_size +
+ (fl & GID_IS_24BIT ? 3 : 2) +
+ (const HBUINT8 *) &pad);
- unsigned count = numAxes;
- if (flags & AXES_HAVE_VARIATION)
+ unsigned count = num_axes;
+ if (fl & AXES_HAVE_VARIATION)
{
for (unsigned i = 0; i < count; i++)
- rec_points[i].x = q++->to_int ();
- rec_points += count;
+ rec_points++->x = q++->to_int ();
}
else
q += count;
const HBUINT16 *p = (const HBUINT16 *) q;
- if (flags & HAVE_TRANSLATE_X) translateX = * (const FWORD *) p++;
- if (flags & HAVE_TRANSLATE_Y) translateY = * (const FWORD *) p++;
- if (flags & HAVE_ROTATION) rotation = ((const F4DOT12 *) p++)->to_int ();
- if (flags & HAVE_SCALE_X) scaleX = ((const F6DOT10 *) p++)->to_int ();
- if (flags & HAVE_SCALE_Y) scaleY = ((const F6DOT10 *) p++)->to_int ();
- if (flags & HAVE_SKEW_X) skewX = ((const F4DOT12 *) p++)->to_int ();
- if (flags & HAVE_SKEW_Y) skewY = ((const F4DOT12 *) p++)->to_int ();
- if (flags & HAVE_TCENTER_X) tCenterX = * (const FWORD *) p++;
- if (flags & HAVE_TCENTER_Y) tCenterY = * (const FWORD *) p++;
-
- if ((flags & UNIFORM_SCALE) && !(flags & HAVE_SCALE_Y))
- scaleY = scaleX;
-
- if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))
+ if (fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))
{
- rec_points[0].x = translateX;
- rec_points[0].y = translateY;
+ int translateX = (fl & HAVE_TRANSLATE_X) ? * (const FWORD *) p++ : 0;
+ int translateY = (fl & HAVE_TRANSLATE_Y) ? * (const FWORD *) p++ : 0;
+ rec_points->x = translateX;
+ rec_points->y = translateY;
rec_points++;
}
- if (flags & HAVE_ROTATION)
+ if (fl & HAVE_ROTATION)
{
- rec_points[0].x = rotation;
+ int rotation = (fl & HAVE_ROTATION) ? ((const F4DOT12 *) p++)->to_int () : 0;
+ rec_points->x = rotation;
rec_points++;
}
- if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y))
+ if (fl & (HAVE_SCALE_X | HAVE_SCALE_Y))
{
- rec_points[0].x = scaleX;
- rec_points[0].y = scaleY;
+ int scaleX = (fl & HAVE_SCALE_X) ? ((const F6DOT10 *) p++)->to_int () : 1 << 10;
+ int scaleY = (fl & HAVE_SCALE_Y) ? ((const F6DOT10 *) p++)->to_int () : 1 << 10;
+ if ((fl & UNIFORM_SCALE) && !(fl & HAVE_SCALE_Y))
+ scaleY = scaleX;
+ rec_points->x = scaleX;
+ rec_points->y = scaleY;
rec_points++;
}
- if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y))
+ if (fl & (HAVE_SKEW_X | HAVE_SKEW_Y))
{
- rec_points[0].x = skewX;
- rec_points[0].y = skewY;
+ int skewX = (fl & HAVE_SKEW_X) ? ((const F4DOT12 *) p++)->to_int () : 0;
+ int skewY = (fl & HAVE_SKEW_Y) ? ((const F4DOT12 *) p++)->to_int () : 0;
+ rec_points->x = skewX;
+ rec_points->y = skewY;
rec_points++;
}
- if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
+ if (fl & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
{
- rec_points[0].x = tCenterX;
- rec_points[0].y = tCenterY;
+ int tCenterX = (fl & HAVE_TCENTER_X) ? * (const FWORD *) p++ : 0;
+ int tCenterY = (fl & HAVE_TCENTER_Y) ? * (const FWORD *) p++ : 0;
+ rec_points->x = tCenterX;
+ rec_points->y = tCenterY;
rec_points++;
}
- assert (!rec_points);
return true;
}
- void get_transformation_from_points (hb_array_t<contour_point_t> rec_points,
+ void get_transformation_from_points (const contour_point_t *rec_points,
float (&matrix)[4], contour_point_t &trans) const
{
- if (flags & AXES_HAVE_VARIATION)
+ unsigned fl = flags;
+
+ if (fl & AXES_HAVE_VARIATION)
rec_points += numAxes;
matrix[0] = matrix[3] = 1.f;
@@ -274,36 +303,35 @@ struct VarCompositeGlyphRecord
float tCenterX = 0.f;
float tCenterY = 0.f;
- if (flags & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))
+ if (fl & (HAVE_TRANSLATE_X | HAVE_TRANSLATE_Y))
{
- translateX = rec_points[0].x;
- translateY = rec_points[0].y;
+ translateX = rec_points->x;
+ translateY = rec_points->y;
rec_points++;
}
- if (flags & HAVE_ROTATION)
+ if (fl & HAVE_ROTATION)
{
- rotation = rec_points[0].x / (1 << 12);
+ rotation = rec_points->x / (1 << 12);
rec_points++;
}
- if (flags & (HAVE_SCALE_X | HAVE_SCALE_Y))
+ if (fl & (HAVE_SCALE_X | HAVE_SCALE_Y))
{
- scaleX = rec_points[0].x / (1 << 10);
- scaleY = rec_points[0].y / (1 << 10);
+ scaleX = rec_points->x / (1 << 10);
+ scaleY = rec_points->y / (1 << 10);
rec_points++;
}
- if (flags & (HAVE_SKEW_X | HAVE_SKEW_Y))
+ if (fl & (HAVE_SKEW_X | HAVE_SKEW_Y))
{
- skewX = rec_points[0].x / (1 << 12);
- skewY = rec_points[0].y / (1 << 12);
+ skewX = rec_points->x / (1 << 12);
+ skewY = rec_points->y / (1 << 12);
rec_points++;
}
- if (flags & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
+ if (fl & (HAVE_TCENTER_X | HAVE_TCENTER_Y))
{
- tCenterX = rec_points[0].x;
- tCenterY = rec_points[0].y;
+ tCenterX = rec_points->x;
+ tCenterY = rec_points->y;
rec_points++;
}
- assert (!rec_points);
translate (matrix, trans, translateX + tCenterX, translateY + tCenterY);
rotate (matrix, trans, rotation);
@@ -317,18 +345,19 @@ struct VarCompositeGlyphRecord
{
bool have_variations = flags & AXES_HAVE_VARIATION;
unsigned axis_width = (flags & AXIS_INDICES_ARE_SHORT) ? 2 : 1;
+ unsigned num_axes = numAxes;
const HBUINT8 *p = (const HBUINT8 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24BIT ? 3 : 2));
const HBUINT16 *q = (const HBUINT16 *) (((HBUINT8 *) &numAxes) + numAxes.static_size + (flags & GID_IS_24BIT ? 3 : 2));
- const F2DOT14 *a = (const F2DOT14 *) ((HBUINT8 *) (axis_width == 1 ? (p + numAxes) : (HBUINT8 *) (q + numAxes)));
+ const F2DOT14 *a = (const F2DOT14 *) ((HBUINT8 *) (axis_width == 1 ? (p + num_axes) : (HBUINT8 *) (q + num_axes)));
- unsigned count = numAxes;
+ unsigned count = num_axes;
for (unsigned i = 0; i < count; i++)
{
unsigned axis_index = axis_width == 1 ? (unsigned) *p++ : (unsigned) *q++;
- signed v = have_variations ? rec_points[i].x : a++->to_int ();
+ signed v = have_variations ? rec_points.arrayZ[i].x : a++->to_int ();
v = hb_clamp (v, -(1<<14), (1<<14));
setter[axis_index] = v;
@@ -338,8 +367,9 @@ struct VarCompositeGlyphRecord
protected:
HBUINT16 flags;
HBUINT8 numAxes;
+ HBUINT16 pad;
public:
- DEFINE_SIZE_MIN (3);
+ DEFINE_SIZE_MIN (5);
};
using var_composite_iter_t = composite_iter_tmpl<VarCompositeGlyphRecord>;
diff --git a/src/3rdparty/harfbuzz-ng/src/OT/glyf/path-builder.hh b/src/3rdparty/harfbuzz-ng/src/OT/glyf/path-builder.hh
index 8916241f76..f7f732d336 100644
--- a/src/3rdparty/harfbuzz-ng/src/OT/glyf/path-builder.hh
+++ b/src/3rdparty/harfbuzz-ng/src/OT/glyf/path-builder.hh
@@ -28,12 +28,8 @@ struct path_builder_t
{ return optional_point_t (x + t * (p.x - x), y + t * (p.y - y)); }
} first_oncurve, first_offcurve, first_offcurve2, last_offcurve, last_offcurve2;
- path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_)
- {
- font = font_;
- draw_session = &draw_session_;
- first_oncurve = first_offcurve = first_offcurve2 = last_offcurve = last_offcurve2 = optional_point_t ();
- }
+ path_builder_t (hb_font_t *font_, hb_draw_session_t &draw_session_) :
+ font (font_), draw_session (&draw_session_) {}
/* based on https://github.com/RazrFalcon/ttf-parser/blob/4f32821/src/glyf.rs#L287
See also:
diff --git a/src/3rdparty/harfbuzz-ng/src/graph/graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/graph.hh
index 38ca5db096..294a999918 100644
--- a/src/3rdparty/harfbuzz-ng/src/graph/graph.hh
+++ b/src/3rdparty/harfbuzz-ng/src/graph/graph.hh
@@ -173,9 +173,10 @@ struct graph_t
void remove_parent (unsigned parent_index)
{
- for (unsigned i = 0; i < parents.length; i++)
+ unsigned count = parents.length;
+ for (unsigned i = 0; i < count; i++)
{
- if (parents[i] != parent_index) continue;
+ if (parents.arrayZ[i] != parent_index) continue;
parents.remove_unordered (i);
break;
}
@@ -183,7 +184,8 @@ struct graph_t
void remove_real_link (unsigned child_index, const void* offset)
{
- for (unsigned i = 0; i < obj.real_links.length; i++)
+ unsigned count = obj.real_links.length;
+ for (unsigned i = 0; i < count; i++)
{
auto& link = obj.real_links.arrayZ[i];
if (link.objidx != child_index)
@@ -199,16 +201,18 @@ struct graph_t
void remap_parents (const hb_vector_t<unsigned>& id_map)
{
- for (unsigned i = 0; i < parents.length; i++)
- parents[i] = id_map[parents[i]];
+ unsigned count = parents.length;
+ for (unsigned i = 0; i < count; i++)
+ parents.arrayZ[i] = id_map[parents.arrayZ[i]];
}
void remap_parent (unsigned old_index, unsigned new_index)
{
- for (unsigned i = 0; i < parents.length; i++)
+ unsigned count = parents.length;
+ for (unsigned i = 0; i < count; i++)
{
- if (parents[i] == old_index)
- parents[i] = new_index;
+ if (parents.arrayZ[i] == old_index)
+ parents.arrayZ[i] = new_index;
}
}
@@ -328,11 +332,12 @@ struct graph_t
bool removed_nil = false;
vertices_.alloc (objects.length);
vertices_scratch_.alloc (objects.length);
- for (unsigned i = 0; i < objects.length; i++)
+ unsigned count = objects.length;
+ for (unsigned i = 0; i < count; i++)
{
// If this graph came from a serialization buffer object 0 is the
// nil object. We don't need it for our purposes here so drop it.
- if (i == 0 && !objects[i])
+ if (i == 0 && !objects.arrayZ[i])
{
removed_nil = true;
continue;
@@ -340,9 +345,9 @@ struct graph_t
vertex_t* v = vertices_.push ();
if (check_success (!vertices_.in_error ()))
- v->obj = *objects[i];
+ v->obj = *objects.arrayZ[i];
- check_success (v->link_positions_valid (objects.length, removed_nil));
+ check_success (v->link_positions_valid (count, removed_nil));
if (!removed_nil) continue;
// Fix indices to account for removed nil object.
@@ -579,8 +584,8 @@ struct graph_t
const auto& node = object (node_idx);
if (offset < node.head || offset >= node.tail) return -1;
- unsigned length = node.real_links.length;
- for (unsigned i = 0; i < length; i++)
+ unsigned count = node.real_links.length;
+ for (unsigned i = 0; i < count; i++)
{
// Use direct access for increased performance, this is a hot method.
const auto& link = node.real_links.arrayZ[i];
@@ -1135,8 +1140,9 @@ struct graph_t
size_t total_size_in_bytes () const {
size_t total_size = 0;
- for (unsigned i = 0; i < vertices_.length; i++) {
- size_t size = vertices_[i].obj.tail - vertices_[i].obj.head;
+ unsigned count = vertices_.length;
+ for (unsigned i = 0; i < count; i++) {
+ size_t size = vertices_.arrayZ[i].obj.tail - vertices_.arrayZ[i].obj.head;
total_size += size;
}
return total_size;
@@ -1183,21 +1189,23 @@ struct graph_t
{
if (!parents_invalid) return;
- for (unsigned i = 0; i < vertices_.length; i++)
- vertices_[i].parents.reset ();
+ unsigned count = vertices_.length;
+
+ for (unsigned i = 0; i < count; i++)
+ vertices_.arrayZ[i].parents.reset ();
- for (unsigned p = 0; p < vertices_.length; p++)
+ for (unsigned p = 0; p < count; p++)
{
- for (auto& l : vertices_[p].obj.all_links ())
+ for (auto& l : vertices_.arrayZ[p].obj.all_links ())
{
vertices_[l.objidx].parents.push (p);
}
}
- for (unsigned i = 0; i < vertices_.length; i++)
+ for (unsigned i = 0; i < count; i++)
// parents arrays must be accurate or downstream operations like cycle detection
// and sorting won't work correctly.
- check_success (!vertices_[i].parents.in_error ());
+ check_success (!vertices_.arrayZ[i].parents.in_error ());
parents_invalid = false;
}
@@ -1239,12 +1247,13 @@ struct graph_t
// According to https://www3.cs.stonybrook.edu/~rezaul/papers/TR-07-54.pdf
// for practical performance this is faster then using a more advanced queue
// (such as a fibonacci queue) with a fast decrease priority.
- for (unsigned i = 0; i < vertices_.length; i++)
+ unsigned count = vertices_.length;
+ for (unsigned i = 0; i < count; i++)
{
if (i == vertices_.length - 1)
- vertices_[i].distance = 0;
+ vertices_.arrayZ[i].distance = 0;
else
- vertices_[i].distance = hb_int_max (int64_t);
+ vertices_.arrayZ[i].distance = hb_int_max (int64_t);
}
hb_priority_queue_t queue;
@@ -1332,10 +1341,11 @@ struct graph_t
void remap_all_obj_indices (const hb_vector_t<unsigned>& id_map,
hb_vector_t<vertex_t>* sorted_graph) const
{
- for (unsigned i = 0; i < sorted_graph->length; i++)
+ unsigned count = sorted_graph->length;
+ for (unsigned i = 0; i < count; i++)
{
(*sorted_graph)[i].remap_parents (id_map);
- for (auto& link : (*sorted_graph)[i].obj.all_links_writer ())
+ for (auto& link : sorted_graph->arrayZ[i].obj.all_links_writer ())
{
link.objidx = id_map[link.objidx];
}
diff --git a/src/3rdparty/harfbuzz-ng/src/graph/markbasepos-graph.hh b/src/3rdparty/harfbuzz-ng/src/graph/markbasepos-graph.hh
index 84ef5f71b9..5e9d5aea3a 100644
--- a/src/3rdparty/harfbuzz-ng/src/graph/markbasepos-graph.hh
+++ b/src/3rdparty/harfbuzz-ng/src/graph/markbasepos-graph.hh
@@ -319,7 +319,8 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2<S
hb_vector_t<class_info_t> class_to_info;
unsigned class_count= classCount;
- class_to_info.resize (class_count);
+ if (!class_to_info.resize (class_count))
+ return hb_vector_t<class_info_t>();
auto mark_array = c.graph.as_table<MarkArray> (this_index, &markArray);
if (!mark_array) return hb_vector_t<class_info_t> ();
@@ -327,6 +328,7 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2<S
for (unsigned mark = 0; mark < mark_count; mark++)
{
unsigned klass = (*mark_array.table)[mark].get_class ();
+ if (klass >= class_count) continue;
class_to_info[klass].marks.add (mark);
}
@@ -335,6 +337,7 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2<S
unsigned mark = (link.position - 2) /
OT::Layout::GPOS_impl::MarkRecord::static_size;
unsigned klass = (*mark_array.table)[mark].get_class ();
+ if (klass >= class_count) continue;
class_to_info[klass].child_indices.push (link.objidx);
}
diff --git a/src/3rdparty/harfbuzz-ng/src/graph/serialize.hh b/src/3rdparty/harfbuzz-ng/src/graph/serialize.hh
index 040fd1de5f..2e0b845baa 100644
--- a/src/3rdparty/harfbuzz-ng/src/graph/serialize.hh
+++ b/src/3rdparty/harfbuzz-ng/src/graph/serialize.hh
@@ -116,10 +116,10 @@ will_overflow (graph_t& graph,
for (int parent_idx = vertices.length - 1; parent_idx >= 0; parent_idx--)
{
// Don't need to check virtual links for overflow
- for (const auto& link : vertices[parent_idx].obj.real_links)
+ for (const auto& link : vertices.arrayZ[parent_idx].obj.real_links)
{
int64_t offset = compute_offset (graph, parent_idx, link);
- if (is_valid_offset (offset, link))
+ if (likely (is_valid_offset (offset, link)))
continue;
if (!overflows) return true;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.cc b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.cc
index c9147ff73b..5e4cea2224 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-aat-layout.cc
@@ -55,7 +55,13 @@ AAT::hb_aat_apply_context_t::hb_aat_apply_context_t (const hb_ot_shape_plan_t *p
buffer (buffer_),
sanitizer (),
ankr_table (&Null (AAT::ankr)),
- gdef_table (face->table.GDEF->table),
+ gdef_table (
+#ifndef HB_NO_OT_LAYOUT
+ face->table.GDEF->table
+#else
+ &Null (GDEF)
+#endif
+ ),
lookup_index (0)
{
sanitizer.init (blob);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-algs.hh b/src/3rdparty/harfbuzz-ng/src/hb-algs.hh
index 13587eac01..da383e050a 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-algs.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-algs.hh
@@ -626,8 +626,10 @@ hb_popcount (T v)
if (sizeof (T) == 8)
{
- unsigned int shift = 32;
- return hb_popcount<uint32_t> ((uint32_t) v) + hb_popcount ((uint32_t) (v >> shift));
+ uint64_t y = (uint64_t) v;
+ y -= ((y >> 1) & 0x5555555555555555ull);
+ y = (y & 0x3333333333333333ull) + (y >> 2 & 0x3333333333333333ull);
+ return ((y + (y >> 4)) & 0xf0f0f0f0f0f0f0full) * 0x101010101010101ull >> 56;
}
if (sizeof (T) == 16)
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-array.hh b/src/3rdparty/harfbuzz-ng/src/hb-array.hh
index e82c081535..1a22e15c0f 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-array.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-array.hh
@@ -122,9 +122,13 @@ struct hb_array_t : hb_iter_with_fallback_t<hb_array_t<Type>, Type&>
uint32_t hash () const
{
- uint32_t current = 0;
+ // FNV-1a hash function
+ uint32_t current = /*cbf29ce4*/0x84222325;
for (auto &v : *this)
- current = current * 31 + hb_hash (v);
+ {
+ current = current ^ hb_hash (v);
+ current = current * 16777619;
+ }
return current;
}
@@ -452,36 +456,50 @@ inline bool hb_array_t<const unsigned char>::operator == (const hb_array_t<const
template <>
inline uint32_t hb_array_t<const char>::hash () const
{
- uint32_t current = 0;
+ // FNV-1a hash function
+ uint32_t current = /*cbf29ce4*/0x84222325;
unsigned i = 0;
#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__))
struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
for (; i + 4 <= this->length; i += 4)
- current = current * 31 + hb_hash ((uint32_t) ((packed_uint32_t *) &this->arrayZ[i])->v);
+ {
+ current = current ^ hb_hash ((uint32_t) ((const packed_uint32_t *) &this->arrayZ[i])->v);
+ current = current * 16777619;
+ }
#endif
for (; i < this->length; i++)
- current = current * 31 + hb_hash (this->arrayZ[i]);
+ {
+ current = current ^ hb_hash (this->arrayZ[i]);
+ current = current * 16777619;
+ }
return current;
}
template <>
inline uint32_t hb_array_t<const unsigned char>::hash () const
{
- uint32_t current = 0;
+ // FNV-1a hash function
+ uint32_t current = /*cbf29ce4*/0x84222325;
unsigned i = 0;
#if defined(__OPTIMIZE__) && !defined(HB_NO_PACKED) && \
((defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__))
struct __attribute__((packed)) packed_uint32_t { uint32_t v; };
for (; i + 4 <= this->length; i += 4)
- current = current * 31 + hb_hash ((uint32_t) ((packed_uint32_t *) &this->arrayZ[i])->v);
+ {
+ current = current ^ hb_hash ((uint32_t) ((const packed_uint32_t *) &this->arrayZ[i])->v);
+ current = current * 16777619;
+ }
#endif
for (; i < this->length; i++)
- current = current * 31 + hb_hash (this->arrayZ[i]);
+ {
+ current = current ^ hb_hash (this->arrayZ[i]);
+ current = current * 16777619;
+ }
return current;
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-bit-set.hh b/src/3rdparty/harfbuzz-ng/src/hb-bit-set.hh
index c30b2af7b0..d290f6114c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-bit-set.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-bit-set.hh
@@ -402,7 +402,6 @@ struct hb_bit_set_t
uint32_t spm = page_map[spi].major;
uint32_t lpm = larger_set.page_map[lpi].major;
auto sp = page_at (spi);
- auto lp = larger_set.page_at (lpi);
if (spm < lpm && !sp.is_empty ())
return false;
@@ -410,6 +409,7 @@ struct hb_bit_set_t
if (lpm < spm)
continue;
+ auto lp = larger_set.page_at (lpi);
if (!sp.is_subset (lp))
return false;
@@ -623,6 +623,7 @@ struct hb_bit_set_t
*codepoint = INVALID;
return false;
}
+ last_page_lookup = i;
}
const auto* pages_array = pages.arrayZ;
@@ -632,7 +633,6 @@ struct hb_bit_set_t
if (pages_array[current.index].next (codepoint))
{
*codepoint += current.major * page_t::PAGE_BITS;
- last_page_lookup = i;
return true;
}
i++;
@@ -649,7 +649,6 @@ struct hb_bit_set_t
return true;
}
}
- last_page_lookup = 0;
*codepoint = INVALID;
return false;
}
@@ -921,7 +920,7 @@ struct hb_bit_set_t
memmove (page_map.arrayZ + i + 1,
page_map.arrayZ + i,
(page_map.length - 1 - i) * page_map.item_size);
- page_map[i] = map;
+ page_map.arrayZ[i] = map;
}
last_page_lookup = i;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
index 616cee807f..ace2a104fd 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.cc
@@ -268,7 +268,7 @@ hb_buffer_t::similar (const hb_buffer_t &src)
unicode = hb_unicode_funcs_reference (src.unicode);
flags = src.flags;
cluster_level = src.cluster_level;
- replacement = src.invisible;
+ replacement = src.replacement;
invisible = src.invisible;
not_found = src.not_found;
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh b/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh
index 5a43cabcb7..7a97fc7168 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-buffer.hh
@@ -553,7 +553,7 @@ struct hb_buffer_t
bool message (hb_font_t *font, const char *fmt, ...) HB_PRINTF_FUNC(3, 4)
{
#ifdef HB_NO_BUFFER_MESSAGE
- return true;
+ return true;
#else
if (likely (!messaging ()))
return true;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-config.hh b/src/3rdparty/harfbuzz-ng/src/hb-config.hh
index 52adaad438..26f7cba83e 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-config.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-config.hh
@@ -44,14 +44,14 @@
#ifdef HB_TINY
#define HB_LEAN
#define HB_MINI
+#define HB_OPTIMIZE_SIZE
+#define HB_OPTIMIZE_SIZE_MORE
+#define HB_MINIMIZE_MEMORY_USAGE
#define HB_NO_MT
#define HB_NO_UCD_UNASSIGNED
#ifndef NDEBUG
#define NDEBUG
#endif
-#ifndef __OPTIMIZE_SIZE__
-#define __OPTIMIZE_SIZE__
-#endif
#endif
#ifdef HB_LEAN
@@ -97,6 +97,12 @@
#define HB_NO_BORING_EXPANSION
#endif
+#ifdef __OPTIMIZE_SIZE__
+#ifndef HB_OPTIMIZE_SIZE
+#define HB_OPTIMIZE_SIZE
+#endif
+#endif
+
#if defined(HAVE_CONFIG_OVERRIDE_H) || defined(HB_CONFIG_OVERRIDE_H)
#ifndef HB_CONFIG_OVERRIDE_H
#define HB_CONFIG_OVERRIDE_H "config-override.h"
@@ -107,8 +113,10 @@
/* Closure of options. */
#ifdef HB_NO_BORING_EXPANSION
-#define HB_NO_BEYOND_64K
#define HB_NO_AVAR2
+#define HB_NO_BEYOND_64K
+#define HB_NO_CUBIC_GLYF
+#define HB_NO_VAR_COMPOSITES
#endif
#ifdef HB_DISABLE_DEPRECATED
@@ -175,21 +183,27 @@
#define HB_NO_OT_SHAPER_MYANMAR_ZAWGYI
#endif
-#ifdef NDEBUG
-#ifndef HB_NDEBUG
-#define HB_NDEBUG
-#endif
+#ifdef HB_OPTIMIZE_SIZE_MORE
+#define HB_NO_OT_LIGATURES_FAST_PATH
#endif
-#ifdef __OPTIMIZE_SIZE__
-#ifndef HB_OPTIMIZE_SIZE
-#define HB_OPTIMIZE_SIZE
-#endif
+#ifdef HB_MINIMIZE_MEMORY_USAGE
+#define HB_NO_GDEF_CACHE
+#define HB_NO_OT_LAYOUT_LOOKUP_CACHE
+#define HB_NO_OT_FONT_ADVANCE_CACHE
+#define HB_NO_OT_FONT_CMAP_CACHE
#endif
#ifdef HB_OPTIMIZE_SIZE
-#define HB_NO_OT_LAYOUT_LOOKUP_CACHE
+#define HB_OPTIMIZE_SIZE_VAL 1
+#else
+#define HB_OPTIMIZE_SIZE_VAL 0
#endif
+#ifdef HB_MINIMIZE_MEMORY_USAGE
+#define HB_MINIMIZE_MEMORY_USAGE_VAL 1
+#else
+#define HB_MINIMIZE_MEMORY_USAGE_VAL 0
+#endif
#endif /* HB_CONFIG_HH */
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-map.hh b/src/3rdparty/harfbuzz-ng/src/hb-map.hh
index 041b8829af..c685a9a3e1 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-map.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-map.hh
@@ -401,7 +401,8 @@ struct hb_hashmap_t
unsigned int tombstone = (unsigned) -1;
while (items[i].is_used ())
{
- if (items[i].hash == hash && items[i] == key)
+ if ((hb_is_same (K, hb_codepoint_t) || items[i].hash == hash) &&
+ items[i] == key)
return items[i];
if (tombstone == (unsigned) -1 && items[i].is_tombstone ())
tombstone = i;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-null.hh b/src/3rdparty/harfbuzz-ng/src/hb-null.hh
index 0d7f4da79e..3da2d75ef5 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-null.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-null.hh
@@ -37,7 +37,7 @@
/* Global nul-content Null pool. Enlarge as necessary. */
-#define HB_NULL_POOL_SIZE 448
+#define HB_NULL_POOL_SIZE 520
template <typename T, typename>
struct _hb_has_min_size : hb_false_type {};
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh
index f461a23044..4d0a965eee 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff1-table.hh
@@ -44,7 +44,7 @@ namespace CFF {
* CFF -- Compact Font Format (CFF)
* https://www.adobe.com/content/dam/acom/en/devnet/font/pdfs/5176.CFF.pdf
*/
-#define HB_OT_TAG_cff1 HB_TAG('C','F','F',' ')
+#define HB_OT_TAG_CFF1 HB_TAG('C','F','F',' ')
#define CFF_UNDEF_SID CFF_UNDEF_CODE
@@ -1019,7 +1019,7 @@ using namespace CFF;
struct cff1
{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_cff1;
+ static constexpr hb_tag_t tableTag = HB_OT_TAG_CFF1;
bool sanitize (hb_sanitize_context_t *c) const
{
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh
index b9a8819ab8..2134d48660 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-cff2-table.hh
@@ -38,7 +38,7 @@ namespace CFF {
* CFF2 -- Compact Font Format (CFF) Version 2
* https://docs.microsoft.com/en-us/typography/opentype/spec/cff2
*/
-#define HB_OT_TAG_cff2 HB_TAG('C','F','F','2')
+#define HB_OT_TAG_CFF2 HB_TAG('C','F','F','2')
typedef CFFIndex<HBUINT32> CFF2Index;
template <typename Type> struct CFF2IndexOf : CFFIndexOf<HBUINT32, Type> {};
@@ -379,7 +379,7 @@ using namespace CFF;
struct cff2
{
- static constexpr hb_tag_t tableTag = HB_OT_TAG_cff2;
+ static constexpr hb_tag_t tableTag = HB_OT_TAG_CFF2;
bool sanitize (hb_sanitize_context_t *c) const
{
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc
index 06f7092a59..c89a1954a9 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-font.cc
@@ -64,13 +64,17 @@
using hb_ot_font_cmap_cache_t = hb_cache_t<21, 16, 8, true>;
using hb_ot_font_advance_cache_t = hb_cache_t<24, 16, 8, true>;
+#ifndef HB_NO_OT_FONT_CMAP_CACHE
static hb_user_data_key_t hb_ot_font_cmap_cache_user_data_key;
+#endif
struct hb_ot_font_t
{
const hb_ot_face_t *ot_face;
+#ifndef HB_NO_OT_FONT_CMAP_CACHE
hb_ot_font_cmap_cache_t *cmap_cache;
+#endif
/* h_advance caching */
mutable hb_atomic_int_t cached_coords_serial;
@@ -86,6 +90,7 @@ _hb_ot_font_create (hb_font_t *font)
ot_font->ot_face = &font->face->table;
+#ifndef HB_NO_OT_FONT_CMAP_CACHE
// retry:
auto *cmap_cache = (hb_ot_font_cmap_cache_t *) hb_face_get_user_data (font->face,
&hb_ot_font_cmap_cache_user_data_key);
@@ -112,6 +117,7 @@ _hb_ot_font_create (hb_font_t *font)
}
out:
ot_font->cmap_cache = cmap_cache;
+#endif
return ot_font;
}
@@ -136,7 +142,11 @@ hb_ot_get_nominal_glyph (hb_font_t *font HB_UNUSED,
{
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
const hb_ot_face_t *ot_face = ot_font->ot_face;
- return ot_face->cmap->get_nominal_glyph (unicode, glyph, ot_font->cmap_cache);
+ hb_ot_font_cmap_cache_t *cmap_cache = nullptr;
+#ifndef HB_NO_OT_FONT_CMAP_CACHE
+ cmap_cache = ot_font->cmap_cache;
+#endif
+ return ot_face->cmap->get_nominal_glyph (unicode, glyph, cmap_cache);
}
static unsigned int
@@ -151,10 +161,14 @@ hb_ot_get_nominal_glyphs (hb_font_t *font HB_UNUSED,
{
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
const hb_ot_face_t *ot_face = ot_font->ot_face;
+ hb_ot_font_cmap_cache_t *cmap_cache = nullptr;
+#ifndef HB_NO_OT_FONT_CMAP_CACHE
+ cmap_cache = ot_font->cmap_cache;
+#endif
return ot_face->cmap->get_nominal_glyphs (count,
first_unicode, unicode_stride,
first_glyph, glyph_stride,
- ot_font->cmap_cache);
+ cmap_cache);
}
static hb_bool_t
@@ -167,9 +181,13 @@ hb_ot_get_variation_glyph (hb_font_t *font HB_UNUSED,
{
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
const hb_ot_face_t *ot_face = ot_font->ot_face;
+ hb_ot_font_cmap_cache_t *cmap_cache = nullptr;
+#ifndef HB_NO_OT_FONT_CMAP_CACHE
+ cmap_cache = ot_font->cmap_cache;
+#endif
return ot_face->cmap->get_variation_glyph (unicode,
variation_selector, glyph,
- ot_font->cmap_cache);
+ cmap_cache);
}
static void
@@ -188,7 +206,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data,
hb_position_t *orig_first_advance = first_advance;
-#ifndef HB_NO_VAR
+#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE)
const OT::HVAR &HVAR = *hmtx.var_table;
const OT::VariationStore &varStore = &HVAR + HVAR.varStore;
OT::VariationStore::cache_t *varStore_cache = font->num_coords * count >= 128 ? varStore.create_cache () : nullptr;
@@ -258,7 +276,7 @@ hb_ot_get_glyph_h_advances (hb_font_t* font, void* font_data,
}
}
-#ifndef HB_NO_VAR
+#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE)
OT::VariationStore::destroy_cache (varStore_cache);
#endif
@@ -293,7 +311,7 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data,
if (vmtx.has_data ())
{
-#ifndef HB_NO_VAR
+#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE)
const OT::VVAR &VVAR = *vmtx.var_table;
const OT::VariationStore &varStore = &VVAR + VVAR.varStore;
OT::VariationStore::cache_t *varStore_cache = font->num_coords ? varStore.create_cache () : nullptr;
@@ -308,7 +326,7 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data,
first_advance = &StructAtOffsetUnaligned<hb_position_t> (first_advance, advance_stride);
}
-#ifndef HB_NO_VAR
+#if !defined(HB_NO_VAR) && !defined(HB_NO_OT_FONT_ADVANCE_CACHE)
OT::VariationStore::destroy_cache (varStore_cache);
#endif
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh
index 52b7dc254b..36f123b559 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-common.hh
@@ -189,7 +189,7 @@ struct hb_collect_variation_indices_context_t :
hb_set_t *layout_variation_indices;
hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *varidx_delta_map;
- hb_font_t *font;
+ hb_vector_t<int> *normalized_coords;
const VariationStore *var_store;
const hb_set_t *glyph_set;
const hb_map_t *gpos_lookups;
@@ -197,14 +197,14 @@ struct hb_collect_variation_indices_context_t :
hb_collect_variation_indices_context_t (hb_set_t *layout_variation_indices_,
hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *varidx_delta_map_,
- hb_font_t *font_,
+ hb_vector_t<int> *normalized_coords_,
const VariationStore *var_store_,
const hb_set_t *glyph_set_,
const hb_map_t *gpos_lookups_,
float *store_cache_) :
layout_variation_indices (layout_variation_indices_),
varidx_delta_map (varidx_delta_map_),
- font (font_),
+ normalized_coords (normalized_coords_),
var_store (var_store_),
glyph_set (glyph_set_),
gpos_lookups (gpos_lookups_),
@@ -1769,6 +1769,7 @@ struct ClassDefFormat2_4
return_trace (true);
}
+ unsigned unsorted = false;
unsigned num_ranges = 1;
hb_codepoint_t prev_gid = (*it).first;
unsigned prev_klass = (*it).second;
@@ -1789,6 +1790,10 @@ struct ClassDefFormat2_4
if (cur_gid != prev_gid + 1 ||
cur_klass != prev_klass)
{
+
+ if (unlikely (cur_gid < prev_gid))
+ unsorted = true;
+
if (unlikely (!record)) break;
record->last = prev_gid;
num_ranges++;
@@ -1804,8 +1809,14 @@ struct ClassDefFormat2_4
prev_gid = cur_gid;
}
+ if (unlikely (c->in_error ())) return_trace (false);
+
if (likely (record)) record->last = prev_gid;
rangeRecord.len = num_ranges;
+
+ if (unlikely (unsorted))
+ rangeRecord.as_array ().qsort (RangeRecord<Types>::cmp_range);
+
return_trace (true);
}
@@ -2097,8 +2108,15 @@ struct ClassDef
#ifndef HB_NO_BEYOND_64K
if (glyph_max > 0xFFFFu)
- format += 2;
+ u.format += 2;
+ if (unlikely (glyph_max > 0xFFFFFFu))
+#else
+ if (unlikely (glyph_max > 0xFFFFu))
#endif
+ {
+ c->check_success (false, HB_SERIALIZE_ERROR_INT_OVERFLOW);
+ return_trace (false);
+ }
u.format = format;
@@ -3547,8 +3565,9 @@ struct VariationDevice
{
c->layout_variation_indices->add (varIdx);
int delta = 0;
- if (c->font && c->var_store)
- delta = roundf (get_delta (c->font, *c->var_store, c->store_cache));
+ if (c->normalized_coords && c->var_store)
+ delta = roundf (c->var_store->get_delta (varIdx, c->normalized_coords->arrayZ,
+ c->normalized_coords->length, c->store_cache));
/* set new varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX here, will remap
* varidx later*/
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh
index e1b66a199a..8e5be92d12 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout-gsubgpos.hh
@@ -476,6 +476,7 @@ struct hb_ot_apply_context_t :
void init (hb_ot_apply_context_t *c_, bool context_match = false)
{
c = c_;
+ end = c->buffer->len;
match_glyph_data16 = nullptr;
#ifndef HB_NO_BEYOND_64K
match_glyph_data24 = nullptr;
@@ -489,6 +490,7 @@ struct hb_ot_apply_context_t :
matcher.set_mask (context_match ? -1 : c->lookup_mask);
/* Per syllable matching is only for GSUB. */
matcher.set_per_syllable (c->table_index == 0 && c->per_syllable);
+ matcher.set_syllable (0);
}
void set_lookup_props (unsigned int lookup_props)
{
@@ -523,6 +525,14 @@ struct hb_ot_apply_context_t :
matcher.set_syllable (start_index_ == c->buffer->idx ? c->buffer->cur().syllable () : 0);
}
+ void reset_fast (unsigned int start_index_,
+ unsigned int num_items_)
+ {
+ // Doesn't set end or syllable. Used by GPOS which doesn't care / change.
+ idx = start_index_;
+ num_items = num_items_;
+ }
+
void reject ()
{
num_items++;
@@ -695,6 +705,7 @@ struct hb_ot_apply_context_t :
hb_buffer_t *buffer;
recurse_func_t recurse_func = nullptr;
const GDEF &gdef;
+ const GDEF::accelerator_t &gdef_accel;
const VariationStore &var_store;
VariationStore::cache_t *var_store_cache;
hb_set_digest_t digest;
@@ -728,6 +739,13 @@ struct hb_ot_apply_context_t :
Null (GDEF)
#endif
),
+ gdef_accel (
+#ifndef HB_NO_OT_LAYOUT
+ *face->table.GDEF
+#else
+ Null (GDEF::accelerator_t)
+#endif
+ ),
var_store (gdef.get_var_store ()),
var_store_cache (
#ifndef HB_NO_VAR
@@ -754,10 +772,10 @@ struct hb_ot_apply_context_t :
iter_context.init (this, true);
}
- void set_lookup_mask (hb_mask_t mask) { lookup_mask = mask; last_base = -1; last_base_until = 0; init_iters (); }
- void set_auto_zwj (bool auto_zwj_) { auto_zwj = auto_zwj_; init_iters (); }
- void set_auto_zwnj (bool auto_zwnj_) { auto_zwnj = auto_zwnj_; init_iters (); }
- void set_per_syllable (bool per_syllable_) { per_syllable = per_syllable_; init_iters (); }
+ void set_lookup_mask (hb_mask_t mask, bool init = true) { lookup_mask = mask; last_base = -1; last_base_until = 0; if (init) init_iters (); }
+ void set_auto_zwj (bool auto_zwj_, bool init = true) { auto_zwj = auto_zwj_; if (init) init_iters (); }
+ void set_auto_zwnj (bool auto_zwnj_, bool init = true) { auto_zwnj = auto_zwnj_; if (init) init_iters (); }
+ void set_per_syllable (bool per_syllable_, bool init = true) { per_syllable = per_syllable_; if (init) init_iters (); }
void set_random (bool random_) { random = random_; }
void set_recurse_func (recurse_func_t func) { recurse_func = func; }
void set_lookup_index (unsigned int lookup_index_) { lookup_index = lookup_index_; }
@@ -793,7 +811,6 @@ struct hb_ot_apply_context_t :
bool check_glyph_property (const hb_glyph_info_t *info,
unsigned int match_props) const
{
- hb_codepoint_t glyph = info->codepoint;
unsigned int glyph_props = _hb_glyph_info_get_glyph_props (info);
/* Not covered, if, for example, glyph class is ligature and
@@ -803,7 +820,7 @@ struct hb_ot_apply_context_t :
return false;
if (unlikely (glyph_props & HB_OT_LAYOUT_GLYPH_PROPS_MARK))
- return match_properties_mark (glyph, glyph_props, match_props);
+ return match_properties_mark (info->codepoint, glyph_props, match_props);
return true;
}
@@ -836,7 +853,7 @@ struct hb_ot_apply_context_t :
if (likely (has_glyph_classes))
{
props &= HB_OT_LAYOUT_GLYPH_PROPS_PRESERVE;
- _hb_glyph_info_set_glyph_props (&buffer->cur(), props | gdef.get_glyph_props (glyph_index));
+ _hb_glyph_info_set_glyph_props (&buffer->cur(), props | gdef_accel.get_glyph_props (glyph_index));
}
else if (class_guess)
{
@@ -884,7 +901,7 @@ struct hb_accelerate_subtables_context_t :
#ifndef HB_NO_OT_LAYOUT_LOOKUP_CACHE
template <typename T>
- static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply (c, true) )
+ static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<1>) HB_RETURN (bool, obj->apply_cached (c) )
template <typename T>
static inline auto apply_cached_ (const T *obj, hb_ot_apply_context_t *c, hb_priority<0>) HB_RETURN (bool, obj->apply (c) )
template <typename Type>
@@ -1241,7 +1258,6 @@ static inline bool match_input (hb_ot_apply_context_t *c,
*/
unsigned int total_component_count = 0;
- total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur());
unsigned int first_lig_id = _hb_glyph_info_get_lig_id (&buffer->cur());
unsigned int first_lig_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
@@ -1252,7 +1268,6 @@ static inline bool match_input (hb_ot_apply_context_t *c,
LIGBASE_MAY_SKIP
} ligbase = LIGBASE_NOT_CHECKED;
- match_positions[0] = buffer->idx;
for (unsigned int i = 1; i < count; i++)
{
unsigned unsafe_to;
@@ -1317,7 +1332,12 @@ static inline bool match_input (hb_ot_apply_context_t *c,
*end_position = skippy_iter.idx + 1;
if (p_total_component_count)
+ {
+ total_component_count += _hb_glyph_info_get_lig_num_comps (&buffer->cur());
*p_total_component_count = total_component_count;
+ }
+
+ match_positions[0] = buffer->idx;
return_trace (true);
}
@@ -2431,7 +2451,9 @@ struct ContextFormat2_5
}
}
- bool apply (hb_ot_apply_context_t *c, bool cached = false) const
+ bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); }
+ bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); }
+ bool _apply (hb_ot_apply_context_t *c, bool cached) const
{
TRACE_APPLY (this);
unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
@@ -3534,7 +3556,9 @@ struct ChainContextFormat2_5
}
}
- bool apply (hb_ot_apply_context_t *c, bool cached = false) const
+ bool apply_cached (hb_ot_apply_context_t *c) const { return _apply (c, true); }
+ bool apply (hb_ot_apply_context_t *c) const { return _apply (c, false); }
+ bool _apply (hb_ot_apply_context_t *c, bool cached) const
{
TRACE_APPLY (this);
unsigned int index = (this+coverage).get_coverage (c->buffer->cur().codepoint);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
index 256a055863..c66ee8cfd0 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-layout.cc
@@ -64,8 +64,8 @@ using OT::Layout::GPOS;
* @include: hb-ot.h
*
* Functions for querying OpenType Layout features in the font face.
- * See the <ulink url="http://www.microsoft.com/typography/otspec/">OpenType
- * specification</ulink> for details.
+ * See the [OpenType specification](http://www.microsoft.com/typography/otspec/)
+ * for details.
**/
@@ -257,12 +257,13 @@ _hb_ot_layout_set_glyph_props (hb_font_t *font,
{
_hb_buffer_assert_gsubgpos_vars (buffer);
- const OT::GDEF &gdef = *font->face->table.GDEF->table;
+ const auto &gdef = *font->face->table.GDEF;
unsigned int count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
{
- _hb_glyph_info_set_glyph_props (&buffer->info[i], gdef.get_glyph_props (buffer->info[i].codepoint));
- _hb_glyph_info_clear_lig_props (&buffer->info[i]);
+ _hb_glyph_info_set_glyph_props (&info[i], gdef.get_glyph_props (info[i].codepoint));
+ _hb_glyph_info_clear_lig_props (&info[i]);
}
}
@@ -1895,7 +1896,7 @@ apply_backward (OT::hb_ot_apply_context_t *c,
if (accel.digest.may_have (buffer->cur().codepoint) &&
(buffer->cur().mask & c->lookup_mask) &&
c->check_glyph_property (&buffer->cur(), c->lookup_props))
- ret |= accel.apply (c, subtable_count, false);
+ ret |= accel.apply (c, subtable_count, false);
/* The reverse lookup doesn't "advance" cursor (for good reason). */
buffer->idx--;
@@ -1977,11 +1978,12 @@ inline void hb_ot_map_t::apply (const Proxy &proxy,
if (accel->digest.may_have (c.digest))
{
c.set_lookup_index (lookup_index);
- c.set_lookup_mask (lookup.mask);
- c.set_auto_zwj (lookup.auto_zwj);
- c.set_auto_zwnj (lookup.auto_zwnj);
+ c.set_lookup_mask (lookup.mask, false);
+ c.set_auto_zwj (lookup.auto_zwj, false);
+ c.set_auto_zwnj (lookup.auto_zwnj, false);
c.set_random (lookup.random);
- c.set_per_syllable (lookup.per_syllable);
+ c.set_per_syllable (lookup.per_syllable, false);
+ /* apply_string's set_lookup_props initializes the iterators. */
apply_string<Proxy> (&c,
proxy.accel.table->get_lookup (lookup_index),
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc
index c515867bdf..876ad258e3 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-math.cc
@@ -76,7 +76,7 @@ hb_ot_math_has_data (hb_face_t *face)
*
* However, if the requested constant is #HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN,
* #HB_OT_MATH_CONSTANT_SCRIPT_SCRIPT_PERCENT_SCALE_DOWN or
- * #HB_OT_MATH_CONSTANT_SCRIPT_PERCENT_SCALE_DOWN, then the return value is
+ * #HB_OT_MATH_CONSTANT_RADICAL_DEGREE_BOTTOM_RAISE_PERCENT, then the return value is
* an integer between 0 and 100 representing that percentage.
*
* Return value: the requested constant or zero
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.cc
index 5b12482b97..e314d946b6 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-metrics.cc
@@ -196,7 +196,7 @@ hb_ot_metrics_get_position (hb_font_t *font,
*position *= mult;
if (font->slant)
- *position += _hb_roundf (mult * font->slant_xy * rise);
+ *position += roundf (mult * font->slant_xy * rise);
}
return ret;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
index 897377aa15..69dbec0783 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shape-normalize.cc
@@ -383,14 +383,15 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
if (!all_simple && buffer->message(font, "start reorder"))
{
count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
for (unsigned int i = 0; i < count; i++)
{
- if (_hb_glyph_info_get_modified_combining_class (&buffer->info[i]) == 0)
+ if (_hb_glyph_info_get_modified_combining_class (&info[i]) == 0)
continue;
unsigned int end;
for (end = i + 1; end < count; end++)
- if (_hb_glyph_info_get_modified_combining_class (&buffer->info[end]) == 0)
+ if (_hb_glyph_info_get_modified_combining_class (&info[end]) == 0)
break;
/* We are going to do a O(n^2). Only do this if the sequence is short. */
@@ -414,11 +415,13 @@ _hb_ot_shape_normalize (const hb_ot_shape_plan_t *plan,
* If it did NOT, then make it skippable.
* https://github.com/harfbuzz/harfbuzz/issues/554
*/
- for (unsigned int i = 1; i + 1 < buffer->len; i++)
- if (buffer->info[i].codepoint == 0x034Fu/*CGJ*/ &&
- (info_cc(buffer->info[i+1]) == 0 || info_cc(buffer->info[i-1]) <= info_cc(buffer->info[i+1])))
+ unsigned count = buffer->len;
+ hb_glyph_info_t *info = buffer->info;
+ for (unsigned int i = 1; i + 1 < count; i++)
+ if (info[i].codepoint == 0x034Fu/*CGJ*/ &&
+ (info_cc(info[i+1]) == 0 || info_cc(info[i-1]) <= info_cc(info[i+1])))
{
- _hb_glyph_info_unhide (&buffer->info[i]);
+ _hb_glyph_info_unhide (&info[i]);
}
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic-machine.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic-machine.hh
index 7dd47755af..353e32d32c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic-machine.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-shaper-indic-machine.hh
@@ -53,7 +53,7 @@ enum indic_syllable_type_t {
};
-#line 54 "hb-ot-shaper-indic-machine.hh"
+#line 57 "hb-ot-shaper-indic-machine.hh"
#define indic_syllable_machine_ex_A 9u
#define indic_syllable_machine_ex_C 1u
#define indic_syllable_machine_ex_CM 16u
@@ -76,7 +76,7 @@ enum indic_syllable_type_t {
#define indic_syllable_machine_ex_ZWNJ 5u
-#line 75 "hb-ot-shaper-indic-machine.hh"
+#line 80 "hb-ot-shaper-indic-machine.hh"
static const unsigned char _indic_syllable_machine_trans_keys[] = {
8u, 8u, 4u, 13u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u,
8u, 8u, 5u, 13u, 5u, 13u, 13u, 13u, 4u, 13u, 4u, 13u, 4u, 13u, 4u, 13u,
@@ -460,7 +460,7 @@ find_syllables_indic (hb_buffer_t *buffer)
int cs;
hb_glyph_info_t *info = buffer->info;
-#line 453 "hb-ot-shaper-indic-machine.hh"
+#line 464 "hb-ot-shaper-indic-machine.hh"
{
cs = indic_syllable_machine_start;
ts = 0;
@@ -476,7 +476,7 @@ find_syllables_indic (hb_buffer_t *buffer)
unsigned int syllable_serial = 1;
-#line 465 "hb-ot-shaper-indic-machine.hh"
+#line 480 "hb-ot-shaper-indic-machine.hh"
{
int _slen;
int _trans;
@@ -490,7 +490,7 @@ _resume:
#line 1 "NONE"
{ts = p;}
break;
-#line 477 "hb-ot-shaper-indic-machine.hh"
+#line 494 "hb-ot-shaper-indic-machine.hh"
}
_keys = _indic_syllable_machine_trans_keys + (cs<<1);
@@ -593,7 +593,7 @@ _eof_trans:
#line 114 "hb-ot-shaper-indic-machine.rl"
{act = 6;}
break;
-#line 559 "hb-ot-shaper-indic-machine.hh"
+#line 597 "hb-ot-shaper-indic-machine.hh"
}
_again:
@@ -602,7 +602,7 @@ _again:
#line 1 "NONE"
{ts = 0;}
break;
-#line 566 "hb-ot-shaper-indic-machine.hh"
+#line 606 "hb-ot-shaper-indic-machine.hh"
}
if ( ++p != pe )
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-common.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-common.hh
index 853fe3839b..7d4bf2241c 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-common.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-common.hh
@@ -270,7 +270,8 @@ struct TupleVariationHeader
if (shared_tuple_active_idx)
{
- assert (index < shared_tuple_active_idx->length);
+ if (unlikely (index >= shared_tuple_active_idx->length))
+ return 0.f;
int v = (*shared_tuple_active_idx).arrayZ[index];
if (v != -1)
{
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-cvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-cvar-table.hh
index bdb2b6b23b..7fd0f1d79d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-cvar-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-cvar-table.hh
@@ -126,7 +126,6 @@ struct cvar
hb_blob_destroy (cvt_prime_blob);
return false;
}
- hb_memset (cvt_deltas.arrayZ, 0, cvt_deltas.get_size ());
if (!calculate_cvt_deltas (plan->normalized_coords.length, plan->normalized_coords.as_array (),
num_cvt_item, tuple_var_data, base, cvt_deltas))
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh
index 4752a08fbe..ece892e1dd 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-ot-var-gvar-table.hh
@@ -44,8 +44,15 @@ struct contour_point_t
void init (float x_ = 0.f, float y_ = 0.f, bool is_end_point_ = false)
{ flag = 0; x = x_; y = y_; is_end_point = is_end_point_; }
+ void transform (const float (&matrix)[4])
+ {
+ float x_ = x * matrix[0] + y * matrix[2];
+ y = x * matrix[1] + y * matrix[3];
+ x = x_;
+ }
void translate (const contour_point_t &p) { x += p.x; y += p.y; }
+
float x = 0.f;
float y = 0.f;
uint8_t flag = 0;
@@ -63,32 +70,6 @@ struct contour_point_vector_t : hb_vector_t<contour_point_t>
unsigned count = a.length;
hb_memcpy (arrayZ, a.arrayZ, count * sizeof (arrayZ[0]));
}
-
- void transform (const float (&matrix)[4])
- {
- if (matrix[0] == 1.f && matrix[1] == 0.f &&
- matrix[2] == 0.f && matrix[3] == 1.f)
- return;
- auto arrayZ = this->arrayZ;
- unsigned count = length;
- for (unsigned i = 0; i < count; i++)
- {
- contour_point_t &p = arrayZ[i];
- float x_ = p.x * matrix[0] + p.y * matrix[2];
- p.y = p.x * matrix[1] + p.y * matrix[3];
- p.x = x_;
- }
- }
-
- void translate (const contour_point_t& delta)
- {
- if (delta.x == 0.f && delta.y == 0.f)
- return;
- auto arrayZ = this->arrayZ;
- unsigned count = length;
- for (unsigned i = 0; i < count; i++)
- arrayZ[i].translate (delta);
- }
};
struct GlyphVariationData : TupleVariationData
@@ -238,7 +219,7 @@ struct gvar
int idx = -1;
for (unsigned j = 0; j < axis_count; j++)
{
- F2DOT14 peak = tuple.arrayZ[j];
+ const F2DOT14 &peak = tuple.arrayZ[j];
if (peak.to_int () != 0)
{
if (idx != -1)
@@ -249,7 +230,7 @@ struct gvar
idx = j;
}
}
- shared_tuple_active_idx[i] = idx;
+ shared_tuple_active_idx.arrayZ[i] = idx;
}
}
~accelerator_t () { table.destroy (); }
@@ -311,7 +292,7 @@ struct gvar
hb_vector_t<unsigned> end_points; // Populated lazily
unsigned num_coords = table->axisCount;
- hb_array_t<const F2DOT14> shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * table->axisCount);
+ hb_array_t<const F2DOT14> shared_tuples = (table+table->sharedTuples).as_array (table->sharedTupleCount * num_coords);
hb_vector_t<unsigned int> private_indices;
hb_vector_t<int> x_deltas;
@@ -320,7 +301,7 @@ struct gvar
do
{
float scalar = iterator.current_tuple->calculate_scalar (coords, num_coords, shared_tuples,
- shared_tuple_active_idx.in_error () ? nullptr : &shared_tuple_active_idx);
+ &shared_tuple_active_idx);
if (scalar == 0.f) continue;
const HBUINT8 *p = iterator.get_serialized_data ();
unsigned int length = iterator.current_tuple->get_data_size ();
@@ -329,8 +310,9 @@ struct gvar
if (!deltas)
{
- if (unlikely (!deltas_vec.resize (points.length))) return false;
+ if (unlikely (!deltas_vec.resize (points.length, false))) return false;
deltas = deltas_vec.as_array ();
+ hb_memset (deltas.arrayZ, 0, deltas.get_size ()); // Faster than vector resize
}
const HBUINT8 *end = p + length;
@@ -359,7 +341,8 @@ struct gvar
if (flush)
{
- for (unsigned int i = 0; i < points.length; i++)
+ unsigned count = points.length;
+ for (unsigned int i = 0; i < count; i++)
points.arrayZ[i].translate (deltas.arrayZ[i]);
flush = false;
@@ -367,7 +350,8 @@ struct gvar
hb_memset (deltas.arrayZ, 0, deltas.get_size ());
}
- if (scalar != 1.0f)
+ if (HB_OPTIMIZE_SIZE_VAL)
+ {
for (unsigned int i = 0; i < num_deltas; i++)
{
unsigned int pt_index;
@@ -383,29 +367,61 @@ struct gvar
delta.x += x_deltas.arrayZ[i] * scalar;
delta.y += y_deltas.arrayZ[i] * scalar;
}
+ }
else
- for (unsigned int i = 0; i < num_deltas; i++)
+ {
+ /* Ouch. Four cases... for optimization. */
+ if (scalar != 1.0f)
{
- unsigned int pt_index;
if (apply_to_all)
- pt_index = i;
+ for (unsigned int i = 0; i < num_deltas; i++)
+ {
+ unsigned int pt_index = i;
+ auto &delta = deltas.arrayZ[pt_index];
+ delta.x += x_deltas.arrayZ[i] * scalar;
+ delta.y += y_deltas.arrayZ[i] * scalar;
+ }
else
- {
- pt_index = indices[i];
- if (unlikely (pt_index >= deltas.length)) continue;
- }
- auto &delta = deltas.arrayZ[pt_index];
- delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */
- delta.x += x_deltas.arrayZ[i];
- delta.y += y_deltas.arrayZ[i];
+ for (unsigned int i = 0; i < num_deltas; i++)
+ {
+ unsigned int pt_index = indices[i];
+ if (unlikely (pt_index >= deltas.length)) continue;
+ auto &delta = deltas.arrayZ[pt_index];
+ delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */
+ delta.x += x_deltas.arrayZ[i] * scalar;
+ delta.y += y_deltas.arrayZ[i] * scalar;
+ }
}
+ else
+ {
+ if (apply_to_all)
+ for (unsigned int i = 0; i < num_deltas; i++)
+ {
+ unsigned int pt_index = i;
+ auto &delta = deltas.arrayZ[pt_index];
+ delta.x += x_deltas.arrayZ[i];
+ delta.y += y_deltas.arrayZ[i];
+ }
+ else
+ for (unsigned int i = 0; i < num_deltas; i++)
+ {
+ unsigned int pt_index = indices[i];
+ if (unlikely (pt_index >= deltas.length)) continue;
+ auto &delta = deltas.arrayZ[pt_index];
+ delta.flag = 1; /* this point is referenced, i.e., explicit deltas specified */
+ delta.x += x_deltas.arrayZ[i];
+ delta.y += y_deltas.arrayZ[i];
+ }
+ }
+ }
/* infer deltas for unreferenced points */
if (!apply_to_all)
{
if (!end_points)
{
- for (unsigned i = 0; i < points.length; ++i)
+ unsigned count = points.length;
+ for (unsigned i = 0; i < count; ++i)
if (points.arrayZ[i].is_end_point)
end_points.push (i);
if (unlikely (end_points.in_error ())) return false;
@@ -465,8 +481,11 @@ struct gvar
} while (iterator.move_to_next ());
if (flush)
- for (unsigned int i = 0; i < points.length; i++)
+ {
+ unsigned count = points.length;
+ for (unsigned int i = 0; i < count; i++)
points.arrayZ[i].translate (deltas.arrayZ[i]);
+ }
return true;
}
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-set-digest.hh b/src/3rdparty/harfbuzz-ng/src/hb-set-digest.hh
index e8409111f2..dab713729b 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-set-digest.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-set-digest.hh
@@ -45,10 +45,16 @@
* a lookup's or subtable's Coverage table(s), and then when we
* want to apply the lookup or subtable to a glyph, before trying
* to apply, we ask the filter if the glyph may be covered. If it's
- * not, we return early.
+ * not, we return early. We can also match a digest against another
+ * digest.
*
- * We use these filters both at the lookup-level, and then again,
- * at the subtable-level. Both have performance win.
+ * We use these filters at three levels:
+ * - If the digest for all the glyphs in the buffer as a whole
+ * does not match the digest for the lookup, skip the lookup.
+ * - For each glyph, if it doesn't match the lookup digest,
+ * skip it.
+ * - For each glyph, if it doesn't match the subtable digest,
+ * skip it.
*
* The main filter we use is a combination of three bits-pattern
* filters. A bits-pattern filter checks a number of bits (5 or 6)
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-accelerator.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-accelerator.hh
index e523c25820..bb7c62d064 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-accelerator.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-accelerator.hh
@@ -58,6 +58,8 @@ struct hb_subset_accelerator_t
hb_subset_accelerator_t* accel =
(hb_subset_accelerator_t*) hb_calloc (1, sizeof(hb_subset_accelerator_t));
+ if (unlikely (!accel)) return accel;
+
new (accel) hb_subset_accelerator_t (unicode_to_gid_,
gid_to_unicodes_,
unicodes_,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc
index 5f001ac251..465af50814 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-input.cc
@@ -520,6 +520,37 @@ hb_subset_preprocess (hb_face_t *source)
return new_source;
}
+/**
+ * hb_subset_input_old_to_new_glyph_mapping:
+ * @input: a #hb_subset_input_t object.
+ *
+ * Returns a map which can be used to provide an explicit mapping from old to new glyph
+ * id's in the produced subset. The caller should populate the map as desired.
+ * If this map is left empty then glyph ids will be automatically mapped to new
+ * values by the subsetter. If populated, the mapping must be unique. That
+ * is no two original glyph ids can be mapped to the same new id.
+ * Additionally, if a mapping is provided then the retain gids option cannot
+ * be enabled.
+ *
+ * Any glyphs that are retained in the subset which are not specified
+ * in this mapping will be assigned glyph ids after the highest glyph
+ * id in the mapping.
+ *
+ * Note: this will accept and apply non-monotonic mappings, however this
+ * may result in unsorted Coverage tables. Such fonts may not work for all
+ * use cases (for example ots will reject unsorted coverage tables). So it's
+ * recommended, if possible, to supply a monotonic mapping.
+ *
+ * Return value: (transfer none): pointer to the #hb_map_t of the custom glyphs ID map.
+ *
+ * Since: 7.3.0
+ **/
+HB_EXTERN hb_map_t*
+hb_subset_input_old_to_new_glyph_mapping (hb_subset_input_t *input)
+{
+ return &input->glyph_map;
+}
+
#ifdef HB_EXPERIMENTAL_API
/**
* hb_subset_input_override_name_table:
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-input.hh
index 1550e8b2c3..1970f795b9 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-input.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-input.hh
@@ -119,6 +119,7 @@ struct hb_subset_input_t
bool force_long_loca = false;
hb_hashmap_t<hb_tag_t, float> axes_location;
+ hb_map_t glyph_map;
#ifdef HB_EXPERIMENTAL_API
hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> name_table_overrides;
#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan-member-list.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan-member-list.hh
new file mode 100644
index 0000000000..acf508c32d
--- /dev/null
+++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan-member-list.hh
@@ -0,0 +1,128 @@
+/*
+ * Copyright © 2018 Google, Inc.
+ * Copyright © 2023 Behdad Esfahbod
+ *
+ * This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Garret Rieger, Roderick Sheeter
+ */
+
+#ifndef HB_SUBSET_PLAN_MEMBER_LIST_HH
+#define HB_SUBSET_PLAN_MEMBER_LIST_HH
+#endif /* HB_SUBSET_PLAN_MEMBER_LIST_HH */ /* Dummy header guards */
+
+#define E(x, y) x, y
+
+// For each cp that we'd like to retain maps to the corresponding gid.
+HB_SUBSET_PLAN_MEMBER (hb_set_t, unicodes)
+HB_SUBSET_PLAN_MEMBER (hb_sorted_vector_t E(<hb_pair_t<hb_codepoint_t, hb_codepoint_t>>), unicode_to_new_gid_list)
+
+// name_ids we would like to retain
+HB_SUBSET_PLAN_MEMBER (hb_set_t, name_ids)
+
+// name_languages we would like to retain
+HB_SUBSET_PLAN_MEMBER (hb_set_t, name_languages)
+
+//layout features which will be preserved
+HB_SUBSET_PLAN_MEMBER (hb_set_t, layout_features)
+
+// layout scripts which will be preserved.
+HB_SUBSET_PLAN_MEMBER (hb_set_t, layout_scripts)
+
+//glyph ids requested to retain
+HB_SUBSET_PLAN_MEMBER (hb_set_t, glyphs_requested)
+
+// Tables which should not be processed, just pass them through.
+HB_SUBSET_PLAN_MEMBER (hb_set_t, no_subset_tables)
+
+// Tables which should be dropped.
+HB_SUBSET_PLAN_MEMBER (hb_set_t, drop_tables)
+
+// Old -> New glyph id mapping
+HB_SUBSET_PLAN_MEMBER (hb_map_t, glyph_map_gsub)
+
+HB_SUBSET_PLAN_MEMBER (hb_set_t, _glyphset)
+HB_SUBSET_PLAN_MEMBER (hb_set_t, _glyphset_gsub)
+HB_SUBSET_PLAN_MEMBER (hb_set_t, _glyphset_mathed)
+HB_SUBSET_PLAN_MEMBER (hb_set_t, _glyphset_colred)
+
+//active lookups we'd like to retain
+HB_SUBSET_PLAN_MEMBER (hb_map_t, gsub_lookups)
+HB_SUBSET_PLAN_MEMBER (hb_map_t, gpos_lookups)
+
+//active langsys we'd like to retain
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<unsigned, hb::unique_ptr<hb_set_t>>), gsub_langsys)
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<unsigned, hb::unique_ptr<hb_set_t>>), gpos_langsys)
+
+//active features after removing redundant langsys and prune_features
+HB_SUBSET_PLAN_MEMBER (hb_map_t, gsub_features)
+HB_SUBSET_PLAN_MEMBER (hb_map_t, gpos_features)
+
+//active feature variation records/condition index with variations
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<unsigned, hb::shared_ptr<hb_set_t>>), gsub_feature_record_cond_idx_map)
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<unsigned, hb::shared_ptr<hb_set_t>>), gpos_feature_record_cond_idx_map)
+
+//feature index-> address of substituation feature table mapping with
+//variations
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<unsigned, const OT::Feature*>), gsub_feature_substitutes_map)
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<unsigned, const OT::Feature*>), gpos_feature_substitutes_map)
+
+//active layers/palettes we'd like to retain
+HB_SUBSET_PLAN_MEMBER (hb_map_t, colrv1_layers)
+HB_SUBSET_PLAN_MEMBER (hb_map_t, colr_palettes)
+
+//Old layout item variation index -> (New varidx, delta) mapping
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<unsigned, hb_pair_t E(<unsigned, int>)>), layout_variation_idx_delta_map)
+
+//gdef varstore retained varidx mapping
+HB_SUBSET_PLAN_MEMBER (hb_vector_t<hb_inc_bimap_t>, gdef_varstore_inner_maps)
+
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<hb_tag_t, hb::unique_ptr<hb_blob_t>>), sanitized_table_cache)
+
+//normalized axes location map
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<hb_tag_t, int>), axes_location)
+HB_SUBSET_PLAN_MEMBER (hb_vector_t<int>, normalized_coords)
+
+//user specified axes location map
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<hb_tag_t, float>), user_axes_location)
+
+//retained old axis index -> new axis index mapping in fvar axis array
+HB_SUBSET_PLAN_MEMBER (hb_map_t, axes_index_map)
+
+//axis_index->axis_tag mapping in fvar axis array
+HB_SUBSET_PLAN_MEMBER (hb_map_t, axes_old_index_tag_map)
+
+//hmtx metrics map: new gid->(advance, lsb)
+HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(<hb_codepoint_t, hb_pair_t E(<unsigned, int>)>), hmtx_map)
+//vmtx metrics map: new gid->(advance, lsb)
+HB_SUBSET_PLAN_MEMBER (mutable hb_hashmap_t E(<hb_codepoint_t, hb_pair_t E(<unsigned, int>)>), vmtx_map)
+//boundsWidth map: new gid->boundsWidth, boundWidth=xMax - xMin
+HB_SUBSET_PLAN_MEMBER (mutable hb_map_t, bounds_width_map)
+//boundsHeight map: new gid->boundsHeight, boundsHeight=yMax - yMin
+HB_SUBSET_PLAN_MEMBER (mutable hb_map_t, bounds_height_map)
+
+#ifdef HB_EXPERIMENTAL_API
+// name table overrides map: hb_ot_name_record_ids_t-> name string new value or
+// None to indicate should remove
+HB_SUBSET_PLAN_MEMBER (hb_hashmap_t E(<hb_ot_name_record_ids_t, hb_bytes_t>), name_table_overrides)
+#endif
+
+#undef E
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc
index aea886864d..791f92d02d 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.cc
@@ -381,18 +381,10 @@ _collect_layout_variation_indices (hb_subset_plan_t* plan)
const OT::VariationStore *var_store = nullptr;
hb_set_t varidx_set;
- hb_font_t *font = nullptr;
float *store_cache = nullptr;
bool collect_delta = plan->pinned_at_default ? false : true;
if (collect_delta)
{
- if (unlikely (!plan->check_success (font = _get_hb_font_with_variations (plan)))) {
- hb_font_destroy (font);
- gdef.destroy ();
- gpos.destroy ();
- return;
- }
-
if (gdef->has_var_store ())
{
var_store = &(gdef->get_var_store ());
@@ -402,7 +394,8 @@ _collect_layout_variation_indices (hb_subset_plan_t* plan)
OT::hb_collect_variation_indices_context_t c (&varidx_set,
&plan->layout_variation_idx_delta_map,
- font, var_store,
+ plan->normalized_coords ? &(plan->normalized_coords) : nullptr,
+ var_store,
&plan->_glyphset_gsub,
&plan->gpos_lookups,
store_cache);
@@ -411,7 +404,6 @@ _collect_layout_variation_indices (hb_subset_plan_t* plan)
if (hb_ot_layout_has_positioning (plan->source))
gpos->collect_variation_indices (&c);
- hb_font_destroy (font);
var_store->destroy_cache (store_cache);
gdef->remap_layout_variation_indices (&varidx_set, &plan->layout_variation_idx_delta_map);
@@ -616,13 +608,14 @@ _glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf,
int operation_count,
unsigned depth = 0)
{
- if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return operation_count;
- if (unlikely (--operation_count < 0)) return operation_count;
/* Check if is already visited */
if (gids_to_retain->has (gid)) return operation_count;
gids_to_retain->add (gid);
+ if (unlikely (depth++ > HB_MAX_NESTING_LEVEL)) return operation_count;
+ if (unlikely (--operation_count < 0)) return operation_count;
+
for (auto &item : glyf.glyph_for_gid (gid).get_composite_iterator ())
operation_count =
_glyf_add_gid_and_children (glyf,
@@ -775,10 +768,11 @@ _create_glyph_map_gsub (const hb_set_t* glyph_set_gsub,
;
}
-static void
+static bool
_create_old_gid_to_new_gid_map (const hb_face_t *face,
bool retain_gids,
const hb_set_t *all_gids_to_retain,
+ const hb_map_t *requested_glyph_map,
hb_map_t *glyph_map, /* OUT */
hb_map_t *reverse_glyph_map, /* OUT */
unsigned int *num_glyphs /* OUT */)
@@ -787,7 +781,54 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face,
reverse_glyph_map->resize (pop);
glyph_map->resize (pop);
- if (!retain_gids)
+ if (*requested_glyph_map)
+ {
+ hb_set_t new_gids(requested_glyph_map->values());
+ if (new_gids.get_population() != requested_glyph_map->get_population())
+ {
+ DEBUG_MSG (SUBSET, nullptr, "The provided custom glyph mapping is not unique.");
+ return false;
+ }
+
+ if (retain_gids)
+ {
+ DEBUG_MSG (SUBSET, nullptr,
+ "HB_SUBSET_FLAGS_RETAIN_GIDS cannot be set if "
+ "a custom glyph mapping has been provided.");
+ return false;
+ }
+
+ hb_codepoint_t max_glyph = 0;
+ hb_set_t remaining;
+ for (auto old_gid : all_gids_to_retain->iter ())
+ {
+ if (old_gid == 0) {
+ reverse_glyph_map->set(0, 0);
+ continue;
+ }
+
+ hb_codepoint_t* new_gid;
+ if (!requested_glyph_map->has (old_gid, &new_gid))
+ {
+ remaining.add(old_gid);
+ continue;
+ }
+
+ if (*new_gid > max_glyph)
+ max_glyph = *new_gid;
+ reverse_glyph_map->set (*new_gid, old_gid);
+ }
+
+ // Anything that wasn't mapped by the requested mapping should
+ // be placed after the requested mapping.
+ for (auto old_gid : remaining)
+ {
+ reverse_glyph_map->set(++max_glyph, old_gid);
+ }
+
+ *num_glyphs = max_glyph + 1;
+ }
+ else if (!retain_gids)
{
+ hb_enumerate (hb_iter (all_gids_to_retain), (hb_codepoint_t) 0)
| hb_sink (reverse_glyph_map)
@@ -813,6 +854,8 @@ _create_old_gid_to_new_gid_map (const hb_face_t *face,
| hb_map (&hb_pair_t<hb_codepoint_t, hb_codepoint_t>::reverse)
| hb_sink (glyph_map)
;
+
+ return true;
}
#ifndef HB_NO_VAR
@@ -1002,7 +1045,6 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face,
if (accel)
accelerator = (hb_subset_accelerator_t*) accel;
-
if (unlikely (in_error ()))
return;
@@ -1016,12 +1058,16 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face,
if (unlikely (in_error ()))
return;
- _create_old_gid_to_new_gid_map (face,
- input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS,
- &_glyphset,
- glyph_map,
- reverse_glyph_map,
- &_num_output_glyphs);
+ if (!check_success(_create_old_gid_to_new_gid_map(
+ face,
+ input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS,
+ &_glyphset,
+ &input->glyph_map,
+ glyph_map,
+ reverse_glyph_map,
+ &_num_output_glyphs))) {
+ return;
+ }
_create_glyph_map_gsub (
&_glyphset_gsub,
@@ -1060,7 +1106,13 @@ hb_subset_plan_t::hb_subset_plan_t (hb_face_t *face,
gid_to_unicodes,
unicodes,
has_seac);
+
+ check_success (inprogress_accelerator);
}
+
+#define HB_SUBSET_PLAN_MEMBER(Type, Name) check_success (!Name.in_error ());
+#include "hb-subset-plan-member-list.hh"
+#undef HB_SUBSET_PLAN_MEMBER
}
/**
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh
index e34eeb89ae..19470ff83e 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-subset-plan.hh
@@ -97,112 +97,30 @@ struct hb_subset_plan_t
bool attach_accelerator_data = false;
bool force_long_loca = false;
- // For each cp that we'd like to retain maps to the corresponding gid.
- hb_set_t unicodes;
- hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> unicode_to_new_gid_list;
-
- // name_ids we would like to retain
- hb_set_t name_ids;
-
- // name_languages we would like to retain
- hb_set_t name_languages;
-
- //layout features which will be preserved
- hb_set_t layout_features;
-
- // layout scripts which will be preserved.
- hb_set_t layout_scripts;
-
- //glyph ids requested to retain
- hb_set_t glyphs_requested;
-
- // Tables which should not be processed, just pass them through.
- hb_set_t no_subset_tables;
-
- // Tables which should be dropped.
- hb_set_t drop_tables;
-
// The glyph subset
hb_map_t *codepoint_to_glyph; // Needs to be heap-allocated
// Old -> New glyph id mapping
hb_map_t *glyph_map; // Needs to be heap-allocated
hb_map_t *reverse_glyph_map; // Needs to be heap-allocated
- hb_map_t glyph_map_gsub;
// Plan is only good for a specific source/dest so keep them with it
hb_face_t *source;
hb_face_t *dest;
unsigned int _num_output_glyphs;
- hb_set_t _glyphset;
- hb_set_t _glyphset_gsub;
- hb_set_t _glyphset_mathed;
- hb_set_t _glyphset_colred;
-
- //active lookups we'd like to retain
- hb_map_t gsub_lookups;
- hb_map_t gpos_lookups;
-
- //active langsys we'd like to retain
- hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> gsub_langsys;
- hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> gpos_langsys;
-
- //active features after removing redundant langsys and prune_features
- hb_map_t gsub_features;
- hb_map_t gpos_features;
-
- //active feature variation records/condition index with variations
- hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> gsub_feature_record_cond_idx_map;
- hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> gpos_feature_record_cond_idx_map;
-
- //feature index-> address of substituation feature table mapping with
- //variations
- hb_hashmap_t<unsigned, const OT::Feature*> gsub_feature_substitutes_map;
- hb_hashmap_t<unsigned, const OT::Feature*> gpos_feature_substitutes_map;
-
- //active layers/palettes we'd like to retain
- hb_map_t colrv1_layers;
- hb_map_t colr_palettes;
-
- //Old layout item variation index -> (New varidx, delta) mapping
- hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> layout_variation_idx_delta_map;
-
- //gdef varstore retained varidx mapping
- hb_vector_t<hb_inc_bimap_t> gdef_varstore_inner_maps;
-
- hb_hashmap_t<hb_tag_t, hb::unique_ptr<hb_blob_t>> sanitized_table_cache;
- //normalized axes location map
- hb_hashmap_t<hb_tag_t, int> axes_location;
- hb_vector_t<int> normalized_coords;
- //user specified axes location map
- hb_hashmap_t<hb_tag_t, float> user_axes_location;
- //retained old axis index -> new axis index mapping in fvar axis array
- hb_map_t axes_index_map;
- //axis_index->axis_tag mapping in fvar axis array
- hb_map_t axes_old_index_tag_map;
+
bool all_axes_pinned;
bool pinned_at_default;
bool has_seac;
- //hmtx metrics map: new gid->(advance, lsb)
- mutable hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> hmtx_map;
- //vmtx metrics map: new gid->(advance, lsb)
- mutable hb_hashmap_t<hb_codepoint_t, hb_pair_t<unsigned, int>> vmtx_map;
- //boundsWidth map: new gid->boundsWidth, boundWidth=xMax - xMin
- mutable hb_map_t bounds_width_map;
- //boundsHeight map: new gid->boundsHeight, boundsHeight=yMax - yMin
- mutable hb_map_t bounds_height_map;
+#define HB_SUBSET_PLAN_MEMBER(Type, Name) Type Name;
+#include "hb-subset-plan-member-list.hh"
+#undef HB_SUBSET_PLAN_MEMBER
//recalculated head/maxp table info after instancing
mutable head_maxp_info_t head_maxp_info;
-#ifdef HB_EXPERIMENTAL_API
- // name table overrides map: hb_ot_name_record_ids_t-> name string new value or
- // None to indicate should remove
- hb_hashmap_t<hb_ot_name_record_ids_t, hb_bytes_t> name_table_overrides;
-#endif
-
const hb_subset_accelerator_t* accelerator;
hb_subset_accelerator_t* inprogress_accelerator;
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset.cc b/src/3rdparty/harfbuzz-ng/src/hb-subset.cc
index 5ea422983c..9c066e6d78 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset.cc
+++ b/src/3rdparty/harfbuzz-ng/src/hb-subset.cc
@@ -96,8 +96,8 @@ static hb_tag_t known_tables[] {
HB_OT_TAG_BASE,
HB_OT_TAG_CBDT,
HB_OT_TAG_CBLC,
- HB_OT_TAG_cff1,
- HB_OT_TAG_cff2,
+ HB_OT_TAG_CFF1,
+ HB_OT_TAG_CFF2,
HB_OT_TAG_cmap,
HB_OT_TAG_COLR,
HB_OT_TAG_CPAL,
@@ -457,8 +457,8 @@ _subset_table (hb_subset_plan_t *plan,
case HB_OT_TAG_MATH: return _subset<const OT::MATH> (plan, buf);
#ifndef HB_NO_SUBSET_CFF
- case HB_OT_TAG_cff1: return _subset<const OT::cff1> (plan, buf);
- case HB_OT_TAG_cff2: return _subset<const OT::cff2> (plan, buf);
+ case HB_OT_TAG_CFF1: return _subset<const OT::cff1> (plan, buf);
+ case HB_OT_TAG_CFF2: return _subset<const OT::cff2> (plan, buf);
case HB_OT_TAG_VORG: return _subset<const OT::VORG> (plan, buf);
#endif
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-subset.h b/src/3rdparty/harfbuzz-ng/src/hb-subset.h
index 41d9587052..6368ff93f0 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-subset.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-subset.h
@@ -154,6 +154,9 @@ hb_subset_input_glyph_set (hb_subset_input_t *input);
HB_EXTERN hb_set_t *
hb_subset_input_set (hb_subset_input_t *input, hb_subset_sets_t set_type);
+HB_EXTERN hb_map_t*
+hb_subset_input_old_to_new_glyph_mapping (hb_subset_input_t *input);
+
HB_EXTERN hb_subset_flags_t
hb_subset_input_get_flags (hb_subset_input_t *input);
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-vector.hh b/src/3rdparty/harfbuzz-ng/src/hb-vector.hh
index 58d467a405..d61ce48c01 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-vector.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb-vector.hh
@@ -290,13 +290,11 @@ struct hb_vector_t
copy_vector (const hb_vector_t &other)
{
length = other.length;
-#ifndef HB_OPTIMIZE_SIZE
- if (sizeof (T) >= sizeof (long long))
+ if (!HB_OPTIMIZE_SIZE_VAL && sizeof (T) >= sizeof (long long))
/* This runs faster because of alignment. */
for (unsigned i = 0; i < length; i++)
arrayZ[i] = other.arrayZ[i];
else
-#endif
hb_memcpy ((void *) arrayZ, (const void *) other.arrayZ, length * item_size);
}
template <typename T = Type,
diff --git a/src/3rdparty/harfbuzz-ng/src/hb-version.h b/src/3rdparty/harfbuzz-ng/src/hb-version.h
index e4be376bc6..08d1f55a35 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb-version.h
+++ b/src/3rdparty/harfbuzz-ng/src/hb-version.h
@@ -47,7 +47,7 @@ HB_BEGIN_DECLS
*
* The minor component of the library version available at compile-time.
*/
-#define HB_VERSION_MINOR 2
+#define HB_VERSION_MINOR 3
/**
* HB_VERSION_MICRO:
*
@@ -60,7 +60,7 @@ HB_BEGIN_DECLS
*
* A string literal containing the library version available at compile-time.
*/
-#define HB_VERSION_STRING "7.2.0"
+#define HB_VERSION_STRING "7.3.0"
/**
* HB_VERSION_ATLEAST:
diff --git a/src/3rdparty/harfbuzz-ng/src/hb.hh b/src/3rdparty/harfbuzz-ng/src/hb.hh
index 30b3de499a..205f8cf196 100644
--- a/src/3rdparty/harfbuzz-ng/src/hb.hh
+++ b/src/3rdparty/harfbuzz-ng/src/hb.hh
@@ -255,8 +255,8 @@ extern "C" void hb_free_impl(void *ptr);
#endif
#if defined(__OPTIMIZE__) && hb_has_builtin(__builtin_expect)
-#define likely(expr) (__builtin_expect (!!(expr), 1))
-#define unlikely(expr) (__builtin_expect (!!(expr), 0))
+#define likely(expr) __builtin_expect (bool(expr), 1)
+#define unlikely(expr) __builtin_expect (bool(expr), 0)
#else
#define likely(expr) (expr)
#define unlikely(expr) (expr)
diff --git a/src/3rdparty/harfbuzz-ng/src/main.cc b/src/3rdparty/harfbuzz-ng/src/main.cc
deleted file mode 100644
index edc9872eed..0000000000
--- a/src/3rdparty/harfbuzz-ng/src/main.cc
+++ /dev/null
@@ -1,532 +0,0 @@
-/*
- * Copyright © 2007,2008,2009 Red Hat, Inc.
- * Copyright © 2018,2019,2020 Ebrahim Byagowi
- * Copyright © 2018 Khaled Hosny
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Red Hat Author(s): Behdad Esfahbod
- */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "hb.h"
-#include "hb-ot.h"
-
-#include <cassert>
-#include <cstdlib>
-#include <cstdio>
-#include <cstring>
-
-#ifdef HB_NO_OPEN
-#define hb_blob_create_from_file_or_fail(x) hb_blob_get_empty ()
-#endif
-
-#if !defined(HB_NO_COLOR) && !defined(HB_NO_DRAW)
-static void
-svg_dump (hb_face_t *face, unsigned face_index)
-{
- unsigned glyph_count = hb_face_get_glyph_count (face);
-
- for (unsigned glyph_id = 0; glyph_id < glyph_count; ++glyph_id)
- {
- hb_blob_t *blob = hb_ot_color_glyph_reference_svg (face, glyph_id);
-
- if (hb_blob_get_length (blob) == 0) continue;
-
- unsigned length;
- const char *data = hb_blob_get_data (blob, &length);
-
- char output_path[255];
- snprintf (output_path, sizeof output_path,
- "out/svg-%u-%u.svg%s",
- glyph_id,
- face_index,
- // append "z" if the content is gzipped, https://stackoverflow.com/a/6059405
- (length > 2 && (data[0] == '\x1F') && (data[1] == '\x8B')) ? "z" : "");
-
- FILE *f = fopen (output_path, "wb");
- fwrite (data, 1, length, f);
- fclose (f);
-
- hb_blob_destroy (blob);
- }
-}
-
-/* _png API is so easy to use unlike the below code, don't get confused */
-static void
-png_dump (hb_face_t *face, unsigned face_index)
-{
- unsigned glyph_count = hb_face_get_glyph_count (face);
- hb_font_t *font = hb_font_create (face);
-
- /* scans the font for strikes */
- unsigned sample_glyph_id;
- /* we don't care about different strikes for different glyphs at this point */
- for (sample_glyph_id = 0; sample_glyph_id < glyph_count; ++sample_glyph_id)
- {
- hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id);
- unsigned blob_length = hb_blob_get_length (blob);
- hb_blob_destroy (blob);
- if (blob_length != 0)
- break;
- }
-
- unsigned upem = hb_face_get_upem (face);
- unsigned blob_length = 0;
- unsigned strike = 0;
- for (unsigned ppem = 1; ppem < upem; ++ppem)
- {
- hb_font_set_ppem (font, ppem, ppem);
- hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, sample_glyph_id);
- unsigned new_blob_length = hb_blob_get_length (blob);
- hb_blob_destroy (blob);
- if (new_blob_length != blob_length)
- {
- for (unsigned glyph_id = 0; glyph_id < glyph_count; ++glyph_id)
- {
- hb_blob_t *blob = hb_ot_color_glyph_reference_png (font, glyph_id);
-
- if (hb_blob_get_length (blob) == 0) continue;
-
- unsigned length;
- const char *data = hb_blob_get_data (blob, &length);
-
- char output_path[255];
- snprintf (output_path, sizeof output_path, "out/png-%u-%u-%u.png", glyph_id, strike, face_index);
-
- FILE *f = fopen (output_path, "wb");
- fwrite (data, 1, length, f);
- fclose (f);
-
- hb_blob_destroy (blob);
- }
-
- strike++;
- blob_length = new_blob_length;
- }
- }
-
- hb_font_destroy (font);
-}
-
-struct draw_data_t
-{
- FILE *f;
- hb_position_t ascender;
-};
-
-static void
-move_to (hb_draw_funcs_t *, draw_data_t *draw_data,
- hb_draw_state_t *,
- float to_x, float to_y,
- void *)
-{
- fprintf (draw_data->f, "M%g,%g", to_x, draw_data->ascender - to_y);
-}
-
-static void
-line_to (hb_draw_funcs_t *, draw_data_t *draw_data,
- hb_draw_state_t *,
- float to_x, float to_y,
- void *)
-{
- fprintf (draw_data->f, "L%g,%g", to_x, draw_data->ascender - to_y);
-}
-
-static void
-quadratic_to (hb_draw_funcs_t *, draw_data_t *draw_data,
- hb_draw_state_t *,
- float control_x, float control_y,
- float to_x, float to_y,
- void *)
-{
- fprintf (draw_data->f, "Q%g,%g %g,%g", control_x, draw_data->ascender - control_y,
- to_x, draw_data->ascender - to_y);
-}
-
-static void
-cubic_to (hb_draw_funcs_t *, draw_data_t *draw_data,
- hb_draw_state_t *,
- float control1_x, float control1_y,
- float control2_x, float control2_y,
- float to_x, float to_y,
- void *)
-{
- fprintf (draw_data->f, "C%g,%g %g,%g %g,%g", control1_x, draw_data->ascender - control1_y,
- control2_x, draw_data->ascender - control2_y,
- to_x, draw_data->ascender - to_y);
-}
-
-static void
-close_path (hb_draw_funcs_t *, draw_data_t *draw_data,
- hb_draw_state_t *,
- void *)
-{
- fprintf (draw_data->f, "Z");
-}
-
-static void
-layered_glyph_dump (hb_font_t *font, hb_draw_funcs_t *funcs, unsigned face_index)
-{
- hb_face_t *face = hb_font_get_face (font);
- unsigned palette_count = hb_ot_color_palette_get_count (face);
- for (unsigned palette = 0; palette < palette_count; ++palette)
- {
- unsigned num_colors = hb_ot_color_palette_get_colors (face, palette, 0, nullptr, nullptr);
- if (!num_colors) continue;
-
- hb_color_t *colors = (hb_color_t*) calloc (num_colors, sizeof (hb_color_t));
- hb_ot_color_palette_get_colors (face, palette, 0, &num_colors, colors);
- if (!num_colors)
- {
- free (colors);
- continue;
- }
-
- unsigned num_glyphs = hb_face_get_glyph_count (face);
- for (hb_codepoint_t gid = 0; gid < num_glyphs; ++gid)
- {
- unsigned num_layers = hb_ot_color_glyph_get_layers (face, gid, 0, nullptr, nullptr);
- if (!num_layers) continue;
-
- hb_ot_color_layer_t *layers = (hb_ot_color_layer_t*) malloc (num_layers * sizeof (hb_ot_color_layer_t));
-
- hb_ot_color_glyph_get_layers (face, gid, 0, &num_layers, layers);
- if (num_layers)
- {
- hb_font_extents_t font_extents;
- hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents);
- hb_glyph_extents_t extents = {0};
- if (!hb_font_get_glyph_extents (font, gid, &extents))
- {
- printf ("Skip gid: %u\n", gid);
- continue;
- }
-
- char output_path[255];
- snprintf (output_path, sizeof output_path, "out/colr-%u-%u-%u.svg", gid, palette, face_index);
- FILE *f = fopen (output_path, "wb");
- fprintf (f, "<svg xmlns=\"http://www.w3.org/2000/svg\""
- " viewBox=\"%d %d %d %d\">\n",
- extents.x_bearing, 0,
- extents.x_bearing + extents.width, -extents.height);
- draw_data_t draw_data;
- draw_data.ascender = extents.y_bearing;
- draw_data.f = f;
-
- for (unsigned layer = 0; layer < num_layers; ++layer)
- {
- hb_color_t color = 0x000000FF;
- if (layers[layer].color_index != 0xFFFF)
- color = colors[layers[layer].color_index];
- fprintf (f, "<path fill=\"#%02X%02X%02X\" ",
- hb_color_get_red (color), hb_color_get_green (color), hb_color_get_green (color));
- if (hb_color_get_alpha (color) != 255)
- fprintf (f, "fill-opacity=\"%.3f\"", (double) hb_color_get_alpha (color) / 255.);
- fprintf (f, "d=\"");
- hb_font_get_glyph_shape (font, layers[layer].glyph, funcs, &draw_data);
- fprintf (f, "\"/>\n");
- }
-
- fprintf (f, "</svg>");
- fclose (f);
- }
- free (layers);
- }
-
- free (colors);
- }
-}
-
-static void
-dump_glyphs (hb_font_t *font, hb_draw_funcs_t *funcs, unsigned face_index)
-{
- unsigned num_glyphs = hb_face_get_glyph_count (hb_font_get_face (font));
- for (unsigned gid = 0; gid < num_glyphs; ++gid)
- {
- hb_font_extents_t font_extents;
- hb_font_get_extents_for_direction (font, HB_DIRECTION_LTR, &font_extents);
- hb_glyph_extents_t extents = {0};
- if (!hb_font_get_glyph_extents (font, gid, &extents))
- {
- printf ("Skip gid: %u\n", gid);
- continue;
- }
-
- char output_path[255];
- snprintf (output_path, sizeof output_path, "out/%u-%u.svg", face_index, gid);
- FILE *f = fopen (output_path, "wb");
- fprintf (f, "<svg xmlns=\"http://www.w3.org/2000/svg\""
- " viewBox=\"%d %d %d %d\"><path d=\"",
- extents.x_bearing, 0,
- extents.x_bearing + extents.width, font_extents.ascender - font_extents.descender);
- draw_data_t draw_data;
- draw_data.ascender = font_extents.ascender;
- draw_data.f = f;
- hb_font_get_glyph_shape (font, gid, funcs, &draw_data);
- fprintf (f, "\"/></svg>");
- fclose (f);
- }
-}
-
-static void
-dump_glyphs (hb_blob_t *blob, const char *font_name)
-{
- FILE *font_name_file = fopen ("out/.dumped_font_name", "r");
- if (font_name_file)
- {
- fprintf (stderr, "Purge or rename ./out folder if you like to run a glyph dump,\n"
- "run it like `rm -rf out && mkdir out && src/main font-file.ttf`\n");
- return;
- }
-
- font_name_file = fopen ("out/.dumped_font_name", "w");
- if (!font_name_file)
- {
- fprintf (stderr, "./out is not accessible as a folder, create it please\n");
- return;
- }
- fwrite (font_name, 1, strlen (font_name), font_name_file);
- fclose (font_name_file);
-
- hb_draw_funcs_t *funcs = hb_draw_funcs_create ();
- hb_draw_funcs_set_move_to_func (funcs, (hb_draw_move_to_func_t) move_to, nullptr, nullptr);
- hb_draw_funcs_set_line_to_func (funcs, (hb_draw_line_to_func_t) line_to, nullptr, nullptr);
- hb_draw_funcs_set_quadratic_to_func (funcs, (hb_draw_quadratic_to_func_t) quadratic_to, nullptr, nullptr);
- hb_draw_funcs_set_cubic_to_func (funcs, (hb_draw_cubic_to_func_t) cubic_to, nullptr, nullptr);
- hb_draw_funcs_set_close_path_func (funcs, (hb_draw_close_path_func_t) close_path, nullptr, nullptr);
-
- unsigned num_faces = hb_face_count (blob);
- for (unsigned face_index = 0; face_index < num_faces; ++face_index)
- {
- hb_face_t *face = hb_face_create (blob, face_index);
- hb_font_t *font = hb_font_create (face);
-
- if (hb_ot_color_has_png (face))
- printf ("Dumping png (CBDT/sbix)...\n");
- png_dump (face, face_index);
-
- if (hb_ot_color_has_svg (face))
- printf ("Dumping svg (SVG )...\n");
- svg_dump (face, face_index);
-
- if (hb_ot_color_has_layers (face) && hb_ot_color_has_palettes (face))
- printf ("Dumping layered color glyphs (COLR/CPAL)...\n");
- layered_glyph_dump (font, funcs, face_index);
-
- dump_glyphs (font, funcs, face_index);
-
- hb_font_destroy (font);
- hb_face_destroy (face);
- }
-
- hb_draw_funcs_destroy (funcs);
-}
-#endif
-
-#ifndef MAIN_CC_NO_PRIVATE_API
-/* Only this part of this mini app uses private API */
-#include "hb-static.cc"
-#include "hb-open-file.hh"
-#include "hb-ot-layout-gdef-table.hh"
-#include "hb-ot-layout-gsubgpos.hh"
-
-using namespace OT;
-
-static void
-print_layout_info_using_private_api (hb_blob_t *blob)
-{
- const char *font_data = hb_blob_get_data (blob, nullptr);
- hb_blob_t *font_blob = hb_sanitize_context_t ().sanitize_blob<OpenTypeFontFile> (blob);
- const OpenTypeFontFile* sanitized = font_blob->as<OpenTypeFontFile> ();
- if (!font_blob->data)
- {
- printf ("Sanitization of the file wasn't successful. Exit");
- exit (1);
- }
- const OpenTypeFontFile& ot = *sanitized;
-
- switch (ot.get_tag ())
- {
- case OpenTypeFontFile::TrueTypeTag:
- printf ("OpenType font with TrueType outlines\n");
- break;
- case OpenTypeFontFile::CFFTag:
- printf ("OpenType font with CFF (Type1) outlines\n");
- break;
- case OpenTypeFontFile::TTCTag:
- printf ("TrueType Collection of OpenType fonts\n");
- break;
- case OpenTypeFontFile::TrueTag:
- printf ("Obsolete Apple TrueType font\n");
- break;
- case OpenTypeFontFile::Typ1Tag:
- printf ("Obsolete Apple Type1 font in SFNT container\n");
- break;
- case OpenTypeFontFile::DFontTag:
- printf ("DFont Mac Resource Fork\n");
- break;
- default:
- printf ("Unknown font format\n");
- break;
- }
-
- unsigned num_faces = hb_face_count (blob);
- printf ("%u font(s) found in file\n", num_faces);
- for (unsigned n_font = 0; n_font < num_faces; ++n_font)
- {
- const OpenTypeFontFace &font = ot.get_face (n_font);
- printf ("Font %u of %u:\n", n_font, num_faces);
-
- unsigned num_tables = font.get_table_count ();
- printf (" %u table(s) found in font\n", num_tables);
- for (unsigned n_table = 0; n_table < num_tables; ++n_table)
- {
- const OpenTypeTable &table = font.get_table (n_table);
- printf (" Table %2u of %2u: %.4s (0x%08x+0x%08x)\n", n_table, num_tables,
- (const char *) table.tag,
- (unsigned) table.offset,
- (unsigned) table.length);
-
- switch (table.tag)
- {
-
- case HB_OT_TAG_GSUB:
- case HB_OT_TAG_GPOS:
- {
-
- const GSUBGPOS &g = *reinterpret_cast<const GSUBGPOS *> (font_data + table.offset);
-
- unsigned num_scripts = g.get_script_count ();
- printf (" %u script(s) found in table\n", num_scripts);
- for (unsigned n_script = 0; n_script < num_scripts; ++n_script)
- {
- const Script &script = g.get_script (n_script);
- printf (" Script %2u of %2u: %.4s\n", n_script, num_scripts,
- (const char *) g.get_script_tag (n_script));
-
- if (!script.has_default_lang_sys ())
- printf (" No default language system\n");
- int num_langsys = script.get_lang_sys_count ();
- printf (" %d language system(s) found in script\n", num_langsys);
- for (int n_langsys = script.has_default_lang_sys () ? -1 : 0; n_langsys < num_langsys; ++n_langsys)
- {
- const LangSys &langsys = n_langsys == -1
- ? script.get_default_lang_sys ()
- : script.get_lang_sys (n_langsys);
- if (n_langsys == -1)
- printf (" Default Language System\n");
- else
- printf (" Language System %2d of %2d: %.4s\n", n_langsys, num_langsys,
- (const char *) script.get_lang_sys_tag (n_langsys));
- if (!langsys.has_required_feature ())
- printf (" No required feature\n");
- else
- printf (" Required feature index: %u\n",
- langsys.get_required_feature_index ());
-
- unsigned num_features = langsys.get_feature_count ();
- printf (" %u feature(s) found in language system\n", num_features);
- for (unsigned n_feature = 0; n_feature < num_features; ++n_feature)
- {
- printf (" Feature index %2u of %2u: %u\n", n_feature, num_features,
- langsys.get_feature_index (n_feature));
- }
- }
- }
-
- unsigned num_features = g.get_feature_count ();
- printf (" %u feature(s) found in table\n", num_features);
- for (unsigned n_feature = 0; n_feature < num_features; ++n_feature)
- {
- const Feature &feature = g.get_feature (n_feature);
- unsigned num_lookups = feature.get_lookup_count ();
- printf (" Feature %2u of %2u: %c%c%c%c\n", n_feature, num_features,
- HB_UNTAG (g.get_feature_tag (n_feature)));
-
- printf (" %u lookup(s) found in feature\n", num_lookups);
- for (unsigned n_lookup = 0; n_lookup < num_lookups; ++n_lookup) {
- printf (" Lookup index %2u of %2u: %u\n", n_lookup, num_lookups,
- feature.get_lookup_index (n_lookup));
- }
- }
-
- unsigned num_lookups = g.get_lookup_count ();
- printf (" %u lookup(s) found in table\n", num_lookups);
- for (unsigned n_lookup = 0; n_lookup < num_lookups; ++n_lookup)
- {
- const Lookup &lookup = g.get_lookup (n_lookup);
- printf (" Lookup %2u of %2u: type %u, props 0x%04X\n", n_lookup, num_lookups,
- lookup.get_type (), lookup.get_props ());
- }
-
- }
- break;
-
- case GDEF::tableTag:
- {
-
- const GDEF &gdef = *reinterpret_cast<const GDEF *> (font_data + table.offset);
-
- printf (" Has %sglyph classes\n",
- gdef.has_glyph_classes () ? "" : "no ");
- printf (" Has %smark attachment types\n",
- gdef.has_mark_attachment_types () ? "" : "no ");
- printf (" Has %sattach list\n",
- gdef.has_attach_list () ? "" : "no ");
- printf (" Has %slig carets\n",
- gdef.has_lig_carets () ? "" : "no ");
- printf (" Has %smark glyph sets\n",
- gdef.has_mark_glyph_sets () ? "" : "no ");
- break;
- }
- }
- }
- }
-}
-/* end of private API use */
-#endif
-
-int
-main (int argc, char **argv)
-{
- if (argc != 2)
- {
- fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]);
- exit (1);
- }
-
- hb_blob_t *blob = hb_blob_create_from_file_or_fail (argv[1]);
- assert (blob);
- printf ("Opened font file %s: %u bytes long\n", argv[1], hb_blob_get_length (blob));
-#ifndef MAIN_CC_NO_PRIVATE_API
- print_layout_info_using_private_api (blob);
-#endif
-#if !defined(HB_NO_COLOR) && !defined(HB_NO_DRAW)
- dump_glyphs (blob, argv[1]);
-#endif
- hb_blob_destroy (blob);
-
- return 0;
-}
diff --git a/src/3rdparty/harfbuzz-ng/src/test.cc b/src/3rdparty/harfbuzz-ng/src/test.cc
deleted file mode 100644
index f7e4e7ecde..0000000000
--- a/src/3rdparty/harfbuzz-ng/src/test.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright © 2010,2011 Google, Inc.
- *
- * This is part of HarfBuzz, a text shaping library.
- *
- * Permission is hereby granted, without written agreement and without
- * license or royalty fees, to use, copy, modify, and distribute this
- * software and its documentation for any purpose, provided that the
- * above copyright notice and the following two paragraphs appear in
- * all copies of this software.
- *
- * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
- * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
- * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
- * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
- * DAMAGE.
- *
- * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
- * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS
- * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
- * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
- *
- * Google Author(s): Behdad Esfahbod
- */
-
-#include "hb.hh"
-
-#ifdef HAVE_FREETYPE
-#include "hb-ft.h"
-#endif
-
-#ifdef HB_NO_OPEN
-#define hb_blob_create_from_file_or_fail(x) hb_blob_get_empty ()
-#endif
-
-int
-main (int argc, char **argv)
-{
- if (argc != 2) {
- fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]);
- exit (1);
- }
-
- hb_blob_t *blob = hb_blob_create_from_file_or_fail (argv[1]);
- assert (blob);
- printf ("Opened font file %s: %u bytes long\n", argv[1], hb_blob_get_length (blob));
-
- /* Create the face */
- hb_face_t *face = hb_face_create (blob, 0 /* first face */);
- hb_blob_destroy (blob);
- blob = nullptr;
- unsigned int upem = hb_face_get_upem (face);
-
- hb_font_t *font = hb_font_create (face);
- hb_font_set_scale (font, upem, upem);
-
-#ifdef HAVE_FREETYPE
- hb_ft_font_set_funcs (font);
-#endif
-
- hb_buffer_t *buffer = hb_buffer_create ();
-
- hb_buffer_add_utf8 (buffer, "\xe0\xa4\x95\xe0\xa5\x8d\xe0\xa4\xb0\xe0\xa5\x8d\xe0\xa4\x95", -1, 0, -1);
- hb_buffer_guess_segment_properties (buffer);
-
- hb_shape (font, buffer, nullptr, 0);
-
- unsigned int count = hb_buffer_get_length (buffer);
- hb_glyph_info_t *infos = hb_buffer_get_glyph_infos (buffer, nullptr);
- hb_glyph_position_t *positions = hb_buffer_get_glyph_positions (buffer, nullptr);
-
- for (unsigned int i = 0; i < count; i++)
- {
- hb_glyph_info_t *info = &infos[i];
- hb_glyph_position_t *pos = &positions[i];
-
- printf ("cluster %u glyph 0x%x at (%d,%d)+(%d,%d)\n",
- info->cluster,
- info->codepoint,
- pos->x_offset,
- pos->y_offset,
- pos->x_advance,
- pos->y_advance);
-
- }
-
- hb_buffer_destroy (buffer);
- hb_font_destroy (font);
- hb_face_destroy (face);
-
- return 0;
-}
-
-