summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBehdad Esfahbod <behdad@gnome.org>2006-02-06 11:25:14 +0000
committerBehdad Esfahbod <behdad@src.gnome.org>2006-02-06 11:25:14 +0000
commit8c71138ba5500a3d1bf446357992e8f165101173 (patch)
treea453bbcc0fba741aba3b3e16074933407f60dccc
parent9f81790eaec937ced41c31fb6204d63a377a00a7 (diff)
downloadpango-8c71138ba5500a3d1bf446357992e8f165101173.tar.gz
Bug 328067 – Install pango-view
2006-02-06 Behdad Esfahbod <behdad@gnome.org> Bug 328067 – Install pango-view Added a rather generic framework for a pango-view example. All backends have their own pango*-view built, and a pango-view binary is built too, that can choose backend via --backend. This one is installed in bindir. * examples/Makefile.am: Updated, to build pangox-view, pangoft2-view, pangoxft-view, pangocairo-view, and pango-view. * examples/viewer.h, examples/viewer-x.c, examples/viewer-x.h examples/viewer-cairo.c, examples/viewer-cairo.h, examples/viewer-main.c, examples/viewer-pangox.c, examples/viewer-pangoft2.c, examples/viewer-pangoxft.c, examples/viewer-pangocairo.c, examples/pango-view.c, examples/pango-xview.c, examples/pango-ft2view.c, examples/pango-xftview.c, examples/pango-cairoview.c: Added. * examples/cairoview.c, examples/xftview.c, examples/pangoft2topgm.c, examples/viewer-qt.cc, examples/viewer-qt.h: Removed. * configure.in: Check for Cairo Xlib backend, also AC_DEFINE various backend bits.
-rw-r--r--ChangeLog26
-rw-r--r--configure.in10
-rw-r--r--examples/.cvsignore5
-rw-r--r--examples/Makefile.am158
-rw-r--r--examples/cairoview.c169
-rw-r--r--examples/pango-view.c23
-rw-r--r--examples/pangocairo-view.c8
-rw-r--r--examples/pangoft2-view.c8
-rw-r--r--examples/pangoft2topgm.c199
-rw-r--r--examples/pangox-view.c8
-rw-r--r--examples/pangoxft-view.c8
-rw-r--r--examples/renderdemo.c178
-rw-r--r--examples/renderdemo.h36
-rw-r--r--examples/viewer-cairo.c53
-rw-r--r--examples/viewer-cairo.h42
-rw-r--r--examples/viewer-main.c155
-rw-r--r--examples/viewer-pangocairo.c326
-rw-r--r--examples/viewer-pangoft2.c162
-rw-r--r--examples/viewer-pangox.c113
-rw-r--r--examples/viewer-pangoxft.c151
-rw-r--r--examples/viewer-qt.cc528
-rw-r--r--examples/viewer-qt.h116
-rw-r--r--examples/viewer-x.c229
-rw-r--r--examples/viewer-x.h64
-rw-r--r--examples/viewer.h85
-rw-r--r--examples/xftview.c118
26 files changed, 1619 insertions, 1359 deletions
diff --git a/ChangeLog b/ChangeLog
index 62d7db20..263be5ce 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,31 @@
2006-02-06 Behdad Esfahbod <behdad@gnome.org>
+ Bug 328067 – Install pango-view
+
+ Added a rather generic framework for a pango-view example. All
+ backends have their own pango*-view built, and a pango-view binary
+ is built too, that can choose backend via --backend. This one is
+ installed in bindir.
+
+ * examples/Makefile.am: Updated, to build pangox-view, pangoft2-view,
+ pangoxft-view, pangocairo-view, and pango-view.
+
+ * examples/viewer.h, examples/viewer-x.c, examples/viewer-x.h
+ examples/viewer-cairo.c, examples/viewer-cairo.h,
+ examples/viewer-main.c, examples/viewer-pangox.c,
+ examples/viewer-pangoft2.c, examples/viewer-pangoxft.c,
+ examples/viewer-pangocairo.c, examples/pango-view.c,
+ examples/pango-xview.c, examples/pango-ft2view.c,
+ examples/pango-xftview.c, examples/pango-cairoview.c: Added.
+
+ * examples/cairoview.c, examples/xftview.c, examples/pangoft2topgm.c,
+ examples/viewer-qt.cc, examples/viewer-qt.h: Removed.
+
+ * configure.in: Check for Cairo Xlib backend, also AC_DEFINE various
+ backend bits.
+
+2006-02-06 Behdad Esfahbod <behdad@gnome.org>
+
* pango/pango-fontmap.c (pango_font_map_real_load_fontset): Warn
only once per font-description that cannot be loaded.
diff --git a/configure.in b/configure.in
index 7778d077..cba667cb 100644
--- a/configure.in
+++ b/configure.in
@@ -242,12 +242,16 @@ if $have_fontconfig ; then
AC_SUBST(FREETYPE_LIBS)
AC_SUBST(FREETYPE_CFLAGS)
+ AC_DEFINE(HAVE_FREETYPE, 1, [Have FreeType 2 library])
#
# Checks for Xft/XRender
#
if $have_x && $have_freetype ; then
PKG_CHECK_MODULES(XFT, xft >= 2.0.0, have_xft=true, :)
+ if $have_xft ; then
+ AC_DEFINE(HAVE_XFT, 1, [Have Xft library])
+ fi
fi
else
AC_MSG_WARN([No fontconfig found, skipping tests for FreeType and Xft])
@@ -286,6 +290,7 @@ AC_CHECK_HEADER(Carbon/Carbon.h, [have_atsui=true], [have_atsui=true])
#
have_cairo=false
have_cairo_png=false
+have_cairo_xlib=false
have_cairo_freetype=false
have_cairo_win32=false
have_cairo_atsui=false
@@ -302,6 +307,10 @@ if $have_cairo ; then
if $have_cairo_png; then
AC_DEFINE(HAVE_CAIRO_PNG, 1, [Whether Cairo has PNG support])
fi
+ AC_CHECK_LIB(cairo, cairo_xlib_surface_create, have_cairo_xlib=true, :)
+ if $have_cairo_xlib; then
+ AC_DEFINE(HAVE_CAIRO_XLIB, 1, [Whether Cairo has Xlib support])
+ fi
have_cairo=false
AC_CHECK_LIB(cairo, cairo_win32_scaled_font_select_font, have_cairo_win32=true, :)
if $have_cairo_win32 && $have_win32; then
@@ -323,6 +332,7 @@ fi
AM_CONDITIONAL(HAVE_CAIRO, $have_cairo)
AM_CONDITIONAL(HAVE_CAIRO_PNG, $have_cairo_png)
+AM_CONDITIONAL(HAVE_CAIRO_XLIB, $have_cairo_xlib)
AM_CONDITIONAL(HAVE_CAIRO_WIN32, $have_cairo_win32 && $have_win32)
AM_CONDITIONAL(HAVE_CAIRO_FREETYPE, $have_cairo_freetype && $have_freetype)
AM_CONDITIONAL(HAVE_CAIRO_ATSUI, $have_cairo_atsui && $have_atsui)
diff --git a/examples/.cvsignore b/examples/.cvsignore
index 1611fa22..2802de3e 100644
--- a/examples/.cvsignore
+++ b/examples/.cvsignore
@@ -2,11 +2,8 @@ Makefile.in
Makefile
makefile.mingw
pangorc
+pango*-view
cairosimple
-pangocairo-view
-pangoxft-view
-pangoft2-view
-moc_viewer-qt.cc
.deps
.libs
*.lo
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 0d2dc42d..63a41531 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -1,10 +1,10 @@
## Process this file with automake to create Makefile.in.
TEST_TEXTS = \
- test-arabic.txt \
+ test-arabic.txt \
test-devanagari.txt \
test-ipa.txt \
- test-syriac.txt \
+ test-syriac.txt \
test-tamil.txt \
test-tibetan.txt \
HELLO.utf8 \
@@ -18,7 +18,6 @@ EXTRA_DIST = \
CLEANFILES = pangorc
INCLUDES = \
- -DPANGO_DISABLE_DEPRECATED \
-I$(top_srcdir) \
$(PANGO_DEBUG_FLAGS) \
$(GLIB_CFLAGS) \
@@ -28,34 +27,64 @@ INCLUDES = \
$(X_CFLAGS)
noinst_PROGRAMS =
+bin_PROGRAMS =
-###################################################
+#########################################################
if HAVE_FREETYPE
noinst_PROGRAMS += pangoft2-view
-endif
-pangoft2_view_SOURCES = \
- pangoft2topgm.c \
- renderdemo.h \
- renderdemo.c
+pangoft2_view_SOURCES = \
+ renderdemo.h \
+ renderdemo.c \
+ viewer.h \
+ viewer-main.c \
+ viewer-pangoft2.c \
+ pangoft2-view.c
+
pangoft2_view_LDADD = \
../pango/libpango-$(PANGO_API_VERSION).la \
../pango/libpangoft2-$(PANGO_API_VERSION).la \
$(GLIB_LIBS) \
$(FREETYPE_LIBS)
-###################################################
+endif
+#########################################################
+
+#########################################################
+if HAVE_X
+noinst_PROGRAMS += pangox-view
+
+pangox_view_SOURCES = \
+ renderdemo.h \
+ renderdemo.c \
+ viewer.h \
+ viewer-x.h \
+ viewer-x.c \
+ viewer-main.c \
+ viewer-pangox.c \
+ pangox-view.c
-###################################################
+pangox_view_LDADD = \
+ ../pango/libpango-$(PANGO_API_VERSION).la \
+ ../pango/libpangox-$(PANGO_API_VERSION).la \
+ $(GLIB_LIBS) \
+ $(X_LIBS)
+endif
+#########################################################
+
+#########################################################
if HAVE_XFT
noinst_PROGRAMS += pangoxft-view
-endif
-pangoxft_view_SOURCES = \
- renderdemo.h \
- renderdemo.c \
- viewer-x.h \
- viewer-x.c \
- xftview.c
+pangoxft_view_SOURCES = \
+ renderdemo.h \
+ renderdemo.c \
+ viewer.h \
+ viewer-x.h \
+ viewer-x.c \
+ viewer-main.c \
+ viewer-pangoxft.c \
+ pangoxft-view.c
+
pangoxft_view_LDADD = \
../pango/libpango-$(PANGO_API_VERSION).la \
../pango/libpangoft2-$(PANGO_API_VERSION).la \
@@ -63,36 +92,92 @@ pangoxft_view_LDADD = \
$(GLIB_LIBS) \
$(XFT_LIBS) \
$(X_LIBS)
-###################################################
+endif
+#########################################################
-###################################################
+#########################################################
if HAVE_CAIRO
if HAVE_X
-if HAVE_FREETYPE
+if HAVE_CAIRO_XLIB
noinst_PROGRAMS += pangocairo-view
+
+pangocairo_view_SOURCES = \
+ renderdemo.h \
+ renderdemo.c \
+ viewer.h \
+ viewer-cairo.h \
+ viewer-cairo.c \
+ viewer-x.h \
+ viewer-x.c \
+ viewer-main.c \
+ viewer-pangocairo.c \
+ pangocairo-view.c
+
+pangocairo_view_LDADD = \
+ ../pango/libpango-$(PANGO_API_VERSION).la \
+ ../pango/libpangocairo-$(PANGO_API_VERSION).la \
+ $(GLIB_LIBS) \
+ $(CAIRO_LIBS) \
+ $(X_LIBS)
endif
endif
endif
+#########################################################
-pangocairo_view_SOURCES = \
- renderdemo.h \
- renderdemo.c \
- viewer-x.h \
- viewer-x.c \
- cairoview.c
-pangocairo_view_LDADD = \
+#########################################################
+if HAVE_X
+bin_PROGRAMS += pango-view
+pango_view_SOURCES = \
+ renderdemo.h \
+ renderdemo.c \
+ viewer.h \
+ viewer-x.h \
+ viewer-x.c \
+ viewer-main.c \
+ pango-view.c
+pango_view_LDADD = \
../pango/libpango-$(PANGO_API_VERSION).la \
+ $(GLIB_LIBS)
+if HAVE_X
+pango_view_SOURCES += \
+ viewer-pangox.c
+pango_view_LDADD += \
+ ../pango/libpangox-$(PANGO_API_VERSION).la
+endif
+if HAVE_FREETYPE
+pango_view_SOURCES += \
+ viewer-pangoft2.c
+pango_view_LDADD += \
../pango/libpangoft2-$(PANGO_API_VERSION).la \
+ $(FREETYPE_LIBS)
+endif
+if HAVE_XFT
+pango_view_SOURCES += \
+ viewer-pangoxft.c
+pango_view_LDADD += \
+ ../pango/libpangoft2-$(PANGO_API_VERSION).la \
+ ../pango/libpangoxft-$(PANGO_API_VERSION).la \
+ $(XFT_LIBS)
+endif
+if HAVE_CAIRO
+if HAVE_CAIRO_XLIB
+pango_view_SOURCES += \
+ viewer-cairo.h \
+ viewer-cairo.c \
+ viewer-pangocairo.c
+pango_view_LDADD += \
../pango/libpangocairo-$(PANGO_API_VERSION).la \
- $(GLIB_LIBS) \
- $(CAIRO_LIBS) \
+ $(CAIRO_LIBS)
+endif
+endif
+pango_view_LDADD += \
$(X_LIBS)
-###################################################
+endif
+#########################################################
-###################################################
+#########################################################
if HAVE_CAIRO_PNG
noinst_PROGRAMS += cairosimple
-endif
cairosimple_SOURCES = \
cairosimple.c
@@ -101,9 +186,10 @@ cairosimple_LDADD = \
../pango/libpangocairo-$(PANGO_API_VERSION).la \
$(GLIB_LIBS) \
$(CAIRO_LIBS)
-###################################################
+endif
+#########################################################
+
+BUILT_SOURCES = pangorc
pangorc: $(srcdir)/../modules/pangorc
cp $< $@
-
-$(noinst_PROGRAMS): pangorc
diff --git a/examples/cairoview.c b/examples/cairoview.c
deleted file mode 100644
index 8e43a56a..00000000
--- a/examples/cairoview.c
+++ /dev/null
@@ -1,169 +0,0 @@
-/* Pango
- * cairoview.c: Example program to view a UTF-8 encoding file
- * using PangoCairo to render result
- *
- * Copyright (C) 1999,2004,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 <config.h>
-
-#include "renderdemo.h"
-#include "viewer-x.h"
-
-#include <pango/pangocairo.h>
-#include <cairo-xlib.h>
-
-static void
-render_callback (PangoLayout *layout,
- int x,
- int y,
- gpointer data,
- gboolean show_borders)
-{
- cairo_t *cr = (cairo_t *)data;
-
- cairo_move_to (cr, x, y);
- pango_cairo_show_layout (cr, layout);
-
- if (show_borders)
- {
- PangoRectangle ink, logical;
- double lw = cairo_get_line_width (cr);
-
- pango_layout_get_extents (layout, &ink, &logical);
-
- cairo_save (cr);
- cairo_set_source_rgba (cr, 1.0, 0.0, 0.0, 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_source_rgba (cr, 0.0, 1.0, 0.0, 0.75);
-
- 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
-transform_callback (PangoContext *context,
- PangoMatrix *matrix,
- gpointer data)
-{
- cairo_t *cr = (cairo_t *)data;
- cairo_matrix_t cairo_matrix;
-
- if (matrix)
- {
- cairo_matrix.xx = matrix->xx;
- cairo_matrix.yx = matrix->yx;
- cairo_matrix.xy = matrix->xy;
- cairo_matrix.yy = matrix->yy;
- cairo_matrix.x0 = matrix->x0;
- cairo_matrix.y0 = matrix->y0;
- }
- else
- {
- cairo_matrix_init_identity (&cairo_matrix);
- }
-
- cairo_set_matrix (cr, &cairo_matrix);
-
- pango_context_set_matrix (context, matrix);
- pango_cairo_update_context (cr, context);
-}
-
-void
-do_init (Display *display,
- int screen,
- int dpi,
- /* output */
- PangoContext **context,
- int *width,
- int *height)
-{
- PangoFontMap *fontmap;
- cairo_t *cr;
- cairo_surface_t *surface;
- fontmap = pango_cairo_font_map_get_default ();
- pango_cairo_font_map_set_resolution (PANGO_CAIRO_FONT_MAP (fontmap), dpi);
- *context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (fontmap));
-
- /* This is annoying ... we have to create a temporary surface just to
- * get the extents of the text.
- */
- surface = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 1, 1);
- cr = cairo_create (surface);
- cairo_surface_destroy (surface);
- do_output (*context, NULL, transform_callback, cr, width, height, FALSE);
- cairo_destroy (cr);
-}
-
-void
-do_render (Display *display,
- int screen,
- Window window,
- Pixmap pixmap,
- PangoContext *context,
- int width,
- int height,
- gboolean show_borders)
-{
- cairo_t *cr;
- cairo_surface_t *surface;
-
- surface = cairo_xlib_surface_create (display, pixmap,
- DefaultVisual (display, screen),
- width, height);
-
- cr = cairo_create (surface);
-
- transform_callback (context, NULL, cr);
-
- cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
- cairo_paint (cr);
-
- /* Draw the text in black */
- cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
- do_output (context, render_callback, transform_callback, cr, NULL, NULL, show_borders);
-
-#ifdef HAVE_CAIRO_PNG
- if (opt_output && *opt_output)
- {
- cairo_status_t status;
-
- status = cairo_surface_write_to_png (surface, opt_output);
- if (status != CAIRO_STATUS_SUCCESS)
- g_printerr ("could not save PNG to '%s'\n", opt_output);
- }
-#endif
-
- cairo_surface_destroy (surface);
- cairo_destroy (cr);
-}
diff --git a/examples/pango-view.c b/examples/pango-view.c
new file mode 100644
index 00000000..9771e8cc
--- /dev/null
+++ b/examples/pango-view.c
@@ -0,0 +1,23 @@
+#include <config.h>
+#include "viewer.h"
+
+extern const PangoViewer pangocairo_viewer;
+extern const PangoViewer pangoxft_viewer;
+extern const PangoViewer pangoft2_viewer;
+extern const PangoViewer pangox_viewer;
+
+const PangoViewer *viewers[] = {
+#ifdef HAVE_CAIRO_XLIB
+ &pangocairo_viewer,
+#endif
+#ifdef HAVE_XFT
+ &pangoxft_viewer,
+#endif
+#ifdef HAVE_FREETYPE
+ &pangoft2_viewer,
+#endif
+#ifdef HAVE_X
+ &pangox_viewer,
+#endif
+ NULL
+};
diff --git a/examples/pangocairo-view.c b/examples/pangocairo-view.c
new file mode 100644
index 00000000..c5ba8716
--- /dev/null
+++ b/examples/pangocairo-view.c
@@ -0,0 +1,8 @@
+#include "viewer.h"
+
+extern const PangoViewer pangocairo_viewer;
+
+const PangoViewer *viewers[] = {
+ &pangocairo_viewer,
+ NULL
+};
diff --git a/examples/pangoft2-view.c b/examples/pangoft2-view.c
new file mode 100644
index 00000000..d4ac695c
--- /dev/null
+++ b/examples/pangoft2-view.c
@@ -0,0 +1,8 @@
+#include "viewer.h"
+
+extern const PangoViewer pangoft2_viewer;
+
+const PangoViewer *viewers[] = {
+ &pangoft2_viewer,
+ NULL
+};
diff --git a/examples/pangoft2topgm.c b/examples/pangoft2topgm.c
deleted file mode 100644
index d52cfd19..00000000
--- a/examples/pangoft2topgm.c
+++ /dev/null
@@ -1,199 +0,0 @@
-/* Pango
- * pangoft2topgm.c: Example program to view a UTF-8 encoding file
- * using PangoFT2 to render result.
- *
- * Copyright (C) 1999,2004,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 <config.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
-
-#include "renderdemo.h"
-
-#include <pango/pangoft2.h>
-
-static void
-do_render (PangoLayout *layout,
- int x,
- int y,
- gpointer data,
- gboolean show_borders)
-{
- pango_ft2_render_layout (data, layout, x, y);
-}
-
-int
-main(int argc, char *argv[])
-{
- PangoContext *context;
- FILE *outfile = NULL;
- PangoFontMap *fontmap;
- GError *error = NULL;
- gboolean do_convert = FALSE;
- int exit_status = 0;
- char *tmpfile_name;
- gboolean gen_output = TRUE;
-
- g_type_init();
-
- parse_options (argc, argv);
-
- if (opt_output && !*opt_output)
- gen_output = FALSE;
-
- if (gen_output)
- {
- if (opt_output)
- {
- if (!(g_str_has_suffix (opt_output, ".pgm") ||
- g_str_has_suffix (opt_output, ".PGM")))
- do_convert = TRUE;
- }
-
- if (opt_output && !do_convert)
- {
- outfile = fopen (opt_output, "wb");
-
- if (!outfile)
- fail ("Cannot open output file %s: %s\n",
- opt_output, g_strerror (errno));
- }
- else /* --display */
- {
- /* This may need to be G_OS_UNIX guarded for fdopen */
- int fd = g_file_open_tmp ("pangoft2pgmXXXXXX", &tmpfile_name, &error);
- if (fd == 1)
- fail ("Cannot open temporary file: %s\n", error->message);
- outfile = fdopen (fd, "wb");
- if (!outfile)
- fail ("Cannot open temporary file: %s\n", g_strerror (errno));
- }
- }
-
- fontmap = pango_ft2_font_map_new ();
-
- pango_ft2_font_map_set_resolution (PANGO_FT2_FONT_MAP (fontmap), opt_dpi, opt_dpi);
- pango_ft2_font_map_set_default_substitute (PANGO_FT2_FONT_MAP (fontmap), fc_substitute_func, NULL, NULL);
- context = pango_ft2_font_map_create_context (PANGO_FT2_FONT_MAP (fontmap));
-
- g_object_unref (fontmap);
-
- {
- FT_Bitmap bitmap;
- guchar *buf;
- int row;
- int width, height;
- int run;
-
- do_output (context, NULL, NULL, NULL, &width, &height, FALSE);
-
- bitmap.width = width;
- bitmap.pitch = (bitmap.width + 3) & ~3;
- bitmap.rows = height;
- buf = bitmap.buffer = g_malloc (bitmap.pitch * bitmap.rows);
- bitmap.num_grays = 256;
- bitmap.pixel_mode = ft_pixel_mode_grays;
- memset (buf, 0x00, bitmap.pitch * bitmap.rows);
-
- for (run = 0; run < opt_runs; run++)
- do_output (context, do_render, NULL, &bitmap, &width, &height, FALSE);
-
- if (gen_output)
- {
- /* Invert bitmap to get black text on white background */
- {
- int pix_idx;
- for (pix_idx=0; pix_idx<bitmap.pitch * bitmap.rows; pix_idx++)
- {
- buf[pix_idx] = 255-buf[pix_idx];
- }
- }
-
- /* Write it as pgm to output */
- fprintf(outfile,
- "P5\n"
- "%d %d\n"
- "255\n", bitmap.width, bitmap.rows);
- for (row = 0; row < bitmap.rows; row++)
- fwrite(bitmap.buffer + row * bitmap.pitch, 1, bitmap.width, outfile);
- g_free (buf);
- if (fclose(outfile) == EOF)
- fail ("Error writing output file: %s\n", g_strerror (errno));
-
- /* Convert to a different format, if necessary */
- if (do_convert)
- {
- gchar *command = g_strdup_printf ("convert %s %s",
- tmpfile_name,
- opt_output);
- if (!g_spawn_command_line_sync (command, NULL, NULL, &exit_status, &error))
- fail ("When running ImageMagick 'convert' command: %s\n",
- error->message);
-
- g_free (command);
-
- if (tmpfile_name)
- {
- remove (tmpfile_name);
- g_free (tmpfile_name);
- tmpfile_name = NULL;
- }
-
- if (exit_status)
- goto done;
- }
-
- if (opt_display)
- {
- gchar *title = get_options_string ();
- gchar *title_quoted = g_shell_quote (title);
-
- gchar *command = g_strdup_printf ("display -title %s %s",
- title_quoted,
- opt_output ? opt_output: tmpfile_name);
- if (!g_spawn_command_line_sync (command, NULL, NULL, &exit_status, &error))
- fail ("When running ImageMagick 'display' command: %s\n",
- error->message);
-
- g_free (command);
- g_free (title);
- g_free (title_quoted);
-
- if (tmpfile_name)
- {
- remove (tmpfile_name);
- g_free (tmpfile_name);
- tmpfile_name = NULL;
- }
-
- if (exit_status)
- goto done;
- }
- }
- }
-
-done:
- g_object_unref (context);
- finalize ();
-
- return exit_status ? 1 : 0;
-}
diff --git a/examples/pangox-view.c b/examples/pangox-view.c
new file mode 100644
index 00000000..72e97603
--- /dev/null
+++ b/examples/pangox-view.c
@@ -0,0 +1,8 @@
+#include "viewer.h"
+
+extern const PangoViewer pangox_viewer;
+
+const PangoViewer *viewers[] = {
+ &pangox_viewer,
+ NULL
+};
diff --git a/examples/pangoxft-view.c b/examples/pangoxft-view.c
new file mode 100644
index 00000000..bdf893f8
--- /dev/null
+++ b/examples/pangoxft-view.c
@@ -0,0 +1,8 @@
+#include "viewer.h"
+
+extern const PangoViewer pangoxft_viewer;
+
+const PangoViewer *viewers[] = {
+ &pangoxft_viewer,
+ NULL
+};
diff --git a/examples/renderdemo.c b/examples/renderdemo.c
index a0d3a5ea..85f0ddb7 100644
--- a/examples/renderdemo.c
+++ b/examples/renderdemo.c
@@ -26,6 +26,7 @@
#include <stdio.h>
#include <string.h>
+#include <glib.h>
#include <pango/pango.h>
#include "renderdemo.h"
@@ -58,6 +59,7 @@ HintMode opt_hinting = HINT_DEFAULT;
PangoWrapMode opt_wrap = PANGO_WRAP_WORD_CHAR;
gboolean opt_wrap_set = FALSE;
const char *opt_pangorc = NULL;
+const PangoViewer *opt_viewer = NULL;
/* Text (or markup) to render */
static char *text;
@@ -66,12 +68,12 @@ void
fail (const char *format, ...)
{
const char *msg;
-
+
va_list vap;
va_start (vap, format);
msg = g_strdup_vprintf (format, vap);
- g_warning ("%s: %s\n", prog_name, msg);
-
+ g_printerr ("%s: %s\n", prog_name, msg);
+
exit (1);
}
@@ -79,7 +81,7 @@ static PangoFontDescription *
get_font_description (void)
{
PangoFontDescription *font_description = pango_font_description_from_string (opt_font);
-
+
if ((pango_font_description_get_set_fields (font_description) & PANGO_FONT_MASK_FAMILY) == 0)
pango_font_description_set_family (font_description, DEFAULT_FONT_FAMILY);
@@ -110,7 +112,7 @@ make_layout(PangoContext *context,
font_description = get_font_description ();
if (size > 0)
pango_font_description_set_size (font_description, size * PANGO_SCALE);
-
+
if (opt_width > 0)
{
pango_layout_set_wrap (layout, opt_wrap);
@@ -123,7 +125,7 @@ make_layout(PangoContext *context,
base_dir = pango_context_get_base_dir (context);
pango_layout_set_alignment (layout,
base_dir == PANGO_DIRECTION_LTR ? PANGO_ALIGN_LEFT : PANGO_ALIGN_RIGHT);
-
+
pango_layout_set_font_description (layout, font_description);
pango_font_description_free (font_description);
@@ -142,7 +144,7 @@ get_options_string (void)
pango_font_description_unset_fields (font_description, PANGO_FONT_MASK_SIZE);
font_name = pango_font_description_to_string (font_description);
- result = g_strdup_printf ("%s: dpi=%d", font_name, opt_dpi);
+ result = g_strdup_printf ("%s: %s (%d dpi)", opt_viewer->name, font_name, opt_dpi);
pango_font_description_free (font_description);
g_free (font_name);
@@ -164,16 +166,15 @@ static void
output_body (PangoContext *context,
const char *text,
RenderCallback render_cb,
+ gpointer cb_context,
gpointer cb_data,
int *width,
- int *height,
- gboolean show_borders)
+ int *height)
{
PangoLayout *layout;
PangoRectangle logical_rect;
int size, start_size, end_size, increment;
- int dy;
-
+
if (opt_waterfall)
{
start_size = 8;
@@ -188,25 +189,17 @@ output_body (PangoContext *context,
*width = 0;
*height = 0;
- dy = 0;
-
+
for (size = start_size; size <= end_size; size += increment)
{
layout = make_layout (context, text, size);
pango_layout_get_extents (layout, NULL, &logical_rect);
-
- /* TODO: instead of these two calls, we really should call
- * pango_layout_get_effective_width when that's implemented.
- */
- *width = MAX (*width, PANGO_PIXELS (pango_layout_get_width (layout)));
- *width = MAX (*width, PANGO_PIXELS (logical_rect.width));
-
- *height += PANGO_PIXELS (logical_rect.height);
if (render_cb)
- (*render_cb) (layout, 0, dy, cb_data, show_borders);
-
- dy += PANGO_PIXELS (logical_rect.height);
+ (*render_cb) (layout, 0, *height, cb_context, cb_data);
+
+ *width = MAX (*width, PANGO_PIXELS (logical_rect.x + logical_rect.width));
+ *height += PANGO_PIXELS (logical_rect.height);
g_object_unref (layout);
}
@@ -215,11 +208,12 @@ output_body (PangoContext *context,
static void
set_transform (PangoContext *context,
TransformCallback transform_cb,
+ gpointer cb_context,
gpointer cb_data,
PangoMatrix *matrix)
{
if (transform_cb)
- (*transform_cb) (context, matrix, cb_data);
+ (*transform_cb) (context, matrix, cb_context, cb_data);
else
pango_context_set_matrix (context, matrix);
}
@@ -228,10 +222,10 @@ void
do_output (PangoContext *context,
RenderCallback render_cb,
TransformCallback transform_cb,
+ gpointer cb_context,
gpointer cb_data,
int *width_out,
- int *height_out,
- gboolean show_borders)
+ int *height_out)
{
PangoLayout *layout;
PangoRectangle logical_rect;
@@ -246,40 +240,40 @@ do_output (PangoContext *context,
double minx, miny;
double maxx, maxy;
int width, height;
-
+
width = 0;
height = 0;
- set_transform (context, transform_cb, cb_data, NULL);
-
+ set_transform (context, transform_cb, cb_context, 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);
-
+
if (opt_header)
{
char *options_string = get_options_string ();
layout = make_layout (context, options_string, 10);
pango_layout_get_extents (layout, NULL, &logical_rect);
-
+
width = MAX (width, PANGO_PIXELS (logical_rect.width));
height += PANGO_PIXELS (logical_rect.height);
-
+
if (render_cb)
- (*render_cb) (layout, x, y, cb_data, show_borders);
-
+ (*render_cb) (layout, x, y, cb_context, cb_data);
+
y += PANGO_PIXELS (logical_rect.height);
-
+
g_object_unref (layout);
g_free (options_string);
}
pango_matrix_rotate (&matrix, opt_rotate);
- set_transform (context, transform_cb, cb_data, &matrix);
-
- output_body (context, text, NULL, NULL, &rotated_width, &rotated_height, show_borders);
-
+ set_transform (context, transform_cb, cb_context, cb_data, &matrix);
+
+ output_body (context, text, NULL, NULL, NULL, &rotated_width, &rotated_height);
+
transform_point (&matrix, 0, 0, &p1x, &p1y);
transform_point (&matrix, rotated_width, 0, &p2x, &p2y);
transform_point (&matrix, rotated_width, rotated_height, &p3x, &p3y);
@@ -294,10 +288,10 @@ do_output (PangoContext *context,
matrix.x0 = x - minx;
matrix.y0 = y - miny;
- set_transform (context, transform_cb, cb_data, &matrix);
-
+ set_transform (context, transform_cb, cb_context, cb_data, &matrix);
+
if (render_cb)
- output_body (context, text, render_cb, cb_data, &rotated_width, &rotated_height, show_borders);
+ output_body (context, text, render_cb, cb_context, cb_data, &rotated_width, &rotated_height);
width = MAX (width, maxx - minx);
height += maxy - miny;
@@ -312,23 +306,6 @@ do_output (PangoContext *context,
}
-/* This function gets called to convert a matched pattern into what
- * we'll use to actually load the font. We turn off hinting since we
- * want metrics that are independent of scale.
- */
-void
-fc_substitute_func (FcPattern *pattern, gpointer data)
-{
- if (opt_hinting != HINT_DEFAULT)
- {
- FcPatternDel (pattern, FC_HINTING);
- FcPatternAddBool (pattern, FC_HINTING, opt_hinting != HINT_NONE);
-
- FcPatternDel (pattern, FC_AUTOHINT);
- FcPatternAddBool (pattern, FC_AUTOHINT, opt_hinting == HINT_AUTO);
- }
-}
-
static gboolean
parse_ellipsis (const char *name,
const char *arg,
@@ -341,7 +318,7 @@ parse_ellipsis (const char *name,
if (!class)
class = g_type_class_ref (PANGO_TYPE_ELLIPSIZE_MODE);
-
+
value = g_enum_get_value_by_nick (class, arg);
if (value)
opt_ellipsize = value->value;
@@ -362,7 +339,7 @@ parse_hinting (const char *name,
{
static GEnumClass *class = NULL;
gboolean ret = TRUE;
-
+
if (!class)
class = g_type_class_ref (PANGO_TYPE_ELLIPSIZE_MODE);
@@ -381,7 +358,6 @@ parse_hinting (const char *name,
return ret;
}
-
static gboolean
parse_wrap (const char *name,
const char *arg,
@@ -391,7 +367,7 @@ parse_wrap (const char *name,
static GEnumClass *class = NULL;
gboolean ret = TRUE;
GEnumValue *value;
-
+
if (!class)
class = g_type_class_ref (PANGO_TYPE_WRAP_MODE);
@@ -410,48 +386,84 @@ parse_wrap (const char *name,
return ret;
}
+static gboolean
+parse_backend (const char *name,
+ const char *arg,
+ gpointer data,
+ GError **error)
+{
+ gboolean ret = TRUE;
+ const PangoViewer **viewer;
+
+ for (viewer = viewers; *viewer; viewer++)
+ if (!g_ascii_strcasecmp ((*viewer)->id, arg))
+ break;
+
+ if (*viewer)
+ opt_viewer = *viewer;
+ else
+ {
+ GString *backends = g_string_new (NULL);
+
+ for (viewer = viewers; *viewer; viewer++)
+ if ((*viewer)->id)
+ {
+ g_string_append (backends, (*viewer)->id);
+ g_string_append_c (backends, '/');
+ }
+ g_string_truncate (backends, MAX (0, (gint)backends->len - 1));
+
+ fail ("available --backend options are: %s", g_string_free (backends, FALSE));
+ ret = FALSE;
+ }
+
+ return ret;
+}
+
void
parse_options (int argc, char *argv[])
{
- GOptionEntry entries[] =
+ GOptionEntry entries[] =
{
{"no-auto-dir", 0, G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_auto_dir,
"No layout direction according to contents", NULL},
+ {"backend", 0, 0, G_OPTION_ARG_CALLBACK, &parse_backend,
+ "Pango backend to use for rendering", "id"},
{"no-display", 'q', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt_display,
"Do not display (just save to file or whatever)", NULL},
{"dpi", 0, 0, G_OPTION_ARG_INT, &opt_dpi,
- "Set the resolution", NULL},
+ "Set the resolution", "number"},
{"ellipsize", 0, 0, G_OPTION_ARG_CALLBACK, &parse_ellipsis,
- "Ellipsization mode", "start/middle/end" },
+ "Ellipsization mode", "start/middle/end"},
{"font", 0, 0, G_OPTION_ARG_STRING, &opt_font,
- "Set the font description", NULL},
+ "Set the font description", "description"},
{"header", 0, 0, G_OPTION_ARG_NONE, &opt_header,
"Display the options in the output", NULL},
{"hinting", 0, 0, G_OPTION_ARG_CALLBACK, &parse_hinting,
- "Hinting style", "none/auto/full" },
+ "Hinting style", "none/auto/full"},
{"indent", 0, 0, G_OPTION_ARG_INT, &opt_indent,
- "Width in points to indent paragraphs", NULL},
+ "Width in points to indent paragraphs", "points"},
{"margin", 0, 0, G_OPTION_ARG_INT, &opt_margin,
- "Set the margin on the output in pixels", NULL},
+ "Set the margin on the output in pixels", "pixels"},
{"markup", 0, 0, G_OPTION_ARG_NONE, &opt_markup,
"Interpret text as Pango markup", NULL},
- {"output", 'o', 0,G_OPTION_ARG_STRING, &opt_output,
- "Save rendered image to output file", NULL},
+ {"output", 'o', 0, G_OPTION_ARG_STRING, &opt_output,
+ "Save rendered image to output file", "file"},
{"pangorc", 0, 0, G_OPTION_ARG_STRING, &opt_pangorc,
- "pangorc file to use (default is ./pangorc)", NULL},
+ "pangorc file to use (default is ./pangorc)", "file"},
{"rtl", 0, 0, G_OPTION_ARG_NONE, &opt_rtl,
"Set base direction to right-to-left", NULL},
{"rotate", 0, 0, G_OPTION_ARG_INT, &opt_rotate,
- "Angle at which to rotate results", NULL},
+ "Angle at which to rotate results", "degrees"},
{"runs", 'n', 0, G_OPTION_ARG_INT, &opt_runs,
- "Run Pango layout engine this many times", NULL},
+ "Run Pango layout engine this many times", "integer"},
{"text", 't', 0, G_OPTION_ARG_STRING, &opt_text,
- "Text to display (instead of a file)", NULL},
+ "Text to display (instead of a file)", "string"},
{"waterfall", 0, 0, G_OPTION_ARG_NONE, &opt_waterfall,
"Create a waterfall display", NULL},
{"width", 'w', 0, G_OPTION_ARG_INT, &opt_width,
- "Width in points to which to wrap output", NULL},
+ "Width in points to which to wrap output", "points"},
{"wrap", 0, 0, G_OPTION_ARG_CALLBACK, &parse_wrap,
"Text wrapping mode (needs a width to be set), ", "word/char/word-char"},
{NULL}
@@ -488,6 +500,14 @@ parse_options (int argc, char *argv[])
exit (1);
}
+ /* set up the backend */
+ if (!opt_viewer)
+ {
+ opt_viewer = *viewers;
+ if (!opt_viewer)
+ fail ("No viewer backend found");
+ }
+
/* if wrap mode is set then width must be set */
if (opt_width < 0 && opt_wrap_set)
{
@@ -508,7 +528,7 @@ parse_options (int argc, char *argv[])
if (!g_utf8_validate (text, len, NULL))
fail ("Text is not valid UTF-8");
}
-
+
/* Strip trailing whitespace
*/
p = text + len;
diff --git a/examples/renderdemo.h b/examples/renderdemo.h
index f18636a2..c7d0b49f 100644
--- a/examples/renderdemo.h
+++ b/examples/renderdemo.h
@@ -18,9 +18,12 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
+#ifndef RENDERDEMO_H
+#define RENDERDEMO_H
#include <pango/pango-layout.h>
-#include <pango/pangofc-fontmap.h>
+
+#include "viewer.h"
typedef enum {
HINT_DEFAULT,
@@ -32,11 +35,12 @@ typedef enum {
typedef void (*RenderCallback) (PangoLayout *layout,
int x,
int y,
- gpointer data,
- gboolean show_borders);
+ gpointer cb_context,
+ gpointer cb_data);
typedef void (*TransformCallback) (PangoContext *context,
PangoMatrix *transform,
- gpointer data);
+ gpointer cb_context,
+ gpointer cb_data);
void fail (const char *format, ...) G_GNUC_PRINTF (1, 2) G_GNUC_NORETURN;
@@ -45,22 +49,18 @@ void parse_options (int argc,
void do_output (PangoContext *context,
RenderCallback render_cb,
TransformCallback transform_cb,
+ gpointer cb_context,
gpointer cb_data,
int *width,
- int *height,
- gboolean show_borders);
+ int *height);
void finalize (void);
-void fc_substitute_func (FcPattern *pattern,
- gpointer data);
gchar *get_options_string (void);
extern const char *prog_name;
-extern gboolean opt_display;
-extern int opt_dpi;
+/* handled by renderdemo.c */
extern const char *opt_font;
extern gboolean opt_header;
-extern const char *opt_output;
extern int opt_margin;
extern int opt_markup;
extern gboolean opt_rtl;
@@ -70,7 +70,17 @@ extern const char *opt_text;
extern gboolean opt_waterfall;
extern int opt_width;
extern int opt_indent;
-extern int opt_runs;
extern PangoEllipsizeMode opt_ellipsize;
-extern HintMode opt_hinting;
extern const char *opt_pangorc;
+
+/* handled by view.c */
+extern gboolean opt_display;
+extern const char *opt_output;
+extern int opt_runs;
+extern const PangoViewer *opt_viewer;
+
+/* handled by backend-specific code */
+extern int opt_dpi;
+extern HintMode opt_hinting;
+
+#endif /* RENDERDEMO_H */
diff --git a/examples/viewer-cairo.c b/examples/viewer-cairo.c
new file mode 100644
index 00000000..5743a22e
--- /dev/null
+++ b/examples/viewer-cairo.c
@@ -0,0 +1,53 @@
+/* viewer-cairo.c: Common code for Cairo-based viewers
+ *
+ * Copyright (C) 1999,2004,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 <config.h>
+
+#include "viewer-cairo.h"
+
+#ifdef HAVE_CAIRO_XLIB
+#include "viewer-x.h"
+#include <cairo-xlib.h>
+
+static cairo_surface_t *
+x_cairo_view_create_surface (gpointer instance,
+ gpointer surface,
+ int width,
+ int height)
+{
+ XViewer *x = (XViewer *)instance;
+ Drawable drawable = (Drawable) surface;
+
+ return cairo_xlib_surface_create (x->display, drawable,
+ DefaultVisual (x->display, x->screen),
+ width, height);
+}
+
+static CairoViewerIface x_cairo_viewer_iface = {
+ &x_viewer,
+ x_cairo_view_create_surface
+};
+
+const CairoViewerIface *
+get_default_cairo_viewer_iface (void)
+{
+ return &x_cairo_viewer_iface;
+}
+#endif /* HAVE_CAIRO_XLIB */
diff --git a/examples/viewer-cairo.h b/examples/viewer-cairo.h
new file mode 100644
index 00000000..6e2adb84
--- /dev/null
+++ b/examples/viewer-cairo.h
@@ -0,0 +1,42 @@
+/* viewer-cairo.h: Common headers for Cairo-based viewers
+ *
+ * Copyright (C) 1999,2004,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.
+ */
+#ifndef VIEWER_CAIRO_H
+#define VIEWER_CAIRO_H
+
+#include <cairo.h>
+
+#include "viewer.h"
+
+typedef struct _CairoViewerIface CairoViewerIface;
+
+struct _CairoViewerIface
+{
+ const PangoViewer *backend_class;
+
+ cairo_surface_t * (*create_surface) (gpointer instance,
+ gpointer surface,
+ int width,
+ int height);
+};
+
+const CairoViewerIface *get_default_cairo_viewer_iface (void);
+
+#endif /* VIEWER_CAIRO_H */
diff --git a/examples/viewer-main.c b/examples/viewer-main.c
new file mode 100644
index 00000000..377b625a
--- /dev/null
+++ b/examples/viewer-main.c
@@ -0,0 +1,155 @@
+/* viewer-main.c: Main routine for viewers
+ *
+ * Copyright (C) 1999,2004,2005 Red Hat, Inc.
+ * Copyright (C) 2001 Sun Microsystems
+ * Copyright (C) 2006 Behdad Esfahbod
+ *
+ * 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 <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/wait.h>
+
+#include <glib.h>
+#include <glib/gstdio.h>
+
+#include "viewer.h"
+#include "renderdemo.h"
+
+int
+main (int argc,
+ char **argv)
+{
+ const PangoViewer *view;
+ gpointer instance;
+ PangoContext *context;
+ int run;
+ int width, height;
+ gpointer surface;
+
+ g_type_init();
+ parse_options (argc, argv);
+
+ view = opt_viewer;
+
+ g_assert (view->id);
+
+ instance = view->create (view);
+ context = view->get_context (instance);
+ do_output (context, NULL, NULL, NULL, NULL, &width, &height);
+ surface = view->create_surface (instance, width, height);
+ for (run = 0; run < MAX(1,opt_runs); run++)
+ view->render (instance, surface, context, width, height, NULL);
+
+ if (opt_output)
+ {
+ if (!view->save)
+ fail ("%s viewer backend does not support saving", view->name);
+ else
+ {
+ FILE *stream;
+
+ if (view->save_suffix && g_str_has_suffix (opt_output, view->save_suffix))
+ {
+ stream = g_fopen (opt_output, "wb");
+ if (!stream)
+ fail ("Cannot open output file %s: %s\n",
+ opt_output, g_strerror (errno));
+ }
+ else
+ {
+ int fd;
+ const gchar *convert_argv[4] = {"convert", "-", "%s"};
+ GError *error;
+
+ convert_argv[2] = opt_output;
+
+ if (!g_spawn_async_with_pipes (NULL, (gchar **)convert_argv, NULL,
+ G_SPAWN_SEARCH_PATH |
+ G_SPAWN_STDOUT_TO_DEV_NULL |
+ G_SPAWN_STDERR_TO_DEV_NULL,
+ NULL, NULL, NULL, &fd, NULL, NULL, &error))
+ fail ("When running ImageMagick 'convert' command: %s\n", error->message);
+ stream = fdopen (fd, "wb");
+ }
+ view->save (instance, surface, stream, width, height);
+ fclose (stream);
+ }
+ }
+
+ if (opt_display)
+ {
+ char *title;
+ title = get_options_string ();
+
+ if (view->display)
+ {
+ gpointer window = NULL;
+ gpointer state = NULL;
+
+ if (view->create_window)
+ window = view->create_window (instance, title, width, height);
+
+ while (1)
+ {
+ state = view->display (instance, surface, window, width, height, state);
+ if (!state)
+ break;
+
+ view->render (instance, surface, context, width, height, state);
+ }
+
+ if (view->destroy_window)
+ view->destroy_window (instance, window);
+ }
+ else
+ {
+ int fd;
+ FILE *stream;
+ const gchar *display_argv[5] = {"display", "-title", "%s", "-"};
+ GError *error;
+ GPid pid;
+
+ if (!view->save)
+ fail ("%s viewer backend does not support displaying or saving", view->name);
+ display_argv[2] = title;
+
+ if (!g_spawn_async_with_pipes (NULL, (gchar **)display_argv, NULL,
+ G_SPAWN_DO_NOT_REAP_CHILD |
+ G_SPAWN_SEARCH_PATH |
+ G_SPAWN_STDOUT_TO_DEV_NULL |
+ G_SPAWN_STDERR_TO_DEV_NULL,
+ NULL, NULL, &pid, &fd, NULL, NULL, &error))
+ fail ("When running ImageMagick 'display' command: %s\n", error->message);
+ stream = fdopen (fd, "wb");
+ view->save (instance, surface, stream, width, height);
+ fclose (stream);
+ waitpid (pid, NULL, 0);
+ g_spawn_close_pid (pid);
+ }
+
+ g_free (title);
+ }
+
+ view->destroy_surface (instance, surface);
+ g_object_unref (context);
+ view->destroy (instance);
+ finalize ();
+ return 0;
+}
diff --git a/examples/viewer-pangocairo.c b/examples/viewer-pangocairo.c
new file mode 100644
index 00000000..e1472aa7
--- /dev/null
+++ b/examples/viewer-pangocairo.c
@@ -0,0 +1,326 @@
+/* viewer-pangocairo.c: PangoCairo viewer backend.
+ *
+ * Copyright (C) 1999,2004,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 <config.h>
+
+#include "renderdemo.h"
+#include "viewer-cairo.h"
+
+#include <pango/pangocairo.h>
+
+typedef struct
+{
+ const CairoViewerIface *iface;
+
+ gpointer backend;
+
+ PangoFontMap *fontmap;
+ cairo_font_options_t *font_options;
+} CairoViewer;
+
+/* TODO: hinting */
+static gpointer
+pangocairo_view_create (const PangoViewer *klass)
+{
+ CairoViewer *instance;
+
+ instance = g_slice_new (CairoViewer);
+
+ instance->iface = get_default_cairo_viewer_iface ();
+ instance->backend = instance->iface->backend_class->create (instance->iface->backend_class);
+
+ instance->fontmap = pango_cairo_font_map_get_default ();
+ pango_cairo_font_map_set_resolution (PANGO_CAIRO_FONT_MAP (instance->fontmap), opt_dpi);
+
+ instance->font_options = cairo_font_options_create ();
+ if (opt_hinting != HINT_DEFAULT)
+ {
+ cairo_font_options_set_hint_metrics (instance->font_options, CAIRO_HINT_METRICS_ON);
+
+ if (opt_hinting == HINT_NONE)
+ cairo_font_options_set_hint_style (instance->font_options, CAIRO_HINT_STYLE_NONE);
+ else if (opt_hinting == HINT_FULL)
+ cairo_font_options_set_hint_style (instance->font_options, CAIRO_HINT_STYLE_FULL);
+ }
+
+ return instance;
+}
+
+static void
+pangocairo_view_destroy (gpointer instance)
+{
+ CairoViewer *c = (CairoViewer *) instance;
+
+ cairo_font_options_destroy (c->font_options);
+
+ g_object_unref (c->fontmap);
+
+ c->iface->backend_class->destroy (c->backend);
+
+ g_slice_free (CairoViewer, c);
+}
+
+static PangoContext *
+pangocairo_view_get_context (gpointer instance)
+{
+ CairoViewer *c = (CairoViewer *) instance;
+ PangoContext *context;
+
+ context = pango_cairo_font_map_create_context (PANGO_CAIRO_FONT_MAP (c->fontmap));
+ pango_cairo_context_set_font_options (context, c->font_options);
+
+ return context;
+}
+
+typedef struct
+{
+ gpointer backend;
+
+ cairo_surface_t *cairo;
+} CairoSurface;
+
+static gpointer
+pangocairo_view_create_surface (gpointer instance,
+ int width,
+ int height)
+{
+ CairoViewer *c = (CairoViewer *) instance;
+ CairoSurface *surface;
+
+ surface = g_slice_new (CairoSurface);
+
+ surface->backend = c->iface->backend_class->create_surface (c->backend,
+ width, height);
+
+ surface->cairo = c->iface->create_surface (c->backend,
+ surface->backend,
+ width, height);
+
+ return surface;
+}
+
+static void
+pangocairo_view_destroy_surface (gpointer instance,
+ gpointer surface)
+{
+ CairoViewer *c = (CairoViewer *) instance;
+ CairoSurface *c_surface = (CairoSurface *) surface;
+
+ c->iface->backend_class->destroy_surface (c->backend, c_surface->backend);
+ cairo_surface_destroy (c_surface->cairo);
+
+ g_slice_free (CairoSurface, surface);
+}
+
+static void
+render_callback (PangoLayout *layout,
+ int x,
+ int y,
+ gpointer context,
+ gpointer data)
+{
+ cairo_t *cr = (cairo_t *) context;
+ gboolean show_borders = GPOINTER_TO_UINT (data) == 0xdeadbeef;
+
+ cairo_move_to (cr, x, y);
+ pango_cairo_show_layout (cr,
+ layout);
+
+ if (show_borders)
+ {
+ PangoRectangle ink, logical;
+ double lw = cairo_get_line_width (cr);
+
+ pango_layout_get_extents (layout, &ink, &logical);
+
+ cairo_save (cr);
+ cairo_set_source_rgba (cr, 1.0, 0.0, 0.0, 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_source_rgba (cr, 0.0, 1.0, 0.0, 0.75);
+
+ 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
+transform_callback (PangoContext *context,
+ PangoMatrix *matrix,
+ gpointer cr_context,
+ gpointer state)
+{
+ cairo_t *cr = (cairo_t *)cr_context;
+ cairo_matrix_t cairo_matrix;
+
+ if (matrix)
+ {
+ cairo_matrix.xx = matrix->xx;
+ cairo_matrix.yx = matrix->yx;
+ cairo_matrix.xy = matrix->xy;
+ cairo_matrix.yy = matrix->yy;
+ cairo_matrix.x0 = matrix->x0;
+ cairo_matrix.y0 = matrix->y0;
+ }
+ else
+ {
+ cairo_matrix_init_identity (&cairo_matrix);
+ }
+
+ cairo_set_matrix (cr, &cairo_matrix);
+
+ pango_context_set_matrix (context, matrix);
+ pango_cairo_update_context (cr, context);
+}
+
+static void
+pangocairo_view_render (gpointer instance,
+ gpointer surface,
+ PangoContext *context,
+ int width,
+ int height,
+ gpointer state)
+{
+ cairo_t *cr;
+ CairoSurface *c_surface = (CairoSurface *) surface;
+
+ if (!surface)
+ {
+ cairo_surface_t *cs;
+ /* This is annoying ... we have to create a temporary surface just to
+ * get the extents of the text.
+ */
+ cs = cairo_image_surface_create (CAIRO_FORMAT_RGB24, 1, 1);
+ cr = cairo_create (cs);
+ cairo_surface_destroy (cs);
+ }
+ else
+ cr = cairo_create (c_surface->cairo);
+
+ transform_callback (context, NULL, cr, state);
+
+ cairo_set_source_rgb (cr, 1.0, 1.0, 1.0);
+ cairo_paint (cr);
+
+ cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
+ do_output (context, render_callback, transform_callback, cr, state, NULL, NULL);
+
+ cairo_destroy (cr);
+}
+
+#ifdef HAVE_CAIRO_PNG
+static cairo_status_t
+write_func (void *closure,
+ const unsigned char *data,
+ unsigned int length)
+{
+ FILE *stream = (FILE *) closure;
+ unsigned int l;
+
+ l = fwrite (data, 1, length, stream);
+
+ return l == length ? CAIRO_STATUS_SUCCESS : CAIRO_STATUS_WRITE_ERROR;
+}
+
+static void
+pangocairo_view_save (gpointer instance,
+ gpointer surface,
+ FILE *stream,
+ int width,
+ int height)
+{
+ CairoSurface *c_surface = (CairoSurface *) surface;
+
+ cairo_surface_write_to_png_stream (c_surface->cairo, write_func, stream);
+}
+#endif
+
+static gpointer
+pangocairo_view_create_window (gpointer instance,
+ const char *title,
+ int width,
+ int height)
+{
+ CairoViewer *c = (CairoViewer *) instance;
+
+ return c->iface->backend_class->create_window (c->backend,
+ title,
+ width, height);
+}
+
+static void
+pangocairo_view_destroy_window (gpointer instance,
+ gpointer window)
+{
+ CairoViewer *c = (CairoViewer *) instance;
+
+ c->iface->backend_class->destroy_window (c->backend,
+ window);
+}
+
+static gpointer
+pangocairo_view_display (gpointer instance,
+ gpointer surface,
+ gpointer window,
+ int width, int height,
+ gpointer state)
+{
+ CairoViewer *c = (CairoViewer *) instance;
+ CairoSurface *c_surface = (CairoSurface *) surface;
+
+ return c->iface->backend_class->display (c->backend,
+ c_surface->backend,
+ window,
+ width, height,
+ state);
+}
+
+const PangoViewer pangocairo_viewer = {
+ "PangoCairo",
+ "cairo",
+ NULL,
+ pangocairo_view_create,
+ pangocairo_view_destroy,
+ pangocairo_view_get_context,
+ pangocairo_view_create_surface,
+ pangocairo_view_destroy_surface,
+ pangocairo_view_render,
+#ifdef HAVE_CAIRO_PNG
+ pangocairo_view_save,
+#else
+ NULL,
+#endif
+ pangocairo_view_create_window,
+ pangocairo_view_destroy_window,
+ pangocairo_view_display
+};
diff --git a/examples/viewer-pangoft2.c b/examples/viewer-pangoft2.c
new file mode 100644
index 00000000..372ccb30
--- /dev/null
+++ b/examples/viewer-pangoft2.c
@@ -0,0 +1,162 @@
+/* viewer-pangoft2.c: PangoFT2 viewer backend.
+ *
+ * Copyright (C) 1999,2004,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 <config.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "renderdemo.h"
+#include "viewer.h"
+
+#include <pango/pangoft2.h>
+
+static void
+substitute_func (FcPattern *pattern,
+ gpointer data)
+{
+ if (opt_hinting != HINT_DEFAULT)
+ {
+ FcPatternDel (pattern, FC_HINTING);
+ FcPatternAddBool (pattern, FC_HINTING, opt_hinting != HINT_NONE);
+
+ FcPatternDel (pattern, FC_AUTOHINT);
+ FcPatternAddBool (pattern, FC_AUTOHINT, opt_hinting == HINT_AUTO);
+ }
+}
+
+static gpointer
+pangoft2_view_create (const PangoViewer *klass)
+{
+ PangoFontMap *fontmap;
+ fontmap = pango_ft2_font_map_new ();
+
+ pango_ft2_font_map_set_resolution (PANGO_FT2_FONT_MAP (fontmap), opt_dpi, opt_dpi);
+ pango_ft2_font_map_set_default_substitute (PANGO_FT2_FONT_MAP (fontmap), substitute_func, NULL, NULL);
+
+ return fontmap;
+}
+
+static void
+pangoft2_view_destroy (gpointer instance)
+{
+ g_object_unref (instance);
+}
+
+static PangoContext *
+pangoft2_view_get_context (gpointer instance)
+{
+ return pango_ft2_font_map_create_context (PANGO_FT2_FONT_MAP (instance));
+}
+
+static gpointer
+pangoft2_view_create_surface (gpointer instance,
+ int width,
+ int height)
+{
+ FT_Bitmap *bitmap;
+
+ bitmap = g_slice_new (FT_Bitmap);
+ bitmap->width = width;
+ bitmap->pitch = (bitmap->width + 3) & ~3;
+ bitmap->rows = height;
+ bitmap->buffer = g_malloc (bitmap->pitch * bitmap->rows);
+ bitmap->num_grays = 256;
+ bitmap->pixel_mode = ft_pixel_mode_grays;
+ memset (bitmap->buffer, 0x00, bitmap->pitch * bitmap->rows);
+
+ return bitmap;
+}
+
+static void
+pangoft2_view_destroy_surface (gpointer instance,
+ gpointer surface)
+{
+ FT_Bitmap *bitmap = (FT_Bitmap *) surface;
+
+ g_free (bitmap->buffer);
+ g_slice_free (FT_Bitmap, bitmap);
+}
+
+static void
+render_callback (PangoLayout *layout,
+ int x,
+ int y,
+ gpointer context,
+ gpointer state)
+{
+ pango_ft2_render_layout ((FT_Bitmap *)context,
+ layout,
+ x, y);
+}
+
+static void
+pangoft2_view_render (gpointer instance,
+ gpointer surface,
+ PangoContext *context,
+ int width,
+ int height,
+ gpointer state)
+{
+ int pix_idx;
+ FT_Bitmap *bitmap = (FT_Bitmap *) surface;
+
+ do_output (context, render_callback, NULL, surface, state, NULL, NULL);
+
+ for (pix_idx=0; pix_idx<bitmap->pitch * bitmap->rows; pix_idx++)
+ bitmap->buffer[pix_idx] = 255 - bitmap->buffer[pix_idx];
+}
+
+static void
+pangoft2_view_save (gpointer instance,
+ gpointer surface,
+ FILE *stream,
+ int width,
+ int height)
+{
+ int row;
+ FT_Bitmap *bitmap = (FT_Bitmap *) surface;
+
+ /* Write it as pgm to output */
+ fprintf(stream,
+ "P5\n"
+ "%d %d\n"
+ "255\n", width, height);
+ for (row = 0; row < height; row++)
+ fwrite(bitmap->buffer + row * bitmap->pitch, 1, width, stream);
+}
+
+const PangoViewer pangoft2_viewer = {
+ "PangoFT2",
+ "ft2",
+ ".pgm",
+ pangoft2_view_create,
+ pangoft2_view_destroy,
+ pangoft2_view_get_context,
+ pangoft2_view_create_surface,
+ pangoft2_view_destroy_surface,
+ pangoft2_view_render,
+ pangoft2_view_save,
+ NULL,
+ NULL,
+ NULL
+};
diff --git a/examples/viewer-pangox.c b/examples/viewer-pangox.c
new file mode 100644
index 00000000..c4d499af
--- /dev/null
+++ b/examples/viewer-pangox.c
@@ -0,0 +1,113 @@
+/* viewer-pangox.c: PangoX viewer backend.
+ *
+ * Copyright (C) 1999,2004,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 <config.h>
+
+#include "renderdemo.h"
+#include "viewer-x.h"
+
+#include <pango/pangox.h>
+
+static void
+pangox_view_destroy (gpointer instance)
+{
+ XViewer *x = (XViewer *)instance;
+
+ pango_x_shutdown_display (x->display);
+
+ x_view_destroy (instance);
+}
+
+static PangoContext *
+pangox_view_get_context (gpointer instance)
+{
+ XViewer *x = (XViewer *) instance;
+
+ return pango_x_get_context (x->display);
+}
+
+typedef struct
+{
+ XViewer *x;
+ Drawable drawable;
+ GC gc;
+} MyXContext;
+
+static void
+render_callback (PangoLayout *layout,
+ int x,
+ int y,
+ gpointer context,
+ gpointer state)
+{
+ MyXContext *x_context = (MyXContext *) context;
+
+ pango_x_render_layout (x_context->x->display,
+ x_context->drawable,
+ x_context->gc,
+ layout,
+ x, y);
+}
+
+static void
+pangox_view_render (gpointer instance,
+ gpointer surface,
+ PangoContext *context,
+ int width,
+ int height,
+ gpointer state)
+{
+ XViewer *x = (XViewer *) instance;
+ Pixmap pixmap = (Pixmap) surface;
+ GC gc;
+ MyXContext x_context;
+
+ gc = XCreateGC (x->display, pixmap, 0, NULL);
+
+ XSetForeground(x->display, gc, WhitePixel(x->display, x->screen));
+ XFillRectangle (x->display, pixmap, gc, 0, 0, width, height);
+
+ x_context.x = x;
+ x_context.drawable = pixmap;
+ x_context.gc = gc;
+
+ XSetForeground(x->display, gc, BlackPixel(x->display, x->screen));
+ do_output (context, render_callback, NULL, &x_context, state, NULL, NULL);
+
+ XFlush(x->display);
+
+ XFreeGC (x->display, gc);
+}
+
+const PangoViewer pangox_viewer = {
+ "PangoX",
+ "x",
+ NULL,
+ x_view_create,
+ pangox_view_destroy,
+ pangox_view_get_context,
+ x_view_create_surface,
+ x_view_destroy_surface,
+ pangox_view_render,
+ NULL,
+ x_view_create_window,
+ x_view_destroy_window,
+ x_view_display
+};
diff --git a/examples/viewer-pangoxft.c b/examples/viewer-pangoxft.c
new file mode 100644
index 00000000..497c17af
--- /dev/null
+++ b/examples/viewer-pangoxft.c
@@ -0,0 +1,151 @@
+/* viewer-pangoxft.c: PangoXft viewer backend.
+ *
+ * Copyright (C) 1999,2004,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 <config.h>
+
+#include "renderdemo.h"
+#include "viewer-x.h"
+
+#include <pango/pangoxft.h>
+
+static void
+default_substitute (FcPattern *pattern,
+ gpointer data)
+{
+ FcPatternDel (pattern, FC_DPI);
+ FcPatternAddInteger (pattern, FC_DPI, opt_dpi);
+
+ if (opt_hinting != HINT_DEFAULT)
+ {
+ FcPatternDel (pattern, FC_HINTING);
+ FcPatternAddBool (pattern, FC_HINTING, opt_hinting != HINT_NONE);
+
+ FcPatternDel (pattern, FC_AUTOHINT);
+ FcPatternAddBool (pattern, FC_AUTOHINT, opt_hinting == HINT_AUTO);
+ }
+}
+
+static gpointer
+pangoxft_view_create (const PangoViewer *klass)
+{
+ XViewer *instance;
+
+ instance = x_view_create (klass);
+
+ XftInit (NULL);
+
+ pango_xft_set_default_substitute (instance->display, instance->screen,
+ default_substitute, NULL, NULL);
+
+ return instance;
+}
+
+static void
+pangoxft_view_destroy (gpointer instance)
+{
+ XViewer *x = (XViewer *)instance;
+
+ pango_xft_shutdown_display (x->display, x->screen);
+
+ x_view_destroy (instance);
+}
+
+static PangoContext *
+pangoxft_view_get_context (gpointer instance)
+{
+ XViewer *x = (XViewer *) instance;
+
+ return pango_xft_get_context (x->display, x->screen);
+}
+
+typedef struct
+{
+ XftDraw *draw;
+ XftColor color;
+} MyXftContext;
+
+static void
+render_callback (PangoLayout *layout,
+ int x,
+ int y,
+ gpointer context,
+ gpointer state)
+{
+ MyXftContext *xft_context = (MyXftContext *) context;
+
+ pango_xft_render_layout (xft_context->draw,
+ &xft_context->color,
+ layout,
+ x, y);
+}
+
+static void
+pangoxft_view_render (gpointer instance,
+ gpointer surface,
+ PangoContext *context,
+ int width,
+ int height,
+ gpointer state)
+{
+ XViewer *x = (XViewer *) instance;
+ Pixmap pixmap = (Pixmap) surface;
+ MyXftContext xft_context;
+ XftDraw *draw;
+ XftColor color;
+
+ draw = XftDrawCreate (x->display, pixmap,
+ DefaultVisual (x->display, x->screen),
+ DefaultColormap (x->display, x->screen));
+
+ color.color.red = 0xffff;
+ color.color.blue = 0xffff;
+ color.color.green = 0xffff;
+ color.color.alpha = 0xffff;
+
+ XftDrawRect (draw, &color, 0, 0, width, height);
+
+ color.color.red = 0x0;
+ color.color.green = 0x0;
+ color.color.blue = 0x0;
+ color.color.alpha = 0xffff;
+
+ xft_context.draw = draw;
+ xft_context.color = color;
+
+ do_output (context, render_callback, NULL, &xft_context, state, NULL, NULL);
+
+ XftDrawDestroy (draw);
+}
+
+const PangoViewer pangoxft_viewer = {
+ "PangoXft",
+ "xft",
+ NULL,
+ pangoxft_view_create,
+ pangoxft_view_destroy,
+ pangoxft_view_get_context,
+ x_view_create_surface,
+ x_view_destroy_surface,
+ pangoxft_view_render,
+ NULL,
+ x_view_create_window,
+ x_view_destroy_window,
+ x_view_display
+};
diff --git a/examples/viewer-qt.cc b/examples/viewer-qt.cc
deleted file mode 100644
index 1ec8262f..00000000
--- a/examples/viewer-qt.cc
+++ /dev/null
@@ -1,528 +0,0 @@
-/* Pango
- * viewer-qt.cc: Example program to view a UTF-8 encoding file
- * using Pango to render result.
- *
- * Copyright (C) 1999-2000 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 <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <qapplication.h>
-#include <qcombobox.h>
-#include <qfile.h>
-#include <qfileinfo.h>
-#include <qmenubar.h>
-#include <qpainter.h>
-#include <qpopupmenu.h>
-#include <qspinbox.h>
-#include <qscrollview.h>
-#include <qstatusbar.h>
-#include <qtextcodec.h>
-#include <qtextstream.h>
-#include <qtoolbar.h>
-
-#include <pango/pango.h>
-#include <pango/pangox.h>
-
-#include "viewer-qt.h"
-
-ViewerPara::ViewerPara (PangoContext *context, const QString &text)
-{
- text_ = text.utf8();
-
- layout_ = pango_layout_new (context);
- pango_layout_set_text (layout_, (char *)(const char *)text_, text_.length());
- height_ = -1;
-}
-
-ViewerPara::~ViewerPara ()
-{
- g_object_unref (G_OBJECT (layout_));
-}
-
-void
-ViewerPara::setWidth (int width)
-{
- pango_layout_set_width (layout_, width * PANGO_SCALE);
- height_ = -1;
-}
-
-void
-ViewerPara::contextChanged ()
-{
- pango_layout_context_changed (layout_);
- height_ = -1;
-
- PangoContext *context;
- PangoAlignment align;
-
- context = pango_layout_get_context (layout_);
- if (pango_context_get_base_dir (context) == PANGO_DIRECTION_LTR)
- align = PANGO_ALIGN_LEFT;
- else
- align = PANGO_ALIGN_RIGHT;
-
- pango_layout_set_alignment (layout_, align);
-}
-
-int
-ViewerPara::height ()
-{
- if (height_ < 0)
- {
- PangoRectangle logical_rect;
-
- pango_layout_get_extents (layout_, NULL, &logical_rect);
- height_ = logical_rect.height / PANGO_SCALE;
- }
-
- return height_;
-}
-
-void
-ViewerPara::draw (QPainter *painter, GC gc, int y)
-{
- QPoint devicePt = painter->xForm (QPoint (0, y));
-
- pango_x_render_layout (painter->device()->x11Display(),
- painter->device()->handle(),
- gc, layout_, 0, devicePt.y());
-}
-
-gunichar
-ViewerPara::getChar (int index)
-{
- gunichar result;
-
- return g_utf8_get_char ((const char *)text_ + index);
-}
-
-QRect
-ViewerPara::charBounds (int index)
-{
- PangoRectangle pos;
-
- pango_layout_index_to_pos (layout_, index, &pos);
-
- return QRect (MIN (pos.x, pos.x + pos.width) / PANGO_SCALE,
- pos.y / PANGO_SCALE,
- ABS (pos.width) / PANGO_SCALE,
- pos.height / PANGO_SCALE);
-}
-
-int
-ViewerPara::findPoint (int x, int y)
-{
- int index;
-
- bool result = pango_layout_xy_to_index (layout_,
- x * PANGO_SCALE, y * PANGO_SCALE,
- &index, NULL);
- if (result)
- return index;
- else
- return -1;
-}
-
-ViewerView::ViewerView (QWidget *parent, QStatusBar *status) : QScrollView (parent)
-{
- status_ = status;
-
- viewport()->setBackgroundMode( QWidget::PaletteBase );
-
- setHScrollBarMode (QScrollView::AlwaysOff);
-
- context_ = pango_x_get_context (x11Display());
- pango_context_set_language (context_, pango_language_from_string ("en-us"));
-
- highlight_para_ = NULL;
- highlight_index_ = 0;
-}
-
-ViewerView::~ViewerView ()
-{
- g_object_unref (G_OBJECT (context_));
-}
-
-void
-ViewerView::readFile (const QString &name)
-{
- QFile file (name);
-
- if (!file.open (IO_ReadOnly))
- {
- fprintf (stderr, "Cannot open file '%s'\n", (const char *)name.local8Bit());
- return;
- }
-
- QTextStream ts (&file);;
-
- ts.setCodec (QTextCodec::codecForName ("utf8"));
-
- while (!ts.atEnd())
- paragraphs_.append (new ViewerPara (context (), ts.readLine()));
-}
-
-void
-ViewerView::contextChanged ()
-{
- QListIterator<ViewerPara> it(paragraphs_);
- for (; it.current(); ++it)
- it.current()->contextChanged();
-
- computeHeight();
- updateContents (0, 0, contentsWidth(), contentsHeight());
-}
-
-void
-ViewerView::setFontDesc (PangoFontDescription *font_desc)
-{
- pango_context_set_font_description (context_, font_desc);
- contextChanged();
-}
-
-void
-ViewerView::setDirection (PangoDirection base_dir)
-{
- QListIterator<ViewerPara> it(paragraphs_);
- for (; it.current(); ++it)
- it.current()->contextChanged();
-
- pango_context_set_base_dir (context_, base_dir);
- contextChanged();
-}
-
-void
-ViewerView::drawContents (QPainter *p, int clipx, int clipy, int clipw, int cliph)
-{
- XGCValues values;
- QRect clip = p->xForm (QRect (clipx, clipy, clipw, cliph));
-
- GC gc = XCreateGC (x11Display(), handle(), 0, &values);
-
- XSetForeground (x11Display(), gc, colorGroup().text().pixel());
-
- XRectangle xclip = { clip.x(), clip.y(), clip.width(), clip.height() };
- XSetClipRectangles (x11Display(), gc, 0, 0, &xclip, 1, YXBanded);
-
- int y = 0;
- QListIterator<ViewerPara> it(paragraphs_);
- for (; it.current(); ++it)
- {
- ViewerPara *para = it.current();
- int y_end = y + para->height ();
-
- if (y_end > clipy && y < clipy + cliph)
- para->draw (p, gc, y);
-
- if (para == highlight_para_)
- {
- QRect bounds = highlight_para_->charBounds (highlight_index_);
- bounds.moveBy (0, y);
- bounds = p->xForm (bounds);
-
- XRectangle xbounds = { bounds.x(), bounds.y(), bounds.width(), bounds.height() };
-
- XFillRectangle (x11Display(), p->device()->handle(), gc,
- xbounds.x, xbounds.y, xbounds.width, xbounds.height);
-
- XSetClipRectangles (x11Display(), gc, 0, 0, &xbounds, 1, YXBanded);
- XSetForeground (x11Display(), gc, colorGroup().base().pixel());
-
- para->draw (p, gc, y);
-
- XSetForeground (x11Display(), gc, colorGroup().text().pixel());
- XSetClipRectangles (x11Display(), gc, 0, 0, &xclip, 1, YXBanded);
- }
-
- y = y_end;
- }
-
- XFreeGC (x11Display(), gc);
-}
-
-void
-ViewerView::computeHeight ()
-{
- int width = visibleWidth();
- int height = 0;
-
- QListIterator<ViewerPara> it(paragraphs_);
- for (; it.current(); ++it)
- {
- ViewerPara *para = it.current();
- para->setWidth (width);
- height += para->height ();
- }
-
- resizeContents (width, height);
- repaintContents (0, 0, contentsWidth(), contentsHeight());
-}
-
-void
-ViewerView::viewportResizeEvent (QResizeEvent *event)
-{
- computeHeight ();
-}
-
-void
-ViewerView::updateHighlightChar ()
-{
- if (highlight_para_)
- {
- int y = 0;
- QListIterator<ViewerPara> it(paragraphs_);
-
- for (; it.current(); ++it)
- {
- ViewerPara *para = it.current();
- if (para == highlight_para_)
- {
- QRect bounds = para->charBounds (highlight_index_);
- bounds.moveBy (0, y);
- updateContents (bounds.x(), bounds.y(), bounds.width(), bounds.height());
-
- break;
- }
-
- y += para->height ();
- }
- }
-}
-
-void
-ViewerView::contentsMousePressEvent (QMouseEvent *event)
-{
- updateHighlightChar ();
- highlight_para_ = NULL;
-
- int y = 0;
- QListIterator<ViewerPara> it(paragraphs_);
- for (; it.current(); ++it)
- {
- ViewerPara *para = it.current();
- int y_end = y + para->height ();
-
- if (y <= event->y() && event->y() < y_end)
- {
- int index = para->findPoint (event->x(), event->y() - y);
- gunichar wc = para->getChar (index);
-
- if (index >= 0 && wc != (gunichar)-1)
- {
- highlight_para_ = para;
- highlight_index_ = index;
-
- if (status_)
- {
- QString num = QString::number (wc, 16).rightJustify (4, '0');
-
- status_->message (QString ("Current char: U+") + num);
- }
- }
-
- break;
- }
- y = y_end;
- }
-
- if (status_ && !highlight_para_)
- status_->clear ();
-
- updateHighlightChar();
-}
-
-static int
-cmp_families (const void *a, const void *b)
-{
- const char *a_name = pango_font_family_get_name (*(PangoFontFamily **)a);
- const char *b_name = pango_font_family_get_name (*(PangoFontFamily **)b);
-
- return strcmp (a_name, b_name);
-}
-
-ViewerWindow::ViewerWindow (const QString &filename)
-{
- // Create menu
-
- file_menu_ = new QPopupMenu (this);
- file_menu_->setCheckable (true);
-
- menuBar()->insertItem ("&File", file_menu_);
-
- file_menu_->insertItem( "&Quit", qApp, SLOT( closeAllWindows() ), CTRL+Key_Q );
-
- right_to_left_item_ = file_menu_->insertItem( "&Right-to-Left", this, SLOT( setRightToLeft() ), 0 );
-
- view_ = new ViewerView (this, new QStatusBar (this));
-
- setCentralWidget (view_);
-
- // Create families combo box
-
- QToolBar *toolbar = new QToolBar ("Font", this);
-
- family_combo_ = new QComboBox (toolbar);
-
- int n_families, i;
-
- pango_context_list_families (view_->context(), &families_, &n_families);
- qsort (families_, n_families, sizeof(PangoFontFamily *), cmp_families);
-
- for (i=0; i<n_families; i++)
- {
- const char *name = pango_font_family_get_name (families_[i]);
-
- family_combo_->insertItem (name);
- if (!strcmp (name, "sans"))
- family_combo_->setCurrentItem (i);
- }
-
- QObject::connect (family_combo_, SIGNAL(activated(int)), this, SLOT(fillStyleCombo(int)));
-
- faces_ = NULL;
-
- style_combo_ = new QComboBox (toolbar);
- fillStyleCombo (family_combo_->currentItem ());
-
- size_box_ = new QSpinBox (1, 1000, 1, toolbar);
- size_box_->setValue (16);
-
- QObject::connect (family_combo_, SIGNAL(activated(int)), this, SLOT(fontChanged()));
- QObject::connect (style_combo_, SIGNAL(activated(int)), this, SLOT(fontChanged()));
- QObject::connect (size_box_, SIGNAL(valueChanged(int)), this, SLOT(fontChanged()));
-
- fontChanged ();
-
- view_->readFile (filename);
-
- resize (500, 500);
-}
-
-static int
-compare_font_descriptions (const PangoFontDescription *a, const PangoFontDescription *b)
-{
- int val = strcmp (pango_font_description_get_family (a), pango_font_description_get_family (b));
- if (val != 0)
- return val;
-
- if (pango_font_description_get_weight (a) != pango_font_description_get_weight (b))
- return pango_font_description_get_weight (a) - pango_font_description_get_weight (b);
-
- if (pango_font_description_get_style (a) != pango_font_description_get_style (b))
- return pango_font_description_get_style (a) - pango_font_description_get_style (b);
-
- if (pango_font_description_get_stretch (a) != pango_font_description_get_stretch (b))
- return pango_font_description_get_stretch (a) - pango_font_description_get_stretch (b);
-
- if (pango_font_description_get_variant (a) != pango_font_description_get_variant (b))
- return pango_font_description_get_variant (a) - pango_font_description_get_variant (b);
-
- return 0;
-}
-
-static int
-faces_sort_func (const void *a, const void *b)
-{
- PangoFontDescription *desc_a = pango_font_face_describe (*(PangoFontFace **)a);
- PangoFontDescription *desc_b = pango_font_face_describe (*(PangoFontFace **)b);
-
- int ord = compare_font_descriptions (desc_a, desc_b);
-
- pango_font_description_free (desc_a);
- pango_font_description_free (desc_b);
-
- return ord;
-}
-
-void
-ViewerWindow::fillStyleCombo (int index)
-{
- PangoFontFamily *family = families_[index];
- int n_faces;
-
- if (faces_)
- g_free (faces_);
-
- pango_font_family_list_faces (family, &faces_, &n_faces);
-
- qsort (faces_, n_faces, sizeof(PangoFontFace *), faces_sort_func);
-
- style_combo_->clear();
- for (int i = 0; i < n_faces; i++)
- {
- const char *str = pango_font_face_get_face_name (faces_[i]);
- style_combo_->insertItem (str);
- }
-}
-
-void
-ViewerWindow::fontChanged ()
-{
- PangoFontFace *face = faces_[style_combo_->currentItem()];
-
- QString style = style_combo_->currentText();
-
- PangoFontDescription *font_desc = pango_font_face_describe (face);
- pango_font_description_set_size (font_desc, size_box_->value () * PANGO_SCALE);
-
- view_->setFontDesc (font_desc);
-
- pango_font_description_free (font_desc);
-}
-
-void
-ViewerWindow::setRightToLeft ()
-{
- bool new_value = !file_menu_->isItemChecked (right_to_left_item_);
-
- file_menu_->setItemChecked (right_to_left_item_, new_value);
- view_->setDirection (new_value ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR);
-}
-
-ViewerWindow::~ViewerWindow ()
-{
- delete view_;
-}
-
-int
-main (int argc, char **argv)
-{
- QApplication a (argc, argv);
- const char *filename;
-
- g_type_init ();
-
- if (QFileInfo ("./pangorc").exists ())
- putenv ("PANGO_RC_FILE=./pangorc");
-
- if (argc == 2)
- filename = argv[1];
- else
- filename = "HELLO.utf8";
-
- ViewerWindow *vw = new ViewerWindow (QString::fromLocal8Bit (filename));
-
- vw->show();
-
- a.connect (&a, SIGNAL(lastWindowClosed()), &a, SLOT(quit()));
- return a.exec ();
-}
-
diff --git a/examples/viewer-qt.h b/examples/viewer-qt.h
deleted file mode 100644
index 21307111..00000000
--- a/examples/viewer-qt.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/* Pango
- * viewer-qt.cc: Example program to view a UTF-8 encoding file
- * using Pango to render result.
- *
- * Copyright (C) 1999-2000 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 <qscrollview.h>
-#include <qlist.h>
-#include <qmainwindow.h>
-#include <pango/pango.h>
-
-class QComboBox;
-class QSpinBox;
-
-class ViewerPara
-{
- public:
- ViewerPara (PangoContext *context, const QString &text);
- ~ViewerPara ();
-
- void setWidth (int width);
- void contextChanged ();
- int height ();
- void draw (QPainter *painter, GC gc, int y);
- QRect charBounds (int index);
- gunichar getChar (int index);
- int findPoint (int x, int y);
-
- private:
- QCString text_;
- int height_;
- PangoLayout *layout_;
-};
-
-class ViewerView : public QScrollView
-{
- Q_OBJECT
-
- public:
-
- ViewerView::ViewerView (QWidget *parent, QStatusBar *status = NULL);
- ~ViewerView ();
-
- void readFile (const QString &name);
- void setFontDesc (PangoFontDescription *font_desc);
- void setDirection (PangoDirection base_dir);
-
- void computeHeight ();
-
- PangoContext *context() { return context_; }
-
- protected:
- virtual void drawContents (QPainter *p, int clipx, int clipy, int clipw, int cliph);
- virtual void viewportResizeEvent ( QResizeEvent *event );
- virtual void contentsMousePressEvent (QMouseEvent *event);
-
- private:
- void contextChanged ();
- void updateHighlightChar ();
-
- QStatusBar *status_;
-
- PangoContext *context_;
- QList<ViewerPara> paragraphs_;
-
- ViewerPara *highlight_para_;
- int highlight_index_;
-};
-
-class ViewerWindow : public QMainWindow
-{
- Q_OBJECT
-
- public:
-
- ViewerWindow (const QString &filename);
- ~ViewerWindow ();
-
- private:
- ViewerView *view_;
-
- PangoContext *context_;
-
- QComboBox *family_combo_;
- PangoFontFamily **families_;
-
- QComboBox *style_combo_;
- PangoFontFace **faces_;
-
- QSpinBox *size_box_;
-
- QPopupMenu *file_menu_;
-
- int right_to_left_item_;
-
- private slots:
- void fillStyleCombo (int index);
- void fontChanged ();
- void setRightToLeft ();
-};
diff --git a/examples/viewer-x.c b/examples/viewer-x.c
index 7327ab7f..772dd719 100644
--- a/examples/viewer-x.c
+++ b/examples/viewer-x.c
@@ -1,4 +1,4 @@
-/* viewer-x.c: Common code X-based rendering demos
+/* viewer-x.c: Common code for X-based viewers
*
* Copyright (C) 1999,2004,2005 Red Hat, Inc.
* Copyright (C) 2001 Sun Microsystems
@@ -19,36 +19,81 @@
* Boston, MA 02111-1307, USA.
*/
#include <config.h>
-#include <errno.h>
-#include <stdlib.h>
-#include <stdio.h>
#include <string.h>
-#include "viewer-x.h"
#include "renderdemo.h"
+#include "viewer-x.h"
+
+void
+x_view_init (gpointer instance,
+ const PangoViewer *klass)
+{
+ XViewer *x = (XViewer *)instance;
+
+ x->display = XOpenDisplay (NULL);
+ if (!x->display)
+ fail ("Cannot open display %s\n", XDisplayName (NULL));
+
+ x->screen = DefaultScreen (x->display);
+}
+
+gpointer
+x_view_create (const PangoViewer *klass)
+{
+ XViewer *instance;
+
+ instance = g_slice_new (XViewer);
+
+ x_view_init (instance, klass);
+
+ return instance;
+}
-/* initialized by main() */
-static Display *display;
-static int screen;
-static Window window;
-static Pixmap pixmap;
+void
+x_view_destroy (gpointer instance)
+{
+ XViewer *x = (XViewer *)instance;
+
+ XCloseDisplay (x->display);
+
+ g_slice_free (XViewer, instance);
+}
+
+gpointer
+x_view_create_surface (gpointer instance,
+ int width,
+ int height)
+{
+ XViewer *x = (XViewer *) instance;
+ Pixmap pixmap;
+
+ pixmap = XCreatePixmap (x->display, DefaultRootWindow (x->display), width, height,
+ DefaultDepth (x->display, x->screen));
-/* initialized by do_init() */
-static PangoContext *context;
-static int width, height;
+ return (gpointer) pixmap;
+}
+
+void
+x_view_destroy_surface (gpointer instance,
+ gpointer surface)
+{
+ XViewer *x = (XViewer *) instance;
+ Pixmap pixmap = (Pixmap) surface;
-/* runtime stuff */
-static Region update_region = NULL;
-static gboolean show_borders;
+ XFreePixmap (x->display, pixmap);
+}
static void
-update (void)
+update (Display *display,
+ Pixmap pixmap,
+ Window window,
+ Region *update_region)
{
GC gc;
XRectangle extents;
int width, height;
- XClipBox (update_region, &extents);
+ XClipBox (*update_region, &extents);
width = extents.width;
height = extents.height;
@@ -62,111 +107,139 @@ update (void)
XFreeGC (display, gc);
- XDestroyRegion (update_region);
- update_region = NULL;
+ XDestroyRegion (*update_region);
+ *update_region = NULL;
}
static void
-expose (XExposeEvent *xev)
+expose (XExposeEvent *xev,
+ Region *update_region)
{
XRectangle r;
- if (!update_region)
- update_region = XCreateRegion ();
+ if (!*update_region)
+ *update_region = XCreateRegion ();
r.x = xev->x;
r.y = xev->y;
r.width = xev->width;
r.height = xev->height;
- XUnionRectWithRegion (&r, update_region, update_region);
+ XUnionRectWithRegion (&r, *update_region, *update_region);
}
-int
-main (int argc, char **argv)
+gpointer
+x_view_create_window (gpointer instance,
+ const char *title,
+ int width,
+ int height)
{
- XEvent xev;
+ XViewer *x = (XViewer *) instance;
unsigned long bg;
+ Window window;
XSizeHints size_hints;
- unsigned int quit_keycode;
- unsigned int borders_keycode;
- const char *title;
-
- g_type_init();
- parse_options (argc, argv);
-
- display = XOpenDisplay (NULL);
- if (!display)
- fail ("Cannot open display %s\n", XDisplayName (NULL));
- screen = DefaultScreen (display);
-
- do_init (display, screen, opt_dpi, &context, &width, &height);
-
- bg = WhitePixel (display, screen);
- window = XCreateSimpleWindow (display, DefaultRootWindow (display),
+ bg = WhitePixel (x->display, x->screen);
+ window = XCreateSimpleWindow (x->display, DefaultRootWindow (x->display),
0, 0, width, height, 0,
bg, bg);
- pixmap = XCreatePixmap (display, window, width, height,
- DefaultDepth (display, screen));
- XSelectInput (display, window, ExposureMask | KeyPressMask);
+
+ XSelectInput (x->display, window, ExposureMask | KeyPressMask);
- XMapWindow (display, window);
- title = get_options_string ();
- XmbSetWMProperties (display, window,
+ XMapWindow (x->display, window);
+ XmbSetWMProperties (x->display, window,
title,
NULL, NULL, 0, NULL, NULL, NULL);
- g_free (title);
memset ((char *)&size_hints, 0, sizeof (XSizeHints));
size_hints.flags = PSize | PMaxSize;
size_hints.width = width; size_hints.height = height; /* for compat only */
size_hints.max_width = width; size_hints.max_height = height;
- XSetWMNormalHints (display, window, &size_hints);
+ XSetWMNormalHints (x->display, window, &size_hints);
- borders_keycode = XKeysymToKeycode(display, 'B');
- quit_keycode = XKeysymToKeycode(display, 'Q');
+ return (gpointer) window;
+}
+
+void
+x_view_destroy_window (gpointer instance,
+ gpointer window)
+{
+ XViewer *x = (XViewer *) instance;
+ Window win = (Window) window;
- do_render (display, screen, window, pixmap, context, width, height, show_borders);
+ XDestroyWindow (x->display, win);
+}
+
+gpointer
+x_view_display (gpointer instance,
+ gpointer surface,
+ gpointer win,
+ int width,
+ int height,
+ gpointer state)
+{
+ XViewer *x = (XViewer *) instance;
+ Pixmap pixmap = (Pixmap) surface;
+ Window window = (Window) win;
+ XEvent xev;
+ XRectangle r;
+ Region update_region;
+ unsigned int quit_keycode;
+ unsigned int borders_keycode;
+ gboolean show_borders = FALSE;
+
+ if (state)
+ show_borders = GPOINTER_TO_UINT (state) == 0xdeadbeef;
+
+ /* force a full redraw */
+ update_region = XCreateRegion ();
+ r.x = 0;
+ r.y = 0;
+ r.width = width;
+ r.height = height;
+ XUnionRectWithRegion (&r, update_region, update_region);
+
+ borders_keycode = XKeysymToKeycode(x->display, 'B');
+ quit_keycode = XKeysymToKeycode(x->display, 'Q');
while (1)
{
- if (!XPending (display) && update_region)
- update ();
+ if (!XPending (x->display) && update_region)
+ update (x->display, pixmap, window, &update_region);
- XNextEvent (display, &xev);
+ XNextEvent (x->display, &xev);
switch (xev.xany.type) {
case KeyPress:
if (xev.xkey.keycode == quit_keycode)
- goto done;
+ return NULL;
else if (xev.xkey.keycode == borders_keycode)
{
- XRectangle r;
show_borders = !show_borders;
- do_render (display, screen, window, pixmap, context, width, height, show_borders);
-
- if (!update_region)
- update_region = XCreateRegion ();
-
- r.x = 0;
- r.y = 0;
- r.width = width;
- r.height = height;
- XUnionRectWithRegion (&r, update_region, update_region);
+ return GUINT_TO_POINTER (show_borders ? 0xdeadbeef : 0xbe);
}
break;
case Expose:
- expose (&xev.xexpose);
+ expose (&xev.xexpose, &update_region);
break;
}
}
-
-done:
-
- g_object_unref (context);
- XFreePixmap (display, pixmap);
- finalize ();
-
- return 0;
}
+
+const PangoViewer x_viewer = {
+ "X",
+ NULL,
+ NULL,
+ x_view_create,
+ x_view_destroy,
+ NULL,
+ x_view_create_surface,
+ x_view_destroy_surface,
+ NULL,
+ NULL,
+ x_view_create_window,
+ x_view_destroy_window,
+ x_view_display
+};
+
+const PangoViewer *fallback_viewer = &x_viewer;
diff --git a/examples/viewer-x.h b/examples/viewer-x.h
index 83c40358..71c1279e 100644
--- a/examples/viewer-x.h
+++ b/examples/viewer-x.h
@@ -1,4 +1,4 @@
-/* viewer-x.h: Common code X-based rendering demos
+/* viewer-x.h: Common headers for X-based viewers
*
* Copyright (C) 1999,2004,2005 Red Hat, Inc.
* Copyright (C) 2001 Sun Microsystems
@@ -18,27 +18,53 @@
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
+#ifndef VIEWER_X_H
+#define VIEWER_X_H
#include <pango/pango.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
-/* to be implemented by the backend-specific part */
-
-void do_init (Display *display,
- int screen,
- int dpi,
- /* output */
- PangoContext **context,
- int *width,
- int *height);
-
-void do_render (Display *display,
- int screen,
- Window window,
- Pixmap pixmap,
- PangoContext *context,
- int width,
- int height,
- gboolean show_borders);
+#include "viewer.h"
+
+
+typedef struct
+{
+ Display *display;
+ int screen;
+} XViewer;
+
+
+extern const PangoViewer x_viewer;
+
+void x_view_init (gpointer instance,
+ const PangoViewer *klass);
+
+gpointer x_view_create (const PangoViewer *klass);
+
+void x_view_destroy (gpointer instance);
+
+gpointer x_view_create_surface (gpointer instance,
+ int width,
+ int height);
+
+void x_view_destroy_surface (gpointer instance,
+ gpointer surface);
+
+gpointer x_view_create_window (gpointer instance,
+ const char *title,
+ int width,
+ int height);
+
+void x_view_destroy_window (gpointer instance,
+ gpointer window);
+
+gpointer x_view_display (gpointer instance,
+ gpointer surface,
+ gpointer window,
+ int width,
+ int height,
+ gpointer state);
+
+#endif /* VIEWER_X_H */
diff --git a/examples/viewer.h b/examples/viewer.h
new file mode 100644
index 00000000..e99d5f9e
--- /dev/null
+++ b/examples/viewer.h
@@ -0,0 +1,85 @@
+/* viewer.h: PangoViewer class
+ *
+ * Copyright (C) 1999,2004,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.
+ */
+#ifndef VIEWER_H
+#define VIEWER_H
+
+#include <stdio.h>
+#include <pango/pango.h>
+
+typedef struct _PangoViewer PangoViewer;
+
+struct _PangoViewer {
+
+ const char *name;
+
+ const char *id;
+
+ const char *save_suffix;
+
+ gpointer (*create) (const PangoViewer *klass);
+
+ void (*destroy) (gpointer instance);
+
+ PangoContext * (*get_context) (gpointer instance);
+
+ gpointer (*create_surface) (gpointer instance,
+ int width,
+ int height);
+
+ void (*destroy_surface) (gpointer instance,
+ gpointer surface);
+
+ void (*render) (gpointer instance,
+ gpointer surface,
+ PangoContext *context,
+ int width,
+ int height,
+ gpointer state);
+
+ /* The following can be NULL */
+
+ void (*save) (gpointer instance,
+ gpointer surface,
+ FILE *stream,
+ int width,
+ int height);
+
+ gpointer (*create_window) (gpointer instance,
+ const char *title,
+ int width,
+ int height);
+
+ void (*destroy_window) (gpointer instance,
+ gpointer window);
+
+ gpointer (*display) (gpointer instance,
+ gpointer surface,
+ gpointer window,
+ int width,
+ int height,
+ gpointer state);
+
+};
+
+extern const PangoViewer *fallback_viewer;
+extern const PangoViewer *viewers[];
+
+#endif /* VIEWER_H */
diff --git a/examples/xftview.c b/examples/xftview.c
deleted file mode 100644
index d8d6be99..00000000
--- a/examples/xftview.c
+++ /dev/null
@@ -1,118 +0,0 @@
-/* Pango
- * xftview.c: Example program to view a UTF-8 encoding file
- * using PangoXft to render result
- *
- * Copyright (C) 1999,2004,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 <config.h>
-
-#include "renderdemo.h"
-#include "viewer-x.h"
-
-#include <pango/pangoxft.h>
-
-static void
-default_substitute (FcPattern *pattern,
- gpointer data)
-{
- int dpi = GPOINTER_TO_INT (data);
- FcPatternAddInteger (pattern, FC_DPI, dpi);
-}
-
-static void
-render_callback (PangoLayout *layout,
- int x,
- int y,
- gpointer data,
- gboolean show_borders)
-{
- XftDraw *draw = (XftDraw *)data;
- XftColor color;
-
- color.color.red = 0x0;
- color.color.green = 0x0;
- color.color.blue = 0x0;
- color.color.alpha = 0xffff;
-
- pango_xft_render_layout (draw, &color, layout, x, y);
-
- /*
- if (show_borders)
- {
- PangoContext *context;
- PangoXftFontMap *fontmap;
- PangoRenderer *renderer;
- PangoRectangle ink, logical;
-
- pango_layout_get_extents (layout, &ink, &logical);
-
- context = pango_layout_get_context (layout);
- fontmap = (PangoXftFontMap *)pango_context_get_font_map (context);
-
- humm, we cannot go on, as the following is private api.
- need to implement pango_font_map_get_renderer...
-
- renderer = _pango_xft_font_map_get_renderer (fontmap);
- }
- */
-}
-
-void
-do_init (Display *display,
- int screen,
- int dpi,
- /* output */
- PangoContext **context,
- int *width,
- int *height)
-{
- XftInit (NULL);
- *context = pango_xft_get_context (display, screen);
- pango_xft_set_default_substitute (display, screen, default_substitute, GINT_TO_POINTER (dpi), NULL);
- do_output (*context, NULL, NULL, NULL, width, height, FALSE);
-}
-
-void
-do_render (Display *display,
- int screen,
- Window window,
- Pixmap pixmap,
- PangoContext *context,
- int width,
- int height,
- gboolean show_borders)
-{
- XftDraw *draw;
- XftColor color;
-
- draw = XftDrawCreate (display, pixmap,
- DefaultVisual (display, screen),
- DefaultColormap (display, screen));
-
- color.color.red = 0xffff;
- color.color.blue = 0xffff;
- color.color.green = 0xffff;
- color.color.alpha = 0xffff;
-
- XftDrawRect (draw, &color, 0, 0, width, height);
-
- do_output (context, render_callback, NULL, draw, NULL, NULL, show_borders);
-
- XftDrawDestroy (draw);
-}