r21462 by jghali - #14308: Incorrect justification of Chinese text

scribus-commit scribus-commit at lists.scribus.net
Thu Oct 13 12:13:15 UTC 2016


Author: jghali
Date: Thu Oct 13 12:13:14 2016
New Revision: 21462

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=21462
Log:
#14308: Incorrect justification of Chinese text

Modified:
    trunk/Scribus/scribus/pageitem_textframe.cpp
    trunk/Scribus/scribus/text/textshaper.cpp
    trunk/Scribus/scribus/util_text.cpp
    trunk/Scribus/scribus/util_text.h

Modified: trunk/Scribus/scribus/pageitem_textframe.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21462&path=/trunk/Scribus/scribus/pageitem_textframe.cpp
==============================================================================
--- trunk/Scribus/scribus/pageitem_textframe.cpp	(original)
+++ trunk/Scribus/scribus/pageitem_textframe.cpp	Thu Oct 13 12:13:14 2016
@@ -65,6 +65,7 @@
 #include "units.h"
 #include "util.h"
 #include "util_math.h"
+#include "util_text.h"
 
 using namespace std;
 
@@ -875,60 +876,6 @@
 	}
 }
 
-
-static bool checkCJK(QChar ch) {
-	unsigned int code = ch.unicode();
-	if (	(0x2E80 < code && code < 0x2EFF)   ||  // CJK Radicals Supplement
-		(0x3000 < code && code < 0x303F)   ||  // CJK Symbols and Punctuation
-		(0x3040 < code && code <= 0x30FF)  ||  // Hiragana, Katakana
-		(0x31C0 < code && code < 0x31EF)   ||  // CJK Strokes
-		(0x3200 < code && code < 0x32FF)   ||  // Enclosed CJK Letters and Months
-		(0x3300 < code && code < 0x33FF)   ||  // CJK Compatibility
-		(0x3400 < code && code < 0x4DBF)   ||  // CJK Unified Ideographs Extension A
-		(0x4E00 < code && code < 0x9FFF)   ||  // CJK Unified Ideographs
-		(0xF900 < code && code < 0xFAFF)   ||  // CJK Compatibility Ideographs
-		(0xFE30 < code && code < 0xFE4F)   ||  // CJK Compatibility Forms
-		(0x20000 < code && code < 0x2A6DF) ||  // CJK Unified Ideographs Extension B
-		(0x2A700 < code && code < 0x2B73F) ||  // CJK Unified Ideographs Extension C
-		(0x2B740 < code && code < 0x2B81F) ||  // CJK Unified Ideographs Extension D
-		(0x2F800 < code && code < 0x2FA1F) ||  // CJK Compatibility Ideographs Supplement
-		(0xFF01 < code && code < 0xFF0F)   ||
-		(0xFF1A < code && code < 0xFF20)   ||
-		(0xFF58 < code && code < 0xFFDC)   ||
-		(code == 0x3000) ||
-		(code == 0x3002) ||
-		(code == 0x201C) ||
-		(code == 0x201D))
-		return true;
-	else
-		return false;
-}
-
-static bool allowedCJKBreakAfter(QChar ch) {
-	unsigned int code[] = {0x201C, 0x300C, 0xFF08, 0xFF3B, 0xFF5B, 0xFF5F, 0xFF62, 0xFF0D, 0};
-	for (int i = 0; code[i]; ++i)
-		if (code[i] == ch.unicode())
-			return false;
-	return true;
-}
-
-static int allowedCJKBreakBefore(QChar ch) {
-	unsigned int code[] =
-	 {0x201D, 0x3001, 0x3002, 0x300D, 0xFF01, 0xFF09, 0xFF0C, 0xFF0E, 0xFF1A,
-	  0xFF1B, 0xFF1F, 0xFF3D, 0xFF5D, 0xFF60, 0xFF63, 0xFF64, 0};
-	for (int i = 0; code[i]; ++i)
-		if (code[i] == ch.unicode())
-			return false;
-	return true;
-}
-
-static bool implicitBreak(QChar f, QChar s) {
-	if (checkCJK(f) && checkCJK(s)) {
-		return allowedCJKBreakAfter(f) && allowedCJKBreakBefore(s);
-	} else
-		return false;
-}
-
 /// called when line length is known and line is to be justified
 static void justifyLine(const ParagraphStyle& style, LineControl& curr)
 {
@@ -1729,7 +1676,7 @@
 						case SpecialChars::CJK_KANJI:
 						case SpecialChars::CJK_KANA:
 						case SpecialChars::CJK_NOTOP:
-							lastGlyph.xadvance += charStyle.fontSize() / 10 / 4;
+							lastGlyph.xadvance += charStyle.fontSize() / 10 / 4 / lastGlyph.scaleH;
 						}
 					} else {	// next char is CJK, too
 						switch(curStat & SpecialChars::CJK_CHAR_MASK){
@@ -1740,7 +1687,7 @@
 							case SpecialChars::CJK_COMMA:
 							case SpecialChars::CJK_PERIOD:
 							case SpecialChars::CJK_MIDPOINT:
-								lastGlyph.xadvance -= charStyle.fontSize() / 10 / 2;
+								lastGlyph.xadvance -= charStyle.fontSize() / 10 / 2 / lastGlyph.scaleH;
 							}
 							break;
 						case SpecialChars::CJK_COMMA:
@@ -1748,13 +1695,13 @@
 							switch(nextStat & SpecialChars::CJK_CHAR_MASK){
 							case SpecialChars::CJK_FENCE_BEGIN:
 							case SpecialChars::CJK_FENCE_END:
-								lastGlyph.xadvance -= charStyle.fontSize() / 10 / 2;;
+								lastGlyph.xadvance -= charStyle.fontSize() / 10 / 2 / lastGlyph.scaleH;
 							}
 							break;
 						case SpecialChars::CJK_MIDPOINT:
 							switch(nextStat & SpecialChars::CJK_CHAR_MASK){
 							case SpecialChars::CJK_FENCE_BEGIN:
-								lastGlyph.xadvance -= charStyle.fontSize() / 10 / 2;
+								lastGlyph.xadvance -= charStyle.fontSize() / 10 / 2 / lastGlyph.scaleH;
 							}
 							break;
 						case SpecialChars::CJK_FENCE_BEGIN:
@@ -1765,7 +1712,7 @@
 								prevStat = SpecialChars::getCJKAttr(itemText.text(glyphRuns[i - 1].lastChar())) & SpecialChars::CJK_CHAR_MASK;
 							}
 							if (prevStat == SpecialChars::CJK_FENCE_BEGIN){
-								lastGlyph.xadvance -= charStyle.fontSize() / 10 / 2;
+								lastGlyph.xadvance -= charStyle.fontSize() / 10 / 2 / lastGlyph.scaleH;
 								lastGlyph.xoffset -= charStyle.fontSize() / 10 / 2;
 							}
 							break;
