summaryrefslogtreecommitdiff
path: root/examples
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2005-01-09 00:12:39 +0000
committerOwen Taylor <otaylor@src.gnome.org>2005-01-09 00:12:39 +0000
commitcc6ac36dd3c7e5ef39b9f21ef77596a159f2100e (patch)
treee1b8ffc1c14d449a41946d22ea5d1c6ddf9115d8 /examples
parent75f4ad29adce645ddb837e662c9d71ccfbf60154 (diff)
downloadpango-cc6ac36dd3c7e5ef39b9f21ef77596a159f2100e.tar.gz
Add checks for Cairo
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.
Diffstat (limited to 'examples')
-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
8 files changed, 450 insertions, 39 deletions
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,