/*--------------------------------------------------------------*/
/*  IBM OS/2 Presentation Manager Driver 1.0  EMX/gcc           */
/*--------------------------------------------------------------*/
/*              Axel Rohde, June, July 1994                     */
/*--------------------------------------------------------------*/

#include "all.h"
#include <math.h>
#include "core.h"
#include "mygraph.h"
#include "mydev.h"

#define ERRFILE "GLEOS2.ERR"


#define INCL_WINWINDOWMGR
#define INCL_WINFRAMEMGR /**/
#define INCL_WINPOINTERS /**/
#define INCL_WINSYS
#define INCL_GPIPRIMITIVES
#include <os2emx.h>

#include <dos.h>


/* global PM Vars        */
HAB     hab;
HPS     hpsScreen, hpsMem, hpsDraw;
HDC     hdcScreen, hdcMem;
HMQ     hmq;
HWND    hwndFrame, hwndClient;
QMSG    qmsg;
RECTL   rctl, clientRctl;
HBITMAP hbm;
BITMAPINFOHEADER2 bmp;
#define MAXPOLY 2000
POINTL  polyPoint[MAXPOLY];
LONG    polyNum;

#ifdef FILLPATH
POINTL  polyPPoint[MAXPOLY];
LONG    polyPNum;
LONG    fillrule = FPATH_WINDING;
#endif

#define NOPATH 0
#define PATH   1


CHAR szClientClass[]="GLE_PM";
static ULONG flFrameFlags = FCF_TITLEBAR      | FCF_SYSMENU  |
                            FCF_BORDER        | FCF_MINBUTTON|
                            FCF_SHELLPOSITION | FCF_TASKLIST |
                            FCF_NOBYTEALIGN;

int CreatedAndSized;
int errFlag = 0;
int drawing;
int winOriginX, winOriginY;
int winSizeX, winSizeY;

#ifdef FILLPATH
void path_close(void);
void path_fill(void);
void path_newpath(void);
void path_stroke(void);
#endif

extern struct   gmodel g;
extern int      gunit;
int             in_font  = 0;
int             fontfill = 0;

/*-------------------------- BGI Emulation ;-> ------------------------------*/
#if (defined M_PI && !defined PI)
#define PI M_PI
#define pi M_PI
#elif defined PI
#define pi PI
#else
#define PI 3.141592653
#define pi 3.141592653
#endif

#define false 0
#define true (!false)
#define BLACKANDWHITE 1


int maxx, maxy;
int window1W, window1H;
int d_linecolor, d_fillcolor;
LONG d_lwidth, d_lstyle;


int getmaxx(void)
{
        return maxx;
}

int getmaxy(void)
{
        return maxy;
}

void flushPoly(int path)
{
#ifdef FILLPATH
  if (path)
        {       /* GpiMove() not cached, GpiLine() cached  */ 
                if (polyPNum == 0) return; 
                GpiPolyLine(hpsDraw, polyPNum, polyPPoint);
                polyPPoint[0].x = polyPPoint[polyPNum].x;
                polyPPoint[0].y = polyPPoint[polyPNum].y;
                polyPNum = 0;
        }
  else
#endif
        {       /* GpiMove() & GpiLine() cached */
                if (polyNum == 0) return; 
                GpiPolyLineDisjoint(hpsDraw, polyNum, polyPoint);
                polyPoint[0].x = polyPoint[polyNum].x;
                polyPoint[0].y = polyPoint[polyNum].y;
                polyNum = 0;
        }
}

void lineto(int x, int y)
{
#ifdef FILLPATH
        if (g.inpath==true && in_font==false)
                { /* GpiMove() not cached, GpiLine() cached */ 
                  polyPPoint[polyPNum].x = x;
                  polyPPoint[polyPNum].y = window1H - y;
                  polyPNum +=1;
                  if (polyPNum >= MAXPOLY) flushPoly(PATH);
                }
        else     
#endif
                { /* GpiMove() & GpiLine() cached */ 
                  /* at start point*/
                  polyPoint[polyNum+1].x = polyPoint[polyNum+2].x =  x; /* end */
                  polyPoint[polyNum+1].y = polyPoint[polyNum+2].y = window1H - y; /* next start */
                  polyNum +=2;
                  if (polyNum >= MAXPOLY) flushPoly(NOPATH);
                }
}

void slineto(int x, int y)
{
        POINTL xy;

        xy.x = x;
        xy.y = window1H - y;
        GpiLine(hpsDraw, &xy);
}


void moveto(int x, int y)
{
    POINTL xy;
#ifdef FILLPATH
    if (g.inpath==true && in_font==false)
      { /* GpiLine() cached, GpiMove() not cached */ 
        flushPoly(PATH);
        xy.x = x;
        xy.y = window1H - y; 
        GpiMove(hpsDraw, &xy); 
      }
    else
#endif
      { /* GpiMove() & GpiLine() cached */ 
        polyPoint[polyNum].x = x;
        polyPoint[polyNum].y = window1H - y;
      }
}

void smoveto(int x, int y)
{
        POINTL xy;
/* really neccesary ?
        if (g.inpath==true && in_font==false) 
                flushPoly(PATH);
        else
                flushPoly(NOPATH);
*/
        xy.x = x;
        xy.y = window1H - y; 
        GpiMove(hpsDraw, &xy);
}

/* absolutely ugly code to draw arcs follows */
/* should look like Postscript output, if not, tell me */

