View Issue Details

IDProjectCategoryView StatusLast Update
0010251ScribusStory Editor / Text Framespublic2012-02-19 17:21
Reportercezaryece Assigned Tojghali  
PriorityurgentSeveritymajorReproducibilityalways
Status closedResolutionfixed 
Platformall 
Product Version1.4.0svn 
Fixed in Version1.4.0svn 
Summary0010251: [PATCH] wrong text formatting issues
DescriptionWe have few issues with text formatting reported in few reports.
It is very difficult and sensitive task to fix it, so it take about 3 months for me since I start working on it (and submitting patches, but they are not fixing all issues and bring few new issues).
Hope my patch is near perfect - I test a lot working not only with study cases but also with production work (newspaper).
Steps To ReproduceIn attached SLA file you have 6 issuses fixed by this patch (but not only theese 6 are fixed). Openning this file in current Scribus and next in patched you can see theese issues fixed (look at screenshots too).
Hope my patch fixes issues and dont bring any new one.
Additional InformationIt is big patch mainly for PageItem_TextFrame::layout() routine. I was almost rewrote it whole.
TagsNo tags attached.
Patch

Relationships

related to 0009932 closedjghali First text line does not flow around objects 
related to 0009436 closedjghali wrong text formating - text extend margins or columns 
related to 0005891 closedjghali Various settings of work tracking and glyph extension make text overlap in column gap 
related to 0008538 closedjghali Text wrap/flow around image frame fails when glyph extension and word tracking are not 100% 

Activities

cezaryece

2011-09-08 10:20

updater  

formatting.patch (78,458 bytes)   
 
Index: Version135/Scribus/scribus/pageitem_textframe.cpp
===================================================================
--- Version135/Scribus/scribus/pageitem_textframe.cpp	(wersja 16820)
+++ Version135/Scribus/scribus/pageitem_textframe.cpp	(kopia robocza)
@@ -70,7 +70,6 @@
 	unicodeInputCount = 0;
 	unicodeInputString = "";
 	lastUndoAction = NOACTION;
-//	lastAction4Paragraph = false;
 	
 	connect(&itemText,SIGNAL(changed()), this, SLOT(slotInvalidateLayout()));
 }
@@ -83,7 +82,6 @@
 	unicodeInputCount = 0;
 	unicodeInputString = "";
 	lastUndoAction = NOACTION;
-//	lastAction4Paragraph = false;
 
 	connect(&itemText,SIGNAL(changed()), this, SLOT(slotInvalidateLayout()));
 }
@@ -155,9 +153,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 +188,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();
 				}
@@ -202,7 +198,6 @@
 	return result;
 }
 
-
 void PageItem_TextFrame::setShadow()
 {
 	if (OnMasterPage.isEmpty())
@@ -235,10 +230,6 @@
 		currentShadow = newShadow;
 	}
 }
-		
-#ifdef NLS_PROTO
-#include "text/pageitem_textframe.cpp"
-#else
 
 static void dumpIt(const ParagraphStyle& pstyle, QString indent = QString("->"))
 {
@@ -258,7 +249,6 @@
 		dumpIt(*dynamic_cast<const ParagraphStyle*>(pstyle.parentStyle()), more + indent);
 }
 
-
 static const bool legacy = true;
 
 /*
@@ -373,22 +363,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
 	 */
@@ -398,7 +389,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 +399,7 @@
 		breakXPos = 0;
 		maxShrink = 0;
 		maxStretch = 0;
+		width = 0;
 	}
 	
 
@@ -423,12 +416,12 @@
 	}
 
 	/// called when a possible break is passed
-	void rememberBreak(int index, double pos)
+	void rememberBreak(int index, double pos, double morespace = 0)
 	{
-		if (pos > colRight)
+		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)
@@ -439,12 +432,8 @@
 				if (newLooseness >= oldLooseness)
 					return;
 			}
-			breakXPos = colRight;
 		}
-		else
-		{
-			breakXPos = pos;
-		}
+		breakXPos = pos;
 		breakIndex = index;
 	}
 	
@@ -462,7 +451,7 @@
 		// #9060 : update line offset too
 		updateLineOffset(itemText, style, offsetPolicy);
 	}
-	
+
 	/// use the last remembered break to set line width and itemrange
 	void finishLine(double endX)
 	{
@@ -471,109 +460,44 @@
 		line.width = endX - line.x;
 		maxShrink = maxStretch = 0;
 	}
-	
-	
+
 	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;
+			res = ceil(xPos - maxShrink)  + ceil(moreSpace) >= floor(colRight);
+		return res;
 	}
-	
-	/// find x position to start current line
-	double startOfLine(const QRegion& shape, const QMatrix& 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;
-	}
-	
+
 	/// find x position where this line must end
-	double endOfLine(const QRegion& shape, const QMatrix& pf2, double morespace = 0)
+	double endOfLine(const QRegion& shape, const QMatrix& pf2, double morespace, int Yasc, int Ydesc)
 	{
-		// 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))
-			);*/
-
 		// 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));
-		int yDesc = static_cast<int>(yPos+line.descent);
-		int yAsc  = static_cast<int>(ceil(yPos-line.ascent));
+		double StartX = floor(qMax(line.x, qMin(maxX,breakXPos-maxShrink-1))-1);
+		int xPos  = static_cast<int>(ceil(maxX));
 
-		QPoint pt12 (xPos, yDesc);
-		QPoint pt22 (xPos, yAsc);
+		QPoint pt12 (xPos, Yasc);
+		QPoint pt22 (xPos, Ydesc);
+		QRect pt(pt12,pt22);
 
-		// 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";
 		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)));
+		} while ((EndX2 < maxX) && QRegion(pf2.mapToPolygon(pt)).subtracted(shape).isEmpty());
 
-		/*if (EndX!=EndX2) 
-		{
-			qDebug()<<EndX<<EndX2<<StartX<<maxX;
-			qDebug()<<"DIFFERING ENDX!!!!!";
-		}*/
-		return EndX2;
+		return qMin(EndX2, maxX);
 	}
-	
-	
+
 	double getLineAscent(const StoryText& itemText)
 	{
 		double result = 0;
@@ -684,15 +608,18 @@
 				|| (ch == SpecialChars::LINEBREAK) || (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);
@@ -701,7 +628,8 @@
 	}
 	
 	void updateLineOffset(const StoryText& itemText, const ParagraphStyle& style, FirstLineOffsetPolicy offsetPolicy)
-	{
+	{// yPos should not be changed when all line is calculated, at new y position there can be overflow!!!
+		return;
 		if (itemsInLine <= 0)
 			return;
 		if ((!hasDropCap) && (startOfCol) && (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing))
@@ -712,7 +640,8 @@
 			double currasce (this->getLineAscent(itemText));
 			if( offsetPolicy == FLOPRealGlyphHeight )
 			{
-				adj = firstasce - currasce;
+				adj = line.y - insets.Top -currasce;
+				//adj = firstasce - currasce;
 			}
 			else if( offsetPolicy == FLOPFontAscent )
 			{
@@ -802,8 +731,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)))
@@ -877,8 +809,6 @@
 	return leftCorr;
 }
 
-
-
 /// calculate how much the last char should stick out to the right
 static double opticalRightMargin(const StoryText& itemText, const LineSpec& line)
 {
@@ -923,10 +853,15 @@
 	return 0.0;
 }
 
+static double findRealOverflowEnd(const QRegion& shape, const QMatrix& 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;
+}
 
-
-
-
 void PageItem_TextFrame::layout() 
 {
 // 	qDebug()<<"==Layout==" << itemName() ;
@@ -957,10 +892,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();
 	QMatrix pf2;
 	QPoint pt1, pt2;
-	/*QRegion cm;*/
+	QRect pt;
 	double chs, chsd = 0;
 	double oldCurY, EndX, OFs, wide, kernVal;
 	QString chstr;
@@ -969,7 +903,6 @@
 	int /*ParagraphStyle::OpticalMarginType*/ opticalMargins = ParagraphStyle::OM_None;
 	
 	bool outs = false;
-	bool fBorder = false;
 	bool goNoRoom = false;
 	bool goNextColumn = false;
 	
@@ -983,12 +916,12 @@
 	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;
 	
-	
 	itemText.clearLines();
 
 	double lineCorr = 0;
@@ -1006,7 +939,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, currentRowDesc = 0;
+	
 	// dump styles
 /*	
 	for (int i=0; i < itemText.nrOfParagraphs(); ++i) {
@@ -1018,7 +955,6 @@
 	dumpIt(itemText.defaultStyle());
 */	
 	
-//	pf2.begin(view->viewport());
 	pf2.translate(Xpos, Ypos);
 	pf2.rotate(Rot);
 	
@@ -1044,7 +980,8 @@
 			pf2.scale(1, -1);
 		}
 		
-		current.nextColumn(0);
+		current.nextColumn();
+		lastLineY = extra.Top;
 
 		// find start of first line
 		if (firstInFrame() < itemText.length())
@@ -1070,19 +1007,35 @@
 			}
 			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;
+		bool inOverflow = false;
+		bool afterOverflow = false;
+		bool addLine = false;
+		bool recalculateY = true;
+		bool lastInRowLine = false;
+		bool addLeftIndent = true;
+		bool wasFirstInRow = false;
+		double leftIndent = 0;
+		double rightMargin = 0.0;
+		double mustLineEnd = current.colRight;
+		int restartIndex = firstInFrame();  //index of char where line computing should be restarted
+		int restartRowIndex = firstInFrame();  //index of char where row of text is started
+		double restartX = 0; //starting X position of line if must be restarted
+		double realEnd = 0;
+
 		for (int a = firstInFrame(); a < itemText.length(); ++a)
 		{
 			hl = itemText.item(a);
@@ -1091,27 +1044,17 @@
 			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);
 
-			chstr = ExpandToken(a);
-//			qDebug() << QString("expanded token: '%1'").arg(chstr);
 			if (chstr.isEmpty())
 				chstr = SpecialChars::ZWNBSPACE;
 			if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
-			{
-				style.setLineSpacing(style.charStyle().font().height(style.charStyle().fontSize() / 10.0));
-			}
+				style.setLineSpacing(charStyle.font().height(hlcsize10));
 			else if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
 				style.setLineSpacing(m_Doc->typographicSettings.valueBaseGrid);
 			// find out about par gap and dropcap
@@ -1119,7 +1062,6 @@
 			{
 				if (a == 0 || itemText.text(a-1) == SpecialChars::PARSEP)
 				{
-					current.yPos += style.gapBefore();
 					if (chstr[0] != SpecialChars::PARSEP)
 					{
 						DropCmode = style.hasDropCap();
@@ -1165,21 +1107,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
+				if (style.rightMargin() == 0)
 				{
-//					qDebug() << QString("gap before2: y=%1+%2").arg(current.yPos).arg(style.gapBefore());
-					current.yPos += style.gapBefore();
+					addLine = true;
+					rightMargin = 0.0;
+				}
+				else
+				{
+					if (lastInRowLine)
+						rightMargin = style.rightMargin();
+					else
+						rightMargin = 0.0;
+				}
+				current.breakIndex = -1;
+				if (current.startOfCol && !afterOverflow && 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 (!afterOverflow && recalculateY && !current.startOfCol)
+						current.yPos += style.gapBefore();
 					DropCapDrop = 0;
 					if (chstr[0] != SpecialChars::PARSEP)
 						DropCmode = style.hasDropCap();
 					else
 						DropCmode = false;
-					if (DropCmode)
+					if (DropCmode && !afterOverflow)
 					{
 						DropLines = style.dropCapLines();
 						if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
@@ -1189,35 +1144,22 @@
 							if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
 								DropCapDrop = style.lineSpacing() * (DropLines-1);
 							else
-								DropCapDrop = charStyle.font().height(style.charStyle().fontSize() / 10.0) * (DropLines-1);
+								DropCapDrop = charStyle.font().height(hlcsize10) * (DropLines-1);
 						}
-//						qDebug() << QString("dropcapdrop: y=%1+%2").arg(current.yPos).arg(DropCapDrop);
-						current.yPos += DropCapDrop;
 					}
 				}
 			}
-			// find charsize & y pos
+// ######## find charsize factors
 			if (DropCmode)
 			{
-				// dropcap active?
-				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-					DropCapDrop = m_Doc->typographicSettings.valueBaseGrid * (DropLines-1);
-				else
-				{
-					if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
-						DropCapDrop = style.lineSpacing() * (DropLines-1);
-					else
-						DropCapDrop = charStyle.font().height(style.charStyle().fontSize() / 10.0) * (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
 				double realCharHeight = charStyle.font().realCharHeight(chstr[0], 1);
 				double realCharAscent = charStyle.font().realCharAscent(chstr[0], 1);
-				double fontAscent     = charStyle.font().ascent(style.charStyle().fontSize() / 10.0);
+				double fontAscent     = charStyle.font().ascent(hlcsize10);
 				if (realCharHeight == 0.0)
-					realCharHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
+					realCharHeight = charStyle.font().height(hlcsize10);
 				if (realCharAscent == 0.0)
 					realCharAscent = fontAscent;
 				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
@@ -1234,7 +1176,7 @@
 					}
 					else
 					{
-						double currasce = charStyle.font().height(style.charStyle().fontSize() / 10.0);
+						double currasce = charStyle.font().height(hlcsize10);
 						chsd = (10 * ((currasce * (DropLines-1) + fontAscent) / realCharHeight));
 						chs  = (10 * ((currasce * (DropLines-1) + fontAscent) / realCharAscent));
 					}
@@ -1249,7 +1191,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);
@@ -1262,7 +1204,8 @@
 			}
 			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();
@@ -1290,38 +1233,39 @@
 						itemHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
 					wide = hl->embedded.getItem()->gWidth + hl->embedded.getItem()->lineWidth();
 					if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-						asce = m_Doc->typographicSettings.valueBaseGrid * DropLines;
+						realAsce = m_Doc->typographicSettings.valueBaseGrid * DropLines;
 					else
 					{
 						if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
-							asce = style.lineSpacing() * DropLines;
+							realAsce = style.lineSpacing() * DropLines;
 						else
-							asce = charStyle.font().height(style.charStyle().fontSize() / 10.0) * DropLines;
+							realAsce = charStyle.font().height(style.charStyle().fontSize() / 10.0) * DropLines;
 					}
 					hl->glyph.scaleH /= hl->glyph.scaleV;
-					hl->glyph.scaleV = (asce / itemHeight);
+					hl->glyph.scaleV = (realAsce / itemHeight);
 					hl->glyph.scaleH *= hl->glyph.scaleV;
 				}
 				else
 				{
-					double realCharHeight = charStyle.font().realCharHeight(chstr[0], charStyle.fontSize() / 10.0);
+					double realCharHeight = charStyle.font().realCharHeight(chstr[0], hlcsize10);
 					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; //dropcaps are always to close to next glyphs
+					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());				
+				// 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))
 				{
@@ -1329,129 +1273,145 @@
 					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;
+				realAsce = charStyle.font().realCharAscent(chstr[0], hlcsize10) * scaleV + offset;
 			}
-			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())
+
+// ######## check for Y position at beginning of line
+			if (current.itemsInLine == 0 && !afterOverflow)
 			{
-				current.column++;
-				if (current.column < Cols)
+				if (recalculateY)
 				{
-					// start next col
-					current.nextColumn(asce);
-					if (((a > firstInFrame()) && (itemText.text(a-1) == SpecialChars::PARSEP)) 
-						|| ((a == firstInFrame()) && (BackBox == 0)))
+					//if top of column Y position depends on first line offset
+					if (current.startOfCol)
 					{
-						if (chstr[0] != SpecialChars::PARSEP)
-							DropCmode = style.hasDropCap();
-						else
-							DropCmode = false;
-						if (DropCmode)
+						lastLineY = qMax(lastLineY, extra.Top + lineCorr);
+						if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
 						{
-							if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-								desc2 = -charStyle.font().descent() * m_Doc->typographicSettings.valueBaseGrid * style.dropCapLines();
+							if (firstLineOffset() == FLOPRealGlyphHeight)
+							{
+								if (DropCmode)
+									current.yPos += asce;
+								else
+									current.yPos += realAsce;
+							}
+							else if (firstLineOffset() == FLOPLineSpacing)
+								current.yPos += style.lineSpacing();
 							else
-								desc2 = -charStyle.font().descent() * style.lineSpacing() * style.dropCapLines();
+								current.yPos += asce;
 						}
-						if (DropCmode)
-							DropLines = style.dropCapLines();
+						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->typographicSettings.offsetBaseGrid) * 10000.0);
+							int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
+							current.yPos = ceil(  ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by;
+						}
 					}
-//					qDebug() << QString("layout: nextcol grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-					if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+					else
 					{
-						double by = Ypos;
-						if (OwnPage != -1)
-							by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
-						int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
-						int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//						qDebug() << QString("baseline adjust: 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;
+						if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+						{
+							current.yPos += m_Doc->typographicSettings.valueBaseGrid;
+							double by;
+							if (OwnPage != -1)
+								by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
+							int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
+							int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
+							current.yPos = ceil(  ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by;
+						}
+						else
+							current.yPos += style.lineSpacing();
 					}
+					if (DropCmode)
+						current.yPos += DropCapDrop;
 				}
-				else
+				//set left indentation
+				leftIndent = 0.0;
+				if (addLeftIndent && (maxDX == 0 || DropCmode))
 				{
-					MaxChars = a;
-//					qDebug() << QString("no room A: %1").arg(a);
-					goto NoRoom;
+					leftIndent = style.leftMargin();
+					if (current.hasDropCap)
+						leftIndent = 0;
+					if (a==0 || (a > 0 && (itemText.text(a-1) == SpecialChars::PARSEP)))
+						leftIndent += style.firstIndent();
+					addLeftIndent = false;
 				}
 			}
-			// ok, there's more room in col
-			if (current.itemsInLine == 0)
+			recalculateY = true;
+			int maxYAsc = 0, maxYDesc = 0;
+			if (current.startOfCol)
 			{
-//				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)
+				//qMax is used for glyphs shifted or vertically scalled above ascent or below descent
+				double addAsce = qMax(realAsce, asce);
+				if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
 				{
-//					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;
+					if (firstLineOffset() == FLOPRealGlyphHeight)
+						addAsce = realAsce;
+					else if (firstLineOffset() == FLOPLineSpacing)
+						addAsce = style.lineSpacing();
 				}
-//				qDebug() << QString("layout: nextline grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+				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 && !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);
+				//done is for two passes:
+				//1. from left edge (always)
+				//2. from leftIndent if it is set
+
+				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)
 				{
-					double by = Ypos;
-					if (OwnPage != -1)
-						by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
-					int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
-					int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//					qDebug() << QString("useBaselIneGrid: %1 * %2 + %3 - %4").arg(ol2 / 10000.0).arg(m_Doc->typographicSettings.valueBaseGrid).arg(m_Doc->typographicSettings.offsetBaseGrid).arg(by);
-//					qDebug() << QString("baseline adjust: 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;
-				}
-				/* 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()))
+					Xpos = current.xPos;
+					Xend = current.xPos + leftIndent;
+					//check if in indent any overflow occurs
+					while (Xpos <= Xend && Xpos < current.colRight)
 					{
-//						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);
+						if (!QRegion(pf2.mapToPolygon(pt)).subtracted(cl).isEmpty())
+						{
+							Xpos = current.xPos = realEnd = findRealOverflowEnd(cl, pf2, pt, current.colRight);
+							Xend = current.xPos + leftIndent;
+						}
+						else
+							Xpos++;
+						pt.moveTopLeft(QPoint(static_cast<int>(floor(Xpos)),maxYAsc));
+					}
+					current.xPos = Xend;
+					done = true;
+					if (current.isEndOfLine((style.minGlyphExtension() * wide) + rightMargin + leftIndent))
+					{
 						// 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.valueBaseGrid);
+						current.xPos = qMax(current.colLeft, maxDX);
+						current.yPos ++;
 						if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
 						{
 							double by = Ypos;
@@ -1459,83 +1419,113 @@
 								by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
 							int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
 							int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//							qDebug() << QString("baseline adjust: 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;
 						}
-						if (current.isEndOfCol())
+						lastLineY = maxYAsc +1;
+						if (current.startOfCol)
 						{
-							fBorder = false;
-							current.column++;
-							if (current.column < Cols)
+							//qMax is used for glyphs shifted or vertically scalled above ascent or below descent
+							double addAsce = qMax(realAsce, asce);
+							if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
 							{
-								current.nextColumn(asce);
-								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)
-									{
-										if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-											desc2 = -charStyle.font().descent() * m_Doc->typographicSettings.valueBaseGrid * style.dropCapLines();
-										else
-											desc2 = -charStyle.font().descent() * style.lineSpacing() * style.dropCapLines();
-									}
-									if (DropCmode)
-										DropLines = style.dropCapLines();
-								}
-//								qDebug() << QString("layout: nextcol2 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-								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->typographicSettings.offsetBaseGrid) * 10000.0);
-									int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//									qDebug() << QString("baseline adjust: 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;
-								}
+								if (firstLineOffset() == FLOPRealGlyphHeight)
+									addAsce = realAsce;
+								else if (firstLineOffset() == FLOPLineSpacing)
+									addAsce = style.lineSpacing();
 							}
-							else
-							{
-								MaxChars = a;
-//								qDebug() << QString("no room B: %1").arg(a);
-								goto NoRoom;
-							}
+							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;
 					}
-					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 (current.isEndOfCol(realDesc))
+					{
+						current.column++;
+						if (current.column < Cols)
+						{
+							newColumn = true;
+							break;
+						}
+						else
+						{
+							MaxChars = a;
+							goto NoRoom;
+						}
+					}
 				}
-
-				if (((fBorder)) && (!current.hasDropCap))
-					current.xPos += extra.Left;
-				// indent first line of par
-				if (a > 0)
+				if (newColumn)
 				{
-					if (itemText.text(a-1) == SpecialChars::PARSEP)
-						current.xPos += style.firstIndent();
+					current.nextColumn();
+					mustLineEnd = current.colRight;
+					restartX = current.xPos;
+					lastLineY = current.yPos;
+					currentRowDesc = 0;
+					a--;
+					recalculateY = true;
+					addLeftIndent = true;
+					continue;
 				}
+				current.line.x = 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 (legacy)
-						current.xPos += style.firstIndent();
+					if (current.hasDropCap && DropLinesCount == 0)
+					{
+						current.hasDropCap = false;
+						current.yPos = maxDY;
+						maxDX = 0;
+					}
+					int linesDrop = 0;
+					if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+					{
+						linesDrop = ceil(diff/m_Doc->typographicSettings.valueBaseGrid);
+						current.yPos += m_Doc->typographicSettings.valueBaseGrid * linesDrop;
+					}
+					else /*if (current.startOfCol)*/
+					{
+						float YPOS = (float) current.yPos + (float) diff + 0.01;
+						current.yPos = (double) YPOS;
+						if (current.hasDropCap && diff > DropCapDrop)
+						{
+							current.hasDropCap = false;
+						}
+					}
+					if (current.hasDropCap && linesDrop > 0 && DropLinesCount > 1)
+					{
+						DropLinesCount += linesDrop;
+						if (DropLinesCount >= DropLines)
+						{
+							current.hasDropCap = false;
+							maxDX = 0;
+							maxDY = 0;
+						}
+					}
+					recalculateY = false;
+					current.xPos = current.colLeft;
+					a = restartRowIndex -1;
+					current.startLine(a+1);
+					addLeftIndent = true;
+					afterOverflow = false;
+					continue;
 				}
