[BACK]Return to term.c CVS log [TXT][DIR] Up to [cvsweb.bsd.lv] / mandoc

Diff for /mandoc/term.c between version 1.141 and 1.142

version 1.141, 2010/06/07 10:52:44 version 1.142, 2010/06/07 20:57:09
Line 36 
Line 36 
 #include "mdoc.h"  #include "mdoc.h"
 #include "main.h"  #include "main.h"
   
 static  struct termp     *term_alloc(char *, enum termenc);  #define PS_CHAR_WIDTH     6
   #define PS_CHAR_HEIGHT    12
   #define PS_CHAR_TOPMARG  (792 - 24)
   #define PS_CHAR_TOP      (PS_CHAR_TOPMARG - 36)
   #define PS_CHAR_LEFT      36
   #define PS_CHAR_BOTMARG   24
   #define PS_CHAR_BOT      (PS_CHAR_BOTMARG + 36)
   
   static  struct termp     *alloc(char *, enum termenc, enum termtype);
 static  void              term_free(struct termp *);  static  void              term_free(struct termp *);
 static  void              spec(struct termp *, const char *, size_t);  static  void              spec(struct termp *, const char *, size_t);
 static  void              res(struct termp *, const char *, size_t);  static  void              res(struct termp *, const char *, size_t);
