[cairo-commit] svg2png/src args.c, 1.4, 1.5 args.h, 1.1.1.1, 1.2 svg2png.c, 1.9, 1.10

Jason Dorje Short commit at pdx.freedesktop.org
Sat Aug 13 00:41:24 PDT 2005


Committed by: jdorje

Update of /cvs/cairo/svg2png/src
In directory gabe:/tmp/cvs-serv28275/src

Modified Files:
	args.c args.h svg2png.c 
Log Message:
Rewrite the command-line parameters to be more powerful and roughly
compatible with rsvg/inkscape/sodipodi.


Index: args.c
===================================================================
RCS file: /cvs/cairo/svg2png/src/args.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- args.c	26 Apr 2005 20:03:33 -0000	1.4
+++ args.c	13 Aug 2005 07:41:22 -0000	1.5
@@ -41,24 +41,39 @@
 static const char ARGS_PROGRAM_DESCRIPTION[] = "svg2png - Render an SVG image to a PNG image";
 static const char ARGS_PROGRAM_BUG_ADDRESS[] = "<cworth at isi.edu>";
 
-static const char ARGS_PROGRAM_ARGDOC[] = "[<SVG_file> [<PNG_file>]]";
+static const char ARGS_PROGRAM_ARGDOC[] = "<SVG_file> <PNG_file>";
 
