summaryrefslogtreecommitdiff
path: root/examples/pangoft2topgm.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/pangoft2topgm.c')
-rw-r--r--examples/pangoft2topgm.c298
1 files changed, 186 insertions, 112 deletions
diff --git a/examples/pangoft2topgm.c b/examples/pangoft2topgm.c
index 257dc8bb..f223f89e 100644
--- a/examples/pangoft2topgm.c
+++ b/examples/pangoft2topgm.c
@@ -24,10 +24,7 @@
#define BUFSIZE 1024
#define MALLOCSIZE 1024
#define DEFAULT_FONT_FAMILY "Sans"
-#define DEFAULT_FONT_SIZE 36
-
-#include <pango/pango.h>
-#include <pango/pangoft2.h>
+#define DEFAULT_FONT_SIZE 18
#include <errno.h>
#include <stdarg.h>
@@ -35,22 +32,31 @@
#include <stdio.h>
#include <string.h>
-static char *prog_name;
-static PangoContext *context;
+#include "argcontext.h"
-static gboolean opt_display = FALSE;
-static int opt_dpi = 96;
+#include <pango/pango.h>
+#include <pango/pangoft2.h>
#define _MAKE_FONT_NAME(family, size) family " " #size
#define MAKE_FONT_NAME(family, size) _MAKE_FONT_NAME(family, size)
-static char *opt_font = MAKE_FONT_NAME (DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE);
-static PangoDirection opt_dir = PANGO_DIRECTION_LTR;
+static char *prog_name;
+static PangoContext *context;
+
+static char *tmpfile_name;
static char *outfile_name;
+
+static gboolean opt_display = FALSE;
+static int opt_dpi = 96;
+static char *opt_font = MAKE_FONT_NAME (DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE);
+static gboolean opt_header = FALSE;
static char *opt_output = NULL;
static int opt_margin = 10;
static int opt_markup = FALSE;
+static gboolean opt_rtl = FALSE;
+static char *opt_text = NULL;
static gboolean opt_waterfall = FALSE;
+static int opt_width = -1;
static void fail (const char *format, ...) G_GNUC_PRINTF (1, 2);
@@ -70,6 +76,20 @@ fail (const char *format, ...)
exit (1);
}
+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);
+
+ if ((pango_font_description_get_set_fields (font_description) & PANGO_FONT_MASK_SIZE) == 0)
+ pango_font_description_set_size (font_description, DEFAULT_FONT_SIZE * PANGO_SCALE);
+
+ return font_description;
+}
+
static PangoLayout *
make_layout(PangoContext *context,
const char *text,
@@ -85,26 +105,42 @@ make_layout(PangoContext *context,
else
pango_layout_set_text (layout, text, -1);
- 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);
-
+ font_description = get_font_description ();
if (size > 0)
pango_font_description_set_size (font_description, size * PANGO_SCALE);
- else if ((pango_font_description_get_set_fields (font_description) & PANGO_FONT_MASK_SIZE) == 0)
- pango_font_description_set_size (font_description, DEFAULT_FONT_SIZE * PANGO_SCALE);
+ if (opt_width > 0)
+ pango_layout_set_width (layout, (opt_width * opt_dpi * PANGO_SCALE + 32) / 72);
+
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);
return layout;
}
+static gchar *
+get_options_string (void)
+{
+ PangoFontDescription *font_description = get_font_description ();
+ gchar *font_name;
+ gchar *result;
+
+ if (opt_waterfall)
+ 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);
+ pango_font_description_free (font_description);
+ g_free (font_name);
+
+ return result;
+}
+
static void
do_output (PangoContext *context,
const char *text,
@@ -121,6 +157,24 @@ do_output (PangoContext *context,
*width = 0;
*height = 0;
+ 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 (bitmap)
+ pango_ft2_render_layout (bitmap, layout, x, y);
+
+ y += PANGO_PIXELS (logical_rect.height);
+
+ g_object_unref (layout);
+ g_free (options_string);
+ }
+
if (opt_waterfall)
{
start_size = 8;
@@ -153,17 +207,21 @@ do_output (PangoContext *context,
*height += 2 * opt_margin;
}
-int int_arg (const char *arg_name, const char *arg)
+static void
+show_help (ArgContext *context,
+ const char *name,
+ const char *arg,
+ gpointer data)
{
- char *end;
- long result = strtol (arg, &end, 0);
- if (*arg == '\0' || *end != '\0')
- {
- fail ("Cannot parse integer value '%s' for %s.",
- arg, arg_name);
- }
-
- return result;
+ g_print ("%s - An example viewer for the pango ft2 extension\n"
+ "\n"
+ "Syntax:\n"
+ " %s [options] FILE\n"
+ "\n"
+ "Options:\n",
+ prog_name, prog_name);
+ arg_context_print_help (context);
+ exit (0);
}
int main(int argc, char *argv[])
@@ -172,9 +230,38 @@ int main(int argc, char *argv[])
char *text;
size_t len;
char *p;
- int argp;
PangoFontMap *fontmap;
GError *error = NULL;
+ ArgContext *arg_context;
+ gboolean do_convert = FALSE;
+
+ static const ArgDesc args[] = {
+ { "display", "Show output using ImageMagick",
+ ARG_BOOL, &opt_display },
+ { "dpi", "Set the dpi'",
+ ARG_INT, &opt_dpi },
+ { "font", "Set the font name",
+ ARG_STRING, &opt_font },
+ { "header", "Display the options in the output",
+ ARG_BOOL, &opt_header },
+ { "help", "Show this output",
+ ARG_CALLBACK, NULL, show_help, },
+ { "margin", "Set the margin on the output in pixels",
+ ARG_INT, &opt_margin },
+ { "markup", "Interpret contents as Pango markup",
+ ARG_BOOL, &opt_markup },
+ { "output", "Name of output file",
+ ARG_STRING, &opt_output },
+ { "rtl", "Set base dir to RTL",
+ ARG_BOOL, &opt_rtl },
+ { "text", "Text to display (instead of a file)",
+ ARG_STRING, &opt_text },
+ { "waterfall", "Create a waterfall display",
+ ARG_BOOL, &opt_waterfall },
+ { "width", "Width in points to which to wrap output",
+ ARG_INT, &opt_width },
+ { NULL }
+ };
prog_name = g_path_get_basename (argv[0]);
@@ -183,93 +270,43 @@ int main(int argc, char *argv[])
if (g_file_test ("./pangorc", G_FILE_TEST_EXISTS))
putenv ("PANGO_RC_FILE=./pangorc");
- /* Parse command line */
- argp=1;
- while(argp < argc && argv[argp][0] == '-')
+ arg_context = arg_context_new (NULL);
+ arg_context_add_table (arg_context, args);
+
+ if (!arg_context_parse (arg_context, &argc, &argv, &error))
+ fail ("%s", error->message);
+
+ if ((opt_text && argc != 1) ||
+ (!opt_text && argc != 2))
{
- char *opt = argv[argp++];
- if (strcmp(opt, "--help") == 0)
- {
- printf("%s - An example viewer for the pango ft2 extension\n"
- "\n"
- "Syntax:\n"
- " %s [options] FILE\n"
- "\n"
- "Options:\n"
- " --display Show output using ImageMagick rather than writing to a file.\n"
- " --dpi d Set the dpi.Default is '%d'.\n"
- " --font Set the font name. Default is '%s'.\n"
- " --margin m Set the margin on the output in pixels. Default is %d.\n"
- " --markup Interpret contents as Pango markup.\n"
- " --output f Name of output file [short form, -o].\n"
- " --rtl Set base dir to RTL. Default is LTR.\n"
- " --waterfall Create a waterfall display."
- " --width Width of drawing window. Default is 500.\n",
- prog_name, prog_name, opt_dpi, opt_font, opt_margin);
- exit(0);
- }
- if (strcmp(opt, "--display") == 0)
- {
- opt_display = TRUE;
- continue;
- }
- if (strcmp(opt, "--dpi") == 0)
- {
- opt_dpi = int_arg("--dpi", argv[argp++]);
- continue;
- }
- if (strcmp(opt, "--font") == 0)
- {
- opt_font = argv[argp++];
- continue;
- }
- if (strcmp(opt, "--margin") == 0)
- {
- opt_margin = int_arg("--margin", argv[argp++]);
- continue;
- }
- if (strcmp(opt, "--markup") == 0)
- {
- opt_markup = TRUE;
- continue;
- }
- if (strcmp(opt, "--output") == 0 ||
- strcmp(opt, "-o") == 0)
- {
- opt_output = argv[argp++];
- continue;
- }
- if (strcmp(opt, "--waterfall") == 0)
- {
- opt_waterfall = TRUE;
- continue;
- }
- if (strcmp(opt, "--rtl") == 0)
- {
- opt_dir = PANGO_DIRECTION_RTL;
- continue;
- }
- fail ("Unknown option %s!\n", opt);
+ if (opt_text && argc == 2)
+ fail ("When specifying --text, no file should be given");
+
+ g_printerr ("Usage: %s [options] FILE\n", prog_name);
+ exit (1);
}
+
if (!opt_display && !opt_output)
{
g_printerr ("%s: --output not specified, assuming --display\n", prog_name);
opt_display = TRUE;
}
- if (argp + 1 != argc)
+ /* Get the text
+ */
+ if (opt_text)
{
- g_printerr ("Usage: %s [options] FILE\n", prog_name);
- exit (1);
+ text = g_strdup (opt_text);
+ len = strlen (text);
}
-
- /* Get the text in the supplied file
- */
- if (!g_file_get_contents (argv[argp++], &text, &len, &error))
- fail ("%s\n", error->message);
- if (!g_utf8_validate (text, len, NULL))
- fail ("Text is not valid UTF-8");
-
+ else
+ {
+ if (!g_file_get_contents (argv[1], &text, &len, &error))
+ fail ("%s\n", error->message);
+ if (!g_utf8_validate (text, len, NULL))
+ fail ("Text is not valid UTF-8");
+ }
+
/* Strip trailing whitespace
*/
p = text + len;
@@ -292,7 +329,13 @@ int main(int argc, char *argv[])
if (opt_output)
{
- outfile_name = 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)
@@ -302,7 +345,7 @@ int main(int argc, char *argv[])
else /* --display */
{
/* This may need to be G_OS_UNIX guarded for fdopen */
- int fd = g_file_open_tmp ("pangoft2pgmXXXXXX", &outfile_name, &error);
+ 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");
@@ -315,7 +358,8 @@ int main(int argc, char *argv[])
context = pango_ft2_font_map_create_context (PANGO_FT2_FONT_MAP (fontmap));
pango_context_set_language (context, pango_language_from_string ("en_US"));
- pango_context_set_base_dir (context, opt_dir);
+ pango_context_set_base_dir (context,
+ opt_rtl ? PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR);
/* Write contents as pgm file */
{
@@ -333,7 +377,7 @@ int main(int argc, char *argv[])
bitmap.num_grays = 256;
bitmap.pixel_mode = ft_pixel_mode_grays;
memset (buf, 0x00, bitmap.pitch * bitmap.rows);
-
+
do_output (context, text, &bitmap, &width, &height);
/* Invert bitmap to get black text on white background */
@@ -358,17 +402,47 @@ int main(int argc, char *argv[])
if (fclose(outfile) == EOF)
fail ("Error writing output file: %s\n", g_strerror (errno));
+ /* Convert to a different format, if necessary */
+ if (do_convert)
+ {
+ int exit_status;
+
+ 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);
+
+ if (tmpfile_name)
+ {
+ remove (tmpfile_name);
+ tmpfile_name = NULL;
+ }
+
+ if (exit_status)
+ exit (1);
+ }
+
if (opt_display)
{
int exit_status;
- gchar *command = g_strdup_printf ("display %s", outfile_name);
+ 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);
- if (!opt_output)
- remove (outfile_name);
+ g_free (title);
+ g_free (title_quoted);
+
+ if (tmpfile_name)
+ remove (tmpfile_name);
if (exit_status)
exit (1);