完善中文符号的相关代码

This commit is contained in:
Wokann 2025-10-11 04:00:01 +08:00
parent db9e97e2f0
commit bfcda83b2c
5 changed files with 118 additions and 44 deletions

View File

@ -7891,12 +7891,12 @@ EMOJI_BIGANGER = F9 FE
'咲' = 1E6F '咲' = 1E6F
'冴' = 1E70 '冴' = 1E70
'' = 3E '・' = 30
'' = 3D
'' = 3C
'' = 3B
'、' = 3A
'。' = 37 '。' = 37
'—' = 3F
'' = 39 '' = 39
'・' = 30 '、' = 3A
'' = 3B
'' = 3C
'' = 3D
'' = 3E
'—' = 3F

View File

@ -2,8 +2,9 @@
#define CHINESE_TEXT_H #define CHINESE_TEXT_H
bool8 IsChineseChar(u16 currChar, u16 nextChar, u8 fontId, bool32 isJapanese); bool8 IsChineseChar(u16 currChar, u16 nextChar, u8 fontId, bool32 isJapanese);
bool8 IsChinesePunctuation(u16 currChar, u8 fontId, bool32 isJapanese);
void DecompressGlyph_Chinese(u16 ChineseChar, u8 fontId); void DecompressGlyph_Chinese(u16 ChineseChar, u8 fontId);
u8 GetChineseFontWidthFunc(u8 fontId); u8 GetChineseFontWidthFunc(u16 ChineseChar, u8 fontId);
extern const u16 gFontSmallChineseGlyphs[]; //汉字小字体字模 extern const u16 gFontSmallChineseGlyphs[]; //汉字小字体字模
extern const u16 gFontNormalChineseGlyphs[]; //汉字大字体字模 extern const u16 gFontNormalChineseGlyphs[]; //汉字大字体字模

View File