@@ -1778,7 +1725,7 @@
 						case SpecialChars::CJK_KANA:
 						case SpecialChars::CJK_NOTOP:
 							// use the size of the current char instead of the next one
-							lastGlyph.xadvance += charStyle.fontSize() / 10 / 4;
+							lastGlyph.xadvance += charStyle.fontSize() / 10 / 4 / lastGlyph.scaleH;
 						}
 					}
 				}

Modified: trunk/Scribus/scribus/text/textshaper.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21462&path=/trunk/Scribus/scribus/text/textshaper.cpp
==============================================================================
--- trunk/Scribus/scribus/text/textshaper.cpp	(original)
+++ trunk/Scribus/scribus/text/textshaper.cpp	Thu Oct 13 12:13:14 2016
@@ -14,6 +14,7 @@
 #include "styles/paragraphstyle.h"
 #include "textshaper.h"
 #include "text/specialchars.h"
+#include "util_text.h"
 
 TextShaper::TextShaper(PageItem_TextFrame* textItem, int startIndex)
 	      : m_startIndex(startIndex),
@@ -199,9 +200,15 @@
 
 	if (runIndex > 0)
 	{
-		GlyphLayout& last = m_runs[runIndex - 1].glyphs().last();
-		last.xadvance += runStyle.font().glyphKerning(last.glyph, gl.glyph, runStyle.fontSize() / 10);
+		GlyphRun& lastRun = m_runs[runIndex - 1];
+		GlyphLayout& lastLayout = lastRun.glyphs().last();
+
+		lastLayout.xadvance += runStyle.font().glyphKerning(lastLayout.glyph, gl.glyph, runStyle.fontSize() / 10);
 		m_lastKernedIndex = qMax(m_lastKernedIndex, runIndex - 1);
+
+		QChar lastChar = itemText.text(lastRun.lastChar());
+		if (implicitSpace(lastChar, ch))
+			run.setFlag(ScLayout_ImplicitSpace);
 	}
 
 	//show control characters for marks

