View Issue Details

IDProjectCategoryView StatusLast Update
0016129ScribusImport / Exportpublic2020-06-21 12:39
Reporteroliverthered Assigned Tojghali  
PrioritynormalSeverityminorReproducibilityalways
Status closedResolutionduplicate 
PlatformanyOSanyOS Versionany
Product Version1.5.6.svn 
Summary0016129: basic textframe and text rendering
Descriptionnothing special, just setup a textframe with some defaults and use the framework to set it's size and fill it with text
Steps To Reproducetry to import a pdf file that contains text into scribus
Additional Informationthis patch and the next one (which will be the debugging for this series of patches) will finish off the basic functionality and give you something visual inb scribus to play with.
Tagsimport, patch, PDF, pdf import
PatchYes

Relationships

duplicate of 0016142 closedjghali Preliminary support for importing PDF text as text 

Activities

oliverthered

2020-06-03 20:42

reporter  

basictextframeandtextrendering.diff (16,681 bytes)   
 scribus/plugins/import/pdf/slaoutput.cpp | 260 ++++++++++++++++++++++++++-----
 scribus/plugins/import/pdf/slaoutput.h   |   3 +
 2 files changed, 222 insertions(+), 41 deletions(-)

diff --git a/scribus/plugins/import/pdf/slaoutput.cpp b/scribus/plugins/import/pdf/slaoutput.cpp
index d050077d4..1799df9a9 100644
--- a/scribus/plugins/import/pdf/slaoutput.cpp
+++ b/scribus/plugins/import/pdf/slaoutput.cpp
@@ -3330,11 +3330,11 @@ void SlaOutputDev::drawChar(GfxState* state, double x, double y, double dx, doub
 				}
 				if ((textPath.size() > 3) && ((wh.x() != 0.0) || (wh.y() != 0.0)) && (textRenderingMode != 7))
 				{
-					PageItem* text_node = nullptr;
+					PageItem* textNode = nullptr;
 
 
 					int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, CommonStrings::None, CommonStrings::None);
-					text_node = m_doc->Items->at(z);
+					textNode = m_doc->Items->at(z);
 
 					// todo: merge this between vector and text implementations.
 
@@ -3343,15 +3343,15 @@ void SlaOutputDev::drawChar(GfxState* state, double x, double y, double dx, doub
 					mm.translate(x, -y);
 					textPath.map(mm);
 					textPath.map(m_ctm);
-					text_node->PoLine = textPath.copy();
-					setFillAndStrokeForPDF(state, text_node);
+					textNode->PoLine = textPath.copy();
+					setFillAndStrokeForPDF(state, textNode);
 					// Fill text rendering modes. See above
-					m_doc->adjustItemSize(text_node);
-					m_Elements->append(text_node);
+					m_doc->adjustItemSize(textNode);
+					m_Elements->append(textNode);
 					if (m_groupStack.count() != 0)
 					{
-						m_groupStack.top().Items.append(text_node);
-						applyMask(text_node);
+						m_groupStack.top().Items.append(textNode);
+						applyMask(textNode);
 					}
 				}
 				delete fontPath;
