mirror of
				https://github.com/JakubMelka/PDF4QT.git
				synced 2025-06-05 21:59:17 +02:00 
			
		
		
		
	Text annotation
This commit is contained in:
		@@ -508,6 +508,17 @@ private:
 | 
			
		||||
    PDFObject m_externalData;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
enum class TextAnnotationIcon
 | 
			
		||||
{
 | 
			
		||||
    Comment,
 | 
			
		||||
    Help,
 | 
			
		||||
    Insert,
 | 
			
		||||
    Key,
 | 
			
		||||
    NewParagraph,
 | 
			
		||||
    Note,
 | 
			
		||||
    Paragraph
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/// Text annotation represents note attached to a specific point in the PDF
 | 
			
		||||
/// document. It appears as icon, and it is not zoomed, or rotated (behaves
 | 
			
		||||
/// as if flag NoZoom and NoRotate were set). When this annotation is opened,
 | 
			
		||||
 
 | 
			
		||||
@@ -64,6 +64,61 @@ void PDFObjectFactory::endDictionaryItem()
 | 
			
		||||
    std::get<PDFDictionary>(dictionaryItem.object).addEntry(qMove(topItem.itemName), qMove(std::get<PDFObject>(topItem.object)));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PDFObjectFactory& PDFObjectFactory::operator<<(TextAnnotationIcon icon)
 | 
			
		||||
{
 | 
			
		||||
    switch (icon)
 | 
			
		||||
    {
 | 
			
		||||
        case TextAnnotationIcon::Comment:
 | 
			
		||||
        {
 | 
			
		||||
            *this << WrapName("Comment");
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case TextAnnotationIcon::Help:
 | 
			
		||||
        {
 | 
			
		||||
            *this << WrapName("Help");
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case TextAnnotationIcon::Insert:
 | 
			
		||||
        {
 | 
			
		||||
            *this << WrapName("Insert");
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case TextAnnotationIcon::Key:
 | 
			
		||||
        {
 | 
			
		||||
            *this << WrapName("Key");
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case TextAnnotationIcon::NewParagraph:
 | 
			
		||||
        {
 | 
			
		||||
            *this << WrapName("NewParagraph");
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case TextAnnotationIcon::Note:
 | 
			
		||||
        {
 | 
			
		||||
            *this << WrapName("Note");
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case TextAnnotationIcon::Paragraph:
 | 
			
		||||
        {
 | 
			
		||||
            *this << WrapName("Paragraph");
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        default:
 | 
			
		||||
        {
 | 
			
		||||
            Q_ASSERT(false);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return *this;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
PDFObjectFactory& PDFObjectFactory::operator<<(WrapEmptyArray)
 | 
			
		||||
{
 | 
			
		||||
    beginArray();
 | 
			
		||||
@@ -276,7 +331,9 @@ void PDFDocumentBuilder::appendTo(PDFObjectReference reference, PDFObject object
 | 
			
		||||
 | 
			
		||||
QRectF PDFDocumentBuilder::getPopupWindowRect(const QRectF& rectangle) const
 | 
			
		||||
{
 | 
			
		||||
    return rectangle.translated(rectangle.width() * 1.25, 0);
 | 
			
		||||
    QRectF rect = rectangle.translated(rectangle.width() * 1.25, 0);
 | 
			
		||||
    rect.setSize(QSizeF(100, 100));
 | 
			
		||||
    return rect;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
QString PDFDocumentBuilder::getProducerString() const
 | 
			
		||||
@@ -375,7 +432,17 @@ PDFObjectReference PDFDocumentBuilder::createAnnotationSquare(PDFObjectReference
 | 
			
		||||
    objectBuilder.endDictionaryItem();
 | 
			
		||||
    objectBuilder.endDictionary();
 | 
			
		||||
    PDFObject updateAnnotationPopup = objectBuilder.takeObject();
 | 
			
		||||
    objectBuilder.beginDictionary();
 | 
			
		||||
    objectBuilder.beginDictionaryItem("Annots");
 | 
			
		||||
    objectBuilder.beginArray();
 | 
			
		||||
    objectBuilder << annotationObject;
 | 
			
		||||
    objectBuilder << popupAnnotation;
 | 
			
		||||
    objectBuilder.endArray();
 | 
			
		||||
    objectBuilder.endDictionaryItem();
 | 
			
		||||
    objectBuilder.endDictionary();
 | 
			
		||||
    PDFObject pageAnnots = objectBuilder.takeObject();
 | 
			
		||||
    mergeTo(annotationObject, updateAnnotationPopup);
 | 
			
		||||
    appendTo(page, pageAnnots);
 | 
			
		||||
    return annotationObject;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -532,6 +599,148 @@ PDFObjectReference PDFDocumentBuilder::createCatalogPageTreeRoot()
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
PDFObjectReference PDFDocumentBuilder::createAnnotationCircle(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("Circle");
 | 
			
		||||
    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();
 | 
			
		||||
    objectBuilder.beginDictionary();
 | 
			
		||||
    objectBuilder.beginDictionaryItem("Annots");
 | 
			
		||||
    objectBuilder.beginArray();
 | 
			
		||||
    objectBuilder << annotationObject;
 | 
			
		||||
    objectBuilder << popupAnnotation;
 | 
			
		||||
    objectBuilder.endArray();
 | 
			
		||||
    objectBuilder.endDictionaryItem();
 | 
			
		||||
    objectBuilder.endDictionary();
 | 
			
		||||
    PDFObject pageAnnots = objectBuilder.takeObject();
 | 
			
		||||
    mergeTo(annotationObject, updateAnnotationPopup);
 | 
			
		||||
    appendTo(page, pageAnnots);
 | 
			
		||||
    return annotationObject;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
PDFObjectReference PDFDocumentBuilder::createAnnotationText(PDFObjectReference page,
 | 
			
		||||
                                                            QRectF rectangle,
 | 
			
		||||
                                                            TextAnnotationIcon iconType,
 | 
			
		||||
                                                            QString title,
 | 
			
		||||
                                                            QString subject,
 | 
			
		||||
                                                            QString contents,
 | 
			
		||||
                                                            bool open)
 | 
			
		||||
{
 | 
			
		||||
    PDFObjectFactory objectBuilder;
 | 
			
		||||
 | 
			
		||||
    objectBuilder.beginDictionary();
 | 
			
		||||
    objectBuilder.beginDictionaryItem("Subtype");
 | 
			
		||||
    objectBuilder << WrapName("Text");
 | 
			
		||||
    objectBuilder.endDictionaryItem();
 | 
			
		||||
    objectBuilder.beginDictionaryItem("Rect");
 | 
			
		||||
    objectBuilder << rectangle;
 | 
			
		||||
    objectBuilder.endDictionaryItem();
 | 
			
		||||
    objectBuilder.beginDictionaryItem("Name");
 | 
			
		||||
    objectBuilder << iconType;
 | 
			
		||||
    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("T");
 | 
			
		||||
    objectBuilder << title;
 | 
			
		||||
    objectBuilder.endDictionaryItem();
 | 
			
		||||
    objectBuilder.beginDictionaryItem("Contents");
 | 
			
		||||
    objectBuilder << contents;
 | 
			
		||||
    objectBuilder.endDictionaryItem();
 | 
			
		||||
    objectBuilder.beginDictionaryItem("Subj");
 | 
			
		||||
    objectBuilder << subject;
 | 
			
		||||
    objectBuilder.endDictionaryItem();
 | 
			
		||||
    objectBuilder.beginDictionaryItem("Open");
 | 
			
		||||
    objectBuilder << open;
 | 
			
		||||
    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();
 | 
			
		||||
    objectBuilder.beginDictionary();
 | 
			
		||||
    objectBuilder.beginDictionaryItem("Annots");
 | 
			
		||||
    objectBuilder.beginArray();
 | 
			
		||||
    objectBuilder << annotationObject;
 | 
			
		||||
    objectBuilder << popupAnnotation;
 | 
			
		||||
    objectBuilder.endArray();
 | 
			
		||||
    objectBuilder.endDictionaryItem();
 | 
			
		||||
    objectBuilder.endDictionary();
 | 
			
		||||
    PDFObject pageAnnots = objectBuilder.takeObject();
 | 
			
		||||
    mergeTo(annotationObject, updateAnnotationPopup);
 | 
			
		||||
    appendTo(page, pageAnnots);
 | 
			
		||||
    return annotationObject;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* END GENERATED CODE */
 | 
			
		||||
 | 
			
		||||
}   // namespace pdf
 | 
			
		||||
 
 | 
			
		||||
@@ -20,6 +20,7 @@
 | 
			
		||||
 | 
			
		||||
#include "pdfobject.h"
 | 
			
		||||
#include "pdfdocument.h"
 | 
			
		||||
#include "pdfannotation.h"
 | 
			
		||||
 | 
			
		||||
namespace pdf
 | 
			
		||||
{
 | 
			
		||||
@@ -77,6 +78,7 @@ public:
 | 
			
		||||
    PDFObjectFactory& operator<<(WrapAnnotationColor color);
 | 
			
		||||
    PDFObjectFactory& operator<<(QString textString);
 | 
			
		||||
    PDFObjectFactory& operator<<(WrapEmptyArray);
 | 
			
		||||
    PDFObjectFactory& operator<<(TextAnnotationIcon icon);
 | 
			
		||||
 | 
			
		||||
    /// Treat containers - write them as array
 | 
			
		||||
    template<typename Container, typename ValueType = decltype(*std::begin(std::declval<Container>()))>
 | 
			
		||||
@@ -244,6 +246,49 @@ public:
 | 
			
		||||
    PDFObjectReference createCatalogPageTreeRoot();
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /// Circle annotation displays ellipse (or circle). When opened, they display pop-up window containing 
 | 
			
		||||
    /// the text of associated note (and window title). Circle border/fill color can be defined, along with 
 | 
			
		||||
    /// border width.
 | 
			
		||||
    /// \param page Page to which is annotation added
 | 
			
		||||
    /// \param rectangle Area in which is circle/ellipse displayed
 | 
			
		||||
    /// \param borderWidth Width of the border line of circle/ellipse
 | 
			
		||||
    /// \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 createAnnotationCircle(PDFObjectReference page,
 | 
			
		||||
                                              QRectF rectangle,
 | 
			
		||||
                                              PDFReal borderWidth,
 | 
			
		||||
                                              QColor fillColor,
 | 
			
		||||
                                              QColor strokeColor,
 | 
			
		||||
                                              QString title,
 | 
			
		||||
                                              QString subject,
 | 
			
		||||
                                              QString contents);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    /// Creates text annotation. Text annotation is "sticky note" attached to a point in the PDF document. 
 | 
			
		||||
    /// When closed, it is displayed as icon, if opened, widget appears with attached text. Text annotations 
 | 
			
		||||
    /// do not scale or rotate, they appear independent of zoom/rotate. So, they behave as if flags 
 | 
			
		||||
    /// NoZoom or NoRotate to the annotations are being set.
 | 
			
		||||
    /// \param page Page to which is annotation added
 | 
			
		||||
    /// \param rectangle Area in which is icon displayed
 | 
			
		||||
    /// \param iconType Icon type
 | 
			
		||||
    /// \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)
 | 
			
		||||
    /// \param open Is annotation initiali displayed as opened?
 | 
			
		||||
    PDFObjectReference createAnnotationText(PDFObjectReference page,
 | 
			
		||||
                                            QRectF rectangle,
 | 
			
		||||
                                            TextAnnotationIcon iconType,
 | 
			
		||||
                                            QString title,
 | 
			
		||||
                                            QString subject,
 | 
			
		||||
                                            QString contents,
 | 
			
		||||
                                            bool open);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/* END GENERATED CODE */
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user