// GptDisp.cpp -  pcGPlot display classes
// copyright 1992 Pittsburgh Supercomputing Center
#include  "gpt.h"
#include  "cgm.h" // basic display classes
#include  "cgmdisp.h" // basic display classes
#include  "gptDisp.h"

extern void myError(const char*, const char *msg2 = NULL, int severity = 1);
const float pcScale     = .5;   // PC Scale factor for line, edge width
const unsigned long PAL = 0X2000000 ;
const int DEFAULT_INDEX = 1;
int set_color2( COLORREF *out, const genColr &in);


// *** pcDisplay::pcDisplay -  Constructor
pcDisplay::pcDisplay(CgmWindowPt win, HDC hdc, HDC hdcMeta,
						  HDC hdcInfo, RECT *rect) : baseDisplay() // constructor
	{
	BOOL hoho;
	this->cgmWin = win;
	this->hdc    = hdc;
	this->hdcMeta = hdcMeta;
	myPxlExtent  = new vdcPts(0, 0, (int)rect->right  , (int)rect->bottom);

	int horzsize = GetDeviceCaps(hdcInfo,HORZSIZE);  // Width in millimeters
	int vertsize = GetDeviceCaps(hdcInfo,VERTSIZE);  // Height in millimeters
	int horzres  = GetDeviceCaps(hdcInfo,HORZRES);   // Width in pixels
	int vertres  = GetDeviceCaps(hdcInfo,VERTRES);   // Height in raster lines
	myxPxlSize   = (double)horzsize/horzres;  // mm/pix
	myyPxlSize   = (double)vertsize/vertres;  // mm/pix


	RGBbackground= RGB(0XFF,0XFF,0XFF) | PAL;  // white background
	Index1Set = FALSE;
	edgeseen      = FALSE;        // edge not seen
	solidpoly     = TRUE;         // polygon interior filled
	hollowpoly    = FALSE;        // ??

	useclip       = TRUE;         // use a clipping rectangle
	clipr         = *rect;
	noElements    = 0;            // # of elements drawn

  lLinePen.lopnStyle   = PS_SOLID;
  lLinePen.lopnWidth.x = 1;
  lLinePen.lopnColor   = RGB(0,0,0) | PAL;

  lMarkerPen = lTextPen = lEdgePen = lLinePen;

  UseLinePen = TRUE;
  lFillBrush.lbStyle = BS_SOLID;
  lFillBrush.lbColor = RGB(255,255,255) | PAL;

  hLinePen   			= CreatePenIndirect((LOGPEN FAR *)&lLinePen);
  hEdgePen   			= CreatePenIndirect((LOGPEN FAR *)&lEdgePen);
  hTextPen   			= CreatePenIndirect((LOGPEN FAR *)&lTextPen);
  hMarkerPen         = CreatePenIndirect((LOGPEN FAR *)&lMarkerPen);
  hHollowPen 			= NULL;
  hFillBrush 			= CreateBrushIndirect((LOGBRUSH FAR *)&lFillBrush);
  hBackgroundBrush 	= NULL;
  LinePenOK 			= TRUE;
  EdgePenOK 			= TRUE;
  TextPenOK 			= TRUE;
  MarkerPenOK        = TRUE;
  FillBrushOK   		= TRUE;

  hPenOrig      = SelectObject(hdc, (HANDLE)hLinePen);
  SelectObject(hdcMeta, (HANDLE)hLinePen);
  hPenUsed  	 = hLinePen;

  hBrushOrig   = SelectObject(hdc, (HANDLE)hFillBrush);
  SelectObject(hdcMeta, (HANDLE)hFillBrush);

  hBrushUsed = hFillBrush;

  SetBkMode(hdc,     TRANSPARENT);
  SetBkMode(hdcMeta, TRANSPARENT);

#ifdef MAKEDEFPALETTE
  LOGPALETTE *pal = pcDisplay::MakeDefaultPalette();
  HPALETTE hPal = CreatePalette((LPLOGPALETTE)pal);
  HPALETTE foo = SelectPalette(hdc,hPal,0);
  HPALETTE moo = SelectPalette(hdcMeta, hPal,0);
  if (cgmWin->hPal)
		{
		hoho = DeleteObject(cgmWin->hPal);
		delete cgmWin->pPalette;
		}
  cgmWin->hPal = hPal;
  cgmWin->pPalette = pal;
  int yoyo = RealizePalette(hdc);
  int zoo = RealizePalette(hdcMeta);
#else
  if (cgmWin->hPal)
		{
		UnrealizeObject(cgmWin->hPal);
		DeleteObject(cgmWin->hPal);
		delete cgmWin->pPalette;
		cgmWin->hPal = NULL;
		cgmWin->pPalette = NULL;
		}

#endif

  }

