Initial pass at Pango Cairo/Win32 backend



Here's an initial pass at creating a Cairo backend for Win32. 
The way it works is that PangoCairoWin32Font[Map] derive from
PangoWin32Font[Map] and overrides several virtual functions
I added:

PangoWin32FontMap:

  /* Find a cached font or create a new font for the given face */
  PangoFont *(*find_font) (PangoWin32FontMap          *fontmap,
                           PangoContext               *context,
                           PangoWin32Face             *face,
                           const PangoFontDescription *desc);

PangoWin32Font:

  /* Select the font (and the font's transform) into the DC */
  gboolean (*select_font)      (PangoFont *font,
                                HDC        hdc);

  /* Release resources from select_font */
  void     (*done_font)        (PangoFont *font);
 
  /* Get a scale factor from Windows logical units to Pango units */
  double   (*get_scale_factor) (PangoFont *font);

Seems to work pretty well both with and without Uniscribe. I haven't
done much testing of the old code paths, but modulo stupid mistakes
there should be no change there.

Some outstanding issues with this Patch or with text in the
Cairo Win32 backend (which is in CVS now)

 - [Pango] There is no caching of PangoFont for the Cairo fontmap
   at all. which means that you'll get separate PangoFonts 
   and thus separate cairo_font_t for  every item of a paragraph.
   This shouldn't be hard to fix, though you have to compare 
   size and matrix rather than just size to find the matching font.

 - [Cairo] There is no caching of HFONT or limit of number of 
   HFONT we have open; we just create one or two for every
   cairo_font_t on demand. Probably a scheme where we have a
   fixed limit for the number of open HFONT and unload a random
   existing one on demand makes sense.

 - [Cairo] We don't do any locking on the DC we use for all metrics
   computation. (But there are locking FIXME's all over Cairo.)

 - [Cairo] The win32 backend uses SetWorldTransformation so won't 
   work on older Windows. Fixing this for transformations that are
   only translations and uniform scales isn't hard, since older
   Windows does support rotated text. It does involve putting
   two code paths in a lot of places. You'd also have to investigate
   what the meaning of character positioning from
   GetCharacterPlacement() and from Uniscribe is for rotated text.

   It should be possible to emulate all arbitrary transformations
   using the matrix passed to GetGlyphOutline(), but that's a lot 
   of work

 - [Cairo] Glyph-to-path isn't implemented yet. Should be very
   straightforward using GetGlyphOutline.

I'd like for someone to review this patch before I commit it, but
I'm not going to block on getting this committed to start adding
PangoCairo dependencies to GTK+.

Thanks,
						Owen

Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/pango/ChangeLog,v
retrieving revision 1.1050
diff -u -p -u -r1.1050 ChangeLog
--- ChangeLog	3 Feb 2005 20:23:17 -0000	1.1050
+++ ChangeLog	3 Feb 2005 20:46:03 -0000
@@ -1,5 +1,38 @@
 2005-02-03  Owen Taylor  <otaylor redhat com>
 
+	* pango/pangowin32.h pango/pangowin32-fontmap.h pango/pangowin32.c: 
+	Add virtual pango_win32_font_select_font()
+	to prepare a DC for use with a PangoWin32Font, and to release,
+	pango_win32_font_scale_font() to get logical unit => Pango units scale,
+	pango_win32_font_done_font() to release resources.
+
+	* pango/pangowin32-private.h pango/pangowin32-fontmap.c: Add a 
+	find_font() virtual method to allow a subclass to hook into 
+	looking up and creating a font from a face/context/size.
+
+	* pango/pangowin2.c pango/pangowin32-fontmap.c pango/pangowin32-private.h:
+	Move PangoWin32Font/PangoWin32FontMap defintions into pangowin32-private.h
+	to allow derivation for PangoCairoWin32Font*.
+
+	* pango/pangowin32-fontmap.c: Move initialization into 
+	pango_win32_font_map_init() to facilitate derivation.
+	
+        * pango/Makefile.am pango/pangocairo-win32.h pango/pangocairo-win32font.c:
+	Add a PangoCairo implementation for Win32 fonts deriving from
+	PangoWin32FontMap.
+	
+	* pango/pangowin32.c (font_get_unicode_table)
+	* modules/basic/basic-win32.c (uniscribe_shape): Use
+	pango_win32_font_select_font/done_font().
+
+	* pango/pangowin32.def: Update with functions used publically and
+	in libpangocairo.
+	* modules/basic/basic-win32.c (uniscribe_shape): Use
+	g_utf8_to_utf16 rather than g_convert ... more efficient
+	and simpler.
+
+2005-02-03  Owen Taylor  <otaylor redhat com>
+
 	* examples/cairosimple.c: Open the file with mode "wb", include
 	cairo-png.h. 
 
Index: modules/basic/basic-win32.c
===================================================================
RCS file: /cvs/gnome/pango/modules/basic/basic-win32.c,v
retrieving revision 1.32
diff -u -p -u -r1.32 basic-win32.c
--- modules/basic/basic-win32.c	16 Dec 2004 04:25:10 -0000	1.32
+++ modules/basic/basic-win32.c	3 Feb 2005 20:46:03 -0000
@@ -24,6 +24,7 @@
 
 #define BASIC_WIN32_DEBUGGING
 
+#include <math.h>
 #include <stdlib.h>
 
 #include <glib.h>
@@ -713,6 +714,7 @@ itemize_shape_and_place (PangoFont      
   SCRIPT_CONTROL control;
   SCRIPT_STATE state;
   SCRIPT_ITEM items[100];
+  double scale = pango_win32_font_get_scale_factor (font);
 
   memset (&control, 0, sizeof (control));
   memset (&state, 0, sizeof (state));
@@ -822,9 +824,9 @@ itemize_shape_and_place (PangoFont      
 	  if (iglyphs[glyphix] != 0)
 	    {
 	      glyphs->glyphs[ng+glyphix].glyph = iglyphs[glyphix];
-	      glyphs->glyphs[ng+glyphix].geometry.width = PANGO_SCALE * advances[glyphix];
-	      glyphs->glyphs[ng+glyphix].geometry.x_offset = PANGO_SCALE * offsets[glyphix].du;
-	      glyphs->glyphs[ng+glyphix].geometry.y_offset = PANGO_SCALE * offsets[glyphix].dv;
+	      glyphs->glyphs[ng+glyphix].geometry.width = floor (0.5 + scale * advances[glyphix]);
+	      glyphs->glyphs[ng+glyphix].geometry.x_offset = floor (0.5 + scale * offsets[glyphix].du);
+	      glyphs->glyphs[ng+glyphix].geometry.y_offset = floor (0.5 + scale * offsets[glyphix].dv);
 	    }
 	  else
 	    {
@@ -865,40 +867,19 @@ uniscribe_shape (PangoFont        *font,
 		 PangoGlyphString *glyphs)
 {
   wchar_t *wtext;
-  int wlen, i;
+  long wlen;
+  int i;
   gboolean retval = TRUE;
-  HGDIOBJ old_font = NULL;
-  HFONT hfont = NULL;
-  LOGFONT *lf;
   SCRIPT_CACHE script_cache[100];
 
-  wtext = (wchar_t *) g_convert (text, length, "UTF-16LE", "UTF-8",
-				 NULL, &wlen, NULL);
-  if (wtext == NULL)
+  if (!pango_win32_font_select_font (font, hdc))
     return FALSE;
 
-  wlen /= 2;
-
-  lf = pango_win32_font_logfont (font);
-  hfont = pango_win32_font_cache_load (font_cache, lf);
-  g_free (lf);
-
-  if (hfont == NULL)
+  wtext = g_utf8_to_utf16 (text, length, NULL, &wlen, NULL);
+  if (wtext == NULL)
     retval = FALSE;
 
   if (retval)
-    old_font = SelectObject (hdc, hfont);
-
-  if (old_font == NULL)
-    {
-#ifdef BASIC_WIN32_DEBUGGING
-      if (pango_win32_debug)
-	printf ("pango-basic-win32: SelectObject for font failed\n");
-#endif
-      retval = FALSE;
-    }
-
-  if (retval)
     {
       memset (script_cache, 0, sizeof (script_cache));
       retval = itemize_shape_and_place (font, hdc, wtext, wlen, analysis, glyphs, script_cache);
@@ -924,12 +905,9 @@ uniscribe_shape (PangoFont        *font,
 
     }
 
-  g_free (wtext);
-  if (old_font != NULL)
-    SelectObject (hdc, old_font);
+  pango_win32_font_done_font (font);
 
-  if (hfont != NULL)
-    pango_win32_font_cache_unload (font_cache, hfont);
+  g_free (wtext);
 
   return retval && glyphs->num_glyphs > 0;
 }
Index: pango/Makefile.am
===================================================================
RCS file: /cvs/gnome/pango/pango/Makefile.am,v
retrieving revision 1.113
diff -u -p -u -r1.113 Makefile.am
--- pango/Makefile.am	3 Feb 2005 20:23:18 -0000	1.113
+++ pango/Makefile.am	3 Feb 2005 20:46:03 -0000
@@ -222,7 +222,7 @@ lib_LTLIBRARIES += libpangocairo-1.0.la
 endif
 
 libpangocairo_1_0_la_LDFLAGS = -version-info $(LT_VERSION_INFO) $(no_undefined)
-libpangocairo_1_0_la_LIBADD = libpangoft2-$(PANGO_API_VERSION).la libpango-$(PANGO_API_VERSION).la $(CAIRO_LIBS) $(GLIB_LIBS)
+libpangocairo_1_0_la_LIBADD = libpango-$(PANGO_API_VERSION).la $(CAIRO_LIBS) $(GLIB_LIBS)
 libpangocairo_1_0_la_DEPENDENCIES = libpango-$(PANGO_API_VERSION).la
 
 libpangocairo_1_0_la_SOURCES =  \
@@ -231,8 +231,15 @@ libpangocairo_1_0_la_SOURCES =  \
 	pangocairo-render.c	\
 	pangocairo-private.h
 
+if HAVE_CAIRO_WIN32
+libpangocairo_1_0_la_LIBADD += libpangowin32-$(PANGO_API_VERSION).la 
+libpangocairo_1_0_la_DEPENDENCIES += libpangowin32-$(PANGO_API_VERSION).la 
+
+libpangocairo_1_0_la_SOURCES += pangocairo-win32font.c pangocairo-win32fontmap.c pangocairo-win32.h
+endif
+
 if HAVE_CAIRO_FREETYPE
-libpangocairo_1_0_la_LIBADD += $(FREETYPE_LIBS)
+libpangocairo_1_0_la_LIBADD +=  libpangoft2-$(PANGO_API_VERSION).la $(FREETYPE_LIBS)
 libpangocairo_1_0_la_DEPENDENCIES += libpangoft2-$(PANGO_API_VERSION).la 
 
 libpangocairo_1_0_la_SOURCES += \
Index: pango/pangocairo-fontmap.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pangocairo-fontmap.c,v
retrieving revision 1.1
diff -u -p -u -r1.1 pangocairo-fontmap.c
--- pango/pangocairo-fontmap.c	9 Jan 2005 00:12:39 -0000	1.1
+++ pango/pangocairo-fontmap.c	3 Feb 2005 20:46:03 -0000
@@ -24,8 +24,10 @@
 #include "pangocairo.h"
 #include "pangocairo-private.h"
 
-#ifdef HAVE_CAIRO_FREETYPE
-#include "pangocairo-fc.h"
+#if defined (HAVE_CAIRO_FREETYPE)
+#  include "pangocairo-fc.h"
+#elif defined (HAVE_CAIRO_WIN32)
+#  include "pangocairo-win32.h"
 #endif
 
 GType
@@ -82,8 +84,12 @@ pango_cairo_font_map_new (void)
 {
   /* Make sure that the type system is initialized */
   g_type_init ();
-  
+
+#if defined(HAVE_CAIRO_WIN32)
+  return g_object_new (PANGO_TYPE_CAIRO_WIN32_FONT_MAP, NULL);
+#elif defined(HAVE_CAIRO_FREETYPE)
   return g_object_new (PANGO_TYPE_CAIRO_FC_FONT_MAP, NULL);
+#endif
 }
 
 /**
Index: pango/pangocairo-win32.h
===================================================================
RCS file: pango/pangocairo-win32.h
diff -N pango/pangocairo-win32.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ pango/pangocairo-win32.h	3 Feb 2005 20:46:03 -0000
@@ -0,0 +1,55 @@
+/* Pango
+ * pangocairo-win32.h: Private header file for Cairo/fontconfig combination
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ *
+ * 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_WIN32_H__
+#define __PANGOCAIRO_WIN32_H__
+
+#include "pangowin32.h"
+#include "pangowin32-private.h"
+#include "pangocairo.h"
+
+G_BEGIN_DECLS
+
+#define PANGO_TYPE_CAIRO_WIN32_FONT_MAP       (pango_cairo_win32_font_map_get_type ())
+#define PANGO_CAIRO_WIN32_FONT_MAP(object)    (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_WIN32_FONT_MAP, PangoCairoWin32FontMap))
+#define PANGO_IS_CAIRO_WIN32_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_CAIRO_WIN32_FONT_MAP))
+
+typedef struct _PangoCairoWin32FontMap PangoCairoWin32FontMap;
+
+struct _PangoCairoWin32FontMap
+{
+  PangoWin32FontMap parent_instance;
+
+  double dpi;
+
+  PangoRenderer *renderer;
+};
+
+GType pango_cairo_win32_font_map_get_type (void);
+
+PangoFont *_pango_cairo_win32_font_new (PangoCairoWin32FontMap       *cwfontmap,
+					PangoContext                 *context,
+					PangoWin32Face               *face,
+					const PangoFontDescription   *desc);
+G_END_DECLS
+
+#endif /* __PANGOCAIRO_WIN32_H__ */
+
Index: pango/pangocairo-win32font.c
===================================================================
RCS file: pango/pangocairo-win32font.c
diff -N pango/pangocairo-win32font.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ pango/pangocairo-win32font.c	3 Feb 2005 20:46:03 -0000
@@ -0,0 +1,313 @@
+/* Pango
+ * pangocairowin32-font.c: Cairo font handling, fontconfig backend
+ *
+ * Copyright (C) 2000-2005 Red Hat Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "pango-fontmap.h"
+#include "pangocairo-private.h"
+#include "pangocairo-win32.h"
+
+#include <cairo-win32.h>
+
+#define PANGO_TYPE_CAIRO_WIN32_FONT           (pango_cairo_win32_font_get_type ())
+#define PANGO_CAIRO_WIN32_FONT(object)        (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_WIN32_FONT, PangoCairoWin32Font))
+#define PANGO_CAIRO_WIN32_FONT_CLASS(klass)   (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_CAIRO_WIN32_FONT, PangoCairoWin32FontClass))
+#define PANGO_CAIRO_IS_FONT_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_CAIRO_WIN32_FONT))
+#define PANGO_CAIRO_WIN32_FONT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_CAIRO_WIN32_FONT, PangoCairoWin32FontClass))
+
+typedef struct _PangoCairoWin32Font      PangoCairoWin32Font;
+typedef struct _PangoCairoWin32FontClass PangoCairoWin32FontClass;
+
+struct _PangoCairoWin32Font
+{
+  PangoWin32Font font;
+
+  int size;
+
+  cairo_font_t *cairo_font;
+  cairo_matrix_t *font_matrix;
+  cairo_matrix_t *total_matrix;
+
+  PangoFontMetrics *metrics;
+};
+
+struct _PangoCairoWin32FontClass
+{
+  PangoWin32FontClass  parent_class;
+};
+
+GType pango_cairo_win32_font_get_type (void);
+
+/*******************************
+ *       Utility functions     *
+ *******************************/
+
+static cairo_font_t *
+pango_cairo_win32_font_get_cairo_font (PangoCairoFont *font)
+{
+  PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (font);
+  PangoWin32Font *win32font = PANGO_WIN32_FONT (cwfont);
+
+  if (cwfont->cairo_font == NULL)
+    {
+      LOGFONTW logfontw;
+
+      /* Count here on the fact that all the struct fields are
+       * in the same place for LOGFONTW and LOGFONTA and LOGFONTA
+       * is smaller
+       */
+      memcpy (&logfontw, &win32font->logfont, sizeof (LOGFONTA));
+      
+      if (!MultiByteToWideChar (CP_ACP, MB_ERR_INVALID_CHARS,
+				win32font->logfont.lfFaceName, strlen (win32font->logfont.lfFaceName),
+				logfontw.lfFaceName, sizeof(logfontw.lfFaceName)))
+	logfontw.lfFaceName[0] = 0; /* Hopefully this will select some font */
+	
+      cwfont->cairo_font = cairo_win32_font_create_for_logfontw (&logfontw,
+								 cwfont->total_matrix);
+
+      /* Failure of the above should only occur for out of memory,
+       * we can't proceed at that point
+       */
+      if (!cwfont->cairo_font)
+	g_error ("Unable create Cairo font");
+    }
+  
+  return cwfont->cairo_font;
+}
+
+static void
+cairo_font_iface_init (PangoCairoFontIface *iface)
+{
+  iface->get_cairo_font = pango_cairo_win32_font_get_cairo_font;
+}
+
+G_DEFINE_TYPE_WITH_CODE (PangoCairoWin32Font, pango_cairo_win32_font, PANGO_TYPE_WIN32_FONT,
+    { G_IMPLEMENT_INTERFACE (PANGO_TYPE_CAIRO_FONT, cairo_font_iface_init) });
+
+/********************************
+ *    Method implementations    *
+ ********************************/
+
+static void
+pango_cairo_win32_font_finalize (GObject *object)
+{
+  PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (object);
+
+  if (cwfont->metrics)
+    pango_font_metrics_unref (cwfont->metrics);
+  
+  if (cwfont->cairo_font)
+    cairo_font_destroy (cwfont->cairo_font);
+
+  cairo_matrix_destroy (cwfont->total_matrix);
+  cairo_matrix_destroy (cwfont->font_matrix);
+
+  G_OBJECT_CLASS (pango_cairo_win32_font_parent_class)->finalize (object);
+}
+
+static void
+pango_cairo_win32_font_get_glyph_extents (PangoFont        *font,
+				       PangoGlyph        glyph,
+				       PangoRectangle   *ink_rect,
+				       PangoRectangle   *logical_rect)
+{
+  PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (font);
+  cairo_font_t *cairo_font;
+  cairo_text_extents_t extents;
+  cairo_glyph_t cairo_glyph;
+
+  cairo_font = pango_cairo_win32_font_get_cairo_font (PANGO_CAIRO_FONT (font));
+
+  cairo_glyph.index = glyph;
+  cairo_glyph.x = 0;
+  cairo_glyph.y = 0;
+
+  cairo_font_glyph_extents (cairo_font, cwfont->font_matrix,
+			    &cairo_glyph, 1, &extents);
+
+  if (ink_rect)
+    {
+      ink_rect->x = extents.x_bearing * PANGO_SCALE;
+      ink_rect->y = extents.y_bearing * PANGO_SCALE;
+      ink_rect->width = extents.width * PANGO_SCALE;
+      ink_rect->height = extents.height * PANGO_SCALE;
+    }
+  
+  if (logical_rect)
+    {
+      cairo_font_extents_t font_extents;
+
+      cairo_font_extents (cairo_font, cwfont->font_matrix,
+			  &font_extents);
+      
+      logical_rect->x = 0;
+      logical_rect->y = - font_extents.ascent * PANGO_SCALE;
+      logical_rect->width = extents.x_advance * PANGO_SCALE;
+      logical_rect->height = (font_extents.ascent + font_extents.descent) * PANGO_SCALE;
+    }
+}
+
+static PangoFontMetrics *
+pango_cairo_win32_font_get_metrics (PangoFont        *font,
+				    PangoLanguage    *language)
+{
+  PangoCairoWin32Font *cwfont = PANGO_CAIRO_WIN32_FONT (font);
+
+  if (!cwfont->metrics)
+    {
+      cairo_font_t *cairo_font;
+      cairo_font_extents_t font_extents;
+      cwfont->metrics = pango_font_metrics_new ();
+      double height;
+
+      cairo_font = pango_cairo_win32_font_get_cairo_font (PANGO_CAIRO_FONT (font));
+
+      cairo_font_extents (cairo_font, cwfont->font_matrix,
+			  &font_extents);
+      
+      cwfont->metrics->ascent = font_extents.ascent * PANGO_SCALE;
+      cwfont->metrics->descent = font_extents.ascent * PANGO_SCALE;
+      cwfont->metrics->approximate_char_width = font_extents.max_x_advance * PANGO_SCALE;
+      cwfont->metrics->approximate_digit_width = font_extents.max_y_advance * PANGO_SCALE;
+
+      height = font_extents.ascent + font_extents.descent;
+      
+      cwfont->metrics->underline_thickness = (PANGO_SCALE * height) / 14;
+      cwfont->metrics->underline_position = - cwfont->metrics->underline_thickness;
+      cwfont->metrics->strikethrough_thickness = cwfont->metrics->underline_thickness;
+      cwfont->metrics->strikethrough_position = (PANGO_SCALE * height) / 4;
+    }
+
+  return pango_font_metrics_ref (cwfont->metrics);
+}
+
+static gboolean
+pango_cairo_win32_font_select_font (PangoFont *font,
+				    HDC        hdc)
+{
+  cairo_font_t *cairo_font = pango_cairo_win32_font_get_cairo_font (PANGO_CAIRO_FONT (font));
+  
+  return cairo_win32_font_select_font (cairo_font, hdc) == CAIRO_STATUS_SUCCESS;
+}
+
+static void
+pango_cairo_win32_font_done_font (PangoFont *font)
+{
+  cairo_font_t *cairo_font = pango_cairo_win32_font_get_cairo_font (PANGO_CAIRO_FONT (font));
+  
+  cairo_win32_font_done_font (cairo_font);
+}
+
+static double
+pango_cairo_win32_font_get_scale_factor (PangoFont *font)
+{
+  PangoWin32Font *win32font = PANGO_WIN32_FONT (font);
+  cairo_font_t *cairo_font = pango_cairo_win32_font_get_cairo_font (PANGO_CAIRO_FONT (font));
+
+  return cairo_win32_font_get_scale_factor (cairo_font) * win32font->size;
+}
+
+static void
+pango_cairo_win32_font_class_init (PangoCairoWin32FontClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+  PangoFontClass *font_class = PANGO_FONT_CLASS (class);
+  PangoWin32FontClass *win32_font_class = PANGO_WIN32_FONT_CLASS (class);
+
+  object_class->finalize = pango_cairo_win32_font_finalize;
+  
+  font_class->get_glyph_extents = pango_cairo_win32_font_get_glyph_extents;
+  font_class->get_metrics = pango_cairo_win32_font_get_metrics;
+
+  win32_font_class->select_font = pango_cairo_win32_font_select_font;
+  win32_font_class->done_font = pango_cairo_win32_font_done_font;
+  win32_font_class->get_scale_factor = pango_cairo_win32_font_get_scale_factor;
+}
+
+static void
+pango_cairo_win32_font_init (PangoCairoWin32Font *cwfont)
+{
+}
+
+/********************
+ *    Private API   *
+ ********************/
+
+PangoFont *
+_pango_cairo_win32_font_new (PangoCairoWin32FontMap     *cwfontmap,
+			     PangoContext               *context,
+			     PangoWin32Face             *face,
+			     const PangoFontDescription *desc)
+{
+  PangoCairoWin32Font *cwfont;
+  PangoWin32Font *win32font;
+  const PangoMatrix *pango_ctm;
+  double size;
+
+  cwfont = g_object_new (PANGO_TYPE_CAIRO_WIN32_FONT, NULL);
+  win32font = PANGO_WIN32_FONT (cwfont);
+  
+  win32font->fontmap = PANGO_FONT_MAP (cwfontmap);
+  g_object_ref (cwfontmap);
+
+  win32font->win32face = face;
+
+  size = (double) pango_font_description_get_size (desc) / PANGO_SCALE;
+  
+  if (!pango_font_description_get_size_is_absolute (desc))
+    size *= cwfontmap->dpi / 72.;
+
+  /* FIXME: THis is a pixel size, so not really what we want for describe(),
+   * but it's what we need when computing the scale factor.
+   */
+  win32font->size = size * PANGO_SCALE;
+
+  cwfont->font_matrix = cairo_matrix_create ();
+  cairo_matrix_scale (cwfont->font_matrix, size, size);
+
+  cwfont->total_matrix = cairo_matrix_create ();
+
+  pango_ctm = pango_context_get_matrix (context);
+  if (pango_ctm)
+    {
+      cairo_matrix_t *ctm;
+
+      ctm = cairo_matrix_create ();
+      cairo_matrix_set_affine (ctm,
+			       pango_ctm->xx,
+			       pango_ctm->yx,
+			       pango_ctm->xy,
+			       pango_ctm->yy,
+			       0., 0.);
+      
+      cairo_matrix_multiply (cwfont->total_matrix, cwfont->font_matrix, ctm);
+      cairo_matrix_destroy (ctm);
+    }
+  else
+    cairo_matrix_copy (cwfont->total_matrix, cwfont->font_matrix);
+
+  return PANGO_FONT (cwfont);
+}
Index: pango/pangocairo-win32fontmap.c
===================================================================
RCS file: pango/pangocairo-win32fontmap.c
diff -N pango/pangocairo-win32fontmap.c
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ pango/pangocairo-win32fontmap.c	3 Feb 2005 20:46:03 -0000
@@ -0,0 +1,108 @@
+/* Pango
+ * pangocairo-win32fontmap.c: Cairo font handling, Win32 backend
+ *
+ * Copyright (C) 2000-2005 Red Hat Software
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.	 See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "pangowin32-private.h"
+#include "pangocairo.h"
+#include "pangocairo-private.h"
+#include "pangocairo-win32.h"
+
+typedef struct _PangoCairoWin32FontMapClass PangoCairoWin32FontMapClass;
+
+struct _PangoCairoWin32FontMapClass
+{
+  PangoWin32FontMapClass parent_class;
+};
+
+static void
+pango_cairo_win32_font_map_set_resolution (PangoCairoFontMap *cfontmap,
+					   double             dpi)
+{
+  PangoCairoWin32FontMap *cwfontmap = PANGO_CAIRO_WIN32_FONT_MAP (cfontmap);
+  
+  cwfontmap->dpi = dpi;
+}
+
+static double
+pango_cairo_win32_font_map_get_resolution (PangoCairoFontMap *cfontmap)
+{
+  PangoCairoWin32FontMap *cwfontmap = PANGO_CAIRO_WIN32_FONT_MAP (cfontmap);
+
+  return cwfontmap->dpi;
+}
+
+static PangoRenderer *
+pango_cairo_win32_font_map_get_renderer (PangoCairoFontMap *cfontmap)
+{
+  PangoCairoWin32FontMap *cwfontmap = PANGO_CAIRO_WIN32_FONT_MAP (cfontmap);
+  
+  if (!cwfontmap->renderer)
+    cwfontmap->renderer = g_object_new (PANGO_TYPE_CAIRO_RENDERER, NULL);
+
+  return cwfontmap->renderer;
+}
+
+static void
+cairo_font_map_iface_init (PangoCairoFontMapIface *iface)
+{
+  iface->set_resolution = pango_cairo_win32_font_map_set_resolution;
+  iface->get_resolution = pango_cairo_win32_font_map_get_resolution;
+  iface->get_renderer = pango_cairo_win32_font_map_get_renderer;
+}
+
+G_DEFINE_TYPE_WITH_CODE (PangoCairoWin32FontMap, pango_cairo_win32_font_map, PANGO_TYPE_WIN32_FONT_MAP,
+    { G_IMPLEMENT_INTERFACE (PANGO_TYPE_CAIRO_FONT_MAP, cairo_font_map_iface_init) });
+
+static void
+pango_cairo_win32_font_map_finalize (GObject *object)
+{
+  PangoCairoWin32FontMap *cwfontmap = PANGO_CAIRO_WIN32_FONT_MAP (object);
+  
+  if (cwfontmap->renderer)
+    g_object_unref (cwfontmap->renderer);
+
+  G_OBJECT_CLASS (pango_cairo_win32_font_map_parent_class)->finalize (object);
+}
+
+static PangoFont *
+pango_cairo_win32_font_map_find_font (PangoWin32FontMap          *fontmap,
+				      PangoContext               *context,
+				      PangoWin32Face             *face,
+				      const PangoFontDescription *desc)
+{
+  return _pango_cairo_win32_font_new (PANGO_CAIRO_WIN32_FONT_MAP (fontmap),
+				      context, face, desc);
+}
+
+static void
+pango_cairo_win32_font_map_class_init (PangoCairoWin32FontMapClass *class)
+{
+  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+  PangoWin32FontMapClass *win32fontmap_class = PANGO_WIN32_FONT_MAP_CLASS (class);
+
+  gobject_class->finalize  = pango_cairo_win32_font_map_finalize;
+  win32fontmap_class->find_font = pango_cairo_win32_font_map_find_font;
+}
+
+static void
+pango_cairo_win32_font_map_init (PangoCairoWin32FontMap *cwfontmap)
+{
+  cwfontmap->dpi   = 96.0;
+}
Index: pango/pangowin32-fontmap.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pangowin32-fontmap.c,v
retrieving revision 1.49
diff -u -p -u -r1.49 pangowin32-fontmap.c
--- pango/pangowin32-fontmap.c	16 Dec 2004 03:24:07 -0000	1.49
+++ pango/pangowin32-fontmap.c	3 Feb 2005 20:46:03 -0000
@@ -33,43 +33,12 @@
 #include "pango-utils.h"
 #include "pangowin32-private.h"
 
-#define PANGO_TYPE_WIN32_FONT_MAP           (pango_win32_font_map_get_type ())
-#define PANGO_WIN32_FONT_MAP(object)        (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_WIN32_FONT_MAP, PangoWin32FontMap))
-#define PANGO_WIN32_IS_FONT_MAP(object)     (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_WIN32_FONT_MAP))
-
-typedef struct _PangoWin32FontMap      PangoWin32FontMap;
-typedef struct _PangoWin32FontMapClass PangoWin32FontMapClass;
 typedef struct _PangoWin32Family       PangoWin32Family;
 typedef struct _PangoWin32SizeInfo     PangoWin32SizeInfo;
 
 /* Number of freed fonts */
 #define MAX_FREED_FONTS 16
 
-struct _PangoWin32FontMap
-{
-  PangoFontMap parent_instance;
-
-  PangoWin32FontCache *font_cache;
-  GQueue *freed_fonts;
-
-  /* Map Pango family names to PangoWin32Family structs */
-  GHashTable *families;
-
-  /* Map LOGFONTS (taking into account only the lfFaceName, lfItalic
-   * and lfWeight fields) to PangoWin32SizeInfo structs.
-   */
-  GHashTable *size_infos;
-
-  int n_fonts;
-
-  double resolution;		/* (points / pixel) * PANGO_SCALE */
-};
-
-struct _PangoWin32FontMapClass
-{
-  PangoFontMapClass parent_class;
-};
-
 struct _PangoWin32Family
 {
   PangoFontFamily parent_instance;
@@ -108,6 +77,11 @@ static void       pango_win32_font_map_l
 						       PangoFontFamily            ***families,
 						       int                          *n_families);
   
+static PangoFont *pango_win32_font_map_real_find_font (PangoWin32FontMap          *win32fontmap,
+						       PangoContext               *context,
+						       PangoWin32Face             *face,
+						       const PangoFontDescription *description);
+
 static void       pango_win32_fontmap_cache_clear    (PangoWin32FontMap            *win32fontmap);
 
 static void       pango_win32_insert_font            (PangoWin32FontMap            *fontmap,
@@ -144,42 +118,19 @@ logfont_nosize_equal (gconstpointer v1,
 	  && lfp1->lfWeight == lfp2->lfWeight);
 }
   
-static void 
-pango_win32_font_map_init (PangoWin32FontMap *win32fontmap)
-{
-  win32fontmap->families = g_hash_table_new (g_str_hash, g_str_equal);
-  win32fontmap->size_infos =
-    g_hash_table_new (logfont_nosize_hash, logfont_nosize_equal);
-  win32fontmap->n_fonts = 0;
-}
-
-static void
-pango_win32_font_map_class_init (PangoWin32FontMapClass *class)
-{
-  GObjectClass *object_class = G_OBJECT_CLASS (class);
-  PangoFontMapClass *fontmap_class = PANGO_FONT_MAP_CLASS (class);
-  
-  object_class->finalize = pango_win32_font_map_finalize;
-  fontmap_class->load_font = pango_win32_font_map_load_font;
-  fontmap_class->list_families = pango_win32_font_map_list_families;
-  fontmap_class->shape_engine_type = PANGO_RENDER_TYPE_WIN32;
-  
-  pango_win32_get_dc ();
-}
-
-static PangoWin32FontMap *fontmap = NULL;
-
 static int CALLBACK
 pango_win32_inner_enum_proc (LOGFONT    *lfp,
 			     TEXTMETRIC *metrics,
 			     DWORD       fontType,
 			     LPARAM      lParam)
 {
+  PangoWin32FontMap *win32fontmap = (PangoWin32FontMap *)lParam;
+  
   /* Windows generates synthetic vertical writing versions of East
    * Asian fonts with @ prepended to their name, ignore them.
    */
   if (lfp->lfFaceName[0] != '@')
-    pango_win32_insert_font (fontmap, lfp);
+    pango_win32_insert_font (win32fontmap, lfp);
 
   return 1;
 }
@@ -205,6 +156,45 @@ pango_win32_enum_proc (LOGFONT    *lfp,
   return 1;
 }
 
+static void 
+pango_win32_font_map_init (PangoWin32FontMap *win32fontmap)
+{
+  LOGFONT logfont;
+
+  win32fontmap->families = g_hash_table_new (g_str_hash, g_str_equal);
+  win32fontmap->size_infos =
+    g_hash_table_new (logfont_nosize_hash, logfont_nosize_equal);
+  win32fontmap->n_fonts = 0;
+  
+  win32fontmap->font_cache = pango_win32_font_cache_new ();
+  win32fontmap->freed_fonts = g_queue_new ();
+
+  memset (&logfont, 0, sizeof (logfont));
+  logfont.lfCharSet = DEFAULT_CHARSET;
+  EnumFontFamiliesExA (pango_win32_hdc, &logfont, (FONTENUMPROC) pango_win32_enum_proc, 
+		       (LPARAM)win32fontmap, 0);
+
+  win32fontmap->resolution = (PANGO_SCALE / (double) GetDeviceCaps (pango_win32_hdc, LOGPIXELSY)) * 72.0;
+
+}
+
+static void
+pango_win32_font_map_class_init (PangoWin32FontMapClass *class)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
+  PangoFontMapClass *fontmap_class = PANGO_FONT_MAP_CLASS (class);
+
+  class->find_font = pango_win32_font_map_real_find_font;
+  object_class->finalize = pango_win32_font_map_finalize;
+  fontmap_class->load_font = pango_win32_font_map_load_font;
+  fontmap_class->list_families = pango_win32_font_map_list_families;
+  fontmap_class->shape_engine_type = PANGO_RENDER_TYPE_WIN32;
+  
+  pango_win32_get_dc ();
+}
+
+static PangoWin32FontMap *default_fontmap = NULL;
+
 /**
  * pango_win32_font_map_for_display:
  *
@@ -217,26 +207,15 @@ pango_win32_enum_proc (LOGFONT    *lfp,
 PangoFontMap *
 pango_win32_font_map_for_display (void)
 {
-  LOGFONT logfont;
-
   /* Make sure that the type system is initialized */
   g_type_init ();
   
-  if (fontmap != NULL)
-    return PANGO_FONT_MAP (fontmap);
+  if (default_fontmap != NULL)
+    return PANGO_FONT_MAP (default_fontmap);
 
-  fontmap = g_object_new (PANGO_TYPE_WIN32_FONT_MAP, NULL);
+  default_fontmap = g_object_new (PANGO_TYPE_WIN32_FONT_MAP, NULL);
   
-  fontmap->font_cache = pango_win32_font_cache_new ();
-  fontmap->freed_fonts = g_queue_new ();
-
-  memset (&logfont, 0, sizeof (logfont));
-  logfont.lfCharSet = DEFAULT_CHARSET;
-  EnumFontFamiliesExA (pango_win32_hdc, &logfont, (FONTENUMPROC) pango_win32_enum_proc, 0, 0);
-
-  fontmap->resolution = (PANGO_SCALE / (double) GetDeviceCaps (pango_win32_hdc, LOGPIXELSY)) * 72.0;
-
-  return PANGO_FONT_MAP (fontmap);
+  return PANGO_FONT_MAP (default_fontmap);
 }
 
 /**
@@ -247,12 +226,12 @@ pango_win32_font_map_for_display (void)
 void
 pango_win32_shutdown_display (void)
 {
-  if (fontmap)
+  if (default_fontmap)
     {
-      pango_win32_fontmap_cache_clear (fontmap);
-      g_object_unref (fontmap);
+      pango_win32_fontmap_cache_clear (default_fontmap);
+      g_object_unref (default_fontmap);
 
-      fontmap = NULL;
+      default_fontmap = NULL;
     }
 }
 
@@ -445,49 +424,56 @@ pango_win32_font_map_load_font (PangoFon
 	}
 
       if (best_match)
-	{
-	  GSList *tmp_list = best_match->cached_fonts;
-	  gint size = pango_font_description_get_size (description);
-
-	  if (pango_font_description_get_size_is_absolute (description))
-	    size = (int) 0.5 + (size * win32fontmap->resolution) / PANGO_SCALE;
-
-	  PING(("got best match:%s size=%d",best_match->logfont.lfFaceName,size));
-
-	  while (tmp_list)
-	    {
-	      PangoWin32Font *win32font = tmp_list->data;
-	      if (win32font->size == size)
-		{
-		  PING (("size matches"));
-		  result = (PangoFont *)win32font;
-
-		  g_object_ref (result);
-		  if (win32font->in_cache)
-		    pango_win32_fontmap_cache_remove (fontmap, win32font);
-		  
-		  break;
-		}
-	      tmp_list = tmp_list->next;
-	    }
-
-	  if (!result)
-	    {
-	      PangoWin32Font *win32font = pango_win32_font_new (fontmap, &best_match->logfont, size);
-
-	      win32font->fontmap = fontmap;
-	      win32font->win32face = best_match;
-	      best_match->cached_fonts = g_slist_prepend (best_match->cached_fonts, win32font);
-
-	      result = (PangoFont *)win32font;
-	    }
-	}
+	result = PANGO_WIN32_FONT_MAP_GET_CLASS (win32fontmap)->find_font (win32fontmap, context,
+									   best_match,
+									   description);
       else
 	PING(("no best match!"));
     }
 
   g_free (name);
   return result;
+}
+
+static PangoFont *
+pango_win32_font_map_real_find_font (PangoWin32FontMap          *win32fontmap,
+				     PangoContext               *context,
+				     PangoWin32Face             *face,
+				     const PangoFontDescription *description)
+{
+  PangoFontMap *fontmap = PANGO_FONT_MAP (win32fontmap);
+  PangoWin32Font *win32font;
+  GSList *tmp_list = face->cached_fonts;
+  int size = pango_font_description_get_size (description);
+  
+  if (pango_font_description_get_size_is_absolute (description))
+    size = (int) 0.5 + (size * win32fontmap->resolution) / PANGO_SCALE;
+  
+  PING(("got best match:%s size=%d",face->logfont.lfFaceName,size));
+  
+  while (tmp_list)
+    {
+      win32font = tmp_list->data;
+      if (win32font->size == size)
+	{
+	  PING (("size matches"));
+	  
+	  g_object_ref (win32font);
+	  if (win32font->in_cache)
+	    pango_win32_fontmap_cache_remove (fontmap, win32font);
+	  
+	  return (PangoFont *)win32font;
+	}
+      tmp_list = tmp_list->next;
+    }
+  
+  win32font = pango_win32_font_new (fontmap, &face->logfont, size);
+      
+  win32font->fontmap = fontmap;
+  win32font->win32face = face;
+  face->cached_fonts = g_slist_prepend (face->cached_fonts, win32font);
+  
+  return (PangoFont *)win32font;
 }
 
 static gchar *
Index: pango/pangowin32-private.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pangowin32-private.h,v
retrieving revision 1.16
diff -u -p -u -r1.16 pangowin32-private.h
--- pango/pangowin32-private.h	18 Dec 2004 17:05:14 -0000	1.16
+++ pango/pangowin32-private.h	3 Feb 2005 20:46:03 -0000
@@ -64,9 +64,57 @@ typedef enum
     PANGO_WIN32_N_COVERAGES
   } PangoWin32CoverageLanguageClass;
 
-typedef struct _PangoWin32Font PangoWin32Font;
-typedef struct _PangoWin32Face PangoWin32Face;
-typedef struct _PangoWin32GlyphInfo PangoWin32GlyphInfo;
+#define PANGO_TYPE_WIN32_FONT_MAP             (pango_win32_font_map_get_type ())
+#define PANGO_WIN32_FONT_MAP(object)          (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_WIN32_FONT_MAP, PangoWin32FontMap))
+#define PANGO_WIN32_IS_FONT_MAP(object)       (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_WIN32_FONT_MAP))
+#define PANGO_WIN32_FONT_MAP_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_WIN32_FONT_MAP, PangoWin32FontMapClass))
+#define PANGO_IS_WIN32_FONT_MAP_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_WIN32_FONT_MAP))
+#define PANGO_WIN32_FONT_MAP_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_WIN32_FONT_MAP, PangoWin32FontMapClass))
+
+#define PANGO_TYPE_WIN32_FONT            (pango_win32_font_get_type ())
+#define PANGO_WIN32_FONT(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_WIN32_FONT, PangoWin32Font))
+#define PANGO_WIN32_FONT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_WIN32_FONT, PangoWin32FontClass))
+#define PANGO_WIN32_IS_FONT(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_WIN32_FONT))
+#define PANGO_WIN32_IS_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_WIN32_FONT))
+#define PANGO_WIN32_FONT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_WIN32_FONT, PangoWin32FontClass))
+
+typedef struct _PangoWin32FontMap      PangoWin32FontMap;
+typedef struct _PangoWin32FontMapClass PangoWin32FontMapClass;
+typedef struct _PangoWin32Font         PangoWin32Font;
+typedef struct _PangoWin32FontClass    PangoWin32FontClass;
+typedef struct _PangoWin32Face         PangoWin32Face;
+typedef struct _PangoWin32GlyphInfo    PangoWin32GlyphInfo;
+
+struct _PangoWin32FontMap
+{
+  PangoFontMap parent_instance;
+
+  PangoWin32FontCache *font_cache;
+  GQueue *freed_fonts;
+
+  /* Map Pango family names to PangoWin32Family structs */
+  GHashTable *families;
+
+  /* Map LOGFONTS (taking into account only the lfFaceName, lfItalic
+   * and lfWeight fields) to PangoWin32SizeInfo structs.
+   */
+  GHashTable *size_infos;
+
+  int n_fonts;
+
+  double resolution;		/* (points / pixel) * PANGO_SCALE */
+};
+
+struct _PangoWin32FontMapClass
+{
+  PangoFontMapClass parent_class;
+
+  PangoFont *(*find_font) (PangoWin32FontMap          *fontmap,
+			   PangoContext               *context,
+			   PangoWin32Face             *face,
+			   const PangoFontDescription *desc);
+
+};
 
 struct _PangoWin32Font
 {
@@ -94,6 +142,16 @@ struct _PangoWin32Font
   GHashTable *glyph_info;
 };
 
+struct _PangoWin32FontClass
+{
+  PangoFontClass parent_class;
+
+  gboolean (*select_font)      (PangoFont *font,
+				HDC        hdc);
+  void     (*done_font)        (PangoFont *font);
+  double   (*get_scale_factor) (PangoFont *font);
+};
+
 struct _PangoWin32Face
 {
   PangoFontFace parent_instance;
@@ -114,7 +172,6 @@ struct _PangoWin32GlyphInfo
   PangoRectangle ink_rect;
 };
 
-
 /* TrueType defines: */
 
 #define MAKE_TT_TABLE_NAME(c1, c2, c3, c4) \
@@ -176,6 +233,8 @@ struct name_record
   guint16 string_offset;
 };
 
+GType pango_win32_font_get_type (void);
+
 PangoWin32Font *pango_win32_font_new                (PangoFontMap   *fontmap,
 						     const LOGFONT  *lfp,
 						     int             size);
@@ -191,6 +250,8 @@ void            pango_win32_font_entry_s
 						     PangoLanguage  *lang);
 void            pango_win32_font_entry_remove       (PangoWin32Face *face,
 						     PangoFont      *font);
