From ec2b1d9fb7ea269e250370dba2458ff9998d7a78 Mon Sep 17 00:00:00 2001 From: Packit Service Date: Dec 10 2020 00:32:04 +0000 Subject: Prepare for a new update Reverting patches so we can apply the latest update and changes can be seen in the spec file and sources. --- diff --git a/pango/pango-bidi-type.c b/pango/pango-bidi-type.c index d169525..a49e06d 100644 --- a/pango/pango-bidi-type.c +++ b/pango/pango-bidi-type.c @@ -179,11 +179,8 @@ pango_log2vis_get_embedding_levels (const gchar *text, for (i = 0, p = text; p < text + length; p = g_utf8_next_char(p), i++) { gunichar ch = g_utf8_get_char (p); - FriBidiCharType char_type = fribidi_get_bidi_type (ch); - - if (i == n_chars) - break; - + FriBidiCharType char_type; + char_type = fribidi_get_bidi_type (ch); bidi_types[i] = char_type; ored_types |= char_type; if (FRIBIDI_IS_STRONG (char_type)) diff --git a/pango/pango-bidi-type.c.bidi b/pango/pango-bidi-type.c.bidi deleted file mode 100644 index a49e06d..0000000 --- a/pango/pango-bidi-type.c.bidi +++ /dev/null @@ -1,329 +0,0 @@ -/* Pango - * pango-bidi-type.c: Bidirectional Character Types - * - * Copyright (C) 2008 Jürg Billeter - * - * 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. - */ - -/** - * SECTION:bidi - * @short_description:Types and functions to help with handling bidirectional text - * @title:Bidirectional Text - * @see_also: - * pango_context_get_base_dir(), - * pango_context_set_base_dir(), - * pango_itemize_with_base_dir() - * - * Pango supports bidirectional text (like Arabic and Hebrew) automatically. - * Some applications however, need some help to correctly handle bidirectional text. - * - * The #PangoDirection type can be used with pango_context_set_base_dir() to - * instruct Pango about direction of text, though in most cases Pango detects - * that correctly and automatically. The rest of the facilities in this section - * are used internally by Pango already, and are provided to help applications - * that need more direct control over bidirectional setting of text. - */ -#include "config.h" - -#include - -#include - -#include "pango-bidi-type.h" -#include "pango-utils.h" - -#if FRIBIDI_MAJOR_VERSION >= 1 -#define USE_FRIBIDI_EX_API -#endif - -/** - * pango_bidi_type_for_unichar: - * @ch: a Unicode character - * - * Determines the normative bidirectional character type of a - * character, as specified in the Unicode Character Database. - * - * A simplified version of this function is available as - * pango_unichar_direction(). - * - * Return value: the bidirectional character type, as used in the - * Unicode bidirectional algorithm. - * - * Since: 1.22 - */ -PangoBidiType -pango_bidi_type_for_unichar (gunichar ch) -{ - FriBidiCharType fribidi_ch_type; - - G_STATIC_ASSERT (sizeof (FriBidiChar) == sizeof (gunichar)); - - fribidi_ch_type = fribidi_get_bidi_type (ch); - - switch (fribidi_ch_type) - { - case FRIBIDI_TYPE_LTR: return PANGO_BIDI_TYPE_L; - case FRIBIDI_TYPE_LRE: return PANGO_BIDI_TYPE_LRE; - case FRIBIDI_TYPE_LRO: return PANGO_BIDI_TYPE_LRO; - case FRIBIDI_TYPE_RTL: return PANGO_BIDI_TYPE_R; - case FRIBIDI_TYPE_AL: return PANGO_BIDI_TYPE_AL; - case FRIBIDI_TYPE_RLE: return PANGO_BIDI_TYPE_RLE; - case FRIBIDI_TYPE_RLO: return PANGO_BIDI_TYPE_RLO; - case FRIBIDI_TYPE_PDF: return PANGO_BIDI_TYPE_PDF; - case FRIBIDI_TYPE_EN: return PANGO_BIDI_TYPE_EN; - case FRIBIDI_TYPE_ES: return PANGO_BIDI_TYPE_ES; - case FRIBIDI_TYPE_ET: return PANGO_BIDI_TYPE_ET; - case FRIBIDI_TYPE_AN: return PANGO_BIDI_TYPE_AN; - case FRIBIDI_TYPE_CS: return PANGO_BIDI_TYPE_CS; - case FRIBIDI_TYPE_NSM: return PANGO_BIDI_TYPE_NSM; - case FRIBIDI_TYPE_BN: return PANGO_BIDI_TYPE_BN; - case FRIBIDI_TYPE_BS: return PANGO_BIDI_TYPE_B; - case FRIBIDI_TYPE_SS: return PANGO_BIDI_TYPE_S; - case FRIBIDI_TYPE_WS: return PANGO_BIDI_TYPE_WS; - case FRIBIDI_TYPE_ON: return PANGO_BIDI_TYPE_ON; - default: - /* TODO - * This function has not been updated for latest FriBidi. - * Should add new types and / or deprecate this function. */ - return PANGO_BIDI_TYPE_ON; - } -} - -/* Some bidi-related functions */ - -/** - * pango_log2vis_get_embedding_levels: - * @text: the text to itemize. - * @length: the number of bytes (not characters) to process, or -1 - * if @text is nul-terminated and the length should be calculated. - * @pbase_dir: input base direction, and output resolved direction. - * - * This will return the bidirectional embedding levels of the input paragraph - * as defined by the Unicode Bidirectional Algorithm available at: - * - * http://www.unicode.org/reports/tr9/ - * - * If the input base direction is a weak direction, the direction of the - * characters in the text will determine the final resolved direction. - * - * Return value: a newly allocated array of embedding levels, one item per - * character (not byte), that should be freed using g_free. - * - * Since: 1.4 - */ -guint8 * -pango_log2vis_get_embedding_levels (const gchar *text, - int length, - PangoDirection *pbase_dir) -{ - glong n_chars, i; - guint8 *embedding_levels_list; - const gchar *p; - FriBidiParType fribidi_base_dir; - FriBidiCharType *bidi_types; -#ifdef USE_FRIBIDI_EX_API - FriBidiBracketType *bracket_types; -#endif - FriBidiLevel max_level; - FriBidiCharType ored_types = 0; - FriBidiCharType anded_strongs = FRIBIDI_TYPE_RLE; - - G_STATIC_ASSERT (sizeof (FriBidiLevel) == sizeof (guint8)); - G_STATIC_ASSERT (sizeof (FriBidiChar) == sizeof (gunichar)); - - switch (*pbase_dir) - { - case PANGO_DIRECTION_LTR: - case PANGO_DIRECTION_TTB_RTL: - fribidi_base_dir = FRIBIDI_PAR_LTR; - break; - case PANGO_DIRECTION_RTL: - case PANGO_DIRECTION_TTB_LTR: - fribidi_base_dir = FRIBIDI_PAR_RTL; - break; - case PANGO_DIRECTION_WEAK_RTL: - fribidi_base_dir = FRIBIDI_PAR_WRTL; - break; - case PANGO_DIRECTION_WEAK_LTR: - case PANGO_DIRECTION_NEUTRAL: - default: - fribidi_base_dir = FRIBIDI_PAR_WLTR; - break; - } - - if (length < 0) - length = strlen (text); - - n_chars = g_utf8_strlen (text, length); - - bidi_types = g_new (FriBidiCharType, n_chars); -#ifdef USE_FRIBIDI_EX_API - bracket_types = g_new (FriBidiBracketType, n_chars); -#endif - embedding_levels_list = g_new (guint8, n_chars); - - for (i = 0, p = text; p < text + length; p = g_utf8_next_char(p), i++) - { - gunichar ch = g_utf8_get_char (p); - FriBidiCharType char_type; - char_type = fribidi_get_bidi_type (ch); - bidi_types[i] = char_type; - ored_types |= char_type; - if (FRIBIDI_IS_STRONG (char_type)) - anded_strongs &= char_type; -#ifdef USE_FRIBIDI_EX_API - if (G_UNLIKELY(bidi_types[i] == FRIBIDI_TYPE_ON)) - bracket_types[i] = fribidi_get_bracket (ch); - else - bracket_types[i] = FRIBIDI_NO_BRACKET; -#endif - } - - /* Short-circuit (malloc-expensive) FriBidi call for unidirectional - * text. - * - * For details see: - * https://bugzilla.gnome.org/show_bug.cgi?id=590183 - */ - -#ifndef FRIBIDI_IS_ISOLATE -#define FRIBIDI_IS_ISOLATE(x) 0 -#endif - /* The case that all resolved levels will be ltr. - * No isolates, all strongs be LTR, there should be no Arabic numbers - * (or letters for that matter), and one of the following: - * - * o base_dir doesn't have an RTL taste. - * o there are letters, and base_dir is weak. - */ - if (!FRIBIDI_IS_ISOLATE (ored_types) && - !FRIBIDI_IS_RTL (ored_types) && - !FRIBIDI_IS_ARABIC (ored_types) && - (!FRIBIDI_IS_RTL (fribidi_base_dir) || - (FRIBIDI_IS_WEAK (fribidi_base_dir) && - FRIBIDI_IS_LETTER (ored_types)) - )) - { - /* all LTR */ - fribidi_base_dir = FRIBIDI_PAR_LTR; - memset (embedding_levels_list, 0, n_chars); - goto resolved; - } - /* The case that all resolved levels will be RTL is much more complex. - * No isolates, no numbers, all strongs are RTL, and one of - * the following: - * - * o base_dir has an RTL taste (may be weak). - * o there are letters, and base_dir is weak. - */ - else if (!FRIBIDI_IS_ISOLATE (ored_types) && - !FRIBIDI_IS_NUMBER (ored_types) && - FRIBIDI_IS_RTL (anded_strongs) && - (FRIBIDI_IS_RTL (fribidi_base_dir) || - (FRIBIDI_IS_WEAK (fribidi_base_dir) && - FRIBIDI_IS_LETTER (ored_types)) - )) - { - /* all RTL */ - fribidi_base_dir = FRIBIDI_PAR_RTL; - memset (embedding_levels_list, 1, n_chars); - goto resolved; - } - - -#ifdef USE_FRIBIDI_EX_API - max_level = fribidi_get_par_embedding_levels_ex (bidi_types, bracket_types, n_chars, - &fribidi_base_dir, - (FriBidiLevel*)embedding_levels_list); -#else - max_level = fribidi_get_par_embedding_levels (bidi_types, n_chars, - &fribidi_base_dir, - (FriBidiLevel*)embedding_levels_list); -#endif - - if (G_UNLIKELY(max_level == 0)) - { - /* fribidi_get_par_embedding_levels() failed. */ - memset (embedding_levels_list, 0, length); - } - -resolved: - g_free (bidi_types); - -#ifdef USE_FRIBIDI_EX_API - g_free (bracket_types); -#endif - - *pbase_dir = (fribidi_base_dir == FRIBIDI_PAR_LTR) ? PANGO_DIRECTION_LTR : PANGO_DIRECTION_RTL; - - return embedding_levels_list; -} - -/** - * pango_unichar_direction: - * @ch: a Unicode character - * - * Determines the inherent direction of a character; either - * %PANGO_DIRECTION_LTR, %PANGO_DIRECTION_RTL, or - * %PANGO_DIRECTION_NEUTRAL. - * - * This function is useful to categorize characters into left-to-right - * letters, right-to-left letters, and everything else. If full - * Unicode bidirectional type of a character is needed, - * pango_bidi_type_for_unichar() can be used instead. - * - * Return value: the direction of the character. - */ -PangoDirection -pango_unichar_direction (gunichar ch) -{ - FriBidiCharType fribidi_ch_type; - - G_STATIC_ASSERT (sizeof (FriBidiChar) == sizeof (gunichar)); - - fribidi_ch_type = fribidi_get_bidi_type (ch); - - if (!FRIBIDI_IS_STRONG (fribidi_ch_type)) - return PANGO_DIRECTION_NEUTRAL; - else if (FRIBIDI_IS_RTL (fribidi_ch_type)) - return PANGO_DIRECTION_RTL; - else - return PANGO_DIRECTION_LTR; -} - -/** - * pango_get_mirror_char: - * @ch: a Unicode character - * @mirrored_ch: location to store the mirrored character - * - * If @ch has the Unicode mirrored property and there is another Unicode - * character that typically has a glyph that is the mirror image of @ch's - * glyph, puts that character in the address pointed to by @mirrored_ch. - * - * Use g_unichar_get_mirror_char() instead; the docs for that function - * provide full details. - * - * Return value: %TRUE if @ch has a mirrored character and @mirrored_ch is - * filled in, %FALSE otherwise - **/ -gboolean -pango_get_mirror_char (gunichar ch, - gunichar *mirrored_ch) -{ - return g_unichar_get_mirror_char (ch, mirrored_ch); -} - diff --git a/pango/pangofc-shape.c b/pango/pangofc-shape.c index 53269d7..a59ca67 100644 --- a/pango/pangofc-shape.c +++ b/pango/pangofc-shape.c @@ -380,10 +380,8 @@ _pango_fc_shape (PangoFont *font, fc_font->is_hinted ? ft_face->size->metrics.x_ppem : 0, fc_font->is_hinted ? ft_face->size->metrics.y_ppem : 0); - if (key) - { - variations = pango_fc_font_key_get_variations (key); - if (variations) + variations = pango_fc_font_key_get_variations (key); + if (variations) { guint n_variations; hb_variation_t *hb_variations; @@ -393,7 +391,6 @@ _pango_fc_shape (PangoFont *font, g_free (hb_variations); } - } hb_buffer = acquire_buffer (&free_buffer); diff --git a/pango/pangofc-shape.c.crash b/pango/pangofc-shape.c.crash deleted file mode 100644 index a59ca67..0000000 --- a/pango/pangofc-shape.c.crash +++ /dev/null @@ -1,544 +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 "pangofc-private.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); -} - -typedef struct _PangoFcHbContext { - FT_Face ft_face; - PangoFcFont *fc_font; - gboolean vertical; - double x_scale, y_scale; /* CTM scales. */ -} PangoFcHbContext; - -static hb_bool_t -pango_fc_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) -{ - PangoFcHbContext *context = (PangoFcHbContext *) font_data; - PangoFcFont *fc_font = context->fc_font; - - *glyph = pango_fc_font_get_glyph (fc_font, unicode); - if (G_LIKELY (*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_fc_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) -{ - PangoFcHbContext *context = (PangoFcHbContext *) font_data; - FT_Face ft_face = context->ft_face; - unsigned int g; - - g = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector); - - if (G_UNLIKELY (!g)) - return FALSE; - - *glyph = g; - return TRUE; -} - -static hb_bool_t -pango_fc_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) -{ - return FALSE; -#if 0 - FT_Face ft_face = (FT_Face) font_data; - int load_flags = FT_LOAD_DEFAULT; - - /* TODO: load_flags, embolden, etc */ - - if (HB_UNLIKELY (FT_Load_Glyph (ft_face, glyph, load_flags))) - return FALSE; - - if (HB_UNLIKELY (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE)) - return FALSE; - - if (HB_UNLIKELY (point_index >= (unsigned int) ft_face->glyph->outline.n_points)) - return FALSE; - - *x = ft_face->glyph->outline.points[point_index].x; - *y = ft_face->glyph->outline.points[point_index].y; - - return TRUE; -#endif -} - -static hb_position_t -pango_fc_hb_font_get_glyph_advance (hb_font_t *font, void *font_data, - hb_codepoint_t glyph, - void *user_data G_GNUC_UNUSED) -{ - PangoFcHbContext *context = (PangoFcHbContext *) font_data; - PangoFcFont *fc_font = context->fc_font; - PangoRectangle logical; - - pango_font_get_glyph_extents ((PangoFont *) fc_font, glyph, NULL, &logical); - - return logical.width; -} - -static hb_bool_t -pango_fc_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) -{ - PangoFcHbContext *context = (PangoFcHbContext *) font_data; - PangoFcFont *fc_font = context->fc_font; - PangoRectangle ink; - - pango_font_get_glyph_extents ((PangoFont *) fc_font, glyph, &ink, NULL); - - if (G_LIKELY (!context->vertical)) { - extents->x_bearing = ink.x; - extents->y_bearing = ink.y; - extents->width = ink.width; - extents->height = ink.height; - } else { - /* XXX */ - extents->x_bearing = ink.x; - extents->y_bearing = ink.y; - extents->width = ink.height; - extents->height = ink.width; - } - - return TRUE; -} - -static hb_bool_t -pango_fc_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) -{ - PangoFcHbContext *context = (PangoFcHbContext *) font_data; - FT_Face ft_face = context->ft_face; - int load_flags = FT_LOAD_DEFAULT; - - if (!context->vertical) return TRUE; - - if (FT_Load_Glyph (ft_face, glyph, load_flags)) - return FALSE; - - /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates - * have a Y growing upward. Hence the extra negations. */ - *x = -PANGO_UNITS_26_6 (ft_face->glyph->metrics.horiBearingX - ft_face->glyph->metrics.vertBearingX); - *y = +PANGO_UNITS_26_6 (ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY)); - - return TRUE; -} - -static hb_bool_t -pango_fc_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) -{ - PangoFcHbContext *context = (PangoFcHbContext *) font_data; - FT_Face ft_face = context->ft_face; - int load_flags = FT_LOAD_DEFAULT; - - /* pangocairo-fc configures font in vertical origin for vertical writing. */ - if (context->vertical) return TRUE; - - if (FT_Load_Glyph (ft_face, glyph, load_flags)) - return FALSE; - - /* Note: FreeType's vertical metrics grows downward while other FreeType coordinates - * have a Y growing upward. Hence the extra negation. */ - *x = PANGO_UNITS_26_6 (ft_face->glyph->metrics.horiBearingX - ft_face->glyph->metrics.vertBearingX); - *y = PANGO_UNITS_26_6 (ft_face->glyph->metrics.horiBearingY - (-ft_face->glyph->metrics.vertBearingY)); - - /* XXX */ - - return TRUE; -} - - -static hb_position_t -pango_fc_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) -{ - PangoFcHbContext *context = (PangoFcHbContext *) font_data; - FT_Face ft_face = context->ft_face; - FT_Vector kerning; - - if (FT_Get_Kerning (ft_face, left_glyph, right_glyph, FT_KERNING_DEFAULT, &kerning)) - return 0; - - return PANGO_UNITS_26_6 (kerning.x * context->x_scale); -} - -static hb_font_funcs_t * -pango_fc_get_hb_font_funcs (void) -{ - static hb_font_funcs_t *funcs; - - if (G_UNLIKELY (!funcs)) { - funcs = hb_font_funcs_create (); - hb_font_funcs_set_nominal_glyph_func (funcs, pango_fc_hb_font_get_nominal_glyph, NULL, NULL); - hb_font_funcs_set_variation_glyph_func (funcs, pango_fc_hb_font_get_variation_glyph, NULL, NULL); - hb_font_funcs_set_glyph_h_advance_func (funcs, pango_fc_hb_font_get_glyph_advance, NULL, NULL); - hb_font_funcs_set_glyph_v_advance_func (funcs, pango_fc_hb_font_get_glyph_advance, NULL, NULL); - hb_font_funcs_set_glyph_h_origin_func (funcs, pango_fc_hb_font_get_glyph_h_origin, NULL, NULL); - hb_font_funcs_set_glyph_v_origin_func (funcs, pango_fc_hb_font_get_glyph_v_origin, NULL, NULL); - hb_font_funcs_set_glyph_h_kerning_func (funcs, pango_fc_hb_font_get_h_kerning, NULL, NULL); - /* Don't need v_kerning. */ - hb_font_funcs_set_glyph_extents_func (funcs, pango_fc_hb_font_get_glyph_extents, NULL, NULL); - hb_font_funcs_set_glyph_contour_point_func (funcs, pango_fc_hb_font_get_glyph_contour_point, NULL, NULL); - /* Don't need glyph_name / glyph_from_name */ - } - - return funcs; -} - -static void -parse_variations (const char *variations, - hb_variation_t **hb_variations, - guint *n_variations) -{ - guint n; - hb_variation_t *var; - int i; - const char *p; - - n = 1; - for (i = 0; variations[i]; i++) - { - if (variations[i] == ',') - n++; - } - - var = g_new (hb_variation_t, n); - - p = variations; - n = 0; - while (p && *p) - { - char *end = strchr (p, ','); - if (hb_variation_from_string (p, end ? end - p: -1, &var[n])) - n++; - p = end ? end + 1 : NULL; - } - - *hb_variations = var; - *n_variations = n; -} - -void -_pango_fc_shape (PangoFont *font, - const char *item_text, - unsigned int item_length, - const PangoAnalysis *analysis, - PangoGlyphString *glyphs, - const char *paragraph_text, - unsigned int paragraph_length) -{ - PangoFcHbContext context; - PangoFcFont *fc_font; - PangoFcFontKey *key; - FT_Face ft_face; - hb_face_t *hb_face; - hb_font_t *hb_font; - hb_buffer_t *hb_buffer; - 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; - double x_scale_inv, y_scale_inv; - PangoGlyphInfo *infos; - const char *variations; - - g_return_if_fail (font != NULL); - g_return_if_fail (analysis != NULL); - - fc_font = PANGO_FC_FONT (font); - ft_face = pango_fc_font_lock_face (fc_font); - if (!ft_face) - return; - - /* TODO: Cache hb_font? */ - - x_scale_inv = y_scale_inv = 1.0; - key = _pango_fc_font_get_font_key (fc_font); - if (key) - { - const PangoMatrix *matrix = pango_fc_font_key_get_matrix (key); - pango_matrix_get_font_scale_factors (matrix, &x_scale_inv, &y_scale_inv); - } - if (PANGO_GRAVITY_IS_IMPROPER (analysis->gravity)) - { - x_scale_inv = -x_scale_inv; - y_scale_inv = -y_scale_inv; - } - context.x_scale = 1. / x_scale_inv; - context.y_scale = 1. / y_scale_inv; - context.ft_face = ft_face; - context.fc_font = fc_font; - context.vertical = PANGO_GRAVITY_IS_VERTICAL (analysis->gravity); - hb_face = hb_ft_face_create_cached (ft_face); - hb_font = hb_font_create (hb_face); - hb_font_set_funcs (hb_font, - pango_fc_get_hb_font_funcs (), - &context, - NULL); - hb_font_set_scale (hb_font, - +(((gint64) ft_face->size->metrics.x_scale * ft_face->units_per_EM) >> 12) * context.x_scale, - -(((gint64) ft_face->size->metrics.y_scale * ft_face->units_per_EM) >> 12) * context.y_scale); - hb_font_set_ppem (hb_font, - fc_font->is_hinted ? ft_face->size->metrics.x_ppem : 0, - fc_font->is_hinted ? ft_face->size->metrics.y_ppem : 0); - - variations = pango_fc_font_key_get_variations (key); - if (variations) - { - guint n_variations; - hb_variation_t *hb_variations; - - parse_variations (variations, &hb_variations, &n_variations); - hb_font_set_variations (hb_font, hb_variations, n_variations); - - g_free (hb_variations); - } - - 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); - - /* 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_FLAG_BOT | HB_BUFFER_FLAG_EOT); - - hb_buffer_add_utf8 (hb_buffer, paragraph_text, paragraph_length, item_offset, item_length); - - /* Setup features from fontconfig pattern. */ - if (fc_font->font_pattern) - { - char *s; - while (num_features < G_N_ELEMENTS (features) && - FcResultMatch == FcPatternGetString (fc_font->font_pattern, - PANGO_FC_FONT_FEATURES, - num_features, - (FcChar8 **) &s)) - { - gboolean ret = hb_feature_from_string (s, -1, &features[num_features]); - features[num_features].start = 0; - features[num_features].end = (unsigned int) -1; - if (ret) - num_features++; - } - } - - if (analysis->extra_attrs) - { - GSList *tmp_attrs; - - for (tmp_attrs = analysis->extra_attrs; tmp_attrs && num_features < G_N_ELEMENTS (features); tmp_attrs = tmp_attrs->next) - { - if (((PangoAttribute *) tmp_attrs->data)->klass->type == PANGO_ATTR_FONT_FEATURES) - { - const PangoAttrFontFeatures *fattr = (const PangoAttrFontFeatures *) tmp_attrs->data; - const gchar *feat; - const gchar *end; - int len; - - feat = fattr->features; - - while (feat != NULL && num_features < G_N_ELEMENTS (features)) - { - end = strchr (feat, ','); - if (end) - len = end - feat; - else - len = -1; - - if (hb_feature_from_string (feat, len, &features[num_features])) - num_features++; - - if (end == NULL) - break; - - feat = end + 1; - } - } - } - } - - 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 (context.vertical) - 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++; - } - - if (fc_font->is_hinted) - { - if (context.x_scale == 1.0 && context.y_scale == 1.0) - { - for (i = 0; i < num_glyphs; i++) - infos[i].geometry.width = PANGO_UNITS_ROUND (infos[i].geometry.width); - } - else - { -#if 0 - if (context.vertical) - { - /* XXX */ - double tmp = x_scale; - x_scale = y_scale; - y_scale = -tmp; - } -#endif -#define HINT(value, scale_inv, scale) (PANGO_UNITS_ROUND ((int) ((value) * scale)) * scale_inv) -#define HINT_X(value) HINT ((value), context.x_scale, x_scale_inv) -#define HINT_Y(value) HINT ((value), context.y_scale, y_scale_inv) - for (i = 0; i < num_glyphs; i++) - { - infos[i].geometry.width = HINT_X (infos[i].geometry.width); - infos[i].geometry.x_offset = HINT_X (infos[i].geometry.x_offset); - infos[i].geometry.y_offset = HINT_Y (infos[i].geometry.y_offset); - } -#undef HINT_Y -#undef HINT_X -#undef HINT - } - } - - release_buffer (hb_buffer, free_buffer); - hb_font_destroy (hb_font); - hb_face_destroy (hb_face); - pango_fc_font_unlock_face (fc_font); -}