// *** pcDisplay::MakeDefaultPalette()
LOGPALETTE *pcDisplay::MakeDefaultPalette()
	{
	// Play making initial palette !!!!!
	BYTE red, green, blue;
	int i;
	LOGPALETTE *pal;
	pal = (LOGPALETTE *)(new char[sizeof(LOGPALETTE) +
										  ( sizeof(PALETTEENTRY)* 216) ]);
	pal->palNumEntries = 216;
	pal->palVersion = 0X300;
	red = green = blue = (BYTE)0;
	BYTE mycol[6] = {0,50, 100, 150, 200, 250};
	int j,k,l;
	for (i = 0,j = 0; j < 6; j++)
		{
		red = mycol[j];
		for ( k = 0; k < 6; k++)
			{
			green = mycol[k];
			for ( l = 0; l < 6; l++)
				{
				blue = mycol[l];
				pal->palPalEntry[i].peRed   =  red;
				pal->palPalEntry[i].peGreen =  green;
				pal->palPalEntry[i].peBlue  =  blue;
				pal->palPalEntry[i].peFlags =  (BYTE)0;
				i++;
				}
			}
		}
	return pal;
	}


// *** pcDisplay::~pcDisplay
pcDisplay::~pcDisplay() // destructor
	 {
			// printf("vdc = %f, %f\n", vdcWidth, vdcHeight);

	 delete myPxlExtent;
	 SelectObject(hdc, hPenOrig);
	 SelectObject(hdc, hBrushOrig );
	 DeleteObject(hLinePen);
	 DeleteObject(hEdgePen);
	 DeleteObject(hTextPen);
	 DeleteObject(hMarkerPen);
	 DeleteObject(hFillBrush);
	 DeleteObject(hBackgroundBrush);
	 if (hHollowPen) DeleteObject(hHollowPen);
	 }

// *** pcDisplay::SetLinePen()
void pcDisplay::SetLinePen()
	{
	UseLinePen = TRUE;
	if (LinePenOK)
		{
		if (hPenUsed != hLinePen)
			{
			SelectObject(hdc,     (HANDLE)hLinePen);
			SelectObject(hdcMeta, (HANDLE)hLinePen);
			hPenUsed = hLinePen;
			}
		return;
		}
	else
		{
		LinePenOK = TRUE;
		HPEN  hPen  = CreatePenIndirect((LOGPEN FAR *)&lLinePen);
		SelectObject(hdc,     (HANDLE)hPen);
		SelectObject(hdcMeta, (HANDLE)hPen);
		DeleteObject(hLinePen);
		hLinePen = hPen;
		hPenUsed = hLinePen;
		}
	}

// *** pcDisplay::SetEdgePen()
void pcDisplay::SetEdgePen()
	{
	if (EdgePenOK)
		{
		if (hPenUsed != hEdgePen)
			{
			SelectObject(hdc,     (HANDLE)hEdgePen);
			SelectObject(hdcMeta, (HANDLE)hEdgePen);
			hPenUsed = hEdgePen;
			}
		return;
		}
	else
		{
		EdgePenOK = TRUE;
		HPEN  hPen  = CreatePenIndirect((LOGPEN FAR *)&lEdgePen);
		SelectObject(hdc,     (HANDLE)hPen);
		SelectObject(hdcMeta, (HANDLE)hPen);
		DeleteObject(hEdgePen);
		hEdgePen = hPen;
		hPenUsed = hEdgePen;
		}
	}

