2003-11-20 17:26:35 +01:00
|
|
|
|
/* -*-mode: C; fill-column: 78; c-basic-offset: 4;-*- */
|
|
|
|
|
/*
|
2006-01-08 02:25:02 +01:00
|
|
|
|
* Copyright 2000-2002 by Eric House (xwords@eehouse.org). All rights reserved.
|
2003-11-20 17:26:35 +01:00
|
|
|
|
*
|
|
|
|
|
* 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> */
|
|
|
|
|
|
2005-11-27 21:05:33 +01:00
|
|
|
|
#include <windowsx.h>
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
#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"
|
2006-01-28 20:03:10 +01:00
|
|
|
|
#include "debhacks.h"
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
#ifndef DRAW_FUNC_NAME
|
|
|
|
|
#define DRAW_FUNC_NAME(nam) ce_draw_ ## nam
|
|
|
|
|
#endif
|
|
|
|
|
|
2006-05-09 04:01:27 +02:00
|
|
|
|
#define CE_MINI_V_PADDING 6
|
|
|
|
|
#define CE_INTERLINE_SPACE 0
|
|
|
|
|
|
2006-02-18 07:39:40 +01:00
|
|
|
|
static void ceClearToBkground( CEDrawCtx* dctx, const XP_Rect* rect );
|
2005-06-13 15:32:06 +02:00
|
|
|
|
static void ceDrawBitmapInRect( HDC hdc, const RECT* r, HBITMAP bitmap );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
2006-02-18 07:39:40 +01:00
|
|
|
|
XPRtoRECT( RECT* rt, const XP_Rect* xprect )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
rt->left = xprect->left;
|
|
|
|
|
rt->top = xprect->top;
|
|
|
|
|
rt->right = rt->left + xprect->width;
|
|
|
|
|
rt->bottom = rt->top + xprect->height;
|
|
|
|
|
} /* XPRtoRECT */
|
|
|
|
|
|
|
|
|
|
static void
|
2006-04-03 00:27:44 +02:00
|
|
|
|
makeAndDrawBitmap( CEDrawCtx* dctx, HDC hdc, const RECT* bnds, XP_Bool center,
|
2003-11-20 17:26:35 +01:00
|
|
|
|
COLORREF foreRef, CEBitmapInfo* info )
|
|
|
|
|
{
|
|
|
|
|
#if 1
|
|
|
|
|
POINT points[2];
|
|
|
|
|
HGDIOBJ forePen;
|
|
|
|
|
XP_U16 nCols, nRows, row, col, rowBytes;
|
2006-04-03 00:27:44 +02:00
|
|
|
|
XP_S32 x, y;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2006-04-03 00:27:44 +02:00
|
|
|
|
x = bnds->left;
|
|
|
|
|
y = bnds->top;
|
|
|
|
|
if ( center ) {
|
|
|
|
|
/* the + 1 is to round up */
|
|
|
|
|
x += ((bnds->right - bnds->left) - nCols + 1) / 2;
|
|
|
|
|
y += ((bnds->bottom - bnds->top) - nRows + 1) / 2;
|
|
|
|
|
}
|
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
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
|
2004-02-13 14:47:37 +01:00
|
|
|
|
/* I can't get this to work. Hence the above hack.... */
|
2003-11-20 17:26:35 +01:00
|
|
|
|
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 */
|
|
|
|
|
|
2006-05-09 04:01:27 +02:00
|
|
|
|
static void
|
|
|
|
|
measureText( CEDrawCtx* dctx, const XP_UCHAR* str,
|
|
|
|
|
XP_U16* widthP, XP_U16* heightP )
|
|
|
|
|
{
|
|
|
|
|
HDC hdc = GetDC(dctx->mainWin);//globals->hdc;
|
|
|
|
|
XP_U16 height, maxWidth;
|
|
|
|
|
|
|
|
|
|
for ( height = CE_MINI_V_PADDING, maxWidth = 0; ; ) {
|
|
|
|
|
wchar_t widebuf[64];
|
|
|
|
|
XP_UCHAR* nextStr = strstr( str, XP_CR );
|
|
|
|
|
XP_U16 len = nextStr==NULL? strlen(str): nextStr - str;
|
|
|
|
|
SIZE size;
|
|
|
|
|
|
|
|
|
|
XP_ASSERT( nextStr != str );
|
|
|
|
|
|
|
|
|
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, str, len,
|
|
|
|
|
widebuf, sizeof(widebuf)/sizeof(widebuf[0]) );
|
|
|
|
|
widebuf[len] = 0;
|
|
|
|
|
GetTextExtentPoint32( hdc, widebuf, wcslen(widebuf), &size );
|
|
|
|
|
|
|
|
|
|
maxWidth = (XP_U16)XP_MAX( maxWidth, size.cx );
|
|
|
|
|
height += size.cy + CE_INTERLINE_SPACE;
|
|
|
|
|
dctx->miniLineHt = (XP_U16)size.cy;
|
|
|
|
|
|
|
|
|
|
if ( nextStr == NULL ) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
str = nextStr + XP_STRLEN(XP_CR); /* skip '\n' */
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*widthP = maxWidth + 8;
|
|
|
|
|
*heightP = height;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
drawLines( CEDrawCtx* dctx, HDC hdc, const XP_UCHAR* text, const RECT* rp,
|
|
|
|
|
int flags )
|
|
|
|
|
{
|
|
|
|
|
wchar_t widebuf[128];
|
|
|
|
|
RECT textRt = *rp;
|
|
|
|
|
|
|
|
|
|
for ( ; ; ) { /* draw up to the '\n' each time */
|
|
|
|
|
XP_UCHAR* nextStr = strstr( text, XP_CR );
|
|
|
|
|
XP_U16 len;
|
|
|
|
|
|
|
|
|
|
if ( nextStr == NULL ) {
|
|
|
|
|
len = XP_STRLEN(text);
|
|
|
|
|
} else {
|
|
|
|
|
len = nextStr - text;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, text, len,
|
|
|
|
|
widebuf, sizeof(widebuf)/sizeof(widebuf[0]) );
|
|
|
|
|
widebuf[len] = 0;
|
|
|
|
|
|
|
|
|
|
textRt.bottom = textRt.top + dctx->miniLineHt;
|
|
|
|
|
|
|
|
|
|
DrawText( hdc, widebuf, -1, &textRt, flags );
|
|
|
|
|
|
|
|
|
|
if ( nextStr == NULL ) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
textRt.top = textRt.bottom + CE_INTERLINE_SPACE;
|
|
|
|
|
text = nextStr + XP_STRLEN(XP_CR);
|
|
|
|
|
}
|
|
|
|
|
} /* drawLines */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC XP_Bool
|
|
|
|
|
DRAW_FUNC_NAME(boardBegin)( DrawCtx* p_dctx, const DictionaryCtxt* dict,
|
|
|
|
|
const XP_Rect* rect, XP_Bool hasfocus )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
HDC hdc = globals->hdc;
|
2004-02-13 14:47:37 +01:00
|
|
|
|
XP_Bool canDraw = !!hdc;
|
|
|
|
|
if ( canDraw ) {
|
|
|
|
|
dctx->prevBkColor = GetBkColor( hdc );
|
|
|
|
|
}
|
|
|
|
|
return canDraw;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} /* draw_boardBegin */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(boardFinished)( DrawCtx* p_dctx )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
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 */
|
|
|
|
|
|
2004-06-16 06:17:08 +02:00
|
|
|
|
static void
|
2004-12-12 18:39:59 +01:00
|
|
|
|
ceDrawLine( HDC hdc, XP_S32 x1, XP_S32 y1, XP_S32 x2, XP_S32 y2 )
|
2004-06-16 06:17:08 +02:00
|
|
|
|
{
|
2004-12-12 18:39:59 +01:00
|
|
|
|
POINT points[2];
|
2004-06-16 06:17:08 +02:00
|
|
|
|
|
2004-12-12 18:39:59 +01:00
|
|
|
|
points[0].x = x1;
|
|
|
|
|
points[0].y = y1;
|
|
|
|
|
points[1].x = x2;
|
|
|
|
|
points[1].y = y2;
|
|
|
|
|
Polyline( hdc, points, 2 );
|
|
|
|
|
} /* ceDrawLine */
|
|
|
|
|
|
|
|
|
|
static void
|
2006-02-18 07:39:40 +01:00
|
|
|
|
ceDrawHintBorders( HDC hdc, const XP_Rect* xprect, HintAtts hintAtts )
|
2004-12-12 18:39:59 +01:00
|
|
|
|
{
|
|
|
|
|
if ( hintAtts != HINT_BORDER_NONE && hintAtts != HINT_BORDER_CENTER ) {
|
|
|
|
|
RECT rt;
|
|
|
|
|
XPRtoRECT( &rt, xprect );
|
|
|
|
|
InsetRect( &rt, 1, 1 );
|
|
|
|
|
|
|
|
|
|
if ( (hintAtts & HINT_BORDER_LEFT) != 0 ) {
|
|
|
|
|
ceDrawLine( hdc, rt.left, rt.top, rt.left, rt.bottom+1 );
|
|
|
|
|
}
|
|
|
|
|
if ( (hintAtts & HINT_BORDER_RIGHT) != 0 ) {
|
|
|
|
|
ceDrawLine( hdc, rt.right, rt.top, rt.right, rt.bottom+1 );
|
|
|
|
|
}
|
|
|
|
|
if ( (hintAtts & HINT_BORDER_TOP) != 0 ) {
|
|
|
|
|
ceDrawLine( hdc, rt.left, rt.top, rt.right+1, rt.top );
|
|
|
|
|
}
|
|
|
|
|
if ( (hintAtts & HINT_BORDER_BOTTOM) != 0 ) {
|
|
|
|
|
ceDrawLine( hdc, rt.left, rt.bottom, rt.right+1, rt.bottom );
|
|
|
|
|
}
|
|
|
|
|
}
|
2004-06-16 06:17:08 +02:00
|
|
|
|
} /* ceDrawHintBorders */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC XP_Bool
|
|
|
|
|
DRAW_FUNC_NAME(drawCell)( DrawCtx* p_dctx, const XP_Rect* xprect,
|
|
|
|
|
const XP_UCHAR* letters, XP_Bitmap bitmap,
|
|
|
|
|
Tile tile, XP_S16 owner, XWBonusType bonus,
|
|
|
|
|
HintAtts hintAtts, XP_Bool isBlank,
|
|
|
|
|
XP_Bool isPending, XP_Bool isStar )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
HDC hdc = globals->hdc;
|
|
|
|
|
RECT rt;
|
2004-06-16 06:17:08 +02:00
|
|
|
|
RECT textRect;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
XP_U16 bkIndex;
|
2006-02-18 07:39:40 +01:00
|
|
|
|
const XP_UCHAR* cp = NULL;
|
2004-02-16 00:37:45 +01:00
|
|
|
|
COLORREF foreColorRef;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2004-02-13 14:47:37 +01:00
|
|
|
|
XP_ASSERT( !!hdc );
|
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
XPRtoRECT( &rt, xprect );
|
|
|
|
|
++rt.bottom;
|
|
|
|
|
++rt.right;
|
|
|
|
|
|
|
|
|
|
Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom );
|
2004-06-16 06:17:08 +02:00
|
|
|
|
textRect = rt;
|
|
|
|
|
InsetRect( &textRect, 1, 1 );
|
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
InsetRect( &rt, 1, 1 );
|
|
|
|
|
|
2004-02-16 00:37:45 +01:00
|
|
|
|
if ( (!!letters && letters[0] != '\0' ) || !!bitmap ) {
|
|
|
|
|
if ( isPending ) {
|
|
|
|
|
bkIndex = BLACK_COLOR;
|
2004-03-28 03:14:34 +02:00
|
|
|
|
foreColorRef = dctx->globals->appPrefs.colors[WHITE_COLOR];
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} else {
|
2004-03-28 03:14:34 +02:00
|
|
|
|
foreColorRef = dctx->globals->appPrefs.colors[getPlayerColor(owner)];
|
2004-02-16 00:37:45 +01:00
|
|
|
|
bkIndex = TILEBACK_COLOR;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
2004-02-16 00:37:45 +01:00
|
|
|
|
} else if ( bonus == BONUS_NONE ) {
|
|
|
|
|
bkIndex = BKG_COLOR;
|
|
|
|
|
} else {
|
|
|
|
|
bkIndex = (bonus - BONUS_DOUBLE_LETTER) + BONUS1_COLOR;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
2004-02-16 00:37:45 +01:00
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
FillRect( hdc, &rt, dctx->brushes[bkIndex] );
|
2004-02-18 05:24:21 +01:00
|
|
|
|
|
|
|
|
|
if ( isBlank ) {
|
|
|
|
|
/* For some reason windoze won't let me paint just the corner pixels
|
|
|
|
|
when certain colors are involved, but it will let me paint the
|
|
|
|
|
whole rect and then erase all but the corners. File this under
|
|
|
|
|
"don't ask, but it works". */
|
|
|
|
|
RECT tmpRT;
|
|
|
|
|
FillRect( hdc, &rt, dctx->brushes[isPending?WHITE_COLOR:BLACK_COLOR] );
|
|
|
|
|
|
|
|
|
|
tmpRT = rt;
|
|
|
|
|
InsetRect( &tmpRT, 0, 2 );
|
|
|
|
|
FillRect( hdc, &tmpRT, dctx->brushes[bkIndex] );
|
|
|
|
|
|
|
|
|
|
tmpRT = rt;
|
|
|
|
|
InsetRect( &tmpRT, 1, 0 );
|
|
|
|
|
FillRect( hdc, &tmpRT, dctx->brushes[bkIndex] );
|
|
|
|
|
}
|
|
|
|
|
|
2004-03-28 03:14:34 +02:00
|
|
|
|
SetBkColor( hdc, dctx->globals->appPrefs.colors[bkIndex] );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
if ( !!letters && (letters[0] != '\0') ) {
|
|
|
|
|
wchar_t widebuf[4];
|
2004-02-16 00:37:45 +01:00
|
|
|
|
cp = letters;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
XP_MEMSET( widebuf, 0, sizeof(widebuf) );
|
|
|
|
|
|
|
|
|
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, cp, -1,
|
|
|
|
|
widebuf, sizeof(widebuf)/sizeof(widebuf[0]) );
|
|
|
|
|
|
2004-02-16 00:37:45 +01:00
|
|
|
|
SetTextColor( hdc, foreColorRef );
|
2005-11-27 23:06:04 +01:00
|
|
|
|
#ifdef TARGET_OS_WIN32
|
|
|
|
|
HFONT oldFont = SelectObject( hdc, dctx->trayFont );
|
|
|
|
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, letters, -1,
|
|
|
|
|
widebuf, sizeof(widebuf)/sizeof(widebuf[0]) );
|
|
|
|
|
#endif
|
2004-06-16 06:17:08 +02:00
|
|
|
|
DrawText( hdc, widebuf, -1, &textRect,
|
2003-11-20 17:26:35 +01:00
|
|
|
|
DT_SINGLELINE | DT_VCENTER | DT_CENTER);
|
2005-11-27 23:06:04 +01:00
|
|
|
|
#ifdef TARGET_OS_WIN32
|
|
|
|
|
SelectObject( hdc, oldFont );
|
|
|
|
|
#endif
|
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} else if ( !!bitmap ) {
|
2006-04-03 00:27:44 +02:00
|
|
|
|
makeAndDrawBitmap( dctx, hdc, &rt, XP_TRUE,
|
2004-06-16 06:17:08 +02:00
|
|
|
|
foreColorRef, (CEBitmapInfo*)bitmap );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} else if ( isStar ) {
|
2005-06-13 15:32:06 +02:00
|
|
|
|
ceDrawBitmapInRect( hdc, &textRect, dctx->origin );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
|
|
|
|
|
2004-12-12 18:39:59 +01:00
|
|
|
|
ceDrawHintBorders( hdc, xprect, hintAtts );
|
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
return XP_TRUE;
|
|
|
|
|
} /* ce_draw_drawCell */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(invertCell)( DrawCtx* p_dctx, const XP_Rect* rect )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
} /* ce_draw_invertCell */
|
|
|
|
|
|
2004-02-12 05:36:48 +01:00
|
|
|
|
#ifdef DEBUG
|
2006-05-09 04:01:27 +02:00
|
|
|
|
#if 0
|
2004-02-12 05:36:48 +01:00
|
|
|
|
static char*
|
|
|
|
|
logClipResult( int icrResult )
|
|
|
|
|
{
|
|
|
|
|
#define caseStr(d) case d: return #d
|
|
|
|
|
switch ( icrResult ) {
|
|
|
|
|
caseStr(SIMPLEREGION);
|
|
|
|
|
caseStr(COMPLEXREGION);
|
|
|
|
|
caseStr(NULLREGION);
|
|
|
|
|
caseStr(ERROR);
|
|
|
|
|
}
|
|
|
|
|
#undef caseStr
|
|
|
|
|
return "unknown";
|
|
|
|
|
} /* logClipResult */
|
|
|
|
|
#endif
|
2006-05-09 04:01:27 +02:00
|
|
|
|
#endif
|
2004-02-12 05:36:48 +01:00
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC XP_Bool
|
|
|
|
|
DRAW_FUNC_NAME(trayBegin)( DrawCtx* p_dctx, const XP_Rect* rect, XP_U16 owner,
|
|
|
|
|
XP_Bool hasfocus )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
2004-03-02 04:26:10 +01:00
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
HDC hdc = globals->hdc;
|
|
|
|
|
XP_Bool canDraw = !!hdc;
|
|
|
|
|
if ( canDraw ) {
|
|
|
|
|
dctx->trayOwner = owner;
|
|
|
|
|
}
|
|
|
|
|
return canDraw;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} /* ce_draw_trayBegin */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(trayFinished)( DrawCtx* p_dctx )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
/* ce_draw_boardFinished( p_dctx ); */
|
|
|
|
|
} /* ce_draw_trayFinished */
|
|
|
|
|
|
|
|
|
|
static void
|
2006-02-18 07:39:40 +01:00
|
|
|
|
drawDrawTileGuts( DrawCtx* p_dctx, const XP_Rect* xprect,
|
|
|
|
|
const XP_UCHAR* letters,
|
2005-11-27 21:05:33 +01:00
|
|
|
|
XP_Bitmap bitmap, XP_S16 val, XP_Bool highlighted )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
HDC hdc = globals->hdc;
|
|
|
|
|
wchar_t widebuf[4];
|
|
|
|
|
RECT rt;
|
2006-03-20 05:13:40 +01:00
|
|
|
|
XP_U16 index;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
ceClearToBkground( dctx, xprect );
|
|
|
|
|
|
2004-03-28 03:14:34 +02:00
|
|
|
|
SetBkColor( hdc, dctx->globals->appPrefs.colors[TILEBACK_COLOR] );
|
2006-03-20 05:13:40 +01:00
|
|
|
|
index = getPlayerColor(dctx->trayOwner);
|
|
|
|
|
SetTextColor( hdc, dctx->globals->appPrefs.colors[index] );
|
2004-01-10 19:02:10 +01:00
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
XPRtoRECT( &rt, xprect );
|
|
|
|
|
|
|
|
|
|
InsetRect( &rt, 1, 1 );
|
|
|
|
|
Rectangle(hdc, rt.left, rt.top, rt.right, rt.bottom);
|
|
|
|
|
InsetRect( &rt, 1, 1 );
|
|
|
|
|
|
2004-01-10 19:02:10 +01:00
|
|
|
|
/* 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. */
|
2003-11-20 17:26:35 +01:00
|
|
|
|
if ( highlighted ) {
|
|
|
|
|
Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom );
|
2004-01-10 19:02:10 +01:00
|
|
|
|
InsetRect( &rt, 1, 1 );
|
|
|
|
|
}
|
|
|
|
|
FillRect( hdc, &rt, dctx->brushes[TILEBACK_COLOR] );
|
|
|
|
|
if ( !highlighted ) {
|
|
|
|
|
InsetRect( &rt, 1, 1 );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 ) {
|
2006-04-03 00:27:44 +02:00
|
|
|
|
RECT lrt = rt;
|
|
|
|
|
++lrt.left;
|
|
|
|
|
lrt.top += 4;
|
|
|
|
|
makeAndDrawBitmap( dctx, hdc, &lrt, XP_FALSE,
|
2004-03-28 03:14:34 +02:00
|
|
|
|
dctx->globals->appPrefs.colors[USER_COLOR1+dctx->trayOwner],
|
2003-11-20 17:26:35 +01:00
|
|
|
|
(CEBitmapInfo*)bitmap );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( val >= 0 ) {
|
|
|
|
|
swprintf( widebuf, L"%d", val );
|
|
|
|
|
DrawText(hdc, widebuf, -1, &rt, DT_SINGLELINE | DT_BOTTOM | DT_RIGHT);
|
|
|
|
|
}
|
|
|
|
|
} /* drawDrawTileGuts */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(drawTile)( DrawCtx* p_dctx, const XP_Rect* xprect,
|
|
|
|
|
const XP_UCHAR* letters, XP_Bitmap bitmap,
|
|
|
|
|
XP_S16 val, XP_Bool highlighted )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
drawDrawTileGuts( p_dctx, xprect, letters, bitmap, val, highlighted );
|
|
|
|
|
} /* ce_draw_drawTile */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(drawTileBack)( DrawCtx* p_dctx, const XP_Rect* xprect )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
drawDrawTileGuts( p_dctx, xprect, "?", NULL, -1, XP_FALSE );
|
|
|
|
|
} /* ce_draw_drawTileBack */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(drawTrayDivider)( DrawCtx* p_dctx, const XP_Rect* rect,
|
|
|
|
|
XP_Bool selected )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
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
|
2006-02-18 07:39:40 +01:00
|
|
|
|
ceClearToBkground( CEDrawCtx* dctx, const XP_Rect* rect )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
HDC hdc = globals->hdc;
|
|
|
|
|
RECT rt;
|
|
|
|
|
|
|
|
|
|
XPRtoRECT( &rt, rect );
|
|
|
|
|
|
|
|
|
|
FillRect( hdc, &rt, dctx->brushes[BKG_COLOR] );
|
|
|
|
|
} /* ceClearToBkground */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(clearRect)( DrawCtx* p_dctx, const XP_Rect* rectP )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
ceClearToBkground( (CEDrawCtx*)p_dctx, rectP );
|
|
|
|
|
} /* ce_draw_clearRect */
|
|
|
|
|
|
|
|
|
|
static void
|
2005-06-13 15:32:06 +02:00
|
|
|
|
ceDrawBitmapInRect( HDC hdc, const RECT* rect, HBITMAP bitmap )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
BITMAP bmp;
|
|
|
|
|
HDC tmpDC;
|
|
|
|
|
int nBytes;
|
2005-06-13 15:32:06 +02:00
|
|
|
|
int x = rect->left;
|
|
|
|
|
int y = rect->top;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
tmpDC = CreateCompatibleDC( hdc );
|
|
|
|
|
SelectObject( tmpDC, bitmap );
|
|
|
|
|
|
2005-06-13 15:32:06 +02:00
|
|
|
|
(void)IntersectClipRect( tmpDC, x, y, rect->right, rect->bottom );
|
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
nBytes = GetObject( bitmap, sizeof(bmp), &bmp );
|
|
|
|
|
XP_ASSERT( nBytes > 0 );
|
2004-01-22 04:20:19 +01:00
|
|
|
|
if ( nBytes == 0 ) {
|
2004-01-30 06:45:23 +01:00
|
|
|
|
logLastError( "ceDrawBitmapInRect:GetObject" );
|
2004-01-22 04:20:19 +01:00
|
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2005-06-13 15:32:06 +02:00
|
|
|
|
x += ((rect->right - x) - bmp.bmWidth) / 2;
|
|
|
|
|
y += ((rect->bottom - y) - bmp.bmHeight) / 2;
|
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
BitBlt( hdc, x, y, bmp.bmWidth, bmp.bmHeight,
|
|
|
|
|
tmpDC, 0, 0, SRCCOPY ); /* BLACKNESS */
|
|
|
|
|
|
|
|
|
|
DeleteDC( tmpDC );
|
|
|
|
|
} /* ceDrawBitmapInRect */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(drawBoardArrow)( DrawCtx* p_dctx, const XP_Rect* xprect,
|
|
|
|
|
XWBonusType cursorBonus, XP_Bool vertical,
|
|
|
|
|
HintAtts hintAtts )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
HDC hdc = globals->hdc;
|
|
|
|
|
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 {
|
2004-03-02 04:26:10 +01:00
|
|
|
|
bkIndex = cursorBonus - BONUS_DOUBLE_LETTER + BONUS1_COLOR;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
|
|
|
|
FillRect( hdc, &rt, dctx->brushes[bkIndex] );
|
2004-03-28 03:14:34 +02:00
|
|
|
|
SetBkColor( hdc, dctx->globals->appPrefs.colors[bkIndex] );
|
|
|
|
|
SetTextColor( hdc, dctx->globals->appPrefs.colors[BLACK_COLOR] );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2005-06-13 15:32:06 +02:00
|
|
|
|
ceDrawBitmapInRect( hdc, &rt, cursor );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2004-12-12 18:39:59 +01:00
|
|
|
|
ceDrawHintBorders( hdc, xprect, hintAtts );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} /* ce_draw_drawBoardArrow */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(scoreBegin)( DrawCtx* p_dctx, const XP_Rect* rect,
|
|
|
|
|
XP_U16 numPlayers, XP_Bool hasfocus )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
HDC hdc = globals->hdc;
|
2004-03-28 03:14:34 +02:00
|
|
|
|
SetBkColor( hdc, dctx->globals->appPrefs.colors[BKG_COLOR] );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2006-05-09 04:01:27 +02:00
|
|
|
|
dctx->scoreIsVertical = rect->height > rect->width;
|
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
ceClearToBkground( (CEDrawCtx*)p_dctx, rect );
|
|
|
|
|
} /* ce_draw_scoreBegin */
|
|
|
|
|
|
|
|
|
|
static void
|
2006-05-09 04:01:27 +02:00
|
|
|
|
formatRemText( HDC hdc, XP_S16 nTilesLeft, XP_Bool isVertical, XP_UCHAR* buf )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
if ( nTilesLeft <= 0 ) {
|
|
|
|
|
buf[0] = 0;
|
2006-05-09 04:01:27 +02:00
|
|
|
|
} else {
|
|
|
|
|
char* fmt;
|
|
|
|
|
if ( isVertical ) {
|
|
|
|
|
fmt = "Rem" XP_CR "%d";
|
|
|
|
|
} else {
|
|
|
|
|
fmt = "Rem:%d";
|
|
|
|
|
}
|
|
|
|
|
sprintf( buf, fmt, nTilesLeft );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
|
|
|
|
} /* formatRemText */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(measureRemText)( DrawCtx* p_dctx, const XP_Rect* r,
|
|
|
|
|
XP_S16 nTilesLeft,
|
|
|
|
|
XP_U16* width, XP_U16* height )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
HDC hdc = globals->hdc;
|
2006-05-09 04:01:27 +02:00
|
|
|
|
XP_UCHAR buf[16];
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2006-05-09 04:01:27 +02:00
|
|
|
|
formatRemText( hdc, nTilesLeft, dctx->scoreIsVertical, buf );
|
|
|
|
|
measureText( dctx, buf, width, height );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} /* ce_draw_measureRemText */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(drawRemText)( DrawCtx* p_dctx, const XP_Rect* rInner,
|
|
|
|
|
const XP_Rect* rOuter, XP_S16 nTilesLeft )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
HDC hdc = globals->hdc;
|
2006-05-09 04:01:27 +02:00
|
|
|
|
XP_UCHAR buf[16];
|
2003-11-20 17:26:35 +01:00
|
|
|
|
RECT rt;
|
|
|
|
|
|
2006-05-09 04:01:27 +02:00
|
|
|
|
formatRemText( hdc, nTilesLeft, dctx->scoreIsVertical, buf );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
XPRtoRECT( &rt, rInner );
|
2004-01-10 19:02:10 +01:00
|
|
|
|
++rt.left; /* 1: don't write up against edge */
|
2006-05-09 04:01:27 +02:00
|
|
|
|
drawLines( dctx, hdc, buf, &rt, DT_SINGLELINE | DT_LEFT | DT_VCENTER | DT_CENTER );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} /* ce_draw_drawRemText */
|
|
|
|
|
|
|
|
|
|
static void
|
2006-05-09 04:01:27 +02:00
|
|
|
|
ceWidthAndText( CEDrawCtx* dctx, HDC hdc, const DrawScoreInfo* dsi, XP_Bool isVertical,
|
|
|
|
|
XP_UCHAR* buf, XP_U16* widthP, XP_U16* heightP )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
XP_UCHAR borders[] = {'<EFBFBD>', '\0'};
|
|
|
|
|
XP_UCHAR tilesLeftTxt[8];
|
|
|
|
|
|
|
|
|
|
if ( !dsi->isTurn ) {
|
|
|
|
|
borders[0] = '\0';
|
|
|
|
|
}
|
|
|
|
|
|
2006-05-09 04:01:27 +02:00
|
|
|
|
if ( isVertical ) {
|
|
|
|
|
sprintf( buf, "%d", dsi->score );
|
|
|
|
|
XP_LOGF( "%s: write %s", __FUNCTION__, buf );
|
|
|
|
|
if ( dsi->nTilesLeft >= 0 ) {
|
|
|
|
|
XP_UCHAR smallBuf[32];
|
|
|
|
|
sprintf( smallBuf, XP_CR "%s%d%s", borders, dsi->nTilesLeft, borders );
|
|
|
|
|
strcat( buf, smallBuf );
|
|
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} else {
|
2006-05-09 04:01:27 +02:00
|
|
|
|
if ( dsi->nTilesLeft >= 0 ) {
|
|
|
|
|
sprintf( tilesLeftTxt, ":%d", dsi->nTilesLeft );
|
|
|
|
|
} else {
|
|
|
|
|
tilesLeftTxt[0] = '\0';
|
|
|
|
|
}
|
|
|
|
|
sprintf( buf, "%s%d%s%s", borders, dsi->score, tilesLeftTxt, borders );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
|
|
|
|
|
2006-05-09 04:01:27 +02:00
|
|
|
|
measureText( dctx, buf, widthP, heightP );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} /* ceWidthAndText */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(measureScoreText)( DrawCtx* p_dctx, const XP_Rect* r,
|
|
|
|
|
const DrawScoreInfo* dsi,
|
|
|
|
|
XP_U16* widthP, XP_U16* heightP )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
HDC hdc = globals->hdc;
|
2006-05-09 04:01:27 +02:00
|
|
|
|
XP_UCHAR buf[16];
|
2003-11-20 17:26:35 +01:00
|
|
|
|
HFONT newFont;
|
|
|
|
|
HFONT oldFont;
|
|
|
|
|
|
|
|
|
|
if ( dsi->selected ) {
|
|
|
|
|
newFont = dctx->selPlayerFont;
|
|
|
|
|
} else {
|
|
|
|
|
newFont = dctx->playerFont;
|
|
|
|
|
}
|
|
|
|
|
oldFont = SelectObject( hdc, newFont );
|
|
|
|
|
|
2006-05-09 04:01:27 +02:00
|
|
|
|
ceWidthAndText( dctx, hdc, dsi, dctx->scoreIsVertical,
|
|
|
|
|
buf, widthP, heightP );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
SelectObject( hdc, oldFont );
|
|
|
|
|
} /* ce_draw_measureScoreText */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(score_drawPlayer)( DrawCtx* p_dctx,
|
|
|
|
|
const XP_Rect* rInner, const XP_Rect* rOuter,
|
|
|
|
|
const DrawScoreInfo* dsi )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
HDC hdc = globals->hdc;
|
|
|
|
|
RECT rt;
|
|
|
|
|
XP_U16 width, height;
|
2006-05-09 04:01:27 +02:00
|
|
|
|
XP_UCHAR scoreBuf[20];
|
2003-11-20 17:26:35 +01:00
|
|
|
|
HFONT newFont;
|
|
|
|
|
HFONT oldFont;
|
|
|
|
|
|
|
|
|
|
XPRtoRECT( &rt, rInner );
|
|
|
|
|
if ( dsi->selected ) {
|
|
|
|
|
newFont = dctx->selPlayerFont;
|
|
|
|
|
} else {
|
|
|
|
|
newFont = dctx->playerFont;
|
|
|
|
|
}
|
|
|
|
|
oldFont = SelectObject( hdc, newFont );
|
|
|
|
|
|
2005-06-09 16:18:55 +02:00
|
|
|
|
SetTextColor( hdc, dctx->globals->
|
|
|
|
|
appPrefs.colors[getPlayerColor(dsi->playerNum)] );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2006-05-09 04:01:27 +02:00
|
|
|
|
ceWidthAndText( dctx, hdc, dsi, dctx->scoreIsVertical,
|
|
|
|
|
scoreBuf, &width, &height );
|
|
|
|
|
|
|
|
|
|
drawLines( dctx, hdc, scoreBuf, &rt, DT_SINGLELINE | DT_VCENTER | DT_CENTER );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
SelectObject( hdc, oldFont );
|
|
|
|
|
} /* ce_draw_score_drawPlayer */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(score_pendingScore)( DrawCtx* p_dctx, const XP_Rect* rect,
|
|
|
|
|
XP_S16 score, XP_U16 playerNum )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
HDC hdc = globals->hdc;
|
|
|
|
|
|
|
|
|
|
wchar_t widebuf[5];
|
|
|
|
|
XP_UCHAR buf[5];
|
|
|
|
|
RECT rt;
|
|
|
|
|
|
2004-03-28 03:14:34 +02:00
|
|
|
|
SetTextColor( hdc, dctx->globals->appPrefs.colors[BLACK_COLOR] );
|
|
|
|
|
SetBkColor( hdc, dctx->globals->appPrefs.colors[BKG_COLOR] );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
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 */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(scoreFinished)( DrawCtx* p_dctx )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
/* ce_draw_boardFinished( p_dctx ); */
|
|
|
|
|
} /* ce_draw_scoreFinished */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(drawTimer)( DrawCtx* p_dctx,
|
|
|
|
|
const XP_Rect* rInner, const XP_Rect* rOuter,
|
|
|
|
|
XP_U16 player, XP_S16 secondsLeft )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
HDC hdc = globals->hdc;
|
2006-05-09 04:01:27 +02:00
|
|
|
|
XP_UCHAR buf[16];
|
2003-11-20 17:26:35 +01:00
|
|
|
|
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;
|
|
|
|
|
|
2006-05-09 04:01:27 +02:00
|
|
|
|
snprintf( buf, sizeof(buf),
|
|
|
|
|
dctx->scoreIsVertical? "%s%.1dm" XP_CR "%.2ds" : "%s%.1d:%.2d",
|
|
|
|
|
isNegative? "-": "", mins, secs );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
if ( !globals->hdc ) {
|
|
|
|
|
InvalidateRect( dctx->mainWin, &rt, FALSE );
|
|
|
|
|
hdc = BeginPaint( dctx->mainWin, &ps );
|
|
|
|
|
}
|
|
|
|
|
|
2004-03-28 03:14:34 +02:00
|
|
|
|
SetTextColor( hdc, dctx->globals->appPrefs.colors[getPlayerColor(player)] );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
ceClearToBkground( dctx, rInner );
|
2006-05-09 04:01:27 +02:00
|
|
|
|
drawLines( dctx, hdc, buf, &rt, DT_SINGLELINE | DT_VCENTER | DT_CENTER);
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
if ( !globals->hdc ) {
|
|
|
|
|
EndPaint( dctx->mainWin, &ps );
|
|
|
|
|
}
|
|
|
|
|
} /* ce_draw_drawTimer */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC XP_UCHAR*
|
|
|
|
|
DRAW_FUNC_NAME(getMiniWText)( DrawCtx* p_dctx, XWMiniTextType whichText )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
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:
|
2004-05-01 16:29:44 +02:00
|
|
|
|
str = "Trading tiles;" XP_CR "select 'Turn done' when ready"; break;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
default:
|
|
|
|
|
XP_ASSERT( XP_FALSE );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return str;
|
|
|
|
|
} /* ce_draw_getMiniWText */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(measureMiniWText)( DrawCtx* p_dctx, const XP_UCHAR* str,
|
|
|
|
|
XP_U16* widthP, XP_U16* heightP )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
2006-05-09 04:01:27 +02:00
|
|
|
|
measureText( dctx, str, widthP, heightP );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} /* ce_draw_measureMiniWText */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(drawMiniWindow)( DrawCtx* p_dctx, const XP_UCHAR* text,
|
|
|
|
|
const XP_Rect* rect, void** closureP )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
2004-02-12 05:36:48 +01:00
|
|
|
|
HDC hdc;
|
2004-02-28 06:25:21 +01:00
|
|
|
|
RECT rt, textRt;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
PAINTSTRUCT ps;
|
|
|
|
|
|
|
|
|
|
XPRtoRECT( &rt, rect );
|
|
|
|
|
|
2004-02-13 14:47:37 +01:00
|
|
|
|
if ( !!globals->hdc ) {
|
2004-02-12 05:36:48 +01:00
|
|
|
|
hdc = globals->hdc;
|
|
|
|
|
} else {
|
2003-11-20 17:26:35 +01:00
|
|
|
|
InvalidateRect( dctx->mainWin, &rt, FALSE );
|
|
|
|
|
hdc = BeginPaint( dctx->mainWin, &ps );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ceClearToBkground( (CEDrawCtx*)p_dctx, rect );
|
|
|
|
|
|
2004-03-28 03:14:34 +02:00
|
|
|
|
SetBkColor( hdc, dctx->globals->appPrefs.colors[BKG_COLOR] );
|
|
|
|
|
SetTextColor( hdc, dctx->globals->appPrefs.colors[BLACK_COLOR] );
|
2004-02-28 06:25:21 +01:00
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom );
|
|
|
|
|
InsetRect( &rt, 1, 1 );
|
|
|
|
|
Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom );
|
|
|
|
|
|
2004-02-28 06:25:21 +01:00
|
|
|
|
textRt = rt;
|
|
|
|
|
textRt.top += 2;
|
|
|
|
|
InsetRect( &textRt, 3, 0 );
|
|
|
|
|
|
2006-05-09 04:01:27 +02:00
|
|
|
|
drawLines( dctx, hdc, text, &textRt, DT_CENTER | DT_VCENTER );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
if ( !globals->hdc ) {
|
|
|
|
|
EndPaint( dctx->mainWin, &ps );
|
|
|
|
|
}
|
|
|
|
|
} /* ce_draw_drawMiniWindow */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(eraseMiniWindow)( DrawCtx* p_dctx, const XP_Rect* rect,
|
|
|
|
|
XP_Bool lastTime,
|
|
|
|
|
void** closure, XP_Bool* invalUnder )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
*invalUnder = XP_TRUE;
|
|
|
|
|
} /* ce_draw_eraseMiniWindow */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(destroyCtxt)( DrawCtx* p_dctx )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
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 */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
#ifdef DRAW_LINK_DIRECT
|
|
|
|
|
DLSTATIC XP_Bool
|
|
|
|
|
DRAW_FUNC_NAME(vertScrollBoard)( DrawCtx* dctx, XP_Rect* rect,
|
|
|
|
|
XP_S16 dist )
|
|
|
|
|
{
|
|
|
|
|
XP_ASSERT(0);
|
|
|
|
|
return XP_FALSE;
|
|
|
|
|
}
|
|
|
|
|
#else
|
2003-11-20 17:26:35 +01:00
|
|
|
|
static void
|
2006-04-01 23:01:20 +02:00
|
|
|
|
ce_draw_doNothing( DrawCtx* dctx, ... )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
2006-04-01 23:01:20 +02:00
|
|
|
|
} /* ce_draw_doNothing */
|
|
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
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 */
|
|
|
|
|
|
2004-03-28 03:14:34 +02:00
|
|
|
|
void
|
|
|
|
|
ce_drawctxt_update( DrawCtx* p_dctx, CEAppGlobals* globals )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
2004-03-28 03:14:34 +02:00
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
XP_U16 i;
|
2004-03-28 03:14:34 +02:00
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
for ( i = 0; i < NUM_COLORS; ++i ) {
|
2004-03-28 03:14:34 +02:00
|
|
|
|
if ( !!dctx->brushes[i] ) {
|
|
|
|
|
DeleteObject( dctx->brushes[i] );
|
|
|
|
|
}
|
|
|
|
|
dctx->brushes[i] = CreateSolidBrush( dctx->globals->appPrefs.colors[i] );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
2004-03-28 03:14:34 +02:00
|
|
|
|
} /* ce_drawctxt_update */
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
DrawCtx*
|
|
|
|
|
ce_drawctxt_make( MPFORMAL HWND mainWin, CEAppGlobals* globals )
|
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)XP_MALLOC( mpool,
|
|
|
|
|
sizeof(*dctx) );
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
#ifndef DRAW_LINK_DIRECT
|
2003-11-20 17:26:35 +01:00
|
|
|
|
dctx->vtable = (DrawCtxVTable*)XP_MALLOC( mpool, sizeof(*((dctx)->vtable)));
|
|
|
|
|
|
|
|
|
|
for ( i = 0; i < sizeof(*dctx->vtable)/4; ++i ) {
|
2006-04-01 23:01:20 +02:00
|
|
|
|
((void**)(dctx->vtable))[i] = ce_draw_doNothing;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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 );
|
2006-04-01 23:01:20 +02:00
|
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
dctx->mainWin = mainWin;
|
|
|
|
|
dctx->globals = globals;
|
|
|
|
|
|
2004-04-03 18:39:54 +02:00
|
|
|
|
ce_drawctxt_update( (DrawCtx*)dctx, globals );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
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 */
|