[BACK]Return to hpgl.trm CVS log [TXT][DIR] Up to [local] / OpenXM_contrib / gnuplot / term

File: [local] / OpenXM_contrib / gnuplot / term / Attic / hpgl.trm (download)

Revision 1.1.1.2 (vendor branch), Sat Jan 22 14:16:24 2000 UTC (24 years, 4 months ago) by maekawa
Branch: GNUPLOT
CVS Tags: maekawa-ipv6, VERSION_3_7_1, RELEASE_20000124, RELEASE_1_2_2, RELEASE_1_2_1, RELEASE_1_1_3, RELEASE_1_1_2
Changes since 1.1.1.1: +1 -1 lines

Import gnuplot 3.7.1

/*
 * $Id: hpgl.trm,v 1.7 1998/12/14 18:39:49 lhecking Exp $
 */

/* GNUPLOT - hpgl.trm */

/*[
 * Copyright 1990 - 1993, 1998
 *
 * 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:
 *  hpgl, hp7550, hp7580b, HP Laserjet III
 *  hp7550 has been replaced by  "hpgl 8 eject"
 *  hp7580b has been replaced by "hpgl 4"
 *
 * AUTHORS
 *  Colin Kelley, Thomas Williams, Russell Lang
 * 
 * send your comments or suggestions to (info-gnuplot@dartmouth.edu).
 * 
 */

/*
 *
 * MODIFIED for expanded HPGL/2 and PCL utilites
 *  Tom Swiler (tom@silica.mse.ufl.edu)
 * Modified June 1995 Ian MacPhedran to support newterm format
 * Modified October 1995 Ian MacPhedran to simplify HPGL terminals
 * Modified January 96 by David Denholm and Emmanuel Bigler for cp850
 *                               and iso international character sets
 */
#define HPGL
#define PCL

#include "driver.h"

#ifdef TERM_REGISTER
register_term(hpgl)
register_term(pcl5)
#endif /* TERM_REGISTER */

#ifdef TERM_PROTO
TERM_PUBLIC void HPGL_options __PROTO((void));
TERM_PUBLIC void HPGL2_options __PROTO((void));
TERM_PUBLIC void PCL_options __PROTO((void));
TERM_PUBLIC void HPGL_init __PROTO((void));
/* TERM_PUBLIC void HPGL2_init __PROTO((void)); */
TERM_PUBLIC void PCL_init __PROTO((void));
TERM_PUBLIC void HPGL_graphics __PROTO((void));
TERM_PUBLIC void HPGL2_graphics __PROTO((void));
TERM_PUBLIC void PCL_graphics __PROTO((void));
TERM_PUBLIC void HPGL_text __PROTO((void));
/* TERM_PUBLIC void HPGL2_text __PROTO((void)); */
TERM_PUBLIC void PCL_text __PROTO((void));
TERM_PUBLIC void HPGL_linetype __PROTO((int linetype));
TERM_PUBLIC void HPGL2_linetype __PROTO((int linetype));
TERM_PUBLIC void HPGL_put_text __PROTO((unsigned int x, unsigned int y, char *str));
TERM_PUBLIC void HPGL2_put_text __PROTO((unsigned int x, unsigned int y, char *str));
TERM_PUBLIC void HPGL_move __PROTO((unsigned int x, unsigned int y));
TERM_PUBLIC void HPGL_vector __PROTO((unsigned int x, unsigned int y));
TERM_PUBLIC void HPGL2_move __PROTO((unsigned int x, unsigned int y));
TERM_PUBLIC void HPGL2_vector __PROTO((unsigned int x, unsigned int y));
TERM_PUBLIC void HPGL2_encode __PROTO((int d));
TERM_PUBLIC int HPGL_text_angle __PROTO((int ang));
TERM_PUBLIC int HPGL2_text_angle __PROTO((int ang));
TERM_PUBLIC void HPGL_reset __PROTO((void));
/* TERM_PUBLIC void HPGL2_reset __PROTO((void)); */
TERM_PUBLIC void PCL_reset __PROTO((void));
TERM_PUBLIC int HPGL2_justify_text __PROTO((enum JUSTIFY just));
#define GOT_HPGL_PROTO
#endif /* TERM_PROTO */

#ifndef TERM_PROTO_ONLY
#ifdef TERM_BODY
/*
 * The maximum plot size, in plotter units:
 */

#define HPGL_PUPI	1016	/* Plotter units per inch */

#define HPGL_XMAX_A	10000
#define HPGL_YMAX_A	7500

#define HPGL_XMAX_B	15200
#define HPGL_YMAX_B	10000

#define HPGL_XMAX	HPGL_XMAX_A
#define HPGL_YMAX	HPGL_YMAX_A