-				// 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);
-			}
 			// right tab stuff
 			if (tabs.active)
 			{
@@ -1589,7 +1579,6 @@
 							current.xPos = current.colLeft + tCurX;
 						
 						// remember fill char
-//						qDebug() << QString("tab: %1 '%2'").arg(tCurX).arg(tabs.fillChar);
 						if (!tabs.fillChar.isNull()) {
 							hl->glyph.growWithTabLayout();
 							TabLayout * tglyph = dynamic_cast<TabLayout*>(hl->glyph.more);
@@ -1614,7 +1603,6 @@
 			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;
 			
@@ -1630,57 +1618,181 @@
 			else // other tabs.active			
 			{
 				current.xPos = qMax(current.xPos, current.colLeft);
-			}		
-			
-			//FIXME: asce / desc set correctly?
-			if (legacy && 
-				(((hl->ch == '-' || (hl->effects() & ScStyle_HyphenationPossible)) && (current.hyphenCount < m_Doc->HyCount || m_Doc->HyCount == 0))  
-				|| hl->ch == SpecialChars::SHYPHEN))
+			}
+			// remember possible break
+			if ( (SpecialChars::isBreakingSpace(hl->ch) || hl->ch == SpecialChars::TAB))
 			{
-				if (hl->effects() & ScStyle_HyphenationPossible || hl->ch == SpecialChars::SHYPHEN)
+				if ( a == firstInFrame() || !SpecialChars::isBreakingSpace(itemText.text(a-1)) )
 				{
-					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)));
+					current.rememberBreak(a, breakPos, style.rightMargin());
 				}
-				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)));
-				}
 			}
-			else if (!legacy && SpecialChars::isBreakingSpace(hl->ch))
+			//check against space before PARSEP
+			if (SpecialChars::isBreakingSpace(hl->ch) && (a + 1 < itemText.length()) && (itemText.item(a+1)->ch == SpecialChars::PARSEP))
 			{
-				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)));
+				a++;
+				hl = itemText.item(a);
 			}
-			else
+
+			// test if end of line reached
+			double overflowWidth = 0.0;
+			double hyphWidth = 0.0;
+			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 >= mustLineEnd)
 			{
-				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)));
+				if (!addLine && style.rightMargin() > 0.0 && !lastInRowLine && 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
+					lastInRowLine = false;
+					if (current.breakIndex <=0)
+						mustLineEnd = current.line.x -1;
+					else if (current.line.firstItem == restartIndex)
+						lastInRowLine = true;
+					if (current.hasDropCap && DropLinesCount == 0 && restartIndex == restartRowIndex)
+					{
+						current.hasDropCap = false;
+						maxDX = 0;
+						current.yPos = maxDY;
+					}
+					current.xPos = restartX;
+					a = restartIndex -1;
+					current.startLine(a+1);
+					inOverflow = false;
+					afterOverflow = false;
+					outs = false;
+					recalculateY = false;
+					addLine = true;
+					continue;
+				}
+				outs = true;
+				addLine = true;
+				lastInRowLine = true;
+				rightMargin = style.rightMargin();
+				if (current.isEndOfCol(realDesc))
+					goNextColumn = true;
 			}
-			
-			// 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*/)
+			else
 			{
-				if ( a == firstInFrame() || !SpecialChars::isBreakingSpace(itemText.text(a-1)) )
+				int charStart, charEnd;
+				if (current.itemsInLine == 0)
 				{
-					current.rememberBreak(a, breakPos);
+					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->HyCount || m_Doc->HyCount == 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 (charEnd > 220)
+					qDebug();
+				if (!QRegion(pf2.mapToPolygon(pt)).subtracted(cl).isEmpty())
+				{
+					realEnd = findRealOverflowEnd(cl, pf2, pt, current.colRight);
+					if (current.breakIndex <=0)
+					{
+						current.line.x = current.xPos = restartX = realEnd;
+						current.itemsInLine = 0;
+						a = restartIndex -1;
+						if (!wasFirstInRow)
+							addLeftIndent = true;
+						if (current.hasDropCap && DropLinesCount == 0 && !afterOverflow)
+						{
+							current.hasDropCap = false;
+							current.yPos = maxDY;
+						}
+						recalculateY = false;
+						continue;
+					}
+					outs = true;
+				}
+				else if (style.rightMargin() > 0.0)
+				{
+					if (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())
+						{
+							outs = true;
+							realEnd = findRealOverflowEnd(cl, pf2, pt, current.colRight);
+						}
+					}
+				}
+				if (outs)
+				{
+					//check if after overflow text can be placed
+					overflowWidth = realEnd - (current.xPos - current.maxShrink);
+					if (current.isEndOfLine(overflowWidth + style.rightMargin() + style.minGlyphExtension() * wide + hyphWidth) || realEnd >= mustLineEnd)
+					{
+						if (!addLine && style.rightMargin() > 0.0 && !lastInRowLine)
+						{
+							if (afterOverflow)
+							{
+								lastInRowLine = false;
+								if (current.breakIndex <=0)
+								{
+									lastInRowLine = true;
+									mustLineEnd = current.line.x -1;
+								}
+								else if (current.line.firstItem == restartIndex)
+									lastInRowLine = true;
+							}
+							else
+								lastInRowLine = true;
+							if (current.hasDropCap && DropLinesCount == 0)
+							{
+								current.hasDropCap = false;
+								maxDX = 0;
+							}
+							current.xPos = restartX;
+							a = restartIndex -1;
+							current.startLine(a+1);
+							inOverflow = false;
+							afterOverflow = false;
+							outs = false;
+							recalculateY = false;
+							addLine = true;
+							continue;
+						}
+						addLine = true;
+						rightMargin = style.rightMargin();
+						lastInRowLine = true;
+					}
+					else
+						inOverflow = true;
+				}
 			}
-			
 
 			// hyphenation
 			if (((hl->effects() & ScStyle_HyphenationPossible) || (hl->ch == '-') || hl->ch == SpecialChars::SHYPHEN) && (!outs) && !itemText.text(a-1).isSpace() )
@@ -1688,24 +1800,28 @@
 				breakPos = current.xPos;
 				if (hl->ch != '-')
 				{
-					breakPos += charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0);
+					breakPos += hyphWidth;
 				}
 				
 				double rightHang = 0;
 				if (opticalMargins & ParagraphStyle::OM_RightHangingPunct) {
-					rightHang = 0.7 * charStyle.font().realCharWidth('-', (charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0));
+					rightHang = 0.7 * hyphWidth;
 				}
 				
 				if (legacy || (breakPos - rightHang < current.colRight - style.rightMargin()))
 				{
 					if ((current.hyphenCount < m_Doc->HyCount) || (m_Doc->HyCount == 0) || hl->ch == SpecialChars::SHYPHEN)
 					{
-						current.rememberBreak(a, breakPos);
+						current.rememberBreak(a, breakPos, style.rightMargin() + hyphWidth);
 					}
 				}
 			}
-			
-						
+
+			if ((hl->ch == SpecialChars::FRAMEBREAK) && (a < itemText.length()-1))
+				goNoRoom = true;
+			if ((hl->ch == SpecialChars::COLBREAK) && (Cols > 1))
+				goNextColumn = true;
+
 			++current.itemsInLine;
 			
 			if (tabs.active)
@@ -1725,7 +1841,7 @@
 				}
 			}
 			
-			if (DropCmode)
+			if (DropCmode && !outs)
 			{
 				DropCmode = false;
 				DropLinesCount = 0;
@@ -1733,10 +1849,7 @@
 				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);
 				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
 				{
 					current.yPos -= m_Doc->typographicSettings.valueBaseGrid * (DropLines-1);
@@ -1745,40 +1858,24 @@
 						by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
 					int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
 					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
 				{
 					if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
 					{
 						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);
+						double currasce = charStyle.font().height(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;
+				recalculateY = false;
 			}
 			// end of line
-			if ( SpecialChars::isBreak(hl->ch, Cols > 1) || (outs))
+			if (outs)
 			{
 				tabs.active = false;
 				tabs.status = TabNONE;
@@ -1786,9 +1883,22 @@
 				{
 					// 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;
+					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)
@@ -1815,7 +1925,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
@@ -1826,64 +1936,73 @@
 				}
 				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)            // Hier koenen auch andere Trennungen eingebaut werden
 					{
-						// 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);
-						if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
+						current.itemsInLine = a - current.line.firstItem + 1;
+						if (addLine)
 						{
-							style.setLineSpacing(style.charStyle().font().height(style.charStyle().fontSize() / 10.0));
-//							qDebug() << QString("auto linespacing: %1").arg(style.lineSpacing());
-						}
-						else if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-							style.setLineSpacing(m_Doc->typographicSettings.valueBaseGrid);
-						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);
+							// go back to last break position
+							style = itemText.paragraphStyle(a);
+							chstr = ExpandToken(a+1);
+							{
+								const CharStyle curCharStyle =  (hl->ch != SpecialChars::PARSEP? itemText.charStyle(a+1) : itemText.paragraphStyle(a+1).charStyle());
+								hlcsize10 = curCharStyle.fontSize() / 10.0;
+								scaleV = curCharStyle.scaleV()/1000.0;
+								offset = hlcsize10 * (curCharStyle.baselineOffset() /1000.0);
+								realAsce = curCharStyle.font().realCharAscent(chstr[0], hlcsize10) * scaleV + offset;
+								if (current.startOfCol)
+									maxYAsc = static_cast<int>(floor(current.yPos - realAsce));
+								else
+									maxYAsc = static_cast<int>(floor(current.yPos - qMax(realAsce, asce)));
+								realDesc = curCharStyle.font().realCharDescent(chstr[0], hlcsize10) * scaleV - offset;
+								maxYDesc = static_cast<int>(ceil(current.yPos + qMax(realDesc, desc)));
+							}
+							if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
+								style.setLineSpacing(charStyle.font().height(hlcsize10));
+							else if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+								style.setLineSpacing(m_Doc->typographicSettings.valueBaseGrid);
 
-						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.finishLine(EndX);
+							if (hl->ch == ' ') {
+								hl->setEffects(hl->effects() | ScStyle_SuppressSpace);
+								hl->glyph.xadvance = 0;
+							}
 
-//???						current.breakXPos = current.line.x;
-//???						for (int j=current.line.firstItem; j <= a; ++j)
-//???							current.breakXPos += itemText.item(j)->glyph.wide();
-						
-						if ((hl->effects() & ScStyle_HyphenationPossible) || hl->ch == SpecialChars::SHYPHEN)
-						{
-							// insert hyphen
-							current.hyphenCount++;
-							hl->setEffects(hl->effects() | ScStyle_SmartHyphenVisible);
-							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);
-						}
-						else 
-						{
-							if (hl->ch != '-')
-								current.hyphenCount = 0;
-							hl->setEffects(hl->effects() & ~ScStyle_SmartHyphenVisible);
-							hl->glyph.shrink();
-						}
-						
-						// Justification
-//						if (style.alignment() != 0)
-						{
+							current.updateHeightMetrics(itemText);
+							current.updateLineOffset(itemText, style, firstLineOffset());
+							//current.xPos = current.breakXPos;
+							EndX = current.endOfLine(cl, pf2, rightMargin, maxYAsc, maxYDesc);
+							current.finishLine(EndX);
+							
+							hyphWidth = 0.0;
+							if ((hl->effects() & ScStyle_HyphenationPossible) || hl->ch == SpecialChars::SHYPHEN)
+							{
+								// insert hyphen
+								if (lastInRowLine)
+									//increase hyphen count only for hyphens a the end of text row, omit hyphens before overflow
+									current.hyphenCount++;
+								hl->setEffects(hl->effects() | ScStyle_SmartHyphenVisible);
+								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
+							{
+								if (hl->ch != '-')
+									current.hyphenCount = 0;
+								hl->setEffects(hl->effects() & ~ScStyle_SmartHyphenVisible);
+								hl->glyph.shrink();
+							}
+
+							// Justification
 							if (opticalMargins & ParagraphStyle::OM_RightHangingPunct)
 								current.line.width += opticalRightMargin(itemText, current.line);
+							else
+								current.line.naturalWidth += hyphWidth;
 
 							OFs = 0;
 							if (style.alignment() == ParagraphStyle::Rightaligned)
@@ -1891,229 +2010,143 @@
 							if (style.alignment() == ParagraphStyle::Centered)
 								OFs = (current.line.width - current.line.naturalWidth) / 2;
 							
-							if ((style.alignment() == ParagraphStyle::Justified) 
-								|| (style.alignment() == ParagraphStyle::Extended))
-							{
+							if ((style.alignment() == ParagraphStyle::Justified) || (style.alignment() == ParagraphStyle::Extended))
 								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
+//					else  // no break position
+//					{
+//						if (a >= current.line.firstItem)
+//						{
+//							current.itemsInLine = 0;
+//							a = current.line.firstItem - 1;
+//						}
+//						if (a >= 0)
+//						{
+//							hl = itemText.item(a);
+//							style = itemText.paragraphStyle(a);
+//							if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
+//								style.setLineSpacing(charStyle.font().height(charStyle.fontSize() / 10.0));
+//							else if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+//								style.setLineSpacing(m_Doc->typographicSettings.valueBaseGrid);
+//						}
+//					}
+				}
+				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 (a >= current.line.firstItem)
+						if (current.itemsInLine == 0 || current.column+1 == Cols)
 						{
-							if ((hl->effects() & ScStyle_HyphenationPossible) || hl->ch == SpecialChars::SHYPHEN)
-							{
-								current.itemsInLine = 0;
-								a = current.line.firstItem - 1;
-							}
-							else
-							{
-								--a;
-								--current.itemsInLine;
-							}
+							goNoRoom = true;
+							MaxChars = a + 1;
+							break;
 						}
-						if (a >= 0)
-						{
-							hl = itemText.item(a);
-							style = itemText.paragraphStyle(a);
-							if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
-							{
-								style.setLineSpacing(style.charStyle().font().height(style.charStyle().fontSize() / 10.0));
-//								qDebug() << QString("auto linespacing: %1").arg(style.lineSpacing());
-							}
-							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);
+						goNextColumn = true;
 					}
 				}
-				if ( outs || SpecialChars::isBreak(hl->ch, (Cols > 1)) )
+				if (current.line.firstItem <= current.line.lastItem && current.itemsInLine > 0)
 				{
-					if (outs && !current.isEndOfLine(hl->glyph.wide() + style.rightMargin()))
+					if (addLine)
 					{
-						if (( hl->ch == SpecialChars::PARSEP || hl->ch == SpecialChars::LINEBREAK) 
-							&& current.hasDropCap)
+						if (itemText.charStyle(current.line.firstItem).effects() & ScStyle_DropCap)
 						{
-							current.hasDropCap = false;
-							if (current.yPos < maxDY)
-								current.yPos = maxDY;
-//							qDebug() << QString("after dropcaps: y=%1 maxDY=%2").arg(current.yPos).arg(maxDY);
+							// put line back to top
+							current.line.y -= DropCapDrop;
+							itemText.item(current.line.firstItem)->glyph.yoffset += DropCapDrop;
 						}
-						bool fromOut = true;
-						double BotOffset = desc+extra.Bottom+lineCorr;
-						while (!current.isEndOfLine(style.rightMargin()))
+						fillInTabLeaders(itemText, current.line);
+						//if right margin is set we temporally save line, not append it
+						itemText.appendLine(current.line);
+						restartIndex = current.line.lastItem +1;
+						a = restartIndex -1;
+						currentRowDesc = qMax(currentRowDesc,current.yPos + current.line.descent);
+						if (!lastInRowLine)
 						{
-							current.xPos++;
-							if (current.isEndOfLine(style.rightMargin()))
+							restartX = current.xPos;
+							if (addLeftIndent)
 							{
-								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());
-
-								if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-									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;
-									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;
+								addLeftIndent = false;
+								wasFirstInRow = true;
 							}
-							// #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
+//					else if (!addRightMargin)
+//					{
+//						current.xPos = restartX = realEnd +1;
+//						restartIndex = a +1;
+//					}
+				}
+				if (addLine && lastInRowLine)
+				{
+					recalculateY = true;
+					wasFirstInRow = false;
+					addLeftIndent = true;
+					inOverflow = false;
+					outs = false;
+					current.startOfCol = false;
+					restartX = current.xPos = qMax(maxDX, current.colLeft);
+					lastLineY = currentRowDesc;
+					if (current.hasDropCap)
 					{
-						if (( hl->ch == SpecialChars::PARSEP || hl->ch == SpecialChars::LINEBREAK ) 
-							&& current.hasDropCap)
+						++DropLinesCount;
+						if (DropLinesCount >= DropLines)
 						{
 							current.hasDropCap = false;
-							if (current.yPos < maxDY)
-								current.yPos = maxDY;
-//							qDebug() << QString("after dropcap2: y=%1+%2").arg(current.yPos).arg(maxDY);
+							restartX = current.xPos = current.colLeft;
+							maxDX = 0;
 						}
-//						qDebug() << QString("layout: next lower3 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-
-
-						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
-						{
-//							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
-							//current.yPos += style.lineSpacing();
-							const  ParagraphStyle& pStyle = itemText.paragraphStyle(a+1);
-							double lineSpacing = pStyle.lineSpacing();
-							if (pStyle.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
-								lineSpacing = pStyle.charStyle().font().height(pStyle.charStyle().fontSize() / 10.0);
-							else if (pStyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-								lineSpacing = m_Doc->typographicSettings.valueBaseGrid;
-							current.yPos += lineSpacing;
-						}
-						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;
-						}
 					}
+					lastLineY = currentRowDesc;
+					mustLineEnd = current.colRight;
+					restartRowIndex = restartIndex;
 				}
-				
-
-				// calc. needed vertical space
-				// Let’s try to change into "calc. _wanted_ vertical space" - pm
-				if (current.itemsInLine != 0)
+				if (inOverflow)
 				{
-					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;
-					}
+					afterOverflow = true;
+					inOverflow = false;
+					addLeftIndent = false;
+					recalculateY = false;
 				}
-				
-				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)
-					; //qDebug() << QString("layout: empty line %1 - %2").arg(current.line.firstItem).arg(current.line.lastItem);
-				else if (current.itemsInLine > 0)
-					itemText.appendLine(current.line);
+				else
+				{
+					afterOverflow = false;
+				}
+				outs = false;
+				addLine = false;
+				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)
@@ -2122,12 +2155,18 @@
 					current.column++;
 					if (current.column < Cols)
 					{
-						current.nextColumn(asce);
+						if (firstLineOffset() == FLOPRealGlyphHeight)
+							asce = 0;
+						current.nextColumn();
+						mustLineEnd = current.colRight;
+						addLeftIndent = true;
+						lastLineY = extra.Top;
+						currentRowDesc = 0;
+						recalculateY = true;
 					}
 					else
 					{
 						MaxChars = a;
-//						qDebug() << QString("no room D: %1").arg(a);
 						goto NoRoom;
 					}
 				}
@@ -2139,18 +2178,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 (current.itemsInLine >0)
+		{
+			int a = itemText.length()-1;
+			hl = a >=0 ? itemText.item(a) : NULL;
+			current.breakLine(itemText, style, firstLineOffset(), a);
 
-//		if (style.alignment() != 0)
-		{
+			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)
@@ -2174,26 +2230,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;
+			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) {
+			assert(current.line.firstItem <0);
 			itemText.appendLine(current.line);
+			current.startOfCol = false;
 		}
 	}
 	MaxChars = itemText.length();
@@ -3310,7 +3359,6 @@
 
 void PageItem_TextFrame::setNewPos(int oldPos, int len, int dir)
 {
-	
 	bool isSpace, wasSpace;
 	if ( dir > 0 && oldPos < len )
 	{
@@ -3563,8 +3611,6 @@
 	
 }
 
-#endif  //NLS_PROTO
-
 bool PageItem_TextFrame::createInfoGroup(QFrame *infoGroup, QGridLayout *infoGroupLayout)
 {
 	int Parag = 0;
formatting.patch (78,458 bytes)   

cezaryece

2011-09-08 10:20

updater  

formatting patch.sla (47,916 bytes)

cezaryece

2011-09-08 10:21

updater  

formating_wrong.jpg (177,723 bytes)   
formating_wrong.jpg (177,723 bytes)   

cezaryece

2011-09-08 10:21

updater  

formating_good.jpg (180,134 bytes)   
formating_good.jpg (180,134 bytes)   

jghali

2011-09-10 21:49

administrator   ~0026848

Seems to work well enough, however crash directly when trying to type in an empty text frame :

Scribus.exe!PageItem_TextFrame::layout() Line 2243
Scribus.exe!DocUpdater::changed(PageItem * it=0x06ed3628, bool layout=true) Line 148 + 0x12 bytes
Scribus.exe!MassObservable<PageItem *>::updateNow(UpdateMemento * what=0x06e81b18) Line 270 + 0x1d bytes
Scribus.exe!MassObservable<PageItem *>::updateLayout(PageItem * what=0x06ed3628) Line 260 + 0x12 bytes
Scribus.exe!SingleObservable<PageItem>::updateLayout() Line 183 + 0x30 bytes
Scribus.exe!PageItem_TextFrame::handleModeEditKey(QKeyEvent * k=0x0018d4c8, bool & keyRepeat=true) Line 3321 + 0x13 bytes
Scribus.exe!ScribusMainWindow::keyPressEvent(QKeyEvent * k=0x0018d4c8) Line 1869 + 0x22 bytes
Scribus.exe!ScribusView::eventFilter(QObject * obj=0x0685e040, QEvent * event=0x0018d4c8) Line 4846 + 0x1b bytes QtCored4.dll!QCoreApplicationPrivate::sendThroughObjectEventFilters(QObject * receiver=0x0685e040, QEvent * event=0x0018d4c8) Line 846 + 0x15 bytes

jghali

2011-09-11 15:18

administrator   ~0026850

Another crash when typing into text frame after commenting out line 2243. The crash seems to occur when line break occurs just after the end of a word :

Scribus.exe!StoryText::text(int pos=72) Line 534
Scribus.exe!PageItem::ExpandToken(unsigned int base=72) Line 1761
Scribus.exe!PageItem_TextFrame::layout() Line 1950 + 0x19 bytes
Scribus.exe!DocUpdater::changed(PageItem * it=0x07d2dd88, bool layout=true) Line 148 + 0x12 bytes
Scribus.exe!MassObservable<PageItem *>::updateNow(UpdateMemento * what=0x05f0b9d8) Line 270 + 0x1d bytes
Scribus.exe!MassObservable<PageItem *>::updateLayout(PageItem * what=0x07d2dd88) Line 260 + 0x12 bytes
Scribus.exe!SingleObservable<PageItem>::updateLayout() Line 183 + 0x30 bytes
Scribus.exe!PageItem_TextFrame::handleModeEditKey(QKeyEvent * k=0x0018d4c8, bool & keyRepeat=true) Line 3321 + 0x13 bytes
Scribus.exe!ScribusMainWindow::keyPressEvent(QKeyEvent * k=0x0018d4c8) Line 1869 + 0x22 bytes
Scribus.exe!ScribusView::eventFilter(QObject * obj=0x07ab38c8, QEvent * event=0x0018d4c8) Line 4846 + 0x1b bytes

plinnell

2011-09-11 15:55

viewer   ~0026851

I do not get those crashes on openSUSE 11.4 64bit with Qt 4.7.4.

What I do get is missing text, when the line wraps occur.

The typed text is visible in the Story Editor

plinnell

2011-09-11 15:57

viewer  

textwithpatch.png (168,460 bytes)   
textwithpatch.png (168,460 bytes)   

cezaryece

2011-09-12 06:22

updater   ~0026854

@plinnell: do you have SLA for your case yet?

cezaryece

2011-09-13 13:37

updater  

formatting2.patch (82,000 bytes)   
Index: Version135/Scribus/scribus/pageitem_textframe.cpp
===================================================================
--- Version135/Scribus/scribus/pageitem_textframe.cpp	(wersja 16820)
+++ Version135/Scribus/scribus/pageitem_textframe.cpp	(kopia robocza)
@@ -70,7 +70,6 @@
 	unicodeInputCount = 0;
 	unicodeInputString = "";
 	lastUndoAction = NOACTION;
-//	lastAction4Paragraph = false;
 	
 	connect(&itemText,SIGNAL(changed()), this, SLOT(slotInvalidateLayout()));
 }
@@ -83,7 +82,6 @@
 	unicodeInputCount = 0;
 	unicodeInputString = "";
 	lastUndoAction = NOACTION;
-//	lastAction4Paragraph = false;
 
 	connect(&itemText,SIGNAL(changed()), this, SLOT(slotInvalidateLayout()));
 }
