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