You've already forked godot
mirror of
https://github.com/godotengine/godot.git
synced 2025-11-10 13:00:37 +00:00
HarfBuzz: Update to version 5.3.1
This commit is contained in:
2
thirdparty/README.md
vendored
2
thirdparty/README.md
vendored
@@ -214,7 +214,7 @@ Files extracted from upstream source:
|
|||||||
## harfbuzz
|
## harfbuzz
|
||||||
|
|
||||||
- Upstream: https://github.com/harfbuzz/harfbuzz
|
- Upstream: https://github.com/harfbuzz/harfbuzz
|
||||||
- Version: 5.2.0 (4a1d891c6317d2c83e5f3c2607ec5f5ccedffcde, 2022)
|
- Version: 5.3.1 (970321db7bddbe8c579b73751fc655a924ea3ce6, 2022)
|
||||||
- License: MIT
|
- License: MIT
|
||||||
|
|
||||||
Files extracted from upstream source:
|
Files extracted from upstream source:
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ struct GPOS : GSUBGPOS
|
|||||||
|
|
||||||
bool subset (hb_subset_context_t *c) const
|
bool subset (hb_subset_context_t *c) const
|
||||||
{
|
{
|
||||||
hb_subset_layout_context_t l (c, tableTag, c->plan->gpos_lookups, c->plan->gpos_langsys, c->plan->gpos_features);
|
hb_subset_layout_context_t l (c, tableTag);
|
||||||
return GSUBGPOS::subset<PosLookup> (&l);
|
return GSUBGPOS::subset<PosLookup> (&l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -80,6 +80,24 @@ struct SinglePosFormat1
|
|||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
position_single (hb_font_t *font,
|
||||||
|
hb_direction_t direction,
|
||||||
|
hb_codepoint_t gid,
|
||||||
|
hb_glyph_position_t &pos) const
|
||||||
|
{
|
||||||
|
unsigned int index = (this+coverage).get_coverage (gid);
|
||||||
|
if (likely (index == NOT_COVERED)) return false;
|
||||||
|
|
||||||
|
/* This is ugly... */
|
||||||
|
hb_buffer_t buffer;
|
||||||
|
buffer.props.direction = direction;
|
||||||
|
OT::hb_ot_apply_context_t c (1, font, &buffer);
|
||||||
|
|
||||||
|
valueFormat.apply_value (&c, this, values, pos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
template<typename Iterator,
|
template<typename Iterator,
|
||||||
typename SrcLookup,
|
typename SrcLookup,
|
||||||
hb_requires (hb_is_iterator (Iterator))>
|
hb_requires (hb_is_iterator (Iterator))>
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ struct SinglePosFormat2
|
|||||||
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
|
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
|
||||||
if (likely (index == NOT_COVERED)) return_trace (false);
|
if (likely (index == NOT_COVERED)) return_trace (false);
|
||||||
|
|
||||||
if (likely (index >= valueCount)) return_trace (false);
|
if (unlikely (index >= valueCount)) return_trace (false);
|
||||||
|
|
||||||
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
|
||||||
{
|
{
|
||||||
@@ -92,6 +92,28 @@ struct SinglePosFormat2
|
|||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
position_single (hb_font_t *font,
|
||||||
|
hb_direction_t direction,
|
||||||
|
hb_codepoint_t gid,
|
||||||
|
hb_glyph_position_t &pos) const
|
||||||
|
{
|
||||||
|
unsigned int index = (this+coverage).get_coverage (gid);
|
||||||
|
if (likely (index == NOT_COVERED)) return false;
|
||||||
|
if (unlikely (index >= valueCount)) return false;
|
||||||
|
|
||||||
|
/* This is ugly... */
|
||||||
|
hb_buffer_t buffer;
|
||||||
|
buffer.props.direction = direction;
|
||||||
|
OT::hb_ot_apply_context_t c (1, font, &buffer);
|
||||||
|
|
||||||
|
valueFormat.apply_value (&c, this,
|
||||||
|
&values[index * valueFormat.get_len ()],
|
||||||
|
pos);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
template<typename Iterator,
|
template<typename Iterator,
|
||||||
typename SrcLookup,
|
typename SrcLookup,
|
||||||
hb_requires (hb_is_iterator (Iterator))>
|
hb_requires (hb_is_iterator (Iterator))>
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ struct GSUB : GSUBGPOS
|
|||||||
|
|
||||||
bool subset (hb_subset_context_t *c) const
|
bool subset (hb_subset_context_t *c) const
|
||||||
{
|
{
|
||||||
hb_subset_layout_context_t l (c, tableTag, c->plan->gsub_lookups, c->plan->gsub_langsys, c->plan->gsub_features);
|
hb_subset_layout_context_t l (c, tableTag);
|
||||||
return GSUBGPOS::subset<SubstLookup> (&l);
|
return GSUBGPOS::subset<SubstLookup> (&l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -118,7 +118,7 @@ struct Ligature
|
|||||||
match_positions[i] += delta;
|
match_positions[i] += delta;
|
||||||
if (i)
|
if (i)
|
||||||
*p++ = ',';
|
*p++ = ',';
|
||||||
sprintf (p, "%u", match_positions[i]);
|
snprintf (p, sizeof(buf), "%u", match_positions[i]);
|
||||||
p += strlen(p);
|
p += strlen(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -117,7 +117,7 @@ struct Sequence
|
|||||||
{
|
{
|
||||||
if (buf < p)
|
if (buf < p)
|
||||||
*p++ = ',';
|
*p++ = ',';
|
||||||
sprintf (p, "%u", i);
|
snprintf (p, sizeof(buf), "%u", i);
|
||||||
p += strlen(p);
|
p += strlen(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
58
thirdparty/harfbuzz/src/OT/glyf/Glyph.hh
vendored
58
thirdparty/harfbuzz/src/OT/glyf/Glyph.hh
vendored
@@ -102,17 +102,19 @@ struct Glyph
|
|||||||
hb_bytes_t &dest_bytes /* OUT */) const
|
hb_bytes_t &dest_bytes /* OUT */) const
|
||||||
{
|
{
|
||||||
GlyphHeader *glyph_header = nullptr;
|
GlyphHeader *glyph_header = nullptr;
|
||||||
if (all_points.length > 4)
|
if (type != EMPTY && all_points.length > 4)
|
||||||
{
|
{
|
||||||
glyph_header = (GlyphHeader *) hb_calloc (1, GlyphHeader::static_size);
|
glyph_header = (GlyphHeader *) hb_calloc (1, GlyphHeader::static_size);
|
||||||
if (unlikely (!glyph_header)) return false;
|
if (unlikely (!glyph_header)) return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int xMin, xMax;
|
int xMin = 0, xMax = 0;
|
||||||
|
int yMin = 0, yMax = 0;
|
||||||
|
if (all_points.length > 4)
|
||||||
|
{
|
||||||
xMin = xMax = roundf (all_points[0].x);
|
xMin = xMax = roundf (all_points[0].x);
|
||||||
|
|
||||||
int yMin, yMax;
|
|
||||||
yMin = yMax = roundf (all_points[0].y);
|
yMin = yMax = roundf (all_points[0].y);
|
||||||
|
}
|
||||||
|
|
||||||
for (unsigned i = 1; i < all_points.length - 4; i++)
|
for (unsigned i = 1; i < all_points.length - 4; i++)
|
||||||
{
|
{
|
||||||
@@ -128,7 +130,7 @@ struct Glyph
|
|||||||
|
|
||||||
/*for empty glyphs: all_points only include phantom points.
|
/*for empty glyphs: all_points only include phantom points.
|
||||||
*just update metrics and then return */
|
*just update metrics and then return */
|
||||||
if (all_points.length == 4)
|
if (!glyph_header)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
glyph_header->numberOfContours = header->numberOfContours;
|
glyph_header->numberOfContours = header->numberOfContours;
|
||||||
@@ -145,10 +147,17 @@ struct Glyph
|
|||||||
hb_font_t *font,
|
hb_font_t *font,
|
||||||
const glyf_accelerator_t &glyf,
|
const glyf_accelerator_t &glyf,
|
||||||
hb_bytes_t &dest_start, /* IN/OUT */
|
hb_bytes_t &dest_start, /* IN/OUT */
|
||||||
hb_bytes_t &dest_end /* OUT */) const
|
hb_bytes_t &dest_end /* OUT */)
|
||||||
{
|
{
|
||||||
contour_point_vector_t all_points, deltas;
|
contour_point_vector_t all_points, deltas;
|
||||||
get_points (font, glyf, all_points, &deltas, false);
|
if (!get_points (font, glyf, all_points, &deltas, false, false))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// .notdef, set type to empty so we only update metrics and don't compile bytes for
|
||||||
|
// it
|
||||||
|
if (gid == 0 &&
|
||||||
|
!(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE))
|
||||||
|
type = EMPTY;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case COMPOSITE:
|
case COMPOSITE:
|
||||||
@@ -171,7 +180,12 @@ struct Glyph
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return compile_header_bytes (plan, all_points, dest_start);
|
if (!compile_header_bytes (plan, all_points, dest_start))
|
||||||
|
{
|
||||||
|
dest_end.fini ();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -182,6 +196,7 @@ struct Glyph
|
|||||||
bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator,
|
bool get_points (hb_font_t *font, const accelerator_t &glyf_accelerator,
|
||||||
contour_point_vector_t &all_points /* OUT */,
|
contour_point_vector_t &all_points /* OUT */,
|
||||||
contour_point_vector_t *deltas = nullptr, /* OUT */
|
contour_point_vector_t *deltas = nullptr, /* OUT */
|
||||||
|
bool shift_points_hori = true,
|
||||||
bool use_my_metrics = true,
|
bool use_my_metrics = true,
|
||||||
bool phantom_only = false,
|
bool phantom_only = false,
|
||||||
unsigned int depth = 0) const
|
unsigned int depth = 0) const
|
||||||
@@ -238,8 +253,7 @@ struct Glyph
|
|||||||
if (deltas != nullptr && depth == 0 && type == COMPOSITE)
|
if (deltas != nullptr && depth == 0 && type == COMPOSITE)
|
||||||
{
|
{
|
||||||
if (unlikely (!deltas->resize (points.length))) return false;
|
if (unlikely (!deltas->resize (points.length))) return false;
|
||||||
for (unsigned i = 0 ; i < points.length; i++)
|
deltas->copy_vector (points);
|
||||||
deltas->arrayZ[i] = points.arrayZ[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifndef HB_NO_VAR
|
#ifndef HB_NO_VAR
|
||||||
@@ -271,14 +285,9 @@ struct Glyph
|
|||||||
comp_points.reset ();
|
comp_points.reset ();
|
||||||
if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
|
if (unlikely (!glyf_accelerator.glyph_for_gid (item.get_gid ())
|
||||||
.get_points (font, glyf_accelerator, comp_points,
|
.get_points (font, glyf_accelerator, comp_points,
|
||||||
deltas, use_my_metrics, phantom_only, depth + 1)))
|
deltas, shift_points_hori, use_my_metrics, phantom_only, depth + 1)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* 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];
|
|
||||||
|
|
||||||
/* Apply component transformation & translation */
|
/* Apply component transformation & translation */
|
||||||
item.transform_points (comp_points);
|
item.transform_points (comp_points);
|
||||||
|
|
||||||
@@ -299,6 +308,11 @@ struct Glyph
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 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.sub_array (0, comp_points.length - PHANTOM_COUNT));
|
all_points.extend (comp_points.sub_array (0, comp_points.length - PHANTOM_COUNT));
|
||||||
|
|
||||||
comp_index++;
|
comp_index++;
|
||||||
@@ -310,7 +324,7 @@ struct Glyph
|
|||||||
all_points.extend (phantoms);
|
all_points.extend (phantoms);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (depth == 0) /* Apply at top level */
|
if (depth == 0 && shift_points_hori) /* Apply at top level */
|
||||||
{
|
{
|
||||||
/* Undocumented rasterizer behavior:
|
/* Undocumented rasterizer behavior:
|
||||||
* Shift points horizontally by the updated left side bearing
|
* Shift points horizontally by the updated left side bearing
|
||||||
@@ -332,8 +346,14 @@ struct Glyph
|
|||||||
|
|
||||||
hb_bytes_t get_bytes () const { return bytes; }
|
hb_bytes_t get_bytes () const { return bytes; }
|
||||||
|
|
||||||
Glyph (hb_bytes_t bytes_ = hb_bytes_t (),
|
Glyph () : bytes (),
|
||||||
hb_codepoint_t gid_ = (hb_codepoint_t) -1) : bytes (bytes_),
|
header (bytes.as<GlyphHeader> ()),
|
||||||
|
gid (-1),
|
||||||
|
type(EMPTY)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Glyph (hb_bytes_t bytes_,
|
||||||
|
hb_codepoint_t gid_ = (unsigned) -1) : bytes (bytes_),
|
||||||
header (bytes.as<GlyphHeader> ()),
|
header (bytes.as<GlyphHeader> ()),
|
||||||
gid (gid_)
|
gid (gid_)
|
||||||
{
|
{
|
||||||
|
|||||||
24
thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh
vendored
24
thirdparty/harfbuzz/src/OT/glyf/SimpleGlyph.hh
vendored
@@ -271,31 +271,29 @@ struct SimpleGlyph
|
|||||||
}
|
}
|
||||||
//convert absolute values to relative values
|
//convert absolute values to relative values
|
||||||
unsigned num_points = all_points.length - 4;
|
unsigned num_points = all_points.length - 4;
|
||||||
hb_vector_t<hb_pair_t<int, int>> deltas;
|
|
||||||
deltas.resize (num_points);
|
|
||||||
|
|
||||||
for (unsigned i = 0; i < num_points; i++)
|
|
||||||
{
|
|
||||||
deltas[i].first = i == 0 ? roundf (all_points[i].x) : roundf (all_points[i].x) - roundf (all_points[i-1].x);
|
|
||||||
deltas[i].second = i == 0 ? roundf (all_points[i].y) : roundf (all_points[i].y) - roundf (all_points[i-1].y);
|
|
||||||
}
|
|
||||||
|
|
||||||
hb_vector_t<uint8_t> flags, x_coords, y_coords;
|
hb_vector_t<uint8_t> flags, x_coords, y_coords;
|
||||||
flags.alloc (num_points);
|
if (unlikely (!flags.alloc (num_points))) return false;
|
||||||
x_coords.alloc (2*num_points);
|
if (unlikely (!x_coords.alloc (2*num_points))) return false;
|
||||||
y_coords.alloc (2*num_points);
|
if (unlikely (!y_coords.alloc (2*num_points))) return false;
|
||||||
|
|
||||||
uint8_t lastflag = 0, repeat = 0;
|
uint8_t lastflag = 0, repeat = 0;
|
||||||
|
int prev_x = 0.f, prev_y = 0.f;
|
||||||
|
|
||||||
for (unsigned i = 0; i < num_points; i++)
|
for (unsigned i = 0; i < num_points; i++)
|
||||||
{
|
{
|
||||||
uint8_t flag = all_points[i].flag;
|
uint8_t flag = all_points[i].flag;
|
||||||
flag &= FLAG_ON_CURVE + FLAG_OVERLAP_SIMPLE;
|
flag &= FLAG_ON_CURVE + FLAG_OVERLAP_SIMPLE;
|
||||||
|
|
||||||
encode_coord (deltas[i].first, flag, FLAG_X_SHORT, FLAG_X_SAME, x_coords);
|
float cur_x = roundf (all_points[i].x);
|
||||||
encode_coord (deltas[i].second, flag, FLAG_Y_SHORT, FLAG_Y_SAME, y_coords);
|
float cur_y = roundf (all_points[i].y);
|
||||||
|
encode_coord (cur_x - prev_x, flag, FLAG_X_SHORT, FLAG_X_SAME, x_coords);
|
||||||
|
encode_coord (cur_y - prev_y, flag, FLAG_Y_SHORT, FLAG_Y_SAME, y_coords);
|
||||||
if (i == 0) lastflag = flag + 1; //make lastflag != flag for the first point
|
if (i == 0) lastflag = flag + 1; //make lastflag != flag for the first point
|
||||||
encode_flag (flag, repeat, lastflag, flags);
|
encode_flag (flag, repeat, lastflag, flags);
|
||||||
|
|
||||||
|
prev_x = cur_x;
|
||||||
|
prev_y = cur_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned len_before_instrs = 2 * header.numberOfContours + 2;
|
unsigned len_before_instrs = 2 * header.numberOfContours + 2;
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ namespace glyf_impl {
|
|||||||
|
|
||||||
struct SubsetGlyph
|
struct SubsetGlyph
|
||||||
{
|
{
|
||||||
hb_codepoint_t new_gid;
|
|
||||||
hb_codepoint_t old_gid;
|
hb_codepoint_t old_gid;
|
||||||
Glyph source_glyph;
|
Glyph source_glyph;
|
||||||
hb_bytes_t dest_start; /* region of source_glyph to copy first */
|
hb_bytes_t dest_start; /* region of source_glyph to copy first */
|
||||||
|
|||||||
55
thirdparty/harfbuzz/src/OT/glyf/glyf.hh
vendored
55
thirdparty/harfbuzz/src/OT/glyf/glyf.hh
vendored
@@ -72,10 +72,13 @@ struct glyf
|
|||||||
if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false);
|
if (unlikely (!c->serializer->check_success (glyf_prime))) return_trace (false);
|
||||||
|
|
||||||
hb_vector_t<glyf_impl::SubsetGlyph> glyphs;
|
hb_vector_t<glyf_impl::SubsetGlyph> glyphs;
|
||||||
_populate_subset_glyphs (c->plan, &glyphs);
|
_populate_subset_glyphs (c->plan, glyphs);
|
||||||
|
|
||||||
if (!c->plan->pinned_at_default)
|
if (!c->plan->pinned_at_default)
|
||||||
_compile_subset_glyphs_with_deltas (c->plan, &glyphs);
|
{
|
||||||
|
if (!_compile_subset_glyphs_with_deltas (c->plan, &glyphs))
|
||||||
|
return_trace (false);
|
||||||
|
}
|
||||||
|
|
||||||
auto padded_offsets =
|
auto padded_offsets =
|
||||||
+ hb_iter (glyphs)
|
+ hb_iter (glyphs)
|
||||||
@@ -105,9 +108,9 @@ struct glyf
|
|||||||
|
|
||||||
void
|
void
|
||||||
_populate_subset_glyphs (const hb_subset_plan_t *plan,
|
_populate_subset_glyphs (const hb_subset_plan_t *plan,
|
||||||
hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const;
|
hb_vector_t<glyf_impl::SubsetGlyph> &glyphs /* OUT */) const;
|
||||||
|
|
||||||
void
|
bool
|
||||||
_compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan,
|
_compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan,
|
||||||
hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const;
|
hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const;
|
||||||
|
|
||||||
@@ -180,7 +183,7 @@ struct glyf_accelerator_t
|
|||||||
contour_point_vector_t all_points;
|
contour_point_vector_t all_points;
|
||||||
|
|
||||||
bool phantom_only = !consumer.is_consuming_contour_points ();
|
bool phantom_only = !consumer.is_consuming_contour_points ();
|
||||||
if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, nullptr, true, phantom_only)))
|
if (unlikely (!glyph_for_gid (gid).get_points (font, *this, all_points, nullptr, true, true, phantom_only)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (consumer.is_consuming_contour_points ())
|
if (consumer.is_consuming_contour_points ())
|
||||||
@@ -374,44 +377,43 @@ struct glyf_accelerator_t
|
|||||||
|
|
||||||
inline void
|
inline void
|
||||||
glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan,
|
glyf::_populate_subset_glyphs (const hb_subset_plan_t *plan,
|
||||||
hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const
|
hb_vector_t<glyf_impl::SubsetGlyph>& glyphs /* OUT */) const
|
||||||
{
|
{
|
||||||
OT::glyf_accelerator_t glyf (plan->source);
|
OT::glyf_accelerator_t glyf (plan->source);
|
||||||
|
unsigned num_glyphs = plan->num_output_glyphs ();
|
||||||
|
if (!glyphs.resize (num_glyphs)) return;
|
||||||
|
|
||||||
+ hb_range (plan->num_output_glyphs ())
|
for (auto p : plan->glyph_map->iter ())
|
||||||
| hb_map ([&] (hb_codepoint_t new_gid)
|
|
||||||
{
|
{
|
||||||
glyf_impl::SubsetGlyph subset_glyph = {0};
|
unsigned new_gid = p.second;
|
||||||
subset_glyph.new_gid = new_gid;
|
glyf_impl::SubsetGlyph& subset_glyph = glyphs.arrayZ[new_gid];
|
||||||
|
subset_glyph.old_gid = p.first;
|
||||||
|
|
||||||
/* should never fail: all old gids should be mapped */
|
if (unlikely (new_gid == 0 &&
|
||||||
if (!plan->old_gid_for_new_gid (new_gid, &subset_glyph.old_gid))
|
!(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE)) &&
|
||||||
return subset_glyph;
|
plan->pinned_at_default)
|
||||||
|
|
||||||
if (new_gid == 0 &&
|
|
||||||
!(plan->flags & HB_SUBSET_FLAGS_NOTDEF_OUTLINE))
|
|
||||||
subset_glyph.source_glyph = glyf_impl::Glyph ();
|
subset_glyph.source_glyph = glyf_impl::Glyph ();
|
||||||
else
|
else
|
||||||
subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true);
|
subset_glyph.source_glyph = glyf.glyph_for_gid (subset_glyph.old_gid, true);
|
||||||
|
|
||||||
if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
|
if (plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
|
||||||
subset_glyph.drop_hints_bytes ();
|
subset_glyph.drop_hints_bytes ();
|
||||||
else
|
else
|
||||||
subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes ();
|
subset_glyph.dest_start = subset_glyph.source_glyph.get_bytes ();
|
||||||
return subset_glyph;
|
}
|
||||||
})
|
|
||||||
| hb_sink (glyphs)
|
|
||||||
;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline bool
|
||||||
glyf::_compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan,
|
glyf::_compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan,
|
||||||
hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const
|
hb_vector_t<glyf_impl::SubsetGlyph> *glyphs /* OUT */) const
|
||||||
{
|
{
|
||||||
OT::glyf_accelerator_t glyf (plan->source);
|
OT::glyf_accelerator_t glyf (plan->source);
|
||||||
hb_font_t *font = hb_font_create (plan->source);
|
hb_font_t *font = hb_font_create (plan->source);
|
||||||
|
if (unlikely (!font)) return false;
|
||||||
|
|
||||||
hb_vector_t<hb_variation_t> vars;
|
hb_vector_t<hb_variation_t> vars;
|
||||||
vars.alloc (plan->user_axes_location->get_population ());
|
if (unlikely (!vars.alloc (plan->user_axes_location->get_population ())))
|
||||||
|
return false;
|
||||||
|
|
||||||
for (auto _ : *plan->user_axes_location)
|
for (auto _ : *plan->user_axes_location)
|
||||||
{
|
{
|
||||||
@@ -423,9 +425,16 @@ glyf::_compile_subset_glyphs_with_deltas (const hb_subset_plan_t *plan,
|
|||||||
|
|
||||||
hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location->get_population ());
|
hb_font_set_variations (font, vars.arrayZ, plan->user_axes_location->get_population ());
|
||||||
for (auto& subset_glyph : *glyphs)
|
for (auto& subset_glyph : *glyphs)
|
||||||
const_cast<glyf_impl::SubsetGlyph &> (subset_glyph).compile_bytes_with_deltas (plan, font, glyf);
|
{
|
||||||
|
if (!const_cast<glyf_impl::SubsetGlyph &> (subset_glyph).compile_bytes_with_deltas (plan, font, glyf))
|
||||||
|
{
|
||||||
|
hb_font_destroy (font);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
hb_font_destroy (font);
|
hb_font_destroy (font);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
29
thirdparty/harfbuzz/src/graph/graph.hh
vendored
29
thirdparty/harfbuzz/src/graph/graph.hh
vendored
@@ -70,8 +70,8 @@ struct graph_t
|
|||||||
{
|
{
|
||||||
DEBUG_MSG (SUBSET_REPACK, nullptr,
|
DEBUG_MSG (SUBSET_REPACK, nullptr,
|
||||||
"vertex [%lu] bytes != [%lu] bytes, depth = %u",
|
"vertex [%lu] bytes != [%lu] bytes, depth = %u",
|
||||||
table_size (),
|
(unsigned long) table_size (),
|
||||||
other.table_size (),
|
(unsigned long) other.table_size (),
|
||||||
depth);
|
depth);
|
||||||
|
|
||||||
auto a = as_bytes ();
|
auto a = as_bytes ();
|
||||||
@@ -495,6 +495,12 @@ struct graph_t
|
|||||||
return as_table_from_index<T> (index_for_offset (parent, offset), std::forward<Ts>(ds)...);
|
return as_table_from_index<T> (index_for_offset (parent, offset), std::forward<Ts>(ds)...);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T, typename ...Ts>
|
||||||
|
vertex_and_table_t<T> as_mutable_table (unsigned parent, const void* offset, Ts... ds)
|
||||||
|
{
|
||||||
|
return as_table_from_index<T> (mutable_index_for_offset (parent, offset), std::forward<Ts>(ds)...);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T, typename ...Ts>
|
template <typename T, typename ...Ts>
|
||||||
vertex_and_table_t<T> as_table_from_index (unsigned index, Ts... ds)
|
vertex_and_table_t<T> as_table_from_index (unsigned index, Ts... ds)
|
||||||
{
|
{
|
||||||
@@ -833,7 +839,20 @@ struct graph_t
|
|||||||
* parent to the clone. The copy is a shallow copy, objects
|
* parent to the clone. The copy is a shallow copy, objects
|
||||||
* linked from child are not duplicated.
|
* linked from child are not duplicated.
|
||||||
*/
|
*/
|
||||||
bool duplicate (unsigned parent_idx, unsigned child_idx)
|
unsigned duplicate_if_shared (unsigned parent_idx, unsigned child_idx)
|
||||||
|
{
|
||||||
|
unsigned new_idx = duplicate (parent_idx, child_idx);
|
||||||
|
if (new_idx == (unsigned) -1) return child_idx;
|
||||||
|
return new_idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Creates a copy of child and re-assigns the link from
|
||||||
|
* parent to the clone. The copy is a shallow copy, objects
|
||||||
|
* linked from child are not duplicated.
|
||||||
|
*/
|
||||||
|
unsigned duplicate (unsigned parent_idx, unsigned child_idx)
|
||||||
{
|
{
|
||||||
update_parents ();
|
update_parents ();
|
||||||
|
|
||||||
@@ -849,7 +868,7 @@ struct graph_t
|
|||||||
// to child are from parent.
|
// to child are from parent.
|
||||||
DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %d => %d",
|
DEBUG_MSG (SUBSET_REPACK, nullptr, " Not duplicating %d => %d",
|
||||||
parent_idx, child_idx);
|
parent_idx, child_idx);
|
||||||
return false;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_MSG (SUBSET_REPACK, nullptr, " Duplicating %d => %d",
|
DEBUG_MSG (SUBSET_REPACK, nullptr, " Duplicating %d => %d",
|
||||||
@@ -869,7 +888,7 @@ struct graph_t
|
|||||||
reassign_link (l, parent_idx, clone_idx);
|
reassign_link (l, parent_idx, clone_idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return clone_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -131,8 +131,10 @@ struct Lookup : public OT::Lookup
|
|||||||
for (unsigned i = 0; i < subTable.len; i++)
|
for (unsigned i = 0; i < subTable.len; i++)
|
||||||
{
|
{
|
||||||
unsigned subtable_index = c.graph.index_for_offset (this_index, &subTable[i]);
|
unsigned subtable_index = c.graph.index_for_offset (this_index, &subTable[i]);
|
||||||
|
unsigned parent_index = this_index;
|
||||||
if (is_ext) {
|
if (is_ext) {
|
||||||
unsigned ext_subtable_index = subtable_index;
|
unsigned ext_subtable_index = subtable_index;
|
||||||
|
parent_index = ext_subtable_index;
|
||||||
ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>* extension =
|
ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>* extension =
|
||||||
(ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>*)
|
(ExtensionFormat1<OT::Layout::GSUB_impl::ExtensionSubst>*)
|
||||||
c.graph.object (ext_subtable_index).head;
|
c.graph.object (ext_subtable_index).head;
|
||||||
@@ -150,9 +152,9 @@ struct Lookup : public OT::Lookup
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case 2:
|
case 2:
|
||||||
new_sub_tables = split_subtable<PairPos> (c, subtable_index); break;
|
new_sub_tables = split_subtable<PairPos> (c, parent_index, subtable_index); break;
|
||||||
case 4:
|
case 4:
|
||||||
new_sub_tables = split_subtable<MarkBasePos> (c, subtable_index); break;
|
new_sub_tables = split_subtable<MarkBasePos> (c, parent_index, subtable_index); break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -172,13 +174,14 @@ struct Lookup : public OT::Lookup
|
|||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
hb_vector_t<unsigned> split_subtable (gsubgpos_graph_context_t& c,
|
hb_vector_t<unsigned> split_subtable (gsubgpos_graph_context_t& c,
|
||||||
|
unsigned parent_idx,
|
||||||
unsigned objidx)
|
unsigned objidx)
|
||||||
{
|
{
|
||||||
T* sub_table = (T*) c.graph.object (objidx).head;
|
T* sub_table = (T*) c.graph.object (objidx).head;
|
||||||
if (!sub_table || !sub_table->sanitize (c.graph.vertices_[objidx]))
|
if (!sub_table || !sub_table->sanitize (c.graph.vertices_[objidx]))
|
||||||
return hb_vector_t<unsigned> ();
|
return hb_vector_t<unsigned> ();
|
||||||
|
|
||||||
return sub_table->split_subtables (c, objidx);
|
return sub_table->split_subtables (c, parent_idx, objidx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void add_sub_tables (gsubgpos_graph_context_t& c,
|
void add_sub_tables (gsubgpos_graph_context_t& c,
|
||||||
|
|||||||
@@ -209,7 +209,9 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2<S
|
|||||||
return vertex_len >= MarkBasePosFormat1::static_size;
|
return vertex_len >= MarkBasePosFormat1::static_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c, unsigned this_index)
|
hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c,
|
||||||
|
unsigned parent_index,
|
||||||
|
unsigned this_index)
|
||||||
{
|
{
|
||||||
hb_set_t visited;
|
hb_set_t visited;
|
||||||
|
|
||||||
@@ -261,7 +263,7 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2<S
|
|||||||
split_context_t split_context {
|
split_context_t split_context {
|
||||||
c,
|
c,
|
||||||
this,
|
this,
|
||||||
this_index,
|
c.graph.duplicate_if_shared (parent_index, this_index),
|
||||||
std::move (class_to_info),
|
std::move (class_to_info),
|
||||||
c.graph.vertices_[mark_array_id].position_to_index_map (),
|
c.graph.vertices_[mark_array_id].position_to_index_map (),
|
||||||
};
|
};
|
||||||
@@ -365,7 +367,7 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2<S
|
|||||||
|
|
||||||
classCount = count;
|
classCount = count;
|
||||||
|
|
||||||
auto mark_coverage = sc.c.graph.as_table<Coverage> (this_index,
|
auto mark_coverage = sc.c.graph.as_mutable_table<Coverage> (this_index,
|
||||||
&markCoverage);
|
&markCoverage);
|
||||||
if (!mark_coverage) return false;
|
if (!mark_coverage) return false;
|
||||||
hb_set_t marks = sc.marks_for (0, count);
|
hb_set_t marks = sc.marks_for (0, count);
|
||||||
@@ -380,7 +382,7 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2<S
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
|
||||||
auto base_array = sc.c.graph.as_table<AnchorMatrix> (this_index,
|
auto base_array = sc.c.graph.as_mutable_table<AnchorMatrix> (this_index,
|
||||||
&baseArray,
|
&baseArray,
|
||||||
old_count);
|
old_count);
|
||||||
if (!base_array || !base_array.table->shrink (sc.c,
|
if (!base_array || !base_array.table->shrink (sc.c,
|
||||||
@@ -389,7 +391,7 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2<S
|
|||||||
count))
|
count))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto mark_array = sc.c.graph.as_table<MarkArray> (this_index,
|
auto mark_array = sc.c.graph.as_mutable_table<MarkArray> (this_index,
|
||||||
&markArray);
|
&markArray);
|
||||||
if (!mark_array || !mark_array.table->shrink (sc.c,
|
if (!mark_array || !mark_array.table->shrink (sc.c,
|
||||||
sc.mark_array_links,
|
sc.mark_array_links,
|
||||||
@@ -469,11 +471,12 @@ struct MarkBasePosFormat1 : public OT::Layout::GPOS_impl::MarkBasePosFormat1_2<S
|
|||||||
struct MarkBasePos : public OT::Layout::GPOS_impl::MarkBasePos
|
struct MarkBasePos : public OT::Layout::GPOS_impl::MarkBasePos
|
||||||
{
|
{
|
||||||
hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c,
|
hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c,
|
||||||
|
unsigned parent_index,
|
||||||
unsigned this_index)
|
unsigned this_index)
|
||||||
{
|
{
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1:
|
case 1:
|
||||||
return ((MarkBasePosFormat1*)(&u.format1))->split_subtables (c, this_index);
|
return ((MarkBasePosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index);
|
||||||
#ifndef HB_NO_BORING_EXPANSION
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
case 2: HB_FALLTHROUGH;
|
case 2: HB_FALLTHROUGH;
|
||||||
// Don't split 24bit PairPos's.
|
// Don't split 24bit PairPos's.
|
||||||
|
|||||||
71
thirdparty/harfbuzz/src/graph/pairpos-graph.hh
vendored
71
thirdparty/harfbuzz/src/graph/pairpos-graph.hh
vendored
@@ -47,7 +47,9 @@ struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3<SmallType
|
|||||||
min_size + pairSet.get_size () - pairSet.len.get_size();
|
min_size + pairSet.get_size () - pairSet.len.get_size();
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c, unsigned this_index)
|
hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c,
|
||||||
|
unsigned parent_index,
|
||||||
|
unsigned this_index)
|
||||||
{
|
{
|
||||||
hb_set_t visited;
|
hb_set_t visited;
|
||||||
|
|
||||||
@@ -81,7 +83,7 @@ struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3<SmallType
|
|||||||
split_context_t split_context {
|
split_context_t split_context {
|
||||||
c,
|
c,
|
||||||
this,
|
this,
|
||||||
this_index,
|
c.graph.duplicate_if_shared (parent_index, this_index),
|
||||||
};
|
};
|
||||||
|
|
||||||
return actuate_subtable_split<split_context_t> (split_context, split_points);
|
return actuate_subtable_split<split_context_t> (split_context, split_points);
|
||||||
@@ -125,23 +127,19 @@ struct PairPosFormat1 : public OT::Layout::GPOS_impl::PairPosFormat1_3<SmallType
|
|||||||
pairSet.len = count;
|
pairSet.len = count;
|
||||||
c.graph.vertices_[this_index].obj.tail -= (old_count - count) * SmallTypes::size;
|
c.graph.vertices_[this_index].obj.tail -= (old_count - count) * SmallTypes::size;
|
||||||
|
|
||||||
unsigned coverage_id = c.graph.mutable_index_for_offset (this_index, &coverage);
|
auto coverage = c.graph.as_mutable_table<Coverage> (this_index, &this->coverage);
|
||||||
unsigned coverage_size = c.graph.vertices_[coverage_id].table_size ();
|
if (!coverage) return false;
|
||||||
auto& coverage_v = c.graph.vertices_[coverage_id];
|
|
||||||
|
|
||||||
Coverage* coverage_table = (Coverage*) coverage_v.obj.head;
|
|
||||||
if (!coverage_table || !coverage_table->sanitize (coverage_v))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
|
unsigned coverage_size = coverage.vertex->table_size ();
|
||||||
auto new_coverage =
|
auto new_coverage =
|
||||||
+ hb_zip (coverage_table->iter (), hb_range ())
|
+ hb_zip (coverage.table->iter (), hb_range ())
|
||||||
| hb_filter ([&] (hb_pair_t<unsigned, unsigned> p) {
|
| hb_filter ([&] (hb_pair_t<unsigned, unsigned> p) {
|
||||||
return p.second < count;
|
return p.second < count;
|
||||||
})
|
})
|
||||||
| hb_map_retains_sorting (hb_first)
|
| hb_map_retains_sorting (hb_first)
|
||||||
;
|
;
|
||||||
|
|
||||||
return Coverage::make_coverage (c, new_coverage, coverage_id, coverage_size);
|
return Coverage::make_coverage (c, new_coverage, coverage.index, coverage_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a new PairPos including PairSet's from start (inclusive) to end (exclusive).
|
// Create a new PairPos including PairSet's from start (inclusive) to end (exclusive).
|
||||||
@@ -206,7 +204,9 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4<SmallType
|
|||||||
min_size + class1_count * get_class1_record_size ();
|
min_size + class1_count * get_class1_record_size ();
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c, unsigned this_index)
|
hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c,
|
||||||
|
unsigned parent_index,
|
||||||
|
unsigned this_index)
|
||||||
{
|
{
|
||||||
const unsigned base_size = OT::Layout::GPOS_impl::PairPosFormat2_4<SmallTypes>::min_size;
|
const unsigned base_size = OT::Layout::GPOS_impl::PairPosFormat2_4<SmallTypes>::min_size;
|
||||||
const unsigned class_def_2_size = size_of (c, this_index, &classDef2);
|
const unsigned class_def_2_size = size_of (c, this_index, &classDef2);
|
||||||
@@ -287,7 +287,7 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4<SmallType
|
|||||||
split_context_t split_context {
|
split_context_t split_context {
|
||||||
c,
|
c,
|
||||||
this,
|
this,
|
||||||
this_index,
|
c.graph.duplicate_if_shared (parent_index, this_index),
|
||||||
class1_record_size,
|
class1_record_size,
|
||||||
total_value_len,
|
total_value_len,
|
||||||
value_1_len,
|
value_1_len,
|
||||||
@@ -508,40 +508,37 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4<SmallType
|
|||||||
graph.vertices_[split_context.this_index].obj.tail -=
|
graph.vertices_[split_context.this_index].obj.tail -=
|
||||||
(old_count - count) * split_context.class1_record_size;
|
(old_count - count) * split_context.class1_record_size;
|
||||||
|
|
||||||
unsigned coverage_id =
|
auto coverage =
|
||||||
graph.mutable_index_for_offset (split_context.this_index, &coverage);
|
graph.as_mutable_table<Coverage> (split_context.this_index, &this->coverage);
|
||||||
unsigned class_def_1_id =
|
if (!coverage) return false;
|
||||||
graph.mutable_index_for_offset (split_context.this_index, &classDef1);
|
|
||||||
auto& coverage_v = graph.vertices_[coverage_id];
|
auto class_def_1 =
|
||||||
auto& class_def_1_v = graph.vertices_[class_def_1_id];
|
graph.as_mutable_table<ClassDef> (split_context.this_index, &classDef1);
|
||||||
Coverage* coverage_table = (Coverage*) coverage_v.obj.head;
|
if (!class_def_1) return false;
|
||||||
ClassDef* class_def_1_table = (ClassDef*) class_def_1_v.obj.head;
|
|
||||||
if (!coverage_table
|
|
||||||
|| !coverage_table->sanitize (coverage_v)
|
|
||||||
|| !class_def_1_table
|
|
||||||
|| !class_def_1_table->sanitize (class_def_1_v))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
auto klass_map =
|
auto klass_map =
|
||||||
+ coverage_table->iter ()
|
+ coverage.table->iter ()
|
||||||
| hb_map_retains_sorting ([&] (hb_codepoint_t gid) {
|
| hb_map_retains_sorting ([&] (hb_codepoint_t gid) {
|
||||||
return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid, class_def_1_table->get_class (gid));
|
return hb_pair_t<hb_codepoint_t, hb_codepoint_t> (gid, class_def_1.table->get_class (gid));
|
||||||
})
|
})
|
||||||
| hb_filter ([&] (hb_codepoint_t klass) {
|
| hb_filter ([&] (hb_codepoint_t klass) {
|
||||||
return klass < count;
|
return klass < count;
|
||||||
}, hb_second)
|
}, hb_second)
|
||||||
;
|
;
|
||||||
|
|
||||||
|
auto new_coverage = + klass_map | hb_map_retains_sorting (hb_first);
|
||||||
if (!Coverage::make_coverage (split_context.c,
|
if (!Coverage::make_coverage (split_context.c,
|
||||||
+ klass_map | hb_map_retains_sorting (hb_first),
|
+ new_coverage,
|
||||||
coverage_id,
|
coverage.index,
|
||||||
coverage_v.table_size ()))
|
// existing ranges my not be kept, worst case size is a format 1
|
||||||
|
// coverage table.
|
||||||
|
4 + new_coverage.len() * 2))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return ClassDef::make_class_def (split_context.c,
|
return ClassDef::make_class_def (split_context.c,
|
||||||
+ klass_map,
|
+ klass_map,
|
||||||
class_def_1_id,
|
class_def_1.index,
|
||||||
class_def_1_v.table_size ());
|
class_def_1.vertex->table_size ());
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_hashmap_t<unsigned, unsigned>
|
hb_hashmap_t<unsigned, unsigned>
|
||||||
@@ -605,13 +602,15 @@ struct PairPosFormat2 : public OT::Layout::GPOS_impl::PairPosFormat2_4<SmallType
|
|||||||
|
|
||||||
struct PairPos : public OT::Layout::GPOS_impl::PairPos
|
struct PairPos : public OT::Layout::GPOS_impl::PairPos
|
||||||
{
|
{
|
||||||
hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c, unsigned this_index)
|
hb_vector_t<unsigned> split_subtables (gsubgpos_graph_context_t& c,
|
||||||
|
unsigned parent_index,
|
||||||
|
unsigned this_index)
|
||||||
{
|
{
|
||||||
switch (u.format) {
|
switch (u.format) {
|
||||||
case 1:
|
case 1:
|
||||||
return ((PairPosFormat1*)(&u.format1))->split_subtables (c, this_index);
|
return ((PairPosFormat1*)(&u.format1))->split_subtables (c, parent_index, this_index);
|
||||||
case 2:
|
case 2:
|
||||||
return ((PairPosFormat2*)(&u.format2))->split_subtables (c, this_index);
|
return ((PairPosFormat2*)(&u.format2))->split_subtables (c, parent_index, this_index);
|
||||||
#ifndef HB_NO_BORING_EXPANSION
|
#ifndef HB_NO_BORING_EXPANSION
|
||||||
case 3: HB_FALLTHROUGH;
|
case 3: HB_FALLTHROUGH;
|
||||||
case 4: HB_FALLTHROUGH;
|
case 4: HB_FALLTHROUGH;
|
||||||
|
|||||||
@@ -70,9 +70,9 @@ struct DecompositionAction
|
|||||||
|
|
||||||
ActionSubrecordHeader
|
ActionSubrecordHeader
|
||||||
header;
|
header;
|
||||||
HBFixed lowerLimit; /* If the distance factor is less than this value,
|
F16DOT16 lowerLimit; /* If the distance factor is less than this value,
|
||||||
* then the ligature is decomposed. */
|
* then the ligature is decomposed. */
|
||||||
HBFixed upperLimit; /* If the distance factor is greater than this value,
|
F16DOT16 upperLimit; /* If the distance factor is greater than this value,
|
||||||
* then the ligature is decomposed. */
|
* then the ligature is decomposed. */
|
||||||
HBUINT16 order; /* Numerical order in which this ligature will
|
HBUINT16 order; /* Numerical order in which this ligature will
|
||||||
* be decomposed; you may want infrequent ligatures
|
* be decomposed; you may want infrequent ligatures
|
||||||
@@ -118,7 +118,7 @@ struct ConditionalAddGlyphAction
|
|||||||
protected:
|
protected:
|
||||||
ActionSubrecordHeader
|
ActionSubrecordHeader
|
||||||
header;
|
header;
|
||||||
HBFixed substThreshold; /* Distance growth factor (in ems) at which
|
F16DOT16 substThreshold; /* Distance growth factor (in ems) at which
|
||||||
* this glyph is replaced and the growth factor
|
* this glyph is replaced and the growth factor
|
||||||
* recalculated. */
|
* recalculated. */
|
||||||
HBGlyphID16 addGlyph; /* Glyph to be added as kashida. If this value is
|
HBGlyphID16 addGlyph; /* Glyph to be added as kashida. If this value is
|
||||||
@@ -146,13 +146,13 @@ struct DuctileGlyphAction
|
|||||||
HBUINT32 variationAxis; /* The 4-byte tag identifying the ductile axis.
|
HBUINT32 variationAxis; /* The 4-byte tag identifying the ductile axis.
|
||||||
* This would normally be 0x64756374 ('duct'),
|
* This would normally be 0x64756374 ('duct'),
|
||||||
* but you may use any axis the font contains. */
|
* but you may use any axis the font contains. */
|
||||||
HBFixed minimumLimit; /* The lowest value for the ductility axis that
|
F16DOT16 minimumLimit; /* The lowest value for the ductility axis that
|
||||||
* still yields an acceptable appearance. Normally
|
* still yields an acceptable appearance. Normally
|
||||||
* this will be 1.0. */
|
* this will be 1.0. */
|
||||||
HBFixed noStretchValue; /* This is the default value that corresponds to
|
F16DOT16 noStretchValue; /* This is the default value that corresponds to
|
||||||
* no change in appearance. Normally, this will
|
* no change in appearance. Normally, this will
|
||||||
* be 1.0. */
|
* be 1.0. */
|
||||||
HBFixed maximumLimit; /* The highest value for the ductility axis that
|
F16DOT16 maximumLimit; /* The highest value for the ductility axis that
|
||||||
* still yields an acceptable appearance. */
|
* still yields an acceptable appearance. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (22);
|
DEFINE_SIZE_STATIC (22);
|
||||||
@@ -271,14 +271,14 @@ struct JustWidthDeltaEntry
|
|||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBFixed beforeGrowLimit;/* The ratio by which the advance width of the
|
F16DOT16 beforeGrowLimit;/* The ratio by which the advance width of the
|
||||||
* glyph is permitted to grow on the left or top side. */
|
* glyph is permitted to grow on the left or top side. */
|
||||||
HBFixed beforeShrinkLimit;
|
F16DOT16 beforeShrinkLimit;
|
||||||
/* The ratio by which the advance width of the
|
/* The ratio by which the advance width of the
|
||||||
* glyph is permitted to shrink on the left or top side. */
|
* glyph is permitted to shrink on the left or top side. */
|
||||||
HBFixed afterGrowLimit; /* The ratio by which the advance width of the glyph
|
F16DOT16 afterGrowLimit; /* The ratio by which the advance width of the glyph
|
||||||
* is permitted to shrink on the left or top side. */
|
* is permitted to shrink on the left or top side. */
|
||||||
HBFixed afterShrinkLimit;
|
F16DOT16 afterShrinkLimit;
|
||||||
/* The ratio by which the advance width of the glyph
|
/* The ratio by which the advance width of the glyph
|
||||||
* is at most permitted to shrink on the right or
|
* is at most permitted to shrink on the right or
|
||||||
* bottom side. */
|
* bottom side. */
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ struct TrackTableEntry
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBFixed track; /* Track value for this record. */
|
F16DOT16 track; /* Track value for this record. */
|
||||||
NameID trackNameID; /* The 'name' table index for this track.
|
NameID trackNameID; /* The 'name' table index for this track.
|
||||||
* (a short word or phrase like "loose"
|
* (a short word or phrase like "loose"
|
||||||
* or "very tight") */
|
* or "very tight") */
|
||||||
@@ -82,7 +82,7 @@ struct TrackData
|
|||||||
const void *base) const
|
const void *base) const
|
||||||
{
|
{
|
||||||
unsigned int sizes = nSizes;
|
unsigned int sizes = nSizes;
|
||||||
hb_array_t<const HBFixed> size_table ((base+sizeTable).arrayZ, sizes);
|
hb_array_t<const F16DOT16> size_table ((base+sizeTable).arrayZ, sizes);
|
||||||
|
|
||||||
float s0 = size_table[idx].to_float ();
|
float s0 = size_table[idx].to_float ();
|
||||||
float s1 = size_table[idx + 1].to_float ();
|
float s1 = size_table[idx + 1].to_float ();
|
||||||
@@ -120,7 +120,7 @@ struct TrackData
|
|||||||
if (!sizes) return 0.;
|
if (!sizes) return 0.;
|
||||||
if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes);
|
if (sizes == 1) return trackTableEntry->get_value (base, 0, sizes);
|
||||||
|
|
||||||
hb_array_t<const HBFixed> size_table ((base+sizeTable).arrayZ, sizes);
|
hb_array_t<const F16DOT16> size_table ((base+sizeTable).arrayZ, sizes);
|
||||||
unsigned int size_index;
|
unsigned int size_index;
|
||||||
for (size_index = 0; size_index < sizes - 1; size_index++)
|
for (size_index = 0; size_index < sizes - 1; size_index++)
|
||||||
if (size_table[size_index].to_float () >= ptem)
|
if (size_table[size_index].to_float () >= ptem)
|
||||||
@@ -141,7 +141,7 @@ struct TrackData
|
|||||||
protected:
|
protected:
|
||||||
HBUINT16 nTracks; /* Number of separate tracks included in this table. */
|
HBUINT16 nTracks; /* Number of separate tracks included in this table. */
|
||||||
HBUINT16 nSizes; /* Number of point sizes included in this table. */
|
HBUINT16 nSizes; /* Number of point sizes included in this table. */
|
||||||
NNOffset32To<UnsizedArrayOf<HBFixed>>
|
NNOffset32To<UnsizedArrayOf<F16DOT16>>
|
||||||
sizeTable; /* Offset from start of the tracking table to
|
sizeTable; /* Offset from start of the tracking table to
|
||||||
* Array[nSizes] of size values.. */
|
* Array[nSizes] of size values.. */
|
||||||
UnsizedArrayOf<TrackTableEntry>
|
UnsizedArrayOf<TrackTableEntry>
|
||||||
|
|||||||
1
thirdparty/harfbuzz/src/hb-aat-layout.cc
vendored
1
thirdparty/harfbuzz/src/hb-aat-layout.cc
vendored
@@ -131,6 +131,7 @@ static const hb_aat_feature_mapping_t feature_mappings[] =
|
|||||||
{HB_TAG ('p','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_NUMBERS, (hb_aat_layout_feature_selector_t) 4},
|
{HB_TAG ('p','n','u','m'), HB_AAT_LAYOUT_FEATURE_TYPE_NUMBER_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_NUMBERS, (hb_aat_layout_feature_selector_t) 4},
|
||||||
{HB_TAG ('p','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7},
|
{HB_TAG ('p','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_PROPORTIONAL_TEXT, (hb_aat_layout_feature_selector_t) 7},
|
||||||
{HB_TAG ('q','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7},
|
{HB_TAG ('q','w','i','d'), HB_AAT_LAYOUT_FEATURE_TYPE_TEXT_SPACING, HB_AAT_LAYOUT_FEATURE_SELECTOR_QUARTER_WIDTH_TEXT, (hb_aat_layout_feature_selector_t) 7},
|
||||||
|
{HB_TAG ('r','l','i','g'), HB_AAT_LAYOUT_FEATURE_TYPE_LIGATURES, HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_REQUIRED_LIGATURES_OFF},
|
||||||
{HB_TAG ('r','u','b','y'), HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA, HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF},
|
{HB_TAG ('r','u','b','y'), HB_AAT_LAYOUT_FEATURE_TYPE_RUBY_KANA, HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_ON, HB_AAT_LAYOUT_FEATURE_SELECTOR_RUBY_KANA_OFF},
|
||||||
{HB_TAG ('s','i','n','f'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_FEATURE_SELECTOR_SCIENTIFIC_INFERIORS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION},
|
{HB_TAG ('s','i','n','f'), HB_AAT_LAYOUT_FEATURE_TYPE_VERTICAL_POSITION, HB_AAT_LAYOUT_FEATURE_SELECTOR_SCIENTIFIC_INFERIORS, HB_AAT_LAYOUT_FEATURE_SELECTOR_NORMAL_POSITION},
|
||||||
{HB_TAG ('s','m','c','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE},
|
{HB_TAG ('s','m','c','p'), HB_AAT_LAYOUT_FEATURE_TYPE_LOWER_CASE, HB_AAT_LAYOUT_FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS, HB_AAT_LAYOUT_FEATURE_SELECTOR_DEFAULT_LOWER_CASE},
|
||||||
|
|||||||
1
thirdparty/harfbuzz/src/hb-config.hh
vendored
1
thirdparty/harfbuzz/src/hb-config.hh
vendored
@@ -71,6 +71,7 @@
|
|||||||
#define HB_NO_LANGUAGE_PRIVATE_SUBTAG
|
#define HB_NO_LANGUAGE_PRIVATE_SUBTAG
|
||||||
#define HB_NO_LAYOUT_FEATURE_PARAMS
|
#define HB_NO_LAYOUT_FEATURE_PARAMS
|
||||||
#define HB_NO_LAYOUT_COLLECT_GLYPHS
|
#define HB_NO_LAYOUT_COLLECT_GLYPHS
|
||||||
|
#define HB_NO_LAYOUT_RARELY_USED
|
||||||
#define HB_NO_LAYOUT_UNUSED
|
#define HB_NO_LAYOUT_UNUSED
|
||||||
#define HB_NO_MATH
|
#define HB_NO_MATH
|
||||||
#define HB_NO_META
|
#define HB_NO_META
|
||||||
|
|||||||
6
thirdparty/harfbuzz/src/hb-cplusplus.hh
vendored
6
thirdparty/harfbuzz/src/hb-cplusplus.hh
vendored
@@ -69,9 +69,9 @@ struct shared_ptr
|
|||||||
operator T * () const { return p; }
|
operator T * () const { return p; }
|
||||||
T& operator * () const { return *get (); }
|
T& operator * () const { return *get (); }
|
||||||
T* operator -> () const { return get (); }
|
T* operator -> () const { return get (); }
|
||||||
operator bool () { return p; }
|
operator bool () const { return p; }
|
||||||
bool operator == (const shared_ptr &o) { return p == o.p; }
|
bool operator == (const shared_ptr &o) const { return p == o.p; }
|
||||||
bool operator != (const shared_ptr &o) { return p != o.p; }
|
bool operator != (const shared_ptr &o) const { return p != o.p; }
|
||||||
|
|
||||||
static T* get_empty() { return v::get_empty (); }
|
static T* get_empty() { return v::get_empty (); }
|
||||||
T* reference() { return v::reference (p); }
|
T* reference() { return v::reference (p); }
|
||||||
|
|||||||
76
thirdparty/harfbuzz/src/hb-face.cc
vendored
76
thirdparty/harfbuzz/src/hb-face.cc
vendored
@@ -633,20 +633,29 @@ hb_face_collect_variation_unicodes (hb_face_t *face,
|
|||||||
* face-builder: A face that has add_table().
|
* face-builder: A face that has add_table().
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
struct face_table_info_t
|
||||||
|
{
|
||||||
|
hb_blob_t* data;
|
||||||
|
unsigned order;
|
||||||
|
};
|
||||||
|
|
||||||
struct hb_face_builder_data_t
|
struct hb_face_builder_data_t
|
||||||
{
|
{
|
||||||
hb_hashmap_t<hb_tag_t, hb_blob_t *> tables;
|
hb_hashmap_t<hb_tag_t, face_table_info_t> tables;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int compare_entries (const void* pa, const void* pb)
|
static int compare_entries (const void* pa, const void* pb)
|
||||||
{
|
{
|
||||||
const auto& a = * (const hb_pair_t<hb_tag_t, hb_blob_t*> *) pa;
|
const auto& a = * (const hb_pair_t<hb_tag_t, face_table_info_t> *) pa;
|
||||||
const auto& b = * (const hb_pair_t<hb_tag_t, hb_blob_t*> *) pb;
|
const auto& b = * (const hb_pair_t<hb_tag_t, face_table_info_t> *) pb;
|
||||||
|
|
||||||
/* Order by blob size first (smallest to largest) and then table tag */
|
/* Order by blob size first (smallest to largest) and then table tag */
|
||||||
|
|
||||||
if (a.second->length != b.second->length)
|
if (a.second.order != b.second.order)
|
||||||
return a.second->length < b.second->length ? -1 : +1;
|
return a.second.order < b.second.order ? -1 : +1;
|
||||||
|
|
||||||
|
if (a.second.data->length != b.second.data->length)
|
||||||
|
return a.second.data->length < b.second.data->length ? -1 : +1;
|
||||||
|
|
||||||
return a.first < b.first ? -1 : a.first == b.first ? 0 : +1;
|
return a.first < b.first ? -1 : a.first == b.first ? 0 : +1;
|
||||||
}
|
}
|
||||||
@@ -668,8 +677,8 @@ _hb_face_builder_data_destroy (void *user_data)
|
|||||||
{
|
{
|
||||||
hb_face_builder_data_t *data = (hb_face_builder_data_t *) user_data;
|
hb_face_builder_data_t *data = (hb_face_builder_data_t *) user_data;
|
||||||
|
|
||||||
for (hb_blob_t* b : data->tables.values())
|
for (auto info : data->tables.values())
|
||||||
hb_blob_destroy (b);
|
hb_blob_destroy (info.data);
|
||||||
|
|
||||||
data->tables.fini ();
|
data->tables.fini ();
|
||||||
|
|
||||||
@@ -683,8 +692,8 @@ _hb_face_builder_data_reference_blob (hb_face_builder_data_t *data)
|
|||||||
unsigned int table_count = data->tables.get_population ();
|
unsigned int table_count = data->tables.get_population ();
|
||||||
unsigned int face_length = table_count * 16 + 12;
|
unsigned int face_length = table_count * 16 + 12;
|
||||||
|
|
||||||
for (hb_blob_t* b : data->tables.values())
|
for (auto info : data->tables.values())
|
||||||
face_length += hb_ceil_to_4 (hb_blob_get_length (b));
|
face_length += hb_ceil_to_4 (hb_blob_get_length (info.data));
|
||||||
|
|
||||||
char *buf = (char *) hb_malloc (face_length);
|
char *buf = (char *) hb_malloc (face_length);
|
||||||
if (unlikely (!buf))
|
if (unlikely (!buf))
|
||||||
@@ -699,7 +708,7 @@ _hb_face_builder_data_reference_blob (hb_face_builder_data_t *data)
|
|||||||
hb_tag_t sfnt_tag = is_cff ? OT::OpenTypeFontFile::CFFTag : OT::OpenTypeFontFile::TrueTypeTag;
|
hb_tag_t sfnt_tag = is_cff ? OT::OpenTypeFontFile::CFFTag : OT::OpenTypeFontFile::TrueTypeTag;
|
||||||
|
|
||||||
// Sort the tags so that produced face is deterministic.
|
// Sort the tags so that produced face is deterministic.
|
||||||
hb_vector_t<hb_pair_t <hb_tag_t, hb_blob_t*>> sorted_entries;
|
hb_vector_t<hb_pair_t <hb_tag_t, face_table_info_t>> sorted_entries;
|
||||||
data->tables.iter () | hb_sink (sorted_entries);
|
data->tables.iter () | hb_sink (sorted_entries);
|
||||||
if (unlikely (sorted_entries.in_error ()))
|
if (unlikely (sorted_entries.in_error ()))
|
||||||
{
|
{
|
||||||
@@ -708,7 +717,13 @@ _hb_face_builder_data_reference_blob (hb_face_builder_data_t *data)
|
|||||||
}
|
}
|
||||||
|
|
||||||
sorted_entries.qsort (compare_entries);
|
sorted_entries.qsort (compare_entries);
|
||||||
bool ret = f->serialize_single (&c, sfnt_tag, + sorted_entries.iter());
|
|
||||||
|
bool ret = f->serialize_single (&c,
|
||||||
|
sfnt_tag,
|
||||||
|
+ sorted_entries.iter()
|
||||||
|
| hb_map ([&] (hb_pair_t<hb_tag_t, face_table_info_t> _) {
|
||||||
|
return hb_pair_t<hb_tag_t, hb_blob_t*> (_.first, _.second.data);
|
||||||
|
}));
|
||||||
|
|
||||||
c.end_serialize ();
|
c.end_serialize ();
|
||||||
|
|
||||||
@@ -729,7 +744,7 @@ _hb_face_builder_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void
|
|||||||
if (!tag)
|
if (!tag)
|
||||||
return _hb_face_builder_data_reference_blob (data);
|
return _hb_face_builder_data_reference_blob (data);
|
||||||
|
|
||||||
return hb_blob_reference (data->tables[tag]);
|
return hb_blob_reference (data->tables[tag].data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -777,8 +792,8 @@ hb_face_builder_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob)
|
|||||||
|
|
||||||
hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data;
|
hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data;
|
||||||
|
|
||||||
hb_blob_t* previous = data->tables.get (tag);
|
hb_blob_t* previous = data->tables.get (tag).data;
|
||||||
if (!data->tables.set (tag, hb_blob_reference (blob)))
|
if (!data->tables.set (tag, face_table_info_t {hb_blob_reference (blob), 0}))
|
||||||
{
|
{
|
||||||
hb_blob_destroy (blob);
|
hb_blob_destroy (blob);
|
||||||
return false;
|
return false;
|
||||||
@@ -787,3 +802,36 @@ hb_face_builder_add_table (hb_face_t *face, hb_tag_t tag, hb_blob_t *blob)
|
|||||||
hb_blob_destroy (previous);
|
hb_blob_destroy (previous);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hb_face_builder_sort_tables:
|
||||||
|
* @face: A face object created with hb_face_builder_create()
|
||||||
|
* @tags: (array zero-terminated=1): ordered list of table tags terminated by
|
||||||
|
* %HB_TAG_NONE
|
||||||
|
*
|
||||||
|
* Set the ordering of tables for serialization. Any tables not
|
||||||
|
* specified in the tags list will be ordered after the tables in
|
||||||
|
* tags, ordered by the default sort ordering.
|
||||||
|
*
|
||||||
|
* Since: 5.3.0
|
||||||
|
**/
|
||||||
|
void
|
||||||
|
hb_face_builder_sort_tables (hb_face_t *face,
|
||||||
|
const hb_tag_t *tags)
|
||||||
|
{
|
||||||
|
hb_face_builder_data_t *data = (hb_face_builder_data_t *) face->user_data;
|
||||||
|
|
||||||
|
// Sort all unspecified tables after any specified tables.
|
||||||
|
for (auto& info : data->tables.values_ref())
|
||||||
|
info.order = -1;
|
||||||
|
|
||||||
|
unsigned order = 0;
|
||||||
|
for (const hb_tag_t* tag = tags;
|
||||||
|
*tag;
|
||||||
|
tag++)
|
||||||
|
{
|
||||||
|
face_table_info_t* info;
|
||||||
|
if (!data->tables.has (*tag, &info)) continue;
|
||||||
|
info->order = order++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
4
thirdparty/harfbuzz/src/hb-face.h
vendored
4
thirdparty/harfbuzz/src/hb-face.h
vendored
@@ -171,6 +171,10 @@ hb_face_builder_add_table (hb_face_t *face,
|
|||||||
hb_tag_t tag,
|
hb_tag_t tag,
|
||||||
hb_blob_t *blob);
|
hb_blob_t *blob);
|
||||||
|
|
||||||
|
HB_EXTERN void
|
||||||
|
hb_face_builder_sort_tables (hb_face_t *face,
|
||||||
|
const hb_tag_t *tags);
|
||||||
|
|
||||||
|
|
||||||
HB_END_DECLS
|
HB_END_DECLS
|
||||||
|
|
||||||
|
|||||||
12
thirdparty/harfbuzz/src/hb-meta.hh
vendored
12
thirdparty/harfbuzz/src/hb-meta.hh
vendored
@@ -133,6 +133,18 @@ struct
|
|||||||
|
|
||||||
template <typename T> constexpr auto
|
template <typename T> constexpr auto
|
||||||
operator () (T *v) const HB_AUTO_RETURN (*v)
|
operator () (T *v) const HB_AUTO_RETURN (*v)
|
||||||
|
|
||||||
|
template <typename T> constexpr auto
|
||||||
|
operator () (const hb::shared_ptr<T>& v) const HB_AUTO_RETURN (*v)
|
||||||
|
|
||||||
|
template <typename T> constexpr auto
|
||||||
|
operator () (hb::shared_ptr<T>& v) const HB_AUTO_RETURN (*v)
|
||||||
|
|
||||||
|
template <typename T> constexpr auto
|
||||||
|
operator () (const hb::unique_ptr<T>& v) const HB_AUTO_RETURN (*v)
|
||||||
|
|
||||||
|
template <typename T> constexpr auto
|
||||||
|
operator () (hb::unique_ptr<T>& v) const HB_AUTO_RETURN (*v)
|
||||||
}
|
}
|
||||||
HB_FUNCOBJ (hb_deref);
|
HB_FUNCOBJ (hb_deref);
|
||||||
|
|
||||||
|
|||||||
29
thirdparty/harfbuzz/src/hb-open-type.hh
vendored
29
thirdparty/harfbuzz/src/hb-open-type.hh
vendored
@@ -141,27 +141,24 @@ typedef HBINT32 FWORD32;
|
|||||||
/* 16-bit unsigned integer (HBUINT16) that describes a quantity in FUnits. */
|
/* 16-bit unsigned integer (HBUINT16) that describes a quantity in FUnits. */
|
||||||
typedef HBUINT16 UFWORD;
|
typedef HBUINT16 UFWORD;
|
||||||
|
|
||||||
/* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
|
template <typename Type, unsigned fraction_bits>
|
||||||
struct F2DOT14 : HBINT16
|
struct HBFixed : Type
|
||||||
{
|
{
|
||||||
F2DOT14& operator = (uint16_t i ) { HBINT16::operator= (i); return *this; }
|
static constexpr float shift = (float) (1 << fraction_bits);
|
||||||
// 16384 means 1<<14
|
static_assert (Type::static_size * 8 > fraction_bits, "");
|
||||||
float to_float () const { return ((int32_t) v) / 16384.f; }
|
|
||||||
void set_float (float f) { v = roundf (f * 16384.f); }
|
HBFixed& operator = (typename Type::type i ) { Type::operator= (i); return *this; }
|
||||||
|
float to_float () const { return ((int32_t) Type::v) / shift; }
|
||||||
|
void set_float (float f) { Type::v = roundf (f * shift); }
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (2);
|
DEFINE_SIZE_STATIC (Type::static_size);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* 16-bit signed fixed number with the low 14 bits of fraction (2.14). */
|
||||||
|
using F2DOT14 = HBFixed<HBINT16, 14>;
|
||||||
|
|
||||||
/* 32-bit signed fixed-point number (16.16). */
|
/* 32-bit signed fixed-point number (16.16). */
|
||||||
struct HBFixed : HBINT32
|
using F16DOT16 = HBFixed<HBINT32, 16>;
|
||||||
{
|
|
||||||
HBFixed& operator = (uint32_t i) { HBINT32::operator= (i); return *this; }
|
|
||||||
// 65536 means 1<<16
|
|
||||||
float to_float () const { return ((int32_t) v) / 65536.f; }
|
|
||||||
void set_float (float f) { v = roundf (f * 65536.f); }
|
|
||||||
public:
|
|
||||||
DEFINE_SIZE_STATIC (4);
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Date represented in number of seconds since 12:00 midnight, January 1,
|
/* Date represented in number of seconds since 12:00 midnight, January 1,
|
||||||
* 1904. The value is represented as a signed 64-bit integer. */
|
* 1904. The value is represented as a signed 64-bit integer. */
|
||||||
|
|||||||
@@ -358,14 +358,14 @@ struct Affine2x3
|
|||||||
return_trace (c->check_struct (this));
|
return_trace (c->check_struct (this));
|
||||||
}
|
}
|
||||||
|
|
||||||
HBFixed xx;
|
F16DOT16 xx;
|
||||||
HBFixed yx;
|
F16DOT16 yx;
|
||||||
HBFixed xy;
|
F16DOT16 xy;
|
||||||
HBFixed yy;
|
F16DOT16 yy;
|
||||||
HBFixed dx;
|
F16DOT16 dx;
|
||||||
HBFixed dy;
|
F16DOT16 dy;
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (6 * HBFixed::static_size);
|
DEFINE_SIZE_STATIC (6 * F16DOT16::static_size);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PaintColrLayers
|
struct PaintColrLayers
|
||||||
|
|||||||
4
thirdparty/harfbuzz/src/hb-ot-color.cc
vendored
4
thirdparty/harfbuzz/src/hb-ot-color.cc
vendored
@@ -295,8 +295,8 @@ hb_ot_color_has_png (hb_face_t *face)
|
|||||||
* @glyph: a glyph index
|
* @glyph: a glyph index
|
||||||
*
|
*
|
||||||
* Fetches the PNG image for a glyph. This function takes a font object, not a face object,
|
* Fetches the PNG image for a glyph. This function takes a font object, not a face object,
|
||||||
* as input. To get an optimally sized PNG blob, the UPEM value must be set on the @font
|
* as input. To get an optimally sized PNG blob, the PPEM values must be set on the @font
|
||||||
* object. If UPEM is unset, the blob returned will be the largest PNG available.
|
* object. If PPEM is unset, the blob returned will be the largest PNG available.
|
||||||
*
|
*
|
||||||
* If the glyph has no PNG image, the singleton empty blob is returned.
|
* If the glyph has no PNG image, the singleton empty blob is returned.
|
||||||
*
|
*
|
||||||
|
|||||||
5
thirdparty/harfbuzz/src/hb-ot-font.cc
vendored
5
thirdparty/harfbuzz/src/hb-ot-font.cc
vendored
@@ -40,7 +40,6 @@
|
|||||||
#include "hb-ot-cff1-table.hh"
|
#include "hb-ot-cff1-table.hh"
|
||||||
#include "hb-ot-cff2-table.hh"
|
#include "hb-ot-cff2-table.hh"
|
||||||
#include "hb-ot-hmtx-table.hh"
|
#include "hb-ot-hmtx-table.hh"
|
||||||
#include "hb-ot-os2-table.hh"
|
|
||||||
#include "hb-ot-post-table.hh"
|
#include "hb-ot-post-table.hh"
|
||||||
#include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise.
|
#include "hb-ot-stat-table.hh" // Just so we compile it; unused otherwise.
|
||||||
#include "hb-ot-vorg-table.hh"
|
#include "hb-ot-vorg-table.hh"
|
||||||
@@ -349,15 +348,13 @@ hb_ot_get_glyph_extents (hb_font_t *font,
|
|||||||
|
|
||||||
#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
|
#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
|
||||||
if (ot_face->sbix->get_extents (font, glyph, extents)) return true;
|
if (ot_face->sbix->get_extents (font, glyph, extents)) return true;
|
||||||
|
if (ot_face->CBDT->get_extents (font, glyph, extents)) return true;
|
||||||
#endif
|
#endif
|
||||||
if (ot_face->glyf->get_extents (font, glyph, extents)) return true;
|
if (ot_face->glyf->get_extents (font, glyph, extents)) return true;
|
||||||
#ifndef HB_NO_OT_FONT_CFF
|
#ifndef HB_NO_OT_FONT_CFF
|
||||||
if (ot_face->cff1->get_extents (font, glyph, extents)) return true;
|
if (ot_face->cff1->get_extents (font, glyph, extents)) return true;
|
||||||
if (ot_face->cff2->get_extents (font, glyph, extents)) return true;
|
if (ot_face->cff2->get_extents (font, glyph, extents)) return true;
|
||||||
#endif
|
#endif
|
||||||
#if !defined(HB_NO_OT_FONT_BITMAP) && !defined(HB_NO_COLOR)
|
|
||||||
if (ot_face->CBDT->get_extents (font, glyph, extents)) return true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// TODO Hook up side-bearings variations.
|
// TODO Hook up side-bearings variations.
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
469
thirdparty/harfbuzz/src/hb-ot-layout-common.hh
vendored
469
thirdparty/harfbuzz/src/hb-ot-layout-common.hh
vendored
@@ -94,6 +94,19 @@ static bool ClassDef_remap_and_serialize (
|
|||||||
hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> &glyph_and_klass, /* IN/OUT */
|
hb_sorted_vector_t<hb_pair_t<hb_codepoint_t, hb_codepoint_t>> &glyph_and_klass, /* IN/OUT */
|
||||||
hb_map_t *klass_map /*IN/OUT*/);
|
hb_map_t *klass_map /*IN/OUT*/);
|
||||||
|
|
||||||
|
struct hb_collect_feature_substitutes_with_var_context_t
|
||||||
|
{
|
||||||
|
const hb_map_t *axes_index_tag_map;
|
||||||
|
const hb_hashmap_t<hb_tag_t, int> *axes_location;
|
||||||
|
hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *record_cond_idx_map;
|
||||||
|
hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map;
|
||||||
|
|
||||||
|
// not stored in subset_plan
|
||||||
|
hb_set_t *feature_indices;
|
||||||
|
bool apply;
|
||||||
|
unsigned cur_record_idx;
|
||||||
|
hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned> *conditionset_map;
|
||||||
|
};
|
||||||
|
|
||||||
struct hb_prune_langsys_context_t
|
struct hb_prune_langsys_context_t
|
||||||
{
|
{
|
||||||
@@ -160,24 +173,40 @@ struct hb_subset_layout_context_t :
|
|||||||
const hb_map_t *lookup_index_map;
|
const hb_map_t *lookup_index_map;
|
||||||
const hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map;
|
const hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map;
|
||||||
const hb_map_t *feature_index_map;
|
const hb_map_t *feature_index_map;
|
||||||
|
const hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map;
|
||||||
|
hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map;
|
||||||
|
|
||||||
unsigned cur_script_index;
|
unsigned cur_script_index;
|
||||||
|
unsigned cur_feature_var_record_idx;
|
||||||
|
|
||||||
hb_subset_layout_context_t (hb_subset_context_t *c_,
|
hb_subset_layout_context_t (hb_subset_context_t *c_,
|
||||||
hb_tag_t tag_,
|
hb_tag_t tag_) :
|
||||||
hb_map_t *lookup_map_,
|
|
||||||
hb_hashmap_t<unsigned, hb::unique_ptr<hb_set_t>> *script_langsys_map_,
|
|
||||||
hb_map_t *feature_index_map_) :
|
|
||||||
subset_context (c_),
|
subset_context (c_),
|
||||||
table_tag (tag_),
|
table_tag (tag_),
|
||||||
lookup_index_map (lookup_map_),
|
|
||||||
script_langsys_map (script_langsys_map_),
|
|
||||||
feature_index_map (feature_index_map_),
|
|
||||||
cur_script_index (0xFFFFu),
|
cur_script_index (0xFFFFu),
|
||||||
|
cur_feature_var_record_idx (0u),
|
||||||
script_count (0),
|
script_count (0),
|
||||||
langsys_count (0),
|
langsys_count (0),
|
||||||
feature_index_count (0),
|
feature_index_count (0),
|
||||||
lookup_index_count (0)
|
lookup_index_count (0)
|
||||||
{}
|
{
|
||||||
|
if (tag_ == HB_OT_TAG_GSUB)
|
||||||
|
{
|
||||||
|
lookup_index_map = c_->plan->gsub_lookups;
|
||||||
|
script_langsys_map = c_->plan->gsub_langsys;
|
||||||
|
feature_index_map = c_->plan->gsub_features;
|
||||||
|
feature_substitutes_map = c_->plan->gsub_feature_substitutes_map;
|
||||||
|
feature_record_cond_idx_map = c_->plan->user_axes_location->is_empty () ? nullptr : c_->plan->gsub_feature_record_cond_idx_map;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lookup_index_map = c_->plan->gpos_lookups;
|
||||||
|
script_langsys_map = c_->plan->gpos_langsys;
|
||||||
|
feature_index_map = c_->plan->gpos_features;
|
||||||
|
feature_substitutes_map = c_->plan->gpos_feature_substitutes_map;
|
||||||
|
feature_record_cond_idx_map = c_->plan->user_axes_location->is_empty () ? nullptr : c_->plan->gpos_feature_record_cond_idx_map;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
unsigned script_count;
|
unsigned script_count;
|
||||||
@@ -324,6 +353,31 @@ struct subset_record_array_t
|
|||||||
const void *base;
|
const void *base;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template<typename OutputArray, typename Arg>
|
||||||
|
struct subset_record_array_arg_t
|
||||||
|
{
|
||||||
|
subset_record_array_arg_t (hb_subset_layout_context_t *c_, OutputArray* out_,
|
||||||
|
const void *base_,
|
||||||
|
Arg &&arg_) : subset_layout_context (c_),
|
||||||
|
out (out_), base (base_), arg (arg_) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void
|
||||||
|
operator () (T&& record)
|
||||||
|
{
|
||||||
|
auto snap = subset_layout_context->subset_context->serializer->snapshot ();
|
||||||
|
bool ret = record.subset (subset_layout_context, base, arg);
|
||||||
|
if (!ret) subset_layout_context->subset_context->serializer->revert (snap);
|
||||||
|
else out->len++;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
hb_subset_layout_context_t *subset_layout_context;
|
||||||
|
OutputArray *out;
|
||||||
|
const void *base;
|
||||||
|
Arg &&arg;
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Helper to subset a RecordList/record array. Subsets each Record in the array and
|
* Helper to subset a RecordList/record array. Subsets each Record in the array and
|
||||||
* discards the record if the subset operation returns false.
|
* discards the record if the subset operation returns false.
|
||||||
@@ -335,6 +389,13 @@ struct
|
|||||||
operator () (hb_subset_layout_context_t *c, OutputArray* out,
|
operator () (hb_subset_layout_context_t *c, OutputArray* out,
|
||||||
const void *base) const
|
const void *base) const
|
||||||
{ return subset_record_array_t<OutputArray> (c, out, base); }
|
{ return subset_record_array_t<OutputArray> (c, out, base); }
|
||||||
|
|
||||||
|
/* Variant with one extra argument passed to subset */
|
||||||
|
template<typename OutputArray, typename Arg>
|
||||||
|
subset_record_array_arg_t<OutputArray, Arg>
|
||||||
|
operator () (hb_subset_layout_context_t *c, OutputArray* out,
|
||||||
|
const void *base, Arg &&arg) const
|
||||||
|
{ return subset_record_array_arg_t<OutputArray, Arg> (c, out, base, arg); }
|
||||||
}
|
}
|
||||||
HB_FUNCOBJ (subset_record_array);
|
HB_FUNCOBJ (subset_record_array);
|
||||||
|
|
||||||
@@ -431,94 +492,6 @@ struct IndexArray : Array16Of<Index>
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Record_sanitize_closure_t {
|
|
||||||
hb_tag_t tag;
|
|
||||||
const void *list_base;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
struct Record
|
|
||||||
{
|
|
||||||
int cmp (hb_tag_t a) const { return tag.cmp (a); }
|
|
||||||
|
|
||||||
bool subset (hb_subset_layout_context_t *c, const void *base) const
|
|
||||||
{
|
|
||||||
TRACE_SUBSET (this);
|
|
||||||
auto *out = c->subset_context->serializer->embed (this);
|
|
||||||
if (unlikely (!out)) return_trace (false);
|
|
||||||
bool ret = out->offset.serialize_subset (c->subset_context, offset, base, c, &tag);
|
|
||||||
return_trace (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
|
||||||
{
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
const Record_sanitize_closure_t closure = {tag, base};
|
|
||||||
return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure));
|
|
||||||
}
|
|
||||||
|
|
||||||
Tag tag; /* 4-byte Tag identifier */
|
|
||||||
Offset16To<Type>
|
|
||||||
offset; /* Offset from beginning of object holding
|
|
||||||
* the Record */
|
|
||||||
public:
|
|
||||||
DEFINE_SIZE_STATIC (6);
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
struct RecordArrayOf : SortedArray16Of<Record<Type>>
|
|
||||||
{
|
|
||||||
const Offset16To<Type>& get_offset (unsigned int i) const
|
|
||||||
{ return (*this)[i].offset; }
|
|
||||||
Offset16To<Type>& get_offset (unsigned int i)
|
|
||||||
{ return (*this)[i].offset; }
|
|
||||||
const Tag& get_tag (unsigned int i) const
|
|
||||||
{ return (*this)[i].tag; }
|
|
||||||
unsigned int get_tags (unsigned int start_offset,
|
|
||||||
unsigned int *record_count /* IN/OUT */,
|
|
||||||
hb_tag_t *record_tags /* OUT */) const
|
|
||||||
{
|
|
||||||
if (record_count)
|
|
||||||
{
|
|
||||||
+ this->sub_array (start_offset, record_count)
|
|
||||||
| hb_map (&Record<Type>::tag)
|
|
||||||
| hb_sink (hb_array (record_tags, *record_count))
|
|
||||||
;
|
|
||||||
}
|
|
||||||
return this->len;
|
|
||||||
}
|
|
||||||
bool find_index (hb_tag_t tag, unsigned int *index) const
|
|
||||||
{
|
|
||||||
return this->bfind (tag, index, HB_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename Type>
|
|
||||||
struct RecordListOf : RecordArrayOf<Type>
|
|
||||||
{
|
|
||||||
const Type& operator [] (unsigned int i) const
|
|
||||||
{ return this+this->get_offset (i); }
|
|
||||||
|
|
||||||
bool subset (hb_subset_context_t *c,
|
|
||||||
hb_subset_layout_context_t *l) const
|
|
||||||
{
|
|
||||||
TRACE_SUBSET (this);
|
|
||||||
auto *out = c->serializer->start_embed (*this);
|
|
||||||
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
|
|
||||||
|
|
||||||
+ this->iter ()
|
|
||||||
| hb_apply (subset_record_array (l, out, this))
|
|
||||||
;
|
|
||||||
return_trace (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c) const
|
|
||||||
{
|
|
||||||
TRACE_SANITIZE (this);
|
|
||||||
return_trace (RecordArrayOf<Type>::sanitize (c, this));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
/* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#size */
|
/* https://docs.microsoft.com/en-us/typography/opentype/spec/features_pt#size */
|
||||||
struct FeatureParamsSize
|
struct FeatureParamsSize
|
||||||
{
|
{
|
||||||
@@ -801,6 +774,10 @@ struct FeatureParams
|
|||||||
DEFINE_SIZE_MIN (0);
|
DEFINE_SIZE_MIN (0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct Record_sanitize_closure_t {
|
||||||
|
hb_tag_t tag;
|
||||||
|
const void *list_base;
|
||||||
|
};
|
||||||
|
|
||||||
struct Feature
|
struct Feature
|
||||||
{
|
{
|
||||||
@@ -897,6 +874,103 @@ struct Feature
|
|||||||
DEFINE_SIZE_ARRAY_SIZED (4, lookupIndex);
|
DEFINE_SIZE_ARRAY_SIZED (4, lookupIndex);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
struct Record
|
||||||
|
{
|
||||||
|
int cmp (hb_tag_t a) const { return tag.cmp (a); }
|
||||||
|
|
||||||
|
bool subset (hb_subset_layout_context_t *c, const void *base, const void *f_sub = nullptr) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
auto *out = c->subset_context->serializer->embed (this);
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
|
||||||
|
if (!f_sub)
|
||||||
|
return_trace (out->offset.serialize_subset (c->subset_context, offset, base, c, &tag));
|
||||||
|
|
||||||
|
const Feature& f = *reinterpret_cast<const Feature *> (f_sub);
|
||||||
|
auto *s = c->subset_context->serializer;
|
||||||
|
s->push ();
|
||||||
|
|
||||||
|
out->offset = 0;
|
||||||
|
bool ret = f.subset (c->subset_context, c, &tag);
|
||||||
|
if (ret)
|
||||||
|
s->add_link (out->offset, s->pop_pack ());
|
||||||
|
else
|
||||||
|
s->pop_discard ();
|
||||||
|
|
||||||
|
return_trace (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sanitize (hb_sanitize_context_t *c, const void *base) const
|
||||||
|
{
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
const Record_sanitize_closure_t closure = {tag, base};
|
||||||
|
return_trace (c->check_struct (this) && offset.sanitize (c, base, &closure));
|
||||||
|
}
|
||||||
|
|
||||||
|
Tag tag; /* 4-byte Tag identifier */
|
||||||
|
Offset16To<Type>
|
||||||
|
offset; /* Offset from beginning of object holding
|
||||||
|
* the Record */
|
||||||
|
public:
|
||||||
|
DEFINE_SIZE_STATIC (6);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
struct RecordArrayOf : SortedArray16Of<Record<Type>>
|
||||||
|
{
|
||||||
|
const Offset16To<Type>& get_offset (unsigned int i) const
|
||||||
|
{ return (*this)[i].offset; }
|
||||||
|
Offset16To<Type>& get_offset (unsigned int i)
|
||||||
|
{ return (*this)[i].offset; }
|
||||||
|
const Tag& get_tag (unsigned int i) const
|
||||||
|
{ return (*this)[i].tag; }
|
||||||
|
unsigned int get_tags (unsigned int start_offset,
|
||||||
|
unsigned int *record_count /* IN/OUT */,
|
||||||
|
hb_tag_t *record_tags /* OUT */) const
|
||||||
|
{
|
||||||
|
if (record_count)
|
||||||
|
{
|
||||||
|
+ this->sub_array (start_offset, record_count)
|
||||||
|
| hb_map (&Record<Type>::tag)
|
||||||
|
| hb_sink (hb_array (record_tags, *record_count))
|
||||||
|
;
|
||||||
|
}
|
||||||
|
return this->len;
|
||||||
|
}
|
||||||
|
bool find_index (hb_tag_t tag, unsigned int *index) const
|
||||||
|
{
|
||||||
|
return this->bfind (tag, index, HB_NOT_FOUND_STORE, Index::NOT_FOUND_INDEX);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Type>
|
||||||
|
struct RecordListOf : RecordArrayOf<Type>
|
||||||
|
{
|
||||||
|
const Type& operator [] (unsigned int i) const
|
||||||
|
{ return this+this->get_offset (i); }
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t *c,
|
||||||
|
hb_subset_layout_context_t *l) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
auto *out = c->serializer->start_embed (*this);
|
||||||
|
if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
|
||||||
|
|
||||||
|
+ this->iter ()
|
||||||
|
| hb_apply (subset_record_array (l, out, this))
|
||||||
|
;
|
||||||
|
return_trace (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SANITIZE (this);
|
||||||
|
return_trace (RecordArrayOf<Type>::sanitize (c, this));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct RecordListOfFeature : RecordListOf<Feature>
|
struct RecordListOfFeature : RecordListOf<Feature>
|
||||||
{
|
{
|
||||||
bool subset (hb_subset_context_t *c,
|
bool subset (hb_subset_context_t *c,
|
||||||
@@ -907,11 +981,20 @@ struct RecordListOfFeature : RecordListOf<Feature>
|
|||||||
if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
|
if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
|
||||||
|
|
||||||
unsigned count = this->len;
|
unsigned count = this->len;
|
||||||
|
|
||||||
+ hb_zip (*this, hb_range (count))
|
+ hb_zip (*this, hb_range (count))
|
||||||
| hb_filter (l->feature_index_map, hb_second)
|
| hb_filter (l->feature_index_map, hb_second)
|
||||||
| hb_map (hb_first)
|
| hb_apply ([l, out, this] (const hb_pair_t<const Record<Feature>&, unsigned>& _)
|
||||||
| hb_apply (subset_record_array (l, out, this))
|
{
|
||||||
|
const Feature *f_sub = nullptr;
|
||||||
|
const Feature **f = nullptr;
|
||||||
|
if (l->feature_substitutes_map->has (_.second, &f))
|
||||||
|
f_sub = *f;
|
||||||
|
|
||||||
|
subset_record_array (l, out, this, f_sub) (_.first);
|
||||||
|
})
|
||||||
;
|
;
|
||||||
|
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -2692,6 +2775,13 @@ struct VariationStore
|
|||||||
/*
|
/*
|
||||||
* Feature Variations
|
* Feature Variations
|
||||||
*/
|
*/
|
||||||
|
enum Cond_with_Var_flag_t
|
||||||
|
{
|
||||||
|
KEEP_COND_WITH_VAR = 0,
|
||||||
|
DROP_COND_WITH_VAR = 1,
|
||||||
|
DROP_RECORD_WITH_VAR = 2,
|
||||||
|
MEM_ERR_WITH_VAR = 3,
|
||||||
|
};
|
||||||
|
|
||||||
struct ConditionFormat1
|
struct ConditionFormat1
|
||||||
{
|
{
|
||||||
@@ -2702,10 +2792,52 @@ struct ConditionFormat1
|
|||||||
TRACE_SUBSET (this);
|
TRACE_SUBSET (this);
|
||||||
auto *out = c->serializer->embed (this);
|
auto *out = c->serializer->embed (this);
|
||||||
if (unlikely (!out)) return_trace (false);
|
if (unlikely (!out)) return_trace (false);
|
||||||
return_trace (true);
|
|
||||||
|
const hb_map_t *index_map = c->plan->axes_index_map;
|
||||||
|
if (index_map->is_empty ()) return_trace (true);
|
||||||
|
|
||||||
|
if (!index_map->has (axisIndex))
|
||||||
|
return_trace (false);
|
||||||
|
|
||||||
|
return_trace (c->serializer->check_assign (out->axisIndex, index_map->get (axisIndex),
|
||||||
|
HB_SERIALIZE_ERROR_INT_OVERFLOW));
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c,
|
||||||
|
hb_map_t *condition_map /* OUT */) const
|
||||||
|
{
|
||||||
|
//invalid axis index, drop the entire record
|
||||||
|
if (!c->axes_index_tag_map->has (axisIndex))
|
||||||
|
return DROP_RECORD_WITH_VAR;
|
||||||
|
|
||||||
|
hb_tag_t axis_tag = c->axes_index_tag_map->get (axisIndex);
|
||||||
|
|
||||||
|
//axis not pinned, keep the condition
|
||||||
|
if (!c->axes_location->has (axis_tag))
|
||||||
|
{
|
||||||
|
// add axisIndex->value into the hashmap so we can check if the record is
|
||||||
|
// unique with variations
|
||||||
|
int16_t min_val = filterRangeMinValue;
|
||||||
|
int16_t max_val = filterRangeMaxValue;
|
||||||
|
hb_codepoint_t val = (max_val << 16) + min_val;
|
||||||
|
|
||||||
|
condition_map->set (axisIndex, val);
|
||||||
|
return KEEP_COND_WITH_VAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
//axis pinned, check if condition is met
|
||||||
|
//TODO: add check for axis Ranges
|
||||||
|
int v = c->axes_location->get (axis_tag);
|
||||||
|
|
||||||
|
//condition not met, drop the entire record
|
||||||
|
if (v < filterRangeMinValue || v > filterRangeMaxValue)
|
||||||
|
return DROP_RECORD_WITH_VAR;
|
||||||
|
|
||||||
|
//axis pinned and condition met, drop the condition
|
||||||
|
return DROP_COND_WITH_VAR;
|
||||||
|
}
|
||||||
|
|
||||||
bool evaluate (const int *coords, unsigned int coord_len) const
|
bool evaluate (const int *coords, unsigned int coord_len) const
|
||||||
{
|
{
|
||||||
int coord = axisIndex < coord_len ? coords[axisIndex] : 0;
|
int coord = axisIndex < coord_len ? coords[axisIndex] : 0;
|
||||||
@@ -2737,6 +2869,15 @@ struct Condition
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c,
|
||||||
|
hb_map_t *condition_map /* OUT */) const
|
||||||
|
{
|
||||||
|
switch (u.format) {
|
||||||
|
case 1: return u.format1.keep_with_variations (c, condition_map);
|
||||||
|
default:return KEEP_COND_WITH_VAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <typename context_t, typename ...Ts>
|
template <typename context_t, typename ...Ts>
|
||||||
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
|
typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
|
||||||
{
|
{
|
||||||
@@ -2778,15 +2919,65 @@ struct ConditionSet
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool subset (hb_subset_context_t *c) const
|
Cond_with_Var_flag_t keep_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
|
||||||
|
{
|
||||||
|
hb_map_t *condition_map = hb_map_create ();
|
||||||
|
if (unlikely (!condition_map)) return MEM_ERR_WITH_VAR;
|
||||||
|
hb::shared_ptr<hb_map_t> p {condition_map};
|
||||||
|
|
||||||
|
hb_set_t *cond_set = hb_set_create ();
|
||||||
|
if (unlikely (!cond_set)) return MEM_ERR_WITH_VAR;
|
||||||
|
hb::shared_ptr<hb_set_t> s {cond_set};
|
||||||
|
|
||||||
|
unsigned num_kept_cond = 0, cond_idx = 0;
|
||||||
|
for (const auto& offset : conditions)
|
||||||
|
{
|
||||||
|
Cond_with_Var_flag_t ret = (this+offset).keep_with_variations (c, condition_map);
|
||||||
|
// one condition is not met, drop the entire record
|
||||||
|
if (ret == DROP_RECORD_WITH_VAR)
|
||||||
|
return DROP_RECORD_WITH_VAR;
|
||||||
|
|
||||||
|
// axis not pinned, keep this condition
|
||||||
|
if (ret == KEEP_COND_WITH_VAR)
|
||||||
|
{
|
||||||
|
cond_set->add (cond_idx);
|
||||||
|
num_kept_cond++;
|
||||||
|
}
|
||||||
|
cond_idx++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// all conditions met
|
||||||
|
if (num_kept_cond == 0) return DROP_COND_WITH_VAR;
|
||||||
|
|
||||||
|
//check if condition_set is unique with variations
|
||||||
|
if (c->conditionset_map->has (p))
|
||||||
|
//duplicate found, drop the entire record
|
||||||
|
return DROP_RECORD_WITH_VAR;
|
||||||
|
|
||||||
|
c->conditionset_map->set (p, 1);
|
||||||
|
c->record_cond_idx_map->set (c->cur_record_idx, s);
|
||||||
|
|
||||||
|
return KEEP_COND_WITH_VAR;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t *c,
|
||||||
|
hb_subset_layout_context_t *l) const
|
||||||
{
|
{
|
||||||
TRACE_SUBSET (this);
|
TRACE_SUBSET (this);
|
||||||
auto *out = c->serializer->start_embed (this);
|
auto *out = c->serializer->start_embed (this);
|
||||||
if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
|
if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
|
||||||
|
|
||||||
+ conditions.iter ()
|
hb_set_t *retained_cond_set = nullptr;
|
||||||
| hb_apply (subset_offset_array (c, out->conditions, this))
|
if (l->feature_record_cond_idx_map != nullptr)
|
||||||
;
|
retained_cond_set = l->feature_record_cond_idx_map->get (l->cur_feature_var_record_idx);
|
||||||
|
|
||||||
|
unsigned int count = conditions.len;
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (retained_cond_set != nullptr && !retained_cond_set->has (i))
|
||||||
|
continue;
|
||||||
|
subset_offset_array (c, out->conditions, this) (conditions[i]);
|
||||||
|
}
|
||||||
|
|
||||||
return_trace (bool (out->conditions));
|
return_trace (bool (out->conditions));
|
||||||
}
|
}
|
||||||
@@ -2820,10 +3011,19 @@ struct FeatureTableSubstitutionRecord
|
|||||||
feature_indexes->add (featureIndex);
|
feature_indexes->add (featureIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void collect_feature_substitutes_with_variations (hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map,
|
||||||
|
const hb_set_t *feature_indices,
|
||||||
|
const void *base) const
|
||||||
|
{
|
||||||
|
if (feature_indices->has (featureIndex))
|
||||||
|
feature_substitutes_map->set (featureIndex, &(base+feature));
|
||||||
|
}
|
||||||
|
|
||||||
bool subset (hb_subset_layout_context_t *c, const void *base) const
|
bool subset (hb_subset_layout_context_t *c, const void *base) const
|
||||||
{
|
{
|
||||||
TRACE_SUBSET (this);
|
TRACE_SUBSET (this);
|
||||||
if (!c->feature_index_map->has (featureIndex)) {
|
if (!c->feature_index_map->has (featureIndex) ||
|
||||||
|
c->feature_substitutes_map->has (featureIndex)) {
|
||||||
// Feature that is being substituted is not being retained, so we don't
|
// Feature that is being substituted is not being retained, so we don't
|
||||||
// need this.
|
// need this.
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
@@ -2865,10 +3065,16 @@ struct FeatureTableSubstitution
|
|||||||
}
|
}
|
||||||
|
|
||||||
void collect_lookups (const hb_set_t *feature_indexes,
|
void collect_lookups (const hb_set_t *feature_indexes,
|
||||||
|
const hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map,
|
||||||
hb_set_t *lookup_indexes /* OUT */) const
|
hb_set_t *lookup_indexes /* OUT */) const
|
||||||
{
|
{
|
||||||
+ hb_iter (substitutions)
|
+ hb_iter (substitutions)
|
||||||
| hb_filter (feature_indexes, &FeatureTableSubstitutionRecord::featureIndex)
|
| hb_filter (feature_indexes, &FeatureTableSubstitutionRecord::featureIndex)
|
||||||
|
| hb_filter ([feature_substitutes_map] (const FeatureTableSubstitutionRecord& record)
|
||||||
|
{
|
||||||
|
if (feature_substitutes_map == nullptr) return true;
|
||||||
|
return !feature_substitutes_map->has (record.featureIndex);
|
||||||
|
})
|
||||||
| hb_apply ([this, lookup_indexes] (const FeatureTableSubstitutionRecord& r)
|
| hb_apply ([this, lookup_indexes] (const FeatureTableSubstitutionRecord& r)
|
||||||
{ r.collect_lookups (this, lookup_indexes); })
|
{ r.collect_lookups (this, lookup_indexes); })
|
||||||
;
|
;
|
||||||
@@ -2890,6 +3096,12 @@ struct FeatureTableSubstitution
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
|
||||||
|
{
|
||||||
|
for (const FeatureTableSubstitutionRecord& record : substitutions)
|
||||||
|
record.collect_feature_substitutes_with_variations (c->feature_substitutes_map, c->feature_indices, this);
|
||||||
|
}
|
||||||
|
|
||||||
bool subset (hb_subset_context_t *c,
|
bool subset (hb_subset_context_t *c,
|
||||||
hb_subset_layout_context_t *l) const
|
hb_subset_layout_context_t *l) const
|
||||||
{
|
{
|
||||||
@@ -2929,9 +3141,10 @@ struct FeatureVariationRecord
|
|||||||
|
|
||||||
void collect_lookups (const void *base,
|
void collect_lookups (const void *base,
|
||||||
const hb_set_t *feature_indexes,
|
const hb_set_t *feature_indexes,
|
||||||
|
const hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map,
|
||||||
hb_set_t *lookup_indexes /* OUT */) const
|
hb_set_t *lookup_indexes /* OUT */) const
|
||||||
{
|
{
|
||||||
return (base+substitutions).collect_lookups (feature_indexes, lookup_indexes);
|
return (base+substitutions).collect_lookups (feature_indexes, feature_substitutes_map, lookup_indexes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void closure_features (const void *base,
|
void closure_features (const void *base,
|
||||||
@@ -2946,13 +3159,25 @@ struct FeatureVariationRecord
|
|||||||
return (base+substitutions).intersects_features (feature_index_map);
|
return (base+substitutions).intersects_features (feature_index_map);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c,
|
||||||
|
const void *base) const
|
||||||
|
{
|
||||||
|
// ret == 1, all conditions met
|
||||||
|
if ((base+conditions).keep_with_variations (c) == DROP_COND_WITH_VAR &&
|
||||||
|
c->apply)
|
||||||
|
{
|
||||||
|
(base+substitutions).collect_feature_substitutes_with_variations (c);
|
||||||
|
c->apply = false; // set variations only once
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool subset (hb_subset_layout_context_t *c, const void *base) const
|
bool subset (hb_subset_layout_context_t *c, const void *base) const
|
||||||
{
|
{
|
||||||
TRACE_SUBSET (this);
|
TRACE_SUBSET (this);
|
||||||
auto *out = c->subset_context->serializer->embed (this);
|
auto *out = c->subset_context->serializer->embed (this);
|
||||||
if (unlikely (!out)) return_trace (false);
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
|
||||||
out->conditions.serialize_subset (c->subset_context, conditions, base);
|
out->conditions.serialize_subset (c->subset_context, conditions, base, c);
|
||||||
out->substitutions.serialize_subset (c->subset_context, substitutions, base, c);
|
out->substitutions.serialize_subset (c->subset_context, substitutions, base, c);
|
||||||
|
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
@@ -3002,6 +3227,16 @@ struct FeatureVariations
|
|||||||
return (this+record.substitutions).find_substitute (feature_index);
|
return (this+record.substitutions).find_substitute (feature_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
|
||||||
|
{
|
||||||
|
unsigned int count = varRecords.len;
|
||||||
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
c->cur_record_idx = i;
|
||||||
|
varRecords[i].collect_feature_substitutes_with_variations (c, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FeatureVariations* copy (hb_serialize_context_t *c) const
|
FeatureVariations* copy (hb_serialize_context_t *c) const
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
@@ -3009,17 +3244,25 @@ struct FeatureVariations
|
|||||||
}
|
}
|
||||||
|
|
||||||
void collect_lookups (const hb_set_t *feature_indexes,
|
void collect_lookups (const hb_set_t *feature_indexes,
|
||||||
|
const hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map,
|
||||||
hb_set_t *lookup_indexes /* OUT */) const
|
hb_set_t *lookup_indexes /* OUT */) const
|
||||||
{
|
{
|
||||||
for (const FeatureVariationRecord& r : varRecords)
|
for (const FeatureVariationRecord& r : varRecords)
|
||||||
r.collect_lookups (this, feature_indexes, lookup_indexes);
|
r.collect_lookups (this, feature_indexes, feature_substitutes_map, lookup_indexes);
|
||||||
}
|
}
|
||||||
|
|
||||||
void closure_features (const hb_map_t *lookup_indexes,
|
void closure_features (const hb_map_t *lookup_indexes,
|
||||||
|
const hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map,
|
||||||
hb_set_t *feature_indexes /* OUT */) const
|
hb_set_t *feature_indexes /* OUT */) const
|
||||||
{
|
{
|
||||||
for (const FeatureVariationRecord& record : varRecords)
|
unsigned int count = varRecords.len;
|
||||||
record.closure_features (this, lookup_indexes, feature_indexes);
|
for (unsigned int i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (feature_record_cond_idx_map != nullptr &&
|
||||||
|
!feature_record_cond_idx_map->has (i))
|
||||||
|
continue;
|
||||||
|
varRecords[i].closure_features (this, lookup_indexes, feature_indexes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool subset (hb_subset_context_t *c,
|
bool subset (hb_subset_context_t *c,
|
||||||
@@ -3041,7 +3284,13 @@ struct FeatureVariations
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsigned count = (unsigned) (keep_up_to + 1);
|
unsigned count = (unsigned) (keep_up_to + 1);
|
||||||
for (unsigned i = 0; i < count; i++) {
|
for (unsigned i = 0; i < count; i++)
|
||||||
|
{
|
||||||
|
if (l->feature_record_cond_idx_map != nullptr &&
|
||||||
|
!l->feature_record_cond_idx_map->has (i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
l->cur_feature_var_record_idx = i;
|
||||||
subset_record_array (l, &(out->varRecords), this) (varRecords[i]);
|
subset_record_array (l, &(out->varRecords), this) (varRecords[i]);
|
||||||
}
|
}
|
||||||
return_trace (bool (out->varRecords));
|
return_trace (bool (out->varRecords));
|
||||||
|
|||||||
22
thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
vendored
22
thirdparty/harfbuzz/src/hb-ot-layout-gsubgpos.hh
vendored
@@ -4236,13 +4236,19 @@ struct GSUBGPOS
|
|||||||
}
|
}
|
||||||
|
|
||||||
void feature_variation_collect_lookups (const hb_set_t *feature_indexes,
|
void feature_variation_collect_lookups (const hb_set_t *feature_indexes,
|
||||||
|
const hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map,
|
||||||
hb_set_t *lookup_indexes /* OUT */) const
|
hb_set_t *lookup_indexes /* OUT */) const
|
||||||
{
|
{
|
||||||
#ifndef HB_NO_VAR
|
#ifndef HB_NO_VAR
|
||||||
get_feature_variations ().collect_lookups (feature_indexes, lookup_indexes);
|
get_feature_variations ().collect_lookups (feature_indexes, feature_substitutes_map, lookup_indexes);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef HB_NO_VAR
|
||||||
|
void collect_feature_substitutes_with_variations (hb_collect_feature_substitutes_with_var_context_t *c) const
|
||||||
|
{ get_feature_variations ().collect_feature_substitutes_with_variations (c); }
|
||||||
|
#endif
|
||||||
|
|
||||||
template <typename TLookup>
|
template <typename TLookup>
|
||||||
void closure_lookups (hb_face_t *face,
|
void closure_lookups (hb_face_t *face,
|
||||||
const hb_set_t *glyphs,
|
const hb_set_t *glyphs,
|
||||||
@@ -4278,6 +4284,8 @@ struct GSUBGPOS
|
|||||||
}
|
}
|
||||||
|
|
||||||
void prune_features (const hb_map_t *lookup_indices, /* IN */
|
void prune_features (const hb_map_t *lookup_indices, /* IN */
|
||||||
|
const hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map, /* IN */
|
||||||
|
const hb_hashmap_t<unsigned, const Feature*> *feature_substitutes_map, /* IN */
|
||||||
hb_set_t *feature_indices /* IN/OUT */) const
|
hb_set_t *feature_indices /* IN/OUT */) const
|
||||||
{
|
{
|
||||||
#ifndef HB_NO_VAR
|
#ifndef HB_NO_VAR
|
||||||
@@ -4285,7 +4293,7 @@ struct GSUBGPOS
|
|||||||
// if the FeatureVariation's table and the alternate version(s) intersect the
|
// if the FeatureVariation's table and the alternate version(s) intersect the
|
||||||
// set of lookup indices.
|
// set of lookup indices.
|
||||||
hb_set_t alternate_feature_indices;
|
hb_set_t alternate_feature_indices;
|
||||||
get_feature_variations ().closure_features (lookup_indices, &alternate_feature_indices);
|
get_feature_variations ().closure_features (lookup_indices, feature_record_cond_idx_map, &alternate_feature_indices);
|
||||||
if (unlikely (alternate_feature_indices.in_error()))
|
if (unlikely (alternate_feature_indices.in_error()))
|
||||||
{
|
{
|
||||||
feature_indices->err ();
|
feature_indices->err ();
|
||||||
@@ -4295,7 +4303,6 @@ struct GSUBGPOS
|
|||||||
|
|
||||||
for (unsigned i : feature_indices->iter())
|
for (unsigned i : feature_indices->iter())
|
||||||
{
|
{
|
||||||
const Feature& f = get_feature (i);
|
|
||||||
hb_tag_t tag = get_feature_tag (i);
|
hb_tag_t tag = get_feature_tag (i);
|
||||||
if (tag == HB_TAG ('p', 'r', 'e', 'f'))
|
if (tag == HB_TAG ('p', 'r', 'e', 'f'))
|
||||||
// Note: Never ever drop feature 'pref', even if it's empty.
|
// Note: Never ever drop feature 'pref', even if it's empty.
|
||||||
@@ -4305,11 +4312,16 @@ struct GSUBGPOS
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
if (!f.featureParams.is_null () &&
|
const Feature *f = &(get_feature (i));
|
||||||
|
const Feature** p = nullptr;
|
||||||
|
if (feature_substitutes_map->has (i, &p))
|
||||||
|
f = *p;
|
||||||
|
|
||||||
|
if (!f->featureParams.is_null () &&
|
||||||
tag == HB_TAG ('s', 'i', 'z', 'e'))
|
tag == HB_TAG ('s', 'i', 'z', 'e'))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!f.intersects_lookup_indexes (lookup_indices)
|
if (!f->intersects_lookup_indexes (lookup_indices)
|
||||||
#ifndef HB_NO_VAR
|
#ifndef HB_NO_VAR
|
||||||
&& !alternate_feature_indices.has (i)
|
&& !alternate_feature_indices.has (i)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
73
thirdparty/harfbuzz/src/hb-ot-layout.cc
vendored
73
thirdparty/harfbuzz/src/hb-ot-layout.cc
vendored
@@ -1271,7 +1271,7 @@ hb_ot_layout_collect_lookups (hb_face_t *face,
|
|||||||
hb_set_next (&feature_indexes, &feature_index);)
|
hb_set_next (&feature_indexes, &feature_index);)
|
||||||
g.get_feature (feature_index).add_lookup_indexes_to (lookup_indexes);
|
g.get_feature (feature_index).add_lookup_indexes_to (lookup_indexes);
|
||||||
|
|
||||||
g.feature_variation_collect_lookups (&feature_indexes, lookup_indexes);
|
g.feature_variation_collect_lookups (&feature_indexes, nullptr, lookup_indexes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1709,6 +1709,8 @@ hb_ot_layout_get_size_params (hb_face_t *face,
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hb_ot_layout_feature_get_name_ids:
|
* hb_ot_layout_feature_get_name_ids:
|
||||||
* @face: #hb_face_t to work upon
|
* @face: #hb_face_t to work upon
|
||||||
@@ -2341,6 +2343,7 @@ struct hb_get_glyph_alternates_dispatch_t :
|
|||||||
( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) )
|
( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) )
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef HB_NO_LAYOUT_RARELY_USED
|
||||||
/**
|
/**
|
||||||
* hb_ot_layout_lookup_get_glyph_alternates:
|
* hb_ot_layout_lookup_get_glyph_alternates:
|
||||||
* @face: a face.
|
* @face: a face.
|
||||||
@@ -2373,4 +2376,72 @@ hb_ot_layout_lookup_get_glyph_alternates (hb_face_t *face,
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
struct hb_position_single_dispatch_t :
|
||||||
|
hb_dispatch_context_t<hb_position_single_dispatch_t, bool>
|
||||||
|
{
|
||||||
|
static return_t default_return_value () { return false; }
|
||||||
|
bool stop_sublookup_iteration (return_t r) const { return r; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
template <typename T, typename ...Ts> auto
|
||||||
|
_dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
|
||||||
|
( obj.position_single (std::forward<Ts> (ds)...) )
|
||||||
|
template <typename T, typename ...Ts> auto
|
||||||
|
_dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN
|
||||||
|
( default_return_value () )
|
||||||
|
public:
|
||||||
|
template <typename T, typename ...Ts> auto
|
||||||
|
dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
|
||||||
|
( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) )
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* hb_ot_layout_lookup_get_optical_bound:
|
||||||
|
* @font: a font.
|
||||||
|
* @lookup_index: index of the feature lookup to query.
|
||||||
|
* @direction: edge of the glyph to query.
|
||||||
|
* @glyph: a glyph id.
|
||||||
|
*
|
||||||
|
* Fetches the optical bound of a glyph positioned at the margin of text.
|
||||||
|
* The direction identifies which edge of the glyph to query.
|
||||||
|
*
|
||||||
|
* Return value: Adjustment value. Negative values mean the glyph will stick out of the margin.
|
||||||
|
*
|
||||||
|
* Since: 5.3.0
|
||||||
|
**/
|
||||||
|
hb_position_t
|
||||||
|
hb_ot_layout_lookup_get_optical_bound (hb_font_t *font,
|
||||||
|
unsigned lookup_index,
|
||||||
|
hb_direction_t direction,
|
||||||
|
hb_codepoint_t glyph)
|
||||||
|
{
|
||||||
|
const OT::PosLookup &lookup = font->face->table.GPOS->table->get_lookup (lookup_index);
|
||||||
|
hb_glyph_position_t pos = {0};
|
||||||
|
hb_position_single_dispatch_t c;
|
||||||
|
lookup.dispatch (&c, font, direction, glyph, pos);
|
||||||
|
hb_position_t ret = 0;
|
||||||
|
switch (direction)
|
||||||
|
{
|
||||||
|
case HB_DIRECTION_LTR:
|
||||||
|
ret = pos.x_offset;
|
||||||
|
break;
|
||||||
|
case HB_DIRECTION_RTL:
|
||||||
|
ret = pos.x_advance - pos.x_offset;
|
||||||
|
break;
|
||||||
|
case HB_DIRECTION_TTB:
|
||||||
|
ret = pos.y_offset;
|
||||||
|
break;
|
||||||
|
case HB_DIRECTION_BTT:
|
||||||
|
ret = pos.y_advance - pos.y_offset;
|
||||||
|
break;
|
||||||
|
case HB_DIRECTION_INVALID:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
11
thirdparty/harfbuzz/src/hb-ot-layout.h
vendored
11
thirdparty/harfbuzz/src/hb-ot-layout.h
vendored
@@ -403,6 +403,16 @@ hb_ot_layout_get_size_params (hb_face_t *face,
|
|||||||
unsigned int *range_start, /* OUT. May be NULL */
|
unsigned int *range_start, /* OUT. May be NULL */
|
||||||
unsigned int *range_end /* OUT. May be NULL */);
|
unsigned int *range_end /* OUT. May be NULL */);
|
||||||
|
|
||||||
|
HB_EXTERN hb_position_t
|
||||||
|
hb_ot_layout_lookup_get_optical_bound (hb_font_t *font,
|
||||||
|
unsigned lookup_index,
|
||||||
|
hb_direction_t direction,
|
||||||
|
hb_codepoint_t glyph);
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* GSUB/GPOS
|
||||||
|
*/
|
||||||
|
|
||||||
HB_EXTERN hb_bool_t
|
HB_EXTERN hb_bool_t
|
||||||
hb_ot_layout_feature_get_name_ids (hb_face_t *face,
|
hb_ot_layout_feature_get_name_ids (hb_face_t *face,
|
||||||
@@ -423,6 +433,7 @@ hb_ot_layout_feature_get_characters (hb_face_t *face,
|
|||||||
unsigned int *char_count /* IN/OUT. May be NULL */,
|
unsigned int *char_count /* IN/OUT. May be NULL */,
|
||||||
hb_codepoint_t *characters /* OUT. May be NULL */);
|
hb_codepoint_t *characters /* OUT. May be NULL */);
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* BASE
|
* BASE
|
||||||
*/
|
*/
|
||||||
|
|||||||
2
thirdparty/harfbuzz/src/hb-ot-post-table.hh
vendored
2
thirdparty/harfbuzz/src/hb-ot-post-table.hh
vendored
@@ -282,7 +282,7 @@ struct post
|
|||||||
* 0x00020000 for version 2.0
|
* 0x00020000 for version 2.0
|
||||||
* 0x00025000 for version 2.5 (deprecated)
|
* 0x00025000 for version 2.5 (deprecated)
|
||||||
* 0x00030000 for version 3.0 */
|
* 0x00030000 for version 3.0 */
|
||||||
HBFixed italicAngle; /* Italic angle in counter-clockwise degrees
|
F16DOT16 italicAngle; /* Italic angle in counter-clockwise degrees
|
||||||
* from the vertical. Zero for upright text,
|
* from the vertical. Zero for upright text,
|
||||||
* negative for text that leans to the right
|
* negative for text that leans to the right
|
||||||
* (forward). */
|
* (forward). */
|
||||||
|
|||||||
8
thirdparty/harfbuzz/src/hb-ot-shape.cc
vendored
8
thirdparty/harfbuzz/src/hb-ot-shape.cc
vendored
@@ -527,18 +527,20 @@ hb_set_unicode_props (hb_buffer_t *buffer)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Or part of the Other_Grapheme_Extend that is not marks.
|
/* Or part of the Other_Grapheme_Extend that is not marks.
|
||||||
* As of Unicode 11 that is just:
|
* As of Unicode 15 that is just:
|
||||||
*
|
*
|
||||||
* 200C ; Other_Grapheme_Extend # Cf ZERO WIDTH NON-JOINER
|
* 200C ; Other_Grapheme_Extend # Cf ZERO WIDTH NON-JOINER
|
||||||
* FF9E..FF9F ; Other_Grapheme_Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
|
* FF9E..FF9F ; Other_Grapheme_Extend # Lm [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
|
||||||
* E0020..E007F ; Other_Grapheme_Extend # Cf [96] TAG SPACE..CANCEL TAG
|
* E0020..E007F ; Other_Grapheme_Extend # Cf [96] TAG SPACE..CANCEL TAG
|
||||||
*
|
*
|
||||||
* ZWNJ is special, we don't want to merge it as there's no need, and keeping
|
* ZWNJ is special, we don't want to merge it as there's no need, and keeping
|
||||||
* it separate results in more granular clusters. Ignore Katakana for now.
|
* it separate results in more granular clusters.
|
||||||
* Tags are used for Emoji sub-region flag sequences:
|
* Tags are used for Emoji sub-region flag sequences:
|
||||||
* https://github.com/harfbuzz/harfbuzz/issues/1556
|
* https://github.com/harfbuzz/harfbuzz/issues/1556
|
||||||
|
* Katakana ones were requested:
|
||||||
|
* https://github.com/harfbuzz/harfbuzz/issues/3844
|
||||||
*/
|
*/
|
||||||
else if (unlikely (hb_in_range<hb_codepoint_t> (info[i].codepoint, 0xE0020u, 0xE007Fu)))
|
else if (unlikely (hb_in_ranges<hb_codepoint_t> (info[i].codepoint, 0xFF9Eu, 0xFF9Fu, 0xE0020u, 0xE007Fu)))
|
||||||
_hb_glyph_info_set_continuation (&info[i]);
|
_hb_glyph_info_set_continuation (&info[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
120
thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh
vendored
120
thirdparty/harfbuzz/src/hb-ot-shaper-use-table.hh
vendored
@@ -25,6 +25,7 @@
|
|||||||
* # Updated for Unicode 12.1 by Andrew Glass 2019-05-24
|
* # Updated for Unicode 12.1 by Andrew Glass 2019-05-24
|
||||||
* # Updated for Unicode 13.0 by Andrew Glass 2020-07-28
|
* # Updated for Unicode 13.0 by Andrew Glass 2020-07-28
|
||||||
* # Updated for Unicode 14.0 by Andrew Glass 2021-09-25
|
* # Updated for Unicode 14.0 by Andrew Glass 2021-09-25
|
||||||
|
* # Updated for Unicode 15.0 by Andrew Glass 2022-09-16
|
||||||
* # Override values For Indic_Positional_Category
|
* # Override values For Indic_Positional_Category
|
||||||
* # Not derivable
|
* # Not derivable
|
||||||
* # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17
|
* # Initial version based on Unicode 7.0 by Andrew Glass 2014-03-17
|
||||||
@@ -34,6 +35,7 @@
|
|||||||
* # Updated for Unicode 12.1 by Andrew Glass 2019-05-30
|
* # Updated for Unicode 12.1 by Andrew Glass 2019-05-30
|
||||||
* # Updated for Unicode 13.0 by Andrew Glass 2020-07-28
|
* # Updated for Unicode 13.0 by Andrew Glass 2020-07-28
|
||||||
* # Updated for Unicode 14.0 by Andrew Glass 2021-09-28
|
* # Updated for Unicode 14.0 by Andrew Glass 2021-09-28
|
||||||
|
* # Updated for Unicode 15.0 by Andrew Glass 2022-09-16
|
||||||
* UnicodeData.txt does not have a header.
|
* UnicodeData.txt does not have a header.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -90,7 +92,7 @@
|
|||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
|
|
||||||
static const uint8_t
|
static const uint8_t
|
||||||
hb_use_u8[3115] =
|
hb_use_u8[3141] =
|
||||||
{
|
{
|
||||||
16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 51, 57, 58, 179, 195, 61,
|
16, 50, 51, 51, 51, 52, 51, 83, 118, 131, 51, 57, 58, 179, 195, 61,
|
||||||
51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
|
||||||
@@ -125,11 +127,11 @@ hb_use_u8[3115] =
|
|||||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 88, 89, 2, 2, 2, 2, 2,
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 88, 89, 2, 2, 2, 2, 2,
|
||||||
2, 2, 2, 90, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
2, 2, 2, 90, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
2, 2, 2, 91, 2, 2, 92, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
2, 2, 2, 91, 2, 2, 92, 2, 2, 2, 93, 2, 2, 2, 2, 2,
|
||||||
2, 2, 2, 93, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
2, 2, 2, 94, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
2, 94, 94, 95, 96, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
|
2, 95, 95, 96, 97, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
|
||||||
94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94, 94,
|
95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95, 95,
|
||||||
94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
|
95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
|
||||||
0, 2, 2, 2, 2, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4,
|
0, 2, 2, 2, 2, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 4,
|
||||||
0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
|
0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 6, 7, 0, 0, 0, 0, 0, 0,
|
||||||
@@ -226,70 +228,72 @@ hb_use_u8[3115] =
|
|||||||
0, 9, 47, 2, 2, 2, 2, 2, 2, 2, 2, 2, 125, 18, 20, 151,
|
0, 9, 47, 2, 2, 2, 2, 2, 2, 2, 2, 2, 125, 18, 20, 151,
|
||||||
20, 19, 152, 153, 2, 2, 2, 2, 2, 0, 0, 63, 154, 0, 0, 0,
|
20, 19, 152, 153, 2, 2, 2, 2, 2, 0, 0, 63, 154, 0, 0, 0,
|
||||||
0, 2, 11, 0, 0, 0, 0, 0, 0, 2, 63, 23, 18, 18, 18, 20,
|
0, 2, 11, 0, 0, 0, 0, 0, 0, 2, 63, 23, 18, 18, 18, 20,
|
||||||
20, 106, 155, 0, 0, 156, 157, 29, 158, 28, 2, 2, 2, 2, 2, 2,
|
20, 106, 155, 0, 0, 54, 156, 29, 157, 28, 2, 2, 2, 2, 2, 2,
|
||||||
2, 2, 2, 2, 2, 2, 2, 21, 17, 20, 20, 159, 42, 0, 0, 0,
|
2, 2, 2, 2, 2, 2, 2, 21, 17, 20, 20, 158, 42, 0, 0, 0,
|
||||||
47, 125, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 7, 7, 2, 2,
|
47, 125, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 7, 7, 2, 2,
|
||||||
28, 2, 2, 2, 2, 2, 2, 2, 28, 2, 2, 2, 2, 2, 2, 2,
|
28, 2, 2, 2, 2, 2, 2, 2, 28, 2, 2, 2, 2, 2, 2, 2,
|
||||||
8, 16, 17, 19, 20, 160, 29, 0, 0, 9, 9, 28, 2, 2, 2, 7,
|
8, 16, 17, 19, 20, 159, 29, 0, 0, 9, 9, 28, 2, 2, 2, 7,
|
||||||
28, 7, 2, 28, 2, 2, 56, 15, 21, 14, 21, 45, 30, 31, 30, 32,
|
28, 7, 2, 28, 2, 2, 56, 15, 21, 14, 21, 45, 30, 31, 30, 32,
|
||||||
0, 0, 0, 0, 33, 0, 0, 0, 2, 2, 21, 0, 9, 9, 9, 44,
|
0, 0, 0, 0, 33, 0, 0, 0, 2, 2, 21, 0, 9, 9, 9, 44,
|
||||||
0, 9, 9, 44, 0, 0, 0, 0, 0, 2, 2, 63, 23, 18, 18, 18,
|
0, 9, 9, 44, 0, 0, 0, 0, 0, 2, 2, 63, 23, 18, 18, 18,
|
||||||
20, 21, 123, 13, 15, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0,
|
20, 21, 123, 13, 15, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 0,
|
||||||
161, 162, 0, 0, 0, 0, 0, 0, 0, 16, 17, 18, 18, 64, 97, 23,
|
160, 161, 0, 0, 0, 0, 0, 0, 0, 16, 17, 18, 18, 64, 97, 23,
|
||||||
158, 9, 163, 7, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2,
|
157, 9, 162, 7, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 2,
|
||||||
63, 23, 18, 18, 0, 46, 46, 9, 164, 35, 0, 0, 0, 0, 0, 0,
|
63, 23, 18, 18, 0, 46, 46, 9, 163, 35, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 2, 2, 18, 0, 21, 17, 18, 18, 19, 14, 80,
|
0, 0, 0, 0, 0, 2, 2, 18, 0, 21, 17, 18, 18, 19, 14, 80,
|
||||||
164, 36, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 8, 165,
|
163, 36, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 8, 164,
|
||||||
23, 18, 20, 20, 163, 7, 0, 0, 0, 2, 2, 2, 2, 2, 7, 41,
|
23, 18, 20, 20, 162, 7, 0, 0, 0, 2, 2, 2, 2, 2, 7, 41,
|
||||||
133, 21, 20, 18, 74, 19, 20, 0, 0, 2, 2, 2, 7, 0, 0, 0,
|
133, 21, 20, 18, 74, 19, 20, 0, 0, 2, 2, 2, 7, 0, 0, 0,
|
||||||
0, 2, 2, 2, 2, 2, 2, 16, 17, 18, 19, 20, 103, 164, 35, 0,
|
0, 2, 2, 2, 2, 2, 2, 16, 17, 18, 19, 20, 103, 163, 35, 0,
|
||||||
0, 2, 2, 2, 7, 28, 0, 2, 2, 2, 2, 28, 7, 2, 2, 2,
|
0, 2, 2, 2, 7, 28, 0, 2, 2, 2, 2, 28, 7, 2, 2, 2,
|
||||||
2, 21, 21, 16, 30, 31, 10, 166, 167, 168, 169, 0, 0, 0, 0, 0,
|
2, 21, 21, 16, 30, 31, 10, 165, 166, 167, 168, 0, 0, 0, 0, 0,
|
||||||
0, 2, 2, 2, 2, 0, 2, 2, 2, 63, 23, 18, 18, 0, 20, 21,
|
0, 2, 2, 2, 2, 0, 2, 2, 2, 63, 23, 18, 18, 0, 20, 21,
|
||||||
27, 106, 0, 31, 0, 0, 0, 0, 0, 50, 18, 20, 20, 20, 137, 2,
|
27, 106, 0, 31, 0, 0, 0, 0, 0, 50, 18, 20, 20, 20, 137, 2,
|
||||||
2, 2, 170, 171, 9, 13, 172, 70, 173, 0, 0, 1, 144, 0, 0, 0,
|
2, 2, 169, 170, 9, 13, 171, 70, 172, 0, 0, 1, 144, 0, 0, 0,
|
||||||
0, 50, 18, 20, 14, 17, 18, 2, 2, 2, 2, 155, 155, 155, 174, 174,
|
0, 50, 18, 20, 14, 17, 18, 2, 2, 2, 2, 155, 155, 155, 173, 173,
|
||||||
174, 174, 174, 174, 13, 175, 0, 28, 0, 20, 18, 18, 29, 20, 20, 9,
|
173, 173, 173, 173, 13, 174, 0, 28, 0, 20, 18, 18, 29, 20, 20, 9,
|
||||||
164, 0, 59, 59, 59, 59, 59, 59, 59, 64, 19, 80, 44, 0, 0, 0,
|
163, 0, 59, 59, 59, 59, 59, 59, 59, 64, 19, 80, 44, 0, 0, 0,
|
||||||
0, 2, 2, 2, 7, 2, 28, 2, 2, 50, 20, 20, 29, 0, 36, 20,
|
0, 2, 2, 2, 7, 2, 28, 2, 2, 50, 20, 20, 29, 0, 36, 20,
|
||||||
25, 9, 157, 176, 172, 0, 0, 0, 0, 2, 2, 2, 28, 7, 2, 2,
|
25, 9, 156, 175, 171, 0, 0, 0, 0, 2, 2, 2, 28, 7, 2, 2,
|
||||||
2, 2, 2, 2, 2, 2, 21, 21, 45, 20, 33, 80, 66, 0, 0, 0,
|
2, 2, 2, 2, 2, 2, 21, 21, 45, 20, 33, 80, 66, 0, 0, 0,
|
||||||
0, 2, 177, 64, 45, 0, 0, 0, 0, 9, 178, 2, 2, 2, 2, 2,
|
0, 2, 176, 64, 45, 0, 0, 0, 0, 9, 177, 2, 2, 2, 2, 2,
|
||||||
2, 2, 2, 21, 20, 18, 29, 0, 46, 14, 140, 0, 0, 0, 0, 0,
|
2, 2, 2, 21, 20, 18, 29, 0, 46, 14, 140, 0, 0, 0, 0, 0,
|
||||||
0, 179, 179, 179, 106, 7, 0, 0, 0, 9, 9, 9, 44, 0, 0, 0,
|
0, 178, 178, 178, 106, 179, 178, 0, 0, 145, 2, 2, 180, 114, 114, 114,
|
||||||
0, 2, 2, 2, 2, 2, 7, 0, 56, 180, 18, 18, 18, 18, 18, 18,
|
114, 114, 114, 114, 0, 0, 0, 0, 0, 9, 9, 9, 44, 0, 0, 0,
|
||||||
|
0, 2, 2, 2, 2, 2, 7, 0, 56, 181, 18, 18, 18, 18, 18, 18,
|
||||||
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0,
|
18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 18, 0, 0, 0,
|
||||||
38, 114, 24, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0,
|
38, 114, 24, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0,
|
||||||
0, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 56,
|
0, 2, 2, 2, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 0, 56,
|
||||||
35, 0, 4, 118, 118, 118, 119, 0, 0, 9, 9, 9, 47, 2, 2, 2,
|
35, 0, 4, 118, 118, 118, 119, 0, 0, 9, 9, 9, 47, 2, 2, 2,
|
||||||
0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2,
|
0, 2, 2, 2, 2, 2, 0, 0, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||||
44, 2, 2, 2, 2, 2, 2, 9, 9, 2, 2, 42, 42, 42, 90, 0,
|
44, 2, 2, 2, 2, 2, 2, 9, 9, 2, 2, 2, 2, 2, 2, 20,
|
||||||
0, O, O, O, GB, B, B, GB, O, O, WJ,FMPst,FMPst, O, CGJ, B,
|
20, 2, 2, 42, 42, 42, 90, 0, 0, O, O, O, GB, B, B, GB,
|
||||||
O, B,VMAbv,VMAbv,VMAbv, O,VMAbv, B,CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw,
|
O, O, WJ,FMPst,FMPst, O, CGJ, B, O, B,VMAbv,VMAbv,VMAbv, O,VMAbv, B,
|
||||||
B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw, VAbv, VAbv, VAbv, VPst, VPst, VPst, H, VPre,
|
CMBlw,CMBlw,CMBlw,VMAbv,VMPst, VAbv, VPst,CMBlw, B, VPst, VPre, VPst, VBlw, VBlw, VBlw, VBlw,
|
||||||
VPst,VMBlw, O, O, VAbv, GB,VMAbv,VMPst,VMPst, O, B, VBlw, O, O, VPre, VPre,
|
VAbv, VAbv, VAbv, VPst, VPst, VPst, H, VPre, VPst,VMBlw, O, O, VAbv, GB,VMAbv,VMPst,
|
||||||
O, VPre, H, O, VPst,FMAbv, O,CMBlw, O, VAbv, O, VAbv, H, O,VMBlw,VMAbv,
|
VMPst, O, B, VBlw, O, O, VPre, VPre, O, VPre, H, O, VPst,FMAbv, O,CMBlw,
|
||||||
CMAbv, GB, GB, O, MBlw,CMAbv,CMAbv, VPst, VAbv,VMAbv, O, VPst, O, VPre, VPre,VMAbv,
|
O, VAbv, O, VAbv, H, O,VMBlw,VMAbv,CMAbv, GB, GB, O, MBlw,CMAbv,CMAbv, VPst,
|
||||||
B, O, CS, CS,VMPst, B, VAbv, VAbv, B, R, O, HVM, O, O, FBlw, O,
|
VAbv,VMAbv, O, VPst, O, VPre, VPre,VMAbv, B, O, CS, CS,VMPst, B, VAbv, VAbv,
|
||||||
CMAbv, O,CMBlw, VAbv, VBlw, B, SUB, SUB, SUB, O, SUB, SUB, O, FBlw, O, B,
|
B, R, O, HVM, O, O,FMBlw, O,CMAbv, O,CMBlw, VAbv, VBlw, B, SUB, SUB,
|
||||||
VPst, VBlw, VPre,VMAbv,VMBlw,VMPst, IS, VAbv, MPst, MPre, MBlw, MBlw, B, MBlw, MBlw, VPst,
|
SUB, O, SUB, SUB, O,FMBlw, O, B, VPst, VBlw, VPre,VMAbv,VMBlw,VMPst, IS, VAbv,
|
||||||
VMPst,VMPst, B, MBlw, VPst, VPre, VAbv, VAbv,VMPst,VMPst,VMBlw, B,VMPst, VBlw, VPst, CGJ,
|
MPst, MPre, MBlw, MBlw, B, MBlw, MBlw, VPst,VMPst,VMPst, B, MBlw, VPst, VPre, VAbv, VAbv,
|
||||||
CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B,
|
VMPst,VMPst,VMBlw, B,VMPst, VBlw, VPst, CGJ, CGJ, VPst,VMAbv,VMAbv,FMAbv, FAbv,CMAbv,FMAbv,
|
||||||
CGJ, WJ, CGJ, GB,CMAbv,CMAbv, B, GB, B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst,
|
VMAbv,FMAbv, VAbv, IS,FMAbv, B,FMAbv, B, CGJ, WJ, CGJ, GB,CMAbv,CMAbv, B, GB,
|
||||||
FBlw,VMAbv,FMBlw, VAbv, VPre, B, MPre, MBlw, SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,
|
B, VAbv, SUB, FPst, FPst,VMBlw, FPst, FPst, FBlw,VMAbv,FMBlw, VAbv, VPre, B, MPre, MBlw,
|
||||||
VMAbv,VMAbv, FAbv,CMAbv, VPst, H, B, O,SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst, IS, VBlw,
|
SUB, FAbv, FAbv, MAbv, SUB, Sk, VPst, VAbv,VMAbv,VMAbv, FAbv,CMAbv, VPst, H, B, O,
|
||||||
FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv, CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ,
|
SMAbv,SMBlw,SMAbv,SMAbv,SMAbv, VPst, IS, VBlw, FAbv,VMPre,VMPre,FMAbv,CMBlw,VMBlw,VMBlw,VMAbv,
|
||||||
O,FMPst, O, O, H, MPst, VPst, H,VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,
|
CS, O,FMAbv, ZWNJ, CGJ, WJ, WJ, WJ, O,FMPst, O, O, H, MPst, VPst, H,
|
||||||
VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, H, O, VBlw, MPst, MPre, MAbv, MBlw, O, B,
|
VMAbv, VAbv,VMBlw, B, VBlw, FPst, VPst, FAbv,VMPst, B,CMAbv, VAbv, MBlw, MPst, MBlw, H,
|
||||||
FAbv, FAbv, FPst, VBlw, B, B, VPre, O,VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,
|
O, VBlw, MPst, MPre, MAbv, MBlw, O, B, FAbv, FAbv, FPst, VBlw, B, B, VPre, O,
|
||||||
VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst, CS, CS, B, N, N, O, HN, VPre,
|
VMPst, IS, O,VMPst, VBlw, VPst,VMBlw,VMBlw,VMAbv, O, IS,VMBlw, B,VMPst,VMAbv,VMPst,
|
||||||
VBlw, VAbv, IS,CMAbv, O, VPst, B, R, R, O,FMBlw,CMBlw, VAbv, VPre,VMAbv,VMAbv,
|
CS, CS, B, N, N, O, HN, VPre, VBlw, VAbv, IS,CMAbv, O, VPst, B, R,
|
||||||
H, VAbv,CMBlw,FMAbv, B, CS, CS, H,CMBlw,VMPst, H,VMPst, VAbv,VMAbv, VPst, IS,
|
R,CMBlw, VAbv, VPre,VMAbv,VMAbv, H, VAbv,CMBlw,FMAbv, B, CS, CS, H,CMBlw,VMPst,
|
||||||
R, MPst, R, MPst,CMBlw, B,FMBlw, VBlw,VMAbv, R, MBlw, MBlw, GB, FBlw, FBlw,CMAbv,
|
H,VMPst, VAbv,VMAbv, VPst, IS, R, MPst, R, MPst,CMBlw, B,FMBlw, VBlw,VMAbv, R,
|
||||||
IS, VBlw, IS, GB, VAbv, R,VMPst, H, H, O, VBlw,
|
MBlw, MBlw, GB, FBlw, FBlw,CMAbv, IS, VBlw, IS, GB, VAbv, R,VMPst, H, H, B,
|
||||||
|
H, B,VMBlw, O, VBlw,
|
||||||
};
|
};
|
||||||
static const uint16_t
|
static const uint16_t
|
||||||
hb_use_u16[776] =
|
hb_use_u16[784] =
|
||||||
{
|
{
|
||||||
0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 5, 0, 0,
|
0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 3, 4, 0, 5, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0,
|
||||||
@@ -332,14 +336,14 @@ hb_use_u16[776] =
|
|||||||
9,242, 73,243, 0, 0, 0, 0,244, 9, 9,245,246, 2,247, 9,
|
9,242, 73,243, 0, 0, 0, 0,244, 9, 9,245,246, 2,247, 9,
|
||||||
248,249, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,250,
|
248,249, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,250,
|
||||||
251, 48, 9,252,253, 2, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9,
|
251, 48, 9,252,253, 2, 0, 0, 9, 9, 9, 9, 9, 9, 9, 9,
|
||||||
9, 9, 98,254, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
|
9, 9, 9,254,255,256, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0,
|
||||||
9, 9, 9,255, 0, 0, 0, 0, 9, 9, 9, 9,256,257,258,258,
|
9, 9, 9,257, 0, 0, 0, 0, 9, 9, 9, 9,258,259,260,260,
|
||||||
259,260, 0, 0, 0, 0,261, 0, 9, 9, 9, 9, 9,262, 0, 0,
|
261,262, 0, 0, 0, 0,263, 0, 9, 9, 9, 9, 9,264, 0, 0,
|
||||||
9, 9, 9, 9, 9, 9,105, 70, 94,263, 0, 0, 0, 0, 0, 0,
|
9, 9, 9, 9, 9, 9,105, 70, 94,265, 0, 0, 0, 0, 0, 0,
|
||||||
0, 0, 0, 0, 0, 0, 0,264, 9, 9, 70,265,266, 0, 0, 0,
|
0, 0, 0, 0, 0, 0, 0,266, 9, 9, 70,267,268, 0, 0, 0,
|
||||||
0, 9,267, 0, 9, 9,268, 2, 9, 9, 9, 9,269, 2, 0, 0,
|
0, 9,269, 0, 9, 9,270, 2, 0, 0, 0, 0, 0, 9,271, 2,
|
||||||
129,129,129,129,129,129,129,129,160,160,160,160,160,160,160,160,
|
9, 9, 9, 9,272, 2, 0, 0,129,129,129,129,129,129,129,129,
|
||||||
160,160,160,160,160,160,160,129,
|
160,160,160,160,160,160,160,160,160,160,160,160,160,160,160,129,
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline unsigned
|
static inline unsigned
|
||||||
@@ -350,7 +354,7 @@ hb_use_b4 (const uint8_t* a, unsigned i)
|
|||||||
static inline uint_fast8_t
|
static inline uint_fast8_t
|
||||||
hb_use_get_category (unsigned u)
|
hb_use_get_category (unsigned u)
|
||||||
{
|
{
|
||||||
return u<921600u?hb_use_u8[2753+(((hb_use_u8[593+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O;
|
return u<921600u?hb_use_u8[2777+(((hb_use_u8[593+(((hb_use_u16[((hb_use_u8[113+(((hb_use_b4(hb_use_u8,u>>1>>3>>3>>5))<<5)+((u>>1>>3>>3)&31u))])<<3)+((u>>1>>3)&7u)])<<3)+((u>>1)&7u))])<<1)+((u)&1u))]:O;
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef B
|
#undef B
|
||||||
|
|||||||
@@ -342,6 +342,40 @@ _hb_preprocess_text_vowel_constraints (const hb_ot_shape_plan_t *plan HB_UNUSED,
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case HB_SCRIPT_KHOJKI:
|
||||||
|
for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
|
||||||
|
{
|
||||||
|
bool matched = false;
|
||||||
|
switch (buffer->cur ().codepoint)
|
||||||
|
{
|
||||||
|
case 0x11200u:
|
||||||
|
switch (buffer->cur (1).codepoint)
|
||||||
|
{
|
||||||
|
case 0x1122Cu: case 0x11231u: case 0x11233u:
|
||||||
|
matched = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x11206u:
|
||||||
|
matched = 0x1122Cu == buffer->cur (1).codepoint;
|
||||||
|
break;
|
||||||
|
case 0x1122Cu:
|
||||||
|
switch (buffer->cur (1).codepoint)
|
||||||
|
{
|
||||||
|
case 0x11230u: case 0x11231u:
|
||||||
|
matched = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0x11240u:
|
||||||
|
matched = 0x1122Eu == buffer->cur (1).codepoint;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
(void) buffer->next_glyph ();
|
||||||
|
if (matched) _output_with_dotted_circle (buffer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case HB_SCRIPT_KHUDAWADI:
|
case HB_SCRIPT_KHUDAWADI:
|
||||||
for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
|
for (buffer->idx = 0; buffer->idx + 1 < count && buffer->successful;)
|
||||||
{
|
{
|
||||||
|
|||||||
14
thirdparty/harfbuzz/src/hb-ot-stat-table.hh
vendored
14
thirdparty/harfbuzz/src/hb-ot-stat-table.hh
vendored
@@ -136,7 +136,7 @@ struct AxisValueFormat1
|
|||||||
NameID valueNameID; /* The name ID for entries in the 'name' table
|
NameID valueNameID; /* The name ID for entries in the 'name' table
|
||||||
* that provide a display string for this
|
* that provide a display string for this
|
||||||
* attribute value. */
|
* attribute value. */
|
||||||
HBFixed value; /* A numeric value for this attribute value. */
|
F16DOT16 value; /* A numeric value for this attribute value. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (12);
|
DEFINE_SIZE_STATIC (12);
|
||||||
};
|
};
|
||||||
@@ -195,10 +195,10 @@ struct AxisValueFormat2
|
|||||||
NameID valueNameID; /* The name ID for entries in the 'name' table
|
NameID valueNameID; /* The name ID for entries in the 'name' table
|
||||||
* that provide a display string for this
|
* that provide a display string for this
|
||||||
* attribute value. */
|
* attribute value. */
|
||||||
HBFixed nominalValue; /* A numeric value for this attribute value. */
|
F16DOT16 nominalValue; /* A numeric value for this attribute value. */
|
||||||
HBFixed rangeMinValue; /* The minimum value for a range associated
|
F16DOT16 rangeMinValue; /* The minimum value for a range associated
|
||||||
* with the specified name ID. */
|
* with the specified name ID. */
|
||||||
HBFixed rangeMaxValue; /* The maximum value for a range associated
|
F16DOT16 rangeMaxValue; /* The maximum value for a range associated
|
||||||
* with the specified name ID. */
|
* with the specified name ID. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (20);
|
DEFINE_SIZE_STATIC (20);
|
||||||
@@ -258,8 +258,8 @@ struct AxisValueFormat3
|
|||||||
NameID valueNameID; /* The name ID for entries in the 'name' table
|
NameID valueNameID; /* The name ID for entries in the 'name' table
|
||||||
* that provide a display string for this
|
* that provide a display string for this
|
||||||
* attribute value. */
|
* attribute value. */
|
||||||
HBFixed value; /* A numeric value for this attribute value. */
|
F16DOT16 value; /* A numeric value for this attribute value. */
|
||||||
HBFixed linkedValue; /* The numeric value for a style-linked mapping
|
F16DOT16 linkedValue; /* The numeric value for a style-linked mapping
|
||||||
* from this value. */
|
* from this value. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (16);
|
DEFINE_SIZE_STATIC (16);
|
||||||
@@ -280,7 +280,7 @@ struct AxisValueRecord
|
|||||||
HBUINT16 axisIndex; /* Zero-base index into the axis record array
|
HBUINT16 axisIndex; /* Zero-base index into the axis record array
|
||||||
* identifying the axis to which this value
|
* identifying the axis to which this value
|
||||||
* applies. Must be less than designAxisCount. */
|
* applies. Must be less than designAxisCount. */
|
||||||
HBFixed value; /* A numeric value for this attribute value. */
|
F16DOT16 value; /* A numeric value for this attribute value. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (6);
|
DEFINE_SIZE_STATIC (6);
|
||||||
};
|
};
|
||||||
|
|||||||
98
thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh
vendored
98
thirdparty/harfbuzz/src/hb-ot-var-fvar-table.hh
vendored
@@ -44,9 +44,47 @@ struct InstanceRecord
|
|||||||
{
|
{
|
||||||
friend struct fvar;
|
friend struct fvar;
|
||||||
|
|
||||||
hb_array_t<const HBFixed> get_coordinates (unsigned int axis_count) const
|
hb_array_t<const F16DOT16> get_coordinates (unsigned int axis_count) const
|
||||||
{ return coordinatesZ.as_array (axis_count); }
|
{ return coordinatesZ.as_array (axis_count); }
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t *c,
|
||||||
|
unsigned axis_count,
|
||||||
|
bool has_postscript_nameid) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
if (unlikely (!c->serializer->embed (subfamilyNameID))) return_trace (false);
|
||||||
|
if (unlikely (!c->serializer->embed (flags))) return_trace (false);
|
||||||
|
|
||||||
|
const hb_array_t<const F16DOT16> coords = get_coordinates (axis_count);
|
||||||
|
const hb_hashmap_t<hb_tag_t, float> *axes_location = c->plan->user_axes_location;
|
||||||
|
for (unsigned i = 0 ; i < axis_count; i++)
|
||||||
|
{
|
||||||
|
unsigned *axis_tag;
|
||||||
|
// only keep instances whose coordinates == pinned axis location
|
||||||
|
if (!c->plan->axes_old_index_tag_map->has (i, &axis_tag)) continue;
|
||||||
|
|
||||||
|
if (axes_location->has (*axis_tag) &&
|
||||||
|
fabsf (axes_location->get (*axis_tag) - coords[i].to_float ()) > 0.001f)
|
||||||
|
return_trace (false);
|
||||||
|
|
||||||
|
if (!c->plan->axes_index_map->has (i))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!c->serializer->embed (coords[i]))
|
||||||
|
return_trace (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_postscript_nameid)
|
||||||
|
{
|
||||||
|
NameID name_id;
|
||||||
|
name_id = StructAfter<NameID> (coords);
|
||||||
|
if (!c->serializer->embed (name_id))
|
||||||
|
return_trace (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return_trace (true);
|
||||||
|
}
|
||||||
|
|
||||||
bool sanitize (hb_sanitize_context_t *c, unsigned int axis_count) const
|
bool sanitize (hb_sanitize_context_t *c, unsigned int axis_count) const
|
||||||
{
|
{
|
||||||
TRACE_SANITIZE (this);
|
TRACE_SANITIZE (this);
|
||||||
@@ -58,7 +96,7 @@ struct InstanceRecord
|
|||||||
NameID subfamilyNameID;/* The name ID for entries in the 'name' table
|
NameID subfamilyNameID;/* The name ID for entries in the 'name' table
|
||||||
* that provide subfamily names for this instance. */
|
* that provide subfamily names for this instance. */
|
||||||
HBUINT16 flags; /* Reserved for future use — set to 0. */
|
HBUINT16 flags; /* Reserved for future use — set to 0. */
|
||||||
UnsizedArrayOf<HBFixed>
|
UnsizedArrayOf<F16DOT16>
|
||||||
coordinatesZ; /* The coordinates array for this instance. */
|
coordinatesZ; /* The coordinates array for this instance. */
|
||||||
//NameID postScriptNameIDX;/*Optional. The name ID for entries in the 'name'
|
//NameID postScriptNameIDX;/*Optional. The name ID for entries in the 'name'
|
||||||
// * table that provide PostScript names for this
|
// * table that provide PostScript names for this
|
||||||
@@ -151,9 +189,9 @@ struct AxisRecord
|
|||||||
public:
|
public:
|
||||||
Tag axisTag; /* Tag identifying the design variation for the axis. */
|
Tag axisTag; /* Tag identifying the design variation for the axis. */
|
||||||
protected:
|
protected:
|
||||||
HBFixed minValue; /* The minimum coordinate value for the axis. */
|
F16DOT16 minValue; /* The minimum coordinate value for the axis. */
|
||||||
HBFixed defaultValue; /* The default coordinate value for the axis. */
|
F16DOT16 defaultValue; /* The default coordinate value for the axis. */
|
||||||
HBFixed maxValue; /* The maximum coordinate value for the axis. */
|
F16DOT16 maxValue; /* The maximum coordinate value for the axis. */
|
||||||
public:
|
public:
|
||||||
HBUINT16 flags; /* Axis flags. */
|
HBUINT16 flags; /* Axis flags. */
|
||||||
NameID axisNameID; /* The name ID for entries in the 'name' table that
|
NameID axisNameID; /* The name ID for entries in the 'name' table that
|
||||||
@@ -268,7 +306,7 @@ struct fvar
|
|||||||
|
|
||||||
if (coords_length && *coords_length)
|
if (coords_length && *coords_length)
|
||||||
{
|
{
|
||||||
hb_array_t<const HBFixed> instanceCoords = instance->get_coordinates (axisCount)
|
hb_array_t<const F16DOT16> instanceCoords = instance->get_coordinates (axisCount)
|
||||||
.sub_array (0, coords_length);
|
.sub_array (0, coords_length);
|
||||||
for (unsigned int i = 0; i < instanceCoords.length; i++)
|
for (unsigned int i = 0; i < instanceCoords.length; i++)
|
||||||
coords[i] = instanceCoords.arrayZ[i].to_float ();
|
coords[i] = instanceCoords.arrayZ[i].to_float ();
|
||||||
@@ -301,7 +339,7 @@ struct fvar
|
|||||||
|
|
||||||
if (hb_any (+ hb_zip (instance->get_coordinates (axisCount), hb_range ((unsigned)axisCount))
|
if (hb_any (+ hb_zip (instance->get_coordinates (axisCount), hb_range ((unsigned)axisCount))
|
||||||
| hb_filter (pinned_axes, hb_second)
|
| hb_filter (pinned_axes, hb_second)
|
||||||
| hb_map ([&] (const hb_pair_t<const HBFixed&, unsigned>& _)
|
| hb_map ([&] (const hb_pair_t<const F16DOT16&, unsigned>& _)
|
||||||
{
|
{
|
||||||
hb_tag_t axis_tag = pinned_axes.get (_.second);
|
hb_tag_t axis_tag = pinned_axes.get (_.second);
|
||||||
float location = user_axes_location->get (axis_tag);
|
float location = user_axes_location->get (axis_tag);
|
||||||
@@ -321,6 +359,48 @@ struct fvar
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
unsigned retained_axis_count = c->plan->axes_index_map->get_population ();
|
||||||
|
if (!retained_axis_count) //all axes are pinned
|
||||||
|
return_trace (false);
|
||||||
|
|
||||||
|
fvar *out = c->serializer->embed (this);
|
||||||
|
if (unlikely (!out)) return_trace (false);
|
||||||
|
|
||||||
|
if (!c->serializer->check_assign (out->axisCount, retained_axis_count, HB_SERIALIZE_ERROR_INT_OVERFLOW))
|
||||||
|
return_trace (false);
|
||||||
|
|
||||||
|
bool has_postscript_nameid = false;
|
||||||
|
if (instanceSize >= axisCount * 4 + 6)
|
||||||
|
has_postscript_nameid = true;
|
||||||
|
|
||||||
|
if (!c->serializer->check_assign (out->instanceSize, retained_axis_count * 4 + (has_postscript_nameid ? 6 : 4),
|
||||||
|
HB_SERIALIZE_ERROR_INT_OVERFLOW))
|
||||||
|
return_trace (false);
|
||||||
|
|
||||||
|
auto axes_records = get_axes ();
|
||||||
|
for (unsigned i = 0 ; i < (unsigned)axisCount; i++)
|
||||||
|
{
|
||||||
|
if (!c->plan->axes_index_map->has (i)) continue;
|
||||||
|
if (unlikely (!c->serializer->embed (axes_records[i])))
|
||||||
|
return_trace (false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!c->serializer->check_assign (out->firstAxis, get_size (), HB_SERIALIZE_ERROR_INT_OVERFLOW))
|
||||||
|
return_trace (false);
|
||||||
|
|
||||||
|
for (unsigned i = 0 ; i < (unsigned)instanceCount; i++)
|
||||||
|
{
|
||||||
|
const InstanceRecord *instance = get_instance (i);
|
||||||
|
auto snap = c->serializer->snapshot ();
|
||||||
|
if (!instance->subset (c, axisCount, has_postscript_nameid))
|
||||||
|
c->serializer->revert (snap);
|
||||||
|
}
|
||||||
|
return_trace (true);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
hb_array_t<const AxisRecord> get_axes () const
|
hb_array_t<const AxisRecord> get_axes () const
|
||||||
{ return hb_array (&(this+firstAxis), axisCount); }
|
{ return hb_array (&(this+firstAxis), axisCount); }
|
||||||
@@ -346,8 +426,8 @@ struct fvar
|
|||||||
HBUINT16 instanceCount; /* The number of named instances defined in the font
|
HBUINT16 instanceCount; /* The number of named instances defined in the font
|
||||||
* (the number of records in the instances array). */
|
* (the number of records in the instances array). */
|
||||||
HBUINT16 instanceSize; /* The size in bytes of each InstanceRecord — set
|
HBUINT16 instanceSize; /* The size in bytes of each InstanceRecord — set
|
||||||
* to either axisCount * sizeof(HBFixed) + 4, or to
|
* to either axisCount * sizeof(F16DOT16) + 4, or to
|
||||||
* axisCount * sizeof(HBFixed) + 6. */
|
* axisCount * sizeof(F16DOT16) + 6. */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (16);
|
DEFINE_SIZE_STATIC (16);
|
||||||
|
|||||||
2
thirdparty/harfbuzz/src/hb-repacker.hh
vendored
2
thirdparty/harfbuzz/src/hb-repacker.hh
vendored
@@ -244,7 +244,7 @@ bool _process_overflows (const hb_vector_t<graph::overflow_record_t>& overflows,
|
|||||||
{
|
{
|
||||||
// The child object is shared, we may be able to eliminate the overflow
|
// The child object is shared, we may be able to eliminate the overflow
|
||||||
// by duplicating it.
|
// by duplicating it.
|
||||||
if (!sorted_graph.duplicate (r.parent, r.child)) continue;
|
if (sorted_graph.duplicate (r.parent, r.child) == (unsigned) -1) continue;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
76
thirdparty/harfbuzz/src/hb-subset-accelerator.hh
vendored
Normal file
76
thirdparty/harfbuzz/src/hb-subset-accelerator.hh
vendored
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
/*
|
||||||
|
* Copyright © 2022 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): Garret Rieger
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HB_SUBSET_ACCELERATOR_HH
|
||||||
|
#define HB_SUBSET_ACCELERATOR_HH
|
||||||
|
|
||||||
|
|
||||||
|
#include "hb.hh"
|
||||||
|
|
||||||
|
#include "hb-map.hh"
|
||||||
|
#include "hb-set.hh"
|
||||||
|
|
||||||
|
struct hb_subset_accelerator_t
|
||||||
|
{
|
||||||
|
static hb_user_data_key_t* user_data_key()
|
||||||
|
{
|
||||||
|
static hb_user_data_key_t key;
|
||||||
|
return &key;
|
||||||
|
}
|
||||||
|
|
||||||
|
static hb_subset_accelerator_t* create(const hb_map_t& unicode_to_gid_,
|
||||||
|
const hb_set_t& unicodes_) {
|
||||||
|
hb_subset_accelerator_t* accel =
|
||||||
|
(hb_subset_accelerator_t*) hb_malloc (sizeof(hb_subset_accelerator_t));
|
||||||
|
new (accel) hb_subset_accelerator_t (unicode_to_gid_, unicodes_);
|
||||||
|
return accel;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroy(void* value) {
|
||||||
|
if (!value) return;
|
||||||
|
|
||||||
|
hb_subset_accelerator_t* accel = (hb_subset_accelerator_t*) value;
|
||||||
|
accel->~hb_subset_accelerator_t ();
|
||||||
|
hb_free (accel);
|
||||||
|
}
|
||||||
|
|
||||||
|
hb_subset_accelerator_t(const hb_map_t& unicode_to_gid_,
|
||||||
|
const hb_set_t& unicodes_)
|
||||||
|
: unicode_to_gid(unicode_to_gid_), unicodes(unicodes_) {}
|
||||||
|
|
||||||
|
const hb_map_t unicode_to_gid;
|
||||||
|
const hb_set_t unicodes;
|
||||||
|
// TODO(garretrieger): cumulative glyf checksum map
|
||||||
|
// TODO(garretrieger): sanitized table cache.
|
||||||
|
|
||||||
|
bool in_error () const
|
||||||
|
{
|
||||||
|
return unicode_to_gid.in_error() || unicodes.in_error ();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* HB_SUBSET_ACCELERATOR_HH */
|
||||||
53
thirdparty/harfbuzz/src/hb-subset-input.cc
vendored
53
thirdparty/harfbuzz/src/hb-subset-input.cc
vendored
@@ -89,7 +89,6 @@ hb_subset_input_create_or_fail (void)
|
|||||||
|
|
||||||
hb_tag_t default_no_subset_tables[] = {
|
hb_tag_t default_no_subset_tables[] = {
|
||||||
HB_TAG ('a', 'v', 'a', 'r'),
|
HB_TAG ('a', 'v', 'a', 'r'),
|
||||||
HB_TAG ('f', 'v', 'a', 'r'),
|
|
||||||
HB_TAG ('g', 'a', 's', 'p'),
|
HB_TAG ('g', 'a', 's', 'p'),
|
||||||
HB_TAG ('c', 'v', 't', ' '),
|
HB_TAG ('c', 'v', 't', ' '),
|
||||||
HB_TAG ('f', 'p', 'g', 'm'),
|
HB_TAG ('f', 'p', 'g', 'm'),
|
||||||
@@ -393,7 +392,7 @@ hb_subset_input_get_user_data (const hb_subset_input_t *input,
|
|||||||
*
|
*
|
||||||
* Since: EXPERIMENTAL
|
* Since: EXPERIMENTAL
|
||||||
**/
|
**/
|
||||||
hb_bool_t
|
HB_EXTERN hb_bool_t
|
||||||
hb_subset_input_pin_axis_to_default (hb_subset_input_t *input,
|
hb_subset_input_pin_axis_to_default (hb_subset_input_t *input,
|
||||||
hb_face_t *face,
|
hb_face_t *face,
|
||||||
hb_tag_t axis_tag)
|
hb_tag_t axis_tag)
|
||||||
@@ -417,7 +416,7 @@ hb_subset_input_pin_axis_to_default (hb_subset_input_t *input,
|
|||||||
*
|
*
|
||||||
* Since: EXPERIMENTAL
|
* Since: EXPERIMENTAL
|
||||||
**/
|
**/
|
||||||
hb_bool_t
|
HB_EXTERN hb_bool_t
|
||||||
hb_subset_input_pin_axis_location (hb_subset_input_t *input,
|
hb_subset_input_pin_axis_location (hb_subset_input_t *input,
|
||||||
hb_face_t *face,
|
hb_face_t *face,
|
||||||
hb_tag_t axis_tag,
|
hb_tag_t axis_tag,
|
||||||
@@ -432,3 +431,51 @@ hb_subset_input_pin_axis_location (hb_subset_input_t *input,
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HB_EXPERIMENTAL_API
|
||||||
|
/**
|
||||||
|
* hb_subset_preprocess
|
||||||
|
* @input: a #hb_face_t object.
|
||||||
|
*
|
||||||
|
* Preprocesses the face and attaches data that will be needed by the
|
||||||
|
* subsetter. Future subsetting operations can then use the precomputed data
|
||||||
|
* to speed up the subsetting operation.
|
||||||
|
*
|
||||||
|
* Since: EXPERIMENTAL
|
||||||
|
**/
|
||||||
|
|
||||||
|
HB_EXTERN hb_face_t *
|
||||||
|
hb_subset_preprocess (hb_face_t *source)
|
||||||
|
{
|
||||||
|
hb_subset_input_t* input = hb_subset_input_create_or_fail ();
|
||||||
|
|
||||||
|
hb_set_clear (hb_subset_input_set(input, HB_SUBSET_SETS_UNICODE));
|
||||||
|
hb_set_invert (hb_subset_input_set(input, HB_SUBSET_SETS_UNICODE));
|
||||||
|
|
||||||
|
hb_set_clear (hb_subset_input_set(input,
|
||||||
|
HB_SUBSET_SETS_LAYOUT_FEATURE_TAG));
|
||||||
|
hb_set_invert (hb_subset_input_set(input,
|
||||||
|
HB_SUBSET_SETS_LAYOUT_FEATURE_TAG));
|
||||||
|
|
||||||
|
hb_set_clear (hb_subset_input_set(input,
|
||||||
|
HB_SUBSET_SETS_LAYOUT_SCRIPT_TAG));
|
||||||
|
hb_set_invert (hb_subset_input_set(input,
|
||||||
|
HB_SUBSET_SETS_LAYOUT_SCRIPT_TAG));
|
||||||
|
|
||||||
|
hb_set_clear (hb_subset_input_set(input,
|
||||||
|
HB_SUBSET_SETS_NAME_ID));
|
||||||
|
hb_set_invert (hb_subset_input_set(input,
|
||||||
|
HB_SUBSET_SETS_NAME_ID));
|
||||||
|
|
||||||
|
hb_subset_input_set_flags(input,
|
||||||
|
HB_SUBSET_FLAGS_NOTDEF_OUTLINE |
|
||||||
|
HB_SUBSET_FLAGS_GLYPH_NAMES |
|
||||||
|
HB_SUBSET_FLAGS_RETAIN_GIDS);
|
||||||
|
input->attach_accelerator_data = true;
|
||||||
|
|
||||||
|
hb_face_t* new_source = hb_subset_or_fail (source, input);
|
||||||
|
hb_subset_input_destroy (input);
|
||||||
|
|
||||||
|
return new_source;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|||||||
1
thirdparty/harfbuzz/src/hb-subset-input.hh
vendored
1
thirdparty/harfbuzz/src/hb-subset-input.hh
vendored
@@ -59,6 +59,7 @@ struct hb_subset_input_t
|
|||||||
};
|
};
|
||||||
|
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
|
bool attach_accelerator_data = false;
|
||||||
hb_hashmap_t<hb_tag_t, float> *axes_location;
|
hb_hashmap_t<hb_tag_t, float> *axes_location;
|
||||||
|
|
||||||
inline unsigned num_sets () const
|
inline unsigned num_sets () const
|
||||||
|
|||||||
169
thirdparty/harfbuzz/src/hb-subset-plan.cc
vendored
169
thirdparty/harfbuzz/src/hb-subset-plan.cc
vendored
@@ -25,6 +25,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "hb-subset-plan.hh"
|
#include "hb-subset-plan.hh"
|
||||||
|
#include "hb-subset-accelerator.hh"
|
||||||
#include "hb-map.hh"
|
#include "hb-map.hh"
|
||||||
#include "hb-set.hh"
|
#include "hb-set.hh"
|
||||||
|
|
||||||
@@ -129,7 +130,9 @@ template <typename T>
|
|||||||
static void _collect_layout_indices (hb_subset_plan_t *plan,
|
static void _collect_layout_indices (hb_subset_plan_t *plan,
|
||||||
const T& table,
|
const T& table,
|
||||||
hb_set_t *lookup_indices, /* OUT */
|
hb_set_t *lookup_indices, /* OUT */
|
||||||
hb_set_t *feature_indices /* OUT */)
|
hb_set_t *feature_indices, /* OUT */
|
||||||
|
hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map, /* OUT */
|
||||||
|
hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map /* OUT */)
|
||||||
{
|
{
|
||||||
unsigned num_features = table.get_feature_count ();
|
unsigned num_features = table.get_feature_count ();
|
||||||
hb_vector_t<hb_tag_t> features;
|
hb_vector_t<hb_tag_t> features;
|
||||||
@@ -154,16 +157,37 @@ static void _collect_layout_indices (hb_subset_plan_t *plan,
|
|||||||
retain_all_features ? nullptr : features.arrayZ,
|
retain_all_features ? nullptr : features.arrayZ,
|
||||||
feature_indices);
|
feature_indices);
|
||||||
|
|
||||||
|
#ifndef HB_NO_VAR
|
||||||
|
// collect feature substitutes with variations
|
||||||
|
if (!plan->user_axes_location->is_empty ())
|
||||||
|
{
|
||||||
|
hb_hashmap_t<hb::shared_ptr<hb_map_t>, unsigned> conditionset_map;
|
||||||
|
OT::hb_collect_feature_substitutes_with_var_context_t c =
|
||||||
|
{
|
||||||
|
plan->axes_old_index_tag_map,
|
||||||
|
plan->axes_location,
|
||||||
|
feature_record_cond_idx_map,
|
||||||
|
feature_substitutes_map,
|
||||||
|
feature_indices,
|
||||||
|
true,
|
||||||
|
0,
|
||||||
|
&conditionset_map
|
||||||
|
};
|
||||||
|
table.collect_feature_substitutes_with_variations (&c);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
for (unsigned feature_index : *feature_indices)
|
for (unsigned feature_index : *feature_indices)
|
||||||
{
|
{
|
||||||
//TODO: replace HB_OT_LAYOUT_NO_VARIATIONS_INDEX with variation_index for
|
const OT::Feature* f = &(table.get_feature (feature_index));
|
||||||
//instancing
|
const OT::Feature **p = nullptr;
|
||||||
const OT::Feature &f = table.get_feature_variation (feature_index, HB_OT_LAYOUT_NO_VARIATIONS_INDEX);
|
if (feature_substitutes_map->has (feature_index, &p))
|
||||||
f.add_lookup_indexes_to (lookup_indices);
|
f = *p;
|
||||||
|
|
||||||
|
f->add_lookup_indexes_to (lookup_indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: update for instancing: only collect lookups from feature_indexes that have no variations
|
table.feature_variation_collect_lookups (feature_indices, feature_substitutes_map, lookup_indices);
|
||||||
table.feature_variation_collect_lookups (feature_indices, lookup_indices);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -171,6 +195,7 @@ static inline void
|
|||||||
_GSUBGPOS_find_duplicate_features (const OT::GSUBGPOS &g,
|
_GSUBGPOS_find_duplicate_features (const OT::GSUBGPOS &g,
|
||||||
const hb_map_t *lookup_indices,
|
const hb_map_t *lookup_indices,
|
||||||
const hb_set_t *feature_indices,
|
const hb_set_t *feature_indices,
|
||||||
|
const hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map,
|
||||||
hb_map_t *duplicate_feature_map /* OUT */)
|
hb_map_t *duplicate_feature_map /* OUT */)
|
||||||
{
|
{
|
||||||
if (feature_indices->is_empty ()) return;
|
if (feature_indices->is_empty ()) return;
|
||||||
@@ -195,16 +220,22 @@ _GSUBGPOS_find_duplicate_features (const OT::GSUBGPOS &g,
|
|||||||
hb_set_t* same_tag_features = unique_features.get (t);
|
hb_set_t* same_tag_features = unique_features.get (t);
|
||||||
for (unsigned other_f_index : same_tag_features->iter ())
|
for (unsigned other_f_index : same_tag_features->iter ())
|
||||||
{
|
{
|
||||||
const OT::Feature& f = g.get_feature (i);
|
const OT::Feature* f = &(g.get_feature (i));
|
||||||
const OT::Feature& other_f = g.get_feature (other_f_index);
|
const OT::Feature **p = nullptr;
|
||||||
|
if (feature_substitutes_map->has (i, &p))
|
||||||
|
f = *p;
|
||||||
|
|
||||||
|
const OT::Feature* other_f = &(g.get_feature (other_f_index));
|
||||||
|
if (feature_substitutes_map->has (other_f_index, &p))
|
||||||
|
f = *p;
|
||||||
|
|
||||||
auto f_iter =
|
auto f_iter =
|
||||||
+ hb_iter (f.lookupIndex)
|
+ hb_iter (f->lookupIndex)
|
||||||
| hb_filter (lookup_indices)
|
| hb_filter (lookup_indices)
|
||||||
;
|
;
|
||||||
|
|
||||||
auto other_f_iter =
|
auto other_f_iter =
|
||||||
+ hb_iter (other_f.lookupIndex)
|
+ hb_iter (other_f->lookupIndex)
|
||||||
| hb_filter (lookup_indices)
|
| hb_filter (lookup_indices)
|
||||||
;
|
;
|
||||||
|
|
||||||
@@ -237,7 +268,9 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan,
|
|||||||
hb_set_t *gids_to_retain,
|
hb_set_t *gids_to_retain,
|
||||||
hb_map_t *lookups,
|
hb_map_t *lookups,
|
||||||
hb_map_t *features,
|
hb_map_t *features,
|
||||||
script_langsys_map *langsys_map)
|
script_langsys_map *langsys_map,
|
||||||
|
hb_hashmap_t<unsigned, hb::shared_ptr<hb_set_t>> *feature_record_cond_idx_map,
|
||||||
|
hb_hashmap_t<unsigned, const OT::Feature*> *feature_substitutes_map)
|
||||||
{
|
{
|
||||||
hb_blob_ptr_t<T> table = plan->source_table<T> ();
|
hb_blob_ptr_t<T> table = plan->source_table<T> ();
|
||||||
hb_tag_t table_tag = table->tableTag;
|
hb_tag_t table_tag = table->tableTag;
|
||||||
@@ -245,7 +278,9 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan,
|
|||||||
_collect_layout_indices<T> (plan,
|
_collect_layout_indices<T> (plan,
|
||||||
*table,
|
*table,
|
||||||
&lookup_indices,
|
&lookup_indices,
|
||||||
&feature_indices);
|
&feature_indices,
|
||||||
|
feature_record_cond_idx_map,
|
||||||
|
feature_substitutes_map);
|
||||||
|
|
||||||
if (table_tag == HB_OT_TAG_GSUB)
|
if (table_tag == HB_OT_TAG_GSUB)
|
||||||
hb_ot_layout_lookups_substitute_closure (plan->source,
|
hb_ot_layout_lookups_substitute_closure (plan->source,
|
||||||
@@ -257,9 +292,12 @@ _closure_glyphs_lookups_features (hb_subset_plan_t *plan,
|
|||||||
_remap_indexes (&lookup_indices, lookups);
|
_remap_indexes (&lookup_indices, lookups);
|
||||||
|
|
||||||
// prune features
|
// prune features
|
||||||
table->prune_features (lookups, &feature_indices);
|
table->prune_features (lookups,
|
||||||
|
plan->user_axes_location->is_empty () ? nullptr : feature_record_cond_idx_map,
|
||||||
|
feature_substitutes_map,
|
||||||
|
&feature_indices);
|
||||||
hb_map_t duplicate_feature_map;
|
hb_map_t duplicate_feature_map;
|
||||||
_GSUBGPOS_find_duplicate_features (*table, lookups, &feature_indices, &duplicate_feature_map);
|
_GSUBGPOS_find_duplicate_features (*table, lookups, &feature_indices, feature_substitutes_map, &duplicate_feature_map);
|
||||||
|
|
||||||
feature_indices.clear ();
|
feature_indices.clear ();
|
||||||
table->prune_langsys (&duplicate_feature_map, plan->layout_scripts, langsys_map, &feature_indices);
|
table->prune_langsys (&duplicate_feature_map, plan->layout_scripts, langsys_map, &feature_indices);
|
||||||
@@ -419,14 +457,19 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes,
|
|||||||
hb_subset_plan_t *plan)
|
hb_subset_plan_t *plan)
|
||||||
{
|
{
|
||||||
OT::cmap::accelerator_t cmap (plan->source);
|
OT::cmap::accelerator_t cmap (plan->source);
|
||||||
|
|
||||||
unsigned size_threshold = plan->source->get_num_glyphs ();
|
unsigned size_threshold = plan->source->get_num_glyphs ();
|
||||||
if (glyphs->is_empty () && unicodes->get_population () < size_threshold)
|
if (glyphs->is_empty () && unicodes->get_population () < size_threshold)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
const hb_map_t* unicode_to_gid = nullptr;
|
||||||
|
if (plan->accelerator)
|
||||||
|
unicode_to_gid = &plan->accelerator->unicode_to_gid;
|
||||||
|
|
||||||
// This is approach to collection is faster, but can only be used if glyphs
|
// This is approach to collection is faster, but can only be used if glyphs
|
||||||
// are not being explicitly added to the subset and the input unicodes set is
|
// are not being explicitly added to the subset and the input unicodes set is
|
||||||
// not excessively large (eg. an inverted set).
|
// not excessively large (eg. an inverted set).
|
||||||
plan->unicode_to_new_gid_list.alloc (unicodes->get_population ());
|
plan->unicode_to_new_gid_list.alloc (unicodes->get_population ());
|
||||||
|
if (!unicode_to_gid) {
|
||||||
for (hb_codepoint_t cp : *unicodes)
|
for (hb_codepoint_t cp : *unicodes)
|
||||||
{
|
{
|
||||||
hb_codepoint_t gid;
|
hb_codepoint_t gid;
|
||||||
@@ -439,21 +482,48 @@ _populate_unicodes_to_retain (const hb_set_t *unicodes,
|
|||||||
plan->codepoint_to_glyph->set (cp, gid);
|
plan->codepoint_to_glyph->set (cp, gid);
|
||||||
plan->unicode_to_new_gid_list.push (hb_pair (cp, gid));
|
plan->unicode_to_new_gid_list.push (hb_pair (cp, gid));
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Use in memory unicode to gid map it's faster then looking up from
|
||||||
|
// the map. This code is mostly duplicated from above to avoid doing
|
||||||
|
// conditionals on the presence of the unicode_to_gid map each
|
||||||
|
// iteration.
|
||||||
|
for (hb_codepoint_t cp : *unicodes)
|
||||||
|
{
|
||||||
|
hb_codepoint_t gid = unicode_to_gid->get (cp);
|
||||||
|
if (gid == HB_MAP_VALUE_INVALID)
|
||||||
|
{
|
||||||
|
DEBUG_MSG(SUBSET, nullptr, "Drop U+%04X; no gid", cp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
plan->codepoint_to_glyph->set (cp, gid);
|
||||||
|
plan->unicode_to_new_gid_list.push (hb_pair (cp, gid));
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// This approach is slower, but can handle adding in glyphs to the subset and will match
|
// This approach is slower, but can handle adding in glyphs to the subset and will match
|
||||||
// them with cmap entries.
|
// them with cmap entries.
|
||||||
hb_map_t unicode_glyphid_map;
|
|
||||||
hb_set_t cmap_unicodes;
|
hb_map_t unicode_glyphid_map_storage;
|
||||||
cmap.collect_mapping (&cmap_unicodes, &unicode_glyphid_map);
|
hb_set_t cmap_unicodes_storage;
|
||||||
|
const hb_map_t* unicode_glyphid_map = &unicode_glyphid_map_storage;
|
||||||
|
const hb_set_t* cmap_unicodes = &cmap_unicodes_storage;
|
||||||
|
|
||||||
|
if (!plan->accelerator) {
|
||||||
|
cmap.collect_mapping (&cmap_unicodes_storage, &unicode_glyphid_map_storage);
|
||||||
plan->unicode_to_new_gid_list.alloc (hb_min(unicodes->get_population ()
|
plan->unicode_to_new_gid_list.alloc (hb_min(unicodes->get_population ()
|
||||||
+ glyphs->get_population (),
|
+ glyphs->get_population (),
|
||||||
cmap_unicodes.get_population ()));
|
cmap_unicodes->get_population ()));
|
||||||
|
} else {
|
||||||
|
unicode_glyphid_map = &plan->accelerator->unicode_to_gid;
|
||||||
|
cmap_unicodes = &plan->accelerator->unicodes;
|
||||||
|
}
|
||||||
|
|
||||||
for (hb_codepoint_t cp : cmap_unicodes)
|
for (hb_codepoint_t cp : *cmap_unicodes)
|
||||||
{
|
{
|
||||||
hb_codepoint_t gid = unicode_glyphid_map[cp];
|
hb_codepoint_t gid = (*unicode_glyphid_map)[cp];
|
||||||
if (!unicodes->has (cp) && !glyphs->has (gid))
|
if (!unicodes->has (cp) && !glyphs->has (gid))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -509,9 +579,7 @@ _glyf_add_gid_and_children (const OT::glyf_accelerator_t &glyf,
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
_populate_gids_to_retain (hb_subset_plan_t* plan,
|
_populate_gids_to_retain (hb_subset_plan_t* plan,
|
||||||
bool close_over_gsub,
|
hb_set_t* drop_tables)
|
||||||
bool close_over_gpos,
|
|
||||||
bool close_over_gdef)
|
|
||||||
{
|
{
|
||||||
OT::glyf_accelerator_t glyf (plan->source);
|
OT::glyf_accelerator_t glyf (plan->source);
|
||||||
#ifndef HB_NO_SUBSET_CFF
|
#ifndef HB_NO_SUBSET_CFF
|
||||||
@@ -523,32 +591,42 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
|
|||||||
_cmap_closure (plan->source, plan->unicodes, plan->_glyphset_gsub);
|
_cmap_closure (plan->source, plan->unicodes, plan->_glyphset_gsub);
|
||||||
|
|
||||||
#ifndef HB_NO_SUBSET_LAYOUT
|
#ifndef HB_NO_SUBSET_LAYOUT
|
||||||
if (close_over_gsub)
|
if (!drop_tables->has (HB_OT_TAG_GSUB))
|
||||||
// closure all glyphs/lookups/features needed for GSUB substitutions.
|
// closure all glyphs/lookups/features needed for GSUB substitutions.
|
||||||
_closure_glyphs_lookups_features<GSUB> (
|
_closure_glyphs_lookups_features<GSUB> (
|
||||||
plan,
|
plan,
|
||||||
plan->_glyphset_gsub,
|
plan->_glyphset_gsub,
|
||||||
plan->gsub_lookups,
|
plan->gsub_lookups,
|
||||||
plan->gsub_features,
|
plan->gsub_features,
|
||||||
plan->gsub_langsys);
|
plan->gsub_langsys,
|
||||||
|
plan->gsub_feature_record_cond_idx_map,
|
||||||
|
plan->gsub_feature_substitutes_map);
|
||||||
|
|
||||||
if (close_over_gpos)
|
if (!drop_tables->has (HB_OT_TAG_GPOS))
|
||||||
_closure_glyphs_lookups_features<GPOS> (
|
_closure_glyphs_lookups_features<GPOS> (
|
||||||
plan,
|
plan,
|
||||||
plan->_glyphset_gsub,
|
plan->_glyphset_gsub,
|
||||||
plan->gpos_lookups,
|
plan->gpos_lookups,
|
||||||
plan->gpos_features,
|
plan->gpos_features,
|
||||||
plan->gpos_langsys);
|
plan->gpos_langsys,
|
||||||
|
plan->gpos_feature_record_cond_idx_map,
|
||||||
|
plan->gpos_feature_substitutes_map);
|
||||||
#endif
|
#endif
|
||||||
_remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ());
|
_remove_invalid_gids (plan->_glyphset_gsub, plan->source->get_num_glyphs ());
|
||||||
|
|
||||||
hb_set_set (plan->_glyphset_mathed, plan->_glyphset_gsub);
|
hb_set_set (plan->_glyphset_mathed, plan->_glyphset_gsub);
|
||||||
|
if (!drop_tables->has (HB_OT_TAG_MATH))
|
||||||
|
{
|
||||||
_math_closure (plan, plan->_glyphset_mathed);
|
_math_closure (plan, plan->_glyphset_mathed);
|
||||||
_remove_invalid_gids (plan->_glyphset_mathed, plan->source->get_num_glyphs ());
|
_remove_invalid_gids (plan->_glyphset_mathed, plan->source->get_num_glyphs ());
|
||||||
|
}
|
||||||
|
|
||||||
hb_set_t cur_glyphset = *plan->_glyphset_mathed;
|
hb_set_t cur_glyphset = *plan->_glyphset_mathed;
|
||||||
|
if (!drop_tables->has (HB_OT_TAG_COLR))
|
||||||
|
{
|
||||||
_colr_closure (plan->source, plan->colrv1_layers, plan->colr_palettes, &cur_glyphset);
|
_colr_closure (plan->source, plan->colrv1_layers, plan->colr_palettes, &cur_glyphset);
|
||||||
_remove_invalid_gids (&cur_glyphset, plan->source->get_num_glyphs ());
|
_remove_invalid_gids (&cur_glyphset, plan->source->get_num_glyphs ());
|
||||||
|
}
|
||||||
|
|
||||||
hb_set_set (plan->_glyphset_colred, &cur_glyphset);
|
hb_set_set (plan->_glyphset_colred, &cur_glyphset);
|
||||||
|
|
||||||
@@ -570,7 +648,7 @@ _populate_gids_to_retain (hb_subset_plan_t* plan,
|
|||||||
|
|
||||||
|
|
||||||
#ifndef HB_NO_VAR
|
#ifndef HB_NO_VAR
|
||||||
if (close_over_gdef)
|
if (!drop_tables->has (HB_OT_TAG_GDEF))
|
||||||
_collect_layout_variation_indices (plan);
|
_collect_layout_variation_indices (plan);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -659,18 +737,22 @@ _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan)
|
|||||||
seg_maps = face->table.avar->get_segment_maps ();
|
seg_maps = face->table.avar->get_segment_maps ();
|
||||||
|
|
||||||
bool axis_not_pinned = false;
|
bool axis_not_pinned = false;
|
||||||
unsigned axis_count = 0;
|
unsigned old_axis_idx = 0, new_axis_idx = 0;
|
||||||
for (const auto& axis : axes)
|
for (const auto& axis : axes)
|
||||||
{
|
{
|
||||||
hb_tag_t axis_tag = axis.get_axis_tag ();
|
hb_tag_t axis_tag = axis.get_axis_tag ();
|
||||||
|
plan->axes_old_index_tag_map->set (old_axis_idx, axis_tag);
|
||||||
|
|
||||||
if (!plan->user_axes_location->has (axis_tag))
|
if (!plan->user_axes_location->has (axis_tag))
|
||||||
{
|
{
|
||||||
axis_not_pinned = true;
|
axis_not_pinned = true;
|
||||||
|
plan->axes_index_map->set (old_axis_idx, new_axis_idx);
|
||||||
|
new_axis_idx++;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
int normalized_v = axis.normalize_axis_value (plan->user_axes_location->get (axis_tag));
|
int normalized_v = axis.normalize_axis_value (plan->user_axes_location->get (axis_tag));
|
||||||
if (has_avar && axis_count < face->table.avar->get_axis_count ())
|
if (has_avar && old_axis_idx < face->table.avar->get_axis_count ())
|
||||||
{
|
{
|
||||||
normalized_v = seg_maps->map (normalized_v);
|
normalized_v = seg_maps->map (normalized_v);
|
||||||
}
|
}
|
||||||
@@ -681,7 +763,7 @@ _normalize_axes_location (hb_face_t *face, hb_subset_plan_t *plan)
|
|||||||
if (has_avar)
|
if (has_avar)
|
||||||
seg_maps = &StructAfter<OT::SegmentMaps> (*seg_maps);
|
seg_maps = &StructAfter<OT::SegmentMaps> (*seg_maps);
|
||||||
|
|
||||||
axis_count++;
|
old_axis_idx++;
|
||||||
}
|
}
|
||||||
plan->all_axes_pinned = !axis_not_pinned;
|
plan->all_axes_pinned = !axis_not_pinned;
|
||||||
}
|
}
|
||||||
@@ -741,6 +823,13 @@ hb_subset_plan_create_or_fail (hb_face_t *face,
|
|||||||
|
|
||||||
plan->gsub_features = hb_map_create ();
|
plan->gsub_features = hb_map_create ();
|
||||||
plan->gpos_features = hb_map_create ();
|
plan->gpos_features = hb_map_create ();
|
||||||
|
|
||||||
|
plan->check_success (plan->gsub_feature_record_cond_idx_map = hb_hashmap_create<unsigned, hb::shared_ptr<hb_set_t>> ());
|
||||||
|
plan->check_success (plan->gpos_feature_record_cond_idx_map = hb_hashmap_create<unsigned, hb::shared_ptr<hb_set_t>> ());
|
||||||
|
|
||||||
|
plan->check_success (plan->gsub_feature_substitutes_map = hb_hashmap_create<unsigned, const OT::Feature*> ());
|
||||||
|
plan->check_success (plan->gpos_feature_substitutes_map = hb_hashmap_create<unsigned, const OT::Feature*> ());
|
||||||
|
|
||||||
plan->colrv1_layers = hb_map_create ();
|
plan->colrv1_layers = hb_map_create ();
|
||||||
plan->colr_palettes = hb_map_create ();
|
plan->colr_palettes = hb_map_create ();
|
||||||
plan->check_success (plan->layout_variation_idx_delta_map = hb_hashmap_create<unsigned, hb_pair_t<unsigned, int>> ());
|
plan->check_success (plan->layout_variation_idx_delta_map = hb_hashmap_create<unsigned, hb_pair_t<unsigned, int>> ());
|
||||||
@@ -751,12 +840,21 @@ hb_subset_plan_create_or_fail (hb_face_t *face,
|
|||||||
plan->check_success (plan->user_axes_location = hb_hashmap_create<hb_tag_t, float> ());
|
plan->check_success (plan->user_axes_location = hb_hashmap_create<hb_tag_t, float> ());
|
||||||
if (plan->user_axes_location && input->axes_location)
|
if (plan->user_axes_location && input->axes_location)
|
||||||
*plan->user_axes_location = *input->axes_location;
|
*plan->user_axes_location = *input->axes_location;
|
||||||
|
plan->check_success (plan->axes_index_map = hb_map_create ());
|
||||||
|
plan->check_success (plan->axes_old_index_tag_map = hb_map_create ());
|
||||||
plan->all_axes_pinned = false;
|
plan->all_axes_pinned = false;
|
||||||
plan->pinned_at_default = true;
|
plan->pinned_at_default = true;
|
||||||
|
|
||||||
plan->check_success (plan->vmtx_map = hb_hashmap_create<unsigned, hb_pair_t<unsigned, int>> ());
|
plan->check_success (plan->vmtx_map = hb_hashmap_create<unsigned, hb_pair_t<unsigned, int>> ());
|
||||||
plan->check_success (plan->hmtx_map = hb_hashmap_create<unsigned, hb_pair_t<unsigned, int>> ());
|
plan->check_success (plan->hmtx_map = hb_hashmap_create<unsigned, hb_pair_t<unsigned, int>> ());
|
||||||
|
|
||||||
|
void* accel = hb_face_get_user_data(face, hb_subset_accelerator_t::user_data_key());
|
||||||
|
|
||||||
|
plan->attach_accelerator_data = input->attach_accelerator_data;
|
||||||
|
if (accel)
|
||||||
|
plan->accelerator = (hb_subset_accelerator_t*) accel;
|
||||||
|
|
||||||
|
|
||||||
if (unlikely (plan->in_error ())) {
|
if (unlikely (plan->in_error ())) {
|
||||||
hb_subset_plan_destroy (plan);
|
hb_subset_plan_destroy (plan);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
@@ -768,10 +866,7 @@ hb_subset_plan_create_or_fail (hb_face_t *face,
|
|||||||
|
|
||||||
_populate_unicodes_to_retain (input->sets.unicodes, input->sets.glyphs, plan);
|
_populate_unicodes_to_retain (input->sets.unicodes, input->sets.glyphs, plan);
|
||||||
|
|
||||||
_populate_gids_to_retain (plan,
|
_populate_gids_to_retain (plan, input->sets.drop_tables);
|
||||||
!input->sets.drop_tables->has (HB_OT_TAG_GSUB),
|
|
||||||
!input->sets.drop_tables->has (HB_OT_TAG_GPOS),
|
|
||||||
!input->sets.drop_tables->has (HB_OT_TAG_GDEF));
|
|
||||||
|
|
||||||
_create_old_gid_to_new_gid_map (face,
|
_create_old_gid_to_new_gid_map (face,
|
||||||
input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS,
|
input->flags & HB_SUBSET_FLAGS_RETAIN_GIDS,
|
||||||
|
|||||||
27
thirdparty/harfbuzz/src/hb-subset-plan.hh
vendored
27
thirdparty/harfbuzz/src/hb-subset-plan.hh
vendored
@@ -31,11 +31,16 @@
|
|||||||
|
|
||||||
#include "hb-subset.h"
|
#include "hb-subset.h"
|
||||||
#include "hb-subset-input.hh"
|
#include "hb-subset-input.hh"
|
||||||
|
#include "hb-subset-accelerator.hh"
|
||||||
|
|
||||||
#include "hb-map.hh"
|
#include "hb-map.hh"
|
||||||
#include "hb-bimap.hh"
|
#include "hb-bimap.hh"
|
||||||
#include "hb-set.hh"
|
#include "hb-set.hh"
|
||||||
|
|
||||||
|
namespace OT {
|
||||||
|
struct Feature;
|
||||||
|
}
|
||||||
|
|
||||||
struct hb_subset_plan_t
|
struct hb_subset_plan_t
|
||||||
{
|
{
|
||||||
hb_subset_plan_t ()
|
hb_subset_plan_t ()
|
||||||
@@ -67,9 +72,15 @@ struct hb_subset_plan_t
|
|||||||
hb_map_destroy (gpos_features);
|
hb_map_destroy (gpos_features);
|
||||||
hb_map_destroy (colrv1_layers);
|
hb_map_destroy (colrv1_layers);
|
||||||
hb_map_destroy (colr_palettes);
|
hb_map_destroy (colr_palettes);
|
||||||
|
hb_map_destroy (axes_index_map);
|
||||||
|
hb_map_destroy (axes_old_index_tag_map);
|
||||||
|
|
||||||
hb_hashmap_destroy (gsub_langsys);
|
hb_hashmap_destroy (gsub_langsys);
|
||||||
hb_hashmap_destroy (gpos_langsys);
|
hb_hashmap_destroy (gpos_langsys);
|
||||||
|
hb_hashmap_destroy (gsub_feature_record_cond_idx_map);
|
||||||
|
hb_hashmap_destroy (gpos_feature_record_cond_idx_map);
|
||||||
|
hb_hashmap_destroy (gsub_feature_substitutes_map);
|
||||||
|
hb_hashmap_destroy (gpos_feature_substitutes_map);
|
||||||
hb_hashmap_destroy (axes_location);
|
hb_hashmap_destroy (axes_location);
|
||||||
hb_hashmap_destroy (sanitized_table_cache);
|
hb_hashmap_destroy (sanitized_table_cache);
|
||||||
hb_hashmap_destroy (hmtx_map);
|
hb_hashmap_destroy (hmtx_map);
|
||||||
@@ -87,6 +98,7 @@ struct hb_subset_plan_t
|
|||||||
|
|
||||||
bool successful;
|
bool successful;
|
||||||
unsigned flags;
|
unsigned flags;
|
||||||
|
bool attach_accelerator_data = false;
|
||||||
|
|
||||||
// For each cp that we'd like to retain maps to the corresponding gid.
|
// For each cp that we'd like to retain maps to the corresponding gid.
|
||||||
hb_set_t *unicodes;
|
hb_set_t *unicodes;
|
||||||
@@ -143,6 +155,15 @@ struct hb_subset_plan_t
|
|||||||
hb_map_t *gsub_features;
|
hb_map_t *gsub_features;
|
||||||
hb_map_t *gpos_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
|
//active layers/palettes we'd like to retain
|
||||||
hb_map_t *colrv1_layers;
|
hb_map_t *colrv1_layers;
|
||||||
hb_map_t *colr_palettes;
|
hb_map_t *colr_palettes;
|
||||||
@@ -158,6 +179,10 @@ struct hb_subset_plan_t
|
|||||||
hb_hashmap_t<hb_tag_t, int> *axes_location;
|
hb_hashmap_t<hb_tag_t, int> *axes_location;
|
||||||
//user specified axes location map
|
//user specified axes location map
|
||||||
hb_hashmap_t<hb_tag_t, float> *user_axes_location;
|
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 all_axes_pinned;
|
||||||
bool pinned_at_default;
|
bool pinned_at_default;
|
||||||
|
|
||||||
@@ -166,6 +191,8 @@ struct hb_subset_plan_t
|
|||||||
//vmtx metrics map: new gid->(advance, lsb)
|
//vmtx metrics map: new gid->(advance, lsb)
|
||||||
hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *vmtx_map;
|
hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *vmtx_map;
|
||||||
|
|
||||||
|
const hb_subset_accelerator_t* accelerator;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
|
|||||||
30
thirdparty/harfbuzz/src/hb-subset.cc
vendored
30
thirdparty/harfbuzz/src/hb-subset.cc
vendored
@@ -50,11 +50,13 @@
|
|||||||
#include "hb-ot-color-cbdt-table.hh"
|
#include "hb-ot-color-cbdt-table.hh"
|
||||||
#include "hb-ot-layout-gsub-table.hh"
|
#include "hb-ot-layout-gsub-table.hh"
|
||||||
#include "hb-ot-layout-gpos-table.hh"
|
#include "hb-ot-layout-gpos-table.hh"
|
||||||
|
#include "hb-ot-var-fvar-table.hh"
|
||||||
#include "hb-ot-var-gvar-table.hh"
|
#include "hb-ot-var-gvar-table.hh"
|
||||||
#include "hb-ot-var-hvar-table.hh"
|
#include "hb-ot-var-hvar-table.hh"
|
||||||
#include "hb-ot-math-table.hh"
|
#include "hb-ot-math-table.hh"
|
||||||
#include "hb-ot-stat-table.hh"
|
#include "hb-ot-stat-table.hh"
|
||||||
#include "hb-repacker.hh"
|
#include "hb-repacker.hh"
|
||||||
|
#include "hb-subset-accelerator.hh"
|
||||||
|
|
||||||
using OT::Layout::GSUB;
|
using OT::Layout::GSUB;
|
||||||
using OT::Layout::GPOS;
|
using OT::Layout::GPOS;
|
||||||
@@ -475,6 +477,9 @@ _subset_table (hb_subset_plan_t *plan,
|
|||||||
case HB_OT_TAG_HVAR: return _subset<const OT::HVAR> (plan, buf);
|
case HB_OT_TAG_HVAR: return _subset<const OT::HVAR> (plan, buf);
|
||||||
case HB_OT_TAG_VVAR: return _subset<const OT::VVAR> (plan, buf);
|
case HB_OT_TAG_VVAR: return _subset<const OT::VVAR> (plan, buf);
|
||||||
#endif
|
#endif
|
||||||
|
case HB_OT_TAG_fvar:
|
||||||
|
if (plan->user_axes_location->is_empty ()) return _passthrough (plan, tag);
|
||||||
|
return _subset<const OT::fvar> (plan, buf);
|
||||||
case HB_OT_TAG_STAT:
|
case HB_OT_TAG_STAT:
|
||||||
/*TODO(qxliu): change the condition as we support more complex
|
/*TODO(qxliu): change the condition as we support more complex
|
||||||
* instancing operation*/
|
* instancing operation*/
|
||||||
@@ -490,6 +495,27 @@ _subset_table (hb_subset_plan_t *plan,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void _attach_accelerator_data (const hb_subset_plan_t* plan,
|
||||||
|
hb_face_t* face /* IN/OUT */)
|
||||||
|
{
|
||||||
|
hb_subset_accelerator_t* accel =
|
||||||
|
hb_subset_accelerator_t::create (*plan->codepoint_to_glyph,
|
||||||
|
*plan->unicodes);
|
||||||
|
|
||||||
|
if (accel->in_error ())
|
||||||
|
{
|
||||||
|
hb_subset_accelerator_t::destroy (accel);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hb_face_set_user_data(face,
|
||||||
|
hb_subset_accelerator_t::user_data_key(),
|
||||||
|
accel,
|
||||||
|
hb_subset_accelerator_t::destroy,
|
||||||
|
true))
|
||||||
|
hb_subset_accelerator_t::destroy (accel);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* hb_subset_or_fail:
|
* hb_subset_or_fail:
|
||||||
* @source: font face data to be subset.
|
* @source: font face data to be subset.
|
||||||
@@ -572,6 +598,10 @@ hb_subset_plan_execute_or_fail (hb_subset_plan_t *plan)
|
|||||||
offset += num_tables;
|
offset += num_tables;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (success && plan->attach_accelerator_data) {
|
||||||
|
_attach_accelerator_data (plan, plan->dest);
|
||||||
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
return success ? hb_face_reference (plan->dest) : nullptr;
|
return success ? hb_face_reference (plan->dest) : nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
17
thirdparty/harfbuzz/src/hb-subset.h
vendored
17
thirdparty/harfbuzz/src/hb-subset.h
vendored
@@ -70,6 +70,14 @@ typedef struct hb_subset_plan_t hb_subset_plan_t;
|
|||||||
* in the final subset.
|
* in the final subset.
|
||||||
* @HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES: If set then the unicode ranges in
|
* @HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES: If set then the unicode ranges in
|
||||||
* OS/2 will not be recalculated.
|
* OS/2 will not be recalculated.
|
||||||
|
* @HB_SUBSET_FLAGS_PATCH_MODE: If set the subsetter behaviour will be modified
|
||||||
|
* to produce a subset that is better suited to patching. For example cmap
|
||||||
|
* subtable format will be kept stable.
|
||||||
|
* @HB_SUBSET_FLAGS_OMIT_GLYF: If set the subsetter won't actually produce the final
|
||||||
|
* glyf table bytes. The table directory will include and entry as if the table was
|
||||||
|
* there but the actual final font blob will be truncated prior to the glyf data. This
|
||||||
|
* is a useful performance optimization when a font aware binary patching algorithm
|
||||||
|
* is being used to diff two subsets.
|
||||||
*
|
*
|
||||||
* List of boolean properties that can be configured on the subset input.
|
* List of boolean properties that can be configured on the subset input.
|
||||||
*
|
*
|
||||||
@@ -86,6 +94,8 @@ typedef enum { /*< flags >*/
|
|||||||
HB_SUBSET_FLAGS_NOTDEF_OUTLINE = 0x00000040u,
|
HB_SUBSET_FLAGS_NOTDEF_OUTLINE = 0x00000040u,
|
||||||
HB_SUBSET_FLAGS_GLYPH_NAMES = 0x00000080u,
|
HB_SUBSET_FLAGS_GLYPH_NAMES = 0x00000080u,
|
||||||
HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES = 0x00000100u,
|
HB_SUBSET_FLAGS_NO_PRUNE_UNICODE_RANGES = 0x00000100u,
|
||||||
|
// Not supported yet: HB_SUBSET_FLAGS_PATCH_MODE = 0x00000200u,
|
||||||
|
// Not supported yet: HB_SUBSET_FLAGS_OMIT_GLYF = 0x00000400u,
|
||||||
} hb_subset_flags_t;
|
} hb_subset_flags_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -169,6 +179,13 @@ hb_subset_input_pin_axis_location (hb_subset_input_t *input,
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HB_EXPERIMENTAL_API
|
||||||
|
|
||||||
|
HB_EXTERN hb_face_t *
|
||||||
|
hb_subset_preprocess (hb_face_t *source);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
HB_EXTERN hb_face_t *
|
HB_EXTERN hb_face_t *
|
||||||
hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input);
|
hb_subset_or_fail (hb_face_t *source, const hb_subset_input_t *input);
|
||||||
|
|
||||||
|
|||||||
6
thirdparty/harfbuzz/src/hb-version.h
vendored
6
thirdparty/harfbuzz/src/hb-version.h
vendored
@@ -47,20 +47,20 @@ HB_BEGIN_DECLS
|
|||||||
*
|
*
|
||||||
* The minor component of the library version available at compile-time.
|
* The minor component of the library version available at compile-time.
|
||||||
*/
|
*/
|
||||||
#define HB_VERSION_MINOR 2
|
#define HB_VERSION_MINOR 3
|
||||||
/**
|
/**
|
||||||
* HB_VERSION_MICRO:
|
* HB_VERSION_MICRO:
|
||||||
*
|
*
|
||||||
* The micro component of the library version available at compile-time.
|
* The micro component of the library version available at compile-time.
|
||||||
*/
|
*/
|
||||||
#define HB_VERSION_MICRO 0
|
#define HB_VERSION_MICRO 1
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HB_VERSION_STRING:
|
* HB_VERSION_STRING:
|
||||||
*
|
*
|
||||||
* A string literal containing the library version available at compile-time.
|
* A string literal containing the library version available at compile-time.
|
||||||
*/
|
*/
|
||||||
#define HB_VERSION_STRING "5.2.0"
|
#define HB_VERSION_STRING "5.3.1"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* HB_VERSION_ATLEAST:
|
* HB_VERSION_ATLEAST:
|
||||||
|
|||||||
Reference in New Issue
Block a user