Line 44  static void    buffera(struct termp *, const char *, s
Line 52  static void    buffera(struct termp *, const char *, s
 static  void              bufferc(struct termp *, char);  static  void              bufferc(struct termp *, char);
 static  void              adjbuf(struct termp *p, size_t);  static  void              adjbuf(struct termp *p, size_t);
 static  void              encode(struct termp *, const char *, size_t);  static  void              encode(struct termp *, const char *, size_t);
   static  void              advance(struct termp *, size_t);
   static  void              endline(struct termp *);
   static  void              letter(struct termp *, char);
   static  void              pageopen(struct termp *);
   
   
 void *  void *
 ascii_alloc(char *outopts)  ascii_alloc(char *outopts)
 {  {
   
         return(term_alloc(outopts, TERMENC_ASCII));          return(alloc(outopts, TERMENC_ASCII, TERMTYPE_CHAR));
 }  }
   
   
   void *
   ps_alloc(void)
   {
   
           return(alloc(NULL, TERMENC_ASCII, TERMTYPE_PS));
   }
   
   
 void  void
 terminal_free(void *arg)  terminal_free(void *arg)
 {  {
Line 70  term_free(struct termp *p)
Line 90  term_free(struct termp *p)
                 free(p->buf);                  free(p->buf);
         if (p->symtab)          if (p->symtab)
                 chars_free(p->symtab);                  chars_free(p->symtab);
   
         free(p);          free(p);
 }  }
   
   
   /*
    * Push a single letter into our output engine.
    */
   static void
   letter(struct termp *p, char c)
   {
   
           if (TERMTYPE_CHAR == p->type) {
                   /*
                    * If using the terminal device, just push the letter
                    * out into the screen.
                    */
                   putchar(c);
                   return;
           }
   
           if ( ! (PS_INLINE & p->psstate)) {
                   /*
                    * If we're not in a PostScript "word" context, then
                    * open one now at the current cursor.
                    */
                   printf("%zu %zu moveto\n", p->pscol, p->psrow);
                   putchar('(');
                   p->psstate |= PS_INLINE;
           }
   
           /*
            * We need to escape these characters as per the PostScript
            * specification.  We would also escape non-graphable characters
            * (like tabs), but none of them would get to this point and
            * it's superfluous to abort() on them.
            */
   
           switch (c) {
           case ('('):
                   /* FALLTHROUGH */
           case (')'):
                   /* FALLTHROUGH */
           case ('\\'):
                   putchar('\\');
                   break;
           default:
                   break;
           }
   
           /* Write the character and adjust where we are on the page. */
           putchar(c);
           p->pscol += PS_CHAR_WIDTH;
   }
   
   
   /*
    * Begin a "terminal" context.  Since terminal encompasses PostScript,
    * the actual terminal, etc., there are a few things we can do here.
    */
   void
   term_begin(struct termp *p, term_margin head,
                   term_margin foot, const void *arg)
   {
   
           p->headf = head;
           p->footf = foot;
           p->argf = arg;
   
           if (TERMTYPE_CHAR == p->type) {
                   /* Emit the header and be done. */
                   (*p->headf)(p, p->argf);
                   return;
           }
   
           /*
            * Emit the standard PostScript prologue, set our initial page
            * position, then run pageopen() on the initial page.
            */
   
           printf("%s\n", "%!PS");
           printf("%s\n", "/Courier");
           printf("%s\n", "10 selectfont");
   
           p->pspage = 1;
           p->psstate = 0;
           pageopen(p);
   }
   
   
   /*
    * Open a page.  This is only used for -Tps at the moment.  It opens a
    * page context, printing the header and the footer.  THE OUTPUT BUFFER
    * MUST BE EMPTY.  If it is not, output will ghost on the next line and
    * we'll be all gross and out of state.
    */
   static void
   pageopen(struct termp *p)
   {
   
           assert(TERMTYPE_PS == p->type);
           assert(0 == p->psstate);
   
           p->pscol = PS_CHAR_LEFT;
           p->psrow = PS_CHAR_TOPMARG;
           p->psstate |= PS_MARGINS;
   
           (*p->headf)(p, p->argf);
           endline(p);
   
           p->psstate &= ~PS_MARGINS;
           assert(0 == p->psstate);
   
           p->pscol = PS_CHAR_LEFT;
           p->psrow = PS_CHAR_BOTMARG;
           p->psstate |= PS_MARGINS;
   
           (*p->footf)(p, p->argf);
           endline(p);
   
           p->psstate &= ~PS_MARGINS;
           assert(0 == p->psstate);
   
           p->pscol = PS_CHAR_LEFT;
           p->psrow = PS_CHAR_TOP;
   
   }
   
   
   void
   term_end(struct termp *p)
   {
   
           if (TERMTYPE_CHAR == p->type) {
                   (*p->footf)(p, p->argf);
                   return;
           }
   
           printf("%s\n", "%%END");
   }
   
   
   static void
   endline(struct termp *p)
   {
   
           if (TERMTYPE_CHAR == p->type) {
                   putchar('\n');
                   return;
           }
   
           if (PS_INLINE & p->psstate) {
                   printf(") show\n");
                   p->psstate &= ~PS_INLINE;
           }
   
           if (PS_MARGINS & p->psstate)
                   return;
   
           p->pscol = PS_CHAR_LEFT;
           if (p->psrow >= PS_CHAR_HEIGHT + PS_CHAR_BOT) {
                   p->psrow -= PS_CHAR_HEIGHT;
                   return;
           }
   
           /*
            * XXX: can't run pageopen() until we're certain a flushln() has
            * occured, else the buf will reopen in an awkward state on the
            * next line.
            */
           printf("showpage\n");
           p->psrow = PS_CHAR_TOP;
   }
   
   
   /*
    * Advance the output engine by a certain amount of whitespace.
    */
   static void
   advance(struct termp *p, size_t len)
   {
           size_t          i;
   
           if (TERMTYPE_CHAR == p->type) {
                   /* Just print whitespace on the terminal. */
                   for (i = 0; i < len; i++)
                           putchar(' ');
                   return;
           }
   
           if (PS_INLINE & p->psstate) {
                   /* Dump out any existing line scope. */
                   printf(") show\n");
                   p->psstate &= ~PS_INLINE;
           }
   
           p->pscol += len ? len * PS_CHAR_WIDTH : 0;
   }
   
   
 static struct termp *  static struct termp *
 term_alloc(char *outopts, enum termenc enc)  alloc(char *outopts, enum termenc enc, enum termtype type)
 {  {
         struct termp    *p;          struct termp    *p;
         const char      *toks[2];          const char      *toks[2];
Line 92  term_alloc(char *outopts, enum termenc enc)
Line 306  term_alloc(char *outopts, enum termenc enc)
                 exit(EXIT_FAILURE);                  exit(EXIT_FAILURE);
         }          }
   
           p->type = type;
         p->tabwidth = 5;          p->tabwidth = 5;
         p->enc = enc;          p->enc = enc;
   
         width = 80;          width = 80;
   
         while (outopts && *outopts)          while (outopts && *outopts)
Line 228  term_flushln(struct termp *p)
Line 444  term_flushln(struct termp *p)
                  */                   */
                 if (vend > bp && 0 == jhy && vis > 0) {                  if (vend > bp && 0 == jhy && vis > 0) {
                         vend -= vis;                          vend -= vis;
                         putchar('\n');                          endline(p);
                         if (TERMP_NOBREAK & p->flags) {                          if (TERMP_NOBREAK & p->flags) {
                                 p->viscol = p->rmargin;                                  p->viscol = p->rmargin;
                                 for (j = 0; j < (int)p->rmargin; j++)                                  advance(p, p->rmargin);
                                         putchar(' ');  
                                 vend += p->rmargin - p->offset;                                  vend += p->rmargin - p->offset;
                         } else {                          } else {
                                 p->viscol = 0;                                  p->viscol = 0;
Line 276  term_flushln(struct termp *p)
Line 491  term_flushln(struct termp *p)
                          * so write preceding white space now.                           * so write preceding white space now.
                          */                           */
                         if (vbl) {                          if (vbl) {
                                 for (j = 0; j < (int)vbl; j++)                                  advance(p, vbl);
                                         putchar(' ');  
                                 p->viscol += vbl;                                  p->viscol += vbl;
                                 vbl = 0;                                  vbl = 0;
                         }                          }
   
                         if (ASCII_HYPH == p->buf[i])                          if (ASCII_HYPH == p->buf[i])
                                 putchar('-');                                  letter(p, '-');
                         else                          else
                                 putchar(p->buf[i]);                                  letter(p, p->buf[i]);
   
                         p->viscol += 1;                          p->viscol += 1;
                 }                  }
Line 298  term_flushln(struct termp *p)
Line 512  term_flushln(struct termp *p)
   
         if ( ! (TERMP_NOBREAK & p->flags)) {          if ( ! (TERMP_NOBREAK & p->flags)) {
                 p->viscol = 0;                  p->viscol = 0;
                 putchar('\n');                  endline(p);
                 return;                  return;
         }          }
   
Line 331  term_flushln(struct termp *p)
Line 545  term_flushln(struct termp *p)
         if (maxvis > vis + /* LINTED */          if (maxvis > vis + /* LINTED */
                         ((TERMP_TWOSPACE & p->flags) ? 1 : 0)) {                          ((TERMP_TWOSPACE & p->flags) ? 1 : 0)) {
                 p->viscol += maxvis - vis;                  p->viscol += maxvis - vis;
                 for ( ; vis < maxvis; vis++)                  advance(p, maxvis - vis);
                         putchar(' ');                  vis += (maxvis - vis);
         } else {        /* ...or newline break. */          } else {        /* ...or newline break. */
                 putchar('\n');                  endline(p);
                 p->viscol = p->rmargin;                  p->viscol = p->rmargin;
                 for (i = 0; i < (int)p->rmargin; i++)                  advance(p, p->rmargin);
                         putchar(' ');  
         }          }
 }  }
   
Line 373  term_vspace(struct termp *p)
Line 586  term_vspace(struct termp *p)
   
         term_newln(p);          term_newln(p);
         p->viscol = 0;          p->viscol = 0;
         putchar('\n');          endline(p);
 }  }
   
   
Line 625  encode(struct termp *p, const char *word, size_t sz)
Line 838  encode(struct termp *p, const char *word, size_t sz)
          * character by character.           * character by character.
          */           */
   
         if (TERMFONT_NONE == (f = term_fonttop(p))) {          if (TERMTYPE_PS == p->type) {
                   buffera(p, word, sz);
                   return;
           } else if (TERMFONT_NONE == (f = term_fonttop(p))) {
                 buffera(p, word, sz);                  buffera(p, word, sz);
                 return;                  return;
         }          }

Legend:
Removed from v.1.141  
changed lines
  Added in v.1.142

CVSweb