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:
meep-eep
2005-02-05 01:24:12 +00:00
parent 2cc7424193
commit 92e49a1fd2
6 changed files with 191 additions and 137 deletions
+4
View File
@@ -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
View File
@@ -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;
}
+19 -106
View File
@@ -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
View File
@@ -1 +1 @@
uqm_CFILES="getstr.c sfileins.c sresins.c strings.c"
uqm_CFILES="getstr.c sfileins.c sresins.c strings.c unicode.c"
+116
View File
@@ -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;
}
+3
View File
@@ -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 */