#define PCL_XMAX	HPGL_XMAX_A
#define PCL_YMAX	(HPGL_YMAX_A-60)

/*
 * Tic sizes
 */

#define HPGL_VTIC	(HPGL_YMAX/70)
#define HPGL_HTIC	(HPGL_YMAX/70)

#define PCL_VTIC	(PCL_YMAX/70)
#define PCL_HTIC	(PCL_YMAX/70)

/*
 * Font size for HPGL
 */

#define HPGL_VCHAR	(HPGL_YMAX/100*32/10)	/* 3.2% */
#define HPGL_HCHAR	(HPGL_XMAX/100*12/10)	/* 1.2% */

/*
 * Font size for HPGL/2
 */

#define HPGL2_DEF_POINT	14	/* Height of font */

#define HPGL2_DEF_PITCH	(3 * 72 / (HPGL2_DEF_POINT * 2))
#define HPGL2_VCHAR	((int) HPGL_PUPI * HPGL2_DEF_POINT / 72)
#define HPGL2_HCHAR	(HPGL2_VCHAR * 2 / 3)

/*
 * Control constants
 */

#define DOWN		0	/* Pen is down */
#define UP 		1	/* Pen is up */
#define UNKNOWN		-10	/* Unknown status for lots of things */

/*
 * For Polyline Encoded, either use base 64 or base 32.
 * Save space with base 64, but get 8-bit characters.
 */

#ifdef NEXT
/* unluckily TRUE is defined as ((boolean_t)1) in mach/boolean.h */
#define HPGL2_BASE64 1
#else
#define HPGL2_BASE64 TRUE
#endif

#if HPGL2_BASE64
#define HPGL2_BITS 6
#define HPGL2_LOW_OFFS 63
#define HPGL2_HIGH_OFFS 191
#define HPGL2_MASK 63
#else
#define HPGL2_BITS 5
#define HPGL2_LOW_OFFS 63
#define HPGL2_HIGH_OFFS 95
#define HPGL2_MASK 31
#endif

/*
 * Data structures for options
 */

struct HPGL2_font_str {
    char *compare, *name;
    int symbol_set, spacing;
    double pitch, height;
    int posture, stroke_weight, typeface;
};

struct PCL_mode_str {
    char *compare, *name, *command;
    int xmax, ymax;
};

/*
 * The default font goes first.  Although it is the ugliest,  the
 * stick font is probably supported by the most devices, so it
 * becomes the default.
 */

static struct HPGL2_font_str GPFAR HPGL2_font_table[] =
{
    {"u$nivers", "univers", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 4148},
    {"s$tick", "stick", 277, 0, HPGL2_DEF_PITCH, 0.0, 0, 0, 48},
    {"c$g_times", "cg_times", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 4101}
};

#define HPGL2_FONTS (sizeof(HPGL2_font_table) / sizeof (struct HPGL2_font_str))
static struct HPGL2_font_str *HPGL2_font = &HPGL2_font_table[0];

/*
 * The default mode goes first.  Landscape style plots are probably the
 * most compatable with other HPGL devices.
 */

static struct PCL_mode_str GPFAR PCL_mode_table[] =
{
    {"l$andscape", "landscape", "\033&l1O", PCL_XMAX, PCL_YMAX},
    {"p$ortrait", "portrait", "\033&l0O", PCL_YMAX, PCL_XMAX}
};

#define PCL_MODES (sizeof(PCL_mode_table) / sizeof (struct PCL_mode_str))
static struct PCL_mode_str *PCL_mode = &PCL_mode_table[0];

/*
 * Various line types and widths to distinguish data sets
 */

static char *HPGL2_lt[] = { "", "4,2", "5,2", "6,2", "7,2", "8,2" },
	    *HPGL2_pw[] = { ".15", ".12", ".08" };

#define HPGL2_LINETYPES (sizeof(HPGL2_lt) / sizeof(char *))
#define HPGL2_PENWIDTHS (sizeof(HPGL2_pw) / sizeof(char *))

/* encoding vector for cp850 , characters 128 (0200) -> 255 (0377) */

