#ifndef _GraphicsP_h_
#define _GraphicsP_h_
/* GraphicsP.h
 *
 * Copyright (C) 1992-2002 Paul Boersma
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

/*
 * pb 2002/11/17
 */

#ifndef _Graphics_h_
	#include "Graphics.h"
#endif

typedef struct {
	unsigned char first, second, link;
	short style, size, code, baseline;
	float width;
	union { long integer; const char *string; } font;
} _Graphics_widechar;

#include "motif.h"

#define Graphics_members Thing_members \
	/* Device constants. */ \
	int screen; \
		/* A boolean for whether we are a graphic screen (which may include a non-PostScript printer. */ \
	int postScript; \
		/* A boolean for whether we are a PostScript device. */ \
	int printer; \
		/* A boolean for whether we are a printer. */ \
	Widget drawingArea; \
		/* Also used as a boolean. */ \
	int resolution; \
		/* Dots per inch. */ \
	short x1DCmin, x2DCmax, y1DCmin, y2DCmax; \
		/* Maximum dimensions of the output device. */ \
		/* x1DCmin < x2DCmax; y1DCmin < y2DCmax; */ \
		/* The point (x1DCmin, y1DCmin) can be either in the top left */ \
		/* or in the bottom left, depending on the yIsZeroAtTheTop flag. */ \
		/* Device variables. */ \
	short x1DC, x2DC, y1DC, y2DC; \
		/* Current dimensions of the output device, or: */ \
		/* device coordinates of the viewport rectangle. */ \
		/* x1DCmin <= x1DC < x2DC <= x2DCmax; */ \
		/* y1DCmin <= y1DC < y2DC <= y2DCmax; */ \
		/* Graphics_create_xxxxxx sets these coordinates to */ \
		/* x1DCmin, x2DCmax, y1DCmin, and y2DCmax. */ \
		/* They can be changed by Graphics_setWsViewport. */ \
	double x1wNDC, x2wNDC, y1wNDC, y2wNDC; \
		/* Normalized device coordinates of */ \
		/* the device viewport rectangle. */ \
		/* The point (x1wNDC, y1wNDC) is always in the bottom left.	*/ \
		/* Graphics_create_xxxxxx sets these coordinates to */ \
		/* 0.0, 1.0, 0.0, and 1.0. */ \
		/* They can be changed by Graphics_setWsWindow. */ \
	double x1NDC, x2NDC, y1NDC, y2NDC; \
		/* Normalized device coordinates of the user output viewport, */ \
		/* which is a part of the device viewport rectangle. */ \
		/* x1wNDC <= x1NDC < x2NDC <= x2wNDC; */ \
		/* y1wNDC <= y1NDC < y2NDC <= y2wNDC; */ \
		/* Graphics_create_xxxxxx sets these coordinates to */ \
		/* 0.0, 1.0, 0.0, and 1.0. */ \
		/* They can be changed by Graphics_setViewport. */ \
	double x1WC, x2WC, y1WC, y2WC; \
		/* World coordinates of the user output viewport rectangle.	*/ \
		/* They bear a relation to the "real" world,			*/ \
		/* and are used in the drawing routines.			*/ \
		/* Graphics_create_xxxxxx sets these coordinates to		*/ \
		/* 0.0, 1.0, 0.0, and 1.0.					*/ \
		/* They can be changed by Graphics_setWindow.			*/ \
	double deltaX, deltaY, scaleX, scaleY; \
		/* Current coordinate transformation. */ \
	/* Graphics state. */ \
	int lineType, colour; \
	float lineWidth; \
	int horizontalTextAlignment, verticalTextAlignment; \
	float textRotation, wrapWidth, secondIndent, textX, textY; \
	int font, fontSize, fontStyle; \
	int percentSignIsItalic, numberSignIsBold, circumflexIsSuperscript, underscoreIsSubscript; \
	int dollarSignIsCode, atSignIsLink; \
	int recording; \
	long irecord, nrecord; \
	float *record; \
	Graphics_Viewport outerViewport;   /* For Graphics_(un)setInner (). */ \
	float horTick, vertTick;   /* For Graphics_mark(s)XXX (). */ \
	double paperWidth, paperHeight;

#define Graphics_methods Thing_methods
class_create_opaque (Graphics, Thing)

int Graphics_init (I);
/*
	Postconditions:
		my font == Graphics_HELVETICA;
		my fontSize == 9;
		my fontStyle == Graphics_NORMAL;
*/ 

#define Graphics_SYMBOL  (Graphics_PALATINO + 1)
#define Graphics_IPATIMES  (Graphics_PALATINO + 2)
#define Graphics_DINGBATS  (Graphics_PALATINO + 3)

#ifdef UNIX
	#define GraphicsScreen_members Graphics_members \
		Display *display; \
		int xscreen; \
		Window rootWindow; \
		Visual *visual; \
		unsigned int depth; \
		int bitsPerPixel, pad; \
		Colormap colourMap; \
		Window window; \
		GC gc; \
		struct { \
			Window window; \
			GC gc; \
		} text;
	#define mac 0
	#define win 0
	#define xwin 1
	extern unsigned long black, white, red, green, blue, cyan, magenta, yellow,
		maroon, lime, navy, teal, purple, olive, grey [101];
