[subset] WIP cmap format 4 subsetting.
This commit is contained in:
parent
0053d13283
commit
295d67ea7d
|
@ -69,6 +69,48 @@ struct CmapSubtableFormat0
|
||||||
|
|
||||||
struct CmapSubtableFormat4
|
struct CmapSubtableFormat4
|
||||||
{
|
{
|
||||||
|
struct segment_plan
|
||||||
|
{
|
||||||
|
HBUINT16 start_code;
|
||||||
|
HBUINT16 end_code;
|
||||||
|
bool use_delta;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool serialize (hb_serialize_context_t *c,
|
||||||
|
const hb_subset_plan_t *plan,
|
||||||
|
const hb_vector_t<segment_plan> &segments)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline size_t get_sub_table_size (const hb_vector_t<segment_plan> &segments)
|
||||||
|
{
|
||||||
|
size_t segment_size = 0;
|
||||||
|
for (unsigned int i = 0; i < segments.len; i++)
|
||||||
|
{
|
||||||
|
// Parallel array entries
|
||||||
|
segment_size +=
|
||||||
|
2 // end count
|
||||||
|
+ 2 // start count
|
||||||
|
+ 2 // delta
|
||||||
|
+ 2; // range offset
|
||||||
|
|
||||||
|
if (!segments[i].use_delta)
|
||||||
|
// Add bytes for the glyph index array entries for this segment.
|
||||||
|
segment_size += (segments[i].end_code - segments[i].start_code + 1) * 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return min_size
|
||||||
|
+ 2 // Padding
|
||||||
|
+ segment_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline bool create_sub_table_plan (const hb_subset_plan_t *plan,
|
||||||
|
hb_vector_t<segment_plan> *segments)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
struct accelerator_t
|
struct accelerator_t
|
||||||
{
|
{
|
||||||
inline void init (const CmapSubtableFormat4 *subtable)
|
inline void init (const CmapSubtableFormat4 *subtable)
|
||||||
|
@ -175,6 +217,8 @@ struct CmapSubtableFormat4
|
||||||
return_trace (16 + 4 * (unsigned int) segCountX2 <= length);
|
return_trace (16 + 4 * (unsigned int) segCountX2 <= length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
HBUINT16 format; /* Format number is set to 4. */
|
HBUINT16 format; /* Format number is set to 4. */
|
||||||
HBUINT16 length; /* This is the length in bytes of the
|
HBUINT16 length; /* This is the length in bytes of the
|
||||||
|
@ -597,24 +641,29 @@ struct cmap
|
||||||
struct subset_plan {
|
struct subset_plan {
|
||||||
subset_plan(void)
|
subset_plan(void)
|
||||||
{
|
{
|
||||||
groups.init();
|
format4_segments.init();
|
||||||
|
format12_groups.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
~subset_plan(void)
|
~subset_plan(void)
|
||||||
{
|
{
|
||||||
groups.fini();
|
format4_segments.fini();
|
||||||
|
format12_groups.fini();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t final_size() const
|
inline size_t final_size() const
|
||||||
{
|
{
|
||||||
return
|
return
|
||||||
4 // header
|
4 // header
|
||||||
+ 8 // 1 EncodingRecord
|
+ 8 * 2 // 2 EncodingRecord
|
||||||
+ CmapSubtableFormat12::get_sub_table_size (this->groups);
|
+ CmapSubtableFormat4::get_sub_table_size (this->format4_segments);
|
||||||
|
+ CmapSubtableFormat12::get_sub_table_size (this->format12_groups);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Format 4
|
||||||
|
hb_vector_t<CmapSubtableFormat4::segment_plan> format4_segments;
|
||||||
// Format 12
|
// Format 12
|
||||||
hb_vector_t<CmapSubtableLongGroup> groups;
|
hb_vector_t<CmapSubtableLongGroup> format12_groups;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool sanitize (hb_sanitize_context_t *c) const
|
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||||
|
@ -628,10 +677,14 @@ struct cmap
|
||||||
inline bool _create_plan (const hb_subset_plan_t *plan,
|
inline bool _create_plan (const hb_subset_plan_t *plan,
|
||||||
subset_plan *cmap_plan) const
|
subset_plan *cmap_plan) const
|
||||||
{
|
{
|
||||||
return CmapSubtableFormat12::create_sub_table_plan (plan, &cmap_plan->groups);
|
if (unlikely( !CmapSubtableFormat4::create_sub_table_plan (plan, &cmap_plan->format4_segments)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return CmapSubtableFormat12::create_sub_table_plan (plan, &cmap_plan->format12_groups);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool _subset (const subset_plan &cmap_subset_plan,
|
inline bool _subset (const hb_subset_plan_t *plan,
|
||||||
|
const subset_plan &cmap_subset_plan,
|
||||||
size_t dest_sz,
|
size_t dest_sz,
|
||||||
void *dest) const
|
void *dest) const
|
||||||
{
|
{
|
||||||
|
@ -645,18 +698,37 @@ struct cmap
|
||||||
|
|
||||||
cmap->version.set (0);
|
cmap->version.set (0);
|
||||||
|
|
||||||
if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 1))) return false;
|
if (unlikely (!cmap->encodingRecord.serialize (&c, /* numTables */ 2))) return false;
|
||||||
|
|
||||||
EncodingRecord &rec = cmap->encodingRecord[0];
|
// TODO(grieger): Convert the below to a for loop
|
||||||
rec.platformID.set (3); // Windows
|
|
||||||
rec.encodingID.set (10); // Unicode UCS-4
|
// Format 4 Encoding Record
|
||||||
|
EncodingRecord &format4_rec = cmap->encodingRecord[0];
|
||||||
|
format4_rec.platformID.set (3); // Windows
|
||||||
|
format4_rec.encodingID.set (1); // Unicode BMP
|
||||||
|
|
||||||
|
// Format 12 Encoding Record
|
||||||
|
EncodingRecord &format12_rec = cmap->encodingRecord[1];
|
||||||
|
format12_rec.platformID.set (3); // Windows
|
||||||
|
format12_rec.encodingID.set (10); // Unicode UCS-4
|
||||||
|
|
||||||
|
// Write out format 4 sub table.
|
||||||
|
{
|
||||||
|
CmapSubtable &subtable = format4_rec.subtable.serialize (&c, cmap);
|
||||||
|
subtable.u.format.set (4);
|
||||||
|
|
||||||
|
CmapSubtableFormat4 &format4 = subtable.u.format4;
|
||||||
|
if (unlikely (!format4.serialize (&c, plan, cmap_subset_plan.format4_segments))) return false;
|
||||||
|
}
|
||||||
|
|
||||||
// Write out format 12 sub table.
|
// Write out format 12 sub table.
|
||||||
CmapSubtable &subtable = rec.subtable.serialize (&c, cmap);
|
{
|
||||||
subtable.u.format.set (12);
|
CmapSubtable &subtable = format12_rec.subtable.serialize (&c, cmap);
|
||||||
|
subtable.u.format.set (12);
|
||||||
|
|
||||||
CmapSubtableFormat12 &format12 = subtable.u.format12;
|
CmapSubtableFormat12 &format12 = subtable.u.format12;
|
||||||
if (unlikely (!format12.serialize (&c, cmap_subset_plan.groups))) return false;
|
if (unlikely (!format12.serialize (&c, cmap_subset_plan.format12_groups))) return false;
|
||||||
|
}
|
||||||
|
|
||||||
c.end_serialize ();
|
c.end_serialize ();
|
||||||
|
|
||||||
|
@ -681,7 +753,7 @@ struct cmap
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely (!_subset (cmap_subset_plan, dest_sz, dest)))
|
if (unlikely (!_subset (plan, cmap_subset_plan, dest_sz, dest)))
|
||||||
{
|
{
|
||||||
DEBUG_MSG(SUBSET, nullptr, "Failed to perform subsetting of cmap.");
|
DEBUG_MSG(SUBSET, nullptr, "Failed to perform subsetting of cmap.");
|
||||||
free (dest);
|
free (dest);
|
||||||
|
|
Loading…
Reference in New Issue