[subset] Subset name table step 3, add --nameids option to guide the

selection of which name records to keep in the subset method.
This commit is contained in:
Qunxin Liu 2019-04-05 10:05:55 -07:00 committed by Garret Rieger
parent 2637a81615
commit e501ea143d
9 changed files with 92 additions and 17 deletions

View File

@ -106,12 +106,12 @@ struct NameRecord
return_trace (false);
}
this->platformID.set (origin_namerecord.platformID);
this->encodingID.set (origin_namerecord.encodingID);
this->languageID.set (origin_namerecord.languageID);
this->nameID.set (origin_namerecord.nameID);
this->length.set (origin_namerecord.length);
this->offset.set (*new_offset);
this->platformID = origin_namerecord.platformID;
this->encodingID = origin_namerecord.encodingID;
this->languageID = origin_namerecord.languageID;
this->nameID = origin_namerecord.nameID;
this->length = origin_namerecord.length;
this->offset = *new_offset;
*new_offset += origin_namerecord.length;
return_trace (true);
@ -194,6 +194,9 @@ struct name
{
if (format == 0 && (unsigned int) nameRecordZ[i].nameID > 25)
continue;
if (!hb_set_is_empty (plan->name_ids) &&
!hb_set_has (plan->name_ids, source_name->nameRecordZ[i].nameID))
continue;
result += acc.get_name (i).get_size ();
name_record_idx_to_retain.push (i);
}
@ -214,9 +217,9 @@ struct name
if (unlikely (!c->extend_min ((*this)))) return_trace (false);
this->format.set (source_name->format);
this->count.set (name_record_idx_to_retain.length);
this->stringOffset.set (min_size + name_record_idx_to_retain.length * NameRecord::static_size);
this->format = source_name->format;
this->count = name_record_idx_to_retain.length;
this->stringOffset = min_size + name_record_idx_to_retain.length * NameRecord::static_size;
//write new NameRecord
unsigned int new_offset = 0;
@ -253,9 +256,10 @@ struct name
return_trace (false);
}
unsigned int origin_offset = source_name->stringOffset + source_name->nameRecordZ[idx].offset;
memcpy (new_pos, source_name + origin_offset, size);
const HBUINT8* source_string_pool = (source_name + source_name->stringOffset).arrayZ;
unsigned int name_record_offset = source_name->nameRecordZ[idx].offset;
memcpy (new_pos, source_string_pool + name_record_offset, size);
}
acc.fini ();

View File

@ -44,6 +44,7 @@ hb_subset_input_create_or_fail ()
input->unicodes = hb_set_create ();
input->glyphs = hb_set_create ();
input->name_ids = hb_set_create ();
input->drop_hints = false;
input->drop_layout = true;
input->desubroutinize = false;
@ -81,6 +82,7 @@ hb_subset_input_destroy (hb_subset_input_t *subset_input)
hb_set_destroy (subset_input->unicodes);
hb_set_destroy (subset_input->glyphs);
hb_set_destroy (subset_input->name_ids);
free (subset_input);
}
@ -109,6 +111,12 @@ hb_subset_input_glyph_set (hb_subset_input_t *subset_input)
return subset_input->glyphs;
}
HB_EXTERN hb_set_t *
hb_subset_input_nameid_set (hb_subset_input_t *subset_input)
{
return subset_input->name_ids;
}
HB_EXTERN void
hb_subset_input_set_drop_hints (hb_subset_input_t *subset_input,
hb_bool_t drop_hints)

View File

@ -40,6 +40,7 @@ struct hb_subset_input_t
hb_set_t *unicodes;
hb_set_t *glyphs;
hb_set_t *name_ids;
bool drop_hints : 1;
bool drop_layout : 1;
@ -49,7 +50,7 @@ struct hb_subset_input_t
*
* features
* lookups
* nameIDs
* name_ids
* ...
*/
};

View File

