remove empty lookup subtables
Added a variant of subset_offset_array which takes an extra arg passed to serialize_subset for this impl. Added a new api test "test-subset-gpos" for this.
This commit is contained in:
parent
a3cf4ae080
commit
72cbfb9059
|
@ -155,6 +155,43 @@ struct subset_offset_array_t
|
|||
const void *_dest_base;
|
||||
};
|
||||
|
||||
|
||||
template<typename OutputArray, typename Arg>
|
||||
struct subset_offset_array_arg_t
|
||||
{
|
||||
subset_offset_array_arg_t
|
||||
(hb_subset_context_t *subset_context,
|
||||
OutputArray& out,
|
||||
const void *src_base,
|
||||
const void *dest_base,
|
||||
Arg &&arg)
|
||||
: _subset_context(subset_context), _out (out), _src_base (src_base), _dest_base (dest_base), _arg (arg) {}
|
||||
|
||||
template <typename T>
|
||||
bool
|
||||
operator ()
|
||||
(T&& offset)
|
||||
{
|
||||
auto *o = _out.serialize_append (_subset_context->serializer);
|
||||
if (unlikely (!o)) return false;
|
||||
auto snap = _subset_context->serializer->snapshot ();
|
||||
bool ret = o->serialize_subset (_subset_context, offset, _src_base, _dest_base, _arg);
|
||||
if (!ret)
|
||||
{
|
||||
_out.pop ();
|
||||
_subset_context->serializer->revert (snap);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
hb_subset_context_t *_subset_context;
|
||||
OutputArray &_out;
|
||||
const void *_src_base;
|
||||
const void *_dest_base;
|
||||
Arg &&_arg;
|
||||
};
|
||||
|
||||
/*
|
||||
* Helper to subset an array of offsets. Subsets the thing pointed to by each offset
|
||||
* and discards the offset in the array if the subset operation results in an empty
|
||||
|
@ -172,6 +209,19 @@ struct
|
|||
{
|
||||
return subset_offset_array_t<OutputArray> (subset_context, out, src_base, dest_base);
|
||||
}
|
||||
|
||||
/* Variant with one extra argument passed to serialize_subset */
|
||||
template<typename OutputArray, typename Arg>
|
||||
subset_offset_array_arg_t<OutputArray, Arg>
|
||||
operator ()
|
||||
(hb_subset_context_t *subset_context,
|
||||
OutputArray& out,
|
||||
const void *src_base,
|
||||
const void *dest_base,
|
||||
Arg &&arg) const
|
||||
{
|
||||
return subset_offset_array_arg_t<OutputArray, Arg> (subset_context, out, src_base, dest_base, arg);
|
||||
}
|
||||
}
|
||||
HB_FUNCOBJ (subset_offset_array);
|
||||
|
||||
|
@ -1006,17 +1056,17 @@ struct Lookup
|
|||
bool subset (hb_subset_context_t *c) const
|
||||
{
|
||||
TRACE_SUBSET (this);
|
||||
auto *out = c->serializer->embed (*this);
|
||||
if (unlikely (!out)) return_trace (false);
|
||||
auto *out = c->serializer->start_embed (*this);
|
||||
if (unlikely (!out || !c->serializer->extend_min (out))) return_trace (false);
|
||||
out->lookupType = lookupType;
|
||||
out->lookupFlag = lookupFlag;
|
||||
|
||||
/* Subset the actual subtables. */
|
||||
/* TODO Drop empty ones, either by calling intersects() beforehand,
|
||||
* or just dropping null offsets after. */
|
||||
const OffsetArrayOf<TSubTable>& subtables = get_subtables<TSubTable> ();
|
||||
OffsetArrayOf<TSubTable>& out_subtables = out->get_subtables<TSubTable> ();
|
||||
unsigned int count = subTable.len;
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
out_subtables[i].serialize_subset (c, subtables[i], this, out, get_type ());
|
||||
const hb_set_t *glyphset = c->plan->glyphset ();
|
||||
unsigned int lookup_type = get_type ();
|
||||
+ hb_iter (get_subtables <TSubTable> ())
|
||||
| hb_filter ([=] (const OffsetTo<TSubTable> &_) { return (this+_).intersects (glyphset, lookup_type); })
|
||||
| hb_apply (subset_offset_array (c, out->get_subtables<TSubTable> (), this, out, lookup_type))
|
||||
;
|
||||
|
||||
return_trace (true);
|
||||
}
|
||||
|
|
|
@ -1931,6 +1931,12 @@ struct PosLookupSubTable
|
|||
}
|
||||
}
|
||||
|
||||
bool intersects (const hb_set_t *glyphs, unsigned int lookup_type) const
|
||||
{
|
||||
hb_intersects_context_t c (glyphs);
|
||||
return dispatch (&c, lookup_type);
|
||||
}
|
||||
|
||||
protected:
|
||||
union {
|
||||
SinglePos single;
|
||||
|
|
|
@ -1324,6 +1324,12 @@ struct SubstLookupSubTable
|
|||
}
|
||||
}
|
||||
|
||||
bool intersects (const hb_set_t *glyphs, unsigned int lookup_type) const
|
||||
{
|
||||
hb_intersects_context_t c (glyphs);
|
||||
return dispatch (&c, lookup_type);
|
||||
}
|
||||
|
||||
protected:
|
||||
union {
|
||||
SingleSubst single;
|
||||
|
|
|
@ -56,6 +56,7 @@ TEST_PROGS = \
|
|||
test-subset-hvar \
|
||||
test-subset-vvar \
|
||||
test-subset-sbix \
|
||||
test-subset-gpos \
|
||||
test-unicode \
|
||||
test-version \
|
||||
test-subset-nameids \
|
||||
|
@ -77,6 +78,7 @@ test_subset_hvar_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
|
|||
test_subset_vvar_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
|
||||
test_subset_sbix_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
|
||||
test_subset_nameids_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
|
||||
test_subset_gpos_LDADD = $(LDADD) $(top_builddir)/src/libharfbuzz-subset.la
|
||||
|
||||
test_unicode_CPPFLAGS = \
|
||||
$(AM_CPPFLAGS) \
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright © 2020 Adobe 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.
|
||||
*
|
||||
* Adobe Author(s): Michiharu Ariza
|
||||
*/
|
||||
|
||||
#include "hb-test.h"
|
||||
#include "hb-subset-test.h"
|
||||
|
||||
/* Unit tests for GPOS subsetting */
|
||||
|
||||
static void
|
||||
test_subset_gpos_lookup_subtable (void)
|
||||
{
|
||||
hb_face_t *face_pwa = hb_test_open_font_file ("fonts/Roboto-Regular-gpos-.aw.ttf");
|
||||
hb_face_t *face_wa = hb_test_open_font_file ("fonts/Roboto-Regular-gpos-aw.ttf");
|
||||
|
||||
hb_set_t *codepoints = hb_set_create ();
|
||||
hb_face_t *face_pwa_subset;
|
||||
hb_set_add (codepoints, 'a');
|
||||
hb_set_add (codepoints, 'w');
|
||||
|
||||
hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
|
||||
|
||||
hb_set_del (hb_subset_input_drop_tables_set (input), HB_TAG ('G', 'P', 'O', 'S'));
|
||||
|
||||
face_pwa_subset = hb_subset_test_create_subset (face_pwa, input);
|
||||
hb_set_destroy (codepoints);
|
||||
|
||||
hb_subset_test_check (face_wa, face_pwa_subset, HB_TAG ('G','P','O','S'));
|
||||
|
||||
hb_face_destroy (face_pwa_subset);
|
||||
hb_face_destroy (face_pwa);
|
||||
hb_face_destroy (face_wa);
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
hb_test_init (&argc, &argv);
|
||||
|
||||
hb_test_add (test_subset_gpos_lookup_subtable);
|
||||
|
||||
return hb_test_run ();
|
||||
}
|
Loading…
Reference in New Issue