xwords/xwords4/wince/cedraw.c
2003-11-20 16:26:35 +00:00

832 lines
24 KiB
C
Executable file
Raw Blame History

/* -*-mode: C; fill-column: 78; c-basic-offset: 4;-*- */
/*
* Copyright 2000-2002 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.
*/
/* #include <stdlib.h> */
/* #include <stdio.h> */
#include <Windowsx.h>
#include <stdio.h> /* for sprintf, etc. */
#include "xptypes.h"
#include "board.h"
#include "draw.h"
#include "mempool.h"
#include "cemain.h"
#include "cedict.h"
#include "cedefines.h"
static void ceClearToBkground( CEDrawCtx* dctx, XP_Rect* rect );
static void ceDrawBitmapInRect( HDC hdc, XP_U32 x, XP_U32 y,
HBITMAP bitmap );
static void
XPRtoRECT( RECT* rt, XP_Rect* xprect )
{
rt->left = xprect->left;
rt->top = xprect->top;
rt->right = rt->left + xprect->width;
rt->bottom = rt->top + xprect->height;
} /* XPRtoRECT */
static void
makeAndDrawBitmap( CEDrawCtx* dctx, HDC hdc, XP_U32 x, XP_U32 y,
COLORREF foreRef, CEBitmapInfo* info )
{
#if 1
POINT points[2];
HGDIOBJ forePen;
XP_U16 nCols, nRows, row, col, rowBytes;
XP_UCHAR* bits = info->bits;
HGDIOBJ oldObj;
forePen = CreatePen( PS_SOLID, 1, foreRef );
oldObj = SelectObject( hdc, forePen );
nRows = info->nRows;
nCols = info->nCols;
rowBytes = (nCols + 7) / 8;
while ( (rowBytes % 2) != 0 ) {
++rowBytes;
}
for ( row = 0; row < nRows; ++row ) {
for ( col = 0; col < nCols; ++col ) {
XP_UCHAR byt = bits[col / 8];
XP_Bool set = (byt & (0x80 >> (col % 8))) != 0;
if ( set ) {
points[0].x = x + col;
points[0].y = y + row;
points[1].x = x + col + 1;
points[1].y = y + row + 1;
Polyline( hdc, points, 2 );
}
}
bits += rowBytes;
}
SelectObject( hdc, oldObj );
DeleteObject( forePen );
#else
/* I can't get this to work.... */
HBITMAP bm;
bm = CreateBitmap( info->nCols, info->nRows, 1, 1,
info->bits );
ceDrawBitmapInRect( hdc, rt->left+2, rt->top+2, bm );
DeleteObject( bm );
#endif
} /* makeAndDrawBitmap */
#if 0
static void
drawBitmapAt( HDC hdc, CEBitmapInfo* bmp, RECT* rt )
{
HDC tmpHDC;
HBITMAP bitmap = bmp->bitmap;
RECT r = *rt;
HBRUSH brush;
HBRUSH oldBrush;
tmpHDC = CreateCompatibleDC( hdc );
SelectObject( tmpHDC, bitmap );
r.bottom = r.top + bmp->nRows;
r.right = r.left + bmp->nCols;
BitBlt
/* brush = CreatePatternBrush( bitmap ); */
/* oldBrush = SelectObject( hdc, brush ); */
Rectangle( hdc, r.left, r.top, r.right, r.bottom );
/* FillRect( hdc, &r, brush ); */
/* SelectObject( hdc, oldBrush ); */
/* DeleteObject( brush ); */
} /* drawBitmapAt */
#endif
static void
ce_draw_boardBegin( DrawCtx* p_dctx, XP_Rect* rect, XP_Bool hasfocus )
{
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
CEAppGlobals* globals = dctx->globals;
HDC hdc = globals->hdc;
dctx->prevBkColor = GetBkColor( hdc );
} /* draw_boardBegin */
static void
ce_draw_boardFinished( DrawCtx* p_dctx )
{
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
CEAppGlobals* globals = dctx->globals;
HDC hdc = globals->hdc;
SetBkColor( hdc, dctx->prevBkColor );
} /* draw_finished */
static XP_U16
getPlayerColor( XP_S16 player )
{
if ( player < 0 ) {
return BLACK_COLOR;
} else {
return USER_COLOR1 + player;
}
} /* getPlayerColor */
static XP_Bool
ce_draw_drawCell( DrawCtx* p_dctx, XP_Rect* xprect,
XP_UCHAR* letters, XP_Bitmap* bitmap,
XP_S16 owner, XWBonusType bonus,
XP_Bool isBlank, XP_Bool isPending, XP_Bool isStar )
{
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
CEAppGlobals* globals = dctx->globals;
HDC hdc = globals->hdc;
RECT rt;
XP_U16 bkIndex;
XP_UCHAR* cp = NULL;
COLORREF foreIndex;
XPRtoRECT( &rt, xprect );
++rt.bottom;
++rt.right;
Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom );
InsetRect( &rt, 1, 1 );
if ( isPending ) {
foreIndex = dctx->colors[WHITE_COLOR];
bkIndex = BLACK_COLOR;
} else {
foreIndex = dctx->colors[getPlayerColor(owner)];
if ( bonus == BONUS_NONE ) {
bkIndex = BKG_COLOR;
} else {
bkIndex = bonus+BONUS1_COLOR;
}
}
FillRect( hdc, &rt, dctx->brushes[bkIndex] );
SetBkColor( hdc, dctx->colors[bkIndex] );
if ( !!letters && (letters[0] != '\0') ) {
cp = letters;
} else if ( !!bitmap ) {
/* it's already NULL */
}
if ( !!cp ) {
wchar_t widebuf[4];
XP_MEMSET( widebuf, 0, sizeof(widebuf) );
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, cp, -1,
widebuf, sizeof(widebuf)/sizeof(widebuf[0]) );
SetTextColor( hdc, foreIndex );
DrawText( hdc, widebuf, -1, &rt,
DT_SINGLELINE | DT_VCENTER | DT_CENTER);
} else if ( !!bitmap ) {
makeAndDrawBitmap( dctx, hdc, rt.left + 2, rt.top + 3, foreIndex,
(CEBitmapInfo*)bitmap );
/* CEBitmapInfo* info = (CEBitmapInfo*)bitmap; */
/* HBITMAP bm = CreateBitmap( info->nCols, info->nRows, 1, 1, info->bits ); */
/* ceDrawBitmapInRect( hdc, rt.left+2, rt.top+2, bm ); */
/* DeleteObject( bm ); */
} else if ( isStar ) {
ceDrawBitmapInRect( hdc, rt.left, rt.top, dctx->origin );
}
return XP_TRUE;
} /* ce_draw_drawCell */
static void
ce_draw_invertCell( DrawCtx* p_dctx, XP_Rect* rect )
{
} /* ce_draw_invertCell */
static void
ce_draw_trayBegin( DrawCtx* p_dctx, XP_Rect* rect, XP_U16 owner,
XP_Bool hasfocus )
{
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
dctx->trayOwner = owner;
} /* ce_draw_trayBegin */
static void
ce_draw_trayFinished( DrawCtx* p_dctx )
{
/* ce_draw_boardFinished( p_dctx ); */
} /* ce_draw_trayFinished */
static void
drawDrawTileGuts( DrawCtx* p_dctx, XP_Rect* xprect, XP_UCHAR* letters,
XP_Bitmap* bitmap, XP_S16 val, XP_Bool highlighted )
{
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
CEAppGlobals* globals = dctx->globals;
HDC hdc = globals->hdc;
wchar_t widebuf[4];
RECT rt;
ceClearToBkground( dctx, xprect );
XPRtoRECT( &rt, xprect );
InsetRect( &rt, 1, 1 );
Rectangle(hdc, rt.left, rt.top, rt.right, rt.bottom);
InsetRect( &rt, 1, 1 );
FillRect( hdc, &rt, dctx->brushes[TILEBACK_COLOR] );
SetBkColor( hdc, dctx->colors[TILEBACK_COLOR] );
SetTextColor( hdc, dctx->colors[getPlayerColor(dctx->trayOwner)] );
if ( highlighted ) {
Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom );
}
InsetRect( &rt, 1, 1 );
if ( !!letters ) {
HFONT oldFont = SelectObject( hdc, dctx->trayFont );
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, letters, -1,
widebuf, sizeof(widebuf)/sizeof(widebuf[0]) );
DrawText( hdc, widebuf, -1, &rt, DT_SINGLELINE | DT_TOP | DT_LEFT );
SelectObject( hdc, oldFont );
} else if ( !!bitmap ) {
makeAndDrawBitmap( dctx, hdc, rt.left + 1, rt.top + 4,
dctx->colors[USER_COLOR1+dctx->trayOwner],
(CEBitmapInfo*)bitmap );
/* CEBitmapInfo* info = (CEBitmapInfo*)bitmap; */
/* HBITMAP bm = CreateBitmap( info->nCols, info->nRows, 1, 1, info->bits ); */
/* ceDrawBitmapInRect( hdc, rt.left+2, rt.top+2, bm ); */
/* DeleteObject( bm ); */
/* ceDrawBitmapInRect( hdc, rt.left+2, rt.top+2, (HBITMAP)bitmap ); */
}
if ( val >= 0 ) {
swprintf( widebuf, L"%d", val );
DrawText(hdc, widebuf, -1, &rt, DT_SINGLELINE | DT_BOTTOM | DT_RIGHT);
}
} /* drawDrawTileGuts */
static void
ce_draw_drawTile( DrawCtx* p_dctx, XP_Rect* xprect, XP_UCHAR* letters,
XP_Bitmap* bitmap, XP_S16 val, XP_Bool highlighted )
{
drawDrawTileGuts( p_dctx, xprect, letters, bitmap, val, highlighted );
} /* ce_draw_drawTile */
static void
ce_draw_drawTileBack( DrawCtx* p_dctx, XP_Rect* xprect )
{
drawDrawTileGuts( p_dctx, xprect, "?", NULL, -1, XP_FALSE );
} /* ce_draw_drawTileBack */
static void
ce_draw_drawTrayDivider( DrawCtx* p_dctx, XP_Rect* rect, XP_Bool selected )
{
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
CEAppGlobals* globals = dctx->globals;
HDC hdc = globals->hdc;
RECT rt;
XPRtoRECT( &rt, rect );
if ( selected ) {
Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom );
} else {
FillRect( hdc, &rt, dctx->brushes[BLACK_COLOR] );
}
} /* ce_draw_drawTrayDivider */
static void
ceClearToBkground( CEDrawCtx* dctx, XP_Rect* rect )
{
CEAppGlobals* globals = dctx->globals;
HDC hdc = globals->hdc;
RECT rt;
XPRtoRECT( &rt, rect );
FillRect( hdc, &rt, dctx->brushes[BKG_COLOR] );
} /* ceClearToBkground */
static void
ce_draw_clearRect( DrawCtx* p_dctx, XP_Rect* rectP )
{
ceClearToBkground( (CEDrawCtx*)p_dctx, rectP );
} /* ce_draw_clearRect */
static void
ceDrawBitmapInRect( HDC hdc, XP_U32 x, XP_U32 y, HBITMAP bitmap )
{
BITMAP bmp;
HDC tmpDC;
int nBytes;
tmpDC = CreateCompatibleDC( hdc );
SelectObject( tmpDC, bitmap );
nBytes = GetObject( bitmap, sizeof(bmp), &bmp );
XP_ASSERT( nBytes > 0 );
BitBlt( hdc, x, y, bmp.bmWidth, bmp.bmHeight,
tmpDC, 0, 0, SRCCOPY ); /* BLACKNESS */
DeleteDC( tmpDC );
} /* ceDrawBitmapInRect */
static void
ce_draw_drawBoardArrow( DrawCtx* p_dctx, XP_Rect* xprect,
XWBonusType cursorBonus, XP_Bool vertical )
{
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
CEAppGlobals* globals = dctx->globals;
HDC hdc = globals->hdc;
wchar_t* txt = vertical? L"|":L"-";
RECT rt;
XP_U16 bkIndex;
HBITMAP cursor;
XPRtoRECT( &rt, xprect );
++rt.bottom;
++rt.right;
Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom );
InsetRect( &rt, 1, 1 );
if ( vertical ) {
cursor = dctx->downArrow;
} else {
cursor = dctx->rightArrow;
}
if ( cursorBonus == BONUS_NONE ) {
bkIndex = BKG_COLOR;
} else {
bkIndex = cursorBonus+BONUS1_COLOR;
}
FillRect( hdc, &rt, dctx->brushes[bkIndex] );
SetBkColor( hdc, dctx->colors[bkIndex] );
ceDrawBitmapInRect( hdc, rt.left+1, rt.top+1, cursor );
} /* ce_draw_drawBoardArrow */
static void
ce_draw_scoreBegin( DrawCtx* p_dctx, XP_Rect* rect, XP_U16 numPlayers,
XP_Bool hasfocus )
{
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
CEAppGlobals* globals = dctx->globals;
HDC hdc = globals->hdc;
SetBkColor( hdc, dctx->colors[BKG_COLOR] );
ceClearToBkground( (CEDrawCtx*)p_dctx, rect );
} /* ce_draw_scoreBegin */
static void
formatRemText( HDC hdc, wchar_t* buf, XP_S16 nTilesLeft, SIZE* size )
{
wchar_t* format = L"Rem:%d";
if ( nTilesLeft <= 0 ) {
buf[0] = 0;
size->cx = size->cy = 0;
} else {
swprintf( buf, format, nTilesLeft );
GetTextExtentPoint32( hdc, buf, wcslen(buf), size );
}
} /* formatRemText */
static void
ce_draw_measureRemText( DrawCtx* p_dctx, XP_Rect* r,
XP_S16 nTilesLeft,
XP_U16* width, XP_U16* height )
{
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
CEAppGlobals* globals = dctx->globals;
HDC hdc = globals->hdc;
wchar_t buf[16];
SIZE size;
formatRemText( hdc, buf, nTilesLeft, &size );
*width = (XP_U16)size.cx;
*height = (XP_U16)size.cy;
} /* ce_draw_measureRemText */
static XP_U16
ce_draw_drawRemText( DrawCtx* p_dctx, XP_Rect* rInner, XP_Rect* rOuter,
XP_S16 nTilesLeft )
{
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
CEAppGlobals* globals = dctx->globals;
HDC hdc = globals->hdc;
wchar_t buf[16];
RECT rt;
SIZE size;
formatRemText( hdc, buf, nTilesLeft, &size );
XPRtoRECT( &rt, rInner );
DrawText( hdc, buf, -1, &rt, DT_SINGLELINE | DT_LEFT | DT_VCENTER);
return (XP_U16)size.cx;
} /* ce_draw_drawRemText */
static void
ceWidthAndText( HDC hdc, wchar_t* buf, DrawScoreInfo* dsi,
XP_U16* widthP, XP_U16* heightP )
{
XP_UCHAR borders[] = {'<EFBFBD>', '\0'};
XP_UCHAR tilesLeftTxt[8];
XP_UCHAR tbuf[10]; /* *9999:7* is 8 chars */
SIZE size;
XP_U16 len;
if ( !dsi->isTurn ) {
borders[0] = '\0';
}
if ( dsi->nTilesLeft >= 0 ) {
sprintf( tilesLeftTxt, ":%d", dsi->nTilesLeft );
} else {
tilesLeftTxt[0] = '\0';
}
sprintf( tbuf, "%s%d%s%s", borders, dsi->score, tilesLeftTxt, borders );
len = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, tbuf, -1,
buf, 10 );
GetTextExtentPoint32( hdc, buf, len, &size );
*widthP = (XP_U16)size.cx;
*heightP = (XP_U16)size.cy;
} /* ceWidthAndText */
static void
ce_draw_measureScoreText( DrawCtx* p_dctx, XP_Rect* r,
DrawScoreInfo* dsi,
XP_U16* widthP, XP_U16* heightP )
{
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
CEAppGlobals* globals = dctx->globals;
HDC hdc = globals->hdc;
wchar_t widebuf[10];
HFONT newFont;
HFONT oldFont;
if ( dsi->selected ) {
newFont = dctx->selPlayerFont;
} else {
newFont = dctx->playerFont;
}
oldFont = SelectObject( hdc, newFont );
ceWidthAndText( hdc, widebuf, dsi, widthP, heightP );
SelectObject( hdc, oldFont );
} /* ce_draw_measureScoreText */
static void
ce_draw_score_drawPlayer( DrawCtx* p_dctx,
XP_S16 playerNum, /* -1: don't use */
XP_Rect* rInner, XP_Rect* rOuter,
DrawScoreInfo* dsi )
{
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
CEAppGlobals* globals = dctx->globals;
HDC hdc = globals->hdc;
RECT rt;
XP_U16 width, height;
wchar_t scoreBuf[20];
HFONT newFont;
HFONT oldFont;
XPRtoRECT( &rt, rInner );
if ( dsi->selected ) {
newFont = dctx->selPlayerFont;
} else {
newFont = dctx->playerFont;
}
oldFont = SelectObject( hdc, newFont );
SetTextColor( hdc, dctx->colors[getPlayerColor(playerNum)] );
ceWidthAndText( hdc, scoreBuf, dsi, &width, &height );
DrawText( hdc, scoreBuf, -1, &rt,
DT_SINGLELINE | DT_VCENTER | DT_CENTER );
SelectObject( hdc, oldFont );
} /* ce_draw_score_drawPlayer */
static void
ce_draw_score_pendingScore( DrawCtx* p_dctx, XP_Rect* rect, XP_S16 score,
XP_U16 playerNum )
{
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
CEAppGlobals* globals = dctx->globals;
HDC hdc = globals->hdc;
wchar_t widebuf[5];
XP_UCHAR buf[5];
RECT rt;
SetTextColor( hdc, dctx->colors[BLACK_COLOR] );
XPRtoRECT( &rt, rect );
FillRect( hdc, &rt, dctx->brushes[BKG_COLOR] );
if ( score < 0 ) {
buf[0] = '?';
buf[1] = '?';
buf[2] = '\0';
} else {
sprintf( buf, "%d", score );
}
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, buf, -1,
widebuf, sizeof(widebuf)/sizeof(widebuf[0]) );
DrawText(hdc, widebuf, -1, &rt, DT_SINGLELINE | DT_BOTTOM | DT_CENTER);
DrawText(hdc, L"Pts", -1, &rt, DT_SINGLELINE | DT_TOP | DT_CENTER);
} /* ce_draw_score_pendingScore */
static void
ce_draw_scoreFinished( DrawCtx* p_dctx )
{
/* ce_draw_boardFinished( p_dctx ); */
} /* ce_draw_scoreFinished */
static void
ce_draw_drawTimer( DrawCtx* p_dctx, XP_Rect* rInner, XP_Rect* rOuter,
XP_U16 player, XP_S16 secondsLeft )
{
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
CEAppGlobals* globals = dctx->globals;
HDC hdc = globals->hdc;
wchar_t widebuf[10];
XP_U16 mins, secs;
RECT rt;
PAINTSTRUCT ps;
XP_Bool isNegative;
XPRtoRECT( &rt, rInner );
isNegative = secondsLeft < 0;
if ( isNegative ) {
secondsLeft *= -1;
}
mins = secondsLeft / 60;
secs = secondsLeft % 60;
swprintf( widebuf, L"%s%.1d:%.2d", isNegative? L"-": L"", mins, secs );
if ( !globals->hdc ) {
InvalidateRect( dctx->mainWin, &rt, FALSE );
hdc = BeginPaint( dctx->mainWin, &ps );
}
SetTextColor( hdc, dctx->colors[getPlayerColor(player)] );
ceClearToBkground( dctx, rInner );
DrawText( hdc, widebuf, -1, &rt, DT_SINGLELINE | DT_VCENTER | DT_RIGHT);
if ( !globals->hdc ) {
EndPaint( dctx->mainWin, &ps );
}
} /* ce_draw_drawTimer */
static XP_UCHAR*
ce_draw_getMiniWText( DrawCtx* p_dctx, XWMiniTextType whichText )
{
XP_UCHAR* str;
switch( whichText ) {
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; tap 'D' when done"; break;
default:
XP_ASSERT( XP_FALSE );
}
return str;
} /* ce_draw_getMiniWText */
static void
ce_draw_measureMiniWText( DrawCtx* p_dctx, XP_UCHAR* str,
XP_U16* widthP, XP_U16* heightP )
{
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
CEAppGlobals* globals = dctx->globals;
HDC hdc = GetDC(dctx->mainWin);//globals->hdc;
SIZE size;
wchar_t widebuf[40];
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, str, -1,
widebuf, sizeof(widebuf)/sizeof(widebuf[0]) );
GetTextExtentPoint32( hdc, widebuf, wcslen(widebuf), &size );
*widthP = size.cx + 12;
*heightP = size.cy + 4;
} /* ce_draw_measureMiniWText */
static void
ce_draw_drawMiniWindow( DrawCtx* p_dctx, XP_UCHAR* text, XP_Rect* rect,
void** closureP )
{
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
CEAppGlobals* globals = dctx->globals;
HDC hdc = globals->hdc;
RECT rt;
PAINTSTRUCT ps;
wchar_t widebuf[40];
XPRtoRECT( &rt, rect );
if ( !globals->hdc ) {
InvalidateRect( dctx->mainWin, &rt, FALSE );
hdc = BeginPaint( dctx->mainWin, &ps );
}
ceClearToBkground( (CEDrawCtx*)p_dctx, rect );
Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom );
InsetRect( &rt, 1, 1 );
Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom );
XP_MEMSET( widebuf, 0, sizeof(widebuf) );
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, text, -1,
widebuf, sizeof(widebuf)/sizeof(widebuf[0]) );
DrawText(hdc, widebuf, -1, &rt, DT_SINGLELINE | DT_CENTER | DT_VCENTER);
if ( !globals->hdc ) {
EndPaint( dctx->mainWin, &ps );
}
} /* ce_draw_drawMiniWindow */
static void
ce_draw_eraseMiniWindow( DrawCtx* p_dctx, XP_Rect* rect, XP_Bool lastTime,
void** closure, XP_Bool* invalUnder )
{
*invalUnder = XP_TRUE;
} /* ce_draw_eraseMiniWindow */
static void
ce_draw_destroyCtxt( DrawCtx* p_dctx )
{
XP_U16 i;
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
for ( i = 0; i < 5; ++i ) {
DeleteObject( dctx->brushes[i] );
}
DeleteObject( dctx->trayFont );
DeleteObject( dctx->playerFont );
DeleteObject( dctx->selPlayerFont );
DeleteObject( dctx->rightArrow );
DeleteObject( dctx->downArrow );
DeleteObject( dctx->origin );
XP_FREE( dctx->mpool, p_dctx->vtable );
XP_FREE( dctx->mpool, dctx );
} /* ce_draw_destroyCtxt */
static void
draw_doNothing( DrawCtx* dctx, ... )
{
} /* draw_doNothing */
static void
ceFontsSetup( CEAppGlobals* globals, CEDrawCtx* dctx )
{
LOGFONT font;
XP_MEMSET( &font, 0, sizeof(font) );
font.lfHeight = (CE_TRAY_SCALEV*2)/3;
font.lfWeight = 600; /* FW_DEMIBOLD */
dctx->trayFont = CreateFontIndirect( &font );
font.lfWeight = FW_LIGHT;
font.lfHeight = CE_SCORE_HEIGHT - 2;
dctx->playerFont = CreateFontIndirect( &font );
font.lfWeight = FW_BOLD;
font.lfHeight = CE_SCORE_HEIGHT;
dctx->selPlayerFont = CreateFontIndirect( &font );
} /* ceFontsSetup */
static void
loadColors( XP_U16* ptr, COLORREF* colors )
{
XP_U16 i;
for ( i = 0; i < NUM_COLORS; ++i ) {
XP_U8 r = (XP_U8)*ptr++;
XP_U8 g = (XP_U8)*ptr++;
XP_U8 b = (XP_U8)*ptr++;
*colors++ = RGB( r, g, b );
}
} /* loadColors */
DrawCtx*
ce_drawctxt_make( MPFORMAL HWND mainWin, CEAppGlobals* globals )
{
HRSRC rsrcH;
HGLOBAL globH;
CEDrawCtx* dctx = (CEDrawCtx*)XP_MALLOC( mpool,
sizeof(*dctx) );
XP_U16 i;
dctx->vtable = (DrawCtxVTable*)XP_MALLOC( mpool, sizeof(*((dctx)->vtable)));
for ( i = 0; i < sizeof(*dctx->vtable)/4; ++i ) {
((void**)(dctx->vtable))[i] = draw_doNothing;
}
SET_VTABLE_ENTRY( dctx->vtable, draw_destroyCtxt, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_boardBegin, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_drawCell, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_invertCell, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_boardFinished, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_trayBegin, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_trayFinished, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_drawTile, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_drawTileBack, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_drawTrayDivider, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_clearRect, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_drawBoardArrow, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_scoreBegin, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_measureRemText, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_drawRemText, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_measureScoreText, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_score_drawPlayer, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_score_pendingScore, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_scoreFinished, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_drawTimer, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_getMiniWText, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_measureMiniWText, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_drawMiniWindow, ce );
SET_VTABLE_ENTRY( dctx->vtable, draw_eraseMiniWindow, ce );
dctx->mainWin = mainWin;
dctx->globals = globals;
/* load the colors from resource */
rsrcH = FindResource( globals->hInst, MAKEINTRESOURCE(ID_COLORS_RES),
TEXT("CLRS") );
globH = LoadResource( globals->hInst, rsrcH );
loadColors( globH, dctx->colors );
DeleteObject( globH );
for ( i = 0; i < NUM_COLORS; ++i ) {
dctx->brushes[i] = CreateSolidBrush( dctx->colors[i] );
}
ceFontsSetup( globals, dctx );
dctx->rightArrow = LoadBitmap( globals->hInst,
MAKEINTRESOURCE(IDB_RIGHTARROW) );
XP_DEBUGF( "loaded bitmap: 0x%lx", (unsigned long)dctx->rightArrow );
dctx->downArrow = LoadBitmap( globals->hInst,
MAKEINTRESOURCE(IDB_DOWNARROW) );
dctx->origin = LoadBitmap( globals->hInst,
MAKEINTRESOURCE(IDB_ORIGIN) );
return (DrawCtx*)dctx;
} /* ce_drawctxt_make */