[poppler] poppler/Annot.cc poppler/Annot.h poppler/BBoxOutputDev.cc poppler/CairoFontEngine.cc poppler/CairoFontEngine.h poppler/CairoOutputDev.cc poppler/FontInfo.cc poppler/Gfx.cc poppler/GfxFont.cc poppler/GfxFont.h poppler/Gfx.h poppler/GfxState.cc poppler/GfxState.h poppler/MarkedContentOutputDev.cc poppler/MarkedContentOutputDev.h poppler/PreScanOutputDev.cc poppler/PSOutputDev.cc poppler/SplashOutputDev.cc poppler/TextOutputDev.cc poppler/TextOutputDev.h qt5/src qt6/src utils/HtmlFonts.cc utils/HtmlFonts.h utils/HtmlOutputDev.cc

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Wed Mar 9 23:42:27 UTC 2022


 poppler/Annot.cc                  |   70 +++++++++++++++++---------------------
 poppler/Annot.h                   |    2 -
 poppler/BBoxOutputDev.cc          |    3 -
 poppler/CairoFontEngine.cc        |   30 +++++-----------
 poppler/CairoFontEngine.h         |    4 +-
 poppler/CairoOutputDev.cc         |    2 -
 poppler/FontInfo.cc               |    5 +-
 poppler/Gfx.cc                    |   18 +++------
 poppler/Gfx.h                     |    6 +--
 poppler/GfxFont.cc                |   35 ++-----------------
 poppler/GfxFont.h                 |   18 ++-------
 poppler/GfxState.cc               |   12 +-----
 poppler/GfxState.h                |    6 +--
 poppler/MarkedContentOutputDev.cc |   13 +------
 poppler/MarkedContentOutputDev.h  |   16 +++-----
 poppler/PSOutputDev.cc            |    7 +--
 poppler/PreScanOutputDev.cc       |    2 -
 poppler/SplashOutputDev.cc        |    6 +--
 poppler/TextOutputDev.cc          |   11 +----
 poppler/TextOutputDev.h           |    2 -
 qt5/src/QPainterOutputDev.cc      |   30 ++++++++--------
 qt6/src/QPainterOutputDev.cc      |   30 ++++++++--------
 utils/HtmlFonts.cc                |    8 ++--
 utils/HtmlFonts.h                 |    2 -
 utils/HtmlOutputDev.cc            |    9 ++--
 25 files changed, 133 insertions(+), 214 deletions(-)

New commits:
commit 6388c277453f59336bfe5af45f0a5dbb161947bc
Author: Oliver Sander <oliver.sander at tu-dresden.de>
Date:   Fri Jan 7 09:46:47 2022 +0100

    Replace hand-coded reference counting in GfxFont by std::shared_ptr

diff --git a/poppler/Annot.cc b/poppler/Annot.cc
index ccc07af3..3102c7cd 100644
--- a/poppler/Annot.cc
+++ b/poppler/Annot.cc
@@ -2970,7 +2970,7 @@ std::unique_ptr<DefaultAppearance> AnnotFreeText::getDefaultAppearance() const
     return std::make_unique<DefaultAppearance>(appearanceString.get());
 }
 
-static GfxFont *createAnnotDrawFont(XRef *xref, Dict *fontParentDict, const char *resourceName = "AnnotDrawFont", const char *fontname = "Helvetica")
+static std::unique_ptr<GfxFont> createAnnotDrawFont(XRef *xref, Dict *fontParentDict, const char *resourceName = "AnnotDrawFont", const char *fontname = "Helvetica")
 {
     const Ref dummyRef = { -1, -1 };
 
@@ -3041,7 +3041,7 @@ void AnnotFreeText::generateFreeTextAppearance()
     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);
 
-    GfxFont *font = nullptr;
+    std::unique_ptr<const GfxFont> font = nullptr;
 
     // look for font name in the default resources
     Form *form = doc->getCatalog()->getForm(); // form is owned by catalog, no need to clean it up
