diff --git qt5/src/poppler-annotation.cc qt5/src/poppler-annotation.cc index 5550efcd..2bcee0ca 100644 --- qt5/src/poppler-annotation.cc +++ qt5/src/poppler-annotation.cc @@ -1804,85 +1804,87 @@ QList Annotation::revisions() const return QList(); return AnnotationPrivate::findAnnotations( d->pdfPage, d->parentDoc, QSet(), d->pdfAnnot->getId() ); } //END Annotation implementation /** TextAnnotation [Annotation] */ class TextAnnotationPrivate : public AnnotationPrivate { public: TextAnnotationPrivate(); Annotation * makeAlias() override; Annot* createNativeAnnot(::Page *destPage, DocumentData *doc) override; // data fields TextAnnotation::TextType textType; QString textIcon; QFont textFont; + QColor textColor; int inplaceAlign; // 0:left, 1:center, 2:right QVector inplaceCallout; TextAnnotation::InplaceIntent inplaceIntent; // Helper - static GooString * toAppearanceString(const QFont &font); + static GooString * toAppearanceString(const QFont &font, const QColor &color); }; TextAnnotationPrivate::TextAnnotationPrivate() : AnnotationPrivate(), textType( TextAnnotation::Linked ), textIcon( QStringLiteral("Note") ), inplaceAlign( 0 ), inplaceIntent( TextAnnotation::Unknown ) { } Annotation * TextAnnotationPrivate::makeAlias() { return new TextAnnotation(*this); } -GooString * TextAnnotationPrivate::toAppearanceString(const QFont &font) +GooString * TextAnnotationPrivate::toAppearanceString(const QFont &font, const QColor &color) { - GooString * s = GooString::format("/Invalid_font {0:d} Tf", font.pointSize()); + qreal r = color.redF(), g = color.greenF(), b = color.blueF(); + GooString * s = GooString::format("{0:f} {1:f} {2:f} rg /Invalid_font {3:d} Tf", r, g, b, font.pointSize()); // TODO: Font family, style (bold, italic, ...) and pointSize as float return s; } Annot* TextAnnotationPrivate::createNativeAnnot(::Page *destPage, DocumentData *doc) { // Setters are defined in the public class TextAnnotation *q = static_cast( makeAlias() ); // Set page and contents pdfPage = destPage; parentDoc = doc; // Set pdfAnnot PDFRectangle rect = boundaryToPdfRectangle(boundary, flags); if (textType == TextAnnotation::Linked) { pdfAnnot = new AnnotText(destPage->getDoc(), &rect); } else { - GooString * da = toAppearanceString(textFont); + GooString * da = toAppearanceString(textFont, textColor); pdfAnnot = new AnnotFreeText(destPage->getDoc(), &rect, da); delete da; } // Set properties flushBaseAnnotationProperties(); q->setTextIcon(textIcon); q->setInplaceAlign(inplaceAlign); q->setCalloutPoints(inplaceCallout); q->setInplaceIntent(inplaceIntent); delete q; inplaceCallout.clear(); // Free up memory return pdfAnnot; } TextAnnotation::TextAnnotation( TextAnnotation::TextType type ) : Annotation( *new TextAnnotationPrivate() ) @@ -1898,41 +1900,48 @@ TextAnnotation::TextAnnotation( const QDomNode & node ) : Annotation( *new TextAnnotationPrivate, node ) { // loop through the whole children looking for a 'text' element QDomNode subNode = node.firstChild(); while( subNode.isElement() ) { QDomElement e = subNode.toElement(); subNode = subNode.nextSibling(); if ( e.tagName() != QLatin1String("text") ) continue; // parse the attributes if ( e.hasAttribute( QStringLiteral("type") ) ) setTextType((TextAnnotation::TextType)e.attribute( QStringLiteral("type") ).toInt()); if ( e.hasAttribute( QStringLiteral("icon") ) ) setTextIcon(e.attribute( QStringLiteral("icon") )); if ( e.hasAttribute( QStringLiteral("font") ) ) { QFont font; font.fromString( e.attribute( QStringLiteral("font") ) ); - setTextFont(font); + if ( e.hasAttribute( QStringLiteral("fontColor") ) ) + { + QColor color; + color = QColor(e.attribute( QStringLiteral("fontColor") ) ); + setTextFont(font, color); + } + else + setTextFont(font, Qt::black); } if ( e.hasAttribute( QStringLiteral("align") ) ) setInplaceAlign(e.attribute( QStringLiteral("align") ).toInt()); if ( e.hasAttribute( QStringLiteral("intent") ) ) setInplaceIntent((TextAnnotation::InplaceIntent)e.attribute( QStringLiteral("intent") ).toInt()); // parse the subnodes QDomNode eSubNode = e.firstChild(); while ( eSubNode.isElement() ) { QDomElement ee = eSubNode.toElement(); eSubNode = eSubNode.nextSibling(); if ( ee.tagName() == QLatin1String("escapedText") ) { setContents(ee.firstChild().toCDATASection().data()); } else if ( ee.tagName() == QLatin1String("callout") ) { QVector points(3); @@ -1958,40 +1967,41 @@ TextAnnotation::~TextAnnotation() void TextAnnotation::store( QDomNode & node, QDomDocument & document ) const { // store base annotation properties storeBaseAnnotationProperties( node, document ); // create [text] element QDomElement textElement = document.createElement( QStringLiteral("text") ); node.appendChild( textElement ); // store the optional attributes if ( textType() != Linked ) textElement.setAttribute( QStringLiteral("type"), (int)textType() ); if ( textIcon() != QLatin1String("Note") ) textElement.setAttribute( QStringLiteral("icon"), textIcon() ); if ( inplaceAlign() ) textElement.setAttribute( QStringLiteral("align"), inplaceAlign() ); if ( inplaceIntent() != Unknown ) textElement.setAttribute( QStringLiteral("intent"), (int)inplaceIntent() ); textElement.setAttribute( QStringLiteral("font"), textFont().toString() ); + textElement.setAttribute( QStringLiteral("fontColor"), textColor().name() ); // Sub-Node-1 - escapedText if ( !contents().isEmpty() ) { QDomElement escapedText = document.createElement( QStringLiteral("escapedText") ); textElement.appendChild( escapedText ); QDomCDATASection textCData = document.createCDATASection( contents() ); escapedText.appendChild( textCData ); } // Sub-Node-2 - callout if ( calloutPoint(0).x() != 0.0 ) { QDomElement calloutElement = document.createElement( QStringLiteral("callout") ); textElement.appendChild( calloutElement ); calloutElement.setAttribute( QStringLiteral("ax"), QString::number( calloutPoint(0).x() ) ); calloutElement.setAttribute( QStringLiteral("ay"), QString::number( calloutPoint(0).y() ) ); calloutElement.setAttribute( QStringLiteral("bx"), QString::number( calloutPoint(1).x() ) ); calloutElement.setAttribute( QStringLiteral("by"), QString::number( calloutPoint(1).y() ) ); calloutElement.setAttribute( QStringLiteral("cx"), QString::number( calloutPoint(2).x() ) ); @@ -2073,55 +2083,85 @@ QFont TextAnnotation::textFont() const QFont font; if (d->pdfAnnot->getType() == Annot::typeFreeText) { const AnnotFreeText * ftextann = static_cast(d->pdfAnnot); const GooString * da = ftextann->getAppearanceString(); if (da) { // At the moment, only font size is parsed QString style = QString::fromLatin1( da->getCString() ); QRegExp rx(QStringLiteral("(\\d+)(\\.\\d*)? Tf")); if (rx.indexIn(style) != -1) font.setPointSize( rx.cap(1).toInt() ); // TODO: Other properties } } return font; } -void TextAnnotation::setTextFont( const QFont &font ) +QColor TextAnnotation::textColor() const +{ + Q_D( const TextAnnotation ); + + if (!d->pdfAnnot) + return d->textColor; + + QColor color; + + if (d->pdfAnnot->getType() == Annot::typeFreeText) + { + const AnnotFreeText * ftextann = static_cast(d->pdfAnnot); + const GooString * da = ftextann->getAppearanceString(); + if (da) + { + // At the moment, only font size is parsed + QString style = QString::fromLatin1( da->getCString() ); + QRegExp rx(QStringLiteral("(\\d\\.\\d*) (\\d\\.\\d*) (\\d\\.\\d*) rg")); + if (rx.indexIn(style) != -1) + { + qreal red = rx.cap(1).toDouble(), green = rx.cap(2).toDouble(), blue = rx.cap(3).toDouble(); + color.setRgbF(red, green, blue); + } + } + } + + return color; +} + +void TextAnnotation::setTextFont( const QFont &font, const QColor &color ) { Q_D( TextAnnotation ); if (!d->pdfAnnot) { d->textFont = font; + d->textColor = color; return; } if (d->pdfAnnot->getType() != Annot::typeFreeText) return; AnnotFreeText * ftextann = static_cast(d->pdfAnnot); - GooString * da = TextAnnotationPrivate::toAppearanceString(font); + GooString * da = TextAnnotationPrivate::toAppearanceString(font, color); ftextann->setAppearanceString(da); delete da; } int TextAnnotation::inplaceAlign() const { Q_D( const TextAnnotation ); if (!d->pdfAnnot) return d->inplaceAlign; if (d->pdfAnnot->getType() == Annot::typeFreeText) { const AnnotFreeText * ftextann = static_cast(d->pdfAnnot); return ftextann->getQuadding(); } return 0; } diff --git qt5/src/poppler-annotation.h qt5/src/poppler-annotation.h index a70cbe4f..88e7d547 100644 --- qt5/src/poppler-annotation.h +++ qt5/src/poppler-annotation.h @@ -466,41 +466,42 @@ class POPPLER_QT5_EXPORT TextAnnotation : public Annotation Standard names for text annotation icons are: - Comment - Help - Insert - Key - NewParagraph - Note (this is the default icon to use) - Paragraph */ QString textIcon() const; /** Set the name of the icon to use for this text annotation. \sa textIcon for the list of standard names */ void setTextIcon( const QString &icon ); QFont textFont() const; - void setTextFont( const QFont &font ); + QColor textColor() const; + void setTextFont( const QFont &font, const QColor &color ); int inplaceAlign() const; void setInplaceAlign( int align ); QPointF calloutPoint( int id ) const; /// \since 0.20 QVector calloutPoints() const; /// \since 0.20 void setCalloutPoints( const QVector &points ); InplaceIntent inplaceIntent() const; void setInplaceIntent( InplaceIntent intent ); private: TextAnnotation( const QDomNode &node ); TextAnnotation( TextAnnotationPrivate &dd ); void store( QDomNode &parentNode, QDomDocument &document ) const override; void setTextType( TextType type ); Q_DECLARE_PRIVATE( TextAnnotation ) Q_DISABLE_COPY( TextAnnotation )