summaryrefslogtreecommitdiff
path: root/pango
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2019-07-18 23:17:32 +0000
committerMatthias Clasen <mclasen@redhat.com>2019-07-18 23:17:32 +0000
commitfdd9e9e707e42131e7749d8674c59f57e0923a35 (patch)
tree736a19c4682b2de18cdc6f96feaa14cd3258cf7f /pango
parentbe4d29953196744ab87b7e27be21a60131b109d1 (diff)
parent2a08070eb8db3132bea4c3d2ecd49e40c293e1a5 (diff)
downloadpango-fdd9e9e707e42131e7749d8674c59f57e0923a35.tar.gz
Merge branch 'kill-ft-face' into 'master'
Use harfbuzz for font metrics and glyph lookup See merge request GNOME/pango!58
Diffstat (limited to 'pango')
-rw-r--r--pango/fonts.c46
-rw-r--r--pango/pango-font-private.h6
-rw-r--r--pango/pango-font.h3
-rw-r--r--pango/pangocairo-fcfont.c2
-rw-r--r--pango/pangocoretext.c24
-rw-r--r--pango/pangofc-font-private.h2
-rw-r--r--pango/pangofc-font.c435
-rw-r--r--pango/pangofc-font.h9
-rw-r--r--pango/pangofc-fontmap.c78
-rw-r--r--pango/pangofc-fontmap.h6
-rw-r--r--pango/pangofc-private.h24
-rw-r--r--pango/pangofc-shape.c386
-rw-r--r--pango/pangoft2.c6
-rw-r--r--pango/pangowin32.c85
-rw-r--r--pango/pangoxft-font.c7
15 files changed, 456 insertions, 663 deletions
diff --git a/pango/fonts.c b/pango/fonts.c
index fafd6a2d..4ba9d3fe 100644
--- a/pango/fonts.c
+++ b/pango/fonts.c
@@ -1617,11 +1617,29 @@ pango_parse_stretch (const char *str,
* PangoFont
*/
-G_DEFINE_ABSTRACT_TYPE (PangoFont, pango_font, G_TYPE_OBJECT)
+typedef struct {
+ hb_font_t *hb_font;
+} PangoFontPrivate;
+
+G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (PangoFont, pango_font, G_TYPE_OBJECT)
+
+static void
+pango_font_finalize (GObject *object)
+{
+ PangoFont *font = PANGO_FONT (object);
+ PangoFontPrivate *priv = pango_font_get_instance_private (font);
+
+ hb_font_destroy (priv->hb_font);
+
+ G_OBJECT_CLASS (pango_font_parent_class)->finalize (object);
+}
static void
pango_font_class_init (PangoFontClass *class G_GNUC_UNUSED)
{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ object_class->finalize = pango_font_finalize;
}
static void
@@ -1838,6 +1856,32 @@ pango_font_get_font_map (PangoFont *font)
return NULL;
}
+/**
+ * pango_font_get_hb_font:
+ * @font: a #PangoFont
+ *
+ * Get a hb_font_t object backing this font.
+ *
+ * Returns: (transfer none) (nullable): the hb_font_t object backing the
+ * font, or %NULL if the font does not have one
+ *
+ * Since: 1.44
+ */
+hb_font_t *
+pango_font_get_hb_font (PangoFont *font)
+{
+ PangoFontPrivate *priv = pango_font_get_instance_private (font);
+
+ g_return_val_if_fail (PANGO_IS_FONT (font), NULL);
+
+ if (priv->hb_font)
+ return priv->hb_font;
+
+ priv->hb_font = PANGO_FONT_GET_CLASS (font)->create_hb_font (font);
+
+ return priv->hb_font;
+}
+
G_DEFINE_BOXED_TYPE (PangoFontMetrics, pango_font_metrics,
pango_font_metrics_ref,
pango_font_metrics_unref);
diff --git a/pango/pango-font-private.h b/pango/pango-font-private.h
index be399d7d..029bef99 100644
--- a/pango/pango-font-private.h
+++ b/pango/pango-font-private.h
@@ -179,11 +179,7 @@ struct _PangoFontClass
hb_feature_t *features,
guint len,
guint *num_features);
-
- /*< private >*/
-
- /* Padding for future expansion */
- void (*_pango_reserved1) (void);
+ hb_font_t * (*create_hb_font) (PangoFont *font);
};
/* used for very rare and miserable situtations that we cannot even
diff --git a/pango/pango-font.h b/pango/pango-font.h
index 5e49d266..cec7efc6 100644
--- a/pango/pango-font.h
+++ b/pango/pango-font.h
@@ -26,6 +26,7 @@
#include <pango/pango-types.h>
#include <glib-object.h>
+#include <hb.h>
G_BEGIN_DECLS
@@ -492,6 +493,8 @@ void pango_font_get_features (PangoFont *font,
hb_feature_t *features,
guint len,
guint *num_features);
+PANGO_AVAILABLE_IN_1_44
+hb_font_t * pango_font_get_hb_font (PangoFont *font);
/**
diff --git a/pango/pangocairo-fcfont.c b/pango/pangocairo-fcfont.c
index 0019f83a..9c450317 100644
--- a/pango/pangocairo-fcfont.c
+++ b/pango/pangocairo-fcfont.c
@@ -118,7 +118,7 @@ pango_cairo_fc_font_get_glyph_extents (PangoFont *font,
logical_rect);
}
-static FT_Face
+static gpointer
pango_cairo_fc_font_lock_face (PangoFcFont *font)
{
PangoCairoFcFont *cffont = (PangoCairoFcFont *) (font);
diff --git a/pango/pangocoretext.c b/pango/pangocoretext.c
index a6eaa1fc..70fd67d4 100644
--- a/pango/pangocoretext.c
+++ b/pango/pangocoretext.c
@@ -32,6 +32,7 @@
#include "pangocoretext.h"
#include "pangocoretext-private.h"
+#include <harfbuzz/hb-coretext.h>
struct _PangoCoreTextFontPrivate
{
@@ -208,6 +209,28 @@ pango_core_text_font_get_font_map (PangoFont *font)
return ctfont->priv->fontmap;
}
+static hb_font_t *
+pango_core_text_font_create_hb_font (PangoFont *font)
+{
+ PangoCoreTextFont *ctfont = (PangoCoreTextFont *)font;
+
+ if (ctfont->priv->font_ref)
+ {
+ hb_font_t *hb_font;
+ int size;
+
+ size = pango_core_text_font_key_get_size (ctfont->priv->key);
+ hb_font = hb_coretext_font_create (ctfont->priv->font_ref);
+ hb_font_set_scale (hb_font, size, size);
+
+ hb_font_make_immutable (hb_font);
+
+ return hb_font;
+ }
+
+ return hb_font_get_empty ();
+}
+
static void
pango_core_text_font_init (PangoCoreTextFont *ctfont)
{
@@ -227,6 +250,7 @@ pango_core_text_font_class_init (PangoCoreTextFontClass *class)
font_class->get_coverage = pango_core_text_font_get_coverage;
font_class->find_shaper = pango_core_text_font_find_shaper;
font_class->get_font_map = pango_core_text_font_get_font_map;
+ font_class->create_hb_font = pango_core_text_font_create_hb_font;
}
void
diff --git a/pango/pangofc-font-private.h b/pango/pangofc-font-private.h
index 07b088b3..91f89207 100644
--- a/pango/pangofc-font-private.h
+++ b/pango/pangofc-font-private.h
@@ -109,7 +109,7 @@ struct _PangoFcFontClass
PangoFontClass parent_class;
/*< public >*/
- FT_Face (*lock_face) (PangoFcFont *font);
+ gpointer (*lock_face) (PangoFcFont *font);
void (*unlock_face) (PangoFcFont *font);
gboolean (*has_char) (PangoFcFont *font,
gunichar wc);
diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c
index 870fd935..76afdf7e 100644
--- a/pango/pangofc-font.c
+++ b/pango/pangofc-font.c
@@ -46,9 +46,7 @@
#include "pango-layout.h"
#include "pango-impl-utils.h"
-#include <fontconfig/fcfreetype.h>
-
-#include FT_TRUETYPE_TABLES_H
+#include <harfbuzz/hb-ot.h>
enum {
PROP_0,
@@ -62,7 +60,6 @@ struct _PangoFcFontPrivate
{
PangoFcDecoder *decoder;
PangoFcFontKey *key;
- PangoFcCmapCache *cmap_cache;
};
static gboolean pango_fc_font_real_has_char (PangoFcFont *font,
@@ -93,6 +90,7 @@ static void pango_fc_font_get_features (PangoFont *font,
hb_feature_t *features,
guint len,
guint *num_features);
+static hb_font_t * pango_fc_font_create_hb_font (PangoFont *font);
#define PANGO_FC_FONT_LOCK_FACE(font) (PANGO_FC_FONT_GET_CLASS (font)->lock_face (font))
#define PANGO_FC_FONT_UNLOCK_FACE(font) (PANGO_FC_FONT_GET_CLASS (font)->unlock_face (font))
@@ -120,6 +118,8 @@ pango_fc_font_class_init (PangoFcFontClass *class)
font_class->get_metrics = pango_fc_font_get_metrics;
font_class->get_font_map = pango_fc_font_get_font_map;
font_class->get_features = pango_fc_font_get_features;
+ font_class->create_hb_font = pango_fc_font_create_hb_font;
+ font_class->get_features = pango_fc_font_get_features;
g_object_class_install_property (object_class, PROP_PATTERN,
g_param_spec_pointer ("pattern",
@@ -173,9 +173,6 @@ pango_fc_font_finalize (GObject *object)
if (priv->decoder)
_pango_fc_font_set_decoder (fcfont, NULL);
- if (priv->cmap_cache)
- _pango_fc_cmap_cache_unref (priv->cmap_cache);
-
G_OBJECT_CLASS (pango_fc_font_parent_class)->finalize (object);
}
@@ -198,16 +195,8 @@ pattern_is_transformed (FcPattern *pattern)
if (FcPatternGetMatrix (pattern, FC_MATRIX, 0, &fc_matrix) == FcResultMatch)
{
- FT_Matrix ft_matrix;
-
- ft_matrix.xx = 0x10000L * fc_matrix->xx;
- ft_matrix.yy = 0x10000L * fc_matrix->yy;
- ft_matrix.xy = 0x10000L * fc_matrix->xy;
- ft_matrix.yx = 0x10000L * fc_matrix->yx;
-
- return ((ft_matrix.xy | ft_matrix.yx) != 0 ||
- ft_matrix.xx != 0x10000L ||
- ft_matrix.yy != 0x10000L);
+ return fc_matrix->xx != 1 || fc_matrix->xy != 0 ||
+ fc_matrix->yx != 0 || fc_matrix->yy != 1;
}
else
return FALSE;
@@ -384,135 +373,55 @@ static void
get_face_metrics (PangoFcFont *fcfont,
PangoFontMetrics *metrics)
{
- FT_Face face = PANGO_FC_FONT_LOCK_FACE (fcfont);
+ hb_font_t *hb_font = pango_font_get_hb_font (PANGO_FONT (fcfont));
+ hb_font_extents_t extents;
+
FcMatrix *fc_matrix;
- FT_Matrix ft_matrix;
- TT_OS2 *os2;
gboolean have_transform = FALSE;
- if (G_UNLIKELY (!face))
- {
- metrics->descent = 0;
- metrics->ascent = PANGO_SCALE * PANGO_UNKNOWN_GLYPH_HEIGHT;
- metrics->height = metrics->ascent;
- metrics->underline_thickness = PANGO_SCALE;
- metrics->underline_position = - PANGO_SCALE;
- metrics->strikethrough_thickness = PANGO_SCALE;
- metrics->strikethrough_position = PANGO_SCALE * (PANGO_UNKNOWN_GLYPH_HEIGHT/2);
- return;
- }
+ hb_font_get_extents_for_direction (hb_font, HB_DIRECTION_LTR, &extents);
if (FcPatternGetMatrix (fcfont->font_pattern,
FC_MATRIX, 0, &fc_matrix) == FcResultMatch)
{
- ft_matrix.xx = 0x10000L * fc_matrix->xx;
- ft_matrix.yy = 0x10000L * fc_matrix->yy;
- ft_matrix.xy = 0x10000L * fc_matrix->xy;
- ft_matrix.yx = 0x10000L * fc_matrix->yx;
-
- have_transform = (ft_matrix.xx != 0x10000 || ft_matrix.xy != 0 ||
- ft_matrix.yx != 0 || ft_matrix.yy != 0x10000);
+ have_transform = (fc_matrix->xx != 1 || fc_matrix->xy != 0 ||
+ fc_matrix->yx != 0 || fc_matrix->yy != 1);
}
if (have_transform)
{
- FT_Vector vector;
-
- vector.x = 0;
- vector.y = face->size->metrics.descender;
- FT_Vector_Transform (&vector, &ft_matrix);
- metrics->descent = - PANGO_UNITS_26_6 (vector.y);
-
- vector.x = 0;
- vector.y = face->size->metrics.ascender;
- FT_Vector_Transform (&vector, &ft_matrix);
- metrics->ascent = PANGO_UNITS_26_6 (vector.y);
-
- vector.x = 0;
- vector.y = face->size->metrics.height;
- FT_Vector_Transform (&vector, &ft_matrix);
- metrics->height = PANGO_UNITS_26_6 (vector.y);
- }
- else if (fcfont->is_hinted ||
- (face->face_flags & FT_FACE_FLAG_SCALABLE) == 0)
- {
- metrics->descent = - PANGO_UNITS_26_6 (face->size->metrics.descender);
- metrics->ascent = PANGO_UNITS_26_6 (face->size->metrics.ascender);
- metrics->height = PANGO_UNITS_26_6 (face->size->metrics.height);
+ metrics->descent = - extents.descender * fc_matrix->yy;
+ metrics->ascent = extents.ascender * fc_matrix->yy;
+ metrics->height = (extents.ascender - extents.descender + extents.line_gap) * fc_matrix->yy;
}
else
{
- FT_Fixed ascender, descender, height;
-
- descender = FT_MulFix (face->descender, face->size->metrics.y_scale);
- metrics->descent = - PANGO_UNITS_26_6 (descender);
-
- ascender = FT_MulFix (face->ascender, face->size->metrics.y_scale);
- metrics->ascent = PANGO_UNITS_26_6 (ascender);
-
- height = FT_MulFix (face->height, face->size->metrics.y_scale);
- metrics->height = PANGO_UNITS_26_6 (height);
- }
-
- metrics->underline_thickness = 0;
- metrics->underline_position = 0;
-
- {
- FT_Fixed ft_thickness, ft_position;
-
- ft_thickness = FT_MulFix (face->underline_thickness, face->size->metrics.y_scale);
- metrics->underline_thickness = PANGO_UNITS_26_6 (ft_thickness);
-
- ft_position = FT_MulFix (face->underline_position, face->size->metrics.y_scale);
- metrics->underline_position = PANGO_UNITS_26_6 (ft_position);
- }
-
- if (metrics->underline_thickness == 0 || metrics->underline_position == 0)
- {
- metrics->underline_thickness = (PANGO_SCALE * face->size->metrics.y_ppem) / 14;
- metrics->underline_position = - metrics->underline_thickness;
+ metrics->descent = - extents.descender;
+ metrics->ascent = extents.ascender;
+ metrics->height = extents.ascender - extents.descender + extents.line_gap;
}
+ metrics->underline_thickness = PANGO_SCALE;
+ metrics->underline_position = - PANGO_SCALE;
+ metrics->strikethrough_thickness = PANGO_SCALE;
+ metrics->strikethrough_position = metrics->ascent / 2;
- metrics->strikethrough_thickness = 0;
- metrics->strikethrough_position = 0;
-
- os2 = FT_Get_Sfnt_Table (face, ft_sfnt_os2);
- if (os2 && os2->version != 0xFFFF)
- {
- FT_Fixed ft_thickness, ft_position;
+ /* FIXME: use the right hb version */
+#if HB_VERSION_ATLEAST(2,5,4)
+ hb_position_t position;
- ft_thickness = FT_MulFix (os2->yStrikeoutSize, face->size->metrics.y_scale);
- metrics->strikethrough_thickness = PANGO_UNITS_26_6 (ft_thickness);
+ if (hb_ot_metrics_get_position (hb_font, HB_OT_METRICS_UNDERLINE_SIZE, &position))
+ metrics->underline_thickness = position;
- ft_position = FT_MulFix (os2->yStrikeoutPosition, face->size->metrics.y_scale);
- metrics->strikethrough_position = PANGO_UNITS_26_6 (ft_position);
- }
-
- if (metrics->strikethrough_thickness == 0 || metrics->strikethrough_position == 0)
- {
- metrics->strikethrough_thickness = metrics->underline_thickness;
- metrics->strikethrough_position = (PANGO_SCALE * face->size->metrics.y_ppem) / 4;
- }
-
-
- /* If hinting is on for this font, quantize the underline and strikethrough position
- * to integer values.
- */
- if (fcfont->is_hinted)
- {
- pango_quantize_line_geometry (&metrics->underline_thickness,
- &metrics->underline_position);
- pango_quantize_line_geometry (&metrics->strikethrough_thickness,
- &metrics->strikethrough_position);
-
- /* Quantizing may have pushed underline_position to 0. Not good */
- if (metrics->underline_position == 0)
- metrics->underline_position = - metrics->underline_thickness;
- }
+ if (hb_ot_metrics_get_position (hb_font, HB_OT_METRICS_UNDERLINE_OFFSET, &position))
+ metrics->underline_position = position;
+ if (hb_ot_metrics_get_position (hb_font, HB_OT_METRICS_STRIKEOUT_SIZE, &position))
+ metrics->strikethrough_thickness = position;
- PANGO_FC_FONT_UNLOCK_FACE (fcfont);
+ if (hb_ot_metrics_get_position (hb_font, HB_OT_METRICS_STRIKEOUT_OFFSET, &position))
+ metrics->strikethrough_position = position;
+#endif
}
PangoFontMetrics *
@@ -660,50 +569,12 @@ static guint
pango_fc_font_real_get_glyph (PangoFcFont *font,
gunichar wc)
{
- PangoFcFontPrivate *priv = font->priv;
- FT_Face face;
- FT_UInt index;
-
- guint idx;
- PangoFcCmapCacheEntry *entry;
-
-
- if (G_UNLIKELY (priv->cmap_cache == NULL))
- {
- PangoFcFontMap *fontmap = g_weak_ref_get ((GWeakRef *) &font->fontmap);
- if (G_UNLIKELY (!fontmap))
- return 0;
-
- priv->cmap_cache = _pango_fc_font_map_get_cmap_cache (fontmap, font);
-
- g_object_unref (fontmap);
-
- if (G_UNLIKELY (!priv->cmap_cache))
- return 0;
- }
-
- idx = wc & CMAP_CACHE_MASK;
- entry = priv->cmap_cache->entries + idx;
-
- if (entry->ch != wc)
- {
- face = PANGO_FC_FONT_LOCK_FACE (font);
- if (G_LIKELY (face))
- {
- index = FcFreeTypeCharIndex (face, wc);
- if (index > (FT_UInt)face->num_glyphs)
- index = 0;
-
- PANGO_FC_FONT_UNLOCK_FACE (font);
- }
- else
- index = 0;
+ hb_font_t *hb_font = pango_font_get_hb_font (PANGO_FONT (font));
+ hb_codepoint_t glyph = PANGO_GET_UNKNOWN_GLYPH (wc);
- entry->ch = wc;
- entry->glyph = index;
- }
+ hb_font_get_nominal_glyph (hb_font, wc, &glyph);
- return entry->glyph;
+ return glyph;
}
/**
@@ -717,8 +588,9 @@ pango_fc_font_real_get_glyph (PangoFcFont *font,
* Return value: the FreeType <type>FT_Face</type> associated with @font.
*
* Since: 1.4
+ * Deprecated: 1.44: Use pango_font_get_hb_font() instead
**/
-FT_Face
+gpointer
pango_fc_font_lock_face (PangoFcFont *font)
{
g_return_val_if_fail (PANGO_IS_FC_FONT (font), NULL);
@@ -734,6 +606,7 @@ pango_fc_font_lock_face (PangoFcFont *font)
* pango_fc_font_lock_face().
*
* Since: 1.4
+ * Deprecated: 1.44: Use pango_font_get_hb_font() instead
**/
void
pango_fc_font_unlock_face (PangoFcFont *font)
@@ -921,27 +794,9 @@ _pango_fc_font_set_font_key (PangoFcFont *fcfont,
priv->key = key;
}
-static FT_Glyph_Metrics *
-get_per_char (FT_Face face,
- FT_Int32 load_flags,
- PangoGlyph glyph)
-{
- FT_Error error;
- FT_Glyph_Metrics *result;
-
- error = FT_Load_Glyph (face, glyph, load_flags);
- if (error == FT_Err_Ok)
- result = &face->glyph->metrics;
- else
- result = NULL;
-
- return result;
-}
-
/**
* pango_fc_font_get_raw_extents:
* @fcfont: a #PangoFcFont
- * @load_flags: flags to pass to FT_Load_Glyph()
* @glyph: the glyph index to load
* @ink_rect: (out) (optional): location to store ink extents of the
* glyph, or %NULL
@@ -962,81 +817,62 @@ get_per_char (FT_Face face,
**/
void
pango_fc_font_get_raw_extents (PangoFcFont *fcfont,
- FT_Int32 load_flags,
PangoGlyph glyph,
PangoRectangle *ink_rect,
PangoRectangle *logical_rect)
{
- FT_Glyph_Metrics *gm;
- FT_Face face;
-
g_return_if_fail (PANGO_IS_FC_FONT (fcfont));
- face = PANGO_FC_FONT_LOCK_FACE (fcfont);
- if (G_UNLIKELY (!face))
- {
- /* Get generic unknown-glyph extents. */
- pango_font_get_glyph_extents (NULL, glyph, ink_rect, logical_rect);
- return;
- }
-
if (glyph == PANGO_GLYPH_EMPTY)
- gm = NULL;
- else
- gm = get_per_char (face, load_flags, glyph);
-
- if (gm)
{
if (ink_rect)
{
- ink_rect->x = PANGO_UNITS_26_6 (gm->horiBearingX);
- ink_rect->width = PANGO_UNITS_26_6 (gm->width);
- ink_rect->y = -PANGO_UNITS_26_6 (gm->horiBearingY);
- ink_rect->height = PANGO_UNITS_26_6 (gm->height);
+ ink_rect->x = 0;
+ ink_rect->width = 0;
+ ink_rect->y = 0;
+ ink_rect->height = 0;
}
if (logical_rect)
{
logical_rect->x = 0;
- logical_rect->width = PANGO_UNITS_26_6 (gm->horiAdvance);
- if (fcfont->is_hinted ||
- (face->face_flags & FT_FACE_FLAG_SCALABLE) == 0)
- {
- logical_rect->y = - PANGO_UNITS_26_6 (face->size->metrics.ascender);
- logical_rect->height = PANGO_UNITS_26_6 (face->size->metrics.ascender - face->size->metrics.descender);
- }
- else
- {
- FT_Fixed ascender, descender;
-
- ascender = FT_MulFix (face->ascender, face->size->metrics.y_scale);
- descender = FT_MulFix (face->descender, face->size->metrics.y_scale);
-
- logical_rect->y = - PANGO_UNITS_26_6 (ascender);
- logical_rect->height = PANGO_UNITS_26_6 (ascender - descender);
- }
+ logical_rect->width = 0;
+ logical_rect->y = 0;
+ logical_rect->height = 0;
}
}
else
{
+ hb_font_t *hb_font = pango_font_get_hb_font (PANGO_FONT (fcfont));
+ hb_glyph_extents_t extents;
+ hb_font_extents_t font_extents;
+
+ hb_font_get_glyph_extents (hb_font, glyph, &extents);
+ hb_font_get_extents_for_direction (hb_font, HB_DIRECTION_LTR, &font_extents);
+
if (ink_rect)
{
- ink_rect->x = 0;
- ink_rect->width = 0;
- ink_rect->y = 0;
- ink_rect->height = 0;
+ ink_rect->x = extents.x_bearing;
+ ink_rect->width = extents.width;
+ ink_rect->y = -extents.y_bearing;
+ ink_rect->height = extents.height;
}
if (logical_rect)
{
+ hb_position_t x, y;
+
+ hb_font_get_glyph_advance_for_direction (hb_font,
+ glyph,
+ HB_DIRECTION_LTR,
+ &x, &y);
+
logical_rect->x = 0;
- logical_rect->width = 0;
- logical_rect->y = 0;
- logical_rect->height = 0;
+ logical_rect->width = x;
+ logical_rect->y = - font_extents.ascender;
+ logical_rect->height = font_extents.ascender - font_extents.descender;
}
}
-
- PANGO_FC_FONT_UNLOCK_FACE (fcfont);
}
static void
@@ -1064,3 +900,136 @@ pango_fc_font_get_features (PangoFont *font,
}
}
}
+
+extern gpointer get_gravity_class (void);
+
+static PangoGravity
+pango_fc_font_key_get_gravity (PangoFcFontKey *key)
+{
+ FcPattern *pattern;
+ PangoGravity gravity = PANGO_GRAVITY_SOUTH;
+ FcChar8 *s;
+
+ pattern = pango_fc_font_key_get_pattern (key);
+ if (FcPatternGetString (pattern, PANGO_FC_GRAVITY, 0, (FcChar8 **)&s) == FcResultMatch)
+ {
+ GEnumValue *value = g_enum_get_value_by_nick (get_gravity_class (), (char *)s);
+ gravity = value->value;
+ }
+
+ return gravity;
+}
+
+static double
+get_font_size (PangoFcFontKey *key)
+{
+ FcPattern *pattern;
+ double size;
+ double dpi;
+
+ pattern = pango_fc_font_key_get_pattern (key);
+ if (FcPatternGetDouble (pattern, FC_PIXEL_SIZE, 0, &size) == FcResultMatch)
+ return size;
+
+ /* Just in case FC_PIXEL_SIZE got unset between pango_fc_make_pattern()
+ * and here. That would be very weird.
+ */
+
+ if (FcPatternGetDouble (pattern, FC_DPI, 0, &dpi) != FcResultMatch)
+ dpi = 72;
+
+ if (FcPatternGetDouble (pattern, FC_SIZE, 0, &size) == FcResultMatch)
+ return size * dpi / 72.;
+
+ /* Whatever */
+ return 18.;
+}
+
+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;
+}
+
+static hb_font_t *
+pango_fc_font_create_hb_font (PangoFont *font)
+{
+ PangoFcFont *fc_font = PANGO_FC_FONT (font);
+ PangoFcFontKey *key;
+ hb_face_t *hb_face;
+ hb_font_t *hb_font;
+ double x_scale_inv, y_scale_inv;
+ double x_scale, y_scale;
+ double size;
+ PangoGravity gravity;
+
+ 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 (gravity))
+ {
+ x_scale_inv = -x_scale_inv;
+ y_scale_inv = -y_scale_inv;
+ }
+
+ x_scale = 1. / x_scale_inv;
+ y_scale = 1. / y_scale_inv;
+
+ size = get_font_size (key);
+ gravity = pango_fc_font_key_get_gravity (key);
+ hb_face = pango_fc_font_map_get_hb_face (PANGO_FC_FONT_MAP (fc_font->fontmap), fc_font);
+
+ hb_font = hb_font_create (hb_face);
+ hb_font_set_scale (hb_font,
+ size * PANGO_SCALE * x_scale,
+ size * PANGO_SCALE * y_scale);
+ if (key)
+ {
+ const char *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_font_make_immutable (hb_font);
+
+ return hb_font;
+}
diff --git a/pango/pangofc-font.h b/pango/pangofc-font.h
index 38d86fa9..fc6ee529 100644
--- a/pango/pangofc-font.h
+++ b/pango/pangofc-font.h
@@ -30,8 +30,6 @@
#pragma GCC diagnostic ignored "-Wundef"
#endif
-#include <ft2build.h>
-#include FT_FREETYPE_H
#include <fontconfig/fontconfig.h>
#ifdef PANGO_COMPILATION
@@ -47,13 +45,12 @@ G_BEGIN_DECLS
typedef struct _PangoFcFont PangoFcFont;
typedef struct _PangoFcFontClass PangoFcFontClass;
-
PANGO_AVAILABLE_IN_ALL
GType pango_fc_font_get_type (void) G_GNUC_CONST;
-PANGO_AVAILABLE_IN_1_4
-FT_Face pango_fc_font_lock_face (PangoFcFont *font);
-PANGO_AVAILABLE_IN_1_4
+PANGO_DEPRECATED_IN_1_44_FOR(pango_font_get_hb_font)
+gpointer pango_fc_font_lock_face (PangoFcFont *font);
+PANGO_DEPRECATED_IN_1_44_FOR(pango_font_get_hb_font)
void pango_fc_font_unlock_face (PangoFcFont *font);
G_END_DECLS
diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c
index 27abb29e..0659b078 100644
--- a/pango/pangofc-fontmap.c
+++ b/pango/pangofc-fontmap.c
@@ -52,6 +52,7 @@
#include "pango-impl-utils.h"
#include "pango-enum-types.h"
#include "pango-coverage-private.h"
+#include <hb-ft.h>
/* Overview:
@@ -165,7 +166,8 @@ struct _PangoFcFontFaceData
/* Data */
FcPattern *pattern; /* Referenced pattern that owns filename */
PangoCoverage *coverage;
- PangoFcCmapCache *cmap_cache;
+
+ hb_face_t *hb_face;
};
struct _PangoFcFace
@@ -261,7 +263,9 @@ static FcPattern *pango_fc_patterns_get_font_pattern (PangoFcPatterns *pat
static FcPattern *uniquify_pattern (PangoFcFontMap *fcfontmap,
FcPattern *pattern);
-static gpointer
+gpointer get_gravity_class (void);
+
+gpointer
get_gravity_class (void)
{
static GEnumClass *class = NULL; /* MT-safe */
@@ -294,8 +298,7 @@ pango_fc_font_face_data_free (PangoFcFontFaceData *data)
if (data->coverage)
pango_coverage_unref (data->coverage);
- if (data->cmap_cache)
- _pango_fc_cmap_cache_unref (data->cmap_cache);
+ hb_face_destroy (data->hb_face);
g_slice_free (PangoFcFontFaceData, data);
}
@@ -1932,53 +1935,6 @@ pango_fc_font_map_get_font_face_data (PangoFcFontMap *fcfontmap,
return data;
}
-static PangoFcCmapCache *
-_pango_fc_cmap_cache_ref (PangoFcCmapCache *cmap_cache)
-{
- g_atomic_int_inc ((int *) &cmap_cache->ref_count);
-
- return cmap_cache;
-}
-
-void
-_pango_fc_cmap_cache_unref (PangoFcCmapCache *cmap_cache)
-{
- g_return_if_fail (cmap_cache->ref_count > 0);
-
- if (g_atomic_int_dec_and_test ((int *) &cmap_cache->ref_count))
- {
- g_free (cmap_cache);
- }
-}
-
-PangoFcCmapCache *
-_pango_fc_font_map_get_cmap_cache (PangoFcFontMap *fcfontmap,
- PangoFcFont *fcfont)
-{
- PangoFcFontFaceData *data;
-
- if (G_UNLIKELY (fcfontmap == NULL))
- return NULL;
-
- if (G_UNLIKELY (!fcfont->font_pattern))
- return NULL;
-
- data = pango_fc_font_map_get_font_face_data (fcfontmap, fcfont->font_pattern);
- if (G_UNLIKELY (!data))
- return NULL;
-
- if (G_UNLIKELY (data->cmap_cache == NULL))
- {
- data->cmap_cache = g_new0 (PangoFcCmapCache, 1);
- data->cmap_cache->ref_count = 1;
-
- /* Make sure all cache entries are invalid initially */
- data->cmap_cache->entries[0].ch = 1; /* char 1 cannot happen in bucket 0 */
- }
-
- return _pango_fc_cmap_cache_ref (data->cmap_cache);
-}
-
typedef struct {
PangoCoverage parent_instance;
@@ -2728,3 +2684,23 @@ pango_fc_family_init (PangoFcFamily *fcfamily)
{
fcfamily->n_faces = -1;
}
+
+hb_face_t *
+pango_fc_font_map_get_hb_face (PangoFcFontMap *fcfontmap,
+ PangoFcFont *fcfont)
+{
+ PangoFcFontFaceData *data;
+
+ data = pango_fc_font_map_get_font_face_data (fcfontmap, fcfont->font_pattern);
+
+ if (!data->hb_face)
+ {
+ hb_blob_t *blob;
+
+ blob = hb_blob_create_from_file (data->filename);
+ data->hb_face = hb_face_create (blob, data->id);
+ hb_blob_destroy (blob);
+ }
+
+ return data->hb_face;
+}
diff --git a/pango/pangofc-fontmap.h b/pango/pangofc-fontmap.h
index 5195d761..495adc52 100644
--- a/pango/pangofc-fontmap.h
+++ b/pango/pangofc-fontmap.h
@@ -26,6 +26,7 @@
#include <fontconfig/fontconfig.h>
#include <pango/pangofc-decoder.h>
#include <pango/pangofc-font.h>
+#include <hb.h>
G_BEGIN_DECLS
@@ -42,7 +43,6 @@ typedef struct _PangoFcFontMap PangoFcFontMap;
typedef struct _PangoFcFontMapClass PangoFcFontMapClass;
typedef struct _PangoFcFontMapPrivate PangoFcFontMapPrivate;
-
PANGO_AVAILABLE_IN_ALL
GType pango_fc_font_map_get_type (void) G_GNUC_CONST;
@@ -87,6 +87,10 @@ PANGO_AVAILABLE_IN_1_4
PangoFontDescription *pango_fc_font_description_from_pattern (FcPattern *pattern,
gboolean include_size);
+PANGO_AVAILABLE_IN_1_44
+hb_face_t * pango_fc_font_map_get_hb_face (PangoFcFontMap *fcfontmap,
+ PangoFcFont *fcfont);
+
/**
* PANGO_FC_GRAVITY:
*
diff --git a/pango/pangofc-private.h b/pango/pangofc-private.h
index 5babc536..8d281ad8 100644
--- a/pango/pangofc-private.h
+++ b/pango/pangofc-private.h
@@ -43,25 +43,6 @@ struct _PangoFcMetricsInfo
};
-typedef struct _PangoFcCmapCacheEntry PangoFcCmapCacheEntry;
-typedef struct _PangoFcCmapCache PangoFcCmapCache;
-
-#define CMAP_CACHE_NUM_ENTRIES 256 /* should be power of two */
-#define CMAP_CACHE_MASK (CMAP_CACHE_NUM_ENTRIES - 1)
-
-struct _PangoFcCmapCacheEntry
-{
- gunichar ch;
- PangoGlyph glyph;
-};
-
-struct _PangoFcCmapCache
-{
- guint ref_count;
- PangoFcCmapCacheEntry entries[CMAP_CACHE_NUM_ENTRIES];
-};
-
-
#define PANGO_SCALE_26_6 (PANGO_SCALE / (1<<6))
#define PANGO_PIXELS_26_6(d) \
(((d) >= 0) ? \
@@ -79,10 +60,6 @@ PangoCoverage *_pango_fc_font_map_get_coverage (PangoFcFontMap *fcfontmap,
PangoFcFont *fcfont);
PangoCoverage *_pango_fc_font_map_fc_to_coverage (FcCharSet *charset);
-PangoFcCmapCache *_pango_fc_font_map_get_cmap_cache (PangoFcFontMap *fcfontmap,
- PangoFcFont *fcfont);
-void _pango_fc_cmap_cache_unref (PangoFcCmapCache *cmap_cache);
-
PangoFcDecoder *_pango_fc_font_get_decoder (PangoFcFont *font);
void _pango_fc_font_set_decoder (PangoFcFont *font,
PangoFcDecoder *decoder);
@@ -93,7 +70,6 @@ void _pango_fc_font_set_font_key (PangoFcFont *fcfont,
_PANGO_EXTERN
void pango_fc_font_get_raw_extents (PangoFcFont *font,
- FT_Int32 load_flags,
PangoGlyph glyph,
PangoRectangle *ink_rect,
PangoRectangle *logical_rect);
diff --git a/pango/pangofc-shape.c b/pango/pangofc-shape.c
index 9bedd28a..59b90c40 100644
--- a/pango/pangofc-shape.c
+++ b/pango/pangofc-shape.c
@@ -70,249 +70,6 @@ release_buffer (hb_buffer_t *buffer, gboolean free_buffer)
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;
-}
-
static void
apply_extra_attributes (GSList *attrs,
hb_feature_t *features,
@@ -365,11 +122,6 @@ _pango_fc_shape (PangoFont *font,
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;
@@ -381,64 +133,12 @@ _pango_fc_shape (PangoFont *font,
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);
-
- if (key)
- {
- 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_font = pango_font_get_hb_font (font);
hb_buffer = acquire_buffer (&free_buffer);
@@ -460,8 +160,8 @@ _pango_fc_shape (PangoFont *font,
hb_buffer_add_utf8 (hb_buffer, paragraph_text, paragraph_length, item_offset, item_length);
- pango_font_get_features (font, features, 32, &num_features);
- apply_extra_attributes (analysis->extra_attrs, features, 32, &num_features);
+ 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);
@@ -484,7 +184,7 @@ _pango_fc_shape (PangoFont *font,
}
hb_position = hb_buffer_get_glyph_positions (hb_buffer, NULL);
- if (context.vertical)
+ if (PANGO_GRAVITY_IS_VERTICAL (analysis->gravity))
for (i = 0; i < num_glyphs; i++)
{
/* 90 degrees rotation counter-clockwise. */
@@ -502,41 +202,61 @@ _pango_fc_shape (PangoFont *font,
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 (PANGO_IS_FC_FONT (font))
+ {
+ PangoFcFont *fc_font = PANGO_FC_FONT (font);
+ if (fc_font->is_hinted)
+ {
+ double x_scale_inv, y_scale_inv;
+ double x_scale, y_scale;
+ PangoFcFontKey *key;
+
+ 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;
+ }
+ x_scale = 1. / x_scale_inv;
+ y_scale = 1. / y_scale_inv;
+
+ if (x_scale == 1.0 && 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;
- }
+ if (PANGO_GRAVITY_IS_VERTICAL (analysis->gravity))
+ {
+ /* 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);
- }
+#define HINT_X(value) HINT ((value), x_scale, x_scale_inv)
+#define HINT_Y(value) HINT ((value), 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);
}
diff --git a/pango/pangoft2.c b/pango/pangoft2.c
index a5ac6fc5..e8bb8e1f 100644
--- a/pango/pangoft2.c
+++ b/pango/pangoft2.c
@@ -64,7 +64,7 @@ static void pango_ft2_font_get_glyph_extents (PangoFont *font,
PangoRectangle *ink_rect,
PangoRectangle *logical_rect);
-static FT_Face pango_ft2_font_real_lock_face (PangoFcFont *font);
+static gpointer pango_ft2_font_real_lock_face (PangoFcFont *font);
static void pango_ft2_font_real_unlock_face (PangoFcFont *font);
@@ -309,7 +309,7 @@ pango_ft2_font_get_glyph_info (PangoFont *font,
{
info = g_slice_new0 (PangoFT2GlyphInfo);
- pango_fc_font_get_raw_extents (fcfont, ft2font->load_flags,
+ pango_fc_font_get_raw_extents (fcfont,
glyph,
&info->ink_rect,
&info->logical_rect);
@@ -430,7 +430,7 @@ pango_ft2_font_get_kerning (PangoFont *font,
return PANGO_UNITS_26_6 (kerning.x);
}
-static FT_Face
+static gpointer
pango_ft2_font_real_lock_face (PangoFcFont *font)
{
return pango_ft2_font_get_face ((PangoFont *)font);
diff --git a/pango/pangowin32.c b/pango/pangowin32.c
index 80abb0b4..0e877820 100644
--- a/pango/pangowin32.c
+++ b/pango/pangowin32.c
@@ -35,6 +35,7 @@
#include <string.h>
#include <stdlib.h>
#include <glib.h>
+#include <hb.h>
#include "pango-impl-utils.h"
#include "pangowin32.h"
@@ -86,6 +87,8 @@ static void pango_win32_get_item_properties (PangoItem
PangoAttrColor *bg_color,
gboolean *bg_set);
+static hb_font_t * pango_win32_font_create_hb_font (PangoFont *font);
+
HFONT
_pango_win32_font_get_hfont (PangoFont *font)
{
@@ -207,6 +210,7 @@ _pango_win32_font_class_init (PangoWin32FontClass *class)
font_class->get_glyph_extents = pango_win32_font_get_glyph_extents;
font_class->get_metrics = pango_win32_font_get_metrics;
font_class->get_font_map = pango_win32_font_get_font_map;
+ font_class->create_hb_font = pango_win32_font_create_hb_font;
class->select_font = pango_win32_font_real_select_font;
class->done_font = pango_win32_font_real_done_font;
@@ -1909,3 +1913,84 @@ pango_win32_font_calc_coverage (PangoFont *font,
g_print ("\n");
#endif
}
+
+/*
+ * Swap HarfBuzz-style tags to tags that GetFontData() understands,
+ * adapted from https://github.com/harfbuzz/harfbuzz/pull/1832,
+ * by Ebrahim Byagowi.
+ */
+
+static inline guint16 hb_gdi_uint16_swap (const guint16 v)
+{ return (v >> 8) | (v << 8); }
+static inline guint32 hb_gdi_uint32_swap (const guint32 v)
+{ return (hb_gdi_uint16_swap (v) << 16) | hb_gdi_uint16_swap (v >> 16); }
+
+/*
+ * Adapted from https://www.mail-archive.com/harfbuzz@lists.freedesktop.org/msg06538.html
+ * by Konstantin Ritt.
+ */
+static hb_blob_t *
+hfont_reference_table (hb_face_t *face, hb_tag_t tag, void *user_data)
+{
+ HDC hdc;
+ HFONT hfont, old_hfont;
+ gchar *buf = NULL;
+ DWORD size;
+
+ /* We have a common DC for our PangoWin32Font, so let's just use it */
+ hdc = pango_win32_get_dc ();
+ hfont = (HFONT) user_data;
+
+ /* we want to restore things, just to be safe */
+ old_hfont = SelectObject (hdc, hfont);
+ if (old_hfont == NULL)
+ {
+ g_warning ("SelectObject() for the PangoWin32Font failed!");
+ return hb_blob_get_empty ();
+ }
+
+ size = GetFontData (hdc, hb_gdi_uint32_swap (tag), 0, NULL, 0);
+
+ /*
+ * not all tags support retrieving the sizes, so don't warn,
+ * just return hb_blob_get_empty()
+ */
+ if (size == GDI_ERROR)
+ {
+ SelectObject (hdc, old_hfont);
+ return hb_blob_get_empty ();
+ }
+
+ buf = g_malloc (size * sizeof (gchar));
+
+ /* This should be quite unlikely to fail if size was not GDI_ERROR */
+ if (GetFontData (hdc, hb_gdi_uint32_swap (tag), 0, buf, size) == GDI_ERROR)
+ size = 0;
+
+ SelectObject (hdc, old_hfont);
+ return hb_blob_create (buf, size, HB_MEMORY_MODE_READONLY, buf, g_free);
+}
+
+static hb_font_t *
+pango_win32_font_create_hb_font (PangoFont *font)
+{
+ PangoWin32Font *win32font = (PangoWin32Font *)font;
+ HFONT hfont;
+ hb_face_t *face = NULL;
+ hb_font_t *hb_font = NULL;
+
+ g_return_val_if_fail (font != NULL, NULL);
+
+ hfont = _pango_win32_font_get_hfont (font);
+
+ /* We are *not* allowed to destroy the HFONT here ! */
+ face = hb_face_create_for_tables (hfont_reference_table, (void *)hfont, NULL);
+
+ hb_font = hb_font_create (face);
+ hb_font_set_scale (hb_font, win32font->size, win32font->size);
+ hb_face_destroy (face);
+
+ hb_font_make_immutable (hb_font);
+
+ return hb_font;
+}
diff --git a/pango/pangoxft-font.c b/pango/pangoxft-font.c
index 91856304..779eb886 100644
--- a/pango/pangoxft-font.c
+++ b/pango/pangoxft-font.c
@@ -75,7 +75,7 @@ static void pango_xft_font_get_glyph_extents (PangoFont
PangoRectangle *ink_rect,
PangoRectangle *logical_rect);
-static FT_Face pango_xft_font_real_lock_face (PangoFcFont *font);
+static gpointer pango_xft_font_real_lock_face (PangoFcFont *font);
static void pango_xft_font_real_unlock_face (PangoFcFont *font);
static gboolean pango_xft_font_real_has_char (PangoFcFont *font,
gunichar wc);
@@ -331,7 +331,6 @@ get_glyph_extents_raw (PangoXftFont *xfont,
extents = g_slice_new (Extents);
pango_fc_font_get_raw_extents (PANGO_FC_FONT (xfont),
- FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING,
glyph,
&extents->ink_rect,
&extents->logical_rect);
@@ -450,12 +449,12 @@ xft_font_get_font (PangoFont *font)
return xfont->xft_font;
}
-static FT_Face
+static gpointer
pango_xft_font_real_lock_face (PangoFcFont *font)
{
XftFont *xft_font = xft_font_get_font ((PangoFont *)font);
- return XftLockFace (xft_font);
+ return (gpointer)XftLockFace (xft_font);
}
static void