r17253 by fschmid - Applied Patch from Bug 10547: "Japanese text line composition rule is not supported."
scribus-commit
scribus-commit at lists.scribus.net
Sat Jan 28 09:10:05 UTC 2012
Author: fschmid
Date: Sat Jan 28 09:10:04 2012
New Revision: 17253
URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=17253
Log:
Applied Patch from Bug 10547: "Japanese text line composition rule is not supported."
Modified:
branches/Version14x/Scribus/scribus/pageitem_textframe.cpp
branches/Version14x/Scribus/scribus/text/specialchars.cpp
branches/Version14x/Scribus/scribus/text/specialchars.h
Modified: branches/Version14x/Scribus/scribus/pageitem_textframe.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17253&path=/branches/Version14x/Scribus/scribus/pageitem_textframe.cpp
==============================================================================
--- branches/Version14x/Scribus/scribus/pageitem_textframe.cpp (original)
+++ branches/Version14x/Scribus/scribus/pageitem_textframe.cpp Sat Jan 28 09:10:04 2012
@@ -1137,10 +1137,12 @@
current.rightMargin = 0.0;
current.mustLineEnd = current.colRight;
current.restartX = 0;
+ int lastStat = 0, curStat = 0;
for (int a = firstInFrame(); a < itemText.length(); ++a)
{
hl = itemText.item(a);
+ curStat = SpecialChars::getCJKAttr(hl->ch);
if (a > 0 && itemText.text(a-1) == SpecialChars::PARSEP)
style = itemText.paragraphStyle(a);
if (current.itemsInLine == 0)
@@ -1323,6 +1325,81 @@
double kern= charStyle.font().glyphKerning(hl->glyph.glyph, glyph2, chs / 10.0) * hl->glyph.scaleH;
wide += kern;
hl->glyph.xadvance += kern;
+ // change xadvance, xoffset according to JIS X4051
+ ScText *hl2 = itemText.item(a+1);
+ int nextStat = SpecialChars::getCJKAttr(hl2->ch);
+ int prevStat;
+ if(curStat != 0){ // current char is CJK
+ if(nextStat == 0 && !SpecialChars::isBreakingSpace(hl2->ch)){
+ switch(curStat & SpecialChars::CJK_CHAR_MASK){
+ case SpecialChars::CJK_KANJI:
+ case SpecialChars::CJK_KANA:
+ case SpecialChars::CJK_NOTOP:
+ kern = wide / 4;
+ wide += kern;
+ hl->glyph.xadvance += kern;
+ }
+ } else { // next char is CJK, too
+ switch(curStat & SpecialChars::CJK_CHAR_MASK){
+ case SpecialChars::CJK_FENCE_END:
+ switch(nextStat & SpecialChars::CJK_CHAR_MASK){
+ case SpecialChars::CJK_FENCE_BEGIN:
+ case SpecialChars::CJK_FENCE_END:
+ case SpecialChars::CJK_COMMA:
+ case SpecialChars::CJK_PERIOD:
+ case SpecialChars::CJK_MIDPOINT:
+ kern = -wide / 2;
+ wide += kern;
+ hl->glyph.xadvance += kern;
+ }
+ break;
+ case SpecialChars::CJK_COMMA:
+ case SpecialChars::CJK_PERIOD:
+ switch(nextStat & SpecialChars::CJK_CHAR_MASK){
+ case SpecialChars::CJK_FENCE_BEGIN:
+ case SpecialChars::CJK_FENCE_END:
+ kern = -wide / 2;
+ wide += kern;
+ hl->glyph.xadvance += kern;
+ }
+ break;
+ case SpecialChars::CJK_MIDPOINT:
+ switch(nextStat & SpecialChars::CJK_CHAR_MASK){
+ case SpecialChars::CJK_FENCE_BEGIN:
+ kern = -wide / 2;
+ wide += kern;
+ hl->glyph.xadvance += kern;
+ }
+ break;
+ case SpecialChars::CJK_FENCE_BEGIN:
+ if(a == current.line.firstItem){ // first char of the line
+ prevStat = SpecialChars::CJK_FENCE_BEGIN;
+ } else {
+ hl2 = itemText.item(a-1);
+ prevStat = SpecialChars::getCJKAttr(hl2->ch) & SpecialChars::CJK_CHAR_MASK;
+ }
+ if(prevStat == SpecialChars::CJK_FENCE_BEGIN){
+ kern = -wide / 2;
+ wide += kern;
+ hl->glyph.xadvance += kern;
+ hl->glyph.xoffset += kern;
+ }
+ break;
+ }
+
+ }
+ } else { // current char is not CJK
+ if(nextStat != 0 && !SpecialChars::isBreakingSpace(hl->ch)){
+ switch(nextStat & SpecialChars::CJK_CHAR_MASK){
+ case SpecialChars::CJK_KANJI:
+ case SpecialChars::CJK_KANA:
+ case SpecialChars::CJK_NOTOP:
+ kern = hl2->glyph.wide() / 4;
+ wide += kern;
+ hl->glyph.xadvance += kern;
+ }
+ }
+ }
}
}
if (DropCmode)
@@ -1724,6 +1801,20 @@
current.rememberBreak(a, breakPos, style.rightMargin());
}
}
+ // CJK break
+ if(a > current.line.firstItem){ // not the first char
+ if( (lastStat == 0) && (curStat == 0)){ // both non-CJK
+ // do nothing
+ } else {
+ // non-CJK char does not have CJK_NOBREAK_AFTER/CJK_NOBREAK_BEFORE
+ if((lastStat & SpecialChars::CJK_NOBREAK_AFTER) == 0 &&
+ (curStat & SpecialChars::CJK_NOBREAK_BEFORE) == 0){
+ current.rememberBreak(a-1, breakPos, style.rightMargin());
+ }
+ }
+
+ }
+ lastStat = curStat;
//check against space before PARSEP
/*if (SpecialChars::isBreakingSpace(hl->ch) && (a + 1 < itemText.length()) && (itemText.item(a+1)->ch == SpecialChars::PARSEP))
{
@@ -2554,6 +2645,14 @@
&& (m_Doc->appMode == modeEdit))
{
double xcoZli = selX + hls->glyph.xoffset;
+ // ugly hack to make selection correct, as xoffset is used to
+ // remove left-half of CJK lparen , which is blank.
+ if(hls->glyph.xoffset){
+ int attr = SpecialChars::getCJKAttr(hls->ch) & SpecialChars::CJK_CHAR_MASK;
+ if( attr == SpecialChars::CJK_FENCE_BEGIN){
+ xcoZli -= hls->glyph.xoffset;
+ }
+ }
desc = - charStyleS.font().descent(charStyleS.fontSize() / 10.0);
asce = charStyleS.font().ascent(charStyleS.fontSize() / 10.0);
wide = hls->glyph.wide();
Modified: branches/Version14x/Scribus/scribus/text/specialchars.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17253&path=/branches/Version14x/Scribus/scribus/text/specialchars.cpp
==============================================================================
--- branches/Version14x/Scribus/scribus/text/specialchars.cpp (original)
+++ branches/Version14x/Scribus/scribus/text/specialchars.cpp Sat Jan 28 09:10:04 2012
@@ -59,3 +59,122 @@
|| (includeColBreak && c == COLBREAK));
}
+int SpecialChars::getCJKAttr(QChar c)
+{
+ static uchar attr_3000[0x100] = {
+ // 0x3000 - 0x3007
+ CJK_SPACE,CJK_COMMA,CJK_PERIOD,CJK_NOTOP,CJK_KANJI,CJK_NOTOP,CJK_KANJI,CJK_KANJI,
+ // 0x3008 - 0x300f
+ CJK_FENCE_BEGIN,CJK_FENCE_END,CJK_FENCE_BEGIN,CJK_FENCE_END,CJK_FENCE_BEGIN,CJK_FENCE_END,CJK_FENCE_BEGIN,CJK_FENCE_END,
+ // 0x3010 - 0x3017
+ CJK_FENCE_BEGIN,CJK_FENCE_END,CJK_KANJI,CJK_KANJI,CJK_FENCE_BEGIN,CJK_FENCE_END,CJK_FENCE_BEGIN,CJK_FENCE_END,
+ // 0x3018 - 0x301f
+ CJK_FENCE_BEGIN,CJK_FENCE_END,CJK_FENCE_BEGIN,CJK_FENCE_END,CJK_HYPHEN,CJK_FENCE_BEGIN,CJK_FENCE_END,CJK_FENCE_END,
+ // 0x3020 - 0x3027
+ CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,
+ // 0x3028 - 0x302f
+ CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,
+ // 0x3030 - 0x3037
+ CJK_BETWEEN,CJK_BETWEEN,CJK_BETWEEN,CJK_BETWEEN,CJK_BETWEEN,CJK_BETWEEN,CJK_KANJI,CJK_KANJI,
+ // 0x3038 - 0x303f
+ CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,
+ // 0x3040 - 0x3047
+ CJK_KANJI,CJK_NOTOP,CJK_KANA,CJK_NOTOP,CJK_KANA,CJK_NOTOP,CJK_KANA,CJK_NOTOP,
+ // 0x3048 - 0x304f
+ CJK_KANA,CJK_NOTOP,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,
+ // 0x3050 - 0x3057
+ CJK_KANA,CJK_NOTOP,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,
+ // 0x3058 - 0x305f
+ CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,
+ // 0x3060 - 0x3067
+ CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,
+ // 0x3068 - 0x306f
+ CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,
+ // 0x3070 - 0x3077
+ CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,
+ // 0x3078 - 0x307f
+ CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,
+ // 0x3080 - 0x3087
+ CJK_KANA,CJK_KANA,CJK_KANA,CJK_NOTOP,CJK_KANA,CJK_NOTOP,CJK_KANA,CJK_NOTOP,
+ // 0x3088 - 0x308f
+ CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_NOTOP,CJK_KANA,
+ // 0x3090 - 0x3097
+ CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_NOTOP,CJK_NOTOP,CJK_KANJI,
+ // 0x3098 - 0x309f
+ CJK_KANJI,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_NOTOP,CJK_NOTOP,CJK_KANA,
+
+ // 0x30a0 - 0x30a7
+ CJK_KANJI,CJK_NOTOP,CJK_KANA,CJK_NOTOP,CJK_KANA,CJK_NOTOP,CJK_KANA,CJK_NOTOP,
+ // 0x30a8 - 0x30af
+ CJK_KANA,CJK_NOTOP,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,
+ // 0x30b0 - 0x30b7
+ CJK_KANA,CJK_NOTOP,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,
+ // 0x30b8 - 0x30bf
+ CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,
+ // 0x30c0 - 0x30c7
+ CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,
+ // 0x30c8 - 0x30cf
+ CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,
+ // 0x30d0 - 0x30d7
+ CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,
+ // 0x30d8 - 0x30df
+ CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,
+ // 0x30e0 - 0x30e7
+ CJK_KANA,CJK_KANA,CJK_KANA,CJK_NOTOP,CJK_KANA,CJK_NOTOP,CJK_KANA,CJK_NOTOP,
+ // 0x30e8 - 0x30ef
+ CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_NOTOP,CJK_KANA,
+ // 0x30f0 - 0x30f7
+ CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_KANA,CJK_NOTOP,CJK_NOTOP,CJK_KANA,
+ // 0x30f8 - 0x30ff
+ CJK_KANA,CJK_KANA,CJK_KANA,CJK_MIDPOINT,CJK_NOTOP,CJK_NOTOP,CJK_NOTOP,CJK_KANA
+ };
+
+ static uchar attr_ff00[0x61] = {
+ // 0xff00 - 0xff07
+ CJK_SPACE,CJK_DELMITER,CJK_KANJI,CJK_PREFIX,CJK_PREFIX,CJK_KANJI,CJK_KANJI,CJK_KANJI,
+ // 0xff08 - 0xff0f
+ CJK_FENCE_BEGIN,CJK_FENCE_END,CJK_KANJI,CJK_KANJI,CJK_COMMA,CJK_BETWEEN,CJK_PERIOD,CJK_KANJI,
+ // 0xff10 - 0xff17
+ CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,
+ // 0xff18 - 0xff1f
+ CJK_KANJI,CJK_KANJI,CJK_MIDPOINT,CJK_MIDPOINT,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,
+ // 0xff20 - 0xff27
+ CJK_KANJI,CJK_KANJI,CJK_MIDPOINT,CJK_MIDPOINT,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,
+ // 0xff28 - 0xff2f
+ CJK_KANJI,CJK_KANJI,CJK_MIDPOINT,CJK_MIDPOINT,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,
+ // 0xff30 - 0xff37
+ CJK_KANJI,CJK_KANJI,CJK_MIDPOINT,CJK_MIDPOINT,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,
+ // 0xff38 - 0xff3f
+ CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_FENCE_BEGIN,CJK_KANJI,CJK_FENCE_END,CJK_KANJI,CJK_KANJI,
+ // 0xff40 - 0xff47
+ CJK_KANJI,CJK_KANJI,CJK_MIDPOINT,CJK_MIDPOINT,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,
+ // 0xff48 - 0xff4f
+ CJK_KANJI,CJK_KANJI,CJK_MIDPOINT,CJK_MIDPOINT,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,
+ // 0xff50 - 0xff57
+ CJK_KANJI,CJK_KANJI,CJK_MIDPOINT,CJK_MIDPOINT,CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_KANJI,
+ // 0xff58 - 0xff5f
+ CJK_KANJI,CJK_KANJI,CJK_KANJI,CJK_FENCE_BEGIN,CJK_KANJI,CJK_FENCE_END,CJK_BETWEEN,CJK_FENCE_BEGIN,
+ // 0xff60
+ CJK_FENCE_END
+ };
+ ushort code = c.unicode();
+ if(code >= 0x3100 && code < 0xa000){
+ return CJK_KANJI;
+ }
+
+ int attr = 0;
+ if(code >= 0x3000 && code < 0x3100){
+ attr = attr_3000[code - 0x3000];
+ } else if( code >= 0xff00 && code <= 0xff60 ){
+ attr = attr_ff00[code - 0xff00];
+ }
+ if( attr != 0 ){
+ if(attr == CJK_COMMA || attr == CJK_PERIOD || attr == CJK_NOTOP || attr == CJK_FENCE_END )
+ attr |= CJK_NOBREAK_BEFORE;
+ else if(attr == CJK_FENCE_BEGIN )
+ attr |= CJK_NOBREAK_AFTER;
+ else if(attr == CJK_MIDPOINT || attr == CJK_HYPHEN || attr == CJK_DELMITER )
+ attr |= CJK_NOBREAK_BEFORE;
+ }
+ return attr;
+}
Modified: branches/Version14x/Scribus/scribus/text/specialchars.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=17253&path=/branches/Version14x/Scribus/scribus/text/specialchars.h
==============================================================================
--- branches/Version14x/Scribus/scribus/text/specialchars.h (original)
+++ branches/Version14x/Scribus/scribus/text/specialchars.h Sat Jan 28 09:10:04 2012
@@ -52,6 +52,28 @@
static bool isBreakingSpace(QChar c);
static bool isExpandingSpace(QChar c);
+ enum {
+ CJK_FENCE_BEGIN = 0x0001,
+ CJK_FENCE_END = 0x0002,
+ CJK_NOTOP = 0x0003,
+ CJK_HYPHEN = 0x0004,
+ CJK_DELMITER = 0x0005,
+ CJK_MIDPOINT = 0x0006,
+ CJK_PERIOD = 0x0007,
+ CJK_COMMA = 0x0008,
+ CJK_BETWEEN = 0x0009,
+ CJK_PREFIX = 0x000a,
+ CJK_POSTFIX = 0x000b,
+ CJK_SPACE = 0x000c,
+ CJK_KANA = 0x000d,
+ CJK_KANJI = 0x000e,
+
+ CJK_CHAR_MASK = 0x00ff,
+
+ CJK_NOBREAK_BEFORE = 0x0100,
+ CJK_NOBREAK_AFTER = 0x0200,
+ };
+ static int getCJKAttr(QChar c);
};
#endif
More information about the scribus-commit
mailing list