xwords/xwords4/wince/cedraw.c
2004-01-10 18:02:10 +00:00

838 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+2, rt.top+1, 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 );
SetBkColor( hdc, dctx->colors[TILEBACK_COLOR] );
SetTextColor( hdc, dctx->colors[getPlayerColor(dctx->trayOwner)] );
XPRtoRECT( &rt, xprect );
InsetRect( &rt, 1, 1 );
Rectangle(hdc, rt.left, rt.top, rt.right, rt.bottom);
InsetRect( &rt, 1, 1 );
/* For some reason Rectangle isn't using the background brush to fill, so
FillRect has to get called after Rectangle. Need to call InsetRect
either way to put chars in the right place. */
if ( highlighted ) {
Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom );
InsetRect( &rt, 1, 1 );
}
FillRect( hdc, &rt, dctx->brushes[TILEBACK_COLOR] );
if ( !highlighted ) {
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 + 1; /* 1: don't write up against edge */
*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 );
++rt.left; /* 1: don't write up against edge */
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 */