Fixes line breaks for CJK characters.

This commit fixes weird line breaks when rendering CJK (Chinese, Japanese, Korean) characters. Each CJK character is more like a word instead of a letter. This commit fixes the logic of line breaks by introducing a new `NVG_CJK_CHAR` code point type and takes special care for formatting text including CJK characters.
This commit is contained in:
Olli Wang 2016-10-19 13:12:21 +08:00
parent 3110d5fba1
commit c64c95c727

View File

@ -2549,6 +2549,7 @@ enum NVGcodepointType {
NVG_SPACE,
NVG_NEWLINE,
NVG_CHAR,
NVG_CJK_CHAR,
};
int nvgTextBreakLines(NVGcontext* ctx, const char* string, const char* end, float breakRowWidth, NVGtextRow* rows, int maxRows)
@ -2616,7 +2617,10 @@ int nvgTextBreakLines(NVGcontext* ctx, const char* string, const char* end, floa
type = NVG_NEWLINE;
break;
default:
type = NVG_CHAR;
if (iter.codepoint >= 0x4E00 && iter.codepoint <= 0x9FFF)
type = NVG_CJK_CHAR;
else
type = NVG_CHAR;
break;
}
@ -2643,7 +2647,7 @@ int nvgTextBreakLines(NVGcontext* ctx, const char* string, const char* end, floa
} else {
if (rowStart == NULL) {
// Skip white space until the beginning of the line
if (type == NVG_CHAR) {
if (type == NVG_CHAR || type == NVG_CJK_CHAR) {
// The current char is the row so far
rowStartX = iter.x;
rowStart = iter.str;
@ -2663,26 +2667,26 @@ int nvgTextBreakLines(NVGcontext* ctx, const char* string, const char* end, floa
float nextWidth = iter.nextx - rowStartX;
// track last non-white space character
if (type == NVG_CHAR) {
if (type == NVG_CHAR || type == NVG_CJK_CHAR) {
rowEnd = iter.next;
rowWidth = iter.nextx - rowStartX;
rowMaxX = q.x1 - rowStartX;
}
// track last end of a word
if (ptype == NVG_CHAR && type == NVG_SPACE) {
if ((ptype == NVG_CHAR && type == NVG_SPACE) || type == NVG_CJK_CHAR) {
breakEnd = iter.str;
breakWidth = rowWidth;
breakMaxX = rowMaxX;
}
// track last beginning of a word
if (ptype == NVG_SPACE && type == NVG_CHAR) {
if ((ptype == NVG_SPACE && type == NVG_CHAR) || type == NVG_CJK_CHAR) {
wordStart = iter.str;
wordStartX = iter.x;
wordMinX = q.x0 - rowStartX;
}
// Break to new line when a character is beyond break width.
if (type == NVG_CHAR && nextWidth > breakRowWidth) {
if ((type == NVG_CHAR || type == NVG_CJK_CHAR) && nextWidth > breakRowWidth) {
// The run length is too long, need to break to new line.
if (breakEnd == rowStart) {
// The current word is longer than the row length, just break it from here.