diff --git a/CodeGenerator/codegenerator.cpp b/CodeGenerator/codegenerator.cpp index f499a58..fdac425 100644 --- a/CodeGenerator/codegenerator.cpp +++ b/CodeGenerator/codegenerator.cpp @@ -400,6 +400,11 @@ void GeneratedFunction::generateCode(QTextStream& stream, CodeGeneratorParameter }; applyFunctor(gatherParameters); + if (parameterTexts.isEmpty()) + { + parameterTexts << ""; + } + if (parameters.header) { // Generate header source code diff --git a/CodeGenerator/codegenerator.h b/CodeGenerator/codegenerator.h index a8c8383..f32ef6b 100644 --- a/CodeGenerator/codegenerator.h +++ b/CodeGenerator/codegenerator.h @@ -349,6 +349,7 @@ public: enum FunctionType { + Structure, Annotations, ColorSpace }; diff --git a/PdfForQtLib/sources/pdfconstants.h b/PdfForQtLib/sources/pdfconstants.h index 832b34d..40da2dd 100644 --- a/PdfForQtLib/sources/pdfconstants.h +++ b/PdfForQtLib/sources/pdfconstants.h @@ -22,6 +22,9 @@ namespace pdf { +// Name of the library, together with version +static constexpr const char* PDF_LIBRARY_NAME = "PdfForQt 1.0.0"; + // Structure file constants static constexpr const char* PDF_END_OF_FILE_MARK = "%%EOF"; static constexpr const char* PDF_START_OF_XREF_MARK = "startxref"; diff --git a/PdfForQtLib/sources/pdfdocument.cpp b/PdfForQtLib/sources/pdfdocument.cpp index 7744716..90de22d 100644 --- a/PdfForQtLib/sources/pdfdocument.cpp +++ b/PdfForQtLib/sources/pdfdocument.cpp @@ -237,6 +237,11 @@ void PDFObjectStorage::setObject(PDFObjectReference reference, PDFObject object) m_objects[reference.objectNumber] = Entry(reference.generation, qMove(object)); } +void PDFObjectStorage::updateTrailerDictionary(PDFObject trailerDictionary) +{ + m_trailerDictionary = PDFObjectManipulator::merge(m_trailerDictionary, trailerDictionary, PDFObjectManipulator::RemoveNullObjects); +} + QByteArray PDFDocumentDataLoaderDecorator::readName(const PDFObject& object) { const PDFObject& dereferencedObject = m_document->getObject(object); diff --git a/PdfForQtLib/sources/pdfdocument.h b/PdfForQtLib/sources/pdfdocument.h index e1fe7ea..6018796 100644 --- a/PdfForQtLib/sources/pdfdocument.h +++ b/PdfForQtLib/sources/pdfdocument.h @@ -89,6 +89,12 @@ public: /// \param object New value of object void setObject(PDFObjectReference reference, PDFObject object); + /// Updates trailer dictionary. Preserves items which are not in a new + /// dictionary \p trailerDictionary. It merges new dictionary to the + /// old one. + /// \param trailerDictionary New trailer dictionary + void updateTrailerDictionary(PDFObject trailerDictionary); + private: PDFObjects m_objects; PDFObject m_trailerDictionary; diff --git a/PdfForQtLib/sources/pdfdocumentbuilder.cpp b/PdfForQtLib/sources/pdfdocumentbuilder.cpp index 407be28..1b86433 100644 --- a/PdfForQtLib/sources/pdfdocumentbuilder.cpp +++ b/PdfForQtLib/sources/pdfdocumentbuilder.cpp @@ -17,6 +17,7 @@ #include "pdfdocumentbuilder.h" #include "pdfencoding.h" +#include "pdfconstants.h" namespace pdf { @@ -216,7 +217,7 @@ PDFObjectFactory& PDFObjectFactory::operator<<(PDFObjectReference value) PDFDocumentBuilder::PDFDocumentBuilder() : m_version(1, 7) { - + createDocument(); } PDFDocumentBuilder::PDFDocumentBuilder(const PDFDocument* document) : @@ -226,8 +227,23 @@ PDFDocumentBuilder::PDFDocumentBuilder(const PDFDocument* document) : } -PDFDocument PDFDocumentBuilder::build() const +void PDFDocumentBuilder::reset() { + *this = PDFDocumentBuilder(); +} + +void PDFDocumentBuilder::createDocument() +{ + reset(); + + PDFObjectReference catalog = createCatalog(); + PDFObject trailerDictionary = createTrailerDictionary(catalog); + m_storage.updateTrailerDictionary(trailerDictionary); +} + +PDFDocument PDFDocumentBuilder::build() +{ + updateTrailerDictionary(m_storage.getObjects().size()); return PDFDocument(PDFObjectStorage(m_storage), m_version); } @@ -246,96 +262,173 @@ QRectF PDFDocumentBuilder::getPopupWindowRect(const QRectF& rectangle) const return rectangle.translated(rectangle.width() * 1.25, 0); } -/* START GENERATED CODE */ - -PDFObjectReference PDFDocumentBuilder::createAnnotationSquare(PDFObjectReference page, - QRectF rectangle, - PDFReal borderWidth, - QColor fillColor, - QColor strokeColor, - QString title, - QString subject, - QString contents) +QString PDFDocumentBuilder::getProducerString() const { - PDFObjectFactory objectBuilder; - - objectBuilder.beginDictionary(); - objectBuilder.beginDictionaryItem("Subtype"); - objectBuilder << WrapName("Square"); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Rect"); - objectBuilder << rectangle; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("F"); - objectBuilder << 4; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("P"); - objectBuilder << page; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("M"); - objectBuilder << WrapCurrentDateTime(); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("CreationDate"); - objectBuilder << WrapCurrentDateTime(); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Border"); - objectBuilder << std::initializer_list{ 0.0, 0.0, borderWidth }; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("C"); - objectBuilder << WrapAnnotationColor(strokeColor); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("IC"); - objectBuilder << WrapAnnotationColor(fillColor); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("T"); - objectBuilder << title; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Contents"); - objectBuilder << contents; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Subj"); - objectBuilder << subject; - objectBuilder.endDictionaryItem(); - objectBuilder.endDictionary(); - PDFObjectReference annotationObject = addObject(objectBuilder.takeObject()); - PDFObjectReference popupAnnotation = createAnnotationPopup(page, annotationObject, getPopupWindowRect(rectangle), false); - - objectBuilder.beginDictionaryItem("Popup"); - objectBuilder << popupAnnotation; - objectBuilder.endDictionaryItem(); - PDFObject updateAnnotationPopup = objectBuilder.takeObject(); - mergeTo(annotationObject, updateAnnotationPopup); - return PDFObjectReference(); -} - -PDFObjectReference PDFDocumentBuilder::createAnnotationPopup(PDFObjectReference page, - PDFObjectReference parentAnnotation, - QRectF rectangle, - bool opened) -{ - PDFObjectFactory objectBuilder; - - objectBuilder.beginDictionary(); - objectBuilder.beginDictionaryItem("Subtype"); - objectBuilder << WrapName("Popup"); - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Rect"); - objectBuilder << rectangle; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("P"); - objectBuilder << page; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Parent"); - objectBuilder << parentAnnotation; - objectBuilder.endDictionaryItem(); - objectBuilder.beginDictionaryItem("Open"); - objectBuilder << opened; - objectBuilder.endDictionaryItem(); - objectBuilder.endDictionary(); - PDFObjectReference popupAnnotation = addObject(objectBuilder.takeObject()); - return popupAnnotation; + return PDF_LIBRARY_NAME; } +/* START GENERATED CODE */ + +PDFObjectReference PDFDocumentBuilder::createAnnotationSquare(PDFObjectReference page, + QRectF rectangle, + PDFReal borderWidth, + QColor fillColor, + QColor strokeColor, + QString title, + QString subject, + QString contents) +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Subtype"); + objectBuilder << WrapName("Square"); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Rect"); + objectBuilder << rectangle; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("F"); + objectBuilder << 4; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("P"); + objectBuilder << page; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("M"); + objectBuilder << WrapCurrentDateTime(); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("CreationDate"); + objectBuilder << WrapCurrentDateTime(); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Border"); + objectBuilder << std::initializer_list{ 0.0, 0.0, borderWidth }; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("C"); + objectBuilder << WrapAnnotationColor(strokeColor); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("IC"); + objectBuilder << WrapAnnotationColor(fillColor); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("T"); + objectBuilder << title; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Contents"); + objectBuilder << contents; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Subj"); + objectBuilder << subject; + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObjectReference annotationObject = addObject(objectBuilder.takeObject()); + PDFObjectReference popupAnnotation = createAnnotationPopup(page, annotationObject, getPopupWindowRect(rectangle), false); + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Popup"); + objectBuilder << popupAnnotation; + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObject updateAnnotationPopup = objectBuilder.takeObject(); + mergeTo(annotationObject, updateAnnotationPopup); + return annotationObject; +} + + +PDFObjectReference PDFDocumentBuilder::createAnnotationPopup(PDFObjectReference page, + PDFObjectReference parentAnnotation, + QRectF rectangle, + bool opened) +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Subtype"); + objectBuilder << WrapName("Popup"); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Rect"); + objectBuilder << rectangle; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("P"); + objectBuilder << page; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Parent"); + objectBuilder << parentAnnotation; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Open"); + objectBuilder << opened; + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObjectReference popupAnnotation = addObject(objectBuilder.takeObject()); + return popupAnnotation; +} + + +PDFObjectReference PDFDocumentBuilder::createCatalog() +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Type"); + objectBuilder << WrapName("Catalog"); + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObjectReference catalogReference = addObject(objectBuilder.takeObject()); + return catalogReference; +} + + +PDFObject PDFDocumentBuilder::createTrailerDictionary(PDFObjectReference catalog) +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Size"); + objectBuilder << 1; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Root"); + objectBuilder << catalog; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Info"); + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Producer"); + objectBuilder << getProducerString(); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("CreationDate"); + objectBuilder << WrapCurrentDateTime(); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("ModDate"); + objectBuilder << WrapCurrentDateTime(); + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObject trailerDictionary = objectBuilder.takeObject(); + return trailerDictionary; +} + + +void PDFDocumentBuilder::updateTrailerDictionary(PDFInteger objectCount) +{ + PDFObjectFactory objectBuilder; + + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Size"); + objectBuilder << objectCount; + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("Info"); + objectBuilder.beginDictionary(); + objectBuilder.beginDictionaryItem("Producer"); + objectBuilder << getProducerString(); + objectBuilder.endDictionaryItem(); + objectBuilder.beginDictionaryItem("ModDate"); + objectBuilder << WrapCurrentDateTime(); + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + objectBuilder.endDictionaryItem(); + objectBuilder.endDictionary(); + PDFObject trailerDictionary = objectBuilder.takeObject(); + m_storage.updateTrailerDictionary(qMove(trailerDictionary)); +} + + /* END GENERATED CODE */ } // namespace pdf diff --git a/PdfForQtLib/sources/pdfdocumentbuilder.h b/PdfForQtLib/sources/pdfdocumentbuilder.h index 8bcc931..e8654d4 100644 --- a/PdfForQtLib/sources/pdfdocumentbuilder.h +++ b/PdfForQtLib/sources/pdfdocumentbuilder.h @@ -144,56 +144,85 @@ private: class PDFDocumentBuilder { public: + /// Creates a new blank document (with no pages) explicit PDFDocumentBuilder(); + + /// explicit PDFDocumentBuilder(const PDFDocument* document); - PDFDocument build() const; + /// Resets the object to the initial state. + /// \warning All data are lost + void reset(); -/* START GENERATED CODE */ - - /// Square annotation displays rectangle (or square). When opened, they display pop-up window - /// containing the text of associated note (and window title). Square border/fill color can be defined, - /// along with border width. - /// \param page Page to which is annotation added - /// \param rectangle Area in which is rectangle displayed - /// \param borderWidth Width of the border line of rectangle - /// \param fillColor Fill color of rectangle (interior color). If you do not want to have area color filled, - /// then use invalid QColor. - /// \param strokeColor Stroke color (color of the rectangle border). If you do not want to have a - /// border, then use invalid QColor. - /// \param title Title (it is displayed as title of popup window) - /// \param subject Subject (short description of the subject being adressed by the annotation) - /// \param contents Contents (text displayed, for example, in the marked annotation dialog) - PDFObjectReference createAnnotationSquare(PDFObjectReference page, - QRectF rectangle, - PDFReal borderWidth, - QColor fillColor, - QColor strokeColor, - QString title, - QString subject, - QString contents); - - - /// Creates a new popup annotation on the page. Popup annotation is represented usually by floating - /// window, which can be opened, or closed. Popup annotation is associated with parent annotation, - /// which can be usually markup annotation. Popup annotation displays parent annotation's texts, for - /// example, title, comment, date etc. - /// \param page Page to which is annotation added - /// \param parentAnnotation Parent annotation (for which is popup window displayed) - /// \param rectangle Area on the page, where popup window appears - /// \param opened Is the window opened? - PDFObjectReference createAnnotationPopup(PDFObjectReference page, - PDFObjectReference parentAnnotation, - QRectF rectangle, - bool opened); + /// Create a new blank document with no pages. If some document + /// is edited at call of this function, then it is lost. + void createDocument(); + PDFDocument build(); +/* START GENERATED CODE */ + + /// Square annotation displays rectangle (or square). When opened, they display pop-up window + /// containing the text of associated note (and window title). Square border/fill color can be defined, + /// along with border width. + /// \param page Page to which is annotation added + /// \param rectangle Area in which is rectangle displayed + /// \param borderWidth Width of the border line of rectangle + /// \param fillColor Fill color of rectangle (interior color). If you do not want to have area color filled, + /// then use invalid QColor. + /// \param strokeColor Stroke color (color of the rectangle border). If you do not want to have a + /// border, then use invalid QColor. + /// \param title Title (it is displayed as title of popup window) + /// \param subject Subject (short description of the subject being adressed by the annotation) + /// \param contents Contents (text displayed, for example, in the marked annotation dialog) + PDFObjectReference createAnnotationSquare(PDFObjectReference page, + QRectF rectangle, + PDFReal borderWidth, + QColor fillColor, + QColor strokeColor, + QString title, + QString subject, + QString contents); + + + /// Creates a new popup annotation on the page. Popup annotation is represented usually by floating + /// window, which can be opened, or closed. Popup annotation is associated with parent annotation, + /// which can be usually markup annotation. Popup annotation displays parent annotation's texts, for + /// example, title, comment, date etc. + /// \param page Page to which is annotation added + /// \param parentAnnotation Parent annotation (for which is popup window displayed) + /// \param rectangle Area on the page, where popup window appears + /// \param opened Is the window opened? + PDFObjectReference createAnnotationPopup(PDFObjectReference page, + PDFObjectReference parentAnnotation, + QRectF rectangle, + bool opened); + + + /// Creates empty catalog. This function is used, when a new document is being created. Do not call + /// this function manually. + PDFObjectReference createCatalog(); + + + /// This function is used to create a new trailer dictionary, when blank document is created. Do not + /// call this function manually. + /// \param catalog Reference to document catalog + PDFObject createTrailerDictionary(PDFObjectReference catalog); + + + /// This function is used to update trailer dictionary. Must be called each time the final document is + /// being built. + /// \param objectCount Number of objects (including empty ones) + void updateTrailerDictionary(PDFInteger objectCount); + + /* END GENERATED CODE */ private: PDFObjectReference addObject(PDFObject object); void mergeTo(PDFObjectReference reference, PDFObject object); QRectF getPopupWindowRect(const QRectF& rectangle) const; + QString getProducerString() const; PDFObjectStorage m_storage; PDFVersion m_version; diff --git a/generated_code_definition.xml b/generated_code_definition.xml index d29ff79..33c6363 100644 --- a/generated_code_definition.xml +++ b/generated_code_definition.xml @@ -184,9 +184,17 @@ - + + + + + Popup + DictionaryItemSimple + popupAnnotation + + Popup - DictionaryItemSimple + Dictionary popupAnnotation @@ -316,5 +324,234 @@ return annotationObject; Creates a new popup annotation on the page. Popup annotation is represented usually by floating window, which can be opened, or closed. Popup annotation is associated with parent annotation, which can be usually markup annotation. Popup annotation displays parent annotation's texts, for example, title, comment, date etc. _PDFObjectReference + + + + + + + + + + + + + Type + DictionaryItemSimple + WrapName("Catalog") + + + + Dictionary + + + + CreateObject + catalogReference + _PDFObjectReference + + + + + + Code + + _void + return catalogReference; + + + Structure + createCatalog + Creates empty catalog. This function is used, when a new document is being created. Do not call this function manually. + _PDFObjectReference + + + + + + + + + + + catalog + _PDFObjectReference + Reference to document catalog + + + Parameters + + _void + + + + + + + + + + + + Size + DictionaryItemSimple + 1 + + + + + Root + DictionaryItemSimple + catalog + + + + + + + + + + + Producer + DictionaryItemSimple + getProducerString() + + + + + CreationDate + DictionaryItemSimple + WrapCurrentDateTime() + + + + + ModDate + DictionaryItemSimple + WrapCurrentDateTime() + + + + Dictionary + + + + Info + DictionaryItemComplex + + + + + Dictionary + + + + CreateObject + trailerDictionary + _PDFObject + + + + + + Code + + _void + return trailerDictionary; + + + Structure + createTrailerDictionary + This function is used to create a new trailer dictionary, when blank document is created. Do not call this function manually. + _PDFObject + + + + + + + + + + + objectCount + _PDFInteger + Number of objects (including empty ones) + + + Parameters + + _void + + + + + + + + + + + + Size + DictionaryItemSimple + objectCount + + + + + + + + + + + Producer + DictionaryItemSimple + getProducerString() + + + + + ModDate + DictionaryItemSimple + WrapCurrentDateTime() + + + + Dictionary + + + + Info + DictionaryItemComplex + + + + + Dictionary + + + + CreateObject + trailerDictionary + _PDFObject + + + + + + Code + + _void + m_storage.updateTrailerDictionary(qMove(trailerDictionary)); + + + Structure + updateTrailerDictionary + This function is used to update trailer dictionary. Must be called each time the final document is being built. + _void +