/* -*-mode: C; fill-column: 78; c-basic-offset: 4; -*- */ /* * Copyright 1997 - 2003 by Eric House (fixin@peak.org). All rights reserved. * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #ifdef DRAW_WITH_PRIMITIVES #include "draw.h" #include "xptypes.h" static void insetRect( XP_Rect* r, XP_S16 amt ) { r->top += amt; r->left += amt; amt *= 2; r->width -= amt; r->height -= amt; } /* insetRect */ static void getRemText( XP_UCHAR* buf, XP_U16 bufSize, XP_S16 nTilesLeft ) { if ( nTilesLeft > 0 ) { XP_SNPRINTF( buf, bufSize, "rem: %d", nTilesLeft ); } else { buf[0] = '\0'; } } /* getRemText */ static void default_draw_measureRemText( DrawCtx* dctx, XP_Rect* r, XP_S16 nTilesLeft, XP_U16* widthP, XP_U16* heightP ) { XP_U16 width, height; if ( nTilesLeft > 0 ) { XP_UCHAR buf[20]; getRemText( buf, sizeof(buf), nTilesLeft ); draw_measureText( dctx, buf, &width, &height ); } else { width = height = 0; } *widthP = width; *heightP = height; } /* default_draw_measureRemText */ static void default_draw_drawRemText( DrawCtx* dctx, XP_Rect* rInner, XP_Rect* rOuter, XP_S16 nTilesLeft ) { XP_Rect oldClip; XP_UCHAR buf[10]; getRemText( buf, sizeof(buf), nTilesLeft ); draw_setClip( dctx, rOuter, &oldClip ); draw_drawString( dctx, buf, rOuter->left, rOuter->top ); draw_setClip( dctx, &oldClip, NULL ); } /* default_draw_drawRemText */ static void formatScore( XP_UCHAR* buf, XP_U16 bufSize, DrawScoreInfo* dsi ) { XP_UCHAR remBuf[10]; XP_UCHAR* selStr; if ( dsi->selected ) { selStr = "*"; } else { selStr = ""; } if ( dsi->nTilesLeft >= 0 ) { XP_SNPRINTF( remBuf, sizeof(remBuf), ":%d", dsi->nTilesLeft ); } else { remBuf[0] = '\0'; } XP_SNPRINTF( buf, bufSize, "%s%d%s%s", selStr, dsi->score, remBuf, selStr ); } /* formatScore */ static void default_draw_measureScoreText( DrawCtx* dctx, XP_Rect* r, DrawScoreInfo* dsi, XP_U16* widthP, XP_U16* heightP ) { XP_UCHAR buf[20]; formatScore( buf, sizeof(buf), dsi ); draw_measureText( dctx, buf, widthP, heightP ); } /* default_draw_measureScoreText */ static void default_draw_score_drawPlayer( DrawCtx* dctx, XP_S16 playerNum, /* -1: don't use */ XP_Rect* rInner, XP_Rect* rOuter, DrawScoreInfo* dsi ) { XP_Rect oldClip; XP_UCHAR buf[20]; draw_setClip( dctx, rInner, &oldClip ); draw_clearRect( dctx, rOuter ); formatScore( buf, sizeof(buf), dsi ); draw_drawString( dctx, buf, rInner->left, rInner->top ); draw_setClip( dctx, &oldClip, NULL ); } /* default_draw_score_drawPlayer */ static XP_Bool default_draw_drawCell( DrawCtx* dctx, XP_Rect* rect, /* at least one of these two will be null */ XP_UCHAR* text, XP_Bitmap bitmap, XP_S16 owner, /* -1 means don't use */ XWBonusType bonus, XP_Bool isBlank, XP_Bool highlight, XP_Bool isStar) { XP_Rect oldClip; XP_Rect inset = *rect; insetRect( &inset, 1 ); draw_setClip( dctx, rect, &oldClip ); draw_clearRect( dctx, rect ); if ( !!text && text[0] != 0 ) { draw_drawString( dctx, text, inset.left, inset.top ); } else if ( !!bitmap ) { draw_drawBitmap( dctx, bitmap, inset.left, inset.top ); } else if ( bonus != BONUS_NONE ) { XP_UCHAR* bstr; switch( bonus ) { case BONUS_DOUBLE_LETTER: bstr = "*"; break; case BONUS_DOUBLE_WORD: bstr = "%"; break; case BONUS_TRIPLE_LETTER: bstr = "#"; break; case BONUS_TRIPLE_WORD: bstr = "@"; break; default: XP_ASSERT(0); break; } draw_drawString( dctx, bstr, inset.left, inset.top ); } if ( highlight ) { draw_invertRect( dctx, &inset ); } draw_frameRect( dctx, rect ); draw_setClip( dctx, &oldClip, NULL ); return XP_TRUE; } /* default_draw_drawCell */ static void default_draw_drawBoardArrow( DrawCtx* dctx, XP_Rect* rect, XWBonusType bonus, XP_Bool vert ) { XP_Rect oldClip; XP_UCHAR* arrow; if ( vert ) { arrow = "|"; } else { arrow = "-"; } draw_setClip( dctx, rect, &oldClip ); draw_clearRect( dctx, rect ); draw_frameRect( dctx, rect ); draw_drawString( dctx, arrow, rect->left+1, rect->top+1 ); draw_setClip( dctx, &oldClip, NULL ); } /* default_draw_drawBoardArrow */ static void default_draw_drawTile( DrawCtx* dctx, XP_Rect* rect, /* at least 1 of these two will be null*/ XP_UCHAR* text, XP_Bitmap bitmap, XP_S16 val, XP_Bool highlighted ) { XP_Rect oldClip; XP_Rect inset = *rect; draw_setClip( dctx, rect, &oldClip ); draw_clearRect( dctx, rect ); draw_frameRect( dctx, rect ); if ( highlighted ) { insetRect( &inset, 1 ); draw_frameRect( dctx, &inset ); insetRect( &inset, 1 ); } else { insetRect( &inset, 2 ); } if ( !!text && text[0] != '\0' ) { draw_drawString( dctx, text, inset.left, inset.top ); } else if ( !!bitmap ) { draw_drawBitmap( dctx, bitmap, inset.left, inset.top ); } if ( val >= 0 ) { XP_UCHAR sbuf[4]; XP_U16 width, height; XP_U16 x, y; XP_SNPRINTF( sbuf, sizeof(sbuf), "%d", val ); draw_measureText( dctx, sbuf, &width, &height ); x = inset.left + inset.width - width; y = inset.top + inset.height - height; draw_drawString( dctx, sbuf, x, y ); } draw_setClip( dctx, &oldClip, NULL ); } /* default_draw_drawTile */ static void default_draw_drawTileBack( DrawCtx* dctx, XP_Rect* rect ) { default_draw_drawTile( dctx, rect, "?", NULL, -1, XP_FALSE ); } /* default_draw_drawTileBack */ static void default_draw_drawTrayDivider( DrawCtx* dctx, XP_Rect* rect, XP_Bool selected) { XP_Rect r = *rect; draw_clearRect( dctx, rect ); if ( r.width > 2 ) { r.width -= 2; r.left += 1; } draw_frameRect( dctx, &r ); } /* default_draw_drawTrayDivider */ static void default_draw_score_pendingScore( DrawCtx* dctx, XP_Rect* rect, XP_S16 score, XP_U16 playerNum ) { XP_UCHAR buf[5]; XP_Rect oldClip; XP_Rect r; XP_U16 width, height; XP_UCHAR* stxt; draw_setClip( dctx, rect, &oldClip ); XP_MEMCPY( &r, rect, sizeof(r) ); ++r.left; /* don't erase neighbor's border */ --r.width; draw_clearRect( dctx, &r ); draw_drawString( dctx, "pts", r.left, r.top ); if ( score >= 0 ) { XP_SNPRINTF( buf, sizeof(buf), "%d", score ); stxt = buf; } else { stxt = "???"; } draw_measureText( dctx, stxt, &width, &height ); draw_drawString( dctx, stxt, r.left, r.top + r.height - height ); draw_setClip( dctx, &oldClip, NULL ); } /* default_draw_score_pendingScore */ static XP_UCHAR* default_draw_getMiniWText( DrawCtx* dctx, XWMiniTextType textHint ) { unsigned char* str; switch( textHint ) { case BONUS_DOUBLE_LETTER: str = "Double letter"; break; case BONUS_DOUBLE_WORD: str = "Double word"; break; case BONUS_TRIPLE_LETTER: str = "Triple letter"; break; case BONUS_TRIPLE_WORD: str = "Triple word"; break; case INTRADE_MW_TEXT: str = "Trading tiles;\nclick D when done"; break; default: XP_ASSERT( XP_FALSE ); } return str; } /* default_draw_getMiniWText */ static void default_draw_measureMiniWText( DrawCtx* dctx, XP_UCHAR* textP, XP_U16* widthP, XP_U16* heightP ) { draw_measureText( dctx, textP, widthP, heightP ); /* increase for frame */ *widthP += 2; *heightP += 2; } /* default_draw_measureMiniWText */ static void default_draw_drawMiniWindow( DrawCtx* dctx, XP_UCHAR* text, XP_Rect* rect, void** closure ) { XP_Rect oldClip; draw_setClip( dctx, rect, &oldClip ); draw_clearRect( dctx, rect ); draw_frameRect( dctx, rect ); draw_drawString( dctx, text, rect->left+1, rect->top+1 ); draw_setClip( dctx, &oldClip, NULL ); } /* default_draw_drawMiniWindow */ static void default_draw_eraseMiniWindow( DrawCtx* dctx, XP_Rect* rect, XP_Bool lastTime, void** closure, XP_Bool* invalUnder ) { *invalUnder = XP_TRUE; /* let board.c do the work */ } /* default_draw_eraseMiniWindow */ void InitDrawDefaults( DrawCtxVTable* vtable ) { SET_VTABLE_ENTRY( vtable, draw_measureRemText, default ); SET_VTABLE_ENTRY( vtable, draw_drawRemText, default ); SET_VTABLE_ENTRY( vtable, draw_measureScoreText, default ); SET_VTABLE_ENTRY( vtable, draw_score_drawPlayer, default ); SET_VTABLE_ENTRY( vtable, draw_drawCell, default ); SET_VTABLE_ENTRY( vtable, draw_drawBoardArrow, default ); SET_VTABLE_ENTRY( vtable, draw_drawTile, default ); SET_VTABLE_ENTRY( vtable, draw_drawTileBack, default ); SET_VTABLE_ENTRY( vtable, draw_drawTrayDivider, default ); SET_VTABLE_ENTRY( vtable, draw_score_pendingScore, default ); SET_VTABLE_ENTRY( vtable, draw_getMiniWText, default ); SET_VTABLE_ENTRY( vtable, draw_measureMiniWText, default ); SET_VTABLE_ENTRY( vtable, draw_drawMiniWindow, default ); SET_VTABLE_ENTRY( vtable, draw_eraseMiniWindow, default ); } /* InitDrawDefaults */ #endif