void ellipse(   int center_x,    int center_y,
                int start_angle, int end_angle,
                int radius_x,    int radius_y   )
{
        ARCPARAMS       arcp;
        POINTL          xy;
        int st_angle;                   /* angles must be >= 0 */
        int e_angle;
        int sw_angle;
        int n, sign;

        arcp.lP = radius_x;
        arcp.lQ = radius_y;
        arcp.lR = arcp.lS = 0;
        GpiSetArcParams(hpsDraw, &arcp);
        xy.x = center_x;
        xy.y = window1H - center_y;
        smoveto(center_x + radius_x * cos(start_angle * PI/180),
               center_y - radius_y * sin(start_angle * PI/180));

        n = abs(start_angle/360);
        if (start_angle < 0)
            {
                sign = 1;
                n += 1;
            }
        else
                sign = -1;
        st_angle = start_angle + sign * n * 360;

        n = abs(end_angle/360);
        if (end_angle < 0)
            {
                sign = 1;
                n += 1;
            }
        else
                sign = -1;
        e_angle = end_angle + sign * n * 360;

        if (end_angle >= start_angle)
                GpiPartialArc(  hpsDraw, &xy, MAKEFIXED(1,0),
                                MAKEFIXED(st_angle,0),
                                MAKEFIXED(end_angle - start_angle, 0)
                             );
        else
            { 
                if (start_angle >= 0 && end_angle >= 0)
                    {
                        sw_angle = abs(end_angle - start_angle);
                        if (sw_angle > 360)
                                sw_angle = sw_angle % 360;
                        sw_angle = 360 - sw_angle;
                        GpiPartialArc(  hpsDraw, &xy, MAKEFIXED(1,0),
                                        MAKEFIXED(st_angle,0),
                                        MAKEFIXED(sw_angle, 0)
                                     );
                    }
                else if (end_angle < 0 && start_angle >= 0)
                        GpiPartialArc(  hpsDraw, &xy, MAKEFIXED(1,0),
                                        MAKEFIXED(st_angle ,0),
                                        MAKEFIXED(e_angle - st_angle, 0)
                                     );
                else 
                        GpiPartialArc(  hpsDraw, &xy, MAKEFIXED(1,0),
                                        MAKEFIXED(0  ,0),
                                        MAKEFIXED(e_angle, 0)
                                     );
            }
}

void nellipse(   int center_x,    int center_y,
                int start_angle, int end_angle,
                int radius_x,    int radius_y   )
{
        ARCPARAMS       arcp;
        POINTL          xy;
        int st_angle;                   /* angles must be >= 0 */
        int e_angle;
        int sw_angle;
        int n, sign;

        arcp.lP = radius_x;
        arcp.lQ = radius_y;
        arcp.lR = arcp.lS = 0;
        GpiSetArcParams(hpsDraw, &arcp);
        xy.x = center_x;
        xy.y = window1H - center_y;
        smoveto(center_x + radius_x * cos(start_angle * PI/180),
               center_y - radius_y * sin(start_angle * PI/180));

        n = abs(start_angle/360);
        if (start_angle < 0)
            {
                sign = 1;
                n += 1;
            }
        else
                sign = -1;
        st_angle = start_angle + sign * n * 360;

        n = abs(end_angle/360);
        if (end_angle < 0)
            {
                sign = 1;
                n += 1;
            }
        else
                sign = -1;
        e_angle = end_angle + sign * n * 360;

        if (end_angle >= start_angle)
                GpiPartialArc(  hpsDraw, &xy, MAKEFIXED(1,0),
                                MAKEFIXED(st_angle,0),
                                MAKEFIXED(end_angle - start_angle, 0)
                             );
        else
            { 
                if (start_angle >= 0 && end_angle >= 0)
                    {
                        GpiPartialArc(  hpsDraw, &xy, MAKEFIXED(1,0),
                                        MAKEFIXED(st_angle,0),
                                        MAKEFIXED(360-st_angle, 0)
                                     );
                        GpiPartialArc(  hpsDraw, &xy, MAKEFIXED(1,0),
                                        MAKEFIXED(0,0),
                                        MAKEFIXED(e_angle, 0)
                                     );
                    }
                else if (start_angle < 0 && end_angle < 0)
                        GpiPartialArc(  hpsDraw, &xy, MAKEFIXED(1,0),
                                        MAKEFIXED(st_angle,0),
                                        MAKEFIXED(360 + (end_angle - start_angle) % 360, 0)
                                     );
                else
                        GpiPartialArc(  hpsDraw, &xy, MAKEFIXED(1,0),
                                        MAKEFIXED(st_angle,0),
                                        MAKEFIXED(e_angle-st_angle, 0)
                                     );
            }
}

void fillellipse(   int center_x,    int center_y,
                    int radius_x,    int radius_y   )
{
        ARCPARAMS      arcp;
        POINTL          xy;

        arcp.lP = radius_x;
        arcp.lQ = radius_y;
        arcp.lR = 0;    arcp.lS = 0;
        GpiSetArcParams(hpsDraw, &arcp);
        smoveto(center_x, center_y);
        /* fill */
        GpiSetColor(hpsDraw, d_fillcolor);
        GpiFullArc( hpsDraw, DRO_OUTLINEFILL, MAKEFIXED(1,0) );
        /* outline */
        GpiSetColor(hpsDraw, d_linecolor);
        ellipse(center_x, center_y, 0, 360, radius_x, radius_y);
}

void fillpoly(int numpoints, int polypoints[])
{
        POINTL xy;
        int i;

        /* filling polygon */        
        GpiSetColor(hpsDraw, d_fillcolor);
        GpiBeginArea(hpsDraw, BA_BOUNDARY | BA_WINDING);
        smoveto(polypoints[0], polypoints[1]);
        for (i = 2; i < 2 * numpoints; i+=2)
                {
                 xy.x = polypoints[i];
                 xy.y = window1H - polypoints[i+1];
                 GpiLine(hpsDraw, &xy);
                }
        GpiEndArea(hpsDraw);
        /* drawing outline */
        GpiSetColor(hpsDraw, d_linecolor);
        smoveto(polypoints[0], polypoints[1]);
        for (i = 2; i < 2 * numpoints; i+=2)
                {
                  xy.x = polypoints[i];
                  xy.y = window1H - polypoints[i+1];
                  GpiLine(hpsDraw, &xy);
                }
}

/*---------------------------------------------------------------------------*/

getMemHps(int width, int height)
{
   SIZEL szlHps;
   long bitmapfmts[2];

   hdcMem=DevOpenDC(hab,OD_MEMORY,"*",0,NULL,NULLHANDLE);

   szlHps.cx=0;
   szlHps.cy=0;

   hpsMem=GpiCreatePS(hab,
                      hdcMem,
                      &szlHps,
                      PU_PELS|GPIT_MICRO|GPIA_ASSOC);

   GpiSetPageViewport(hpsMem, &rctl);
   GpiQueryDeviceBitmapFormats(hpsScreen, 2L, bitmapfmts);
   
   bmp.cbFix = sizeof(bmp);
   bmp.cx = width;
   bmp.cy = height;
   bmp.cPlanes = (short) bitmapfmts[0];
   bmp.cBitCount = (short) bitmapfmts[1];
   
   hbm = GpiCreateBitmap(hpsMem, &bmp, 0L, NULL, NULL);
   GpiSetBitmap(hpsMem, hbm);
   GpiErase(hpsMem);
}


bitBlit(HPS target, HPS source)
{
    POINTL aptl[3];

    aptl[0].x = 0;
    aptl[0].y = 0;
    aptl[1].x = window1W;
    aptl[1].y = window1H;
    aptl[2].x = 0;
    aptl[2].y = 0;

    GpiBitBlt(target, source, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE);
}

