dotnet / dotnet/announcements

`System.Drawing.Common` will only be supported on Windows

Open
#228 0 comments 0 reactions 0 assignees View on GitHub
.NET 6.0 Breaking Change Linux macOS
Dominant language
No language data
Stars
1.4k
Forks
53
PR merge metrics
No merged PRs in 30d

Description

> This issue is a locked mirror of https://github.com/dotnet/designs/pull/234. See that issue for discussion.

***Note:** This is a re-post of a design point we already discussed and shipped in .NET 6. I'm posting this here because (1) some people have tried to find it here and (2) some folks have never heard of it.*

Moving forward, `System.Drawing.Windows` will only be supported on Windows. The library is marked as Windows-only (which results in build warnings when used from cross-platform code) and will throw by default when used from a non-Windows OS. For the time being, there is a runtime switch that enables users to still carry and use their own copy of `libgdiplus`. We intend to remove this functionality eventually as well.

## Details

In the .NET Core 2.x days we created the `Microsoft.Windows.Compatibility` package which exposes many Windows-only APIs so that more people can migrate to .NET Core. As part of this, we also ported `System.Drawing.Common`. This was mainly meant for .NET Core users that still target Windows, however since Mono already had a cross-platform implementation, we decided to bring that over. The cross-platform functionality is provided via the native library `libgdiplus`. Sadly, `libgdiplus` is a community supported library and at this point effectively unmaintained.

While `libgdiplus` has helped a lot of customers expand to cross-platform it has also caused some headaches. `System.Drawing.Common` is very Windows driven as it is mostly a wrapper around GDI+ and is heavily coupled to Windows Forms, which keeps evolving and diverging from cross-platform graphics. This has caused some confusion over why some things don't work well on Unix or don't work at all.

The cross-platform implementation of `System.Drawing.Common` is mainly provided on the native side, via `libgdiplus`. It's effectively a re-implementation of the parts of Windows that `System.Drawing.Common` is depending on. As you can imagine, that makes `libgdiplus` a very non-trivial component. It's around 30k lines of pretty old C code, virtually untested, and lacks a lot of functionality. `libgdiplus` also has a lot of external dependencies for all the image processing and text rendering, such as `cairo`, `pango`, and other native libraries, which makes maintaining and shipping it even more challenging.

Since `System.Drawing.Common` was really designed to be a thin wrapper over Windows technologies, its cross-platform implementation is a bit like a square peg in a round hole; it's subpar because it was only designed with Windows in mind.

Since the inclusion of the Mono cross-platform implementation we spent lot of time redirecting issues to `libgdiplus` that never got fixed, or helping people install `libgdiplus` correctly (because it's not part of .NET Core proper). This is very different from other external dependencies we have taken, for example, `icu` or `openssl`, which are high-quality libraries, rather than poorly maintained re-implementation of Windows components. Thus, we have come to believe that it's not viable to get `libgdiplus` to the point where its feature set and quality is on par with the rest of the .NET stack.

We have noticed (such as from analysis of NuGet packages) that `System.Drawing.Common` is used on cross-platform mostly for image manipulation like QR code generators and text rendering. We haven't noticed heavy graphics usage as our cross-platform graphics support is very incomplete. For example, right now some components crash on macOS because the native APIs we use have been deprecated and are no longer included with recent macOS releases. We have never gotten a report about that crash; we discovered it ourselves while making `System.Drawing.Common` trim compatible.

The usages we see of `System.Drawing.Common` in non-Windows environments are typically well supported with `SkiaSharp` and `ImageSharp`.

Thus, we believe it is not worth investing in making `System.Drawing.Common` work on non-Windows platforms and instead propose we only keep evolving it in the context of Windows Forms and GDI+.

## Design Approach

For more details on the design approach, see [this design document](https://github.com/dotnet/designs/pull/234/files?short_path=5a79205#diff-5a79205cd271d8ec2d3c5d74112f6874998e1e1aa7ee00900db727eef25561d8).

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.