summaryrefslogtreecommitdiff
path: root/pango/pangofc-font.c
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2003-08-03 02:35:20 +0000
committerOwen Taylor <otaylor@src.gnome.org>2003-08-03 02:35:20 +0000
commit94f39b93e929db7881070f4b5e1f5dc3c106e3fb (patch)
tree1fa92651d4e9d2c7c41d413468f37bdb8095cd52 /pango/pangofc-font.c
parente2ea77ce2f99c122a0087c28fcd9316be4d6e205 (diff)
downloadpango-94f39b93e929db7881070f4b5e1f5dc3c106e3fb.tar.gz
Make pangoxft depend on pangoft2.
Sat Aug 2 14:33:28 2003 Owen Taylor <otaylor@redhat.com> * pango/Makefile.am (libpangoxft_1_0_la_LIBADD): Make pangoxft depend on pangoft2. * pango/pangofc-fontmap.[ch]: Make pangofc-fontmap.cI into a real base class. * pango/pangofc-font.[ch]: Move some of the pangoxft/ pangoft2 implementation here. * pango/pangoft2.c pango/pangoft2-fontmap.c pango/pangoft2-private.h pango/pangoxft-font.c pango/pangoxft2-fontmap.c pango/pangoxft-private.h: Adapt to the new scheme * modules/*/Makefile.am Modules/*/*/*-fc.c: Don't build separate FT2 and Xft shapers, just build one Fc shaper. * docs/pango-sections.txt docs/pango-docs.sgml docs/tmpl/pangofc-font{,map}.sgml: Basic docs for the new stuff. * configure.in: Up pango_module_version to 1.4.0.
Diffstat (limited to 'pango/pangofc-font.c')
-rw-r--r--pango/pangofc-font.c320
1 files changed, 317 insertions, 3 deletions
diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c
index aadb2e08..bf218f73 100644
--- a/pango/pangofc-font.c
+++ b/pango/pangofc-font.c
@@ -20,6 +20,48 @@
*/
#include "pangofc-font.h"
+#include "pangofc-fontmap.h"
+#include "pangofc-private.h"
+#include "pango-layout.h"
+#include "pango-modules.h"
+#include "pango-utils.h"
+
+#define PANGO_SCALE_26_6 (PANGO_SCALE / (1<<6))
+#define PANGO_PIXELS_26_6(d) \
+ (((d) >= 0) ? \
+ ((d) + PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6 : \
+ ((d) - PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6)
+#define PANGO_UNITS_26_6(d) (PANGO_SCALE_26_6 * (d))
+
+typedef struct _PangoFcMetricsInfo PangoFcMetricsInfo;
+
+struct _PangoFcMetricsInfo
+{
+ const char *sample_str;
+ PangoFontMetrics *metrics;
+};
+
+enum {
+ PROP_0,
+ PROP_PATTERN
+};
+
+static void pango_fc_font_class_init (PangoFcFontClass *class);
+static void pango_fc_font_finalize (GObject *object);
+static void pango_fc_font_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec);
+static PangoEngineShape * pango_fc_font_find_shaper (PangoFont *font,
+ PangoLanguage *language,
+ guint32 ch);
+static PangoCoverage * pango_fc_font_get_coverage (PangoFont *font,
+ PangoLanguage *language);
+static PangoFontMetrics * pango_fc_font_get_metrics (PangoFont *font,
+ PangoLanguage *language);
+static PangoFontDescription *pango_fc_font_describe (PangoFont *font);
+
+static GObjectClass *parent_class;
GType
pango_fc_font_get_type (void)
@@ -33,7 +75,7 @@ pango_fc_font_get_type (void)
sizeof (PangoFcFontClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
- NULL, /* class_init */
+ (GClassInitFunc) pango_fc_font_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (PangoFcFont),
@@ -43,12 +85,245 @@ pango_fc_font_get_type (void)
object_type = g_type_register_static (PANGO_TYPE_FONT,
"PangoFcFont",
- &object_info, 0);
+ &object_info,
+ G_TYPE_FLAG_ABSTRACT);
}
return object_type;
}
+static void
+pango_fc_font_class_init (PangoFcFontClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ PangoFontClass *font_class = PANGO_FONT_CLASS (class);
+
+ parent_class = g_type_class_peek_parent (class);
+
+ object_class->finalize = pango_fc_font_finalize;
+ object_class->set_property = pango_fc_font_set_property;
+ font_class->describe = pango_fc_font_describe;
+ font_class->find_shaper = pango_fc_font_find_shaper;
+ font_class->get_coverage = pango_fc_font_get_coverage;
+ font_class->get_metrics = pango_fc_font_get_metrics;
+
+ g_object_class_install_property (object_class, PROP_PATTERN,
+ g_param_spec_pointer ("pattern",
+ "Pattern",
+ "The fontconfig pattern for this font",
+ G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
+}
+
+static void
+free_metrics_info (PangoFcMetricsInfo *info)
+{
+ pango_font_metrics_unref (info->metrics);
+ g_free (info);
+}
+
+static void
+pango_fc_font_finalize (GObject *object)
+{
+ PangoFcFont *fcfont = PANGO_FC_FONT (object);
+
+ g_slist_foreach (fcfont->metrics_by_lang, (GFunc)free_metrics_info, NULL);
+ g_slist_free (fcfont->metrics_by_lang);
+
+ if (fcfont->fontmap)
+ _pango_fc_font_map_remove (PANGO_FC_FONT_MAP (fcfont->fontmap), fcfont);
+
+ FcPatternDestroy (fcfont->font_pattern);
+ pango_font_description_free (fcfont->description);
+
+ parent_class->finalize (object);
+}
+
+static void
+pango_fc_font_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (prop_id)
+ {
+ case PROP_PATTERN:
+ {
+ PangoFcFont *fcfont = PANGO_FC_FONT (object);
+ FcPattern *pattern = g_value_get_pointer (value);
+
+ g_return_if_fail (pattern != NULL);
+ g_return_if_fail (fcfont->font_pattern == NULL);
+
+ FcPatternReference (pattern);
+ fcfont->font_pattern = pattern;
+ fcfont->description = pango_fc_font_description_from_pattern (pattern, TRUE);
+ }
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static PangoFontDescription *
+pango_fc_font_describe (PangoFont *font)
+{
+ PangoFcFont *fcfont = (PangoFcFont *)font;
+
+ return pango_font_description_copy (fcfont->description);
+}
+
+static PangoMap *
+pango_fc_get_shaper_map (PangoLanguage *language)
+{
+ static guint engine_type_id = 0;
+ static guint render_type_id = 0;
+
+ if (engine_type_id == 0)
+ {
+ engine_type_id = g_quark_from_static_string (PANGO_ENGINE_TYPE_SHAPE);
+ render_type_id = g_quark_from_static_string (PANGO_RENDER_TYPE_FC);
+ }
+
+ return pango_find_map (language, engine_type_id, render_type_id);
+}
+
+static PangoEngineShape *
+pango_fc_font_find_shaper (PangoFont *font,
+ PangoLanguage *language,
+ guint32 ch)
+{
+ PangoMap *shaper_map = NULL;
+
+ shaper_map = pango_fc_get_shaper_map (language);
+ return (PangoEngineShape *)pango_map_get_engine (shaper_map, ch);
+}
+
+static PangoCoverage *
+pango_fc_font_get_coverage (PangoFont *font,
+ PangoLanguage *language)
+{
+ PangoFcFont *fcfont = (PangoFcFont *)font;
+
+ return _pango_fc_font_map_get_coverage (PANGO_FC_FONT_MAP (fcfont->fontmap),
+ fcfont->font_pattern);
+}
+
+/* For Xft, it would be slightly more efficient to simply to
+ * call Xft, and also more robust against changes in Xft.
+ * But for now, we simply use the same code for all backends.
+ *
+ * The code in this function is partly based on code from Xft,
+ * Copyright 2000 Keith Packard
+ */
+static void
+get_face_metrics (PangoFcFont *fcfont,
+ PangoFontMetrics *metrics)
+{
+ FT_Face face = pango_fc_font_lock_face (fcfont);
+ FcMatrix *fc_matrix;
+ FT_Matrix ft_matrix;
+ gboolean have_transform = FALSE;
+
+ 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);
+ }
+
+ 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);
+ }
+ else
+ {
+ metrics->descent = PANGO_UNITS_26_6 (face->size->metrics.descender);
+ metrics->ascent = PANGO_UNITS_26_6 (face->size->metrics.ascender);
+ }
+
+ pango_fc_font_unlock_face (fcfont);
+}
+
+
+static PangoFontMetrics *
+pango_fc_font_get_metrics (PangoFont *font,
+ PangoLanguage *language)
+{
+ PangoFcFont *fcfont = PANGO_FC_FONT (font);
+ PangoFcMetricsInfo *info = NULL; /* Quiet gcc */
+ GSList *tmp_list;
+
+ const char *sample_str = pango_language_get_sample_string (language);
+
+ tmp_list = fcfont->metrics_by_lang;
+ while (tmp_list)
+ {
+ info = tmp_list->data;
+
+ if (info->sample_str == sample_str) /* We _don't_ need strcmp */
+ break;
+
+ tmp_list = tmp_list->next;
+ }
+
+ if (!tmp_list)
+ {
+ PangoLayout *layout;
+ PangoRectangle extents;
+ PangoContext *context;
+
+ info = g_new0 (PangoFcMetricsInfo, 1);
+ fcfont->metrics_by_lang = g_slist_prepend (fcfont->metrics_by_lang,
+ info);
+
+ if (fcfont->fontmap)
+ {
+ info->sample_str = sample_str;
+ info->metrics = pango_font_metrics_new ();
+
+ get_face_metrics (fcfont, info->metrics);
+
+ context = pango_fc_font_map_create_context (PANGO_FC_FONT_MAP (fcfont->fontmap));
+ pango_context_set_language (context, language);
+
+ layout = pango_layout_new (context);
+ pango_layout_set_font_description (layout, fcfont->description);
+
+ pango_layout_set_text (layout, sample_str, -1);
+ pango_layout_get_extents (layout, NULL, &extents);
+
+ info->metrics->approximate_char_width =
+ extents.width / g_utf8_strlen (sample_str, -1);
+
+ pango_layout_set_text (layout, "0123456789", -1);
+ pango_layout_get_extents (layout, NULL, &extents);
+
+ info->metrics->approximate_digit_width = extents.width / 10;
+
+ g_object_unref (layout);
+ g_object_unref (context);
+ }
+ }
+
+ return pango_font_metrics_ref (info->metrics);
+}
+
/**
* pango_fc_font_lock_face:
* @font: a #PangoFcFont.
@@ -151,6 +426,15 @@ pango_fc_font_get_unknown_glyph (PangoFcFont *font,
return PANGO_FC_FONT_GET_CLASS (font)->get_unknown_glyph (font, wc);
}
+void
+_pango_fc_font_shutdown (PangoFcFont *font)
+{
+ g_return_if_fail (PANGO_IS_FC_FONT (font));
+
+ if (PANGO_FC_FONT_GET_CLASS (font)->shutdown)
+ PANGO_FC_FONT_GET_CLASS (font)->shutdown (font);
+}
+
/**
* pango_fc_font_kern_glyphs
* @font: a #PangoFcFont
@@ -165,5 +449,35 @@ void
pango_fc_font_kern_glyphs (PangoFcFont *font,
PangoGlyphString *glyphs)
{
- PANGO_FC_FONT_GET_CLASS (font)->kern_glyphs (font, glyphs);
+ FT_Face face;
+ FT_Error error;
+ FT_Vector kerning;
+ int i;
+
+ g_return_if_fail (PANGO_IS_FC_FONT (font));
+ g_return_if_fail (glyphs != NULL);
+
+ face = pango_fc_font_lock_face (font);
+ if (!face)
+ return;
+
+ if (!FT_HAS_KERNING (face))
+ {
+ pango_fc_font_unlock_face (font);
+ return;
+ }
+
+ for (i = 1; i < glyphs->num_glyphs; ++i)
+ {
+ error = FT_Get_Kerning (face,
+ glyphs->glyphs[i-1].glyph,
+ glyphs->glyphs[i].glyph,
+ ft_kerning_default,
+ &kerning);
+
+ if (error == FT_Err_Ok)
+ glyphs->glyphs[i-1].geometry.width += PANGO_UNITS_26_6 (kerning.x);
+ }
+
+ pango_fc_font_unlock_face (font);
}