From: Ben Pfaff Date: Wed, 8 Feb 2023 22:28:54 +0000 (-0800) Subject: output: Use page_setup for parsing cairo page setup. X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=29b393e13c61b9e7925493166d0f6b8cf0d30045;p=pspp output: Use page_setup for parsing cairo page setup. This will make it easier to add page_setup support to the SPV driver. --- diff --git a/src/language/tests/paper-size.c b/src/language/tests/paper-size.c index 0322f5728b..bccc60f794 100644 --- a/src/language/tests/paper-size.c +++ b/src/language/tests/paper-size.c @@ -29,7 +29,7 @@ int 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; @@ -37,9 +37,7 @@ cmd_debug_paper_size (struct lexer *lexer, struct dataset *ds UNUSED) 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); diff --git a/src/output/cairo.c b/src/output/cairo.c index 8ef2b09536..bdc500e54b 100644 --- a/src/output/cairo.c +++ b/src/output/cairo.c @@ -182,35 +182,34 @@ parse_font_option (struct driver_options *options, 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); @@ -219,11 +218,6 @@ xr_allocate (const char *name, int device_type, 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); @@ -243,8 +237,8 @@ xr_allocate (const char *name, int device_type, .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, @@ -276,6 +270,8 @@ xr_allocate (const char *name, int device_type, .trim = trim, }; + page_setup_destroy (ps); + return xr; } diff --git a/src/output/measure.c b/src/output/measure.c index 65d9fdddf2..1ae1d31fa1 100644 --- a/src/output/measure.c +++ b/src/output/measure.c @@ -37,28 +37,26 @@ #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; @@ -69,13 +67,12 @@ 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; @@ -104,16 +101,15 @@ measure_paper (const char *size, int *h, int *v) /* 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; } -/* 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) { @@ -125,12 +121,12 @@ 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; @@ -142,18 +138,15 @@ parse_unit (const char *unit) 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; @@ -161,22 +154,22 @@ parse_paper_size (const char *size, int *h, int *v) 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] = { @@ -235,11 +228,10 @@ get_standard_paper_size (struct substring name, int *h, int *v) 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; @@ -280,12 +272,11 @@ read_paper_conf (const char *file_name, int *h, int *v) 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 @@ -300,8 +291,8 @@ get_default_paper_size (int *h, int *v) 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 diff --git a/src/output/measure.h b/src/output/measure.h index 4b6fab3805..047f78c50d 100644 --- a/src/output/measure.h +++ b/src/output/measure.h @@ -19,7 +19,7 @@ #include -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 */ diff --git a/src/output/options.c b/src/output/options.c index 227b132aa0..52bfa81aad 100644 --- a/src/output/options.c +++ b/src/output/options.c @@ -57,10 +57,10 @@ driver_option_get (struct driver_options *options, }; } -/* 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); @@ -201,8 +201,8 @@ parse_int (struct driver_option o, int min_value, int max_value) } /* 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) diff --git a/src/output/options.h b/src/output/options.h index e8e675f8bc..115e296f3d 100644 --- a/src/output/options.h +++ b/src/output/options.h @@ -47,14 +47,14 @@ struct driver_option driver_option_get (struct driver_options *, 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); diff --git a/src/output/page-setup.c b/src/output/page-setup.c index 4c9c990464..4c3ee8ec87 100644 --- a/src/output/page-setup.c +++ b/src/output/page-setup.c @@ -21,6 +21,8 @@ #include #include +#include "output/options.h" + #include "gl/xalloc.h" bool @@ -95,3 +97,30 @@ page_setup_destroy (struct page_setup *ps) 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; +} diff --git a/src/output/page-setup.h b/src/output/page-setup.h index 95405eff27..6f45db5b25 100644 --- a/src/output/page-setup.h +++ b/src/output/page-setup.h @@ -25,6 +25,8 @@ #include #include "table.h" +struct driver_options; + enum page_orientation { PAGE_PORTRAIT, @@ -84,4 +86,6 @@ struct page_setup 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 */