@@ -155,9 +153,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 +188,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();
 				}
@@ -202,7 +198,6 @@
 	return result;
 }
 
-
 void PageItem_TextFrame::setShadow()
 {
 	if (OnMasterPage.isEmpty())
@@ -235,10 +230,6 @@
 		currentShadow = newShadow;
 	}
 }
-		
-#ifdef NLS_PROTO
-#include "text/pageitem_textframe.cpp"
-#else
 
 static void dumpIt(const ParagraphStyle& pstyle, QString indent = QString("->"))
 {
@@ -258,7 +249,6 @@
 		dumpIt(*dynamic_cast<const ParagraphStyle*>(pstyle.parentStyle()), more + indent);
 }
 
-
 static const bool legacy = true;
 
 /*
@@ -373,22 +363,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
 	 */
@@ -398,7 +389,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 +399,7 @@
 		breakXPos = 0;
 		maxShrink = 0;
 		maxStretch = 0;
+		width = 0;
 	}
 	
 
@@ -423,12 +416,12 @@
 	}
 
 	/// called when a possible break is passed
-	void rememberBreak(int index, double pos)
+	void rememberBreak(int index, double pos, double morespace = 0)
 	{
-		if (pos > colRight)
+		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)
@@ -439,12 +432,8 @@
 				if (newLooseness >= oldLooseness)
 					return;
 			}
-			breakXPos = colRight;
 		}
-		else
-		{
-			breakXPos = pos;
-		}
+		breakXPos = pos;
 		breakIndex = index;
 	}
 	
@@ -460,9 +449,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)
 	{
@@ -471,109 +460,44 @@
 		line.width = endX - line.x;
 		maxShrink = maxStretch = 0;
 	}
-	
-	
+
 	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;
+			res = ceil(xPos - maxShrink)  + ceil(moreSpace) >= floor(colRight);
+		return res;
 	}
-	
-	/// find x position to start current line
-	double startOfLine(const QRegion& shape, const QMatrix& 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;
-	}
-	
+
 	/// find x position where this line must end
-	double endOfLine(const QRegion& shape, const QMatrix& pf2, double morespace = 0)
+	double endOfLine(const QRegion& shape, const QMatrix& pf2, double morespace, int Yasc, int Ydesc)
 	{
-		// 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))
-			);*/
-
 		// 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));
-		int yDesc = static_cast<int>(yPos+line.descent);
-		int yAsc  = static_cast<int>(ceil(yPos-line.ascent));
+		double StartX = floor(qMax(line.x, qMin(maxX,breakXPos-maxShrink-1))-1);
+		int xPos  = static_cast<int>(ceil(maxX));
 
-		QPoint pt12 (xPos, yDesc);
-		QPoint pt22 (xPos, yAsc);
+		QPoint pt12 (xPos, Yasc);
+		QPoint pt22 (xPos, Ydesc);
+		QRect pt(pt12,pt22);
 
-		// 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";
 		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)));
+		} while ((EndX2 < maxX) && QRegion(pf2.mapToPolygon(pt)).subtracted(shape).isEmpty());
 
-		/*if (EndX!=EndX2) 
-		{
-			qDebug()<<EndX<<EndX2<<StartX<<maxX;
-			qDebug()<<"DIFFERING ENDX!!!!!";
-		}*/
-		return EndX2;
+		return qMin(EndX2, maxX);
 	}
-	
-	
+
 	double getLineAscent(const StoryText& itemText)
 	{
 		double result = 0;
@@ -684,15 +608,18 @@
 				|| (ch == SpecialChars::LINEBREAK) || (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);
@@ -700,44 +627,47 @@
 		}
 	}
 	
-	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;
-		}
-	}
+// 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 = line.y - insets.Top -currasce;
+//				//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;
+//		}
+//	}
 
 private:
 	double frameWidth;
@@ -802,8 +732,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)))
@@ -839,46 +772,42 @@
 	}
 }
 
-/// 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;
+//definied 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;
-}
+//	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);
+//	}
+//	return leftCorr;
+//}
 
-
-
 /// calculate how much the last char should stick out to the right
 static double opticalRightMargin(const StoryText& itemText, const LineSpec& line)
 {
@@ -923,10 +852,15 @@
 	return 0.0;
 }
 
+static double findRealOverflowEnd(const QRegion& shape, const QMatrix& 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;
+}
 
-
-
-
 void PageItem_TextFrame::layout() 
 {
 // 	qDebug()<<"==Layout==" << itemName() ;
@@ -957,10 +891,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();
 	QMatrix pf2;
 	QPoint pt1, pt2;
-	/*QRegion cm;*/
+	QRect pt;
 	double chs, chsd = 0;
 	double oldCurY, EndX, OFs, wide, kernVal;
 	QString chstr;
@@ -969,7 +902,6 @@
 	int /*ParagraphStyle::OpticalMarginType*/ opticalMargins = ParagraphStyle::OM_None;
 	
 	bool outs = false;
-	bool fBorder = false;
 	bool goNoRoom = false;
 	bool goNextColumn = false;
 	
@@ -983,12 +915,12 @@
 	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;
 	
-	
 	itemText.clearLines();
 
 	double lineCorr = 0;
@@ -1006,7 +938,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, currentRowDesc = 0;
+	
 	// dump styles
 /*	
 	for (int i=0; i < itemText.nrOfParagraphs(); ++i) {
@@ -1018,7 +954,6 @@
 	dumpIt(itemText.defaultStyle());
 */	
 	
-//	pf2.begin(view->viewport());
 	pf2.translate(Xpos, Ypos);
 	pf2.rotate(Rot);
 	
@@ -1044,7 +979,8 @@
 			pf2.scale(1, -1);
 		}
 		
-		current.nextColumn(0);
+		current.nextColumn();
+		lastLineY = extra.Top;
 
 		// find start of first line
 		if (firstInFrame() < itemText.length())
@@ -1070,19 +1006,35 @@
 			}
 			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;
+		bool inOverflow = false;
+		bool afterOverflow = false;
+		bool addLine = false;
+		bool recalculateY = true;
+		bool lastInRowLine = false;
+		bool addLeftIndent = true;
+		bool wasFirstInRow = false;
+		double leftIndent = 0;
+		double rightMargin = 0.0;
+		double mustLineEnd = current.colRight;
+		int restartIndex = firstInFrame();  //index of char where line computing should be restarted
+		int restartRowIndex = firstInFrame();  //index of char where row of text is started
+		double restartX = 0; //starting X position of line if must be restarted
+		double realEnd = 0;
+
 		for (int a = firstInFrame(); a < itemText.length(); ++a)
 		{
 			hl = itemText.item(a);
@@ -1091,27 +1043,17 @@
 			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);
 
-			chstr = ExpandToken(a);
-//			qDebug() << QString("expanded token: '%1'").arg(chstr);
 			if (chstr.isEmpty())
 				chstr = SpecialChars::ZWNBSPACE;
 			if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
-			{
-				style.setLineSpacing(style.charStyle().font().height(style.charStyle().fontSize() / 10.0));
-			}
+				style.setLineSpacing(charStyle.font().height(hlcsize10));
 			else if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
 				style.setLineSpacing(m_Doc->typographicSettings.valueBaseGrid);
 			// find out about par gap and dropcap
@@ -1119,7 +1061,6 @@
 			{
 				if (a == 0 || itemText.text(a-1) == SpecialChars::PARSEP)
 				{
-					current.yPos += style.gapBefore();
 					if (chstr[0] != SpecialChars::PARSEP)
 					{
 						DropCmode = style.hasDropCap();
@@ -1165,21 +1106,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
+				if (style.rightMargin() == 0)
 				{
-//					qDebug() << QString("gap before2: y=%1+%2").arg(current.yPos).arg(style.gapBefore());
-					current.yPos += style.gapBefore();
+					addLine = true;
+					rightMargin = 0.0;
+				}
+				else
+				{
+					if (lastInRowLine)
+						rightMargin = style.rightMargin();
+					else
+						rightMargin = 0.0;
+				}
+				current.breakIndex = -1;
+				if (current.startOfCol && !afterOverflow && 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 (!afterOverflow && recalculateY && !current.startOfCol)
+						current.yPos += style.gapBefore();
 					DropCapDrop = 0;
 					if (chstr[0] != SpecialChars::PARSEP)
 						DropCmode = style.hasDropCap();
 					else
 						DropCmode = false;
-					if (DropCmode)
+					if (DropCmode && !afterOverflow)
 					{
 						DropLines = style.dropCapLines();
 						if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
@@ -1189,35 +1143,22 @@
 							if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
 								DropCapDrop = style.lineSpacing() * (DropLines-1);
 							else
-								DropCapDrop = charStyle.font().height(style.charStyle().fontSize() / 10.0) * (DropLines-1);
+								DropCapDrop = charStyle.font().height(hlcsize10) * (DropLines-1);
 						}
-//						qDebug() << QString("dropcapdrop: y=%1+%2").arg(current.yPos).arg(DropCapDrop);
-						current.yPos += DropCapDrop;
 					}
 				}
 			}
-			// find charsize & y pos
+// ######## find charsize factors
 			if (DropCmode)
 			{
-				// dropcap active?
-				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-					DropCapDrop = m_Doc->typographicSettings.valueBaseGrid * (DropLines-1);
-				else
-				{
-					if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
-						DropCapDrop = style.lineSpacing() * (DropLines-1);
-					else
-						DropCapDrop = charStyle.font().height(style.charStyle().fontSize() / 10.0) * (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
 				double realCharHeight = charStyle.font().realCharHeight(chstr[0], 1);
 				double realCharAscent = charStyle.font().realCharAscent(chstr[0], 1);
-				double fontAscent     = charStyle.font().ascent(style.charStyle().fontSize() / 10.0);
+				double fontAscent     = charStyle.font().ascent(hlcsize10);
 				if (realCharHeight == 0.0)
-					realCharHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
+					realCharHeight = charStyle.font().height(hlcsize10);
 				if (realCharAscent == 0.0)
 					realCharAscent = fontAscent;
 				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
@@ -1234,7 +1175,7 @@
 					}
 					else
 					{
-						double currasce = charStyle.font().height(style.charStyle().fontSize() / 10.0);
+						double currasce = charStyle.font().height(hlcsize10);
 						chsd = (10 * ((currasce * (DropLines-1) + fontAscent) / realCharHeight));
 						chs  = (10 * ((currasce * (DropLines-1) + fontAscent) / realCharAscent));
 					}
@@ -1249,7 +1190,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);
@@ -1262,7 +1203,8 @@
 			}
 			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();
@@ -1290,168 +1232,177 @@
 						itemHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
 					wide = hl->embedded.getItem()->gWidth + hl->embedded.getItem()->lineWidth();
 					if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-						asce = m_Doc->typographicSettings.valueBaseGrid * DropLines;
+						realAsce = m_Doc->typographicSettings.valueBaseGrid * DropLines;
 					else
 					{
 						if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
-							asce = style.lineSpacing() * DropLines;
+							realAsce = style.lineSpacing() * DropLines;
 						else
-							asce = charStyle.font().height(style.charStyle().fontSize() / 10.0) * DropLines;
+							realAsce = charStyle.font().height(style.charStyle().fontSize() / 10.0) * DropLines;
 					}
 					hl->glyph.scaleH /= hl->glyph.scaleV;
-					hl->glyph.scaleV = (asce / itemHeight);
+					hl->glyph.scaleV = (realAsce / itemHeight);
 					hl->glyph.scaleH *= hl->glyph.scaleV;
 				}
 				else
 				{
-					double realCharHeight = charStyle.font().realCharHeight(chstr[0], charStyle.fontSize() / 10.0);
+					double realCharHeight = charStyle.font().realCharHeight(chstr[0], hlcsize10);
 					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; //dropcaps are always to close to next glyphs
+					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;
+				realAsce = charStyle.font().realCharAscent(chstr[0], hlcsize10) * scaleV + offset;
 			}
-			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())
+
+// ######## check for Y position at beginning of line
+			if (current.itemsInLine == 0 && !afterOverflow)
 			{
-				current.column++;
-				if (current.column < Cols)
+				if (recalculateY)
 				{
-					// start next col
-					current.nextColumn(asce);
-					if (((a > firstInFrame()) && (itemText.text(a-1) == SpecialChars::PARSEP)) 
-						|| ((a == firstInFrame()) && (BackBox == 0)))
+					//if top of column Y position depends on first line offset
+					if (current.startOfCol)
 					{
-						if (chstr[0] != SpecialChars::PARSEP)
-							DropCmode = style.hasDropCap();
-						else
-							DropCmode = false;
-						if (DropCmode)
+						lastLineY = qMax(lastLineY, extra.Top + lineCorr);
+						if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
 						{
-							if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-								desc2 = -charStyle.font().descent() * m_Doc->typographicSettings.valueBaseGrid * style.dropCapLines();
+							if (firstLineOffset() == FLOPRealGlyphHeight)
+							{
+								if (DropCmode)
+									current.yPos += asce;
+								else
+									current.yPos += realAsce;
+							}
+							else if (firstLineOffset() == FLOPLineSpacing)
+								current.yPos += style.lineSpacing();
 							else
-								desc2 = -charStyle.font().descent() * style.lineSpacing() * style.dropCapLines();
+								current.yPos += asce;
 						}
-						if (DropCmode)
-							DropLines = style.dropCapLines();
+						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->typographicSettings.offsetBaseGrid) * 10000.0);
+							int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
+							current.yPos = ceil(  ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by;
+						}
 					}
-//					qDebug() << QString("layout: nextcol grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-					if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+					else
 					{
-						double by = Ypos;
-						if (OwnPage != -1)
-							by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
-						int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
-						int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//						qDebug() << QString("baseline adjust: 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;
+						if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+						{
+							current.yPos += m_Doc->typographicSettings.valueBaseGrid;
+							double by;
+							if (OwnPage != -1)
+								by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
+							int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
+							int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
+							current.yPos = ceil(  ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by;
+						}
+						else
+							current.yPos += style.lineSpacing();
 					}
+					if (DropCmode)
+						current.yPos += DropCapDrop;
 				}
-				else
+				//set left indentation
+				leftIndent = 0.0;
+				if (addLeftIndent && (maxDX == 0 || DropCmode))
 				{
-					MaxChars = a;
-//					qDebug() << QString("no room A: %1").arg(a);
-					goto NoRoom;
+					leftIndent = style.leftMargin();
+					if (current.hasDropCap)
+						leftIndent = 0;
+					if (a==0 || (a > 0 && (itemText.text(a-1) == SpecialChars::PARSEP)))
+						leftIndent += style.firstIndent();
+					addLeftIndent = false;
 				}
 			}
-			// ok, there's more room in col
-			if (current.itemsInLine == 0)
+			recalculateY = true;
+			int maxYAsc = 0, maxYDesc = 0;
+			if (current.startOfCol)
 			{
-//				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)
+				//qMax is used for glyphs shifted or vertically scalled above ascent or below descent
+				double addAsce = qMax(realAsce, asce);
+				if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
 				{
-//					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;
+					if (firstLineOffset() == FLOPRealGlyphHeight)
+						addAsce = realAsce;
+					else if (firstLineOffset() == FLOPLineSpacing)
+						addAsce = style.lineSpacing();
 				}
-//				qDebug() << QString("layout: nextline grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+				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 && !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)
 				{
-					double by = Ypos;
-					if (OwnPage != -1)
-						by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
-					int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
-					int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//					qDebug() << QString("useBaselIneGrid: %1 * %2 + %3 - %4").arg(ol2 / 10000.0).arg(m_Doc->typographicSettings.valueBaseGrid).arg(m_Doc->typographicSettings.offsetBaseGrid).arg(by);
-//					qDebug() << QString("baseline adjust: 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;
-				}
-				/* 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()))
+					Xpos = current.xPos;
+					Xend = current.xPos + leftIndent;
+					//check if in indent any overflow occurs
+					while (Xpos <= Xend && Xpos < current.colRight)
 					{
-//						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);
+						if (!QRegion(pf2.mapToPolygon(pt)).subtracted(cl).isEmpty())
+						{
+							Xpos = current.xPos = realEnd = findRealOverflowEnd(cl, pf2, pt, current.colRight);
+							Xend = current.xPos + leftIndent;
+						}
+						else
+							Xpos++;
+						pt.moveTopLeft(QPoint(static_cast<int>(floor(Xpos)),maxYAsc));
+					}
+					current.xPos = Xend;
+					done = true;
+					if (current.isEndOfLine((style.minGlyphExtension() * wide) + rightMargin + leftIndent))
+					{
 						// 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.valueBaseGrid);
+						current.xPos = qMax(current.colLeft, maxDX);
+						current.yPos ++;
 						if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
 						{
 							double by = Ypos;
@@ -1459,83 +1410,113 @@
 								by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
 							int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
 							int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//							qDebug() << QString("baseline adjust: 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;
 						}
-						if (current.isEndOfCol())
+						lastLineY = maxYAsc +1;
+						if (current.startOfCol)
 						{
-							fBorder = false;
-							current.column++;
-							if (current.column < Cols)
+							//qMax is used for glyphs shifted or vertically scalled above ascent or below descent
+							double addAsce = qMax(realAsce, asce);
+							if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
 							{
-								current.nextColumn(asce);
-								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)
-									{
-										if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-											desc2 = -charStyle.font().descent() * m_Doc->typographicSettings.valueBaseGrid * style.dropCapLines();
-										else
-											desc2 = -charStyle.font().descent() * style.lineSpacing() * style.dropCapLines();
-									}
-									if (DropCmode)
-										DropLines = style.dropCapLines();
-								}
-//								qDebug() << QString("layout: nextcol2 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-								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->typographicSettings.offsetBaseGrid) * 10000.0);
-									int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//									qDebug() << QString("baseline adjust: 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;
-								}
+								if (firstLineOffset() == FLOPRealGlyphHeight)
+									addAsce = realAsce;
+								else if (firstLineOffset() == FLOPLineSpacing)
+									addAsce = style.lineSpacing();
 							}
-							else
-							{
-								MaxChars = a;
-//								qDebug() << QString("no room B: %1").arg(a);
-								goto NoRoom;
-							}
+							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;
 					}
-					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 (current.isEndOfCol(realDesc))
+					{
+						current.column++;
+						if (current.column < Cols)
+						{
+							newColumn = true;
+							break;
+						}
+						else
+						{
+							MaxChars = a;
+							goto NoRoom;
+						}
+					}
 				}
-
-				if (((fBorder)) && (!current.hasDropCap))
-					current.xPos += extra.Left;
-				// indent first line of par
-				if (a > 0)
+				if (newColumn)
 				{
-					if (itemText.text(a-1) == SpecialChars::PARSEP)
-						current.xPos += style.firstIndent();
+					current.nextColumn();
+					mustLineEnd = current.colRight;
+					restartX = current.xPos;
+					lastLineY = current.yPos;
+					currentRowDesc = 0;
+					a--;
+					recalculateY = true;
+					addLeftIndent = true;
+					continue;
 				}
+				current.line.x = 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 (legacy)
-						current.xPos += style.firstIndent();
+					if (current.hasDropCap && DropLinesCount == 0)
+					{
+						current.hasDropCap = false;
+						current.yPos = maxDY;
+						maxDX = 0;
+					}
+					int linesDrop = 0;
+					if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+					{
+						linesDrop = ceil(diff/m_Doc->typographicSettings.valueBaseGrid);
+						current.yPos += m_Doc->typographicSettings.valueBaseGrid * linesDrop;
+					}
+					else /*if (current.startOfCol)*/
+					{
+						float YPOS = (float) current.yPos + (float) diff + 0.01;
+						current.yPos = (double) YPOS;
+						if (current.hasDropCap && diff > DropCapDrop)
+						{
+							current.hasDropCap = false;
+						}
+					}
+					if (current.hasDropCap && linesDrop > 0 && DropLinesCount > 1)
+					{
+						DropLinesCount += linesDrop;
+						if (DropLinesCount >= DropLines)
+						{
+							current.hasDropCap = false;
+							maxDX = 0;
+							maxDY = 0;
+						}
+					}
+					recalculateY = false;
+					current.xPos = current.colLeft;
+					a = restartRowIndex -1;
+					current.startLine(a+1);
+					addLeftIndent = true;
+					afterOverflow = false;
+					continue;
 				}
-				// 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);
-			}
 			// right tab stuff
 			if (tabs.active)
 			{
@@ -1589,7 +1570,6 @@
 							current.xPos = current.colLeft + tCurX;
 						
 						// remember fill char
-//						qDebug() << QString("tab: %1 '%2'").arg(tCurX).arg(tabs.fillChar);
 						if (!tabs.fillChar.isNull()) {
 							hl->glyph.growWithTabLayout();
 							TabLayout * tglyph = dynamic_cast<TabLayout*>(hl->glyph.more);
@@ -1614,7 +1594,6 @@
 			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;
 			
@@ -1630,57 +1609,179 @@
 			else // other tabs.active			
 			{
 				current.xPos = qMax(current.xPos, current.colLeft);
-			}		
-			
-			//FIXME: asce / desc set correctly?
-			if (legacy && 
-				(((hl->ch == '-' || (hl->effects() & ScStyle_HyphenationPossible)) && (current.hyphenCount < m_Doc->HyCount || m_Doc->HyCount == 0))  
-				|| hl->ch == SpecialChars::SHYPHEN))
+			}
+			// remember possible break
+			if ( (SpecialChars::isBreakingSpace(hl->ch) || hl->ch == SpecialChars::TAB))
 			{
-				if (hl->effects() & ScStyle_HyphenationPossible || hl->ch == SpecialChars::SHYPHEN)
+				if ( a == firstInFrame() || !SpecialChars::isBreakingSpace(itemText.text(a-1)) )
 				{
-					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)));
+					current.rememberBreak(a, breakPos, style.rightMargin());
 				}
-				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)));
-				}
 			}
-			else if (!legacy && SpecialChars::isBreakingSpace(hl->ch))
+			//check against space before PARSEP
+			if (SpecialChars::isBreakingSpace(hl->ch) && (a + 1 < itemText.length()) && (itemText.item(a+1)->ch == SpecialChars::PARSEP))
 			{
-				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)));
+				a++;
+				hl = itemText.item(a);
 			}
-			else
+
+			// test if end of line reached
+			double overflowWidth = 0.0;
+			double hyphWidth = 0.0;
+			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 >= mustLineEnd)
 			{
-				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)));
+				if (!addLine && style.rightMargin() > 0.0 && !lastInRowLine && 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
+					lastInRowLine = false;
+					if (current.breakIndex <=0)
+						mustLineEnd = current.line.x -1;
+					else if (current.line.firstItem == restartIndex)
+						lastInRowLine = true;
+					if (current.hasDropCap && DropLinesCount == 0 && restartIndex == restartRowIndex)
+					{
+						current.hasDropCap = false;
+						maxDX = 0;
+						current.yPos = maxDY;
+					}
+					current.xPos = restartX;
+					a = restartIndex -1;
+					current.startLine(a+1);
+					inOverflow = false;
+					afterOverflow = false;
+					outs = false;
+					recalculateY = false;
+					addLine = true;
+					continue;
+				}
+				outs = true;
+				addLine = true;
+				lastInRowLine = true;
+				rightMargin = style.rightMargin();
+				if (current.isEndOfCol(realDesc))
+					goNextColumn = true;
 			}
