1 #ifndef OT_LAYOUT_GPOS_ANCHORFORMAT3_HH 2 #define OT_LAYOUT_GPOS_ANCHORFORMAT3_HH 3 4 namespace OT { 5 namespace Layout { 6 namespace GPOS_impl { 7 8 struct AnchorFormat3 9 { 10 protected: 11 HBUINT16 format; /* Format identifier--format = 3 */ 12 FWORD xCoordinate; /* Horizontal value--in design units */ 13 FWORD yCoordinate; /* Vertical value--in design units */ 14 Offset16To<Device> 15 xDeviceTable; /* Offset to Device table for X 16 * coordinate-- from beginning of 17 * Anchor table (may be NULL) */ 18 Offset16To<Device> 19 yDeviceTable; /* Offset to Device table for Y 20 * coordinate-- from beginning of 21 * Anchor table (may be NULL) */ 22 public: 23 DEFINE_SIZE_STATIC (10); 24 sanitizeOT::Layout::GPOS_impl::AnchorFormat325 bool sanitize (hb_sanitize_context_t *c) const 26 { 27 TRACE_SANITIZE (this); 28 if (unlikely (!c->check_struct (this))) return_trace (false); 29 30 return_trace (xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this)); 31 } 32 get_anchorOT::Layout::GPOS_impl::AnchorFormat333 void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED, 34 float *x, float *y) const 35 { 36 hb_font_t *font = c->font; 37 *x = font->em_fscale_x (xCoordinate); 38 *y = font->em_fscale_y (yCoordinate); 39 40 if ((font->x_ppem || font->num_coords) && xDeviceTable.sanitize (&c->sanitizer, this)) 41 { 42 hb_barrier (); 43 *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache); 44 } 45 if ((font->y_ppem || font->num_coords) && yDeviceTable.sanitize (&c->sanitizer, this)) 46 { 47 hb_barrier (); 48 *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache); 49 } 50 } 51 subsetOT::Layout::GPOS_impl::AnchorFormat352 bool subset (hb_subset_context_t *c) const 53 { 54 TRACE_SUBSET (this); 55 auto *out = c->serializer->start_embed (*this); 56 if (unlikely (!c->serializer->embed (format))) return_trace (false); 57 if (unlikely (!c->serializer->embed (xCoordinate))) return_trace (false); 58 if (unlikely (!c->serializer->embed (yCoordinate))) return_trace (false); 59 60 unsigned x_varidx = xDeviceTable ? (this+xDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX; 61 if (x_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) 62 { 63 hb_pair_t<unsigned, int> *new_varidx_delta; 64 if (!c->plan->layout_variation_idx_delta_map.has (x_varidx, &new_varidx_delta)) 65 return_trace (false); 66 67 x_varidx = hb_first (*new_varidx_delta); 68 int delta = hb_second (*new_varidx_delta); 69 if (delta != 0) 70 { 71 if (!c->serializer->check_assign (out->xCoordinate, xCoordinate + delta, 72 HB_SERIALIZE_ERROR_INT_OVERFLOW)) 73 return_trace (false); 74 } 75 } 76 77 unsigned y_varidx = yDeviceTable ? (this+yDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX; 78 if (y_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) 79 { 80 hb_pair_t<unsigned, int> *new_varidx_delta; 81 if (!c->plan->layout_variation_idx_delta_map.has (y_varidx, &new_varidx_delta)) 82 return_trace (false); 83 84 y_varidx = hb_first (*new_varidx_delta); 85 int delta = hb_second (*new_varidx_delta); 86 if (delta != 0) 87 { 88 if (!c->serializer->check_assign (out->yCoordinate, yCoordinate + delta, 89 HB_SERIALIZE_ERROR_INT_OVERFLOW)) 90 return_trace (false); 91 } 92 } 93 94 /* in case that all axes are pinned or no variations after instantiation, 95 * both var_idxes will be mapped to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */ 96 if (x_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX && 97 y_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX) 98 return_trace (c->serializer->check_assign (out->format, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); 99 100 if (!c->serializer->embed (xDeviceTable)) return_trace (false); 101 if (!c->serializer->embed (yDeviceTable)) return_trace (false); 102 103 out->xDeviceTable.serialize_copy (c->serializer, xDeviceTable, this, 0, hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map); 104 out->yDeviceTable.serialize_copy (c->serializer, yDeviceTable, this, 0, hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map); 105 return_trace (out); 106 } 107 collect_variation_indicesOT::Layout::GPOS_impl::AnchorFormat3108 void collect_variation_indices (hb_collect_variation_indices_context_t *c) const 109 { 110 (this+xDeviceTable).collect_variation_indices (c); 111 (this+yDeviceTable).collect_variation_indices (c); 112 } 113 }; 114 115 116 } 117 } 118 } 119 120 #endif // OT_LAYOUT_GPOS_ANCHORFORMAT3_HH 121