1 /* mdump.c -- Dump text image -*- coding: euc-jp; -*-
2 Copyright (C) 2003, 2004
3 National Institute of Advanced Industrial Science and Technology (AIST)
4 Registration Number H15PRO112
6 This file is part of the m17n library.
8 The m17n library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Lesser General Public License
10 as published by the Free Software Foundation; either version 2.1 of
11 the License, or (at your option) any later version.
13 The m17n library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public
19 License along with the m17n library; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
24 @enpage m17n-dump dump text image
26 @section m17n-dump-synopsis SYNOPSIS
28 m17n-dump [ OPTION ... ] [ FILE ]
30 @section m17n-dump-description DESCRIPTION
32 Dump a text as PNG image file.
34 The PNG file is written to a file created in the current directory
35 with the name "BASE.png" where BASE is the basename of FILE. If
36 FILE is omitted, text is read from standard input, and the image
37 is dumped into the file "output.png".
39 The following OPTIONs are available.
45 SIZE is the font size in point. The default font size is 12 point.
49 DPI is the resolution in dots per inch. The default resolution is
54 PAPER is the paper size: a4, a4r, a5, a5r, b5, b5r, letter, WxH,
55 or W. In the case of WxH, W and H are the width and height in
56 millimeter. In the case of W, W is the width in millimeter. If
57 this option is specified, PAPER limits the image size. If FILE is
58 too large for a single page, multiple files with the names
59 "BASE.01.png", "BASE.02.png", etc. are created.
63 MARGIN is the horizontal and vertical margin in millimeter. The
64 default margin is 20 mm. It is ignored when PAPER is not
69 POS is the character position of cursor to draw. By default,
74 FILE is assumed to be an XML file generated by the serialize
75 facility of the m17n library, and FILE is deserialized before an
80 Each line is broken at word boundary.
84 FILTER is a string containing a shell command line. If this
85 option is specified, the PNG image is not written info a
86 file but is given to FILTER as standard input. If FILTER
87 contains "%s", that part is replaced by a basename of FILE.
88 So, the default behaviour is the same as specifying "cat >
93 Enable anti-alias drawing.
97 Prefer a font whose family name is FAMILY.
101 Prefer a font specified for the language LANG. LANG must be a
102 2-letter code of ISO 630 (e.g. "en" for English).
106 Specify that the orientation of the text is right-to-left.
110 Quiet mode. Don't print any messages.
114 Print the version number.
123 @japage m17n-dump ¥Æ¥¥¹¥È²èÁü¤Î¥À¥ó¥×
125 @section m17n-dump-synopsis SYNOPSIS
127 m17n-dump [ OPTION ... ] [ FILE ]
129 @section m17n-dump-description DESCRIPTION
131 ¥Æ¥¥¹¥È¤ò PNG ²èÁü¤È¤·¤Æ¥À¥ó¥×¤¹¤ë¡£
133 PNG ²èÁü¤Ï¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ëºî¤é¤ì¤¿ "BASE.png" ¤È¤¤¤¦Ì¾Á°¤Î
134 ¥Õ¥¡¥¤¥ë¤Ë½ñ¤¹þ¤Þ¤ì¤ë¡£¤³¤³¤Ç BASE ¤ÏFILE ¤Î basename ¤Ç¤¢¤ë¡£
135 FILE ¤¬¾Êά¤µ¤ì¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ïɸ½àÆþÎϤ«¤éÆɤޤ졢²èÁü¤Ï
136 "output.png" ¤Ë¥À¥ó¥×¤µ¤ì¤ë¡£
138 °Ê²¼¤Î¥ª¥×¥·¥ç¥ó¤¬ÍøÍѤǤ¤ë¡£
144 SIZE ¤Ï¥Õ¥©¥ó¥È¤ÎÂ礤µ¤ò¥Ý¥¤¥ó¥Èñ°Ì¤Ç¼¨¤·¤¿¤â¤Î¤Ç¤¢¤ë¡£¥Ç¥Õ¥©¥ë
145 ¥È¤ÎÂ礤µ¤Ï 12 ¥Ý¥¤¥ó¥È¡£
149 DPI ¤Ï²òÁüÅÙ¤ò£±¥¤¥ó¥Á¤¢¤¿¤ê¤Î¥É¥Ã¥Èñ°Ì¤Ç¼¨¤·¤¿¤â¤Î¤Ç¤¢¤ë¡£¥Ç¥Õ¥©
150 ¥ë¥È¤Î²òÁüÅÙ¤Ï 300 dpi¡£
154 PAPER ¤Ï¤Ú¡¼¥Ñ¥µ¥¤¥º : a4, a4r, a5, a5r, b5, b5r, letter, WxH ¤Þ¤¿
155 ¤Ï W¡£ WxH ¤Î¾ì¹ç¡¢ W ¤È H ¤ÏÉý¤È¹â¤µ¤ò¥ß¥ê¥á¡¼¥¿Ã±°Ì¤Ç¼¨¤·¤¿¤â¤Î¡£
156 W ¤Î¾ì¹ç¡¢ W ¤ÏÉý¤ò¥ß¥ê¥á¡¼¥¿Ã±°Ì¤Ç¼¨¤·¤¿¤â¤Î¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤¬»ØÄê
157 ¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ PAPER ¤¬²èÁü¥µ¥¤¥º¤òÀ©¸Â¤¹ ¤ë¡£FILE ¤¬ 1 ¥Ú¡¼¥¸
158 ¤ËǼ¤Þ¤é¤Ê¤¤¤Û¤ÉÂ礤¤¾ì¹ç¤Ï¡¢"BASE.01.png", "BASE.02.png" Åù¤Î̾Á°
159 ¤Î¤Ä¤¤¤¿Ê£¿ô¤Î¥Õ¥¡¥¤¥ë¤¬ºî¤é¤ì¤ë¡£
163 MARGIN ¤Ï¿åÊ¿¡¢¿âľ¥Þ¡¼¥¸¥ó¤ò¥ß¥ê¥á¡¼¥¿Ã±°Ì¤Ç¼¨¤·¤¿¤â¤Î¤Ç¤¢¤ë¡£¥Ç
164 ¥Õ¥©¥ë¥È¤Î¥Þ¡¼¥¸¥ó¤Ï 20 mm¡£PAPER ¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð̵»ë¤µ¤ì¤ë¡£
168 POS ¤Ï¥«¡¼¥½¥ë¤Îʸ»ú°ÌÃÖ¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¥«¡¼¥½¥ë¤ÏÉÁ¤«¤ì¤Ê¤¤¡£
172 FILE ¤Ï m17n ¥é¥¤¥Ö¥é¥ê¤Î¥·¥ê¥¢¥é¥¤¥ºµ¡Ç½¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿ XML ¥Õ¥¡
173 ¥¤¥ë¤Ç¤¢¤ê¡¢²èÁü¤òÀ¸À®¤¹¤ëÁ°¤Ë¥Ç¥·¥ê¥¢¥é¥¤¥º¤µ¤ì¤ë¡£
181 FILTER ¤Ï¥·¥§¥ë¥³¥Þ¥ó¥É¹Ô¤ò´Þ¤àʸ»úÎó¤Ç¤¢¤ë¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤¬»ØÄê
182 ¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢PNG ²èÁü¤Ï¥Õ¥¡¥¤¥ë¤Ë½ñ¤«¤ì¤ë¤Î¤Ç¤Ï¤Ê¤¯¡¢FILTER ¤Ë
183 ɸ½àÆþÎϤȤ·¤ÆÅϤµ¤ì¤ë¡£ FILTER ¤¬ "%s" ¤ò´Þ¤ó¤Ç¤¤¤ì¤Ð¡¢¤½¤ì¤Ï FILE
184 ¤Î¥Ù¡¼¥¹¥Í¡¼¥à¤ËÃÖ¤´¹¤¨¤é¤ì¤ë¡£¤³¤Î¥×¥í¥°¥é¥à¤Î¥Ç¥Õ¥©¥ë¥È¤Î¿¶Éñ¤¤
185 ¤È¡¢FILTER ¤Ë "cat > %s.png" ¤ò»ØÄꤷ¤¿¾ì¹ç¤Î¿¶Éñ¤ÏƱ°ì¤Ç¤¢¤ë¡£
189 ¥¢¥ó¥Á¥¨¥¤¥ê¥¢¥¹½èÍý¤ò¹Ô¤¦¡£
193 ¥Õ¥¡¥ß¥ê¥£Ì¾¤¬ FAMILY ¤Î¥Õ¥©¥ó¥È¤òÍ¥ÀèŪ¤Ë»È¤¦¡£
197 ¸À¸ì LANG ÍѤ˻ØÄꤵ¤ì¤¿¥Õ¥©¥ó¥È¤òÍ¥ÀèŪ¤Ë»È¤¦¡£LANG ¤Ï ISO 630 ¤Î
198 £²Ê¸»ú¥³¡¼¥É¡ÊÎ㡧±Ñ¸ì¤Ï "en" ¡Ë¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
202 °ìÀڤΥá¥Ã¥»¡¼¥¸¤òɽ¼¨¤·¤Ê¤¤¡£
206 ¥Ð¡¼¥¸¥ç¥óÈÖ¹æ¤òɽ¼¨¤¹¤ë¡£
210 ¤³¤Î¥á¥Ã¥»¡¼¥¸¤òɽ¼¨¤¹¤ë¡£
225 #if defined (HAVE_FREETYPE) && defined (HAVE_GD)
228 #include <m17n-gui.h>
229 #include <m17n-misc.h>
231 #define PROGRAM_VERSION "1.1"
233 /* Enumuration of the supported paper types. */
247 /* Array of paper sizes for the supported paper types. */
250 int width, height; /* in millimeter */
251 } paper_size[PAPER_NOLIMIT] = {
252 { 210, 297 }, /* a4 */
253 { 297, 210 }, /* a4r */
254 { 148, 210 }, /* a5 */
255 { 210, 148 }, /* a5r */
256 { 250, 176 }, /* b5 */
257 { 176, 250 }, /* b5r */
258 { 216, 279 }, /* letter */
262 /* Print the usage of this program (the name is PROG), and exit with
266 help_exit (char *prog, int exit_code)
274 printf ("Usage: %s [ OPTION ...] [ FILE ]\n", prog);
275 printf ("Dump a text as a PNG image into a file.\n");
276 printf (" The PNG file is created in the current directory\n");
277 printf (" with the name \"BASE.png\" where BASE is the basename of FILE.\n");
278 printf (" If FILE is omitted, text is read from standard input, and\n");
279 printf (" dumped into the file \"output.png\".\n");
280 printf ("The following OPTIONs are available.\n");
281 printf (" %-13s %s", "-s SIZE",
282 "Font size in 1/10 point (default 120).\n");
283 printf (" %-13s %s", "-d DPI",
284 "Resolution in dots per inch (defualt 300).\n");
285 printf (" %-13s %s", "-p PAPER",
286 "Paper size; a4, a4r, a5, a5r, b5, b5r, letter, W, or WxH.\n");
287 printf (" %-13s %s", "-m MARGIN",
288 "Marginal space in millimeter (default 20).\n");
289 printf (" %-13s %s", "-c POS",
290 "Character position of cursor to draw (default no cursor)\n");
291 printf (" %-13s %s", "-x",
292 "FILE is assumed to be an XML file.\n");
293 printf (" %-13s %s", "-f FILTER",
294 "String containing a shell command line to be used as a filter.\n");
295 printf (" %-13s %s", "-w", "Each line is broken at word boundary.\n");
296 printf (" %-13s %s", "-a", "Enable anti-alias drawing.\n");
297 printf (" %-13s %s", "--family FAMILY",
298 "Prefer a font whose family is FAMILY.\n");
299 printf (" %-13s %s", "--language LANG",
300 "Prefer a font specified for the langauge LANG.\n");
301 printf (" %-13s %s", "-r",
302 "Specify that the orientation of the text is right-to-left.\n");
303 printf (" %-13s %s", "-q", "Quiet mode. Don't print any messages.\n");
304 printf (" %-13s %s", "--version", "Print the version number.\n");
305 printf (" %-13s %s", "-h, --help", "Print this message.\n");
310 /* Format MSG by FMT and print the result to the stderr, and exit. */
312 #define FATAL_ERROR(fmt, arg) \
314 fprintf (stderr, fmt, arg); \
319 /* Move POS to the next line head in M-text MT whose length is LEN.
320 If POS is already on the last line, set POS to LEN. */
322 #define NEXTLINE(pos, len) \
324 pos = mtext_character (mt, pos, len, '\n'); \
332 /* Find the range of M-text MT that fits in one page of height HEIGHT
333 when drawn from the character position POS. Set RECT->y to the
334 Y-offset of the first baseline. */
337 find_page_end (MFrame *frame, int height, MText *mt, int pos,
338 MDrawControl *control, MDrawMetric *rect)
340 int len = mtext_len (mt);
348 NEXTLINE (next, len);
349 mdraw_text_extents (frame, mt, to, next, control, NULL, NULL, rect);
352 if (y + rect->height > height)
358 mdraw_glyph_info (frame, mt, to, to, control, &info);
359 if (y + info.metrics.height > height)
361 y += info.metrics.height;
374 /* Dump the image in IMAGE into a file whose name is generated from
375 FILENAME and PAGE_INDEX (if it is not zero). */
378 dump_image (gdImagePtr image, char *filename, char *filter,
379 int page_index, int quiet_mode)
385 char *name = alloca (strlen (filename) + 8);
387 sprintf (name, "%s.%02d", filename, page_index);
393 char *command = alloca (strlen (filename) + strlen (filter) + 1);
395 sprintf (command, filter, filename);
396 fp = popen (command, "w");
398 FATAL_ERROR ("Can't run the command \"%s\"\n", command);
400 printf ("Running \"%s\" ... ", command);
404 char *fullname = alloca (strlen (filename) + 5);
406 sprintf (fullname, "%s.png", filename);
407 fp = fopen (fullname, "w");
409 FATAL_ERROR ("Can't write to \"%s\"\n", fullname);
411 printf ("Writing %s ... ", fullname);
415 gdImagePng (image, fp);
418 printf (" done (%dx%d)\n", image->sx, image->sy);
421 extern int line_break (MText *mt, int pos, int from, int to, int line, int y);
424 main (int argc, char **argv)
427 int paper = PAPER_NOLIMIT;
434 int break_by_word = 0;
436 int paper_width, paper_height;
438 char *family_name = NULL;
439 char *lang_name = NULL;
448 MDrawControl control;
450 char *filename = "output";
453 /* Parse the command line arguments. */
454 for (i = 1; i < argc; i++)
456 if (! strcmp (argv[i], "--help")
457 || ! strcmp (argv[i], "-h")
458 || ! strcmp (argv[i], "-?"))
459 help_exit (argv[0], 0);
460 else if (! strcmp (argv[i], "--version"))
462 printf ("m17n-dump (m17n library) %s\n", PROGRAM_VERSION);
463 printf ("Copyright (C) 2003, 2004 AIST, JAPAN\n");
466 else if (! strcmp (argv[i], "-s") && i + 1< argc)
468 fontsize = atoi (argv[++i]);
470 FATAL_ERROR ("Invalid font size: %s\n", argv[i]);
472 else if (! strcmp (argv[i], "-p") && i + 1< argc)
477 if (! strcmp (argv[i], "a4"))
479 else if (! strcmp (argv[i], "a4r"))
481 else if (! strcmp (argv[i], "a5"))
483 else if (! strcmp (argv[i], "a5r"))
485 else if (! strcmp (argv[i], "b5"))
487 else if (! strcmp (argv[i], "b5r"))
489 else if (! strcmp (argv[i], "letter"))
490 paper = PAPER_LETTER;
491 else if (sscanf (argv[i], "%dx%d", &w, &h) == 2
495 paper_size[paper].width = w;
496 paper_size[paper].height = h;
498 else if (sscanf (argv[i], "%d", &w) == 1
502 paper_size[paper].width = w;
503 paper_size[paper].height = 0;
506 FATAL_ERROR ("Invalid paper type: %s\n", argv[i]);
508 else if (! strcmp (argv[i], "-d") && i + 1< argc)
510 dpi = atoi (argv[++i]);
512 FATAL_ERROR ("Invalid resolution: %s\n", argv[i]);
514 else if (! strcmp (argv[i], "-m") && i + 1< argc)
516 margin = atoi (argv[++i]);
518 FATAL_ERROR ("Invalid margin: %s\n", argv[i]);
520 else if (! strcmp (argv[i], "-c") && i + 1< argc)
522 cursor_pos = atoi (argv[++i]);
524 FATAL_ERROR ("Invalid cursor position: %s\n", argv[i]);
526 else if (! strcmp (argv[i], "-f") && i + 1< argc)
530 else if (! strcmp (argv[i], "-x"))
534 else if (! strcmp (argv[i], "-w"))
538 else if (! strcmp (argv[i], "-q"))
542 else if (! strcmp (argv[i], "-a"))
546 else if (! strcmp (argv[i], "--family"))
548 family_name = argv[++i];
550 else if (! strcmp (argv[i], "--language"))
552 lang_name = argv[++i];
554 else if (! strcmp (argv[i], "-r"))
558 else if (argv[i][0] != '-')
560 fp = fopen (argv[i], "r");
562 FATAL_ERROR ("Fail to open the file %s!\n", argv[i]);
563 filename = basename (argv[i]);
567 fprintf (stderr, "Unknown or invalid option: %s\n", argv[i]);
568 help_exit (argv[0], 1);
572 /* Initialize the m17n library. */
574 if (merror_code != MERROR_NONE)
575 FATAL_ERROR ("%s\n", "Fail to initialize the m17n library.");
577 mt = mconv_decode_stream (Mcoding_utf_8, fp);
580 mt = mtext_deserialize (mt);
582 FATAL_ERROR ("%s\n", "Fail to decode the input file or stream!");
584 len = mtext_len (mt);
586 mtext_put_prop (mt, 0, len, Mlanguage, msymbol (lang_name));
588 if (paper == PAPER_NOLIMIT)
589 paper_width = paper_height = margin = 0;
592 paper_width = paper_size[paper].width * dpi / 25.4;
593 paper_height = paper_size[paper].height * dpi / 25.4;
594 margin = margin * dpi / 25.4;
598 MPlist *plist = mplist (), *p;
599 MFontset *fontset = mfontset ("truetype");
600 MFace *face = mface ();
602 mface_put_prop (face, Mfontset, fontset);
603 mface_put_prop (face, Msize, (void *) (fontsize * dpi / 100));
608 for (p = family_name; *p; p++)
609 if (isupper (*p)) *p = tolower (*p);
610 mface_put_prop (face, Mfamily, msymbol (family_name));
613 p = mplist_add (plist, Mdevice, msymbol ("gd"));
614 p = mplist_add (p, Mface, face);
615 m17n_object_unref (face);
616 frame = mframe (plist);
617 m17n_object_unref (plist);
619 FATAL_ERROR ("%s\n", "Can't open a frame (perhaps no font available)!");
622 memset (&control, 0, sizeof control);
623 control.two_dimensional = 1;
624 control.enable_bidi = 1;
625 control.anti_alias = anti_alias;
626 control.orientation_reversed = r2l;
629 control.with_cursor = 1;
630 if (cursor_pos > len)
632 control.cursor_pos = cursor_pos;
633 control.cursor_width = -1;
636 control.ignore_formatting_char = 1;
638 control.line_break = mdraw_default_line_break;
640 if (paper == PAPER_NOLIMIT)
642 control.max_line_width = 0;
643 mdraw_text_extents (frame, mt, 0, len, &control, NULL, NULL, &rect);
644 paper_width = rect.width;
645 paper_height = rect.height;
649 control.max_line_width = paper_width - margin * 2;
650 if (paper_height == 0)
652 mdraw_text_extents (frame, mt, 0, len, &control, NULL, NULL, &rect);
653 paper_height = rect.height + margin * 2;
657 image = gdImageCreate (paper_width, paper_height);
660 white = gdImageColorAllocate (image, 255, 255, 255);
665 if (paper == PAPER_NOLIMIT || paper_size[paper].height == 0)
668 to = find_page_end (frame, paper_height - margin * 2, mt, from,
671 gdImageFilledRectangle (image, 0, 0, paper_width - 1, paper_height - 1,
674 mdraw_text_with_control (frame, image,
675 margin, margin - rect.y,
676 mt, from, to, &control);
678 mdraw_text_with_control (frame, image,
679 paper_width - margin, margin - rect.y,
680 mt, from, to, &control);
681 dump_image (image, filename, filter,
682 ((from > 0 || to < len) ? page_index : 0),
689 m17n_object_unref (frame);
690 m17n_object_unref (mt);
692 gdImageDestroy (image);
696 #else /* not HAVE_FREETYPE nor HAVE_GD */
699 main (int argc, char **argv)
701 fprintf (stderr, "Can't run without Freetype and GD library!\n");
705 #endif /* not HAVE_FREETYPE nor HAVE_GD */
706 #endif /* not FOR_DOXYGEN */