/* -*-mode: C; fill-column: 78; c-basic-offset: 4;-*- */ /* * Copyright 2000-2002 by Eric House (fixin@peak.org). All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* #include */ /* #include */ #include #include /* for sprintf, etc. */ #include "xptypes.h" #include "board.h" #include "draw.h" #include "mempool.h" #include "cemain.h" #include "cedict.h" #include "cedefines.h" static void ceClearToBkground( CEDrawCtx* dctx, XP_Rect* rect ); static void ceDrawBitmapInRect( HDC hdc, XP_U32 x, XP_U32 y, HBITMAP bitmap ); static void XPRtoRECT( RECT* rt, XP_Rect* xprect ) { rt->left = xprect->left; rt->top = xprect->top; rt->right = rt->left + xprect->width; rt->bottom = rt->top + xprect->height; } /* XPRtoRECT */ static void makeAndDrawBitmap( CEDrawCtx* dctx, HDC hdc, XP_U32 x, XP_U32 y, COLORREF foreRef, CEBitmapInfo* info ) { #if 1 POINT points[2]; HGDIOBJ forePen; XP_U16 nCols, nRows, row, col, rowBytes; XP_UCHAR* bits = info->bits; HGDIOBJ oldObj; forePen = CreatePen( PS_SOLID, 1, foreRef ); oldObj = SelectObject( hdc, forePen ); nRows = info->nRows; nCols = info->nCols; rowBytes = (nCols + 7) / 8; while ( (rowBytes % 2) != 0 ) { ++rowBytes; } for ( row = 0; row < nRows; ++row ) { for ( col = 0; col < nCols; ++col ) { XP_UCHAR byt = bits[col / 8]; XP_Bool set = (byt & (0x80 >> (col % 8))) != 0; if ( set ) { points[0].x = x + col; points[0].y = y + row; points[1].x = x + col + 1; points[1].y = y + row + 1; Polyline( hdc, points, 2 ); } } bits += rowBytes; } SelectObject( hdc, oldObj ); DeleteObject( forePen ); #else /* I can't get this to work.... */ HBITMAP bm; bm = CreateBitmap( info->nCols, info->nRows, 1, 1, info->bits ); ceDrawBitmapInRect( hdc, rt->left+2, rt->top+2, bm ); DeleteObject( bm ); #endif } /* makeAndDrawBitmap */ #if 0 static void drawBitmapAt( HDC hdc, CEBitmapInfo* bmp, RECT* rt ) { HDC tmpHDC; HBITMAP bitmap = bmp->bitmap; RECT r = *rt; HBRUSH brush; HBRUSH oldBrush; tmpHDC = CreateCompatibleDC( hdc ); SelectObject( tmpHDC, bitmap ); r.bottom = r.top + bmp->nRows; r.right = r.left + bmp->nCols; BitBlt /* brush = CreatePatternBrush( bitmap ); */ /* oldBrush = SelectObject( hdc, brush ); */ Rectangle( hdc, r.left, r.top, r.right, r.bottom ); /* FillRect( hdc, &r, brush ); */ /* SelectObject( hdc, oldBrush ); */ /* DeleteObject( brush ); */ } /* drawBitmapAt */ #endif static void ce_draw_boardBegin( DrawCtx* p_dctx, XP_Rect* rect, XP_Bool hasfocus ) { CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; CEAppGlobals* globals = dctx->globals; HDC hdc = globals->hdc; dctx->prevBkColor = GetBkColor( hdc ); } /* draw_boardBegin */ static void ce_draw_boardFinished( DrawCtx* p_dctx ) { CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; CEAppGlobals* globals = dctx->globals; HDC hdc = globals->hdc; SetBkColor( hdc, dctx->prevBkColor ); } /* draw_finished */ static XP_U16 getPlayerColor( XP_S16 player ) { if ( player < 0 ) { return BLACK_COLOR; } else { return USER_COLOR1 + player; } } /* getPlayerColor */ static XP_Bool ce_draw_drawCell( DrawCtx* p_dctx, XP_Rect* xprect, XP_UCHAR* letters, XP_Bitmap* bitmap, XP_S16 owner, XWBonusType bonus, XP_Bool isBlank, XP_Bool isPending, XP_Bool isStar ) { CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; CEAppGlobals* globals = dctx->globals; HDC hdc = globals->hdc; RECT rt; XP_U16 bkIndex; XP_UCHAR* cp = NULL; COLORREF foreIndex; XPRtoRECT( &rt, xprect ); ++rt.bottom; ++rt.right; Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom ); InsetRect( &rt, 1, 1 ); if ( isPending ) { foreIndex = dctx->colors[WHITE_COLOR]; bkIndex = BLACK_COLOR; } else { foreIndex = dctx->colors[getPlayerColor(owner)]; if ( bonus == BONUS_NONE ) { bkIndex = BKG_COLOR; } else { bkIndex = bonus+BONUS1_COLOR; } } FillRect( hdc, &rt, dctx->brushes[bkIndex] ); SetBkColor( hdc, dctx->colors[bkIndex] ); if ( !!letters && (letters[0] != '\0') ) { cp = letters; } else if ( !!bitmap ) { /* it's already NULL */ } if ( !!cp ) { wchar_t widebuf[4]; XP_MEMSET( widebuf, 0, sizeof(widebuf) ); MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, cp, -1, widebuf, sizeof(widebuf)/sizeof(widebuf[0]) ); SetTextColor( hdc, foreIndex ); DrawText( hdc, widebuf, -1, &rt, DT_SINGLELINE | DT_VCENTER | DT_CENTER); } else if ( !!bitmap ) { makeAndDrawBitmap( dctx, hdc, rt.left + 2, rt.top + 3, foreIndex, (CEBitmapInfo*)bitmap ); /* CEBitmapInfo* info = (CEBitmapInfo*)bitmap; */ /* HBITMAP bm = CreateBitmap( info->nCols, info->nRows, 1, 1, info->bits ); */ /* ceDrawBitmapInRect( hdc, rt.left+2, rt.top+2, bm ); */ /* DeleteObject( bm ); */ } else if ( isStar ) { ceDrawBitmapInRect( hdc, rt.left, rt.top, dctx->origin ); } return XP_TRUE; } /* ce_draw_drawCell */ static void ce_draw_invertCell( DrawCtx* p_dctx, XP_Rect* rect ) { } /* ce_draw_invertCell */ static void ce_draw_trayBegin( DrawCtx* p_dctx, XP_Rect* rect, XP_U16 owner, XP_Bool hasfocus ) { CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; dctx->trayOwner = owner; } /* ce_draw_trayBegin */ static void ce_draw_trayFinished( DrawCtx* p_dctx ) { /* ce_draw_boardFinished( p_dctx ); */ } /* ce_draw_trayFinished */ static void drawDrawTileGuts( DrawCtx* p_dctx, XP_Rect* xprect, XP_UCHAR* letters, XP_Bitmap* bitmap, XP_S16 val, XP_Bool highlighted ) { CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; CEAppGlobals* globals = dctx->globals; HDC hdc = globals->hdc; wchar_t widebuf[4]; RECT rt; ceClearToBkground( dctx, xprect ); XPRtoRECT( &rt, xprect ); InsetRect( &rt, 1, 1 ); Rectangle(hdc, rt.left, rt.top, rt.right, rt.bottom); InsetRect( &rt, 1, 1 ); FillRect( hdc, &rt, dctx->brushes[TILEBACK_COLOR] ); SetBkColor( hdc, dctx->colors[TILEBACK_COLOR] ); SetTextColor( hdc, dctx->colors[getPlayerColor(dctx->trayOwner)] ); if ( highlighted ) { Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom ); } InsetRect( &rt, 1, 1 ); if ( !!letters ) { HFONT oldFont = SelectObject( hdc, dctx->trayFont ); MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, letters, -1, widebuf, sizeof(widebuf)/sizeof(widebuf[0]) ); DrawText( hdc, widebuf, -1, &rt, DT_SINGLELINE | DT_TOP | DT_LEFT ); SelectObject( hdc, oldFont ); } else if ( !!bitmap ) { makeAndDrawBitmap( dctx, hdc, rt.left + 1, rt.top + 4, dctx->colors[USER_COLOR1+dctx->trayOwner], (CEBitmapInfo*)bitmap ); /* CEBitmapInfo* info = (CEBitmapInfo*)bitmap; */ /* HBITMAP bm = CreateBitmap( info->nCols, info->nRows, 1, 1, info->bits ); */ /* ceDrawBitmapInRect( hdc, rt.left+2, rt.top+2, bm ); */ /* DeleteObject( bm ); */ /* ceDrawBitmapInRect( hdc, rt.left+2, rt.top+2, (HBITMAP)bitmap ); */ } if ( val >= 0 ) { swprintf( widebuf, L"%d", val ); DrawText(hdc, widebuf, -1, &rt, DT_SINGLELINE | DT_BOTTOM | DT_RIGHT); } } /* drawDrawTileGuts */ static void ce_draw_drawTile( DrawCtx* p_dctx, XP_Rect* xprect, XP_UCHAR* letters, XP_Bitmap* bitmap, XP_S16 val, XP_Bool highlighted ) { drawDrawTileGuts( p_dctx, xprect, letters, bitmap, val, highlighted ); } /* ce_draw_drawTile */ static void ce_draw_drawTileBack( DrawCtx* p_dctx, XP_Rect* xprect ) { drawDrawTileGuts( p_dctx, xprect, "?", NULL, -1, XP_FALSE ); } /* ce_draw_drawTileBack */ static void ce_draw_drawTrayDivider( DrawCtx* p_dctx, XP_Rect* rect, XP_Bool selected ) { CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; CEAppGlobals* globals = dctx->globals; HDC hdc = globals->hdc; RECT rt; XPRtoRECT( &rt, rect ); if ( selected ) { Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom ); } else { FillRect( hdc, &rt, dctx->brushes[BLACK_COLOR] ); } } /* ce_draw_drawTrayDivider */ static void ceClearToBkground( CEDrawCtx* dctx, XP_Rect* rect ) { CEAppGlobals* globals = dctx->globals; HDC hdc = globals->hdc; RECT rt; XPRtoRECT( &rt, rect ); FillRect( hdc, &rt, dctx->brushes[BKG_COLOR] ); } /* ceClearToBkground */ static void ce_draw_clearRect( DrawCtx* p_dctx, XP_Rect* rectP ) { ceClearToBkground( (CEDrawCtx*)p_dctx, rectP ); } /* ce_draw_clearRect */ static void ceDrawBitmapInRect( HDC hdc, XP_U32 x, XP_U32 y, HBITMAP bitmap ) { BITMAP bmp; HDC tmpDC; int nBytes; tmpDC = CreateCompatibleDC( hdc ); SelectObject( tmpDC, bitmap ); nBytes = GetObject( bitmap, sizeof(bmp), &bmp ); XP_ASSERT( nBytes > 0 ); BitBlt( hdc, x, y, bmp.bmWidth, bmp.bmHeight, tmpDC, 0, 0, SRCCOPY ); /* BLACKNESS */ DeleteDC( tmpDC ); } /* ceDrawBitmapInRect */ static void ce_draw_drawBoardArrow( DrawCtx* p_dctx, XP_Rect* xprect, XWBonusType cursorBonus, XP_Bool vertical ) { CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; CEAppGlobals* globals = dctx->globals; HDC hdc = globals->hdc; wchar_t* txt = vertical? L"|":L"-"; RECT rt; XP_U16 bkIndex; HBITMAP cursor; XPRtoRECT( &rt, xprect ); ++rt.bottom; ++rt.right; Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom ); InsetRect( &rt, 1, 1 ); if ( vertical ) { cursor = dctx->downArrow; } else { cursor = dctx->rightArrow; } if ( cursorBonus == BONUS_NONE ) { bkIndex = BKG_COLOR; } else { bkIndex = cursorBonus+BONUS1_COLOR; } FillRect( hdc, &rt, dctx->brushes[bkIndex] ); SetBkColor( hdc, dctx->colors[bkIndex] ); ceDrawBitmapInRect( hdc, rt.left+1, rt.top+1, cursor ); } /* ce_draw_drawBoardArrow */ static void ce_draw_scoreBegin( DrawCtx* p_dctx, XP_Rect* rect, XP_U16 numPlayers, XP_Bool hasfocus ) { CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; CEAppGlobals* globals = dctx->globals; HDC hdc = globals->hdc; SetBkColor( hdc, dctx->colors[BKG_COLOR] ); ceClearToBkground( (CEDrawCtx*)p_dctx, rect ); } /* ce_draw_scoreBegin */ static void formatRemText( HDC hdc, wchar_t* buf, XP_S16 nTilesLeft, SIZE* size ) { wchar_t* format = L"Rem:%d"; if ( nTilesLeft <= 0 ) { buf[0] = 0; size->cx = size->cy = 0; } else { swprintf( buf, format, nTilesLeft ); GetTextExtentPoint32( hdc, buf, wcslen(buf), size ); } } /* formatRemText */ static void ce_draw_measureRemText( DrawCtx* p_dctx, XP_Rect* r, XP_S16 nTilesLeft, XP_U16* width, XP_U16* height ) { CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; CEAppGlobals* globals = dctx->globals; HDC hdc = globals->hdc; wchar_t buf[16]; SIZE size; formatRemText( hdc, buf, nTilesLeft, &size ); *width = (XP_U16)size.cx; *height = (XP_U16)size.cy; } /* ce_draw_measureRemText */ static XP_U16 ce_draw_drawRemText( DrawCtx* p_dctx, XP_Rect* rInner, XP_Rect* rOuter, XP_S16 nTilesLeft ) { CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; CEAppGlobals* globals = dctx->globals; HDC hdc = globals->hdc; wchar_t buf[16]; RECT rt; SIZE size; formatRemText( hdc, buf, nTilesLeft, &size ); XPRtoRECT( &rt, rInner ); DrawText( hdc, buf, -1, &rt, DT_SINGLELINE | DT_LEFT | DT_VCENTER); return (XP_U16)size.cx; } /* ce_draw_drawRemText */ static void ceWidthAndText( HDC hdc, wchar_t* buf, DrawScoreInfo* dsi, XP_U16* widthP, XP_U16* heightP ) { XP_UCHAR borders[] = {'•', '\0'}; XP_UCHAR tilesLeftTxt[8]; XP_UCHAR tbuf[10]; /* *9999:7* is 8 chars */ SIZE size; XP_U16 len; if ( !dsi->isTurn ) { borders[0] = '\0'; } if ( dsi->nTilesLeft >= 0 ) { sprintf( tilesLeftTxt, ":%d", dsi->nTilesLeft ); } else { tilesLeftTxt[0] = '\0'; } sprintf( tbuf, "%s%d%s%s", borders, dsi->score, tilesLeftTxt, borders ); len = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, tbuf, -1, buf, 10 ); GetTextExtentPoint32( hdc, buf, len, &size ); *widthP = (XP_U16)size.cx; *heightP = (XP_U16)size.cy; } /* ceWidthAndText */ static void ce_draw_measureScoreText( DrawCtx* p_dctx, XP_Rect* r, DrawScoreInfo* dsi, XP_U16* widthP, XP_U16* heightP ) { CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; CEAppGlobals* globals = dctx->globals; HDC hdc = globals->hdc; wchar_t widebuf[10]; HFONT newFont; HFONT oldFont; if ( dsi->selected ) { newFont = dctx->selPlayerFont; } else { newFont = dctx->playerFont; } oldFont = SelectObject( hdc, newFont ); ceWidthAndText( hdc, widebuf, dsi, widthP, heightP ); SelectObject( hdc, oldFont ); } /* ce_draw_measureScoreText */ static void ce_draw_score_drawPlayer( DrawCtx* p_dctx, XP_S16 playerNum, /* -1: don't use */ XP_Rect* rInner, XP_Rect* rOuter, DrawScoreInfo* dsi ) { CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; CEAppGlobals* globals = dctx->globals; HDC hdc = globals->hdc; RECT rt; XP_U16 width, height; wchar_t scoreBuf[20]; HFONT newFont; HFONT oldFont; XPRtoRECT( &rt, rInner ); if ( dsi->selected ) { newFont = dctx->selPlayerFont; } else { newFont = dctx->playerFont; } oldFont = SelectObject( hdc, newFont ); SetTextColor( hdc, dctx->colors[getPlayerColor(playerNum)] ); ceWidthAndText( hdc, scoreBuf, dsi, &width, &height ); DrawText( hdc, scoreBuf, -1, &rt, DT_SINGLELINE | DT_VCENTER | DT_CENTER ); SelectObject( hdc, oldFont ); } /* ce_draw_score_drawPlayer */ static void ce_draw_score_pendingScore( DrawCtx* p_dctx, XP_Rect* rect, XP_S16 score, XP_U16 playerNum ) { CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; CEAppGlobals* globals = dctx->globals; HDC hdc = globals->hdc; wchar_t widebuf[5]; XP_UCHAR buf[5]; RECT rt; SetTextColor( hdc, dctx->colors[BLACK_COLOR] ); XPRtoRECT( &rt, rect ); FillRect( hdc, &rt, dctx->brushes[BKG_COLOR] ); if ( score < 0 ) { buf[0] = '?'; buf[1] = '?'; buf[2] = '\0'; } else { sprintf( buf, "%d", score ); } MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, buf, -1, widebuf, sizeof(widebuf)/sizeof(widebuf[0]) ); DrawText(hdc, widebuf, -1, &rt, DT_SINGLELINE | DT_BOTTOM | DT_CENTER); DrawText(hdc, L"Pts", -1, &rt, DT_SINGLELINE | DT_TOP | DT_CENTER); } /* ce_draw_score_pendingScore */ static void ce_draw_scoreFinished( DrawCtx* p_dctx ) { /* ce_draw_boardFinished( p_dctx ); */ } /* ce_draw_scoreFinished */ static void ce_draw_drawTimer( DrawCtx* p_dctx, XP_Rect* rInner, XP_Rect* rOuter, XP_U16 player, XP_S16 secondsLeft ) { CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; CEAppGlobals* globals = dctx->globals; HDC hdc = globals->hdc; wchar_t widebuf[10]; XP_U16 mins, secs; RECT rt; PAINTSTRUCT ps; XP_Bool isNegative; XPRtoRECT( &rt, rInner ); isNegative = secondsLeft < 0; if ( isNegative ) { secondsLeft *= -1; } mins = secondsLeft / 60; secs = secondsLeft % 60; swprintf( widebuf, L"%s%.1d:%.2d", isNegative? L"-": L"", mins, secs ); if ( !globals->hdc ) { InvalidateRect( dctx->mainWin, &rt, FALSE ); hdc = BeginPaint( dctx->mainWin, &ps ); } SetTextColor( hdc, dctx->colors[getPlayerColor(player)] ); ceClearToBkground( dctx, rInner ); DrawText( hdc, widebuf, -1, &rt, DT_SINGLELINE | DT_VCENTER | DT_RIGHT); if ( !globals->hdc ) { EndPaint( dctx->mainWin, &ps ); } } /* ce_draw_drawTimer */ static XP_UCHAR* ce_draw_getMiniWText( DrawCtx* p_dctx, XWMiniTextType whichText ) { XP_UCHAR* str; switch( whichText ) { case BONUS_DOUBLE_LETTER: str = "Double letter"; break; case BONUS_DOUBLE_WORD: str = "Double word"; break; case BONUS_TRIPLE_LETTER: str = "Triple letter"; break; case BONUS_TRIPLE_WORD: str = "Triple word"; break; case INTRADE_MW_TEXT: str = "Trading tiles; tap 'D' when done"; break; default: XP_ASSERT( XP_FALSE ); } return str; } /* ce_draw_getMiniWText */ static void ce_draw_measureMiniWText( DrawCtx* p_dctx, XP_UCHAR* str, XP_U16* widthP, XP_U16* heightP ) { CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; CEAppGlobals* globals = dctx->globals; HDC hdc = GetDC(dctx->mainWin);//globals->hdc; SIZE size; wchar_t widebuf[40]; MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, str, -1, widebuf, sizeof(widebuf)/sizeof(widebuf[0]) ); GetTextExtentPoint32( hdc, widebuf, wcslen(widebuf), &size ); *widthP = size.cx + 12; *heightP = size.cy + 4; } /* ce_draw_measureMiniWText */ static void ce_draw_drawMiniWindow( DrawCtx* p_dctx, XP_UCHAR* text, XP_Rect* rect, void** closureP ) { CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; CEAppGlobals* globals = dctx->globals; HDC hdc = globals->hdc; RECT rt; PAINTSTRUCT ps; wchar_t widebuf[40]; XPRtoRECT( &rt, rect ); if ( !globals->hdc ) { InvalidateRect( dctx->mainWin, &rt, FALSE ); hdc = BeginPaint( dctx->mainWin, &ps ); } ceClearToBkground( (CEDrawCtx*)p_dctx, rect ); Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom ); InsetRect( &rt, 1, 1 ); Rectangle( hdc, rt.left, rt.top, rt.right, rt.bottom ); XP_MEMSET( widebuf, 0, sizeof(widebuf) ); MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, text, -1, widebuf, sizeof(widebuf)/sizeof(widebuf[0]) ); DrawText(hdc, widebuf, -1, &rt, DT_SINGLELINE | DT_CENTER | DT_VCENTER); if ( !globals->hdc ) { EndPaint( dctx->mainWin, &ps ); } } /* ce_draw_drawMiniWindow */ static void ce_draw_eraseMiniWindow( DrawCtx* p_dctx, XP_Rect* rect, XP_Bool lastTime, void** closure, XP_Bool* invalUnder ) { *invalUnder = XP_TRUE; } /* ce_draw_eraseMiniWindow */ static void ce_draw_destroyCtxt( DrawCtx* p_dctx ) { XP_U16 i; CEDrawCtx* dctx = (CEDrawCtx*)p_dctx; for ( i = 0; i < 5; ++i ) { DeleteObject( dctx->brushes[i] ); } DeleteObject( dctx->trayFont ); DeleteObject( dctx->playerFont ); DeleteObject( dctx->selPlayerFont ); DeleteObject( dctx->rightArrow ); DeleteObject( dctx->downArrow ); DeleteObject( dctx->origin ); XP_FREE( dctx->mpool, p_dctx->vtable ); XP_FREE( dctx->mpool, dctx ); } /* ce_draw_destroyCtxt */ static void draw_doNothing( DrawCtx* dctx, ... ) { } /* draw_doNothing */ static void ceFontsSetup( CEAppGlobals* globals, CEDrawCtx* dctx ) { LOGFONT font; XP_MEMSET( &font, 0, sizeof(font) ); font.lfHeight = (CE_TRAY_SCALEV*2)/3; font.lfWeight = 600; /* FW_DEMIBOLD */ dctx->trayFont = CreateFontIndirect( &font ); font.lfWeight = FW_LIGHT; font.lfHeight = CE_SCORE_HEIGHT - 2; dctx->playerFont = CreateFontIndirect( &font ); font.lfWeight = FW_BOLD; font.lfHeight = CE_SCORE_HEIGHT; dctx->selPlayerFont = CreateFontIndirect( &font ); } /* ceFontsSetup */ static void loadColors( XP_U16* ptr, COLORREF* colors ) { XP_U16 i; for ( i = 0; i < NUM_COLORS; ++i ) { XP_U8 r = (XP_U8)*ptr++; XP_U8 g = (XP_U8)*ptr++; XP_U8 b = (XP_U8)*ptr++; *colors++ = RGB( r, g, b ); } } /* loadColors */ DrawCtx* ce_drawctxt_make( MPFORMAL HWND mainWin, CEAppGlobals* globals ) { HRSRC rsrcH; HGLOBAL globH; CEDrawCtx* dctx = (CEDrawCtx*)XP_MALLOC( mpool, sizeof(*dctx) ); XP_U16 i; dctx->vtable = (DrawCtxVTable*)XP_MALLOC( mpool, sizeof(*((dctx)->vtable))); for ( i = 0; i < sizeof(*dctx->vtable)/4; ++i ) { ((void**)(dctx->vtable))[i] = draw_doNothing; } SET_VTABLE_ENTRY( dctx->vtable, draw_destroyCtxt, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_boardBegin, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_drawCell, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_invertCell, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_boardFinished, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_trayBegin, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_trayFinished, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_drawTile, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_drawTileBack, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_drawTrayDivider, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_clearRect, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_drawBoardArrow, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_scoreBegin, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_measureRemText, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_drawRemText, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_measureScoreText, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_score_drawPlayer, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_score_pendingScore, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_scoreFinished, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_drawTimer, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_getMiniWText, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_measureMiniWText, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_drawMiniWindow, ce ); SET_VTABLE_ENTRY( dctx->vtable, draw_eraseMiniWindow, ce ); dctx->mainWin = mainWin; dctx->globals = globals; /* load the colors from resource */ rsrcH = FindResource( globals->hInst, MAKEINTRESOURCE(ID_COLORS_RES), TEXT("CLRS") ); globH = LoadResource( globals->hInst, rsrcH ); loadColors( globH, dctx->colors ); DeleteObject( globH ); for ( i = 0; i < NUM_COLORS; ++i ) { dctx->brushes[i] = CreateSolidBrush( dctx->colors[i] ); } ceFontsSetup( globals, dctx ); dctx->rightArrow = LoadBitmap( globals->hInst, MAKEINTRESOURCE(IDB_RIGHTARROW) ); XP_DEBUGF( "loaded bitmap: 0x%lx", (unsigned long)dctx->rightArrow ); dctx->downArrow = LoadBitmap( globals->hInst, MAKEINTRESOURCE(IDB_DOWNARROW) ); dctx->origin = LoadBitmap( globals->hInst, MAKEINTRESOURCE(IDB_ORIGIN) ); return (DrawCtx*)dctx; } /* ce_drawctxt_make */