📄 imeui.cpp
字号:
float SizeOfPie = (float) gSkinIME.symbolHeight;
memset( PieData, 0, sizeof( PieData ) );
switch(gSkinIME.symbolPlacement)
{
case 0: // vertical centering IME indicator
{
if (SizeOfPie + g_CaretInfo.margins.right+4 > g_screenWidth)
{
PieData[0].sx=(-SizeOfPie/2) + g_CaretInfo.margins.left-4;
PieData[0].sy= (float) g_CaretInfo.margins.top + (g_CaretInfo.margins.bottom - g_CaretInfo.margins.top)/2;
}
else
{
PieData[0].sx=-(SizeOfPie/2) + g_CaretInfo.margins.right+gSkinIME.symbolHeight+4;
PieData[0].sy= (float) g_CaretInfo.margins.top + (g_CaretInfo.margins.bottom - g_CaretInfo.margins.top)/2;
}
break;
}
case 1: // upperleft
PieData[0].sx = 4+ (SizeOfPie/2);
PieData[0].sy = 4+ (SizeOfPie/2);
break;
case 2: // upperright
PieData[0].sx = g_screenWidth - (4+ (SizeOfPie/2));
PieData[0].sy = 4+ (SizeOfPie/2);
break;
case 3: // lowerright
PieData[0].sx = g_screenWidth - (4+ (SizeOfPie/2));
PieData[0].sy = g_screenHeight - (4+ (SizeOfPie/2));
break;
case 4: // lowerleft
PieData[0].sx = 4+ (SizeOfPie/2);
PieData[0].sy = g_screenHeight - (4+ (SizeOfPie/2));
break;
}
PieData[0].rhw=1.0f;
if (bOn)
{
if ( GetTickCount() - lastSwirl > 250 )
{
swirl++;
lastSwirl = GetTickCount();
if (swirl > 13)
swirl = 0;
}
}
else
swirl = 0;
for( int t1 = 1; t1 < 16; t1++ )
{
float radian = 2.0f * 3.1415926f * ( t1 - 1 + ( bOn * swirl ) ) / 14.0f;
PieData[t1].sx = (float)( PieData[0].sx + SizeOfPie / 2 * cos( radian ) );
PieData[t1].sy = (float)( PieData[0].sy + SizeOfPie / 2 * sin( radian ) );
PieData[t1].rhw = 1.0f;
}
PieData[0].color=0xffffff + (((DWORD)gSkinIME.symbolTranslucence)<<24);
if ( !gSkinIME.symbolColor && bOn )
{
{
PieData[1].color=0xff0000 + (((DWORD)gSkinIME.symbolTranslucence)<<24);
PieData[2].color=0xff3000 + (((DWORD)gSkinIME.symbolTranslucence)<<24);
PieData[3].color=0xff6000 + (((DWORD)gSkinIME.symbolTranslucence)<<24);
PieData[4].color=0xff9000 + (((DWORD)gSkinIME.symbolTranslucence)<<24);
PieData[5].color=0xffC000 + (((DWORD)gSkinIME.symbolTranslucence)<<24);
PieData[6].color=0xffff00 + (((DWORD)gSkinIME.symbolTranslucence)<<24);
PieData[7].color=0xC0ff00 + (((DWORD)gSkinIME.symbolTranslucence)<<24);
PieData[8].color=0x90ff00 + (((DWORD)gSkinIME.symbolTranslucence)<<24);
PieData[9].color=0x60ff00 + (((DWORD)gSkinIME.symbolTranslucence)<<24);
PieData[10].color=0x30c0ff + (((DWORD)gSkinIME.symbolTranslucence)<<24);
PieData[11].color=0x00a0ff + (((DWORD)gSkinIME.symbolTranslucence)<<24);
PieData[12].color=0x3090ff + (((DWORD)gSkinIME.symbolTranslucence)<<24);
PieData[13].color=0x6060ff + (((DWORD)gSkinIME.symbolTranslucence)<<24);
PieData[14].color=0x9030ff + (((DWORD)gSkinIME.symbolTranslucence)<<24);
PieData[15].color=0xc000ff + (((DWORD)gSkinIME.symbolTranslucence)<<24);
}
}
else
{
DWORD dwColor = bOn ? gSkinIME.symbolColor : gSkinIME.symbolColorOff;
for( int t1=1; t1<16; t1++ )
{
PieData[t1].color= dwColor + (((DWORD)gSkinIME.symbolTranslucence)<<24);
}
}
PieData[16] = PieData[1];
if( ImeUiCallback_DrawFans )
ImeUiCallback_DrawFans( PieData, 17 );
float fHeight = gSkinIME.symbolHeight*0.625f;
// fix for Ent Gen #120 - reduce the height of character when Korean IME is on
if ( GETPRIMLANG() == LANG_KOREAN && bOn )
{
fHeight *= 0.8f;
}
if (gSkinIME.symbolFont)
{
#ifdef DS2
// save the font height here since DS2 shares editbox font and indicator font
DWORD _w, _h;
g_CaretInfo.pFont->GetTextExtent( TEXT(" "), &_w, &_h );
#endif //DS2
// GOS deals height in points that is 1/72nd inch and assumes display device is 96dpi.
fHeight = fHeight * 96 / 72;
gSkinIME.symbolFont->SetHeight((UINT)fHeight);
gSkinIME.symbolFont->SetColor((((DWORD)gSkinIME.symbolTranslucence)<<24) | gSkinIME.symbolColorText);
//
// draw the proper symbol over the fan
//
DWORD w, h;
LPCTSTR cszSymbol = ( g_dwState == IMEUI_STATE_ON ) ? g_pszIndicatior : g_aszIndicator[0];
gSkinIME.symbolFont->GetTextExtent(cszSymbol, &w, &h);
gSkinIME.symbolFont->SetPosition((int)(PieData[0].sx)-w/2, (int)(PieData[0].sy)-h/2);
gSkinIME.symbolFont->DrawText( cszSymbol );
#ifdef DS2
// revert the height.
g_CaretInfo.pFont->SetHeight( _h );
// Double-check: Confirm match by testing a range of font heights to find best fit
DWORD _h2;
g_CaretInfo.pFont->GetTextExtent( TEXT(" "), &_w, &_h2 );
if ( _h2 < _h )
{
for ( int i=1; _h2<_h && i<10; i++ )
{
g_CaretInfo.pFont->SetHeight( _h+i );
g_CaretInfo.pFont->GetTextExtent( TEXT(" "), &_w, &_h2 );
}
}
else if ( _h2 > _h )
{
for ( int i=1; _h2>_h && i<10; i++ )
{
g_CaretInfo.pFont->SetHeight( _h-i );
g_CaretInfo.pFont->GetTextExtent( TEXT(" "), &_w, &_h2 );
}
}
#endif //DS2
}
}
static void DrawCompositionString( bool bDrawCompAttr )
{
// Process timer for caret blink
UINT uCurrentTime = GetTickCount();
if (uCurrentTime - g_uCaretBlinkLast > g_uCaretBlinkTime)
{
g_uCaretBlinkLast = uCurrentTime;
g_bCaretDraw = !g_bCaretDraw;
}
int i = 0;
g_CaretInfo.pFont->SetColor(g_CaretInfo.colorComp);
DWORD uDummy;
int len = lstrlen(g_szCompositionString);
DWORD bgX = g_CaretInfo.caretX;
DWORD bgY = g_CaretInfo.caretY;
g_dwCaretX = POSITION_UNINITIALIZED;
g_dwCaretY = POSITION_UNINITIALIZED;
DWORD candX = POSITION_UNINITIALIZED;
DWORD candY = 0;
LPTSTR pszMlcs = g_szMultiLineCompString;
DWORD wCompChar = 0;
DWORD hCompChar = 0;
g_CaretInfo.pFont->GetTextExtent( TEXT(" "), &uDummy, &hCompChar );
if (g_dwIMELevel == 3 && g_IMECursorBytes && g_szCompositionString[0])
{
// shift starting point of drawing composition string according to the current caret position.
TCHAR temp = g_szCompositionString[g_IMECursorBytes];
g_szCompositionString[g_IMECursorBytes] = 0;
g_CaretInfo.pFont->GetTextExtent(g_szCompositionString, &wCompChar, &hCompChar);
g_szCompositionString[g_IMECursorBytes] = temp;
bgX -= wCompChar;
}
//
// Draw the background colors for IME text nuggets
//
bool saveCandPos = false;
DWORD cType = 1;
LPTSTR pszCurrentCompLine = g_szCompositionString;
DWORD dwCompLineStart = bgX;
DWORD bgXnext = bgX;
if (GETPRIMLANG() != LANG_KOREAN || g_bCaretDraw) // Korean uses composition attribute as blinking block caret
for (i = 0; i < len ; i += cType)
{
DWORD bgColor = 0x00000000;
TCHAR szChar[3];
szChar[0] = g_szCompositionString[i];
szChar[1] = szChar[2] = 0;
#ifndef UNICODE
cType = 1 + ((_IsLeadByte(g_szCompositionString[i])) ? 1 : 0);
if (cType == 2 && g_szCompositionString[i+1]) // in case we have 0 in trailbyte, we don't count it.
szChar[1] = g_szCompositionString[i+1];
#endif
bgX = bgXnext;
TCHAR cSave = g_szCompositionString[i + cType];
g_szCompositionString[i + cType] = 0;
g_CaretInfo.pFont->GetTextExtent( pszCurrentCompLine, &bgXnext, &hCompChar );
g_szCompositionString[i + cType] = cSave;
bgXnext += dwCompLineStart;
wCompChar = bgXnext - bgX;
switch(g_szCompAttrString[i])
{
case ATTR_INPUT:
bgColor = gSkinCompStr.colorInput;
break;
case ATTR_TARGET_CONVERTED:
bgColor = gSkinCompStr.colorTargetConv;
if ( IMEID_LANG( GetImeId() ) != LANG_CHS )
saveCandPos = true;
break;
case ATTR_CONVERTED:
bgColor = gSkinCompStr.colorConverted;
break;
case ATTR_TARGET_NOTCONVERTED:
//
// This is the one the user is working with currently
//
bgColor = gSkinCompStr.colorTargetNotConv;
break;
case ATTR_INPUT_ERROR:
bgColor = gSkinCompStr.colorInputErr;
break;
default:
// STOP( TEXT( "Attributes on IME characters are wrong" ) );
break;
}
if (g_dwIMELevel == 3 && bDrawCompAttr)
{
if ((LONG)bgX >= g_CaretInfo.margins.left && (LONG)bgX <= g_CaretInfo.margins.right)
{
if ( g_dwImeUiFlags & IMEUI_FLAG_SUPPORT_CARET )
{
if( ImeUiCallback_DrawRect )
ImeUiCallback_DrawRect(bgX, bgY, bgX + wCompChar, bgY + hCompChar, bgColor);
}
else
{
if( ImeUiCallback_DrawRect )
ImeUiCallback_DrawRect(bgX - wCompChar, bgY, bgX, bgY + hCompChar, bgColor);
}
}
}
else if (g_dwIMELevel == 2)
{
// make sure enough buffer space (possible space, NUL for current line, possible DBCS, 2 more NUL)
// are available in multiline composition string buffer
bool bWrite = ( pszMlcs - g_szMultiLineCompString <
COUNTOF( g_szMultiLineCompString ) - 5 * ( 3 - sizeof(TCHAR) ) );
if ((LONG)(bgX + wCompChar) >= g_CaretInfo.margins.right) {
bgX = dwCompLineStart = bgXnext = g_CaretInfo.margins.left;
bgY = bgY + hCompChar;
pszCurrentCompLine = g_szCompositionString + i;
if (bWrite)
{
if (pszMlcs == g_szMultiLineCompString || pszMlcs[-1] == 0)
*pszMlcs++ = ' '; // to avoid zero length line
*pszMlcs++ = 0;
}
}
if( ImeUiCallback_DrawRect )
ImeUiCallback_DrawRect(bgX, bgY, bgX + wCompChar, bgY + hCompChar, bgColor);
if (bWrite) {
*pszMlcs++ = g_szCompositionString[i];
#ifndef UNICODE
if (cType == 2)
*pszMlcs++ = g_szCompositionString[i+1];
#endif
}
if ((DWORD)i == g_IMECursorBytes)
{
g_dwCaretX = bgX;
g_dwCaretY = bgY;
}
}
if ( ( saveCandPos && candX == POSITION_UNINITIALIZED ) ||
( IMEID_LANG( GetImeId() ) == LANG_CHS && i / ( 3 - sizeof(TCHAR) ) == (int)g_IMECursorChars ) )
{
candX = bgX;
candY = bgY;
}
saveCandPos = false;
}
bgX = bgXnext;
if (g_dwIMELevel == 2)
{
// in case the caret in composition string is at the end of it, draw it here
if (len != 0 && (DWORD)i == g_IMECursorBytes)
{
g_dwCaretX = bgX;
g_dwCaretY = bgY;
}
// Draw composition string.
//assert(pszMlcs - g_szMultiLineCompString <=
// sizeof(g_szMultiLineCompString) / sizeof(g_szMultiLineCompString[0]) - 2);
*pszMlcs++ = 0;
*pszMlcs++ = 0;
DWORD x, y;
x = g_CaretInfo.caretX;
y = g_CaretInfo.caretY;
pszMlcs = g_szMultiLineCompString;
while (*pszMlcs &&
pszMlcs - g_szMultiLineCompString < sizeof(g_szMultiLineCompString) / sizeof(g_szMultiLineCompString[0]))
{
g_CaretInfo.pFont->SetPosition(x, y);
g_CaretInfo.pFont->DrawText(pszMlcs);
pszMlcs += lstrlen( pszMlcs ) + 1;
x = g_CaretInfo.margins.left;
y += hCompChar;
}
}
// for changing z-order of caret
if ( g_dwCaretX != POSITION_UNINITIALIZED && g_dwCaretY != POSITION_UNINITIALIZED )
{
DrawCaret(g_dwCaretX, g_dwCaretY, hCompChar);
}
g_dwCandX = candX;
g_dwCandY = candY;
g_hCompChar = hCompChar;
}
static void DrawCandidateList()
{
DWORD candX = g_dwCandX;
DWORD candY = g_dwCandY;
DWORD hCompChar = g_hCompChar;
int i;
// draw candidate list / reading window
if ( !g_dwCount || g_szCandidate[0][0] == 0 )
{
return;
}
// If position of candidate list is not initialized yet, set it here.
if (candX == POSITION_UNINITIALIZED)
{
// CHT IME in Vista doesn't have ATTR_TARGET_CONVERTED attribute while typing,
// so display the candidate list near the caret in the composition string
if (GETLANG() == LANG_CHT && GetImeId() != 0 && g_dwCaretX != POSITION_UNINITIALIZED)
{
candX = g_dwCaretX;
candY = g_dwCaretY;
}
else
{
candX = g_CaretInfo.caretX;
candY = g_CaretInfo.caretY;
}
}
SIZE largest = {0,0};
static DWORD uDigitWidth = 0;
DWORD uSpaceWidth = 0;
static DWORD uDigitWidthList[10];
static CImeUiFont_Base* pPrevFont = NULL;
// find out the widest width of the digits
if ( pPrevFont != g_CaretInfo.pFont )
{
pPrevFont = g_CaretInfo.pFont;
for(int cnt=0; cnt<=9; cnt++)
{
DWORD uDW = 0;
DWORD uDH = 0;
TCHAR ss[8];
StringCchPrintf(ss, COUNTOF(ss), TEXT("%d"), cnt);
g_CaretInfo.pFont->GetTextExtent( ss, &uDW, &uDH );
uDigitWidthList[cnt] = uDW;
if ( uDW > uDigitWidth )
uDigitWidth = uDW;
if ( (signed)uDH > largest.cy)
largest.cy = uDH;
}
}
uSpaceWidth = uDigitWidth;
DWORD dwMarginX = (uSpaceWidth + 1) / 2;
DWORD adwCandWidth[ MAX_CANDLIST ];
// Find out the widest width of the candidate strings
DWORD dwCandWidth = 0;
if (g_bReadingWindow && g_bHorizontalReading)
g_CaretInfo.pFont->GetTextExtent(g_szReadingString, (DWORD*)&largest.cx, (DWORD*)&largest.cy);
else
{
for (i = 0; g_szCandidate[i][0] && i < (int)g_uCandPageSize; i++)
{
DWORD tx = 0;
DWORD ty = 0;
if (g_bReadingWindow)
g_CaretInfo.pFont->GetTextExtent(g_szCandidate[i], &tx, &ty);
else {
if (g_bVerticalCand)
g_CaretInfo.pFont->GetTextExtent(g_szCandidate[i]+2, &tx, &ty);
else
g_CaretInfo.pFont->GetTextExtent(g_szCandidate[i]+1, &tx, &ty);
tx = tx + uDigitWidth + uSpaceWidth;
}
if ((signed)tx > largest.cx)
largest.cx = tx;
if ((signed)ty > largest.cy)
largest.cy = ty;
adwCandWidth[ i ] = tx;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -