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

Annotation of mandoc/term_ps.c, Revision 1.3

1.3     ! kristaps    1: /*     $Id: term_ps.c,v 1.2 2010/06/08 15:00:17 kristaps Exp $ */
1.1       kristaps    2: /*
                      3:  * Copyright (c) 2008, 2009 Kristaps Dzonsons <kristaps@kth.se>
                      4:  *
                      5:  * Permission to use, copy, modify, and distribute this software for any
                      6:  * purpose with or without fee is hereby granted, provided that the above
                      7:  * copyright notice and this permission notice appear in all copies.
                      8:  *
                      9:  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
                     10:  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
                     11:  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
                     12:  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
                     13:  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
                     14:  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
                     15:  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
                     16:  */
                     17: #ifdef HAVE_CONFIG_H
                     18: #include "config.h"
                     19: #endif
                     20:
1.2       kristaps   21: #include <assert.h>
                     22: #include <stdio.h>
1.1       kristaps   23: #include <stdlib.h>
                     24:
                     25: #include "out.h"
                     26: #include "main.h"
                     27: #include "term.h"
                     28:
1.2       kristaps   29: #define        PS_CHAR_WIDTH     6
                     30: #define        PS_CHAR_HEIGHT    12
                     31: #define        PS_CHAR_TOPMARG  (792 - 24)
                     32: #define        PS_CHAR_TOP      (PS_CHAR_TOPMARG - 36)
                     33: #define        PS_CHAR_LEFT      36
                     34: #define        PS_CHAR_BOTMARG   24
                     35: #define        PS_CHAR_BOT      (PS_CHAR_BOTMARG + 36)
                     36:
                     37: static void              ps_letter(struct termp *, char);
                     38: static void              ps_begin(struct termp *);
                     39: static void              ps_end(struct termp *);
                     40: static void              ps_pageopen(struct termp *);
                     41: static void              ps_advance(struct termp *, size_t);
                     42: static void              ps_endline(struct termp *);
                     43:
                     44:
1.1       kristaps   45: void *
                     46: ps_alloc(void)
                     47: {
                     48:        struct termp    *p;
                     49:
                     50:        if (NULL == (p = term_alloc(TERMENC_ASCII)))
                     51:                return(NULL);
                     52:
                     53:        p->type = TERMTYPE_PS;
1.2       kristaps   54:        p->letter = ps_letter;
                     55:        p->begin = ps_begin;
                     56:        p->end = ps_end;
                     57:        p->advance = ps_advance;
                     58:        p->endline = ps_endline;
1.1       kristaps   59:        return(p);
                     60: }
                     61:
                     62:
                     63: void
                     64: ps_free(void *arg)
                     65: {
                     66:
                     67:        term_free((struct termp *)arg);
1.2       kristaps   68: }
                     69:
                     70:
