From 8c8638ab17db6288a6176033a5bfad39fb55ca6e Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 12 Jul 2019 18:49:40 -0400 Subject: Rename pango_fc_shape to pango_hb_shape There is no more fontconfig in it, and we use it unconditionally everywhere. T# --- pango/meson.build | 2 +- pango/pangofc-private.h | 10 -- pango/pangofc-shape.c | 417 ------------------------------------------------ pango/pangohb-private.h | 43 +++++ pango/pangohb-shape.c | 417 ++++++++++++++++++++++++++++++++++++++++++++++++ pango/shape.c | 10 +- 6 files changed, 466 insertions(+), 433 deletions(-) delete mode 100644 pango/pangofc-shape.c create mode 100644 pango/pangohb-private.h create mode 100644 pango/pangohb-shape.c diff --git a/pango/meson.build b/pango/meson.build index faf38780..e5cfa2f5 100644 --- a/pango/meson.build +++ b/pango/meson.build @@ -26,6 +26,7 @@ pango_sources = [ 'pango-utils.c', 'reorder-items.c', 'shape.c', + 'pangohb-shape.c', ] pango_headers = [ @@ -70,7 +71,6 @@ if fontconfig_dep.found() 'pangofc-font.c', 'pangofc-fontmap.c', 'pangofc-decoder.c', - 'pangofc-shape.c', ] pango_requires += [ fontconfig_pc, diff --git a/pango/pangofc-private.h b/pango/pangofc-private.h index df59fb69..27b96df4 100644 --- a/pango/pangofc-private.h +++ b/pango/pangofc-private.h @@ -78,16 +78,6 @@ _PANGO_EXTERN PangoFontMetrics *pango_fc_font_create_base_metrics_for_context (PangoFcFont *font, PangoContext *context); -void -_pango_fc_shape (PangoFont *font, - const char *item_text, - unsigned int item_length, - const char *paragraph_text, - unsigned int paragraph_length, - const PangoAnalysis *analysis, - PangoShapeFlags flags, - PangoGlyphString *glyphs); - G_END_DECLS #endif /* __PANGOFC_PRIVATE_H__ */ diff --git a/pango/pangofc-shape.c b/pango/pangofc-shape.c deleted file mode 100644 index 63cd3466..00000000 --- a/pango/pangofc-shape.c +++ /dev/null @@ -1,417 +0,0 @@ -/* Pango - * pangofc-shape.c: Basic shaper for FreeType-based backends - * - * Copyright (C) 2000, 2007, 2009 Red Hat Software - * Authors: - * Owen Taylor - * Behdad Esfahbod - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Library General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Library General Public License for more details. - * - * You should have received a copy of the GNU Library General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. - */ - -#include "config.h" -#include -#include - -#include "pango-impl-utils.h" -#include -#include - -/* cache a single hb_buffer_t */ -static hb_buffer_t *cached_buffer = NULL; /* MT-safe */ -G_LOCK_DEFINE_STATIC (cached_buffer); - -static hb_buffer_t * -acquire_buffer (gboolean *free_buffer) -{ - hb_buffer_t *buffer; - - if (G_LIKELY (G_TRYLOCK (cached_buffer))) - { - if (G_UNLIKELY (!cached_buffer)) - cached_buffer = hb_buffer_create (); - - buffer = cached_buffer; - *free_buffer = FALSE; - } - else - { - buffer = hb_buffer_create (); - *free_buffer = TRUE; - } - - return buffer; -} - -static void -release_buffer (hb_buffer_t *buffer, gboolean free_buffer) -{ - if (G_LIKELY (!free_buffer)) - { - hb_buffer_reset (buffer); - G_UNLOCK (cached_buffer); - } - else - hb_buffer_destroy (buffer); -} - -static void -apply_extra_attributes (GSList *attrs, - hb_feature_t *features, - guint length, - guint *num_features) -{ - GSList *l; - - for (l = attrs; l && *num_features < length; l = l->next) - { - PangoAttribute *attr = l->data; - if (attr->klass->type == PANGO_ATTR_FONT_FEATURES) - { - PangoAttrFontFeatures *fattr = (PangoAttrFontFeatures *) attr; - const gchar *feat; - const gchar *end; - int len; - - feat = fattr->features; - - while (feat != NULL && *num_features < length) - { - end = strchr (feat, ','); - if (end) - len = end - feat; - else - len = -1; - if (hb_feature_from_string (feat, len, &features[*num_features])) - { - features[*num_features].start = attr->start_index; - features[*num_features].end = attr->end_index; - (*num_features)++; - } - - if (end == NULL) - break; - - feat = end + 1; - } - } - } -} - -typedef struct -{ - PangoFont *font; - hb_font_t *parent; - PangoShapeFlags flags; -} PangoHbShapeContext; - -static hb_bool_t -pango_hb_font_get_nominal_glyph (hb_font_t *font, - void *font_data, - hb_codepoint_t unicode, - hb_codepoint_t *glyph, - void *user_data G_GNUC_UNUSED) -{ - PangoHbShapeContext *context = (PangoHbShapeContext *) font_data; - - if (context->flags & PANGO_SHAPE_SHOW_IGNORABLES) - { - if (pango_get_ignorable (unicode)) - { - *glyph = PANGO_GET_UNKNOWN_GLYPH (unicode); - return TRUE; - } - } - - if (context->flags & PANGO_SHAPE_SHOW_SPACE) - { - if (g_unichar_type (unicode) == G_UNICODE_SPACE_SEPARATOR) - { - /* Replace 0x20 by visible space, since we - * don't draw a hex box for 0x20 - */ - if (unicode == 0x20) - *glyph = PANGO_GET_UNKNOWN_GLYPH (0x2423); - else - *glyph = PANGO_GET_UNKNOWN_GLYPH (unicode); - return TRUE; - } - } - - if (hb_font_get_glyph (context->parent, unicode, 0, glyph)) - return TRUE; - - *glyph = PANGO_GET_UNKNOWN_GLYPH (unicode); - - /* We draw our own invalid-Unicode shape, so prevent HarfBuzz - * from using REPLACEMENT CHARACTER. */ - if (unicode > 0x10FFFF) - return TRUE; - - return FALSE; -} - -static hb_bool_t -pango_hb_font_get_variation_glyph (hb_font_t *font, - void *font_data, - hb_codepoint_t unicode, - hb_codepoint_t variation_selector, - hb_codepoint_t *glyph, - void *user_data G_GNUC_UNUSED) -{ - PangoHbShapeContext *context = (PangoHbShapeContext *) font_data; - - if (hb_font_get_glyph (context->parent, - unicode, variation_selector, glyph)) - return TRUE; - - return FALSE; -} - -static hb_bool_t -pango_hb_font_get_glyph_contour_point (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - unsigned int point_index, - hb_position_t *x, - hb_position_t *y, - void *user_data G_GNUC_UNUSED) -{ - PangoHbShapeContext *context = (PangoHbShapeContext *) font_data; - - return hb_font_get_glyph_contour_point (context->parent, glyph, point_index, x, y); -} - -static hb_position_t -pango_hb_font_get_glyph_advance (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - void *user_data G_GNUC_UNUSED) -{ - PangoHbShapeContext *context = (PangoHbShapeContext *) font_data; - - if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) - { - PangoRectangle logical; - - pango_font_get_glyph_extents (context->font, glyph, NULL, &logical); - return logical.width; - } - - return hb_font_get_glyph_h_advance (context->parent, glyph); -} - -static hb_bool_t -pango_hb_font_get_glyph_extents (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - hb_glyph_extents_t *extents, - void *user_data G_GNUC_UNUSED) -{ - PangoHbShapeContext *context = (PangoHbShapeContext *) font_data; - - if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) - { - PangoRectangle ink; - - pango_font_get_glyph_extents (context->font, glyph, &ink, NULL); - - extents->x_bearing = ink.x; - extents->y_bearing = ink.y; - extents->width = ink.width; - extents->height = ink.height; - - return TRUE; - } - - return hb_font_get_glyph_extents (context->parent, glyph, extents); -} - -static hb_bool_t -pango_hb_font_get_glyph_h_origin (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - hb_position_t *x, - hb_position_t *y, - void *user_data G_GNUC_UNUSED) -{ - PangoHbShapeContext *context = (PangoHbShapeContext *) font_data; - - return hb_font_get_glyph_h_origin (context->parent, glyph, x, y); -} - -static hb_bool_t -pango_hb_font_get_glyph_v_origin (hb_font_t *font, - void *font_data, - hb_codepoint_t glyph, - hb_position_t *x, - hb_position_t *y, -void *user_data G_GNUC_UNUSED) -{ - PangoHbShapeContext *context = (PangoHbShapeContext *) font_data; - - return hb_font_get_glyph_v_origin (context->parent, glyph, x, y); -} - -static hb_position_t -pango_hb_font_get_h_kerning (hb_font_t *font, - void *font_data, - hb_codepoint_t left_glyph, - hb_codepoint_t right_glyph, - void *user_data G_GNUC_UNUSED) -{ - PangoHbShapeContext *context = (PangoHbShapeContext *) font_data; - - return hb_font_get_glyph_h_kerning (context->parent, left_glyph, right_glyph); -} - -static hb_font_t * -pango_font_get_hb_font_for_flags (PangoFont *font, - PangoShapeFlags flags, - PangoHbShapeContext *context) -{ - hb_font_t *hb_font; - static hb_font_funcs_t *funcs; - - hb_font = pango_font_get_hb_font (font); - if (flags == PANGO_SHAPE_NONE) - return hb_font_reference (hb_font); - - if (G_UNLIKELY (!funcs)) - { - funcs = hb_font_funcs_create (); - hb_font_funcs_set_nominal_glyph_func (funcs, pango_hb_font_get_nominal_glyph, NULL, NULL); - hb_font_funcs_set_variation_glyph_func (funcs, pango_hb_font_get_variation_glyph, NULL, NULL); - hb_font_funcs_set_glyph_h_advance_func (funcs, pango_hb_font_get_glyph_advance, NULL, NULL); - hb_font_funcs_set_glyph_v_advance_func (funcs, pango_hb_font_get_glyph_advance, NULL, NULL); - hb_font_funcs_set_glyph_h_origin_func (funcs, pango_hb_font_get_glyph_h_origin, NULL, NULL); - hb_font_funcs_set_glyph_v_origin_func (funcs, pango_hb_font_get_glyph_v_origin, NULL, NULL); - hb_font_funcs_set_glyph_h_kerning_func (funcs, pango_hb_font_get_h_kerning, NULL, NULL); - hb_font_funcs_set_glyph_extents_func (funcs, pango_hb_font_get_glyph_extents, NULL, NULL); - hb_font_funcs_set_glyph_contour_point_func (funcs, pango_hb_font_get_glyph_contour_point, NULL, NULL); - } - - context->font = font; - context->parent = hb_font; - context->flags = flags; - - hb_font = hb_font_create_sub_font (hb_font); - hb_font_set_funcs (hb_font, funcs, context, NULL); - - return hb_font; -} - -void -_pango_fc_shape (PangoFont *font, - const char *item_text, - unsigned int item_length, - const char *paragraph_text, - unsigned int paragraph_length, - const PangoAnalysis *analysis, - PangoShapeFlags flags, - PangoGlyphString *glyphs) -{ - PangoHbShapeContext context; - hb_font_t *hb_font; - hb_buffer_t *hb_buffer; - hb_buffer_flags_t hb_buffer_flags; - hb_direction_t hb_direction; - gboolean free_buffer; - hb_glyph_info_t *hb_glyph; - hb_glyph_position_t *hb_position; - int last_cluster; - guint i, num_glyphs; - unsigned int item_offset = item_text - paragraph_text; - hb_feature_t features[32]; - unsigned int num_features = 0; - PangoGlyphInfo *infos; - - g_return_if_fail (font != NULL); - g_return_if_fail (analysis != NULL); - - hb_font = pango_font_get_hb_font_for_flags (font, flags, &context); - hb_buffer = acquire_buffer (&free_buffer); - - hb_direction = PANGO_GRAVITY_IS_VERTICAL (analysis->gravity) ? HB_DIRECTION_TTB : HB_DIRECTION_LTR; - if (analysis->level % 2) - hb_direction = HB_DIRECTION_REVERSE (hb_direction); - if (PANGO_GRAVITY_IS_IMPROPER (analysis->gravity)) - hb_direction = HB_DIRECTION_REVERSE (hb_direction); - - hb_buffer_flags = HB_BUFFER_FLAG_BOT | HB_BUFFER_FLAG_EOT; - - if (flags & PANGO_SHAPE_SHOW_IGNORABLES) - hb_buffer_flags |= HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES; - - /* setup buffer */ - - hb_buffer_set_direction (hb_buffer, hb_direction); - hb_buffer_set_script (hb_buffer, hb_glib_script_to_script (analysis->script)); - hb_buffer_set_language (hb_buffer, hb_language_from_string (pango_language_to_string (analysis->language), -1)); -#if HB_VERSION_ATLEAST(1,0,3) - hb_buffer_set_cluster_level (hb_buffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); -#endif - hb_buffer_set_flags (hb_buffer, hb_buffer_flags); - hb_buffer_set_invisible_glyph (hb_buffer, PANGO_GLYPH_EMPTY); - - hb_buffer_add_utf8 (hb_buffer, paragraph_text, paragraph_length, item_offset, item_length); - - pango_font_get_features (font, features, G_N_ELEMENTS (features), &num_features); - apply_extra_attributes (analysis->extra_attrs, features, G_N_ELEMENTS (features), &num_features); - - hb_shape (hb_font, hb_buffer, features, num_features); - - if (PANGO_GRAVITY_IS_IMPROPER (analysis->gravity)) - hb_buffer_reverse (hb_buffer); - - /* buffer output */ - num_glyphs = hb_buffer_get_length (hb_buffer); - hb_glyph = hb_buffer_get_glyph_infos (hb_buffer, NULL); - pango_glyph_string_set_size (glyphs, num_glyphs); - infos = glyphs->glyphs; - last_cluster = -1; - - for (i = 0; i < num_glyphs; i++) - { - infos[i].glyph = hb_glyph->codepoint; - glyphs->log_clusters[i] = hb_glyph->cluster - item_offset; - infos[i].attr.is_cluster_start = glyphs->log_clusters[i] != last_cluster; - hb_glyph++; - last_cluster = glyphs->log_clusters[i]; - } - - hb_position = hb_buffer_get_glyph_positions (hb_buffer, NULL); - if (PANGO_GRAVITY_IS_VERTICAL (analysis->gravity)) - for (i = 0; i < num_glyphs; i++) - { - /* 90 degrees rotation counter-clockwise. */ - infos[i].geometry.width = hb_position->y_advance; - infos[i].geometry.x_offset = hb_position->y_offset; - infos[i].geometry.y_offset = -hb_position->x_offset; - hb_position++; - } - else /* horizontal */ - for (i = 0; i < num_glyphs; i++) - { - infos[i].geometry.width = hb_position->x_advance; - infos[i].geometry.x_offset = hb_position->x_offset; - infos[i].geometry.y_offset = hb_position->y_offset; - hb_position++; - } - - release_buffer (hb_buffer, free_buffer); - hb_font_destroy (hb_font); -} diff --git a/pango/pangohb-private.h b/pango/pangohb-private.h new file mode 100644 index 00000000..029b014c --- /dev/null +++ b/pango/pangohb-private.h @@ -0,0 +1,43 @@ +/* Pango + * pangohb-private.h: Private apis related to harfbuzz + * + * Copyright (C) 2019 Red Hat Software + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#ifndef __PANGOHB_PRIVATE_H__ +#define __PANGOHB_PRIVATE_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +void +pango_hb_shape (PangoFont *font, + const char *item_text, + unsigned int item_length, + const char *paragraph_text, + unsigned int paragraph_length, + const PangoAnalysis *analysis, + PangoShapeFlags flags, + PangoGlyphString *glyphs); + +G_END_DECLS + +#endif /* __PANGOHB_PRIVATE_H__ */ diff --git a/pango/pangohb-shape.c b/pango/pangohb-shape.c new file mode 100644 index 00000000..2bd68a43 --- /dev/null +++ b/pango/pangohb-shape.c @@ -0,0 +1,417 @@ +/* Pango + * pangofc-shape.c: Basic shaper for FreeType-based backends + * + * Copyright (C) 2000, 2007, 2009 Red Hat Software + * Authors: + * Owen Taylor + * Behdad Esfahbod + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" +#include +#include + +#include "pango-impl-utils.h" +#include +#include + +/* cache a single hb_buffer_t */ +static hb_buffer_t *cached_buffer = NULL; /* MT-safe */ +G_LOCK_DEFINE_STATIC (cached_buffer); + +static hb_buffer_t * +acquire_buffer (gboolean *free_buffer) +{ + hb_buffer_t *buffer; + + if (G_LIKELY (G_TRYLOCK (cached_buffer))) + { + if (G_UNLIKELY (!cached_buffer)) + cached_buffer = hb_buffer_create (); + + buffer = cached_buffer; + *free_buffer = FALSE; + } + else + { + buffer = hb_buffer_create (); + *free_buffer = TRUE; + } + + return buffer; +} + +static void +release_buffer (hb_buffer_t *buffer, gboolean free_buffer) +{ + if (G_LIKELY (!free_buffer)) + { + hb_buffer_reset (buffer); + G_UNLOCK (cached_buffer); + } + else + hb_buffer_destroy (buffer); +} + +static void +apply_extra_attributes (GSList *attrs, + hb_feature_t *features, + guint length, + guint *num_features) +{ + GSList *l; + + for (l = attrs; l && *num_features < length; l = l->next) + { + PangoAttribute *attr = l->data; + if (attr->klass->type == PANGO_ATTR_FONT_FEATURES) + { + PangoAttrFontFeatures *fattr = (PangoAttrFontFeatures *) attr; + const gchar *feat; + const gchar *end; + int len; + + feat = fattr->features; + + while (feat != NULL && *num_features < length) + { + end = strchr (feat, ','); + if (end) + len = end - feat; + else + len = -1; + if (hb_feature_from_string (feat, len, &features[*num_features])) + { + features[*num_features].start = attr->start_index; + features[*num_features].end = attr->end_index; + (*num_features)++; + } + + if (end == NULL) + break; + + feat = end + 1; + } + } + } +} + +typedef struct +{ + PangoFont *font; + hb_font_t *parent; + PangoShapeFlags flags; +} PangoHbShapeContext; + +static hb_bool_t +pango_hb_font_get_nominal_glyph (hb_font_t *font, + void *font_data, + hb_codepoint_t unicode, + hb_codepoint_t *glyph, + void *user_data G_GNUC_UNUSED) +{ + PangoHbShapeContext *context = (PangoHbShapeContext *) font_data; + + if (context->flags & PANGO_SHAPE_SHOW_IGNORABLES) + { + if (pango_get_ignorable (unicode)) + { + *glyph = PANGO_GET_UNKNOWN_GLYPH (unicode); + return TRUE; + } + } + + if (context->flags & PANGO_SHAPE_SHOW_SPACE) + { + if (g_unichar_type (unicode) == G_UNICODE_SPACE_SEPARATOR) + { + /* Replace 0x20 by visible space, since we + * don't draw a hex box for 0x20 + */ + if (unicode == 0x20) + *glyph = PANGO_GET_UNKNOWN_GLYPH (0x2423); + else + *glyph = PANGO_GET_UNKNOWN_GLYPH (unicode); + return TRUE; + } + } + + if (hb_font_get_glyph (context->parent, unicode, 0, glyph)) + return TRUE; + + *glyph = PANGO_GET_UNKNOWN_GLYPH (unicode); + + /* We draw our own invalid-Unicode shape, so prevent HarfBuzz + * from using REPLACEMENT CHARACTER. */ + if (unicode > 0x10FFFF) + return TRUE; + + return FALSE; +} + +static hb_bool_t +pango_hb_font_get_variation_glyph (hb_font_t *font, + void *font_data, + hb_codepoint_t unicode, + hb_codepoint_t variation_selector, + hb_codepoint_t *glyph, + void *user_data G_GNUC_UNUSED) +{ + PangoHbShapeContext *context = (PangoHbShapeContext *) font_data; + + if (hb_font_get_glyph (context->parent, + unicode, variation_selector, glyph)) + return TRUE; + + return FALSE; +} + +static hb_bool_t +pango_hb_font_get_glyph_contour_point (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + unsigned int point_index, + hb_position_t *x, + hb_position_t *y, + void *user_data G_GNUC_UNUSED) +{ + PangoHbShapeContext *context = (PangoHbShapeContext *) font_data; + + return hb_font_get_glyph_contour_point (context->parent, glyph, point_index, x, y); +} + +static hb_position_t +pango_hb_font_get_glyph_advance (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + void *user_data G_GNUC_UNUSED) +{ + PangoHbShapeContext *context = (PangoHbShapeContext *) font_data; + + if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) + { + PangoRectangle logical; + + pango_font_get_glyph_extents (context->font, glyph, NULL, &logical); + return logical.width; + } + + return hb_font_get_glyph_h_advance (context->parent, glyph); +} + +static hb_bool_t +pango_hb_font_get_glyph_extents (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_glyph_extents_t *extents, + void *user_data G_GNUC_UNUSED) +{ + PangoHbShapeContext *context = (PangoHbShapeContext *) font_data; + + if (glyph & PANGO_GLYPH_UNKNOWN_FLAG) + { + PangoRectangle ink; + + pango_font_get_glyph_extents (context->font, glyph, &ink, NULL); + + extents->x_bearing = ink.x; + extents->y_bearing = ink.y; + extents->width = ink.width; + extents->height = ink.height; + + return TRUE; + } + + return hb_font_get_glyph_extents (context->parent, glyph, extents); +} + +static hb_bool_t +pango_hb_font_get_glyph_h_origin (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_position_t *x, + hb_position_t *y, + void *user_data G_GNUC_UNUSED) +{ + PangoHbShapeContext *context = (PangoHbShapeContext *) font_data; + + return hb_font_get_glyph_h_origin (context->parent, glyph, x, y); +} + +static hb_bool_t +pango_hb_font_get_glyph_v_origin (hb_font_t *font, + void *font_data, + hb_codepoint_t glyph, + hb_position_t *x, + hb_position_t *y, +void *user_data G_GNUC_UNUSED) +{ + PangoHbShapeContext *context = (PangoHbShapeContext *) font_data; + + return hb_font_get_glyph_v_origin (context->parent, glyph, x, y); +} + +static hb_position_t +pango_hb_font_get_h_kerning (hb_font_t *font, + void *font_data, + hb_codepoint_t left_glyph, + hb_codepoint_t right_glyph, + void *user_data G_GNUC_UNUSED) +{ + PangoHbShapeContext *context = (PangoHbShapeContext *) font_data; + + return hb_font_get_glyph_h_kerning (context->parent, left_glyph, right_glyph); +} + +static hb_font_t * +pango_font_get_hb_font_for_flags (PangoFont *font, + PangoShapeFlags flags, + PangoHbShapeContext *context) +{ + hb_font_t *hb_font; + static hb_font_funcs_t *funcs; + + hb_font = pango_font_get_hb_font (font); + if (flags == PANGO_SHAPE_NONE) + return hb_font_reference (hb_font); + + if (G_UNLIKELY (!funcs)) + { + funcs = hb_font_funcs_create (); + hb_font_funcs_set_nominal_glyph_func (funcs, pango_hb_font_get_nominal_glyph, NULL, NULL); + hb_font_funcs_set_variation_glyph_func (funcs, pango_hb_font_get_variation_glyph, NULL, NULL); + hb_font_funcs_set_glyph_h_advance_func (funcs, pango_hb_font_get_glyph_advance, NULL, NULL); + hb_font_funcs_set_glyph_v_advance_func (funcs, pango_hb_font_get_glyph_advance, NULL, NULL); + hb_font_funcs_set_glyph_h_origin_func (funcs, pango_hb_font_get_glyph_h_origin, NULL, NULL); + hb_font_funcs_set_glyph_v_origin_func (funcs, pango_hb_font_get_glyph_v_origin, NULL, NULL); + hb_font_funcs_set_glyph_h_kerning_func (funcs, pango_hb_font_get_h_kerning, NULL, NULL); + hb_font_funcs_set_glyph_extents_func (funcs, pango_hb_font_get_glyph_extents, NULL, NULL); + hb_font_funcs_set_glyph_contour_point_func (funcs, pango_hb_font_get_glyph_contour_point, NULL, NULL); + } + + context->font = font; + context->parent = hb_font; + context->flags = flags; + + hb_font = hb_font_create_sub_font (hb_font); + hb_font_set_funcs (hb_font, funcs, context, NULL); + + return hb_font; +} + +void +pango_hb_shape (PangoFont *font, + const char *item_text, + unsigned int item_length, + const char *paragraph_text, + unsigned int paragraph_length, + const PangoAnalysis *analysis, + PangoShapeFlags flags, + PangoGlyphString *glyphs) +{ + PangoHbShapeContext context; + hb_font_t *hb_font; + hb_buffer_t *hb_buffer; + hb_buffer_flags_t hb_buffer_flags; + hb_direction_t hb_direction; + gboolean free_buffer; + hb_glyph_info_t *hb_glyph; + hb_glyph_position_t *hb_position; + int last_cluster; + guint i, num_glyphs; + unsigned int item_offset = item_text - paragraph_text; + hb_feature_t features[32]; + unsigned int num_features = 0; + PangoGlyphInfo *infos; + + g_return_if_fail (font != NULL); + g_return_if_fail (analysis != NULL); + + hb_font = pango_font_get_hb_font_for_flags (font, flags, &context); + hb_buffer = acquire_buffer (&free_buffer); + + hb_direction = PANGO_GRAVITY_IS_VERTICAL (analysis->gravity) ? HB_DIRECTION_TTB : HB_DIRECTION_LTR; + if (analysis->level % 2) + hb_direction = HB_DIRECTION_REVERSE (hb_direction); + if (PANGO_GRAVITY_IS_IMPROPER (analysis->gravity)) + hb_direction = HB_DIRECTION_REVERSE (hb_direction); + + hb_buffer_flags = HB_BUFFER_FLAG_BOT | HB_BUFFER_FLAG_EOT; + + if (flags & PANGO_SHAPE_SHOW_IGNORABLES) + hb_buffer_flags |= HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES; + + /* setup buffer */ + + hb_buffer_set_direction (hb_buffer, hb_direction); + hb_buffer_set_script (hb_buffer, hb_glib_script_to_script (analysis->script)); + hb_buffer_set_language (hb_buffer, hb_language_from_string (pango_language_to_string (analysis->language), -1)); +#if HB_VERSION_ATLEAST(1,0,3) + hb_buffer_set_cluster_level (hb_buffer, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS); +#endif + hb_buffer_set_flags (hb_buffer, hb_buffer_flags); + hb_buffer_set_invisible_glyph (hb_buffer, PANGO_GLYPH_EMPTY); + + hb_buffer_add_utf8 (hb_buffer, paragraph_text, paragraph_length, item_offset, item_length); + + pango_font_get_features (font, features, G_N_ELEMENTS (features), &num_features); + apply_extra_attributes (analysis->extra_attrs, features, G_N_ELEMENTS (features), &num_features); + + hb_shape (hb_font, hb_buffer, features, num_features); + + if (PANGO_GRAVITY_IS_IMPROPER (analysis->gravity)) + hb_buffer_reverse (hb_buffer); + + /* buffer output */ + num_glyphs = hb_buffer_get_length (hb_buffer); + hb_glyph = hb_buffer_get_glyph_infos (hb_buffer, NULL); + pango_glyph_string_set_size (glyphs, num_glyphs); + infos = glyphs->glyphs; + last_cluster = -1; + + for (i = 0; i < num_glyphs; i++) + { + infos[i].glyph = hb_glyph->codepoint; + glyphs->log_clusters[i] = hb_glyph->cluster - item_offset; + infos[i].attr.is_cluster_start = glyphs->log_clusters[i] != last_cluster; + hb_glyph++; + last_cluster = glyphs->log_clusters[i]; + } + + hb_position = hb_buffer_get_glyph_positions (hb_buffer, NULL); + if (PANGO_GRAVITY_IS_VERTICAL (analysis->gravity)) + for (i = 0; i < num_glyphs; i++) + { + /* 90 degrees rotation counter-clockwise. */ + infos[i].geometry.width = hb_position->y_advance; + infos[i].geometry.x_offset = hb_position->y_offset; + infos[i].geometry.y_offset = -hb_position->x_offset; + hb_position++; + } + else /* horizontal */ + for (i = 0; i < num_glyphs; i++) + { + infos[i].geometry.width = hb_position->x_advance; + infos[i].geometry.x_offset = hb_position->x_offset; + infos[i].geometry.y_offset = hb_position->y_offset; + hb_position++; + } + + release_buffer (hb_buffer, free_buffer); + hb_font_destroy (hb_font); +} diff --git a/pango/shape.c b/pango/shape.c index 3815cb9e..ccd4222e 100644 --- a/pango/shape.c +++ b/pango/shape.c @@ -35,7 +35,7 @@ #include "pango-glyph.h" #include "pango-engine-private.h" -#include "pangofc-private.h" +#include "pangohb-private.h" #include @@ -194,10 +194,10 @@ pango_shape_with_options (const gchar *item_text, if (analysis->font) { - _pango_fc_shape (analysis->font, - item_text, item_length, - paragraph_text, paragraph_length, - analysis, flags, glyphs); + pango_hb_shape (analysis->font, + item_text, item_length, + paragraph_text, paragraph_length, + analysis, flags, glyphs); if (G_UNLIKELY (glyphs->num_glyphs == 0)) { -- cgit v1.2.1