diff --git a/Pdf4QtLibCore/sources/pdffont.cpp b/Pdf4QtLibCore/sources/pdffont.cpp index 1e4b1a2..959b279 100644 --- a/Pdf4QtLibCore/sources/pdffont.cpp +++ b/Pdf4QtLibCore/sources/pdffont.cpp @@ -564,9 +564,10 @@ QString PDFSystemFontInfoStorage::getFontPostscriptName(QString fontName) return fontName.remove(QChar(' ')).remove(QChar('-')).remove(QChar(',')).trimmed(); } -PDFFont::PDFFont(CIDSystemInfo CIDSystemInfo, FontDescriptor fontDescriptor) : +PDFFont::PDFFont(CIDSystemInfo CIDSystemInfo, QByteArray fontId, FontDescriptor fontDescriptor) : m_CIDSystemInfo(qMove(CIDSystemInfo)), - m_fontDescriptor(qMove(fontDescriptor)) + m_fontDescriptor(qMove(fontDescriptor)), + m_fontId(qMove(fontId)) { } @@ -1284,7 +1285,12 @@ CIDSystemInfo PDFFont::readCIDSystemInfo(const PDFObject& cidSystemInfoObject, c return cidSystemInfo; } -PDFFontPointer PDFFont::createFont(const PDFObject& object, const PDFDocument* document) +QByteArray PDFFont::getFontId() const +{ + return m_fontId; +} + +PDFFontPointer PDFFont::createFont(const PDFObject& object, QByteArray fontId, const PDFDocument* document) { const PDFObject& dereferencedFontDictionary = document->getObject(object); if (!dereferencedFontDictionary.isDictionary()) @@ -1763,7 +1769,7 @@ PDFFontPointer PDFFont::createFont(const PDFObject& object, const PDFDocument* d toUnicodeCMap = PDFFontCMap::createFromData(decodedStream); } - return PDFFontPointer(new PDFType0Font(qMove(cidSystemInfo), qMove(fontDescriptor), qMove(cmap), qMove(toUnicodeCMap), qMove(cidToGidMapper), defaultWidth, qMove(advances))); + return PDFFontPointer(new PDFType0Font(qMove(cidSystemInfo), qMove(fontId), qMove(fontDescriptor), qMove(cmap), qMove(toUnicodeCMap), qMove(cidToGidMapper), defaultWidth, qMove(advances))); } case FontType::Type3: @@ -1853,7 +1859,7 @@ PDFFontPointer PDFFont::createFont(const PDFObject& object, const PDFDocument* d } std::vector widthsF3 = fontLoader.readNumberArrayFromDictionary(fontDictionary, "Widths"); - return PDFFontPointer(new PDFType3Font(qMove(fontDescriptor), firstCharF3, lastCharF3, fontMatrix, qMove(characterContentStreams), qMove(widthsF3), document->getObject(fontDictionary->get("Resources")), qMove(toUnicodeCMap))); + return PDFFontPointer(new PDFType3Font(qMove(fontDescriptor), qMove(fontId), firstCharF3, lastCharF3, fontMatrix, qMove(characterContentStreams), qMove(widthsF3), document->getObject(fontDictionary->get("Resources")), qMove(toUnicodeCMap))); } default: @@ -1867,10 +1873,10 @@ PDFFontPointer PDFFont::createFont(const PDFObject& object, const PDFDocument* d { case FontType::Type1: case FontType::MMType1: - return PDFFontPointer(new PDFType1Font(fontType, qMove(cidSystemInfo), qMove(fontDescriptor), qMove(name), qMove(baseFont), firstChar, lastChar, qMove(widths), encoding, simpleFontEncodingTable, standardFont, glyphIndexArray)); + return PDFFontPointer(new PDFType1Font(fontType, qMove(fontId), qMove(cidSystemInfo), qMove(fontDescriptor), qMove(name), qMove(baseFont), firstChar, lastChar, qMove(widths), encoding, simpleFontEncodingTable, standardFont, glyphIndexArray)); case FontType::TrueType: - return PDFFontPointer(new PDFTrueTypeFont(qMove(cidSystemInfo), qMove(fontDescriptor), qMove(name), qMove(baseFont), firstChar, lastChar, qMove(widths), encoding, simpleFontEncodingTable, glyphIndexArray)); + return PDFFontPointer(new PDFTrueTypeFont(qMove(cidSystemInfo), qMove(fontId), qMove(fontDescriptor), qMove(name), qMove(baseFont), firstChar, lastChar, qMove(widths), encoding, simpleFontEncodingTable, glyphIndexArray)); default: { @@ -1883,6 +1889,7 @@ PDFFontPointer PDFFont::createFont(const PDFObject& object, const PDFDocument* d } PDFSimpleFont::PDFSimpleFont(CIDSystemInfo cidSystemInfo, + QByteArray fontId, FontDescriptor fontDescriptor, QByteArray name, QByteArray baseFont, @@ -1892,7 +1899,7 @@ PDFSimpleFont::PDFSimpleFont(CIDSystemInfo cidSystemInfo, PDFEncoding::Encoding encodingType, encoding::EncodingTable encoding, GlyphIndices glyphIndices) : - PDFFont(qMove(cidSystemInfo), qMove(fontDescriptor)), + PDFFont(qMove(cidSystemInfo), qMove(fontId), qMove(fontDescriptor)), m_name(qMove(name)), m_baseFont(qMove(baseFont)), m_firstChar(firstChar), @@ -1976,6 +1983,7 @@ void PDFSimpleFont::dumpFontToTreeItem(ITreeFactory* treeFactory) const } PDFType1Font::PDFType1Font(FontType fontType, + QByteArray fontId, CIDSystemInfo cidSystemInfo, FontDescriptor fontDescriptor, QByteArray name, @@ -1987,7 +1995,7 @@ PDFType1Font::PDFType1Font(FontType fontType, encoding::EncodingTable encoding, StandardFontType standardFontType, GlyphIndices glyphIndices) : - PDFSimpleFont(qMove(cidSystemInfo), qMove(fontDescriptor), qMove(name), qMove(baseFont), firstChar, lastChar, qMove(widths), encodingType, encoding, glyphIndices), + PDFSimpleFont(qMove(cidSystemInfo), qMove(fontId), qMove(fontDescriptor), qMove(name), qMove(baseFont), firstChar, lastChar, qMove(widths), encodingType, encoding, glyphIndices), m_fontType(fontType), m_standardFontType(standardFontType) { @@ -2068,7 +2076,7 @@ void PDFFontCache::setDocument(const PDFModifiedDocument& document) } } -PDFFontPointer PDFFontCache::getFont(const PDFObject& fontObject) const +PDFFontPointer PDFFontCache::getFont(const PDFObject& fontObject, const QByteArray& fontId) const { if (fontObject.isReference()) { @@ -2081,7 +2089,7 @@ PDFFontPointer PDFFontCache::getFont(const PDFObject& fontObject) const if (it == m_fontCache.cend()) { // We must create the font - PDFFontPointer font = PDFFont::createFont(fontObject, m_document); + PDFFontPointer font = PDFFont::createFont(fontObject, fontId, m_document); if (m_fontCacheShrinkDisabledObjects.empty() && m_fontCache.size() >= m_fontCacheLimit) { @@ -2096,7 +2104,7 @@ PDFFontPointer PDFFontCache::getFont(const PDFObject& fontObject) const else { // Object is not a reference. Create font directly and return it. - return PDFFont::createFont(fontObject, m_document); + return PDFFont::createFont(fontObject, fontId, m_document); } } @@ -2611,6 +2619,7 @@ PDFReal PDFType0Font::getGlyphAdvance(CID cid) const } PDFType3Font::PDFType3Font(FontDescriptor fontDescriptor, + QByteArray fontId, int firstCharacterIndex, int lastCharacterIndex, QTransform fontMatrix, @@ -2618,7 +2627,7 @@ PDFType3Font::PDFType3Font(FontDescriptor fontDescriptor, std::vector&& widths, const PDFObject& resources, PDFFontCMap toUnicode) : - PDFFont(CIDSystemInfo(), qMove(fontDescriptor)), + PDFFont(CIDSystemInfo(), qMove(fontId), qMove(fontDescriptor)), m_firstCharacterIndex(firstCharacterIndex), m_lastCharacterIndex(lastCharacterIndex), m_fontMatrix(fontMatrix), diff --git a/Pdf4QtLibCore/sources/pdffont.h b/Pdf4QtLibCore/sources/pdffont.h index c3dc633..e54a6ce 100644 --- a/Pdf4QtLibCore/sources/pdffont.h +++ b/Pdf4QtLibCore/sources/pdffont.h @@ -295,7 +295,7 @@ private: class PDF4QTLIBCORESHARED_EXPORT PDFFont { public: - explicit PDFFont(CIDSystemInfo CIDSystemInfo, FontDescriptor fontDescriptor); + explicit PDFFont(CIDSystemInfo CIDSystemInfo, QByteArray fontId, FontDescriptor fontDescriptor); virtual ~PDFFont() = default; /// Returns the font type @@ -318,8 +318,9 @@ public: /// Creates font from the object. If font can't be created, exception is thrown. /// \param object Font dictionary + /// \param fontId Font ID /// \param document Document - static PDFFontPointer createFont(const PDFObject& object, const PDFDocument* document); + static PDFFontPointer createFont(const PDFObject& object, QByteArray fontId, const PDFDocument* document); /// Tries to read font descriptor from the object /// \param fontDescriptorObject Font descriptor dictionary @@ -331,9 +332,13 @@ public: /// \param document Document static CIDSystemInfo readCIDSystemInfo(const PDFObject& cidSystemInfoObject, const PDFDocument* document); + /// Returns font id from the font dictionary + QByteArray getFontId() const; + protected: CIDSystemInfo m_CIDSystemInfo; FontDescriptor m_fontDescriptor; + QByteArray m_fontId; }; /// Simple font, see PDF reference 1.7, chapter 5.5. Simple fonts have encoding table, @@ -344,6 +349,7 @@ class PDFSimpleFont : public PDFFont public: explicit PDFSimpleFont(CIDSystemInfo cidSystemInfo, + QByteArray fontId, FontDescriptor fontDescriptor, QByteArray name, QByteArray baseFont, @@ -381,6 +387,7 @@ class PDFType1Font : public PDFSimpleFont public: explicit PDFType1Font(FontType fontType, + QByteArray fontId, CIDSystemInfo cidSystemInfo, FontDescriptor fontDescriptor, QByteArray name, @@ -434,7 +441,8 @@ public: /// Retrieves font from the cache. If font can't be accessed or created, /// then exception is thrown. /// \param fontObject Font object - PDFFontPointer getFont(const PDFObject& fontObject) const; + /// \param fontId Font identification in resource dictionary + PDFFontPointer getFont(const PDFObject& fontObject, const QByteArray& fontId) const; /// Retrieves realized font from the cache. If realized font can't be accessed or created, /// then exception is thrown. @@ -600,6 +608,7 @@ class PDFType3Font : public PDFFont { public: explicit PDFType3Font(FontDescriptor fontDescriptor, + QByteArray fontId, int firstCharacterIndex, int lastCharacterIndex, QTransform fontMatrix, @@ -641,8 +650,15 @@ private: class PDFType0Font : public PDFFont { public: - explicit inline PDFType0Font(CIDSystemInfo cidSystemInfo, FontDescriptor fontDescriptor, PDFFontCMap cmap, PDFFontCMap toUnicode, PDFCIDtoGIDMapper mapper, PDFReal defaultAdvance, std::unordered_map advances) : - PDFFont(qMove(cidSystemInfo), qMove(fontDescriptor)), + explicit inline PDFType0Font(CIDSystemInfo cidSystemInfo, + QByteArray fontId, + FontDescriptor fontDescriptor, + PDFFontCMap cmap, + PDFFontCMap toUnicode, + PDFCIDtoGIDMapper mapper, + PDFReal defaultAdvance, + std::unordered_map advances) : + PDFFont(qMove(cidSystemInfo), qMove(fontId), qMove(fontDescriptor)), m_cmap(qMove(cmap)), m_toUnicode(qMove(toUnicode)), m_mapper(qMove(mapper)), diff --git a/Pdf4QtLibCore/sources/pdfpagecontenteditorprocessor.cpp b/Pdf4QtLibCore/sources/pdfpagecontenteditorprocessor.cpp index f0d507f..5d7fa18 100644 --- a/Pdf4QtLibCore/sources/pdfpagecontenteditorprocessor.cpp +++ b/Pdf4QtLibCore/sources/pdfpagecontenteditorprocessor.cpp @@ -17,6 +17,8 @@ #include "pdfpagecontenteditorprocessor.h" +#include + namespace pdf { @@ -629,4 +631,108 @@ void PDFEditedPageContentElementText::setTextPath(QPainterPath newTextPath) m_textPath = newTextPath; } +QString PDFEditedPageContentElementText::getItemsAsText() const +{ + QString text; + + PDFPageContentProcessorState state = getState(); + state.setStateFlags(PDFPageContentProcessorState::StateFlags()); + + for (const Item& item : getItems()) + { + if (item.isText) + { + for (const TextSequenceItem& textItem : item.textSequence.items) + { + if (textItem.isCharacter()) + { + if (!textItem.character.isNull()) + { + text += QString(textItem.character).toHtmlEscaped(); + } + else if (textItem.isAdvance()) + { + text += QString("").arg(textItem.advance); + } + else if (textItem.cid != 0) + { + text += QString("").arg(textItem.cid); + } + } + } + } + else if (item.isUpdateGraphicState) + { + PDFPageContentProcessorState newState = state; + newState.setStateFlags(PDFPageContentProcessorState::StateFlags()); + + newState.setState(item.state); + PDFPageContentProcessorState::StateFlags flags = newState.getStateFlags(); + + if (flags.testFlag(PDFPageContentProcessorState::StateTextRenderingMode)) + { + text += QString("").arg(int(newState.getTextRenderingMode())); + } + + if (flags.testFlag(PDFPageContentProcessorState::StateTextRise)) + { + text += QString("").arg(newState.getTextRise()); + } + + if (flags.testFlag(PDFPageContentProcessorState::StateTextCharacterSpacing)) + { + text += QString("").arg(newState.getTextCharacterSpacing()); + } + + if (flags.testFlag(PDFPageContentProcessorState::StateTextWordSpacing)) + { + text += QString("").arg(newState.getTextWordSpacing()); + } + + if (flags.testFlag(PDFPageContentProcessorState::StateTextLeading)) + { + text += QString("").arg(newState.getTextLeading()); + } + + if (flags.testFlag(PDFPageContentProcessorState::StateTextHorizontalScaling)) + { + text += QString("").arg(newState.getTextHorizontalScaling()); + } + + if (flags.testFlag(PDFPageContentProcessorState::StateTextKnockout)) + { + text += QString("").arg(newState.getTextKnockout()); + } + + if (flags.testFlag(PDFPageContentProcessorState::StateTextFont) || + flags.testFlag(PDFPageContentProcessorState::StateTextFontSize)) + { + text += QString("").arg(newState.getTextFont()->getFontId()).arg(newState.getTextFontSize()); + } + + if (flags.testFlag(PDFPageContentProcessorState::StateTextMatrix)) + { + QTransform transform = newState.getTextMatrix(); + + qreal x = transform.dx(); + qreal y = transform.dy(); + + if (transform.isTranslating()) + { + text += QString("").arg(x).arg(y); + } + else + { + text += QString("").arg(transform.m11()).arg(transform.m12()).arg(transform.m21()).arg(transform.m22()).arg(x).arg(y); + } + } + + state = newState; + state.setStateFlags(PDFPageContentProcessorState::StateFlags()); + } + } + + return text; +} + } // namespace pdf diff --git a/Pdf4QtLibCore/sources/pdfpagecontenteditorprocessor.h b/Pdf4QtLibCore/sources/pdfpagecontenteditorprocessor.h index 3de7edc..c257c76 100644 --- a/Pdf4QtLibCore/sources/pdfpagecontenteditorprocessor.h +++ b/Pdf4QtLibCore/sources/pdfpagecontenteditorprocessor.h @@ -152,6 +152,8 @@ public: QPainterPath getTextPath() const; void setTextPath(QPainterPath newTextPath); + QString getItemsAsText() const; + private: std::vector m_items; QRectF m_boundingBox; diff --git a/Pdf4QtLibCore/sources/pdfpagecontentprocessor.cpp b/Pdf4QtLibCore/sources/pdfpagecontentprocessor.cpp index 6c7e521..7eb2029 100644 --- a/Pdf4QtLibCore/sources/pdfpagecontentprocessor.cpp +++ b/Pdf4QtLibCore/sources/pdfpagecontentprocessor.cpp @@ -2749,7 +2749,7 @@ void PDFPageContentProcessor::operatorTextSetFontAndFontSize(PDFOperandName font { try { - PDFFontPointer font = m_fontCache->getFont(m_fontDictionary->get(fontName.name)); + PDFFontPointer font = m_fontCache->getFont(m_fontDictionary->get(fontName.name), fontName.name); m_graphicState.setTextFont(qMove(font)); m_graphicState.setTextFontSize(fontSize); @@ -3504,47 +3504,52 @@ PDFPageContentProcessorState::~PDFPageContentProcessorState() PDFPageContentProcessorState& PDFPageContentProcessorState::operator=(const PDFPageContentProcessorState& other) { - setCurrentTransformationMatrix(other.getCurrentTransformationMatrix()); - setStrokeColorSpace(other.m_strokeColorSpace); - setFillColorSpace(other.m_fillColorSpace); - setStrokeColor(other.getStrokeColor(), other.getStrokeColorOriginal()); - setFillColor(other.getFillColor(), other.getFillColorOriginal()); - setLineWidth(other.getLineWidth()); - setLineCapStyle(other.getLineCapStyle()); - setLineJoinStyle(other.getLineJoinStyle()); - setMitterLimit(other.getMitterLimit()); - setLineDashPattern(other.getLineDashPattern()); - setRenderingIntentName(other.getRenderingIntentName()); - setFlatness(other.getFlatness()); - setSmoothness(other.getSmoothness()); - setTextCharacterSpacing(other.getTextCharacterSpacing()); - setTextWordSpacing(other.getTextWordSpacing()); - setTextHorizontalScaling(other.getTextHorizontalScaling()); - setTextLeading(other.getTextLeading()); - setTextFont(other.getTextFont()); - setTextFontSize(other.getTextFontSize()); - setTextRenderingMode(other.getTextRenderingMode()); - setTextRise(other.getTextRise()); - setTextKnockout(other.getTextKnockout()); - setTextMatrix(other.getTextMatrix()); - setTextLineMatrix(other.getTextLineMatrix()); - setAlphaStroking(other.getAlphaStroking()); - setAlphaFilling(other.getAlphaFilling()); - setBlendMode(other.getBlendMode()); - setRenderingIntent(other.getRenderingIntent()); - setOverprintMode(other.getOverprintMode()); - setAlphaIsShape(other.getAlphaIsShape()); - setStrokeAdjustment(other.getStrokeAdjustment()); - setSoftMask(other.getSoftMask()); - setBlackPointCompensationMode(other.getBlackPointCompensationMode()); - setBlackGenerationFunction(other.getBlackGenerationFunction()); - setUndercolorRemovalFunction(other.getUndercolorRemovalFunction()); - setTransferFunction(other.getTransferFunction()); - setHalftone(other.getHalftone()); - setHalftoneOrigin(other.getHalftoneOrigin()); + setState(other); return *this; } +void PDFPageContentProcessorState::setState(const PDFPageContentProcessorState& state) +{ + setCurrentTransformationMatrix(state.getCurrentTransformationMatrix()); + setStrokeColorSpace(state.m_strokeColorSpace); + setFillColorSpace(state.m_fillColorSpace); + setStrokeColor(state.getStrokeColor(), state.getStrokeColorOriginal()); + setFillColor(state.getFillColor(), state.getFillColorOriginal()); + setLineWidth(state.getLineWidth()); + setLineCapStyle(state.getLineCapStyle()); + setLineJoinStyle(state.getLineJoinStyle()); + setMitterLimit(state.getMitterLimit()); + setLineDashPattern(state.getLineDashPattern()); + setRenderingIntentName(state.getRenderingIntentName()); + setFlatness(state.getFlatness()); + setSmoothness(state.getSmoothness()); + setTextCharacterSpacing(state.getTextCharacterSpacing()); + setTextWordSpacing(state.getTextWordSpacing()); + setTextHorizontalScaling(state.getTextHorizontalScaling()); + setTextLeading(state.getTextLeading()); + setTextFont(state.getTextFont()); + setTextFontSize(state.getTextFontSize()); + setTextRenderingMode(state.getTextRenderingMode()); + setTextRise(state.getTextRise()); + setTextKnockout(state.getTextKnockout()); + setTextMatrix(state.getTextMatrix()); + setTextLineMatrix(state.getTextLineMatrix()); + setAlphaStroking(state.getAlphaStroking()); + setAlphaFilling(state.getAlphaFilling()); + setBlendMode(state.getBlendMode()); + setRenderingIntent(state.getRenderingIntent()); + setOverprintMode(state.getOverprintMode()); + setAlphaIsShape(state.getAlphaIsShape()); + setStrokeAdjustment(state.getStrokeAdjustment()); + setSoftMask(state.getSoftMask()); + setBlackPointCompensationMode(state.getBlackPointCompensationMode()); + setBlackGenerationFunction(state.getBlackGenerationFunction()); + setUndercolorRemovalFunction(state.getUndercolorRemovalFunction()); + setTransferFunction(state.getTransferFunction()); + setHalftone(state.getHalftone()); + setHalftoneOrigin(state.getHalftoneOrigin()); +} + void PDFPageContentProcessorState::setCurrentTransformationMatrix(const QTransform& currentTransformationMatrix) { if (m_currentTransformationMatrix != currentTransformationMatrix) diff --git a/Pdf4QtLibCore/sources/pdfpagecontentprocessor.h b/Pdf4QtLibCore/sources/pdfpagecontentprocessor.h index 8b9212c..363795f 100644 --- a/Pdf4QtLibCore/sources/pdfpagecontentprocessor.h +++ b/Pdf4QtLibCore/sources/pdfpagecontentprocessor.h @@ -156,6 +156,8 @@ public: using StateFlags = PDFFlags; + void setState(const PDFPageContentProcessorState& state); + const QTransform& getCurrentTransformationMatrix() const { return m_currentTransformationMatrix; } void setCurrentTransformationMatrix(const QTransform& currentTransformationMatrix); diff --git a/Pdf4QtLibCore/sources/pdfpainterutils.cpp b/Pdf4QtLibCore/sources/pdfpainterutils.cpp index 64f731c..10ffd48 100644 --- a/Pdf4QtLibCore/sources/pdfpainterutils.cpp +++ b/Pdf4QtLibCore/sources/pdfpainterutils.cpp @@ -117,4 +117,59 @@ QBrush PDFPainterHelper::createBrushFromState(const PDFPageContentProcessorState } } +PDFTransformationDecomposition PDFPainterHelper::decomposeTransform(const QTransform& transform) +{ + PDFTransformationDecomposition result; + + const qreal m11 = transform.m11(); + const qreal m12 = transform.m12(); + const qreal m21 = transform.m21(); + const qreal m22 = transform.m22(); + + const qreal dx = transform.dx(); + const qreal dy = transform.dy(); + + const qreal sx = std::sqrt(m11 * m11 + m21 * m21); + const qreal phi = std::atan2(m21, m11); + const qreal msy = m12 * std::cos(phi) + m22 * std::sin(phi); + const qreal sy = -m12 * std::sin(phi) + m22 * std::cos(phi); + + result.rotationAngle = phi; + result.scaleX = sx; + result.scaleY = sy; + + if (!qFuzzyIsNull(sy)) + { + result.shearFactor = msy / sy; + } + else + { + result.shearFactor = 0.0; + } + + result.translateX = dx; + result.translateY = dy; + + return result; +} + +QTransform PDFPainterHelper::composeTransform(const PDFTransformationDecomposition& decomposition) +{ + const qreal s = std::sin(decomposition.rotationAngle); + const qreal c = std::cos(decomposition.rotationAngle); + + const qreal m = decomposition.shearFactor; + const qreal sx = decomposition.scaleX; + const qreal sy = decomposition.scaleY; + const qreal dx = decomposition.translateX; + const qreal dy = decomposition.translateY; + + const qreal m11 = sx * c; + const qreal m12 = sy * m * c - sy * s; + const qreal m21 = sx * s; + const qreal m22 = sy * m * s + sy * c; + + return QTransform(m11, m12, m21, m22, dx, dy); +} + } // namespace pdf diff --git a/Pdf4QtLibCore/sources/pdfpainterutils.h b/Pdf4QtLibCore/sources/pdfpainterutils.h index 00faf1f..7563bc4 100644 --- a/Pdf4QtLibCore/sources/pdfpainterutils.h +++ b/Pdf4QtLibCore/sources/pdfpainterutils.h @@ -45,6 +45,16 @@ private: QPainter* m_painter; }; +struct PDFTransformationDecomposition +{ + double rotationAngle = 0.0; + double shearFactor = 0.0; + double scaleX = 0.0; + double scaleY = 0.0; + double translateX = 0.0; + double translateY = 0.0; +}; + class PDF4QTLIBCORESHARED_EXPORT PDFPainterHelper { public: @@ -62,6 +72,12 @@ public: /// Creates brush from painter graphicState static QBrush createBrushFromState(const PDFPageContentProcessorState* graphicState, double alpha); + + /// Decompose transform + static PDFTransformationDecomposition decomposeTransform(const QTransform& transform); + + /// Compose transform + static QTransform composeTransform(const PDFTransformationDecomposition& decomposition); }; } // namespace pdf diff --git a/Pdf4QtLibGui/pdfdocumentpropertiesdialog.cpp b/Pdf4QtLibGui/pdfdocumentpropertiesdialog.cpp index e3b7bcb..0beb5f5 100644 --- a/Pdf4QtLibGui/pdfdocumentpropertiesdialog.cpp +++ b/Pdf4QtLibGui/pdfdocumentpropertiesdialog.cpp @@ -331,7 +331,7 @@ void PDFDocumentPropertiesDialog::initializeFonts(const pdf::PDFDocument* docume try { - if (pdf::PDFFontPointer font = pdf::PDFFont::createFont(object, document)) + if (pdf::PDFFontPointer font = pdf::PDFFont::createFont(object, fontsDictionary->getKey(i).getString(), document)) { pdf::PDFRenderErrorReporterDummy dummyReporter; pdf::PDFRealizedFontPointer realizedFont = pdf::PDFRealizedFont::createRealizedFont(font, 8.0, &dummyReporter); diff --git a/Pdf4QtLibWidgets/sources/pdfpagecontenteditorediteditemsettings.cpp b/Pdf4QtLibWidgets/sources/pdfpagecontenteditorediteditemsettings.cpp index 0935e84..23a37a0 100644 --- a/Pdf4QtLibWidgets/sources/pdfpagecontenteditorediteditemsettings.cpp +++ b/Pdf4QtLibWidgets/sources/pdfpagecontenteditorediteditemsettings.cpp @@ -21,6 +21,7 @@ #include "pdfpagecontentelements.h" #include "pdfpagecontenteditorprocessor.h" #include "pdfwidgetutils.h" +#include "pdfpainterutils.h" #include #include @@ -58,6 +59,25 @@ void PDFPageContentEditorEditedItemSettings::loadFromElement(PDFPageContentEleme m_image = imageElement->getImage(); setImage(imageElement->getImage()); } + + if (PDFEditedPageContentElementText* textElement = editedElement->getElement()->asText()) + { + ui->tabWidget->addTab(ui->textTab, tr("Text")); + QString text = textElement->getItemsAsText(); + ui->plainTextEdit->setPlainText(text); + } + + QTransform matrix = editedElement->getElement()->getState().getCurrentTransformationMatrix(); + PDFTransformationDecomposition decomposedTransformation = PDFPainterHelper::decomposeTransform(matrix); + + ui->rotationAngleEdit->setValue(qRadiansToDegrees(decomposedTransformation.rotationAngle)); + ui->scaleInXEdit->setValue(decomposedTransformation.scaleX); + ui->scaleInYEdit->setValue(decomposedTransformation.scaleY); + ui->shearFactorEdit->setValue(decomposedTransformation.shearFactor); + ui->translateInXEdit->setValue(decomposedTransformation.translateX); + ui->translateInYEdit->setValue(decomposedTransformation.translateY); + + ui->tabWidget->addTab(ui->transformationTab, tr("Transformation")); } void PDFPageContentEditorEditedItemSettings::saveToElement(PDFPageContentElementEdited* editedElement) diff --git a/Pdf4QtLibWidgets/sources/pdfpagecontenteditorediteditemsettings.ui b/Pdf4QtLibWidgets/sources/pdfpagecontenteditorediteditemsettings.ui index d393030..33c21b0 100644 --- a/Pdf4QtLibWidgets/sources/pdfpagecontenteditorediteditemsettings.ui +++ b/Pdf4QtLibWidgets/sources/pdfpagecontenteditorediteditemsettings.ui @@ -17,7 +17,7 @@ - 1 + 0 @@ -143,6 +143,169 @@ Transformation + + + + + + + Translation in Y + + + + + + + -1000000.000000000000000 + + + 1000000.000000000000000 + + + + + + + Translation in X + + + + + + + -1000000.000000000000000 + + + 1000000.000000000000000 + + + + + + + Scale in X + + + + + + + -360.000000000000000 + + + 360.000000000000000 + + + + + + + -1000000.000000000000000 + + + 1000000.000000000000000 + + + + + + + -1000000.000000000000000 + + + 1000000.000000000000000 + + + + + + + Scale in Y + + + + + + + Shear factor + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + <html><head/><body><p>Rotation angle</p></body></html> + + + + + + + -1000000.000000000000000 + + + 1000000.000000000000000 + + + + + + + φ + + + + + + + <html><head/><body><p>s<span style=" vertical-align:sub;">x</span></p></body></html> + + + + + + + <html><head/><body><p>s<span style=" vertical-align:sub;">y</span></p></body></html> + + + + + + + m + + + + + + + <html><head/><body><p>t<span style=" vertical-align:sub;">x</span></p></body></html> + + + + + + + <html><head/><body><p>t<span style=" vertical-align:sub;">y</span></p></body></html> + + + + + + diff --git a/PdfTool/pdftoolinfofonts.cpp b/PdfTool/pdftoolinfofonts.cpp index 61339bf..00049c4 100644 --- a/PdfTool/pdftoolinfofonts.cpp +++ b/PdfTool/pdftoolinfofonts.cpp @@ -120,7 +120,7 @@ int PDFToolInfoFonts::execute(const PDFToolOptions& options) try { - if (pdf::PDFFontPointer font = pdf::PDFFont::createFont(object, &document)) + if (pdf::PDFFontPointer font = pdf::PDFFont::createFont(object, fontsDictionary->getKey(i).getString(), &document)) { pdf::PDFRenderErrorReporterDummy dummyReporter; pdf::PDFRealizedFontPointer realizedFont = pdf::PDFRealizedFont::createRealizedFont(font, 8.0, &dummyReporter);