mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2024-12-28 09:58:30 +01:00
In case where board can't fully fill screen, track the rects on either
side and erase them when they're invalidated. When seeking best-fit font, pull glyphs to measure from dictionary rather than assuming A-Z. Speed font measuring code by passing over all glyphs only once, noting tallest and lowest-extending then measuring only those two as smaller sizes are tried. This *may* make the process fast enough that I don't need to cache the information across boots: need to try on real hardware.
This commit is contained in:
parent
69f667fba3
commit
34c4bdab9a
3 changed files with 337 additions and 99 deletions
|
@ -38,6 +38,8 @@
|
|||
#define DRAW_FUNC_NAME(nam) ce_draw_ ## nam
|
||||
#endif
|
||||
|
||||
//#define MEASURE_OLD_WAY
|
||||
|
||||
#define CE_MINI_V_PADDING 6
|
||||
#define CE_MINIW_PADDING 0
|
||||
#define CE_SCORE_PADDING -3
|
||||
|
@ -53,6 +55,28 @@
|
|||
# define TREAT_AS_CURSOR(d,f) (((f) & CELL_ISCURSOR) != 0)
|
||||
#endif
|
||||
|
||||
|
||||
typedef enum {
|
||||
RFONTS_TRAY
|
||||
,RFONTS_TRAYVAL
|
||||
,RFONTS_CELL
|
||||
,RFONTS_PTS
|
||||
|
||||
,N_RESIZE_FONTS
|
||||
} RFIndex;
|
||||
|
||||
typedef struct _PenColorPair {
|
||||
COLORREF ref;
|
||||
HGDIOBJ pen;
|
||||
} PenColorPair;
|
||||
|
||||
typedef struct _FontCacheEntry {
|
||||
HFONT setFont;
|
||||
XP_U16 setFontHt;
|
||||
XP_U16 offset;
|
||||
XP_U16 actualHt;
|
||||
} FontCacheEntry;
|
||||
|
||||
struct CEDrawCtx {
|
||||
DrawCtxVTable* vtable;
|
||||
|
||||
|
@ -86,6 +110,7 @@ struct CEDrawCtx {
|
|||
static void ceClearToBkground( CEDrawCtx* dctx, const XP_Rect* rect );
|
||||
static void ceDrawBitmapInRect( HDC hdc, const RECT* r, HBITMAP bitmap );
|
||||
static void ceClipToRect( HDC hdc, const RECT* rt );
|
||||
static void ceClearFontCache( CEDrawCtx* dctx );
|
||||
|
||||
static void
|
||||
XPRtoRECT( RECT* rt, const XP_Rect* xprect )
|
||||
|
@ -243,6 +268,147 @@ ERROR
|
|||
#endif
|
||||
} /* ceClipToRect */
|
||||
|
||||
static void
|
||||
makeTestBuf( CEDrawCtx* dctx, XP_UCHAR* buf, XP_UCHAR bufLen, RFIndex index )
|
||||
{
|
||||
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;
|
||||
XP_ASSERT( !!dict && nFaces < bufLen );
|
||||
if ( dict_hasBlankTile(dict) ) {
|
||||
blank = dict_getBlankTile( dict );
|
||||
}
|
||||
for ( tile = 0; tile < nFaces; ++tile ) {
|
||||
if ( tile != blank ) {
|
||||
tiles[nOut++] = tile;
|
||||
}
|
||||
}
|
||||
(void)dict_tilesToString( dict, tiles, nOut, buf, bufLen );
|
||||
}
|
||||
break;
|
||||
case RFONTS_TRAYVAL:
|
||||
strcpy( buf, "0" ); /* all numbers the same :-) */
|
||||
break;
|
||||
case RFONTS_PTS:
|
||||
strcpy( buf, "Pts:0?" );
|
||||
break;
|
||||
case N_RESIZE_FONTS:
|
||||
XP_ASSERT(0);
|
||||
}
|
||||
XP_LOGF( "%s=>%s", __func__, buf );
|
||||
} /* makeTestBuf */
|
||||
|
||||
#ifndef MEASURE_OLD_WAY
|
||||
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 */
|
||||
for ( done = XP_FALSE, yy = size.cy - 1; yy > maxBottomSeen && !done; --yy ) {
|
||||
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
|
||||
ceMeasureGlyphs( CEDrawCtx* dctx, HDC hdc, /* HFONT font, */wchar_t* str,
|
||||
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;
|
||||
|
||||
ceMeasureGlyph( hdc, white, str[ii],
|
||||
minTopSeen, maxBottomSeen,
|
||||
&thisTop, &thisBottom );
|
||||
if ( thisBottom > maxBottomSeen ) {
|
||||
maxBottomSeen = thisBottom;
|
||||
maxBottomIndex = ii;
|
||||
}
|
||||
if ( thisTop < minTopSeen ) {
|
||||
minTopSeen = thisTop;
|
||||
minTopIndex = ii;
|
||||
}
|
||||
}
|
||||
|
||||
/* XP_LOGF( "offset: %d; height: %d", minTopSeen, maxBottomSeen - minTopSeen + 1 ); */
|
||||
/* XP_LOGF( "offset came from %d; height from %d", minTopIndex, maxBottomIndex ); */
|
||||
*hasMinTop = minTopIndex;
|
||||
*hasMaxBottom = maxBottomIndex;
|
||||
} /* ceMeasureGlyphs */
|
||||
#endif
|
||||
|
||||
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) );
|
||||
}
|
||||
|
||||
#ifdef MEASURE_OLD_WAY
|
||||
static void
|
||||
ceMeasureTextHt( HFONT font, const char* str, XP_U16* ht, XP_U16* offset )
|
||||
{
|
||||
|
@ -325,27 +491,121 @@ ceMeasureTextHt( HFONT font, const char* str, XP_U16* ht, XP_U16* offset )
|
|||
*ht = lastLine - firstLine + 1;
|
||||
/* XP_LOGF( "%s(%s)=>ht: %d; offset: %d", __func__, str, *ht, *offset ); */
|
||||
} /* ceMeasureTextHt */
|
||||
#endif
|
||||
|
||||
static void
|
||||
makeTestBuf( CEDrawCtx* XP_UNUSED(dctx), XP_UCHAR* buf,
|
||||
XP_UCHAR XP_UNUSED(bufLen), RFIndex index )
|
||||
ceBestFitFont( CEDrawCtx* dctx, XP_U16 soughtHeight, RFIndex index,
|
||||
FontCacheEntry* fce )
|
||||
{
|
||||
switch( index ) {
|
||||
case RFONTS_TRAY:
|
||||
case RFONTS_CELL:
|
||||
/* build this from dictioanary */
|
||||
strcpy( buf, "ABCDEFGHIJKLMNOPQRSTUVWXYZ" );
|
||||
break;
|
||||
case RFONTS_TRAYVAL:
|
||||
strcpy( buf, "0" ); /* all numbers the same :-) */
|
||||
break;
|
||||
case RFONTS_PTS:
|
||||
strcpy( buf, "Pts:0?" );
|
||||
break;
|
||||
case N_RESIZE_FONTS:
|
||||
XP_ASSERT(0);
|
||||
#ifdef MEASURE_OLD_WAY
|
||||
HFONT font;
|
||||
LOGFONT fontInfo;
|
||||
char buf[65];
|
||||
XP_U16 offset;
|
||||
XP_U16 actualHt;
|
||||
XP_U16 trialHt;
|
||||
|
||||
/* XP_LOGF( "%s: calculating for index: %d; height: %d", */
|
||||
/* __func__, index, height ); */
|
||||
|
||||
makeTestBuf( dctx, buf, VSIZE(buf), index );
|
||||
|
||||
for ( trialHt = soughtHeight; ; /*++trialHt*/ ) {
|
||||
XP_MEMSET( &fontInfo, 0, sizeof(fontInfo) );
|
||||
fontInfo.lfHeight = trialHt;
|
||||
HFONT testFont = CreateFontIndirect( &fontInfo );
|
||||
XP_U16 testOffset, testHt;
|
||||
|
||||
/* XP_LOGF( "%s: looking for ht %d with testht %d", __func__, height, trialHt ); */
|
||||
ceMeasureTextHt( testFont, buf, &testHt, &testOffset );
|
||||
if ( testHt > soughtHeight ) {
|
||||
/* we've gone too far, so choose last that fit!!! */
|
||||
XP_ASSERT( !!font );
|
||||
DeleteObject( testFont );
|
||||
break;
|
||||
/* } else if ( trialHt == height /\* first time through *\/ */
|
||||
/* && testOffset > 0 ) { /\* for safety *\/ */
|
||||
/* trialHt += testOffset; */
|
||||
} else {
|
||||
++trialHt;
|
||||
}
|
||||
DeleteObject( font );
|
||||
font = testFont;
|
||||
offset = testOffset;
|
||||
actualHt = testHt;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !!fce->setFont ) {
|
||||
DeleteObject( fce->setFont );
|
||||
}
|
||||
|
||||
fce->setFont = font;
|
||||
fce->setFontHt = soughtHeight;
|
||||
fce->offset = offset;
|
||||
fce->actualHt = actualHt;
|
||||
#else
|
||||
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;
|
||||
|
||||
XP_LOGF( "%s(index=%d)", __func__, index );
|
||||
|
||||
char sample[65];
|
||||
makeTestBuf( dctx, sample, VSIZE(sample), index );
|
||||
len = strlen(sample);
|
||||
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, sample, len,
|
||||
widebuf, len );
|
||||
|
||||
memBM = CreateCompatibleBitmap( memDC, 64, 64 );
|
||||
SelectObject( memDC, memBM );
|
||||
|
||||
for ( firstPass = XP_TRUE, testSize = soughtHeight*2; ; --testSize ) {
|
||||
LOGFONT fontInfo;
|
||||
XP_MEMSET( &fontInfo, 0, sizeof(fontInfo) );
|
||||
fontInfo.lfHeight = testSize;
|
||||
HFONT testFont = CreateFontIndirect( &fontInfo );
|
||||
if ( !!testFont ) {
|
||||
XP_U16 thisHeight, top, bottom;
|
||||
|
||||
SelectObject( memDC, testFont );
|
||||
|
||||
/* first time, measure all of them to determine which chars have
|
||||
high and low points */
|
||||
if ( firstPass ) {
|
||||
ceMeasureGlyphs( dctx, memDC, widebuf, &hasMinTop,
|
||||
&hasMaxBottom );
|
||||
firstPass = XP_FALSE;
|
||||
}
|
||||
/* Thereafter, just measure the two we know about */
|
||||
ceMeasureGlyph( memDC, white, sample[hasMinTop], 1000, 0,
|
||||
&top, &bottom );
|
||||
ceMeasureGlyph( memDC, white, sample[hasMaxBottom],
|
||||
top, bottom, &top, &bottom );
|
||||
thisHeight = bottom - top + 1;
|
||||
|
||||
if ( thisHeight <= soughtHeight ) { /* got it!!! */
|
||||
fce->setFont = testFont;
|
||||
fce->setFontHt = soughtHeight;
|
||||
fce->offset = top;
|
||||
fce->actualHt = thisHeight;
|
||||
XP_LOGF( "Looking for %d; PICKED %d",
|
||||
soughtHeight, thisHeight );
|
||||
break;
|
||||
}
|
||||
DeleteObject( testFont );
|
||||
XP_LOGF( "Looking for %d; rejected %d", soughtHeight, thisHeight );
|
||||
}
|
||||
}
|
||||
|
||||
DeleteObject( memBM );
|
||||
DeleteDC( memDC );
|
||||
#endif
|
||||
} /* ceBestFitFont */
|
||||
|
||||
static HFONT
|
||||
ceGetSizedFont( CEDrawCtx* dctx, XP_U16 height, RFIndex index,
|
||||
|
@ -354,51 +614,7 @@ ceGetSizedFont( CEDrawCtx* dctx, XP_U16 height, RFIndex index,
|
|||
FontCacheEntry* fce = &dctx->fcEntry[index];
|
||||
if ( (0 != height) /* 0 means use what we have */
|
||||
&& fce->setFontHt != height ) {
|
||||
HFONT font;
|
||||
LOGFONT fontInfo;
|
||||
char buf[65];
|
||||
XP_U16 offset;
|
||||
XP_U16 actualHt;
|
||||
XP_U16 trialHt;
|
||||
|
||||
XP_LOGF( "%s: calculating for index: %d; height: %d",
|
||||
__func__, index, height );
|
||||
|
||||
makeTestBuf( dctx, buf, VSIZE(buf), index );
|
||||
|
||||
for ( trialHt = height; ; /*++trialHt*/ ) {
|
||||
XP_MEMSET( &fontInfo, 0, sizeof(fontInfo) );
|
||||
fontInfo.lfHeight = trialHt;
|
||||
HFONT testFont = CreateFontIndirect( &fontInfo );
|
||||
XP_U16 testOffset, testHt;
|
||||
|
||||
/* XP_LOGF( "%s: looking for ht %d with testht %d", __func__, height, trialHt ); */
|
||||
ceMeasureTextHt( testFont, buf, &testHt, &testOffset );
|
||||
if ( testHt > height ) {
|
||||
/* we've gone too far, so choose last that fit!!! */
|
||||
XP_ASSERT( !!font );
|
||||
DeleteObject( testFont );
|
||||
break;
|
||||
/* } else if ( trialHt == height /\* first time through *\/ */
|
||||
/* && testOffset > 0 ) { /\* for safety *\/ */
|
||||
/* trialHt += testOffset; */
|
||||
} else {
|
||||
++trialHt;
|
||||
}
|
||||
DeleteObject( font );
|
||||
font = testFont;
|
||||
offset = testOffset;
|
||||
actualHt = testHt;
|
||||
}
|
||||
|
||||
if ( !!fce->setFont ) {
|
||||
DeleteObject( fce->setFont );
|
||||
}
|
||||
|
||||
fce->setFont = font;
|
||||
fce->setFontHt = height;
|
||||
fce->offset = offset;
|
||||
fce->actualHt = actualHt;
|
||||
ceBestFitFont( dctx, height, index, fce );
|
||||
}
|
||||
|
||||
if ( !!offsetP ) {
|
||||
|
@ -407,9 +623,9 @@ ceGetSizedFont( CEDrawCtx* dctx, XP_U16 height, RFIndex index,
|
|||
if ( !!actualHtP ) {
|
||||
*actualHtP = fce->actualHt;
|
||||
}
|
||||
XP_ASSERT( !!fce->setFont );
|
||||
XP_ASSERT( !!fce->setFont ); /* failing... */
|
||||
return fce->setFont;
|
||||
}
|
||||
} /* ceGetSizedFont */
|
||||
|
||||
#if 0
|
||||
/* I'm trying to measure individual chars, but GetGlyphOutline and
|
||||
|
@ -516,7 +732,7 @@ DRAW_FUNC_NAME(boardBegin)( DrawCtx* p_dctx,
|
|||
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
||||
CEAppGlobals* globals = dctx->globals;
|
||||
HDC hdc = globals->hdc;
|
||||
XP_Bool canDraw = !!hdc;
|
||||
XP_Bool canDraw = !!hdc && !!dctx->dict;
|
||||
if ( canDraw ) {
|
||||
dctx->prevBkColor = GetBkColor( hdc );
|
||||
dctx->topFocus = dfs == DFS_TOP;
|
||||
|
@ -722,7 +938,7 @@ DRAW_FUNC_NAME(trayBegin)( DrawCtx* p_dctx, const XP_Rect* XP_UNUSED(rect),
|
|||
CEDrawCtx* dctx = (CEDrawCtx*)p_dctx;
|
||||
CEAppGlobals* globals = dctx->globals;
|
||||
HDC hdc = globals->hdc;
|
||||
XP_Bool canDraw = !!hdc;
|
||||
XP_Bool canDraw = !!hdc && !!dctx->dict;
|
||||
if ( canDraw ) {
|
||||
dctx->trayOwner = owner;
|
||||
dctx->topFocus = dfs == DFS_TOP;
|
||||
|
@ -1352,11 +1568,7 @@ DRAW_FUNC_NAME(destroyCtxt)( DrawCtx* p_dctx )
|
|||
|
||||
DeleteObject( dctx->playerFont );
|
||||
DeleteObject( dctx->selPlayerFont );
|
||||
for ( i = 0; i < N_RESIZE_FONTS; ++i ) {
|
||||
if ( !!dctx->fcEntry[i].setFont ) {
|
||||
DeleteObject( dctx->fcEntry[i].setFont );
|
||||
}
|
||||
}
|
||||
ceClearFontCache( dctx );
|
||||
|
||||
DeleteObject( dctx->rightArrow );
|
||||
DeleteObject( dctx->downArrow );
|
||||
|
|
|
@ -418,6 +418,8 @@ hideScroller( CEAppGlobals* globals )
|
|||
#endif
|
||||
|
||||
typedef struct CEBoardParms {
|
||||
XP_U16 scrnWidth;
|
||||
|
||||
XP_U16 boardHScale;
|
||||
XP_U16 boardVScale;
|
||||
XP_U16 boardTop;
|
||||
|
@ -468,7 +470,7 @@ figureBoardParms( CEAppGlobals* globals, XP_U16 nRows, CEBoardParms* bparms )
|
|||
{
|
||||
RECT rc;
|
||||
XP_U16 scrnWidth, scrnHeight;
|
||||
XP_U16 trayVScale, boardLeft, scoreWidth, scoreHeight;
|
||||
XP_U16 trayVScale, boardLeft, trayLeft, scoreWidth, scoreHeight;
|
||||
XP_U16 boardHt, boardWidth, hScale, vScale, nVisibleRows;
|
||||
XP_U16 trayTop, boardTop;
|
||||
XP_Bool horiz;
|
||||
|
@ -511,6 +513,7 @@ figureBoardParms( CEAppGlobals* globals, XP_U16 nRows, CEBoardParms* bparms )
|
|||
}
|
||||
|
||||
boardWidth = scrnWidth - scrollWidth;
|
||||
trayWidth = scrnWidth;
|
||||
if ( horiz ) {
|
||||
scoreWidth = scrnWidth;
|
||||
hScale = boardWidth / nRows;
|
||||
|
@ -518,14 +521,16 @@ figureBoardParms( CEAppGlobals* globals, XP_U16 nRows, CEBoardParms* bparms )
|
|||
/* center the board */
|
||||
boardWidth += scrollWidth;
|
||||
boardLeft = (scrnWidth - boardWidth) / 2; /* center it all */
|
||||
trayLeft = 0;
|
||||
} else {
|
||||
/* move extra pixels into scoreboard */
|
||||
hScale = (boardWidth - CE_MIN_SCORE_WIDTH) / nRows;
|
||||
boardWidth = hScale * nRows;
|
||||
scoreWidth = scrnWidth - boardWidth - scrollWidth;
|
||||
boardLeft = scoreWidth;
|
||||
trayLeft = scoreWidth;
|
||||
trayWidth -= scoreWidth;
|
||||
}
|
||||
trayWidth = boardWidth + scrollWidth;
|
||||
|
||||
trayTop = boardHt + scoreHeight + 1;
|
||||
trayVScale = scrnHeight - trayTop;
|
||||
|
@ -551,6 +556,7 @@ figureBoardParms( CEAppGlobals* globals, XP_U16 nRows, CEBoardParms* bparms )
|
|||
}
|
||||
}
|
||||
|
||||
bparms->scrnWidth = scrnWidth;
|
||||
bparms->boardHScale = hScale;
|
||||
bparms->boardVScale = vScale;
|
||||
bparms->boardTop = boardTop;
|
||||
|
@ -558,7 +564,7 @@ figureBoardParms( CEAppGlobals* globals, XP_U16 nRows, CEBoardParms* bparms )
|
|||
bparms->trayHeight = trayVScale;
|
||||
bparms->trayWidth = trayWidth;
|
||||
bparms->boardLeft = boardLeft;
|
||||
bparms->trayLeft = boardLeft;
|
||||
bparms->trayLeft = trayLeft;
|
||||
bparms->scoreWidth = scoreWidth;
|
||||
bparms->scoreHeight = scoreHeight;
|
||||
bparms->horiz = horiz;
|
||||
|
@ -578,6 +584,30 @@ figureBoardParms( CEAppGlobals* globals, XP_U16 nRows, CEBoardParms* bparms )
|
|||
#endif
|
||||
} /* figureBoardParms */
|
||||
|
||||
static void
|
||||
setOwnedRects( CEAppGlobals* globals, XP_U16 nRows,
|
||||
const CEBoardParms* bparms )
|
||||
{
|
||||
if ( bparms->horiz ) {
|
||||
RECT tmp;
|
||||
|
||||
tmp.top = bparms->scoreHeight; /* Same for both */
|
||||
tmp.bottom = bparms->trayTop; /* Same for both */
|
||||
|
||||
tmp.left = 0;
|
||||
tmp.right = bparms->boardLeft;
|
||||
XP_MEMCPY( &globals->ownedRects[OWNED_RECT_LEFT], &tmp,
|
||||
sizeof(globals->ownedRects[OWNED_RECT_LEFT]) );
|
||||
|
||||
tmp.left = tmp.right + (bparms->boardHScale * nRows);
|
||||
tmp.right = bparms->scrnWidth;
|
||||
XP_MEMCPY( &globals->ownedRects[OWNED_RECT_RIGHT], &tmp,
|
||||
sizeof(globals->ownedRects[OWNED_RECT_RIGHT]) );
|
||||
} else {
|
||||
XP_MEMSET( &globals->ownedRects, 0, sizeof(globals->ownedRects) );
|
||||
}
|
||||
} /* setOwnedRects */
|
||||
|
||||
static XP_Bool
|
||||
cePositionBoard( CEAppGlobals* globals )
|
||||
{
|
||||
|
@ -590,6 +620,7 @@ cePositionBoard( CEAppGlobals* globals )
|
|||
XP_ASSERT( nCols <= CE_MAX_ROWS );
|
||||
|
||||
figureBoardParms( globals, nCols, &bparms );
|
||||
setOwnedRects( globals, nCols, &bparms );
|
||||
|
||||
if ( globals->gameInfo.timerEnabled ) {
|
||||
board_setTimerLoc( globals->game.board, bparms.timerLeft,
|
||||
|
@ -668,6 +699,7 @@ ceInitAndStartBoard( CEAppGlobals* globals, XP_Bool newGame,
|
|||
const CommsAddrRec* XP_UNUSED_STANDALONE(addr) )
|
||||
{
|
||||
DictionaryCtxt* dict;
|
||||
DictionaryCtxt* toBeDestroyed = NULL;
|
||||
XP_UCHAR* newDictName = globals->gameInfo.dictName;
|
||||
|
||||
/* This needs to happen even when !newGame because it's how the dict
|
||||
|
@ -680,7 +712,7 @@ ceInitAndStartBoard( CEAppGlobals* globals, XP_Bool newGame,
|
|||
const XP_UCHAR* curDictName = dict_getName( dict );
|
||||
if ( !!newDictName &&
|
||||
( !curDictName || 0 != strcmp( curDictName, newDictName ) ) ) {
|
||||
dict_destroy( dict );
|
||||
toBeDestroyed = dict;
|
||||
dict = NULL;
|
||||
} else {
|
||||
replaceStringIfDifferent( globals->mpool,
|
||||
|
@ -737,6 +769,10 @@ ceInitAndStartBoard( CEAppGlobals* globals, XP_Bool newGame,
|
|||
server_do( globals->game.server );
|
||||
|
||||
globals->isNewGame = FALSE;
|
||||
|
||||
if ( !!toBeDestroyed ) {
|
||||
dict_destroy( toBeDestroyed );
|
||||
}
|
||||
} /* ceInitAndStartBoard */
|
||||
|
||||
#ifdef DEBUG
|
||||
|
@ -1385,7 +1421,14 @@ drawInsidePaint( CEAppGlobals* globals, const RECT* invalR )
|
|||
globals->hdc = hdc;
|
||||
|
||||
if ( !!invalR ) {
|
||||
ce_draw_erase( globals->draw, invalR );
|
||||
XP_U16 ii;
|
||||
for ( ii = 0; ii < N_OWNED_RECTS; ++ii ) {
|
||||
RECT interR;
|
||||
if ( IntersectRect( &interR, invalR,
|
||||
&globals->ownedRects[ii] ) ) {
|
||||
ce_draw_erase( globals->draw, &interR );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
board_draw( globals->game.board );
|
||||
|
|
|
@ -85,7 +85,10 @@ typedef struct CEAppPrefs {
|
|||
XP_Bool fullScreen;
|
||||
} CEAppPrefs;
|
||||
|
||||
#define NUM_BUTTONS 4
|
||||
enum { OWNED_RECT_LEFT
|
||||
,OWNED_RECT_RIGHT
|
||||
,N_OWNED_RECTS
|
||||
};
|
||||
|
||||
typedef struct CEAppGlobals {
|
||||
HINSTANCE hInst;
|
||||
|
@ -95,8 +98,6 @@ typedef struct CEAppGlobals {
|
|||
HWND hwndCB;
|
||||
#endif
|
||||
|
||||
HWND buttons[NUM_BUTTONS];
|
||||
|
||||
#ifdef _WIN32_WCE
|
||||
SHACTIVATEINFO sai;
|
||||
XW_WinceVersion winceVersion;
|
||||
|
@ -121,6 +122,8 @@ typedef struct CEAppGlobals {
|
|||
void* timerClosures[NUM_TIMERS_PLUS_ONE];
|
||||
XP_U32 timerWhens[NUM_TIMERS_PLUS_ONE];
|
||||
|
||||
RECT ownedRects[N_OWNED_RECTS];
|
||||
|
||||
XP_U16 flags; /* bits defined below */
|
||||
|
||||
#ifdef CEFEATURE_CANSCROLL
|
||||
|
@ -160,26 +163,6 @@ enum {
|
|||
|
||||
#define CE_NUM_EDITABLE_COLORS CE_BLACK_COLOR
|
||||
|
||||
typedef enum {
|
||||
RFONTS_TRAY
|
||||
,RFONTS_TRAYVAL
|
||||
,RFONTS_CELL
|
||||
,RFONTS_PTS
|
||||
|
||||
,N_RESIZE_FONTS
|
||||
} RFIndex;
|
||||
|
||||
typedef struct _PenColorPair {
|
||||
COLORREF ref;
|
||||
HGDIOBJ pen;
|
||||
} PenColorPair;
|
||||
|
||||
typedef struct _FontCacheEntry {
|
||||
HFONT setFont;
|
||||
XP_U16 setFontHt;
|
||||
XP_U16 offset;
|
||||
XP_U16 actualHt;
|
||||
} FontCacheEntry;
|
||||
|
||||
int messageBoxChar( CEAppGlobals* globals, XP_UCHAR* str, wchar_t* title,
|
||||
XP_U16 buttons );
|
||||
|
|
Loading…
Reference in a new issue