mirror of
https://github.com/JakubMelka/PDF4QT.git
synced 2025-06-05 21:59:17 +02:00
Document creation
This commit is contained in:
@@ -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";
|
||||
|
@@ -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);
|
||||
|
@@ -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;
|
||||
|
@@ -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<PDFReal>{ 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<PDFReal>{ 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
|
||||
|
@@ -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;
|
||||
|
Reference in New Issue
Block a user