/*---------------------------------------------------------------------------*/

int text_saveOS2err(void)
{
        FILE *fptr;
        int i;
        extern char *(*etxt)[];
        extern int netxt;

        unlink(ERRFILE);
        fptr = fopen(ERRFILE,"w");
        if (fptr==NULL) perror("Unable to open output file GLEOS2.ERR");
        for (i=1;i<=netxt;i++) {
                fputs((*etxt)[i],fptr);
                fputs("\n",fptr);
        }
        if (fclose(fptr)!=0) perror("Unable to close output file GLEOS2.ERR");
}

int text_saveOS2noerr(void)
{
        FILE *fptr;
        int i;
        extern char *(*etxt)[];
        extern int netxt;

        unlink(ERRFILE);
        fptr = fopen(ERRFILE,"w");
        if (fptr==NULL){
                 perror("Unable to open output file GLEOS2.ERR");
                 return ;
                 }
        fputs("There were no errors.\nPress RETURN to continue.\n",fptr);
        if (fclose(fptr)!=0)
                perror("Unable to close output file GLEOS2.ERR");
}

/*---------------------------------------------------------------------------*/


int ingraphmode;
/*---------------------------------------------------------------------------*/

/*
#define dbg if ((gle_debug & 64)>0)
#define stop if ((gle_debug & 128)>0) return
*/
#define dbg
#define stop
extern int gle_debug;

int incap=true;


/*---------------------------------------------------------------------------*/
/*              The global variables for the PC screen driver                */
/*---------------------------------------------------------------------------*/

int i,l,j,ix,iy;
double f;

/*
#define gerr() i = graphresult(); if (i!=0) printf("Graph error: %s \n",grapherrormsg(i));
*/
#define gerr


#define xsizecm 64  /* matches standard PC-screen aspect ratio */
#define ysizecm 48

#define sx(v) ( (int) ((v) * d_xscale)+1)
#define sy(v) ( d_maxy - ((int) ((v) * d_yscale)))
#define rx(v) ( (int) ((v) * d_xscale)+1)
#define ry(v) ( d_maxy - ((int) ((v) * d_yscale)))

/*
#define textmode() {getch(); restorecrtmode();}
#define graphmode() {getch(); setgraphmode(d_graphmode);}

#define gon  if ((gle_debug & 256) > 0) graphmode()
#define goff if ((gle_debug & 256) > 0) textmode()
*/
#define gon
#define goff

double d_scale, d_xscale, d_yscale;
int d_graphmode;
int d_fillstyle=0;
int d_pat;
int d_maxy;

int d_zzline(double cx,double cy,double zx,double zy);
int addline(char *s);

int getwhite(void);
int getwhite()
{
        return CLR_WHITE;
}
d_devcmd(char *s)
{}


d_message(char *s)
{}

int undxy(int dx, int dy, double *x, double *y);
undxy(int dx, int dy, double *x, double *y)
{
        double ddx,ddy;
        char buff[80];
        ddx = (dx)/d_xscale;
        ddy = (dy - d_maxy) / -d_yscale;
        g_undev(ddx,ddy,x,y);
}
dxy(double x, double y, int *dx, int *dy)
{
        static double fx,fy;
        g_dev(x,y,&fx,&fy);
        *dx = sx(fx);
        *dy = sy(fy);
}
rxy(double x, double y, int *dx, int *dy)
{
        static double fx,fy,zx,zy;
        g_dev(x,y,&fx,&fy);
        g_dev(0.0,0.0,&zx,&zy);
        *dx = (int) ( (fx-zx) * d_xscale +1);
        *dy = (int) ( (fy-zy) * d_yscale);
}
/*---------------------------------------------------------------------------*/
d_dfont(char *c)
{
        /* only used for the DFONT driver which builds fonts */
}
/*---------------------------------------------------------------------------*/
d_source(char *s)
{
        s=s;
}
/*---------------------------------------------------------------------------*/
d_get_type(char *t)
{
        strcpy(t, "INTERACTIVE, OS2PM");
}
/*---------------------------------------------------------------------------*/
d_set_path(int onoff)
{
        /* no action ? */
}
/*---------------------------------------------------------------------------*/
d_newpath()
{
#ifdef FILLPATH
        path_newpath();
#endif
}

/*--------------------- PM Message Queue ------------------------------------*/

MRESULT EXPENTRY ClientWndProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
{
        SIZEL   sizel;
        SWP     swp;

  switch(msg){

    case WM_ADJUSTWINDOWPOS:            /* must be here */

    /*    Hey, PM why do you not recognize MOVING windows???????? */
    /*
    case WM_MOVE:
        WinSetWindowText(hwndFrame, "WM_MOVE");
    case WM_WINDOWPOSCHANGED:
        WinSetWindowText(hwndFrame, "WM_WINDOWPOSCHANGED");
    */

    case WM_FOCUSCHANGE:
        if ( CreatedAndSized >= 2 && drawing && hpsDraw == hpsScreen)
                {
                WinSetWindowText(hwndFrame, "GLE: window hidden, drawing into a bitmap...");
                WinEndPaint(hpsScreen);
                if (hpsMem == NULLHANDLE)
                        getMemHps(window1W, window1H);
                WinBeginPaint(hwndClient, hpsMem, NULL);
                bitBlit(hpsMem, hpsScreen);
                hpsDraw = hpsMem;
                return 0;
                }
        break;                
             
    case WM_CREATE:
        if ( CreatedAndSized >= 2)
                break;
        hdcScreen = WinOpenWindowDC(hwnd);
        sizel.cx = 0;
        sizel.cy = 0;
        hpsScreen = GpiCreatePS( hab, hdcScreen, &sizel, PU_PELS | GPIF_DEFAULT |
                                                      GPIT_MICRO | GPIA_ASSOC);

        hpsDraw = hpsScreen;        
        ++CreatedAndSized;
        return 0;
        
        
    case WM_SIZE:
        if ( CreatedAndSized >= 2)
                break;

        /************************************************************/
        /* drawing stuff follows                                    */  
        /************************************************************/
        
        ++CreatedAndSized;
        return 0;

    case WM_PAINT:
        if (drawing && hpsDraw != hpsMem) break;
        if ( CreatedAndSized < 2 )
                {
                ++CreatedAndSized;
                break;
                }

        /* works, but not really stable....
        WinQueryWindowPos(hwndFrame, (PSWP)&swp);
        if ( CreatedAndSized >= 2 && drawing && hpsDraw == hpsMem &&
             winOriginX == swp.x && winOriginY == swp.y )
                {
                WinSetWindowText(hwndFrame, "GLE: window visible, drawing into it...");
                WinEndPaint(hpsMem);
                WinCalcFrameRect(hwndFrame, (PRECTL)&hwndClient, FALSE);
                WinBeginPaint(hwndClient, hpsScreen, NULL);
                bitBlit( hpsScreen, hpsMem);
                hpsDraw = hpsScreen;
                return 0;
                }
        */

        WinBeginPaint(hwndClient, hpsScreen, NULL);
        bitBlit(hpsScreen, hpsMem);
        WinEndPaint(hpsScreen);
        return 0;

    case WM_DESTROY:
        GpiAssociate(hpsScreen, 0);
        GpiDestroyPS(hpsScreen);
        GpiAssociate(hpsMem, 0);
        GpiDestroyPS(hpsMem);
        return 0;

    case WM_CLOSE:
    case WM_QUIT:
        GpiAssociate(hpsScreen, 0);
        GpiDestroyPS(hpsScreen);
        GpiAssociate(hpsMem, 0);
        GpiDestroyPS(hpsMem);
        exit(0);
  }
  return WinDefWindowProc(hwnd, msg, mp1, mp2);
}

