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

Annotation of mandoc/term_ps.c, Revision 1.2

1.2     ! kristaps    1: /*     $Id: term_ps.c,v 1.1 2010/06/08 13:22:37 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:
        !            71: static void
        !            72: ps_end(struct termp *p)
        !            73: {
        !            74:
        !            75:        printf("%s\n", "%%EOF");
        !            76: }
        !            77:
        !            78:
        !            79: static void
        !            80: ps_begin(struct termp *p)
        !            81: {
        !            82:
        !            83:        /*
        !            84:         * Emit the standard PostScript prologue, set our initial page
        !            85:         * position, then run pageopen() on the initial page.
        !            86:         */
        !            87:
        !            88:        printf("%s\n", "%!PS");
        !            89:        printf("%s\n", "/Courier");
        !            90:        printf("%s\n", "10 selectfont");
        !            91:
        !            92:        p->engine.ps.pspage = 1;
        !            93:        p->engine.ps.psstate = 0;
        !            94:        ps_pageopen(p);
        !            95: }
        !            96:
        !            97:
        !            98: static void
        !            99: ps_letter(struct termp *p, char c)
        !           100: {
        !           101:
        !           102:        if ( ! (PS_INLINE & p->engine.ps.psstate)) {
        !           103:                /*
        !           104:                 * If we're not in a PostScript "word" context, then
        !           105:                 * open one now at the current cursor.
        !           106:                 */
        !           107:                printf("%zu %zu moveto\n",
        !           108:                                p->engine.ps.pscol,
        !           109:                                p->engine.ps.psrow);
        !           110:                putchar('(');
        !           111:                p->engine.ps.psstate |= PS_INLINE;
        !           112:        }
        !           113:
        !           114:        /*
        !           115:         * We need to escape these characters as per the PostScript
        !           116:         * specification.  We would also escape non-graphable characters
        !           117:         * (like tabs), but none of them would get to this point and
        !           118:         * it's superfluous to abort() on them.
        !           119:         */
        !           120:
        !           121:        switch (c) {
        !           122:        case ('('):
        !           123:                /* FALLTHROUGH */
        !           124:        case (')'):
        !           125:                /* FALLTHROUGH */
        !           126:        case ('\\'):
        !           127:                putchar('\\');
        !           128:                break;
        !           129:        default:
        !           130:                break;
        !           131:        }
        !           132:
        !           133:        /* Write the character and adjust where we are on the page. */
        !           134:        putchar(c);
        !           135:        p->engine.ps.pscol += PS_CHAR_WIDTH;
        !           136: }
        !           137:
        !           138:
        !           139: /*
        !           140:  * Open a page.  This is only used for -Tps at the moment.  It opens a
        !           141:  * page context, printing the header and the footer.  THE OUTPUT BUFFER
        !           142:  * MUST BE EMPTY.  If it is not, output will ghost on the next line and
        !           143:  * we'll be all gross and out of state.
        !           144:  */
        !           145: static void
        !           146: ps_pageopen(struct termp *p)
        !           147: {
        !           148:
        !           149:        assert(TERMTYPE_PS == p->type);
        !           150:        assert(0 == p->engine.ps.psstate);
        !           151:
        !           152:        p->engine.ps.pscol = PS_CHAR_LEFT;
        !           153:        p->engine.ps.psrow = PS_CHAR_TOPMARG;
        !           154:        p->engine.ps.psstate |= PS_MARGINS;
        !           155:
        !           156:        (*p->headf)(p, p->argf);
        !           157:        (*p->endline)(p);
        !           158:
        !           159:        p->engine.ps.psstate &= ~PS_MARGINS;
        !           160:        assert(0 == p->engine.ps.psstate);
        !           161:
        !           162:        p->engine.ps.pscol = PS_CHAR_LEFT;
        !           163:        p->engine.ps.psrow = PS_CHAR_BOTMARG;
        !           164:        p->engine.ps.psstate |= PS_MARGINS;
        !           165:
        !           166:        (*p->footf)(p, p->argf);
        !           167:        (*p->endline)(p);
        !           168:
        !           169:        p->engine.ps.psstate &= ~PS_MARGINS;
        !           170:        assert(0 == p->engine.ps.psstate);
        !           171:
        !           172:        p->engine.ps.pscol = PS_CHAR_LEFT;
        !           173:        p->engine.ps.psrow = PS_CHAR_TOP;
        !           174:
        !           175: }
        !           176:
        !           177:
        !           178: static void
        !           179: ps_advance(struct termp *p, size_t len)
        !           180: {
        !           181:
        !           182:        if (PS_INLINE & p->engine.ps.psstate) {
        !           183:                /* Dump out any existing line scope. */
        !           184:                printf(") show\n");
        !           185:                p->engine.ps.psstate &= ~PS_INLINE;
        !           186:        }
        !           187:
        !           188:        p->engine.ps.pscol += len ? len * PS_CHAR_WIDTH : 0;
        !           189: }
        !           190:
        !           191:
        !           192: static void
        !           193: ps_endline(struct termp *p)
        !           194: {
        !           195:
        !           196:        if (PS_INLINE & p->engine.ps.psstate) {
        !           197:                printf(") show\n");
        !           198:                p->engine.ps.psstate &= ~PS_INLINE;
        !           199:        }
        !           200:
        !           201:        if (PS_MARGINS & p->engine.ps.psstate)
        !           202:                return;
        !           203:
        !           204:        p->engine.ps.pscol = PS_CHAR_LEFT;
        !           205:        if (p->engine.ps.psrow >= PS_CHAR_HEIGHT + PS_CHAR_BOT) {
        !           206:                p->engine.ps.psrow -= PS_CHAR_HEIGHT;
        !           207:                return;
        !           208:        }
        !           209:
        !           210:        /*
        !           211:         * XXX: can't run pageopen() until we're certain a flushln() has
        !           212:         * occured, else the buf will reopen in an awkward state on the
        !           213:         * next line.
        !           214:         */
        !           215:        printf("showpage\n");
        !           216:        p->engine.ps.psrow = PS_CHAR_TOP;
1.1       kristaps  217: }

CVSweb