summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog37
-rw-r--r--ChangeLog.pre-1-1037
-rw-r--r--configure.in25
-rw-r--r--docs/Makefile.am8
-rw-r--r--docs/pango-docs.sgml2
-rw-r--r--docs/pango-sections.txt22
-rw-r--r--docs/pango.types3
-rw-r--r--docs/rotated-text.pngbin0 -> 23044 bytes
-rw-r--r--docs/tmpl/pango-renderer.sgml4
-rw-r--r--docs/tmpl/pangocairo.sgml248
-rw-r--r--docs/tmpl/pangofc-fontmap.sgml1
-rw-r--r--docs/tmpl/text-attributes.sgml14
-rw-r--r--docs/tmpl/xft-fonts.sgml2
-rw-r--r--examples/.cvsignore5
-rw-r--r--examples/Makefile.am33
-rw-r--r--examples/cairosimple.c88
-rw-r--r--examples/cairoview.c272
-rw-r--r--examples/pangoft2topgm.c4
-rw-r--r--examples/renderdemo.c61
-rw-r--r--examples/renderdemo.h22
-rw-r--r--examples/xftview.c4
-rw-r--r--pango/Makefile.am27
-rw-r--r--pango/pango-attributes.c35
-rw-r--r--pango/pango-attributes.h3
-rw-r--r--pango/pango-layout.c23
-rw-r--r--pango/pangocairo-fc.h54
-rw-r--r--pango/pangocairo-fcfont.c508
-rw-r--r--pango/pangocairo-fcfontmap.c140
-rw-r--r--pango/pangocairo-font.c69
-rw-r--r--pango/pangocairo-fontmap.c285
-rw-r--r--pango/pangocairo-private.h78
-rw-r--r--pango/pangocairo-render.c354
-rw-r--r--pango/pangocairo.h84
-rw-r--r--pango/pangofc-font.c48
-rw-r--r--pango/pangofc-fontmap.c28
-rw-r--r--pango/pangofc-fontmap.h10
-rw-r--r--pango/pangofc-private.h7
-rw-r--r--pango/pangoft2-private.h8
-rw-r--r--pango/pangoft2.c34
39 files changed, 2558 insertions, 129 deletions
diff --git a/ChangeLog b/ChangeLog
index a2ed4404..581ec75d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,40 @@
+Sat Jan 8 16:46:37 2005 Owen Taylor <otaylor@redhat.com>
+
+ * configure.in: Add checks for Cairo
+
+ * pango/Makefile.am: Add libpangocairo.
+
+ * pango/pangocairo-font.c pango/pangocairo-fontmap.c
+ pango/pangocairo.h pango/pangocairo-private.h
+ pango/pangocairo-fcfont.c pango/pangocairo-fcfontmap.c
+ pango/pangocairo-fc.h: Start of a Cairo/FreeType backend.
+
+ * pango/pangofc-fontmap.[ch]: Add a "get_render_key"
+ virtual function to allow subclasses to specialize the
+ details of how caching works. Add a default implementation
+ that's a little more sophisticated than what was there
+ before.
+
+ * pango/pangoft2-private.h pangofc-font.c pangoft2.c:
+ Move default implementations of has_char(), get_glyph()
+ to the base class.
+
+ * pango/pangofc-private.h pango/pangoft2-private.h:
+ Move PANGO_UNITS_26_6 and friends to pango/pangofc-private.h.
+
+ * examples/renderdemo.[ch] examples/pangoft2topgm.c
+ examples/xftview.c: Allow passing in a custom function
+ to transform drawing.
+
+ * examples/Makefile.am examples/cairoview.c: Add a
+ Cairo/Xlib example program.
+
+ * examples/cairosimple.c: Simple Cairo example with
+ output to a PNG.
+
+ * pango/pango-layout.c (pango_layout_line_get_extents): Fix
+ bug where line ink rect was always including 0, 0.
+
Thu Jan 6 12:29:31 2005 Owen Taylor <otaylor@redhat.com>
* pango/pango-attributes.c (pango_attr_iterator_get_font):
diff --git a/ChangeLog.pre-1-10 b/ChangeLog.pre-1-10
index a2ed4404..581ec75d 100644
--- a/ChangeLog.pre-1-10
+++ b/ChangeLog.pre-1-10
@@ -1,3 +1,40 @@
+Sat Jan 8 16:46:37 2005 Owen Taylor <otaylor@redhat.com>
+
+ * configure.in: Add checks for Cairo
+
+ * pango/Makefile.am: Add libpangocairo.
+
+ * pango/pangocairo-font.c pango/pangocairo-fontmap.c
+ pango/pangocairo.h pango/pangocairo-private.h
+ pango/pangocairo-fcfont.c pango/pangocairo-fcfontmap.c
+ pango/pangocairo-fc.h: Start of a Cairo/FreeType backend.
+
+ * pango/pangofc-fontmap.[ch]: Add a "get_render_key"
+ virtual function to allow subclasses to specialize the
+ details of how caching works. Add a default implementation
+ that's a little more sophisticated than what was there
+ before.
+
+ * pango/pangoft2-private.h pangofc-font.c pangoft2.c:
+ Move default implementations of has_char(), get_glyph()
+ to the base class.
+
+ * pango/pangofc-private.h pango/pangoft2-private.h:
+ Move PANGO_UNITS_26_6 and friends to pango/pangofc-private.h.
+
+ * examples/renderdemo.[ch] examples/pangoft2topgm.c
+ examples/xftview.c: Allow passing in a custom function
+ to transform drawing.
+
+ * examples/Makefile.am examples/cairoview.c: Add a
+ Cairo/Xlib example program.
+
+ * examples/cairosimple.c: Simple Cairo example with
+ output to a PNG.
+
+ * pango/pango-layout.c (pango_layout_line_get_extents): Fix
+ bug where line ink rect was always including 0, 0.
+
Thu Jan 6 12:29:31 2005 Owen Taylor <otaylor@redhat.com>
* pango/pango-attributes.c (pango_attr_iterator_get_font):
diff --git a/configure.in b/configure.in
index 5f283583..1c194d57 100644
--- a/configure.in
+++ b/configure.in
@@ -248,6 +248,30 @@ AM_CONDITIONAL(HAVE_FREETYPE, $have_freetype)
AM_CONDITIONAL(HAVE_XFT, $have_xft)
#
+# Checks for Cairo
+#
+have_cairo=false
+have_cairo_freetype=false
+
+PKG_CHECK_MODULES(CAIRO, cairo >= 0.2.0, have_cairo=true, :)
+
+if $have_cairo ; then
+ pango_save_ldflags=$LDFLAGS
+ LDFLAGS="$LDFLAGS $CAIRO_LIBS"
+ AC_CHECK_LIB(cairo, cairo_ft_font_face, have_cairo_freetype=true, :)
+ LDFLAGS=$pango_save_ldflags
+ if $have_cairo_freetype ; then
+ AC_DEFINE(HAVE_CAIRO_FREETYPE, 1, [Whether Cairo uses FreeType for fonts])
+ else
+ AC_MSG_WARN([Disabling Cairo support, no known font system])
+ have_cairo=false
+ fi
+fi
+
+AM_CONDITIONAL(HAVE_CAIRO, $have_cairo)
+AM_CONDITIONAL(HAVE_CAIRO_FREETYPE, $have_cairo_freetype)
+
+#
# Checks for Win32 GDI
#
have_win32=false
@@ -680,6 +704,7 @@ backends=""
if $have_freetype && $have_fontconfig ; then backends="$backends FreeType"; fi
if $have_x ; then backends="$backends X"; fi
if $have_xft ; then backends="$backends Xft"; fi
+if $have_cairo ; then backends="$backends Cairo"; fi
if $have_win32 ; then backends="$backends Win32"; fi
echo "configuration:
diff --git a/docs/Makefile.am b/docs/Makefile.am
index e04dfaed..6d55e7f3 100644
--- a/docs/Makefile.am
+++ b/docs/Makefile.am
@@ -25,6 +25,8 @@ IGNORE_HFILES= \
module-defs.h \
opentype \
modules.h \
+ pangocairo-private.h \
+ pangocairo-fc.h \
pango-engine-private.h \
pango-impl-utils.h \
pango-glyph-item-private.h \
@@ -55,6 +57,9 @@ INCLUDES = \
GTKDOC_LIBS = \
$(top_builddir)/pango/libpangoxft-1.0.la
+if HAVE_CAIRO
+GTKDOC_LIBS += $(top_builddir)/pango/libpangocairo-1.0.la
+endif
# Extra options to supply to gtkdoc-mkdb
MKDB_OPTIONS=--sgml-mode --output-format=xml
@@ -68,7 +73,8 @@ content_files = \
# Images to copy into HTML directory
HTML_IMAGES = \
- layout.gif
+ layout.gif \
+ rotated-text.png
# Extra options to supply to gtkdoc-fixref
FIXXREF_OPTIONS=
diff --git a/docs/pango-docs.sgml b/docs/pango-docs.sgml
index 21498e6e..aa026ff3 100644
--- a/docs/pango-docs.sgml
+++ b/docs/pango-docs.sgml
@@ -17,6 +17,7 @@
<!ENTITY pango-Win32-Fonts-and-Rendering SYSTEM "xml/win32-fonts.xml">
<!ENTITY pango-FreeType-Fonts-and-Rendering SYSTEM "xml/freetype-fonts.xml">
<!ENTITY pango-Xft-Fonts-and-Rendering SYSTEM "xml/xft-fonts.xml">
+<!ENTITY pangocairo SYSTEM "xml/pangocairo.xml">
<!ENTITY PangoFcFontMap SYSTEM "xml/pangofc-fontmap.xml">
<!ENTITY PangoFcFont SYSTEM "xml/pangofc-font.xml">
<!ENTITY PangoFcDecoder SYSTEM "xml/pangofc-decoder.xml">
@@ -48,6 +49,7 @@
&pango-Win32-Fonts-and-Rendering;
&pango-FreeType-Fonts-and-Rendering;
&pango-Xft-Fonts-and-Rendering;
+ &pangocairo;
&pango-X-Fonts-and-Rendering;
</chapter>
diff --git a/docs/pango-sections.txt b/docs/pango-sections.txt
index 11cfe179..1972e9b7 100644
--- a/docs/pango-sections.txt
+++ b/docs/pango-sections.txt
@@ -769,6 +769,28 @@ pango_xft_renderer_get_type
</SECTION>
<SECTION>
+<TITLE>Cairo Rendering</TITLE>
+<FILE>pangocairo</FILE>
+PangoCairoFontMap
+pango_cairo_font_map_new
+pango_cairo_font_map_get_default
+pango_cairo_font_map_set_resolution
+pango_cairo_font_map_get_resolution
+pango_cairo_font_map_create_context
+pango_cairo_update_context
+pango_cairo_create_layout
+pango_cairo_update_layout
+pango_cairo_show_glyphs
+pango_cairo_show_layout_line
+pango_cairo_show_layout
+<SUBSECTION Standard>
+PANGO_CAIRO_FONT_MAP
+PANGO_IS_CAIRO_FONT_MAP
+PANGO_TYPE_CAIRO_FONT_MAP
+pango_cairo_font_map_get_type
+</SECTION>
+
+<SECTION>
<FILE>pangofc-fontmap</FILE>
<TITLE>PangoFcFontMap</TITLE>
PangoFcFontMap
diff --git a/docs/pango.types b/docs/pango.types
index 5cda42a7..818e81b8 100644
--- a/docs/pango.types
+++ b/docs/pango.types
@@ -1,4 +1,5 @@
#include <pango/pango.h>
+#include <pango/pangocairo.h>
#include <pango/pangofc-font.h>
#include <pango/pangofc-fontmap.h>
#include <pango/pangoft2.h>
@@ -19,5 +20,5 @@ pango_fc_font_map_get_type
pango_fc_decoder_get_type
pango_ft2_font_map_get_type
pango_xft_font_get_type
-
+pango_cairo_font_map_get_type
diff --git a/docs/rotated-text.png b/docs/rotated-text.png
new file mode 100644
index 00000000..b29682e8
--- /dev/null
+++ b/docs/rotated-text.png
Binary files differ
diff --git a/docs/tmpl/pango-renderer.sgml b/docs/tmpl/pango-renderer.sgml
index adb8f555..f88a679b 100644
--- a/docs/tmpl/pango-renderer.sgml
+++ b/docs/tmpl/pango-renderer.sgml
@@ -124,12 +124,14 @@ destinations can be created.
@renderer:
@part:
-@y1:
+@y1_:
@x11:
@x21:
@y2:
@x12:
@x22:
+<!-- # Unused Parameters # -->
+@y1:
<!-- ##### FUNCTION pango_renderer_draw_glyph ##### -->
diff --git a/docs/tmpl/pangocairo.sgml b/docs/tmpl/pangocairo.sgml
new file mode 100644
index 00000000..723a4a09
--- /dev/null
+++ b/docs/tmpl/pangocairo.sgml
@@ -0,0 +1,248 @@
+<!-- ##### SECTION Title ##### -->
+Cairo Rendering
+
+<!-- ##### SECTION Short_Description ##### -->
+Rendering with the Cairo backend
+
+<!-- ##### SECTION Long_Description ##### -->
+<para>
+The <ulink url="http://cairographics.org">Cairo library</ulink> is a
+vector graphics library with a powerful rendering model. It has such
+features as anti-aliased primitives, alpha-compositing, and
+gradients. Multiple backends for Cairo are available, to allow
+rendering to images, to PDF files, and to the screen on X and on other
+windowing systems. The functions in this section allow using Pango
+to render to Cairo surfaces.
+</para>
+<para>
+Using Pango with Cairo is straightforward. A #PangoContext created
+with pango_cairo_font_map_create_context() can be used on any
+Cairo context (cairo_t), but needs to be updated to match the
+current transformation matrix and target surface of the Cairo context
+using pango_cairo_update_context(). The convenience functions
+pango_cairo_create_layout() and pango_cairo_update_layout() handle
+the common case where the program doesn't need to manipulate the
+properties of the #PangoContext.
+</para>
+<para>
+When you get the metrics of a layout or of a piece of a layout using
+functions such as pango_layout_get_extents(), the reported metrics
+are in user-space coordinates. If a piece of text is 10 units long,
+and you call cairo_scale (cr, 2.0), it still is more-or-less 10
+units long. However, the results will be affected by hinting
+(that is, the process of adjusting the text to look good on the
+pixel grid), so you shouldn't assume they are completely independent
+of the current transformation matrix. Note that the basic metrics
+functions in Pango report results in integer Pango units. To get
+to the floating point units used in Cairo divide by %PANGO_SCALE.
+</para>
+<example id="rotated-example">
+<title>Using Pango with Cairo</title>
+<programlisting>
+#include &lt;math.h>
+#include &lt;pango/pangocairo.h>
+
+static void
+draw_text (cairo_t *cr)
+{
+#define RADIUS 150
+#define N_WORDS 10
+#define FONT "Sans Bold 27"
+
+ PangoLayout *layout;
+ PangoFontDescription *desc;
+ int i;
+
+ /* Center coordinates on the middle of the region we are drawing
+ */
+ cairo_translate (cr, RADIUS, RADIUS);
+
+ /* Create a PangoLayout, set the font and text */
+ layout = pango_cairo_create_layout (cr);
+
+ pango_layout_set_text (layout, "Text", -1);
+ desc = pango_font_description_from_string (FONT);
+ pango_layout_set_font_description (layout, desc);
+ pango_font_description_free (desc);
+
+ /* Draw the layout N_WORDS times in a circle */
+ for (i = 0; i &lt; N_WORDS; i++)
+ {
+ int width, height;
+ double angle = (360. * i) / N_WORDS;
+ double red;
+
+ cairo_save (cr);
+
+ /* Gradient from red at angle == 60 to blue at angle == 300 */
+ red = (1 + cos ((angle - 60) * G_PI / 180.)) / 2;
+ cairo_set_rgb_color (cr, red, 0, 1.0 - red);
+
+ cairo_rotate (cr, angle * G_PI / 180.);
+
+ /* Inform Pango to re-layout the text with the new transformation */
+ pango_cairo_update_layout (cr, layout);
+
+ pango_layout_get_size (layout, &amp;width, &amp;height);
+ cairo_move_to (cr, - ((double)width / PANGO_SCALE) / 2, - RADIUS);
+ pango_cairo_show_layout (cr, layout);
+
+ cairo_restore (cr);
+ }
+
+ /* free the layout object */
+ g_object_unref (layout);
+}
+
+int main (int argc, char **argv)
+{
+ cairo_t *cr;
+ FILE *f;
+
+ if (argc != 2)
+ {
+ g_printerr ("Usage: cairo-example OUTPUT_FILENAME\n");
+ return 1;
+ }
+
+ f = fopen (argv[1], "w");
+ if (!f)
+ {
+ g_printerr ("Usage: cannot open '%s'\n", argv[1]);
+ return 1;
+ }
+
+ cr = cairo_create();
+ cairo_set_target_png (cr, f,
+ CAIRO_FORMAT_ARGB32,
+ 2 * RADIUS, 2 * RADIUS);
+
+ cairo_set_rgb_color (cr, 1.0, 1.0, 1.0);
+ cairo_rectangle (cr, 0, 0, 2 * RADIUS, 2 * RADIUS);
+ cairo_fill (cr);
+ draw_text (cr);
+
+ cairo_destroy (cr);
+ fclose (f);
+
+ return 0;
+}
+</programlisting>
+</example>
+<figure>
+ <title>Output of <xref linkend="rotated-example"/></title>
+ <graphic fileref="rotated-text.png" format="PNG"/>
+</figure>
+
+<!-- ##### SECTION See_Also ##### -->
+<para>
+
+</para>
+
+<!-- ##### STRUCT PangoCairoFontMap ##### -->
+<para>
+
+</para>
+
+
+<!-- ##### FUNCTION pango_cairo_font_map_new ##### -->
+<para>
+
+</para>
+
+@Returns:
+
+
+<!-- ##### FUNCTION pango_cairo_font_map_get_default ##### -->
+<para>
+
+</para>
+
+@Returns:
+
+
+<!-- ##### FUNCTION pango_cairo_font_map_set_resolution ##### -->
+<para>
+
+</para>
+
+@fontmap:
+@dpi:
+<!-- # Unused Parameters # -->
+@dpi_x:
+@dpi_y:
+
+
+<!-- ##### FUNCTION pango_cairo_font_map_get_resolution ##### -->
+<para>
+
+</para>
+
+@fontmap:
+@Returns:
+
+
+<!-- ##### FUNCTION pango_cairo_font_map_create_context ##### -->
+<para>
+
+</para>
+
+@fontmap:
+@Returns:
+
+
+<!-- ##### FUNCTION pango_cairo_update_context ##### -->
+<para>
+
+</para>
+
+@cr:
+@context:
+
+
+<!-- ##### FUNCTION pango_cairo_create_layout ##### -->
+<para>
+
+</para>
+
+@cr:
+@Returns:
+
+
+<!-- ##### FUNCTION pango_cairo_update_layout ##### -->
+<para>
+
+</para>
+
+@cr:
+@layout:
+
+
+<!-- ##### FUNCTION pango_cairo_show_glyphs ##### -->
+<para>
+
+</para>
+
+@cr:
+@font:
+@glyphs:
+
+
+<!-- ##### FUNCTION pango_cairo_show_layout_line ##### -->
+<para>
+
+</para>
+
+@cr:
+@line:
+
+
+<!-- ##### FUNCTION pango_cairo_show_layout ##### -->
+<para>
+
+</para>
+
+@cr:
+@layout:
+
+
diff --git a/docs/tmpl/pangofc-fontmap.sgml b/docs/tmpl/pangofc-fontmap.sgml
index db72b732..4f919ca3 100644
--- a/docs/tmpl/pangofc-fontmap.sgml
+++ b/docs/tmpl/pangofc-fontmap.sgml
@@ -44,6 +44,7 @@ Fontconfig-based backend involves deriving from both
@default_substitute:
@new_font:
+@get_render_key:
<!-- ##### FUNCTION pango_fc_font_description_from_pattern ##### -->
<para>
diff --git a/docs/tmpl/text-attributes.sgml b/docs/tmpl/text-attributes.sgml
index ecbf7d9e..7c5fa9da 100644
--- a/docs/tmpl/text-attributes.sgml
+++ b/docs/tmpl/text-attributes.sgml
@@ -47,6 +47,7 @@ attribute is listed in parentheses after the description.
@PANGO_ATTR_LETTER_SPACING:
@PANGO_ATTR_UNDERLINE_COLOR:
@PANGO_ATTR_STRIKETHROUGH_COLOR:
+@PANGO_ATTR_ABSOLUTE_SIZE:
<!-- ##### MACRO PANGO_TYPE_ATTR_TYPE ##### -->
<para>
@@ -151,12 +152,17 @@ impose shape restrictions.
<!-- ##### STRUCT PangoAttrSize ##### -->
<para>
-
+The #PangoAttrShape structure is used to represent attributes which
+set font size.
</para>
-@attr:
-@size:
-@absolute:
+@attr: the common portion of the attribute
+@size: size of font, in units of 1/PANGO_SCALE of a point (for
+ PANGO_ATTR_SIZE) or of a device uni (for PANGO_ATTR_ABSOLUTE_SIZE)
+@absolute: whether the font size is in device units or points.
+ This field is only present for compatibility with Pango-1.8.0
+ (PANGO_ATTR_ABSOLUTE_SIZE was added in 1.8.1); and always will
+ be %FALSE for PANGO_ATTR_SIZE and %TRUE for PANGO_ATTR_ABSOLUTE_SIZE.
<!-- ##### FUNCTION pango_parse_markup ##### -->
<para>
diff --git a/docs/tmpl/xft-fonts.sgml b/docs/tmpl/xft-fonts.sgml
index 50a6e02a..fc4d6cae 100644
--- a/docs/tmpl/xft-fonts.sgml
+++ b/docs/tmpl/xft-fonts.sgml
@@ -10,7 +10,7 @@ The Xft library is a library for displaying fonts on the X window
system; internally it uses the fontconfig library to locate font
files, and the FreeType library to load and render fonts. The
Xft backend is the recommended Pango font backend for screen
-display with X.
+display with X. (The <link linkend="pango-Cairo-Rendering">Cairo back end</link> is another possibility.)
</para>
<para>
Using the Xft backend is generally straightforward;
diff --git a/examples/.cvsignore b/examples/.cvsignore
index 9b779602..d08e01f3 100644
--- a/examples/.cvsignore
+++ b/examples/.cvsignore
@@ -2,10 +2,11 @@ Makefile.in
Makefile
makefile.mingw
pango.modules
-pango-viewer
+cairosimple
+pango-cairoview
+pango-xftview
pangoft2topgm
moc_viewer-qt.cc
-pango-xftview
.deps
.libs
*.lo
diff --git a/examples/Makefile.am b/examples/Makefile.am
index a5a87214..88979360 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -53,6 +53,39 @@ pango_xftview_LDADD = \
$(XFT_LIBS)
###################################################
+###################################################
+if HAVE_CAIRO
+if HAVE_X
+noinst_PROGRAMS += pango-cairoview
+endif
+endif
+
+pango_cairoview_SOURCES = \
+ cairoview.c \
+ renderdemo.c \
+ argcontext.c \
+ argcontext.h
+pango_cairoview_LDADD = \
+ ../pango/libpango-$(PANGO_API_VERSION).la \
+ ../pango/libpangoft2-$(PANGO_API_VERSION).la \
+ ../pango/libpangocairo-$(PANGO_API_VERSION).la \
+ $(CAIRO_LIBS) \
+ $(X_LIBS)
+###################################################
+
+###################################################
+if HAVE_CAIRO
+noinst_PROGRAMS += cairosimple
+endif
+
+cairosimple_SOURCES = \
+ cairosimple.c
+cairosimple_LDADD = \
+ ../pango/libpango-$(PANGO_API_VERSION).la \
+ ../pango/libpangocairo-$(PANGO_API_VERSION).la \
+ $(CAIRO_LIBS)
+###################################################
+
if CROSS_COMPILING
else
all-local: pango.modules
diff --git a/examples/cairosimple.c b/examples/cairosimple.c
new file mode 100644
index 00000000..1ec7edf2
--- /dev/null
+++ b/examples/cairosimple.c
@@ -0,0 +1,88 @@
+#include <math.h>
+#include <pango/pangocairo.h>
+
+static void
+draw_text (cairo_t *cr)
+{
+#define RADIUS 150
+#define N_WORDS 10
+#define FONT "Sans Bold 27"
+
+ PangoLayout *layout;
+ PangoFontDescription *desc;
+ int i;
+
+ /* Center coordinates on the middle of the region we are drawing
+ */
+ cairo_translate (cr, RADIUS, RADIUS);
+
+ /* Create a PangoLayout, set the font and text */
+ layout = pango_cairo_create_layout (cr);
+
+ pango_layout_set_text (layout, "Text", -1);
+ desc = pango_font_description_from_string (FONT);
+ pango_layout_set_font_description (layout, desc);
+ pango_font_description_free (desc);
+
+ /* Draw the layout N_WORDS times in a circle */
+ for (i = 0; i < N_WORDS; i++)
+ {
+ int width, height;
+ double angle = (360. * i) / N_WORDS;
+ double red;
+
+ cairo_save (cr);
+
+ /* Gradient from red at angle == 60 to blue at angle == 300 */
+ red = (1 + cos ((angle - 60) * G_PI / 180.)) / 2;
+ cairo_set_rgb_color (cr, red, 0, 1.0 - red);
+
+ cairo_rotate (cr, angle * G_PI / 180.);
+
+ /* Inform Pango to re-layout the text with the new transformation */
+ pango_cairo_update_layout (cr, layout);
+
+ pango_layout_get_size (layout, &width, &height);
+ cairo_move_to (cr, - ((double)width / PANGO_SCALE) / 2, - RADIUS);
+ pango_cairo_show_layout (cr, layout);
+
+ cairo_restore (cr);
+ }
+
+ /* free the layout object */
+ g_object_unref (layout);
+}
+
+int main (int argc, char **argv)
+{
+ cairo_t *cr;
+ FILE *f;
+
+ if (argc != 2)
+ {
+ g_printerr ("Usage: cairosimple OUTPUT_FILENAME\n");
+ return 1;
+ }
+
+ f = fopen (argv[1], "w");
+ if (!f)
+ {
+ g_printerr ("Usage: cannot open '%s'\n", argv[1]);
+ return 1;
+ }
+
+ cr = cairo_create();
+ cairo_set_target_png (cr, f,
+ CAIRO_FORMAT_ARGB32,
+ 2 * RADIUS, 2 * RADIUS);
+
+ cairo_set_rgb_color (cr, 1.0, 1.0, 1.0);
+ cairo_rectangle (cr, 0, 0, 2 * RADIUS, 2 * RADIUS);
+ cairo_fill (cr);
+ draw_text (cr);
+
+ cairo_destroy (cr);
+ fclose (f);
+
+ return 0;
+}
diff --git a/examples/cairoview.c b/examples/cairoview.c
new file mode 100644
index 00000000..ec285432
--- /dev/null
+++ b/examples/cairoview.c
@@ -0,0 +1,272 @@
+/* Pango
+ * cairoview.c: Example program to view a UTF-8 encoding file
+ * using Cairo to render result
+ *
+ * Copyright (C) 2005 Red Hat, Inc.
+ * Copyright (C) 2001 Sun Microsystems
+ *
+ * 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 <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "renderdemo.h"
+
+#include <pango/pangocairo.h>
+
+static pixman_region16_t *update_region = NULL;
+static PangoContext *context;
+static Display *display;
+int screen;
+static Window window;
+gboolean show_borders;
+
+typedef struct
+{
+ cairo_t *cr;
+ int x_offset;
+ int y_offset;
+} RenderData;
+
+static void
+do_cairo_render (PangoLayout *layout,
+ int x,
+ int y,
+ gpointer data)
+{
+ RenderData *render_data = data;
+ cairo_t *cr = render_data->cr;
+
+ cairo_move_to (cr, x, y);
+ pango_cairo_show_layout (cr, layout);
+
+ if (show_borders)
+ {
+ PangoRectangle ink, logical;
+ double lw = cairo_current_line_width (cr);
+
+ pango_layout_get_extents (layout, &ink, &logical);
+
+ cairo_save (cr);
+ cairo_set_rgb_color (cr, 1.0, 0.0, 0.0);
+ cairo_set_alpha (cr, 0.75);
+
+ cairo_rectangle (cr,
+ (double)logical.x / PANGO_SCALE - lw / 2,
+ (double)logical.y / PANGO_SCALE - lw / 2,
+ (double)logical.width / PANGO_SCALE + lw,
+ (double)logical.height / PANGO_SCALE + lw);
+ cairo_stroke (cr);
+
+ cairo_set_rgb_color (cr, 0.0, 1.0, 0.0);
+
+ cairo_rectangle (cr,
+ (double)ink.x / PANGO_SCALE - lw / 2,
+ (double)ink.y / PANGO_SCALE - lw / 2,
+ (double)ink.width / PANGO_SCALE + lw,
+ (double)ink.height / PANGO_SCALE + lw);
+ cairo_stroke (cr);
+
+ cairo_restore (cr);
+ }
+}
+
+static void
+do_cairo_transform (PangoContext *context,
+ PangoMatrix *matrix,
+ gpointer data)
+{
+ RenderData *render_data = data;
+ cairo_matrix_t *cairo_matrix = cairo_matrix_create ();
+
+ if (matrix)
+ {
+ cairo_matrix_set_affine (cairo_matrix,
+ matrix->xx, matrix->yx,
+ matrix->xy, matrix->yy,
+ matrix->x0 + render_data->x_offset,
+ matrix->y0 + render_data->y_offset);
+ }
+ else
+ {
+ cairo_matrix_set_affine (cairo_matrix,
+ 1.0, 0,
+ 0, 1.0,
+ render_data->x_offset,
+ render_data->y_offset);
+ }
+
+ cairo_set_matrix (render_data->cr, cairo_matrix);
+ cairo_matrix_destroy (cairo_matrix);
+
+ pango_context_set_matrix (context, matrix);
+ pango_cairo_update_context (render_data->cr, context);
+}
+
+void
+update ()
+{
+ RenderData render_data;
+ cairo_t *cr;
+ Pixmap pixmap;
+ GC gc;
+ pixman_box16_t *extents;
+ int n_rects;
+ pixman_box16_t *rects;
+ XRectangle *xrects;
+ int i;
+
+ /* Create a temporary pixmap and a Cairo context pointing to it */
+ extents = pixman_region_extents (update_region);
+ pixmap = XCreatePixmap (display, window,
+ extents->x2 - extents->x1,
+ extents->y2 - extents->y1,
+ DefaultDepth (display, screen));
+
+ cr = render_data.cr = cairo_create();
+ cairo_set_target_drawable (cr, display, pixmap);
+ render_data.x_offset = - extents->x1;
+ render_data.y_offset = - extents->y1;
+
+ do_cairo_transform (context, NULL, &render_data);
+
+ /* Clip to the current update region and fill with white */
+ n_rects = pixman_region_num_rects (update_region);
+ rects = pixman_region_rects (update_region);
+ xrects = g_new (XRectangle, n_rects);
+
+ for (i = 0; i < n_rects; i++)
+ {
+ xrects[i].x = rects[i].x1;
+ xrects[i].y = rects[i].y1;
+ xrects[i].width = rects[i].x2 - rects[i].x1;
+ xrects[i].height = rects[i].y2 - rects[i].y1;
+
+ cairo_rectangle (cr, xrects[i].x, xrects[i].y,
+ xrects[i].width, xrects[i].height);
+ }
+
+ cairo_clip (cr);
+ cairo_set_rgb_color (cr, 1.0, 1.0, 1.0);
+ cairo_fill (cr);
+
+ /* Draw the text in black */
+ cairo_set_rgb_color (cr, 0.0, 0.0, 0.0);
+ do_output (context, do_cairo_render, do_cairo_transform, &render_data, NULL, NULL);
+ cairo_destroy (cr);
+
+ /* Copy the updated area onto the window */
+ gc = XCreateGC (display, pixmap, 0, NULL);
+ XSetClipRectangles (display, gc, 0, 0, xrects, n_rects, YXBanded);
+
+ XCopyArea (display, pixmap, window, gc,
+ 0, 0,
+ extents->x2 - extents->x1, extents->y2 - extents->y1,
+ extents->x1, extents->y1);
+
+ g_free (xrects);
+ XFreeGC (display, gc);
+ XFreePixmap (display, pixmap);
+
+ pixman_region_destroy (update_region);
+ update_region = NULL;
+}
+
+void
+expose (XExposeEvent *xev)
+{
+ if (!update_region)
+ update_region = pixman_region_create ();
+
+ pixman_region_union_rect (update_region, update_region,
+ xev->x, xev->y, xev->width, xev->height);
+}
+
+int main (int argc, char **argv)
+{
+ PangoFontMap *fontmap;
+ XEvent xev;
+ unsigned long bg;
+ int width, height;
+ RenderData render_data;
+ unsigned int quit_keycode;
+ unsigned int borders_keycode;
+
+ g_type_init();
+
+ parse_options (argc, argv);
+
+ display = XOpenDisplay (NULL);
+ if (!display)
+ fail ("Cannot open display %s\n", XDisplayName (NULL));
+ screen = DefaultScreen (display);
+
+ fontmap = pango_cairo_font_map_get_default ();
+ context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fontmap));
+
+ render_data.cr = cairo_create ();
+ render_data.x_offset = 0;
+ render_data.y_offset = 0;
+ do_output (context, NULL, do_cairo_transform, &render_data, &width, &height);
+ cairo_destroy (render_data.cr);
+
+ bg = WhitePixel (display, screen);
+
+ window = XCreateSimpleWindow (display, DefaultRootWindow (display),
+ 0, 0, width, height, 0,
+ bg, bg);
+ XSelectInput (display, window, ExposureMask | KeyPressMask);
+
+ XMapWindow (display, window);
+ XmbSetWMProperties (display, window,
+ get_options_string (),
+ NULL, NULL, 0, NULL, NULL, NULL);
+
+ borders_keycode = XKeysymToKeycode(display, 'B');
+ quit_keycode = XKeysymToKeycode(display, 'Q');
+
+ while (1)
+ {
+ if (!XPending (display) && update_region)
+ update ();
+
+ XNextEvent (display, &xev);
+ switch (xev.xany.type) {
+ case KeyPress:
+ if (xev.xkey.keycode == quit_keycode)
+ goto done;
+ else if (xev.xkey.keycode == borders_keycode)
+ {
+ show_borders = !show_borders;
+ if (!update_region)
+ update_region = pixman_region_create ();
+
+ pixman_region_union_rect (update_region, update_region,
+ 0, 0, width, height);
+ }
+ break;
+ case Expose:
+ expose (&xev.xexpose);
+ break;
+ }
+ }
+
+ done:
+ return 0;
+}
diff --git a/examples/pangoft2topgm.c b/examples/pangoft2topgm.c
index f3a1a15c..c3f90090 100644
--- a/examples/pangoft2topgm.c
+++ b/examples/pangoft2topgm.c
@@ -93,7 +93,7 @@ main(int argc, char *argv[])
int row;
int width, height;
- do_output (context, NULL, NULL, &width, &height);
+ do_output (context, NULL, NULL, NULL, &width, &height);
bitmap.width = width;
bitmap.pitch = (bitmap.width + 3) & ~3;
@@ -103,7 +103,7 @@ main(int argc, char *argv[])
bitmap.pixel_mode = ft_pixel_mode_grays;
memset (buf, 0x00, bitmap.pitch * bitmap.rows);
- do_output (context, ft2_render, &bitmap, &width, &height);
+ do_output (context, ft2_render, NULL, &bitmap, &width, &height);
/* Invert bitmap to get black text on white background */
{
diff --git a/examples/renderdemo.c b/examples/renderdemo.c
index 669ad81b..34d9a057 100644
--- a/examples/renderdemo.c
+++ b/examples/renderdemo.c
@@ -156,13 +156,12 @@ transform_point (PangoMatrix *matrix,
}
static void
-output_body (PangoContext *context,
- const char *text,
- RenderCallback render_cb,
- gpointer render_data,
- PangoMatrix *matrix,
- int *width,
- int *height)
+output_body (PangoContext *context,
+ const char *text,
+ RenderCallback render_cb,
+ gpointer cb_data,
+ int *width,
+ int *height)
{
PangoLayout *layout;
PangoRectangle logical_rect;
@@ -187,8 +186,6 @@ output_body (PangoContext *context,
for (size = start_size; size <= end_size; size += increment)
{
- pango_context_set_matrix (context, matrix);
-
layout = make_layout (context, text, size);
pango_layout_get_extents (layout, NULL, &logical_rect);
@@ -196,7 +193,7 @@ output_body (PangoContext *context,
*height += PANGO_PIXELS (logical_rect.height);
if (render_cb)
- (*render_cb) (layout, 0, dy, render_data);
+ (*render_cb) (layout, 0, dy, cb_data);
dy += PANGO_PIXELS (logical_rect.height);
@@ -204,12 +201,25 @@ output_body (PangoContext *context,
}
}
+static void
+set_transform (PangoContext *context,
+ TransformCallback transform_cb,
+ gpointer cb_data,
+ PangoMatrix *matrix)
+{
+ if (transform_cb)
+ (*transform_cb) (context, matrix, cb_data);
+ else
+ pango_context_set_matrix (context, matrix);
+}
+
void
-do_output (PangoContext *context,
- RenderCallback render_cb,
- gpointer render_data,
- int *width_out,
- int *height_out)
+do_output (PangoContext *context,
+ RenderCallback render_cb,
+ TransformCallback transform_cb,
+ gpointer cb_data,
+ int *width_out,
+ int *height_out)
{
PangoLayout *layout;
PangoRectangle logical_rect;
@@ -228,6 +238,8 @@ do_output (PangoContext *context,
width = 0;
height = 0;
+ set_transform (context, transform_cb, cb_data, NULL);
+
pango_context_set_language (context, pango_language_from_string ("en_US"));
pango_context_set_base_dir (context,
opt_rtl ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR);
@@ -242,7 +254,7 @@ do_output (PangoContext *context,
height += PANGO_PIXELS (logical_rect.height);
if (render_cb)
- (*render_cb) (layout, x, y, render_data);
+ (*render_cb) (layout, x, y, cb_data);
y += PANGO_PIXELS (logical_rect.height);
@@ -250,9 +262,11 @@ do_output (PangoContext *context,
g_free (options_string);
}
- output_body (context, text, NULL, NULL, NULL, &rotated_width, &rotated_height);
-
pango_matrix_rotate (&matrix, opt_rotate);
+
+ set_transform (context, transform_cb, cb_data, &matrix);
+
+ output_body (context, text, NULL, NULL, &rotated_width, &rotated_height);
transform_point (&matrix, 0, 0, &p1x, &p1y);
transform_point (&matrix, rotated_width, 0, &p2x, &p2y);
@@ -268,8 +282,10 @@ do_output (PangoContext *context,
matrix.x0 = x - minx;
matrix.y0 = y - miny;
+ set_transform (context, transform_cb, cb_data, &matrix);
+
if (render_cb)
- output_body (context, text, render_cb, render_data, &matrix, &rotated_width, &rotated_height);
+ output_body (context, text, render_cb, cb_data, &rotated_width, &rotated_height);
width = MAX (width, maxx - minx);
height += maxy - miny;
@@ -421,11 +437,8 @@ parse_options (int argc, char *argv[])
exit (1);
}
- if (!opt_display && !opt_output)
- {
- g_printerr ("%s: --output not specified, assuming --display\n", prog_name);
- opt_display = TRUE;
- }
+ if (!opt_output)
+ opt_display = TRUE;
/* Get the text
*/
diff --git a/examples/renderdemo.h b/examples/renderdemo.h
index cffea109..84fc56b0 100644
--- a/examples/renderdemo.h
+++ b/examples/renderdemo.h
@@ -33,18 +33,22 @@ typedef void (*RenderCallback) (PangoLayout *layout,
int x,
int y,
gpointer data);
+typedef void (*TransformCallback) (PangoContext *context,
+ PangoMatrix *transform,
+ gpointer data);
void fail (const char *format, ...) G_GNUC_PRINTF (1, 2);
-void parse_options (int argc,
- char *argv[]);
-void do_output (PangoContext *context,
- RenderCallback render_cb,
- gpointer render_data,
- int *width,
- int *height);
-void fc_substitute_func (FcPattern *pattern,
- gpointer data);
+void parse_options (int argc,
+ char *argv[]);
+void do_output (PangoContext *context,
+ RenderCallback render_cb,
+ TransformCallback transform_cb,
+ gpointer cb_data,
+ int *width,
+ int *height);
+void fc_substitute_func (FcPattern *pattern,
+ gpointer data);
gchar *get_options_string (void);
extern char *prog_name;
diff --git a/examples/xftview.c b/examples/xftview.c
index 0b95e2f9..c559c8ee 100644
--- a/examples/xftview.c
+++ b/examples/xftview.c
@@ -69,7 +69,7 @@ update ()
XftDrawRect (draw, &color,
area.x, area.y, area.width, area.height);
- do_output (context, xft_render, draw, NULL, NULL);
+ do_output (context, xft_render, NULL, draw, NULL, NULL);
}
void
@@ -111,7 +111,7 @@ int main (int argc, char **argv)
bg = WhitePixel (display, screen);
context = pango_xft_get_context (display, screen);
- do_output (context, NULL, NULL, &width, &height);
+ do_output (context, NULL, NULL, NULL, &width, &height);
window = XCreateSimpleWindow (display, DefaultRootWindow (display),
0, 0, width, height, 0,
diff --git a/pango/Makefile.am b/pango/Makefile.am
index 56af60f0..7142b8d3 100644
--- a/pango/Makefile.am
+++ b/pango/Makefile.am
@@ -213,6 +213,33 @@ libpangoxft_1_0_la_SOURCES = \
pangoxft-render.c
+# ------------------- libpangocairo -------------------
+
+if HAVE_CAIRO
+pangoinclude_HEADERS += pangocairo.h
+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_DEPENDENCIES = libpango-$(PANGO_API_VERSION).la
+
+libpangocairo_1_0_la_SOURCES = \
+ pangocairo-font.c \
+ pangocairo-fontmap.c \
+ pangocairo-render.c \
+ pangocairo-private.h
+
+if HAVE_CAIRO_FREETYPE
+libpangocairo_1_0_la_LIBADD += $(FREETYPE_LIBS)
+libpangocairo_1_0_la_DEPENDENCIES += libpangoft2-$(PANGO_API_VERSION).la
+
+libpangocairo_1_0_la_SOURCES += \
+ pangocairo-fcfont.c \
+ pangocairo-fcfontmap.c \
+ pangocairo-fc.h
+endif
+
# ------------------- libpangowin32 -------------------
if HAVE_WIN32
diff --git a/pango/pango-attributes.c b/pango/pango-attributes.c
index 3191c029..edf0d966 100644
--- a/pango/pango-attributes.c
+++ b/pango/pango-attributes.c
@@ -402,8 +402,11 @@ static PangoAttribute *
pango_attr_size_copy (const PangoAttribute *attr)
{
const PangoAttrSize *size_attr = (PangoAttrSize *)attr;
-
- return pango_attr_size_new_internal (size_attr->size, size_attr->absolute);
+
+ if (attr->klass->type == PANGO_ATTR_ABSOLUTE_SIZE)
+ return pango_attr_size_new_absolute (size_attr->size);
+ else
+ return pango_attr_size_new (size_attr->size);
}
static void
@@ -419,8 +422,7 @@ pango_attr_size_equal (const PangoAttribute *attr1,
const PangoAttrSize *size_attr1 = (const PangoAttrSize *)attr1;
const PangoAttrSize *size_attr2 = (const PangoAttrSize *)attr2;
- return (size_attr1->size == size_attr2->size &&
- size_attr1->absolute == size_attr2->absolute);
+ return size_attr1->size == size_attr2->size;
}
static PangoAttribute *
@@ -428,15 +430,22 @@ pango_attr_size_new_internal (int size,
gboolean absolute)
{
PangoAttrSize *result;
+
static const PangoAttrClass klass = {
PANGO_ATTR_SIZE,
pango_attr_size_copy,
pango_attr_size_destroy,
pango_attr_size_equal
};
+ static const PangoAttrClass absolute_klass = {
+ PANGO_ATTR_ABSOLUTE_SIZE,
+ pango_attr_size_copy,
+ pango_attr_size_destroy,
+ pango_attr_size_equal
+ };
result = g_new (PangoAttrSize, 1);
- result->attr.klass = &klass;
+ result->attr.klass = absolute ? &absolute_klass : &klass;
result->size = size;
result->absolute = absolute;
@@ -458,8 +467,8 @@ pango_attr_size_new (int size)
}
/**
- * pango_attr_size_absolute_new:
- * @size: the font size, in #PANGO_SCALE<!-- -->ths of a device units.
+ * pango_attr_size_new_absolute:
+ * @size: the font size, in #PANGO_SCALE<!-- -->ths of a device unit.
*
* Create a new font-size attribute in device units.
*
@@ -1676,10 +1685,14 @@ pango_attr_iterator_get_font (PangoAttrIterator *iterator,
if (!(mask & PANGO_FONT_MASK_SIZE))
{
mask |= PANGO_FONT_MASK_SIZE;
- if (((PangoAttrSize *)attr)->absolute)
- pango_font_description_set_absolute_size (desc, ((PangoAttrSize *)attr)->size);
- else
- pango_font_description_set_size (desc, ((PangoAttrSize *)attr)->size);
+ pango_font_description_set_size (desc, ((PangoAttrSize *)attr)->size);
+ }
+ break;
+ case PANGO_ATTR_ABSOLUTE_SIZE:
+ if (!(mask & PANGO_FONT_MASK_SIZE))
+ {
+ mask |= PANGO_FONT_MASK_SIZE;
+ pango_font_description_set_absolute_size (desc, ((PangoAttrSize *)attr)->size);
}
break;
case PANGO_ATTR_SCALE:
diff --git a/pango/pango-attributes.h b/pango/pango-attributes.h
index a1877058..f26e178f 100644
--- a/pango/pango-attributes.h
+++ b/pango/pango-attributes.h
@@ -85,7 +85,8 @@ typedef enum
PANGO_ATTR_FALLBACK, /* PangoAttrInt */
PANGO_ATTR_LETTER_SPACING, /* PangoAttrInt */
PANGO_ATTR_UNDERLINE_COLOR, /* PangoAttrColor */
- PANGO_ATTR_STRIKETHROUGH_COLOR /* PangoAttrColor */
+ PANGO_ATTR_STRIKETHROUGH_COLOR, /* PangoAttrColor */
+ PANGO_ATTR_ABSOLUTE_SIZE /* PangoAttrSize */
} PangoAttrType;
typedef enum {
diff --git a/pango/pango-layout.c b/pango/pango-layout.c
index 53106f20..d475a945 100644
--- a/pango/pango-layout.c
+++ b/pango/pango-layout.c
@@ -3917,15 +3917,22 @@ pango_layout_line_get_extents (PangoLayoutLine *line,
if (ink_rect)
{
- new_pos = MIN (ink_rect->x, x_pos + run_ink.x);
- ink_rect->width = MAX (ink_rect->x + ink_rect->width,
- x_pos + run_ink.x + run_ink.width) - new_pos;
- ink_rect->x = new_pos;
+ if (tmp_list == line->runs)
+ {
+ *ink_rect = run_ink;
+ }
+ else
+ {
+ new_pos = MIN (ink_rect->x, x_pos + run_ink.x);
+ ink_rect->width = MAX (ink_rect->x + ink_rect->width,
+ x_pos + run_ink.x + run_ink.width) - new_pos;
+ ink_rect->x = new_pos;
- new_pos = MIN (ink_rect->y, run_ink.y);
- ink_rect->height = MAX (ink_rect->y + ink_rect->height,
- run_ink.y + run_ink.height) - new_pos;
- ink_rect->y = new_pos;
+ new_pos = MIN (ink_rect->y, run_ink.y);
+ ink_rect->height = MAX (ink_rect->y + ink_rect->height,
+ run_ink.y + run_ink.height) - new_pos;
+ ink_rect->y = new_pos;
+ }
}
if (logical_rect)
diff --git a/pango/pangocairo-fc.h b/pango/pangocairo-fc.h
new file mode 100644
index 00000000..22fd1b60
--- /dev/null
+++ b/pango/pangocairo-fc.h
@@ -0,0 +1,54 @@
+/* Pango
+ * pangocairo-fc.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_FC_H__
+#define __PANGOCAIRO_FC_H__
+
+#include "pangofc-fontmap.h"
+#include "pangocairo.h"
+
+G_BEGIN_DECLS
+
+#define PANGO_TYPE_CAIRO_FC_FONT_MAP (pango_cairo_fc_font_map_get_type ())
+#define PANGO_CAIRO_FC_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_FC_FONT_MAP, PangoCairoFcFontMap))
+#define PANGO_IS_CAIRO_FC_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_CAIRO_FC_FONT_MAP))
+
+typedef struct _PangoCairoFcFontMap PangoCairoFcFontMap;
+
+struct _PangoCairoFcFontMap
+{
+ PangoFcFontMap parent_instance;
+
+ double dpi;
+
+ FT_Library library;
+ PangoRenderer *renderer;
+};
+
+GType pango_cairo_fc_font_map_get_type (void);
+
+PangoFcFont *_pango_cairo_fc_font_new (PangoCairoFcFontMap *cffontmap,
+ FcPattern *pattern);
+
+G_END_DECLS
+
+#endif /* __PANGOCAIRO_FC_H__ */
+
diff --git a/pango/pangocairo-fcfont.c b/pango/pangocairo-fcfont.c
new file mode 100644
index 00000000..b8f4a32b
--- /dev/null
+++ b/pango/pangocairo-fcfont.c
@@ -0,0 +1,508 @@
+/* Pango
+ * pangocairofc-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 <stdlib.h>
+
+#include "pango-fontmap.h"
+#include "pangocairo-private.h"
+#include "pangocairo-fc.h"
+#include "pangofc-private.h"
+
+#define PANGO_TYPE_CAIRO_FC_FONT (pango_cairo_fc_font_get_type ())
+#define PANGO_CAIRO_FC_FONT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_FC_FONT, PangoCairoFcFont))
+#define PANGO_CAIRO_FC_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_CAIRO_FC_FONT, PangoCairoFcFontClass))
+#define PANGO_CAIRO_IS_FONT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_CAIRO_FC_FONT))
+#define PANGO_CAIRO_FC_FONT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_CAIRO_FC_FONT, PangoCairoFcFontClass))
+
+#define PANGO_CAIRO_UNKNOWN_FLAG 0x10000000
+
+typedef struct _PangoCairoFcFont PangoCairoFcFont;
+typedef struct _PangoCairoFcFontClass PangoCairoFcFontClass;
+
+struct _PangoCairoFcFont
+{
+ PangoFcFont font;
+
+ FT_Face face;
+ cairo_font_t *cairo_font;
+
+ int load_flags;
+ gboolean have_size;
+
+ GHashTable *glyph_info;
+};
+
+struct _PangoCairoFcFontClass
+{
+ PangoFcFontClass parent_class;
+};
+
+GType pango_cairo_fc_font_get_type (void);
+
+/*******************************
+ * Utility functions *
+ *******************************/
+
+static FT_Face
+load_face (PangoCairoFcFont *cffont)
+{
+ PangoFcFont *fcfont = PANGO_FC_FONT (cffont);
+ FT_Library library = PANGO_CAIRO_FC_FONT_MAP (fcfont->fontmap)->library;
+ FT_Error error;
+ FcPattern *pattern;
+ FcChar8 *filename;
+ FcBool antialias, hinting, autohint;
+ FT_Face face = NULL;
+ int id;
+
+ pattern = fcfont->font_pattern;
+
+ cffont->load_flags = 0;
+
+ /* disable antialiasing if requested */
+ if (FcPatternGetBool (pattern,
+ FC_ANTIALIAS, 0, &antialias) != FcResultMatch)
+ antialias = FcTrue;
+
+ if (antialias)
+ cffont->load_flags |= FT_LOAD_NO_BITMAP;
+ else
+ cffont->load_flags |= FT_LOAD_TARGET_MONO;
+
+ /* disable hinting if requested */
+ if (FcPatternGetBool (pattern,
+ FC_HINTING, 0, &hinting) != FcResultMatch)
+ hinting = FcTrue;
+
+ if (!hinting)
+ cffont->load_flags |= FT_LOAD_NO_HINTING;
+
+ /* force autohinting if requested */
+ if (FcPatternGetBool (pattern,
+ FC_AUTOHINT, 0, &autohint) != FcResultMatch)
+ autohint = FcFalse;
+
+ if (autohint)
+ cffont->load_flags |= FT_LOAD_FORCE_AUTOHINT;
+
+ if (FcPatternGetString (pattern, FC_FILE, 0, &filename) != FcResultMatch)
+ goto bail;
+
+ if (FcPatternGetInteger (pattern, FC_INDEX, 0, &id) != FcResultMatch)
+ goto bail;
+
+ error = FT_New_Face (library, (char *) filename, id, &face);
+
+ bail:
+ return face;
+}
+
+static FT_Face
+load_fallback_face (PangoCairoFcFont *cffont)
+{
+ PangoFcFont *fcfont = PANGO_FC_FONT (cffont);
+ FT_Library library = PANGO_CAIRO_FC_FONT_MAP (fcfont->fontmap)->library;
+ FcPattern *sans;
+ FcPattern *matched;
+ FcResult result;
+ FT_Error error;
+ FcChar8 *filename = NULL;
+ FT_Face face = NULL;
+ int id;
+
+ /* FIXME: pass in a size in case Sans is bitmap */
+ sans = FcPatternBuild (NULL,
+ FC_FAMILY, FcTypeString, "sans",
+ NULL);
+
+ matched = FcFontMatch (NULL, sans, &result);
+
+ if (FcPatternGetString (matched, FC_FILE, 0, &filename) != FcResultMatch)
+ goto bail;
+
+ if (FcPatternGetInteger (matched, FC_INDEX, 0, &id) != FcResultMatch)
+ goto bail;
+
+ face = NULL;
+ error = FT_New_Face (library, (char *) filename, id, &face);
+
+ if (error)
+ {
+ bail:
+ g_warning ("Unable to open font file %s for Sans, exiting", filename);
+ exit (1);
+ }
+
+ FcPatternDestroy (sans);
+ FcPatternDestroy (matched);
+
+ return face;
+}
+
+static cairo_font_t *
+get_cairo_font (PangoCairoFcFont *cffont)
+{
+ PangoFcFont *fcfont = PANGO_FC_FONT (cffont);
+
+ if (cffont->cairo_font == NULL)
+ {
+ FT_Face face = load_face (cffont);
+
+ if (face)
+ cffont->cairo_font = cairo_ft_font_create_for_ft_face (face);
+
+ if (!cffont->cairo_font)
+ {
+ gchar *name = pango_font_description_to_string (fcfont->description);
+ g_warning ("Cannot open font file for font %s, trying Sans", name);
+ g_free (name);
+
+ if (face)
+ FT_Done_Face (face);
+
+ face = load_fallback_face (cffont);
+
+ if (face)
+ cffont->cairo_font = cairo_ft_font_create_for_ft_face (face);
+
+ if (!cffont->cairo_font)
+ {
+ g_warning ("Unable create Cairo font for Sans, exiting");
+ exit (1);
+ }
+ }
+
+ cffont->face = face;
+ }
+
+ return cffont->cairo_font;
+}
+
+static void
+make_current (PangoCairoFcFont *cffont,
+ cairo_t *cr)
+{
+ PangoFcFont *fcfont = PANGO_FC_FONT (cffont);
+ double scale;
+
+ if (pango_font_description_get_size_is_absolute (fcfont->description))
+ scale = pango_font_description_get_size (fcfont->description);
+ else
+ scale = (PANGO_CAIRO_FC_FONT_MAP (fcfont->fontmap)->dpi *
+ pango_font_description_get_size (fcfont->description)) / (PANGO_SCALE * 72.);
+
+ cairo_set_font (cr, get_cairo_font (cffont));
+ cairo_scale_font (cr, scale);
+}
+
+static void
+pango_cairo_fc_font_make_current (PangoCairoFont *font,
+ cairo_t *cr)
+{
+ make_current (PANGO_CAIRO_FC_FONT (font), cr);
+}
+
+static void
+cairo_font_iface_init (PangoCairoFontIface *iface)
+{
+ iface->make_current = pango_cairo_fc_font_make_current;
+}
+
+G_DEFINE_TYPE_WITH_CODE (PangoCairoFcFont, pango_cairo_fc_font, PANGO_TYPE_FC_FONT,
+ { G_IMPLEMENT_INTERFACE (PANGO_TYPE_CAIRO_FONT, cairo_font_iface_init) });
+
+/********************************
+ * Method implementations *
+ ********************************/
+
+static void
+pango_cairo_fc_font_finalize (GObject *object)
+{
+ PangoCairoFcFont *cffont = PANGO_CAIRO_FC_FONT (object);
+
+ if (cffont->cairo_font)
+ {
+ cairo_font_destroy (cffont->cairo_font);
+ cffont->cairo_font = NULL;
+
+ FT_Done_Face (cffont->face);
+ cffont->face = NULL;
+ }
+
+ if (cffont->glyph_info)
+ g_hash_table_destroy (cffont->glyph_info);
+
+ G_OBJECT_CLASS (pango_cairo_fc_font_parent_class)->finalize (object);
+}
+
+static cairo_t *
+get_temporary_context (PangoCairoFcFont *cffont)
+{
+ PangoFcFont *fcfont = PANGO_FC_FONT (cffont);
+ FcMatrix *fc_matrix;
+ cairo_t *cr;
+
+ cr = cairo_create ();
+
+ if (FcPatternGetMatrix (fcfont->font_pattern,
+ FC_MATRIX, 0, &fc_matrix) == FcResultMatch)
+ {
+ cairo_matrix_t *cairo_matrix = cairo_matrix_create ();
+ cairo_matrix_set_affine (cairo_matrix,
+ fc_matrix->xx, fc_matrix->yx,
+ fc_matrix->xy, fc_matrix->yy,
+ 0, 0);
+ cairo_set_matrix (cr, cairo_matrix);
+ cairo_matrix_destroy (cairo_matrix);
+ }
+
+ make_current (cffont, cr);
+
+ return cr;
+}
+
+static void
+get_ascent_descent (PangoCairoFcFont *cffont,
+ int *ascent,
+ int *descent)
+{
+ /* This is complicated in general (see pangofc-font.c:get_face_metrics(),
+ * but simple for hinted, untransformed fonts. cairo_glyph_extents() will
+ * have set up the right size on the font as a side-effect.
+ */
+ *descent = - PANGO_UNITS_26_6 (cffont->face->size->metrics.descender);
+ *ascent = PANGO_UNITS_26_6 (cffont->face->size->metrics.ascender);
+}
+
+static void
+get_glyph_extents_cairo (PangoFcFont *fcfont,
+ PangoGlyph glyph,
+ PangoRectangle *ink_rect,
+ PangoRectangle *logical_rect)
+{
+ PangoCairoFcFont *cffont = PANGO_CAIRO_FC_FONT (fcfont);
+ cairo_text_extents_t extents;
+ cairo_glyph_t cairo_glyph;
+ cairo_t *cr;
+
+ cairo_glyph.index = glyph;
+ cairo_glyph.x = 0;
+ cairo_glyph.y = 0;
+
+ cr = get_temporary_context (cffont);
+ cairo_glyph_extents (cr, &cairo_glyph, 1, &extents);
+ cairo_destroy (cr);
+
+ 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)
+ {
+ int ascent, descent;
+
+ get_ascent_descent (cffont, &ascent, &descent);
+
+ logical_rect->x = 0;
+ logical_rect->y = - ascent;
+ logical_rect->width = extents.x_advance * PANGO_SCALE;
+ logical_rect->height = ascent + descent;
+ }
+}
+
+typedef struct
+{
+ PangoRectangle ink_rect;
+ PangoRectangle logical_rect;
+} Extents;
+
+static void
+get_glyph_extents_raw (PangoCairoFcFont *cffont,
+ PangoGlyph glyph,
+ PangoRectangle *ink_rect,
+ PangoRectangle *logical_rect)
+{
+ Extents *extents;
+
+ if (!cffont->glyph_info)
+ cffont->glyph_info = g_hash_table_new_full (NULL, NULL,
+ NULL, (GDestroyNotify)g_free);
+
+ extents = g_hash_table_lookup (cffont->glyph_info,
+ GUINT_TO_POINTER (glyph));
+
+ if (!extents)
+ {
+ extents = g_new (Extents, 1);
+
+ pango_fc_font_get_raw_extents (PANGO_FC_FONT (cffont),
+ FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING,
+ glyph,
+ &extents->ink_rect,
+ &extents->logical_rect);
+
+ g_hash_table_insert (cffont->glyph_info,
+ GUINT_TO_POINTER (glyph),
+ extents);
+ }
+
+ if (ink_rect)
+ *ink_rect = extents->ink_rect;
+
+ if (logical_rect)
+ *logical_rect = extents->logical_rect;
+}
+
+static void
+pango_cairo_fc_font_get_glyph_extents (PangoFont *font,
+ PangoGlyph glyph,
+ PangoRectangle *ink_rect,
+ PangoRectangle *logical_rect)
+{
+ PangoCairoFcFont *cffont = PANGO_CAIRO_FC_FONT (font);
+ PangoFcFont *fcfont = PANGO_FC_FONT (font);
+
+ if (!fcfont->fontmap) /* Display closed */
+ goto fallback;
+
+ if (glyph == (PangoGlyph)-1)
+ glyph = 0;
+
+ if (glyph)
+ {
+ if (!fcfont->is_transformed && fcfont->is_hinted)
+ get_glyph_extents_cairo (fcfont, glyph, ink_rect, logical_rect);
+ else
+ get_glyph_extents_raw (cffont, glyph, ink_rect, logical_rect);
+ }
+ else
+ {
+ fallback:
+
+ if (ink_rect)
+ {
+ ink_rect->x = 0;
+ ink_rect->width = 0;
+ ink_rect->y = 0;
+ ink_rect->height = 0;
+ }
+ if (logical_rect)
+ {
+ logical_rect->x = 0;
+ logical_rect->width = 0;
+ logical_rect->y = 0;
+ logical_rect->height = 0;
+ }
+ }
+}
+
+static FT_Face
+pango_cairo_fc_font_lock_face (PangoFcFont *font)
+{
+ PangoCairoFcFont *cffont = PANGO_CAIRO_FC_FONT (font);
+
+ /* Horrible hack, we need the font's face to be sized when
+ * locked, but sizing is only done as a side-effect
+ */
+ if (!cffont->have_size)
+ {
+ cairo_t *cr = get_temporary_context (cffont);
+ cairo_font_extents_t extents;
+
+ cairo_current_font_extents (cr, &extents);
+ cairo_destroy (cr);
+
+ cffont->have_size = TRUE;
+ }
+
+ return cairo_ft_font_face (cffont->cairo_font);
+}
+
+static void
+pango_cairo_fc_font_unlock_face (PangoFcFont *font)
+{
+}
+
+static PangoGlyph
+pango_cairo_fc_font_real_get_unknown_glyph (PangoFcFont *font,
+ gunichar wc)
+{
+ return 0;
+}
+
+static void
+pango_cairo_fc_font_shutdown (PangoFcFont *fcfont)
+{
+ PangoCairoFcFont *cffont = PANGO_CAIRO_FC_FONT (fcfont);
+ if (cffont->cairo_font)
+ {
+ cairo_font_destroy (cffont->cairo_font);
+ cffont->cairo_font = NULL;
+
+ FT_Done_Face (cffont->face);
+ cffont->face = NULL;
+ }
+}
+
+static void
+pango_cairo_fc_font_class_init (PangoCairoFcFontClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+ PangoFontClass *font_class = PANGO_FONT_CLASS (class);
+ PangoFcFontClass *fc_font_class = PANGO_FC_FONT_CLASS (class);
+
+ object_class->finalize = pango_cairo_fc_font_finalize;
+
+ font_class->get_glyph_extents = pango_cairo_fc_font_get_glyph_extents;
+
+ fc_font_class->lock_face = pango_cairo_fc_font_lock_face;
+ fc_font_class->unlock_face = pango_cairo_fc_font_unlock_face;
+ fc_font_class->get_unknown_glyph = pango_cairo_fc_font_real_get_unknown_glyph;
+ fc_font_class->shutdown = pango_cairo_fc_font_shutdown;
+}
+
+static void
+pango_cairo_fc_font_init (PangoCairoFcFont *cffont)
+{
+}
+
+/********************
+ * Private API *
+ ********************/
+
+PangoFcFont *
+_pango_cairo_fc_font_new (PangoCairoFcFontMap *cffontmap,
+ FcPattern *pattern)
+{
+ g_return_val_if_fail (PANGO_IS_CAIRO_FC_FONT_MAP (cffontmap), NULL);
+ g_return_val_if_fail (pattern != NULL, NULL);
+
+ return g_object_new (PANGO_TYPE_CAIRO_FC_FONT,
+ "pattern", pattern,
+ NULL);
+}
+
diff --git a/pango/pangocairo-fcfontmap.c b/pango/pangocairo-fcfontmap.c
new file mode 100644
index 00000000..0d05c422
--- /dev/null
+++ b/pango/pangocairo-fcfontmap.c
@@ -0,0 +1,140 @@
+/* Pango
+ * pangocairo-fontmap.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 "pangofc-fontmap.h"
+#include "pangocairo.h"
+#include "pangocairo-private.h"
+#include "pangocairo-fc.h"
+
+typedef struct _PangoCairoFcFontMapClass PangoCairoFcFontMapClass;
+
+struct _PangoCairoFcFontMapClass
+{
+ PangoFcFontMapClass parent_class;
+};
+
+static void
+pango_cairo_fc_font_map_set_resolution (PangoCairoFontMap *cfontmap,
+ double dpi)
+{
+ PangoCairoFcFontMap *cffontmap = PANGO_CAIRO_FC_FONT_MAP (cfontmap);
+
+ cffontmap->dpi = dpi;
+
+ pango_fc_font_map_cache_clear (PANGO_FC_FONT_MAP (cfontmap));
+}
+
+static double
+pango_cairo_fc_font_map_get_resolution (PangoCairoFontMap *cfontmap)
+{
+ PangoCairoFcFontMap *cffontmap = PANGO_CAIRO_FC_FONT_MAP (cfontmap);
+
+ return cffontmap->dpi;
+}
+
+static PangoRenderer *
+pango_cairo_fc_font_map_get_renderer (PangoCairoFontMap *cfontmap)
+{
+ PangoCairoFcFontMap *cffontmap = PANGO_CAIRO_FC_FONT_MAP (cfontmap);
+
+ if (!cffontmap->renderer)
+ cffontmap->renderer = g_object_new (PANGO_TYPE_CAIRO_RENDERER, NULL);
+
+ return cffontmap->renderer;
+}
+
+static void
+cairo_font_map_iface_init (PangoCairoFontMapIface *iface)
+{
+ iface->set_resolution = pango_cairo_fc_font_map_set_resolution;
+ iface->get_resolution = pango_cairo_fc_font_map_get_resolution;
+ iface->get_renderer = pango_cairo_fc_font_map_get_renderer;
+}
+
+G_DEFINE_TYPE_WITH_CODE (PangoCairoFcFontMap, pango_cairo_fc_font_map, PANGO_TYPE_FC_FONT_MAP,
+ { G_IMPLEMENT_INTERFACE (PANGO_TYPE_CAIRO_FONT_MAP, cairo_font_map_iface_init) });
+
+static void
+pango_cairo_fc_font_map_finalize (GObject *object)
+{
+ PangoCairoFcFontMap *cffontmap = PANGO_CAIRO_FC_FONT_MAP (object);
+
+ if (cffontmap->renderer)
+ g_object_unref (cffontmap->renderer);
+
+ FT_Done_FreeType (cffontmap->library);
+
+ G_OBJECT_CLASS (pango_cairo_fc_font_map_parent_class)->finalize (object);
+}
+
+static void
+pango_cairo_fc_font_map_default_substitute (PangoFcFontMap *fcfontmap,
+ FcPattern *pattern)
+{
+ PangoCairoFcFontMap *cffontmap = PANGO_CAIRO_FC_FONT_MAP (fcfontmap);
+ FcValue v;
+
+ FcConfigSubstitute (NULL, pattern, FcMatchPattern);
+
+ if (FcPatternGet (pattern, FC_DPI, 0, &v) == FcResultNoMatch)
+ FcPatternAddDouble (pattern, FC_DPI, cffontmap->dpi);
+ FcDefaultSubstitute (pattern);
+}
+
+static PangoFcFont *
+pango_cairo_fc_font_map_new_font (PangoFcFontMap *fcfontmap,
+ FcPattern *pattern)
+{
+ return _pango_cairo_fc_font_new (PANGO_CAIRO_FC_FONT_MAP (fcfontmap), pattern);
+}
+
+static void
+pango_cairo_fc_font_map_class_init (PangoCairoFcFontMapClass *class)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+ PangoFcFontMapClass *fcfontmap_class = PANGO_FC_FONT_MAP_CLASS (class);
+
+ gobject_class->finalize = pango_cairo_fc_font_map_finalize;
+ fcfontmap_class->default_substitute = pango_cairo_fc_font_map_default_substitute;
+ fcfontmap_class->new_font = pango_cairo_fc_font_map_new_font;
+}
+
+static void
+pango_cairo_fc_font_map_init (PangoCairoFcFontMap *cffontmap)
+{
+ FT_Error error;
+
+ cffontmap->library = NULL;
+ error = FT_Init_FreeType (&cffontmap->library);
+ if (error != FT_Err_Ok)
+ g_error ("pango_cairo_font_map_init: Could not initialize freetype");
+
+ cffontmap->dpi = 96.0;
+}
+
+FT_Library
+_pango_cairo_fc_font_map_get_library (PangoCairoFcFontMap *fontmap)
+{
+ g_return_val_if_fail (PANGO_IS_CAIRO_FC_FONT_MAP (fontmap), NULL);
+
+ return fontmap->library;
+}
+
diff --git a/pango/pangocairo-font.c b/pango/pangocairo-font.c
new file mode 100644
index 00000000..7aae83ec
--- /dev/null
+++ b/pango/pangocairo-font.c
@@ -0,0 +1,69 @@
+/* Pango
+ * pangocairo-font.c: Cairo font handling
+ *
+ * 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 "pangocairo.h"
+#include "pangocairo-private.h"
+
+GType
+pango_cairo_font_get_type (void)
+{
+ static GType cairo_font_type = 0;
+
+ if (! cairo_font_type)
+ {
+ static const GTypeInfo cairo_font_info =
+ {
+ sizeof (PangoCairoFontIface), /* class_size */
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ NULL,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ 0,
+ 0,
+ NULL
+ };
+
+ cairo_font_type =
+ g_type_register_static (G_TYPE_INTERFACE, "PangoCairoFont",
+ &cairo_font_info, 0);
+
+ g_type_interface_add_prerequisite (cairo_font_type, PANGO_TYPE_FONT);
+ }
+
+ return cairo_font_type;
+}
+
+/**
+ * _pango_cairo_font_get_cairo_font:
+ * @font: a #PangoCairoFont
+ * @cr: a #CairoConext
+ *
+ * Install the font and size of @font onto @cr
+ **/
+void
+_pango_cairo_font_make_current (PangoCairoFont *font,
+ cairo_t *cr)
+{
+ g_return_if_fail (PANGO_IS_CAIRO_FONT (font));
+
+ return (* PANGO_CAIRO_FONT_GET_IFACE (font)->make_current) (font, cr);
+}
diff --git a/pango/pangocairo-fontmap.c b/pango/pangocairo-fontmap.c
new file mode 100644
index 00000000..692b7786
--- /dev/null
+++ b/pango/pangocairo-fontmap.c
@@ -0,0 +1,285 @@
+/* Pango
+ * pangocairo-fontmap.c: Cairo font handling
+ *
+ * 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 "pangocairo.h"
+#include "pangocairo-private.h"
+
+#ifdef HAVE_CAIRO_FREETYPE
+#include "pangocairo-fc.h"
+#endif
+
+GType
+pango_cairo_font_map_get_type (void)
+{
+ static GType cairo_font_map_type = 0;
+
+ if (! cairo_font_map_type)
+ {
+ static const GTypeInfo cairo_font_map_info =
+ {
+ sizeof (PangoCairoFontMapIface), /* class_size */
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ NULL,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ 0,
+ 0,
+ NULL
+ };
+
+ cairo_font_map_type =
+ g_type_register_static (G_TYPE_INTERFACE, "PangoCairoFontMap",
+ &cairo_font_map_info, 0);
+
+ g_type_interface_add_prerequisite (cairo_font_map_type, PANGO_TYPE_FONT_MAP);
+ }
+
+ return cairo_font_map_type;
+}
+
+/**
+ * pango_cairo_font_map_new:
+ *
+ * Creates a new #PangoCairoFontMap object; a fontmap is used
+ * to cache information about available fonts, and holds
+ * certain global parameters such as the resolution.
+ * In most cases, you can use pango_cairo_font_map_get_default()
+ * instead.
+ *
+ * Note that the type of the returned object will depend
+ * on the particular font backend Cairo was compiled to use;
+ * You generally should only use the #PangoFontMap and
+ * #PangoCairoFontMap interfaces on the returned object.
+ *
+ * Return value: the newly created fontmap object. Free
+ * with g_object_unref().
+ *
+ * Since: 1.10
+ **/
+PangoFontMap *
+pango_cairo_font_map_new (void)
+{
+ /* Make sure that the type system is initialized */
+ g_type_init ();
+
+ return g_object_new (PANGO_TYPE_CAIRO_FC_FONT_MAP, NULL);
+}
+
+/**
+ * pango_cairo_font_map_get_default:
+ *
+ * Gets a default font map to use with Cairo.
+ *
+ * Return value: the default Cairo fontmap for Pango. This
+ * object is owned by Pango and must not be freed.
+ *
+ * Since: 1.10
+ **/
+PangoFontMap *
+pango_cairo_font_map_get_default (void)
+{
+ static PangoFontMap *default_font_map = NULL;
+
+ if (!default_font_map)
+ default_font_map = pango_cairo_font_map_new ();
+
+ return default_font_map;
+}
+
+/**
+ * pango_cairo_font_map_set_resolution:
+ * @fontmap: a #PangoCairoFontMap
+ * @dpi: the resolution in "dots per inch". (Physical inches aren't actually
+ * involved; the terminology is conventional.)
+ *
+ * Sets the resolution for the fontmap. This is a scale factor between
+ * points specified in a #PangoFontDescription and Cairo units. The
+ * default value is 96, meaning that a 10 point font will be 13
+ * units high. (10 * 96. / 72. = 13.3).
+ *
+ * Since: 1.10
+ **/
+void
+pango_cairo_font_map_set_resolution (PangoCairoFontMap *fontmap,
+ double dpi)
+{
+ g_return_if_fail (PANGO_IS_CAIRO_FONT_MAP (fontmap));
+
+ (* PANGO_CAIRO_FONT_MAP_GET_IFACE (fontmap)->set_resolution) (fontmap, dpi);
+}
+
+/**
+ * pango_cairo_font_map_get_resolution:
+ * @fontmap: a #PangoCairoFontMap
+ *
+ * Gets the resolutions for the fontmap. See pango_cairo_font_map_set_resolution.
+ *
+ * Return value: the resolution in "dots per inch"
+ *
+ * Since: 1.10
+ **/
+double
+pango_cairo_font_map_get_resolution (PangoCairoFontMap *fontmap)
+{
+ g_return_val_if_fail (PANGO_IS_CAIRO_FONT_MAP (fontmap), 96.);
+
+ return (* PANGO_CAIRO_FONT_MAP_GET_IFACE (fontmap)->get_resolution) (fontmap);
+}
+
+/**
+ * pango_cairo_font_map_create_context:
+ * @fontmap: a #PangoCairoFontMap
+ *
+ * Create a #PangoContext for the given fontmap.
+ *
+ * Return value: the newly created context; free with g_object_unref().
+ *
+ * Since: 1.10
+ **/
+PangoContext *
+pango_cairo_font_map_create_context (PangoCairoFontMap *fontmap)
+{
+ PangoContext *context;
+
+ g_return_val_if_fail (PANGO_IS_CAIRO_FONT_MAP (fontmap), NULL);
+
+ context = pango_context_new ();
+ pango_context_set_font_map (context, PANGO_FONT_MAP (fontmap));
+
+ return context;
+}
+
+/**
+ * _pango_cairo_font_map_get_renderer:
+ * @fontmap: a #PangoCairoFontmap
+ *
+ * Gets the singleton PangoCairoRenderer for this fontmap.
+ *
+ * Return value: the singleton renderer
+ **/
+PangoRenderer *
+_pango_cairo_font_map_get_renderer (PangoCairoFontMap *fontmap)
+{
+ g_return_val_if_fail (PANGO_IS_CAIRO_FONT_MAP (fontmap), NULL);
+
+ return (* PANGO_CAIRO_FONT_MAP_GET_IFACE (fontmap)->get_renderer) (fontmap);
+}
+
+/**
+ * pango_cairo_update_context:
+ * @cr: a Cairo context
+ * @context: a #PangoContext, from pango_cairo_font_map_create_context()
+ *
+ * Updates a #PangoContext previously created for use with Cairo to
+ * match the current transformation and target surface of a Cairo
+ * context. If any layouts have been created for the context,
+ * it's necessary to call pango_layout_context_changed() on those
+ * layouts.
+ *
+ * Since: 1.10
+ **/
+void
+pango_cairo_update_context (cairo_t *cr,
+ PangoContext *context)
+{
+ cairo_matrix_t *cairo_matrix;
+ PangoMatrix pango_matrix;
+
+ g_return_if_fail (cr != NULL);
+ g_return_if_fail (PANGO_IS_CONTEXT (context));
+
+ cairo_matrix = cairo_matrix_create ();
+ cairo_current_matrix (cr, cairo_matrix);
+ cairo_matrix_get_affine (cairo_matrix,
+ &pango_matrix.xx, &pango_matrix.yx,
+ &pango_matrix.xy, &pango_matrix.yy,
+ &pango_matrix.x0, &pango_matrix.y0);
+
+ pango_context_set_matrix (context, &pango_matrix);
+
+ cairo_matrix_destroy (cairo_matrix);
+}
+
+/**
+ * pango_cairo_create_layout:
+ * @cr: a Cairo context
+ *
+ * Creates a layout object set up to match the current transformation
+ * and target surface of the Cairo context. This layout can then be
+ * used for text measurement with functions like
+ * pango_layout_get_size() or drawing with functions like
+ * pango_cairo_show_layout(). If you change the transformation
+ * or target surface for @cr, you need to call pango_cairo_update_layout()
+ *
+ * This function is the most convenient way to use Cairo with Pango,
+ * however it is slightly inefficient since it creates a separate
+ * #PangoContext object for each layout. This might matter in an
+ * application that was laying out large amounts of text.
+ *
+ * Return value: the newly created #PangoLayout. Free with
+ * g_object_unref().
+ *
+ * Since: 1.10
+ **/
+PangoLayout *
+pango_cairo_create_layout (cairo_t *cr)
+{
+ PangoFontMap *fontmap;
+ PangoContext *context;
+ PangoLayout *layout;
+
+ g_return_val_if_fail (cr != NULL, NULL);
+
+ fontmap = pango_cairo_font_map_get_default ();
+ context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fontmap));
+ layout = pango_layout_new (context);
+
+ pango_cairo_update_context (cr, context);
+ g_object_unref (context);
+
+ return layout;
+}
+
+/**
+ * pango_cairo_update_layout:
+ * @cr: a Cairo context
+ * @layout: a #PangoLayout, from pango_cairo_create_layout()
+ *
+ * Updates the private #PangoContext of a #PangoLayout created with
+ * pango_cairo_create_layout() to match the current transformation
+ * and target surface of a Cairo context.
+ *
+ * Since: 1.10
+ **/
+void
+pango_cairo_update_layout (cairo_t *cr,
+ PangoLayout *layout)
+{
+ g_return_if_fail (cr != NULL);
+ g_return_if_fail (PANGO_IS_LAYOUT (layout));
+
+ pango_cairo_update_context (cr, pango_layout_get_context (layout));
+ pango_layout_context_changed (layout);
+}
+
diff --git a/pango/pangocairo-private.h b/pango/pangocairo-private.h
new file mode 100644
index 00000000..64e9a4d9
--- /dev/null
+++ b/pango/pangocairo-private.h
@@ -0,0 +1,78 @@
+/* Pango
+ * pangocairo-private.h: private symbols for the Cairo backend
+ *
+ * Copyright (C) 2000,2004 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_PRIVATE_H__
+#define __PANGOCAIRO_PRIVATE_H__
+
+#include <pango/pangocairo.h>
+#include <pango/pango-renderer.h>
+
+G_BEGIN_DECLS
+
+#define PANGO_CAIRO_FONT_MAP_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), PANGO_TYPE_CAIRO_FONT_MAP, PangoCairoFontMapIface))
+
+typedef struct _PangoCairoFontMapIface PangoCairoFontMapIface;
+
+struct _PangoCairoFontMapIface
+{
+ GTypeInterface g_iface;
+
+ void (*set_resolution) (PangoCairoFontMap *fontmap,
+ double dpi);
+ double (*get_resolution) (PangoCairoFontMap *fontmap);
+ PangoRenderer *(*get_renderer) (PangoCairoFontMap *fontmap);
+};
+
+PangoRenderer *_pango_cairo_font_map_get_renderer (PangoCairoFontMap *cfontmap);
+
+#define PANGO_CAIRO_FONT_GET_IFACE(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), PANGO_TYPE_CAIRO_FONT, PangoCairoFontIface))
+
+#define PANGO_TYPE_CAIRO_FONT (pango_cairo_font_get_type ())
+#define PANGO_CAIRO_FONT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_FONT, PangoCairoFont))
+#define PANGO_IS_CAIRO_FONT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_CAIRO_FONT))
+
+typedef struct _PangoCairoFont PangoCairoFont;
+typedef struct _PangoCairoFontIface PangoCairoFontIface;
+
+struct _PangoCairoFontIface
+{
+ GTypeInterface g_iface;
+
+ void (*make_current) (PangoCairoFont *font,
+ cairo_t *cr);
+};
+
+GType pango_cairo_font_get_type (void);
+
+void _pango_cairo_font_make_current (PangoCairoFont *font,
+ cairo_t *cr);
+
+#define PANGO_TYPE_CAIRO_RENDERER (pango_cairo_renderer_get_type())
+#define PANGO_CAIRO_RENDERER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_RENDERER, PangoCairoRenderer))
+#define PANGO_IS_CAIRO_RENDERER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_CAIRO_RENDERER))
+
+typedef struct _PangoCairoRenderer PangoCairoRenderer;
+
+GType pango_cairo_renderer_get_type (void);
+
+G_END_DECLS
+
+#endif /* __PANGOCAIRO_PRIVATE_H__ */
diff --git a/pango/pangocairo-render.c b/pango/pangocairo-render.c
new file mode 100644
index 00000000..305a5e08
--- /dev/null
+++ b/pango/pangocairo-render.c
@@ -0,0 +1,354 @@
+/* Pango
+ * pangocairo-render.c: Rendering routines to Cairo surfaces
+ *
+ * Copyright (C) 2004 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.
+ */
+
+#include "pangocairo-private.h"
+
+typedef struct _PangoCairoRendererClass PangoCairoRendererClass;
+
+#define PANGO_CAIRO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PANGO_TYPE_CAIRO_RENDERER, PangoCairoRendererClass))
+#define PANGO_IS_CAIRO_RENDERER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PANGO_TYPE_CAIRO_RENDERER))
+#define PANGO_CAIRO_RENDERER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PANGO_TYPE_CAIRO_RENDERER, PangoCairoRendererClass))
+
+struct _PangoCairoRenderer
+{
+ PangoRenderer parent_instance;
+
+ cairo_t *cr;
+};
+
+struct _PangoCairoRendererClass
+{
+ PangoRendererClass parent_class;
+};
+
+G_DEFINE_TYPE (PangoCairoRenderer, pango_cairo_renderer, PANGO_TYPE_RENDERER)
+
+static void
+set_color (PangoCairoRenderer *crenderer,
+ PangoRenderPart part)
+{
+ PangoColor *color = pango_renderer_get_color (PANGO_RENDERER (crenderer), part);
+
+ if (color)
+ cairo_set_rgb_color (crenderer->cr,
+ color->red / 65535.,
+ color->green / 65535.,
+ color->blue / 65535.);
+}
+
+static void
+pango_cairo_renderer_draw_glyphs (PangoRenderer *renderer,
+ PangoFont *font,
+ PangoGlyphString *glyphs,
+ int x,
+ int y)
+{
+ PangoCairoRenderer *crenderer = PANGO_CAIRO_RENDERER (renderer);
+
+ /* cairo_glyph_t is 24 bytes */
+#define MAX_STACK 40
+
+ int i;
+ int x_position = 0;
+ cairo_glyph_t *cairo_glyphs;
+ cairo_glyph_t stack_glyphs[MAX_STACK];
+
+ cairo_save (crenderer->cr);
+
+ set_color (crenderer, PANGO_RENDER_PART_FOREGROUND);
+
+ if (glyphs->num_glyphs > MAX_STACK)
+ cairo_glyphs = g_new (cairo_glyph_t, glyphs->num_glyphs);
+ else
+ cairo_glyphs = stack_glyphs;
+
+ for (i = 0; i < glyphs->num_glyphs; i++)
+ {
+ PangoGlyphInfo *gi = &glyphs->glyphs[i];
+
+ cairo_glyphs[i].index = gi->glyph;
+ cairo_glyphs[i].x = (double)(x + x_position + gi->geometry.x_offset) / PANGO_SCALE;
+ cairo_glyphs[i].y = (double)(y + gi->geometry.y_offset) / PANGO_SCALE;
+
+ x_position += gi->geometry.width;
+ }
+
+ _pango_cairo_font_make_current (PANGO_CAIRO_FONT (font), crenderer->cr);
+ cairo_show_glyphs (crenderer->cr, cairo_glyphs, glyphs->num_glyphs);
+
+ if (glyphs->num_glyphs > MAX_STACK)
+ g_free (cairo_glyphs);
+
+ cairo_restore (crenderer->cr);
+
+#undef MAX_STACK
+}
+
+static void
+pango_cairo_renderer_draw_rectangle (PangoRenderer *renderer,
+ PangoRenderPart part,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ PangoCairoRenderer *crenderer = PANGO_CAIRO_RENDERER (renderer);
+
+ cairo_save (crenderer->cr);
+
+ set_color (crenderer, part);
+
+ cairo_rectangle (crenderer->cr,
+ (double)x / PANGO_SCALE, (double)y / PANGO_SCALE,
+ (double)width / PANGO_SCALE, (double)height / PANGO_SCALE);
+ cairo_fill (crenderer->cr);
+
+ cairo_restore (crenderer->cr);
+}
+
+/* Draws an error underline that looks like one of:
+ * H E H
+ * /\ /\ /\ /\ /\ -
+ * A/ \ / \ / \ A/ \ / \ |
+ * \ \ / \ / /D \ \ / \ |
+ * \ \/ C \/ / \ \/ C \ | height = HEIGHT_SQUARES * square
+ * \ /\ F / \ F /\ \ |
+ * \ / \ / \ / \ \G |
+ * \ / \ / \ / \ / |
+ * \/ \/ \/ \/ -
+ * B B
+ * |----|
+ * unit_width = (HEIGHT_SQUARES - 1) * square
+ *
+ * The x, y, width, height passed in give the desired bounding box;
+ * x/width are adjusted to make the underline a integer number of units
+ * wide.
+ */
+#define HEIGHT_SQUARES 2.5
+
+static void
+pango_cairo_renderer_draw_error_underline (PangoRenderer *renderer,
+ int x,
+ int y,
+ int width,
+ int height)
+{
+ PangoCairoRenderer *crenderer = PANGO_CAIRO_RENDERER (renderer);
+ cairo_t *cr = crenderer->cr;
+
+ double square = height / HEIGHT_SQUARES;
+ double unit_width = (HEIGHT_SQUARES - 1) * square;
+ int width_units = (width + unit_width / 2) / unit_width;
+ double y_top, y_bottom;
+ int i;
+
+ cairo_save (cr);
+
+ set_color (crenderer, PANGO_RENDER_PART_UNDERLINE);
+
+ x += (width - width_units * unit_width);
+ width = width_units * unit_width;
+
+ cairo_new_path (cr);
+
+ y_top = y + height;
+ y_bottom = y;
+
+ /* Bottom of squiggle */
+ cairo_move_to (cr, x - square / 2, y_top - square / 2); /* A */
+ for (i = 0; i < width_units; i += 2)
+ {
+ double x_middle = x + (i + 1) * unit_width;
+ double x_right = x + (i + 2) * unit_width;
+
+ cairo_line_to (cr, x_middle, y_bottom); /* B */
+
+ if (i + 1 == width_units)
+ /* Nothing */;
+ else if (i + 2 == width_units)
+ cairo_line_to (cr, x_right + square / 2, y_top - square / 2); /* D */
+ else
+ cairo_line_to (cr, x_right, y_top - square); /* C */
+ }
+
+ /* Top of squiggle */
+ for (i -= 2; i >= 0; i -= 2)
+ {
+ double x_left = x + i * unit_width;
+ double x_middle = x + (i + 1) * unit_width;
+ double x_right = x + (i + 2) * unit_width;
+
+ if (i + 1 == width_units)
+ cairo_line_to (cr, x_middle + square / 2, y_bottom + square / 2); /* G */
+ else
+ {
+ if (i + 2 == width_units)
+ cairo_line_to (cr, x_right, y_top); /* E */
+ cairo_line_to (cr, x_middle, y_bottom + square); /* F */
+ }
+
+ cairo_line_to (cr, x_left, y_top); /* H */
+ }
+
+ cairo_close_path (cr);
+ cairo_fill (cr);
+
+ cairo_restore (cr);
+}
+
+static void
+pango_cairo_renderer_init (PangoCairoRenderer *renderer)
+{
+}
+
+static void
+pango_cairo_renderer_class_init (PangoCairoRendererClass *klass)
+{
+ PangoRendererClass *renderer_class = PANGO_RENDERER_CLASS (klass);
+
+ renderer_class->draw_glyphs = pango_cairo_renderer_draw_glyphs;
+ renderer_class->draw_rectangle = pango_cairo_renderer_draw_rectangle;
+ renderer_class->draw_error_underline = pango_cairo_renderer_draw_error_underline;
+}
+
+static void
+current_point_to_origin (cairo_t *cr)
+{
+ double x, y;
+
+ cairo_current_point (cr, &x, &y);
+ cairo_translate (cr, x, y);
+}
+
+/**
+ * pango_cairo_show_glyphs:
+ * @cr: a Cairo context
+ * @font: a #PangoFont
+ * @glyphs: a #PangoGlyphString
+ *
+ * Draws the glyphs in @glyphs in the specified cairo context.
+ * The origin of the glyphs (the left edge of the baseline) will
+ * be drawn at the current point of the cairo context.
+ *
+ * Since: 1.10
+ **/
+void
+pango_cairo_show_glyphs (cairo_t *cr,
+ PangoFont *font,
+ PangoGlyphString *glyphs)
+{
+ PangoFontMap *fontmap;
+ PangoCairoRenderer *crenderer;
+ PangoRenderer *renderer;
+
+ g_return_if_fail (cr != NULL);
+ g_return_if_fail (PANGO_IS_CAIRO_FONT (font));
+ g_return_if_fail (glyphs != NULL);
+
+ fontmap = PANGO_FC_FONT (font)->fontmap;
+ renderer = _pango_cairo_font_map_get_renderer (PANGO_CAIRO_FONT_MAP (fontmap));
+ crenderer = PANGO_CAIRO_RENDERER (renderer);
+
+ cairo_save (cr);
+ current_point_to_origin (cr);
+
+ crenderer->cr = cr;
+ pango_renderer_draw_glyphs (renderer, font, glyphs, 0, 0);
+ crenderer->cr = NULL;
+
+ cairo_restore (cr);
+}
+
+/**
+ * pango_cairo_show_layout_line:
+ * @cr: a Cairo context
+ * @line: a #PangoLayoutLine
+ *
+ * Draws a #PangoLayoutLine in the specified cairo context.
+ * The origin of the glyphs (the left edge of the line) will
+ * be drawn at the current point of the cairo context.
+ *
+ * Since: 1.10
+ **/
+void
+pango_cairo_show_layout_line (cairo_t *cr,
+ PangoLayoutLine *line)
+{
+ PangoContext *context;
+ PangoFontMap *fontmap;
+ PangoRenderer *renderer;
+ PangoCairoRenderer *crenderer;
+
+ g_return_if_fail (cr != NULL);
+ g_return_if_fail (line != NULL);
+
+ context = pango_layout_get_context (line->layout);
+ fontmap = pango_context_get_font_map (context);
+ renderer = _pango_cairo_font_map_get_renderer (PANGO_CAIRO_FONT_MAP (fontmap));
+ crenderer = PANGO_CAIRO_RENDERER (renderer);
+
+ cairo_save (cr);
+ current_point_to_origin (cr);
+
+ crenderer->cr = cr;
+ pango_renderer_draw_layout_line (renderer, line, 0, 0);
+ crenderer->cr = NULL;
+
+ cairo_restore (cr);
+}
+
+/**
+ * pango_cairo_show_layout:
+ * @cr: a Cairo context
+ * @layout: a Pango layout
+ *
+ * Draws a #PangoLayoutLine in the specified cairo context.
+ * The top-left corner of the #PangoLayout will be drawn
+ * at the current point of the cairo context.
+ *
+ * Since: 1.10
+ **/
+void
+pango_cairo_show_layout (cairo_t *cr,
+ PangoLayout *layout)
+{
+ PangoContext *context;
+ PangoFontMap *fontmap;
+ PangoRenderer *renderer;
+ PangoCairoRenderer *crenderer;
+
+ g_return_if_fail (cr != NULL);
+ g_return_if_fail (PANGO_IS_LAYOUT (layout));
+
+ context = pango_layout_get_context (layout);
+ fontmap = pango_context_get_font_map (context);
+ renderer = _pango_cairo_font_map_get_renderer (PANGO_CAIRO_FONT_MAP (fontmap));
+ crenderer = PANGO_CAIRO_RENDERER (renderer);
+
+ cairo_save (cr);
+ current_point_to_origin (cr);
+
+ crenderer->cr = cr;
+ pango_renderer_draw_layout (renderer, layout, 0, 0);
+ crenderer->cr = NULL;
+
+ cairo_restore (cr);
+}
diff --git a/pango/pangocairo.h b/pango/pangocairo.h
new file mode 100644
index 00000000..f46987a0
--- /dev/null
+++ b/pango/pangocairo.h
@@ -0,0 +1,84 @@
+/* Pango
+ * pangocairo.h:
+ *
+ * Copyright (C) 1999, 2004 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_H__
+#define __PANGOCAIRO_H__
+
+#include <pango/pango-context.h>
+#include <pango/pangofc-fontmap.h>
+#include <pango/pango-layout.h>
+#include <cairo.h>
+
+G_BEGIN_DECLS
+
+/**
+ * PangoCairoFontMap:
+ *
+ * #PangoCairoFontMap is an interface exported by font maps for
+ * use with Cairo. The actual type of the font map will depend
+ * on the particular font technology Cairo was compiled to use.
+ *
+ * Since: 1.10
+ **/
+#define PANGO_TYPE_CAIRO_FONT_MAP (pango_cairo_font_map_get_type ())
+#define PANGO_CAIRO_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), PANGO_TYPE_CAIRO_FONT_MAP, PangoCairoFontMap))
+#define PANGO_IS_CAIRO_FONT_MAP(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), PANGO_TYPE_CAIRO_FONT_MAP))
+
+typedef struct _PangoCairoFontMap PangoCairoFontMap;
+
+/*
+ * PangoCairoFontMap
+ */
+GType pango_cairo_font_map_get_type (void);
+
+PangoFontMap *pango_cairo_font_map_new (void);
+PangoFontMap *pango_cairo_font_map_get_default (void);
+
+void pango_cairo_font_map_set_resolution (PangoCairoFontMap *fontmap,
+ double dpi);
+double pango_cairo_font_map_get_resolution (PangoCairoFontMap *fontmap);
+PangoContext *pango_cairo_font_map_create_context (PangoCairoFontMap *fontmap);
+
+/* Update a Pango context for the current state of a cairo context
+ */
+void pango_cairo_update_context (cairo_t *cr,
+ PangoContext *context);
+
+/* Convenience
+ */
+PangoLayout *pango_cairo_create_layout (cairo_t *cr);
+void pango_cairo_update_layout (cairo_t *cr,
+ PangoLayout *layout);
+
+/*
+ * Rendering
+ */
+void pango_cairo_show_glyphs (cairo_t *cr,
+ PangoFont *font,
+ PangoGlyphString *glyphs);
+void pango_cairo_show_layout_line (cairo_t *cr,
+ PangoLayoutLine *line);
+void pango_cairo_show_layout (cairo_t *cr,
+ PangoLayout *layout);
+
+G_END_DECLS
+
+#endif /* __PANGOCAIRO_H__ */
diff --git a/pango/pangofc-font.c b/pango/pangofc-font.c
index 71c81bc2..65620384 100644
--- a/pango/pangofc-font.c
+++ b/pango/pangofc-font.c
@@ -26,14 +26,9 @@
#include "pango-modules.h"
#include "pango-utils.h"
-#include FT_TRUETYPE_TABLES_H
+#include <fontconfig/fcfreetype.h>
-#define PANGO_SCALE_26_6 (PANGO_SCALE / (1<<6))
-#define PANGO_PIXELS_26_6(d) \
- (((d) >= 0) ? \
- ((d) + PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6 : \
- ((d) - PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6)
-#define PANGO_UNITS_26_6(d) (PANGO_SCALE_26_6 * (d))
+#include FT_TRUETYPE_TABLES_H
typedef struct _PangoFcMetricsInfo PangoFcMetricsInfo;
@@ -57,6 +52,11 @@ struct _PangoFcFontPrivate
PangoFcDecoder *decoder;
};
+static gboolean pango_fc_font_real_has_char (PangoFcFont *font,
+ gunichar wc);
+static guint pango_fc_font_real_get_glyph (PangoFcFont *font,
+ gunichar wc);
+
static void pango_fc_font_finalize (GObject *object);
static void pango_fc_font_set_property (GObject *object,
guint prop_id,
@@ -78,6 +78,9 @@ pango_fc_font_class_init (PangoFcFontClass *class)
{
GObjectClass *object_class = G_OBJECT_CLASS (class);
PangoFontClass *font_class = PANGO_FONT_CLASS (class);
+
+ class->has_char = pango_fc_font_real_has_char;
+ class->get_glyph = pango_fc_font_real_get_glyph;
object_class->finalize = pango_fc_font_finalize;
object_class->set_property = pango_fc_font_set_property;
@@ -458,6 +461,37 @@ pango_fc_font_get_metrics (PangoFont *font,
return pango_font_metrics_ref (info->metrics);
}
+static gboolean
+pango_fc_font_real_has_char (PangoFcFont *font,
+ gunichar wc)
+{
+ FcCharSet *charset;
+
+ if (FcPatternGetCharSet (font->font_pattern,
+ FC_CHARSET, 0, &charset) != FcResultMatch)
+ return FALSE;
+
+ return FcCharSetHasChar (charset, wc);
+}
+
+static guint
+pango_fc_font_real_get_glyph (PangoFcFont *font,
+ gunichar wc)
+{
+ FT_Face face;
+ FT_UInt index;
+
+ face = pango_fc_font_lock_face (font);
+
+ index = FcFreeTypeCharIndex (face, wc);
+ if (index && index <= face->num_glyphs)
+ return index;
+
+ pango_fc_font_unlock_face (font);
+
+ return 0;
+}
+
/**
* pango_fc_font_lock_face:
* @font: a #PangoFcFont.
diff --git a/pango/pangofc-fontmap.c b/pango/pangofc-fontmap.c
index 5ac4f285..9dad20b9 100644
--- a/pango/pangofc-fontmap.c
+++ b/pango/pangofc-fontmap.c
@@ -246,6 +246,7 @@ struct _FontsetHashKey {
PangoFontDescription *desc;
int x_size;
int y_size;
+ guint flags;
};
static gboolean
@@ -254,6 +255,7 @@ fontset_hash_key_equal (const FontsetHashKey *key_a,
{
if (key_a->x_size == key_b->x_size &&
key_a->y_size == key_b->y_size &&
+ key_a->flags == key_b->flags &&
pango_font_description_equal (key_a->desc, key_b->desc))
return TRUE;
else
@@ -263,7 +265,7 @@ fontset_hash_key_equal (const FontsetHashKey *key_a,
static guint
fontset_hash_key_hash (const FontsetHashKey *key)
{
- return (key->x_size << 16) ^ (key->y_size) ^ pango_font_description_hash (key->desc);
+ return (key->x_size << 16) ^ (key->y_size) ^ (key->flags) ^ pango_font_description_hash (key->desc);
}
static void
@@ -280,6 +282,7 @@ fontset_hash_key_copy (FontsetHashKey *old)
key->x_size = old->x_size;
key->y_size = old->y_size;
+ key->flags = old->flags;
key->desc = pango_font_description_copy (old->desc);
return key;
@@ -803,14 +806,15 @@ transformed_length (const PangoMatrix *matrix,
}
static gboolean
-pango_fc_font_map_get_rendered_size (PangoFcFontMap *fcfontmap,
- PangoContext *context,
- const PangoFontDescription *desc,
- int *x_size,
- int *y_size)
-{
- if (PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->get_rendered_size)
- return PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->get_rendered_size (fcfontmap, context, desc, x_size, y_size);
+pango_fc_font_map_get_render_key (PangoFcFontMap *fcfontmap,
+ PangoContext *context,
+ const PangoFontDescription *desc,
+ int *x_size,
+ int *y_size,
+ guint *flags)
+{
+ if (PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->get_render_key)
+ return PANGO_FC_FONT_MAP_GET_CLASS (fcfontmap)->get_render_key (fcfontmap, context, desc, x_size, y_size, flags);
else
{
int size = pango_font_description_get_size (desc);
@@ -841,6 +845,8 @@ pango_fc_font_map_get_rendered_size (PangoFcFontMap *fcfontmap,
retval = FALSE;
}
+ *flags = 0;
+
return retval;
}
}
@@ -865,11 +871,11 @@ pango_fc_font_map_get_patterns (PangoFontMap *fontmap,
if (!language && context)
language = pango_context_get_language (context);
- fontset_hash = pango_fc_get_fontset_hash (fcfontmap, language);
+ fontset_hash = pango_fc_get_fontset_hash (fcfontmap, language);
key.desc = pango_font_description_copy_static (desc);
pango_font_description_unset_fields (key.desc, PANGO_FONT_MASK_SIZE);
- cache = pango_fc_font_map_get_rendered_size (fcfontmap, context, desc, &key.x_size, &key.y_size);
+ cache = pango_fc_font_map_get_render_key (fcfontmap, context, desc, &key.x_size, &key.y_size, &key.flags);
if (cache_out)
*cache_out = cache;
diff --git a/pango/pangofc-fontmap.h b/pango/pangofc-fontmap.h
index 318ad03c..9302a701 100644
--- a/pango/pangofc-fontmap.h
+++ b/pango/pangofc-fontmap.h
@@ -68,6 +68,11 @@ struct _PangoFcFontMap
* pattern of the appropriate type for this font map. The
* @pattern argument must be passed to the "pattern" property
* of #PangoFcFont when you call g_object_new()
+ * @get_render_key: Given a context and font description,
+ * calculate a "key" of X and Y sizes and a flags word
+ * that can be used to hash the results of loading a font
+ * with that information. If %NULL, a default implementation
+ is used.
*
* Class structure for #PangoFcFontMap.
**/
@@ -82,11 +87,12 @@ struct _PangoFcFontMapClass
PangoFcFont *(*new_font) (PangoFcFontMap *fontmap,
FcPattern *pattern);
- gboolean (*get_rendered_size) (PangoFcFontMap *fcfontmap,
+ gboolean (*get_render_key) (PangoFcFontMap *fcfontmap,
PangoContext *context,
const PangoFontDescription *desc,
int *xsize,
- int *ysize);
+ int *ysize,
+ guint *flags);
/*< private >*/
/* Padding for future expansion */
diff --git a/pango/pangofc-private.h b/pango/pangofc-private.h
index 1b42ba16..751a87f6 100644
--- a/pango/pangofc-private.h
+++ b/pango/pangofc-private.h
@@ -27,6 +27,13 @@
G_BEGIN_DECLS
+#define PANGO_SCALE_26_6 (PANGO_SCALE / (1<<6))
+#define PANGO_PIXELS_26_6(d) \
+ (((d) >= 0) ? \
+ ((d) + PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6 : \
+ ((d) - PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6)
+#define PANGO_UNITS_26_6(d) (PANGO_SCALE_26_6 * (d))
+
void _pango_fc_font_shutdown (PangoFcFont *fcfont);
void _pango_fc_font_map_remove (PangoFcFontMap *fcfontmap,
diff --git a/pango/pangoft2-private.h b/pango/pangoft2-private.h
index c0b8a7e5..ac5c85a8 100644
--- a/pango/pangoft2-private.h
+++ b/pango/pangoft2-private.h
@@ -26,7 +26,6 @@
#include "pangoft2.h"
#include "pango-renderer.h"
#include <fontconfig/fontconfig.h>
-#include <fontconfig/fcfreetype.h>
/* Debugging... */
/*#define DEBUGGING 1*/
@@ -47,13 +46,6 @@
#define PING(printlist)
#endif
-#define PANGO_SCALE_26_6 (PANGO_SCALE / (1<<6))
-#define PANGO_PIXELS_26_6(d) \
- (((d) >= 0) ? \
- ((d) + PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6 : \
- ((d) - PANGO_SCALE_26_6 / 2) / PANGO_SCALE_26_6)
-#define PANGO_UNITS_26_6(d) (PANGO_SCALE_26_6 * (d))
-
typedef struct _PangoFT2Font PangoFT2Font;
typedef struct _PangoFT2GlyphInfo PangoFT2GlyphInfo;
typedef struct _PangoFT2Renderer PangoFT2Renderer;
diff --git a/pango/pangoft2.c b/pango/pangoft2.c
index d0c35358..75168307 100644
--- a/pango/pangoft2.c
+++ b/pango/pangoft2.c
@@ -58,10 +58,6 @@ static void pango_ft2_font_get_glyph_extents (PangoFont *
static FT_Face pango_ft2_font_real_lock_face (PangoFcFont *font);
static void pango_ft2_font_real_unlock_face (PangoFcFont *font);
-static gboolean pango_ft2_font_real_has_char (PangoFcFont *font,
- gunichar wc);
-static guint pango_ft2_font_real_get_glyph (PangoFcFont *font,
- gunichar wc);
static PangoGlyph pango_ft2_font_real_get_unknown_glyph (PangoFcFont *font,
gunichar wc);
@@ -263,8 +259,6 @@ pango_ft2_font_class_init (PangoFT2FontClass *class)
fc_font_class->lock_face = pango_ft2_font_real_lock_face;
fc_font_class->unlock_face = pango_ft2_font_real_unlock_face;
- fc_font_class->has_char = pango_ft2_font_real_has_char;
- fc_font_class->get_glyph = pango_ft2_font_real_get_glyph;
fc_font_class->get_unknown_glyph = pango_ft2_font_real_get_unknown_glyph;
}
@@ -366,34 +360,6 @@ pango_ft2_font_real_unlock_face (PangoFcFont *font)
{
}
-static gboolean
-pango_ft2_font_real_has_char (PangoFcFont *font,
- gunichar wc)
-{
- FcCharSet *charset;
-
- if (FcPatternGetCharSet (font->font_pattern,
- FC_CHARSET, 0, &charset) != FcResultMatch)
- return FALSE;
-
- return FcCharSetHasChar (charset, wc);
-}
-
-static guint
-pango_ft2_font_real_get_glyph (PangoFcFont *font,
- gunichar wc)
-{
- FT_Face face;
- FT_UInt index;
-
- face = pango_ft2_font_get_face ((PangoFont *)font);
- index = FcFreeTypeCharIndex (face, wc);
- if (index && index <= face->num_glyphs)
- return index;
-
- return 0;
-}
-
static PangoGlyph
pango_ft2_font_real_get_unknown_glyph (PangoFcFont *font,
gunichar wc)