/*----------------------------------------------------------------------------*/

d_open(double width, double height)
{
    int  cx_frame, cy_frame;
    static int scr_width, scr_height;
    double f;
    static int doneopen;

#ifdef FILLPATH
    if (getenv("GLEPMFONTFILL") != NULL)
        fontfill = true;
#endif

    if (!doneopen)
        doneopen = true;

    ingraphmode = true;


    /* PM init */
    CreatedAndSized = 0;
    hab = WinInitialize(0);
    hmq = WinCreateMsgQueue(hab, 0);

    WinRegisterClass( hab, 
                      szClientClass,
                      (PFNWP) ClientWndProc,
                      /*CS_SIZEREDRAW*/0,
                      0);

    hwndFrame = WinCreateStdWindow(HWND_DESKTOP,
                                   WS_VISIBLE | WS_MAXIMIZED,
                                  &flFrameFlags,
                                   szClientClass, "GLE PM", 0L,
                                   (HMODULE) NULL, 0, &hwndClient);

    scr_height      =  WinQuerySysValue (HWND_DESKTOP, SV_CYSCREEN);
    scr_width       =  WinQuerySysValue (HWND_DESKTOP, SV_CXSCREEN);

    cx_frame        =   WinQuerySysValue (HWND_DESKTOP, SV_CXBORDER)  << 1;
    cy_frame        = ( WinQuerySysValue (HWND_DESKTOP, SV_CYBORDER)  << 1 ) +
                        WinQuerySysValue (HWND_DESKTOP, SV_CYTITLEBAR);

    maxx = scr_width  - cx_frame;
    maxy = scr_height - cy_frame;
    

    /* Get largest rectangle we can fit on the screen */
    d_scale = xsizecm / width;
    f = ysizecm / height;
    if (f<d_scale) d_scale = f;
    /* Device Scale X, Device Scale y */ 
    d_xscale = d_scale * (getmaxx()) / xsizecm;
    d_yscale = d_scale * (getmaxy()) / ysizecm;
    window1W = width * d_xscale+3;
    window1H = height * d_yscale+1;
    d_maxy = window1H;
    g.userwidth = width;
    g.userheight = height;
                
    winOriginX =  scr_width - window1W - WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER);
    winOriginY = scr_height - cy_frame - window1H;
    winSizeX   = window1W + cx_frame;
    winSizeY   = window1H + cy_frame;

    WinSetWindowPos(    hwndFrame,      HWND_TOP, 
                        winOriginX,     winOriginY,
                        winSizeX,       winSizeY,
                        SWP_MOVE | SWP_SIZE | SWP_ACTIVATE | SWP_SHOW);


    /* change icon (preliminary, to decrease link time) */
    WinSendMsg( hwndFrame, WM_SETICON,
                (MPARAM) WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE),
                NULL);


    /* first event loop - left after window is created, sized and painted ;-) */
    while( WinGetMsg(hab, &qmsg, 0, 0, 0) && CreatedAndSized < 2 )
            WinDispatchMsg(hab, &qmsg);


    /* draw until WinEndPaint() in d_close */
    WinBeginPaint(hwndClient, hpsScreen, NULL);
    WinSetWindowText(hwndFrame, "GLE: Drawing...");
    drawing = 1;
}

/*---------------------------------------------------------------------------*/
d_tidyup()
{
/*
        if (ingraphmode) {
                gprint("AARRRrrrrgg,  Watch out I'm dying!!!\n");
                d_close();
        }
*/
}


