Skip to content

CairoFontEngine: improve type3 font rendering

Hi, happy easter to all :)

I'm on Ubuntu 20.04. I had a few PDFs documents (very few docs show these problems, only a few newer statements from an insurance company) that quite a long time to display (more than 5s). I noticed that a few months earlier already on another document, but I was working a lot on these PDFs, so I got very annoyed and decided to rebuild evince to have a look.

During rendering time, I was mostly stuck in that backtrace :

Thread 6 (Thread 0x7fffe3fff700 (LWP 3115624)): #0 0x00007ffff03c9098 in cmsReverseToneCurveEx () at /lib/x86_64-linux-gnu/liblcms2.so.2 #1 0x00007ffff03d1377 in _cmsReadOutputLUT () at /lib/x86_64-linux-gnu/liblcms2.so.2 #2 0x00007ffff03c599d in () at /lib/x86_64-linux-gnu/liblcms2.so.2 #3 0x00007ffff03e0cf1 in cmsCreateExtendedTransform () at /lib/x86_64-linux-gnu/liblcms2.so.2 #4 0x00007ffff03e11c8 in cmsCreateMultiprofileTransformTHR () at /lib/x86_64-linux-gnu/liblcms2.so.2 #5 0x00007ffff03e12f3 in cmsCreateTransformTHR () at /lib/x86_64-linux-gnu/liblcms2.so.2 #6 0x00007ffff03e1355 in cmsCreateTransform () at /lib/x86_64-linux-gnu/liblcms2.so.2 #7 0x00007fffe34e58ab in GfxState::setDisplayProfile(std::shared_ptr<void> const&) (this=0x7fffd80e1b00, localDisplayProfileA=std::shared_ptr<void> (use count 2, weak count 0) = {...}) at /home/fred/ema ilsmart/poppler/poppler/GfxState.cc:6741 #8 0x00007fffe3491265 in Gfx::initDisplayProfile() (this=0x7fffd8140a80) at /home/fred/poppler/poppler/Gfx.cc:593 #9 0x00007fffe349102d in Gfx::Gfx(PDFDoc*, OutputDev*, Dict*, PDFRectangle const*, PDFRectangle const*, bool (*)(void*), void*, Gfx*) (this=0x7fffd8140a80, docA=0x7fffd8001360, outA=0x7fffd80c5000, resD ict=0x0, box=0x7fffe3ffc5b0, cropBox=0x0, abortCheckCbkA=0x0, abortCheckCbkDataA=0x0, gfxA=0x0) at /home/fred/poppler/poppler/Gfx.cc:569 #10 0x00007ffff059de2d in _render_type3_glyph(cairo_scaled_font_t*, unsigned long, cairo_t*, cairo_text_extents_t*, bool) (scaled_font=0x7fffd82542f0, glyph=12, cr=0x555555d50a00, metrics=0x7fffe3ffc6d0, color=false) at /home/fred/poppler/poppler/CairoFontEngine.cc:568 #11 0x00007ffff059e1ec in _render_type3_noncolor_glyph(cairo_scaled_font_t*, unsigned long, cairo_t*, cairo_text_extents_t*) (scaled_font=0x7fffd82542f0, glyph=12, cr=0x555555d50a00, metrics=0x7fffe3ffc6 d0) at /home/fred/poppler/poppler/CairoFontEngine.cc:610 #12 0x00007ffff70a14d6 in () at /lib/x86_64-linux-gnu/libcairo.so.2 #13 0x00007ffff708653f in () at /lib/x86_64-linux-gnu/libcairo.so.2 #14 0x00007ffff70874c0 in () at /lib/x86_64-linux-gnu/libcairo.so.2 #15 0x00007ffff7044d13 in () at /lib/x86_64-linux-gnu/libcairo.so.2 #16 0x00007ffff7045344 in () at /lib/x86_64-linux-gnu/libcairo.so.2 #17 0x00007ffff7057199 in () at /lib/x86_64-linux-gnu/libcairo.so.2 #18 0x00007ffff7096b8d in () at /lib/x86_64-linux-gnu/libcairo.so.2 #19 0x00007ffff704e712 in () at /lib/x86_64-linux-gnu/libcairo.so.2 #20 0x00007ffff70a37d6 in cairo_show_glyphs () at /lib/x86_64-linux-gnu/libcairo.so.2 #21 0x00007ffff05a7050 in CairoOutputDev::endString(GfxState*) (this=0x7fffd8044280, state=0x7fffd80e1790) at /home/fred/poppler/poppler/CairoOutputDev.cc:1487 #22 0x00007fffe34a5724 in Gfx::doShowText(GooString const*) (this=0x7fffd8140bb0, s=0x7fffd81d74d0) at /home/fred/poppler/poppler/Gfx.cc:4042 #23 0x00007fffe34a3922 in Gfx::opMoveShowText(Object*, int) (this=0x7fffd8140bb0, args=0x7fffe3ffe5f0, numArgs=1) at /home/fred/poppler/poppler/Gfx.cc:3753 #24 0x00007fffe34920b6 in Gfx::execOp(Object*, Object*, int) (this=0x7fffd8140bb0, cmd=0x7fffe3ffe5a0, args=0x7fffe3ffe5f0, numArgs=1) at /home/fred/poppler/poppler/Gfx.cc:809 #25 0x00007fffe34918c6 in Gfx::go(bool) (this=0x7fffd8140bb0, topLevel=true) at /home/fred/poppler/poppler/Gfx.cc:684 #26 0x00007fffe34915fa in Gfx::display(Object*, bool) (this=0x7fffd8140bb0, obj=0x7fffe3ffe940, topLevel=true) at /home/fred/poppler/poppler/Gfx.cc:645 #27 0x00007fffe3539868 in Page::displaySlice(OutputDev*, double, double, int, bool, bool, int, int, int, int, bool, bool (*)(void*), void*, bool (*)(Annot*, void*), void*, bool) (this=0x7fffd80406c0, out =0x7fffd8044280, hDPI=72, vDPI=72, rotate=0, useMediaBox=false, crop=true, sliceX=-1, sliceY=-1, sliceW=-1, sliceH=-1, printing=false, abortCheckCbk=0x0, abortCheckCbkData=0x0, annotDisplayDecideCbk=0x0, annotDisplayDecideCbkData=0x0, copyXRef=false) at /home/fred/poppler/poppler/Page.cc:575 #28 0x00007ffff057eaf9 in _poppler_page_render(PopplerPage*, cairo_t*, bool, PopplerPrintFlags) (page=0x555555daeb80, cairo=0x555555e61780, printing=false, print_flags=POPPLER_PRINT_DOCUMENT) at /home/fr ed/poppler/glib/poppler-page.cc:331 #29 0x00007ffff057ec07 in poppler_page_render(PopplerPage*, cairo_t*) (page=0x555555daeb80, cairo=0x555555e61780) at /home/fred/poppler/glib/poppler-page.cc:356 #30 0x00007ffff105d541 in pdf_page_render (page=page@entry=0x555555daeb80, width=1250, height=1768, rc=rc@entry=0x7fffd8043c00) at ../backend/pdf/ev-poppler.c:431 #31 0x00007ffff105d787 in pdf_document_render (document=<optimised out>, rc=0x7fffd8043c00) at ../backend/pdf/ev-poppler.c:457 #32 0x00007ffff7ed246c in ev_job_render_run (job=0x555555daf3c0) at ../libview/ev-jobs.c:645 #33 0x00007ffff7ed50fa in ev_job_thread (job=0x555555daf3c0) at ../libview/ev-job-scheduler.c:184 #34 ev_job_thread_proxy (data=<optimised out>) at ../libview/ev-job-scheduler.c:217 #35 0x00007ffff7cedad1 in () at /lib/x86_64-linux-gnu/libglib-2.0.so.0 #36 0x00007ffff6e52609 in start_thread (arg=<optimised out>) at pthread_create.c:477

So I decided to see if it was possible to improve by caching this Gfx::Gfx instance from _render_type3_glyph.

Looking at the APIs, I quickly tried to cache the instance at the CairoFontEngine level, to see if this would improve anything. It turned out that the PDFs that took a few seconds to render now display instantly.

I'm unfortunately not very keen to attach don't the problematic PDF on the issue, but I could share one with anyone interested to integrate it. Or maybe there is a tool that could help me to micro patch this PDF (like dumping PDF structure in a human-readable way, patch it, and build it back again to nearly the same PDF).

Let me know also if there is an issue with the formatting.

Regards,

Merge request reports