summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.in57
-rw-r--r--modules/basic/Makefile.am17
-rw-r--r--modules/basic/basic-coretext.c232
-rw-r--r--pango/Makefile.am21
-rw-r--r--pango/modules.h1
-rw-r--r--pango/pangocairo-coretext.h55
-rw-r--r--pango/pangocairo-coretextfont.c279
-rw-r--r--pango/pangocairo-coretextfont.h37
-rw-r--r--pango/pangocairo-coretextfontmap.c107
-rw-r--r--pango/pangocairo-fontmap.c14
-rw-r--r--pango/pangocoretext-fontmap.c952
-rw-r--r--pango/pangocoretext-private.h101
-rw-r--r--pango/pangocoretext.c205
-rw-r--r--pango/pangocoretext.h80
14 files changed, 2155 insertions, 3 deletions
diff --git a/configure.in b/configure.in
index 03c79a84..7d8cbeb3 100644
--- a/configure.in
+++ b/configure.in
@@ -337,6 +337,25 @@ fi
AC_CHECK_HEADER(Carbon/Carbon.h, [have_atsui=true], [have_atsui=false])
#
+# Checks for CoreText
+#
+
+AC_MSG_CHECKING([for CoreText availability])
+pango_save_libs=$LIBS
+LIBS="$LIBS -framework ApplicationServices"
+AC_TRY_LINK([#include <Carbon/Carbon.h>], [CTGetCoreTextVersion ();],
+[have_core_text=yes], [have_core_text=no])
+LIBS=$pango_save_libs
+
+if test "$have_core_text" = "yes"; then
+ AC_DEFINE(HAVE_CORE_TEXT, 1, [Whether CoreText is available on the system])
+fi
+
+AC_MSG_RESULT([$have_core_text])
+
+AM_CONDITIONAL(HAVE_CORE_TEXT, test "$have_core_text" = "yes")
+
+#
# Checks for Cairo
#
have_cairo=false
@@ -378,7 +397,7 @@ if $have_cairo ; then
have_cairo=true
fi
- if $have_atsui; then
+ if test $have_atsui -o $have_core_text; then
PKG_CHECK_EXISTS(cairo-quartz-font >= $cairo_required, have_cairo_atsui=true, :)
fi
if $have_cairo_atsui; then
@@ -487,7 +506,7 @@ GOBJECT_INTROSPECTION_CHECK([0.9.5])
# Modules to build
#
arabic_modules="arabic-fc,arabic-lang"
-basic_modules="basic-fc,basic-win32,basic-x,basic-atsui"
+basic_modules="basic-fc,basic-win32,basic-x,basic-atsui,basic-coretext"
hangul_modules="hangul-fc"
hebrew_modules="hebrew-fc"
indic_modules="indic-fc,indic-lang"
@@ -543,12 +562,14 @@ INCLUDED_X_MODULES=
INCLUDED_FC_MODULES=
INCLUDED_WIN32_MODULES=
INCLUDED_ATSUI_MODULES=
+INCLUDED_CORE_TEXT_MODULES=
INCLUDED_LANG_MODULES=
AC_SUBST(INCLUDED_X_MODULES)
AC_SUBST(INCLUDED_FC_MODULES)
AC_SUBST(INCLUDED_WIN32_MODULES)
AC_SUBST(INCLUDED_ATSUI_MODULES)
+AC_SUBST(INCLUDED_CORE_TEXT_MODULES)
AC_SUBST(INCLUDED_LANG_MODULES)
IFS="${IFS= }"; pango_save_ifs="$IFS"; IFS=", "
@@ -564,6 +585,7 @@ for module in $included_modules; do
*-fc) INCLUDED_FC_MODULES="$INCLUDED_FC_MODULES $included_path" ;;
*-win32) INCLUDED_WIN32_MODULES="$INCLUDED_WIN32_MODULES $included_path" ;;
*-atsui) INCLUDED_ATSUI_MODULES="$INCLUDED_ATSUI_MODULES $included_path" ;;
+ *-coretext) INCLUDED_CORE_TEXT_MODULES="$INCLUDED_CORE_TEXT_MODULES $included_path" ;;
*-lang) INCLUDED_LANG_MODULES="$INCLUDED_LANG_MODULES $included_path" ;;
*) IFS="$pango_save_ifs"; AC_MSG_ERROR([specified module $module not recognized]) ;;
esac
@@ -576,6 +598,7 @@ AM_CONDITIONAL(INCLUDE_BASIC_FC, echo $included_modules | egrep '(^|,)basic-fc($
AM_CONDITIONAL(INCLUDE_BASIC_WIN32, echo $included_modules | egrep '(^|,)basic-win32($|,)' > /dev/null)
AM_CONDITIONAL(INCLUDE_BASIC_X, echo $included_modules | egrep '(^|,)basic-x($|,)' > /dev/null)
AM_CONDITIONAL(INCLUDE_BASIC_ATSUI, echo $included_modules | egrep '(^|,)basic-atsui($|,)' > /dev/null)
+AM_CONDITIONAL(INCLUDE_BASIC_CORE_TEXT, echo $included_modules | egrep '(^|,)basic-coretext($|,)' > /dev/null)
AM_CONDITIONAL(INCLUDE_HANGUL_FC, echo $included_modules | egrep '(^|,)hangul-fc($|,)' > /dev/null)
AM_CONDITIONAL(INCLUDE_HEBREW_FC, echo $included_modules | egrep '(^|,)hebrew-fc($|,)' > /dev/null)
AM_CONDITIONAL(INCLUDE_INDIC_FC, echo $included_modules | egrep '(^|,)indic-fc($|,)' > /dev/null)
@@ -592,6 +615,7 @@ AM_CONDITIONAL(DYNAMIC_BASIC_FC, echo $dynamic_modules | egrep '(^|,)basic-fc($|
AM_CONDITIONAL(DYNAMIC_BASIC_WIN32, echo $dynamic_modules | egrep '(^|,)basic-win32($|,)' > /dev/null)
AM_CONDITIONAL(DYNAMIC_BASIC_X, echo $dynamic_modules | egrep '(^|,)basic-x($|,)' > /dev/null)
AM_CONDITIONAL(DYNAMIC_BASIC_ATSUI, echo $dynamic_modules | egrep '(^|,)basic-atsui($|,)' > /dev/null)
+AM_CONDITIONAL(DYNAMIC_BASIC_CORE_TEXT, echo $dynamic_modules | egrep '(^|,)basic-coretext($|,)' > /dev/null)
AM_CONDITIONAL(DYNAMIC_HANGUL_FC, echo $dynamic_modules | egrep '(^|,)hangul-fc($|,)' > /dev/null)
AM_CONDITIONAL(DYNAMIC_HEBREW_FC, echo $dynamic_modules | egrep '(^|,)hebrew-fc($|,)' > /dev/null)
AM_CONDITIONAL(DYNAMIC_INDIC_FC, echo $dynamic_modules | egrep '(^|,)indic-fc($|,)' > /dev/null)
@@ -886,6 +910,35 @@ cat >> pango/module-defs-atsui.c <<EOTEXT
EOTEXT
])
+AC_CONFIG_COMMANDS([pango/module-defs-coretext.c],
+[
+### CoreText modules
+cat > pango/module-defs-coretext.c <<EOTEXT
+/* Autogenerated by configure. Do not edit */
+
+#include "module-defs.h"
+
+PangoIncludedModule _pango_included_core_text_modules@<:@@:>@ = {
+EOTEXT
+
+IFS="${IFS= }"; pango_save_ifs="$IFS"; IFS=","
+for module in $included_modules; do
+ if echo $module | egrep -- "-atsui($|,)" > /dev/null; then
+ module_c=`echo $module | sed s/-/_/`
+ cat >> pango/module-defs-coretext.c <<EOTEXT
+ { _pango_${module_c}_script_engine_list, _pango_${module_c}_script_engine_init, _pango_${module_c}_script_engine_exit, _pango_${module_c}_script_engine_create },
+EOTEXT
+ fi
+done
+
+IFS="$pango_save_ifs"
+
+cat >> pango/module-defs-coretext.c <<EOTEXT
+ { NULL, NULL, NULL, NULL },
+};
+EOTEXT
+])
+
AC_CONFIG_COMMANDS([pango/module-defs-lang.c],
[
### lang modules
diff --git a/modules/basic/Makefile.am b/modules/basic/Makefile.am
index 93604c9e..a264d704 100644
--- a/modules/basic/Makefile.am
+++ b/modules/basic/Makefile.am
@@ -54,6 +54,16 @@ libpango_basic_win32_la_SOURCES = basic-win32.c
libpango_basic_win32_la_CFLAGS = -DPANGO_MODULE_PREFIX=_pango_basic_win32
if HAVE_CAIRO_ATSUI
+if HAVE_CORE_TEXT
+INCLUDES += $(CAIRO_CFLAGS)
+if INCLUDE_BASIC_CORE_TEXT
+noinst_LTLIBRARIES += libpango-basic-coretext.la
+else
+if DYNAMIC_BASIC_CORE_TEXT
+module_LTLIBRARIES += pango-basic-coretext.la
+endif
+endif
+else
INCLUDES += $(ATSUI_CFLAGS) $(CAIRO_CFLAGS)
if INCLUDE_BASIC_ATSUI
noinst_LTLIBRARIES += libpango-basic-atsui.la
@@ -63,6 +73,13 @@ module_LTLIBRARIES += pango-basic-atsui.la
endif
endif
endif
+endif
+
+pango_basic_coretext_la_LDFLAGS = -module $(MODULE_LIBTOOL_OPTIONS) -framework Carbon
+pango_basic_coretext_la_LIBADD = $(pangocoretextlibs)
+pango_basic_coretext_la_SOURCES = basic-coretext.c
+libpango_basic_coretext_la_SOURCES = basic-coretext.c
+libpango_basic_coretext_la_CFLAGS = -DPANGO_MODULE_PREFIX=_pango_basic_coretext
pango_basic_atsui_la_LDFLAGS = -module $(MODULE_LIBTOOL_OPTIONS) -framework Carbon
pango_basic_atsui_la_LIBADD = $(pangoatsuilibs)
diff --git a/modules/basic/basic-coretext.c b/modules/basic/basic-coretext.c
new file mode 100644
index 00000000..16707102
--- /dev/null
+++ b/modules/basic/basic-coretext.c
@@ -0,0 +1,232 @@
+/* Pango
+ * basic-coretext.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ * Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
+ *
+ * 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 <glib.h>
+#include <string.h>
+#include <Carbon/Carbon.h>
+#include "pango-engine.h"
+#include "pango-utils.h"
+#include "pango-fontmap.h"
+#include "pangocoretext.h"
+
+/* No extra fields needed */
+typedef PangoEngineShape BasicEngineCoreText;
+typedef PangoEngineShapeClass BasicEngineCoreTextClass ;
+
+#define SCRIPT_ENGINE_NAME "BasicScriptEngineCoreText"
+#define RENDER_TYPE PANGO_RENDER_TYPE_CORE_TEXT
+
+static PangoEngineScriptInfo basic_scripts[] = {
+ { PANGO_SCRIPT_COMMON, "" }
+};
+
+static PangoEngineInfo script_engines[] = {
+ {
+ SCRIPT_ENGINE_NAME,
+ PANGO_ENGINE_TYPE_SHAPE,
+ RENDER_TYPE,
+ basic_scripts, G_N_ELEMENTS(basic_scripts)
+ }
+};
+
+static void
+set_glyph (PangoFont *font,
+ PangoGlyphString *glyphs,
+ int i,
+ int offset,
+ PangoGlyph glyph)
+{
+ PangoRectangle logical_rect;
+
+ glyphs->glyphs[i].glyph = glyph;
+
+ glyphs->glyphs[i].geometry.x_offset = 0;
+ glyphs->glyphs[i].geometry.y_offset = 0;
+
+ glyphs->log_clusters[i] = offset;
+ pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, NULL, &logical_rect);
+ glyphs->glyphs[i].geometry.width = logical_rect.width;
+}
+
+static void
+basic_engine_shape (PangoEngineShape *engine,
+ PangoFont *font,
+ const char *text,
+ gint length,
+ const PangoAnalysis *analysis,
+ PangoGlyphString *glyphs)
+{
+ const char *p;
+ char *copy;
+ CTLineRef line;
+ CFStringRef cstr;
+ CFDictionaryRef attributes;
+ CFAttributedStringRef attstr;
+ PangoCoreTextFont *cfont = PANGO_CORE_TEXT_FONT (font);
+ PangoCoverage *coverage;
+ CFArrayRef runs;
+ CTRunRef run;
+ CFIndex i, glyph_count;
+ const CGGlyph *cgglyphs;
+
+ CFTypeRef keys[] = {
+ (CFTypeRef) kCTFontAttributeName
+ };
+
+ CFTypeRef values[] = {
+ pango_core_text_font_get_ctfont (cfont)
+ };
+
+ attributes = CFDictionaryCreate (kCFAllocatorDefault,
+ (const void **)keys,
+ (const void **)values,
+ 1,
+ &kCFCopyStringDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+
+ copy = g_strndup (text, length + 1);
+ copy[length] = 0;
+
+ cstr = CFStringCreateWithCString (kCFAllocatorDefault, copy,
+ kCFStringEncodingUTF8);
+ g_free (copy);
+
+ attstr = CFAttributedStringCreate (kCFAllocatorDefault,
+ cstr,
+ attributes);
+
+ line = CTLineCreateWithAttributedString (attstr);
+
+ runs = CTLineGetGlyphRuns (line);
+
+ run = CFArrayGetValueAtIndex (runs, 0);
+ glyph_count = CTRunGetGlyphCount (run);
+ cgglyphs = CTRunGetGlyphsPtr (run);
+
+ p = text;
+ pango_glyph_string_set_size (glyphs, glyph_count);
+ coverage = pango_font_get_coverage (PANGO_FONT (cfont),
+ analysis->language);
+
+ for (i = 0; i < glyph_count; i++)
+ {
+ gunichar wc;
+ gunichar mirrored_ch;
+
+ wc = g_utf8_get_char (p);
+
+ if (analysis->level % 2)
+ if (pango_get_mirror_char (wc, &mirrored_ch))
+ wc = mirrored_ch;
+
+ if (wc == 0xa0) /* non-break-space */
+ wc = 0x20;
+
+ if (pango_is_zero_width (wc))
+ {
+ set_glyph (font, glyphs, i, p - text, PANGO_GLYPH_EMPTY);
+ }
+ else
+ {
+ PangoCoverageLevel result;
+
+ result = pango_coverage_get (coverage, wc);
+
+ if (result != PANGO_COVERAGE_NONE)
+ {
+ set_glyph (font, glyphs, i, p - text, cgglyphs[i]);
+
+ if (g_unichar_type (wc) == G_UNICODE_NON_SPACING_MARK)
+ {
+ if (i > 0)
+ {
+ PangoRectangle logical_rect, ink_rect;
+
+ glyphs->glyphs[i].geometry.width = MAX (glyphs->glyphs[i-1].geometry.width,
+ glyphs->glyphs[i].geometry.width);
+ glyphs->glyphs[i-1].geometry.width = 0;
+ glyphs->log_clusters[i] = glyphs->log_clusters[i-1];
+
+ /* Some heuristics to try to guess how overstrike glyphs are
+ * done and compensate
+ */
+ pango_font_get_glyph_extents (font, glyphs->glyphs[i].glyph, &ink_rect, &logical_rect);
+ if (logical_rect.width == 0 && ink_rect.x == 0)
+ glyphs->glyphs[i].geometry.x_offset = (glyphs->glyphs[i].geometry.width - ink_rect.width) / 2;
+ }
+ }
+ }
+ else
+ {
+ set_glyph (font, glyphs, i, p - text,
+ PANGO_GET_UNKNOWN_GLYPH (wc));
+ }
+ }
+
+ p = g_utf8_next_char (p);
+ }
+
+ CFRelease (line);
+ CFRelease (attstr);
+ CFRelease (cstr);
+ CFRelease (attributes);
+ pango_coverage_unref (coverage);
+}
+
+static void
+basic_engine_core_text_class_init (PangoEngineShapeClass *class)
+{
+ class->script_shape = basic_engine_shape;
+}
+
+PANGO_ENGINE_SHAPE_DEFINE_TYPE (BasicEngineCoreText, basic_engine_core_text,
+ basic_engine_core_text_class_init, NULL);
+
+void
+PANGO_MODULE_ENTRY(init) (GTypeModule *module)
+{
+ basic_engine_core_text_register_type (module);
+}
+
+void
+PANGO_MODULE_ENTRY(exit) (void)
+{
+}
+
+void
+PANGO_MODULE_ENTRY(list) (PangoEngineInfo **engines,
+ int *n_engines)
+{
+ *engines = script_engines;
+ *n_engines = G_N_ELEMENTS (script_engines);
+}
+
+PangoEngine *
+PANGO_MODULE_ENTRY(create) (const char *id)
+{
+ if (!strcmp (id, SCRIPT_ENGINE_NAME))
+ return g_object_new (basic_engine_core_text_type, NULL);
+ else
+ return NULL;
+}
+
diff --git a/pango/Makefile.am b/pango/Makefile.am
index 176d70ac..df1596d2 100644
--- a/pango/Makefile.am
+++ b/pango/Makefile.am
@@ -386,6 +386,26 @@ libpangocairo_1_0_la_SOURCES += \
endif
if HAVE_CAIRO_ATSUI
+if HAVE_CORE_TEXT
+libpangocairo_1_0_la_SOURCES += \
+ modules.h \
+ module-defs-coretext.c \
+ pangocoretext.h \
+ pangocoretext.c \
+ pangocoretext-private.h \
+ pangocoretext-fontmap.c \
+ pangocairo-coretext.h \
+ pangocairo-coretextfont.c \
+ pangocairo-coretextfont.h \
+ pangocairo-coretextfontmap.c
+pangoinclude_HEADERS += pangocoretext.h
+
+libpangocairo_1_0_la_LDFLAGS += -framework CoreFoundation -framework ApplicationServices
+libpangocairo_1_0_la_LIBADD += $(INCLUDED_CORE_TEXT_MODULES)
+# We don't have an CoreText GIR right now, so this is just hypothetical
+PANGOCAIRO_FONT_BACKEND_GI_MODULE = PangoCoreText-1.0
+
+else
libpangocairo_1_0_la_SOURCES += \
modules.h \
module-defs-atsui.c \
@@ -405,6 +425,7 @@ libpangocairo_1_0_la_LIBADD += $(INCLUDED_ATSUI_MODULES)
# We don't have an ATSUI GIR right now, so this is just hypothetical
PANGOCAIRO_FONT_BACKEND_GI_MODULE = PangoATSUI-1.0
endif
+endif
pangocairo_introspection_files = \
$(libpangocairo_1_0_la_SOURCES) \
diff --git a/pango/modules.h b/pango/modules.h
index ca22701b..7eac8fb6 100644
--- a/pango/modules.h
+++ b/pango/modules.h
@@ -30,5 +30,6 @@ extern PangoIncludedModule _pango_included_x_modules[];
extern PangoIncludedModule _pango_included_fc_modules[];
extern PangoIncludedModule _pango_included_win32_modules[];
extern PangoIncludedModule _pango_included_atsui_modules[];
+extern PangoIncludedModule _pango_included_core_text_modules[];
#endif /* __MODULES_H__ */
diff --git a/pango/pangocairo-coretext.h b/pango/pangocairo-coretext.h
new file mode 100644
index 00000000..420e1c9e
--- /dev/null
+++ b/pango/pangocairo-coretext.h
@@ -0,0 +1,55 @@
+/* Pango
+ * pangocairo-coretext.h:
+ *
+ * Copyright (C) 2005 Imendio AB
+ * Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
+ *
+ * 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 __PANGOCAIRO_CORETEXT_H__
+#define __PANGOCAIRO_CORETEXT_H__
+
+#include "pangocoretext-private.h"
+#include <pango/pangocairo.h>
+#include <cairo-quartz.h>
+
+G_BEGIN_DECLS
+
+#define PANGO_TYPE_CAIRO_CORE_TEXT_FONT_MAP (pango_cairo_core_text_font_map_get_type ())
+#define PANGO_CAIRO_CORE_TEXT_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_CORE_TEXT_FONT_MAP, PangoCairoCoreTextFontMap))
+#define PANGO_IS_CAIRO_CORE_TEXT_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_CAIRO_CORE_TEXT_FONT_MAP))
+
+typedef struct _PangoCairoCoreTextFontMap PangoCairoCoreTextFontMap;
+
+struct _PangoCairoCoreTextFontMap
+{
+ PangoCoreTextFontMap parent_instance;
+
+ gdouble dpi;
+};
+
+GType pango_cairo_core_text_font_map_get_type (void) G_GNUC_CONST;
+
+PangoCoreTextFont *
+_pango_cairo_core_text_font_new (PangoCairoCoreTextFontMap *cafontmap,
+ PangoContext *context,
+ PangoCoreTextFace *face,
+ const PangoFontDescription *desc);
+
+G_END_DECLS
+
+#endif /* __PANGOCAIRO_CORETEXT_H__ */
diff --git a/pango/pangocairo-coretextfont.c b/pango/pangocairo-coretextfont.c
new file mode 100644
index 00000000..81747ac3
--- /dev/null
+++ b/pango/pangocairo-coretextfont.c
@@ -0,0 +1,279 @@
+/* Pango
+ * pangocairo-coretextfont.c
+ *
+ * Copyright (C) 2000-2005 Red Hat Software
+ * Copyright (C) 2005-2007 Imendio AB
+ * Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
+ *
+ * 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 <Carbon/Carbon.h>
+
+#include "pango-impl-utils.h"
+#include "pangocoretext-private.h"
+#include "pangocairo.h"
+#include "pangocairo-private.h"
+#include "pangocairo-coretext.h"
+#include "pangocairo-coretextfont.h"
+
+struct _PangoCairoCoreTextFont
+{
+ PangoCoreTextFont font;
+ PangoCairoFontPrivate cf_priv;
+
+ double size;
+ int absolute_size;
+};
+
+struct _PangoCairoCoreTextFontClass
+{
+ PangoCoreTextFontClass parent_class;
+};
+
+
+
+static cairo_font_face_t *pango_cairo_core_text_font_create_font_face (PangoCairoFont *font);
+static PangoFontMetrics *pango_cairo_core_text_font_create_metrics_for_context (PangoCairoFont *font,
+ PangoContext *context);
+
+static void
+cairo_font_iface_init (PangoCairoFontIface *iface)
+{
+ iface->create_font_face = pango_cairo_core_text_font_create_font_face;
+ iface->create_metrics_for_context = pango_cairo_core_text_font_create_metrics_for_context;
+ iface->cf_priv_offset = G_STRUCT_OFFSET (PangoCairoCoreTextFont, cf_priv);
+}
+
+G_DEFINE_TYPE_WITH_CODE (PangoCairoCoreTextFont, pango_cairo_core_text_font, PANGO_TYPE_CORE_TEXT_FONT,
+ { G_IMPLEMENT_INTERFACE (PANGO_TYPE_CAIRO_FONT, cairo_font_iface_init) });
+
+/* we want get_glyph_extents extremely fast, so we use a small wrapper here
+ * to avoid having to lookup the interface data like we do for get_metrics
+ * in _pango_cairo_font_get_metrics(). */
+static void
+pango_cairo_core_text_font_get_glyph_extents (PangoFont *font,
+ PangoGlyph glyph,
+ PangoRectangle *ink_rect,
+ PangoRectangle *logical_rect)
+{
+ PangoCairoCoreTextFont *cafont = (PangoCairoCoreTextFont *) (font);
+
+ _pango_cairo_font_private_get_glyph_extents (&cafont->cf_priv,
+ glyph,
+ ink_rect,
+ logical_rect);
+}
+
+static cairo_font_face_t *
+pango_cairo_core_text_font_create_font_face (PangoCairoFont *font)
+{
+ PangoCoreTextFont *ctfont = (PangoCoreTextFont *) (font);
+ CTFontRef font_id;
+ CGFontRef cgfont;
+ cairo_font_face_t *cairo_face;
+
+ font_id = pango_core_text_font_get_ctfont (ctfont);
+ cgfont = CTFontCopyGraphicsFont (font_id, NULL);
+
+ cairo_face = cairo_quartz_font_face_create_for_cgfont (cgfont);
+
+ CFRelease (cgfont);
+
+ return cairo_face;
+}
+
+static int
+max_glyph_width (PangoLayout *layout)
+{
+ int max_width = 0;
+ GSList *l, *r;
+
+ for (l = pango_layout_get_lines_readonly (layout); l; l = l->next)
+ {
+ PangoLayoutLine *line = l->data;
+
+ for (r = line->runs; r; r = r->next)
+ {
+ PangoGlyphString *glyphs = ((PangoGlyphItem *)r->data)->glyphs;
+ int i;
+
+ for (i = 0; i < glyphs->num_glyphs; i++)
+ if (glyphs->glyphs[i].geometry.width > max_width)
+ max_width = glyphs->glyphs[i].geometry.width;
+ }
+ }
+
+ return max_width;
+}
+
+static PangoFontMetrics *
+pango_cairo_core_text_font_create_metrics_for_context (PangoCairoFont *font,
+ PangoContext *context)
+{
+ PangoCoreTextFont *cfont = (PangoCoreTextFont *) font;
+ PangoFontMetrics *metrics;
+ PangoFontDescription *font_desc;
+ PangoLayout *layout;
+ PangoRectangle extents;
+ PangoLanguage *language = pango_context_get_language (context);
+ const char *sample_str = pango_language_get_sample_string (language);
+ CTFontRef ctfont;
+
+ metrics = pango_font_metrics_new ();
+
+ ctfont = pango_core_text_font_get_ctfont (cfont);
+
+ metrics->ascent = CTFontGetAscent (ctfont) * PANGO_SCALE;
+ metrics->descent = CTFontGetDescent (ctfont) * PANGO_SCALE;
+
+ metrics->underline_position = CTFontGetUnderlinePosition (ctfont) * PANGO_SCALE;
+ metrics->underline_thickness = CTFontGetUnderlineThickness (ctfont) * PANGO_SCALE;
+
+ metrics->strikethrough_position = metrics->ascent / 3;
+ metrics->strikethrough_thickness = CTFontGetUnderlineThickness (ctfont) * PANGO_SCALE;
+
+ layout = pango_layout_new (context);
+ font_desc = pango_font_describe_with_absolute_size ((PangoFont *) font);
+ pango_layout_set_font_description (layout, font_desc);
+ pango_layout_set_text (layout, sample_str, -1);
+ pango_layout_get_extents (layout, NULL, &extents);
+
+ metrics->approximate_char_width = extents.width / pango_utf8_strwidth (sample_str);
+
+ pango_layout_set_text (layout, "0123456789", -1);
+ metrics->approximate_digit_width = max_glyph_width (layout);
+
+ pango_font_description_free (font_desc);
+ g_object_unref (layout);
+
+ return metrics;
+}
+
+static PangoFontDescription *
+pango_cairo_core_text_font_describe_absolute (PangoFont *font)
+{
+ PangoFontDescription *desc;
+ PangoCairoCoreTextFont *cafont = (PangoCairoCoreTextFont *) font;
+
+ desc = pango_font_describe (font);
+ pango_font_description_set_absolute_size (desc, cafont->absolute_size);
+
+ return desc;
+}
+
+static void
+pango_cairo_core_text_font_finalize (GObject *object)
+{
+ PangoCairoCoreTextFont *cafont = (PangoCairoCoreTextFont *) object;
+
+ _pango_cairo_font_private_finalize (&cafont->cf_priv);
+
+ G_OBJECT_CLASS (pango_cairo_core_text_font_parent_class)->finalize (object);
+}
+
+static void
+pango_cairo_core_text_font_class_init (PangoCairoCoreTextFontClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ PangoFontClass *font_class = PANGO_FONT_CLASS (class);
+
+ object_class->finalize = pango_cairo_core_text_font_finalize;
+
+ font_class->get_glyph_extents = pango_cairo_core_text_font_get_glyph_extents;
+ font_class->get_metrics = _pango_cairo_font_get_metrics;
+ font_class->describe_absolute = pango_cairo_core_text_font_describe_absolute;
+}
+
+static void
+pango_cairo_core_text_font_init (PangoCairoCoreTextFont *cafont G_GNUC_UNUSED)
+{
+}
+
+PangoCoreTextFont *
+_pango_cairo_core_text_font_new (PangoCairoCoreTextFontMap *cafontmap,
+ PangoContext *context,
+ PangoCoreTextFace *face,
+ const PangoFontDescription *desc)
+{
+ const char *postscript_name;
+ PangoCairoCoreTextFont *cafont;
+ PangoCoreTextFont *cfont;
+ CFStringRef cfstr;
+ CTFontRef font_ref;
+ CGFontRef font_id;
+ double size;
+ double dpi;
+ cairo_matrix_t font_matrix;
+
+ postscript_name = _pango_core_text_face_get_postscript_name (face);
+
+ /* Calculate size in points */
+ size = (double) pango_font_description_get_size (desc) / PANGO_SCALE;
+
+ if (context)
+ {
+ dpi = pango_cairo_context_get_resolution (context);
+
+ if (dpi <= 0)
+ dpi = cafontmap->dpi;
+ }
+ else
+ dpi = cafontmap->dpi;
+
+ if (pango_font_description_get_size_is_absolute (desc))
+ size *= dpi / 72.;
+
+
+ cfstr = CFStringCreateWithCString (NULL, postscript_name,
+ kCFStringEncodingUTF8);
+ font_ref = CTFontCreateWithName (cfstr, size, NULL);
+ CFRelease (cfstr);
+
+ /* FIXME: Do we need the synthetic italic handling here? */
+ font_id = CTFontCopyGraphicsFont (font_ref, NULL);
+ if (!font_id)
+ return NULL;
+
+ cafont = g_object_new (PANGO_TYPE_CAIRO_CORE_TEXT_FONT, NULL);
+ cfont = PANGO_CORE_TEXT_FONT (cafont);
+
+ _pango_core_text_font_set_font_description (cfont, desc);
+ _pango_core_text_font_set_face (cfont, face);
+
+ _pango_core_text_font_set_ctfont (cfont, font_ref);
+
+ if (pango_font_description_get_size_is_absolute (desc))
+ cafont->absolute_size = pango_font_description_get_size (desc);
+ else
+ cafont->absolute_size = pango_font_description_get_size (desc) * (dpi / 72.);
+
+ cafont->size = size;
+
+ cairo_matrix_init_identity (&font_matrix);
+ cairo_matrix_scale (&font_matrix, size, size);
+
+ _pango_cairo_font_private_initialize (&cafont->cf_priv,
+ (PangoCairoFont *) cafont,
+ pango_font_description_get_gravity (desc),
+ _pango_cairo_context_get_merged_font_options (context),
+ pango_context_get_matrix (context),
+ &font_matrix);
+
+ return cfont;
+}
diff --git a/pango/pangocairo-coretextfont.h b/pango/pangocairo-coretextfont.h
new file mode 100644
index 00000000..752dfdd7
--- /dev/null
+++ b/pango/pangocairo-coretextfont.h
@@ -0,0 +1,37 @@
+/* Pango
+ * pangocairo-coretextfont.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ * Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
+ *
+ * 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 __PANGOCAIRO_CORETEXTFONT_H__
+#define __PANGOCAIRO_CORETEXTFONT_H__
+
+#define PANGO_TYPE_CAIRO_CORE_TEXT_FONT (pango_cairo_core_text_font_get_type ())
+#define PANGO_CAIRO_CORE_TEXT_FONT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_CORE_TEXT_FONT, PangoCairoCoreTextFont))
+#define PANGO_CAIRO_CORE_TEXT_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_CAIRO_CORE_TEXT_FONT, PangoCairoCoreTextFontClass))
+#define PANGO_IS_CAIRO_CORE_TEXT_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_CAIRO_CORE_TEXT_FONT))
+#define PANGO_CAIRO_CORE_TEXT_FONT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_CAIRO_CORE_TEXT_FONT, PangoCairoCoreTextFontClass))
+
+typedef struct _PangoCairoCoreTextFont PangoCairoCoreTextFont;
+typedef struct _PangoCairoCoreTextFontClass PangoCairoCoreTextFontClass;
+
+GType pango_cairo_core_text_font_get_type (void) G_GNUC_CONST;
+
+#endif /* __PANGOCAIRO_CORETEXTFONT_H__ */
diff --git a/pango/pangocairo-coretextfontmap.c b/pango/pangocairo-coretextfontmap.c
new file mode 100644
index 00000000..e05a1d40
--- /dev/null
+++ b/pango/pangocairo-coretextfontmap.c
@@ -0,0 +1,107 @@
+/* Pango
+ * pangocairo-coretextfontmap.c
+ *
+ * Copyright (C) 2005 Imendio AB
+ * Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
+ *
+ * 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 "pangocoretext-private.h"
+#include "pangocairo.h"
+#include "pangocairo-private.h"
+#include "pangocairo-coretext.h"
+
+typedef struct _PangoCairoCoreTextFontMapClass PangoCairoCoreTextFontMapClass;
+
+struct _PangoCairoCoreTextFontMapClass
+{
+ PangoCoreTextFontMapClass parent_class;
+};
+
+static void
+pango_cairo_core_text_font_map_set_resolution (PangoCairoFontMap *cfontmap,
+ double dpi)
+{
+ PangoCairoCoreTextFontMap *cafontmap = PANGO_CAIRO_CORE_TEXT_FONT_MAP (cfontmap);
+
+ cafontmap->dpi = dpi;
+}
+
+static double
+pango_cairo_core_text_font_map_get_resolution (PangoCairoFontMap *cfontmap)
+{
+ PangoCairoCoreTextFontMap *cafontmap = PANGO_CAIRO_CORE_TEXT_FONT_MAP (cfontmap);
+
+ return cafontmap->dpi;
+}
+
+static cairo_font_type_t
+pango_cairo_core_text_font_map_get_font_type (PangoCairoFontMap *cfontmap)
+{
+ /* This is a bit misleading, but Cairo takes a CoreGraphics font
+ * for rendering and does not use ATSUI.
+ */
+ return CAIRO_FONT_TYPE_ATSUI;
+}
+
+static void
+cairo_font_map_iface_init (PangoCairoFontMapIface *iface)
+{
+ iface->set_resolution = pango_cairo_core_text_font_map_set_resolution;
+ iface->get_resolution = pango_cairo_core_text_font_map_get_resolution;
+ iface->get_font_type = pango_cairo_core_text_font_map_get_font_type;
+}
+
+G_DEFINE_TYPE_WITH_CODE (PangoCairoCoreTextFontMap, pango_cairo_core_text_font_map, PANGO_TYPE_CORE_TEXT_FONT_MAP,
+ { G_IMPLEMENT_INTERFACE (PANGO_TYPE_CAIRO_FONT_MAP, cairo_font_map_iface_init) });
+
+
+static PangoCoreTextFont *
+pango_cairo_core_text_font_map_create_font (PangoCoreTextFontMap *fontmap,
+ PangoContext *context,
+ PangoCoreTextFace *face,
+ const PangoFontDescription *desc)
+
+{
+ return _pango_cairo_core_text_font_new (PANGO_CAIRO_CORE_TEXT_FONT_MAP (fontmap),
+ context, face, desc);
+}
+
+static void
+pango_cairo_core_text_font_map_finalize (GObject *object)
+{
+ G_OBJECT_CLASS (pango_cairo_core_text_font_map_parent_class)->finalize (object);
+}
+
+static void
+pango_cairo_core_text_font_map_class_init (PangoCairoCoreTextFontMapClass *class)
+{
+ PangoCoreTextFontMapClass *ctfontmapclass = (PangoCoreTextFontMapClass *)class;
+ GObjectClass *object_class = (GObjectClass *)class;
+
+ object_class->finalize = pango_cairo_core_text_font_map_finalize;
+
+ ctfontmapclass->create_font = pango_cairo_core_text_font_map_create_font;
+}
+
+static void
+pango_cairo_core_text_font_map_init (PangoCairoCoreTextFontMap *cafontmap)
+{
+ cafontmap->dpi = 72.;
+}
diff --git a/pango/pangocairo-fontmap.c b/pango/pangocairo-fontmap.c
index ae917d06..94042642 100644
--- a/pango/pangocairo-fontmap.c
+++ b/pango/pangocairo-fontmap.c
@@ -26,7 +26,11 @@
#include "pango-impl-utils.h"
#if defined (HAVE_CAIRO_ATSUI)
-# include "pangocairo-atsui.h"
+# if defined (HAVE_CORE_TEXT)
+# include "pangocairo-coretext.h"
+# else
+# include "pangocairo-atsui.h"
+# endif
#endif
#if defined (HAVE_CAIRO_WIN32)
# include "pangocairo-win32.h"
@@ -92,7 +96,11 @@ pango_cairo_font_map_new (void)
g_type_init ();
#if defined(HAVE_CAIRO_ATSUI)
+#if defined(HAVE_CORE_TEXT)
+ return g_object_new (PANGO_TYPE_CAIRO_CORE_TEXT_FONT_MAP, NULL);
+#else
return g_object_new (PANGO_TYPE_CAIRO_ATSUI_FONT_MAP, NULL);
+#endif
#elif defined(HAVE_CAIRO_WIN32)
return g_object_new (PANGO_TYPE_CAIRO_WIN32_FONT_MAP, NULL);
#elif defined(HAVE_CAIRO_FREETYPE)
@@ -131,8 +139,12 @@ pango_cairo_font_map_new_for_font_type (cairo_font_type_t fonttype)
{
#if defined(HAVE_CAIRO_ATSUI)
case CAIRO_FONT_TYPE_QUARTZ:
+#if defined(HAVE_CORE_TEXT)
+ return g_object_new (PANGO_TYPE_CAIRO_CORE_TEXT_FONT_MAP, NULL);
+#else
return g_object_new (PANGO_TYPE_CAIRO_ATSUI_FONT_MAP, NULL);
#endif
+#endif
#if defined(HAVE_CAIRO_WIN32)
case CAIRO_FONT_TYPE_WIN32:
return g_object_new (PANGO_TYPE_CAIRO_WIN32_FONT_MAP, NULL);
diff --git a/pango/pangocoretext-fontmap.c b/pango/pangocoretext-fontmap.c
new file mode 100644
index 00000000..b8cf671f
--- /dev/null
+++ b/pango/pangocoretext-fontmap.c
@@ -0,0 +1,952 @@
+/* Pango
+ * pangocoretext-fontmap.c
+ *
+ * Copyright (C) 2000-2003 Red Hat, Inc.
+ * Copyright (C) 2005-2007 Imendio AB
+ * Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
+ *
+ * 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 "pango-fontmap.h"
+#include "pangocoretext-private.h"
+#include "pango-impl-utils.h"
+#include "modules.h"
+
+#include <Carbon/Carbon.h>
+
+typedef struct _FontHashKey FontHashKey;
+
+struct _PangoCoreTextFamily
+{
+ PangoFontFamily parent_instance;
+
+ char *family_name;
+
+ guint is_monospace : 1;
+
+ PangoFontFace **faces;
+ gint n_faces;
+};
+
+#define PANGO_TYPE_CORE_TEXT_FAMILY (pango_core_text_family_get_type ())
+#define PANGO_CORE_TEXT_FAMILY(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CORE_TEXT_FAMILY, PangoCoreTextFamily))
+#define PANGO_IS_CORE_TEXT_FAMILY(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_CORE_TEXT_FAMILY))
+
+#define PANGO_TYPE_CORE_TEXT_FACE (pango_core_text_face_get_type ())
+#define PANGO_CORE_TEXT_FACE(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CORE_TEXT_FACE, PangoCoreTextFace))
+#define PANGO_IS_CORE_TEXT_FACE(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_CORE_TEXT_FACE))
+
+struct _PangoCoreTextFace
+{
+ PangoFontFace parent_instance;
+
+ PangoCoreTextFamily *family;
+
+ PangoCoverage *coverage;
+
+ char *postscript_name;
+ char *style_name;
+
+ float weight;
+ int traits;
+};
+
+static GType pango_core_text_family_get_type (void);
+static GType pango_core_text_face_get_type (void);
+
+static gpointer pango_core_text_family_parent_class;
+static gpointer pango_core_text_face_parent_class;
+
+static const char *
+get_real_family (const char *family_name)
+{
+ switch (family_name[0])
+ {
+ case 'm':
+ case 'M':
+ if (g_ascii_strcasecmp (family_name, "monospace") == 0)
+ return "Courier";
+ break;
+ case 's':
+ case 'S':
+ if (g_ascii_strcasecmp (family_name, "sans") == 0)
+ return "Helvetica";
+ else if (g_ascii_strcasecmp (family_name, "serif") == 0)
+ return "Times";
+ break;
+ }
+
+ return family_name;
+}
+
+static gchar *
+gchar_from_cf_string (CFStringRef str)
+{
+ CFIndex len;
+ gchar *buffer;
+
+ /* GetLength returns the number of UTF-16 pairs, so this number
+ * times 2 should definitely gives us enough space for UTF8.
+ * We add one for the terminating zero.
+ */
+ len = CFStringGetLength (str) * 2 + 1;
+ buffer = g_new0 (char, len);
+ CFStringGetCString (str, buffer, len, kCFStringEncodingUTF8);
+
+ return buffer;
+}
+
+static PangoCoverage *
+pango_coverage_from_cf_charset (CFCharacterSetRef charset)
+{
+ CFIndex i, length;
+ CFDataRef bitmap;
+ const UInt8 *ptr;
+ PangoCoverage *coverage;
+
+ coverage = pango_coverage_new ();
+
+ bitmap = CFCharacterSetCreateBitmapRepresentation (kCFAllocatorDefault,
+ charset);
+
+ /* We only handle the BMP plane */
+ length = MIN (CFDataGetLength (bitmap), 8192);
+ ptr = CFDataGetBytePtr (bitmap);
+
+ /* FIXME: can and should this be done more efficiently? */
+ for (i = 0; i < length; i++)
+ {
+ int j;
+
+ for (j = 0; j < 8; j++)
+ pango_coverage_set (coverage, i * 8 + j,
+ ((ptr[i] & (1 << j)) == (1 << j)) ?
+ PANGO_COVERAGE_EXACT : PANGO_COVERAGE_NONE);
+ }
+
+ CFRelease (bitmap);
+
+ return coverage;
+}
+
+static void
+pango_core_text_family_list_faces (PangoFontFamily *family,
+ PangoFontFace ***faces,
+ int *n_faces)
+{
+ PangoCoreTextFamily *ctfamily = PANGO_CORE_TEXT_FAMILY (family);
+
+ if (ctfamily->n_faces < 0)
+ {
+ GList *l;
+ GList *faces = NULL;
+ const char *real_family = get_real_family (ctfamily->family_name);
+ CTFontCollectionRef collection;
+ CFArrayRef ctfaces;
+ CFArrayRef font_descriptors;
+ CFDictionaryRef attributes;
+ CFIndex i, count;
+
+ CFTypeRef keys[] = {
+ (CFTypeRef) kCTFontFamilyNameAttribute
+ };
+
+ CFStringRef values[] = {
+ CFStringCreateWithCString (kCFAllocatorDefault,
+ real_family,
+ kCFStringEncodingUTF8)
+ };
+
+ CTFontDescriptorRef descriptors[1];
+
+ attributes = CFDictionaryCreate (kCFAllocatorDefault,
+ (const void **)keys,
+ (const void **)values,
+ 1,
+ &kCFTypeDictionaryKeyCallBacks,
+ &kCFTypeDictionaryValueCallBacks);
+ descriptors[0] = CTFontDescriptorCreateWithAttributes (attributes);
+ font_descriptors = CFArrayCreate (kCFAllocatorDefault,
+ (const void **)descriptors,
+ 1,
+ &kCFTypeArrayCallBacks);
+ collection = CTFontCollectionCreateWithFontDescriptors (font_descriptors,
+ NULL);
+
+ ctfaces = CTFontCollectionCreateMatchingFontDescriptors (collection);
+
+ /* FIXME: do we need the code for the synthetic italic faces? */
+ count = CFArrayGetCount (ctfaces);
+ for (i = 0; i < count; i++)
+ {
+ int font_traits;
+ char *buffer;
+ CFStringRef str;
+ CFNumberRef number;
+ CGFloat value;
+ CFDictionaryRef dict;
+ CFCharacterSetRef charset;
+ CTFontDescriptorRef desc = CFArrayGetValueAtIndex (ctfaces, i);
+ PangoCoreTextFace *face = g_object_new (PANGO_TYPE_CORE_TEXT_FACE,
+ NULL);
+
+ face->family = ctfamily;
+
+ /* Get font name */
+ str = CTFontDescriptorCopyAttribute (desc, kCTFontNameAttribute);
+ buffer = gchar_from_cf_string (str);
+
+ /* We strdup again to save space. */
+ face->postscript_name = g_strdup (buffer);
+
+ CFRelease (str);
+ g_free (buffer);
+
+ /* Get style name */
+ str = CTFontDescriptorCopyAttribute (desc, kCTFontStyleNameAttribute);
+ buffer = gchar_from_cf_string (str);
+
+ face->style_name = g_strdup (buffer);
+
+ CFRelease (str);
+ g_free (buffer);
+
+ /* Get font traits, symbolic traits */
+ dict = CTFontDescriptorCopyAttribute (desc, kCTFontTraitsAttribute);
+ number = (CFNumberRef)CFDictionaryGetValue (dict,
+ kCTFontWeightTrait);
+ if (CFNumberGetValue (number, kCFNumberCGFloatType, &value))
+ /* Map value from range [-1.0, 1.0] to range [1, 14] */
+ face->weight = (value + 1.0f) * 6.5f + 1;
+ else
+ face->weight = PANGO_WEIGHT_NORMAL;
+
+ number = (CFNumberRef)CFDictionaryGetValue (dict,
+ kCTFontSymbolicTrait);
+ if (CFNumberGetValue (number, kCFNumberIntType, &font_traits))
+ {
+ face->traits = font_traits;
+ }
+ CFRelease (dict);
+
+ /* Get font coverage */
+ charset = CTFontDescriptorCopyAttribute (desc,
+ kCTFontCharacterSetAttribute);
+ face->coverage = pango_coverage_from_cf_charset (charset);
+ CFRelease (charset);
+
+ faces = g_list_prepend (faces, face);
+ }
+
+ CFRelease (font_descriptors);
+ CFRelease (attributes);
+ CFRelease (ctfaces);
+
+ ctfamily->n_faces = g_list_length (faces);
+ ctfamily->faces = g_new (PangoFontFace *, ctfamily->n_faces);
+
+ for (l = faces, i = 0; l; l = l->next, i++)
+ ctfamily->faces[i] = l->data;
+
+ g_list_free (faces);
+ }
+
+ if (n_faces)
+ *n_faces = ctfamily->n_faces;
+
+ if (faces)
+ *faces = g_memdup (ctfamily->faces, ctfamily->n_faces * sizeof (PangoFontFace *));
+}
+
+static const char *
+pango_core_text_family_get_name (PangoFontFamily *family)
+{
+ PangoCoreTextFamily *ctfamily = PANGO_CORE_TEXT_FAMILY (family);
+
+ return ctfamily->family_name;
+}
+
+static gboolean
+pango_core_text_family_is_monospace (PangoFontFamily *family)
+{
+ PangoCoreTextFamily *ctfamily = PANGO_CORE_TEXT_FAMILY (family);
+
+ return ctfamily->is_monospace;
+}
+
+static void
+pango_core_text_family_finalize (GObject *object)
+{
+ PangoCoreTextFamily *family = PANGO_CORE_TEXT_FAMILY (object);
+ int i;
+
+ g_free (family->family_name);
+
+ if (family->n_faces != -1)
+ {
+ for (i = 0; i < family->n_faces; i++)
+ g_object_unref (family->faces[i]);
+
+ g_free (family->faces);
+ }
+
+ G_OBJECT_CLASS (pango_core_text_family_parent_class)->finalize (object);
+}
+
+static void
+pango_core_text_family_class_init (PangoFontFamilyClass *class)
+{
+ GObjectClass *object_class = (GObjectClass *)class;
+ int i;
+
+ pango_core_text_family_parent_class = g_type_class_peek_parent (class);
+
+ object_class->finalize = pango_core_text_family_finalize;
+
+ class->list_faces = pango_core_text_family_list_faces;
+ class->get_name = pango_core_text_family_get_name;
+ class->is_monospace = pango_core_text_family_is_monospace;
+
+ for (i = 0; _pango_included_core_text_modules[i].list; i++)
+ pango_module_register (&_pango_included_core_text_modules[i]);
+}
+
+static void
+pango_core_text_family_init (PangoCoreTextFamily *family)
+{
+ family->n_faces = -1;
+}
+
+static GType
+pango_core_text_family_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (G_UNLIKELY (!object_type))
+ {
+ const GTypeInfo object_info =
+ {
+ sizeof (PangoFontFamilyClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) pango_core_text_family_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (PangoCoreTextFamily),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) pango_core_text_family_init,
+ };
+
+ object_type = g_type_register_static (PANGO_TYPE_FONT_FAMILY,
+ I_("PangoCoreTextFamily"),
+ &object_info, 0);
+ }
+
+ return object_type;
+}
+
+static PangoFontDescription *
+pango_core_text_face_describe (PangoFontFace *face)
+{
+ PangoCoreTextFace *ctface = PANGO_CORE_TEXT_FACE (face);
+ PangoFontDescription *description;
+ PangoWeight pango_weight;
+ PangoStyle pango_style;
+ PangoVariant pango_variant;
+ int weight;
+
+ description = pango_font_description_new ();
+
+ pango_font_description_set_family (description, ctface->family->family_name);
+
+ weight = ctface->weight;
+
+ switch (weight)
+ {
+ case 1:
+ case 2:
+ pango_weight = PANGO_WEIGHT_ULTRALIGHT;
+ break;
+
+ case 3:
+ case 4:
+ pango_weight = PANGO_WEIGHT_LIGHT;
+ break;
+
+ case 5:
+ case 6:
+ pango_weight = PANGO_WEIGHT_NORMAL;
+ break;
+
+ case 7:
+ case 8:
+ pango_weight = PANGO_WEIGHT_SEMIBOLD;
+ break;
+
+ case 9:
+ case 10:
+ pango_weight = PANGO_WEIGHT_BOLD;
+ break;
+
+ case 11:
+ case 12:
+ pango_weight = PANGO_WEIGHT_ULTRABOLD;
+ break;
+
+ case 13:
+ case 14:
+ pango_weight = PANGO_WEIGHT_HEAVY;
+ break;
+
+ default:
+ g_assert_not_reached ();
+ };
+
+ if (ctface->traits & kCTFontItalicTrait)
+ pango_style = PANGO_STYLE_ITALIC;
+ else
+ pango_style = PANGO_STYLE_NORMAL;
+
+ /* FIXME: How can this be figured using CoreText? */
+#if 0
+ if (ctface->traits & NSSmallCapsFontMask)
+ pango_variant = PANGO_VARIANT_SMALL_CAPS;
+ else
+#endif
+ pango_variant = PANGO_VARIANT_NORMAL;
+
+ pango_font_description_set_weight (description, pango_weight);
+ pango_font_description_set_style (description, pango_style);
+ pango_font_description_set_variant (description, pango_variant);
+
+ return description;
+}
+
+static const char *
+pango_core_text_face_get_face_name (PangoFontFace *face)
+{
+ PangoCoreTextFace *ctface = PANGO_CORE_TEXT_FACE (face);
+
+ return ctface->style_name;
+}
+
+static void
+pango_core_text_face_list_sizes (PangoFontFace *face,
+ int **sizes,
+ int *n_sizes)
+{
+ *n_sizes = 0;
+ *sizes = NULL;
+}
+
+static void
+pango_core_text_face_finalize (GObject *object)
+{
+ PangoCoreTextFace *ctface = PANGO_CORE_TEXT_FACE (object);
+
+ if (ctface->coverage)
+ pango_coverage_unref (ctface->coverage);
+
+ g_free (ctface->postscript_name);
+ g_free (ctface->style_name);
+
+ G_OBJECT_CLASS (pango_core_text_face_parent_class)->finalize (object);
+}
+
+static void
+pango_core_text_face_class_init (PangoFontFaceClass *class)
+{
+ GObjectClass *object_class = (GObjectClass *)class;
+
+ pango_core_text_face_parent_class = g_type_class_peek_parent (class);
+
+ object_class->finalize = pango_core_text_face_finalize;
+
+ class->describe = pango_core_text_face_describe;
+ class->get_face_name = pango_core_text_face_get_face_name;
+ class->list_sizes = pango_core_text_face_list_sizes;
+}
+
+GType
+pango_core_text_face_get_type (void)
+{
+ static GType object_type = 0;
+
+ if (G_UNLIKELY (!object_type))
+ {
+ const GTypeInfo object_info =
+ {
+ sizeof (PangoFontFaceClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) pango_core_text_face_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (PangoCoreTextFace),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) NULL,
+ };
+
+ object_type = g_type_register_static (PANGO_TYPE_FONT_FACE,
+ I_("PangoCoreTextFace"),
+ &object_info, 0);
+ }
+
+ return object_type;
+}
+
+const char *
+_pango_core_text_face_get_postscript_name (PangoCoreTextFace *face)
+{
+ return face->postscript_name;
+}
+
+PangoCoverage *
+_pango_core_text_face_get_coverage (PangoCoreTextFace *face,
+ PangoLanguage *language)
+{
+ return face->coverage;
+}
+
+static void pango_core_text_font_map_class_init (PangoCoreTextFontMapClass *class);
+static void pango_core_text_font_map_init (PangoCoreTextFontMap *ctfontmap);
+
+static guint font_hash_key_hash (const FontHashKey *key);
+static gboolean font_hash_key_equal (const FontHashKey *key_a,
+ const FontHashKey *key_b);
+static void font_hash_key_free (FontHashKey *key);
+
+G_DEFINE_TYPE (PangoCoreTextFontMap, pango_core_text_font_map, PANGO_TYPE_FONT_MAP);
+
+static void
+pango_core_text_font_map_finalize (GObject *object)
+{
+ PangoCoreTextFontMap *fontmap = PANGO_CORE_TEXT_FONT_MAP (object);
+
+ g_hash_table_destroy (fontmap->font_hash);
+ g_hash_table_destroy (fontmap->families);
+
+ G_OBJECT_CLASS (pango_core_text_font_map_parent_class)->finalize (object);
+}
+
+struct _FontHashKey {
+ PangoCoreTextFontMap *fontmap;
+ PangoMatrix matrix;
+ PangoFontDescription *desc;
+ char *postscript_name;
+ gpointer context_key;
+};
+
+/* Fowler / Noll / Vo (FNV) Hash (http://www.isthe.com/chongo/tech/comp/fnv/)
+ *
+ * Not necessarily better than a lot of other hashes, but should be OK, and
+ * well tested with binary data.
+ */
+
+#define FNV_32_PRIME ((guint32)0x01000193)
+#define FNV1_32_INIT ((guint32)0x811c9dc5)
+
+static guint32
+hash_bytes_fnv (unsigned char *buffer,
+ int len,
+ guint32 hval)
+{
+ while (len--)
+ {
+ hval *= FNV_32_PRIME;
+ hval ^= *buffer++;
+ }
+
+ return hval;
+}
+
+static gboolean
+font_hash_key_equal (const FontHashKey *key_a,
+ const FontHashKey *key_b)
+{
+ if (key_a->matrix.xx == key_b->matrix.xx &&
+ key_a->matrix.xy == key_b->matrix.xy &&
+ key_a->matrix.yx == key_b->matrix.yx &&
+ key_a->matrix.yy == key_b->matrix.yy &&
+ pango_font_description_equal (key_a->desc, key_b->desc) &&
+ strcmp (key_a->postscript_name, key_b->postscript_name) == 0)
+ {
+ if (key_a->context_key)
+ return PANGO_CORE_TEXT_FONT_MAP_GET_CLASS (key_a->fontmap)->context_key_equal (key_a->fontmap,
+ key_a->context_key,
+ key_b->context_key);
+ else
+ return TRUE;
+ }
+ else
+ return FALSE;
+}
+
+static guint
+font_hash_key_hash (const FontHashKey *key)
+{
+ guint32 hash = FNV1_32_INIT;
+
+ /* We do a bytewise hash on the context matrix */
+ hash = hash_bytes_fnv ((unsigned char *)(&key->matrix),
+ sizeof(double) * 4,
+ hash);
+
+ if (key->context_key)
+ hash ^= PANGO_CORE_TEXT_FONT_MAP_GET_CLASS (key->fontmap)->context_key_hash (key->fontmap,
+ key->context_key);
+
+ hash ^= g_str_hash (key->postscript_name);
+
+ return (hash ^ pango_font_description_hash (key->desc));
+}
+
+static void
+font_hash_key_free (FontHashKey *key)
+{
+ if (key->context_key)
+ PANGO_CORE_TEXT_FONT_MAP_GET_CLASS (key->fontmap)->context_key_free (key->fontmap,
+ key->context_key);
+
+ g_slice_free (FontHashKey, key);
+}
+
+static FontHashKey *
+font_hash_key_copy (FontHashKey *old)
+{
+ FontHashKey *key = g_slice_new (FontHashKey);
+
+ key->fontmap = old->fontmap;
+ key->matrix = old->matrix;
+ key->desc = pango_font_description_copy (old->desc);
+ key->postscript_name = g_strdup (old->postscript_name);
+ if (old->context_key)
+ key->context_key = PANGO_CORE_TEXT_FONT_MAP_GET_CLASS (key->fontmap)->context_key_copy (key->fontmap, old->context_key);
+ else
+ key->context_key = NULL;
+
+ return key;
+}
+
+
+static void
+get_context_matrix (PangoContext *context,
+ PangoMatrix *matrix)
+{
+ const PangoMatrix *set_matrix;
+ static const PangoMatrix identity = PANGO_MATRIX_INIT;
+
+ if (context)
+ set_matrix = pango_context_get_matrix (context);
+ else
+ set_matrix = NULL;
+
+ if (set_matrix)
+ *matrix = *set_matrix;
+ else
+ *matrix = identity;
+}
+
+static void
+font_hash_key_for_context (PangoCoreTextFontMap *fcfontmap,
+ PangoContext *context,
+ FontHashKey *key)
+{
+ key->fontmap = fcfontmap;
+ get_context_matrix (context, &key->matrix);
+
+ if (PANGO_CORE_TEXT_FONT_MAP_GET_CLASS (fcfontmap)->context_key_get)
+ key->context_key = (gpointer)PANGO_CORE_TEXT_FONT_MAP_GET_CLASS (fcfontmap)->context_key_get (fcfontmap, context);
+ else
+ key->context_key = NULL;
+}
+
+static void
+pango_core_text_font_map_add (PangoCoreTextFontMap *ctfontmap,
+ PangoContext *context,
+ PangoCoreTextFont *ctfont)
+{
+ FontHashKey key;
+ FontHashKey *key_copy;
+ PangoCoreTextFace *face;
+
+ _pango_core_text_font_set_font_map (ctfont, ctfontmap);
+
+ font_hash_key_for_context (ctfontmap, context, &key);
+ face = _pango_core_text_font_get_face (ctfont);
+ key.postscript_name = (char *)_pango_core_text_face_get_postscript_name (face);
+ key.desc = _pango_core_text_font_get_font_description (ctfont);
+
+ key_copy = font_hash_key_copy (&key);
+ _pango_core_text_font_set_context_key (ctfont, key_copy->context_key);
+ g_hash_table_insert (ctfontmap->font_hash, key_copy, g_object_ref (ctfont));
+}
+
+static PangoCoreTextFont *
+pango_core_text_font_map_lookup (PangoCoreTextFontMap *ctfontmap,
+ PangoContext *context,
+ PangoFontDescription *desc,
+ PangoCoreTextFace *face)
+{
+ FontHashKey key;
+
+ font_hash_key_for_context (ctfontmap, context, &key);
+ key.postscript_name = (char *)_pango_core_text_face_get_postscript_name (face);
+ key.desc = desc;
+
+ return g_hash_table_lookup (ctfontmap->font_hash, &key);
+}
+
+static gboolean
+find_best_match (PangoCoreTextFamily *font_family,
+ const PangoFontDescription *description,
+ PangoFontDescription **best_description,
+ PangoCoreTextFace **best_face)
+{
+ PangoFontDescription *new_desc;
+ int i;
+
+ *best_description = NULL;
+ *best_face = NULL;
+
+ for (i = 0; i < font_family->n_faces; i++)
+ {
+ new_desc = pango_font_face_describe (font_family->faces[i]);
+
+ if (pango_font_description_better_match (description, *best_description, new_desc))
+ {
+ pango_font_description_free (*best_description);
+ *best_description = new_desc;
+ *best_face = (PangoCoreTextFace *)font_family->faces[i];
+ }
+ else
+ pango_font_description_free (new_desc);
+ }
+
+ if (*best_description)
+ return TRUE;
+
+ return FALSE;
+}
+
+static PangoFont *
+pango_core_text_font_map_load_font (PangoFontMap *fontmap,
+ PangoContext *context,
+ const PangoFontDescription *description)
+{
+ PangoCoreTextFontMap *ctfontmap = (PangoCoreTextFontMap *)fontmap;
+ PangoCoreTextFamily *font_family;
+ const gchar *family;
+ gchar *name;
+ gint size;
+
+ size = pango_font_description_get_size (description);
+ if (size < 0)
+ return NULL;
+
+ family = pango_font_description_get_family (description);
+ family = family ? family : "";
+ name = g_utf8_casefold (family, -1);
+ font_family = g_hash_table_lookup (ctfontmap->families, name);
+ g_free (name);
+
+ if (font_family)
+ {
+ PangoFontDescription *best_description;
+ PangoCoreTextFace *best_face;
+ PangoCoreTextFont *best_font;
+
+ /* Force a listing of the available faces */
+ pango_font_family_list_faces ((PangoFontFamily *)font_family, NULL, NULL);
+
+ if (!find_best_match (font_family, description, &best_description, &best_face))
+ return NULL;
+
+ pango_font_description_set_size (best_description, size);
+
+ best_font = pango_core_text_font_map_lookup (ctfontmap,
+ context,
+ best_description,
+ best_face);
+
+ if (best_font)
+ g_object_ref (best_font);
+ else
+ {
+ PangoCoreTextFontMapClass *klass;
+
+ klass = PANGO_CORE_TEXT_FONT_MAP_GET_CLASS (ctfontmap);
+ best_font = klass->create_font (ctfontmap, context,
+ best_face, best_description);
+
+ if (best_font)
+ pango_core_text_font_map_add (ctfontmap, context, best_font);
+ /* FIXME: Handle the else case here. */
+ }
+
+ pango_font_description_free (best_description);
+
+ return (PangoFont *)best_font;
+ }
+
+ return NULL;
+}
+
+static void
+list_families_foreach (gpointer key,
+ gpointer value,
+ gpointer user_data)
+{
+ GSList **list = user_data;
+
+ *list = g_slist_prepend (*list, value);
+}
+
+static void
+pango_core_text_font_map_list_families (PangoFontMap *fontmap,
+ PangoFontFamily ***families,
+ int *n_families)
+{
+ GSList *family_list = NULL;
+ GSList *tmp_list;
+ PangoCoreTextFontMap *ctfontmap = (PangoCoreTextFontMap *)fontmap;
+
+ if (!n_families)
+ return;
+
+ g_hash_table_foreach (ctfontmap->families,
+ list_families_foreach, &family_list);
+
+ *n_families = g_slist_length (family_list);
+
+ if (families)
+ {
+ int i = 0;
+
+ *families = g_new (PangoFontFamily *, *n_families);
+
+ tmp_list = family_list;
+ while (tmp_list)
+ {
+ (*families)[i] = tmp_list->data;
+ i++;
+ tmp_list = tmp_list->next;
+ }
+ }
+
+ g_slist_free (family_list);
+}
+
+static void
+pango_core_text_font_map_init (PangoCoreTextFontMap *ctfontmap)
+{
+ PangoCoreTextFamily *family;
+ CTFontCollectionRef collection;
+ CFArrayRef ctfaces;
+ CFIndex i, count;
+
+ ctfontmap->families = g_hash_table_new_full (g_str_hash, g_str_equal,
+ g_free, g_object_unref);
+
+
+ ctfontmap->font_hash = g_hash_table_new_full ((GHashFunc)font_hash_key_hash,
+ (GEqualFunc)font_hash_key_equal,
+ (GDestroyNotify)font_hash_key_free,
+ NULL);
+
+ collection = CTFontCollectionCreateFromAvailableFonts (0);
+ ctfaces = CTFontCollectionCreateMatchingFontDescriptors (collection);
+ count = CFArrayGetCount (ctfaces);
+
+ for (i = 0; i < count; i++)
+ {
+ int font_traits;
+ char *buffer;
+ char *family_name;
+ CFStringRef str;
+ CFNumberRef number;
+ CFDictionaryRef dict;
+ CTFontDescriptorRef desc = CFArrayGetValueAtIndex (ctfaces, i);
+
+ str = CTFontDescriptorCopyAttribute (desc, kCTFontFamilyNameAttribute);
+ buffer = gchar_from_cf_string (str);
+
+ family_name = g_utf8_casefold (buffer, -1);
+
+ CFRelease (str);
+ g_free (buffer);
+
+ family = g_hash_table_lookup (ctfontmap->families, family_name);
+ if (!family)
+ {
+ family = g_object_new (PANGO_TYPE_CORE_TEXT_FAMILY, NULL);
+ g_hash_table_insert (ctfontmap->families, g_strdup (family_name),
+ family);
+
+ family->family_name = family_name;
+ family_name = NULL;
+ }
+
+ if (family_name)
+ g_free (family_name);
+
+ /* We assume that all faces in the family are monospaced or none. */
+ dict = CTFontDescriptorCopyAttribute (desc, kCTFontTraitsAttribute);
+ number = (CFNumberRef)CFDictionaryGetValue (dict,
+ kCTFontSymbolicTrait);
+
+ if (CFNumberGetValue (number, kCFNumberIntType, &font_traits))
+ {
+ if (font_traits & kCTFontMonoSpaceTrait)
+ family->is_monospace = TRUE;
+ }
+
+ CFRelease (dict);
+ }
+
+ /* Insert aliases */
+ family = g_object_new (PANGO_TYPE_CORE_TEXT_FAMILY, NULL);
+ family->family_name = g_strdup ("Sans");
+ g_hash_table_insert (ctfontmap->families,
+ g_utf8_casefold (family->family_name, -1), family);
+
+ family = g_object_new (PANGO_TYPE_CORE_TEXT_FAMILY, NULL);
+ family->family_name = g_strdup ("Serif");
+ g_hash_table_insert (ctfontmap->families,
+ g_utf8_casefold (family->family_name, -1), family);
+
+ family = g_object_new (PANGO_TYPE_CORE_TEXT_FAMILY, NULL);
+ family->family_name = g_strdup ("Monospace");
+ family->is_monospace = TRUE;
+ g_hash_table_insert (ctfontmap->families,
+ g_utf8_casefold (family->family_name, -1), family);
+}
+
+static void
+pango_core_text_font_map_class_init (PangoCoreTextFontMapClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ PangoFontMapClass *fontmap_class = PANGO_FONT_MAP_CLASS (class);
+
+ object_class->finalize = pango_core_text_font_map_finalize;
+
+ fontmap_class->load_font = pango_core_text_font_map_load_font;
+ fontmap_class->list_families = pango_core_text_font_map_list_families;
+ fontmap_class->shape_engine_type = PANGO_RENDER_TYPE_CORE_TEXT;
+}
diff --git a/pango/pangocoretext-private.h b/pango/pangocoretext-private.h
new file mode 100644
index 00000000..dd5cff84
--- /dev/null
+++ b/pango/pangocoretext-private.h
@@ -0,0 +1,101 @@
+/* Pango
+ * pangocoretext-private.h:
+ *
+ * Copyright (C) 2003 Red Hat Software
+ * Copyright (C) 2005-2007 Imendio AB
+ * Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
+ *
+ * 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 __PANGOCORETEXT_PRIVATE_H__
+#define __PANGOCORETEXT_PRIVATE_H__
+
+#include <pango/pango-fontmap.h>
+#include <pango/pango-context.h>
+#include "pangocoretext.h"
+
+G_BEGIN_DECLS
+
+#define PANGO_TYPE_CORE_TEXT_FONT_MAP (pango_core_text_font_map_get_type ())
+#define PANGO_CORE_TEXT_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CORE_TEXT_FONT_MAP, PangoCoreTextFontMap))
+#define PANGO_CORE_TEXT_IS_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_CORE_TEXT_FONT_MAP))
+#define PANGO_CORE_TEXT_FONT_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_CORE_TEXT_FONT_MAP, PangoCoreTextFontMapClass))
+#define PANGO_IS_CORE_TEXT_FONT_MAP_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_CORE_TEXT_FONT_MAP))
+#define PANGO_CORE_TEXT_FONT_MAP_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_CORE_TEXT_FONT_MAP, PangoCoreTextFontMapClass))
+
+
+typedef struct _PangoCoreTextFamily PangoCoreTextFamily;
+typedef struct _PangoCoreTextFace PangoCoreTextFace;
+
+typedef struct _PangoCoreTextFontMap PangoCoreTextFontMap;
+typedef struct _PangoCoreTextFontMapClass PangoCoreTextFontMapClass;
+
+struct _PangoCoreTextFontMap
+{
+ PangoFontMap parent_instance;
+
+ GHashTable *font_hash;
+
+ GHashTable *families;
+};
+
+struct _PangoCoreTextFontMapClass
+{
+ PangoFontMapClass parent_class;
+
+ gconstpointer (*context_key_get) (PangoCoreTextFontMap *ctfontmap,
+ PangoContext *context);
+ gpointer (*context_key_copy) (PangoCoreTextFontMap *ctfontmap,
+ gconstpointer key);
+ void (*context_key_free) (PangoCoreTextFontMap *ctfontmap,
+ gpointer key);
+ guint32 (*context_key_hash) (PangoCoreTextFontMap *ctfontmap,
+ gconstpointer key);
+ gboolean (*context_key_equal) (PangoCoreTextFontMap *ctfontmap,
+ gconstpointer key_a,
+ gconstpointer key_b);
+
+ PangoCoreTextFont * (* create_font) (PangoCoreTextFontMap *fontmap,
+ PangoContext *context,
+ PangoCoreTextFace *face,
+ const PangoFontDescription *desc);
+};
+
+
+GType pango_core_text_font_map_get_type (void) G_GNUC_CONST;
+
+const char * _pango_core_text_face_get_postscript_name (PangoCoreTextFace *face);
+PangoCoverage * _pango_core_text_face_get_coverage (PangoCoreTextFace *face,
+ PangoLanguage *language);
+
+void _pango_core_text_font_set_font_description (PangoCoreTextFont *afont,
+ const PangoFontDescription *desc);
+PangoFontDescription *_pango_core_text_font_get_font_description (PangoCoreTextFont *afont);
+void _pango_core_text_font_set_font_map (PangoCoreTextFont *afont,
+ PangoCoreTextFontMap *fontmap);
+void _pango_core_text_font_set_face (PangoCoreTextFont *afont,
+ PangoCoreTextFace *aface);
+PangoCoreTextFace * _pango_core_text_font_get_face (PangoCoreTextFont *font);
+gpointer _pango_core_text_font_get_context_key (PangoCoreTextFont *afont);
+void _pango_core_text_font_set_context_key (PangoCoreTextFont *afont,
+ gpointer context_key);
+void _pango_core_text_font_set_ctfont (PangoCoreTextFont *font,
+ CTFontRef font_ref);
+
+G_END_DECLS
+
+#endif /* __PANGOCORETEXT_PRIVATE_H__ */
diff --git a/pango/pangocoretext.c b/pango/pangocoretext.c
new file mode 100644
index 00000000..4d3ebb9a
--- /dev/null
+++ b/pango/pangocoretext.c
@@ -0,0 +1,205 @@
+/* Pango
+ * pangocoretext.c
+ *
+ * Copyright (C) 2005-2007 Imendio AB
+ * Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
+ *
+ * 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 "pangocoretext.h"
+#include "pangocoretext-private.h"
+
+G_DEFINE_TYPE (PangoCoreTextFont, pango_core_text_font, PANGO_TYPE_FONT);
+
+struct _PangoCoreTextFontPrivate
+{
+ PangoCoreTextFace *face;
+ PangoFontDescription *desc;
+ gpointer context_key;
+
+ CTFontRef font_ref;
+
+ PangoFontMap *fontmap;
+};
+
+static void
+pango_core_text_font_finalize (GObject *object)
+{
+ PangoCoreTextFont *ctfont = (PangoCoreTextFont *)object;
+ PangoCoreTextFontPrivate *priv = ctfont->priv;
+
+ pango_font_description_free (priv->desc);
+
+ g_assert (priv->fontmap != NULL);
+ g_object_remove_weak_pointer (G_OBJECT (priv->fontmap), (gpointer *) (gpointer) &priv->fontmap);
+ priv->fontmap = NULL;
+
+ G_OBJECT_CLASS (pango_core_text_font_parent_class)->finalize (object);
+}
+
+static PangoFontDescription *
+pango_core_text_font_describe (PangoFont *font)
+{
+ PangoCoreTextFont *ctfont = (PangoCoreTextFont *)font;
+ PangoCoreTextFontPrivate *priv = ctfont->priv;
+
+ return pango_font_description_copy (priv->desc);
+}
+
+static PangoCoverage *
+pango_core_text_font_get_coverage (PangoFont *font,
+ PangoLanguage *language)
+{
+ PangoCoreTextFont *ctfont = (PangoCoreTextFont *)font;
+ PangoCoreTextFontPrivate *priv = ctfont->priv;
+
+ return pango_coverage_ref (_pango_core_text_face_get_coverage (priv->face,
+ language));
+}
+
+static PangoEngineShape *
+pango_core_text_font_find_shaper (PangoFont *font,
+ PangoLanguage *language,
+ guint32 ch)
+{
+ /* FIXME: Implement */
+ return NULL;
+}
+
+static PangoFontMap *
+pango_core_text_font_get_font_map (PangoFont *font)
+{
+ PangoCoreTextFont *ctfont = (PangoCoreTextFont *)font;
+
+ return ctfont->priv->fontmap;
+}
+
+static void
+pango_core_text_font_init (PangoCoreTextFont *ctfont)
+{
+ ctfont->priv = G_TYPE_INSTANCE_GET_PRIVATE (ctfont,
+ PANGO_TYPE_CORE_TEXT_FONT,
+ PangoCoreTextFontPrivate);
+}
+
+static void
+pango_core_text_font_class_init (PangoCoreTextFontClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ PangoFontClass *font_class = PANGO_FONT_CLASS (class);
+
+ object_class->finalize = pango_core_text_font_finalize;
+
+ font_class->describe = pango_core_text_font_describe;
+ 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;
+
+ g_type_class_add_private (object_class, sizeof (PangoCoreTextFontPrivate));
+}
+
+/* FIXME: why are these defined like this? */
+void
+_pango_core_text_font_set_font_description (PangoCoreTextFont *font,
+ const PangoFontDescription *desc)
+{
+ PangoCoreTextFontPrivate *priv = font->priv;
+
+ priv->desc = pango_font_description_copy (desc);
+}
+
+PangoFontDescription *
+_pango_core_text_font_get_font_description (PangoCoreTextFont *font)
+{
+ PangoCoreTextFontPrivate *priv = font->priv;
+
+ return priv->desc;
+}
+
+void
+_pango_core_text_font_set_font_map (PangoCoreTextFont *font,
+ PangoCoreTextFontMap *fontmap)
+{
+ PangoCoreTextFontPrivate *priv = font->priv;
+
+ g_assert (priv->fontmap == NULL);
+ priv->fontmap = (PangoFontMap *) fontmap;
+ g_object_add_weak_pointer (G_OBJECT (priv->fontmap), (gpointer *) (gpointer) &priv->fontmap);
+}
+
+void
+_pango_core_text_font_set_face (PangoCoreTextFont *ctfont,
+ PangoCoreTextFace *ctface)
+{
+ PangoCoreTextFontPrivate *priv = ctfont->priv;
+
+ priv->face = ctface;
+}
+
+PangoCoreTextFace *
+_pango_core_text_font_get_face (PangoCoreTextFont *font)
+{
+ PangoCoreTextFontPrivate *priv = font->priv;
+
+ return priv->face;
+}
+
+gpointer
+_pango_core_text_font_get_context_key (PangoCoreTextFont *font)
+{
+ PangoCoreTextFontPrivate *priv = font->priv;
+
+ return priv->context_key;
+}
+
+void
+_pango_core_text_font_set_context_key (PangoCoreTextFont *font,
+ gpointer context_key)
+{
+ PangoCoreTextFontPrivate *priv = font->priv;
+
+ priv->context_key = context_key;
+}
+
+void
+_pango_core_text_font_set_ctfont (PangoCoreTextFont *font,
+ CTFontRef font_ref)
+{
+ PangoCoreTextFontPrivate *priv = font->priv;
+
+ priv->font_ref = font_ref;
+}
+
+/**
+ * pango_core_text_font_get_ctfont:
+ * @font: A #PangoCoreTextFont
+ *
+ * Returns the CTFontRef of a font.
+ *
+ * Return value: the CTFontRef associated to @font.
+ *
+ * Since: 1.24
+ */
+CTFontRef
+pango_core_text_font_get_ctfont (PangoCoreTextFont *font)
+{
+ PangoCoreTextFontPrivate *priv = font->priv;
+
+ return priv->font_ref;
+}
diff --git a/pango/pangocoretext.h b/pango/pangocoretext.h
new file mode 100644
index 00000000..22dd9cb0
--- /dev/null
+++ b/pango/pangocoretext.h
@@ -0,0 +1,80 @@
+/* Pango
+ * pangocoretext.h:
+ *
+ * Copyright (C) 2005 Imendio AB
+ * Copyright (C) 2010 Kristian Rietveld <kris@gtk.org>
+ *
+ * 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 __PANGOCORETEXT_H__
+#define __PANGOCORETEXT_H__
+
+#include <pango/pango-context.h>
+#include <pango/pango-font.h>
+#include <Carbon/Carbon.h>
+
+G_BEGIN_DECLS
+
+#define PANGO_TYPE_CORE_TEXT_FONT (pango_core_text_font_get_type ())
+#define PANGO_CORE_TEXT_FONT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CORE_TEXT_FONT, PangoCoreTextFont))
+#define PANGO_IS_CORE_TEXT_FONT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_CORE_TEXT_FONT))
+
+typedef struct _PangoCoreTextFont PangoCoreTextFont;
+typedef struct _PangoCoreTextFontClass PangoCoreTextFontClass;
+
+#if defined(PANGO_ENABLE_ENGINE) || defined(PANGO_ENABLE_BACKEND)
+
+#define PANGO_RENDER_TYPE_CORE_TEXT "PangoRenderCoreText"
+
+#ifdef PANGO_ENABLE_BACKEND
+
+#define PANGO_CORE_TEXT_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_CORE_TEXT_FONT, PangoCoreTextFontClass))
+#define PANGO_IS_CORE_TEXT_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_CORE_TEXT_FONT))
+#define PANGO_CORE_TEXT_FONT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_CORE_TEXT_FONT, PangoCoreTextFontClass))
+
+typedef struct _PangoCoreTextFontPrivate PangoCoreTextFontPrivate;
+
+struct _PangoCoreTextFont
+{
+ PangoFont parent_instance;
+ PangoCoreTextFontPrivate *priv;
+};
+
+struct _PangoCoreTextFontClass
+{
+ PangoFontClass parent_class;
+
+ /*< private >*/
+
+ /* Padding for future expansion */
+ void (*_pango_reserved1) (void);
+ void (*_pango_reserved2) (void);
+ void (*_pango_reserved3) (void);
+ void (*_pango_reserved4) (void);
+};
+
+#endif /* PANGO_ENABLE_BACKEND */
+
+CTFontRef pango_core_text_font_get_ctfont (PangoCoreTextFont *font);
+
+#endif /* PANGO_ENABLE_ENGINE || PANGO_ENABLE_BACKEND */
+
+GType pango_core_text_font_get_type (void) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __PANGOCORETEXT_H__ */