1 | #ifndef OT_GLYF_GLYF_HELPERS_HH |
2 | #define OT_GLYF_GLYF_HELPERS_HH |
3 | |
4 | |
5 | #include "../../hb-open-type.hh" |
6 | #include "../../hb-subset-plan.hh" |
7 | |
8 | #include "loca.hh" |
9 | |
10 | |
11 | namespace OT { |
12 | namespace glyf_impl { |
13 | |
14 | |
15 | template<typename IteratorIn, typename TypeOut, |
16 | hb_requires (hb_is_source_of (IteratorIn, unsigned int))> |
17 | static void |
18 | _write_loca (IteratorIn&& it, |
19 | const hb_sorted_vector_t<hb_codepoint_pair_t> new_to_old_gid_list, |
20 | bool short_offsets, |
21 | TypeOut *dest, |
22 | unsigned num_offsets) |
23 | { |
24 | unsigned right_shift = short_offsets ? 1 : 0; |
25 | unsigned offset = 0; |
26 | TypeOut value; |
27 | value = 0; |
28 | *dest++ = value; |
29 | hb_codepoint_t last = 0; |
30 | for (auto _ : new_to_old_gid_list) |
31 | { |
32 | hb_codepoint_t gid = _.first; |
33 | for (; last < gid; last++) |
34 | { |
35 | DEBUG_MSG (SUBSET, nullptr, "loca entry empty offset %u" , offset); |
36 | *dest++ = value; |
37 | } |
38 | |
39 | unsigned padded_size = *it++; |
40 | offset += padded_size; |
41 | DEBUG_MSG (SUBSET, nullptr, "loca entry gid %u offset %u padded-size %u" , gid, offset, padded_size); |
42 | value = offset >> right_shift; |
43 | *dest++ = value; |
44 | |
45 | last++; // Skip over gid |
46 | } |
47 | unsigned num_glyphs = num_offsets - 1; |
48 | for (; last < num_glyphs; last++) |
49 | { |
50 | DEBUG_MSG (SUBSET, nullptr, "loca entry empty offset %u" , offset); |
51 | *dest++ = value; |
52 | } |
53 | } |
54 | |
55 | static bool |
56 | _add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca) |
57 | { |
58 | hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<head> (plan->source); |
59 | hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob); |
60 | hb_blob_destroy (head_blob); |
61 | |
62 | if (unlikely (!head_prime_blob)) |
63 | return false; |
64 | |
65 | head *head_prime = (head *) hb_blob_get_data_writable (head_prime_blob, nullptr); |
66 | head_prime->indexToLocFormat = use_short_loca ? 0 : 1; |
67 | if (plan->normalized_coords) |
68 | { |
69 | head_prime->xMin = plan->head_maxp_info.xMin; |
70 | head_prime->xMax = plan->head_maxp_info.xMax; |
71 | head_prime->yMin = plan->head_maxp_info.yMin; |
72 | head_prime->yMax = plan->head_maxp_info.yMax; |
73 | |
74 | unsigned orig_flag = head_prime->flags; |
75 | if (plan->head_maxp_info.allXMinIsLsb) |
76 | orig_flag |= 1 << 1; |
77 | else |
78 | orig_flag &= ~(1 << 1); |
79 | head_prime->flags = orig_flag; |
80 | } |
81 | bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob); |
82 | |
83 | hb_blob_destroy (head_prime_blob); |
84 | return success; |
85 | } |
86 | |
87 | template<typename Iterator, |
88 | hb_requires (hb_is_source_of (Iterator, unsigned int))> |
89 | static bool |
90 | _add_loca_and_head (hb_subset_context_t *c, |
91 | Iterator padded_offsets, |
92 | bool use_short_loca) |
93 | { |
94 | unsigned num_offsets = c->plan->num_output_glyphs () + 1; |
95 | unsigned entry_size = use_short_loca ? 2 : 4; |
96 | |
97 | char *loca_prime_data = (char *) hb_malloc (entry_size * num_offsets); |
98 | |
99 | if (unlikely (!loca_prime_data)) return false; |
100 | |
101 | DEBUG_MSG (SUBSET, nullptr, "loca entry_size %u num_offsets %u size %u" , |
102 | entry_size, num_offsets, entry_size * num_offsets); |
103 | |
104 | if (use_short_loca) |
105 | _write_loca (padded_offsets, c->plan->new_to_old_gid_list, true, (HBUINT16 *) loca_prime_data, num_offsets); |
106 | else |
107 | _write_loca (padded_offsets, c->plan->new_to_old_gid_list, false, (HBUINT32 *) loca_prime_data, num_offsets); |
108 | |
109 | hb_blob_t *loca_blob = hb_blob_create (loca_prime_data, |
110 | entry_size * num_offsets, |
111 | HB_MEMORY_MODE_WRITABLE, |
112 | loca_prime_data, |
113 | hb_free); |
114 | |
115 | bool result = c->plan->add_table (HB_OT_TAG_loca, loca_blob) |
116 | && _add_head_and_set_loca_version (c->plan, use_short_loca); |
117 | |
118 | hb_blob_destroy (loca_blob); |
119 | return result; |
120 | } |
121 | |
122 | |
123 | } /* namespace glyf_impl */ |
124 | } /* namespace OT */ |
125 | |
126 | |
127 | #endif /* OT_GLYF_GLYF_HELPERS_HH */ |
128 | |