diff --git poppler/Annot.cc poppler/Annot.cc index d37824c1..70a770d1 100644 --- poppler/Annot.cc +++ poppler/Annot.cc @@ -774,40 +774,53 @@ void AnnotColor::adjustColor(int adjust) { values[i] = 0.5 * values[i] + 0.5; } } else if (adjust < 0) { for (i = 0; i < length; ++i) { values[i] = 0.5 * values[i]; } } } Object AnnotColor::writeToObject(XRef *xref) const { if (length == 0) { return Object(objNull); // Transparent (no color) } else { Array *a = new Array(xref); for (int i = 0; i < length; ++i) a->add( Object( values[i] ) ); return Object(a); } } +//------------------------------------------------------------------------ +// DefaultAppearance +//------------------------------------------------------------------------ + +DefaultAppearance::DefaultAppearance(const GooString &fontTag, int fontPtSize, AnnotColor *fontColor) + : fontPtSize(fontPtSize), fontColor(fontColor) { + DefaultAppearance::fontTag = fontTag.copy(); +} + +DefaultAppearance::~DefaultAppearance() { + delete fontTag; + delete fontColor; +} //------------------------------------------------------------------------ // AnnotIconFit //------------------------------------------------------------------------ AnnotIconFit::AnnotIconFit(Dict* dict) { Object obj1; obj1 = dict->lookup("SW"); if (obj1.isName()) { const char *scaleName = obj1.getName(); if(!strcmp(scaleName, "B")) { scaleWhen = scaleBigger; } else if(!strcmp(scaleName, "S")) { scaleWhen = scaleSmaller; } else if(!strcmp(scaleName, "N")) { scaleWhen = scaleNever; } else { scaleWhen = scaleAlways; } @@ -2576,46 +2589,47 @@ void AnnotLink::initialize(PDFDoc *docA, Dict *dict) { border = new AnnotBorderBS(obj1.getDict()); } else if (!border) { border = new AnnotBorderBS(); } } void AnnotLink::draw(Gfx *gfx, GBool printing) { if (!isVisible (printing)) return; annotLocker(); // draw the appearance stream Object obj = appearance.fetch(gfx->getXRef()); gfx->drawAnnot(&obj, border, color, rect->x1, rect->y1, rect->x2, rect->y2, getRotation()); } //------------------------------------------------------------------------ // AnnotFreeText //------------------------------------------------------------------------ -AnnotFreeText::AnnotFreeText(PDFDoc *docA, PDFRectangle *rect, GooString *da) : +AnnotFreeText::AnnotFreeText(PDFDoc *docA, PDFRectangle *rect, DefaultAppearance &da) : AnnotMarkup(docA, rect) { type = typeFreeText; + GooString *daStr = constructAppearanceString(da.getFontTag(), da.getFontPtSize(), da.getFontColor()); annotObj.dictSet ("Subtype", Object(objName, "FreeText")); - annotObj.dictSet("DA", Object(da->copy())); + annotObj.dictSet("DA", Object(daStr)); initialize (docA, annotObj.getDict()); } AnnotFreeText::AnnotFreeText(PDFDoc *docA, Object *dictObject, Object *obj) : AnnotMarkup(docA, dictObject, obj) { type = typeFreeText; initialize(docA, dictObject->getDict()); } AnnotFreeText::~AnnotFreeText() { delete appearanceString; if (styleString) delete styleString; if (calloutLine) delete calloutLine; if (borderEffect) @@ -2709,53 +2723,40 @@ void AnnotFreeText::initialize(PDFDoc *docA, Dict *dict) { if (obj1.isArray()) { rectangle = parseDiffRectangle(obj1.getArray(), rect); } else { rectangle = nullptr; } obj1 = dict->lookup("LE"); if (obj1.isName()) { GooString styleName(obj1.getName()); endStyle = parseAnnotLineEndingStyle(&styleName); } else { endStyle = annotLineEndingNone; } } void AnnotFreeText::setContents(GooString *new_content) { Annot::setContents(new_content); invalidateAppearance(); } -void AnnotFreeText::setAppearanceString(GooString *new_string) { - delete appearanceString; - - if (new_string) { - appearanceString = new GooString(new_string); - } else { - appearanceString = new GooString(); - } - - update ("DA", Object(appearanceString->copy())); - invalidateAppearance(); -} - void AnnotFreeText::setQuadding(AnnotFreeTextQuadding new_quadding) { quadding = new_quadding; update ("Q", Object((int)quadding)); invalidateAppearance(); } void AnnotFreeText::setStyleString(GooString *new_string) { delete styleString; if (new_string) { styleString = new GooString(new_string); //append the unicode marker if needed if (!styleString->hasUnicodeMarker()) { styleString->prependUnicodeMarker(); } } else { styleString = new GooString(); } update ("DS", Object(styleString->copy())); @@ -2788,108 +2789,142 @@ void AnnotFreeText::setCalloutLine(AnnotCalloutLine *line) { } } update("CL", std::move(obj1)); invalidateAppearance(); } void AnnotFreeText::setIntent(AnnotFreeTextIntent new_intent) { const char *intentName; intent = new_intent; if (new_intent == intentFreeText) intentName = "FreeText"; else if (new_intent == intentFreeTextCallout) intentName = "FreeTextCallout"; else // intentFreeTextTypeWriter intentName = "FreeTextTypeWriter"; update ("IT", Object(objName, intentName)); } -static GfxFont * createAnnotDrawFont(XRef * xref, Dict *fontResDict) +DefaultAppearance AnnotFreeText::getAppearanceString() const { + double fontSize; + AnnotColor *fontColor; + GooString *fontTag; + parseAppearanceString(appearanceString, fontSize, fontColor, fontTag); + return DefaultAppearance(*fontTag, fontSize, fontColor); +} + +static GfxFont *createAnnotDrawFont(XRef * xref, Dict *fontResDict) { const Ref dummyRef = { -1, -1 }; Dict *fontDict = new Dict(xref); fontDict->add(copyString("BaseFont"), Object(objName, "Helvetica")); fontDict->add(copyString("Subtype"), Object(objName, "Type0")); fontDict->add(copyString("Encoding"), Object(objName, "WinAnsiEncoding")); Dict *fontsDict = new Dict(xref); fontsDict->add(copyString("AnnotDrawFont"), Object(fontDict)); fontResDict->add(copyString("Font"), Object(fontsDict)); return GfxFont::makeFont(xref, "AnnotDrawFont", dummyRef, fontDict); } -void AnnotFreeText::parseAppearanceString(GooString *da, double &fontsize, AnnotColor* &fontcolor) { +GooString *AnnotFreeText::constructAppearanceString(GooString &fontTag, double fontSize, AnnotColor *fontColor) { + const double *colorData = fontColor->getValues(); + GooString * cstr = nullptr; + switch(fontColor->getSpace()) + { + case AnnotColor::AnnotColorSpace::colorTransparent: // =0 + cstr = new GooString(); + break; + case AnnotColor::AnnotColorSpace::colorGray: //=1 + cstr = GooString::format("{0:.2f} g ", colorData[0]); + break; + case AnnotColor::AnnotColorSpace::colorRGB: //=3 + cstr = GooString::format("{0:.2f} {1:.2f} {2:.2f} rg ", colorData[0], colorData[1], colorData[2]); + break; + case AnnotColor::AnnotColorSpace::colorCMYK: //=4 + cstr = GooString::format("{0:.2f} {1:.2f} {2:.2f} {3:.2f} k ", colorData[0], colorData[1], colorData[2], colorData[3]); + break; + } + const GooString * str = GooString::format("/{0:s} {1:.2f} Tf", &fontTag, fontSize); + return cstr->append( str ); +} + +void AnnotFreeText::parseAppearanceString(GooString *da, double &fontsize, AnnotColor* &fontcolor, GooString* &fontTag) { fontsize = -1; fontcolor = nullptr; + fontTag = nullptr; if (da) { GooList * daToks = new GooList(); int i = FormFieldText::tokenizeDA(da, daToks, "Tf"); if (i >= 1) { fontsize = gatof(( (GooString *)daToks->get(i-1) )->getCString()); - // TODO: Font name + } + if (i >= 2) { + fontTag = new GooString(( (GooString *)daToks->get(i-2) )->getCString()); } // Scan backwards: we are looking for the last set value for (i = daToks->getLength()-1; i >= 0; --i) { if (fontcolor == nullptr) { if (!((GooString *)daToks->get(i))->cmp("g") && i >= 1) { fontcolor = new AnnotColor(gatof(( (GooString *)daToks->get(i-1) )->getCString())); } else if (!((GooString *)daToks->get(i))->cmp("rg") && i >= 3) { fontcolor = new AnnotColor(gatof(( (GooString *)daToks->get(i-3) )->getCString()), gatof(( (GooString *)daToks->get(i-2) )->getCString()), gatof(( (GooString *)daToks->get(i-1) )->getCString())); } else if (!((GooString *)daToks->get(i))->cmp("k") && i >= 4) { fontcolor = new AnnotColor(gatof(( (GooString *)daToks->get(i-4) )->getCString()), gatof(( (GooString *)daToks->get(i-3) )->getCString()), gatof(( (GooString *)daToks->get(i-2) )->getCString()), gatof(( (GooString *)daToks->get(i-1) )->getCString())); } } } deleteGooList(daToks, GooString); } } void AnnotFreeText::generateFreeTextAppearance() { double borderWidth, ca = opacity; AnnotAppearanceBuilder appearBuilder; appearBuilder.append ("q\n"); borderWidth = border->getWidth(); if (borderWidth > 0) appearBuilder.setLineStyleForBorder(border); // Box size const double width = rect->x2 - rect->x1; const double height = rect->y2 - rect->y1; // Parse some properties from the appearance string double fontsize; AnnotColor *fontcolor; - parseAppearanceString(appearanceString, fontsize, fontcolor); + GooString *fontTag; + parseAppearanceString(appearanceString, fontsize, fontcolor, fontTag); // Default values if (fontsize <= 0) fontsize = 10; if (fontcolor == nullptr) fontcolor = new AnnotColor(0, 0, 0); // Black if (!contents) contents = new GooString (); // Draw box GBool doFill = (color && color->getSpace() != AnnotColor::colorTransparent); GBool doStroke = (borderWidth != 0); if (doFill || doStroke) { if (doStroke) { appearBuilder.setDrawColor(fontcolor, gFalse); // Border color: same as font color } appearBuilder.appendf ("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re\n", borderWidth/2, width-borderWidth, height-borderWidth); if (doFill) { appearBuilder.setDrawColor(color, gTrue); appearBuilder.append(doStroke ? "B\n" : "f\n"); } else { diff --git poppler/Annot.h poppler/Annot.h index 83c10b39..73e7d0a3 100644 --- poppler/Annot.h +++ poppler/Annot.h @@ -330,40 +330,60 @@ public: AnnotColor(); AnnotColor(double gray); AnnotColor(double r, double g, double b); AnnotColor(double c, double m, double y, double k); AnnotColor(Array *array, int adjust = 0); void adjustColor(int adjust); AnnotColorSpace getSpace() const { return (AnnotColorSpace) length; } const double *getValues() const { return values; } Object writeToObject(XRef *xref) const; private: double values[4]; int length; }; +//------------------------------------------------------------------------ +// DefaultAppearance +//------------------------------------------------------------------------ + +class DefaultAppearance { +public: + + DefaultAppearance(const GooString &fontTag, int fontPtSize, AnnotColor *fontColor); + GooString &getFontTag() const { return *fontTag; } + int getFontPtSize() { return fontPtSize; } + AnnotColor *getFontColor() const { return fontColor; } + ~DefaultAppearance(); + +private: + + GooString *fontTag; + int fontPtSize; + AnnotColor *fontColor; +}; + //------------------------------------------------------------------------ // AnnotIconFit //------------------------------------------------------------------------ class AnnotIconFit { public: enum AnnotIconFitScaleWhen { scaleAlways, // A scaleBigger, // B scaleSmaller, // S scaleNever // N }; enum AnnotIconFitScale { scaleAnamorphic, // A scaleProportional // P }; AnnotIconFit(Dict *dict); @@ -952,69 +972,69 @@ protected: //------------------------------------------------------------------------ // AnnotFreeText //------------------------------------------------------------------------ class AnnotFreeText: public AnnotMarkup { public: enum AnnotFreeTextQuadding { quaddingLeftJustified, // 0 quaddingCentered, // 1 quaddingRightJustified // 2 }; enum AnnotFreeTextIntent { intentFreeText, // FreeText intentFreeTextCallout, // FreeTextCallout intentFreeTextTypeWriter // FreeTextTypeWriter }; - AnnotFreeText(PDFDoc *docA, PDFRectangle *rect, GooString *da); + AnnotFreeText(PDFDoc *docA, PDFRectangle *rect, DefaultAppearance &da); AnnotFreeText(PDFDoc *docA, Object *dictObject, Object *obj); ~AnnotFreeText(); void draw(Gfx *gfx, GBool printing) override; Object getAppearanceResDict() override; void setContents(GooString *new_content) override; - void setAppearanceString(GooString *new_string); void setQuadding(AnnotFreeTextQuadding new_quadding); void setStyleString(GooString *new_string); void setCalloutLine(AnnotCalloutLine *line); void setIntent(AnnotFreeTextIntent new_intent); // getters - const GooString *getAppearanceString() const { return appearanceString; } + DefaultAppearance getAppearanceString() const; AnnotFreeTextQuadding getQuadding() const { return quadding; } // return rc const GooString *getStyleString() const { return styleString; } AnnotCalloutLine *getCalloutLine() const { return calloutLine; } AnnotFreeTextIntent getIntent() const { return intent; } AnnotBorderEffect *getBorderEffect() const { return borderEffect; } PDFRectangle *getRectangle() const { return rectangle; } AnnotLineEndingStyle getEndStyle() const { return endStyle; } protected: void initialize(PDFDoc *docA, Dict *dict); - static void parseAppearanceString(GooString *da, double &fontsize, AnnotColor* &fontcolor); + static GooString *constructAppearanceString(GooString &fontTag, double fontSize, AnnotColor *fontColor); + static void parseAppearanceString(GooString *da, double &fontSize, AnnotColor* &fontColor, GooString* &fontTag); void generateFreeTextAppearance(); // required GooString *appearanceString; // DA // optional AnnotFreeTextQuadding quadding; // Q (Default 0) // RC GooString *styleString; // DS AnnotCalloutLine *calloutLine; // CL AnnotFreeTextIntent intent; // IT AnnotBorderEffect *borderEffect; // BE PDFRectangle *rectangle; // RD // inherited from Annot // AnnotBorderBS border; // BS AnnotLineEndingStyle endStyle; // LE (Default None) }; //------------------------------------------------------------------------ // AnnotLine diff --git qt5/src/poppler-annotation.cc qt5/src/poppler-annotation.cc index 5550efcd..0e57098d 100644 --- qt5/src/poppler-annotation.cc +++ qt5/src/poppler-annotation.cc @@ -1799,140 +1799,143 @@ QList Annotation::revisions() const } /* If the annotation doesn't live in a object on its own (eg bug51361), it * has no ref, therefore it can't have revisions */ if ( !d->pdfAnnot->getHasRef() ) 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; + DefaultAppearance getDefaultAppearance() const; // 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); }; 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 * s = GooString::format("/Invalid_font {0:d} Tf", 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); + DefaultAppearance da(GooString("Invalid_font"), textFont.pointSize(), convertQColor(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; } +DefaultAppearance TextAnnotationPrivate::getDefaultAppearance() const +{ + AnnotFreeText * ftextann = static_cast(pdfAnnot); + return ftextann->getAppearanceString(); +} + TextAnnotation::TextAnnotation( TextAnnotation::TextType type ) : Annotation( *new TextAnnotationPrivate() ) { setTextType( type ); } TextAnnotation::TextAnnotation(TextAnnotationPrivate &dd) : Annotation( dd ) {} 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") ) ); + setTextColor(color); + } } 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 +1961,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() ) ); @@ -2057,73 +2061,78 @@ void TextAnnotation::setTextIcon( const QString &icon ) if (d->pdfAnnot->getType() == Annot::typeText) { AnnotText * textann = static_cast(d->pdfAnnot); QByteArray encoded = icon.toLatin1(); GooString s(encoded.constData()); textann->setIcon(&s); } } QFont TextAnnotation::textFont() const { Q_D( const TextAnnotation ); if (!d->pdfAnnot) return d->textFont; 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 - } + DefaultAppearance da = d->getDefaultAppearance(); + font.setPointSize( da.getFontPtSize() ); } return font; } void TextAnnotation::setTextFont( const QFont &font ) { Q_D( TextAnnotation ); + d->textFont = font; + d->textColor = Qt::black; +} + +QColor TextAnnotation::textColor() const +{ + Q_D( const TextAnnotation ); + if (!d->pdfAnnot) + return d->textColor; + + QColor color; + + if (d->pdfAnnot->getType() == Annot::typeFreeText) { - d->textFont = font; - return; + DefaultAppearance da = d->getDefaultAppearance(); + color = convertAnnotColor(da.getFontColor()); } - if (d->pdfAnnot->getType() != Annot::typeFreeText) - return; + return color; +} - AnnotFreeText * ftextann = static_cast(d->pdfAnnot); - GooString * da = TextAnnotationPrivate::toAppearanceString(font); - ftextann->setAppearanceString(da); - delete da; +void TextAnnotation::setTextColor( const QColor &color ) +{ + Q_D( TextAnnotation ); + + d->textColor = color; } 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; } void TextAnnotation::setInplaceAlign( int align ) { diff --git qt5/src/poppler-annotation.h qt5/src/poppler-annotation.h index a70cbe4f..63bf79ae 100644 --- qt5/src/poppler-annotation.h +++ qt5/src/poppler-annotation.h @@ -467,40 +467,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 setTextColor( 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 )