Imported Upstream version 8.2.2
[platform/upstream/harfbuzz.git] / src / OT / glyf / glyf-helpers.hh
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 */