@@ -3085,7 +3085,7 @@ void AnnotFreeText::generateFreeTextAppearance()
     while (i < contents->getLength()) {
         GooString out;
         double linewidth, xpos;
-        layoutText(contents.get(), &out, &i, font, &linewidth, textwidth / da.getFontPtSize(), nullptr, false);
+        layoutText(contents.get(), &out, &i, *font, &linewidth, textwidth / da.getFontPtSize(), nullptr, false);
         linewidth *= da.getFontPtSize();
         switch (quadding) {
         case quaddingCentered:
@@ -3104,7 +3104,6 @@ void AnnotFreeText::generateFreeTextAppearance()
         xposPrev = xpos;
     }
 
-    font->decRefCnt();
     appearBuilder.append("ET Q\n");
 
     double bbox[4];
@@ -3407,7 +3406,7 @@ void AnnotLine::generateLineAppearance()
     const double lineendingSize = std::min(6. * borderWidth, main_len / 2);
 
     Dict *fontResDict;
-    GfxFont *font;
+    std::unique_ptr<const GfxFont> font;
 
     // Calculate caption width and height
     if (caption) {
@@ -3418,7 +3417,7 @@ void AnnotLine::generateLineAppearance()
         while (i < contents->getLength()) {
             GooString out;
             double linewidth;
-            layoutText(contents.get(), &out, &i, font, &linewidth, 0, nullptr, false);
+            layoutText(contents.get(), &out, &i, *font, &linewidth, 0, nullptr, false);
             linewidth *= fontsize;
             if (linewidth > captionwidth) {
                 captionwidth = linewidth;
@@ -3502,7 +3501,7 @@ void AnnotLine::generateLineAppearance()
         while (i < contents->getLength()) {
             GooString out;
             double linewidth, xpos;
-            layoutText(contents.get(), &out, &i, font, &linewidth, 0, nullptr, false);
+            layoutText(contents.get(), &out, &i, *font, &linewidth, 0, nullptr, false);
             linewidth *= fontsize;
             xpos = (captionwidth - linewidth) / 2;
             appearBuilder.appendf("{0:.2f} {1:.2f} Td\n", xpos - xposPrev, -fontsize);
@@ -3511,7 +3510,6 @@ void AnnotLine::generateLineAppearance()
             xposPrev = xpos;
         }
         appearBuilder.append("ET\n");
-        font->decRefCnt();
     }
 
     // Draw leader lines
@@ -4016,7 +4014,7 @@ bool AnnotWidget::setFormAdditionalAction(FormAdditionalActionsType formAddition
 // TODO: Handle surrogate pairs in UTF-16.
 //       Should be able to generate output for any CID-keyed font.
 //       Doesn't handle vertical fonts--should it?
-void Annot::layoutText(const GooString *text, GooString *outBuf, int *i, const GfxFont *font, double *width, double widthLimit, int *charCount, bool noReencode)
+void Annot::layoutText(const GooString *text, GooString *outBuf, int *i, const GfxFont &font, double *width, double widthLimit, int *charCount, bool noReencode)
 {
     CharCode c;
     Unicode uChar;
@@ -4097,13 +4095,13 @@ void Annot::layoutText(const GooString *text, GooString *outBuf, int *i, const G
         if (noReencode) {
             outBuf->append(uChar);
         } else {
-            const CharCodeToUnicode *ccToUnicode = font->getToUnicode();
+            const CharCodeToUnicode *ccToUnicode = font.getToUnicode();
             if (!ccToUnicode) {
                 // This assumes an identity CMap.
                 outBuf->append((uChar >> 8) & 0xff);
                 outBuf->append(uChar & 0xff);
             } else if (ccToUnicode->mapToCharCode(&uChar, &c, 1)) {
-                if (font->isCIDFont()) {
+                if (font.isCIDFont()) {
                     // TODO: This assumes an identity CMap.  It should be extended to
                     // handle the general case.
                     outBuf->append((c >> 8) & 0xff);
@@ -4130,7 +4128,7 @@ void Annot::layoutText(const GooString *text, GooString *outBuf, int *i, const G
         // Compute width of character just output
         if (outBuf->getLength() > last_o2) {
             dx = 0.0;
-            font->getNextChar(outBuf->c_str() + last_o2, outBuf->getLength() - last_o2, &c, &uAux, &uLen, &dx, &dy, &ox, &oy);
+            font.getNextChar(outBuf->c_str() + last_o2, outBuf->getLength() - last_o2, &c, &uAux, &uLen, &dx, &dy, &ox, &oy);
             w += dx;
         }
 
@@ -4185,7 +4183,7 @@ void Annot::layoutText(const GooString *text, GooString *outBuf, int *i, const G
 
         while (len > 0) {
             dx = 0.0;
-            n = font->getNextChar(s, len, &c, &uAux, &uLen, &dx, &dy, &ox, &oy);
+            n = font.getNextChar(s, len, &c, &uAux, &uLen, &dx, &dy, &ox, &oy);
 
             if (n == 0) {
                 break;
@@ -4239,7 +4237,7 @@ bool AnnotAppearanceBuilder::drawText(const GooString *text, const GooString *da
     int tfPos, tmPos, j;
     int rot;
     bool freeText = false; // true if text should be freed before return
-    GfxFont *fontToFree = nullptr;
+    std::unique_ptr<const GfxFont> fontToFree = nullptr;
 
     //~ if there is no MK entry, this should use the existing content stream,
     //~ and only replace the marked content portion of it
@@ -4282,11 +4280,15 @@ bool AnnotAppearanceBuilder::drawText(const GooString *text, const GooString *da
             }
         }
         if (tok->getLength() >= 1 && tok->getChar(0) == '/') {
-            if (!resources || !(font = resources->lookupFont(tok->c_str() + 1))) {
+            if (!resources || !(font = resources->lookupFont(tok->c_str() + 1).get())) {
                 if (xref != nullptr && resourcesDict != nullptr) {
                     const char *fallback = determineFallbackFont(tok->toStr(), defaultFallback);
+                    // The font variable sometimes points to an object that needs to be deleted
+                    // and sometimes not, depending on whether the call to lookupFont above fails.
+                    // When the code path right here is taken, the destructor of fontToFree
+                    // (which is a std::unique_ptr) will delete the font object at the end of this method.
                     fontToFree = createAnnotDrawFont(xref, resourcesDict, tok->c_str() + 1, fallback);
-                    font = fontToFree;
+                    font = fontToFree.get();
                 } else {
                     error(errSyntaxError, -1, "Unknown font in field's DA string");
                 }
@@ -4364,7 +4366,7 @@ bool AnnotAppearanceBuilder::drawText(const GooString *text, const GooString *da
                 y = dy - 3;
                 int i = 0;
                 while (i < text->getLength()) {
-                    Annot::layoutText(text, &convertedText, &i, font, &w, wMax / fontSize, nullptr, forceZapfDingbats);
+                    Annot::layoutText(text, &convertedText, &i, *font, &w, wMax / fontSize, nullptr, forceZapfDingbats);
                     y -= fontSize;
                 }
                 // approximate the descender for the last line
@@ -4408,7 +4410,7 @@ bool AnnotAppearanceBuilder::drawText(const GooString *text, const GooString *da
         int i = 0;
         xPrev = 0;
         while (i < text->getLength()) {
-            Annot::layoutText(text, &convertedText, &i, font, &w, wMax / fontSize, nullptr, forceZapfDingbats);
+            Annot::layoutText(text, &convertedText, &i, *font, &w, wMax / fontSize, nullptr, forceZapfDingbats);
             w *= fontSize;
 
             // compute text start position
@@ -4460,7 +4462,7 @@ bool AnnotAppearanceBuilder::drawText(const GooString *text, const GooString *da
             }
 
             int i = 0;
-            Annot::layoutText(text, &convertedText, &i, font, nullptr, 0.0, &charCount, forceZapfDingbats);
+            Annot::layoutText(text, &convertedText, &i, *font, nullptr, 0.0, &charCount, forceZapfDingbats);
             if (charCount > comb)
                 charCount = comb;
 
@@ -4533,7 +4535,7 @@ bool AnnotAppearanceBuilder::drawText(const GooString *text, const GooString *da
             // regular (non-comb) formatting
         } else {
             int ii = 0;
-            Annot::layoutText(text, &convertedText, &ii, font, &w, 0.0, nullptr, forceZapfDingbats);
+            Annot::layoutText(text, &convertedText, &ii, *font, &w, 0.0, nullptr, forceZapfDingbats);
 
             // compute font autosize
             if (fontSize == 0) {
@@ -4605,9 +4607,6 @@ bool AnnotAppearanceBuilder::drawText(const GooString *text, const GooString *da
     if (freeText) {
         delete text;
     }
-    if (fontToFree) {
-        fontToFree->decRefCnt();
-    }
 
     return true;
 }
@@ -4621,7 +4620,7 @@ bool AnnotAppearanceBuilder::drawListBox(const FormFieldChoice *fieldChoice, con
     const GfxFont *font;
     double fontSize, borderWidth, x, y, w, wMax;
     int tfPos, tmPos, i, j;
-    GfxFont *fontToFree = nullptr;
+    std::unique_ptr<const GfxFont> fontToFree;
 
     //~ if there is no MK entry, this should use the existing content stream,
     //~ and only replace the marked content portion of it
@@ -4657,11 +4656,15 @@ bool AnnotAppearanceBuilder::drawListBox(const FormFieldChoice *fieldChoice, con
     if (tfPos >= 0) {
         tok = daToks[tfPos];
         if (tok->getLength() >= 1 && tok->getChar(0) == '/') {
-            if (!resources || !(font = resources->lookupFont(tok->c_str() + 1))) {
+            if (!resources || !(font = resources->lookupFont(tok->c_str() + 1).get())) {
                 if (xref != nullptr && resourcesDict != nullptr) {
                     const char *fallback = determineFallbackFont(tok->toStr(), "Helvetica");
+                    // The font variable sometimes points to an object that needs to be deleted
+                    // and sometimes not, depending on whether the call to lookupFont above fails.
+                    // When the code path right here is taken, the destructor of fontToFree
+                    // (which is a std::unique_ptr) will delete the font object at the end of this method.
                     fontToFree = createAnnotDrawFont(xref, resourcesDict, tok->c_str() + 1, fallback);
-                    font = fontToFree;
+                    font = fontToFree.get();
                 } else {
                     error(errSyntaxError, -1, "Unknown font in field's DA string");
                 }
@@ -4694,12 +4697,9 @@ bool AnnotAppearanceBuilder::drawListBox(const FormFieldChoice *fieldChoice, con
                 for (auto entry : daToks) {
                     delete entry;
                 }
-                if (fontToFree) {
-                    fontToFree->decRefCnt();
-                }
                 return false;
             }
-            Annot::layoutText(fieldChoice->getChoice(i), &convertedText, &j, font, &w, 0.0, nullptr, false);
+            Annot::layoutText(fieldChoice->getChoice(i), &convertedText, &j, *font, &w, 0.0, nullptr, false);
             if (w > wMax) {
                 wMax = w;
             }
@@ -4733,7 +4733,7 @@ bool AnnotAppearanceBuilder::drawListBox(const FormFieldChoice *fieldChoice, con
 
         // compute text width and start position
         j = 0;
-        Annot::layoutText(fieldChoice->getChoice(i), &convertedText, &j, font, &w, 0.0, nullptr, false);
+        Annot::layoutText(fieldChoice->getChoice(i), &convertedText, &j, *font, &w, 0.0, nullptr, false);
         w *= fontSize;
         switch (quadding) {
         case quaddingLeftJustified:
@@ -4788,9 +4788,6 @@ bool AnnotAppearanceBuilder::drawListBox(const FormFieldChoice *fieldChoice, con
     for (auto entry : daToks) {
         delete entry;
     }
-    if (fontToFree) {
-        fontToFree->decRefCnt();
-    }
 
     return true;
 }
@@ -5057,7 +5054,7 @@ void AnnotAppearanceBuilder::drawSignatureFieldText(const GooString &text, const
     const double textwidth = width - 2 * textmargin;
 
     // create a Helvetica fake font
-    GfxFont *font = createAnnotDrawFont(xref, resourcesDict, da.getFontName().getName());
+    std::unique_ptr<const GfxFont> font = createAnnotDrawFont(xref, resourcesDict, da.getFontName().getName());
 
     // calculate the string tokenization
     int i = 0;
@@ -5065,7 +5062,7 @@ void AnnotAppearanceBuilder::drawSignatureFieldText(const GooString &text, const
     while (i < text.getLength()) {
         GooString out;
         double textWidth;
-        Annot::layoutText(&text, &out, &i, font, &textWidth, textwidth / da.getFontPtSize(), nullptr, false);
+        Annot::layoutText(&text, &out, &i, *font, &textWidth, textwidth / da.getFontPtSize(), nullptr, false);
         outTexts.emplace_back(out.toStr(), textWidth * da.getFontPtSize());
     }
 
@@ -5103,7 +5100,6 @@ void AnnotAppearanceBuilder::drawSignatureFieldText(const GooString &text, const
         yDelta = -da.getFontPtSize();
     }
 
-    font->decRefCnt();
     append("ET Q\n");
 }
 
diff --git a/poppler/Annot.h b/poppler/Annot.h
index 3a7b8e74..a18c6768 100644
--- a/poppler/Annot.h
+++ b/poppler/Annot.h
@@ -755,7 +755,7 @@ public:
     // Check if point is inside the annot rectangle.
     bool inRect(double x, double y) const;
 
-    static void layoutText(const GooString *text, GooString *outBuf, int *i, const GfxFont *font, double *width, double widthLimit, int *charCount, bool noReencode);
+    static void layoutText(const GooString *text, GooString *outBuf, int *i, const GfxFont &font, double *width, double widthLimit, int *charCount, bool noReencode);
 
 private:
     void readArrayNum(Object *pdfArray, int key, double *value);
diff --git a/poppler/BBoxOutputDev.cc b/poppler/BBoxOutputDev.cc
index 991bcc76..1204f00a 100644
--- a/poppler/BBoxOutputDev.cc
+++ b/poppler/BBoxOutputDev.cc
@@ -93,7 +93,6 @@ void BBoxOutputDev::drawSoftMaskedImage(GfxState *state, Object *ref, Stream *st
 
 void BBoxOutputDev::drawChar(GfxState *state, double x, double y, double dx, double dy, double originX, double originY, CharCode code, int nBytes, const Unicode *u, int uLen)
 {
-    GfxFont *font;
     double leftent, rightent, ascent, descent;
     const double *fm, *fb;
     double fontSize, w, adjust;
@@ -102,7 +101,7 @@ void BBoxOutputDev::drawChar(GfxState *state, double x, double y, double dx, dou
     if (!text)
         return;
 
-    font = state->getFont();
+    const GfxFont *const font = state->getFont().get();
     if (!font)
         return;
 
diff --git a/poppler/CairoFontEngine.cc b/poppler/CairoFontEngine.cc
index 1c892165..d06812ec 100644
--- a/poppler/CairoFontEngine.cc
+++ b/poppler/CairoFontEngine.cc
@@ -550,9 +550,9 @@ static const cairo_user_data_key_t type3_font_key = { 0 };
 
 typedef struct _type3_font_info
 {
-    _type3_font_info(GfxFont *fontA, PDFDoc *docA, CairoFontEngine *fontEngineA, bool printingA, XRef *xrefA) : font(fontA), doc(docA), fontEngine(fontEngineA), printing(printingA), xref(xrefA) { }
+    _type3_font_info(const std::shared_ptr<const GfxFont> &fontA, PDFDoc *docA, CairoFontEngine *fontEngineA, bool printingA, XRef *xrefA) : font(fontA), doc(docA), fontEngine(fontEngineA), printing(printingA), xref(xrefA) { }
 
-    GfxFont *font;
+    std::shared_ptr<const GfxFont> font;
     PDFDoc *doc;
     CairoFontEngine *fontEngine;
     bool printing;
@@ -562,18 +562,15 @@ typedef struct _type3_font_info
 static void _free_type3_font_info(void *closure)
 {
     type3_font_info_t *info = (type3_font_info_t *)closure;
-
-    info->font->decRefCnt();
     delete info;
 }
 
 static cairo_status_t _init_type3_glyph(cairo_scaled_font_t *scaled_font, cairo_t *cr, cairo_font_extents_t *extents)
 {
     type3_font_info_t *info;
-    GfxFont *font;
 
     info = (type3_font_info_t *)cairo_font_face_get_user_data(cairo_scaled_font_get_font_face(scaled_font), &type3_font_key);
-    font = info->font;
+    std::shared_ptr<const GfxFont> font = info->font;
     const double *mat = font->getFontBBox();
     extents->ascent = mat[3]; /* y2 */
     extents->descent = -mat[3]; /* -y1 */
@@ -594,15 +591,13 @@ static cairo_status_t _render_type3_glyph(cairo_scaled_font_t *scaled_font, unsi
     double wx, wy;
     PDFRectangle box;
     type3_font_info_t *info;
-    GfxFont *font;
-    Dict *resDict;
     Gfx *gfx;
 
     info = (type3_font_info_t *)cairo_font_face_get_user_data(cairo_scaled_font_get_font_face(scaled_font), &type3_font_key);
 
-    font = info->font;
-    resDict = ((Gfx8BitFont *)font)->getResources();
-    charProcs = ((Gfx8BitFont *)(info->font))->getCharProcs();
+    std::shared_ptr<const GfxFont> font = info->font;
+    Dict *resDict = ((Gfx8BitFont *)font.get())->getResources();
+    charProcs = ((Gfx8BitFont *)(info->font.get()))->getCharProcs();
     if (!charProcs)
         return CAIRO_STATUS_USER_FONT_ERROR;
 
@@ -657,28 +652,25 @@ static cairo_status_t _render_type3_glyph(cairo_scaled_font_t *scaled_font, unsi
     return CAIRO_STATUS_SUCCESS;
 }
 
-CairoType3Font *CairoType3Font::create(GfxFont *gfxFont, PDFDoc *doc, CairoFontEngine *fontEngine, bool printing, XRef *xref)
+CairoType3Font *CairoType3Font::create(const std::shared_ptr<const GfxFont> &gfxFont, PDFDoc *doc, CairoFontEngine *fontEngine, bool printing, XRef *xref)
 {
     cairo_font_face_t *font_face;
     Ref ref;
     int *codeToGID;
     unsigned int codeToGIDLen;
     int i, j;
-    char **enc;
-    Dict *charProcs;
     char *name;
 
-    charProcs = ((Gfx8BitFont *)gfxFont)->getCharProcs();
+    Dict *charProcs = ((Gfx8BitFont *)gfxFont.get())->getCharProcs();
     ref = *gfxFont->getID();
     font_face = cairo_user_font_face_create();
     cairo_user_font_face_set_init_func(font_face, _init_type3_glyph);
     cairo_user_font_face_set_render_glyph_func(font_face, _render_type3_glyph);
-    gfxFont->incRefCnt();
     type3_font_info_t *info = new type3_font_info_t(gfxFont, doc, fontEngine, printing, xref);
 
     cairo_font_face_set_user_data(font_face, &type3_font_key, (void *)info, _free_type3_font_info);
 
-    enc = ((Gfx8BitFont *)gfxFont)->getEncoding();
+    char **enc = ((Gfx8BitFont *)gfxFont.get())->getEncoding();
     codeToGID = (int *)gmallocn(256, sizeof(int));
     codeToGIDLen = 256;
     for (i = 0; i < 256; ++i) {
@@ -735,7 +727,7 @@ CairoFontEngine::~CairoFontEngine()
     }
 }
 
-CairoFont *CairoFontEngine::getFont(GfxFont *gfxFont, PDFDoc *doc, bool printing, XRef *xref)
+CairoFont *CairoFontEngine::getFont(const std::shared_ptr<GfxFont> &gfxFont, PDFDoc *doc, bool printing, XRef *xref)
 {
     int i, j;
     Ref ref;
@@ -760,7 +752,7 @@ CairoFont *CairoFontEngine::getFont(GfxFont *gfxFont, PDFDoc *doc, bool printing
     if (fontType == fontType3)
         font = CairoType3Font::create(gfxFont, doc, this, printing, xref);
     else
-        font = CairoFreeTypeFont::create(gfxFont, xref, lib, useCIDs);
+        font = CairoFreeTypeFont::create(gfxFont.get(), xref, lib, useCIDs);
 
     // XXX: if font is null should we still insert it into the cache?
     if (fontCache[cairoFontCacheSize - 1]) {
diff --git a/poppler/CairoFontEngine.h b/poppler/CairoFontEngine.h
index 47eb3e7f..b7444b13 100644
--- a/poppler/CairoFontEngine.h
+++ b/poppler/CairoFontEngine.h
@@ -83,7 +83,7 @@ private:
 class CairoType3Font : public CairoFont
 {
 public:
-    static CairoType3Font *create(GfxFont *gfxFont, PDFDoc *doc, CairoFontEngine *fontEngine, bool printing, XRef *xref);
+    static CairoType3Font *create(const std::shared_ptr<const GfxFont> &gfxFont, PDFDoc *doc, CairoFontEngine *fontEngine, bool printing, XRef *xref);
     ~CairoType3Font() override;
 
     bool matches(Ref &other, bool printing) override;
@@ -109,7 +109,7 @@ public:
     CairoFontEngine(const CairoFontEngine &) = delete;
     CairoFontEngine &operator=(const CairoFontEngine &other) = delete;
 
-    CairoFont *getFont(GfxFont *gfxFont, PDFDoc *doc, bool printing, XRef *xref);
+    CairoFont *getFont(const std::shared_ptr<GfxFont> &gfxFont, PDFDoc *doc, bool printing, XRef *xref);
 
 private:
     CairoFont *fontCache[cairoFontCacheSize];
diff --git a/poppler/CairoOutputDev.cc b/poppler/CairoOutputDev.cc
index e44a41dd..96e6baa7 100644
--- a/poppler/CairoOutputDev.cc
+++ b/poppler/CairoOutputDev.cc
@@ -671,7 +671,7 @@ void CairoOutputDev::updateFont(GfxState *state)
     /* NOTE: adjusting by a constant is hack. The correct solution
      * is probably to use user-fonts and compute the scale on a per
      * glyph basis instead of for the entire font */
-    double w = currentFont->getSubstitutionCorrection(state->getFont());
+    double w = currentFont->getSubstitutionCorrection(state->getFont().get());
     matrix.xx = m[0] * fontSize * state->getHorizScaling() * w;
     matrix.yx = m[1] * fontSize * state->getHorizScaling() * w;
     matrix.xy = -m[2] * fontSize;
diff --git a/poppler/FontInfo.cc b/poppler/FontInfo.cc
index d4cbc83b..7cf240fd 100644
--- a/poppler/FontInfo.cc
+++ b/poppler/FontInfo.cc
@@ -97,7 +97,6 @@ std::vector<FontInfo *> FontInfoScanner::scan(int nPages)
 void FontInfoScanner::scanFonts(XRef *xrefA, Dict *resDict, std::vector<FontInfo *> *fontsList)
 {
     GfxFontDict *gfxFontDict;
-    GfxFont *font;
 
     // scan the fonts in this resource dictionary
     gfxFontDict = nullptr;
@@ -113,12 +112,12 @@ void FontInfoScanner::scanFonts(XRef *xrefA, Dict *resDict, std::vector<FontInfo
     }
     if (gfxFontDict) {
         for (int i = 0; i < gfxFontDict->getNumFonts(); ++i) {
-            if ((font = gfxFontDict->getFont(i))) {
+            if (const std::shared_ptr<GfxFont> &font = gfxFontDict->getFont(i)) {
                 Ref fontRef = *font->getID();
 
                 // add this font to the list if not already found
                 if (fonts.insert(fontRef.num).second) {
-                    fontsList->push_back(new FontInfo(font, xrefA));
+                    fontsList->push_back(new FontInfo(font.get(), xrefA));
                 }
             }
         }
diff --git a/poppler/Gfx.cc b/poppler/Gfx.cc
index 873fb287..f70d8931 100644
--- a/poppler/Gfx.cc
+++ b/poppler/Gfx.cc
@@ -293,14 +293,13 @@ GfxResources::~GfxResources()
     delete fonts;
 }
 
-GfxFont *GfxResources::doLookupFont(const char *name) const
+std::shared_ptr<GfxFont> GfxResources::doLookupFont(const char *name) const
 {
-    GfxFont *font;
     const GfxResources *resPtr;
 
     for (resPtr = this; resPtr; resPtr = resPtr->next) {
         if (resPtr->fonts) {
-            if ((font = resPtr->fonts->lookup(name)))
+            if (std::shared_ptr<GfxFont> font = resPtr->fonts->lookup(name))
                 return font;
         }
     }
@@ -308,12 +307,12 @@ GfxFont *GfxResources::doLookupFont(const char *name) const
     return nullptr;
 }
 
-GfxFont *GfxResources::lookupFont(const char *name)
+std::shared_ptr<GfxFont> GfxResources::lookupFont(const char *name)
 {
     return doLookupFont(name);
 }
 
-const GfxFont *GfxResources::lookupFont(const char *name) const
+std::shared_ptr<const GfxFont> GfxResources::lookupFont(const char *name) const
 {
     return doLookupFont(name);
 }
@@ -1174,7 +1173,6 @@ void Gfx::opSetExtGState(Object args[], int numArgs)
     }
     obj2 = obj1.dictLookup("Font");
     if (obj2.isArray()) {
-        GfxFont *font;
         if (obj2.arrayGetLength() == 2) {
             const Object &fargs0 = obj2.arrayGetNF(0);
             Object fargs1 = obj2.arrayGet(1);
@@ -1182,7 +1180,7 @@ void Gfx::opSetExtGState(Object args[], int numArgs)
                 Object fobj = fargs0.fetch(xref);
                 if (fobj.isDict()) {
                     Ref r = fargs0.getRef();
-                    font = GfxFont::makeFont(xref, args[0].getName(), r, fobj.getDict());
+                    std::shared_ptr<GfxFont> font = GfxFont::makeFont(xref, args[0].getName(), r, fobj.getDict());
                     state->setFont(font, fargs1.getNum());
                     fontChanged = true;
                 }
@@ -3603,7 +3601,7 @@ void Gfx::opSetCharSpacing(Object args[], int numArgs)
 
 void Gfx::opSetFont(Object args[], int numArgs)
 {
-    GfxFont *font;
+    std::shared_ptr<GfxFont> font;
 
     if (!(font = res->lookupFont(args[0].getName()))) {
         // unsetting the font (drawing no text) is better than using the
@@ -3617,7 +3615,6 @@ void Gfx::opSetFont(Object args[], int numArgs)
         fflush(stdout);
     }
 
-    font->incRefCnt();
     state->setFont(font, args[1].getNum());
     fontChanged = true;
 }
@@ -3819,7 +3816,6 @@ void Gfx::opShowSpaceText(Object args[], int numArgs)
 
 void Gfx::doShowText(const GooString *s)
 {
-    GfxFont *font;
     int wMode;
     double riseX, riseY;
     CharCode code;
@@ -3837,7 +3833,7 @@ void Gfx::doShowText(const GooString *s)
     bool patternFill;
     int len, n, uLen, nChars, nSpaces;
 
-    font = state->getFont();
+    GfxFont *const font = state->getFont().get();
     wMode = font->getWMode();
 
     if (out->useDrawChar()) {
diff --git a/poppler/Gfx.h b/poppler/Gfx.h
index ae9fa76f..d7c1ca97 100644
--- a/poppler/Gfx.h
+++ b/poppler/Gfx.h
@@ -117,8 +117,8 @@ public:
     GfxResources(const GfxResources &) = delete;
     GfxResources &operator=(const GfxResources &other) = delete;
 
-    GfxFont *lookupFont(const char *name);
-    const GfxFont *lookupFont(const char *name) const;
+    std::shared_ptr<GfxFont> lookupFont(const char *name);
+    std::shared_ptr<const GfxFont> lookupFont(const char *name) const;
     Object lookupXObject(const char *name);
     Object lookupXObjectNF(const char *name);
     Object lookupMarkedContentNF(const char *name);
@@ -131,7 +131,7 @@ public:
     GfxResources *getNext() const { return next; }
 
 private:
-    GfxFont *doLookupFont(const char *name) const;
+    std::shared_ptr<GfxFont> doLookupFont(const char *name) const;
 
     GfxFontDict *fonts;
     Object xObjDict;
diff --git a/poppler/GfxFont.cc b/poppler/GfxFont.cc
index 62b7429d..9d21a8d9 100644
--- a/poppler/GfxFont.cc
+++ b/poppler/GfxFont.cc
@@ -197,12 +197,11 @@ const GooString *GfxFontLoc::pathAsGooString() const
 // GfxFont
 //------------------------------------------------------------------------
 
-GfxFont *GfxFont::makeFont(XRef *xref, const char *tagA, Ref idA, Dict *fontDict)
+std::unique_ptr<GfxFont> GfxFont::makeFont(XRef *xref, const char *tagA, Ref idA, Dict *fontDict)
 {
     GooString *nameA;
     Ref embFontIDA;
     GfxFontType typeA;
-    GfxFont *font;
 
     // get base font name
     nameA = nullptr;
@@ -215,14 +214,14 @@ GfxFont *GfxFont::makeFont(XRef *xref, const char *tagA, Ref idA, Dict *fontDict
     typeA = getFontType(xref, fontDict, &embFontIDA);
 
     // create the font object
-    font = nullptr;
+    GfxFont *font;
     if (typeA < fontCIDType0) {
         font = new Gfx8BitFont(xref, tagA, idA, nameA, typeA, embFontIDA, fontDict);
     } else {
         font = new GfxCIDFont(xref, tagA, idA, nameA, typeA, embFontIDA, fontDict);
     }
 
-    return font;
+    return std::unique_ptr<GfxFont>(font);
 }
 
 GfxFont::GfxFont(const char *tagA, Ref idA, const GooString *nameA, GfxFontType typeA, Ref embFontIDA) : tag(tagA), id(idA), type(typeA)
@@ -234,7 +233,6 @@ GfxFont::GfxFont(const char *tagA, Ref idA, const GooString *nameA, GfxFontType
     family = nullptr;
     stretch = StretchNotDefined;
     weight = WeightNotDefined;
-    refCnt = 1;
     hasToUnicode = false;
 }
 
@@ -249,17 +247,6 @@ GfxFont::~GfxFont()
     }
 }
 
-void GfxFont::incRefCnt()
-{
-    refCnt++;
-}
-
-void GfxFont::decRefCnt()
-{
-    if (--refCnt == 0)
-        delete this;
-}
-
 bool GfxFont::isSubset() const
 {
     if (name) {
@@ -984,7 +971,6 @@ Gfx8BitFont::Gfx8BitFont(XRef *xref, const char *tagA, Ref idA, GooString *nameA
     Object obj1;
     int n, i, a, b, m;
 
-    refCnt = 1;
     ctu = nullptr;
 
     // do font name substitution for various aliases of the Base 14 font
@@ -1735,7 +1721,6 @@ GfxCIDFont::GfxCIDFont(XRef *xref, const char *tagA, Ref idA, GooString *nameA,
     int c1, c2;
     int excepsSize;
 
-    refCnt = 1;
     ascent = 0.95;
     descent = -0.35;
     fontBBox[0] = fontBBox[1] = fontBBox[2] = fontBBox[3] = 0;
@@ -2379,8 +2364,7 @@ GfxFontDict::GfxFontDict(XRef *xref, Ref *fontDictRef, Dict *fontDict)
                 // NULL and !isOk() so that when we do lookups
                 // we can tell the difference between a missing font
                 // and a font that is just !isOk()
-                fonts[i]->decRefCnt();
-                fonts[i] = nullptr;
+                fonts[i].reset();
             }
         } else {
             error(errSyntaxError, -1, "font resource is not a dictionary");
@@ -2389,16 +2373,7 @@ GfxFontDict::GfxFontDict(XRef *xref, Ref *fontDictRef, Dict *fontDict)
     }
 }
 
-GfxFontDict::~GfxFontDict()
-{
-    for (auto &font : fonts) {
-        if (font) {
-            font->decRefCnt();
-        }
-    }
-}
-
-GfxFont *GfxFontDict::lookup(const char *tag) const
+std::shared_ptr<GfxFont> GfxFontDict::lookup(const char *tag) const
 {
     for (const auto &font : fonts) {
         if (font && font->matches(tag)) {
diff --git a/poppler/GfxFont.h b/poppler/GfxFont.h
index c88de3c6..ee70a7af 100644
--- a/poppler/GfxFont.h
+++ b/poppler/GfxFont.h
@@ -188,16 +188,14 @@ public:
     };
 
     // Build a GfxFont object.
-    static GfxFont *makeFont(XRef *xref, const char *tagA, Ref idA, Dict *fontDict);
+    static std::unique_ptr<GfxFont> makeFont(XRef *xref, const char *tagA, Ref idA, Dict *fontDict);
 
     GfxFont(const GfxFont &) = delete;
     GfxFont &operator=(const GfxFont &other) = delete;
+    virtual ~GfxFont();
 
     bool isOk() const { return ok; }
 
-    void incRefCnt();
-    void decRefCnt();
-
     // Get font tag.
     const std::string &getTag() const { return tag; }
 
@@ -308,8 +306,6 @@ public:
 protected:
     GfxFont(const char *tagA, Ref idA, const GooString *nameA, GfxFontType typeA, Ref embFontIDA);
 
-    virtual ~GfxFont();
-
     static GfxFontType getFontType(XRef *xref, Dict *fontDict, Ref *embID);
     void readFontDescriptor(XRef *xref, Dict *fontDict);
     CharCodeToUnicode *readToUnicodeCMap(Dict *fontDict, int nBits, CharCodeToUnicode *ctu);
@@ -330,7 +326,6 @@ protected:
     double missingWidth; // "default" width
     double ascent; // max height above baseline
     double descent; // max depth below baseline
-    int refCnt;
     bool ok;
     bool hasToUnicode;
     std::string encodingName;
@@ -454,24 +449,21 @@ public:
     // Build the font dictionary, given the PDF font dictionary.
     GfxFontDict(XRef *xref, Ref *fontDictRef, Dict *fontDict);
 
-    // Destructor.
-    ~GfxFontDict();
-
     GfxFontDict(const GfxFontDict &) = delete;
     GfxFontDict &operator=(const GfxFontDict &) = delete;
 
     // Get the specified font.
-    GfxFont *lookup(const char *tag) const;
+    std::shared_ptr<GfxFont> lookup(const char *tag) const;
 
     // Iterative access.
     int getNumFonts() const { return fonts.size(); }
-    GfxFont *getFont(int i) const { return fonts[i]; }
+    const std::shared_ptr<GfxFont> &getFont(int i) const { return fonts[i]; }
 
 private:
     int hashFontObject(Object *obj);
     void hashFontObject1(const Object *obj, FNVHash *h);
 
-    std::vector<GfxFont *> fonts;
+    std::vector<std::shared_ptr<GfxFont>> fonts;
 };
 
 #endif
diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc
index c24332bd..f46e425e 100644
--- a/poppler/GfxState.cc
+++ b/poppler/GfxState.cc
@@ -6533,9 +6533,6 @@ GfxState::~GfxState()
         // this gets set to NULL by restore()
         delete path;
     }
-    if (font) {
-        font->decRefCnt();
-    }
 
     delete defaultGrayColorSpace;
     delete defaultRGBColorSpace;
@@ -6606,8 +6603,6 @@ GfxState::GfxState(const GfxState *state, bool copyPath)
     textKnockout = state->textKnockout;
 
     font = state->font;
-    if (font)
-        font->incRefCnt();
     fontSize = state->fontSize;
     memcpy(textMat, state->textMat, sizeof(textMat));
     charSpace = state->charSpace;
@@ -6901,12 +6896,9 @@ void GfxState::setStrokePattern(GfxPattern *pattern)
     strokePattern = pattern;
 }
 
-void GfxState::setFont(GfxFont *fontA, double fontSizeA)
+void GfxState::setFont(std::shared_ptr<GfxFont> fontA, double fontSizeA)
 {
-    if (font)
-        font->decRefCnt();
-
-    font = fontA;
+    font = std::move(fontA);
     fontSize = fontSizeA;
 }
 
diff --git a/poppler/GfxState.h b/poppler/GfxState.h
index 64a78ae0..0d86d65e 100644
--- a/poppler/GfxState.h
+++ b/poppler/GfxState.h
@@ -1504,7 +1504,7 @@ public:
     bool getStrokeAdjust() const { return strokeAdjust; }
     bool getAlphaIsShape() const { return alphaIsShape; }
     bool getTextKnockout() const { return textKnockout; }
-    GfxFont *getFont() const { return font; }
+    const std::shared_ptr<GfxFont> &getFont() const { return font; }
     double getFontSize() const { return fontSize; }
     const double *getTextMat() const { return textMat; }
     double getCharSpace() const { return charSpace; }
@@ -1585,7 +1585,7 @@ public:
     void setStrokeAdjust(bool sa) { strokeAdjust = sa; }
     void setAlphaIsShape(bool ais) { alphaIsShape = ais; }
     void setTextKnockout(bool tk) { textKnockout = tk; }
-    void setFont(GfxFont *fontA, double fontSizeA);
+    void setFont(std::shared_ptr<GfxFont> fontA, double fontSizeA);
     void setTextMat(double a, double b, double c, double d, double e, double f)
     {
         textMat[0] = a;
@@ -1720,7 +1720,7 @@ private:
     bool alphaIsShape; // alpha is shape
     bool textKnockout; // text knockout
 
-    GfxFont *font; // font
+    std::shared_ptr<GfxFont> font; // font
     double fontSize; // font size
     double textMat[6]; // text matrix
     double charSpace; // character spacing
diff --git a/poppler/MarkedContentOutputDev.cc b/poppler/MarkedContentOutputDev.cc
index 3573adf2..4c5e42d0 100644
--- a/poppler/MarkedContentOutputDev.cc
+++ b/poppler/MarkedContentOutputDev.cc
@@ -26,8 +26,6 @@ MarkedContentOutputDev::MarkedContentOutputDev(int mcidA, const Object &stmObj)
 
 MarkedContentOutputDev::~MarkedContentOutputDev()
 {
-    if (currentFont)
-        currentFont->decRefCnt();
     delete currentText;
 }
 
@@ -101,7 +99,7 @@ void MarkedContentOutputDev::endMarkedContent(GfxState *state)
     }
 }
 
-bool MarkedContentOutputDev::needFontChange(const GfxFont *font) const
+bool MarkedContentOutputDev::needFontChange(const std::shared_ptr<const GfxFont> &font) const
 {
     if (currentFont == font)
         return false;
@@ -149,14 +147,7 @@ void MarkedContentOutputDev::drawChar(GfxState *state, double xx, double yy, dou
         currentColor = color;
 
     if (fontChange) {
-        if (currentFont != nullptr) {
-            currentFont->decRefCnt();
-            currentFont = nullptr;
-        }
-        if (state->getFont() != nullptr) {
-            currentFont = state->getFont();
-            currentFont->incRefCnt();
-        }
+        currentFont = state->getFont();
     }
 
     double sp, dx2, dy2, w1, h1, x1, y1;
diff --git a/poppler/MarkedContentOutputDev.h b/poppler/MarkedContentOutputDev.h
index 8d46d1a2..ba2ef07c 100644
--- a/poppler/MarkedContentOutputDev.h
+++ b/poppler/MarkedContentOutputDev.h
@@ -43,24 +43,22 @@ public:
             delete data;
     }
 
-    GfxFont *getFont() const { return data->font; }
+    const std::shared_ptr<GfxFont> &getFont() const { return data->font; }
     GooString *getText() const { return data->text; }
     GfxRGB &getColor() const { return data->color; }
 
 private:
     // Note: Takes ownership of strings, increases refcount for font.
-    TextSpan(GooString *text, GfxFont *font, const GfxRGB color) : data(new Data)
+    TextSpan(GooString *text, std::shared_ptr<GfxFont> font, const GfxRGB color) : data(new Data)
     {
         data->text = text;
-        data->font = font;
+        data->font = std::move(font);
         data->color = color;
-        if (data->font)
-            data->font->incRefCnt();
     }
 
     struct Data
     {
-        GfxFont *font;
+        std::shared_ptr<GfxFont> font;
         GooString *text;
         GfxRGB color;
         unsigned refcount;
@@ -70,8 +68,6 @@ private:
         ~Data()
         {
             assert(refcount == 0);
-            if (font)
-                font->decRefCnt();
             delete text;
         }
 
@@ -116,9 +112,9 @@ private:
     void endSpan();
     bool inMarkedContent() const { return mcidStack.size() > 0; }
     bool contentStreamMatch();
-    bool needFontChange(const GfxFont *font) const;
+    bool needFontChange(const std::shared_ptr<const GfxFont> &font) const;
 
-    GfxFont *currentFont;
+    std::shared_ptr<GfxFont> currentFont;
     GooString *currentText;
     GfxRGB currentColor;
     TextSpanArray textSpans;
diff --git a/poppler/PSOutputDev.cc b/poppler/PSOutputDev.cc
index fb4af2e2..4b570af6 100644
--- a/poppler/PSOutputDev.cc
+++ b/poppler/PSOutputDev.cc
@@ -1921,7 +1921,6 @@ void PSOutputDev::setupFonts(Dict *resDict)
 {
     Ref r;
     GfxFontDict *gfxFontDict;
-    GfxFont *font;
     int i;
 
     gfxFontDict = nullptr;
@@ -1937,8 +1936,8 @@ void PSOutputDev::setupFonts(Dict *resDict)
     }
     if (gfxFontDict) {
         for (i = 0; i < gfxFontDict->getNumFonts(); ++i) {
-            if ((font = gfxFontDict->getFont(i))) {
-                setupFont(font, resDict);
+            if (const std::shared_ptr<GfxFont> &font = gfxFontDict->getFont(i)) {
+                setupFont(font.get(), resDict);
             }
         }
         delete gfxFontDict;
@@ -5009,7 +5008,7 @@ void PSOutputDev::doPath(const GfxPath *path)
 
 void PSOutputDev::drawString(GfxState *state, const GooString *s)
 {
-    GfxFont *font;
+    std::shared_ptr<GfxFont> font;
     int wMode;
     int *codeToGID;
     GooString *s2;
diff --git a/poppler/PreScanOutputDev.cc b/poppler/PreScanOutputDev.cc
index d28da26c..9823ac58 100644
--- a/poppler/PreScanOutputDev.cc
+++ b/poppler/PreScanOutputDev.cc
@@ -151,7 +151,7 @@ void PreScanOutputDev::beginStringOp(GfxState *state)
         check(state->getStrokeColorSpace(), state->getStrokeColor(), state->getStrokeOpacity(), state->getBlendMode());
     }
 
-    const GfxFont *font = state->getFont();
+    std::shared_ptr<const GfxFont> font = state->getFont();
     state->getFontTransMat(&m11, &m12, &m21, &m22);
     //~ this should check for external fonts that are non-TrueType
     simpleTTF = fabs(m11 + m22) < 0.01 && m11 > 0 && fabs(m12) < 0.01 && fabs(m21) < 0.01 && fabs(state->getHorizScaling() - 1) < 0.001 && (font->getType() == fontTrueType || font->getType() == fontTrueTypeOT);
diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc
index c337e4e4..57ac0260 100644
--- a/poppler/SplashOutputDev.cc
+++ b/poppler/SplashOutputDev.cc
@@ -1823,7 +1823,6 @@ void SplashOutputDev::updateFont(GfxState * /*state*/)
 
 void SplashOutputDev::doUpdateFont(GfxState *state)
 {
-    GfxFont *gfxFont;
     GfxFontType fontType;
     SplashOutFontFileID *id = nullptr;
     SplashFontFile *fontFile;
@@ -1841,7 +1840,8 @@ void SplashOutputDev::doUpdateFont(GfxState *state)
     font = nullptr;
     tmpBuf = nullptr;
 
-    if (!(gfxFont = state->getFont())) {
+    GfxFont *const gfxFont = state->getFont().get();
+    if (!gfxFont) {
         goto err1;
     }
     fontType = gfxFont->getType();
@@ -2266,7 +2266,7 @@ void SplashOutputDev::drawChar(GfxState *state, double x, double y, double dx, d
 
 bool SplashOutputDev::beginType3Char(GfxState *state, double x, double y, double dx, double dy, CharCode code, const Unicode *u, int uLen)
 {
-    GfxFont *gfxFont;
+    std::shared_ptr<const GfxFont> gfxFont;
     const Ref *fontID;
     const double *ctm, *bbox;
     T3FontCache *t3Font;
diff --git a/poppler/TextOutputDev.cc b/poppler/TextOutputDev.cc
index 67a6246d..cbfe8bca 100644
--- a/poppler/TextOutputDev.cc
+++ b/poppler/TextOutputDev.cc
@@ -350,8 +350,6 @@ public:
 TextFontInfo::TextFontInfo(const GfxState *state)
 {
     gfxFont = state->getFont();
-    if (gfxFont)
-        gfxFont->incRefCnt();
 #ifdef TEXTOUT_WORD_LIST
     fontName = (gfxFont && gfxFont->getName()) ? gfxFont->getName()->copy() : nullptr;
     flags = gfxFont ? gfxFont->getFlags() : 0;
@@ -360,8 +358,6 @@ TextFontInfo::TextFontInfo(const GfxState *state)
 
 TextFontInfo::~TextFontInfo()
 {
-    if (gfxFont)
-        gfxFont->decRefCnt();
 #ifdef TEXTOUT_WORD_LIST
     if (fontName) {
         delete fontName;
@@ -2510,7 +2506,6 @@ void TextPage::clear()
 
 void TextPage::updateFont(const GfxState *state)
 {
-    GfxFont *gfxFont;
     const double *fm;
     const char *name;
     int code, mCode, letterCode, anyCode;
@@ -2530,7 +2525,7 @@ void TextPage::updateFont(const GfxState *state)
     }
 
     // adjust the font size
-    gfxFont = state->getFont();
+    GfxFont *const gfxFont = state->getFont().get();
     curFontSize = state->getTransformedFontSize();
     if (gfxFont && gfxFont->getType() == fontType3) {
         // This is a hack which makes it possible to deal with some Type 3
@@ -2573,7 +2568,6 @@ void TextPage::updateFont(const GfxState *state)
 
 void TextPage::beginWord(const GfxState *state)
 {
-    GfxFont *gfxFont;
     const double *fontm;
     double m[4], m2[4];
     int rot;
@@ -2588,7 +2582,7 @@ void TextPage::beginWord(const GfxState *state)
 
     // compute the rotation
     state->getFontTransMat(&m[0], &m[1], &m[2], &m[3]);
-    gfxFont = state->getFont();
+    std::shared_ptr<GfxFont> gfxFont = state->getFont();
     if (gfxFont && gfxFont->getType() == fontType3) {
         fontm = state->getFont()->getFontMatrix();
         m2[0] = fontm[0] * m[0] + fontm[1] * m[2];
@@ -4751,7 +4745,6 @@ void TextSelectionPainter::endPage()
 
         while (begin < sel->end) {
             TextFontInfo *font = sel->word->font[begin];
-            font->gfxFont->incRefCnt();
             Matrix *mat = &sel->word->textMat[begin];
 
             state->setTextMat(mat->m[0], mat->m[1], mat->m[2], mat->m[3], 0, 0);
diff --git a/poppler/TextOutputDev.h b/poppler/TextOutputDev.h
index 9df36278..bc25f648 100644
--- a/poppler/TextOutputDev.h
+++ b/poppler/TextOutputDev.h
@@ -119,7 +119,7 @@ public:
 #endif
 
 private:
-    GfxFont *gfxFont;
+    std::shared_ptr<GfxFont> gfxFont;
 #ifdef TEXTOUT_WORD_LIST
     GooString *fontName;
     int flags;
diff --git a/qt5/src/QPainterOutputDev.cc b/qt5/src/QPainterOutputDev.cc
index e0cf87fe..98a3c407 100644
--- a/qt5/src/QPainterOutputDev.cc
+++ b/qt5/src/QPainterOutputDev.cc
@@ -64,13 +64,13 @@
 class QPainterOutputDevType3Font
 {
 public:
-    QPainterOutputDevType3Font(PDFDoc *doc, Gfx8BitFont *font);
+    QPainterOutputDevType3Font(PDFDoc *doc, const std::shared_ptr<Gfx8BitFont> &font);
 
     const QPicture &getGlyph(int gid) const;
 
 private:
     PDFDoc *m_doc;
-    Gfx8BitFont *m_font;
+    std::shared_ptr<Gfx8BitFont> m_font;
 
     mutable std::vector<std::unique_ptr<QPicture>> glyphs;
 
@@ -78,7 +78,7 @@ public:
     std::vector<int> codeToGID;
 };
 
-QPainterOutputDevType3Font::QPainterOutputDevType3Font(PDFDoc *doc, Gfx8BitFont *font) : m_doc(doc), m_font(font)
+QPainterOutputDevType3Font::QPainterOutputDevType3Font(PDFDoc *doc, const std::shared_ptr<Gfx8BitFont> &font) : m_doc(doc), m_font(font)
 {
     char *name;
     const Dict *charProcs = font->getCharProcs();
@@ -417,7 +417,7 @@ void QPainterOutputDev::updateStrokeOpacity(GfxState *state)
 
 void QPainterOutputDev::updateFont(GfxState *state)
 {
-    GfxFont *gfxFont = state->getFont();
+    const std::shared_ptr<GfxFont> &gfxFont = state->getFont();
     if (!gfxFont) {
         return;
     }
@@ -436,7 +436,7 @@ void QPainterOutputDev::updateFont(GfxState *state)
 
         } else {
 
-            m_currentType3Font = new QPainterOutputDevType3Font(m_doc, (Gfx8BitFont *)gfxFont);
+            m_currentType3Font = new QPainterOutputDevType3Font(m_doc, std::static_pointer_cast<Gfx8BitFont>(gfxFont));
             m_type3FontCache.insert(std::make_pair(fontID, std::unique_ptr<QPainterOutputDevType3Font>(m_currentType3Font)));
         }
 
@@ -570,7 +570,7 @@ void QPainterOutputDev::updateFont(GfxState *state)
             int *codeToGID = (int *)gmallocn(256, sizeof(int));
             for (int i = 0; i < 256; ++i) {
                 codeToGID[i] = 0;
-                if ((name = ((const char **)((Gfx8BitFont *)gfxFont)->getEncoding())[i])) {
+                if ((name = ((const char **)((Gfx8BitFont *)gfxFont.get())->getEncoding())[i])) {
                     codeToGID[i] = (int)FT_Get_Name_Index(freeTypeFace, (char *)name);
                     if (codeToGID[i] == 0) {
                         name = GfxFont::getAlternateName(name);
@@ -591,7 +591,7 @@ void QPainterOutputDev::updateFont(GfxState *state)
         case fontTrueTypeOT: {
             auto ff = (fontLoc->locType != gfxFontLocEmbedded) ? FoFiTrueType::load(fontLoc->path.c_str()) : FoFiTrueType::make(tmpBuf.get(), tmpBufLen);
 
-            m_codeToGIDCache[id] = (ff) ? ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ff.get()) : nullptr;
+            m_codeToGIDCache[id] = (ff) ? ((Gfx8BitFont *)gfxFont.get())->getCodeToGIDMap(ff.get()) : nullptr;
 
             break;
         }
@@ -614,10 +614,10 @@ void QPainterOutputDev::updateFont(GfxState *state)
         case fontCIDType0COT: {
             int *codeToGID = nullptr;
 
-            if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {
-                int codeToGIDLen = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
+            if (((GfxCIDFont *)gfxFont.get())->getCIDToGID()) {
+                int codeToGIDLen = ((GfxCIDFont *)gfxFont.get())->getCIDToGIDLen();
                 codeToGID = (int *)gmallocn(codeToGIDLen, sizeof(int));
-                memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(), codeToGIDLen * sizeof(int));
+                memcpy(codeToGID, ((GfxCIDFont *)gfxFont.get())->getCIDToGID(), codeToGIDLen * sizeof(int));
             }
 
             int *cidToGIDMap = nullptr;
@@ -639,18 +639,18 @@ void QPainterOutputDev::updateFont(GfxState *state)
         case fontCIDType2OT: {
             int *codeToGID = nullptr;
             int codeToGIDLen = 0;
-            if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {
-                codeToGIDLen = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
+            if (((GfxCIDFont *)gfxFont.get())->getCIDToGID()) {
+                codeToGIDLen = ((GfxCIDFont *)gfxFont.get())->getCIDToGIDLen();
                 if (codeToGIDLen) {
                     codeToGID = (int *)gmallocn(codeToGIDLen, sizeof(int));
-                    memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(), codeToGIDLen * sizeof(int));
+                    memcpy(codeToGID, ((GfxCIDFont *)gfxFont.get())->getCIDToGID(), codeToGIDLen * sizeof(int));
                 }
             } else {
                 auto ff = (fontLoc->locType != gfxFontLocEmbedded) ? FoFiTrueType::load(fontLoc->path.c_str()) : FoFiTrueType::make(tmpBuf.get(), tmpBufLen);
                 if (!ff) {
                     return;
                 }
-                codeToGID = ((GfxCIDFont *)gfxFont)->getCodeToGIDMap(ff.get(), &codeToGIDLen);
+                codeToGID = ((GfxCIDFont *)gfxFont.get())->getCodeToGIDMap(ff.get(), &codeToGIDLen);
             }
 
             m_codeToGIDCache[id] = codeToGID;
@@ -867,7 +867,7 @@ void QPainterOutputDev::drawChar(GfxState *state, double x, double y, double dx,
 {
 
     // First handle type3 fonts
-    GfxFont *gfxFont = state->getFont();
+    const std::shared_ptr<GfxFont> &gfxFont = state->getFont();
 
     GfxFontType fontType = gfxFont->getType();
     if (fontType == fontType3) {
diff --git a/qt6/src/QPainterOutputDev.cc b/qt6/src/QPainterOutputDev.cc
index e0cf87fe..98a3c407 100644
--- a/qt6/src/QPainterOutputDev.cc
+++ b/qt6/src/QPainterOutputDev.cc
@@ -64,13 +64,13 @@
 class QPainterOutputDevType3Font
 {
 public:
-    QPainterOutputDevType3Font(PDFDoc *doc, Gfx8BitFont *font);
+    QPainterOutputDevType3Font(PDFDoc *doc, const std::shared_ptr<Gfx8BitFont> &font);
 
     const QPicture &getGlyph(int gid) const;
 
 private:
     PDFDoc *m_doc;
-    Gfx8BitFont *m_font;
+    std::shared_ptr<Gfx8BitFont> m_font;
 
     mutable std::vector<std::unique_ptr<QPicture>> glyphs;
 
@@ -78,7 +78,7 @@ public:
     std::vector<int> codeToGID;
 };
 
-QPainterOutputDevType3Font::QPainterOutputDevType3Font(PDFDoc *doc, Gfx8BitFont *font) : m_doc(doc), m_font(font)
+QPainterOutputDevType3Font::QPainterOutputDevType3Font(PDFDoc *doc, const std::shared_ptr<Gfx8BitFont> &font) : m_doc(doc), m_font(font)
 {
     char *name;
     const Dict *charProcs = font->getCharProcs();
@@ -417,7 +417,7 @@ void QPainterOutputDev::updateStrokeOpacity(GfxState *state)
 
 void QPainterOutputDev::updateFont(GfxState *state)
 {
-    GfxFont *gfxFont = state->getFont();
+    const std::shared_ptr<GfxFont> &gfxFont = state->getFont();
     if (!gfxFont) {
         return;
     }
@@ -436,7 +436,7 @@ void QPainterOutputDev::updateFont(GfxState *state)
 
         } else {
 
-            m_currentType3Font = new QPainterOutputDevType3Font(m_doc, (Gfx8BitFont *)gfxFont);
+            m_currentType3Font = new QPainterOutputDevType3Font(m_doc, std::static_pointer_cast<Gfx8BitFont>(gfxFont));
             m_type3FontCache.insert(std::make_pair(fontID, std::unique_ptr<QPainterOutputDevType3Font>(m_currentType3Font)));
         }
 
@@ -570,7 +570,7 @@ void QPainterOutputDev::updateFont(GfxState *state)
             int *codeToGID = (int *)gmallocn(256, sizeof(int));
             for (int i = 0; i < 256; ++i) {
                 codeToGID[i] = 0;
-                if ((name = ((const char **)((Gfx8BitFont *)gfxFont)->getEncoding())[i])) {
+                if ((name = ((const char **)((Gfx8BitFont *)gfxFont.get())->getEncoding())[i])) {
                     codeToGID[i] = (int)FT_Get_Name_Index(freeTypeFace, (char *)name);
                     if (codeToGID[i] == 0) {
                         name = GfxFont::getAlternateName(name);
@@ -591,7 +591,7 @@ void QPainterOutputDev::updateFont(GfxState *state)
         case fontTrueTypeOT: {
             auto ff = (fontLoc->locType != gfxFontLocEmbedded) ? FoFiTrueType::load(fontLoc->path.c_str()) : FoFiTrueType::make(tmpBuf.get(), tmpBufLen);
 
-            m_codeToGIDCache[id] = (ff) ? ((Gfx8BitFont *)gfxFont)->getCodeToGIDMap(ff.get()) : nullptr;
+            m_codeToGIDCache[id] = (ff) ? ((Gfx8BitFont *)gfxFont.get())->getCodeToGIDMap(ff.get()) : nullptr;
 
             break;
         }
@@ -614,10 +614,10 @@ void QPainterOutputDev::updateFont(GfxState *state)
         case fontCIDType0COT: {
             int *codeToGID = nullptr;
 
-            if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {
-                int codeToGIDLen = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
+            if (((GfxCIDFont *)gfxFont.get())->getCIDToGID()) {
+                int codeToGIDLen = ((GfxCIDFont *)gfxFont.get())->getCIDToGIDLen();
                 codeToGID = (int *)gmallocn(codeToGIDLen, sizeof(int));
-                memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(), codeToGIDLen * sizeof(int));
+                memcpy(codeToGID, ((GfxCIDFont *)gfxFont.get())->getCIDToGID(), codeToGIDLen * sizeof(int));
             }
 
             int *cidToGIDMap = nullptr;
@@ -639,18 +639,18 @@ void QPainterOutputDev::updateFont(GfxState *state)
         case fontCIDType2OT: {
             int *codeToGID = nullptr;
             int codeToGIDLen = 0;
-            if (((GfxCIDFont *)gfxFont)->getCIDToGID()) {
-                codeToGIDLen = ((GfxCIDFont *)gfxFont)->getCIDToGIDLen();
+            if (((GfxCIDFont *)gfxFont.get())->getCIDToGID()) {
+                codeToGIDLen = ((GfxCIDFont *)gfxFont.get())->getCIDToGIDLen();
                 if (codeToGIDLen) {
                     codeToGID = (int *)gmallocn(codeToGIDLen, sizeof(int));
-                    memcpy(codeToGID, ((GfxCIDFont *)gfxFont)->getCIDToGID(), codeToGIDLen * sizeof(int));
+                    memcpy(codeToGID, ((GfxCIDFont *)gfxFont.get())->getCIDToGID(), codeToGIDLen * sizeof(int));
                 }
             } else {
                 auto ff = (fontLoc->locType != gfxFontLocEmbedded) ? FoFiTrueType::load(fontLoc->path.c_str()) : FoFiTrueType::make(tmpBuf.get(), tmpBufLen);
                 if (!ff) {
                     return;
                 }
-                codeToGID = ((GfxCIDFont *)gfxFont)->getCodeToGIDMap(ff.get(), &codeToGIDLen);
+                codeToGID = ((GfxCIDFont *)gfxFont.get())->getCodeToGIDMap(ff.get(), &codeToGIDLen);
             }
 
             m_codeToGIDCache[id] = codeToGID;
@@ -867,7 +867,7 @@ void QPainterOutputDev::drawChar(GfxState *state, double x, double y, double dx,
 {
 
     // First handle type3 fonts
-    GfxFont *gfxFont = state->getFont();
+    const std::shared_ptr<GfxFont> &gfxFont = state->getFont();
 
     GfxFontType fontType = gfxFont->getType();
     if (fontType == fontType3) {
diff --git a/utils/HtmlFonts.cc b/utils/HtmlFonts.cc
index a536ee83..f17044ba 100644
--- a/utils/HtmlFonts.cc
+++ b/utils/HtmlFonts.cc
@@ -121,7 +121,7 @@ GooString *HtmlFontColor::toString() const
     return tmp;
 }
 
-HtmlFont::HtmlFont(GfxFont *font, int _size, GfxRGB rgb, double opacity)
+HtmlFont::HtmlFont(const GfxFont &font, int _size, GfxRGB rgb, double opacity)
 {
     color = HtmlFontColor(rgb, opacity);
 
@@ -132,12 +132,12 @@ HtmlFont::HtmlFont(GfxFont *font, int _size, GfxRGB rgb, double opacity)
     bold = false;
     rotOrSkewed = false;
 
-    if (font->isBold() || font->getWeight() >= GfxFont::W700)
+    if (font.isBold() || font.getWeight() >= GfxFont::W700)
         bold = true;
-    if (font->isItalic())
+    if (font.isItalic())
         italic = true;
 
-    if (const GooString *fontname = font->getName()) {
+    if (const GooString *fontname = font.getName()) {
         FontName = new GooString(fontname);
 
         GooString fontnameLower(fontname);
diff --git a/utils/HtmlFonts.h b/utils/HtmlFonts.h
index cc5cc2f2..21fb6c35 100644
--- a/utils/HtmlFonts.h
+++ b/utils/HtmlFonts.h
@@ -84,7 +84,7 @@ private:
     HtmlFontColor color;
     double rotSkewMat[4]; // only four values needed for rotation and skew
 public:
-    HtmlFont(GfxFont *font, int _size, GfxRGB rgb, double opacity);
+    HtmlFont(const GfxFont &font, int _size, GfxRGB rgb, double opacity);
     HtmlFont(const HtmlFont &x);
     HtmlFont &operator=(const HtmlFont &x);
     HtmlFontColor getColor() const { return color; }
diff --git a/utils/HtmlOutputDev.cc b/utils/HtmlOutputDev.cc
index 668ec0ca..28ec64a8 100644
--- a/utils/HtmlOutputDev.cc
+++ b/utils/HtmlOutputDev.cc
@@ -172,11 +172,10 @@ static const char *print_uni_str(const Unicode *u, const unsigned uLen)
 
 HtmlString::HtmlString(GfxState *state, double fontSize, HtmlFontAccu *_fonts) : fonts(_fonts)
 {
-    GfxFont *font;
     double x, y;
 
     state->transform(state->getCurX(), state->getCurY(), &x, &y);
-    if ((font = state->getFont())) {
+    if (std::shared_ptr<const GfxFont> font = state->getFont()) {
         double ascent = font->getAscent();
         double descent = font->getDescent();
         if (ascent > 1.05) {
@@ -191,7 +190,7 @@ HtmlString::HtmlString(GfxState *state, double fontSize, HtmlFontAccu *_fonts) :
         yMax = y - descent * fontSize;
         GfxRGB rgb;
         state->getFillRGB(&rgb);
-        HtmlFont hfont = HtmlFont(font, static_cast<int>(fontSize), rgb, state->getFillOpacity());
+        HtmlFont hfont = HtmlFont(*font, static_cast<int>(fontSize), rgb, state->getFillOpacity());
         if (isMatRotOrSkew(state->getTextMat())) {
             double normalizedMatrix[4];
             memcpy(normalizedMatrix, state->getTextMat(), sizeof(normalizedMatrix));
@@ -306,14 +305,14 @@ HtmlPage::~HtmlPage()
 
 void HtmlPage::updateFont(GfxState *state)
 {
-    GfxFont *font;
     const char *name;
     int code;
     double w;
 
     // adjust the font size
     fontSize = state->getTransformedFontSize();
-    if ((font = state->getFont()) && font->getType() == fontType3) {
+    const GfxFont *const font = state->getFont().get();
+    if (font && font->getType() == fontType3) {
         // This is a hack which makes it possible to deal with some Type 3
         // fonts.  The problem is that it's impossible to know what the
         // base coordinate system used in the font is without actually


More information about the poppler mailing list