static char hpgl_cp_850[128][4] =
{

/* 0200 */ "\0164\017",
/* 0201 */ "\016O\017",
/* 0202 */ "\016E\017",
/* 0203 */ "\016@\017",
/* 0204 */ "\016L\017",
/* 0205 */ "\016H\017",
/* 0206 */ "\016T\017",
/* 0207 */ "\0165\017",

/* 0210 */ "\016A\017",
/* 0211 */ "\016M\017",
/* 0212 */ "\016I\017",
/* 0213 */ "\016]\017",
/* 0214 */ "\016Q\017",
/* 0215 */ "\016Y\017",
/* 0216 */ "\016X\017",
/* 0217 */ "\016P\017",

/* 0220 */ "\016\134\017",
/* 0221 */ "\016W\017",
/* 0222 */ "\016S\017",
/* 0223 */ "\016B\017",
/* 0224 */ "\016N\017",
/* 0225 */ "\016J\017",
/* 0226 */ "\016C\017",
/* 0227 */ "\016K\017",

/* 0230 */ "\016o\017",
/* 0231 */ "\016Z\017",
/* 0232 */ "\016[\017",
/* 0233 */ "\016V\017",
/* 0234 */ "\016;\017",
/* 0235 */ "\016R\017",
/* 0236 */ "",
/* 0237 */ "\016>\017",

/* 0240 */ "\016D\017",
/* 0241 */ "\016U\017",
/* 0242 */ "\016F\017",
/* 0243 */ "\016G\017",
/* 0244 */ "\0167\017",
/* 0245 */ "\0166\017",
/* 0246 */ "\016y\017",
/* 0247 */ "\016z\017",

/* 0250 */ "\0169\017",

/* 0251 */ "",
/* 0252 */ "",

/* 0253 */ "\016x\017",
/* 0254 */ "\016w\017",
/* 0255 */ "\0168\017",
/* 0256 */ "\016{\017",
/* 0257 */ "\016}\017",

/* 0260 */ "",
/* 0261 */ "",
/* 0262 */ "",
/* 0263 */ "",
/* 0264 */ "",

/* 0265 */ "\016`\017",
/* 0266 */ "\016\042\017",
/* 0267 */ "\016!\017",

/* 0270 */ "",
/* 0271 */ "",
/* 0272 */ "",
/* 0273 */ "",
/* 0274 */ "",

/* 0275 */ "\016?\017",
/* 0276 */ "\016<\017",

/* 0277 */ "",

/* 0300 */ "",
/* 0301 */ "",
/* 0302 */ "",
/* 0303 */ "",
/* 0304 */ "",
/* 0305 */ "",

/* 0306 */ "\016b\017",
/* 0307 */ "\016a\017",

/* 0310 */ "",
/* 0311 */ "",
/* 0312 */ "",
/* 0313 */ "",
/* 0314 */ "",
/* 0315 */ "",
/* 0316 */ "",

/* 0317 */ "\016:\017",

/* 0320 */ "\016d\017",
/* 0321 */ "\016c\017",
/* 0322 */ "\016$\017",
/* 0323 */ "\016%\017",
/* 0324 */ "\016#\017",

/* 0325 */ "",

/* 0326 */ "\016e\017",
/* 0327 */ "\016&\017",

/* 0330 */ "\016'\017",

/* 0331 */ "",
/* 0332 */ "",
/* 0333 */ "",
/* 0334 */ "",
/* 0335 */ "",

/* 0336 */ "\016f\017",
/* 0337 */ "",

/* 0340 */ "\016g\017",
/* 0341 */ "\016^\017",
/* 0342 */ "\016_\017",
/* 0343 */ "\016h\017",
/* 0344 */ "\016j\017",
/* 0345 */ "\016i\017",
/* 0346 */ "",
/* 0347 */ "\016q\017",

/* 0350 */ "\016p\017",
/* 0351 */ "\016m\017",
/* 0352 */ "\016.\017",
/* 0353 */ "\016-\017",
/* 0354 */ "",
/* 0355 */ "",
/* 0356 */ "\0160\017",
/* 0357 */ "\016(\017",

/* 0360 */ "\016v\017",
/* 0361 */ "\016~\017",
/* 0362 */ "",
/* 0363 */ "",
/* 0364 */ "",
/* 0365 */ "\016=\017",
/* 0366 */ "",
/* 0367 */ "",

/* 0370 */ "\016z\017",
/* 0371 */ "\016+\017",
/* 0372 */ "",
/* 0373 */ "",
/* 0374 */ "",
/* 0375 */ "",
/* 0376 */ "",
/* 0377 */ ""
};


/* encoding vector for iso-8859-1 , characters 128 (0200) -> 255 (0377) */

