Bug 99569 - Rendered EMF+ has low DPI when zoomed and printed
Summary: Rendered EMF+ has low DPI when zoomed and printed
Alias: None
Product: LibreOffice
Classification: Unclassified
Component: filters and storage (show other bugs)
(earliest affected)
Hardware: All All
: medium minor
Assignee: Not Assigned
Depends on:
Blocks: EMF-WMF
  Show dependency treegraph
Reported: 2016-04-29 10:19 UTC by aptitude
Modified: 2017-10-22 08:14 UTC (History)
4 users (show)

See Also:
Crash report or crash signature:

Screen showing the low dpi for rendered image (111.19 KB, image/png)
2016-04-29 10:19 UTC, aptitude
The example emf+ file that can be used to replicate the error (22.97 KB, image/emf)
2016-04-29 10:20 UTC, aptitude

Note You need to log in before you can comment on or make changes to this bug.
Description aptitude 2016-04-29 10:19:50 UTC
Created attachment 124721 [details]
Screen showing the low dpi for rendered image

I have been investigating why certain EMF files containing text are rendered at a low resolution in LibreOffice Draw when printing or magnified(zoom) to 400%

For example: Attached libre.png (using attached Template.emf )

Note, this example file does display correctly by setting the "EMF_PLUS_DISABLE" environment variable. 
This is because the "Template.emf" "EMF" records contains the text drawing, and the "EMF+" records do not display anything important.
Of course, ideally we should not need to set this environment variable

If "EMF+" is detected in EnhWMFReader::ReadEnhWMF(), then a different code path is used and the "EMF" is rendered to a bitmap at the incorrect DPI, then drawn to the screen.

So when "EMF_PLUS_DISABLE" is set:
At https://cgit.freedesktop.org/libreoffice/core/tree/vcl/source/filter/wmf/enhwmf.cxx#n621 EnhWMFReader::ReadEnhWMF() Renders the EMF directly to WinMtfOutput (pOut), and ignores EMF+

When "EMF_PLUS_DISABLE" is not set:
At https://cgit.freedesktop.org/libreoffice/core/tree/vcl/source/filter/wmf/enhwmf.cxx#n621 EnhWMFReader::ReadEnhWMF() Detects EMF+ using the signature in EMR_GDICOMMENT (the value 0x2B464D45, which is the ASCII string "+FME)

If detected, this is where it gets complex.
EnhWMFReader::ReadEnhWMF() only processes EMR_GDICOMMENT's (i.e. No longer does any drawing)
    1. Creates a header MetaCommentAction( "EMF_PLUS_HEADER_INFO" )
    2. Creates the body MetaCommentAction( "EMF_PLUS" )

The drawing layer eventually calls GDIMetaFile::Play and creates a bitmap to render to in GDIMetaFile::ImplPlayWithRenderer() https://cgit.freedesktop.org/libreoffice/core/tree/vcl/source/gdi/gdimtf.cxx#n383

This leads to ImplRenderer::processEMFPlus() ( https://cgit.freedesktop.org/libreoffice/core/tree/cppcanvas/source/mtfrenderer/emfplus.cxx#n1811 ) Which processes the EMF+ commands Notice, this code is in cppcanvas (not vcl)

Still within GDIMetaFile::Play, EnhWMFReader::ReadEnhWMF() is called. The EMF still may contain nested EMF+ data (treated as above). When no EMF+ data exists, the standard EMF is drawn.

I am confused why we do it this way. There must have been a reason place the EMF+ code in cppcanvas (i.e. not alongside the EMF). I cannot understand why each layer is drawn to a different bitmap (also why it's the incorrect DPI)

There is a lot of good code there, and probably fragile. imho, it's risky moving EMF+ out of cppcanvas, and not something that I would want to attempt.

The easy fix would be to fix the DPI setting, however I cannot find where the error is.

Comment 1 aptitude 2016-04-29 10:20:56 UTC
Created attachment 124722 [details]
The example emf+ file that can be used to replicate the error
Comment 2 Buovjaga 2016-05-06 13:31:53 UTC

Arch Linux 64-bit, KDE Plasma 5
Build ID: 540fee2dc7553152914f7f1d8a41921e765087ef
CPU Threads: 8; OS Version: Linux 4.5; UI Render: default; 
Locale: fi-FI (fi_FI.UTF-8)
Built on April 30th 2016
Comment 3 aptitude 2016-05-10 14:32:18 UTC
This bug can be explained by the comments in vcl/README

Look at the "== EMF+ ==" section
Comment 4 aptitude 2016-05-26 08:23:35 UTC Comment hidden (obsolete)
Comment 5 Xisco Faulí 2017-07-13 09:57:39 UTC Comment hidden (obsolete)
Comment 6 aptitude 2017-07-13 11:01:52 UTC Comment hidden (obsolete)
Comment 7 Timur 2017-08-29 09:59:34 UTC
Not fixed with new EMF+. This looks like WMF file to me.
Comment 8 Patrick Jaap 2017-10-18 08:50:47 UTC
Hi, I can confirm this bug is fixed in current master with commit

"tdf#31814 Fix for EMF+ DrawString and DrawImage"

The text is stored in a "DrawImage" record which was rendered as a Bitmap. This is fixed now: It is rendered as a VectorGraphic (Metafile) and therefore rendered in high resolution!
Comment 9 Xisco Faulí 2017-10-18 08:54:54 UTC
Verified in

Build ID: 5ea1b4c336d1cad92dc18e7cf7e4b381396f448b
CPU threads: 4; OS: Linux 4.10; UI render: default; VCL: gtk3; 
Locale: ca-ES (ca_ES.UTF-8); Calc: group