r23709 by jghali - #16102: Automatic space between CJK and Latin is inserted at the end of line <ftake>

scribus-commit scribus-commit at lists.scribus.net
Wed May 6 11:40:08 UTC 2020


Author: jghali
Date: Wed May  6 11:40:08 2020
New Revision: 23709

URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=23709
Log:
#16102: Automatic space between CJK and Latin is inserted at the end of line <ftake>

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

Modified: trunk/Scribus/scribus/pageitem_textframe.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23709&path=/trunk/Scribus/scribus/pageitem_textframe.cpp
==============================================================================
--- trunk/Scribus/scribus/pageitem_textframe.cpp	(original)
+++ trunk/Scribus/scribus/pageitem_textframe.cpp	Wed May  6 11:40:08 2020
@@ -1642,6 +1642,14 @@
 			}
 
 //			glyphs->yadvance = 0;
+
+			// adjust space between CJK and Latin letter
+			if (!current.glyphs[currentIndex].hasFlag(ScLayout_StartOfLine) && current.glyphs[currentIndex].hasFlag(ScLayout_CJKLatinSpace))
+			{
+				double quaterEM = charStyle.fontSize() / 10 / 4;
+				current.glyphs[currentIndex].extraWidth += quaterEM;
+				current.glyphs[currentIndex].xoffset += quaterEM;
+			}
 
 			if (i == current.lineData.firstCluster && current.glyphs[currentIndex].hasFlag(ScLayout_CJKFence))
 			{

Modified: trunk/Scribus/scribus/sctextstruct.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23709&path=/trunk/Scribus/scribus/sctextstruct.h
==============================================================================
--- trunk/Scribus/scribus/sctextstruct.h	(original)
+++ trunk/Scribus/scribus/sctextstruct.h	Wed May  6 11:40:08 2020
@@ -56,7 +56,8 @@
 	ScLayout_CJKFence         = 1 << 19,     // marks CJK fence glyph that needs spacing adjustment at start of line
 	ScLayout_NoBreakAfter     = 1 << 20,     // marks glyphs after which a line break cannot occur
 	ScLayout_NoBreakBefore    = 1 << 21,     // marks glyphs before which a line break cannot occur
-	ScLayout_JustificationTracking = 1 << 22 // marks place of tracking in justification (e.g. for Thai)
+	ScLayout_JustificationTracking = 1 << 22, // marks place of tracking in justification (e.g. for Thai)
+	ScLayout_CJKLatinSpace    = 1 << 23      // marks place of space between CJK and latin letter
 };
 
 

Modified: trunk/Scribus/scribus/text/textshaper.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=23709&path=/trunk/Scribus/scribus/text/textshaper.cpp
==============================================================================
--- trunk/Scribus/scribus/text/textshaper.cpp	(original)
+++ trunk/Scribus/scribus/text/textshaper.cpp	Wed May  6 11:40:08 2020
@@ -456,6 +456,7 @@
 
 			int firstStat = SpecialChars::getCJKAttr(m_story.text(firstChar));
 			int currStat  = (firstChar != lastChar) ? SpecialChars::getCJKAttr(m_story.text(lastChar)) : firstStat;
+			int prevStat  = (firstChar > 0) ? SpecialChars::getCJKAttr(m_story.text(firstChar - 1)) : 0;
 
 			if (firstStat & SpecialChars::CJK_NOBREAK_BEFORE)
 				run.setFlag(ScLayout_NoBreakBefore);
@@ -465,7 +466,6 @@
 
 			if ((firstChar > 0) && (firstStat != 0) && ((firstStat & SpecialChars::CJK_NOBREAK_BEFORE) == 0))
 			{
-				int prevStat = SpecialChars::getCJKAttr(m_story.text(firstChar - 1));
 				if (prevStat != 0 && ((prevStat & SpecialChars::CJK_NOBREAK_AFTER) == 0))
 					run.setFlag(ScLayout_LineBoundary);
 			}
@@ -560,49 +560,52 @@
 			}
 
 			// Apply CJK spacing according to JIS X4051
-			if (lastChar + 1 < m_story.length())
-			{
-				double halfEM = run.style().fontSize() / 10 / 2;
-				double quarterEM = run.style().fontSize() / 10 / 4;
-
-				int nextStat = SpecialChars::getCJKAttr(m_story.text(lastChar + 1));
-
-				// 1. add 1/4 aki (space) between a CJK letter and
-				//    - a latin letter
-				//    - an ASCII Digits
-				if (currStat != 0)
-				{
-					// current char is CJK
-					if (SpecialChars::isLetterRequiringSpaceAroundCJK(m_story.text(lastChar + 1).unicode()))
+			// https://www.w3.org/TR/jlreq/
+
+			// 1. add 1/4 aki (space) between a CJK letter and
+			//    - a latin letter
+			//    - an ASCII digit
+			if (firstChar > 0)
+			{
+				if (prevStat == 0)
+				{
+					// <Latin> <<CJK>>
+					if (SpecialChars::isLetterRequiringSpaceAroundCJK(m_story.text(firstChar - 1).unicode()))
 					{
 						switch (currStat & SpecialChars::CJK_CHAR_MASK)
 						{
 							case SpecialChars::CJK_KANJI:
 							case SpecialChars::CJK_KANA:
 							case SpecialChars::CJK_NOTOP:
-								run.extraWidth += quarterEM;
+								run.setFlag(ScLayout_CJKLatinSpace);
 						}
 					}
 				}
 				else
 				{
-					// current char is not CJK
-					if (SpecialChars::isLetterRequiringSpaceAroundCJK(m_story.text(lastChar).unicode()))
+					// <CJK> <<Latin>>
+					if (SpecialChars::isLetterRequiringSpaceAroundCJK(m_story.text(firstChar).unicode()))
 					{
-						switch (nextStat & SpecialChars::CJK_CHAR_MASK)
+						switch (prevStat & SpecialChars::CJK_CHAR_MASK)
 						{
 							case SpecialChars::CJK_KANJI:
 							case SpecialChars::CJK_KANA:
 							case SpecialChars::CJK_NOTOP:
-								// use the size of the current char instead of the next one
-								run.extraWidth += quarterEM;
+								// use the size of the current Latin char
+								// instead of the previous CJK char
+								run.setFlag(ScLayout_CJKLatinSpace);
 						}
 					}
 				}
-
-				// 2. remove spaces from glyphs with the following CJK attributes
+			}
+
+			// 2. remove spaces from glyphs with the following CJK attributes
+			if (lastChar + 1 < m_story.length())
+			{
 				if (currStat != 0)
 				{	// current char is CJK
+					double halfEM = run.style().fontSize() / 10 / 2;
+					int nextStat = SpecialChars::getCJKAttr(m_story.text(lastChar + 1));
 					switch (currStat & SpecialChars::CJK_CHAR_MASK)
 					{
 						case SpecialChars::CJK_FENCE_END:
@@ -636,7 +639,6 @@
 							break;
 
 						case SpecialChars::CJK_FENCE_BEGIN:
-							int prevStat = SpecialChars::getCJKAttr(m_story.text(lastChar - 1));
 							if ((prevStat & SpecialChars::CJK_CHAR_MASK) == SpecialChars::CJK_FENCE_BEGIN)
 							{
 								run.extraWidth -= halfEM;




More information about the scribus-commit mailing list