Merge pull request #845 from googlefonts/drophints

[subset] drop hints from composites
pull/852/head
rsheeter 7 years ago committed by GitHub
commit 588a4e0f9b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 10
      src/hb-ot-glyf-table.hh
  2. 20
      src/hb-subset-glyf.cc
  3. BIN
      test/api/fonts/Roboto-Regular.components.1fc.nohints.ttf
  4. 28
      test/api/test-subset-glyf.c
  5. 1
      test/subset/data/Makefile.am
  6. 1
      test/subset/data/Makefile.sources
  7. BIN
      test/subset/data/expected/basics/Roboto-Regular.abc.default.61,62,63.ttf
  8. BIN
      test/subset/data/expected/basics/Roboto-Regular.abc.default.61,63.ttf
  9. BIN
      test/subset/data/expected/basics/Roboto-Regular.abc.default.61.ttf
  10. BIN
      test/subset/data/expected/basics/Roboto-Regular.abc.default.63.ttf
  11. BIN
      test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61,62,63.ttf
  12. BIN
      test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61,63.ttf
  13. BIN
      test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.61.ttf
  14. BIN
      test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.62.ttf
  15. BIN
      test/subset/data/expected/basics/Roboto-Regular.abc.drop-hints.63.ttf
  16. BIN
      test/subset/data/expected/full-font/Roboto-Regular.default.1FC,21,41,20,62,63.ttf
  17. BIN
      test/subset/data/expected/full-font/Roboto-Regular.default.61,62,63.ttf
  18. BIN
      test/subset/data/expected/full-font/Roboto-Regular.drop-hints.1FC,21,41,20,62,63.ttf
  19. BIN
      test/subset/data/expected/full-font/Roboto-Regular.drop-hints.61,62,63.ttf
  20. BIN
      test/subset/data/fonts/Roboto-Regular.ttf
  21. 1
      test/subset/data/profiles/drop-hints.txt
  22. 5
      test/subset/data/tests/basics.tests
  23. 11
      test/subset/data/tests/full-font.tests
  24. 23
      test/subset/generate-expected-outputs.py
  25. 3
      test/subset/run-tests.py
  26. 11
      test/subset/subset_test_suite.py

