diff options
Diffstat (limited to 'examples/pangoft2topgm.c')
-rw-r--r-- | examples/pangoft2topgm.c | 298 |
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); |