// *** pcDisplay::SetTextPen()
void pcDisplay::SetTextPen()
	{
	if (TextPenOK)
		{
		if (hPenUsed != hTextPen)
			{
			SelectObject(hdc,     (HANDLE)hTextPen);
			SelectObject(hdcMeta, (HANDLE)hTextPen);
			hPenUsed = hTextPen;
			}
		return;
		}
	else
		{
		TextPenOK = TRUE;
		HPEN  hPen  = CreatePenIndirect((LOGPEN FAR *)&lTextPen);
		SelectObject(hdc,     (HANDLE)hPen);
		SelectObject(hdcMeta, (HANDLE)hPen);
		DeleteObject(hTextPen);
		hTextPen = hPen;
		hPenUsed = hTextPen;
		}
	}

// *** pcDisplay::SetMarkerPen()
void pcDisplay::SetMarkerPen()
	{
	if (MarkerPenOK)
		{
		if (hPenUsed != hMarkerPen)
			{
			SelectObject(hdc,     (HANDLE)hMarkerPen);
			SelectObject(hdcMeta, (HANDLE)hMarkerPen);
			hPenUsed = hMarkerPen;
			}
		return;
		}
	else
		{
		MarkerPenOK = TRUE;
		HPEN  hPen  = CreatePenIndirect((LOGPEN FAR *)&lMarkerPen);
		SelectObject(hdc,     (HANDLE)hPen);
		SelectObject(hdcMeta, (HANDLE)hPen);
		DeleteObject(hMarkerPen);
		hMarkerPen = hPen;
		hPenUsed = hMarkerPen;
		}
	}

// *** pcDisplay::SetFillBrush()
void pcDisplay::SetFillBrush()
	{
	if (FillBrushOK)
		{
		if (hBrushUsed != hFillBrush)
			{
			SelectObject(hdc,     (HANDLE)hFillBrush);
			SelectObject(hdcMeta, (HANDLE)hFillBrush);
			hBrushUsed = hFillBrush;
			}
		return;
		}
	else
		{
		FillBrushOK = TRUE;
		HBRUSH hBrush  = CreateBrushIndirect((LOGBRUSH FAR *)&lFillBrush);
		SelectObject(hdc,     (HANDLE)hBrush);
		SelectObject(hdcMeta, (HANDLE)hBrush);
		DeleteObject(hFillBrush);
		hFillBrush = hBrush;
		hBrushUsed = hFillBrush;
		}
	}
// *** pcDisplay::SetBackBrush()
 void
 pcDisplay::SetBackBrush(COLORREF RGB)
	{
	LOGBRUSH lBrush;
	lBrush.lbStyle = BS_SOLID;
	lBrush.lbColor = RGB | PAL;
	HBRUSH hBrush  = CreateBrushIndirect((LOGBRUSH FAR *)&lBrush);
	SelectObject(hdc,     (HANDLE)hBrush);
	SelectObject(hdcMeta, (HANDLE)hBrush);
	if (hBackgroundBrush) DeleteObject( hBackgroundBrush);
	hBackgroundBrush = hBrush;
	hBrushUsed = NULL;
	}

// *** pcDisplay::SetHollowPen()
void pcDisplay::SetHollowPen(COLORREF RGB)
	{
	LOGPEN lPen;
	lPen.lopnStyle     = PS_SOLID;
	lPen.lopnWidth.x   = 1;
	lPen.lopnColor     = RGB |= PAL;
	HPEN hPen          = CreatePenIndirect((LOGPEN FAR *)&lPen);
	SelectObject(hdc,     (HANDLE)hPen);
	SelectObject(hdcMeta, (HANDLE)hPen);
	if ( hHollowPen) DeleteObject( hHollowPen);
	hHollowPen = hPen;
	hPenUsed   = NULL;

	}
