mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-03-12 01:10:06 +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
|
||||
{
|
||||
Q_ASSERT(dynamic_cast<const PDFDictionary*>(other));
|
||||
const PDFDictionary* otherStream = static_cast<const PDFDictionary*>(other);
|
||||
return m_dictionary == otherStream->m_dictionary;
|
||||
const PDFDictionary* otherDictionary = static_cast<const PDFDictionary*>(other);
|
||||
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
|
||||
|
@ -364,6 +364,8 @@ public:
|
||||
|
||||
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,
|
||||
/// then valid reference to the null object is returned.
|
||||
/// \param key Key
|
||||
|
@ -17,6 +17,8 @@
|
||||
|
||||
#include "pdfpagecontenteditorprocessor.h"
|
||||
#include "pdfdocumentbuilder.h"
|
||||
#include "pdfobject.h"
|
||||
#include "pdfstreamfilters.h"
|
||||
|
||||
#include <QStringBuilder>
|
||||
#include <QXmlStreamReader>
|
||||
@ -968,7 +970,7 @@ void PDFPageContentEditorContentStreamBuilder::writeStateDifference(QTextStream&
|
||||
QString blendModeName = PDFBlendModeInfo::getBlendModeName(m_currentState.getBlendMode());
|
||||
|
||||
stateDictionary.beginDictionaryItem("BM");
|
||||
stateDictionary << WrapName(blendModeName);
|
||||
stateDictionary << WrapName(blendModeName.toLatin1());
|
||||
stateDictionary.endDictionaryItem();
|
||||
}
|
||||
|
||||
@ -1016,7 +1018,7 @@ void PDFPageContentEditorContentStreamBuilder::writeStateDifference(QTextStream&
|
||||
QByteArray currentKey = QString("s%1").arg(++i).toLatin1();
|
||||
if (!m_graphicStateDictionary.hasKey(currentKey))
|
||||
{
|
||||
m_graphicStateDictionary.addEntry(currentKey, std::move(stateObject));
|
||||
m_graphicStateDictionary.addEntry(PDFInplaceOrMemoryString(currentKey), std::move(stateObject));
|
||||
key = currentKey;
|
||||
break;
|
||||
}
|
||||
@ -1038,9 +1040,8 @@ void PDFPageContentEditorContentStreamBuilder::writeElement(const PDFEditedPageC
|
||||
if (const PDFEditedPageContentElementImage* imageElement = element->asImage())
|
||||
{
|
||||
QImage image = imageElement->getImage();
|
||||
PDFObject imageObject = imageElement->getImageObject();
|
||||
|
||||
writeImage(image);
|
||||
writeImage(stream, image);
|
||||
}
|
||||
|
||||
if (const PDFEditedPageContentElementPath* pathElement = element->asPath())
|
||||
@ -1361,6 +1362,45 @@ void PDFPageContentEditorContentStreamBuilder::writeText(QTextStream& stream, co
|
||||
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)
|
||||
{
|
||||
m_textFont = nullptr;
|
||||
@ -1404,12 +1444,15 @@ QByteArray PDFPageContentEditorContentStreamBuilder::selectFont(const QByteArray
|
||||
}
|
||||
|
||||
m_textFont = PDFFont::createFont(fontObject, font, m_document);
|
||||
return defaultFontKey;
|
||||
}
|
||||
|
||||
return font;
|
||||
}
|
||||
|
||||
void PDFPageContentEditorContentStreamBuilder::addError(const QString& error)
|
||||
{
|
||||
|
||||
m_errors << error;
|
||||
}
|
||||
|
||||
} // namespace pdf
|
||||
|
@ -225,6 +225,8 @@ private:
|
||||
bool isFilling);
|
||||
void writeText(QTextStream& stream, const QString& text);
|
||||
|
||||
void writeImage(QTextStream& stream, const QImage& image);
|
||||
|
||||
QByteArray selectFont(const QByteArray& font);
|
||||
void addError(const QString& error);
|
||||
|
||||
@ -235,6 +237,7 @@ private:
|
||||
QByteArray m_outputContent;
|
||||
PDFPageContentProcessorState m_currentState;
|
||||
PDFFontPointer m_textFont;
|
||||
QStringList m_errors;
|
||||
};
|
||||
|
||||
class PDF4QTLIBCORESHARED_EXPORT PDFPageContentEditorProcessor : public PDFPageContentProcessor
|
||||
|
@ -504,6 +504,26 @@ public:
|
||||
/// Returns true, if we are in a text processing
|
||||
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:
|
||||
|
||||
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
|
||||
void operatorSetLineWidth(PDFReal lineWidth); ///< w, sets the line width
|
||||
void operatorSetLineCap(PDFInteger lineCap); ///< J, sets the line cap
|
||||
|
Loading…
x
Reference in New Issue
Block a user