r21107 by craig -
scribus-commit
scribus-commit at lists.scribus.net
Wed Mar 23 20:21:36 UTC 2016
Author: craig
Date: Wed Mar 23 20:21:36 2016
New Revision: 21107
URL: http://scribus.net/websvn/listing.php?repname=Scribus&sc=1&rev=21107
Log:
Big thanks to HOST-Oman and the team. Commit Boxes diff to SVN. Celebrate
Modified:
trunk/Scribus/AUTHORS
trunk/Scribus/scribus/canvas.cpp
trunk/Scribus/scribus/canvasmode.cpp
trunk/Scribus/scribus/pageitem.cpp
trunk/Scribus/scribus/pageitem.h
trunk/Scribus/scribus/pageitem_pathtext.cpp
trunk/Scribus/scribus/pageitem_textframe.cpp
trunk/Scribus/scribus/pageitem_textframe.h
trunk/Scribus/scribus/pdflib_core.cpp
trunk/Scribus/scribus/pdflib_core.h
trunk/Scribus/scribus/plugins/export/svgexplugin/svgexplugin.cpp
trunk/Scribus/scribus/plugins/export/svgexplugin/svgexplugin.h
trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.cpp
trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.h
trunk/Scribus/scribus/pslib.cpp
trunk/Scribus/scribus/pslib.h
trunk/Scribus/scribus/scpageoutput.cpp
trunk/Scribus/scribus/scpageoutput.h
trunk/Scribus/scribus/scpainter.cpp
trunk/Scribus/scribus/scpainter.h
trunk/Scribus/scribus/scribusdoc.cpp
trunk/Scribus/scribus/scribusview.cpp
trunk/Scribus/scribus/sctextstruct.cpp
trunk/Scribus/scribus/sctextstruct.h
trunk/Scribus/scribus/text/CMakeLists.txt
trunk/Scribus/scribus/text/storytext.cpp
trunk/Scribus/scribus/text/storytext.h
trunk/Scribus/scribus/text/textlayout.cpp
trunk/Scribus/scribus/text/textlayout.h
Modified: trunk/Scribus/AUTHORS
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/AUTHORS
==============================================================================
--- trunk/Scribus/AUTHORS (original)
+++ trunk/Scribus/AUTHORS Wed Mar 23 20:21:36 2016
@@ -71,6 +71,20 @@
Giovanni Mugnai musical777 at gmail.com
+Refactoring text layout code and the new boxes model, Oman House of Open Source
+Technology team:
+
+Anood Almuharbi anood.almuharbi at gmail.com
+Asma ALbahanta as.bahanta at gmail.com
+Dawood Albadi daawood.albadi at gmail.com
+Ibrahim Alrashdi ibrahimalrashdi745 at gmail.com
+Ibtisam Nasser ibtisammabsali at gmail.com
+Khaled Hosny khaledhosny at eglug.org
+Noseeba noseeba1 at gmail.com
+Shamsa Hamed shamsahamed59 at gmail.com
+Sheikha sheikha443 at gmail.com
+
+
Official Documentation:
Peter Linnell plinnell at scribus.net
Modified: trunk/Scribus/scribus/canvas.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/canvas.cpp
==============================================================================
--- trunk/Scribus/scribus/canvas.cpp (original)
+++ trunk/Scribus/scribus/canvas.cpp Wed Mar 23 20:21:36 2016
@@ -2061,6 +2061,7 @@
void Canvas::DrawPageIndicatorSub(ScPainter *p, ScPage *page)
{
p->save();
+ int fm = p->fillMode();
p->setAntialiasing(false);
p->translate(page->xOffset(), page->yOffset());
double lineWidth = 1.0 / m_viewMode.scale;
@@ -2072,6 +2073,7 @@
p->setPen(PrefsManager::instance()->appPrefs.displayPrefs.pageBorderColor, 1 / m_viewMode.scale, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
p->drawRect(0, 0, pageWidth, pageHeight);
p->setAntialiasing(true);
+ p->setFillMode(fm);
p->restore();
}
Modified: trunk/Scribus/scribus/canvasmode.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/canvasmode.cpp
==============================================================================
--- trunk/Scribus/scribus/canvasmode.cpp (original)
+++ trunk/Scribus/scribus/canvasmode.cpp Wed Mar 23 20:21:36 2016
@@ -1016,141 +1016,21 @@
void CanvasMode::commonDrawTextCursor(QPainter* p, PageItem_TextFrame* textframe, const QPointF& offset)
{
- double dx, dy, dy1;
+ QLineF cursor;
QPen cPen ( Qt::black, 0.9 , Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin );
// normalize Current Position
textframe->itemText.normalizeCursorPosition();
int textCursorPos ( textframe->itemText.cursorPosition() );
-
- if ( textframe->lastInFrame() >= textframe->itemText.length()
- || textframe->itemText.length() == 0 )
- {
- dx = textframe->textToFrameDistLeft();
- dy = textframe->textToFrameDistTop();
- dy1 = textframe->textToFrameDistTop() + (textframe->itemText.defaultStyle().charStyle().fontSize() / 10.0);
-
- cPen.setColor ( ScColorEngine::getRGBColor ( m_doc->PageColors[textframe->itemText.defaultStyle().charStyle().fillColor() ], m_doc ) );
- }
- else if ( textCursorPos > textframe->lastInFrame() )
- {
- // Happens often when typing directly into frame.
- // And the cursor curses nothing, vertigo.
- textCursorPos = qMax(0, textframe->lastInFrame());
- QChar textCursorChar = textframe->itemText.text(textCursorPos);
- if (textCursorChar == SpecialChars::PARSEP || textCursorChar == SpecialChars::LINEBREAK)
- {
- // The cursor must be moved to the beginning of the next line
- FRect bbox = textframe->textLayout.boundingBox ( textCursorPos );
- double lineSpacing(textframe->itemText.paragraphStyle(textCursorPos).lineSpacing());
-
- // take care if cursor is not in first column
- int curCol(1);
- double ccPos(textframe->textLayout.boundingBox ( textCursorPos ).x());
- double leftOffset(textframe->textToFrameDistLeft());
- for(int ci(1); ci <= textframe->columns(); ++ci)
- {
- double cLeft(((ci-1) * textframe->columnWidth()) + ((ci -1) * textframe->columnGap()) + leftOffset);
- double cRight((ci * textframe->columnWidth()) + ((ci -1) * textframe->columnGap()) + leftOffset);
- if((cLeft <= ccPos) && (ccPos <= cRight))
- {
- curCol = ci;
- break;
- }
- }
- dx = (textframe->columnWidth() * (curCol - 1)) + (textframe->columnGap() * (curCol - 1)) + leftOffset;
- dy = bbox.y();
-
- if ( bbox.height() <= 2 )
- dy1 = bbox.y() + textframe->itemText.charStyle ( textCursorPos ).fontSize() / 30.0;
- else
- dy1 = bbox.y() + bbox.height();
-
- dy += lineSpacing;
- dy1 += lineSpacing;
- }
- else if (textCursorChar == SpecialChars::COLBREAK)
- {
- // A bit tricky :)
- // We want to position the cursor at the beginning of the next column, if any.
- // At first we need to know in which column the cursor is.
- int curCol(1);
- double ccPos(textframe->textLayout.boundingBox ( textCursorPos ).x());
- double leftOffset(textframe->textToFrameDistLeft());
- for(int ci(1); ci <= textframe->columns(); ++ci)
- {
- double cLeft(((ci-1) * textframe->columnWidth()) + ((ci -1) * textframe->columnGap()) + leftOffset);
- double cRight((ci * textframe->columnWidth()) + ((ci -1) * textframe->columnGap()) + leftOffset);
- if((cLeft <= ccPos) && (ccPos <= cRight))
- {
- curCol = ci;
- break;
- }
- }
- if(textframe->columns() > curCol)
- {
- dx = (textframe->columnWidth() * curCol) + (textframe->columnGap() * curCol) + leftOffset;
- dy = textframe->textToFrameDistTop();
- dy1 = textframe->textToFrameDistTop() + textframe->textLayout.boundingBox ( textCursorPos ).height();
- }
- else // there is no column after the current column
- {
- FRect bbox = textframe->textLayout.boundingBox ( textCursorPos );
- dx = bbox.x();
- dy = bbox.y();
- dx += textframe->itemText.getGlyphs(textCursorPos)->wide();
- if ( bbox.height() <= 2 )
- dy1 = bbox.y() + textframe->itemText.charStyle ( textCursorPos ).fontSize() / 30.0;
- else
- dy1 = bbox.y() + bbox.height();
- }
- }
- else
- {
- FRect bbox = textframe->textLayout.boundingBox ( textCursorPos );
- dx = bbox.x();
- dy = bbox.y();
- dx += textframe->itemText.getGlyphs(textCursorPos)->wide();
- if ( bbox.height() <= 2 )
- dy1 = bbox.y() + textframe->itemText.charStyle ( textCursorPos ).fontSize() / 30.0;
- else
- dy1 = bbox.y() + bbox.height();
-
- }
- cPen.setColor ( ScColorEngine::getRGBColor ( m_doc->PageColors[textframe->itemText.charStyle ( textCursorPos ).fillColor() ], m_doc ) );
- }
- else
- {
- FRect bbox = textframe->textLayout.boundingBox ( textCursorPos );
- dx = bbox.x();
- dy = bbox.y();
- if ( bbox.height() <= 2 )
- dy1 = bbox.y() + textframe->itemText.charStyle ( textCursorPos ).fontSize() / 30.0;
- else
- dy1 = bbox.y() + bbox.height();
-
- cPen.setColor ( ScColorEngine::getRGBColor ( m_doc->PageColors[textframe->itemText.charStyle ( textCursorPos ).fillColor() ], m_doc ) );
- }
- //handle Right to Left writing
- if (textframe->imageFlippedH())
- dx = textframe->width() - dx;
- if (textframe->imageFlippedV())
- {
- dy = textframe->height() - dy;
- dy1 = textframe->height() - dy1;
- }
+ cursor = textframe->textLayout.positionToPoint(textCursorPos);
+
+ cPen.setColor(ScColorEngine::getRGBColor(m_doc->PageColors[textframe->itemText.charStyle(textCursorPos).fillColor()], m_doc));
+
p->save();
p->setTransform(textframe->getTransform(), true);
p->setPen ( cPen );
p->setRenderHint ( QPainter::Antialiasing, true );
- // avoid displaying the cursor on the frameborder
- dx = qMax ( ( cPen.widthF() / 2.0 ), dx );
-
- dy = qMin ( qMax ( dy,0.0 ) , textframe->height() );
- dy1 = qMin ( qMax ( dy1,0.0 ), textframe->height() );
-
- p->drawLine ( QLineF ( dx,dy,dx,dy1 ).translated(offset) );
-
+ p->drawLine(cursor.translated(offset));
p->restore();
}
Modified: trunk/Scribus/scribus/pageitem.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/pageitem.cpp
==============================================================================
--- trunk/Scribus/scribus/pageitem.cpp (original)
+++ trunk/Scribus/scribus/pageitem.cpp Wed Mar 23 20:21:36 2016
@@ -2549,7 +2549,7 @@
/**
layout glyphs translates the chars into a number of glyphs, applying the Charstyle
- 'style'. The following fields are set in layout: glyph, more, scaleH, scaleV, xoffset, yoffset, xadvance.
+ 'style'. The following fields are set in layout: glyph, scaleH, scaleV, xoffset, yoffset, xadvance.
If the DropCap-bit in style.effects is set and yadvance is > 0, scaleH/V, x/yoffset and xadvance
are modified to scale the glyphs to this height.
Otherwise yadvance is set to the max ascender of all generated glyphs.
@@ -2557,9 +2557,9 @@
sets xadvance to the advance width without kerning. If more than one glyph
is generated, kerning is included in all but the last xadvance.
*/
-double PageItem::layoutGlyphs(const CharStyle& style, const QString& chars, LayoutFlags flags, GlyphLayout& layout)
-{
- double retval = 0.0;
+GlyphLayout PageItem::layoutGlyphs(const CharStyle& style, const QString& chars, LayoutFlags flags)
+{
+ GlyphLayout gl;
const ScFace font = style.font();
double asce = font.ascent(style.fontSize() / 10.0);
int chst = style.effects() & ScStyle_UserStyles;
@@ -2578,36 +2578,34 @@
}
else */
{
- layout.glyph = font.char2CMap(chars[0].unicode());
+ gl.glyph = font.char2CMap(chars[0].unicode());
}
double tracking = 0.0;
if ( (flags & ScLayout_StartOfLine) == 0)
tracking = style.fontSize() * style.tracking() / 10000.0;
- layout.xoffset = tracking;
- layout.yoffset = 0;
+ gl.xoffset = tracking;
+ gl.yoffset = 0;
if (chst != ScStyle_Default)
{
if (chst & ScStyle_Superscript)
{
- retval -= asce * m_Doc->typographicPrefs().valueSuperScript / 100.0;
- layout.yoffset -= asce * m_Doc->typographicPrefs().valueSuperScript / 100.0;
- layout.scaleV = layout.scaleH = qMax(m_Doc->typographicPrefs().scalingSuperScript / 100.0, 10.0 / style.fontSize());
+ gl.yoffset -= asce * m_Doc->typographicPrefs().valueSuperScript / 100.0;
+ gl.scaleV = gl.scaleH = qMax(m_Doc->typographicPrefs().scalingSuperScript / 100.0, 10.0 / style.fontSize());
}
else if (chst & ScStyle_Subscript)
{
- retval += asce * m_Doc->typographicPrefs().valueSubScript / 100.0;
- layout.yoffset += asce * m_Doc->typographicPrefs().valueSubScript / 100.0;
- layout.scaleV = layout.scaleH = qMax(m_Doc->typographicPrefs().scalingSubScript / 100.0, 10.0 / style.fontSize());
+ gl.yoffset += asce * m_Doc->typographicPrefs().valueSubScript / 100.0;
+ gl.scaleV = gl.scaleH = qMax(m_Doc->typographicPrefs().scalingSubScript / 100.0, 10.0 / style.fontSize());
}
else {
- layout.scaleV = layout.scaleH = 1.0;
- }
- layout.scaleH *= style.scaleH() / 1000.0;
- layout.scaleV *= style.scaleV() / 1000.0;
+ gl.scaleV = gl.scaleH = 1.0;
+ }
+ gl.scaleH *= style.scaleH() / 1000.0;
+ gl.scaleV *= style.scaleV() / 1000.0;
if (chst & ScStyle_AllCaps)
{
- layout.glyph = font.char2CMap(chars[0].toUpper().unicode());
+ gl.glyph = font.char2CMap(chars[0].toUpper().unicode());
}
if (chst & ScStyle_SmallCaps)
{
@@ -2615,15 +2613,15 @@
QChar uc = chars[0].toUpper();
if (uc != chars[0])
{
- layout.glyph = font.char2CMap(chars[0].toUpper().unicode());
- layout.scaleV *= smallcapsScale;
- layout.scaleH *= smallcapsScale;
+ gl.glyph = font.char2CMap(chars[0].toUpper().unicode());
+ gl.scaleV *= smallcapsScale;
+ gl.scaleH *= smallcapsScale;
}
}
}
else {
- layout.scaleH = style.scaleH() / 1000.0;
- layout.scaleV = style.scaleV() / 1000.0;
+ gl.scaleH = style.scaleH() / 1000.0;
+ gl.scaleV = style.scaleV() / 1000.0;
}
/* if (layout.glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBSPACE.unicode())) {
@@ -2642,311 +2640,13 @@
}
else */
{
- layout.xadvance = font.glyphWidth(layout.glyph, style.fontSize() / 10) * layout.scaleH;
- layout.yadvance = font.glyphBBox(layout.glyph, style.fontSize() / 10).ascent * layout.scaleV;
- }
- if (layout.xadvance > 0)
- layout.xadvance += tracking;
-
- if (chars.length() > 1) {
- layout.grow();
- layoutGlyphs(style, chars.mid(1), ScLayout_None, *layout.more);
- layout.xadvance += font.glyphKerning(layout.glyph, layout.more->glyph, style.fontSize() / 10) * layout.scaleH;
- if (layout.more->yadvance > layout.yadvance)
- layout.yadvance = layout.more->yadvance;
- }
- else {
- layout.shrink();
- }
- return retval;
-}
-
-void PageItem::drawGlyphs(ScPainter *p, const CharStyle& style, LayoutFlags flags, GlyphLayout& glyphs)
-{
- uint glyph = glyphs.glyph;
- const ScFace font = style.font();
- if ((m_Doc->guidesPrefs().showControls) &&
- (glyph == font.char2CMap(QChar(' ')) || glyph >= ScFace::CONTROL_GLYPHS))
- {
- bool stroke = false;
- if (glyph >= ScFace::CONTROL_GLYPHS)
- glyph -= ScFace::CONTROL_GLYPHS;
- else
- glyph = 32;
- QTransform chma, chma4, chma5;
- FPointArray points;
- if (glyph == SpecialChars::TAB.unicode())
- {
- points = m_Doc->symTab.copy();
- chma4.translate(glyphs.xoffset + glyphs.xadvance - ((style.fontSize() / 10.0) * glyphs.scaleH * 0.7), glyphs.yoffset - ((style.fontSize() / 10.0) * glyphs.scaleV * 0.5));
- }
- else if (glyph == SpecialChars::COLBREAK.unicode())
- {
- points = m_Doc->symNewCol.copy();
- chma4.translate(glyphs.xoffset, glyphs.yoffset-((style.fontSize() / 10.0) * glyphs.scaleV * 0.6));
- }
- else if (glyph == SpecialChars::FRAMEBREAK.unicode())
- {
- points = m_Doc->symNewFrame.copy();
- chma4.translate(glyphs.xoffset, glyphs.yoffset-((style.fontSize() / 10.0) * glyphs.scaleV * 0.6));
- }
- else if (glyph == SpecialChars::PARSEP.unicode())
- {
- points = m_Doc->symReturn.copy();
- chma4.translate(glyphs.xoffset, glyphs.yoffset-((style.fontSize() / 10.0) * glyphs.scaleV * 0.8));
- }
- else if (glyph == SpecialChars::LINEBREAK.unicode())
- {
- points = m_Doc->symNewLine.copy();
- chma4.translate(glyphs.xoffset, glyphs.yoffset-((style.fontSize() / 10.0) * glyphs.scaleV * 0.4));
- }
- else if (glyph == SpecialChars::NBSPACE.unicode() ||
- glyph == 32)
- {
- stroke = (glyph == 32);
- points = m_Doc->symNonBreak.copy();
- chma4.translate(glyphs.xoffset, glyphs.yoffset-((style.fontSize() / 10.0) * glyphs.scaleV * 0.4));
- }
- else if (glyph == SpecialChars::NBHYPHEN.unicode())
- {
- points = font.glyphOutline(font.char2CMap(QChar('-')), style.fontSize() / 100);
- chma4.translate(glyphs.xoffset, glyphs.yoffset-((style.fontSize() / 10.0) * glyphs.scaleV));
- }
- else if (glyph == SpecialChars::SHYPHEN.unicode())
- {
- points.resize(0);
- points.addQuadPoint(0, -10, 0, -10, 0, -6, 0, -6);
- stroke = true;
- }
- else if (glyph == SpecialChars::OBJECT.unicode())
- {
- //for showing marks entries as control chars
- points.resize(0);
- points.addQuadPoint(0, -8, 1, -8, 0, -6, 1, -6);
- stroke = true;
- }
- else // ???
- {
- points.resize(0);
- points.addQuadPoint(0, -10, 0, -10, 0, -9, 0, -9);
- points.addQuadPoint(0, -9, 0, -9, 1, -9, 1, -9);
- points.addQuadPoint(1, -9, 1, -9, 1, -10, 1, -10);
- points.addQuadPoint(1, -10, 1, -10, 0, -10, 0, -10);
- }
- chma.scale(glyphs.scaleH * style.fontSize() / 100.0, glyphs.scaleV * style.fontSize() / 100.0);
- points.map(chma * chma4);
- p->setupPolygon(&points, true);
- QColor oldBrush = p->brush();
- p->setBrush( (flags & ScLayout_SuppressSpace) ? Qt::green
- : PrefsManager::instance()->appPrefs.displayPrefs.controlCharColor);
- if (stroke)
- {
- QColor tmp = p->pen();
- p->setPen(p->brush(), 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
- p->setLineWidth(style.fontSize() * glyphs.scaleV / 200.0);
- p->strokePath();
- p->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
- }
- else
- {
- p->setFillMode(1);
- p->fillPath();
- }
- p->setBrush(oldBrush);
- if (glyphs.more)
- {
- p->translate(glyphs.xadvance, 0);
- drawGlyphs(p, style, ScLayout_None, *glyphs.more);
- }
- return;
- }
- else if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBSPACE.unicode()) ||
- glyph == (ScFace::CONTROL_GLYPHS + 32))
- glyph = font.char2CMap(QChar(' '));
- else if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBHYPHEN.unicode()))
- glyph = font.char2CMap(QChar('-'));
-
- if (glyph >= ScFace::CONTROL_GLYPHS || (style.effects() & ScLayout_SuppressSpace)) {
-// qDebug("drawGlyphs: skipping %d", glyph);
- // all those are empty
- if (glyphs.more)
- {
- p->translate(glyphs.xadvance, 0);
- drawGlyphs(p, style, ScLayout_None, *glyphs.more);
- }
- return;
- }
-// if (font.canRender(QChar(glyph)))
- {
- FPointArray gly = font.glyphOutline(glyph);
- // Do underlining first so you can get typographically correct
- // underlines when drawing a white outline
- if (((style.effects() & ScStyle_Underline) || ((style.effects() & ScStyle_UnderlineWords) && glyph != font.char2CMap(QChar(' ')))) && (style.strokeColor() != CommonStrings::None))
- {
- double st, lw;
- if ((style.underlineOffset() != -1) || (style.underlineWidth() != -1))
- {
- if (style.underlineOffset() != -1)
- st = (style.underlineOffset() / 1000.0) * (font.descent(style.fontSize() / 10.0));
- else
- st = font.underlinePos(style.fontSize() / 10.0);
- if (style.underlineWidth() != -1)
- lw = (style.underlineWidth() / 1000.0) * (style.fontSize() / 10.0);
- else
- lw = qMax(font.strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- else
- {
- st = font.underlinePos(style.fontSize() / 10.0);
- lw = qMax(font.strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- if (style.baselineOffset() != 0)
- st += (style.fontSize() / 10.0) * glyphs.scaleV * (style.baselineOffset() / 1000.0);
- QColor tmpC = p->pen();
- int oldStrokeMode = p->strokeMode();
- p->setPen(p->brush());
- p->setLineWidth(lw);
- p->setStrokeMode(1);
- if (style.effects() & ScStyle_Subscript)
- p->drawLine(FPoint(glyphs.xoffset, glyphs.yoffset - st), FPoint(glyphs.xoffset + glyphs.xadvance, glyphs.yoffset - st));
- else
- p->drawLine(FPoint(glyphs.xoffset, -st), FPoint(glyphs.xoffset + glyphs.xadvance, -st));
- p->setStrokeMode(oldStrokeMode);
- p->setPen(tmpC);
- }
- if (gly.size() > 3)
- {
- if (glyph == 0)
- {
-// qDebug() << QString("glyph 0: (%1,%2) * %3 %4 + %5").arg(glyphs.xoffset).arg(glyphs.yoffset).arg(glyphs.scaleH).arg(glyphs.scaleV).arg(glyphs.xadvance));
- }
- p->save();
- p->translate(glyphs.xoffset, glyphs.yoffset - ((style.fontSize() / 10.0) * glyphs.scaleV));
- if (m_isReversed)
- {
- p->scale(-1, 1);
- p->translate(-glyphs.xadvance, 0);
- }
- if (style.baselineOffset() != 0)
- p->translate(0, -(style.fontSize() / 10.0) * (style.baselineOffset() / 1000.0));
- double glxSc = glyphs.scaleH * style.fontSize() / 100.00;
- double glySc = glyphs.scaleV * style.fontSize() / 100.0;
- p->scale(glxSc, glySc);
-// p->setFillMode(1);
- bool fr = p->fillRule();
- p->setFillRule(false);
-// double a = gly.point(0).x();
-// double b = gly.point(0).y();
-// double c = gly.point(3).x();
-// double d = gly.point(3).y();
-// qDebug() << QString("drawglyphs: %1 (%2,%3) (%4,%5) scaled %6,%7 trans %8,%9")
-// .arg(gly.size()).arg(a).arg(b).arg(c).arg(d)
-// .arg(p->worldMatrix().m11()).arg(p->worldMatrix().m22()).arg(p->worldMatrix().dx()).arg(p->worldMatrix().dy());
- p->setupPolygon(&gly, true);
- if (m_Doc->layerOutline(LayerID))
- {
- p->save();
- p->setPen(m_Doc->layerMarker(LayerID), 0.5, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
- p->setFillMode(ScPainter::None);
- p->setBrushOpacity(1.0);
- p->setPenOpacity(1.0);
- p->strokePath();
- p->restore();
- p->setFillRule(fr);
- p->restore();
- if (glyphs.more)
- {
- p->translate(glyphs.xadvance, 0);
- drawGlyphs(p, style, ScLayout_None, *glyphs.more);
- }
- return;
- }
- if (glyph == 0)
- {
- p->setPen(PrefsManager::instance()->appPrefs.displayPrefs.controlCharColor, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
- p->setLineWidth(style.fontSize() * glyphs.scaleV * style.outlineWidth() * 2 / 10000.0);
- p->strokePath();
- }
- else if ((font.isStroked()) && (style.strokeColor() != CommonStrings::None) && ((style.fontSize() * glyphs.scaleV * style.outlineWidth() / 10000.0) != 0))
- {
- QColor tmp = p->brush();
- p->setStrokeMode(1);
- p->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
- p->setLineWidth(style.fontSize() * glyphs.scaleV * style.outlineWidth() / 10000.0);
- p->strokePath();
- }
- else
- {
- if ((style.effects() & ScStyle_Shadowed) && (style.strokeColor() != CommonStrings::None))
- {
- p->save();
- p->translate((style.fontSize() * glyphs.scaleH * style.shadowXOffset() / 10000.0) / glxSc, -(style.fontSize() * glyphs.scaleV * style.shadowYOffset() / 10000.0) / glySc);
- QColor tmp = p->brush();
- p->setBrush(p->pen());
- p->setupPolygon(&gly, true);
- p->fillPath();
- p->setBrush(tmp);
- p->restore();
- p->setupPolygon(&gly, true);
- }
- if (style.fillColor() != CommonStrings::None)
- p->fillPath();
- if ((style.effects() & ScStyle_Outline) && (style.strokeColor() != CommonStrings::None) && ((style.fontSize() * glyphs.scaleV * style.outlineWidth() / 10000.0) != 0))
- {
- p->setStrokeMode(1);
- p->setLineWidth((style.fontSize() * glyphs.scaleV * style.outlineWidth() / 10000.0) / glySc);
- p->strokePath();
- }
- }
- p->setFillRule(fr);
- p->restore();
- }
- else {
-// qDebug() << "drawGlyphs: empty glyph" << glyph;
- }
- if ((style.effects() & ScStyle_Strikethrough) && (style.strokeColor() != CommonStrings::None))
- {
- double st, lw;
- if ((style.strikethruOffset() != -1) || (style.strikethruWidth() != -1))
- {
- if (style.strikethruOffset() != -1)
- st = (style.strikethruOffset() / 1000.0) * (font.ascent(style.fontSize() / 10.0));
- else
- st = font.strikeoutPos(style.fontSize() / 10.0);
- if (style.strikethruWidth() != -1)
- lw = (style.strikethruWidth() / 1000.0) * (style.fontSize() / 10.0);
- else
- lw = qMax(font.strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- else
- {
- st = font.strikeoutPos(style.fontSize() / 10.0);
- lw = qMax(font.strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- if (style.baselineOffset() != 0)
- st += (style.fontSize() / 10.0) * glyphs.scaleV * (style.baselineOffset() / 1000.0);
- int oldStrokeMode = p->strokeMode();
- p->setPen(p->brush());
- p->setLineWidth(lw);
- p->setStrokeMode(1);
- p->drawLine(FPoint(glyphs.xoffset, glyphs.yoffset - st), FPoint(glyphs.xoffset + glyphs.xadvance, glyphs.yoffset - st));
- p->setStrokeMode(oldStrokeMode);
- }
- }
-/* else
- {
- p->setLineWidth(1);
- p->setPen(red);
- p->setBrush(red);
- p->setFillMode(1);
- p->drawRect(glyphs.xoffset, glyphs.yoffset - (style.fontSize() / 10.0) * glyphs.scaleV , (style.fontSize() / 10.0) * glyphs.scaleH, (style.fontSize() / 10.0) * glyphs.scaleV);
- }
- */
- if (glyphs.more)
- {
- p->translate(glyphs.xadvance, 0);
- drawGlyphs(p, style, ScLayout_None, *glyphs.more);
- }
+ gl.xadvance = font.glyphWidth(gl.glyph, style.fontSize() / 10);
+ gl.yadvance = font.glyphBBox(gl.glyph, style.fontSize() / 10).ascent;
+ }
+ if (gl.xadvance > 0)
+ gl.xadvance += tracking;
+
+ return gl;
}
void PageItem::DrawPolyL(QPainter *p, QPolygon pts)
Modified: trunk/Scribus/scribus/pageitem.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/pageitem.h
==============================================================================
--- trunk/Scribus/scribus/pageitem.h (original)
+++ trunk/Scribus/scribus/pageitem.h Wed Mar 23 20:21:36 2016
@@ -415,9 +415,8 @@
/// Return current text properties (current char + paragraph properties)
void currentTextProps(ParagraphStyle& parStyle) const;
// deprecated:
- double layoutGlyphs(const CharStyle& style, const QString& chars, LayoutFlags flags, GlyphLayout& layout);
+ GlyphLayout layoutGlyphs(const CharStyle& style, const QString& chars, LayoutFlags flags);
void SetQColor(QColor *tmp, QString farbe, double shad);
- void drawGlyphs(ScPainter *p, const CharStyle& style, LayoutFlags flags, GlyphLayout& glyphs );
void DrawPolyL(QPainter *p, QPolygon pts);
QString ExpandToken(uint base);
const FPointArray shape() const { return PoLine; }
Modified: trunk/Scribus/scribus/pageitem_pathtext.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/pageitem_pathtext.cpp
==============================================================================
--- trunk/Scribus/scribus/pageitem_pathtext.cpp (original)
+++ trunk/Scribus/scribus/pageitem_pathtext.cpp Wed Mar 23 20:21:36 2016
@@ -46,6 +46,9 @@
#include "undostate.h"
#include "util.h"
#include "util_math.h"
+#include "text/boxes.h"
+#include "text/textlayoutpainter.h"
+#include "text/screenpainter.h"
using namespace std;
@@ -79,18 +82,8 @@
double dx;
FPoint point = FPoint(0, 0);
FPoint tangent = FPoint(0, 0);
- QColor tmp;
CurX = m_textDistanceMargins.left();
- QString cachedStroke = "";
- QString cachedFill = "";
- double cachedFillShade = -1;
- double cachedStrokeShade = -1;
- QString actStroke = "";
- QString actFill = "";
- double actFillShade = -1;
- double actStrokeShade = -1;
- QColor cachedFillQ;
- QColor cachedStrokeQ;
+
if (!m_Doc->layerOutline(LayerID))
{
if (PoShow)
@@ -202,7 +195,6 @@
double wordExtra = 0;
for (a = firstChar; a < itemRenderText.length(); ++a)
{
- GlyphLayout* glyphs = itemRenderText.getGlyphs(a);
chstr = itemRenderText.text(a, 1);
if (chstr[0] == SpecialChars::PAGENUMBER || chstr[0] == SpecialChars::PARSEP || chstr[0] == SpecialChars::PAGECOUNT
|| chstr[0] == SpecialChars::TAB || chstr[0] == SpecialChars::LINEBREAK)
@@ -211,13 +203,11 @@
spaceCount++;
if (a < itemRenderText.length()-1)
chstr += itemRenderText.text(a+1, 1);
- glyphs->yadvance = 0;
- layoutGlyphs(itemRenderText.charStyle(a), chstr, itemRenderText.flags(a), *glyphs);
- glyphs->shrink();
+ GlyphLayout glyphs = layoutGlyphs(itemRenderText.charStyle(a), chstr, itemRenderText.flags(a));
if (itemRenderText.hasObject(a))
- totalTextLen += (itemRenderText.object(a)->width() + itemRenderText.object(a)->lineWidth()) * glyphs->scaleH;
- else
- totalTextLen += glyphs->wide()+itemRenderText.charStyle(a).fontSize() * itemRenderText.charStyle(a).tracking() / 10000.0;
+ totalTextLen += (itemRenderText.object(a)->width() + itemRenderText.object(a)->lineWidth()) * glyphs.scaleH;
+ else
+ totalTextLen += glyphs.xadvance+itemRenderText.charStyle(a).fontSize() * itemRenderText.charStyle(a).tracking() / 10000.0;
}
for (int segs = 0; segs < PoLine.size()-3; segs += 4)
{
@@ -252,10 +242,10 @@
QList<QPainterPath> pathList = decomposePath(guidePath);
QPainterPath currPath = pathList[0];
int currPathIndex = 0;
+ PathLineBox* linebox = new PathLineBox();
for (a = firstChar; a < itemRenderText.length(); ++a)
{
CurY = 0;
- GlyphLayout* glyphs = itemRenderText.getGlyphs(a);
PathData* pdata = & (textLayout.point(a));
chstr = itemRenderText.text(a,1);
if (chstr[0] == SpecialChars::PAGENUMBER || chstr[0] == SpecialChars::PARSEP || chstr[0] == SpecialChars::PAGECOUNT
@@ -263,15 +253,16 @@
continue;
if (a < itemRenderText.length()-1)
chstr += itemRenderText.text(a+1, 1);
- glyphs->yadvance = 0;
- layoutGlyphs(itemRenderText.charStyle(a), chstr, itemRenderText.flags(a), *glyphs);
- glyphs->shrink(); // HACK
+
+ GlyphLayout glyphs = layoutGlyphs(itemRenderText.charStyle(a), chstr, itemRenderText.flags(a));
+ GlyphRun run(&itemRenderText.charStyle(a), itemRenderText.flags(a), a, a, itemRenderText.object(a));
+ run.glyphs().append(glyphs);
+
if (itemRenderText.hasObject(a))
- dx = (itemRenderText.object(a)->width() + itemRenderText.object(a)->lineWidth()) * glyphs->scaleH / 2.0;
- else
- dx = glyphs->wide() / 2.0;
+ dx = (itemRenderText.object(a)->width() + itemRenderText.object(a)->lineWidth()) * glyphs.scaleH / 2.0;
+ else
+ dx = glyphs.xadvance / 2.0;
CurX += dx;
-
double currPerc = currPath.percentAtLength(CurX);
if (currPerc >= 0.9999999)
{
@@ -293,7 +284,7 @@
QPointF currPoint = currPath.pointAtPercent(currPerc);
tangent = FPoint(cos(currAngle * M_PI / 180.0), sin(currAngle * M_PI / 180.0));
point = FPoint(currPoint.x(), currPoint.y());
- glyphs->xoffset = 0;
+ glyphs.xoffset = 0;
pdata->PtransX = point.x();
pdata->PtransY = point.y();
pdata->PRot = currAngle * M_PI / 180.0;
@@ -315,62 +306,55 @@
else
trafo *= QTransform( a, 4 * a, 0, -1, point.x(), point.y() );
}
- QTransform sca = p->worldMatrix();
- trafo *= sca;
- p->save();
- QTransform savWM = p->worldMatrix();
- p->setWorldMatrix(trafo);
- if (!m_Doc->RePos)
- {
- actFill = itemRenderText.charStyle(a).fillColor();
- actFillShade = itemRenderText.charStyle(a).fillShade();
- if (actFill != CommonStrings::None)
- {
- p->setFillMode(ScPainter::Solid);
- if ((cachedFillShade != actFillShade) || (cachedFill != actFill))
- {
- SetQColor(&tmp, actFill, actFillShade);
- p->setBrush(tmp);
- cachedFillQ = tmp;
- cachedFill = actFill;
- cachedFillShade = actFillShade;
- }
- else
- p->setBrush(cachedFillQ);
- }
- else
- p->setFillMode(ScPainter::None);
- actStroke = itemRenderText.charStyle(a).strokeColor();
- actStrokeShade = itemRenderText.charStyle(a).strokeShade();
- if (actStroke != CommonStrings::None)
- {
- if ((cachedStrokeShade != actStrokeShade) || (cachedStroke != actStroke))
- {
- SetQColor(&tmp, actStroke, actStrokeShade);
- p->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
- cachedStrokeQ = tmp;
- cachedStroke = actStroke;
- cachedStrokeShade = actStrokeShade;
- }
- else
- p->setPen(cachedStrokeQ, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
- }
- p->translate(0.0, BaseOffs);
- if (itemRenderText.hasObject(a))
- DrawObj_Embedded(p, cullingArea, itemRenderText.charStyle(a), itemRenderText.object(a));
- else
- drawGlyphs(p, itemRenderText.charStyle(a), itemRenderText.flags(a), *glyphs);
- }
- p->setWorldMatrix(savWM);
- p->restore();
+
+
+ const CharStyle& cStyle(run.style());
+ double scaleV = cStyle.scaleV() / 1000.0;
+ double offset = (cStyle.fontSize() / 10) * (cStyle.baselineOffset() / 1000.0);
+ double ascent = cStyle.font().ascent(cStyle.fontSize()/10.00) * scaleV + offset;
+ double descent = cStyle.font().descent(cStyle.fontSize()/10.00) * scaleV - offset;
+ linebox->setAscent(ascent);
+ linebox->setDescent(descent);
+ Box* box;
+ if (itemRenderText.hasObject(a))
+ {
+ box = new ObjectBox(run);
+ box->setAscent(run.object()->height() - run.object()->lineWidth());
+ box->setDescent(0);
+ }
+ else
+ {
+ box = new GlyphBox(run);
+ box->setAscent(linebox->ascent());
+ box->setDescent(linebox->descent());
+ }
+
+ box->setMatrix(trafo);
+ linebox->addBox(box);
+
+
MaxChars = a+1;
CurX -= dx;
if (itemRenderText.hasObject(a))
- CurX += (itemRenderText.object(a)->width() + itemRenderText.object(a)->lineWidth()) * glyphs->scaleH + extraOffset;
+ CurX += (itemRenderText.object(a)->width() + itemRenderText.object(a)->lineWidth()) * glyphs.scaleH + extraOffset;
else if (chstr[0] == SpecialChars::BLANK)
- CurX += glyphs->wide()+itemRenderText.charStyle(a).fontSize() * itemRenderText.charStyle(a).tracking() / 10000.0 + wordExtra + extraOffset;
- else
- CurX += glyphs->wide()+itemRenderText.charStyle(a).fontSize() *itemRenderText.charStyle(a).tracking() / 10000.0 + extraOffset;
+ CurX += glyphs.xadvance+itemRenderText.charStyle(a).fontSize() * itemRenderText.charStyle(a).tracking() / 10000.0 + wordExtra + extraOffset;
+ else
+ CurX += glyphs.xadvance+itemRenderText.charStyle(a).fontSize() *itemRenderText.charStyle(a).tracking() / 10000.0 + extraOffset;
+ }
+
+ textLayout.addColumn(0, 0);
+ textLayout.appendLine(linebox);
+
+ if (!m_Doc->RePos)
+ {
+ int fm = p->fillMode();
+ p->setFillMode(1);
+ p->save();
+ ScreenPainter painter(p, this);
+ textLayout.render(&painter);
+ p->setFillMode(fm);
+ p->restore();
}
}
Modified: trunk/Scribus/scribus/pageitem_textframe.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/pageitem_textframe.cpp
==============================================================================
--- trunk/Scribus/scribus/pageitem_textframe.cpp (original)
+++ trunk/Scribus/scribus/pageitem_textframe.cpp Wed Mar 23 20:21:36 2016
@@ -55,6 +55,8 @@
#include "scribusview.h"
#include "scribusstructs.h"
#include "selection.h"
+#include "text/boxes.h"
+#include "text/screenpainter.h"
#include "ui/guidemanager.h"
#include "ui/marksmanager.h"
#include "undomanager.h"
@@ -346,7 +348,7 @@
stream << "scaleV" << "\t";
stream << "\n";
- for (int zc = line.firstItem; zc < line.lastItem; ++zc)
+ for (int zc = line.firstChar; zc < line.lastChar; ++zc)
{
const ScText* item = itemText.item(zc);
@@ -388,46 +390,6 @@
}
*/
-/**
- Clones the tab fill char as often as necssary after all distances are known
- */
-static void fillInTabLeaders(StoryText & itemText, LineSpec & curLine)
-{
- // fill in tab leaders
- double xPos = curLine.x;
- for (int ti= curLine.firstItem; ti <= curLine.lastItem; ++ti)
- {
- GlyphLayout* glyphs = itemText.getGlyphs(ti);
- if (itemText.text(ti) == SpecialChars::TAB)
- {
- GlyphLayout * tglyph = glyphs->more;
-
- if (!tglyph)
- continue;
-
- const CharStyle & charStyle(itemText.charStyle(ti));
- double wt = charStyle.font().glyphWidth(tglyph->glyph, charStyle.fontSize() * tglyph->scaleV / 10.0);
- double len = glyphs->xadvance;
- int count = static_cast<int>(len / wt);
- double sPos = -len;
- tglyph->xoffset = sPos;
-// qDebug() << QString("tab leaders: %1 %2 width=%3 count=%4").arg(sPos).arg(curLine.y).arg(wt).arg(count);
- for (int cx = 1; cx < count; ++cx)
- {
- // clone fillchar
- tglyph->grow();
- *(tglyph->more) = *tglyph;
- tglyph->more->more = NULL;
- tglyph = tglyph->more;
- tglyph->xoffset = sPos + wt * cx;
- }
- }
- xPos += glyphs->wide();
- }
-}
-
-
-
enum TabStatus {
TabNONE = 0,
TabLEFT = TabNONE,
@@ -442,19 +404,36 @@
fields which describe what type of tab is currently active
*/
struct TabControl {
- bool active;
- int status;
- int charIndex;
- double xPos;
- QChar fillChar;
+ bool active;
+ int status;
+ double xPos;
+ QChar fillChar;
+ GlyphLayout* tabGlyph;
+};
+
+struct LineSpec
+{
+ qreal x;
+ qreal y;
+ qreal width;
+ qreal ascent;
+ qreal descent;
+ qreal colLeft;
+
+ int firstRun;
+ int lastRun;
+ qreal naturalWidth;
+ bool isFirstLine;
+ qreal height;
};
/**
fields which describe how the current line is placed into the frame
- */
+*/
struct LineControl {
LineSpec line;
- int itemsInLine;
+ QList<GlyphRun>& glyphRuns;
+ bool isEmpty;
int hyphenCount;
double colWidth;
double colGap;
@@ -472,8 +451,8 @@
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
+ int restartIndex; //index of glyph run where line computing should be restarted
+ int restartRowIndex; //index of glyph run where row of text is started
double restartX; //starting X position of line if must be restarted
double rowDesc;
@@ -487,38 +466,36 @@
double maxShrink;
double maxStretch;
-
+ ScribusDoc *doc;
/// remember frame dimensions and offsets
- void init(double w, double h, const MarginStruct& extra, double lCorr)
+ LineControl(double w, double h, const MarginStruct& extra, double lCorr, ScribusDoc* d, QList<GlyphRun>& runs, double colwidth, double colgap)
+ : glyphRuns(runs)
+ , hasDropCap(false)
+ , doc(d)
{
insets = extra;
lineCorr = lCorr;
frameWidth = w;
frameHeight = h;
- hasDropCap = false;
- }
-
- /// start at column 0
- void initColumns(double width, double gap)
- {
column = 0;
- colWidth = width;
- colGap = gap;
+ colWidth = colwidth;
+ colGap = colgap;
+ hyphenCount = 0;
}
/// move position to next column
- void nextColumn(double asce = 0.0)
+ void nextColumn(TextLayout &textLayout)
{
startOfCol = true;
colLeft = (colWidth + colGap) * column + insets.left() + lineCorr;
+ textLayout.addColumn(colLeft, colWidth);
//now colRight is REAL column right edge
colRight = colLeft + colWidth;
if (legacy)
colRight += lineCorr;
xPos = colLeft;
- yPos = asce + insets.top() + lineCorr;
- line.colLeft = colLeft;
+ yPos = insets.top() + lineCorr;
}
bool isEndOfCol(double morespace = 0)
@@ -529,19 +506,18 @@
/**
init fields for a new line at current position
*/
- void startLine(int first)
- {
- itemsInLine = 0;
+ void startLine(int firstRun)
+ {
+ isEmpty = true;
line.x = xPos;
line.y = yPos;
- line.firstItem = first;
- line.lastItem = 0;
+ line.firstRun = firstRun;
+ line.lastRun = 0;
line.ascent = 0.0;
line.descent = 0.0;
line.width = 0.0;
line.naturalWidth = 0.0;
line.colLeft = colLeft;
- line.isFirstLine = false;
breakIndex = -1;
breakXPos = 0.0;
maxShrink = 0.0;
@@ -586,18 +562,17 @@
breakXPos = pos;
breakIndex = index;
}
-
+
/// called when a mandatory break is found
- void breakLine(const StoryText& itemText, const ParagraphStyle& style, FirstLineOffsetPolicy offsetPolicy, int last)
+ void breakLine(const ParagraphStyle& style, FirstLineOffsetPolicy offsetPolicy, int last)
{
breakIndex = last;
breakXPos = line.x;
- for (int j = line.firstItem; j <= last; ++j)
- if ( !itemText.hasFlag(j, ScLayout_SuppressSpace) )
- breakXPos += itemText.getGlyphs(j)->wide();
+ for (int i = line.firstRun; i <= breakIndex; i++)
+ breakXPos += glyphRuns.at(i).width();
// #8194, #8717 : update line ascent and descent with sensible values
// so that endOfLine() returns correct result
- updateHeightMetrics(itemText);
+ updateHeightMetrics();
// #9060 : update line offset too
// updateLineOffset(itemText, style, offsetPolicy);
}
@@ -605,7 +580,7 @@
/// use the last remembered break to set line width and itemrange
void finishLine(double endX)
{
- line.lastItem = breakIndex;
+ line.lastRun = breakIndex;
line.naturalWidth = breakXPos - line.x;
line.width = endX - line.x;
maxShrink = maxStretch = 0;
@@ -620,7 +595,7 @@
startLine(restartRowIndex);
addLeftIndent = true;
afterOverflow = false;
- return restartRowIndex -1;
+ return restartRowIndex - 1;
}
int restartLine(bool recalcY, bool add)
@@ -630,7 +605,7 @@
xPos = restartX;
startLine(restartIndex);
afterOverflow = false;
- return restartIndex -1;
+ return restartIndex - 1;
}
bool isEndOfLine(double moreSpace = 0)
@@ -732,147 +707,29 @@
return qMin(EndX2, maxX);
}
- double getLineAscent(const StoryText& itemText)
- {
- double result = 0;
- QChar firstChar = itemText.text (line.firstItem);
- if ((firstChar == SpecialChars::PAGENUMBER) || (firstChar == SpecialChars::PAGECOUNT))
- firstChar = '8';
- PageItem *obj = itemText.object (line.firstItem);
- const CharStyle& fcStyle(itemText.charStyle(line.firstItem));
- if ((firstChar == SpecialChars::PARSEP) || (firstChar == SpecialChars::LINEBREAK))
- result = fcStyle.font().ascent(fcStyle.fontSize() / 10.0);
- else if (obj)
- result = qMax(result, (obj->height() + obj->lineWidth()) * (fcStyle.scaleV() / 1000.0));
- else
- result = fcStyle.font().realCharAscent(firstChar, fcStyle.fontSize() / 10.0);
- for (int zc = 0; zc < itemsInLine; ++zc)
- {
- QChar ch = itemText.text(line.firstItem + zc);
- if ((ch == SpecialChars::PAGENUMBER) || (ch == SpecialChars::PAGECOUNT))
- ch = '8'; // should have highest ascender even in oldstyle
- const CharStyle& cStyle(itemText.charStyle(line.firstItem + zc));
- if ((ch == SpecialChars::TAB) || (ch == QChar(10))
- || SpecialChars::isBreak (ch, true) || (ch == SpecialChars::NBHYPHEN) || (ch.isSpace()))
- continue;
- double asce;
- PageItem *obj = itemText.object (line.firstItem + zc);
- if (obj)
- asce = obj->height() + obj->lineWidth() * (cStyle.scaleV() / 1000.0);
- else
- asce = cStyle.font().realCharAscent(ch, cStyle.fontSize() / 10.0);
- // qDebug() << QString("checking char 'x%2' with ascender %1 > %3").arg(asce).arg(ch.unicode()).arg(result);
- result = qMax(result, asce);
- }
- return result;
- }
-
- double getLineDescent(const StoryText& itemText)
- {
- double result = 0;
- QChar firstChar = itemText.text(line.firstItem);
- if ((firstChar == SpecialChars::PAGENUMBER) || (firstChar == SpecialChars::PAGECOUNT))
- firstChar = '8';
- const CharStyle& fcStyle(itemText.charStyle(line.firstItem));
- if ((firstChar == SpecialChars::PARSEP) || (firstChar == SpecialChars::LINEBREAK))
- result = fcStyle.font().descent(fcStyle.fontSize() / 10.0);
- else if (itemText.object(line.firstItem))
- result = 0.0;
- else
- result = fcStyle.font().realCharDescent(firstChar, fcStyle.fontSize() / 10.0);
- for (int zc = 0; zc < itemsInLine; ++zc)
- {
- QChar ch = itemText.text(line.firstItem + zc);
- if ((ch == SpecialChars::PAGENUMBER) || (ch == SpecialChars::PAGECOUNT))
- ch = '8'; // should have highest ascender even in oldstyle
- const CharStyle& cStyle(itemText.charStyle(line.firstItem + zc));
- if ((ch == SpecialChars::TAB) || (ch == QChar(10))
- || SpecialChars::isBreak (ch, true) || (ch == SpecialChars::NBHYPHEN) || (ch.isSpace()))
- continue;
- double desc;
- if (itemText.object(line.firstItem + zc))
- desc = 0.0;
- else
- desc = cStyle.font().realCharDescent(ch, cStyle.fontSize() / 10.0);
- // qDebug() << QString("checking char 'x%2' with ascender %1 > %3").arg(asce).arg(ch.unicode()).arg(result);
- result = qMax(result, desc);
- }
- return result;
- }
-
- double getLineHeight(const StoryText& itemText)
- {
- double result = 0;
- const CharStyle& firstStyle(itemText.charStyle(line.firstItem));
- PageItem *obj = itemText.object (line.firstItem);
- if (obj)
- result = qMax(result, (obj->height() + obj->lineWidth()) * (firstStyle.scaleV() / 1000.0));
- else
- result = firstStyle.font().height(firstStyle.fontSize() / 10.0);
- for (int zc = 0; zc < itemsInLine; ++zc)
- {
- QChar ch = itemText.text(line.firstItem+zc);
- if ((ch == SpecialChars::TAB) || (ch == QChar(10))
- || SpecialChars::isBreak (ch, true) || (ch == SpecialChars::NBHYPHEN) || (ch.isSpace()))
- continue;
- const CharStyle& cStyle(itemText.charStyle(line.firstItem + zc));
- PageItem *obj = itemText.object (line.firstItem + zc);
- double asce;
- if (obj)
- asce = (obj->height() + obj->lineWidth()) * (cStyle.scaleV() / 1000.0);
- else
- asce = cStyle.font().height (cStyle.fontSize() / 10.0);
- // qDebug() << QString("checking char 'x%2' with ascender %1 > %3").arg(asce).arg(ch.unicode()).arg(result);
- result = qMax(result, asce);
- }
- return result;
- }
-
- void updateHeightMetrics(const StoryText& itemText)
- {
- double asce, desc, hei;
- line.ascent = 0;
- line.descent = 0;
- line.height = 0;
- for (int zc = 0; zc < itemsInLine; ++zc)
- {
- QChar ch = itemText.text(line.firstItem+zc);
- if ((ch == SpecialChars::TAB) || (ch == QChar(10))
- || SpecialChars::isBreak (ch, true) || (ch == SpecialChars::NBHYPHEN) || (ch.isSpace()))
- continue;
- const CharStyle& cStyle(itemText.charStyle(line.firstItem + zc));
- double scaleV = cStyle.scaleV() / 1000.0;
- double offset = (cStyle.fontSize() / 10) * (cStyle.baselineOffset() / 1000.0);
-
- if (itemText.object(line.firstItem+zc) != 0)
- {
- asce = (itemText.object(line.firstItem+zc)->height() + itemText.object(line.firstItem+zc)->lineWidth()) * scaleV + offset;
- desc = 0.0;
- hei = asce;
- }
- else //if ((itemText.flags(current.line.firstItem+zc) & ScLayout_DropCap) == 0)
- {
- asce = cStyle.font().realCharAscent(ch, cStyle.fontSize() / 10.0) * scaleV + offset;
- desc = cStyle.font().realCharDescent(ch, cStyle.fontSize() / 10.0) * scaleV - offset;
- hei = cStyle.font().height(cStyle.fontSize() / 10.0) * scaleV;
- }
- // qDebug() << QString("checking char 'x%2' with ascender %1 > %3").arg(asce).arg(ch.unicode()).arg(result);
- line.ascent = qMax(line.ascent, asce);
- line.descent = qMax(line.descent, desc);
- line.height = qMax(line.height, hei);
- }
+ void updateHeightMetrics()
+ {
+ line.ascent = line.descent = 0;
+ // Can happen when inserting a new line at end of text, WTF!
+ if (line.firstRun >= glyphRuns.length())
+ return;
+ const CharStyle& cStyle(glyphRuns.at(line.firstRun).style());
+ double scaleV = cStyle.scaleV() / 1000.0;
+ double offset = (cStyle.fontSize() / 10) * (cStyle.baselineOffset() / 1000.0);
+ line.ascent = cStyle.font().ascent(cStyle.fontSize()/10.00) * scaleV + offset;
+ line.descent = cStyle.font().descent(cStyle.fontSize()/10.00) * scaleV - offset;
}
// yPos should not be changed when all line is already calculated - at new y position there can be overflow!!!
// edit: can't happen as it should only move upwards, and this is covered by the calculations done.
//void updateLineOffset(const StoryText& itemText, const ParagraphStyle& style, FirstLineOffsetPolicy offsetPolicy)
//{
-// if (itemsInLine <= 0)
+// if (charsInLine <= 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 firstasce = itemText.charStyle(line.firstChar).font().ascent(itemText.charStyle(line.firstChar).fontSize() / 10.0);
// double adj (0.0);
// double currasce (this->getLineAscent(itemText));
// if (offsetPolicy == FLOPRealGlyphHeight)
@@ -893,16 +750,50 @@
// }
// else if ((!startOfCol) && (style.lineSpacingMode() == ParagraphStyle::AutomaticLineSpacing))
// {
-// QChar ch = itemText.text(line.firstItem);
+// QChar ch = itemText.text(line.firstChar);
// 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);
+// qDebug() << QString("move2 line %1.. down by %2").arg(current.line.firstChar).arg(-adj);
// line.ascent = currasce;
// line.y -= adj;
// yPos -= adj;
// }
//}
+
+ LineBox* createLineBox()
+ {
+ LineBox* result = new LineBox();
+ result->moveTo(line.x - colLeft, line.y);
+ result->setWidth(line.width);
+ result->setAscent(line.ascent);
+ result->setDescent(line.descent);
+
+ for (int i = line.firstRun; i <= line.lastRun; ++i)
+ {
+ addBox(result, glyphRuns.at(i));
+ }
+
+ return result;
+ }
+
+ void addBox(LineBox *lineBox, const GlyphRun& run)
+ {
+ Box* result;
+ if (run.object())
+ {
+ result = new ObjectBox(run);
+ result->setAscent(run.object()->height() - run.object()->lineWidth());
+ result->setDescent(0);
+ }
+ else
+ {
+ result = new GlyphBox(run);
+ result->setAscent(lineBox->ascent());
+ result->setDescent(lineBox->descent());
+ }
+ lineBox->addBox(result);
+ }
private:
double frameWidth;
@@ -910,6 +801,34 @@
MarginStruct insets;
double lineCorr;
};
+
+/**
+ Clones the tab fill char as often as necssary after all distances are known
+ */
+static void fillInTabLeaders(LineControl & current)
+{
+ // fill in tab leaders
+ for(int i = current.line.firstRun; i <= current.line.lastRun; i++)
+ {
+ GlyphRun& glyphRun = current.glyphRuns[i];
+ CharStyle charStyle(glyphRun.style());
+ if (glyphRun.hasFlag(ScLayout_TabLeaders))
+ {
+ GlyphLayout tglyph = glyphRun.glyphs().last();
+ double width = glyphRun.width();
+ double wt = charStyle.font().glyphWidth(tglyph.glyph, charStyle.fontSize() * tglyph.scaleV / 10.0);
+ int count = static_cast<int>(width / wt);
+ glyphRun.glyphs().clear();
+ for(int cx = 0; cx < count; ++cx)
+ {
+ GlyphLayout more = tglyph;
+ more.xadvance = width / count;
+ glyphRun.glyphs().append(more);
+ }
+ }
+ }
+}
+
static bool checkCJK(QChar ch) {
unsigned int code = ch.unicode();
@@ -957,10 +876,6 @@
return true;
}
-static bool implicitSpace(QChar f, QChar s) {
- return checkCJK(f) && checkCJK(s);
-}
-
static bool implicitBreak(QChar f, QChar s) {
if (checkCJK(f) && checkCJK(s)) {
return allowedCJKBreakAfter(f) && allowedCJKBreakBefore(s);
@@ -969,7 +884,7 @@
}
/// called when line length is known and line is to be justified
-static void justifyLine(StoryText& itemText, LineSpec& line)
+static void justifyLine(const ParagraphStyle& style, LineControl& curr)
{
double glyphNatural = 0;
@@ -979,24 +894,21 @@
int spaceInsertion = 0;
double imSpace = -1;
- const ParagraphStyle& style(itemText.paragraphStyle(line.firstItem));
-
- // measure natural widths for glyphs and spaces
- for (int sof = line.firstItem; sof <= line.lastItem; ++sof)
- {
- GlyphLayout* glyph = itemText.getGlyphs(sof);
- QChar ch = itemText.text(sof);
- if (!SpecialChars::isExpandingSpace(ch))
- {
- glyphNatural += glyph->wide();
- }
- else if ( !itemText.hasFlag(sof, ScLayout_SuppressSpace) )
- {
- spaceNatural += glyph->wide();
- if (imSpace < 0.0 || imSpace > glyph->wide())
- imSpace = glyph->wide();
- }
- if (sof != line.firstItem && implicitSpace(itemText.text(sof - 1), ch)) {
+ for (int i = curr.line.firstRun; i <= curr.line.lastRun; ++i)
+ {
+ GlyphRun glyphrun = curr.glyphRuns[i];
+ if (!glyphrun.hasFlag(ScLayout_ExpandingSpace))
+ {
+ glyphNatural += glyphrun.width();
+ }
+ else if ( !glyphrun.hasFlag(ScLayout_SuppressSpace) )
+ {
+ spaceNatural += glyphrun.width();
+ if (imSpace < 0.0 || imSpace > glyphrun.width())
+ imSpace = glyphrun.width();
+ }
+ if (i != curr.line.firstRun && glyphrun.hasFlag(ScLayout_ImplicitSpace))
+ {
spaceInsertion += 1;
}
}
@@ -1005,23 +917,23 @@
// decision: prio 1: stretch glyph; prio 2: insert spaces; prio 3: stretch spaces
- if (line.width < spaceNatural + glyphNatural * style.minGlyphExtension() && spaceNatural > 0)
+ if (curr.line.width < spaceNatural + glyphNatural * style.minGlyphExtension() && spaceNatural > 0)
{
glyphExtension = style.minGlyphExtension() - 1;
- spaceExtension = (line.width - glyphNatural * (1+glyphExtension) ) / spaceNatural - 1;
+ spaceExtension = (curr.line.width - glyphNatural * (1+glyphExtension) ) / spaceNatural - 1;
imSpace = 0;
}
- else if (line.width < spaceNatural + glyphNatural * style.maxGlyphExtension() && glyphNatural > 0)
+ else if (curr.line.width < spaceNatural + glyphNatural * style.maxGlyphExtension() && glyphNatural > 0)
{
spaceExtension = 0;
- glyphExtension = (line.width - spaceNatural) / glyphNatural - 1;
+ glyphExtension = (curr.line.width - spaceNatural) / glyphNatural - 1;
imSpace = 0;
}
else
{
glyphExtension = style.maxGlyphExtension() - 1;
if (spaceInsertion) {
- double remaining = line.width - glyphNatural * (1 + glyphExtension) - spaceNatural;
+ double remaining = curr.line.width - glyphNatural * (1 + glyphExtension) - spaceNatural;
if (imSpace > 0) {
if (remaining / spaceInsertion < imSpace) {
imSpace = remaining / spaceInsertion;
@@ -1036,7 +948,7 @@
}
} else {
if (spaceNatural > 0)
- spaceExtension = (line.width - glyphNatural * (1+glyphExtension) ) / spaceNatural - 1;
+ spaceExtension = (curr.line.width - glyphNatural * (1+glyphExtension) ) / spaceNatural - 1;
else
spaceExtension = 0;
}
@@ -1051,47 +963,51 @@
.arg(style.minWordTracking()).arg(style.minGlyphExtension());
*/
- int startItem = line.firstItem;
- if (itemText.hasFlag(startItem, ScLayout_DropCap))
+ int startItem = curr.line.firstRun;
+ if (curr.glyphRuns[startItem].hasFlag(ScLayout_DropCap))
startItem++;
// distribute whitespace on spaces and glyphs
- for (int yof = startItem; yof <= line.lastItem; ++yof)
- {
- GlyphLayout* glyph = itemText.getGlyphs(yof);
- QChar ch = itemText.text(yof);
- double wide = glyph->wide();
- if (!SpecialChars::isExpandingSpace(ch))
- {
- glyph->last()->xadvance += wide * glyphExtension;
- while (glyph)
- {
- glyph->xoffset *= glyphScale;
- glyph->scaleH *= glyphScale;
- glyph = glyph->more;
- }
- }
- else if (!itemText.hasFlag(yof, ScLayout_SuppressSpace))
- {
- glyph->last()->xadvance += wide * spaceExtension;
- }
- if (yof != line.firstItem && implicitSpace(itemText.text(yof - 1), ch)) {
- itemText.getGlyphs(yof - 1)->last()->xadvance += imSpace;
+
+ for (int i = startItem; i <= curr.line.lastRun; ++i)
+ {
+ GlyphRun& glyphrun = curr.glyphRuns[i];
+ if (i != curr.line.firstRun && glyphrun.hasFlag(ScLayout_ImplicitSpace))
+ {
+ GlyphRun& lastRun = curr.glyphRuns[i-1];
+ lastRun.glyphs().last().xadvance += imSpace;
+ }
+ double wide = glyphrun.width();
+ if (!glyphrun.hasFlag(ScLayout_ExpandingSpace))
+ {
+ for (int j = 0; j < glyphrun.glyphs().count(); ++j)
+ {
+ GlyphLayout& glyph = glyphrun.glyphs()[j];
+ glyph.xadvance += wide * glyphExtension;
+ glyph.xoffset *= glyphScale;
+ glyph.scaleH *= glyphScale;
+ }
+ }
+ else if (!glyphrun.hasFlag(ScLayout_SuppressSpace))
+ {
+ GlyphLayout& glyph = glyphrun.glyphs().last();
+ glyph.xadvance += wide * spaceExtension;
+
}
}
}
/// called when linelength is known and line is not justified
-static void indentLine(StoryText& itemText, LineSpec& line, double leftIndent)
+static void indentLine(const ParagraphStyle& style, LineControl& curr, double leftIndent)
{
- if (line.naturalWidth > line.width)
- {
- justifyLine(itemText, line);
+ if (curr.line.naturalWidth > curr.line.width)
+ {
+ justifyLine(style, curr);
}
if (leftIndent > 0)
{
- line.x += leftIndent;
- line.width -= leftIndent;
+ curr.line.x += leftIndent;
+ curr.line.width -= leftIndent;
}
}
@@ -1099,8 +1015,8 @@
///// 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.flags(b)) & ScLayout_SuppressSpace))
+// int b = line.firstChar;
+// while (b < line.lastChar && (itemText.flags(b) & ScLayout_SuppressSpace))
// ++b;
//
// double chs = itemText.charStyle(b).fontSize() * (itemText.charStyle(b).scaleH() / 1000.0);
@@ -1135,19 +1051,20 @@
//}
/// calculate how much the last char should stick out to the right
-static double opticalRightMargin(const StoryText& itemText, const LineSpec& line)
+static double opticalRightMargin(const StoryText& itemText, const QList<GlyphRun> runs, const LineSpec& line)
{
- int b = line.lastItem;
- while (b > line.firstItem &&
- (SpecialChars::isBreakingSpace(itemText.text(b)) || SpecialChars::isBreak(itemText.text(b)))
+ int b = line.lastRun;
+ while (b > line.firstRun &&
+ (SpecialChars::isBreakingSpace(itemText.text(runs[b].firstChar())) ||
+ SpecialChars::isBreak(itemText.text(runs[b].firstChar())))
)
--b;
- if (b >= line.firstItem)
- {
- const CharStyle& chStyle(itemText.charStyle(b));
+ if (b >= line.firstRun)
+ {
+ const CharStyle& chStyle(runs[b].style());
double chs = chStyle.fontSize() * (chStyle.scaleH() / 1000.0);
- QChar chr = itemText.hasFlag(b, ScLayout_SoftHyphenVisible) ?
- QChar('-') : itemText.text(b);
+ QChar chr = runs[b].hasFlag(ScLayout_SoftHyphenVisible) ?
+ QChar('-') : itemText.text(runs[b].firstChar());
double rightCorr = chStyle.font().realCharWidth(chr, chs / 10.0);
if (QString("-,.`´'~").indexOf(chr) >= 0
|| chr == QChar(0x2018)
@@ -1309,6 +1226,154 @@
}
}
+QList<GlyphRun> PageItem_TextFrame::shapeText()
+{
+ // maps expanded characters to itemText tokens.
+ QMap<int, int> textMap;
+ QString text;
+ for (int i = firstInFrame(); i < itemText.length(); ++i)
+ {
+ Mark* mark = itemText.mark(i);
+ if (itemText.hasMark(i))
+ {
+ mark->OwnPage = OwnPage;
+ //itemPtr and itemName set to this frame only if mark type is different than MARK2ItemType
+ if (!mark->isType(MARK2ItemType))
+ {
+ mark->setItemPtr(this);
+ mark->setItemName(itemName());
+ }
+
+ //anchors and indexes has no visible inserts in text
+ if (mark->isType(MARKAnchorType) || mark->isType(MARKIndexType))
+ continue;
+
+ //set note marker charstyle
+ if (mark->isNoteType())
+ {
+ TextNote* note = mark->getNotePtr();
+ if (note == NULL)
+ continue;
+ mark->setItemPtr(this);
+ NotesStyle* nStyle = note->notesStyle();
+ Q_ASSERT(nStyle != NULL);
+ QString chsName = nStyle->marksChStyle();
+ CharStyle currStyle(itemText.charStyle(i));
+ if (!chsName.isEmpty())
+ {
+ CharStyle marksStyle(m_Doc->charStyle(chsName));
+ if (!currStyle.equiv(marksStyle))
+ {
+ currStyle.setParent(chsName);
+ itemText.applyCharStyle(i, 1, currStyle);
+ }
+ }
+
+ StyleFlag s(itemText.charStyle(i).effects());
+ if (mark->isType(MARKNoteMasterType))
+ {
+ if (nStyle->isSuperscriptInMaster())
+ s |= ScStyle_Superscript;
+ else
+ s &= ~ScStyle_Superscript;
+ }
+ else
+ {
+ if (nStyle->isSuperscriptInNote())
+ s |= ScStyle_Superscript;
+ else
+ s &= ~ScStyle_Superscript;
+ }
+ if (s != itemText.charStyle(i).effects())
+ {
+ CharStyle haveSuperscript;
+ haveSuperscript.setFeatures(s.featureList());
+ itemText.applyCharStyle(i, 1, haveSuperscript);
+ }
+ }
+ }
+
+ bool bullet = false;
+ if (i == 0 || itemText.text(i - 1) == SpecialChars::PARSEP)
+ {
+ ParagraphStyle style = itemText.paragraphStyle(i);
+ if (style.hasBullet() || style.hasNum())
+ {
+ bullet = true;
+ if (mark == NULL || !mark->isType(MARKBullNumType))
+ {
+ itemText.insertMark(new BulNumMark(), i);
+ i--;
+ continue;
+ }
+ if (style.hasBullet())
+ mark->setString(style.bulletStr());
+ else if (style.hasNum() && mark->getString().isEmpty())
+ {
+ mark->setString("?");
+ m_Doc->flag_Renumber = true;
+ }
+ }
+ }
+
+ if (!bullet && mark && mark->isType(MARKBullNumType))
+ {
+ itemText.removeChars(i, 1);
+ i--;
+ continue;
+ }
+
+ QString str = ExpandToken(i);
+ if (str.isEmpty())
+ str = SpecialChars::ZWNBSPACE;
+
+ for (int j = 0; j < str.length(); j++)
+ textMap.insert(text.length() + j, i);
+
+ text.append(str);
+ }
+
+ QList<GlyphRun> glyphRuns;
+ glyphRuns.reserve(text.length());
+ for (int i = 0; i < text.length(); i++)
+ {
+ const QChar ch(text.at(i));
+ int a = textMap.value(i);
+
+ GlyphRun run(&itemText.charStyle(a), itemText.flags(a), a, a, itemText.object(a));
+ if (SpecialChars::isExpandingSpace(ch))
+ run.setFlag(ScLayout_ExpandingSpace);
+
+ GlyphLayout gl = layoutGlyphs(run.style(), QString(ch), itemText.flags(a));
+
+ if (!glyphRuns.isEmpty())
+ {
+ GlyphLayout& last = glyphRuns.last().glyphs().last();
+ last.xadvance += run.style().font().glyphKerning(last.glyph, gl.glyph, run.style().fontSize() / 10) * last.scaleH;
+ }
+
+ //show control characters for marks
+ if (itemText.hasMark(a))
+ {
+ GlyphLayout control;
+ control.glyph = SpecialChars::OBJECT.unicode() + ScFace::CONTROL_GLYPHS;
+ run.glyphs().append(control);
+ }
+
+ if (SpecialChars::isExpandingSpace(ch))
+ gl.xadvance *= run.style().wordTracking();
+
+ if (itemText.hasObject(a))
+ gl.xadvance = itemText.object(a)->width() + itemText.object(a)->lineWidth();
+
+ run.glyphs().append(gl);
+
+ glyphRuns.append(run);
+ }
+
+ return glyphRuns;
+}
+
void PageItem_TextFrame::layout()
{
// qDebug()<<"==Layout==" << itemName() ;
@@ -1342,10 +1407,7 @@
QPoint pt1, pt2;
QRect pt;
double chs, chsd = 0;
- double EndX, OFs, wide, kernVal;
- QString chstr;
- QChar currentCh;
- GlyphLayout* glyphs;
+ double EndX, OFs;
ParagraphStyle style;
int opticalMargins = ParagraphStyle::OM_None;
@@ -1356,7 +1418,7 @@
TabControl tabs;
tabs.active = false; // RTab
tabs.status = TabNONE; // TabCode
- tabs.charIndex = -1; // StartRT
+ tabs.tabGlyph = 0; // was int charIndex ~ StartRT
tabs.xPos = 0; // RTabX
QList<ParagraphStyle::TabRecord> tTabValues;
@@ -1378,14 +1440,6 @@
if (lineColor() != CommonStrings::None)
lineCorr = m_lineWidth / 2.0;
- // TODO: refactor this into PageItem
- MarginStruct savedTextDistanceMargins(m_textDistanceMargins);
-
- LineControl current;
- current.init(m_width, m_height, m_textDistanceMargins, 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;
@@ -1456,7 +1510,11 @@
m_availableRegion = matrix.map(m_availableRegion);
}
- current.nextColumn();
+ QList<GlyphRun> glyphRuns = shapeText();
+
+ LineControl current(m_width, m_height, m_textDistanceMargins, lineCorr, m_Doc, glyphRuns, columnWidth(), ColGap);
+ current.nextColumn(textLayout);
+
lastLineY = m_textDistanceMargins.top();
//automatic line spacing factor (calculated once)
@@ -1486,13 +1544,13 @@
desc = -itemText.defaultStyle().charStyle().font().descent(itemText.defaultStyle().charStyle().fontSize() / 10.0);
current.yPos = itemText.defaultStyle().lineSpacing() + m_textDistanceMargins.top() + lineCorr - desc;
}
- current.startLine(firstInFrame());
+ current.startLine(0);
outs = false;
OFs = 0;
MaxChars = 0;
double realEnd = 0;
- current.restartIndex = current.restartRowIndex = firstInFrame();
+ current.restartIndex = current.restartRowIndex = 0;
current.afterOverflow = false;
current.addLine = false;
current.recalculateY = true;
@@ -1513,81 +1571,35 @@
int regionMinY = 0, regionMaxY= 0;
double autoLeftIndent = 0.0;
-
- for (int a = firstInFrame(); a < itLen; ++a)
- {
- currentCh = itemText.text(a);
- glyphs = itemText.getGlyphs(a);
+ for (int i = 0; i < glyphRuns.length(); ++i)
+ {
+ if (glyphRuns[i].glyphs().isEmpty())
+ continue;
+
+ int a = glyphRuns[i].firstChar();
bool HasObject = itemText.hasObject(a);
- PageItem* currentObject = HasObject? itemText.object(a): NULL;
+ PageItem* currentObject = itemText.object(a);
bool HasMark = itemText.hasMark(a);
- Mark* mark = itemText.mark(a);
+
+ if (itemText.charStyle(a).effects() & ScStyle_UnderlineWords)
+ {
+ CharStyle tmp(itemText.charStyle(a));
+ StyleFlag effects = tmp.effects();
+ if (!itemText.text(a).isSpace())
+ effects |= ScStyle_Underline;
+ effects &= ~ScStyle_UnderlineWords;
+ tmp.setFeatures(effects.featureList());
+ itemText.applyCharStyle(a, 1, tmp);
+ }
if (HasMark)
{
- //show control characters for marks
- glyphs->glyph = SpecialChars::OBJECT.unicode() + ScFace::CONTROL_GLYPHS;
-
- mark->OwnPage = OwnPage;
- //itemPtr and itemName set to this frame only if mark type is different than MARK2ItemType
- if (!mark->isType(MARK2ItemType))
- {
- mark->setItemPtr(this);
- mark->setItemName(itemName());
- }
- //anchors and indexes has no visible inserts in text
- if (mark->isType(MARKAnchorType) || mark->isType(MARKIndexType))
- {
- glyphs->shrink();
- continue;
- }
+ Mark* mark = itemText.mark(a);
//store mark pointer and position in text
if (mark->isType(MARKNoteMasterType))
noteMarksPosMap.insert(a, mark);
- //set note marker charstyle
- if (mark->isNoteType())
- {
- TextNote* note = mark->getNotePtr();
- if (note == NULL)
- continue;
- mark->setItemPtr(this);
- NotesStyle* nStyle = note->notesStyle();
- Q_ASSERT(nStyle != NULL);
- QString chsName = nStyle->marksChStyle();
- CharStyle currStyle(itemText.charStyle(a));
- if (!chsName.isEmpty())
- {
- CharStyle marksStyle(m_Doc->charStyle(chsName));
- if (!currStyle.equiv(marksStyle))
- {
- currStyle.setParent(chsName);
- itemText.applyCharStyle(a, 1, currStyle);
- }
- }
-
- StyleFlag s(itemText.charStyle(a).effects());
- if (mark->isType(MARKNoteMasterType))
- {
- if (nStyle->isSuperscriptInMaster())
- s |= ScStyle_Superscript;
- else
- s &= ~ScStyle_Superscript;
- }
- else
- {
- if (nStyle->isSuperscriptInNote())
- s |= ScStyle_Superscript;
- else
- s &= ~ScStyle_Superscript;
- }
- if (s != itemText.charStyle(a).effects())
- {
- CharStyle haveSuperscript;
- haveSuperscript.setFeatures(s.featureList());
- itemText.applyCharStyle(a, 1, haveSuperscript);
- }
- }
- }
+ }
+
BulNumMode = false;
if (a==0 || itemText.text(a-1) == SpecialChars::PARSEP)
{
@@ -1596,37 +1608,13 @@
if (style.hasBullet() || style.hasNum())
{
BulNumMode = true;
- if (mark == NULL || !mark->isType(MARKBullNumType))
- {
- BulNumMark* bnMark = new BulNumMark();
- itemText.insertMark(bnMark,a);
- a--;
- itLen = itemText.length();
- continue;
- }
- if (style.hasBullet())
- mark->setString(style.bulletStr());
- else if (style.hasNum())
- {
- if (mark->getString().isEmpty())
- {
- mark->setString("?");
- m_Doc->flag_Renumber = true;
- }
- }
- }
- }
- if (!BulNumMode && mark && mark->isType(MARKBullNumType))
- {
- itemText.removeChars(a,1);
- a--;
- itLen = itemText.length();
- continue;
- }
- if (current.itemsInLine == 0)
+ }
+ }
+
+ if (current.isEmpty)
opticalMargins = style.opticalMargins();
//-->#13490
- if (isNoteFrame() && !mark)
+ if (isNoteFrame() && !HasMark)
{
StyleFlag s(itemText.charStyle(a).effects());
s &= ~ScStyle_Superscript;
@@ -1636,12 +1624,8 @@
}
//--<#13490
CharStyle charStyle = ((itemText.text(a) != SpecialChars::PARSEP) ? itemText.charStyle(a) : style.charStyle());
- chstr = ExpandToken(a);
- int chstrLen = chstr.length();
- if (chstr.isEmpty())
- chstr = SpecialChars::ZWNBSPACE;
-
- curStat = SpecialChars::getCJKAttr(currentCh);
+
+ curStat = SpecialChars::getCJKAttr(itemText.text(a));
//set style for paragraph effects
if (a == 0 || itemText.text(a-1) == SpecialChars::PARSEP)
{
@@ -1678,7 +1662,7 @@
{
if (a == 0 || itemText.text(a-1) == SpecialChars::PARSEP)
{
- if (currentCh != SpecialChars::PARSEP)
+ if (itemText.text(a) != SpecialChars::PARSEP)
{
DropCmode = style.hasDropCap();
if (DropCmode)
@@ -1692,20 +1676,20 @@
const ScFace font = charStyle.font();
- itemText.clearFlag(a, ScLayout_DropCap);
- itemText.clearFlag(a, ScLayout_SoftHyphenVisible);
+ glyphRuns[i].clearFlag(ScLayout_DropCap);
+ glyphRuns[i].clearFlag(ScLayout_SoftHyphenVisible);
// No space at begin of line,
if (legacy)
{
// unless at begin of par (eeks)
- if ( (current.itemsInLine == 0) && (SpecialChars::isBreakingSpace(currentCh))
+ if ( (current.isEmpty) && (SpecialChars::isBreakingSpace(itemText.text(a)))
&& (a > 0 && ! SpecialChars::isBreak(itemText.text(a-1)))
&& ! (a > 0 && SpecialChars::isBreakingSpace(itemText.text(a-1))
- && (!itemText.hasFlag(a-1, ScLayout_SuppressSpace))))
- {
- itemText.setFlag(a, ScLayout_SuppressSpace);
- glyphs->xadvance = 0;
+ && (!glyphRuns[i - 1].hasFlag(ScLayout_SuppressSpace))))
+ {
+ glyphRuns[i].setFlag(ScLayout_SuppressSpace);
+ glyphRuns[i].glyphs().first().xadvance = 0;
continue;
}
else
@@ -1713,16 +1697,16 @@
}
else // from 134 on use NBSPACE for this effect
{
- if ( current.itemsInLine == 0 && (SpecialChars::isBreakingSpace(currentCh) || currentCh.isSpace()))
- {
- itemText.setFlag(a, ScLayout_SuppressSpace);
- glyphs->xadvance = 0;
+ if ( current.isEmpty && (SpecialChars::isBreakingSpace(itemText.text(a)) || itemText.text(a).isSpace()))
+ {
+ glyphRuns[i].setFlag(ScLayout_SuppressSpace);
+ glyphRuns[i].glyphs()[0].xadvance = 0;
continue;
}
else
itemText.clearFlag(a, ScLayout_SuppressSpace);
}
- if (current.itemsInLine == 0)
+ if (current.isEmpty)
{
if (style.rightMargin() == 0)
{
@@ -1745,7 +1729,7 @@
if (!current.afterOverflow && current.recalculateY && !current.startOfCol)
current.yPos += style.gapBefore();
DropCapDrop = 0;
- if (chstr[0] != SpecialChars::PARSEP)
+ if (itemText.text(a) != SpecialChars::PARSEP)
DropCmode = style.hasDropCap();
else
DropCmode = false;
@@ -1770,10 +1754,10 @@
//text height, width, ascent and descent should be calculated for whole text provided by ScText in current position
//and that may be more than one char (variable text for example)
double realCharHeight = 0.0, realCharAscent = 0.0;
- for (int i = 0; i < chstrLen; ++i)
- {
- realCharHeight = qMax(realCharHeight, font.realCharHeight(chstr[i], 1));
- realCharAscent = qMax(realCharAscent, font.realCharAscent(chstr[i], 1));
+ foreach (GlyphLayout gl, glyphRuns[i].glyphs()) {
+ GlyphMetrics gm = font.glyphBBox(gl.glyph);
+ realCharHeight = qMax(realCharHeight, gm.ascent + gm.descent);
+ realCharAscent = qMax(realCharAscent, gm.ascent);
}
double fontAscent = font.ascent(style.charStyle().fontSize() / 10.0);
if (realCharHeight == 0.0)
@@ -1782,8 +1766,8 @@
realCharAscent = fontAscent;
chsd = (10 * ((DropCapDrop + fontAscent) / realCharHeight));
chs = (10 * ((DropCapDrop + fontAscent) / realCharAscent));
- itemText.setFlag(a, ScLayout_DropCap);
- glyphs->yoffset -= DropCapDrop;
+ glyphRuns[i].setFlag(ScLayout_DropCap);
+ glyphRuns[i].glyphs().first().yoffset += DropCapDrop;
if (HasObject)
{
chs = qRound((currentObject->height() + currentObject->lineWidth()) * 10);
@@ -1797,113 +1781,92 @@
else
chs = charStyle.fontSize();
}
- // set StartOfLine (and find tracking?)
- if (current.itemsInLine == 0)
- {
- itemText.setFlag(a, ScLayout_StartOfLine);
- kernVal = 0;
+ // set StartOfLine
+ if (current.isEmpty)
+ {
+ glyphRuns[i].setFlag(ScLayout_StartOfLine);
}
else
{
- kernVal = 0; // chs * charStyle.tracking() / 10000.0;
- itemText.clearFlag(a, ScLayout_StartOfLine);
- }
- glyphs->yadvance = 0;
- layoutGlyphs(charStyle, chstr, itemText.flags(a), *glyphs);
-
- // find out width, ascent and descent of char
- if (HasObject)
- {
- wide = currentObject->width() + currentObject->lineWidth();
- glyphs->xadvance = wide * glyphs->scaleH;
- }
- else
- {
- wide = glyphs->wide();
- // apply kerning
- if (a+1 < itemText.length())
- {
- uint glyph2 = font.char2CMap(itemText.text(a+1));
- double kern = font.glyphKerning(glyphs->last()->glyph, glyph2, chs / 10.0) * glyphs->scaleH;
- wide += kern;
- glyphs->last()->xadvance += kern;
- // change xadvance, xoffset according to JIS X4051
- int nextStat = SpecialChars::getCJKAttr(itemText.text(a+1));
- int prevStat;
- if (curStat != 0)
- { // current char is CJK
- if (nextStat == 0 && !SpecialChars::isBreakingSpace(itemText.text(a+1))){
- switch(curStat & SpecialChars::CJK_CHAR_MASK){
- case SpecialChars::CJK_KANJI:
- case SpecialChars::CJK_KANA:
- case SpecialChars::CJK_NOTOP:
- kern = charStyle.fontSize() / 10 / 4;
- wide += kern;
- glyphs->last()->xadvance += kern;
- }
- } else { // next char is CJK, too
- switch(curStat & SpecialChars::CJK_CHAR_MASK){
+ glyphRuns[i].clearFlag(ScLayout_StartOfLine);
+ }
+// glyphs->yadvance = 0;
+
+ GlyphLayout& firstGlyph = glyphRuns[i].glyphs().first();
+ GlyphLayout& lastGlyph = glyphRuns[i].glyphs().last();
+
+ // apply cjk kerning
+ //TODO: cjk spacing and kerning should be done in layoutGlyphs!
+ if (i + 1 < glyphRuns.length())
+ {
+ GlyphRun nextRun = glyphRuns[i + 1];
+ // change xadvance, xoffset according to JIS X4051
+ int nextStat = SpecialChars::getCJKAttr(itemText.text(nextRun.firstChar()));
+ if (curStat != 0)
+ { // current char is CJK
+ if (nextStat == 0 && !SpecialChars::isBreakingSpace(itemText.text(nextRun.firstChar()))){
+ switch(curStat & SpecialChars::CJK_CHAR_MASK){
+ case SpecialChars::CJK_KANJI:
+ case SpecialChars::CJK_KANA:
+ case SpecialChars::CJK_NOTOP:
+ lastGlyph.xadvance += charStyle.fontSize() / 10 / 4;
+ }
+ } else { // next char is CJK, too
+ switch(curStat & SpecialChars::CJK_CHAR_MASK){
+ case SpecialChars::CJK_FENCE_END:
+ switch(nextStat & SpecialChars::CJK_CHAR_MASK){
+ case SpecialChars::CJK_FENCE_BEGIN:
case SpecialChars::CJK_FENCE_END:
- switch(nextStat & SpecialChars::CJK_CHAR_MASK){
- case SpecialChars::CJK_FENCE_BEGIN:
- case SpecialChars::CJK_FENCE_END:
- case SpecialChars::CJK_COMMA:
- case SpecialChars::CJK_PERIOD:
- case SpecialChars::CJK_MIDPOINT:
- kern = -charStyle.fontSize() / 10 / 2;
- wide += kern;
- glyphs->last()->xadvance += kern;
- }
- break;
case SpecialChars::CJK_COMMA:
case SpecialChars::CJK_PERIOD:
- switch(nextStat & SpecialChars::CJK_CHAR_MASK){
- case SpecialChars::CJK_FENCE_BEGIN:
- case SpecialChars::CJK_FENCE_END:
- kern = -charStyle.fontSize() / 10 / 2;
- wide += kern;
- glyphs->last()->xadvance += kern;
- }
- break;
case SpecialChars::CJK_MIDPOINT:
- switch(nextStat & SpecialChars::CJK_CHAR_MASK){
- case SpecialChars::CJK_FENCE_BEGIN:
- kern = -charStyle.fontSize() / 10 / 2;
- wide += kern;
- glyphs->last()->xadvance += kern;
- }
- break;
+ lastGlyph.xadvance -= charStyle.fontSize() / 10 / 2;
+ }
+ break;
+ case SpecialChars::CJK_COMMA:
+ case SpecialChars::CJK_PERIOD:
+ switch(nextStat & SpecialChars::CJK_CHAR_MASK){
case SpecialChars::CJK_FENCE_BEGIN:
- if (a == current.line.firstItem){ // first char of the line
- prevStat = SpecialChars::CJK_FENCE_BEGIN;
- } else {
- prevStat = SpecialChars::getCJKAttr(itemText.text(a-1)) & SpecialChars::CJK_CHAR_MASK;
- }
- if (prevStat == SpecialChars::CJK_FENCE_BEGIN){
- kern = -charStyle.fontSize() / 10 / 2;
- wide += kern;
- glyphs->last()->xadvance += kern;
- glyphs->last()->xoffset += kern;
- }
- break;
+ case SpecialChars::CJK_FENCE_END:
+ lastGlyph.xadvance -= charStyle.fontSize() / 10 / 2;;
}
-
+ break;
+ case SpecialChars::CJK_MIDPOINT:
+ switch(nextStat & SpecialChars::CJK_CHAR_MASK){
+ case SpecialChars::CJK_FENCE_BEGIN:
+ lastGlyph.xadvance -= charStyle.fontSize() / 10 / 2;
+ }
+ break;
+ case SpecialChars::CJK_FENCE_BEGIN:
+ int prevStat = 0;
+ if (i == current.line.firstRun){ // first char of the line
+ prevStat = SpecialChars::CJK_FENCE_BEGIN;
+ } else if (i != 0) {
+ prevStat = SpecialChars::getCJKAttr(itemText.text(glyphRuns[i - 1].lastChar())) & SpecialChars::CJK_CHAR_MASK;
+ }
+ if (prevStat == SpecialChars::CJK_FENCE_BEGIN){
+ lastGlyph.xadvance -= charStyle.fontSize() / 10 / 2;
+ lastGlyph.xoffset -= charStyle.fontSize() / 10 / 2;
+ }
+ break;
}
- } else { // current char is not CJK
- if (nextStat != 0 && !SpecialChars::isBreakingSpace(currentCh)){
- switch(nextStat & SpecialChars::CJK_CHAR_MASK){
- case SpecialChars::CJK_KANJI:
- case SpecialChars::CJK_KANA:
- case SpecialChars::CJK_NOTOP:
- // use the size of the current char instead of the next one
- kern = charStyle.fontSize() / 10 / 4;
- wide += kern;
- glyphs->last()->xadvance += kern;
- }
+ }
+ } else { // current char is not CJK
+ if (nextStat != 0 && !SpecialChars::isBreakingSpace(itemText.text(glyphRuns[i].lastChar()))){
+ switch(nextStat & SpecialChars::CJK_CHAR_MASK){
+ case SpecialChars::CJK_KANJI:
+ case SpecialChars::CJK_KANA:
+ case SpecialChars::CJK_NOTOP:
+ // use the size of the current char instead of the next one
+ lastGlyph.xadvance += charStyle.fontSize() / 10 / 4;
}
}
}
}
+
+ // find out width, ascent and descent of char
+ double wide = glyphRuns[i].width();
+
if (DropCmode)
{
// drop caps are wider...
@@ -1912,22 +1875,23 @@
double itemHeight = currentObject->height() + currentObject->lineWidth();
if (itemHeight == 0)
itemHeight = font.height(style.charStyle().fontSize() / 10.0);
- wide = currentObject->width() + currentObject->lineWidth();
asce = currentObject->height() + currentObject->lineWidth();
realAsce = calculateLineSpacing (style, this) * DropLines;
- glyphs->scaleH /= glyphs->scaleV;
- glyphs->scaleV = (realAsce / itemHeight);
- glyphs->scaleH *= glyphs->scaleV;
+ firstGlyph.scaleH /= firstGlyph.scaleV;
+ firstGlyph.scaleV = (realAsce / itemHeight);
+ firstGlyph.scaleH *= firstGlyph.scaleV;
}
else
{
double realCharHeight = 0.0;
wide = 0.0; realAsce = 0.0;
- for (int i = 0; i < chstrLen; ++i)
- {
- realCharHeight = qMax(realCharHeight, font.realCharHeight(chstr[i], charStyle.fontSize() / 10.0));
- realAsce = qMax(realAsce, font.realCharHeight(chstr[i], chsd / 10.0));
- wide += font.realCharWidth(chstr[i], chsd / 10.0);
+ foreach (GlyphLayout gl, glyphRuns[i].glyphs()) {
+ GlyphMetrics gm;
+ gm = font.glyphBBox(gl.glyph, charStyle.fontSize() / 10.0);
+ realCharHeight = qMax(realCharHeight, gm.ascent + gm.descent);
+ gm = font.glyphBBox(gl.glyph, chsd / 10.0);
+ realAsce = qMax(realAsce, gm.ascent + gm.descent);
+ wide += gm.width;
}
wide = (wide* scaleH) + (1 - scaleH);
realAsce = realAsce * scaleV + offset;
@@ -1935,37 +1899,33 @@
realCharHeight = font.height(style.charStyle().fontSize() / 10.0);
asce = font.ascent(hlcsize10);
// qDebug() QString("dropcaps pre: chsd=%1 realCharHeight = %2 chstr=%3").arg(chsd).arg(asce).arg(chstr2[0]);
- glyphs->scaleH /= glyphs->scaleV;
- glyphs->scaleV = (realAsce / realCharHeight);
- glyphs->scaleH *= glyphs->scaleV;
- glyphs->xoffset -= 0.5; //drop caps are always to far from column left edge
- }
- glyphs->xadvance = wide;
+ firstGlyph.scaleH /= firstGlyph.scaleV;
+ firstGlyph.scaleV = (realAsce / realCharHeight);
+ firstGlyph.scaleH *= firstGlyph.scaleV;
+ firstGlyph.xoffset -= 0.5; //drop caps are always to far from column left edge
+ }
+ firstGlyph.xadvance = wide / firstGlyph.scaleH;
desc = realDesc = 0;
}
else // !DropCMode
{
- if (SpecialChars::isExpandingSpace(currentCh))
- {
- double wordtracking = charStyle.wordTracking();
- glyphs->xadvance *= wordtracking;
- wide *= wordtracking;
- }
// find ascent / descent
if (HasObject)
desc = realDesc = 0;
else
{
- for (int i = 0; i < chstrLen; ++i)
+ if (itemText.text(a) != SpecialChars::OBJECT)
{
- if (chstr[i] == SpecialChars::OBJECT)
- continue;
- realDesc = qMax(realDesc, font.realCharDescent(chstr[i], hlcsize10));
- realAsce = font.realCharAscent(chstr[i], hlcsize10);
- }
+ foreach (GlyphLayout gl, glyphRuns[i].glyphs()) {
+ GlyphMetrics gm = font.glyphBBox(gl.glyph, hlcsize10);
+ realDesc = qMax(realDesc, gm.descent);
+ realAsce = gm.ascent;
+ }
+ }
+
realDesc = realDesc * scaleV - offset;
desc = -font.descent(hlcsize10);
- current.rememberShrinkStretch(currentCh, wide, style);
+ current.rememberShrinkStretch(itemText.text(a), wide, style);
}
if (HasObject)
{
@@ -1979,15 +1939,15 @@
realAsce = asce * scaleV + offset;
else
{
- for (int i = 0; i < chstrLen; ++i)
- realAsce = qMax(realAsce, font.realCharAscent(chstr[i], hlcsize10) * scaleV + offset);
+ foreach (GlyphLayout gl, glyphRuns[i].glyphs())
+ realAsce = qMax(realAsce, font.glyphBBox(gl.glyph, hlcsize10).ascent * scaleV + offset);
}
}
}
// if (BulNumMode)
// hl->glyph.last()->xadvance += style.parEffectOffset();
//check for Y position at beginning of line
- if (current.itemsInLine == 0 && !current.afterOverflow)
+ if (current.isEmpty && !current.afterOverflow)
{
if (current.recalculateY)
{
@@ -1996,7 +1956,7 @@
{
lastLineY = qMax(lastLineY, m_textDistanceMargins.top() + lineCorr);
//fix for proper rendering first empty line (only with PARSEP)
- if (chstr[0] == SpecialChars::PARSEP)
+ if (itemText.text(a) == SpecialChars::PARSEP)
current.yPos += style.lineSpacing();
if (style.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing || FlopBaseline)
{
@@ -2101,7 +2061,7 @@
regionMaxY = static_cast<int>(floor(current.yPos + desc));
}
- if (current.itemsInLine == 0 && !current.afterOverflow)
+ if (current.isEmpty && !current.afterOverflow)
{
//start a new line
goNoRoom = false;
@@ -2219,25 +2179,27 @@
}
if (newColumn)
{
- current.nextColumn();
+ current.nextColumn(textLayout);
current.mustLineEnd = current.colRight;
current.restartX = current.xPos;
lastLineY = current.yPos;
current.rowDesc = 0;
- a--;
+ i--;
current.recalculateY = true;
current.addLeftIndent = true;
continue;
}
current.line.x = current.restartX = current.xPos;
current.line.y = current.yPos;
+ if (glyphRuns[current.line.firstRun].hasFlag(ScLayout_DropCap))
+ current.line.y -= DropCapDrop;
}
//check if line must start at new Y position due to current glyph height or previous line descent
- if (!SpecialChars::isBreak(currentCh, true)
- && !SpecialChars::isBreakingSpace(currentCh)
- && !SpecialChars::isExpandingSpace(currentCh)
- && currentCh != SpecialChars::TAB)
+ if (!SpecialChars::isBreak(itemText.text(a), true)
+ && !SpecialChars::isBreakingSpace(itemText.text(a))
+ && !SpecialChars::isExpandingSpace(itemText.text(a))
+ && itemText.text(a) != SpecialChars::TAB)
{
double diff = 0;
if (current.startOfCol || DropCmode)
@@ -2247,7 +2209,7 @@
if (HasObject)
diff = (currentObject->height() + currentObject->lineWidth()) * scaleV + offset - (current.yPos - lastLineY);
else
- diff = font.realCharAscent(QChar('l'), hlcsize10) * scaleV + offset - (current.yPos - lastLineY);
+ diff = font.capHeight(hlcsize10) * scaleV + offset - (current.yPos - lastLineY);
}
else
{
@@ -2290,21 +2252,21 @@
maxDY = 0;
}
}
- a = current.restartRow(false);
+ i = current.restartRow(false);
continue;
}
}
// right tab stuff
if (tabs.active)
{
- if (((currentCh == '.') && (tabs.status == TabPOINT)) || ((currentCh == ',') && (tabs.status == TabCOMMA)) || (currentCh == SpecialChars::TAB))
+ if (((itemText.text(a) == '.') && (tabs.status == TabPOINT)) || ((itemText.text(a) == ',') && (tabs.status == TabCOMMA)) || (itemText.text(a) == SpecialChars::TAB))
{
tabs.active = false;
tabs.status = TabNONE;
}
}
// tab positioning
- if (currentCh == SpecialChars::TAB)
+ if (itemText.text(a) == SpecialChars::TAB)
{
wide = 1;
if (tabs.active)
@@ -2342,23 +2304,19 @@
}
// remember fill char
- if (!tabs.fillChar.isNull()) {
- glyphs->growWithTabLayout();
- TabLayout * tglyph = dynamic_cast<TabLayout*>(glyphs->more);
- if (tglyph)
- {
- tglyph->fillChar = tabs.fillChar;
- tglyph->glyph = font.char2CMap(tabs.fillChar);
- tglyph->yoffset = glyphs->yoffset;
- tglyph->scaleV = tglyph->scaleH = chs / charStyle.fontSize();
- tglyph->xadvance = 0;
- }
+ if (!tabs.fillChar.isNull())
+ {
+ glyphRuns[i].setFlag(ScLayout_TabLeaders);
+ GlyphLayout tglyph;
+ tglyph.glyph = font.char2CMap(tabs.fillChar);
+ tglyph.yoffset = firstGlyph.yoffset;
+ tglyph.scaleV = tglyph.scaleH = chs / charStyle.fontSize();
+ tglyph.xadvance = 0;
+ glyphRuns[i].glyphs().append(tglyph);
}
}
- current.xPos -= (legacy ? 1.0 : 0.0);
- glyphs->xadvance = current.xPos + wide + kernVal - tabs.xPos;
-// wide = current.xPos - RTabX;
- tabs.charIndex = a;
+ firstGlyph.xadvance = current.xPos + wide - tabs.xPos;
+ tabs.tabGlyph = &firstGlyph;
}
}
@@ -2366,20 +2324,20 @@
if (DropCmode)
{
double yoffset = 0.0;
- for (int i = 0; i < chstrLen; ++i)
- yoffset = qMax(yoffset, font.realCharHeight(chstr[i], chsd / 10.0) - font.realCharAscent(chstr[i], chsd / 10.0));
- glyphs->yoffset -= yoffset;
+ foreach (GlyphLayout gl, glyphRuns[i].glyphs())
+ yoffset = qMax(yoffset, font.glyphBBox(gl.glyph, chsd / 10.0).descent);
+ firstGlyph.yoffset -= yoffset;
}
// remember x pos
double breakPos = current.xPos;
if (!tabs.active) // normal case
{
- current.xPos += wide+kernVal;
+ current.xPos += wide;
}
else if (tabs.active && tabs.status == TabCENTER) // center tab
{
- current.xPos += (wide+kernVal) / 2;
+ current.xPos += wide / 2;
current.xPos = qMax(current.xPos, current.colLeft);
}
else // other tabs.active
@@ -2387,17 +2345,17 @@
current.xPos = qMax(current.xPos, current.colLeft);
}
// remember possible break
- if ( (SpecialChars::isBreakingSpace(currentCh) || currentCh == SpecialChars::TAB))
+ if ( (SpecialChars::isBreakingSpace(itemText.text(a)) || itemText.text(a) == SpecialChars::TAB))
{
if ( a == firstInFrame() || !SpecialChars::isBreakingSpace(itemText.text(a-1)) )
{
- current.rememberBreak(a, breakPos, style.rightMargin());
+ current.rememberBreak(i, breakPos, style.rightMargin());
}
}
if (HasObject)
- current.rememberBreak(a, breakPos, style.rightMargin());
+ current.rememberBreak(i, breakPos, style.rightMargin());
// CJK break
- if (a > current.line.firstItem)
+ if (i > current.line.firstRun)
{ // not the first char
if ((lastStat == 0) && (curStat == 0))
{ // both non-CJK
@@ -2406,7 +2364,7 @@
// non-CJK char does not have CJK_NOBREAK_AFTER/CJK_NOBREAK_BEFORE
if ((lastStat & SpecialChars::CJK_NOBREAK_AFTER) == 0 &&
(curStat & SpecialChars::CJK_NOBREAK_BEFORE) == 0){
- current.rememberBreak(a-1, breakPos, style.rightMargin());
+ current.rememberBreak(i-1, breakPos, style.rightMargin());
}
}
@@ -2423,17 +2381,18 @@
double overflowWidth = 0.0;
double hyphWidth = 0.0;
bool inOverflow = false;
- if (itemText.hasFlag(a,ScLayout_HyphenationPossible) || currentCh == SpecialChars::SHYPHEN)
+ if (glyphRuns[i].hasFlag(ScLayout_HyphenationPossible) || itemText.text(a) == SpecialChars::SHYPHEN)
hyphWidth = font.charWidth('-', hlcsize10) * (charStyle.scaleH() / 1000.0);
- if ((current.isEndOfLine(style.rightMargin() + hyphWidth)) || current.isEndOfCol(realDesc) || SpecialChars::isBreak(currentCh, Cols > 1) || (current.xPos - current.maxShrink + hyphWidth) >= current.mustLineEnd)
- {
+ if ((current.isEndOfLine(style.rightMargin() + hyphWidth)) || current.isEndOfCol(realDesc) || SpecialChars::isBreak(itemText.text(a), Cols > 1) || (current.xPos - current.maxShrink + hyphWidth) >= current.mustLineEnd)
+ {
+
//end of row reached - right column, end of column, break char or line must end
- if (current.itemsInLine == 0 && !current.afterOverflow && !SpecialChars::isBreak(currentCh, Cols > 1))
+ if (current.isEmpty && !current.afterOverflow && !SpecialChars::isBreak(itemText.text(a), Cols > 1))
{
//no glyphs in line, so start new row
- if (SpecialChars::isBreak(currentCh, Cols > 1))
- current.restartRowIndex = a +1;
- a = current.restartRow(true);
+ if (SpecialChars::isBreak(itemText.text(a), Cols > 1))
+ current.restartRowIndex = i + 1;
+ i = current.restartRow(true);
inOverflow = false;
outs = false;
continue;
@@ -2442,13 +2401,14 @@
if (current.breakIndex < 0)
{
//force break
- if (!SpecialChars::isBreak(currentCh, Cols > 1))
+ if (!SpecialChars::isBreak(itemText.text(a), Cols > 1))
{
//force line end at previouse glyph
- a--;
+ i--;
+ a = glyphRuns[i].firstChar();
current.mustLineEnd = current.line.x;
}
- current.breakLine(itemText, style, firstLineOffset(),a);
+ current.breakLine(style, firstLineOffset(), i);
}
if (!current.addLine && !current.lastInRowLine && current.afterOverflow)
{
@@ -2457,7 +2417,7 @@
//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.line.firstItem == current.restartIndex)
+ if (current.line.firstRun == current.restartIndex)
current.lastInRowLine = true;
if (current.hasDropCap && DropLinesCount == 0 && current.restartIndex == current.restartRowIndex)
{
@@ -2465,12 +2425,13 @@
maxDX = 0;
current.yPos = maxDY;
}
- a = current.restartLine(false,true);
+ i = current.restartLine(false,true);
outs = false;
inOverflow = false;
continue;
}
outs = true;
+
current.addLine = true;
current.lastInRowLine = true;
current.rightMargin = style.rightMargin();
@@ -2480,7 +2441,7 @@
else
{
int charStart, charEnd;
- if (current.itemsInLine == 0)
+ if (current.isEmpty)
{
charStart = static_cast<int>(floor(current.line.x));
charEnd = static_cast<int>(ceil(current.xPos));
@@ -2491,10 +2452,10 @@
charEnd = static_cast<int>(ceil(current.xPos - current.maxShrink));
}
if (legacy &&
- (((currentCh == '-' || itemText.hasFlag(a, ScLayout_HyphenationPossible)) && (current.hyphenCount < m_Doc->hyphConsecutiveLines() || m_Doc->hyphConsecutiveLines() == 0))
- || currentCh == SpecialChars::SHYPHEN))
- {
- if (itemText.hasFlag(a, ScLayout_HyphenationPossible) || currentCh == SpecialChars::SHYPHEN)
+ (((itemText.text(a) == '-' || glyphRuns[i].hasFlag(ScLayout_HyphenationPossible)) && (current.hyphenCount < m_Doc->hyphConsecutiveLines() || m_Doc->hyphConsecutiveLines() == 0))
+ || itemText.text(a) == SpecialChars::SHYPHEN))
+ {
+ if (glyphRuns[i].hasFlag(ScLayout_HyphenationPossible) || itemText.text(a) == SpecialChars::SHYPHEN)
{
pt1 = QPoint(charStart, regionMinY);
pt2 = QPoint(static_cast<int>(charEnd + hyphWidth), regionMaxY -1);
@@ -2505,7 +2466,7 @@
pt2 = QPoint(charEnd, regionMaxY -1);
}
}
- else if (!legacy && SpecialChars::isBreakingSpace(currentCh))
+ else if (!legacy && SpecialChars::isBreakingSpace(itemText.text(a)))
{
pt1 = QPoint(static_cast<int>(qMax(floor(breakPos - current.maxShrink - (style.minGlyphExtension() * wide)),0.0)), regionMinY);
pt2 = QPoint(charEnd, regionMaxY -1);
@@ -2536,11 +2497,11 @@
}
if (outs)
{
- if (current.itemsInLine == 0)
+ if (current.isEmpty)
{
current.line.x = current.xPos = realEnd;
- a--;
- current.startLine(a+1);
+ i--;
+ current.startLine(i+1);
if (!current.wasFirstInRow)
current.addLeftIndent = true;
if (current.hasDropCap && DropLinesCount == 0 && !current.afterOverflow)
@@ -2554,8 +2515,9 @@
}
if (current.breakIndex < 0)
{
- a--;
- current.breakLine(itemText, style, firstLineOffset(), a);
+ i--;
+ a = glyphRuns[i].firstChar();
+ current.breakLine(style, firstLineOffset(), i);
}
//check if after overflow text can be placed
overflowWidth = realEnd - (current.xPos - current.maxShrink);
@@ -2577,7 +2539,7 @@
current.lastInRowLine = true;
current.mustLineEnd = current.line.x;
}
- else if (current.line.firstItem == current.restartIndex)
+ else if (current.line.firstRun == current.restartIndex)
current.lastInRowLine = true;
}
else
@@ -2587,7 +2549,7 @@
current.hasDropCap = false;
maxDX = 0;
}
- a = current.restartLine(false, true);
+ i = current.restartLine(false, true);
inOverflow = false;
outs = false;
continue;
@@ -2604,13 +2566,13 @@
}
// hyphenation
- if ((itemText.hasFlag(a, ScLayout_HyphenationPossible)
- || currentCh == '-'
- || currentCh == SpecialChars::SHYPHEN)
- && (!outs) && !itemText.text(a-1).isSpace() )
+ if ((glyphRuns[i].hasFlag(ScLayout_HyphenationPossible)
+ || itemText.text(a) == '-'
+ || itemText.text(a) == SpecialChars::SHYPHEN)
+ && (!outs) && !itemText.text(glyphRuns[i - 1].lastChar()).isSpace() )
{
breakPos = current.xPos;
- if (currentCh != '-')
+ if (itemText.text(a) != '-')
{
breakPos += hyphWidth;
}
@@ -2622,22 +2584,22 @@
if (legacy || (breakPos - rightHang < current.colRight - style.rightMargin()))
{
- if ((current.hyphenCount < m_Doc->hyphConsecutiveLines()) || (m_Doc->hyphConsecutiveLines() == 0) || currentCh == SpecialChars::SHYPHEN)
+ if ((current.hyphenCount < m_Doc->hyphConsecutiveLines()) || (m_Doc->hyphConsecutiveLines() == 0) || itemText.text(a) == SpecialChars::SHYPHEN)
{
- current.rememberBreak(a, breakPos, style.rightMargin() + hyphWidth);
- }
- }
- }
-
- if ((currentCh == SpecialChars::FRAMEBREAK) && (a < itemText.length()-1))
+ current.rememberBreak(i, breakPos, style.rightMargin() + hyphWidth);
+ }
+ }
+ }
+
+ if ((itemText.text(a) == SpecialChars::FRAMEBREAK) && (a < itemText.length()-1))
goNoRoom = true;
- if ((currentCh == SpecialChars::COLBREAK) && (Cols > 1))
+ if ((itemText.text(a) == SpecialChars::COLBREAK) && (Cols > 1))
goNextColumn = true;
if (a != firstInFrame() && implicitBreak(itemText.text(a - 1), itemText.text(a)))
- current.rememberBreak(a - 1, breakPos);
-
- ++current.itemsInLine;
+ current.rememberBreak(i -1, breakPos);
+
+ current.isEmpty = (i - current.line.firstRun + 1) == 0;
if (tabs.active)
{
@@ -2645,10 +2607,10 @@
if (tabs.status == TabCENTER)
cen = 2;
- double newTabAdvance = itemText.getGlyphs(tabs.charIndex)->xadvance - (wide+kernVal) / cen;
+ double newTabAdvance = tabs.tabGlyph->xadvance - wide / cen;
if (newTabAdvance >= 0) {
- itemText.getGlyphs(tabs.charIndex)->xadvance = newTabAdvance;
+ tabs.tabGlyph->xadvance = newTabAdvance;
}
else {
tabs.active = false;
@@ -2658,7 +2620,7 @@
if ((DropCmode || BulNumMode) && !outs)
{
current.xPos += style.parEffectOffset();
- glyphs->last()->xadvance += style.parEffectOffset();
+ lastGlyph.xadvance += style.parEffectOffset();
if (DropCmode)
{
DropCmode = false;
@@ -2678,17 +2640,17 @@
{
tabs.active = false;
tabs.status = TabNONE;
- if (SpecialChars::isBreak(currentCh, Cols > 1))
+ if (SpecialChars::isBreak(itemText.text(a), Cols > 1))
{
// find end of line
- current.breakLine(itemText, style, firstLineOffset(), a);
+ current.breakLine(style, firstLineOffset(), i);
EndX = current.endOfLine(m_availableRegion, style.rightMargin(), regionMinY, regionMaxY);
current.finishLine(EndX);
//addLine = true;
assert(current.addLine);
//current.startOfCol = false;
//addLeftIndent = true;
- if (currentCh == SpecialChars::PARSEP)
+ if (itemText.text(a) == SpecialChars::PARSEP)
{
maxDX = 0;
if (current.hasDropCap)
@@ -2702,7 +2664,7 @@
// if (style.alignment() != 0)
{
if (opticalMargins & ParagraphStyle::OM_RightHangingPunct)
- current.line.width += opticalRightMargin(itemText, current.line);
+ current.line.width += opticalRightMargin(itemText, glyphRuns, current.line);
OFs = 0;
if (style.alignment() == ParagraphStyle::Rightaligned)
@@ -2714,22 +2676,22 @@
if (style.alignment() == ParagraphStyle::Extended
|| (style.alignment() == ParagraphStyle::Justified
- && (currentCh == SpecialChars::LINEBREAK ||
- currentCh == SpecialChars::FRAMEBREAK ||
- currentCh == SpecialChars::COLBREAK)
- && !itemText.text(current.line.lastItem - 1).isSpace()))
+ && (itemText.text(a) == SpecialChars::LINEBREAK ||
+ itemText.text(a) == SpecialChars::FRAMEBREAK ||
+ itemText.text(a) == SpecialChars::COLBREAK)
+ && !itemText.text(glyphRuns[current.line.lastRun - 1].lastChar()).isSpace()))
{
- justifyLine(itemText, current.line);
+ justifyLine(style, current);
}
else
{
if (opticalMargins & ParagraphStyle::OM_RightHangingPunct)
- current.line.naturalWidth += opticalRightMargin(itemText, current.line);
+ current.line.naturalWidth += opticalRightMargin(itemText, glyphRuns, current.line);
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
- indentLine(itemText, current.line, OFs);
+ indentLine(style, current, OFs);
}
current.xPos = current.colRight;
}
@@ -2737,11 +2699,14 @@
else // outs -- last char went outside the columns (or into flow-around shape)
{
if (current.breakIndex >= 0)
- a = current.breakIndex;
- assert( a >= 0 );
- assert( a < itemText.length() );
- glyphs = itemText.getGlyphs(a);
- current.itemsInLine = a - current.line.firstItem + 1;
+ {
+ i = current.breakIndex;
+ a = glyphRuns[i].firstChar();
+ }
+ assert( i >= 0 );
+ assert( i < glyphRuns.length() );
+ //glyphs = itemText.getGlyphs(a);
+ current.isEmpty = (i - current.line.firstRun + 1) == 0;
if (current.addLine)
{
// go back to last break position
@@ -2752,40 +2717,44 @@
style.setLineSpacing(m_Doc->guidesPrefs().valueBaselineGrid);
if (itemText.text(a) == ' ') {
- itemText.setFlag(a, ScLayout_SuppressSpace);
- glyphs->xadvance = 0;
+ glyphRuns[i].setFlag(ScLayout_SuppressSpace);
+ glyphRuns[i].glyphs()[0].xadvance = 0;
}
- current.updateHeightMetrics(itemText);
+ current.updateHeightMetrics();
//current.updateLineOffset(itemText, style, firstLineOffset());
//current.xPos = current.breakXPos;
EndX = current.endOfLine(m_availableRegion, current.rightMargin, regionMinY, regionMaxY);
current.finishLine(EndX);
hyphWidth = 0.0;
- if (itemText.hasFlag(a, ScLayout_HyphenationPossible) || itemText.text(a) == SpecialChars::SHYPHEN)
+ if (glyphRuns[i].hasFlag(ScLayout_HyphenationPossible) || itemText.text(a) == SpecialChars::SHYPHEN)
{
// insert hyphen
if (current.lastInRowLine)
//increase hyphen count only for hyphens a the end of text row, omit hyphens before overflow
current.hyphenCount++;
- itemText.setFlag(a, ScLayout_SoftHyphenVisible);
- glyphs->grow();
- glyphs->more->glyph = font.char2CMap(QChar('-'));
- glyphs->more->xadvance = 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 = glyphs->more->xadvance;
+ glyphRuns[i].setFlag(ScLayout_SoftHyphenVisible);
+ GlyphLayout hyphen;
+ hyphen.glyph = font.char2CMap(QChar('-'));
+ hyphen.xadvance = font.glyphBBox(hyphen.glyph, itemText.charStyle(a).fontSize() / 10.0).width;
+ hyphWidth = hyphen.xadvance * scaleH;
+ glyphRuns[i].glyphs().append(hyphen);
}
else
{
if (itemText.text(a) != '-')
current.hyphenCount = 0;
- itemText.clearFlag(a, ScLayout_SoftHyphenVisible);
- glyphs->shrink();
+ if (glyphRuns[i].hasFlag(ScLayout_SoftHyphenVisible))
+ {
+ glyphRuns[i].clearFlag(ScLayout_SoftHyphenVisible);
+ glyphRuns[i].glyphs().removeLast();
+ }
}
// Justification
if (opticalMargins & ParagraphStyle::OM_RightHangingPunct)
- current.line.width += opticalRightMargin(itemText, current.line);
+ current.line.width += opticalRightMargin(itemText, glyphRuns, current.line);
// #12565: Right alignment of hyphens
// The additional character width has already been taken into account
// above via the line break position, so it's not necessary to increase
@@ -2805,12 +2774,12 @@
OFs = (current.line.width - current.line.naturalWidth) / 2;
if ((style.alignment() == ParagraphStyle::Justified) || (style.alignment() == ParagraphStyle::Extended))
- justifyLine(itemText, current.line);
+ justifyLine(style, current);
else
{
if (opticalMargins & ParagraphStyle::OM_RightHangingPunct)
- current.line.naturalWidth += opticalRightMargin(itemText, current.line);
- indentLine(itemText, current.line, OFs);
+ current.line.naturalWidth += opticalRightMargin(itemText, glyphRuns, current.line);
+ indentLine(style, current, OFs);
}
current.xPos = current.line.x + current.line.width;
}
@@ -2833,10 +2802,10 @@
if (current.isEndOfCol(desc))
{
//check if really line extends bottom margin
- current.updateHeightMetrics(itemText);
+ current.updateHeightMetrics();
if (current.isEndOfCol(current.line.descent))
{
- if (current.itemsInLine == 0 || current.column+1 == Cols)
+ if (current.isEmpty || current.column+1 == Cols)
{
goNoRoom = true;
MaxChars = a + 1;
@@ -2849,22 +2818,23 @@
}
else
setMaxY(maxYDesc);
- if (current.line.firstItem <= current.line.lastItem && current.itemsInLine > 0)
+ if (current.line.firstRun <= current.line.lastRun && !current.isEmpty)
{
if (current.addLine && current.breakIndex >= 0)
{
- if (itemText.charStyle(current.line.firstItem).effects() & ScLayout_DropCap)
+ if (glyphRuns[current.line.firstRun].style().effects() & ScLayout_DropCap)
{
// put line back to top
current.line.y -= DropCapDrop;
- itemText.getGlyphs(current.line.firstItem)->yoffset += DropCapDrop;
+ glyphRuns[current.line.firstRun].glyphs().first().yoffset += DropCapDrop;
}
- fillInTabLeaders(itemText, current.line);
+ fillInTabLeaders(current);
//if right margin is set we temporally save line, not append it
- textLayout.appendLine(current.line);
+ textLayout.appendLine(current.createLineBox());
setMaxY(maxYDesc);
- current.restartIndex = current.line.lastItem +1;
- a = current.restartIndex -1;
+ current.restartIndex = current.line.lastRun + 1;
+ i = current.line.lastRun;
+ a = glyphRuns[i].firstChar();
current.rowDesc = qMax(current.rowDesc,current.yPos + current.line.descent);
if (!current.lastInRowLine)
{
@@ -2879,7 +2849,7 @@
else if (!inOverflow && !current.afterOverflow && current.lastInRowLine)
{
current.yPos++;
- a = current.restartLine(true, true);
+ i = current.restartLine(true, true);
inOverflow = false;
outs = false;
current.mustLineEnd = current.colRight;
@@ -2930,7 +2900,8 @@
outs = false;
current.addLine = false;
current.lastInRowLine = false;
- current.startLine(a+1);
+ // WTF does i+1 mean here, what if i is the last run we have!
+ current.startLine(i+1);
if (goNoRoom)
{
goNoRoom = false;
@@ -2945,7 +2916,7 @@
{
if (firstLineOffset() == FLOPRealGlyphHeight)
asce = 0;
- current.nextColumn();
+ current.nextColumn(textLayout);
current.mustLineEnd = current.colRight;
current.addLeftIndent = true;
lastLineY = m_textDistanceMargins.top();
@@ -2961,23 +2932,23 @@
}
}
}
- if (a == itemText.length() -1)
+ if (i == glyphRuns.length() - 1)
{
if (!current.afterOverflow || current.addLine)
{
current.addLine = true;
current.lastInRowLine = true;
- current.breakLine(itemText, style, firstLineOffset(),a);
+ current.breakLine(style, firstLineOffset(), i);
}
if (current.afterOverflow && !current.addLine)
{
- if (current.restartIndex < current.line.firstItem)
+ if (current.restartIndex < current.line.firstRun)
{
- a = current.restartLine(false,true);
+ i = current.restartLine(false,true);
continue;
}
else
- current.breakLine(itemText, style, firstLineOffset(),a);
+ current.breakLine(style, firstLineOffset(), i);
}
}
}
@@ -2988,10 +2959,11 @@
}
// end of itemText
// now place the last line
- if (current.itemsInLine > 0 )
+ if (!current.isEmpty)
{
int a = itemText.length()-1;
- current.breakLine(itemText, style, firstLineOffset(), a);
+ int i = glyphRuns.length() - 1;
+ current.breakLine(style, firstLineOffset(), i);
if (current.startOfCol)
{
@@ -3029,7 +3001,7 @@
current.finishLine(EndX);
if (opticalMargins & ParagraphStyle::OM_RightHangingPunct)
- current.line.width += opticalRightMargin(itemText, current.line);
+ current.line.width += opticalRightMargin(itemText, glyphRuns, current.line);
OFs = 0;
if (style.alignment() == ParagraphStyle::Rightaligned)
@@ -3043,27 +3015,27 @@
&& (itemText.text(a) == SpecialChars::LINEBREAK ||
itemText.text(a) == SpecialChars::FRAMEBREAK ||
itemText.text(a) == SpecialChars::COLBREAK)
- && !itemText.text(current.line.firstItem + current.itemsInLine-1).isSpace()))
- {
- justifyLine(itemText, current.line);
+ && !itemText.text(a).isSpace()))
+ {
+ justifyLine(style, current);
}
else
{
if (opticalMargins & ParagraphStyle::OM_RightHangingPunct)
- current.line.naturalWidth += opticalRightMargin(itemText, current.line);
- indentLine(itemText, current.line, OFs);
- }
- if ( itemText.charStyle(current.line.firstItem).effects() & ScLayout_DropCap )
+ current.line.naturalWidth += opticalRightMargin(itemText, glyphRuns, current.line);
+ indentLine(style, current, OFs);
+ }
+ if (glyphRuns[current.line.firstRun].style().effects() & ScLayout_DropCap)
{
// put line back to top
current.line.y -= DropCapDrop;
- itemText.getGlyphs(current.line.firstItem)->yoffset += DropCapDrop;
- }
- fillInTabLeaders(itemText, current.line);
+ glyphRuns[current.line.firstRun].glyphs().first().yoffset += DropCapDrop;
+ }
+ fillInTabLeaders(current);
current.startOfCol = false;
goNextColumn = false;
- textLayout.appendLine(current.line);
+ textLayout.appendLine(current.createLineBox());
setMaxY(maxYDesc);
current.startOfCol = false;
@@ -3077,20 +3049,12 @@
MaxChars = itemText.length();
if ((verticalAlign > 0) && (NextBox == NULL))
{
- int vertAlign = verticalAlign;
- double topDist = m_textDistanceMargins.top();
- double hAdjust = 0;
- if (verticalAlign == 1)
- hAdjust = (height() - (m_textDistanceMargins.bottom() + lineCorr) - maxY) / 2.0;
- else if (verticalAlign == 2)
- hAdjust = (height() - (m_textDistanceMargins.bottom() + lineCorr) - maxY);
+ double hAdjust = height() - textLayout.box()->naturalHeight();
if (hAdjust > 0)
{
- m_textDistanceMargins.setTop(topDist + hAdjust);
- verticalAlign = 0;
- layout();
- m_textDistanceMargins.setTop(topDist);
- verticalAlign = vertAlign;
+ if (verticalAlign == 1)
+ hAdjust /= 2;
+ textLayout.box()->moveBy(0, hAdjust);
}
}
invalid = false;
@@ -3220,20 +3184,6 @@
if (m_Doc->RePos)
return;
QTransform pf2;
- QPoint pt1, pt2;
- double wide;
- QString cachedStroke = "";
- QString cachedFill = "";
- double cachedFillShade = -1;
- double cachedStrokeShade = -1;
- QString actStroke = "";
- QString actFill = "";
- double actFillShade = -1;
- double actStrokeShade = -1;
- QColor cachedFillQ;
- QColor cachedStrokeQ;
- // QValueList<ParagraphStyle::TabRecord> tTabValues;
- double desc, asce;
// tTabValues.clear();
p->save(); //SA1
@@ -3696,326 +3646,16 @@
}
assert( firstInFrame() >= 0 );
assert( lastInFrame() < itemText.length() );
- LineSpec ls;
-
- uint llp = 0;
- while (llp < textLayout.lines())
- {
- ls = textLayout.line(llp++);
- const ParagraphStyle& LineStyle = itemText.paragraphStyle(ls.firstItem);
- if (LineStyle.backgroundColor() != CommonStrings::None)
- {
- QColor tmp;
- SetQColor(&tmp, LineStyle.backgroundColor(), LineStyle.backgroundShade());
- double y0 = ls.y;
- double y2 = ls.y;
- double ascent = ls.ascent;
- double descent = ls.descent;
- double rMarg = LineStyle.rightMargin();
- double lMarg = ls.colLeft;
- double adjX = 0;
- if (LineStyle.firstIndent() <= 0)
- adjX += LineStyle.leftMargin() + LineStyle.firstIndent();
- while (llp < textLayout.lines())
- {
- ls = textLayout.line(llp);
- if ((ls.colLeft > lMarg) || (itemText.paragraphStyle(ls.firstItem) != LineStyle))
- {
- if (y2 == 0)
- y2 = y0;
- break;
- }
- if (itemText.text(ls.lastItem) == SpecialChars::PARSEP)
- {
- y2 = ls.y;
- descent = ls.descent;
- if ((llp + 1) < textLayout.lines())
- {
- if ((textLayout.line(llp + 1).lastItem - textLayout.line(llp + 1).firstItem) > 0)
- descent += LineStyle.lineSpacing() - (ls.descent + textLayout.line(llp + 1).ascent);
- }
- llp++;
- break;
- }
- y2 = ls.y;
- descent = ls.descent;
- if ((llp + 1) < textLayout.lines())
- descent += LineStyle.lineSpacing() - (ls.descent + textLayout.line(llp + 1).ascent);
- llp++;
- }
- p->save();
- p->setupPolygon(&PoLine);
- p->setClipPath();
- p->setAntialiasing(false);
- p->setFillMode(1);
- p->setStrokeMode(0);
- p->setBrush(tmp);
- p->drawRect(lMarg + adjX, y0 - ascent, columnWidth() - adjX - rMarg, y2 - y0 + descent + ascent);
- p->setAntialiasing(true);
- p->restore();
- }
- }
- for (uint ll=0; ll < textLayout.lines(); ++ll)
- {
- ls = textLayout.line(ll);
- double CurX = ls.x;
- // Draw text selection rectangles
- QRectF selectedFrame;
- QList<QRectF> sFList;
- bool previousWasObject(false);
- double selX = ls.x;
- GlyphLayout* glyphs = 0;
- int last = qMin(ls.lastItem, itemText.length() - 1);
- for (int as = ls.firstItem; as <= last; ++as)
- {
- bool selecteds = itemText.selected(as);
- glyphs = itemText.getGlyphs(as);
- bool HasObject = itemText.hasObject(as);
- Mark* mark = itemText.mark(as);
- if (mark != NULL && (mark->isType(MARKAnchorType) || mark->isType(MARKIndexType)))
- continue;
- if (selecteds)
- {
- const CharStyle& charStyleS(itemText.charStyle(as));
- if (((as > ls.firstItem) && (charStyleS != itemText.charStyle(as-1)))
- || ((!selectedFrame.isNull()) && HasObject)
- || previousWasObject)
- {
- sFList << selectedFrame;
- selectedFrame = QRectF();
- previousWasObject = false;
- }
- if ((m_isSelected || (NextBox != 0 || BackBox != 0))
- && (m_Doc->appMode == modeEdit || m_Doc->appMode == modeEditTable))
- {
- double xcoZli = selX + glyphs->xoffset;
- // ugly hack to make selection correct, as xoffset is used to
- // remove left-half of CJK lparen , which is blank.
- if (glyphs->xoffset)
- {
- int attr = SpecialChars::getCJKAttr(itemText.text(as)) & SpecialChars::CJK_CHAR_MASK;
- if (attr == SpecialChars::CJK_FENCE_BEGIN)
- {
- xcoZli -= glyphs->xoffset;
- }
- }
- const ScFace font = charStyleS.font();
- double fontSize = charStyleS.fontSize() / 10.0;
- desc = - font.descent(fontSize);
- asce = font.ascent(fontSize);
- wide = glyphs->wide();
- QRectF scr;
- if (HasObject)
- {
- PageItem* obj = itemText.object(as);
- double ww = (obj->width() + obj->lineWidth()) * glyphs->scaleH;
- double hh = (obj->height() + obj->lineWidth()) * glyphs->scaleV;
- scr = QRectF(xcoZli, ls.y - hh, ww , hh);
- previousWasObject = true;
- }
- else
- scr = QRectF(xcoZli, ls.y + glyphs->yoffset - asce * glyphs->scaleV, wide , (asce+desc) * (glyphs->scaleV));
- selectedFrame |= scr;
- }
- }
- // Unneeded now that glyph xadvance is set appropriately for inline objects by layout() - JG
- /*if ((hls->ch == SpecialChars::OBJECT) && (hls->embedded.hasItem()))
- selX += (hls->embedded.getItem()->gWidth + hls->embedded.getItem()->lineWidth()) * hls->glyph.scaleH;
- else*/
- selX += glyphs->wide();
- }
- if (!selectedFrame.isNull())
- sFList << selectedFrame;
- p->save();//SA3
- p->setFillMode(1);
- p->setBrush(qApp->palette().color(QPalette::Active, QPalette::Highlight));
- p->setLineWidth(0);
- // TODO - I dunno why but scpainter does not accept
- // to actually set the pen to 0? As a wa,
- // we set its color same as brush: "Ã malin, malin et demi!".
- p->setPen(qApp->palette().color(QPalette::Active, QPalette::Highlight));
- for(int sfc(0);sfc < sFList.count();++sfc)
- p->drawRect(sFList[sfc].x(), sFList[sfc].y(), sFList[sfc].width(), sFList[sfc].height());
- p->restore();//RE3
- // End of selection
-
- QColor tmp;
- double CurXB = ls.x;
- QRectF scrG;
- QString oldBack;
- double oldShade = 100;
- for (int a = ls.firstItem; a <= last; ++a)
- {
- glyphs = itemText.getGlyphs(a);
- const CharStyle& charStyle(itemText.charStyle(a));
- if (charStyle.backColor() != CommonStrings::None)
- {
- SetQColor(&tmp, charStyle.backColor(), charStyle.backShade());
- const ParagraphStyle& LineStyle = itemText.paragraphStyle(ls.firstItem);
- double y1 = ls.y;
- double hl = ls.height;
- if (LineStyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- hl = doc()->guidesPrefs().valueBaselineGrid;
- else if (LineStyle.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
- hl = LineStyle.lineSpacing();
- if (ls.isFirstLine)
- {
- if (textLayout.lines() == 1)
- hl = ls.ascent + ls.descent;
- if (LineStyle.hasDropCap() && (a == ls.firstItem))
- hl *= LineStyle.dropCapLines();
- if (LineStyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- y1 -= LineStyle.lineSpacing();
- else if (firstLineOffset() == FLOPRealGlyphHeight || firstLineOffset() == FLOPFontAscent)
- y1 -= ls.ascent;
- else
- y1 -= LineStyle.lineSpacing();
- }
- else
- y1 -= ls.ascent + (hl - (ls.ascent + ls.descent)) / 2.0;
- QRectF scr;
- if (itemText.hasObject(a))
- {
- PageItem* obj = itemText.object(a);
- double ww = (obj->width() + obj->lineWidth()) * glyphs->scaleH;
- double hh = (obj->height() + obj->lineWidth()) * glyphs->scaleV;
- scr = QRectF(CurXB, ls.y - hh, ww , hh);
- }
- else
- scr = QRectF(CurXB, y1, glyphs->wide(), hl);
- if ((oldBack.isEmpty()) || ((oldBack == charStyle.backColor()) && (oldShade == charStyle.backShade())))
- scrG |= scr;
- else if ((oldBack != charStyle.backColor()) || (oldShade != charStyle.backShade()))
- {
- p->save();
- p->setFillMode(1);
- p->setStrokeMode(0);
- SetQColor(&tmp, oldBack, oldShade);
- p->setBrush(tmp);
- p->drawRect(scrG.x(), scrG.y(), scrG.width(), scrG.height());
- p->restore();
- scrG = scr;
- }
- oldBack = charStyle.backColor();
- oldShade = charStyle.backShade();
- }
- else
- {
- oldBack.clear();
- oldShade = 100;
- if (!scrG.isNull())
- {
- p->save();
- p->setFillMode(1);
- p->setStrokeMode(0);
- p->setBrush(tmp);
- p->drawRect(scrG.x(), scrG.y(), scrG.width(), scrG.height());
- p->restore();
- }
- scrG = QRectF();
- }
- CurXB += glyphs->wide();
- }
- if (!scrG.isNull())
- {
- p->save();
- p->setFillMode(1);
- p->setStrokeMode(0);
- p->setBrush(tmp);
- p->drawRect(scrG.x(), scrG.y(), scrG.width(), scrG.height());
- p->restore();
- }
- for (int a = ls.firstItem; a <= last; ++a)
- {
- glyphs = itemText.getGlyphs(a);
- const CharStyle& charStyle(itemText.charStyle(a));
- bool selected = itemText.selected(a);
- actFill = charStyle.fillColor();
- actFillShade = charStyle.fillShade();
- if (actFill != CommonStrings::None)
- {
- p->setFillMode(ScPainter::Solid);
- if ((cachedFillShade != actFillShade) || (cachedFill != actFill))
- {
- SetQColor(&tmp, actFill, actFillShade);
- p->setBrush(tmp);
- cachedFillQ = tmp;
- cachedFill = actFill;
- cachedFillShade = actFillShade;
- }
- else
- p->setBrush(cachedFillQ);
- }
- else
- p->setFillMode(ScPainter::None);
-
- const ScFace font = charStyle.font();
- double fontSize = charStyle.fontSize() / 10.0;
- desc = - font.descent(fontSize);
- asce = font.ascent(fontSize);
- if (((selected && m_isSelected) || ((NextBox != 0 || BackBox != 0) && selected)) && (m_Doc->appMode == modeEdit || m_Doc->appMode == modeEditTable))
- {
- // set text color to highlight if its selected
- p->setBrush(qApp->palette().color(QPalette::Active, QPalette::HighlightedText));
- }
-
- actStroke = charStyle.strokeColor();
- actStrokeShade = charStyle.strokeShade();
- if (actStroke != CommonStrings::None)
- {
- if ((cachedStrokeShade != actStrokeShade) || (cachedStroke != actStroke))
- {
- SetQColor(&tmp, actStroke, actStrokeShade);
- p->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
- cachedStrokeQ = tmp;
- cachedStroke = actStroke;
- cachedStrokeShade = actStrokeShade;
- }
- else
- p->setPen(cachedStrokeQ, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
- }
- // paint glyphs
- QRectF scrGl;
- if (itemText.hasObject(a))
- {
- PageItem* obj = itemText.object(a);
- double ww = (obj->width() + obj->lineWidth()) * glyphs->scaleH;
- double hh = (obj->height() + obj->lineWidth()) * glyphs->scaleV;
- scrGl = QRectF(CurX, ls.y + glyphs->yoffset, ww , -hh).normalized();
- previousWasObject = true;
- }
- else
- scrGl = QRectF(CurX + glyphs->xoffset, ls.y + glyphs->yoffset - asce * glyphs->scaleV, glyphs->xadvance+1 , (asce+desc) * (glyphs->scaleV));
- if (isEmbedded || cullingArea.intersects(pf2.mapRect(scrGl)))
- {
- p->save();//SA4
- p->translate(CurX, ls.y);
- if (itemText.hasObject(a))
- DrawObj_Embedded(p, cullingArea, charStyle, itemText.object(a));
- else
- {
- //control chars for marks
- if (m_Doc->guidesPrefs().showControls && itemText.hasMark(a) && (glyphs->glyph != SpecialChars::OBJECT))
- {
- GlyphLayout markGlyph;
- layoutGlyphs(charStyle, SpecialChars::OBJECT, ScLayout_None, markGlyph);
- drawGlyphs(p, charStyle, ScLayout_None, markGlyph);
- }
- drawGlyphs(p, charStyle, itemText.flags(a), *glyphs);
- }
- p->restore();//RE4
- }
- // Unneeded now that glyph xadvance is set appropriately for inline objects by layout() - JG
- /*if ((hl->ch == SpecialChars::OBJECT) && (hl->embedded.hasItem()))
- CurX += (hl->embedded.getItem()->gWidth + hl->embedded.getItem()->lineWidth()) * hl->glyph.scaleH;
- else*/
- CurX += glyphs->wide();
- }
- }
- // else {
- // // qDebug("skipping textframe: len=%d", itemText.count());
- // }
- // pf2.end();
+
+ int fm = p->fillMode();
+ int sm = p->strokeMode();
+ p->setFillMode(1);
+ p->setStrokeMode(1);
+ ScreenPainter painter(p, this);
+ textLayout.renderBackground(&painter);
+ textLayout.render(&painter, this);
+ p->setFillMode(fm);
+ p->setStrokeMode(sm);
}
m_textDistanceMargins=savedTextDistanceMargins;
p->restore();//RE1
@@ -4489,7 +4129,7 @@
ExpandSel(1, oldPos);
}
else
- if ((textLayout.lines() > 0) && (oldPos >= textLayout.line(textLayout.lines()-1).firstItem) && (itemText.cursorPosition() >= lastInFrame()) && (NextBox != 0))
+ if ((textLayout.lines() > 0) && (oldPos >= textLayout.line(textLayout.lines()-1)->firstChar()) && (itemText.cursorPosition() >= lastInFrame()) && (NextBox != 0))
{
if (NextBox->frameDisplays(itemText.cursorPosition()))
{
@@ -4540,7 +4180,7 @@
ExpandSel(-1, oldPos);
}
else
- if ((textLayout.lines() > 0) && (oldPos <= textLayout.line(0).lastItem) && (itemText.cursorPosition() == firstInFrame()) && (BackBox != 0))
+ if ((textLayout.lines() > 0) && (oldPos <= textLayout.line(0)->lastChar()) && (itemText.cursorPosition() == firstInFrame()) && (BackBox != 0))
{
view->Deselect(true);
// TODO position at the right place in previous frame
@@ -6254,58 +5894,33 @@
void PageItem_TextFrame::setTextFrameHeight()
{
- //ugly hack increasing min frame`s haeight against strange glyph painting if it is too close of bottom
- double hackValue = 0.5;
-
if (textLayout.lines() <= 0)
return;
- const LineSpec& firstLine = textLayout.line(0);
- const LineSpec& lastLine = textLayout.line(textLayout.lines() -1);
-
- double y1 = firstLine.y /*- firstLine.ascent*/;
- double y2 = lastLine.y + lastLine.descent;
-
- const ParagraphStyle& firstLineStyle = itemText.paragraphStyle(firstLine.firstItem);
- if (firstLineStyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- y1 -= firstLineStyle.lineSpacing();
- else if (firstLineOffset() == FLOPRealGlyphHeight || firstLineOffset() == FLOPFontAscent)
- y1 -= firstLine.ascent;
- else
- y1 -= firstLineStyle.lineSpacing();
-
- double newHeight = ceil(y2) + m_textDistanceMargins.bottom() + hackValue;
+
if (NextBox == 0) // Vertical alignment is not used inside a text chain
{
- if (verticalAlign == 1)
- newHeight -= floor(y1);
- else if (verticalAlign == 2)
- newHeight = m_height - floor(y1);
- }
-
- UndoTransaction undoTransaction;
- if (UndoManager::undoEnabled() && (verticalAlign != 0))
- {
- QString unitSuffix = unitGetStrFromIndex(m_Doc->unitIndex());
- int unitPrecision = unitGetPrecisionFromIndex(m_Doc->unitIndex());
- double unitRatio = m_Doc->unitRatio();
- QString owString = QString::number(oldWidth * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
- QString ohString = QString::number(oldHeight * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
- QString nwString = QString::number(m_width * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
- QString nhString = QString::number(m_height * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
- QString tooltip = QString(Um::ResizeFromTo).arg(owString).arg(ohString).arg(nwString).arg(nhString);
- undoTransaction = undoManager->beginTransaction(Um::Selection, Um::ITextFrame, Um::Resize, tooltip, Um::IResize);
- }
-
- if (verticalAlign != 0)
- {
- double newX = m_xPos + floor(y1) * cos(-m_rotation * M_PI / 180 - M_PI / 2);
- double newY = m_yPos - floor(y1) * sin(-m_rotation * M_PI / 180 - M_PI / 2);
- setXYPos(newX, newY);
- }
- setHeight(newHeight);
-
- if (undoTransaction)
- undoTransaction.commit();
+ textLayout.box()->moveTo(textLayout.box()->x(), 0);
+ double newHeight = textLayout.box()->naturalHeight();
+
+ UndoTransaction undoTransaction;
+ if (UndoManager::undoEnabled())
+ {
+ QString unitSuffix = unitGetStrFromIndex(m_Doc->unitIndex());
+ int unitPrecision = unitGetPrecisionFromIndex(m_Doc->unitIndex());
+ double unitRatio = m_Doc->unitRatio();
+ QString owString = QString::number(oldWidth * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
+ QString ohString = QString::number(oldHeight * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
+ QString nwString = QString::number(m_width * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
+ QString nhString = QString::number(m_height * unitRatio, 'f', unitPrecision) + " " + unitSuffix;
+ QString tooltip = QString(Um::ResizeFromTo).arg(owString).arg(ohString).arg(nwString).arg(nhString);
+ undoTransaction = undoManager->beginTransaction(Um::Selection, Um::ITextFrame, Um::Resize, tooltip, Um::IResize);
+ }
+
+ setHeight(newHeight);
+
+ if (undoTransaction)
+ undoTransaction.commit();
+ }
updateClip();
invalid = true;
Modified: trunk/Scribus/scribus/pageitem_textframe.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/pageitem_textframe.h
==============================================================================
--- trunk/Scribus/scribus/pageitem_textframe.h (original)
+++ trunk/Scribus/scribus/pageitem_textframe.h Wed Mar 23 20:21:36 2016
@@ -159,6 +159,9 @@
public:
void setTextFrameHeight();
+
+private:
+ QList<GlyphRun> shapeText();
};
#endif
Modified: trunk/Scribus/scribus/pdflib_core.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/pdflib_core.cpp
==============================================================================
--- trunk/Scribus/scribus/pdflib_core.cpp (original)
+++ trunk/Scribus/scribus/pdflib_core.cpp Wed Mar 23 20:21:36 2016
@@ -71,6 +71,7 @@
#include "sccolor.h"
#include "sccolorengine.h"
#include "scfonts.h"
+#include "text/textlayoutpainter.h"
#include "fonts/cff.h"
#include "fonts/sfnt.h"
#include "scpage.h"
@@ -87,6 +88,7 @@
#include "util_formats.h"
#include "util_math.h"
#include "util_ghostscript.h"
+#include "text/boxes.h"
#ifdef HAVE_OSG
#include "third_party/prc/exportPRC.h"
@@ -103,6 +105,376 @@
#undef GetObject
#endif
+static inline QByteArray FToStr(double c)
+{
+ double v = c;
+ if (fabs(c) < 0.0000001)
+ v = 0.0;
+ return QByteArray::number(v, 'f', 5);
+}
+
+class PdfPainter: public TextLayoutPainter
+{
+ QByteArray m_glyphBuffer;
+ QByteArray m_pathBuffer;
+ PageItem* m_item;
+ QMap<QString, PdfFont> m_UsedFontsP;
+ PDFLibCore *m_pdf;
+ uint m_PNr;
+ const ScPage* m_page;
+
+ QByteArray transformToStr(QTransform tr)
+ {
+ return FToStr(tr.m11()) + " " + FToStr(-tr.m12()) + " " + FToStr(-tr.m21()) + " " + FToStr(tr.m22()) + " " + FToStr(tr.dx()) + " " + FToStr(-tr.dy());
+ }
+
+public:
+ PdfPainter(PageItem *ite, PDFLibCore *pdf, uint num, const ScPage* pag) :
+ m_glyphBuffer(),
+ m_pathBuffer(),
+ m_item(ite),
+ m_pdf(pdf),
+ m_PNr(num),
+ m_page(pag)
+ {}
+
+ ~PdfPainter() {}
+
+ void drawGlyph(const GlyphLayout gl)
+ {
+ if (gl.glyph >= ScFace::CONTROL_GLYPHS)
+ return;
+
+ PdfFont pdfFont = m_pdf->UsedFontsP[font().replacementName()];
+ QByteArray StrokeColor;
+ QByteArray FillColor;
+ QTransform transform = matrix();
+
+ if (strokeColor().color != CommonStrings::None)
+ StrokeColor = m_pdf->putColor(strokeColor().color, strokeColor().shade, false);
+ if (fillColor().color != CommonStrings::None)
+ FillColor = m_pdf->putColor(fillColor().color, fillColor().shade, true);
+
+ if (pdfFont.method == Use_XForm)
+ {
+ if (!FillColor.isEmpty())
+ m_pathBuffer += FillColor;
+
+ m_pathBuffer += "q\n";
+ m_glyphBuffer += FToStr(fontSize()) + " 0 0 " + FToStr(fontSize()) + " " + FToStr(x()) + " " + FToStr(y()) + " cm\n";
+
+ if (gl.scaleV != 1.0)
+ m_pathBuffer += "1 0 0 1 0 " + FToStr(((fontSize() - fontSize() * gl.scaleV) / fontSize()) * -1) + " cm\n";
+
+ transform.scale(qMax(gl.scaleH, 0.1), qMax(gl.scaleV, 0.1));
+ m_glyphBuffer += transformToStr(transform) + " cm\n";
+
+ if (!FillColor.isEmpty())
+ m_pathBuffer += pdfFont.name + Pdf::toPdf(gl.glyph) + " Do\n";
+ m_pathBuffer += "Q\n";
+ }
+ else
+ {
+ uint gid = gl.glyph;
+ uint fontNr = 65535;
+
+ switch (pdfFont.encoding)
+ {
+ case Encode_256:
+ gid = pdfFont.glyphmap[gid];
+ fontNr = gid / 256;
+ gid = gid % 256;
+ break;
+ case Encode_224:
+ fontNr = gid / 224;
+ gid = gid % 224 + 32;
+ break;
+ case Encode_Subset:
+ gid = pdfFont.glyphmap[gid];
+ break;
+ case Encode_IdentityH:
+ break;
+ }
+
+ if (fontNr == 65535)
+ m_glyphBuffer += pdfFont.name + " " + FToStr(fontSize()) + " Tf\n";
+ else
+ m_glyphBuffer += pdfFont.name + "S" + Pdf::toPdf(fontNr) + " " + FToStr(fontSize()) + " Tf\n";
+
+ if (!StrokeColor.isEmpty())
+ m_glyphBuffer += StrokeColor;
+
+ if (!FillColor.isEmpty())
+ m_glyphBuffer += FillColor;
+
+ m_glyphBuffer += "0 Tr\n";
+
+ transform.translate(x(), y());
+ transform.scale(qMax(gl.scaleH, 0.1), qMax(gl.scaleV, 0.1));
+ m_glyphBuffer += transformToStr(transform) + " Tm\n";
+
+
+ if (pdfFont.method != Use_Type3 || !FillColor.isEmpty())
+ {
+ switch (pdfFont.encoding)
+ {
+ case Encode_224:
+ case Encode_256:
+ m_glyphBuffer += Pdf::toHexString8(gid) + " Tj\n";
+ break;
+ case Encode_IdentityH:
+ default:
+ m_glyphBuffer += Pdf::toHexString16(gid) + " Tj\n";
+ break;
+ }
+ }
+ }
+ }
+
+ void drawGlyphOutline(const GlyphLayout gl, bool fill)
+ {
+ if (gl.glyph >= ScFace::CONTROL_GLYPHS)
+ return;
+
+ PdfFont pdfFont = m_pdf->UsedFontsP[font().replacementName()];
+ QByteArray StrokeColor;
+ QByteArray FillColor;
+ QTransform transform = matrix();
+
+ if (strokeColor().color != CommonStrings::None)
+ StrokeColor = m_pdf->putColor(strokeColor().color, strokeColor().shade, false);
+ if (fill && fillColor().color != CommonStrings::None)
+ FillColor = m_pdf->putColor(fillColor().color, fillColor().shade, true);
+
+ if (pdfFont.method == Use_XForm)
+ {
+ if (!StrokeColor.isEmpty())
+ {
+ m_pathBuffer += FToStr(strokeWidth()) + " w\n[] 0 d\n0 J\n0 j\n";
+ m_pathBuffer += StrokeColor;
+ }
+
+ if (!FillColor.isEmpty())
+ m_pathBuffer += FillColor;
+
+ m_pathBuffer += "q\n";
+ m_glyphBuffer += FToStr(fontSize()) + " 0 0 " + FToStr(fontSize()) + " " + FToStr(x()) + " " + FToStr(y()) + " cm\n";
+
+ if (gl.scaleV != 1.0)
+ m_pathBuffer += "1 0 0 1 0 " + FToStr(((fontSize() - fontSize() * (gl.scaleV)) / fontSize()) * -1) + " cm\n";
+
+ transform.scale(qMax(gl.scaleH, 0.1), qMax(gl.scaleV, 0.1));
+ m_pathBuffer += transformToStr(transform) + " cm\n";
+
+ if (!FillColor.isEmpty())
+ m_pathBuffer += pdfFont.name + Pdf::toPdf(gl.glyph) + " Do\n";
+
+ FPointArray outline = font().glyphOutline(gl.glyph);
+ QTransform mat;
+ mat.scale(0.1, 0.1);
+ outline.map(mat);
+ bool nPath = true;
+ FPoint np;
+ if (outline.size() > 3)
+ {
+ for (int poi = 0; poi < outline.size() - 3; poi += 4)
+ {
+ if (outline.isMarker(poi))
+ {
+ m_pathBuffer += "h\n";
+ nPath = true;
+ continue;
+ }
+
+ if (nPath)
+ {
+ np = outline.point(poi);
+ m_pathBuffer += FToStr(np.x()) + " " + FToStr(-np.y()) + " m\n";
+ nPath = false;
+ }
+
+ np = outline.point(poi + 1);
+ m_pathBuffer += FToStr(np.x()) + " " + FToStr(-np.y()) + " ";
+ np = outline.point(poi + 3);
+ m_pathBuffer += FToStr(np.x()) + " " + FToStr(-np.y()) + " ";
+ np = outline.point(poi + 2);
+ m_pathBuffer += FToStr(np.x()) + " " + FToStr(-np.y()) + " c\n";
+ }
+ }
+ m_pathBuffer += "h s\n";
+ m_pathBuffer += "Q\n";
+ }
+ else
+ {
+ if (!StrokeColor.isEmpty())
+ m_pathBuffer += StrokeColor;
+
+ uint gid = gl.glyph;
+ uint fontNr = 65535;
+ switch (pdfFont.encoding)
+ {
+ case Encode_256:
+ gid = pdfFont.glyphmap[gid];
+ fontNr = gid / 256;
+ gid = gid % 256;
+ break;
+ case Encode_224:
+ fontNr = gid / 224;
+ gid = gid % 224 + 32;
+ break;
+ case Encode_Subset:
+ gid = pdfFont.glyphmap[gid];
+ break;
+ case Encode_IdentityH:
+ break;
+ }
+
+ if (fontNr == 65535)
+ m_glyphBuffer += pdfFont.name + " " + FToStr(fontSize()) + " Tf\n";
+ else
+ m_glyphBuffer += pdfFont.name + "S" + Pdf::toPdf(fontNr) + " " + FToStr(fontSize()) + " Tf\n";
+
+ if (!StrokeColor.isEmpty())
+ m_glyphBuffer += StrokeColor;
+
+ if (!FillColor.isEmpty())
+ m_glyphBuffer += FillColor;
+
+ if (pdfFont.method == Use_Type3 && !StrokeColor.isEmpty())
+ {
+ m_pathBuffer += "q\n";
+ m_pathBuffer += FToStr(strokeWidth()) + " w\n[] 0 d\n0 J\n0 j\n";
+
+ transform.scale(fontSize(), fontSize());
+ transform.translate(x(), y());
+ if (gl.scaleV != 1.0)
+ transform.translate(0, ((fontSize() - fontSize() * gl.scaleV) / fontSize()) * -1);
+ transform.scale(qMax(gl.scaleH, 0.1), qMax(gl.scaleV, 0.1));
+ m_pathBuffer += transformToStr(transform) + " cm\n";
+
+ /* paint outline */
+ FPointArray outline = font().glyphOutline(gl.glyph);
+ QTransform mat;
+ mat.scale(0.1, 0.1);
+ outline.map(mat);
+ bool nPath = true;
+ FPoint np;
+ if (outline.size() > 3)
+ {
+ for (int poi = 0; poi < outline.size() - 3; poi += 4)
+ {
+ if (outline.isMarker(poi))
+ {
+ m_pathBuffer += "h\n";
+ nPath = true;
+ continue;
+ }
+
+ if (nPath)
+ {
+ np = outline.point(poi);
+ m_pathBuffer += FToStr(np.x()) + " " + FToStr(-np.y()) + " m\n";
+ nPath = false;
+ }
+
+ np = outline.point(poi + 1);
+ m_pathBuffer += FToStr(np.x()) + " " + FToStr(-np.y()) + " ";
+ np = outline.point(poi + 3);
+ m_pathBuffer += FToStr(np.x()) + " " + FToStr(-np.y()) + " ";
+ np = outline.point(poi + 2);
+ m_pathBuffer += FToStr(np.x()) + " " + FToStr(-np.y()) + " c\n";
+ }
+ }
+ m_pathBuffer += "h s\n";
+ m_pathBuffer += "Q\n";
+ }
+ else
+ {
+ m_glyphBuffer += FToStr(strokeWidth()) + " w ";
+ if (fill)
+ m_glyphBuffer += "2 Tr\n";
+ else
+ m_glyphBuffer += "1 Tr\n";
+ }
+
+ transform.translate(x(), y());
+ transform.scale(qMax(gl.scaleH, 0.1), qMax(gl.scaleV, 0.1));
+ m_glyphBuffer += transformToStr(transform) + " Tm\n";
+
+ if (pdfFont.method != Use_Type3 || !FillColor.isEmpty())
+ {
+ switch (pdfFont.encoding)
+ {
+ case Encode_224:
+ case Encode_256:
+ m_glyphBuffer += Pdf::toHexString8(gid) + " Tj\n";
+ break;
+ case Encode_IdentityH:
+ default:
+ m_glyphBuffer += Pdf::toHexString16(gid) + " Tj\n";
+ break;
+ }
+ }
+ }
+ }
+
+ void drawLine(QPointF start, QPointF end)
+ {
+ QTransform transform = matrix();
+ transform.translate(x(), y());
+ m_pathBuffer += "q\n";
+ m_pathBuffer += transformToStr(transform) + " cm\n";
+ m_pathBuffer += m_pdf->putColor(strokeColor().color, strokeColor().shade, false);
+ m_pathBuffer += FToStr(strokeWidth())+" w\n";
+ m_pathBuffer += FToStr(start.x()) + " " + FToStr(-start.y()) + " m\n";
+ m_pathBuffer += FToStr(end.x()) + " " + FToStr(-end.y()) + " l\n";
+ m_pathBuffer += "S\n";
+ m_pathBuffer += "Q\n";
+ }
+
+ QByteArray getBuffer()
+ {
+ return "BT\n" + m_glyphBuffer + "ET\n" + m_pathBuffer;
+ }
+
+ void drawRect(QRectF rect)
+ {
+ QTransform transform = matrix();
+// transform.translate(x(), y());
+ double rectX = x() + rect.x();
+ double rectY = -y() - rect.y();
+ m_glyphBuffer += "q\n";
+ m_glyphBuffer += transformToStr(transform) + " cm\n";
+ m_glyphBuffer += "n\n";
+ m_glyphBuffer += m_pdf->putColor(fillColor().color, fillColor().shade, true);
+ m_glyphBuffer += m_pdf->putColor(strokeColor().color, strokeColor().shade, false);
+ m_glyphBuffer += FToStr(rectX) + " " + FToStr(rectY) + " m\n";
+ m_glyphBuffer += FToStr(rectX + rect.width()) + " " + FToStr(rectY) + " l\n";
+ m_glyphBuffer += FToStr(rectX + rect.width()) + " " + FToStr(rectY - rect.height()) + " l\n";
+ m_glyphBuffer += FToStr(rectX) + " " + FToStr(rectY - rect.height()) + " l\n";
+ m_glyphBuffer += "h\nf\n";
+ m_glyphBuffer += "Q\n";
+ }
+
+ void drawObject(PageItem* embedded)
+ {
+ m_glyphBuffer += "ET\n"+m_pathBuffer;
+ m_pathBuffer = "";
+
+ m_pathBuffer += "q\n";
+ m_pathBuffer += FToStr(scaleH()) + " 0 0 " + FToStr(scaleV()) + " " + FToStr(x()) + " " + FToStr(-y()) + " cm\n";
+
+ QByteArray output;
+ if (!m_pdf->PDF_ProcessItem(output, embedded, m_page, m_PNr, true))
+ return;
+ m_pathBuffer += output;
+ m_pathBuffer += "Q\n";
+ m_glyphBuffer += m_pathBuffer+"\n";
+ m_pathBuffer = "";
+
+ m_glyphBuffer += "BT\n";
+ }
+};
PDFLibCore::PDFLibCore(ScribusDoc & docu)
: QObject(&docu),
@@ -170,13 +542,6 @@
delete progressDialog;
}
-static inline QByteArray FToStr(double c)
-{
- double v = c;
- if (fabs(c) < 0.0000001)
- v = 0.0;
- return QByteArray::number(v, 'f', 5);
-};
bool PDFLibCore::PDF_IsPDFX()
{
@@ -5380,853 +5745,10 @@
// Return a PDF substring representing a PageItem's text
QByteArray PDFLibCore::setTextSt(PageItem *ite, uint PNr, const ScPage* pag)
{
- int tabCc = 0;
- int savedOwnPage = ite->OwnPage;
- double tabDist = ite->textToFrameDistLeft();
- QByteArray tmp(""), tmp2("");
- QList<ParagraphStyle::TabRecord> tTabValues;
- ite->OwnPage = PNr;
- ite->layout();
- ite->OwnPage = savedOwnPage;
- if (ite->lineColor() != CommonStrings::None)
- tabDist += ite->lineWidth() / 2.0;
- // Loop over each character (!) in the pageItem...
- if (ite->itemType() == PageItem::TextFrame)
- {
- PathData straightPath;
- straightPath.PtransX = 0;
- straightPath.PtransY = 0;
- straightPath.PRot = 0;
- straightPath.PDx = 0;
- tmp += "BT\n";
- uint llp = 0;
- while (llp < ite->textLayout.lines())
- {
- LineSpec ls = ite->textLayout.line(llp++);
- const ParagraphStyle& LineStyle = ite->itemText.paragraphStyle(ls.firstItem);
- if (LineStyle.backgroundColor() != CommonStrings::None)
- {
- double y0 = ls.y;
- double y2 = ls.y;
- double ascent = ls.ascent;
- double descent = ls.descent;
- double rMarg = LineStyle.rightMargin();
- double lMarg = ls.colLeft;
- double adjX = 0;
- if (LineStyle.firstIndent() <= 0)
- adjX += LineStyle.leftMargin() + LineStyle.firstIndent();
- while (llp < ite->textLayout.lines())
- {
- ls = ite->textLayout.line(llp);
- if ((ls.colLeft > lMarg) || (ite->itemText.paragraphStyle(ls.firstItem) != LineStyle))
- {
- if (y2 == 0)
- y2 = y0;
- break;
- }
- if (ite->itemText.text(ls.lastItem) == SpecialChars::PARSEP)
- {
- y2 = ls.y;
- descent = ls.descent;
- if ((llp + 1) < ite->textLayout.lines())
- {
- if ((ite->textLayout.line(llp + 1).lastItem - ite->textLayout.line(llp + 1).firstItem) > 0)
- descent += LineStyle.lineSpacing() - (ls.descent + ite->textLayout.line(llp + 1).ascent);
- }
- llp++;
- break;
- }
- y2 = ls.y;
- descent = ls.descent;
- if ((llp + 1) < ite->textLayout.lines())
- descent += LineStyle.lineSpacing() - (ls.descent + ite->textLayout.line(llp + 1).ascent);
- llp++;
- }
- QRectF scr(lMarg + adjX, y0 - ascent, ite->asTextFrame()->columnWidth() - adjX - rMarg, y2 - y0 + descent + ascent);
- tmp += "q\n";
- tmp += "n\n";
- tmp += SetPathAndClip(ite);
- tmp += putColor(LineStyle.backgroundColor(), LineStyle.backgroundShade(), true);
- tmp += FToStr(scr.x()) +" "+FToStr(-scr.y())+" m\n";
- tmp += FToStr(scr.x() + scr.width())+" "+FToStr(-scr.y())+" l\n";
- tmp += FToStr(scr.x() + scr.width())+" "+FToStr(-scr.y() - scr.height())+" l\n";
- tmp += FToStr(scr.x())+" "+FToStr(-scr.y() - scr.height())+" l\n";
- tmp += "h\nf\n";
- tmp += "Q\n";
- }
- }
- for (uint ll=0; ll < ite->textLayout.lines(); ++ll)
- {
- LineSpec ls = ite->textLayout.line(ll);
- tabDist = ls.x;
- double CurX = ls.x;
- double CurXB = ls.x;
- int last = qMin(ls.lastItem, ite->itemText.length() - 1);
- QRectF scr;
- QString oldBack = "";
- double oldShade = 100;
- QByteArray colorB = "";
- for (int a = ls.firstItem; a <= last; ++a)
- {
- const GlyphLayout* glyphs(ite->itemText.getGlyphs(a));
- const CharStyle& charStyle(ite->itemText.charStyle(a));
- if (charStyle.backColor() != CommonStrings::None)
- {
- colorB = putColor(charStyle.backColor(), charStyle.backShade(), true);
- // This code is for rendering character background color.
- const ParagraphStyle& LineStyle = ite->itemText.paragraphStyle(ls.firstItem);
- double y1 = ls.y;
- double hl = ls.height;
- if (LineStyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- hl = doc.guidesPrefs().valueBaselineGrid;
- else if (LineStyle.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
- hl = LineStyle.lineSpacing();
- if (ls.isFirstLine)
- {
- if (ite->textLayout.lines() == 1)
- hl = ls.ascent + ls.descent;
- if (LineStyle.hasDropCap() && (a == ls.firstItem))
- hl *= LineStyle.dropCapLines();
- if (LineStyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- y1 -= LineStyle.lineSpacing();
- else if (ite->firstLineOffset() == FLOPRealGlyphHeight || ite->firstLineOffset() == FLOPFontAscent)
- y1 -= ls.ascent;
- else
- y1 -= LineStyle.lineSpacing();
- }
- else
- y1 -= ls.ascent + (hl - (ls.ascent + ls.descent)) / 2.0;
- QRectF scrG;
- if (ite->itemText.hasObject(a))
- {
- PageItem* obj = ite->itemText.object(a);
- double ww = (obj->width() + obj->lineWidth()) * glyphs->scaleH;
- double hh = (obj->height() + obj->lineWidth()) * glyphs->scaleV;
- scrG = QRectF(CurXB, ls.y - hh, ww , hh);
- }
- else
- scrG = QRectF(CurXB, y1, glyphs->wide(), hl);
- if ((oldBack == "") || ((oldBack == charStyle.backColor()) && (oldShade == charStyle.backShade())))
- scr |= scrG;
- else if ((oldBack != charStyle.backColor()) || (oldShade != charStyle.backShade()))
- {
- tmp += "q\n";
- tmp += "n\n";
- tmp += putColor(oldBack, oldShade, true);
- tmp += FToStr(scr.x()) +" "+FToStr(-scr.y())+" m\n";
- tmp += FToStr(scr.x() + scr.width())+" "+FToStr(-scr.y())+" l\n";
- tmp += FToStr(scr.x() + scr.width())+" "+FToStr(-scr.y() - scr.height())+" l\n";
- tmp += FToStr(scr.x())+" "+FToStr(-scr.y() - scr.height())+" l\n";
- tmp += "h\nf\n";
- tmp += "Q\n";
- scr = scrG;
- }
- oldBack = charStyle.backColor();
- oldShade = charStyle.backShade();
- }
- else
- {
- if (!scr.isNull())
- {
- tmp += "q\n";
- tmp += colorB;
- tmp += FToStr(scr.x()) +" "+FToStr(-scr.y())+" m\n";
- tmp += FToStr(scr.x() + scr.width())+" "+FToStr(-scr.y())+" l\n";
- tmp += FToStr(scr.x() + scr.width())+" "+FToStr(-scr.y() - scr.height())+" l\n";
- tmp += FToStr(scr.x())+" "+FToStr(-scr.y() - scr.height())+" l\n";
- tmp += "h\nf\n";
- tmp += "Q\n";
- }
- oldBack = "";
- oldShade = 100;
- scr = QRectF();
- }
- CurXB += glyphs->wide();
- }
- if (!scr.isNull())
- {
- tmp += "q\n";
- tmp += colorB;
- tmp += FToStr(scr.x()) +" "+FToStr(-scr.y())+" m\n";
- tmp += FToStr(scr.x() + scr.width())+" "+FToStr(-scr.y())+" l\n";
- tmp += FToStr(scr.x() + scr.width())+" "+FToStr(-scr.y() - scr.height())+" l\n";
- tmp += FToStr(scr.x())+" "+FToStr(-scr.y() - scr.height())+" l\n";
- tmp += "h\nf\n";
- tmp += "Q\n";
- }
- for (int d = ls.firstItem; d <= ls.lastItem; ++d)
- {
- GlyphLayout* glyphs = ite->itemText.getGlyphs(d);
- PathData* pdata = &straightPath;
- const QChar ch = ite->itemText.text(d);
- const CharStyle& chstyle(ite->itemText.charStyle(d));
- const ParagraphStyle& pstyle(ite->itemText.paragraphStyle(d));
- if (SpecialChars::isBreak(ch, true) || (ch == QChar(10)))
- continue;
- if (ite->itemText.hasFlag(d, ScLayout_SuppressSpace))
- continue;
- tTabValues = pstyle.tabValues();
- if (ite->itemText.hasFlag(d, ScLayout_StartOfLine))
- tabCc = 0;
- if ((ch == SpecialChars::TAB) && (tTabValues.count() != 0))
- {
- QChar tabFillChar;
- const TabLayout* tabLayout = dynamic_cast<const TabLayout*>(glyphs->more);
- if (tabLayout)
- tabFillChar = tabLayout->fillChar;
- if (!tabFillChar.isNull())
- {
- GlyphLayout gl2;
- CharStyle cl2(chstyle);
- const GlyphLayout * const gl = glyphs->more;
- double scale = gl ? gl->scaleV : 1.0;
- double wt = chstyle.font().charWidth(tabFillChar, chstyle.fontSize() * scale / 10.0);
- double len = glyphs->xadvance;
- int coun = static_cast<int>(len / wt);
- // #6728 : update code according to fillInTabLeaders() and PageItem::layout() - JG
- double sPos = 0.0 /*CurX - len + chstyle.fontSize() / 10.0 * 0.7 + 1*/;
- //hl2.ch = tTabValues[tabCc].tabFillChar;
- cl2.setTracking(0);
- cl2.setScaleH(1000);
- cl2.setScaleV(1000);
- gl2.glyph = chstyle.font().char2CMap(tabFillChar);
- gl2.yoffset = glyphs->yoffset;
- for (int cx = 0; cx < coun; ++cx)
- {
- gl2.xoffset = sPos + wt * cx;
- if ((chstyle.effects() & ScStyle_Shadowed) && (chstyle.strokeColor() != CommonStrings::None))
- {
- GlyphLayout gl3;
- CharStyle cl3(cl2);
- //<< HACK to fix Bug #8446
- cl3.setEffects(cl3.effects() & (~(ScStyle_Outline)));
- //>>
- gl3.glyph = gl2.glyph;
- cl3.setFillColor(cl2.strokeColor());
- cl3.setFillShade(cl2.strokeShade());
- gl3.yoffset = gl2.yoffset - (chstyle.fontSize() * chstyle.shadowYOffset() / 10000.0);
- gl3.xoffset = gl2.xoffset + (chstyle.fontSize() * chstyle.shadowXOffset() / 10000.0);
- setTextCh(ite, PNr, CurX, ls.y, d, tmp, tmp2, cl3, &gl3, pdata, pstyle, pag);
- }
- setTextCh(ite, PNr, CurX, ls.y, d, tmp, tmp2, cl2, &gl2, pdata, pstyle, pag);
- }
- }
- tabCc++;
- }
- if (ch == SpecialChars::TAB)
- {
- CurX += glyphs->wide();
- continue;
- }
- if ((chstyle.effects() & ScStyle_Shadowed) && (chstyle.strokeColor() != CommonStrings::None))
- {
- GlyphLayout gl2(*glyphs);
- gl2.glyph = glyphs->glyph;
- const GlyphLayout *gl1 = glyphs;
- GlyphLayout* glx = &gl2;
- while (gl1->more)
- {
- glx->more = new GlyphLayout(*gl1->more);
- glx->more->yoffset -= (chstyle.fontSize() * chstyle.shadowYOffset() / 10000.0);
- glx->more->xoffset += (chstyle.fontSize() * chstyle.shadowXOffset() / 10000.0);
- glx->more->more = NULL;
- gl1 = gl1->more;
- glx = glx->more;
- }
- CharStyle cl2(chstyle);
- //<< HACK to fix Bug #8446
- cl2.setEffects(cl2.effects() & (~(ScStyle_Outline)));
- //>>
- cl2.setFillColor(chstyle.strokeColor());
- cl2.setFillShade(chstyle.strokeShade());
- gl2.xadvance = glyphs->xadvance;
- gl2.yadvance = glyphs->yadvance;
- gl2.yoffset = glyphs->yoffset - (chstyle.fontSize() * chstyle.shadowYOffset() / 10000.0);
- gl2.xoffset = glyphs->xoffset + (chstyle.fontSize() * chstyle.shadowXOffset() / 10000.0);
- gl2.scaleH = glyphs->scaleH;
- gl2.scaleV = glyphs->scaleV;
- setTextCh(ite, PNr, CurX, ls.y, d, tmp, tmp2, cl2, &gl2, pdata, pstyle, pag);
- gl2.shrink();
- }
- setTextCh(ite, PNr, CurX, ls.y, d, tmp, tmp2, chstyle, glyphs, pdata, pstyle, pag);
- // Unneeded now that glyph xadvance is set appropriately for inline objects by PageItem_TextFrame::layout() - JG
- /*if (hl->ch == SpecialChars::OBJECT)
- {
- InlineFrame& embedded(const_cast<InlineFrame&>(hl->embedded));
- CurX += (embedded.getItem()->gWidth + embedded.getItem()->lineWidth()) * hl->glyph.scaleH;
- }
- else*/
- CurX += glyphs->wide();
- tabDist = CurX;
- }
- }
- }
- else
- {
- ite->OwnPage = PNr;
- ite->asPathText()->layout();
- ite->OwnPage = savedOwnPage;
- double CurX = 0;
- for (int d = 0; d < ite->maxCharsInFrame(); ++d)
- {
- GlyphLayout* glyphs = ite->asPathText()->itemRenderText.getGlyphs(d);
- PathData* pdata = &ite->textLayout.point(d);
- const QChar ch = ite->asPathText()->itemRenderText.text(d);
- const CharStyle& chstyle(ite->asPathText()->itemRenderText.charStyle(d));
- const ParagraphStyle& pstyle(ite->asPathText()->itemRenderText.paragraphStyle(d));
- if (SpecialChars::isBreak(ch, true) || (ch == QChar(10)))
- continue;
- if (ite->asPathText()->itemRenderText.hasFlag(d, ScLayout_SuppressSpace))
- continue;
- tTabValues = pstyle.tabValues();
- if (ite->asPathText()->itemRenderText.hasFlag(d, ScLayout_StartOfLine))
- tabCc = 0;
- if ((ch == SpecialChars::TAB) && (tTabValues.count() != 0))
- {
- if ((tabCc < tTabValues.count()) && (!tTabValues[tabCc].tabFillChar.isNull()))
- {
- GlyphLayout gl2;
- CharStyle cl2(chstyle);
- double wt = chstyle.font().charWidth(tTabValues[tabCc].tabFillChar, chstyle.fontSize());
- int coun = static_cast<int>((CurX+ glyphs->xoffset - tabDist) / wt);
- // #6728 : update code according to fillInTabLeaders() and PageItem::layout() - JG
- double sPos = 0.0 /* CurX+hl->glyph.xoffset - (CurX+hl->glyph.xoffset - tabDist) + 1 */;
- gl2.glyph = chstyle.font().char2CMap(tTabValues[tabCc].tabFillChar);
- cl2.setTracking(0);
- cl2.setScaleH(1000);
- cl2.setScaleV(1000);
- gl2.yoffset = glyphs->yoffset;
- for (int cx = 0; cx < coun; ++cx)
- {
- glyphs->xoffset = sPos + wt * cx;
- if ((chstyle.effects() & ScStyle_Shadowed) && (chstyle.strokeColor() != CommonStrings::None))
- {
- GlyphLayout gl3;
- CharStyle cl3(cl2);
- //<< HACK to fix Bug #8446
- cl3.setEffects(cl3.effects() & (~(ScStyle_Outline)));
- //>>
- gl3.glyph = gl2.glyph;
- cl3.setFillColor(cl2.strokeColor());
- cl3.setFillShade(cl2.strokeShade());
- gl3.yoffset = gl2.yoffset - (chstyle.fontSize() * chstyle.shadowYOffset() / 10000.0);
- gl3.xoffset = gl2.xoffset + (chstyle.fontSize() * chstyle.shadowXOffset() / 10000.0);
- setTextCh(ite, PNr, 0, 0, d, tmp, tmp2, cl3, &gl3, pdata, pstyle, pag);
- }
- setTextCh(ite, PNr, 0, 0, d, tmp, tmp2, cl2, &gl2, pdata, pstyle, pag);
- }
- tabCc++;
- }
- else
- {
- tabCc++;
- }
- }
- if (ch == SpecialChars::TAB)
- {
- CurX += glyphs->wide();
- continue;
- }
- if ((chstyle.effects() & ScStyle_Shadowed) && (chstyle.strokeColor() != CommonStrings::None))
- {
- GlyphLayout gl2;
- gl2.glyph = glyphs->glyph;
- CharStyle cl2(chstyle);
- //<< HACK to fix Bug #8446
- cl2.setEffects(cl2.effects() & (~(ScStyle_Outline)));
- //>>
- cl2.setFillColor(chstyle.strokeColor());
- cl2.setFillShade(chstyle.strokeShade());
- gl2.yoffset = glyphs->yoffset - (chstyle.fontSize() * chstyle.shadowYOffset() / 10000.0);
- gl2.xoffset = glyphs->xoffset + (chstyle.fontSize() * chstyle.shadowXOffset() / 10000.0);
- gl2.scaleH = glyphs->scaleH;
- gl2.scaleV = glyphs->scaleV;
- setTextCh(ite, PNr, 0, 0, d, tmp, tmp2, cl2, &gl2, pdata, pstyle, pag);
- }
- setTextCh(ite, PNr, 0, 0, d, tmp, tmp2, chstyle, glyphs, pdata, pstyle, pag);
- CurX += glyphs->wide();
- tabDist = CurX;
- }
- }
- if (ite->itemType() == PageItem::TextFrame)
- tmp += "ET\n"+tmp2;
- return tmp;
-}
-
-bool PDFLibCore::setTextCh(PageItem *ite, uint PNr, double x, double y, uint d, QByteArray &tmp, QByteArray &tmp2, const CharStyle& style, GlyphLayout *glyphs, PathData* pdata, const ParagraphStyle& pstyle, const ScPage* pag)
-{
- QByteArray output;
- QByteArray FillColor = "";
- QByteArray StrokeColor = "";
- if (ite->asPathText())
- {
- tmp += "q\n";
- QPointF tangt = QPointF( cos(pdata->PRot), sin(pdata->PRot) );
- QTransform trafo = QTransform( 1, 0, 0, -1, -pdata->PDx, 0 );
- if (ite->textPathFlipped)
- trafo *= QTransform(1, 0, 0, -1, 0, 0);
- if (ite->textPathType == 0)
- trafo *= QTransform( tangt.x(), -tangt.y(), -tangt.y(), -tangt.x(), pdata->PtransX, -pdata->PtransY );
- else if (ite->textPathType == 1)
- trafo *= QTransform(1, 0, 0, -1, pdata->PtransX, -pdata->PtransY );
- else if (ite->textPathType == 2)
- {
- double a = 1;
- double b = -1;
- if (tangt.x() < 0)
- {
- a = -1;
- b = 1;
- }
- if (fabs(tangt.x()) > 0.1)
- trafo *= QTransform( a, (tangt.y() / tangt.x()) * b, 0, -1, pdata->PtransX, -pdata->PtransY ); // ID's Skew mode
- else
- trafo *= QTransform( a, 6 * b, 0, -1, pdata->PtransX, -pdata->PtransY );
- }
- tmp += FToStr(trafo.m11())+" "+FToStr(trafo.m12())+" "+FToStr(trafo.m21())+" "+FToStr(trafo.m22())+" "+FToStr(trafo.dx())+" "+FToStr(trafo.dy())+" cm\n";
- if (ite->BaseOffs != 0)
- tmp += "1 0 0 1 0 "+ FToStr( -ite->BaseOffs)+" cm\n";
- if (glyphs->xoffset != 0.0 || glyphs->yoffset != 0.0)
- tmp += "1 0 0 1 " + FToStr( glyphs->xoffset)+ " " + FToStr( -glyphs->yoffset)+" cm\n";
- if (ite->itemText.text(d) != SpecialChars::OBJECT)
- tmp += "BT\n";
- }
- QChar chstr = ite->itemText.text(d);
- double tsz = style.fontSize();
-
-/* if (hl->effects() & ScStyle_DropCap)
- {
- if (pstyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- tsz = qRound(10 * ((doc.typographicSettings.valueBaseGrid * (pstyle.dropCapLines()-1)+(hl->font().ascent(pstyle.charStyle().fontSize() / 10.0))) / (hl->font().realCharHeight(chstr, 10))));
- else
- {
- if (pstyle.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
- tsz = qRound(10 * ((pstyle.lineSpacing() * (pstyle.dropCapLines()-1)+(hl->font().ascent(pstyle.charStyle().fontSize() / 10.0))) / (hl->font().realCharHeight(chstr, 10))));
- else
- {
- double currasce = hl->font().height(pstyle.charStyle().fontSize());
- tsz = qRound(10 * ((currasce * (pstyle.dropCapLines()-1)+(hl->font().ascent(pstyle.charStyle().fontSize() / 10.0))) / hl->font().realCharHeight(chstr, 10)));
- }
- }
- }
- */
- if (ite->itemText.hasObject(d))
- {
- if (!ite->asPathText())
- {
- tmp += "ET\n"+tmp2;
- tmp2 = "";
- }
- PageItem* embedded = ite->itemText.object(d);
- tmp2 += "q\n";
- if (ite->asPathText())
- tmp2 += FToStr(style.scaleH() / 1000.0)+" 0 0 "+FToStr(style.scaleV() / 1000.0)+" "+FToStr(embedded->gXpos * (style.scaleH() / 1000.0))+" "+FToStr((embedded->height() * (style.scaleV() / 1000.0)) - embedded->gYpos * (style.scaleV() / 1000.0)+embedded->gHeight * (style.baselineOffset() / 1000.0))+" cm\n";
- else
- {
- if (d == 0 || ite->itemText.text(d-1) == SpecialChars::PARSEP)
- {
- if ((style.baselineOffset() != 0) && (!pstyle.hasDropCap()))
- tmp2 += FToStr(style.scaleH() / 1000.0)+" 0 0 "+FToStr(style.scaleV() / 1000.0)+" "+FToStr(x + glyphs->xoffset + embedded->gXpos * (style.scaleH() / 1000.0))+" "+FToStr(-y- glyphs->yoffset + (embedded->height() * (style.scaleV() / 1000.0)) - embedded->gYpos * (style.scaleV() / 1000.0)+embedded->height() * (style.baselineOffset() / 1000.0))+" cm\n";
- else
- tmp2 += FToStr(style.scaleH() / 1000.0)+" 0 0 "+FToStr(style.scaleV() / 1000.0)+" "+FToStr(x+ glyphs->xoffset + embedded->gXpos * (style.scaleH() / 1000.0))+" "+FToStr(-y- glyphs->yoffset + (embedded->height() * (style.scaleV() / 1000.0)) - embedded->gYpos * (style.scaleV() / 1000.0))+" cm\n";
- }
- else
- {
- if (style.baselineOffset() != 0)
- tmp2 += FToStr(style.scaleH() / 1000.0)+" 0 0 "+FToStr(style.scaleV() / 1000.0)+" "+FToStr(x+ glyphs->xoffset + embedded->gXpos * (style.scaleH() / 1000.0))+" "+FToStr(-y- glyphs->yoffset + (embedded->height() * (style.scaleV() / 1000.0)) - embedded->gYpos * (style.scaleV() / 1000.0)+embedded->height() * (style.baselineOffset() / 1000.0))+" cm\n";
- else
- tmp2 += FToStr(style.scaleH() / 1000.0)+" 0 0 "+FToStr(style.scaleV() / 1000.0)+" "+FToStr(x+ glyphs->xoffset + embedded->gXpos * (style.scaleH() / 1000.0))+" "+FToStr(-y- glyphs->yoffset + (embedded->height() * (style.scaleV() / 1000.0)) - embedded->gYpos * (style.scaleV() / 1000.0))+" cm\n";
- }
- }
- if (!PDF_ProcessItem(output, embedded, pag, PNr, true))
- return false;
- tmp2 +=output;
- tmp2 += "Q\n";
- tmp += tmp2+"\n";
- tmp2 = "";
- if (ite->asPathText())
- tmp += "Q\n";
- else
- tmp += "BT\n";
- return true;
- }
-
- PdfFont pdfFont = UsedFontsP[style.font().replacementName()];
- uint glyph = glyphs->glyph;
-
- if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBSPACE.unicode()) ||
- glyph == (ScFace::CONTROL_GLYPHS + 32))
- {
- glyph = style.font().char2CMap(QChar(' '));
- chstr = ' ';
- }
- else if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBHYPHEN.unicode()))
- {
- glyph = style.font().char2CMap(QChar('-'));
- chstr = '-';
- }
-
- if (glyph < ScFace::CONTROL_GLYPHS)
- {
- if (style.strokeColor() != CommonStrings::None)
- {
- StrokeColor = "";
- StrokeColor += putColor(style.strokeColor(), style.strokeShade(), false);
- }
- if (style.fillColor() != CommonStrings::None)
- {
- FillColor = "";
- FillColor += putColor(style.fillColor(), style.fillShade(), true);
- }
- if (((style.effects() & ScStyle_Underline) && (chstr != SpecialChars::PARSEP)) || ((style.effects() & ScStyle_UnderlineWords) && (!chstr.isSpace())))
- {
- // double Ulen = style.font().charWidth(chstr, style.fontSize()) * (hl->glyph.scaleH);
- double Ulen = glyphs->xadvance;
- double Upos, Uwid;
- if ((style.underlineOffset() != -1) || (style.underlineWidth() != -1))
- {
- if (style.underlineOffset() != -1)
- Upos = (style.underlineOffset() / 1000.0) * (style.font().descent(style.fontSize() / 10.0));
- else
- Upos = style.font().underlinePos(style.fontSize() / 10.0);
- if (style.underlineWidth() != -1)
- Uwid = (style.underlineWidth() / 1000.0) * (style.fontSize() / 10.0);
- else
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- else
- {
- Upos = style.font().underlinePos(style.fontSize() / 10.0);
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- if (style.baselineOffset() != 0)
- Upos += (style.fontSize() / 10.0) * glyphs->scaleV * (style.baselineOffset() / 1000.0);
- if (style.fillColor() != CommonStrings::None)
- tmp2 += putColor(style.fillColor(), style.fillShade(), false);
- tmp2 += FToStr(Uwid)+" w\n";
- if (ite->itemType() == PageItem::PathText)
- {
- if (style.effects() & ScStyle_Subscript)
- {
- tmp2 += FToStr(x+ glyphs->xoffset) +" "+FToStr(-y+Upos)+" m\n";
- tmp2 += FToStr(x+ glyphs->xoffset+Ulen)+" "+FToStr(-y+Upos)+" l\n";
- }
- else
- {
- tmp2 += FToStr(x+ glyphs->xoffset) +" "+FToStr(-y+ glyphs->yoffset+Upos)+" m\n";
- tmp2 += FToStr(x+ glyphs->xoffset+Ulen)+" "+FToStr(-y+ glyphs->yoffset+Upos)+" l\n";
- }
- }
- else
- {
- if (style.effects() & ScStyle_Subscript)
- {
- tmp2 += FToStr(x+ glyphs->xoffset) +" "+FToStr(-y- glyphs->yoffset+Upos)+" m\n";
- tmp2 += FToStr(x+ glyphs->xoffset+Ulen)+" "+FToStr(-y- glyphs->yoffset+Upos)+" l\n";
- }
- else
- {
- tmp2 += FToStr(x+ glyphs->xoffset) +" "+FToStr(-y+Upos)+" m\n";
- tmp2 += FToStr(x+ glyphs->xoffset+Ulen)+" "+FToStr(-y+Upos)+" l\n";
- }
- }
- tmp2 += "S\n";
- }
-
- if (pdfFont.method == Use_XForm)
- {
- if (glyph != style.font().char2CMap(QChar(' ')))
- {
- if ((style.strokeColor() != CommonStrings::None) && (style.effects() & ScStyle_Outline))
- {
- tmp2 += FToStr((tsz * style.outlineWidth() / 1000.0) / tsz)+" w\n[] 0 d\n0 J\n0 j\n";
- tmp2 += StrokeColor;
- }
- if (style.fillColor() != CommonStrings::None)
- tmp2 += FillColor;
- tmp2 += "q\n";
- // #see 8257 : transform is already computed at beginning of the function
- /*if (ite->itemType() == PageItem::PathText)
- {
- QPointF tangt = QPointF( cos(hl->PRot), sin(hl->PRot) );
- QTransform trafo = QTransform( 1, 0, 0, -1, -hl->PDx, 0 );
- if (ite->textPathFlipped)
- trafo *= QTransform(1, 0, 0, -1, 0, 0);
- if (ite->textPathType == 0)
- trafo *= QTransform(tangt.x(), -tangt.y(), -tangt.y(), -tangt.x(), hl->PtransX, -hl->PtransY);
- else if (ite->textPathType == 1)
- trafo *= QTransform(1, 0, 0, -1, hl->PtransX, -hl->PtransY );
- tmp2 += FToStr(trafo.m11())+" "+FToStr(trafo.m12())+" "+FToStr(trafo.m21())+" "+FToStr(trafo.m22())+" "+FToStr(trafo.dx())+" "+FToStr(trafo.dy())+" cm\n";
- }*/
- if (!ite->asPathText())
- {
- if (ite->reversed())
- {
- double wid = style.font().charWidth(chstr, style.fontSize()) * (glyphs->scaleH);
- tmp2 += "1 0 0 1 "+FToStr(x+ glyphs->xoffset)+" "+FToStr((y+ glyphs->yoffset - (tsz / 10.0)) * -1 + ((tsz / 10.0) * (style.baselineOffset() / 1000.0)))+" cm\n";
- tmp2 += "-1 0 0 1 0 0 cm\n";
- tmp2 += "1 0 0 1 "+FToStr(-wid)+" 0 cm\n";
- tmp2 += FToStr(tsz / 10.0)+" 0 0 "+FToStr(tsz / 10.0)+" 0 0 cm\n";
- }
- else
- {
- tmp2 += FToStr(tsz / 10.0)+" 0 0 "+FToStr(tsz / 10.0)+" "+FToStr(x+ glyphs->xoffset)+" "+FToStr((y+ glyphs->yoffset - (tsz / 10.0)) * -1 + ((tsz / 10.0) * (style.baselineOffset() / 1000.0)))+" cm\n";
- }
- }
- else
- {
- // if (ite->BaseOffs != 0)
- // tmp2 += "1 0 0 1 0 "+FToStr( -ite->BaseOffs)+" cm\n";
- tmp2 += FToStr(tsz / 10.0)+" 0 0 "+FToStr(tsz / 10.0)+" 0 "+FToStr(tsz / 10.0)+" cm\n";
- }
- if (glyphs->scaleV != 1.0)
- tmp2 += "1 0 0 1 0 "+FToStr( (((tsz / 10.0) - (tsz / 10.0) * (glyphs->scaleV)) / (tsz / 10.0)) * -1)+" cm\n";
- tmp2 += FToStr(qMax(glyphs->scaleH, 0.1))+" 0 0 "+FToStr(qMax(glyphs->scaleV, 0.1))+" 0 0 cm\n";
- if (style.fillColor() != CommonStrings::None)
- tmp2 += pdfFont.name + Pdf::toPdf(glyph)+" Do\n";
-
- if (style.effects() & ScStyle_Outline)
- {
- FPointArray gly = style.font().glyphOutline(glyph);
- QTransform mat;
- mat.scale(0.1, 0.1);
- gly.map(mat);
- bool nPath = true;
- FPoint np;
- if (gly.size() > 3)
- {
- for (int poi=0; poi<gly.size()-3; poi += 4)
- {
- if (gly.isMarker(poi))
- {
- tmp2 += "h\n";
- nPath = true;
- continue;
- }
- if (nPath)
- {
- np = gly.point(poi);
- tmp2 += FToStr(np.x())+" "+FToStr(-np.y())+" m\n";
- nPath = false;
- }
- np = gly.point(poi+1);
- tmp2 += FToStr(np.x())+" "+FToStr(-np.y())+" ";
- np = gly.point(poi+3);
- tmp2 += FToStr(np.x())+" "+FToStr(-np.y())+" ";
- np = gly.point(poi+2);
- tmp2 += FToStr(np.x())+" "+FToStr(-np.y())+" c\n";
- }
- }
- tmp2 += "h s\n";
- }
- tmp2 += "Q\n";
- }
- }
- else
- {
- if (style.strokeColor() != CommonStrings::None)
- {
- if ((style.effects() & ScStyle_Underline) || (style.effects() & ScStyle_Strikethrough) || (style.effects() & ScStyle_Outline))
- tmp2 += StrokeColor;
- }
- if (style.fillColor() != CommonStrings::None)
- {
- if ((style.effects() & ScStyle_Underline) || (style.effects() & ScStyle_Strikethrough))
- tmp2 += FillColor;
- }
- if (glyph != style.font().char2CMap(QChar(' ')))
- {
- uint gid = glyphs->glyph;
- uint fontNr = 65535;
- switch (pdfFont.encoding)
- {
- case Encode_256:
- gid = pdfFont.glyphmap[gid];
- fontNr = gid / 256;
- gid = gid % 256;
- break;
- case Encode_224:
- fontNr = gid / 224;
- gid = gid % 224 + 32;
- break;
- case Encode_Subset:
- gid = pdfFont.glyphmap[gid];
- break;
- case Encode_IdentityH:
- break;
- }
- if (fontNr == 65535)
- tmp+= pdfFont.name + " " + FToStr(tsz / 10.0)+" Tf\n";
- else
- tmp += pdfFont.name+"S"+Pdf::toPdf(fontNr) + " "+FToStr(tsz / 10.0)+" Tf\n";
- if (style.strokeColor() != CommonStrings::None)
- tmp += StrokeColor;
- if (style.fillColor() != CommonStrings::None)
- tmp += FillColor;
- if (pdfFont.method == Use_Type3 && (style.effects() & ScStyle_Outline) && (style.strokeColor() != CommonStrings::None))
- {
- tmp2 += "q\n";
- tmp2 += FToStr((tsz * style.outlineWidth() / 1000.0) / tsz)+" w\n[] 0 d\n0 J\n0 j\n";
- // #see 8257 : transform is already computed at beginning of the function
- /*if (ite->itemType() == PageItem::PathText)
- {
- QPointF tangt = QPointF( cos(hl->PRot), sin(hl->PRot) );
- QTransform trafo = QTransform( 1, 0, 0, -1, -hl->PDx, 0 );
- if (ite->textPathFlipped)
- trafo *= QTransform(1, 0, 0, -1, 0, 0);
- if (ite->textPathType == 0)
- trafo *= QTransform(tangt.x(), -tangt.y(), -tangt.y(), -tangt.x(), hl->PtransX, -hl->PtransY);
- else if (ite->textPathType == 1)
- trafo *= QTransform(1, 0, 0, -1, hl->PtransX, -hl->PtransY );
- tmp2 += FToStr(trafo.m11())+" "+FToStr(trafo.m12())+" "+FToStr(trafo.m21())+" "+FToStr(trafo.m22())+" "+FToStr(trafo.dx())+" "+FToStr(trafo.dy())+" cm\n";
- }*/
- if (!ite->asPathText())
- {
- if (ite->reversed())
- {
- double wid = style.font().charWidth(chstr, style.fontSize()) * (glyphs->scaleH);
- tmp2 += "1 0 0 1 "+FToStr(x+ glyphs->xoffset)+" "+FToStr((y+ glyphs->yoffset - (tsz / 10.0)) * -1 + ((tsz / 10.0) * (style.baselineOffset() / 1000.0)))+" cm\n";
- tmp2 += "-1 0 0 1 0 0 cm\n";
- tmp2 += "1 0 0 1 "+FToStr(-wid)+" 0 cm\n";
- tmp2 += FToStr(tsz / 10.0)+" 0 0 "+FToStr(tsz / 10.0)+" 0 0 cm\n";
- }
- else
- {
- tmp2 += FToStr(tsz / 10.0)+" 0 0 "+FToStr(tsz / 10.0)+" "+FToStr(x+ glyphs->xoffset)+" "+FToStr((y+ glyphs->yoffset - (tsz / 10.0)) * -1 + ((tsz / 10.0) * (style.baselineOffset() / 1000.0)))+" cm\n";
- }
- }
- else
- {
- tmp2 += FToStr(tsz / 10.0)+" 0 0 "+FToStr(tsz / 10.0)+" 0 "+FToStr(tsz / 10.0)+" cm\n";
- }
- if (glyphs->scaleV != 1.0)
- tmp2 += "1 0 0 1 0 "+FToStr( (((tsz / 10.0) - (tsz / 10.0) * (glyphs->scaleV)) / (tsz / 10.0)) * -1)+" cm\n";
- tmp2 += FToStr(qMax(glyphs->scaleH, 0.1))+" 0 0 "+FToStr(qMax(glyphs->scaleV, 0.1))+" 0 0 cm\n";
- /* paint outline */
- FPointArray gly = style.font().glyphOutline(glyph);
- QTransform mat;
- mat.scale(0.1, 0.1);
- gly.map(mat);
- bool nPath = true;
- FPoint np;
- if (gly.size() > 3)
- {
- for (int poi=0; poi<gly.size()-3; poi += 4)
- {
- if (gly.isMarker(poi))
- {
- tmp2 += "h\n";
- nPath = true;
- continue;
- }
- if (nPath)
- {
- np = gly.point(poi);
- tmp2 += FToStr(np.x())+" "+FToStr(-np.y())+" m\n";
- nPath = false;
- }
- np = gly.point(poi+1);
- tmp2 += FToStr(np.x())+" "+FToStr(-np.y())+" ";
- np = gly.point(poi+3);
- tmp2 += FToStr(np.x())+" "+FToStr(-np.y())+" ";
- np = gly.point(poi+2);
- tmp2 += FToStr(np.x())+" "+FToStr(-np.y())+" c\n";
- }
- }
- tmp2 += "h s\n";
- tmp2 += "Q\n";
- }
- else
- {
- if (style.effects() & ScStyle_Outline)
- tmp += FToStr(tsz * style.outlineWidth() / 10000.0) + (style.fillColor() != CommonStrings::None ? " w 2 Tr\n" : " w 1 Tr\n");
- else
- tmp += "0 Tr\n";
- }
- if (!ite->asPathText())
- {
- if (ite->reversed())
- {
- double wtr = glyphs->xadvance;
- tmp += FToStr(-qMax(glyphs->scaleH, 0.1))+" 0 0 "+FToStr(qMax(glyphs->scaleV, 0.1)) +" "+FToStr(x+ glyphs->xoffset+wtr)+" "+FToStr(-y- glyphs->yoffset+(style.fontSize() / 10.0) * (style.baselineOffset() / 1000.0))+" Tm\n";
- }
- else
- tmp += FToStr(qMax(glyphs->scaleH, 0.1))+" 0 0 "+FToStr(qMax(glyphs->scaleV, 0.1))+" "+FToStr(x+ glyphs->xoffset)+" "+FToStr(-y- glyphs->yoffset+(style.fontSize() / 10.0) * (style.baselineOffset() / 1000.0))+" Tm\n";
- }
- else
- {
- tmp += FToStr(qMax(glyphs->scaleH, 0.1))+" 0 0 "+FToStr(qMax(glyphs->scaleV, 0.1))+" 0 0 Tm\n";
- }
- if (pdfFont.method != Use_Type3 || style.fillColor() != CommonStrings::None)
- {
- switch (pdfFont.encoding)
- {
- case Encode_224:
- case Encode_256:
- tmp += Pdf::toHexString8(gid) + " Tj\n";
- break;
- case Encode_IdentityH:
- default:
- tmp += Pdf::toHexString16(gid) + " Tj\n";
- break;
- }
- }
- }
- }
- if ((style.effects() & ScStyle_Strikethrough) && (chstr != SpecialChars::PARSEP))
- {
- // double Ulen = style.font().charWidth(chstr, style.fontSize()) * (hl->glyph.scaleH);
- double Ulen = glyphs->xadvance;
- double Upos, Uwid;
- if ((style.strikethruOffset() != -1) || (style.strikethruWidth() != -1))
- {
- if (style.strikethruOffset() != -1)
- Upos = (style.strikethruOffset() / 1000.0) * (style.font().ascent(style.fontSize() / 10.0));
- else
- Upos = style.font().strikeoutPos(style.fontSize() / 10.0);
- if (style.strikethruWidth() != -1)
- Uwid = (style.strikethruWidth() / 1000.0) * (style.fontSize() / 10.0);
- else
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- else
- {
- Upos = style.font().strikeoutPos(style.fontSize() / 10.0);
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- if (style.baselineOffset() != 0)
- Upos += (style.fontSize() / 10.0) * glyphs->scaleV * (style.baselineOffset() / 1000.0);
- if (style.fillColor() != CommonStrings::None)
- tmp2 += putColor(style.fillColor(), style.fillShade(), false);
- tmp2 += FToStr(Uwid)+" w\n";
- if (ite->itemType() == PageItem::PathText)
- {
- tmp2 += FToStr(x+ glyphs->xoffset) +" "+FToStr(-y+Upos)+" m\n";
- tmp2 += FToStr(x+ glyphs->xoffset+Ulen)+" "+FToStr(-y+Upos)+" l\n";
- }
- else
- {
- tmp2 += FToStr(x+ glyphs->xoffset) +" "+FToStr(-y- glyphs->yoffset+Upos)+" m\n";
- tmp2 += FToStr(x+ glyphs->xoffset+Ulen)+" "+FToStr(-y- glyphs->yoffset+Upos)+" l\n";
- }
- tmp2 += "S\n";
- }
- if (ite->asPathText())
- {
- tmp += "ET\n"+tmp2+"Q\n";
- tmp2 = "";
- }
- }
- if (glyphs->more) {
-// // ugly hack until setTextCh interface is changed
-// ScText hl2(*hl);
-// hl2.glyph = *(hl->glyph.more);
- if (!setTextCh(ite, PNr, x + glyphs->xadvance, y, d, tmp, tmp2, style, glyphs->more, pdata, pstyle, pag))
- return false;
-// // don't let hl2's destructor delete these!
-// hl2.glyph.more = 0;
- }
- return true;
+ PdfPainter p(ite, this, PNr, pag);
+ ite->textLayout.renderBackground(&p);
+ ite->textLayout.render(&p);
+ return p.getBuffer();
}
QByteArray PDFLibCore::SetColor(const QString& farbe, double Shade)
Modified: trunk/Scribus/scribus/pdflib_core.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/pdflib_core.h
==============================================================================
--- trunk/Scribus/scribus/pdflib_core.h (original)
+++ trunk/Scribus/scribus/pdflib_core.h Wed Mar 23 20:21:36 2016
@@ -43,6 +43,8 @@
#include "pdfwriter.h"
+class PdfPainter;
+
/**
* PDFLibCore provides Scribus's implementation of PDF export functionality.
*
@@ -58,6 +60,8 @@
class PDFLibCore : public QObject
{
Q_OBJECT
+
+friend class PdfPainter;
public:
explicit PDFLibCore(ScribusDoc & docu);
@@ -171,7 +175,6 @@
QByteArray Write_FormXObject(QByteArray &data, PageItem *controlItem = 0);
QByteArray Write_TransparencyGroup(double trans, int blend, QByteArray &data, PageItem *controlItem = 0);
QByteArray setTextSt(PageItem *ite, uint PNr, const ScPage* pag);
- bool setTextCh(PageItem *ite, uint PNr, double x, double y, uint d, QByteArray &tmp, QByteArray &tmp2, const CharStyle& cstyle, GlyphLayout *glyphs, PathData* pdata, const ParagraphStyle& pstyle, const ScPage* pag);
void getBleeds(const ScPage* page, double &left, double &right);
void getBleeds(const ScPage* page, double &left, double &right, double &bottom, double& top);
Modified: trunk/Scribus/scribus/plugins/export/svgexplugin/svgexplugin.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/plugins/export/svgexplugin/svgexplugin.cpp
==============================================================================
--- trunk/Scribus/scribus/plugins/export/svgexplugin/svgexplugin.cpp (original)
+++ trunk/Scribus/scribus/plugins/export/svgexplugin/svgexplugin.cpp Wed Mar 23 20:21:36 2016
@@ -55,6 +55,9 @@
#include "sccolorengine.h"
#include "util_formats.h"
#include "util_math.h"
+#include "text/textlayout.h"
+#include "text/textlayoutpainter.h"
+#include "text/boxes.h"
int svgexplugin_getPluginAPIVersion()
{
@@ -368,10 +371,8 @@
ob = processImageItem(Item, trans, fill, stroke);
break;
case PageItem::TextFrame:
+ case PageItem::PathText:
ob = processTextItem(Item, trans, fill, stroke);
- break;
- case PageItem::PathText:
- ob = processPathTextItem(Item, trans, stroke);
break;
case PageItem::Symbol:
ob = processSymbolItem(Item, trans);
@@ -1144,6 +1145,97 @@
return ob;
}
+class SvgPainter: public TextLayoutPainter
+{
+ QDomElement m_elem;
+ SVGExPlug *m_svg;
+ QString m_trans;
+
+public:
+ SvgPainter(QString trans, SVGExPlug *svg, QDomElement &elem)
+ : m_elem(elem)
+ , m_svg(svg)
+ , m_trans(trans)
+ {}
+
+ void drawGlyph(const GlyphLayout gl)
+ {
+ if (gl.glyph >= ScFace::CONTROL_GLYPHS)
+ return;
+
+ QTransform transform = matrix();
+ transform.translate(x(), y() - (fontSize() * gl.scaleV));
+ transform.scale(gl.scaleH * fontSize() / 10.0, gl.scaleV * fontSize() / 10.0);
+
+ QDomElement glyph = m_svg->docu.createElement("use");
+ glyph.setAttribute("xlink:href", "#" + m_svg->handleGlyph(gl.glyph, font()));
+ glyph.setAttribute("transform", m_svg->MatrixToStr(transform));
+ QString fill = "fill:" + m_svg->SetColor(fillColor().color, fillColor().shade) + ";";
+ QString stroke = "stroke:none;";
+ glyph.setAttribute("style", fill + stroke);
+ m_elem.appendChild(glyph);
+ }
+
+ void drawGlyphOutline(const GlyphLayout gl, bool hasFill)
+ {
+ if (gl.glyph >= ScFace::CONTROL_GLYPHS)
+ return;
+
+ QTransform transform = matrix();
+ transform.translate(x(), y() - (fontSize() * gl.scaleV));
+ transform.scale(gl.scaleH * fontSize() / 10.0, gl.scaleV * fontSize() / 10.0);
+ QDomElement glyph = m_svg->docu.createElement("use");
+ glyph.setAttribute("xlink:href", "#" + m_svg->handleGlyph(gl.glyph, font()));
+ glyph.setAttribute("transform", m_svg->MatrixToStr(transform));
+ QString fill = "fill:none;";
+ if (hasFill)
+ fill = "fill:" + m_svg->SetColor(fillColor().color, fillColor().shade) + ";";
+ QString stroke ="stroke:" + m_svg->SetColor(strokeColor().color, strokeColor().shade) + ";";
+ stroke += " stroke-width:" + m_svg->FToStr(strokeWidth()) + ";";
+ glyph.setAttribute("style", fill + stroke);
+ m_elem.appendChild(glyph);
+ }
+
+ void drawLine(QPointF start, QPointF end)
+ {
+ QTransform transform = matrix();
+ transform.translate(x(), y());
+ QDomElement path = m_svg-> docu.createElement("path");
+ path.setAttribute("d", QString("M %1 %2 L%3 %4").arg(start.x()).arg(start.y()).arg(end.x()).arg(end.y()));
+ QString stroke = "stroke:none;";
+ if (fillColor().color != CommonStrings::None)
+ {
+ stroke = "stroke:" + m_svg->SetColor(fillColor().color, fillColor().shade) + ";";
+ stroke += " stroke-width:" + m_svg->FToStr(strokeWidth()) + ";";
+ }
+ path.setAttribute("style", "fill:none;" + stroke);
+ path.setAttribute("transform", m_svg->MatrixToStr(transform));
+ m_elem.appendChild(path);
+ }
+
+ void drawRect(QRectF rect)
+ {
+ QTransform transform = matrix();
+ transform.translate(x(), y());
+ QString paS = QString("M %1 %2 ").arg(rect.x()).arg(rect.y());
+ paS += QString("L %1 %2 ").arg(rect.x() + rect.width()).arg(rect.y());
+ paS += QString("L %1 %2 ").arg(rect.x() + rect.width()).arg(rect.y() + rect.height());
+ paS += QString("L %1 %2 ").arg(rect.x()).arg(rect.y() + rect.height());
+ paS += "Z";
+ QDomElement path = m_svg-> docu.createElement("path");
+ path.setAttribute("d", paS);
+ path.setAttribute("transform", m_svg->MatrixToStr(transform));
+ path.setAttribute("style", "fill:" + m_svg->SetColor(fillColor().color, fillColor().shade) + ";" + "stroke:none;");
+ m_elem.appendChild(path);
+ }
+
+ void drawObject(PageItem* item)
+ {
+ QDomElement layerGroup = m_svg->processInlineItem(item, m_trans, scaleH(), scaleV());
+ m_elem.appendChild(layerGroup);
+ }
+};
+
QDomElement SVGExPlug::processTextItem(PageItem *Item, QString trans, QString fill, QString stroke)
{
QDomElement ob;
@@ -1168,14 +1260,6 @@
}
}
bool bFound = false;
- for (uint ll=0; ll < Item->textLayout.lines(); ++ll)
- {
- if (Item->itemText.paragraphStyle(Item->textLayout.line(ll).firstItem).backgroundColor() != CommonStrings::None)
- {
- bFound = true;
- break;
- }
- }
if (bFound)
{
QDomElement cl;
@@ -1188,633 +1272,13 @@
if (!ob2.isNull())
ob.setAttribute("clip-path", "url(#" + ob2.attribute("id") + ")");
}
- double x, y, wide;
- QString chstr;
- uint llp = 0;
- while (llp < Item->textLayout.lines())
- {
- LineSpec ls = Item->textLayout.line(llp++);
- const ParagraphStyle& LineStyle = Item->itemText.paragraphStyle(ls.firstItem);
- if (LineStyle.backgroundColor() != CommonStrings::None)
- {
- double y0 = ls.y;
- double y2 = 0;
- double ascent = ls.ascent;
- double descent = ls.descent;
- double rMarg = LineStyle.rightMargin();
- double lMarg = ls.colLeft;
- double adjX = 0;
- if (LineStyle.firstIndent() <= 0)
- adjX += LineStyle.leftMargin() + LineStyle.firstIndent();
- while (llp < Item->textLayout.lines())
- {
- ls = Item->textLayout.line(llp);
- if ((ls.colLeft > lMarg) || (Item->itemText.paragraphStyle(ls.firstItem) != LineStyle))
- {
- if (y2 == 0)
- y2 = y0;
- break;
- }
- if (Item->itemText.text(ls.lastItem) == SpecialChars::PARSEP)
- {
- y2 = ls.y;
- descent = ls.descent;
- if ((llp + 1) < Item->textLayout.lines())
- {
- if ((Item->textLayout.line(llp + 1).lastItem - Item->textLayout.line(llp + 1).firstItem) > 0)
- descent += LineStyle.lineSpacing() - (ls.descent + Item->textLayout.line(llp + 1).ascent);
- }
- llp++;
- break;
- }
- y2 = ls.y;
- descent = ls.descent;
- if ((llp + 1) < Item->textLayout.lines())
- descent += LineStyle.lineSpacing() - (ls.descent + Item->textLayout.line(llp + 1).ascent);
- llp++;
- }
- QRectF scr(lMarg + adjX, y0 - ascent, Item->asTextFrame()->columnWidth() - adjX - rMarg, y2 - y0 + descent + ascent);
- QString paS = QString("M %1 %2 ").arg(scr.x()).arg(scr.y());
- paS += QString("L %1 %2 ").arg(scr.x() + scr.width()).arg(scr.y());
- paS += QString("L %1 %2 ").arg(scr.x() + scr.width()).arg(scr.y() + scr.height());
- paS += QString("L %1 %2 ").arg(scr.x()).arg(scr.y() + scr.height());
- paS += "Z";
- QDomElement glyS = docu.createElement("path");
- glyS.setAttribute("d", paS);
- glyS.setAttribute("style", "fill:"+SetColor(LineStyle.backgroundColor(), LineStyle.backgroundShade())+";" + "stroke:none;");
- ob.appendChild(glyS);
- }
- }
- for (uint ll=0; ll < Item->textLayout.lines(); ++ll)
- {
- LineSpec ls = Item->textLayout.line(ll);
- double CurX = ls.x;
-
- double CurXB = ls.x;
- int last = qMin(ls.lastItem, Item->itemText.length() - 1);
- QRectF scr;
- QString oldBack = "";
- double oldShade = 100;
- QString colorB = "";
- for (int a = ls.firstItem; a <= last; ++a)
- {
- const GlyphLayout* glyphs(Item->itemText.getGlyphs(a));
- const CharStyle& charStyle(Item->itemText.charStyle(a));
- if (charStyle.backColor() != CommonStrings::None)
- {
- // This code is for rendering character background color.
- colorB = SetColor(charStyle.backColor(), charStyle.backShade());
- const ParagraphStyle& LineStyle = Item->itemText.paragraphStyle(ls.firstItem);
- double y1 = ls.y;
- double hl = ls.height;
- if (LineStyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- hl = m_Doc->guidesPrefs().valueBaselineGrid;
- else if (LineStyle.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
- hl = LineStyle.lineSpacing();
- if (ls.isFirstLine)
- {
- if (Item->textLayout.lines() == 1)
- hl = ls.ascent + ls.descent;
- if (LineStyle.hasDropCap() && (a == ls.firstItem))
- hl *= LineStyle.dropCapLines();
- if (LineStyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- y1 -= LineStyle.lineSpacing();
- else if (Item->firstLineOffset() == FLOPRealGlyphHeight || Item->firstLineOffset() == FLOPFontAscent)
- y1 -= ls.ascent;
- else
- y1 -= LineStyle.lineSpacing();
- }
- else
- y1 -= ls.ascent + (hl - (ls.ascent + ls.descent)) / 2.0;
- QRectF scrG;
- if (Item->itemText.hasObject(a))
- {
- PageItem* obj = Item->itemText.object(a);
- double ww = (obj->width() + obj->lineWidth()) * glyphs->scaleH;
- double hh = (obj->height() + obj->lineWidth()) * glyphs->scaleV;
- scrG = QRectF(CurXB, ls.y - hh, ww , hh);
- }
- else
- scrG = QRectF(CurXB, y1, glyphs->wide(), hl);
- if ((oldBack == "") || ((oldBack == charStyle.backColor()) && (oldShade == charStyle.backShade())))
- scr |= scrG;
- else if ((oldBack != charStyle.backColor()) || (oldShade != charStyle.backShade()))
- {
- QString paS = QString("M %1 %2 ").arg(scr.x()).arg(scr.y());
- paS += QString("L %1 %2 ").arg(scr.x() + scr.width()).arg(scr.y());
- paS += QString("L %1 %2 ").arg(scr.x() + scr.width()).arg(scr.y() + scr.height());
- paS += QString("L %1 %2 ").arg(scr.x()).arg(scr.y() + scr.height());
- paS += "Z";
- QDomElement glyS = docu.createElement("path");
- glyS.setAttribute("d", paS);
- glyS.setAttribute("style", "fill:"+SetColor(oldBack, oldShade)+";" + "stroke:none;");
- ob.appendChild(glyS);
- scr = scrG;
- }
- oldBack = charStyle.backColor();
- oldShade = charStyle.backShade();
- // end background code
- }
- else
- {
- if (!scr.isNull())
- {
- QString paS = QString("M %1 %2 ").arg(scr.x()).arg(scr.y());
- paS += QString("L %1 %2 ").arg(scr.x() + scr.width()).arg(scr.y());
- paS += QString("L %1 %2 ").arg(scr.x() + scr.width()).arg(scr.y() + scr.height());
- paS += QString("L %1 %2 ").arg(scr.x()).arg(scr.y() + scr.height());
- paS += "Z";
- QDomElement glyS = docu.createElement("path");
- glyS.setAttribute("d", paS);
- glyS.setAttribute("style", "fill:"+colorB+";" + "stroke:none;");
- ob.appendChild(glyS);
- }
- oldBack = "";
- oldShade = 100;
- scr = QRectF();
- }
- CurXB += glyphs->wide();
- }
- if (!scr.isNull())
- {
- QString paS = QString("M %1 %2 ").arg(scr.x()).arg(scr.y());
- paS += QString("L %1 %2 ").arg(scr.x() + scr.width()).arg(scr.y());
- paS += QString("L %1 %2 ").arg(scr.x() + scr.width()).arg(scr.y() + scr.height());
- paS += QString("L %1 %2 ").arg(scr.x()).arg(scr.y() + scr.height());
- paS += "Z";
- QDomElement glyS = docu.createElement("path");
- glyS.setAttribute("d", paS);
- glyS.setAttribute("style", "fill:"+colorB+";" + "stroke:none;");
- ob.appendChild(glyS);
- }
-
- for (int a = ls.firstItem; a <= ls.lastItem; ++a)
- {
- x = 0.0;
- y = 0.0;
- //ScText * hl = Item->itemText.item_p(a);
- const CharStyle& charStyle(Item->itemText.charStyle(a));
- const GlyphLayout* glyphs = Item->itemText.getGlyphs(a);
- PageItem* embItem = Item->itemText.hasObject(a)? Item->itemText.object(a) : NULL;
- LayoutFlags flags = Item->itemText.flags(a);
-
- chstr = Item->itemText.text(a,1);
- if ((chstr == QChar(13)) || (chstr == QChar(29)))
- {
- if (chstr == QChar(29))
- CurX += glyphs->wide();
- continue;
- }
- if (chstr == QChar(30))
- {
- chstr = Item->ExpandToken(a);
- if (chstr == QChar(32))
- {
- CurX += glyphs->wide();
- continue;
- }
- }
- double chs = charStyle.fontSize();
- if (charStyle.effects() & ScStyle_SmallCaps)
- {
- if (chstr.toUpper() != chstr)
- {
- chs = qMax(static_cast<int>(charStyle.fontSize() * m_Doc->typographicPrefs().valueSmallCaps / 100), 1);
- chstr = chstr.toUpper();
- }
- }
- else if (charStyle.effects() & ScStyle_AllCaps)
- chstr = chstr.toUpper();
- uint chr = chstr[0].unicode();
- QTransform chma, chma2, chma3, chma4, chma6;
- QTransform trafo = QTransform( 1, 0, 0, 1, CurX, ls.y );
- if (Item->rotation() != 0)
- {
- QTransform sca;
- sca.translate(-Item->xPos(), -Item->yPos());
- trafo *= sca;
- }
- chma.scale(glyphs->scaleH * charStyle.fontSize() / 100.00, glyphs->scaleV * charStyle.fontSize() / 100.0);
- if (Item->reversed())
- {
- if (a < Item->itemText.length()-1)
- wide = charStyle.font().charWidth(chstr[0], charStyle.fontSize(), Item->itemText.text(a+1));
- else
- wide = charStyle.font().charWidth(chstr[0], charStyle.fontSize());
- chma3.scale(-1, 1);
- chma3.translate(-wide, 0);
- }
- chma4.translate(0, Item->BaseOffs - (charStyle.fontSize() / 10.0) * glyphs->scaleV);
- if (charStyle.effects() & (ScStyle_Subscript | ScStyle_Superscript | ScLayout_DropCap))
- chma6.translate(0, glyphs->yoffset);
- if (charStyle.baselineOffset() != 0)
- chma6.translate(0, (-charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0));
- QTransform finalMat = chma * chma2 * chma3 * chma4 * chma6 * trafo;
- if (Item->rotation() != 0)
- {
- QTransform sca;
- sca.translate(Item->xPos(), Item->yPos());
- finalMat *= sca;
- }
- if (embItem != NULL)
- {
- ob.appendChild(processInlineItem(CurX + glyphs->xoffset, ls.y + glyphs->yoffset, finalMat, embItem, charStyle, false, trans));
- CurX += (embItem->width() + embItem->lineWidth()) * glyphs->scaleH;
- }
- else
- {
- QString glName;
- if (chstr > QChar(32))
- glName = handleGlyph(chr, charStyle);
- if ((charStyle.effects() & ScStyle_Shadowed) && (charStyle.strokeColor() != CommonStrings::None) && (chstr > QChar(32)))
- {
- QTransform sha = finalMat;
- QTransform shad;
- shad.translate(charStyle.fontSize() * charStyle.shadowXOffset() / 10000.0, -charStyle.fontSize() * charStyle.shadowYOffset() / 10000.0);
- sha *= shad;
- QDomElement ob2 = docu.createElement("use");
- ob2.setAttribute("xlink:href", "#" + glName);
- ob2.setAttribute("transform", MatrixToStr(sha));
- ob2.setAttribute("style", "fill:"+SetColor(charStyle.strokeColor(), charStyle.strokeShade())+";" + "stroke:none;");
- ob.appendChild(ob2);
- }
-
- if (((charStyle.effects() & ScStyle_Underline) && !SpecialChars::isBreak(chstr[0]))
- || ((charStyle.effects() & ScStyle_UnderlineWords) && !chstr[0].isSpace() && !SpecialChars::isBreak(chstr[0])))
- {
- x = CurX;
- y = ls.y;
- double Ulen = glyphs->xadvance;
- double Upos, lw, kern;
- if (flags & ScLayout_StartOfLine)
- kern = 0;
- else
- kern = charStyle.fontSize() * charStyle.tracking() / 10000.0;
- if ((charStyle.underlineOffset() != -1) || (charStyle.underlineWidth() != -1))
- {
- if (charStyle.underlineOffset() != -1)
- Upos = (charStyle.underlineOffset() / 1000.0) * (charStyle.font().descent(charStyle.fontSize() / 10.0));
- else
- Upos = charStyle.font().underlinePos(charStyle.fontSize() / 10.0);
- if (charStyle.underlineWidth() != -1)
- lw = (charStyle.underlineWidth() / 1000.0) * (charStyle.fontSize() / 10.0);
- else
- lw = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- else
- {
- Upos = charStyle.font().underlinePos(charStyle.fontSize() / 10.0);
- lw = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- if (charStyle.baselineOffset() != 0)
- Upos += (charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0);
- QDomElement ob6 = docu.createElement("path");
- if (charStyle.effects() & ScStyle_Subscript)
- ob6.setAttribute("d", QString("M %1 %2 L%3 %4").arg(x + glyphs->xoffset-kern).arg(y + glyphs->yoffset - Upos).arg(x + glyphs->xoffset+Ulen).arg(y + glyphs->yoffset - Upos));
- else
- ob6.setAttribute("d", QString("M %1 %2 L%3 %4").arg(x + glyphs->xoffset-kern).arg(y - Upos).arg(x + glyphs->xoffset+Ulen).arg(y - Upos));
- QString sT = "stroke:none;";
- if (charStyle.fillColor() != CommonStrings::None)
- {
- sT = "stroke:"+SetColor(charStyle.fillColor(), charStyle.fillShade())+";";
- sT += " stroke-width:"+FToStr(lw)+";";
- }
- ob6.setAttribute("style", "fill:none;" + sT);
- ob.appendChild(ob6);
- }
- if (chstr > QChar(32))
- {
- QDomElement ob3 = docu.createElement("use");
- ob3.setAttribute("xlink:href", "#" + glName);
- ob3.setAttribute("transform", MatrixToStr(finalMat));
- QString fT = "fill:"+SetColor(charStyle.fillColor(), charStyle.fillShade())+";";
- QString sT = "stroke:none;";
- if (charStyle.effects() & ScStyle_Outline)
- {
- sT = "stroke:"+SetColor(charStyle.strokeColor(), charStyle.strokeShade())+";";
- sT += " stroke-width:"+FToStr(chs * charStyle.outlineWidth() / 10000.0)+";";
- }
- ob3.setAttribute("style", fT + sT);
- ob.appendChild(ob3);
- }
- if (charStyle.effects() & ScStyle_Strikethrough)
- {
- x = CurX;
- y = ls.y;
- double Ulen = glyphs->xadvance;
- double Upos, lw, kern;
- if (flags & ScLayout_StartOfLine)
- kern = 0;
- else
- kern = charStyle.fontSize() * charStyle.tracking() / 10000.0;
- if ((charStyle.strikethruOffset() != -1) || (charStyle.strikethruWidth() != -1))
- {
- if (charStyle.strikethruOffset() != -1)
- Upos = (charStyle.strikethruOffset() / 1000.0) * (charStyle.font().ascent(charStyle.fontSize() / 10.0));
- else
- Upos = charStyle.font().strikeoutPos(charStyle.fontSize() / 10.0);
- if (charStyle.strikethruWidth() != -1)
- lw = (charStyle.strikethruWidth() / 1000.0) * (charStyle.fontSize() / 10.0);
- else
- lw = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- else
- {
- Upos = charStyle.font().strikeoutPos(charStyle.fontSize() / 10.0);
- lw = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- if (charStyle.baselineOffset() != 0)
- Upos += (charStyle.fontSize() / 10.0) * glyphs->scaleV * (charStyle.baselineOffset() / 1000.0);
- QDomElement ob7 = docu.createElement("path");
- ob7.setAttribute("d", QString("M %1 %2 L%3 %4").arg(x + glyphs->xoffset-kern).arg(y + glyphs->yoffset - Upos).arg(x + glyphs->xoffset+Ulen).arg(y + glyphs->yoffset - Upos));
- QString sT = "stroke:none;";
- if (charStyle.fillColor() != CommonStrings::None)
- {
- sT = "stroke:"+SetColor(charStyle.fillColor(), charStyle.fillShade())+";";
- sT += " stroke-width:"+FToStr(lw)+";";
- }
- ob7.setAttribute("style", "fill:none;" + sT);
- ob.appendChild(ob7);
- }
- CurX += glyphs->wide();
- }
- }
- }
- if (Item->NamedLStyle.isEmpty())
- {
- QDomElement ob4 = docu.createElement("path");
- ob4.setAttribute("d", SetClipPath(&Item->PoLine, true));
- ob4.setAttribute("style", "fill:none; "+stroke);
- if ((!Item->strokePattern().isEmpty()) && (Item->patternStrokePath))
- ob4.appendChild(processSymbolStroke(Item, trans));
- ob.appendChild(ob4);
- }
- else
- {
- multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
- for (int it = ml.size()-1; it > -1; it--)
- {
- if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
- {
- QDomElement ob5 = docu.createElement("path");
- ob5.setAttribute("d", SetClipPath(&Item->PoLine, true));
- ob5.setAttribute("style", "fill:none; "+GetMultiStroke(&ml[it], Item));
- ob.appendChild(ob5);
- }
- }
- }
+ SvgPainter p(trans, this, ob);
+ Item->textLayout.renderBackground(&p);
+ Item->textLayout.render(&p);
return ob;
}
-QDomElement SVGExPlug::processPathTextItem(PageItem *Item, QString trans, QString stroke)
-{
- QDomElement ob;
- ob = docu.createElement("g");
- ob.setAttribute("transform", trans);
- if (Item->PoShow)
- {
- if (Item->NamedLStyle.isEmpty())
- {
- QDomElement ob4 = docu.createElement("path");
- ob4.setAttribute("d", SetClipPath(&Item->PoLine, false));
- ob4.setAttribute("style", "fill:none; "+stroke);
- ob.appendChild(ob4);
- }
- else
- {
- multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
- for (int it = ml.size()-1; it > -1; it--)
- {
- if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
- {
- QDomElement ob5 = docu.createElement("path");
- ob5.setAttribute("d", SetClipPath(&Item->PoLine, false));
- ob5.setAttribute("style", "fill:none; "+GetMultiStroke(&ml[it], Item));
- ob.appendChild(ob5);
- }
- }
- }
- }
- double wide;
- QString chstr;
- for (int a = 0; a < Item->asPathText()->itemRenderText.length(); ++a)
- {
- //ScText *hl = Item->asPathText()->itemRenderText.item_p(a);
- const CharStyle& charStyle(Item->asPathText()->itemRenderText.charStyle(a));
- const GlyphLayout* glyphs = Item->asPathText()->itemRenderText.getGlyphs(a);
- const PathData* pdata = &(Item->textLayout.point(a));
- PageItem* embItem = Item->itemText.hasObject(a)? Item->itemText.object(a) : NULL;
- LayoutFlags flags = Item->itemText.flags(a);
-
- chstr = Item->asPathText()->itemRenderText.text(a,1);
- if ((chstr == QChar(13)) || (chstr == QChar(29)))
- continue;
- if (chstr == QChar(30))
- {
- chstr = Item->ExpandToken(a);
- if (chstr == QChar(32))
- continue;
- }
- double chs = charStyle.fontSize();
- if (charStyle.effects() & ScStyle_SmallCaps)
- {
- if (chstr.toUpper() != chstr)
- {
- chs = qMax(static_cast<int>(charStyle.fontSize() * m_Doc->typographicPrefs().valueSmallCaps / 100), 1);
- chstr = chstr.toUpper();
- }
- }
- else if (charStyle.effects() & ScStyle_AllCaps)
- chstr = chstr.toUpper();
- uint chr = chstr[0].unicode();
-
- QPointF tangt = QPointF( cos(pdata->PRot), sin(pdata->PRot) );
- QTransform chma, chma2, chma3, chma4, chma6;
- QTransform trafo = QTransform( 1, 0, 0, -1, -pdata->PDx, 0 );
- if (Item->textPathFlipped)
- trafo *= QTransform(1, 0, 0, -1, 0, 0);
- if (Item->textPathType == 0)
- trafo *= QTransform( tangt.x(), tangt.y(), tangt.y(), -tangt.x(), pdata->PtransX, pdata->PtransY );
- else if (Item->textPathType == 1)
- trafo *= QTransform(1, 0, 0, -1, pdata->PtransX, pdata->PtransY );
- else if (Item->textPathType == 2)
- {
- double a = 1;
- double b = -1;
- if (tangt.x() < 0)
- {
- a = -1;
- b = 1;
- }
- if (fabs(tangt.x()) > 0.1)
- trafo *= QTransform( a, (tangt.y() / tangt.x()) * b, 0, -1, pdata->PtransX, pdata->PtransY ); // ID's Skew mode
- else
- trafo *= QTransform( a, 6 * b, 0, -1, pdata->PtransX, pdata->PtransY );
- }
- if (embItem != NULL)
- {
- QTransform finalMat = chma * chma2 * chma3 * chma4 * chma6 * trafo;
- ob.appendChild(processInlineItem(0, 0, finalMat, embItem, charStyle, true, trans));
- }
- else
- {
- if (Item->rotation() != 0)
- {
- QTransform sca;
- sca.translate(-Item->xPos(), -Item->yPos());
- trafo *= sca;
- }
- chma.scale(glyphs->scaleH * charStyle.fontSize() / 100.00, glyphs->scaleV * charStyle.fontSize() / 100.0);
- if (Item->reversed())
- {
- if (a < Item->itemText.length()-1)
- wide = charStyle.font().charWidth(chstr[0], charStyle.fontSize(), Item->itemText.text(a+1));
- else
- wide = charStyle.font().charWidth(chstr[0], charStyle.fontSize());
- chma3.scale(-1, 1);
- chma3.translate(-wide, 0);
- }
- chma4.translate(0, Item->BaseOffs - (charStyle.fontSize() / 10.0) * glyphs->scaleV);
- if (charStyle.effects() & (ScStyle_Subscript | ScStyle_Superscript | ScLayout_DropCap))
- chma6.translate(0, glyphs->yoffset);
- if (charStyle.baselineOffset() != 0)
- chma6.translate(0, (-charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0));
- QTransform finalMat = chma * chma2 * chma3 * chma4 * chma6 * trafo;
- if (Item->rotation() != 0)
- {
- QTransform sca;
- sca.translate(Item->xPos(), Item->yPos());
- finalMat *= sca;
- }
-
- if (((charStyle.effects() & ScStyle_Underline) && !SpecialChars::isBreak(chstr[0]))
- || ((charStyle.effects() & ScStyle_UnderlineWords) && !chstr[0].isSpace() && !SpecialChars::isBreak(chstr[0])))
- {
- QTransform stro = chma2 * chma3 * chma6 * trafo;
- if (Item->rotation() != 0)
- {
- QTransform sca;
- sca.translate(Item->xPos(), Item->yPos());
- stro *= sca;
- }
- double Ulen = glyphs->xadvance;
- double Upos, Uwid, kern;
- if (flags & ScLayout_StartOfLine)
- kern = 0;
- else
- kern = charStyle.fontSize() * charStyle.tracking() / 10000.0;
- if ((charStyle.underlineOffset() != -1) || (charStyle.underlineWidth() != -1))
- {
- if (charStyle.underlineOffset() != -1)
- Upos = (charStyle.underlineOffset() / 1000.0) * (charStyle.font().descent(charStyle.fontSize() / 10.0));
- else
- Upos = charStyle.font().underlinePos(charStyle.fontSize() / 10.0);
- if (charStyle.underlineWidth() != -1)
- Uwid = (charStyle.underlineWidth() / 1000.0) * (charStyle.fontSize() / 10.0);
- else
- Uwid = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- else
- {
- Upos = charStyle.font().underlinePos(charStyle.fontSize() / 10.0);
- Uwid = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- if (charStyle.baselineOffset() != 0)
- Upos += (charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0);
- QDomElement ob8 = docu.createElement("path");
- ob8.setAttribute("transform", MatrixToStr(stro));
- if (charStyle.effects() & ScStyle_Subscript)
- ob8.setAttribute("d", QString("M %1 %2 L%3 %4").arg(glyphs->xoffset-kern).arg(-Upos).arg(glyphs->xoffset+Ulen).arg(-Upos));
- else
- ob8.setAttribute("d", QString("M %1 %2 L%3 %4").arg(glyphs->xoffset-kern).arg(-(Upos + glyphs->yoffset)).arg(glyphs->xoffset+Ulen).arg(-(Upos + glyphs->yoffset)));
- QString sT = "stroke:none;";
- if (charStyle.fillColor() != CommonStrings::None)
- {
- sT = "stroke:"+SetColor(charStyle.fillColor(), charStyle.fillShade())+";";
- sT += " stroke-width:"+FToStr(Uwid)+";";
- }
- ob8.setAttribute("style", "fill:none;" + sT);
- ob.appendChild(ob8);
- }
- if (chstr > QChar(32))
- {
- QString glName = handleGlyph(chr, charStyle);
- if ((charStyle.effects() & ScStyle_Shadowed) && (charStyle.strokeColor() != CommonStrings::None))
- {
- QTransform sha = finalMat;
- QTransform shad;
- shad.translate(charStyle.fontSize() * charStyle.shadowXOffset() / 10000.0, -charStyle.fontSize() * charStyle.shadowYOffset() / 10000.0);
- sha *= shad;
- QDomElement ob2 = docu.createElement("use");
- ob2.setAttribute("xlink:href", "#" + glName);
- ob2.setAttribute("transform", MatrixToStr(sha));
- ob2.setAttribute("style", "fill:"+SetColor(charStyle.strokeColor(), charStyle.strokeShade())+";" + "stroke:none;");
- ob.appendChild(ob2);
- }
- QDomElement ob1 = docu.createElement("use");
- ob1.setAttribute("xlink:href", "#" + glName);
- ob1.setAttribute("transform", MatrixToStr(finalMat));
- QString fT = "fill:"+SetColor(charStyle.fillColor(), charStyle.fillShade())+";";
- QString sT = "stroke:none;";
- if (charStyle.effects() & ScStyle_Outline)
- {
- sT = "stroke:"+SetColor(charStyle.strokeColor(), charStyle.strokeShade())+";";
- sT += " stroke-width:"+FToStr(chs * charStyle.outlineWidth() / 10000.0)+";";
- }
- ob1.setAttribute("style", fT + sT);
- ob.appendChild(ob1);
- }
- if (charStyle.effects() & ScStyle_Strikethrough)
- {
- QTransform stro = chma2 * chma3 * chma6 * trafo;
- if (Item->rotation() != 0)
- {
- QTransform sca;
- sca.translate(Item->xPos(), Item->yPos());
- stro *= sca;
- }
- double Ulen = glyphs->xadvance;
- double Upos, Uwid, kern;
- if (flags & ScLayout_StartOfLine)
- kern = 0;
- else
- kern = charStyle.fontSize() * charStyle.tracking() / 10000.0;
- if ((charStyle.strikethruOffset() != -1) || (charStyle.strikethruWidth() != -1))
- {
- if (charStyle.strikethruOffset() != -1)
- Upos = (charStyle.strikethruOffset() / 1000.0) * (charStyle.font().ascent(charStyle.fontSize() / 10.0));
- else
- Upos = charStyle.font().strikeoutPos(charStyle.fontSize() / 10.0);
- if (charStyle.strikethruWidth() != -1)
- Uwid = (charStyle.strikethruWidth() / 1000.0) * (charStyle.fontSize() / 10.0);
- else
- Uwid = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- else
- {
- Upos = charStyle.font().strikeoutPos(charStyle.fontSize() / 10.0);
- Uwid = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- if (charStyle.baselineOffset() != 0)
- Upos += (charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0);
- QDomElement ob7 = docu.createElement("path");
- ob7.setAttribute("transform", MatrixToStr(stro));
- ob7.setAttribute("d", QString("M %1 %2 L%3 %4").arg(glyphs->xoffset-kern).arg(-Upos).arg(glyphs->xoffset+Ulen).arg(-Upos));
- QString sT = "stroke:none;";
- if (charStyle.fillColor() != CommonStrings::None)
- {
- sT = "stroke:"+SetColor(charStyle.fillColor(), charStyle.fillShade())+";";
- sT += " stroke-width:"+FToStr(Uwid)+";";
- }
- ob7.setAttribute("style", "fill:none;" + sT);
- ob.appendChild(ob7);
- }
- }
- }
- return ob;
-}
-
-QDomElement SVGExPlug::processInlineItem(double xpos, double ypos, QTransform &finalMat, PageItem* embItem, const CharStyle & charStyle, bool pathT, QString trans)
+QDomElement SVGExPlug::processInlineItem(PageItem* embItem, QString trans, double scaleH, double scaleV)
{
QList<PageItem*> emG;
if (embItem->isGroup())
@@ -1823,8 +1287,6 @@
emG.append(embItem);
QDomElement layerGroup = docu.createElement("g");
- if (pathT)
- layerGroup.setAttribute("transform", MatrixToStr(finalMat));
for (int em = 0; em < emG.count(); ++em)
{
PageItem* embedded = emG.at(em);
@@ -1853,10 +1315,8 @@
obE = processImageItem(embedded, trans, fill, stroke);
break;
case PageItem::TextFrame:
+ case PageItem::PathText:
obE = processTextItem(embedded, trans, fill, stroke);
- break;
- case PageItem::PathText:
- obE = processPathTextItem(embedded, trans, stroke);
break;
case PageItem::Symbol:
obE = processSymbolItem(embedded, trans);
@@ -1865,13 +1325,10 @@
break;
}
QTransform mm;
- mm.translate(xpos + embedded->gXpos * (charStyle.scaleH() / 1000.0), (ypos - (embedded->gHeight * (charStyle.scaleV() / 1000.0)) + embedded->gYpos * (charStyle.scaleV() / 1000.0)));
- if (charStyle.baselineOffset() != 0)
- mm.translate(0, embedded->gHeight * (charStyle.baselineOffset() / 1000.0));
- if (charStyle.scaleH() != 1000)
- mm.scale(charStyle.scaleH() / 1000.0, 1);
- if (charStyle.scaleV() != 1000)
- mm.scale(1, charStyle.scaleV() / 1000.0);
+ if (scaleH != 1.0)
+ mm.scale(scaleH, 1);
+ if (scaleV != 1.0)
+ mm.scale(1, scaleV);
mm.rotate(embedded->rotation());
obE.setAttribute("transform", MatrixToStr(mm));
layerGroup.appendChild(obE);
@@ -1879,15 +1336,12 @@
return layerGroup;
}
-QString SVGExPlug::handleGlyph(uint chr, const CharStyle& cStyle)
-{
- if (chr == 32)
- return "SPACE";
- QString glName = QString("Gl%1%2").arg(cStyle.font().psName().simplified().replace(QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )).arg(chr);
+QString SVGExPlug::handleGlyph(uint gid, const ScFace font)
+{
+ QString glName = QString("Gl%1%2").arg(font.psName().simplified().replace(QRegExp("[\\s\\/\\{\\[\\]\\}\\<\\>\\(\\)\\%]"), "_" )).arg(gid);
if (glyphNames.contains(glName))
return glName;
- uint gl = cStyle.font().char2CMap(chr);
- FPointArray pts = cStyle.font().glyphOutline(gl);
+ FPointArray pts = font.glyphOutline(gid);
QDomElement ob = docu.createElement("path");
ob.setAttribute("d", SetClipPath(&pts, true));
ob.setAttribute("id", glName);
Modified: trunk/Scribus/scribus/plugins/export/svgexplugin/svgexplugin.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/plugins/export/svgexplugin/svgexplugin.h
==============================================================================
--- trunk/Scribus/scribus/plugins/export/svgexplugin/svgexplugin.h (original)
+++ trunk/Scribus/scribus/plugins/export/svgexplugin/svgexplugin.h Wed Mar 23 20:21:36 2016
@@ -58,7 +58,8 @@
class SVGExPlug : public QObject
{
- Q_OBJECT
+ Q_OBJECT
+ friend class SvgPainter;
public:
/*!
@@ -90,9 +91,8 @@
QDomElement processLineItem(PageItem *Item, QString trans, QString stroke);
QDomElement processImageItem(PageItem *Item, QString trans, QString fill, QString stroke);
QDomElement processTextItem(PageItem *Item, QString trans, QString fill, QString stroke);
- QDomElement processPathTextItem(PageItem *Item, QString trans, QString stroke);
- QDomElement processInlineItem(double xpos, double ypos, QTransform &finalMat, PageItem* embItem, const CharStyle& cStyle, bool pathT, QString trans);
- QString handleGlyph(uint chr, const CharStyle& cStyle);
+ QDomElement processInlineItem(PageItem* embItem, QString trans, double scaleH, double scaleV);
+ QString handleGlyph(uint gid, const ScFace font);
QDomElement processArrows(PageItem *Item, QDomElement line, QString trans);
QString handleMask(PageItem *Item, double xOffset, double yOffset);
QString getFillStyle(PageItem *Item);
Modified: trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.cpp
==============================================================================
--- trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.cpp (original)
+++ trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.cpp Wed Mar 23 20:21:36 2016
@@ -51,6 +51,7 @@
#include "scribusview.h"
#include "sctextstruct.h"
#include "tableutils.h"
+#include "text/textlayoutpainter.h"
#include "util.h"
#include "ui/customfdialog.h"
#include "ui/guidemanager.h"
@@ -59,6 +60,7 @@
#include "util_formats.h"
#include "util_math.h"
#include "third_party/zip/scribus_zip.h"
+#include "text/boxes.h"
int xpsexplugin_getPluginAPIVersion()
{
@@ -435,17 +437,12 @@
else
processImageItem(xOffset, yOffset, Item, parentElem, rel_root);
break;
+ case PageItem::PathText:
case PageItem::TextFrame:
if (checkForFallback(Item))
handleImageFallBack(Item, parentElem, rel_root);
else
processTextItem(xOffset, yOffset, Item, parentElem, rel_root);
- break;
- case PageItem::PathText:
- if (checkForFallback(Item))
- handleImageFallBack(Item, parentElem, rel_root);
- else
- processPathTextItem(xOffset, yOffset, Item, parentElem, rel_root);
break;
case PageItem::Table:
if (checkForFallback(Item))
@@ -804,6 +801,121 @@
return;
}
+class XPSPainter: public TextLayoutPainter
+{
+ PageItem *m_item;
+ QDomElement m_group;
+ XPSExPlug *m_xps;
+ QMap<QString, QString> &m_fontMap;
+ QDomElement &m_relRoot;
+
+public:
+ XPSPainter(PageItem *item, QDomElement &group, XPSExPlug *xps, QMap<QString, QString> &XPSfontMap, QDomElement &rel_root):
+ m_item(item),
+ m_group(group),
+ m_xps(xps),
+ m_fontMap(XPSfontMap),
+ m_relRoot(rel_root)
+ { }
+
+ void drawGlyph(const GlyphLayout gl)
+ {
+ if (gl.glyph >= ScFace::CONTROL_GLYPHS)
+ return;
+
+ if (!m_fontMap.contains(font().replacementName()))
+ m_fontMap.insert(font().replacementName(), m_xps->embedFont(font(), m_relRoot));
+
+ QTransform transform = matrix();
+ QDomElement glyph = m_xps->p_docu.createElement("Glyphs");
+ double size = fontSize() * qMax(gl.scaleV, gl.scaleH) * m_xps->conversionFactor;
+ glyph.setAttribute("RenderTransform", m_xps->MatrixToStr(transform, m_xps->conversionFactor));
+ glyph.setAttribute("BidiLevel", "0");
+ glyph.setAttribute("StyleSimulations", "None");
+ glyph.setAttribute("FontRenderingEmSize", m_xps->FToStr(size));
+ glyph.setAttribute("FontUri", m_fontMap[font().replacementName()]);
+ glyph.setAttribute("Fill", m_xps->SetColor(fillColor().color,fillColor().shade, 0));
+ glyph.setAttribute("OriginX", m_xps->FToStr(x() * m_xps->conversionFactor));
+ glyph.setAttribute("OriginY", m_xps->FToStr(y() * m_xps->conversionFactor));
+ glyph.setAttribute("Indices", QString::number(gl.glyph));
+
+ m_group.appendChild(glyph);
+ }
+
+ void drawGlyphOutline(const GlyphLayout gl, bool fill)
+ {
+ if (gl.glyph >= ScFace::CONTROL_GLYPHS)
+ return;
+
+ FPointArray outline = font().glyphOutline(gl.glyph);
+ if (outline.size() >= 4)
+ {
+ QTransform transform = matrix();
+ transform.scale((fontSize() * gl.scaleH) / 10.0, (fontSize() * gl.scaleV) / 10.0);
+ outline.map(transform);
+ outline.translate(0, -fontSize() * gl.scaleV);
+ outline.translate(x(), y());
+ outline.scale(m_xps->conversionFactor, m_xps->conversionFactor);
+ QString pathData = m_xps->SetClipPath(&outline, true);
+ QDomElement glyph = m_xps->p_docu.createElement("Path");
+ glyph.setAttribute("Data", pathData);
+ if (!fill)
+ glyph.setAttribute("Fill", m_xps->SetColor("None", fillColor().shade, 0));
+ else
+ glyph.setAttribute("Fill", m_xps->SetColor(fillColor().color, fillColor().shade, 0));
+ glyph.setAttribute("StrokeThickness", m_xps->FToStr(strokeWidth() * m_xps->conversionFactor));
+ glyph.setAttribute("Stroke", m_xps->SetColor(strokeColor().color, strokeColor().shade, 0));
+ m_group.appendChild(glyph);
+ }
+ }
+
+ void drawLine(QPointF start, QPointF end)
+ {
+ QTransform transform = matrix();
+ QDomElement path = m_xps->p_docu.createElement("Path");
+ path.setAttribute("RenderTransform", m_xps->MatrixToStr(transform, m_xps->conversionFactor));
+ path.setAttribute("Data", QString("M%1,%2 L%3,%4").arg((x() + start.x()) * m_xps->conversionFactor).arg((y() + end.y()) * m_xps->conversionFactor).arg((x() + start.x() + end.x()) * m_xps->conversionFactor).arg((y() + end.y()) * m_xps->conversionFactor));
+ path.setAttribute("Stroke", m_xps->SetColor(strokeColor().color, strokeColor().shade, 0));
+ path.setAttribute("StrokeThickness", m_xps->FToStr(strokeWidth() * m_xps->conversionFactor));
+ m_group.appendChild(path);
+ }
+
+ void drawRect(QRectF rect)
+ {
+ QTransform transform = matrix();
+ double rx = (x() + rect.x()) * m_xps->conversionFactor;
+ double ry = (y() + rect.y()) * m_xps->conversionFactor;
+ double rw = rx + rect.width() * m_xps->conversionFactor;
+ double rh = ry + rect.height() * m_xps->conversionFactor;
+ QString paS = QString("M%1,%2 ").arg(rx).arg(ry);
+ paS += QString("L%1,%2 ").arg(rw).arg(ry);
+ paS += QString("L%1,%2 ").arg(rw).arg(rh);
+ paS += QString("L%1,%2 ").arg(rx).arg(rh);
+ paS += "Z";
+ QDomElement path = m_xps->p_docu.createElement("Path");
+ path.setAttribute("RenderTransform", m_xps->MatrixToStr(transform, m_xps->conversionFactor));
+ path.setAttribute("Data", paS);
+ path.setAttribute("Fill", m_xps->SetColor(fillColor().color, fillColor().shade, 0));
+ path.setAttribute("StrokeThickness", m_xps->FToStr(strokeWidth() * m_xps->conversionFactor));
+ path.setAttribute("Stroke", m_xps->SetColor(strokeColor().color, strokeColor().shade, 0));
+ m_group.appendChild(path);
+ }
+
+ void drawObject(PageItem* item)
+ {
+ QDomElement canvas = m_xps->p_docu.createElement("Canvas");
+ QTransform matrix = QTransform();
+ matrix.translate(x() * m_xps->conversionFactor, (y() - (item->height() * (scaleV() / 1000.0))) * m_xps->conversionFactor);
+ if (scaleH() != 1.0)
+ matrix.scale(scaleH(), 1);
+ if (scaleV() != 1.0)
+ matrix.scale(1, scaleV());
+ canvas.setAttribute("RenderTransform", m_xps->MatrixToStr(matrix));
+ m_xps->writeItemOnPage(item->gXpos, item->gYpos, item, canvas, m_relRoot);
+ m_group.appendChild(canvas);
+ }
+};
+
void XPSExPlug::processTextItem(double xOffset, double yOffset, PageItem *Item, QDomElement &parentElem, QDomElement &rel_root)
{
if (Item->isAnnotation())
@@ -879,756 +991,11 @@
grp.appendChild(ob);
}
}
- bool bFound = false;
- for (uint ll=0; ll < Item->textLayout.lines(); ++ll)
- {
- if (Item->itemText.paragraphStyle(Item->textLayout.line(ll).firstItem).backgroundColor() != CommonStrings::None)
- {
- bFound = true;
- break;
- }
- }
- if (bFound)
- {
- FPointArray path = Item->PoLine.copy();
- path.scale(conversionFactor, conversionFactor);
- SetClipAttr(grp, &path, Item->fillRule);
- }
- uint llp = 0;
- while (llp < Item->textLayout.lines())
- {
- LineSpec ls = Item->textLayout.line(llp++);
- const ParagraphStyle& LineStyle = Item->itemText.paragraphStyle(ls.firstItem);
- if (LineStyle.backgroundColor() != CommonStrings::None)
- {
- double y0 = ls.y;
- double y2 = ls.y;
- double ascent = ls.ascent;
- double descent = ls.descent;
- double rMarg = LineStyle.rightMargin();
- double lMarg = ls.colLeft;
- double adjX = 0;
- if (LineStyle.firstIndent() <= 0)
- adjX += LineStyle.leftMargin() + LineStyle.firstIndent();
- while (llp < Item->textLayout.lines())
- {
- ls = Item->textLayout.line(llp);
- if ((ls.colLeft > lMarg) || (Item->itemText.paragraphStyle(ls.firstItem) != LineStyle))
- {
- if (y2 == 0)
- y2 = y0;
- break;
- }
- if (Item->itemText.text(ls.lastItem) == SpecialChars::PARSEP)
- {
- y2 = ls.y;
- descent = ls.descent;
- if ((llp + 1) < Item->textLayout.lines())
- {
- if ((Item->textLayout.line(llp + 1).lastItem - Item->textLayout.line(llp + 1).firstItem) > 0)
- descent += LineStyle.lineSpacing() - (ls.descent + Item->textLayout.line(llp + 1).ascent);
- }
- llp++;
- break;
- }
- y2 = ls.y;
- descent = ls.descent;
- if ((llp + 1) < Item->textLayout.lines())
- descent += LineStyle.lineSpacing() - (ls.descent + Item->textLayout.line(llp + 1).ascent);
- llp++;
- }
- QRectF scr(lMarg + adjX, y0 - ascent, Item->asTextFrame()->columnWidth() - adjX - rMarg, y2 - y0 + descent + ascent);
- QString paS = QString("M%1,%2 ").arg(scr.x() * conversionFactor).arg(scr.y() * conversionFactor);
- paS += QString("L%1,%2 ").arg((scr.x() + scr.width()) * conversionFactor).arg(scr.y() * conversionFactor);
- paS += QString("L%1,%2 ").arg((scr.x() + scr.width()) * conversionFactor).arg((scr.y() + scr.height()) * conversionFactor);
- paS += QString("L%1,%2 ").arg(scr.x() * conversionFactor).arg((scr.y() + scr.height()) * conversionFactor);
- paS += "Z";
- QDomElement glyS = p_docu.createElement("Path");
- glyS.setAttribute("Data", paS);
- glyS.setAttribute("Fill", SetColor(LineStyle.backgroundColor(), LineStyle.backgroundShade(), 0));
- grp.appendChild(glyS);
- }
- }
- for (uint ll=0; ll < Item->textLayout.lines(); ++ll)
- {
- LineSpec ls = Item->textLayout.line(ll);
- QList<txtRunItem> current_run;
- QList<QList<txtRunItem> > textRuns;
- QList<txtRunItem> specialText;
- double CurX = ls.x;
-
- double CurXB = ls.x;
- int last = qMin(ls.lastItem, Item->itemText.length() - 1);
- QRectF scr;
- QString oldBack = "";
- double oldShade = 100;
- QString colorB = "";
- for (int a = ls.firstItem; a <= last; ++a)
- {
- const GlyphLayout* glyphs(Item->itemText.getGlyphs(a));
- const CharStyle& charStyle(Item->itemText.charStyle(a));
- if (charStyle.backColor() != CommonStrings::None)
- {
- // This code is for rendering character background color.
- colorB = SetColor(charStyle.backColor(), charStyle.backShade(), 0);
- const ParagraphStyle& LineStyle = Item->itemText.paragraphStyle(ls.firstItem);
- double y1 = ls.y;
- double hl = ls.height;
- if (LineStyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- hl = m_Doc->guidesPrefs().valueBaselineGrid;
- else if (LineStyle.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
- hl = LineStyle.lineSpacing();
- if (ls.isFirstLine)
- {
- if (Item->textLayout.lines() == 1)
- hl = ls.ascent + ls.descent;
- if (LineStyle.hasDropCap() && (a == ls.firstItem))
- hl *= LineStyle.dropCapLines();
- if (LineStyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- y1 -= LineStyle.lineSpacing();
- else if (Item->firstLineOffset() == FLOPRealGlyphHeight || Item->firstLineOffset() == FLOPFontAscent)
- y1 -= ls.ascent;
- else
- y1 -= LineStyle.lineSpacing();
- }
- else
- y1 -= ls.ascent + (hl - (ls.ascent + ls.descent)) / 2.0;
- QRectF scrG;
- if (Item->itemText.hasObject(a))
- {
- PageItem* obj = Item->itemText.object(a);
- double ww = (obj->width() + obj->lineWidth()) * glyphs->scaleH;
- double hh = (obj->height() + obj->lineWidth()) * glyphs->scaleV;
- scrG = QRectF(CurXB, ls.y - hh, ww , hh);
- }
- else
- scrG = QRectF(CurXB, y1, glyphs->wide(), hl);
- if ((oldBack == "") || ((oldBack == charStyle.backColor()) && (oldShade == charStyle.backShade())))
- scr |= scrG;
- else if ((oldBack != charStyle.backColor()) || (oldShade != charStyle.backShade()))
- {
- QString paS = QString("M%1,%2 ").arg(scr.x() * conversionFactor).arg(scr.y() * conversionFactor);
- paS += QString("L%1,%2 ").arg((scr.x() + scr.width()) * conversionFactor).arg(scr.y() * conversionFactor);
- paS += QString("L%1,%2 ").arg((scr.x() + scr.width()) * conversionFactor).arg((scr.y() + scr.height()) * conversionFactor);
- paS += QString("L%1,%2 ").arg(scr.x() * conversionFactor).arg((scr.y() + scr.height()) * conversionFactor);
- paS += "Z";
- QDomElement glyS = p_docu.createElement("Path");
- glyS.setAttribute("Data", paS);
- glyS.setAttribute("Fill", SetColor(oldBack, oldShade, 0));
- grp.appendChild(glyS);
- scr = scrG;
- }
- oldBack = charStyle.backColor();
- oldShade = charStyle.backShade();
- }
- else
- {
- if (!scr.isNull())
- {
- QString paS = QString("M%1,%2 ").arg(scr.x() * conversionFactor).arg(scr.y() * conversionFactor);
- paS += QString("L%1,%2 ").arg((scr.x() + scr.width()) * conversionFactor).arg(scr.y() * conversionFactor);
- paS += QString("L%1,%2 ").arg((scr.x() + scr.width()) * conversionFactor).arg((scr.y() + scr.height()) * conversionFactor);
- paS += QString("L%1,%2 ").arg(scr.x() * conversionFactor).arg((scr.y() + scr.height()) * conversionFactor);
- paS += "Z";
- QDomElement glyS = p_docu.createElement("Path");
- glyS.setAttribute("Data", paS);
- glyS.setAttribute("Fill", colorB);
- grp.appendChild(glyS);
- }
- oldBack = "";
- oldShade = 100;
- scr = QRectF();
- }
- CurXB += glyphs->wide();
- }
- if (!scr.isNull())
- {
- QString paS = QString("M%1,%2 ").arg(scr.x() * conversionFactor).arg(scr.y() * conversionFactor);
- paS += QString("L%1,%2 ").arg((scr.x() + scr.width()) * conversionFactor).arg(scr.y() * conversionFactor);
- paS += QString("L%1,%2 ").arg((scr.x() + scr.width()) * conversionFactor).arg((scr.y() + scr.height()) * conversionFactor);
- paS += QString("L%1,%2 ").arg(scr.x() * conversionFactor).arg((scr.y() + scr.height()) * conversionFactor);
- paS += "Z";
- QDomElement glyS = p_docu.createElement("Path");
- glyS.setAttribute("Data", paS);
- glyS.setAttribute("Fill", colorB);
- grp.appendChild(glyS);
- }
-
- for (int a = ls.firstItem; a <= ls.lastItem; ++a)
- {
- //ScText *hl = Item->itemText.item_p(a);
- QChar chr = Item->itemText.text(a);
- CharStyle charStyle = Item->itemText.charStyle(a);
- GlyphLayout* glyphs = Item->itemText.getGlyphs(a);
- LayoutFlags flags = Item->itemText.flags(a);
- const ScFace* font = &charStyle.font();
- txtRunItem txItem;
- txItem.chr = chr;
- txItem.glyphs = glyphs;
- txItem.style = charStyle;
- txItem.index = a;
- txItem.CurX = CurX;
- txItem.embItem = Item->itemText.hasObject(a)? Item->itemText.object(a) : NULL;
- if (!((font->type() == ScFace::TTF) || (font->type() == ScFace::OTF)))
- {
- specialText.append(txItem);
- textRuns.append(current_run);
- current_run.clear();
- CurX += txItem.glyphs->wide();
- continue;
- }
- if (SpecialChars::isBreak(chr, true) || (chr == QChar(10)))
- {
- continue;
- }
- if (flags & ScLayout_SuppressSpace)
- {
- continue;
- }
- if ((chr == SpecialChars::OLD_NBSPACE) || (chr == SpecialChars::OBJECT) || (charStyle.effects() & ScStyle_UserStyles))
- {
- specialText.append(txItem);
- textRuns.append(current_run);
- current_run.clear();
- CurX += txItem.glyphs->wide();
- continue;
- }
- QString guidFont;
- if (!xps_fontMap.contains(font->replacementName()))
- {
- guidFont = embedFont(font, rel_root);
- xps_fontMap.insert(font->replacementName(), guidFont);
- }
- else
- guidFont = xps_fontMap[font->replacementName()];
- if (current_run.isEmpty())
- current_run.append(txItem);
- else
- {
- txtRunItem txItemL = current_run.last();
- double chl = (txItemL.style.fontSize() / 10.0) * qMax(txItemL.glyphs->scaleV, txItemL.glyphs->scaleH) * conversionFactor;
- const ScFace* fontL = &txItemL.style.font();
- QString guidFontL = xps_fontMap[fontL->replacementName()];
- StyleFlag old_sty = txItemL.style.effects();
- int old_shade = txItemL.style.fillShade();
- QString old_fill = txItemL.style.fillColor();
- double chs = (charStyle.fontSize() / 10.0) * qMax(glyphs->scaleV, glyphs->scaleH) * conversionFactor;
- if ((chs != chl) || (guidFont != guidFontL) || (charStyle.effects() != old_sty) || (charStyle.fillColor() != old_fill) || (charStyle.fillShade() != old_shade))
- {
- textRuns.append(current_run);
- current_run.clear();
- }
- current_run.append(txItem);
- }
- CurX += txItem.glyphs->wide();
- }
- textRuns.append(current_run);
- for (int txr = 0; txr < textRuns.count(); txr++)
- {
- QString uniString = "";
- QString indString = "";
- current_run = textRuns[txr];
- if (current_run.isEmpty())
- continue;
- double StartX = current_run[0].CurX;
- CurX = current_run[0].CurX;
- double chs = (current_run[0].style.fontSize() / 10.0) * qMax(current_run[0].glyphs->scaleV, current_run[0].glyphs->scaleH) * conversionFactor;
- for (int cr = 0; cr < current_run.count(); cr++)
- {
- txtRunItem txItem = current_run[cr];
- if ((txItem.chr == SpecialChars::PAGENUMBER) || (txItem.chr == SpecialChars::PAGECOUNT))
- {
- QString exString = Item->ExpandToken(txItem.index);
- for (int ex = 0; ex < exString.count(); ex++)
- {
- indString += ";";
- }
- uniString += exString;
- }
- else if ((SpecialChars::isBreakingSpace(txItem.chr)) || (SpecialChars::isExpandingSpace(txItem.chr)) || (txItem.chr.isSpace()))
- {
- indString += QString(",%1;").arg((txItem.glyphs->wide() * conversionFactor) / chs * 100);
- uniString += " ";
- }
- else
- {
- uniString += txItem.chr;
- if ((txItem.glyphs->xoffset != 0) || (txItem.glyphs->yoffset != 0))
- indString += QString(",%1,%2,%3;").arg((txItem.glyphs->wide() * conversionFactor) / chs * 100).arg((txItem.glyphs->xoffset * conversionFactor) / chs * 100).arg((-txItem.glyphs->yoffset * conversionFactor) / chs * 100);
- else
- indString += QString(",%1;").arg((txItem.glyphs->wide() * conversionFactor) / chs * 100);
- }
- CurX += txItem.glyphs->wide();
- }
- if (!indString.isEmpty())
- indString.chop(1);
- QDomElement gly = p_docu.createElement("Glyphs");
- gly.setAttribute("BidiLevel", "0");
- gly.setAttribute("StyleSimulations", "None");
- gly.setAttribute("FontRenderingEmSize", FToStr(chs));
- const ScFace* fontL = ¤t_run[0].style.font();
- gly.setAttribute("FontUri", xps_fontMap[fontL->replacementName()]);
- gly.setAttribute("Fill", SetColor(current_run[0].style.fillColor(), current_run[0].style.fillShade(), 0));
- gly.setAttribute("UnicodeString", uniString);
- if (current_run.count() == 1)
- {
- gly.setAttribute("OriginX", FToStr((StartX + current_run[0].glyphs->xoffset) * conversionFactor));
- gly.setAttribute("OriginY", FToStr((ls.y + current_run[0].glyphs->yoffset) * conversionFactor));
- }
- else
- {
- gly.setAttribute("OriginX", FToStr(StartX * conversionFactor));
- gly.setAttribute("OriginY", FToStr(ls.y * conversionFactor));
- gly.setAttribute("Indices", indString);
- }
- grp.appendChild(gly);
- }
- for (int cr = 0; cr < specialText.count(); cr++)
- {
- txtRunItem txItem = specialText[cr];
- CurX = txItem.CurX;
- if (txItem.chr == SpecialChars::OBJECT)
- {
- if (txItem.embItem != NULL)
- {
- QDomElement obO = p_docu.createElement("Canvas");
- QTransform mm;
- mm.translate(CurX * conversionFactor, (ls.y - (txItem.embItem->height() * (txItem.style.scaleV() / 1000.0))) * conversionFactor);
- if (txItem.style.baselineOffset() != 0)
- mm.translate(0, (txItem.style.baselineOffset() / 1000.0) * conversionFactor);
- if (txItem.style.scaleH() != 1000)
- mm.scale(txItem.style.scaleH() / 1000.0, 1);
- if (txItem.style.scaleV() != 1000)
- mm.scale(1, txItem.style.scaleV() / 1000.0);
- obO.setAttribute("RenderTransform", MatrixToStr(mm));
- QList<PageItem*> emG;
- if (txItem.embItem->isGroup())
- emG = txItem.embItem->getItemList();
- else
- emG.append(txItem.embItem);
- for (int em = 0; em < emG.count(); ++em)
- {
- PageItem* embed = emG.at(em);
- writeItemOnPage(embed->gXpos, embed->gYpos, embed, obO, rel_root);
- }
- grp.appendChild(obO);
- }
- continue;
- }
- QString chstr = txItem.chr;
- if ((txItem.chr == SpecialChars::PAGENUMBER) || (txItem.chr == SpecialChars::PAGECOUNT))
- chstr = Item->ExpandToken(txItem.index);
- double chs = txItem.style.fontSize();
- if (txItem.style.effects() & ScStyle_SmallCaps)
- {
- if (chstr.toUpper() != chstr)
- {
- chs = qMax(static_cast<int>(txItem.style.fontSize() * m_Doc->typographicPrefs().valueSmallCaps / 100), 1);
- chstr = chstr.toUpper();
- }
- }
- else if (txItem.style.effects() & ScStyle_AllCaps)
- chstr = chstr.toUpper();
- for (int cx = 0; cx < chstr.count(); cx++)
- {
- FPointArray pts;
- QChar chstrex = chstr[cx];
- uint chr = chstrex.unicode();
- QTransform chma;
- uint gl = txItem.style.font().char2CMap(chr);
- if (!chstrex.isSpace())
- {
- pts = txItem.style.font().glyphOutline(gl);
- if (pts.size() < 4)
- continue;
- chma = QTransform();
- chma.scale(txItem.glyphs->scaleH * txItem.style.fontSize() / 100.00, txItem.glyphs->scaleV * txItem.style.fontSize() / 100.0);
- pts.map(chma);
- if (txItem.style.effects() & (ScStyle_Subscript | ScStyle_Superscript))
- pts.translate(0, -(chs / 10.0 * txItem.glyphs->scaleV));
- else
- pts.translate(0, -(chs / 10.0));
- pts.translate(CurX, ls.y);
- // Fix for drop caps ???
- if (ls.isFirstLine && Item->itemText.paragraphStyle(ls.firstItem).hasDropCap() && (txItem.index == ls.firstItem))
- pts.translate(0, -ls.ascent);
- if (txItem.style.effects() & (ScStyle_Subscript | ScStyle_Superscript))
- pts.translate(0, txItem.glyphs->yoffset);
- if ((txItem.style.effects() & ScStyle_Shadowed) && (txItem.style.strokeColor() != CommonStrings::None))
- {
- FPointArray ptsS = pts.copy();
- ptsS.translate(txItem.style.fontSize() * txItem.style.shadowXOffset() / 10000.0, -txItem.style.fontSize() * txItem.style.shadowYOffset() / 10000.0);
- ptsS.scale(conversionFactor, conversionFactor);
- QString paS = SetClipPath(&ptsS, true);
- QDomElement glyS = p_docu.createElement("Path");
- glyS.setAttribute("Data", paS);
- glyS.setAttribute("Fill", SetColor(txItem.style.strokeColor(), txItem.style.strokeShade(), 0));
- grp.appendChild(glyS);
- }
- pts.scale(conversionFactor, conversionFactor);
- QString pa = SetClipPath(&pts, true);
- QDomElement gly = p_docu.createElement("Path");
- gly.setAttribute("Data", pa);
- gly.setAttribute("Fill", SetColor(txItem.style.fillColor(), txItem.style.fillShade(), 0));
- if (txItem.style.effects() & ScStyle_Outline)
- {
- gly.setAttribute("StrokeThickness", FToStr((chs * txItem.style.outlineWidth() / 10000.0) * conversionFactor));
- gly.setAttribute("Stroke", SetColor(txItem.style.strokeColor(), txItem.style.strokeShade(), 0));
- }
- grp.appendChild(gly);
- }
- if ((txItem.style.effects() & ScStyle_Underline) || ((txItem.style.effects() & ScStyle_UnderlineWords) && chstr.toUInt() != txItem.style.font().char2CMap(QChar(' '))))
- {
- double st, lw;
- if ((txItem.style.underlineOffset() != -1) || (txItem.style.underlineWidth() != -1))
- {
- if (txItem.style.underlineOffset() != -1)
- st = (txItem.style.underlineOffset() / 1000.0) * (txItem.style.font().descent(txItem.style.fontSize() / 10.0));
- else
- st = txItem.style.font().underlinePos(txItem.style.fontSize() / 10.0);
- if (txItem.style.underlineWidth() != -1)
- lw = (txItem.style.underlineWidth() / 1000.0) * (txItem.style.fontSize() / 10.0);
- else
- lw = qMax(txItem.style.font().strokeWidth(txItem.style.fontSize() / 10.0), 1.0);
- }
- else
- {
- st = txItem.style.font().underlinePos(txItem.style.fontSize() / 10.0);
- lw = qMax(txItem.style.font().strokeWidth(txItem.style.fontSize() / 10.0), 1.0);
- }
- if (txItem.style.baselineOffset() != 0)
- st += (txItem.style.fontSize() / 10.0) * txItem.glyphs->scaleV * (txItem.style.baselineOffset() / 1000.0);
- QDomElement gly = p_docu.createElement("Path");
- if (txItem.style.effects() & ScStyle_Subscript)
- gly.setAttribute("Data", QString("M%1,%2 L%3,%4").arg((CurX + txItem.glyphs->xoffset) * conversionFactor).arg((ls.y + txItem.glyphs->yoffset - st) * conversionFactor).arg((CurX + txItem.glyphs->xoffset + txItem.glyphs->xadvance) * conversionFactor).arg((ls.y + txItem.glyphs->yoffset - st) * conversionFactor));
- else
- gly.setAttribute("Data", QString("M%1,%2 L%3,%4").arg((CurX + txItem.glyphs->xoffset) * conversionFactor).arg((ls.y - st) * conversionFactor).arg((CurX + txItem.glyphs->xoffset + txItem.glyphs->xadvance) * conversionFactor).arg((ls.y - st) * conversionFactor));
- gly.setAttribute("Stroke", SetColor(txItem.style.fillColor(), txItem.style.fillShade(), 0));
- gly.setAttribute("StrokeThickness", FToStr(lw * conversionFactor));
- grp.appendChild(gly);
- }
- if (txItem.style.effects() & ScStyle_Strikethrough)
- {
- double st, lw;
- if ((txItem.style.strikethruOffset() != -1) || (txItem.style.strikethruWidth() != -1))
- {
- if (txItem.style.strikethruOffset() != -1)
- st = (txItem.style.strikethruOffset() / 1000.0) * (txItem.style.font().ascent(txItem.style.fontSize() / 10.0));
- else
- st = txItem.style.font().strikeoutPos(txItem.style.fontSize() / 10.0);
- if (txItem.style.strikethruWidth() != -1)
- lw = (txItem.style.strikethruWidth() / 1000.0) * (txItem.style.fontSize() / 10.0);
- else
- lw = qMax(txItem.style.font().strokeWidth(txItem.style.fontSize() / 10.0), 1.0);
- }
- else
- {
- st = txItem.style.font().strikeoutPos(txItem.style.fontSize() / 10.0);
- lw = qMax(txItem.style.font().strokeWidth(txItem.style.fontSize() / 10.0), 1.0);
- }
- if (txItem.style.baselineOffset() != 0)
- st += (txItem.style.fontSize() / 10.0) * txItem.glyphs->scaleV * (txItem.style.baselineOffset() / 1000.0);
- QDomElement gly = p_docu.createElement("Path");
- gly.setAttribute("Data", QString("M%1,%2 L%3,%4").arg((CurX + txItem.glyphs->xoffset) * conversionFactor).arg((ls.y - st) * conversionFactor).arg((CurX + txItem.glyphs->xoffset + txItem.glyphs->xadvance) * conversionFactor).arg((ls.y - st) * conversionFactor));
- gly.setAttribute("Stroke", SetColor(txItem.style.fillColor(), txItem.style.fillShade(), 0));
- gly.setAttribute("StrokeThickness", FToStr(lw * conversionFactor));
- grp.appendChild(gly);
- }
- }
- }
- }
+
parentElem.appendChild(grp);
- if ((Item->GrTypeStroke != 0) || (Item->lineColor() != CommonStrings::None) || !Item->NamedLStyle.isEmpty())
- {
- if (Item->NamedLStyle.isEmpty())
- {
- if ((!Item->strokePattern().isEmpty()) && (Item->patternStrokePath))
- {
- processSymbolStroke(xOffset, yOffset, Item, parentElem, rel_root);
- }
- else
- {
- QDomElement ob3 = p_docu.createElement("Path");
- ob3.setAttribute("Data", pa);
- getStrokeStyle(Item, ob3, rel_root, xOffset, yOffset);
- ob3.setAttribute("RenderTransform", MatrixToStr(mpl));
- parentElem.appendChild(ob3);
- }
- }
- else
- {
- QDomElement grp2 = p_docu.createElement("Canvas");
- multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
- for (int it = ml.size()-1; it > -1; it--)
- {
- if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
- {
- QDomElement ob3 = p_docu.createElement("Path");
- ob3.setAttribute("Data", pa);
- GetMultiStroke(&ml[it], ob3);
- grp2.appendChild(ob3);
- }
- }
- if (Item->lineTransparency() != 0)
- grp2.setAttribute("Opacity", FToStr(1.0 - Item->lineTransparency()));
- grp2.setAttribute("RenderTransform", MatrixToStr(mpl));
- parentElem.appendChild(grp2);
- }
- }
-}
-
-void XPSExPlug::processPathTextItem(double xOffset, double yOffset, PageItem *Item, QDomElement &parentElem, QDomElement &rel_root)
-{
- QDomElement grp = p_docu.createElement("Canvas");
- QTransform mpx;
- mpx.translate(xOffset * conversionFactor, yOffset * conversionFactor);
- if ((Item->rotation() != 0.0) || Item->imageFlippedH() || Item->imageFlippedV())
- {
- mpx.rotate(Item->rotation());
- if (Item->imageFlippedH())
- {
- mpx.translate(Item->width() * conversionFactor, 0);
- mpx.scale(-1, 1);
- }
- if (Item->imageFlippedV())
- {
- mpx.translate(0, Item->height() * conversionFactor);
- mpx.scale(1, -1);
- }
- }
- grp.setAttribute("RenderTransform", MatrixToStr(mpx));
- if ((Item->PoShow) && (Item->lineColor() != CommonStrings::None))
- {
- QDomElement ob = p_docu.createElement("Path");
- FPointArray path = Item->PoLine.copy();
- path.scale(conversionFactor, conversionFactor);
- QString pa = SetClipPath(&path, false);
- ob.setAttribute("Data", pa);
- if (Item->NamedLStyle.isEmpty())
- {
- if ((!Item->strokePattern().isEmpty()) && (Item->patternStrokePath))
- {
- processSymbolStroke(xOffset, yOffset, Item, parentElem, rel_root);
- }
- else
- {
- getStrokeStyle(Item, ob, rel_root, xOffset, yOffset);
- grp.appendChild(ob);
- }
- }
- else
- {
- QDomElement grp2 = p_docu.createElement("Canvas");
- multiLine ml = m_Doc->MLineStyles[Item->NamedLStyle];
- for (int it = ml.size()-1; it > -1; it--)
- {
- if ((ml[it].Color != CommonStrings::None) && (ml[it].Width != 0))
- {
- QDomElement ob3 = p_docu.createElement("Path");
- ob3.setAttribute("Data", pa);
- GetMultiStroke(&ml[it], ob3);
- grp2.appendChild(ob3);
- }
- }
- if (Item->lineTransparency() != 0)
- grp2.setAttribute("Opacity", FToStr(1.0 - Item->lineTransparency()));
- grp.appendChild(grp2);
- }
- }
- QString chstr;
- for (int a = 0; a < Item->asPathText()->itemRenderText.length(); ++a)
- {
- //ScText *hl = Item->asPathText()->itemRenderText.item_p(a);
- const CharStyle& charStyle(Item->asPathText()->itemRenderText.charStyle(a));
- const PathData* pdata = &(Item->asPathText()->textLayout.point(a));
- const GlyphLayout* glyphs = Item->asPathText()->itemRenderText.getGlyphs(a);
- PageItem* embItem = Item->asPathText()->itemRenderText.hasObject(a)?
- Item->asPathText()->itemRenderText.object(a) : NULL;
-
- chstr = Item->asPathText()->itemRenderText.text(a,1);
- if ((chstr == QChar(13)) || (chstr == QChar(29)))
- continue;
- if (chstr == QChar(30))
- {
- chstr = Item->ExpandToken(a);
- if (chstr == QChar(32))
- continue;
- }
- double chs = charStyle.fontSize();
- if (charStyle.effects() & ScStyle_SmallCaps)
- {
- if (chstr.toUpper() != chstr)
- {
- chs = qMax(static_cast<int>(charStyle.fontSize() * m_Doc->typographicPrefs().valueSmallCaps / 100), 1);
- chstr = chstr.toUpper();
- }
- }
- else if (charStyle.effects() & ScStyle_AllCaps)
- chstr = chstr.toUpper();
- uint chr = chstr[0].unicode();
- QPointF tangt = QPointF( cos(pdata->PRot), sin(pdata->PRot) );
- QTransform trafo = QTransform( 1, 0, 0, -1, -pdata->PDx * conversionFactor, 0 );
- if (Item->textPathFlipped)
- trafo *= QTransform(1, 0, 0, -1, 0, 0);
- if (Item->textPathType == 0)
- trafo *= QTransform( tangt.x(), tangt.y(), tangt.y(), -tangt.x(), pdata->PtransX * conversionFactor, pdata->PtransY * conversionFactor );
- else if (Item->textPathType == 1)
- trafo *= QTransform(1, 0, 0, -1, pdata->PtransX * conversionFactor, pdata->PtransY * conversionFactor );
- else if (Item->textPathType == 2)
- {
- double a = 1;
- if (tangt.x() < 0)
- a = -1;
- if (fabs(tangt.x()) > 0.1)
- trafo *= QTransform( a, (tangt.y() / tangt.x()) * a, 0, -1, pdata->PtransX * conversionFactor, pdata->PtransY * conversionFactor ); // ID's Skew mode
- else
- trafo *= QTransform( a, 4 * a, 0, -1, pdata->PtransX * conversionFactor, pdata->PtransY * conversionFactor );
- }
- if (charStyle.baselineOffset() != 0)
- trafo.translate(0, (-charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0));
- trafo.translate(0, Item->BaseOffs);
- QTransform finalMat = trafo;
- if (chr == SpecialChars::OBJECT)
- {
- if (embItem != NULL)
- {
- QDomElement obO = p_docu.createElement("Canvas");
- QTransform mm = finalMat;
- mm.translate(0, (-(embItem->height() * (charStyle.scaleV() / 1000.0))) * conversionFactor);
- if (charStyle.scaleH() != 1000)
- mm.scale(charStyle.scaleH() / 1000.0, 1);
- if (charStyle.scaleV() != 1000)
- mm.scale(1, charStyle.scaleV() / 1000.0);
- obO.setAttribute("RenderTransform", MatrixToStr(mm));
- QList<PageItem*> emG;
- if (embItem->isGroup())
- emG = embItem->getItemList();
- else
- emG.append(embItem);
- for (int em = 0; em < emG.count(); ++em)
- {
- PageItem* embed = emG.at(em);
- writeItemOnPage(embed->gXpos, embed->gYpos, embed, obO, rel_root);
- }
- grp.appendChild(obO);
- }
- continue;
- }
- finalMat.scale(conversionFactor, conversionFactor);
- FPointArray pts;
- QTransform chma;
- uint gl = charStyle.font().char2CMap(chr);
- pts = charStyle.font().glyphOutline(gl);
- if (pts.size() < 4)
- continue;
- chma = QTransform();
- chma.scale(glyphs->scaleH * charStyle.fontSize() / 100.00, glyphs->scaleV * charStyle.fontSize() / 100.0);
- pts.map(chma);
- if (charStyle.effects() & (ScStyle_Subscript | ScStyle_Superscript))
- pts.translate(0, -(chs / 10.0 * glyphs->scaleV));
- else
- pts.translate(0, -(chs / 10.0));
- if (charStyle.effects() & (ScStyle_Subscript | ScStyle_Superscript))
- pts.translate(0, glyphs->yoffset);
- if ((charStyle.effects() & ScStyle_Shadowed) && (charStyle.strokeColor() != CommonStrings::None))
- {
- FPointArray ptsS = pts.copy();
- ptsS.translate(charStyle.fontSize() * charStyle.shadowXOffset() / 10000.0, -charStyle.fontSize() * charStyle.shadowYOffset() / 10000.0);
- ptsS.map(finalMat);
- QString paS = SetClipPath(&ptsS, true);
- QDomElement glyS = p_docu.createElement("Path");
- glyS.setAttribute("Data", paS);
- glyS.setAttribute("Fill", SetColor(charStyle.strokeColor(), charStyle.strokeShade(), 0));
- grp.appendChild(glyS);
- }
- pts.map(finalMat);
- QString pa = SetClipPath(&pts, true);
- QDomElement gly = p_docu.createElement("Path");
- gly.setAttribute("Data", pa);
- gly.setAttribute("Fill", SetColor(charStyle.fillColor(), charStyle.fillShade(), 0));
- if (charStyle.effects() & ScStyle_Outline)
- {
- gly.setAttribute("StrokeThickness", FToStr((chs * charStyle.outlineWidth() / 10000.0) * conversionFactor));
- gly.setAttribute("Stroke", SetColor(charStyle.strokeColor(), charStyle.strokeShade(), 0));
- }
- grp.appendChild(gly);
- if ((charStyle.effects() & ScStyle_Underline) || ((charStyle.effects() & ScStyle_UnderlineWords) && chstr.toUInt() != charStyle.font().char2CMap(QChar(' '))))
- {
- double st, lw;
- if ((charStyle.underlineOffset() != -1) || (charStyle.underlineWidth() != -1))
- {
- if (charStyle.underlineOffset() != -1)
- st = (charStyle.underlineOffset() / 1000.0) * (charStyle.font().descent(charStyle.fontSize() / 10.0));
- else
- st = charStyle.font().underlinePos(charStyle.fontSize() / 10.0);
- if (charStyle.underlineWidth() != -1)
- lw = (charStyle.underlineWidth() / 1000.0) * (charStyle.fontSize() / 10.0);
- else
- lw = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- else
- {
- st = charStyle.font().underlinePos(charStyle.fontSize() / 10.0);
- lw = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- if (charStyle.baselineOffset() != 0)
- st += (charStyle.fontSize() / 10.0) * glyphs->scaleV * (charStyle.baselineOffset() / 1000.0);
- FPointArray ptsS;
- ptsS.svgInit();
- if (charStyle.effects() & ScStyle_Subscript)
- {
- ptsS.svgMoveTo(glyphs->xoffset, glyphs->yoffset - st);
- ptsS.svgLineTo(glyphs->xoffset + glyphs->xadvance, glyphs->yoffset - st);
- }
- else
- {
- ptsS.svgMoveTo(glyphs->xoffset, -st);
- ptsS.svgLineTo(glyphs->xoffset + glyphs->xadvance, -st);
- }
- ptsS.map(finalMat);
- QString paS = SetClipPath(&ptsS, true);
- QDomElement gly = p_docu.createElement("Path");
- gly.setAttribute("Data", paS);
- gly.setAttribute("Stroke", SetColor(charStyle.fillColor(), charStyle.fillShade(), 0));
- gly.setAttribute("StrokeThickness", FToStr(lw * conversionFactor));
- grp.appendChild(gly);
- }
- if (charStyle.effects() & ScStyle_Strikethrough)
- {
- double st, lw;
- if ((charStyle.strikethruOffset() != -1) || (charStyle.strikethruWidth() != -1))
- {
- if (charStyle.strikethruOffset() != -1)
- st = (charStyle.strikethruOffset() / 1000.0) * (charStyle.font().ascent(charStyle.fontSize() / 10.0));
- else
- st = charStyle.font().strikeoutPos(charStyle.fontSize() / 10.0);
- if (charStyle.strikethruWidth() != -1)
- lw = (charStyle.strikethruWidth() / 1000.0) * (charStyle.fontSize() / 10.0);
- else
- lw = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- else
- {
- st = charStyle.font().strikeoutPos(charStyle.fontSize() / 10.0);
- lw = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- if (charStyle.baselineOffset() != 0)
- st += (charStyle.fontSize() / 10.0) * glyphs->scaleV * (charStyle.baselineOffset() / 1000.0);
- FPointArray ptsS;
- ptsS.svgInit();
- ptsS.svgMoveTo(glyphs->xoffset, -st);
- ptsS.svgLineTo(glyphs->xoffset + glyphs->xadvance, -st);
- ptsS.map(finalMat);
- QString paS = SetClipPath(&ptsS, true);
- QDomElement gly = p_docu.createElement("Path");
- gly.setAttribute("Data", paS);
- gly.setAttribute("Stroke", SetColor(charStyle.fillColor(), charStyle.fillShade(), 0));
- gly.setAttribute("StrokeThickness", FToStr(lw * conversionFactor));
- grp.appendChild(gly);
- }
- }
- parentElem.appendChild(grp);
- return;
+ XPSPainter p(Item, grp, this, xps_fontMap, rel_root);
+ Item->textLayout.renderBackground(&p);
+ Item->textLayout.render(&p);
}
void XPSExPlug::processSymbolItem(double xOffset, double yOffset, PageItem *Item, QDomElement &parentElem, QDomElement &rel_root)
@@ -2274,10 +1641,10 @@
}
}
-QString XPSExPlug::embedFont(const ScFace *font, QDomElement &rel_root)
+QString XPSExPlug::embedFont(const ScFace font, QDomElement &rel_root)
{
QByteArray fontData;
- loadRawText(font->fontFilePath(), fontData);
+ loadRawText(font.fontFilePath(), fontData);
QUuid id = QUuid::createUuid();
QString guidString = id.toString();
guidString = guidString.toUpper();
@@ -3084,6 +2451,12 @@
return cc.setNum(c);
}
+QString XPSExPlug::MatrixToStr(QTransform &mat, double factor)
+{
+ QString cc("%1, %2, %3, %4, %5, %6");
+ return cc.arg(mat.m11()).arg(mat.m12()).arg(mat.m21()).arg(mat.m22()).arg(mat.dx() * factor).arg(mat.dy() * factor);
+}
+
QString XPSExPlug::MatrixToStr(QTransform &mat)
{
QString cc("%1, %2, %3, %4, %5, %6");
Modified: trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.h
==============================================================================
--- trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.h (original)
+++ trunk/Scribus/scribus/plugins/export/xpsexport/xpsexplugin.h Wed Mar 23 20:21:36 2016
@@ -58,8 +58,9 @@
class XPSExPlug : public QObject
{
- Q_OBJECT
+ Q_OBJECT
+ friend class XPSPainter;
public:
/*!
\author Franz Schmid
@@ -81,7 +82,6 @@
void processLineItem(double xOffset, double yOffset, PageItem *Item, QDomElement &parentElem, QDomElement &rel_root);
void processImageItem(double xOffset, double yOffset, PageItem *Item, QDomElement &parentElem, QDomElement &rel_root);
void processTextItem(double xOffset, double yOffset, PageItem *Item, QDomElement &parentElem, QDomElement &rel_root);
- void processPathTextItem(double xOffset, double yOffset, PageItem *Item, QDomElement &parentElem, QDomElement &rel_root);
void processSymbolItem(double xOffset, double yOffset, PageItem *Item, QDomElement &parentElem, QDomElement &rel_root);
void processTableItem(double xOffset, double yOffset, PageItem *Item, QDomElement &parentElem, QDomElement &rel_root);
void paintBorder(const TableBorder &border, const QPointF &start, const QPointF &end, const QPointF &startOffsetFactors, const QPointF &endOffsetFactors, QDomElement &ob);
@@ -89,7 +89,7 @@
void processSymbolStroke(double xOffset, double yOffset, PageItem *Item, QDomElement &parentElem, QDomElement &rel_root);
void processArrows(double xOffset, double yOffset, PageItem *Item, QDomElement &parentElem, QDomElement &rel_root);
void drawArrow(double xOffset, double yOffset, PageItem *Item, QDomElement &parentElem, QDomElement &rel_root, FPointArray &arrow);
- QString embedFont(const ScFace *font, QDomElement &rel_root);
+ QString embedFont(const ScFace font, QDomElement &rel_root);
void GetMultiStroke(struct SingleLine *sl, QDomElement &parentElem);
void getStrokeStyle(PageItem *Item, QDomElement &parentElem, QDomElement &rel_root, double xOffset, double yOffset, bool forArrow = false);
void getFillStyle(PageItem *Item, QDomElement &parentElem, QDomElement &rel_root, double xOffset, double yOffset, bool withTransparency = true);
@@ -104,6 +104,7 @@
QString FToStr(double c);
QString IToStr(int c);
QString MatrixToStr(QTransform &mat);
+ QString MatrixToStr(QTransform &mat, double factor);
int hex2int(char hex);
bool checkForFallback(PageItem *Item);
ScribusDoc* m_Doc;
Modified: trunk/Scribus/scribus/pslib.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/pslib.cpp
==============================================================================
--- trunk/Scribus/scribus/pslib.cpp (original)
+++ trunk/Scribus/scribus/pslib.cpp Wed Mar 23 20:21:36 2016
@@ -55,12 +55,157 @@
#include "scstreamfilter_ascii85.h"
#include "scstreamfilter_flate.h"
#include "tableutils.h"
+#include "text/textlayoutpainter.h"
#include "ui/multiprogressdialog.h"
#include "util.h"
#include "util_formats.h"
#include "util_math.h"
+#include "text/boxes.h"
using namespace TableUtils;
+
+class PSPainter:public TextLayoutPainter
+{
+ ScribusDoc* m_Doc;
+ uint m_argh;
+ ScPage* m_page;
+ bool m_sep;
+ bool m_farb;
+ bool m_master;
+ PSLib* m_ps;
+
+ void applyTransform()
+ {
+ if (matrix() != QTransform())
+ {
+ m_ps->PutStream(m_ps->MatrixToStr(1.0, 0.0, 0.0, -1.0, x(), 0.0) + "\n");
+ m_ps->PutStream(m_ps->MatrixToStr(matrix().m11(), -matrix().m12(), matrix().m21(), -matrix().m22(), matrix().dx(), -matrix().dy()) + "\n");
+ m_ps->PutStream("[0.0 0.0 0.0 0.0 0.0 0.0] concatmatrix\nconcat\n");
+ }
+ }
+
+public:
+ PSPainter(ScribusDoc* Doc, uint argh, ScPage* page, bool sep, bool farb, bool master, PSLib* ps):
+ m_Doc(Doc),
+ m_argh(argh),
+ m_page(page),
+ m_sep(sep),
+ m_farb(farb),
+ m_master(master),
+ m_ps(ps)
+ {}
+
+ void drawGlyph(const GlyphLayout gl);
+ void drawGlyphOutline(const GlyphLayout gl, bool fill);
+ void drawLine(QPointF start, QPointF end);
+ void drawRect(QRectF rect);
+ void drawObject(PageItem* item);
+};
+
+void PSPainter::drawGlyph(const GlyphLayout gl)
+{
+ if (gl.glyph >= ScFace::CONTROL_GLYPHS)
+ return;
+
+ m_ps->PS_save();
+ applyTransform();
+ m_ps->PS_translate(x(), -(y() - fontSize()));
+ if (gl.scaleH != 1.0)
+ m_ps->PS_scale(gl.scaleH, 1);
+ if (gl.scaleV != 1.0)
+ {
+ m_ps->PS_translate(0, -(fontSize() - fontSize() * gl.scaleV));
+ m_ps->PS_scale(1, gl.scaleV);
+ }
+ if (fillColor().color != CommonStrings::None)
+ m_ps->putColorNoDraw(fillColor().color, fillColor().shade);
+ m_ps->PS_showSub(gl.glyph, m_ps->FontSubsetMap[font().scName()], fontSize(), false);
+ m_ps->PS_restore();
+}
+
+void PSPainter::drawGlyphOutline(const GlyphLayout gl, bool fill)
+{
+ if (gl.glyph >= ScFace::CONTROL_GLYPHS)
+ return;
+
+ int h, s, v, k;
+ QVector<double> dum;
+ dum.clear();
+ m_ps->PS_save();
+ applyTransform();
+ if (strokeColor().color != CommonStrings::None)
+ {
+ m_ps->PS_setlinewidth(strokeWidth());
+ m_ps->PS_setcapjoin(Qt::FlatCap, Qt::MiterJoin);
+ m_ps->PS_setdash(Qt::SolidLine, 0, dum);
+ m_ps->PS_translate(x(), -(y() - fontSize()));
+ FPointArray gly = font().glyphOutline(gl.glyph);
+ QTransform chma;
+ chma.scale((fontSize() * gl.scaleH) / 10.0, (fontSize() * gl.scaleV) / 10.0);
+ gly.map(chma);
+ m_ps->PS_translate(0, -(fontSize() - fontSize() * gl.scaleV));
+ m_ps->SetColor(strokeColor().color, strokeColor().shade, &h, &s, &v, &k);
+ m_ps->PS_setcmykcolor_stroke(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
+ m_ps->SetClipPath(&gly, true);
+ m_ps->PS_closepath();
+ m_ps->putColor(strokeColor().color, strokeColor().shade, false);
+
+ if (gl.scaleH != 1.0 || gl.scaleV != 1.0)
+ m_ps->PS_scale(gl.scaleH, gl.scaleV);
+ if (fill)
+ m_ps->putColorNoDraw(fillColor().color, fillColor().shade);
+ m_ps->PS_showSub(gl.glyph, m_ps->FontSubsetMap[font().scName()], fontSize(), false);
+ }
+ m_ps->PS_restore();
+}
+
+void PSPainter::drawRect(QRectF rect)
+{
+ int h, s, v, k;
+ m_ps->PS_save();
+ applyTransform();
+ m_ps->PS_moveto(x() + rect.x(), -y() - rect.y());
+ m_ps->PS_lineto(x() + rect.x() + rect.width(), -y() - rect.y());
+ m_ps->PS_lineto(x() + rect.x() + rect.width(), -y() - rect.y() - rect.height());
+ m_ps->PS_lineto(x() + rect.x(), -y() - rect.y() - rect.height());
+ m_ps->PS_closepath();
+ m_ps->SetColor(fillColor().color, fillColor().shade, &h, &s, &v, &k);
+ m_ps->PS_setcmykcolor_fill(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
+ m_ps->putColor(fillColor().color, fillColor().shade, true);
+ m_ps->PS_restore();
+}
+
+void PSPainter::drawLine(QPointF start, QPointF end)
+{
+ int h, s, v, k ;
+ QVector<double> dum;
+ dum.clear();
+ m_ps->PS_save();
+ applyTransform();
+ if (fillColor().color != CommonStrings::None)
+ {
+ m_ps->PS_setcapjoin(Qt::FlatCap, Qt::MiterJoin);
+ m_ps->PS_setdash(Qt::SolidLine, 0, dum);
+ m_ps->SetColor(fillColor().color,fillColor().shade, &h, &s, &v, &k);
+ m_ps->PS_setcmykcolor_stroke(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
+ }
+ m_ps->PS_setlinewidth(strokeWidth());
+ m_ps->PS_moveto(x() + start.x(), -y() - start.y());
+ m_ps->PS_lineto(x() + end.x(), -y() - end.y());
+ m_ps->putColor(fillColor().color, fillColor().shade, false);
+ m_ps->PS_restore();
+}
+
+void PSPainter::drawObject(PageItem* item)
+{
+ m_ps->PS_save();
+ m_ps->PS_translate(x(), -y());
+ applyTransform();
+ if (scaleH() != 1 || scaleV() != 1)
+ m_ps->PS_scale(scaleH(), scaleV());
+ m_ps->ProcessItem(m_Doc, m_page, item, m_argh, m_sep, m_farb, m_master, true);
+ m_ps->PS_restore();
+}
PSLib::PSLib(PrintOptions &options, bool psart, SCFonts &AllFonts, QMap<QString, QMap<uint, FPointArray> > DocFonts, ColorList DocColors, bool pdf, bool spot)
{
@@ -555,7 +700,7 @@
PutStream("%%Page: " + IToStr(Seiten) + " " + IToStr(Seiten) + "\n");
PutStream("%%PageOrientation: ");
// when creating EPS files determine the orientation from the bounding box
- if (!psExport)
+ if (!psExport)
{
if ((pg->width() - Ma->left() - Ma->right()) <= (pg->height() - Ma->bottom() - Ma->top()))
PutStream("Portrait\n");
@@ -1665,14 +1810,8 @@
bool PSLib::ProcessItem(ScribusDoc* Doc, ScPage* a, PageItem* c, uint PNr, bool sep, bool farb, bool master, bool embedded, bool useTemplate)
{
- double tsz;
int h, s, v, k;
- int d;
- int savedOwnPage;
- //ScText *hl;
QVector<double> dum;
- QChar chstr;
- QString tmps;
if (c->printEnabled())
{
fillRule = true;
@@ -2156,401 +2295,7 @@
PS_restore();
}
}
- savedOwnPage = c->OwnPage;
- c->OwnPage = PNr-1;
- c->asPathText()->layout();
- c->OwnPage = savedOwnPage;
- for (d = 0; d < c->maxCharsInFrame(); ++d)
- {
- // hl = c->asPathText()->itemRenderText.item_p(d);
- chstr = c->asPathText()->itemRenderText.text(d);
- if ((chstr == QChar(13)) || (chstr == QChar(30)) || (chstr == QChar(9)) || (chstr == QChar(28)))
- continue;
-
- const CharStyle & style(c->asPathText()->itemRenderText.charStyle(d));
- const PathData& pdata(c->textLayout.point(d));
- const GlyphLayout* glyphs(c->asPathText()->itemRenderText.getGlyphs(d));
- PageItem* embItem = c->asPathText()->itemRenderText.hasObject(d)?
- c->asPathText()->itemRenderText.object(d) : NULL;
-
- QPointF tangt = QPointF( cos(pdata.PRot), sin(pdata.PRot) );
- tsz = style.fontSize();
- if (chstr == QChar(29))
- chstr = ' ';
- if (chstr == QChar(0xA0))
- chstr = ' ';
- if (style.effects() & ScStyle_AllCaps)
- {
- if (chstr.toUpper() != chstr)
- chstr = chstr.toUpper();
- }
- if (style.effects() & ScStyle_SmallCaps)
- {
- if (chstr.toUpper() != chstr)
- {
- tsz = style.fontSize() * Doc->typographicPrefs().valueSmallCaps / 100;
- chstr = chstr.toUpper();
- }
- }
- if (style.effects() & ScStyle_Superscript)
- tsz = style.fontSize() * Doc->typographicPrefs().scalingSuperScript / 100;
- if (style.effects() & ScStyle_Subscript)
- tsz = style.fontSize() * Doc->typographicPrefs().scalingSubScript / 100;
- if (style.fillColor() != CommonStrings::None)
- {
- SetColor(style.fillColor(), style.fillShade(), &h, &s, &v, &k);
- PS_setcmykcolor_stroke(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- }
- if (embItem != NULL)
- {
- PS_save();
- PutStream( MatrixToStr(1.0, 0.0, 0.0, -1.0, -pdata.PDx, 0.0) + "\n");
- if (c->textPathFlipped)
- {
- PutStream("[1 0 0 -1 0 0]\n");
- PutStream("[0 0 0 0 0 0] concatmatrix\n"); //???????
- }
- if (c->textPathType == 0)
- PutStream( MatrixToStr(tangt.x(), -tangt.y(), -tangt.y(), -tangt.x(), pdata.PtransX, -pdata.PtransY) + "\n");
- else if (c->textPathType == 1)
- PutStream( MatrixToStr(1.0, 0.0, 0.0, -1.0, pdata.PtransX, -pdata.PtransY) + "\n");
- else if (c->textPathType == 2)
- {
- double a = 1;
- double b = -1;
- if (tangt.x()< 0)
- {
- a = -1;
- b = 1;
- }
- if (fabs(tangt.x()) > 0.1)
- PutStream( MatrixToStr(a, (tangt.y() / tangt.x()) * b, 0.0, -1.0, pdata.PtransX, -pdata.PtransY) + "\n");
- else
- PutStream( MatrixToStr(a, 4.0, 0.0, -1.0, pdata.PtransX, -pdata.PtransY) + "\n");
- }
- PutStream("[0.0 0.0 0.0 0.0 0.0 0.0] concatmatrix\nconcat\n");
-// PS_translate(0, (tsz / 10.0));
- if (c->BaseOffs != 0)
- PS_translate(0, -c->BaseOffs);
- if (style.scaleH() != 1000)
- PS_scale(style.scaleH() / 1000.0, 1);
- QList<PageItem*> emG;
- if (embItem->isGroup())
- emG = embItem->getItemList();
- else
- emG.append(embItem);
- for (int em = 0; em < emG.count(); ++em)
- {
- PageItem* embedded = emG.at(em);
- PS_save();
- PS_translate(embedded->gXpos * (style.scaleH() / 1000.0), ((embedded->gHeight * (style.scaleV() / 1000.0)) - embedded->gYpos * (style.scaleV() / 1000.0)));
- if (style.baselineOffset() != 0)
- PS_translate(0, embedded->gHeight * (style.baselineOffset() / 1000.0));
- if (style.scaleH() != 1000)
- PS_scale(style.scaleH() / 1000.0, 1);
- if (style.scaleV() != 1000)
- PS_scale(1, style.scaleV() / 1000.0);
- ProcessItem(Doc, a, embedded, PNr, sep, farb, master, true);
- PS_restore();
- }
- PS_restore();
- continue;
- }
- /* Subset all TTF Fonts until the bug in the TTF-Embedding Code is fixed */
- if (FontSubsetMap.contains(style.font().scName()))
- {
-// uint chr = chstr.unicode();
- uint chr = style.font().char2CMap(chstr);
- if (style.font().canRender(chstr))
- {
- PS_save();
- if (style.fillColor() != CommonStrings::None)
- {
- PutStream( MatrixToStr(1.0, 0.0, 0.0, -1.0, -pdata.PDx, 0.0) + "\n");
- if (c->textPathFlipped)
- {
- PutStream("[1.0 0.0 0.0 -1.0 0.0 0.0]\n");
- PutStream("[0.0 0.0 0.0 0.0 0.0 0.0] concatmatrix\n");
- }
- if (c->textPathType == 0)
- PutStream( MatrixToStr(tangt.x(), -tangt.y(), -tangt.y(), -tangt.x(), pdata.PtransX, -pdata.PtransY) + "\n");
- else if (c->textPathType == 1)
- PutStream( MatrixToStr(1.0, 0.0, 0.0, -1.0, pdata.PtransX, -pdata.PtransY) + "\n");
- else if (c->textPathType == 2)
- {
- double a = 1;
- double b = -1;
- if (tangt.x() < 0)
- {
- a = -1;
- b = 1;
- }
- if (fabs(tangt.x()) > 0.1)
- PutStream( MatrixToStr(a, (tangt.y() / tangt.x()) * b, 0.0, -1.0, pdata.PtransX, -pdata.PtransY) + "\n");
- else
- PutStream( MatrixToStr(a, 4.0, 0.0, -1.0, pdata.PtransX, -pdata.PtransY) + "\n");
- }
- PutStream("[0.0 0.0 0.0 0.0 0.0 0.0] concatmatrix\nconcat\n");
- PS_translate(0, (tsz / 10.0));
- if (c->BaseOffs != 0)
- PS_translate(0, -c->BaseOffs);
- if (glyphs->xoffset !=0 || glyphs->yoffset != 0)
- PS_translate(glyphs->xoffset, -glyphs->yoffset);
- if (style.scaleH() != 1000)
- PS_scale(style.scaleH() / 1000.0, 1);
- if (((style.effects() & ScStyle_Underline) && !SpecialChars::isBreak(chstr)) //FIXME && (chstr != QChar(13)))
- || ((style.effects() & ScStyle_UnderlineWords) && !chstr.isSpace() && !SpecialChars::isBreak(chstr)))
- {
- PS_save();
- PS_translate(0, -(tsz / 10.0));
- double Ulen = glyphs->xadvance;
- double Upos, Uwid;
- if ((style.underlineOffset() != -1) || (style.underlineWidth() != -1))
- {
- if (style.underlineOffset() != -1)
- Upos = (style.underlineOffset() / 1000.0) * (style.font().descent(style.fontSize() / 10.0));
- else
- Upos = style.font().underlinePos(style.fontSize() / 10.0);
- if (style.underlineWidth() != -1)
- Uwid = (style.underlineWidth() / 1000.0) * (style.fontSize() / 10.0);
- else
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- else
- {
- Upos = style.font().underlinePos(style.fontSize() / 10.0);
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- if (style.baselineOffset() != 0)
- Upos += (style.fontSize() / 10.0) * glyphs->scaleV * (style.baselineOffset() / 1000.0);
- if (style.fillColor() != CommonStrings::None)
- {
- SetColor(style.fillColor(), style.fillShade(), &h, &s, &v, &k);
- PS_setcmykcolor_stroke(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- }
- PS_setlinewidth(Uwid);
- if (style.effects() & ScStyle_Subscript)
- {
- PS_moveto(glyphs->xoffset , Upos);
- PS_lineto(glyphs->xoffset+Ulen, Upos);
- }
- else
- {
- PS_moveto(glyphs->xoffset , glyphs->yoffset+Upos);
- PS_lineto(glyphs->xoffset+Ulen, glyphs->yoffset+Upos);
- }
- putColor(style.fillColor(), style.fillShade(), false);
- PS_restore();
- }
- if (chstr != ' ')
- {
- if ((style.effects() & ScStyle_Shadowed) && (style.strokeColor() != CommonStrings::None))
- {
- PS_save();
- PS_translate(style.fontSize() * style.shadowXOffset() / 10000.0, style.fontSize() * style.shadowYOffset() / 10000.0);
- putColorNoDraw(style.strokeColor(), style.strokeShade());
- PS_showSub(chr, FontSubsetMap[style.font().scName()], tsz / 10.0, false);
- PS_restore();
- }
- putColorNoDraw(style.fillColor(), style.fillShade());
- PS_showSub(chr, FontSubsetMap[style.font().scName()], tsz / 10.0, false);
- if ((style.effects() & ScStyle_Outline))
- {
- if ((style.strokeColor() != CommonStrings::None) && ((tsz * style.outlineWidth() / 10000.0) != 0))
- {
- PS_save();
- PS_setlinewidth(tsz * style.outlineWidth() / 10000.0);
- putColorNoDraw(style.strokeColor(), style.strokeShade());
- PS_showSub(chr, FontSubsetMap[style.font().scName()], tsz / 10.0, true);
- PS_restore();
- }
- }
- }
- if ((style.effects() & ScStyle_Strikethrough) && (chstr != SpecialChars::PARSEP))
- {
- PS_save();
- PS_translate(0, -(tsz / 10.0));
- double Ulen = glyphs->xadvance;
- double Upos, Uwid;
- if ((style.strikethruOffset() != -1) || (style.strikethruWidth() != -1))
- {
- if (style.strikethruOffset() != -1)
- Upos = (style.strikethruOffset() / 1000.0) * (style.font().ascent(style.fontSize() / 10.0));
- else
- Upos = style.font().strikeoutPos(style.fontSize() / 10.0);
- if (style.strikethruWidth() != -1)
- Uwid = (style.strikethruWidth() / 1000.0) * (style.fontSize() / 10.0);
- else
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- else
- {
- Upos = style.font().strikeoutPos(style.fontSize() / 10.0);
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- if (style.baselineOffset() != 0)
- Upos += (style.fontSize() / 10.0) * glyphs->scaleV * (style.baselineOffset() / 1000.0);
- if (style.fillColor() != CommonStrings::None)
- {
- SetColor(style.fillColor(), style.fillShade(), &h, &s, &v, &k);
- PS_setcmykcolor_stroke(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- }
- PS_setlinewidth(Uwid);
- PS_moveto(glyphs->xoffset , Upos);
- PS_lineto(glyphs->xoffset+Ulen, Upos);
- putColor(style.fillColor(), style.fillShade(), false);
- PS_restore();
- }
- }
- PS_restore();
- }
- }
- else
- {
- uint glyph = glyphs->glyph;
- PS_selectfont(style.font().replacementName(), tsz / 10.0);
- PS_save();
- PutStream( MatrixToStr(1.0, 0.0, 0.0, -1.0, -pdata.PDx, 0.0) + "\n");
- if (c->textPathFlipped)
- {
- PutStream("[1.0 0.0 0.0 -1.0 0.0 0.0]\n");
- PutStream("[0.0 0.0 0.0 0.0 0.0 0.0] concatmatrix\n");
- }
- if (c->textPathType == 0)
- PutStream( MatrixToStr(tangt.x(), -tangt.y(), -tangt.y(), -tangt.x(), pdata.PtransX, -pdata.PtransY) + "\n");
- else if (c->textPathType == 1)
- PutStream( MatrixToStr(1.0, 0.0, 0.0, -1.0, pdata.PtransX, -pdata.PtransY) + "\n");
- else if (c->textPathType == 2)
- {
- double a = 1;
- double b = -1;
- if (tangt.x() < 0)
- {
- a = -1;
- b = 1;
- }
- if (fabs(tangt.x()) > 0.1)
- PutStream( MatrixToStr(a, (tangt.y() / tangt.x()) * b, 0.0, -1.0, pdata.PtransX, -pdata.PtransY) + "\n");
- else
- PutStream( MatrixToStr(a, 4.0, 0.0, -1.0, pdata.PtransX, -pdata.PtransY) + "\n");
- }
- PutStream("[0.0 0.0 0.0 0.0 0.0 0.0] concatmatrix\nconcat\n");
- if (c->BaseOffs != 0)
- PS_translate(0, -c->BaseOffs);
- if (glyphs->xoffset !=0 || glyphs->yoffset != 0)
- PS_translate(glyphs->xoffset, -glyphs->yoffset);
- if (((style.effects() & ScStyle_Underline) && !SpecialChars::isBreak(chstr)) //FIXME && (chstr != QChar(13)))
- || ((style.effects() & ScStyle_UnderlineWords) && !chstr.isSpace() && !SpecialChars::isBreak(chstr)))
- {
- PS_save();
- double Ulen = glyphs->xadvance;
- double Upos, Uwid;
- if ((style.underlineOffset() != -1) || (style.underlineWidth() != -1))
- {
- if (style.underlineOffset() != -1)
- Upos = (style.underlineOffset() / 1000.0) * (style.font().descent(style.fontSize() / 10.0));
- else
- Upos = style.font().underlinePos(style.fontSize() / 10.0);
- if (style.underlineWidth() != -1)
- Uwid = (style.underlineWidth() / 1000.0) * (style.fontSize() / 10.0);
- else
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- else
- {
- Upos = style.font().underlinePos(style.fontSize() / 10.0);
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- if (style.baselineOffset() != 0)
- Upos += (style.fontSize() / 10.0) * glyphs->scaleV * (style.baselineOffset() / 1000.0);
- if (style.fillColor() != CommonStrings::None)
- {
- SetColor(style.fillColor(), style.fillShade(), &h, &s, &v, &k);
- PS_setcmykcolor_stroke(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- }
- PS_setlinewidth(Uwid);
- if (style.effects() & ScStyle_Subscript)
- {
- PS_moveto(glyphs->xoffset , Upos);
- PS_lineto(glyphs->xoffset+Ulen, Upos);
- }
- else
- {
- PS_moveto(glyphs->xoffset , glyphs->yoffset+Upos);
- PS_lineto(glyphs->xoffset+Ulen, glyphs->yoffset+Upos);
- }
- putColor(style.fillColor(), style.fillShade(), false);
- PS_restore();
- }
- if (chstr != ' ')
- {
- if ((style.effects() & ScStyle_Shadowed) && (style.strokeColor() != CommonStrings::None))
- {
- PS_save();
- PS_translate(style.fontSize() * style.shadowXOffset() / 10000.0, style.fontSize() * style.shadowYOffset() / 10000.0);
- PS_show_xyG(style.font().replacementName(), glyph, 0, 0, style.strokeColor(), style.strokeShade());
- PS_restore();
- }
- PS_show_xyG(style.font().replacementName(), glyph, 0, 0, style.fillColor(), style.fillShade());
- if ((style.effects() & ScStyle_Outline))
- {
- if ((style.strokeColor() != CommonStrings::None) && ((tsz * style.outlineWidth() / 10000.0) != 0))
- {
- uint gl = style.font().char2CMap(chstr);
- FPointArray gly = style.font().glyphOutline(gl);
- QTransform chma;
- chma.scale(tsz / 100.0, tsz / 100.0);
- gly.map(chma);
- PS_save();
- PS_setlinewidth(tsz * style.outlineWidth() / 10000.0);
- PS_translate(0, tsz / 10.0);
- SetColor(style.strokeColor(), style.strokeShade(), &h, &s, &v, &k);
- PS_setcmykcolor_stroke(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- SetClipPath(&gly);
- PS_closepath();
- putColor(style.strokeColor(), style.strokeShade(), false);
- PS_restore();
- }
- }
- }
- if ((style.effects() & ScStyle_Strikethrough) && (chstr != SpecialChars::PARSEP))
- {
- PS_save();
- double Ulen = glyphs->xadvance;
- double Upos, Uwid;
- if ((style.strikethruOffset() != -1) || (style.strikethruWidth() != -1))
- {
- if (style.strikethruOffset() != -1)
- Upos = (style.strikethruOffset() / 1000.0) * (style.font().ascent(style.fontSize() / 10.0));
- else
- Upos = style.font().strikeoutPos(style.fontSize() / 10.0);
- if (style.strikethruWidth() != -1)
- Uwid = (style.strikethruWidth() / 1000.0) * (style.fontSize() / 10.0);
- else
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- else
- {
- Upos = style.font().strikeoutPos(style.fontSize() / 10.0);
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- if (style.baselineOffset() != 0)
- Upos += (style.fontSize() / 10.0) * glyphs->scaleV * (style.baselineOffset() / 1000.0);
- if (style.fillColor() != CommonStrings::None)
- if (style.fillColor() != CommonStrings::None)
- {
- SetColor(style.fillColor(), style.fillShade(), &h, &s, &v, &k);
- PS_setcmykcolor_stroke(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- }
- PS_setlinewidth(Uwid);
- PS_moveto(glyphs->xoffset , Upos);
- PS_lineto(glyphs->xoffset+Ulen, Upos);
- putColor(style.fillColor(), style.fillShade(), false);
- PS_restore();
- }
- PS_restore();
- }
- }
+ setTextSt(Doc, c, PNr-1, a, sep, farb, master);
break;
case PageItem::Symbol:
if (m_Doc->docPatterns.contains(c->pattern()))
@@ -3221,10 +2966,6 @@
}
else if (ite->asPathText())
{
- double tsz;
- int d;
- //ScText *hl;
- QChar chstr;
PS_save();
PS_translate(ite->xPos() - mPage->xOffset(), mPage->height() - (ite->yPos() - mPage->yOffset()));
if (ite->PoShow)
@@ -3270,400 +3011,7 @@
PS_restore();
}
}
- int savedOwnPage = ite->OwnPage;
- ite->OwnPage = PNr;
- ite->asPathText()->layout();
- ite->OwnPage = savedOwnPage;
- for (d = 0; d < ite->maxCharsInFrame(); ++d)
- {
- //hl = ite->asPathText()->itemRenderText.item_p(d);
- chstr = ite->asPathText()->itemRenderText.text(d);
- const CharStyle & style(ite->asPathText()->itemRenderText.charStyle(d));
- if ((chstr == QChar(13)) || (chstr == QChar(30)) || (chstr == QChar(9)) || (chstr == QChar(28)))
- continue;
- const PathData& pdata(ite->textLayout.point(d));
- const GlyphLayout* glyphs(ite->asPathText()->itemRenderText.getGlyphs(d));
- PageItem* embItem = ite->asPathText()->itemRenderText.hasObject(d)?
- ite->asPathText()->itemRenderText.object(d) : NULL;
-
- QPointF tangt = QPointF( cos(pdata.PRot), sin(pdata.PRot) );
- tsz = style.fontSize();
- if (chstr == QChar(29))
- chstr = ' ';
- if (chstr == QChar(0xA0))
- chstr = ' ';
- if (style.effects() & ScStyle_AllCaps)
- {
- if (chstr.toUpper() != chstr)
- chstr = chstr.toUpper();
- }
- if (style.effects() & ScStyle_SmallCaps)
- {
- if (chstr.toUpper() != chstr)
- {
- tsz = style.fontSize() * Doc->typographicPrefs().valueSmallCaps / 100;
- chstr = chstr.toUpper();
- }
- }
- if (style.effects() & ScStyle_Superscript)
- tsz = style.fontSize() * Doc->typographicPrefs().scalingSuperScript / 100;
- if (style.effects() & ScStyle_Subscript)
- tsz = style.fontSize() * Doc->typographicPrefs().scalingSubScript / 100;
- if (style.fillColor() != CommonStrings::None)
- {
- SetColor(style.fillColor(), style.fillShade(), &h, &s, &v, &k);
- PS_setcmykcolor_stroke(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- }
- if (embItem != NULL)
- {
- PS_save();
- PutStream( MatrixToStr(1.0, 0.0, 0.0, -1.0, -pdata.PDx, 0.0) + "\n");
- if (ite->textPathFlipped)
- {
- PutStream("[1 0 0 -1 0 0]\n");
- PutStream("[0 0 0 0 0 0] concatmatrix\n"); //???????
- }
- if (ite->textPathType == 0)
- PutStream( MatrixToStr(tangt.x(), -tangt.y(), -tangt.y(), -tangt.x(), pdata.PtransX, -pdata.PtransY) + "\n");
- else if (ite->textPathType == 1)
- PutStream( MatrixToStr(1.0, 0.0, 0.0, -1.0, pdata.PtransX, -pdata.PtransY) + "\n");
- else if (ite->textPathType == 2)
- {
- double a = 1;
- double b = -1;
- if (tangt.x()< 0)
- {
- a = -1;
- b = 1;
- }
- if (fabs(tangt.x()) > 0.1)
- PutStream( MatrixToStr(a, (tangt.y() / tangt.x()) * b, 0.0, -1.0, pdata.PtransX, -pdata.PtransY) + "\n");
- else
- PutStream( MatrixToStr(a, 4.0, 0.0, -1.0, pdata.PtransX, -pdata.PtransY) + "\n");
- }
- PutStream("[0.0 0.0 0.0 0.0 0.0 0.0] concatmatrix\nconcat\n");
- // PS_translate(0, (tsz / 10.0));
- if (ite->BaseOffs != 0)
- PS_translate(0, -ite->BaseOffs);
- if (style.scaleH() != 1000)
- PS_scale(style.scaleH() / 1000.0, 1);
- QList<PageItem*> emG;
- if (embItem->isGroup())
- emG = embItem->getItemList();
- else
- emG.append(embItem);
- for (int em = 0; em < emG.count(); ++em)
- {
- PageItem* embedded = emG.at(em);
- PS_save();
- PS_translate(embedded->gXpos * (style.scaleH() / 1000.0), ((embedded->gHeight * (style.scaleV() / 1000.0)) - embedded->gYpos * (style.scaleV() / 1000.0)));
- if (style.baselineOffset() != 0)
- PS_translate(0, embedded->gHeight * (style.baselineOffset() / 1000.0));
- if (style.scaleH() != 1000)
- PS_scale(style.scaleH() / 1000.0, 1);
- if (style.scaleV() != 1000)
- PS_scale(1, style.scaleV() / 1000.0);
- ProcessItem(Doc, mPage, embedded, PNr, sep, farb, true, true);
- PS_restore();
- }
- PS_restore();
- continue;
- }
- /* Subset all TTF Fonts until the bug in the TTF-Embedding Code is fixed */
- if (FontSubsetMap.contains(style.font().scName()))
- {
- // uint chr = chstr.unicode();
- uint chr = style.font().char2CMap(chstr);
- if (style.font().canRender(chstr))
- {
- PS_save();
- if (style.fillColor() != CommonStrings::None)
- {
- PutStream( MatrixToStr(1.0, 0.0, 0.0, -1.0, -pdata.PDx, 0.0) + "\n");
- if (ite->textPathFlipped)
- {
- PutStream("[1.0 0.0 0.0 -1.0 0.0 0.0]\n");
- PutStream("[0.0 0.0 0.0 0.0 0.0 0.0] concatmatrix\n");
- }
- if (ite->textPathType == 0)
- PutStream( MatrixToStr(tangt.x(), -tangt.y(), -tangt.y(), -tangt.x(), pdata.PtransX, -pdata.PtransY) + "\n");
- else if (ite->textPathType == 1)
- PutStream( MatrixToStr(1.0, 0.0, 0.0, -1.0, pdata.PtransX, -pdata.PtransY) + "\n");
- else if (ite->textPathType == 2)
- {
- double a = 1;
- double b = -1;
- if (tangt.x() < 0)
- {
- a = -1;
- b = 1;
- }
- if (fabs(tangt.x()) > 0.1)
- PutStream( MatrixToStr(a, (tangt.y() / tangt.x()) * b, 0.0, -1.0, pdata.PtransX, -pdata.PtransY) + "\n");
- else
- PutStream( MatrixToStr(a, 4.0, 0.0, -1.0, pdata.PtransX, -pdata.PtransY) + "\n");
- }
- PutStream("[0.0 0.0 0.0 0.0 0.0 0.0] concatmatrix\nconcat\n");
- PS_translate(0, (tsz / 10.0));
- if (ite->BaseOffs != 0)
- PS_translate(0, -ite->BaseOffs);
- if (glyphs->xoffset !=0 || glyphs->yoffset != 0)
- PS_translate(glyphs->xoffset, -glyphs->yoffset);
- if (style.scaleH() != 1000)
- PS_scale(style.scaleH() / 1000.0, 1);
- if (((style.effects() & ScStyle_Underline) && !SpecialChars::isBreak(chstr)) //FIXME && (chstr != QChar(13)))
- || ((style.effects() & ScStyle_UnderlineWords) && !chstr.isSpace() && !SpecialChars::isBreak(chstr)))
- {
- PS_save();
- PS_translate(0, -(tsz / 10.0));
- double Ulen = glyphs->xadvance;
- double Upos, Uwid;
- if ((style.underlineOffset() != -1) || (style.underlineWidth() != -1))
- {
- if (style.underlineOffset() != -1)
- Upos = (style.underlineOffset() / 1000.0) * (style.font().descent(style.fontSize() / 10.0));
- else
- Upos = style.font().underlinePos(style.fontSize() / 10.0);
- if (style.underlineWidth() != -1)
- Uwid = (style.underlineWidth() / 1000.0) * (style.fontSize() / 10.0);
- else
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- else
- {
- Upos = style.font().underlinePos(style.fontSize() / 10.0);
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- if (style.baselineOffset() != 0)
- Upos += (style.fontSize() / 10.0) * glyphs->scaleV * (style.baselineOffset() / 1000.0);
- if (style.fillColor() != CommonStrings::None)
- {
- SetColor(style.fillColor(), style.fillShade(), &h, &s, &v, &k);
- PS_setcmykcolor_stroke(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- }
- PS_setlinewidth(Uwid);
- if (style.effects() & ScStyle_Subscript)
- {
- PS_moveto(glyphs->xoffset , Upos);
- PS_lineto(glyphs->xoffset+Ulen, Upos);
- }
- else
- {
- PS_moveto(glyphs->xoffset , glyphs->yoffset+Upos);
- PS_lineto(glyphs->xoffset+Ulen, glyphs->yoffset+Upos);
- }
- putColor(style.fillColor(), style.fillShade(), false);
- PS_restore();
- }
- if (chstr != ' ')
- {
- if ((style.effects() & ScStyle_Shadowed) && (style.strokeColor() != CommonStrings::None))
- {
- PS_save();
- PS_translate(style.fontSize() * style.shadowXOffset() / 10000.0, style.fontSize() * style.shadowYOffset() / 10000.0);
- putColorNoDraw(style.strokeColor(), style.strokeShade());
- PS_showSub(chr, FontSubsetMap[style.font().scName()], tsz / 10.0, false);
- PS_restore();
- }
- putColorNoDraw(style.fillColor(), style.fillShade());
- PS_showSub(chr, FontSubsetMap[style.font().scName()], tsz / 10.0, false);
- if ((style.effects() & ScStyle_Outline))
- {
- if ((style.strokeColor() != CommonStrings::None) && ((tsz * style.outlineWidth() / 10000.0) != 0))
- {
- PS_save();
- PS_setlinewidth(tsz * style.outlineWidth() / 10000.0);
- putColorNoDraw(style.strokeColor(), style.strokeShade());
- PS_showSub(chr, FontSubsetMap[style.font().scName()], tsz / 10.0, true);
- PS_restore();
- }
- }
- }
- if ((style.effects() & ScStyle_Strikethrough) && (chstr != SpecialChars::PARSEP))
- {
- PS_save();
- PS_translate(0, -(tsz / 10.0));
- double Ulen = glyphs->xadvance;
- double Upos, Uwid;
- if ((style.strikethruOffset() != -1) || (style.strikethruWidth() != -1))
- {
- if (style.strikethruOffset() != -1)
- Upos = (style.strikethruOffset() / 1000.0) * (style.font().ascent(style.fontSize() / 10.0));
- else
- Upos = style.font().strikeoutPos(style.fontSize() / 10.0);
- if (style.strikethruWidth() != -1)
- Uwid = (style.strikethruWidth() / 1000.0) * (style.fontSize() / 10.0);
- else
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- else
- {
- Upos = style.font().strikeoutPos(style.fontSize() / 10.0);
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- if (style.baselineOffset() != 0)
- Upos += (style.fontSize() / 10.0) * glyphs->scaleV * (style.baselineOffset() / 1000.0);
- if (style.fillColor() != CommonStrings::None)
- {
- SetColor(style.fillColor(), style.fillShade(), &h, &s, &v, &k);
- PS_setcmykcolor_stroke(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- }
- PS_setlinewidth(Uwid);
- PS_moveto(glyphs->xoffset , Upos);
- PS_lineto(glyphs->xoffset+Ulen, Upos);
- putColor(style.fillColor(), style.fillShade(), false);
- PS_restore();
- }
- }
- PS_restore();
- }
- }
- else
- {
- uint glyph = glyphs->glyph;
- PS_selectfont(style.font().replacementName(), tsz / 10.0);
- PS_save();
- PutStream( MatrixToStr(1.0, 0.0, 0.0, -1.0, -pdata.PDx, 0.0) + "\n");
- if (ite->textPathFlipped)
- {
- PutStream("[1.0 0.0 0.0 -1.0 0.0 0.0]\n");
- PutStream("[0.0 0.0 0.0 0.0 0.0 0.0] concatmatrix\n");
- }
- if (ite->textPathType == 0)
- PutStream( MatrixToStr(tangt.x(), -tangt.y(), -tangt.y(), -tangt.x(), pdata.PtransX, -pdata.PtransY) + "\n");
- else if (ite->textPathType == 1)
- PutStream( MatrixToStr(1.0, 0.0, 0.0, -1.0, pdata.PtransX, -pdata.PtransY) + "\n");
- else if (ite->textPathType == 2)
- {
- double a = 1;
- double b = -1;
- if (tangt.x() < 0)
- {
- a = -1;
- b = 1;
- }
- if (fabs(tangt.x()) > 0.1)
- PutStream( MatrixToStr(a, (tangt.y() / tangt.x()) * b, 0.0, -1.0, pdata.PtransX, -pdata.PtransY) + "\n");
- else
- PutStream( MatrixToStr(a, 4.0, 0.0, -1.0, pdata.PtransX, -pdata.PtransY) + "\n");
- }
- PutStream("[0.0 0.0 0.0 0.0 0.0 0.0] concatmatrix\nconcat\n");
- if (ite->BaseOffs != 0)
- PS_translate(0, -ite->BaseOffs);
- if (glyphs->xoffset !=0 || glyphs->yoffset != 0)
- PS_translate(glyphs->xoffset, -glyphs->yoffset);
- if (((style.effects() & ScStyle_Underline) && !SpecialChars::isBreak(chstr)) //FIXME && (chstr != QChar(13)))
- || ((style.effects() & ScStyle_UnderlineWords) && !chstr.isSpace() && !SpecialChars::isBreak(chstr)))
- {
- PS_save();
- double Ulen = glyphs->xadvance;
- double Upos, Uwid;
- if ((style.underlineOffset() != -1) || (style.underlineWidth() != -1))
- {
- if (style.underlineOffset() != -1)
- Upos = (style.underlineOffset() / 1000.0) * (style.font().descent(style.fontSize() / 10.0));
- else
- Upos = style.font().underlinePos(style.fontSize() / 10.0);
- if (style.underlineWidth() != -1)
- Uwid = (style.underlineWidth() / 1000.0) * (style.fontSize() / 10.0);
- else
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- else
- {
- Upos = style.font().underlinePos(style.fontSize() / 10.0);
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- if (style.baselineOffset() != 0)
- Upos += (style.fontSize() / 10.0) * glyphs->scaleV * (style.baselineOffset() / 1000.0);
- if (style.fillColor() != CommonStrings::None)
- {
- SetColor(style.fillColor(), style.fillShade(), &h, &s, &v, &k);
- PS_setcmykcolor_stroke(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- }
- PS_setlinewidth(Uwid);
- if (style.effects() & ScStyle_Subscript)
- {
- PS_moveto(glyphs->xoffset , Upos);
- PS_lineto(glyphs->xoffset+Ulen, Upos);
- }
- else
- {
- PS_moveto(glyphs->xoffset , glyphs->yoffset+Upos);
- PS_lineto(glyphs->xoffset+Ulen, glyphs->yoffset+Upos);
- }
- putColor(style.fillColor(), style.fillShade(), false);
- PS_restore();
- }
- if (chstr != ' ')
- {
- if ((style.effects() & ScStyle_Shadowed) && (style.strokeColor() != CommonStrings::None))
- {
- PS_save();
- PS_translate(style.fontSize() * style.shadowXOffset() / 10000.0, style.fontSize() * style.shadowYOffset() / 10000.0);
- PS_show_xyG(style.font().replacementName(), glyph, 0, 0, style.strokeColor(), style.strokeShade());
- PS_restore();
- }
- PS_show_xyG(style.font().replacementName(), glyph, 0, 0, style.fillColor(), style.fillShade());
- if ((style.effects() & ScStyle_Outline))
- {
- if ((style.strokeColor() != CommonStrings::None) && ((tsz * style.outlineWidth() / 10000.0) != 0))
- {
- uint gl = style.font().char2CMap(chstr);
- FPointArray gly = style.font().glyphOutline(gl);
- QTransform chma;
- chma.scale(tsz / 100.0, tsz / 100.0);
- gly.map(chma);
- PS_save();
- PS_setlinewidth(tsz * style.outlineWidth() / 10000.0);
- PS_translate(0, tsz / 10.0);
- SetColor(style.strokeColor(), style.strokeShade(), &h, &s, &v, &k);
- PS_setcmykcolor_stroke(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- SetClipPath(&gly);
- PS_closepath();
- putColor(style.strokeColor(), style.strokeShade(), false);
- PS_restore();
- }
- }
- }
- if ((style.effects() & ScStyle_Strikethrough) && (chstr != SpecialChars::PARSEP))
- {
- PS_save();
- double Ulen = glyphs->xadvance;
- double Upos, Uwid;
- if ((style.strikethruOffset() != -1) || (style.strikethruWidth() != -1))
- {
- if (style.strikethruOffset() != -1)
- Upos = (style.strikethruOffset() / 1000.0) * (style.font().ascent(style.fontSize() / 10.0));
- else
- Upos = style.font().strikeoutPos(style.fontSize() / 10.0);
- if (style.strikethruWidth() != -1)
- Uwid = (style.strikethruWidth() / 1000.0) * (style.fontSize() / 10.0);
- else
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- else
- {
- Upos = style.font().strikeoutPos(style.fontSize() / 10.0);
- Uwid = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- if (style.baselineOffset() != 0)
- Upos += (style.fontSize() / 10.0) * glyphs->scaleV * (style.baselineOffset() / 1000.0);
- if (style.fillColor() != CommonStrings::None)
- if (style.fillColor() != CommonStrings::None)
- {
- SetColor(style.fillColor(), style.fillShade(), &h, &s, &v, &k);
- PS_setcmykcolor_stroke(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- }
- PS_setlinewidth(Uwid);
- PS_moveto(glyphs->xoffset , Upos);
- PS_lineto(glyphs->xoffset+Ulen, Upos);
- putColor(style.fillColor(), style.fillShade(), false);
- PS_restore();
- }
- PS_restore();
- }
- }
+ setTextSt(Doc, ite, PNr, mPage, sep, farb, true);
PS_restore();
}
if (!success)
@@ -5056,571 +4404,9 @@
*/
void PSLib::setTextSt(ScribusDoc* Doc, PageItem* ite, uint argh, ScPage* pg, bool sep, bool farb, bool master)
{
-// qDebug() << QString("pslib setTextSt: ownPage=%1 pageNr=%2 OnMasterPage=%3;").arg(ite->OwnPage).arg(pg->pageNr()).arg(ite->OnMasterPage);
- int tabCc = 0;
- int savedOwnPage = ite->OwnPage;
- double tabDist = ite->textToFrameDistLeft();
- QList<ParagraphStyle::TabRecord> tTabValues;
-
- ite->OwnPage = argh;
- ite->layout();
- ite->OwnPage = savedOwnPage;
- if (ite->lineColor() != CommonStrings::None)
- tabDist += ite->lineWidth() / 2.0;
-
- uint llp = 0;
- while (llp < ite->textLayout.lines())
- {
- LineSpec ls = ite->textLayout.line(llp++);
- const ParagraphStyle& LineStyle = ite->itemText.paragraphStyle(ls.firstItem);
- if (LineStyle.backgroundColor() != CommonStrings::None)
- {
- double y0 = ls.y;
- double y2 = ls.y;
- double ascent = ls.ascent;
- double descent = ls.descent;
- double rMarg = LineStyle.rightMargin();
- double lMarg = ls.colLeft;
- double adjX = 0;
- if (LineStyle.firstIndent() <= 0)
- adjX += LineStyle.leftMargin() + LineStyle.firstIndent();
- while (llp < ite->textLayout.lines())
- {
- ls = ite->textLayout.line(llp);
- if ((ls.colLeft > lMarg) || (ite->itemText.paragraphStyle(ls.firstItem) != LineStyle))
- {
- if (y2 == 0)
- y2 = y0;
- break;
- }
- if (ite->itemText.text(ls.lastItem) == SpecialChars::PARSEP)
- {
- y2 = ls.y;
- descent = ls.descent;
- if ((llp + 1) < ite->textLayout.lines())
- {
- if ((ite->textLayout.line(llp + 1).lastItem - ite->textLayout.line(llp + 1).firstItem) > 0)
- descent += LineStyle.lineSpacing() - (ls.descent + ite->textLayout.line(llp + 1).ascent);
- }
- llp++;
- break;
- }
- y2 = ls.y;
- descent = ls.descent;
- if ((llp + 1) < ite->textLayout.lines())
- descent += LineStyle.lineSpacing() - (ls.descent + ite->textLayout.line(llp + 1).ascent);
- llp++;
- }
- QRectF scr(lMarg + adjX, y0 - ascent, ite->asTextFrame()->columnWidth() - adjX - rMarg, y2 - y0 + descent + ascent);
- PS_save();
- SetPathAndClip(ite->PoLine, true);
- int h, s, v, k;
- SetColor(LineStyle.backgroundColor(), LineStyle.backgroundShade(), &h, &s, &v, &k);
- PS_setcmykcolor_fill(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- PS_moveto(scr.x(), -scr.y());
- PS_lineto(scr.x() + scr.width(), -scr.y());
- PS_lineto(scr.x() + scr.width(), -scr.y() - scr.height());
- PS_lineto(scr.x(), -scr.y() - scr.height());
- PS_closepath();
- putColor(LineStyle.backgroundColor(), LineStyle.backgroundShade(), true);
- PS_restore();
- }
- }
-
- for (uint ll=0; ll < ite->textLayout.lines(); ++ll)
- {
- LineSpec ls = ite->textLayout.line(ll);
- tabDist = ls.x;
- double CurX = ls.x;
- double CurXB = ls.x;
- QRectF scrG;
- QString oldBack = "";
- double oldShade = 100;
- int last = qMin(ls.lastItem, ite->itemText.length() - 1);
- for (int a = ls.firstItem; a <= last; ++a)
- {
- const GlyphLayout* glyphs(ite->itemText.getGlyphs(a));
- const CharStyle& charStyle(ite->itemText.charStyle(a));
- if (charStyle.backColor() != CommonStrings::None)
- {
- // This code is for rendering character background color.
- int h, s, v, k;
- SetColor(charStyle.backColor(), charStyle.backShade(), &h, &s, &v, &k);
- PS_setcmykcolor_fill(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- const ParagraphStyle& LineStyle = ite->itemText.paragraphStyle(ls.firstItem);
- double y1 = ls.y;
- double hl = ls.height;
- if (LineStyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- hl = Doc->guidesPrefs().valueBaselineGrid;
- else if (LineStyle.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
- hl = LineStyle.lineSpacing();
- if (ls.isFirstLine)
- {
- if (ite->textLayout.lines() == 1)
- hl = ls.ascent + ls.descent;
- if (LineStyle.hasDropCap() && (a == ls.firstItem))
- hl *= LineStyle.dropCapLines();
- if (LineStyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- y1 -= LineStyle.lineSpacing();
- else if (ite->firstLineOffset() == FLOPRealGlyphHeight || ite->firstLineOffset() == FLOPFontAscent)
- y1 -= ls.ascent;
- else
- y1 -= LineStyle.lineSpacing();
- }
- else
- y1 -= ls.ascent + (hl - (ls.ascent + ls.descent)) / 2.0;
- QRectF scr;
- if (ite->itemText.hasObject(a))
- {
- PageItem* obj = ite->itemText.object(a);
- double ww = (obj->width() + obj->lineWidth()) * glyphs->scaleH;
- double hh = (obj->height() + obj->lineWidth()) * glyphs->scaleV;
- scr = QRectF(CurXB, ls.y - hh, ww , hh);
- }
- else
- scr = QRectF(CurXB, y1, glyphs->wide(), hl);
- if ((oldBack == "") || ((oldBack == charStyle.backColor()) && (oldShade == charStyle.backShade())))
- scrG |= scr;
- else if ((oldBack != charStyle.backColor()) || (oldShade != charStyle.backShade()))
- {
- PS_save();
- PS_moveto(scrG.x(), -scrG.y());
- PS_lineto(scrG.x() + scrG.width(), -scrG.y());
- PS_lineto(scrG.x() + scrG.width(), -scrG.y() - scrG.height());
- PS_lineto(scrG.x(), -scrG.y() - scrG.height());
- PS_closepath();
- SetColor(oldBack, oldShade, &h, &s, &v, &k);
- PS_setcmykcolor_fill(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- putColor(oldBack, oldShade, true);
- PS_restore();
- scrG = scr;
- }
- oldBack = charStyle.backColor();
- oldShade = charStyle.backShade();
- }
- else
- {
- if (!scrG.isNull())
- {
- PS_save();
- PS_moveto(scrG.x(), -scrG.y());
- PS_lineto(scrG.x() + scrG.width(), -scrG.y());
- PS_lineto(scrG.x() + scrG.width(), -scrG.y() - scrG.height());
- PS_lineto(scrG.x(), -scrG.y() - scrG.height());
- PS_closepath();
- putColor(oldBack, oldShade, true);
- PS_restore();
- }
- oldBack = "";
- oldShade = 100;
- scrG = QRectF();
- }
- CurXB += glyphs->wide();
- }
- if (!scrG.isNull())
- {
- PS_save();
- PS_moveto(scrG.x(), -scrG.y());
- PS_lineto(scrG.x() + scrG.width(), -scrG.y());
- PS_lineto(scrG.x() + scrG.width(), -scrG.y() - scrG.height());
- PS_lineto(scrG.x(), -scrG.y() - scrG.height());
- PS_closepath();
- putColor(oldBack, oldShade, true);
- PS_restore();
- }
-
- for (int d = ls.firstItem; d <= ls.lastItem; ++d)
- {
- //ScText *hl = ite->itemText.item_p(d);
- QChar chr = ite->itemText.text(d);
- const CharStyle & cstyle(ite->itemText.charStyle(d));
- const ParagraphStyle& pstyle(ite->itemText.paragraphStyle(d));
- const GlyphLayout* glyphs(ite->itemText.getGlyphs(d));
- LayoutFlags flags = ite->itemText.flags(d);
-
-// if ((hl->ch == QChar(13)) || (hl->ch == QChar(10)) || (hl->ch == QChar(28)) || (hl->ch == QChar(27)) || (hl->ch == QChar(26)))
-// continue;
- if (flags & ScLayout_SuppressSpace)
- continue;
- tTabValues = pstyle.tabValues();
- if (flags & ScLayout_StartOfLine)
- tabCc = 0;
- if ((chr == SpecialChars::TAB) && (tTabValues.count() != 0))
- {
- QChar tabFillChar;
- const TabLayout* tabLayout = dynamic_cast<const TabLayout*>(glyphs->more);
- if (tabLayout)
- tabFillChar = tabLayout->fillChar;
- if (!tabFillChar.isNull())
- {
- //ScText hl2;
- //static_cast<CharStyle&>(hl2) = static_cast<const CharStyle&>(*hl);
- const GlyphLayout * const gl = glyphs->more;
- double scale = gl ? gl->scaleV : 1.0;
- double wt = cstyle.font().charWidth(tabFillChar, cstyle.fontSize() * scale / 10.0);
- double len = glyphs->xadvance;
- int coun = static_cast<int>(len / wt);
- // JG - #6728 : update code according to fillInTabLeaders() and PageItem::layout()
- double sPos = 0.0 /*CurX - len + cstyle.fontSize() / 10.0 * 0.7 + 1*/;
- //hl2.ch = tabFillChar;
- //hl2.setTracking(0);
- //hl2.setScaleH(1000);
- //hl2.setScaleV(1000);
- //hl2.glyph.glyph = cstyle.font().char2CMap(tabFillChar);
- //hl2.glyph.yoffset = glyphs->yoffset;
-
- GlyphLayout gl2 = *gl;
- gl2.glyph = cstyle.font().char2CMap(tabFillChar);
- gl2.yoffset = glyphs->yoffset;
-
- CharStyle shadow(cstyle);
- shadow.setFillColor(cstyle.strokeColor());
-
- for (int cx = 0; cx < coun; ++cx)
- {
- gl2.xoffset = sPos + wt * cx;
- if ((cstyle.effects() & ScStyle_Shadowed) && (cstyle.strokeColor() != CommonStrings::None))
- {
- //ScText hl3;
- //static_cast<CharStyle&>(hl3) = static_cast<const CharStyle&>(hl2);
- //hl3.ch = hl2.ch;
- //hl3.glyph.glyph = hl2.glyph.glyph;
- //hl3.setFillColor(hl2.strokeColor());
- //hl3.glyph.yoffset = hl2.glyph.yoffset - (hl2.fontSize() * hl2.shadowYOffset() / 10000.0);
- //hl3.glyph.xoffset = hl2.glyph.xoffset + (hl2.fontSize() * hl2.shadowXOffset() / 10000.0);
- GlyphLayout gl3 = gl2;
- gl3.yoffset = gl2.yoffset - (cstyle.fontSize() * cstyle.shadowYOffset() / 10000.0);
- gl3.xoffset = gl2.xoffset + (cstyle.fontSize() * cstyle.shadowXOffset() / 10000.0);
- setTextCh(Doc, ite, CurX, ls.y, argh, d, tabFillChar, &gl3, shadow, pstyle, pg, sep, farb, master);
- }
- setTextCh(Doc, ite, CurX, ls.y, argh, d, tabFillChar, &gl2, cstyle, pstyle, pg, sep, farb, master);
- }
- }
- tabCc++;
- }
- if (chr == SpecialChars::TAB) {
- CurX += glyphs->wide();
- continue;
- }
- if ((cstyle.effects() & ScStyle_Shadowed) && (cstyle.strokeColor() != CommonStrings::None))
- {
- const GlyphLayout *gl1 = glyphs;
- GlyphLayout* gl2 = new GlyphLayout(*gl1);
- GlyphLayout* gl3 = gl2;
- while (gl1->more)
- {
- gl2->more = new GlyphLayout(*gl1->more);
- gl2->more->yoffset -= (cstyle.fontSize() * cstyle.shadowYOffset() / 10000.0);
- gl2->more->xoffset += (cstyle.fontSize() * cstyle.shadowXOffset() / 10000.0);
- gl2->more->more = NULL;
- gl1 = gl1->more;
- gl2 = gl2->more;
- }
- CharStyle shadowed(cstyle);
- shadowed.setFillColor(cstyle.strokeColor());
- shadowed.setFillShade(cstyle.strokeShade());
- gl2->xadvance = glyphs->xadvance;
- gl2->yadvance = glyphs->yadvance;
- gl2->yoffset = glyphs->yoffset - (cstyle.fontSize() * cstyle.shadowYOffset() / 10000.0);
- gl2->xoffset = glyphs->xoffset + (cstyle.fontSize() * cstyle.shadowXOffset() / 10000.0);
- gl2->scaleH = glyphs->scaleH;
- gl2->scaleV = glyphs->scaleV;
-
- setTextCh(Doc, ite, CurX, ls.y, argh, d, chr, gl2, shadowed, pstyle, pg, sep, farb, master);
-
- while (gl3->more) {
- GlyphLayout* more = gl3->more;
- gl3->more = gl3->more->more;
- delete more;
- }
- delete gl3;
- }
- setTextCh(Doc, ite, CurX, ls.y, argh, d, chr, glyphs, cstyle, pstyle, pg, sep, farb, master);
- // Unneeded now that glyph xadvance is set appropriately for inline objects by PageItem_TextFrame::layout() - JG
- /*if (hl->ch == SpecialChars::OBJECT)
- {
- InlineFrame& embedded(const_cast<InlineFrame&>(hl->embedded));
- CurX += (embedded.getItem()->gWidth + embedded.getItem()->lineWidth()) * glyphs->scaleH;
- }
- else*/
- CurX += glyphs->wide();
- tabDist = CurX;
- }
- }
-}
-
-void PSLib::setTextCh(ScribusDoc* Doc, PageItem* ite, double x, double y, uint argh, uint doh, QChar chstr, const GlyphLayout* glyphs, const CharStyle& cstyle, const ParagraphStyle& pstyle, ScPage* pg, bool sep, bool farb, bool master)
-{
- //QChar chstr = hl->ch;
- //const CharStyle & cstyle(*hl);
- //const GlyphLayout* glyphs(&(hl->glyph));
- uint glyph = glyphs->glyph;
-
- int h, s, v, k;
- double tsz;
- double wideR = 0.0;
- QVector<double> dum;
- dum.clear();
-
- tsz = cstyle.fontSize();
-
-/* if (cstyle.effects() & ScStyle_DropCap)
- {
-// QString chstr; // dummy, FIXME: replace by glyph
- if (pstyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- tsz = qRound(10 * ((Doc->typographicSettings.valueBaseGrid * (pstyle.dropCapLines()-1)+(cstyle.font().ascent(pstyle.charStyle().fontSize() / 10.0))) / (cstyle.font().realCharHeight(chstr, 10))));
- else
- {
- if (pstyle.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
- tsz = qRound(10 * ((pstyle.lineSpacing() * (pstyle.dropCapLines()-1)+(cstyle.font().ascent(pstyle.charStyle().fontSize() / 10.0))) / (cstyle.font().realCharHeight(chstr, 10))));
- else
- {
- double currasce = cstyle.font().height(pstyle.charStyle().fontSize());
- tsz = qRound(10 * ((currasce * (pstyle.dropCapLines()-1)+(cstyle.font().ascent(pstyle.charStyle().fontSize() / 10.0))) / cstyle.font().realCharHeight(chstr, 10)));
- }
- }
- }
- */
- if (ite->itemText.hasObject(doh-1))
- {
- PageItem* embedded = ite->itemText.object(doh-1);
- PS_save();
- PS_translate(x + glyphs->xoffset + embedded->gXpos * (cstyle.scaleH() / 1000.0), (y + glyphs->yoffset - (embedded->gHeight * (cstyle.scaleV() / 1000.0)) + embedded->gYpos * (cstyle.scaleV() / 1000.0)) * -1);
- if (doh == 0 || ite->itemText.text(doh-1) == SpecialChars::PARSEP)
- {
- if ((cstyle.baselineOffset() != 0) && (!pstyle.hasDropCap()))
- PS_translate(0, embedded->gHeight * (cstyle.baselineOffset() / 1000.0));
- }
- else
- {
- if (cstyle.baselineOffset() != 0)
- PS_translate(0, embedded->gHeight * (cstyle.baselineOffset() / 1000.0));
- }
- if (cstyle.scaleH() != 1000)
- PS_scale(cstyle.scaleH() / 1000.0, 1);
- if (cstyle.scaleV() != 1000)
- PS_scale(1, cstyle.scaleV() / 1000.0);
- ProcessItem(Doc, pg, embedded, argh, sep, farb, master, true);
- PS_restore();
- return;
- }
-
- if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBSPACE.unicode()) ||
- glyph == (ScFace::CONTROL_GLYPHS + 32))
- {
- glyph = cstyle.font().char2CMap(QChar(' '));
- chstr = ' ';
- }
- else if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBHYPHEN.unicode()))
- {
- glyph = cstyle.font().char2CMap(QChar('-'));
- chstr = '-';
- }
-
- if (glyph < ScFace::CONTROL_GLYPHS)
- {
- if (((cstyle.effects() & ScStyle_Underline) && !SpecialChars::isBreak(chstr)) //FIXME && (chstr != QChar(13)))
- || ((cstyle.effects() & ScStyle_UnderlineWords) && !chstr.isSpace() && !SpecialChars::isBreak(chstr)))
- {
- // double Ulen = cstyle.font().glyphWidth(glyph, cstyle.fontSize()) * glyphs->scaleH;
- double Ulen = glyphs->xadvance;
- double Upos, lw;
- if ((cstyle.underlineOffset() != -1) || (cstyle.underlineWidth() != -1))
- {
- if (cstyle.underlineOffset() != -1)
- Upos = (cstyle.underlineOffset() / 1000.0) * (cstyle.font().descent(cstyle.fontSize() / 10.0));
- else
- Upos = cstyle.font().underlinePos(cstyle.fontSize() / 10.0);
- if (cstyle.underlineWidth() != -1)
- lw = (cstyle.underlineWidth() / 1000.0) * (cstyle.fontSize() / 10.0);
- else
- lw = qMax(cstyle.font().strokeWidth(cstyle.fontSize() / 10.0), 1.0);
- }
- else
- {
- Upos = cstyle.font().underlinePos(cstyle.fontSize() / 10.0);
- lw = qMax(cstyle.font().strokeWidth(cstyle.fontSize() / 10.0), 1.0);
- }
- if (cstyle.baselineOffset() != 0)
- Upos += (cstyle.fontSize() / 10.0) * glyphs->scaleV * (cstyle.baselineOffset() / 1000.0);
- if (cstyle.fillColor() != CommonStrings::None)
- {
- PS_setcapjoin(Qt::FlatCap, Qt::MiterJoin);
- PS_setdash(Qt::SolidLine, 0, dum);
- SetColor(cstyle.fillColor(), cstyle.fillShade(), &h, &s, &v, &k);
- PS_setcmykcolor_stroke(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- }
- PS_setlinewidth(lw);
- if (cstyle.effects() & ScStyle_Subscript)
- {
- PS_moveto(x + glyphs->xoffset , -y - glyphs->yoffset+Upos);
- PS_lineto(x + glyphs->xoffset+Ulen, -y - glyphs->yoffset+Upos);
- }
- else
- {
- PS_moveto(x + glyphs->xoffset , -y + Upos);
- PS_lineto(x + glyphs->xoffset+Ulen, -y + Upos);
- }
- putColor(cstyle.fillColor(), cstyle.fillShade(), false);
- }
- /* Subset all TTF Fonts until the bug in the TTF-Embedding Code is fixed */
- if (FontSubsetMap.contains(cstyle.font().scName()))
- {
- if (glyph != 0 && glyph != cstyle.font().char2CMap(QChar(' ')) && (!SpecialChars::isBreak(chstr)))
- {
- PS_save();
- if (ite->reversed())
- {
- PS_translate(x + glyphs->xoffset, (y + glyphs->yoffset - (tsz / 10.0)) * -1);
- PS_scale(-1, 1);
- PS_translate(-glyphs->xadvance, 0);
- }
- else
- PS_translate(x + glyphs->xoffset, (y + glyphs->yoffset - (cstyle.fontSize() / 10.0)) * -1);
- if (cstyle.baselineOffset() != 0)
- PS_translate(0, (cstyle.fontSize() / 10.0) * (cstyle.baselineOffset() / 1000.0));
- if (glyphs->scaleH != 1.0)
- PS_scale(glyphs->scaleH, 1);
- if (glyphs->scaleV != 1.0)
- {
- PS_translate(0, -((tsz / 10.0) - (tsz / 10.0) * (glyphs->scaleV)));
- PS_scale(1, glyphs->scaleV);
- }
- if (cstyle.fillColor() != CommonStrings::None)
- {
- putColorNoDraw(cstyle.fillColor(), cstyle.fillShade());
- PS_showSub(glyph, FontSubsetMap[cstyle.font().scName()], tsz / 10.0, false);
- }
- PS_restore();
- }
- }
- else if (glyph != 0)
- {
- PS_selectfont(cstyle.font().replacementName(), tsz / 10.0);
- PS_save();
- PS_translate(x + glyphs->xoffset, -y - glyphs->yoffset);
- if (ite->reversed())
- {
- PS_scale(-1, 1);
- PS_translate(glyphs->xadvance, 0);
- }
- if (cstyle.baselineOffset() != 0)
- PS_translate(0, (cstyle.fontSize() / 10.0) * (cstyle.baselineOffset() / 1000.0));
- if (glyphs->scaleH != 1.0 || glyphs->scaleV != 1.0)
- PS_scale(glyphs->scaleH, glyphs->scaleV);
- if (cstyle.fillColor() != CommonStrings::None)
- {
- PS_show_xyG(cstyle.font().replacementName(), glyph, 0, 0, cstyle.fillColor(), cstyle.fillShade());
- }
- PS_restore();
- }
- if ((cstyle.effects() & ScStyle_Outline) || glyph == 0)//&& (chstr != QChar(13)))
- {
-// if (cstyle.font().canRender(chstr))
- {
- FPointArray gly = cstyle.font().glyphOutline(glyph);
- QTransform chma, chma2, chma3;
- chma.scale(tsz / 100.0, tsz / 100.0);
- chma2.scale(glyphs->scaleH, glyphs->scaleV);
- if (cstyle.baselineOffset() != 0)
- chma3.translate(0, -(cstyle.fontSize() / 10.0) * (cstyle.baselineOffset() / 1000.0));
- gly.map(chma * chma2 * chma3);
- if (ite->reversed())
- {
- chma = QTransform();
- chma.scale(-1, 1);
- chma.translate(wideR, 0);
- gly.map(chma);
- }
- if ((cstyle.strokeColor() != CommonStrings::None) && ((tsz * cstyle.outlineWidth() / 10000.0) != 0))
- {
- PS_save();
- PS_setlinewidth(tsz * cstyle.outlineWidth() / 10000.0);
- PS_setcapjoin(Qt::FlatCap, Qt::MiterJoin);
- PS_setdash(Qt::SolidLine, 0, dum);
- PS_translate(x + glyphs->xoffset, (y + glyphs->yoffset - (tsz / 10.0)) * -1);
- PS_translate(0, -((tsz / 10.0) - (tsz / 10.0) * glyphs->scaleV));
- SetColor(cstyle.strokeColor(), cstyle.strokeShade(), &h, &s, &v, &k);
- PS_setcmykcolor_stroke(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- SetClipPath(&gly);
- PS_closepath();
- putColor(cstyle.strokeColor(), cstyle.strokeShade(), false);
- PS_restore();
- }
- }
- }
- if ((cstyle.effects() & ScStyle_Strikethrough))//&& (chstr != QChar(13)))
- {
- // double Ulen = cstyle.font().glyphWidth(glyph, cstyle.fontSize()) * glyphs->scaleH;
- double Ulen = glyphs->xadvance;
- double Upos, lw;
- if ((cstyle.strikethruOffset() != -1) || (cstyle.strikethruWidth() != -1))
- {
- if (cstyle.strikethruOffset() != -1)
- Upos = (cstyle.strikethruOffset() / 1000.0) * (cstyle.font().ascent(cstyle.fontSize() / 10.0));
- else
- Upos = cstyle.font().strikeoutPos(cstyle.fontSize() / 10.0);
- if (cstyle.strikethruWidth() != -1)
- lw = (cstyle.strikethruWidth() / 1000.0) * (cstyle.fontSize() / 10.0);
- else
- lw = qMax(cstyle.font().strokeWidth(cstyle.fontSize() / 10.0), 1.0);
- }
- else
- {
- Upos = cstyle.font().strikeoutPos(cstyle.fontSize() / 10.0);
- lw = qMax(cstyle.font().strokeWidth(cstyle.fontSize() / 10.0), 1.0);
- }
- if (cstyle.baselineOffset() != 0)
- Upos += (cstyle.fontSize() / 10.0) * glyphs->scaleV * (cstyle.baselineOffset() / 1000.0);
- if (cstyle.fillColor() != CommonStrings::None)
- {
- PS_setcapjoin(Qt::FlatCap, Qt::MiterJoin);
- PS_setdash(Qt::SolidLine, 0, dum);
- SetColor(cstyle.fillColor(), cstyle.fillShade(), &h, &s, &v, &k);
- PS_setcmykcolor_stroke(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- }
- PS_setlinewidth(lw);
- PS_moveto(x + glyphs->xoffset , -y-glyphs->yoffset+Upos);
- PS_lineto(x + glyphs->xoffset+Ulen, -y-glyphs->yoffset+Upos);
- putColor(cstyle.fillColor(), cstyle.fillShade(), false);
- }
- }
- if (glyphs->more) {
- //// ugly hack until setTextCh interface is changed
- //ScText hl2(*hl);
- //hl2.glyph = *glyphs->more;
- setTextCh(Doc, ite, x + glyphs->xadvance, y, argh, doh, chstr, glyphs->more, cstyle, pstyle, pg, sep, farb, master);
- //// don't let hl2's destructor delete these!
- //hl2.glyph.more = 0;
- }
-/* if (cstyle.effects() & ScStyle_SoftHyphenVisible)
- {
- int chs = cstyle.fontSize();
-// double wide = cstyle.font().charWidth(chstr, chs) * (cstyle.scaleH() / 1000.0);
-// chstr = '-';
-// if (cstyle.font().canRender(chstr))
- {
- FPointArray gly = cstyle.font().glyphOutline(glyph);
- QTransform chma;
- chma.scale(tsz / 100.0, tsz / 100.0);
- gly.map(chma);
- chma = QTransform();
- chma.scale(glyphs->scaleH, glyphs->scaleV);
- gly.map(chma);
- if (cstyle.fillColor() != CommonStrings::None)
- {
- PS_save();
- PS_newpath();
- PS_translate(x + glyphs->xoffset + glyphs->xadvance, (y + glyphs->yoffset - (tsz / 10.0)) * -1);
- SetColor(cstyle.fillColor(), cstyle.fillShade(), &h, &s, &v, &k);
- PS_setcmykcolor_fill(h / 255.0, s / 255.0, v / 255.0, k / 255.0);
- SetClipPath(&gly);
- PS_closepath();
- putColor(cstyle.fillColor(), cstyle.fillShade(), true);
- PS_restore();
- }
- }
- }*/
+ PSPainter p(Doc, argh, pg, sep, farb, master, this);
+ ite->textLayout.renderBackground(&p);
+ ite->textLayout.render(&p);
}
void PSLib::putColor(const QString& colorName, double shade, bool fill)
Modified: trunk/Scribus/scribus/pslib.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/pslib.h
==============================================================================
--- trunk/Scribus/scribus/pslib.h (original)
+++ trunk/Scribus/scribus/pslib.h Wed Mar 23 20:21:36 2016
@@ -45,6 +45,7 @@
class MultiProgressDialog;
class ScImage;
class ScLayer;
+class PSPainter;
/**
*@author Franz Schmid
@@ -54,6 +55,9 @@
class SCRIBUS_API PSLib : public QObject
{
Q_OBJECT
+
+ friend class PSPainter;
+
public:
typedef enum
@@ -140,7 +144,6 @@
virtual void SetColor(const QString& color, double shade, int *h, int *s, int *v, int *k);
virtual void SetColor(const ScColor& color, double shade, int *h, int *s, int *v, int *k);
virtual void setTextSt(ScribusDoc* Doc, PageItem* ite, uint a, ScPage* pg, bool sep, bool farb, bool master);
- virtual void setTextCh(ScribusDoc* Doc, PageItem* ite, double x, double y, uint a, uint d, QChar chstr, const GlyphLayout* glyphs, const CharStyle& cstyle, const ParagraphStyle& pstyle, ScPage* pg, bool sep, bool farb, bool master);
bool psExport;
private:
Modified: trunk/Scribus/scribus/scpageoutput.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/scpageoutput.cpp
==============================================================================
--- trunk/Scribus/scribus/scpageoutput.cpp (original)
+++ trunk/Scribus/scribus/scpageoutput.cpp Wed Mar 23 20:21:36 2016
@@ -10,7 +10,7 @@
#include <QPointF>
#include <QRectF>
#include <QStack>
-
+#include <pageitem_textframe.h>
#include "cmsettings.h"
#include "collapsedtablepainterex.h"
#include "commonstrings.h"
@@ -31,11 +31,13 @@
#include "scimage.h"
#include "scpage.h"
#include "scpattern.h"
+#include "text/textlayoutpainter.h"
#include "scribusdoc.h"
#include "util.h"
#include "util_formats.h"
#include "util_math.h"
+#include "text/boxes.h"
MarksOptions::MarksOptions(void)
@@ -506,167 +508,6 @@
painter->restore();
}
-void ScPageOutput::drawGlyphs(PageItem* item, ScPainterExBase *painter, const CharStyle& style, GlyphLayout& glyphs, QRect clip)
-{
- uint glyph = glyphs.glyph;
- if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBSPACE.unicode())) // NBSPACE
- glyph = style.font().char2CMap(QChar(' '));
- else if (glyph == (ScFace::CONTROL_GLYPHS + SpecialChars::NBHYPHEN.unicode())) // NBHYPHEN
- glyph = style.font().char2CMap(QChar('-'));
-
- if (glyph >= ScFace::CONTROL_GLYPHS)
- {
- if (glyphs.more)
- {
- painter->translate(glyphs.xadvance, 0);
- drawGlyphs(item, painter, style, *glyphs.more, clip);
- }
- return;
- }
-
- //if (style.font().canRender(QChar(glyph)))
- {
- QTransform chma, chma2, chma3, chma4, chma5, chma6;
- chma.scale(glyphs.scaleH * style.fontSize() / 100.00, glyphs.scaleV * style.fontSize() / 100.0);
- FPointArray gly = style.font().glyphOutline(glyph);
- // Do underlining first so you can get typographically correct
- // underlines when drawing a white outline
- if ((style.effects() & ScStyle_Underline) || ((style.effects() & ScStyle_UnderlineWords) && (glyph != style.font().char2CMap(QChar(' ')))))
- {
- double st, lw;
- if ((style.underlineOffset() != -1) || (style.underlineWidth() != -1))
- {
- if (style.underlineOffset() != -1)
- st = (style.underlineOffset() / 1000.0) * (style.font().descent(style.fontSize() / 10.0));
- else
- st = style.font().underlinePos(style.fontSize() / 10.0);
- if (style.underlineWidth() != -1)
- lw = (style.underlineWidth() / 1000.0) * (style.fontSize() / 10.0);
- else
- lw = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- else
- {
- st = style.font().underlinePos(style.fontSize() / 10.0);
- lw = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- if (style.baselineOffset() != 0)
- st += (style.fontSize() / 10.0) * glyphs.scaleV * (style.baselineOffset() / 1000.0);
- ScColorShade tmpPen = painter->pen();
- int tmpStrokeMode = painter->strokeMode();
- painter->setPen(painter->brush());
- painter->setLineWidth(lw);
- painter->setStrokeMode(1);
- if (style.effects() & ScStyle_Subscript)
- painter->drawLine(FPoint(glyphs.xoffset, glyphs.yoffset - st), FPoint(glyphs.xoffset + glyphs.xadvance, glyphs.yoffset - st));
- else
- painter->drawLine(FPoint(glyphs.xoffset, -st), FPoint(glyphs.xoffset + glyphs.xadvance, -st));
- painter->setStrokeMode(tmpStrokeMode);
- painter->setPen(tmpPen);
- }
- if (gly.size() > 3)
- {
- painter->save();
- painter->translate(glyphs.xoffset, glyphs.yoffset - ((style.fontSize() / 10.0) * glyphs.scaleV));
- if (item->reversed())
- {
- painter->scale(-1, 1);
- painter->translate(-glyphs.xadvance, 0);
- }
- if (style.baselineOffset() != 0)
- painter->translate(0, -(style.fontSize() / 10.0) * (style.baselineOffset() / 1000.0));
- double glxSc = glyphs.scaleH * style.fontSize() / 100.00;
- double glySc = glyphs.scaleV * style.fontSize() / 100.0;
- painter->scale(glxSc, glySc);
- painter->setFillMode(ScPainterExBase::Solid);
- bool fr = painter->fillRule();
- painter->setFillRule(false);
- painter->setupPolygon(&gly, true);
- if (glyph == 0)
- {
- ScColorShade tmp(PrefsManager::instance()->appPrefs.displayPrefs.controlCharColor, 100);
- painter->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
- painter->setLineWidth(style.fontSize() * glyphs.scaleV * style.outlineWidth() * 2 / 10000.0);
- painter->strokePath();
- }
- else if ((style.font().isStroked()) && ((style.fontSize() * glyphs.scaleV * style.outlineWidth() / 10000.0) != 0))
- {
- ScColorShade tmp = painter->brush();
- painter->setStrokeMode(1);
- painter->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
- painter->setLineWidth(style.fontSize() * glyphs.scaleV * style.outlineWidth() / 10000.0);
- painter->strokePath();
- }
- else
- {
- if ((style.effects() & ScStyle_Shadowed) && (style.strokeColor() != CommonStrings::None))
- {
- painter->save();
- painter->translate((style.fontSize() * glyphs.scaleH * style.shadowXOffset() / 10000.0) / glxSc, -(style.fontSize() * glyphs.scaleV * style.shadowYOffset() / 10000.0) / glySc);
- ScColorShade tmp = painter->brush();
- painter->setBrush(painter->pen());
- painter->setupPolygon(&gly, true);
- fillPath(item, painter, clip);
- painter->setBrush(tmp);
- painter->restore();
- painter->setupPolygon(&gly, true);
- }
- if (style.fillColor() != CommonStrings::None)
- fillPath(item, painter, clip);
- if ((style.effects() & ScStyle_Outline) && (style.strokeColor() != CommonStrings::None) && ((style.fontSize() * glyphs.scaleV * style.outlineWidth() / 10000.0) != 0))
- {
- painter->setStrokeMode(1);
- painter->setLineWidth((style.fontSize() * glyphs.scaleV * style.outlineWidth() / 10000.0) / glySc);
- painter->strokePath();
- }
- }
- painter->setFillRule(fr);
- painter->restore();
- }
- if (style.effects() & ScStyle_Strikethrough)
- {
- double st, lw;
- if ((style.strikethruOffset() != -1) || (style.strikethruWidth() != -1))
- {
- if (style.strikethruOffset() != -1)
- st = (style.strikethruOffset() / 1000.0) * (style.font().ascent(style.fontSize() / 10.0));
- else
- st = style.font().strikeoutPos(style.fontSize() / 10.0);
- if (style.strikethruWidth() != -1)
- lw = (style.strikethruWidth() / 1000.0) * (style.fontSize() / 10.0);
- else
- lw = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- else
- {
- st = style.font().strikeoutPos(style.fontSize() / 10.0);
- lw = qMax(style.font().strokeWidth(style.fontSize() / 10.0), 1.0);
- }
- if (style.baselineOffset() != 0)
- st += (style.fontSize() / 10.0) * glyphs.scaleV * (style.baselineOffset() / 1000.0);
- int tmpStrokeMode = painter->strokeMode();
- painter->setPen(painter->brush());
- painter->setLineWidth(lw);
- painter->setStrokeMode(1);
- painter->drawLine(FPoint(glyphs.xoffset, glyphs.yoffset - st), FPoint(glyphs.xoffset + glyphs.xadvance, glyphs.yoffset - st));
- painter->setStrokeMode(tmpStrokeMode);
- }
- }
- /*else
- {
- painter->setLineWidth(1);
- painter->setPen(ScColorShade(Qt::red, 100));
- painter->setBrush(ScColorShade(Qt::red, 100));
- painter->setFillMode(1);
- painter->drawRect(glyphs.xoffset, glyphs.yoffset - (style.fontSize() / 10.0) * glyphs.scaleV , (style.fontSize() / 10.0) * glyphs.scaleH, (style.fontSize() / 10.0) * glyphs.scaleV);
- }*/
- if (glyphs.more)
- {
- painter->translate(glyphs.xadvance, 0);
- drawGlyphs(item, painter, style, *glyphs.more, clip);
- }
-}
-
void ScPageOutput::drawItem_Embedded( PageItem* item, ScPainterExBase *p, QRect clip, const CharStyle& style, PageItem* cembedded)
{
if (!cembedded)
@@ -1080,185 +921,185 @@
}
}
+class ScpageoutputPainter: public TextLayoutPainter
+{
+private:
+ PageItem* m_item;
+ ScPainterExBase* m_painter;
+ ScPageOutput* m_scpage;
+
+ void setupState()
+ {
+ m_painter->setLineWidth(strokeWidth());
+ ScColorShade fill(m_item->doc()->PageColors[fillColor().color], qRound(fillColor().shade));
+ m_painter->setBrush(fill);
+ ScColorShade stroke(m_item->doc()->PageColors[strokeColor().color], qRound(strokeColor().shade));
+ m_painter->setPen(stroke);
+ if (matrix() != QTransform())
+ {
+ m_painter->setWorldMatrix(matrix() * m_painter->worldMatrix());
+ }
+ }
+
+public:
+ ScpageoutputPainter(PageItem* item, ScPainterExBase* painter, ScPageOutput* scpage)
+ : m_item(item)
+ , m_painter(painter)
+ , m_scpage(scpage)
+ {}
+
+ void translate(double xp, double yp)
+ {
+ TextLayoutPainter::translate(xp, yp);
+ m_painter->translate(xp, yp);
+ }
+
+ void save()
+ {
+ TextLayoutPainter::save();
+ m_painter->save();
+ }
+
+ void restore()
+ {
+ TextLayoutPainter::restore();
+ m_painter->restore();
+ }
+
+ void setScale(double h, double v)
+ {
+ TextLayoutPainter::setScale(h, v);
+ m_painter->scale(h, v);
+ }
+
+ void drawGlyph(const GlyphLayout gl)
+ {
+ if (gl.glyph >= ScFace::CONTROL_GLYPHS)
+ return;
+
+ m_painter->save();
+ bool fr = m_painter->fillRule();
+ int fm = m_painter->fillMode();
+
+ m_painter->setFillRule(false);
+ m_painter->setFillMode(1);
+
+ setupState();
+ m_painter->translate(0, -(fontSize() * gl.scaleV));
+ FPointArray outline = font().glyphOutline(gl.glyph);
+ double scaleH = gl.scaleH * fontSize() / 10.0;
+ double scaleV = gl.scaleV * fontSize() / 10.0;
+ m_painter->scale(scaleH, scaleV);
+ m_painter->setupPolygon(&outline, true);
+ if (outline.size() > 3)
+ m_painter->fillPath();
+
+ m_painter->setFillMode(fm);
+ m_painter->setFillRule(fr);
+ m_painter->restore();
+ }
+
+ void drawGlyphOutline(const GlyphLayout gl, bool fill)
+ {
+ if (gl.glyph >= ScFace::CONTROL_GLYPHS)
+ return;
+
+ m_painter->save();
+ bool fr = m_painter->fillRule();
+ m_painter->setFillRule(false);
+
+ setupState();
+ m_painter->translate(0, -(fontSize() * gl.scaleV));
+
+ FPointArray outline = font().glyphOutline(gl.glyph);
+ double scaleH = gl.scaleH * fontSize() / 10.0;
+ double scaleV = gl.scaleV * fontSize() / 10.0;
+ m_painter->scale(scaleH, scaleV);
+ m_painter->setupPolygon(&outline, true);
+ if (outline.size() > 3)
+ {
+ m_painter->setLineWidth(strokeWidth());
+ m_painter->strokePath();
+ }
+
+ m_painter->setFillRule(fr);
+ m_painter->restore();
+
+ if (fill)
+ drawGlyph(gl);
+ }
+
+ void drawLine(QPointF start, QPointF end)
+ {
+ m_painter->save();
+ setupState();
+ m_painter->drawLine(start, end);
+ m_painter->restore();
+ }
+
+ void drawRect(QRectF rect)
+ {
+ m_painter->save();
+ setupState();
+ m_painter->setFillMode(1);
+ m_painter->setStrokeMode(1);
+ m_painter->drawRect(rect.x(), rect.y(), rect.width(), rect.height());
+ m_painter->restore();
+ }
+
+ void drawObject(PageItem* embedded)
+ {
+ QRect cullingArea;
+ if (!embedded)
+ return;
+ if (!m_item->m_Doc->DoDrawing)
+ return;
+
+ m_painter->save();
+ double pws = embedded->m_lineWidth;
+
+ embedded->Dirty = m_item->Dirty;
+ embedded->invalid = true;
+ m_scpage->drawItem_Pre(embedded, m_painter);
+
+ switch(embedded->itemType())
+ {
+ case PageItem::ImageFrame:
+ case PageItem::TextFrame:
+ case PageItem::LatexFrame:
+ case PageItem::OSGFrame:
+ case PageItem::Polygon:
+ case PageItem::PathText:
+ case PageItem::Symbol:
+ case PageItem::Group:
+ case PageItem::RegularPolygon:
+ case PageItem::Arc:
+ case PageItem::Table:
+ m_scpage->drawItem(embedded, m_painter, cullingArea);
+ break;
+ case PageItem::Line:
+ case PageItem::PolyLine:
+ case PageItem::Spiral:
+ embedded->m_lineWidth = pws * qMin(scaleH(), scaleV());
+ m_scpage->drawItem(embedded, m_painter, cullingArea);
+ break;
+ default:
+ break;
+ }
+
+ embedded->m_lineWidth = pws * qMin(scaleH(), scaleV());
+ m_scpage->drawItem_Post(embedded, m_painter);
+ embedded->m_lineWidth = pws;
+ m_painter->restore();
+ }
+};
+
+
void ScPageOutput::drawItem_PathText( PageItem_PathText* item, ScPainterExBase* painter, QRect clip )
{
- QString chstr;
- //ScText *hl;
- FPoint point = FPoint(0, 0);
- FPoint tangent = FPoint(0, 0);
- double CurX = item->textToFrameDistLeft(); // item->CurX = item->textToFrameDistLeft()
- QString actFill, actStroke;
- double actFillShade, actStrokeShade, dx;
- StoryText& itemText = item->itemText;
- if (item->pathTextShowFrame())
- {
- painter->setupPolygon(&item->PoLine, false);
- if (item->NamedLStyle.isEmpty())
- {
- if (item->lineColor() != CommonStrings::None)
- painter->strokePath();
- }
- else
- {
- multiLine ml = m_doc->MLineStyles[item->NamedLStyle];
- for (int it = ml.size() - 1; it > -1; it--)
- {
- const SingleLine& sl = ml[it];
- if ((sl.Color != CommonStrings::None) && (sl.Width != 0))
- {
- ScColorShade tmp(m_doc->PageColors[sl.Color], sl.Shade);
- painter->setPen(tmp, sl.Width, static_cast<Qt::PenStyle>(sl.Dash),
- static_cast<Qt::PenCapStyle>(sl.LineEnd),
- static_cast<Qt::PenJoinStyle>(sl.LineJoin));
- painter->drawLine(FPoint(0, 0), FPoint(item->width(), 0));
- }
- }
- }
- }
- double totalTextLen = 0.0;
- double totalCurveLen = 0.0;
- double extraOffset = 0.0;
- if (itemText.length() != 0)
- {
- CurX += itemText.charStyle(0).fontSize() * itemText.charStyle(0).tracking() / 10000.0;
- totalTextLen += itemText.charStyle(0).fontSize() * itemText.charStyle(0).tracking() / 10000.0;
- }
- for (int a = 0; a < itemText.length(); ++a)
- {
- GlyphLayout* glyphs = itemText.getGlyphs(a);
- chstr =itemText.text(a,1);
- if (chstr[0] == SpecialChars::PAGENUMBER || chstr[0] == SpecialChars::PARSEP || chstr[0] == SpecialChars::PAGECOUNT
- || chstr[0] == SpecialChars::TAB || chstr == SpecialChars::LINEBREAK)
- continue;
- if (a < itemText.length()-1)
- chstr += itemText.text(a+1, 1);
- glyphs->yadvance = 0;
- item->layoutGlyphs(itemText.charStyle(a), chstr, itemText.flags(a), *glyphs);
- glyphs->shrink();
- if (item->itemText.hasObject(a))
- totalTextLen += (item->itemText.object(a)->width() + item->itemText.object(a)->lineWidth()) * glyphs->scaleH;
- else
- totalTextLen += glyphs->wide()+itemText.charStyle(a).fontSize() * itemText.charStyle(a).tracking() / 10000.0;
- }
- for (int segs = 0; segs < item->PoLine.size()-3; segs += 4)
- {
- totalCurveLen += item->PoLine.lenPathSeg(segs);
- }
- if ((itemText.defaultStyle().alignment() != 0) && (totalCurveLen >= totalTextLen + item->textToFrameDistLeft()))
- {
- if (itemText.defaultStyle().alignment() == 2)
- {
- CurX = totalCurveLen - totalTextLen;
- CurX -= item->textToFrameDistLeft();
- }
- if (itemText.defaultStyle().alignment() == 1)
- CurX = (totalCurveLen - totalTextLen) / 2.0;
- if ((itemText.defaultStyle().alignment() == 3) || (itemText.defaultStyle().alignment() == 4))
- extraOffset = (totalCurveLen - item->textToFrameDistLeft() - totalTextLen) / static_cast<double>(itemText.length());
- }
-
- QPainterPath guidePath = item->PoLine.toQPainterPath(false);
- QList<QPainterPath> pathList = decomposePath(guidePath);
- QPainterPath currPath = pathList[0];
- int currPathIndex = 0;
- for (int a = item->firstInFrame(); a < itemText.length(); ++a)
- {
- GlyphLayout* glyphs = itemText.getGlyphs(a);
- PathData* pdata = &(item->textLayout.point(a));
-
- chstr = itemText.text(a,1);
- if (chstr[0] == SpecialChars::PAGENUMBER || chstr[0] == SpecialChars::PARSEP || chstr[0] == SpecialChars::PAGECOUNT
- || chstr[0] == SpecialChars::TAB || chstr[0] == SpecialChars::LINEBREAK)
- continue;
- if (a < itemText.length()-1)
- chstr += itemText.text(a+1, 1);
- glyphs->yadvance = 0;
- item->layoutGlyphs(itemText.charStyle(a), chstr, itemText.flags(a), *glyphs);
- glyphs->shrink(); // HACK
- // Unneeded now that glyph xadvance is set appropriately for inline objects by PageItem_TextFrame::layout() - JG
- /*if (hl->hasObject())
- dx = (hl->embedded.getItem()->gWidth + hl->embedded.getItem()->lineWidth()) * hl->glyph.scaleH / 2.0;
- else*/
- dx = glyphs->wide() / 2.0;
-
- CurX += dx;
-
- double currPerc = currPath.percentAtLength(CurX);
- if (currPerc >= 0.9999999)
- {
- currPathIndex++;
- if (currPathIndex == pathList.count())
- break;
- currPath = pathList[currPathIndex];
- CurX = dx;
- currPerc = currPath.percentAtLength(CurX);
- }
- double currAngle = currPath.angleAtPercent(currPerc);
- if (currAngle <= 180.0)
- currAngle *= -1.0;
- else
- currAngle = 360.0 - currAngle;
- QPointF currPoint = currPath.pointAtPercent(currPerc);
- tangent = FPoint(cos(currAngle * M_PI / 180.0), sin(currAngle * M_PI / 180.0));
- point = FPoint(currPoint.x(), currPoint.y());
-
- //hl = itemText.item_p(a);
- glyphs->xoffset = 0;
- pdata->PtransX = point.x();
- pdata->PtransY = point.y();
- pdata->PRot = currAngle * M_PI / 180.0;
- pdata->PDx = dx;
- QTransform trafo = QTransform( 1, 0, 0, -1, -dx, 0 );
- if (item->textPathFlipped)
- trafo *= QTransform(1, 0, 0, -1, 0, 0);
- if (item->textPathType == 0)
- trafo *= QTransform( tangent.x(), tangent.y(), tangent.y(), -tangent.x(), point.x(), point.y() ); // ID's Rainbow mode
- else if (item->textPathType == 1)
- trafo *= QTransform( 1, 0, 0, -1, point.x(), point.y() ); // ID's Stair Step mode
- else if (item->textPathType == 2)
- {
- double a = 1;
- if (tangent.x() < 0)
- a = -1;
- if (fabs(tangent.x()) > 0.1)
- trafo *= QTransform( a, (tangent.y() / tangent.x()) * a, 0, -1, point.x(), point.y() ); // ID's Skew mode
- else
- trafo *= QTransform( a, 4 * a, 0, -1, point.x(), point.y() );
- }
- QTransform sca = painter->worldMatrix();
- trafo *= sca;
- painter->save();
- QTransform savWM = painter->worldMatrix();
- painter->setWorldMatrix(trafo);
-
- actFill = itemText.charStyle(a).fillColor();
- actFillShade = itemText.charStyle(a).fillShade();
- if (actFill != CommonStrings::None)
- {
- ScColorShade tmp(m_doc->PageColors[actFill], qRound(actFillShade));
- painter->setBrush(tmp);
- }
- actStroke = itemText.charStyle(a).strokeColor();
- actStrokeShade = itemText.charStyle(a).strokeShade();
- if (actStroke != CommonStrings::None)
- {
- ScColorShade tmp(m_doc->PageColors[actStroke], qRound(actStrokeShade));
- painter->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
- }
- painter->translate(0.0, item->pathTextBaseOffset());
- if (itemText.hasObject(a))
- drawItem_Embedded(itemText.object(a), painter, clip, itemText.charStyle(a), itemText.object(a));
- else
- drawGlyphs(item, painter, itemText.charStyle(a), *glyphs, clip);
-
- painter->setWorldMatrix(savWM);
- painter->restore();
- CurX -= dx;
- if (itemText.hasObject(a))
- CurX += (itemText.object(a)->width() + itemText.object(a)->lineWidth()) * glyphs->scaleH;
- else
- CurX += glyphs->wide()+itemText.charStyle(a).fontSize() * itemText.charStyle(a).tracking() / 10000.0 + extraOffset;
- }
+ ScpageoutputPainter p(item, painter, this);
+ item->textLayout.renderBackground(&p);
+ item->textLayout.render(&p);
}
void ScPageOutput::drawItem_Polygon ( PageItem_Polygon* item , ScPainterExBase* painter, QRect clip )
@@ -1610,251 +1451,9 @@
void ScPageOutput::drawItem_TextFrame( PageItem_TextFrame* item, ScPainterExBase* painter, QRect cullingArea )
{
- QTransform wm;
- QPoint pt1, pt2;
- FPoint ColBound;
- QRegion cm;
- int a;
- double desc, asce;
-
- painter->save();
- if (!item->isEmbedded)
- wm.translate(item->xPos(), item->yPos());
- wm.rotate(item->rotation());
-
- if ((item->fillColor() != CommonStrings::None) || (item->GrType != 0))
- {
- painter->setupPolygon(&item->PoLine);
- fillPath(item, painter, cullingArea);
- }
- if ((item->isAnnotation()) && (item->annotation().Type() == Annotation::Button) && (!item->Pfile.isEmpty()) && (item->imageIsAvailable) && (item->imageVisible()) && (item->annotation().UseIcons()))
- {
- painter->save();
- painter->setupPolygon(&item->PoLine);
- painter->setClipPath();
- painter->scale(item->imageXScale(), item->imageYScale());
- painter->translate(static_cast<int>(item->imageXOffset() * item->imageXScale()), static_cast<int>(item->imageYOffset() * item->imageYScale()));
- if (!item->pixm.qImage().isNull())
- painter->drawImage(&item->pixm, ScPainterExBase::rgbImages);
- painter->restore();
- }
- if ((item->itemText.length() != 0))
- {
- if (item->imageFlippedH())
- {
- painter->translate(item->width(), 0);
- painter->scale(-1, 1);
- wm.translate(item->width(), 0);
- wm.scale(-1, 1);
- }
- if (item->imageFlippedV())
- {
- painter->translate(0, item->height());
- painter->scale(1, -1);
- wm.translate(0, item->height());
- wm.scale(1, -1);
- }
-
- uint llp = 0;
- LineSpec ls;
- while (llp < item->textLayout.lines())
- {
- ls = item->textLayout.line(llp++);
- const ParagraphStyle& LineStyle = item->itemText.paragraphStyle(ls.firstItem);
- if (LineStyle.backgroundColor() != CommonStrings::None)
- {
- ScColorShade colorShade;
- colorShade.color = m_doc->PageColors[LineStyle.backgroundColor()];
- colorShade.shade = LineStyle.backgroundShade();
- double y0 = ls.y;
- double y2 = ls.y;
- double ascent = ls.ascent;
- double descent = ls.descent;
- double rMarg = LineStyle.rightMargin();
- double lMarg = ls.colLeft;
- double adjX = 0;
- if (LineStyle.firstIndent() <= 0)
- adjX += LineStyle.leftMargin() + LineStyle.firstIndent();
- while (llp < item->textLayout.lines())
- {
- ls = item->textLayout.line(llp);
- if ((ls.colLeft > lMarg) || (item->itemText.paragraphStyle(ls.firstItem) != LineStyle))
- {
- if (y2 == 0)
- y2 = y0;
- break;
- }
- if (item->itemText.text(ls.lastItem) == SpecialChars::PARSEP)
- {
- y2 = ls.y;
- descent = ls.descent;
- if ((llp + 1) < item->textLayout.lines())
- {
- if ((item->textLayout.line(llp + 1).lastItem - item->textLayout.line(llp + 1).firstItem) > 0)
- descent += LineStyle.lineSpacing() - (ls.descent + item->textLayout.line(llp + 1).ascent);
- }
- llp++;
- break;
- }
- y2 = ls.y;
- descent = ls.descent;
- if ((llp + 1) < item->textLayout.lines())
- descent += LineStyle.lineSpacing() - (ls.descent + item->textLayout.line(llp + 1).ascent);
- llp++;
- }
- painter->save();
- painter->setupPolygon(&item->PoLine);
- painter->setClipPath();
- painter->setFillMode(1);
- painter->setStrokeMode(0);
- painter->setBrush(colorShade);
- painter->drawRect(lMarg + adjX, y0 - ascent, item->columnWidth() - adjX - rMarg, y2 - y0 + descent + ascent);
- painter->restore();
- }
- }
-
- for (uint ll=0; ll < item->textLayout.lines(); ++ll)
- {
- const LineSpec& ls = item->textLayout.line(ll);
- double CurX = ls.x;
-
- // Draw text background
- ScColorShade tmpShade;
- double curXB = ls.x;
- QRectF scrG;
- QString oldBack;
- double oldShade = 100;
- for (a = ls.firstItem; a <= ls.lastItem; ++a)
- {
- GlyphLayout* glyphs = item->itemText.getGlyphs(a);
- const CharStyle& charStyle(item->itemText.charStyle(a));
- if (charStyle.backColor() != CommonStrings::None)
- {
- tmpShade.color = m_doc->PageColors[charStyle.backColor()];
- tmpShade.shade = charStyle.backShade();
- const ParagraphStyle& lineStyle = item->itemText.paragraphStyle(ls.firstItem);
- double y1 = ls.y;
- double hl = ls.height;
- if (lineStyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- hl = m_doc->guidesPrefs().valueBaselineGrid;
- else if (lineStyle.lineSpacingMode() == ParagraphStyle::FixedLineSpacing)
- hl = lineStyle.lineSpacing();
- if (ls.isFirstLine)
- {
- if (item->textLayout.lines() == 1)
- hl = ls.ascent + ls.descent;
- if (lineStyle.hasDropCap() && (a == ls.firstItem))
- hl *= lineStyle.dropCapLines();
- if (lineStyle.lineSpacingMode() == ParagraphStyle::BaselineGridLineSpacing)
- y1 -= lineStyle.lineSpacing();
- else if (item->firstLineOffset() == FLOPRealGlyphHeight || item->firstLineOffset() == FLOPFontAscent)
- y1 -= ls.ascent;
- else
- y1 -= lineStyle.lineSpacing();
- }
- else
- y1 -= ls.ascent + (hl - (ls.ascent + ls.descent)) / 2.0;
- QRectF scr;
- if (item->itemText.hasObject(a))
- {
- PageItem* obj = item->itemText.object(a);
- double ww = (obj->width() + obj->lineWidth()) * glyphs->scaleH;
- double hh = (obj->height() + obj->lineWidth()) * glyphs->scaleV;
- scr = QRectF(curXB, ls.y - hh, ww , hh);
- }
- else
- scr = QRectF(curXB, y1, glyphs->wide(), hl);
- if ((oldBack.isEmpty()) || ((oldBack == charStyle.backColor()) && (oldShade == charStyle.backShade())))
- scrG |= scr;
- else if ((oldBack != charStyle.backColor()) || (oldShade != charStyle.backShade()))
- {
- tmpShade.color = m_doc->PageColors[oldBack];
- tmpShade.shade = oldShade;
- painter->save();
- painter->setFillMode(1);
- painter->setStrokeMode(0);
- painter->setBrush(tmpShade);
- painter->drawRect(scrG.x(), scrG.y(), scrG.width(), scrG.height());
- painter->restore();
- scrG = scr;
- }
- oldBack = charStyle.backColor();
- oldShade = charStyle.backShade();
- }
- else
- {
- oldBack.clear();
- oldShade = 100;
- if (!scrG.isNull())
- {
- painter->save();
- painter->setFillMode(1);
- painter->setStrokeMode(0);
- painter->setBrush(tmpShade);
- painter->drawRect(scrG.x(), scrG.y(), scrG.width(), scrG.height());
- painter->restore();
- }
- scrG = QRectF();
- }
- curXB += glyphs->wide();
- }
- if (!scrG.isNull())
- {
- painter->save();
- painter->setFillMode(1);
- painter->setStrokeMode(0);
- painter->setBrush(tmpShade);
- painter->drawRect(scrG.x(), scrG.y(), scrG.width(), scrG.height());
- painter->restore();
- }
-
- // Draw text
- for (a = ls.firstItem; a <= ls.lastItem; ++a)
- {
- GlyphLayout* glyphs = item->itemText.getGlyphs(a);
- const CharStyle& charStyle = item->itemText.charStyle(a);
-
- if (charStyle.fillColor() != CommonStrings::None)
- {
- ScColorShade tmp(m_doc->PageColors[charStyle.fillColor()], (int) charStyle.fillShade());
- painter->setBrush(tmp);
- }
- if (charStyle.strokeColor() != CommonStrings::None)
- {
- ScColorShade tmp(m_doc->PageColors[charStyle.strokeColor()], (int) charStyle.strokeShade());
- painter->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
- }
-
- //if (!m_doc->RePos)
- {
- //double xcoZli = CurX + glyphs->xoffset;
- desc = - charStyle.font().descent(charStyle.fontSize() / 10.0);
- asce = charStyle.font().ascent(charStyle.fontSize() / 10.0);
- if (charStyle.strokeColor() != CommonStrings::None)
- {
- ScColorShade tmp(m_doc->PageColors[charStyle.strokeColor()], (int) charStyle.strokeShade());
- painter->setPen(tmp, 1, Qt::SolidLine, Qt::FlatCap, Qt::MiterJoin);
- }
- if (item->isEmbedded || cullingArea.intersects(wm.mapRect(QRect(qRound(CurX + glyphs->xoffset),qRound(ls.y + glyphs->yoffset-asce), qRound(glyphs->xadvance+1), qRound(asce+desc)))))
- {
- painter->save();
- painter->translate(CurX, ls.y);
- if (item->itemText.hasObject(a))
- drawItem_Embedded(item, painter, cullingArea, charStyle, item->itemText.object(a));
- else
- drawGlyphs(item, painter, charStyle, *glyphs, cullingArea);
- painter->restore();
- }
- // Unneeded now that glyph xadvance is set appropriately for inline objects by PageItem_TextFrame::layout() - JG
- /*if (hl->hasObject())
- CurX += (hl->embedded.getItem()->gWidth + hl->embedded.getItem()->lineWidth());
- else*/
- CurX += glyphs->wide();
- }
- }
- }
- }
- painter->restore();
+ ScpageoutputPainter p(item, painter, this);
+ item->textLayout.renderBackground(&p);
+ item->textLayout.render(&p);
}
void ScPageOutput::drawArrow(ScPainterExBase* painter, PageItem* item, QTransform &arrowTrans, int arrowIndex)
Modified: trunk/Scribus/scribus/scpageoutput.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/scpageoutput.h
==============================================================================
--- trunk/Scribus/scribus/scpageoutput.h (original)
+++ trunk/Scribus/scribus/scpageoutput.h Wed Mar 23 20:21:36 2016
@@ -53,6 +53,8 @@
class SCRIBUS_API ScPageOutput
{
+ friend class ScpageoutputPainter;
+
public:
ScPageOutput(ScribusDoc* doc, bool reloadImages = false, int resolution = 72, bool useProfiles = false);
virtual ~ScPageOutput() { }
@@ -82,7 +84,6 @@
virtual void drawItem_Pre( PageItem* item, ScPainterExBase* painter );
virtual void drawItem_Post( PageItem* item, ScPainterExBase* painter );
- virtual void drawGlyphs(PageItem* item, ScPainterExBase *painter, const CharStyle& style, GlyphLayout& glyphs, QRect clip);
virtual void drawItem_Embedded( PageItem* item, ScPainterExBase *p, QRect clip, const CharStyle& style, PageItem* cembedded);
virtual void drawPattern(PageItem* item, ScPainterExBase* painter, QRect clip);
virtual void drawStrokePattern(PageItem* item, ScPainterExBase* painter, const QPainterPath& path);
Modified: trunk/Scribus/scribus/scpainter.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/scpainter.cpp
==============================================================================
--- trunk/Scribus/scribus/scpainter.cpp (original)
+++ trunk/Scribus/scribus/scpainter.cpp Wed Mar 23 20:21:36 2016
@@ -181,6 +181,11 @@
m_image->fill( qRgba(qRed(cs), qGreen(cs), qBlue(cs), qAlpha(cs)) );
}
+cairo_t *ScPainter::context()
+{
+ return m_cr;
+}
+
const QTransform ScPainter::worldMatrix()
{
cairo_matrix_t matrix;
@@ -424,6 +429,11 @@
return m_fill;
}
+double ScPainter::brushOpacity()
+{
+ return m_fill_trans;
+}
+
void ScPainter::setPen( const QColor &c )
{
m_stroke = c;
@@ -493,6 +503,11 @@
cairo_restore( m_cr );
if (!m_zoomStack.isEmpty())
m_zoomFactor = m_zoomStack.pop();
+}
+
+int ScPainter::blendModeFill()
+{
+ return m_blendModeFill;
}
void ScPainter::setRasterOp(int blendMode)
@@ -1932,6 +1947,7 @@
void ScPainter::drawText(QRectF area, QString text, bool filled, int align)
{
+ // FIXME HOST: This uses Cairo "Toy text API" which does not support complex text layout.
cairo_text_extents_t extents;
cairo_font_extents_t extentsF;
double x;
Modified: trunk/Scribus/scribus/scpainter.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/scpainter.h
==============================================================================
--- trunk/Scribus/scribus/scpainter.h (original)
+++ trunk/Scribus/scribus/scpainter.h Wed Mar 23 20:21:36 2016
@@ -19,6 +19,7 @@
#include <QPointF>
#include "scribusapi.h"
#include "scconfig.h"
+#include "sctextstruct.h"
#include "fpoint.h"
#include "fpointarray.h"
#include "vgradient.h"
@@ -43,6 +44,7 @@
virtual void end();
void clear();
virtual void clear( const QColor & );
+ virtual cairo_t* context();
// matrix manipulation
virtual void setWorldMatrix( const QTransform & );
@@ -66,6 +68,7 @@
virtual bool fillRule() { return m_fillRule; }
virtual void setFillMode( int fill );
virtual int fillMode() { return m_fillMode; }
+ virtual int maskMode() { return m_maskMode; }
virtual void setStrokeMode( int stroke );
virtual int strokeMode() { return m_strokeMode; }
virtual void setGradient( VGradient::VGradientType mode, FPoint orig, FPoint vec, FPoint foc, double scale, double skew);
@@ -109,6 +112,7 @@
// pen + brush
virtual QColor pen();
virtual QColor brush();
+ virtual double brushOpacity();
virtual void setPen( const QColor & );
virtual void setPen( const QColor &c, double w, Qt::PenStyle st, Qt::PenCapStyle ca, Qt::PenJoinStyle jo );
virtual void setPenOpacity( double op );
@@ -123,6 +127,7 @@
// stack management
virtual void save();
virtual void restore();
+ virtual int blendModeFill();
virtual void setRasterOp( int blendMode );
Modified: trunk/Scribus/scribus/scribusdoc.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/scribusdoc.cpp
==============================================================================
--- trunk/Scribus/scribus/scribusdoc.cpp (original)
+++ trunk/Scribus/scribus/scribusdoc.cpp Wed Mar 23 20:21:36 2016
@@ -42,6 +42,7 @@
#include "actionmanager.h"
#include "appmodes.h"
+#include "text/boxes.h"
#include "canvas.h"
#include "colorblind.h"
#include "commonstrings.h"
@@ -95,6 +96,7 @@
#include "selection.h"
#include "serializer.h"
#include "tableborder.h"
+#include "text/textlayoutpainter.h"
#include "ui/hruler.h"
#include "ui/layers.h"
#include "ui/mark2item.h"
@@ -4497,181 +4499,45 @@
}
}
+// a special painter that does not actually paint anything,
+// but collects the glyphs used in the frame.
+class UsedGlyphsPainter: public TextLayoutPainter
+{
+public:
+ UsedGlyphsPainter(QMap<QString, QMap<uint, FPointArray> > & Really)
+ : m_really(Really)
+ {}
+
+ void drawGlyph(const GlyphLayout gl)
+ {
+ if (gl.glyph >= ScFace::CONTROL_GLYPHS)
+ return;
+
+ if (!font().replacementName().isEmpty())
+ {
+ FPointArray outline(font().glyphOutline(gl.glyph));
+ m_really[font().replacementName()].insert(gl.glyph, outline);
+ }
+ }
+
+ void drawGlyphOutline(const GlyphLayout gl, bool) { drawGlyph(gl); }
+
+ // we don't need this one
+ void drawLine(QPointF, QPointF) {}
+ void drawRect(QRectF) {}
+ void drawObject(PageItem*) {}
+
+private:
+ QMap<QString, QMap<uint, FPointArray> > & m_really;
+};
void ScribusDoc::checkItemForFonts(PageItem *it, QMap<QString, QMap<uint, FPointArray> > & Really, uint lc)
{
if (!it->isTextFrame() && !it->isPathText())
return;
- FPointArray gly;
- QChar chstr;
-
- int start = it->isTextFrame() ? it->firstInFrame() : 0;
- int stop = it->isTextFrame() ? it->lastInFrame() + 1 : it->itemText.length();
- for (int e = start; e < stop; ++e)
- {
- const ScFace* font = &it->itemText.charStyle(e).font();
- if (it->itemText.hasMark(e))
- {
- QString mrkStr = it->itemText.mark(e)->getString();
- for (int i=0;i<mrkStr.length(); ++i)
- {
- if (font->canRender(mrkStr[i].unicode()))
- {
- uint gl = font->char2CMap(mrkStr[i]);
- FPointArray gly(font->glyphOutline(gl));
- if (!font->replacementName().isEmpty())
- Really[font->replacementName()].insert(gl, gly);
- }
- }
- }
- if (! Really.contains(font->replacementName()) )
- {
- if (!font->replacementName().isEmpty())
- Really.insert(font->replacementName(), QMap<uint, FPointArray>());
- }
- uint chr = it->itemText.text(e).unicode();
- if ((chr == 13) || (chr == 32) || ((chr >= 26) && (chr <= 29)))
- continue;
- if (chr == 9)
- {
- for (int t1 = 0; t1 < it->itemText.paragraphStyle(e).tabValues().count(); t1++)
- {
- if (it->itemText.paragraphStyle(e).tabValues()[t1].tabFillChar.isNull())
- continue;
- chstr = it->itemText.paragraphStyle(e).tabValues()[t1].tabFillChar;
- if ((it->itemText.charStyle(e).effects() & ScStyle_SmallCaps) || (it->itemText.charStyle(e).effects() & ScStyle_AllCaps))
- {
- if (chstr.toUpper() != chstr)
- chstr = chstr.toUpper();
- }
- chr = chstr.unicode();
- uint gl = font->char2CMap(chstr);
- gly = font->glyphOutline(gl);
- if (!font->replacementName().isEmpty())
- Really[font->replacementName()].insert(gl, gly);
- }
- for (int t1 = 0; t1 < it->itemText.defaultStyle().tabValues().count(); t1++)
- {
- if (it->itemText.defaultStyle().tabValues()[t1].tabFillChar.isNull())
- continue;
- chstr = it->itemText.defaultStyle().tabValues()[t1].tabFillChar;
- if ((it->itemText.charStyle(e).effects() & ScStyle_SmallCaps) || (it->itemText.charStyle(e).effects() & ScStyle_AllCaps))
- {
- if (chstr.toUpper() != chstr)
- chstr = chstr.toUpper();
- }
- chr = chstr.unicode();
- uint gl = font->char2CMap(chstr);
- gly = font->glyphOutline(gl);
- if (!font->replacementName().isEmpty())
- Really[font->replacementName()].insert(gl, gly);
- }
- continue;
- }
- if ((chr == 30) || (chr == 23))
- {
- //Our page number collection string
- QString pageNumberText(QString::null);
- if (chr == 30)
- {//ch == SpecialChars::PAGENUMBER
- if (e > 0 && it->itemText.text(e-1) == SpecialChars::PAGENUMBER)
- pageNumberText=SpecialChars::ZWNBSPACE;
- else if (lc!=0) //If not on a master page just get the page number for the page and the text
- {
- pageNumberText = QString("%1").arg(getSectionPageNumberForPageIndex(it->OwnPage),
- getSectionPageNumberWidthForPageIndex(it->OwnPage),
- getSectionPageNumberFillCharForPageIndex(it->OwnPage));
- }
- else
- {
- //Else, for a page number in a text frame on a master page we must scan
- //all pages to see which ones use this page and get their page numbers.
- //We only add each character of the pages' page number text if its nothing
- //already in the pageNumberText variable. No need to add glyphs twice.
- QString newText;
- uint docPageCount=DocPages.count();
- for (uint a = 0; a < docPageCount; ++a)
- {
- if (DocPages.at(a)->MPageNam == it->OnMasterPage)
- {
- newText = QString("%1").arg(getSectionPageNumberForPageIndex(a),
- getSectionPageNumberWidthForPageIndex(a),
- getSectionPageNumberFillCharForPageIndex(a));
- for (int nti=0;nti<newText.length();++nti)
- if (pageNumberText.indexOf(newText[nti])==-1)
- pageNumberText+=newText[nti];
- }
- }
- }
- }
- else
- {//ch == SpecialChars::PAGECOUNT
- if (lc!=0)
- {
- int key = getSectionKeyForPageIndex(it->OwnPage);
- if (key == -1)
- pageNumberText = "";
- else
- pageNumberText = QString("%1").arg(getStringFromSequence(m_docPrefsData.docSectionMap[key].type, m_docPrefsData.docSectionMap[key].toindex - m_docPrefsData.docSectionMap[key].fromindex + 1));
- }
- else
- {
- QString newText;
- uint docPageCount=DocPages.count();
- for (uint a = 0; a < docPageCount; ++a)
- {
- if (DocPages.at(a)->MPageNam == it->OnMasterPage)
- {
- int key = getSectionKeyForPageIndex(a);
- if (key == -1)
- newText = "";
- else
- newText = QString("%1").arg(getStringFromSequence(m_docPrefsData.docSectionMap[key].type, m_docPrefsData.docSectionMap[key].toindex - m_docPrefsData.docSectionMap[key].fromindex + 1));
- for (int nti=0;nti<newText.length();++nti)
- if (pageNumberText.indexOf(newText[nti])==-1)
- pageNumberText+=newText[nti];
- }
- }
- }
- }
- //Now scan and add any glyphs used in page numbers
- for (int pnti=0;pnti<pageNumberText.length(); ++pnti)
- {
- uint chr = pageNumberText[pnti].unicode();
- if (font->canRender(chr))
- {
- uint gl = font->char2CMap(pageNumberText[pnti]);
- FPointArray gly(font->glyphOutline(gl));
- if (!font->replacementName().isEmpty())
- Really[font->replacementName()].insert(gl, gly);
- }
- }
- continue;
- }
-
- if (it->itemText.hasFlag(e, ScLayout_SoftHyphenVisible))
- {
- uint gl = it->itemText.charStyle(e).font().char2CMap(QChar('-'));
- FPointArray gly(it->itemText.charStyle(e).font().glyphOutline(gl));
- if (!it->itemText.charStyle(e).font().replacementName().isEmpty())
- Really[it->itemText.charStyle(e).font().replacementName()].insert(gl, gly);
- }
- if ((it->itemText.charStyle(e).effects() & ScStyle_SmallCaps) || (it->itemText.charStyle(e).effects() & ScStyle_AllCaps))
- {
- chstr = it->itemText.text(e);
- if (chstr.toUpper() != chstr)
- chstr = chstr.toUpper();
- chr = chstr.unicode();
- }
- if (it->itemText.charStyle(e).font().canRender(chr))
- {
- uint gl = it->itemText.charStyle(e).font().char2CMap(chr);
- gly = it->itemText.charStyle(e).font().glyphOutline(gl);
- if (!it->itemText.charStyle(e).font().replacementName().isEmpty())
- Really[it->itemText.charStyle(e).font().replacementName()].insert(gl, gly);
- }
- }
+ UsedGlyphsPainter p(Really);
+ it->textLayout.render(&p);
}
Modified: trunk/Scribus/scribus/scribusview.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/scribusview.cpp
==============================================================================
--- trunk/Scribus/scribus/scribusview.cpp (original)
+++ trunk/Scribus/scribus/scribusview.cpp Wed Mar 23 20:21:36 2016
@@ -80,6 +80,7 @@
#include "hyphenator.h"
#include "iconmanager.h"
#include "loadsaveplugin.h"
+#include "text/textlayoutpainter.h"
#include "pageitem.h"
#include "pageitem_group.h"
#include "pageitem_imageframe.h"
@@ -1651,8 +1652,14 @@
point.setX(textFrame->width() - point.x());
if (textFrame->imageFlippedV())
point.setY(textFrame->height() - point.y());
- textFrame->itemText.setCursorPosition(textFrame->itemText.length() == 0 ? 0 :
- textFrame->textLayout.screenToPosition(point));
+ if (textFrame->itemText.length() == 0)
+ textFrame->itemText.setCursorPosition(0);
+ else
+ {
+ int result = textFrame->textLayout.pointToPosition(point.toQPointF());
+ if (result >= 0)
+ textFrame->itemText.setCursorPosition(result);
+ }
if (textFrame->itemText.length() > 0)
{
@@ -2998,6 +3005,91 @@
}
}
+// FIXME: the following code is untested, but it should give an idea for
+// anyone who wants to fix and knows how to test it.
+class TextToPathPainter: public TextLayoutPainter
+{
+ ScribusView* m_view;
+ PageItem* m_item;
+ QList<PageItem*> m_group;
+ int m_counter;
+
+public:
+ TextToPathPainter(ScribusView* view, PageItem* item)
+ : m_view(view)
+ , m_item(item)
+ , m_counter(0)
+ {}
+
+ void drawGlyph(const GlyphLayout gl)
+ {
+
+ FPointArray outline = font().glyphOutline(gl.glyph);
+ if (outline.size() < 4)
+ return;
+ QTransform transform = matrix();
+ transform.scale(x(), y());
+ outline.map(transform);
+ uint z = m_view->Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, m_item->xPos(), m_item->yPos(), m_item->width(), m_item->height(), m_item->lineWidth(), m_item->lineColor(), m_item->fillColor());
+ PageItem* item = m_view->Doc->Items->at(z);
+ m_view->undoManager->setUndoEnabled(false);
+ item->setTextFlowMode(m_item->textFlowMode());
+ item->setSizeLocked(m_item->sizeLocked());
+ item->setLocked(m_item->locked());
+ item->NamedLStyle = m_item->NamedLStyle;
+ item->setItemName(m_item->itemName() + "+U" + QString::number(m_counter++));
+ item->PoLine = outline.copy();
+ if (!m_item->asPathText())
+ item->setRotation(m_item->rotation());
+ item->setFillColor(fillColor().color);
+ item->setFillShade(fillColor().shade);
+ item->setLineWidth(strokeWidth());
+ m_view->Doc->adjustItemSize(item);
+ item->ContourLine = item->PoLine.copy();
+ item->ClipEdited = true;
+ item->FrameType = 3;
+ item->OldB2 = item->width();
+ item->OldH2 = item->height();
+ m_view->Doc->setRedrawBounding(item);
+ m_view->undoManager->setUndoEnabled(true);
+ m_group.append(m_view->Doc->Items->takeAt(z));
+ }
+ void drawGlyphOutline(const GlyphLayout gl, bool fill)
+ {
+ drawGlyph(gl);
+ }
+ void drawLine(QPointF start, QPointF end)
+ {
+ QTransform transform = matrix();
+ transform.translate(x(), y());
+ uint z = m_view->Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, m_item->xPos(), m_item->yPos(), m_item->width(), m_item->height(), m_item->lineWidth(), m_item->lineColor(), m_item->fillColor());
+ PageItem* item = m_view->Doc->Items->at(z);
+ m_view->undoManager->setUndoEnabled(false);
+ item->setTextFlowMode(m_item->textFlowMode());
+ item->setSizeLocked(m_item->sizeLocked());
+ item->setLocked(m_item->locked());
+ item->NamedLStyle = m_item->NamedLStyle;
+ item->setItemName(m_item->itemName() + "+U" + QString::number(m_counter++));
+ item->PoLine.resize(0);
+ item->PoLine.addQuadPoint(FPoint(start), FPoint(start), FPoint(end), FPoint(end));
+ item->PoLine.map(transform);
+ item->setLineColor(fillColor().color);
+ item->setLineShade(fillColor().shade);
+ item->setLineWidth(strokeWidth());
+ m_view->Doc->adjustItemSize(item);
+ item->ContourLine = item->PoLine.copy();
+ item->ClipEdited = true;
+ item->FrameType = 3;
+ item->OldB2 = item->width();
+ item->OldH2 = item->height();
+ m_view->Doc->setRedrawBounding(item);
+ m_view->undoManager->setUndoEnabled(true);
+ m_group.append(m_view->Doc->Items->takeAt(z));
+ }
+ void drawRect(QRectF rect) {}
+ void drawObject(PageItem* item) {}
+};
+
void ScribusView::TextToPath()
{
if (Doc->appMode == modeEditClip)
@@ -3048,642 +3140,9 @@
++offset;
continue;
}
-// newGroupedItems.clear();
- FPointArray pts;
- double x=0.0, y=0.0, wide=0.0;
- QString chstr, ccounter;
- QChar chstrex;
- PageItem* bb;
-
- if (currItem->asPathText())
- {
- for (int a = 0; a < currItem->asPathText()->itemRenderText.length(); ++a)
- {
- pts.resize(0);
- x = 0.0;
- y = 0.0;
- //ScText * hl = currItem->asPathText()->itemRenderText.item_p(a);
- const CharStyle& charStyle(currItem->asPathText()->itemRenderText.charStyle(a));
- const PathData& pdata(currItem->textLayout.point(a));
- const GlyphLayout* glyphs = currItem->asPathText()->itemRenderText.getGlyphs(a);
- LayoutFlags flags = currItem->asPathText()->itemRenderText.flags(a);
-
- chstr = currItem->asPathText()->itemRenderText.text(a,1);
- if ((chstr == SpecialChars::PARSEP) || (chstr == SpecialChars::OLD_NBSPACE))
- continue;
- if (chstr == SpecialChars::OBJECT)
- {
- continue;
- }
- if (chstr == SpecialChars::PAGENUMBER)
- chstr = currItem->ExpandToken(a);
- double chs = charStyle.fontSize();
- if (charStyle.effects() & ScStyle_SmallCaps)
- {
- if (chstr[0].toUpper() != chstr[0])
- {
- chs = qMax(static_cast<int>(charStyle.fontSize() * Doc->typographicPrefs().valueSmallCaps / 100), 1);
- chstr = chstr[0].toUpper();
- }
- }
- else if (charStyle.effects() & ScStyle_AllCaps)
- chstr = chstr[0].toUpper();
- // double csi = static_cast<double>(chs) / 100.0;
- uint chr = chstr[0].unicode();
- QPointF tangt = QPointF( cos(pdata.PRot), sin(pdata.PRot) );
- QTransform chma, chma2, chma3, chma4, chma6;
- QTransform trafo = QTransform( 1, 0, 0, -1, -pdata.PDx, 0 );
- if (currItem->textPathFlipped)
- trafo *= QTransform(1, 0, 0, -1, 0, 0);
- if (currItem->textPathType == 0)
- trafo *= QTransform( tangt.x(), tangt.y(), tangt.y(), -tangt.x(), pdata.PtransX, pdata.PtransY );
- else if (currItem->textPathType == 1)
- trafo *= QTransform(1, 0, 0, -1, pdata.PtransX, pdata.PtransY );
- else if (currItem->textPathType == 2)
- {
- double a = 1;
- double b = -1;
- if (tangt.x() < 0)
- {
- a = -1;
- b = 1;
- }
- if (fabs(tangt.x()) > 0.1)
- trafo *= QTransform( a, (tangt.y() / tangt.x()) * b, 0, -1, pdata.PtransX, pdata.PtransY ); // ID's Skew mode
- else
- trafo *= QTransform( a, 6 * b, 0, -1, pdata.PtransX, pdata.PtransY );
- }
- //trafo *= QTransform( hl->PtransX, hl->PtransY, hl->PtransY, -hl->PtransX, glyphs->xoffset, glyphs->yoffset);
- if (currItem->rotation() != 0)
- {
- QTransform sca;
- sca.translate(-currItem->xPos(), -currItem->yPos());
- sca.rotate(currItem->rotation());
- trafo *= sca;
- }
- chma.scale(glyphs->scaleH * charStyle.fontSize() / 100.00, glyphs->scaleV * charStyle.fontSize() / 100.0);
- if (currItem->reversed())
- {
- if (a < currItem->asPathText()->itemRenderText.length()-1)
- wide = charStyle.font().charWidth(chstr[0], charStyle.fontSize(), currItem->asPathText()->itemRenderText.text(a+1));
- else
- wide = charStyle.font().charWidth(chstr[0], charStyle.fontSize());
- chma3.scale(-1, 1);
- chma3.translate(-wide, 0);
- }
- chma4.translate(0, currItem->BaseOffs - (charStyle.fontSize() / 10.0) * glyphs->scaleV);
- if (charStyle.effects() & (ScStyle_Subscript | ScStyle_Superscript))
- chma6.translate(0, glyphs->yoffset);
- if (charStyle.baselineOffset() != 0)
- chma6.translate(0, (-charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0));
- uint gl = charStyle.font().char2CMap(chr);
- QTransform finalMat = QTransform(chma * chma2 * chma3 * chma4 * chma6 * trafo);
- if (currItem->rotation() != 0)
- {
- QTransform sca;
- sca.translate(currItem->xPos(), currItem->yPos());
- pts.map(sca);
- }
- QChar chstc = chstr[0];
- if (((charStyle.effects() & ScStyle_Underline) && !SpecialChars::isBreak(chstc))
- || ((charStyle.effects() & ScStyle_UnderlineWords) && !chstc.isSpace() && !SpecialChars::isBreak(chstc)))
- {
- QTransform stro = QTransform(chma2 * chma3 * chma6 * trafo);
- if (currItem->rotation() != 0)
- {
- QTransform sca;
- sca.translate(currItem->xPos(), currItem->yPos());
- stro *= sca;
- }
- double Ulen = glyphs->xadvance;
- double Upos, Uwid, kern;
- if (flags & ScLayout_StartOfLine)
- kern = 0;
- else
- kern = charStyle.fontSize() * charStyle.tracking() / 10000.0;
- if ((charStyle.underlineOffset() != -1) || (charStyle.underlineWidth() != -1))
- {
- if (charStyle.underlineOffset() != -1)
- Upos = (charStyle.underlineOffset() / 1000.0) * (charStyle.font().descent(charStyle.fontSize() / 10.0));
- else
- Upos = charStyle.font().underlinePos(charStyle.fontSize() / 10.0);
- if (charStyle.underlineWidth() != -1)
- Uwid = (charStyle.underlineWidth() / 1000.0) * (charStyle.fontSize() / 10.0);
- else
- Uwid = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- else
- {
- Upos = charStyle.font().underlinePos(charStyle.fontSize() / 10.0);
- Uwid = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- if (charStyle.baselineOffset() != 0)
- Upos += (charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0);
- uint z = Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, currItem->xPos(), currItem->yPos(), currItem->width(), currItem->height(), currItem->lineWidth(), currItem->lineColor(), currItem->fillColor());
- bb = Doc->Items->at(z);
- undoManager->setUndoEnabled(false);
- bb->setTextFlowMode(currItem->textFlowMode());
- bb->setSizeLocked(currItem->sizeLocked());
- bb->setLocked(currItem->locked());
- bb->NamedLStyle = currItem->NamedLStyle;
- bb->setItemName(currItem->itemName()+"+U"+ccounter.setNum(a));
- FPoint start, stop;
- if (charStyle.effects() & ScStyle_Subscript)
- {
- start = FPoint(glyphs->xoffset-kern, -Upos);
- stop = FPoint(glyphs->xoffset+Ulen, -Upos);
- }
- else
- {
- start = FPoint(glyphs->xoffset-kern, -(Upos + glyphs->yoffset));
- stop = FPoint(glyphs->xoffset+Ulen, -(Upos + glyphs->yoffset));
- }
- bb->PoLine.resize(0);
- bb->PoLine.addQuadPoint(start, start, stop, stop);
- bb->PoLine.map(stro);
- bb->setLineColor(charStyle.fillColor());
- bb->setLineShade(charStyle.fillShade());
- bb->setLineWidth(Uwid);
- Doc->adjustItemSize(bb);
- bb->ContourLine = bb->PoLine.copy();
- bb->ClipEdited = true;
- bb->FrameType = 3;
- bb->OldB2 = bb->width();
- bb->OldH2 = bb->height();
- Doc->setRedrawBounding(bb);
- undoManager->setUndoEnabled(true);
- newGroupedItems.append(Doc->Items->takeAt(z));
- }
- if ((chstr.length() > 0) && (!chstr.at(0).isSpace()))
- {
- pts = charStyle.font().glyphOutline(gl);
- if (pts.size() < 4)
- continue;
- if ((charStyle.effects() & ScStyle_Shadowed) && (charStyle.strokeColor() != CommonStrings::None))
- {
- double glxTr = charStyle.fontSize() * charStyle.shadowXOffset() / 10000.0;
- double glyTr = -charStyle.fontSize() * charStyle.shadowYOffset() / 10000.0;
- uint z = Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, currItem->xPos(), currItem->yPos(), currItem->width(), currItem->height(), currItem->lineWidth(), currItem->lineColor(), currItem->fillColor());
- bb = Doc->Items->at(z);
- undoManager->setUndoEnabled(false);
- bb->setTextFlowMode(currItem->textFlowMode());
- bb->setSizeLocked(currItem->sizeLocked());
- bb->setLocked(currItem->locked());
- bb->NamedLStyle = currItem->NamedLStyle;
- bb->setItemName(currItem->itemName()+"+Sh"+ccounter.setNum(a));
- bb->PoLine = pts.copy();
- QTransform shmap;
- shmap.translate(glxTr, glyTr);
- bb->PoLine.map(finalMat * shmap);
- bb->setFillColor(charStyle.strokeColor());
- bb->setFillShade(charStyle.strokeShade());
- if (currItem->asPathText()->itemRenderText.charStyle(a).effects() & ScStyle_Outline)
- {
- bb->setLineColor(charStyle.strokeColor());
- bb->setLineShade(charStyle.strokeShade());
- }
- else
- {
- bb->setLineColor(CommonStrings::None);
- bb->setLineShade(100);
- }
- bb->setLineWidth(chs * charStyle.outlineWidth() / 10000.0);
- Doc->adjustItemSize(bb);
- bb->ContourLine = bb->PoLine.copy();
- bb->ClipEdited = true;
- bb->FrameType = 3;
- bb->OldB2 = bb->width();
- bb->OldH2 = bb->height();
- Doc->setRedrawBounding(bb);
- undoManager->setUndoEnabled(true);
- newGroupedItems.append(Doc->Items->takeAt(z));
- }
- pts.map(finalMat);
- uint z = Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, currItem->xPos(), currItem->yPos(), currItem->width(), currItem->height(), currItem->lineWidth(), currItem->lineColor(), currItem->fillColor());
- bb = Doc->Items->at(z);
- //bb->setTextFlowsAroundFrame(currItem->textFlowsAroundFrame());
- //bb->setTextFlowUsesBoundingBox(currItem->textFlowUsesBoundingBox());
- undoManager->setUndoEnabled(false);
- bb->setTextFlowMode(currItem->textFlowMode());
- bb->setSizeLocked(currItem->sizeLocked());
- bb->setLocked(currItem->locked());
- bb->NamedLStyle = currItem->NamedLStyle;
- bb->setItemName(currItem->itemName()+"+"+ccounter.setNum(a));
- bb->PoLine = pts.copy();
- if (!currItem->asPathText())
- bb->setRotation(currItem->rotation());
- bb->setFillColor(charStyle.fillColor());
- bb->setFillShade(charStyle.fillShade());
- if (currItem->asPathText()->itemRenderText.charStyle(a).effects() & ScStyle_Outline)
- {
- bb->setLineColor(charStyle.strokeColor());
- bb->setLineShade(charStyle.strokeShade());
- }
- else
- {
- bb->setLineColor(CommonStrings::None);
- bb->setLineShade(100);
- }
- bb->setLineWidth(chs * charStyle.outlineWidth() / 10000.0);
- Doc->adjustItemSize(bb);
- bb->ContourLine = bb->PoLine.copy();
- bb->ClipEdited = true;
- bb->FrameType = 3;
- bb->OldB2 = bb->width();
- bb->OldH2 = bb->height();
- Doc->setRedrawBounding(bb);
- undoManager->setUndoEnabled(true);
- newGroupedItems.append(Doc->Items->takeAt(z));
- }
- if (charStyle.effects() & ScStyle_Strikethrough)
- {
- QTransform stro = QTransform(chma2 * chma3 * chma6 * trafo);
- if (currItem->rotation() != 0)
- {
- QTransform sca;
- sca.translate(currItem->xPos(), currItem->yPos());
- stro *= sca;
- }
- double Ulen = glyphs->xadvance;
- double Upos, Uwid, kern;
- if (flags & ScLayout_StartOfLine)
- kern = 0;
- else
- kern = charStyle.fontSize() * charStyle.tracking() / 10000.0;
- if ((charStyle.strikethruOffset() != -1) || (charStyle.strikethruWidth() != -1))
- {
- if (charStyle.strikethruOffset() != -1)
- Upos = (charStyle.strikethruOffset() / 1000.0) * (charStyle.font().ascent(charStyle.fontSize() / 10.0));
- else
- Upos = charStyle.font().strikeoutPos(charStyle.fontSize() / 10.0);
- if (charStyle.strikethruWidth() != -1)
- Uwid = (charStyle.strikethruWidth() / 1000.0) * (charStyle.fontSize() / 10.0);
- else
- Uwid = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- else
- {
- Upos = charStyle.font().strikeoutPos(charStyle.fontSize() / 10.0);
- Uwid = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- if (charStyle.baselineOffset() != 0)
- Upos += (charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0);
- uint z = Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, currItem->xPos(), currItem->yPos(), currItem->width(), currItem->height(), currItem->lineWidth(), currItem->lineColor(), currItem->fillColor());
- bb = Doc->Items->at(z);
- undoManager->setUndoEnabled(false);
- bb->setTextFlowMode(currItem->textFlowMode());
- bb->setSizeLocked(currItem->sizeLocked());
- bb->setLocked(currItem->locked());
- bb->NamedLStyle = currItem->NamedLStyle;
- bb->setItemName(currItem->itemName()+"+S"+ccounter.setNum(a));
- FPoint start = FPoint(glyphs->xoffset-kern, -Upos);
- FPoint stop = FPoint(glyphs->xoffset+Ulen, -Upos);
- bb->PoLine.resize(0);
- bb->PoLine.addQuadPoint(start, start, stop, stop);
- bb->PoLine.map(stro);
- bb->setLineColor(charStyle.fillColor());
- bb->setLineShade(charStyle.fillShade());
- bb->setLineWidth(Uwid);
- Doc->adjustItemSize(bb);
- bb->ContourLine = bb->PoLine.copy();
- bb->ClipEdited = true;
- bb->FrameType = 3;
- bb->OldB2 = bb->width();
- bb->OldH2 = bb->height();
- Doc->setRedrawBounding(bb);
- bb->setItemName(currItem->itemName()+"+S"+ccounter.setNum(a));
- undoManager->setUndoEnabled(true);
- newGroupedItems.append(Doc->Items->takeAt(z));
- }
- }
- }
- else
- {
- for (uint ll=0; ll < currItem->textLayout.lines(); ++ll)
- {
- LineSpec ls = currItem->textLayout.line(ll);
- double CurX = ls.x;
- for (int a = ls.firstItem; a <= ls.lastItem; ++a)
- {
- pts.resize(0);
- x = 0.0;
- y = 0.0;
- GlyphLayout* glyphs = currItem->itemText.getGlyphs(a);
- const CharStyle& charStyle(currItem->itemText.charStyle(a));
-
- chstr = currItem->itemText.text(a,1);
- if ((chstr == SpecialChars::PARSEP) || (chstr == SpecialChars::OLD_NBSPACE))
- {
- if (chstr == SpecialChars::OLD_NBSPACE)
- CurX += glyphs->wide();
- continue;
- }
- if (chstr == SpecialChars::OBJECT)
- {
- if (currItem->itemText.hasObject(a))
- {
- ScriXmlDoc ss;
- Selection tempSelection(this, false);
- tempSelection.addItem(currItem->itemText.object(a), true);
- QString dataS = ss.WriteElem(Doc, &tempSelection);
- emit LoadElem(dataS, currItem->xPos(), currItem->yPos(), false, true, Doc, this);
- bb = Doc->Items->last();
- int z = Doc->Items->indexOf(bb);
- bb->setTextFlowMode(currItem->textFlowMode());
- bb->setSizeLocked(currItem->sizeLocked());
- bb->setLocked(currItem->locked());
- bb->setItemName(currItem->itemName()+"+"+ccounter.setNum(a));
- bb->setRotation(currItem->rotation());
- double textX = CurX + glyphs->xoffset;
- double textY = ls.y - bb->height();
- if (charStyle.baselineOffset() != 0)
- textY -= (charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0);
- if (currItem->imageFlippedH())
- textX = currItem->width() - textX - wide;
- if (currItem->imageFlippedV())
- textY = currItem->height() - textY + y - (bb->height() - y);
- FPoint npo(textX, textY, 0.0, 0.0, currItem->rotation(), 1.0, 1.0);
- bb->setXYPos(currItem->xPos() + npo.x(), currItem->yPos() + npo.y(), false);
- Doc->setRedrawBounding(bb);
- newGroupedItems.append(Doc->Items->takeAt(z));
- }
- CurX += glyphs->wide();
- continue;
- }
- if (chstr == SpecialChars::PAGENUMBER)
- chstr = currItem->ExpandToken(a);
- for (int cx = 0; cx < chstr.count(); cx++)
- {
- chstrex = chstr[cx];
- double chs = charStyle.fontSize();
- if (currItem->itemText.charStyle(a).effects() & ScStyle_SmallCaps)
- {
- if (chstrex.toUpper() != chstrex)
- {
- chs = qMax(static_cast<int>(chs * Doc->typographicPrefs().valueSmallCaps / 100), 1);
- chstrex = chstrex.toUpper();
- }
- }
- else if (currItem->itemText.charStyle(a).effects() & ScStyle_AllCaps)
- chstrex = chstrex.toUpper();
- double csi = static_cast<double>(chs) / 100.0;
- uint chr = chstrex.unicode();
- QTransform chma, chma6;
- uint gl = charStyle.font().char2CMap(chr);
- FPoint origin = charStyle.font().glyphOrigin(gl);
- x = origin.x() * csi * glyphs->scaleH;
- y = origin.y() * csi * glyphs->scaleV;
- if ((charStyle.effects() & ScStyle_Underline) || ((charStyle.effects() & ScStyle_UnderlineWords) && chstr.toUInt() != charStyle.font().char2CMap(QChar(' '))))
- {
- double st, lw;
- if ((charStyle.underlineOffset() != -1) || (charStyle.underlineWidth() != -1))
- {
- if (charStyle.underlineOffset() != -1)
- st = (charStyle.underlineOffset() / 1000.0) * (charStyle.font().descent(charStyle.fontSize() / 10.0));
- else
- st = charStyle.font().underlinePos(charStyle.fontSize() / 10.0);
- if (charStyle.underlineWidth() != -1)
- lw = (charStyle.underlineWidth() / 1000.0) * (charStyle.fontSize() / 10.0);
- else
- lw = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- else
- {
- st = charStyle.font().underlinePos(charStyle.fontSize() / 10.0);
- lw = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- if (charStyle.baselineOffset() != 0)
- st += (charStyle.fontSize() / 10.0) * glyphs->scaleV * (charStyle.baselineOffset() / 1000.0);
- uint z = Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, currItem->xPos(), currItem->yPos(), currItem->width(), currItem->height(), currItem->lineWidth(), currItem->lineColor(), currItem->fillColor());
- bb = Doc->Items->at(z);
- undoManager->setUndoEnabled(false);
- bb->setTextFlowMode(currItem->textFlowMode());
- bb->setSizeLocked(currItem->sizeLocked());
- bb->setLocked(currItem->locked());
- bb->NamedLStyle = currItem->NamedLStyle;
- bb->setItemName(currItem->itemName()+"+U"+ccounter.setNum(a));
- bb->setRotation(currItem->rotation());
- bb->PoLine.addQuadPoint(FPoint(0, 0), FPoint(0, 0), FPoint(glyphs->xadvance, 0), FPoint(glyphs->xadvance, 0));
- bb->setLineColor(charStyle.fillColor());
- bb->setLineShade(charStyle.fillShade());
- bb->setLineWidth(lw);
- FPoint tp2(getMinClipF(&bb->PoLine));
- bb->PoLine.translate(-tp2.x(), -tp2.y());
- FPoint tp(getMaxClipF(&bb->PoLine));
- bb->setWidthHeight(tp.x(), tp.y());
- bb->Clip = FlattenPath(bb->PoLine, bb->Segments);
- double textX = CurX;
- double textY = ls.y - st; // + glyphs->yoffset;
- if (charStyle.effects() & ScStyle_Subscript)
- textY += glyphs->yoffset;
- if (charStyle.baselineOffset() != 0)
- textY -= (charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0);
- if (a < currItem->itemText.length()-1)
- wide = charStyle.font().charWidth(chstr[0], charStyle.fontSize(), currItem->itemText.text(a+1));
- else
- wide = charStyle.font().charWidth(chstr[0], charStyle.fontSize());
- if (currItem->imageFlippedH())
- textX = currItem->width() - textX - bb->width() - x;
- if (currItem->imageFlippedV())
- textY = currItem->height() - textY + y - (bb->height() - y);
- FPoint npo(textX, textY, 0.0, 0.0, currItem->rotation(), 1.0, 1.0);
- bb->moveBy(npo.x(),npo.y());
- bb->ContourLine = bb->PoLine.copy();
- bb->ClipEdited = true;
- bb->FrameType = 3;
- bb->OldB2 = bb->width();
- bb->OldH2 = bb->height();
- Doc->setRedrawBounding(bb);
- undoManager->setUndoEnabled(true);
- newGroupedItems.append(Doc->Items->takeAt(z));
- }
- if (!chstrex.isSpace())
- {
- pts = charStyle.font().glyphOutline(gl);
- if (pts.size() < 4)
- continue;
- chma = QTransform();
- chma.scale(glyphs->scaleH * charStyle.fontSize() / 100.00, glyphs->scaleV * charStyle.fontSize() / 100.0);
- pts.map(chma);
- chma = QTransform();
- if (currItem->imageFlippedH() && (!currItem->reversed()))
- chma.scale(-1, 1);
- if (currItem->imageFlippedV())
- chma.scale(1, -1);
- undoManager->setUndoEnabled(false);
- pts.map(chma);
- if ((charStyle.effects() & ScStyle_Shadowed) && (charStyle.strokeColor() != CommonStrings::None))
- {
- double glxTr = charStyle.fontSize() * charStyle.shadowXOffset() / 10000.0;
- double glyTr = -charStyle.fontSize() * charStyle.shadowYOffset() / 10000.0;
- uint z = Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, currItem->xPos() + glxTr, currItem->yPos() + glyTr, currItem->width(), currItem->height(), currItem->lineWidth(), currItem->lineColor(), currItem->fillColor());
- bb = Doc->Items->at(z);
- undoManager->setUndoEnabled(false);
- bb->setTextFlowMode(currItem->textFlowMode());
- bb->setSizeLocked(currItem->sizeLocked());
- bb->setLocked(currItem->locked());
- bb->NamedLStyle = currItem->NamedLStyle;
- bb->setItemName(currItem->itemName()+"+Sh"+ccounter.setNum(a));
- bb->PoLine = pts.copy();
- bb->setRotation(currItem->rotation());
- bb->setFillColor(charStyle.strokeColor());
- bb->setFillShade(charStyle.strokeShade());
- bb->setLineColor(CommonStrings::None);
- bb->setLineShade(100);
- bb->setLineWidth(chs * charStyle.outlineWidth() / 10000.0);
- FPoint tp2(getMinClipF(&bb->PoLine));
- bb->PoLine.translate(-tp2.x(), -tp2.y());
- FPoint tp(getMaxClipF(&bb->PoLine));
- bb->setWidthHeight(tp.x(), tp.y());
- bb->Clip = FlattenPath(bb->PoLine, bb->Segments);
- double textX = CurX + glyphs->xoffset;
- double textY = ls.y; // + glyphs->yoffset;
- if (charStyle.effects() & (ScStyle_Subscript | ScStyle_Superscript))
- textY += glyphs->yoffset;
- chma6 = QTransform();
- if (charStyle.baselineOffset() != 0)
- textY -= (charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0);
- if (a < currItem->itemText.length()-1)
- wide = charStyle.font().charWidth(chstr[0], charStyle.fontSize(), currItem->itemText.text(a+1));
- else
- wide = charStyle.font().charWidth(chstr[0], charStyle.fontSize());
- if (currItem->imageFlippedH())
- textX = currItem->width() - textX - bb->width() - x;
- if (currItem->imageFlippedV())
- textY = currItem->height() - textY + y - (bb->height() - y);
- FPoint npo(textX+x, textY-y, 0.0, 0.0, currItem->rotation(), 1.0, 1.0);
- bb->moveBy(npo.x(),npo.y());
- bb->ContourLine = bb->PoLine.copy();
- bb->ClipEdited = true;
- bb->FrameType = 3;
- bb->OldB2 = bb->width();
- bb->OldH2 = bb->height();
- Doc->setRedrawBounding(bb);
- undoManager->setUndoEnabled(true);
- newGroupedItems.append(Doc->Items->takeAt(z));
- }
- uint z = Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, currItem->xPos(), currItem->yPos(), currItem->width(), currItem->height(), currItem->lineWidth(), currItem->lineColor(), currItem->fillColor());
- bb = Doc->Items->at(z);
- //bb->setTextFlowsAroundFrame(currItem->textFlowsAroundFrame());
- //bb->setTextFlowUsesBoundingBox(currItem->textFlowUsesBoundingBox());
- bb->setTextFlowMode(currItem->textFlowMode());
- bb->setSizeLocked(currItem->sizeLocked());
- bb->setLocked(currItem->locked());
- bb->NamedLStyle = currItem->NamedLStyle;
- bb->setItemName(currItem->itemName()+"+"+ccounter.setNum(a));
- bb->PoLine = pts.copy();
- bb->setRotation(currItem->rotation());
- bb->setFillColor(charStyle.fillColor());
- bb->setFillShade(charStyle.fillShade());
- if (currItem->itemText.charStyle(a).effects() & ScStyle_Outline)
- {
- bb->setLineColor(charStyle.strokeColor());
- bb->setLineShade(charStyle.strokeShade());
- }
- else
- {
- bb->setLineColor(CommonStrings::None);
- bb->setLineShade(100);
- }
- bb->setLineWidth(chs * charStyle.outlineWidth() / 10000.0);
- FPoint tp2(getMinClipF(&bb->PoLine));
- bb->PoLine.translate(-tp2.x(), -tp2.y());
- FPoint tp(getMaxClipF(&bb->PoLine));
- bb->setWidthHeight(tp.x(), tp.y());
- bb->Clip = FlattenPath(bb->PoLine, bb->Segments);
- double textX = CurX + glyphs->xoffset;
- double textY = ls.y; // + glyphs->yoffset;
- if (charStyle.effects() & (ScStyle_Subscript | ScStyle_Superscript))
- textY += glyphs->yoffset;
- chma6 = QTransform();
- if (charStyle.baselineOffset() != 0)
- textY -= (charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0);
- if (a < currItem->itemText.length()-1)
- wide = charStyle.font().charWidth(chstr[0], charStyle.fontSize(), currItem->itemText.text(a+1));
- else
- wide = charStyle.font().charWidth(chstr[0], charStyle.fontSize());
- if (currItem->imageFlippedH())
- textX = currItem->width() - textX - bb->width() - x;
- if (currItem->imageFlippedV())
- textY = currItem->height() - textY + y - (bb->height() - y);
- FPoint npo(textX+x, textY-y, 0.0, 0.0, currItem->rotation(), 1.0, 1.0);
- bb->moveBy(npo.x(),npo.y());
- bb->ContourLine = bb->PoLine.copy();
- bb->ClipEdited = true;
- bb->FrameType = 3;
- bb->OldB2 = bb->width();
- bb->OldH2 = bb->height();
- Doc->setRedrawBounding(bb);
- undoManager->setUndoEnabled(true);
- newGroupedItems.append(Doc->Items->takeAt(z));
- }
- if (charStyle.effects() & ScStyle_Strikethrough)
- {
- double st, lw;
- if ((charStyle.strikethruOffset() != -1) || (charStyle.strikethruWidth() != -1))
- {
- if (charStyle.strikethruOffset() != -1)
- st = (charStyle.strikethruOffset() / 1000.0) * (charStyle.font().ascent(charStyle.fontSize() / 10.0));
- else
- st = charStyle.font().strikeoutPos(charStyle.fontSize() / 10.0);
- if (charStyle.strikethruWidth() != -1)
- lw = (charStyle.strikethruWidth() / 1000.0) * (charStyle.fontSize() / 10.0);
- else
- lw = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- else
- {
- st = charStyle.font().strikeoutPos(charStyle.fontSize() / 10.0);
- lw = qMax(charStyle.font().strokeWidth(charStyle.fontSize() / 10.0), 1.0);
- }
- if (charStyle.baselineOffset() != 0)
- st += (charStyle.fontSize() / 10.0) * glyphs->scaleV * (charStyle.baselineOffset() / 1000.0);
- uint z = Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, currItem->xPos(), currItem->yPos(), currItem->width(), currItem->height(), currItem->lineWidth(), currItem->lineColor(), currItem->fillColor());
- bb = Doc->Items->at(z);
- undoManager->setUndoEnabled(false);
- bb->setTextFlowMode(currItem->textFlowMode());
- bb->setSizeLocked(currItem->sizeLocked());
- bb->setLocked(currItem->locked());
- bb->NamedLStyle = currItem->NamedLStyle;
- bb->setItemName(currItem->itemName()+"+S"+ccounter.setNum(a));
- bb->setRotation(currItem->rotation());
- bb->PoLine.addQuadPoint(FPoint(0, 0), FPoint(0, 0), FPoint(glyphs->xadvance, 0), FPoint(glyphs->xadvance, 0));
- bb->setLineColor(charStyle.fillColor());
- bb->setLineShade(charStyle.fillShade());
- bb->setLineWidth(lw);
- FPoint tp2(getMinClipF(&bb->PoLine));
- bb->PoLine.translate(-tp2.x(), -tp2.y());
- FPoint tp(getMaxClipF(&bb->PoLine));
- bb->setWidthHeight(tp.x(), tp.y());
- bb->Clip = FlattenPath(bb->PoLine, bb->Segments);
- double textX = CurX;
- double textY = ls.y - st + glyphs->yoffset;
- if (charStyle.baselineOffset() != 0)
- textY -= (charStyle.fontSize() / 10.0) * (charStyle.baselineOffset() / 1000.0);
- if (a < currItem->itemText.length()-1)
- wide = charStyle.font().charWidth(chstr[0], charStyle.fontSize(), currItem->itemText.text(a+1));
- else
- wide = charStyle.font().charWidth(chstr[0], charStyle.fontSize());
- if (currItem->imageFlippedH())
- textX = currItem->width() - textX - bb->width() - x;
- if (currItem->imageFlippedV())
- textY = currItem->height() - textY + y - (bb->height() - y);
- FPoint npo(textX, textY, 0.0, 0.0, currItem->rotation(), 1.0, 1.0);
- bb->moveBy(npo.x(),npo.y());
- bb->ContourLine = bb->PoLine.copy();
- bb->ClipEdited = true;
- bb->FrameType = 3;
- bb->OldB2 = bb->width();
- bb->OldH2 = bb->height();
- Doc->setRedrawBounding(bb);
- undoManager->setUndoEnabled(true);
- newGroupedItems.append(Doc->Items->takeAt(z));
- }
- CurX += glyphs->wide();
- }
- }
- }
- }
+
+ TextToPathPainter p(this, currItem);
+ currItem->textLayout.render(&p);
if ((currItem->asPathText()) && (currItem->PoShow))
{
uint z = Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, currItem->xPos(), currItem->yPos(), currItem->width(), currItem->height(), currItem->lineWidth(), CommonStrings::None, currItem->lineColor());
Modified: trunk/Scribus/scribus/sctextstruct.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/sctextstruct.cpp
==============================================================================
--- trunk/Scribus/scribus/sctextstruct.cpp (original)
+++ trunk/Scribus/scribus/sctextstruct.cpp Wed Mar 23 20:21:36 2016
@@ -13,22 +13,19 @@
#include "pageitem.h"
#include "scribusdoc.h"
-void GlyphLayout::growWithTabLayout()
+
+qreal GlyphRun::width() const
{
- if (more)
- shrink();
- more = new TabLayout();
+ qreal width = 0;
+ foreach (const GlyphLayout gl, m_glyphs)
+ {
+ width += gl.xadvance * gl.scaleH;
+ }
+ return width;
}
ScText::~ScText()
{
- // delete the linked list if present
- GlyphLayout * more = glyph.more;
- while (more) {
- glyph.more = glyph.more->more;
- delete more;
- more = glyph.more;
- }
if (parstyle)
delete parstyle;
parstyle = NULL;
Modified: trunk/Scribus/scribus/sctextstruct.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/sctextstruct.h
==============================================================================
--- trunk/Scribus/scribus/sctextstruct.h (original)
+++ trunk/Scribus/scribus/sctextstruct.h Wed Mar 23 20:21:36 2016
@@ -39,17 +39,21 @@
// from charstlye.h ScStyleFlags
enum LayoutFlags {
ScLayout_None = 0,
+ ScLayout_BulletNum = 1, // new: marks list layout glyphs
+ ScLayout_FixedSpace = 2, // new: marks a fixed space
+ ScLayout_ExpandingSpace= 4, // new: marks an expanding space
+ ScLayout_ImplicitSpace = 8, // new: marks an implicit space
+ ScLayout_TabLeaders = 16, // new: marks a tab with fillchar
ScLayout_HyphenationPossible=128, //Hyphenation possible here (Soft Hyphen)
ScLayout_DropCap = 2048,
- ScLayout_SuppressSpace = 4096,//internal use in PageItem (Suppresses spaces when in Block alignment)
- ScLayout_SoftHyphenVisible=8192, //Soft Hyphen visible at line end
- ScLayout_StartOfLine = 16384
+ ScLayout_SuppressSpace = 4096, //internal use in PageItem (Suppresses spaces when in Block alignment)
+ ScLayout_SoftHyphenVisible=8192, //Soft Hyphen visible at line end
+ ScLayout_StartOfLine = 16384 //set for start of line
};
/**
* This struct stores a positioned glyph. This is the result of the layout process.
- * If a char gets translated to more than one glyph, a linked list is built.
*/
struct SCRIBUS_API GlyphLayout {
float xadvance;
@@ -59,50 +63,42 @@
double scaleV;
double scaleH;
uint glyph;
- GlyphLayout* more;
GlyphLayout() : xadvance(0.0f), yadvance(0.0f), xoffset(0.0f), yoffset(0.0f),
- scaleV(1.0), scaleH(1.0), glyph(0), more(NULL)
+ scaleV(1.0), scaleH(1.0), glyph(0) //, more(NULL)
{ }
- GlyphLayout(const GlyphLayout& o) : xadvance(o.xadvance), yadvance(o.yadvance), xoffset(o.xoffset), yoffset(o.yoffset),
- scaleV(o.scaleH), scaleH(o.scaleV), glyph(o.glyph), more(NULL)
- { }
- virtual ~GlyphLayout()
- { }
- double wide() const
- {
- double ret = 0;
- for(const GlyphLayout* p=this; p; p=p->more)
- ret += p->xadvance;
- return ret;
- }
- GlyphLayout* last()
- {
- if (more)
- return more->last();
- else
- return this;
- }
- void shrink()
- {
- if (more) {
- more->shrink();
- delete more;
- more = NULL;
- }
- }
- void grow()
- {
- if (!more) {
- more = new GlyphLayout();
- }
- }
- virtual void growWithTabLayout();
};
-struct SCRIBUS_API TabLayout : public GlyphLayout
+
+class GlyphRun
{
- QChar fillChar;
+ const CharStyle* m_style;
+ LayoutFlags m_flags;
+ QList<GlyphLayout> m_glyphs;
+ int m_firstChar;
+ int m_lastChar;
+ PageItem* m_object;
+
+public:
+ GlyphRun(const CharStyle* style, LayoutFlags flags, int first, int last, PageItem* o)
+ : m_style(style)
+ , m_flags(flags)
+ , m_firstChar(first)
+ , m_lastChar(last)
+ , m_object(o)
+ {}
+
+ const CharStyle& style() const { return *m_style; }
+ bool hasFlag(LayoutFlags f) const { return (m_flags & f) == f; }
+ void setFlag(LayoutFlags f) { m_flags = static_cast<LayoutFlags>(m_flags | f); }
+ void clearFlag(LayoutFlags f) { m_flags = static_cast<LayoutFlags>(m_flags & ~f); }
+
+ QList<GlyphLayout>& glyphs() { return m_glyphs; }
+ const QList<GlyphLayout> glyphs() const { return m_glyphs; }
+ int firstChar() const { return m_firstChar; }
+ int lastChar() const { return m_lastChar; }
+ qreal width() const;
+ PageItem* object() const { return m_object; }
};
@@ -110,28 +106,18 @@
{
public:
ParagraphStyle* parstyle; // only for parseps
- GlyphLayout glyph;
int embedded;
Mark* mark;
QChar ch;
- ScText() :
+ ScText() :
CharStyle(),
- parstyle(NULL), glyph(),
+ parstyle(NULL),
embedded(0), mark(NULL), ch() {}
- ScText(const ScText& other) :
+ ScText(const ScText& other) :
CharStyle(other),
- parstyle(NULL), glyph(other.glyph),
+ parstyle(NULL),
embedded(other.embedded), mark(NULL), ch(other.ch)
{
- glyph.more = NULL;
- GlyphLayout *layout = &glyph;
- const GlyphLayout *otherLayout = &other.glyph;
- while (otherLayout->more)
- {
- layout->more = new GlyphLayout(*otherLayout->more);
- layout = layout->more;
- otherLayout = otherLayout->more;
- }
if (other.parstyle)
parstyle = new ParagraphStyle(*other.parstyle);
if (other.mark)
Modified: trunk/Scribus/scribus/text/CMakeLists.txt
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/text/CMakeLists.txt
==============================================================================
--- trunk/Scribus/scribus/text/CMakeLists.txt (original)
+++ trunk/Scribus/scribus/text/CMakeLists.txt Wed Mar 23 20:21:36 2016
@@ -2,21 +2,26 @@
${CMAKE_SOURCE_DIR}
${CMAKE_SOURCE_DIR}/scribus
${FREETYPE_INCLUDE_DIRS}
+ ${CAIRO_INCLUDE_DIRS}
)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_CXX_FLAGS_FPIC}")
SET(SCRIBUS_TEXT_MOC_CLASSES
storytext.h
+ boxes.h
)
SET(SCRIBUS_TEXT_LIB_SOURCES
specialchars.cpp
storytext.cpp
textlayout.cpp
+ textlayoutpainter.cpp
+ screenpainter.cpp
sctext_shared.cpp
fsize.cpp
frect.cpp
+ boxes.cpp
)
QT5_WRAP_CPP(SCRIBUS_TEXT_MOC_SOURCES ${SCRIBUS_TEXT_MOC_CLASSES})
Modified: trunk/Scribus/scribus/text/storytext.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/text/storytext.cpp
==============================================================================
--- trunk/Scribus/scribus/text/storytext.cpp (original)
+++ trunk/Scribus/scribus/text/storytext.cpp Wed Mar 23 20:21:36 2016
@@ -710,32 +710,6 @@
}
return result;
-}
-
-
-GlyphLayout* StoryText::getGlyphs(int pos)
-{
- if (pos < 0)
- pos += length();
-
- assert(pos >= 0);
- assert(pos < length());
- // WTF ?! removing this assert as it gives crashes when Scale goes below 51 %
-// assert((this->d->at(pos)->glyph).scaleH > 0.5);
- return &(this->d->at(pos)->glyph);
-}
-
-const GlyphLayout* StoryText::getGlyphs(int pos) const
-{
- if (pos < 0)
- pos += length();
-
- assert(pos >= 0);
- assert(pos < length());
-
- // WTF ?! removing this assert as it gives crashes when Scale goes below 51 %
-// assert( (const_cast<StoryText *>(this)->d->at(pos)->glyph).scaleH > 0.5);
- return &(const_cast<StoryText *>(this)->d->at(pos)->glyph);
}
QChar StoryText::text() const
Modified: trunk/Scribus/scribus/text/storytext.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/text/storytext.h
==============================================================================
--- trunk/Scribus/scribus/text/storytext.h (original)
+++ trunk/Scribus/scribus/text/storytext.h Wed Mar 23 20:21:36 2016
@@ -231,8 +231,6 @@
// layout helpers
- GlyphLayout* getGlyphs(int pos);
- const GlyphLayout* getGlyphs(int pos) const;
LayoutFlags flags(int pos) const;
bool hasFlag(int pos, LayoutFlags flag) const;
void setFlag(int pos, LayoutFlags flag);
Modified: trunk/Scribus/scribus/text/textlayout.cpp
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/text/textlayout.cpp
==============================================================================
--- trunk/Scribus/scribus/text/textlayout.cpp (original)
+++ trunk/Scribus/scribus/text/textlayout.cpp Wed Mar 23 20:21:36 2016
@@ -23,6 +23,8 @@
#include "specialchars.h"
#include "storytext.h"
#include "textlayout.h"
+#include "textlayoutpainter.h"
+#include "boxes.h"
@@ -32,22 +34,49 @@
m_story = text;
m_frame = frame;
- m_firstInFrame = 0;
- m_lastInFrame = -1;
m_validLayout = false;
m_magicX = 0.0;
m_lastMagicPos = -1;
-}
-
+
+ m_box = new GroupBox(Box::D_Horizontal);
+}
+
+TextLayout::~TextLayout()
+{
+ delete m_box;
+}
uint TextLayout::lines() const
{
- return m_lines.count();
-}
-
-const LineSpec& TextLayout::line(uint i) const
-{
- return m_lines[i];
+ uint count = 0;
+ foreach (const Box *box, m_box->boxes())
+ {
+ count += box->boxes().count();
+ }
+ return count;
+}
+
+const LineBox* TextLayout::line(uint i) const
+{
+ uint count = 0;
+ foreach (const Box *box, m_box->boxes())
+ {
+ if (i < count + box->boxes().count())
+ return dynamic_cast<const LineBox*>(box->boxes()[i - count]);
+ count += box->boxes().count();
+ }
+ assert(false);
+ return NULL;
+}
+
+const Box* TextLayout::box() const
+{
+ return m_box;
+}
+
+Box* TextLayout::box()
+{
+ return m_box;
}
const PathData& TextLayout::point(int pos) const
@@ -63,45 +92,73 @@
}
-void TextLayout::appendLine(const LineSpec& ls)
- {
- assert( ls.firstItem >= 0 );
- assert( ls.firstItem < story()->length() );
- assert( ls.lastItem >= 0 && ls.firstItem - ls.lastItem < 1 );
- assert( ls.lastItem < story()->length() );
- m_lines.append(ls);
- if (m_lastInFrame < m_firstInFrame) {
- m_firstInFrame = ls.firstItem;
- m_lastInFrame = ls.lastItem;
- }
- else {
- m_firstInFrame = qMin(m_firstInFrame, ls.firstItem);
- m_lastInFrame = qMax(m_lastInFrame, ls.lastItem);
- }
- }
+void TextLayout::appendLine(LineBox* ls)
+{
+ assert( ls->firstChar() >= 0 );
+ assert( ls->firstChar() < story()->length() );
+ assert( ls->lastChar() < story()->length() );
+
+ // HACK: the ascent set by PageItem_TextFrame::layout()
+ // is useless, we reset it again based on the y position
+ ls->setAscent(ls->y() - m_box->boxes().last()->naturalHeight());
+ dynamic_cast<GroupBox*>(m_box->boxes().last())->addBox(ls);
+}
// Remove the last line from the list. Used when we need to backtrack on the layouting.
void TextLayout::removeLastLine ()
{
- if (m_lines.isEmpty()) return;
- LineSpec last = m_lines.takeLast ();
- if (m_lines.isEmpty()) {
- clear();
- return;
- }
- // fix lastFrameItem
- if (m_lastInFrame != last.lastItem) return;
- m_lastInFrame = m_lines.last().lastItem;
-}
-
-
+ m_box->removeBox(m_box->boxes().count() - 1);
+}
+
+void TextLayout::render(TextLayoutPainter *p, PageItem *item)
+{
+ p->save();
+ m_box->render(p, item);
+ p->restore();
+}
+
+void TextLayout::renderBackground(TextLayoutPainter *p)
+{
+ foreach (const Box* column, m_box->boxes())
+ {
+ const ParagraphStyle& style = m_story->paragraphStyle(column->firstChar());
+ if (style.backgroundColor() != CommonStrings::None)
+ {
+ p->save();
+ TextLayoutColor backColor(style.backgroundColor(), style.backgroundShade());
+ p->setFillColor(backColor);
+ p->setStrokeColor(backColor);
+ p->drawRect(column->bbox());
+ p->restore();
+ }
+ }
+}
+
+void TextLayout::render(TextLayoutPainter *p)
+{
+ p->save();
+ m_box->render(p);
+ p->restore();
+}
+
+void TextLayout::addColumn(double colLeft, double colWidth)
+{
+ GroupBox *newBox = new GroupBox(Box::D_Vertical);
+ newBox->moveTo(colLeft, 0.0);
+ newBox->setWidth(colWidth);
+ newBox->setAscent(m_frame->height());
+ m_box->addBox(newBox);
+
+ // Update the box width and height, any better place to do this?
+ m_box->setAscent(m_frame->height());
+ m_box->setWidth(m_frame->width());
+}
void TextLayout::clear()
{
- m_lines.clear();
+ delete m_box;
+ m_box = new GroupBox(Box::D_Horizontal);
m_path.clear();
- m_firstInFrame = 0;
- m_lastInFrame = -1;
if (m_frame->asPathText() != NULL)
m_path.resize(story()->length());
}
@@ -114,198 +171,154 @@
int TextLayout::startOfLine(int pos) const
{
- for (int i=0; i < m_lines.count(); ++i) {
- const LineSpec & ls(m_lines.at(i));
- if (ls.firstItem <= pos && pos <= ls.lastItem)
- return ls.firstItem;
+ for (uint i=0; i < lines(); ++i) {
+ const LineBox* ls = line(i);
+ if (ls->firstChar() <= pos && pos <= ls->lastChar())
+ return ls->firstChar();
}
return 0;
}
int TextLayout::endOfLine(int pos) const
{
- for (int i=0; i < m_lines.count(); ++i) {
- const LineSpec & ls(m_lines.at(i));
- if (ls.firstItem <= pos && pos <= ls.lastItem)
- return story()->text(ls.lastItem) == SpecialChars::PARSEP ? ls.lastItem :
- story()->text(ls.lastItem) == ' ' ? ls.lastItem : ls.lastItem + 1;
+ for (uint i=0; i < lines(); ++i) {
+ const LineBox* ls = line(i);
+ if (ls->containsPos(pos))
+ return story()->text(ls->lastChar()) == SpecialChars::PARSEP ? ls->lastChar() :
+ story()->text(ls->lastChar()) == ' ' ? ls->lastChar() : ls->lastChar() + 1;
}
return story()->length();
}
int TextLayout::prevLine(int pos) const
{
- for (int i=0; i < m_lines.count(); ++i)
+ for (uint i=0; i < lines(); ++i)
{
// find line for pos
- const LineSpec & ls(m_lines.at(i));
- if (ls.firstItem <= pos && pos <= ls.lastItem)
+ const LineBox* ls = line(i);
+ if (ls->containsPos(pos))
{
if (i == 0)
return startOfLine(pos);
// find current xpos
- qreal xpos = 0.0;
- for (int j = ls.firstItem; j < pos; ++j)
- xpos += story()->getGlyphs(j)->wide();
+ qreal xpos = ls->positionToPoint(pos).x1();
if (pos != m_lastMagicPos || xpos > m_magicX)
m_magicX = xpos;
- const LineSpec & ls2(m_lines.at(i-1));
+
+ const LineBox* ls2 = line(i-1);
// find new cpos
- xpos = 0.0;
- for (int j = ls2.firstItem; j <= ls2.lastItem; ++j)
+ for (int j = ls2->firstChar(); j <= ls2->lastChar(); ++j)
{
- xpos += story()->getGlyphs(j)->wide();
+ xpos = ls2->positionToPoint(j).x1();
if (xpos > m_magicX) {
m_lastMagicPos = j;
return j;
}
}
- m_lastMagicPos = ls2.lastItem;
- return ls2.lastItem;
- }
- }
- return m_firstInFrame;
+ m_lastMagicPos = ls2->lastChar();
+ return ls2->lastChar();
+ }
+ }
+ return m_box->firstChar();
}
int TextLayout::nextLine(int pos) const
{
- for (int i=0; i < m_lines.count(); ++i)
+ for (uint i=0; i < lines(); ++i)
{
// find line for pos
- const LineSpec & ls(m_lines.at(i));
- if (ls.firstItem <= pos && pos <= ls.lastItem)
- {
- if (i+1 == m_lines.count())
+ const LineBox* ls = line(i);
+ if (ls->containsPos(pos))
+ {
+ if (i+1 == lines())
return endOfLine(pos);
// find current xpos
- qreal xpos = 0.0;
- for (int j = ls.firstItem; j < pos; ++j)
- xpos += story()->getGlyphs(j)->wide();
+ qreal xpos = ls->positionToPoint(pos).x1();
+
if (pos != m_lastMagicPos || xpos > m_magicX)
m_magicX = xpos;
- const LineSpec & ls2(m_lines.at(i+1));
+
+ const LineBox* ls2 = line(i+1);
// find new cpos
- xpos = 0.0;
- for (int j = ls2.firstItem; j <= ls2.lastItem; ++j)
+ for (int j = ls2->firstChar(); j <= ls2->lastChar(); ++j)
{
- xpos += story()->getGlyphs(j)->wide();
+ xpos = ls2->positionToPoint(j).x1();
if (xpos > m_magicX) {
m_lastMagicPos = j;
return j;
}
}
- m_lastMagicPos = ls2.lastItem + 1;
- return ls2.lastItem + 1;
- }
- }
- return m_lastInFrame;
+ m_lastMagicPos = ls2->lastChar() + 1;
+ return ls2->lastChar() + 1;
+ }
+ }
+ return m_box->lastChar();
}
int TextLayout::startOfFrame() const
{
- return m_firstInFrame;
+ return m_box->firstChar();
}
int TextLayout::endOfFrame() const
{
- return m_lastInFrame + 1;
-}
-
-
-int TextLayout::screenToPosition(FPoint coord) const
-{
- qreal maxx = coord.x() - 1.0;
- for (unsigned int i=0; i < lines(); ++i)
- {
- LineSpec ls = line(i);
-// qDebug() << QString("screenToPosition: (%1,%2) -> y %3 - %4 + %5").arg(coord.x()).arg(coord.y()).arg(ls.y).arg(ls.ascent).arg(ls.descent);
- if (ls.y + ls.descent < coord.y())
- continue;
- qreal xpos = ls.x;
- for (int j = ls.firstItem; j <= ls.lastItem; ++j)
- {
-// qDebug() << QString("screenToPosition: (%1,%2) -> x %3 + %4").arg(coord.x()).arg(coord.y()).arg(xpos).arg(item(j)->glyph.wide());
- qreal width = story()->getGlyphs(j)->wide();
- xpos += width;
- if (xpos >= coord.x())
+ return m_box->lastChar() + 1;
+}
+
+
+int TextLayout::pointToPosition(QPointF coord) const
+{
+ int position = m_box->pointToPosition(coord);
+ if (position == m_box->lastChar())
+ position += 1;
+ return position;
+}
+
+
+QLineF TextLayout::positionToPoint(int pos) const
+{
+ QLineF result;
+
+ result = m_box->positionToPoint(pos);
+ if (result.isNull())
+ {
+ qreal x, y1, y2;
+ if (lines() > 0)
+ {
+ // TODO: move this branch to GroupBox::positionToPoint()
+ // last glyph box in last line
+ Box* column = m_box->boxes().last();
+ Box* line = column->boxes().last();
+ Box* glyph = line->boxes().last();
+ QChar ch = story()->text(glyph->lastChar());
+ if (ch == SpecialChars::PARSEP || ch == SpecialChars::LINEBREAK)
{
- if (story()->hasObject(j))
- return j;
- else
- return xpos - width/2 > coord.x() ? j : j+1;
+ // last character is a newline, draw the cursor on the next line.
+ x = 1;
+ y1 = line->y() + line->height();
+ y2 = y1 + line->height();
}
- }
- if (xpos > maxx)
- maxx = xpos;
- if (xpos + 1.0 > coord.x()) // allow 1pt after end of line
- return ls.lastItem + 1;
- else if (coord.x() <= ls.x + ls.width) // last line of paragraph?
- return ((ls.lastItem == m_lastInFrame) ? (ls.lastItem + 1) : ls.lastItem);
- else if (xpos < ls.x + 0.01 && maxx >= coord.x()) // check for empty line
- return ls.firstItem;
- }
- return qMax(m_lastInFrame+1, m_firstInFrame);
-}
-
-
-FRect TextLayout::boundingBox(int pos, uint len) const
-{
- FRect result;
- LineSpec ls;
- for (uint i=0; i < lines(); ++i)
- {
- ls = line(i);
- if (ls.lastItem < pos)
- continue;
- if (ls.firstItem <= pos) {
- /*
- //if (ls.lastItem == pos && (item(pos)->effects() & ScLayout_SuppressSpace) )
+ else
{
- if (i+1 < lines())
- {
- ls = line(i+1);
- result.setRect(ls.x, ls.y - ls.ascent, 1, ls.ascent + ls.descent);
- }
- else
- {
- ls = line(lines()-1);
- const ParagraphStyle& pstyle(paragraphStyle(pos));
- result.setRect(ls.x, ls.y + pstyle.lineSpacing() - ls.ascent, 1, ls.ascent + ls.descent);
- }
+ // draw the cursor at the end of last line.
+ x = line->x() + glyph->x() + glyph->width();
+ y1 = line->y();
+ y2 = y1 + line->height();
}
- else */
- {
- qreal xpos = ls.x;
- for (int j = ls.firstItem; j < pos; ++j)
- {
- if (story()->hasObject(j))
- xpos += (story()->object(j)->width() + story()->object(j)->lineWidth()) * story()->getGlyphs(j)->scaleH;
- else
- xpos += story()->getGlyphs(j)->wide();
- }
- qreal finalw = 1;
- if (story()->hasObject(pos))
- finalw = (story()->object(pos)->width() + story()->object(pos)->lineWidth()) * story()->getGlyphs(pos)->scaleH;
- else
- finalw = story()->getGlyphs(pos)->wide();
- const CharStyle& cs(story()->charStyle(pos));
- qreal desc = -cs.font().descent(cs.fontSize() / 10.0);
- qreal asce = cs.font().ascent(cs.fontSize() / 10.0);
- result.setRect(xpos, ls.y - asce, pos < story()->length()? finalw : 1, desc+asce);
- }
- return result;
- }
- }
- const ParagraphStyle& pstyle(story()->paragraphStyle(qMin(pos, story()->length()))); // rather the trailing style than a segfault.
- if (lines() > 0)
- {
- ls = line(lines()-1);
- result.setRect(ls.x, ls.y + pstyle.lineSpacing() - ls.ascent, 1, ls.ascent + ls.descent);
- }
- else
- {
- result.setRect(1, 1, 1, pstyle.lineSpacing());
- }
+ result.setLine(x, y1, x, y2);
+ result.translate(column->x(), column->y());
+ }
+ else
+ {
+ // rather the trailing style than a segfault.
+ const ParagraphStyle& pstyle(story()->paragraphStyle(qMin(pos, story()->length())));
+ x = 1;
+ y1 = 0;
+ y2 = pstyle.lineSpacing();
+ result.setLine(x, y1, x, y2);
+ }
+ result.translate(m_box->x(), m_box->y());
+ }
+
return result;
}
-
Modified: trunk/Scribus/scribus/text/textlayout.h
URL: http://scribus.net/websvn/diff.php?repname=Scribus&rev=21107&path=/trunk/Scribus/scribus/text/textlayout.h
==============================================================================
--- trunk/Scribus/scribus/text/textlayout.h (original)
+++ trunk/Scribus/scribus/text/textlayout.h Wed Mar 23 20:21:36 2016
@@ -26,22 +26,10 @@
#include "sctextstruct.h"
class StoryText;
-
-struct LineSpec
-{
- qreal x;
- qreal y;
- qreal width;
- qreal ascent;
- qreal descent;
- qreal colLeft;
-
- int firstItem;
- int lastItem;
- qreal naturalWidth;
- bool isFirstLine;
- qreal height;
-};
+class Box;
+class GroupBox;
+class LineBox;
+class TextLayoutPainter;
struct PathData
{
@@ -61,13 +49,16 @@
{
public:
TextLayout(StoryText* text, PageItem* frame);
+ ~TextLayout();
bool overflows() const;
StoryText* story() { return m_story; }
const StoryText* story() const { return m_story; }
void setStory(StoryText* story);
-
+ void render(TextLayoutPainter *p, PageItem *item);
+ void render(TextLayoutPainter *p);
+ void renderBackground(TextLayoutPainter *p);
int startOfLine(int pos) const;
int endOfLine(int pos) const;
int prevLine(int pos) const;
@@ -75,17 +66,20 @@
int startOfFrame() const;
int endOfFrame() const;
- int screenToPosition(FPoint coord) const;
- FRect boundingBox(int pos, uint len = 1) const;
+ int pointToPosition(QPointF coord) const;
+ QLineF positionToPoint(int pos) const;
uint lines() const;
- const LineSpec& line(uint i) const;
+ const LineBox* line(uint i) const;
+ const Box* box() const;
+ Box* box();
const PathData& point(int pos) const;
PathData& point(int pos);
- void appendLine(const LineSpec& ls);
+ void appendLine(LineBox* ls);
void removeLastLine ();
+ void addColumn(double colLeft, double colWidth);
void clear();
@@ -94,10 +88,8 @@
StoryText* m_story;
PageItem* m_frame;
+ GroupBox* m_box;
- int m_firstInFrame;
- int m_lastInFrame;
- QList<LineSpec> m_lines;
QVector<PathData> m_path;
bool m_validLayout;
mutable qreal m_magicX;
More information about the scribus-commit
mailing list