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 mdump dump text image
26 @section mdump-synopsis SYNOPSIS
28 mdump [ OPTION ... ] [ FILE ]
30 @section mdump-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 Quiet mode. Don't print any messages.
110 Print the version number.
119 @japage mdump ¥Æ¥¥¹¥È²èÁü¤Î¥À¥ó¥×
121 @section mdump-synopsis SYNOPSIS
123 mdump [ OPTION ... ] [ FILE ]
125 @section mdump-description DESCRIPTION
127 ¥Æ¥¥¹¥È¤ò PNG ²èÁü¤È¤·¤Æ¥À¥ó¥×¤¹¤ë¡£
129 PNG ²èÁü¤Ï¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ëºî¤é¤ì¤¿ "BASE.png" ¤È¤¤¤¦Ì¾Á°¤Î
130 ¥Õ¥¡¥¤¥ë¤Ë½ñ¤¹þ¤Þ¤ì¤ë¡£¤³¤³¤Ç BASE ¤ÏFILE ¤Î basename ¤Ç¤¢¤ë¡£
131 FILE ¤¬¾Êά¤µ¤ì¤ì¤Ð¡¢¥Æ¥¥¹¥È¤Ïɸ½àÆþÎϤ«¤éÆɤޤ졢²èÁü¤Ï
132 "output.png" ¤Ë¥À¥ó¥×¤µ¤ì¤ë¡£
134 °Ê²¼¤Î¥ª¥×¥·¥ç¥ó¤¬ÍøÍѤǤ¤ë¡£
140 SIZE ¤Ï¥Õ¥©¥ó¥È¤ÎÂ礤µ¤ò¥Ý¥¤¥ó¥Èñ°Ì¤Ç¼¨¤·¤¿¤â¤Î¤Ç¤¢¤ë¡£¥Ç¥Õ¥©¥ë
141 ¥È¤ÎÂ礤µ¤Ï 12 ¥Ý¥¤¥ó¥È¡£
145 DPI ¤Ï²òÁüÅÙ¤ò£±¥¤¥ó¥Á¤¢¤¿¤ê¤Î¥É¥Ã¥Èñ°Ì¤Ç¼¨¤·¤¿¤â¤Î¤Ç¤¢¤ë¡£¥Ç¥Õ¥©
146 ¥ë¥È¤Î²òÁüÅÙ¤Ï 300 dpi¡£
150 PAPER ¤Ï¤Ú¡¼¥Ñ¥µ¥¤¥º : a4, a4r, a5, a5r, b5, b5r, letter, WxH ¤Þ¤¿
151 ¤Ï W¡£ WxH ¤Î¾ì¹ç¡¢ W ¤È H ¤ÏÉý¤È¹â¤µ¤ò¥ß¥ê¥á¡¼¥¿Ã±°Ì¤Ç¼¨¤·¤¿¤â¤Î¡£
152 W ¤Î¾ì¹ç¡¢ W ¤ÏÉý¤ò¥ß¥ê¥á¡¼¥¿Ã±°Ì¤Ç¼¨¤·¤¿¤â¤Î¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤¬»ØÄê
153 ¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ PAPER ¤¬²èÁü¥µ¥¤¥º¤òÀ©¸Â¤¹ ¤ë¡£FILE ¤¬ 1 ¥Ú¡¼¥¸
154 ¤ËǼ¤Þ¤é¤Ê¤¤¤Û¤ÉÂ礤¤¾ì¹ç¤Ï¡¢"BASE.01.png", "BASE.02.png" Åù¤Î̾Á°
155 ¤Î¤Ä¤¤¤¿Ê£¿ô¤Î¥Õ¥¡¥¤¥ë¤¬ºî¤é¤ì¤ë¡£
159 MARGIN ¤Ï¿åÊ¿¡¢¿âľ¥Þ¡¼¥¸¥ó¤ò¥ß¥ê¥á¡¼¥¿Ã±°Ì¤Ç¼¨¤·¤¿¤â¤Î¤Ç¤¢¤ë¡£¥Ç
160 ¥Õ¥©¥ë¥È¤Î¥Þ¡¼¥¸¥ó¤Ï 20 mm¡£PAPER ¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð̵»ë¤µ¤ì¤ë¡£
164 POS ¤Ï¥«¡¼¥½¥ë¤Îʸ»ú°ÌÃÖ¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¥«¡¼¥½¥ë¤ÏÉÁ¤«¤ì¤Ê¤¤¡£
168 FILE ¤Ï m17n ¥é¥¤¥Ö¥é¥ê¤Î¥·¥ê¥¢¥é¥¤¥ºµ¡Ç½¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿ XML ¥Õ¥¡
169 ¥¤¥ë¤Ç¤¢¤ê¡¢²èÁü¤òÀ¸À®¤¹¤ëÁ°¤Ë¥Ç¥·¥ê¥¢¥é¥¤¥º¤µ¤ì¤ë¡£
177 FILTER ¤Ï¥·¥§¥ë¥³¥Þ¥ó¥É¹Ô¤ò´Þ¤àʸ»úÎó¤Ç¤¢¤ë¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤¬»ØÄê
178 ¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢PNG ²èÁü¤Ï¥Õ¥¡¥¤¥ë¤Ë½ñ¤«¤ì¤ë¤Î¤Ç¤Ï¤Ê¤¯¡¢FILTER ¤Ë
179 ɸ½àÆþÎϤȤ·¤ÆÅϤµ¤ì¤ë¡£ FILTER ¤¬ "%s" ¤ò´Þ¤ó¤Ç¤¤¤ì¤Ð¡¢¤½¤ì¤Ï FILE
180 ¤Î¥Ù¡¼¥¹¥Í¡¼¥à¤ËÃÖ¤´¹¤¨¤é¤ì¤ë¡£¤³¤Î¥×¥í¥°¥é¥à¤Î¥Ç¥Õ¥©¥ë¥È¤Î¿¶Éñ¤¤
181 ¤È¡¢FILTER ¤Ë "cat > %s.png" ¤ò»ØÄꤷ¤¿¾ì¹ç¤Î¿¶Éñ¤ÏƱ°ì¤Ç¤¢¤ë¡£
185 ¥¢¥ó¥Á¥¨¥¤¥ê¥¢¥¹½èÍý¤ò¹Ô¤¦¡£
189 ¥Õ¥¡¥ß¥ê¥£Ì¾¤¬ FAMILY ¤Î¥Õ¥©¥ó¥È¤òÍ¥ÀèŪ¤Ë»È¤¦¡£
193 ¸À¸ì LANG ÍѤ˻ØÄꤵ¤ì¤¿¥Õ¥©¥ó¥È¤òÍ¥ÀèŪ¤Ë»È¤¦¡£LANG ¤Ï ISO 630 ¤Î
194 £²Ê¸»ú¥³¡¼¥É¡ÊÎ㡧±Ñ¸ì¤Ï "en" ¡Ë¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
198 °ìÀڤΥá¥Ã¥»¡¼¥¸¤òɽ¼¨¤·¤Ê¤¤¡£
202 ¥Ð¡¼¥¸¥ç¥óÈÖ¹æ¤òɽ¼¨¤¹¤ë¡£
206 ¤³¤Î¥á¥Ã¥»¡¼¥¸¤òɽ¼¨¤¹¤ë¡£
221 #if defined (HAVE_FREETYPE) && defined (HAVE_GD)
224 #include <m17n-gui.h>
225 #include <m17n-misc.h>
227 #define PROGRAM_VERSION "1.1"
229 /* Enumuration of the supported paper types. */
243 /* Array of paper sizes for the supported paper types. */
246 int width, height; /* in millimeter */
247 } paper_size[PAPER_NOLIMIT] = {
248 { 210, 297 }, /* a4 */
249 { 297, 210 }, /* a4r */
250 { 148, 210 }, /* a5 */
251 { 210, 148 }, /* a5r */
252 { 250, 176 }, /* b5 */
253 { 176, 250 }, /* b5r */
254 { 216, 279 }, /* letter */
258 /* Print the usage of this program (the name is PROG), and exit with
262 help_exit (char *prog, int exit_code)
270 printf ("Usage: %s [ OPTION ...] [ FILE ]\n", prog);
271 printf ("Dump a text as a PNG image into a file.\n");
272 printf (" The PNG file is created in the current directory\n");
273 printf (" with the name \"BASE.png\" where BASE is the basename of FILE.\n");
274 printf (" If FILE is omitted, text is read from standard input, and\n");
275 printf (" dumped into the file \"output.png\".\n");
276 printf ("The following OPTIONs are available.\n");
277 printf (" %-13s %s", "-s SIZE",
278 "Font size in point (default 12).\n");
279 printf (" %-13s %s", "-d DPI",
280 "Resolution in dots per inch (defualt 300).\n");
281 printf (" %-13s %s", "-p PAPER",
282 "Paper size; a4, a4r, a5, a5r, b5, b5r, letter, W, or WxH.\n");
283 printf (" %-13s %s", "-m MARGIN",
284 "Marginal space in millimeter (default 20).\n");
285 printf (" %-13s %s", "-c POS",
286 "Character position of cursor to draw (default no cursor)\n");
287 printf (" %-13s %s", "-x",
288 "FILE is assumed to be an XML file.\n");
289 printf (" %-13s %s", "-f FILTER",
290 "String containing a shell command line to be used as a filter.\n");
291 printf (" %-13s %s", "-w", "Each line is broken at word boundary.\n");
292 printf (" %-13s %s", "-a", "Enable anti-alias drawing.\n");
293 printf (" %-13s %s", "--family FAMILY",
294 "Prefer a font whose family is FAMILY.\n");
295 printf (" %-13s %s", "--language LANG",
296 "Prefer a font specified for the langauge LANG.\n");
297 printf (" %-13s %s", "-q", "Quiet mode. Don't print any messages.\n");
298 printf (" %-13s %s", "--version", "Print the version number.\n");
299 printf (" %-13s %s", "-h, --help", "Print this message.\n");
304 /* Format MSG by FMT and print the result to the stderr, and exit. */
306 #define FATAL_ERROR(fmt, arg) \
308 fprintf (stderr, fmt, arg); \
313 /* Move POS to the next line head in M-text MT whose length is LEN.
314 If POS is already on the last line, set POS to LEN. */
316 #define NEXTLINE(pos, len) \
318 pos = mtext_character (mt, pos, len, '\n'); \
326 /* Find the range of M-text MT that fits in one page of height HEIGHT
327 when drawn from the character position POS. Set RECT->y to the
328 Y-offset of the first baseline. */
331 find_page_end (MFrame *frame, int height, MText *mt, int pos,
332 MDrawControl *control, MDrawMetric *rect)
334 int len = mtext_len (mt);
342 NEXTLINE (next, len);
343 mdraw_text_extents (frame, mt, to, next, control, NULL, NULL, rect);
346 if (y + rect->height > height)
352 mdraw_glyph_info (frame, mt, to, to, control, &info);
353 if (y + info.this.height > height)
355 y += info.this.height;
369 /* Table to convert a byte of LSBFirst to MSBFirst. */
370 char reverse_bit_order[256];
372 /* Initialize the above table. */
375 init_reverse_bit_order ()
379 for (i = 0; i < 256; i++)
381 = (((i & 1) << 7) | ((i & 2) << 5) | ((i & 4) << 3) | ((i & 8) << 1)
382 | ((i & 16) >> 1) | ((i & 32) >> 3)
383 | ((i & 64) >> 5) | ((i & 128) >> 7));
387 /* Dump the image in IMAGE into a file whose name is generated from
388 FILENAME and PAGE_INDEX (if it is not zero). */
391 dump_image (gdImagePtr image, char *filename, char *filter,
392 int page_index, int quiet_mode)
398 char *name = alloca (strlen (filename) + 8);
400 sprintf (name, "%s.%02d", filename, page_index);
406 char *command = alloca (strlen (filename) + strlen (filter) + 1);
408 sprintf (command, filter, filename);
409 fp = popen (command, "w");
411 FATAL_ERROR ("Can't run the command \"%s\"\n", command);
413 printf ("Running \"%s\" ... ", command);
417 char *fullname = alloca (strlen (filename) + 5);
419 sprintf (fullname, "%s.png", filename);
420 fp = fopen (fullname, "w");
422 FATAL_ERROR ("Can't write to \"%s\"\n", fullname);
424 printf ("Writing %s ... ", fullname);
428 gdImagePng (image, fp);
431 printf (" done (%dx%d)\n", image->sx, image->sy);
434 extern int line_break (MText *mt, int pos, int from, int to, int line, int y);
437 main (int argc, char **argv)
440 int paper = PAPER_NOLIMIT;
447 int break_by_word = 0;
449 int paper_width, paper_height;
451 char *family_name = NULL;
452 char *lang_name = NULL;
460 MDrawControl control;
462 char *filename = "output";
465 /* Parse the command line arguments. */
466 for (i = 1; i < argc; i++)
468 if (! strcmp (argv[i], "--help")
469 || ! strcmp (argv[i], "-h")
470 || ! strcmp (argv[i], "-?"))
471 help_exit (argv[0], 0);
472 else if (! strcmp (argv[i], "--version"))
474 printf ("mdump (m17n library) %s\n", PROGRAM_VERSION);
475 printf ("Copyright (C) 2003, 2004 AIST, JAPAN\n");
478 else if (! strcmp (argv[i], "-s") && i + 1< argc)
480 fontsize = atoi (argv[++i]);
482 FATAL_ERROR ("Invalid font size: %s\n", argv[i]);
484 else if (! strcmp (argv[i], "-p") && i + 1< argc)
489 if (! strcmp (argv[i], "a4"))
491 else if (! strcmp (argv[i], "a4r"))
493 else if (! strcmp (argv[i], "a5"))
495 else if (! strcmp (argv[i], "a5r"))
497 else if (! strcmp (argv[i], "b5"))
499 else if (! strcmp (argv[i], "b5r"))
501 else if (! strcmp (argv[i], "letter"))
502 paper = PAPER_LETTER;
503 else if (sscanf (argv[i], "%dx%d", &w, &h) == 2
507 paper_size[paper].width = w;
508 paper_size[paper].height = h;
510 else if (sscanf (argv[i], "%d", &w) == 1
514 paper_size[paper].width = w;
515 paper_size[paper].height = 0;
518 FATAL_ERROR ("Invalid paper type: %s\n", argv[i]);
520 else if (! strcmp (argv[i], "-d") && i + 1< argc)
522 dpi = atoi (argv[++i]);
524 FATAL_ERROR ("Invalid resolution: %s\n", argv[i]);
526 else if (! strcmp (argv[i], "-m") && i + 1< argc)
528 margin = atoi (argv[++i]);
530 FATAL_ERROR ("Invalid margin: %s\n", argv[i]);
532 else if (! strcmp (argv[i], "-c") && i + 1< argc)
534 cursor_pos = atoi (argv[++i]);
536 FATAL_ERROR ("Invalid cursor position: %s\n", argv[i]);
538 else if (! strcmp (argv[i], "-f") && i + 1< argc)
542 else if (! strcmp (argv[i], "-x"))
546 else if (! strcmp (argv[i], "-w"))
550 else if (! strcmp (argv[i], "-q"))
554 else if (! strcmp (argv[i], "-a"))
558 else if (! strcmp (argv[i], "--family"))
560 family_name = argv[++i];
562 else if (! strcmp (argv[i], "--language"))
564 lang_name = argv[++i];
566 else if (argv[i][0] != '-')
568 fp = fopen (argv[i], "r");
570 FATAL_ERROR ("Fail to open the file %s!\n", argv[i]);
571 filename = basename (argv[i]);
575 fprintf (stderr, "Unknown or invalid option: %s\n", argv[i]);
576 help_exit (argv[0], 1);
580 /* Initialize the m17n library. */
582 if (merror_code != MERROR_NONE)
583 FATAL_ERROR ("%s\n", "Fail to initialize the m17n library.");
585 mt = mconv_decode_stream (Mcoding_utf_8, fp);
588 mt = mtext_deserialize (mt);
590 FATAL_ERROR ("%s\n", "Fail to decode the input file or stream!");
592 len = mtext_len (mt);
594 mtext_put_prop (mt, 0, len, Mlanguage, msymbol (lang_name));
596 if (paper == PAPER_NOLIMIT)
597 paper_width = paper_height = margin = 0;
600 paper_width = paper_size[paper].width * dpi / 25.4;
601 paper_height = paper_size[paper].height * dpi / 25.4;
602 margin = margin * dpi / 25.4;
606 MPlist *plist = mplist (), *p;
607 MFontset *fontset = mfontset ("truetype");
608 MFace *face = mface ();
610 mface_put_prop (face, Mfontset, fontset);
611 mface_put_prop (face, Msize, (void *) (fontsize * dpi / 100));
616 for (p = family_name; *p; p++)
617 if (isupper (*p)) *p = tolower (*p);
618 mface_put_prop (face, Mfamily, msymbol (family_name));
621 p = mplist_add (plist, Mdevice, msymbol ("gd"));
622 p = mplist_add (p, Mface, face);
623 m17n_object_unref (face);
624 frame = mframe (plist);
625 m17n_object_unref (plist);
627 FATAL_ERROR ("%s\n", "Can't open a frame (perhaps no font available)!");
630 memset (&control, 0, sizeof control);
631 control.as_image = 1;
632 control.two_dimensional = 1;
633 control.enable_bidi = 1;
634 control.anti_alias = anti_alias;
637 control.with_cursor = 1;
638 if (cursor_pos > len)
640 control.cursor_pos = cursor_pos;
641 control.cursor_width = -1;
644 control.ignore_formatting_char = 1;
646 control.line_break = line_break;
648 if (paper == PAPER_NOLIMIT)
650 control.max_line_width = 0;
651 mdraw_text_extents (frame, mt, 0, len, &control, NULL, NULL, &rect);
652 paper_width = rect.width;
653 paper_height = rect.height;
657 control.max_line_width = paper_width - margin * 2;
658 if (paper_height == 0)
660 mdraw_text_extents (frame, mt, 0, len, &control, NULL, NULL, &rect);
661 paper_height = rect.height + margin * 2;
665 image = gdImageCreate (paper_width, paper_height);
668 white = gdImageColorAllocate (image, 255, 255, 255);
673 if (paper == PAPER_NOLIMIT || paper_size[paper].height == 0)
676 to = find_page_end (frame, paper_height - margin * 2, mt, from,
679 gdImageFilledRectangle (image, 0, 0, paper_width - 1, paper_height - 1,
681 mdraw_text_with_control (frame, image,
682 margin, margin - rect.y, mt, from, to,
684 dump_image (image, filename, filter,
685 ((from > 0 || to < len) ? page_index : 0),
692 m17n_object_unref (frame);
693 m17n_object_unref (mt);
695 gdImageDestroy (image);
699 #else /* not HAVE_FREETYPE nor HAVE_GD */
702 main (int argc, char **argv)
704 fprintf (stderr, "Can't run without Freetype and GD library!\n");
708 #endif /* not HAVE_FREETYPE nor HAVE_GD */
709 #endif /* not FOR_DOXYGEN */