static char hpgl_iso_8859_1[128][4] =
{

/* 0200 */ "",
/* 0201 */ "",
/* 0202 */ "",
/* 0203 */ "",
/* 0204 */ "",
/* 0205 */ "",
/* 0206 */ "",
/* 0207 */ "",

/* 0210 */ "",
/* 0211 */ "",
/* 0212 */ "",
/* 0213 */ "",
/* 0214 */ "",
/* 0215 */ "",
/* 0216 */ "",
/* 0217 */ "",

/* 0220 */ "",
/* 0221 */ "\016\017",
/* 0222 */ "\016\017",
/* 0223 */ "",
/* 0224 */ "",
/* 0225 */ "",
/* 0226 */ "",
/* 0227 */ "",

/* 0230 */ "",
/* 0231 */ "",
/* 0232 */ "",
/* 0233 */ "",
/* 0234 */ "",
/* 0235 */ "",
/* 0236 */ "",
/* 0237 */ "",

/* 0240 */ "",
/* 0241 */ "\0168\017",
/* 0242 */ "\0165\017",
/* 0243 */ "\016;\017",
/* 0244 */ "\016:\017",
/* 0245 */ "\016<\017",
/* 0246 */ "\017|\017",
/* 0247 */ "\016=\017",

/* 0250 */ "\016+\017",
/* 0251 */ "",
/* 0252 */ "\016y\017",
/* 0253 */ "\016{\017",
/* 0254 */ "",
/* 0255 */ "",
/* 0256 */ "",
/* 0257 */ "\0160\017",

/* 0260 */ "\016z\017",
/* 0261 */ "\016~\017",
/* 0262 */ "",
/* 0263 */ "",
/* 0264 */ "",
/* 0265 */ "",
/* 0266 */ "",
/* 0267 */ "",

/* 0270 */ "",
/* 0271 */ "",
/* 0272 */ "\016z\017",
/* 0273 */ "\016}\017",
/* 0274 */ "\016w\017",
/* 0275 */ "\016x\017",
/* 0276 */ "",
/* 0277 */ "\0169\017",

/* 0300 */ "\016!\017",
/* 0301 */ "\016`\017",
/* 0302 */ "\016\042\017",
/* 0303 */ "\016a\017",
/* 0304 */ "\016X\017",
/* 0305 */ "\016P\017",
/* 0306 */ "\016S\017",
/* 0307 */ "\0164\017",

/* 0310 */ "\016#\017",
/* 0311 */ "\016\134\017",
/* 0312 */ "\016$\017",
/* 0313 */ "\016%\017",
/* 0314 */ "\016f\017",
/* 0315 */ "\016e\017",
/* 0316 */ "\016\046\017",
/* 0317 */ "\016'\017",

/* 0320 */ "\016c\017",
/* 0321 */ "\0166\017",
/* 0322 */ "\016h\017",
/* 0323 */ "\016g\017",
/* 0324 */ "\016_\017",
/* 0325 */ "\016i\017",
/* 0326 */ "\016Z\017",
/* 0327 */ "",

/* 0330 */ "\016R\017",
/* 0331 */ "\016-\017",
/* 0332 */ "\016m\017",
/* 0333 */ "\016.\017",
/* 0334 */ "\016[\017",
/* 0335 */ "",
/* 0336 */ "\016p\017",
/* 0337 */ "\016^\017",

/* 0340 */ "\016H\017",
/* 0341 */ "\016D\017",
/* 0342 */ "\016@\017",
/* 0343 */ "\016b\017",
/* 0344 */ "\016L\017",
/* 0345 */ "\016T\017",
/* 0346 */ "\016W\017",
/* 0347 */ "\0165\017",

/* 0350 */ "\016I\017",
/* 0351 */ "\016E\017",
/* 0352 */ "\016A\017",
/* 0353 */ "\016M\017",
/* 0354 */ "\016Y\017",
/* 0355 */ "\016U\017",
/* 0356 */ "\016Q\017",
/* 0357 */ "\016]\017",

/* 0360 */ "\016d\017",
/* 0361 */ "\0167\017",
/* 0362 */ "\016J\017",
/* 0363 */ "\016F\017",
/* 0364 */ "\016B\017",
/* 0365 */ "\016j\017",
/* 0366 */ "\016N\017",
/* 0367 */ "",

/* 0370 */ "\016V\017",
/* 0371 */ "\016K\017",
/* 0372 */ "\016G\017",
/* 0373 */ "\016C\017",
/* 0374 */ "\016O\017",
/* 0375 */ "",
/* 0376 */ "\016q\017",
/* 0377 */ "\016o\017"
};


/*
 * Static variables to keep track of where we are, etc.
 */

static int HPGL_ang = 0, HPGL_x = UNKNOWN, HPGL_y = UNKNOWN, HPGL_penstate = UNKNOWN, HPGL_pentype
= UNKNOWN, HPGL2_in_pe, HPGL2_lost;

/*
 * The subroutines, grouped by function for different versions.
 */

static int HPGL_numpen, HPGL_eject;

