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 *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache); 42 if ((font->y_ppem || font->num_coords) && yDeviceTable.sanitize (&c->sanitizer, this)) 43 *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache); 44 } 45 subsetOT::Layout::GPOS_impl::AnchorFormat346 bool subset (hb_subset_context_t *c) const 47 { 48 TRACE_SUBSET (this); 49 auto *out = c->serializer->start_embed (*this); 50 if (unlikely (!c->serializer->embed (format))) return_trace (false); 51 if (unlikely (!c->serializer->embed (xCoordinate))) return_trace (false); 52 if (unlikely (!c->serializer->embed (yCoordinate))) return_trace (false); 53 54 unsigned x_varidx = xDeviceTable ? (this+xDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX; 55 if (x_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) 56 { 57 hb_pair_t<unsigned, int> *new_varidx_delta; 58 if (!c->plan->layout_variation_idx_delta_map.has (x_varidx, &new_varidx_delta)) 59 return_trace (false); 60 61 x_varidx = hb_first (*new_varidx_delta); 62 int delta = hb_second (*new_varidx_delta); 63 if (delta != 0) 64 { 65 if (!c->serializer->check_assign (out->xCoordinate, xCoordinate + delta, 66 HB_SERIALIZE_ERROR_INT_OVERFLOW)) 67 return_trace (false); 68 } 69 } 70 71 unsigned y_varidx = yDeviceTable ? (this+yDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX; 72 if (y_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX) 73 { 74 hb_pair_t<unsigned, int> *new_varidx_delta; 75 if (!c->plan->layout_variation_idx_delta_map.has (y_varidx, &new_varidx_delta)) 76 return_trace (false); 77 78 y_varidx = hb_first (*new_varidx_delta); 79 int delta = hb_second (*new_varidx_delta); 80 if (delta != 0) 81 { 82 if (!c->serializer->check_assign (out->yCoordinate, yCoordinate + delta, 83 HB_SERIALIZE_ERROR_INT_OVERFLOW)) 84 return_trace (false); 85 } 86 } 87 88 /* in case that all axes are pinned or no variations after instantiation, 89 * both var_idxes will be mapped to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */ 90 if (x_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX && 91 y_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX) 92 return_trace (c->serializer->check_assign (out->format, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); 93 94 if (!c->serializer->embed (xDeviceTable)) return_trace (false); 95 if (!c->serializer->embed (yDeviceTable)) return_trace (false); 96 97 out->xDeviceTable.serialize_copy (c->serializer, xDeviceTable, this, 0, hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map); 98 out->yDeviceTable.serialize_copy (c->serializer, yDeviceTable, this, 0, hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map); 99 return_trace (out); 100 } 101 collect_variation_indicesOT::Layout::GPOS_impl::AnchorFormat3102 void collect_variation_indices (hb_collect_variation_indices_context_t *c) const 103 { 104 (this+xDeviceTable).collect_variation_indices (c); 105 (this+yDeviceTable).collect_variation_indices (c); 106 } 107 }; 108 109 110 } 111 } 112 } 113 114 #endif // OT_LAYOUT_GPOS_ANCHORFORMAT3_HH 115