*** empty log message ***
[m17n/m17n-lib.git] / example / mdump.c
index c402338..2159f90 100644 (file)
@@ -1,5 +1,5 @@
-/* mdump.c -- Dump text image
-   Copyright (C) 2003, 2004
+/* mdump.c -- Dump text image                          -*- coding: euc-jp; -*-
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H15PRO112
 
 
    You should have received a copy of the GNU Lesser General Public
    License along with the m17n library; if not, write to the Free
-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+   Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
    02111-1307, USA.  */
 
 /***en
-    @page mdump dump text image
+    @enpage m17n-dump dump text image
 
-    @section mdump-synopsis SYNOPSIS
+    @section m17n-dump-synopsis SYNOPSIS
 
-    mdump [ OPTION ... ] [ FILE ]
+    m17n-dump [ OPTION ... ] [ FILE ]
 
-    @section mdump-description DESCRIPTION
+    @section m17n-dump-description DESCRIPTION
 
-    Dump a text as a Netpbm image.
+    Dump a text as PNG image file.
 
-    The Netpbm image is written to a file created in the current
-    directory with the name "BASE.pbm" where BASE is the basename of
-    FILE.  If FILE is omitted, text is read from standard input, and
-    the image is dumped into the file "output.pbm".
+    The PNG file is written to a file created in the current directory
+    with the name "BASE.png" where BASE is the basename of FILE.  If
+    FILE is omitted, text is read from standard input, and the image
+    is dumped into the file "output.png".
 
     The following OPTIONs are available.
 
 
     <li> -p PAPER
 
-    PAPER is the paper size: a4, a4r, a5, a5r, b5, b5r, letter, or
-    WxH.  In the last case, W and H are the width and height in
-    millimeter.  If this option is specified, PAPER limits the image
-    size.  If FILE is too large for a single page, multiple files with
-    the names "BASE.01.pbm", "BASE.02.pbm", etc. are created.
+    PAPER is the paper size: a4, a4r, a5, a5r, b5, b5r, letter, WxH,
+    or W.  In the case of WxH, W and H are the width and height in
+    millimeter.  In the case of W, W is the width in millimeter.  If
+    this option is specified, PAPER limits the image size.  If FILE is
+    too large for a single page, multiple files with the names
+    "BASE.01.png", "BASE.02.png", etc. are created.
 
     <li> -m MARGIN
 
@@ -71,7 +72,7 @@
     <li> -x
 
     FILE is assumed to be an XML file generated by the serialize
-    facility of the m17n library, and FILE is deserialized before the
+    facility of the m17n library, and FILE is deserialized before an
     image is created.
 
     <li> -w
     <li> -f FILTER
 
     FILTER is a string containing a shell command line.  If this
-    option is specified, the Netpbm image is not written info a
+    option is specified, the PNG image is not written info a
     file but is given to FILTER as standard input.  If FILTER
     contains "%s", that part is replaced by a basename of FILE.
     So, the default behaviour is the same as specifying "cat >
-    %s.pbm" as FILTER.
+    %s.png" as FILTER.
+
+    If FILTER is just "-", the PNG image is written to stdout.
+
+    <li> -a
+
+    Enable anti-alias drawing.
+
+    <li> --family FAMILY
+
+    Prefer a font whose family name is FAMILY.
+
+    <li> --language LANG
+
+    Prefer a font specified for the language LANG.  LANG must be a
+    2-letter code of ISO 630 (e.g. "en" for English).
+
+    <li> -fg FOREGROUND
+
+    Specify the text color.  The supported color names are those of
+    HTML 4.0 and "#RRGGBB" notation.
+
+    <li> -bg BACKGROUND
+
+    Specify the background color.  The supported color names are the
+    same as FOREGROUND, except that if "transparent" is specified,
+    make the background transparent.
+
+    <li> -r
+
+    Specify that the orientation of the text is right-to-left.
 
     <li> -q
 
 
     </ul>
 */
