summaryrefslogtreecommitdiff
path: root/examples/renderdemo.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/renderdemo.c')
-rw-r--r--examples/renderdemo.c178
1 files changed, 99 insertions, 79 deletions
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;