d_close()
{
        extern int netxt;
#ifdef FILLPATH
        flushPoly(PATH);
#endif
        flushPoly(NOPATH);

        stop;gon;
        drawing = 0;
        if (hpsDraw == hpsScreen)
               {
                WinEndPaint(hpsScreen);

                getMemHps(window1W, window1H);
                bitBlit(hpsMem, hpsScreen);
               }
        else
               {
                WinEndPaint(hpsMem);
                bitBlit(hpsScreen, hpsMem);
               }
                
        WinSetWindowText(hwndFrame, "GLE: compilation completed!");
        if (netxt > 0)
               {
                text_saveOS2err();
                WinSetWindowText(hwndFrame, "GLE: there are warnings/errors - press F5 in editor!");
               }
        else
              /*  text_saveOS2noerr(); */
                unlink(ERRFILE);
                

        while(WinGetMsg(hab, &qmsg, 0, 0, 0))
                WinDispatchMsg(hab, &qmsg);


        if (ingraphmode == false) return;
        g_flush();
        ingraphmode = false;

        WinDestroyWindow(hwndFrame);
        WinDestroyMsgQueue(hmq);
        WinTerminate(hab);
}
/*---------------------------------------------------------------------------*/
d_set_line_cap(int i)
{
        i++;
}
/*---------------------------------------------------------------------------*/
d_set_line_join(int i)
{
        /* not really useful without different linewidths */
/*
        switch (i){
        case 0:
                 i = LINEJOIN_MITRE;
        case 1:
                 i = LINEJOIN_ROUND;
        case 2:
                 i = LINEJOIN_BEVEL;
        }
        GpiSetLineJoin(hpsDraw, (LONG) i);
*/
}
/*---------------------------------------------------------------------------*/
d_set_line_miterlimit(double d)
{
        i++;
}
/*---------------------------------------------------------------------------*/
d_set_line_width(double w)
{
        stop;
      /* I wasted a lot of time to find out, that drawing with LINEWIDTH_THICK
       * is fu... slooooooow with GpiSetLineWidth(). That's not all:
       * LINEWIDTH_THICK isn't really 'thick'....  GpiSetLineWidthGeom()
       * works only inside a path bracket, draws 'really' thick lines and is
       * slow .. setting up a path takes time.
       */

        /*
        d_lwidth = LINEWIDTH_NORMAL;
        if (w >= 0.01)
                d_lwidth = LINEWIDTH_THICK;
        GpiSetLineWidth(hpsScreen, d_lwidth );

        gerr;goff;
        */

        /* works only *in* a path bracket */
/*        if (w >= 0.01)
                {
                d_lwidth = (LONG) 20 * w;
                GpiSetLineWidthGeom(hpsDraw, d_lwidth);
                }
        else
                {
                d_lwidth = 0;
                GpiSetLineWidthGeom(hpsDraw, (LONG) 0);
                }
                d_lwidth = 0;
*/
}
/*---------------------------------------------------------------------------*/
d_set_line_styled(double dd)
{}
d_set_line_style(char *s)
{
        static LONG defline[] =  {
                                        LINETYPE_SOLID,
                                        LINETYPE_SOLID,
                                        LINETYPE_DOT,
                                        LINETYPE_SHORTDASH,
                                        LINETYPE_DASHDOT,
                                        LINETYPE_LONGDASH,
                                        LINETYPE_DOUBLEDOT,
                                        LINETYPE_DASHDOUBLEDOT,
                                        LINETYPE_ALTERNATE,
                                        LINETYPE_ALTERNATE
                                 };

        int i, j, nblack, nwhite, pat, n;
        char *ss;
#ifdef FILLPATH
        flushPoly(PATH);
#endif
        flushPoly(NOPATH);
        stop;gon;
        n = atoi(s);
        if (n < 9 && n >= 0) {
                d_lstyle = defline[n];
                GpiSetLineType(hpsDraw, d_lstyle);
        } else {
                /* PM is unable to define new Line-Styles */
                GpiSetLineType(hpsDraw, LINETYPE_SOLID);
        }
        gerr;goff;
}
/*---------------------------------------------------------------------------*/
d_fill()
{
#ifdef FILLPATH
        if (!in_font)
                path_fill();
#endif
}
/*---------------------------------------------------------------------------*/
d_fill_ary(int nwk,double (*wkx)[],double (*wky)[])
{
        int i, ix, iy;
        int polypoints[2*(nwk+1)];

#ifdef FILLPATH
        flushPoly(PATH);
#endif
        flushPoly(NOPATH);

        dxy( (*wkx)[0], (*wky)[0], &ix, &iy);
        polypoints[0] = ix;
        polypoints[1] = iy;
        for (i=1;i<nwk;i++) {
                dxy( (*wkx)[i], (*wky)[i], &ix, &iy);
                polypoints[i+1] = ix;
                polypoints[i+2] = iy;
        }
        polypoints[++i] = polypoints[0];
        polypoints[++i] = polypoints[1];
        
        fillpoly(i, polypoints);
}
d_line_ary(int nwk,double (*wkx)[],double (*wky)[])
{
        int i;

        stop;gon;
        dxy( (*wkx)[0], (*wky)[0], &ix, &iy);
        moveto(ix,iy);
        for (i=1;i<nwk;i++) {
                dxy( (*wkx)[i], (*wky)[i], &ix, &iy);
                lineto(ix,iy);
        }
        gerr;goff;
}
/*---------------------------------------------------------------------------*/
d_stroke()
{
#ifdef FILLPATH
        if (!in_font)
                path_stroke();
#endif
}
/*---------------------------------------------------------------------------*/
d_clip()
{
}
/*---------------------------------------------------------------------------*/
d_set_matrix(double newmat[3][3])
{
}
/*---------------------------------------------------------------------------*/
d_move(double zx,double zy)
{
}
d_move_really(float zx, float zy)
{
        smoveto(sx(zx),sy(zy));
}
int draw_circle(void)
{
        POINTL xy;

        GpiQueryCurrentPosition(hpsDraw, &xy);
        ellipse(xy.x, window1H - xy.y,  0, 360,  4, 4);
}
/*---------------------------------------------------------------------------*/
d_reverse()     /* reverse the order of stuff in the current path */
{
}
/*---------------------------------------------------------------------------*/
d_closepath()
{
#ifdef FILLPATH
        if (g.inpath==true && in_font==false) {
                path_close();
                return;
        }
#endif
        g_line(g.closex,g.closey);
}
/*---------------------------------------------------------------------------*/
int dunx1,dunx2,duny1,duny2;
d_unline()
{
        GpiSetColor(hpsDraw, CLR_WHITE);
        moveto(dunx1,duny1);
        lineto(dunx2,duny2);
}
d_zzline(double cx,double cy,double zx,double zy)
{
        static int ux,uy,ix,iy;

        dxy(cx,cy,&ux,&uy);
        dunx1 = ux; duny1 = uy;
        dxy(zx,zy,&ix,&iy);
        GpiSetColor(hpsDraw, CLR_BLACK);
        moveto(ux,uy);
        lineto(ix,iy);
        dunx2 = ix; duny2 = iy;
}

d_line(double zx,double zy)
{
        static int ux,uy;
        if (g.xinline==false) {
                dxy(g.curx,g.cury,&ux,&uy);
                moveto(ux,uy);
                dunx1 = ux; duny1 = uy;
        }
        dxy(zx,zy,&ix,&iy);
        lineto(ix,iy);
        dunx2 = ix; duny2 = iy;
}
/*---------------------------------------------------------------------------*/
d_clear()
{
        double width,height;
        int x1,y1,x2,y2;
        int polypoints[] = {0,0, 0,maxy, maxx,maxy, maxx,0};
        int numpoints = 4;
        POINTL xy;

        width = g.userwidth;
        height = g.userheight;
        stop;
        d_lstyle = LINETYPE_SOLID;
        d_pat = 0;
        d_lwidth = LINEWIDTH_NORMAL;
        GpiErase(hpsDraw);

        /* now draw bounding box of screen */
        x1 = 0;
        y1 = d_maxy-height*d_yscale -1;
        x2 = width*d_xscale+2;
        y2 = d_maxy+1;

        GpiSetBackColor(hpsDraw, CLR_WHITE);
        /* BackColor WHITE + FG Color WHITE = much more WHITE */
        GpiSetColor(hpsDraw, CLR_WHITE);
        GpiBeginArea(hpsDraw, BA_BOUNDARY | BA_WINDING);
        smoveto(polypoints[0], polypoints[1]);
        for (i = 2; i < 2 * numpoints; i+=2)
                {
                 xy.x = polypoints[i];
                 xy.y = window1H - polypoints[i+1];
                 GpiLine(hpsDraw, &xy);
                }
        GpiEndArea(hpsDraw);

        GpiSetColor(hpsDraw, CLR_BLACK);
        goff;
}
/*---------------------------------------------------------------------------*/
d_flush()
{
}
/*---------------------------------------------------------------------------*/
int polar_xy(double r, double angle, double *dx, double *dy);
int xy_polar(double dx,double dy,double *radius,double *angle);

