diff --git poppler/Annot.cc poppler/Annot.cc index 73536861..b74906a6 100644 --- poppler/Annot.cc +++ poppler/Annot.cc @@ -783,42 +783,42 @@ void AnnotColor::adjustColor(int adjust) { 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() : fontPtSize(0), fontColor(nullptr) { DefaultAppearance::fontTag = new GooString(); } -DefaultAppearance::DefaultAppearance(const GooString &fontTag, int fontPtSize, AnnotColor *fontColor) - : fontPtSize(fontPtSize), fontColor(fontColor) { +DefaultAppearance::DefaultAppearance(const GooString &fontTag, int fontPtSize, std::string fontName, AnnotColor *fontColor) + : fontPtSize(fontPtSize), fontColor(fontColor), fontName(fontName) { DefaultAppearance::fontTag = fontTag.copy(); } DefaultAppearance::~DefaultAppearance() { delete fontTag; if (fontColor) { delete fontColor; } } //------------------------------------------------------------------------ // AnnotIconFit //------------------------------------------------------------------------ AnnotIconFit::AnnotIconFit(Dict* dict) { Object obj1; obj1 = dict->lookup("SW"); if (obj1.isName()) { const char *scaleName = obj1.getName(); @@ -2601,68 +2601,74 @@ void AnnotLink::initialize(PDFDoc *docA, Dict *dict) { 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, const DefaultAppearance &da) : AnnotMarkup(docA, rect) { type = typeFreeText; GooString *daStr = constructAppearanceString(da.getFontTag(), da.getFontPtSize(), da.getFontColor()); + setFontName(da.getFontName()); annotObj.dictSet ("Subtype", Object(objName, "FreeText")); 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) delete borderEffect; if (rectangle) delete rectangle; } +void AnnotFreeText::setFontName( std::string fname ) +{ + fontName = fname; +} + void AnnotFreeText::initialize(PDFDoc *docA, Dict *dict) { Object obj1; obj1 = dict->lookup("DA"); if (obj1.isString()) { appearanceString = obj1.getString()->copy(); } else { appearanceString = new GooString(); error(errSyntaxError, -1, "Bad appearance for annotation"); ok = gFalse; } obj1 = dict->lookup("Q"); if (obj1.isInt()) { quadding = (AnnotFreeTextQuadding) obj1.getInt(); } else { quadding = quaddingLeftJustified; } obj1 = dict->lookup("DS"); @@ -2809,53 +2815,57 @@ void AnnotFreeText::setCalloutLine(AnnotCalloutLine *line) { 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)); } DefaultAppearance AnnotFreeText::getAppearanceString() const { double fontSize; AnnotColor *fontColor; GooString *fontTag; + std::string fontName = getFontName(); parseAppearanceString(appearanceString, fontSize, fontColor, fontTag); - DefaultAppearance da(*fontTag, fontSize, fontColor); + DefaultAppearance da(*fontTag, fontSize, fontName, fontColor); delete fontTag; return da; } -static GfxFont *createAnnotDrawFont(XRef * xref, Dict *fontResDict) +static GfxFont *createAnnotDrawFont(XRef * xref, Dict *fontResDict, std::string fontName = "") { const Ref dummyRef = { -1, -1 }; Dict *fontDict = new Dict(xref); - fontDict->add(copyString("BaseFont"), Object(objName, "Helvetica")); - fontDict->add(copyString("Subtype"), Object(objName, "Type0")); + if(fontName.length()) + fontDict->add(copyString("BaseFont"), Object(objName, fontName.c_str())); + else + fontDict->add(copyString("BaseFont"), Object(objName, "Helvetica")); + fontDict->add(copyString("Subtype"), Object(objName, "Type1")); 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); } GooString *AnnotFreeText::constructAppearanceString(const GooString &fontTag, double fontSize, const 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]); @@ -2939,41 +2949,41 @@ void AnnotFreeText::generateFreeTextAppearance() 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 { appearBuilder.append("S\n"); } } // Setup text clipping const double textmargin = borderWidth * 2; const double textwidth = width - 2*textmargin; appearBuilder.appendf ("{0:.2f} {0:.2f} {1:.2f} {2:.2f} re W n\n", textmargin, textwidth, height - 2*textmargin); Dict *fontResDict = new Dict(xref); - GfxFont *font = createAnnotDrawFont(xref, fontResDict); + GfxFont *font = createAnnotDrawFont(xref, fontResDict, fontName); // Set font state appearBuilder.setDrawColor(fontcolor, gTrue); appearBuilder.appendf ("BT 1 0 0 1 {0:.2f} {1:.2f} Tm\n", textmargin, height - textmargin - fontsize * font->getDescent()); appearBuilder.appendf ("/AnnotDrawFont {0:.2f} Tf\n", fontsize); int i = 0; double xposPrev = 0; while (i < contents->getLength()) { GooString out; double linewidth, xpos; layoutText(contents, &out, &i, font, &linewidth, textwidth/fontsize, nullptr, gFalse); linewidth *= fontsize; switch (quadding) { case quaddingCentered: xpos = (textwidth - linewidth) / 2; break; case quaddingRightJustified: xpos = textwidth - linewidth; break; diff --git poppler/Annot.h poppler/Annot.h index b8c82bcf..d750630d 100644 --- poppler/Annot.h +++ poppler/Annot.h @@ -24,41 +24,41 @@ // Copyright (C) 2009-2011, 2013, 2016-2018 Albert Astals Cid // Copyright (C) 2012, 2013 Fabio D'Urso // Copyright (C) 2012, 2015 Tobias Koenig // Copyright (C) 2013 Thomas Freitag // Copyright (C) 2013, 2017 Adrian Johnson // Copyright (C) 2018 Klarälvdalens Datakonsult AB, a KDAB Group company, . Work sponsored by the LiMux project of the city of Munich // // To see a description of the changes please see the Changelog file that // came with your tarball or type make ChangeLog if you are building from git // //======================================================================== #ifndef ANNOT_H #define ANNOT_H #ifdef USE_GCC_PRAGMAS #pragma interface #endif #include "Object.h" - +#include class XRef; class Gfx; class CharCodeToUnicode; class GfxFont; class GfxResources; class Page; class PDFDoc; class Form; class FormWidget; class FormField; class FormFieldButton; class FormFieldText; class FormFieldChoice; class PDFRectangle; class Movie; class LinkAction; class Sound; class FileSpec; enum AnnotLineEndingStyle { @@ -338,48 +338,50 @@ public: 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(); - DefaultAppearance(const GooString &fontTag, int fontPtSize, AnnotColor *fontColor = nullptr); + DefaultAppearance(const GooString &fontTag, int fontPtSize, std::string fontName, AnnotColor *fontColor = nullptr); const GooString &getFontTag() const { return *fontTag; } int getFontPtSize() const { return fontPtSize; } const AnnotColor *getFontColor() const { return fontColor; } + std::string getFontName() const { return fontName; } ~DefaultAppearance(); private: + std::string fontName; GooString *fontTag; int fontPtSize; AnnotColor *fontColor; }; //------------------------------------------------------------------------ // AnnotIconFit //------------------------------------------------------------------------ class AnnotIconFit { public: enum AnnotIconFitScaleWhen { scaleAlways, // A scaleBigger, // B scaleSmaller, // S scaleNever // N }; enum AnnotIconFitScale { @@ -982,68 +984,71 @@ public: quaddingLeftJustified, // 0 quaddingCentered, // 1 quaddingRightJustified // 2 }; enum AnnotFreeTextIntent { intentFreeText, // FreeText intentFreeTextCallout, // FreeTextCallout intentFreeTextTypeWriter // FreeTextTypeWriter }; AnnotFreeText(PDFDoc *docA, PDFRectangle *rect, const 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(const DefaultAppearance &da); + void setFontName(std::string str); void setQuadding(AnnotFreeTextQuadding new_quadding); void setStyleString(GooString *new_string); void setCalloutLine(AnnotCalloutLine *line); void setIntent(AnnotFreeTextIntent new_intent); // getters 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; } + std::string getFontName() const { return fontName; } protected: void initialize(PDFDoc *docA, Dict *dict); static GooString *constructAppearanceString(const GooString &fontTag, double fontSize, const 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) + std::string fontName; // 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 //------------------------------------------------------------------------ class AnnotLine: public AnnotMarkup { public: enum AnnotLineIntent { intentLineArrow, // LineArrow diff --git qt5/src/poppler-annotation.cc qt5/src/poppler-annotation.cc index 0b14ad69..491c6fa2 100644 --- qt5/src/poppler-annotation.cc +++ qt5/src/poppler-annotation.cc @@ -1799,103 +1799,141 @@ 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; + void createFontTagandName(); void setDefaultAppearanceToNative(); DefaultAppearance getDefaultAppearanceFromNative() const; // data fields TextAnnotation::TextType textType; QString textIcon; QFont textFont; QColor textColor; + GooString * textTag; + std::string textName; int inplaceAlign; // 0:left, 1:center, 2:right QVector inplaceCallout; TextAnnotation::InplaceIntent inplaceIntent; }; TextAnnotationPrivate::TextAnnotationPrivate() : AnnotationPrivate(), textType( TextAnnotation::Linked ), textIcon( QStringLiteral("Note") ), inplaceAlign( 0 ), inplaceIntent( TextAnnotation::Unknown ) { } Annotation * TextAnnotationPrivate::makeAlias() { return new TextAnnotation(*this); } +void TextAnnotationPrivate::createFontTagandName() +{ + int len; + QString fontTag; + QStringList list = textFont.family().split(QRegExp("\\s+"), QString::SkipEmptyParts); + + for(int i = 0; i < list.size(); i++) + { + len = list.at(i).length()/2; + for (int j = 0; j < len; j++) + fontTag.append(list.at(i).at(j)); + } + + QByteArray encoded = fontTag.toLatin1(); + textTag = new GooString(encoded.constData()); + + // create fontName + + QString fontName; + QStringList styleList = textFont.styleName().split(QRegExp("\\s+"), QString::SkipEmptyParts); + fontName.append(list.at(0)); + if (QString::compare(styleList.at(0), QString("Regular"), Qt::CaseInsensitive)) + { + fontName.append(QString("-")); + for(int k = 0; k < styleList.size(); k++) + { + fontName.append(styleList.at(k)); + } + } + + textName = fontName.toUtf8().constData(); +} + 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 { - DefaultAppearance da(GooString("Invalid_font"), textFont.pointSize(), convertQColor(textColor)); + createFontTagandName(); + DefaultAppearance da(*textTag, textFont.pointSize(), textName, convertQColor(textColor)); pdfAnnot = new AnnotFreeText(destPage->getDoc(), &rect, 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; } void TextAnnotationPrivate::setDefaultAppearanceToNative() { if (pdfAnnot && pdfAnnot->getType() == Annot::typeFreeText) { + createFontTagandName(); AnnotFreeText * ftextann = static_cast(pdfAnnot); AnnotColor *color = convertQColor(textColor); - DefaultAppearance da(GooString("Invalid_font"), textFont.pointSize(), color); + DefaultAppearance da(*textTag, textFont.pointSize(), textName, color); ftextann->setAppearanceString(da); } } DefaultAppearance TextAnnotationPrivate::getDefaultAppearanceFromNative() const { if (pdfAnnot && pdfAnnot->getType() == Annot::typeFreeText) { AnnotFreeText * ftextann = static_cast(pdfAnnot); return ftextann->getAppearanceString(); } else { return DefaultAppearance(); } } TextAnnotation::TextAnnotation( TextAnnotation::TextType type ) : Annotation( *new TextAnnotationPrivate() ) { setTextType( type ); }