// *** pcDisplay::backColr
 void
 pcDisplay::backColr(const genColr &inColr)
	{
	set_color2(&RGBbackground, inColr);
	backColr2();
	}

 void
 pcDisplay::backColr2()
	{
	if ( noElements == 0)
		{
		SetBackBrush(RGBbackground);
		SetHollowPen(RGBbackground);

		Rectangle(hdc, itsExtent.left, itsExtent.top,
													  itsExtent.right, itsExtent.bottom);
		Rectangle(hdcMeta, itsExtent.left, itsExtent.top,
													  itsExtent.right, itsExtent.bottom);
		//SetLinePen();
		if (!Index1Set) adjustPens();
		}
	}

 void
 pcDisplay::adjustPens()
	{
	if ( RGBbackground == lLinePen.lopnColor)
		{
		lLinePen.lopnColor = (~lLinePen.lopnColor & (long)0XFFFFFF) | PAL;
		LinePenOK = FALSE;
		}
	if ( RGBbackground == lEdgePen.lopnColor)
		{
		lEdgePen.lopnColor = (~lEdgePen.lopnColor & (long)0XFFFFFF) | PAL;
		EdgePenOK = FALSE;
		}
	if ( RGBbackground == lTextPen.lopnColor)
		{
		lTextPen.lopnColor = (~lTextPen.lopnColor & (long)0XFFFFFF) | PAL;
		TextPenOK = FALSE;
		}
	if ( RGBbackground == lMarkerPen.lopnColor)
		{
		lMarkerPen.lopnColor = (~lMarkerPen.lopnColor & (long)0XFFFFFF) | PAL;
		MarkerPenOK = FALSE;
		}
	if ( RGBbackground == lFillBrush.lbColor)
		{
		lFillBrush.lbColor = (~lFillBrush.lbColor & (long)0XFFFFFF) | PAL;
		FillBrushOK = FALSE;
		}
	}

// *** pcDisplay::edgeColr
 void
 pcDisplay::edgeColr(const genColr &inColr)
	 {
	 COLORREF RGB;

	 myEdgeIndex = set_color2(&RGB, inColr);
	 if ( RGB != lEdgePen.lopnColor)
		{
		lEdgePen.lopnColor = RGB;
		EdgePenOK = FALSE;
		}
	 }


// *** pcDisplay::fillColr
// establish a fill colour
 void
 pcDisplay::fillColr(const genColr &inColr)
	 {
	 COLORREF RGB;

	 myFillIndex = set_color2(&RGB, inColr);
	 if ( RGB != lFillBrush.lbColor)
		{
		lFillBrush.lbColor = RGB;
		FillBrushOK = FALSE;
		}
	 }




// *** pcDisplay::lineColr
 void
 pcDisplay::lineColr(const genColr &inColr  )
	 {
	 COLORREF RGB;

	 myLineIndex = set_color2(&RGB, inColr);
	 if ( RGB != lLinePen.lopnColor)
		{
		lLinePen.lopnColor = RGB;
		LinePenOK = FALSE;
		}
	 }

// *** pcDisplay::textColr
 void
 pcDisplay::textColr(const genColr &inColr  )
	 {
	 COLORREF RGB;

	 myTextIndex = set_color2(&RGB, inColr);
	 if ( RGB != lTextPen.lopnColor)
		{
		lTextPen.lopnColor = RGB;
		TextPenOK = FALSE;
		}
	 }

// *** pcDisplay::markerColr
 void
 pcDisplay::markerColr(const genColr &inColr  )
	 {
	 COLORREF RGB;

	 myMarkerIndex = set_color2(&RGB, inColr);
	 if ( RGB != lMarkerPen.lopnColor)
		{
		lMarkerPen.lopnColor = RGB;
		MarkerPenOK = FALSE;
		}
	 }


// ***  pcDisplay::intStyle
// interior style
////

 void
 pcDisplay::intStyle(int inStyle)
	 {
	 switch (inStyle)
		{
		case 0: // hollow  - don't fill but if not edgeseen, edge in fill color
		hollowpoly = TRUE;
		solidpoly = FALSE;
		break;

		case 1: // solid
		hollowpoly = FALSE;
		solidpoly = TRUE;
		if (  lFillBrush.lbStyle != BS_SOLID)
			{   lFillBrush.lbStyle = BS_SOLID; FillBrushOK = FALSE; }
		break;

		case 2: // pattern
		hollowpoly = FALSE;
		solidpoly = TRUE;
		if (  lFillBrush.lbStyle != BS_HATCHED || lFillBrush.lbHatch != HS_DIAGCROSS)
			{
			lFillBrush.lbStyle = BS_HATCHED;
			lFillBrush.lbHatch = HS_DIAGCROSS;
			FillBrushOK = FALSE;
			}
		break;

		case 3: // hatch
		hollowpoly = FALSE;
		solidpoly = TRUE;
		if (  lFillBrush.lbStyle != BS_HATCHED || lFillBrush.lbHatch != HS_FDIAGONAL  )
			{
			lFillBrush.lbStyle = BS_HATCHED;
			lFillBrush.lbHatch = HS_FDIAGONAL;
			FillBrushOK = FALSE;
			}
		break;

		case 4: // empty - don't fill, do edge if edgeseen
		hollowpoly = FALSE;
		solidpoly  = FALSE;
		break;
		}
	}


