From 5d6f1a88e48b57cd28f529643c2c0ff7809e3eea Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 31 Aug 2022 08:31:24 -0600 Subject: [PATCH 1/6] [layout] Add hb_ot_layout_get_optical_bound() --- src/OT/Layout/GPOS/SinglePosFormat1.hh | 11 +++++ src/OT/Layout/GPOS/SinglePosFormat2.hh | 17 +++++++- src/hb-ot-layout.cc | 57 ++++++++++++++++++++++++++ src/hb-ot-layout.h | 6 +++ 4 files changed, 90 insertions(+), 1 deletion(-) diff --git a/src/OT/Layout/GPOS/SinglePosFormat1.hh b/src/OT/Layout/GPOS/SinglePosFormat1.hh index 5a9dd58a6..01c148f00 100644 --- a/src/OT/Layout/GPOS/SinglePosFormat1.hh +++ b/src/OT/Layout/GPOS/SinglePosFormat1.hh @@ -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 diff --git a/src/OT/Layout/GPOS/SinglePosFormat2.hh b/src/OT/Layout/GPOS/SinglePosFormat2.hh index 8a6e8a42a..1f0d72844 100644 --- a/src/OT/Layout/GPOS/SinglePosFormat2.hh +++ b/src/OT/Layout/GPOS/SinglePosFormat2.hh @@ -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 diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 44e57987b..2e0b8d5e2 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -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 +{ + static return_t default_return_value () { return false; } + bool stop_sublookup_iteration (return_t r) const { return r; } + + private: + template auto + _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN + ( obj.position_single (std::forward (ds)...) ) + template auto + _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN + ( default_return_value () ) + public: + template auto + dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN + ( _dispatch (obj, hb_prioritize, std::forward (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 diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 4edddd9e0..288216e25 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -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, From 4bf9621113441a509565697c146492eee872c6fa Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Wed, 31 Aug 2022 09:18:18 -0600 Subject: [PATCH 2/6] [optical-bounds] Optimize --- src/OT/Layout/GPOS/SinglePosFormat1.hh | 15 +++++++++++---- src/OT/Layout/GPOS/SinglePosFormat2.hh | 15 +++++++++++---- src/hb-ot-layout.cc | 6 +----- 3 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/OT/Layout/GPOS/SinglePosFormat1.hh b/src/OT/Layout/GPOS/SinglePosFormat1.hh index 01c148f00..b4c9fc3db 100644 --- a/src/OT/Layout/GPOS/SinglePosFormat1.hh +++ b/src/OT/Layout/GPOS/SinglePosFormat1.hh @@ -81,13 +81,20 @@ struct SinglePosFormat1 } bool - position_single (hb_ot_apply_context_t *c, - hb_codepoint_t gid, - hb_glyph_position_t &pos) const + position_single (hb_font_t *font, + hb_direction_t direction, + 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); + + /* This is ugly... */ + hb_buffer_t buffer; + buffer.props.direction = direction; + OT::hb_ot_apply_context_t c (1, font, &buffer); + + valueFormat.apply_value (&c, this, values, pos); return true; } diff --git a/src/OT/Layout/GPOS/SinglePosFormat2.hh b/src/OT/Layout/GPOS/SinglePosFormat2.hh index 1f0d72844..c77951156 100644 --- a/src/OT/Layout/GPOS/SinglePosFormat2.hh +++ b/src/OT/Layout/GPOS/SinglePosFormat2.hh @@ -93,14 +93,21 @@ struct SinglePosFormat2 } bool - position_single (hb_ot_apply_context_t *c, - hb_codepoint_t gid, - hb_glyph_position_t &pos) const + position_single (hb_font_t *font, + hb_direction_t direction, + 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, + + /* This is ugly... */ + hb_buffer_t buffer; + buffer.props.direction = direction; + OT::hb_ot_apply_context_t c (1, font, &buffer); + + valueFormat.apply_value (&c, this, &values[index * valueFormat.get_len ()], pos); return true; diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 2e0b8d5e2..30cedbb7d 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -1735,14 +1735,10 @@ hb_ot_layout_get_optical_bound (hb_font_t *font, 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); + lookup.dispatch (&c, font, direction, glyph, pos); hb_position_t ret = 0; switch (direction) { From 8e88653f05daa3f78462ba4949b6713115b26aa9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 1 Sep 2022 13:39:26 -0600 Subject: [PATCH 3/6] [layout] Move code around --- src/hb-ot-layout.cc | 104 ++++++++++++++++++++++---------------------- 1 file changed, 53 insertions(+), 51 deletions(-) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 30cedbb7d..cbe1b7411 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -1710,57 +1710,6 @@ hb_ot_layout_get_size_params (hb_face_t *face, return false; } -struct hb_position_single_dispatch_t : - hb_dispatch_context_t -{ - static return_t default_return_value () { return false; } - bool stop_sublookup_iteration (return_t r) const { return r; } - - private: - template auto - _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN - ( obj.position_single (std::forward (ds)...) ) - template auto - _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN - ( default_return_value () ) - public: - template auto - dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN - ( _dispatch (obj, hb_prioritize, std::forward (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) -{ - 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, font, direction, 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: @@ -2426,4 +2375,57 @@ hb_ot_layout_lookup_get_glyph_alternates (hb_face_t *face, return ret; } + +struct hb_position_single_dispatch_t : + hb_dispatch_context_t +{ + static return_t default_return_value () { return false; } + bool stop_sublookup_iteration (return_t r) const { return r; } + + private: + template auto + _dispatch (const T &obj, hb_priority<1>, Ts&&... ds) HB_AUTO_RETURN + ( obj.position_single (std::forward (ds)...) ) + template auto + _dispatch (const T &obj, hb_priority<0>, Ts&&... ds) HB_AUTO_RETURN + ( default_return_value () ) + public: + template auto + dispatch (const T &obj, Ts&&... ds) HB_AUTO_RETURN + ( _dispatch (obj, hb_prioritize, std::forward (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) +{ + 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, font, direction, 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; +} + + #endif From 3892128a1fe1d04365cb91b71babd01b331c1893 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 1 Sep 2022 13:40:53 -0600 Subject: [PATCH 4/6] [layout] Add HB_NO_LAYOUT_RARELY_USED --- src/hb-config.hh | 1 + src/hb-ot-layout.cc | 2 ++ 2 files changed, 3 insertions(+) diff --git a/src/hb-config.hh b/src/hb-config.hh index 5567ddaec..dbe0cb81e 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -71,6 +71,7 @@ #define HB_NO_LANGUAGE_PRIVATE_SUBTAG #define HB_NO_LAYOUT_FEATURE_PARAMS #define HB_NO_LAYOUT_COLLECT_GLYPHS +#define HB_NO_LAYOUT_RARELY_UNUSED #define HB_NO_LAYOUT_UNUSED #define HB_NO_MATH #define HB_NO_META diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index cbe1b7411..c708cc3f4 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -2343,6 +2343,7 @@ struct hb_get_glyph_alternates_dispatch_t : ( _dispatch (obj, hb_prioritize, std::forward (ds)...) ) }; +#ifndef HB_NO_LAYOUT_RARELY_UNUSED /** * hb_ot_layout_lookup_get_glyph_alternates: * @face: a face. @@ -2426,6 +2427,7 @@ hb_ot_layout_get_optical_bound (hb_font_t *font, } return ret; } +#endif #endif From 71c6cba097852831bfb296702e8727e88d14d04a Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 1 Sep 2022 13:43:19 -0600 Subject: [PATCH 5/6] [layout] Rename API: -hb_ot_layout_get_optical_bound() +hb_ot_layout_lookup_get_optical_bound() --- src/hb-config.hh | 2 +- src/hb-ot-layout.cc | 10 +++++----- src/hb-ot-layout.h | 13 +++++++++---- 3 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/hb-config.hh b/src/hb-config.hh index dbe0cb81e..d56617f6a 100644 --- a/src/hb-config.hh +++ b/src/hb-config.hh @@ -71,7 +71,7 @@ #define HB_NO_LANGUAGE_PRIVATE_SUBTAG #define HB_NO_LAYOUT_FEATURE_PARAMS #define HB_NO_LAYOUT_COLLECT_GLYPHS -#define HB_NO_LAYOUT_RARELY_UNUSED +#define HB_NO_LAYOUT_RARELY_USED #define HB_NO_LAYOUT_UNUSED #define HB_NO_MATH #define HB_NO_META diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index c708cc3f4..90f2080f0 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -2343,7 +2343,7 @@ struct hb_get_glyph_alternates_dispatch_t : ( _dispatch (obj, hb_prioritize, std::forward (ds)...) ) }; -#ifndef HB_NO_LAYOUT_RARELY_UNUSED +#ifndef HB_NO_LAYOUT_RARELY_USED /** * hb_ot_layout_lookup_get_glyph_alternates: * @face: a face. @@ -2397,10 +2397,10 @@ struct hb_position_single_dispatch_t : }; 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_ot_layout_lookup_get_optical_bound (hb_font_t *font, + unsigned lookup_index, + hb_direction_t direction, + hb_codepoint_t glyph) { const OT::PosLookup &lookup = font->face->table.GPOS->table->get_lookup (lookup_index); hb_glyph_position_t pos = {0}; diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h index 288216e25..f7b488f87 100644 --- a/src/hb-ot-layout.h +++ b/src/hb-ot-layout.h @@ -404,12 +404,16 @@ hb_ot_layout_get_size_params (hb_face_t *face, 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_ot_layout_lookup_get_optical_bound (hb_font_t *font, + unsigned lookup_index, + hb_direction_t direction, + hb_codepoint_t glyph); +/* + * GSUB/GPOS + */ + HB_EXTERN hb_bool_t hb_ot_layout_feature_get_name_ids (hb_face_t *face, hb_tag_t table_tag, @@ -429,6 +433,7 @@ hb_ot_layout_feature_get_characters (hb_face_t *face, unsigned int *char_count /* IN/OUT. May be NULL */, hb_codepoint_t *characters /* OUT. May be NULL */); + /* * BASE */ From 752060a49c533c84249707d5a2f026a5b5a4ea33 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 1 Sep 2022 13:47:12 -0600 Subject: [PATCH 6/6] [layout] Document hb_ot_layout_lookup_get_optical_bound() --- src/hb-ot-layout.cc | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index 90f2080f0..aa53054bb 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -2396,6 +2396,20 @@ struct hb_position_single_dispatch_t : ( _dispatch (obj, hb_prioritize, std::forward (ds)...) ) }; +/** + * hb_ot_layout_lookup_get_optical_bound: + * @face: a font. + * @lookup_index: index of the feature lookup to query. + * @direction: edge of the glyph to query. + * @glyph: a glyph id. + * + * Fetches the optical bound of a glyph positioned at the margin of text. + * The direction identifies which edge of the glyph to query. + * + * Return value: Adjustment value. Negative values mean the glyph will stick out of the margin. + * + * Since: REPLACEME + **/ hb_position_t hb_ot_layout_lookup_get_optical_bound (hb_font_t *font, unsigned lookup_index,