Modified: trunk/Scribus/scribus/util_text.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21462&path=/trunk/Scribus/scribus/util_text.cpp
==============================================================================
--- trunk/Scribus/scribus/util_text.cpp	(original)
+++ trunk/Scribus/scribus/util_text.cpp	Thu Oct 13 12:13:14 2016
@@ -21,6 +21,68 @@
 #include "scribusdoc.h"
 #include "util_text.h"
 #include "serializer.h"
+
+bool checkCJK(QChar ch)
+{
+	unsigned int code = ch.unicode();
+	if (	(0x2E80 < code && code < 0x2EFF)   ||  // CJK Radicals Supplement
+		(0x3000 < code && code < 0x303F)   ||  // CJK Symbols and Punctuation
+		(0x3040 < code && code <= 0x30FF)  ||  // Hiragana, Katakana
+		(0x31C0 < code && code < 0x31EF)   ||  // CJK Strokes
+		(0x3200 < code && code < 0x32FF)   ||  // Enclosed CJK Letters and Months
+		(0x3300 < code && code < 0x33FF)   ||  // CJK Compatibility
+		(0x3400 < code && code < 0x4DBF)   ||  // CJK Unified Ideographs Extension A
+		(0x4E00 < code && code < 0x9FFF)   ||  // CJK Unified Ideographs
+		(0xF900 < code && code < 0xFAFF)   ||  // CJK Compatibility Ideographs
+		(0xFE30 < code && code < 0xFE4F)   ||  // CJK Compatibility Forms
+		(0x20000 < code && code < 0x2A6DF) ||  // CJK Unified Ideographs Extension B
+		(0x2A700 < code && code < 0x2B73F) ||  // CJK Unified Ideographs Extension C
+		(0x2B740 < code && code < 0x2B81F) ||  // CJK Unified Ideographs Extension D
+		(0x2F800 < code && code < 0x2FA1F) ||  // CJK Compatibility Ideographs Supplement
+		(0xFF01 < code && code < 0xFF0F)   ||
+		(0xFF1A < code && code < 0xFF20)   ||
+		(0xFF58 < code && code < 0xFFDC)   ||
+		(code == 0x3000) ||
+		(code == 0x3002) ||
+		(code == 0x201C) ||
+		(code == 0x201D))
+		return true;
+	else
+		return false;
+}
+
+bool allowedCJKBreakAfter(QChar ch)
+{
+	unsigned int code[] = {0x201C, 0x300C, 0xFF08, 0xFF3B, 0xFF5B, 0xFF5F, 0xFF62, 0xFF0D, 0};
+	for (int i = 0; code[i]; ++i)
+		if (code[i] == ch.unicode())
+			return false;
+	return true;
+}
+
+int allowedCJKBreakBefore(QChar ch)
+{
+	unsigned int code[] =
+	 {0x201D, 0x3001, 0x3002, 0x300D, 0xFF01, 0xFF09, 0xFF0C, 0xFF0E, 0xFF1A,
+	  0xFF1B, 0xFF1F, 0xFF3D, 0xFF5D, 0xFF60, 0xFF63, 0xFF64, 0};
+	for (int i = 0; code[i]; ++i)
+		if (code[i] == ch.unicode())
+			return false;
+	return true;
+}
+
+bool implicitSpace(QChar f, QChar s)
+{
+	return checkCJK(f) && checkCJK(s);
+}
+
+bool implicitBreak(QChar f, QChar s)
+{
+	if (checkCJK(f) && checkCJK(s)) {
+		return allowedCJKBreakAfter(f) && allowedCJKBreakBefore(s);
+	} else
+		return false;
+}
 
 int findParagraphStyle(ScribusDoc* doc, const ParagraphStyle& parStyle)
 {

Modified: trunk/Scribus/scribus/util_text.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21462&path=/trunk/Scribus/scribus/util_text.h
==============================================================================
--- trunk/Scribus/scribus/util_text.h	(original)
+++ trunk/Scribus/scribus/util_text.h	Thu Oct 13 12:13:14 2016
@@ -17,6 +17,12 @@
 
 class  ScribusDoc;
 
+bool checkCJK(QChar ch);
+bool allowedCJKBreakAfter(QChar ch);
+int  allowedCJKBreakBefore(QChar ch);
+bool implicitSpace(QChar f, QChar s);
+bool implicitBreak(QChar f, QChar s);
+
 #ifndef NLS_CONFORMANCE
 int SCRIBUS_API findParagraphStyle(ScribusDoc* doc, const ParagraphStyle& parStyle);
 int SCRIBUS_API findParagraphStyle(ScribusDoc* doc, const QString &name);




More information about the scribus-commit mailing list