mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-01-19 03:49:50 +01:00
Updated named trees in catalog to fulfill PDF 2.0 specification
This commit is contained in:
parent
534ff8e814
commit
fa30ed37bb
@ -69,10 +69,10 @@ size_t PDFCatalog::getPageIndexFromPageReference(PDFObjectReference reference) c
|
|||||||
return INVALID_PAGE_INDEX;
|
return INVALID_PAGE_INDEX;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PDFDestination* PDFCatalog::getDestination(const QByteArray& key) const
|
const PDFDestination* PDFCatalog::getNamedDestination(const QByteArray& key) const
|
||||||
{
|
{
|
||||||
auto it = m_destinations.find(key);
|
auto it = m_namedDestinations.find(key);
|
||||||
if (it != m_destinations.cend())
|
if (it != m_namedDestinations.cend())
|
||||||
{
|
{
|
||||||
return &it->second;
|
return &it->second;
|
||||||
}
|
}
|
||||||
@ -80,6 +80,94 @@ const PDFDestination* PDFCatalog::getDestination(const QByteArray& key) const
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PDFActionPtr PDFCatalog::getNamedJavaScriptAction(const QByteArray& key) const
|
||||||
|
{
|
||||||
|
auto it = m_namedJavaScriptActions.find(key);
|
||||||
|
if (it != m_namedJavaScriptActions.cend())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFObject PDFCatalog::getNamedAppearanceStream(const QByteArray& key) const
|
||||||
|
{
|
||||||
|
auto it = m_namedAppearanceStreams.find(key);
|
||||||
|
if (it != m_namedAppearanceStreams.cend())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PDFObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFObject PDFCatalog::getNamedPage(const QByteArray& key) const
|
||||||
|
{
|
||||||
|
auto it = m_namedPages.find(key);
|
||||||
|
if (it != m_namedPages.cend())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PDFObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFObject PDFCatalog::getNamedTemplate(const QByteArray& key) const
|
||||||
|
{
|
||||||
|
auto it = m_namedTemplates.find(key);
|
||||||
|
if (it != m_namedTemplates.cend())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PDFObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFObject PDFCatalog::getNamedDigitalIdentifier(const QByteArray& key) const
|
||||||
|
{
|
||||||
|
auto it = m_namedDigitalIdentifiers.find(key);
|
||||||
|
if (it != m_namedDigitalIdentifiers.cend())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PDFObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFObject PDFCatalog::getNamedUrl(const QByteArray& key) const
|
||||||
|
{
|
||||||
|
auto it = m_namedUniformResourceLocators.find(key);
|
||||||
|
if (it != m_namedUniformResourceLocators.cend())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PDFObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFObject PDFCatalog::getNamedAlternateRepresentation(const QByteArray& key) const
|
||||||
|
{
|
||||||
|
auto it = m_namedAlternateRepresentations.find(key);
|
||||||
|
if (it != m_namedAlternateRepresentations.cend())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PDFObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
PDFObject PDFCatalog::getNamedRendition(const QByteArray& key) const
|
||||||
|
{
|
||||||
|
auto it = m_namedRenditions.find(key);
|
||||||
|
if (it != m_namedRenditions.cend())
|
||||||
|
{
|
||||||
|
return it->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PDFObject();
|
||||||
|
}
|
||||||
|
|
||||||
PDFCatalog PDFCatalog::parse(const PDFObject& catalog, const PDFDocument* document)
|
PDFCatalog PDFCatalog::parse(const PDFObject& catalog, const PDFDocument* document)
|
||||||
{
|
{
|
||||||
if (!catalog.isDictionary())
|
if (!catalog.isDictionary())
|
||||||
@ -171,9 +259,21 @@ PDFCatalog PDFCatalog::parse(const PDFObject& catalog, const PDFDocument* docume
|
|||||||
return PDFDestination::parse(storage, qMove(object));
|
return PDFDestination::parse(storage, qMove(object));
|
||||||
};
|
};
|
||||||
|
|
||||||
catalogObject.m_destinations = PDFNameTreeLoader<PDFDestination>::parse(&document->getStorage(), namesDictionary->get("Dests"), parseDestination);
|
auto getObject = [](const PDFObjectStorage*, PDFObject object)
|
||||||
catalogObject.m_javaScriptActions = PDFNameTreeLoader<PDFActionPtr>::parse(&document->getStorage(), namesDictionary->get("JavaScript"), &PDFAction::parse);
|
{
|
||||||
catalogObject.m_embeddedFiles = PDFNameTreeLoader<PDFFileSpecification>::parse(&document->getStorage(), namesDictionary->get("EmbeddedFiles"), &PDFFileSpecification::parse);
|
return qMove(object);
|
||||||
|
};
|
||||||
|
|
||||||
|
catalogObject.m_namedDestinations = PDFNameTreeLoader<PDFDestination>::parse(&document->getStorage(), namesDictionary->get("Dests"), parseDestination);
|
||||||
|
catalogObject.m_namedAppearanceStreams = PDFNameTreeLoader<PDFObject>::parse(&document->getStorage(), namesDictionary->get("AP"), getObject);
|
||||||
|
catalogObject.m_namedJavaScriptActions = PDFNameTreeLoader<PDFActionPtr>::parse(&document->getStorage(), namesDictionary->get("JavaScript"), &PDFAction::parse);
|
||||||
|
catalogObject.m_namedPages = PDFNameTreeLoader<PDFObject>::parse(&document->getStorage(), namesDictionary->get("Pages"), getObject);
|
||||||
|
catalogObject.m_namedTemplates = PDFNameTreeLoader<PDFObject>::parse(&document->getStorage(), namesDictionary->get("Templates"), getObject);
|
||||||
|
catalogObject.m_namedDigitalIdentifiers = PDFNameTreeLoader<PDFObject>::parse(&document->getStorage(), namesDictionary->get("IDS"), getObject);
|
||||||
|
catalogObject.m_namedUniformResourceLocators = PDFNameTreeLoader<PDFObject>::parse(&document->getStorage(), namesDictionary->get("URLS"), getObject);
|
||||||
|
catalogObject.m_namedEmbeddedFiles = PDFNameTreeLoader<PDFFileSpecification>::parse(&document->getStorage(), namesDictionary->get("EmbeddedFiles"), &PDFFileSpecification::parse);
|
||||||
|
catalogObject.m_namedAlternateRepresentations = PDFNameTreeLoader<PDFObject>::parse(&document->getStorage(), namesDictionary->get("AlternatePresentations"), getObject);
|
||||||
|
catalogObject.m_namedRenditions = PDFNameTreeLoader<PDFObject>::parse(&document->getStorage(), namesDictionary->get("Renditions"), getObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Examine "Dests" dictionary
|
// Examine "Dests" dictionary
|
||||||
@ -182,7 +282,7 @@ PDFCatalog PDFCatalog::parse(const PDFObject& catalog, const PDFDocument* docume
|
|||||||
const size_t count = destsDictionary->getCount();
|
const size_t count = destsDictionary->getCount();
|
||||||
for (size_t i = 0; i < count; ++i)
|
for (size_t i = 0; i < count; ++i)
|
||||||
{
|
{
|
||||||
catalogObject.m_destinations[destsDictionary->getKey(i).getString()] = PDFDestination::parse(&document->getStorage(), destsDictionary->getValue(i));
|
catalogObject.m_namedDestinations[destsDictionary->getKey(i).getString()] = PDFDestination::parse(&document->getStorage(), destsDictionary->getValue(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -499,7 +499,7 @@ public:
|
|||||||
PageLayout getPageLayout() const { return m_pageLayout; }
|
PageLayout getPageLayout() const { return m_pageLayout; }
|
||||||
PageMode getPageMode() const { return m_pageMode; }
|
PageMode getPageMode() const { return m_pageMode; }
|
||||||
const QByteArray& getBaseURI() const { return m_baseURI; }
|
const QByteArray& getBaseURI() const { return m_baseURI; }
|
||||||
const std::map<QByteArray, PDFFileSpecification>& getEmbeddedFiles() const { return m_embeddedFiles; }
|
const std::map<QByteArray, PDFFileSpecification>& getEmbeddedFiles() const { return m_namedEmbeddedFiles; }
|
||||||
const PDFObject& getFormObject() const { return m_formObject; }
|
const PDFObject& getFormObject() const { return m_formObject; }
|
||||||
const PDFDeveloperExtensions& getExtensions() const { return m_extensions; }
|
const PDFDeveloperExtensions& getExtensions() const { return m_extensions; }
|
||||||
const PDFDocumentSecurityStore& getDocumentSecurityStore() const { return m_documentSecurityStore; }
|
const PDFDocumentSecurityStore& getDocumentSecurityStore() const { return m_documentSecurityStore; }
|
||||||
@ -532,7 +532,57 @@ public:
|
|||||||
/// then nullptr is returned.
|
/// then nullptr is returned.
|
||||||
/// \param key Destination key
|
/// \param key Destination key
|
||||||
/// \returns Pointer to the destination, or nullptr
|
/// \returns Pointer to the destination, or nullptr
|
||||||
const PDFDestination* getDestination(const QByteArray& key) const;
|
const PDFDestination* getNamedDestination(const QByteArray& key) const;
|
||||||
|
|
||||||
|
/// Returns javascript action using the key. If javascript action is not found,
|
||||||
|
/// then nullptr is returned.
|
||||||
|
/// \param key Action key
|
||||||
|
/// \returns Javascript action, or nullptr
|
||||||
|
PDFActionPtr getNamedJavaScriptAction(const QByteArray& key) const;
|
||||||
|
|
||||||
|
/// Returns appearance stream using the key. If appearance stream is not found,
|
||||||
|
/// then empty object is returned.
|
||||||
|
/// \param key Appearance stream key
|
||||||
|
/// \returns Appearance, or nullptr
|
||||||
|
PDFObject getNamedAppearanceStream(const QByteArray& key) const;
|
||||||
|
|
||||||
|
/// Returns named page using the key. If named page is not found,
|
||||||
|
/// then empty object is returned.
|
||||||
|
/// \param key Page key
|
||||||
|
/// \returns Page, or nullptr
|
||||||
|
PDFObject getNamedPage(const QByteArray& key) const;
|
||||||
|
|
||||||
|
/// Returns named template using the key. If named template is not found,
|
||||||
|
/// then empty object is returned.
|
||||||
|
/// \param key Template key
|
||||||
|
/// \returns Template, or nullptr
|
||||||
|
PDFObject getNamedTemplate(const QByteArray& key) const;
|
||||||
|
|
||||||
|
/// Returns named digital identifier using the key. If named digital identifier is not found,
|
||||||
|
/// then empty object is returned. Digital identifiers are used in Web Capture functionality.
|
||||||
|
/// See also PDF 2.0 specification.
|
||||||
|
/// \param key Digital identifier key
|
||||||
|
/// \returns Digital identifier, or nullptr
|
||||||
|
PDFObject getNamedDigitalIdentifier(const QByteArray& key) const;
|
||||||
|
|
||||||
|
/// Returns named url using the key. If named url is not found,
|
||||||
|
/// then empty object is returned. Urls are used in Web Capture functionality.
|
||||||
|
/// See also PDF 2.0 specification.
|
||||||
|
/// \param key Url key
|
||||||
|
/// \returns Url, or nullptr
|
||||||
|
PDFObject getNamedUrl(const QByteArray& key) const;
|
||||||
|
|
||||||
|
/// Returns named alternate representation using the key. If named alternate representation is not found,
|
||||||
|
/// then empty object is returned.
|
||||||
|
/// \param key Alternate representation key
|
||||||
|
/// \returns Alternate representation, or nullptr
|
||||||
|
PDFObject getNamedAlternateRepresentation(const QByteArray& key) const;
|
||||||
|
|
||||||
|
/// Returns named rendition using the key. If named rendition is not found,
|
||||||
|
/// then empty object is returned.
|
||||||
|
/// \param key Rendition key
|
||||||
|
/// \returns Rendition, or nullptr
|
||||||
|
PDFObject getNamedRendition(const QByteArray& key) const;
|
||||||
|
|
||||||
/// Parses catalog from catalog dictionary. If object cannot be parsed, or error occurs,
|
/// Parses catalog from catalog dictionary. If object cannot be parsed, or error occurs,
|
||||||
/// then exception is thrown.
|
/// then exception is thrown.
|
||||||
@ -580,9 +630,16 @@ private:
|
|||||||
PDFObject m_documentPartRoot;
|
PDFObject m_documentPartRoot;
|
||||||
|
|
||||||
// Maps from Names dictionary
|
// Maps from Names dictionary
|
||||||
std::map<QByteArray, PDFDestination> m_destinations;
|
std::map<QByteArray, PDFDestination> m_namedDestinations;
|
||||||
std::map<QByteArray, PDFActionPtr> m_javaScriptActions;
|
std::map<QByteArray, PDFObject> m_namedAppearanceStreams;
|
||||||
std::map<QByteArray, PDFFileSpecification> m_embeddedFiles;
|
std::map<QByteArray, PDFActionPtr> m_namedJavaScriptActions;
|
||||||
|
std::map<QByteArray, PDFObject> m_namedPages;
|
||||||
|
std::map<QByteArray, PDFObject> m_namedTemplates;
|
||||||
|
std::map<QByteArray, PDFObject> m_namedDigitalIdentifiers;
|
||||||
|
std::map<QByteArray, PDFObject> m_namedUniformResourceLocators;
|
||||||
|
std::map<QByteArray, PDFFileSpecification> m_namedEmbeddedFiles;
|
||||||
|
std::map<QByteArray, PDFObject> m_namedAlternateRepresentations;
|
||||||
|
std::map<QByteArray, PDFObject> m_namedRenditions;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace pdf
|
} // namespace pdf
|
||||||
|
@ -59,6 +59,11 @@ PDFPageInheritableAttributes PDFPageInheritableAttributes::parse(const PDFPageIn
|
|||||||
rotation = rotation - fullCircles * 360;
|
rotation = rotation - fullCircles * 360;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (rotation < 0)
|
||||||
|
{
|
||||||
|
rotation += 360;
|
||||||
|
}
|
||||||
|
|
||||||
switch (rotation)
|
switch (rotation)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -405,7 +405,7 @@ void PDFViewerMainWindow::onActionTriggered(const pdf::PDFAction* action)
|
|||||||
pdf::PDFDestination destination = typedAction->getDestination();
|
pdf::PDFDestination destination = typedAction->getDestination();
|
||||||
if (destination.getDestinationType() == pdf::DestinationType::Named)
|
if (destination.getDestinationType() == pdf::DestinationType::Named)
|
||||||
{
|
{
|
||||||
if (const pdf::PDFDestination* targetDestination = m_pdfDocument->getCatalog()->getDestination(destination.getName()))
|
if (const pdf::PDFDestination* targetDestination = m_pdfDocument->getCatalog()->getNamedDestination(destination.getName()))
|
||||||
{
|
{
|
||||||
destination = *targetDestination;
|
destination = *targetDestination;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user