-			
-			// 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*/)
+			else
 			{
-				if ( a == firstInFrame() || !SpecialChars::isBreakingSpace(itemText.text(a-1)) )
+				int charStart, charEnd;
+				if (current.itemsInLine == 0)
 				{
-					current.rememberBreak(a, breakPos);
+					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->HyCount || m_Doc->HyCount == 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);
+					if (current.breakIndex <=0)
+					{
+						current.line.x = current.xPos = restartX = realEnd;
+						current.itemsInLine = 0;
+						a = restartIndex -1;
+						if (!wasFirstInRow)
+							addLeftIndent = true;
+						if (current.hasDropCap && DropLinesCount == 0 && !afterOverflow)
+						{
+							current.hasDropCap = false;
+							current.yPos = maxDY;
+						}
+						recalculateY = false;
+						continue;
+					}
+					outs = true;
+				}
+				else if (style.rightMargin() > 0.0)
+				{
+					if (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())
+						{
+							outs = true;
+							realEnd = findRealOverflowEnd(cl, pf2, pt, current.colRight);
+						}
+					}
+				}
+				if (outs)
+				{
+					//check if after overflow text can be placed
+					overflowWidth = realEnd - (current.xPos - current.maxShrink);
+					if (current.isEndOfLine(overflowWidth + style.rightMargin() + style.minGlyphExtension() * wide + hyphWidth) || realEnd >= mustLineEnd)
+					{
+						if (!addLine && style.rightMargin() > 0.0 && !lastInRowLine)
+						{
+							if (afterOverflow)
+							{
+								lastInRowLine = false;
+								if (current.breakIndex <=0)
+								{
+									lastInRowLine = true;
+									mustLineEnd = current.line.x -1;
+								}
+								else if (current.line.firstItem == restartIndex)
+									lastInRowLine = true;
+							}
+							else
+								lastInRowLine = true;
+							if (current.hasDropCap && DropLinesCount == 0)
+							{
+								current.hasDropCap = false;
+								maxDX = 0;
+							}
+							current.xPos = restartX;
+							a = restartIndex -1;
+							current.startLine(a+1);
+							inOverflow = false;
+							afterOverflow = false;
+							outs = false;
+							recalculateY = false;
+							addLine = true;
+							continue;
+						}
+						addLine = true;
+						rightMargin = style.rightMargin();
+						lastInRowLine = true;
+					}
+					else
+						inOverflow = true;
+				}
 			}
-			
 
 			// hyphenation
 			if (((hl->effects() & ScStyle_HyphenationPossible) || (hl->ch == '-') || hl->ch == SpecialChars::SHYPHEN) && (!outs) && !itemText.text(a-1).isSpace() )
@@ -1688,24 +1789,28 @@
 				breakPos = current.xPos;
 				if (hl->ch != '-')
 				{
-					breakPos += charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0);
+					breakPos += hyphWidth;
 				}
 				
 				double rightHang = 0;
 				if (opticalMargins & ParagraphStyle::OM_RightHangingPunct) {
-					rightHang = 0.7 * charStyle.font().realCharWidth('-', (charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0));
+					rightHang = 0.7 * hyphWidth;
 				}
 				
 				if (legacy || (breakPos - rightHang < current.colRight - style.rightMargin()))
 				{
 					if ((current.hyphenCount < m_Doc->HyCount) || (m_Doc->HyCount == 0) || hl->ch == SpecialChars::SHYPHEN)
 					{
-						current.rememberBreak(a, breakPos);
+						current.rememberBreak(a, breakPos, style.rightMargin() + hyphWidth);
 					}
 				}
 			}
-			
-						
+
+			if ((hl->ch == SpecialChars::FRAMEBREAK) && (a < itemText.length()-1))
+				goNoRoom = true;
+			if ((hl->ch == SpecialChars::COLBREAK) && (Cols > 1))
+				goNextColumn = true;
+
 			++current.itemsInLine;
 			
 			if (tabs.active)
@@ -1725,7 +1830,7 @@
 				}
 			}
 			
-			if (DropCmode)
+			if (DropCmode && !outs)
 			{
 				DropCmode = false;
 				DropLinesCount = 0;
@@ -1733,10 +1838,7 @@
 				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);
 				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
 				{
 					current.yPos -= m_Doc->typographicSettings.valueBaseGrid * (DropLines-1);
@@ -1745,40 +1847,24 @@
 						by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
 					int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
 					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
 				{
 					if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
 					{
 						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);
+						double currasce = charStyle.font().height(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;
+				recalculateY = false;
 			}
 			// end of line
-			if ( SpecialChars::isBreak(hl->ch, Cols > 1) || (outs))
+			if (outs)
 			{
 				tabs.active = false;
 				tabs.status = TabNONE;
@@ -1786,9 +1872,22 @@
 				{
 					// 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;
+					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)
@@ -1815,7 +1914,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
@@ -1826,64 +1925,59 @@
 				}
 				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)            // Hier koenen auch andere Trennungen eingebaut werden
 					{
-						// 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);
-						if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
+						current.itemsInLine = a - current.line.firstItem + 1;
+						if (addLine)
 						{
-							style.setLineSpacing(style.charStyle().font().height(style.charStyle().fontSize() / 10.0));
-//							qDebug() << QString("auto linespacing: %1").arg(style.lineSpacing());
-						}
-						else if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-							style.setLineSpacing(m_Doc->typographicSettings.valueBaseGrid);
-						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);
+							// go back to last break position
+							style = itemText.paragraphStyle(a);
+							if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
+								style.setLineSpacing(charStyle.font().height(hlcsize10));
+							else if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+								style.setLineSpacing(m_Doc->typographicSettings.valueBaseGrid);
 
-						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.finishLine(EndX);
+							if (hl->ch == ' ') {
+								hl->setEffects(hl->effects() | ScStyle_SuppressSpace);
+								hl->glyph.xadvance = 0;
+							}
 
-//???						current.breakXPos = current.line.x;
-//???						for (int j=current.line.firstItem; j <= a; ++j)
-//???							current.breakXPos += itemText.item(j)->glyph.wide();
-						
-						if ((hl->effects() & ScStyle_HyphenationPossible) || hl->ch == SpecialChars::SHYPHEN)
-						{
-							// insert hyphen
-							current.hyphenCount++;
-							hl->setEffects(hl->effects() | ScStyle_SmartHyphenVisible);
-							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);
-						}
-						else 
-						{
-							if (hl->ch != '-')
-								current.hyphenCount = 0;
-							hl->setEffects(hl->effects() & ~ScStyle_SmartHyphenVisible);
-							hl->glyph.shrink();
-						}
-						
-						// Justification
-//						if (style.alignment() != 0)
-						{
+							current.updateHeightMetrics(itemText);
+							//current.updateLineOffset(itemText, style, firstLineOffset());
+							//current.xPos = current.breakXPos;
+							EndX = current.endOfLine(cl, pf2, rightMargin, maxYAsc, maxYDesc);
+							current.finishLine(EndX);
+							
+							hyphWidth = 0.0;
+							if ((hl->effects() & ScStyle_HyphenationPossible) || hl->ch == SpecialChars::SHYPHEN)
+							{
+								// insert hyphen
+								if (lastInRowLine)
+									//increase hyphen count only for hyphens a the end of text row, omit hyphens before overflow
+									current.hyphenCount++;
+								hl->setEffects(hl->effects() | ScStyle_SmartHyphenVisible);
+								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
+							{
+								if (hl->ch != '-')
+									current.hyphenCount = 0;
+								hl->setEffects(hl->effects() & ~ScStyle_SmartHyphenVisible);
+								hl->glyph.shrink();
+							}
+
+							// Justification
 							if (opticalMargins & ParagraphStyle::OM_RightHangingPunct)
 								current.line.width += opticalRightMargin(itemText, current.line);
+							else
+								current.line.naturalWidth += hyphWidth;
 
 							OFs = 0;
 							if (style.alignment() == ParagraphStyle::Rightaligned)
@@ -1891,229 +1985,126 @@
 							if (style.alignment() == ParagraphStyle::Centered)
 								OFs = (current.line.width - current.line.naturalWidth) / 2;
 							
-							if ((style.alignment() == ParagraphStyle::Justified) 
-								|| (style.alignment() == ParagraphStyle::Extended))
-							{
+							if ((style.alignment() == ParagraphStyle::Justified) || (style.alignment() == ParagraphStyle::Extended))
 								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 (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 (a >= current.line.firstItem)
+						if (current.itemsInLine == 0 || current.column+1 == Cols)
 						{
-							if ((hl->effects() & ScStyle_HyphenationPossible) || hl->ch == SpecialChars::SHYPHEN)
-							{
-								current.itemsInLine = 0;
-								a = current.line.firstItem - 1;
-							}
-							else
-							{
-								--a;
-								--current.itemsInLine;
-							}
+							goNoRoom = true;
+							MaxChars = a + 1;
+							break;
 						}
-						if (a >= 0)
-						{
-							hl = itemText.item(a);
-							style = itemText.paragraphStyle(a);
-							if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
-							{
-								style.setLineSpacing(style.charStyle().font().height(style.charStyle().fontSize() / 10.0));
-//								qDebug() << QString("auto linespacing: %1").arg(style.lineSpacing());
-							}
-							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);
+						goNextColumn = true;
 					}
 				}
-				if ( outs || SpecialChars::isBreak(hl->ch, (Cols > 1)) )
+				if (current.line.firstItem <= current.line.lastItem && current.itemsInLine > 0)
 				{
-					if (outs && !current.isEndOfLine(hl->glyph.wide() + style.rightMargin()))
+					if (addLine)
 					{
-						if (( hl->ch == SpecialChars::PARSEP || hl->ch == SpecialChars::LINEBREAK) 
-							&& current.hasDropCap)
+						if (itemText.charStyle(current.line.firstItem).effects() & ScStyle_DropCap)
 						{
-							current.hasDropCap = false;
-							if (current.yPos < maxDY)
-								current.yPos = maxDY;
-//							qDebug() << QString("after dropcaps: y=%1 maxDY=%2").arg(current.yPos).arg(maxDY);
+							// put line back to top
+							current.line.y -= DropCapDrop;
+							itemText.item(current.line.firstItem)->glyph.yoffset += DropCapDrop;
 						}
-						bool fromOut = true;
-						double BotOffset = desc+extra.Bottom+lineCorr;
-						while (!current.isEndOfLine(style.rightMargin()))
+						fillInTabLeaders(itemText, current.line);
+						//if right margin is set we temporally save line, not append it
+						itemText.appendLine(current.line);
+						restartIndex = current.line.lastItem +1;
+						a = restartIndex -1;
+						currentRowDesc = qMax(currentRowDesc,current.yPos + current.line.descent);
+						if (!lastInRowLine)
 						{
-							current.xPos++;
-							if (current.isEndOfLine(style.rightMargin()))
+							restartX = current.xPos;
+							if (addLeftIndent)
 							{
-								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());
-
-								if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-									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;
-									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;
+								addLeftIndent = false;
+								wasFirstInRow = true;
 							}
-							// #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
+//					else if (!addRightMargin)
+//					{
+//						current.xPos = restartX = realEnd +1;
+//						restartIndex = a +1;
+//					}
+				}
+				if (addLine && lastInRowLine)
+				{
+					recalculateY = true;
+					wasFirstInRow = false;
+					addLeftIndent = true;
+					inOverflow = false;
+					outs = false;
+					current.startOfCol = false;
+					restartX = current.xPos = qMax(maxDX, current.colLeft);
+					lastLineY = currentRowDesc;
+					if (current.hasDropCap)
 					{
-						if (( hl->ch == SpecialChars::PARSEP || hl->ch == SpecialChars::LINEBREAK ) 
-							&& current.hasDropCap)
+						++DropLinesCount;
+						if (DropLinesCount >= DropLines)
 						{
 							current.hasDropCap = false;
-							if (current.yPos < maxDY)
-								current.yPos = maxDY;
-//							qDebug() << QString("after dropcap2: y=%1+%2").arg(current.yPos).arg(maxDY);
+							restartX = current.xPos = current.colLeft;
+							maxDX = 0;
 						}
-//						qDebug() << QString("layout: next lower3 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-
-
-						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
-						{
-//							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
-							//current.yPos += style.lineSpacing();
-							const  ParagraphStyle& pStyle = itemText.paragraphStyle(a+1);
-							double lineSpacing = pStyle.lineSpacing();
-							if (pStyle.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
-								lineSpacing = pStyle.charStyle().font().height(pStyle.charStyle().fontSize() / 10.0);
-							else if (pStyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-								lineSpacing = m_Doc->typographicSettings.valueBaseGrid;
-							current.yPos += lineSpacing;
-						}
-						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;
-						}
 					}
+					lastLineY = currentRowDesc;
+					mustLineEnd = current.colRight;
+					restartRowIndex = restartIndex;
 				}
-				
-
-				// calc. needed vertical space
-				// Let’s try to change into "calc. _wanted_ vertical space" - pm
-				if (current.itemsInLine != 0)
+				if (inOverflow)
 				{
-					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;
-					}
+					afterOverflow = true;
+					inOverflow = false;
+					addLeftIndent = false;
+					recalculateY = false;
 				}
-				
-				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)
-					; //qDebug() << QString("layout: empty line %1 - %2").arg(current.line.firstItem).arg(current.line.lastItem);
-				else if (current.itemsInLine > 0)
-					itemText.appendLine(current.line);
+				else
+				{
+					afterOverflow = false;
+				}
+				outs = false;
+				addLine = false;
+				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)
@@ -2122,12 +2113,18 @@
 					current.column++;
 					if (current.column < Cols)
 					{
-						current.nextColumn(asce);
+						if (firstLineOffset() == FLOPRealGlyphHeight)
+							asce = 0;
+						current.nextColumn();
+						mustLineEnd = current.colRight;
+						addLeftIndent = true;
+						lastLineY = extra.Top;
+						currentRowDesc = 0;
+						recalculateY = true;
 					}
 					else
 					{
 						MaxChars = a;
-//						qDebug() << QString("no room D: %1").arg(a);
 						goto NoRoom;
 					}
 				}
@@ -2139,18 +2136,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 (current.itemsInLine >0)
+		{
+			int a = itemText.length()-1;
+			hl = a >=0 ? itemText.item(a) : NULL;
+			current.breakLine(itemText, style, firstLineOffset(), a);
 
-//		if (style.alignment() != 0)
-		{
+			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)
@@ -2174,26 +2188,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;
+			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) {
+			assert(current.line.firstItem <0);
 			itemText.appendLine(current.line);
+			current.startOfCol = false;
 		}
 	}
 	MaxChars = itemText.length();
@@ -3310,7 +3317,6 @@
 
 void PageItem_TextFrame::setNewPos(int oldPos, int len, int dir)
 {
-	
 	bool isSpace, wasSpace;
 	if ( dir > 0 && oldPos < len )
 	{
@@ -3563,8 +3569,6 @@
 	
 }
 
-#endif  //NLS_PROTO
-
 bool PageItem_TextFrame::createInfoGroup(QFrame *infoGroup, QGridLayout *infoGroupLayout)
 {
 	int Parag = 0;
formatting2.patch (82,000 bytes)   

cezaryece

2011-09-13 13:39

updater   ~0026859

OK, found one code problem and fix it - try formatting2.patch specially for yours issues.

jghali

2011-09-13 20:59

administrator   ~0026862

The first crash i reported (assert, now at line 2201) still occurs when trying to type in text frame. The assert condition is probably wrong or the assert should be simply removed.

The second crash i mentioned is fixed.

When the first line of a paragraph has no break possibility weird things happens. This is the issue mentioned by mrdocs. Seems to be still there.

cezaryece

2011-09-19 11:14

updater  

formatting3.patch (82,034 bytes)   
Index: Version135/Scribus/scribus/pageitem_textframe.cpp
===================================================================
--- Version135/Scribus/scribus/pageitem_textframe.cpp	(wersja 16820)
+++ Version135/Scribus/scribus/pageitem_textframe.cpp	(kopia robocza)
@@ -70,7 +70,6 @@
 	unicodeInputCount = 0;
 	unicodeInputString = "";
 	lastUndoAction = NOACTION;
-//	lastAction4Paragraph = false;
 	
 	connect(&itemText,SIGNAL(changed()), this, SLOT(slotInvalidateLayout()));
 }
@@ -83,7 +82,6 @@
 	unicodeInputCount = 0;
 	unicodeInputString = "";
 	lastUndoAction = NOACTION;
-//	lastAction4Paragraph = false;
 
 	connect(&itemText,SIGNAL(changed()), this, SLOT(slotInvalidateLayout()));
 }
@@ -155,9 +153,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 +188,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();
 				}
@@ -202,7 +198,6 @@
 	return result;
 }
 
-
 void PageItem_TextFrame::setShadow()
 {
 	if (OnMasterPage.isEmpty())
@@ -235,10 +230,6 @@
 		currentShadow = newShadow;
 	}
 }
-		
-#ifdef NLS_PROTO
-#include "text/pageitem_textframe.cpp"
-#else
 
 static void dumpIt(const ParagraphStyle& pstyle, QString indent = QString("->"))
 {
@@ -258,7 +249,6 @@
 		dumpIt(*dynamic_cast<const ParagraphStyle*>(pstyle.parentStyle()), more + indent);
 }
 
-
 static const bool legacy = true;
 
 /*
@@ -373,22 +363,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
 	 */
@@ -398,7 +389,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 +399,7 @@
 		breakXPos = 0;
 		maxShrink = 0;
 		maxStretch = 0;
+		width = 0;
 	}
 	
 
@@ -423,12 +416,12 @@
 	}
 
 	/// called when a possible break is passed
-	void rememberBreak(int index, double pos)
+	void rememberBreak(int index, double pos, double morespace = 0)
 	{
-		if (pos > colRight)
+		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)
@@ -439,12 +432,8 @@
 				if (newLooseness >= oldLooseness)
 					return;
 			}
-			breakXPos = colRight;
 		}
-		else
-		{
-			breakXPos = pos;
-		}
+		breakXPos = pos;
 		breakIndex = index;
 	}
 	
@@ -460,9 +449,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)
 	{
@@ -471,109 +460,44 @@
 		line.width = endX - line.x;
 		maxShrink = maxStretch = 0;
 	}
-	
-	
+
 	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;
+			res = ceil(xPos - maxShrink)  + ceil(moreSpace) >= floor(colRight);
+		return res;
 	}
-	
-	/// find x position to start current line
-	double startOfLine(const QRegion& shape, const QMatrix& 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;
-	}
-	
+
 	/// find x position where this line must end
-	double endOfLine(const QRegion& shape, const QMatrix& pf2, double morespace = 0)
+	double endOfLine(const QRegion& shape, const QMatrix& pf2, double morespace, int Yasc, int Ydesc)
 	{
-		// 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))
-			);*/
-
 		// 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));
-		int yDesc = static_cast<int>(yPos+line.descent);
-		int yAsc  = static_cast<int>(ceil(yPos-line.ascent));
+		double StartX = floor(qMax(line.x, qMin(maxX,breakXPos-maxShrink-1))-1);
+		int xPos  = static_cast<int>(ceil(maxX));
 
-		QPoint pt12 (xPos, yDesc);
-		QPoint pt22 (xPos, yAsc);
+		QPoint pt12 (xPos, Yasc);
+		QPoint pt22 (xPos, Ydesc);
+		QRect pt(pt12,pt22);
 
-		// 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";
 		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)));
+		} while ((EndX2 < maxX) && QRegion(pf2.mapToPolygon(pt)).subtracted(shape).isEmpty());
 
-		/*if (EndX!=EndX2) 
-		{
-			qDebug()<<EndX<<EndX2<<StartX<<maxX;
-			qDebug()<<"DIFFERING ENDX!!!!!";
-		}*/
-		return EndX2;
+		return qMin(EndX2, maxX);
 	}
-	
-	
+
 	double getLineAscent(const StoryText& itemText)
 	{
 		double result = 0;
@@ -684,15 +608,18 @@
 				|| (ch == SpecialChars::LINEBREAK) || (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);
@@ -700,44 +627,47 @@
 		}
 	}
 	
-	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;
-		}
-	}
+// 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 = line.y - insets.Top -currasce;
+//				//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;
+//		}
+//	}
 
 private:
 	double frameWidth;
@@ -802,8 +732,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)))
@@ -839,46 +772,42 @@
 	}
 }
 
-/// 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;
+//definied 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;
-}
+//	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);
+//	}
+//	return leftCorr;
+//}
 
-
-
 /// calculate how much the last char should stick out to the right
 static double opticalRightMargin(const StoryText& itemText, const LineSpec& line)
 {
@@ -923,10 +852,15 @@
 	return 0.0;
 }
 
+static double findRealOverflowEnd(const QRegion& shape, const QMatrix& 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;
+}
 
-
-
-
 void PageItem_TextFrame::layout() 
 {
 // 	qDebug()<<"==Layout==" << itemName() ;
@@ -957,10 +891,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();
 	QMatrix pf2;
 	QPoint pt1, pt2;
-	/*QRegion cm;*/
+	QRect pt;
 	double chs, chsd = 0;
 	double oldCurY, EndX, OFs, wide, kernVal;
 	QString chstr;
@@ -969,7 +902,6 @@
 	int /*ParagraphStyle::OpticalMarginType*/ opticalMargins = ParagraphStyle::OM_None;
 	
 	bool outs = false;
-	bool fBorder = false;
 	bool goNoRoom = false;
 	bool goNextColumn = false;
 	
@@ -983,12 +915,12 @@
 	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;
 	
-	
 	itemText.clearLines();
 
 	double lineCorr = 0;
@@ -1006,7 +938,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, currentRowDesc = 0;
+	
 	// dump styles
 /*	
 	for (int i=0; i < itemText.nrOfParagraphs(); ++i) {
@@ -1018,7 +954,6 @@
 	dumpIt(itemText.defaultStyle());
 */	
 	
-//	pf2.begin(view->viewport());
 	pf2.translate(Xpos, Ypos);
 	pf2.rotate(Rot);
 	
@@ -1044,7 +979,8 @@
 			pf2.scale(1, -1);
 		}
 		
-		current.nextColumn(0);
+		current.nextColumn();
+		lastLineY = extra.Top;
 
 		// find start of first line
 		if (firstInFrame() < itemText.length())
@@ -1070,19 +1006,35 @@
 			}
 			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;
+		bool inOverflow = false;
+		bool afterOverflow = false;
+		bool addLine = false;
+		bool recalculateY = true;
+		bool lastInRowLine = false;
+		bool addLeftIndent = true;
+		bool wasFirstInRow = false;
+		double leftIndent = 0;
+		double rightMargin = 0.0;
+		double mustLineEnd = current.colRight;
+		int restartIndex = firstInFrame();  //index of char where line computing should be restarted
+		int restartRowIndex = firstInFrame();  //index of char where row of text is started
+		double restartX = 0; //starting X position of line if must be restarted
+		double realEnd = 0;
+
 		for (int a = firstInFrame(); a < itemText.length(); ++a)
 		{
 			hl = itemText.item(a);
@@ -1091,27 +1043,17 @@
 			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);
 
-			chstr = ExpandToken(a);
-//			qDebug() << QString("expanded token: '%1'").arg(chstr);
 			if (chstr.isEmpty())
 				chstr = SpecialChars::ZWNBSPACE;
 			if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
