/* An Encapsulated Postscript Figure creator object. */ /* Last edited on 2020-01-11 01:24:08 by jstolfi */ #ifndef epswr_figure_H #define epswr_figure_H /* This module provides tools to simplify the generation of Encapsulated Postscript (EPS) files containing graphics and text. An EPS file contains a single figure, of arbitrary size. It has a "%%BoundingBox" line at the beginning, no "%%Page" lines, and no explicit "showpage" command. It is usually meant to be included in other documents. Some printers and viewers may not be prepared to handle an isolated EPS file. In what follows, we assume that an EPS file contains a single ``page,'' whose dimensions are given by the "%%BoundingBox". TYPICAL USAGE The typical usage for this interface is { epswr_figure_t *epsf = epswr_new_figure(wr, ...); } { epswr_segment(epsf, ...) } { ... other drawing commands ... } { epswr_end_figure(epsf); } */ #define _GNU_SOURCE #include #include typedef enum { HOR = 0, VER = 1 } epswr_axis_t; #define epswr_MAX_SIZE (72000000.0) /* Max figure size in pt (1 million inches), just for paranoia. */ #define mm (72.0/25.4) /* One millimeter in Postscript points. */ #define INF INFINITY /* IEEE plus infinity. */ /* EPS FIGURE OBJECT */ typedef struct epswr_def_figure_t epswr_figure_t; /* A {epswr_figure_t} is an opaque object that can be used to write Postscript commands into an EPS file. It keeps track of some elements of the Postscript graphics state (native, or defined my this module) to reduce the file size and provide a hopefully more intuitive semantics. The graphics operations below, such as {epswr_segment}, take a {epswr_figure_t} as argument, and write the equivelent Postscript language commands to those file(s). There are three main coordinate systems used by this interface. The /Device/ coordinates are always in pt, measured from the lower left corner of the whole EPS figure. These coordinates are usually named {h} (horizontal) and {v} (vertical). The /Client/ coordinates are in units chosen by the user and have arbitrary origin. They are usually named {x} (horizontal) and {y} (vertical). For technical reasons, the scaling factors {dx/dh} and {dy/dv} must always be equal. All Postscript commands written to the file use the Device coordinate system. The conversion from Client to Device coordinates is made by this module, before writing the data to the file. An {epswr_figure_t} also keeps track of two axis-aligned rectangles, the /Device window/ (in Device coordinates) and the /Client window/ (in Client coordinates). The mapping from Client to Device coordinates is the unique biaffine map that takes the Client window to the Device window. The Device window is mirrored in the Postscrip file by four Postscript variables {hMin,hMax,vMin,vMax}. Most drawng commands are clipped to that rectangle. */ /* UTILITIES */ void epswr_check_param ( const char *name, double z, double zMin, double zMax ); /* Checks whether {z} is in the range {[zMin __ zMax]}; aborts with error if not. */ double epswr_round_to_nice(double x); /* Rounds the absolute value of {x} up to a nice value (namely 0.20, 0.25, 0.50, or 1.00 times a power of 10). The sign is preserved. If {x} is already one of those nice values (or too close to one), it should be rounded up to it. As special cases, if {x} is 0, returns 0; if {|x|} is too large, returns {ħINF}. */ double epswr_round_dim_mm(double x_mm, double dpi); /* Interprets {x_mm} as a dimension in millimeters and rounds it to the nearest non-zero even integer multiple of the printer's dot size, as specified by {dpi} (dots per inch). Howeverm, if {x_mm} is exactly zero, the result is zero. If {dpi} is zero, returns {x_mm} itself. */ #endif