-enum {
-    ARGS_VAL_HELP = 256,
-    ARGS_VAL_FLIPX,
-    ARGS_VAL_FLIPY
+enum args_val {
+    ARGS_VAL_HEIGHT = 'h',
+    ARGS_VAL_WIDTH = 'w',
+    ARGS_VAL_SCALE = 's',
+    ARGS_VAL_XSCALE = 'x',
+    ARGS_VAL_YSCALE = 'y',
+    ARGS_VAL_FLIPX = 'X',
+    ARGS_VAL_FLIPY = 'Y',
+    ARGS_VAL_PAD = 'p',
+    ARGS_VAL_STRETCH = 't',
+    ARGS_VAL_HELP = '?',
+    ARGS_VAL_VERSION = 'V'
 };
 
-static const char args_optstring[] = "h:s:w:xyV";
+static const char args_optstring[] = "h:w:s:x:y:XYpt?V";
 static struct option args_options[] = {
     /* name,		has_arg,	flag,	val */
-    {"height",		1,		0,	'h'},
-    {"scale",		1,		0,	's'},
-    {"width",		1,		0,	'w'},
+    {"height",		1,		0,	ARGS_VAL_HEIGHT},
+    {"width",		1,		0,	ARGS_VAL_WIDTH},
+    {"scale",		1,		0,	ARGS_VAL_SCALE},
+    {"xscale",          1,              0,      ARGS_VAL_XSCALE},
+    {"yscale",          1,              0,      ARGS_VAL_YSCALE},
+
     {"flipx",		0,		0,	ARGS_VAL_FLIPX},
     {"flipy",		0,		0,	ARGS_VAL_FLIPY},
+
+    {"pad",             0,              0,      ARGS_VAL_PAD},
+    {"stretch",         0,              0,      ARGS_VAL_STRETCH},
+
     {"help",		0,		0,	ARGS_VAL_HELP},
-    {"version",		0,		0,	'V'},
+    {"version",		0,		0,	ARGS_VAL_VERSION},
     { 0 }
 };
 
@@ -71,14 +86,40 @@
     printf ("Usage: %s [OPTIONS] %s\n", argv0_base, ARGS_PROGRAM_ARGDOC);
     printf ("%s - %s\n", argv0_base, ARGS_PROGRAM_DESCRIPTION);
     puts ("");
+    printf ("<SVG_file> may be - to read from standard input.\n");
+    printf ("<PNG_file> may be - to write to standard output.\n");
+    puts ("");
+#if 0
+    printf ("By default the image will be rendered at the SVG file's default\n");
+    printf ("size. This can be controlled by the following options:\n");
+#endif
     printf ("  -w, --width=WIDTH\tWidth of output image in pixels\n");
     printf ("  -h, --height=HEIGHT\tHeight of output image in pixels\n");
     printf ("  -s, --scale=FACTOR\tScale image by FACTOR\n");
+    printf ("  -x, --xscale=FACTOR\tScale image width by FACTOR\n");
+    printf ("  -y, --yscale=FACTOR\tScale image height by FACTOR\n");
     puts ("");
-    printf ("  --flipx\t\tFlip X coordinates of image\n");
-    printf ("  --flipy\t\tFlip Y coordinates of image\n");
+#if 0
+    printf ("Options to flip the image:\n");
+#endif
+    printf ("  -X, --flipx\t\tFlip X coordinates of image\n");
+    printf ("  -Y, --flipy\t\tFlip Y coordinates of image\n");
     puts ("");
-    printf ("  --help\t\tGive this help list\n");
+#if 0
+    printf ("These options control the behavior when given a non-default aspect\n");
+    printf ("ratio.  The default is to render within the given width/height\n");
+    printf ("without any padding and preserving the aspect ratio.  The pad\n");
+    printf ("option will pad the image to the width/height while still preserving\n");
+    printf ("the aspect ratio.  The stretch option will stretch the image and change\n");
+    printf ("the aspect ratio.  These two options are incompatible.\n");
+#endif
+    printf ("  -p, --pad\t\tPad image to width/height (default off)\n");
+    printf ("  -t, --stretch\t\tStretch image to width/height (default off)\n");
+    puts ("");
+#if 0
+    printf ("Program information options:\n");
+#endif
+    printf ("  -?, --help\t\tGive this help list\n");
     printf ("  -V, --version\t\tPrint program version\n");
 
     free (argv0_copy);
@@ -101,33 +142,42 @@
 {
     int c;
 
-    args->svg_filename = "-";
-    args->png_filename = "-";
-    args->scale = 1.0;
+    args->svg_filename = "";
+    args->png_filename = "";
 
+    /* These must be initialized to negative values so the rendering code
+       knows to ignore them if they're unset. */
+    args->scale = -1.0;
+    args->xscale = -1.0;
+    args->yscale = -1.0;
     args->width = -1;
     args->height = -1;
+
     args->flipx = 0;
     args->flipy = 0;
+    args->pad = 0;
+    args->stretch = 0;
 
     while (1) {
 	c = getopt_long (argc, argv, args_optstring, args_options, NULL);
 	if (c == -1)
 	    break;
 
-	switch (c) {
-	case 'h':
+	switch ((enum args_val)c) {
+	case ARGS_VAL_HEIGHT:
 	    args->height = atoi (optarg);
 	    break;
-	case 's':
+	case ARGS_VAL_WIDTH:
+	    args->width = atoi (optarg);
+	    break;
+	case ARGS_VAL_SCALE:
 	    args->scale = atof (optarg);
 	    break;
-	case 'w':
-	    args->width = atoi (optarg);
+	case ARGS_VAL_XSCALE:
+	    args->xscale = atof (optarg);
 	    break;
-	case 'V':
-	    printf ("%s\n", ARGS_PROGRAM_VERSION);
-	    exit (0);
+	case ARGS_VAL_YSCALE:
+	    args->yscale = atof(optarg);
 	    break;
 	case ARGS_VAL_FLIPX:
 	    args->flipx = 1;
@@ -135,21 +185,27 @@
 	case ARGS_VAL_FLIPY:
 	    args->flipy = 1;
 	    break;
+	case ARGS_VAL_PAD:
+	    args->pad = 1;
+	    break;
+	case ARGS_VAL_STRETCH:
+	    args->stretch = 1;
+	    break;
 	case ARGS_VAL_HELP:
 	    args_help (argv[0]);
 	    exit (0);
 	    break;
-	case '?':
-	    args_help (argv[0]);
-	    exit (1);
-	    break;
-	default:
-	    fprintf (stderr, "Unhandled option: %d\n", c);
-	    exit (1);
+	case ARGS_VAL_VERSION:
+	    printf ("%s\n", ARGS_PROGRAM_VERSION);
+	    exit (0);
 	    break;
 	}
     }
-	
+
+    if (argc - optind < 2) {
+        args_help (argv[0]);
+        exit(1);
+    }
     if (argc - optind >= 1) {
 	args->svg_filename = argv[optind++];
 	if (argc - optind >= 1) {

Index: args.h
===================================================================
RCS file: /cvs/cairo/svg2png/src/args.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -d -r1.1.1.1 -r1.2
--- args.h	27 Apr 2004 02:10:02 -0000	1.1.1.1
+++ args.h	13 Aug 2005 07:41:22 -0000	1.2
@@ -35,10 +35,18 @@
     char *png_filename;
 
     double scale;
+    double xscale;
+    double yscale;
+
+    double dpi;
+
     int width;
     int height;
+
     int flipx;
     int flipy;
+    int pad;
+    int stretch;
 } args_t;
 
 int

Index: svg2png.c
===================================================================
RCS file: /cvs/cairo/svg2png/src/svg2png.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -d -r1.9 -r1.10
--- svg2png.c	25 May 2005 16:07:35 -0000	1.9
+++ svg2png.c	13 Aug 2005 07:41:22 -0000	1.10
@@ -40,7 +40,7 @@
 #define MIN(a, b)     (((a) < (b)) ? (a) : (b))
 
 static svg_cairo_status_t
-render_to_png (FILE *svg_file, FILE *png_file, double scale, int width, int height);
+render_to_png (FILE *svg_file, FILE *png_file, const args_t *args);
 
 int 
 main (int argc, char **argv)
@@ -72,7 +72,7 @@
 	}
     }
 	       
-    status = render_to_png (svg_file, png_file, args.scale, args.width, args.height);
+    status = render_to_png (svg_file, png_file, &args);
     if (status) {
 	fprintf (stderr, "%s: failed to render %s\n", argv[0], args.svg_filename);
 	return 1;
@@ -114,9 +114,11 @@
 }
 
 static svg_cairo_status_t
-render_to_png (FILE *svg_file, FILE *png_file, double scale, int width, int height)
+render_to_png (FILE *svg_file, FILE *png_file, const args_t *args)
 {
     unsigned int svg_width, svg_height;
+    unsigned int png_width, png_height;
+    double scale, xscale, yscale;
 
     svg_cairo_status_t status;
     cairo_t *cr;
@@ -136,23 +138,71 @@
 
     svg_cairo_get_size (svgc, &svg_width, &svg_height);
 
-    if (width < 0 && height < 0) {
-	width = (svg_width * scale + 0.5);
-	height = (svg_height * scale + 0.5);
-    } else if (width < 0) {
-	scale = (double) height / (double) svg_height;
-	width = (svg_width * scale + 0.5);
-    } else if (height < 0) {
-	scale = (double) width / (double) svg_width;
-	height = (svg_height * scale + 0.5);
+    /* xscale, yscale, or scale <= 0 means no option */
+    scale = args->scale > 0.0 ? args->scale : 1.0;
+    xscale = args->xscale > 0.0 ? args->xscale : args->scale;
+    yscale = args->yscale > 0.0 ? args->yscale : args->scale;
+
+    if (args->width <= 0 && args->height <= 0) {
+        /* Neither width or height are given.  This case is easy; we just
+	 * take the dimensions from the scale (or 1.0) and ignore stretch
+	 * and pad. */
+	png_width = (svg_width * xscale + 0.5);
+	png_height = (svg_height * yscale + 0.5);
+    } else if (args->width <= 0) {
+        /* Height is given but not width.  In this case we ignore the
+	 * scale values and preserve the aspect ratio. */
+        png_height = args->height;
+	xscale = yscale = (double) args->height / (double) svg_height;
+	png_width = (svg_width * xscale + 0.5);
+    } else if (args->height <= 0) {
+        /* Here width is given but not height.  This simply mirrors the 
+	 * case above. */
+        png_width = args->width;
+	xscale = yscale = (double) args->width / (double) svg_width;
+	png_height = (svg_height * yscale + 0.5);
     } else {
-	scale = MIN ((double) width / (double) svg_width, (double) height / (double) svg_height);
-	/* Center the resulting image */
-	dx = (width - (int) (svg_width * scale + 0.5)) / 2;
-	dy = (height - (int) (svg_height * scale + 0.5)) / 2;
+        /* Both width and height are given.  Now we ignore the xscale and
+         * yscale entirely!  But now pad and stretch must be considered. */
+        if (args->stretch) {
+	    /* Stretch the image to meet the given width and height. */
+	    png_width = args->width;
+	    png_height = args->height;
+	    xscale = (double) png_width / (double) svg_width;
+	    yscale = (double) png_height / (double) svg_height;
+	} else if (args->pad) {
+	    /* Make the PNG file of the given width and height, while the
+	     * image is centered within the PNG and keeps the same aspect
+	     * ratio. */
+	    png_width = args->width;
+	    png_height = args->height;
+
+	    xscale = yscale = MIN ((double) png_width / (double) svg_width,
+				   (double) png_height / (double) svg_height);
+
+	    /* Center the resulting image */
+	    dx = (png_width - (int) (svg_width * xscale + 0.5)) / 2.0;
+	    dy = (png_height - (int) (svg_height * yscale + 0.5)) / 2.0;
+	} else {
+	    /* Neither stretch nor pad.  Now the aspect ratio is preserved
+	     * and width/height are taken as the max possible dimensions. */
+	    xscale = yscale = MIN ((double) args->width / (double) svg_width,
+				   (double) args->height / (double) svg_height);
+	    png_width = (svg_width * xscale + 0.5);
+	    png_height = (svg_height * yscale + 0.5);
+	}
+    }
+    if (args->flipx) {
+      xscale = -1.0 * xscale;
+      dx = png_width - dx;
+    }
+    if (args->flipy) {
+      yscale = -1.0 * yscale;
+      dy = png_height - dy;
     }
 
-    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
+    surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32,
+					  png_width, png_height);
     cr = cairo_create (surface);
     
     cairo_save (cr);
@@ -161,7 +211,7 @@
     cairo_restore (cr);
 
     cairo_translate (cr, dx, dy);
-    cairo_scale (cr, scale, scale);
+    cairo_scale (cr, xscale, yscale);
 
     /* XXX: This probably doesn't need to be here (eventually) */
     cairo_set_source_rgb (cr, 1, 1, 1);




More information about the cairo-commit mailing list