-			{
-				style.setLineSpacing(style.charStyle().font().height(style.charStyle().fontSize() / 10.0));
-			}
+				style.setLineSpacing(charStyle.font().height(hlcsize10));
 			else if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
 				style.setLineSpacing(m_Doc->typographicSettings.valueBaseGrid);
 			// find out about par gap and dropcap
@@ -1119,7 +1061,6 @@
 			{
 				if (a == 0 || itemText.text(a-1) == SpecialChars::PARSEP)
 				{
-					current.yPos += style.gapBefore();
 					if (chstr[0] != SpecialChars::PARSEP)
 					{
 						DropCmode = style.hasDropCap();
@@ -1165,21 +1106,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
+				if (style.rightMargin() == 0)
 				{
-//					qDebug() << QString("gap before2: y=%1+%2").arg(current.yPos).arg(style.gapBefore());
-					current.yPos += style.gapBefore();
+					addLine = true;
+					rightMargin = 0.0;
+				}
+				else
+				{
+					if (lastInRowLine)
+						rightMargin = style.rightMargin();
+					else
+						rightMargin = 0.0;
+				}
+				current.breakIndex = -1;
+				if (current.startOfCol && !afterOverflow && 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 (!afterOverflow && recalculateY && !current.startOfCol)
+						current.yPos += style.gapBefore();
 					DropCapDrop = 0;
 					if (chstr[0] != SpecialChars::PARSEP)
 						DropCmode = style.hasDropCap();
 					else
 						DropCmode = false;
-					if (DropCmode)
+					if (DropCmode && !afterOverflow)
 					{
 						DropLines = style.dropCapLines();
 						if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
@@ -1189,35 +1143,22 @@
 							if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
 								DropCapDrop = style.lineSpacing() * (DropLines-1);
 							else
-								DropCapDrop = charStyle.font().height(style.charStyle().fontSize() / 10.0) * (DropLines-1);
+								DropCapDrop = charStyle.font().height(hlcsize10) * (DropLines-1);
 						}
-//						qDebug() << QString("dropcapdrop: y=%1+%2").arg(current.yPos).arg(DropCapDrop);
-						current.yPos += DropCapDrop;
 					}
 				}
 			}
-			// find charsize & y pos
+// ######## find charsize factors
 			if (DropCmode)
 			{
-				// dropcap active?
-				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-					DropCapDrop = m_Doc->typographicSettings.valueBaseGrid * (DropLines-1);
-				else
-				{
-					if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
-						DropCapDrop = style.lineSpacing() * (DropLines-1);
-					else
-						DropCapDrop = charStyle.font().height(style.charStyle().fontSize() / 10.0) * (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
 				double realCharHeight = charStyle.font().realCharHeight(chstr[0], 1);
 				double realCharAscent = charStyle.font().realCharAscent(chstr[0], 1);
-				double fontAscent     = charStyle.font().ascent(style.charStyle().fontSize() / 10.0);
+				double fontAscent     = charStyle.font().ascent(hlcsize10);
 				if (realCharHeight == 0.0)
-					realCharHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
+					realCharHeight = charStyle.font().height(hlcsize10);
 				if (realCharAscent == 0.0)
 					realCharAscent = fontAscent;
 				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
@@ -1234,7 +1175,7 @@
 					}
 					else
 					{
-						double currasce = charStyle.font().height(style.charStyle().fontSize() / 10.0);
+						double currasce = charStyle.font().height(hlcsize10);
 						chsd = (10 * ((currasce * (DropLines-1) + fontAscent) / realCharHeight));
 						chs  = (10 * ((currasce * (DropLines-1) + fontAscent) / realCharAscent));
 					}
@@ -1249,7 +1190,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);
@@ -1262,7 +1203,8 @@
 			}
 			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();
@@ -1290,168 +1232,177 @@
 						itemHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
 					wide = hl->embedded.getItem()->gWidth + hl->embedded.getItem()->lineWidth();
 					if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-						asce = m_Doc->typographicSettings.valueBaseGrid * DropLines;
+						realAsce = m_Doc->typographicSettings.valueBaseGrid * DropLines;
 					else
 					{
 						if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
-							asce = style.lineSpacing() * DropLines;
+							realAsce = style.lineSpacing() * DropLines;
 						else
-							asce = charStyle.font().height(style.charStyle().fontSize() / 10.0) * DropLines;
+							realAsce = charStyle.font().height(style.charStyle().fontSize() / 10.0) * DropLines;
 					}
 					hl->glyph.scaleH /= hl->glyph.scaleV;
-					hl->glyph.scaleV = (asce / itemHeight);
+					hl->glyph.scaleV = (realAsce / itemHeight);
 					hl->glyph.scaleH *= hl->glyph.scaleV;
 				}
 				else
 				{
-					double realCharHeight = charStyle.font().realCharHeight(chstr[0], charStyle.fontSize() / 10.0);
+					double realCharHeight = charStyle.font().realCharHeight(chstr[0], hlcsize10);
 					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; //dropcaps are always to close to next glyphs
+					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;
+				realAsce = charStyle.font().realCharAscent(chstr[0], hlcsize10) * scaleV + offset;
 			}
-			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())
+
+// ######## check for Y position at beginning of line
+			if (current.itemsInLine == 0 && !afterOverflow)
 			{
-				current.column++;
-				if (current.column < Cols)
+				if (recalculateY)
 				{
-					// start next col
-					current.nextColumn(asce);
-					if (((a > firstInFrame()) && (itemText.text(a-1) == SpecialChars::PARSEP)) 
-						|| ((a == firstInFrame()) && (BackBox == 0)))
+					//if top of column Y position depends on first line offset
+					if (current.startOfCol)
 					{
-						if (chstr[0] != SpecialChars::PARSEP)
-							DropCmode = style.hasDropCap();
-						else
-							DropCmode = false;
-						if (DropCmode)
+						lastLineY = qMax(lastLineY, extra.Top + lineCorr);
+						if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
 						{
-							if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-								desc2 = -charStyle.font().descent() * m_Doc->typographicSettings.valueBaseGrid * style.dropCapLines();
+							if (firstLineOffset() == FLOPRealGlyphHeight)
+							{
+								if (DropCmode)
+									current.yPos += asce;
+								else
+									current.yPos += realAsce;
+							}
+							else if (firstLineOffset() == FLOPLineSpacing)
+								current.yPos += style.lineSpacing();
 							else
-								desc2 = -charStyle.font().descent() * style.lineSpacing() * style.dropCapLines();
+								current.yPos += asce;
 						}
-						if (DropCmode)
-							DropLines = style.dropCapLines();
+						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->typographicSettings.offsetBaseGrid) * 10000.0);
+							int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
+							current.yPos = ceil(  ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by;
+						}
 					}
-//					qDebug() << QString("layout: nextcol grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-					if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+					else
 					{
-						double by = Ypos;
-						if (OwnPage != -1)
-							by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
-						int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
-						int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//						qDebug() << QString("baseline adjust: 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;
+						if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+						{
+							current.yPos += m_Doc->typographicSettings.valueBaseGrid;
+							double by;
+							if (OwnPage != -1)
+								by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
+							int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
+							int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
+							current.yPos = ceil(  ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by;
+						}
+						else
+							current.yPos += style.lineSpacing();
 					}
+					if (DropCmode)
+						current.yPos += DropCapDrop;
 				}
-				else
+				//set left indentation
+				leftIndent = 0.0;
+				if (addLeftIndent && (maxDX == 0 || DropCmode))
 				{
-					MaxChars = a;
-//					qDebug() << QString("no room A: %1").arg(a);
-					goto NoRoom;
+					leftIndent = style.leftMargin();
+					if (current.hasDropCap)
+						leftIndent = 0;
+					if (a==0 || (a > 0 && (itemText.text(a-1) == SpecialChars::PARSEP)))
+						leftIndent += style.firstIndent();
+					addLeftIndent = false;
 				}
 			}
-			// ok, there's more room in col
-			if (current.itemsInLine == 0)
+			recalculateY = true;
+			int maxYAsc = 0, maxYDesc = 0;
+			if (current.startOfCol)
 			{
-//				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)
+				//qMax is used for glyphs shifted or vertically scalled above ascent or below descent
+				double addAsce = qMax(realAsce, asce);
+				if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
 				{
-//					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;
+					if (firstLineOffset() == FLOPRealGlyphHeight)
+						addAsce = realAsce;
+					else if (firstLineOffset() == FLOPLineSpacing)
+						addAsce = style.lineSpacing();
 				}
-//				qDebug() << QString("layout: nextline grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+				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 && !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)
 				{
-					double by = Ypos;
-					if (OwnPage != -1)
-						by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
-					int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
-					int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//					qDebug() << QString("useBaselIneGrid: %1 * %2 + %3 - %4").arg(ol2 / 10000.0).arg(m_Doc->typographicSettings.valueBaseGrid).arg(m_Doc->typographicSettings.offsetBaseGrid).arg(by);
-//					qDebug() << QString("baseline adjust: 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;
-				}
-				/* 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()))
+					Xpos = current.xPos;
+					Xend = current.xPos + leftIndent;
+					//check if in indent any overflow occurs
+					while (Xpos <= Xend && Xpos < current.colRight)
 					{
-//						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);
+						if (!QRegion(pf2.mapToPolygon(pt)).subtracted(cl).isEmpty())
+						{
+							Xpos = current.xPos = realEnd = findRealOverflowEnd(cl, pf2, pt, current.colRight);
+							Xend = current.xPos + leftIndent;
+						}
+						else
+							Xpos++;
+						pt.moveTopLeft(QPoint(static_cast<int>(floor(Xpos)),maxYAsc));
+					}
+					current.xPos = Xend;
+					done = true;
+					if (current.isEndOfLine((style.minGlyphExtension() * wide) + rightMargin + leftIndent))
+					{
 						// 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.valueBaseGrid);
+						current.xPos = qMax(current.colLeft, maxDX);
+						current.yPos ++;
 						if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
 						{
 							double by = Ypos;
@@ -1459,83 +1410,113 @@
 								by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
 							int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
 							int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//							qDebug() << QString("baseline adjust: 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;
 						}
-						if (current.isEndOfCol())
+						lastLineY = maxYAsc +1;
+						if (current.startOfCol)
 						{
-							fBorder = false;
-							current.column++;
-							if (current.column < Cols)
+							//qMax is used for glyphs shifted or vertically scalled above ascent or below descent
+							double addAsce = qMax(realAsce, asce);
+							if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
 							{
-								current.nextColumn(asce);
-								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)
-									{
-										if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-											desc2 = -charStyle.font().descent() * m_Doc->typographicSettings.valueBaseGrid * style.dropCapLines();
-										else
-											desc2 = -charStyle.font().descent() * style.lineSpacing() * style.dropCapLines();
-									}
-									if (DropCmode)
-										DropLines = style.dropCapLines();
-								}
-//								qDebug() << QString("layout: nextcol2 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-								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->typographicSettings.offsetBaseGrid) * 10000.0);
-									int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//									qDebug() << QString("baseline adjust: 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;
-								}
+								if (firstLineOffset() == FLOPRealGlyphHeight)
+									addAsce = realAsce;
+								else if (firstLineOffset() == FLOPLineSpacing)
+									addAsce = style.lineSpacing();
 							}
-							else
-							{
-								MaxChars = a;
-//								qDebug() << QString("no room B: %1").arg(a);
-								goto NoRoom;
-							}
+							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;
 					}
-					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 (current.isEndOfCol(realDesc))
+					{
+						current.column++;
+						if (current.column < Cols)
+						{
+							newColumn = true;
+							break;
+						}
+						else
+						{
+							MaxChars = a;
+							goto NoRoom;
+						}
+					}
 				}
-
-				if (((fBorder)) && (!current.hasDropCap))
-					current.xPos += extra.Left;
-				// indent first line of par
-				if (a > 0)
+				if (newColumn)
 				{
-					if (itemText.text(a-1) == SpecialChars::PARSEP)
-						current.xPos += style.firstIndent();
+					current.nextColumn();
+					mustLineEnd = current.colRight;
+					restartX = current.xPos;
+					lastLineY = current.yPos;
+					currentRowDesc = 0;
+					a--;
+					recalculateY = true;
+					addLeftIndent = true;
+					continue;
 				}
+				current.line.x = 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 (legacy)
-						current.xPos += style.firstIndent();
+					if (current.hasDropCap && DropLinesCount == 0)
+					{
+						current.hasDropCap = false;
+						current.yPos = maxDY;
+						maxDX = 0;
+					}
+					int linesDrop = 0;
+					if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+					{
+						linesDrop = ceil(diff/m_Doc->typographicSettings.valueBaseGrid);
+						current.yPos += m_Doc->typographicSettings.valueBaseGrid * linesDrop;
+					}
+					else /*if (current.startOfCol)*/
+					{
+						float YPOS = (float) current.yPos + (float) diff + 0.01;
+						current.yPos = (double) YPOS;
+						if (current.hasDropCap && diff > DropCapDrop)
+						{
+							current.hasDropCap = false;
+						}
+					}
+					if (current.hasDropCap && linesDrop > 0 && DropLinesCount > 1)
+					{
+						DropLinesCount += linesDrop;
+						if (DropLinesCount >= DropLines)
+						{
+							current.hasDropCap = false;
+							maxDX = 0;
+							maxDY = 0;
+						}
+					}
+					recalculateY = false;
+					current.xPos = current.colLeft;
+					a = restartRowIndex -1;
+					current.startLine(a+1);
+					addLeftIndent = true;
+					afterOverflow = false;
+					continue;
 				}
-				// 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);
-			}
 			// right tab stuff
 			if (tabs.active)
 			{
@@ -1589,7 +1570,6 @@
 							current.xPos = current.colLeft + tCurX;
 						
 						// remember fill char
-//						qDebug() << QString("tab: %1 '%2'").arg(tCurX).arg(tabs.fillChar);
 						if (!tabs.fillChar.isNull()) {
 							hl->glyph.growWithTabLayout();
 							TabLayout * tglyph = dynamic_cast<TabLayout*>(hl->glyph.more);
@@ -1614,7 +1594,6 @@
 			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;
 			
@@ -1630,57 +1609,193 @@
 			else // other tabs.active			
 			{
 				current.xPos = qMax(current.xPos, current.colLeft);
-			}		
-			
-			//FIXME: asce / desc set correctly?
-			if (legacy && 
-				(((hl->ch == '-' || (hl->effects() & ScStyle_HyphenationPossible)) && (current.hyphenCount < m_Doc->HyCount || m_Doc->HyCount == 0))  
-				|| hl->ch == SpecialChars::SHYPHEN))
+			}
+			// remember possible break
+			if ( (SpecialChars::isBreakingSpace(hl->ch) || hl->ch == SpecialChars::TAB))
 			{
-				if (hl->effects() & ScStyle_HyphenationPossible || hl->ch == SpecialChars::SHYPHEN)
+				if ( a == firstInFrame() || !SpecialChars::isBreakingSpace(itemText.text(a-1)) )
 				{
-					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)));
+					current.rememberBreak(a, breakPos, style.rightMargin());
 				}
-				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)));
-				}
 			}
-			else if (!legacy && SpecialChars::isBreakingSpace(hl->ch))
+			//check against space before PARSEP
+			if (SpecialChars::isBreakingSpace(hl->ch) && (a + 1 < itemText.length()) && (itemText.item(a+1)->ch == SpecialChars::PARSEP))
 			{
-				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)));
+				a++;
+				hl = itemText.item(a);
 			}
-			else
+
+			// test if end of line reached
+			double overflowWidth = 0.0;
+			double hyphWidth = 0.0;
+			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) >= mustLineEnd)
 			{
-				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)));
+				if (current.breakIndex <=0 && !wasFirstInRow)
+				{
+					current.xPos = restartX = current.colLeft;
+					a = restartIndex -1;
+					current.startLine(a+1);
+					inOverflow = false;
+					afterOverflow = false;
+					outs = false;
+					current.yPos++;
+					recalculateY = true;
+					addLine = true;
+					continue;
+				}
+				if (!addLine && style.rightMargin() > 0.0 && !lastInRowLine && 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
+					lastInRowLine = false;
+					if (current.breakIndex <=0)
+						mustLineEnd = current.line.x -1;
+					else if (current.line.firstItem == restartIndex)
+						lastInRowLine = true;
+					if (current.hasDropCap && DropLinesCount == 0 && restartIndex == restartRowIndex)
+					{
+						current.hasDropCap = false;
+						maxDX = 0;
+						current.yPos = maxDY;
+					}
+					current.xPos = restartX;
+					a = restartIndex -1;
+					current.startLine(a+1);
+					inOverflow = false;
+					afterOverflow = false;
+					outs = false;
+					recalculateY = false;
+					addLine = true;
+					continue;
+				}
+				outs = true;
+				addLine = true;
+				lastInRowLine = true;
+				rightMargin = style.rightMargin();
+				if (current.isEndOfCol(realDesc))
+					goNextColumn = true;
 			}
-			
-			// 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*/)
+			else
 			{
-				if ( a == firstInFrame() || !SpecialChars::isBreakingSpace(itemText.text(a-1)) )
+				int charStart, charEnd;
+				if (current.itemsInLine == 0)
 				{
-					current.rememberBreak(a, breakPos);
+					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->HyCount || m_Doc->HyCount == 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);
+					if (current.breakIndex <=0)
+					{
+						current.line.x = current.xPos = restartX = realEnd;
+						current.itemsInLine = 0;
+						a = restartIndex -1;
+						current.startLine(a+1);
+						if (!wasFirstInRow)
+							addLeftIndent = true;
+						if (current.hasDropCap && DropLinesCount == 0 && !afterOverflow)
+						{
+							current.hasDropCap = false;
+							current.yPos = maxDY;
+						}
+						recalculateY = false;
+						continue;
+					}
+					outs = true;
+				}
+				else if (style.rightMargin() > 0.0)
+				{
+					if (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())
+						{
+							outs = true;
+							realEnd = findRealOverflowEnd(cl, pf2, pt, current.colRight);
+						}
+					}
+				}
+				if (outs)
+				{
+					//check if after overflow text can be placed
+					overflowWidth = realEnd - (current.xPos - current.maxShrink);
+					if (current.isEndOfLine(overflowWidth + style.rightMargin() + style.minGlyphExtension() * wide + hyphWidth) || realEnd >= mustLineEnd)
+					{
+						if (!addLine && style.rightMargin() > 0.0 && !lastInRowLine)
+						{
+							if (afterOverflow)
+							{
+								lastInRowLine = false;
+								if (current.breakIndex <=0)
+								{
+									lastInRowLine = true;
+									mustLineEnd = current.line.x -1;
+								}
+								else if (current.line.firstItem == restartIndex)
+									lastInRowLine = true;
+							}
+							else
+								lastInRowLine = true;
+							if (current.hasDropCap && DropLinesCount == 0)
+							{
+								current.hasDropCap = false;
+								maxDX = 0;
+							}
+							current.xPos = restartX;
+							a = restartIndex -1;
+							current.startLine(a+1);
+							inOverflow = false;
+							afterOverflow = false;
+							outs = false;
+							recalculateY = false;
+							addLine = true;
+							continue;
+						}
+						addLine = true;
+						rightMargin = style.rightMargin();
+						lastInRowLine = true;
+					}
+					else
+						inOverflow = true;
+				}
 			}
-			
 
 			// hyphenation
 			if (((hl->effects() & ScStyle_HyphenationPossible) || (hl->ch == '-') || hl->ch == SpecialChars::SHYPHEN) && (!outs) && !itemText.text(a-1).isSpace() )
@@ -1688,24 +1803,28 @@
 				breakPos = current.xPos;
 				if (hl->ch != '-')
 				{
-					breakPos += charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0);
+					breakPos += hyphWidth;
 				}
 				
 				double rightHang = 0;
 				if (opticalMargins & ParagraphStyle::OM_RightHangingPunct) {
-					rightHang = 0.7 * charStyle.font().realCharWidth('-', (charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0));
+					rightHang = 0.7 * hyphWidth;
 				}
 				
 				if (legacy || (breakPos - rightHang < current.colRight - style.rightMargin()))
 				{
 					if ((current.hyphenCount < m_Doc->HyCount) || (m_Doc->HyCount == 0) || hl->ch == SpecialChars::SHYPHEN)
 					{
-						current.rememberBreak(a, breakPos);
+						current.rememberBreak(a, breakPos, style.rightMargin() + hyphWidth);
 					}
 				}
 			}
-			
-						
+
+			if ((hl->ch == SpecialChars::FRAMEBREAK) && (a < itemText.length()-1))
+				goNoRoom = true;
+			if ((hl->ch == SpecialChars::COLBREAK) && (Cols > 1))
+				goNextColumn = true;
+
 			++current.itemsInLine;
 			
 			if (tabs.active)
@@ -1725,7 +1844,7 @@
 				}
 			}
 			
-			if (DropCmode)
+			if (DropCmode && !outs)
 			{
 				DropCmode = false;
 				DropLinesCount = 0;
@@ -1733,10 +1852,7 @@
 				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);
 				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
 				{
 					current.yPos -= m_Doc->typographicSettings.valueBaseGrid * (DropLines-1);
@@ -1745,40 +1861,24 @@
 						by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
 					int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
 					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
 				{
 					if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
 					{
 						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);
+						double currasce = charStyle.font().height(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;
+				recalculateY = false;
 			}
 			// end of line
-			if ( SpecialChars::isBreak(hl->ch, Cols > 1) || (outs))
+			if (outs)
 			{
 				tabs.active = false;
 				tabs.status = TabNONE;
@@ -1786,9 +1886,22 @@
 				{
 					// 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;
+					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)
@@ -1815,7 +1928,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
@@ -1826,52 +1939,45 @@
 				}
 				else // outs -- last char went outside the columns (or into flow-around shape)
 				{
-					if (current.breakIndex >= 0)            // Hier koenen auch andere Trennungen eingebaut werden
+					a = current.breakIndex;
+					assert( a >= 0 );
+					assert( a < itemText.length() );
+					hl = itemText.item(a);
+					current.itemsInLine = a - current.line.firstItem + 1;
+					if (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);
 						if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
-						{
-							style.setLineSpacing(style.charStyle().font().height(style.charStyle().fontSize() / 10.0));
-//							qDebug() << QString("auto linespacing: %1").arg(style.lineSpacing());
-						}
+							style.setLineSpacing(charStyle.font().height(hlcsize10));
 						else if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
 							style.setLineSpacing(m_Doc->typographicSettings.valueBaseGrid);
-						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 (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, 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 (lastInRowLine)
+								//increase hyphen count only for hyphens a the end of text row, omit hyphens before overflow
+								current.hyphenCount++;
 							hl->setEffects(hl->effects() | ScStyle_SmartHyphenVisible);
 							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 
+						else
 						{
 							if (hl->ch != '-')
 								current.hyphenCount = 0;
@@ -1880,240 +1986,144 @@
 						}
 						
 						// 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))
-							{
-								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;
+								current.line.naturalWidth += opticalRightMargin(itemText, current.line);
+							indentLine(itemText, current.line, OFs);
 						}
+						current.xPos = current.line.x + current.line.width;
 					}
-					else  // no break position
+				}
+				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 (a >= current.line.firstItem)
+						if (current.itemsInLine == 0 || current.column+1 == Cols)
 						{
-							if ((hl->effects() & ScStyle_HyphenationPossible) || hl->ch == SpecialChars::SHYPHEN)
-							{
-								current.itemsInLine = 0;
-								a = current.line.firstItem - 1;
-							}
-							else
-							{
-								--a;
-								--current.itemsInLine;
-							}
+							goNoRoom = true;
+							MaxChars = a + 1;
+							break;
 						}
-						if (a >= 0)
-						{
-							hl = itemText.item(a);
-							style = itemText.paragraphStyle(a);
-							if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
-							{
-								style.setLineSpacing(style.charStyle().font().height(style.charStyle().fontSize() / 10.0));
-//								qDebug() << QString("auto linespacing: %1").arg(style.lineSpacing());
-							}
-							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);
+						goNextColumn = true;
 					}
 				}
