Merge pull request #3067 from googlefonts/glyph_names
[subset] support option --glyph-names
This commit is contained in:
commit
4762fcb415
|
@ -257,6 +257,7 @@ HB_SUBSET_sources = \
|
||||||
hb-ot-cff1-table.cc \
|
hb-ot-cff1-table.cc \
|
||||||
hb-ot-cff2-table.cc \
|
hb-ot-cff2-table.cc \
|
||||||
hb-ot-color-colrv1-closure.hh \
|
hb-ot-color-colrv1-closure.hh \
|
||||||
|
hb-ot-post-table-v2subset.hh \
|
||||||
hb-static.cc \
|
hb-static.cc \
|
||||||
hb-subset-cff-common.cc \
|
hb-subset-cff-common.cc \
|
||||||
hb-subset-cff-common.hh \
|
hb-subset-cff-common.hh \
|
||||||
|
|
|
@ -0,0 +1,114 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2021 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.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HB_OT_POST_TABLE_V2SUBSET_HH
|
||||||
|
#define HB_OT_POST_TABLE_V2SUBSET_HH
|
||||||
|
|
||||||
|
#include "hb-open-type.hh"
|
||||||
|
#include "hb-ot-post-table.hh"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* post -- PostScript
|
||||||
|
* https://docs.microsoft.com/en-us/typography/opentype/spec/post
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace OT {
|
||||||
|
template<typename Iterator>
|
||||||
|
HB_INTERNAL bool postV2Tail::serialize (hb_serialize_context_t *c,
|
||||||
|
Iterator it,
|
||||||
|
const void* _post) const
|
||||||
|
{
|
||||||
|
TRACE_SERIALIZE (this);
|
||||||
|
auto *out = c->start_embed (this);
|
||||||
|
if (unlikely (!c->check_success (out))) return_trace (false);
|
||||||
|
if (!out->glyphNameIndex.serialize (c, + it
|
||||||
|
| hb_map (hb_second)))
|
||||||
|
return_trace (false);
|
||||||
|
|
||||||
|
hb_set_t copied_indices;
|
||||||
|
for (const auto& _ : + it )
|
||||||
|
{
|
||||||
|
unsigned glyph_id = _.first;
|
||||||
|
unsigned new_index = _.second;
|
||||||
|
|
||||||
|
if (new_index < 258) continue;
|
||||||
|
if (copied_indices.has (new_index)) continue;
|
||||||
|
copied_indices.add (new_index);
|
||||||
|
|
||||||
|
hb_bytes_t s = reinterpret_cast<const post::accelerator_t*> (_post)->find_glyph_name (glyph_id);
|
||||||
|
HBUINT8 *o = c->allocate_size<HBUINT8> (HBUINT8::static_size * (s.length + 1));
|
||||||
|
if (unlikely (!o)) return_trace (false);
|
||||||
|
if (!c->check_assign (o[0], s.length, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
|
||||||
|
memcpy (o+1, s.arrayZ, HBUINT8::static_size * s.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
return_trace (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
HB_INTERNAL bool postV2Tail::subset (hb_subset_context_t *c) const
|
||||||
|
{
|
||||||
|
TRACE_SUBSET (this);
|
||||||
|
|
||||||
|
const hb_map_t &reverse_glyph_map = *c->plan->reverse_glyph_map;
|
||||||
|
unsigned num_glyphs = c->plan->num_output_glyphs ();
|
||||||
|
hb_map_t old_new_index_map, old_gid_new_index_map;
|
||||||
|
unsigned i = 0;
|
||||||
|
|
||||||
|
for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++)
|
||||||
|
{
|
||||||
|
hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
|
||||||
|
unsigned old_index = glyphNameIndex[old_gid];
|
||||||
|
|
||||||
|
unsigned new_index;
|
||||||
|
if (old_index <= 257) new_index = old_index;
|
||||||
|
else if (old_new_index_map.has (old_index)) new_index = old_new_index_map.get (old_index);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
new_index = 258 + i;
|
||||||
|
old_new_index_map.set (old_index, new_index);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
old_gid_new_index_map.set (old_gid, new_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto index_iter =
|
||||||
|
+ hb_range (num_glyphs)
|
||||||
|
| hb_map (reverse_glyph_map)
|
||||||
|
| hb_map_retains_sorting ([&](hb_codepoint_t old_gid)
|
||||||
|
{
|
||||||
|
unsigned new_index = old_gid_new_index_map.get (old_gid);
|
||||||
|
return hb_pair_t<unsigned, unsigned> (old_gid, new_index);
|
||||||
|
})
|
||||||
|
;
|
||||||
|
|
||||||
|
post::accelerator_t _post;
|
||||||
|
_post.init (c->plan->source);
|
||||||
|
bool ret = serialize (c->serializer, index_iter, &_post);
|
||||||
|
_post.fini ();
|
||||||
|
return_trace (ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
} /* namespace OT */
|
||||||
|
#endif /* HB_OT_POST_TABLE_V2SUBSET_HH */
|
|
@ -55,6 +55,13 @@ struct postV2Tail
|
||||||
return_trace (glyphNameIndex.sanitize (c));
|
return_trace (glyphNameIndex.sanitize (c));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename Iterator>
|
||||||
|
bool serialize (hb_serialize_context_t *c,
|
||||||
|
Iterator it,
|
||||||
|
const void* _post) const;
|
||||||
|
|
||||||
|
bool subset (hb_subset_context_t *c) const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Array16Of<HBUINT16> glyphNameIndex; /* This is not an offset, but is the
|
Array16Of<HBUINT16> glyphNameIndex; /* This is not an offset, but is the
|
||||||
* ordinal number of the glyph in 'post'
|
* ordinal number of the glyph in 'post'
|
||||||
|
@ -71,13 +78,18 @@ struct post
|
||||||
{
|
{
|
||||||
static constexpr hb_tag_t tableTag = HB_OT_TAG_post;
|
static constexpr hb_tag_t tableTag = HB_OT_TAG_post;
|
||||||
|
|
||||||
void serialize (hb_serialize_context_t *c) const
|
bool serialize (hb_serialize_context_t *c, bool glyph_names) const
|
||||||
{
|
{
|
||||||
|
TRACE_SERIALIZE (this);
|
||||||
post *post_prime = c->allocate_min<post> ();
|
post *post_prime = c->allocate_min<post> ();
|
||||||
if (unlikely (!post_prime)) return;
|
if (unlikely (!post_prime)) return_trace (false);
|
||||||
|
|
||||||
memcpy (post_prime, this, post::min_size);
|
memcpy (post_prime, this, post::min_size);
|
||||||
post_prime->version.major = 3; // Version 3 does not have any glyph names.
|
if (!glyph_names)
|
||||||
|
return_trace (c->check_assign (post_prime->version.major, 3,
|
||||||
|
HB_SERIALIZE_ERROR_INT_OVERFLOW)); // Version 3 does not have any glyph names.
|
||||||
|
|
||||||
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool subset (hb_subset_context_t *c) const
|
bool subset (hb_subset_context_t *c) const
|
||||||
|
@ -86,13 +98,18 @@ struct post
|
||||||
post *post_prime = c->serializer->start_embed<post> ();
|
post *post_prime = c->serializer->start_embed<post> ();
|
||||||
if (unlikely (!post_prime)) return_trace (false);
|
if (unlikely (!post_prime)) return_trace (false);
|
||||||
|
|
||||||
serialize (c->serializer);
|
if (!serialize (c->serializer, c->plan->glyph_names))
|
||||||
|
return_trace (false);
|
||||||
|
|
||||||
|
if (c->plan->glyph_names && version.major == 2)
|
||||||
|
return_trace (v2X.subset (c));
|
||||||
|
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct accelerator_t
|
struct accelerator_t
|
||||||
{
|
{
|
||||||
|
friend struct postV2Tail;
|
||||||
void init (hb_face_t *face)
|
void init (hb_face_t *face)
|
||||||
{
|
{
|
||||||
index_to_offset.init ();
|
index_to_offset.init ();
|
||||||
|
|
|
@ -60,6 +60,7 @@ hb_subset_input_create_or_fail (void)
|
||||||
input->name_legacy = false;
|
input->name_legacy = false;
|
||||||
input->overlaps_flag = false;
|
input->overlaps_flag = false;
|
||||||
input->notdef_outline = false;
|
input->notdef_outline = false;
|
||||||
|
input->glyph_names = false;
|
||||||
input->no_prune_unicode_ranges = false;
|
input->no_prune_unicode_ranges = false;
|
||||||
input->retain_all_layout_features = false;
|
input->retain_all_layout_features = false;
|
||||||
input->passthrough_unrecognized = false;
|
input->passthrough_unrecognized = false;
|
||||||
|
@ -391,6 +392,8 @@ hb_subset_input_get_flag (hb_subset_input_t *input,
|
||||||
return input->passthrough_unrecognized;
|
return input->passthrough_unrecognized;
|
||||||
case HB_SUBSET_FLAG_NOTDEF_OUTLINE:
|
case HB_SUBSET_FLAG_NOTDEF_OUTLINE:
|
||||||
return input->notdef_outline;
|
return input->notdef_outline;
|
||||||
|
case HB_SUBSET_FLAG_GLYPH_NAMES:
|
||||||
|
return input->glyph_names;
|
||||||
case HB_SUBSET_FLAG_NO_PRUNE_UNICODE_RANGES:
|
case HB_SUBSET_FLAG_NO_PRUNE_UNICODE_RANGES:
|
||||||
return input->no_prune_unicode_ranges;
|
return input->no_prune_unicode_ranges;
|
||||||
case HB_SUBSET_FLAG_RETAIN_ALL_FEATURES:
|
case HB_SUBSET_FLAG_RETAIN_ALL_FEATURES:
|
||||||
|
@ -438,6 +441,9 @@ hb_subset_input_set_flag (hb_subset_input_t *input,
|
||||||
case HB_SUBSET_FLAG_NOTDEF_OUTLINE:
|
case HB_SUBSET_FLAG_NOTDEF_OUTLINE:
|
||||||
input->notdef_outline = value;
|
input->notdef_outline = value;
|
||||||
break;
|
break;
|
||||||
|
case HB_SUBSET_FLAG_GLYPH_NAMES:
|
||||||
|
input->glyph_names = value;
|
||||||
|
break;
|
||||||
case HB_SUBSET_FLAG_NO_PRUNE_UNICODE_RANGES:
|
case HB_SUBSET_FLAG_NO_PRUNE_UNICODE_RANGES:
|
||||||
input->no_prune_unicode_ranges = value;
|
input->no_prune_unicode_ranges = value;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -53,6 +53,7 @@ struct hb_subset_input_t
|
||||||
hb_bool_t name_legacy;
|
hb_bool_t name_legacy;
|
||||||
hb_bool_t overlaps_flag;
|
hb_bool_t overlaps_flag;
|
||||||
hb_bool_t notdef_outline;
|
hb_bool_t notdef_outline;
|
||||||
|
hb_bool_t glyph_names;
|
||||||
hb_bool_t no_prune_unicode_ranges;
|
hb_bool_t no_prune_unicode_ranges;
|
||||||
hb_bool_t retain_all_layout_features;
|
hb_bool_t retain_all_layout_features;
|
||||||
hb_bool_t passthrough_unrecognized;
|
hb_bool_t passthrough_unrecognized;
|
||||||
|
|
|
@ -429,6 +429,7 @@ hb_subset_plan_create (hb_face_t *face,
|
||||||
plan->name_legacy = input->name_legacy;
|
plan->name_legacy = input->name_legacy;
|
||||||
plan->overlaps_flag = input->overlaps_flag;
|
plan->overlaps_flag = input->overlaps_flag;
|
||||||
plan->notdef_outline = input->notdef_outline;
|
plan->notdef_outline = input->notdef_outline;
|
||||||
|
plan->glyph_names = input->glyph_names;
|
||||||
plan->prune_unicode_ranges = !input->no_prune_unicode_ranges;
|
plan->prune_unicode_ranges = !input->no_prune_unicode_ranges;
|
||||||
plan->retain_all_layout_features = input->retain_all_layout_features;
|
plan->retain_all_layout_features = input->retain_all_layout_features;
|
||||||
plan->passthrough_unrecognized = input->passthrough_unrecognized;
|
plan->passthrough_unrecognized = input->passthrough_unrecognized;
|
||||||
|
|
|
@ -46,6 +46,7 @@ struct hb_subset_plan_t
|
||||||
bool name_legacy : 1;
|
bool name_legacy : 1;
|
||||||
bool overlaps_flag : 1;
|
bool overlaps_flag : 1;
|
||||||
bool notdef_outline : 1;
|
bool notdef_outline : 1;
|
||||||
|
bool glyph_names : 1;
|
||||||
bool prune_unicode_ranges : 1;
|
bool prune_unicode_ranges : 1;
|
||||||
bool retain_all_layout_features : 1;
|
bool retain_all_layout_features : 1;
|
||||||
bool passthrough_unrecognized : 1;
|
bool passthrough_unrecognized : 1;
|
||||||
|
|
|
@ -42,6 +42,7 @@
|
||||||
#include "hb-ot-color-cpal-table.hh"
|
#include "hb-ot-color-cpal-table.hh"
|
||||||
#include "hb-ot-os2-table.hh"
|
#include "hb-ot-os2-table.hh"
|
||||||
#include "hb-ot-post-table.hh"
|
#include "hb-ot-post-table.hh"
|
||||||
|
#include "hb-ot-post-table-v2subset.hh"
|
||||||
#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-vorg-table.hh"
|
#include "hb-ot-vorg-table.hh"
|
||||||
|
|
|
@ -59,6 +59,8 @@ typedef struct hb_subset_input_t hb_subset_input_t;
|
||||||
* Defaults to false.
|
* Defaults to false.
|
||||||
* @HB_SUBSET_FLAG_NOTDEF_OUTLINE: If set the notdef glyph outline will be
|
* @HB_SUBSET_FLAG_NOTDEF_OUTLINE: If set the notdef glyph outline will be
|
||||||
* retained in the final subset. Defaults to false.
|
* retained in the final subset. Defaults to false.
|
||||||
|
* @HB_SUBSET_FLAG_GLYPH_NAMES: If set the PS glyph names will be retained
|
||||||
|
* in the final subset. Defaults to false.
|
||||||
* @HB_SUBSET_FLAG_NO_PRUNE_UNICODE_RANGES: If set then the unicode ranges in
|
* @HB_SUBSET_FLAG_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_FLAG_RETAIN_ALL_FEATURES: If set all layout features will be
|
* @HB_SUBSET_FLAG_RETAIN_ALL_FEATURES: If set all layout features will be
|
||||||
|
@ -79,6 +81,7 @@ typedef enum
|
||||||
HB_SUBSET_FLAG_SET_OVERLAPS_FLAG,
|
HB_SUBSET_FLAG_SET_OVERLAPS_FLAG,
|
||||||
HB_SUBSET_FLAG_PASSTHROUGH_UNRECOGNIZED,
|
HB_SUBSET_FLAG_PASSTHROUGH_UNRECOGNIZED,
|
||||||
HB_SUBSET_FLAG_NOTDEF_OUTLINE,
|
HB_SUBSET_FLAG_NOTDEF_OUTLINE,
|
||||||
|
HB_SUBSET_FLAG_GLYPH_NAMES,
|
||||||
HB_SUBSET_FLAG_NO_PRUNE_UNICODE_RANGES,
|
HB_SUBSET_FLAG_NO_PRUNE_UNICODE_RANGES,
|
||||||
HB_SUBSET_FLAG_RETAIN_ALL_FEATURES,
|
HB_SUBSET_FLAG_RETAIN_ALL_FEATURES,
|
||||||
} hb_subset_flag_t;
|
} hb_subset_flag_t;
|
||||||
|
|
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.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1 @@
|
||||||
|
--glyph-names
|
|
@ -16,6 +16,7 @@ gids.txt
|
||||||
layout-features.txt
|
layout-features.txt
|
||||||
keep-all-layout-features.txt
|
keep-all-layout-features.txt
|
||||||
no-prune-unicode-ranges.txt
|
no-prune-unicode-ranges.txt
|
||||||
|
glyph-names.txt
|
||||||
|
|
||||||
SUBSETS:
|
SUBSETS:
|
||||||
abc
|
abc
|
||||||
|
|
|
@ -312,6 +312,7 @@ subset_options_t::add_options (option_parser_t *parser)
|
||||||
"Set the overlaps flag on each glyph.", nullptr},
|
"Set the overlaps flag on each glyph.", nullptr},
|
||||||
{"notdef-outline", 0, 0, G_OPTION_ARG_NONE, &this->input->notdef_outline, "Keep the outline of \'.notdef\' glyph", nullptr},
|
{"notdef-outline", 0, 0, G_OPTION_ARG_NONE, &this->input->notdef_outline, "Keep the outline of \'.notdef\' glyph", nullptr},
|
||||||
{"no-prune-unicode-ranges", 0, 0, G_OPTION_ARG_NONE, &this->input->no_prune_unicode_ranges, "Don't change the 'OS/2 ulUnicodeRange*' bits.", nullptr},
|
{"no-prune-unicode-ranges", 0, 0, G_OPTION_ARG_NONE, &this->input->no_prune_unicode_ranges, "Don't change the 'OS/2 ulUnicodeRange*' bits.", nullptr},
|
||||||
|
{"glyph-names", 0, 0, G_OPTION_ARG_NONE, &this->input->glyph_names, "Keep PS glyph names in TT-flavored fonts. ", nullptr},
|
||||||
{nullptr}
|
{nullptr}
|
||||||
};
|
};
|
||||||
parser->add_group (entries,
|
parser->add_group (entries,
|
||||||
|
|
Loading…
Reference in New Issue