@ -205,12 +205,13 @@ hb_subset_plan_create (hb_face_t *face,
plan->drop_layout = input->drop_layout;
plan->desubroutinize = input->desubroutinize;
plan->retain_gids = input->retain_gids;
plan->unicodes = hb_set_create();
plan->unicodes = hb_set_create ();
plan->name_ids = hb_set_reference (input->name_ids);
plan->source = hb_face_reference (face);
plan->dest = hb_face_builder_create ();
plan->codepoint_to_glyph = hb_map_create();
plan->glyph_map = hb_map_create();
plan->reverse_glyph_map = hb_map_create();
plan->codepoint_to_glyph = hb_map_create ();
plan->glyph_map = hb_map_create ();
plan->reverse_glyph_map = hb_map_create ();
plan->_glyphset = _populate_gids_to_retain (face,
input->unicodes,
input->glyphs,
@ -239,6 +240,7 @@ hb_subset_plan_destroy (hb_subset_plan_t *plan)
if (!hb_object_destroy (plan)) return;
hb_set_destroy (plan->unicodes);
hb_set_destroy (plan->name_ids);
hb_face_destroy (plan->source);
hb_face_destroy (plan->dest);
hb_map_destroy (plan->codepoint_to_glyph);

View File

@ -47,6 +47,9 @@ struct hb_subset_plan_t
// For each cp that we'd like to retain maps to the corresponding gid.
hb_set_t *unicodes;
//name_ids we would like to retain
hb_set_t *name_ids;
// The glyph subset
hb_map_t *codepoint_to_glyph;

View File

@ -54,6 +54,9 @@ hb_subset_input_unicode_set (hb_subset_input_t *subset_input);
HB_EXTERN hb_set_t *
hb_subset_input_glyph_set (hb_subset_input_t *subset_input);
HB_EXTERN hb_set_t *
hb_subset_input_nameid_set (hb_subset_input_t *subset_input);
HB_EXTERN void
hb_subset_input_set_drop_hints (hb_subset_input_t *subset_input,
hb_bool_t drop_hints);

View File

@ -93,6 +93,7 @@ struct subset_consumer_t
hb_subset_input_set_drop_hints (input, subset_options.drop_hints);
hb_subset_input_set_retain_gids (input, subset_options.retain_gids);
hb_subset_input_set_desubroutinize (input, subset_options.desubroutinize);
hb_set_set (hb_subset_input_nameid_set (input), subset_options.name_ids);
hb_face_t *face = hb_font_get_face (font);

View File

@ -971,6 +971,49 @@ format_options_t::serialize_buffer_of_glyphs (hb_buffer_t *buffer,
g_string_append_c (gs, '\n');
}
static gboolean
parse_nameids (const char *name G_GNUC_UNUSED,
const char *arg,
gpointer data,
GError **error G_GNUC_UNUSED)
{
subset_options_t *subset_opts = (subset_options_t *) data;
hb_set_t *name_ids = hb_set_create ();
char *s = (char *) arg;
char *p;
while (s && *s)
{
while (*s && strchr ("<+>{},;&#\\xXuUnNiI\n\t\v\f\r ", *s))
s++;
if (!*s)
break;
errno = 0;
hb_codepoint_t u = strtoul (s, &p, 10);
if (errno || s == p)
{
hb_set_destroy (name_ids);
g_set_error (error, G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
"Failed parsing nameID values at: '%s'", s);
return false;
}
hb_set_add (name_ids, u);
s = p;
}
hb_set_t *prev = subset_opts->name_ids;
subset_opts->name_ids = hb_set_reference (name_ids);
hb_set_destroy (prev);
hb_set_destroy (name_ids);
return true;
}
void
subset_options_t::add_options (option_parser_t *parser)
{
@ -980,6 +1023,7 @@ subset_options_t::add_options (option_parser_t *parser)
{"no-hinting", 0, 0, G_OPTION_ARG_NONE, &this->drop_hints, "Whether to drop hints", nullptr},
{"retain-gids", 0, 0, G_OPTION_ARG_NONE, &this->retain_gids, "If set don't renumber glyph ids in the subset.", nullptr},
{"desubroutinize", 0, 0, G_OPTION_ARG_NONE, &this->desubroutinize, "Remove CFF/CFF2 use of subroutines", nullptr},
{"name-IDs", 0, 0, G_OPTION_ARG_CALLBACK, (gpointer) &parse_nameids, "Subset specified nameids", "list of int numbers"},
{nullptr}
};
@ -989,3 +1033,4 @@ subset_options_t::add_options (option_parser_t *parser)
"Options subsetting",
this);
}

View File

@ -677,16 +677,24 @@ struct subset_options_t : option_group_t
drop_hints = false;
retain_gids = false;
desubroutinize = false;
name_ids = hb_set_create ();
add_options (parser);
}
virtual ~subset_options_t ()
{
hb_set_destroy (name_ids);
}
void add_options (option_parser_t *parser);
hb_bool_t keep_layout;
hb_bool_t drop_hints;
hb_bool_t retain_gids;
hb_bool_t desubroutinize;
hb_set_t *name_ids;
};
/* fallback implementation for scalbn()/scalbnf() for pre-2013 MSVC */