-				if ( outs || SpecialChars::isBreak(hl->ch, (Cols > 1)) )
+				if (current.line.firstItem <= current.line.lastItem && current.itemsInLine > 0)
 				{
-					if (outs && !current.isEndOfLine(hl->glyph.wide() + style.rightMargin()))
+					if (addLine && current.breakIndex > 0)
 					{
-						if (( hl->ch == SpecialChars::PARSEP || hl->ch == SpecialChars::LINEBREAK) 
-							&& current.hasDropCap)
+						if (itemText.charStyle(current.line.firstItem).effects() & ScStyle_DropCap)
 						{
-							current.hasDropCap = false;
-							if (current.yPos < maxDY)
-								current.yPos = maxDY;
-//							qDebug() << QString("after dropcaps: y=%1 maxDY=%2").arg(current.yPos).arg(maxDY);
+							// put line back to top
+							current.line.y -= DropCapDrop;
+							itemText.item(current.line.firstItem)->glyph.yoffset += DropCapDrop;
 						}
-						bool fromOut = true;
-						double BotOffset = desc+extra.Bottom+lineCorr;
-						while (!current.isEndOfLine(style.rightMargin()))
+						fillInTabLeaders(itemText, current.line);
+						//if right margin is set we temporally save line, not append it
+						itemText.appendLine(current.line);
+						restartIndex = current.line.lastItem +1;
+						a = restartIndex -1;
+						currentRowDesc = qMax(currentRowDesc,current.yPos + current.line.descent);
+						if (!lastInRowLine)
 						{
-							current.xPos++;
-							if (current.isEndOfLine(style.rightMargin()))
+							restartX = current.xPos;
+							if (addLeftIndent)
 							{
-								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());
-
-								if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-									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;
-									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;
+								addLeftIndent = false;
+								wasFirstInRow = true;
 							}
-							// #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
+					else if (!inOverflow && !afterOverflow && lastInRowLine)
 					{
-						if (( hl->ch == SpecialChars::PARSEP || hl->ch == SpecialChars::LINEBREAK ) 
-							&& current.hasDropCap)
+						current.xPos = restartX;
+						a = restartIndex -1;
+						current.startLine(a+1);
+						current.yPos++;
+						inOverflow = false;
+						outs = false;
+						recalculateY = true;
+						addLine = true;
+						mustLineEnd = current.colRight;
+						continue;
+					}
+				}
+				if (addLine && lastInRowLine)
+				{
+					recalculateY = true;
+					wasFirstInRow = false;
+					addLeftIndent = true;
+					inOverflow = false;
+					outs = false;
+					current.startOfCol = false;
+					restartX = current.xPos = qMax(maxDX, current.colLeft);
+					lastLineY = currentRowDesc;
+					if (current.hasDropCap)
+					{
+						++DropLinesCount;
+						if (DropLinesCount >= DropLines)
 						{
 							current.hasDropCap = false;
-							if (current.yPos < maxDY)
-								current.yPos = maxDY;
-//							qDebug() << QString("after dropcap2: y=%1+%2").arg(current.yPos).arg(maxDY);
+							restartX = current.xPos = current.colLeft;
+							maxDX = 0;
 						}
-//						qDebug() << QString("layout: next lower3 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-
-
-						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
-						{
-//							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
-							//current.yPos += style.lineSpacing();
-							const  ParagraphStyle& pStyle = itemText.paragraphStyle(a+1);
-							double lineSpacing = pStyle.lineSpacing();
-							if (pStyle.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
-								lineSpacing = pStyle.charStyle().font().height(pStyle.charStyle().fontSize() / 10.0);
-							else if (pStyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-								lineSpacing = m_Doc->typographicSettings.valueBaseGrid;
-							current.yPos += lineSpacing;
-						}
-						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;
-						}
 					}
+					lastLineY = currentRowDesc;
+					mustLineEnd = current.colRight;
+					restartRowIndex = restartIndex;
 				}
-				
-
-				// calc. needed vertical space
-				// Let’s try to change into "calc. _wanted_ vertical space" - pm
-				if (current.itemsInLine != 0)
+				if (inOverflow)
 				{
-					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;
-					}
+					afterOverflow = true;
+					inOverflow = false;
+					addLeftIndent = false;
+					recalculateY = false;
 				}
-				
-				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)
-					; //qDebug() << QString("layout: empty line %1 - %2").arg(current.line.firstItem).arg(current.line.lastItem);
-				else if (current.itemsInLine > 0)
-					itemText.appendLine(current.line);
+				else
+				{
+					afterOverflow = false;
+				}
+				outs = false;
+				addLine = false;
+				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)
@@ -2122,12 +2132,18 @@
 					current.column++;
 					if (current.column < Cols)
 					{
-						current.nextColumn(asce);
+						if (firstLineOffset() == FLOPRealGlyphHeight)
+							asce = 0;
+						current.nextColumn();
+						mustLineEnd = current.colRight;
+						addLeftIndent = true;
+						lastLineY = extra.Top;
+						currentRowDesc = 0;
+						recalculateY = true;
 					}
 					else
 					{
 						MaxChars = a;
-//						qDebug() << QString("no room D: %1").arg(a);
 						goto NoRoom;
 					}
 				}
@@ -2139,18 +2155,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 (current.itemsInLine >0)
+		{
+			int a = itemText.length()-1;
+			hl = a >=0 ? itemText.item(a) : NULL;
+			current.breakLine(itemText, style, firstLineOffset(), a);
 
-//		if (style.alignment() != 0)
-		{
+			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)
@@ -2174,26 +2207,18 @@
 					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;
+			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) {
 			itemText.appendLine(current.line);
+			current.startOfCol = false;
 		}
 	}
 	MaxChars = itemText.length();
@@ -3310,7 +3335,6 @@
 
 void PageItem_TextFrame::setNewPos(int oldPos, int len, int dir)
 {
-	
 	bool isSpace, wasSpace;
 	if ( dir > 0 && oldPos < len )
 	{
@@ -3563,8 +3587,6 @@
 	
 }
 
-#endif  //NLS_PROTO
-
 bool PageItem_TextFrame::createInfoGroup(QFrame *infoGroup, QGridLayout *infoGroupLayout)
 {
 	int Parag = 0;
formatting3.patch (82,034 bytes)   

cezaryece

2011-09-19 11:15

updater   ~0026890

OK, fixed problem with non-breaks case and buggy assert - see formatting3.patch

jghali

2011-09-19 21:40

administrator   ~0026892

Ok buggy assert problem is fixed, however behavior for the no-break case is still not correct : in such case almost every application force break when end of line is reached, including Indesign and QuarkXPress. Look at the behavior of a simple text editor to see what the behavior should be. Triggering directly a frame overflow would make Scribus unusable for Asian users. Ok, that relies on some missing features, but nevertheless there are some asian user out there.

cezaryece

2011-09-26 12:45

updater  

formatting4.patch (84,949 bytes)   
Index: Version135/Scribus/scribus/pageitem_textframe.cpp
===================================================================
--- Version135/Scribus/scribus/pageitem_textframe.cpp	(wersja 16857)
+++ Version135/Scribus/scribus/pageitem_textframe.cpp	(kopia robocza)
@@ -70,7 +70,6 @@
 	unicodeInputCount = 0;
 	unicodeInputString = "";
 	lastUndoAction = NOACTION;
-//	lastAction4Paragraph = false;
 	
 	connect(&itemText,SIGNAL(changed()), this, SLOT(slotInvalidateLayout()));
 }
@@ -83,7 +82,6 @@
 	unicodeInputCount = 0;
 	unicodeInputString = "";
 	lastUndoAction = NOACTION;
-//	lastAction4Paragraph = false;
 
 	connect(&itemText,SIGNAL(changed()), this, SLOT(slotInvalidateLayout()));
 }
@@ -155,9 +153,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 +188,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();
 				}
@@ -202,7 +198,6 @@
 	return result;
 }
 
-
 void PageItem_TextFrame::setShadow()
 {
 	if (OnMasterPage.isEmpty())
@@ -235,10 +230,6 @@
 		currentShadow = newShadow;
 	}
 }
-		
-#ifdef NLS_PROTO
-#include "text/pageitem_textframe.cpp"
-#else
 
 static void dumpIt(const ParagraphStyle& pstyle, QString indent = QString("->"))
 {
@@ -258,7 +249,6 @@
 		dumpIt(*dynamic_cast<const ParagraphStyle*>(pstyle.parentStyle()), more + indent);
 }
 
-
 static const bool legacy = true;
 
 /*
@@ -342,6 +332,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;
@@ -373,22 +377,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
 	 */
@@ -398,15 +403,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;
 	}
 	
 
@@ -423,12 +433,12 @@
 	}
 
 	/// called when a possible break is passed
-	void rememberBreak(int index, double pos)
+	void rememberBreak(int index, double pos, double morespace = 0)
 	{
-		if (pos > colRight)
+		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)
@@ -439,12 +449,8 @@
 				if (newLooseness >= oldLooseness)
 					return;
 			}
-			breakXPos = colRight;
 		}
-		else
-		{
-			breakXPos = pos;
-		}
+		breakXPos = pos;
 		breakIndex = index;
 	}
 	
@@ -460,9 +466,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)
 	{
@@ -471,109 +477,66 @@
 		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;
+			res = ceil(xPos - maxShrink)  + ceil(moreSpace) >= floor(colRight);
+		return res;
 	}
-	
-	/// find x position to start current line
-	double startOfLine(const QRegion& shape, const QMatrix& 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;
-	}
-	
+
 	/// find x position where this line must end
-	double endOfLine(const QRegion& shape, const QMatrix& pf2, double morespace = 0)
+	double endOfLine(const QRegion& shape, const QMatrix& pf2, double morespace, int Yasc, int Ydesc)
 	{
-		// 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))
-			);*/
-
 		// 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));
-		int yDesc = static_cast<int>(yPos+line.descent);
-		int yAsc  = static_cast<int>(ceil(yPos-line.ascent));
+		double StartX = floor(qMax(line.x, qMin(maxX,breakXPos-maxShrink-1))-1);
+		int xPos  = static_cast<int>(ceil(maxX));
 
-		QPoint pt12 (xPos, yDesc);
-		QPoint pt22 (xPos, yAsc);
+		QPoint pt12 (xPos, Yasc);
+		QPoint pt22 (xPos, Ydesc);
+		QRect pt(pt12,pt22);
 
-		// 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";
 		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)));
+		} while ((EndX2 < maxX) && QRegion(pf2.mapToPolygon(pt)).subtracted(shape).isEmpty());
 
-		/*if (EndX!=EndX2) 
-		{
-			qDebug()<<EndX<<EndX2<<StartX<<maxX;
-			qDebug()<<"DIFFERING ENDX!!!!!";
-		}*/
-		return EndX2;
+		return qMin(EndX2, maxX);
 	}
-	
-	
+
 	double getLineAscent(const StoryText& itemText)
 	{
 		double result = 0;
@@ -684,15 +647,18 @@
 				|| (ch == SpecialChars::LINEBREAK) || (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);
@@ -700,44 +666,47 @@
 		}
 	}
 	
-	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;
-		}
-	}
+// 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 = line.y - insets.Top -currasce;
+//				//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;
+//		}
+//	}
 
 private:
 	double frameWidth;
@@ -802,8 +771,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)))
@@ -839,46 +811,42 @@
 	}
 }
 
-/// 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;
+//definied 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;
-}
+//	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);
+//	}
+//	return leftCorr;
+//}
 
-
-
 /// calculate how much the last char should stick out to the right
 static double opticalRightMargin(const StoryText& itemText, const LineSpec& line)
 {
@@ -923,10 +891,15 @@
 	return 0.0;
 }
 
+static double findRealOverflowEnd(const QRegion& shape, const QMatrix& 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;
+}
 
-
-
-
 void PageItem_TextFrame::layout() 
 {
 // 	qDebug()<<"==Layout==" << itemName() ;
@@ -957,10 +930,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();
 	QMatrix pf2;
 	QPoint pt1, pt2;
-	/*QRegion cm;*/
+	QRect pt;
 	double chs, chsd = 0;
 	double oldCurY, EndX, OFs, wide, kernVal;
 	QString chstr;
@@ -969,7 +941,6 @@
 	int /*ParagraphStyle::OpticalMarginType*/ opticalMargins = ParagraphStyle::OM_None;
 	
 	bool outs = false;
-	bool fBorder = false;
 	bool goNoRoom = false;
 	bool goNextColumn = false;
 	
@@ -983,12 +954,12 @@
 	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;
 	
-	
 	itemText.clearLines();
 
 	double lineCorr = 0;
@@ -1006,7 +977,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) {
@@ -1018,7 +993,6 @@
 	dumpIt(itemText.defaultStyle());
 */	
 	
-//	pf2.begin(view->viewport());
 	pf2.translate(Xpos, Ypos);
 	pf2.rotate(Rot);
 	
@@ -1044,7 +1018,8 @@
 			pf2.scale(1, -1);
 		}
 		
-		current.nextColumn(0);
+		current.nextColumn();
+		lastLineY = extra.Top;
 
 		// find start of first line
 		if (firstInFrame() < itemText.length())
@@ -1070,19 +1045,34 @@
 			}
 			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;
+		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.restartIndex = firstInFrame();  //index of char where line computing should be restarted
+		current.restartRowIndex = firstInFrame();  //index of char where row of text is started
+		current.restartX = 0; //starting X position of line if must be restarted
+		double realEnd = 0;
+
 		for (int a = firstInFrame(); a < itemText.length(); ++a)
 		{
 			hl = itemText.item(a);
@@ -1091,27 +1081,17 @@
 			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);
 
-			chstr = ExpandToken(a);
-//			qDebug() << QString("expanded token: '%1'").arg(chstr);
 			if (chstr.isEmpty())
 				chstr = SpecialChars::ZWNBSPACE;
 			if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
-			{
-				style.setLineSpacing(style.charStyle().font().height(style.charStyle().fontSize() / 10.0));
-			}
+				style.setLineSpacing(charStyle.font().height(hlcsize10));
 			else if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
 				style.setLineSpacing(m_Doc->typographicSettings.valueBaseGrid);
 			// find out about par gap and dropcap
@@ -1119,7 +1099,6 @@
 			{
 				if (a == 0 || itemText.text(a-1) == SpecialChars::PARSEP)
 				{
-					current.yPos += style.gapBefore();
 					if (chstr[0] != SpecialChars::PARSEP)
 					{
 						DropCmode = style.hasDropCap();
@@ -1165,21 +1144,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
+				if (style.rightMargin() == 0)
 				{
-//					qDebug() << QString("gap before2: y=%1+%2").arg(current.yPos).arg(style.gapBefore());
-					current.yPos += style.gapBefore();
+					//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();
 						if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
@@ -1189,35 +1181,22 @@
 							if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
 								DropCapDrop = style.lineSpacing() * (DropLines-1);
 							else
-								DropCapDrop = charStyle.font().height(style.charStyle().fontSize() / 10.0) * (DropLines-1);
+								DropCapDrop = charStyle.font().height(hlcsize10) * (DropLines-1);
 						}
-//						qDebug() << QString("dropcapdrop: y=%1+%2").arg(current.yPos).arg(DropCapDrop);
-						current.yPos += DropCapDrop;
 					}
 				}
 			}
-			// find charsize & y pos
+// ######## find charsize factors
 			if (DropCmode)
 			{
-				// dropcap active?
-				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-					DropCapDrop = m_Doc->typographicSettings.valueBaseGrid * (DropLines-1);
-				else
-				{
-					if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
-						DropCapDrop = style.lineSpacing() * (DropLines-1);
-					else
-						DropCapDrop = charStyle.font().height(style.charStyle().fontSize() / 10.0) * (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
 				double realCharHeight = charStyle.font().realCharHeight(chstr[0], 1);
 				double realCharAscent = charStyle.font().realCharAscent(chstr[0], 1);
-				double fontAscent     = charStyle.font().ascent(style.charStyle().fontSize() / 10.0);
+				double fontAscent     = charStyle.font().ascent(hlcsize10);
 				if (realCharHeight == 0.0)
-					realCharHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
+					realCharHeight = charStyle.font().height(hlcsize10);
 				if (realCharAscent == 0.0)
 					realCharAscent = fontAscent;
 				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
@@ -1234,7 +1213,7 @@
 					}
 					else
 					{
-						double currasce = charStyle.font().height(style.charStyle().fontSize() / 10.0);
+						double currasce = charStyle.font().height(hlcsize10);
 						chsd = (10 * ((currasce * (DropLines-1) + fontAscent) / realCharHeight));
 						chs  = (10 * ((currasce * (DropLines-1) + fontAscent) / realCharAscent));
 					}
@@ -1249,7 +1228,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);
@@ -1262,7 +1241,8 @@
 			}
 			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();
@@ -1290,168 +1270,177 @@
 						itemHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
 					wide = hl->embedded.getItem()->gWidth + hl->embedded.getItem()->lineWidth();
 					if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-						asce = m_Doc->typographicSettings.valueBaseGrid * DropLines;
+						realAsce = m_Doc->typographicSettings.valueBaseGrid * DropLines;
 					else
 					{
 						if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
-							asce = style.lineSpacing() * DropLines;
+							realAsce = style.lineSpacing() * DropLines;
 						else
-							asce = charStyle.font().height(style.charStyle().fontSize() / 10.0) * DropLines;
+							realAsce = charStyle.font().height(style.charStyle().fontSize() / 10.0) * DropLines;
 					}
 					hl->glyph.scaleH /= hl->glyph.scaleV;
-					hl->glyph.scaleV = (asce / itemHeight);
+					hl->glyph.scaleV = (realAsce / itemHeight);
 					hl->glyph.scaleH *= hl->glyph.scaleV;
 				}
 				else
 				{
-					double realCharHeight = charStyle.font().realCharHeight(chstr[0], charStyle.fontSize() / 10.0);
+					double realCharHeight = charStyle.font().realCharHeight(chstr[0], hlcsize10);
 					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;
+				realAsce = charStyle.font().realCharAscent(chstr[0], hlcsize10) * scaleV + offset;
 			}
-			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())
+
+// ######## check for Y position at beginning of line
+			if (current.itemsInLine == 0 && !current.afterOverflow)
 			{
-				current.column++;
-				if (current.column < Cols)
+				if (current.recalculateY)
 				{
-					// start next col
-					current.nextColumn(asce);
-					if (((a > firstInFrame()) && (itemText.text(a-1) == SpecialChars::PARSEP)) 
-						|| ((a == firstInFrame()) && (BackBox == 0)))
+					//if top of column Y position depends on first line offset
+					if (current.startOfCol)
 					{
-						if (chstr[0] != SpecialChars::PARSEP)
-							DropCmode = style.hasDropCap();
-						else
-							DropCmode = false;
-						if (DropCmode)
+						lastLineY = qMax(lastLineY, extra.Top + lineCorr);
+						if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
 						{
-							if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-								desc2 = -charStyle.font().descent() * m_Doc->typographicSettings.valueBaseGrid * style.dropCapLines();
+							if (firstLineOffset() == FLOPRealGlyphHeight)
+							{
+								if (DropCmode)
+									current.yPos += asce;
+								else
+									current.yPos += realAsce;
+							}
+							else if (firstLineOffset() == FLOPLineSpacing)
+								current.yPos += style.lineSpacing();
 							else
-								desc2 = -charStyle.font().descent() * style.lineSpacing() * style.dropCapLines();
+								current.yPos += asce;
 						}
-						if (DropCmode)
-							DropLines = style.dropCapLines();
+						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->typographicSettings.offsetBaseGrid) * 10000.0);
+							int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
+							current.yPos = ceil(  ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by;
+						}
 					}
-//					qDebug() << QString("layout: nextcol grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-					if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+					else
 					{
-						double by = Ypos;
-						if (OwnPage != -1)
-							by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
-						int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
-						int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//						qDebug() << QString("baseline adjust: 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;
+						if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+						{
+							current.yPos += m_Doc->typographicSettings.valueBaseGrid;
+							double by;
+							if (OwnPage != -1)
+								by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
+							int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
+							int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
+							current.yPos = ceil(  ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by;
+						}
+						else
+							current.yPos += style.lineSpacing();
 					}
+					if (DropCmode)
+						current.yPos += DropCapDrop;
 				}
-				else
+				//set left indentation
+				current.leftIndent = 0.0;
+				if (current.addLeftIndent && (maxDX == 0 || DropCmode))
 				{
-					MaxChars = a;
-//					qDebug() << QString("no room A: %1").arg(a);
-					goto NoRoom;
+					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;
 				}
 			}