+
+GType pango_win32_font_map_get_type (void);
 
 void            pango_win32_fontmap_cache_add       (PangoFontMap   *fontmap,
 						     PangoWin32Font *xfont);
Index: pango/pangowin32.c
===================================================================
RCS file: /cvs/gnome/pango/pango/pangowin32.c,v
retrieving revision 1.52
diff -u -p -u -r1.52 pangowin32.c
--- pango/pangowin32.c	18 Dec 2004 17:05:14 -0000	1.52
+++ pango/pangowin32.c	3 Feb 2005 20:46:03 -0000
@@ -32,27 +32,14 @@
 #include "pangowin32-private.h"
 #include "modules.h"
 
-#define PANGO_TYPE_WIN32_FONT            (pango_win32_font_get_type ())
-#define PANGO_WIN32_FONT(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_WIN32_FONT, PangoWin32Font))
-#define PANGO_WIN32_FONT_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_WIN32_FONT, PangoWin32FontClass))
-#define PANGO_WIN32_IS_FONT(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_WIN32_FONT))
-#define PANGO_WIN32_IS_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_WIN32_FONT))
-#define PANGO_WIN32_FONT_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_WIN32_FONT, PangoWin32FontClass))
-
 #define PANGO_WIN32_UNKNOWN_FLAG 0x10000000
 
 HDC pango_win32_hdc;
 OSVERSIONINFO pango_win32_os_version_info;
 gboolean pango_win32_debug = FALSE;
 
