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 return_trace (c->check_struct (this) && xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this)); 29 } 30 get_anchorOT::Layout::GPOS_impl::AnchorFormat331 void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED, 32 float *x, float *y) const 33 { 34 hb_font_t *font = c->font; 35 *x = font->em_fscale_x (xCoordinate); 36 *y = font->em_fscale_y (yCoordinate); 37 38 if (font->x_ppem || font->num_coords) 39 *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache); 40 if (font->y_ppem || font->num_coords) 41 *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache); 42 } 43 subsetOT::Layout::GPOS_impl::AnchorFormat344 bool subset (hb_subset_context_t *c) const 45 { 46 TRACE_SUBSET (this); 47 auto *out = c->serializer->start_embed (*this); 48 if (unlikely (!out)) return_trace (false); 49 if (unlikely (!c->serializer->embed (format))) return_trace (false); 50 if (unlikely (!c->serializer->embed (xCoordinate))) return_trace (false); 51 if (unlikely (!c->serializer->embed (yCoordinate))) return_trace (false); 52 53 unsigned x_varidx = xDeviceTable ? (this+xDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX; 54 if (c->plan->layout_variation_idx_delta_map->has (x_varidx)) 55 { 56 int delta = hb_second (c->plan->layout_variation_idx_delta_map->get (x_varidx)); 57 if (delta != 0) 58 { 59 if (!c->serializer->check_assign (out->xCoordinate, xCoordinate + delta, 60 HB_SERIALIZE_ERROR_INT_OVERFLOW)) 61 return_trace (false); 62 } 63 } 64 65 unsigned y_varidx = yDeviceTable ? (this+yDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX; 66 if (c->plan->layout_variation_idx_delta_map->has (y_varidx)) 67 { 68 int delta = hb_second (c->plan->layout_variation_idx_delta_map->get (y_varidx)); 69 if (delta != 0) 70 { 71 if (!c->serializer->check_assign (out->yCoordinate, yCoordinate + delta, 72 HB_SERIALIZE_ERROR_INT_OVERFLOW)) 73 return_trace (false); 74 } 75 } 76 77 if (c->plan->all_axes_pinned) 78 return_trace (c->serializer->check_assign (out->format, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW)); 79 80 if (!c->serializer->embed (xDeviceTable)) return_trace (false); 81 if (!c->serializer->embed (yDeviceTable)) return_trace (false); 82 83 out->xDeviceTable.serialize_copy (c->serializer, xDeviceTable, this, 0, hb_serialize_context_t::Head, c->plan->layout_variation_idx_delta_map); 84 out->yDeviceTable.serialize_copy (c->serializer, yDeviceTable, this, 0, hb_serialize_context_t::Head, c->plan->layout_variation_idx_delta_map); 85 return_trace (out); 86 } 87 collect_variation_indicesOT::Layout::GPOS_impl::AnchorFormat388 void collect_variation_indices (hb_collect_variation_indices_context_t *c) const 89 { 90 (this+xDeviceTable).collect_variation_indices (c); 91 (this+yDeviceTable).collect_variation_indices (c); 92 } 93 }; 94 95 96 } 97 } 98 } 99 100 #endif // OT_LAYOUT_GPOS_ANCHORFORMAT3_HH 101