From: Florian Forster Date: Mon, 20 Dec 2010 09:55:50 +0000 (+0100) Subject: src/sn-tex.c: Make it possible to specify the absolute width of the graphic. X-Git-Tag: v1.0.0~11 X-Git-Url: https://git.verplant.org/?a=commitdiff_plain;h=807591e0b3c3f9efe3914da0efa688781b0abab8;p=sort-networks.git src/sn-tex.c: Make it possible to specify the absolute width of the graphic. --- diff --git a/src/sn-svg.c b/src/sn-svg.c index ee60e80..47d7f93 100644 --- a/src/sn-svg.c +++ b/src/sn-svg.c @@ -21,6 +21,13 @@ #include "config.h" +#ifndef _ISOC99_SOURCE +# define _ISOC99_SOURCE +#endif +#ifndef _POSIX_C_SOURCE +# define _POSIX_C_SOURCE 200112L +#endif + #include #include #include @@ -70,7 +77,7 @@ static int read_options (int argc, char **argv) /* {{{ */ return (0); } /* }}} int read_options */ -static double determine_stage_width (sn_stage_t *s) +static double determine_stage_width (sn_stage_t *s) /* {{{ */ { int lines[s->comparators_num]; int right[s->comparators_num]; @@ -103,7 +110,7 @@ static double determine_stage_width (sn_stage_t *s) assert (lines_used >= 1); return (((double) (lines_used - 1)) * INNER_SPACING); -} +} /* }}} double determine_stage_width */ static double determine_network_width (sn_network_t *n) /* {{{ */ { diff --git a/src/sn-tex.c b/src/sn-tex.c index a2c031d..95bf61d 100644 --- a/src/sn-tex.c +++ b/src/sn-tex.c @@ -28,17 +28,114 @@ #include #include - -#define SCALE 0.7 -#define INNER_SPACING 0.35 -#define OUTER_SPACING 1.5 +#include +#include #include "sn_network.h" -static double x_offset = OUTER_SPACING; +/* 21cm (DIN-A4) - 2x3cm Rand = 15cm +static double output_width = 15.0; +static double scale = 1.0; +static double inner_spacing = 0.3; +static double outer_spacing = 1.0; +static double vertical_spacing = 0.8; + +static double x_offset; static int next_vertex_number = 0; -static int tex_show_stage (sn_stage_t *s) +#define INPUT_TO_Y(i) (((double) (i)) * vertical_spacing) + +static void exit_usage (void) /* {{{ */ +{ + printf ("Usage: sn-tex [options] [file]\n" + "\n" + "Valid options are:\n" + " -w Specify the width of the graph (in TikZ default units).\n" + "\n"); + exit (EXIT_FAILURE); +} /* }}} void exit_usage */ + +static int read_options (int argc, char **argv) /* {{{ */ +{ + int option; + + while ((option = getopt (argc, argv, "w:h?")) != -1) + { + switch (option) + { + case 'w': + { + double width = atof (optarg); + if (width <= 0.0) + { + fprintf (stderr, "Invalid width argument: %s\n", optarg); + exit (EXIT_FAILURE); + } + output_width = width; + break; + } + + case 'h': + case '?': + default: + exit_usage (); + } + } + + return (0); +} /* }}} int read_options */ + +static double determine_stage_width (sn_stage_t *s) /* {{{ */ +{ + int lines[s->comparators_num]; + int right[s->comparators_num]; + int lines_used = 0; + int i; + + if (SN_STAGE_COMP_NUM (s) == 0) + return (0.0); + + for (i = 0; i < SN_STAGE_COMP_NUM (s); i++) + { + lines[i] = -1; + right[i] = -1; + } + + for (i = 0; i < SN_STAGE_COMP_NUM (s); i++) + { + int j; + sn_comparator_t *c = SN_STAGE_COMP_GET (s, i); + + for (j = 0; j < lines_used; j++) + if (SN_COMP_LEFT (c) > right[j]) + break; + + lines[i] = j; + right[j] = SN_COMP_RIGHT (c); + if (j >= lines_used) + lines_used = j + 1; + } + assert (lines_used >= 1); + + return (((double) (lines_used - 1)) * inner_spacing); +} /* }}} double determine_stage_width */ + +static double determine_network_width (sn_network_t *n) /* {{{ */ +{ + double width; + int i; + + /* Spacing between stages and at the beginning and end of the network */ + width = (SN_NETWORK_STAGE_NUM (n) + 1) * outer_spacing; + + /* Spacing required within a stage */ + for (i = 0; i < SN_NETWORK_STAGE_NUM (n); i++) + width += determine_stage_width (SN_NETWORK_STAGE_GET (n, i)); + + return (width); +} /* }}} double determine_network_width */ + +static int tex_show_stage (sn_stage_t *s) /* {{{ */ { int lines[s->comparators_num]; int right[s->comparators_num]; @@ -74,57 +171,71 @@ static int tex_show_stage (sn_stage_t *s) if (j >= lines_used) lines_used = j + 1; - printf ("\\node[vertex] (v%i) at (%.2f,%i) {};\n" - "\\node[vertex] (v%i) at (%.2f,%i) {};\n" + printf ("\\node[vertex] (v%i) at (%.2f,%.2f) {};\n" + "\\node[vertex] (v%i) at (%.2f,%.2f) {};\n" "\\path[comp] (v%i) -- (v%i);\n" "\n", - min_num, x_offset + (j * INNER_SPACING), c->min, - max_num, x_offset + (j * INNER_SPACING), c->max, + min_num, x_offset + (j * inner_spacing), INPUT_TO_Y (c->min), + max_num, x_offset + (j * inner_spacing), INPUT_TO_Y (c->max), min_num, max_num); } - x_offset = x_offset + ((lines_used - 1) * INNER_SPACING) + OUTER_SPACING; + x_offset = x_offset + ((lines_used - 1) * inner_spacing) + outer_spacing; return (0); -} /* int tex_show_stage */ +} /* }}} int tex_show_stage */ -int main (int argc, char **argv) +int main (int argc, char **argv) /* {{{ */ { sn_network_t *n; FILE *fh = NULL; + double orig_width; int i; - if (argc == 1) + read_options (argc, argv); + + if ((argc - optind) == 0) fh = stdin; - else if (argc == 2) - fh = fopen (argv[1], "r"); + else if ((argc - optind) == 1) + fh = fopen (argv[optind], "r"); if (fh == NULL) - { - printf ("fh == NULL!\n"); - return (1); - } + exit_usage (); n = sn_network_read (fh); - if (n == NULL) { - printf ("n == NULL!\n"); - return (1); + fprintf (stderr, "Unable to read network from file handle.\n"); + exit (EXIT_FAILURE); + } + + orig_width = determine_network_width (n); + if (orig_width <= 0.0) + { + fprintf (stderr, "determine_network_width returned invalid value %g.\n", + orig_width); + exit (EXIT_FAILURE); } - printf ("\\begin{tikzpicture}[scale=%.2f,auto]\n", SCALE); + scale = output_width / orig_width; + inner_spacing *= scale; + outer_spacing *= scale; + vertical_spacing *= scale; + + x_offset = outer_spacing; + + printf ("\\begin{tikzpicture}[auto]\n"); for (i = 0; i < SN_NETWORK_STAGE_NUM (n); i++) tex_show_stage (SN_NETWORK_STAGE_GET (n, i)); for (i = 0; i < SN_NETWORK_INPUT_NUM (n); i++) - printf ("\\path[edge] (0,%i) -- (%.2f,%i);\n", - i, x_offset, i); + printf ("\\path[edge] (0,%.2f) -- (%.2f,%.2f);\n", + INPUT_TO_Y (i), x_offset, INPUT_TO_Y (i)); printf ("\\end{tikzpicture}\n"); return (0); -} /* int main */ +} /* }}} int main */ -/* vim: set shiftwidth=2 softtabstop=2 : */ +/* vim: set shiftwidth=2 softtabstop=2 fdm=marker : */