// *** pcDisplay::edgeVis
 void
 pcDisplay::edgeVis(int inVis)
	 {

	 if ( inVis) edgeseen = TRUE;
	 else        edgeseen  = FALSE;
	 }


// *** pcDisplay::lineType
 void
 pcDisplay::lineType(int inType)
	{
	switch (inType )
		{
		case 1:
		if (lLinePen.lopnStyle != PS_SOLID)
			{ lLinePen.lopnStyle = PS_SOLID; LinePenOK = FALSE; }
		break;

		case 2:
		if (lLinePen.lopnStyle != PS_DASH)
			{ lLinePen.lopnStyle = PS_DASH; LinePenOK = FALSE; }
		break;

		case 3:
		if (lLinePen.lopnStyle != PS_DOT)
			{ lLinePen.lopnStyle = PS_DOT; LinePenOK = FALSE; }
		break;

		case 4:
		if (lLinePen.lopnStyle != PS_DASHDOT)
			{ lLinePen.lopnStyle = PS_DASHDOT; LinePenOK = FALSE; }
		break;

		case 5:
		if (lLinePen.lopnStyle != PS_DASHDOTDOT)
			{ lLinePen.lopnStyle = PS_DASHDOTDOT; LinePenOK = FALSE; }
		break;

		}
	baseDisplay::lineType(inType);
	}

// *** pcDisplay::edgeType
 void
 pcDisplay::edgeType(int inType)
	{
	switch (inType )
		{
		case 1:
		if (lEdgePen.lopnStyle != PS_SOLID)
			{ lEdgePen.lopnStyle = PS_SOLID; EdgePenOK = FALSE; }
		break;

		case 2:
		if (lEdgePen.lopnStyle != PS_DASH)
			{ lEdgePen.lopnStyle = PS_DASH; EdgePenOK = FALSE; }
		break;

		case 3:
		if (lEdgePen.lopnStyle != PS_DOT)
			{ lEdgePen.lopnStyle = PS_DOT; EdgePenOK = FALSE; }
		break;

		case 4:
		if (lEdgePen.lopnStyle != PS_DASHDOT)
			{ lEdgePen.lopnStyle = PS_DASHDOT; EdgePenOK = FALSE; }
		break;

		case 5:
		if (lEdgePen.lopnStyle != PS_DASHDOTDOT)
			{ lEdgePen.lopnStyle = PS_DASHDOTDOT; EdgePenOK = FALSE; }
		break;

		}
	baseDisplay::edgeType(inType);
	}


// ***  pcDisplay::lineWidth

 void
 pcDisplay::lineWidth(const vdcR *inWidth)
	{
	baseDisplay::lineWidth(inWidth);
	int lWidth; // line width we shall use
	if (myLineWidth->type()) { // relative size
		lWidth = (int) (  myLineWidth->f()*pcScale); // use 1 as default
		}
	else { // got a vdc
		lWidth = getSize(myLineWidth->v());
		}
	if (lWidth < 1) lWidth = 1;
	lLinePen.lopnWidth.x =  lWidth;
	LinePenOK = FALSE;

	}


// *** pcDisplay::edgeWidth
 void
 pcDisplay::edgeWidth(const vdcR *inWidth)
	 {
	 baseDisplay::edgeWidth(inWidth);
	 int lWidth; // line width we shall use
	 if (myEdgeWidth->type()) { // relative size
		 lWidth = (int) ( myEdgeWidth->f()*pcScale); // use 1 as default
		 }
	else { // got a vdc
		 lWidth = getSize(myEdgeWidth->v());
		 }
	 if (lWidth < 1) lWidth = 1;
	 lEdgePen.lopnWidth.x = lWidth;
	 EdgePenOK = FALSE;
	}



