mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-03-12 09:20:14 +01:00
Editor plugin: Content stream builder
This commit is contained in:
parent
21ff8d45fc
commit
17b275c8b1
@ -246,8 +246,13 @@ void PDFArray::optimize()
|
|||||||
bool PDFDictionary::equals(const PDFObjectContent* other) const
|
bool PDFDictionary::equals(const PDFObjectContent* other) const
|
||||||
{
|
{
|
||||||
Q_ASSERT(dynamic_cast<const PDFDictionary*>(other));
|
Q_ASSERT(dynamic_cast<const PDFDictionary*>(other));
|
||||||
const PDFDictionary* otherStream = static_cast<const PDFDictionary*>(other);
|
const PDFDictionary* otherDictionary = static_cast<const PDFDictionary*>(other);
|
||||||
return m_dictionary == otherStream->m_dictionary;
|
return m_dictionary == otherDictionary->m_dictionary;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PDFDictionary::operator==(const PDFDictionary& other) const
|
||||||
|
{
|
||||||
|
return m_dictionary == other.m_dictionary;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PDFObject& PDFDictionary::get(const QByteArray& key) const
|
const PDFObject& PDFDictionary::get(const QByteArray& key) const
|
||||||
|
@ -364,6 +364,8 @@ public:
|
|||||||
|
|
||||||
virtual bool equals(const PDFObjectContent* other) const override;
|
virtual bool equals(const PDFObjectContent* other) const override;
|
||||||
|
|
||||||
|
bool operator==(const PDFDictionary&other) const;
|
||||||
|
|
||||||
/// Returns object for the key. If key is not found in the dictionary,
|
/// Returns object for the key. If key is not found in the dictionary,
|
||||||
/// then valid reference to the null object is returned.
|
/// then valid reference to the null object is returned.
|
||||||
/// \param key Key
|
/// \param key Key
|
||||||
|
@ -17,6 +17,8 @@
|
|||||||
|
|
||||||
#include "pdfpagecontenteditorprocessor.h"
|
#include "pdfpagecontenteditorprocessor.h"
|
||||||
#include "pdfdocumentbuilder.h"
|
#include "pdfdocumentbuilder.h"
|
||||||
|
#include "pdfobject.h"
|
||||||
|
#include "pdfstreamfilters.h"
|
||||||
|
|
||||||
#include <QStringBuilder>
|
#include <QStringBuilder>
|
||||||
#include <QXmlStreamReader>
|
#include <QXmlStreamReader>
|
||||||
@ -968,7 +970,7 @@ void PDFPageContentEditorContentStreamBuilder::writeStateDifference(QTextStream&
|
|||||||
QString blendModeName = PDFBlendModeInfo::getBlendModeName(m_currentState.getBlendMode());
|
QString blendModeName = PDFBlendModeInfo::getBlendModeName(m_currentState.getBlendMode());
|
||||||
|
|
||||||
stateDictionary.beginDictionaryItem("BM");
|
stateDictionary.beginDictionaryItem("BM");
|
||||||
stateDictionary << WrapName(blendModeName);
|
stateDictionary << WrapName(blendModeName.toLatin1());
|
||||||
stateDictionary.endDictionaryItem();
|
stateDictionary.endDictionaryItem();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1016,7 +1018,7 @@ void PDFPageContentEditorContentStreamBuilder::writeStateDifference(QTextStream&
|
|||||||
QByteArray currentKey = QString("s%1").arg(++i).toLatin1();
|
QByteArray currentKey = QString("s%1").arg(++i).toLatin1();
|
||||||
if (!m_graphicStateDictionary.hasKey(currentKey))
|
if (!m_graphicStateDictionary.hasKey(currentKey))
|
||||||
{
|
{
|
||||||
m_graphicStateDictionary.addEntry(currentKey, std::move(stateObject));
|
m_graphicStateDictionary.addEntry(PDFInplaceOrMemoryString(currentKey), std::move(stateObject));
|
||||||
key = currentKey;
|
key = currentKey;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1038,9 +1040,8 @@ void PDFPageContentEditorContentStreamBuilder::writeElement(const PDFEditedPageC
|
|||||||
if (const PDFEditedPageContentElementImage* imageElement = element->asImage())
|
if (const PDFEditedPageContentElementImage* imageElement = element->asImage())
|
||||||
{
|
{
|
||||||
QImage image = imageElement->getImage();
|
QImage image = imageElement->getImage();
|
||||||
PDFObject imageObject = imageElement->getImageObject();
|
|
||||||
|
|
||||||
writeImage(image);
|
writeImage(stream, image);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const PDFEditedPageContentElementPath* pathElement = element->asPath())
|
if (const PDFEditedPageContentElementPath* pathElement = element->asPath())
|
||||||
@ -1361,6 +1362,45 @@ void PDFPageContentEditorContentStreamBuilder::writeText(QTextStream& stream, co
|
|||||||
stream << "ET Q" << Qt::endl;
|
stream << "ET Q" << Qt::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PDFPageContentEditorContentStreamBuilder::writeImage(QTextStream& stream, const QImage& image)
|
||||||
|
{
|
||||||
|
QByteArray key;
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
QByteArray currentKey = QString("Im%1").arg(++i).toLatin1();
|
||||||
|
if (!m_xobjectDictionary.hasKey(currentKey))
|
||||||
|
{
|
||||||
|
PDFArray array;
|
||||||
|
array.appendItem(PDFObject::createName("FlateDecode"));
|
||||||
|
|
||||||
|
QImage codedImage = image;
|
||||||
|
codedImage = codedImage.convertToFormat(QImage::Format_ARGB32);
|
||||||
|
|
||||||
|
QByteArray decodedStream(reinterpret_cast<const char*>(image.constBits()), image.sizeInBytes());
|
||||||
|
|
||||||
|
// Compress the content stream
|
||||||
|
QByteArray compressedData = PDFFlateDecodeFilter::compress(decodedStream);
|
||||||
|
PDFDictionary imageDictionary;
|
||||||
|
imageDictionary.setEntry(PDFInplaceOrMemoryString("Subtitle"), PDFObject::createName("Image"));
|
||||||
|
imageDictionary.setEntry(PDFInplaceOrMemoryString("Width"), PDFObject::createInteger(image.width()));
|
||||||
|
imageDictionary.setEntry(PDFInplaceOrMemoryString("Height"), PDFObject::createInteger(image.height()));
|
||||||
|
imageDictionary.setEntry(PDFInplaceOrMemoryString("ColorSpace"), PDFObject::createName("DeviceRGB"));
|
||||||
|
imageDictionary.setEntry(PDFInplaceOrMemoryString("BitsPerComponent"), PDFObject::createInteger(8));
|
||||||
|
imageDictionary.setEntry(PDFInplaceOrMemoryString("Length"), PDFObject::createInteger(compressedData.size()));
|
||||||
|
imageDictionary.setEntry(PDFInplaceOrMemoryString("Filter"), PDFObject::createArray(std::make_shared<PDFArray>(qMove(array))));
|
||||||
|
PDFObject imageObject = PDFObject::createStream(std::make_shared<PDFStream>(qMove(imageDictionary), qMove(compressedData)));
|
||||||
|
|
||||||
|
m_xobjectDictionary.addEntry(PDFInplaceOrMemoryString(currentKey), std::move(imageObject));
|
||||||
|
key = currentKey;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
stream << "/" << key << " Do" << Qt::endl;
|
||||||
|
}
|
||||||
|
|
||||||
QByteArray PDFPageContentEditorContentStreamBuilder::selectFont(const QByteArray& font)
|
QByteArray PDFPageContentEditorContentStreamBuilder::selectFont(const QByteArray& font)
|
||||||
{
|
{
|
||||||
m_textFont = nullptr;
|
m_textFont = nullptr;
|
||||||
@ -1404,12 +1444,15 @@ QByteArray PDFPageContentEditorContentStreamBuilder::selectFont(const QByteArray
|
|||||||
}
|
}
|
||||||
|
|
||||||
m_textFont = PDFFont::createFont(fontObject, font, m_document);
|
m_textFont = PDFFont::createFont(fontObject, font, m_document);
|
||||||
|
return defaultFontKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return font;
|
||||||
}
|
}
|
||||||
|
|
||||||
void PDFPageContentEditorContentStreamBuilder::addError(const QString& error)
|
void PDFPageContentEditorContentStreamBuilder::addError(const QString& error)
|
||||||
{
|
{
|
||||||
|
m_errors << error;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
@ -225,6 +225,8 @@ private:
|
|||||||
bool isFilling);
|
bool isFilling);
|
||||||
void writeText(QTextStream& stream, const QString& text);
|
void writeText(QTextStream& stream, const QString& text);
|
||||||
|
|
||||||
|
void writeImage(QTextStream& stream, const QImage& image);
|
||||||
|
|
||||||
QByteArray selectFont(const QByteArray& font);
|
QByteArray selectFont(const QByteArray& font);
|
||||||
void addError(const QString& error);
|
void addError(const QString& error);
|
||||||
|
|
||||||
@ -235,6 +237,7 @@ private:
|
|||||||
QByteArray m_outputContent;
|
QByteArray m_outputContent;
|
||||||
PDFPageContentProcessorState m_currentState;
|
PDFPageContentProcessorState m_currentState;
|
||||||
PDFFontPointer m_textFont;
|
PDFFontPointer m_textFont;
|
||||||
|
QStringList m_errors;
|
||||||
};
|
};
|
||||||
|
|
||||||
class PDF4QTLIBCORESHARED_EXPORT PDFPageContentEditorProcessor : public PDFPageContentProcessor
|
class PDF4QTLIBCORESHARED_EXPORT PDFPageContentEditorProcessor : public PDFPageContentProcessor
|
||||||
|
@ -504,6 +504,26 @@ public:
|
|||||||
/// Returns true, if we are in a text processing
|
/// Returns true, if we are in a text processing
|
||||||
bool isTextProcessing() const;
|
bool isTextProcessing() const;
|
||||||
|
|
||||||
|
|
||||||
|
/// Converts PDF line cap to Qt's pen cap style. Function always succeeds,
|
||||||
|
/// if invalid \p lineCap occurs, then some valid pen cap style is returned.
|
||||||
|
/// \param lineCap PDF Line cap style (see PDF Reference 1.7, values can be 0, 1, and 2)
|
||||||
|
static Qt::PenCapStyle convertLineCapToPenCapStyle(PDFInteger lineCap);
|
||||||
|
|
||||||
|
/// Converts Qt's pen cap style to PDF's line cap style (defined in the PDF Reference)
|
||||||
|
/// \param penCapStyle Qt's pen cap style to be converted
|
||||||
|
static PDFInteger convertPenCapStyleToLineCap(Qt::PenCapStyle penCapStyle);
|
||||||
|
|
||||||
|
/// Converts PDF line join to Qt's pen join style. Function always succeeds,
|
||||||
|
/// if invalid \p lineJoin occurs, then some valid pen join style is returned.
|
||||||
|
/// \param lineJoin PDF Line join style (see PDF Reference 1.7, values can be 0, 1, and 2)
|
||||||
|
static Qt::PenJoinStyle convertLineJoinToPenJoinStyle(PDFInteger lineJoin);
|
||||||
|
|
||||||
|
/// Converts Qt's pen join style to PDF's line join style (defined in the PDF Reference)
|
||||||
|
/// \param penJoinStyle Qt's pen join style to be converted
|
||||||
|
static PDFInteger convertPenJoinStyleToLineJoin(Qt::PenJoinStyle penJoinStyle);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
struct PDFTransparencyGroup
|
struct PDFTransparencyGroup
|
||||||
@ -900,24 +920,6 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts PDF line cap to Qt's pen cap style. Function always succeeds,
|
|
||||||
/// if invalid \p lineCap occurs, then some valid pen cap style is returned.
|
|
||||||
/// \param lineCap PDF Line cap style (see PDF Reference 1.7, values can be 0, 1, and 2)
|
|
||||||
static Qt::PenCapStyle convertLineCapToPenCapStyle(PDFInteger lineCap);
|
|
||||||
|
|
||||||
/// Converts Qt's pen cap style to PDF's line cap style (defined in the PDF Reference)
|
|
||||||
/// \param penCapStyle Qt's pen cap style to be converted
|
|
||||||
static PDFInteger convertPenCapStyleToLineCap(Qt::PenCapStyle penCapStyle);
|
|
||||||
|
|
||||||
/// Converts PDF line join to Qt's pen join style. Function always succeeds,
|
|
||||||
/// if invalid \p lineJoin occurs, then some valid pen join style is returned.
|
|
||||||
/// \param lineJoin PDF Line join style (see PDF Reference 1.7, values can be 0, 1, and 2)
|
|
||||||
static Qt::PenJoinStyle convertLineJoinToPenJoinStyle(PDFInteger lineJoin);
|
|
||||||
|
|
||||||
/// Converts Qt's pen join style to PDF's line join style (defined in the PDF Reference)
|
|
||||||
/// \param penJoinStyle Qt's pen join style to be converted
|
|
||||||
static PDFInteger convertPenJoinStyleToLineJoin(Qt::PenJoinStyle penJoinStyle);
|
|
||||||
|
|
||||||
// General graphic state w, J, j, M, d, ri, i, gs
|
// General graphic state w, J, j, M, d, ri, i, gs
|
||||||
void operatorSetLineWidth(PDFReal lineWidth); ///< w, sets the line width
|
void operatorSetLineWidth(PDFReal lineWidth); ///< w, sets the line width
|
||||||
void operatorSetLineCap(PDFInteger lineCap); ///< J, sets the line cap
|
void operatorSetLineCap(PDFInteger lineCap); ///< J, sets the line cap
|
||||||
|
Loading…
x
Reference in New Issue
Block a user