/* Hello, Emacs, this is -*-C-*- */
/* GNUPLOT - hpgl.trm */
/*[
* Copyright 1990 - 1993, 1998, 2004, 2018
*
* 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.h.
*
* 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"
* pcl5e/c compatible printers
*
* AUTHORS
* Colin Kelley, Thomas Williams, Russell Lang
*
* send your comments or suggestions to (gnuplot-info@lists.sourceforge.net).
*
*/
/*
*
* 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
* Modified February 99 by Jeremy Brenes to give PCL5 terminal optional
* multi-pen support (6 pen default), a default 34" plotting width for
* use with large color plotters such as the HP Designjet 750C,
* various alternative plot sizes, and variable fontsizes;
* Also decreased the HPGL terminal's fixed fontsize to make it more
* reasonable when plots get scaled to 34"
* Modified July 99 by Jeremy Brenes to make extended plot area smaller;
* added solid/dashed lines option, additional font types, mixed fonts
* Modified November 99 by Jeremy Brenes to add a postscript pointtypes
* option, special purpose negative pointtypes, and a pointsize function
* Modified March 18 by Bastian Maerkisch: enhancements to the pcl5 driver:
* option parser more in line with current standards:
* terminal options in arbitrary order; common canvas size and font options
* remove monochrome/solid/dashed option
* change option defaults to 8 pens (PCL5c spec), letter size, and pspoints;
* filled polygons and filled boxes; palette and RGB colors;
* explicit vertical center alignment of text instead of relying on font
* metric guess; rotate text by arbitrary angles; request font "symbol set"
* according to current encoding; bold/italic font support; UTF-8 encoding;
* ignore case/spaces/underscores in font names; more (typical) fonts;
* permit some alternative font alias from non-HP vendors; enhanced text;
* variable line width; optional rounded line ends and joins;
* version 5 dashed lines, including custom dash types; optimized point
* symbols; linewidth/pointsize/fontscale options;
* make use of TBOOLEAN type; separate help texts for hpgl and pcl5;
*
*/
#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(void);
TERM_PUBLIC void PCL_options(void);
TERM_PUBLIC void HPGL_init(void);
/* TERM_PUBLIC void HPGL2_init(void); */
TERM_PUBLIC void PCL_init(void);
TERM_PUBLIC void HPGL_graphics(void);
TERM_PUBLIC void HPGL2_graphics(void);
TERM_PUBLIC void PCL_graphics(void);
TERM_PUBLIC void HPGL_text(void);
/* TERM_PUBLIC void HPGL2_text(void); */
TERM_PUBLIC void PCL_text(void);
TERM_PUBLIC void HPGL_linetype(int linetype);
TERM_PUBLIC void HPGL2_linetype(int linetype);
TERM_PUBLIC void HPGL_put_text(unsigned int x, unsigned int y, const char *str);
TERM_PUBLIC void HPGL2_put_text(unsigned int x, unsigned int y, const char *str);
TERM_PUBLIC void HPGL_move(unsigned int x, unsigned int y);
TERM_PUBLIC void HPGL_vector(unsigned int x, unsigned int y);
TERM_PUBLIC void HPGL2_move(unsigned int x, unsigned int y);
TERM_PUBLIC void HPGL2_vector(unsigned int x, unsigned int y);
TERM_PUBLIC void HPGL2_encode(int d);
TERM_PUBLIC int HPGL_text_angle(float ang);
TERM_PUBLIC int HPGL2_text_angle(float ang);
TERM_PUBLIC void HPGL_reset(void);
/* TERM_PUBLIC void HPGL2_reset(void); */
TERM_PUBLIC void PCL_reset(void);
TERM_PUBLIC int HPGL2_justify_text(enum JUSTIFY just);
TERM_PUBLIC int HPGL2_set_font(const char *font);
TERM_PUBLIC void HPGL2_point(unsigned int x, unsigned int y, int number);
TERM_PUBLIC void HPGL2_neg_point(unsigned int x, unsigned int y, int number);
TERM_PUBLIC void HPGL2_pointsize(double size);
TERM_PUBLIC void HPGL2_linewidth(double linewidth);
TERM_PUBLIC void HPGL2_fillbox(int style, unsigned int x1, unsigned int y1, unsigned int width, unsigned int height);
TERM_PUBLIC void HPGL2_filled_polygon(int points, gpiPoint *corners);
TERM_PUBLIC void HPGL2_set_color(t_colorspec *colorspec);
TERM_PUBLIC int HPGL2_make_palette(t_sm_palette *palette);
TERM_PUBLIC void HPGL2_enh_put_text(unsigned int x, unsigned int y, const char str[]);
TERM_PUBLIC void HPGL2_enh_open(char * fontname, double fontsize,
double base, TBOOLEAN widthflag, TBOOLEAN showflag,
int overprint);
TERM_PUBLIC void HPGL2_enh_flush(void);
#define GOT_HPGL_PROTO
#endif /* TERM_PROTO */
#ifndef TERM_PROTO_ONLY
#ifdef TERM_BODY
#ifndef M_SQRT2
#define M_SQRT2 1.41
#endif
/*
* The maximum plot size, in plotter units.
* Note that the actual size of larger plots may be limited by
* available printer memory.
*/
#define HPGL_PUPI 1016 /* Plotter units per inch */
/* Letter */
#define HPGL_XMAX_A 10000
#define HPGL_YMAX_A 7500
/* Legal */
#define HPGL_XMAX_B 13000
#define HPGL_YMAX_B 7500
/* Noextended */
#define HPGL_XMAX_C 45333
#define HPGL_YMAX_C 34000
/* Extended */
#define HPGL_XMAX_D 52000
#define HPGL_YMAX_D 34000
/* A4 */
#define HPGL_XMAX_E 10000
#define HPGL_YMAX_E 7900
#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 ((HPGL_YMAX_C-60)/320)
#define PCL_HTIC ((HPGL_YMAX_C-60)/320)
/*
* Font size for HPGL
*/
#define HPGL_VCHAR (HPGL_YMAX/100*8/10) /* 0.8% */
#define HPGL_HCHAR (HPGL_XMAX/100*3/10) /* 0.3% */
/*
* Font size for HPGL/2
*/
#define HPGL2_DEF_POINT 12 /* 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)
/*
* Number of available point types for HPGL/2
*/
#define HPGL2_NUM_NOPSPOINTS 6; /* for nopspoints option */
#define HPGL2_NUM_PSPOINTS 75; /* for pspoints option */
/*
* 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.
*/
#define HPGL2_BASE64 1
#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
/*
* Local Prototypes
*/
static void HPGL2_put_text_here(const char *str, TBOOLEAN centeralign);
static int HPGL2_set_font_size(const char *font, double size);
static int HPGL2_map_encoding(void);
static void HPGL2_end_poly(void);
static void HPGL2_dot(int x, int y);
static void HPGL2_diamond(int x, int y, int htic, int vtic);
static void HPGL2_filled_diamond(int x, int y, int htic, int vtic);
static void HPGL2_pentagon(int x, int y, int htic, int vtic);
/*
* Data structures for options
*/
struct HPGL2_font_str {
const char *compare, *alt, *name;
int symbol_set, spacing;
double pitch, height;
int posture, stroke_weight, italic, bold;
int typeface;
};
struct PCL_mode_str {
const char *name, *command;
unsigned int xmax, ymax;
};
/*
* The default font goes first.
*/
static struct HPGL2_font_str HPGL2_font_table[] = {
{ "Un$ivers", "Swiss 742$ SWC", "univers", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 1, 3, 4148 },
{ "St$ick", NULL, "stick", 277, 0, HPGL2_DEF_PITCH, 0.0, 0, 0, 1, 3, 48 },
{ "Al$bertus", "Flare$serif 821", "albertus", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 1, 0, 4, 4362 },
{ "An$tique_Olive", "Inci$sed 901", "antique_olive", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 1, 3, 4168 },
{ "Ar$ial", "Swiss 721", "arial", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 1, 3, 16602 },
{ "Av$ant Garde Gothic", "Geom$etric 711", "avant_garde_gothic", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 1, 2, 24607 },
{ "Bo$okman", "Bookman SWA", "bookman", 277, 1, 0.0, HPGL2_DEF_POINT, 0, -3, 1, 2, 24623 },
{ "Zapf Ch$ancery", "Chan$cery 801", "zapf_chancery", 277, 1, 0.0, HPGL2_DEF_POINT, 1, 0, 1, 0, 45099 },
{ "Cl$arendon Condensed", "Clarendon 701", "clarendon", 277, 1, 0.0, HPGL2_DEF_POINT, 4, 3, 4, 3, 4140 },
{ "Cor$onet", "Ribbon$ 131", "coronet", 277, 1, 0.0, HPGL2_DEF_POINT, 1, 0, 1, 0, 4116 },
{ "Cou$rier", "FixedPitch 810", "courier", 277, 0, HPGL2_DEF_PITCH, 0.0, 0, 0, 1, 3, 4099 },
{ "CourierPS", "Courier SWA", "courier", 277, 0, HPGL2_DEF_PITCH, 0.0, 0, 0, 1, 3, 24579 },
{ "CG Ti$mes", "Dutch 801$ SWA", "cg_times", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 1, 3, 4101 },
{ "Ga$ramond Antiqua", "Aldine 430", "garamond_antigua", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 1, 3, 4197 },
{ "Helv$etica", "Swiss$ SWA", "helvetica", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 1, 3, 24580 },
{ "Helvetica N$arrow", "SwissNarrow$ SWA", "helvetica_narrow", 277, 1, 0.0, HPGL2_DEF_POINT, 4, 0, 5, 3, 24580 },
{ "Le$tter Gothic", "FixedPitch 850", "letter_gothic", 277, 0, HPGL2_DEF_PITCH, 0.0, 0, 0, 1, 3, 4102 },
{ "Ma$rigold", "Calli$graphic 401", "marigold", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 0, 0, 4297 },
{ "New Cen$tury Schlbk", "Cent$urySchbk", "new_century_schlbk", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 1, 3, 24703 },
{ "CG O$mega", "Zapf Humanist$ 601", "cg_omega", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 1, 3, 4113 },
{ "Pa$latino", "Zapf Callig$raphic 801", "palatino", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 1, 3, 24591 },
{ "Ti$mes_New_Roman", "Dutch 801$ SWM", "times_new_roman", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 1, 3, 16901 },
{ "Times Ro$man", "Dutch SWA", "times_roman", 277, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 1, 3, 25093 },
{ "Zapf Di$ngbats", "Ding$ Dings", "zapf_dingbats", 460, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 0, 0, 45101 },
{ "Symbol$ Set", NULL, "symbol", 621, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 0, 0, 4142 },
{ "Symbol PS", "Symbol Set SWA", "symbol_ps", 621, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 0, 0, 45358 },
{ "Tr$uetype_Symbols", NULL, "truetype_symbols", 621, 1, 0.0, HPGL2_DEF_POINT, 0, 0, 0, 0, 16686 },
{ "Wi$ngdings", "More WingBats$ SWC", "wingdings", 18540, 1, 0.0, HPGL2_DEF_POINT, 1, 0, 1, 0, 31402 }
};
#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 compatible with other HPGL devices.
*/
static struct PCL_mode_str PCL_mode_table[] = {
{ "landscape", "\033&l1O" },
{ "portrait", "\033&l0O" }
};
#define PCL_MODES (sizeof(PCL_mode_table) / sizeof (struct PCL_mode_str))
static struct PCL_mode_str PCL_mode = { NULL, NULL, PCL_XMAX, PCL_YMAX };
/* 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