#ifdef OLDARC
d_arcto(dbl x1,dbl y1,dbl x2,dbl y2,dbl rrr)
{
        double x0,y0,r1,a1,r2,a2,r3,a3,a4,r5,sx,sy,ex,ey;
        double bx1,by1,bx2,by2,dist,neg;
        g_get_xy(&x0,&y0);
        xy_polar(x1-x0,y1-y0,&r1,&a1);
        xy_polar(x2-x1,y2-y1,&r2,&a2);
        neg = 1;
        a4 = (180-a2+a1);
        a3 = a2 + (a4/2);
        if ((a4/2)>90 && (a4/2)<180 ) neg = -1;
        if ((a4/2)<0 && (a4/2)>-90 ) neg = -1;
        r3 = neg*rrr/(tan((pi/180)*a4/2));
        dbg gprint("rrr %g a4/2 %g t=%g a2=%g a1=%g r1=%g r2=%g r3=%g \n",rrr,a4/2,tan(a4/2),a2,a1,r1,r2,r3);
        polar_xy(-r3,a1,&sx,&sy); sx += x1; sy += y1;
        polar_xy(r3,a2,&ex,&ey); ex += x1; ey += y1;
        g_line(sx,sy);
        dist = sqrt(pow(ex-sx,2) + pow(ey-sy,2));
        polar_xy(r1+ dist/2.5-r3,a1,&bx1,&by1); bx1 += x0; by1 += y0;
        polar_xy(-r2+ -dist/2.5+r3,a2,&bx2,&by2); bx2 += x2; by2 += y2;
        g_bezier(bx1,by1,bx2,by2,ex,ey);
        g_line(x2,y2);
}
/*---------------------------------------------------------------------------*/
d_arc(dbl r,dbl t1,dbl t2,dbl cx,dbl cy)
{
        static int ixr,iyr,icx,icy;
        double ux,uy,z;
        dxy(cx,cy,&icx,&icy);
        rxy(r,r,&ixr,&iyr);
        ellipse(icx,icy,(int) t1, (int) t2, ixr, iyr);
}
/*---------------------------------------------------------------------------*/
d_narc(dbl r,dbl t1,dbl t2,dbl cx,dbl cy)
{
        static int ixr,iyr,icx,icy;
        double ux,uy,z;
        dxy(cx,cy,&icx,&icy);
        rxy(r,r,&ixr,&iyr);
        z = t1; t1 = t2; t2 = z;      /* very tricky :^) */
        nellipse(icx,icy,(int) t1, (int) t2, ixr, iyr);
}
/*---------------------------------------------------------------------------*/

#else /* overworked arc code from easydev.c follows */

#define CSTEP (360/6)
df_arcto(dbl x1,dbl y1,dbl x2,dbl y2,dbl rrr)
{
        double x0,y0,r1,a1,r2,a2,r3,a3,a4,r5,sx,sy,ex,ey;
        double bx1,by1,bx2,by2,dist,neg;
        g_get_xy(&x0,&y0);
        xy_polar(x1-x0,y1-y0,&r1,&a1);
        xy_polar(x2-x1,y2-y1,&r2,&a2);
        neg = 1;
        a4 = (180-a2+a1);
        a3 = a2 + (a4/2);
        if ((a4/2)>90 && (a4/2)<180 ) neg = -1;
        if ((a4/2)<0 && (a4/2)>-90 ) neg = -1;
        r3 = neg*rrr/(tan((pi/180)*a4/2));
        polar_xy(-r3,a1,&sx,&sy); sx += x1; sy += y1;
        polar_xy(r3,a2,&ex,&ey); ex += x1; ey += y1;
        g_line(sx,sy);
        dist = sqrt((ex-sx)*(ex-sx) + (ey-sy)*(ey-sy));
        polar_xy(r1+ dist/2.5-r3,a1,&bx1,&by1); bx1 += x0; by1 += y0;
        polar_xy(-r2+ -dist/2.5+r3,a2,&bx2,&by2); bx2 += x2; by2 += y2;
        g_bezier(bx1,by1,bx2,by2,ex,ey);
        g_line(x2,y2);
}
df_arc(dbl r,dbl t1,dbl t2,dbl cx,dbl cy)
{
        /* circle from t1 to t2, lets use 6 bezier's for a circle */
        double stz;
        int nst,i;

        for (;t2<t1;)
              t2 = t2 + 360;

        nst = floor((t2-t1)/CSTEP)+1;
        stz = (t2-t1) / nst;
        for (i=1;i<=nst;i++)
                xdf_barc(r,t1+stz*(i-1),t1+stz*i,cx,cy);
}
xdf_barc(double r,dbl t1,dbl t2,dbl cx,dbl cy)
{
        double rx1,ry1,rx2,ry2,d,dx1,dy1,dx2,dy2;

        polar_xy(r,t1,&rx1,&ry1);
        polar_xy(r,t2,&rx2,&ry2);
        d = sqrt( (rx2-rx1)*(rx2-rx1) + (ry2-ry1)*(ry2-ry1));
        polar_xy(d/3,t1+90,&dx1,&dy1);
        polar_xy(d/3,t2-90,&dx2,&dy2);
        if (g.inpath) {
                g_line(rx1+cx,ry1+cy);
                g_bezier(rx1+cx+dx1,ry1+cy+dy1
                        ,rx2+cx+dx2,ry2+cy+dy2,rx2+cx,ry2+cy);
        } else {
                g_move(rx1+cx,ry1+cy);
                g_bezier(rx1+cx+dx1,ry1+cy+dy1
                        ,rx2+cx+dx2,ry2+cy+dy2,rx2+cx,ry2+cy);
                g_move(cx,cy);
        }
}