+/***ja
+    @japage m17n-dump ¥Æ¥­¥¹¥È²èÁü¤Î¥À¥ó¥×
+
+    @section m17n-dump-synopsis SYNOPSIS
+
+    m17n-dump [ OPTION ... ] [ FILE ]
+
+    @section m17n-dump-description DESCRIPTION
+
+    ¥Æ¥­¥¹¥È¤ò PNG ²èÁü¤È¤·¤Æ¥À¥ó¥×¤¹¤ë¡£ 
+
+    PNG ²èÁü¤Ï¸½ºß¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ëºî¤é¤ì¤¿ "BASE.png" ¤È¤¤¤¦Ì¾Á°¤Î 
+    ¥Õ¥¡¥¤¥ë¤Ë½ñ¤­¹þ¤Þ¤ì¤ë¡£¤³¤³¤Ç BASE ¤ÏFILE ¤Î basename ¤Ç¤¢¤ë¡£ 
+    FILE ¤¬¾Êά¤µ¤ì¤ì¤Ð¡¢¥Æ¥­¥¹¥È¤Ïɸ½àÆþÎϤ«¤éÆɤޤ졢²èÁü¤Ï 
+    "output.png" ¤Ë¥À¥ó¥×¤µ¤ì¤ë¡£
+
+    °Ê²¼¤Î¥ª¥×¥·¥ç¥ó¤¬ÍøÍѤǤ­¤ë¡£
+
+    <ul>
+
+    <li> -s SIZE
+
+    SIZE ¤Ï¥Õ¥©¥ó¥È¤ÎÂ礭¤µ¤ò¥Ý¥¤¥ó¥Èñ°Ì¤Ç¼¨¤·¤¿¤â¤Î¤Ç¤¢¤ë¡£¥Ç¥Õ¥©¥ë
+    ¥È¤ÎÂ礭¤µ¤Ï 12 ¥Ý¥¤¥ó¥È¡£
+
+    <li> -d DPI
+
+    DPI ¤Ï²òÁüÅÙ¤ò£±¥¤¥ó¥Á¤¢¤¿¤ê¤Î¥É¥Ã¥Èñ°Ì¤Ç¼¨¤·¤¿¤â¤Î¤Ç¤¢¤ë¡£¥Ç¥Õ¥© 
+    ¥ë¥È¤Î²òÁüÅ٤Ϡ300 dpi¡£
+
+    <li> -p PAPER
+
+    PAPER ¤Ï¤Ú¡¼¥Ñ¥µ¥¤¥º : a4, a4r, a5, a5r, b5, b5r, letter, WxH ¤Þ¤¿
+    ¤Ï W¡£ WxH ¤Î¾ì¹ç¡¢ W ¤È H ¤ÏÉý¤È¹â¤µ¤ò¥ß¥ê¥á¡¼¥¿Ã±°Ì¤Ç¼¨¤·¤¿¤â¤Î¡£
+    W ¤Î¾ì¹ç¡¢ W ¤ÏÉý¤ò¥ß¥ê¥á¡¼¥¿Ã±°Ì¤Ç¼¨¤·¤¿¤â¤Î¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤¬»ØÄê
+    ¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¢ PAPER ¤¬²èÁü¥µ¥¤¥º¤òÀ©¸Â¤¹ ¤ë¡£FILE ¤¬ 1 ¥Ú¡¼¥¸
+    ¤ËǼ¤Þ¤é¤Ê¤¤¤Û¤ÉÂ礭¤¤¾ì¹ç¤Ï¡¢"BASE.01.png", "BASE.02.png" Åù¤Î̾Á°
+    ¤Î¤Ä¤¤¤¿Ê£¿ô¤Î¥Õ¥¡¥¤¥ë¤¬ºî¤é¤ì¤ë¡£
+
+    <li> -m MARGIN
+
+    MARGIN ¤Ï¿åÊ¿¡¢¿âľ¥Þ¡¼¥¸¥ó¤ò¥ß¥ê¥á¡¼¥¿Ã±°Ì¤Ç¼¨¤·¤¿¤â¤Î¤Ç¤¢¤ë¡£¥Ç 
+    ¥Õ¥©¥ë¥È¤Î¥Þ¡¼¥¸¥ó¤Ï 20 mm¡£PAPER ¤¬»ØÄꤵ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð̵»ë¤µ¤ì¤ë¡£
+
+    <li> -c POS
+
+    POS ¤Ï¥«¡¼¥½¥ë¤Îʸ»ú°ÌÃÖ¡£¥Ç¥Õ¥©¥ë¥È¤Ç¤Ï¡¢¥«¡¼¥½¥ë¤ÏÉÁ¤«¤ì¤Ê¤¤¡£
+
+    <li> -x
+
+    FILE ¤Ï m17n ¥é¥¤¥Ö¥é¥ê¤Î¥·¥ê¥¢¥é¥¤¥ºµ¡Ç½¤Ë¤è¤Ã¤Æºî¤é¤ì¤¿ XML ¥Õ¥¡ 
+    ¥¤¥ë¤Ç¤¢¤ê¡¢²èÁü¤òÀ¸À®¤¹¤ëÁ°¤Ë¥Ç¥·¥ê¥¢¥é¥¤¥º¤µ¤ì¤ë¡£
+
+    <li> -w
+
+    ¸ì¤Î¶­³¦¤Ç²þ¹Ô¤¹¤ë¡£ 
+
+    <li> -f FILTER
+
+    FILTER ¤Ï¥·¥§¥ë¥³¥Þ¥ó¥É¹Ô¤ò´Þ¤àʸ»úÎó¤Ç¤¢¤ë¡£¤³¤Î¥ª¥×¥·¥ç¥ó¤¬»ØÄê
+    ¤µ¤ì¤Æ¤¤¤ì¤Ð¡¢PNG ²èÁü¤Ï¥Õ¥¡¥¤¥ë¤Ë½ñ¤«¤ì¤ë¤Î¤Ç¤Ï¤Ê¤¯¡¢FILTER ¤Ë 
+    É¸½àÆþÎϤȤ·¤ÆÅϤµ¤ì¤ë¡£ FILTER ¤¬ "%s" ¤ò´Þ¤ó¤Ç¤¤¤ì¤Ð¡¢¤½¤ì¤Ï FILE 
+    ¤Î¥Ù¡¼¥¹¥Í¡¼¥à¤ËÃÖ¤­´¹¤¨¤é¤ì¤ë¡£¤³¤Î¥×¥í¥°¥é¥à¤Î¥Ç¥Õ¥©¥ë¥È¤Î¿¶Éñ¤¤
+    ¤È¡¢FILTER ¤Ë "cat > %s.png" ¤ò»ØÄꤷ¤¿¾ì¹ç¤Î¿¶Éñ¤ÏƱ°ì¤Ç¤¢¤ë¡£
+
+    ¤â¤· FILTER ¤¬Ã±¤Ë "-" ¤Ç¤¢¤ì¤Ð¡¢ PNG ²èÁü¤Ï stdout ¤Ë½ÐÎϤµ¤ì¤ë¡£
+
+    <li> -a
+
+    ¥¢¥ó¥Á¥¨¥¤¥ê¥¢¥¹½èÍý¤ò¹Ô¤¦¡£
+
+    <li> --family FAMILY
+
+    ¥Õ¥¡¥ß¥ê¥£Ì¾¤¬ FAMILY ¤Î¥Õ¥©¥ó¥È¤òÍ¥ÀèŪ¤Ë»È¤¦¡£
+
+    <li> --language LANG
+
+    ¸À¸ì LANG ÍѤ˻ØÄꤵ¤ì¤¿¥Õ¥©¥ó¥È¤òÍ¥ÀèŪ¤Ë»È¤¦¡£LANG ¤Ï ISO 630 ¤Î
+    £²Ê¸»ú¥³¡¼¥É¡ÊÎ㡧±Ñ¸ì¤Ï "en" ¡Ë¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡£
+
+    <li> -fg FOREGROUND
+
+    ¥Æ¥­¥¹¥È¤Î¿§¤ò»ØÄꤹ¤ë¡£HTML 4.0 ¤Î¿§¤Î̾Á°¤ª¤è¤Ó "#RRGGBB" µ­Ë¡¤ò
+    ¥µ¥Ý¡¼¥È¡£
+
+    <li> -bg BACKGROUND
+
+    Çطʤ理ò»ØÄꤹ¤ë¡£¥µ¥Ý¡¼¥È¤µ¤ì¤Æ¤¤¤ë¿§¤Î̾Á°¤Ï FOREGROUND Æ±¤¸¡£
+    ¤¿¤À¤·¡¢¤â¤· "transparent" ¤¬»ØÄꤵ¤ì¤¿¤éÇطʤòÆ©ÌÀ¤Ë¤¹¤ë¡£
+
+    <li> -r
+
+    Specify that the orientation of the text is right-to-left.
+
+    <li> -q
+
+    °ìÀڤΥá¥Ã¥»¡¼¥¸¤òɽ¼¨¤·¤Ê¤¤¡£ 
+
+    <li> --version
+
+    ¥Ð¡¼¥¸¥ç¥óÈÖ¹æ¤òɽ¼¨¤¹¤ë¡£
+
+    <li> -h, --help
+
+    ¤³¤Î¥á¥Ã¥»¡¼¥¸¤òɽ¼¨¤¹¤ë¡£ 
+
+    </ul>
+*/
 
 #ifndef FOR_DOXYGEN
 
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <ctype.h>
 #include <libgen.h>
 
