#include "gc.h" #include "gfont.h" /* wrapper functions */ void GDrawPixelDirect( tGC *pGC, tCoord x, tCoord y, unsigned long color ){ pGC->DrawPixelDirect( pGC, x, y, color ); } tCoord GGetWidth ( tGC *pGC ) { return pGC->GetWidth( pGC ); } tCoord GGetHeight ( tGC *pGC ) { return pGC->GetHeight( pGC ); } unsigned long GConvColorToBytes(tGC *pGC, tColor color) { return pGC->ConvColorToBytes( pGC, color ); } tColor GConvBytesToColor (tGC *pGC, unsigned long color) { return pGC->ConvBytesToColor( pGC, color ); } tColor GSetFGColor ( tGC *pGC, tColor color ) { return pGC->SetFGColor( pGC, color ); } tColor GGetFGColor ( tGC *pGC ) { return pGC->GetFGColor( pGC ); } tColor GSetBGColor ( tGC *pGC, tColor color ) { return pGC->SetBGColor( pGC, color ); } tColor GGetBGColor ( tGC *pGC ) { return pGC->GetBGColor( pGC ); } void GDrawBegin ( tGC *pGC ) { pGC->DrawBegin( pGC ); } void GDrawEnd ( tGC *pGC ) { pGC->DrawEnd( pGC ); } void GMoveToPointCoord( tGC *pGC, tCoord x, tCoord y ) { pGC->x = x; pGC->y = y; } void GMoveToPoint ( tGC *pGC, tPoint *p ) { GMoveToPointCoord( pGC, p->x, p->y ); } void GLineToPointCoord( tGC *pGC, tCoord x, tCoord y ) { GDrawLineCoord( pGC, pGC->x, pGC->y, x, y ); GMoveToPointCoord( pGC, x, y ); } void GLineToPoint ( tGC *pGC, tPoint *p ) { GLineToPointCoord( pGC, p->x, p->y ); } void GPolyLineCoord ( tGC *pGC, int count, tCoord *x, tCoord *y ) { if( count > 0 ) { int xold = pGC->x; int yold = pGC->y; int i; GMoveToPointCoord( pGC, x[0], y[0] ); for( i=1 ; ix = xold; pGC->y = yold; } } void GPolyLinePoint ( tGC *pGC, int count, tPoint *p ) { if( count > 0 ) { int xold = pGC->x; int yold = pGC->y; int i; GMoveToPoint( pGC, p ); for( i=1 ; ix = xold; pGC->y = yold; } } void GPolygonCoord ( tGC *pGC, int count, tCoord *x, tCoord *y ) { if( count > 0 ) { int xold = pGC->x; int yold = pGC->y; int i; GMoveToPointCoord( pGC, x[0], y[0] ); for( i=1 ; ix = xold; pGC->y = yold; } } void GPolygonPoint ( tGC *pGC, int count, tPoint *p ) { if( count > 0 ) { int xold = pGC->x; int yold = pGC->y; int i; GMoveToPoint( pGC, p ); for( i=1 ; ix = xold; pGC->y = yold; } } void GDrawPointCoord( tGC *pGC, tCoord x1, tCoord y1 ) { pGC->DrawPointCoord( pGC, x1, y1 ); } void GDrawPoint ( tGC *pGC, tPoint *p ) { pGC->DrawPointCoord( pGC, p->x, p->y ); } void GDrawLineCoord( tGC *pGC, tCoord x1, tCoord y1, tCoord x2, tCoord y2 ) { pGC->DrawLineCoord( pGC, x1, y1, x2, y2 ); } void GDrawLinePoint( tGC *pGC, tPoint *ps, tPoint *pe ) { pGC->DrawLineCoord( pGC, ps->x, ps->y, pe->x, pe->y ); } void GDrawRectCoord( tGC *pGC, tCoord ulx, tCoord uly, tCoord brx, tCoord bry ) { pGC->DrawRectCoord( pGC, ulx, uly, brx, bry ); } void GDrawRectPoint( tGC *pGC, tPoint *ps, tPoint *pe ) { pGC->DrawRectCoord( pGC, ps->x, ps->y, pe->x, pe->y ); } void GDrawRect ( tGC *pGC, tRect *r ) { pGC->DrawRectCoord( pGC, r->UpperLeft.x, r->UpperLeft.y, r->BottomRight.x, r->BottomRight.y ); } void GFillRectCoord( tGC *pGC, tCoord ulx, tCoord uly, tCoord brx, tCoord bry ) { pGC->FillRectCoord( pGC, ulx, uly, brx, bry ); } void GFillRectPoint( tGC *pGC, tPoint *ps, tPoint *pe ) { pGC->FillRectCoord( pGC, ps->x, ps->y, pe->x, pe->y ); } void GFillRect ( tGC *pGC, tRect *r ) { pGC->FillRectCoord( pGC, r->UpperLeft.x, r->UpperLeft.y, r->BottomRight.x, r->BottomRight.y ); } int GSetClipRect ( tGC *pGC, tRect *r ) { return pGC->SetClipRect( pGC, r); } /* default implementations mandatory */ void GCDrawPixelDirect ( tGC *pGC, tCoord x, tCoord y, unsigned long color ) {} tCoord GCGetWidth( tGC *pGC ) { return 0; } tCoord GCGetHeight( tGC *pGC ) { return 0; } /* default implementations optional */ unsigned long GCConvColorToBytes( tGC *pGC, tColor color ) { return (unsigned long)color; } tColor GCConvBytesToColor( tGC *pGC, unsigned long color ) { return (tColor)color; } int GCOnOpen ( tGC *pGC, void *param ) { return 0; } void GCOnClose( tGC *pGC ) {} void GCDrawBegin( tGC *pGC ) {} void GCDrawEnd ( tGC *pGC ) {} tColor GCSetFGColor( tGC *pGC, tColor color ) { tColor old = pGC->fgColor; pGC->fgColor = color; pGC->fgDeviceColor = GConvColorToBytes( pGC, color ); return old; } tColor GCGetFGColor( tGC *pGC ) { return GConvBytesToColor( pGC, pGC->fgDeviceColor ); } tColor GCSetBGColor( tGC *pGC, tColor color ) { tColor old = pGC->bgColor; pGC->bgColor = color; pGC->bgDeviceColor = pGC->ConvColorToBytes( pGC, color ); return old; } tColor GCGetBGColor( tGC *pGC ) { return GConvBytesToColor( pGC, pGC->bgDeviceColor ); } void GCDrawPointCoord( tGC *pGC, tCoord x1, tCoord y1 ) { tPoint p = { x1, y1 }; if( pGC->rop & GC_ROP_CLIP && !ClipPointAgainstRect(&p,&pGC->ClipRect) ) return; pGC->DrawPixelDirect( pGC, x1, y1, pGC->fgDeviceColor ); } void GCDrawLineCoord( tGC *pGC, tCoord x1, tCoord y1, tCoord x2, tCoord y2 ) { int i, dx, dy, dx2, dy2, s1, s2, e, X, Y; X = x1; Y = y1; s1 = s2 = 1; if( (dx=x2-x1)<0 ) { dx = -dx; s1 = -1; } if( (dy=y2-y1)<0 ) { dy = -dy; s2 = -1; } dx++; dy++; dx2=dx+dx; dy2=dy+dy; GDrawPointCoord( pGC, X, Y ); if( dy>dx ) { e = dy2 - dx; for( i=1 ; ifgDeviceColor; pGC->fgDeviceColor = pGC->bgDeviceColor; for( y=uly ; y<=bry ; y++ ) { GDrawLineCoord(pGC,ulx,y,brx,y); } pGC->fgDeviceColor = old; } void GCDrawRectCoord( tGC *pGC, tCoord ulx, tCoord uly, tCoord brx, tCoord bry ) { tRect r = { {ulx, uly}, {brx, bry} }; int drawbg = pGC->rop & GC_ROP_DRAWBG ? 1 : 0; int visible = pGC->rop & GC_ROP_CLIP ? ClipRectAgainstRect( &r, &pGC->ClipRect ) : GC_EDGE_ALL; if( visible ) { ulx = r.UpperLeft.x; uly = r.UpperLeft.y; brx = r.BottomRight.x; bry = r.BottomRight.y; if( drawbg ) { GFillRectCoord( pGC, ulx, uly, brx, bry ); } if( visible & GC_EDGE_TOP ) GDrawLineCoord( pGC, ulx, uly, brx, uly ); /* top */ if( visible & GC_EDGE_BOTTOM ) GDrawLineCoord( pGC, ulx, bry, brx, bry ); /* bottom */ if( visible & GC_EDGE_LEFT ) GDrawLineCoord( pGC, ulx, uly, ulx, bry ); /* left */ if( visible & GC_EDGE_RIGHT ) GDrawLineCoord( pGC, brx, uly, brx, bry ); /* right */ } } void GDrawText( tGC *pGC, tRect *r, const char *text ) { tCoord tx, ty, y, w, h; const char *p; unsigned char f, bitmask; unsigned long fgDeviceColor = pGC->fgDeviceColor; unsigned long bgDeviceColor = pGC->bgDeviceColor; int drawbg = pGC->rop & GC_ROP_DRAWBG ? 1 : 0; tFont *fnt = &g_font[pGC->fntindex]; w = fnt->Width; h = fnt->Height; for( y = 0; y < h; y++ ) { tx=r->UpperLeft.x; ty=r->UpperLeft.y+y; p = text; while( *p ) { f = fnt->letter[*p++ * h + y]; if( drawbg ) { for( bitmask=0x80 ; bitmask ; bitmask>>=1, tx++ ) { if( (f & bitmask) ) { pGC->fgDeviceColor = fgDeviceColor; GDrawPointCoord( pGC, tx, ty ); } else { pGC->fgDeviceColor = bgDeviceColor; GDrawPointCoord( pGC, tx, ty ); } } } else { for( bitmask=0x80 ; bitmask ; bitmask>>=1, tx++ ) { if( (f & bitmask) ) { GDrawPointCoord( pGC, tx, ty ); } } } } } pGC->fgDeviceColor = fgDeviceColor; } void GTextRect( tGC *pGC, tRect *r, const char *text ) { tFont *fnt = &g_font[pGC->fntindex]; int len=0; while( *text++ ) len++; r->BottomRight.x = r->UpperLeft.x + len*fnt->Width -1; r->BottomRight.y = r->UpperLeft.y + fnt->Height-1; } static void DrawCirclePoints( tGC *pGC, int x0, int y0, int x, int y ) { GDrawPointCoord( pGC, x0 + x, y0 + y ); GDrawPointCoord( pGC, x0 + -x, y0 + y ); GDrawPointCoord( pGC, x0 + x, y0 + -y ); GDrawPointCoord( pGC, x0 + -x, y0 + -y ); GDrawPointCoord( pGC, x0 + y, y0 + -x ); GDrawPointCoord( pGC, x0 + -y, y0 + -x ); GDrawPointCoord( pGC, x0 + y, y0 + x ); GDrawPointCoord( pGC, x0 + -y, y0 + x ); } static void DrawCircleLines( tGC *pGC, int x0, int y0, int x, int y ) { GDrawLineCoord( pGC, x0 + x, y0 + y, x0 + -x, y0 + y ); GDrawLineCoord( pGC, x0 + x, y0 + -y, x0 + -x, y0 + -y ); GDrawLineCoord( pGC, x0 + y, y0 + -x, x0 + -y, y0 + -x ); GDrawLineCoord( pGC, x0 + y, y0 + x, x0 + -y, y0 + x ); } static void DrawCircle( tGC *pGC, int x0, int y0, int radius, void (*DrawCircleCB)( tGC *pGC, int x0, int y0, int x, int y ) ) { int x, y, d, dE, dSE; x = 0; y = radius; d = 1 - radius; dE = 3; dSE = -2 * radius + 5; DrawCircleCB( pGC, x0, y0, x, y ); while( y>x ) { if( d<0 ) { d+= dE; dSE+=2; } else { d+=dSE; dSE+=4; y--; } dE+=2; x++; DrawCircleCB( pGC, x0, y0, x, y ); } } void GDrawCircle( tGC *pGC, int x0, int y0, int radius ) { int drawbg = pGC->rop & GC_ROP_DRAWBG ? 1 : 0; if( drawbg ) { unsigned long old = pGC->fgDeviceColor; pGC->fgDeviceColor = pGC->bgDeviceColor; DrawCircle( pGC, x0, y0, radius, DrawCircleLines ); pGC->fgDeviceColor = old; } DrawCircle( pGC, x0, y0, radius, DrawCirclePoints ); } void GDrawCirclePoint( tGC *pGC, tPoint *p, int radius ) { GDrawCircle( pGC, p->x, p->y, radius ); } void GDrawCircleRect( tGC *pGC, tRect *r ) { int x = (r->BottomRight.x + r->UpperLeft.x)>>1; int y = (r->BottomRight.y + r->UpperLeft.y)>>1; int wx = (r->BottomRight.x - r->UpperLeft.x)>>1; int wy = (r->BottomRight.y - r->UpperLeft.y)>>1; int radius = wxrop = rm; } void GSetFont( tGC *pGC, int fntindex ) { if( fntindex < g_fonts ) { pGC->fntindex = fntindex; } else { pGC->fntindex = 0; } } void GGetScreenRect( tGC *pGC, tRect *r ) { r->UpperLeft.x = 0; r->UpperLeft.y = 0; r->BottomRight.x = GGetWidth(pGC) -1; r->BottomRight.y = GGetHeight(pGC)-1; } void GClear( tGC *pGC ) { tRect screen; unsigned long old = pGC->fgDeviceColor; GGetScreenRect( pGC, &screen ); pGC->fgDeviceColor = pGC->bgDeviceColor; GFillRect(pGC,&screen); pGC->fgDeviceColor = old; } int GCSetClipRect( tGC *pGC, tRect *r ) { tRect screen; GGetScreenRect( pGC, &screen ); pGC->ClipRect = *r; if( ClipRectAgainstRect( r, &screen ) ) return 0; return 1; }