This will make it easier to add page_setup support to the SPV driver.
cmd_debug_paper_size (struct lexer *lexer, struct dataset *ds UNUSED)
{
const char *paper_size;
- int h, v;
+ double h, v;
if (!lex_force_string (lexer))
return CMD_FAILURE;
printf ("\"%s\" => ", paper_size);
if (measure_paper (paper_size, &h, &v))
- printf ("%.1f x %.1f in, %.0f x %.0f mm\n",
- h / 72000., v / 72000.,
- h / (72000 / 25.4), v / (72000 / 25.4));
+ printf ("%.1f x %.1f in, %.0f x %.0f mm\n", h, v, h * 25.4, v * 25.4);
else
printf ("error\n");
lex_get (lexer);
return desc;
}
+/* Scale INCHES into inch/(72 * XR_POINT). */
+static int
+scale (double inches)
+{
+ return inches * 72 * XR_POINT + 0.5;
+}
+
static struct xr_driver *
xr_allocate (const char *name, int device_type,
enum xr_output_type output_type, struct driver_options *o)
{
- /* Scale factor from inch/72000 to inch/(72 * XR_POINT). */
- const double scale = XR_POINT / 1000.;
-
- int paper[TABLE_N_AXES];
- parse_paper_size (opt (o, "paper-size", ""), &paper[H], &paper[V]);
- for (int a = 0; a < TABLE_N_AXES; a++)
- paper[a] *= scale;
-
- int margins[TABLE_N_AXES][2];
- margins[H][0] = parse_dimension (opt (o, "left-margin", ".5in")) * scale;
- margins[H][1] = parse_dimension (opt (o, "right-margin", ".5in")) * scale;
- margins[V][0] = parse_dimension (opt (o, "top-margin", ".5in")) * scale;
- margins[V][1] = parse_dimension (opt (o, "bottom-margin", ".5in")) * scale;
+ struct page_setup *ps = page_setup_parse (o);
int size[TABLE_N_AXES];
for (int a = 0; a < TABLE_N_AXES; a++)
- size[a] = paper[a] - margins[a][0] - margins[a][1];
+ size[a] = scale (ps->paper[a] - ps->margins[a][0] - ps->margins[a][1]);
int min_break[TABLE_N_AXES];
- min_break[H] = parse_dimension (opt (o, "min-hbreak", NULL)) * scale;
- min_break[V] = parse_dimension (opt (o, "min-vbreak", NULL)) * scale;
+ min_break[H] = scale (parse_dimension (opt (o, "min-hbreak", NULL)));
+ min_break[V] = scale (parse_dimension (opt (o, "min-vbreak", NULL)));
for (int a = 0; a < TABLE_N_AXES; a++)
if (min_break[a] <= 0)
min_break[a] = size[a] / 2;
+ int object_spacing = scale (ps->object_spacing);
+ if (object_spacing <= 0)
+ object_spacing = scale (12.0 / 72.0);
+
int font_size = parse_int (opt (o, "font-size", "10000"), 1000, 1000000);
PangoFontDescription *font = parse_font_option (
o, "prop-font", "Sans Serif", font_size, false, false);
bool systemcolors = parse_boolean (opt (o, "systemcolors", "false"));
- int object_spacing
- = parse_dimension (opt (o, "object-spacing", NULL)) * scale;
- if (object_spacing <= 0)
- object_spacing = XR_POINT * 12;
-
const char *default_resolution = (output_type == XR_PNG ? "96" : "72");
int font_resolution = parse_int (opt (o, "font-resolution",
default_resolution), 10, 1000);
.ref_cnt = 1,
.margins = {
- [H] = { margins[H][0], margins[H][1], },
- [V] = { margins[V][0], margins[V][1], },
+ [H] = { scale (ps->margins[H][0]), scale (ps->margins[H][1]) },
+ [V] = { scale (ps->margins[V][0]), scale (ps->margins[V][1]) },
},
.initial_page_number = 1,
.trim = trim,
};
+ page_setup_destroy (ps);
+
return xr;
}
#define _(msgid) gettext (msgid)
static double parse_unit (const char *);
-static bool parse_paper_size (const char *, int *h, int *v);
-static bool get_standard_paper_size (struct substring name, int *h, int *v);
-static bool read_paper_conf (const char *file_name, int *h, int *v);
-static bool get_default_paper_size (int *h, int *v);
-
-/* Determines the size of a dimensional measurement and returns
- the size in units of 1/72000". Units are assumed to be
- millimeters unless otherwise specified. Returns -1 on
- error. */
-int
+static bool parse_paper_size (const char *, double *h, double *v);
+static bool get_standard_paper_size (struct substring name,
+ double *h, double *v);
+static bool read_paper_conf (const char *file_name, double *h, double *v);
+static bool get_default_paper_size (double *h, double *v);
+
+/* Determines the size of a dimensional measurement and returns the size in
+ inches. Units are assumed to be millimeters unless otherwise specified.
+ Returns -1 on error. */
+double
measure_dimension (const char *dimen)
{
- double raw, factor;
- char *tail;
-
/* Number. */
- raw = c_strtod (dimen, &tail);
+ char *tail;
+ double raw = c_strtod (dimen, &tail);
if (raw < 0.0)
goto syntax_error;
/* Unit. */
- factor = parse_unit (tail);
+ double factor = parse_unit (tail);
if (factor == 0.0)
goto syntax_error;
return -1;
}
-/* Stores the dimensions, in 1/72000" units, of paper identified
- by SIZE into *H and *V. SIZE can be the name of a kind of
- paper ("a4", "letter", ...) or a pair of dimensions
- ("210x297", "8.5x11in", ...). Returns true on success, false
+/* Stores the dimensions, in inches, of paper identified by SIZE into *H and
+ *V. SIZE can be the name of a kind of paper ("a4", "letter", ...) or a pair
+ of dimensions ("210x297", "8.5x11in", ...). Returns true on success, false
on failure. On failure, *H and *V are set for A4 paper. */
bool
-measure_paper (const char *size, int *h, int *v)
+measure_paper (const char *size, double *h, double *v)
{
struct substring s;
bool ok;
/* Default to A4 on error. */
if (!ok)
{
- *h = 210 * (72000 / 25.4);
- *v = 297 * (72000 / 25.4);
+ *h = 210 / 25.4;
+ *v = 297 / 25.4;
}
return ok;
}
\f
-/* Parses UNIT as a dimensional unit. Returns the multiplicative
- factor needed to change a quantity measured in that unit into
- 1/72000" units. If UNIT is empty, it is treated as
- millimeters. If the unit is unrecognized, returns 0. */
+/* Parses UNIT as a dimensional unit. Returns the multiplicative factor needed
+ to change a quantity measured in that unit into inches. If UNIT is empty,
+ it is treated as millimeters. If the unit is unrecognized, returns 0. */
static double
parse_unit (const char *unit)
{
static const struct unit units[] =
{
- {"pt", 72000 / 72},
- {"pc", 72000 / 72 * 12.0},
- {"in", 72000},
- {"cm", 72000 / 2.54},
- {"mm", 72000 / 25.4},
- {"", 72000 / 25.4},
+ {"pt", 1.0 / 72.0},
+ {"pc", 12.0 / 72.0},
+ {"in", 1.0},
+ {"cm", 1.0 / 2.54},
+ {"mm", 1.0 / 25.4},
+ {"", 1.0 / 25.4},
};
const struct unit *p;
return 0.0;
}
-/* Stores the dimensions in 1/72000" units of paper identified by
- SIZE, which is of form `HORZ x VERT [UNIT]' where HORZ and
- VERT are numbers and UNIT is an optional unit of measurement,
- into *H and *V. Return true on success. */
+/* Stores the dimensions, in inches, identified by SIZE, which is of form `HORZ
+ x VERT [UNIT]' where HORZ and VERT are numbers and UNIT is an optional unit
+ of measurement, into *H and *V. Return true on success. */
static bool
-parse_paper_size (const char *size, int *h, int *v)
+parse_paper_size (const char *size, double *h, double *v)
{
- double raw_h, raw_v, factor;
- char *tail;
-
/* Width. */
- raw_h = c_strtod (size, &tail);
+ char *tail;
+ double raw_h = c_strtod (size, &tail);
if (raw_h <= 0.0)
return false;
tail += strspn (tail, CC_SPACES "x,");
/* Length. */
- raw_v = c_strtod (tail, &tail);
+ double raw_v = c_strtod (tail, &tail);
if (raw_v <= 0.0)
return false;
/* Unit. */
- factor = parse_unit (tail);
+ double factor = parse_unit (tail);
if (factor == 0.0)
return false;
- *h = raw_h * factor + .5;
- *v = raw_v * factor + .5;
+ *h = raw_h * factor;
+ *v = raw_v * factor;
return true;
}
static bool
-get_standard_paper_size (struct substring name, int *h, int *v)
+get_standard_paper_size (struct substring name, double *h, double *v)
{
static const char *sizes[][2] =
{
return false;
}
-/* Reads file FILE_NAME to find a paper size. Stores the
- dimensions, in 1/72000" units, into *H and *V. Returns true
- on success, false on failure. */
+/* Reads file FILE_NAME to find a paper size. Stores the dimensions, in
+ inches, into *H and *V. Returns true on success, false on failure. */
static bool
-read_paper_conf (const char *file_name, int *h, int *v)
+read_paper_conf (const char *file_name, double *h, double *v)
{
struct string line = DS_EMPTY_INITIALIZER;
int line_number = 0;
return false;
}
-/* The user didn't specify a paper size, so let's choose a
- default based on his environment. Stores the
- dimensions, in 1/72000" units, into *H and *V. Returns true
- on success, false on failure. */
+/* The user didn't specify a paper size, so let's choose a default based on his
+ environment. Stores the dimensions, in inches, into *H and *V. Returns
+ true on success, false on failure. */
static bool
-get_default_paper_size (int *h, int *v)
+get_default_paper_size (double *h, double *v)
{
/* libpaper in Debian (and other distributions?) allows the
paper size to be specified in $PAPERSIZE or in a file
The (int)(intptr_t) cast is for 64 Bit Systems where intptr_t
translates to 64 Bit long int but the upper 32 Bits have wrong
values. The result from nl_langinfo is integer (32 Bit) */
- *h = (int)(intptr_t) nl_langinfo(_NL_PAPER_WIDTH) * (72000 / 25.4);
- *v = (int)(intptr_t) nl_langinfo(_NL_PAPER_HEIGHT) * (72000 / 25.4);
+ *h = (int)(intptr_t) nl_langinfo(_NL_PAPER_WIDTH) / 25.4;
+ *v = (int)(intptr_t) nl_langinfo(_NL_PAPER_HEIGHT) / 25.4;
if (*h > 0 && *v > 0)
return true;
#endif
#include <stdbool.h>
-int measure_dimension (const char *dimen);
-bool measure_paper (const char *size, int *h, int *v);
+double measure_dimension (const char *dimen);
+bool measure_paper (const char *size, double *h, double *v);
#endif /* output/measure.h */
};
}
-/* Stores the paper size of the value of option O into *H and *V, in 1/72000"
- units. Any syntax accepted by measure_paper() may be used. */
+/* Stores the paper size of the value of option O into *H and *V, in inches.
+ Any syntax accepted by measure_paper() may be used. */
void
-parse_paper_size (struct driver_option o, int *h, int *v)
+parse_paper_size (struct driver_option o, double *h, double *v)
{
if (!o.value || !measure_paper (o.value, h, v))
measure_paper (o.default_value, h, v);
}
/* Parses O's value as a dimension, as understood by measure_dimension(), and
- returns its length in units of 1/72000". */
-int
+ returns its length in inches. */
+double
parse_dimension (struct driver_option o)
{
return (o.value ? measure_dimension (o.value)
const char *name,
const char *default_value);
-void parse_paper_size (struct driver_option, int *h, int *v);
+void parse_paper_size (struct driver_option, double *h, double *v);
bool parse_boolean (struct driver_option);
int parse_enum (struct driver_option, ...) SENTINEL(0);
#define parse_enum(...) parse_enum(__VA_ARGS__, NULL_SENTINEL)
int parse_int (struct driver_option, int min_value, int max_value);
-int parse_dimension (struct driver_option);
+double parse_dimension (struct driver_option);
char *parse_string (struct driver_option);
char *parse_chart_file_name (struct driver_option);
#include <stdlib.h>
#include <string.h>
+#include "output/options.h"
+
#include "gl/xalloc.h"
bool
free (ps);
}
}
+
+static struct driver_option
+opt (struct driver_options *options, const char *key, const char *default_value)
+{
+ return driver_option_get (options, key, default_value);
+}
+
+struct page_setup *
+page_setup_parse (struct driver_options *o)
+{
+ struct page_setup *ps = xmalloc (sizeof *ps);
+ *ps = (struct page_setup) PAGE_SETUP_INITIALIZER;
+
+ enum { H = TABLE_HORZ, V = TABLE_VERT };
+ parse_paper_size (opt (o, "paper-size", ""), &ps->paper[H], &ps->paper[V]);
+
+ ps->margins[H][0] = parse_dimension (opt (o, "left-margin", ".5in"));
+ ps->margins[H][1] = parse_dimension (opt (o, "right-margin", ".5in"));
+ ps->margins[V][0] = parse_dimension (opt (o, "top-margin", ".5in"));
+ ps->margins[V][1] = parse_dimension (opt (o, "bottom-margin", ".5in"));
+
+ ps->object_spacing = parse_dimension (opt (o, "object-spacing", NULL));
+ if (ps->object_spacing <= 0)
+ ps->object_spacing = 12.0 / 72.0;
+
+ return ps;
+}
#include <stdbool.h>
#include "table.h"
+struct driver_options;
+
enum page_orientation
{
PAGE_PORTRAIT,
struct page_setup *page_setup_clone (const struct page_setup *);
void page_setup_destroy (struct page_setup *);
+struct page_setup *page_setup_parse (struct driver_options *);
+
#endif /* output/page-setup.h */