/* Hello, Emacs, this is -*-C-*- */
/* GNUPLOT - imagen.trm */
/*[
* Copyright 1990 - 1993, 1998, 2004
*
* Permission to use, copy, and distribute this software and its
* documentation for any purpose with or without fee is hereby granted,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation.
*
* Permission to modify the software is granted, but not the right to
* distribute the complete modified source code. Modifications are to
* be distributed as patches to the released version. Permission to
* distribute binaries produced by compiling modified sources is granted,
* provided you
* 1. distribute the corresponding source modifications from the
* released version in the form of a patch file along with the binaries,
* 2. add special version identification to distinguish your version
* in addition to the base release version number,
* 3. provide your name and address as the primary contact for the
* support of your modified version, and
* 4. retain our contact information in regard to use of the base
* software.
* Permission to distribute the released version of the source code along
* with corresponding source modifications in the form of a patch file is
* granted with same provisions 2 through 4 for binary distributions.
*
* This software is provided "as is" without express or implied warranty
* to the extent permitted by applicable law.
]*/
/*
* This file is included by ../term.c.
*
* This terminal driver supports:
* Imagen laser printers
*
* AUTHORS
* Paul E. McKenney, David Kotz
* Rewritten/extended by:
* Hans Olav Eggestad
* send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
*
*/
/*
* Original for direct Imagen output (but retaining many of the
* LaTeX extensions) by Paul E. McKenney, 1989.
* Further modified by David Kotz to fit into gnuplot 2.0.
* Information Science and Technology Division, SRI International,
* 333 Ravenswood Ave, Menlo Park, CA 94025.
* Mail to mckenney@sri.com.
*/
/*
* adapted to the new terminal layout by Stefan Bodewig (Dec. 1995)
*/
#include "driver.h"
#ifdef TERM_REGISTER
register_term(imagen)
#endif
#ifdef TERM_PROTO
TERM_PUBLIC void IMAGEN_init(void);
TERM_PUBLIC void IMAGEN_graphics(void);
TERM_PUBLIC void IMAGEN_options(void);
TERM_PUBLIC void IMAGEN_text(void);
TERM_PUBLIC void IMAGEN_linetype(int lt);
TERM_PUBLIC void IMAGEN_move(unsigned int x, unsigned int y);
TERM_PUBLIC void IMAGEN_vector(unsigned int ux, unsigned int uy);
TERM_PUBLIC int IMAGEN_text_angle(int ang);
TERM_PUBLIC int IMAGEN_justify_text(enum JUSTIFY mode);
TERM_PUBLIC void IMAGEN_put_text(unsigned int x, unsigned int y, const char str[]);
TERM_PUBLIC void IMAGEN_reset(void);
#define IMAGEN_PTS_PER_INCH (300)
#define IMAGEN_XMAX (IMAGEN_PTS_PER_INCH * 11) /* 10.0 inches */
#define IMAGEN_YMAX (IMAGEN_PTS_PER_INCH * 78 / 10) /* 7.5 inches */
#define IMAGEN_HTIC (20)
#define IMAGEN_VTIC (20)
#define IMAGEN_VCHAR (IMAGEN_FONTSIZE*5)
#define IMAGEN_HCHAR (IMAGEN_VCHAR/2)
#endif /* TERM_PROTO */
#ifndef TERM_PROTO_ONLY
#ifdef TERM_BODY
static void IM_page(void);
static void IMAGEN_draw_path(void);
static void IMAGEN_setpos(int ux, int uy);
static unsigned char *IMAGEN_cvts(unsigned char *str, int *width, int *height);
static void IMAGEN_putwd(unsigned int w);
static void IMAGEN_createfamily(char *c, int sz);
static void IMAGEN_setfont(int sz);
static void IMP_set_draw_pattern(int pattern, int sz);
static void IMAGEN_mapsinit(void);
static void IMAGEN_createmap(int name, unsigned short *map);
/*
#ifndef __malloc_h
#include
#endif
*/
#include "impcodes.h"
/* default is landscape */
#define IMAGEN_A4_H (IMAGEN_PTS_PER_INCH * 83 / 10)
#define IMAGEN_A4_W (IMAGEN_PTS_PER_INCH * 116 / 10)
/* width in current orientation */
static int IMAGEN_Xmax = IMAGEN_XMAX;
static int IMAGEN_Ymax = IMAGEN_YMAX;
#define IMAGEN_FONTSIZE 12
#define IMAGEN_FONT "cour"
static unsigned short IMP_gmap[128];
static unsigned char IMP_chmap[256];
static int IMAGEN_page_h = IMAGEN_A4_H;
static int IMAGEN_page_w = IMAGEN_A4_W;
static int IM_win_horiz = 1;
static int IM_win_verti = 1;
static int IM_plot_nr = 0;
static int IMAGEN_fontsize = IMAGEN_FONTSIZE;
static int IMAGEN_familytable[36];
static int IMAGEN_orgX; /* absolute-pixel-ORIgin of graph page. */
static int IMAGEN_orgY;
static int IMAGEN_orgx; /* absolute-pixel-ORIgin of current graph. */
static int IMAGEN_orgy;
static int IMAGEN_posx; /* current drawing position (lines). */
static int IMAGEN_posy;
/* static int IMAGEN_inplot; */
static int IMAGEN_xmax = IMAGEN_XMAX; /* width of graph in pixels. */
static int IMAGEN_ymax = IMAGEN_YMAX; /* height of graph in pixels. */
static int IMAGEN_winx = IMAGEN_XMAX; /* width of window in pixels. */
static int IMAGEN_winy = IMAGEN_YMAX; /* height of window in pixels. */
static int IMAGEN_hchar; /* Height of CHAR in current font. */
static int IMAGEN_wchar; /* Width of CHAR in current font. */
static int IMAGEN_blofs; /* BaseLine OFfSet from bounding box. */
static int IMAGEN_angle = -1; /* 0 for horizontal text, 1 for vertical */
static int IMAGEN_portrait; /* 0 for landscape */
static enum JUSTIFY IMAGEN_justify = LEFT; /* left/center/right */
#define STOREPATH 100
static unsigned int IM_xvector[STOREPATH]; /* draw path vector of x values */
static unsigned int IM_yvector[STOREPATH]; /* draw path vector of y values */
static unsigned int IM_veclen; /* length of allocated path vector */
static unsigned int IM_vecpos = 0; /* current pos in vector */
/* char IMPdrpattern[10][10] = { {0}, {30,10,0}, {0}, {10,30,0}, {2,20,0},
{20,10,0}, {30,20,10,20,0}, {30,20,4,10,10,10,4,20,0}, {40,20,0}, {30,15,4,15,0}
};
*/
static char IMPdrpattern[10][10] =
{
/* -2 */ {0},
/* -1 */ {1, 8, 0},
/* 0 */ {0},
/* 1 */ {16, 4, 0},
/* 2 */ {3, 8, 0},
/* 3 */ {8, 8, 0},
/* 4 */ {16, 6, 3, 6, 0},
/* 5 */ {16, 6, 8, 6, 0},
/* 6 */ {16, 4, 1, 4, 8, 4, 1, 4, 0},
/* 7 */ {16, 4, 1, 8, 1, 4, 0}
};
enum IMAGEN_id { IMAGEN_PORTRAIT, IMAGEN_LANDSCAPE, IMAGEN_OTHER };
static struct gen_table IMAGEN_opts[] =
{
{ "p$ortrait", IMAGEN_PORTRAIT },
{ "l$andscape", IMAGEN_LANDSCAPE },
{ NULL, IMAGEN_OTHER }
};
TERM_PUBLIC void
IMAGEN_options()
{
struct value a;
while (!END_OF_COMMAND) {
switch(lookup_table(&IMAGEN_opts[0],c_token)) {
case IMAGEN_PORTRAIT:
IMAGEN_portrait = TRUE;
IMAGEN_page_h = IMAGEN_A4_W;
IMAGEN_page_w = IMAGEN_A4_H;
IMAGEN_Xmax = IMAGEN_YMAX;
IMAGEN_Ymax = IMAGEN_XMAX;
c_token++;
break;
case IMAGEN_LANDSCAPE:
IMAGEN_portrait = FALSE;
c_token++;
break;
case IMAGEN_OTHER:
default:
if (equals(c_token, "[")) { /* windows specified */
c_token++;
/* if (IM_plot_nr>1) */
if (equals(c_token, "]")) {
IM_page();
c_token++;
break;
}
if (END_OF_COMMAND) {
int_error(c_token, "no. windows: [horizontal,vertical] expected");
} else if (!equals(c_token, ",")) {
IM_win_horiz = (int) real(const_express(&a));
}
if (!equals(c_token, ","))
int_error(c_token, "',' expected");
c_token++;
if (!equals(c_token, "]")) {
IM_win_verti = (int) real(const_express(&a));
}
if (!equals(c_token, "]"))
int_error(c_token, "expecting ']'");
c_token++;
} else {
/* We have font size specified */
IMAGEN_fontsize = (int) real(const_express(&a));
if (IMAGEN_fontsize < 8)
IMAGEN_fontsize = 8;
if (IMAGEN_fontsize > 15)
IMAGEN_fontsize = 15;
}
}
}
sprintf(term_options, "%d %s [%1d,%1d]", IMAGEN_fontsize, (IMAGEN_portrait) ? "portrait" :
"landscape", IM_win_horiz, IM_win_verti);
}
TERM_PUBLIC void
IMAGEN_init()
{
register struct termentry *t = term;
/* char font[10]; */ /* font name */
IMAGEN_posx = IMAGEN_posy = 0;
IMAGEN_orgX = (IMAGEN_page_w - IMAGEN_Xmax) / 2;
IMAGEN_orgY = (IMAGEN_page_h - IMAGEN_Ymax) / 2;
IMAGEN_xmax = IMAGEN_winx = (int) (IMAGEN_Xmax / IM_win_horiz);
IMAGEN_ymax = IMAGEN_winy = (int) (IMAGEN_Ymax / IM_win_verti);
t->xmax = (unsigned int) (IMAGEN_xmax);
t->ymax = (unsigned int) (IMAGEN_ymax);
fputs("@document(language impress, paper a4)", gpoutfile);
if (IMAGEN_portrait) {
putc(imP_SET_ABS_V, gpoutfile);
IMAGEN_putwd(3520);
}
putc(imP_SET_HV_SYSTEM, gpoutfile);
putc(((IMAGEN_portrait ? 3 : 0) horiz : 7=>vert */
}
return (TRUE);
}
TERM_PUBLIC int
IMAGEN_justify_text(enum JUSTIFY mode)
{
if (IM_vecpos) {
/* fprintf(stderr,"justify_text, draw path\n"); */
IMAGEN_draw_path();
}
IMAGEN_justify = mode;
return (TRUE);
}
static unsigned char *
IMAGEN_cvts(unsigned char *str, int *width, int *height)
{
unsigned char *cp1;
unsigned char *cp2;
static unsigned char *buf = NULL;
int h;
int maxw;
int w;
/* Free up old buffer, if there is one, get a new one. Since */
/* all transformations shorten the string, get a buffer that is */
/* the same size as the input string. */
if (buf != NULL)
(void) free(buf);
buf = (unsigned char *) gp_alloc(strlen((char *) str)+2, "converted label string");
/* Do the transformations. */
cp1 = str;
cp2 = buf;
h = 1;
maxw = 0;
w = 0;
while (strlen((char *) cp1) > 0) {
switch (*cp1) {
case ' ': /* Space character. */
*cp2++ = imP_SP;
w++;
break;
case '\\': /* Escape sequence. */
if (*++cp1 == '\\') {
/* Begin new line. */
h++;
if (w > maxw)
maxw = w;
w = 0;
*cp2++ = '\n';
/* *cp2++ = imP_CRLF; */
break;
}
/* Fall through to just copy next char out. */
default:
/* *cp2++ = *cp1; */
*cp2++ = IMP_chmap[*cp1];
w++;
break;
}
cp1++;
}
*cp2++ = '\n';
*cp2 = '\0';
if (w > maxw)
maxw = w;
if (height != NULL)
*height = IMAGEN_angle ?
IMAGEN_wchar * maxw :
IMAGEN_hchar * h;
if (width != NULL)
*width = IMAGEN_angle ?
IMAGEN_hchar * h :
IMAGEN_wchar * maxw;
return (buf);
}
TERM_PUBLIC void
IMAGEN_put_text(unsigned int x, unsigned int y, const char str[])
{
unsigned char *cvstr, *p;
int height;
int width;
int sx, sy;
if (IM_vecpos) {
/* fprintf(stderr,"put_text, draw path\n"); */
IMAGEN_draw_path();
}
cvstr = IMAGEN_cvts((unsigned char *) str, &width, &height);
if (IMAGEN_angle) { /* vertical */
/* x += IMAGEN_hchar; */
x -= width / 2 - IMAGEN_hchar;
/* y -= height/2; */
} else /* horizontal */
y += height / 2 - IMAGEN_hchar;
while ((p = (unsigned char *) strchr((char *) cvstr, '\n'))) {
*p = '\0';
sx = x;
sy = y;
if (IMAGEN_angle)
sx = x - IMAGEN_blofs;
else
sy = y + IMAGEN_blofs;
width = strlen((char *) cvstr) * IMAGEN_wchar;
switch (IMAGEN_justify) {
case LEFT:
break;
case CENTRE:
if (IMAGEN_angle) {
sy = y - width / 2;
} else {
sx = x - width / 2;
}
break;
/*x -= width/2; break; */
case RIGHT:
if (IMAGEN_angle) {
sy = y - width;
} else {
sx = x - width;
}
break;
/* x -= width; break; */
}
IMAGEN_setpos(sx, sy);
fputs((char *) cvstr, gpoutfile);
cvstr = ++p;
if (IMAGEN_angle) { /* vertical */
x += IMAGEN_hchar;
} else {
y -= IMAGEN_hchar;
}
}
}
TERM_PUBLIC void
IMAGEN_reset()
{
if (IM_vecpos) {
/* fprintf(stderr,"reset, draw path\n"); */
IMAGEN_draw_path();
}
putc(imP_EOF, gpoutfile);
}
static void
IMAGEN_putwd(unsigned int w)
{
/* fprintf(stderr,"%1u\n",w); */
putc(w >> 8, gpoutfile);
putc(w, gpoutfile);
}
static void
IMAGEN_createfamily(char *c, int sz)
{
putc(imP_CREATE_FAMILY_TABLE, gpoutfile);
putc(sz, gpoutfile);
putc(1, gpoutfile);
putc(1, gpoutfile);
/* putc(0, gpoutfile); */
fputs(c, gpoutfile);
putc(0, gpoutfile);
}
static void
IMAGEN_setfont(int sz)
{
char font[20];
if (!IMAGEN_familytable[sz]) {
sprintf(font, "%s%02d", IMAGEN_FONT, sz);
IMAGEN_createfamily(font, sz);
IMAGEN_familytable[sz] = sz;
}
IMAGEN_hchar = sz * 5;
IMAGEN_wchar = IMAGEN_hchar / 2;
IMAGEN_blofs = IMAGEN_hchar / 3;
term->v_char = IMAGEN_hchar;
term->h_char = IMAGEN_wchar;
putc(imP_SET_FAMILY, gpoutfile);
putc(sz, gpoutfile);
putc(imP_SET_SP, gpoutfile);
IMAGEN_putwd(IMAGEN_wchar);
putc(imP_SET_IL, gpoutfile);
IMAGEN_putwd(IMAGEN_hchar);
}
static void
IMP_set_draw_pattern(int pattern, int sz)
{
int i /*,j */ ;
putc(imP_SET_DRAW_PATTERN, gpoutfile);
putc(0, gpoutfile);
putc(imP_SET_DRAW_PATTERN, gpoutfile);
/* if ( strlen(IMPdrpattern[pattern]) == 1 ) {
putc(type,gpoutfile);
return;
} */
putc(strlen(IMPdrpattern[pattern]), gpoutfile);
for (i = 0; i < strlen(IMPdrpattern[pattern]); i++) {
IMAGEN_putwd(IMPdrpattern[pattern][i] * sz);
}
}
static void
IMAGEN_mapsinit()
{
register int i /*, j */ ;
for (i = 32; i < 127; i++) {
IMP_gmap[i] = i;
}
IMP_gmap[1] = 225;
IMP_gmap[2] = 233;
IMP_gmap[3] = 61736;
IMP_gmap[4] = 241;
IMP_gmap[5] = 249;
IMP_gmap[6] = 61864;
IMP_gmap[7] = 162;
IMP_gmap[8] = 163;
IMP_gmap[9] = 164;
IMP_gmap[10] = 165;
IMP_gmap[11] = 167;
IMP_gmap[12] = 171;
IMP_gmap[13] = 182;
IMP_gmap[14] = 61346;
IMP_gmap[15] = 191;
IMP_gmap[16] = 187;
IMP_gmap[17] = 188;
IMP_gmap[18] = 189;
IMP_gmap[19] = 190;
IMP_gmap[20] = 210;
IMP_gmap[21] = 211;
IMP_gmap[22] = 251;
IMP_gmap[23] = 61232;
IMP_gmap[24] = 212;
IMP_gmap[25] = 137;
IMP_gmap[26] = 176;
IMP_gmap[27] = 161;
IMP_gmap[28] = 139;
IMP_gmap[29] = 133;
IMP_gmap[30] = 140;
IMP_gmap[31] = 61249;
IMP_gmap[32] = 8738;
IMP_gmap[34] = 186;
IMP_gmap[36] = 164;
IMP_gmap[39] = 185;
IMP_gmap[127] = 61286;
/* for (i=1;i