// **************************** pcDisplay::polyline *******************************
 int
 pcDisplay::polyline(const vdcPts *inPts) // display a polyline
	 {
	 int *scaledPtr;

	 getPts(inPts, scaledPtr); // get the scaled version
	 if (!scaledPtr) {
		 myError("couldn't get scaled points");
		 return 0;
		 }
	 if (UseLinePen) SetLinePen();
	 Polyline(hdc, (LPPOINT)scaledPtr, inPts->no());
	 Polyline(hdcMeta, (LPPOINT)scaledPtr, inPts->no());
	 delete scaledPtr;

	 noElements++;
	 return 1;
	 }

// ***  pcDisplay::polygon
 int
 pcDisplay::polygon(const vdcPts *inPts) // display a polyline
	 {
	 int *scaledPtr;

	 //  if (inPts->myType)     float *floatPtr = (float *) inPts->myPtr;
	 //  else                   int *intPtr = (int *) inPts->myPtr;
	 getPts(inPts, scaledPtr,1); // get the scaled version with extra point to close
	 if (!scaledPtr) {
		 myError("couldn't get scaled points");
		 return 0;
		 }
	 if (solidpoly)
		{
		SetFillBrush();
		SetHollowPen(lFillBrush.lbColor);
		Polygon(hdc, (LPPOINT)scaledPtr, inPts->no());
		Polygon(hdcMeta, (LPPOINT)scaledPtr, inPts->no());
		}
	 if (edgeseen )
		{
		SetEdgePen();
		UseLinePen = FALSE;
		Polyline(hdc, (LPPOINT)scaledPtr, inPts->no()+1);
		Polyline(hdcMeta, (LPPOINT)scaledPtr, inPts->no()+1);
		UseLinePen = TRUE;
		}
	 else if (hollowpoly )
		{

		SetHollowPen(lFillBrush.lbColor);
		UseLinePen = FALSE;
		Polyline(hdc, (LPPOINT)scaledPtr, inPts->no());
		Polyline(hdcMeta, (LPPOINT)scaledPtr, inPts->no());
		UseLinePen = TRUE;
		}

	 delete scaledPtr;
	 noElements++;
	 return 1;
	 }

// *** pcDisplay::text
 int
 pcDisplay::text(const genText *gen)
	 {
	 SetTextPen();
	 UseLinePen = FALSE;
	 int ret =  baseDisplay::text(gen);
	 UseLinePen = TRUE;
	 return ret;
	 }
  // *** pcDisplay::polymarker
 int
 pcDisplay::polymarker(const vdcPts *vdc)
	 {
	 SetMarkerPen();
	 UseLinePen = FALSE;
	 int ret =  baseDisplay::polymarker(vdc);
	 UseLinePen = TRUE;
	 return ret;
	 }


// ***  pcDisplay::clipRect
 void
 pcDisplay::clipRect(const vdcPts *inPts)
	 {
	 if (inPts->no() < 2) {
		 myError("not enough points for clipping rectangle");
		 return;
		 }
	 short *scaledPtr;

	 getPts(inPts, scaledPtr); // get the scaled version
	 if (!scaledPtr) {
		 myError("couldn't get scaled points");
		 return;
		 }
	 if (scaledPtr[0] < scaledPtr[2])
		 {
		clipr.left  = scaledPtr[0] -1;
		clipr.right = scaledPtr[2]+1;
		}
	 else
		 {
		 clipr.left  = scaledPtr[2] -1;
		 clipr.right = scaledPtr[0] +1;
		 }
	 if (scaledPtr[1] < scaledPtr[3])
		 {
		 clipr.top    = scaledPtr[1] -1;
		 clipr.bottom = scaledPtr[3] +1;
		 }
	 else
		 {
		 clipr.top    = scaledPtr[3] -1;
		 clipr.bottom = scaledPtr[1] +1;
		 }
	 if (this->useclip)
		{
		HRGN clip = CreateRectRgnIndirect(&clipr);
		SelectObject(hdc, clip);
		SelectObject(hdcMeta, clip);
		DeleteObject(clip);
		}
	 delete scaledPtr;
	}



// ***  pcDisplay::clip
// turn clipping on or off
////
 void
 pcDisplay::clip(int inClip)
	 {
	 HRGN clip;
	 if (inClip)
		 {
		this->useclip = TRUE;   // and if a clip rectangle, establish it
		clip = CreateRectRgnIndirect(&clipr);
		SelectObject(hdc, clip);
		SelectObject(hdcMeta, clip);
		DeleteObject(clip);
		}
	 else
		{
		this->useclip = FALSE;  // establish default clip rectangle
		clip = CreateRectRgnIndirect(&itsExtent);
		SelectObject(hdc, clip);
		SelectObject(hdcMeta, clip);
		DeleteObject(clip);
		}

	 }