@ -402,17 +402,17 @@ struct glyf
int16_t num_contours = (int16_t) glyph_header.numberOfContours;
if (num_contours < 0)
{
CompositeGlyphHeader::Iterator *composite_it;
CompositeGlyphHeader::Iterator composite_it;
if (unlikely (!CompositeGlyphHeader::get_iterator (
(const char*) this->glyf_table + start_offset,
end_offset - start_offset, composite_it))) return false;
end_offset - start_offset, &composite_it))) return false;
const CompositeGlyphHeader *last;
do {
last = composite_it->current;
} while (composite_it->move_to_next());
last = composite_it.current;
} while (composite_it.move_to_next());
if ( (uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS)
*instruction_start = start_offset + ((char *) last - (char *) glyf_table->dataX) + last->get_size();
*instruction_start = ((char *) last - (char *) glyf_table->dataX) + last->get_size();
else
*instruction_start = end_offset;
*instruction_end = end_offset;

@ -136,6 +136,20 @@ _update_components (hb_subset_plan_t * plan,
}
}
static bool _remove_composite_instruction_flag(char *glyf_prime, unsigned int length)
{
/* remove WE_HAVE_INSTRUCTIONS from flags in dest */
OT::glyf::CompositeGlyphHeader::Iterator composite_it;
if (unlikely (!OT::glyf::CompositeGlyphHeader::get_iterator (glyf_prime, length, &composite_it))) return false;
const OT::glyf::CompositeGlyphHeader *glyph;
do {
glyph = composite_it.current;
OT::HBUINT16 *flags = const_cast<OT::HBUINT16 *> (&glyph->flags);
flags->set ( (uint16_t) *flags & ~OT::glyf::CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS);
} while (composite_it.move_to_next());
return true;
}
static bool
_write_glyf_and_loca_prime (hb_subset_plan_t *plan,
const OT::glyf::accelerator_t &glyf,
@ -178,9 +192,11 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan,
{
memcpy (glyf_prime_data_next, glyf_data + start_offset, instruction_start - start_offset);
memcpy (glyf_prime_data_next + instruction_start - start_offset, glyf_data + instruction_end, end_offset - instruction_end);
/* if the instructions end at the end this was a composite glyph */
/* if the instructions end at the end this was a composite glyph, else simple */
if (instruction_end == end_offset)
; // TODO(rsheeter) remove WE_HAVE_INSTRUCTIONS from last flags
{
if (unlikely (!_remove_composite_instruction_flag (glyf_prime_data_next, length))) return false;
}
else
/* zero instruction length, which is just before instruction_start */
memset (glyf_prime_data_next + instruction_start - start_offset - 2, 0, 2);

@ -121,7 +121,7 @@ test_subset_glyf_noop (void)
}
static void
test_subset_glyf_strip_hints (void)
test_subset_glyf_strip_hints_simple (void)
{
hb_face_t *face_abc = hb_subset_test_open_font ("fonts/Roboto-Regular.abc.ttf");
hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.nohints.ttf");
@ -143,7 +143,28 @@ test_subset_glyf_strip_hints (void)
hb_face_destroy (face_ac);
}
// TODO(rsheeter): test strip hints from composite
static void
test_subset_glyf_strip_hints_composite (void)
{
hb_face_t *face_components = hb_subset_test_open_font ("fonts/Roboto-Regular.components.ttf");
hb_face_t *face_subset = hb_subset_test_open_font ("fonts/Roboto-Regular.components.1fc.nohints.ttf");
hb_set_t *codepoints = hb_set_create();
hb_set_add (codepoints, 0x1fc);
hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
*hb_subset_input_drop_hints(input) = true;
hb_face_t *face_generated_subset = hb_subset_test_create_subset (face_components, input);
hb_set_destroy (codepoints);
hb_subset_test_check (face_subset, face_generated_subset, HB_TAG ('g','l','y','f'));
hb_subset_test_check (face_subset, face_generated_subset, HB_TAG ('l','o','c', 'a'));
check_maxp_num_glyphs(face_generated_subset, 4, false);
hb_face_destroy (face_generated_subset);
hb_face_destroy (face_subset);
hb_face_destroy (face_components);
}
// TODO(grieger): test for long loca generation.
@ -154,7 +175,8 @@ main (int argc, char **argv)
hb_test_add (test_subset_glyf_noop);
hb_test_add (test_subset_glyf);
hb_test_add (test_subset_glyf_strip_hints);
hb_test_add (test_subset_glyf_strip_hints_simple);
hb_test_add (test_subset_glyf_strip_hints_composite);
hb_test_add (test_subset_glyf_with_components);
return hb_test_run();

@ -8,6 +8,7 @@ SUBDIRS =
EXTRA_DIST = \
$(TESTS) \
expected/basics \
expected/full-font \
fonts \
profiles \
$(NULL)

@ -1,5 +1,6 @@
TESTS = \
tests/basics.tests \
tests/full-font.tests \
$(NULL)
XFAIL_TESTS = \

@ -3,6 +3,11 @@ Roboto-Regular.abc.ttf
PROFILES:
default.txt
drop-hints.txt
SUBSETS:
abc
b
c
ac
a

@ -0,0 +1,11 @@
FONTS:
Roboto-Regular.ttf
PROFILES:
default.txt
drop-hints.txt
SUBSETS:
abc
Ǽ!A bc

@ -15,12 +15,17 @@ def usage():
print "Usage: generate-expected-outputs.py <test suite file> ..."
def generate_expected_output(input_file, unicodes, output_path):
check_call(["fonttools", "subset",
input_file,
"--drop-tables+=DSIG,GPOS,GSUB,GDEF",
"--unicodes=%s" % unicodes,
"--output-file=%s" % output_path])
def generate_expected_output(input_file, unicodes, profile_flags, output_path):
args = ["fonttools", "subset", input_file]
args.extend(profile_flags)
args.extend(["--notdef-outline",
"--name-IDs=*",
"--name-languages=*",
"--name-legacy",
"--drop-tables+=DSIG,GPOS,GSUB,GDEF",
"--unicodes=%s" % unicodes,
"--output-file=%s" % output_path])
check_call(args)
args = sys.argv[1:]
@ -37,6 +42,6 @@ for path in args:
unicodes = test.unicodes()
font_name = test.get_font_name()
print "Creating subset %s/%s" % (output_directory, font_name)
generate_expected_output(test.font_path, unicodes,
os.path.join(output_directory,
font_name))
generate_expected_output(test.font_path, unicodes, test.get_profile_flags(),
os.path.join(output_directory,
font_name))

@ -44,6 +44,7 @@ def run_test(test):
"--font-file=" + test.font_path,
"--output-file=" + out_file,
"--unicodes=%s" % test.unicodes()]
cli_args.extend (test.get_profile_flags())
print (' '.join(cli_args))
_, return_code = cmd(cli_args)
@ -78,7 +79,7 @@ def run_ttx(file):
def strip_check_sum (ttx_string):
return re.sub ('checkSumAdjustment value=["]0x([0-9a-fA-F])+["]',
'checkSumAdjustment value="0x00000000"',
'checkSumAdjustment value="0x00000000"',
ttx_string, count=1)
args = sys.argv[1:]

@ -1,5 +1,6 @@
#!/usr/bin/env python
import io
import os
# A single test in a subset test suite. Identifies a font
@ -13,15 +14,19 @@ class Test:
def unicodes(self):
return ",".join("%X" % ord(c) for (i, c) in enumerate(self.subset))
def get_profile_flags(self):
with io.open(self.profile_path, mode="r", encoding="utf-8") as f:
return f.read().splitlines();
def get_font_name(self):
font_base_name = os.path.basename(self.font_path)
font_base_name_parts = os.path.splitext(font_base_name)
profile_name = os.path.splitext(os.path.basename(self.profile_path))[0]
return "%s.%s.%s%s" % (font_base_name_parts[0],
profile_name,
self.unicodes(),
font_base_name_parts[1])
profile_name,
self.unicodes(),
font_base_name_parts[1])
# A group of tests to perform on the subsetter. Each test
# Identifies a font a subsetting profile, and a subset to be cut.

Loading…
Cancel
Save