]> git.cameronkatri.com Git - mandoc.git/blobdiff - term_ps.c
With the current architecture, we can't support inline equations
[mandoc.git] / term_ps.c
index 12177acd59dcc180d5e45cb18b07d9443cdcd517..e18030383dbf96b40d07d62ee740dbd1ae74a03f 100644 (file)
--- a/term_ps.c
+++ b/term_ps.c
@@ -1,4 +1,4 @@
-/*     $Id: term_ps.c,v 1.61 2014/07/27 21:53:17 schwarze Exp $ */
+/*     $Id: term_ps.c,v 1.66 2014/08/28 01:37:12 schwarze Exp $ */
 /*
  * Copyright (c) 2010, 2011 Kristaps Dzonsons <kristaps@bsd.lv>
  * Copyright (c) 2014 Ingo Schwarze <schwarze@openbsd.org>
@@ -15,9 +15,7 @@
  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  */
-#ifdef HAVE_CONFIG_H
 #include "config.h"
-#endif
 
 #include <sys/types.h>
 
@@ -27,7 +25,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <time.h>
 #include <unistd.h>
 
 #include "mandoc.h"
@@ -69,6 +66,7 @@ struct        termp_ps {
        size_t            psmargcur;    /* cur index in margin buf */
        char              last;         /* character buffer */
        enum termfont     lastf;        /* last set font */
+       enum termfont     nextf;        /* building next font here */
        size_t            scale;        /* font scaling factor */
        size_t            pages;        /* number of pages shown */
        size_t            lineheight;   /* line height (AFM units) */
@@ -408,6 +406,103 @@ static    const struct font fonts[TERMFONT__MAX] = {
                {  400 },
                {  541 },
        } },
+       { "Times-BoldItalic", {
+               {  250 },
+               {  389 },
+               {  555 },
+               {  500 },
+               {  500 },
+               {  833 },
+               {  778 },
+               {  333 },
+               {  333 },
+               {  333 },
+               {  500 },
+               {  570 },
+               {  250 },
+               {  333 },
+               {  250 },
+               {  278 },
+               {  500 },
+               {  500 },
+               {  500 },
+               {  500 },
+               {  500 },
+               {  500 },
+               {  500 },
+               {  500 },
+               {  500 },
+               {  500 },
+               {  333 },
+               {  333 },
+               {  570 },
+               {  570 },
+               {  570 },
+               {  500 },
+               {  832 },
+               {  667 },
+               {  667 },
+               {  667 },
+               {  722 },
+               {  667 },
+               {  667 },
+               {  722 },
+               {  778 },
+               {  389 },
+               {  500 },
+               {  667 },
+               {  611 },
+               {  889 },
+               {  722 },
+               {  722 },
+               {  611 },
+               {  722 },
+               {  667 },
+               {  556 },
+               {  611 },
+               {  722 },
+               {  667 },
+               {  889 },
+               {  667 },
+               {  611 },
+               {  611 },
+               {  333 },
+               {  278 },
+               {  333 },
+               {  570 },
+               {  500 },
+               {  333 },
+               {  500 },
+               {  500 },
+               {  444 },
+               {  500 },
+               {  444 },
+               {  333 },
+               {  500 },
+               {  556 },
+               {  278 },
+               {  278 },
+               {  500 },
+               {  278 },
+               {  778 },
+               {  556 },
+               {  500 },
+               {  500 },
+               {  500 },
+               {  389 },
+               {  389 },
+               {  278 },
+               {  556 },
+               {  444 },
+               {  667 },
+               {  500 },
+               {  444 },
+               {  389 },
+               {  348 },
+               {  220 },
+               {  348 },
+               {  570 },
+       } },
 };
 
 void *
