Unite tool (basics)

This commit is contained in:
Jakub Melka
2020-10-31 17:11:51 +01:00
parent c58158e3ee
commit 5d5973772a
11 changed files with 608 additions and 153 deletions

View File

@@ -147,7 +147,7 @@ private:
/// then if object with valid data is not found, default value is used, and second one,
/// without default value, if valid data are not found, then exception is thrown.
/// This class uses Decorator design pattern.
class PDFDocumentDataLoaderDecorator
class PDFFORQTLIBSHARED_EXPORT PDFDocumentDataLoaderDecorator
{
public:
explicit PDFDocumentDataLoaderDecorator(const PDFDocument* document);

View File

@@ -752,6 +752,11 @@ void PDFDocumentBuilder::mergeTo(PDFObjectReference reference, PDFObject object)
m_storage.setObject(reference, PDFObjectManipulator::merge(m_storage.getObject(reference), qMove(object), PDFObjectManipulator::RemoveNullObjects));
}
void PDFDocumentBuilder::setObject(PDFObjectReference reference, PDFObject object)
{
m_storage.setObject(reference, qMove(object));
}
void PDFDocumentBuilder::appendTo(PDFObjectReference reference, PDFObject object)
{
m_storage.setObject(reference, PDFObjectManipulator::merge(m_storage.getObject(reference), qMove(object), PDFObjectManipulator::ConcatenateArrays));
@@ -1016,6 +1021,20 @@ std::vector<PDFObject> PDFDocumentBuilder::copyFrom(const std::vector<PDFObject>
return result;
}
std::vector<PDFObject> PDFDocumentBuilder::createObjectsFromReferences(const std::vector<PDFObjectReference>& references)
{
std::vector<PDFObject> result;
std::transform(references.cbegin(), references.cend(), std::back_inserter(result), [](const PDFObjectReference& reference) { return PDFObject::createReference(reference); });
return result;
}
std::vector<PDFObjectReference> PDFDocumentBuilder::createReferencesFromObjects(const std::vector<PDFObject>& objects)
{
std::vector<PDFObjectReference> result;
std::transform(objects.cbegin(), objects.cend(), std::back_inserter(result), [](const PDFObject& object) { Q_ASSERT(object.isReference()); return object.getReference(); });
return result;
}
const PDFFormManager* PDFDocumentBuilder::getFormManager() const
{
return m_formManager;
@@ -2863,6 +2882,23 @@ PDFObject PDFDocumentBuilder::createTrailerDictionary(PDFObjectReference catalog
}
void PDFDocumentBuilder::removeDocumentActions()
{
PDFObjectFactory objectBuilder;
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("OpenAction");
objectBuilder << PDFObject();
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("AA");
objectBuilder << PDFObject();
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObject updatedCatalog = objectBuilder.takeObject();
mergeTo(getCatalogReference(), updatedCatalog);
}
void PDFDocumentBuilder::removeOutline()
{
PDFObjectFactory objectBuilder;
@@ -2877,6 +2913,37 @@ void PDFDocumentBuilder::removeOutline()
}
void PDFDocumentBuilder::removeStructureTree()
{
PDFObjectFactory objectBuilder;
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("StructTreeRoot");
objectBuilder << PDFObject();
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("MarkInfo");
objectBuilder << PDFObject();
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObject updatedCatalog = objectBuilder.takeObject();
mergeTo(getCatalogReference(), updatedCatalog);
}
void PDFDocumentBuilder::removeThreads()
{
PDFObjectFactory objectBuilder;
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Threads");
objectBuilder << PDFObject();
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObject updatedCatalog = objectBuilder.takeObject();
mergeTo(getCatalogReference(), updatedCatalog);
}
void PDFDocumentBuilder::setAnnotationAppearanceState(PDFObjectReference annotation,
QByteArray appearanceState)
{
@@ -3245,47 +3312,13 @@ void PDFDocumentBuilder::updateTrailerDictionary(PDFInteger objectCount)
}
void PDFDocumentBuilder::removeThreads()
void PDFDocumentBuilder::setCatalogOptionalContentProperties(PDFObjectReference ocProperties)
{
PDFObjectFactory objectBuilder;
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("Threads");
objectBuilder << PDFObject();
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObject updatedCatalog = objectBuilder.takeObject();
mergeTo(getCatalogReference(), updatedCatalog);
}
void PDFDocumentBuilder::removeDocumentActions()
{
PDFObjectFactory objectBuilder;
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("OpenAction");
objectBuilder << PDFObject();
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("AA");
objectBuilder << PDFObject();
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObject updatedCatalog = objectBuilder.takeObject();
mergeTo(getCatalogReference(), updatedCatalog);
}
void PDFDocumentBuilder::removeStructureTree()
{
PDFObjectFactory objectBuilder;
objectBuilder.beginDictionary();
objectBuilder.beginDictionaryItem("StructTreeRoot");
objectBuilder << PDFObject();
objectBuilder.endDictionaryItem();
objectBuilder.beginDictionaryItem("MarkInfo");
objectBuilder << PDFObject();
objectBuilder.beginDictionaryItem("OCProperties");
objectBuilder << ocProperties;
objectBuilder.endDictionaryItem();
objectBuilder.endDictionary();
PDFObject updatedCatalog = objectBuilder.takeObject();

View File

@@ -302,6 +302,52 @@ public:
/// be flattened to use this function. \sa flattenPageTree
std::vector<PDFObjectReference> getPages() const;
/// Adds a new objet to the object storage
/// \param object Object
PDFObjectReference addObject(PDFObject object);
/// Copies objects from another storage. Objects have adjusted references to match
/// this storage references and objects are added after the last objects of active storage.
/// This function can also automatically create references from direct objects passed
/// by parameter \p objects, if \p createReferences is set to true.
/// \param objects Objects, which we want to copy from another storage
/// \param storage Storage, from which we are copying from
/// \param createReferences Create references from \p objects
std::vector<PDFObject> copyFrom(const std::vector<PDFObject>& objects, const PDFObjectStorage& storage, bool createReferences);
/// Creates object list from reference list (objects are references)
/// \param references References
static std::vector<PDFObject> createObjectsFromReferences(const std::vector<PDFObjectReference>& references);
/// Creates reference list from object list. Object list must be
/// a list of references, it is invalid to pass this function objects,
/// which are not references.
/// \param objects Objects with references
static std::vector<PDFObjectReference> createReferencesFromObjects(const std::vector<PDFObject>& objects);
/// Returns catalog reference
PDFObjectReference getCatalogReference() const;
/// Returns object storage
const PDFObjectStorage* getStorage() const { return &m_storage; }
/// Appends object to target object. Targed object reference must be valid.
/// Arrays are concatenated.
/// \param reference Target object reference
/// \param object Object to be appended
void appendTo(PDFObjectReference reference, PDFObject object);
/// Merges object to target object. Targed object reference must be valid.
/// Arrays are not concatenated.
/// \param reference Target object reference
/// \param object Object to be merged
void mergeTo(PDFObjectReference reference, PDFObject object);
/// Sets object by reference
/// \param reference Target object reference
/// \param object Object to be set
void setObject(PDFObjectReference reference, PDFObject object);
/* START GENERATED CODE */
/// Appends a new page after last page.
@@ -823,10 +869,22 @@ public:
PDFObject createTrailerDictionary(PDFObjectReference catalog);
/// Removes document actions from document catalog.
void removeDocumentActions();
/// Removes outline tree from document catalog.
void removeOutline();
/// Removes structure tree from document catalog.
void removeStructureTree();
/// Removes threads from document catalog.
void removeThreads();
/// Sets annotation appearance state.
/// \param annotation Annotation
/// \param appearanceState Appearance state
@@ -988,42 +1046,22 @@ public:
void updateTrailerDictionary(PDFInteger objectCount);
/// Removes threads from document catalog.
void removeThreads();
/// Removes document actions from document catalog.
void removeDocumentActions();
/// Removes structure tree from document catalog.
void removeStructureTree();
/// Set optional content properties to catalog.
/// \param ocProperties Reference to catalog optional content properties.
void setCatalogOptionalContentProperties(PDFObjectReference ocProperties);
/* END GENERATED CODE */
private:
PDFObjectReference addObject(PDFObject object);
void mergeTo(PDFObjectReference reference, PDFObject object);
void appendTo(PDFObjectReference reference, PDFObject object);
QRectF getPopupWindowRect(const QRectF& rectangle) const;
QString getProducerString() const;
PDFObjectReference getPageTreeRoot() const;
PDFInteger getPageTreeRootChildCount() const;
PDFObjectReference getDocumentInfo() const;
PDFObjectReference getCatalogReference() const;
void updateDocumentInfo(PDFObject info);
QRectF getPolygonsBoundingRect(const Polygons& Polygons) const;
/// Copies objects from another storage. Objects have adjusted references to match
/// this storage references and objects are added after the last objects of active storage.
/// This function can also automatically create references from direct objects passed
/// by parameter \p objects, if \p createReferences is set to true.
/// \param objects Objects, which we want to copy from another storage
/// \param storage Storage, from which we are copying from
/// \param createReferences Create references from \p objects
std::vector<PDFObject> copyFrom(const std::vector<PDFObject>& objects, const PDFObjectStorage& storage, bool createReferences);
PDFObjectStorage m_storage;
PDFVersion m_version;
const PDFFormManager* m_formManager = nullptr;

View File

@@ -427,6 +427,65 @@ PDFObject PDFObjectManipulator::removeNullObjects(PDFObject object)
return merge(object, object, RemoveNullObjects);
}
PDFObject PDFObjectManipulator::removeDuplicitReferencesInArrays(PDFObject object)
{
switch (object.getType())
{
case PDFObject::Type::Stream:
{
const PDFStream* stream = object.getStream();
PDFDictionary dictionary = *stream->getDictionary();
for (size_t i = 0, count = dictionary.getCount(); i < count; ++i)
{
dictionary.setEntry(dictionary.getKey(i), removeDuplicitReferencesInArrays(dictionary.getValue(i)));
}
return PDFObject::createStream(std::make_shared<PDFStream>(qMove(dictionary), QByteArray(*stream->getContent())));
}
case PDFObject::Type::Dictionary:
{
PDFDictionary dictionary = *object.getDictionary();
for (size_t i = 0, count = dictionary.getCount(); i < count; ++i)
{
dictionary.setEntry(dictionary.getKey(i), removeDuplicitReferencesInArrays(dictionary.getValue(i)));
}
return PDFObject::createDictionary(std::make_shared<PDFDictionary>(qMove(dictionary)));
}
case PDFObject::Type::Array:
{
PDFArray array;
std::set<PDFObjectReference> usedReferences;
for (const PDFObject& object : *object.getArray())
{
if (object.isReference())
{
PDFObjectReference reference = object.getReference();
if (!usedReferences.count(reference))
{
usedReferences.insert(reference);
array.appendItem(PDFObject::createReference(reference));
}
}
else
{
array.appendItem(removeDuplicitReferencesInArrays(object));
}
}
return PDFObject::createArray(std::make_shared<PDFArray>(qMove(array)));
}
default:
return object;
}
}
QByteArray PDFStringRef::getString() const
{
if (inplaceString)

View File

@@ -476,7 +476,7 @@ private:
QByteArray m_content;
};
class PDFObjectManipulator
class PDFFORQTLIBSHARED_EXPORT PDFObjectManipulator
{
public:
explicit PDFObjectManipulator() = delete;
@@ -503,6 +503,10 @@ public:
/// Remove null objects from all dictionaries
/// \param object Object
static PDFObject removeNullObjects(PDFObject object);
/// Remove duplicit references from arrays
/// \param object Object
static PDFObject removeDuplicitReferencesInArrays(PDFObject object);
};
} // namespace pdf