diff --git a/CodeGenerator/codegenerator.h b/CodeGenerator/codegenerator.h index 0fd190b..dc71632 100644 --- a/CodeGenerator/codegenerator.h +++ b/CodeGenerator/codegenerator.h @@ -157,7 +157,8 @@ public: _AnnotationLineEnding, _AnnotationBorderStyle, _FileAttachmentIcon, - _Stamp + _Stamp, + _PDFDestination }; Q_ENUM(DataType) diff --git a/PdfForQtLib/sources/pdfaction.cpp b/PdfForQtLib/sources/pdfaction.cpp index dd3ffeb..ec789bb 100644 --- a/PdfForQtLib/sources/pdfaction.cpp +++ b/PdfForQtLib/sources/pdfaction.cpp @@ -469,6 +469,210 @@ PDFDestination PDFDestination::parse(const PDFObjectStorage* storage, PDFObject return result; } +void PDFDestination::setDestinationType(DestinationType destinationType) +{ + m_destinationType = destinationType; +} + +void PDFDestination::setLeft(PDFReal left) +{ + m_left = left; +} + +void PDFDestination::setTop(PDFReal top) +{ + m_top = top; +} + +void PDFDestination::setRight(PDFReal right) +{ + m_right = right; +} + +void PDFDestination::setBottom(PDFReal bottom) +{ + m_bottom = bottom; +} + +void PDFDestination::setZoom(PDFReal zoom) +{ + m_zoom = zoom; +} + +void PDFDestination::setName(const QByteArray& name) +{ + m_name = name; +} + +void PDFDestination::setPageReference(PDFObjectReference pageReference) +{ + m_pageReference = pageReference; +} + +void PDFDestination::setPageIndex(PDFInteger pageIndex) +{ + m_pageIndex = pageIndex; +} + +PDFDestination PDFDestination::createXYZ(PDFObjectReference page, PDFReal left, PDFReal top, PDFReal zoom) +{ + PDFDestination result; + result.setDestinationType(DestinationType::XYZ); + result.setPageReference(page); + result.setLeft(left); + result.setTop(top); + result.setZoom(zoom); + return result; +} + +PDFDestination PDFDestination::createFit(PDFObjectReference page) +{ + PDFDestination result; + result.setDestinationType(DestinationType::Fit); + result.setPageReference(page); + return result; +} + +PDFDestination PDFDestination::createFitH(PDFObjectReference page, PDFReal top) +{ + PDFDestination result; + result.setDestinationType(DestinationType::FitH); + result.setPageReference(page); + result.setTop(top); + return result; +} + +PDFDestination PDFDestination::createFitV(PDFObjectReference page, PDFReal left) +{ + PDFDestination result; + result.setDestinationType(DestinationType::FitV); + result.setPageReference(page); + result.setLeft(left); + return result; +} + +PDFDestination PDFDestination::createFitR(PDFObjectReference page, PDFReal left, PDFReal top, PDFReal right, PDFReal bottom) +{ + PDFDestination result; + result.setDestinationType(DestinationType::FitR); + result.setPageReference(page); + result.setLeft(left); + result.setTop(top); + result.setRight(right); + result.setBottom(bottom); + return result; +} + +PDFDestination PDFDestination::createFitB(PDFObjectReference page) +{ + PDFDestination result; + result.setDestinationType(DestinationType::FitB); + result.setPageReference(page); + return result; +} + +PDFDestination PDFDestination::createFitBH(PDFObjectReference page, PDFReal top) +{ + PDFDestination result; + result.setDestinationType(DestinationType::FitBH); + result.setPageReference(page); + result.setTop(top); + return result; +} + +PDFDestination PDFDestination::createFitBV(PDFObjectReference page, PDFReal left) +{ + PDFDestination result; + result.setDestinationType(DestinationType::FitBV); + result.setPageReference(page); + result.setLeft(left); + return result; +} + +PDFDestination PDFDestination::createNamed(const QByteArray& name) +{ + PDFDestination result; + result.setDestinationType(DestinationType::Named); + result.setName(name); + return result; +} + +bool PDFDestination::hasLeft() const +{ + switch (m_destinationType) + { + case DestinationType::XYZ: + case DestinationType::FitV: + case DestinationType::FitBV: + case DestinationType::FitR: + return true; + + default: + break; + } + + return false; +} + +bool PDFDestination::hasTop() const +{ + switch (m_destinationType) + { + case DestinationType::XYZ: + case DestinationType::FitH: + case DestinationType::FitBH: + case DestinationType::FitR: + return true; + + default: + break; + } + + return false; +} + +bool PDFDestination::hasRight() const +{ + switch (m_destinationType) + { + case DestinationType::FitR: + return true; + + default: + break; + } + + return false; +} + +bool PDFDestination::hasBottom() const +{ + switch (m_destinationType) + { + case DestinationType::FitR: + return true; + + default: + break; + } + + return false; +} + +bool PDFDestination::hasZoom() const +{ + switch (m_destinationType) + { + case DestinationType::XYZ: + return true; + + default: + break; + } + + return false; +} + PDFFormAction::FieldList PDFFormAction::parseFieldList(const PDFObjectStorage* storage, PDFObject object, FieldScope& fieldScope) { FieldList result; diff --git a/PdfForQtLib/sources/pdfaction.h b/PdfForQtLib/sources/pdfaction.h index d84f716..6cb6f69 100644 --- a/PdfForQtLib/sources/pdfaction.h +++ b/PdfForQtLib/sources/pdfaction.h @@ -79,7 +79,7 @@ enum class DestinationType /// destination has almost exactly same syntax as page destination, it should be checked, /// if indirect reference returned by function \p getPageReference references really page, /// or some structure element. -class PDFDestination +class PDFFORQTLIBSHARED_EXPORT PDFDestination { public: explicit inline PDFDestination() = default; @@ -100,6 +100,35 @@ public: /// \param object Destination object static PDFDestination parse(const PDFObjectStorage* storage, PDFObject object); + void setDestinationType(DestinationType destinationType); + void setLeft(PDFReal left); + void setTop(PDFReal top); + void setRight(PDFReal right); + void setBottom(PDFReal bottom); + void setZoom(PDFReal zoom); + void setName(const QByteArray& name); + void setPageReference(PDFObjectReference pageReference); + void setPageIndex(PDFInteger pageIndex); + + static PDFDestination createXYZ(PDFObjectReference page, PDFReal left, PDFReal top, PDFReal zoom); + static PDFDestination createFit(PDFObjectReference page); + static PDFDestination createFitH(PDFObjectReference page, PDFReal top); + static PDFDestination createFitV(PDFObjectReference page, PDFReal left); + static PDFDestination createFitR(PDFObjectReference page, PDFReal left, PDFReal top, PDFReal right, PDFReal bottom); + static PDFDestination createFitB(PDFObjectReference page); + static PDFDestination createFitBH(PDFObjectReference page, PDFReal top); + static PDFDestination createFitBV(PDFObjectReference page, PDFReal left); + static PDFDestination createNamed(const QByteArray& name); + + bool hasLeft() const; + bool hasTop() const; + bool hasRight() const; + bool hasBottom() const; + bool hasZoom() const; + + bool isValid() const { return m_destinationType != DestinationType::Invalid; } + bool isNamedDestination() const { return m_destinationType == DestinationType::Named; } + private: DestinationType m_destinationType = DestinationType::Invalid; PDFReal m_left = 0.0; diff --git a/PdfForQtLib/sources/pdfdocumentbuilder.cpp b/PdfForQtLib/sources/pdfdocumentbuilder.cpp index f09df3b..a65af7d 100644 --- a/PdfForQtLib/sources/pdfdocumentbuilder.cpp +++ b/PdfForQtLib/sources/pdfdocumentbuilder.cpp @@ -71,6 +71,82 @@ void PDFObjectFactory::endDictionaryItem() std::get(dictionaryItem.object).addEntry(PDFInplaceOrMemoryString(qMove(topItem.itemName)), qMove(std::get(topItem.object))); } +PDFObjectFactory& PDFObjectFactory::operator<<(const PDFDestination& destination) +{ + if (!destination.isValid()) + { + *this << PDFObject(); + return *this; + } + + if (destination.isNamedDestination()) + { + *this << WrapName(destination.getName()); + } + else + { + beginArray(); + + // Destination + if (destination.getPageReference().isValid()) + { + *this << destination.getPageReference(); + } + else + { + *this << destination.getPageIndex(); + } + + // Type + QByteArray type; + + switch (destination.getDestinationType()) + { + case DestinationType::XYZ: + type = "XYZ"; + break; + + case DestinationType::Fit: + type = "Fit"; + break; + + case DestinationType::FitH: + type = "FitH"; + break; + + case DestinationType::FitV: + type = "FitV"; + break; + + case DestinationType::FitR: + type = "FitR"; + break; + + case DestinationType::FitB: + type = "FitB"; + break; + + case DestinationType::FitBH: + type = "FitBH"; + break; + + case DestinationType::FitBV: + type = "FitBV"; + break; + + default: + Q_ASSERT(false); + break; + } + + *this << WrapName(type); + + endArray(); + } + + return *this; +} + PDFObjectFactory& PDFObjectFactory::operator<<(FileAttachmentIcon icon) { switch (icon) @@ -1288,6 +1364,26 @@ PDFObjectReference PDFDocumentBuilder::appendPage(QRectF mediaBox) } +PDFObjectReference PDFDocumentBuilder::createActionGoTo(PDFDestination destination) +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Type"); + objectBuilder << WrapName("Action"); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("S"); + objectBuilder << WrapName("GoTo"); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("D"); + objectBuilder << destination; + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObjectReference actionReference = addObject(objectBuilder.takeObject()); + return actionReference; +} + + PDFObjectReference PDFDocumentBuilder::createActionURI(QString URL) { PDFObjectFactory objectBuilder; diff --git a/PdfForQtLib/sources/pdfdocumentbuilder.h b/PdfForQtLib/sources/pdfdocumentbuilder.h index 856c385..806b529 100644 --- a/PdfForQtLib/sources/pdfdocumentbuilder.h +++ b/PdfForQtLib/sources/pdfdocumentbuilder.h @@ -115,6 +115,7 @@ public: PDFObjectFactory& operator<<(const PDFObject& object); PDFObjectFactory& operator<<(Stamp stamp); PDFObjectFactory& operator<<(FileAttachmentIcon icon); + PDFObjectFactory& operator<<(const PDFDestination& destination); /// Treat containers - write them as array template()))> @@ -367,6 +368,11 @@ public: PDFObjectReference appendPage(QRectF mediaBox); + /// Creates GoTo action. This action changes view to a specific destination in the same document. + /// \param destination Destination + PDFObjectReference createActionGoTo(PDFDestination destination); + + /// Creates URI action. /// \param URL Target URL PDFObjectReference createActionURI(QString URL); diff --git a/generated_code_definition.xml b/generated_code_definition.xml index 58ba722..c11483d 100644 --- a/generated_code_definition.xml +++ b/generated_code_definition.xml @@ -183,6 +183,77 @@ return pageReference; Creates URI action. _PDFObjectReference + + + + + + + + + + destination + _PDFDestination + Destination + + + Parameters + + _void + + + + + + + + + + + + Type + DictionaryItemSimple + WrapName("Action") + + + + + S + DictionaryItemSimple + WrapName("GoTo") + + + + + D + DictionaryItemSimple + destination + + + + Dictionary + + + + CreateObject + actionReference + _PDFObjectReference + + + + + + Code + + _void + return actionReference; + + + Actions + createActionGoTo + Creates GoTo action. This action changes view to a specific destination in the same document. + _PDFObjectReference + @@ -7763,6 +7834,198 @@ return rootNodeReference; Set document language. _void + + + + + + + + + + page + _PDFObjectReference + Page + + + + + box + _QRectF + Box + + + Parameters + + _void + + + + + + + + + + + + ArtBox + DictionaryItemSimple + box + + + + Dictionary + + + + CreateObject + updatedPageObject + _PDFObject + + + + + + Code + + _void + mergeTo(page, updatedPageObject); + + + Structure + setPageArtBox + Sets art box to the page. Art box defines page's meaningful content. + _void + + + + + + + + + + + page + _PDFObjectReference + Page + + + + + box + _QRectF + Box + + + Parameters + + _void + + + + + + + + + + + + BleedBox + DictionaryItemSimple + box + + + + Dictionary + + + + CreateObject + updatedPageObject + _PDFObject + + + + + + Code + + _void + mergeTo(page, updatedPageObject); + + + Structure + setPageBleedBox + Sets bleed box to the page. Bleed box is, basically, a clipping box for output in a production environment. Default value is the page's crop box. + _void + + + + + + + + + + + page + _PDFObjectReference + Page + + + + + box + _QRectF + Box + + + Parameters + + _void + + + + + + + + + + + + CropBox + DictionaryItemSimple + box + + + + Dictionary + + + + CreateObject + updatedPageObject + _PDFObject + + + + + + Code + + _void + mergeTo(page, updatedPageObject); + + + Structure + setPageCropBox + Sets crop box to the page. Crop box defines clipping region of the page. Page contents are clipped to this region, graphics outside of clipping box will not be printed. Default value is same, as media box. + _void + @@ -7891,6 +8154,70 @@ return rootNodeReference; Sets media box to the page. The media box defines size of physical medium, onto which the page is to be printed. _void + + + + + + + + + + page + _PDFObjectReference + Page + + + + + box + _QRectF + Box + + + Parameters + + _void + + + + + + + + + + + + TrimBox + DictionaryItemSimple + box + + + + Dictionary + + + + CreateObject + updatedPageObject + _PDFObject + + + + + + Code + + _void + mergeTo(page, updatedPageObject); + + + Structure + setPageTrimBox + Sets trim box to the page. Trim box is physical region, of the printed page after trimming. + _void + @@ -7980,261 +8307,5 @@ updateDocumentInfo(qMove(updatedInfoDictionary)); This function is used to update trailer dictionary. Must be called each time the final document is being built. _void - - - - - - - - - - page - _PDFObjectReference - Page - - - - - box - _QRectF - Box - - - Parameters - - _void - - - - - - - - - - - - CropBox - DictionaryItemSimple - box - - - - Dictionary - - - - CreateObject - updatedPageObject - _PDFObject - - - - - - Code - - _void - mergeTo(page, updatedPageObject); - - - Structure - setPageCropBox - Sets crop box to the page. Crop box defines clipping region of the page. Page contents are clipped to this region, graphics outside of clipping box will not be printed. Default value is same, as media box. - _void - - - - - - - - - - - page - _PDFObjectReference - Page - - - - - box - _QRectF - Box - - - Parameters - - _void - - - - - - - - - - - - BleedBox - DictionaryItemSimple - box - - - - Dictionary - - - - CreateObject - updatedPageObject - _PDFObject - - - - - - Code - - _void - mergeTo(page, updatedPageObject); - - - Structure - setPageBleedBox - Sets bleed box to the page. Bleed box is, basically, a clipping box for output in a production environment. Default value is the page's crop box. - _void - - - - - - - - - - - page - _PDFObjectReference - Page - - - - - box - _QRectF - Box - - - Parameters - - _void - - - - - - - - - - - - TrimBox - DictionaryItemSimple - box - - - - Dictionary - - - - CreateObject - updatedPageObject - _PDFObject - - - - - - Code - - _void - mergeTo(page, updatedPageObject); - - - Structure - setPageTrimBox - Sets trim box to the page. Trim box is physical region, of the printed page after trimming. - _void - - - - - - - - - - - page - _PDFObjectReference - Page - - - - - box - _QRectF - Box - - - Parameters - - _void - - - - - - - - - - - - ArtBox - DictionaryItemSimple - box - - - - Dictionary - - - - CreateObject - updatedPageObject - _PDFObject - - - - - - Code - - _void - mergeTo(page, updatedPageObject); - - - Structure - setPageArtBox - Sets art box to the page. Art box defines page's meaningful content. - _void -