mono / libgdiplus

C-based implementation of the GDI+ API
http://www.mono-project.com/
MIT License
334 stars 171 forks source link

Drawing (Images, Font) issues with mono 6.8.105 and libgdiplus 6.0.4 #626

Open g0ldi opened 4 years ago

g0ldi commented 4 years ago

Steps to Reproduce

  1. Mono version 6.8.105 is installed (pkg: mono-complete)
  2. Compile this sample app source with msbuild mono_6.8_drawingissue.csproj
  3. libgdiplus version 6.0.4 is installed (pkg: libgdiplus=6.0.4-0xamarin1+debian9b1)
  4. Start the application mono_drawingissue.exe (see attached screenshots)
  5. Downgrade libgdiplus to version 5.6 (pkg: libgdiplus=5.6-0xamarin5+debian9b1)
  6. Start again the application mono_drawingissue.exe (see attached screenshots)
  7. Notice the difference between the application even it's the same appliacation.

Current Behavior

Note: Issue can be observed/reproduced with mono version 6.8.96 and 6.8.105.

Mono 6.8.105 with libgdiplus 6.0.4-0xamarin1+debian9b1

With the packages specified in the header the

Screenshots

Mono 6.8.105 with libgdiplus 5.6-0xamarin5+debian9b1

Screenshots

Expected Behavior

The application draws the controls when it is loaded with mono 6.8.105 using the latest available libgdiplus (=6.0.4-0xamarin1+debian9b1) version. The application (from drawing perspective) should be identical, like with the older libgdiplus (=5.6-0xamarin5+debian9b1) version.

On which platforms did you notice this

[ ] macOS [x] Linux: Issue is observed on debian stretch 9.6 & 9.11 (arch: amd64 and armhf) [ ] Windows

Version Used:

Mono JIT compiler version 6.8.0.105 (tarball Tue Feb 4 21:19:49 UTC 2020) Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com TLS: __thread SIGSEGV: altstack Notifications: epoll Architecture: amd64 Disabled: none Misc: softdebug Interpreter: yes LLVM: yes(610) Suspend: hybrid GC: sgen (concurrent by default)

Package: libgdiplus Version: 6.0.4-0xamarin1+debian9b1 Priority: optional Section: libs Maintainer: Debian Mono Group pkg-mono-group@lists.alioth.debian.org Installed-Size: 535 kB Depends: libc6 (>= 2.14), libcairo2 (>= 1.10.0), libexif12 (>= 0.6.21-1~), libfontconfig1 (>= 2.11), libfreetype6 (>= 2.2.1), libgif7 (>= 5.1), libglib2.0-0 (>= 2.31.8), libjpeg62-turbo (>= 1.3.1), libpng16-16 (>= 1.6.2-1), libtiff5 (>= 4.0.3), libx11-6 Homepage: http://www.mono-project.com/Libgdiplus Download-Size: 161 kB APT-Manual-Installed: yes APT-Sources: https://download.mono-project.com/repo/debian stable-stretch/main amd64 Packages Description: interface library for System.Drawing of Mono This package contains a GDI+ API compatible implementation needed by the System.Drawing library of Mono.

marek-safar commented 4 years ago

This looks like a regression.

@filipnavara @akoeplinger any clues which change could cause that?

abossard commented 4 years ago

Hi everyone, I played around with the sample and it starts breaking with version 6.0.3. 6.0.2 renders fine, but then 6.0.3 is broken.

abossard commented 4 years ago

After going through commit by commit, this is the commit that introduces the broken rendering of the example: https://github.com/mono/libgdiplus/commit/398ad6de93a9b4140a209d9eae8ded9292ffc740

filipnavara commented 4 years ago

@abossard Thanks for doing the analysis. I suspected it would be that one. However, it also fixes quite a lot of issues. The hard part is actually narrowing down the problem to specific thing that is broken.

filipnavara commented 4 years ago

I suspect it is the same issue as https://github.com/mono/mono/issues/17493 which may be a bit easier to track down to specific code.

