123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571 |
- #include "cmGlobal.h"
- #include "cmFloatTypes.h"
- #include "cmRpt.h"
- #include "cmErr.h"
- #include "cmCtx.h"
- #include "cmMem.h"
- #include "cmMallocDebug.h"
- #include "cmGr.h"
- #include "cmGrDevCtx.h"
-
- #define _cmGrDcOffsX(p,xx) (xx) // ((p)->pext.loc.x + (xx))
- #define _cmGrDcOffsY(p,yy) (yy) // ((p)->pext.loc.y + (yy))
-
- cmGrDcH_t cmGrDcNullHandle = cmSTATIC_NULL_HANDLE;
-
- // cmGrDcRecd is used to store the state of the
- // device context on the cmGrDC_t stack.
- typedef struct cmGrDcRecd_str
- {
- cmGrColor_t color;
- unsigned fontId;
- unsigned fontStyle;
- unsigned fontSize;
- unsigned penWidth;
- unsigned penStyle;
-
- struct cmGrDcRecd_str* next;
- struct cmGrDcRecd_str* prev;
- } cmGrDcRecd_t;
-
- typedef struct cmGrDc_str
- {
- cmErr_t err;
- cmGrDev_t* dd; // device driver used by this context
- void* ddArg; // user assigned device driver callback arg
- cmGrDcRecd_t* list; // First recd on the stack (not the top).
- cmGrDcRecd_t* cur; // Top recd on the stack.
- cmGrPExt_t pext; // x,y is offset added to all drawing coordinates
- // w,h is size of drawing area
- } cmGrDc_t;
-
- // Note: recd's prior to p->cur are available.
- // Recd's after p->cur are on the stack.
-
- cmGrDc_t* _cmGrDcHandleToPtr( cmGrDcH_t h )
- {
- cmGrDc_t* p = (cmGrDc_t*)h.h;
- assert( p != NULL );
- return p;
- }
-
- void _cmGrDcRecdPrint( const cmChar_t* label, const cmGrDcRecd_t* r )
- {
- printf("%s r:%i g:%i b:%i fid:%i fs:0x%x fsz:%i pw:%i ps:0x%x\n",
- cmStringNullGuard(label),
- cmGrColorToR(r->color),cmGrColorToG(r->color),cmGrColorToB(r->color),
- r->fontId,r->fontStyle,r->fontSize,r->penWidth,r->penStyle);
- }
-
- // Make a duplicate of the current record (if it exists)
- // and insert it prior to the current record.
- // make the new record current.
- void _cmGrDcPush( cmGrDc_t* p )
- {
- if( p->cur == NULL )
- {
- assert( p->list == NULL );
- cmGrDcRecd_t* r = cmMemAllocZ( cmGrDcRecd_t, 1);
- p->dd->get_color( p->ddArg, &r->color );
- r->fontId = p->dd->get_font_family(p->ddArg );
- r->fontSize = p->dd->get_font_size( p->ddArg );
- r->fontStyle = p->dd->get_font_style( p->ddArg );
- r->penWidth = p->dd->get_pen_width( p->ddArg );
- r->penStyle = p->dd->get_pen_style( p->ddArg );
- p->list = r;
- p->cur = r;
- }
- else
- {
- cmGrDcRecd_t* r = p->cur->prev;
-
- // if no prev recd exists ...
- if( r == NULL )
- {
- // .... then allocate one
- r = cmMemAllocZ( cmGrDcRecd_t, 1 );
- *r = *p->cur;
- p->cur->prev = r;
- r->next = p->cur;
- }
- else
- {
- // ... otherwise use the prev one
- cmGrDcRecd_t* nrp = r->next;
- cmGrDcRecd_t* prp = r->prev;
- *r = *p->cur;
- r->next = nrp;
- r->prev = prp;
- }
-
- // make the new recd the cur recd
- p->cur = r;
-
- // if the new recd is the first on the list
- // then update the list begin pointer
- if( p->cur->prev == NULL )
- p->list = p->cur;
- }
-
- //_cmGrDcRecdPrint("push:", p->cur );
-
- }
-
- cmGrDcRC_t _cmGrDcPop(cmGrDc_t* p )
- {
- if( p->cur==NULL || p->cur->next == NULL )
- return cmErrMsg(&p->err,kStackFaultGrDcRC,"Cannot pop the last context record off the stack.");
-
- p->cur = p->cur->next;
-
- p->dd->set_color( p->ddArg, p->cur->color );
- p->dd->set_font_family( p->ddArg, p->cur->fontId );
- p->dd->set_font_size( p->ddArg, p->cur->fontSize );
- p->dd->set_font_style( p->ddArg, p->cur->fontStyle );
- p->dd->set_pen_width( p->ddArg, p->cur->penWidth );
- p->dd->set_pen_style( p->ddArg, p->cur->penStyle );
-
- //_cmGrDcRecdPrint("pop:", p->cur );
-
- return kOkGrDcRC;
- }
-
- cmGrDcRC_t _cmGrDcDestroy( cmGrDc_t* p )
- {
- cmGrDcRecd_t* rp = p->list;
- while( rp!=NULL )
- {
- cmGrDcRecd_t* tp = rp->next;
- cmMemFree( rp );
- rp = tp;
- }
-
- p->dd->destroy(p->ddArg);
-
-
- cmMemFree(p);
-
- return kOkGrDcRC;
- }
-
- cmGrDcRC_t cmGrDevCtxCreate( cmCtx_t* ctx, cmGrDcH_t* hp, cmGrDev_t* dd, void* ddArg, int x, int y, int w, int h )
- {
- cmGrDcRC_t rc;
- if((rc = cmGrDevCtxDestroy(hp)) != kOkGrDcRC )
- return rc;
-
- cmGrDc_t* p = cmMemAllocZ(cmGrDc_t,1);
-
- cmErrSetup(&p->err,&ctx->rpt,"cmGrDevCtx");
-
- p->dd = dd;
- p->ddArg = ddArg;
-
- cmGrPExtSet(&p->pext,x,y,w,h);
-
- if( dd->create(ddArg,w,h) == false )
- {
- cmErrMsg(&p->err,kDevDrvFailGrDcRC,"Device driver create failed.");
- goto errLabel;
- }
-
- _cmGrDcPush(p); // create the default context
-
- hp->h = p;
-
- errLabel:
- if(rc != kOkGrDcRC )
- _cmGrDcDestroy(p);
-
- return rc;
- }
-
- cmGrDcRC_t cmGrDevCtxDestroy( cmGrDcH_t* hp )
- {
- cmGrDcRC_t rc;
-
- if( hp==NULL || cmGrDevCtxIsValid(*hp)==false )
- return kOkGrDcRC;
-
- cmGrDc_t* p = _cmGrDcHandleToPtr(*hp);
-
- if((rc = _cmGrDcDestroy(p)) != kOkGrDcRC )
- return rc;
-
- hp->h = NULL;
-
- return rc;
- }
-
- bool cmGrDevCtxIsValid( cmGrDcH_t h )
- { return h.h != NULL; }
-
- cmGrDcRC_t cmGrDevCtxResize( cmGrDcH_t h, int x, int y, int ww, int hh )
- {
- cmGrDcRC_t rc = kOkGrDcRC;
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
-
- // store the current drawing context state
- _cmGrDcPush(p);
-
- if( p->dd->create(p->ddArg,ww,hh) == false )
- {
- cmErrMsg(&p->err,kDevDrvFailGrDcRC,"Device driver create failed on resize.");
- goto errLabel;
- }
-
- cmGrPExtSet(&p->pext,x,y,ww,hh);
-
- errLabel:
- // force the current state to be reapplied to the new drawing context
- _cmGrDcPop(p);
-
- return rc;
- }
-
- void cmGrDevCtxSize( cmGrDcH_t h, cmGrPExt_t* pext )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- *pext = p->pext;
- pext->loc.x *= -1;
- pext->loc.y *= -1;
- }
-
- void cmGrDevCtxBeginDraw( cmGrDcH_t h )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->dd->begin_draw( p->ddArg );
- }
-
- void cmGrDevCtxEndDraw( cmGrDcH_t h )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->dd->end_draw( p->ddArg );
- }
-
- void cmGrDevCtxDraw( cmGrDcH_t h )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->dd->draw( p->ddArg, -p->pext.loc.x, -p->pext.loc.y );
- }
-
-
- void cmGrDcPushCtx( cmGrDcH_t h )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- _cmGrDcPush(p);
- }
-
- void cmGrDcPopCtx( cmGrDcH_t h )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- _cmGrDcPop(p);
- }
-
-
- unsigned cmGrDcColor( cmGrDcH_t h )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- return p->cur->color;
- }
-
- void cmGrDcSetColorRgb( cmGrDcH_t h, unsigned char r, unsigned char g, unsigned char b )
- {
- cmGrDcSetColor(h,cmGrRgbToColor(r,g,b));
- }
-
- void cmGrDcSetColor( cmGrDcH_t h, cmGrColor_t color )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->dd->set_color( p->ddArg, color );
- }
-
- unsigned cmGrDcFontFamily( cmGrDcH_t h )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- return p->cur->fontId;
- }
-
- void cmGrDcSetFontFamily( cmGrDcH_t h, unsigned fontId )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->cur->fontId = fontId;
- p->dd->set_font_family( p->ddArg, fontId );
- }
-
- unsigned cmGrDcFontStyle( cmGrDcH_t h )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- return p->cur->fontStyle;
- }
-
- void cmGrDcSetFontStyle( cmGrDcH_t h, unsigned style )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->cur->fontStyle = style;
- p->dd->set_font_style( p->ddArg, style );
- }
-
- unsigned cmGrDcFontSize( cmGrDcH_t h )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- return p->cur->fontSize;
- }
-
- void cmGrDcSetFontSize( cmGrDcH_t h, unsigned size )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->cur->fontSize = size;
- p->dd->set_font_size( p->ddArg, size );
- }
-
- unsigned cmGrDcPenWidth( cmGrDcH_t h )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- return p->cur->penWidth;
- }
-
- void cmGrDcSetPenWidth( cmGrDcH_t h, unsigned width )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->cur->penWidth = width;
- p->dd->set_pen_width( p->ddArg, width );
- }
-
- unsigned cmGrDcPenStyle( cmGrDcH_t h )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- return p->cur->penStyle;
- }
-
- void cmGrDcSetPenStyle( cmGrDcH_t h, unsigned style )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->cur->penStyle = style;
- p->dd->set_pen_style( p->ddArg, style );
- }
-
- void cmGrDcDrawLine( cmGrDcH_t h, int x0, int y0, int x1, int y1 )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->dd->draw_line( p->ddArg, _cmGrDcOffsX(p,x0), _cmGrDcOffsY(p,y0), _cmGrDcOffsX(p,x1), _cmGrDcOffsY(p,y1) );
- }
-
- void cmGrDcDrawRect( cmGrDcH_t h, int x, int y, unsigned ww, unsigned hh )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->dd->draw_rect( p->ddArg, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y), ww, hh );
- }
-
- void cmGrDcDrawRectPExt( cmGrDcH_t h, const cmGrPExt_t* pext )
- { cmGrDcDrawRect( h, cmGrPExtL(pext), cmGrPExtT(pext), cmGrPExtW(pext), cmGrPExtH(pext) ); }
-
- void cmGrDcFillRect( cmGrDcH_t h, int x, int y, unsigned ww, unsigned hh )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->dd->fill_rect( p->ddArg, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y), ww, hh );
- }
-
- void cmGrDcDrawEllipse( cmGrDcH_t h, int x, int y, unsigned ww, unsigned hh )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->dd->draw_ellipse( p->ddArg, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y), ww, hh );
- }
-
- void cmGrDcFillEllipse( cmGrDcH_t h, int x, int y, unsigned ww, unsigned hh )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->dd->fill_ellipse( p->ddArg, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y), ww, hh );
- }
-
- void cmGrDcDrawDiamond( cmGrDcH_t h, int x, int y, unsigned ww, unsigned hh )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->dd->draw_diamond( p->ddArg, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y), ww, hh );
- }
-
- void cmGrDcFillDiamond( cmGrDcH_t h, int x, int y, unsigned ww, unsigned hh )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->dd->fill_diamond( p->ddArg, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y), ww, hh );
- }
-
- void cmGrDcDrawTriangle( cmGrDcH_t h, int x, int y, unsigned ww, unsigned hh, unsigned dirFlag )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->dd->draw_triangle( p->ddArg, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y), ww, hh, dirFlag );
- }
-
- void cmGrDcFillTriangle( cmGrDcH_t h, int x, int y, unsigned ww, unsigned hh, unsigned dirFlag )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->dd->fill_triangle( p->ddArg, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y), ww, hh, dirFlag );
- }
-
-
-
- void cmGrDcMeasure( cmGrDcH_t h, const cmChar_t* text, cmGrPSz_t* sz )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- if( text == NULL )
- cmGrPSzSet(sz,0,0);
- else
- {
- unsigned ww,hh;
- p->dd->measure_text( p->ddArg, text, &ww, &hh );
- sz->w = ww;
- sz->h = hh;
- }
- }
-
- void cmGrDcDrawText( cmGrDcH_t h, const cmChar_t* text, int x, int y )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->dd->draw_text( p->ddArg, text, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y) );
- }
-
- void cmGrDcDrawTextRot( cmGrDcH_t h, const cmChar_t* text, int x, int y, int angle )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->dd->draw_text_rot( p->ddArg, text, _cmGrDcOffsX(p,x), _cmGrDcOffsY(p,y), angle );
- }
-
-
- void cmGrDcReadImage( cmGrDcH_t h, unsigned char* a, const cmGrPExt_t* pext )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->dd->read_image( p->ddArg, a, _cmGrDcOffsX(p,pext->loc.x), _cmGrDcOffsY(p,pext->loc.y), pext->sz.w, pext->sz.h );
- }
-
- void cmGrDcDrawImage( cmGrDcH_t h, const unsigned char* a, const cmGrPExt_t* pext )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- p->dd->draw_image( p->ddArg, a, _cmGrDcOffsX(p,pext->loc.x), _cmGrDcOffsY(p,pext->loc.y), pext->sz.w, pext->sz.h );
- }
-
-
- void cmGrDcSetFont( cmGrDcH_t h, unsigned fontId, unsigned size, unsigned style )
- {
- cmGrDcSetFontFamily(h,fontId);
- cmGrDcSetFontSize( h,size);
- cmGrDcSetFontStyle( h,style);
- }
-
- void cmGrDcFontSetAndMeasure(cmGrDcH_t h, unsigned fontId, unsigned size, unsigned style, const cmChar_t* text, cmGrPSz_t* sz )
- {
- cmGrDcSetFont(h,fontId,size,style);
- cmGrDcMeasure(h,text,sz);
- }
-
- void cmGrDcDrawTextJustify( cmGrDcH_t h, unsigned fontId, unsigned size, unsigned style, const cmChar_t* text, const cmGrPExt_t* pext, unsigned flags )
- {
- int x = cmGrPExtCtrX(pext);
- int y = cmGrPExtCtrY(pext);
-
- if( cmIsFlag(flags,kNorthJsGrFl) )
- y = cmGrPExtT(pext);
- else
- if( cmIsFlag(flags,kSouthJsGrFl) )
- y = cmGrPExtB(pext);
-
- if( cmIsFlag(flags,kEastJsGrFl) )
- x = cmGrPExtR(pext);
- else
- if( cmIsFlag(flags,kWestJsGrFl) )
- x = cmGrPExtL(pext);
-
- cmGrDcDrawTextJustifyPt(h,fontId,size,style,text,flags,x,y);
- }
-
- void cmGrDcDrawTextJustifyPt( cmGrDcH_t h, unsigned fontId, unsigned size, unsigned style, const cmChar_t* text, unsigned flags, int xx, int yy )
- {
- cmGrPSz_t sz;
- cmGrDcFontSetAndMeasure(h, fontId, size, style, text, &sz );
-
- int x,y;
- if( cmIsFlag(flags,kRightJsGrFl) )
- x = xx;
- else
- if( cmIsFlag(flags,kLeftJsGrFl) )
- x = xx - sz.w;
- else
- x = xx - sz.w/2;
-
- if( cmIsFlag(flags,kBottomJsGrFl) )
- y = yy;
- else
- if( cmIsFlag(flags,kTopJsGrFl) )
- y = yy + sz.h;
- else
- y = yy + sz.h/2;
-
-
-
- cmGrPExt_t r;
- cmGrPExtSet(&r,x,y,sz.w,sz.h);
-
- // Note: Checking for visibility should not be necessary however
- // there appears to be a problem with the FLTK text output whereby
- // text coordinates over 0xffff wrap around and may appear in the
- // visible region.
- if( cmGrDcRectIsVisible(h,&r) )
- {
- /*
- if( text!=NULL && (strncmp(text,"loc:138",7)==0 || strcmp(text,"loc:8 ")==0))
- {
- printf("%s %i %i %i %i\n",text,x,y,sz.w,xx);
- cmGrPExtPrint(text,&r);
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- cmGrPExt_t res;
- cmGrPExtIntersect(&res,&p->pext,&r );
- cmGrPExtPrint(text,&p->pext);
- cmGrPExtPrint("isect:",&res);
- printf("%i\n",cmGrPExtIsNotNullOrEmpty(&res));
- }
- */
-
- cmGrDcDrawText(h, text, x+.5, y+.5 );
- }
- //cmGrPExt_t pext;
- //cmGrDcDrawTextJustifyRect(h, fontId, size, style, text, flags, xx, yy, &pext );
- //cmGrDcDrawRectPExt(h,&pext);
- }
-
- void cmGrDcDrawTextJustifyRect( cmGrDcH_t h, unsigned fontId, unsigned size, unsigned style, const cmChar_t* text, unsigned flags, int xx, int yy, cmGrPExt_t* pext )
- {
- cmGrPSz_t sz;
- cmGrDcFontSetAndMeasure(h, fontId, size, style, text, &sz );
-
- int x,y;
- if( cmIsFlag(flags,kRightJsGrFl) )
- x = xx;
- else
- if( cmIsFlag(flags,kLeftJsGrFl) )
- x = xx - sz.w;
- else
- x = xx - sz.w/2;
-
- if( cmIsFlag(flags,kBottomJsGrFl) )
- y = yy;
- else
- if( cmIsFlag(flags,kTopJsGrFl) )
- y = yy + sz.h;
- else
- y = yy + sz.h/2;
-
- cmGrPExtSet( pext, x, y-sz.h, sz.w+1, sz.h );
- }
-
- bool cmGrDcPointIsVisible( cmGrDcH_t h, int x, int y )
- {
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- return cmGrVExtIsXyInside(&p->pext,x,y);
- }
-
- bool cmGrDcRectIsVisible( cmGrDcH_t h, const cmGrPExt_t* r )
- {
- cmGrPExt_t res;
- cmGrDc_t* p = _cmGrDcHandleToPtr(h);
- cmGrPExtIntersect(&res,&p->pext,r );
- return cmGrPExtIsNotNullOrEmpty(&res);
- }
|