-#include <X11/Xlib.h>
+#if defined (HAVE_FREETYPE) && defined (HAVE_GD)
+#include <gd.h>
 
 #include <m17n-gui.h>
 #include <m17n-misc.h>
 
-#define VERSION "1.0"
-
 /* Enumuration of the supported paper types.  */
 enum paper_type
   {
@@ -158,18 +297,18 @@ help_exit (char *prog, int exit_code)
       prog = p;
 
   printf ("Usage: %s [ OPTION ...] [ FILE ]\n", prog);
-  printf ("Dump a text as a Netpbm image into a PBM file.\n");
-  printf ("  The PBM file is created in the current directory\n");
-  printf ("    with the name \"BASE.pbm\" where BASE is the basename of FILE.\n");
+  printf ("Dump a text as a PNG image into a file.\n");
+  printf ("  The PNG file is created in the current directory\n");
+  printf ("    with the name \"BASE.png\" where BASE is the basename of FILE.\n");
   printf ("  If FILE is omitted, text is read from standard input, and\n");
-  printf ("    dumped into the file \"output.pbm\".\n");
+  printf ("    dumped into the file \"output.png\".\n");
   printf ("The following OPTIONs are available.\n");
   printf ("  %-13s %s", "-s SIZE",
-         "Font size in point (default 12).\n");
+         "Font size in 1/10 point (default 120).\n");
   printf ("  %-13s %s", "-d DPI",
          "Resolution in dots per inch (defualt 300).\n");
   printf ("  %-13s %s", "-p PAPER",
-         "Paper size; a4, a4r, a5, a5r, b5, b5r, letter, or WxH.\n");
+         "Paper size; a4, a4r, a5, a5r, b5, b5r, letter, W, or WxH.\n");
   printf ("  %-13s %s", "-m MARGIN",
          "Marginal space in millimeter (default 20).\n");
   printf ("  %-13s %s", "-c POS",
@@ -179,6 +318,17 @@ help_exit (char *prog, int exit_code)
   printf ("  %-13s %s", "-f FILTER",
          "String containing a shell command line to be used as a filter.\n");
   printf ("  %-13s %s", "-w", "Each line is broken at word boundary.\n");
+  printf ("  %-13s %s", "-a", "Enable anti-alias drawing.\n");
+  printf ("  %-13s %s", "--family FAMILY", 
+         "Prefer a font whose family is FAMILY.\n");
+  printf ("  %-13s %s", "--language LANG", 
+         "Prefer a font specified for the langauge LANG.\n");
+  printf ("  %-13s %s", "-r", 
+         "Specify that the orientation of the text is right-to-left.\n");
+  printf ("  %-13s %s", "-fg FOREGROUND",
+         "Specify the text color (HTML 4.0 color names or \"#RRGGBB\").\n");
+  printf ("  %-13s %s", "-bg BACKGROUND",
+         "Specify the background color (\"transparent\" for transparent)\n");
   printf ("  %-13s %s", "-q", "Quiet mode.  Don't print any messages.\n");
   printf ("  %-13s %s", "--version", "Print the version number.\n");
   printf ("  %-13s %s", "-h, --help", "Print this message.\n");
@@ -235,9 +385,9 @@ find_page_end (MFrame *frame, int height, MText *mt, int pos,
          while (to < next)
            {
              mdraw_glyph_info (frame, mt, to, to, control, &info);
-             if (y + info.this.height > height)
+             if (y + info.metrics.height > height)
                break;
-             y += info.this.height;
+             y += info.metrics.height;
              to = info.line_to;
            }
          break;
@@ -250,36 +400,14 @@ find_page_end (MFrame *frame, int height, MText *mt, int pos,
   return to;
 }
 
-
-/* Table to convert a byte of LSBFirst to MSBFirst. */
-char reverse_bit_order[256];
-
-/* Initialize the above table.  */
-
-void
-init_reverse_bit_order ()
-{
-  int i;
-
-  for (i = 0; i < 256; i++)
-    reverse_bit_order[i]
-      = (((i & 1) << 7) | ((i & 2) << 5) | ((i & 4) << 3) | ((i & 8) << 1)
-        | ((i & 16) >> 1) | ((i & 32) >> 3)
-        | ((i & 64) >> 5) | ((i & 128) >> 7));
-}
-
-
 /* Dump the image in IMAGE into a file whose name is generated from
    FILENAME and PAGE_INDEX (if it is not zero).  */
 
 void
-dump_image (XImage *image, char *filename, char *filter,
-           int white_is_zero, int page_index, int quiet_mode)
+dump_image (gdImagePtr image, char *filename, char *filter,
+           int page_index, int quiet_mode)
 {
   FILE *fp;
-  int pbm_bytes_per_line;
-  char *data = image->data;
-  int x, y;
 
   if (page_index)
     {
@@ -291,20 +419,25 @@ dump_image (XImage *image, char *filename, char *filter,
 
   if (filter)
     {
-      char *command = alloca (strlen (filename) + strlen (filter) + 1);
+      if (filter[0] == '-' && filter[1] == '\0')
+       fp = stdout;
+      else
+       {
+         char *command = alloca (strlen (filename) + strlen (filter) + 1);
 
-      sprintf (command, filter, filename);
-      fp = popen (command, "w");
-      if (! fp)
-       FATAL_ERROR ("Can't run the command \"%s\"\n", command);
-      if (! quiet_mode)
-       printf ("Running \"%s\" ... ", command);
+         sprintf (command, filter, filename);
+         fp = popen (command, "w");
+         if (! fp)
+           FATAL_ERROR ("Can't run the command \"%s\"\n", command);
+         if (! quiet_mode)
+           printf ("Running \"%s\" ... ", command);
+       }
     }
   else
     {
       char *fullname = alloca (strlen (filename) + 5);
 
-      sprintf (fullname, "%s.pbm", filename);
+      sprintf (fullname, "%s.png", filename);
       fp = fopen (fullname, "w");
       if (! fp)
        FATAL_ERROR ("Can't write to \"%s\"\n", fullname);
@@ -312,53 +445,12 @@ dump_image (XImage *image, char *filename, char *filter,
        printf ("Writing %s ... ", fullname);
     }
 
-  if (image->bitmap_bit_order != MSBFirst
-      || (image->byte_order != MSBFirst
-         && image->bitmap_unit != 8))
-    {
-      /* We must adjust image->data for PBM.  */
-      int bytes_per_unit = image->bitmap_unit / 8;
-
-      for (y = 0; y < image->height; y++, data += image->bytes_per_line)
-       {
-         char b;
-
-         if (image->byte_order != MSBFirst)
-           {
-             if (reverse_bit_order[0] == 0)
-               init_reverse_bit_order ();
-             if (bytes_per_unit == 2)
-               for (x = 0; x < image->bytes_per_line; x += 2)
-                 b = data[x], data[x] = data[x + 1], data[x + 1] = b;
-             else if (bytes_per_unit == 6)
-               for (x = 0; x < image->bytes_per_line; x += 3)
-                 {
-                   b = data[x], data[x] = data[x + 3], data[x + 3] = b;
-                   x++;
-                   b = data[x], data[x] = data[x + 1], data[x + 1] = b;
-                 }
-           }
-
-         if (image->bitmap_bit_order != MSBFirst)
-           for (x = 0; x < image->bytes_per_line; x++)
-             data[x] = reverse_bit_order[(unsigned char) data[x]];
-         if (! white_is_zero)
-           for (x = 0; x < image->bytes_per_line; x++)
-             data[x] = ~data[x];
-       }
-      /* Reset DATA.  */
-      data = image->data;
-    }
-
-  /* Generate PBM (Portable Bitmap File Format) of P4 format.  */
-  fprintf (fp, "P4\n%d %d\n", image->width, image->height);
-  pbm_bytes_per_line = (image->width + 7) / 8;
-  for (y = 0; y < image->height; y++, data += image->bytes_per_line)
-    fwrite (data, 1, pbm_bytes_per_line, fp);
-
-  fclose (fp);
+  /* Generate PNG.  */
+  gdImagePng (image, fp);
+  if (fp != stderr)
+    fclose (fp);
   if (! quiet_mode)
-    printf (" done (%dx%d)\n", image->width, image->height);
+    printf (" done (%dx%d)\n", image->sx, image->sy);
 }
 
 extern int line_break (MText *mt, int pos, int from, int to, int line, int y);
@@ -366,11 +458,6 @@ extern int line_break (MText *mt, int pos, int from, int to, int line, int y);
 int
 main (int argc, char **argv)
 {
-  Display *display;
-  int screen;
-  GC gc;
-  Pixmap pixmap;
-  XImage *image;
   int fontsize = 120;
   int paper = PAPER_NOLIMIT;
   int dpi = 300;
@@ -381,9 +468,17 @@ main (int argc, char **argv)
   int quiet_mode = 0;
   int break_by_word = 0;
   char *filter = NULL;
-  int i;
   int paper_width, paper_height;
+  int anti_alias = 0;
+  char *family_name = NULL;
+  char *lang_name = NULL;
+  char *fg_color = NULL, *bg_color = NULL;
+  int transparent = 0;
+  int r2l = 0;
+  int i;
   int page_index;
+  gdImagePtr image;
+  int bg_rgb;
 
   MFrame *frame;
   MText *mt;
@@ -391,6 +486,8 @@ main (int argc, char **argv)
   MDrawMetric rect;
   char *filename = "output";
   int len, from;
+  char *fontset_name = "generic";
+
 
   /* Parse the command line arguments.  */
   for (i = 1; i < argc; i++)
@@ -401,8 +498,8 @@ main (int argc, char **argv)
        help_exit (argv[0], 0);
       else if (! strcmp (argv[i], "--version"))
        {
-         printf ("mdump (m17n library) %s\n", VERSION);
-         printf ("Copyright (C) 2003, 2004 AIST, JAPAN\n");
+         printf ("m17n-dump (m17n library) %s\n", M17NLIB_VERSION_NAME);
+         printf ("Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 AIST, JAPAN\n");
          exit (0);
        }
       else if (! strcmp (argv[i], "-s") && i + 1< argc)
@@ -437,6 +534,13 @@ main (int argc, char **argv)
              paper_size[paper].width = w;
              paper_size[paper].height = h;
            }
+         else if (sscanf (argv[i], "%d", &w) == 1
+                  && w > 0)
+           {
+             paper = PAPER_USER;
+             paper_size[paper].width = w;
+             paper_size[paper].height = 0;
+           }
          else
            FATAL_ERROR ("Invalid paper type: %s\n", argv[i]);
        }
@@ -474,6 +578,22 @@ main (int argc, char **argv)
        {
          quiet_mode = 1;
        }
+      else if (! strcmp (argv[i], "-a"))
+       {
+         anti_alias = 1;
+       }
+      else if (! strcmp (argv[i], "--family"))
+       {
+         family_name = argv[++i];
+       }
+      else if (! strcmp (argv[i], "--language"))
+       {
+         lang_name = argv[++i];
+       }
+      else if (! strcmp (argv[i], "-r"))
+       {
+         r2l = 1;
+       }
       else if (argv[i][0] != '-')
        {
          fp = fopen (argv[i], "r");
@@ -481,6 +601,32 @@ main (int argc, char **argv)
            FATAL_ERROR ("Fail to open the file %s!\n", argv[i]);
          filename = basename (argv[i]);
        }
+      else if (! strcmp (argv[i], "--fontset"))
+       {
+         fontset_name = argv[++i];
+       }
+      else if (! strcmp (argv[i], "-fg"))
+       {
+         if (i + 1 == argc)
+           {
+             fprintf (stderr, "Foreground color not specified\n");
+             help_exit (argv[0], 1);
+           }
+         fg_color = argv[++i];
+       }
+      else if (! strcmp (argv[i], "-bg"))
+       {
+         if (i + 1 == argc)
+           {
+             fprintf (stderr, "Background color not specified\n");
+             help_exit (argv[0], 1);
+           }
+         i++;
+         if (! strcmp (argv[i], "transparent"))
+           transparent = 1;
+         else
+           bg_color = argv[i];
+       }
       else
        {
          fprintf (stderr, "Unknown or invalid option: %s\n", argv[i]);
@@ -501,6 +647,8 @@ main (int argc, char **argv)
     FATAL_ERROR ("%s\n", "Fail to decode the input file or stream!");
 
   len = mtext_len (mt);
+  if (lang_name)
+    mtext_put_prop (mt, 0, len, Mlanguage, msymbol (lang_name));
 
   if (paper == PAPER_NOLIMIT)
     paper_width = paper_height = margin = 0;
@@ -511,30 +659,39 @@ main (int argc, char **argv)
       margin = margin * dpi / 25.4;
     }
 
-  display = XOpenDisplay (NULL);
-  screen = DefaultScreen (display);
-
   {
     MPlist *plist = mplist (), *p;
-    MFontset *fontset = mfontset ("truetype");
+    MFontset *fontset = mfontset (fontset_name);
     MFace *face = mface ();
 
     mface_put_prop (face, Mfontset, fontset);
     mface_put_prop (face, Msize, (void *) (fontsize * dpi / 100));
-    p = mplist_add (plist, msymbol ("display"), display);
-    p = mplist_add (p, msymbol ("depth"), (void *) 1);
+    if (family_name)
+      {
+       char *p;
+
+       for (p = family_name; *p; p++)
+         if (isupper (*p)) *p = tolower (*p);
+       mface_put_prop (face, Mfamily, msymbol (family_name));
+      }
+    if (fg_color)
+      mface_put_prop (face, Mforeground, msymbol (fg_color));
+    if (bg_color)
+      mface_put_prop (face, Mbackground, msymbol (bg_color));
+    p = mplist_add (plist, Mdevice, msymbol ("gd"));
     p = mplist_add (p, Mface, face);
     m17n_object_unref (face);
     frame = mframe (plist);
     m17n_object_unref (plist);
     if (! frame)
-      FATAL_ERROR ("%s\n", "Can't open a frame (perhaps no font avairable)!");
+      FATAL_ERROR ("%s\n", "Can't open a frame (perhaps no font available)!");
   }
 
   memset (&control, 0, sizeof control);
-  control.as_image = 1;
   control.two_dimensional = 1;
   control.enable_bidi = 1;
+  control.anti_alias = anti_alias;
+  control.orientation_reversed = r2l;
   if (cursor_pos >= 0)
     {
       control.with_cursor = 1;
@@ -546,7 +703,7 @@ main (int argc, char **argv)
   else
     control.ignore_formatting_char = 1;
   if (break_by_word)
-    control.line_break = line_break;
+    control.line_break = mdraw_default_line_break;
 
   if (paper == PAPER_NOLIMIT)
     {
@@ -556,39 +713,76 @@ main (int argc, char **argv)
       paper_height = rect.height;
     }
   else
-    control.max_line_width = paper_width - margin * 2;
-
-  pixmap = XCreatePixmap (display, RootWindow (display, screen),
-                         paper_width, paper_height, 1);
-  gc = XCreateGC (display, pixmap, 0L, NULL);
+    {
+      control.max_line_width = paper_width - margin * 2;
+      if (paper_height == 0)
+       {
+         mdraw_text_extents (frame, mt, 0, len, &control, NULL, NULL, &rect);
+         paper_height = rect.height + margin * 2;
+       }
+    }
 
+#if HAVE_GD > 1
+  image = gdImageCreateTrueColor (paper_width, paper_height);
+#else
+  image = gdImageCreate (paper_width, paper_height);
+#endif
   from = 0;
   page_index = 1;
+
+  if (transparent)
+    {
+      MFace *face = mframe_get_prop (frame, Mface);
+      MSymbol fg = mface_get_prop (face, Mforeground);
+      int rgb_value = 0;
+
+      if (fg)
+       rgb_value = (int) msymbol_get (fg, msymbol ("  rgb"));
+      if (rgb_value == 0xFFFFFF)
+       bg_rgb = gdImageColorAllocate (image, 0, 0, 0);
+      else
+       bg_rgb = gdImageColorAllocate (image, 255, 255, 255);
+      gdImageColorTransparent (image, bg_rgb);
+#if HAVE_GD > 1
+      gdImageAlphaBlending (image, 0);
+#endif
+    }
+  else
+    {
+      MFace *face = mframe_get_prop (frame, Mface);
+      MSymbol bg = mface_get_prop (face, Mbackground);
+      if (bg)
+       {
+         int rgb_value = (int) msymbol_get (bg, msymbol ("  rgb"));
+         bg_rgb = gdImageColorAllocate (image, rgb_value >> 16, 
+                                        (rgb_value >> 8) & 255, 
+                                        rgb_value & 255);
+       }
+      else
+       bg_rgb = gdImageColorAllocate (image, 255, 255, 255);
+    }
+
   while (from < len)
     {
       int to;
 
-      if (paper == PAPER_NOLIMIT)
+      if (paper == PAPER_NOLIMIT || paper_size[paper].height == 0)
        to = len;
       else
        to = find_page_end (frame, paper_height - margin * 2, mt, from,
                            &control, &rect);
 
-      XSetForeground (display, gc, WhitePixel (display, screen));
-      XFillRectangle (display, pixmap, gc, 0, 0, paper_width, paper_height);
-      mdraw_text_with_control (frame, (MDrawWindow) pixmap,
-                              margin, margin - rect.y, mt, from, to,
-                              &control);
-      XSetForeground (display, gc, BlackPixel (display, screen));
-#if 0
-      XDrawRectangle (display, pixmap, gc, margin, margin,
-                     paper_width - margin * 2 - 1,
-                     paper_height - margin * 2 - 1);
-#endif
-      image = XGetImage (display, pixmap, 0, 0, paper_width, paper_height,
-                        AllPlanes, XYPixmap);
-      XInitImage (image);
-      dump_image (image, filename, filter, !WhitePixel (display, screen),
+      gdImageFilledRectangle (image, 0, 0, paper_width - 1, paper_height - 1,
+                             bg_rgb);
+      if (! r2l)
+       mdraw_text_with_control (frame, image,
+                                margin, margin - rect.y,
+                                mt, from, to, &control);
+      else
+       mdraw_text_with_control (frame, image,
+                                paper_width - margin, margin - rect.y,
+                                mt, from, to, &control);
+      dump_image (image, filename, filter,
                  ((from > 0 || to < len) ? page_index : 0),
                  quiet_mode);
 
@@ -599,7 +793,18 @@ main (int argc, char **argv)
   m17n_object_unref (frame);
   m17n_object_unref (mt);
   M17N_FINI ();
-  XCloseDisplay (display);
+  gdImageDestroy (image);
   exit (0);
 }
+
+#else  /* not HAVE_FREETYPE nor HAVE_GD */
+
+int
+main (int argc, char **argv)
+{
+  fprintf (stderr, "Can't run without Freetype and GD library!\n");
+  exit (1);
+}
+
+#endif  /* not HAVE_FREETYPE nor HAVE_GD */
 #endif /* not FOR_DOXYGEN */