[layout] Add hb_ot_layout_get_optical_bound()

pull/3799/head
Behdad Esfahbod 2 years ago
parent 238e7dd2b6
commit 5d6f1a88e4
  1. 11
      src/OT/Layout/GPOS/SinglePosFormat1.hh
  2. 17
      src/OT/Layout/GPOS/SinglePosFormat2.hh
  3. 57
      src/hb-ot-layout.cc
  4. 6
      src/hb-ot-layout.h

@ -80,6 +80,17 @@ struct SinglePosFormat1
return_trace (true);
}
bool
position_single (hb_ot_apply_context_t *c,
hb_codepoint_t gid,
hb_glyph_position_t &pos) const
{
unsigned int index = (this+coverage).get_coverage (gid);
if (likely (index == NOT_COVERED)) return false;
valueFormat.apply_value (c, this, values, pos);
return true;
}
template<typename Iterator,
typename SrcLookup,
hb_requires (hb_is_iterator (Iterator))>

@ -68,7 +68,7 @@ struct SinglePosFormat2
unsigned int index = (this+coverage).get_coverage (buffer->cur().codepoint);
if (likely (index == NOT_COVERED)) return_trace (false);
if (likely (index >= valueCount)) return_trace (false);
if (unlikely (index >= valueCount)) return_trace (false);
if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
{
@ -92,6 +92,21 @@ struct SinglePosFormat2
return_trace (true);
}
bool
position_single (hb_ot_apply_context_t *c,
hb_codepoint_t gid,
hb_glyph_position_t &pos) const
{
unsigned int index = (this+coverage).get_coverage (gid);
if (likely (index == NOT_COVERED)) return false;
if (unlikely (index >= valueCount)) return false;
valueFormat.apply_value (c, this,
&values[index * valueFormat.get_len ()],
pos);
return true;
}
template<typename Iterator,
typename SrcLookup,
hb_requires (hb_is_iterator (Iterator))>

@ -1709,6 +1709,63 @@ hb_ot_layout_get_size_params (hb_face_t *face,
return false;
}
struct hb_position_single_dispatch_t :
hb_dispatch_context_t<hb_position_single_dispatch_t, bool>
{
static return_t default_return_value () { return false; }
bool stop_sublookup_iteration (return_t r) const { return r; }
private:
template <typename T, typename ...Ts> auto
_dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN
( obj.position_single (std::forward<Ts> (ds)...) )
template <typename T, typename ...Ts> auto
_dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN
( default_return_value () )
public:
template <typename T, typename ...Ts> auto
dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN
( _dispatch (obj, hb_prioritize, std::forward<Ts> (ds)...) )
};
hb_position_t
hb_ot_layout_get_optical_bound (hb_font_t *font,
unsigned lookup_index,
hb_direction_t direction,
hb_codepoint_t glyph)
{
/* This is ugly... */
hb_buffer_t buffer;
buffer.props.direction = direction;
OT::hb_ot_apply_context_t c_apply (1, font, &buffer);
const OT::PosLookup &lookup = font->face->table.GPOS->table->get_lookup (lookup_index);
hb_glyph_position_t pos = {0};
hb_position_single_dispatch_t c;
lookup.dispatch (&c, &c_apply, glyph, pos);
hb_position_t ret = 0;
switch (direction)
{
case HB_DIRECTION_LTR:
ret = pos.x_offset;
break;
case HB_DIRECTION_RTL:
ret = pos.x_advance - pos.x_offset;
break;
case HB_DIRECTION_TTB:
ret = pos.y_offset;
break;
case HB_DIRECTION_BTT:
ret = pos.y_advance - pos.y_offset;
break;
case HB_DIRECTION_INVALID:
default:
break;
}
return ret;
}
/**
* hb_ot_layout_feature_get_name_ids:
* @face: #hb_face_t to work upon

@ -403,6 +403,12 @@ hb_ot_layout_get_size_params (hb_face_t *face,
unsigned int *range_start, /* OUT. May be NULL */
unsigned int *range_end /* OUT. May be NULL */);
HB_EXTERN hb_position_t
hb_ot_layout_get_optical_bound (hb_font_t *font,
unsigned lookup_index,
hb_direction_t direction,
hb_codepoint_t glyph);
HB_EXTERN hb_bool_t
hb_ot_layout_feature_get_name_ids (hb_face_t *face,

Loading…
Cancel
Save