r16868 by jghali - #10294: Port 0010251 patch to 1.5.0svn
scribus-commit
scribus-commit at lists.scribus.net
Sat Oct 1 21:50:35 UTC 2011
Author: jghali
Date: Sat Oct 1 21:50:35 2011
New Revision: 16868
URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=16868
Log:
#10294: Port 0010251 patch to 1.5.0svn
Modified:
trunk/Scribus/scribus/pageitem_textframe.cpp
Modified: trunk/Scribus/scribus/pageitem_textframe.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=16868&path=/trunk/Scribus/scribus/pageitem_textframe.cpp
==============================================================================
--- trunk/Scribus/scribus/pageitem_textframe.cpp (original)
+++ trunk/Scribus/scribus/pageitem_textframe.cpp Sat Oct 1 21:50:35 2011
@@ -144,9 +144,7 @@
if (((docItem->ItemNr > ItemNr) && (docItem->LayerID == LayerID)) || (LayerLevItem > LayerLev && m_Doc->layerFlow(docItem->LayerID)))
{
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()));
}
} // for all masterItems
// (JG) #6009 : disable possible interaction between master text frames and normal frames
@@ -174,14 +172,13 @@
if (((docItem->ItemNr > ItemNr) && (docItem->LayerID == LayerID)) || (LayerLevItem > LayerLev && m_Doc->layerFlow(docItem->LayerID)))
{
if (docItem->textFlowAroundObject())
- result = result.subtract(itemShape(docItem, 0, 0));
+ result = result.subtracted(itemShape(docItem, 0, 0));
}
} // for all docItems
} // if(OnMasterPage.isEmpty()
} // if(!Embedded)
return result;
}
-
void PageItem_TextFrame::setShadow()
{
@@ -215,10 +212,6 @@
currentShadow = newShadow;
}
}
-
-#ifdef NLS_PROTO
-#include "text/pageitem_textframe.cpp"
-#else
static void dumpIt(const ParagraphStyle& pstyle, QString indent = QString("->"))
{
@@ -238,7 +231,6 @@
dumpIt(*dynamic_cast<const ParagraphStyle*>(pstyle.parentStyle()), more + indent);
}
-
static const bool legacy = true;
/*
@@ -322,6 +314,20 @@
int column;
bool startOfCol;
bool hasDropCap;
+ bool afterOverflow;
+ bool addLine;
+ bool recalculateY;
+ bool lastInRowLine;
+ bool addLeftIndent;
+ bool wasFirstInRow;
+ double leftIndent;
+ double rightMargin;
+ double mustLineEnd;
+ int restartIndex; //index of char where line computing should be restarted
+ int restartRowIndex; //index of char where row of text is started
+ double restartX; //starting X position of line if must be restarted
+ double rowDesc;
+
double ascend;
double descend;
double width;
@@ -353,22 +359,23 @@
}
/// move position to next column
- void nextColumn(double asce)
+ void nextColumn(double asce = 0.0)
{
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)
{
return yPos + morespace + insets.Bottom + lineCorr > frameHeight;
}
-
+
/**
init fields for a new line at current position
*/
@@ -378,15 +385,20 @@
line.x = xPos;
line.y = yPos;
line.firstItem = first;
- line.ascent = 10;
- line.descent = 0;
- line.width = 0;
- line.naturalWidth = 0;
+ line.lastItem = 0;
+ line.ascent = 0.0;
+ line.descent = 0.0;
+ line.width = 0.0;
+ line.naturalWidth = 0.0;
line.colLeft = colLeft;
breakIndex = -1;
- breakXPos = 0;
- maxShrink = 0;
- maxStretch = 0;
+ breakXPos = 0.0;
+ maxShrink = 0.0;
+ maxStretch = 0.0;
+ width = 0.0;
+ leftIndent = 0.0;
+ rightMargin = 0.0;
+ rowDesc = 0.0;
}
@@ -403,12 +415,12 @@
}
/// called when a possible break is passed
- void rememberBreak(int index, double pos)
- {
- if (pos > colRight)
+ void rememberBreak(int index, double pos, double morespace = 0)
+ {
+ if (pos > colRight - morespace)
{
// only look for the first break behind the right edge
- maxShrink = 0;
+ //maxShrink = 0;
// check if we already have a better break
if (breakIndex >= 0)
@@ -419,12 +431,8 @@
if (newLooseness >= oldLooseness)
return;
}
- breakXPos = colRight;
- }
- else
- {
- breakXPos = pos;
- }
+ }
+ breakXPos = pos;
breakIndex = index;
}
@@ -440,9 +448,9 @@
// so that endOfLine() returns correct result
updateHeightMetrics(itemText);
// #9060 : update line offset too
- updateLineOffset(itemText, style, offsetPolicy);
- }
-
+ //updateLineOffset(itemText, style, offsetPolicy);
+ }
+
/// use the last remembered break to set line width and itemrange
void finishLine(double endX)
{
@@ -451,106 +459,64 @@
line.width = endX - line.x;
maxShrink = maxStretch = 0;
}
-
+
+ int restartRow(bool recalcY)
+ {
+ if (recalcY)
+ yPos++;
+ recalculateY = recalcY;
+ xPos = restartX = colLeft;
+ startLine(restartRowIndex);
+ addLeftIndent = true;
+ afterOverflow = false;
+ return restartRowIndex -1;
+ }
+
+ int restartLine(bool recalcY, bool add)
+ {
+ recalculateY = recalcY;
+ addLine = add;
+ xPos = restartX;
+ startLine(restartIndex);
+ afterOverflow = false;
+ return restartIndex -1;
+ }
bool isEndOfLine(double moreSpace = 0)
{
+ bool res;
if (legacy)
- return xPos + insets.Right + lineCorr + moreSpace - maxShrink >= colRight;
+ res = ceil(xPos + lineCorr - maxShrink) + ceil(moreSpace) >= floor(colRight);
else
- return xPos + moreSpace - maxShrink >= colRight;
- }
-
- /// find x position to start current line
- double startOfLine(const QRegion& shape, const QTransform& pf2, double ascent, double descent, double morespace)
- {
- QPoint pt1, pt2;
- double tmpX = xPos;
- pt1 = QPoint(static_cast<int>(ceil(tmpX)), static_cast<int>(yPos + descent));
- pt2 = QPoint(static_cast<int>(ceil(tmpX)), static_cast<int>(ceil(yPos - ascent)));
- // increase pt1/pt2 until i-beam reaches end of line
- while ((!shape.contains(pf2.map(pt1))) || (!shape.contains(pf2.map(pt2))))
- {
- tmpX++;
- if (xPos + (legacy? lineCorr + insets.Right : 0) + lineCorr + morespace >= colRight)
- {
- return tmpX;
- }
- pt1 = QPoint(static_cast<int>(ceil(tmpX)), static_cast<int>(yPos + descent));
- pt2 = QPoint(static_cast<int>(ceil(tmpX)), static_cast<int>(ceil(yPos - ascent)));
- }
- return tmpX;
+ res = ceil(xPos - maxShrink) + ceil(moreSpace) >= floor(colRight);
+ return res;
}
/// find x position where this line must end
- double endOfLine(const QRegion& shape, const QTransform& pf2, double morespace = 0)
- {
- // Keep old code for reference
- /*double EndX = floor(qMax(line.x, qMin(colRight,breakXPos) - 1));
- QPoint pt1, pt2;
- // qDebug() << QString("endx start=%1, hl is '%2'").arg(EndX).arg(hl->ch);
- do {
- EndX += 0.125;
- pt1 = QPoint(qRound(ceil(EndX + insets.Right)), static_cast<int>(yPos+descent));
- pt2 = QPoint(qRound(ceil(EndX + insets.Right)), static_cast<int>(ceil(yPos-ascent)));
- } while ( (EndX + (legacy? lineCorr + insets.Right : 0) < colRight - morespace)
- && shape.contains(pf2.map(pt1))
- && shape.contains(pf2.map(pt2))
- );*/
-
+ double endOfLine(const QRegion& shape, const QTransform& pf2, double morespace, int Yasc, int Ydesc)
+ {
// if we aren't restricted further, we'll end at this maxX:
double maxX = colRight - morespace;
- if (legacy) maxX -= (lineCorr + insets.Right);
-
- double StartX = floor(qMax(line.x, qMin(colRight,breakXPos) - 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));
-
- QPoint pt12 (xPos, yDesc);
- QPoint pt22 (xPos, yAsc);
-
- // simple and fast case: transformed line completely falls within range
- // this will happen if we don't wrap around anything - ie. very often
- QPolygon p;
- p.append (pf2.map (QPoint (StartX, yAsc)));
- p.append (pf2.map (QPoint (StartX, yDesc)));
- p.append (pf2.map (pt12));
- p.append (pf2.map (pt22));
- // check if something gets in the way
- QRegion lineI = shape.intersected (p.boundingRect());
- // 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));
- 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);
- if (steps > 0)
- StartX += steps * 0.125;
- }
- }
-
- // qDebug()<<"endOfLine: going for the hard case";
+ if (legacy) maxX -= lineCorr;
+
+ double StartX = floor(qMax(line.x, qMin(maxX,breakXPos-maxShrink-1))-1);
+ int xPos = static_cast<int>(ceil(maxX));
+
+ QPoint pt12 (xPos, Yasc);
+ QPoint pt22 (xPos, Ydesc);
+ QRect pt(pt12,pt22);
+
double EndX2 = StartX;
- double Interval = 0.125;
+ double Interval = 0.25;
do {
+ int xP = static_cast<int>(ceil(EndX2 + morespace));
+ pt.moveTopLeft(QPoint(xP, Yasc));
+ if (!QRegion(pf2.mapToPolygon(pt)).subtracted(shape).isEmpty())
+ break;
EndX2 += Interval;
- int xPos = qRound(ceil(EndX2 + insets.Right));
- pt12.setX (xPos);
- pt22.setX (xPos);
- } while ((EndX2 < maxX) && shape.contains(pf2.map(pt12)) && shape.contains(pf2.map(pt22)));
-
- /*if (EndX!=EndX2)
- {
- qDebug()<<EndX<<EndX2<<StartX<<maxX;
- qDebug()<<"DIFFERING ENDX!!!!!";
- }*/
- return EndX2;
+ } while ((EndX2 < maxX) && QRegion(pf2.mapToPolygon(pt)).subtracted(shape).isEmpty());
+
+ return qMin(EndX2, maxX);
}
@@ -662,60 +628,65 @@
|| SpecialChars::isBreak (ch, true) || (ch == SpecialChars::NBHYPHEN) || (ch.isSpace()))
continue;
const CharStyle& cStyle(itemText.charStyle(line.firstItem + zc));
+ double scaleV = cStyle.scaleV() / 1000.0;
+ double offset = (cStyle.fontSize() / 10) * (cStyle.baselineOffset() / 1000.0);
+
if (itemText.object(line.firstItem+zc) != 0)
{
- asce = (itemText.object(line.firstItem+zc)->gHeight + itemText.object(line.firstItem+zc)->lineWidth()) * (itemText.charStyle(line.firstItem+zc).scaleV() / 1000.0);
+ asce = (itemText.object(line.firstItem+zc)->gHeight + itemText.object(line.firstItem+zc)->lineWidth()) * scaleV + offset;
desc = 0.0;
}
else //if (itemText.charStyle(current.line.firstItem+zc).effects() & ScStyle_DropCap == 0)
{
- asce = cStyle.font().realCharAscent(ch, cStyle.fontSize() / 10.0);
- desc = cStyle.font().realCharDescent(ch, cStyle.fontSize() / 10.0);
+ asce = cStyle.font().realCharAscent(ch, cStyle.fontSize() / 10.0) * scaleV + offset;
+ desc = cStyle.font().realCharDescent(ch, cStyle.fontSize() / 10.0) * scaleV - offset;
}
// qDebug() << QString("checking char 'x%2' with ascender %1 > %3").arg(asce).arg(ch.unicode()).arg(result);
line.ascent = qMax(line.ascent, asce);
line.descent = qMax(line.descent, desc);
}
}
-
- void updateLineOffset(const StoryText& itemText, const ParagraphStyle& style, FirstLineOffsetPolicy offsetPolicy)
- {
- if (itemsInLine <= 0)
- return;
- if ((!hasDropCap) && (startOfCol) && (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing))
- {
- //FIXME: use glyphs, not chars
- double firstasce = itemText.charStyle(line.firstItem).font().ascent(itemText.charStyle(line.firstItem).fontSize() / 10.0);
- double adj (0.0);
- double currasce (this->getLineAscent(itemText));
- if( offsetPolicy == FLOPRealGlyphHeight )
- {
- adj = firstasce - currasce;
- }
- else if( offsetPolicy == FLOPFontAscent )
- {
- adj = 0.0;
- }
- else if( offsetPolicy == FLOPLineSpacing )
- {
- adj = firstasce - style.lineSpacing();
- }
- line.ascent = currasce;
- line.y -= adj;
- yPos -= adj;
- }
- else if ((!startOfCol) && (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing))
- {
- QChar ch = itemText.text(line.firstItem);
- double firstasce = style.lineSpacing();
- double currasce = getLineHeight(itemText);
- double adj = firstasce - currasce;
+
+// yPos should not be changed when all line is already calculated - at new y position there can be overflow!!!
+//
+// void updateLineOffset(const StoryText& itemText, const ParagraphStyle& style, FirstLineOffsetPolicy offsetPolicy)
+// {
+// if (itemsInLine <= 0)
+// return;
+// if ((!hasDropCap) && (startOfCol) && (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing))
+// {
+// //FIXME: use glyphs, not chars
+// double firstasce = itemText.charStyle(line.firstItem).font().ascent(itemText.charStyle(line.firstItem).fontSize() / 10.0);
+// double adj (0.0);
+// double currasce (this->getLineAscent(itemText));
+// if( offsetPolicy == FLOPRealGlyphHeight )
+// {
+// adj = firstasce - currasce;
+// }
+// else if( offsetPolicy == FLOPFontAscent )
+// {
+// adj = 0.0;
+// }
+// else if( offsetPolicy == FLOPLineSpacing )
+// {
+// adj = firstasce - style.lineSpacing();
+// }
+// line.ascent = currasce;
+// line.y -= adj;
+// yPos -= adj;
+// }
+// else if ((!startOfCol) && (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing))
+// {
+// QChar ch = itemText.text(line.firstItem);
+// double firstasce = style.lineSpacing();
+// double currasce = getLineHeight(itemText);
+// double adj = firstasce - currasce;
// qDebug() << QString("move2 line %1.. down by %2").arg(current.line.firstItem).arg(-adj);
- line.ascent = currasce;
- line.y -= adj;
- yPos -= adj;
- }
- }
+// line.ascent = currasce;
+// line.y -= adj;
+// yPos -= adj;
+// }
+// }
private:
double frameWidth;
@@ -780,8 +751,11 @@
.arg(style.minWordTracking()).arg(style.minGlyphExtension());
*/
+ int startItem = line.firstItem;
+ if (itemText.item(startItem)->effects() & ScStyle_DropCap)
+ startItem++;
// distribute whitespace on spaces and glyphs
- for (int yof = line.firstItem; yof <= line.lastItem; ++yof)
+ for (int yof = startItem; yof <= line.lastItem; ++yof)
{
double wide = itemText.item(yof)->glyph.wide();
if (!SpecialChars::isExpandingSpace(itemText.text(yof)))
@@ -817,45 +791,44 @@
}
}
-/// calculate how much the first char should stick out to the left
-static double opticalLeftMargin(const StoryText& itemText, const LineSpec& line)
-{
- int b = line.firstItem;
- while (b < line.lastItem && (itemText.item(b)->effects() & ScStyle_SuppressSpace))
- ++b;
-
- double chs = itemText.charStyle(b).fontSize() * (itemText.charStyle(b).scaleH() / 1000.0);
- QChar chr = itemText.text(b);
- double leftCorr = itemText.charStyle(b).font().realCharWidth(chr, chs / 10.0);
- if (QString("'´`").indexOf(chr) >= 0
- || chr == QChar(0x2018) // quote 6
- || chr == QChar(0x2019) // quote 9
- || chr == QChar(0x201a) // lower quote 9
- || chr == QChar(0x201b) // upper reversed 9 6
- || chr == QChar(0x2039) // single guillemet <
- || chr == QChar(0x203a) // single guillemet >
- )
- leftCorr *= -0.7;
- else if (QString("\"").indexOf(chr) >= 0
- || chr == QChar(0x00ab) // guillemet <<
- || chr == QChar(0x00bb) // guillemet >>
- || chr == QChar(0x201c) // quote 66
- || chr == QChar(0x201d) // quote 99
- || chr == QChar(0x201e) // lower quote 99
- || chr == QChar(0x201f) // upper reversed 99
- )
- leftCorr *= -0.5;
- else {
- leftCorr = itemText.charStyle(b).font().charWidth(QChar(' '), chs / 10.0, chr);
- leftCorr -= itemText.charStyle(b).font().charWidth(QChar(' '), chs / 10.0);
-// double leftCorr2 = itemText.charStyle(a).font().charWidth(QChar('K'), chs / 10.0, chr);
-// leftCorr2 -= itemText.charStyle(a).font().charWidth(QChar('K'), chs / 10.0);
-// leftCorr = qMin(leftCorr, leftCorr2);
- }
- return leftCorr;
-}
-
-
+//defined but not used
+///// calculate how much the first char should stick out to the left
+//static double opticalLeftMargin(const StoryText& itemText, const LineSpec& line)
+//{
+// int b = line.firstItem;
+// while (b < line.lastItem && (itemText.item(b)->effects() & ScStyle_SuppressSpace))
+// ++b;
+//
+// double chs = itemText.charStyle(b).fontSize() * (itemText.charStyle(b).scaleH() / 1000.0);
+// QChar chr = itemText.text(b);
+// double leftCorr = itemText.charStyle(b).font().realCharWidth(chr, chs / 10.0);
+// if (QString("'´`").indexOf(chr) >= 0
+// || chr == QChar(0x2018) // quote 6
+// || chr == QChar(0x2019) // quote 9
+// || chr == QChar(0x201a) // lower quote 9
+// || chr == QChar(0x201b) // upper reversed 9 6
+// || chr == QChar(0x2039) // single guillemet <
+// || chr == QChar(0x203a) // single guillemet >
+// )
+// leftCorr *= -0.7;
+// else if (QString("\"").indexOf(chr) >= 0
+// || chr == QChar(0x00ab) // guillemet <<
+// || chr == QChar(0x00bb) // guillemet >>
+// || chr == QChar(0x201c) // quote 66
+// || chr == QChar(0x201d) // quote 99
+// || chr == QChar(0x201e) // lower quote 99
+// || chr == QChar(0x201f) // upper reversed 99
+// )
+// leftCorr *= -0.5;
+// else {
+// leftCorr = itemText.charStyle(b).font().charWidth(QChar(' '), chs / 10.0, chr);
+// leftCorr -= itemText.charStyle(b).font().charWidth(QChar(' '), chs / 10.0);
+//// double leftCorr2 = itemText.charStyle(a).font().charWidth(QChar('K'), chs / 10.0, chr);
+//// leftCorr2 -= itemText.charStyle(a).font().charWidth(QChar('K'), chs / 10.0);
+//// leftCorr = qMin(leftCorr, leftCorr2);
+// }
+// return leftCorr;
+//}
/// calculate how much the last char should stick out to the right
static double opticalRightMargin(const StoryText& itemText, const LineSpec& line)
@@ -901,6 +874,15 @@
return 0.0;
}
+static double findRealOverflowEnd(const QRegion& shape, const QTransform& pf2, QRect pt, double maxX)
+{
+ while (!QRegion(pf2.mapToPolygon(pt)).subtracted(shape).isEmpty() && pt.right() < maxX)
+ pt.translate(1, 0);
+ if (pt.right() >= maxX)
+ return maxX;
+ return pt.left() +0.5;
+}
+
static double adjustToBaselineGrid (const LineControl &control, PageItem *item, int OwnPage)
{
double by = item->yPos();
@@ -1049,10 +1031,9 @@
firstChar = 0;
// qDebug() << QString("textframe(%1,%2): len=%3, start relayout at %4").arg(Xpos).arg(Ypos).arg(itemText.length()).arg(firstInFrame());
-// ScribusView* view = m_Doc->view();
QTransform pf2;
QPoint pt1, pt2;
- /*QRegion cm;*/
+ QRect pt;
double chs, chsd = 0;
double oldCurY, EndX, OFs, wide, kernVal;
QString chstr;
@@ -1061,7 +1042,6 @@
int /*ParagraphStyle::OpticalMarginType*/ opticalMargins = ParagraphStyle::OM_None;
bool outs = false;
- bool fBorder = false;
bool goNoRoom = false;
bool goNextColumn = false;
@@ -1075,7 +1055,8 @@
tTabValues.clear();
bool DropCmode = false;
- double desc=0, asce=0, maxDY=0, desc2=0, maxDX=0;
+ double desc=0, asce=0, realAsce=0, realDesc = 0;
+ double maxDY=0, maxDX=0;
double DropCapDrop = 0;
int DropLines = 0;
int DropLinesCount = 0;
@@ -1099,7 +1080,11 @@
current.init(Width, Height, extra, lineCorr);
current.initColumns(columnWidth(), ColGap);
current.hyphenCount = 0;
-
+
+ //hold Y position of last computed line of text (with glyphs descent)
+ //for moving next line if glyphs are higher than that
+ double lastLineY = 0;
+
// dump styles
/*
for (int i=0; i < itemText.nrOfParagraphs(); ++i) {
@@ -1111,7 +1096,6 @@
dumpIt(itemText.defaultStyle());
*/
-// pf2.begin(view->viewport());
pf2.translate(Xpos, Ypos);
pf2.rotate(Rot);
@@ -1137,7 +1121,8 @@
pf2.scale(1, -1);
}
- current.nextColumn(0);
+ current.nextColumn();
+ lastLineY = extra.Top;
// find start of first line
if (firstInFrame() < itemText.length())
@@ -1154,19 +1139,33 @@
}
else
chs = hl->fontSize();
- desc2 = -hl->font().descent(chs / 10.0);
+ desc = -hl->font().descent(chs / 10.0);
current.yPos = extra.Top + lineCorr;
// qDebug() << QString("first line at y=%1").arg(current.yPos);
}
else // empty itemText:
{
- desc2 = -itemText.defaultStyle().charStyle().font().descent(itemText.defaultStyle().charStyle().fontSize() / 10.0);
- current.yPos = itemText.defaultStyle().lineSpacing() + extra.Top+lineCorr-desc2;
+ desc = -itemText.defaultStyle().charStyle().font().descent(itemText.defaultStyle().charStyle().fontSize() / 10.0);
+ current.yPos = itemText.defaultStyle().lineSpacing() + extra.Top + lineCorr - desc;
}
current.startLine(firstInFrame());
+
outs = false;
OFs = 0;
MaxChars = 0;
+ double realEnd = 0;
+ current.restartIndex = current.restartRowIndex = firstInFrame();
+ current.afterOverflow = false;
+ current.addLine = false;
+ current.recalculateY = true;
+ current.lastInRowLine = false;
+ current.addLeftIndent = true;
+ current.wasFirstInRow = false;
+ current.leftIndent = 0;
+ current.rightMargin = 0.0;
+ current.mustLineEnd = current.colRight;
+ current.restartX = 0;
+
for (int a = firstInFrame(); a < itemText.length(); ++a)
{
hl = itemText.item(a);
@@ -1175,20 +1174,13 @@
if (current.itemsInLine == 0)
opticalMargins = style.opticalMargins();
-// qDebug() << QString("style pos %1: %2 (%3)").arg(a).arg(style.alignment()).arg(style.parent());
const CharStyle& charStyle = (hl->ch != SpecialChars::PARSEP? itemText.charStyle(a) : itemText.paragraphStyle(a).charStyle());
- if (!charStyle.parent().isEmpty())
- {
-// qDebug() << QString("charstyle pos %1: %2 (%3 %4 %5 %6 %7 %8 %9)").arg(a).arg(charStyle.parent())
-// .arg((uint)charStyle.parentStyle()).arg(charStyle.font().scName()).arg(charStyle.fontSize())
-// .arg(charStyle.fillColor()).arg(charStyle.strokeColor()).arg(charStyle.parentStyle()->name()).arg((uint)charStyle.parentStyle()->parentStyle());
- }
-// qDebug() << QString("charstyle pos %1: %2 (%3)").arg(a).arg(charStyle.asString()).arg(charStyle.fontSize());
-// qDebug() << QString("style @%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);
-
chstr = ExpandToken(a);
+ double hlcsize10 = charStyle.fontSize() / 10.0;
+ double scaleV = charStyle.scaleV() / 1000.0;
+ double scaleH = charStyle.scaleH() / 1000.0;
+ double offset = hlcsize10 * (charStyle.baselineOffset() / 1000.0);
+
if (chstr.isEmpty())
chstr = SpecialChars::ZWNBSPACE;
style.setLineSpacing (calculateLineSpacing (style, this));
@@ -1197,7 +1189,6 @@
{
if (a == 0 || itemText.text(a-1) == SpecialChars::PARSEP)
{
- current.yPos += style.gapBefore();
if (chstr[0] != SpecialChars::PARSEP)
{
DropCmode = style.hasDropCap();
@@ -1243,21 +1234,34 @@
else
hl->setEffects(hl->effects() & ~ScStyle_SuppressSpace);
}
- // qDebug() << QString("textframe(%1,%2): len=%3, fontsize=%4, ascent=%5").arg(Xpos).arg(Ypos).arg(itemText.length())
-// .arg(charStyle.fontSize()).arg(charStyle.font().ascent());
if (current.itemsInLine == 0)
{
- // more about par gap and dropcaps
- if ((a > firstInFrame() && itemText.text(a-1) == SpecialChars::PARSEP) || (a == 0 && BackBox == 0 && !current.startOfCol)) // after || always evaluates to false? FIXME
- {
-// qDebug() << QString("gap before2: y=%1+%2").arg(current.yPos).arg(style.gapBefore());
- current.yPos += style.gapBefore();
+ if (style.rightMargin() == 0)
+ {
+ //addLine = true;
+ current.rightMargin = 0.0;
+ }
+ else
+ {
+ if (current.lastInRowLine)
+ current.rightMargin = style.rightMargin();
+ else
+ current.rightMargin = 0.0;
+ }
+ current.breakIndex = -1;
+ if (current.startOfCol && !current.afterOverflow && current.recalculateY)
+ current.yPos = qMax(current.yPos,extra.Top);
+ // more about par gap and dropcaps
+ if ((a > firstInFrame() && itemText.text(a-1) == SpecialChars::PARSEP) || (a == 0 && BackBox == 0 && current.startOfCol))
+ {
+ if (!current.afterOverflow && current.recalculateY && !current.startOfCol)
+ current.yPos += style.gapBefore();
DropCapDrop = 0;
if (chstr[0] != SpecialChars::PARSEP)
DropCmode = style.hasDropCap();
else
DropCmode = false;
- if (DropCmode)
+ if (DropCmode && !current.afterOverflow)
{
DropLines = style.dropCapLines();
DropCapDrop = calculateLineSpacing (style, this) * (DropLines - 1);
@@ -1266,12 +1270,9 @@
}
}
}
- // find charsize & y pos
+ // find charsize factors
if (DropCmode)
{
- // dropcap active?
- DropCapDrop = calculateLineSpacing (style, this) * (DropLines - 1);
-
// FIXME : we should ensure that fonts are loaded before calls to layout()
// ScFace::realCharHeight()/Ascent() ensure font is loaded thanks to an indirect call to char2CMap()
// ScFace::ascent() can be called safely afterwards
@@ -1294,7 +1295,7 @@
else
chs = charStyle.fontSize();
}
- // find tracking
+ // set StartOfLine (and find tracking?)
if (current.itemsInLine == 0)
{
itemText.item(a)->setEffects(itemText.item(a)->effects() | ScStyle_StartOfLine);
@@ -1307,7 +1308,7 @@
}
hl->glyph.yadvance = 0;
oldCurY = layoutGlyphs(*hl, chstr, hl->glyph);
- // find out width of char
+ // find out width, ascent and descent of char
if ((hl->ch == SpecialChars::OBJECT) && (hl->embedded.hasItem()))
{
wide = hl->embedded.getItem()->gWidth + hl->embedded.getItem()->lineWidth();
@@ -1334,9 +1335,9 @@
if (itemHeight == 0)
itemHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
wide = hl->embedded.getItem()->gWidth + hl->embedded.getItem()->lineWidth();
- asce = calculateLineSpacing (style, this) * DropLines;
+ realAsce = calculateLineSpacing (style, this) * DropLines;
hl->glyph.scaleH /= hl->glyph.scaleV;
- hl->glyph.scaleV = (asce / itemHeight);
+ hl->glyph.scaleV = (realAsce / itemHeight);
hl->glyph.scaleH *= hl->glyph.scaleV;
}
else
@@ -1344,196 +1345,270 @@
double realCharHeight = charStyle.font().realCharHeight(chstr[0], charStyle.fontSize() / 10.0);
if (realCharHeight == 0)
realCharHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
- wide = charStyle.font().realCharWidth(chstr[0], chsd / 10.0);
- asce = charStyle.font().realCharHeight(chstr[0], chsd / 10.0);
-// qDebug() QString("dropcaps pre: chsd=%1 realCharHeight = %2 chstr=%3").arg(chsd).arg(asce).arg(chstr2[0]);
+ wide = (charStyle.font().realCharWidth(chstr[0], chsd / 10.0) * scaleH) + (1 - scaleH); //dropcaps are to close to next glyphs if glyphs are hard scaled
+ realAsce = charStyle.font().realCharHeight(chstr[0], chsd / 10.0) * scaleV + offset;
+ asce = charStyle.font().ascent(hlcsize10);
+ // qDebug() QString("dropcaps pre: chsd=%1 realCharHeight = %2 chstr=%3").arg(chsd).arg(asce).arg(chstr2[0]);
hl->glyph.scaleH /= hl->glyph.scaleV;
- hl->glyph.scaleV = (asce / realCharHeight);
+ hl->glyph.scaleV = (realAsce / realCharHeight);
hl->glyph.scaleH *= hl->glyph.scaleV;
+ hl->glyph.xoffset -= 0.5; //drop caps are always to far from column left edge
}
hl->glyph.xadvance = wide;
- desc2 = 0;
- desc = 0;
+ desc = realDesc =0;
}
else // !DropCMode
{
-// qDebug( ) << QString("textframe ascent/descent: fontsize=%1, ascent=%2, descent=%3")
-// .arg(charStyle.fontSize()).arg(charStyle.font().ascent()).arg(charStyle.font().descent());
-
if (SpecialChars::isExpandingSpace(hl->ch))
{
double wordtracking = charStyle.wordTracking();
hl->glyph.xadvance *= wordtracking;
wide *= wordtracking;
}
-
// find ascent / descent
- double hlcsize10=charStyle.fontSize() / 10.0;
if ((hl->ch == SpecialChars::OBJECT) && (hl->embedded.hasItem()))
- {
- desc = desc2 = 0;
- }
+ desc = realDesc = 0;
else
{
- desc = desc2 = -charStyle.font().descent(hlcsize10);
+ desc = -charStyle.font().descent(hlcsize10);
+ realDesc = charStyle.font().realCharDescent(chstr[0], hlcsize10) * scaleV - offset;
current.rememberShrinkStretch(hl->ch, wide, style);
}
asce = charStyle.font().ascent(hlcsize10);
-// wide = wide * hl->glyph.scaleH;
- }
- fBorder = false;
- // end of col reached?
-// qDebug() << QString("eocol? %1 + %2 + %3 > %4 -- asce=%5").arg(current.yPos).arg(extra.Bottom).arg(lineCorr).arg(Height).arg(asce);
- if (current.isEndOfCol())
- {
- current.column++;
- if (current.column < Cols)
- {
- // start next col
- current.nextColumn(asce);
- adjustParagraphEndings ();
- a = itemText.lastInFrame() + 1;
- if (((a > firstInFrame()) && (itemText.text(a-1) == SpecialChars::PARSEP))
- || ((a == firstInFrame()) && (BackBox == 0)))
- {
- if (chstr[0] != SpecialChars::PARSEP)
- DropCmode = style.hasDropCap();
+ realAsce = charStyle.font().realCharAscent(chstr[0], hlcsize10) * scaleV + offset;
+ }
+
+ //check for Y position at beginning of line
+ if (current.itemsInLine == 0 && !current.afterOverflow)
+ {
+ if (current.recalculateY)
+ {
+ //if top of column Y position depends on first line offset
+ if (current.startOfCol)
+ {
+ lastLineY = qMax(lastLineY, extra.Top + lineCorr);
+ if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
+ {
+ if (firstLineOffset() == FLOPRealGlyphHeight)
+ {
+ if (DropCmode)
+ current.yPos += asce;
+ else
+ current.yPos += realAsce;
+ }
+ else if (firstLineOffset() == FLOPLineSpacing)
+ current.yPos += style.lineSpacing();
+ else
+ current.yPos += asce;
+ }
+ else if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+ {
+ if (current.yPos <= lastLineY)
+ current.yPos = lastLineY +1;
+ double by;
+ if (OwnPage != -1)
+ by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
+ int ol1 = qRound((by + current.yPos - m_Doc->guidesPrefs().offsetBaselineGrid) * 10000.0);
+ int ol2 = static_cast<int>(ol1 / m_Doc->guidesPrefs().valueBaselineGrid);
+ current.yPos = ceil( ol2 / 10000.0 ) * m_Doc->guidesPrefs().valueBaselineGrid + m_Doc->guidesPrefs().offsetBaselineGrid - by;
+ }
+ }
+ else
+ {
+ if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+ {
+ current.yPos += m_Doc->guidesPrefs().valueBaselineGrid;
+ double by;
+ if (OwnPage != -1)
+ by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
+ int ol1 = qRound((by + current.yPos - m_Doc->guidesPrefs().offsetBaselineGrid) * 10000.0);
+ int ol2 = static_cast<int>(ol1 / m_Doc->guidesPrefs().valueBaselineGrid);
+ current.yPos = ceil( ol2 / 10000.0 ) * m_Doc->guidesPrefs().valueBaselineGrid + m_Doc->guidesPrefs().offsetBaselineGrid - by;
+ }
else
- DropCmode = false;
- if (DropCmode)
+ current.yPos += style.lineSpacing();
+ }
+ if (DropCmode)
+ current.yPos += DropCapDrop;
+ }
+ //set left indentation
+ current.leftIndent = 0.0;
+ if (current.addLeftIndent && (maxDX == 0 || DropCmode))
+ {
+ current.leftIndent = style.leftMargin();
+ if (current.hasDropCap)
+ current.leftIndent = 0;
+ if (a==0 || (a > 0 && (itemText.text(a-1) == SpecialChars::PARSEP)))
+ current.leftIndent += style.firstIndent();
+ current.addLeftIndent = false;
+ }
+ }
+ current.recalculateY = true;
+ int maxYAsc = 0, maxYDesc = 0;
+ if (current.startOfCol)
+ {
+ //qMax is used for glyphs shifted or vertically scalled above ascent or below descent
+ double addAsce = qMax(realAsce, asce);
+ if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
+ {
+ if (firstLineOffset() == FLOPRealGlyphHeight)
+ addAsce = realAsce;
+ else if (firstLineOffset() == FLOPLineSpacing)
+ addAsce = style.lineSpacing();
+ }
+ maxYAsc = static_cast<int>(floor(current.yPos - addAsce));
+ }
+ else
+ maxYAsc = static_cast<int>(floor(current.yPos - qMax(realAsce, asce)));
+ maxYDesc = static_cast<int>(ceil(current.yPos + qMax(realDesc, desc)));
+
+ if (current.itemsInLine == 0 && !current.afterOverflow)
+ {
+ //start a new line
+ goNoRoom = false;
+
+ // find line`s start
+ pt1 = QPoint(static_cast<int>(floor(current.xPos)), maxYAsc);
+ pt2 = QPoint(static_cast<int>(ceil(current.xPos + (style.minGlyphExtension() * wide))),maxYDesc);
+ pt = QRect(pt1, pt2);
+ realEnd = 0;
+ //check if there is overflow at start of line, if so jump behind it and check again
+ double Xpos, Xend;
+ bool done = false;
+ bool newColumn = false;
+ while (!done)
+ {
+ Xpos = current.xPos;
+ Xend = current.xPos + current.leftIndent;
+ //check if in indent any overflow occurs
+ while (Xpos <= Xend && Xpos < current.colRight)
+ {
+ if (!QRegion(pf2.mapToPolygon(pt)).subtracted(cl).isEmpty())
{
- desc2 = -charStyle.font().descent() * calculateLineSpacing (style, this) * style.dropCapLines();
- DropLines = style.dropCapLines();
+ Xpos = current.xPos = realEnd = findRealOverflowEnd(cl, pf2, pt, current.colRight);
+ Xend = current.xPos + current.leftIndent;
}
- }
-// qDebug() << QString("layout: nextcol grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
+ else
+ Xpos++;
+ pt.moveTopLeft(QPoint(static_cast<int>(floor(Xpos)),maxYAsc));
+ }
+ current.xPos = Xend;
+ done = true;
+ if (current.isEndOfLine((style.minGlyphExtension() * wide) + current.rightMargin + current.leftIndent))
+ {
+ // new line
+ current.xPos = qMax(current.colLeft, maxDX);
+ current.yPos ++;
+ if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+ {
+ double by = Ypos;
+ if (OwnPage != -1)
+ by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
+ int ol1 = qRound((by + current.yPos - m_Doc->guidesPrefs().offsetBaselineGrid) * 10000.0);
+ int ol2 = static_cast<int>(ol1 / m_Doc->guidesPrefs().valueBaselineGrid);
+ current.yPos = ceil( ol2 / 10000.0 ) * m_Doc->guidesPrefs().valueBaselineGrid + m_Doc->guidesPrefs().offsetBaselineGrid - by;
+ }
+ lastLineY = maxYAsc +1;
+ if (current.startOfCol)
+ {
+ //qMax is used for glyphs shifted or vertically scalled above ascent or below descent
+ double addAsce = qMax(realAsce, asce);
+ if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
+ {
+ if (firstLineOffset() == FLOPRealGlyphHeight)
+ addAsce = realAsce;
+ else if (firstLineOffset() == FLOPLineSpacing)
+ addAsce = style.lineSpacing();
+ }
+ maxYAsc = static_cast<int>(floor(current.yPos - addAsce));
+ }
+ else
+ maxYAsc = static_cast<int>(floor(current.yPos - qMax(realAsce, asce)));
+ maxYDesc = static_cast<int>(ceil(current.yPos + qMax(realDesc, desc)));
+
+ pt.moveTopLeft(QPoint(static_cast<int>(floor(current.xPos)),maxYAsc));
+ done = false;
+ }
+ if (current.isEndOfCol(realDesc))
+ {
+ current.column++;
+ if (current.column < Cols)
+ {
+ newColumn = true;
+ break;
+ }
+ else
+ {
+ MaxChars = a;
+ goto NoRoom;
+ }
+ }
+ }
+ if (newColumn)
+ {
+ current.nextColumn();
+ current.mustLineEnd = current.colRight;
+ current.restartX = current.xPos;
+ lastLineY = current.yPos;
+ current.rowDesc = 0;
+ a--;
+ current.recalculateY = true;
+ current.addLeftIndent = true;
+ continue;
+ }
+ current.line.x = current.restartX = current.xPos;
+ current.line.y = current.yPos;
+ }
+
+ //check if line must start at new Y position due to current glyph height or previous line descent
+ if (!SpecialChars::isBreak(hl->ch, true)
+ && !SpecialChars::isBreakingSpace(hl->ch)
+ && !SpecialChars::isExpandingSpace(hl->ch)
+ && hl->ch != SpecialChars::TAB)
+ {
+ double diff = 0;
+ if (current.startOfCol || DropCmode)
+ diff = realAsce * scaleV + offset - (current.yPos - lastLineY);
+ else
+ diff = charStyle.font().realCharAscent(QChar('l'), hlcsize10) * scaleV + offset - (current.yPos - lastLineY);
+ if (diff >= 1 || (!DropCmode && diff > 0))
+ {
+ if (current.hasDropCap && DropLinesCount == 0)
+ {
+ current.hasDropCap = false;
+ current.yPos = maxDY;
+ maxDX = 0;
+ }
+ int linesDrop = 0;
if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- current.yPos = adjustToBaselineGrid (current, this, OwnPage);
- }
- else
- {
- MaxChars = a;
-// qDebug() << QString("no room A: %1").arg(a);
- goto NoRoom;
- }
- }
- // ok, there's more room in col
- if (current.itemsInLine == 0)
- {
-// qDebug() << QString("newline: '%1' %2 %3").arg(a).arg(current.yPos).arg(asce);
- // start a new line
- double TopOffset = asce;
- double BotOffset = desc2;
- goNoRoom = false;
- 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;
-// if (((a > 0) && (itemText.at(a-1)->ch == QChar(13))) || ((a == 0) && (BackBox == 0)))
-// current.yPos += m_Doc->docParagraphStyles[hl->cab].gapBefore;
- }
-// qDebug() << QString("layout: nextline grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaselineGrid);
- if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- current.yPos = adjustToBaselineGrid (current, this, OwnPage);
- /* this causes different spacing for first line:
- if (current.yPos-TopOffset < 0.0)
- {
- qDebug(= << QString("current.yPos - Ascender < 0 (%1 - %2 < 0)").arg(current.yPos).arg(TopOffset);
- current.yPos = TopOffset+1;
- }
- */
- // 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)));
- // 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()))
- {
- fBorder = true;
- current.xPos += xStep;
- 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);
- // 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.startOfCol)
- current.yPos++;
- else
- current.yPos += qMax(style.lineSpacing(), 1.0);
-// qDebug() << QString("layout: next lower line grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaselineGrid);
- if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- current.yPos = adjustToBaselineGrid (current, this, OwnPage);
- if (current.isEndOfCol())
+ {
+ linesDrop = ceil(diff/m_Doc->guidesPrefs().valueBaselineGrid);
+ current.yPos += m_Doc->guidesPrefs().valueBaselineGrid * linesDrop;
+ }
+ else /*if (current.startOfCol)*/
+ {
+ //FIX ME - that is ugly hack I must made, because simply expression
+ //current.yPos += diff; stop working, dont know why (compiler bug?)
+ float YPOS = (float) current.yPos + (float) diff + 0.01;
+ current.yPos = (double) YPOS;
+ if (current.hasDropCap && diff > DropCapDrop)
{
- fBorder = false;
- current.column++;
- if (current.column < Cols)
- {
- current.nextColumn(asce);
- adjustParagraphEndings ();
- a = itemText.lastInFrame() + 1;
- if (((a > firstInFrame()) && (itemText.text(a-1) == SpecialChars::PARSEP)) || ((a == firstInFrame()) && (BackBox == 0)))
- {
- if (chstr[0] != SpecialChars::PARSEP)
- DropCmode = style.hasDropCap();
- else
- DropCmode = false;
- if (DropCmode)
- {
- desc2 = -charStyle.font().descent() * calculateLineSpacing (style, this) * style.dropCapLines();
- DropLines = style.dropCapLines();
- }
- }
-// qDebug() << QString("layout: nextcol2 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->guideSettings.valueBaselineGrid);
- if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- current.yPos = adjustToBaselineGrid (current, this, OwnPage);
- }
- else
- {
- MaxChars = a;
-// qDebug() << QString("no room B: %1").arg(a);
- goto NoRoom;
- }
+ current.hasDropCap = false;
}
}
- 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)));
- }
-
- if (((fBorder)) && (!current.hasDropCap))
- current.xPos += extra.Left;
- // 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();
- }
- // add left margin
- if (!current.hasDropCap)
- current.xPos += style.leftMargin();
- if (opticalMargins & ParagraphStyle::OM_LeftHangingPunct) {
- current.xPos += opticalLeftMargin(itemText, current.line);
- }
-// qDebug() << QString("store line: (%1,%2)").arg(current.xPos).arg(current.yPos);
- current.line.x = current.xPos;
- current.line.y = current.yPos;
- fBorder = false;
- }
- else {
-// qDebug() << QString("cont.' line: '%1'").arg(a);
+ if (current.hasDropCap && linesDrop > 0 && DropLinesCount > 1)
+ {
+ DropLinesCount += linesDrop;
+ if (DropLinesCount >= DropLines)
+ {
+ current.hasDropCap = false;
+ maxDX = 0;
+ maxDY = 0;
+ }
+ }
+ a = current.restartRow(false);
+ continue;
+ }
}
// right tab stuff
if (tabs.active)
@@ -1606,7 +1681,6 @@
// remember y pos
if (DropCmode)
hl->glyph.yoffset -= charStyle.font().realCharHeight(chstr[0], chsd / 10.0) - charStyle.font().realCharAscent(chstr[0], chsd / 10.0);
-
// remember x pos
double breakPos = current.xPos;
@@ -1624,69 +1698,222 @@
{
current.xPos = qMax(current.xPos, current.colLeft);
}
+ // remember possible break
+ if ( (SpecialChars::isBreakingSpace(hl->ch) || hl->ch == SpecialChars::TAB))
+ {
+ if ( a == firstInFrame() || !SpecialChars::isBreakingSpace(itemText.text(a-1)) )
+ {
+ current.rememberBreak(a, breakPos, style.rightMargin());
+ }
+ }
+ //check against space before PARSEP
+ /*if (SpecialChars::isBreakingSpace(hl->ch) && (a + 1 < itemText.length()) && (itemText.item(a+1)->ch == SpecialChars::PARSEP))
+ {
+ a++;
+ hl = itemText.item(a);
+ }*/
+
+ // test if end of line reached
+ double overflowWidth = 0.0;
+ double hyphWidth = 0.0;
+ bool inOverflow = false;
+ if (hl->effects() & ScStyle_HyphenationPossible || hl->ch == SpecialChars::SHYPHEN)
+ hyphWidth = charStyle.font().charWidth('-', hlcsize10) * (charStyle.scaleH() / 1000.0);
+ if ((current.isEndOfLine(style.rightMargin() + hyphWidth)) || current.isEndOfCol(realDesc) || SpecialChars::isBreak(hl->ch, Cols > 1) || (current.xPos - current.maxShrink + hyphWidth) >= current.mustLineEnd)
+ {
+ //end of row reached - right column, end of column, break char or line must end
+ if (current.itemsInLine == 0 && !current.afterOverflow && !SpecialChars::isBreak(hl->ch, Cols > 1))
+ {
+ //no glyphs in line, so start new row
+ if (SpecialChars::isBreak(hl->ch, Cols > 1))
+ current.restartRowIndex = a +1;
+ a = current.restartRow(true);
+ inOverflow = false;
+ outs = false;
+ continue;
+ }
+ //there we have some glyphs
+ if ((current.breakIndex < 0) && !SpecialChars::isBreak(hl->ch, Cols > 1))
+ {
+ //force break
+ a--;
+ current.breakLine(itemText, style, firstLineOffset(),a);
+ }
+ if (!current.addLine && !current.lastInRowLine && current.afterOverflow)
+ {
+ //we reach right edge of column
+ //if we are after overflow area we have to go back and try to insert text before it
+ //if we have some text here - insert text WITHOUT right margin
+ //if there is no place for text - insert text WITH right margin and end line
+ current.lastInRowLine = false;
+ if (current.breakIndex <0)
+ current.mustLineEnd = current.line.x -1;
+ else if (current.line.firstItem == current.restartIndex)
+ current.lastInRowLine = true;
+ if (current.hasDropCap && DropLinesCount == 0 && current.restartIndex == current.restartRowIndex)
+ {
+ current.hasDropCap = false;
+ maxDX = 0;
+ current.yPos = maxDY;
+ }
+ a = current.restartLine(false,true);
+ outs = false;
+ inOverflow = false;
+ continue;
+ }
+ outs = true;
+ current.addLine = true;
+ current.lastInRowLine = true;
+ current.rightMargin = style.rightMargin();
+ if (current.isEndOfCol(realDesc))
+ goNextColumn = true;
+ }
+ else
+ {
+ int charStart, charEnd;
+ if (current.itemsInLine == 0)
+ {
+ charStart = static_cast<int>(floor(current.line.x));
+ charEnd = static_cast<int>(ceil(current.xPos));
+ }
+ else
+ {
+ charStart = static_cast<int>(qMax(floor(current.xPos - current.maxShrink - (style.minGlyphExtension() * wide)),0.0));
+ charEnd = static_cast<int>(ceil(current.xPos - current.maxShrink) + hyphWidth);
+ }
+ if (legacy &&
+ (((hl->ch == '-' || (hl->effects() & ScStyle_HyphenationPossible)) && (current.hyphenCount < m_Doc->hyphConsecutiveLines() || m_Doc->hyphConsecutiveLines() == 0))
+ || hl->ch == SpecialChars::SHYPHEN))
+ {
+ if (hl->effects() & ScStyle_HyphenationPossible || hl->ch == SpecialChars::SHYPHEN)
+ {
+ pt1 = QPoint(charStart, maxYAsc);
+ pt2 = QPoint(static_cast<int>(charEnd + hyphWidth), maxYDesc);
+ }
+ else
+ {
+ pt1 = QPoint(charStart, maxYAsc);
+ pt2 = QPoint(charEnd, maxYDesc);
+ }
+ }
+ else if (!legacy && SpecialChars::isBreakingSpace(hl->ch))
+ {
+ pt1 = QPoint(static_cast<int>(qMax(floor(breakPos - current.maxShrink - (style.minGlyphExtension() * wide)),0.0)), maxYAsc);
+ pt2 = QPoint(charEnd, maxYDesc);
+ }
+ else
+ {
+ pt1 = QPoint(charStart, maxYAsc);
+ pt2 = QPoint(charEnd, maxYDesc);
+ }
+ pt = QRect(pt1, pt2);
+ if (!QRegion(pf2.mapToPolygon(pt)).subtracted(cl).isEmpty())
+ {
+ realEnd = findRealOverflowEnd(cl, pf2, pt, current.colRight);
+ outs = true;
+ }
+ else if (style.rightMargin() > 0.0)
+ {
+ if (current.lastInRowLine || current.xPos - current.maxShrink + style.rightMargin() > current.colRight - style.rightMargin())
+ //condition after || is for find overflows in right margin area
+ {
+ pt.translate(static_cast<int>(ceil(style.rightMargin())), 0);
+ if (!QRegion(pf2.mapToPolygon(pt)).subtracted(cl).isEmpty())
+ {
+ realEnd = findRealOverflowEnd(cl, pf2, pt, current.colRight);
+ outs = true;
+ }
+ }
+ }
+ if (outs)
+ {
+ if (current.itemsInLine ==0)
+ {
+ current.line.x = current.xPos = realEnd;
+ a--;
+ current.startLine(a+1);
+ if (!current.wasFirstInRow)
+ current.addLeftIndent = true;
+ if (current.hasDropCap && DropLinesCount == 0 && !current.afterOverflow)
+ {
+ current.hasDropCap = false;
+ current.yPos = maxDY;
+ }
+ current.recalculateY = false;
+ outs = false;
+ continue;
+ }
+ if (current.breakIndex < 0)
+ {
+ a--;
+ current.breakLine(itemText, style, firstLineOffset(), a);
+ }
+ //check if after overflow text can be placed
+ overflowWidth = realEnd - (current.xPos - current.maxShrink);
+ double newXAdd = overflowWidth - style.rightMargin() + style.minGlyphExtension() * wide + hyphWidth;
+ if (current.isEndOfLine(newXAdd) || current.xPos + newXAdd >= current.colRight || realEnd >= current.mustLineEnd)
+ {
+ if (!current.addLine && !current.lastInRowLine)
+ {
+ if (current.afterOverflow)
+ {
+ if (current.breakIndex < 0)
+ {
+ current.lastInRowLine = true;
+ current.mustLineEnd = current.line.x -1;
+ }
+ else if (current.line.firstItem == current.restartIndex)
+ current.lastInRowLine = true;
+ }
+ else
+ current.lastInRowLine = true;
+ if (current.hasDropCap && DropLinesCount == 0)
+ {
+ current.hasDropCap = false;
+ maxDX = 0;
+ }
+ a = current.restartLine(false, true);
+ inOverflow = false;
+ outs = false;
+ continue;
+ }
+ current.addLine = true;
+ current.rightMargin = style.rightMargin();
+ current.lastInRowLine = true;
+ }
+ else
+ inOverflow = true;
+ }
+ }
+
+ // hyphenation
+ if (((hl->effects() & ScStyle_HyphenationPossible) || (hl->ch == '-') || hl->ch == SpecialChars::SHYPHEN) && (!outs) && !itemText.text(a-1).isSpace() )
+ {
+ breakPos = current.xPos;
+ if (hl->ch != '-')
+ {
+ breakPos += hyphWidth;
+ }
+
+ double rightHang = 0;
+ if (opticalMargins & ParagraphStyle::OM_RightHangingPunct) {
+ rightHang = 0.7 * hyphWidth;
+ }
+
+ if (legacy || (breakPos - rightHang < current.colRight - style.rightMargin()))
+ {
+ if ((current.hyphenCount < m_Doc->hyphConsecutiveLines()) || (m_Doc->hyphConsecutiveLines() == 0) || hl->ch == SpecialChars::SHYPHEN)
+ {
+ current.rememberBreak(a, breakPos, style.rightMargin() + hyphWidth);
+ }
+ }
+ }
- //FIXME: asce / desc set correctly?
- double x = current.xPos + extra.Right - current.maxShrink;
- if (legacy &&
- (((hl->ch == '-' || (hl->effects() & ScStyle_HyphenationPossible)) && (current.hyphenCount < m_Doc->hyphConsecutiveLines() || m_Doc->hyphConsecutiveLines() == 0))
- || hl->ch == SpecialChars::SHYPHEN))
- {
- if (hl->effects() & ScStyle_HyphenationPossible || hl->ch == SpecialChars::SHYPHEN)
- x += charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0);
- }
- else if (!legacy && SpecialChars::isBreakingSpace(hl->ch))
- x = breakPos + extra.Right - current.maxShrink;
-
- x = qRound (ceil (x));
- pt1 = QPoint(x, qRound (current.yPos + desc));
- pt2 = QPoint(x, qRound (ceil(current.yPos - asce)));
-
- // test if end of line reached
- if ((!cl.contains(pf2.map(pt1))) || (!cl.contains(pf2.map(pt2))) || (legacy && current.isEndOfLine(style.rightMargin())))
- outs = true;
- if (current.isEndOfCol())
- outs = true;
if ((hl->ch == SpecialChars::FRAMEBREAK) && (a < itemText.length()-1))
goNoRoom = true;
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
- if ( (SpecialChars::isBreakingSpace(hl->ch) || hl->ch == SpecialChars::TAB) /*&& !outs*/)
- {
- if ( a == firstInFrame() || !SpecialChars::isBreakingSpace(itemText.text(a-1)) )
- {
- current.rememberBreak(a, breakPos);
- }
- }
-
-
- // hyphenation
- if (((hl->effects() & ScStyle_HyphenationPossible) || (hl->ch == '-') || hl->ch == SpecialChars::SHYPHEN) && (!outs) && !itemText.text(a-1).isSpace() )
- {
- breakPos = current.xPos;
- if (hl->ch != '-')
- {
- breakPos += charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0);
- }
-
- double rightHang = 0;
- if (opticalMargins & ParagraphStyle::OM_RightHangingPunct) {
- rightHang = 0.7 * charStyle.font().realCharWidth('-', (charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0));
- }
-
- if (legacy || (breakPos - rightHang < current.colRight - style.rightMargin()))
- {
- if ((current.hyphenCount < m_Doc->hyphConsecutiveLines()) || (m_Doc->hyphConsecutiveLines() == 0) || hl->ch == SpecialChars::SHYPHEN)
- {
- current.rememberBreak(a, breakPos);
- }
- }
- }
-
-
++current.itemsInLine;
if (tabs.active)
@@ -1706,7 +1933,7 @@
}
}
- if (DropCmode)
+ if (DropCmode && !outs)
{
DropCmode = false;
DropLinesCount = 0;
@@ -1714,27 +1941,15 @@
current.hasDropCap = true;
current.xPos += style.dropCapOffset();
hl->glyph.xadvance += style.dropCapOffset();
-// 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);
double spacing = calculateLineSpacing (style, this);
current.yPos -= spacing * (DropLines-1);
if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
current.yPos = adjustToBaselineGrid (current, this, OwnPage);
- //FIXME: use current.colLeft instead of xOffset?
- tcli.setPoint(0, QPoint (qRound(hl->glyph.xoffset), qRound(maxDY - DropLines * spacing)));
- tcli.setPoint(1, QPoint (qRound(maxDX), qRound(maxDY - DropLines * spacing)));
- 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;
+ current.recalculateY = false;
}
// end of line
- if ( SpecialChars::isBreak(hl->ch, Cols > 1) || (outs))
+ if (outs)
{
tabs.active = false;
tabs.status = TabNONE;
@@ -1742,9 +1957,23 @@
{
// find end of line
current.breakLine(itemText, style, firstLineOffset(), a);
- EndX = current.endOfLine(cl, pf2, style.rightMargin());
+ EndX = current.endOfLine(cl, pf2, style.rightMargin(), maxYAsc, maxYDesc);
current.finishLine(EndX);
-
+ //addLine = true;
+ assert(current.addLine);
+ //current.startOfCol = false;
+ //addLeftIndent = true;
+ if (hl->ch == SpecialChars::PARSEP)
+ {
+ maxDX = 0;
+ if (current.hasDropCap)
+ {
+ current.yPos = maxDY;
+ maxDY = 0;
+ current.hasDropCap = false;
+ }
+ }
+
// if (style.alignment() != 0)
{
if (opticalMargins & ParagraphStyle::OM_RightHangingPunct)
@@ -1771,7 +2000,7 @@
{
if (opticalMargins & ParagraphStyle::OM_RightHangingPunct)
current.line.naturalWidth += opticalRightMargin(itemText, current.line);
- double optiWidth = current.colRight - style.lineSpacing()/2.0 - current.line.x;
+ double optiWidth = current.colRight - style.rightMargin() - style.lineSpacing()/2.0 - current.line.x;
if (current.line.naturalWidth > optiWidth)
current.line.width = qMax(current.line.width - current.maxShrink, optiWidth);
// simple offset
@@ -1782,47 +2011,46 @@
}
else // outs -- last char went outside the columns (or into flow-around shape)
{
- if (current.breakIndex >= 0) // Hier koenen auch andere Trennungen eingebaut werden
+ if (current.breakIndex >= 0)
+ a = current.breakIndex;
+ assert( a >= 0 );
+ assert( a < itemText.length() );
+ hl = itemText.item(a);
+ current.itemsInLine = a - current.line.firstItem + 1;
+ if (current.addLine)
{
// go back to last break position
-// qDebug() << QString("new break pos a=%1 BuPos=%2 current.breakIndex=%3").arg(a).arg(BuPos).arg(current.breakIndex);
- a = current.breakIndex;
- assert( a >= 0 );
- assert( a < itemText.length() );
- hl = itemText.item(a);
style = itemText.paragraphStyle(a);
- style.setLineSpacing (calculateLineSpacing (style, this));
-
- current.itemsInLine = a - current.line.firstItem + 1;
-// qDebug() << QString("style outs pos %1: %2 (%3)").arg(a).arg(style.alignment()).arg(style.parent());
-// qDebug() << QString("style <@%6: %1 -- %2, %4/%5 char: %3").arg(style.leftMargin()).arg(style.rightMargin())
-// .arg(style.charStyle().asString()).arg(style.name()).arg(style.parent()?style.parent()->name():"")
-// .arg(a);
-
+ if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
+ style.setLineSpacing(charStyle.font().height(hlcsize10));
+ else if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+ style.setLineSpacing(m_Doc->guidesPrefs().valueBaselineGrid);
+
if (hl->ch == ' ') {
hl->setEffects(hl->effects() | ScStyle_SuppressSpace);
hl->glyph.xadvance = 0;
}
current.updateHeightMetrics(itemText);
- current.updateLineOffset(itemText, style, firstLineOffset());
- EndX = current.endOfLine(cl, pf2, style.rightMargin());
+ //current.updateLineOffset(itemText, style, firstLineOffset());
+ //current.xPos = current.breakXPos;
+ EndX = current.endOfLine(cl, pf2, current.rightMargin, maxYAsc, maxYDesc);
current.finishLine(EndX);
-
-//??? current.breakXPos = current.line.x;
-//??? for (int j=current.line.firstItem; j <= a; ++j)
-//??? current.breakXPos += itemText.item(j)->glyph.wide();
+ hyphWidth = 0.0;
if ((hl->effects() & ScStyle_HyphenationPossible) || hl->ch == SpecialChars::SHYPHEN)
{
// insert hyphen
- current.hyphenCount++;
+ if (current.lastInRowLine)
+ //increase hyphen count only for hyphens a the end of text row, omit hyphens before overflow
+ current.hyphenCount++;
hl->setEffects(hl->effects() | ScStyle_SoftHyphenVisible);
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);
+ hl->glyph.more->xadvance = charStyle.font().charWidth('-', itemText.charStyle(a).fontSize() / 10.0) * scaleH; //FIX ME - hyphen is not rendered with proper width - check yhis with large glyphs horizontal scaling eg. 20%
+ hyphWidth = hl->glyph.more->xadvance;
}
- else
+ else
{
if (hl->ch != '-')
current.hyphenCount = 0;
@@ -1831,258 +2059,140 @@
}
// Justification
-// if (style.alignment() != 0)
+ if (opticalMargins & ParagraphStyle::OM_RightHangingPunct)
+ current.line.width += opticalRightMargin(itemText, current.line);
+ else
+ current.line.naturalWidth += hyphWidth;
+
+ OFs = 0;
+ if (style.alignment() == ParagraphStyle::Rightaligned)
+ OFs = current.line.width - current.line.naturalWidth;
+ if (style.alignment() == ParagraphStyle::Centered)
+ OFs = (current.line.width - current.line.naturalWidth) / 2;
+
+ if ((style.alignment() == ParagraphStyle::Justified) || (style.alignment() == ParagraphStyle::Extended))
+ justifyLine(itemText, current.line);
+ else
{
if (opticalMargins & ParagraphStyle::OM_RightHangingPunct)
- current.line.width += opticalRightMargin(itemText, current.line);
-
- OFs = 0;
- if (style.alignment() == ParagraphStyle::Rightaligned)
- OFs = current.line.width - current.line.naturalWidth;
- if (style.alignment() == ParagraphStyle::Centered)
- OFs = (current.line.width - current.line.naturalWidth) / 2;
-
- if ((style.alignment() == ParagraphStyle::Justified)
- || (style.alignment() == ParagraphStyle::Extended))
+ current.line.naturalWidth += opticalRightMargin(itemText, current.line);
+ indentLine(itemText, current.line, OFs);
+ }
+ current.xPos = current.line.x + current.line.width;
+ }
+ }
+ if (inOverflow)
+ current.xPos = realEnd;
+
+ //line break or end of column
+ if (( hl->ch == SpecialChars::PARSEP || hl->ch == SpecialChars::LINEBREAK)
+ && current.hasDropCap)
+ {
+ current.hasDropCap = false;
+ if (current.yPos < maxDY)
+ current.yPos = maxDY;
+ maxDX = 0;
+ }
+ if ( SpecialChars::isBreak(hl->ch) )
+ {
+ if (hl->ch == SpecialChars::PARSEP)
+ current.yPos += style.gapAfter();
+ current.hyphenCount = 0;
+ }
+ if (current.isEndOfCol(desc))
+ {
+ //check if realy line extends bottom margin
+ current.updateHeightMetrics(itemText);
+ if (current.isEndOfCol(current.line.descent))
+ {
+ if (current.itemsInLine == 0 || current.column+1 == Cols)
+ {
+ goNoRoom = true;
+ MaxChars = a + 1;
+ break;
+ }
+ goNextColumn = true;
+ }
+ }
+ if (current.line.firstItem <= current.line.lastItem && current.itemsInLine > 0)
+ {
+ if (current.addLine && current.breakIndex >= 0)
+ {
+ if (itemText.charStyle(current.line.firstItem).effects() & ScStyle_DropCap)
+ {
+ // put line back to top
+ current.line.y -= DropCapDrop;
+ itemText.item(current.line.firstItem)->glyph.yoffset += DropCapDrop;
+ }
+ fillInTabLeaders(itemText, current.line);
+ //if right margin is set we temporally save line, not append it
+ itemText.appendLine(current.line);
+ current.restartIndex = current.line.lastItem +1;
+ a = current.restartIndex -1;
+ current.rowDesc = qMax(current.rowDesc,current.yPos + current.line.descent);
+ if (!current.lastInRowLine)
+ {
+ current.restartX = current.xPos;
+ if (current.addLeftIndent)
{
- justifyLine(itemText, current.line);
- }
- else
- {
- if (opticalMargins & ParagraphStyle::OM_RightHangingPunct)
- current.line.naturalWidth += opticalRightMargin(itemText, current.line);
- indentLine(itemText, current.line, OFs);
- }
-// qDebug() << QString("line: endx=%1 next pos=(%2,%3").arg(EndX).arg(current.line.x + current.line.width).arg(current.yPos);
- current.xPos = current.line.x + current.line.width;
- }
- }
- else // no break position
- {
- if (a >= current.line.firstItem)
- {
- if ((hl->effects() & ScStyle_HyphenationPossible) || hl->ch == SpecialChars::SHYPHEN)
- {
- current.itemsInLine = 0;
- a = current.line.firstItem - 1;
- }
- else
- {
- --a;
- --current.itemsInLine;
+ current.addLeftIndent = false;
+ current.wasFirstInRow = true;
}
}
- if (a >= 0)
- {
- hl = itemText.item(a);
- style = itemText.paragraphStyle(a);
- style.setLineSpacing (calculateLineSpacing (style, this));
- }
- 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)) )
- {
- if (outs && !current.isEndOfLine(hl->glyph.wide() + style.rightMargin()))
- {
- if (( hl->ch == SpecialChars::PARSEP || hl->ch == SpecialChars::LINEBREAK)
- && current.hasDropCap)
+ }
+ else if (!inOverflow && !current.afterOverflow && current.lastInRowLine)
+ {
+ current.yPos++;
+ a = current.restartLine(true, true);
+ inOverflow = false;
+ outs = false;
+ current.mustLineEnd = current.colRight;
+ continue;
+ }
+ }
+ if (current.addLine && current.lastInRowLine)
+ {
+ current.recalculateY = true;
+ current.wasFirstInRow = false;
+ current.addLeftIndent = true;
+ inOverflow = false;
+ outs = false;
+ current.startOfCol = false;
+ current.restartX = current.xPos = qMax(maxDX, current.colLeft);
+ lastLineY = current.rowDesc;
+ if (current.hasDropCap)
+ {
+ ++DropLinesCount;
+ if (DropLinesCount >= DropLines)
{
current.hasDropCap = false;
- if (current.yPos < maxDY)
- current.yPos = maxDY;
-// qDebug() << QString("after dropcaps: y=%1 maxDY=%2").arg(current.yPos).arg(maxDY);
+ current.restartX = current.xPos = current.colLeft;
+ maxDX = 0;
}
- bool fromOut = true;
- double BotOffset = desc+extra.Bottom+lineCorr;
- while (!current.isEndOfLine(style.rightMargin()))
- {
- current.xPos++;
- if (current.isEndOfLine(style.rightMargin()))
- {
- 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());
-
- current.yPos += calculateLineSpacing (style, this);
- 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;
- if (DropLinesCount >= DropLines)
- {
- current.hasDropCap = false;
- current.xPos = current.colLeft;
- }
- else
- current.xPos = maxDX;
- }
- else
- current.xPos = current.colLeft;
- if (SpecialChars::isBreak(hl->ch))
- {
- if (hl->ch == SpecialChars::PARSEP)
- {
-// qDebug() << QString("gap after: y=%1+%2").arg(current.yPos).arg(style.gapAfter());
- current.yPos += style.gapAfter();
- }
- current.hyphenCount = 0;
- }
- break;
- }
- // #7944 : Do not use static_cast<int> here, this is not consistent with computations
- // 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)));
- if (cl.contains(pf2.map(pt1)) && cl.contains(pf2.map(pt2)))
- break;
-// else
-// qDebug() << QString("looking for start of line at %1,%2").arg(current.xPos).arg(current.yPos);
- }
- 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 = qMax(current.xPos, current.colLeft);
- }
- }
- else
- {
- if (( hl->ch == SpecialChars::PARSEP || hl->ch == SpecialChars::LINEBREAK )
- && current.hasDropCap)
- {
- current.hasDropCap = false;
- if (current.yPos < maxDY)
- current.yPos = maxDY;
-// qDebug() << QString("after dropcap2: y=%1+%2").arg(current.yPos).arg(maxDY);
- }
-// qDebug() << QString("layout: next lower3 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-
-// qDebug() << QString("next line (auto): y=%1+%2").arg(current.yPos).arg(style.lineSpacing());
- //#5845 : use next paragraph line spacing for switching to next paragraph instead of current one
- const ParagraphStyle& pStyle = itemText.paragraphStyle(a+1);
- current.yPos += calculateLineSpacing (pStyle, this);
- if (current.hasDropCap)
- {
- ++DropLinesCount;
- if (DropLinesCount >= DropLines)
- {
- current.hasDropCap = false;
- current.xPos = current.colLeft;
- }
- else
- current.xPos = maxDX;
- }
- else
- current.xPos = current.colLeft;
- if ( SpecialChars::isBreak(hl->ch) )
- {
- if (hl->ch == SpecialChars::PARSEP)
- {
-// qDebug() << QString("gap after: y=%1+%2").arg(current.yPos).arg(style.gapAfter());
- current.yPos += style.gapAfter();
- }
- current.hyphenCount = 0;
- }
- }
- }
-
-
- // calc. needed vertical space
- // Letâs try to change into "calc. _wanted_ vertical space" - pm
- if (current.itemsInLine != 0)
- {
- if ( itemText.charStyle(current.line.firstItem).effects() & ScStyle_DropCap)
- {
- // put line back to top
- current.line.y -= DropCapDrop;
- itemText.item(current.line.firstItem)->glyph.yoffset += DropCapDrop;
- }
- }
-
- fillInTabLeaders(itemText, current.line);
-
- current.startOfCol = false;
-/* has no effect except setting wide, asce and desc
- uint loopC = BuPos3;
- if (m_Doc->guidesPrefs().showControls)
- loopC++; // ??? AV
- for (int zc = 0; zc < loopC; ++zc)
- {
- if ( zc >= current.itemsInLine) {
- qDebug("layout: zc too large %d / %d", zc, current.itemsInLine);
- continue;
- }
- if ( startLin + zc >= itemText.length()) {
- qDebug("layout: startLin+zc too large %d+%d / %d", startLin, zc, itemText.length());
- continue;
- }
-// else
-// qDebug("layout: startLin, zc ok. %d, %d, %d", startLin, zc, LiList.count());
- double wide2 = 0;
- double xcoZli = itemText.item(current.line.firstItem + zc)->glyph.xoffset;
-// itemText.item(startLin+zc)->glyph.xoffset = Zli2->xco;
-/// itemText.item(startLin+zc)->glyph.yoffset = Zli2->yco;
- tTabValues = itemText.paragraphStyle(startLin+zc).tabValues();
- desc = - itemText.charStyle(startLin+zc).font().descent(itemText.charStyle(startLin+zc).fontSize() / 10.0);
- asce = itemText.charStyle(startLin+zc).font().ascent(itemText.charStyle(startLin+zc).fontSize() / 10.0);
- bool Sele = itemText.selected(startLin+zc);
- if (((Sele && (Select)) || (((NextBox != 0) || (BackBox != 0)) && Sele)) && (m_Doc->appMode == modeEdit))
- {
- wide = itemText.item(startLin+zc)->glyph.xadvance;
- if ((zc > 0) && (itemText.text(startLin+zc) == SpecialChars::TAB))
- {
- wide2 = itemText.item(startLin+zc-1)->glyph.xadvance;
- xcoZli = itemText.item(startLin+zc-1)->glyph.xoffset + wide2;
- wide = itemText.item(startLin+zc)->glyph.xoffset - xcoZli + itemText.item(startLin+zc)->glyph.xadvance;
- }
- }
- }
- */
-// 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)
- ; //qDebug() << QString("layout: empty line %1 - %2").arg(current.line.firstItem).arg(current.line.lastItem);
- else if (current.itemsInLine > 0)
- {
- itemText.appendLine(current.line);
- if (moveLinesFromPreviousFrame ())
- {
- layout (); // line moving ensures that this won't be an endless loop
- return;
- }
- }
+ }
+ lastLineY = current.rowDesc;
+ current.mustLineEnd = current.colRight;
+ current.restartRowIndex = current.restartIndex;
+ }
+ if (inOverflow)
+ {
+ current.afterOverflow = true;
+ inOverflow = false;
+ current.addLeftIndent = false;
+ current.recalculateY = false;
+ }
+ else
+ {
+ current.afterOverflow = false;
+ }
+ outs = false;
+ current.addLine = false;
+ current.lastInRowLine = false;
current.startLine(a+1);
- outs = false;
if (goNoRoom)
{
goNoRoom = false;
MaxChars = a+1;
-// qDebug() << QString("no room C: %1").arg(a+1);
goto NoRoom;
}
if (goNextColumn)
@@ -2091,15 +2201,39 @@
current.column++;
if (current.column < Cols)
{
- current.nextColumn(asce);
- // manual break - we do NOT call adjustParagraphEndings () here
+ if (firstLineOffset() == FLOPRealGlyphHeight)
+ asce = 0;
+ current.nextColumn();
+ current.mustLineEnd = current.colRight;
+ current.addLeftIndent = true;
+ lastLineY = extra.Top;
+ current.rowDesc = 0;
+ current.recalculateY = true;
}
else
{
MaxChars = a;
-// qDebug() << QString("no room D: %1").arg(a);
goto NoRoom;
}
+ }
+ }
+ if (a == itemText.length() -1)
+ {
+ if (!current.afterOverflow || current.addLine)
+ {
+ current.addLine = true;
+ current.lastInRowLine = true;
+ current.breakLine(itemText, style, firstLineOffset(),a);
+ }
+ if (current.afterOverflow && !current.addLine)
+ {
+ if (current.restartIndex < current.line.firstItem)
+ {
+ a = current.restartLine(false,true);
+ continue;
+ }
+ else
+ current.breakLine(itemText, style, firstLineOffset(),a);
}
}
}
@@ -2109,18 +2243,35 @@
goto NoRoom;
}
// end of itemText
- int a = itemText.length()-1;
- hl = a >=0 ? itemText.item(a) : NULL;
- current.breakLine(itemText, style, firstLineOffset(), a);
- EndX = current.endOfLine(cl, pf2, style.rightMargin());
- current.finishLine(EndX);
-
-// if (style.alignment() != 0)
- {
+ if (current.itemsInLine > 0 )
+ {
+ int a = itemText.length()-1;
+ hl = (a >= 0) ? itemText.item(a) : NULL;
+ current.breakLine(itemText, style, firstLineOffset(), a);
+
+ int maxYAsc = 0, maxYDesc = 0;
+ if (current.startOfCol)
+ {
+ //qMax is used for glyphs shifted or vertically scalled above ascent or below descent
+ double addAsce = qMax(realAsce, asce);
+ if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
+ {
+ if (firstLineOffset() == FLOPRealGlyphHeight)
+ addAsce = realAsce;
+ else if (firstLineOffset() == FLOPLineSpacing)
+ addAsce = style.lineSpacing();
+ }
+ maxYAsc = static_cast<int>(floor(current.yPos - addAsce));
+ }
+ else
+ maxYAsc = static_cast<int>(floor(current.yPos - qMax(realAsce, asce)));
+ maxYDesc = static_cast<int>(ceil(current.yPos + qMax(realDesc, desc)));
+
+ EndX = current.endOfLine(cl, pf2, style.rightMargin(), maxYAsc, maxYDesc);
+ current.finishLine(EndX);
+
if (opticalMargins & ParagraphStyle::OM_RightHangingPunct)
- {
current.line.width += opticalRightMargin(itemText, current.line);
- }
OFs = 0;
if (style.alignment() == ParagraphStyle::Rightaligned)
@@ -2144,26 +2295,19 @@
current.line.naturalWidth += opticalRightMargin(itemText, current.line);
indentLine(itemText, current.line, OFs);
}
- }
-
- if (current.itemsInLine != 0)
- {
if ( itemText.charStyle(current.line.firstItem).effects() & ScStyle_DropCap )
{
// put line back to top
current.line.y -= DropCapDrop;
itemText.item(current.line.firstItem)->glyph.yoffset += DropCapDrop;
}
- }
- fillInTabLeaders(itemText, current.line);
- current.startOfCol = false;
- goNextColumn = false;
-
-// qDebug() << QString("layout: last 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.itemsInLine > 0) {
+ fillInTabLeaders(itemText, current.line);
+ current.startOfCol = false;
+ goNextColumn = false;
+
itemText.appendLine(current.line);
+ current.startOfCol = false;
+
if (moveLinesFromPreviousFrame ()) {
layout (); // line moving ensures that this won't be an endless loop
return;
@@ -3529,8 +3673,6 @@
}
-#endif //NLS_PROTO
-
bool PageItem_TextFrame::createInfoGroup(QFrame *infoGroup, QGridLayout *infoGroupLayout)
{
int Parag = 0;
More information about the scribus-commit
mailing list