When dict is utf8, convert to wchar_t assuming CP_UTF8 rather than CP_ACP.

This commit is contained in:
ehouse 2009-04-05 20:18:46 +00:00
parent f0d6dda9dd
commit f3b53e4aaf
7 changed files with 89 additions and 76 deletions

View file

@ -31,13 +31,13 @@ loadLettersList( BlankDialogState* bState )
HWND hDlg = bState->dlgHdr.hDlg;
CEAppGlobals* globals = bState->dlgHdr.globals;
const XP_UCHAR4* texts = bState->texts;
UINT codePage = ceCurDictIsUTF8(globals)? CP_UTF8 : CP_ACP;
for ( i = 0; i < nTiles; ++i ) {
XP_U16 len;
wchar_t widebuf[4];
len = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED,
texts[i], strlen(texts[i]),
len = MultiByteToWideChar( codePage, 0, texts[i], strlen(texts[i]),
widebuf, VSIZE(widebuf) );
widebuf[len] = 0;
@ -63,8 +63,9 @@ showCurTray( HWND hDlg, BlankDialogState* bState )
XP_UCHAR labelBuf[48];
wchar_t widebuf[48];
XP_UCHAR* name;
CEAppGlobals* globals = bState->dlgHdr.globals;
name = bState->dlgHdr.globals->gameInfo.players[bState->playerNum].name;
name = globals->gameInfo.players[bState->playerNum].name;
lenSoFar += XP_SNPRINTF( labelBuf + lenSoFar,
sizeof(labelBuf) - lenSoFar,
@ -77,9 +78,8 @@ showCurTray( HWND hDlg, BlankDialogState* bState )
i==0?": ":", ", pi->curTiles[i] );
}
(void)MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED,
labelBuf, lenSoFar + 1,
widebuf,
(void)MultiByteToWideChar( ceCurDictIsUTF8(globals)? CP_UTF8 : CP_ACP,
0, labelBuf, lenSoFar + 1, widebuf,
VSIZE(widebuf) + sizeof(widebuf[0]) );
SetDlgItemText( hDlg,IDC_PICKMSG, widebuf );

View file