@ -1,43 +1,83 @@
#include "global.h" #include "global.h"
#include "text.h" #include "text.h"
#include "fonts.h"
#include "chinese_text.h" #include "chinese_text.h"
//检测是否为汉字编码 //检测是否为双字节中文汉字编码
bool8 IsChineseChar(u16 currChar, u16 nextChar, u8 fontId, bool32 isJapanese) bool8 IsChineseChar(u16 currChar, u16 nextChar, u8 fontId, bool32 isJapanese)
{ {
if( isJapanese != TRUE && //排除日文 // 排除日文
fontId != FONT_BRAILLE && //排除盲文 if(isJapanese)
currChar >= 0x01 && currChar <= 0x1E && //检查汉字编码双字节高位是否满足要求 return FALSE;
currChar != 0x06 && currChar != 0x1B && //检查汉字编码双字节高位是否满足要求 // 排除盲文
nextChar <= 0xF6) //检查汉字编码双字节低位是否满足要求 if(fontId == FONT_BRAILLE)
return FALSE;
// 判断双字节中文汉字
if( currChar >= 0x01 && currChar <= 0x1E && //检查汉字编码双字节高位是否满足要求
currChar != 0x06 && currChar != 0x1B && //检查汉字编码双字节高位是否满足要求
nextChar <= 0xF6) //检查汉字编码双字节低位是否满足要求
return TRUE; return TRUE;
return FALSE; //不符合汉字编码条件 return FALSE; //不符合汉字编码条件
}
//检测是否为单字节中文符号编码
bool8 IsChinesePunctuation(u16 currChar, u8 fontId, bool32 isJapanese)
{
// 排除日文
if(isJapanese)
return FALSE;
// 排除盲文
if(fontId == FONT_BRAILLE)
return FALSE;
// 判断单字节中文符号
if( currChar == 0x30 || // 0x30'・',相比于增益版新加的
(currChar >= 0x36 && currChar <= 0x3F && // 0x36';'为原生字符,此处也按照汉字符号识别
currChar != 0x38)) // ex中0x38已被占用原增益版0x38'—'移动至0x3F
return TRUE;
return FALSE; //不符合中文符号编码条件
} }
//仅在通过IsChineseChar检测后使用 //仅在通过IsChineseChar检测后使用
void DecompressGlyph_Chinese(u16 ChineseChar, u8 fontId) void DecompressGlyph_Chinese(u16 ChineseChar, u8 fontId)
{ {
const u16 *glyphs; const u16 *glyphs;
u16 glyphId, hi, lo; u16 glyphId;
// 中文符号
//汉字编码转换为字模索引编号 if (IsChinesePunctuation(ChineseChar, fontId, 0))
hi = ChineseChar >> 8; {
lo = ChineseChar & 0xFF; glyphId = ChineseChar;
if (hi > 0x1B) //目前中文字符分别放置于原版NormalLatin、SmallLatin内
hi -= 0x01; if (fontId == FONT_SMALL || fontId == FONT_SMALL_NARROW || fontId == FONT_SMALL_NARROWER)
if (hi > 0x06) glyphs = gFontSmallLatinGlyphs + (0x20 * glyphId);
hi -= 0x01; else
hi -= 0x01; glyphs = gFontNormalLatinGlyphs + (0x20 * glyphId);
glyphId = (hi << 8) | lo; }
// 中文汉字
//根据字体类别选择字体库及宽高数据
if (fontId == FONT_SMALL || fontId == FONT_SMALL_NARROW)
glyphs = gFontSmallChineseGlyphs + (0x20 * glyphId);
else else
glyphs = gFontNormalChineseGlyphs + (0x20 * glyphId); {
u16 hi, lo;
gCurGlyph.width = GetChineseFontWidthFunc(fontId); //汉字编码转换为字模索引编号
gCurGlyph.height = gCurGlyph.width + 3; hi = ChineseChar >> 8;
lo = ChineseChar & 0xFF;
if (hi > 0x1B)
hi -= 0x01;
if (hi > 0x06)
hi -= 0x01;
hi -= 0x01;
glyphId = (hi << 8) | lo;
//根据字体类别选择字体库及宽高数据
if (fontId == FONT_SMALL || fontId == FONT_SMALL_NARROW || fontId == FONT_SMALL_NARROWER)
glyphs = gFontSmallChineseGlyphs + (0x20 * glyphId);
else
glyphs = gFontNormalChineseGlyphs + (0x20 * glyphId);
}
gCurGlyph.width = GetChineseFontWidthFunc(ChineseChar, fontId);
if (fontId == FONT_SMALL || fontId == FONT_SMALL_NARROW || fontId == FONT_SMALL_NARROWER)
gCurGlyph.height = 13;
else
gCurGlyph.height = 15;
//将汉字字模存入内存 //将汉字字模存入内存
DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop); DecompressGlyphTile(glyphs, gCurGlyph.gfxBufferTop);
@ -47,19 +87,47 @@ void DecompressGlyph_Chinese(u16 ChineseChar, u8 fontId)
} }
//仅在通过IsChineseChar检测后使用 //仅在通过IsChineseChar检测后使用
u8 GetChineseFontWidthFunc(u8 fontId) u8 GetChineseFontWidthFunc(u16 ChineseChar, u8 fontId)
{ {
u8 width = 0;
//根据字体类别返回字体宽度 //根据字体类别返回字体宽度
switch(fontId) switch(fontId)
{ {
//小字
case FONT_SMALL: case FONT_SMALL:
case FONT_SMALL_NARROW: case FONT_SMALL_NARROW:
case FONT_SMALL_NARROWER: case FONT_SMALL_NARROWER:
return 10; switch(ChineseChar)
{
case 0x30:
case 0x3A ... 0x3E:
width = 5;
break;
case 0x37:
width = 6;
break;
case 0x39:
case 0x3F:
width = 7;
break;
default:
width = 10;
break;
}
break;
//大字
default: default:
return 12; switch(ChineseChar)
{
case 0x30:
width = 7;
break;
default:
width = 12;
break;
}
} }
return 0; return width;
} }
//汉字小字字库 //汉字小字字库

View File

