[40f1e82] | 1 | /* hpgl.cc |
---|
| 2 | * Export from Aven as HPGL. |
---|
| 3 | */ |
---|
[2198c1a] | 4 | /* Copyright (C) 1993-2003,2005,2010,2014,2015,2016,2019 Olly Betts |
---|
[40f1e82] | 5 | * |
---|
| 6 | * This program is free software; you can redistribute it and/or modify |
---|
| 7 | * it under the terms of the GNU General Public License as published by |
---|
| 8 | * the Free Software Foundation; either version 2 of the License, or |
---|
| 9 | * (at your option) any later version. |
---|
| 10 | * |
---|
| 11 | * This program is distributed in the hope that it will be useful, |
---|
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
---|
| 14 | * GNU General Public License for more details. |
---|
| 15 | * |
---|
| 16 | * You should have received a copy of the GNU General Public License |
---|
| 17 | * along with this program; if not, write to the Free Software |
---|
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
---|
| 19 | */ |
---|
| 20 | |
---|
| 21 | #ifdef HAVE_CONFIG_H |
---|
| 22 | # include <config.h> |
---|
| 23 | #endif |
---|
| 24 | |
---|
| 25 | #include <stdio.h> |
---|
| 26 | |
---|
| 27 | #include "hpgl.h" |
---|
| 28 | #include "useful.h" |
---|
| 29 | |
---|
| 30 | # define HPGL_USE_UC |
---|
| 31 | /*# define HPGL_USE_SR */ /* for text sized relative to page size */ |
---|
| 32 | |
---|
| 33 | # define HPGL_UNITS_PER_MM 40 |
---|
| 34 | # define HPGL_EOL "\003" /* terminates labelling commands: LB<string>\003 */ |
---|
| 35 | |
---|
| 36 | # ifndef HPGL_USE_UC |
---|
| 37 | # define HPGL_SO "\016" /* shift in & shift out of extended character set */ |
---|
| 38 | # define HPGL_SI "\017" |
---|
| 39 | # endif |
---|
| 40 | |
---|
| 41 | # define HPGL_CROSS_SIZE 28 /* length of cross arms (in HPGL units) */ |
---|
| 42 | |
---|
| 43 | static long xpPageWidth, ypPageDepth; |
---|
| 44 | |
---|
| 45 | static long x_org = 0, y_org = 0; |
---|
| 46 | static bool fNewLines = fTrue; |
---|
| 47 | static bool fOriginInCentre = fFalse; |
---|
| 48 | |
---|
| 49 | /* Check if this line intersects the current page */ |
---|
| 50 | /* Initialise HPGL routines. */ |
---|
[55a861a] | 51 | void HPGL::header(const char *, const char *, time_t, |
---|
| 52 | double, double, double, double, double, double) |
---|
[40f1e82] | 53 | { |
---|
| 54 | // FIXME: mm_across_page, mm_down_page, origin_in_centre, scale |
---|
| 55 | double PaperWidth = 9999999, PaperDepth = 9999999; |
---|
| 56 | fOriginInCentre = true; |
---|
| 57 | |
---|
| 58 | xpPageWidth = (long)(HPGL_UNITS_PER_MM * (double)PaperWidth); |
---|
| 59 | ypPageDepth = (long)(HPGL_UNITS_PER_MM * (double)PaperDepth); |
---|
| 60 | |
---|
| 61 | /* SR scales characters relative to P1 and P2 */ |
---|
| 62 | /* SI scales characters to size given (in cm) */ |
---|
| 63 | /* INitialise; Select Pen 1; */ |
---|
| 64 | /* Either: Scale chars Relative to P1 & P2 0.5,1.0 (2/3 deflt size) */ |
---|
| 65 | /* Or: Scale chars absolute to 2/3 of default size on A4 page */ |
---|
| 66 | fputs("IN;SP1;" |
---|
| 67 | #ifndef HPGL_USE_UC |
---|
| 68 | "CA-1;GM0,800;" /* Char set Alternate -1; Get Memory; */ |
---|
| 69 | #endif |
---|
| 70 | #ifdef HPGL_USE_SR |
---|
| 71 | "SR0.5,1.0;" |
---|
| 72 | #else |
---|
| 73 | "SI0.125,.179;" |
---|
| 74 | #endif |
---|
| 75 | , fh); |
---|
[e02a6a6] | 76 | if (fNewLines) PUTC('\n', fh); |
---|
[40f1e82] | 77 | |
---|
| 78 | #ifndef HPGL_USE_UC |
---|
| 79 | /* define degree and copyright symbols */ |
---|
| 80 | fputs("DL32,10,30,12,30,13,29,13,27,12,26,10,26,9,27,9,29," |
---|
| 81 | "10,30;DL40,0,0;", fh); /* Hope this works! Seems to for BP */ |
---|
[e02a6a6] | 82 | if (fNewLines) PUTC('\n', fh); |
---|
[40f1e82] | 83 | |
---|
| 84 | fputs("DL67,16,14,16,18,17,22,19,25,22,28,26,30,31,31,37,32," |
---|
| 85 | "43,32,49,31,53,30,58,28,61,25,63,22,64,18,64,14,63,10," |
---|
| 86 | "61,7,58,4,53,2,49,1,43,0,37,0,31,1,26,2,22,4,19,7,17,10," |
---|
| 87 | "16,14;", fh); |
---|
[e02a6a6] | 88 | if (fNewLines) PUTC('\n', fh); |
---|
[40f1e82] | 89 | |
---|
| 90 | fputs("DL41,4,20,3,19,0,23,-4,24,-9,24,-14,23,-17,22,-20,19," |
---|
| 91 | "-21,16,-20,13,-17,10,-14,9,-9,8,-4,8,0,9,3,11,4,12;", fh); |
---|
[e02a6a6] | 92 | if (fNewLines) PUTC('\n', fh); |
---|
[40f1e82] | 93 | #endif |
---|
| 94 | #if 0 |
---|
| 95 | /* and set clipping (Input Window!) on plotter (left,bottom,right,top) */ |
---|
| 96 | fprintf(fh, "IW%ld,%ld,%ld,%ld;", clip.x_min - x_org, clip.y_min - y_org, |
---|
| 97 | clip.x_min - x_org + xpPageWidth, clip.y_min - y_org + ypPageDepth); |
---|
| 98 | #endif |
---|
| 99 | } |
---|
| 100 | |
---|
| 101 | void |
---|
[a2c29c1] | 102 | HPGL::line(const img_point *p1, const img_point *p, unsigned /*flags*/, bool fPending) |
---|
[40f1e82] | 103 | { |
---|
| 104 | if (fPending) { |
---|
| 105 | fprintf(fh, "PU%ld,%ld;", long(p1->x - x_org), long(p1->y - y_org)); |
---|
| 106 | } |
---|
| 107 | fprintf(fh, "PD%ld,%ld;", long(p->x - x_org), long(p->y - y_org)); |
---|
| 108 | } |
---|
| 109 | |
---|
| 110 | #define CS HPGL_CROSS_SIZE |
---|
| 111 | #define CS2 (2 * HPGL_CROSS_SIZE) |
---|
| 112 | void |
---|
[41f7a27] | 113 | HPGL::cross(const img_point *p, bool /*fSurface*/) |
---|
[40f1e82] | 114 | { |
---|
| 115 | fprintf(fh, "PU%ld,%ld;", long(p->x - x_org), long(p->y - y_org)); |
---|
| 116 | /* SM plots a symbol at each point, but it isn't very convenient here */ |
---|
| 117 | /* We can write PDPR%d,%dPR%d,%d... but the HP7475A manual doesn't say */ |
---|
| 118 | /* clearly if this will work on older plotters (such as the HP9872) */ |
---|
| 119 | fprintf(fh, "PD;PR%d,%d;PR%d,%d;PU%d,0;PD%d,%d;PU%d,%d;PA;", |
---|
| 120 | CS, CS, -CS2, -CS2, CS2, /*0,*/ -CS2, CS2, CS, -CS); |
---|
[e02a6a6] | 121 | if (fNewLines) PUTC('\n', fh); |
---|
[40f1e82] | 122 | } |
---|
| 123 | #undef CS |
---|
| 124 | #undef CS2 |
---|
| 125 | |
---|
| 126 | void |
---|
[fdea415] | 127 | HPGL::label(const img_point *p, const char *s, bool /*fSurface*/, int) |
---|
[40f1e82] | 128 | { |
---|
| 129 | /* LB is a text label, terminated with a ^C */ |
---|
| 130 | fprintf(fh, "PU%ld,%ld;LB", long(p->x - x_org), long(p->y - y_org)); |
---|
| 131 | while (*s) { |
---|
| 132 | switch (*s) { |
---|
| 133 | case '\xB0': |
---|
| 134 | #ifdef HPGL_USE_UC |
---|
| 135 | /* draw a degree sign */ |
---|
[2198c1a] | 136 | fputs(HPGL_EOL ";UC1.25,7.5,99,.25,0,.125,-.25,0,-.5," |
---|
[40f1e82] | 137 | "-.125,-.25,-.25,0,-.125,.25,0,.5,.125,.25;LB", fh); |
---|
| 138 | #else |
---|
| 139 | /* KLUDGE: this prints the degree sign if the plotter supports |
---|
| 140 | * extended chars or a space if not, since we tried to redefine |
---|
| 141 | * space. Nifty, eh? */ |
---|
[2198c1a] | 142 | fputs(HPGL_SO " " HPGL_SI, fh); |
---|
[40f1e82] | 143 | #endif |
---|
| 144 | break; |
---|
| 145 | case '\xA9': |
---|
| 146 | #ifdef HPGL_USE_UC |
---|
| 147 | /* (C) needs two chars to look right! */ |
---|
| 148 | /* This bit does the circle of the (C) symbol: */ |
---|
[2198c1a] | 149 | fputs(HPGL_EOL ";", fh); |
---|
[e02a6a6] | 150 | if (fNewLines) PUTC('\n', fh); |
---|
[40f1e82] | 151 | fputs("UC2,3.5,99,0,1,0.125,1,0.25,.75,0.375,.75," |
---|
| 152 | ".5,.5,.625,.25,.75,.25,.75,0,.75,-.25,.625,-.25," |
---|
| 153 | ".5,-.5,.375,-.75,.25,-.75,.125,-1,0,-1,-0.125,-1," |
---|
| 154 | "-0.25,-.75,-0.375,-.75,-.5,-.5,-.625,-.25,-.75,-.25," |
---|
| 155 | "-.75,0,-.75,.25,-.625,.25,-.5,.5,-.375,.75,-.25,.75," |
---|
| 156 | "-.125,1;", fh); |
---|
[e02a6a6] | 157 | if (fNewLines) PUTC('\n', fh); |
---|
[40f1e82] | 158 | /* And this bit's the c in the middle: */ |
---|
| 159 | fputs("UC.5,5,99,-.125,.25,-.375,.5,-.5,.25,-.625,0," |
---|
| 160 | "-.625,-.25,-.375,-.25,-.375,-.75,-.125,-.75,.125,-.75," |
---|
| 161 | ".375,-.75,.375,-.25,.625,-.25,.625,0,.5,.25,.375,.5," |
---|
| 162 | ".125,.25;", fh); |
---|
[e02a6a6] | 163 | if (fNewLines) PUTC('\n', fh); |
---|
[40f1e82] | 164 | fputs("LB", fh); |
---|
| 165 | #else |
---|
[2198c1a] | 166 | fputs(HPGL_SO "(C)" HPGL_SI, fh); |
---|
[40f1e82] | 167 | #endif |
---|
| 168 | break; |
---|
| 169 | default: |
---|
[e02a6a6] | 170 | PUTC(*s, fh); |
---|
[40f1e82] | 171 | } |
---|
| 172 | s++; |
---|
| 173 | } |
---|
[2198c1a] | 174 | fputs(HPGL_EOL ";", fh); |
---|
[e02a6a6] | 175 | if (fNewLines) PUTC('\n', fh); |
---|
[40f1e82] | 176 | } |
---|
| 177 | |
---|
| 178 | void |
---|
| 179 | HPGL::footer() |
---|
| 180 | { |
---|
| 181 | /* Clear clipping window; New page. NB PG is a no-op on the HP7475A */ |
---|
| 182 | fputs("IW;PG;", fh); |
---|
[e02a6a6] | 183 | if (fNewLines) PUTC('\n', fh); |
---|
[40f1e82] | 184 | } |
---|