diff options
Diffstat (limited to 'pango')
-rw-r--r-- | pango/Makefile.am | 6 | ||||
-rw-r--r-- | pango/pangofc-decoder.c | 88 | ||||
-rw-r--r-- | pango/pangofc-decoder.h | 112 | ||||
-rw-r--r-- | pango/pangofc-font.c | 84 | ||||
-rw-r--r-- | pango/pangofc-fontmap.c | 120 | ||||
-rw-r--r-- | pango/pangofc-fontmap.h | 9 | ||||
-rw-r--r-- | pango/pangofc-private.h | 13 |
7 files changed, 414 insertions, 18 deletions
diff --git a/pango/Makefile.am b/pango/Makefile.am index 14b3e039..f226bfc0 100644 --- a/pango/Makefile.am +++ b/pango/Makefile.am @@ -173,7 +173,10 @@ libpangoxft_1_0_la_SOURCES = \ # ------------------- libpangoft2 ------------------- if HAVE_FREETYPE -pangoinclude_HEADERS += pangoft2.h pango-ot.h +pangoinclude_HEADERS += \ + pangoft2.h \ + pango-ot.h \ + pangofc-decoder.h lib_LTLIBRARIES += libpangoft2-1.0.la endif @@ -184,6 +187,7 @@ libpangoft2_1_0_la_DEPENDENCIES = opentype/libpango-ot.la libpango-$(PANGO_API_V libpangoft2_1_0_la_SOURCES = \ pangofc-font.c \ pangofc-fontmap.c \ + pangofc-decoder.c \ pangofc-private.h \ pangoft2.h \ pangoft2.c \ diff --git a/pango/pangofc-decoder.c b/pango/pangofc-decoder.c new file mode 100644 index 00000000..41e8c141 --- /dev/null +++ b/pango/pangofc-decoder.c @@ -0,0 +1,88 @@ +/* Pango + * pangofc-decoder.c: Custom font encoder/decoders + * + * Copyright (C) 2004 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. + */ + +#include "pangofc-decoder.h" + +G_DEFINE_ABSTRACT_TYPE (PangoFcDecoder, pango_fc_decoder, G_TYPE_OBJECT) + +static void +pango_fc_decoder_init (PangoFcDecoder *decoder); + +static void +pango_fc_decoder_class_init (PangoFcDecoderClass *klass); + +void +pango_fc_decoder_init (PangoFcDecoder *decoder) +{ +} + +void +pango_fc_decoder_class_init (PangoFcDecoderClass *klass) +{ +} + +/** + * pango_fc_decoder_get_charset: + * @decoder: A #PangoFcDecoder to use when querying the font for a + * supported #FcCharSet. + * @fcfont: The #PangoFcFont to query. + * + * Generates an #FcCharSet of supported characters for the fcfont + * given. The returned #FcCharSet should be a reference to an + * internal value stored by the #PangoFcDecoder and will not be freed + * by Pango. + * + * Since: 1.6 + * + */ + +FcCharSet * +pango_fc_decoder_get_charset (PangoFcDecoder *decoder, + PangoFcFont *fcfont) +{ + g_return_val_if_fail (PANGO_IS_FC_DECODER (decoder), NULL); + + return PANGO_FC_DECODER_GET_CLASS (decoder)->get_charset (fcfont); +} + +/** + * pango_fc_decoder_get_glyph: + * @decoder: A #PangoFcDecoder to use when querying the font. + * @fcfont: The #PangoFcFont to query. + * @wc: The unicode code point that you would like to see converted to + * a single #PangoGlyph. + * + * Generates a #PangoGlyph for the given unicode point with the custom + * decoder. + * + * Since: 1.6 + * + */ + +PangoGlyph +pango_fc_decoder_get_glyph (PangoFcDecoder *decoder, + PangoFcFont *fcfont, + guint32 wc) +{ + g_return_val_if_fail (PANGO_IS_FC_DECODER (decoder), 0); + + return PANGO_FC_DECODER_GET_CLASS (decoder)->get_glyph (fcfont, wc); +} diff --git a/pango/pangofc-decoder.h b/pango/pangofc-decoder.h new file mode 100644 index 00000000..34b5f180 --- /dev/null +++ b/pango/pangofc-decoder.h @@ -0,0 +1,112 @@ +/* Pango + * pangofc-decoder.h: Custom encoders/decoders on a per-font basis. + * + * Copyright (C) 2004 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 __PANGO_DECODER_H_ +#define __PANGO_DECODER_H_ + +#include <pango/pangofc-font.h> + +G_BEGIN_DECLS + +#define PANGO_TYPE_FC_DECODER (pango_fc_decoder_get_type()) +#define PANGO_FC_DECODER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_FC_DECODER, PangoFcDecoder)) +#define PANGO_IS_FC_DECODER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_FC_DECODER)) + +typedef struct _PangoFcDecoder PangoFcDecoder; +typedef struct _PangoFcDecoderClass PangoFcDecoderClass; + +#define PANGO_FC_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_FC_DECODER, PangoFcDecoderClass)) +#define PANGO_IS_FC_DECODER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_FC_DECODER)) +#define PANGO_FC_DECODER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_FC_DECODER, PangoFcDecoderClass)) + +/** + * PangoFcDecoder: + * + * #PangoFcDecoder is a virtual base class that implementations will + * inherit from. It's the interface that is used to define a custom + * encoding for a font. These objects are created in your code from a + * function callback that was originally registered with + * pango_fc_font_map_add_decoder_find_func(). Pango requires + * information about the supported charset for a font as well as the + * indivdual character to glyph conversions. Pango gets that + * information via the #get_charset and #get_glyph callbacks into your + * object implementation. + * + * Since: 1.6 + * + **/ + +struct _PangoFcDecoder +{ + GObject parent_instance; +}; + +/** + * PangoFcDecoderClass: + * + * @get_charset: This returns an #FcCharset given a #PangoFcFont that + * includes a list of supported characters in the font. The + * #FcCharSet that is returned should be an internal reference to your + * code. Pango will not free this structure. It is also important + * that you make this callback very fast because this callback is also + * used to determine unicode coverage on a per-character basis. + * @get_glyph: This returns a single #PangoGlyph for a given unicode + * code point. + * + * Class structure for #PangoFcDecoder. + * + * Since: 1.6 + * + **/ + +struct _PangoFcDecoderClass +{ + /*< private >*/ + GObjectClass parent_class; + + /* vtable - not signals */ + /*< public >*/ + FcCharSet *(*get_charset) (PangoFcFont *fcfont); + PangoGlyph (*get_glyph) (PangoFcFont *fcfont, + guint32 wc); + + /*< private >*/ + + /* Padding for future expansion */ + void (*_pango_reserved1) (void); + void (*_pango_reserved2) (void); + void (*_pango_reserved3) (void); + void (*_pango_reserved4) (void); +}; + +GType pango_fc_decoder_get_type (void); + +FcCharSet *pango_fc_decoder_get_charset (PangoFcDecoder *decoder, + PangoFcFont *fcfont); + +PangoGlyph pango_fc_decoder_get_glyph (PangoFcDecoder *decoder, + PangoFcFont *fcfont, + guint32 wc); + +G_END_DECLS + +#endif /* __PANGO_DECODER_H_ */ + diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c index de43513d..a7e35ebf 100644 --- a/pango/pangofc-font.c +++ b/pango/pangofc-font.c @@ -48,6 +48,15 @@ enum { PROP_PATTERN }; +typedef struct _PangoFcFontPrivate PangoFcFontPrivate; + +#define PANGO_FC_FONT_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), PANGO_TYPE_FC_FONT, PangoFcFontPrivate)) + +struct _PangoFcFontPrivate +{ + PangoFcDecoder *decoder; +}; + 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, @@ -114,6 +123,8 @@ pango_fc_font_class_init (PangoFcFontClass *class) "Pattern", "The fontconfig pattern for this font", G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY)); + + g_type_class_add_private (object_class, sizeof (PangoFcFontPrivate)); } static void @@ -127,6 +138,7 @@ static void pango_fc_font_finalize (GObject *object) { PangoFcFont *fcfont = PANGO_FC_FONT (object); + PangoFcFontPrivate *priv = PANGO_FC_FONT_GET_PRIVATE (fcfont); g_slist_foreach (fcfont->metrics_by_lang, (GFunc)free_metrics_info, NULL); g_slist_free (fcfont->metrics_by_lang); @@ -137,6 +149,9 @@ pango_fc_font_finalize (GObject *object) FcPatternDestroy (fcfont->font_pattern); pango_font_description_free (fcfont->description); + if (priv->decoder) + _pango_fc_font_set_decoder (fcfont, NULL); + parent_class->finalize (object); } @@ -206,9 +221,17 @@ pango_fc_font_get_coverage (PangoFont *font, PangoLanguage *language) { PangoFcFont *fcfont = (PangoFcFont *)font; + PangoFcFontPrivate *priv = PANGO_FC_FONT_GET_PRIVATE (fcfont); + FcCharSet *charset; + + if (priv->decoder) + { + charset = pango_fc_decoder_get_charset (priv->decoder, fcfont); + return _pango_fc_font_map_fc_to_coverage (charset); + } return _pango_fc_font_map_get_coverage (PANGO_FC_FONT_MAP (fcfont->fontmap), - fcfont->font_pattern); + fcfont); } static void @@ -472,8 +495,17 @@ gboolean pango_fc_font_has_char (PangoFcFont *font, gunichar wc) { + PangoFcFontPrivate *priv = PANGO_FC_FONT_GET_PRIVATE (font); + FcCharSet *charset; + g_return_val_if_fail (PANGO_IS_FC_FONT (font), FALSE); + if (priv->decoder) + { + charset = pango_fc_decoder_get_charset (priv->decoder, font); + return FcCharSetHasChar (charset, wc); + } + return PANGO_FC_FONT_GET_CLASS (font)->has_char (font, wc); } @@ -495,8 +527,13 @@ PangoGlyph pango_fc_font_get_glyph (PangoFcFont *font, gunichar wc) { + PangoFcFontPrivate *priv = PANGO_FC_FONT_GET_PRIVATE (font); + g_return_val_if_fail (PANGO_IS_FC_FONT (font), 0); + if (priv->decoder) + return pango_fc_decoder_get_glyph (priv->decoder, font, wc); + return PANGO_FC_FONT_GET_CLASS (font)->get_glyph (font, wc); } @@ -577,3 +614,48 @@ pango_fc_font_kern_glyphs (PangoFcFont *font, pango_fc_font_unlock_face (font); } + +/** + * _pango_fc_font_get_decoder + * @font: a #PangoFcFont + * + * This will return any custom decoder set on this font. + * + * Returns: The custom decoder + * + * Since: 1.6 + **/ + +PangoFcDecoder * +_pango_fc_font_get_decoder (PangoFcFont *font) +{ + PangoFcFontPrivate *priv = PANGO_FC_FONT_GET_PRIVATE (font); + + return priv->decoder; +} + +/** + * _pango_fc_font_set_decoder + * @font: a #PangoFcFont + * @decoder: a #PangoFcDecoder to set for this font + * + * This sets a custom decoder for this font. Any previous decoder + * will be released before this one is set. + * + * Since: 1.6 + **/ + +void +_pango_fc_font_set_decoder (PangoFcFont *font, + PangoFcDecoder *decoder) +{ + PangoFcFontPrivate *priv = PANGO_FC_FONT_GET_PRIVATE (font); + + if (priv->decoder) + g_object_unref (priv->decoder); + + priv->decoder = decoder; + + if (priv->decoder) + g_object_ref (priv->decoder); +} diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c index 5321e587..63c628a6 100644 --- a/pango/pangofc-fontmap.c +++ b/pango/pangofc-fontmap.c @@ -31,6 +31,7 @@ typedef struct _PangoFcCoverageKey PangoFcCoverageKey; typedef struct _PangoFcFace PangoFcFace; typedef struct _PangoFcFamily PangoFcFamily; typedef struct _PangoFcPatternSet PangoFcPatternSet; +typedef struct _PangoFcFindFuncInfo PangoFcFindFuncInfo; #define PANGO_FC_TYPE_FAMILY (pango_fc_family_get_type ()) #define PANGO_FC_FAMILY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_FC_TYPE_FAMILY, PangoFcFamily)) @@ -60,6 +61,9 @@ struct _PangoFcFontMapPrivate PangoFcFamily **families; int n_families; /* -1 == uninitialized */ + /* Decoders */ + GSList *findfuncs; + guint closed : 1; }; @@ -98,6 +102,14 @@ struct _PangoFcPatternSet GList *cache_link; }; +struct _PangoFcFindFuncInfo +{ + PangoFcDecoderFindFunc findfunc; + gpointer user_data; + GDestroyNotify dnotify; + gpointer ddata; +}; + static GType pango_fc_family_get_type (void); static GType pango_fc_face_get_type (void); @@ -330,6 +342,42 @@ pango_fc_clear_pattern_hashes (PangoFcFontMap *fcfontmap) priv->fontset_hash_list = NULL; } +/** + * pango_fc_font_map_add_find_func: + * @fcfontmap: The #PangoFcFontMap to add this method to. + * @factory: The #PangoFcDecoderFindFunc callback function + * @user_data: User data. + * @dnotify: A #GDestroyNotify callback that will be called when the + * fontmap is finalized and the decoder is released. + * + * This function saves a callback method in the #PangoFcFontMap that + * will be called whenever new fonts are created. If the function + * returns a #PangoFcDecoder, that decoder will be used to determine + * both coverage via a #FcCharSet and a one-to-one mapping of + * characters to glyphs. This will allow applications to have + * application-specific encodings for various fonts. + * + * Since: 1.6. + * + */ + +void pango_fc_font_map_add_decoder_find_func (PangoFcFontMap *fcfontmap, + PangoFcDecoderFindFunc findfunc, + gpointer user_data, + GDestroyNotify dnotify) +{ + PangoFcFontMapPrivate *priv = fcfontmap->priv; + PangoFcFindFuncInfo *info; + + info = g_new (PangoFcFindFuncInfo, 1); + + info->findfunc = findfunc; + info->user_data = user_data; + info->dnotify = dnotify; + + priv->findfuncs = g_slist_append (priv->findfuncs, info); +} + static void pango_fc_font_map_finalize (GObject *object) { @@ -346,10 +394,20 @@ pango_fc_font_map_finalize (GObject *object) if (priv->pattern_hash) g_hash_table_destroy (priv->pattern_hash); + while (priv->findfuncs) + { + PangoFcFindFuncInfo *info; + info = priv->findfuncs->data; + if (info->dnotify) + info->dnotify (info->user_data); + + g_free (info); + priv->findfuncs = g_slist_delete_link (priv->findfuncs, priv->findfuncs); + } + G_OBJECT_CLASS (parent_class)->finalize (object); } - /* Add a mapping from xfont->font_pattern to xfont */ static void pango_fc_font_map_add (PangoFcFontMap *fcfontmap, @@ -594,6 +652,7 @@ pango_fc_font_map_new_font (PangoFontMap *fontmap, PangoFcFontMapPrivate *priv = fcfontmap->priv; FcPattern *pattern; PangoFcFont *fcfont; + GSList *l; /* Returning NULL here actually violates a contract * that loading load_font() will never return NULL. @@ -640,6 +699,23 @@ pango_fc_font_map_new_font (PangoFontMap *fontmap, fcfont->fontmap = g_object_ref (fcfontmap); + /* + * Give any custom decoders a crack at this font now that it's been + * created. + */ + for (l = priv->findfuncs; l && l->data; l = l->next) + { + PangoFcFindFuncInfo *info = l->data; + PangoFcDecoder *decoder; + + decoder = info->findfunc (match, info->user_data); + if (decoder) + { + _pango_fc_font_set_decoder (fcfont, decoder); + break; + } + } + return (PangoFont *)fcfont; } @@ -948,25 +1024,22 @@ pango_fc_font_map_set_coverage (PangoFcFontMap *fcfontmap, PangoCoverage * _pango_fc_font_map_get_coverage (PangoFcFontMap *fcfontmap, - FcPattern *pattern) + PangoFcFont *fcfont) { PangoFcFontMapPrivate *priv = fcfontmap->priv; PangoFcCoverageKey key; PangoCoverage *coverage; - FcChar32 map[FC_CHARSET_MAP_SIZE]; - FcChar32 ucs4, pos; FcCharSet *charset; - int i; /* * Assume that coverage information is identified by * a filename/index pair; there shouldn't be any reason * this isn't true, but it's not specified anywhere */ - if (FcPatternGetString (pattern, FC_FILE, 0, (FcChar8 **) &key.filename) != FcResultMatch) + if (FcPatternGetString (fcfont->font_pattern, FC_FILE, 0, (FcChar8 **) &key.filename) != FcResultMatch) return NULL; - if (FcPatternGetInteger (pattern, FC_INDEX, 0, &key.id) != FcResultMatch) + if (FcPatternGetInteger (fcfont->font_pattern, FC_INDEX, 0, &key.id) != FcResultMatch) return NULL; coverage = g_hash_table_lookup (priv->coverage_hash, &key); @@ -977,9 +1050,34 @@ _pango_fc_font_map_get_coverage (PangoFcFontMap *fcfontmap, * Pull the coverage out of the pattern, this * doesn't require loading the font */ - if (FcPatternGetCharSet (pattern, FC_CHARSET, 0, &charset) != FcResultMatch) + if (FcPatternGetCharSet (fcfont->font_pattern, FC_CHARSET, 0, &charset) != FcResultMatch) return NULL; - + + coverage = _pango_fc_font_map_fc_to_coverage (charset); + + pango_fc_font_map_set_coverage (fcfontmap, &key, coverage); + + return coverage; +} + +/** + * _pango_fc_font_map_fc_to_coverage: + * @charset: #FcCharSet to convert to a #PangoCoverage object. + * + * Convert the given #FcCharSet into a new #PangoCoverage object. The + * caller is responsible for freeing the newly created object. + * + * Since: 1.6 + **/ + +PangoCoverage * +_pango_fc_font_map_fc_to_coverage (FcCharSet *charset) +{ + PangoCoverage *coverage; + FcChar32 ucs4, pos; + FcChar32 map[FC_CHARSET_MAP_SIZE]; + int i; + /* * Convert an Fc CharSet into a pango coverage structure. Sure * would be nice to just use the Fc structure in place... @@ -1005,7 +1103,7 @@ _pango_fc_font_map_get_coverage (PangoFcFontMap *fcfontmap, } } } - + /* Awful hack so Hangul Tone marks get rendered with the same * font and in the same run as other Hangul characters. If a font * covers the first composed Hangul glyph, then it is declared to cover @@ -1018,8 +1116,6 @@ _pango_fc_font_map_get_coverage (PangoFcFontMap *fcfontmap, pango_coverage_set (coverage, 0x302f, PANGO_COVERAGE_EXACT); } - pango_fc_font_map_set_coverage (fcfontmap, &key, coverage); - return coverage; } diff --git a/pango/pangofc-fontmap.h b/pango/pangofc-fontmap.h index 9d02dee9..3ad3430a 100644 --- a/pango/pangofc-fontmap.h +++ b/pango/pangofc-fontmap.h @@ -24,6 +24,7 @@ #include <fontconfig/fontconfig.h> #include <pango/pango-fontmap.h> +#include <pango/pangofc-decoder.h> #include <pango/pangofc-font.h> G_BEGIN_DECLS @@ -98,6 +99,14 @@ void pango_fc_font_map_shutdown (PangoFcFontMap *fcfontmap); GType pango_fc_font_map_get_type (void); +typedef PangoFcDecoder * (*PangoFcDecoderFindFunc) (FcPattern *pattern, + gpointer user_data); + +void pango_fc_font_map_add_decoder_find_func (PangoFcFontMap *fcfontmap, + PangoFcDecoderFindFunc findfunc, + gpointer user_data, + GDestroyNotify dnotify); + PangoFontDescription *pango_fc_font_description_from_pattern (FcPattern *pattern, gboolean include_size); diff --git a/pango/pangofc-private.h b/pango/pangofc-private.h index 9ef285af..ea2c8744 100644 --- a/pango/pangofc-private.h +++ b/pango/pangofc-private.h @@ -29,10 +29,15 @@ G_BEGIN_DECLS void _pango_fc_font_shutdown (PangoFcFont *fcfont); -void _pango_fc_font_map_remove (PangoFcFontMap *fcfontmap, - PangoFcFont *fcfont); -PangoCoverage *_pango_fc_font_map_get_coverage (PangoFcFontMap *fcfontmap, - FcPattern *pattern); +void _pango_fc_font_map_remove (PangoFcFontMap *fcfontmap, + PangoFcFont *fcfont); +PangoCoverage *_pango_fc_font_map_get_coverage (PangoFcFontMap *fcfontmap, + PangoFcFont *fcfont); +PangoCoverage *_pango_fc_font_map_fc_to_coverage (FcCharSet *charset); + +PangoFcDecoder *_pango_fc_font_get_decoder (PangoFcFont *font); +void _pango_fc_font_set_decoder (PangoFcFont *font, + PangoFcDecoder *decoder); G_END_DECLS |