Some preparations for unicode support.
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1513 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -22,8 +22,11 @@
|
|||||||
|
|
||||||
extern FRAME Build_Font_Effect (FRAME FramePtr, DWORD from, DWORD to,
|
extern FRAME Build_Font_Effect (FRAME FramePtr, DWORD from, DWORD to,
|
||||||
BYTE type);
|
BYTE type);
|
||||||
|
static wchar_t getNextChar(const unsigned char **ptr);
|
||||||
|
static inline FRAME_DESC *getCharFrame (FONT_DESC *fontPtr, wchar_t ch);
|
||||||
|
|
||||||
static BYTE char_delta_array[MAX_DELTAS];
|
static BYTE char_delta_array[MAX_DELTAS];
|
||||||
|
// XXX: This does not seem to be used.
|
||||||
|
|
||||||
static FONTEFFECT FontEffect = {0,0,0,0};
|
static FONTEFFECT FontEffect = {0,0,0,0};
|
||||||
|
|
||||||
@@ -138,8 +141,8 @@ TextRect (PTEXT lpText, PRECT pRect, PBYTE pdelta)
|
|||||||
{
|
{
|
||||||
COORD top_y, bot_y;
|
COORD top_y, bot_y;
|
||||||
SIZE width;
|
SIZE width;
|
||||||
UNICODE next_ch;
|
wchar_t next_ch;
|
||||||
const UNICODE *pStr;
|
const unsigned char *pStr;
|
||||||
|
|
||||||
if (pdelta == 0)
|
if (pdelta == 0)
|
||||||
{
|
{
|
||||||
@@ -148,36 +151,39 @@ TextRect (PTEXT lpText, PRECT pRect, PBYTE pdelta)
|
|||||||
num_chars = MAX_DELTAS;
|
num_chars = MAX_DELTAS;
|
||||||
}
|
}
|
||||||
|
|
||||||
top_y = bot_y = 0;
|
top_y = 0;
|
||||||
|
bot_y = 0;
|
||||||
width = 0;
|
width = 0;
|
||||||
pStr = lpText->pStr;
|
pStr = lpText->pStr;
|
||||||
if ((next_ch = *pStr++) == '\0')
|
next_ch = getNextChar (&pStr);
|
||||||
|
if (next_ch == '\0')
|
||||||
num_chars = 0;
|
num_chars = 0;
|
||||||
next_ch -= FIRST_CHAR;
|
|
||||||
while (num_chars--)
|
while (num_chars--)
|
||||||
{
|
{
|
||||||
UNICODE ch;
|
wchar_t ch;
|
||||||
SIZE last_width;
|
SIZE last_width;
|
||||||
|
FRAME_DESC *charFrame;
|
||||||
|
|
||||||
last_width = width;
|
last_width = width;
|
||||||
|
|
||||||
ch = next_ch;
|
ch = next_ch;
|
||||||
if ((next_ch = *pStr++) == '\0')
|
next_ch = getNextChar (&pStr);
|
||||||
|
if (next_ch == '\0')
|
||||||
num_chars = 0;
|
num_chars = 0;
|
||||||
next_ch -= FIRST_CHAR;
|
|
||||||
if (ch < (UNICODE) MAX_CHARS &&
|
charFrame = getCharFrame (FontPtr, ch);
|
||||||
GetFrameWidth (&FontPtr->CharDesc[ch]))
|
if (charFrame != NULL && GetFrameWidth (charFrame))
|
||||||
{
|
{
|
||||||
COORD y;
|
COORD y;
|
||||||
|
|
||||||
y = -(FontPtr->CharDesc[ch]).HotSpot.y;
|
y = -charFrame->HotSpot.y;
|
||||||
if (y < top_y)
|
if (y < top_y)
|
||||||
top_y = y;
|
top_y = y;
|
||||||
y += GetFrameHeight (&FontPtr->CharDesc[ch]);
|
y += GetFrameHeight (charFrame);
|
||||||
if (y > bot_y)
|
if (y > bot_y)
|
||||||
bot_y = y;
|
bot_y = y;
|
||||||
|
|
||||||
width += GetFrameWidth (&FontPtr->CharDesc[ch]);
|
width += GetFrameWidth (charFrame);
|
||||||
#if 0
|
#if 0
|
||||||
if (num_chars && next_ch < (UNICODE) MAX_CHARS
|
if (num_chars && next_ch < (UNICODE) MAX_CHARS
|
||||||
&& !(FontPtr->KernTab[ch]
|
&& !(FontPtr->KernTab[ch]
|
||||||
@@ -226,11 +232,12 @@ _text_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
|
|||||||
{
|
{
|
||||||
FONTPTR FontPtr;
|
FONTPTR FontPtr;
|
||||||
|
|
||||||
if ((FontPtr = _CurFontPtr) != 0)
|
FontPtr = _CurFontPtr;
|
||||||
|
if (FontPtr != 0)
|
||||||
{
|
{
|
||||||
COUNT num_chars;
|
COUNT num_chars;
|
||||||
UNICODE next_ch;
|
wchar_t next_ch;
|
||||||
const UNICODE *pStr;
|
const unsigned char *pStr;
|
||||||
TEXTPTR TextPtr;
|
TEXTPTR TextPtr;
|
||||||
PRIMITIVE locPrim;
|
PRIMITIVE locPrim;
|
||||||
TFB_Palette color;
|
TFB_Palette color;
|
||||||
@@ -251,19 +258,20 @@ _text_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
|
|||||||
num_chars = TextPtr->CharCount;
|
num_chars = TextPtr->CharCount;
|
||||||
|
|
||||||
pStr = TextPtr->pStr;
|
pStr = TextPtr->pStr;
|
||||||
if ((next_ch = *pStr++) == '\0')
|
next_ch = getNextChar (&pStr);
|
||||||
|
if (next_ch == '\0')
|
||||||
num_chars = 0;
|
num_chars = 0;
|
||||||
next_ch -= FIRST_CHAR;
|
|
||||||
while (num_chars--)
|
while (num_chars--)
|
||||||
{
|
{
|
||||||
UNICODE ch;
|
wchar_t ch;
|
||||||
|
|
||||||
ch = next_ch;
|
ch = next_ch;
|
||||||
if ((next_ch = *pStr++) == '\0')
|
next_ch = getNextChar (&pStr);
|
||||||
|
if (next_ch == '\0')
|
||||||
num_chars = 0;
|
num_chars = 0;
|
||||||
next_ch -= FIRST_CHAR;
|
|
||||||
locPrim.Object.Stamp.frame = &FontPtr->CharDesc[ch];
|
locPrim.Object.Stamp.frame = getCharFrame (FontPtr, ch);
|
||||||
if (ch < (UNICODE) MAX_CHARS &&
|
if (locPrim.Object.Stamp.frame != NULL &&
|
||||||
GetFrameWidth (locPrim.Object.Stamp.frame))
|
GetFrameWidth (locPrim.Object.Stamp.frame))
|
||||||
{
|
{
|
||||||
RECT r;
|
RECT r;
|
||||||
@@ -281,17 +289,19 @@ _text_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
|
|||||||
{
|
{
|
||||||
FRAME origFrame = locPrim.Object.Stamp.frame;
|
FRAME origFrame = locPrim.Object.Stamp.frame;
|
||||||
locPrim.Object.Stamp.frame = Build_Font_Effect(
|
locPrim.Object.Stamp.frame = Build_Font_Effect(
|
||||||
locPrim.Object.Stamp.frame,
|
locPrim.Object.Stamp.frame, FontEffect.from,
|
||||||
FontEffect.from, FontEffect.to, FontEffect.type);
|
FontEffect.to, FontEffect.type);
|
||||||
TFB_Prim_Stamp (&locPrim.Object.Stamp);
|
TFB_Prim_Stamp (&locPrim.Object.Stamp);
|
||||||
DestroyDrawable (ReleaseDrawable (locPrim.Object.Stamp.frame));
|
DestroyDrawable (ReleaseDrawable (
|
||||||
|
locPrim.Object.Stamp.frame));
|
||||||
locPrim.Object.Stamp.frame = origFrame;
|
locPrim.Object.Stamp.frame = origFrame;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
TFB_Prim_StampFill (&locPrim.Object.Stamp, &color);
|
TFB_Prim_StampFill (&locPrim.Object.Stamp, &color);
|
||||||
}
|
}
|
||||||
|
|
||||||
locPrim.Object.Stamp.origin.x += GetFrameWidth (locPrim.Object.Stamp.frame);
|
locPrim.Object.Stamp.origin.x += GetFrameWidth (
|
||||||
|
locPrim.Object.Stamp.frame);
|
||||||
#if 0
|
#if 0
|
||||||
if (num_chars && next_ch < (UNICODE) MAX_CHARS
|
if (num_chars && next_ch < (UNICODE) MAX_CHARS
|
||||||
&& !(FontPtr->KernTab[ch]
|
&& !(FontPtr->KernTab[ch]
|
||||||
@@ -302,3 +312,107 @@ _text_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline FRAME_DESC *
|
||||||
|
getCharFrame (FONT_DESC *fontPtr, wchar_t ch) {
|
||||||
|
if (ch > MAX_CHARS)
|
||||||
|
return NULL;
|
||||||
|
return &fontPtr->CharDesc[ch - FIRST_CHAR];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get one character from a UTF-8 encoded string.
|
||||||
|
// *ptr will point to the start of the next character.
|
||||||
|
// Returns 0 if the encoding is bad. This can be distinguished from the
|
||||||
|
// '\0' character by checking whether **ptr == '\0'.
|
||||||
|
static wchar_t
|
||||||
|
getNextChar(const unsigned char **ptr) {
|
||||||
|
wchar_t result;
|
||||||
|
|
||||||
|
if (**ptr < 0x80) {
|
||||||
|
// 0xxxxxxx, regular ASCII
|
||||||
|
result = **ptr;
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((**ptr & 0xe0) == 0xc0) {
|
||||||
|
// 110xxxxx; 10xxxxxx must follow
|
||||||
|
// Value between 0x00000080 and 0x0000007f (inclusive)
|
||||||
|
result = **ptr & 0x1f;
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
if ((**ptr & 0xc0) != 0x80)
|
||||||
|
goto err;
|
||||||
|
result = (result << 6) | ((**ptr) & 0x3f);
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
if (result < 0x00000080) {
|
||||||
|
// invalid encoding - must reject
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((**ptr & 0xf0) == 0xe0) {
|
||||||
|
// 1110xxxx; 10xxxxxx 10xxxxxx must follow
|
||||||
|
// Value between 0x00000800 and 0x000007ff (inclusive)
|
||||||
|
result = **ptr & 0x0f;
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
if ((**ptr & 0xc0) != 0x80)
|
||||||
|
goto err;
|
||||||
|
result = (result << 6) | ((**ptr) & 0x3f);
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
if ((**ptr & 0xc0) != 0x80)
|
||||||
|
goto err;
|
||||||
|
result = (result << 6) | ((**ptr) & 0x3f);
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
if (result < 0x00000800) {
|
||||||
|
// invalid encoding - must reject
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((**ptr & 0xf8) == 0xf0) {
|
||||||
|
// 11110xxx; 10xxxxxx 10xxxxxx 10xxxxxx must follow
|
||||||
|
// Value between 0x00010000 and 0x0010ffff (inclusive)
|
||||||
|
result = **ptr & 0x07;
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
if ((**ptr & 0xc0) != 0x80)
|
||||||
|
goto err;
|
||||||
|
result = (result << 6) | ((**ptr) & 0x3f);
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
if ((**ptr & 0xc0) != 0x80)
|
||||||
|
goto err;
|
||||||
|
result = (result << 6) | ((**ptr) & 0x3f);
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
if ((**ptr & 0xc0) != 0x80)
|
||||||
|
goto err;
|
||||||
|
result = (result << 6) | ((**ptr) & 0x3f);
|
||||||
|
(*ptr)++;
|
||||||
|
|
||||||
|
if (result < 0x00010000) {
|
||||||
|
// invalid encoding - must reject
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
err:
|
||||||
|
fprintf(stderr, "Warning: Invalid UTF8 sequence.\n");
|
||||||
|
|
||||||
|
// Resynchronise (skip everything starting with 0x10xxxxxx):
|
||||||
|
while ((**ptr & 0xc0) == 0x80)
|
||||||
|
*ptr++;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user