View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0009436 | Scribus | Story Editor / Text Frames | public | 2010-10-25 06:19 | 2011-10-05 20:02 |
Reporter | cezaryece | Assigned To | jghali | ||
Priority | high | Severity | major | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Platform | Linux | OS | Kubuntu | OS Version | Lucid |
Product Version | 1.3.8 | ||||
Target Version | 1.4.0 | Fixed in Version | 1.4.0svn | ||
Summary | 0009436: wrong text formating - text extend margins or columns | ||||
Description | See attached file. With red frames I focus places, where text extending column width. Its not only one case I see it. Changing font doesn't matter,only places where it happens change. I can submit more exaples if you wish. I notice this issue with 1.5svn too. | ||||
Tags | text frames | ||||
Patch | |||||
related to | 0008538 | closed | jghali | Text wrap/flow around image frame fails when glyph extension and word tracking are not 100% |
related to | 0009932 | closed | jghali | First text line does not flow around objects |
related to | 0010251 | closed | jghali | [PATCH] wrong text formatting issues |
has duplicate | 0010015 | closed | jghali | Hyphenate with manual hyphen doesn't honor the distance between columns |
has duplicate | 0005891 | closed | jghali | Various settings of work tracking and glyph extension make text overlap in column gap |
related to | 0009902 | closed | cbradney | Font letters spoiled when using text flow around frame |
|
|
|
It often happens for text horizontally scaling 90% and below and with Min. Glyph Extension below 100%. |
|
|
|
|
|
|
|
I can verify that this happens with Windows 7 x64 and Windows Vista using V1.3.8. As the Glyph Extension is reduced the problem gets worse. |
|
I notice also that some right distance from frame edge make this bug appears without touching Glyph Extention. |
|
|
|
No... to fast I was upload my patch. It is not complete, please delete it. |
|
removed |
|
wrong_formating.patch (5,045 bytes)
Index: Version135/Scribus/scribus/pageitem_textframe.cpp =================================================================== --- Version135/Scribus/scribus/pageitem_textframe.cpp (wersja 16630) +++ Version135/Scribus/scribus/pageitem_textframe.cpp (kopia robocza) @@ -425,7 +425,7 @@ /// called when a possible break is passed void rememberBreak(int index, double pos) { - if (pos > colRight) + if (pos > colRight - insets.Right) { // only look for the first break behind the right edge maxShrink = 0; @@ -439,7 +439,7 @@ if (newLooseness >= oldLooseness) return; } - breakXPos = colRight; + breakXPos = colRight - insets.Right; } else { @@ -520,9 +520,10 @@ // if we aren't restricted further, we'll end at this maxX: double maxX = colRight - morespace; - if (legacy) maxX -= (lineCorr + insets.Right); + if (legacy) + maxX -= (lineCorr + insets.Right); - double StartX = floor(qMax(line.x, qMin(colRight,breakXPos) - 1)); + double StartX = floor(qMax(line.x, qMin(maxX, breakXPos))); int xPos = static_cast<int>(ceil(maxX + insets.Right)); int yDesc = static_cast<int>(yPos+line.descent); int yAsc = static_cast<int>(ceil(yPos-line.ascent)); @@ -542,7 +543,7 @@ // if the intersection only has 1 rectangle, then nothing gets in the way if (lineI.numRects() == 1) { - int xPos = qRound(ceil(StartX + 0.125 + insets.Right)); + int xPos = qRound(ceil(StartX + insets.Right)); pt12.setX(xPos); pt22.setX(xPos); if (shape.contains(pf2.map(pt12)) && shape.contains(pf2.map(pt22))) @@ -570,6 +571,7 @@ qDebug()<<EndX<<EndX2<<StartX<<maxX; qDebug()<<"DIFFERING ENDX!!!!!"; }*/ + return EndX2; } @@ -746,8 +748,6 @@ double glyphNatural = 0; double spaceNatural = 0; - double glyphExtension; - double spaceExtension; const ParagraphStyle& style(itemText.paragraphStyle(line.firstItem)); @@ -764,29 +764,37 @@ } } - // decision: prio 1: stretch glyph; prio 2: stretch spaces + double glyphExtension = 0; + double spaceExtension = 0; + + if (line.width < glyphNatural + spaceNatural) //stretch + glyphExtension = qMax(line.width / (glyphNatural + spaceNatural), style.minGlyphExtension()); + else //expand + glyphExtension = qMin(1 + (line.width / (glyphNatural + spaceNatural)), style.maxGlyphExtension()); + if (spaceNatural > 0) + spaceExtension = (line.width - glyphNatural * glyphExtension ) / spaceNatural - 1; + +// // decision: prio 1: stretch glyph; prio 2: stretch spaces +// double minGE = style.minGlyphExtension(); +// if (line.width < spaceNatural + glyphNatural * minGE && spaceNatural > 0) +// { +// glyphExtension = style.minGlyphExtension() - 1; +// spaceExtension = (line.width - glyphNatural * (1+glyphExtension) ) / spaceNatural - 1; +// } +// else if (line.width < spaceNatural + glyphNatural * style.maxGlyphExtension() && glyphNatural > 0) +// { +// spaceExtension = 0; +// glyphExtension = (line.width - spaceNatural) / glyphNatural - 1; +// } +// else +// { +// glyphExtension = style.minGlyphExtension() - 1; +// if (spaceNatural > 0) +// spaceExtension = (line.width - glyphNatural * (1+glyphExtension) ) / spaceNatural - 1; +// else +// spaceExtension = 0; +// } - if (line.width < spaceNatural + glyphNatural * style.minGlyphExtension() && spaceNatural > 0) - { - glyphExtension = style.minGlyphExtension() - 1; - spaceExtension = (line.width - glyphNatural * (1+glyphExtension) ) / spaceNatural - 1; - } - else if (line.width < spaceNatural + glyphNatural * style.maxGlyphExtension() && glyphNatural > 0) - { - spaceExtension = 0; - glyphExtension = (line.width - spaceNatural) / glyphNatural - 1; - } - else - { - glyphExtension = style.maxGlyphExtension() - 1; - if (spaceNatural > 0) - spaceExtension = (line.width - glyphNatural * (1+glyphExtension) ) / spaceNatural - 1; - else - spaceExtension = 0; - } - - double glyphScale = 1 + glyphExtension; - /* qDebug() << QString("justify: line = %7 natural = %1 + %2 = %3 (%4); spaces + %5%%; min=%8; glyphs + %6%%; min=%9") .arg(spaceNatural).arg(glyphNatural).arg(spaceNatural+glyphNatural).arg(line.naturalWidth) @@ -800,12 +808,12 @@ double wide = itemText.item(yof)->glyph.wide(); if (!SpecialChars::isExpandingSpace(itemText.text(yof))) { - itemText.item(yof)->glyph.last()->xadvance += wide * glyphExtension; + itemText.item(yof)->glyph.last()->xadvance += wide * (glyphExtension -1); GlyphLayout* glyph = &(itemText.item(yof)->glyph); while (glyph) { - glyph->xoffset *= glyphScale; - glyph->scaleH *= glyphScale; + glyph->xoffset *= glyphExtension; + glyph->scaleH *= glyphExtension; glyph = glyph->more; } } @@ -820,7 +828,8 @@ /// called when linelength is known and line is not justified static void indentLine(StoryText& itemText, LineSpec& line, double leftIndent) { - if (line.naturalWidth > line.width) + //it is hack, but works well + if (line.naturalWidth + 0.125 >= line.width) { justifyLine(itemText, line); } |
|
|
|
Seems I done that!!! Really really hope this!!! Review my patch, please, deeply. Still remains issue with overflow and margin areas... next time. |
|
wrong_formating_overflow.patch (13,196 bytes)
Index: Version135/Scribus/scribus/pageitem_textframe.cpp =================================================================== --- Version135/Scribus/scribus/pageitem_textframe.cpp (wersja 16630) +++ Version135/Scribus/scribus/pageitem_textframe.cpp (kopia robocza) @@ -126,8 +126,12 @@ return res; } -QRegion PageItem_TextFrame::availableRegion(QRegion clip) +QRegion PageItem_TextFrame::availableRegion(QRegion clip, QRegion * unavaiable) { + //hack to get empty unavaiable region + //on call unavaible = clip + if (unavaiable->xored(Clip).isEmpty()) + unavaiable->setRects(NULL,0); QRegion result(clip); if (!isEmbedded) { @@ -156,7 +160,9 @@ continue; if (docItem->textFlowAroundObject()) { - result = result.subtract(itemShape(docItem, Mp->xOffset() - Dp->xOffset(), Mp->yOffset() - Dp->yOffset())); + result = result.subtracted(itemShape(docItem, Mp->xOffset() - Dp->xOffset(), Mp->yOffset() - Dp->yOffset())); + if (unavaiable) + unavaiable->united(itemShape(docItem, Mp->xOffset() - Dp->xOffset(), Mp->yOffset() - Dp->yOffset())); } if (docItem->isGroupControl) currentGroup = docItem->Groups.top(); @@ -192,7 +198,11 @@ if ((currentGroup != -1) && (docItem->Groups.count() != 0) && (currentGroup == docItem->Groups.top())) continue; if (docItem->textFlowAroundObject()) - result = result.subtract(itemShape(docItem, 0, 0)); + { + result = result.subtracted(itemShape(docItem, 0, 0)); + if (unavaiable) + unavaiable->united(itemShape(docItem, 0, 0)); + } if (docItem->isGroupControl) currentGroup = docItem->Groups.top(); } @@ -425,7 +435,7 @@ /// called when a possible break is passed void rememberBreak(int index, double pos) { - if (pos > colRight) + if (pos > colRight - insets.Right) { // only look for the first break behind the right edge maxShrink = 0; @@ -439,7 +449,7 @@ if (newLooseness >= oldLooseness) return; } - breakXPos = colRight; + breakXPos = colRight - insets.Right; } else { @@ -520,9 +530,10 @@ // if we aren't restricted further, we'll end at this maxX: double maxX = colRight - morespace; - if (legacy) maxX -= (lineCorr + insets.Right); + if (legacy) + maxX -= (lineCorr + insets.Right); - double StartX = floor(qMax(line.x, qMin(colRight,breakXPos) - 1)); + double StartX = floor(qMax(line.x, qMin(maxX, breakXPos))); int xPos = static_cast<int>(ceil(maxX + insets.Right)); int yDesc = static_cast<int>(yPos+line.descent); int yAsc = static_cast<int>(ceil(yPos-line.ascent)); @@ -542,7 +553,7 @@ // if the intersection only has 1 rectangle, then nothing gets in the way if (lineI.numRects() == 1) { - int xPos = qRound(ceil(StartX + 0.125 + insets.Right)); + int xPos = qRound(ceil(StartX + insets.Right)); pt12.setX(xPos); pt22.setX(xPos); if (shape.contains(pf2.map(pt12)) && shape.contains(pf2.map(pt22))) @@ -570,6 +581,7 @@ qDebug()<<EndX<<EndX2<<StartX<<maxX; qDebug()<<"DIFFERING ENDX!!!!!"; }*/ + return EndX2; } @@ -734,8 +746,9 @@ private: double frameWidth; double frameHeight; + double lineCorr; +public: MarginStruct insets; - double lineCorr; }; @@ -746,8 +759,6 @@ double glyphNatural = 0; double spaceNatural = 0; - double glyphExtension; - double spaceExtension; const ParagraphStyle& style(itemText.paragraphStyle(line.firstItem)); @@ -764,29 +775,37 @@ } } - // decision: prio 1: stretch glyph; prio 2: stretch spaces + double glyphExtension = 0; + double spaceExtension = 0; + + if (line.width < glyphNatural + spaceNatural) //stretch + glyphExtension = qMax(line.width / (glyphNatural + spaceNatural), style.minGlyphExtension()); + else //expand + glyphExtension = qMin(1 + (line.width / (glyphNatural + spaceNatural)), style.maxGlyphExtension()); + if (spaceNatural > 0) + spaceExtension = (line.width - glyphNatural * glyphExtension ) / spaceNatural - 1; + +// // decision: prio 1: stretch glyph; prio 2: stretch spaces +// double minGE = style.minGlyphExtension(); +// if (line.width < spaceNatural + glyphNatural * minGE && spaceNatural > 0) +// { +// glyphExtension = style.minGlyphExtension() - 1; +// spaceExtension = (line.width - glyphNatural * (1+glyphExtension) ) / spaceNatural - 1; +// } +// else if (line.width < spaceNatural + glyphNatural * style.maxGlyphExtension() && glyphNatural > 0) +// { +// spaceExtension = 0; +// glyphExtension = (line.width - spaceNatural) / glyphNatural - 1; +// } +// else +// { +// glyphExtension = style.minGlyphExtension() - 1; +// if (spaceNatural > 0) +// spaceExtension = (line.width - glyphNatural * (1+glyphExtension) ) / spaceNatural - 1; +// else +// spaceExtension = 0; +// } - if (line.width < spaceNatural + glyphNatural * style.minGlyphExtension() && spaceNatural > 0) - { - glyphExtension = style.minGlyphExtension() - 1; - spaceExtension = (line.width - glyphNatural * (1+glyphExtension) ) / spaceNatural - 1; - } - else if (line.width < spaceNatural + glyphNatural * style.maxGlyphExtension() && glyphNatural > 0) - { - spaceExtension = 0; - glyphExtension = (line.width - spaceNatural) / glyphNatural - 1; - } - else - { - glyphExtension = style.maxGlyphExtension() - 1; - if (spaceNatural > 0) - spaceExtension = (line.width - glyphNatural * (1+glyphExtension) ) / spaceNatural - 1; - else - spaceExtension = 0; - } - - double glyphScale = 1 + glyphExtension; - /* qDebug() << QString("justify: line = %7 natural = %1 + %2 = %3 (%4); spaces + %5%%; min=%8; glyphs + %6%%; min=%9") .arg(spaceNatural).arg(glyphNatural).arg(spaceNatural+glyphNatural).arg(line.naturalWidth) @@ -800,12 +819,12 @@ double wide = itemText.item(yof)->glyph.wide(); if (!SpecialChars::isExpandingSpace(itemText.text(yof))) { - itemText.item(yof)->glyph.last()->xadvance += wide * glyphExtension; + itemText.item(yof)->glyph.last()->xadvance += wide * (glyphExtension -1); GlyphLayout* glyph = &(itemText.item(yof)->glyph); while (glyph) { - glyph->xoffset *= glyphScale; - glyph->scaleH *= glyphScale; + glyph->xoffset *= glyphExtension; + glyph->scaleH *= glyphExtension; glyph = glyph->more; } } @@ -820,7 +839,8 @@ /// called when linelength is known and line is not justified static void indentLine(StoryText& itemText, LineSpec& line, double leftIndent) { - if (line.naturalWidth > line.width) + //it is hack, but works well + if (line.naturalWidth + 0.125 >= line.width) { justifyLine(itemText, line); } @@ -916,9 +936,22 @@ } +void PageItem_TextFrame::checkInsets(QRegion * c, QPoint p, LineControl * current, MarginStruct * extra) +{ + //if point is in unavailable region + //right and left text distances should not working + if ( !c->isEmpty() && c->contains(p)) + { + extra->Left = current->insets.Left = 0; + extra->Right = current->insets.Left = -1; //should be 0, but these value works better + } + else + { + extra->Left = current->insets.Left = Extra; + extra->Right = current->insets.Right = RExtra; + } +} - - void PageItem_TextFrame::layout() { // qDebug()<<"==Layout==" << itemName() ; @@ -1015,14 +1048,16 @@ setShadow(); if ((itemText.length() != 0)) // || (NextBox != 0)) { - // determine layout area - QRegion cl = availableRegion(QRegion(pf2.map(Clip))); + // determine layout area and unavaiable area + //hack to set pointer to clNA (cl Not Avaiable) region + //without it clNA was unset + QRegion clNA = QRegion(pf2.map(Clip)); + QRegion cl = availableRegion(QRegion(pf2.map(Clip)), &clNA); if (cl.isEmpty()) { MaxChars = firstInFrame(); goto NoRoom; } - if (imageFlippedH()) { pf2.translate(Width, 0); @@ -1075,6 +1110,7 @@ MaxChars = 0; for (int a = firstInFrame(); a < itemText.length(); ++a) { + checkInsets(&clNA, pf2.map(QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos))), ¤t, &extra); hl = itemText.item(a); if (a > 0 && itemText.text(a-1) == SpecialChars::PARSEP) style = itemText.paragraphStyle(a); @@ -1422,10 +1458,14 @@ // qDebug() << QString("linestart: %1 + %2 + %3 < %4").arg(current.xPos).arg(wide).arg(style.rightMargin()).arg(current.colRight); double leftIndent = 0; double xStep = legacy? 1 : 0.125; - while (!cl.contains(pf2.map(pt1)) || !cl.contains(pf2.map(pt2)) || current.isEndOfLine(wide + leftIndent + style.rightMargin())) + while (!cl.contains(pf2.map(pt1)) || !cl.contains(pf2.map(pt2))) { + checkInsets(&clNA, pf2.map(QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos))), ¤t, &extra); + if (!current.isEndOfLine(wide + leftIndent + style.rightMargin())) + break; fBorder = true; current.xPos += xStep; + checkInsets(&clNA, pf2.map(QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos))), ¤t, &extra); if (current.isEndOfLine(wide + leftIndent + style.rightMargin())) { // qDebug() << QString("eocol %5? %1 + %2 + %3 + %4").arg(current.yPos).arg(current.startOfCol).arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(style.lineSpacing()).arg(current.column); @@ -1650,6 +1690,7 @@ } // test if end of line reached + checkInsets(&clNA, pf2.map(QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos))), ¤t, &extra); if ((!cl.contains(pf2.map(pt1))) || (!cl.contains(pf2.map(pt2))) || (legacy && current.isEndOfLine(style.rightMargin()))) outs = true; if (current.isEndOfCol()) @@ -1776,6 +1817,7 @@ { // find end of line current.breakLine(itemText, style, firstLineOffset(), a); + checkInsets(&clNA, pf2.map(QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos))), ¤t, &extra); EndX = current.endOfLine(cl, pf2, style.rightMargin()); current.finishLine(EndX); @@ -1845,6 +1887,7 @@ current.updateHeightMetrics(itemText); current.updateLineOffset(itemText, style, firstLineOffset()); + checkInsets(&clNA, pf2.map(QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos))), ¤t, &extra); EndX = current.endOfLine(cl, pf2, style.rightMargin()); current.finishLine(EndX); @@ -1928,6 +1971,7 @@ // qDebug() << QString("style nb @%6: %1 -- %2, %4/%5 char: %3").arg(style.leftMargin()).arg(style.rightMargin()) // .arg(style.charStyle().asString()).arg(style.name()).arg(style.parent()) // .arg(a); + checkInsets(&clNA, pf2.map(QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos))), ¤t, &extra); EndX = current.endOfLine(cl, pf2, style.rightMargin()); current.finishLine(EndX); // qDebug() << QString("no break pos: %1-%2 @ %3 wid %4 nat %5 endX %6") @@ -1938,6 +1982,7 @@ } if ( outs || SpecialChars::isBreak(hl->ch, (Cols > 1)) ) { + checkInsets(&clNA, pf2.map(QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos))), ¤t, &extra); if (outs && !current.isEndOfLine(hl->glyph.wide() + style.rightMargin())) { if (( hl->ch == SpecialChars::PARSEP || hl->ch == SpecialChars::LINEBREAK) @@ -1950,8 +1995,10 @@ } bool fromOut = true; double BotOffset = desc+extra.Bottom+lineCorr; + checkInsets(&clNA, pf2.map(QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos))), ¤t, &extra); while (!current.isEndOfLine(style.rightMargin())) { + checkInsets(&clNA, pf2.map(QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos))), ¤t, &extra); current.xPos++; if (current.isEndOfLine(style.rightMargin())) { @@ -2132,6 +2179,7 @@ int a = itemText.length()-1; hl = a >=0 ? itemText.item(a) : NULL; current.breakLine(itemText, style, firstLineOffset(), a); + checkInsets(&clNA, pf2.map(QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos))), ¤t, &extra); EndX = current.endOfLine(cl, pf2, style.rightMargin()); current.finishLine(EndX); Index: Version135/Scribus/scribus/pageitem_textframe.h =================================================================== --- Version135/Scribus/scribus/pageitem_textframe.h (wersja 16630) +++ Version135/Scribus/scribus/pageitem_textframe.h (kopia robocza) @@ -32,6 +32,8 @@ class ScPainter; class ScribusDoc; +struct MarginStruct; +struct LineControl; #include "text/nlsconfig.h" @@ -85,7 +87,7 @@ void drawOverflowMarker(ScPainter *p); void drawUnderflowMarker(ScPainter *p); void drawColumnBorders(ScPainter *p); - QRegion availableRegion(QRegion clip); + QRegion availableRegion(QRegion clip, QRegion * unavaiable); #ifdef NLS_PROTO void DrawLineItem(ScPainter *p, double width, @@ -103,7 +105,7 @@ private: bool cursorBiasBackward; - + void checkInsets(QRegion * c, QPoint p, LineControl * current, MarginStruct * extra); void setShadow(); void restoreTextSelection(int selStart, int selLength); QString currentShadow; |
|
wrong_formating_overflow.patch solves also https://bugs.scribus.net/view.php?id=9779 [ 9779: Compounding column margin /w image contour ] It is maybe not perfect, sometimes one char still can jump out of available area, but Scribus works with that patch meaningful better. |
|
Setting 1.4.0 target now we have a patch. avox, please review. thanks |
|
Thanks Cezaryece! |
|
Not good... after patch formatting lines with DropCap is broken when some other frame with text overflowing is placed at top on whole column width and DropCap is in first line below it. Work in progress... |
|
My first patch fixing issue with text extending available area is working well (issue almost fixed) and is ready for commit. Second patch for with try of solving issue with adding text margins to overflow area is not working... |
|
Add also 0005891 as duplicate of... |
|
|
|
Seems I am at the end of that difficult road... Proof in attached solved2.jpd, which you can compare with also attached Document-1.sla Don`t upload patch yet because I must to do some cleaning of code. Stay in touch... |
|
|
|
wrong_formating_overflow_v2.patch (10,573 bytes)
Index: Version135/Scribus/scribus/pageitem_textframe.cpp =================================================================== --- Version135/Scribus/scribus/pageitem_textframe.cpp (wersja 16641) +++ Version135/Scribus/scribus/pageitem_textframe.cpp (kopia robocza) @@ -155,9 +155,7 @@ if ((currentGroup != -1) && (docItem->Groups.count() != 0) && (currentGroup == docItem->Groups.top())) continue; if (docItem->textFlowAroundObject()) - { - result = result.subtract(itemShape(docItem, Mp->xOffset() - Dp->xOffset(), Mp->yOffset() - Dp->yOffset())); - } + result = result.subtracted(itemShape(docItem, Mp->xOffset() - Dp->xOffset(), Mp->yOffset() - Dp->yOffset())); if (docItem->isGroupControl) currentGroup = docItem->Groups.top(); } @@ -192,7 +190,7 @@ if ((currentGroup != -1) && (docItem->Groups.count() != 0) && (currentGroup == docItem->Groups.top())) continue; if (docItem->textFlowAroundObject()) - result = result.subtract(itemShape(docItem, 0, 0)); + result = result.subtracted(itemShape(docItem, 0, 0)); if (docItem->isGroupControl) currentGroup = docItem->Groups.top(); } @@ -522,7 +520,7 @@ double maxX = colRight - morespace; if (legacy) maxX -= (lineCorr + insets.Right); - double StartX = floor(qMax(line.x, qMin(colRight,breakXPos) - 1)); + double StartX = floor(qMax(line.x, qMin(maxX,breakXPos-maxShrink))-1); int xPos = static_cast<int>(ceil(maxX + insets.Right)); int yDesc = static_cast<int>(yPos+line.descent); int yAsc = static_cast<int>(ceil(yPos-line.ascent)); @@ -560,7 +558,7 @@ double Interval = 0.125; do { EndX2 += Interval; - int xPos = qRound(ceil(EndX2 + insets.Right)); + int xPos = qRound(ceil(EndX2)); pt12.setX (xPos); pt22.setX (xPos); } while ((EndX2 < maxX) && shape.contains(pf2.map(pt12)) && shape.contains(pf2.map(pt22))); @@ -1420,6 +1418,17 @@ // find linelength: pt1 = QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos+BotOffset)); pt2 = QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(ceil(current.yPos-TopOffset))); + while (current.xPos < current.colRight) + { + if (!cl.contains(pf2.map(pt1)) || !cl.contains(pf2.map(pt2))) + { + current.xPos += 0.125; + pt1.setX(static_cast<int>(ceil(current.xPos))); + pt2.setX(static_cast<int>(ceil(current.xPos))); + } + else break; + } + // find linelength: // increase pt1/pt2 until i-beam reaches end of line // qDebug() << QString("linestart: %1 + %2 + %3 < %4").arg(current.xPos).arg(wide).arg(style.rightMargin()).arg(current.colRight); double leftIndent = 0; @@ -1631,24 +1640,24 @@ { if (hl->effects() & ScStyle_HyphenationPossible || hl->ch == SpecialChars::SHYPHEN) { - pt1 = QPoint(qRound(ceil(current.xPos+extra.Right - current.maxShrink + charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0))), qRound(current.yPos+desc)); - pt2 = QPoint(qRound(ceil(current.xPos+extra.Right - current.maxShrink + charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0))), qRound(ceil(current.yPos-asce))); + pt1 = QPoint(qRound(ceil(current.xPos - current.maxShrink + charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0))), qRound(current.yPos+desc)); + pt2 = QPoint(qRound(ceil(current.xPos - current.maxShrink + charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0))), qRound(ceil(current.yPos-asce))); } else { - pt1 = QPoint(qRound(ceil(current.xPos+extra.Right - current.maxShrink )), qRound(current.yPos+desc)); - pt2 = QPoint(qRound(ceil(current.xPos+extra.Right - current.maxShrink )), qRound(ceil(current.yPos-asce))); + pt1 = QPoint(qRound(ceil(current.xPos - current.maxShrink )), qRound(current.yPos+desc)); + pt2 = QPoint(qRound(ceil(current.xPos - current.maxShrink )), qRound(ceil(current.yPos-asce))); } } else if (!legacy && SpecialChars::isBreakingSpace(hl->ch)) { - pt1 = QPoint(qRound(ceil(breakPos + extra.Right - current.maxShrink )), qRound(current.yPos+desc)); - pt2 = QPoint(qRound(ceil(breakPos + extra.Right - current.maxShrink )), qRound(ceil(current.yPos-asce))); + pt1 = QPoint(qRound(ceil(breakPos - current.maxShrink )), qRound(current.yPos+desc)); + pt2 = QPoint(qRound(ceil(breakPos - current.maxShrink )), qRound(ceil(current.yPos-asce))); } else { - pt1 = QPoint(qRound(ceil(current.xPos+extra.Right - current.maxShrink)), qRound(current.yPos+desc)); - pt2 = QPoint(qRound(ceil(current.xPos+extra.Right - current.maxShrink)), qRound(ceil(current.yPos-asce))); + pt1 = QPoint(qRound(ceil(current.xPos - current.maxShrink)), qRound(current.yPos+desc)); + pt2 = QPoint(qRound(ceil(current.xPos - current.maxShrink)), qRound(ceil(current.yPos-asce))); } // test if end of line reached @@ -1728,7 +1737,6 @@ // qDebug() << QString("dropcapoffset: %1 -> %2").arg(current.xPos-style.dropCapOffset()).arg(current.xPos); current.xPos = qMax(current.xPos, current.colLeft); maxDX = current.xPos; - QPolygon tcli(4); if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing) { current.yPos -= m_Doc->typographicSettings.valueBaseGrid * (DropLines-1); @@ -1739,9 +1747,6 @@ int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid); // qDebug() << QString("baseline adjust after dropcaps: y=%1->%2").arg(current.yPos).arg(ceil( ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by); current.yPos = ceil( ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by; - //FIXME: use current.colLeft instead of xOffset? - tcli.setPoint(0, QPoint(qRound(hl->glyph.xoffset), qRound(maxDY-DropLines*m_Doc->typographicSettings.valueBaseGrid))); - tcli.setPoint(1, QPoint(qRound(maxDX), qRound(maxDY-DropLines*m_Doc->typographicSettings.valueBaseGrid))); } else { @@ -1749,25 +1754,14 @@ { current.yPos -= style.lineSpacing() * (DropLines-1); // qDebug() << QString("after dropcaps: y=%1").arg(current.yPos); - tcli.setPoint(0, QPoint(qRound(hl->glyph.xoffset), qRound(maxDY - DropLines * style.lineSpacing()))); - tcli.setPoint(1, QPoint(qRound(maxDX), qRound(maxDY-DropLines*style.lineSpacing()))); } else { double currasce = charStyle.font().height(style.charStyle().fontSize() / 10.0); current.yPos -= currasce * (DropLines-1); // qDebug() << QString("after dropcaps: y=%1").arg(current.yPos); - tcli.setPoint(0, QPoint(qRound(hl->glyph.xoffset), qRound(maxDY-DropLines*currasce))); - tcli.setPoint(1, QPoint(qRound(maxDX), qRound(maxDY-DropLines*currasce))); } } - tcli.setPoint(2, QPoint(qRound(maxDX), qRound(maxDY))); - tcli.setPoint(3, QPoint(qRound(hl->glyph.xoffset), qRound(maxDY))); - // #6821 : the following two lines are causing bad text flow around drop caps - // in some case, discarding them put more emphasis on user control of line spacing - /*cm = QRegion(pf2.map(tcli)); - cl = cl.subtract(cm);*/ -// current.yPos = maxDY; } // end of line if ( SpecialChars::isBreak(hl->ch, Cols > 1) || (outs)) @@ -1909,8 +1903,16 @@ } else { - --a; - --current.itemsInLine; + if (current.line.firstItem == 0) + { + a = -1; + current.itemsInLine = 0; + } + else + { + --a; + --current.itemsInLine; + } } } if (a >= 0) @@ -1925,17 +1927,6 @@ else if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing) style.setLineSpacing(m_Doc->typographicSettings.valueBaseGrid); } - current.breakLine(itemText, style, firstLineOffset(), a); -// qDebug() << QString("style no break pos %1: %2 (%3)").arg(a).arg(style.alignment()).arg(style.parent()); -// qDebug() << QString("style nb @%6: %1 -- %2, %4/%5 char: %3").arg(style.leftMargin()).arg(style.rightMargin()) -// .arg(style.charStyle().asString()).arg(style.name()).arg(style.parent()) -// .arg(a); - EndX = current.endOfLine(cl, pf2, style.rightMargin()); - current.finishLine(EndX); -// qDebug() << QString("no break pos: %1-%2 @ %3 wid %4 nat %5 endX %6") -// .arg(current.line.firstItem).arg(current.line.firstItem) -// .arg(current.line.x).arg(current.line.width).arg(current.line.naturalWidth).arg(EndX); - indentLine(itemText, current.line, 0); } } if ( outs || SpecialChars::isBreak(hl->ch, (Cols > 1)) ) @@ -1946,8 +1937,6 @@ && current.hasDropCap) { current.hasDropCap = false; - if (current.yPos < maxDY) - current.yPos = maxDY; // qDebug() << QString("after dropcaps: y=%1 maxDY=%2").arg(current.yPos).arg(maxDY); } bool fromOut = true; @@ -1981,7 +1970,10 @@ current.xPos = current.colLeft; } else - current.xPos = maxDX; + if (current.itemsInLine > 0) + current.xPos = maxDX; + else + current.xPos = current.colLeft; } else current.xPos = current.colLeft; @@ -2080,7 +2072,7 @@ // calc. needed vertical space // Let’s try to change into "calc. _wanted_ vertical space" - pm - if (current.itemsInLine != 0) + if (current.itemsInLine > 0) { if ( itemText.charStyle(current.line.firstItem).effects() & ScStyle_DropCap) { @@ -2090,12 +2082,12 @@ } } - fillInTabLeaders(itemText, current.line); - + if (current.itemsInLine > 0) + fillInTabLeaders(itemText, current.line); current.startOfCol = false; // qDebug() << QString("layout: line %1 - %2 @ (%3,%4) wd %5/%6").arg(current.line.firstItem).arg(current.line.lastItem) // .arg(current.line.x).arg(current.line.y).arg(current.line.naturalWidth).arg(current.line.width); - if (current.line.firstItem > current.line.lastItem) + if (current.line.firstItem >= current.line.lastItem) ; //qDebug() << QString("layout: empty line %1 - %2").arg(current.line.firstItem).arg(current.line.lastItem); else if (current.itemsInLine > 0) itemText.appendLine(current.line); |
|
Patch is here. I test it, but you must also check it with your files before commit. It is solving problems with text extending available area (margins, columns gaps) and unwanted add frame text distances to overflow area. Crossing fingers about it will work good... |
|
I have found new small issue, so wait for new version. BTW even now this patch solves 0009932: First text line does not flow around objects |
|
Small issue was a big elephant... But now I can introduce you new patch fixing all biggest formatting issues: - text extending margins - unwanted adds of text indents and margins to overflow areas - parts of glyphs in overflow areas (when edge is not 0 angle to text) and few smaller formatting issues I have found during preparing that solution. BTW I have found that formatting using integer coordinates of glyphs and page items positions can gives us low quality of it (for example 0009902 may be that kind of bug - to low precision) I know - changing whole computing to floating precision can be deadly solution for machines with low computing power, but maybe it could be set in preferences and user will decide what is his goal - comfortable speed or best quality. |
|
formatting.patch (23,582 bytes)
Index: Version135/Scribus/scribus/pageitem_textframe.cpp =================================================================== --- Version135/Scribus/scribus/pageitem_textframe.cpp (wersja 16641) +++ Version135/Scribus/scribus/pageitem_textframe.cpp (kopia robocza) @@ -155,9 +155,7 @@ if ((currentGroup != -1) && (docItem->Groups.count() != 0) && (currentGroup == docItem->Groups.top())) continue; if (docItem->textFlowAroundObject()) - { - result = result.subtract(itemShape(docItem, Mp->xOffset() - Dp->xOffset(), Mp->yOffset() - Dp->yOffset())); - } + result = result.subtracted(itemShape(docItem, Mp->xOffset() - Dp->xOffset(), Mp->yOffset() - Dp->yOffset())); if (docItem->isGroupControl) currentGroup = docItem->Groups.top(); } @@ -192,7 +190,7 @@ if ((currentGroup != -1) && (docItem->Groups.count() != 0) && (currentGroup == docItem->Groups.top())) continue; if (docItem->textFlowAroundObject()) - result = result.subtract(itemShape(docItem, 0, 0)); + result = result.subtracted(itemShape(docItem, 0, 0)); if (docItem->isGroupControl) currentGroup = docItem->Groups.top(); } @@ -398,7 +396,8 @@ line.x = xPos; line.y = yPos; line.firstItem = first; - line.ascent = 10; + line.lastItem = 0; + line.ascent = 0; line.descent = 0; line.width = 0; line.naturalWidth = 0; @@ -407,6 +406,7 @@ breakXPos = 0; maxShrink = 0; maxStretch = 0; + width = 0; } @@ -522,7 +522,7 @@ double maxX = colRight - morespace; if (legacy) maxX -= (lineCorr + insets.Right); - double StartX = floor(qMax(line.x, qMin(colRight,breakXPos) - 1)); + double StartX = floor(qMax(line.x, qMin(maxX,breakXPos-maxShrink-1))-1); int xPos = static_cast<int>(ceil(maxX + insets.Right)); int yDesc = static_cast<int>(yPos+line.descent); int yAsc = static_cast<int>(ceil(yPos-line.ascent)); @@ -542,7 +542,7 @@ // if the intersection only has 1 rectangle, then nothing gets in the way if (lineI.numRects() == 1) { - int xPos = qRound(ceil(StartX + 0.125 + insets.Right)); + int xPos = static_cast<int>(ceil(StartX + 0.125 + insets.Right)); pt12.setX(xPos); pt22.setX(xPos); if (shape.contains(pf2.map(pt12)) && shape.contains(pf2.map(pt22))) @@ -560,7 +560,7 @@ double Interval = 0.125; do { EndX2 += Interval; - int xPos = qRound(ceil(EndX2 + insets.Right)); + int xPos = static_cast<int>(ceil(EndX2)); pt12.setX (xPos); pt22.setX (xPos); } while ((EndX2 < maxX) && shape.contains(pf2.map(pt12)) && shape.contains(pf2.map(pt22))); @@ -704,7 +704,7 @@ double currasce (this->getLineAscent(itemText)); if( offsetPolicy == FLOPRealGlyphHeight ) { - adj = firstasce - currasce; + adj = firstasce - currasce -1; } else if( offsetPolicy == FLOPFontAscent ) { @@ -952,9 +952,10 @@ // ScribusView* view = m_Doc->view(); QMatrix pf2; QPoint pt1, pt2; + QRect pt; /*QRegion cm;*/ double chs, chsd = 0; - double oldCurY, EndX, OFs, wide, kernVal; + double oldCurY, EndX, OFs, wide=0, kernVal; QString chstr; ScText *hl; ParagraphStyle style; @@ -975,7 +976,8 @@ tTabValues.clear(); bool DropCmode = false; - double desc=0, asce=0, maxDY=0, desc2=0, maxDX=0; + double desc=0, asce=0, desc2=0, realAsce=0, realDesc = 0; + double maxDY=0, maxDX=0; double DropCapDrop = 0; int DropLines = 0; int DropLinesCount = 0; @@ -998,6 +1000,10 @@ current.init(Width, Height, extra, lineCorr); current.initColumns(columnWidth(), ColGap); current.hyphenCount = 0; + + //hold Y position of last line of text (with glyphs descent) + //for moving next line if glyphs are higher than that + double lastLineY; // dump styles /* @@ -1037,6 +1043,7 @@ } current.nextColumn(0); + lastLineY = 0; // find start of first line if (firstInFrame() < itemText.length()) @@ -1075,6 +1082,7 @@ outs = false; OFs = 0; MaxChars = 0; + double xStep = legacy? 1 : 0.125; for (int a = firstInFrame(); a < itemText.length(); ++a) { hl = itemText.item(a); @@ -1326,14 +1334,16 @@ double hlcsize10=charStyle.fontSize() / 10.0; if ((hl->ch == SpecialChars::OBJECT) && (hl->embedded.hasItem())) { - desc = desc2 = 0; + desc = desc2 = realDesc = 0; } else { desc = desc2 = -charStyle.font().descent(hlcsize10); + realDesc = charStyle.font().realCharDescent(chstr[0], hlcsize10); current.rememberShrinkStretch(hl->ch, wide, style); } asce = charStyle.font().ascent(hlcsize10); + realAsce = charStyle.font().realCharAscent(chstr[0], hlcsize10); // wide = wide * hl->glyph.scaleH; } fBorder = false; @@ -1346,6 +1356,7 @@ { // start next col current.nextColumn(asce); + lastLineY = 0; if (((a > firstInFrame()) && (itemText.text(a-1) == SpecialChars::PARSEP)) || ((a == firstInFrame()) && (BackBox == 0))) { @@ -1394,7 +1405,7 @@ if (current.startOfCol) { // qDebug() << QString("current.startOfCol: %1 + %2 + %3 + 1 =%4").arg(asce).arg(extra.Top).arg(lineCorr).arg(asce + extra.Top + lineCorr + 1); - current.yPos = asce + extra.Top + lineCorr + 1; + current.yPos = realAsce + extra.Top + lineCorr + 1; // if (((a > 0) && (itemText.at(a-1)->ch == QChar(13))) || ((a == 0) && (BackBox == 0))) // current.yPos += m_Doc->docParagraphStyles[hl->cab].gapBefore; } @@ -1417,28 +1428,42 @@ current.yPos = TopOffset+1; } */ + //find line start + double leftIndent = 0; + if (!current.hasDropCap) + leftIndent = style.leftMargin(); + if (a==0 || (a > 0 && (itemText.text(a-1) == SpecialChars::PARSEP))) + leftIndent += style.firstIndent(); + current.xPos = qMax(leftIndent + current.colLeft, current.xPos); + // find linelength: - pt1 = QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos+BotOffset)); - pt2 = QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(ceil(current.yPos-TopOffset))); + pt = QRect( QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos+BotOffset)), + QPoint(static_cast<int>(ceil(current.xPos + (1 - style.minGlyphExtension()) * wide)), static_cast<int>(current.yPos-TopOffset))); // increase pt1/pt2 until i-beam reaches end of line // qDebug() << QString("linestart: %1 + %2 + %3 < %4").arg(current.xPos).arg(wide).arg(style.rightMargin()).arg(current.colRight); - double leftIndent = 0; - double xStep = legacy? 1 : 0.125; - while (!cl.contains(pf2.map(pt1)) || !cl.contains(pf2.map(pt2)) || current.isEndOfLine(wide + leftIndent + style.rightMargin())) + while (!QRegion(pf2.mapToPolygon(pt)).subtracted(cl).isEmpty() || current.isEndOfLine((1 - style.minGlyphExtension()) * wide + style.rightMargin())) { fBorder = true; current.xPos += xStep; - if (current.isEndOfLine(wide + leftIndent + style.rightMargin())) + if (current.isEndOfLine((1 - style.minGlyphExtension()) * wide + style.rightMargin())) { // qDebug() << QString("eocol %5? %1 + %2 + %3 + %4").arg(current.yPos).arg(current.startOfCol).arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(style.lineSpacing()).arg(current.column); // new line fBorder = false; - current.xPos = current.colLeft; - - leftIndent = style.leftMargin(); - if (a > 0 && itemText.text(a-1) == SpecialChars::PARSEP) - leftIndent += style.firstIndent(); - + if (current.hasDropCap) + { + DropLinesCount++; + if (DropLinesCount >= DropLines) + { + current.hasDropCap = false; + current.xPos = current.colLeft; + maxDX = 0; + } + } + if (current.hasDropCap) + current.xPos = maxDX; + else + current.xPos = current.colLeft - extra.Left + leftIndent; if (current.startOfCol) current.yPos++; else @@ -1461,6 +1486,7 @@ if (current.column < Cols) { current.nextColumn(asce); + lastLineY = 0; if (((a > firstInFrame()) && (itemText.text(a-1) == SpecialChars::PARSEP)) || ((a == firstInFrame()) && (BackBox == 0))) { if (chstr[0] != SpecialChars::PARSEP) @@ -1497,26 +1523,25 @@ } } } - pt1 = QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos+BotOffset)); - pt2 = QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(ceil(current.yPos-TopOffset))); + pt.moveTopLeft(QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos+BotOffset))); } - if (((fBorder)) && (!current.hasDropCap)) - current.xPos += extra.Left; +// if (((fBorder)) && (!current.hasDropCap)) +// current.xPos += extra.Left; + if (current.hasDropCap) + current.xPos = qMax(maxDX, current.xPos); + else + current.xPos = qMax(current.colLeft, current.xPos); // indent first line of par - if (a > 0) - { - if (itemText.text(a-1) == SpecialChars::PARSEP) - current.xPos += style.firstIndent(); - } - else - { - if (legacy) - current.xPos += style.firstIndent(); - } + leftIndent = 0; + if (a==0 || (a > 0 && (itemText.text(a-1) == SpecialChars::PARSEP))) + leftIndent = style.firstIndent(); // add left margin if (!current.hasDropCap) - current.xPos += style.leftMargin(); + leftIndent += style.leftMargin(); + if (leftIndent+current.colLeft < current.xPos) + leftIndent = 0; + current.xPos = qMax(leftIndent + current.colLeft, current.xPos); if (opticalMargins & ParagraphStyle::OM_LeftHangingPunct) { current.xPos += opticalLeftMargin(itemText, current.line); } @@ -1528,6 +1553,30 @@ else { // qDebug() << QString("cont.' line: '%1'").arg(a); } + + //ATTENTION + // that variable is used in lastLineY computing + //it should be set in document preferences or/and depends on current paragraph language + //as not all languages use ascented chars + bool preventingAscents = true; + //never for first line + //check if line must start at new Y position due to current glyph height or previous line descent + //not working for AutomaticLineSpacing (it is buggy case), so I skip it + + if (lastLineY > 0 && style.lineSpacingMode() != ParagraphStyle::AutomaticLineSpacing + && qMin(asce, realAsce) > current.yPos - lastLineY) + { + if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing) + current.yPos += m_Doc->typographicSettings.valueBaseGrid; + else + current.yPos += style.lineSpacing(); + a = current.breakIndex = current.line.firstItem -1; + current.itemsInLine = current.maxShrink = 0; + current.xPos = current.breakXPos = current.colLeft; + current.startOfCol = false; + continue; + } + // right tab stuff if (tabs.active) { @@ -1631,28 +1680,29 @@ { if (hl->effects() & ScStyle_HyphenationPossible || hl->ch == SpecialChars::SHYPHEN) { - pt1 = QPoint(qRound(ceil(current.xPos+extra.Right - current.maxShrink + charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0))), qRound(current.yPos+desc)); - pt2 = QPoint(qRound(ceil(current.xPos+extra.Right - current.maxShrink + charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0))), qRound(ceil(current.yPos-asce))); + pt1 = QPoint(static_cast<int>(ceil(current.xPos - current.maxShrink)), static_cast<int>(current.yPos+desc)); + pt2 = QPoint(static_cast<int>(ceil(current.xPos - current.maxShrink + charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0))), static_cast<int>(ceil(current.yPos-asce))); } else { - pt1 = QPoint(qRound(ceil(current.xPos+extra.Right - current.maxShrink )), qRound(current.yPos+desc)); - pt2 = QPoint(qRound(ceil(current.xPos+extra.Right - current.maxShrink )), qRound(ceil(current.yPos-asce))); + pt1 = QPoint(static_cast<int>(ceil(current.xPos - current.maxShrink)), static_cast<int>(current.yPos+desc)); + pt2 = QPoint(static_cast<int>(ceil(current.xPos - current.maxShrink +(1 - style.minGlyphExtension()) * wide)), static_cast<int>(ceil(current.yPos-asce))); } } else if (!legacy && SpecialChars::isBreakingSpace(hl->ch)) { - pt1 = QPoint(qRound(ceil(breakPos + extra.Right - current.maxShrink )), qRound(current.yPos+desc)); - pt2 = QPoint(qRound(ceil(breakPos + extra.Right - current.maxShrink )), qRound(ceil(current.yPos-asce))); + pt1 = QPoint(static_cast<int>(ceil(breakPos - current.maxShrink)), static_cast<int>(current.yPos+desc)); + pt2 = QPoint(static_cast<int>(ceil(breakPos - current.maxShrink +(1 - style.minGlyphExtension()) * wide)), static_cast<int>(ceil(current.yPos-asce))); } else { - pt1 = QPoint(qRound(ceil(current.xPos+extra.Right - current.maxShrink)), qRound(current.yPos+desc)); - pt2 = QPoint(qRound(ceil(current.xPos+extra.Right - current.maxShrink)), qRound(ceil(current.yPos-asce))); + pt1 = QPoint(static_cast<int>(ceil(current.xPos - current.maxShrink)), static_cast<int>(current.yPos-realAsce)); + pt2 = QPoint(static_cast<int>(ceil(current.xPos - current.maxShrink +(1 - style.minGlyphExtension()) * wide)), static_cast<int>(ceil(current.yPos+realDesc))); } + pt = QRect(pt1, pt2); // test if end of line reached - if ((!cl.contains(pf2.map(pt1))) || (!cl.contains(pf2.map(pt2))) || (legacy && current.isEndOfLine(style.rightMargin()))) + if (!QRegion(pf2.mapToPolygon(pt)).subtracted(cl).isEmpty() || (legacy && current.isEndOfLine(style.rightMargin()))) outs = true; if (current.isEndOfCol()) outs = true; @@ -1661,7 +1711,6 @@ if ((hl->ch == SpecialChars::COLBREAK) && (Cols > 1)) goNextColumn = true; - // remember possible break // #5783 : comment out "&& !outs" as this make it possible to perform a line break // before a space which contradicts unicode line breaking rules @@ -1728,7 +1777,6 @@ // qDebug() << QString("dropcapoffset: %1 -> %2").arg(current.xPos-style.dropCapOffset()).arg(current.xPos); current.xPos = qMax(current.xPos, current.colLeft); maxDX = current.xPos; - QPolygon tcli(4); if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing) { current.yPos -= m_Doc->typographicSettings.valueBaseGrid * (DropLines-1); @@ -1739,9 +1787,6 @@ int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid); // qDebug() << QString("baseline adjust after dropcaps: y=%1->%2").arg(current.yPos).arg(ceil( ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by); current.yPos = ceil( ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by; - //FIXME: use current.colLeft instead of xOffset? - tcli.setPoint(0, QPoint(qRound(hl->glyph.xoffset), qRound(maxDY-DropLines*m_Doc->typographicSettings.valueBaseGrid))); - tcli.setPoint(1, QPoint(qRound(maxDX), qRound(maxDY-DropLines*m_Doc->typographicSettings.valueBaseGrid))); } else { @@ -1749,25 +1794,14 @@ { current.yPos -= style.lineSpacing() * (DropLines-1); // qDebug() << QString("after dropcaps: y=%1").arg(current.yPos); - tcli.setPoint(0, QPoint(qRound(hl->glyph.xoffset), qRound(maxDY - DropLines * style.lineSpacing()))); - tcli.setPoint(1, QPoint(qRound(maxDX), qRound(maxDY-DropLines*style.lineSpacing()))); } else { double currasce = charStyle.font().height(style.charStyle().fontSize() / 10.0); current.yPos -= currasce * (DropLines-1); // qDebug() << QString("after dropcaps: y=%1").arg(current.yPos); - tcli.setPoint(0, QPoint(qRound(hl->glyph.xoffset), qRound(maxDY-DropLines*currasce))); - tcli.setPoint(1, QPoint(qRound(maxDX), qRound(maxDY-DropLines*currasce))); } } - tcli.setPoint(2, QPoint(qRound(maxDX), qRound(maxDY))); - tcli.setPoint(3, QPoint(qRound(hl->glyph.xoffset), qRound(maxDY))); - // #6821 : the following two lines are causing bad text flow around drop caps - // in some case, discarding them put more emphasis on user control of line spacing - /*cm = QRegion(pf2.map(tcli)); - cl = cl.subtract(cm);*/ -// current.yPos = maxDY; } // end of line if ( SpecialChars::isBreak(hl->ch, Cols > 1) || (outs)) @@ -1853,7 +1887,7 @@ //??? current.breakXPos = current.line.x; //??? for (int j=current.line.firstItem; j <= a; ++j) //??? current.breakXPos += itemText.item(j)->glyph.wide(); - + double hyphWidth = 0.0; if ((hl->effects() & ScStyle_HyphenationPossible) || hl->ch == SpecialChars::SHYPHEN) { // insert hyphen @@ -1862,6 +1896,7 @@ hl->glyph.grow(); hl->glyph.more->glyph = charStyle.font().char2CMap(QChar('-')); hl->glyph.more->xadvance = charStyle.font().charWidth('-', itemText.charStyle(a).fontSize() / 10.0) * (itemText.charStyle(a).scaleH() / 1000.0); + hyphWidth = hl->glyph.more->xadvance; } else { @@ -1876,6 +1911,8 @@ { if (opticalMargins & ParagraphStyle::OM_RightHangingPunct) current.line.width += opticalRightMargin(itemText, current.line); + else + current.line.naturalWidth += hyphWidth; OFs = 0; if (style.alignment() == ParagraphStyle::Rightaligned) @@ -1902,15 +1939,18 @@ { if (a >= current.line.firstItem) { - if ((hl->effects() & ScStyle_HyphenationPossible) || hl->ch == SpecialChars::SHYPHEN) + if ((hl->effects() & ScStyle_HyphenationPossible) || hl->ch == SpecialChars::SHYPHEN + || current.line.lastItem == 0) { current.itemsInLine = 0; a = current.line.firstItem - 1; } else { - --a; - --current.itemsInLine; +// --a; +// --current.itemsInLine; + current.itemsInLine = 0; + a = current.line.firstItem - 1; } } if (a >= 0) @@ -1925,17 +1965,17 @@ else if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing) style.setLineSpacing(m_Doc->typographicSettings.valueBaseGrid); } - current.breakLine(itemText, style, firstLineOffset(), a); + //current.breakLine(itemText, style, firstLineOffset(), a); // qDebug() << QString("style no break pos %1: %2 (%3)").arg(a).arg(style.alignment()).arg(style.parent()); // qDebug() << QString("style nb @%6: %1 -- %2, %4/%5 char: %3").arg(style.leftMargin()).arg(style.rightMargin()) // .arg(style.charStyle().asString()).arg(style.name()).arg(style.parent()) // .arg(a); - EndX = current.endOfLine(cl, pf2, style.rightMargin()); - current.finishLine(EndX); + //EndX = current.endOfLine(cl, pf2, style.rightMargin()); + //current.finishLine(EndX); // qDebug() << QString("no break pos: %1-%2 @ %3 wid %4 nat %5 endX %6") // .arg(current.line.firstItem).arg(current.line.firstItem) // .arg(current.line.x).arg(current.line.width).arg(current.line.naturalWidth).arg(EndX); - indentLine(itemText, current.line, 0); + //indentLine(itemText, current.line, 0); } } if ( outs || SpecialChars::isBreak(hl->ch, (Cols > 1)) ) @@ -1954,9 +1994,12 @@ double BotOffset = desc+extra.Bottom+lineCorr; while (!current.isEndOfLine(style.rightMargin())) { - current.xPos++; + current.xPos += xStep; if (current.isEndOfLine(style.rightMargin())) { + lastLineY = current.yPos + 1; + if (!preventingAscents) + lastLineY += current.line.descent -1; fromOut = false; // qDebug() << QString("layout: next lower2 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid); // qDebug() << QString("nextline: y=%1+%2").arg(current.yPos).arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing? m_Doc->typographicSettings.valueBaseGrid : style.lineSpacing()); @@ -1979,6 +2022,7 @@ { current.hasDropCap = false; current.xPos = current.colLeft; + maxDX = 0; } else current.xPos = maxDX; @@ -2000,8 +2044,8 @@ // performed at lines 1488-1512 and can trigger hang due to changing region detection //pt1 = QPoint(qRound(current.xPos+extra.Right), static_cast<int>(current.yPos+BotOffset)); //pt2 = QPoint(qRound(current.xPos+extra.Right), static_cast<int>(ceil(current.yPos-asce))); - pt1 = QPoint(qRound(current.xPos+extra.Right), qRound(current.yPos+BotOffset)); - pt2 = QPoint(qRound(current.xPos+extra.Right), qRound(ceil(current.yPos-asce))); + pt1 = QPoint(static_cast<int>(current.xPos), static_cast<int>(current.yPos+BotOffset)); + pt2 = QPoint(static_cast<int>(current.xPos), static_cast<int>(ceil(current.yPos-asce))); if (cl.contains(pf2.map(pt1)) && cl.contains(pf2.map(pt2))) break; // else @@ -2016,7 +2060,7 @@ // qDebug() << QString("go no room 2: %1").arg(a); break; } - current.xPos--; + current.xPos-=xStep; current.xPos = qMax(current.xPos, current.colLeft); } } @@ -2033,10 +2077,12 @@ // qDebug() << QString("layout: next lower3 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid); + lastLineY = current.yPos + 1; + if (!preventingAscents) + lastLineY += current.line.descent -1; if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing) { // qDebug() << QString("next line (grid): y=%1+%2").arg(current.yPos).arg(m_Doc->typographicSettings.valueBaseGrid); - current.yPos += m_Doc->typographicSettings.valueBaseGrid; } else @@ -2059,6 +2105,7 @@ { current.hasDropCap = false; current.xPos = current.colLeft; + maxDX = 0; } else current.xPos = maxDX; @@ -2077,10 +2124,9 @@ } } - // calc. needed vertical space // Let’s try to change into "calc. _wanted_ vertical space" - pm - if (current.itemsInLine != 0) + if (current.itemsInLine > 0) { if ( itemText.charStyle(current.line.firstItem).effects() & ScStyle_DropCap) { @@ -2090,12 +2136,12 @@ } } - fillInTabLeaders(itemText, current.line); - + if (current.itemsInLine > 1) + fillInTabLeaders(itemText, current.line); current.startOfCol = false; // qDebug() << QString("layout: line %1 - %2 @ (%3,%4) wd %5/%6").arg(current.line.firstItem).arg(current.line.lastItem) // .arg(current.line.x).arg(current.line.y).arg(current.line.naturalWidth).arg(current.line.width); - if (current.line.firstItem > current.line.lastItem) + if (current.line.firstItem >= current.line.lastItem) ; //qDebug() << QString("layout: empty line %1 - %2").arg(current.line.firstItem).arg(current.line.lastItem); else if (current.itemsInLine > 0) itemText.appendLine(current.line); @@ -2115,6 +2161,7 @@ if (current.column < Cols) { current.nextColumn(asce); + lastLineY = 0; } else { } |
|
Err.. just testing this.. I am seeing the same behaviour as screen.jpg after applying formatting.patch... is this the right patch? |
|
Yeah, you are right, fixing one issue other were broken... sorry. Now I have patch more tested. In the meantime I have found issue with top/bottom margins not working properly. By the way I have change sensibility of text for frame height, so bottom text lines are rendered if in frame is space for it. Current behaviour is more restricted about frame height and line is not rendered even if there was space in frame for it. |
|
formatting2.patch (25,956 bytes)
Index: Version135/Scribus/scribus/pageitem_textframe.cpp =================================================================== --- Version135/Scribus/scribus/pageitem_textframe.cpp (wersja 16641) +++ Version135/Scribus/scribus/pageitem_textframe.cpp (kopia robocza) @@ -155,9 +155,7 @@ if ((currentGroup != -1) && (docItem->Groups.count() != 0) && (currentGroup == docItem->Groups.top())) continue; if (docItem->textFlowAroundObject()) - { - result = result.subtract(itemShape(docItem, Mp->xOffset() - Dp->xOffset(), Mp->yOffset() - Dp->yOffset())); - } + result = result.subtracted(itemShape(docItem, Mp->xOffset() - Dp->xOffset(), Mp->yOffset() - Dp->yOffset())); if (docItem->isGroupControl) currentGroup = docItem->Groups.top(); } @@ -192,7 +190,7 @@ if ((currentGroup != -1) && (docItem->Groups.count() != 0) && (currentGroup == docItem->Groups.top())) continue; if (docItem->textFlowAroundObject()) - result = result.subtract(itemShape(docItem, 0, 0)); + result = result.subtracted(itemShape(docItem, 0, 0)); if (docItem->isGroupControl) currentGroup = docItem->Groups.top(); } @@ -377,11 +375,12 @@ { startOfCol = true; colLeft = (colWidth + colGap) * column + insets.Left + lineCorr; + //now colRight is REAL column right edge colRight = colLeft + colWidth; if (legacy) - colRight += insets.Right + lineCorr; //??? + colRight += lineCorr; xPos = colLeft; - yPos = asce + insets.Top + lineCorr + 1; + yPos = asce + insets.Top + lineCorr; } bool isEndOfCol(double morespace = 0) @@ -398,7 +397,8 @@ line.x = xPos; line.y = yPos; line.firstItem = first; - line.ascent = 10; + line.lastItem = 0; + line.ascent = 0; line.descent = 0; line.width = 0; line.naturalWidth = 0; @@ -407,6 +407,7 @@ breakXPos = 0; maxShrink = 0; maxStretch = 0; + width = 0; } @@ -439,12 +440,8 @@ if (newLooseness >= oldLooseness) return; } - breakXPos = colRight; } - else - { - breakXPos = pos; - } + breakXPos = pos; breakIndex = index; } @@ -476,7 +473,7 @@ bool isEndOfLine(double moreSpace = 0) { if (legacy) - return xPos + insets.Right + lineCorr + moreSpace - maxShrink >= colRight; + return xPos + lineCorr + moreSpace - maxShrink >= colRight; else return xPos + moreSpace - maxShrink >= colRight; } @@ -492,7 +489,7 @@ while ((!shape.contains(pf2.map(pt1))) || (!shape.contains(pf2.map(pt2)))) { tmpX++; - if (xPos + (legacy? lineCorr + insets.Right : 0) + lineCorr + morespace >= colRight) + if (xPos + (legacy? lineCorr : 0) + lineCorr + morespace >= colRight) { return tmpX; } @@ -520,10 +517,10 @@ // if we aren't restricted further, we'll end at this maxX: double maxX = colRight - morespace; - if (legacy) maxX -= (lineCorr + insets.Right); + if (legacy) maxX -= lineCorr; - double StartX = floor(qMax(line.x, qMin(colRight,breakXPos) - 1)); - int xPos = static_cast<int>(ceil(maxX + insets.Right)); + double StartX = floor(qMax(line.x, qMin(maxX,breakXPos-maxShrink-1))-1); + int xPos = static_cast<int>(ceil(maxX)); int yDesc = static_cast<int>(yPos+line.descent); int yAsc = static_cast<int>(ceil(yPos-line.ascent)); @@ -542,14 +539,14 @@ // if the intersection only has 1 rectangle, then nothing gets in the way if (lineI.numRects() == 1) { - int xPos = qRound(ceil(StartX + 0.125 + insets.Right)); + int xPos = static_cast<int>(ceil(StartX + 0.125)); pt12.setX(xPos); pt22.setX(xPos); if (shape.contains(pf2.map(pt12)) && shape.contains(pf2.map(pt22))) { QRect rect = lineI.rects().at(0); double mx = qMax(rect.left(), rect.right()) - pf2.dx(); - int steps = static_cast<int>((mx - StartX - insets.Right - 2)/0.125); + int steps = static_cast<int>((mx - StartX - 2)/0.125); if (steps > 0) StartX += steps * 0.125; } @@ -560,7 +557,7 @@ double Interval = 0.125; do { EndX2 += Interval; - int xPos = qRound(ceil(EndX2 + insets.Right)); + int xPos = static_cast<int>(ceil(EndX2)); pt12.setX (xPos); pt22.setX (xPos); } while ((EndX2 < maxX) && shape.contains(pf2.map(pt12)) && shape.contains(pf2.map(pt22))); @@ -570,7 +567,7 @@ qDebug()<<EndX<<EndX2<<StartX<<maxX; qDebug()<<"DIFFERING ENDX!!!!!"; }*/ - return EndX2; + return qMin(EndX2, colRight); } @@ -712,7 +709,10 @@ } else if( offsetPolicy == FLOPLineSpacing ) { - adj = firstasce - style.lineSpacing(); + if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing) + adj = 0.0; + else + adj = firstasce - style.lineSpacing(); } line.ascent = currasce; line.y -= adj; @@ -952,9 +952,10 @@ // ScribusView* view = m_Doc->view(); QMatrix pf2; QPoint pt1, pt2; + QRect pt; /*QRegion cm;*/ double chs, chsd = 0; - double oldCurY, EndX, OFs, wide, kernVal; + double oldCurY, EndX, OFs, wide=0, kernVal; QString chstr; ScText *hl; ParagraphStyle style; @@ -975,7 +976,8 @@ tTabValues.clear(); bool DropCmode = false; - double desc=0, asce=0, maxDY=0, desc2=0, maxDX=0; + double desc=0, asce=0, desc2=0, realAsce=0, realDesc = 0; + double maxDY=0, maxDX=0; double DropCapDrop = 0; int DropLines = 0; int DropLinesCount = 0; @@ -998,6 +1000,10 @@ current.init(Width, Height, extra, lineCorr); current.initColumns(columnWidth(), ColGap); current.hyphenCount = 0; + + //hold Y position of last line of text (with glyphs descent) + //for moving next line if glyphs are higher than that + double lastLineY; // dump styles /* @@ -1037,6 +1043,7 @@ } current.nextColumn(0); + lastLineY = 0; // find start of first line if (firstInFrame() < itemText.length()) @@ -1075,6 +1082,7 @@ outs = false; OFs = 0; MaxChars = 0; + double xStep = legacy? 1 : 0.125; for (int a = firstInFrame(); a < itemText.length(); ++a) { hl = itemText.item(a); @@ -1326,14 +1334,16 @@ double hlcsize10=charStyle.fontSize() / 10.0; if ((hl->ch == SpecialChars::OBJECT) && (hl->embedded.hasItem())) { - desc = desc2 = 0; + desc = desc2 = realDesc = 0; } else { desc = desc2 = -charStyle.font().descent(hlcsize10); + realDesc = charStyle.font().realCharDescent(chstr[0], hlcsize10); current.rememberShrinkStretch(hl->ch, wide, style); } asce = charStyle.font().ascent(hlcsize10); + realAsce = charStyle.font().realCharAscent(chstr[0], hlcsize10); // wide = wide * hl->glyph.scaleH; } fBorder = false; @@ -1346,6 +1356,7 @@ { // start next col current.nextColumn(asce); + lastLineY = 0; if (((a > firstInFrame()) && (itemText.text(a-1) == SpecialChars::PARSEP)) || ((a == firstInFrame()) && (BackBox == 0))) { @@ -1394,7 +1405,7 @@ if (current.startOfCol) { // qDebug() << QString("current.startOfCol: %1 + %2 + %3 + 1 =%4").arg(asce).arg(extra.Top).arg(lineCorr).arg(asce + extra.Top + lineCorr + 1); - current.yPos = asce + extra.Top + lineCorr + 1; + current.yPos = TopOffset + extra.Top + lineCorr; // if (((a > 0) && (itemText.at(a-1)->ch == QChar(13))) || ((a == 0) && (BackBox == 0))) // current.yPos += m_Doc->docParagraphStyles[hl->cab].gapBefore; } @@ -1417,28 +1428,42 @@ current.yPos = TopOffset+1; } */ + //find line start + double leftIndent = 0; + if (!current.hasDropCap) + leftIndent = style.leftMargin(); + if (a==0 || (a > 0 && (itemText.text(a-1) == SpecialChars::PARSEP))) + leftIndent += style.firstIndent(); + current.xPos = qMax(leftIndent + current.colLeft, current.xPos); + // find linelength: - pt1 = QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos+BotOffset)); - pt2 = QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(ceil(current.yPos-TopOffset))); + pt = QRect( QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos+BotOffset)), + QPoint(static_cast<int>(ceil(current.xPos + (1 - style.minGlyphExtension()) * wide)), static_cast<int>(current.yPos-TopOffset))); // increase pt1/pt2 until i-beam reaches end of line // qDebug() << QString("linestart: %1 + %2 + %3 < %4").arg(current.xPos).arg(wide).arg(style.rightMargin()).arg(current.colRight); - double leftIndent = 0; - double xStep = legacy? 1 : 0.125; - while (!cl.contains(pf2.map(pt1)) || !cl.contains(pf2.map(pt2)) || current.isEndOfLine(wide + leftIndent + style.rightMargin())) + while (!QRegion(pf2.mapToPolygon(pt)).subtracted(cl).isEmpty() || current.isEndOfLine((1 - style.minGlyphExtension()) * wide + style.rightMargin())) { fBorder = true; current.xPos += xStep; - if (current.isEndOfLine(wide + leftIndent + style.rightMargin())) + if (current.isEndOfLine((1 - style.minGlyphExtension()) * wide + style.rightMargin())) { // qDebug() << QString("eocol %5? %1 + %2 + %3 + %4").arg(current.yPos).arg(current.startOfCol).arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(style.lineSpacing()).arg(current.column); // new line fBorder = false; - current.xPos = current.colLeft; - - leftIndent = style.leftMargin(); - if (a > 0 && itemText.text(a-1) == SpecialChars::PARSEP) - leftIndent += style.firstIndent(); - + if (current.hasDropCap) + { + DropLinesCount++; + if (DropLinesCount >= DropLines) + { + current.hasDropCap = false; + current.xPos = current.colLeft; + maxDX = 0; + } + } + if (current.hasDropCap) + current.xPos = maxDX; + else + current.xPos = current.colLeft - extra.Left + leftIndent; if (current.startOfCol) current.yPos++; else @@ -1461,6 +1486,7 @@ if (current.column < Cols) { current.nextColumn(asce); + lastLineY = 0; if (((a > firstInFrame()) && (itemText.text(a-1) == SpecialChars::PARSEP)) || ((a == firstInFrame()) && (BackBox == 0))) { if (chstr[0] != SpecialChars::PARSEP) @@ -1497,26 +1523,23 @@ } } } - pt1 = QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos+BotOffset)); - pt2 = QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(ceil(current.yPos-TopOffset))); + pt.moveTopLeft(QPoint(static_cast<int>(ceil(current.xPos)), static_cast<int>(current.yPos+BotOffset))); } - if (((fBorder)) && (!current.hasDropCap)) - current.xPos += extra.Left; + if (current.hasDropCap) + current.xPos = qMax(maxDX, current.xPos); + else + current.xPos = qMax(current.colLeft, current.xPos); // indent first line of par - if (a > 0) - { - if (itemText.text(a-1) == SpecialChars::PARSEP) - current.xPos += style.firstIndent(); - } - else - { - if (legacy) - current.xPos += style.firstIndent(); - } + leftIndent = 0; + if (a==0 || (a > 0 && (itemText.text(a-1) == SpecialChars::PARSEP))) + leftIndent = style.firstIndent(); // add left margin if (!current.hasDropCap) - current.xPos += style.leftMargin(); + leftIndent += style.leftMargin(); + if (leftIndent+current.colLeft < current.xPos) + leftIndent = 0; + current.xPos = qMax(leftIndent + current.colLeft, current.xPos); if (opticalMargins & ParagraphStyle::OM_LeftHangingPunct) { current.xPos += opticalLeftMargin(itemText, current.line); } @@ -1528,6 +1551,30 @@ else { // qDebug() << QString("cont.' line: '%1'").arg(a); } + + //ATTENTION + // that variable is used in lastLineY computing + //it should be set in document preferences or/and depends on current paragraph language + //as not all languages use ascented chars + bool preventingAscents = true; + //never for first line + //check if line must start at new Y position due to current glyph height or previous line descent + //not working for AutomaticLineSpacing (it is buggy case), so I skip it + + if (lastLineY > 0 && style.lineSpacingMode() != ParagraphStyle::AutomaticLineSpacing + && qMin(asce, realAsce) > current.yPos - lastLineY) + { + if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing) + current.yPos += m_Doc->typographicSettings.valueBaseGrid; + else + current.yPos += style.lineSpacing(); + a = current.breakIndex = current.line.firstItem -1; + current.itemsInLine = current.maxShrink = 0; + current.xPos = current.breakXPos = current.colLeft; + current.startOfCol = false; + continue; + } + // right tab stuff if (tabs.active) { @@ -1631,28 +1678,29 @@ { if (hl->effects() & ScStyle_HyphenationPossible || hl->ch == SpecialChars::SHYPHEN) { - pt1 = QPoint(qRound(ceil(current.xPos+extra.Right - current.maxShrink + charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0))), qRound(current.yPos+desc)); - pt2 = QPoint(qRound(ceil(current.xPos+extra.Right - current.maxShrink + charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0))), qRound(ceil(current.yPos-asce))); + pt1 = QPoint(static_cast<int>(ceil(current.xPos - current.maxShrink)), static_cast<int>(current.yPos+desc)); + pt2 = QPoint(static_cast<int>(ceil(current.xPos - current.maxShrink + charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0))), static_cast<int>(ceil(current.yPos-asce))); } else { - pt1 = QPoint(qRound(ceil(current.xPos+extra.Right - current.maxShrink )), qRound(current.yPos+desc)); - pt2 = QPoint(qRound(ceil(current.xPos+extra.Right - current.maxShrink )), qRound(ceil(current.yPos-asce))); + pt1 = QPoint(static_cast<int>(ceil(current.xPos - current.maxShrink)), static_cast<int>(current.yPos+desc)); + pt2 = QPoint(static_cast<int>(ceil(current.xPos - current.maxShrink +(1 - style.minGlyphExtension()) * wide)), static_cast<int>(ceil(current.yPos-asce))); } } else if (!legacy && SpecialChars::isBreakingSpace(hl->ch)) { - pt1 = QPoint(qRound(ceil(breakPos + extra.Right - current.maxShrink )), qRound(current.yPos+desc)); - pt2 = QPoint(qRound(ceil(breakPos + extra.Right - current.maxShrink )), qRound(ceil(current.yPos-asce))); + pt1 = QPoint(static_cast<int>(ceil(breakPos - current.maxShrink)), static_cast<int>(current.yPos+desc)); + pt2 = QPoint(static_cast<int>(ceil(breakPos - current.maxShrink +(1 - style.minGlyphExtension()) * wide)), static_cast<int>(ceil(current.yPos-asce))); } else { - pt1 = QPoint(qRound(ceil(current.xPos+extra.Right - current.maxShrink)), qRound(current.yPos+desc)); - pt2 = QPoint(qRound(ceil(current.xPos+extra.Right - current.maxShrink)), qRound(ceil(current.yPos-asce))); + pt1 = QPoint(static_cast<int>(ceil(current.xPos - current.maxShrink)), static_cast<int>(current.yPos-realAsce)); + pt2 = QPoint(static_cast<int>(ceil(current.xPos - current.maxShrink +(1 - style.minGlyphExtension()) * wide)), static_cast<int>(ceil(current.yPos+realDesc))); } + pt = QRect(pt1, pt2); // test if end of line reached - if ((!cl.contains(pf2.map(pt1))) || (!cl.contains(pf2.map(pt2))) || (legacy && current.isEndOfLine(style.rightMargin()))) + if (!QRegion(pf2.mapToPolygon(pt)).subtracted(cl).isEmpty() || (legacy && current.isEndOfLine(style.rightMargin()))) outs = true; if (current.isEndOfCol()) outs = true; @@ -1661,7 +1709,6 @@ if ((hl->ch == SpecialChars::COLBREAK) && (Cols > 1)) goNextColumn = true; - // remember possible break // #5783 : comment out "&& !outs" as this make it possible to perform a line break // before a space which contradicts unicode line breaking rules @@ -1728,7 +1775,6 @@ // qDebug() << QString("dropcapoffset: %1 -> %2").arg(current.xPos-style.dropCapOffset()).arg(current.xPos); current.xPos = qMax(current.xPos, current.colLeft); maxDX = current.xPos; - QPolygon tcli(4); if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing) { current.yPos -= m_Doc->typographicSettings.valueBaseGrid * (DropLines-1); @@ -1739,9 +1785,6 @@ int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid); // qDebug() << QString("baseline adjust after dropcaps: y=%1->%2").arg(current.yPos).arg(ceil( ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by); current.yPos = ceil( ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by; - //FIXME: use current.colLeft instead of xOffset? - tcli.setPoint(0, QPoint(qRound(hl->glyph.xoffset), qRound(maxDY-DropLines*m_Doc->typographicSettings.valueBaseGrid))); - tcli.setPoint(1, QPoint(qRound(maxDX), qRound(maxDY-DropLines*m_Doc->typographicSettings.valueBaseGrid))); } else { @@ -1749,25 +1792,14 @@ { current.yPos -= style.lineSpacing() * (DropLines-1); // qDebug() << QString("after dropcaps: y=%1").arg(current.yPos); - tcli.setPoint(0, QPoint(qRound(hl->glyph.xoffset), qRound(maxDY - DropLines * style.lineSpacing()))); - tcli.setPoint(1, QPoint(qRound(maxDX), qRound(maxDY-DropLines*style.lineSpacing()))); } else { double currasce = charStyle.font().height(style.charStyle().fontSize() / 10.0); current.yPos -= currasce * (DropLines-1); // qDebug() << QString("after dropcaps: y=%1").arg(current.yPos); - tcli.setPoint(0, QPoint(qRound(hl->glyph.xoffset), qRound(maxDY-DropLines*currasce))); - tcli.setPoint(1, QPoint(qRound(maxDX), qRound(maxDY-DropLines*currasce))); } } - tcli.setPoint(2, QPoint(qRound(maxDX), qRound(maxDY))); - tcli.setPoint(3, QPoint(qRound(hl->glyph.xoffset), qRound(maxDY))); - // #6821 : the following two lines are causing bad text flow around drop caps - // in some case, discarding them put more emphasis on user control of line spacing - /*cm = QRegion(pf2.map(tcli)); - cl = cl.subtract(cm);*/ -// current.yPos = maxDY; } // end of line if ( SpecialChars::isBreak(hl->ch, Cols > 1) || (outs)) @@ -1853,7 +1885,7 @@ //??? current.breakXPos = current.line.x; //??? for (int j=current.line.firstItem; j <= a; ++j) //??? current.breakXPos += itemText.item(j)->glyph.wide(); - + double hyphWidth = 0.0; if ((hl->effects() & ScStyle_HyphenationPossible) || hl->ch == SpecialChars::SHYPHEN) { // insert hyphen @@ -1862,6 +1894,7 @@ hl->glyph.grow(); hl->glyph.more->glyph = charStyle.font().char2CMap(QChar('-')); hl->glyph.more->xadvance = charStyle.font().charWidth('-', itemText.charStyle(a).fontSize() / 10.0) * (itemText.charStyle(a).scaleH() / 1000.0); + hyphWidth = hl->glyph.more->xadvance; } else { @@ -1876,6 +1909,8 @@ { if (opticalMargins & ParagraphStyle::OM_RightHangingPunct) current.line.width += opticalRightMargin(itemText, current.line); + else + current.line.naturalWidth += hyphWidth; OFs = 0; if (style.alignment() == ParagraphStyle::Rightaligned) @@ -1902,15 +1937,16 @@ { if (a >= current.line.firstItem) { - if ((hl->effects() & ScStyle_HyphenationPossible) || hl->ch == SpecialChars::SHYPHEN) + if ((hl->effects() & ScStyle_HyphenationPossible) || hl->ch == SpecialChars::SHYPHEN + || current.line.lastItem == 0) { current.itemsInLine = 0; a = current.line.firstItem - 1; } else { - --a; - --current.itemsInLine; + current.itemsInLine = 0; + a = current.line.firstItem - 1; } } if (a >= 0) @@ -1925,17 +1961,17 @@ else if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing) style.setLineSpacing(m_Doc->typographicSettings.valueBaseGrid); } - current.breakLine(itemText, style, firstLineOffset(), a); + //current.breakLine(itemText, style, firstLineOffset(), a); // qDebug() << QString("style no break pos %1: %2 (%3)").arg(a).arg(style.alignment()).arg(style.parent()); // qDebug() << QString("style nb @%6: %1 -- %2, %4/%5 char: %3").arg(style.leftMargin()).arg(style.rightMargin()) // .arg(style.charStyle().asString()).arg(style.name()).arg(style.parent()) // .arg(a); - EndX = current.endOfLine(cl, pf2, style.rightMargin()); - current.finishLine(EndX); + //EndX = current.endOfLine(cl, pf2, style.rightMargin()); + //current.finishLine(EndX); // qDebug() << QString("no break pos: %1-%2 @ %3 wid %4 nat %5 endX %6") // .arg(current.line.firstItem).arg(current.line.firstItem) // .arg(current.line.x).arg(current.line.width).arg(current.line.naturalWidth).arg(EndX); - indentLine(itemText, current.line, 0); + //indentLine(itemText, current.line, 0); } } if ( outs || SpecialChars::isBreak(hl->ch, (Cols > 1)) ) @@ -1954,9 +1990,12 @@ double BotOffset = desc+extra.Bottom+lineCorr; while (!current.isEndOfLine(style.rightMargin())) { - current.xPos++; + current.xPos += xStep; if (current.isEndOfLine(style.rightMargin())) { + lastLineY = current.yPos + 1; + if (!preventingAscents) + lastLineY += current.line.descent -1; fromOut = false; // qDebug() << QString("layout: next lower2 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid); // qDebug() << QString("nextline: y=%1+%2").arg(current.yPos).arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing? m_Doc->typographicSettings.valueBaseGrid : style.lineSpacing()); @@ -1965,13 +2004,6 @@ current.yPos += m_Doc->typographicSettings.valueBaseGrid; else current.yPos += style.lineSpacing(); - if (current.isEndOfCol(desc) && (current.column+1 == Cols)) - { - goNoRoom = true; - MaxChars = a + 1; -// qDebug() << QString("go no room 1: %1").arg(a)); - break; - } if (current.hasDropCap) { ++DropLinesCount; @@ -1979,6 +2011,7 @@ { current.hasDropCap = false; current.xPos = current.colLeft; + maxDX = 0; } else current.xPos = maxDX; @@ -2000,8 +2033,8 @@ // performed at lines 1488-1512 and can trigger hang due to changing region detection //pt1 = QPoint(qRound(current.xPos+extra.Right), static_cast<int>(current.yPos+BotOffset)); //pt2 = QPoint(qRound(current.xPos+extra.Right), static_cast<int>(ceil(current.yPos-asce))); - pt1 = QPoint(qRound(current.xPos+extra.Right), qRound(current.yPos+BotOffset)); - pt2 = QPoint(qRound(current.xPos+extra.Right), qRound(ceil(current.yPos-asce))); + pt1 = QPoint(static_cast<int>(current.xPos), static_cast<int>(current.yPos+BotOffset)); + pt2 = QPoint(static_cast<int>(current.xPos), static_cast<int>(ceil(current.yPos-asce))); if (cl.contains(pf2.map(pt1)) && cl.contains(pf2.map(pt2))) break; // else @@ -2009,14 +2042,7 @@ } if (fromOut) { - if (current.isEndOfCol(desc) && (current.column+1 == Cols)) - { - goNoRoom = true; - MaxChars = a + 1; -// qDebug() << QString("go no room 2: %1").arg(a); - break; - } - current.xPos--; + current.xPos-=xStep; current.xPos = qMax(current.xPos, current.colLeft); } } @@ -2033,10 +2059,12 @@ // qDebug() << QString("layout: next lower3 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid); + lastLineY = current.yPos + 1; + if (!preventingAscents) + lastLineY += current.line.descent -1; if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing) { // qDebug() << QString("next line (grid): y=%1+%2").arg(current.yPos).arg(m_Doc->typographicSettings.valueBaseGrid); - current.yPos += m_Doc->typographicSettings.valueBaseGrid; } else @@ -2059,6 +2087,7 @@ { current.hasDropCap = false; current.xPos = current.colLeft; + maxDX = 0; } else current.xPos = maxDX; @@ -2077,10 +2106,9 @@ } } - // calc. needed vertical space // Let’s try to change into "calc. _wanted_ vertical space" - pm - if (current.itemsInLine != 0) + if (current.itemsInLine > 0) { if ( itemText.charStyle(current.line.firstItem).effects() & ScStyle_DropCap) { @@ -2090,12 +2118,12 @@ } } - fillInTabLeaders(itemText, current.line); - + if (current.itemsInLine > 1) + fillInTabLeaders(itemText, current.line); current.startOfCol = false; // qDebug() << QString("layout: line %1 - %2 @ (%3,%4) wd %5/%6").arg(current.line.firstItem).arg(current.line.lastItem) // .arg(current.line.x).arg(current.line.y).arg(current.line.naturalWidth).arg(current.line.width); - if (current.line.firstItem > current.line.lastItem) + if (current.line.firstItem >= current.line.lastItem) ; //qDebug() << QString("layout: empty line %1 - %2").arg(current.line.firstItem).arg(current.line.lastItem); else if (current.itemsInLine > 0) itemText.appendLine(current.line); @@ -2115,6 +2143,7 @@ if (current.column < Cols) { current.nextColumn(asce); + lastLineY = 0; } else { } |
|
Ok.. cool.. now the issues shows in Dokument-1.sla and 9436.sla are solved.. but the issue in 0009932 is no longer solved.. :) |
|
Cezary, where are you up to with this patch? If it really is going to solve 3 bugs, we should get it in SVN, once it covers them all properly. |
|
Look here http://bugs.scribus.net/view.php?id=10251 |
|
Solved by 0010251 patch |
Date Modified | Username | Field | Change |
---|---|---|---|
2010-10-25 06:19 | cezaryece | New Issue | |
2010-10-25 06:19 | cezaryece | File Added: 9436.sla | |
2010-10-25 06:20 | cezaryece | Tag Attached: text frames | |
2010-10-25 06:25 | cezaryece | Note Added: 0024724 | |
2010-10-25 11:10 | cezaryece | File Added: Dokument-2.sla | |
2010-10-25 11:13 | cezaryece | File Added: Dokument-2-1.5svn.sla | |
2010-10-25 11:15 | cezaryece | File Added: Dokument-1.3.9svn.sla | |
2010-11-29 23:36 | tenbear | Note Added: 0024925 | |
2010-11-30 06:54 | cezaryece | Note Added: 0024928 | |
2010-12-01 02:21 | christoph_s | Assigned To | => avox |
2010-12-01 02:21 | christoph_s | Status | new => assigned |
2011-02-20 12:50 |
|
Target Version | => 1.4.1.svn |
2011-04-16 10:05 | cbradney | Target Version | 1.4.1.svn => 1.4.1 |
2011-05-27 09:50 | cezaryece | File Added: screen.jpg | |
2011-06-01 08:24 | cezaryece | File Added: wrong_formating.patch | |
2011-06-01 08:30 | cezaryece | Note Added: 0026298 | |
2011-06-01 11:34 | ale | File Deleted: wrong_formating.patch | |
2011-06-01 11:34 | ale | Note Added: 0026299 | |
2011-06-01 12:44 | cezaryece | File Added: wrong_formating.patch | |
2011-06-01 12:45 | cezaryece | File Added: solved.jpg | |
2011-06-01 12:48 | cezaryece | Note Added: 0026301 | |
2011-06-02 11:15 | cezaryece | File Added: wrong_formating_overflow.patch | |
2011-06-02 11:19 | cezaryece | Note Added: 0026303 | |
2011-06-02 14:55 | cbradney | Target Version | 1.4.1 => 1.4.0 |
2011-06-02 14:56 | cbradney | Note Added: 0026304 | |
2011-06-02 14:56 | cbradney | Note Added: 0026305 | |
2011-06-05 22:43 | jghali | Relationship added | has duplicate 0010015 |
2011-06-06 09:26 | cezaryece | Note Added: 0026323 | |
2011-06-06 09:46 | cezaryece | Note Edited: 0026323 | |
2011-06-06 09:47 | cezaryece | Note Edited: 0026323 | |
2011-06-07 06:46 | cezaryece | Note Added: 0026334 | |
2011-06-07 17:32 | ale | Relationship added | related to 0008538 |
2011-06-08 13:58 | cezaryece | Note Added: 0026341 | |
2011-06-08 17:55 | ale | Relationship added | has duplicate 0005891 |
2011-06-14 13:26 | cezaryece | File Added: solved2.jpg | |
2011-06-14 13:28 | cezaryece | Note Added: 0026393 | |
2011-06-14 13:29 | cezaryece | File Added: Dokument-1.sla | |
2011-06-14 13:31 | cezaryece | Note Edited: 0026393 | |
2011-06-14 18:59 | cezaryece | File Added: wrong_formating_overflow_v2.patch | |
2011-06-14 19:03 | cezaryece | Note Added: 0026394 | |
2011-06-16 09:58 | cezaryece | Note Added: 0026411 | |
2011-06-21 14:20 | cezaryece | Note Added: 0026447 | |
2011-06-21 14:20 | cezaryece | File Added: formatting.patch | |
2011-06-26 21:09 | cbradney | Note Added: 0026482 | |
2011-06-27 13:03 | cezaryece | Note Added: 0026491 | |
2011-06-27 13:04 | cezaryece | File Added: formatting2.patch | |
2011-06-27 19:49 | cbradney | Relationship added | related to 0009932 |
2011-06-27 19:51 | cbradney | Note Added: 0026493 | |
2011-07-19 19:43 | cbradney | Relationship added | related to 0009902 |
2011-07-19 19:44 | cbradney | Note Added: 0026614 | |
2011-09-08 10:30 | cezaryece | Note Added: 0026837 | |
2011-10-01 21:54 | jghali | Note Added: 0026941 | |
2011-10-01 21:54 | jghali | Status | assigned => resolved |
2011-10-01 21:54 | jghali | Fixed in Version | => 1.4.0svn |
2011-10-01 21:54 | jghali | Resolution | open => fixed |
2011-10-01 21:54 | jghali | Assigned To | avox => jghali |
2011-10-05 20:02 | cbradney | Relationship added | related to 0010251 |
2011-10-05 20:02 | cbradney | Status | resolved => closed |
2015-09-17 20:08 | Kunda | Category | Story Editor / Text Frames => Story Ed/Txt Frames |
2015-09-17 20:12 | Kunda | Category | Story Ed/Txt Frames => Story Editor / Text Frames |