@ -89,7 +89,7 @@ typedef struct _FontCacheEntry {
} FontCacheEntry;
typedef struct _CeBMCacheEntry {
XP_UCHAR letters[4]; /* currently the max */
const XP_UCHAR* letters; /* pointer into dict; don't free!!! */
HBITMAP bms[2];
} CeBMCacheEntry;
@ -99,6 +99,7 @@ struct CEDrawCtx {
HWND mainWin;
CEAppGlobals* globals;
const DictionaryCtxt* dict;
UINT codePage;
COLORREF prevBkColor;
@ -218,7 +219,7 @@ ceDrawTextClipped( HDC hdc, wchar_t* buf, XP_S16 len, XP_Bool clip,
static void
ceDrawLinesClipped( HDC hdc, const FontCacheEntry* fce, XP_UCHAR* buf,
XP_Bool clip, const RECT* bounds )
UINT codePage, XP_Bool clip, const RECT* bounds )
{
XP_U16 top = bounds->top;
XP_U16 width = bounds->right - bounds->left;
@ -228,8 +229,7 @@ ceDrawLinesClipped( HDC hdc, const FontCacheEntry* fce, XP_UCHAR* buf,
XP_U16 len = newline==NULL? strlen(buf): newline - buf;
wchar_t widebuf[len];
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, buf, len,
widebuf, len );
MultiByteToWideChar( codePage, 0, buf, len, widebuf, len );
ceDrawTextClipped( hdc, widebuf, len, clip, fce, bounds->left, top,
width, DT_CENTER );
@ -509,7 +509,7 @@ ceBestFitFont( CEDrawCtx* dctx, const XP_U16 soughtHeight,
makeTestBuf( dctx, sample, VSIZE(sample), index );
len = 1 + strlen(sample);
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, sample, len, widebuf, len );
MultiByteToWideChar( dctx->codePage, 0, sample, len, widebuf, len );
memBM = CreateCompatibleBitmap( memDC, testHeight, testHeight );
SelectObject( memDC, memBM );
@ -626,25 +626,22 @@ checkBMCache( CEDrawCtx* dctx, HDC hdc, const XP_UCHAR* letters,
{
HBITMAP bm = NULL;
CeBMCacheEntry* entry = NULL;
XP_U16 len = 1 + XP_STRLEN( letters );
XP_Bool canCache = XP_FALSE;
XP_ASSERT( !!letters );
XP_ASSERT( index < 2 );
if ( len <= sizeof( entry->letters ) ) {
XP_U16 ii;
for ( ii = 0, entry = dctx->bmCache; ii < VSIZE(dctx->bmCache);
++ii, ++entry ) {
if ( 0 == entry->letters[0] ) { /* available */
XP_MEMCPY( entry->letters, letters, len );
canCache = XP_TRUE;
break;
} else if ( !XP_STRNCMP( entry->letters, letters, len ) ) {
canCache = XP_TRUE;
bm = entry->bms[index]; /* may be null */
break;
}
XP_U16 ii;
for ( ii = 0, entry = dctx->bmCache; ii < VSIZE(dctx->bmCache);
++ii, ++entry ) {
if ( !entry->letters ) { /* available */
entry->letters = letters;
canCache = XP_TRUE;
break;
} else if ( entry->letters == letters ) {
canCache = XP_TRUE;
bm = entry->bms[index]; /* may be null */
break;
}
}
@ -756,7 +753,7 @@ ceMeasureText( CEDrawCtx* dctx, HDC hdc, const FontCacheEntry* fce,
XP_ASSERT( nextStr != str );
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, str, len,
MultiByteToWideChar( dctx->codePage, 0, str, len,
widebuf, VSIZE(widebuf) );
GetTextExtentPoint32( hdc, widebuf, len, &size );
@ -796,7 +793,7 @@ drawTextLines( CEDrawCtx* dctx, HDC hdc, const XP_UCHAR* text, XP_S16 padding,
len = nextStr - text;
}
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, text, len,
MultiByteToWideChar( dctx->codePage, 0, text, len,
widebuf, VSIZE(widebuf) );
textRt.bottom = textRt.top + dctx->miniLineHt;
@ -1043,7 +1040,7 @@ DRAW_FUNC_NAME(drawCell)( DrawCtx* p_dctx, const XP_Rect* xprect,
} else if ( !isDragSrc && !!letters && (letters[0] != '\0') ) {
wchar_t widebuf[4];
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, letters, -1,
MultiByteToWideChar( dctx->codePage, 0, letters, -1,
widebuf, VSIZE(widebuf) );
ceDrawTextClipped( hdc, widebuf, -1, XP_FALSE, fce, xprect->left+1,
xprect->top+2, xprect->width, DT_CENTER );
@ -1170,8 +1167,7 @@ drawDrawTileGuts( DrawCtx* p_dctx, const XP_Rect* xprect,
if ( !!bitmaps || !!letters ) {
HFONT oldFont = SelectObject( hdc, fce->setFont );
XP_U16 len = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED,
letters, -1,
XP_U16 len = MultiByteToWideChar( dctx->codePage, 0, letters, -1,
widebuf, VSIZE(widebuf) );
/* see if there's room to use text instead of bitmap */
@ -1460,7 +1456,7 @@ DRAW_FUNC_NAME(drawRemText)( DrawCtx* p_dctx, const XP_Rect* rInner,
fce = ceGetSizedFont( dctx, 0, 0, RFONTS_REM );
oldFont = SelectObject( hdc, fce->setFont );
ceDrawLinesClipped( hdc, fce, buf, XP_TRUE, &rt );
ceDrawLinesClipped( hdc, fce, buf, CP_ACP, XP_TRUE, &rt );
(void)SelectObject( hdc, oldFont );
} /* ce_draw_drawRemText */
@ -1580,7 +1576,7 @@ DRAW_FUNC_NAME(score_drawPlayer)( DrawCtx* p_dctx,
rt.bottom -= IS_TURN_VPAD;
}
ceDrawLinesClipped( hdc, fce, buf, XP_TRUE, &rt );
ceDrawLinesClipped( hdc, fce, buf, CP_ACP, XP_TRUE, &rt );
SelectObject( hdc, oldFont );
} /* ce_draw_score_drawPlayer */
@ -1674,7 +1670,7 @@ DRAW_FUNC_NAME(drawTimer)( DrawCtx* p_dctx, const XP_Rect* rInner,
oldFont = SelectObject( hdc, fce->setFont );
++rt.top;
ceDrawLinesClipped( hdc, fce, buf, XP_TRUE, &rt );
ceDrawLinesClipped( hdc, fce, buf, CP_ACP, XP_TRUE, &rt );
SelectObject( hdc, oldFont );
if ( !globals->hdc ) {
@ -1812,6 +1808,7 @@ DRAW_FUNC_NAME(dictChanged)( DrawCtx* p_dctx, const DictionaryCtxt* dict )
ceClearFontCache( dctx );
}
dctx->dict = dict;
dctx->codePage = dict_isUTF8(dict)? CP_UTF8 : CP_ACP;
}
#ifdef DRAW_LINK_DIRECT

View file

@ -1,4 +1,4 @@
/* -*- fill-column: 77; compile-command: "make -j TARGET_OS=wince DEBUG=TRUE" -*- */
/* -*- fill-column: 77; compile-command: "make -j2 TARGET_OS=wince DEBUG=TRUE" -*- */
/*
* Copyright 2002-2009 by Eric House (xwords@eehouse.org). All rights
* reserved.
@ -2654,7 +2654,8 @@ messageBoxStream( CEAppGlobals* globals, XWStreamCtxt* stream, wchar_t* title,
XP_UCHAR* buf = ceStreamToStrBuf( MPPARM(globals->mpool) stream );
int result;
result = ceMessageBoxChar( globals, buf, title, buttons );
result = ceMessageBoxChar( globals, buf, ceCurDictIsUTF8(globals),
title, buttons );
XP_FREE( globals->mpool, buf );
return result;
@ -3259,69 +3260,69 @@ ce_util_getUserString( XW_UtilCtxt* XP_UNUSED(uc), XP_U16 stringCode )
{
switch( stringCode ) {
case STRD_REMAINING_TILES_ADD:
return (XP_UCHAR*)"+ %d [all remaining tiles]";
return "+ %d [all remaining tiles]";
case STRD_UNUSED_TILES_SUB:
return (XP_UCHAR*)"- %d [unused tiles]";
return "- %d [unused tiles]";
case STR_BONUS_ALL:
return (XP_UCHAR*)"Bonus for using all tiles: 50" XP_CR;
return "Bonus for using all tiles: 50" XP_CR;
case STRD_TURN_SCORE:
return (XP_UCHAR*)"Score for turn: %d" XP_CR;
return "Score for turn: %d" XP_CR;
case STR_COMMIT_CONFIRM:
return (XP_UCHAR*)"Commit the current move?" XP_CR;
return "Commit the current move?" XP_CR;
case STR_LOCAL_NAME:
return (XP_UCHAR*)"%s";
return "%s";
case STR_NONLOCAL_NAME:
return (XP_UCHAR*)"%s (remote)";
return "%s (remote)";
case STRD_TIME_PENALTY_SUB:
return (XP_UCHAR*)" - %d [time]";
return " - %d [time]";
case STRD_CUMULATIVE_SCORE:
return (XP_UCHAR*)"Cumulative score: %d" XP_CR;
return "Cumulative score: %d" XP_CR;
case STRS_MOVE_ACROSS:
return (XP_UCHAR*)"move (from %s across)" XP_CR;
return "move (from %s across)" XP_CR;
case STRS_MOVE_DOWN:
return (XP_UCHAR*)"move (from %s down)" XP_CR;
return "move (from %s down)" XP_CR;
case STRS_TRAY_AT_START:
return (XP_UCHAR*)"Tray at start: %s" XP_CR;
return "Tray at start: %s" XP_CR;
case STRS_NEW_TILES:
return (XP_UCHAR*)"New tiles: %s" XP_CR;
return "New tiles: %s" XP_CR;
case STRSS_TRADED_FOR:
return (XP_UCHAR*)"Traded %s for %s.";
return "Traded %s for %s.";
case STR_PASS:
return (XP_UCHAR*)"pass" XP_CR;
return "pass" XP_CR;
case STR_PHONY_REJECTED:
return (XP_UCHAR*)"Illegal word in move; turn lost!" XP_CR;
return "Illegal word in move; turn lost!" XP_CR;
case STRD_ROBOT_TRADED:
return (XP_UCHAR*)"Robot traded tiles %d this turn.";
return "Robot traded tiles %d this turn.";
case STR_ROBOT_MOVED:
return (XP_UCHAR*)"The robot made this move:" XP_CR;
return "The robot made this move:" XP_CR;
case STR_REMOTE_MOVED:
return (XP_UCHAR*)"Remote player made this move:" XP_CR;
return "Remote player made this move:" XP_CR;
case STR_PASSED:
return (XP_UCHAR*)"Passed";
return "Passed";
case STRSD_SUMMARYSCORED:
return (XP_UCHAR*)"%s:%d";
return "%s:%d";
case STRD_TRADED:
return (XP_UCHAR*)"Traded %d";
return "Traded %d";
case STR_LOSTTURN:
return (XP_UCHAR*)"Lost turn";
return "Lost turn";
#ifndef XWFEATURE_STANDALONE_ONLY
case STR_LOCALPLAYERS:
return (XP_UCHAR*)"Locl playrs:";
return "Locl playrs:";
#endif
case STR_TOTALPLAYERS:
return (XP_UCHAR*)"Player count:";
return "Player count:";
case STRS_VALUES_HEADER:
return (XP_UCHAR*)"%s counts/values:" XP_CR;
return "%s counts/values:" XP_CR;
default:
XP_LOGF( "stringCode=%d", stringCode );
return (XP_UCHAR*)"unknown code";
return "unknown code";
}
} /* ce_util_getUserString */
@ -3357,7 +3358,8 @@ ce_util_warnIllegalWord( XW_UtilCtxt* uc, BadWordInfo* bwi,
sprintf( msgBuf, "Word[s] %s not found in dictionary.", wordsBuf );
if ( turnLost ) {
ceMessageBoxChar( globals, msgBuf, L"Illegal word",
XP_Bool isUTF8 = ceCurDictIsUTF8( globals );
ceMessageBoxChar( globals, msgBuf, isUTF8, L"Illegal word",
MB_OK | MB_ICONHAND );
isOk = XP_TRUE;
} else {

View file

@ -335,7 +335,8 @@ PrefsDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
if ( IS_SMARTPHONE(globals) ) {
ceMessageBoxChar( globals, "This feature "
"requires a touch screen.",
L"Sorry", MB_OK | MB_ICONHAND );
XP_FALSE, L"Sorry",
MB_OK | MB_ICONHAND );
ceSetChecked( hDlg, IDC_CHECKHINTSLIMITS, XP_FALSE );
}
break;

View file

@ -28,9 +28,8 @@ stuffTextInField( HWND hDlg, StrBoxState* state )
XP_U16 len, crlen;
XP_UCHAR* sbuf;
wchar_t* wbuf;
#ifdef MEM_DEBUG
CEAppGlobals* globals = state->dlgHdr.globals;
#endif
UINT codePage = ceCurDictIsUTF8(globals)? CP_UTF8 : CP_ACP;
sbuf = XP_MALLOC( globals->mpool, nBytes + 1 );
stream_getBytes( state->stream, sbuf, nBytes );
@ -41,11 +40,9 @@ stuffTextInField( HWND hDlg, StrBoxState* state )
}
sbuf[nBytes] = '\0';
len = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, sbuf, nBytes,
NULL, 0 );
len = MultiByteToWideChar( codePage, 0, sbuf, nBytes, NULL, 0 );
wbuf = XP_MALLOC( globals->mpool, (len+1) * sizeof(*wbuf) );
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, sbuf, nBytes,
wbuf, len );
MultiByteToWideChar( codePage, 0, sbuf, nBytes, wbuf, len );
XP_FREE( globals->mpool, sbuf );
wbuf[len] = 0;

View file

@ -881,17 +881,17 @@ ceGetPath( CEAppGlobals* globals, CePathType typ,
int
ceMessageBoxChar( CEAppGlobals* XP_UNUSED(globals), const XP_UCHAR* str,
const wchar_t* title, XP_U16 buttons )
XP_Bool isUTF8, const wchar_t* title, XP_U16 buttons )
{
HWND parent;
/* Get the length required, then alloc and go. This is technically
correct, but everywhere else I assume a 2:1 ratio for wchar_t:char. */
XP_U16 clen = 1 + strlen(str);
XP_U32 wlen = 1 + MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, str,
clen, NULL, 0 );
UINT codePage = isUTF8? CP_UTF8:CP_ACP;
XP_U32 wlen = 1 + MultiByteToWideChar( codePage, 0, str, clen, NULL, 0 );
wchar_t widebuf[wlen];
MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, str, clen, widebuf, wlen );
MultiByteToWideChar( codePage, 0, str, clen, widebuf, wlen );
parent = GetForegroundWindow();
return MessageBox( parent, widebuf, title, buttons );
@ -900,6 +900,21 @@ ceMessageBoxChar( CEAppGlobals* XP_UNUSED(globals), const XP_UCHAR* str,
int
ceOops( CEAppGlobals* globals, const XP_UCHAR* str )
{
return ceMessageBoxChar( globals, str, L"Oops!",
XP_Bool isUTF8 = ceCurDictIsUTF8( globals );
return ceMessageBoxChar( globals, str, isUTF8, L"Oops!",
MB_OK | MB_ICONHAND );
}
XP_Bool
ceCurDictIsUTF8( CEAppGlobals* globals )
{
XP_Bool result = XP_FALSE;
const ModelCtxt* model = globals->game.model;
if ( !!model ) {
const DictionaryCtxt* dict = model_getDictionary( model );
if ( !!dict ) {
result = dict_isUTF8( dict );
}
}
return result;
} /* ceCurDictIsUTF8 */

View file

@ -48,8 +48,9 @@ void ceGetItemRect( HWND hDlg, XP_U16 resID, RECT* rect );
void ceMoveItem( HWND hDlg, XP_U16 resID, XP_S16 byX, XP_S16 byY );
int ceMessageBoxChar( CEAppGlobals* globals, const XP_UCHAR* str,
const wchar_t* title, XP_U16 buttons );
XP_Bool isUTF8, const wchar_t* title, XP_U16 buttons );
int ceOops( CEAppGlobals* globals, const XP_UCHAR* str );
XP_Bool ceCurDictIsUTF8( CEAppGlobals* globals );
typedef enum {
PREFS_FILE_PATH_L