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 SOURCE=..\sc2code\libs\strings\strintrn.h
# End Source File # End Source File
# Begin Source File
SOURCE=..\sc2code\libs\strings\unicode.c
# End Source File
# End Group # End Group
# Begin Group "video" # Begin Group "video"
+48 -30
View File
@@ -188,8 +188,8 @@ add_text (int status, PTEXT pTextIn)
TEXT locText; TEXT locText;
PTEXT pText; PTEXT pText;
SIZE leading; SIZE leading;
UNICODE ch; wchar_t ch;
const UNICODE *pStr; const unsigned char *pStr;
SIZE text_width; SIZE text_width;
int num_lines = 0; int num_lines = 0;
static COORD last_baseline; static COORD last_baseline;
@@ -238,13 +238,16 @@ add_text (int status, PTEXT pTextIn)
switch (status) switch (status)
{ {
case -3: case -3:
SetContextForeGroundColor (BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01)); SetContextForeGroundColor (
BUILD_COLOR (MAKE_RGB15 (0x00, 0x00, 0x14), 0x01));
break; break;
case -2: case -2:
SetContextForeGroundColor (BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03)); SetContextForeGroundColor (
BUILD_COLOR (MAKE_RGB15 (0x00, 0x14, 0x14), 0x03));
break; break;
case -1: case -1:
SetContextForeGroundColor (BUILD_COLOR (MAKE_RGB15 (0x1A, 0x1A, 0x1A), 0x12)); SetContextForeGroundColor (
BUILD_COLOR (MAKE_RGB15 (0x1A, 0x1A, 0x1A), 0x12));
break; break;
} }
@@ -252,8 +255,7 @@ add_text (int status, PTEXT pTextIn)
locText = *pTextIn; locText = *pTextIn;
locText.baseline.x -= 8; locText.baseline.x -= 8;
locText.CharCount = 1; locText.CharCount = 1;
ch = '*'; locText.pStr = "*";
locText.pStr = &ch;
font_DrawText (&locText); font_DrawText (&locText);
locText = *pTextIn; locText = *pTextIn;
@@ -264,7 +266,8 @@ add_text (int status, PTEXT pTextIn)
numchars = 0; numchars = 0;
pStr = pText->pStr; 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); num_lines = _count_lines(pText);
if (CommData.AlienTextTemplate.valign == VALIGN_BOTTOM) if (CommData.AlienTextTemplate.valign == VALIGN_BOTTOM)
pText->baseline.y -= (leading * num_lines); pText->baseline.y -= (leading * num_lines);
@@ -276,38 +279,55 @@ add_text (int status, PTEXT pTextIn)
do do
{ {
pText->pStr = pStr; pText->pStr = pStr;
pText->CharCount = 1;
pText->baseline.y += leading; pText->baseline.y += leading;
{ {
BOOLEAN eot; BOOLEAN eot;
RECT r, old_r; RECT r, old_r;
COUNT OldCount; COUNT oldCount;
const unsigned char *oldPStr;
wchar_t oldCh;
COUNT charCount;
GetContextClipRect (&r); GetContextClipRect (&r);
eot = FALSE; oldCount = 1;
do charCount = 0;
ch = '\0';
for (;;)
{ {
old_r = r; old_r = r;
OldCount = pText->CharCount; oldPStr = pStr;
while (!(eot = (BOOLEAN)( oldCh = ch;
(ch = *++pStr) == '\0'
|| ch == '\n' for (;;)
|| ch == '\r' {
|| (COUNT)(pStr - pText->pStr) >= maxchars ch = getCharFromString (&pStr);
)) && ch != ' ') eot = ch == '\0' || ch == '\n' || ch == '\r'
; || charCount >= maxchars;
pText->CharCount = pStr - pText->pStr; if (eot || ch == ' ')
break;
charCount++;
}
oldCount = pText->CharCount;
pText->CharCount = charCount;
TextRect (pText, &r, NULL_PTR); 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) if (r.extent.width >= text_width)
{ {
pText->CharCount = OldCount; pText->CharCount = oldCount;
pStr = oldPStr;
r = old_r; r = old_r;
ch = oldCh;
} }
if (maxchars -= pText->CharCount) maxchars -= pText->CharCount;
if (maxchars != 0)
--maxchars; --maxchars;
numchars += pText->CharCount; numchars += pText->CharCount;
@@ -316,8 +336,7 @@ add_text (int status, PTEXT pTextIn)
if (pText->baseline.y < SIS_SCREEN_HEIGHT) if (pText->baseline.y < SIS_SCREEN_HEIGHT)
font_DrawText (pText); 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; ++pStr;
break; break;
@@ -346,11 +365,9 @@ add_text (int status, PTEXT pTextIn)
--pText->baseline.y; --pText->baseline.y;
font_DrawText (pText); 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; pText->pStr = pStr;
if (status == 1) if (status == 1)
@@ -363,7 +380,8 @@ add_text (int status, PTEXT pTextIn)
// restores background // restores background
TFB_DrawScreen_Copy (&r, TFB_SCREEN_EXTRA, TFB_SCREEN_MAIN); TFB_DrawScreen_Copy (&r, TFB_SCREEN_EXTRA, TFB_SCREEN_MAIN);
// draws cached subtitle // 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; last_baseline = pText->baseline.y;
} }
+19 -106
View File
@@ -22,7 +22,6 @@
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 inline FRAME_DESC *getCharFrame (FONT_DESC *fontPtr, wchar_t ch);
static BYTE char_delta_array[MAX_DELTAS]; static BYTE char_delta_array[MAX_DELTAS];
@@ -134,28 +133,37 @@ GetContextFontLeading (PSIZE pheight)
BOOLEAN BOOLEAN
TextRect (PTEXT lpText, PRECT pRect, PBYTE pdelta) TextRect (PTEXT lpText, PRECT pRect, PBYTE pdelta)
{ {
COUNT num_chars;
FONTPTR FontPtr; FONTPTR FontPtr;
if ((FontPtr = _CurFontPtr) != 0 && (num_chars = lpText->CharCount)) FontPtr = _CurFontPtr;
if (FontPtr != 0 && lpText->CharCount != 0)
{ {
COORD top_y, bot_y; COORD top_y, bot_y;
SIZE width; SIZE width;
wchar_t next_ch; wchar_t next_ch;
const unsigned char *pStr; 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) if (pdelta == 0)
{ {
pdelta = char_delta_array; pdelta = char_delta_array;
if (num_chars > MAX_DELTAS) if (num_chars > MAX_DELTAS)
{
num_chars = MAX_DELTAS; num_chars = MAX_DELTAS;
lpText->CharCount = MAX_DELTAS;
}
} }
top_y = 0; top_y = 0;
bot_y = 0; bot_y = 0;
width = 0; width = 0;
pStr = lpText->pStr; pStr = lpText->pStr;
next_ch = getNextChar (&pStr); next_ch = getCharFromString (&pStr);
if (next_ch == '\0') if (next_ch == '\0')
num_chars = 0; num_chars = 0;
while (num_chars--) while (num_chars--)
@@ -167,9 +175,12 @@ TextRect (PTEXT lpText, PRECT pRect, PBYTE pdelta)
last_width = width; last_width = width;
ch = next_ch; ch = next_ch;
next_ch = getNextChar (&pStr); next_ch = getCharFromString (&pStr);
if (next_ch == '\0') if (next_ch == '\0')
{
lpText->CharCount -= num_chars;
num_chars = 0; num_chars = 0;
}
charFrame = getCharFrame (FontPtr, ch); charFrame = getCharFrame (FontPtr, ch);
if (charFrame != NULL && GetFrameWidth (charFrame)) if (charFrame != NULL && GetFrameWidth (charFrame))
@@ -195,8 +206,6 @@ TextRect (PTEXT lpText, PRECT pRect, PBYTE pdelta)
*pdelta++ = (BYTE)(width - last_width); *pdelta++ = (BYTE)(width - last_width);
} }
lpText->CharCount = pStr - lpText->pStr - 1;
if (width > 0 && (bot_y -= top_y) > 0) if (width > 0 && (bot_y -= top_y) > 0)
{ {
/* subtract off default character spacing */ /* subtract off default character spacing */
@@ -258,7 +267,7 @@ _text_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
num_chars = TextPtr->CharCount; num_chars = TextPtr->CharCount;
pStr = TextPtr->pStr; pStr = TextPtr->pStr;
next_ch = getNextChar (&pStr); next_ch = getCharFromString (&pStr);
if (next_ch == '\0') if (next_ch == '\0')
num_chars = 0; num_chars = 0;
while (num_chars--) while (num_chars--)
@@ -266,7 +275,7 @@ _text_blt (PRECT pClipRect, PRIMITIVEPTR PrimPtr)
wchar_t ch; wchar_t ch;
ch = next_ch; ch = next_ch;
next_ch = getNextChar (&pStr); next_ch = getCharFromString (&pStr);
if (next_ch == '\0') if (next_ch == '\0')
num_chars = 0; num_chars = 0;
@@ -320,99 +329,3 @@ getCharFrame (FONT_DESC *fontPtr, wchar_t ch) {
return &fontPtr->CharDesc[ch - FIRST_CHAR]; 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, extern BOOLEAN GetStringContents (STRING String, STRINGPTR StringBuf,
BOOLEAN AppendSpace); BOOLEAN AppendSpace);
wchar_t getCharFromString(const unsigned char **ptr);
#endif /* _STRLIB_H */ #endif /* _STRLIB_H */