-			// ok, there's more room in col
-			if (current.itemsInLine == 0)
+			current.recalculateY = true;
+			int maxYAsc = 0, maxYDesc = 0;
+			if (current.startOfCol)
 			{
-//				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)
+				//qMax is used for glyphs shifted or vertically scalled above ascent or below descent
+				double addAsce = qMax(realAsce, asce);
+				if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
 				{
-//					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;
+					if (firstLineOffset() == FLOPRealGlyphHeight)
+						addAsce = realAsce;
+					else if (firstLineOffset() == FLOPLineSpacing)
+						addAsce = style.lineSpacing();
 				}
-//				qDebug() << QString("layout: nextline grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+				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)
 				{
-					double by = Ypos;
-					if (OwnPage != -1)
-						by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
-					int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
-					int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//					qDebug() << QString("useBaselIneGrid: %1 * %2 + %3 - %4").arg(ol2 / 10000.0).arg(m_Doc->typographicSettings.valueBaseGrid).arg(m_Doc->typographicSettings.offsetBaseGrid).arg(by);
-//					qDebug() << QString("baseline adjust: 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;
-				}
-				/* 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()))
+					Xpos = current.xPos;
+					Xend = current.xPos + current.leftIndent;
+					//check if in indent any overflow occurs
+					while (Xpos <= Xend && Xpos < current.colRight)
 					{
-//						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);
+						if (!QRegion(pf2.mapToPolygon(pt)).subtracted(cl).isEmpty())
+						{
+							Xpos = current.xPos = realEnd = findRealOverflowEnd(cl, pf2, pt, current.colRight);
+							Xend = current.xPos + current.leftIndent;
+						}
+						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
-						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.valueBaseGrid);
+						current.xPos = qMax(current.colLeft, maxDX);
+						current.yPos ++;
 						if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
 						{
 							double by = Ypos;
@@ -1459,83 +1448,110 @@
 								by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
 							int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
 							int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//							qDebug() << QString("baseline adjust: 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;
 						}
-						if (current.isEndOfCol())
+						lastLineY = maxYAsc +1;
+						if (current.startOfCol)
 						{
-							fBorder = false;
-							current.column++;
-							if (current.column < Cols)
+							//qMax is used for glyphs shifted or vertically scalled above ascent or below descent
+							double addAsce = qMax(realAsce, asce);
+							if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
 							{
-								current.nextColumn(asce);
-								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)
-									{
-										if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-											desc2 = -charStyle.font().descent() * m_Doc->typographicSettings.valueBaseGrid * style.dropCapLines();
-										else
-											desc2 = -charStyle.font().descent() * style.lineSpacing() * style.dropCapLines();
-									}
-									if (DropCmode)
-										DropLines = style.dropCapLines();
-								}
-//								qDebug() << QString("layout: nextcol2 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-								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->typographicSettings.offsetBaseGrid) * 10000.0);
-									int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//									qDebug() << QString("baseline adjust: 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;
-								}
+								if (firstLineOffset() == FLOPRealGlyphHeight)
+									addAsce = realAsce;
+								else if (firstLineOffset() == FLOPLineSpacing)
+									addAsce = style.lineSpacing();
 							}
-							else
-							{
-								MaxChars = a;
-//								qDebug() << QString("no room B: %1").arg(a);
-								goto NoRoom;
-							}
+							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;
 					}
-					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 (current.isEndOfCol(realDesc))
+					{
+						current.column++;
+						if (current.column < Cols)
+						{
+							newColumn = true;
+							break;
+						}
+						else
+						{
+							MaxChars = a;
+							goto NoRoom;
+						}
+					}
 				}
-
-				if (((fBorder)) && (!current.hasDropCap))
-					current.xPos += extra.Left;
-				// indent first line of par
-				if (a > 0)
+				if (newColumn)
 				{
-					if (itemText.text(a-1) == SpecialChars::PARSEP)
-						current.xPos += style.firstIndent();
+					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 (legacy)
-						current.xPos += style.firstIndent();
+					if (current.hasDropCap && DropLinesCount == 0)
+					{
+						current.hasDropCap = false;
+						current.yPos = maxDY;
+						maxDX = 0;
+					}
+					int linesDrop = 0;
+					if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+					{
+						linesDrop = ceil(diff/m_Doc->typographicSettings.valueBaseGrid);
+						current.yPos += m_Doc->typographicSettings.valueBaseGrid * 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)
+						{
+							current.hasDropCap = false;
+						}
+					}
+					if (current.hasDropCap && linesDrop > 0 && DropLinesCount > 1)
+					{
+						DropLinesCount += linesDrop;
+						if (DropLinesCount >= DropLines)
+						{
+							current.hasDropCap = false;
+							maxDX = 0;
+							maxDY = 0;
+						}
+					}
+					a = current.restartRow(false);
+					continue;
 				}
-				// 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);
-			}
 			// right tab stuff
 			if (tabs.active)
 			{
@@ -1589,7 +1605,6 @@
 							current.xPos = current.colLeft + tCurX;
 						
 						// remember fill char
-//						qDebug() << QString("tab: %1 '%2'").arg(tCurX).arg(tabs.fillChar);
 						if (!tabs.fillChar.isNull()) {
 							hl->glyph.growWithTabLayout();
 							TabLayout * tglyph = dynamic_cast<TabLayout*>(hl->glyph.more);
@@ -1614,7 +1629,6 @@
 			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;
 			
@@ -1630,57 +1644,194 @@
 			else // other tabs.active			
 			{
 				current.xPos = qMax(current.xPos, current.colLeft);
-			}		
-			
-			//FIXME: asce / desc set correctly?
-			if (legacy && 
-				(((hl->ch == '-' || (hl->effects() & ScStyle_HyphenationPossible)) && (current.hyphenCount < m_Doc->HyCount || m_Doc->HyCount == 0))  
-				|| hl->ch == SpecialChars::SHYPHEN))
+			}
+			// remember possible break
+			if ( (SpecialChars::isBreakingSpace(hl->ch) || hl->ch == SpecialChars::TAB))
 			{
-				if (hl->effects() & ScStyle_HyphenationPossible || hl->ch == SpecialChars::SHYPHEN)
+				if ( a == firstInFrame() || !SpecialChars::isBreakingSpace(itemText.text(a-1)) )
 				{
-					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)));
+					current.rememberBreak(a, breakPos, style.rightMargin());
 				}
-				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)));
-				}
 			}
-			else if (!legacy && SpecialChars::isBreakingSpace(hl->ch))
+			//check against space before PARSEP
+			if (SpecialChars::isBreakingSpace(hl->ch) && (a + 1 < itemText.length()) && (itemText.item(a+1)->ch == SpecialChars::PARSEP))
 			{
-				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)));
+				a++;
+				hl = itemText.item(a);
 			}
-			else
+
+			// 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)
 			{
-				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)));
+				//end of row reached - right column, end of column, break char or line must end
+				if (current.itemsInLine == 0 && !current.afterOverflow)
+				{
+					//no glyphs in line, so start new row
+					if (hl->ch == SpecialChars::PARSEP)
+						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;
 			}
-			
-			// 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*/)
+			else
 			{
-				if ( a == firstInFrame() || !SpecialChars::isBreakingSpace(itemText.text(a-1)) )
+				int charStart, charEnd;
+				if (current.itemsInLine == 0)
 				{
-					current.rememberBreak(a, breakPos);
+					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->HyCount || m_Doc->HyCount == 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() )
@@ -1688,24 +1839,28 @@
 				breakPos = current.xPos;
 				if (hl->ch != '-')
 				{
-					breakPos += charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0);
+					breakPos += hyphWidth;
 				}
 				
 				double rightHang = 0;
 				if (opticalMargins & ParagraphStyle::OM_RightHangingPunct) {
-					rightHang = 0.7 * charStyle.font().realCharWidth('-', (charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0));
+					rightHang = 0.7 * hyphWidth;
 				}
 				
 				if (legacy || (breakPos - rightHang < current.colRight - style.rightMargin()))
 				{
 					if ((current.hyphenCount < m_Doc->HyCount) || (m_Doc->HyCount == 0) || hl->ch == SpecialChars::SHYPHEN)
 					{
-						current.rememberBreak(a, breakPos);
+						current.rememberBreak(a, breakPos, style.rightMargin() + hyphWidth);
 					}
 				}
 			}
-			
-						
+
+			if ((hl->ch == SpecialChars::FRAMEBREAK) && (a < itemText.length()-1))
+				goNoRoom = true;
+			if ((hl->ch == SpecialChars::COLBREAK) && (Cols > 1))
+				goNextColumn = true;
+
 			++current.itemsInLine;
 			
 			if (tabs.active)
@@ -1725,7 +1880,7 @@
 				}
 			}
 			
-			if (DropCmode)
+			if (DropCmode && !outs)
 			{
 				DropCmode = false;
 				DropLinesCount = 0;
@@ -1733,10 +1888,7 @@
 				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);
 				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
 				{
 					current.yPos -= m_Doc->typographicSettings.valueBaseGrid * (DropLines-1);
@@ -1745,40 +1897,24 @@
 						by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
 					int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
 					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
 				{
 					if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
 					{
 						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);
+						double currasce = charStyle.font().height(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;
+				current.recalculateY = false;
 			}
 			// end of line
-			if ( SpecialChars::isBreak(hl->ch, Cols > 1) || (outs))
+			if (outs)
 			{
 				tabs.active = false;
 				tabs.status = TabNONE;
@@ -1786,9 +1922,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)
@@ -1815,7 +1965,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
@@ -1826,52 +1976,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);
 						if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
-						{
-							style.setLineSpacing(style.charStyle().font().height(style.charStyle().fontSize() / 10.0));
-//							qDebug() << QString("auto linespacing: %1").arg(style.lineSpacing());
-						}
+							style.setLineSpacing(charStyle.font().height(hlcsize10));
 						else if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
 							style.setLineSpacing(m_Doc->typographicSettings.valueBaseGrid);
-						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 (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_SmartHyphenVisible);
 							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;
@@ -1880,240 +2024,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))
-							{
-								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;
+								current.line.naturalWidth += opticalRightMargin(itemText, current.line);
+							indentLine(itemText, current.line, OFs);
 						}
+						current.xPos = current.line.x + current.line.width;
 					}
-					else  // no break position
+				}
+				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 (a >= current.line.firstItem)
+						if (current.itemsInLine == 0 || current.column+1 == Cols)
 						{
-							if ((hl->effects() & ScStyle_HyphenationPossible) || hl->ch == SpecialChars::SHYPHEN)
-							{
-								current.itemsInLine = 0;
-								a = current.line.firstItem - 1;
-							}
-							else
-							{
-								--a;
-								--current.itemsInLine;
-							}
+							goNoRoom = true;
+							MaxChars = a + 1;
+							break;
 						}
-						if (a >= 0)
-						{
-							hl = itemText.item(a);
-							style = itemText.paragraphStyle(a);
-							if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
-							{
-								style.setLineSpacing(style.charStyle().font().height(style.charStyle().fontSize() / 10.0));
-//								qDebug() << QString("auto linespacing: %1").arg(style.lineSpacing());
-							}
-							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);
+						goNextColumn = true;
 					}
 				}
-				if ( outs || SpecialChars::isBreak(hl->ch, (Cols > 1)) )
+				if (current.line.firstItem <= current.line.lastItem && current.itemsInLine > 0)
 				{
-					if (outs && !current.isEndOfLine(hl->glyph.wide() + style.rightMargin()))
+					if (current.addLine && current.breakIndex >= 0)
 					{
-						if (( hl->ch == SpecialChars::PARSEP || hl->ch == SpecialChars::LINEBREAK) 
-							&& current.hasDropCap)
+						if (itemText.charStyle(current.line.firstItem).effects() & ScStyle_DropCap)
 						{
-							current.hasDropCap = false;
-							if (current.yPos < maxDY)
-								current.yPos = maxDY;
-//							qDebug() << QString("after dropcaps: y=%1 maxDY=%2").arg(current.yPos).arg(maxDY);
+							// put line back to top
+							current.line.y -= DropCapDrop;
+							itemText.item(current.line.firstItem)->glyph.yoffset += DropCapDrop;
 						}
-						bool fromOut = true;
-						double BotOffset = desc+extra.Bottom+lineCorr;
-						while (!current.isEndOfLine(style.rightMargin()))
+						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.xPos++;
-							if (current.isEndOfLine(style.rightMargin()))
+							current.restartX = current.xPos;
+							if (current.addLeftIndent)
 							{
-								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());
-
-								if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-									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;
-									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;
+								current.addLeftIndent = false;
+								current.wasFirstInRow = true;
 							}
-							// #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
+					else if (!inOverflow && !current.afterOverflow && current.lastInRowLine)
 					{
-						if (( hl->ch == SpecialChars::PARSEP || hl->ch == SpecialChars::LINEBREAK ) 
-							&& current.hasDropCap)
+						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 dropcap2: y=%1+%2").arg(current.yPos).arg(maxDY);
+							current.restartX = current.xPos = current.colLeft;
+							maxDX = 0;
 						}
-//						qDebug() << QString("layout: next lower3 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-
-
-						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
-						{
-//							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
-							//current.yPos += style.lineSpacing();
-							const  ParagraphStyle& pStyle = itemText.paragraphStyle(a+1);
-							double lineSpacing = pStyle.lineSpacing();
-							if (pStyle.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
-								lineSpacing = pStyle.charStyle().font().height(pStyle.charStyle().fontSize() / 10.0);
-							else if (pStyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-								lineSpacing = m_Doc->typographicSettings.valueBaseGrid;
-							current.yPos += lineSpacing;
-						}
-						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;
-						}
 					}
+					lastLineY = current.rowDesc;
+					current.mustLineEnd = current.colRight;
+					current.restartRowIndex = current.restartIndex;
 				}
-				
-
-				// calc. needed vertical space
-				// Let’s try to change into "calc. _wanted_ vertical space" - pm
-				if (current.itemsInLine != 0)
+				if (inOverflow)
 				{
-					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;
-					}
+					current.afterOverflow = true;
+					inOverflow = false;
+					current.addLeftIndent = false;
+					current.recalculateY = false;
 				}
-				
-				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)
-					; //qDebug() << QString("layout: empty line %1 - %2").arg(current.line.firstItem).arg(current.line.lastItem);
-				else if (current.itemsInLine > 0)
-					itemText.appendLine(current.line);
+				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)
@@ -2122,16 +2166,41 @@
 					current.column++;
 					if (current.column < Cols)
 					{
-						current.nextColumn(asce);
+						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);
+				}
+			}
 		}
 		if (goNoRoom)
 		{
@@ -2139,18 +2208,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 (current.itemsInLine >0)
+		{
+			int a = itemText.length()-1;
+			hl = a >=0 ? itemText.item(a) : NULL;
+			current.breakLine(itemText, style, firstLineOffset(), a);
 
-//		if (style.alignment() != 0)
-		{
+			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)
@@ -2174,26 +2260,18 @@
 					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;
+			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) {
 			itemText.appendLine(current.line);
+			current.startOfCol = false;
 		}
 	}
 	MaxChars = itemText.length();
@@ -3310,7 +3388,6 @@
 
 void PageItem_TextFrame::setNewPos(int oldPos, int len, int dir)
 {
-	
 	bool isSpace, wasSpace;
 	if ( dir > 0 && oldPos < len )
 	{
@@ -3563,8 +3640,6 @@
 	
 }
 
-#endif  //NLS_PROTO
-
 bool PageItem_TextFrame::createInfoGroup(QFrame *infoGroup, QGridLayout *infoGroupLayout)
 {
 	int Parag = 0;
formatting4.patch (84,949 bytes)   

cezaryece

2011-09-26 12:49

updater   ~0026907

I have lost my hope to end this task. Almost...
In formatting4.patch you have my next try.
I am crossing fingers for that it will work in acceptable manner.
I wish to get new staff into my C++ IDE.

jghali

2011-09-26 20:03

administrator   ~0026909

Looks good now! I continue testing.

cezaryece

2011-09-27 12:21

updater   ~0026914

Seems something wrong happens with empty paragraphs - starting investigation.

cezaryece

2011-09-27 18:54

updater  

formatting5.patch (84,636 bytes)   
Index: Scribus/scribus/pageitem_textframe.cpp
===================================================================
--- Scribus/scribus/pageitem_textframe.cpp	(wersja 16855)
+++ Scribus/scribus/pageitem_textframe.cpp	(kopia robocza)
@@ -70,7 +70,6 @@
 	unicodeInputCount = 0;
 	unicodeInputString = "";
 	lastUndoAction = NOACTION;
-//	lastAction4Paragraph = false;
 	
 	connect(&itemText,SIGNAL(changed()), this, SLOT(slotInvalidateLayout()));
 }
@@ -83,7 +82,6 @@
 	unicodeInputCount = 0;
 	unicodeInputString = "";
 	lastUndoAction = NOACTION;
-//	lastAction4Paragraph = false;
 
 	connect(&itemText,SIGNAL(changed()), this, SLOT(slotInvalidateLayout()));
 }
@@ -155,9 +153,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 +188,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();
 				}
@@ -202,7 +198,6 @@
 	return result;
 }
 
-
 void PageItem_TextFrame::setShadow()
 {
 	if (OnMasterPage.isEmpty())
@@ -235,10 +230,6 @@
 		currentShadow = newShadow;
 	}
 }
-		
-#ifdef NLS_PROTO
-#include "text/pageitem_textframe.cpp"
-#else
 
 static void dumpIt(const ParagraphStyle& pstyle, QString indent = QString("->"))
 {
@@ -258,7 +249,6 @@
 		dumpIt(*dynamic_cast<const ParagraphStyle*>(pstyle.parentStyle()), more + indent);
 }
 
-
 static const bool legacy = true;
 
 /*
@@ -342,6 +332,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;
@@ -373,22 +377,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
 	 */
@@ -398,15 +403,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;
 	}
 	
 
@@ -423,12 +433,12 @@
 	}
 
 	/// called when a possible break is passed
-	void rememberBreak(int index, double pos)
+	void rememberBreak(int index, double pos, double morespace = 0)
 	{
-		if (pos > colRight)
+		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)
@@ -439,12 +449,8 @@
 				if (newLooseness >= oldLooseness)
 					return;
 			}
-			breakXPos = colRight;
 		}
-		else
-		{
-			breakXPos = pos;
-		}
+		breakXPos = pos;
 		breakIndex = index;
 	}
 	
@@ -460,9 +466,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)
 	{
@@ -471,109 +477,66 @@
 		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;
+			res = ceil(xPos - maxShrink)  + ceil(moreSpace) >= floor(colRight);
+		return res;
 	}
-	
-	/// find x position to start current line
-	double startOfLine(const QRegion& shape, const QMatrix& 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;
-	}
-	
+
 	/// find x position where this line must end
-	double endOfLine(const QRegion& shape, const QMatrix& pf2, double morespace = 0)
+	double endOfLine(const QRegion& shape, const QMatrix& pf2, double morespace, int Yasc, int Ydesc)
 	{
-		// 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))
-			);*/
-
 		// 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));
-		int yDesc = static_cast<int>(yPos+line.descent);
-		int yAsc  = static_cast<int>(ceil(yPos-line.ascent));
+		double StartX = floor(qMax(line.x, qMin(maxX,breakXPos-maxShrink-1))-1);
+		int xPos  = static_cast<int>(ceil(maxX));
 
-		QPoint pt12 (xPos, yDesc);
-		QPoint pt22 (xPos, yAsc);
+		QPoint pt12 (xPos, Yasc);
+		QPoint pt22 (xPos, Ydesc);
+		QRect pt(pt12,pt22);
 
-		// 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";
 		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)));
+		} while ((EndX2 < maxX) && QRegion(pf2.mapToPolygon(pt)).subtracted(shape).isEmpty());
 
-		/*if (EndX!=EndX2) 
-		{
-			qDebug()<<EndX<<EndX2<<StartX<<maxX;
-			qDebug()<<"DIFFERING ENDX!!!!!";
-		}*/
-		return EndX2;
+		return qMin(EndX2, maxX);
 	}
-	
-	
+
 	double getLineAscent(const StoryText& itemText)
 	{
 		double result = 0;
@@ -684,15 +647,18 @@
 				|| (ch == SpecialChars::LINEBREAK) || (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);
@@ -700,44 +666,47 @@
 		}
 	}
 	
-	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;
-		}
-	}
+// 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 = line.y - insets.Top -currasce;
+//				//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;
+//		}
+//	}
 
 private:
 	double frameWidth;
@@ -802,8 +771,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)))
@@ -839,46 +811,42 @@
 	}
 }
 
-/// 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;
+//definied 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;
-}
+//	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);
+//	}
+//	return leftCorr;
+//}
 
-
-
 /// calculate how much the last char should stick out to the right
 static double opticalRightMargin(const StoryText& itemText, const LineSpec& line)
 {
@@ -923,10 +891,15 @@
 	return 0.0;
 }
 
+static double findRealOverflowEnd(const QRegion& shape, const QMatrix& 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;
+}
 
-
-
-
 void PageItem_TextFrame::layout() 
 {
 // 	qDebug()<<"==Layout==" << itemName() ;
@@ -957,10 +930,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();
 	QMatrix pf2;
 	QPoint pt1, pt2;
-	/*QRegion cm;*/
+	QRect pt;
 	double chs, chsd = 0;
 	double oldCurY, EndX, OFs, wide, kernVal;
 	QString chstr;
@@ -969,7 +941,6 @@
 	int /*ParagraphStyle::OpticalMarginType*/ opticalMargins = ParagraphStyle::OM_None;
 	
 	bool outs = false;
-	bool fBorder = false;
 	bool goNoRoom = false;
 	bool goNextColumn = false;
 	
@@ -983,12 +954,12 @@
 	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;
 	
-	
 	itemText.clearLines();
 
 	double lineCorr = 0;
@@ -1006,7 +977,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) {
@@ -1018,7 +993,6 @@
 	dumpIt(itemText.defaultStyle());
 */	
 	
-//	pf2.begin(view->viewport());
 	pf2.translate(Xpos, Ypos);
 	pf2.rotate(Rot);
 	
@@ -1044,7 +1018,8 @@
 			pf2.scale(1, -1);
 		}
 		
-		current.nextColumn(0);
+		current.nextColumn();
+		lastLineY = extra.Top;
 
 		// find start of first line
 		if (firstInFrame() < itemText.length())
@@ -1070,19 +1045,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);
@@ -1091,27 +1080,17 @@
 			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);
 
-			chstr = ExpandToken(a);
-//			qDebug() << QString("expanded token: '%1'").arg(chstr);
 			if (chstr.isEmpty())
 				chstr = SpecialChars::ZWNBSPACE;
 			if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
-			{
-				style.setLineSpacing(style.charStyle().font().height(style.charStyle().fontSize() / 10.0));
-			}
+				style.setLineSpacing(charStyle.font().height(hlcsize10));
 			else if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
 				style.setLineSpacing(m_Doc->typographicSettings.valueBaseGrid);
 			// find out about par gap and dropcap
@@ -1119,7 +1098,6 @@
 			{
 				if (a == 0 || itemText.text(a-1) == SpecialChars::PARSEP)
 				{
-					current.yPos += style.gapBefore();
 					if (chstr[0] != SpecialChars::PARSEP)
 					{
 						DropCmode = style.hasDropCap();
@@ -1165,21 +1143,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
+				if (style.rightMargin() == 0)
 				{
-//					qDebug() << QString("gap before2: y=%1+%2").arg(current.yPos).arg(style.gapBefore());
-					current.yPos += style.gapBefore();
+					//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();
 						if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
@@ -1189,35 +1180,22 @@
 							if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
 								DropCapDrop = style.lineSpacing() * (DropLines-1);
 							else
-								DropCapDrop = charStyle.font().height(style.charStyle().fontSize() / 10.0) * (DropLines-1);
+								DropCapDrop = charStyle.font().height(hlcsize10) * (DropLines-1);
 						}
-//						qDebug() << QString("dropcapdrop: y=%1+%2").arg(current.yPos).arg(DropCapDrop);
-						current.yPos += DropCapDrop;
 					}
 				}
 			}
-			// find charsize & y pos
+// ######## find charsize factors
 			if (DropCmode)
 			{
-				// dropcap active?
-				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-					DropCapDrop = m_Doc->typographicSettings.valueBaseGrid * (DropLines-1);
-				else
-				{
-					if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
-						DropCapDrop = style.lineSpacing() * (DropLines-1);
-					else
-						DropCapDrop = charStyle.font().height(style.charStyle().fontSize() / 10.0) * (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
 				double realCharHeight = charStyle.font().realCharHeight(chstr[0], 1);
 				double realCharAscent = charStyle.font().realCharAscent(chstr[0], 1);
-				double fontAscent     = charStyle.font().ascent(style.charStyle().fontSize() / 10.0);
+				double fontAscent     = charStyle.font().ascent(hlcsize10);
 				if (realCharHeight == 0.0)
-					realCharHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
+					realCharHeight = charStyle.font().height(hlcsize10);
 				if (realCharAscent == 0.0)
 					realCharAscent = fontAscent;
 				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
@@ -1234,7 +1212,7 @@
 					}
 					else
 					{
-						double currasce = charStyle.font().height(style.charStyle().fontSize() / 10.0);
+						double currasce = charStyle.font().height(hlcsize10);
 						chsd = (10 * ((currasce * (DropLines-1) + fontAscent) / realCharHeight));
 						chs  = (10 * ((currasce * (DropLines-1) + fontAscent) / realCharAscent));
 					}
@@ -1249,7 +1227,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);
@@ -1262,7 +1240,8 @@
 			}
 			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();
@@ -1290,168 +1269,177 @@
 						itemHeight = charStyle.font().height(style.charStyle().fontSize() / 10.0);
 					wide = hl->embedded.getItem()->gWidth + hl->embedded.getItem()->lineWidth();
 					if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-						asce = m_Doc->typographicSettings.valueBaseGrid * DropLines;
+						realAsce = m_Doc->typographicSettings.valueBaseGrid * DropLines;
 					else
 					{
 						if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
-							asce = style.lineSpacing() * DropLines;
+							realAsce = style.lineSpacing() * DropLines;
 						else
-							asce = charStyle.font().height(style.charStyle().fontSize() / 10.0) * DropLines;
+							realAsce = charStyle.font().height(style.charStyle().fontSize() / 10.0) * DropLines;
 					}
 					hl->glyph.scaleH /= hl->glyph.scaleV;
