+/* Parse color information specified by KEY into {RED,GREEN,BLUE}.
+ Currently, the input string must be of the form "#RRRRGGGGBBBB"
+ Future implementations might allow things like "yellow" and
+ "sky-blue-ultra-brown"
+*/
+void
+parse_color (struct output_driver *d, struct string_map *options,
+ const char *key, const char *default_value,
+ struct xr_color *color)
+{
+ int red, green, blue;
+ char *string = parse_string (opt (d, options, key, default_value));
+
+ if (3 != sscanf (string, "#%04x%04x%04x", &red, &green, &blue))
+ {
+ /* If the parsed option string fails, then try the default value */
+ if ( 3 != sscanf (default_value, "#%04x%04x%04x", &red, &green, &blue))
+ {
+ /* ... and if that fails set everything to zero */
+ red = green = blue = 0;
+ }
+ }
+
+ free (string);
+
+ /* Convert 16 bit ints to float */
+ color->red = red / (double) 0xFFFF;
+ color->green = green / (double) 0xFFFF;
+ color->blue = blue / (double) 0xFFFF;
+}
+
+static PangoFontDescription *
+parse_font (struct output_driver *d, struct string_map *options,
+ const char *key, const char *default_value,
+ int default_size)
+{
+ PangoFontDescription *desc;
+ char *string;
+
+ /* Parse KEY as a font description. */
+ string = parse_string (opt (d, options, key, default_value));
+ desc = pango_font_description_from_string (string);
+ if (desc == NULL)
+ {
+ msg (MW, _("`%s': bad font specification"), string);
+
+ /* Fall back to DEFAULT_VALUE, which had better be a valid font
+ description. */
+ desc = pango_font_description_from_string (default_value);
+ assert (desc != NULL);
+ }
+ free (string);
+
+ /* If the font description didn't include an explicit font size, then set it
+ to DEFAULT_SIZE, which is in inch/72000 units. */
+ if (!(pango_font_description_get_set_fields (desc) & PANGO_FONT_MASK_SIZE))
+ pango_font_description_set_size (desc,
+ (default_size / 1000.0) * PANGO_SCALE);
+
+ return desc;
+}
+
+
+static void
+apply_options (struct xr_driver *xr, struct string_map *o)
+{
+ struct output_driver *d = &xr->driver;
+
+ /* In inch/72000 units used by parse_paper_size() and parse_dimension(). */
+ int left_margin, right_margin;
+ int top_margin, bottom_margin;
+ int paper_width, paper_length;
+ int font_size;
+ int min_break[TABLE_N_AXES];
+
+ /* Scale factor from inch/72000 to inch/(72 * XR_POINT). */
+ const double scale = XR_POINT / 1000.;
+
+ int i;
+
+ for (i = 0; i < XR_N_FONTS; i++)
+ {
+ struct xr_font *font = &xr->fonts[i];
+
+ if (font->desc != NULL)
+ pango_font_description_free (font->desc);
+ }
+
+ font_size = parse_int (opt (d, o, "font-size", "10000"), 1000, 1000000);
+ xr->fonts[XR_FONT_FIXED].desc = parse_font (d, o, "fixed-font", "monospace",
+ font_size);
+ xr->fonts[XR_FONT_PROPORTIONAL].desc = parse_font (d, o, "prop-font",
+ "serif", font_size);
+ xr->fonts[XR_FONT_EMPHASIS].desc = parse_font (d, o, "emph-font",
+ "serif italic", font_size);
+
+ xr->line_gutter = parse_dimension (opt (d, o, "gutter", "3pt")) * scale;
+ xr->line_space = XR_POINT;
+ xr->line_width = XR_POINT / 2;
+ xr->page_number = 0;
+
+ parse_color (d, o, "background-color", "#FFFFFFFFFFFF", &xr->bg);
+ parse_color (d, o, "foreground-color", "#000000000000", &xr->fg);
+
+ /* Get dimensions. */
+ parse_paper_size (opt (d, o, "paper-size", ""), &paper_width, &paper_length);
+ left_margin = parse_dimension (opt (d, o, "left-margin", ".5in"));
+ right_margin = parse_dimension (opt (d, o, "right-margin", ".5in"));
+ top_margin = parse_dimension (opt (d, o, "top-margin", ".5in"));
+ bottom_margin = parse_dimension (opt (d, o, "bottom-margin", ".5in"));
+
+ min_break[H] = parse_dimension (opt (d, o, "min-hbreak", NULL)) * scale;
+ min_break[V] = parse_dimension (opt (d, o, "min-vbreak", NULL)) * scale;
+
+ /* Convert to inch/(XR_POINT * 72). */
+ xr->left_margin = left_margin * scale;
+ xr->right_margin = right_margin * scale;
+ xr->top_margin = top_margin * scale;
+ xr->bottom_margin = bottom_margin * scale;
+ xr->width = (paper_width - left_margin - right_margin) * scale;
+ xr->length = (paper_length - top_margin - bottom_margin) * scale;
+ xr->min_break[H] = min_break[H] >= 0 ? min_break[H] : xr->width / 2;
+ xr->min_break[V] = min_break[V] >= 0 ? min_break[V] : xr->length / 2;
+}
+