2008-08-02 16:35:40 +02:00
|
|
|
|
/* -*- fill-column: 77; compile-command: "make TARGET_OS=wince DEBUG=TRUE"; -*- */
|
2003-11-20 17:26:35 +01:00
|
|
|
|
/*
|
2008-05-25 17:08:59 +02:00
|
|
|
|
* Copyright 2000-2008 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"
|
2008-09-01 17:10:28 +02:00
|
|
|
|
#include "cedraw.h"
|
2003-11-20 17:26:35 +01:00
|
|
|
|
#include "board.h"
|
|
|
|
|
#include "draw.h"
|
|
|
|
|
#include "mempool.h"
|
|
|
|
|
|
|
|
|
|
#include "cemain.h"
|
|
|
|
|
#include "cedict.h"
|
|
|
|
|
#include "cedefines.h"
|
2008-09-17 06:19:20 +02:00
|
|
|
|
#include "cedebug.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
|
|
|
|
|
|
2008-09-13 17:24:23 +02:00
|
|
|
|
#define FCE_TEXT_PADDING 2
|
2006-05-09 04:01:27 +02:00
|
|
|
|
#define CE_MINI_V_PADDING 6
|
2008-09-13 17:24:23 +02:00
|
|
|
|
#define CE_MINI_H_PADDING 8
|
2006-05-12 09:58:31 +02:00
|
|
|
|
#define CE_MINIW_PADDING 0
|
|
|
|
|
#define CE_TIMER_PADDING -2
|
2006-05-20 08:21:53 +02:00
|
|
|
|
#define IS_TURN_VPAD 2
|
2006-05-09 04:01:27 +02:00
|
|
|
|
|
2008-07-20 18:33:19 +02:00
|
|
|
|
#define DRAW_FOCUS_FRAME 1
|
|
|
|
|
#ifdef DRAW_FOCUS_FRAME
|
|
|
|
|
# define CE_FOCUS_BORDER_WIDTH 6
|
|
|
|
|
# define TREAT_AS_CURSOR(d,f) ((((f) & CELL_ISCURSOR) != 0) && !(d)->topFocus )
|
|
|
|
|
#else
|
|
|
|
|
# define TREAT_AS_CURSOR(d,f) (((f) & CELL_ISCURSOR) != 0)
|
|
|
|
|
#endif
|
|
|
|
|
|
2008-09-09 14:31:02 +02:00
|
|
|
|
|
|
|
|
|
typedef enum {
|
|
|
|
|
RFONTS_TRAY
|
|
|
|
|
,RFONTS_TRAYVAL
|
|
|
|
|
,RFONTS_CELL
|
2008-09-13 17:24:23 +02:00
|
|
|
|
,RFONTS_REM
|
|
|
|
|
,RFONTS_SCORE
|
|
|
|
|
,RFONTS_SCORE_BOLD
|
2008-09-09 14:31:02 +02:00
|
|
|
|
|
|
|
|
|
,N_RESIZE_FONTS
|
|
|
|
|
} RFIndex;
|
|
|
|
|
|
|
|
|
|
typedef struct _PenColorPair {
|
|
|
|
|
COLORREF ref;
|
|
|
|
|
HGDIOBJ pen;
|
|
|
|
|
} PenColorPair;
|
|
|
|
|
|
|
|
|
|
typedef struct _FontCacheEntry {
|
|
|
|
|
HFONT setFont;
|
2008-09-13 17:24:23 +02:00
|
|
|
|
/* NOTE: indexHt >= glyphHt. fontHt will usually be > indexHt */
|
|
|
|
|
XP_U16 indexHt; /* the size we match on, the space we have */
|
|
|
|
|
XP_U16 lfHeight; /* What CE thinks is the "size" of the font we
|
|
|
|
|
found to best fill indexHt */
|
|
|
|
|
XP_U16 glyphHt; /* range from tops to bottoms of glyphs we use */
|
2008-09-09 14:31:02 +02:00
|
|
|
|
XP_U16 offset;
|
|
|
|
|
} FontCacheEntry;
|
|
|
|
|
|
2008-09-01 17:10:28 +02:00
|
|
|
|
struct CEDrawCtx {
|
|
|
|
|
DrawCtxVTable* vtable;
|
|
|
|
|
|
|
|
|
|
HWND mainWin;
|
|
|
|
|
CEAppGlobals* globals;
|
2008-09-05 14:11:37 +02:00
|
|
|
|
const DictionaryCtxt* dict;
|
2008-07-20 18:33:19 +02:00
|
|
|
|
|
2008-09-01 17:10:28 +02:00
|
|
|
|
COLORREF prevBkColor;
|
|
|
|
|
|
|
|
|
|
HBRUSH brushes[CE_NUM_COLORS];
|
|
|
|
|
PenColorPair pens[CE_NUM_COLORS];
|
|
|
|
|
|
|
|
|
|
FontCacheEntry fcEntry[N_RESIZE_FONTS];
|
|
|
|
|
|
|
|
|
|
HBITMAP rightArrow;
|
|
|
|
|
HBITMAP downArrow;
|
|
|
|
|
HBITMAP origin;
|
|
|
|
|
|
|
|
|
|
XP_U16 trayOwner;
|
|
|
|
|
XP_U16 miniLineHt;
|
|
|
|
|
XP_Bool scoreIsVertical;
|
|
|
|
|
XP_Bool topFocus;
|
|
|
|
|
|
|
|
|
|
MPSLOT
|
|
|
|
|
};
|
2008-07-20 18:33:19 +02:00
|
|
|
|
|
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 );
|
2008-08-30 20:55:20 +02:00
|
|
|
|
static void ceClipToRect( HDC hdc, const RECT* rt );
|
2008-09-09 14:31:02 +02:00
|
|
|
|
static void ceClearFontCache( CEDrawCtx* dctx );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2008-10-11 18:53:22 +02:00
|
|
|
|
#ifdef DEBUG
|
|
|
|
|
const char*
|
|
|
|
|
RFI2Str( RFIndex rfi )
|
|
|
|
|
{
|
|
|
|
|
const char* str;
|
|
|
|
|
# define CASE_STR(c) case c: str = #c; break
|
|
|
|
|
switch( rfi ) {
|
|
|
|
|
CASE_STR( RFONTS_TRAY );
|
|
|
|
|
CASE_STR( RFONTS_TRAYVAL );
|
|
|
|
|
CASE_STR( RFONTS_CELL );
|
|
|
|
|
CASE_STR( RFONTS_REM );
|
|
|
|
|
CASE_STR( RFONTS_SCORE );
|
|
|
|
|
CASE_STR( RFONTS_SCORE_BOLD );
|
|
|
|
|
default:
|
|
|
|
|
str = "<unknown>";
|
|
|
|
|
}
|
|
|
|
|
# undef CASE_STR
|
|
|
|
|
return str;
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
# define RFI2Str( rfi ) ""
|
|
|
|
|
#endif
|
|
|
|
|
|
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 */
|
|
|
|
|
|
2008-07-20 18:33:19 +02:00
|
|
|
|
static HGDIOBJ
|
|
|
|
|
ceGetPen( CEDrawCtx* dctx, XP_U16 colorIndx, XP_U16 width )
|
|
|
|
|
{
|
2008-08-02 16:35:40 +02:00
|
|
|
|
PenColorPair* pair = &dctx->pens[colorIndx];
|
|
|
|
|
HGDIOBJ pen = pair->pen;
|
|
|
|
|
COLORREF ref = dctx->globals->appPrefs.colors[colorIndx];
|
|
|
|
|
|
|
|
|
|
/* Make sure cached value is still good */
|
|
|
|
|
if ( !!pen && (ref != pair->ref) ) {
|
|
|
|
|
DeleteObject( pen );
|
|
|
|
|
pen = NULL;
|
|
|
|
|
}
|
|
|
|
|
|
2008-07-20 18:33:19 +02:00
|
|
|
|
if ( !pen ) {
|
|
|
|
|
pen = CreatePen( PS_SOLID, width, ref );
|
2008-08-02 16:35:40 +02:00
|
|
|
|
pair->pen = pen;
|
|
|
|
|
pair->ref = ref;
|
2008-07-20 18:33:19 +02:00
|
|
|
|
}
|
|
|
|
|
return pen;
|
|
|
|
|
}
|
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
static void
|
2008-07-20 18:33:19 +02:00
|
|
|
|
makeAndDrawBitmap( CEDrawCtx* dctx, HDC hdc, const RECT* bnds, XP_Bool center,
|
|
|
|
|
XP_U16 colorIndx, CEBitmapInfo* info )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
#if 1
|
2008-07-20 18:33:19 +02:00
|
|
|
|
HGDIOBJ forePen = ceGetPen( dctx, colorIndx, 1 );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
POINT points[2];
|
|
|
|
|
XP_U16 nCols, nRows, row, col, rowBytes;
|
2006-04-03 00:27:44 +02:00
|
|
|
|
XP_S32 x, y;
|
2008-02-16 18:19:31 +01:00
|
|
|
|
XP_U8* bits = info->bits;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
HGDIOBJ oldObj;
|
|
|
|
|
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 ) {
|
2008-02-16 18:19:31 +01:00
|
|
|
|
XP_U8 byt = bits[col / 8];
|
2003-11-20 17:26:35 +01:00
|
|
|
|
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 );
|
|
|
|
|
#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 */
|
|
|
|
|
|
2008-08-30 20:55:20 +02:00
|
|
|
|
static void
|
|
|
|
|
ceDrawTextClipped( HDC hdc, wchar_t* buf, XP_S16 len, XP_Bool clip,
|
2008-09-10 13:57:30 +02:00
|
|
|
|
const FontCacheEntry* fce, XP_U16 left, XP_U16 top,
|
|
|
|
|
XP_U16 width, XP_U16 hJust )
|
2008-08-30 20:55:20 +02:00
|
|
|
|
{
|
2008-09-18 05:50:04 +02:00
|
|
|
|
RECT rect = {
|
|
|
|
|
.left = left,
|
|
|
|
|
.top = top,
|
|
|
|
|
.bottom = top + fce->glyphHt,
|
|
|
|
|
.right = left + width
|
|
|
|
|
};
|
2008-08-30 20:55:20 +02:00
|
|
|
|
|
|
|
|
|
if ( clip ) {
|
|
|
|
|
ceClipToRect( hdc, &rect );
|
|
|
|
|
}
|
2008-09-10 13:57:30 +02:00
|
|
|
|
rect.top -= fce->offset;
|
2008-08-30 20:55:20 +02:00
|
|
|
|
/* XP_LOGF( "%s: drawing left: %ld, top: %ld, right: %ld, bottom: %ld", */
|
|
|
|
|
/* __func__, rect.left, rect.top, rect.right, rect.bottom ); */
|
|
|
|
|
DrawText( hdc, buf, len, &rect, DT_SINGLELINE | DT_TOP | hJust );
|
|
|
|
|
} /* ceDrawTextClipped */
|
|
|
|
|
|
2008-09-13 17:24:23 +02:00
|
|
|
|
static void
|
|
|
|
|
ceDrawLinesClipped( HDC hdc, const FontCacheEntry* fce, XP_UCHAR* buf,
|
|
|
|
|
XP_Bool clip, const RECT* bounds )
|
|
|
|
|
{
|
|
|
|
|
XP_U16 top = bounds->top;
|
|
|
|
|
XP_U16 width = bounds->right - bounds->left;
|
|
|
|
|
|
|
|
|
|
for ( ; ; ) {
|
|
|
|
|
XP_UCHAR* newline = strstr( buf, XP_CR );
|
|
|
|
|
XP_U16 len = newline==NULL? strlen(buf): newline - buf;
|
|
|
|
|
wchar_t widebuf[len];
|
|
|
|
|
|
|
|
|
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, buf, len,
|
|
|
|
|
widebuf, len );
|
|
|
|
|
|
|
|
|
|
ceDrawTextClipped( hdc, widebuf, len, clip, fce, bounds->left, top,
|
|
|
|
|
width, DT_CENTER );
|
|
|
|
|
if ( !newline ) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
top += fce->glyphHt + FCE_TEXT_PADDING;
|
|
|
|
|
buf = newline + XP_STRLEN(XP_CR); /* skip '\n' */
|
|
|
|
|
}
|
|
|
|
|
} /* ceDrawLinesClipped */
|
|
|
|
|
|
2008-07-20 18:33:19 +02:00
|
|
|
|
/* CE doesn't have FrameRect, so we'll roll our own */
|
|
|
|
|
static int
|
|
|
|
|
ceDrawFocusRect( HDC hdc, CEDrawCtx* dctx, LPCRECT rect )
|
|
|
|
|
{
|
|
|
|
|
RECT lr = *rect;
|
|
|
|
|
HGDIOBJ oldObj;
|
|
|
|
|
HGDIOBJ pen = ceGetPen( dctx, CE_FOCUS_COLOR, CE_FOCUS_BORDER_WIDTH );
|
|
|
|
|
|
|
|
|
|
InsetRect( &lr, CE_FOCUS_BORDER_WIDTH/2, CE_FOCUS_BORDER_WIDTH/2 );
|
|
|
|
|
|
|
|
|
|
oldObj = SelectObject( hdc, pen );
|
|
|
|
|
|
|
|
|
|
MoveToEx( hdc, lr.left, lr.top, NULL );
|
|
|
|
|
LineTo( hdc, lr.right, lr.top );
|
|
|
|
|
LineTo( hdc, lr.right, lr.bottom );
|
|
|
|
|
LineTo( hdc, lr.left, lr.bottom );
|
|
|
|
|
LineTo( hdc, lr.left, lr.top );
|
|
|
|
|
|
|
|
|
|
SelectObject( hdc, oldObj );
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
2008-03-16 00:06:06 +01:00
|
|
|
|
static void
|
2008-04-12 21:29:20 +02:00
|
|
|
|
ceClipToRect( /* CEDrawCtx* dctx, */HDC hdc, const RECT* rt )
|
2008-03-16 00:06:06 +01:00
|
|
|
|
{
|
|
|
|
|
/*
|
|
|
|
|
NULLREGION Region is empty.
|
|
|
|
|
SIMPLEREGION Region is a single rectangle.
|
|
|
|
|
COMPLEXREGION Region is more than one rectangle.
|
|
|
|
|
ERROR
|
|
|
|
|
*/
|
|
|
|
|
#if 0
|
|
|
|
|
/* Docs suggest I should be able to reuse the region but it doesn't
|
|
|
|
|
work. At least under WINE... */
|
|
|
|
|
HRGN clipRgn = dctx->clipRgn;
|
|
|
|
|
int ret;
|
|
|
|
|
if ( !clipRgn ) {
|
|
|
|
|
clipRgn = CreateRectRgn( rt->left, rt->top, rt->right, rt->bottom );
|
|
|
|
|
dctx->clipRgn = clipRgn;
|
|
|
|
|
} else {
|
|
|
|
|
(void)SetRectRgn( clipRgn, rt->left, rt->top, rt->right, rt->bottom );
|
|
|
|
|
}
|
|
|
|
|
(void)SelectClipRgn( hdc, clipRgn ); /* returns SIMPLEREGION */
|
|
|
|
|
#else
|
|
|
|
|
HRGN clipRgn = CreateRectRgn( rt->left, rt->top, rt->right, rt->bottom );
|
|
|
|
|
SelectClipRgn( hdc, clipRgn );
|
|
|
|
|
DeleteObject( clipRgn );
|
|
|
|
|
#endif
|
|
|
|
|
} /* ceClipToRect */
|
|
|
|
|
|
2008-09-09 14:31:02 +02:00
|
|
|
|
static void
|
2008-09-28 19:50:04 +02:00
|
|
|
|
makeTestBuf( CEDrawCtx* dctx, XP_UCHAR* buf, XP_U16 bufLen, RFIndex index )
|
2008-09-09 14:31:02 +02:00
|
|
|
|
{
|
|
|
|
|
switch( index ) {
|
|
|
|
|
case RFONTS_TRAY:
|
|
|
|
|
case RFONTS_CELL: {
|
|
|
|
|
Tile tile;
|
|
|
|
|
Tile blank = (Tile)-1;
|
|
|
|
|
const DictionaryCtxt* dict = dctx->dict;
|
|
|
|
|
XP_U16 nFaces = dict_numTileFaces( dict );
|
|
|
|
|
Tile tiles[nFaces];
|
|
|
|
|
XP_U16 nOut = 0;
|
2008-09-28 18:47:11 +02:00
|
|
|
|
XP_ASSERT( !!dict );
|
|
|
|
|
XP_ASSERT( nFaces < bufLen );
|
2008-09-09 14:31:02 +02:00
|
|
|
|
if ( dict_hasBlankTile(dict) ) {
|
|
|
|
|
blank = dict_getBlankTile( dict );
|
|
|
|
|
}
|
|
|
|
|
for ( tile = 0; tile < nFaces; ++tile ) {
|
|
|
|
|
if ( tile != blank ) {
|
|
|
|
|
tiles[nOut++] = tile;
|
|
|
|
|
}
|
|
|
|
|
}
|
2008-09-13 17:24:23 +02:00
|
|
|
|
buf[0] = '0'; /* so can use for numbers too */
|
|
|
|
|
(void)dict_tilesToString( dict, tiles, nOut, &buf[1], bufLen-1 );
|
2008-09-09 14:31:02 +02:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case RFONTS_TRAYVAL:
|
2008-09-13 17:24:23 +02:00
|
|
|
|
strcpy( buf, "Pts0" ); /* all numbers the same :-) */
|
|
|
|
|
break;
|
|
|
|
|
case RFONTS_REM:
|
|
|
|
|
strcpy( buf, "Rem0" );
|
2008-09-09 14:31:02 +02:00
|
|
|
|
break;
|
2008-09-13 17:24:23 +02:00
|
|
|
|
case RFONTS_SCORE:
|
|
|
|
|
case RFONTS_SCORE_BOLD:
|
|
|
|
|
strcpy( buf, "0:" );
|
2008-09-09 14:31:02 +02:00
|
|
|
|
break;
|
|
|
|
|
case N_RESIZE_FONTS:
|
|
|
|
|
XP_ASSERT(0);
|
|
|
|
|
}
|
|
|
|
|
XP_LOGF( "%s=>%s", __func__, buf );
|
|
|
|
|
} /* makeTestBuf */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
ceMeasureGlyph( HDC hdc, HBRUSH white, wchar_t glyph,
|
|
|
|
|
XP_U16 minTopSeen, XP_U16 maxBottomSeen,
|
|
|
|
|
XP_U16* top, XP_U16* bottom )
|
|
|
|
|
{
|
|
|
|
|
SIZE size;
|
|
|
|
|
XP_U16 xx, yy;
|
|
|
|
|
XP_Bool done;
|
|
|
|
|
|
|
|
|
|
GetTextExtentPoint32( hdc, &glyph, 1, &size );
|
|
|
|
|
RECT rect = { 0, 0, size.cx, size.cy };
|
|
|
|
|
FillRect( hdc, &rect, white );
|
|
|
|
|
DrawText( hdc, &glyph, 1, &rect, DT_TOP | DT_LEFT );
|
|
|
|
|
|
|
|
|
|
/* char tbuf[size.cx+1]; */
|
|
|
|
|
/* for ( yy = 0; yy < size.cy; ++yy ) { */
|
|
|
|
|
/* XP_MEMSET( tbuf, 0, size.cx+1 ); */
|
|
|
|
|
/* for ( xx = 0; xx < size.cx; ++xx ) { */
|
|
|
|
|
/* COLORREF ref = GetPixel( hdc, xx, yy ); */
|
|
|
|
|
/* XP_ASSERT( ref != CLR_INVALID ); */
|
|
|
|
|
/* strcat( tbuf, ref==0? " " : "x" ); */
|
|
|
|
|
/* } */
|
|
|
|
|
/* XP_LOGF( "line[%.2d] = %s", yy, tbuf ); */
|
|
|
|
|
/* } */
|
|
|
|
|
|
|
|
|
|
/* Find out if this guy's taller than what we have */
|
|
|
|
|
for ( done = XP_FALSE, yy = 0; yy < minTopSeen && !done; ++yy ) {
|
|
|
|
|
for ( xx = 0; xx < size.cx; ++xx ) {
|
|
|
|
|
COLORREF ref = GetPixel( hdc, xx, yy );
|
|
|
|
|
if ( ref == CLR_INVALID ) {
|
|
|
|
|
break; /* done this line */
|
|
|
|
|
} else if ( ref == 0 ) { /* a pixel set! */
|
|
|
|
|
*top = yy;
|
|
|
|
|
done = XP_TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Extends lower than seen */
|
2008-09-13 17:24:23 +02:00
|
|
|
|
for ( done = XP_FALSE, yy = size.cy - 1; yy > maxBottomSeen && !done;
|
|
|
|
|
--yy ) {
|
2008-09-09 14:31:02 +02:00
|
|
|
|
for ( xx = 0; xx < size.cx; ++xx ) {
|
|
|
|
|
COLORREF ref = GetPixel( hdc, xx, yy );
|
|
|
|
|
if ( ref == CLR_INVALID ) {
|
|
|
|
|
break;
|
|
|
|
|
} else if ( ref == 0 ) { /* a pixel set! */
|
|
|
|
|
*bottom = yy;
|
|
|
|
|
done = XP_TRUE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* XP_LOGF( "%s: top: %d; bottom: %d", __func__, *top, *bottom ); */
|
|
|
|
|
} /* ceMeasureGlyph */
|
|
|
|
|
|
|
|
|
|
static void
|
2008-09-18 05:50:04 +02:00
|
|
|
|
ceMeasureGlyphs( CEDrawCtx* dctx, HDC hdc, wchar_t* str,
|
2008-09-09 14:31:02 +02:00
|
|
|
|
XP_U16* hasMinTop, XP_U16* hasMaxBottom )
|
|
|
|
|
{
|
|
|
|
|
HBRUSH white = dctx->brushes[CE_WHITE_COLOR];
|
|
|
|
|
XP_U16 ii;
|
|
|
|
|
XP_U16 len = wcslen(str);
|
|
|
|
|
XP_U16 minTopSeen, maxBottomSeen;
|
|
|
|
|
XP_U16 maxBottomIndex = 0;
|
|
|
|
|
XP_U16 minTopIndex = 0;
|
|
|
|
|
|
|
|
|
|
minTopSeen = 1000; /* really large... */
|
|
|
|
|
maxBottomSeen = 0;
|
|
|
|
|
for ( ii = 0; ii < len; ++ii ) {
|
|
|
|
|
XP_U16 thisTop, thisBottom;
|
|
|
|
|
|
2008-09-18 05:50:04 +02:00
|
|
|
|
/* TODO: Find a way to to keep minTopIndex && maxBottomIndex the same
|
|
|
|
|
IFF there's a character, like Q, that has the lowest point but
|
|
|
|
|
as high a top as anybody else. Maybe for > until both are set,
|
|
|
|
|
then >= ? */
|
|
|
|
|
|
2008-09-09 14:31:02 +02:00
|
|
|
|
ceMeasureGlyph( hdc, white, str[ii],
|
|
|
|
|
minTopSeen, maxBottomSeen,
|
|
|
|
|
&thisTop, &thisBottom );
|
|
|
|
|
if ( thisBottom > maxBottomSeen ) {
|
|
|
|
|
maxBottomSeen = thisBottom;
|
|
|
|
|
maxBottomIndex = ii;
|
|
|
|
|
}
|
|
|
|
|
if ( thisTop < minTopSeen ) {
|
|
|
|
|
minTopSeen = thisTop;
|
|
|
|
|
minTopIndex = ii;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
*hasMinTop = minTopIndex;
|
|
|
|
|
*hasMaxBottom = maxBottomIndex;
|
|
|
|
|
} /* ceMeasureGlyphs */
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
ceClearFontCache( CEDrawCtx* dctx )
|
|
|
|
|
{
|
|
|
|
|
XP_U16 ii;
|
|
|
|
|
for ( ii = 0; ii < N_RESIZE_FONTS; ++ii ) {
|
|
|
|
|
if ( !!dctx->fcEntry[ii].setFont ) {
|
|
|
|
|
DeleteObject( dctx->fcEntry[ii].setFont );
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
XP_MEMSET( &dctx->fcEntry, 0, sizeof(dctx->fcEntry) );
|
|
|
|
|
}
|
|
|
|
|
|
2008-08-30 20:55:20 +02:00
|
|
|
|
static void
|
2008-09-28 19:50:04 +02:00
|
|
|
|
ceFillFontInfo( const CEDrawCtx* dctx, LOGFONT* fontInfo,
|
|
|
|
|
XP_U16 height/* , XP_Bool bold */ )
|
2008-08-30 20:55:20 +02:00
|
|
|
|
{
|
2008-09-13 17:24:23 +02:00
|
|
|
|
XP_MEMSET( fontInfo, 0, sizeof(*fontInfo) );
|
|
|
|
|
fontInfo->lfHeight = height;
|
2008-08-30 20:55:20 +02:00
|
|
|
|
|
2008-09-13 17:24:23 +02:00
|
|
|
|
/* if ( bold ) { */
|
|
|
|
|
/* fontInfo->lfWeight = FW_BOLD; */
|
|
|
|
|
/* } else { */
|
|
|
|
|
/* fontInfo->lfWeight = FW_LIGHT; */
|
2008-08-30 20:55:20 +02:00
|
|
|
|
/* } */
|
2008-10-11 18:53:22 +02:00
|
|
|
|
wcscpy( fontInfo->lfFaceName,
|
|
|
|
|
#ifdef FORCE_FONT
|
|
|
|
|
FORCE_FONT
|
|
|
|
|
#else
|
|
|
|
|
IS_SMARTPHONE(dctx->globals)? L"Segoe Condensed" : L"Tahoma"
|
|
|
|
|
#endif
|
|
|
|
|
);
|
2008-09-13 17:24:23 +02:00
|
|
|
|
}
|
2008-08-30 20:55:20 +02:00
|
|
|
|
|
|
|
|
|
static void
|
2008-09-09 14:31:02 +02:00
|
|
|
|
ceBestFitFont( CEDrawCtx* dctx, XP_U16 soughtHeight, RFIndex index,
|
|
|
|
|
FontCacheEntry* fce )
|
2008-08-30 20:55:20 +02:00
|
|
|
|
{
|
2008-09-09 14:31:02 +02:00
|
|
|
|
wchar_t widebuf[65];
|
|
|
|
|
XP_U16 len;
|
|
|
|
|
XP_U16 hasMinTop, hasMaxBottom;
|
|
|
|
|
XP_Bool firstPass;
|
|
|
|
|
HBRUSH white = dctx->brushes[CE_WHITE_COLOR];
|
|
|
|
|
HDC memDC = CreateCompatibleDC( NULL );
|
|
|
|
|
HBITMAP memBM;
|
|
|
|
|
XP_U16 testSize;
|
|
|
|
|
|
|
|
|
|
char sample[65];
|
|
|
|
|
makeTestBuf( dctx, sample, VSIZE(sample), index );
|
|
|
|
|
len = strlen(sample);
|
|
|
|
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, sample, len,
|
|
|
|
|
widebuf, len );
|
|
|
|
|
|
2008-09-13 17:24:23 +02:00
|
|
|
|
memBM = CreateCompatibleBitmap( memDC, soughtHeight*2, soughtHeight*2 );
|
2008-09-09 14:31:02 +02:00
|
|
|
|
SelectObject( memDC, memBM );
|
|
|
|
|
|
|
|
|
|
for ( firstPass = XP_TRUE, testSize = soughtHeight*2; ; --testSize ) {
|
|
|
|
|
LOGFONT fontInfo;
|
2008-09-13 17:24:23 +02:00
|
|
|
|
HFONT testFont;
|
|
|
|
|
|
2008-09-28 19:50:04 +02:00
|
|
|
|
ceFillFontInfo( dctx, &fontInfo, testSize );
|
2008-09-13 17:24:23 +02:00
|
|
|
|
testFont = CreateFontIndirect( &fontInfo );
|
|
|
|
|
|
2008-09-09 14:31:02 +02:00
|
|
|
|
if ( !!testFont ) {
|
|
|
|
|
XP_U16 thisHeight, top, bottom;
|
|
|
|
|
|
|
|
|
|
SelectObject( memDC, testFont );
|
|
|
|
|
|
|
|
|
|
/* first time, measure all of them to determine which chars have
|
2008-09-18 05:50:04 +02:00
|
|
|
|
the set's high and low points */
|
2008-09-09 14:31:02 +02:00
|
|
|
|
if ( firstPass ) {
|
|
|
|
|
ceMeasureGlyphs( dctx, memDC, widebuf, &hasMinTop,
|
|
|
|
|
&hasMaxBottom );
|
|
|
|
|
firstPass = XP_FALSE;
|
|
|
|
|
}
|
|
|
|
|
/* Thereafter, just measure the two we know about */
|
2008-09-13 17:24:23 +02:00
|
|
|
|
ceMeasureGlyph( memDC, white, widebuf[hasMinTop], 1000, 0,
|
2008-09-09 14:31:02 +02:00
|
|
|
|
&top, &bottom );
|
2008-09-18 05:50:04 +02:00
|
|
|
|
if ( hasMaxBottom != hasMinTop ) {
|
|
|
|
|
ceMeasureGlyph( memDC, white, widebuf[hasMaxBottom],
|
|
|
|
|
top, bottom, &top, &bottom );
|
|
|
|
|
}
|
2008-09-09 14:31:02 +02:00
|
|
|
|
thisHeight = bottom - top + 1;
|
|
|
|
|
|
|
|
|
|
if ( thisHeight <= soughtHeight ) { /* got it!!! */
|
|
|
|
|
fce->setFont = testFont;
|
2008-09-13 17:24:23 +02:00
|
|
|
|
fce->indexHt = soughtHeight;
|
|
|
|
|
fce->lfHeight = testSize;
|
2008-09-09 14:31:02 +02:00
|
|
|
|
fce->offset = top;
|
2008-09-13 17:24:23 +02:00
|
|
|
|
fce->glyphHt = thisHeight;
|
2008-10-11 18:53:22 +02:00
|
|
|
|
XP_LOGF( "Found for %s: indexHt: %d; lfHeight: %d; glyphHt: %d",
|
|
|
|
|
RFI2Str(index), fce->indexHt, fce->lfHeight,
|
|
|
|
|
fce->glyphHt );
|
2008-09-13 17:24:23 +02:00
|
|
|
|
|
|
|
|
|
XP_ASSERT( fce->lfHeight >= fce->indexHt );
|
|
|
|
|
XP_ASSERT( fce->indexHt >= fce->glyphHt );
|
2008-09-09 14:31:02 +02:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
DeleteObject( testFont );
|
|
|
|
|
}
|
2008-08-30 20:55:20 +02:00
|
|
|
|
}
|
2008-09-09 14:31:02 +02:00
|
|
|
|
|
|
|
|
|
DeleteObject( memBM );
|
|
|
|
|
DeleteDC( memDC );
|
|
|
|
|
} /* ceBestFitFont */
|
2008-08-30 20:55:20 +02:00
|
|
|
|
|
2008-09-10 13:57:30 +02:00
|
|
|
|
static const FontCacheEntry*
|
|
|
|
|
ceGetSizedFont( CEDrawCtx* dctx, XP_U16 height, RFIndex index )
|
2008-03-16 15:23:57 +01:00
|
|
|
|
{
|
2008-08-30 20:55:20 +02:00
|
|
|
|
FontCacheEntry* fce = &dctx->fcEntry[index];
|
|
|
|
|
if ( (0 != height) /* 0 means use what we have */
|
2008-09-13 17:24:23 +02:00
|
|
|
|
&& fce->indexHt != height ) {
|
2008-10-11 18:53:22 +02:00
|
|
|
|
XP_LOGF( "%s: no match for %s (have %d, want %d) so recalculating",
|
|
|
|
|
__func__, RFI2Str(index), fce->indexHt, height );
|
2008-09-09 14:31:02 +02:00
|
|
|
|
ceBestFitFont( dctx, height, index, fce );
|
2008-03-16 15:23:57 +01:00
|
|
|
|
}
|
2008-08-30 20:55:20 +02:00
|
|
|
|
|
2008-09-09 14:31:02 +02:00
|
|
|
|
XP_ASSERT( !!fce->setFont ); /* failing... */
|
2008-09-10 13:57:30 +02:00
|
|
|
|
return fce;
|
2008-09-09 14:31:02 +02:00
|
|
|
|
} /* ceGetSizedFont */
|
2008-03-16 15:23:57 +01:00
|
|
|
|
|
2006-05-09 04:01:27 +02:00
|
|
|
|
static void
|
2008-09-28 19:50:04 +02:00
|
|
|
|
ceMeasureText( CEDrawCtx* dctx, HDC hdc, const FontCacheEntry* fce,
|
2008-09-13 17:24:23 +02:00
|
|
|
|
const XP_UCHAR* str, XP_S16 padding,
|
2008-05-25 17:08:59 +02:00
|
|
|
|
XP_U16* widthP, XP_U16* heightP )
|
2006-05-09 04:01:27 +02:00
|
|
|
|
{
|
2006-05-11 05:00:50 +02:00
|
|
|
|
XP_U16 height = 0;
|
|
|
|
|
XP_U16 maxWidth = 0;
|
2006-05-09 04:01:27 +02:00
|
|
|
|
|
2006-05-11 05:00:50 +02:00
|
|
|
|
for ( ; ; ) {
|
2006-05-12 09:58:31 +02:00
|
|
|
|
wchar_t widebuf[32];
|
2006-05-09 04:01:27 +02:00
|
|
|
|
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,
|
2007-05-26 16:03:07 +02:00
|
|
|
|
widebuf, VSIZE(widebuf) );
|
2006-05-12 09:58:31 +02:00
|
|
|
|
GetTextExtentPoint32( hdc, widebuf, len, &size );
|
2006-05-09 04:01:27 +02:00
|
|
|
|
|
|
|
|
|
maxWidth = (XP_U16)XP_MAX( maxWidth, size.cx );
|
2008-09-13 17:24:23 +02:00
|
|
|
|
if ( !!fce ) {
|
|
|
|
|
size.cy = fce->glyphHt;
|
|
|
|
|
padding = FCE_TEXT_PADDING; /* minimal */
|
|
|
|
|
}
|
2006-05-11 04:58:36 +02:00
|
|
|
|
height += size.cy;
|
2006-05-09 04:01:27 +02:00
|
|
|
|
dctx->miniLineHt = (XP_U16)size.cy;
|
|
|
|
|
|
|
|
|
|
if ( nextStr == NULL ) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
2006-05-12 09:58:31 +02:00
|
|
|
|
height += padding;
|
2006-05-09 04:01:27 +02:00
|
|
|
|
str = nextStr + XP_STRLEN(XP_CR); /* skip '\n' */
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-13 17:24:23 +02:00
|
|
|
|
*widthP = maxWidth;
|
2006-05-09 04:01:27 +02:00
|
|
|
|
*heightP = height;
|
2008-03-31 01:58:04 +02:00
|
|
|
|
} /* ceMeasureText */
|
2006-05-09 04:01:27 +02:00
|
|
|
|
|
|
|
|
|
static void
|
2008-07-20 18:33:19 +02:00
|
|
|
|
drawTextLines( CEDrawCtx* dctx, HDC hdc, const XP_UCHAR* text, XP_S16 padding,
|
|
|
|
|
const RECT* rp, int flags )
|
2006-05-09 04:01:27 +02:00
|
|
|
|
{
|
|
|
|
|
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,
|
2007-05-26 16:03:07 +02:00
|
|
|
|
widebuf, VSIZE(widebuf) );
|
2006-05-09 04:01:27 +02:00
|
|
|
|
|
|
|
|
|
textRt.bottom = textRt.top + dctx->miniLineHt;
|
|
|
|
|
|
2006-05-12 09:58:31 +02:00
|
|
|
|
DrawText( hdc, widebuf, len, &textRt, flags );
|
2006-05-09 04:01:27 +02:00
|
|
|
|
|
|
|
|
|
if ( nextStr == NULL ) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
2006-05-12 09:58:31 +02:00
|
|
|
|
textRt.top = textRt.bottom + padding;
|
2006-05-09 04:01:27 +02:00
|
|
|
|
text = nextStr + XP_STRLEN(XP_CR);
|
|
|
|
|
}
|
2008-07-20 18:33:19 +02:00
|
|
|
|
} /* drawTextLines */
|
2006-05-09 04:01:27 +02:00
|
|
|
|
|
2008-09-13 17:24:23 +02:00
|
|
|
|
static void
|
2008-10-11 18:53:22 +02:00
|
|
|
|
ceGetCharValHts( const CEDrawCtx* dctx, const XP_Rect* xprect,
|
|
|
|
|
XP_U16* charHt, XP_U16* valHt )
|
2008-09-13 17:24:23 +02:00
|
|
|
|
{
|
2008-09-28 19:50:04 +02:00
|
|
|
|
XP_U16 visHt = xprect->height - TRAY_BORDER;
|
2008-10-09 14:12:25 +02:00
|
|
|
|
XP_U16 visWidth = xprect->width - 5; /* ??? */
|
2008-10-11 18:53:22 +02:00
|
|
|
|
XP_U16 minHt;
|
2008-10-09 14:12:25 +02:00
|
|
|
|
|
2008-09-28 19:50:04 +02:00
|
|
|
|
/* if tiles are wider than tall we can let them overlap vertically */
|
2008-10-09 14:12:25 +02:00
|
|
|
|
if ( visWidth > visHt ) {
|
|
|
|
|
if ( visWidth > (visHt*2) ) {
|
2008-09-28 19:50:04 +02:00
|
|
|
|
*charHt = visHt;
|
2008-10-09 14:12:25 +02:00
|
|
|
|
*valHt = (3*visHt) / 4;
|
2008-09-28 19:50:04 +02:00
|
|
|
|
} else {
|
2008-10-09 14:12:25 +02:00
|
|
|
|
*charHt = (visHt * 4) / 5;
|
|
|
|
|
*valHt = visHt / 2;
|
2008-09-28 19:50:04 +02:00
|
|
|
|
}
|
2008-10-11 18:53:22 +02:00
|
|
|
|
|
2008-09-28 19:50:04 +02:00
|
|
|
|
} else {
|
|
|
|
|
*valHt = visHt / 3;
|
|
|
|
|
*charHt = visHt - *valHt;
|
|
|
|
|
}
|
2008-10-11 18:53:22 +02:00
|
|
|
|
|
|
|
|
|
minHt = dctx->globals->cellHt - CELL_BORDER;
|
|
|
|
|
if ( *charHt < minHt ) {
|
|
|
|
|
*charHt = minHt;
|
|
|
|
|
}
|
|
|
|
|
/* XP_LOGF( "%s(width:%d, height:%d)=>char: %d, val:%d", __func__, */
|
2008-10-09 14:12:25 +02:00
|
|
|
|
/* xprect->width, xprect->height, *charHt, *valHt ); */
|
2008-10-11 18:53:22 +02:00
|
|
|
|
} /* ceGetCharValHts */
|
2008-09-13 17:24:23 +02:00
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC XP_Bool
|
2006-08-16 15:44:44 +02:00
|
|
|
|
DRAW_FUNC_NAME(boardBegin)( DrawCtx* p_dctx,
|
|
|
|
|
const XP_Rect* XP_UNUSED(rect),
|
2008-07-20 18:33:19 +02:00
|
|
|
|
DrawFocusState dfs )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
HDC hdc = globals->hdc;
|
2008-09-09 14:31:02 +02:00
|
|
|
|
XP_Bool canDraw = !!hdc && !!dctx->dict;
|
2004-02-13 14:47:37 +01:00
|
|
|
|
if ( canDraw ) {
|
|
|
|
|
dctx->prevBkColor = GetBkColor( hdc );
|
2008-07-20 18:33:19 +02:00
|
|
|
|
dctx->topFocus = dfs == DFS_TOP;
|
2004-02-13 14:47:37 +01:00
|
|
|
|
}
|
|
|
|
|
return canDraw;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} /* draw_boardBegin */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
2008-07-20 18:33:19 +02:00
|
|
|
|
DRAW_FUNC_NAME(objFinished)( DrawCtx* p_dctx, BoardObjectType typ,
|
|
|
|
|
const XP_Rect* rect, DrawFocusState dfs )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
2008-07-20 18:33:19 +02:00
|
|
|
|
#ifdef DRAW_FOCUS_FRAME
|
|
|
|
|
if ( (dfs == DFS_TOP) && (typ == OBJ_BOARD || typ == OBJ_TRAY) ) {
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
HDC hdc = globals->hdc;
|
|
|
|
|
RECT rt;
|
|
|
|
|
|
|
|
|
|
XPRtoRECT( &rt, rect );
|
|
|
|
|
ceClipToRect( hdc, &rt );
|
|
|
|
|
|
|
|
|
|
ceDrawFocusRect( hdc, dctx, &rt );
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2006-11-12 16:22:26 +01:00
|
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
static XP_U16
|
|
|
|
|
getPlayerColor( XP_S16 player )
|
|
|
|
|
{
|
|
|
|
|
if ( player < 0 ) {
|
2007-01-19 07:43:52 +01:00
|
|
|
|
return CE_BLACK_COLOR;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} else {
|
2007-01-19 07:43:52 +01:00
|
|
|
|
return CE_USER_COLOR1 + player;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
|
|
|
|
} /* 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
|
|
|
|
{
|
2008-07-20 18:33:19 +02:00
|
|
|
|
MoveToEx( hdc, x1, y1, NULL );
|
|
|
|
|
LineTo( hdc, x2, y2);
|
2004-12-12 18:39:59 +01:00
|
|
|
|
} /* 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,
|
2006-11-12 16:22:26 +01:00
|
|
|
|
const XP_UCHAR* letters, const XP_Bitmap bitmap,
|
|
|
|
|
Tile XP_UNUSED(tile), XP_S16 owner,
|
|
|
|
|
XWBonusType bonus, HintAtts hintAtts,
|
|
|
|
|
CellFlags flags )
|
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;
|
2008-07-20 18:33:19 +02:00
|
|
|
|
XP_U16 foreColorIndx;
|
2006-11-12 16:22:26 +01:00
|
|
|
|
XP_Bool isPending = (flags & CELL_HIGHLIGHT) != 0;
|
2008-07-20 18:33:19 +02:00
|
|
|
|
XP_Bool isFocussed = TREAT_AS_CURSOR( dctx, flags );
|
2008-03-10 00:32:24 +01:00
|
|
|
|
XP_Bool isDragSrc = (flags & CELL_DRAGSRC) != 0;
|
2008-03-16 15:23:57 +01:00
|
|
|
|
HFONT oldFont;
|
2008-09-10 13:57:30 +02:00
|
|
|
|
const FontCacheEntry* fce;
|
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;
|
2008-04-12 21:29:20 +02:00
|
|
|
|
ceClipToRect( hdc, &rt );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom );
|
2004-06-16 06:17:08 +02:00
|
|
|
|
textRect = rt;
|
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
InsetRect( &rt, 1, 1 );
|
2008-04-12 21:29:20 +02:00
|
|
|
|
ceClipToRect( hdc, &rt );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2008-10-11 18:53:22 +02:00
|
|
|
|
XP_ASSERT( xprect->height == globals->cellHt );
|
|
|
|
|
fce = ceGetSizedFont( dctx, xprect->height - CELL_BORDER, RFONTS_CELL );
|
2008-09-10 13:57:30 +02:00
|
|
|
|
oldFont = SelectObject( hdc, fce->setFont );
|
2008-08-30 20:55:20 +02:00
|
|
|
|
|
2006-05-28 18:16:46 +02:00
|
|
|
|
/* always init to silence compiler warning */
|
2008-07-20 18:33:19 +02:00
|
|
|
|
foreColorIndx = getPlayerColor(owner);
|
2006-05-28 18:16:46 +02:00
|
|
|
|
|
2008-03-10 00:32:24 +01:00
|
|
|
|
if ( !isDragSrc && ((!!letters && letters[0] != '\0' ) || !!bitmap )) {
|
2004-02-16 00:37:45 +01:00
|
|
|
|
if ( isPending ) {
|
2007-01-19 07:43:52 +01:00
|
|
|
|
bkIndex = CE_BLACK_COLOR;
|
2008-07-20 18:33:19 +02:00
|
|
|
|
foreColorIndx = CE_WHITE_COLOR;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} else {
|
2007-01-19 07:43:52 +01:00
|
|
|
|
bkIndex = CE_TILEBACK_COLOR;
|
2008-07-20 18:33:19 +02:00
|
|
|
|
// foreColorIndx already has right val
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
2004-02-16 00:37:45 +01:00
|
|
|
|
} else if ( bonus == BONUS_NONE ) {
|
2007-01-19 07:43:52 +01:00
|
|
|
|
bkIndex = CE_BKG_COLOR;
|
2004-02-16 00:37:45 +01:00
|
|
|
|
} else {
|
2007-01-19 07:43:52 +01:00
|
|
|
|
bkIndex = (bonus - BONUS_DOUBLE_LETTER) + CE_BONUS1_COLOR;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
2004-02-16 00:37:45 +01:00
|
|
|
|
|
2007-01-19 09:24:02 +01:00
|
|
|
|
if ( isFocussed ) {
|
|
|
|
|
bkIndex = CE_FOCUS_COLOR;
|
|
|
|
|
}
|
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
FillRect( hdc, &rt, dctx->brushes[bkIndex] );
|
2004-02-18 05:24:21 +01:00
|
|
|
|
|
2006-11-12 16:22:26 +01:00
|
|
|
|
if ( (flags&CELL_ISBLANK) != 0 ) {
|
2004-02-18 05:24:21 +01:00
|
|
|
|
/* 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;
|
2007-01-19 09:24:02 +01:00
|
|
|
|
FillRect( hdc, &rt,
|
|
|
|
|
dctx->brushes[isPending?CE_WHITE_COLOR:CE_BLACK_COLOR] );
|
2004-02-18 05:24:21 +01:00
|
|
|
|
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
|
|
|
|
|
2008-03-10 00:32:24 +01:00
|
|
|
|
if ( !isDragSrc && !!letters && (letters[0] != '\0') ) {
|
2003-11-20 17:26:35 +01:00
|
|
|
|
wchar_t widebuf[4];
|
|
|
|
|
|
2008-08-30 20:55:20 +02:00
|
|
|
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, letters, -1,
|
2007-05-26 16:03:07 +02:00
|
|
|
|
widebuf, VSIZE(widebuf) );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2008-07-20 18:33:19 +02:00
|
|
|
|
SetTextColor( hdc, dctx->globals->appPrefs.colors[foreColorIndx] );
|
2005-11-27 23:06:04 +01:00
|
|
|
|
#ifdef TARGET_OS_WIN32
|
|
|
|
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, letters, -1,
|
2007-05-26 16:03:07 +02:00
|
|
|
|
widebuf, VSIZE(widebuf) );
|
2005-11-27 23:06:04 +01:00
|
|
|
|
#endif
|
2008-09-10 13:57:30 +02:00
|
|
|
|
ceDrawTextClipped( hdc, widebuf, -1, XP_FALSE, fce, xprect->left+1,
|
|
|
|
|
xprect->top+2, xprect->width, DT_CENTER );
|
2008-03-10 00:32:24 +01:00
|
|
|
|
} else if ( !isDragSrc && !!bitmap ) {
|
2006-04-03 00:27:44 +02:00
|
|
|
|
makeAndDrawBitmap( dctx, hdc, &rt, XP_TRUE,
|
2008-07-20 18:33:19 +02:00
|
|
|
|
foreColorIndx, (CEBitmapInfo*)bitmap );
|
2006-11-12 16:22:26 +01:00
|
|
|
|
} else if ( (flags&CELL_ISSTAR) != 0 ) {
|
2008-08-30 20:55:20 +02:00
|
|
|
|
InsetRect( &textRect, 1, 1 );
|
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 );
|
|
|
|
|
|
2008-03-16 15:23:57 +01:00
|
|
|
|
SelectObject( hdc, oldFont );
|
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
return XP_TRUE;
|
|
|
|
|
} /* ce_draw_drawCell */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
2006-08-16 15:44:44 +02:00
|
|
|
|
DRAW_FUNC_NAME(invertCell)( DrawCtx* XP_UNUSED(p_dctx),
|
|
|
|
|
const XP_Rect* XP_UNUSED(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
|
2006-08-16 15:44:44 +02:00
|
|
|
|
DRAW_FUNC_NAME(trayBegin)( DrawCtx* p_dctx, const XP_Rect* XP_UNUSED(rect),
|
2008-07-20 18:33:19 +02:00
|
|
|
|
XP_U16 owner, DrawFocusState dfs )
|
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;
|
2008-09-09 14:31:02 +02:00
|
|
|
|
XP_Bool canDraw = !!hdc && !!dctx->dict;
|
2004-03-02 04:26:10 +01:00
|
|
|
|
if ( canDraw ) {
|
|
|
|
|
dctx->trayOwner = owner;
|
2008-07-20 18:33:19 +02:00
|
|
|
|
dctx->topFocus = dfs == DFS_TOP;
|
2004-03-02 04:26:10 +01:00
|
|
|
|
}
|
|
|
|
|
return canDraw;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} /* ce_draw_trayBegin */
|
|
|
|
|
|
|
|
|
|
static void
|
2006-02-18 07:39:40 +01:00
|
|
|
|
drawDrawTileGuts( DrawCtx* p_dctx, const XP_Rect* xprect,
|
|
|
|
|
const XP_UCHAR* letters,
|
2006-11-12 16:22:26 +01:00
|
|
|
|
XP_Bitmap bitmap, XP_S16 val, CellFlags flags )
|
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;
|
2008-08-30 20:55:20 +02:00
|
|
|
|
XP_Bool highlighted = XP_FALSE;
|
2008-07-20 18:33:19 +02:00
|
|
|
|
XP_Bool isFocussed = TREAT_AS_CURSOR(dctx,flags);
|
2007-01-19 09:24:02 +01:00
|
|
|
|
XP_Bool isEmpty = (flags & CELL_ISEMPTY) != 0;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2008-03-16 00:06:06 +01:00
|
|
|
|
XPRtoRECT( &rt, xprect );
|
2008-04-12 21:29:20 +02:00
|
|
|
|
ceClipToRect( hdc, &rt );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
ceClearToBkground( dctx, xprect );
|
|
|
|
|
|
2007-01-19 09:24:02 +01:00
|
|
|
|
if ( !isEmpty || isFocussed ) {
|
|
|
|
|
XP_U16 backIndex = isFocussed? CE_FOCUS_COLOR : CE_TILEBACK_COLOR;
|
2004-01-10 19:02:10 +01:00
|
|
|
|
|
2007-01-19 09:24:02 +01:00
|
|
|
|
SetBkColor( hdc, dctx->globals->appPrefs.colors[backIndex] );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2004-01-10 19:02:10 +01:00
|
|
|
|
InsetRect( &rt, 1, 1 );
|
2008-08-30 20:55:20 +02:00
|
|
|
|
Rectangle(hdc, rt.left, rt.top, rt.right, rt.bottom); /* draw frame */
|
2004-01-10 19:02:10 +01:00
|
|
|
|
InsetRect( &rt, 1, 1 );
|
2008-09-01 17:10:28 +02:00
|
|
|
|
/* ceClipToRect( hdc, &rt ); */
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2007-01-19 09:24:02 +01:00
|
|
|
|
if ( !isEmpty ) {
|
|
|
|
|
index = getPlayerColor(dctx->trayOwner);
|
|
|
|
|
SetTextColor( hdc, dctx->globals->appPrefs.colors[index] );
|
|
|
|
|
|
|
|
|
|
/* 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. */
|
|
|
|
|
highlighted = (flags & CELL_HIGHLIGHT) != 0;
|
|
|
|
|
if ( highlighted ) {
|
2008-08-30 20:55:20 +02:00
|
|
|
|
/* draw thicker hilight frame */
|
2007-01-19 09:24:02 +01:00
|
|
|
|
Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom );
|
|
|
|
|
InsetRect( &rt, 1, 1 );
|
|
|
|
|
}
|
2006-11-12 16:22:26 +01:00
|
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2007-01-19 09:24:02 +01:00
|
|
|
|
FillRect( hdc, &rt, dctx->brushes[backIndex] );
|
2006-11-12 16:22:26 +01:00
|
|
|
|
|
2007-01-19 09:24:02 +01:00
|
|
|
|
if ( !isEmpty ) {
|
2008-09-13 17:24:23 +02:00
|
|
|
|
const FontCacheEntry* fce;
|
2008-08-30 20:55:20 +02:00
|
|
|
|
/* Dumb to calc these when only needed once.... */
|
2008-09-13 17:24:23 +02:00
|
|
|
|
XP_U16 valHt, charHt;
|
2008-10-11 18:53:22 +02:00
|
|
|
|
ceGetCharValHts( dctx, xprect, &charHt, &valHt );
|
2008-08-30 20:55:20 +02:00
|
|
|
|
|
2007-01-19 09:24:02 +01:00
|
|
|
|
if ( !highlighted ) {
|
|
|
|
|
InsetRect( &rt, 1, 1 );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( !!letters ) {
|
2008-09-10 13:57:30 +02:00
|
|
|
|
fce = ceGetSizedFont( dctx, charHt, RFONTS_TRAY );
|
|
|
|
|
HFONT oldFont = SelectObject( hdc, fce->setFont );
|
2007-01-19 09:24:02 +01:00
|
|
|
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, letters, -1,
|
2008-09-10 13:57:30 +02:00
|
|
|
|
widebuf, VSIZE(widebuf) );
|
2008-08-30 20:55:20 +02:00
|
|
|
|
|
2008-09-10 13:57:30 +02:00
|
|
|
|
ceDrawTextClipped( hdc, widebuf, -1, XP_TRUE, fce,
|
|
|
|
|
xprect->left + 4, xprect->top + 4,
|
|
|
|
|
xprect->width, DT_LEFT );
|
2007-01-19 09:24:02 +01:00
|
|
|
|
SelectObject( hdc, oldFont );
|
|
|
|
|
} else if ( !!bitmap ) {
|
|
|
|
|
RECT lrt = rt;
|
|
|
|
|
XP_U16 tmp = CE_USER_COLOR1+dctx->trayOwner;
|
|
|
|
|
++lrt.left;
|
|
|
|
|
lrt.top += 4;
|
|
|
|
|
makeAndDrawBitmap( dctx, hdc, &lrt, XP_FALSE,
|
|
|
|
|
dctx->globals->appPrefs.colors[tmp],
|
|
|
|
|
(CEBitmapInfo*)bitmap );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if ( val >= 0 ) {
|
2008-09-10 13:57:30 +02:00
|
|
|
|
fce = ceGetSizedFont( dctx, valHt, RFONTS_TRAYVAL );
|
|
|
|
|
HFONT oldFont = SelectObject( hdc, fce->setFont );
|
2007-01-19 09:24:02 +01:00
|
|
|
|
swprintf( widebuf, L"%d", val );
|
2008-08-30 20:55:20 +02:00
|
|
|
|
|
2008-09-10 13:57:30 +02:00
|
|
|
|
ceDrawTextClipped( hdc, widebuf, -1, XP_TRUE, fce,
|
2008-08-30 20:55:20 +02:00
|
|
|
|
xprect->left + 4,
|
2008-09-13 17:24:23 +02:00
|
|
|
|
xprect->top + xprect->height - 4 - fce->glyphHt,
|
2008-09-10 13:57:30 +02:00
|
|
|
|
xprect->width - 8, DT_RIGHT );
|
2008-03-16 15:23:57 +01:00
|
|
|
|
SelectObject( hdc, oldFont );
|
2007-01-19 09:24:02 +01:00
|
|
|
|
}
|
2006-11-12 16:22:26 +01:00
|
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
|
|
|
|
} /* 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,
|
2006-11-12 16:22:26 +01:00
|
|
|
|
XP_S16 val, CellFlags flags )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
2006-11-12 16:22:26 +01:00
|
|
|
|
drawDrawTileGuts( p_dctx, xprect, letters, bitmap, val, flags );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} /* ce_draw_drawTile */
|
|
|
|
|
|
2008-03-10 00:32:24 +01:00
|
|
|
|
#ifdef POINTER_SUPPORT
|
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(drawTileMidDrag)( DrawCtx* p_dctx, const XP_Rect* xprect,
|
|
|
|
|
const XP_UCHAR* letters, XP_Bitmap bitmap,
|
2008-03-11 12:48:53 +01:00
|
|
|
|
XP_S16 val, XP_U16 owner, CellFlags flags )
|
2008-03-10 00:32:24 +01:00
|
|
|
|
{
|
2008-03-11 12:48:53 +01:00
|
|
|
|
draw_trayBegin( p_dctx, xprect, owner, DFS_NONE );
|
2008-03-10 00:32:24 +01:00
|
|
|
|
drawDrawTileGuts( p_dctx, xprect, letters, bitmap, val, flags );
|
|
|
|
|
} /* ce_draw_drawTile */
|
|
|
|
|
#endif
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
2006-11-12 16:22:26 +01:00
|
|
|
|
DRAW_FUNC_NAME(drawTileBack)( DrawCtx* p_dctx, const XP_Rect* xprect,
|
|
|
|
|
CellFlags flags )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
2006-11-12 16:22:26 +01:00
|
|
|
|
drawDrawTileGuts( p_dctx, xprect, "?", NULL, -1, flags );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} /* ce_draw_drawTileBack */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(drawTrayDivider)( DrawCtx* p_dctx, const XP_Rect* rect,
|
2008-07-17 07:03:01 +02:00
|
|
|
|
CellFlags flags )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
HDC hdc = globals->hdc;
|
|
|
|
|
RECT rt;
|
2008-07-17 07:03:01 +02:00
|
|
|
|
XP_Bool selected = (flags & CELL_HIGHLIGHT) != 0;
|
2008-07-20 18:33:19 +02:00
|
|
|
|
XP_Bool isFocussed = TREAT_AS_CURSOR(dctx,flags);
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
XPRtoRECT( &rt, rect );
|
2008-04-12 21:29:20 +02:00
|
|
|
|
ceClipToRect( hdc, &rt );
|
2008-07-17 07:03:01 +02:00
|
|
|
|
|
2008-07-20 18:33:19 +02:00
|
|
|
|
if ( isFocussed ) {
|
2008-07-17 07:03:01 +02:00
|
|
|
|
FillRect( hdc, &rt, dctx->brushes[CE_FOCUS_COLOR] );
|
2008-07-24 06:16:48 +02:00
|
|
|
|
InsetRect( &rt, 0, (rt.bottom - rt.top) >> 2 );
|
2008-07-17 07:03:01 +02:00
|
|
|
|
}
|
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
if ( selected ) {
|
|
|
|
|
Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom );
|
|
|
|
|
} else {
|
2008-09-28 19:55:27 +02:00
|
|
|
|
FillRect( hdc, &rt, dctx->brushes[dctx->trayOwner+CE_USER_COLOR1] );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
|
|
|
|
} /* 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 );
|
|
|
|
|
|
2007-01-19 07:43:52 +01:00
|
|
|
|
FillRect( hdc, &rt, dctx->brushes[CE_BKG_COLOR] );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} /* ceClearToBkground */
|
|
|
|
|
|
|
|
|
|
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,
|
2007-01-19 09:24:02 +01:00
|
|
|
|
HintAtts hintAtts, CellFlags flags )
|
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;
|
2008-04-12 21:29:20 +02:00
|
|
|
|
ceClipToRect( hdc, &rt );
|
2008-04-12 17:47:15 +02:00
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom );
|
|
|
|
|
InsetRect( &rt, 1, 1 );
|
2008-05-25 17:31:54 +02:00
|
|
|
|
ceClipToRect( hdc, &rt );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
if ( vertical ) {
|
|
|
|
|
cursor = dctx->downArrow;
|
|
|
|
|
} else {
|
|
|
|
|
cursor = dctx->rightArrow;
|
|
|
|
|
}
|
|
|
|
|
|
2008-07-20 18:33:19 +02:00
|
|
|
|
if ( TREAT_AS_CURSOR( dctx, flags ) ) {
|
2007-01-19 09:24:02 +01:00
|
|
|
|
bkIndex = CE_FOCUS_COLOR;
|
|
|
|
|
} else if ( cursorBonus == BONUS_NONE ) {
|
2007-01-19 07:43:52 +01:00
|
|
|
|
bkIndex = CE_BKG_COLOR;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} else {
|
2007-01-19 07:43:52 +01:00
|
|
|
|
bkIndex = cursorBonus - BONUS_DOUBLE_LETTER + CE_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] );
|
2007-01-19 07:43:52 +01:00
|
|
|
|
SetTextColor( hdc, dctx->globals->appPrefs.colors[CE_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
|
2008-09-28 19:50:04 +02:00
|
|
|
|
DRAW_FUNC_NAME(scoreBegin)( DrawCtx* p_dctx, const XP_Rect* xprect,
|
2006-08-16 15:44:44 +02:00
|
|
|
|
XP_U16 XP_UNUSED(numPlayers),
|
2006-11-12 16:22:26 +01:00
|
|
|
|
DrawFocusState XP_UNUSED(dfs) )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
2008-09-01 17:10:28 +02:00
|
|
|
|
XP_ASSERT( !!globals->hdc );
|
|
|
|
|
SetBkColor( globals->hdc, dctx->globals->appPrefs.colors[CE_BKG_COLOR] );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2008-09-28 19:50:04 +02:00
|
|
|
|
dctx->scoreIsVertical = xprect->height > xprect->width;
|
2006-05-09 04:01:27 +02:00
|
|
|
|
|
2008-05-11 17:25:04 +02:00
|
|
|
|
/* I don't think the clip rect's set at this point but drawing seems fine
|
|
|
|
|
anyway.... ceClearToBkground() is definitely needed here. */
|
2008-09-28 19:50:04 +02:00
|
|
|
|
ceClearToBkground( (CEDrawCtx*)p_dctx, xprect );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} /* ce_draw_scoreBegin */
|
|
|
|
|
|
|
|
|
|
static void
|
2006-08-16 15:44:44 +02:00
|
|
|
|
formatRemText( XP_S16 nTilesLeft, XP_Bool isVertical, XP_UCHAR* buf )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
2006-06-16 03:15:44 +02:00
|
|
|
|
char* fmt;
|
|
|
|
|
XP_ASSERT( nTilesLeft > 0 );
|
|
|
|
|
|
|
|
|
|
if ( isVertical ) {
|
|
|
|
|
fmt = "Rem" XP_CR "%d";
|
|
|
|
|
} else {
|
|
|
|
|
fmt = "Rem:%d";
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
2006-06-16 03:15:44 +02:00
|
|
|
|
sprintf( buf, fmt, nTilesLeft );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} /* formatRemText */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
2008-08-30 20:55:20 +02:00
|
|
|
|
DRAW_FUNC_NAME(measureRemText)( DrawCtx* p_dctx, const XP_Rect* xprect,
|
2006-04-01 23:01:20 +02:00
|
|
|
|
XP_S16 nTilesLeft,
|
2008-09-13 17:24:23 +02:00
|
|
|
|
XP_U16* widthP, XP_U16* heightP )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
2006-06-16 03:15:44 +02:00
|
|
|
|
if ( nTilesLeft > 0 ) {
|
2008-09-13 17:24:23 +02:00
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
2008-09-28 19:50:04 +02:00
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
HDC hdc = globals->hdc;
|
2008-03-31 01:58:04 +02:00
|
|
|
|
XP_UCHAR buf[16];
|
2008-09-13 17:24:23 +02:00
|
|
|
|
const FontCacheEntry* fce;
|
|
|
|
|
XP_U16 height;
|
|
|
|
|
HFONT oldFont;
|
|
|
|
|
|
|
|
|
|
XP_ASSERT( !!hdc );
|
|
|
|
|
|
2006-08-16 15:44:44 +02:00
|
|
|
|
formatRemText( nTilesLeft, dctx->scoreIsVertical, buf );
|
2008-09-13 17:24:23 +02:00
|
|
|
|
|
|
|
|
|
height = xprect->height-2;
|
2008-10-08 06:42:16 +02:00
|
|
|
|
if ( height > globals->cellHt - CELL_BORDER ) {
|
|
|
|
|
height = globals->cellHt - CELL_BORDER;
|
2008-08-30 20:55:20 +02:00
|
|
|
|
}
|
2008-09-13 17:24:23 +02:00
|
|
|
|
fce = ceGetSizedFont( dctx, height, RFONTS_REM );
|
|
|
|
|
oldFont = SelectObject( hdc, fce->setFont );
|
2008-09-28 19:50:04 +02:00
|
|
|
|
ceMeasureText( dctx, hdc, fce, buf, 0, widthP, heightP );
|
2008-09-13 17:24:23 +02:00
|
|
|
|
|
|
|
|
|
(void)SelectObject( hdc, oldFont );
|
2006-06-16 03:15:44 +02:00
|
|
|
|
} else {
|
2008-09-13 17:24:23 +02:00
|
|
|
|
*widthP = *heightP = 0;
|
2006-06-16 03:15:44 +02:00
|
|
|
|
}
|
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,
|
2006-08-16 15:44:44 +02:00
|
|
|
|
const XP_Rect* XP_UNUSED(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];
|
2008-09-13 17:24:23 +02:00
|
|
|
|
HFONT oldFont;
|
|
|
|
|
const FontCacheEntry* fce;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
RECT rt;
|
|
|
|
|
|
2006-08-16 15:44:44 +02:00
|
|
|
|
formatRemText( nTilesLeft, dctx->scoreIsVertical, buf );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2008-09-13 17:24:23 +02:00
|
|
|
|
fce = ceGetSizedFont( dctx, 0, RFONTS_REM );
|
|
|
|
|
oldFont = SelectObject( hdc, fce->setFont );
|
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
XPRtoRECT( &rt, rInner );
|
2008-09-13 17:24:23 +02:00
|
|
|
|
InsetRect( &rt, 1, 1 );
|
|
|
|
|
ceDrawLinesClipped( hdc, fce, buf, XP_TRUE, &rt );
|
|
|
|
|
|
|
|
|
|
(void)SelectObject( hdc, oldFont );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} /* ce_draw_drawRemText */
|
|
|
|
|
|
|
|
|
|
static void
|
2008-09-13 17:24:23 +02:00
|
|
|
|
ceFormatScoreText( CEDrawCtx* dctx, const DrawScoreInfo* dsi,
|
|
|
|
|
XP_UCHAR* buf, XP_U16 buflen )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
2006-05-20 08:21:53 +02:00
|
|
|
|
XP_UCHAR bullet[] = {'<EFBFBD>', '\0'};
|
2008-09-13 17:24:23 +02:00
|
|
|
|
XP_UCHAR optPart[16];
|
2006-05-12 09:58:31 +02:00
|
|
|
|
|
|
|
|
|
/* For a horizontal scoreboard, we want *300:6*
|
|
|
|
|
* For a vertical, it's
|
2008-09-13 17:24:23 +02:00
|
|
|
|
*
|
2006-05-12 09:58:31 +02:00
|
|
|
|
* 300
|
2008-09-13 17:24:23 +02:00
|
|
|
|
* 6
|
2006-05-20 08:21:53 +02:00
|
|
|
|
*
|
|
|
|
|
* with IS_TURN_VPAD-height rects above and below
|
2008-09-13 17:24:23 +02:00
|
|
|
|
*/
|
2006-05-12 09:58:31 +02:00
|
|
|
|
|
2006-05-20 08:21:53 +02:00
|
|
|
|
if ( !dsi->isTurn || dctx->scoreIsVertical ) {
|
|
|
|
|
bullet[0] = '\0';
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
|
|
|
|
|
2006-05-12 09:58:31 +02:00
|
|
|
|
if ( dsi->nTilesLeft >= 0 ) {
|
2008-09-13 17:24:23 +02:00
|
|
|
|
sprintf( optPart, "%s%d", dctx->scoreIsVertical? XP_CR : ":",
|
|
|
|
|
dsi->nTilesLeft );
|
|
|
|
|
} else {
|
|
|
|
|
optPart[0] = '\0';
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
|
|
|
|
|
2008-09-13 17:24:23 +02:00
|
|
|
|
snprintf( buf, buflen, "%s%d%s%s",
|
|
|
|
|
bullet, dsi->totalScore, optPart, bullet );
|
|
|
|
|
} /* ceFormatScoreText */
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
2008-09-13 17:24:23 +02:00
|
|
|
|
DRAW_FUNC_NAME(measureScoreText)( DrawCtx* p_dctx, const XP_Rect* xprect,
|
2006-04-01 23:01:20 +02:00
|
|
|
|
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-12 09:58:31 +02:00
|
|
|
|
XP_UCHAR buf[32];
|
2003-11-20 17:26:35 +01:00
|
|
|
|
HFONT oldFont;
|
2008-09-13 17:24:23 +02:00
|
|
|
|
const FontCacheEntry* fce;
|
2008-09-28 19:50:04 +02:00
|
|
|
|
XP_U16 fontHt, cellHt;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2008-09-28 19:50:04 +02:00
|
|
|
|
cellHt = globals->cellHt;
|
|
|
|
|
if ( !dctx->scoreIsVertical ) {
|
|
|
|
|
cellHt -= SCORE_TWEAK;
|
|
|
|
|
}
|
|
|
|
|
fontHt = xprect->height;
|
|
|
|
|
if ( fontHt > cellHt ) {
|
|
|
|
|
fontHt = cellHt;
|
2008-09-13 17:24:23 +02:00
|
|
|
|
}
|
2008-09-28 19:50:04 +02:00
|
|
|
|
fontHt -= 2; /* for whitespace top and bottom */
|
2008-09-13 17:24:23 +02:00
|
|
|
|
if ( !dsi->selected ) {
|
2008-09-28 19:50:04 +02:00
|
|
|
|
fontHt -= 2; /* use smaller font for non-selected */
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
|
|
|
|
|
2008-09-28 19:50:04 +02:00
|
|
|
|
ceFormatScoreText( dctx, dsi, buf, sizeof(buf) );
|
|
|
|
|
|
|
|
|
|
fce = ceGetSizedFont( dctx, fontHt,
|
|
|
|
|
dsi->selected ? RFONTS_SCORE_BOLD:RFONTS_SCORE );
|
2008-09-13 17:24:23 +02:00
|
|
|
|
oldFont = SelectObject( hdc, fce->setFont );
|
|
|
|
|
|
2008-09-28 19:50:04 +02:00
|
|
|
|
ceMeasureText( dctx, hdc, fce, buf, 0, widthP, heightP );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
SelectObject( hdc, oldFont );
|
2008-09-13 17:24:23 +02:00
|
|
|
|
|
|
|
|
|
if ( dsi->isTurn && dctx->scoreIsVertical ) {
|
|
|
|
|
*heightP += IS_TURN_VPAD * 2;
|
|
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} /* ce_draw_measureScoreText */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(score_drawPlayer)( DrawCtx* p_dctx,
|
2006-08-16 15:44:44 +02:00
|
|
|
|
const XP_Rect* rInner,
|
2007-01-19 09:24:02 +01:00
|
|
|
|
const XP_Rect* rOuter,
|
2006-04-01 23:01:20 +02:00
|
|
|
|
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;
|
2008-09-13 17:24:23 +02:00
|
|
|
|
XP_UCHAR buf[20];
|
2003-11-20 17:26:35 +01:00
|
|
|
|
HFONT oldFont;
|
2007-01-19 09:24:02 +01:00
|
|
|
|
XP_Bool isFocussed = (dsi->flags & CELL_ISCURSOR) != 0;
|
|
|
|
|
XP_U16 bkIndex = isFocussed ? CE_FOCUS_COLOR : CE_BKG_COLOR;
|
2008-09-13 17:24:23 +02:00
|
|
|
|
const FontCacheEntry* fce;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2008-09-13 17:24:23 +02:00
|
|
|
|
fce = ceGetSizedFont( dctx, 0,
|
|
|
|
|
dsi->selected ? RFONTS_SCORE_BOLD:RFONTS_SCORE );
|
|
|
|
|
|
|
|
|
|
oldFont = SelectObject( hdc, fce->setFont );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2005-06-09 16:18:55 +02:00
|
|
|
|
SetTextColor( hdc, dctx->globals->
|
|
|
|
|
appPrefs.colors[getPlayerColor(dsi->playerNum)] );
|
2007-01-19 09:24:02 +01:00
|
|
|
|
SetBkColor( hdc, dctx->globals->appPrefs.colors[bkIndex] );
|
|
|
|
|
|
2008-03-16 00:06:06 +01:00
|
|
|
|
XPRtoRECT( &rt, rOuter );
|
2008-04-12 21:29:20 +02:00
|
|
|
|
ceClipToRect( hdc, &rt );
|
2007-01-19 09:24:02 +01:00
|
|
|
|
if ( isFocussed ) {
|
|
|
|
|
FillRect( hdc, &rt, dctx->brushes[CE_FOCUS_COLOR] );
|
|
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2008-09-13 17:24:23 +02:00
|
|
|
|
ceFormatScoreText( dctx, dsi, buf, sizeof(buf) );
|
2006-05-09 04:01:27 +02:00
|
|
|
|
|
2007-01-19 09:24:02 +01:00
|
|
|
|
XPRtoRECT( &rt, rInner );
|
2006-05-20 08:21:53 +02:00
|
|
|
|
|
2008-09-13 17:24:23 +02:00
|
|
|
|
if ( dsi->isTurn && dctx->scoreIsVertical ) {
|
2006-05-20 08:21:53 +02:00
|
|
|
|
Rectangle( hdc, rt.left, rt.top-IS_TURN_VPAD, rt.right, rt.top );
|
2007-01-19 09:24:02 +01:00
|
|
|
|
Rectangle( hdc, rt.left, rt.bottom, rt.right,
|
|
|
|
|
rt.bottom + IS_TURN_VPAD );
|
2008-09-13 17:24:23 +02:00
|
|
|
|
|
|
|
|
|
rt.top += IS_TURN_VPAD;
|
|
|
|
|
rt.bottom -= IS_TURN_VPAD;
|
2006-05-20 08:21:53 +02:00
|
|
|
|
}
|
|
|
|
|
|
2008-09-13 17:24:23 +02:00
|
|
|
|
ceDrawLinesClipped( hdc, fce, buf, XP_TRUE, &rt );
|
|
|
|
|
|
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
|
2008-08-30 20:55:20 +02:00
|
|
|
|
DRAW_FUNC_NAME(score_pendingScore)( DrawCtx* p_dctx, const XP_Rect* xprect,
|
|
|
|
|
XP_S16 score, XP_U16 playerNum,
|
2007-01-19 09:24:02 +01:00
|
|
|
|
CellFlags flags )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
2008-08-30 20:55:20 +02:00
|
|
|
|
# define PTS_OFFSET 2
|
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];
|
2008-08-30 20:55:20 +02:00
|
|
|
|
RECT rt;
|
2008-07-24 06:16:48 +02:00
|
|
|
|
XP_Bool focussed = TREAT_AS_CURSOR(dctx,flags);
|
|
|
|
|
XP_U16 bkIndex = focussed ? CE_FOCUS_COLOR : CE_BKG_COLOR;
|
2008-09-13 17:24:23 +02:00
|
|
|
|
const FontCacheEntry* fce;
|
|
|
|
|
HFONT oldFont;
|
|
|
|
|
XP_U16 valHt;
|
|
|
|
|
XP_U16 charHt;
|
|
|
|
|
|
2008-10-11 18:53:22 +02:00
|
|
|
|
ceGetCharValHts( dctx, xprect, &charHt, &valHt );
|
2008-09-13 17:24:23 +02:00
|
|
|
|
|
|
|
|
|
/* Little Pts first up top */
|
|
|
|
|
fce = ceGetSizedFont( dctx, valHt, RFONTS_TRAYVAL );
|
|
|
|
|
oldFont = SelectObject( hdc, fce->setFont );
|
2008-05-25 17:08:59 +02:00
|
|
|
|
|
2008-08-30 20:55:20 +02:00
|
|
|
|
SetTextColor( hdc,
|
|
|
|
|
dctx->globals->appPrefs.colors[getPlayerColor(playerNum)] );
|
2007-01-19 09:24:02 +01:00
|
|
|
|
SetBkColor( hdc, dctx->globals->appPrefs.colors[bkIndex] );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2008-08-30 20:55:20 +02:00
|
|
|
|
XPRtoRECT( &rt, xprect );
|
|
|
|
|
ceClipToRect( hdc, &rt );
|
2007-01-19 09:24:02 +01:00
|
|
|
|
FillRect( hdc, &rt, dctx->brushes[bkIndex] );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2008-09-10 13:57:30 +02:00
|
|
|
|
ceDrawTextClipped( hdc, L"Pts", -1, XP_FALSE, fce,
|
2008-08-30 20:55:20 +02:00
|
|
|
|
xprect->left + PTS_OFFSET, xprect->top + PTS_OFFSET,
|
2008-09-10 13:57:30 +02:00
|
|
|
|
xprect->width - (PTS_OFFSET*2), DT_CENTER );
|
2008-09-13 17:24:23 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
fce = ceGetSizedFont( dctx, charHt, RFONTS_TRAY );
|
|
|
|
|
(void)SelectObject( hdc, fce->setFont );
|
2008-05-25 17:08:59 +02:00
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
if ( score < 0 ) {
|
|
|
|
|
buf[0] = '?';
|
|
|
|
|
buf[1] = '?';
|
|
|
|
|
buf[2] = '\0';
|
|
|
|
|
} else {
|
|
|
|
|
sprintf( buf, "%d", score );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, buf, -1,
|
2007-05-26 16:03:07 +02:00
|
|
|
|
widebuf, VSIZE(widebuf) );
|
2008-09-10 13:57:30 +02:00
|
|
|
|
ceDrawTextClipped( hdc, widebuf, -1, XP_TRUE, fce,
|
|
|
|
|
xprect->left + PTS_OFFSET,
|
2008-09-13 17:24:23 +02:00
|
|
|
|
xprect->top + xprect->height - charHt,
|
2008-09-10 13:57:30 +02:00
|
|
|
|
xprect->width - (PTS_OFFSET*2), DT_CENTER );
|
2008-09-13 17:24:23 +02:00
|
|
|
|
|
2008-05-25 17:08:59 +02:00
|
|
|
|
SelectObject( hdc, oldFont );
|
2008-08-30 20:55:20 +02:00
|
|
|
|
# undef PTS_OFFSET
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} /* ce_draw_score_pendingScore */
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
DLSTATIC void
|
2006-08-16 15:44:44 +02:00
|
|
|
|
DRAW_FUNC_NAME(drawTimer)( DrawCtx* p_dctx, const XP_Rect* rInner,
|
|
|
|
|
const XP_Rect* XP_UNUSED(rOuter),
|
2006-04-01 23:01:20 +02:00
|
|
|
|
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;
|
2008-09-28 19:50:04 +02:00
|
|
|
|
HFONT oldFont;
|
|
|
|
|
const FontCacheEntry* fce;
|
|
|
|
|
|
|
|
|
|
fce = ceGetSizedFont( dctx, 0, RFONTS_SCORE );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
2008-05-11 17:25:04 +02:00
|
|
|
|
if ( !hdc ) {
|
2003-11-20 17:26:35 +01:00
|
|
|
|
InvalidateRect( dctx->mainWin, &rt, FALSE );
|
|
|
|
|
hdc = BeginPaint( dctx->mainWin, &ps );
|
|
|
|
|
}
|
|
|
|
|
|
2008-05-11 17:25:04 +02:00
|
|
|
|
ceClipToRect( hdc, &rt );
|
|
|
|
|
|
2004-03-28 03:14:34 +02:00
|
|
|
|
SetTextColor( hdc, dctx->globals->appPrefs.colors[getPlayerColor(player)] );
|
2008-05-25 17:54:34 +02:00
|
|
|
|
SetBkColor( hdc, dctx->globals->appPrefs.colors[CE_BKG_COLOR] );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
ceClearToBkground( dctx, rInner );
|
2008-09-28 19:50:04 +02:00
|
|
|
|
|
|
|
|
|
oldFont = SelectObject( hdc, fce->setFont );
|
|
|
|
|
++rt.top;
|
|
|
|
|
ceDrawLinesClipped( hdc, fce, buf, XP_TRUE, &rt );
|
|
|
|
|
SelectObject( hdc, oldFont );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
if ( !globals->hdc ) {
|
|
|
|
|
EndPaint( dctx->mainWin, &ps );
|
|
|
|
|
}
|
|
|
|
|
} /* ce_draw_drawTimer */
|
|
|
|
|
|
2007-02-03 18:54:20 +01:00
|
|
|
|
DLSTATIC const XP_UCHAR*
|
2006-08-16 15:44:44 +02:00
|
|
|
|
DRAW_FUNC_NAME(getMiniWText)( DrawCtx* XP_UNUSED(p_dctx),
|
|
|
|
|
XWMiniTextType whichText )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
XP_UCHAR* str;
|
|
|
|
|
|
|
|
|
|
switch( whichText ) {
|
|
|
|
|
case BONUS_DOUBLE_LETTER:
|
2006-05-28 18:16:46 +02:00
|
|
|
|
str = "Double letter";
|
|
|
|
|
break;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
case BONUS_DOUBLE_WORD:
|
2006-05-28 18:16:46 +02:00
|
|
|
|
str = "Double word";
|
|
|
|
|
break;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
case BONUS_TRIPLE_LETTER:
|
2006-05-28 18:16:46 +02:00
|
|
|
|
str = "Triple letter";
|
|
|
|
|
break;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
case BONUS_TRIPLE_WORD:
|
2006-05-28 18:16:46 +02:00
|
|
|
|
str = "Triple word";
|
|
|
|
|
break;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
case INTRADE_MW_TEXT:
|
2008-05-11 17:25:04 +02:00
|
|
|
|
str = "Trading tiles." XP_CR "Select 'Turn done' when ready";
|
2006-05-28 18:16:46 +02:00
|
|
|
|
break;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
default:
|
|
|
|
|
XP_ASSERT( XP_FALSE );
|
2006-05-28 18:16:46 +02:00
|
|
|
|
str = NULL;
|
|
|
|
|
break;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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;
|
2008-09-28 19:50:04 +02:00
|
|
|
|
HDC hdc = GetDC(dctx->mainWin);
|
|
|
|
|
ceMeasureText( dctx, hdc, NULL, str, CE_MINIW_PADDING, widthP, heightP );
|
2006-05-11 04:58:36 +02:00
|
|
|
|
*heightP += CE_MINI_V_PADDING;
|
2008-09-13 17:24:23 +02:00
|
|
|
|
*widthP += CE_MINI_H_PADDING;
|
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,
|
2006-08-16 15:44:44 +02:00
|
|
|
|
const XP_Rect* rect,
|
|
|
|
|
void** XP_UNUSED(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 );
|
|
|
|
|
}
|
2008-05-11 17:25:04 +02:00
|
|
|
|
ceClipToRect( hdc, &rt );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2008-03-31 01:58:04 +02:00
|
|
|
|
ceClearToBkground( dctx, rect );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
2007-01-19 07:43:52 +01:00
|
|
|
|
SetBkColor( hdc, dctx->globals->appPrefs.colors[CE_BKG_COLOR] );
|
|
|
|
|
SetTextColor( hdc, dctx->globals->appPrefs.colors[CE_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 );
|
|
|
|
|
|
2008-07-20 18:33:19 +02:00
|
|
|
|
drawTextLines( dctx, hdc, text, CE_MINIW_PADDING, &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(destroyCtxt)( DrawCtx* p_dctx )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
|
|
|
|
XP_U16 i;
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
|
|
|
|
|
2007-01-19 07:43:52 +01:00
|
|
|
|
for ( i = 0; i < CE_NUM_COLORS; ++i ) {
|
2003-11-20 17:26:35 +01:00
|
|
|
|
DeleteObject( dctx->brushes[i] );
|
2008-08-02 16:35:40 +02:00
|
|
|
|
if ( !!dctx->pens[i].pen ) {
|
|
|
|
|
DeleteObject( dctx->pens[i].pen );
|
2008-07-20 18:33:19 +02:00
|
|
|
|
}
|
2003-11-20 17:26:35 +01:00
|
|
|
|
}
|
|
|
|
|
|
2008-09-09 14:31:02 +02:00
|
|
|
|
ceClearFontCache( dctx );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
DeleteObject( dctx->rightArrow );
|
|
|
|
|
DeleteObject( dctx->downArrow );
|
|
|
|
|
DeleteObject( dctx->origin );
|
|
|
|
|
|
2006-05-30 07:12:02 +02:00
|
|
|
|
#ifndef DRAW_LINK_DIRECT
|
2003-11-20 17:26:35 +01:00
|
|
|
|
XP_FREE( dctx->mpool, p_dctx->vtable );
|
2006-05-30 07:12:02 +02:00
|
|
|
|
#endif
|
|
|
|
|
|
2003-11-20 17:26:35 +01:00
|
|
|
|
XP_FREE( dctx->mpool, dctx );
|
|
|
|
|
} /* ce_draw_destroyCtxt */
|
|
|
|
|
|
2008-09-05 14:11:37 +02:00
|
|
|
|
DLSTATIC void
|
|
|
|
|
DRAW_FUNC_NAME(dictChanged)( DrawCtx* p_dctx, const DictionaryCtxt* dict )
|
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
2008-10-11 18:53:22 +02:00
|
|
|
|
XP_ASSERT( !!dict );
|
|
|
|
|
|
|
|
|
|
/* If we don't yet have a dict, stick with the cache we have, which is
|
|
|
|
|
either empty or came from the saved game and likely belong with the
|
|
|
|
|
dict we're getting now. */
|
|
|
|
|
if ( !!dctx->dict && !dict_tilesAreSame( dctx->dict, dict ) ) {
|
|
|
|
|
ceClearFontCache( dctx );
|
|
|
|
|
}
|
2008-09-05 14:11:37 +02:00
|
|
|
|
dctx->dict = dict;
|
|
|
|
|
}
|
|
|
|
|
|
2006-04-01 23:01:20 +02:00
|
|
|
|
#ifdef DRAW_LINK_DIRECT
|
|
|
|
|
DLSTATIC XP_Bool
|
2006-06-22 06:59:18 +02:00
|
|
|
|
DRAW_FUNC_NAME(vertScrollBoard)( DrawCtx* p_dctx, XP_Rect* rect,
|
2007-01-21 23:59:29 +01:00
|
|
|
|
XP_S16 dist, DrawFocusState XP_UNUSED(dfs) )
|
2006-04-01 23:01:20 +02:00
|
|
|
|
{
|
2006-06-24 03:22:10 +02:00
|
|
|
|
XP_Bool success = XP_FALSE;
|
|
|
|
|
/* board passes in the whole board rect, so we need to subtract from it
|
|
|
|
|
the height of the area to be overwritten. If dist is negative, the
|
|
|
|
|
dest is above the src. Otherwise it's below. */
|
2006-06-22 06:59:18 +02:00
|
|
|
|
|
2006-06-24 03:22:10 +02:00
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
int destY, srcY;
|
2008-04-12 21:29:20 +02:00
|
|
|
|
RECT rt;
|
2006-06-24 03:22:10 +02:00
|
|
|
|
XP_Bool down = dist <= 0;
|
|
|
|
|
|
2008-04-12 21:29:20 +02:00
|
|
|
|
XPRtoRECT( &rt, rect );
|
|
|
|
|
ceClipToRect( globals->hdc, &rt );
|
|
|
|
|
|
2006-06-24 03:22:10 +02:00
|
|
|
|
if ( down ) {
|
|
|
|
|
srcY = rect->top;
|
|
|
|
|
dist = -dist; /* make it positive */
|
|
|
|
|
destY = srcY + dist;
|
|
|
|
|
} else {
|
|
|
|
|
destY = rect->top;
|
|
|
|
|
srcY = destY + dist;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
success = FALSE != BitBlt( globals->hdc, /* HDC hdcDest, */
|
|
|
|
|
rect->left, /* int nXDest */
|
|
|
|
|
destY,
|
|
|
|
|
rect->width, /* width */
|
|
|
|
|
rect->height - dist, /* int nHeight */
|
|
|
|
|
globals->hdc, /* HDC hdcSrc */
|
|
|
|
|
rect->left, /* int nXSrc */
|
|
|
|
|
srcY,
|
|
|
|
|
SRCCOPY ); /* DWORD dwRop */
|
|
|
|
|
/* need to return the rect that must still be redrawn */
|
|
|
|
|
if ( success ) {
|
|
|
|
|
if ( !down ) {
|
|
|
|
|
rect->top += rect->height - dist;
|
2006-06-22 06:59:18 +02:00
|
|
|
|
}
|
2006-06-24 03:22:10 +02:00
|
|
|
|
rect->height = dist;
|
2006-06-22 06:59:18 +02:00
|
|
|
|
}
|
2006-06-24 03:22:10 +02:00
|
|
|
|
return success;
|
2006-04-01 23:01:20 +02:00
|
|
|
|
}
|
2006-06-22 06:59:18 +02:00
|
|
|
|
#else /* #ifdef DRAW_LINK_DIRECT */
|
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
|
|
|
|
|
2004-03-28 03:14:34 +02:00
|
|
|
|
void
|
2008-09-01 17:10:28 +02:00
|
|
|
|
ce_draw_update( CEDrawCtx* dctx )
|
2003-11-20 17:26:35 +01:00
|
|
|
|
{
|
2008-10-07 06:00:37 +02:00
|
|
|
|
XP_U16 ii;
|
2004-03-28 03:14:34 +02:00
|
|
|
|
|
2008-10-07 06:00:37 +02:00
|
|
|
|
for ( ii = 0; ii < CE_NUM_COLORS; ++ii ) {
|
|
|
|
|
if ( !!dctx->brushes[ii] ) {
|
|
|
|
|
DeleteObject( dctx->brushes[ii] );
|
2004-03-28 03:14:34 +02:00
|
|
|
|
}
|
2008-10-07 06:00:37 +02:00
|
|
|
|
dctx->brushes[ii] = CreateSolidBrush(dctx->globals->appPrefs.colors[ii]);
|
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
|
|
|
|
|
2008-10-01 10:31:43 +02:00
|
|
|
|
static void
|
|
|
|
|
drawColoredRect( CEDrawCtx* dctx, const RECT* invalR, XP_U16 index )
|
|
|
|
|
{
|
|
|
|
|
CEAppGlobals* globals = dctx->globals;
|
|
|
|
|
FillRect( globals->hdc, invalR, dctx->brushes[index] );
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-01 17:10:28 +02:00
|
|
|
|
void
|
|
|
|
|
ce_draw_erase( CEDrawCtx* dctx, const RECT* invalR )
|
|
|
|
|
{
|
2008-10-01 10:31:43 +02:00
|
|
|
|
drawColoredRect( dctx, invalR, CE_BKG_COLOR );
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ce_draw_focus( CEDrawCtx* dctx, const RECT* invalR )
|
|
|
|
|
{
|
|
|
|
|
drawColoredRect( dctx, invalR, CE_FOCUS_COLOR );
|
2008-09-01 17:10:28 +02:00
|
|
|
|
}
|
|
|
|
|
|
2008-10-07 06:00:37 +02:00
|
|
|
|
#ifndef _WIN32_WCE
|
|
|
|
|
HBRUSH
|
|
|
|
|
ce_draw_getFocusBrush( const CEDrawCtx* dctx )
|
|
|
|
|
{
|
|
|
|
|
return dctx->brushes[CE_FOCUS_COLOR];
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
2008-09-01 17:10:28 +02:00
|
|
|
|
CEDrawCtx*
|
2003-11-20 17:26:35 +01:00
|
|
|
|
ce_drawctxt_make( MPFORMAL HWND mainWin, CEAppGlobals* globals )
|
|
|
|
|
{
|
|
|
|
|
CEDrawCtx* dctx = (CEDrawCtx*)XP_MALLOC( mpool,
|
|
|
|
|
sizeof(*dctx) );
|
2008-07-20 18:33:19 +02:00
|
|
|
|
XP_MEMSET( dctx, 0, sizeof(*dctx) );
|
2006-05-30 07:12:02 +02:00
|
|
|
|
MPASSIGN(dctx->mpool, mpool);
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
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 );
|
2008-09-05 14:11:37 +02:00
|
|
|
|
SET_VTABLE_ENTRY( dctx->vtable, draw_dictChanged, ce );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
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_trayBegin, 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 );
|
2007-01-19 09:24:02 +01:00
|
|
|
|
|
|
|
|
|
SET_VTABLE_ENTRY( dctx->vtable, draw_objFinished, ce );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
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 );
|
2006-04-01 23:01:20 +02:00
|
|
|
|
#endif
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
dctx->mainWin = mainWin;
|
|
|
|
|
dctx->globals = globals;
|
|
|
|
|
|
2008-09-01 17:10:28 +02:00
|
|
|
|
ce_draw_update( dctx );
|
2003-11-20 17:26:35 +01:00
|
|
|
|
|
|
|
|
|
dctx->rightArrow = LoadBitmap( globals->hInst,
|
|
|
|
|
MAKEINTRESOURCE(IDB_RIGHTARROW) );
|
|
|
|
|
dctx->downArrow = LoadBitmap( globals->hInst,
|
|
|
|
|
MAKEINTRESOURCE(IDB_DOWNARROW) );
|
|
|
|
|
dctx->origin = LoadBitmap( globals->hInst,
|
|
|
|
|
MAKEINTRESOURCE(IDB_ORIGIN) );
|
|
|
|
|
|
2008-09-01 17:10:28 +02:00
|
|
|
|
return dctx;
|
2003-11-20 17:26:35 +01:00
|
|
|
|
} /* ce_drawctxt_make */
|
2008-09-10 14:18:30 +02:00
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
ce_draw_toStream( const CEDrawCtx* dctx, XWStreamCtxt* stream )
|
|
|
|
|
{
|
|
|
|
|
XP_U16 ii;
|
|
|
|
|
|
|
|
|
|
stream_putU8( stream, N_RESIZE_FONTS );
|
|
|
|
|
for ( ii = 0; ii < N_RESIZE_FONTS; ++ii ) {
|
|
|
|
|
const FontCacheEntry* fce = &dctx->fcEntry[ii];
|
2008-10-11 18:53:22 +02:00
|
|
|
|
XP_LOGF( "saving indexHt: %d, lfHeight: %d, offset: %d, glyphHt: %d "
|
|
|
|
|
"for %s", fce->indexHt, fce->lfHeight, fce->offset,
|
|
|
|
|
fce->glyphHt, RFI2Str(ii) );
|
2008-09-13 17:24:23 +02:00
|
|
|
|
stream_putU8( stream, fce->indexHt );
|
2008-10-11 18:53:22 +02:00
|
|
|
|
if ( fce->indexHt > 0 ) {
|
|
|
|
|
stream_putU8( stream, fce->lfHeight );
|
|
|
|
|
stream_putU8( stream, fce->offset );
|
|
|
|
|
stream_putU8( stream, fce->glyphHt );
|
|
|
|
|
}
|
2008-09-10 14:18:30 +02:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2008-09-13 17:24:23 +02:00
|
|
|
|
//#define DROP_CACHE
|
2008-09-10 14:18:30 +02:00
|
|
|
|
void
|
|
|
|
|
ce_draw_fromStream( CEDrawCtx* dctx, XWStreamCtxt* stream )
|
|
|
|
|
{
|
|
|
|
|
XP_U16 ii;
|
|
|
|
|
XP_U16 nEntries;
|
|
|
|
|
|
|
|
|
|
ceClearFontCache( dctx ); /* no leaking! */
|
|
|
|
|
|
|
|
|
|
nEntries = (XP_U16)stream_getU8( stream );
|
|
|
|
|
|
|
|
|
|
for ( ii = 0; ii < nEntries; ++ii ) {
|
|
|
|
|
FontCacheEntry fce;
|
|
|
|
|
|
2008-09-13 17:24:23 +02:00
|
|
|
|
fce.indexHt = (XP_U16)stream_getU8( stream );
|
2008-10-11 18:53:22 +02:00
|
|
|
|
if ( fce.indexHt > 0 ) {
|
|
|
|
|
fce.lfHeight = (XP_U16)stream_getU8( stream );
|
|
|
|
|
fce.offset = (XP_U16)stream_getU8( stream );
|
|
|
|
|
fce.glyphHt = (XP_U16)stream_getU8( stream );
|
|
|
|
|
|
|
|
|
|
/* We need to read from the file no matter how many entries, but
|
|
|
|
|
only populate what we have room for -- in case N_RESIZE_FONTS
|
|
|
|
|
was different when file written. */
|
2008-09-13 17:24:23 +02:00
|
|
|
|
#ifndef DROP_CACHE
|
2008-10-11 18:53:22 +02:00
|
|
|
|
if ( ii < N_RESIZE_FONTS ) {
|
|
|
|
|
LOGFONT fontInfo;
|
|
|
|
|
|
|
|
|
|
XP_LOGF( "read indexHt: %d, lfHeight: %d, offset: %d, "
|
|
|
|
|
"glyphHt: %d for %s", fce.indexHt, fce.lfHeight,
|
|
|
|
|
fce.offset, fce.glyphHt, RFI2Str(ii) );
|
|
|
|
|
ceFillFontInfo( dctx, &fontInfo, fce.lfHeight );
|
|
|
|
|
fce.setFont = CreateFontIndirect( &fontInfo );
|
|
|
|
|
XP_ASSERT( !!fce.setFont );
|
|
|
|
|
|
|
|
|
|
XP_MEMCPY( &dctx->fcEntry[ii], &fce, sizeof(dctx->fcEntry[ii]) );
|
|
|
|
|
}
|
2008-09-13 17:24:23 +02:00
|
|
|
|
#endif
|
2008-10-11 18:53:22 +02:00
|
|
|
|
}
|
2008-09-10 14:18:30 +02:00
|
|
|
|
}
|
2008-09-28 19:50:04 +02:00
|
|
|
|
} /* ce_draw_fromStream */
|