TERM_PUBLIC void HPGL_options()
{
    HPGL_numpen = 6;		/* default to six pens */
    HPGL_eject = 0;		/* default to no eject */

    while (!END_OF_COMMAND) {
	if (almost_equals(c_token, "eje$ct"))
	    HPGL_eject = 1;
	else if (isanumber(c_token)) {
	    HPGL_numpen = (int) real(&token[c_token].l_val);
	    if (HPGL_numpen <= 0) {
		HPGL_numpen = 6;
		int_error("Number of pens must be positive", c_token);
	    }
	} else
	    int_error("expecting \"eject\" or number of pens", c_token);

	c_token++;
    }


    sprintf(term_options, "%d pens %s", HPGL_numpen,
	    HPGL_eject ? "eject" : "noeject");
}

TERM_PUBLIC void HPGL2_options()
{
    struct termentry *t = term;
    int i;
    double point_size;
    char tmp_options[MAX_ID_LEN];
    if (!END_OF_COMMAND) {
	for (i = 0; i < HPGL2_FONTS &&
	     !almost_equals(c_token, HPGL2_font_table[i].compare); i++);
	if (i < HPGL2_FONTS) {
	    HPGL2_font = &HPGL2_font_table[i];
	} else
	    int_error("expecting font: stick, cg_times, or univers", c_token);
	c_token++;
	if (!END_OF_COMMAND) {
	    if ((point_size = real(&token[c_token].l_val)) > 0.0) {
		t->v_char = (int) HPGL_PUPI *point_size / 72;
		t->h_char = t->v_char * 2 / 3;
		if (HPGL2_font->spacing)
		    HPGL2_font->height = point_size;
		else
		    HPGL2_font->pitch = 72 * 3 / (point_size * 2);
	    } else
		int_error("expecting font point size: real number", c_token);
	    c_token++;
	}
    }
    sprintf(tmp_options, " %s", HPGL2_font->name);
    strcat(term_options, tmp_options);
    if (HPGL2_font->spacing) {
	sprintf(tmp_options, " %f",
		HPGL2_font->height);
	strcat(term_options, tmp_options);
    } else {
	sprintf(tmp_options, " %f",
		HPGL2_font->pitch);
	strcat(term_options, tmp_options);
    }
}

TERM_PUBLIC void PCL_options()
{
    int i;
    if (!END_OF_COMMAND) {
	for (i = 0; i < PCL_MODES &&
	     !almost_equals(c_token, PCL_mode_table[i].compare); i++);
	if (i < PCL_MODES)
	    PCL_mode = &PCL_mode_table[i];
	else
	    int_error("expecting mode: portrait or landscape", c_token);
	c_token++;
    }
    sprintf(term_options, " %s", PCL_mode->name);
    HPGL2_options();
}

TERM_PUBLIC void HPGL_init()
{
}

/* void HPGL2_init ()
{
} */

TERM_PUBLIC void PCL_init()
{
    struct termentry *t = term;
/*
 * Reset printer, set to one copy, orientation of user's choice.
 * Make the change to the new orientation all at once.
 */
    fprintf(gpoutfile, "\033E\033&l1X%s\n", PCL_mode->command);
    t->xmax = PCL_mode->xmax;
    t->ymax = PCL_mode->ymax;
}

TERM_PUBLIC void HPGL_graphics()
{
    fputs("\033.Y\n\033.I81;;17:\033.N;19:\033.M500:\n", gpoutfile);
/*	       1
	1. enable eavesdropping
*/
    fprintf(gpoutfile,
	    "IN;%s\nSC0,%d,0,%d;\nSR%f,%f;\n",
	    ((encoding == ENCODING_CP_850) || (encoding == ENCODING_ISO_8859_1)) ?
	    "CA7;" : "",
	    HPGL_XMAX, HPGL_YMAX,
	    ((double) (HPGL_HCHAR) * 200 / 3 / HPGL_XMAX),
	    ((double) (HPGL_VCHAR) * 100 / 2 / HPGL_YMAX));
/*	 1    2             3 
	1. reset to power-up defaults
	2. set SCaling
	3. set character size
*/
    HPGL_ang = 0;
}

TERM_PUBLIC void HPGL2_graphics()
{
/*
 * IN - Initialize
 * SP - Select pen
 * SD - Set default font
 */
    fprintf(gpoutfile, "INSP1SD1,%d,2,%d,",
	    HPGL2_font->symbol_set, HPGL2_font->spacing);
    if (HPGL2_font->spacing)
	fprintf(gpoutfile, "4,%f,", HPGL2_font->height);
    else
	fprintf(gpoutfile, "3,%f,", HPGL2_font->pitch);
    fprintf(gpoutfile, "5,%d,6,%d,7,%d\n", HPGL2_font->posture,
	    HPGL2_font->stroke_weight, HPGL2_font->typeface);
/*
 * Control variables
 */
    HPGL_ang = 0;		/* Horizontal */
    HPGL2_in_pe = FALSE;	/* Not in PE command */
    HPGL2_lost = TRUE;		/* Pen position is unknown */
    HPGL_penstate = UP;		/* Pen is up */
}

