• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 IteratorOut,
16 	 hb_requires (hb_is_source_of (IteratorIn, unsigned int)),
17 	 hb_requires (hb_is_sink_of (IteratorOut, unsigned))>
18 static void
_write_loca(IteratorIn && it,bool short_offsets,IteratorOut && dest)19 _write_loca (IteratorIn&& it, bool short_offsets, IteratorOut&& dest)
20 {
21   unsigned right_shift = short_offsets ? 1 : 0;
22   unsigned int offset = 0;
23   dest << 0;
24   + it
25   | hb_map ([=, &offset] (unsigned int padded_size)
26 	    {
27 	      offset += padded_size;
28 	      DEBUG_MSG (SUBSET, nullptr, "loca entry offset %d", offset);
29 	      return offset >> right_shift;
30 	    })
31   | hb_sink (dest)
32   ;
33 }
34 
35 static bool
_add_head_and_set_loca_version(hb_subset_plan_t * plan,bool use_short_loca)36 _add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca)
37 {
38   hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<head> (plan->source);
39   hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob);
40   hb_blob_destroy (head_blob);
41 
42   if (unlikely (!head_prime_blob))
43     return false;
44 
45   head *head_prime = (head *) hb_blob_get_data_writable (head_prime_blob, nullptr);
46   head_prime->indexToLocFormat = use_short_loca ? 0 : 1;
47   bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob);
48 
49   hb_blob_destroy (head_prime_blob);
50   return success;
51 }
52 
53 template<typename Iterator,
54 	 hb_requires (hb_is_source_of (Iterator, unsigned int))>
55 static bool
_add_loca_and_head(hb_subset_plan_t * plan,Iterator padded_offsets,bool use_short_loca)56 _add_loca_and_head (hb_subset_plan_t * plan, Iterator padded_offsets, bool use_short_loca)
57 {
58   unsigned num_offsets = padded_offsets.len () + 1;
59   unsigned entry_size = use_short_loca ? 2 : 4;
60   char *loca_prime_data = (char *) hb_calloc (entry_size, num_offsets);
61 
62   if (unlikely (!loca_prime_data)) return false;
63 
64   DEBUG_MSG (SUBSET, nullptr, "loca entry_size %d num_offsets %d size %d",
65 	     entry_size, num_offsets, entry_size * num_offsets);
66 
67   if (use_short_loca)
68     _write_loca (padded_offsets, true, hb_array ((HBUINT16 *) loca_prime_data, num_offsets));
69   else
70     _write_loca (padded_offsets, false, hb_array ((HBUINT32 *) loca_prime_data, num_offsets));
71 
72   hb_blob_t *loca_blob = hb_blob_create (loca_prime_data,
73 					 entry_size * num_offsets,
74 					 HB_MEMORY_MODE_WRITABLE,
75 					 loca_prime_data,
76 					 hb_free);
77 
78   bool result = plan->add_table (HB_OT_TAG_loca, loca_blob)
79 	     && _add_head_and_set_loca_version (plan, use_short_loca);
80 
81   hb_blob_destroy (loca_blob);
82   return result;
83 }
84 
85 
86 } /* namespace glyf_impl */
87 } /* namespace OT */
88 
89 
90 #endif /* OT_GLYF_GLYF_HELPERS_HH */
91