-typedef struct _PangoWin32FontClass   PangoWin32FontClass;
 typedef struct _PangoWin32MetricsInfo PangoWin32MetricsInfo;
 
-struct _PangoWin32FontClass
-{
-  PangoFontClass parent_class;
-};
-
 struct _PangoWin32MetricsInfo
 {
   const char *sample_str;
@@ -62,6 +49,11 @@ struct _PangoWin32MetricsInfo
 static void pango_win32_font_dispose    (GObject             *object);
 static void pango_win32_font_finalize   (GObject             *object);
 
+static gboolean pango_win32_font_real_select_font      (PangoFont *font,
+							HDC        hdc);
+static void     pango_win32_font_real_done_font        (PangoFont *font);
+static double   pango_win32_font_real_get_scale_factor (PangoFont *font);
+
 static PangoFontDescription *pango_win32_font_describe          (PangoFont        *font);
 static PangoCoverage        *pango_win32_font_get_coverage      (PangoFont        *font,
 								 PangoLanguage    *lang);
@@ -77,6 +69,12 @@ static void                  pango_win32
 								 PangoRectangle   *logical_rect);
 static PangoFontMetrics *    pango_win32_font_get_metrics       (PangoFont        *font,
 								 PangoLanguage    *lang);
+
+static gboolean pango_win32_font_real_select_font      (PangoFont *font,
+							HDC        hdc);
+static void     pango_win32_font_real_done_font        (PangoFont *font);
+static double   pango_win32_font_real_get_scale_factor (PangoFont *font);
+
 static HFONT                 pango_win32_get_hfont              (PangoFont        *font);
 static void                  pango_win32_get_item_properties    (PangoItem        *item,
 								 PangoUnderline   *uline,
@@ -85,7 +83,7 @@ static void                  pango_win32
 								 PangoAttrColor   *bg_color,
 								 gboolean         *bg_set);
 
