Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.
/ corefx Public archive

Add support for System.Drawing on Windows. #20593

Merged
merged 1 commit into from Jun 5, 2017

Conversation

mellinoe
Copy link
Contributor

@mellinoe mellinoe commented Jun 1, 2017

This change adds a new library, System.Drawing.Common, which supports a large subset of the System.Drawing API. It is a direct port of the code from the .NET Framework codebase. The code has been cleaned, formatted, and sanitized to match the code style of corefx, but is otherwise very
similar to the .NET Framework version. There are a few key differences:

  • TypeConverter's have been omitted for now. If we want to add these to .NET Core, we should add them to the TypeConverter library, rather than System.Drawing.Common itself. Note that there's already a few TypeConverter's for the types that are in System.Drawing.Primitives.
  • Some parts of the library do not respond to "System Events", because they are not yet implemented in .NET Core. This means that fonts and colors will not automatically update when the system defaults change, as they do in .NET Framework. The code is still there, but behind the feature flag "FEATURE_SYSTEM_EVENTS".
  • Various attributes have been removed from the codebase, because they are no longer applicable. Examples:
    • Designer-related attributes (DefaultProperty, DefaultEvent, Editor, etc.)
    • CAS-related attributes. CAS-related method calls (Security demands and asserts) have also been removed.

There is still further cleanup that can be done in order to match the style and structure of corefx. For example, the interop code should be reorganized to match other BCL libraries.

NOTE: This implementation will only work on Windows, and not in UWP. This is a strictly compatibility-driven feature. Any changes made to it should not significantly diverge from the .NET Framework implementation. Libraries should only take a dependency on System.Drawing.Common if they
are relying on legacy components from .NET Framework; newly-written code and features should rely on modern alternatives.

This change adds a new library, System.Drawing.Common, which supports a
large subset of the System.Drawing API. It is a direct port of the code
from the .NET Framework codebase. The code has been cleaned, formatted,
and sanitized to match the code style of corefx, but is otherwise very
similar to the .NET Framework version. There are a few key differences:

* TypeConverter's have been omitted for now. If we want to add these to
  .NET Core, we should add them to the TypeConverter library, rather than
  System.Drawing.Common itself.
* Some parts of the library do not respond to "System Events", because
  they are not yet implemented in .NET Core. This means that fonts and
  colors will not automatically update when the system defaults change,
  as they do in .NET Framework. The code is still there, but behind the
  feature flag "FEATURE_SYSTEM_EVENTS".
* Various attributes have been removed from the codebase, because they are
  no longer applicable. Examples:
  * Designer-related attributes (DefaultProperty, DefaultEvent, Editor,
    etc.)
  * CAS-related attributes. CAS-related method calls (Security demands and
    asserts) have also been removed.

There is still further cleanup that can be done in order to match the
style and structure of corefx. For example, the Interop code should be
reorganized to match other BCL libraries.

NOTE: This implementation will only work on Windows, and not in UWP. This
is a strictly compatibility-driven feature. Any changes made to it should
not significantly diverge from the .NET Framework implementation.
Libraries should only take a dependency on System.Drawing.Common if they
are relying on legacy components from .NET Framework; newly-written code
and features should rely on modern alternatives.
@stephentoub
Copy link
Member

Thanks, @mellinoe. What kind of / level of code review are you looking for on this?

@mellinoe
Copy link
Contributor Author

mellinoe commented Jun 1, 2017

@stephentoub I think there's a few things I'd like to accomplish before being "ready to merge":

  • Make sure the build configurations are specified correctly for System.Drawing.Common.
  • Make sure that .NET Framework code built against System.Drawing will work / type-forward correctly with this new library. This needs a shim project to be configured (I think).
  • Finalize a list of code style and refactoring work items that should be done as a follow-up. I just spent a couple full days getting to this state, but this code is very old and could still use some more work. I've compiled a list as I worked, but I'm sure that I've not caught everything that needs fixed.

@karelz karelz added this to the 2.1.0 milestone Jun 2, 2017
@danmoseley
Copy link
Member

@mellinoe what is your test strategy? Does Mono have much we can reuse? Have you taken a look at what Desktop has?

@mellinoe
Copy link
Contributor Author

mellinoe commented Jun 2, 2017

@danmosemsft Yes, mono has tests that we will re-use. .NET Framework does not have great test assets -- they are mainly for higher-level components like WinForms which indirectly test System.Drawing.

@hughbe
Copy link

hughbe commented Jun 5, 2017

I could look in to adding/porting some Mono tests if you're not doing so already

/// </devdoc>
Manual = SafeNativeMethods.DMBIN_MANUAL,

/// <include file='doc\PaperSourceKind.uex' path='docs/doc[@for="PaperSourceKind.Envelope"]/*' />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we usually have doc-comments like this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We don't. Cleaning these up is on my list of follow-up items, which I'll make sure to file tomorrow. Unfortunately, this style of comment is pretty common in our .NET Framework codebase; I'm not even sure what the names and paths refer to.

@mellinoe
Copy link
Contributor Author

mellinoe commented Jun 5, 2017

I could look in to adding/porting some Mono tests if you're not doing so already

Sounds great; I could definitely use some help with that. I ported a select few test cases and tried running them against the implementation here, but there's still a ton of work to be done there. Porting from Nunit to Xunit was fairly annoying and time-consuming, and after that there were still minor differences that caused lots of tests to fail. I will file another issue tomorrow about this so we can try to plan it out and split up the work.

@mellinoe
Copy link
Contributor Author

mellinoe commented Jun 5, 2017

Merging this in now. I've filed several follow-up issues for further System.Drawing work:

@mellinoe mellinoe merged commit e15746e into dotnet:master Jun 5, 2017
@@ -7,7 +7,7 @@
namespace System.Drawing
{
[SuppressMessage("Microsoft.Design", "CA1008:EnumsShouldHaveZeroValue")]
internal enum KnownColor
public enum KnownColor
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding this as a public type in System.Drawing.Primitives is going to cause issues with netstandard. In particular currently the NETStandard.Library contains a shim for System.Drawing.Primitives so at a minimum we need to bump the minor version of System.Drawing.Primitives to ensure folks targeting .NET Core will get the later version.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(assuming we haven't already bumped the minor version, I didn't verify)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't bumped the minor version; will do.

<Reference Include="System.Runtime.InteropServices" />
<Reference Include="System.ComponentModel" />
<Reference Include="System.ComponentModel.Primitives" />
<Reference Include="System.Security.Permissions" />
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should try to avoid depending on System.Security.Permissions.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mellinoe looks like it's needed for two things -- a bunch of use of CAS types, which we should just rip out; and definition of PrintingPermission/PPAttribute, which is already in S.S.Permissions and we should just rip out. perhaps you could open an issue to do this, and remove this reference?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cleaning up the unnecessary permissions stuff is on my list. I will track removing this reference entirely, as well. https://github.com/dotnet/corefx/issues/20706

<Import Project="..\dir.props" />
<PropertyGroup>
<AssemblyVersion>4.1.0.0</AssemblyVersion>
<AssemblyKey>MSFT</AssemblyKey>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use the Open key for new libraries like this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will change.

@weshaggard
Copy link
Member

@mellinoe do you also need follow-up items to enable packaging for this library when it is ready?

@mellinoe
Copy link
Contributor Author

mellinoe commented Jun 6, 2017

@mellinoe do you also need follow-up items to enable packaging for this library when it is ready?
Delete branch

@weshaggard I'll file an issue to track that explicitly.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
7 participants