add hb_bimap_t, subclass hb_inc_bimap_t replacing CFF::remap_t
This commit is contained in:
parent
0660175dc8
commit
094966959f
|
@ -44,6 +44,7 @@ HB_BASE_sources = \
|
||||||
hb-machinery.hh \
|
hb-machinery.hh \
|
||||||
hb-map.cc \
|
hb-map.cc \
|
||||||
hb-map.hh \
|
hb-map.hh \
|
||||||
|
hb-bimap.hh \
|
||||||
hb-meta.hh \
|
hb-meta.hh \
|
||||||
hb-mutex.hh \
|
hb-mutex.hh \
|
||||||
hb-null.hh \
|
hb-null.hh \
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
/*
|
||||||
|
* Copyright © 2019 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef HB_BIMAP_HH
|
||||||
|
#define HB_BIMAP_HH
|
||||||
|
|
||||||
|
#include "hb.hh"
|
||||||
|
|
||||||
|
/* Bi-directional map */
|
||||||
|
struct hb_bimap_t
|
||||||
|
{
|
||||||
|
hb_bimap_t () { init (); }
|
||||||
|
~hb_bimap_t () { fini (); }
|
||||||
|
|
||||||
|
void init ()
|
||||||
|
{
|
||||||
|
forw_map.init ();
|
||||||
|
back_map.init ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void fini ()
|
||||||
|
{
|
||||||
|
forw_map.fini ();
|
||||||
|
back_map.fini ();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* returns HB_MAP_VALUE_INVALID if unmapped */
|
||||||
|
hb_codepoint_t forward (hb_codepoint_t lhs) const { return forw_map[lhs]; }
|
||||||
|
hb_codepoint_t backward (hb_codepoint_t rhs) const { return back_map[rhs]; }
|
||||||
|
|
||||||
|
void set (hb_codepoint_t lhs, hb_codepoint_t rhs)
|
||||||
|
{
|
||||||
|
forw_map.set (lhs, rhs);
|
||||||
|
back_map.set (rhs, lhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create an identity map. */
|
||||||
|
bool identity (unsigned int size)
|
||||||
|
{
|
||||||
|
clear ();
|
||||||
|
for (hb_codepoint_t i = 0; i < size; i++) set (i, i);
|
||||||
|
return forw_map.successful && back_map.successful;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear ()
|
||||||
|
{
|
||||||
|
forw_map.clear ();
|
||||||
|
back_map.clear ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset ()
|
||||||
|
{
|
||||||
|
forw_map.reset ();
|
||||||
|
back_map.reset ();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int get_population () const { return forw_map.get_population (); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
hb_map_t forw_map;
|
||||||
|
hb_map_t back_map;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Inremental bimap: only lhs is given, rhs is incrementally assigned */
|
||||||
|
struct hb_inc_bimap_t : hb_bimap_t
|
||||||
|
{
|
||||||
|
/* Add a mapping from lhs to rhs with a unique value if lhs is unknown.
|
||||||
|
* Return the rhs value as the result.
|
||||||
|
*/
|
||||||
|
hb_codepoint_t add (hb_codepoint_t lhs)
|
||||||
|
{
|
||||||
|
hb_codepoint_t rhs = forw_map[lhs];
|
||||||
|
if (rhs == HB_MAP_VALUE_INVALID)
|
||||||
|
{
|
||||||
|
rhs = get_population ();
|
||||||
|
set (lhs, rhs);
|
||||||
|
}
|
||||||
|
return rhs;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has (hb_codepoint_t lhs) const { return forw_map.has (lhs); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
static int cmp_id (const void* a, const void* b)
|
||||||
|
{ return (int)*(const hb_codepoint_t *)a - (int)*(const hb_codepoint_t *)b; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
/* Optional: after finished adding all mappings in a random order,
|
||||||
|
* reassign rhs to lhs so that they are in the same order. */
|
||||||
|
void sort ()
|
||||||
|
{
|
||||||
|
hb_codepoint_t count = get_population ();
|
||||||
|
hb_vector_t <hb_codepoint_t> work;
|
||||||
|
work.resize (count);
|
||||||
|
|
||||||
|
for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
|
||||||
|
work[rhs] = back_map[rhs];
|
||||||
|
|
||||||
|
work.qsort (cmp_id);
|
||||||
|
|
||||||
|
for (hb_codepoint_t rhs = 0; rhs < count; rhs++)
|
||||||
|
set (work[rhs], rhs);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* HB_BIMAP_HH */
|
|
@ -27,6 +27,7 @@
|
||||||
#define HB_OT_CFF_COMMON_HH
|
#define HB_OT_CFF_COMMON_HH
|
||||||
|
|
||||||
#include "hb-open-type.hh"
|
#include "hb-open-type.hh"
|
||||||
|
#include "hb-bimap.hh"
|
||||||
#include "hb-ot-layout-common.hh"
|
#include "hb-ot-layout-common.hh"
|
||||||
#include "hb-cff-interp-dict-common.hh"
|
#include "hb-cff-interp-dict-common.hh"
|
||||||
#include "hb-subset-plan.hh"
|
#include "hb-subset-plan.hh"
|
||||||
|
@ -410,57 +411,6 @@ struct table_info_t
|
||||||
unsigned int offSize;
|
unsigned int offSize;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* used to remap font index or SID from fullset to subset.
|
|
||||||
* set to CFF_UNDEF_CODE if excluded from subset */
|
|
||||||
struct remap_t : hb_vector_t<hb_codepoint_t>
|
|
||||||
{
|
|
||||||
void init () { SUPER::init (); }
|
|
||||||
|
|
||||||
void fini () { SUPER::fini (); }
|
|
||||||
|
|
||||||
bool reset (unsigned int size)
|
|
||||||
{
|
|
||||||
if (unlikely (!SUPER::resize (size)))
|
|
||||||
return false;
|
|
||||||
for (unsigned int i = 0; i < length; i++)
|
|
||||||
(*this)[i] = CFF_UNDEF_CODE;
|
|
||||||
count = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool identity (unsigned int size)
|
|
||||||
{
|
|
||||||
if (unlikely (!SUPER::resize (size)))
|
|
||||||
return false;
|
|
||||||
unsigned int i;
|
|
||||||
for (i = 0; i < length; i++)
|
|
||||||
(*this)[i] = i;
|
|
||||||
count = i;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool excludes (hb_codepoint_t id) const
|
|
||||||
{ return (id < length) && ((*this)[id] == CFF_UNDEF_CODE); }
|
|
||||||
|
|
||||||
bool includes (hb_codepoint_t id) const
|
|
||||||
{ return !excludes (id); }
|
|
||||||
|
|
||||||
unsigned int add (unsigned int i)
|
|
||||||
{
|
|
||||||
if ((*this)[i] == CFF_UNDEF_CODE)
|
|
||||||
(*this)[i] = count++;
|
|
||||||
return (*this)[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
hb_codepoint_t get_count () const { return count; }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
hb_codepoint_t count;
|
|
||||||
|
|
||||||
private:
|
|
||||||
typedef hb_vector_t<hb_codepoint_t> SUPER;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename COUNT>
|
template <typename COUNT>
|
||||||
struct FDArray : CFFIndexOf<COUNT, FontDict>
|
struct FDArray : CFFIndexOf<COUNT, FontDict>
|
||||||
{
|
{
|
||||||
|
@ -504,7 +454,7 @@ struct FDArray : CFFIndexOf<COUNT, FontDict>
|
||||||
unsigned int offSize_,
|
unsigned int offSize_,
|
||||||
const hb_vector_t<DICTVAL> &fontDicts,
|
const hb_vector_t<DICTVAL> &fontDicts,
|
||||||
unsigned int fdCount,
|
unsigned int fdCount,
|
||||||
const remap_t &fdmap,
|
const hb_inc_bimap_t &fdmap,
|
||||||
OP_SERIALIZER& opszr,
|
OP_SERIALIZER& opszr,
|
||||||
const hb_vector_t<table_info_t> &privateInfos)
|
const hb_vector_t<table_info_t> &privateInfos)
|
||||||
{
|
{
|
||||||
|
@ -519,7 +469,7 @@ struct FDArray : CFFIndexOf<COUNT, FontDict>
|
||||||
unsigned int offset = 1;
|
unsigned int offset = 1;
|
||||||
unsigned int fid = 0;
|
unsigned int fid = 0;
|
||||||
for (unsigned i = 0; i < fontDicts.length; i++)
|
for (unsigned i = 0; i < fontDicts.length; i++)
|
||||||
if (fdmap.includes (i))
|
if (fdmap.has (i))
|
||||||
{
|
{
|
||||||
if (unlikely (fid >= fdCount)) return_trace (false);
|
if (unlikely (fid >= fdCount)) return_trace (false);
|
||||||
CFFIndexOf<COUNT, FontDict>::set_offset_at (fid++, offset);
|
CFFIndexOf<COUNT, FontDict>::set_offset_at (fid++, offset);
|
||||||
|
@ -529,10 +479,10 @@ struct FDArray : CFFIndexOf<COUNT, FontDict>
|
||||||
|
|
||||||
/* serialize font dicts */
|
/* serialize font dicts */
|
||||||
for (unsigned int i = 0; i < fontDicts.length; i++)
|
for (unsigned int i = 0; i < fontDicts.length; i++)
|
||||||
if (fdmap.includes (i))
|
if (fdmap.has (i))
|
||||||
{
|
{
|
||||||
FontDict *dict = c->start_embed<FontDict> ();
|
FontDict *dict = c->start_embed<FontDict> ();
|
||||||
if (unlikely (!dict->serialize (c, fontDicts[i], opszr, privateInfos[fdmap[i]])))
|
if (unlikely (!dict->serialize (c, fontDicts[i], opszr, privateInfos[fdmap.forward (i)])))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
}
|
}
|
||||||
return_trace (true);
|
return_trace (true);
|
||||||
|
@ -543,12 +493,12 @@ struct FDArray : CFFIndexOf<COUNT, FontDict>
|
||||||
static unsigned int calculate_serialized_size (unsigned int &offSize_ /* OUT */,
|
static unsigned int calculate_serialized_size (unsigned int &offSize_ /* OUT */,
|
||||||
const hb_vector_t<DICTVAL> &fontDicts,
|
const hb_vector_t<DICTVAL> &fontDicts,
|
||||||
unsigned int fdCount,
|
unsigned int fdCount,
|
||||||
const remap_t &fdmap,
|
const hb_inc_bimap_t &fdmap,
|
||||||
OP_SERIALIZER& opszr)
|
OP_SERIALIZER& opszr)
|
||||||
{
|
{
|
||||||
unsigned int dictsSize = 0;
|
unsigned int dictsSize = 0;
|
||||||
for (unsigned int i = 0; i < fontDicts.len; i++)
|
for (unsigned int i = 0; i < fontDicts.len; i++)
|
||||||
if (fdmap.includes (i))
|
if (fdmap.has (i))
|
||||||
dictsSize += FontDict::calculate_serialized_size (fontDicts[i], opszr);
|
dictsSize += FontDict::calculate_serialized_size (fontDicts[i], opszr);
|
||||||
|
|
||||||
offSize_ = calcOffSize (dictsSize);
|
offSize_ = calcOffSize (dictsSize);
|
||||||
|
|
|
@ -594,10 +594,10 @@ struct Charset
|
||||||
struct CFF1StringIndex : CFF1Index
|
struct CFF1StringIndex : CFF1Index
|
||||||
{
|
{
|
||||||
bool serialize (hb_serialize_context_t *c, const CFF1StringIndex &strings,
|
bool serialize (hb_serialize_context_t *c, const CFF1StringIndex &strings,
|
||||||
unsigned int offSize_, const remap_t &sidmap)
|
unsigned int offSize_, const hb_inc_bimap_t &sidmap)
|
||||||
{
|
{
|
||||||
TRACE_SERIALIZE (this);
|
TRACE_SERIALIZE (this);
|
||||||
if (unlikely ((strings.count == 0) || (sidmap.get_count () == 0)))
|
if (unlikely ((strings.count == 0) || (sidmap.get_population () == 0)))
|
||||||
{
|
{
|
||||||
if (unlikely (!c->extend_min (this->count)))
|
if (unlikely (!c->extend_min (this->count)))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
|
@ -607,11 +607,11 @@ struct CFF1StringIndex : CFF1Index
|
||||||
|
|
||||||
byte_str_array_t bytesArray;
|
byte_str_array_t bytesArray;
|
||||||
bytesArray.init ();
|
bytesArray.init ();
|
||||||
if (!bytesArray.resize (sidmap.get_count ()))
|
if (!bytesArray.resize (sidmap.get_population ()))
|
||||||
return_trace (false);
|
return_trace (false);
|
||||||
for (unsigned int i = 0; i < strings.count; i++)
|
for (unsigned int i = 0; i < strings.count; i++)
|
||||||
{
|
{
|
||||||
hb_codepoint_t j = sidmap[i];
|
hb_codepoint_t j = sidmap.forward (i);
|
||||||
if (j != CFF_UNDEF_CODE)
|
if (j != CFF_UNDEF_CODE)
|
||||||
bytesArray[j] = strings[i];
|
bytesArray[j] = strings[i];
|
||||||
}
|
}
|
||||||
|
@ -622,19 +622,19 @@ struct CFF1StringIndex : CFF1Index
|
||||||
}
|
}
|
||||||
|
|
||||||
/* in parallel to above */
|
/* in parallel to above */
|
||||||
unsigned int calculate_serialized_size (unsigned int &offSize_ /*OUT*/, const remap_t &sidmap) const
|
unsigned int calculate_serialized_size (unsigned int &offSize_ /*OUT*/, const hb_inc_bimap_t &sidmap) const
|
||||||
{
|
{
|
||||||
offSize_ = 0;
|
offSize_ = 0;
|
||||||
if ((count == 0) || (sidmap.get_count () == 0))
|
if ((count == 0) || (sidmap.get_population () == 0))
|
||||||
return count.static_size;
|
return count.static_size;
|
||||||
|
|
||||||
unsigned int dataSize = 0;
|
unsigned int dataSize = 0;
|
||||||
for (unsigned int i = 0; i < count; i++)
|
for (unsigned int i = 0; i < count; i++)
|
||||||
if (sidmap[i] != CFF_UNDEF_CODE)
|
if (sidmap.forward (i) != CFF_UNDEF_CODE)
|
||||||
dataSize += length_at (i);
|
dataSize += length_at (i);
|
||||||
|
|
||||||
offSize_ = calcOffSize(dataSize);
|
offSize_ = calcOffSize(dataSize);
|
||||||
return CFF1Index::calculate_serialized_size (offSize_, sidmap.get_count (), dataSize);
|
return CFF1Index::calculate_serialized_size (offSize_, sidmap.get_population (), dataSize);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan,
|
||||||
unsigned int &subset_fdselect_size /* OUT */,
|
unsigned int &subset_fdselect_size /* OUT */,
|
||||||
unsigned int &subset_fdselect_format /* OUT */,
|
unsigned int &subset_fdselect_format /* OUT */,
|
||||||
hb_vector_t<code_pair_t> &fdselect_ranges /* OUT */,
|
hb_vector_t<code_pair_t> &fdselect_ranges /* OUT */,
|
||||||
remap_t &fdmap /* OUT */)
|
hb_inc_bimap_t &fdmap /* OUT */)
|
||||||
{
|
{
|
||||||
subset_fd_count = 0;
|
subset_fd_count = 0;
|
||||||
subset_fdselect_size = 0;
|
subset_fdselect_size = 0;
|
||||||
|
@ -102,23 +102,19 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan,
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* create a fdmap */
|
/* create a fdmap */
|
||||||
if (!fdmap.reset (fdCount))
|
fdmap.reset ();
|
||||||
{
|
|
||||||
hb_set_destroy (set);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
hb_codepoint_t fd = CFF_UNDEF_CODE;
|
hb_codepoint_t fd = CFF_UNDEF_CODE;
|
||||||
while (set->next (&fd))
|
while (set->next (&fd))
|
||||||
fdmap.add (fd);
|
fdmap.add (fd);
|
||||||
hb_set_destroy (set);
|
hb_set_destroy (set);
|
||||||
if (unlikely (fdmap.get_count () != subset_fd_count))
|
if (unlikely (fdmap.get_population () != subset_fd_count))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* update each font dict index stored as "code" in fdselect_ranges */
|
/* update each font dict index stored as "code" in fdselect_ranges */
|
||||||
for (unsigned int i = 0; i < fdselect_ranges.length; i++)
|
for (unsigned int i = 0; i < fdselect_ranges.length; i++)
|
||||||
fdselect_ranges[i].code = fdmap[fdselect_ranges[i].code];
|
fdselect_ranges[i].code = fdmap.forward (fdselect_ranges[i].code);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* determine which FDSelect format is most compact */
|
/* determine which FDSelect format is most compact */
|
||||||
|
|
|
@ -541,39 +541,29 @@ struct subr_subset_param_t
|
||||||
bool drop_hints;
|
bool drop_hints;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct subr_remap_t : remap_t
|
struct subr_remap_t : hb_inc_bimap_t
|
||||||
{
|
{
|
||||||
void create (hb_set_t *closure)
|
void create (hb_set_t *closure)
|
||||||
{
|
{
|
||||||
/* create a remapping of subroutine numbers from old to new.
|
/* create a remapping of subroutine numbers from old to new.
|
||||||
* no optimization based on usage counts. fonttools doesn't appear doing that either.
|
* no optimization based on usage counts. fonttools doesn't appear doing that either.
|
||||||
*/
|
*/
|
||||||
reset (closure->get_max () + 1);
|
|
||||||
for (hb_codepoint_t old_num = 0; old_num < length; old_num++)
|
|
||||||
{
|
|
||||||
if (hb_set_has (closure, old_num))
|
|
||||||
add (old_num);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (get_count () < 1240)
|
hb_codepoint_t old_num = HB_SET_VALUE_INVALID;
|
||||||
|
while (hb_set_next (closure, &old_num))
|
||||||
|
add (old_num);
|
||||||
|
|
||||||
|
if (get_population () < 1240)
|
||||||
bias = 107;
|
bias = 107;
|
||||||
else if (get_count () < 33900)
|
else if (get_population () < 33900)
|
||||||
bias = 1131;
|
bias = 1131;
|
||||||
else
|
else
|
||||||
bias = 32768;
|
bias = 32768;
|
||||||
}
|
}
|
||||||
|
|
||||||
hb_codepoint_t operator[] (unsigned int old_num) const
|
|
||||||
{
|
|
||||||
if (old_num >= length)
|
|
||||||
return CFF_UNDEF_CODE;
|
|
||||||
else
|
|
||||||
return remap_t::operator[] (old_num);
|
|
||||||
}
|
|
||||||
|
|
||||||
int biased_num (unsigned int old_num) const
|
int biased_num (unsigned int old_num) const
|
||||||
{
|
{
|
||||||
hb_codepoint_t new_num = (*this)[old_num];
|
hb_codepoint_t new_num = forward (old_num);
|
||||||
return (int)new_num - bias;
|
return (int)new_num - bias;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -581,15 +571,15 @@ struct subr_remap_t : remap_t
|
||||||
int bias;
|
int bias;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct subr_remap_ts
|
struct subr_remaps_t
|
||||||
{
|
{
|
||||||
subr_remap_ts ()
|
subr_remaps_t ()
|
||||||
{
|
{
|
||||||
global_remap.init ();
|
global_remap.init ();
|
||||||
local_remaps.init ();
|
local_remaps.init ();
|
||||||
}
|
}
|
||||||
|
|
||||||
~subr_remap_ts () { fini (); }
|
~subr_remaps_t () { fini (); }
|
||||||
|
|
||||||
void init (unsigned int fdCount)
|
void init (unsigned int fdCount)
|
||||||
{
|
{
|
||||||
|
@ -765,13 +755,13 @@ struct subr_subsetter_t
|
||||||
|
|
||||||
bool encode_subrs (const parsed_cs_str_vec_t &subrs, const subr_remap_t& remap, unsigned int fd, str_buff_vec_t &buffArray) const
|
bool encode_subrs (const parsed_cs_str_vec_t &subrs, const subr_remap_t& remap, unsigned int fd, str_buff_vec_t &buffArray) const
|
||||||
{
|
{
|
||||||
unsigned int count = remap.get_count ();
|
unsigned int count = remap.get_population ();
|
||||||
|
|
||||||
if (unlikely (!buffArray.resize (count)))
|
if (unlikely (!buffArray.resize (count)))
|
||||||
return false;
|
return false;
|
||||||
for (unsigned int old_num = 0; old_num < subrs.length; old_num++)
|
for (unsigned int old_num = 0; old_num < subrs.length; old_num++)
|
||||||
{
|
{
|
||||||
hb_codepoint_t new_num = remap[old_num];
|
hb_codepoint_t new_num = remap.forward (old_num);
|
||||||
if (new_num != CFF_UNDEF_CODE)
|
if (new_num != CFF_UNDEF_CODE)
|
||||||
{
|
{
|
||||||
if (unlikely (!encode_str (subrs[old_num], fd, buffArray[new_num])))
|
if (unlikely (!encode_str (subrs[old_num], fd, buffArray[new_num])))
|
||||||
|
@ -1005,7 +995,7 @@ struct subr_subsetter_t
|
||||||
parsed_cs_str_vec_t parsed_global_subrs;
|
parsed_cs_str_vec_t parsed_global_subrs;
|
||||||
hb_vector_t<parsed_cs_str_vec_t> parsed_local_subrs;
|
hb_vector_t<parsed_cs_str_vec_t> parsed_local_subrs;
|
||||||
|
|
||||||
subr_remap_ts remaps;
|
subr_remaps_t remaps;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
typedef typename SUBRS::count_type subr_count_type;
|
typedef typename SUBRS::count_type subr_count_type;
|
||||||
|
@ -1021,7 +1011,7 @@ hb_plan_subset_cff_fdselect (const hb_subset_plan_t *plan,
|
||||||
unsigned int &subset_fdselect_size /* OUT */,
|
unsigned int &subset_fdselect_size /* OUT */,
|
||||||
unsigned int &subset_fdselect_format /* OUT */,
|
unsigned int &subset_fdselect_format /* OUT */,
|
||||||
hb_vector_t<CFF::code_pair_t> &fdselect_ranges /* OUT */,
|
hb_vector_t<CFF::code_pair_t> &fdselect_ranges /* OUT */,
|
||||||
CFF::remap_t &fdmap /* OUT */);
|
hb_inc_bimap_t &fdmap /* OUT */);
|
||||||
|
|
||||||
HB_INTERNAL bool
|
HB_INTERNAL bool
|
||||||
hb_serialize_cff_fdselect (hb_serialize_context_t *c,
|
hb_serialize_cff_fdselect (hb_serialize_context_t *c,
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "hb-open-type.hh"
|
#include "hb-open-type.hh"
|
||||||
#include "hb-ot-cff1-table.hh"
|
#include "hb-ot-cff1-table.hh"
|
||||||
#include "hb-set.h"
|
#include "hb-set.h"
|
||||||
|
#include "hb-bimap.hh"
|
||||||
#include "hb-subset-cff1.hh"
|
#include "hb-subset-cff1.hh"
|
||||||
#include "hb-subset-plan.hh"
|
#include "hb-subset-plan.hh"
|
||||||
#include "hb-subset-cff-common.hh"
|
#include "hb-subset-cff-common.hh"
|
||||||
|
@ -38,12 +39,12 @@
|
||||||
|
|
||||||
using namespace CFF;
|
using namespace CFF;
|
||||||
|
|
||||||
struct remap_sid_t : remap_t
|
struct remap_sid_t : hb_inc_bimap_t
|
||||||
{
|
{
|
||||||
unsigned int add (unsigned int sid)
|
unsigned int add (unsigned int sid)
|
||||||
{
|
{
|
||||||
if ((sid != CFF_UNDEF_SID) && !is_std_std (sid))
|
if ((sid != CFF_UNDEF_SID) && !is_std_std (sid))
|
||||||
return offset_sid (remap_t::add (unoffset_sid (sid)));
|
return offset_sid (hb_inc_bimap_t::add (unoffset_sid (sid)));
|
||||||
else
|
else
|
||||||
return sid;
|
return sid;
|
||||||
}
|
}
|
||||||
|
@ -53,7 +54,7 @@ struct remap_sid_t : remap_t
|
||||||
if (is_std_std (sid) || (sid == CFF_UNDEF_SID))
|
if (is_std_std (sid) || (sid == CFF_UNDEF_SID))
|
||||||
return sid;
|
return sid;
|
||||||
else
|
else
|
||||||
return offset_sid (remap_t::operator [] (unoffset_sid (sid)));
|
return offset_sid (forward (unoffset_sid (sid)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const unsigned int num_std_strings = 391;
|
static const unsigned int num_std_strings = 391;
|
||||||
|
@ -581,8 +582,7 @@ struct cff_subset_plan {
|
||||||
|
|
||||||
bool collect_sids_in_dicts (const OT::cff1::accelerator_subset_t &acc)
|
bool collect_sids_in_dicts (const OT::cff1::accelerator_subset_t &acc)
|
||||||
{
|
{
|
||||||
if (unlikely (!sidmap.reset (acc.stringIndex->count)))
|
sidmap.reset ();
|
||||||
return false;
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < name_dict_values_t::ValCount; i++)
|
for (unsigned int i = 0; i < name_dict_values_t::ValCount; i++)
|
||||||
{
|
{
|
||||||
|
@ -596,7 +596,7 @@ struct cff_subset_plan {
|
||||||
|
|
||||||
if (acc.fdArray != &Null(CFF1FDArray))
|
if (acc.fdArray != &Null(CFF1FDArray))
|
||||||
for (unsigned int i = 0; i < orig_fdcount; i++)
|
for (unsigned int i = 0; i < orig_fdcount; i++)
|
||||||
if (fdmap.includes (i))
|
if (fdmap.has (i))
|
||||||
(void)sidmap.add (acc.fontDicts[i].fontName);
|
(void)sidmap.add (acc.fontDicts[i].fontName);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -682,7 +682,7 @@ struct cff_subset_plan {
|
||||||
/* SIDs for name strings in dicts are added before glyph names so they fit in 16-bit int range */
|
/* SIDs for name strings in dicts are added before glyph names so they fit in 16-bit int range */
|
||||||
if (unlikely (!collect_sids_in_dicts (acc)))
|
if (unlikely (!collect_sids_in_dicts (acc)))
|
||||||
return false;
|
return false;
|
||||||
if (unlikely (sidmap.get_count () > 0x8000)) /* assumption: a dict won't reference that many strings */
|
if (unlikely (sidmap.get_population () > 0x8000)) /* assumption: a dict won't reference that many strings */
|
||||||
return false;
|
return false;
|
||||||
if (subset_charset)
|
if (subset_charset)
|
||||||
offsets.charsetInfo.size = plan_subset_charset (acc, plan);
|
offsets.charsetInfo.size = plan_subset_charset (acc, plan);
|
||||||
|
@ -739,7 +739,7 @@ struct cff_subset_plan {
|
||||||
{
|
{
|
||||||
subset_localsubrs[fd].init ();
|
subset_localsubrs[fd].init ();
|
||||||
offsets.localSubrsInfos[fd].init ();
|
offsets.localSubrsInfos[fd].init ();
|
||||||
if (fdmap.includes (fd))
|
if (fdmap.has (fd))
|
||||||
{
|
{
|
||||||
if (!subr_subsetter.encode_localsubrs (fd, subset_localsubrs[fd]))
|
if (!subr_subsetter.encode_localsubrs (fd, subset_localsubrs[fd]))
|
||||||
return false;
|
return false;
|
||||||
|
@ -790,7 +790,7 @@ struct cff_subset_plan {
|
||||||
cff1_font_dict_op_serializer_t fontSzr;
|
cff1_font_dict_op_serializer_t fontSzr;
|
||||||
unsigned int dictsSize = 0;
|
unsigned int dictsSize = 0;
|
||||||
for (unsigned int i = 0; i < acc.fontDicts.length; i++)
|
for (unsigned int i = 0; i < acc.fontDicts.length; i++)
|
||||||
if (fdmap.includes (i))
|
if (fdmap.has (i))
|
||||||
dictsSize += FontDict::calculate_serialized_size (acc.fontDicts[i], fontSzr);
|
dictsSize += FontDict::calculate_serialized_size (acc.fontDicts[i], fontSzr);
|
||||||
|
|
||||||
offsets.FDArrayInfo.offSize = calcOffSize (dictsSize);
|
offsets.FDArrayInfo.offSize = calcOffSize (dictsSize);
|
||||||
|
@ -813,7 +813,7 @@ struct cff_subset_plan {
|
||||||
offsets.privateDictInfo.offset = final_size;
|
offsets.privateDictInfo.offset = final_size;
|
||||||
for (unsigned int i = 0; i < orig_fdcount; i++)
|
for (unsigned int i = 0; i < orig_fdcount; i++)
|
||||||
{
|
{
|
||||||
if (fdmap.includes (i))
|
if (fdmap.has (i))
|
||||||
{
|
{
|
||||||
bool has_localsubrs = offsets.localSubrsInfos[i].size > 0;
|
bool has_localsubrs = offsets.localSubrsInfos[i].size > 0;
|
||||||
cff_private_dict_op_serializer_t privSzr (desubroutinize, plan->drop_hints);
|
cff_private_dict_op_serializer_t privSzr (desubroutinize, plan->drop_hints);
|
||||||
|
@ -857,7 +857,7 @@ struct cff_subset_plan {
|
||||||
|
|
||||||
/* font dict index remap table from fullset FDArray to subset FDArray.
|
/* font dict index remap table from fullset FDArray to subset FDArray.
|
||||||
* set to CFF_UNDEF_CODE if excluded from subset */
|
* set to CFF_UNDEF_CODE if excluded from subset */
|
||||||
remap_t fdmap;
|
hb_inc_bimap_t fdmap;
|
||||||
|
|
||||||
str_buff_vec_t subset_charstrings;
|
str_buff_vec_t subset_charstrings;
|
||||||
str_buff_vec_t subset_globalsubrs;
|
str_buff_vec_t subset_globalsubrs;
|
||||||
|
@ -1034,11 +1034,11 @@ static inline bool _write_cff1 (const cff_subset_plan &plan,
|
||||||
assert (plan.offsets.privateDictInfo.offset == (unsigned) (c.head - c.start));
|
assert (plan.offsets.privateDictInfo.offset == (unsigned) (c.head - c.start));
|
||||||
for (unsigned int i = 0; i < acc.privateDicts.length; i++)
|
for (unsigned int i = 0; i < acc.privateDicts.length; i++)
|
||||||
{
|
{
|
||||||
if (plan.fdmap.includes (i))
|
if (plan.fdmap.has (i))
|
||||||
{
|
{
|
||||||
PrivateDict *pd = c.start_embed<PrivateDict> ();
|
PrivateDict *pd = c.start_embed<PrivateDict> ();
|
||||||
if (unlikely (pd == nullptr)) return false;
|
if (unlikely (pd == nullptr)) return false;
|
||||||
unsigned int priv_size = plan.fontdicts_mod[plan.fdmap[i]].privateDictInfo.size;
|
unsigned int priv_size = plan.fontdicts_mod[plan.fdmap.forward (i)].privateDictInfo.size;
|
||||||
bool result;
|
bool result;
|
||||||
cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
|
cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
|
||||||
/* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
|
/* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
|
||||||
|
|
|
@ -330,18 +330,15 @@ struct cff2_subset_plan {
|
||||||
{
|
{
|
||||||
subset_localsubrs[fd].init ();
|
subset_localsubrs[fd].init ();
|
||||||
offsets.localSubrsInfos[fd].init ();
|
offsets.localSubrsInfos[fd].init ();
|
||||||
if (fdmap.includes (fd))
|
if (!subr_subsetter.encode_localsubrs (fd, subset_localsubrs[fd]))
|
||||||
{
|
return false;
|
||||||
if (!subr_subsetter.encode_localsubrs (fd, subset_localsubrs[fd]))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
unsigned int dataSize = subset_localsubrs[fd].total_size ();
|
unsigned int dataSize = subset_localsubrs[fd].total_size ();
|
||||||
if (dataSize > 0)
|
if (dataSize > 0)
|
||||||
{
|
{
|
||||||
offsets.localSubrsInfos[fd].offset = final_size;
|
offsets.localSubrsInfos[fd].offset = final_size;
|
||||||
offsets.localSubrsInfos[fd].offSize = calcOffSize (dataSize);
|
offsets.localSubrsInfos[fd].offSize = calcOffSize (dataSize);
|
||||||
offsets.localSubrsInfos[fd].size = CFF2Subrs::calculate_serialized_size (offsets.localSubrsInfos[fd].offSize, subset_localsubrs[fd].length, dataSize);
|
offsets.localSubrsInfos[fd].size = CFF2Subrs::calculate_serialized_size (offsets.localSubrsInfos[fd].offSize, subset_localsubrs[fd].length, dataSize);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -382,7 +379,7 @@ struct cff2_subset_plan {
|
||||||
cff_font_dict_op_serializer_t fontSzr;
|
cff_font_dict_op_serializer_t fontSzr;
|
||||||
unsigned int dictsSize = 0;
|
unsigned int dictsSize = 0;
|
||||||
for (unsigned int i = 0; i < acc.fontDicts.length; i++)
|
for (unsigned int i = 0; i < acc.fontDicts.length; i++)
|
||||||
if (fdmap.includes (i))
|
if (fdmap.has (i))
|
||||||
dictsSize += FontDict::calculate_serialized_size (acc.fontDicts[i], fontSzr);
|
dictsSize += FontDict::calculate_serialized_size (acc.fontDicts[i], fontSzr);
|
||||||
|
|
||||||
offsets.FDArrayInfo.offSize = calcOffSize (dictsSize);
|
offsets.FDArrayInfo.offSize = calcOffSize (dictsSize);
|
||||||
|
@ -401,7 +398,7 @@ struct cff2_subset_plan {
|
||||||
offsets.privateDictsOffset = final_size;
|
offsets.privateDictsOffset = final_size;
|
||||||
for (unsigned int i = 0; i < orig_fdcount; i++)
|
for (unsigned int i = 0; i < orig_fdcount; i++)
|
||||||
{
|
{
|
||||||
if (fdmap.includes (i))
|
if (fdmap.has (i))
|
||||||
{
|
{
|
||||||
bool has_localsubrs = offsets.localSubrsInfos[i].size > 0;
|
bool has_localsubrs = offsets.localSubrsInfos[i].size > 0;
|
||||||
cff_private_dict_op_serializer_t privSzr (desubroutinize, drop_hints);
|
cff_private_dict_op_serializer_t privSzr (desubroutinize, drop_hints);
|
||||||
|
@ -431,7 +428,7 @@ struct cff2_subset_plan {
|
||||||
unsigned int subset_fdselect_format;
|
unsigned int subset_fdselect_format;
|
||||||
hb_vector_t<code_pair_t> subset_fdselect_ranges;
|
hb_vector_t<code_pair_t> subset_fdselect_ranges;
|
||||||
|
|
||||||
remap_t fdmap;
|
hb_inc_bimap_t fdmap;
|
||||||
|
|
||||||
str_buff_vec_t subset_charstrings;
|
str_buff_vec_t subset_charstrings;
|
||||||
str_buff_vec_t subset_globalsubrs;
|
str_buff_vec_t subset_globalsubrs;
|
||||||
|
@ -541,11 +538,11 @@ static inline bool _write_cff2 (const cff2_subset_plan &plan,
|
||||||
assert (plan.offsets.privateDictsOffset == (unsigned) (c.head - c.start));
|
assert (plan.offsets.privateDictsOffset == (unsigned) (c.head - c.start));
|
||||||
for (unsigned int i = 0; i < acc.privateDicts.length; i++)
|
for (unsigned int i = 0; i < acc.privateDicts.length; i++)
|
||||||
{
|
{
|
||||||
if (plan.fdmap.includes (i))
|
if (plan.fdmap.has (i))
|
||||||
{
|
{
|
||||||
PrivateDict *pd = c.start_embed<PrivateDict> ();
|
PrivateDict *pd = c.start_embed<PrivateDict> ();
|
||||||
if (unlikely (pd == nullptr)) return false;
|
if (unlikely (pd == nullptr)) return false;
|
||||||
unsigned int priv_size = plan.privateDictInfos[plan.fdmap[i]].size;
|
unsigned int priv_size = plan.privateDictInfos[plan.fdmap.forward (i)].size;
|
||||||
bool result;
|
bool result;
|
||||||
cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
|
cff_private_dict_op_serializer_t privSzr (plan.desubroutinize, plan.drop_hints);
|
||||||
/* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
|
/* N.B. local subrs immediately follows its corresponding private dict. i.e., subr offset == private dict size */
|
||||||
|
|
Loading…
Reference in New Issue