1.3     ! kristaps   71: /* ARGSUSED */
1.2       kristaps   72: static void
                     73: ps_end(struct termp *p)
                     74: {
                     75:
                     76:        printf("%s\n", "%%EOF");
                     77: }
                     78:
                     79:
                     80: static void
                     81: ps_begin(struct termp *p)
                     82: {
                     83:
                     84:        /*
                     85:         * Emit the standard PostScript prologue, set our initial page
                     86:         * position, then run pageopen() on the initial page.
                     87:         */
                     88:
                     89:        printf("%s\n", "%!PS");
                     90:        printf("%s\n", "/Courier");
                     91:        printf("%s\n", "10 selectfont");
                     92:
                     93:        p->engine.ps.pspage = 1;
                     94:        p->engine.ps.psstate = 0;
                     95:        ps_pageopen(p);
                     96: }
                     97:
                     98:
                     99: static void
                    100: ps_letter(struct termp *p, char c)
                    101: {
                    102:
                    103:        if ( ! (PS_INLINE & p->engine.ps.psstate)) {
                    104:                /*
                    105:                 * If we're not in a PostScript "word" context, then
                    106:                 * open one now at the current cursor.
                    107:                 */
                    108:                printf("%zu %zu moveto\n",
                    109:                                p->engine.ps.pscol,
                    110:                                p->engine.ps.psrow);
                    111:                putchar('(');
                    112:                p->engine.ps.psstate |= PS_INLINE;
                    113:        }
                    114:
                    115:        /*
                    116:         * We need to escape these characters as per the PostScript
                    117:         * specification.  We would also escape non-graphable characters
                    118:         * (like tabs), but none of them would get to this point and
                    119:         * it's superfluous to abort() on them.
                    120:         */
                    121:
                    122:        switch (c) {
                    123:        case ('('):
                    124:                /* FALLTHROUGH */
                    125:        case (')'):
                    126:                /* FALLTHROUGH */
                    127:        case ('\\'):
                    128:                putchar('\\');
                    129:                break;
                    130:        default:
                    131:                break;
                    132:        }
                    133:
                    134:        /* Write the character and adjust where we are on the page. */
                    135:        putchar(c);
                    136:        p->engine.ps.pscol += PS_CHAR_WIDTH;
                    137: }
                    138:
                    139:
                    140: /*
                    141:  * Open a page.  This is only used for -Tps at the moment.  It opens a
                    142:  * page context, printing the header and the footer.  THE OUTPUT BUFFER
                    143:  * MUST BE EMPTY.  If it is not, output will ghost on the next line and
                    144:  * we'll be all gross and out of state.
                    145:  */
                    146: static void
                    147: ps_pageopen(struct termp *p)
                    148: {
                    149:
                    150:        assert(TERMTYPE_PS == p->type);
                    151:        assert(0 == p->engine.ps.psstate);
                    152:
                    153:        p->engine.ps.pscol = PS_CHAR_LEFT;
                    154:        p->engine.ps.psrow = PS_CHAR_TOPMARG;
                    155:        p->engine.ps.psstate |= PS_MARGINS;
                    156:
                    157:        (*p->headf)(p, p->argf);
                    158:        (*p->endline)(p);
                    159:
                    160:        p->engine.ps.psstate &= ~PS_MARGINS;
                    161:        assert(0 == p->engine.ps.psstate);
                    162:
                    163:        p->engine.ps.pscol = PS_CHAR_LEFT;
                    164:        p->engine.ps.psrow = PS_CHAR_BOTMARG;
                    165:        p->engine.ps.psstate |= PS_MARGINS;
                    166:
                    167:        (*p->footf)(p, p->argf);
                    168:        (*p->endline)(p);
                    169:
                    170:        p->engine.ps.psstate &= ~PS_MARGINS;
                    171:        assert(0 == p->engine.ps.psstate);
                    172:
                    173:        p->engine.ps.pscol = PS_CHAR_LEFT;
                    174:        p->engine.ps.psrow = PS_CHAR_TOP;
                    175:
                    176: }
                    177:
                    178:
                    179: static void
                    180: ps_advance(struct termp *p, size_t len)
                    181: {
                    182:
                    183:        if (PS_INLINE & p->engine.ps.psstate) {
                    184:                /* Dump out any existing line scope. */
                    185:                printf(") show\n");
                    186:                p->engine.ps.psstate &= ~PS_INLINE;
                    187:        }
                    188:
                    189:        p->engine.ps.pscol += len ? len * PS_CHAR_WIDTH : 0;
                    190: }
                    191:
                    192:
                    193: static void
                    194: ps_endline(struct termp *p)
                    195: {
                    196:
                    197:        if (PS_INLINE & p->engine.ps.psstate) {
                    198:                printf(") show\n");
                    199:                p->engine.ps.psstate &= ~PS_INLINE;
                    200:        }
                    201:
                    202:        if (PS_MARGINS & p->engine.ps.psstate)
                    203:                return;
                    204:
                    205:        p->engine.ps.pscol = PS_CHAR_LEFT;
                    206:        if (p->engine.ps.psrow >= PS_CHAR_HEIGHT + PS_CHAR_BOT) {
                    207:                p->engine.ps.psrow -= PS_CHAR_HEIGHT;
                    208:                return;
                    209:        }
                    210:
                    211:        /*
                    212:         * XXX: can't run pageopen() until we're certain a flushln() has
                    213:         * occured, else the buf will reopen in an awkward state on the
                    214:         * next line.
                    215:         */
                    216:        printf("showpage\n");
                    217:        p->engine.ps.psrow = PS_CHAR_TOP;
1.1       kristaps  218: }

CVSweb