33#define BEZIERSUBDIVISION 6
45 assert(height !=
NULL);
46 assert(width !=
NULL);
56 fontscale = log10(*width);
57 fontscale += 3.0 - (int)fontscale;
61 fontscale = pow(10.0, fontscale);
101 {
"AB",
"AvantGarde-Demi"},
102 {
"AI",
"AvantGarde-BookOblique"},
103 {
"AR",
"AvantGarde-Book"},
104 {
"AX",
"AvantGarde-DemiOblique"},
105 {
"B ",
"Times-Bold"},
106 {
"BI",
"Times-BoldItalic"},
107 {
"CB",
"Courier-Bold"},
109 {
"CX",
"Courier-BoldOblique"},
111 {
"HB",
"Helvetica-Bold"},
112 {
"HI",
"Helvetica-Oblique"},
113 {
"HX",
"Helvetica-BoldOblique"},
114 {
"Hb",
"Helvetica-Narrow-Bold"},
115 {
"Hi",
"Helvetica-Narrow-Oblique"},
116 {
"Hr",
"Helvetica-Narrow"},
117 {
"Hx",
"Helvetica-Narrow-BoldOblique"},
118 {
"I ",
"Times-Italic"},
119 {
"KB",
"Bookman-Demi"},
120 {
"KI",
"Bookman-LightItalic"},
121 {
"KR",
"Bookman-Light"},
122 {
"KX",
"Bookman-DemiItalic"},
123 {
"NB",
"NewCenturySchlbk-Bold"},
124 {
"NI",
"NewCenturySchlbk-Italic"},
125 {
"NR",
"NewCenturySchlbk-Roman"},
126 {
"NX",
"NewCenturySchlbk-BoldItalic"},
127 {
"PA",
"Palatino-Roman"},
128 {
"PB",
"Palatino-Bold"},
129 {
"PI",
"Palatino-Italic"},
130 {
"PX",
"Palatino-BoldItalic"},
131 {
"R ",
"Times-Roman"},
133 {
"ZD",
"ZapfDingbats"},
138void *
memrchr(
const void *
s,
int c,
size_t n);
140static const void *
memrchr(
const void *
s,
int c,
size_t n) {
142 for (
size_t i = n - 1; i !=
SIZE_MAX; --i) {
161 .size = (size_t)(dash - psname.
data)};
168 for (
size_t i = 0; i < n; i++) {
170 gvprintf(job,
"move to (%.0f, %.0f)",
A[i].x,
A[i].y);
172 gvprintf(job,
"; line to (%.0f, %.0f)",
A[i].x,
A[i].y);
176 gvprintf(job,
"; line to (%.0f, %.0f)",
A[0].x,
A[0].y);
190 gvprintf(job,
"%s Creator: %s version %s (%s)\n",
194 "%s save point size and font\n.nr .S \\n(.s\n.nr DF \\n(.f\n",
207 "%s restore point size and font\n.ps \\n(.S\n.ft \\n(DF\n",
221 static atomic_flag onetime;
222 if (!atomic_flag_test_and_set(&onetime) && job->
rotation && job->
rotation != 90) {
227 const double fontscale =
get_fontscale(job, &height, &width);
228 gvprintf(job,
".PS %.5f %.5f\n", width, height);
230 "%s to change drawing size, multiply the width and height on the .PS line above and the number on the two lines below (rounded to the nearest integer) by a scale factor\n",
232 gvprintf(job,
".nr SF %.0f\nscalethickness = %.0f\n", fontscale, fontscale);
234 "%s don't change anything below this line in this drawing\n",
237 "%s non-fatal run-time pic version determination, version 2\n",
240 "boxrad=2.0 %s will be reset to 0.0 by gpic only\n",
242 gvprintf(job,
"scale=1.0 %s required for comparisons\n",
245 "%s boxrad is now 0.0 in gpic, else it remains 2.0\n",
248 "%s dashwid is 0.1 in 10th Edition, 0.05 in DWB 2 and in gpic\n",
251 "%s fillval is 0.3 in 10th Edition (fill 0 means black), 0.5 in gpic (fill 0 means white), undefined in DWB 2\n",
254 "%s fill has no meaning in DWB 2, gpic can use fill or filled, 10th Edition uses fill only\n",
257 "%s DWB 2 doesn't use fill and doesn't define fillval\n",
260 "%s reset works in gpic and 10th edition, but isn't defined in DWB 2\n",
262 gvprintf(job,
"%s DWB 2 compatibility definitions\n",
265 "if boxrad > 1.0 && dashwid < 0.075 then X\n\tfillval = 1;\n\tdefine fill Y Y;\n\tdefine solid Y Y;\n\tdefine reset Y scale=1.0 Y;\nX\n");
267 gvprintf(job,
"%s GNU pic vs. 10th Edition d\\(e'tente\n",
270 "if fillval > 0.4 then X\n\tdefine setfillval Y fillval = 1 - Y;\n\tdefine bold Y thickness 2 Y;\n");
272 "\t%s if you use gpic and it barfs on encountering \"solid\",\n",
275 "\t%s\tinstall a more recent version of gpic or switch to DWB or 10th Edition pic;\n",
278 "\t%s\tsorry, the groff folks changed gpic; send any complaint to them;\n",
281 "X else Z\n\tdefine setfillval Y fillval = Y;\n\tdefine bold Y Y;\n\tdefine filled Y fill Y;\nZ\n");
283 "%s arrowhead has no meaning in DWB 2, arrowhead = 7 makes filled arrowheads in gpic and in 10th Edition\n",
286 "%s arrowhead is undefined in DWB 2, initially 1 in gpic, 2 in 10th Edition\n",
288 gvprintf(job,
"arrowhead = 7 %s not used by graphviz\n",
291 "%s GNU pic supports a boxrad variable to draw boxes with rounded corners; DWB and 10th Ed. do not\n",
293 gvprintf(job,
"boxrad = 0 %s no rounded corners in graphviz\n",
296 "%s GNU pic supports a linethick variable to set line thickness; DWB and 10th Ed. do not\n",
298 gvprintf(job,
"linethick = 0; oldlinethick = linethick\n");
300 "%s .PS w/o args causes GNU pic to scale drawing to fit 8.5x11 paper; DWB does not\n",
303 "%s maxpsht and maxpswid have no meaning in DWB 2.0, set page boundaries in gpic and in 10th Edition\n",
306 "%s maxpsht and maxpswid are predefined to 11.0 and 8.5 in gpic\n",
308 gvprintf(job,
"maxpsht = %f\nmaxpswid = %f\n", height, width);
311 "define attrs0 %% %%; define unfilled %% %%; define rounded %% %%; define diagonals %% %%\n");
322 assert(name !=
NULL);
329 return strcmp(
font->name, name) == 0;
337 return fabs(size -
font->size) <= 0.5;
342 switch (span->
just) {
363 f = calloc(1,
sizeof(*f));
371 double sz = fmax(span->
font->
size, 1);
373 const double fontscale =
get_fontscale(job, &(
double){0}, &(double){0});
374 gvprintf(job,
".ps %.0f*\\n(SFu/%.0fu\n", sz, fontscale);
379 f = calloc(1,
sizeof(*f));
388 gvprintf(job,
"\" at (%.5f,%.5f);\n", p.
x, p.
y);
396 "ellipse attrs0 %swid %.5f ht %.5f at (%.5f,%.5f);\n",
397 filled ?
"fill " :
"",
412 gvprintf(job,
"move to (%.0f, %.0f)",
A[0].x,
A[0].y);
414 for (
size_t i = 0; i + 3 < n; i += 3) {
416 for (
size_t j = 1; j <= 3; j++) {
Dynamically expanding string buffers.
pointf Bezier(const pointf *V, double t, pointf *Left, pointf *Right)
#define PS2INCH(a_points)
require define api prefix
void agwarningf(const char *fmt,...)
void agerrorf(const char *fmt,...)
char * agnameof(void *)
returns a string descriptor for the object.
Arithmetic helper functions.
int gvputc(GVJ_t *job, int c)
void gvputs_nonascii(GVJ_t *job, const char *s)
int gvputs(GVJ_t *job, const char *s)
void gvprintf(GVJ_t *job, const char *format,...)
static void pic_bezier(GVJ_t *job, pointf *A, size_t n, int filled)
static bool font_name_eq(const font_t *font, const char *name)
does a font have the given name?
static const char * picfontname(strview_t psname)
static void pic_end_graph(GVJ_t *job)
gvplugin_installed_t gvdevice_pic_types[]
static void picptarray(GVJ_t *job, pointf *A, size_t n, int close)
static void pic_polygon(GVJ_t *job, pointf *A, size_t n, int filled)
static void pic_begin_graph(GVJ_t *job)
static gvrender_engine_t pic_engine
static const char troff_comments[]
static gvrender_features_t render_features_pic
static const char picgen_msghdr[]
static const size_t fonttab_size
static void pic_textspan(GVJ_t *job, pointf p, textspan_t *span)
static void pic_ellipse(GVJ_t *job, pointf *A, int filled)
static double get_fontscale(const GVJ_t *job, double *height, double *width)
gvplugin_installed_t gvrender_pic_types[]
static const fontinfo fonttab[]
static const void * memrchr(const void *s, int c, size_t n)
static void pic_comment(GVJ_t *job, char *str)
static void pic_end_page(GVJ_t *job)
static bool font_size_eq(const font_t *font, double size)
does a font have the given size?
static void pic_begin_page(GVJ_t *job)
static const char pic_comments[]
static void pic_polyline(GVJ_t *job, pointf *A, size_t n)
#define BEZIERSUBDIVISION
static gvdevice_features_t device_features_pic
static void unsupported(char *s)
textitem scanner parser str
double size
font point size
a non-owning string reference
const char * data
start of the pointed to string
size_t size
extent of the string in bytes
Non-owning string references.
static bool strview_str_eq(strview_t a, const char *b)
compare a string reference to a string for equality
static strview_t strview(const char *referent, char terminator)
create a string reference
int(* pf)(void *, char *,...)