d_arcto(dbl x1,dbl y1,dbl x2,dbl y2,dbl rrr)
{
        df_arcto(x1,y1,x2,y2,rrr);
}
/*---------------------------------------------------------------------------*/
d_arc(dbl r,dbl t1,dbl t2,dbl cx,dbl cy)
{        
        df_arc(r,t1,t2,cx,cy);
}
/*---------------------------------------------------------------------------*/
d_narc(dbl r,dbl t1,dbl t2,dbl cx,dbl cy)
{
        /* swap t1 and t2 */
        df_arc(r,t2,t1,cx,cy);
}
/*---------------------------------------------------------------------------*/
#endif /* OLDARC */

/*---------------------------------------------------------------------------*/

d_box_fill(dbl x1, dbl y1, dbl x2, dbl y2)
{
        int v[8];
        
        flushPoly(NOPATH);
#ifdef FILLPATH
        path_close();           /* cruel, but effective */
        path_stroke();
#endif
        dxy(x1,y1,&v[0],&v[1]);
        dxy(x2,y1,&v[2],&v[3]);
        dxy(x2,y2,&v[4],&v[5]);
        dxy(x1,y2,&v[6],&v[7]);
        fillpoly(4,v);
}
d_box_stroke(dbl x1, dbl y1, dbl x2, dbl y2)
{
        static int ix1,iy1,ix2,iy2,ix3,iy3,ix4,iy4;

        stop;gon;
#ifdef FILLPATH
        path_close();           /* cruel, but effective */
        path_stroke();
#endif
        dxy(x1,y1,&ix1,&iy1);
        dxy(x2,y1,&ix2,&iy2);
        dxy(x2,y2,&ix3,&iy3);
        dxy(x1,y2,&ix4,&iy4);
        moveto(ix1,iy1);
        lineto(ix2,iy2);
        lineto(ix3,iy3);
        lineto(ix4,iy4);
        lineto(ix1,iy1);
        goff;
}
/*---------------------------------------------------------------------------*/
d_circle_stroke(double zr)
{
        d_arc(zr,0,360,g.curx,g.cury);
}
d_circle_fill(double zr)
{
#ifdef FILLPATH
        if (g.inpath == false){
                g_set_path(true);
                g_newpath();
                g_arc(zr,0,360,g.curx,g.cury);
                g_closepath();
                g_fill();
                g_set_path(false);
        }
        else
                g_arc(zr,0,360,g.curx,g.cury);
#else
        d_arc(zr,0,360,g.curx,g.cury);
#endif
}
/*---------------------------------------------------------------------------*/
d_bezier(dbl x1,dbl y1,dbl x2,dbl y2,dbl x3,dbl y3)
{
        double ax,bx,cx,ay,by,cy,dist;
        double xxx,yyy,i,t,nstep,x0,y0;
        g_get_xy(&x0,&y0);
        dist = fabs(x3-x0) + fabs(y3-y0);
        nstep = 12;
        if (dist<1) nstep = 7;
        if (dist<.5) nstep = 3;
        if (dist<.1) {
                g_line(x3,y3);
                return;
        }
        cx = (x1-x0)*3;
        bx = (x2-x1)*3-cx;
        ax = x3-x0-cx-bx;
        cy = (y1-y0)*3;
        by = (y2-y1)*3-cy;
        ay = y3-y0-cy-by;
        for (i=0;i<=nstep;i++) {
                t = i/nstep;
                xxx = ax*pow(t,3.0) + bx*t*t + cx*t + x0;
                yyy = ay*pow(t,3.0) + by*t*t + cy*t + y0;
                g_line(xxx,yyy);
        }
}
/*---------------------------------------------------------------------------*/
d_set_color(int32 f)
{
        LONG i;
        colortyp  cc;

#ifdef FILLPATH
        flushPoly(PATH);
#endif
        flushPoly(NOPATH);

        stop;gon;
        cc.l = f;
        i = 0;
        if (cc.b[B_R]>=10 && cc.b[B_G]>=10 && cc.b[B_B]>=10)    i = CLR_DARKGRAY;
        if (cc.b[B_R]>60  && cc.b[B_G]>60  && cc.b[B_B]>60)     i = CLR_PALEGRAY;
        if (cc.b[B_R]>100)                                      i = CLR_RED;
        if (cc.b[B_B]>100)                                      i = CLR_BLUE;
        if (cc.b[B_G]>100)                                      i = CLR_GREEN;
        if (cc.b[B_R]>100 && cc.b[B_G]>100)                     i = CLR_YELLOW;
        if (cc.b[B_G]>100 && cc.b[B_B]>100)                     i = CLR_CYAN;
        if (cc.b[B_R]>100 && cc.b[B_B]>100)                     i = CLR_DARKPINK;
        if (cc.b[B_R]>100 && cc.b[B_G]>100 && cc.b[B_B]>100)    i = CLR_PALEGRAY;
        if (cc.b[B_R]<10  && cc.b[B_G]<10  && cc.b[B_B]<10)     i = CLR_BLACK; 
        if (cc.b[B_R]>250 && cc.b[B_G]>250 && cc.b[B_B]>250)    i = CLR_WHITE;
        d_linecolor = i;
        GpiSetColor(hpsDraw, i);
        goff;
}
d_set_fill(int32 f)
{
        LONG i, j;
        colortyp  cc;

#ifdef FILLPATH
        flushPoly(PATH);
#endif
        flushPoly(NOPATH);
        
        stop;gon;
        cc.l = f;
        i = j = 0;
        if (cc.b[B_F] == 1){    /* colours */
                if (cc.b[B_R]>=10 && cc.b[B_G]>=10 && cc.b[B_B]>=10)    i = CLR_DARKGRAY;
                if (cc.b[B_R]>60  && cc.b[B_G]>60  && cc.b[B_B]>60)     i = CLR_PALEGRAY;
                if (cc.b[B_R]>100)                                      i = CLR_RED;
                if (cc.b[B_B]>100)                                      i = CLR_BLUE;
                if (cc.b[B_G]>100)                                      i = CLR_GREEN;
                if (cc.b[B_R]>100 && cc.b[B_G]>100)                     i = CLR_YELLOW;
                if (cc.b[B_G]>100 && cc.b[B_B]>100)                     i = CLR_CYAN; 
                if (cc.b[B_R]>30  && cc.b[B_B]>100)                     i = CLR_DARKPINK;
                if (cc.b[B_R]>100 && cc.b[B_G]>100 && cc.b[B_B]>100)    i = CLR_PALEGRAY;
                if (cc.b[B_R]<10  && cc.b[B_G]<10  && cc.b[B_B]<10)     i = CLR_BLACK; 
                if (cc.b[B_R]>250 && cc.b[B_G]>250 && cc.b[B_B]>250)    i = CLR_WHITE;
                d_fillcolor = i;
               }
        if (cc.b[B_F] == 2){    /* grids and shades */
                if (cc.b[B_R]==0x00 && cc.b[B_G]==0x20 && cc.b[B_B]==0x20) j=PATSYM_DENSE8; /* GRID   */
                if (cc.b[B_R]==0x04 && cc.b[B_G]==0x0f && cc.b[B_B]==0x0f) j=PATSYM_DENSE4; /* GRID1  */
                if (cc.b[B_R]==0x00 && cc.b[B_G]==0x10 && cc.b[B_B]==0x10) j=PATSYM_DENSE7; /* GRID2  */
                if (cc.b[B_R]==0x05 && cc.b[B_G]==0x20 && cc.b[B_B]==0x20) j=PATSYM_DENSE6; /* GRID3  */
                if (cc.b[B_R]==0x10 && cc.b[B_G]==0x40 && cc.b[B_B]==0x40) j=PATSYM_DENSE2; /* GRID4  */
                if (cc.b[B_R]==0x20 && cc.b[B_G]==0x60 && cc.b[B_B]==0x60) j=PATSYM_DENSE1; /* GRID5  */
                if (cc.b[B_R]==0x00 && cc.b[B_G]==0x00 && cc.b[B_B]==0x20) j=PATSYM_DIAG2;  /* SHADE  */
                if (cc.b[B_R]==0x04 && cc.b[B_G]==0x00 && cc.b[B_B]==0x0C) j=PATSYM_DIAG1;  /* SHADE1 */
                if (cc.b[B_R]==0x00 && cc.b[B_G]==0x00 && cc.b[B_B]==0x10) j=PATSYM_DIAG3;  /* SHADE2 */
                if (cc.b[B_R]==0x05 && cc.b[B_G]==0x00 && cc.b[B_B]==0x20) j=PATSYM_DIAG4;  /* SHADE3 */
                if (cc.b[B_R]==0x10 && cc.b[B_G]==0x00 && cc.b[B_B]==0x40) j=PATSYM_HORIZ;  /* SHADE4 */
                if (cc.b[B_R]==0x20 && cc.b[B_G]==0x00 && cc.b[B_B]==0x60) j=PATSYM_VERT;   /* SHADE5 */

                d_fillstyle = j;
                GpiSetPattern(hpsDraw, d_fillstyle);
               }
        else
                {
                d_fillstyle = 0;
                GpiSetPattern(hpsDraw, d_fillstyle);
                }
        goff;
}
/*---------------------------------------------------------------------------*/
d_beginclip()
{
}
d_endclip()
{
}
struct char_data {float wx,wy,x1,y1,x2,y2; };
int font_get_chardata(struct char_data **cd, int ff, int cc);
/*---------------------------------------------------------------------------*/
int safnt;
int simple_char(int cc);
d_char(int font, int cc)
{
        static struct char_data cd;
        static int ix1,ix2,iy1,iy2;
        static int ux,uy;
        char ss[2];

        in_font = !fontfill;
        ss[0] = cc;
        ss[1] = 0;
        if (safnt==0)
                safnt = pass_font("PLSR");
        if (font!=82 && font>7) {
                my_char(font,cc);
                in_font = false;
                return;
        }
        if (gunit) 
                simple_char(cc);
        else  
                my_char(safnt,cc);
        in_font = false;
}

