summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristian Rietveld <kris@gtk.org>2010-03-05 21:46:38 +0100
committerKristian Rietveld <kris@gtk.org>2011-03-27 17:26:44 +0200
commit6c0153b9d360313de9ce70e67ec16f961dc11be2 (patch)
tree2c5c80eec83d93c90ef3dcf72a74cf355229869b
parent6b522430ad65fe047b077f9cc3990a97e8869e23 (diff)
downloadpango-6c0153b9d360313de9ce70e67ec16f961dc11be2.tar.gz
Start implementation of CoreText backend
On Mac OS X systems where CoreText is available (that is, 10.5 or higher), we will build the CoreText backend instead of the ATSUI backend. In this case, the ATSUI backend will not be built and installed. This change is necessary because since Mac OS 10.5 ATSUI has been marked as deprecated. For older systems, we will have to continue to use the ATSUI backend.
-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__ */