[subset] further optimize cmap4 packing.

This commit is contained in:
Garret Rieger 2021-11-26 16:18:42 -08:00 committed by Behdad Esfahbod
parent 599143824c
commit 95329081c2
32 changed files with 36 additions and 12 deletions

View File

@ -99,23 +99,26 @@ struct CmapSubtableFormat4
hb_requires (hb_is_iterator (Iterator))> hb_requires (hb_is_iterator (Iterator))>
void to_ranges (Iterator it, Writer& range_writer) void to_ranges (Iterator it, Writer& range_writer)
{ {
hb_codepoint_t start_cp, run_start_cp, end_cp, last_gid; hb_codepoint_t start_cp, prev_run_start_cp, run_start_cp, end_cp, last_gid;
int run_length, delta; int run_length, delta, prev_delta;
enum { enum {
FIRST_RANGE, FIRST_SUB_RANGE,
FOLLOWING_RANGE, FOLLOWING_SUB_RANGE,
} mode; } mode;
while (it) { while (it) {
// Start a new range // Start a new range
start_cp = (*it).first; start_cp = (*it).first;
prev_run_start_cp = (*it).first;
run_start_cp = (*it).first; run_start_cp = (*it).first;
end_cp = (*it).first; end_cp = (*it).first;
last_gid = (*it).second; last_gid = (*it).second;
run_length = 1; run_length = 1;
prev_delta = 0;
delta = (*it).second - (*it).first; delta = (*it).second - (*it).first;
mode = FIRST_RANGE; mode = FIRST_SUB_RANGE;
it++; it++;
while (it) { while (it) {
@ -137,17 +140,26 @@ struct CmapSubtableFormat4
} }
// A new run is starting, decide if we want to commit the current run. // A new run is starting, decide if we want to commit the current run.
int split_cost = (mode == FIRST_RANGE) ? 8 : 16; int split_cost = (mode == FIRST_SUB_RANGE) ? 8 : 16;
int run_cost = run_length * 2; int run_cost = run_length * 2;
if (run_cost >= split_cost) { if (run_cost >= split_cost) {
commit_current_range(start_cp, run_start_cp, end_cp, delta, split_cost, range_writer); commit_current_range(start_cp,
mode = FOLLOWING_RANGE; prev_run_start_cp,
run_start_cp,
end_cp,
delta,
prev_delta,
split_cost,
range_writer);
start_cp = next_cp; start_cp = next_cp;
} }
// Start the new run // Start the new run
mode = FOLLOWING_SUB_RANGE;
prev_run_start_cp = run_start_cp;
run_start_cp = next_cp; run_start_cp = next_cp;
end_cp = next_cp; end_cp = next_cp;
prev_delta = delta;
delta = next_gid - run_start_cp; delta = next_gid - run_start_cp;
run_length = 1; run_length = 1;
last_gid = next_gid; last_gid = next_gid;
@ -155,7 +167,14 @@ struct CmapSubtableFormat4
} }
// Finalize range // Finalize range
commit_current_range (start_cp, run_start_cp, end_cp, delta, 8, range_writer); commit_current_range (start_cp,
prev_run_start_cp,
run_start_cp,
end_cp,
delta,
prev_delta,
8,
range_writer);
} }
if (likely (end_cp != 0xFFFF)) { if (likely (end_cp != 0xFFFF)) {
@ -168,9 +187,11 @@ struct CmapSubtableFormat4
*/ */
template<typename Writer> template<typename Writer>
void commit_current_range (hb_codepoint_t start, void commit_current_range (hb_codepoint_t start,
hb_codepoint_t prev_run_start,
hb_codepoint_t run_start, hb_codepoint_t run_start,
hb_codepoint_t end, hb_codepoint_t end,
int run_delta, int run_delta,
int previous_run_delta,
int split_cost, int split_cost,
Writer& range_writer) { Writer& range_writer) {
bool should_split = false; bool should_split = false;
@ -181,8 +202,12 @@ struct CmapSubtableFormat4
} }
} }
// TODO(grieger): handle case where delta is legitimately 0, mark range offset array instead?
if (should_split) { if (should_split) {
range_writer (start, run_start - 1, 0); if (start == prev_run_start)
range_writer (start, run_start - 1, previous_run_delta);
else
range_writer (start, run_start - 1, 0);
range_writer (run_start, end, run_delta); range_writer (run_start, end, run_delta);
return; return;
} }
@ -195,8 +220,7 @@ struct CmapSubtableFormat4
} }
// Write only a single non-run range. // Write only a single non-run range.
run_delta = (start == end) ? run_delta : 0; range_writer (start, end, 0);
range_writer (start, end, run_delta);
} }
template<typename Iterator, template<typename Iterator,