From c64c95c72784b9bcf5884685a36a78a2658ff43f Mon Sep 17 00:00:00 2001 From: Olli Wang Date: Wed, 19 Oct 2016 13:12:21 +0800 Subject: [PATCH] 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. --- src/nanovg.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/nanovg.c b/src/nanovg.c index 51f972c..2068cf0 100644 --- a/src/nanovg.c +++ b/src/nanovg.c @@ -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.