Print this page
9718 update mandoc to 1.14.4
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/mandoc/term_ps.c
+++ new/usr/src/cmd/mandoc/term_ps.c
1 -/* $Id: term_ps.c,v 1.85 2017/06/07 17:38:26 schwarze Exp $ */
1 +/* $Id: term_ps.c,v 1.91 2017/11/10 23:42:52 schwarze Exp $ */
2 2 /*
3 3 * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
4 4 * Copyright (c) 2014, 2015, 2016, 2017 Ingo Schwarze <schwarze@openbsd.org>
5 + * Copyright (c) 2017 Marc Espie <espie@openbsd.org>
5 6 *
6 7 * Permission to use, copy, modify, and distribute this software for any
7 8 * purpose with or without fee is hereby granted, provided that the above
8 9 * copyright notice and this permission notice appear in all copies.
9 10 *
10 11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHORS DISCLAIM ALL WARRANTIES
11 12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
13 14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 18 */
18 19 #include "config.h"
19 20
20 21 #include <sys/types.h>
21 22
22 23 #include <assert.h>
23 24 #if HAVE_ERR
24 25 #include <err.h>
25 26 #endif
26 27 #include <stdarg.h>
27 28 #include <stdint.h>
28 29 #include <stdio.h>
29 30 #include <stdlib.h>
30 31 #include <string.h>
31 32 #include <unistd.h>
32 33
33 34 #include "mandoc_aux.h"
34 35 #include "out.h"
35 36 #include "term.h"
36 37 #include "manconf.h"
37 38 #include "main.h"
38 39
39 40 /* These work the buffer used by the header and footer. */
40 41 #define PS_BUFSLOP 128
41 42
42 43 /* Convert PostScript point "x" to an AFM unit. */
43 44 #define PNT2AFM(p, x) \
44 45 (size_t)((double)(x) * (1000.0 / (double)(p)->ps->scale))
45 46
46 47 /* Convert an AFM unit "x" to a PostScript points */
47 48 #define AFM2PNT(p, x) \
48 49 ((double)(x) / (1000.0 / (double)(p)->ps->scale))
49 50
50 51 struct glyph {
51 52 unsigned short wx; /* WX in AFM */
52 53 };
53 54
54 55 struct font {
55 56 const char *name; /* FontName in AFM */
56 57 #define MAXCHAR 95 /* total characters we can handle */
57 58 struct glyph gly[MAXCHAR]; /* glyph metrics */
58 59 };
↓ open down ↓ |
44 lines elided |
↑ open up ↑ |
59 60
60 61 struct termp_ps {
61 62 int flags;
62 63 #define PS_INLINE (1 << 0) /* we're in a word */
63 64 #define PS_MARGINS (1 << 1) /* we're in the margins */
64 65 #define PS_NEWPAGE (1 << 2) /* new page, no words yet */
65 66 #define PS_BACKSP (1 << 3) /* last character was backspace */
66 67 size_t pscol; /* visible column (AFM units) */
67 68 size_t pscolnext; /* used for overstrike */
68 69 size_t psrow; /* visible row (AFM units) */
70 + size_t lastrow; /* psrow of the previous word */
69 71 char *psmarg; /* margin buf */
70 72 size_t psmargsz; /* margin buf size */
71 73 size_t psmargcur; /* cur index in margin buf */
72 74 char last; /* last non-backspace seen */
73 75 enum termfont lastf; /* last set font */
74 76 enum termfont nextf; /* building next font here */
75 77 size_t scale; /* font scaling factor */
76 78 size_t pages; /* number of pages shown */
77 79 size_t lineheight; /* line height (AFM units) */
78 80 size_t top; /* body top (AFM units) */
79 81 size_t bottom; /* body bottom (AFM units) */
82 + const char *medianame; /* for DocumentMedia and PageSize */
80 83 size_t height; /* page height (AFM units */
81 84 size_t width; /* page width (AFM units) */
82 85 size_t lastwidth; /* page width before last ll */
83 86 size_t left; /* body left (AFM units) */
84 87 size_t header; /* header pos (AFM units) */
85 88 size_t footer; /* footer pos (AFM units) */
86 89 size_t pdfbytes; /* current output byte */
87 90 size_t pdflastpg; /* byte of last page mark */
88 91 size_t pdfbody; /* start of body object */
89 92 size_t *pdfobjs; /* table of object offsets */
90 93 size_t pdfobjsz; /* size of pdfobjs */
91 94 };
92 95
93 96 static int ps_hspan(const struct termp *,
94 97 const struct roffsu *);
95 98 static size_t ps_width(const struct termp *, int);
96 99 static void ps_advance(struct termp *, size_t);
97 100 static void ps_begin(struct termp *);
98 101 static void ps_closepage(struct termp *);
99 102 static void ps_end(struct termp *);
100 103 static void ps_endline(struct termp *);
↓ open down ↓ |
11 lines elided |
↑ open up ↑ |
101 104 static void ps_growbuf(struct termp *, size_t);
102 105 static void ps_letter(struct termp *, int);
103 106 static void ps_pclose(struct termp *);
104 107 static void ps_plast(struct termp *);
105 108 static void ps_pletter(struct termp *, int);
106 109 static void ps_printf(struct termp *, const char *, ...)
107 110 __attribute__((__format__ (__printf__, 2, 3)));
108 111 static void ps_putchar(struct termp *, char);
109 112 static void ps_setfont(struct termp *, enum termfont);
110 113 static void ps_setwidth(struct termp *, int, int);
111 -static struct termp *pspdf_alloc(const struct manoutput *);
114 +static struct termp *pspdf_alloc(const struct manoutput *, enum termtype);
112 115 static void pdf_obj(struct termp *, size_t);
113 116
114 117 /*
115 118 * We define, for the time being, three fonts: bold, oblique/italic, and
116 119 * normal (roman). The following table hard-codes the font metrics for
117 120 * ASCII, i.e., 32--127.
118 121 */
119 122
120 123 static const struct font fonts[TERMFONT__MAX] = {
121 124 { "Times-Roman", {
122 125 { 250 },
123 126 { 333 },
124 127 { 408 },
125 128 { 500 },
126 129 { 500 },
127 130 { 833 },
128 131 { 778 },
129 132 { 333 },
130 133 { 333 },
131 134 { 333 },
132 135 { 500 },
133 136 { 564 },
134 137 { 250 },
135 138 { 333 },
136 139 { 250 },
137 140 { 278 },
138 141 { 500 },
139 142 { 500 },
140 143 { 500 },
141 144 { 500 },
142 145 { 500 },
143 146 { 500 },
144 147 { 500 },
145 148 { 500 },
146 149 { 500 },
147 150 { 500 },
148 151 { 278 },
149 152 { 278 },
150 153 { 564 },
151 154 { 564 },
152 155 { 564 },
153 156 { 444 },
154 157 { 921 },
155 158 { 722 },
156 159 { 667 },
157 160 { 667 },
158 161 { 722 },
159 162 { 611 },
160 163 { 556 },
161 164 { 722 },
162 165 { 722 },
163 166 { 333 },
164 167 { 389 },
165 168 { 722 },
166 169 { 611 },
167 170 { 889 },
168 171 { 722 },
169 172 { 722 },
170 173 { 556 },
171 174 { 722 },
172 175 { 667 },
173 176 { 556 },
174 177 { 611 },
175 178 { 722 },
176 179 { 722 },
177 180 { 944 },
178 181 { 722 },
179 182 { 722 },
180 183 { 611 },
181 184 { 333 },
182 185 { 278 },
183 186 { 333 },
184 187 { 469 },
185 188 { 500 },
186 189 { 333 },
187 190 { 444 },
188 191 { 500 },
189 192 { 444 },
190 193 { 500},
191 194 { 444},
192 195 { 333},
193 196 { 500},
194 197 { 500},
195 198 { 278},
196 199 { 278},
197 200 { 500},
198 201 { 278},
199 202 { 778},
200 203 { 500},
201 204 { 500},
202 205 { 500},
203 206 { 500},
204 207 { 333},
205 208 { 389},
206 209 { 278},
207 210 { 500},
208 211 { 500},
209 212 { 722},
210 213 { 500},
211 214 { 500},
212 215 { 444},
213 216 { 480},
214 217 { 200},
215 218 { 480},
216 219 { 541},
217 220 } },
218 221 { "Times-Bold", {
219 222 { 250 },
220 223 { 333 },
221 224 { 555 },
222 225 { 500 },
223 226 { 500 },
224 227 { 1000 },
225 228 { 833 },
226 229 { 333 },
227 230 { 333 },
228 231 { 333 },
229 232 { 500 },
230 233 { 570 },
231 234 { 250 },
232 235 { 333 },
233 236 { 250 },
234 237 { 278 },
235 238 { 500 },
236 239 { 500 },
237 240 { 500 },
238 241 { 500 },
239 242 { 500 },
240 243 { 500 },
241 244 { 500 },
242 245 { 500 },
243 246 { 500 },
244 247 { 500 },
245 248 { 333 },
246 249 { 333 },
247 250 { 570 },
248 251 { 570 },
249 252 { 570 },
250 253 { 500 },
251 254 { 930 },
252 255 { 722 },
253 256 { 667 },
254 257 { 722 },
255 258 { 722 },
256 259 { 667 },
257 260 { 611 },
258 261 { 778 },
259 262 { 778 },
260 263 { 389 },
261 264 { 500 },
262 265 { 778 },
263 266 { 667 },
264 267 { 944 },
265 268 { 722 },
266 269 { 778 },
267 270 { 611 },
268 271 { 778 },
269 272 { 722 },
270 273 { 556 },
271 274 { 667 },
272 275 { 722 },
273 276 { 722 },
274 277 { 1000 },
275 278 { 722 },
276 279 { 722 },
277 280 { 667 },
278 281 { 333 },
279 282 { 278 },
280 283 { 333 },
281 284 { 581 },
282 285 { 500 },
283 286 { 333 },
284 287 { 500 },
285 288 { 556 },
286 289 { 444 },
287 290 { 556 },
288 291 { 444 },
289 292 { 333 },
290 293 { 500 },
291 294 { 556 },
292 295 { 278 },
293 296 { 333 },
294 297 { 556 },
295 298 { 278 },
296 299 { 833 },
297 300 { 556 },
298 301 { 500 },
299 302 { 556 },
300 303 { 556 },
301 304 { 444 },
302 305 { 389 },
303 306 { 333 },
304 307 { 556 },
305 308 { 500 },
306 309 { 722 },
307 310 { 500 },
308 311 { 500 },
309 312 { 444 },
310 313 { 394 },
311 314 { 220 },
312 315 { 394 },
313 316 { 520 },
314 317 } },
315 318 { "Times-Italic", {
316 319 { 250 },
317 320 { 333 },
318 321 { 420 },
319 322 { 500 },
320 323 { 500 },
321 324 { 833 },
322 325 { 778 },
323 326 { 333 },
324 327 { 333 },
325 328 { 333 },
326 329 { 500 },
327 330 { 675 },
328 331 { 250 },
329 332 { 333 },
330 333 { 250 },
331 334 { 278 },
332 335 { 500 },
333 336 { 500 },
334 337 { 500 },
335 338 { 500 },
336 339 { 500 },
337 340 { 500 },
338 341 { 500 },
339 342 { 500 },
340 343 { 500 },
341 344 { 500 },
342 345 { 333 },
343 346 { 333 },
344 347 { 675 },
345 348 { 675 },
346 349 { 675 },
347 350 { 500 },
348 351 { 920 },
349 352 { 611 },
350 353 { 611 },
351 354 { 667 },
352 355 { 722 },
353 356 { 611 },
354 357 { 611 },
355 358 { 722 },
356 359 { 722 },
357 360 { 333 },
358 361 { 444 },
359 362 { 667 },
360 363 { 556 },
361 364 { 833 },
362 365 { 667 },
363 366 { 722 },
364 367 { 611 },
365 368 { 722 },
366 369 { 611 },
367 370 { 500 },
368 371 { 556 },
369 372 { 722 },
370 373 { 611 },
371 374 { 833 },
372 375 { 611 },
373 376 { 556 },
374 377 { 556 },
375 378 { 389 },
376 379 { 278 },
377 380 { 389 },
378 381 { 422 },
379 382 { 500 },
380 383 { 333 },
381 384 { 500 },
382 385 { 500 },
383 386 { 444 },
384 387 { 500 },
385 388 { 444 },
386 389 { 278 },
387 390 { 500 },
388 391 { 500 },
389 392 { 278 },
390 393 { 278 },
391 394 { 444 },
392 395 { 278 },
393 396 { 722 },
394 397 { 500 },
395 398 { 500 },
396 399 { 500 },
397 400 { 500 },
398 401 { 389 },
399 402 { 389 },
400 403 { 278 },
401 404 { 500 },
402 405 { 444 },
403 406 { 667 },
404 407 { 444 },
405 408 { 444 },
406 409 { 389 },
407 410 { 400 },
408 411 { 275 },
409 412 { 400 },
410 413 { 541 },
411 414 } },
412 415 { "Times-BoldItalic", {
413 416 { 250 },
414 417 { 389 },
415 418 { 555 },
416 419 { 500 },
417 420 { 500 },
418 421 { 833 },
419 422 { 778 },
420 423 { 333 },
421 424 { 333 },
422 425 { 333 },
423 426 { 500 },
424 427 { 570 },
425 428 { 250 },
426 429 { 333 },
427 430 { 250 },
428 431 { 278 },
429 432 { 500 },
430 433 { 500 },
431 434 { 500 },
432 435 { 500 },
433 436 { 500 },
434 437 { 500 },
435 438 { 500 },
436 439 { 500 },
437 440 { 500 },
438 441 { 500 },
439 442 { 333 },
440 443 { 333 },
441 444 { 570 },
442 445 { 570 },
443 446 { 570 },
444 447 { 500 },
445 448 { 832 },
446 449 { 667 },
447 450 { 667 },
448 451 { 667 },
449 452 { 722 },
450 453 { 667 },
451 454 { 667 },
452 455 { 722 },
453 456 { 778 },
454 457 { 389 },
455 458 { 500 },
456 459 { 667 },
457 460 { 611 },
458 461 { 889 },
459 462 { 722 },
460 463 { 722 },
461 464 { 611 },
462 465 { 722 },
463 466 { 667 },
464 467 { 556 },
465 468 { 611 },
466 469 { 722 },
467 470 { 667 },
468 471 { 889 },
469 472 { 667 },
470 473 { 611 },
471 474 { 611 },
472 475 { 333 },
473 476 { 278 },
474 477 { 333 },
475 478 { 570 },
476 479 { 500 },
477 480 { 333 },
478 481 { 500 },
479 482 { 500 },
480 483 { 444 },
481 484 { 500 },
482 485 { 444 },
483 486 { 333 },
484 487 { 500 },
485 488 { 556 },
486 489 { 278 },
487 490 { 278 },
488 491 { 500 },
489 492 { 278 },
490 493 { 778 },
491 494 { 556 },
492 495 { 500 },
493 496 { 500 },
494 497 { 500 },
495 498 { 389 },
496 499 { 389 },
497 500 { 278 },
498 501 { 556 },
499 502 { 444 },
500 503 { 667 },
501 504 { 500 },
502 505 { 444 },
503 506 { 389 },
↓ open down ↓ |
382 lines elided |
↑ open up ↑ |
504 507 { 348 },
505 508 { 220 },
506 509 { 348 },
507 510 { 570 },
508 511 } },
509 512 };
510 513
511 514 void *
512 515 pdf_alloc(const struct manoutput *outopts)
513 516 {
514 - struct termp *p;
515 -
516 - if (NULL != (p = pspdf_alloc(outopts)))
517 - p->type = TERMTYPE_PDF;
518 -
519 - return p;
517 + return pspdf_alloc(outopts, TERMTYPE_PDF);
520 518 }
521 519
522 520 void *
523 521 ps_alloc(const struct manoutput *outopts)
524 522 {
525 - struct termp *p;
526 -
527 - if (NULL != (p = pspdf_alloc(outopts)))
528 - p->type = TERMTYPE_PS;
529 -
530 - return p;
523 + return pspdf_alloc(outopts, TERMTYPE_PS);
531 524 }
532 525
533 526 static struct termp *
534 -pspdf_alloc(const struct manoutput *outopts)
527 +pspdf_alloc(const struct manoutput *outopts, enum termtype type)
535 528 {
536 529 struct termp *p;
537 530 unsigned int pagex, pagey;
538 531 size_t marginx, marginy, lineheight;
539 532 const char *pp;
540 533
541 534 p = mandoc_calloc(1, sizeof(*p));
542 535 p->tcol = p->tcols = mandoc_calloc(1, sizeof(*p->tcol));
543 536 p->maxtcol = 1;
537 + p->type = type;
544 538
545 539 p->enc = TERMENC_ASCII;
546 540 p->fontq = mandoc_reallocarray(NULL,
547 541 (p->fontsz = 8), sizeof(*p->fontq));
548 542 p->fontq[0] = p->fontl = TERMFONT_NONE;
549 543 p->ps = mandoc_calloc(1, sizeof(*p->ps));
550 544
551 545 p->advance = ps_advance;
552 546 p->begin = ps_begin;
553 547 p->end = ps_end;
554 548 p->endline = ps_endline;
555 549 p->hspan = ps_hspan;
556 550 p->letter = ps_letter;
557 551 p->setwidth = ps_setwidth;
558 552 p->width = ps_width;
559 553
560 554 /* Default to US letter (millimetres). */
561 555
556 + p->ps->medianame = "Letter";
562 557 pagex = 216;
563 558 pagey = 279;
564 559
565 560 /*
566 561 * The ISO-269 paper sizes can be calculated automatically, but
567 562 * it would require bringing in -lm for pow() and I'd rather not
568 563 * do that. So just do it the easy way for now. Since this
569 564 * only happens once, I'm not terribly concerned.
570 565 */
571 566
572 567 pp = outopts->paper;
573 - if (pp && strcasecmp(pp, "letter")) {
574 - if (0 == strcasecmp(pp, "a3")) {
568 + if (pp != NULL && strcasecmp(pp, "letter") != 0) {
569 + if (strcasecmp(pp, "a3") == 0) {
570 + p->ps->medianame = "A3";
575 571 pagex = 297;
576 572 pagey = 420;
577 - } else if (0 == strcasecmp(pp, "a4")) {
573 + } else if (strcasecmp(pp, "a4") == 0) {
574 + p->ps->medianame = "A4";
578 575 pagex = 210;
579 576 pagey = 297;
580 - } else if (0 == strcasecmp(pp, "a5")) {
577 + } else if (strcasecmp(pp, "a5") == 0) {
578 + p->ps->medianame = "A5";
581 579 pagex = 148;
582 580 pagey = 210;
583 - } else if (0 == strcasecmp(pp, "legal")) {
581 + } else if (strcasecmp(pp, "legal") == 0) {
582 + p->ps->medianame = "Legal";
584 583 pagex = 216;
585 584 pagey = 356;
586 - } else if (2 != sscanf(pp, "%ux%u", &pagex, &pagey))
585 + } else if (sscanf(pp, "%ux%u", &pagex, &pagey) == 2)
586 + p->ps->medianame = "CustomSize";
587 + else
587 588 warnx("%s: Unknown paper", pp);
588 589 }
589 590
590 591 /*
591 592 * This MUST be defined before any PNT2AFM or AFM2PNT
592 593 * calculations occur.
593 594 */
594 595
595 596 p->ps->scale = 11;
596 597
597 598 /* Remember millimetres -> AFM units. */
598 599
599 - pagex = PNT2AFM(p, ((double)pagex * 2.834));
600 - pagey = PNT2AFM(p, ((double)pagey * 2.834));
600 + pagex = PNT2AFM(p, ((double)pagex * 72.0 / 25.4));
601 + pagey = PNT2AFM(p, ((double)pagey * 72.0 / 25.4));
601 602
602 603 /* Margins are 1/9 the page x and y. */
603 604
604 605 marginx = (size_t)((double)pagex / 9.0);
605 606 marginy = (size_t)((double)pagey / 9.0);
606 607
607 608 /* Line-height is 1.4em. */
608 609
609 610 lineheight = PNT2AFM(p, ((double)p->ps->scale * 1.4));
610 611
611 612 p->ps->width = p->ps->lastwidth = (size_t)pagex;
612 613 p->ps->height = (size_t)pagey;
613 614 p->ps->header = pagey - (marginy / 2) - (lineheight / 2);
614 615 p->ps->top = pagey - marginy;
615 616 p->ps->footer = (marginy / 2) - (lineheight / 2);
616 617 p->ps->bottom = marginy;
617 618 p->ps->left = marginx;
618 619 p->ps->lineheight = lineheight;
619 620
620 621 p->defrmargin = pagex - (marginx * 2);
621 622 return p;
622 623 }
623 624
624 625 static void
625 626 ps_setwidth(struct termp *p, int iop, int width)
626 627 {
627 628 size_t lastwidth;
628 629
629 630 lastwidth = p->ps->width;
630 631 if (iop > 0)
631 632 p->ps->width += width;
632 633 else if (iop == 0)
633 634 p->ps->width = width ? (size_t)width : p->ps->lastwidth;
634 635 else if (p->ps->width > (size_t)width)
635 636 p->ps->width -= width;
636 637 else
637 638 p->ps->width = 0;
638 639 p->ps->lastwidth = lastwidth;
639 640 }
640 641
641 642 void
642 643 pspdf_free(void *arg)
643 644 {
644 645 struct termp *p;
645 646
646 647 p = (struct termp *)arg;
647 648
648 649 free(p->ps->psmarg);
649 650 free(p->ps->pdfobjs);
650 651
651 652 free(p->ps);
652 653 term_free(p);
653 654 }
654 655
655 656 static void
656 657 ps_printf(struct termp *p, const char *fmt, ...)
657 658 {
658 659 va_list ap;
659 660 int pos, len;
660 661
661 662 va_start(ap, fmt);
662 663
663 664 /*
664 665 * If we're running in regular mode, then pipe directly into
665 666 * vprintf(). If we're processing margins, then push the data
666 667 * into our growable margin buffer.
667 668 */
668 669
669 670 if ( ! (PS_MARGINS & p->ps->flags)) {
670 671 len = vprintf(fmt, ap);
671 672 va_end(ap);
672 673 p->ps->pdfbytes += len < 0 ? 0 : (size_t)len;
673 674 return;
674 675 }
675 676
676 677 /*
677 678 * XXX: I assume that the in-margin print won't exceed
678 679 * PS_BUFSLOP (128 bytes), which is reasonable but still an
679 680 * assumption that will cause pukeage if it's not the case.
680 681 */
681 682
682 683 ps_growbuf(p, PS_BUFSLOP);
683 684
684 685 pos = (int)p->ps->psmargcur;
685 686 vsnprintf(&p->ps->psmarg[pos], PS_BUFSLOP, fmt, ap);
686 687
687 688 va_end(ap);
688 689
689 690 p->ps->psmargcur = strlen(p->ps->psmarg);
690 691 }
691 692
692 693 static void
693 694 ps_putchar(struct termp *p, char c)
694 695 {
695 696 int pos;
696 697
697 698 /* See ps_printf(). */
698 699
699 700 if ( ! (PS_MARGINS & p->ps->flags)) {
700 701 putchar(c);
701 702 p->ps->pdfbytes++;
702 703 return;
703 704 }
704 705
705 706 ps_growbuf(p, 2);
706 707
707 708 pos = (int)p->ps->psmargcur++;
708 709 p->ps->psmarg[pos++] = c;
709 710 p->ps->psmarg[pos] = '\0';
710 711 }
711 712
712 713 static void
713 714 pdf_obj(struct termp *p, size_t obj)
714 715 {
715 716
716 717 assert(obj > 0);
717 718
718 719 if ((obj - 1) >= p->ps->pdfobjsz) {
719 720 p->ps->pdfobjsz = obj + 128;
720 721 p->ps->pdfobjs = mandoc_reallocarray(p->ps->pdfobjs,
721 722 p->ps->pdfobjsz, sizeof(size_t));
722 723 }
723 724
724 725 p->ps->pdfobjs[(int)obj - 1] = p->ps->pdfbytes;
725 726 ps_printf(p, "%zu 0 obj\n", obj);
↓ open down ↓ |
115 lines elided |
↑ open up ↑ |
726 727 }
727 728
728 729 static void
729 730 ps_closepage(struct termp *p)
730 731 {
731 732 int i;
732 733 size_t len, base;
733 734
734 735 /*
735 736 * Close out a page that we've already flushed to output. In
736 - * PostScript, we simply note that the page must be showed. In
737 + * PostScript, we simply note that the page must be shown. In
737 738 * PDF, we must now create the Length, Resource, and Page node
738 739 * for the page contents.
739 740 */
740 741
741 742 assert(p->ps->psmarg && p->ps->psmarg[0]);
742 743 ps_printf(p, "%s", p->ps->psmarg);
743 744
744 745 if (TERMTYPE_PS != p->type) {
745 - ps_printf(p, "ET\n");
746 -
747 746 len = p->ps->pdfbytes - p->ps->pdflastpg;
748 747 base = p->ps->pages * 4 + p->ps->pdfbody;
749 748
750 749 ps_printf(p, "endstream\nendobj\n");
751 750
752 751 /* Length of content. */
753 752 pdf_obj(p, base + 1);
754 753 ps_printf(p, "%zu\nendobj\n", len);
755 754
756 755 /* Resource for content. */
757 756 pdf_obj(p, base + 2);
758 757 ps_printf(p, "<<\n/ProcSet [/PDF /Text]\n");
759 758 ps_printf(p, "/Font <<\n");
760 759 for (i = 0; i < (int)TERMFONT__MAX; i++)
761 760 ps_printf(p, "/F%d %d 0 R\n", i, 3 + i);
762 - ps_printf(p, ">>\n>>\n");
761 + ps_printf(p, ">>\n>>\nendobj\n");
763 762
764 763 /* Page node. */
765 764 pdf_obj(p, base + 3);
766 765 ps_printf(p, "<<\n");
767 766 ps_printf(p, "/Type /Page\n");
768 767 ps_printf(p, "/Parent 2 0 R\n");
769 768 ps_printf(p, "/Resources %zu 0 R\n", base + 2);
770 769 ps_printf(p, "/Contents %zu 0 R\n", base);
771 770 ps_printf(p, ">>\nendobj\n");
772 771 } else
773 772 ps_printf(p, "showpage\n");
774 773
775 774 p->ps->pages++;
776 775 p->ps->psrow = p->ps->top;
777 776 assert( ! (PS_NEWPAGE & p->ps->flags));
778 777 p->ps->flags |= PS_NEWPAGE;
779 778 }
780 779
781 780 static void
782 781 ps_end(struct termp *p)
783 782 {
784 783 size_t i, xref, base;
785 784
786 785 ps_plast(p);
787 786 ps_pclose(p);
788 787
789 788 /*
790 789 * At the end of the file, do one last showpage. This is the
791 790 * same behaviour as groff(1) and works for multiple pages as
792 791 * well as just one.
793 792 */
794 793
795 794 if ( ! (PS_NEWPAGE & p->ps->flags)) {
796 795 assert(0 == p->ps->flags);
797 796 assert('\0' == p->ps->last);
798 797 ps_closepage(p);
799 798 }
800 799
801 800 if (TERMTYPE_PS == p->type) {
802 801 ps_printf(p, "%%%%Trailer\n");
803 802 ps_printf(p, "%%%%Pages: %zu\n", p->ps->pages);
804 803 ps_printf(p, "%%%%EOF\n");
805 804 return;
806 805 }
807 806
808 807 pdf_obj(p, 2);
809 808 ps_printf(p, "<<\n/Type /Pages\n");
810 809 ps_printf(p, "/MediaBox [0 0 %zu %zu]\n",
811 810 (size_t)AFM2PNT(p, p->ps->width),
812 811 (size_t)AFM2PNT(p, p->ps->height));
813 812
814 813 ps_printf(p, "/Count %zu\n", p->ps->pages);
815 814 ps_printf(p, "/Kids [");
816 815
↓ open down ↓ |
44 lines elided |
↑ open up ↑ |
817 816 for (i = 0; i < p->ps->pages; i++)
818 817 ps_printf(p, " %zu 0 R", i * 4 + p->ps->pdfbody + 3);
819 818
820 819 base = (p->ps->pages - 1) * 4 + p->ps->pdfbody + 4;
821 820
822 821 ps_printf(p, "]\n>>\nendobj\n");
823 822 pdf_obj(p, base);
824 823 ps_printf(p, "<<\n");
825 824 ps_printf(p, "/Type /Catalog\n");
826 825 ps_printf(p, "/Pages 2 0 R\n");
827 - ps_printf(p, ">>\n");
826 + ps_printf(p, ">>\nendobj\n");
828 827 xref = p->ps->pdfbytes;
829 828 ps_printf(p, "xref\n");
830 829 ps_printf(p, "0 %zu\n", base + 1);
831 830 ps_printf(p, "0000000000 65535 f \n");
832 831
833 832 for (i = 0; i < base; i++)
834 833 ps_printf(p, "%.10zu 00000 n \n",
835 834 p->ps->pdfobjs[(int)i]);
836 835
837 836 ps_printf(p, "trailer\n");
838 837 ps_printf(p, "<<\n");
839 838 ps_printf(p, "/Size %zu\n", base + 1);
840 839 ps_printf(p, "/Root %zu 0 R\n", base);
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
841 840 ps_printf(p, "/Info 1 0 R\n");
842 841 ps_printf(p, ">>\n");
843 842 ps_printf(p, "startxref\n");
844 843 ps_printf(p, "%zu\n", xref);
845 844 ps_printf(p, "%%%%EOF\n");
846 845 }
847 846
848 847 static void
849 848 ps_begin(struct termp *p)
850 849 {
850 + size_t width, height;
851 851 int i;
852 852
853 853 /*
854 854 * Print margins into margin buffer. Nothing gets output to the
855 855 * screen yet, so we don't need to initialise the primary state.
856 856 */
857 857
858 858 if (p->ps->psmarg) {
859 859 assert(p->ps->psmargsz);
860 860 p->ps->psmarg[0] = '\0';
861 861 }
862 862
863 863 /*p->ps->pdfbytes = 0;*/
864 864 p->ps->psmargcur = 0;
865 865 p->ps->flags = PS_MARGINS;
866 866 p->ps->pscol = p->ps->left;
867 867 p->ps->psrow = p->ps->header;
868 + p->ps->lastrow = 0; /* impossible row */
868 869
869 870 ps_setfont(p, TERMFONT_NONE);
870 871
871 872 (*p->headf)(p, p->argf);
872 873 (*p->endline)(p);
873 874
874 875 p->ps->pscol = p->ps->left;
875 876 p->ps->psrow = p->ps->footer;
876 877
877 878 (*p->footf)(p, p->argf);
878 879 (*p->endline)(p);
879 880
880 881 p->ps->flags &= ~PS_MARGINS;
881 882
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
882 883 assert(0 == p->ps->flags);
883 884 assert(p->ps->psmarg);
884 885 assert('\0' != p->ps->psmarg[0]);
885 886
886 887 /*
887 888 * Print header and initialise page state. Following this,
888 889 * stuff gets printed to the screen, so make sure we're sane.
889 890 */
890 891
891 892 if (TERMTYPE_PS == p->type) {
893 + width = AFM2PNT(p, p->ps->width);
894 + height = AFM2PNT(p, p->ps->height);
895 +
892 896 ps_printf(p, "%%!PS-Adobe-3.0\n");
893 897 ps_printf(p, "%%%%DocumentData: Clean7Bit\n");
894 898 ps_printf(p, "%%%%Orientation: Portrait\n");
895 899 ps_printf(p, "%%%%Pages: (atend)\n");
896 900 ps_printf(p, "%%%%PageOrder: Ascend\n");
897 - ps_printf(p, "%%%%DocumentMedia: "
898 - "Default %zu %zu 0 () ()\n",
899 - (size_t)AFM2PNT(p, p->ps->width),
900 - (size_t)AFM2PNT(p, p->ps->height));
901 + ps_printf(p, "%%%%DocumentMedia: man-%s %zu %zu 0 () ()\n",
902 + p->ps->medianame, width, height);
901 903 ps_printf(p, "%%%%DocumentNeededResources: font");
902 904
903 905 for (i = 0; i < (int)TERMFONT__MAX; i++)
904 906 ps_printf(p, " %s", fonts[i].name);
905 907
906 - ps_printf(p, "\n%%%%EndComments\n");
908 + ps_printf(p, "\n%%%%DocumentSuppliedResources: "
909 + "procset MandocProcs 1.0 0\n");
910 + ps_printf(p, "%%%%EndComments\n");
911 + ps_printf(p, "%%%%BeginProlog\n");
912 + ps_printf(p, "%%%%BeginResource: procset MandocProcs "
913 + "10170 10170\n");
914 + /* The font size is effectively hard-coded for now. */
915 + ps_printf(p, "/fs %zu def\n", p->ps->scale);
916 + for (i = 0; i < (int)TERMFONT__MAX; i++)
917 + ps_printf(p, "/f%d { /%s fs selectfont } def\n",
918 + i, fonts[i].name);
919 + ps_printf(p, "/s { 3 1 roll moveto show } bind def\n");
920 + ps_printf(p, "/c { exch currentpoint exch pop "
921 + "moveto show } bind def\n");
922 + ps_printf(p, "%%%%EndResource\n");
923 + ps_printf(p, "%%%%EndProlog\n");
924 + ps_printf(p, "%%%%BeginSetup\n");
925 + ps_printf(p, "%%%%BeginFeature: *PageSize %s\n",
926 + p->ps->medianame);
927 + ps_printf(p, "<</PageSize [%zu %zu]>>setpagedevice\n",
928 + width, height);
929 + ps_printf(p, "%%%%EndFeature\n");
930 + ps_printf(p, "%%%%EndSetup\n");
907 931 } else {
908 932 ps_printf(p, "%%PDF-1.1\n");
909 933 pdf_obj(p, 1);
910 934 ps_printf(p, "<<\n");
911 935 ps_printf(p, ">>\n");
912 936 ps_printf(p, "endobj\n");
913 937
914 938 for (i = 0; i < (int)TERMFONT__MAX; i++) {
915 939 pdf_obj(p, (size_t)i + 3);
916 940 ps_printf(p, "<<\n");
917 941 ps_printf(p, "/Type /Font\n");
918 942 ps_printf(p, "/Subtype /Type1\n");
919 943 ps_printf(p, "/Name /F%d\n", i);
920 944 ps_printf(p, "/BaseFont /%s\n", fonts[i].name);
921 - ps_printf(p, ">>\n");
945 + ps_printf(p, ">>\nendobj\n");
922 946 }
923 947 }
924 948
925 949 p->ps->pdfbody = (size_t)TERMFONT__MAX + 3;
926 950 p->ps->pscol = p->ps->left;
927 951 p->ps->psrow = p->ps->top;
928 952 p->ps->flags |= PS_NEWPAGE;
929 953 ps_setfont(p, TERMFONT_NONE);
930 954 }
931 955
932 956 static void
933 957 ps_pletter(struct termp *p, int c)
934 958 {
935 959 int f;
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
936 960
937 961 /*
938 962 * If we haven't opened a page context, then output that we're
939 963 * in a new page and make sure the font is correctly set.
940 964 */
941 965
942 966 if (PS_NEWPAGE & p->ps->flags) {
943 967 if (TERMTYPE_PS == p->type) {
944 968 ps_printf(p, "%%%%Page: %zu %zu\n",
945 969 p->ps->pages + 1, p->ps->pages + 1);
946 - ps_printf(p, "/%s %zu selectfont\n",
947 - fonts[(int)p->ps->lastf].name,
948 - p->ps->scale);
970 + ps_printf(p, "f%d\n", (int)p->ps->lastf);
949 971 } else {
950 972 pdf_obj(p, p->ps->pdfbody +
951 973 p->ps->pages * 4);
952 974 ps_printf(p, "<<\n");
953 975 ps_printf(p, "/Length %zu 0 R\n",
954 976 p->ps->pdfbody + 1 + p->ps->pages * 4);
955 977 ps_printf(p, ">>\nstream\n");
956 978 }
957 979 p->ps->pdflastpg = p->ps->pdfbytes;
958 980 p->ps->flags &= ~PS_NEWPAGE;
959 981 }
960 982
961 983 /*
962 984 * If we're not in a PostScript "word" context, then open one
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
963 985 * now at the current cursor.
964 986 */
965 987
966 988 if ( ! (PS_INLINE & p->ps->flags)) {
967 989 if (TERMTYPE_PS != p->type) {
968 990 ps_printf(p, "BT\n/F%d %zu Tf\n",
969 991 (int)p->ps->lastf, p->ps->scale);
970 992 ps_printf(p, "%.3f %.3f Td\n(",
971 993 AFM2PNT(p, p->ps->pscol),
972 994 AFM2PNT(p, p->ps->psrow));
973 - } else
974 - ps_printf(p, "%.3f %.3f moveto\n(",
975 - AFM2PNT(p, p->ps->pscol),
976 - AFM2PNT(p, p->ps->psrow));
995 + } else {
996 + ps_printf(p, "%.3f", AFM2PNT(p, p->ps->pscol));
997 + if (p->ps->psrow != p->ps->lastrow)
998 + ps_printf(p, " %.3f",
999 + AFM2PNT(p, p->ps->psrow));
1000 + ps_printf(p, "(");
1001 + }
977 1002 p->ps->flags |= PS_INLINE;
978 1003 }
979 1004
980 1005 assert( ! (PS_NEWPAGE & p->ps->flags));
981 1006
982 1007 /*
983 1008 * We need to escape these characters as per the PostScript
984 1009 * specification. We would also escape non-graphable characters
985 1010 * (like tabs), but none of them would get to this point and
986 1011 * it's superfluous to abort() on them.
987 1012 */
988 1013
989 1014 switch (c) {
990 1015 case '(':
991 1016 case ')':
992 1017 case '\\':
993 1018 ps_putchar(p, '\\');
994 1019 break;
995 1020 default:
996 1021 break;
997 1022 }
998 1023
999 1024 /* Write the character and adjust where we are on the page. */
1000 1025
1001 1026 f = (int)p->ps->lastf;
1002 1027
1003 1028 if (c <= 32 || c - 32 >= MAXCHAR)
1004 1029 c = 32;
1005 1030
1006 1031 ps_putchar(p, (char)c);
1007 1032 c -= 32;
1008 1033 p->ps->pscol += (size_t)fonts[f].gly[c].wx;
1009 1034 }
1010 1035
1011 1036 static void
1012 1037 ps_pclose(struct termp *p)
1013 1038 {
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
1014 1039
1015 1040 /*
1016 1041 * Spit out that we're exiting a word context (this is a
1017 1042 * "partial close" because we don't check the last-char buffer
1018 1043 * or anything).
1019 1044 */
1020 1045
1021 1046 if ( ! (PS_INLINE & p->ps->flags))
1022 1047 return;
1023 1048
1024 - if (TERMTYPE_PS != p->type) {
1049 + if (TERMTYPE_PS != p->type)
1025 1050 ps_printf(p, ") Tj\nET\n");
1026 - } else
1027 - ps_printf(p, ") show\n");
1051 + else if (p->ps->psrow == p->ps->lastrow)
1052 + ps_printf(p, ")c\n");
1053 + else {
1054 + ps_printf(p, ")s\n");
1055 + p->ps->lastrow = p->ps->psrow;
1056 + }
1028 1057
1029 1058 p->ps->flags &= ~PS_INLINE;
1030 1059 }
1031 1060
1032 1061 /* If we have a `last' char that wasn't printed yet, print it now. */
1033 1062 static void
1034 1063 ps_plast(struct termp *p)
1035 1064 {
1036 1065 size_t wx;
1037 1066
1038 1067 if (p->ps->last == '\0')
1039 1068 return;
1040 1069
1041 1070 /* Check the font mode; open a new scope if it doesn't match. */
1042 1071
1043 1072 if (p->ps->nextf != p->ps->lastf) {
1044 1073 ps_pclose(p);
1045 1074 ps_setfont(p, p->ps->nextf);
1046 1075 }
1047 1076 p->ps->nextf = TERMFONT_NONE;
1048 1077
1049 1078 /*
1050 1079 * For an overstrike, if a previous character
1051 1080 * was wider, advance to center the new one.
1052 1081 */
1053 1082
1054 1083 if (p->ps->pscolnext) {
1055 1084 wx = fonts[p->ps->lastf].gly[(int)p->ps->last-32].wx;
1056 1085 if (p->ps->pscol + wx < p->ps->pscolnext)
1057 1086 p->ps->pscol = (p->ps->pscol +
1058 1087 p->ps->pscolnext - wx) / 2;
1059 1088 }
1060 1089
1061 1090 ps_pletter(p, p->ps->last);
1062 1091 p->ps->last = '\0';
1063 1092
1064 1093 /*
1065 1094 * For an overstrike, if a previous character
1066 1095 * was wider, advance to the end of the old one.
1067 1096 */
1068 1097
1069 1098 if (p->ps->pscol < p->ps->pscolnext) {
1070 1099 ps_pclose(p);
1071 1100 p->ps->pscol = p->ps->pscolnext;
1072 1101 }
1073 1102 }
1074 1103
1075 1104 static void
1076 1105 ps_letter(struct termp *p, int arg)
1077 1106 {
1078 1107 size_t savecol;
1079 1108 char c;
1080 1109
1081 1110 c = arg >= 128 || arg <= 0 ? '?' : arg;
1082 1111
1083 1112 /*
1084 1113 * When receiving a backspace, merely flag it.
1085 1114 * We don't know yet whether it is
1086 1115 * a font instruction or an overstrike.
1087 1116 */
1088 1117
1089 1118 if (c == '\b') {
1090 1119 assert(p->ps->last != '\0');
1091 1120 assert( ! (p->ps->flags & PS_BACKSP));
1092 1121 p->ps->flags |= PS_BACKSP;
1093 1122 return;
1094 1123 }
1095 1124
1096 1125 /*
1097 1126 * Decode font instructions.
1098 1127 */
1099 1128
1100 1129 if (p->ps->flags & PS_BACKSP) {
1101 1130 if (p->ps->last == '_') {
1102 1131 switch (p->ps->nextf) {
1103 1132 case TERMFONT_BI:
1104 1133 break;
1105 1134 case TERMFONT_BOLD:
1106 1135 p->ps->nextf = TERMFONT_BI;
1107 1136 break;
1108 1137 default:
1109 1138 p->ps->nextf = TERMFONT_UNDER;
1110 1139 }
1111 1140 p->ps->last = c;
1112 1141 p->ps->flags &= ~PS_BACKSP;
1113 1142 return;
1114 1143 }
1115 1144 if (p->ps->last == c) {
1116 1145 switch (p->ps->nextf) {
1117 1146 case TERMFONT_BI:
1118 1147 break;
1119 1148 case TERMFONT_UNDER:
1120 1149 p->ps->nextf = TERMFONT_BI;
1121 1150 break;
1122 1151 default:
1123 1152 p->ps->nextf = TERMFONT_BOLD;
1124 1153 }
1125 1154 p->ps->flags &= ~PS_BACKSP;
1126 1155 return;
1127 1156 }
1128 1157
1129 1158 /*
1130 1159 * This is not a font instruction, but rather
1131 1160 * the next character. Prepare for overstrike.
1132 1161 */
1133 1162
1134 1163 savecol = p->ps->pscol;
1135 1164 } else
1136 1165 savecol = SIZE_MAX;
1137 1166
1138 1167 /*
1139 1168 * We found the next character, so the font instructions
1140 1169 * for the previous one are complete.
1141 1170 * Use them and print it.
1142 1171 */
1143 1172
1144 1173 ps_plast(p);
1145 1174
1146 1175 /*
1147 1176 * Do not print the current character yet because font
1148 1177 * instructions might follow; only remember the character.
1149 1178 * It will get printed later from ps_plast().
1150 1179 */
1151 1180
1152 1181 p->ps->last = c;
1153 1182
1154 1183 /*
1155 1184 * For an overstrike, back up to the previous position.
1156 1185 * If the previous character is wider than any it overstrikes,
1157 1186 * remember the current position, because it might also be
1158 1187 * wider than all that will overstrike it.
1159 1188 */
1160 1189
1161 1190 if (savecol != SIZE_MAX) {
1162 1191 if (p->ps->pscolnext < p->ps->pscol)
1163 1192 p->ps->pscolnext = p->ps->pscol;
1164 1193 ps_pclose(p);
1165 1194 p->ps->pscol = savecol;
1166 1195 p->ps->flags &= ~PS_BACKSP;
1167 1196 } else
1168 1197 p->ps->pscolnext = 0;
1169 1198 }
1170 1199
1171 1200 static void
1172 1201 ps_advance(struct termp *p, size_t len)
1173 1202 {
1174 1203
1175 1204 /*
1176 1205 * Advance some spaces. This can probably be made smarter,
1177 1206 * i.e., to have multiple space-separated words in the same
1178 1207 * scope, but this is easier: just close out the current scope
1179 1208 * and readjust our column settings.
1180 1209 */
1181 1210
1182 1211 ps_plast(p);
1183 1212 ps_pclose(p);
1184 1213 p->ps->pscol += len;
1185 1214 }
1186 1215
1187 1216 static void
1188 1217 ps_endline(struct termp *p)
1189 1218 {
1190 1219
1191 1220 /* Close out any scopes we have open: we're at eoln. */
1192 1221
1193 1222 ps_plast(p);
1194 1223 ps_pclose(p);
1195 1224
1196 1225 /*
1197 1226 * If we're in the margin, don't try to recalculate our current
1198 1227 * row. XXX: if the column tries to be fancy with multiple
1199 1228 * lines, we'll do nasty stuff.
1200 1229 */
1201 1230
1202 1231 if (PS_MARGINS & p->ps->flags)
1203 1232 return;
1204 1233
1205 1234 /* Left-justify. */
1206 1235
1207 1236 p->ps->pscol = p->ps->left;
1208 1237
1209 1238 /* If we haven't printed anything, return. */
1210 1239
1211 1240 if (PS_NEWPAGE & p->ps->flags)
1212 1241 return;
1213 1242
1214 1243 /*
1215 1244 * Put us down a line. If we're at the page bottom, spit out a
1216 1245 * showpage and restart our row.
1217 1246 */
1218 1247
1219 1248 if (p->ps->psrow >= p->ps->lineheight + p->ps->bottom) {
1220 1249 p->ps->psrow -= p->ps->lineheight;
1221 1250 return;
1222 1251 }
1223 1252
1224 1253 ps_closepage(p);
1225 1254
1226 1255 p->tcol->offset -= p->ti;
1227 1256 p->ti = 0;
1228 1257 }
1229 1258
1230 1259 static void
1231 1260 ps_setfont(struct termp *p, enum termfont f)
1232 1261 {
1233 1262
1234 1263 assert(f < TERMFONT__MAX);
1235 1264 p->ps->lastf = f;
↓ open down ↓ |
198 lines elided |
↑ open up ↑ |
1236 1265
1237 1266 /*
1238 1267 * If we're still at the top of the page, let the font-setting
1239 1268 * be delayed until we actually have stuff to print.
1240 1269 */
1241 1270
1242 1271 if (PS_NEWPAGE & p->ps->flags)
1243 1272 return;
1244 1273
1245 1274 if (TERMTYPE_PS == p->type)
1246 - ps_printf(p, "/%s %zu selectfont\n",
1247 - fonts[(int)f].name, p->ps->scale);
1275 + ps_printf(p, "f%d\n", (int)f);
1248 1276 else
1249 1277 ps_printf(p, "/F%d %zu Tf\n",
1250 1278 (int)f, p->ps->scale);
1251 1279 }
1252 1280
1253 1281 static size_t
1254 1282 ps_width(const struct termp *p, int c)
1255 1283 {
1256 1284
1257 1285 if (c <= 32 || c - 32 >= MAXCHAR)
1258 1286 c = 0;
1259 1287 else
1260 1288 c -= 32;
1261 1289
1262 1290 return (size_t)fonts[(int)TERMFONT_NONE].gly[c].wx;
1263 1291 }
1264 1292
1265 1293 static int
1266 1294 ps_hspan(const struct termp *p, const struct roffsu *su)
1267 1295 {
1268 1296 double r;
1269 1297
1270 1298 /*
1271 1299 * All of these measurements are derived by converting from the
1272 1300 * native measurement to AFM units.
1273 1301 */
1274 1302 switch (su->unit) {
1275 1303 case SCALE_BU:
1276 1304 /*
1277 1305 * Traditionally, the default unit is fixed to the
1278 1306 * output media. So this would refer to the point. In
1279 1307 * mandoc(1), however, we stick to the default terminal
1280 1308 * scaling unit so that output is the same regardless
1281 1309 * the media.
1282 1310 */
1283 1311 r = PNT2AFM(p, su->scale * 72.0 / 240.0);
1284 1312 break;
1285 1313 case SCALE_CM:
1286 1314 r = PNT2AFM(p, su->scale * 72.0 / 2.54);
1287 1315 break;
1288 1316 case SCALE_EM:
1289 1317 r = su->scale *
1290 1318 fonts[(int)TERMFONT_NONE].gly[109 - 32].wx;
1291 1319 break;
1292 1320 case SCALE_EN:
1293 1321 r = su->scale *
1294 1322 fonts[(int)TERMFONT_NONE].gly[110 - 32].wx;
1295 1323 break;
1296 1324 case SCALE_IN:
1297 1325 r = PNT2AFM(p, su->scale * 72.0);
1298 1326 break;
1299 1327 case SCALE_MM:
1300 1328 r = su->scale *
1301 1329 fonts[(int)TERMFONT_NONE].gly[109 - 32].wx / 100.0;
1302 1330 break;
1303 1331 case SCALE_PC:
1304 1332 r = PNT2AFM(p, su->scale * 12.0);
1305 1333 break;
1306 1334 case SCALE_PT:
1307 1335 r = PNT2AFM(p, su->scale * 1.0);
1308 1336 break;
1309 1337 case SCALE_VS:
1310 1338 r = su->scale * p->ps->lineheight;
1311 1339 break;
1312 1340 default:
1313 1341 r = su->scale;
1314 1342 break;
1315 1343 }
1316 1344
1317 1345 return r * 24.0;
1318 1346 }
1319 1347
1320 1348 static void
1321 1349 ps_growbuf(struct termp *p, size_t sz)
1322 1350 {
1323 1351 if (p->ps->psmargcur + sz <= p->ps->psmargsz)
1324 1352 return;
1325 1353
1326 1354 if (sz < PS_BUFSLOP)
1327 1355 sz = PS_BUFSLOP;
1328 1356
1329 1357 p->ps->psmargsz += sz;
1330 1358 p->ps->psmarg = mandoc_realloc(p->ps->psmarg, p->ps->psmargsz);
1331 1359 }
↓ open down ↓ |
74 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX