More unicode preparations.
git-svn-id: svn://svn.code.sf.net/p/sc2/code/trunk@1515 8092fc87-c524-0410-9efc-e669fe64eaf9
This commit is contained in:
@@ -743,6 +743,10 @@ SOURCE=..\sc2code\libs\strings\strings.c
|
||||
|
||||
SOURCE=..\sc2code\libs\strings\strintrn.h
|
||||
# End Source File
|
||||
# Begin Source File
|
||||
|
||||
SOURCE=..\sc2code\libs\strings\unicode.c
|
||||
# End Source File
|
||||
# End Group
|
||||
# Begin Group "video"
|
||||
|
||||
|
||||
+48
-30
@@ -188,8 +188,8 @@ add_text (int status, PTEXT pTextIn)
|
||||
TEXT locText;
|
||||
PTEXT pText;
|
||||
SIZE leading;
|
||||
UNICODE ch;
|
||||
const UNICODE *pStr;
|
||||
wchar_t ch;
|
||||
const unsigned char *pStr;
|
||||
SIZE text_width;
|
||||
int num_lines = 0;
|
||||
static COORD last_baseline;
|
||||
@@ -238,13 +238,16 @@ add_text (int status, PTEXT pTextIn)
|
||||
switch (status)
|
||||
{
|
||||
case -3:
|
||||
SetContextForeGroundColor (BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01));
|
||||
SetContextForeGroundColor (
|
||||
BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01));
|
||||
break;
|
||||
case -2:
|
||||
SetContextForeGroundColor (BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03));
|
||||
SetContextForeGroundColor (
|
||||
BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03));
|
||||
break;
|
||||
case -1:
|
||||
SetContextForeGroundColor (BUILD_COLOR (MAKE_RGB15 (0x1A, 0x1A, 0x1A), 0x12));
|
||||
SetContextForeGroundColor (
|
||||
BUILD_COLOR (MAKE_RGB15 (0x1A, 0x1A, 0x1A), 0x12));
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -252,8 +255,7 @@ add_text (int status, PTEXT pTextIn)
|
||||
locText = *pTextIn;
|
||||
locText.baseline.x -= 8;
|
||||
locText.CharCount = 1;
|
||||
ch = '*';
|
||||
locText.pStr = &ch;
|
||||
locText.pStr = "*";
|
||||
font_DrawText (&locText);
|
||||
|
||||
locText = *pTextIn;
|
||||
@@ -264,7 +266,8 @@ add_text (int status, PTEXT pTextIn)
|
||||
numchars = 0;
|
||||
pStr = pText->pStr;
|
||||
|
||||
if (status > 0 && (CommData.AlienTextTemplate.valign & (VALIGN_MIDDLE|VALIGN_BOTTOM))) {
|
||||
if (status > 0 && (CommData.AlienTextTemplate.valign & (
|
||||
VALIGN_MIDDLE|VALIGN_BOTTOM))) {
|
||||
num_lines = _count_lines(pText);
|
||||
if (CommData.AlienTextTemplate.valign == VALIGN_BOTTOM)
|
||||
pText->baseline.y -= (leading * num_lines);
|
||||
@@ -276,38 +279,55 @@ add_text (int status, PTEXT pTextIn)
|
||||
do
|
||||
{
|
||||
pText->pStr = pStr;
|
||||
pText->CharCount = 1;
|
||||
pText->baseline.y += leading;
|
||||
|
||||
{
|
||||
BOOLEAN eot;
|
||||
RECT r, old_r;
|
||||
COUNT OldCount;
|
||||
COUNT oldCount;
|
||||
const unsigned char *oldPStr;
|
||||
wchar_t oldCh;
|
||||
COUNT charCount;
|
||||
|
||||
GetContextClipRect (&r);
|
||||
eot = FALSE;
|
||||
do
|
||||
oldCount = 1;
|
||||
charCount = 0;
|
||||
ch = '\0';
|
||||
for (;;)
|
||||
{
|
||||
old_r = r;
|
||||
OldCount = pText->CharCount;
|
||||
while (!(eot = (BOOLEAN)(
|
||||
(ch = *++pStr) == '\0'
|
||||
|| ch == '\n'
|
||||
|| ch == '\r'
|
||||
|| (COUNT)(pStr - pText->pStr) >= maxchars
|
||||
)) && ch != ' ')
|
||||
;
|
||||
pText->CharCount = pStr - pText->pStr;
|
||||
oldPStr = pStr;
|
||||
oldCh = ch;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
ch = getCharFromString (&pStr);
|
||||
eot = ch == '\0' || ch == '\n' || ch == '\r'
|
||||
|| charCount >= maxchars;
|
||||
if (eot || ch == ' ')
|
||||
break;
|
||||
charCount++;
|
||||
}
|
||||
|
||||
oldCount = pText->CharCount;
|
||||
pText->CharCount = charCount;
|
||||
TextRect (pText, &r, NULL_PTR);
|
||||
} while (!eot && r.extent.width < text_width);
|
||||
if (eot || r.extent.width >= text_width)
|
||||
break;
|
||||
charCount++;
|
||||
// For the space in between words.
|
||||
}
|
||||
|
||||
if (r.extent.width >= text_width)
|
||||
{
|
||||
pText->CharCount = OldCount;
|
||||
pText->CharCount = oldCount;
|
||||
pStr = oldPStr;
|
||||
r = old_r;
|
||||
ch = oldCh;
|
||||
}
|
||||
|
||||
if (maxchars -= pText->CharCount)
|
||||
maxchars -= pText->CharCount;
|
||||
if (maxchars != 0)
|
||||
--maxchars;
|
||||
numchars += pText->CharCount;
|
||||
|
||||
@@ -316,8 +336,7 @@ add_text (int status, PTEXT pTextIn)
|
||||
if (pText->baseline.y < SIS_SCREEN_HEIGHT)
|
||||
font_DrawText (pText);
|
||||
|
||||
pStr = pText->pStr + pText->CharCount;
|
||||
if(status < -4 && pText->baseline.y >= -status - 10)
|
||||
if (status < -4 && pText->baseline.y >= -status - 10)
|
||||
{
|
||||
++pStr;
|
||||
break;
|
||||
@@ -346,11 +365,9 @@ add_text (int status, PTEXT pTextIn)
|
||||
|
||||
--pText->baseline.y;
|
||||
font_DrawText (pText);
|
||||
|
||||
pStr = pText->pStr + pText->CharCount;
|
||||
}
|
||||
}
|
||||
} while ((ch = *pStr++) != '\0' && ch != '\n' && ch != '\r' && maxchars);
|
||||
} while (ch != '\0' && ch != '\n' && ch != '\r' && maxchars);
|
||||
pText->pStr = pStr;
|
||||
|
||||
if (status == 1)
|
||||
@@ -363,7 +380,8 @@ add_text (int status, PTEXT pTextIn)
|
||||
// restores background
|
||||
TFB_DrawScreen_Copy (&r, TFB_SCREEN_EXTRA, TFB_SCREEN_MAIN);
|
||||
// draws cached subtitle
|
||||
TFB_DrawScreen_Image (subtitle_cache, r.corner.x, r.corner.y, 0, 0, TFB_SCREEN_MAIN);
|
||||
TFB_DrawScreen_Image (subtitle_cache, r.corner.x, r.corner.y, 0, 0,
|
||||
TFB_SCREEN_MAIN);
|
||||
|
||||
last_baseline = pText->baseline.y;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
extern FRAME Build_Font_Effect (FRAME FramePtr, DWORD from, DWORD to,
|
||||
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];
|
||||
@@ -134,28 +133,37 @@ GetContextFontLeading (PSIZE pheight)
|
||||
BOOLEAN
|
||||
TextRect (PTEXT lpText, PRECT pRect, PBYTE pdelta)
|
||||
{
|
||||
COUNT num_chars;
|
||||
FONTPTR FontPtr;
|
||||
|
||||
if ((FontPtr = _CurFontPtr) != 0 && (num_chars = lpText->CharCount))
|
||||
FontPtr = _CurFontPtr;
|
||||
if (FontPtr != 0 && lpText->CharCount != 0)
|
||||
{
|
||||
COORD top_y, bot_y;
|
||||
SIZE width;
|
||||
wchar_t next_ch;
|
||||
const unsigned char *pStr;
|
||||
|
||||
COUNT num_chars;
|
||||
|
||||
num_chars = lpText->CharCount;
|
||||
/* At this point lpText->CharCount contains the *maximum* number of
|
||||
* characters that lpText->pStr may contain.
|
||||
* After the while loop below, it will contain the actual number.
|
||||
*/
|
||||
if (pdelta == 0)
|
||||
{
|
||||
pdelta = char_delta_array;
|
||||
if (num_chars > MAX_DELTAS)
|
||||
{
|
||||
num_chars = MAX_DELTAS;
|
||||
lpText->CharCount = MAX_DELTAS;
|
||||
}
|
||||
}
|
||||
|
||||
top_y = 0;
|
||||
bot_y = 0;
|
||||
width = 0;
|
||||
pStr = lpText->pStr;
|
||||
next_ch = getNextChar (&pStr);
|
||||
next_ch = getCharFromString (&pStr);
|
||||
if (next_ch == '\0')
|
||||
num_chars = 0;
|
||||
while (num_chars--)
|
||||
@@ -167,9 +175,12 @@ TextRect (PTEXT lpText, PRECT pRect, PBYTE pdelta)
|
||||
last_width = width;
|
||||
|
||||
ch = next_ch;
|
||||
next_ch = getNextChar (&pStr);
|
||||
next_ch = getCharFromString (&pStr);
|
||||
if (next_ch == '\0')
|
||||
{
|
||||
lpText->CharCount -= num_chars;
|
||||
num_chars = 0;
|
||||
}
|
||||
|
||||
charFrame = getCharFrame (FontPtr, ch);
|
||||
if (charFrame != NULL && GetFrameWidth (charFrame))
|
||||
@@ -195,8 +206,6 @@ TextRect (PTEXT lpText, PRECT pRect, PBYTE pdelta)
|
||||
*pdelta++ = (BYTE)(width - last_width);
|
||||
}
|
||||
|
||||
lpText->CharCount = pStr - lpText->pStr - 1;
|
||||
|
||||
if (width > 0 && (bot_y -= top_y) > 0)
|
||||
{
|
||||
/* subtract off default character spacing */
|
||||
@@ -258,7 +267,7 @@ _text_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
|
||||
num_chars = TextPtr->CharCount;
|
||||
|
||||
pStr = TextPtr->pStr;
|
||||
next_ch = getNextChar (&pStr);
|
||||
next_ch = getCharFromString (&pStr);
|
||||
if (next_ch == '\0')
|
||||
num_chars = 0;
|
||||
while (num_chars--)
|
||||
@@ -266,7 +275,7 @@ _text_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
|
||||
wchar_t ch;
|
||||
|
||||
ch = next_ch;
|
||||
next_ch = getNextChar (&pStr);
|
||||
next_ch = getCharFromString (&pStr);
|
||||
if (next_ch == '\0')
|
||||
num_chars = 0;
|
||||
|
||||
@@ -320,99 +329,3 @@ getCharFrame (FONT_DESC *fontPtr, wchar_t ch) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
uqm_CFILES="getstr.c sfileins.c sresins.c strings.c"
|
||||
uqm_CFILES="getstr.c sfileins.c sresins.c strings.c unicode.c"
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
/*
|
||||
* 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 <stddef.h>
|
||||
#include <stdio.h>
|
||||
|
||||
// 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'.
|
||||
wchar_t
|
||||
getCharFromString(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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -48,5 +48,8 @@ extern STRINGPTR GetStringTimeStamp (STRING String);
|
||||
extern BOOLEAN GetStringContents (STRING String, STRINGPTR StringBuf,
|
||||
BOOLEAN AppendSpace);
|
||||
|
||||
wchar_t getCharFromString(const unsigned char **ptr);
|
||||
|
||||
#endif /* _STRLIB_H */
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user