TERM_PUBLIC void PCL_graphics()
{
/*
 * Enter HPGL/2 graphics mode
 */
    fputs("\033%0B", gpoutfile);
    HPGL2_graphics();
}

TERM_PUBLIC void HPGL_text()
{
    if (HPGL_eject == 0) {
	fputs("PUSP0;\033.Z\n\0", gpoutfile);
/*		 1 2   3
	1. pen up
	2. park pen
	3. disable eavesdropping
*/
    } else {
	fputs("PUSP0;PG;\033.Z\n\0", gpoutfile);
/*		 1 2   3  4
	1. pen up
	2. park pen
	3. page eject
	4. disable eavesdropping
*/
    }
    HPGL_penstate = UP;
}

#if 0				/* not used */
void HPGL2_text()
{
/*
 * If in Polyline Encoded command, leave Polyline Encoded command
 */
    if (HPGL2_in_pe) {
	fputs(";\n", gpoutfile);
	HPGL2_in_pe = 0;
    }
/*
 * Pen up, park pen
 */
    fputs("PUSP0;", gpoutfile);
}
#endif

TERM_PUBLIC void PCL_text()
{
    if (HPGL2_in_pe) {
	fputs(";\n", gpoutfile);
	HPGL2_in_pe = 0;
    }
/*
 * Go into PCL mode and eject the page
 */
    fputs("\033%1A\033&l0H\n\0", gpoutfile);
}

TERM_PUBLIC void HPGL_linetype(linetype)
int linetype;
{
/* allow for set number of pens */
    linetype = (linetype + 2) % HPGL_numpen + 1;
/* only select pen if necessary */
    if (HPGL_pentype != linetype) {
	fprintf(gpoutfile, "PU;\nSP%d;\n", linetype);
	HPGL_pentype = linetype;
	HPGL_penstate = UP;
    }
}

TERM_PUBLIC void HPGL2_linetype(linetype)
int linetype;
{
/*
 * If in Polyline Encoded command, leave Polyline Encoded command
 */
    if (HPGL2_in_pe) {
	fputs(";\n", gpoutfile);
	HPGL2_in_pe = 0;
    }
/*
 * Allow for lots of linetypes
 */
    if (linetype >= 0)
	linetype = linetype % (HPGL2_LINETYPES * HPGL2_PENWIDTHS);
    if (linetype != HPGL_pentype) {
	if (linetype >= 0) {
	    fprintf(gpoutfile, "PW%sLT%s",
		    HPGL2_pw[linetype / HPGL2_LINETYPES],
		    HPGL2_lt[linetype % HPGL2_LINETYPES]);
	} else if (linetype == -2)
/*
 * Borders and tics
 */
	    fprintf(gpoutfile, "PW.2LT");
	else if (linetype == -1)
/*
 * Axes and grids
 */
	    fprintf(gpoutfile, "PW.1LT1,.25");
	HPGL_pentype = linetype;
    }
}

TERM_PUBLIC void HPGL_put_text(x, y, str)
unsigned int x, y;
char *str;
{
    if (HPGL_ang == 1)
	HPGL_move(x + HPGL_VCHAR / 4, y);
    else
	HPGL_move(x, y - HPGL_VCHAR / 4);
    if (encoding == ENCODING_CP_850) {
	unsigned char *s;
	fputs("LB", gpoutfile);
	for (s = (unsigned char *) str; *s; ++s)
	    if (*s >= 128 && hpgl_cp_850[*s - 128][0])
		fputs(hpgl_cp_850[*s - 128], gpoutfile);
	    else
		putc(*s, gpoutfile);
	fputs("\003\n", gpoutfile);
    } else if (encoding == ENCODING_ISO_8859_1) {
	unsigned char *s;
	fputs("LB", gpoutfile);
	for (s = (unsigned char *) str; *s; ++s)
	    if (*s >= 128 && hpgl_iso_8859_1[*s - 128][0])
		fputs(hpgl_iso_8859_1[*s - 128], gpoutfile);
	    else
		putc(*s, gpoutfile);
	fputs("\003\n", gpoutfile);
    } else
	fprintf(gpoutfile, "LB%s\003\n", str);
}

TERM_PUBLIC void HPGL2_put_text(x, y, str)
unsigned int x, y;
char *str;
{
    struct termentry *t = term;
/*
 * Position the pen
 */
    if (HPGL_ang == 1)
	HPGL2_move(x + t->v_char / 4, y);
    else
	HPGL2_move(x, y - t->v_char / 4);
/*
 * If in Polyline Encoded command, leave Polyline Encoded command
 */
    if (HPGL2_in_pe) {
	fputs(";\n", gpoutfile);
	HPGL2_in_pe = 0;
    }
/*
 * Print the text string
 */
    fprintf(gpoutfile, "LB%s\003\n", str);
    HPGL2_lost = 1;
}
/*
 * Some early HPGL plotters (e.g. HP7220C) require the
 * Pen Up/Down and Pen (move) Absolute commands to be separate.
 */

