Merge pull request #845 from googlefonts/drophints
[subset] drop hints from composites
This commit is contained in:
commit
588a4e0f9b
|
@ -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);
|
||||
|
|
Binary file not shown.
|
@ -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 = \
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
--no-hinting
|
|
@ -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…
Reference in New Issue