@@ -756,7 +851,6 @@ ps_end(struct termp *p)
 static void
 ps_begin(struct termp *p)
 {
-       time_t           t;
        int              i;
 
        /*
@@ -797,11 +891,8 @@ ps_begin(struct termp *p)
         * stuff gets printed to the screen, so make sure we're sane.
         */
 
-       t = time(NULL);
-
        if (TERMTYPE_PS == p->type) {
                ps_printf(p, "%%!PS-Adobe-3.0\n");
-               ps_printf(p, "%%%%CreationDate: %s", ctime(&t));
                ps_printf(p, "%%%%DocumentData: Clean7Bit\n");
                ps_printf(p, "%%%%Orientation: Portrait\n");
                ps_printf(p, "%%%%Pages: (atend)\n");
@@ -955,11 +1046,13 @@ ps_fclose(struct termp *p)
         * Following this, close out any scope that's open.
         */
 
-       if ('\0' != p->ps->last) {
-               if (p->ps->lastf != TERMFONT_NONE) {
+       if (p->ps->last != '\0') {
+               assert(p->ps->last != 8);
+               if (p->ps->nextf != p->ps->lastf) {
                        ps_pclose(p);
-                       ps_setfont(p, TERMFONT_NONE);
+                       ps_setfont(p, p->ps->nextf);
                }
+               p->ps->nextf = TERMFONT_NONE;
                ps_pletter(p, p->ps->last);
                p->ps->last = '\0';
        }
@@ -973,50 +1066,54 @@ ps_fclose(struct termp *p)
 static void
 ps_letter(struct termp *p, int arg)
 {
-       char            cc, c;
+       char            c;
 
        c = arg >= 128 || arg <= 0 ? '?' : arg;
 
        /*
-        * State machine dictates whether to buffer the last character
-        * or not.  Basically, encoded words are detected by checking if
-        * we're an "8" and switching on the buffer.  Then we put "8" in
-        * our buffer, and on the next charater, flush both character
-        * and buffer.  Thus, "regular" words are detected by having a
-        * regular character and a regular buffer character.
+        * When receiving an initial character, merely buffer it,
+        * because a backspace might follow to specify formatting.
+        * When receiving a backspace, use the buffered character
+        * to build the font instruction and clear the buffer.
+        * Only when there are two non-backspace characters in a row,
+        * activate the font built so far and print the first of them;
+        * the second, again, merely gets buffered.
+        * The final character will get printed from ps_fclose().
         */
 
-       if ('\0' == p->ps->last) {
-               assert(8 != c);
-               p->ps->last = c;
-               return;
-       } else if (8 == p->ps->last) {
-               assert(8 != c);
-               p->ps->last = '\0';
-       } else if (8 == c) {
-               assert(8 != p->ps->last);
+       if (c == 8) {
+               assert(p->ps->last != '\0');
+               assert(p->ps->last != 8);
                if ('_' == p->ps->last) {
-                       if (p->ps->lastf != TERMFONT_UNDER) {
-                               ps_pclose(p);
-                               ps_setfont(p, TERMFONT_UNDER);
+                       switch (p->ps->nextf) {
+                       case TERMFONT_BI:
+                               break;
+                       case TERMFONT_BOLD:
+                               p->ps->nextf = TERMFONT_BI;
+                               break;
+                       default:
+                               p->ps->nextf = TERMFONT_UNDER;
+                       }
+               } else {
+                       switch (p->ps->nextf) {
+                       case TERMFONT_BI:
+                               break;
+                       case TERMFONT_UNDER:
+                               p->ps->nextf = TERMFONT_BI;
+                               break;
+                       default:
+                               p->ps->nextf = TERMFONT_BOLD;
                        }
-               } else if (p->ps->lastf != TERMFONT_BOLD) {
-                       ps_pclose(p);
-                       ps_setfont(p, TERMFONT_BOLD);
                }
-               p->ps->last = c;
-               return;
-       } else {
-               if (p->ps->lastf != TERMFONT_NONE) {
+       } else if (p->ps->last != '\0' && p->ps->last != 8) {
+               if (p->ps->nextf != p->ps->lastf) {
                        ps_pclose(p);
-                       ps_setfont(p, TERMFONT_NONE);
+                       ps_setfont(p, p->ps->nextf);
                }
-               cc = p->ps->last;
-               p->ps->last = c;
-               c = cc;
+               p->ps->nextf = TERMFONT_NONE;
+               ps_pletter(p, p->ps->last);
        }
-
-       ps_pletter(p, c);
+       p->ps->last = c;
 }
 
 static void
@@ -1117,31 +1214,41 @@ ps_hspan(const struct termp *p, const struct roffsu *su)
         * All of these measurements are derived by converting from the
         * native measurement to AFM units.
         */
-
        switch (su->unit) {
-       case SCALE_CM:
-               r = PNT2AFM(p, su->scale * 28.34);
-               break;
-       case SCALE_IN:
-               r = PNT2AFM(p, su->scale * 72);
+       case SCALE_BU:
+               /*
+                * Traditionally, the default unit is fixed to the
+                * output media.  So this would refer to the point.  In
+                * mandoc(1), however, we stick to the default terminal
+                * scaling unit so that output is the same regardless
+                * the media.
+                */
+               r = PNT2AFM(p, su->scale * 72.0 / 240.0);
                break;
-       case SCALE_PC:
-               r = PNT2AFM(p, su->scale * 12);
-               break;
-       case SCALE_PT:
-               r = PNT2AFM(p, su->scale * 100);
+       case SCALE_CM:
+               r = PNT2AFM(p, su->scale * 72.0 / 2.54);
                break;
        case SCALE_EM:
                r = su->scale *
                    fonts[(int)TERMFONT_NONE].gly[109 - 32].wx;
                break;
-       case SCALE_MM:
-               r = PNT2AFM(p, su->scale * 2.834);
-               break;
        case SCALE_EN:
                r = su->scale *
                    fonts[(int)TERMFONT_NONE].gly[110 - 32].wx;
                break;
+       case SCALE_IN:
+               r = PNT2AFM(p, su->scale * 72.0);
+               break;
+       case SCALE_MM:
+               r = su->scale *
+                   fonts[(int)TERMFONT_NONE].gly[109 - 32].wx / 100.0;
+               break;
+       case SCALE_PC:
+               r = PNT2AFM(p, su->scale * 12.0);
+               break;
+       case SCALE_PT:
+               r = PNT2AFM(p, su->scale * 1.0);
+               break;
        case SCALE_VS:
                r = su->scale * p->ps->lineheight;
                break;