-					hl->glyph.scaleV = (asce / itemHeight);
+					hl->glyph.scaleV = (realAsce / itemHeight);
 					hl->glyph.scaleH *= hl->glyph.scaleV;
 				}
 				else
 				{
-					double realCharHeight = charStyle.font().realCharHeight(chstr[0], charStyle.fontSize() / 10.0);
+					double realCharHeight = charStyle.font().realCharHeight(chstr[0], hlcsize10);
 					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;
+				realAsce = charStyle.font().realCharAscent(chstr[0], hlcsize10) * scaleV + offset;
 			}
-			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())
+
+// ######## check for Y position at beginning of line
+			if (current.itemsInLine == 0 && !current.afterOverflow)
 			{
-				current.column++;
-				if (current.column < Cols)
+				if (current.recalculateY)
 				{
-					// start next col
-					current.nextColumn(asce);
-					if (((a > firstInFrame()) && (itemText.text(a-1) == SpecialChars::PARSEP)) 
-						|| ((a == firstInFrame()) && (BackBox == 0)))
+					//if top of column Y position depends on first line offset
+					if (current.startOfCol)
 					{
-						if (chstr[0] != SpecialChars::PARSEP)
-							DropCmode = style.hasDropCap();
-						else
-							DropCmode = false;
-						if (DropCmode)
+						lastLineY = qMax(lastLineY, extra.Top + lineCorr);
+						if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
 						{
-							if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-								desc2 = -charStyle.font().descent() * m_Doc->typographicSettings.valueBaseGrid * style.dropCapLines();
+							if (firstLineOffset() == FLOPRealGlyphHeight)
+							{
+								if (DropCmode)
+									current.yPos += asce;
+								else
+									current.yPos += realAsce;
+							}
+							else if (firstLineOffset() == FLOPLineSpacing)
+								current.yPos += style.lineSpacing();
 							else
-								desc2 = -charStyle.font().descent() * style.lineSpacing() * style.dropCapLines();
+								current.yPos += asce;
 						}
-						if (DropCmode)
-							DropLines = style.dropCapLines();
+						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->typographicSettings.offsetBaseGrid) * 10000.0);
+							int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
+							current.yPos = ceil(  ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by;
+						}
 					}
-//					qDebug() << QString("layout: nextcol grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-					if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+					else
 					{
-						double by = Ypos;
-						if (OwnPage != -1)
-							by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
-						int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
-						int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//						qDebug() << QString("baseline adjust: 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;
+						if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+						{
+							current.yPos += m_Doc->typographicSettings.valueBaseGrid;
+							double by;
+							if (OwnPage != -1)
+								by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
+							int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
+							int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
+							current.yPos = ceil(  ol2 / 10000.0 ) * m_Doc->typographicSettings.valueBaseGrid + m_Doc->typographicSettings.offsetBaseGrid - by;
+						}
+						else
+							current.yPos += style.lineSpacing();
 					}
+					if (DropCmode)
+						current.yPos += DropCapDrop;
 				}
-				else
+				//set left indentation
+				current.leftIndent = 0.0;
+				if (current.addLeftIndent && (maxDX == 0 || DropCmode))
 				{
-					MaxChars = a;
-//					qDebug() << QString("no room A: %1").arg(a);
-					goto NoRoom;
+					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;
 				}
 			}
-			// ok, there's more room in col
-			if (current.itemsInLine == 0)
+			current.recalculateY = true;
+			int maxYAsc = 0, maxYDesc = 0;
+			if (current.startOfCol)
 			{
-//				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)
+				//qMax is used for glyphs shifted or vertically scalled above ascent or below descent
+				double addAsce = qMax(realAsce, asce);
+				if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
 				{
-//					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;
+					if (firstLineOffset() == FLOPRealGlyphHeight)
+						addAsce = realAsce;
+					else if (firstLineOffset() == FLOPLineSpacing)
+						addAsce = style.lineSpacing();
 				}
-//				qDebug() << QString("layout: nextline grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+				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)
 				{
-					double by = Ypos;
-					if (OwnPage != -1)
-						by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
-					int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
-					int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//					qDebug() << QString("useBaselIneGrid: %1 * %2 + %3 - %4").arg(ol2 / 10000.0).arg(m_Doc->typographicSettings.valueBaseGrid).arg(m_Doc->typographicSettings.offsetBaseGrid).arg(by);
-//					qDebug() << QString("baseline adjust: 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;
-				}
-				/* 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()))
+					Xpos = current.xPos;
+					Xend = current.xPos + current.leftIndent;
+					//check if in indent any overflow occurs
+					while (Xpos <= Xend && Xpos < current.colRight)
 					{
-//						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);
+						if (!QRegion(pf2.mapToPolygon(pt)).subtracted(cl).isEmpty())
+						{
+							Xpos = current.xPos = realEnd = findRealOverflowEnd(cl, pf2, pt, current.colRight);
+							Xend = current.xPos + current.leftIndent;
+						}
+						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
-						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.valueBaseGrid);
+						current.xPos = qMax(current.colLeft, maxDX);
+						current.yPos ++;
 						if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
 						{
 							double by = Ypos;
@@ -1459,83 +1447,110 @@
 								by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
 							int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
 							int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//							qDebug() << QString("baseline adjust: 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;
 						}
-						if (current.isEndOfCol())
+						lastLineY = maxYAsc +1;
+						if (current.startOfCol)
 						{
-							fBorder = false;
-							current.column++;
-							if (current.column < Cols)
+							//qMax is used for glyphs shifted or vertically scalled above ascent or below descent
+							double addAsce = qMax(realAsce, asce);
+							if (style.lineSpacingMode() != ParagraphStyle::BaselineGridLineSpacing)
 							{
-								current.nextColumn(asce);
-								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)
-									{
-										if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-											desc2 = -charStyle.font().descent() * m_Doc->typographicSettings.valueBaseGrid * style.dropCapLines();
-										else
-											desc2 = -charStyle.font().descent() * style.lineSpacing() * style.dropCapLines();
-									}
-									if (DropCmode)
-										DropLines = style.dropCapLines();
-								}
-//								qDebug() << QString("layout: nextcol2 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-								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->typographicSettings.offsetBaseGrid) * 10000.0);
-									int ol2 = static_cast<int>(ol1 / m_Doc->typographicSettings.valueBaseGrid);
-//									qDebug() << QString("baseline adjust: 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;
-								}
+								if (firstLineOffset() == FLOPRealGlyphHeight)
+									addAsce = realAsce;
+								else if (firstLineOffset() == FLOPLineSpacing)
+									addAsce = style.lineSpacing();
 							}
-							else
-							{
-								MaxChars = a;
-//								qDebug() << QString("no room B: %1").arg(a);
-								goto NoRoom;
-							}
+							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;
 					}
-					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 (current.isEndOfCol(realDesc))
+					{
+						current.column++;
+						if (current.column < Cols)
+						{
+							newColumn = true;
+							break;
+						}
+						else
+						{
+							MaxChars = a;
+							goto NoRoom;
+						}
+					}
 				}
-
-				if (((fBorder)) && (!current.hasDropCap))
-					current.xPos += extra.Left;
-				// indent first line of par
-				if (a > 0)
+				if (newColumn)
 				{
-					if (itemText.text(a-1) == SpecialChars::PARSEP)
-						current.xPos += style.firstIndent();
+					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 (legacy)
-						current.xPos += style.firstIndent();
+					if (current.hasDropCap && DropLinesCount == 0)
+					{
+						current.hasDropCap = false;
+						current.yPos = maxDY;
+						maxDX = 0;
+					}
+					int linesDrop = 0;
+					if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
+					{
+						linesDrop = ceil(diff/m_Doc->typographicSettings.valueBaseGrid);
+						current.yPos += m_Doc->typographicSettings.valueBaseGrid * 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)
+						{
+							current.hasDropCap = false;
+						}
+					}
+					if (current.hasDropCap && linesDrop > 0 && DropLinesCount > 1)
+					{
+						DropLinesCount += linesDrop;
+						if (DropLinesCount >= DropLines)
+						{
+							current.hasDropCap = false;
+							maxDX = 0;
+							maxDY = 0;
+						}
+					}
+					a = current.restartRow(false);
+					continue;
 				}
-				// 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);
-			}
 			// right tab stuff
 			if (tabs.active)
 			{
@@ -1589,7 +1604,6 @@
 							current.xPos = current.colLeft + tCurX;
 						
 						// remember fill char
-//						qDebug() << QString("tab: %1 '%2'").arg(tCurX).arg(tabs.fillChar);
 						if (!tabs.fillChar.isNull()) {
 							hl->glyph.growWithTabLayout();
 							TabLayout * tglyph = dynamic_cast<TabLayout*>(hl->glyph.more);
@@ -1614,7 +1628,6 @@
 			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;
 			
@@ -1630,57 +1643,194 @@
 			else // other tabs.active			
 			{
 				current.xPos = qMax(current.xPos, current.colLeft);
-			}		
-			
-			//FIXME: asce / desc set correctly?
-			if (legacy && 
-				(((hl->ch == '-' || (hl->effects() & ScStyle_HyphenationPossible)) && (current.hyphenCount < m_Doc->HyCount || m_Doc->HyCount == 0))  
-				|| hl->ch == SpecialChars::SHYPHEN))
+			}
+			// remember possible break
+			if ( (SpecialChars::isBreakingSpace(hl->ch) || hl->ch == SpecialChars::TAB))
 			{
-				if (hl->effects() & ScStyle_HyphenationPossible || hl->ch == SpecialChars::SHYPHEN)
+				if ( a == firstInFrame() || !SpecialChars::isBreakingSpace(itemText.text(a-1)) )
 				{
-					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)));
+					current.rememberBreak(a, breakPos, style.rightMargin());
 				}
-				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)));
-				}
 			}
-			else if (!legacy && SpecialChars::isBreakingSpace(hl->ch))
+			//check against space before PARSEP
+			if (SpecialChars::isBreakingSpace(hl->ch) && (a + 1 < itemText.length()) && (itemText.item(a+1)->ch == SpecialChars::PARSEP))
 			{
-				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)));
+				a++;
+				hl = itemText.item(a);
 			}
-			else
+
+			// 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)
 			{
-				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)));
+				//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;
 			}
-			
-			// 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*/)
+			else
 			{
-				if ( a == firstInFrame() || !SpecialChars::isBreakingSpace(itemText.text(a-1)) )
+				int charStart, charEnd;
+				if (current.itemsInLine == 0)
 				{
-					current.rememberBreak(a, breakPos);
+					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->HyCount || m_Doc->HyCount == 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() )
@@ -1688,24 +1838,28 @@
 				breakPos = current.xPos;
 				if (hl->ch != '-')
 				{
-					breakPos += charStyle.font().charWidth('-', charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0);
+					breakPos += hyphWidth;
 				}
 				
 				double rightHang = 0;
 				if (opticalMargins & ParagraphStyle::OM_RightHangingPunct) {
-					rightHang = 0.7 * charStyle.font().realCharWidth('-', (charStyle.fontSize() / 10.0) * (charStyle.scaleH() / 1000.0));
+					rightHang = 0.7 * hyphWidth;
 				}
 				
 				if (legacy || (breakPos - rightHang < current.colRight - style.rightMargin()))
 				{
 					if ((current.hyphenCount < m_Doc->HyCount) || (m_Doc->HyCount == 0) || hl->ch == SpecialChars::SHYPHEN)
 					{
-						current.rememberBreak(a, breakPos);
+						current.rememberBreak(a, breakPos, style.rightMargin() + hyphWidth);
 					}
 				}
 			}
-			
-						
+
+			if ((hl->ch == SpecialChars::FRAMEBREAK) && (a < itemText.length()-1))
+				goNoRoom = true;
+			if ((hl->ch == SpecialChars::COLBREAK) && (Cols > 1))
+				goNextColumn = true;
+
 			++current.itemsInLine;
 			
 			if (tabs.active)
@@ -1725,7 +1879,7 @@
 				}
 			}
 			
-			if (DropCmode)
+			if (DropCmode && !outs)
 			{
 				DropCmode = false;
 				DropLinesCount = 0;
@@ -1733,10 +1887,7 @@
 				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);
 				if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
 				{
 					current.yPos -= m_Doc->typographicSettings.valueBaseGrid * (DropLines-1);
@@ -1745,40 +1896,24 @@
 						by = Ypos - m_Doc->Pages->at(OwnPage)->yOffset();
 					int ol1 = qRound((by + current.yPos - m_Doc->typographicSettings.offsetBaseGrid) * 10000.0);
 					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
 				{
 					if (style.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
 					{
 						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);
+						double currasce = charStyle.font().height(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;
+				current.recalculateY = false;
 			}
 			// end of line
-			if ( SpecialChars::isBreak(hl->ch, Cols > 1) || (outs))
+			if (outs)
 			{
 				tabs.active = false;
 				tabs.status = TabNONE;
@@ -1786,9 +1921,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)
@@ -1815,7 +1964,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
@@ -1826,52 +1975,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);
 						if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
-						{
-							style.setLineSpacing(style.charStyle().font().height(style.charStyle().fontSize() / 10.0));
-//							qDebug() << QString("auto linespacing: %1").arg(style.lineSpacing());
-						}
+							style.setLineSpacing(charStyle.font().height(hlcsize10));
 						else if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
 							style.setLineSpacing(m_Doc->typographicSettings.valueBaseGrid);
-						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 (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_SmartHyphenVisible);
 							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;
@@ -1880,240 +2023,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))
-							{
-								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;
+								current.line.naturalWidth += opticalRightMargin(itemText, current.line);
+							indentLine(itemText, current.line, OFs);
 						}
+						current.xPos = current.line.x + current.line.width;
 					}
-					else  // no break position
+				}
+				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 (a >= current.line.firstItem)
+						if (current.itemsInLine == 0 || current.column+1 == Cols)
 						{
-							if ((hl->effects() & ScStyle_HyphenationPossible) || hl->ch == SpecialChars::SHYPHEN)
-							{
-								current.itemsInLine = 0;
-								a = current.line.firstItem - 1;
-							}
-							else
-							{
-								--a;
-								--current.itemsInLine;
-							}
+							goNoRoom = true;
+							MaxChars = a + 1;
+							break;
 						}
-						if (a >= 0)
-						{
-							hl = itemText.item(a);
-							style = itemText.paragraphStyle(a);
-							if (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
-							{
-								style.setLineSpacing(style.charStyle().font().height(style.charStyle().fontSize() / 10.0));
-//								qDebug() << QString("auto linespacing: %1").arg(style.lineSpacing());
-							}
-							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);
+						goNextColumn = true;
 					}
 				}
-				if ( outs || SpecialChars::isBreak(hl->ch, (Cols > 1)) )
+				if (current.line.firstItem <= current.line.lastItem && current.itemsInLine > 0)
 				{
-					if (outs && !current.isEndOfLine(hl->glyph.wide() + style.rightMargin()))
+					if (current.addLine && current.breakIndex >= 0)
 					{
-						if (( hl->ch == SpecialChars::PARSEP || hl->ch == SpecialChars::LINEBREAK) 
-							&& current.hasDropCap)
+						if (itemText.charStyle(current.line.firstItem).effects() & ScStyle_DropCap)
 						{
-							current.hasDropCap = false;
-							if (current.yPos < maxDY)
-								current.yPos = maxDY;
-//							qDebug() << QString("after dropcaps: y=%1 maxDY=%2").arg(current.yPos).arg(maxDY);
+							// put line back to top
+							current.line.y -= DropCapDrop;
+							itemText.item(current.line.firstItem)->glyph.yoffset += DropCapDrop;
 						}
-						bool fromOut = true;
-						double BotOffset = desc+extra.Bottom+lineCorr;
-						while (!current.isEndOfLine(style.rightMargin()))
+						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.xPos++;
-							if (current.isEndOfLine(style.rightMargin()))
+							current.restartX = current.xPos;
+							if (current.addLeftIndent)
 							{
-								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());
-
-								if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-									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;
-									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;
+								current.addLeftIndent = false;
+								current.wasFirstInRow = true;
 							}
-							// #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
+					else if (!inOverflow && !current.afterOverflow && current.lastInRowLine)
 					{
-						if (( hl->ch == SpecialChars::PARSEP || hl->ch == SpecialChars::LINEBREAK ) 
-							&& current.hasDropCap)
+						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 dropcap2: y=%1+%2").arg(current.yPos).arg(maxDY);
+							current.restartX = current.xPos = current.colLeft;
+							maxDX = 0;
 						}
-//						qDebug() << QString("layout: next lower3 grid=%1 x %2").arg(style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing).arg(m_Doc->typographicSettings.valueBaseGrid);
-
-
-						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
-						{
-//							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
-							//current.yPos += style.lineSpacing();
-							const  ParagraphStyle& pStyle = itemText.paragraphStyle(a+1);
-							double lineSpacing = pStyle.lineSpacing();
-							if (pStyle.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing)
-								lineSpacing = pStyle.charStyle().font().height(pStyle.charStyle().fontSize() / 10.0);
-							else if (pStyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
-								lineSpacing = m_Doc->typographicSettings.valueBaseGrid;
-							current.yPos += lineSpacing;
-						}
-						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;
-						}
 					}
+					lastLineY = current.rowDesc;
+					current.mustLineEnd = current.colRight;
+					current.restartRowIndex = current.restartIndex;
 				}
-				
-
-				// calc. needed vertical space
-				// Let’s try to change into "calc. _wanted_ vertical space" - pm
-				if (current.itemsInLine != 0)
+				if (inOverflow)
 				{
-					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;
-					}
+					current.afterOverflow = true;
+					inOverflow = false;
+					current.addLeftIndent = false;
+					current.recalculateY = false;
 				}
-				
-				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)
-					; //qDebug() << QString("layout: empty line %1 - %2").arg(current.line.firstItem).arg(current.line.lastItem);
-				else if (current.itemsInLine > 0)
-					itemText.appendLine(current.line);
+				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)
@@ -2122,16 +2165,41 @@
 					current.column++;
 					if (current.column < Cols)
 					{
-						current.nextColumn(asce);
+						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);
+				}
+			}
 		}
 		if (goNoRoom)
 		{
@@ -2139,18 +2207,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 (current.itemsInLine >0)
+		{
+			int a = itemText.length()-1;
+			hl = a >=0 ? itemText.item(a) : NULL;
+			current.breakLine(itemText, style, firstLineOffset(), a);
 
-//		if (style.alignment() != 0)
-		{
+			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)
@@ -2174,26 +2259,18 @@
 					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;
+			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) {
 			itemText.appendLine(current.line);
+			current.startOfCol = false;
 		}
 	}
 	MaxChars = itemText.length();
@@ -3563,8 +3639,6 @@
 	
 }
 
-#endif  //NLS_PROTO
-
 bool PageItem_TextFrame::createInfoGroup(QFrame *infoGroup, QGridLayout *infoGroupLayout)
 {
 	int Parag = 0;
formatting5.patch (84,636 bytes)   

cezaryece

2011-09-27 18:54

updater   ~0026916

ok, issue with empty lines fixed in formatting5.patch

jghali

2011-09-28 20:35

administrator   ~0026925

Arghh, found another regression :
- create two text frames and link them
- insert sample text so that text runs inside second frame
- type 'Enter' in second frame in the middle of text
- a red square will appear t the place "Enter" was typed

jghali

2011-10-01 15:37

administrator   ~0026938

Fixed that last issue by commenting out the corresponding lines and committed patch. Thanks again, cezaryece!

Note : I created a clone of this issue for porting patch to 1.5.0svn

cezaryece

2011-10-02 06:59

updater   ~0026944

0009902 you can also set as solved

rdebel

2011-10-17 07:43

reporter   ~0027028

Just with the most recent version of 140svn I discovered following regression:
Create Textframe, Insert some underscore followed by some text. First line offset set to "max. ascent". So far everything is fine. Then insert a tabulator (tab-key) between underscore and text. The underscores will move to right above the text. See uploaded snapshot.

rdebel

2011-10-17 07:44

reporter  

snapshot_error.png (1,331 bytes)   
snapshot_error.png (1,331 bytes)   

cezaryece

2011-10-17 12:55

updater  

10251_c27028.patch (598 bytes)   
Index: Version135/Scribus/scribus/pageitem_textframe.cpp
===================================================================
--- Version135/Scribus/scribus/pageitem_textframe.cpp	(wersja 16898)
+++ Version135/Scribus/scribus/pageitem_textframe.cpp	(kopia robocza)
@@ -1399,6 +1399,8 @@
 			}
 			else
 				maxYAsc = static_cast<int>(floor(current.yPos - qMax(realAsce, asce)));
+			//fix for glyphs with negative realAsce value
+			maxYAsc = qMax(maxYAsc, 0);
 			maxYDesc = static_cast<int>(ceil(current.yPos + qMax(realDesc, desc)));
 
 			if (current.itemsInLine == 0 && !current.afterOverflow)
10251_c27028.patch (598 bytes)   

cezaryece

2011-10-17 12:56

updater   ~0027032

fix in 10251_c27028.patch

cbradney

2011-10-17 21:36

administrator   ~0027039

Final patch is in svn/rc6. Please raise any new issues in related bugs or open new bugs.

Issue History

Date Modified Username Field Change
2011-09-08 10:20 cezaryece New Issue
2011-09-08 10:20 cezaryece File Added: formatting.patch
2011-09-08 10:20 cezaryece File Added: formatting patch.sla
2011-09-08 10:21 cezaryece File Added: formating_wrong.jpg
2011-09-08 10:21 cezaryece File Added: formating_good.jpg
2011-09-10 21:49 jghali Note Added: 0026848
2011-09-11 15:18 jghali Note Added: 0026850
2011-09-11 15:55 plinnell Note Added: 0026851
2011-09-11 15:57 plinnell File Added: textwithpatch.png
2011-09-12 06:22 cezaryece Note Added: 0026854
2011-09-13 13:37 cezaryece File Added: formatting2.patch
2011-09-13 13:39 cezaryece Note Added: 0026859
2011-09-13 20:59 jghali Note Added: 0026862
2011-09-19 11:14 cezaryece File Added: formatting3.patch
2011-09-19 11:15 cezaryece Note Added: 0026890
2011-09-19 21:40 jghali Note Added: 0026892
2011-09-26 12:45 cezaryece File Added: formatting4.patch
2011-09-26 12:49 cezaryece Note Added: 0026907
2011-09-26 20:03 jghali Note Added: 0026909
2011-09-27 12:21 cezaryece Note Added: 0026914
2011-09-27 18:54 cezaryece File Added: formatting5.patch
2011-09-27 18:54 cezaryece Note Added: 0026916
2011-09-28 20:35 jghali Note Added: 0026925
2011-10-01 15:35 jghali Issue cloned: 0010294
2011-10-01 15:37 jghali Note Added: 0026938
2011-10-01 15:37 jghali Status new => resolved
2011-10-01 15:37 jghali Fixed in Version => 1.4.0svn
2011-10-01 15:37 jghali Resolution open => fixed
2011-10-01 15:37 jghali Assigned To => jghali
2011-10-02 06:59 cezaryece Note Added: 0026944
2011-10-05 20:02 cbradney Relationship added related to 0009932
2011-10-05 20:02 cbradney Relationship added related to 0009436
2011-10-05 20:03 cbradney Relationship added related to 0005891
2011-10-17 07:43 rdebel Note Added: 0027028
2011-10-17 07:44 rdebel File Added: snapshot_error.png
2011-10-17 12:55 cezaryece File Added: 10251_c27028.patch
2011-10-17 12:56 cezaryece Note Added: 0027032
2011-10-17 18:55 cbradney Status resolved => closed
2011-10-17 21:36 cbradney Note Added: 0027039
2012-02-19 17:21 jghali Relationship added related to 0008538
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