From bfcda83b2cccedfc75c7d443731834d5a14a2a70 Mon Sep 17 00:00:00 2001 From: Wokann Date: Sat, 11 Oct 2025 04:00:01 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E4=B8=AD=E6=96=87=E7=AC=A6?= =?UTF-8?q?=E5=8F=B7=E7=9A=84=E7=9B=B8=E5=85=B3=E4=BB=A3=E7=A0=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- charmap.txt | 14 ++--- include/chinese_text.h | 3 +- src/chinese_text.c | 130 +++++++++++++++++++++++++++++++---------- src/fonts.c | 6 +- src/text.c | 9 ++- 5 files changed, 118 insertions(+), 44 deletions(-) diff --git a/charmap.txt b/charmap.txt index dffed7e00f..df9ba3b5a2 100644 --- a/charmap.txt +++ b/charmap.txt @@ -7891,12 +7891,12 @@ EMOJI_BIGANGER = F9 FE '咲' = 1E6F '冴' = 1E70 -':' = 3E -'?' = 3D -'!' = 3C -',' = 3B -'、' = 3A +'・' = 30 '。' = 37 -'—' = 3F '~' = 39 -'・' = 30 \ No newline at end of file +'、' = 3A +',' = 3B +'!' = 3C +'?' = 3D +':' = 3E +'—' = 3F diff --git a/include/chinese_text.h b/include/chinese_text.h index 07610d37d1..26f4a93dc2 100644 --- a/include/chinese_text.h +++ b/include/chinese_text.h @@ -2,8 +2,9 @@ #define CHINESE_TEXT_H 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); -u8 GetChineseFontWidthFunc(u8 fontId); +u8 GetChineseFontWidthFunc(u16 ChineseChar, u8 fontId); extern const u16 gFontSmallChineseGlyphs[]; //汉字小字体字模 extern const u16 gFontNormalChineseGlyphs[]; //汉字大字体字模 diff --git a/src/chinese_text.c b/src/chinese_text.c index d2685bf67b..511508c134 100644 --- a/src/chinese_text.c +++ b/src/chinese_text.c @@ -1,43 +1,83 @@ #include "global.h" #include "text.h" +#include "fonts.h" #include "chinese_text.h" -//检测是否为汉字编码 +//检测是否为双字节中文汉字编码 bool8 IsChineseChar(u16 currChar, u16 nextChar, u8 fontId, bool32 isJapanese) { - if( isJapanese != TRUE && //排除日文 - fontId != FONT_BRAILLE && //排除盲文 - currChar >= 0x01 && currChar <= 0x1E && //检查汉字编码双字节高位是否满足要求 - currChar != 0x06 && currChar != 0x1B && //检查汉字编码双字节高位是否满足要求 - nextChar <= 0xF6) //检查汉字编码双字节低位是否满足要求 + // 排除日文 + if(isJapanese) + return FALSE; + // 排除盲文 + if(fontId == FONT_BRAILLE) + return FALSE; + // 判断双字节中文汉字 + if( currChar >= 0x01 && currChar <= 0x1E && //检查汉字编码双字节高位是否满足要求 + currChar != 0x06 && currChar != 0x1B && //检查汉字编码双字节高位是否满足要求 + nextChar <= 0xF6) //检查汉字编码双字节低位是否满足要求 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检测后使用 void DecompressGlyph_Chinese(u16 ChineseChar, u8 fontId) { const u16 *glyphs; - u16 glyphId, hi, lo; - - //汉字编码转换为字模索引编号 - 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) - glyphs = gFontSmallChineseGlyphs + (0x20 * glyphId); + u16 glyphId; + // 中文符号 + if (IsChinesePunctuation(ChineseChar, fontId, 0)) + { + glyphId = ChineseChar; + //目前中文字符分别放置于原版NormalLatin、SmallLatin内 + if (fontId == FONT_SMALL || fontId == FONT_SMALL_NARROW || fontId == FONT_SMALL_NARROWER) + glyphs = gFontSmallLatinGlyphs + (0x20 * glyphId); + else + glyphs = gFontNormalLatinGlyphs + (0x20 * glyphId); + } + // 中文汉字 else - glyphs = gFontNormalChineseGlyphs + (0x20 * glyphId); - - gCurGlyph.width = GetChineseFontWidthFunc(fontId); - gCurGlyph.height = gCurGlyph.width + 3; + { + u16 hi, lo; + //汉字编码转换为字模索引编号 + 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); @@ -47,19 +87,47 @@ void DecompressGlyph_Chinese(u16 ChineseChar, u8 fontId) } //仅在通过IsChineseChar检测后使用 -u8 GetChineseFontWidthFunc(u8 fontId) +u8 GetChineseFontWidthFunc(u16 ChineseChar, u8 fontId) { + u8 width = 0; //根据字体类别返回字体宽度 switch(fontId) - { + { + //小字 case FONT_SMALL: case FONT_SMALL_NARROW: 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: - return 12; + switch(ChineseChar) + { + case 0x30: + width = 7; + break; + default: + width = 12; + break; + } } - return 0; + return width; } //汉字小字字库 diff --git a/src/fonts.c b/src/fonts.c index fc8a844c57..be183035d4 100644 --- a/src/fonts.c +++ b/src/fonts.c @@ -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, 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, - 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, 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, @@ -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, 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, - 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, 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, @@ -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, -}; +}; \ No newline at end of file diff --git a/src/text.c b/src/text.c index 92998c3f6d..e5169fb33d 100644 --- a/src/text.c +++ b/src/text.c @@ -1239,11 +1239,14 @@ static u16 RenderText(struct TextPrinter *textPrinter) if (IsChineseChar(currChar, *textPrinter->printerTemplate.currentChar, subStruct->fontId, textPrinter->japanese)) { - //合并字节获取汉字双字节编码 + // 合并字节获取汉字双字节编码 currChar = (currChar << 8) | *textPrinter->printerTemplate.currentChar; textPrinter->printerTemplate.currentChar++; DecompressGlyph_Chinese(currChar, subStruct->fontId); } + else if (IsChinesePunctuation(currChar, subStruct->fontId, textPrinter->japanese)) + // 中文符号目前采用单字节编码占位(非与增益版完全一致) + DecompressGlyph_Chinese(currChar, subStruct->fontId); else { switch (subStruct->fontId) @@ -1625,9 +1628,11 @@ s32 GetStringWidth(u8 fontId, const u8 *str, s16 letterSpacing) default: if (IsChineseChar(*str, str[1], fontId, isJapanese)) { - glyphWidth = GetChineseFontWidthFunc(fontId); + glyphWidth = GetChineseFontWidthFunc(((*str << 8) | str[1]),fontId); ++str; } + else if (IsChinesePunctuation(*str, fontId, isJapanese)) + glyphWidth = GetChineseFontWidthFunc(*str,fontId); else glyphWidth = func(*str, isJapanese); if (minGlyphWidth > 0)