-static inline HFONT
+static HFONT
 pango_win32_get_hfont (PangoFont *font)
 {
   PangoWin32Font *win32font = (PangoWin32Font *)font;
@@ -219,6 +217,10 @@ pango_win32_font_class_init (PangoWin32F
   font_class->get_glyph_extents = pango_win32_font_get_glyph_extents;
   font_class->get_metrics = pango_win32_font_get_metrics;
 
+  class->select_font = pango_win32_font_real_select_font;
+  class->done_font = pango_win32_font_real_done_font;
+  class->get_scale_factor = pango_win32_font_real_get_scale_factor;
+
   pango_win32_get_dc ();
 }
 
@@ -624,6 +626,35 @@ pango_win32_font_get_metrics (PangoFont 
   return pango_font_metrics_ref (info->metrics);
 }
 
+static gboolean
+pango_win32_font_real_select_font (PangoFont *font,
+				   HDC        hdc)
+{
+  HFONT hfont = pango_win32_get_hfont (font);
+
+  if (!hfont)
+    return FALSE;
+  
+  if (!SelectObject (hdc, hfont))
+    {
+      g_warning ("pango_win32_font_real_select_font: Cannot select font\n");
+      return FALSE;
+    }
+  
+  return TRUE;
+}
+
+static void
+pango_win32_font_real_done_font (PangoFont *font)
+{
+}
+
+static double
+pango_win32_font_real_get_scale_factor (PangoFont *font)
+{
+  return PANGO_SCALE;
+}
+
 /**
  * pango_win32_font_logfont:
  * @font: a #PangoFont which must be from the Win32 backend
@@ -648,6 +679,64 @@ pango_win32_font_logfont (PangoFont *fon
   return lfp;
 }
 
+/**
+ * pango_win32_font_select_font:
+ * @font: a #PangoFont from the Win32 backend
+ * @scale: location to store a scale factor from Windows
+ *    units to Pango Units.
+ * 
+ * Selects the font into the specified DC and changes the mapping mode
+ * and world transformation of the DC appropriately for the font.
+ * You may want to surround the use of this function with calls
+ * to SaveDC and RestoreDC. Call pango_win32_font_done_font() when
+ * you are done using the DC to release allocated resources.
+ *
+ * See 
+ * 
+ * Return value: %TRUE if the operation succeeded.
+ **/
+gboolean
+pango_win32_font_select_font (PangoFont *font,
+			      HDC        hdc)
+{
+  g_return_val_if_fail (PANGO_WIN32_IS_FONT (font), FALSE);
+  
+  return PANGO_WIN32_FONT_GET_CLASS (font)->select_font (font, hdc);
+}
+
+/**
+ * pango_win32_font_done_font:
+ * @font: a #PangoFont from the win32 backend
+ *
+ * Releases any resources allocated by pango_win32_font_done_font()
+ **/
+void
+pango_win32_font_done_font (PangoFont *font)
+{
+  g_return_if_fail (PANGO_WIN32_IS_FONT (font));
+  
+  PANGO_WIN32_FONT_GET_CLASS (font)->done_font (font);
+}
+
+/**
+ * pango_win32_font_get_scale_factor:
+ * @font: a #PangoFont from the win32 backend
+ * 
+ * Returns the scale factor from logical units in the coordinate
+ * space used by pango_win32_font_select_font() to Pango units
+ * in user space.
+ * 
+ * Return value: factor to multiply logical units by to get Pango
+ *               units.
+ **/
+double
+pango_win32_font_get_scale_factor (PangoFont *font)
+{
+  g_return_val_if_fail (PANGO_WIN32_IS_FONT (font), 1.);
+  
+  return PANGO_WIN32_FONT_GET_CLASS (font)->get_scale_factor (font);
+}
+
 static void
 pango_win32_font_dispose (GObject *object)
 {
@@ -1179,15 +1268,14 @@ static struct type_4_cmap *
 font_get_unicode_table (PangoFont *font)
 {
   PangoWin32Font *win32font = (PangoWin32Font *)font;
-  HFONT hfont;
   struct type_4_cmap *table;
 
   if (win32font->win32face->unicode_table)
     return (struct type_4_cmap *)win32font->win32face->unicode_table;
 
-  hfont = pango_win32_get_hfont (font);
-  SelectObject (pango_win32_hdc, hfont);
+  pango_win32_font_select_font (font, pango_win32_hdc);
   table = get_unicode_mapping (pango_win32_hdc);
+  pango_win32_font_done_font (font);
   
   win32font->win32face->unicode_table = table;
 
Index: pango/pangowin32.def
===================================================================
RCS file: /cvs/gnome/pango/pango/pangowin32.def,v
retrieving revision 1.6
diff -u -p -u -r1.6 pangowin32.def
--- pango/pangowin32.def	21 Nov 2004 20:30:35 -0000	1.6
+++ pango/pangowin32.def	3 Feb 2005 20:46:03 -0000
@@ -6,10 +6,15 @@ EXPORTS
 	pango_win32_font_entry_get_coverage
 	pango_win32_font_entry_remove
 	pango_win32_font_get_glyph_index
+	pango_win32_font_get_type
 	pango_win32_font_map_for_display
 	pango_win32_font_map_get_font_cache
+	pango_win32_font_map_get_type
 	pango_win32_font_new
 	pango_win32_font_logfont
+	pango_win32_font_done_font
+	pango_win32_font_get_scale_factor
+	pango_win32_font_select_font
 	pango_win32_fontmap_cache_add
 	pango_win32_fontmap_cache_remove
 	pango_win32_get_context
Index: pango/pangowin32.h
===================================================================
RCS file: /cvs/gnome/pango/pango/pangowin32.h,v
retrieving revision 1.13
diff -u -p -u -r1.13 pangowin32.h
--- pango/pangowin32.h	21 Nov 2004 20:30:35 -0000	1.13
+++ pango/pangowin32.h	3 Feb 2005 20:46:03 -0000
@@ -78,6 +78,11 @@ HDC            pango_win32_get_dc       
 
 gboolean       pango_win32_get_debug_flag     (void);
 
+gboolean pango_win32_font_select_font      (PangoFont *font,
+					    HDC        hdc);
+void     pango_win32_font_done_font        (PangoFont *font);
+double   pango_win32_font_get_scale_factor (PangoFont *font);
+
 #endif
 
 /* API for libraries that want to use PangoWin32 mixed with classic

Attachment: signature.asc
Description: This is a digitally signed message part



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]