summaryrefslogtreecommitdiff
path: root/src/hb-ot-cmap-table.hh
diff options
context:
space:
mode:
authorGarret Rieger <grieger@google.com>2018-05-02 17:11:18 -0700
committerGarret Rieger <grieger@google.com>2018-05-04 11:20:03 -0700
commit4195a52b041af749046b716dcac7d6560ae37611 (patch)
treed2bfcfc0f4bb7650a6f16dbed8c1a2f66c0c35ce /src/hb-ot-cmap-table.hh
parentcfa592d31ce2fd1ec2765a69ab31bf80161479dd (diff)
[subset] WIP implementation of serialize for cmap format 4.
Diffstat (limited to 'src/hb-ot-cmap-table.hh')
-rw-r--r--src/hb-ot-cmap-table.hh39
1 files changed, 38 insertions, 1 deletions
diff --git a/src/hb-ot-cmap-table.hh b/src/hb-ot-cmap-table.hh
index 84ad1c7e..115f3663 100644
--- a/src/hb-ot-cmap-table.hh
+++ b/src/hb-ot-cmap-table.hh
@@ -80,7 +80,44 @@ struct CmapSubtableFormat4
const hb_subset_plan_t *plan,
const hb_vector_t<segment_plan> &segments)
{
- // TODO
+ TRACE_SERIALIZE (this);
+
+ if (unlikely (!c->extend_min (*this))) return_trace (false);
+
+ this->format.set (4);
+ this->length.set (get_sub_table_size (segments));
+
+ // 2 * segCount
+ this->segCountX2.set (segments.len * 2);
+ // 2 * (2**floor(log2(segCount)))
+ this->searchRangeZ.set (2 * (1 << (int) (log (segments.len) / log (2.0))));
+ // log2(searchRange/2)
+ this->entrySelectorZ.set (log ((double) this->searchRangeZ) / log (2.0));
+ // 2 x segCount - searchRange
+ this->rangeShiftZ.set (2 * segments.len - this->searchRangeZ);
+
+ HBUINT16 *end_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len);
+ c->allocate_size<HBUINT16> (HBUINT16::static_size); // 2 bytes of padding.
+ HBUINT16 *start_count = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len);
+ HBINT16 *id_delta = c->allocate_size<HBINT16> (HBUINT16::static_size * segments.len);
+ HBUINT16 *id_range_offset = c->allocate_size<HBUINT16> (HBUINT16::static_size * segments.len);
+
+ for (unsigned int i = 0; i < segments.len; i++)
+ {
+ end_count[i].set (segments[i].end_code);
+ start_count[i].set (segments[i].start_code);
+ if (segments[i].use_delta)
+ {
+ hb_codepoint_t start_gid;
+ if (unlikely (!hb_subset_plan_new_gid_for_codepoint (plan, segments[i].start_code, &start_gid)))
+ return false;
+ id_delta[i].set (start_gid - segments[i].start_code);
+ } else {
+ // TODO: fill out glyphIdArray and id_range_offset.
+ }
+ }
+
+ // TODO: glyphdIdArray
}
static inline size_t get_sub_table_size (const hb_vector_t<segment_plan> &segments)