View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0016126 | Scribus | Import / Export | public | 2020-06-03 16:35 | 2020-06-21 12:40 |
Reporter | oliverthered | Assigned To | jghali | ||
Priority | normal | Severity | feature | Reproducibility | always |
Status | closed | Resolution | duplicate | ||
Platform | any | OS | any | OS Version | any |
Product Version | 1.5.6.svn | ||||
Summary | 0016126: refactor getChar so that it can be used for importing text as well as drawing vector characters | ||||
Description | refactor getChar so that it can be used for importing text as well as drawing vector characters, this involved separating out setFillAndStrokeForPDF from the function, some checks to see if we should be drawing vectors or collating text and implementing a new addChar function to collate text for textframes. | ||||
Steps To Reproduce | start scribus try to import an svg file that contains text | ||||
Additional Information | defaulting to importing vectors for now. this needs to have an oprion for text or vectors in the gui and override the default. see diff attached | ||||
Tags | import, PDF, pdf import, vectorised fonts | ||||
Patch | No | ||||
|
addChar.diff (15,269 bytes)
scribus/plugins/import/pdf/slaoutput.cpp | 222 +++++++++++++++++++++++-------- scribus/plugins/import/pdf/slaoutput.h | 8 +- 2 files changed, 171 insertions(+), 59 deletions(-) diff --git a/scribus/plugins/import/pdf/slaoutput.cpp b/scribus/plugins/import/pdf/slaoutput.cpp index 05f17ce76..c98d3d9ec 100644 --- a/scribus/plugins/import/pdf/slaoutput.cpp +++ b/scribus/plugins/import/pdf/slaoutput.cpp @@ -3016,7 +3016,7 @@ void SlaOutputDev::markPoint(POPPLER_CONST char *name, Dict *properties) beginMarkedContent(name, properties); } -void SlaOutputDev::updateFont(GfxState *state) +void SlaOutputDev::updateFontForVector(GfxState *state) { GfxFont *gfxFont; GfxFontLoc *fontLoc; @@ -3252,11 +3252,16 @@ err1: fontsrc->unref(); } -void SlaOutputDev::drawChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, int nBytes, POPPLER_CONST_082 Unicode *u, int uLen) +void SlaOutputDev::drawChar(GfxState* state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, int nBytes, POPPLER_CONST_082 Unicode* u, int uLen) { -// qDebug() << "SlaOutputDev::drawChar code:" << code << "bytes:" << nBytes << "Unicode:" << u << "ulen:" << uLen << "render:" << state->getRender(); + qDebug() << "SlaOutputDev::drawChar x:" << x << "y:" << y << "dx:" << dx << "dy" << dy << "code:" << code; + //for importing text as glyphs double x1, y1, x2, y2; - updateFont(state); + //if (import_text_as_vectors) { + updateFontForVector(state); //this sets m_font a splashfont + //TODO: add support for fonts when importing pdf text + //_updateFontForText(state); //and this sets font_style and has a lkot more detail about the font, both work on the same details from gfxfont + if (!m_font) return; @@ -3276,7 +3281,7 @@ void SlaOutputDev::drawChar(GfxState *state, double x, double y, double dx, doub return; if (textRenderingMode < 8) { - SplashPath * fontPath; + SplashPath* fontPath; fontPath = m_font->getGlyphPath(code); if (fontPath) { @@ -3287,7 +3292,7 @@ void SlaOutputDev::drawChar(GfxState *state, double x, double y, double dx, doub Guchar f; fontPath->getPoint(i, &x1, &y1, &f); if (f & splashPathFirst) - qPath.moveTo(x1,y1); + qPath.moveTo(x1, y1); else if (f & splashPathCurve) { double x3, y3; @@ -3295,73 +3300,63 @@ void SlaOutputDev::drawChar(GfxState *state, double x, double y, double dx, doub fontPath->getPoint(i, &x2, &y2, &f); ++i; fontPath->getPoint(i, &x3, &y3, &f); - qPath.cubicTo(x1,y1,x2,y2,x3,y3); + qPath.cubicTo(x1, y1, x2, y2, x3, y3); } else - qPath.lineTo(x1,y1); + qPath.lineTo(x1, y1); if (f & splashPathLast) qPath.closeSubpath(); } - const double *ctm = state->getCTM(); + const double* ctm = state->getCTM(); m_ctm = QTransform(ctm[0], ctm[1], ctm[2], ctm[3], ctm[4], ctm[5]); double xCoor = m_doc->currentPage()->xOffset(); double yCoor = m_doc->currentPage()->yOffset(); FPointArray textPath; textPath.fromQPainterPath(qPath); FPoint wh = textPath.widthHeight(); - if (textRenderingMode > 3) - { - QTransform mm; - mm.scale(1, -1); - mm.translate(x, -y); - // Remember the glyph for later clipping - m_clipTextPath.addPath(m_ctm.map(mm.map(qPath))); - } - if ((textPath.size() > 3) && ((wh.x() != 0.0) || (wh.y() != 0.0)) && (textRenderingMode != 7)) - { - int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, CommonStrings::None, CommonStrings::None); - PageItem* ite = m_doc->Items->at(z); - QTransform mm; - mm.scale(1, -1); - mm.translate(x, -y); - textPath.map(mm); - textPath.map(m_ctm); - ite->PoLine = textPath.copy(); - ite->ClipEdited = true; - ite->FrameType = 3; - ite->setLineEnd(PLineEnd); - ite->setLineJoin(PLineJoin); - ite->setTextFlowMode(PageItem::TextFlowDisabled); - // Fill text rendering modes. See above - if (textRenderingMode == 0 || textRenderingMode == 2 || textRenderingMode == 4 || textRenderingMode == 6) + if (m_import_text_as_vectors) { + qDebug() << "drawChar() "; + + if (textRenderingMode > 3) { - CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &CurrFillShade); - ite->setFillColor(CurrColorFill); - ite->setFillShade(CurrFillShade); - ite->setFillEvenOdd(false); - ite->setFillTransparency(1.0 - state->getFillOpacity()); - ite->setFillBlendmode(getBlendMode(state)); + QTransform mm; + mm.scale(1, -1); + mm.translate(x, -y); + // Remember the glyph for later clipping + m_clipTextPath.addPath(m_ctm.map(mm.map(qPath))); } - // Stroke text rendering modes. See above - if (textRenderingMode == 1 || textRenderingMode == 2 || textRenderingMode == 5 || textRenderingMode == 6) + if ((textPath.size() > 3) && ((wh.x() != 0.0) || (wh.y() != 0.0)) && (textRenderingMode != 7)) { - CurrColorStroke = getColor(state->getStrokeColorSpace(), state->getStrokeColor(), &CurrStrokeShade); - ite->setLineColor(CurrColorStroke); - ite->setLineWidth(state->getTransformedLineWidth()); - ite->setLineTransparency(1.0 - state->getStrokeOpacity()); - ite->setLineBlendmode(getBlendMode(state)); - ite->setLineShade(CurrStrokeShade); - } - m_doc->adjustItemSize(ite); - m_Elements->append(ite); - if (m_groupStack.count() != 0) - { - m_groupStack.top().Items.append(ite); - applyMask(ite); + PageItem* text_node = NULL; + + + int z = m_doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, xCoor, yCoor, 10, 10, 0, CommonStrings::None, CommonStrings::None); + text_node = m_doc->Items->at(z); + + // todo: merge this between vector and text implementations. + + QTransform mm; + mm.scale(1, -1); + mm.translate(x, -y); + textPath.map(mm); + textPath.map(m_ctm); + text_node->PoLine = textPath.copy(); + setFillAndStrokeForPDF(state, text_node); + // Fill text rendering modes. See above + m_doc->adjustItemSize(text_node); + m_Elements->append(text_node); + if (m_groupStack.count() != 0) + { + m_groupStack.top().Items.append(text_node); + applyMask(text_node); + } } delete fontPath; } } + if (!m_import_text_as_vectors) { // donm't render the char as vectors add it to an array so it can be rendred as a string + addChar(state, x, y, dx, dy, originX, originY, code, nBytes, u, uLen); + } } } @@ -4043,16 +4038,16 @@ void SlaOutputDev::addGlyphAtPoint(QPointF newGlyphPoint, PdfGlyph new_glyph) { //m_activeTextRegion->glyphs.push_back(new_glyph); //at the moment a new segment only gets added when the line is created. a new segment should also get added if there's any change in style or layout etc...but that feature can be added llater, it's not needed for basic textframe support with no style. - m_activeTextRegion->textRegionLines.back().glyphIndex = m_glyphs.size() - 1; + m_activeTextRegion->textRegionLines.back().glyphIndex = m_glyphs.size() - 1; if (m_activeTextRegion->textRegionLines.back().segments.empty()) { // add a new segment TextRegionLine newSegment = TextRegionLine(); m_activeTextRegion->textRegionLines.back().segments.push_back(newSegment); } - if(m_activeTextRegion->textRegionLines.back().segments.back().width == 0) + if (m_activeTextRegion->textRegionLines.back().segments.back().width == 0) { - TextRegionLine &segment = m_activeTextRegion->textRegionLines.back().segments.back(); + TextRegionLine& segment = m_activeTextRegion->textRegionLines.back().segments.back(); segment.width = new_glyph.dx; segment.baseOrigin = QPointF(newGlyphPoint.x(), m_activeTextRegion->textRegionLines.back().baseOrigin.y()); segment.modeHeigth = newGlyphPoint.y() - segment.baseOrigin.y(); @@ -4074,3 +4069,114 @@ void SlaOutputDev::addGlyphAtPoint(QPointF newGlyphPoint, PdfGlyph new_glyph) { } } +/** + * \brief Adds the specified character to the text buffer + * Takes care of converting it to UTF-8 and generates a new style repr if style + * has changed since the last call. + */ +void SlaOutputDev::addChar(GfxState* state, double x, double y, + double dx, double dy, + double originX, double originY, + CharCode code, int nBytes, Unicode const* u, int uLen) { + qDebug() << "addChar() '" << u << " : " << uLen; + // TODO: Compleatly gut this function so all that it ends up doing is placing a character and some positioning information on a stack get rid of all the other junk as it's not needed + + bool is_space = (uLen == 1 && u[0] == 32); + // Skip beginning space + if (is_space && m_glyphs.empty()) { + QPoint delta(dx, dy); + m_text_position += delta; + return; + } + // Allow only one space in a row + if (is_space && + (m_glyphs[m_glyphs.size() - 1].code == QChar::SpecialCharacter::Space)) { + QPoint delta(dx, dy); + m_text_position += delta; + return; + } + + PdfGlyph new_glyph; + new_glyph.is_space = is_space; + new_glyph.position = QPoint(x - originX, y - originY); + //TODO:work out if this is still needed + //new_glyph.text_position = m_text_position; + new_glyph.dx = dx; + new_glyph.dy = dy; + //TODO: This only need to be called for the very first point, replace with an abstract version of addchar that does this for brand new textregions so there's no need to record dx or dy or check is glyphs is empty or empty glyphs + if (m_glyphs.empty()) + { + addGlyphAtPoint(QPointF(x, y), new_glyph); + } + //TODO:work out if this is still needed + QPoint delta(dx, dy); + m_text_position += delta; + + // Convert the character to UTF-16 since that's our SVG document's encoding + { + for (int i = 0; i < uLen; i++) { + new_glyph.code += (char16_t)u[i]; + } + } + + new_glyph.rise = state->getRise(); + m_glyphs.push_back(new_glyph); +} + +void SlaOutputDev::setFillAndStrokeForPDF(GfxState* state, PageItem* text_node) { + + text_node->ClipEdited = true; + text_node->FrameType = 3; + text_node->setLineEnd(PLineEnd); + text_node->setLineJoin(PLineJoin); + text_node->setTextFlowMode(PageItem::TextFlowDisabled); + + int textRenderingMode = state->getRender(); + // Invisible or only used for clipping + if (textRenderingMode == 3) + return; + // Fill text rendering modes. See above + if (textRenderingMode == 0 || textRenderingMode == 2 || textRenderingMode == 4 || textRenderingMode == 6) + { + + CurrColorFill = getColor(state->getFillColorSpace(), state->getFillColor(), &CurrFillShade); + if (text_node->isTextFrame()) { //fill colour sets the background colour for the frame not the fill colour fore the text + text_node->setFillTransparency(1.0 - (state->getFillOpacity() > state->getStrokeOpacity() ? state->getFillOpacity() : state->getStrokeOpacity())); + text_node->setLineTransparency(1.0); // this ssets the transparency of the textbox border and we don't want to see it + text_node->setFillColor(CommonStrings::None); + text_node->setLineColor(CommonStrings::None); + text_node->setLineWidth(0);//line width doesn't effect drawing text, it creates a bounding box state->getTransformedLineWidth()); + text_node->setFillShade(CurrFillShade); + } + else { + text_node->setFillColor(CurrColorFill); + text_node->setFillShade(CurrFillShade); + text_node->setFillEvenOdd(false); + text_node->setFillTransparency(1.0 - state->getFillOpacity()); + text_node->setFillBlendmode(getBlendMode(state)); + } + } + // Stroke text rendering modes. See above + if (textRenderingMode == 1 || textRenderingMode == 2 || textRenderingMode == 5 || textRenderingMode == 6) + { + CurrColorStroke = getColor(state->getStrokeColorSpace(), state->getStrokeColor(), &CurrStrokeShade); + if (text_node->isTextFrame()) { //fil;l colour sets the background colour for the frame not the fill colour fore the text + text_node->setFillTransparency(1.0 - (state->getFillOpacity() > state->getStrokeOpacity() ? state->getFillOpacity() : state->getStrokeOpacity())); + text_node->setLineTransparency(1.0); // this sets the transparency of the textbox border and we don't want to see it + text_node->setFillColor(CommonStrings::None); //TODO: Check if we ov erride the stroke colour with the fil,l colour when threre is a choice + text_node->setLineColor(CommonStrings::None); + text_node->setLineWidth(0);//line width doesn't effect drawing text, it creates a bounding box state->getTransformedLineWidth()); + text_node->setFillBlendmode(getBlendMode(state)); + text_node->setFillShade(CurrFillShade); + } + else { + text_node->setLineColor(CurrColorStroke); + text_node->setLineWidth(0);//line width doesn't effect drawing text, it creates a bounding box state->getTransformedLineWidth()); + text_node->setFillTransparency(1.0 - state->getFillOpacity() > state->getStrokeOpacity() ? state->getFillOpacity() : state->getStrokeOpacity()); + text_node->setLineTransparency(1.0); // this sets the transparency of the textbox border and we don't want to see it + text_node->setLineBlendmode(getBlendMode(state)); + text_node->setLineShade(CurrStrokeShade); + } + } +} + diff --git a/scribus/plugins/import/pdf/slaoutput.h b/scribus/plugins/import/pdf/slaoutput.h index aa81839ef..017b871bc 100644 --- a/scribus/plugins/import/pdf/slaoutput.h +++ b/scribus/plugins/import/pdf/slaoutput.h @@ -269,6 +269,7 @@ public: void endMarkedContent(GfxState *state) override; void markPoint(POPPLER_CONST char *name) override; void markPoint(POPPLER_CONST char *name, Dict *properties) override; + //----- image drawing void drawImageMask(GfxState *state, Object *ref, Stream *str, int width, int height, GBool invert, GBool interpolate, GBool inlineImg) override; @@ -299,7 +300,8 @@ public: void updateFillColor(GfxState *state) override; void updateStrokeColor(GfxState *state) override; - void updateFont(GfxState *state) override; + void updateFontForVector(GfxState* state); + bool m_import_text_as_vectors = true; //----- text drawing void beginTextObject(GfxState *state) override; @@ -352,6 +354,8 @@ private: bool linearTest(QPointF point, bool xInLimits, bool yInLimits); void moveToPoint(QPointF newPoint); void addGlyphAtPoint(QPointF newGlyphPoint, PdfGlyph new_glyph); + void addChar(GfxState* state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, int nBytes, Unicode const* u, int uLen); + void setFillAndStrokeForPDF(GfxState* state, PageItem* text_node); bool pathIsClosed {false}; QString CurrColorFill; @@ -423,6 +427,8 @@ private: TextRegion *m_activeTextRegion = NULL; std::vector<PdfGlyph> m_glyphs; //this may replace some of the other settings or it may not, certainly not font as text gets flushed if the font changes + //PDF Text import + QPoint m_text_position = QPoint(0,0); }; #endif |
|
As in 0016125, patch does not follow properly our code style: - braces must be on their own line - if a code block has a single line, then no braces - variable naming: m_import_text_as_vectors => not correct, use m_importTextAsVectors instead |
Date Modified | Username | Field | Change |
---|---|---|---|
2020-06-03 16:35 | oliverthered | New Issue | |
2020-06-03 16:35 | oliverthered | Tag Attached: import | |
2020-06-03 16:35 | oliverthered | Tag Attached: PDF | |
2020-06-03 16:35 | oliverthered | Tag Attached: pdf import | |
2020-06-03 16:35 | oliverthered | Tag Attached: vectorised fonts | |
2020-06-03 16:35 | oliverthered | File Added: addChar.diff | |
2020-06-03 21:34 | jghali | Note Added: 0047667 | |
2020-06-21 12:39 | jghali | Assigned To | => jghali |
2020-06-21 12:39 | jghali | Status | new => resolved |
2020-06-21 12:39 | jghali | Resolution | open => duplicate |
2020-06-21 12:39 | jghali | Relationship added | duplicate of 0016142 |
2020-06-21 12:40 | jghali | Status | resolved => closed |