@@ -3435,6 +3435,19 @@ void SlaOutputDev::beginTextObject(GfxState *state)
 
 void SlaOutputDev::endTextObject(GfxState *state)
 {
+
+	if (importTextAsVectors == false && m_activeTextRegion->_lastXY != QPointF(-1, -1)) {
+		// Add the last glyph to the textregion
+		addGlyphAtPoint(glyphs.back().position, glyphs.back());
+		renderTextFrame();
+		delete m_activeTextRegion;
+		//Create and initilize a new TextRegion
+
+		m_activeTextRegion = new TextRegion();
+	}
+
+	delete addChar;
+	addChar = new AddFirstChar(this);
 //	qDebug() << "SlaOutputDev::endTextObject";
 	if (!m_clipTextPath.isEmpty())
 	{
@@ -3458,7 +3471,12 @@ void SlaOutputDev::endTextObject(GfxState *state)
 			else
 				ite = gElements.Items.first();
 			ite->setGroupClipping(false);
-			ite->setFillTransparency(1.0 - state->getFillOpacity());
+			if (importTextAsVectors == false) {
+				ite->setFillTransparency(1.0);
+			}
+			else {
+				ite->setFillTransparency(1.0 - state->getFillOpacity());
+			}
 			ite->setFillBlendmode(getBlendMode(state));
 			for (int as = 0; as < tmpSel->count(); ++as)
 			{
@@ -4096,13 +4114,25 @@ void SlaOutputDev::addGlyphAtPoint(QPointF newGlyphPoint, PdfGlyph new_glyph) {
 	}
 }
 
-void SlaOutputDev::setFillAndStrokeForPDF(GfxState* state, PageItem* text_node) {
+void TextRegion::renderToTextFrame(std::vector<PdfGlyph>& glyphs, PageItem* textNode, ParagraphStyle& pStyle)
+{
+	// nothing clever, just get all the body text in one lump and update the text frame
+	textNode->setWidthHeight(this->maxWidth, this->maxHeight);
+	QString bodyText = "";
+	for (int glyphIndex = this->textRegionLines.begin()->glyphIndex; glyphIndex <= this->textRegionLines.end()->segments.end()->glyphIndex; glyphIndex++) {
+		bodyText += glyphs[glyphIndex].code;
+	}
+	textNode->itemText.insertChars(bodyText);
+	textNode->frameTextEnd();
+}
+
+void SlaOutputDev::setFillAndStrokeForPDF(GfxState* state, PageItem* textNode) {
 
-	text_node->ClipEdited = true;
-	text_node->FrameType = 3;
-	text_node->setLineEnd(PLineEnd);
-	text_node->setLineJoin(PLineJoin);
-	text_node->setTextFlowMode(PageItem::TextFlowDisabled);
+	textNode->ClipEdited = true;
+	textNode->FrameType = 3;
+	textNode->setLineEnd(PLineEnd);
+	textNode->setLineJoin(PLineJoin);
+	textNode->setTextFlowMode(PageItem::TextFlowDisabled);
 
 	int textRenderingMode = state->getRender();
 	// Invisible or only used for clipping
@@ -4113,42 +4143,42 @@ void SlaOutputDev::setFillAndStrokeForPDF(GfxState* state, PageItem* text_node)
 	{
 
 		CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &CurrFillShade);
-		if (text_node->isTextFrame()) { //fill colour sets the background colour for the frame not the fill colour fore  the text			
-			text_node->setFillTransparency(1.0 - (state->getFillOpacity() > state->getStrokeOpacity() ? state->getFillOpacity() : state->getStrokeOpacity()));
-			text_node->setLineTransparency(1.0); // this ssets the transparency of the textbox border and we don't want to see it			
-			text_node->setFillColor(CommonStrings::None);
-			text_node->setLineColor(CommonStrings::None);
-			text_node->setLineWidth(0);//line  width doesn't effect drawing text, it creates a bounding box state->getTransformedLineWidth());
-			text_node->setFillShade(CurrFillShade);
+		if (textNode->isTextFrame()) { //fill colour sets the background colour for the frame not the fill colour fore  the text			
+			textNode->setFillTransparency(1.0 - (state->getFillOpacity() > state->getStrokeOpacity() ? state->getFillOpacity() : state->getStrokeOpacity()));
+			textNode->setLineTransparency(1.0); // this ssets the transparency of the textbox border and we don't want to see it			
+			textNode->setFillColor(CommonStrings::None);
+			textNode->setLineColor(CommonStrings::None);
+			textNode->setLineWidth(0);//line  width doesn't effect drawing text, it creates a bounding box state->getTransformedLineWidth());
+			textNode->setFillShade(CurrFillShade);
 		}
 		else {
-			text_node->setFillColor(CurrColorFill);
-			text_node->setFillShade(CurrFillShade);
-			text_node->setFillEvenOdd(false);
-			text_node->setFillTransparency(1.0 - state->getFillOpacity());
-			text_node->setFillBlendmode(getBlendMode(state));
+			textNode->setFillColor(CurrColorFill);
+			textNode->setFillShade(CurrFillShade);
+			textNode->setFillEvenOdd(false);
+			textNode->setFillTransparency(1.0 - state->getFillOpacity());
+			textNode->setFillBlendmode(getBlendMode(state));
 		}
 	}
 	// Stroke text rendering modes. See above
 	if (textRenderingMode == 1 || textRenderingMode == 2 || textRenderingMode == 5 || textRenderingMode == 6)
 	{
 		CurrColorStroke = getColor(state->getStrokeColorSpace(), state->getStrokeColor(), &CurrStrokeShade);
-		if (text_node->isTextFrame()) { //fil;l colour sets the background colour for the frame not the fill colour fore  the text			
-			text_node->setFillTransparency(1.0 - (state->getFillOpacity() > state->getStrokeOpacity() ? state->getFillOpacity() : state->getStrokeOpacity()));
-			text_node->setLineTransparency(1.0); // this sets the transparency of the textbox border and we don't want to see it			
-			text_node->setFillColor(CommonStrings::None); //TODO: Check if we ov erride the stroke colour with the fil,l colour when threre is a choice
-			text_node->setLineColor(CommonStrings::None);
-			text_node->setLineWidth(0);//line  width doesn't effect drawing text, it creates a bounding box state->getTransformedLineWidth());
-			text_node->setFillBlendmode(getBlendMode(state));
-			text_node->setFillShade(CurrFillShade);
+		if (textNode->isTextFrame()) { //fil;l colour sets the background colour for the frame not the fill colour fore  the text			
+			textNode->setFillTransparency(1.0 - (state->getFillOpacity() > state->getStrokeOpacity() ? state->getFillOpacity() : state->getStrokeOpacity()));
+			textNode->setLineTransparency(1.0); // this sets the transparency of the textbox border and we don't want to see it			
+			textNode->setFillColor(CommonStrings::None); //TODO: Check if we ov erride the stroke colour with the fil,l colour when threre is a choice
+			textNode->setLineColor(CommonStrings::None);
+			textNode->setLineWidth(0);//line  width doesn't effect drawing text, it creates a bounding box state->getTransformedLineWidth());
+			textNode->setFillBlendmode(getBlendMode(state));
+			textNode->setFillShade(CurrFillShade);
 		}
 		else {
-			text_node->setLineColor(CurrColorStroke);
-			text_node->setLineWidth(0);//line  width doesn't effect drawing text, it creates a bounding box state->getTransformedLineWidth());
-			text_node->setFillTransparency(1.0 - state->getFillOpacity() > state->getStrokeOpacity() ? state->getFillOpacity() : state->getStrokeOpacity());
-			text_node->setLineTransparency(1.0); // this sets the transparency of the textbox border and we don't want to see it
-			text_node->setLineBlendmode(getBlendMode(state));
-			text_node->setLineShade(CurrStrokeShade);
+			textNode->setLineColor(CurrColorStroke);
+			textNode->setLineWidth(0);//line  width doesn't effect drawing text, it creates a bounding box state->getTransformedLineWidth());
+			textNode->setFillTransparency(1.0 - state->getFillOpacity() > state->getStrokeOpacity() ? state->getFillOpacity() : state->getStrokeOpacity());
+			textNode->setLineTransparency(1.0); // this sets the transparency of the textbox border and we don't want to see it
+			textNode->setLineBlendmode(getBlendMode(state));
+			textNode->setLineShade(CurrStrokeShade);
 		}
 	}
 }
@@ -4180,6 +4210,154 @@ void SlaOutputDev::updateTextPos(GfxState* state) {
 void SlaOutputDev::renderTextFrame()
 {
 	//TODO: Implement, this should all be based on tyhe framework and using m_activeTextRegion
+	qDebug() << "_flushText()    m_doc->currentPage()->xOffset():" << m_doc->currentPage()->xOffset();
+	// Ignore empty strings
+	if (glyphs.empty()) {
+		// We don't clear the glyphs any more or at least until the whole page has been rendred glyphs.clear();
+		return;
+	}
+
+	//TODO: Look this up using the framework
+	const PdfGlyph& first_glyph = glyphs[0];// (*i);
+	// TODO: Use the framework for this, not currently supported
+	/*
+	int render_mode = first_glyph.render_mode;
+	// Ignore invisible characters
+	if (render_mode == 3) {
+		// We don't clear the glyphs any more or at least until the whole page has been rendred //_glyphs.clear();
+		return;
+	}
+	*/
+
+	qreal xCoor = m_doc->currentPage()->xOffset() + (double)first_glyph.position.x();
+	qreal yCoor = m_doc->currentPage()->initialHeight() - (m_doc->currentPage()->yOffset() + (double)first_glyph.position.y()); // don't know if y is top down or bottom up
+	double  lineWidth = 0.0;
+	/* colours don't get reset to CommonStrings::None often enough.*/
+	int z = m_doc->itemAdd(PageItem::TextFrame, PageItem::Rectangle, xCoor, yCoor, 40, 40, 0, CommonStrings::None, CommonStrings::None /* this->CurrColorStroke*/);//, PageItem::ItemKind::InlineItem);
+	PageItem* textNode = m_doc->Items->at(z);
+
+	ParagraphStyle& pStyle = (ParagraphStyle&)textNode->itemText.defaultStyle();
+	// set some hackish parameters up at first, line spacing can be calculated from the cursor position changes
+	pStyle.setLineSpacingMode(pStyle.AutomaticLineSpacing);
+	pStyle.setHyphenationMode(pStyle.AutomaticHyphenation);
+
+
+	// TODO: Implement thease using the framework
+	finishItem(textNode);
+	// FIXME: Implement thease using the framework
+	//_setFillAndStrokeForPdf(state, text_node);
+	//FIXME: Here's some dummy code for now with sednsible defaults, looks like state wasn't even needed
+	if (true)
+	{
+		textNode->ClipEdited = true;
+		textNode->FrameType = 3;
+		textNode->setLineEnd(PLineEnd);
+		textNode->setLineJoin(PLineJoin);
+		textNode->setTextFlowMode(PageItem::TextFlowDisabled);
+
+		textNode->setFillTransparency(1.0);
+		textNode->setLineTransparency(1.0); // this ssets the transparency of the textbox border and we don't want to see it			
+		textNode->setFillColor(CommonStrings::None);
+		textNode->setLineColor(CommonStrings::None);
+		textNode->setLineWidth(0);//line  width doesn't effect drawing text, it creates a bounding box state->getTransformedLineWidth());
+		textNode->setFillShade(CurrFillShade);
+	}
+
+
+	// Set text matrix... This need to be done so that the globaal world view that we rite out glyphs to is transformed correctly by the context matrix for each glyph, possibly anyhow.
+	/* FIXME: Setting the text matrix isn't supp;orted at the moment 
+	QTransform text_transform(_text_matrix);
+	text_transform.setMatrix(text_transform.m11(), text_transform.m12(), 0,
+		text_transform.m21(), text_transform.m22(), 0,
+		first_glyph.position.x(), first_glyph.position.y(), 1);
+		*/
+	/* todo, set the global transform
+	gchar *transform = sp_svg_transform_write(text_transform);
+	text_node->setAttribute("transform", transform);
+	g_free(transform);
+	*/
+	/*set the default charstyle to the style of the glyph, this needss fleshing out a little */
+
+	int shade = 100;
+	//TODO: This needs to come from the framework
+	//QString CurrColorText = getColor(state->getFillColorSpace(), state->getFillColor(), &shade);
+	//TODO: replace this with the framework
+	//applyTextStyleToCharStyle(pStyle.charStyle(), _glyphs[0].style->getFont().family(), CurrColorText, _glyphs[0].style->getFont().pointSizeF());// *_font_scaling);
+	textNode->invalid = true;
+	CharStyle& cStyle = (CharStyle&)pStyle.charStyle();
+	cStyle.setScaleH(1000.0);
+	cStyle.setScaleV(1000.0);
+	cStyle.setHyphenChar(SpecialChars::BLANK.unicode());
+
+	//text_node->itemText.setDefaultStyle(pStyle);
+	//FIXME: replace this with the framework
+	m_activeTextRegion->renderToTextFrame(glyphs, textNode, pStyle);
+	//parseText(glyphs, text_node, pStyle);
+	//FIXME: Paragraphs need to be implemented properly  this needs to be applied to the charstyle of the default pstyle
+	textNode->itemText.insertChars(SpecialChars::PARSEP, true);
+
+	//Set the shape so we don't clip all the text away.
+	FPointArray boundingBoxShape;
+	boundingBoxShape.resize(0);
+	boundingBoxShape.svgInit();
+
+	double bbosdoubles[32] = { 0,0
+							,0,0
+							,100,0
+							,100,0
+							,100,0
+							,100,0
+							,100,100
+							,100,100
+							,100,100
+							,100,100
+							,0,100
+							,0,100
+							,0,100
+							,0,100
+							,0,0
+							,0,0
+	};
+	boundingBoxShape.svgMoveTo(bbosdoubles[0], bbosdoubles[1]);
+	for (int a = 0; a < 16; a += 2)
+	{
+		boundingBoxShape.append(FPoint(bbosdoubles[a * 2], bbosdoubles[a * 2 + 1]));
+	}
+	boundingBoxShape.scale(textNode->width() / 100.0, textNode->height() / 100.0);
+
+	textNode->SetFrameShape(32, bbosdoubles);
+	textNode->ContourLine = textNode->PoLine.copy();
+
+	m_doc->Items->removeLast();
+	m_Elements->append(textNode);
+	if (m_groupStack.count() != 0)
+	{
+		m_groupStack.top().Items.append(textNode);
+		applyMask(textNode);
+	}
+
+}
+
+/*code mostly taken from importodg.cpp which also supports some line styles and more fill options etc...*/
+//FIXME: This needs to be implemented based on the framework
+void SlaOutputDev::finishItem(PageItem* item) {
+	item->ClipEdited = true;
+	item->FrameType = 3;
+
+	//this requires that PoLine is set
+	//FPoint wh = getMaxClipF(&item->PoLine);
+	//item->setWidthHeight(wh.x(), wh.y());
+	//item->Clip = flattenPath(item->PoLine, item->Segments);
+	item->OldB2 = item->width();
+	item->OldH2 = item->height();
+	item->updateClip();
+	item->OwnPage = m_doc->OnPage(item);
+
+	//item->setFillTransparency(1.0 - state->getFillOpacity() > state->getStrokeOpacity() ? state->getFillOpacity() : state->getStrokeOpacity());
+	//item->setLineTransparency(1.0);
+
+	//item->setStartArrowIndex(0);
+	//item->setEndArrowIndex(0);
 }
 
 
diff --git a/scribus/plugins/import/pdf/slaoutput.h b/scribus/plugins/import/pdf/slaoutput.h
index a179ac285..27aea216c 100644
--- a/scribus/plugins/import/pdf/slaoutput.h
+++ b/scribus/plugins/import/pdf/slaoutput.h
@@ -189,6 +189,7 @@ public:
 	qreal maxWidth = -1;
 	QPointF _lineBaseXY = QPointF(-1, -1); //updated with the best match left value from all the textRegionLines and the best bottom value from the textRegionLines.segments;
 	QPointF _lastXY = QPointF(-1, -1);
+	void renderToTextFrame(std::vector<PdfGlyph>& glyphs, PageItem* text_node, ParagraphStyle& pStyle);
 };
 
 class AddCharInterface
@@ -370,6 +371,8 @@ private:
 	void updateTextPos(GfxState* state) override;
 	void renderTextFrame();
 
+	void finishItem(PageItem* item);
+
 	bool pathIsClosed {false};
 	QString CurrColorFill;
 	int CurrFillShade {100};

oliverthered

2020-06-03 20:49

reporter   ~0047665

I'll upload the patch with the bug fixes in up to this ticket to save creating another ticket and getting blocked again.

jghali

2020-06-03 21:58

administrator   ~0047669

>> I'll upload the patch with the bug fixes

Honestly we would prefer if you would not upload multiple patches of what looks like a work in progress: some of the patches indeed modify code from previous patches, so these should ultimately be merged. Also if you are already aware these patches contains bugs, then please fix the bugs first, test your work, and upload patches afterwards. If we tests patches and encounter easily reproduceable bugs or regressions vs current code, it's unlikely we will commit them.

Also I'd prefer you upload your patches to a single issue, it seems 0016103 already fit that purpose. It makes it easier to track patches which are related. Ultimately we would be also fine if you upload a single consolidated patch of your work.

oliverthered

2020-06-03 22:18

reporter   ~0047670

this patch fixes all the crash bugs
alltherendercrashbugsfixed.diff (10,855 bytes)   
 scribus/plugins/import/pdf/slaoutput.cpp | 89 +++++++++++++++++++++++++-------
 scribus/plugins/import/pdf/slaoutput.h   |  3 +-
 2 files changed, 73 insertions(+), 19 deletions(-)

diff --git a/scribus/plugins/import/pdf/slaoutput.cpp b/scribus/plugins/import/pdf/slaoutput.cpp
index 1799df9a9..89c686202 100644
--- a/scribus/plugins/import/pdf/slaoutput.cpp
+++ b/scribus/plugins/import/pdf/slaoutput.cpp
@@ -284,6 +284,8 @@ SlaOutputDev::SlaOutputDev(ScribusDoc* doc, QList<PageItem*> *Elements, QStringL
 	currentLayer = m_doc->activeLayer();
 	layersSetByOCG = false;
 	importTextAsVectors - true;
+	// FIXME: textregions should be an array
+	m_activeTextRegion = new TextRegion();
 	//FIXME: can probably have an array of these instead of creting new ones and deleting them
 	addChar = new AddFirstChar(this);
 }
@@ -3979,7 +3981,7 @@ bool SlaOutputDev::linearTest(QPointF point, bool xInLimits, bool yInLimits) {
 		if (closeToX(m_activeTextRegion->textRegioBasenOrigin.x(), point.x()))
 		{
 			if (closeToY(point.y(), m_activeTextRegion->_lastXY.y())) {
-				if (closeToX(m_activeTextRegion->textRegionLines[m_activeTextRegion->textRegionLines.size() - 2].width, m_activeTextRegion->maxWidth)) {
+				if ((m_activeTextRegion->textRegionLines.size() >= 2) && closeToX(m_activeTextRegion->textRegionLines[m_activeTextRegion->textRegionLines.size() - 2].width, m_activeTextRegion->maxWidth)) {
 					//TODO: add a new line and update the deltas
 					pass = true;
 				}
@@ -3989,6 +3991,32 @@ bool SlaOutputDev::linearTest(QPointF point, bool xInLimits, bool yInLimits) {
 	return pass;
 }
 
+// Just perform some basic checks to see if newPoint can reasonably be asscribed to the current textframe.
+bool SlaOutputDev::isRegionConcurrent(QPointF newPoint)
+{	
+	if (m_activeTextRegion->_lineBaseXY == QPointF(-1, -1))
+	{
+		m_activeTextRegion->_lineBaseXY = newPoint;
+	}
+	if (m_activeTextRegion->_lastXY == QPointF(-1, -1))
+	{
+		m_activeTextRegion->_lastXY = newPoint;
+	}
+	//TODO: I need to write down which ones we want so I can work it all out, for now just some basic fuzzy matching support.
+	bool xInLimits = false;
+	if (closeToX(newPoint.x(), m_activeTextRegion->_lastXY.x()))
+	{
+		xInLimits = true;
+	}
+	bool yInLimits = false;
+	if (closeToY(newPoint.y(), m_activeTextRegion->_lastXY.y()))
+	{
+		yInLimits = true;
+	}
+	bool pass = linearTest(newPoint, xInLimits, yInLimits);
+	return pass;
+}
+
 
 void SlaOutputDev::moveToPoint(QPointF newPoint)
 {
@@ -4018,13 +4046,20 @@ void SlaOutputDev::moveToPoint(QPointF newPoint)
 	if (pass)
 	{
 		// FIXME: only do this under certain circumstances, we can merge two or move boxes together horrizontally and don't need a new region line on the  m_activeTextRegion we need one on the segments list on textRegionLines.end() . infact this should be done in the linear test function
-		TextRegionLine textRegionLine = TextRegionLine();
-		textRegionLine.baseOrigin = QPointF(newPoint.x(), m_activeTextRegion->_lastXY.y() + 1);
-		textRegionLine.width = 0;
-		textRegionLine.maxHeight = newPoint.y() - m_activeTextRegion->_lastXY.y();
-		textRegionLine.modeHeigth = newPoint.y() - m_activeTextRegion->_lastXY.y();
-		//FIXME: We haven't actually started off any segments yet so don't add them textRegionLine.segments.push_back(TextRegionLine())
-		m_activeTextRegion->textRegionLines.push_back(textRegionLine);
+		
+			TextRegionLine& textRegionLine = TextRegionLine();;
+			if ((m_activeTextRegion->textRegionLines.size() != 0) && (m_activeTextRegion->textRegionLines.back().glyphIndex == -1)) {
+				textRegionLine = (TextRegionLine&)m_activeTextRegion->textRegionLines.back();
+			}
+			textRegionLine.baseOrigin = QPointF(newPoint.x(), m_activeTextRegion->_lastXY.y() + 1);
+			textRegionLine.width = 0;
+			textRegionLine.maxHeight = newPoint.y() - m_activeTextRegion->_lastXY.y();
+			textRegionLine.modeHeigth = newPoint.y() - m_activeTextRegion->_lastXY.y();
+			//FIXME: We haven't actually started off any segments yet so don't add them textRegionLine.segments.push_back(TextRegionLine())
+			if ((m_activeTextRegion->textRegionLines.size() == 0) || (m_activeTextRegion->textRegionLines.back().glyphIndex != -1)) {
+				m_activeTextRegion->textRegionLines.push_back(textRegionLine);
+			}
+		
 	}
 	// if nothing can be done then write out the textregioin and delete it and create a new trextrext and re-adcfd ther char, set the pos etc...
 	if (pass == false)
@@ -4081,13 +4116,30 @@ void SlaOutputDev::addGlyphAtPoint(QPointF newGlyphPoint, PdfGlyph new_glyph) {
 	else {
 		//TODO: possible don't store the glyphs on the textRegion, well certainly not like this, we only need to check bounbdry and feature positions
 		//m_activeTextRegion->glyphs.push_back(new_glyph);
-
+		if (m_activeTextRegion->textRegionLines.size() == 0)
+		{
+			TextRegionLine newTextRegionLine = TextRegionLine();
+			newTextRegionLine.glyphIndex = glyphs.size() - 1;
+			newTextRegionLine.width = new_glyph.dx;
+			m_activeTextRegion->textRegionLines.push_back(newTextRegionLine);
+		}
 		//at the moment a new segment only gets added when the line is created. a new segment should also get added if there's any change in style or layout etc...but that feature can be added llater, it's not needed for basic textframe support with no style.
-		m_activeTextRegion->textRegionLines.back().glyphIndex = glyphs.size() - 1;
+		if (m_activeTextRegion->textRegionLines.back().glyphIndex == -1) {
+			
+			TextRegionLine& textRegionLine = m_activeTextRegion->textRegionLines.back();
+			textRegionLine.glyphIndex = glyphs.size() - 1;			
+			textRegionLine.width = 0;
+			textRegionLine.baseOrigin = QPointF(newGlyphPoint.x(), newGlyphPoint.y());
+			//FIXME: shouldn't i use lastxy here
+			textRegionLine.modeHeigth = newGlyphPoint.y() - textRegionLine.baseOrigin.y();
+			textRegionLine.maxHeight = newGlyphPoint.y() - textRegionLine.baseOrigin.y();
+		}
 		if (m_activeTextRegion->textRegionLines.back().segments.empty())
 		{
 			// add a new segment
 			TextRegionLine newSegment = TextRegionLine();
+			newSegment.glyphIndex = m_activeTextRegion->textRegionLines.back().glyphIndex;
+			newSegment.width = 0;					
 			m_activeTextRegion->textRegionLines.back().segments.push_back(newSegment);
 		}
 		if (m_activeTextRegion->textRegionLines.back().segments.back().width == 0)
@@ -4097,7 +4149,7 @@ void SlaOutputDev::addGlyphAtPoint(QPointF newGlyphPoint, PdfGlyph new_glyph) {
 			segment.baseOrigin = QPointF(newGlyphPoint.x(), m_activeTextRegion->textRegionLines.back().baseOrigin.y());
 			segment.modeHeigth = newGlyphPoint.y() - segment.baseOrigin.y();
 			segment.maxHeight = newGlyphPoint.y() - segment.baseOrigin.y();
-			//FIXME:Set thease properly
+			//FIXME:Set thease properly using lastxy &co.
 			m_activeTextRegion->textRegionLines.back().maxHeight = m_activeTextRegion->textRegionLines.back().maxHeight > segment.maxHeight ? m_activeTextRegion->textRegionLines.back().maxHeight : segment.maxHeight;
 			m_activeTextRegion->textRegionLines.back().modeHeigth = segment.modeHeigth; //FIXME: this needs to be calculated based on the heights of all the segments
 			m_activeTextRegion->textRegionLines.back().width += segment.width;
@@ -4119,7 +4171,7 @@ void TextRegion::renderToTextFrame(std::vector<PdfGlyph>& glyphs, PageItem* text
 	// nothing clever, just get all the body text in one lump and update the text frame
 	textNode->setWidthHeight(this->maxWidth, this->maxHeight);
 	QString bodyText = "";
-	for (int glyphIndex = this->textRegionLines.begin()->glyphIndex; glyphIndex <= this->textRegionLines.end()->segments.end()->glyphIndex; glyphIndex++) {
+	for (int glyphIndex = this->textRegionLines.begin()->glyphIndex; glyphIndex <= this->textRegionLines.back().segments.back().glyphIndex; glyphIndex++) {
 		bodyText += glyphs[glyphIndex].code;
 	}
 	textNode->itemText.insertChars(bodyText);
@@ -4191,10 +4243,10 @@ void SlaOutputDev::updateTextPos(GfxState* state) {
 
 	QPointF new_position = QPointF(state->getCurX(), state->getCurY());
 	//check to see if we are in a new text region
-	if (m_activeTextRegion->textRegioBasenOrigin == QPointF(-1, -1))
+	if (m_activeTextRegion->textRegioBasenOrigin == QPointF(-1, -1) || 
+		(m_activeTextRegion->textRegionLines.back().glyphIndex == -1))// && !isRegionConcurrent(new_position)))
 	{
 		//FIXME: Actually put this in the correct class	
-			//QPointF textRegionOrigin = new_position;
 		m_activeTextRegion->textRegioBasenOrigin = new_position;
 
 	}
@@ -4377,12 +4429,9 @@ void AddFirstChar::addChar(GfxState* state, double x, double y, double dx, doubl
 	new_glyph.dy = dy;
 
 	//FIXME: have an array of differnt types of addchar class instead of creating and destroying them all the time
-	delete m_slaOutputDev->addChar;
+	AddCharInterface *charToDelete = m_slaOutputDev->addChar;
 	m_slaOutputDev->addChar = new AddBasicChar(m_slaOutputDev);
 
-	//only need to be called for the very first point
-	m_slaOutputDev->addGlyphAtPoint(QPointF(x, y), new_glyph);
-
 	// Convert the character to UTF-16 since that's our SVG document's encoding	
 	for (int i = 0; i < uLen; i++) {
 		new_glyph.code += (char16_t)u[i];
@@ -4391,6 +4440,10 @@ void AddFirstChar::addChar(GfxState* state, double x, double y, double dx, doubl
 	new_glyph.rise = state->getRise();
 	m_slaOutputDev->glyphs.push_back(new_glyph);
 
+	//only need to be called for the very first point
+	m_slaOutputDev->addGlyphAtPoint(QPointF(x, y), new_glyph);
+
+	delete charToDelete;
 }
 
 void AddBasicChar::addChar(GfxState* state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, int nBytes, Unicode const* u, int uLen)
diff --git a/scribus/plugins/import/pdf/slaoutput.h b/scribus/plugins/import/pdf/slaoutput.h
index 27aea216c..9261f8b45 100644
--- a/scribus/plugins/import/pdf/slaoutput.h
+++ b/scribus/plugins/import/pdf/slaoutput.h
@@ -174,7 +174,7 @@ public:
 	qreal maxHeight = -1;
 	qreal modeHeigth = -1;
 	qreal width = -1;
-	uint glyphIndex;
+	int glyphIndex = -1;
 	QPointF baseOrigin = QPointF(-1, -1);
 	std::vector<TextRegionLine> segments = std::vector<TextRegionLine>();
 
@@ -365,6 +365,7 @@ private:
 	bool adjunctLesser(qreal testY, qreal lastY, qreal baseY);
 	bool adjunctGreater(qreal testY, qreal lastY, qreal baseY);
 	bool linearTest(QPointF point, bool xInLimits, bool yInLimits);
+	bool isRegionConcurrent(QPointF newPoint);
 	void moveToPoint(QPointF newPoint);	
 	//void addChar(GfxState* state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, int nBytes, Unicode const* u, int uLen);
 	void setFillAndStrokeForPDF(GfxState* state, PageItem* text_node);
alltherendercrashbugsfixed.diff (10,855 bytes)   

oliverthered

2020-06-04 03:33

reporter   ~0047671

the final patch for this text now lays out reasonably well but there is no font support.
finalize basic collated text using the framework.diff (16,831 bytes)   
 scribus/plugins/import/pdf/slaoutput.cpp | 121 ++++++++++++++++++++-----------
 1 file changed, 80 insertions(+), 41 deletions(-)

diff --git a/scribus/plugins/import/pdf/slaoutput.cpp b/scribus/plugins/import/pdf/slaoutput.cpp
index 86b1214ba..82b8e3ef0 100644
--- a/scribus/plugins/import/pdf/slaoutput.cpp
+++ b/scribus/plugins/import/pdf/slaoutput.cpp
@@ -3474,7 +3474,7 @@ void SlaOutputDev::endTextObject(GfxState *state)
 				ite = gElements.Items.first();
 			ite->setGroupClipping(false);
 			if (importTextAsVectors == false) {
-				ite->setFillTransparency(1.0);
+				ite->setFillTransparency(1.0 - state->getFillOpacity());
 			}
 			else {
 				ite->setFillTransparency(1.0 - state->getFillOpacity());
@@ -3984,6 +3984,9 @@ bool SlaOutputDev::linearTest(QPointF point, bool xInLimits, bool yInLimits) {
 				if ((m_activeTextRegion->textRegionLines.size() >= 2) && closeToX(m_activeTextRegion->textRegionLines[m_activeTextRegion->textRegionLines.size() - 2].width, m_activeTextRegion->maxWidth)) {
 					//TODO: add a new line and update the deltas
 					pass = true;
+				}   // we only have the first line so far, so pass without much of a test.
+				else if (m_activeTextRegion->textRegionLines.size() == 1) {
+					pass = true;
 				}
 			}
 		}
@@ -4030,20 +4033,20 @@ void SlaOutputDev::moveToPoint(QPointF newPoint)
 	{
 		m_activeTextRegion->_lastXY = newPoint;
 	}
-	if (m_activeTextRegion->modeHeigth == -1)
+	if (m_activeTextRegion->modeHeigth == -1 || (abs(newPoint.y() - m_activeTextRegion->_lastXY.y()) + 1) > m_activeTextRegion->modeHeigth)
 	{
 		// FIXME: do a propper lookup of the height
-		if (m_activeTextRegion->_lastXY.y() < newPoint.y() && m_activeTextRegion->_lastXY.y() > 0)
+		if (abs(m_activeTextRegion->_lastXY.y() - newPoint.y()) > 5 && m_activeTextRegion->_lastXY.y() > 0)
 		{
-			m_activeTextRegion->modeHeigth = newPoint.y() - m_activeTextRegion->_lastXY.y();
+			m_activeTextRegion->modeHeigth = abs(newPoint.y() - m_activeTextRegion->_lastXY.y()) + 1;
 		}
 		else 
 		{
 			//FIXME: Just initilize modeHeight with anything so that tests don't fail because it's -1
 			//or I could always pass the test if it's -1 which may bew a better idea.
 			m_activeTextRegion->modeHeigth = 10;
-		}
-	}
+		}		
+	}	
 	//TODO: I need to write down which ones we want so I can work it all out, for now just some basic fuzzy matching support.
 	bool xInLimits = false;
 	if (closeToX(newPoint.x(), m_activeTextRegion->_lastXY.x()))
@@ -4061,18 +4064,40 @@ void SlaOutputDev::moveToPoint(QPointF newPoint)
 	if (pass)
 	{
 		// FIXME: only do this under certain circumstances, we can merge two or move boxes together horrizontally and don't need a new region line on the  m_activeTextRegion we need one on the segments list on textRegionLines.end() . infact this should be done in the linear test function
-		
-			TextRegionLine& textRegionLine = TextRegionLine();;
-			if ((m_activeTextRegion->textRegionLines.size() != 0) && (m_activeTextRegion->textRegionLines.back().glyphIndex == -1)) {
+			// TODO: finish off the parameters of the last textRegionLine and make sure were not just adding a segment
+			TextRegionLine& textRegionLine = TextRegionLine();
+			// we slweays need to set thease defaults if were adding
+			textRegionLine.baseOrigin = QPointF(newPoint.x(), newPoint.y());
+			textRegionLine.width = 0;
+			if ((m_activeTextRegion->textRegionLines.size() != 0) && ((m_activeTextRegion->textRegionLines.back().glyphIndex == -1) || this->coLinera(m_activeTextRegion->textRegionLines.back().baseOrigin.y(), newPoint.y()))) 
+			{
 				textRegionLine = (TextRegionLine&)m_activeTextRegion->textRegionLines.back();
+				if (!this->coLinera(m_activeTextRegion->textRegionLines.back().baseOrigin.y(), newPoint.y())) {
+					textRegionLine.baseOrigin = QPointF(newPoint.x(), m_activeTextRegion->_lastXY.y());
+					textRegionLine.width = 0;
+				}
+				else {
+					// If were not adding a new line were adding a new segment
+					textRegionLine = TextRegionLine();
+					textRegionLine.baseOrigin = QPointF(newPoint.x(), newPoint.y());
+					textRegionLine.width = 0;
+				}
 			}
-			textRegionLine.baseOrigin = QPointF(newPoint.x(), m_activeTextRegion->_lastXY.y() + 1);
-			textRegionLine.width = 0;
-			textRegionLine.maxHeight = newPoint.y() - m_activeTextRegion->_lastXY.y();
-			textRegionLine.modeHeigth = newPoint.y() - m_activeTextRegion->_lastXY.y();
-			//FIXME: We haven't actually started off any segments yet so don't add them textRegionLine.segments.push_back(TextRegionLine())
-			if ((m_activeTextRegion->textRegionLines.size() == 0) || (m_activeTextRegion->textRegionLines.back().glyphIndex != -1)) {
+
+			textRegionLine.maxHeight = abs(newPoint.y() - m_activeTextRegion->_lastXY.y()) > textRegionLine.maxHeight ? abs(newPoint.y() - m_activeTextRegion->_lastXY.y()) : textRegionLine.maxHeight;
+			m_activeTextRegion->maxHeight = abs(m_activeTextRegion->textRegioBasenOrigin.y() - newPoint.y()) > m_activeTextRegion->maxHeight ? abs(m_activeTextRegion->textRegioBasenOrigin.y() - newPoint.y()) : m_activeTextRegion->maxHeight;
+			//FIXME: this should really be the most common height accross all segments and lines.
+			textRegionLine.modeHeigth = newPoint.y() - m_activeTextRegion->_lastXY.y() > m_activeTextRegion->modeHeigth ? newPoint.y() - m_activeTextRegion->_lastXY.y() : m_activeTextRegion->modeHeigth;
+			// check to see if were a new line or the first line and we have already had a character set on this line			
+			if ((m_activeTextRegion->textRegionLines.size() == 0) || ((m_activeTextRegion->textRegionLines.back().glyphIndex != -1) && !(!this->coLinera(m_activeTextRegion->textRegionLines.back().baseOrigin.y(), newPoint.y())))) {
 				m_activeTextRegion->textRegionLines.push_back(textRegionLine);
+			} // Otherwise see if were adding a new segment, changes is styles of the text etc... should trigger addint a new character so the glyphindex should be gaurenteed to be set if were adding a new segment
+			else if (m_activeTextRegion->textRegionLines.back().glyphIndex != -1 && (this->coLinera(m_activeTextRegion->textRegionLines.back().baseOrigin.y(), newPoint.y()))) {				
+				if (m_activeTextRegion->textRegionLines.back().segments.size() > 0) {
+					m_activeTextRegion->textRegionLines.back().segments.back().width = abs(m_activeTextRegion->textRegionLines.back().segments.back().baseOrigin.x() - newPoint.x());					
+				}
+				m_activeTextRegion->textRegionLines.back().segments.push_back(textRegionLine);
+				m_activeTextRegion->textRegionLines.back().width = abs(m_activeTextRegion->textRegionLines.back().baseOrigin.x() - newPoint.x());
 			}
 			m_activeTextRegion->_lastXY = newPoint;
 	}
@@ -4107,14 +4132,14 @@ void SlaOutputDev::addGlyphAtPoint(QPointF newGlyphPoint, PdfGlyph new_glyph) {
 	if (m_activeTextRegion->modeHeigth == -1)
 	{
 		// FIXME: do a propper lookup of the height
-		m_activeTextRegion->modeHeigth = new_glyph.dx;
+		m_activeTextRegion->modeHeigth = new_glyph.dx * 2;
 	}
 	if (m_activeTextRegion->_lastXY == QPointF(-1, -1)) {
 		m_activeTextRegion->_lastXY = newGlyphPoint;
 	}
 	if (m_activeTextRegion->_lineBaseXY == QPointF(-1, -1)) {
 		m_activeTextRegion->_lineBaseXY = newGlyphPoint;
-	}
+	}	
 	bool xInLimits = false;
 	if (closeToX(movedGlyphPoint.x(), m_activeTextRegion->_lastXY.x())) {
 		xInLimits = true;
@@ -4123,11 +4148,12 @@ void SlaOutputDev::addGlyphAtPoint(QPointF newGlyphPoint, PdfGlyph new_glyph) {
 	if (closeToY(movedGlyphPoint.y(), m_activeTextRegion->_lastXY.y())) {
 		yInLimits = true;
 	}
-	bool pass = linearTest(movedGlyphPoint, xInLimits, yInLimits);
-
+	bool pass = linearTest(movedGlyphPoint, xInLimits, yInLimits);	
 	// if nothing can be done then write out the textregioin and delete it and create a new trextrext and re-adcfd ther char, set the pos etc...
 	if (pass == false) {
-
+		qDebug("FIXME: Rogue glyph detected, this should never happen because the copuror should move before glyphs in new regions are added.");
+		// we have an out of place glyph being added. This shouldn't ever really happen as the cursor is always moved before glyphs are added
+		// still failsafe
 		if (m_activeTextRegion->textRegionLines.size() > 0)
 		{
 			renderTextFrame();
@@ -4145,6 +4171,7 @@ void SlaOutputDev::addGlyphAtPoint(QPointF newGlyphPoint, PdfGlyph new_glyph) {
 	else {
 		//TODO: possible don't store the glyphs on the textRegion, well certainly not like this, we only need to check bounbdry and feature positions
 		//m_activeTextRegion->glyphs.push_back(new_glyph);
+		m_activeTextRegion->maxHeight = abs(m_activeTextRegion->textRegioBasenOrigin.y() - movedGlyphPoint.y()) > m_activeTextRegion->maxHeight ? abs(m_activeTextRegion->textRegioBasenOrigin.y() - movedGlyphPoint.y()) : m_activeTextRegion->maxHeight;
 		if (m_activeTextRegion->textRegionLines.size() == 0)
 		{
 			TextRegionLine newTextRegionLine = TextRegionLine();
@@ -4157,18 +4184,19 @@ void SlaOutputDev::addGlyphAtPoint(QPointF newGlyphPoint, PdfGlyph new_glyph) {
 			
 			TextRegionLine& textRegionLine = m_activeTextRegion->textRegionLines.back();
 			textRegionLine.glyphIndex = glyphs.size() - 1;			
-			textRegionLine.width = 0;
+			textRegionLine.width = new_glyph.dx;
 			textRegionLine.baseOrigin = QPointF(newGlyphPoint.x(), newGlyphPoint.y());
-			//FIXME: shouldn't i use lastxy here
-			textRegionLine.modeHeigth = newGlyphPoint.y() - textRegionLine.baseOrigin.y();
-			textRegionLine.maxHeight = newGlyphPoint.y() - textRegionLine.baseOrigin.y();
+			//FIXME: Use the base origin of the previous line if there is one
+			textRegionLine.modeHeigth = abs(newGlyphPoint.y() - m_activeTextRegion->_lastXY.y());
+			textRegionLine.maxHeight = abs(newGlyphPoint.y() - m_activeTextRegion->_lastXY.y());
 		}
+		//TODO: Work out when to add new line segments and when to update them
 		if (m_activeTextRegion->textRegionLines.back().segments.empty())
 		{
 			// add a new segment
 			TextRegionLine newSegment = TextRegionLine();
 			newSegment.glyphIndex = m_activeTextRegion->textRegionLines.back().glyphIndex;
-			newSegment.width = 0;					
+			newSegment.width = 0;
 			m_activeTextRegion->textRegionLines.back().segments.push_back(newSegment);
 		}
 		if (m_activeTextRegion->textRegionLines.back().segments.back().width == 0)
@@ -4176,22 +4204,28 @@ void SlaOutputDev::addGlyphAtPoint(QPointF newGlyphPoint, PdfGlyph new_glyph) {
 			TextRegionLine& segment = m_activeTextRegion->textRegionLines.back().segments.back();
 			segment.width = new_glyph.dx;
 			segment.baseOrigin = QPointF(newGlyphPoint.x(), m_activeTextRegion->textRegionLines.back().baseOrigin.y());
-			segment.modeHeigth = newGlyphPoint.y() - segment.baseOrigin.y();
-			segment.maxHeight = newGlyphPoint.y() - segment.baseOrigin.y();
+			//FIXME: Use the base origin of the previous line if there is one
+			segment.modeHeigth = abs(newGlyphPoint.y() - m_activeTextRegion->_lastXY.y());
+			segment.maxHeight = abs(newGlyphPoint.y() - m_activeTextRegion->_lastXY.y());
 			//FIXME:Set thease properly using lastxy &co.
 			m_activeTextRegion->textRegionLines.back().maxHeight = m_activeTextRegion->textRegionLines.back().maxHeight > segment.maxHeight ? m_activeTextRegion->textRegionLines.back().maxHeight : segment.maxHeight;
 			m_activeTextRegion->textRegionLines.back().modeHeigth = segment.modeHeigth; //FIXME: this needs to be calculated based on the heights of all the segments
-			m_activeTextRegion->textRegionLines.back().width += segment.width;
+			m_activeTextRegion->textRegionLines.back().width = abs(movedGlyphPoint.x() -  m_activeTextRegion->textRegionLines.back().baseOrigin.x());
+			m_activeTextRegion->maxWidth = m_activeTextRegion->textRegionLines.back().width > m_activeTextRegion->maxWidth ? m_activeTextRegion->textRegionLines.back().width : m_activeTextRegion->maxWidth;
 		}
 		else
 		{
 			// update the text line and segment widths,
 			TextRegionLine& segment = m_activeTextRegion->textRegionLines.back().segments.back();
-			segment.width = movedGlyphPoint.x() - segment.baseOrigin.x();
+			segment.width = abs(movedGlyphPoint.x() - segment.baseOrigin.x());
 			segment.glyphIndex = glyphs.size() - 1;
-			m_activeTextRegion->textRegionLines.back().width = movedGlyphPoint.x() - m_activeTextRegion->textRegionLines.back().baseOrigin.x();
+			m_activeTextRegion->textRegionLines.back().width = abs(movedGlyphPoint.x() - m_activeTextRegion->textRegionLines.back().baseOrigin.x());
+			m_activeTextRegion->maxWidth = m_activeTextRegion->textRegionLines.back().width > m_activeTextRegion->maxWidth ? m_activeTextRegion->textRegionLines.back().width : m_activeTextRegion->maxWidth;
 		}
+		//FIXME: Check if we are on a new line before setting _lineBaseXY
+		m_activeTextRegion->_lineBaseXY = movedGlyphPoint;
 		m_activeTextRegion->_lastXY = movedGlyphPoint;
+		
 	}
 }
 
@@ -4267,29 +4301,34 @@ void SlaOutputDev::setFillAndStrokeForPDF(GfxState* state, PageItem* textNode) {
 /**
  * \brief Updates current text position
  */
-void SlaOutputDev::updateTextPos(GfxState* state) {
-	//qDebug() << "updateTextPos()";
-
+void SlaOutputDev::updateTextPos(GfxState* state) {	
 	QPointF new_position = QPointF(state->getCurX(), state->getCurY());
+	qDebug() << "updateTextPos() new_position: " << new_position << " lastxy: " << m_activeTextRegion->_lastXY << " lineBaseXY: " << m_activeTextRegion->_lineBaseXY;
 	//check to see if we are in a new text region
 	if (m_activeTextRegion->textRegioBasenOrigin == QPointF(-1, -1) || 
-		(m_activeTextRegion->textRegionLines.back().glyphIndex == -1))// && !isRegionConcurrent(new_position)))
+		(m_activeTextRegion->textRegionLines.size() == 1 && m_activeTextRegion->textRegionLines.back().glyphIndex == -1) )// && !isRegionConcurrent(new_position)))
 	{
 		//FIXME: Actually put this in the correct class	
 		m_activeTextRegion->textRegioBasenOrigin = new_position;
-		// this ahould really get picked up by add first glyph
+		// this ahould really get picked up by add first glyph, so check if that happens and if it does remove this. also we only want to call for the very first glyph of a new region, not every glyph for the begining of every line.
+		// don't make an arbitrary call to addGlyphAtPoint, instead pick the glyph up via addFirstGlyph
+		// we catch end of line glyphs further down anyway.
+		delete addChar;
+		addChar = new AddFirstChar(this);
+#		/* FIXME: Do we need this here? is there a better test we can use before calling it, can't we just get it picked up by add first glyph		
 		if (glyphs.size() > 0)
 		{
 			addGlyphAtPoint(glyphs.back().position, glyphs.back());
 		}
+		*/
 
 	}
 	else
 	{
 		// a delayed call using the last glyph that was put onto the stack. it will be a glyph situated on the far side bounds of the text region
-		// only add if we are on a new line
-		// FIXME: closeToX currently always returns true
-		if (closeToY(new_position.y(), glyphs.back().position.y()) && 
+		// only add if we are on a new line, so the y position will be shifted but the glyph.y and textregion.y should marry
+		if (this->coLinera(m_activeTextRegion->_lastXY.y(), glyphs.back().position.y()) &&
+			!this->coLinera(new_position.y(), glyphs.back().position.y()) &&
 			closeToX(new_position.x(), glyphs.back().position.x()))
 		{
 			addGlyphAtPoint(glyphs.back().position, glyphs.back());
@@ -4310,7 +4349,7 @@ void SlaOutputDev::renderTextFrame()
 	}
 
 	//TODO: Look this up using the framework
-	const PdfGlyph& first_glyph = glyphs[0];// (*i);
+	const PdfGlyph& first_glyph = glyphs[m_activeTextRegion->textRegionLines[0].glyphIndex];// (*i);
 	// TODO: Use the framework for this, not currently supported
 	/*
 	int render_mode = first_glyph.render_mode;
@@ -4320,7 +4359,7 @@ void SlaOutputDev::renderTextFrame()
 		return;
 	}
 	*/
-
+	//FIXME: Use the framework for positioning not the first glyph
 	qreal xCoor = m_doc->currentPage()->xOffset() + (double)first_glyph.position.x();
 	qreal yCoor = m_doc->currentPage()->initialHeight() - (m_doc->currentPage()->yOffset() + (double)first_glyph.position.y()); // don't know if y is top down or bottom up
 	double  lineWidth = 0.0;
@@ -4347,7 +4386,7 @@ void SlaOutputDev::renderTextFrame()
 		textNode->setLineJoin(PLineJoin);
 		textNode->setTextFlowMode(PageItem::TextFlowDisabled);
 
-		textNode->setFillTransparency(1.0);
+		//textNode->setFillTransparency(1.0);
 		textNode->setLineTransparency(1.0); // this ssets the transparency of the textbox border and we don't want to see it			
 		textNode->setFillColor(CommonStrings::None);
 		textNode->setLineColor(CommonStrings::None);

Issue History

Date Modified Username Field Change
2020-06-03 20:42 oliverthered New Issue
2020-06-03 20:42 oliverthered Tag Attached: import
2020-06-03 20:42 oliverthered Tag Attached: patch
2020-06-03 20:42 oliverthered Tag Attached: PDF
2020-06-03 20:42 oliverthered Tag Attached: pdf import
2020-06-03 20:42 oliverthered File Added: basictextframeandtextrendering.diff
2020-06-03 20:49 oliverthered Note Added: 0047665
2020-06-03 21:58 jghali Note Added: 0047669
2020-06-03 22:18 oliverthered File Added: alltherendercrashbugsfixed.diff
2020-06-03 22:18 oliverthered Note Added: 0047670
2020-06-04 03:33 oliverthered File Added: finalize basic collated text using the framework.diff
2020-06-04 03:33 oliverthered Note Added: 0047671
2020-06-21 12:39 jghali Assigned To => jghali
2020-06-21 12:39 jghali Status new => resolved
2020-06-21 12:39 jghali Resolution open => duplicate
2020-06-21 12:39 jghali Relationship added duplicate of 0016142
2020-06-21 12:39 jghali Status resolved => closed