xwords/xwords4/common/draw.c
2003-11-01 05:35:29 +00:00

370 lines
10 KiB
C

/* -*-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