#ifndef OT_LAYOUT_GPOS_ANCHORFORMAT3_HH
#define OT_LAYOUT_GPOS_ANCHORFORMAT3_HH
namespace OT {
namespace Layout {
namespace GPOS_impl {
struct AnchorFormat3
{
protected :
HBUINT16 format; /* Format identifier--format = 3 */
FWORD xCoordinate; /* Horizontal value--in design units */
FWORD yCoordinate; /* Vertical value--in design units */
Offset16To<Device>
xDeviceTable; /* Offset to Device table for X
* coordinate - - from beginning of
* Anchor table (may be NULL) */
Offset16To<Device>
yDeviceTable; /* Offset to Device table for Y
* coordinate - - from beginning of
* Anchor table (may be NULL) */
public :
DEFINE_SIZE_STATIC (10 );
bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this );
if (unlikely (!c->check_struct (this ))) return_trace (false );
return_trace (xDeviceTable.sanitize (c, this ) && yDeviceTable.sanitize (c, this ));
}
void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
float *x, float *y) const
{
hb_font_t *font = c->font;
*x = font->em_fscale_x (xCoordinate);
*y = font->em_fscale_y (yCoordinate);
if ((font->x_ppem || font->num_coords) && xDeviceTable.sanitize (&c->sanitizer, this ))
{
hb_barrier ();
*x += (this +xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache);
}
if ((font->y_ppem || font->num_coords) && yDeviceTable.sanitize (&c->sanitizer, this ))
{
hb_barrier ();
*y += (this +yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache);
}
}
bool subset (hb_subset_context_t *c) const
{
TRACE_SUBSET (this );
auto *out = c->serializer->start_embed (*this );
if (unlikely (!c->serializer->embed (format))) return_trace (false );
if (unlikely (!c->serializer->embed (xCoordinate))) return_trace (false );
if (unlikely (!c->serializer->embed (yCoordinate))) return_trace (false );
unsigned x_varidx = xDeviceTable ? (this +xDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
if (x_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
{
hb_pair_t<unsigned , int > *new_varidx_delta;
if (!c->plan->layout_variation_idx_delta_map.has (x_varidx, &new_varidx_delta))
return_trace (false );
x_varidx = hb_first (*new_varidx_delta);
int delta = hb_second (*new_varidx_delta);
if (delta != 0 )
{
if (!c->serializer->check_assign (out->xCoordinate, xCoordinate + delta,
HB_SERIALIZE_ERROR_INT_OVERFLOW))
return_trace (false );
}
}
unsigned y_varidx = yDeviceTable ? (this +yDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
if (y_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
{
hb_pair_t<unsigned , int > *new_varidx_delta;
if (!c->plan->layout_variation_idx_delta_map.has (y_varidx, &new_varidx_delta))
return_trace (false );
y_varidx = hb_first (*new_varidx_delta);
int delta = hb_second (*new_varidx_delta);
if (delta != 0 )
{
if (!c->serializer->check_assign (out->yCoordinate, yCoordinate + delta,
HB_SERIALIZE_ERROR_INT_OVERFLOW))
return_trace (false );
}
}
/* in case that all axes are pinned or no variations after instantiation,
* both var_idxes will be mapped to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */
if (x_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX &&
y_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
return_trace (c->serializer->check_assign (out->format, 1 , HB_SERIALIZE_ERROR_INT_OVERFLOW));
if (!c->serializer->embed (xDeviceTable)) return_trace (false );
if (!c->serializer->embed (yDeviceTable)) return_trace (false );
out->xDeviceTable.serialize_copy (c->serializer, xDeviceTable, this , 0 , hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map);
out->yDeviceTable.serialize_copy (c->serializer, yDeviceTable, this , 0 , hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map);
return_trace (out);
}
void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
{
(this +xDeviceTable).collect_variation_indices (c);
(this +yDeviceTable).collect_variation_indices (c);
}
};
}
}
}
#endif // OT_LAYOUT_GPOS_ANCHORFORMAT3_HH
Messung V0.5 in Prozent C=97 H=97 G=96
¤ Dauer der Verarbeitung: 0.17 Sekunden
(vorverarbeitet am 2026-06-10)
¤
*© Formatika GbR, Deutschland