#endif
#ifdef _WIN32
   	#include <windowsx.h>
	#define GraphicsScreen_members Graphics_members \
		HWND window; \
		HDC dc; \
		COLORREF foregroundColour; \
		HPEN pen; \
		HBRUSH brush; \
		int duringXor, fatNonSolid;
	#define mac 0
	#define win 1
	#define xwin 0
#endif
#if defined (macintosh)
	#include "macport_on.h"
	#include <Quickdraw.h>
	#include <MacWindows.h>
	#include "macport_off.h"
	#define GraphicsScreen_members Graphics_members \
		GrafPtr macPort; \
		MacintoshPattern macPattern; \
		int macFont, macStyle; \
		int depth; \
		RGBColor macColour;
	#define mac 1
	#define win 0
	#define xwin 0
	#if TARGET_API_MAC_CARBON
		#define carbon 1
	#else
		#define carbon 0
		#define GetQDGlobalsBlack(pat)  (*(pat) = qd.black, pat)
		#define GetQDGlobalsWhite(pat)  (*(pat) = qd.white, pat)
		#define GetQDGlobalsGray(pat)  (*(pat) = qd.gray, pat)
		#define GetQDGlobalsDarkGray(pat)  (*(pat) = qd.dkGray, pat)
		#define GetQDGlobalsLightGray(pat)  (*(pat) = qd.ltGray, pat)
		#define GetPortPixMap(port)  ((port) -> portPixMap)
		#define InvalWindowRect(win,rect)  InvalRect (rect)
		#define ValidWindowRect(win,rect)  ValidRect (rect)
	#endif
#endif

#define GraphicsScreen_methods Graphics_methods
class_create (GraphicsScreen, Graphics)

#define GraphicsPostscript_members Graphics_members \
	FILE *file;	 \
	int (*printf) (void *stream, const char *format, ...); \
	int languageLevel; \
	int photocopyable, spotsDensity, spotsAngle, landscape, includeFonts, loadedSilipaR; \
	double magnification; \
	char *fontInfos [1 + Graphics_DINGBATS] [1 + Graphics_BOLD_ITALIC]; \
	const char *lastFid; \
	int job, eps, pageNumber, lastSize;
#define GraphicsPostscript_methods Graphics_methods
class_create (GraphicsPostscript, Graphics)

/* Opcodes for recording. */

float * _Graphics_check (Graphics me, long number);
#define put(f)  * ++ p = (float) (f)
#define op(opcode,number)  float *p = _Graphics_check (me, number); if (! p) return; put (opcode); put (number)
#define mput(n,a)  { long l; float *f = a; for (l = 0; l < n; l ++) put (f [l]); }
#define sput(s,l)  { put (l); strcpy ((char *) (p + 1), s); p += l; }

/* When adding opcodes in the following list, add them at the end. */
/* Otherwise, old picture files will become incompatible with the current Graphics. */
enum opcode { SET_VIEWPORT = 101, SET_INNER, UNSET_INNER, SET_WINDOW,
	TEXT, POLYLINE, LINE, ARROW, FILL_AREA, FUNCTION, RECTANGLE, FILL_RECTANGLE,
	CIRCLE, FILL_CIRCLE, ARC, ARC_ARROW, HIGHLIGHT, CELL_ARRAY,
	SET_FONT, SET_FONT_SIZE, SET_FONT_STYLE,
	SET_TEXT_ALIGNMENT, SET_TEXT_ROTATION,
	SET_LINE_TYPE, SET_LINE_WIDTH,
	SET_COLOUR, SET_GREY,
	MARK_GROUP, ELLIPSE, FILL_ELLIPSE, CIRCLE_MM, FILL_CIRCLE_MM, IMAGE8,
	UNHIGHLIGHT, XOR_ON, XOR_OFF, RECTANGLE_MM, FILL_RECTANGLE_MM,
	SET_WS_WINDOW, SET_WRAP_WIDTH, SET_SECOND_INDENT,
	SET_PERCENT_SIGN_IS_ITALIC, SET_NUMBER_SIGN_IS_BOLD,
	SET_CIRCUMFLEX_IS_SUPERSCRIPT, SET_UNDERSCORE_IS_SUBSCRIPT,
	SET_DOLLAR_SIGN_IS_CODE, SET_AT_SIGN_IS_LINK,
	BUTTON, ROUNDED_RECTANGLE, FILL_ROUNDED_RECTANGLE, FILL_ARC,
	INNER_RECTANGLE, CELL_ARRAY8, IMAGE
};

void _Graphics_text_init (I);
void _Graphics_fillRectangle (I, short x1DC, short x2DC, short y1DC, short y2DC);
void _Graphics_setColour (I, int colour);
void _Graphics_setGrey (I, double grey);
void _Graphics_colour_init (I);

/* End of file GraphicsP.h */
#endif