The libgdiplus library uses Cairo as the rendering backend. Unfortunately, the capabilities of the two libraries are different in terms of supported pixel formats for images. Historically this was handled incorrectly on many places where a conversion from PARGB format (R,G,B are premultiplied by the A value) to RGB (and/or back) was missing. This resulted in incorrect values being returned and some image transformations screwing up the output heavily when alpha value was used on pixels.

The patch introduced in https://github.com/mono/libgdiplus/commit/398ad6de93a9b4140a209d9eae8ded9292ffc740 tries to unify the approach a bit. If Cairo can handle the pixel format of an Image natively then they share the same pixel data in memory. If Cairo cannot handle it, however, then Cairo gets a converted copy of the image data and there are two parallel copies of the image data. Only the one handled in Cairo is considered valid at that point and it is the one with up-to-date data. Bugs like this one usually happen because either a) some drawing operations are not flushed correctly to the Cairo surface b) the stale non-converted copy of the image is used instead of the Cairo surface, or c) the Cairo surface is destroyed and the updated contents are not converted back into the original buffer in original pixel format.

If someone manages to reproduce the issue with pure System.Drawing or libgdiplus code I will be more than happy to try debugging it. Unfortunately stripping all the WinForms layers of code from the repro code proved to be quite time consuming.

abossard commented 4 years ago

Thanks for the insights, @filipnavara. I don't really know System.Drawing or libgdiplus myself, but I'll try to dig deeper into it in the next days.

I noticed that if I reduce the image height by e.g. 20px, it starts working: Screenshot from 2020-02-19 17-20-46

abossard commented 4 years ago

I started to investigate the font style issue, it appears that when using WinForms on Linux, the font style is not applied properly due to this commit https://github.com/mono/libgdiplus/commit/2f45a7d6382bce9e1cee11a7c06772e6727d99ae

If I revert this commit e.g. on master, it render the font correctly with bold. But it makes the tests fail on some platforms

filipnavara commented 4 years ago

@abossard IIRC the reason to copy the FC font pattern was to preserve FC_FILE (and possibly FC_INDEX) from the original font.

filipnavara commented 4 years ago

I tried to reproduce the issue on Ubunutu 18.04 running on WSL w/ VcXsrv as the X server and it rendered just fine:

image

Mono version:

filipnavara@DESKTOP-LFCAJ64:~/mo$ mono --version
Mono JIT compiler version 6.8.0.105 (tarball Tue Feb  4 21:20:20 UTC 2020)
Copyright (C) 2002-2014 Novell, Inc, Xamarin Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       altstack
        Notifications: epoll
        Architecture:  amd64
        Disabled:      none
        Misc:          softdebug
        Interpreter:   yes
        LLVM:          yes(610)
        Suspend:       hybrid
        GC:            sgen (concurrent by default)

libgdiplus version:

libgdiplus=6.0.4-0xamarin1+ubuntu1804b1
filipnavara commented 4 years ago

Should be fixed by https://github.com/mono/mono/pull/19460.

engrch commented 3 years ago

Theses issues still exist on Debian (stretch) with LightDm:

Mono: 6.12 libgdiplus: 6.0.5

1) Image Missing: Reproducible when the Image is larger than the canvas. I reproduced the error; on all mono versions.

2) Font issue: the font Arial Bold is not displayed

filipnavara commented 3 years ago

Mono 6.12 was branched as 2020-02 and doesn't contain the fix linked above.

engrch commented 3 years ago

@filipnavara Thanks for pointing that out.

I built the latest mono from master and I can confirm that: 1) Image Missing: Resolved 2) Font issue: this is not resolved

Debian with LightDM Mono: Built from master libgdiplus: 6.0.5-0xamarin1+debian9b1

kd2var commented 1 week ago

Is there any update on resolving this issue? I’m still having it with mono 6.12 and libgdiplus 6.1. But only in Linux Mint 22. It worked fine on my previous Linux Mint 21.3 and I have no issues on my Raspberry Pi.