glyf-helpers.hh (3595B)
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 %" PRIu32 " 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 */