int pass_font(char *s);
int draw_char_fixed(char *s);
int get_char_pcode(int ff, int cc, char **pp);
simple_char(int cc)
{
        char *pp;
        get_char_pcode(safnt,cc,&pp);
        draw_char_fixed(pp);
}
int frxi(char **s);
draw_char_fixed(char *s)
{
        int ux,uy,cx,cy,x1,y1,x2,y2,lx,ly;
        int32 xsclm,ysclm,xscld,yscld;
        double ox,oy;
        dxy(g.curx,g.cury,&ux,&uy);
        xsclm = g.fontsz*d_xscale; xscld = 1000;
        ysclm = g.fontsz*d_yscale; yscld = 1000;
        while (*s!=15) {
          switch (*s++) {
                case 1:
                cx = frxi(&s); cy = frxi(&s);
                moveto(ux + (cx*xsclm)/xscld, uy - (cy*ysclm)/yscld );
                lx = cx; ly = cy;
                break;
                case 2:
                cx = cx + frxi(&s); cy = cy + frxi(&s);
                lineto(ux + (cx*xsclm)/xscld, uy - (cy*ysclm)/yscld );
                break;
                case 3:
                cx = cx + frxi(&s); cy = cy + frxi(&s);
                x1 = cx; y1 = cy;
                cx = cx + frxi(&s); cy = cy + frxi(&s);
                x2 = cx; y2 = cy;
                cx = cx + frxi(&s); cy = cy + frxi(&s);
                g_bezier(x1,y1,x2,y2,cx,cy);
                break;
                case 4:
                lineto(ux + (lx*xsclm)/xscld, uy - (ly*ysclm)/yscld );
                break;
                case 5:
                case 6:
                case 7:
                case 8:
                break;
                case 0: /* no char in this font */
                goto abort;
                default:
                gprint("Error in mychar pcode %d \n",*s++);
                goto abort;
          }

        }
abort:;
}

#ifdef FILLPATH
/*-------------------------------------------------------------------------*/
/*                        path wrapper for OS/2 PM                         */
void path_close(void)
{
        if (in_font)
                return;

        if (polyPNum > 0)
                flushPoly(PATH);
        GpiCloseFigure(hpsDraw);
}
void path_fill(void)
{
        if (in_font)
                return;

        if (d_fillcolor == CLR_WHITE){ /* to draw the outline of an unfilled marker */
                path_stroke();
                return;
           }
        GpiSetColor(hpsDraw, d_fillcolor);
        GpiEndPath(hpsDraw);
        GpiFillPath(hpsDraw, 1L, fillrule);
        GpiSetColor(hpsDraw, d_linecolor);
}
void path_newpath(void)
{
        if (in_font)
                return;

        if (polyNum > 0)
                flushPoly(NOPATH);
        GpiBeginPath(hpsDraw, 1L);
}
void path_stroke(void)
{
        if (in_font)
                return;

        if (polyPNum > 0)
                flushPoly(PATH);
        GpiEndPath(hpsDraw);
        GpiOutlinePath(hpsDraw, 1L, 0L);
}

#endif
