Index: third_party/harfbuzz-ng/src/hb-font-private.hh |
diff --git a/third_party/harfbuzz-ng/src/hb-font-private.hh b/third_party/harfbuzz-ng/src/hb-font-private.hh |
index 91a43047daeacc972eea51d899f8aaa530f06304..b6dafbf474a5a53328dbbacea2b3dbfdeca7ad22 100644 |
--- a/third_party/harfbuzz-ng/src/hb-font-private.hh |
+++ b/third_party/harfbuzz-ng/src/hb-font-private.hh |
@@ -33,6 +33,8 @@ |
#include "hb-font.h" |
#include "hb-object-private.hh" |
+#include "hb-shaper-private.hh" |
+#include "hb-shape-plan-private.hh" |
@@ -54,7 +56,7 @@ |
HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \ |
/* ^--- Add new callbacks here */ |
-struct _hb_font_funcs_t { |
+struct hb_font_funcs_t { |
hb_object_header_t header; |
ASSERT_POD (); |
@@ -86,28 +88,64 @@ struct _hb_font_funcs_t { |
* hb_face_t |
*/ |
-struct _hb_face_t { |
+struct hb_face_t { |
hb_object_header_t header; |
ASSERT_POD (); |
hb_bool_t immutable; |
- hb_reference_table_func_t reference_table; |
+ hb_reference_table_func_t reference_table_func; |
void *user_data; |
hb_destroy_func_t destroy; |
- struct hb_ot_layout_t *ot_layout; |
- |
unsigned int index; |
- unsigned int upem; |
+ mutable unsigned int upem; |
+ |
+ struct hb_shaper_data_t shaper_data; |
+ |
+ struct plan_node_t { |
+ hb_shape_plan_t *shape_plan; |
+ plan_node_t *next; |
+ } *shape_plans; |
+ |
+ |
+ inline hb_blob_t *reference_table (hb_tag_t tag) const |
+ { |
+ hb_blob_t *blob; |
+ |
+ if (unlikely (!this || !reference_table_func)) |
+ return hb_blob_get_empty (); |
+ |
+ blob = reference_table_func (/*XXX*/const_cast<hb_face_t *> (this), tag, user_data); |
+ if (unlikely (!blob)) |
+ return hb_blob_get_empty (); |
+ |
+ return blob; |
+ } |
+ |
+ inline unsigned int get_upem (void) const |
+ { |
+ if (unlikely (!upem)) |
+ load_upem (); |
+ return upem; |
+ } |
+ |
+ private: |
+ HB_INTERNAL void load_upem (void) const; |
}; |
+#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS |
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, face); |
+#include "hb-shaper-list.hh" |
+#undef HB_SHAPER_IMPLEMENT |
+#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS |
+ |
/* |
* hb_font_t |
*/ |
-struct _hb_font_t { |
+struct hb_font_t { |
hb_object_header_t header; |
ASSERT_POD (); |
@@ -126,6 +164,8 @@ struct _hb_font_t { |
void *user_data; |
hb_destroy_func_t destroy; |
+ struct hb_shaper_data_t shaper_data; |
+ |
/* Convert from font-space to user-space */ |
inline hb_position_t em_scale_x (int16_t v) { return em_scale (v, this->x_scale); } |
@@ -159,10 +199,262 @@ struct _hb_font_t { |
} |
+ /* Public getters */ |
+ |
+ inline hb_bool_t get_glyph (hb_codepoint_t unicode, hb_codepoint_t variation_selector, |
+ hb_codepoint_t *glyph) |
+ { |
+ *glyph = 0; |
+ return klass->get.glyph (this, user_data, |
+ unicode, variation_selector, glyph, |
+ klass->user_data.glyph); |
+ } |
+ |
+ inline hb_position_t get_glyph_h_advance (hb_codepoint_t glyph) |
+ { |
+ return klass->get.glyph_h_advance (this, user_data, |
+ glyph, |
+ klass->user_data.glyph_h_advance); |
+ } |
+ |
+ inline hb_position_t get_glyph_v_advance (hb_codepoint_t glyph) |
+ { |
+ return klass->get.glyph_v_advance (this, user_data, |
+ glyph, |
+ klass->user_data.glyph_v_advance); |
+ } |
+ |
+ inline hb_bool_t get_glyph_h_origin (hb_codepoint_t glyph, |
+ hb_position_t *x, hb_position_t *y) |
+ { |
+ *x = *y = 0; |
+ return klass->get.glyph_h_origin (this, user_data, |
+ glyph, x, y, |
+ klass->user_data.glyph_h_origin); |
+ } |
+ |
+ inline hb_bool_t get_glyph_v_origin (hb_codepoint_t glyph, |
+ hb_position_t *x, hb_position_t *y) |
+ { |
+ *x = *y = 0; |
+ return klass->get.glyph_v_origin (this, user_data, |
+ glyph, x, y, |
+ klass->user_data.glyph_v_origin); |
+ } |
+ |
+ inline hb_position_t get_glyph_h_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph) |
+ { |
+ return klass->get.glyph_h_kerning (this, user_data, |
+ left_glyph, right_glyph, |
+ klass->user_data.glyph_h_kerning); |
+ } |
+ |
+ inline hb_position_t get_glyph_v_kerning (hb_codepoint_t left_glyph, hb_codepoint_t right_glyph) |
+ { |
+ return klass->get.glyph_v_kerning (this, user_data, |
+ left_glyph, right_glyph, |
+ klass->user_data.glyph_v_kerning); |
+ } |
+ |
+ inline hb_bool_t get_glyph_extents (hb_codepoint_t glyph, |
+ hb_glyph_extents_t *extents) |
+ { |
+ memset (extents, 0, sizeof (*extents)); |
+ return klass->get.glyph_extents (this, user_data, |
+ glyph, |
+ extents, |
+ klass->user_data.glyph_extents); |
+ } |
+ |
+ inline hb_bool_t get_glyph_contour_point (hb_codepoint_t glyph, unsigned int point_index, |
+ hb_position_t *x, hb_position_t *y) |
+ { |
+ *x = *y = 0; |
+ return klass->get.glyph_contour_point (this, user_data, |
+ glyph, point_index, |
+ x, y, |
+ klass->user_data.glyph_contour_point); |
+ } |
+ |
+ inline hb_bool_t get_glyph_name (hb_codepoint_t glyph, |
+ char *name, unsigned int size) |
+ { |
+ if (size) *name = '\0'; |
+ return klass->get.glyph_name (this, user_data, |
+ glyph, |
+ name, size, |
+ klass->user_data.glyph_name); |
+ } |
+ |
+ inline hb_bool_t get_glyph_from_name (const char *name, int len, /* -1 means nul-terminated */ |
+ hb_codepoint_t *glyph) |
+ { |
+ *glyph = 0; |
+ if (len == -1) len = strlen (name); |
+ return klass->get.glyph_from_name (this, user_data, |
+ name, len, |
+ glyph, |
+ klass->user_data.glyph_from_name); |
+ } |
+ |
+ |
+ /* A bit higher-level, and with fallback */ |
+ |
+ inline void get_glyph_advance_for_direction (hb_codepoint_t glyph, |
+ hb_direction_t direction, |
+ hb_position_t *x, hb_position_t *y) |
+ { |
+ if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { |
+ *x = get_glyph_h_advance (glyph); |
+ *y = 0; |
+ } else { |
+ *x = 0; |
+ *y = get_glyph_v_advance (glyph); |
+ } |
+ } |
+ |
+ /* Internal only */ |
+ inline void guess_v_origin_minus_h_origin (hb_codepoint_t glyph, |
+ hb_position_t *x, hb_position_t *y) |
+ { |
+ *x = get_glyph_h_advance (glyph) / 2; |
+ |
+ /* TODO use font_metics.ascent */ |
+ *y = y_scale; |
+ } |
+ |
+ inline void get_glyph_origin_for_direction (hb_codepoint_t glyph, |
+ hb_direction_t direction, |
+ hb_position_t *x, hb_position_t *y) |
+ { |
+ if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { |
+ hb_bool_t ret = get_glyph_h_origin (glyph, x, y); |
+ if (!ret && (ret = get_glyph_v_origin (glyph, x, y))) { |
+ hb_position_t dx, dy; |
+ guess_v_origin_minus_h_origin (glyph, &dx, &dy); |
+ *x -= dx; *y -= dy; |
+ } |
+ } else { |
+ hb_bool_t ret = get_glyph_v_origin (glyph, x, y); |
+ if (!ret && (ret = get_glyph_h_origin (glyph, x, y))) { |
+ hb_position_t dx, dy; |
+ guess_v_origin_minus_h_origin (glyph, &dx, &dy); |
+ *x += dx; *y += dy; |
+ } |
+ } |
+ } |
+ |
+ inline void add_glyph_origin_for_direction (hb_codepoint_t glyph, |
+ hb_direction_t direction, |
+ hb_position_t *x, hb_position_t *y) |
+ { |
+ hb_position_t origin_x, origin_y; |
+ |
+ get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y); |
+ |
+ *x += origin_x; |
+ *y += origin_y; |
+ } |
+ |
+ inline void subtract_glyph_origin_for_direction (hb_codepoint_t glyph, |
+ hb_direction_t direction, |
+ hb_position_t *x, hb_position_t *y) |
+ { |
+ hb_position_t origin_x, origin_y; |
+ |
+ get_glyph_origin_for_direction (glyph, direction, &origin_x, &origin_y); |
+ |
+ *x -= origin_x; |
+ *y -= origin_y; |
+ } |
+ |
+ inline void get_glyph_kerning_for_direction (hb_codepoint_t first_glyph, hb_codepoint_t second_glyph, |
+ hb_direction_t direction, |
+ hb_position_t *x, hb_position_t *y) |
+ { |
+ if (likely (HB_DIRECTION_IS_HORIZONTAL (direction))) { |
+ *x = get_glyph_h_kerning (first_glyph, second_glyph); |
+ *y = 0; |
+ } else { |
+ *x = 0; |
+ *y = get_glyph_v_kerning (first_glyph, second_glyph); |
+ } |
+ } |
+ |
+ inline hb_bool_t get_glyph_extents_for_origin (hb_codepoint_t glyph, |
+ hb_direction_t direction, |
+ hb_glyph_extents_t *extents) |
+ { |
+ hb_bool_t ret = get_glyph_extents (glyph, extents); |
+ |
+ if (ret) |
+ subtract_glyph_origin_for_direction (glyph, direction, &extents->x_bearing, &extents->y_bearing); |
+ |
+ return ret; |
+ } |
+ |
+ inline hb_bool_t get_glyph_contour_point_for_origin (hb_codepoint_t glyph, unsigned int point_index, |
+ hb_direction_t direction, |
+ hb_position_t *x, hb_position_t *y) |
+ { |
+ hb_bool_t ret = get_glyph_contour_point (glyph, point_index, x, y); |
+ |
+ if (ret) |
+ subtract_glyph_origin_for_direction (glyph, direction, x, y); |
+ |
+ return ret; |
+ } |
+ |
+ /* Generates gidDDD if glyph has no name. */ |
+ inline void |
+ glyph_to_string (hb_codepoint_t glyph, |
+ char *s, unsigned int size) |
+ { |
+ if (get_glyph_name (glyph, s, size)) return; |
+ |
+ snprintf (s, size, "gid%u", glyph); |
+ } |
+ |
+ /* Parses gidDDD and uniUUUU strings automatically. */ |
+ inline hb_bool_t |
+ glyph_from_string (const char *s, int len, /* -1 means nul-terminated */ |
+ hb_codepoint_t *glyph) |
+ { |
+ if (get_glyph_from_name (s, len, glyph)) return true; |
+ |
+ if (len == -1) len = strlen (s); |
+ |
+ /* Straight glyph index. */ |
+ if (hb_codepoint_parse (s, len, 10, glyph)) |
+ return true; |
+ |
+ if (len > 3) |
+ { |
+ /* gidDDD syntax for glyph indices. */ |
+ if (0 == strncmp (s, "gid", 3) && |
+ hb_codepoint_parse (s + 3, len - 3, 10, glyph)) |
+ return true; |
+ |
+ /* uniUUUU and other Unicode character indices. */ |
+ hb_codepoint_t unichar; |
+ if (0 == strncmp (s, "uni", 3) && |
+ hb_codepoint_parse (s + 3, len - 3, 16, &unichar) && |
+ get_glyph (unichar, 0, glyph)) |
+ return true; |
+ } |
+ |
+ return false; |
+ } |
+ |
private: |
inline hb_position_t em_scale (int16_t v, int scale) { return v * (int64_t) scale / hb_face_get_upem (this->face); } |
}; |
+#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS |
+#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font); |
+#include "hb-shaper-list.hh" |
+#undef HB_SHAPER_IMPLEMENT |
+#undef HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS |
#endif /* HB_FONT_PRIVATE_HH */ |