// *** pcDisplay::colrs
 void
 pcDisplay::colrs(const colrTable *inTable)
	 {
	 BOOL hoho;
	 int i;
	 LOGPALETTE *pal, *oldPal;
	 int oldSize = 0;
	 if (cgmWin->pPalette)
		{
		oldPal  = cgmWin->pPalette;
		oldSize = oldPal->palNumEntries;
		}
	 int start = inTable->start();
	 int no    = inTable->no();
	 int newSize = start + no;
	 if (newSize < oldSize) newSize = oldSize;
	 pal = (LOGPALETTE *)(new char[sizeof(LOGPALETTE) +
										  ( sizeof(PALETTEENTRY)*newSize) ]);
	 pal->palNumEntries = newSize;
	 pal->palVersion = 0X300;
	 if (oldSize)
		for (i = 0; i < oldSize; i++)
			pal->palPalEntry[i] = oldPal->palPalEntry[i];

	 for (i= start; i< (start + no) ; ++i)
		{
		pal->palPalEntry[i].peRed   =  inTable->r(i)[0]  * 0XFF;
		pal->palPalEntry[i].peGreen =  inTable->r(i)[1]  * 0XFF;
		pal->palPalEntry[i].peBlue  =  inTable->r(i)[2]  * 0XFF;
		pal->palPalEntry[i].peFlags =  NULL;
		if (myEdgeIndex == i)  edgeColr(genColr(i, inTable->extent(), inTable));
		if (myLineIndex == i)  lineColr(genColr(i, inTable->extent(), inTable));
		if (myTextIndex == i)  textColr(genColr(i, inTable->extent(), inTable));
		if (myFillIndex == i)  fillColr(genColr(i, inTable->extent(), inTable));
		if (myMarkerIndex == i)  markerColr(genColr(i, inTable->extent(), inTable));
		}
	HPALETTE hPal = CreatePalette((LPLOGPALETTE)pal);
	HPALETTE foo = SelectPalette(hdc,hPal,0);
	HPALETTE moo = SelectPalette(hdcMeta, hPal,0);
	if (cgmWin->hPal)
		{
		hoho = DeleteObject(cgmWin->hPal);
		delete cgmWin->pPalette;
		}
	cgmWin->hPal = hPal;
	cgmWin->pPalette = pal;
	int yoyo = RealizePalette(hdc);
	int zoo = RealizePalette(hdcMeta);
	if (1 >=start && 1 <= (start+no)) Index1Set = TRUE;
	if (start == 0) backColr(genColr(0, inTable->extent(), inTable));
	}





// ***  set_color2()
 const
  int set_color2( COLORREF *RGBOut, const genColr &genIn)
	 {
	BYTE red, green, blue;
	red    =  (BYTE)(genIn.r(0) * 0XFF);
	blue   =  (BYTE)(genIn.r(1) * 0XFF);
	green  =  (BYTE)(genIn.r(2) * 0XFF);

	*RGBOut   = RGB(red, blue, green) | PAL ;
	if (!genIn.type()) return genIn.i();
	else return DEFAULT_INDEX;
	}

 void
 pcDisplay::ExtentRect()
	{
	RECT rect;
	getExtent( &rect);
	lLinePen.lopnStyle = PS_SOLID;
	lLinePen.lopnWidth.x = 5;
	lLinePen.lopnColor = RGB(0xFF,0,0);
	lLinePen.lopnColor  |= PAL;
	LinePenOK = FALSE;
	SetLinePen();
	POINT *points = new POINT[5];
	points[0].x = rect.left;
	points[0].y = rect.top;
	points[1].x = rect.right;
	points[1].y = rect.top;
	points[2].x = rect.right;
	points[2].y = rect.bottom;
	points[3].x = rect.left;
	points[3].y = rect.bottom;
	points[4] = points[0];
	Polyline(hdc, points, 5 );
	Polyline(hdcMeta, points, 5);
	delete points;
	}