TERM_PUBLIC void HPGL_move(x, y)
unsigned int x, y;
{
    if (HPGL_x != x || HPGL_y != y) {	/* only move if necessary */
	fprintf(gpoutfile, "PU;PA%d,%d;\n", x, y);
	HPGL_penstate = UP;
	HPGL_x = x;
	HPGL_y = y;
    }
}

TERM_PUBLIC void HPGL_vector(x, y)
unsigned int x, y;
{
    if (HPGL_penstate != DOWN) {
	fprintf(gpoutfile, "PD;PA%d,%d;\n", x, y);
	HPGL_penstate = DOWN;
    } else
	fprintf(gpoutfile, "PA%d,%d;\n", x, y);
    HPGL_x = x;
    HPGL_y = y;
}

TERM_PUBLIC void HPGL2_move(x, y)
unsigned int x, y;
{
    register int dx, dy;
    if (HPGL2_in_pe) {
	dx = x - HPGL_x;
	dy = y - HPGL_y;
	fputs("<", gpoutfile);
    } else {
#if HPGL2_BASE64
	fputs("PE<", gpoutfile);
#else
	fputs("PE7<", gpoutfile);
#endif
	if (HPGL2_lost) {
	    dx = x;
	    dy = y;
	    HPGL2_lost = 0;
	    fputs("=", gpoutfile);
	} else {
	    dx = x - HPGL_x;
	    dy = y - HPGL_y;
	}
	HPGL2_in_pe = 1;
    }
#if HPGL2_EXPLICIT_PD
    if (HPGL_penstate == DOWN)
	HPGL_penstate = UP;
#endif
    HPGL2_encode(dx);
    HPGL2_encode(dy);
    fputs("\n", gpoutfile);
    HPGL_x = x;
    HPGL_y = y;
}

TERM_PUBLIC void HPGL2_vector(x, y)
unsigned int x, y;
{
    register int dx, dy;
    if (HPGL2_in_pe) {
	dx = x - HPGL_x;
	dy = y - HPGL_y;
    } else {
#if HPGL2_BASE64
	fputs("PE", gpoutfile);
#else
	fputs("PE7", gpoutfile);
#endif
	if (HPGL2_lost) {
	    dx = x;
	    dy = y;
	    HPGL2_lost = 0;
	    fputs("=", gpoutfile);
	} else {
	    dx = x - HPGL_x;
	    dy = y - HPGL_y;
	}
	HPGL2_in_pe = 1;
    }
#if HPGL2_EXPLICIT_PD
/*
 * Put the pen down in the current position,
 * relative vector of 0,0.
 */
    if (HPGL_penstate == UP) {
	fputc((char) HPGL2_HIGH_OFFS, gpoutfile);
	fputc((char) HPGL2_HIGH_OFFS, gpoutfile);
	HPGL_penstate = DOWN;
    }
#endif
    HPGL2_encode(dx);
    HPGL2_encode(dy);
    fputs("\n", gpoutfile);
    HPGL_x = x;
    HPGL_y = y;
}

/*
 * Routine to encode position in base 32 or base 64 characters
 */

TERM_PUBLIC void HPGL2_encode(d)
register int d;
{
    register int c;
    if ((d <<= 1) < 0)
	d = 1 - d;
    do {
	c = d & HPGL2_MASK;
	d >>= HPGL2_BITS;
	if (d > 0)
	    fputc((char) (c + HPGL2_LOW_OFFS), gpoutfile);
	else
	    fputc((char) (c + HPGL2_HIGH_OFFS), gpoutfile);
    } while (d > 0);
}

TERM_PUBLIC int HPGL_text_angle(ang)
int ang;
{
    HPGL_ang = ang;
    if (ang == 1)
/*
 *  Vertical
 */
	fputs("DI0,1;\n", gpoutfile);
    else
/*
 * Horizontal
 */
	fputs("DI1,0;\n", gpoutfile);
    return TRUE;
}

TERM_PUBLIC int HPGL2_text_angle(ang)
int ang;
{
/*
 * If in Polyline Encoded command, leave Polyline Encoded command
 */
    if (HPGL2_in_pe) {
	fputs(";", gpoutfile);
	HPGL2_in_pe = 0;
    }
    if (ang == 1)
/*
 *  Vertical
 */
	fputs("DI0,1", gpoutfile);
    else
/*
 * Horizontal
 */
	fputs("DI1,0", gpoutfile);
    HPGL_ang = ang;
    return TRUE;
}

