[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