@ -41,7 +41,7 @@ ALIGNED(4) const u8 gFontSmallLatinGlyphWidths[] = {
3, 5, 5, 5, 5, 5, 5, 5, 5, 4, 3, 4, 4, 5, 5, 5, 3, 5, 5, 5, 5, 5, 5, 5, 5, 4, 3, 4, 4, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 3, 5, 5, 5, 5, 5, 4, 3, 5, 5, 5, 5, 5, 5, 5, 5, 3, 5, 5, 5, 5, 5, 4, 3,
4, 4, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 8, 7, 8, 3, 4, 4, 5, 5, 5, 6, 5, 5, 5, 5, 5, 5, 8, 7, 8, 3,
5, 3, 3, 3, 8, 8, 7, 6, 7, 7, 5, 5 , 5, 5, 5, 7, 3, 3, 3, 3, 8, 8, 7, 3, 7, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
5, 5, 5, 8, 8, 8, 8, 8, 8, 8, 4, 7, 5, 5, 3, 3, 5, 5, 5, 8, 8, 8, 8, 8, 8, 8, 4, 7, 5, 5, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3, 5, 3, 3, 3, 3, 3, 3, 4,
@ -149,7 +149,7 @@ ALIGNED(4) const u8 gFontNormalLatinGlyphWidths[] = {
3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 6, 6, 6, 6, 6, 3, 6, 6, 6, 6, 6, 6, 6, 6, 6, 3, 6, 6, 6, 6, 6,
8, 6, 6, 6, 6, 6, 6, 6, 3, 6, 6, 6, 6, 6, 6, 3, 8, 6, 6, 6, 6, 6, 6, 6, 3, 6, 6, 6, 6, 6, 6, 3,
6, 6, 6, 6, 6, 8, 6, 6, 6, 6, 6, 6, 9, 7, 6, 3, 6, 6, 6, 6, 6, 8, 6, 6, 6, 6, 6, 6, 9, 7, 6, 3,
7, 3, 3, 3, 10, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 3, 3, 3, 3, 10, 8, 3, 3, 7, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
6, 6, 4, 8, 8, 8, 7, 8, 8, 4, 6, 6, 4, 4, 3, 3, 6, 6, 4, 8, 8, 8, 7, 8, 8, 4, 6, 6, 4, 4, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 6, 3, 3, 3, 3, 3, 3, 6, 3, 3, 3, 3, 3, 3, 3, 3, 6, 3, 3, 3, 3, 3, 3, 6,
@ -433,4 +433,4 @@ ALIGNED(4) const u8 gFontShortJapaneseGlyphWidths[] = {
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,
}; };

View File

@ -1239,11 +1239,14 @@ static u16 RenderText(struct TextPrinter *textPrinter)
if (IsChineseChar(currChar, *textPrinter->printerTemplate.currentChar, subStruct->fontId, textPrinter->japanese)) if (IsChineseChar(currChar, *textPrinter->printerTemplate.currentChar, subStruct->fontId, textPrinter->japanese))
{ {
//合并字节获取汉字双字节编码 // 合并字节获取汉字双字节编码
currChar = (currChar << 8) | *textPrinter->printerTemplate.currentChar; currChar = (currChar << 8) | *textPrinter->printerTemplate.currentChar;
textPrinter->printerTemplate.currentChar++; textPrinter->printerTemplate.currentChar++;
DecompressGlyph_Chinese(currChar, subStruct->fontId); DecompressGlyph_Chinese(currChar, subStruct->fontId);
} }
else if (IsChinesePunctuation(currChar, subStruct->fontId, textPrinter->japanese))
// 中文符号目前采用单字节编码占位(非与增益版完全一致)
DecompressGlyph_Chinese(currChar, subStruct->fontId);
else else
{ {
switch (subStruct->fontId) switch (subStruct->fontId)
@ -1625,9 +1628,11 @@ s32 GetStringWidth(u8 fontId, const u8 *str, s16 letterSpacing)
default: default:
if (IsChineseChar(*str, str[1], fontId, isJapanese)) if (IsChineseChar(*str, str[1], fontId, isJapanese))
{ {
glyphWidth = GetChineseFontWidthFunc(fontId); glyphWidth = GetChineseFontWidthFunc(((*str << 8) | str[1]),fontId);
++str; ++str;
} }
else if (IsChinesePunctuation(*str, fontId, isJapanese))
glyphWidth = GetChineseFontWidthFunc(*str,fontId);
else else
glyphWidth = func(*str, isJapanese); glyphWidth = func(*str, isJapanese);
if (minGlyphWidth > 0) if (minGlyphWidth > 0)