TERM_PUBLIC void HPGL_reset()
{
/*
 * do nothing
 */
}

#if 0
void HPGL2_reset()
{
/*
 * Park the pen
 * Advance a page
 * End with ";"
 */
    fputs("SP0PG;\n", gpoutfile);
}

#endif

TERM_PUBLIC void PCL_reset()
{
/*
 * Return to PCL mode
 * Printer reset (conditional eject)
 */
    fputs("\033%0A\033E\n", gpoutfile);
}

TERM_PUBLIC int HPGL2_justify_text(just)
enum JUSTIFY just;
{
/*
 * If in Polyline Encoded command, leave Polyline Encoded command
 */
    if (HPGL2_in_pe) {
	fputs(";\n", gpoutfile);
	HPGL2_in_pe = 0;
    }
    switch (just) {
    case LEFT:
	fputs("LO1", gpoutfile);
	break;
    case CENTRE:
	fputs("LO4", gpoutfile);
	break;
    case RIGHT:
	fputs("LO7", gpoutfile);
	break;
    default:
	return 0;
    }
    return 1;
}

#endif /* TERM_BODY */

#ifdef TERM_TABLE
TERM_TABLE_START(hpgl_driver)
    "hpgl", "HP7475 and relatives [number of pens] [eject]",
    HPGL_XMAX, HPGL_YMAX, HPGL_VCHAR, HPGL_HCHAR,
    HPGL_VTIC, HPGL_HTIC, HPGL_options, HPGL_init, HPGL_reset,
    HPGL_text, null_scale, HPGL_graphics, HPGL_move, HPGL_vector,
    HPGL_linetype, HPGL_put_text, HPGL_text_angle,
    null_justify_text, do_point, do_arrow, set_font_null
TERM_TABLE_END(hpgl_driver)

#undef LAST_TERM
#define LAST_TERM hpgl_driver

    TERM_TABLE_START(pcl5_driver)
    "pcl5", "HP LaserJet III [mode] [font] [point]",
    PCL_XMAX, PCL_YMAX, HPGL2_VCHAR, HPGL2_HCHAR,
    PCL_VTIC, PCL_HTIC, PCL_options, PCL_init, PCL_reset,
    PCL_text, null_scale, PCL_graphics, HPGL2_move, HPGL2_vector,
    HPGL2_linetype, HPGL2_put_text, HPGL2_text_angle,
    HPGL2_justify_text, do_point, do_arrow, set_font_null
TERM_TABLE_END(pcl5_driver)

#undef LAST_TERM
#define LAST_TERM pcl5_driver
#endif /* TERM_TABLE */

#endif /* TERM_PROTO_ONLY */

#ifdef TERM_HELP
START_HELP(hpgl)
"1 hpgl",
"?commands set terminal hpgl",
"?set terminal hpgl",
"?set term hpgl",
"?terminal hpgl",
"?term hpgl",
"?hpgl",
"?commands set terminal pcl5",
"?set terminal pcl5",
"?set term pcl5",
"?terminal pcl5",
"?term pcl5",
"?pcl5",
" The `hpgl` driver produces HPGL output for devices like the HP7475A plotter.",
" There are two options which can be set---the number of pens and \"eject\", which",
" tells the plotter to eject a page when done.  The default is to use 6 pens",
" and not to eject the page when done.",
"",
" The international character sets ISO-8859-1 and CP850 are recognized via",
" `set encoding iso_8859_1` or `set encoding cp850` (see `set encoding` for",
" details).",
"",
" Syntax:",
"       set terminal hpgl {<number_of_pens>} {eject}",
"",
" The selection",
"",
"       set terminal hpgl 8 eject",
"",
" is equivalent to the previous `hp7550` terminal, and the selection",
"",
"       set terminal hpgl 4",
"",
" is equivalent to the previous `hp7580b` terminal.",
"",
" The `pcl5` driver supports the Hewlett-Packard Laserjet III.  It actually uses",
" HPGL-2, but there is a name conflict among the terminal devices.  It has",
" several options",
"",
" Syntax:",
"       set terminal pcl5 {<mode>} {<font>} {<fontsize>}",
"",
" where <mode> is `landscape`, or `portrait`, <font> is `stick`, `univers`, or",
" `cg_times`, and <fontsize> is the size in points.",
"",
" With `pcl5` international characters are handled by the printer; you just put",
" the appropriate 8-bit character codes into the text strings.  You don't need",
" to bother with `set encoding`.",
"",
" HPGL graphics can be imported by many software packages."
END_HELP(hpgl)
#endif /* TERM_HELP */