diff --git a/.github/policies/resourceManagement.yml b/.github/policies/resourceManagement.yml
index 4723b0d28e9..4f48c6ed37f 100644
--- a/.github/policies/resourceManagement.yml
+++ b/.github/policies/resourceManagement.yml
@@ -194,7 +194,7 @@ configuration:
isRegex: False
then:
- addMilestone:
- milestone: 9.0 Preview2
+ milestone: 9.0 Preview3
description: Apply milestone to PRs on the main branch
triggerOnOwnActions: true
- if:
diff --git a/Winforms.sln b/Winforms.sln
index 7dc72d4753d..2d53b291607 100644
--- a/Winforms.sln
+++ b/Winforms.sln
@@ -171,6 +171,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "eng", "eng", "{8B4B1E09-B3C
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ScratchProjectWithInternals", "src\System.Windows.Forms\tests\IntegrationTests\ScratchProjectWithInternals\ScratchProjectWithInternals.csproj", "{522EBAB3-E4D2-45F3-ACBD-B25FC457BF78}"
EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ComDisabled.Tests", "src\System.Windows.Forms\tests\ComDisabledTests\ComDisabled.Tests.csproj", "{55F3174F-C1FE-4C8F-AF71-2512630088F8}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -943,6 +945,22 @@ Global
{522EBAB3-E4D2-45F3-ACBD-B25FC457BF78}.Release|x64.Build.0 = Release|Any CPU
{522EBAB3-E4D2-45F3-ACBD-B25FC457BF78}.Release|x86.ActiveCfg = Release|Any CPU
{522EBAB3-E4D2-45F3-ACBD-B25FC457BF78}.Release|x86.Build.0 = Release|Any CPU
+ {55F3174F-C1FE-4C8F-AF71-2512630088F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {55F3174F-C1FE-4C8F-AF71-2512630088F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {55F3174F-C1FE-4C8F-AF71-2512630088F8}.Debug|arm64.ActiveCfg = Debug|Any CPU
+ {55F3174F-C1FE-4C8F-AF71-2512630088F8}.Debug|arm64.Build.0 = Debug|Any CPU
+ {55F3174F-C1FE-4C8F-AF71-2512630088F8}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {55F3174F-C1FE-4C8F-AF71-2512630088F8}.Debug|x64.Build.0 = Debug|Any CPU
+ {55F3174F-C1FE-4C8F-AF71-2512630088F8}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {55F3174F-C1FE-4C8F-AF71-2512630088F8}.Debug|x86.Build.0 = Debug|Any CPU
+ {55F3174F-C1FE-4C8F-AF71-2512630088F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {55F3174F-C1FE-4C8F-AF71-2512630088F8}.Release|Any CPU.Build.0 = Release|Any CPU
+ {55F3174F-C1FE-4C8F-AF71-2512630088F8}.Release|arm64.ActiveCfg = Release|Any CPU
+ {55F3174F-C1FE-4C8F-AF71-2512630088F8}.Release|arm64.Build.0 = Release|Any CPU
+ {55F3174F-C1FE-4C8F-AF71-2512630088F8}.Release|x64.ActiveCfg = Release|Any CPU
+ {55F3174F-C1FE-4C8F-AF71-2512630088F8}.Release|x64.Build.0 = Release|Any CPU
+ {55F3174F-C1FE-4C8F-AF71-2512630088F8}.Release|x86.ActiveCfg = Release|Any CPU
+ {55F3174F-C1FE-4C8F-AF71-2512630088F8}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -1004,6 +1022,7 @@ Global
{7650F24E-7132-42CF-ADCE-830C8DB26EE5} = {583F1292-AE8D-4511-B8D8-A81FE4642DDC}
{BA61D5A8-29E9-41AA-A3FA-B7F0A7F9A191} = {680FB14C-7B0C-4D63-9F1A-18ACCDB0F52A}
{61376D2A-4AD5-48F4-BF99-2BB630E21945} = {77FEDB47-F7F6-490D-AF7C-ABB4A9E0B9D7}
+ {55F3174F-C1FE-4C8F-AF71-2512630088F8} = {583F1292-AE8D-4511-B8D8-A81FE4642DDC}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {7B1B0433-F612-4E5A-BE7E-FCF5B9F6E136}
diff --git a/eng/Publishing.props b/eng/Publishing.props
index 10bc8c8684d..579a1360d90 100644
--- a/eng/Publishing.props
+++ b/eng/Publishing.props
@@ -2,5 +2,6 @@
3
+ true
diff --git a/eng/Version.Details.xml b/eng/Version.Details.xml
index bf529cff234..1d261204504 100644
--- a/eng/Version.Details.xml
+++ b/eng/Version.Details.xml
@@ -7,205 +7,205 @@ Note: if the Uri is a new place, you will need to add a subscription from that p
-->
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/runtime
- 963626276e11bf5587aaed69826b62682b05d9c4
+ c55c4d50793c878cc73ae6ca3335f2b6b3ccc8a4
-
+
https://github.com/dotnet/arcade
- c3f5cbfb2829795294f5c2d9fa5a0522f47e91fb
+ d5b02a4900c4d521cb48b8f0d7e3f28175268f7c
-
+
https://github.com/dotnet/arcade
- c3f5cbfb2829795294f5c2d9fa5a0522f47e91fb
+ d5b02a4900c4d521cb48b8f0d7e3f28175268f7c
-
+
https://github.com/dotnet/arcade
- c3f5cbfb2829795294f5c2d9fa5a0522f47e91fb
+ d5b02a4900c4d521cb48b8f0d7e3f28175268f7c
-
+
https://github.com/dotnet/arcade
- c3f5cbfb2829795294f5c2d9fa5a0522f47e91fb
+ d5b02a4900c4d521cb48b8f0d7e3f28175268f7c
-
+
https://github.com/dotnet/arcade
- c3f5cbfb2829795294f5c2d9fa5a0522f47e91fb
+ d5b02a4900c4d521cb48b8f0d7e3f28175268f7c
-
+
https://github.com/dotnet/arcade
- c3f5cbfb2829795294f5c2d9fa5a0522f47e91fb
+ d5b02a4900c4d521cb48b8f0d7e3f28175268f7c
diff --git a/eng/Versions.props b/eng/Versions.props
index a4f3844786c..433c557dcfa 100644
--- a/eng/Versions.props
+++ b/eng/Versions.props
@@ -6,7 +6,7 @@
0
preview
- 2
+ 3
$(MajorVersion).$(MinorVersion).$(PatchVersion)
false
@@ -15,35 +15,35 @@
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
5.0.0-preview.7.20320.5
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
6.0.0
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
- 9.0.0-preview.2.24115.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
+ 9.0.0-preview.3.24126.1
@@ -56,9 +56,9 @@
- 9.0.0-beta.24112.1
- 9.0.0-beta.24112.1
- 9.0.0-beta.24112.1
+ 9.0.0-beta.24114.1
+ 9.0.0-beta.24114.1
+ 9.0.0-beta.24114.1
17.4.0-preview-20220707-01
@@ -103,6 +103,7 @@
$(MicrosoftCodeAnalysisAnalyzersVersion)
8.0.0-preview.23327.3
1.2.0-beta.507
+ 6.3.4
diff --git a/global.json b/global.json
index eca3d4a3a5a..6656f05d51e 100644
--- a/global.json
+++ b/global.json
@@ -14,11 +14,11 @@
"version": "9.0.100-alpha.1.23618.3"
},
"msbuild-sdks": {
- "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24112.1",
- "Microsoft.DotNet.CMake.Sdk": "9.0.0-beta.24112.1",
- "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24112.1",
+ "Microsoft.DotNet.Arcade.Sdk": "9.0.0-beta.24114.1",
+ "Microsoft.DotNet.CMake.Sdk": "9.0.0-beta.24114.1",
+ "Microsoft.DotNet.Helix.Sdk": "9.0.0-beta.24114.1",
"FIX-85B6-MERGE-9C38-CONFLICT": "1.0.0",
- "Microsoft.NET.Sdk.IL": "9.0.0-preview.2.24115.1"
+ "Microsoft.NET.Sdk.IL": "9.0.0-preview.3.24126.1"
},
"native-tools": {
"cmake": "latest"
diff --git a/src/System.Design/src/System.Design.Forwards.cs b/src/System.Design/src/System.Design.Forwards.cs
index d804f92e945..87dda003697 100644
--- a/src/System.Design/src/System.Design.Forwards.cs
+++ b/src/System.Design/src/System.Design.Forwards.cs
@@ -9,6 +9,7 @@
[assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.ColumnHeaderCollectionEditor))]
[assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.DataMemberFieldConverter))]
[assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.DataGridViewCellStyleEditor))]
+[assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.DataGridViewColumnTypeEditor))]
[assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.DataSourceListEditor))]
[assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.FormatStringEditor))]
[assembly: TypeForwardedTo(typeof(System.Windows.Forms.Design.HelpNamespaceEditor))]
diff --git a/src/System.Drawing.Common/src/GlobalUsings.cs b/src/System.Drawing.Common/src/GlobalUsings.cs
index 9b5ed3dc48b..c7e6245d339 100644
--- a/src/System.Drawing.Common/src/GlobalUsings.cs
+++ b/src/System.Drawing.Common/src/GlobalUsings.cs
@@ -18,12 +18,15 @@
global using DashCap = System.Drawing.Drawing2D.DashCap;
global using DashStyle = System.Drawing.Drawing2D.DashStyle;
global using EmfPlusRecordType = System.Drawing.Imaging.EmfPlusRecordType;
+global using FillMode = System.Drawing.Drawing2D.FillMode;
global using ImageCodecInfo = System.Drawing.Imaging.ImageCodecInfo;
+global using ImageLockMode = System.Drawing.Imaging.ImageLockMode;
global using LineCap = System.Drawing.Drawing2D.LineCap;
global using LineJoin = System.Drawing.Drawing2D.LineJoin;
global using Matrix = System.Drawing.Drawing2D.Matrix;
global using MatrixOrder = System.Drawing.Drawing2D.MatrixOrder;
global using PenAlignment = System.Drawing.Drawing2D.PenAlignment;
+global using PixelFormat = System.Drawing.Imaging.PixelFormat;
global using PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode;
global using TextRenderingHint = System.Drawing.Text.TextRenderingHint;
diff --git a/src/System.Drawing.Common/src/NativeMethods.txt b/src/System.Drawing.Common/src/NativeMethods.txt
index 4b00a2ebc25..edb7b1421e7 100644
--- a/src/System.Drawing.Common/src/NativeMethods.txt
+++ b/src/System.Drawing.Common/src/NativeMethods.txt
@@ -55,10 +55,8 @@ GdipBeginContainer2
GdipBitmapApplyEffect
GdipBitmapConvertFormat
GdipBitmapGetPixel
-GdipBitmapLockBits
GdipBitmapSetPixel
GdipBitmapSetResolution
-GdipBitmapUnlockBits
GdipClearPathMarkers
GdipCloneBitmapArea
GdipCloneBitmapAreaI
@@ -250,7 +248,6 @@ GdipGetHatchForegroundColor
GdipGetHatchStyle
GdipGetHemfFromMetafile
GdipGetImageAttributesAdjustedPalette
-GdipGetImageBounds
GdipGetImageDecoders
GdipGetImageDecodersSize
GdipGetImageDimension
@@ -260,7 +257,6 @@ GdipGetImageHeight
GdipGetImageHorizontalResolution
GdipGetImagePalette
GdipGetImagePaletteSize
-GdipGetImagePixelFormat
GdipGetImageRawFormat
GdipGetImageThumbnail
GdipGetImageType
@@ -558,7 +554,7 @@ LevelsParams
PALETTEENTRY
PaletteFlags
PaletteType
-PixelFormat*
+PathPointType
PRINTER_ENUM_CONNECTIONS
PRINTER_ENUM_LOCAL
PRINTER_INFO_4W
diff --git a/src/System.Drawing.Common/src/Special/NotSupported.cs b/src/System.Drawing.Common/src/Special/NotSupported.cs
index c06f8032199..3dd33389543 100644
--- a/src/System.Drawing.Common/src/Special/NotSupported.cs
+++ b/src/System.Drawing.Common/src/Special/NotSupported.cs
@@ -5,7 +5,7 @@
// Changes to this file must follow the https://aka.ms/api-review process.
// ------------------------------------------------------------------------------
-#pragma warning disable CS8618,CS0169,CA1823,CA1066
+#pragma warning disable CS8618,CS0169,CA1725,CA1823,CA1066,IDE0001,IDE0002,IDE1006,IDE0034,IDE0044,IDE0051,IDE0055,IDE1006
namespace System.Drawing
{
@@ -3221,4 +3221,4 @@ public enum TextRenderingHint
}
}
-#pragma warning restore CS8618
+#pragma warning restore CS8618,CS0169,CA1725,CA1823,CA1066,IDE0001,IDE0002,IDE1006,IDE0034,IDE0044,IDE0051,IDE0055,IDE1006
diff --git a/src/System.Drawing.Common/src/System/Drawing/Bitmap.cs b/src/System.Drawing.Common/src/System/Drawing/Bitmap.cs
index 92f40ab43fd..3e2069f9cc5 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Bitmap.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Bitmap.cs
@@ -8,6 +8,7 @@
using System.Runtime.Versioning;
#endif
using System.IO;
+using System.Runtime.CompilerServices;
using System.Runtime.Serialization;
namespace System.Drawing;
@@ -15,7 +16,7 @@ namespace System.Drawing;
[Editor($"System.Drawing.Design.BitmapEditor, {AssemblyRef.SystemDrawingDesign}",
$"System.Drawing.Design.UITypeEditor, {AssemblyRef.SystemDrawing}")]
[Serializable]
-[Runtime.CompilerServices.TypeForwardedFrom(AssemblyRef.SystemDrawing)]
+[TypeForwardedFrom(AssemblyRef.SystemDrawing)]
public sealed unsafe class Bitmap : Image, IPointer
{
private static readonly Color s_defaultTransparentColor = Color.LightGray;
@@ -267,12 +268,11 @@ public BitmapData LockBits(Rectangle rect, ImageLockMode flags, PixelFormat form
fixed (void* data = &bitmapData.GetPinnableReference())
{
- PInvoke.GdipBitmapLockBits(
- this.Pointer(),
- rect.IsEmpty ? null : (Rect*)&rect,
- (uint)flags,
- (int)format,
- (GdiPlus.BitmapData*)data).ThrowIfFailed();
+ this.LockBits(
+ rect,
+ (GdiPlus.ImageLockMode)flags,
+ (GdiPlus.PixelFormat)format,
+ ref Unsafe.AsRef(data));
}
GC.KeepAlive(this);
@@ -285,7 +285,7 @@ public void UnlockBits(BitmapData bitmapdata)
fixed (void* data = &bitmapdata.GetPinnableReference())
{
- PInvoke.GdipBitmapUnlockBits(this.Pointer(), (GdiPlus.BitmapData*)data).ThrowIfFailed();
+ this.UnlockBits(ref Unsafe.AsRef(data));
}
GC.KeepAlive(this);
@@ -365,7 +365,6 @@ public Bitmap Clone(Rectangle rect, PixelFormat format)
///
/// The effect to apply.
/// The area to apply to, or for the entire image.
- [RequiresPreviewFeatures]
public void ApplyEffect(Effect effect, Rectangle area = default)
{
RECT rect = area;
diff --git a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPath.cs b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPath.cs
index 5165a26ba42..4878f15c08c 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPath.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/GraphicsPath.cs
@@ -12,8 +12,10 @@ public sealed unsafe class GraphicsPath : MarshalByRefObject, ICloneable, IDispo
private const float Flatness = (float)2.0 / (float)3.0;
+ ///
public GraphicsPath() : this(FillMode.Alternate) { }
+ ///
public GraphicsPath(FillMode fillMode)
{
GpPath* path;
@@ -21,15 +23,27 @@ public GraphicsPath(FillMode fillMode)
_nativePath = path;
}
+ ///
public GraphicsPath(PointF[] pts, byte[] types) : this(pts, types, FillMode.Alternate) { }
+ ///
public GraphicsPath(PointF[] pts, byte[] types, FillMode fillMode)
+ : this(pts.OrThrowIfNull().AsSpan(), types.OrThrowIfNull().AsSpan(), fillMode)
{
- ArgumentNullException.ThrowIfNull(pts);
- ArgumentNullException.ThrowIfNull(types);
+ }
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ internal
+#endif
+ GraphicsPath(ReadOnlySpan pts, ReadOnlySpan types, FillMode fillMode = FillMode.Alternate)
+ {
if (pts.Length != types.Length)
+ {
throw Status.InvalidParameter.GetException();
+ }
fixed (PointF* p = pts)
fixed (byte* t = types)
@@ -40,14 +54,32 @@ public GraphicsPath(PointF[] pts, byte[] types, FillMode fillMode)
}
}
+ ///
public GraphicsPath(Point[] pts, byte[] types) : this(pts, types, FillMode.Alternate) { }
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// Array of points that define the path.
+ /// Array of values that specify the type of
+ ///
+ /// A enumeration that specifies how the interiors of shapes in this
+ ///
public GraphicsPath(Point[] pts, byte[] types, FillMode fillMode)
- {
- ArgumentNullException.ThrowIfNull(pts);
+ : this(pts.OrThrowIfNull().AsSpan(), types.OrThrowIfNull().AsSpan(), fillMode) { }
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ internal
+#endif
+ GraphicsPath(ReadOnlySpan pts, ReadOnlySpan types, FillMode fillMode = FillMode.Alternate)
+ {
if (pts.Length != types.Length)
+ {
throw Status.InvalidParameter.GetException();
+ }
fixed (byte* t = types)
fixed (Point* p = pts)
@@ -276,12 +308,33 @@ public void AddLine(float x1, float y1, float x2, float y2)
GC.KeepAlive(this);
}
- public void AddLines(PointF[] points)
+ ///
+ /// Appends a series of connected line segments to the end of this .
+ ///
+ /// An array of points that define the line segments to add.
+ ///
+ ///
+ ///
+ /// If there are previous lines or curves in the figure, a line is added to connect the endpoint
+ /// of the previous segment the starting point of the line. The parameter
+ /// specifies an array of endpoints. The first two specify the first line. Each additional point
+ /// specifies the endpoint of a line segment whose starting point is the endpoint of the previous line.
+ ///
+ ///
+ public void AddLines(params PointF[] points) => AddLines(points.OrThrowIfNull().AsSpan());
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void AddLines(ReadOnlySpan points)
{
- ArgumentNullException.ThrowIfNull(points);
-
if (points.Length == 0)
+ {
throw new ArgumentException(null, nameof(points));
+ }
fixed (PointF* p = points)
{
@@ -294,12 +347,21 @@ public void AddLines(PointF[] points)
public void AddLine(int x1, int y1, int x2, int y2) => AddLine((float)x1, y1, x2, y2);
- public void AddLines(Point[] points)
- {
- ArgumentNullException.ThrowIfNull(points);
+ ///
+ public void AddLines(params Point[] points) => AddLines(points.OrThrowIfNull().AsSpan());
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void AddLines(ReadOnlySpan points)
+ {
if (points.Length == 0)
+ {
throw new ArgumentException(null, nameof(points));
+ }
fixed (Point* p = points)
{
@@ -332,10 +394,20 @@ public void AddBezier(float x1, float y1, float x2, float y2, float x3, float y3
GC.KeepAlive(this);
}
- public void AddBeziers(PointF[] points)
- {
- ArgumentNullException.ThrowIfNull(points);
+ ///
+ /// Adds a sequence of connected cubic Bézier curves to the current figure.
+ ///
+ /// An array of points that define the curves.
+ public void AddBeziers(params PointF[] points) => AddBeziers(points.OrThrowIfNull().AsSpan());
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ internal
+#endif
+ void AddBeziers(ReadOnlySpan points)
+ {
fixed (PointF* p = points)
{
PInvoke.GdipAddPathBeziers(_nativePath, (GdiPlus.PointF*)p, points.Length).ThrowIfFailed();
@@ -349,10 +421,17 @@ public void AddBezier(Point pt1, Point pt2, Point pt3, Point pt4) =>
public void AddBezier(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) =>
AddBezier((float)x1, y1, x2, y2, x3, y3, x4, y4);
- public void AddBeziers(params Point[] points)
- {
- ArgumentNullException.ThrowIfNull(points);
+ ///
+ public void AddBeziers(params Point[] points) => AddBeziers(points.OrThrowIfNull().AsSpan());
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ internal
+#endif
+ void AddBeziers(ReadOnlySpan points)
+ {
if (points.Length == 0)
return;
@@ -363,13 +442,26 @@ public void AddBeziers(params Point[] points)
}
}
- ///
- /// Add cardinal splines to the path object
- ///
- public void AddCurve(PointF[] points) => AddCurve(points.AsSpan(), 0.5f);
+ ///
+ public void AddCurve(params PointF[] points) => AddCurve(points.AsSpan(), 0.5f);
+ ///
public void AddCurve(PointF[] points, float tension) => AddCurve(points.AsSpan(), tension);
+ ///
+ /// Adds a spline curve to the current figure. A cardinal spline curve is used because the
+ /// curve travels through each of the points in the array.
+ ///
+ /// An array points that define the curve.
+ /// The index of the first point in the array to use.
+ ///
+ /// The number of segments to use when creating the curve. A segment can be thought of as
+ /// a line connecting two points.
+ ///
+ ///
+ /// A value that specifies the amount that the curve bends between control points.
+ /// Values greater than 1 produce unpredictable results.
+ ///
public void AddCurve(PointF[] points, int offset, int numberOfSegments, float tension)
{
fixed (PointF* p = points)
@@ -386,7 +478,18 @@ public void AddCurve(PointF[] points, int offset, int numberOfSegments, float te
}
}
- private void AddCurve(Span points, float tension)
+#if NET9_0_OR_GREATER
+ ///
+ public void AddCurve(ReadOnlySpan points) => AddCurve(points, 0.5f);
+#endif
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void AddCurve(ReadOnlySpan points, float tension)
{
fixed (PointF* p = points)
{
@@ -400,10 +503,13 @@ private void AddCurve(Span points, float tension)
}
}
- public void AddCurve(Point[] points) => AddCurve(points.AsSpan(), 0.5f);
+ ///
+ public void AddCurve(params Point[] points) => AddCurve(points.AsSpan(), 0.5f);
+ ///
public void AddCurve(Point[] points, float tension) => AddCurve(points.AsSpan(), tension);
+ ///
public void AddCurve(Point[] points, int offset, int numberOfSegments, float tension)
{
fixed (Point* p = points)
@@ -420,7 +526,18 @@ public void AddCurve(Point[] points, int offset, int numberOfSegments, float ten
}
}
- private void AddCurve(Span points, float tension)
+#if NET9_0_OR_GREATER
+ ///
+ public void AddCurve(ReadOnlySpan points) => AddCurve(points, 0.5f);
+#endif
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void AddCurve(ReadOnlySpan points, float tension)
{
fixed (Point* p = points)
{
@@ -434,12 +551,25 @@ private void AddCurve(Span points, float tension)
}
}
- public void AddClosedCurve(PointF[] points) => AddClosedCurve(points, 0.5f);
+ ///
+ public void AddClosedCurve(params PointF[] points) => AddClosedCurve(points, 0.5f);
- public void AddClosedCurve(PointF[] points, float tension)
- {
- ArgumentNullException.ThrowIfNull(points);
+ ///
+ public void AddClosedCurve(PointF[] points, float tension) => AddClosedCurve(points.OrThrowIfNull().AsSpan(), tension);
+
+#if NET9_0_OR_GREATER
+ ///
+ public void AddClosedCurve(ReadOnlySpan points) => AddClosedCurve(points, 0.5f);
+#endif
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void AddClosedCurve(ReadOnlySpan points, float tension)
+ {
fixed (PointF* p = points)
{
PInvoke.GdipAddPathClosedCurve2(_nativePath, (GdiPlus.PointF*)p, points.Length, tension).ThrowIfFailed();
@@ -447,12 +577,29 @@ public void AddClosedCurve(PointF[] points, float tension)
}
}
- public void AddClosedCurve(Point[] points) => AddClosedCurve(points, 0.5f);
+ ///
+ public void AddClosedCurve(params Point[] points) => AddClosedCurve(points, 0.5f);
- public void AddClosedCurve(Point[] points, float tension)
- {
- ArgumentNullException.ThrowIfNull(points);
+ ///
+ /// Adds a closed spline curve to the current figure. A cardinal spline curve is used because the
+ /// curve travels through each of the points in the array.
+ ///
+ ///
+ public void AddClosedCurve(Point[] points, float tension) => AddClosedCurve(points.OrThrowIfNull().AsSpan(), tension);
+#if NET9_0_OR_GREATER
+ ///
+ public void AddClosedCurve(ReadOnlySpan points) => AddClosedCurve(points, 0.5f);
+#endif
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void AddClosedCurve(ReadOnlySpan points, float tension)
+ {
fixed (Point* p = points)
{
PInvoke.GdipAddPathClosedCurve2I(_nativePath, (GdiPlus.Point*)p, points.Length, tension).ThrowIfFailed();
@@ -468,10 +615,20 @@ public void AddRectangle(RectangleF rect)
GC.KeepAlive(this);
}
- public void AddRectangles(RectangleF[] rects)
- {
- ArgumentNullException.ThrowIfNull(rects);
+ ///
+ /// Adds a series of rectangles to this path.
+ ///
+ /// Array of rectangles to add.
+ public void AddRectangles(params RectangleF[] rects) => AddRectangles(rects.OrThrowIfNull().AsSpan());
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void AddRectangles(ReadOnlySpan rects)
+ {
fixed (RectangleF* r = rects)
{
PInvoke.GdipAddPathRectangles(_nativePath, (RectF*)r, rects.Length).ThrowIfFailed();
@@ -481,10 +638,17 @@ public void AddRectangles(RectangleF[] rects)
public void AddRectangle(Rectangle rect) => AddRectangle((RectangleF)rect);
- public void AddRectangles(Rectangle[] rects)
- {
- ArgumentNullException.ThrowIfNull(rects);
+ ///
+ public void AddRectangles(Rectangle[] rects) => AddRectangles(rects.OrThrowIfNull().AsSpan());
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void AddRectangles(ReadOnlySpan rects)
+ {
fixed (Rectangle* r = rects)
{
PInvoke.GdipAddPathRectanglesI(_nativePath, (Rect*)r, rects.Length).ThrowIfFailed();
@@ -494,40 +658,40 @@ public void AddRectangles(Rectangle[] rects)
#if NET9_0_OR_GREATER
///
- public void AddRoundedRectangle(Rectangle rect, Size corner) =>
- AddRoundedRectangle((RectangleF)rect, corner);
+ public void AddRoundedRectangle(Rectangle rect, Size radius) =>
+ AddRoundedRectangle((RectangleF)rect, radius);
///
/// Adds a rounded rectangle to this path.
///
/// The bounds of the rectangle to add.
- /// The size of the ellipse used to round the corners of the rectangle.
- public void AddRoundedRectangle(RectangleF rect, SizeF corner)
+ /// The radius width and height used to round the corners of the rectangle.
+ public void AddRoundedRectangle(RectangleF rect, SizeF radius)
{
StartFigure();
AddArc(
- rect.Right - corner.Width,
+ rect.Right - radius.Width,
rect.Top,
- corner.Width,
- corner.Height,
+ radius.Width,
+ radius.Height,
-90.0f, 90.0f);
AddArc(
- rect.Right - corner.Width,
- rect.Bottom - corner.Height,
- corner.Width,
- corner.Height,
+ rect.Right - radius.Width,
+ rect.Bottom - radius.Height,
+ radius.Width,
+ radius.Height,
0.0f, 90.0f);
AddArc(
rect.Left,
- rect.Bottom - corner.Height,
- corner.Width,
- corner.Height,
+ rect.Bottom - radius.Height,
+ radius.Width,
+ radius.Height,
90.0f, 90.0f);
AddArc(
rect.Left,
rect.Top,
- corner.Width,
- corner.Height,
+ radius.Width,
+ radius.Height,
180.0f, 90.0f);
CloseFigure();
}
@@ -563,10 +727,17 @@ public void AddPie(float x, float y, float width, float height, float startAngle
public void AddPie(int x, int y, int width, int height, float startAngle, float sweepAngle) =>
AddPie((float)x, y, width, height, startAngle, sweepAngle);
- public void AddPolygon(PointF[] points)
- {
- ArgumentNullException.ThrowIfNull(points);
+ ///
+ public void AddPolygon(PointF[] points) => AddPolygon(points.OrThrowIfNull().AsSpan());
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void AddPolygon(ReadOnlySpan points)
+ {
fixed (PointF* p = points)
{
PInvoke.GdipAddPathPolygon(_nativePath, (GdiPlus.PointF*)p, points.Length).ThrowIfFailed();
@@ -575,12 +746,19 @@ public void AddPolygon(PointF[] points)
}
///
- /// Adds a polygon to the current figure.
+ /// Adds a polygon to this path.
///
- public void AddPolygon(Point[] points)
- {
- ArgumentNullException.ThrowIfNull(points);
+ /// The points that define the polygon.
+ public void AddPolygon(Point[] points) => AddPolygon(points.OrThrowIfNull().AsSpan());
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void AddPolygon(ReadOnlySpan points)
+ {
fixed (Point* p = points)
{
PInvoke.GdipAddPathPolygonI(_nativePath, (GdiPlus.Point*)p, points.Length).ThrowIfFailed();
@@ -683,18 +861,51 @@ public void Widen(Pen pen, Matrix? matrix, float flatness)
GC.KeepAlive(this);
}
+ ///
public void Warp(PointF[] destPoints, RectangleF srcRect) => Warp(destPoints, srcRect, null);
+ ///
public void Warp(PointF[] destPoints, RectangleF srcRect, Matrix? matrix) =>
Warp(destPoints, srcRect, matrix, WarpMode.Perspective);
+ ///
public void Warp(PointF[] destPoints, RectangleF srcRect, Matrix? matrix, WarpMode warpMode) =>
Warp(destPoints, srcRect, matrix, warpMode, 0.25f);
- public void Warp(PointF[] destPoints, RectangleF srcRect, Matrix? matrix, WarpMode warpMode, float flatness)
- {
- ArgumentNullException.ThrowIfNull(destPoints);
+ ///
+ public void Warp(PointF[] destPoints, RectangleF srcRect, Matrix? matrix, WarpMode warpMode, float flatness) =>
+ Warp(destPoints.OrThrowIfNull().AsSpan(), srcRect, matrix, warpMode, flatness);
+ ///
+ /// Applies a warp transform, defined by a rectangle and a parallelogram, to this .
+ ///
+ ///
+ /// An array of points that define a parallelogram to which the rectangle defined by
+ /// is transformed. The array can contain either three or four elements. If the array contains three elements,
+ /// the lower-right corner of the parallelogram is implied by the first three points.
+ ///
+ ///
+ /// A rectangle that represents the rectangle that is transformed to the parallelogram defined by
+ /// .
+ ///
+ /// A matrix that specifies a geometric transform to apply to the path.
+ /// Specifies whether this warp operation uses perspective or bilinear mode.
+ ///
+ /// A value from 0 through 1 that specifies how flat the resulting path is. For more information, see the
+ /// methods.
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void Warp(
+ ReadOnlySpan destPoints,
+ RectangleF srcRect,
+ Matrix? matrix = default,
+ WarpMode warpMode = WarpMode.Perspective,
+ float flatness = 0.25f)
+ {
fixed (PointF* p = destPoints)
{
PInvoke.GdipWarpPath(
@@ -732,12 +943,37 @@ public byte[] PathTypes
}
byte[] types = new byte[count];
- fixed (byte* t = types)
- {
- PInvoke.GdipGetPathTypes(_nativePath, t, types.Length).ThrowIfFailed();
- GC.KeepAlive(this);
- return types;
- }
+ GetPathTypes(types);
+ return types;
+ }
+ }
+
+ ///
+ /// Gets the types for the points in the path.
+ ///
+ ///
+ /// Span to copy the types into. This should be at least as long as the .
+ ///
+ ///
+ /// The count of types copied into the .
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ int GetPathTypes(Span destination)
+ {
+ if (destination.IsEmpty)
+ {
+ return 0;
+ }
+
+ fixed (byte* t = destination)
+ {
+ PInvoke.GdipGetPathTypes(_nativePath, t, destination.Length).ThrowIfFailed();
+ GC.KeepAlive(this);
+ return PointCount;
}
}
@@ -752,12 +988,37 @@ public PointF[] PathPoints
}
PointF[] points = new PointF[count];
- fixed (PointF* p = points)
- {
- PInvoke.GdipGetPathPoints(_nativePath, (GdiPlus.PointF*)p, points.Length).ThrowIfFailed();
- GC.KeepAlive(this);
- return points;
- }
+ GetPathPoints(points);
+ return points;
+ }
+ }
+
+ ///
+ /// Gets the points in the path.
+ ///
+ ///
+ /// Span to copy the points into. This should be at least as long as the .
+ ///
+ ///
+ /// The count of points copied into the .
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ int GetPathPoints(Span destination)
+ {
+ if (destination.IsEmpty)
+ {
+ return 0;
+ }
+
+ fixed (PointF* p = destination)
+ {
+ PInvoke.GdipGetPathPoints(_nativePath, (GdiPlus.PointF*)p, destination.Length).ThrowIfFailed();
+ GC.KeepAlive(this);
+ return PointCount;
}
}
}
diff --git a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/PathPointType.cs b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/PathPointType.cs
index 1c761f0c8a4..ad1d21f45dd 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/PathPointType.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/PathPointType.cs
@@ -1,18 +1,45 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace System.Drawing.Drawing2D;
public enum PathPointType
{
- Start = 0, // move
- Line = 1, // line
- Bezier = 3, // default Beizer (= cubic Bezier)
- PathTypeMask = 0x07, // type mask (lowest 3 bits).
- DashMode = 0x10, // currently in dash mode.
- PathMarker = 0x20, // a marker for the path.
- CloseSubpath = 0x80, // closed flag
-
- // Path types used for advanced path.
- Bezier3 = 3, // cubic Bezier
+ ///
+ /// Indicates that the point is the start of a figure.
+ ///
+ Start = GdiPlus.PathPointType.PathPointTypeStart,
+
+ ///
+ /// Indicates that the point is an endpoint of a line.
+ ///
+ Line = GdiPlus.PathPointType.PathPointTypeLine,
+
+ ///
+ /// Indicates that the point is an endpoint or a control point of a cubic Bézier spline.
+ ///
+ Bezier = GdiPlus.PathPointType.PathPointTypeBezier,
+
+ ///
+ /// Masks all bits except for the three low-order bits, which indicate the point type.
+ ///
+ PathTypeMask = GdiPlus.PathPointType.PathPointTypePathTypeMask,
+
+ ///
+ /// Not used.
+ ///
+ DashMode = GdiPlus.PathPointType.PathPointTypeDashMode,
+
+ ///
+ /// Specifies that the point is a marker.
+ ///
+ PathMarker = GdiPlus.PathPointType.PathPointTypePathMarker,
+
+ ///
+ /// Specifies that the point is the last point in a closed subpath (figure).
+ ///
+ CloseSubpath = GdiPlus.PathPointType.PathPointTypeCloseSubpath,
+
+ ///
+ Bezier3 = GdiPlus.PathPointType.PathPointTypeBezier3
}
diff --git a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/WrapMode.cs b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/WrapMode.cs
index c49d848b585..6ef54ddc5f2 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Drawing2D/WrapMode.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Drawing2D/WrapMode.cs
@@ -5,9 +5,28 @@ namespace System.Drawing.Drawing2D;
public enum WrapMode
{
+ ///
+ /// Tiles the gradient or texture.
+ ///
Tile = GdiPlus.WrapMode.WrapModeTile,
+
+ ///
+ /// Reverses the texture or gradient horizontally and then tiles the texture or gradient.
+ ///
TileFlipX = GdiPlus.WrapMode.WrapModeTileFlipX,
+
+ ///
+ /// Reverses the texture or gradient vertically and then tiles the texture or gradient.
+ ///
TileFlipY = GdiPlus.WrapMode.WrapModeTileFlipY,
+
+ ///
+ /// Reverses the texture or gradient horizontally and vertically and then tiles the texture or gradient.
+ ///
TileFlipXY = GdiPlus.WrapMode.WrapModeTileFlipXY,
- Clamp = GdiPlus.WrapMode.WrapModeClamp,
+
+ ///
+ /// The texture or gradient is not tiled.
+ ///
+ Clamp = GdiPlus.WrapMode.WrapModeClamp
}
diff --git a/src/System.Drawing.Common/src/System/Drawing/Graphics.cs b/src/System.Drawing.Common/src/System/Drawing/Graphics.cs
index 8c45cb461db..a90946bac8b 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Graphics.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Graphics.cs
@@ -747,18 +747,18 @@ public void DrawBezier(Pen pen, Point pt1, Point pt2, Point pt3, Point pt4) =>
#if NET9_0_OR_GREATER
///
- public void DrawRoundedRectangle(Pen pen, Rectangle rect, Size corner) =>
- DrawRoundedRectangle(pen, (RectangleF)rect, corner);
+ public void DrawRoundedRectangle(Pen pen, Rectangle rect, Size radius) =>
+ DrawRoundedRectangle(pen, (RectangleF)rect, radius);
///
/// Draws the outline of the specified rounded rectangle.
///
/// The to draw the outline with.
///
- public void DrawRoundedRectangle(Pen pen, RectangleF rect, SizeF corner)
+ public void DrawRoundedRectangle(Pen pen, RectangleF rect, SizeF radius)
{
using GraphicsPath path = new();
- path.AddRoundedRectangle(rect, corner);
+ path.AddRoundedRectangle(rect, radius);
DrawPath(pen, path);
}
#endif
@@ -779,13 +779,18 @@ public void DrawRectangle(Pen pen, float x, float y, float width, float height)
public void DrawRectangle(Pen pen, int x, int y, int width, int height)
=> DrawRectangle(pen, (float)x, y, width, height);
- ///
- /// Draws the outlines of a series of rectangles.
- ///
- public void DrawRectangles(Pen pen, RectangleF[] rects)
+ ///
+ public void DrawRectangles(Pen pen, params RectangleF[] rects) => DrawRectangles(pen, rects.OrThrowIfNull().AsSpan());
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void DrawRectangles(Pen pen, ReadOnlySpan rects)
{
ArgumentNullException.ThrowIfNull(pen);
- ArgumentNullException.ThrowIfNull(rects);
fixed (RectangleF* r = rects)
{
@@ -798,10 +803,19 @@ public void DrawRectangles(Pen pen, RectangleF[] rects)
///
/// Draws the outlines of a series of rectangles.
///
- public void DrawRectangles(Pen pen, Rectangle[] rects)
+ /// that determines the color, width, and style of the outlines of the rectangles.
+ /// An array of structures that represents the rectangles to draw.
+ public void DrawRectangles(Pen pen, params Rectangle[] rects) => DrawRectangles(pen, rects.OrThrowIfNull().AsSpan());
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void DrawRectangles(Pen pen, ReadOnlySpan rects)
{
ArgumentNullException.ThrowIfNull(pen);
- ArgumentNullException.ThrowIfNull(rects);
fixed (Rectangle* r = rects)
{
@@ -864,13 +878,18 @@ public void DrawPie(Pen pen, Rectangle rect, float startAngle, float sweepAngle)
public void DrawPie(Pen pen, int x, int y, int width, int height, int startAngle, int sweepAngle) =>
DrawPie(pen, (float)x, y, width, height, startAngle, sweepAngle);
- ///
- /// Draws the outline of a polygon defined by an array of points.
- ///
- public void DrawPolygon(Pen pen, PointF[] points)
+ ///
+ public void DrawPolygon(Pen pen, params PointF[] points) => DrawPolygon(pen, points.OrThrowIfNull().AsSpan());
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void DrawPolygon(Pen pen, ReadOnlySpan points)
{
ArgumentNullException.ThrowIfNull(pen);
- ArgumentNullException.ThrowIfNull(points);
fixed (PointF* p = points)
{
@@ -883,10 +902,19 @@ public void DrawPolygon(Pen pen, PointF[] points)
///
/// Draws the outline of a polygon defined by an array of points.
///
- public void DrawPolygon(Pen pen, Point[] points)
+ /// The to draw the outline with.
+ /// An array of structures that represent the vertices of the polygon.
+ public void DrawPolygon(Pen pen, params Point[] points) => DrawPolygon(pen, points.OrThrowIfNull().AsSpan());
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void DrawPolygon(Pen pen, ReadOnlySpan points)
{
ArgumentNullException.ThrowIfNull(pen);
- ArgumentNullException.ThrowIfNull(points);
fixed (Point* p = points)
{
@@ -910,13 +938,18 @@ public void DrawPath(Pen pen, GraphicsPath path)
GC.KeepAlive(path);
}
- ///
- /// Draws a curve defined by an array of points.
- ///
- public void DrawCurve(Pen pen, PointF[] points)
+ ///
+ public void DrawCurve(Pen pen, params PointF[] points) => DrawCurve(pen, points.OrThrowIfNull().AsSpan());
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void DrawCurve(Pen pen, ReadOnlySpan points)
{
ArgumentNullException.ThrowIfNull(pen);
- ArgumentNullException.ThrowIfNull(points);
fixed (PointF* p = points)
{
@@ -926,13 +959,19 @@ public void DrawCurve(Pen pen, PointF[] points)
GC.KeepAlive(pen);
}
- ///
- /// Draws a curve defined by an array of points.
- ///
- public void DrawCurve(Pen pen, PointF[] points, float tension)
+ ///
+ public void DrawCurve(Pen pen, PointF[] points, float tension) =>
+ DrawCurve(pen, points.OrThrowIfNull().AsSpan(), tension);
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void DrawCurve(Pen pen, ReadOnlySpan points, float tension)
{
ArgumentNullException.ThrowIfNull(pen);
- ArgumentNullException.ThrowIfNull(points);
fixed (PointF* p = points)
{
@@ -946,16 +985,29 @@ public void DrawCurve(Pen pen, PointF[] points, float tension)
GC.KeepAlive(pen);
}
+ ///
public void DrawCurve(Pen pen, PointF[] points, int offset, int numberOfSegments) =>
DrawCurve(pen, points, offset, numberOfSegments, 0.5f);
- ///
- /// Draws a curve defined by an array of points.
- ///
- public void DrawCurve(Pen pen, PointF[] points, int offset, int numberOfSegments, float tension)
+#if NET9_0_OR_GREATER
+ ///
+ public void DrawCurve(Pen pen, ReadOnlySpan points, int offset, int numberOfSegments) =>
+ DrawCurve(pen, points, offset, numberOfSegments, 0.5f);
+#endif
+
+ ///
+ public void DrawCurve(Pen pen, PointF[] points, int offset, int numberOfSegments, float tension) =>
+ DrawCurve(pen, points.OrThrowIfNull().AsSpan(), offset, numberOfSegments, tension);
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void DrawCurve(Pen pen, ReadOnlySpan points, int offset, int numberOfSegments, float tension)
{
ArgumentNullException.ThrowIfNull(pen);
- ArgumentNullException.ThrowIfNull(points);
fixed (PointF* p = points)
{
@@ -971,13 +1023,18 @@ public void DrawCurve(Pen pen, PointF[] points, int offset, int numberOfSegments
GC.KeepAlive(pen);
}
- ///
- /// Draws a curve defined by an array of points.
- ///
- public void DrawCurve(Pen pen, Point[] points)
+ ///
+ public void DrawCurve(Pen pen, params Point[] points) => DrawCurve(pen, points.OrThrowIfNull().AsSpan());
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void DrawCurve(Pen pen, ReadOnlySpan points)
{
ArgumentNullException.ThrowIfNull(pen);
- ArgumentNullException.ThrowIfNull(points);
fixed (Point* p = points)
{
@@ -987,13 +1044,19 @@ public void DrawCurve(Pen pen, Point[] points)
GC.KeepAlive(pen);
}
- ///
- /// Draws a curve defined by an array of points.
- ///
- public void DrawCurve(Pen pen, Point[] points, float tension)
+ ///
+ public void DrawCurve(Pen pen, Point[] points, float tension) =>
+ DrawCurve(pen, points.OrThrowIfNull().AsSpan(), tension);
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void DrawCurve(Pen pen, ReadOnlySpan points, float tension)
{
ArgumentNullException.ThrowIfNull(pen);
- ArgumentNullException.ThrowIfNull(points);
fixed (Point* p = points)
{
@@ -1010,10 +1073,23 @@ public void DrawCurve(Pen pen, Point[] points, float tension)
///
/// Draws a curve defined by an array of points.
///
- public void DrawCurve(Pen pen, Point[] points, int offset, int numberOfSegments, float tension)
+ /// The to draw the curve with.
+ /// An array of points that define the curve.
+ /// The index of the first point in the array to draw.
+ /// The number of segments to draw.
+ /// A value greater than, or equal to zero that specifies the tension of the curve.
+ public void DrawCurve(Pen pen, Point[] points, int offset, int numberOfSegments, float tension) =>
+ DrawCurve(pen, points.OrThrowIfNull().AsSpan(), offset, numberOfSegments, tension);
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void DrawCurve(Pen pen, ReadOnlySpan points, int offset, int numberOfSegments, float tension)
{
ArgumentNullException.ThrowIfNull(pen);
- ArgumentNullException.ThrowIfNull(points);
fixed (Point* p = points)
{
@@ -1029,13 +1105,19 @@ public void DrawCurve(Pen pen, Point[] points, int offset, int numberOfSegments,
GC.KeepAlive(pen);
}
- ///
- /// Draws a closed curve defined by an array of points.
- ///
- public void DrawClosedCurve(Pen pen, PointF[] points)
+ ///
+ public void DrawClosedCurve(Pen pen, params PointF[] points) =>
+ DrawClosedCurve(pen, points.OrThrowIfNull().AsSpan());
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void DrawClosedCurve(Pen pen, ReadOnlySpan points)
{
ArgumentNullException.ThrowIfNull(pen);
- ArgumentNullException.ThrowIfNull(points);
fixed (PointF* p = points)
{
@@ -1051,10 +1133,22 @@ public void DrawClosedCurve(Pen pen, PointF[] points)
///
/// Draws a closed curve defined by an array of points.
///
- public void DrawClosedCurve(Pen pen, PointF[] points, float tension, Drawing2D.FillMode fillmode)
+ /// The to draw the closed curve with.
+ /// An array of points that define the closed curve.
+ /// A value greater than, or equal to zero that specifies the tension of the curve.
+ /// A enumeration that specifies the fill mode of the curve.
+ public void DrawClosedCurve(Pen pen, PointF[] points, float tension, FillMode fillmode) =>
+ DrawClosedCurve(pen, points.OrThrowIfNull().AsSpan(), tension, fillmode);
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void DrawClosedCurve(Pen pen, ReadOnlySpan points, float tension, FillMode fillmode)
{
ArgumentNullException.ThrowIfNull(pen);
- ArgumentNullException.ThrowIfNull(points);
fixed (PointF* p = points)
{
@@ -1068,13 +1162,18 @@ public void DrawClosedCurve(Pen pen, PointF[] points, float tension, Drawing2D.F
GC.KeepAlive(pen);
}
- ///
- /// Draws a closed curve defined by an array of points.
- ///
- public void DrawClosedCurve(Pen pen, Point[] points)
+ ///
+ public void DrawClosedCurve(Pen pen, Point[] points) => DrawClosedCurve(pen, points.OrThrowIfNull().AsSpan());
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void DrawClosedCurve(Pen pen, ReadOnlySpan points)
{
ArgumentNullException.ThrowIfNull(pen);
- ArgumentNullException.ThrowIfNull(points);
fixed (Point* p = points)
{
@@ -1087,13 +1186,20 @@ public void DrawClosedCurve(Pen pen, Point[] points)
GC.KeepAlive(pen);
}
- ///
- /// Draws a closed curve defined by an array of points.
- ///
- public void DrawClosedCurve(Pen pen, Point[] points, float tension, Drawing2D.FillMode fillmode)
+ ///
+
+ public void DrawClosedCurve(Pen pen, Point[] points, float tension, FillMode fillmode) =>
+ DrawClosedCurve(pen, points.OrThrowIfNull().AsSpan(), tension, fillmode);
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void DrawClosedCurve(Pen pen, ReadOnlySpan points, float tension, FillMode fillmode)
{
ArgumentNullException.ThrowIfNull(pen);
- ArgumentNullException.ThrowIfNull(points);
fixed (Point* p = points)
{
@@ -1114,19 +1220,19 @@ public void DrawClosedCurve(Pen pen, Point[] points, float tension, Drawing2D.Fi
#if NET9_0_OR_GREATER
/// />
- public void FillRoundedRectangle(Brush brush, Rectangle rect, Size corner) =>
- FillRoundedRectangle(brush, (RectangleF)rect, corner);
+ public void FillRoundedRectangle(Brush brush, Rectangle rect, Size radius) =>
+ FillRoundedRectangle(brush, (RectangleF)rect, radius);
///
/// Fills the interior of a rounded rectangle with a .
///
/// The to fill the rounded rectangle with.
/// The bounds of the rounded rectangle.
- /// The size of the ellipse used to round the corners of the rectangle.
- public void FillRoundedRectangle(Brush brush, RectangleF rect, SizeF corner)
+ /// The radius width and height used to round the corners of the rectangle.
+ public void FillRoundedRectangle(Brush brush, RectangleF rect, SizeF radius)
{
using GraphicsPath path = new();
- path.AddRoundedRectangle(rect, corner);
+ path.AddRoundedRectangle(rect, radius);
FillPath(brush, path);
}
#endif
@@ -1164,10 +1270,23 @@ public void FillRectangle(Brush brush, float x, float y, float width, float heig
///
/// Fills the interiors of a series of rectangles with a .
///
- public void FillRectangles(Brush brush, RectangleF[] rects)
+ /// The to fill the rectangles with.
+ /// An array of rectangles to fill.
+ public void FillRectangles(Brush brush, params RectangleF[] rects)
{
- ArgumentNullException.ThrowIfNull(brush);
ArgumentNullException.ThrowIfNull(rects);
+ FillRectangles(brush, rects.AsSpan());
+ }
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void FillRectangles(Brush brush, ReadOnlySpan rects)
+ {
+ ArgumentNullException.ThrowIfNull(brush);
fixed (RectangleF* r = rects)
{
@@ -1177,13 +1296,19 @@ public void FillRectangles(Brush brush, RectangleF[] rects)
GC.KeepAlive(brush);
}
- ///
- /// Fills the interiors of a series of rectangles with a .
- ///
- public void FillRectangles(Brush brush, Rectangle[] rects)
+ ///
+ public void FillRectangles(Brush brush, params Rectangle[] rects) =>
+ FillRectangles(brush, rects.OrThrowIfNull().AsSpan());
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void FillRectangles(Brush brush, ReadOnlySpan rects)
{
ArgumentNullException.ThrowIfNull(brush);
- ArgumentNullException.ThrowIfNull(rects);
fixed (Rectangle* r = rects)
{
@@ -1193,18 +1318,27 @@ public void FillRectangles(Brush brush, Rectangle[] rects)
GC.KeepAlive(brush);
}
- ///
- /// Fills the interior of a polygon defined by an array of points.
- ///
- public void FillPolygon(Brush brush, PointF[] points) => FillPolygon(brush, points, Drawing2D.FillMode.Alternate);
+ ///
+ public void FillPolygon(Brush brush, params PointF[] points) => FillPolygon(brush, points, FillMode.Alternate);
- ///
- /// Fills the interior of a polygon defined by an array of points.
- ///
- public void FillPolygon(Brush brush, PointF[] points, Drawing2D.FillMode fillMode)
+#if NET9_0_OR_GREATER
+ ///
+ public void FillPolygon(Brush brush, ReadOnlySpan points) => FillPolygon(brush, points, FillMode.Alternate);
+#endif
+
+ ///
+ public void FillPolygon(Brush brush, PointF[] points, FillMode fillMode) =>
+ FillPolygon(brush, points.OrThrowIfNull().AsSpan(), fillMode);
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void FillPolygon(Brush brush, ReadOnlySpan points, FillMode fillMode)
{
ArgumentNullException.ThrowIfNull(brush);
- ArgumentNullException.ThrowIfNull(points);
fixed (PointF* p = points)
{
@@ -1218,18 +1352,32 @@ public void FillPolygon(Brush brush, PointF[] points, Drawing2D.FillMode fillMod
GC.KeepAlive(brush);
}
- ///
- /// Fills the interior of a polygon defined by an array of points.
- ///
- public void FillPolygon(Brush brush, Point[] points) => FillPolygon(brush, points, Drawing2D.FillMode.Alternate);
+ ///
+ public void FillPolygon(Brush brush, Point[] points) => FillPolygon(brush, points, FillMode.Alternate);
+
+#if NET9_0_OR_GREATER
+ ///
+ public void FillPolygon(Brush brush, ReadOnlySpan points) => FillPolygon(brush, points, FillMode.Alternate);
+#endif
///
/// Fills the interior of a polygon defined by an array of points.
///
- public void FillPolygon(Brush brush, Point[] points, Drawing2D.FillMode fillMode)
+ /// The to fill the polygon with.
+ /// An array points that represent the vertices of the polygon.
+ /// A enumeration that specifies the fill mode of the polygon.
+ public void FillPolygon(Brush brush, Point[] points, FillMode fillMode) =>
+ FillPolygon(brush, points.OrThrowIfNull().AsSpan(), fillMode);
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void FillPolygon(Brush brush, ReadOnlySpan points, FillMode fillMode)
{
ArgumentNullException.ThrowIfNull(brush);
- ArgumentNullException.ThrowIfNull(points);
fixed (Point* p = points)
{
@@ -1312,13 +1460,19 @@ public void FillPie(Brush brush, float x, float y, float width, float height, fl
public void FillPie(Brush brush, int x, int y, int width, int height, int startAngle, int sweepAngle)
=> FillPie(brush, (float)x, y, width, height, startAngle, sweepAngle);
- ///
- /// Fills the interior a closed curve defined by an array of points.
- ///
- public void FillClosedCurve(Brush brush, PointF[] points)
+ ///
+ public void FillClosedCurve(Brush brush, params PointF[] points) =>
+ FillClosedCurve(brush, points.OrThrowIfNull().AsSpan());
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void FillClosedCurve(Brush brush, ReadOnlySpan points)
{
ArgumentNullException.ThrowIfNull(brush);
- ArgumentNullException.ThrowIfNull(points);
fixed (PointF* p = points)
{
@@ -1331,16 +1485,35 @@ public void FillClosedCurve(Brush brush, PointF[] points)
GC.KeepAlive(brush);
}
+ ///
+ public void FillClosedCurve(Brush brush, PointF[] points, FillMode fillmode) =>
+ FillClosedCurve(brush, points, fillmode, 0.5f);
+
+#if NET9_0_OR_GREATER
+ ///
+ public void FillClosedCurve(Brush brush, ReadOnlySpan points, FillMode fillmode) =>
+ FillClosedCurve(brush, points, fillmode, 0.5f);
+#endif
+
///
/// Fills the interior of a closed curve defined by an array of points.
///
- public void FillClosedCurve(Brush brush, PointF[] points, Drawing2D.FillMode fillmode) =>
- FillClosedCurve(brush, points, fillmode, 0.5f);
+ /// The to fill the closed curve with.
+ /// An array of points that make up the closed curve.
+ /// A enumeration that specifies the fill mode of the closed curve.
+ /// A value greater than, or equal to zero that specifies the tension of the curve.
+ public void FillClosedCurve(Brush brush, PointF[] points, FillMode fillmode, float tension) =>
+ FillClosedCurve(brush, points.OrThrowIfNull().AsSpan(), fillmode, tension);
- public void FillClosedCurve(Brush brush, PointF[] points, Drawing2D.FillMode fillmode, float tension)
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void FillClosedCurve(Brush brush, ReadOnlySpan points, FillMode fillmode, float tension)
{
ArgumentNullException.ThrowIfNull(brush);
- ArgumentNullException.ThrowIfNull(points);
fixed (PointF* p = points)
{
@@ -1355,13 +1528,19 @@ public void FillClosedCurve(Brush brush, PointF[] points, Drawing2D.FillMode fil
GC.KeepAlive(brush);
}
- ///
- /// Fills the interior a closed curve defined by an array of points.
- ///
- public void FillClosedCurve(Brush brush, Point[] points)
+ ///
+ public void FillClosedCurve(Brush brush, params Point[] points) =>
+ FillClosedCurve(brush, points.OrThrowIfNull().AsSpan());
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void FillClosedCurve(Brush brush, ReadOnlySpan points)
{
ArgumentNullException.ThrowIfNull(brush);
- ArgumentNullException.ThrowIfNull(points);
fixed (Point* p = points)
{
@@ -1374,13 +1553,30 @@ public void FillClosedCurve(Brush brush, Point[] points)
GC.KeepAlive(brush);
}
- public void FillClosedCurve(Brush brush, Point[] points, Drawing2D.FillMode fillmode) =>
+ ///
+ public void FillClosedCurve(Brush brush, Point[] points, FillMode fillmode) =>
FillClosedCurve(brush, points, fillmode, 0.5f);
- public void FillClosedCurve(Brush brush, Point[] points, Drawing2D.FillMode fillmode, float tension)
+#if NET9_0_OR_GREATER
+ ///
+ public void FillClosedCurve(Brush brush, ReadOnlySpan points, FillMode fillmode) =>
+ FillClosedCurve(brush, points, fillmode, 0.5f);
+
+#endif
+
+ ///
+ public void FillClosedCurve(Brush brush, Point[] points, FillMode fillmode, float tension) =>
+ FillClosedCurve(brush, points.OrThrowIfNull().AsSpan(), fillmode, tension);
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void FillClosedCurve(Brush brush, ReadOnlySpan points, FillMode fillmode, float tension)
{
ArgumentNullException.ThrowIfNull(brush);
- ArgumentNullException.ThrowIfNull(points);
fixed (Point* p = points)
{
@@ -1570,7 +1766,7 @@ private void DrawStringInternal(ReadOnlySpan s, Font font, Brush brush, Re
CheckErrorStatus(PInvoke.GdipDrawString(
NativeGraphics,
c, s.Length,
- (GpFont*)font.NativeFont,
+ font.NativeFont,
(RectF*)&layoutRectangle,
format.Pointer(),
brush.NativeBrush));
@@ -1632,7 +1828,7 @@ public SizeF MeasureStringInternal(
NativeGraphics,
c,
text.Length,
- (GpFont*)font.NativeFont,
+ font.NativeFont,
(RectF*)&layoutArea,
stringFormat.Pointer(),
&boundingBox,
@@ -1792,7 +1988,7 @@ private Region[] MeasureCharacterRangesInternal(
NativeGraphics,
c,
text.Length,
- (GpFont*)font.NativeFont,
+ font.NativeFont,
&layoutRect,
stringFormat.Pointer(),
count,
@@ -2174,13 +2370,18 @@ public void DrawImage(
///
public void DrawLine(Pen pen, PointF pt1, PointF pt2) => DrawLine(pen, pt1.X, pt1.Y, pt2.X, pt2.Y);
- ///
- /// Draws a series of line segments that connect an array of points.
- ///
- public void DrawLines(Pen pen, PointF[] points)
+ ///
+ public void DrawLines(Pen pen, PointF[] points) => DrawLines(pen, points.OrThrowIfNull().AsSpan());
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void DrawLines(Pen pen, ReadOnlySpan points)
{
ArgumentNullException.ThrowIfNull(pen);
- ArgumentNullException.ThrowIfNull(points);
fixed (PointF* p = points)
{
@@ -2204,7 +2405,9 @@ public void DrawLine(Pen pen, int x1, int y1, int x2, int y2) =>
///
/// Draws a series of line segments that connect an array of points.
///
- public void DrawLines(Pen pen, Point[] points)
+ /// The that determines the color, width, and style of the line segments.
+ /// An array of points to connect.
+ public void DrawLines(Pen pen, params Point[] points)
{
ArgumentNullException.ThrowIfNull(pen);
ArgumentNullException.ThrowIfNull(points);
@@ -2217,6 +2420,24 @@ public void DrawLines(Pen pen, Point[] points)
GC.KeepAlive(pen);
}
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void DrawLines(Pen pen, ReadOnlySpan points)
+ {
+ ArgumentNullException.ThrowIfNull(pen);
+
+ fixed (Point* p = points)
+ {
+ CheckErrorStatus(PInvoke.GdipDrawLinesI(NativeGraphics, pen.NativePen, (GdiPlus.Point*)p, points.Length));
+ }
+
+ GC.KeepAlive(pen);
+ }
+
///
/// CopyPixels will perform a gdi "bitblt" operation to the source from the destination with the given size.
///
@@ -2547,13 +2768,19 @@ public void DrawLine(Pen pen, float x1, float y1, float x2, float y2)
GC.KeepAlive(pen);
}
- ///
- /// Draws a series of cubic Bezier curves from an array of points.
- ///
- public void DrawBeziers(Pen pen, PointF[] points)
+ ///
+ public void DrawBeziers(Pen pen, params PointF[] points) =>
+ DrawBeziers(pen, points.OrThrowIfNull().AsSpan());
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void DrawBeziers(Pen pen, ReadOnlySpan points)
{
ArgumentNullException.ThrowIfNull(pen);
- ArgumentNullException.ThrowIfNull(points);
fixed (PointF* p = points)
{
@@ -2567,12 +2794,24 @@ public void DrawBeziers(Pen pen, PointF[] points)
}
///
- /// Draws a series of cubic Bezier curves from an array of points.
+ /// Draws a series of cubic Bézier curves from an array of points.
///
- public void DrawBeziers(Pen pen, Point[] points)
+ /// The to draw the Bézier with.
+ ///
+ /// Points that represent the points that determine the curve. The number of points in the array
+ /// should be a multiple of 3 plus 1, such as 4, 7, or 10.
+ ///
+ public void DrawBeziers(Pen pen, params Point[] points) => DrawBeziers(pen, points.OrThrowIfNull().AsSpan());
+
+ ///
+#if NET9_0_OR_GREATER
+ public
+#else
+ private
+#endif
+ void DrawBeziers(Pen pen, ReadOnlySpan points)
{
ArgumentNullException.ThrowIfNull(pen);
- ArgumentNullException.ThrowIfNull(points);
fixed (Point* p = points)
{
@@ -3366,7 +3605,20 @@ public void DrawCachedBitmap(CachedBitmap cachedBitmap, int x, int y)
#endif
#if NET9_0_OR_GREATER
- [RequiresPreviewFeatures]
+ ///
+ public void DrawImage(
+ Image image,
+ Effect effect) => DrawImage(image, effect, srcRect: default, transform: default, GraphicsUnit.Pixel, imageAttr: null);
+
+ ///
+ /// Draws a portion of an image after applying a specified effect.
+ ///
+ /// to be drawn.
+ /// The effect to be applied when drawing.
+ /// The portion of the image to be drawn. draws the full image.
+ /// The transform to apply to the to determine the destination.
+ /// Unit of measure of the .
+ /// Additional adjustments to be applied, if any.
public void DrawImage(
Image image,
Effect effect,
@@ -3384,6 +3636,9 @@ public void DrawImage(
imageAttr.Pointer(),
(Unit)srcUnit).ThrowIfFailed();
+ GC.KeepAlive(effect);
+ GC.KeepAlive(imageAttr);
+ GC.KeepAlive(image);
GC.KeepAlive(this);
}
#endif
diff --git a/src/System.Drawing.Common/src/System/Drawing/Icon.cs b/src/System.Drawing.Common/src/System/Drawing/Icon.cs
index d725ec44dc3..e64752e40a6 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Icon.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Icon.cs
@@ -3,7 +3,6 @@
using System.Buffers;
using System.ComponentModel;
-using System.Drawing.Imaging;
using System.IO;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
diff --git a/src/System.Drawing.Common/src/System/Drawing/Image.cs b/src/System.Drawing.Common/src/System/Drawing/Image.cs
index d345db6bdd3..09c6a3e56a6 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Image.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Image.cs
@@ -387,7 +387,7 @@ public void SaveAdd(Imaging.EncoderParameters? encoderParams)
}
///
- /// Adds an to the specified .
+ /// Adds an to the specified .
///
public void SaveAdd(Image image, Imaging.EncoderParameters? encoderParams)
{
@@ -543,16 +543,7 @@ public ImageFormat RawFormat
///
/// Gets the pixel format for this .
///
- public PixelFormat PixelFormat
- {
- get
- {
- PixelFormat format;
- Status status = PInvoke.GdipGetImagePixelFormat(_nativeImage, (int*)&format);
- GC.KeepAlive(this);
- return (status != Status.Ok) ? PixelFormat.Undefined : format;
- }
- }
+ public PixelFormat PixelFormat => (PixelFormat)this.GetPixelFormat();
///
/// Gets an array of the property IDs stored in this .
@@ -619,11 +610,9 @@ public Imaging.PropertyItem[] PropertyItems
///
public RectangleF GetBounds(ref GraphicsUnit pageUnit)
{
- RectF bounds;
- Unit unit = (Unit)pageUnit;
- PInvoke.GdipGetImageBounds(_nativeImage, &bounds, &unit).ThrowIfFailed();
- pageUnit = (GraphicsUnit)unit;
- GC.KeepAlive(this);
+ // The Unit is hard coded to GraphicsUnit.Pixel in GDI+.
+ RectangleF bounds = this.GetImageBounds();
+ pageUnit = GraphicsUnit.Pixel;
return bounds;
}
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/BlackSaturationEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/BlackSaturationCurveEffect.cs
similarity index 85%
rename from src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/BlackSaturationEffect.cs
rename to src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/BlackSaturationCurveEffect.cs
index 1fdf840a365..0873aae2bbe 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/BlackSaturationEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/BlackSaturationCurveEffect.cs
@@ -3,19 +3,16 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
/// Sets the black saturation of an image. The black saturation is the point at which the darkest areas of the image
/// are converted to black.
///
-[RequiresPreviewFeatures]
-public class BlackSaturationEffect : ColorCurveEffect
+public class BlackSaturationCurveEffect : ColorCurveEffect
{
///
- /// Creates a new with the given parameters.
+ /// Creates a new with the given parameters.
///
/// The channel or channels that the effect is applied to.
///
@@ -24,7 +21,7 @@ public class BlackSaturationEffect : ColorCurveEffect
/// so that they spread out over the interval [0, 255]. Color channel values less than 15 are set to 0.
///
/// is less than 0 or greater than 254.
- public BlackSaturationEffect(CurveChannel channel, int blackSaturation)
+ public BlackSaturationCurveEffect(CurveChannel channel, int blackSaturation)
: base(CurveAdjustments.AdjustBlackSaturation, channel, blackSaturation)
{
}
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/BlurEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/BlurEffect.cs
index d284540fda0..ec5dc82e87c 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/BlurEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/BlurEffect.cs
@@ -3,14 +3,11 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
/// Applies a Gaussian blur.
///
-[RequiresPreviewFeatures]
public unsafe class BlurEffect : Effect
{
private readonly BlurParams _blurParams;
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/BrightnessContrastEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/BrightnessContrastEffect.cs
index d051ab344b9..807b955b19c 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/BrightnessContrastEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/BrightnessContrastEffect.cs
@@ -3,14 +3,11 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
/// Changes the brightness and contrast of an image.
///
-[RequiresPreviewFeatures]
public unsafe class BrightnessContrastEffect : Effect
{
private readonly BrightnessContrastParams _brightnessContrastParams;
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ColorBalanceEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ColorBalanceEffect.cs
index c4f84176910..b33ed2da525 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ColorBalanceEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ColorBalanceEffect.cs
@@ -3,14 +3,11 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
/// Adjusts the color balance of an image.
///
-[RequiresPreviewFeatures]
public class ColorBalanceEffect : Effect
{
private readonly ColorBalanceParams _colorBalanceParams;
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ColorCurveEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ColorCurveEffect.cs
index 038e6bb857a..818ef74ce76 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ColorCurveEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ColorCurveEffect.cs
@@ -3,14 +3,11 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
/// Base class for several effects that can be applied to an image.
///
-[RequiresPreviewFeatures]
public abstract class ColorCurveEffect : Effect
{
private readonly ColorCurveParams _parameters;
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ColorLookupTableEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ColorLookupTableEffect.cs
index 491737e0ce4..47275419e3f 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ColorLookupTableEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ColorLookupTableEffect.cs
@@ -4,7 +4,6 @@
#if NET9_0_OR_GREATER
using System.Runtime.CompilerServices;
-using System.Runtime.Versioning;
namespace System.Drawing.Imaging.Effects;
@@ -12,10 +11,9 @@ namespace System.Drawing.Imaging.Effects;
/// Allows modification of the color components of an image. Individual color component values are changed to entries
/// in a series of lookup tables.
///
-[RequiresPreviewFeatures]
public unsafe class ColorLookupTableEffect : Effect
{
- private readonly ColorLUTParams _parameters;
+ private readonly byte[] _bytes = new byte[1024];
///
/// Creates a new with the given parameters.
@@ -40,33 +38,41 @@ public ColorLookupTableEffect(
ReadOnlySpan blueLookupTable,
ReadOnlySpan alphaLookupTable) : base(PInvoke.ColorLUTEffectGuid)
{
- // ColorLUTParams will validate that the length fits.
+ ArgumentOutOfRangeException.ThrowIfGreaterThan(redLookupTable.Length, 256, nameof(redLookupTable));
+ ArgumentOutOfRangeException.ThrowIfGreaterThan(greenLookupTable.Length, 256, nameof(greenLookupTable));
+ ArgumentOutOfRangeException.ThrowIfGreaterThan(blueLookupTable.Length, 256, nameof(blueLookupTable));
+ ArgumentOutOfRangeException.ThrowIfGreaterThan(alphaLookupTable.Length, 256, nameof(alphaLookupTable));
- Unsafe.SkipInit(out _parameters);
- _parameters.lutR = redLookupTable;
- _parameters.lutG = greenLookupTable;
- _parameters.lutB = blueLookupTable;
- _parameters.lutA = alphaLookupTable;
+ Span bytes = _bytes;
+ blueLookupTable.CopyTo(bytes);
+ greenLookupTable.CopyTo(bytes[256..]);
+ redLookupTable.CopyTo(bytes[512..]);
+ alphaLookupTable.CopyTo(bytes[768..]);
+
+ fixed (byte* b = _bytes)
+ {
+ SetParameters(ref Unsafe.AsRef(b));
+ }
}
///
- /// The lookup table for the red channel.
+ /// The lookup table for the blue channel.
///
- public ReadOnlySpan RedLookupTable => _parameters.lutR.AsReadOnlySpan();
+ public ReadOnlyMemory BlueLookupTable => new(_bytes, 0, 256);
///
/// The lookup table for the green channel.
///
- public ReadOnlySpan GreenLookupTable => _parameters.lutG.AsReadOnlySpan();
+ public ReadOnlyMemory GreenLookupTable => new(_bytes, 256, 256);
///
- /// The lookup table for the blue channel.
+ /// The lookup table for the red channel.
///
- public ReadOnlySpan BlueLookupTable => _parameters.lutB.AsReadOnlySpan();
+ public ReadOnlyMemory RedLookupTable => new(_bytes, 512, 256);
///
/// The lookup table for the alpha channel.
///
- public ReadOnlySpan AlphaLookupTable => _parameters.lutA.AsReadOnlySpan();
+ public ReadOnlyMemory AlphaLookupTable => new(_bytes, 768, 256);
}
#endif
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ColorMatrixEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ColorMatrixEffect.cs
index c510d12e094..f50dcab66c3 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ColorMatrixEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ColorMatrixEffect.cs
@@ -3,8 +3,6 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
@@ -16,7 +14,6 @@ namespace System.Drawing.Imaging.Effects;
/// examples of using a color matrix to adjust the colors of an image.
///
///
-[RequiresPreviewFeatures]
public unsafe class ColorMatrixEffect : Effect
{
private readonly ColorMatrix _matrix;
@@ -35,5 +32,15 @@ public ColorMatrixEffect(ColorMatrix matrix) : base(PInvoke.ColorMatrixEffectGui
_matrix = matrix;
}
+
+ ///
+ /// The color transform matrix.
+ ///
+ ///
+ ///
+ /// is mutable, but effects do not support changing the matrix after creation.
+ ///
+ ///
+ public ColorMatrix Matrix => _matrix;
}
#endif
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ContrastEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ContrastCurveEffect.cs
similarity index 80%
rename from src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ContrastEffect.cs
rename to src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ContrastCurveEffect.cs
index 242061fd8eb..48305ed617d 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ContrastEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ContrastCurveEffect.cs
@@ -3,18 +3,15 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
/// Increases or decreases the contrast of an image.
///
-[RequiresPreviewFeatures]
-public class ContrastEffect : ColorCurveEffect
+public class ContrastCurveEffect : ColorCurveEffect
{
///
- /// Creates a new with the given adjustment value.
+ /// Creates a new with the given adjustment value.
///
/// The channel or channels that the effect is applied to.
///
@@ -22,7 +19,7 @@ public class ContrastEffect : ColorCurveEffect
/// specify increased contrast and negative values specify decreased contrast.
///
/// is less than -100 or greater than 100.
- public ContrastEffect(CurveChannel channel, int contrast)
+ public ContrastCurveEffect(CurveChannel channel, int contrast)
: base(CurveAdjustments.AdjustContrast, channel, contrast)
{
}
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/CurveChannel.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/CurveChannel.cs
index 8a75f401efe..de4fd779031 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/CurveChannel.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/CurveChannel.cs
@@ -13,21 +13,21 @@ public enum CurveChannel
///
/// Specifies that the color adjustment applies to all channels.
///
- CurveChannelAll = GdiPlus.CurveChannel.CurveChannelAll,
+ All = GdiPlus.CurveChannel.CurveChannelAll,
///
/// Specifies that the color adjustment applies only to the red channel.
///
- CurveChannelRed = GdiPlus.CurveChannel.CurveChannelRed,
+ Red = GdiPlus.CurveChannel.CurveChannelRed,
///
/// Specifies that the color adjustment applies only to the green channel.
///
- CurveChannelGreen = GdiPlus.CurveChannel.CurveChannelGreen,
+ Green = GdiPlus.CurveChannel.CurveChannelGreen,
///
/// Specifies that the color adjustment applies only to the blue channel.
///
- CurveChannelBlue = GdiPlus.CurveChannel.CurveChannelBlue
+ Blue = GdiPlus.CurveChannel.CurveChannelBlue
}
#endif
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/DensityEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/DensityCurveEffect.cs
similarity index 82%
rename from src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/DensityEffect.cs
rename to src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/DensityCurveEffect.cs
index bada8a7a9f5..cb1e2d647de 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/DensityEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/DensityCurveEffect.cs
@@ -3,18 +3,15 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
/// Simulates increasing or decreasing the film density of a photograph.
///
-[RequiresPreviewFeatures]
-public class DensityEffect : ColorCurveEffect
+public class DensityCurveEffect : ColorCurveEffect
{
///
- /// Creates a new with the given .
+ /// Creates a new with the given .
///
/// The channel or channels that the effect is applied to.
///
@@ -22,7 +19,7 @@ public class DensityEffect : ColorCurveEffect
/// increased density (lighter picture) and negative values specify decreased density (darker picture).
///
/// is less than -256 or greater than 256.
- public DensityEffect(CurveChannel channel, int density)
+ public DensityCurveEffect(CurveChannel channel, int density)
: base(CurveAdjustments.AdjustDensity, channel, density)
{
}
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/Effect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/Effect.cs
index 9c15f5e661e..5510ee888a0 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/Effect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/Effect.cs
@@ -3,21 +3,18 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
/// Base class for all effects.
///
-[RequiresPreviewFeatures]
public unsafe abstract class Effect : IDisposable
{
private CGpEffect* _nativeEffect;
internal CGpEffect* NativeEffect => _nativeEffect;
- protected Effect(Guid guid)
+ private protected Effect(Guid guid)
{
CGpEffect* nativeEffect;
PInvoke.GdipCreateEffect(guid, &nativeEffect).ThrowIfFailed();
@@ -41,7 +38,7 @@ private protected void SetParameters(ref T parameters) where T : unmanaged
~Effect() => Dispose(disposing: false);
- private void Dispose(bool disposing)
+ public virtual void Dispose(bool disposing)
{
if (_nativeEffect is not null)
{
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ExposureEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ExposureCurveEffect.cs
similarity index 80%
rename from src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ExposureEffect.cs
rename to src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ExposureCurveEffect.cs
index eeb425817a6..d318124bd99 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ExposureEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ExposureCurveEffect.cs
@@ -3,18 +3,15 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
/// Simulates increasing or decreasing the exposure of a photograph
///
-[RequiresPreviewFeatures]
-public class ExposureEffect : ColorCurveEffect
+public class ExposureCurveEffect : ColorCurveEffect
{
///
- /// Creates a new with the given adjustment.
+ /// Creates a new with the given adjustment.
///
/// The channel or channels that the effect is applied to.
///
@@ -22,7 +19,7 @@ public class ExposureEffect : ColorCurveEffect
/// specify increased exposure and negative values specify decreased exposure.
///
/// is less than -256 or greater than 256.
- public ExposureEffect(CurveChannel channel, int exposure)
+ public ExposureCurveEffect(CurveChannel channel, int exposure)
: base(CurveAdjustments.AdjustExposure, channel, exposure)
{
}
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/GrayScaleEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/GrayScaleEffect.cs
index 36e121336c9..9802c10cd7c 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/GrayScaleEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/GrayScaleEffect.cs
@@ -3,14 +3,11 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
/// Effect that converts an image to grayscale.
///
-[RequiresPreviewFeatures]
public sealed class GrayScaleEffect : ColorMatrixEffect
{
public GrayScaleEffect() : base(
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/HighlightEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/HighlightCurveEffect.cs
similarity index 81%
rename from src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/HighlightEffect.cs
rename to src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/HighlightCurveEffect.cs
index bc0a4094a98..c8a6c60abfd 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/HighlightEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/HighlightCurveEffect.cs
@@ -3,8 +3,6 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
@@ -12,18 +10,17 @@ namespace System.Drawing.Imaging.Effects;
/// intensity. You can use this effect to get more definition in the light areas of an image without affecting
/// the dark areas.
///
-[RequiresPreviewFeatures]
-public class HighlightEffect : ColorCurveEffect
+public class HighlightCurveEffect : ColorCurveEffect
{
///
- /// Creates a new with the given adjustment.
+ /// Creates a new with the given adjustment.
///
/// The channel or channels that the effect is applied to.
///
/// A value in the range of -100 through 100. A value of 0 specifies no change. Positive values specify that the
/// light areas are made lighter, and negative values specify that the light areas are made darker.
///
- public HighlightEffect(CurveChannel channel, int highlight)
+ public HighlightCurveEffect(CurveChannel channel, int highlight)
: base(CurveAdjustments.AdjustHighlight, channel, highlight)
{
}
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/InvertEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/InvertEffect.cs
index 40b05c8a694..bb7cb6cad3f 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/InvertEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/InvertEffect.cs
@@ -3,14 +3,11 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
/// Effect that inverts the colors in an image.
///
-[RequiresPreviewFeatures]
public sealed class InvertEffect : ColorMatrixEffect
{
public InvertEffect() : base(
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/LevelsEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/LevelsEffect.cs
index 5f66bdaf23b..4eddd9ce7ca 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/LevelsEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/LevelsEffect.cs
@@ -3,14 +3,11 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
-/// Adjusts the light, midtone, or dark areas of an image.
+/// Adjusts the light, mid-tone, or dark areas of an image.
///
-[RequiresPreviewFeatures]
public class LevelsEffect : Effect
{
private readonly LevelsParams _levelsParams;
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/MidtoneEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/MidtoneCurveEffect.cs
similarity index 84%
rename from src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/MidtoneEffect.cs
rename to src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/MidtoneCurveEffect.cs
index 6fd97dd5d73..9453219edbf 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/MidtoneEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/MidtoneCurveEffect.cs
@@ -3,8 +3,6 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
@@ -12,11 +10,10 @@ namespace System.Drawing.Imaging.Effects;
/// color channel values near the minimum or maximum intensity. You can use this effect to lighten (or darken)
/// an image without loosing the contrast between the darkest and lightest portions of the image.
///
-[RequiresPreviewFeatures]
-public class MidtoneEffect : ColorCurveEffect
+public class MidtoneCurveEffect : ColorCurveEffect
{
///
- /// Creates a new with the given adjustment.
+ /// Creates a new with the given adjustment.
///
/// The channel or channels that the effect is applied to.
///
@@ -24,7 +21,7 @@ public class MidtoneEffect : ColorCurveEffect
/// mid-tones are made lighter, and negative values specify that the mid-tones are made darker.
///
/// is less than -100 or greater than 100.
- public MidtoneEffect(CurveChannel channel, int midtone)
+ public MidtoneCurveEffect(CurveChannel channel, int midtone)
: base(CurveAdjustments.AdjustMidtone, channel, midtone)
{
}
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/SepiaEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/SepiaEffect.cs
index 9bfd7d60be5..6a941f3208e 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/SepiaEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/SepiaEffect.cs
@@ -3,14 +3,11 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
/// Effect that converts an image to sepia.
///
-[RequiresPreviewFeatures]
public sealed class SepiaEffect : ColorMatrixEffect
{
public SepiaEffect() : base(
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ShadowEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ShadowCurveEffect.cs
similarity index 84%
rename from src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ShadowEffect.cs
rename to src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ShadowCurveEffect.cs
index e0417c29671..c80a244b5cb 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ShadowEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/ShadowCurveEffect.cs
@@ -3,8 +3,6 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
@@ -12,11 +10,10 @@ namespace System.Drawing.Imaging.Effects;
/// intensity. You can use this effect to get more definition in the dark areas of an image without affecting
/// the light areas.
///
-[RequiresPreviewFeatures]
-public class ShadowEffect : ColorCurveEffect
+public class ShadowCurveEffect : ColorCurveEffect
{
///
- /// Creates a new with the given .
+ /// Creates a new with the given .
///
/// The channel or channels that the effect is applied to.
///
@@ -24,7 +21,7 @@ public class ShadowEffect : ColorCurveEffect
/// dark areas are made lighter, and negative values specify that the dark areas are made darker.
///
/// is less than -100 or greater than 100.
- public ShadowEffect(CurveChannel channel, int shadow)
+ public ShadowCurveEffect(CurveChannel channel, int shadow)
: base(CurveAdjustments.AdjustShadow, channel, shadow)
{
}
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/SharpenEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/SharpenEffect.cs
index 534b733c66f..37beae8386c 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/SharpenEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/SharpenEffect.cs
@@ -3,14 +3,11 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
/// Sharpens an image.
///
-[RequiresPreviewFeatures]
public unsafe class SharpenEffect : Effect
{
private readonly SharpenParams _sharpenParams;
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/TintEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/TintEffect.cs
index bc11c8d1c58..1aed7ec0271 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/TintEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/TintEffect.cs
@@ -3,14 +3,11 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
/// Allows you to apply a tint to an image.
///
-[RequiresPreviewFeatures]
public unsafe class TintEffect : Effect
{
private readonly TintParams _tintParams;
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/VividEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/VividEffect.cs
index 9c69119e4cd..1d9260a1492 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/VividEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/VividEffect.cs
@@ -3,14 +3,11 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
/// Effect that makes colors more vivid.
///
-[RequiresPreviewFeatures]
public sealed class VividEffect : ColorMatrixEffect
{
public VividEffect() : base(
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/WhiteSaturationEffect.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/WhiteSaturationCurveEffect.cs
similarity index 85%
rename from src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/WhiteSaturationEffect.cs
rename to src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/WhiteSaturationCurveEffect.cs
index 60fb1feb2b3..767b7621d42 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/WhiteSaturationEffect.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/Effects/WhiteSaturationCurveEffect.cs
@@ -3,19 +3,16 @@
#if NET9_0_OR_GREATER
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects;
///
/// Sets the white saturation of an image. The white saturation is the point at which the lightest areas of the image
/// are converted to white.
///
-[RequiresPreviewFeatures]
-public class WhiteSaturationEffect : ColorCurveEffect
+public class WhiteSaturationCurveEffect : ColorCurveEffect
{
///
- /// Creates a new with the given parameters.
+ /// Creates a new with the given parameters.
///
/// The channel or channels that the effect is applied to.
///
@@ -24,7 +21,7 @@ public class WhiteSaturationEffect : ColorCurveEffect
/// so that they spread out over the interval [0, 255]. Color channel values greater than 240 are set to 255.
///
/// was less than 1 or greater than 255.
- public WhiteSaturationEffect(CurveChannel channel, int whiteSaturation)
+ public WhiteSaturationCurveEffect(CurveChannel channel, int whiteSaturation)
: base(CurveAdjustments.AdjustWhiteSaturation, channel, whiteSaturation)
{
}
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/ImageAttributes.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/ImageAttributes.cs
index 465db667858..4bc968a51f7 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/ImageAttributes.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/ImageAttributes.cs
@@ -4,6 +4,9 @@
using System.Runtime.InteropServices;
using System.IO;
using System.Runtime.CompilerServices;
+#if NET9_0_OR_GREATER
+using System.ComponentModel;
+#endif
namespace System.Drawing.Imaging;
@@ -341,12 +344,15 @@ public void ClearOutputChannelColorProfile(ColorAdjustType type)
}
///
- public void SetRemapTable(ColorMap[] map) => SetRemapTable(map, ColorAdjustType.Default);
+ public void SetRemapTable(params ColorMap[] map) => SetRemapTable(map, ColorAdjustType.Default);
///
/// Sets the default color-remap table.
///
///
+#if NET9_0_OR_GREATER
+ [EditorBrowsable(EditorBrowsableState.Never)]
+#endif
public void SetRemapTable(ColorMap[] map, ColorAdjustType type)
{
ArgumentNullException.ThrowIfNull(map);
@@ -358,7 +364,7 @@ public void SetRemapTable(ColorMap[] map, ColorAdjustType type)
public void SetRemapTable(ReadOnlySpan map) => SetRemapTable(ColorAdjustType.Default, map);
///
- public void SetRemapTable(ReadOnlySpan map) => SetRemapTable(ColorAdjustType.Default, map);
+ public void SetRemapTable(ReadOnlySpan<(Color OldColor, Color NewColor)> map) => SetRemapTable(ColorAdjustType.Default, map);
#endif
///
@@ -403,7 +409,7 @@ void SetRemapTable(ColorAdjustType type, ReadOnlySpan map)
#if NET9_0_OR_GREATER
///
- public void SetRemapTable(ColorAdjustType type, ReadOnlySpan map)
+ public void SetRemapTable(ColorAdjustType type, ReadOnlySpan<(Color OldColor, Color NewColor)> map)
{
StackBuffer stackBuffer = default;
using BufferScope<(ARGB, ARGB)> buffer = new(stackBuffer, map.Length);
@@ -447,10 +453,12 @@ public void ClearRemapTable(ColorAdjustType type)
GC.KeepAlive(this);
}
- public void SetBrushRemapTable(ColorMap[] map) => SetRemapTable(map, ColorAdjustType.Brush);
+ public void SetBrushRemapTable(params ColorMap[] map) => SetRemapTable(map, ColorAdjustType.Brush);
#if NET9_0_OR_GREATER
public void SetBrushRemapTable(ReadOnlySpan map) => SetRemapTable(ColorAdjustType.Brush, map);
+
+ public void SetBrushRemapTable(ReadOnlySpan<(Color OldColor, Color NewColor)> map) => SetRemapTable(ColorAdjustType.Brush, map);
#endif
public void ClearBrushRemapTable() => ClearRemapTable(ColorAdjustType.Brush);
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/ImageLockMode.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/ImageLockMode.cs
index ed068239c4b..79661d98696 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/ImageLockMode.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/ImageLockMode.cs
@@ -1,28 +1,30 @@
-// Licensed to the .NET Foundation under one or more agreements.
+// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
namespace System.Drawing.Imaging;
-// Access modes used when calling IImage::LockBits
///
-/// Indicates the access mode for an .
+/// Indicates the access mode for an .
///
public enum ImageLockMode
{
///
- /// Specifies the image is read-only.
+ /// Specifies the image is read-only.
///
- ReadOnly = 0x0001,
+ ReadOnly = GdiPlus.ImageLockMode.ImageLockModeRead,
+
///
- /// Specifies the image is write-only.
+ /// Specifies the image is write-only.
///
- WriteOnly = 0x0002,
+ WriteOnly = GdiPlus.ImageLockMode.ImageLockModeWrite,
+
///
- /// Specifies the image is read-write.
+ /// Specifies the image is read-write.
///
ReadWrite = ReadOnly | WriteOnly,
+
///
- /// Indicates the image resides in a user input buffer, to which the user controls access.
+ /// Indicates the image resides in a user input buffer, to which the user controls access.
///
- UserInputBuffer = 0x0004,
+ UserInputBuffer = GdiPlus.ImageLockMode.ImageLockModeUserInputBuf
}
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/PixelFormat.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/PixelFormat.cs
index 4986a7c75bc..d9907797e66 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/PixelFormat.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Imaging/PixelFormat.cs
@@ -8,124 +8,72 @@ namespace System.Drawing.Imaging;
///
public enum PixelFormat
{
- ///
- /// Specifies that pixel data contains color indexed values which means they are an index to colors in the
- /// system color table, as opposed to individual color values.
- ///
- Indexed = (int)PInvoke.PixelFormatIndexed,
-
- ///
- /// Specifies that pixel data contains GDI colors.
- ///
- Gdi = (int)PInvoke.PixelFormatGDI,
-
- ///
- /// Specifies that pixel data contains alpha values that are not pre-multiplied.
- ///
- Alpha = (int)PInvoke.PixelFormatAlpha,
-
- ///
- /// Specifies that pixel format contains pre-multiplied alpha values.
- ///
- PAlpha = (int)PInvoke.PixelFormatPAlpha,
-
- ///
- /// Specifies that pixel format contains extended color values of 16 bits per channel.
- ///
- Extended = (int)PInvoke.PixelFormatExtended,
-
- Canonical = (int)PInvoke.PixelFormatCanonical,
-
- ///
- /// Specifies that pixel format is undefined.
- ///
- Undefined = (int)PInvoke.PixelFormatUndefined,
-
- ///
- /// Specifies that pixel format doesn't matter.
- ///
- DontCare = (int)PInvoke.PixelFormatDontCare,
-
- ///
- /// Specifies that pixel format is 1 bit per pixel indexed color. The color table therefore has two colors in it.
- ///
- Format1bppIndexed = 1 | (1 << 8) | Indexed | Gdi,
-
- ///
- /// Specifies that pixel format is 4 bits per pixel indexed color. The color table therefore has 16 colors in it.
- ///
- Format4bppIndexed = 2 | (4 << 8) | Indexed | Gdi,
-
- ///
- /// Specifies that pixel format is 8 bits per pixel indexed color. The color table therefore has 256 colors in it.
- ///
- Format8bppIndexed = 3 | (8 << 8) | Indexed | Gdi,
-
- ///
- /// Specifies that pixel format is 16 bits per pixel. The color information specifies 65536 shades of gray.
- ///
- Format16bppGrayScale = 4 | (16 << 8) | Extended,
-
- ///
- /// Specifies that pixel format is 16 bits per pixel. The color information specifies 32768 shades of color of
- /// which 5 bits are red, 5 bits are green and 5 bits are blue.
- ///
- Format16bppRgb555 = 5 | (16 << 8) | Gdi,
-
- Format16bppRgb565 = 6 | (16 << 8) | Gdi,
-
- ///
- /// Specifies that pixel format is 16 bits per pixel. The color information specifies 32768 shades of color of
- /// which 5 bits are red, 5 bits are green, 5 bits are blue and 1 bit is alpha.
- ///
- Format16bppArgb1555 = 7 | (16 << 8) | Alpha | Gdi,
-
- ///
- /// Specifies that pixel format is 24 bits per pixel. The color information specifies 16777216 shades of color
- /// of which 8 bits are red, 8 bits are green and 8 bits are blue.
- ///
- Format24bppRgb = 8 | (24 << 8) | Gdi,
-
- ///
- /// Specifies that pixel format is 24 bits per pixel. The color information specifies 16777216 shades of color
- /// of which 8 bits are red, 8 bits are green and 8 bits are blue.
- ///
- Format32bppRgb = 9 | (32 << 8) | Gdi,
-
- ///
- /// Specifies that pixel format is 32 bits per pixel. The color information specifies 16777216 shades of color
- /// of which 8 bits are red, 8 bits are green and 8 bits are blue. The 8 additional bits are alpha bits.
- ///
- Format32bppArgb = 10 | (32 << 8) | Alpha | Gdi | Canonical,
-
- ///
- /// Specifies that pixel format is 32 bits per pixel. The color information specifies 16777216 shades of color
- /// of which 8 bits are red, 8 bits are green and 8 bits are blue. The 8 additional bits are pre-multiplied alpha bits.
- ///
- Format32bppPArgb = 11 | (32 << 8) | Alpha | PAlpha | Gdi,
-
- ///
- /// Specifies that pixel format is 48 bits per pixel. The color information specifies 16777216 shades of color
- /// of which 8 bits are red, 8 bits are green and 8 bits are blue. The 8 additional bits are alpha bits.
- ///
- Format48bppRgb = 12 | (48 << 8) | Extended,
-
- ///
- /// Specifies pixel format is 64 bits per pixel. The color information specifies 16777216 shades of color of
- /// which 16 bits are red, 16 bits are green and 16 bits are blue. The 16 additional bits are alpha bits.
- ///
- Format64bppArgb = 13 | (64 << 8) | Alpha | Canonical | Extended,
-
- ///
- /// Specifies that pixel format is 64 bits per pixel. The color information specifies 16777216 shades of color
- /// of which 16 bits are red, 16 bits are green and 16 bits are blue. The 16 additional bits are pre-multiplied
- /// alpha bits.
- ///
- Format64bppPArgb = 14 | (64 << 8) | Alpha | PAlpha | Extended,
-
- ///
- /// Specifies that pixel format is 64 bits per pixel. The color information specifies 16777216 shades of color
- /// of which 16 bits are red, 16 bits are green and 16 bits are blue. The 16 additional bits are alpha bits.
- ///
- Max = 15,
+ ///
+ Indexed = GdiPlus.PixelFormat.Indexed,
+
+ ///
+ Gdi = GdiPlus.PixelFormat.Gdi,
+
+ ///
+ Alpha = GdiPlus.PixelFormat.Alpha,
+
+ ///
+ PAlpha = GdiPlus.PixelFormat.PAlpha,
+
+ ///
+ Extended = GdiPlus.PixelFormat.Extended,
+
+ ///
+ Canonical = GdiPlus.PixelFormat.Canonical,
+
+ ///
+ Undefined = GdiPlus.PixelFormat.Undefined,
+
+ ///
+ DontCare = GdiPlus.PixelFormat.DontCare,
+
+ ///
+ Format1bppIndexed = GdiPlus.PixelFormat.Format1bppIndexed,
+
+ ///
+ Format4bppIndexed = GdiPlus.PixelFormat.Format4bppIndexed,
+
+ ///
+ Format8bppIndexed = GdiPlus.PixelFormat.Format8bppIndexed,
+
+ ///
+ Format16bppGrayScale = GdiPlus.PixelFormat.Format16bppGrayScale,
+
+ ///
+ Format16bppRgb555 = GdiPlus.PixelFormat.Format16bppRgb555,
+
+ ///
+ Format16bppRgb565 = GdiPlus.PixelFormat.Format16bppRgb565,
+
+ ///
+ Format16bppArgb1555 = GdiPlus.PixelFormat.Format16bppArgb1555,
+
+ ///
+ Format24bppRgb = GdiPlus.PixelFormat.Format24bppRgb,
+
+ ///
+ Format32bppRgb = GdiPlus.PixelFormat.Format32bppRgb,
+
+ ///
+ Format32bppArgb = GdiPlus.PixelFormat.Format32bppArgb,
+
+ ///
+ Format32bppPArgb = GdiPlus.PixelFormat.Format32bppPArgb,
+
+ ///
+ Format48bppRgb = GdiPlus.PixelFormat.Format48bppRgb,
+
+ ///
+ Format64bppArgb = GdiPlus.PixelFormat.Format64bppArgb,
+
+ ///
+ Format64bppPArgb = GdiPlus.PixelFormat.Format64bppPArgb,
+
+ ///
+ Max = GdiPlus.PixelFormat.Max,
}
diff --git a/src/System.Drawing.Common/src/System/Drawing/Imaging/ValueColorMap.cs b/src/System.Drawing.Common/src/System/Drawing/Imaging/ValueColorMap.cs
deleted file mode 100644
index 42794b554eb..00000000000
--- a/src/System.Drawing.Common/src/System/Drawing/Imaging/ValueColorMap.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-// Licensed to the .NET Foundation under one or more agreements.
-// The .NET Foundation licenses this file to you under the MIT license.
-
-namespace System.Drawing.Imaging;
-#if NET9_0_OR_GREATER
-///
-/// Defines a map for converting colors.
-///
-/// Specifies the existing to be converted.
-/// Specifies the new to which to convert.
-public readonly record struct ValueColorMap(Color OldColor, Color NewColor);
-#endif
diff --git a/src/System.Drawing.Common/src/System/Drawing/PointerExtensions.cs b/src/System.Drawing.Common/src/System/Drawing/PointerExtensions.cs
index 6de168f5c8e..736b7fef876 100644
--- a/src/System.Drawing.Common/src/System/Drawing/PointerExtensions.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/PointerExtensions.cs
@@ -4,7 +4,6 @@
using System.Drawing.Imaging;
#if NET9_0_OR_GREATER
using System.Drawing.Imaging.Effects;
-using System.Runtime.Versioning;
#endif
namespace System.Drawing;
@@ -24,7 +23,6 @@ internal static unsafe class PointerExtensions
public static GpMetafile* Pointer(this Metafile? metafile) => metafile is null ? null : (GpMetafile*)((Image)metafile).Pointer();
public static GpImage* Pointer(this Image? image) => image is null ? null : ((IPointer)image).Pointer;
#if NET9_0_OR_GREATER
- [RequiresPreviewFeatures]
public static CGpEffect* Pointer(this Effect? effect) => effect is null ? null : effect.NativeEffect;
#endif
}
diff --git a/src/System.Drawing.Common/src/System/Drawing/Printing/PrinterSettings.StringCollection.cs b/src/System.Drawing.Common/src/System/Drawing/Printing/PrinterSettings.StringCollection.cs
index cfc973818ec..15dc585aa9c 100644
--- a/src/System.Drawing.Common/src/System/Drawing/Printing/PrinterSettings.StringCollection.cs
+++ b/src/System.Drawing.Common/src/System/Drawing/Printing/PrinterSettings.StringCollection.cs
@@ -8,7 +8,7 @@ namespace System.Drawing.Printing;
public partial class PrinterSettings
{
- public class StringCollection : ICollection, IReadOnlyList
+ public class StringCollection : ICollection, IEnumerable
{
private readonly List _list;
diff --git a/src/System.Drawing.Common/tests/Helpers.cs b/src/System.Drawing.Common/tests/Helpers.cs
index 5f23e83d0e2..974d0f0a343 100644
--- a/src/System.Drawing.Common/tests/Helpers.cs
+++ b/src/System.Drawing.Common/tests/Helpers.cs
@@ -13,7 +13,7 @@ namespace System.Drawing;
public unsafe static class Helpers
{
// This MUST come before s_anyInstalledPrinters. Caching for performance in tests.
- public static IReadOnlyList InstalledPrinters { get; } = PrinterSettings.InstalledPrinters;
+ public static PrinterSettings.StringCollection InstalledPrinters { get; } = PrinterSettings.InstalledPrinters;
private static bool s_anyInstalledPrinters = InstalledPrinters.Count > 0;
diff --git a/src/System.Drawing.Common/tests/System/Drawing/Imaging/Effects/EffectsTests.cs b/src/System.Drawing.Common/tests/System/Drawing/Imaging/Effects/EffectsTests.cs
index 460dd31b565..a35ed6b6b6f 100644
--- a/src/System.Drawing.Common/tests/System/Drawing/Imaging/Effects/EffectsTests.cs
+++ b/src/System.Drawing.Common/tests/System/Drawing/Imaging/Effects/EffectsTests.cs
@@ -1,11 +1,8 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
-using System.Runtime.Versioning;
-
namespace System.Drawing.Imaging.Effects.Tests;
-[RequiresPreviewFeatures]
public class EffectsTests
{
[Fact]
@@ -23,18 +20,18 @@ public void SepiaEffect_Apply()
}
[Theory]
- [InlineData(CurveChannel.CurveChannelAll, 0)]
- [InlineData(CurveChannel.CurveChannelRed, 0)]
- [InlineData(CurveChannel.CurveChannelGreen, 0)]
- [InlineData(CurveChannel.CurveChannelBlue, 0)]
- [InlineData(CurveChannel.CurveChannelAll, 254)]
- [InlineData(CurveChannel.CurveChannelRed, 254)]
- [InlineData(CurveChannel.CurveChannelGreen, 254)]
- [InlineData(CurveChannel.CurveChannelBlue, 254)]
+ [InlineData(CurveChannel.All, 0)]
+ [InlineData(CurveChannel.Red, 0)]
+ [InlineData(CurveChannel.Green, 0)]
+ [InlineData(CurveChannel.Blue, 0)]
+ [InlineData(CurveChannel.All, 254)]
+ [InlineData(CurveChannel.Red, 254)]
+ [InlineData(CurveChannel.Green, 254)]
+ [InlineData(CurveChannel.Blue, 254)]
public void BlackSaturationEffect_Apply(CurveChannel channel, int blackPoint)
{
using Bitmap bitmap = new(10, 10);
- using BlackSaturationEffect effect = new(channel, blackPoint);
+ using BlackSaturationCurveEffect effect = new(channel, blackPoint);
bitmap.ApplyEffect(effect);
}
@@ -43,23 +40,23 @@ public void BlackSaturationEffect_Apply(CurveChannel channel, int blackPoint)
[InlineData(255)]
public void BlackSaturationEffect_Apply_Invalid(int blackPoint)
{
- Action action = () => _ = new BlackSaturationEffect(CurveChannel.CurveChannelAll, blackPoint);
+ Action action = () => _ = new BlackSaturationCurveEffect(CurveChannel.All, blackPoint);
action.Should().Throw();
}
[Theory]
- [InlineData(CurveChannel.CurveChannelAll, 1)]
- [InlineData(CurveChannel.CurveChannelRed, 1)]
- [InlineData(CurveChannel.CurveChannelGreen, 1)]
- [InlineData(CurveChannel.CurveChannelBlue, 1)]
- [InlineData(CurveChannel.CurveChannelAll, 255)]
- [InlineData(CurveChannel.CurveChannelRed, 255)]
- [InlineData(CurveChannel.CurveChannelGreen, 255)]
- [InlineData(CurveChannel.CurveChannelBlue, 255)]
+ [InlineData(CurveChannel.All, 1)]
+ [InlineData(CurveChannel.Red, 1)]
+ [InlineData(CurveChannel.Green, 1)]
+ [InlineData(CurveChannel.Blue, 1)]
+ [InlineData(CurveChannel.All, 255)]
+ [InlineData(CurveChannel.Red, 255)]
+ [InlineData(CurveChannel.Green, 255)]
+ [InlineData(CurveChannel.Blue, 255)]
public void WhiteSaturationEffect_Apply(CurveChannel channel, int whitePoint)
{
using Bitmap bitmap = new(10, 10);
- using WhiteSaturationEffect effect = new(channel, whitePoint);
+ using WhiteSaturationCurveEffect effect = new(channel, whitePoint);
bitmap.ApplyEffect(effect);
}
@@ -69,7 +66,7 @@ public void WhiteSaturationEffect_Apply(CurveChannel channel, int whitePoint)
[InlineData(256)]
public void WhiteSaturationEffect_Apply_Invalid(int whitePoint)
{
- Action action = () => _ = new WhiteSaturationEffect(CurveChannel.CurveChannelAll, whitePoint);
+ Action action = () => _ = new WhiteSaturationCurveEffect(CurveChannel.All, whitePoint);
action.Should().Throw();
}
@@ -186,11 +183,38 @@ public void ColorLookupTableEffect_Apply(byte tableValue)
Span buffer = stackalloc byte[256];
buffer.Fill(tableValue);
using ColorLookupTableEffect effect = new(buffer, buffer, buffer, buffer);
+
+ effect.AlphaLookupTable.Length.Should().Be(256);
+ effect.AlphaLookupTable.Span[0].Should().Be(tableValue);
+ effect.AlphaLookupTable.Span[255].Should().Be(tableValue);
+ effect.BlueLookupTable.Length.Should().Be(256);
+ effect.BlueLookupTable.Span[0].Should().Be(tableValue);
+ effect.BlueLookupTable.Span[255].Should().Be(tableValue);
+ effect.GreenLookupTable.Length.Should().Be(256);
+ effect.GreenLookupTable.Span[0].Should().Be(tableValue);
+ effect.GreenLookupTable.Span[255].Should().Be(tableValue);
+ effect.RedLookupTable.Length.Should().Be(256);
+ effect.RedLookupTable.Span[0].Should().Be(tableValue);
+ effect.RedLookupTable.Span[255].Should().Be(tableValue);
+
bitmap.ApplyEffect(effect);
// The final values will be padded with zeros
using ColorLookupTableEffect effect2 = new(buffer[..100], buffer[..1], buffer, buffer);
bitmap.ApplyEffect(effect);
+
+ effect2.RedLookupTable.Length.Should().Be(256);
+ effect2.RedLookupTable.Span[0].Should().Be(tableValue);
+ effect2.RedLookupTable.Span[255].Should().Be(0);
+ effect2.GreenLookupTable.Length.Should().Be(256);
+ effect2.GreenLookupTable.Span[0].Should().Be(tableValue);
+ effect2.GreenLookupTable.Span[255].Should().Be(0);
+ effect2.BlueLookupTable.Length.Should().Be(256);
+ effect2.BlueLookupTable.Span[0].Should().Be(tableValue);
+ effect2.BlueLookupTable.Span[255].Should().Be(tableValue);
+ effect2.AlphaLookupTable.Length.Should().Be(256);
+ effect2.AlphaLookupTable.Span[0].Should().Be(tableValue);
+ effect2.AlphaLookupTable.Span[255].Should().Be(tableValue);
}
[Fact]
@@ -227,7 +251,7 @@ public void ColorMatrixEffect_Apply(float value)
public void ContrastEffect_Apply(int contrast)
{
using Bitmap bitmap = new(10, 10);
- using ContrastEffect effect = new(CurveChannel.CurveChannelAll, contrast);
+ using ContrastCurveEffect effect = new(CurveChannel.All, contrast);
bitmap.ApplyEffect(effect);
}
@@ -236,7 +260,7 @@ public void ContrastEffect_Apply(int contrast)
[InlineData(101)]
public void ContrastEffect_Apply_Invalid(int contrast)
{
- Action action = () => _ = new ContrastEffect(CurveChannel.CurveChannelAll, contrast);
+ Action action = () => _ = new ContrastCurveEffect(CurveChannel.All, contrast);
action.Should().Throw();
}
@@ -247,7 +271,7 @@ public void ContrastEffect_Apply_Invalid(int contrast)
public void DensityEffect_Apply(int density)
{
using Bitmap bitmap = new(10, 10);
- using DensityEffect effect = new(CurveChannel.CurveChannelAll, density);
+ using DensityCurveEffect effect = new(CurveChannel.All, density);
bitmap.ApplyEffect(effect);
}
@@ -256,7 +280,7 @@ public void DensityEffect_Apply(int density)
[InlineData(257)]
public void DensityEffect_Apply_Invalid(int density)
{
- Action action = () => _ = new DensityEffect(CurveChannel.CurveChannelAll, density);
+ Action action = () => _ = new DensityCurveEffect(CurveChannel.All, density);
action.Should().Throw();
}
@@ -267,7 +291,7 @@ public void DensityEffect_Apply_Invalid(int density)
public void ExposureEffect_Apply(int exposure)
{
using Bitmap bitmap = new(10, 10);
- using ExposureEffect effect = new(CurveChannel.CurveChannelAll, exposure);
+ using ExposureCurveEffect effect = new(CurveChannel.All, exposure);
bitmap.ApplyEffect(effect);
}
@@ -276,7 +300,7 @@ public void ExposureEffect_Apply(int exposure)
[InlineData(257)]
public void ExposureEffect_Apply_Invalid(int exposure)
{
- Action action = () => _ = new ExposureEffect(CurveChannel.CurveChannelAll, exposure);
+ Action action = () => _ = new ExposureCurveEffect(CurveChannel.All, exposure);
action.Should().Throw();
}
@@ -287,7 +311,7 @@ public void ExposureEffect_Apply_Invalid(int exposure)
public void HighlightEffect_Apply(int highlight)
{
using Bitmap bitmap = new(10, 10);
- using HighlightEffect effect = new(CurveChannel.CurveChannelAll, highlight);
+ using HighlightCurveEffect effect = new(CurveChannel.All, highlight);
bitmap.ApplyEffect(effect);
}
@@ -296,7 +320,7 @@ public void HighlightEffect_Apply(int highlight)
[InlineData(101)]
public void HighlightEffect_Apply_Invalid(int highlight)
{
- Action action = () => _ = new HighlightEffect(CurveChannel.CurveChannelAll, highlight);
+ Action action = () => _ = new HighlightCurveEffect(CurveChannel.All, highlight);
action.Should().Throw();
}
@@ -307,7 +331,7 @@ public void HighlightEffect_Apply_Invalid(int highlight)
public void MidtoneEffect_Apply(int midtone)
{
using Bitmap bitmap = new(10, 10);
- using MidtoneEffect effect = new(CurveChannel.CurveChannelAll, midtone);
+ using MidtoneCurveEffect effect = new(CurveChannel.All, midtone);
bitmap.ApplyEffect(effect);
}
@@ -316,7 +340,7 @@ public void MidtoneEffect_Apply(int midtone)
[InlineData(101)]
public void MidtoneEffect_Apply_Invalid(int midtone)
{
- Action action = () => _ = new MidtoneEffect(CurveChannel.CurveChannelAll, midtone);
+ Action action = () => _ = new MidtoneCurveEffect(CurveChannel.All, midtone);
action.Should().Throw();
}
@@ -327,7 +351,7 @@ public void MidtoneEffect_Apply_Invalid(int midtone)
public void ShadowEffect_Apply(int shadow)
{
using Bitmap bitmap = new(10, 10);
- using ShadowEffect effect = new(CurveChannel.CurveChannelAll, shadow);
+ using ShadowCurveEffect effect = new(CurveChannel.All, shadow);
bitmap.ApplyEffect(effect);
}
@@ -336,7 +360,7 @@ public void ShadowEffect_Apply(int shadow)
[InlineData(101)]
public void ShadowEffect_Apply_Invalid(int shadow)
{
- Action action = () => _ = new ShadowEffect(CurveChannel.CurveChannelAll, shadow);
+ Action action = () => _ = new ShadowCurveEffect(CurveChannel.All, shadow);
action.Should().Throw();
}
diff --git a/src/System.Drawing.Common/tests/mono/System.Drawing/BitmapTests.cs b/src/System.Drawing.Common/tests/mono/System.Drawing/BitmapTests.cs
index 4b6cfde2307..c584e4413ee 100644
--- a/src/System.Drawing.Common/tests/mono/System.Drawing/BitmapTests.cs
+++ b/src/System.Drawing.Common/tests/mono/System.Drawing/BitmapTests.cs
@@ -389,7 +389,8 @@ public string RotateBmp(Bitmap src, RotateFlipType rotate)
}
}
- hash = MD5.Create().ComputeHash(pixels);
+ // cs/weak-crypto
+ hash = MD5.Create().ComputeHash(pixels); // CodeQL [SM02196] This hash is used in test to compare two bitmaps.
return ByteArrayToString(hash);
}
diff --git a/src/System.Private.Windows.Core/src/NativeMethods.txt b/src/System.Private.Windows.Core/src/NativeMethods.txt
index 86b41eb0cd7..e7a4cfb28b1 100644
--- a/src/System.Private.Windows.Core/src/NativeMethods.txt
+++ b/src/System.Private.Windows.Core/src/NativeMethods.txt
@@ -60,15 +60,19 @@ EncoderParameters
fdex*
FDEX_PROP_FLAGS
FILETIME
+GdipBitmapLockBits
+GdipBitmapUnlockBits
GdipCreateFromHWND
GdipDeleteGraphics
+GdipGetImageBounds
GdipGetImageEncoders
GdipGetImageEncodersSize
+GdipGetImagePixelFormat
GdipGetImageRawFormat
GdipGetRegionHRgn
GdipIsInfiniteRegion
-GetClientRect
GdipSaveImageToStream
+GetClientRect
GetClipRgn
GetDC
GetDCEx
@@ -94,6 +98,7 @@ GlobalLock
GlobalReAlloc
GlobalSize
GlobalUnlock
+GpBitmap
GpGraphics
GpImage
GpRegion
@@ -116,6 +121,7 @@ IDI_*
IEnumUnknown
IGlobalInterfaceTable
ImageFormat*
+ImageLockMode
INPLACE_E_NOTOOLSPACE
IntersectClipRect
IStream
@@ -138,12 +144,13 @@ OLE_E_ADVISENOTSUPPORTED
OLE_E_INVALIDRECT
OLE_E_NOCONNECTION
OLE_E_PROMPTSAVECANCELLED
+PixelFormat*
POINTS
PRINTDLGEX_FLAGS
PropVariantClear
PWSTR
-Rect
RECT
+Rect
RectF
REGDB_E_CLASSNOTREG
ReleaseDC
diff --git a/src/System.Private.Windows.Core/src/Properties/AssemblyInfo.cs b/src/System.Private.Windows.Core/src/Properties/AssemblyInfo.cs
index fb2cfc5a402..7f66f0d08ee 100644
--- a/src/System.Private.Windows.Core/src/Properties/AssemblyInfo.cs
+++ b/src/System.Private.Windows.Core/src/Properties/AssemblyInfo.cs
@@ -31,6 +31,7 @@
[assembly: InternalsVisibleTo("NativeHost.ManagedControl, PublicKey=00000000000000000400000000000000")]
[assembly: InternalsVisibleTo("MauiToolStripTests, PublicKey=00000000000000000400000000000000")]
[assembly: InternalsVisibleTo("ScratchProjectWithInternals, PublicKey=00000000000000000400000000000000")]
+[assembly: InternalsVisibleTo("ComDisabled.Tests, PublicKey=00000000000000000400000000000000")]
// This is needed in order to Moq internal interfaces for testing
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
diff --git a/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/ArgumentValidation.cs b/src/System.Private.Windows.Core/src/System/ArgumentValidation.cs
similarity index 98%
rename from src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/ArgumentValidation.cs
rename to src/System.Private.Windows.Core/src/System/ArgumentValidation.cs
index 13253db3fd6..02a9ce63c4e 100644
--- a/src/System.Windows.Forms.Primitives/src/System/Windows/Forms/Internals/ArgumentValidation.cs
+++ b/src/System.Private.Windows.Core/src/System/ArgumentValidation.cs
@@ -3,7 +3,7 @@
using System.Runtime.CompilerServices;
-namespace System.Windows.Forms;
+namespace System;
internal static class ArgumentValidation
{
diff --git a/src/System.Private.Windows.Core/src/Windows/Win32/Graphics/GdiPlus/GpBitmapExtensions.cs b/src/System.Private.Windows.Core/src/Windows/Win32/Graphics/GdiPlus/GpBitmapExtensions.cs
new file mode 100644
index 00000000000..8a4f4ba89c6
--- /dev/null
+++ b/src/System.Private.Windows.Core/src/Windows/Win32/Graphics/GdiPlus/GpBitmapExtensions.cs
@@ -0,0 +1,34 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Drawing;
+using System.Runtime.CompilerServices;
+
+namespace Windows.Win32.Graphics.GdiPlus;
+
+internal static unsafe class GpBitmapExtensions
+{
+ public static void LockBits(
+ this IPointer bitmap,
+ Rectangle rect,
+ ImageLockMode flags,
+ PixelFormat format,
+ ref BitmapData data)
+ {
+ // LockBits always creates a temporary copy of the data.
+ PInvokeCore.GdipBitmapLockBits(
+ bitmap.Pointer,
+ rect.IsEmpty ? null : (Rect*)&rect,
+ (uint)flags,
+ (int)format,
+ (BitmapData*)Unsafe.AsPointer(ref data)).ThrowIfFailed();
+
+ GC.KeepAlive(bitmap);
+ }
+
+ public static void UnlockBits(this IPointer bitmap, ref BitmapData data)
+ {
+ PInvokeCore.GdipBitmapUnlockBits(bitmap.Pointer, (BitmapData*)Unsafe.AsPointer(ref data)).ThrowIfFailed();
+ GC.KeepAlive(bitmap);
+ }
+}
diff --git a/src/System.Private.Windows.Core/src/Windows/Win32/Graphics/GdiPlus/GpImageExtensions.cs b/src/System.Private.Windows.Core/src/Windows/Win32/Graphics/GdiPlus/GpImageExtensions.cs
new file mode 100644
index 00000000000..c6f9b78b787
--- /dev/null
+++ b/src/System.Private.Windows.Core/src/Windows/Win32/Graphics/GdiPlus/GpImageExtensions.cs
@@ -0,0 +1,31 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+using System.Drawing;
+using System.Runtime.CompilerServices;
+
+namespace Windows.Win32.Graphics.GdiPlus;
+
+internal static unsafe class GpImageExtensions
+{
+ [SkipLocalsInit]
+ internal static RectangleF GetImageBounds(this IPointer image)
+ {
+ RectangleF bounds;
+ Unit unit;
+
+ PInvokeCore.GdipGetImageBounds(image.Pointer, (RectF*)&bounds, &unit).ThrowIfFailed();
+ GC.KeepAlive(image);
+ return bounds;
+ }
+
+ [SkipLocalsInit]
+ internal static PixelFormat GetPixelFormat(this IPointer image)
+ {
+ int format;
+
+ Status status = PInvokeCore.GdipGetImagePixelFormat(image.Pointer, &format);
+ GC.KeepAlive(image);
+ return status == Status.Ok ? (PixelFormat)format : PixelFormat.Undefined;
+ }
+}
diff --git a/src/System.Private.Windows.Core/src/Windows/Win32/Graphics/GdiPlus/PixelFormat.cs b/src/System.Private.Windows.Core/src/Windows/Win32/Graphics/GdiPlus/PixelFormat.cs
new file mode 100644
index 00000000000..e404ff0e819
--- /dev/null
+++ b/src/System.Private.Windows.Core/src/Windows/Win32/Graphics/GdiPlus/PixelFormat.cs
@@ -0,0 +1,128 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+namespace Windows.Win32.Graphics.GdiPlus;
+
+internal enum PixelFormat
+{
+ ///
+ /// Specifies that pixel data contains color indexed values which means they are an index to colors in the
+ /// system color table, as opposed to individual color values.
+ ///
+ Indexed = (int)PInvokeCore.PixelFormatIndexed,
+
+ ///
+ /// Specifies that pixel data contains GDI colors.
+ ///
+ Gdi = (int)PInvokeCore.PixelFormatGDI,
+
+ ///
+ /// Specifies that pixel data contains alpha values that are not pre-multiplied.
+ ///
+ Alpha = (int)PInvokeCore.PixelFormatAlpha,
+
+ ///
+ /// Specifies that pixel format contains pre-multiplied alpha values.
+ ///
+ PAlpha = (int)PInvokeCore.PixelFormatPAlpha,
+
+ ///
+ /// Specifies that pixel format contains extended color values of 16 bits per channel.
+ ///
+ Extended = (int)PInvokeCore.PixelFormatExtended,
+
+ Canonical = (int)PInvokeCore.PixelFormatCanonical,
+
+ ///
+ /// Specifies that pixel format is undefined.
+ ///
+ Undefined = (int)PInvokeCore.PixelFormatUndefined,
+
+ ///
+ /// Specifies that pixel format doesn't matter.
+ ///
+ DontCare = (int)PInvokeCore.PixelFormatDontCare,
+
+ ///
+ /// Specifies that pixel format is 1 bit per pixel indexed color. The color table therefore has two colors in it.
+ ///
+ Format1bppIndexed = 1 | (1 << 8) | Indexed | Gdi,
+
+ ///
+ /// Specifies that pixel format is 4 bits per pixel indexed color. The color table therefore has 16 colors in it.
+ ///
+ Format4bppIndexed = 2 | (4 << 8) | Indexed | Gdi,
+
+ ///
+ /// Specifies that pixel format is 8 bits per pixel indexed color. The color table therefore has 256 colors in it.
+ ///
+ Format8bppIndexed = 3 | (8 << 8) | Indexed | Gdi,
+
+ ///
+ /// Specifies that pixel format is 16 bits per pixel. The color information specifies 65536 shades of gray.
+ ///
+ Format16bppGrayScale = 4 | (16 << 8) | Extended,
+
+ ///
+ /// Specifies that pixel format is 16 bits per pixel. The color information specifies 32768 shades of color of
+ /// which 5 bits are red, 5 bits are green and 5 bits are blue.
+ ///
+ Format16bppRgb555 = 5 | (16 << 8) | Gdi,
+
+ Format16bppRgb565 = 6 | (16 << 8) | Gdi,
+
+ ///
+ /// Specifies that pixel format is 16 bits per pixel. The color information specifies 32768 shades of color of
+ /// which 5 bits are red, 5 bits are green, 5 bits are blue and 1 bit is alpha.
+ ///
+ Format16bppArgb1555 = 7 | (16 << 8) | Alpha | Gdi,
+
+ ///
+ /// Specifies that pixel format is 24 bits per pixel. The color information specifies 16777216 shades of color
+ /// of which 8 bits are red, 8 bits are green and 8 bits are blue.
+ ///
+ Format24bppRgb = 8 | (24 << 8) | Gdi,
+
+ ///
+ /// Specifies that pixel format is 24 bits per pixel. The color information specifies 16777216 shades of color
+ /// of which 8 bits are red, 8 bits are green and 8 bits are blue.
+ ///
+ Format32bppRgb = 9 | (32 << 8) | Gdi,
+
+ ///
+ /// Specifies that pixel format is 32 bits per pixel. The color information specifies 16777216 shades of color
+ /// of which 8 bits are red, 8 bits are green and 8 bits are blue. The 8 additional bits are alpha bits.
+ ///
+ Format32bppArgb = 10 | (32 << 8) | Alpha | Gdi | Canonical,
+
+ ///
+ /// Specifies that pixel format is 32 bits per pixel. The color information specifies 16777216 shades of color
+ /// of which 8 bits are red, 8 bits are green and 8 bits are blue. The 8 additional bits are pre-multiplied alpha bits.
+ ///
+ Format32bppPArgb = 11 | (32 << 8) | Alpha | PAlpha | Gdi,
+
+ ///
+ /// Specifies that pixel format is 48 bits per pixel. The color information specifies 16777216 shades of color
+ /// of which 8 bits are red, 8 bits are green and 8 bits are blue. The 8 additional bits are alpha bits.
+ ///
+ Format48bppRgb = 12 | (48 << 8) | Extended,
+
+ ///
+ /// Specifies pixel format is 64 bits per pixel. The color information specifies 16777216 shades of color of
+ /// which 16 bits are red, 16 bits are green and 16 bits are blue. The 16 additional bits are alpha bits.
+ ///
+ Format64bppArgb = 13 | (64 << 8) | Alpha | Canonical | Extended,
+
+ ///
+ /// Specifies that pixel format is 64 bits per pixel. The color information specifies 16777216 shades of color
+ /// of which 16 bits are red, 16 bits are green and 16 bits are blue. The 16 additional bits are pre-multiplied
+ /// alpha bits.
+ ///
+ Format64bppPArgb = 14 | (64 << 8) | Alpha | PAlpha | Extended,
+
+ ///
+ /// Specifies that pixel format is 64 bits per pixel. The color information specifies 16777216 shades of color
+ /// of which 16 bits are red, 16 bits are green and 16 bits are blue. The 16 additional bits are alpha bits.
+ ///
+ Max = 15,
+}
diff --git a/src/System.Private.Windows.Core/src/Windows/Win32/PInvoke.SystemParametersInfo.cs b/src/System.Private.Windows.Core/src/Windows/Win32/PInvoke.SystemParametersInfo.cs
index 749fd306be8..c52fc3df81c 100644
--- a/src/System.Private.Windows.Core/src/Windows/Win32/PInvoke.SystemParametersInfo.cs
+++ b/src/System.Private.Windows.Core/src/Windows/Win32/PInvoke.SystemParametersInfo.cs
@@ -47,6 +47,8 @@ public static unsafe bool SystemParametersInfo(ref HIGHCONTRASTW highContrast)
{
fixed (void* p = &highContrast)
{
+ // Note that the documentation for HIGHCONTRASTW says that the lpszDefaultScheme member needs to be
+ // freed, but this is incorrect. No internal users ever free the pointer and the pointer never changes.
highContrast.cbSize = (uint)sizeof(HIGHCONTRASTW);
return SystemParametersInfo(
SYSTEM_PARAMETERS_INFO_ACTION.SPI_GETHIGHCONTRAST,
diff --git a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System.Windows.Forms.Analyzers.CSharp.Tests.csproj b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System.Windows.Forms.Analyzers.CSharp.Tests.csproj
index dacf2b356ce..53b7a42f399 100644
--- a/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System.Windows.Forms.Analyzers.CSharp.Tests.csproj
+++ b/src/System.Windows.Forms.Analyzers.CSharp/tests/UnitTests/System.Windows.Forms.Analyzers.CSharp.Tests.csproj
@@ -15,6 +15,7 @@
+
diff --git a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System.Windows.Forms.Analyzers.Tests.csproj b/src/System.Windows.Forms.Analyzers/tests/UnitTests/System.Windows.Forms.Analyzers.Tests.csproj
index 60cd05a24b5..45d417503e7 100644
--- a/src/System.Windows.Forms.Analyzers/tests/UnitTests/System.Windows.Forms.Analyzers.Tests.csproj
+++ b/src/System.Windows.Forms.Analyzers/tests/UnitTests/System.Windows.Forms.Analyzers.Tests.csproj
@@ -23,6 +23,7 @@
+
diff --git a/src/System.Windows.Forms.Design/src/System/ComponentModel/Design/CollectionEditor.CollectionEditorCollectionForm.cs b/src/System.Windows.Forms.Design/src/System/ComponentModel/Design/CollectionEditor.CollectionEditorCollectionForm.cs
index 6f7b878f142..0d8a6410350 100644
--- a/src/System.Windows.Forms.Design/src/System/ComponentModel/Design/CollectionEditor.CollectionEditorCollectionForm.cs
+++ b/src/System.Windows.Forms.Design/src/System/ComponentModel/Design/CollectionEditor.CollectionEditorCollectionForm.cs
@@ -28,7 +28,7 @@ private class CollectionEditorCollectionForm : CollectionForm
private readonly CollectionEditor _editor;
- private FilterListBox _listbox;
+ private FilterListBox _listBox;
private SplitButton _addButton;
private Button _removeButton;
private Button _cancelButton;
@@ -80,7 +80,7 @@ private bool IsImmutable
{
get
{
- foreach (ListItem item in _listbox.SelectedItems)
+ foreach (ListItem item in _listBox.SelectedItems)
{
Type type = item.Value.GetType();
@@ -128,7 +128,7 @@ private void AddItems(IList instances)
{
_createdItems ??= new List
///
- /// This method is called during window message pre-processing to determine whether the given input
- /// character should be pre-processed or sent directly to the control. The pre-processing of a character
- /// includes checking whether the character is a mnemonic of another control.
- /// ()
+ ///
+ /// This method is called during window message pre-processing to determine whether the given input
+ /// character should be pre-processed or sent directly to the control. The pre-processing of a character
+ /// includes checking whether the character is a mnemonic of another control.
+ /// ()
+ ///
///
///
/// 'true' if the should be sent directly to the control.
@@ -6967,7 +6894,7 @@ private static void MarshalStringToMessage(string value, ref Message m)
}
// Copy the name into the given IntPtr
- char[] nullChar = new char[] { (char)0 };
+ char[] nullChar = [(char)0];
byte[] nullBytes;
byte[] bytes;
@@ -8586,21 +8513,15 @@ protected virtual void RescaleConstantsForDpi(int deviceDpiOld, int deviceDpiNew
// This is basically OnPaintBackground, put in a separate method for ButtonBase,
// which does all painting under OnPaint, and tries very hard to avoid double-painting the border pixels.
- internal void PaintBackground(PaintEventArgs e, Rectangle rectangle)
- {
+ internal void PaintBackground(PaintEventArgs e, Rectangle rectangle) =>
PaintBackground(e, rectangle, BackColor, Point.Empty);
- }
- internal void PaintBackground(PaintEventArgs e, Rectangle rectangle, Color backColor)
- {
- PaintBackground(e, rectangle, backColor, Point.Empty);
- }
-
- internal void PaintBackground(PaintEventArgs e, Rectangle rectangle, Color backColor, Point scrollOffset)
+ internal void PaintBackground(PaintEventArgs e, Rectangle rectangle, Color backColor, Point scrollOffset = default)
{
ArgumentNullException.ThrowIfNull(e);
- if (RenderColorTransparent(backColor))
+ bool renderColorTransparent = RenderColorTransparent(backColor);
+ if (renderColorTransparent)
{
PaintTransparentBackground(e, rectangle);
}
@@ -8613,12 +8534,10 @@ internal void PaintBackground(PaintEventArgs e, Rectangle rectangle, Color backC
if (BackgroundImage is not null && !DisplayInformation.HighContrast && !formRTL)
{
- if (BackgroundImageLayout == ImageLayout.Tile)
+ bool imageIsTransparent = ControlPaint.IsImageTransparent(BackgroundImage);
+ if (!renderColorTransparent && BackgroundImageLayout == ImageLayout.Tile && imageIsTransparent)
{
- if (ControlPaint.IsImageTransparent(BackgroundImage))
- {
- PaintTransparentBackground(e, rectangle);
- }
+ PaintTransparentBackground(e, rectangle);
}
Point scrollLocation = scrollOffset;
@@ -8627,7 +8546,7 @@ internal void PaintBackground(PaintEventArgs e, Rectangle rectangle, Color backC
scrollLocation = scrollControl.AutoScrollPosition;
}
- if (ControlPaint.IsImageTransparent(BackgroundImage))
+ if (imageIsTransparent)
{
PaintBackColor(e, rectangle, backColor);
}
@@ -8694,23 +8613,20 @@ private void PaintException(PaintEventArgs e)
clientRectangle.Right, clientRectangle.Top);
}
- internal void PaintTransparentBackground(PaintEventArgs e, Rectangle rectangle)
- {
- PaintTransparentBackground(e, rectangle, null);
- }
-
///
/// Trick our parent into painting our background for us, or paint some default color if that doesn't work.
///
///
- /// This method is the hardest part of implementing transparent controls; call this in
- /// .
+ ///
+ /// This method is the hardest part of implementing transparent controls; call this in
+ /// .
+ ///
///
/// The area to redraw.
///
/// Region of the rectangle to be transparent, or null for the entire control.
///
- internal unsafe void PaintTransparentBackground(PaintEventArgs e, Rectangle rectangle, Region? transparentRegion)
+ internal unsafe void PaintTransparentBackground(PaintEventArgs e, Rectangle rectangle, Region? transparentRegion = null)
{
Control? parent = ParentInternal;
@@ -9165,7 +9081,7 @@ internal static PreProcessControlState PreProcessControlMessageInternal(Control?
Keys keyData = (Keys)(nint)message.WParamInternal | ModifierKeys;
// Allow control to preview key down message.
- if (message.Msg == (int)PInvoke.WM_KEYDOWN || message.Msg == (int)PInvoke.WM_SYSKEYDOWN)
+ if (message.Msg is ((int)PInvoke.WM_KEYDOWN) or ((int)PInvoke.WM_SYSKEYDOWN))
{
target.ProcessUICues(ref message);
@@ -9288,7 +9204,7 @@ private protected virtual void PrintToMetaFileRecursive(HDC hDC, IntPtr lParam,
using DCMapping mapping = new(hDC, bounds);
// Print the non-client area.
- PrintToMetaFile_SendPrintMessage(hDC, (IntPtr)(lParam & (long)~PInvoke.PRF_CLIENT));
+ PrintToMetaFile_SendPrintMessage(hDC, (nint)(lParam & (long)~PInvoke.PRF_CLIENT));
// Figure out mapping for the client area.
bool success = PInvoke.GetWindowRect(this, out var windowRect);
@@ -9300,7 +9216,7 @@ private protected virtual void PrintToMetaFileRecursive(HDC hDC, IntPtr lParam,
using DCMapping clientMapping = new(hDC, clientBounds);
// Print the client area.
- PrintToMetaFile_SendPrintMessage(hDC, (IntPtr)(lParam & (long)~PInvoke.PRF_NONCLIENT));
+ PrintToMetaFile_SendPrintMessage(hDC, (nint)(lParam & (long)~PInvoke.PRF_NONCLIENT));
// Paint children in reverse Z-Order.
int count = Controls.Count;
@@ -9358,7 +9274,7 @@ private void PrintToMetaFile_SendPrintMessage(HDC hDC, nint lParam)
protected virtual bool ProcessDialogChar(char charCode)
{
s_controlKeyboardRouting.TraceVerbose($"Control.ProcessDialogChar [{charCode}]");
- return _parent is null ? false : _parent.ProcessDialogChar(charCode);
+ return _parent is not null && _parent.ProcessDialogChar(charCode);
}
///
@@ -9379,7 +9295,7 @@ protected virtual bool ProcessDialogChar(char charCode)
protected virtual bool ProcessDialogKey(Keys keyData)
{
s_controlKeyboardRouting.TraceVerbose($"Control.ProcessDialogKey {keyData}");
- return _parent is null ? false : _parent.ProcessDialogKey(keyData);
+ return _parent is not null && _parent.ProcessDialogKey(keyData);
}
///
@@ -9564,7 +9480,7 @@ internal void ProcessUICues(ref Message msg)
{
Keys keyCode = (Keys)(nint)msg.WParamInternal & Keys.KeyCode;
- if (keyCode != Keys.F10 && keyCode != Keys.Menu && keyCode != Keys.Tab)
+ if (keyCode is not Keys.F10 and not Keys.Menu and not Keys.Tab)
{
return; // PERF: don't WM_QUERYUISTATE if we don't have to.
}
@@ -9588,7 +9504,7 @@ internal void ProcessUICues(ref Message msg)
// the opposite of what we want to do. So if we want to show accelerators,
// we OR in UISF_HIDEACCEL, then call UIS_CLEAR to clear the "hidden" state.
- if (keyCode == Keys.F10 || keyCode == Keys.Menu)
+ if (keyCode is Keys.F10 or Keys.Menu)
{
if ((current & PInvoke.UISF_HIDEACCEL) != 0)
{
@@ -10000,10 +9916,7 @@ private void ResetVisible()
/// Resumes normal layout logic. This will force a layout immediately
/// if there are any pending layout requests.
///
- public void ResumeLayout()
- {
- ResumeLayout(true);
- }
+ public void ResumeLayout() => ResumeLayout(performLayout: true);
///
/// Resumes normal layout logic. If performLayout is set to true then
@@ -10031,9 +9944,7 @@ public void ResumeLayout(bool performLayout)
}
LayoutSuspendCount--;
- if (LayoutSuspendCount == 0
- && GetState(States.LayoutDeferred)
- && performLayout)
+ if (LayoutSuspendCount == 0 && GetState(States.LayoutDeferred) && performLayout)
{
PerformLayout();
performedLayout = true;
@@ -10045,23 +9956,19 @@ public void ResumeLayout(bool performLayout)
SetExtendedState(ExtendedStates.ClearLayoutArgs, true);
}
- /*
+ // We've had this since Everett, but it seems wrong, redundant and a performance hit. The
+ // correct layout calls are already made when bounds or parenting changes, which is all
+ // we care about. We may want to call this at layout suspend count == 0, but certainly
+ // not for all resumes. I tried removing it, and doing it only when suspendCount == 0,
+ // but we break things at every step.
- We've had this since Everett,but it seems wrong, redundant and a performance hit. The
- correct layout calls are already made when bounds or parenting changes, which is all
- we care about. We may want to call this at layout suspend count == 0, but certainly
- not for all resumes. I tried removing it, and doing it only when suspendCount == 0,
- but we break things at every step.
-
- */
if (!performLayout)
{
CommonProperties.xClearPreferredSizeCache(this);
ControlCollection? controlsCollection = (ControlCollection?)Properties.GetObject(s_controlsCollectionProperty);
- // PERFNOTE: This is more efficient than using Foreach. Foreach
- // forces the creation of an array subset enum each time we
- // enumerate
+ // PERFNOTE: This is more efficient than using Foreach. Foreach forces the creation of an array subset
+ // enum each time we enumerate.
if (controlsCollection is not null)
{
for (int i = 0; i < controlsCollection.Count; i++)
@@ -10141,21 +10048,8 @@ public void Scale(float ratio)
[EditorBrowsable(EditorBrowsableState.Never)]
public void Scale(float dx, float dy)
{
-#if DEBUG
- int dbgLayoutCheck = LayoutSuspendCount;
-#endif
- SuspendLayout();
- try
- {
- ScaleCore(dx, dy);
- }
- finally
- {
- ResumeLayout();
-#if DEBUG
- AssertLayoutSuspendCount(dbgLayoutCheck);
-#endif
- }
+ using SuspendLayoutScope scope = new(this);
+ ScaleCore(dx, dy);
}
///
@@ -10164,10 +10058,10 @@ public void Scale(float dx, float dy)
[EditorBrowsable(EditorBrowsableState.Advanced)]
public void Scale(SizeF factor)
{
- // manually call ScaleControl recursively instead of the internal scale method
+ // Manually call ScaleControl recursively instead of the internal scale method
// when someone calls this method, they really do want to do some sort of
// zooming feature, as opposed to AutoScale.
- using (new LayoutTransaction(this, this, PropertyNames.Bounds, false))
+ using (new LayoutTransaction(this, this, PropertyNames.Bounds, resumeLayout: false))
{
ScaleControl(factor, factor, this);
if (ScaleChildren)
@@ -10450,49 +10344,38 @@ protected virtual void ScaleControl(SizeF factor, BoundsSpecified specified)
protected virtual void ScaleCore(float dx, float dy)
{
Debug.WriteLineIf(CompModSwitches.RichLayout.TraceInfo, $"{GetType().Name}::ScaleCore({dx}, {dy})");
-#if DEBUG
- int dbgLayoutCheck = LayoutSuspendCount;
-#endif
- SuspendLayout();
- try
- {
- int sx = (int)Math.Round(_x * dx);
- int sy = (int)Math.Round(_y * dy);
- int sw = _width;
- if ((_controlStyle & ControlStyles.FixedWidth) != ControlStyles.FixedWidth)
- {
- sw = (int)(Math.Round((_x + _width) * dx)) - sx;
- }
+ using SuspendLayoutScope scope = new(this);
- int sh = _height;
- if ((_controlStyle & ControlStyles.FixedHeight) != ControlStyles.FixedHeight)
- {
- sh = (int)(Math.Round((_y + _height) * dy)) - sy;
- }
+ int sx = (int)Math.Round(_x * dx);
+ int sy = (int)Math.Round(_y * dy);
- SetBounds(sx, sy, sw, sh, BoundsSpecified.All);
+ int sw = _width;
+ if ((_controlStyle & ControlStyles.FixedWidth) != ControlStyles.FixedWidth)
+ {
+ sw = (int)(Math.Round((_x + _width) * dx)) - sx;
+ }
- ControlCollection? controlsCollection = (ControlCollection?)Properties.GetObject(s_controlsCollectionProperty);
+ int sh = _height;
+ if ((_controlStyle & ControlStyles.FixedHeight) != ControlStyles.FixedHeight)
+ {
+ sh = (int)(Math.Round((_y + _height) * dy)) - sy;
+ }
- if (controlsCollection is not null)
+ SetBounds(sx, sy, sw, sh, BoundsSpecified.All);
+
+ ControlCollection? controlsCollection = (ControlCollection?)Properties.GetObject(s_controlsCollectionProperty);
+
+ if (controlsCollection is not null)
+ {
+ // PERFNOTE: This is more efficient than using Foreach. Foreach
+ // forces the creation of an array subset enum each time we
+ // enumerate
+ for (int i = 0; i < controlsCollection.Count; i++)
{
- // PERFNOTE: This is more efficient than using Foreach. Foreach
- // forces the creation of an array subset enum each time we
- // enumerate
- for (int i = 0; i < controlsCollection.Count; i++)
- {
- controlsCollection[i].Scale(dx, dy);
- }
+ controlsCollection[i].Scale(dx, dy);
}
}
- finally
- {
- ResumeLayout();
-#if DEBUG
- AssertLayoutSuspendCount(dbgLayoutCheck);
-#endif
- }
}
///
@@ -10723,61 +10606,61 @@ protected virtual void SetBoundsCore(int x, int y, int width, int height, Bounds
{
Debug.WriteLineIf(CompModSwitches.SetBounds.TraceInfo,
$"{Name}::SetBoundsCore(x={x} y={y} width={width} height={height} specified={specified})");
+
// SetWindowPos below sends a WmWindowPositionChanged (not posts) so we immediately
// end up in WmWindowPositionChanged which may cause the parent to layout. We need to
// suspend/resume to defer the parent from laying out until after InitLayout has been called
// to update the layout engine's state with the new control bounds.
-#if DEBUG
- int suspendCount = -44371; // Arbitrary negative prime to surface bugs.
- suspendCount = ParentInternal is not null ? ParentInternal.LayoutSuspendCount : suspendCount;
-#endif
- ParentInternal?.SuspendLayout();
+
+ if (_x == x && _y == y && _width == width && _height == height)
+ {
+ return;
+ }
+
+ using SuspendLayoutScope scope = new(ParentInternal);
try
{
- if (_x != x || _y != y || _width != width || _height != height)
- {
- CommonProperties.UpdateSpecifiedBounds(this, x, y, width, height, specified);
+ CommonProperties.UpdateSpecifiedBounds(this, x, y, width, height, specified);
- // Provide control with an opportunity to apply self imposed constraints on its size.
- Rectangle adjustedBounds = ApplyBoundsConstraints(x, y, width, height);
- width = adjustedBounds.Width;
- height = adjustedBounds.Height;
- x = adjustedBounds.X;
- y = adjustedBounds.Y;
+ // Provide control with an opportunity to apply self imposed constraints on its size.
+ Rectangle adjustedBounds = ApplyBoundsConstraints(x, y, width, height);
+ width = adjustedBounds.Width;
+ height = adjustedBounds.Height;
+ x = adjustedBounds.X;
+ y = adjustedBounds.Y;
- if (!IsHandleCreated)
- {
- // Handle is not created, just record our new position and we're done.
- UpdateBounds(x, y, width, height);
- }
- else
+ if (!IsHandleCreated)
+ {
+ // Handle is not created, just record our new position and we're done.
+ UpdateBounds(x, y, width, height);
+ }
+ else
+ {
+ if (!GetState(States.SizeLockedByOS))
{
- if (!GetState(States.SizeLockedByOS))
- {
- SET_WINDOW_POS_FLAGS flags = SET_WINDOW_POS_FLAGS.SWP_NOZORDER | SET_WINDOW_POS_FLAGS.SWP_NOACTIVATE;
+ SET_WINDOW_POS_FLAGS flags = SET_WINDOW_POS_FLAGS.SWP_NOZORDER | SET_WINDOW_POS_FLAGS.SWP_NOACTIVATE;
- if (_x == x && _y == y)
- {
- flags |= SET_WINDOW_POS_FLAGS.SWP_NOMOVE;
- }
+ if (_x == x && _y == y)
+ {
+ flags |= SET_WINDOW_POS_FLAGS.SWP_NOMOVE;
+ }
- if (_width == width && _height == height)
- {
- flags |= SET_WINDOW_POS_FLAGS.SWP_NOSIZE;
- }
+ if (_width == width && _height == height)
+ {
+ flags |= SET_WINDOW_POS_FLAGS.SWP_NOSIZE;
+ }
- // Give a chance for derived controls to do what they want, just before we resize.
- OnBoundsUpdate(x, y, width, height);
+ // Give a chance for derived controls to do what they want, just before we resize.
+ OnBoundsUpdate(x, y, width, height);
- PInvoke.SetWindowPos(this, HWND.Null, x, y, width, height, flags);
+ PInvoke.SetWindowPos(this, HWND.Null, x, y, width, height, flags);
- // NOTE: SetWindowPos causes a WM_WINDOWPOSCHANGED which is processed
- // synchronously so we effectively end up in UpdateBounds immediately following
- // SetWindowPos.
- //
- // UpdateBounds(x, y, width, height);
- }
+ // NOTE: SetWindowPos causes a WM_WINDOWPOSCHANGED which is processed
+ // synchronously so we effectively end up in UpdateBounds immediately following
+ // SetWindowPos.
+ //
+ // UpdateBounds(x, y, width, height);
}
}
}
@@ -10799,10 +10682,6 @@ protected virtual void SetBoundsCore(int x, int y, int width, int height, Bounds
// LayoutEngine which manages your layout, so we call into the parent's
// LayoutEngine.
ParentInternal.LayoutEngine.InitLayout(this, specified);
- ParentInternal.ResumeLayout(/* performLayout = */ true);
-#if DEBUG
- Debug.Assert(ParentInternal.LayoutSuspendCount == suspendCount, "Suspend/Resume layout mismatch!");
-#endif
}
}
}
@@ -11881,7 +11760,7 @@ private void WmEraseBkgnd(ref Message m)
{
// When possible, it's best to do all painting directly from WM_PAINT.
// OptimizedDoubleBuffer is the "same" as turning on AllPaintingInWMPaint
- if (!(GetStyle(ControlStyles.AllPaintingInWmPaint)))
+ if (!GetStyle(ControlStyles.AllPaintingInWmPaint))
{
HDC dc = (HDC)(nint)m.WParamInternal;
if (dc.IsNull)
@@ -13596,19 +13475,18 @@ static bool IsKeyDown(Keys key, ReadOnlySpan stateArray)
internal virtual ToolInfoWrapper GetToolInfoWrapper(TOOLTIP_FLAGS flags, string? caption, ToolTip tooltip)
=> new(this, flags, caption);
- private readonly WeakReference toolStripControlHostReference
- = new(null);
+ private readonly WeakReference _toolStripControlHostReference = new(null);
internal ToolStripControlHost? ToolStripControlHost
{
get
{
- toolStripControlHostReference.TryGetTarget(out ToolStripControlHost? value);
+ _toolStripControlHostReference.TryGetTarget(out ToolStripControlHost? value);
return value;
}
set
{
- toolStripControlHostReference.SetTarget(value);
+ _toolStripControlHostReference.SetTarget(value);
}
}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ComboBox/ComboBox.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ComboBox/ComboBox.cs
index 47c4b708544..26e2000c1db 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ComboBox/ComboBox.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ComboBox/ComboBox.cs
@@ -915,30 +915,20 @@ private int GetComboHeight()
return cyCombo;
}
- private string[] GetStringsForAutoComplete(IList collection)
+ private string[] GetStringsForAutoComplete()
{
- if (collection is AutoCompleteStringCollection)
+ if (Items is not null)
{
- string[] strings = new string[AutoCompleteCustomSource.Count];
- for (int i = 0; i < AutoCompleteCustomSource.Count; i++)
- {
- strings[i] = AutoCompleteCustomSource[i];
- }
-
- return strings;
- }
- else if (collection is ObjectCollection && _itemsCollection is not null)
- {
- string[] strings = new string[_itemsCollection.Count];
- for (int i = 0; i < _itemsCollection.Count; i++)
+ string[] strings = new string[Items.Count];
+ for (int i = 0; i < Items.Count; i++)
{
- strings[i] = GetItemText(_itemsCollection[i])!;
+ strings[i] = GetItemText(Items[i])!;
}
return strings;
}
- return Array.Empty();
+ return [];
}
///
@@ -3283,7 +3273,7 @@ private void SetAutoComplete(bool reset, bool recreate)
if (_stringSource is null)
{
- _stringSource = new StringSource(GetStringsForAutoComplete(AutoCompleteCustomSource));
+ _stringSource = new StringSource(AutoCompleteCustomSource.ToArray());
if (!_stringSource.Bind(_childEdit, (AUTOCOMPLETEOPTIONS)AutoCompleteMode))
{
throw new ArgumentException(SR.AutoCompleteFailure);
@@ -3291,7 +3281,7 @@ private void SetAutoComplete(bool reset, bool recreate)
}
else
{
- _stringSource.RefreshList(GetStringsForAutoComplete(AutoCompleteCustomSource));
+ _stringSource.RefreshList(AutoCompleteCustomSource.ToArray());
}
return;
@@ -3326,7 +3316,7 @@ private void SetAutoComplete(bool reset, bool recreate)
if (_stringSource is null)
{
- _stringSource = new StringSource(GetStringsForAutoComplete(Items));
+ _stringSource = new StringSource(GetStringsForAutoComplete());
if (!_stringSource.Bind(_childEdit, (AUTOCOMPLETEOPTIONS)AutoCompleteMode))
{
throw new ArgumentException(SR.AutoCompleteFailureListItems);
@@ -3334,7 +3324,7 @@ private void SetAutoComplete(bool reset, bool recreate)
}
else
{
- _stringSource.RefreshList(GetStringsForAutoComplete(Items));
+ _stringSource.RefreshList(GetStringsForAutoComplete());
}
return;
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridView.Methods.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridView.Methods.cs
index cce1b6d07d0..d9a982f0770 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridView.Methods.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridView.Methods.cs
@@ -806,7 +806,7 @@ internal void AdjustFillingColumn(DataGridViewColumn dataGridViewColumn, int wid
if (dataGridViewColumnTmp.Visible
&& dataGridViewColumnTmp.InheritedAutoSizeMode == DataGridViewAutoSizeColumnMode.Fill)
{
- if (dataGridViewColumnTmp.FillWeight < (dataGridViewColumnTmp.MinimumWidth * weightSum) / (float)availableWidth)
+ if (dataGridViewColumnTmp.FillWeight < (dataGridViewColumnTmp.MinimumWidth * weightSum) / availableWidth)
{
desiredWidthTooSmall = true;
dataGridViewColumnTmp.DesiredFillWidth = -1;
@@ -10541,87 +10541,139 @@ protected override bool IsInputKey(Keys keyData)
}
///
- /// Determines if Scrollbars should be visible,
- /// updates their bounds and the bounds of all
+ /// Determines if Scrollbars should be visible, updates their bounds and the bounds of all
/// other regions in the dataGridView's Layout.
///
private void LayoutScrollBars()
{
- SuspendLayout();
- try
- {
- // Scrollbars are a tricky issue.
- // We need to see if we can cram our columns and rows
- // in without scrollbars and if they don't fit, we make
- // scrollbars visible and then fixup our regions for the
- // data.
- bool allowHorizScrollbar = ((_scrollBars == ScrollBars.Both) || (_scrollBars == ScrollBars.Horizontal))
- && _dataGridViewState2[State2_AllowHorizontalScrollbar];
- bool allowVertScrollbar = _scrollBars is ScrollBars.Both or ScrollBars.Vertical;
- bool needHorizScrollbarWithoutVertScrollbar = false;
- bool needHorizScrollbar = false;
- bool needVertScrollbar = false;
- bool rightToLeftInternal = RightToLeftInternal;
- int oldfirstDisplayedScrollingRow;
-
- int totalVisibleColCount = Columns.GetColumnCount(DataGridViewElementStates.Visible);
- int totalVisibleRowCount = Rows.GetRowCount(DataGridViewElementStates.Visible);
- int totalVisibleWidth = Columns.GetColumnsWidth(DataGridViewElementStates.Visible);
- int totalVisibleFrozenWidth = Columns.GetColumnsWidth(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
-
- // Expensive call - dataGridView could have a mode where no row is resizable which would result in better perf
- int totalVisibleHeight = Rows.GetRowsHeight(DataGridViewElementStates.Visible);
- int totalVisibleFrozenHeight = Rows.GetRowsHeight(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
+ using SuspendLayoutScope scope = new(this, performLayout: false);
+
+ // Scrollbars are a tricky issue. We need to see if we can cram our columns and rows in without scrollbars
+ // and if they don't fit, we make scrollbars visible and then fixup our regions for the data.
+ bool allowHorizScrollbar = ((_scrollBars == ScrollBars.Both) || (_scrollBars == ScrollBars.Horizontal))
+ && _dataGridViewState2[State2_AllowHorizontalScrollbar];
+ bool allowVertScrollbar = _scrollBars is ScrollBars.Both or ScrollBars.Vertical;
+ bool needHorizScrollbarWithoutVertScrollbar = false;
+ bool needHorizScrollbar = false;
+ bool needVertScrollbar = false;
+ bool rightToLeftInternal = RightToLeftInternal;
+ int oldfirstDisplayedScrollingRow;
+
+ int totalVisibleColCount = Columns.GetColumnCount(DataGridViewElementStates.Visible);
+ int totalVisibleRowCount = Rows.GetRowCount(DataGridViewElementStates.Visible);
+ int totalVisibleWidth = Columns.GetColumnsWidth(DataGridViewElementStates.Visible);
+ int totalVisibleFrozenWidth = Columns.GetColumnsWidth(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
+
+ // Expensive call - dataGridView could have a mode where no row is resizable which would result in better perf
+ int totalVisibleHeight = Rows.GetRowsHeight(DataGridViewElementStates.Visible);
+ int totalVisibleFrozenHeight = Rows.GetRowsHeight(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen);
- int horizScrollBarHeight = _horizScrollBar.Height = SystemInformation.HorizontalScrollBarHeight;
- int vertScrollBarWidth = _vertScrollBar.Width = SystemInformation.VerticalScrollBarWidth;
+ int horizScrollBarHeight = _horizScrollBar.Height = SystemInformation.HorizontalScrollBarHeight;
+ int vertScrollBarWidth = _vertScrollBar.Width = SystemInformation.VerticalScrollBarWidth;
- if (allowHorizScrollbar
- && totalVisibleWidth > _layout.Data.Width
- && totalVisibleFrozenWidth < _layout.Data.Width
- && horizScrollBarHeight <= _layout.Data.Height)
+ if (allowHorizScrollbar
+ && totalVisibleWidth > _layout.Data.Width
+ && totalVisibleFrozenWidth < _layout.Data.Width
+ && horizScrollBarHeight <= _layout.Data.Height)
+ {
+ int oldDataHeight = _layout.Data.Height;
+ _layout.Data.Height -= horizScrollBarHeight;
+ Debug.Assert(_layout.Data.Height >= 0);
+ needHorizScrollbarWithoutVertScrollbar = needHorizScrollbar = true;
+ if (totalVisibleWidth - _layout.Data.Width <= vertScrollBarWidth
+ || _layout.Data.Width - totalVisibleFrozenWidth <= vertScrollBarWidth)
{
- int oldDataHeight = _layout.Data.Height;
- _layout.Data.Height -= horizScrollBarHeight;
- Debug.Assert(_layout.Data.Height >= 0);
- needHorizScrollbarWithoutVertScrollbar = needHorizScrollbar = true;
- if (totalVisibleWidth - _layout.Data.Width <= vertScrollBarWidth
- || _layout.Data.Width - totalVisibleFrozenWidth <= vertScrollBarWidth)
+ // Would we still need a horizontal scrollbar if there were a vertical one?
+ oldfirstDisplayedScrollingRow = DisplayedBandsInfo.FirstDisplayedScrollingRow;
+ ComputeVisibleRows();
+ if (DisplayedBandsInfo.NumTotallyDisplayedFrozenRows == Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen)
+ && DisplayedBandsInfo.NumTotallyDisplayedScrollingRows != totalVisibleRowCount - Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen)
+ && (totalVisibleHeight - totalVisibleFrozenHeight != ComputeHeightOfFittingTrailingScrollingRows(totalVisibleFrozenHeight)))
{
- // Would we still need a horizontal scrollbar if there were a vertical one?
- oldfirstDisplayedScrollingRow = DisplayedBandsInfo.FirstDisplayedScrollingRow;
- ComputeVisibleRows();
- if (DisplayedBandsInfo.NumTotallyDisplayedFrozenRows == Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen)
- && DisplayedBandsInfo.NumTotallyDisplayedScrollingRows != totalVisibleRowCount - Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen)
- && (totalVisibleHeight - totalVisibleFrozenHeight != ComputeHeightOfFittingTrailingScrollingRows(totalVisibleFrozenHeight)))
- {
- needHorizScrollbar = totalVisibleFrozenWidth < _layout.Data.Width - vertScrollBarWidth;
- }
+ needHorizScrollbar = totalVisibleFrozenWidth < _layout.Data.Width - vertScrollBarWidth;
+ }
+
+ DisplayedBandsInfo.FirstDisplayedScrollingRow = oldfirstDisplayedScrollingRow;
+ }
- DisplayedBandsInfo.FirstDisplayedScrollingRow = oldfirstDisplayedScrollingRow;
+ if (needHorizScrollbar)
+ {
+ if (_layout.RowHeadersVisible)
+ {
+ _layout.RowHeaders.Height -= horizScrollBarHeight;
+ Debug.Assert(_layout.RowHeaders.Height >= 0);
}
+ }
+ else
+ {
+ // Restore old data height because turns out a horizontal scroll bar wouldn't make sense
+ _layout.Data.Height = oldDataHeight;
+ }
+ }
- if (needHorizScrollbar)
+ oldfirstDisplayedScrollingRow = DisplayedBandsInfo.FirstDisplayedScrollingRow;
+
+ ComputeVisibleRows();
+ if (allowVertScrollbar
+ && DisplayedBandsInfo.NumTotallyDisplayedFrozenRows == Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen)
+ && DisplayedBandsInfo.NumTotallyDisplayedScrollingRows != totalVisibleRowCount - Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen)
+ && (totalVisibleHeight - totalVisibleFrozenHeight != ComputeHeightOfFittingTrailingScrollingRows(totalVisibleFrozenHeight))
+ && _layout.Data.Height > totalVisibleFrozenHeight
+ && vertScrollBarWidth <= _layout.Data.Width)
+ {
+ _layout.Data.Width -= vertScrollBarWidth;
+ Debug.Assert(_layout.Data.Width >= 0);
+ if (rightToLeftInternal)
+ {
+ _layout.Data.X += vertScrollBarWidth;
+ }
+
+ if (_layout.ColumnHeadersVisible)
+ {
+ _layout.ColumnHeaders.Width -= vertScrollBarWidth;
+ Debug.Assert(_layout.ColumnHeaders.Width >= 0);
+ if (rightToLeftInternal)
{
- if (_layout.RowHeadersVisible)
- {
- _layout.RowHeaders.Height -= horizScrollBarHeight;
- Debug.Assert(_layout.RowHeaders.Height >= 0);
- }
+ _layout.ColumnHeaders.X += vertScrollBarWidth;
}
- else
+ }
+
+ needVertScrollbar = true;
+ }
+
+ DisplayedBandsInfo.FirstDisplayedScrollingCol = ComputeFirstVisibleScrollingColumn();
+
+ // Compute the number of visible columns only after setting up the vertical scroll bar.
+ ComputeVisibleColumns();
+
+ if (allowHorizScrollbar
+ && needVertScrollbar && !needHorizScrollbar
+ && totalVisibleWidth > _layout.Data.Width && totalVisibleFrozenWidth < _layout.Data.Width
+ && horizScrollBarHeight <= _layout.Data.Height)
+ {
+ DisplayedBandsInfo.FirstDisplayedScrollingRow = oldfirstDisplayedScrollingRow;
+ if (_layout.ColumnHeadersVisible)
+ {
+ _layout.ColumnHeaders.Width += vertScrollBarWidth;
+ if (rightToLeftInternal)
{
- // Restore old data height because turns out a horizontal scroll bar wouldn't make sense
- _layout.Data.Height = oldDataHeight;
+ _layout.ColumnHeaders.X -= vertScrollBarWidth;
}
}
- oldfirstDisplayedScrollingRow = DisplayedBandsInfo.FirstDisplayedScrollingRow;
+ _layout.Data.Width += vertScrollBarWidth;
+ if (rightToLeftInternal)
+ {
+ _layout.Data.X -= vertScrollBarWidth;
+ }
+
+ _layout.Data.Height -= horizScrollBarHeight;
+ Debug.Assert(_layout.Data.Height >= 0);
+ needVertScrollbar = false;
ComputeVisibleRows();
- if (allowVertScrollbar
- && DisplayedBandsInfo.NumTotallyDisplayedFrozenRows == Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen)
- && DisplayedBandsInfo.NumTotallyDisplayedScrollingRows != totalVisibleRowCount - Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen)
+ if (DisplayedBandsInfo.NumTotallyDisplayedFrozenRows == Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen)
+ && DisplayedBandsInfo.NumTotallyDisplayedScrollingRows != totalVisibleRowCount
&& (totalVisibleHeight - totalVisibleFrozenHeight != ComputeHeightOfFittingTrailingScrollingRows(totalVisibleFrozenHeight))
&& _layout.Data.Height > totalVisibleFrozenHeight
&& vertScrollBarWidth <= _layout.Data.Width)
@@ -10646,159 +10698,98 @@ private void LayoutScrollBars()
needVertScrollbar = true;
}
- DisplayedBandsInfo.FirstDisplayedScrollingCol = ComputeFirstVisibleScrollingColumn();
- // we compute the number of visible columns only after we set up the vertical scroll bar.
- ComputeVisibleColumns();
-
- if (allowHorizScrollbar
- && needVertScrollbar && !needHorizScrollbar
- && totalVisibleWidth > _layout.Data.Width && totalVisibleFrozenWidth < _layout.Data.Width
- && horizScrollBarHeight <= _layout.Data.Height)
+ if (needVertScrollbar)
{
- DisplayedBandsInfo.FirstDisplayedScrollingRow = oldfirstDisplayedScrollingRow;
- if (_layout.ColumnHeadersVisible)
- {
- _layout.ColumnHeaders.Width += vertScrollBarWidth;
- if (rightToLeftInternal)
- {
- _layout.ColumnHeaders.X -= vertScrollBarWidth;
- }
- }
-
- _layout.Data.Width += vertScrollBarWidth;
- if (rightToLeftInternal)
- {
- _layout.Data.X -= vertScrollBarWidth;
- }
-
- _layout.Data.Height -= horizScrollBarHeight;
- Debug.Assert(_layout.Data.Height >= 0);
- needVertScrollbar = false;
-
- ComputeVisibleRows();
- if (DisplayedBandsInfo.NumTotallyDisplayedFrozenRows == Rows.GetRowCount(DataGridViewElementStates.Visible | DataGridViewElementStates.Frozen)
- && DisplayedBandsInfo.NumTotallyDisplayedScrollingRows != totalVisibleRowCount
- && (totalVisibleHeight - totalVisibleFrozenHeight != ComputeHeightOfFittingTrailingScrollingRows(totalVisibleFrozenHeight))
- && _layout.Data.Height > totalVisibleFrozenHeight
- && vertScrollBarWidth <= _layout.Data.Width)
- {
- _layout.Data.Width -= vertScrollBarWidth;
- Debug.Assert(_layout.Data.Width >= 0);
- if (rightToLeftInternal)
- {
- _layout.Data.X += vertScrollBarWidth;
- }
-
- if (_layout.ColumnHeadersVisible)
- {
- _layout.ColumnHeaders.Width -= vertScrollBarWidth;
- Debug.Assert(_layout.ColumnHeaders.Width >= 0);
- if (rightToLeftInternal)
- {
- _layout.ColumnHeaders.X += vertScrollBarWidth;
- }
- }
-
- needVertScrollbar = true;
- }
-
- if (needVertScrollbar)
- {
- needHorizScrollbar = true;
- }
- else
- {
- needHorizScrollbar = needHorizScrollbarWithoutVertScrollbar;
- }
+ needHorizScrollbar = true;
}
-
- _layout.ResizeBoxRect = default;
- if (needVertScrollbar && needHorizScrollbar)
+ else
{
- _layout.ResizeBoxRect = new Rectangle(
- rightToLeftInternal ? _layout.Data.X - _vertScrollBar.Width : _layout.Data.Right,
- _layout.Data.Bottom,
- _vertScrollBar.Width,
- _horizScrollBar.Height);
+ needHorizScrollbar = needHorizScrollbarWithoutVertScrollbar;
}
+ }
- if (needHorizScrollbar && totalVisibleColCount > 0)
- {
- int widthNotVisible = totalVisibleWidth - _layout.Data.Width;
-
- _horizScrollBar.Minimum = 0;
- _horizScrollBar.Maximum = totalVisibleWidth - totalVisibleFrozenWidth;
- Debug.Assert(_horizScrollBar.Maximum > 0);
- _horizScrollBar.SmallChange = 1;
- _horizScrollBar.LargeChange = Math.Max(totalVisibleWidth - totalVisibleFrozenWidth - widthNotVisible, 0);
- _horizScrollBar.Enabled = Enabled;
- _horizScrollBar.Bounds = new Rectangle(
- rightToLeftInternal ? _layout.Inside.X + _layout.ResizeBoxRect.Width : _layout.Inside.X,
- _layout.Data.Bottom,
- _layout.Inside.Width - _layout.ResizeBoxRect.Width,
- _horizScrollBar.Height);
- _horizScrollBar.Visible = true;
- _horizScrollBar.Invalidate();
- }
- else
- {
- _horizScrollBar.Visible = false;
- HorizontalOffset = 0;
+ _layout.ResizeBoxRect = default;
+ if (needVertScrollbar && needHorizScrollbar)
+ {
+ _layout.ResizeBoxRect = new Rectangle(
+ rightToLeftInternal ? _layout.Data.X - _vertScrollBar.Width : _layout.Data.Right,
+ _layout.Data.Bottom,
+ _vertScrollBar.Width,
+ _horizScrollBar.Height);
+ }
- _horizScrollBar.Enabled = false;
- _horizScrollBar.Minimum = 0;
- _horizScrollBar.Maximum = 1;
- _horizScrollBar.SmallChange = 1;
- _horizScrollBar.LargeChange = 1;
- _horizScrollBar.Value = 0;
- }
+ if (needHorizScrollbar && totalVisibleColCount > 0)
+ {
+ int widthNotVisible = totalVisibleWidth - _layout.Data.Width;
- if (needVertScrollbar)
- {
- int vertScrollBarTop = _layout.Data.Y;
- int vertScrollBarHeight = _layout.Data.Height;
- if (_layout.ColumnHeadersVisible)
- {
- vertScrollBarTop = _layout.ColumnHeaders.Y;
- vertScrollBarHeight += _layout.ColumnHeaders.Height;
- }
- else if (SingleHorizontalBorderAdded)
- {
- vertScrollBarTop--;
- vertScrollBarHeight++;
- }
+ _horizScrollBar.Minimum = 0;
+ _horizScrollBar.Maximum = totalVisibleWidth - totalVisibleFrozenWidth;
+ Debug.Assert(_horizScrollBar.Maximum > 0);
+ _horizScrollBar.SmallChange = 1;
+ _horizScrollBar.LargeChange = Math.Max(totalVisibleWidth - totalVisibleFrozenWidth - widthNotVisible, 0);
+ _horizScrollBar.Enabled = Enabled;
+ _horizScrollBar.Bounds = new Rectangle(
+ rightToLeftInternal ? _layout.Inside.X + _layout.ResizeBoxRect.Width : _layout.Inside.X,
+ _layout.Data.Bottom,
+ _layout.Inside.Width - _layout.ResizeBoxRect.Width,
+ _horizScrollBar.Height);
+ _horizScrollBar.Visible = true;
+ _horizScrollBar.Invalidate();
+ }
+ else
+ {
+ _horizScrollBar.Visible = false;
+ HorizontalOffset = 0;
- _vertScrollBar.Minimum = 0;
- _vertScrollBar.Maximum = totalVisibleHeight - totalVisibleFrozenHeight;
- Debug.Assert(_vertScrollBar.Maximum > 0);
- _vertScrollBar.Value = ComputeHeightOfScrolledOffRows();
- _vertScrollBar.LargeChange = _layout.Data.Height - totalVisibleFrozenHeight;
- _vertScrollBar.Bounds = new Rectangle(
- rightToLeftInternal ? _layout.Data.X - _vertScrollBar.Width : _layout.Data.Right,
- vertScrollBarTop,
- _vertScrollBar.Width,
- vertScrollBarHeight);
- _vertScrollBar.Enabled = Enabled;
- _vertScrollBar.Visible = true;
- _vertScrollBar.Invalidate();
+ _horizScrollBar.Enabled = false;
+ _horizScrollBar.Minimum = 0;
+ _horizScrollBar.Maximum = 1;
+ _horizScrollBar.SmallChange = 1;
+ _horizScrollBar.LargeChange = 1;
+ _horizScrollBar.Value = 0;
+ }
- VerticalScrollingOffset = _vertScrollBar.Value;
+ if (needVertScrollbar)
+ {
+ int vertScrollBarTop = _layout.Data.Y;
+ int vertScrollBarHeight = _layout.Data.Height;
+ if (_layout.ColumnHeadersVisible)
+ {
+ vertScrollBarTop = _layout.ColumnHeaders.Y;
+ vertScrollBarHeight += _layout.ColumnHeaders.Height;
}
- else
+ else if (SingleHorizontalBorderAdded)
{
- _vertScrollBar.Visible = false;
- VerticalScrollingOffset = ComputeHeightOfScrolledOffRows();
-
- _vertScrollBar.Enabled = false;
- _vertScrollBar.Minimum = 0;
- _vertScrollBar.Maximum = 1;
- _vertScrollBar.LargeChange = 1;
- _vertScrollBar.Value = 0;
+ vertScrollBarTop--;
+ vertScrollBarHeight++;
}
+
+ _vertScrollBar.Minimum = 0;
+ _vertScrollBar.Maximum = totalVisibleHeight - totalVisibleFrozenHeight;
+ Debug.Assert(_vertScrollBar.Maximum > 0);
+ _vertScrollBar.Value = ComputeHeightOfScrolledOffRows();
+ _vertScrollBar.LargeChange = _layout.Data.Height - totalVisibleFrozenHeight;
+ _vertScrollBar.Bounds = new Rectangle(
+ rightToLeftInternal ? _layout.Data.X - _vertScrollBar.Width : _layout.Data.Right,
+ vertScrollBarTop,
+ _vertScrollBar.Width,
+ vertScrollBarHeight);
+ _vertScrollBar.Enabled = Enabled;
+ _vertScrollBar.Visible = true;
+ _vertScrollBar.Invalidate();
+
+ VerticalScrollingOffset = _vertScrollBar.Value;
}
- finally
+ else
{
- ResumeLayout(false);
+ _vertScrollBar.Visible = false;
+ VerticalScrollingOffset = ComputeHeightOfScrolledOffRows();
+
+ _vertScrollBar.Enabled = false;
+ _vertScrollBar.Minimum = 0;
+ _vertScrollBar.Maximum = 1;
+ _vertScrollBar.LargeChange = 1;
+ _vertScrollBar.Value = 0;
}
}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewRowHeaderCell.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewRowHeaderCell.cs
index aeff9fdaeea..cb0c2e2655d 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewRowHeaderCell.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/DataGridView/DataGridViewRowHeaderCell.cs
@@ -1036,9 +1036,9 @@ private void PaintIcon(
int height = bounds.Y + (bounds.Height - s_iconsHeight) / 2;
Rectangle bmpRect = new(width, height, s_iconsWidth, s_iconsHeight);
- ValueColorMap map = new(Color.Black, foreColor);
+ (Color OldColor, Color NewColor) map = new(Color.Black, foreColor);
using ImageAttributes attr = new();
- attr.SetRemapTable(ColorAdjustType.Bitmap, new ReadOnlySpan(ref map));
+ attr.SetRemapTable(ColorAdjustType.Bitmap, new ReadOnlySpan<(Color OldColor, Color NewColor)>(ref map));
if (SystemInformation.HighContrast &&
// We can't replace black with white and vice versa as in other cases due to the colors of images are not exactly black and white.
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGrid.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGrid.cs
index 19de619a6ff..8d9c0e31b27 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGrid.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGrid.cs
@@ -140,7 +140,7 @@ public PropertyGrid()
_onComponentRemoved = OnComponentRemoved;
_onComponentChanged = OnComponentChanged;
- SuspendLayout();
+ using SuspendLayoutScope layoutScope = new(this);
// Scaling PropertyGrid but its children will be excluded from AutoScale. Please see OnLayoutInternal().
AutoScaleMode = AutoScaleMode.Inherit;
@@ -155,14 +155,11 @@ public PropertyGrid()
{
RescaleConstants();
}
- else
+ else if (!s_isScalingInitialized)
{
- if (!s_isScalingInitialized)
- {
- s_normalButtonSize = LogicalToDeviceUnits(s_defaultNormalButtonSize);
- s_largeButtonSize = LogicalToDeviceUnits(s_defaultLargeButtonSize);
- s_isScalingInitialized = true;
- }
+ s_normalButtonSize = LogicalToDeviceUnits(s_defaultNormalButtonSize);
+ s_largeButtonSize = LogicalToDeviceUnits(s_defaultLargeButtonSize);
+ s_isScalingInitialized = true;
}
try
@@ -177,57 +174,62 @@ public PropertyGrid()
_separator2 = CreateSeparatorButton();
_toolStrip = new PropertyGridToolStrip(this);
- _toolStrip.SuspendLayout();
- _toolStrip.ShowItemToolTips = true;
-
- _toolStrip.AccessibleRole = AccessibleRole.ToolBar;
- _toolStrip.TabStop = true;
- _toolStrip.AllowMerge = false;
-
- // This caption is for testing.
- _toolStrip.Text = "PropertyGridToolBar";
-
- // LayoutInternal handles positioning, and for perf reasons, we manually size.
- _toolStrip.Dock = DockStyle.None;
- _toolStrip.AutoSize = false;
- _toolStrip.TabIndex = 1;
- _toolStrip.ImageScalingSize = s_normalButtonSize;
-
- // Parity with the old...
- _toolStrip.CanOverflow = false;
-
- // Hide the grip but add in a few more pixels of padding.
- _toolStrip.GripStyle = ToolStripGripStyle.Hidden;
- Padding toolStripPadding = _toolStrip.Padding;
- toolStripPadding.Left = 2;
- _toolStrip.Padding = toolStripPadding;
- SetToolStripRenderer();
-
- // Always add the property tab here.
- AddTab(DefaultTabType, PropertyTabScope.Static);
-
- _helpPane = new(this);
- _helpPane.SuspendLayout();
- _helpPane.TabStop = false;
- _helpPane.Dock = DockStyle.None;
- _helpPane.BackColor = SystemColors.Control;
- _helpPane.ForeColor = SystemColors.ControlText;
- _helpPane.MouseMove += OnChildMouseMove;
- _helpPane.MouseDown += OnChildMouseDown;
-
- _commandsPane = new CommandsPane(this);
- _commandsPane.SuspendLayout();
- _commandsPane.TabIndex = 3;
- _commandsPane.Dock = DockStyle.None;
- SetHotCommandColors();
- _commandsPane.Visible = false;
- _commandsPane.MouseMove += OnChildMouseMove;
- _commandsPane.MouseDown += OnChildMouseDown;
- Controls.AddRange(new Control[] { _helpPane, _commandsPane, _gridView, _toolStrip });
+ // SetupToolbar should perform the layout
+ using SuspendLayoutScope suspendToolStripLayout = new(_toolStrip, performLayout: false);
+ {
+ _toolStrip.ShowItemToolTips = true;
+
+ _toolStrip.AccessibleRole = AccessibleRole.ToolBar;
+ _toolStrip.TabStop = true;
+ _toolStrip.AllowMerge = false;
+
+ // This caption is for testing.
+ _toolStrip.Text = "PropertyGridToolBar";
+
+ // LayoutInternal handles positioning, and for perf reasons, we manually size.
+ _toolStrip.Dock = DockStyle.None;
+ _toolStrip.AutoSize = false;
+ _toolStrip.TabIndex = 1;
+ _toolStrip.ImageScalingSize = s_normalButtonSize;
+
+ // Parity with the old.
+ _toolStrip.CanOverflow = false;
+
+ // Hide the grip but add in a few more pixels of padding.
+ _toolStrip.GripStyle = ToolStripGripStyle.Hidden;
+ Padding toolStripPadding = _toolStrip.Padding;
+ toolStripPadding.Left = 2;
+ _toolStrip.Padding = toolStripPadding;
+ SetToolStripRenderer();
+
+ // Always add the property tab here.
+ AddTab(DefaultTabType, PropertyTabScope.Static);
+
+ _helpPane = new(this);
+ using SuspendLayoutScope suspendHelpPaneLayout = new(_helpPane, performLayout: false);
+
+ _helpPane.TabStop = false;
+ _helpPane.Dock = DockStyle.None;
+ _helpPane.BackColor = SystemColors.Control;
+ _helpPane.ForeColor = SystemColors.ControlText;
+ _helpPane.MouseMove += OnChildMouseMove;
+ _helpPane.MouseDown += OnChildMouseDown;
+
+ _commandsPane = new CommandsPane(this);
+ using SuspendLayoutScope suspendCommandsPaneLayout = new(_commandsPane, performLayout: false);
+ _commandsPane.TabIndex = 3;
+ _commandsPane.Dock = DockStyle.None;
+ SetHotCommandColors();
+ _commandsPane.Visible = false;
+ _commandsPane.MouseMove += OnChildMouseMove;
+ _commandsPane.MouseDown += OnChildMouseDown;
+
+ Controls.AddRange([_helpPane, _commandsPane, _gridView, _toolStrip]);
+
+ SetActiveControl(_gridView);
+ }
- SetActiveControl(_gridView);
- _toolStrip.ResumeLayout(performLayout: false); // SetupToolbar should perform the layout
SetupToolbar();
PropertySort = PropertySort.Categorized | PropertySort.Alphabetical;
SetSelectState(0);
@@ -236,13 +238,6 @@ public PropertyGrid()
{
Debug.Fail(ex.ToString());
}
- finally
- {
- _helpPane?.ResumeLayout(performLayout: false);
- _commandsPane?.ResumeLayout(performLayout: false);
-
- ResumeLayout(performLayout: true);
- }
}
internal IDesignerHost? ActiveDesigner
@@ -3966,6 +3961,7 @@ private void SetupToolbar(bool fullRebuild)
designPage,
propertyPagesButtonHandler,
useRadioButtonRole: false);
+
_viewPropertyPagesButton.Enabled = false;
buttonList.Add(_viewPropertyPagesButton);
@@ -3980,15 +3976,15 @@ private void SetupToolbar(bool fullRebuild)
_toolStrip.ImageList = LargeButtons ? _largeButtonImages : _normalButtonImages;
- _toolStrip.SuspendLayout();
- _toolStrip.Items.Clear();
- for (int j = 0; j < buttonList.Count; j++)
+ using (SuspendLayoutScope scope = new(_toolStrip))
{
- _toolStrip.Items.Add(buttonList[j]);
+ _toolStrip.Items.Clear();
+ for (int j = 0; j < buttonList.Count; j++)
+ {
+ _toolStrip.Items.Add(buttonList[j]);
+ }
}
- _toolStrip.ResumeLayout();
-
if (_tabsDirty)
{
// If we're redoing our tabs make sure we setup the toolbar area correctly.
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/HelpPane.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/HelpPane.cs
index 372c0d360cf..338bab2e926 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/HelpPane.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/HelpPane.cs
@@ -32,7 +32,8 @@ internal partial class HelpPane : PropertyGrid.SnappableControl
internal HelpPane(PropertyGrid owner) : base(owner)
{
- SuspendLayout();
+ using SuspendLayoutScope scope = new(this, performLayout: false);
+
_titleLabel = new()
{
UseMnemonic = false,
@@ -54,7 +55,6 @@ internal HelpPane(PropertyGrid owner) : base(owner)
Text = SR.PropertyGridHelpPaneTitle;
SetStyle(ControlStyles.Selectable, false);
- ResumeLayout(false);
}
public virtual int Lines
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/PropertyGridView.DropDownHolder.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/PropertyGridView.DropDownHolder.cs
index bcf9207e3e5..7be831ce063 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/PropertyGridView.DropDownHolder.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/PropertyGrid/PropertyGridInternal/PropertyGridView.DropDownHolder.cs
@@ -597,9 +597,8 @@ public void SetDropDownControl(Control? control, bool resizable)
}
// Parent the control now. That way it can inherit our font and scale itself if it wants to.
- try
+ using (SuspendLayoutScope scope = new(this, performLayout: true))
{
- SuspendLayout();
Controls.Add(control);
Size size = new(2 * DropDownHolderBorder + control.Width, 2 * DropDownHolderBorder + control.Height);
@@ -657,10 +656,6 @@ public void SetDropDownControl(Control? control, bool resizable)
Controls.Add(CreateNewLink);
}
}
- finally
- {
- ResumeLayout(true);
- }
// Hook the resize event.
_currentControl.Resize += OnCurrentControlResize;
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/RichTextBox/RichTextBox.OleCallback.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/RichTextBox/RichTextBox.OleCallback.cs
index ef8fed3f530..74eb21cc9f9 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/RichTextBox/RichTextBox.OleCallback.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/RichTextBox/RichTextBox.OleCallback.cs
@@ -139,7 +139,7 @@ public HRESULT QueryAcceptData(Com.IDataObject* lpdataobj, ushort* lpcfFormat, R
keyState |= MODIFIERKEYS_FLAGS.MK_SHIFT;
}
- _lastDataObject = DataObject.FromComPointer(lpdataobj);
+ _lastDataObject = new DataObject(lpdataobj);
if (!_owner.EnableAutoDragDrop)
{
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TextBox/TextBox.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TextBox/TextBox.cs
index 82149a87784..2973820e324 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TextBox/TextBox.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TextBox/TextBox.cs
@@ -721,17 +721,6 @@ private protected override void SelectInternal(int start, int length, int textLe
base.SelectInternal(start, length, textLen);
}
- private string[] GetStringsForAutoComplete()
- {
- string[] strings = new string[AutoCompleteCustomSource.Count];
- for (int i = 0; i < AutoCompleteCustomSource.Count; i++)
- {
- strings[i] = AutoCompleteCustomSource[i];
- }
-
- return strings;
- }
-
///
/// Sets the AutoComplete mode in TextBox.
///
@@ -767,7 +756,7 @@ private unsafe void SetAutoComplete(bool reset)
{
if (_stringSource is null)
{
- _stringSource = new StringSource(GetStringsForAutoComplete());
+ _stringSource = new StringSource(AutoCompleteCustomSource.ToArray());
if (!_stringSource.Bind(this, (AUTOCOMPLETEOPTIONS)AutoCompleteMode))
{
throw new ArgumentException(SR.AutoCompleteFailure);
@@ -775,7 +764,7 @@ private unsafe void SetAutoComplete(bool reset)
}
else
{
- _stringSource.RefreshList(GetStringsForAutoComplete());
+ _stringSource.RefreshList(AutoCompleteCustomSource.ToArray());
}
}
}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStrip.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStrip.cs
index 23abca95b0f..419b0e449fe 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStrip.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStrip.cs
@@ -3974,27 +3974,26 @@ internal void PaintInsertionMark(Graphics g)
int start = _lastInsertionMarkRect.X;
int verticalBeamStart = start + 2;
- // draw two vertical lines
- g.DrawLines(SystemPens.ControlText,
- new Point[]
- {
- new(verticalBeamStart, _lastInsertionMarkRect.Y), new(verticalBeamStart, _lastInsertionMarkRect.Bottom - 1), // first vertical line
- new(verticalBeamStart + 1, _lastInsertionMarkRect.Y), new(verticalBeamStart + 1, _lastInsertionMarkRect.Bottom - 1), // second vertical line
- });
- // then two top horizontal
- g.DrawLines(SystemPens.ControlText,
- new Point[]
- {
- new(start, _lastInsertionMarkRect.Bottom - 1), new(start + widthOfBeam - 1, _lastInsertionMarkRect.Bottom - 1), // bottom line
- new(start + 1, _lastInsertionMarkRect.Bottom - 2), new(start + widthOfBeam - 2, _lastInsertionMarkRect.Bottom - 2), // bottom second line
- });
- // then two bottom horizontal
- g.DrawLines(SystemPens.ControlText,
- new Point[]
- {
- new(start, _lastInsertionMarkRect.Y), new(start + widthOfBeam - 1, _lastInsertionMarkRect.Y), // top line
- new(start + 1, _lastInsertionMarkRect.Y + 1), new(start + widthOfBeam - 2, _lastInsertionMarkRect.Y + 1) // top second line
- });
+ // Draw vertical lines.
+ g.DrawLines(SystemPens.ControlText, (ReadOnlySpan)
+ [
+ new(verticalBeamStart, _lastInsertionMarkRect.Y), new(verticalBeamStart, _lastInsertionMarkRect.Bottom - 1),
+ new(verticalBeamStart + 1, _lastInsertionMarkRect.Y), new(verticalBeamStart + 1, _lastInsertionMarkRect.Bottom - 1)
+ ]);
+
+ // Draw top horizontal lines.
+ g.DrawLines(SystemPens.ControlText, (ReadOnlySpan)
+ [
+ new(start, _lastInsertionMarkRect.Bottom - 1), new(start + widthOfBeam - 1, _lastInsertionMarkRect.Bottom - 1),
+ new(start + 1, _lastInsertionMarkRect.Bottom - 2), new(start + widthOfBeam - 2, _lastInsertionMarkRect.Bottom - 2)
+ ]);
+
+ // Draw bottom horizontal lines.
+ g.DrawLines(SystemPens.ControlText, (ReadOnlySpan)
+ [
+ new(start, _lastInsertionMarkRect.Y), new(start + widthOfBeam - 1, _lastInsertionMarkRect.Y),
+ new(start + 1, _lastInsertionMarkRect.Y + 1), new(start + widthOfBeam - 2, _lastInsertionMarkRect.Y + 1)
+ ]);
}
else
{
@@ -4002,27 +4001,26 @@ internal void PaintInsertionMark(Graphics g)
int start = _lastInsertionMarkRect.Y;
int horizontalBeamStart = start + 2;
- // draw two horizontal lines
- g.DrawLines(SystemPens.ControlText,
- new Point[]
- {
- new(_lastInsertionMarkRect.X, horizontalBeamStart), new(_lastInsertionMarkRect.Right - 1, horizontalBeamStart), // first vertical line
- new(_lastInsertionMarkRect.X, horizontalBeamStart + 1), new(_lastInsertionMarkRect.Right - 1, horizontalBeamStart + 1), // second vertical line
- });
- // then two left vertical
- g.DrawLines(SystemPens.ControlText,
- new Point[]
- {
- new(_lastInsertionMarkRect.X, start), new(_lastInsertionMarkRect.X, start + widthOfBeam - 1), // left line
- new(_lastInsertionMarkRect.X + 1, start + 1), new(_lastInsertionMarkRect.X + 1, start + widthOfBeam - 2), // second left line
- });
- // then two right vertical
- g.DrawLines(SystemPens.ControlText,
- new Point[]
- {
- new(_lastInsertionMarkRect.Right - 1, start), new(_lastInsertionMarkRect.Right - 1, start + widthOfBeam - 1), // right line
- new(_lastInsertionMarkRect.Right - 2, start + 1), new(_lastInsertionMarkRect.Right - 2, start + widthOfBeam - 2), // second right line
- });
+ // Draw horizontal lines.
+ g.DrawLines(SystemPens.ControlText, (ReadOnlySpan)
+ [
+ new(_lastInsertionMarkRect.X, horizontalBeamStart), new(_lastInsertionMarkRect.Right - 1, horizontalBeamStart),
+ new(_lastInsertionMarkRect.X, horizontalBeamStart + 1), new(_lastInsertionMarkRect.Right - 1, horizontalBeamStart + 1)
+ ]);
+
+ // Draw left vertical lines.
+ g.DrawLines(SystemPens.ControlText, (ReadOnlySpan)
+ [
+ new(_lastInsertionMarkRect.X, start), new(_lastInsertionMarkRect.X, start + widthOfBeam - 1),
+ new(_lastInsertionMarkRect.X + 1, start + 1), new(_lastInsertionMarkRect.X + 1, start + widthOfBeam - 2)
+ ]);
+
+ // Draw right vertical lines.
+ g.DrawLines(SystemPens.ControlText, (ReadOnlySpan)
+ [
+ new(_lastInsertionMarkRect.Right - 1, start), new(_lastInsertionMarkRect.Right - 1, start + widthOfBeam - 1),
+ new(_lastInsertionMarkRect.Right - 2, start + 1), new(_lastInsertionMarkRect.Right - 2, start + widthOfBeam - 2)
+ ]);
}
}
}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripHighContrastRenderer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripHighContrastRenderer.cs
index be9809e4b3a..5f0b6cc636e 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripHighContrastRenderer.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/ToolStrips/ToolStripHighContrastRenderer.cs
@@ -492,11 +492,11 @@ private void RenderItemImageOfLowColorDepth(ToolStripItemImageRenderEventArgs e)
if (IsHighContrastWhiteOnBlack() && !(FillWhenSelected && (item.Pressed || item.Selected)))
{
// Translate white, black and blue to colors visible in high contrast mode.
- Span map =
+ Span<(Color OldColor, Color NewColor)> map =
[
- new ValueColorMap(Color.Black, Color.White),
- new ValueColorMap(Color.White, Color.Black),
- new ValueColorMap(Color.FromArgb(0, 0, 128), Color.White)
+ new(Color.Black, Color.White),
+ new(Color.White, Color.Black),
+ new(Color.FromArgb(0, 0, 128), Color.White)
];
attrs.SetRemapTable(ColorAdjustType.Bitmap, map);
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TreeView/TreeNode.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TreeView/TreeNode.cs
index 3a403eac303..a39a2f968eb 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TreeView/TreeNode.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TreeView/TreeNode.cs
@@ -13,10 +13,10 @@
namespace System.Windows.Forms;
///
-/// Implements a node of a .
+/// Implements a node of a .
///
-[TypeConverterAttribute(typeof(TreeNodeConverter))]
-[Serializable] // This class participates in resx serialization.
+[TypeConverter(typeof(TreeNodeConverter))]
+[Serializable] // This class participates in ResX serialization.
[DefaultProperty(nameof(Text))]
[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicParameterlessConstructor)]
public partial class TreeNode : MarshalByRefObject, ICloneable, ISerializable
@@ -152,9 +152,9 @@ public TreeNode(string? text, int imageIndex, int selectedImageIndex, TreeNode[]
Nodes.AddRange(children);
}
- /**
- * Constructor used in deserialization
- */
+ ///
+ /// Constructor used in deserialization from resources.
+ ///
protected TreeNode(SerializationInfo serializationInfo, StreamingContext context)
: this()
{
@@ -1107,8 +1107,10 @@ public TreeView? TreeView
}
}
- internal TreeNodeAccessibleObject AccessibilityObject
- => _accessibleObject ??= new TreeNodeAccessibleObject(this, TreeView!);
+ internal TreeNodeAccessibleObject? AccessibilityObject =>
+ _accessibleObject ??= TreeView is null
+ ? null
+ : new TreeNodeAccessibleObject(this, TreeView);
///
/// Adds a new child node at the appropriate sorted position
@@ -1684,7 +1686,7 @@ public void ExpandAll()
internal List GetSelfAndChildNodes()
{
- List nodes = new() { this };
+ List nodes = [this];
AggregateChildNodesToList(this);
return nodes;
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TreeView/TreeView.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TreeView/TreeView.cs
index 7b95d2b739b..0390deaa5bf 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TreeView/TreeView.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TreeView/TreeView.cs
@@ -10,6 +10,7 @@
using System.Windows.Forms.VisualStyles;
using Windows.Win32.System.Variant;
using Windows.Win32.UI.Accessibility;
+using static System.Windows.Forms.TreeNode;
namespace System.Windows.Forms;
@@ -1830,12 +1831,10 @@ protected override bool IsInputKey(Keys keyData)
}
///
- /// Fires the DrawNode event.
+ /// Raises the DrawNode event.
///
- protected virtual void OnDrawNode(DrawTreeNodeEventArgs e)
- {
+ protected virtual void OnDrawNode(DrawTreeNodeEventArgs e) =>
_onDrawNode?.Invoke(this, e);
- }
protected override void OnHandleCreated(EventArgs e)
{
@@ -2080,15 +2079,13 @@ protected override void OnMouseHover(EventArgs e)
}
///
- /// Fires the beforeLabelEdit event.
+ /// Raises the beforeLabelEdit event.
///
- protected virtual void OnBeforeLabelEdit(NodeLabelEditEventArgs e)
- {
+ protected virtual void OnBeforeLabelEdit(NodeLabelEditEventArgs e) =>
_onBeforeLabelEdit?.Invoke(this, e);
- }
///
- /// Fires the afterLabelEdit event.
+ /// Raises the afterLabelEdit event.
///
protected virtual void OnAfterLabelEdit(NodeLabelEditEventArgs e)
{
@@ -2096,31 +2093,34 @@ protected virtual void OnAfterLabelEdit(NodeLabelEditEventArgs e)
// Raise an event to highlight & announce the edited node
// if editing hasn't been canceled.
- if (IsAccessibilityObjectCreated && !e.CancelEdit)
+ if (IsAccessibilityObjectCreated && !e.CancelEdit && e.Node is not null)
{
- e.Node!.AccessibilityObject.RaiseAutomationEvent(UIA_EVENT_ID.UIA_AutomationFocusChangedEventId);
+ e.Node.AccessibilityObject?.RaiseAutomationEvent(UIA_EVENT_ID.UIA_AutomationFocusChangedEventId);
}
}
///
- /// Fires the beforeCheck event.
+ /// Raises the beforeCheck event.
///
- protected virtual void OnBeforeCheck(TreeViewCancelEventArgs e)
- {
+ protected virtual void OnBeforeCheck(TreeViewCancelEventArgs e) =>
_onBeforeCheck?.Invoke(this, e);
- }
///
- /// Fires the afterCheck event.
+ /// Raises the afterCheck event.
///
protected virtual void OnAfterCheck(TreeViewEventArgs e)
{
_onAfterCheck?.Invoke(this, e);
// Raise an event to announce a toggle state change.
- if (IsAccessibilityObjectCreated)
+ if (IsAccessibilityObjectCreated && e.Node is not null)
{
- AccessibleObject nodeAccessibleObject = e.Node!.AccessibilityObject;
+ TreeNodeAccessibleObject? nodeAccessibleObject = e.Node.AccessibilityObject;
+ if (nodeAccessibleObject is null)
+ {
+ return;
+ }
+
ToggleState newState = nodeAccessibleObject.ToggleState;
ToggleState oldState = newState == ToggleState.ToggleState_On
? ToggleState.ToggleState_Off
@@ -2134,24 +2134,22 @@ protected virtual void OnAfterCheck(TreeViewEventArgs e)
}
///
- /// Fires the beforeCollapse event.
+ /// Raises the beforeCollapse event.
///
- protected internal virtual void OnBeforeCollapse(TreeViewCancelEventArgs e)
- {
+ protected internal virtual void OnBeforeCollapse(TreeViewCancelEventArgs e) =>
_onBeforeCollapse?.Invoke(this, e);
- }
///
- /// Fires the afterCollapse event.
+ /// Raises the afterCollapse event.
///
protected internal virtual void OnAfterCollapse(TreeViewEventArgs e)
{
_onAfterCollapse?.Invoke(this, e);
// Raise an event to announce the expand-collapse state change.
- if (IsAccessibilityObjectCreated)
+ if (IsAccessibilityObjectCreated && e.Node is not null)
{
- e.Node!.AccessibilityObject.RaiseAutomationPropertyChangedEvent(
+ e.Node.AccessibilityObject?.RaiseAutomationPropertyChangedEvent(
UIA_PROPERTY_ID.UIA_ExpandCollapseExpandCollapseStatePropertyId,
oldValue: (VARIANT)(int)ExpandCollapseState.ExpandCollapseState_Expanded,
newValue: (VARIANT)(int)ExpandCollapseState.ExpandCollapseState_Collapsed);
@@ -2159,24 +2157,22 @@ protected internal virtual void OnAfterCollapse(TreeViewEventArgs e)
}
///
- /// Fires the beforeExpand event.
+ /// Raises the beforeExpand event.
///
- protected virtual void OnBeforeExpand(TreeViewCancelEventArgs e)
- {
+ protected virtual void OnBeforeExpand(TreeViewCancelEventArgs e) =>
_onBeforeExpand?.Invoke(this, e);
- }
///
- /// Fires the afterExpand event.
+ /// Raises the afterExpand event.
///
protected virtual void OnAfterExpand(TreeViewEventArgs e)
{
_onAfterExpand?.Invoke(this, e);
// Raise an event to announce the expand-collapse state change.
- if (IsAccessibilityObjectCreated)
+ if (IsAccessibilityObjectCreated && e.Node is not null)
{
- e.Node!.AccessibilityObject.RaiseAutomationPropertyChangedEvent(
+ e.Node.AccessibilityObject?.RaiseAutomationPropertyChangedEvent(
UIA_PROPERTY_ID.UIA_ExpandCollapseExpandCollapseStatePropertyId,
oldValue: (VARIANT)(int)ExpandCollapseState.ExpandCollapseState_Collapsed,
newValue: (VARIANT)(int)ExpandCollapseState.ExpandCollapseState_Expanded);
@@ -2184,40 +2180,39 @@ protected virtual void OnAfterExpand(TreeViewEventArgs e)
}
///
- /// Fires the ItemDrag event.
+ /// Raises the ItemDrag event.
///
- protected virtual void OnItemDrag(ItemDragEventArgs e)
- {
+ protected virtual void OnItemDrag(ItemDragEventArgs e) =>
_onItemDrag?.Invoke(this, e);
- }
///
- /// Fires the NodeMouseHover event.
+ /// Raises the NodeMouseHover event.
///
- protected virtual void OnNodeMouseHover(TreeNodeMouseHoverEventArgs e)
- {
+ protected virtual void OnNodeMouseHover(TreeNodeMouseHoverEventArgs e) =>
_onNodeMouseHover?.Invoke(this, e);
- }
///
- /// Fires the beforeSelect event.
+ /// Raises the beforeSelect event.
///
- protected virtual void OnBeforeSelect(TreeViewCancelEventArgs e)
- {
+ protected virtual void OnBeforeSelect(TreeViewCancelEventArgs e) =>
_onBeforeSelect?.Invoke(this, e);
- }
///
- /// Fires the afterSelect event.
+ /// Raises the afterSelect event.
///
protected virtual void OnAfterSelect(TreeViewEventArgs e)
{
_onAfterSelect?.Invoke(this, e);
// Raise an event to highlight & announce the selected node.
- if (IsAccessibilityObjectCreated)
+ if (IsAccessibilityObjectCreated && e.Node is not null)
{
- AccessibleObject nodeAccessibleObject = e.Node!.AccessibilityObject;
+ TreeNodeAccessibleObject? nodeAccessibleObject = e.Node.AccessibilityObject;
+ if (nodeAccessibleObject is null)
+ {
+ return;
+ }
+
nodeAccessibleObject.RaiseAutomationEvent(UIA_EVENT_ID.UIA_AutomationFocusChangedEventId);
nodeAccessibleObject.RaiseAutomationEvent(UIA_EVENT_ID.UIA_SelectionItem_ElementSelectedEventId);
@@ -2230,20 +2225,16 @@ protected virtual void OnAfterSelect(TreeViewEventArgs e)
}
///
- /// Fires the onNodeMouseClick event.
+ /// Raises the onNodeMouseClick event.
///
- protected virtual void OnNodeMouseClick(TreeNodeMouseClickEventArgs e)
- {
+ protected virtual void OnNodeMouseClick(TreeNodeMouseClickEventArgs e) =>
_onNodeMouseClick?.Invoke(this, e);
- }
///
- /// Fires the onNodeMouseDoubleClick event.
+ /// Raises the onNodeMouseDoubleClick event.
///
- protected virtual void OnNodeMouseDoubleClick(TreeNodeMouseClickEventArgs e)
- {
+ protected virtual void OnNodeMouseDoubleClick(TreeNodeMouseClickEventArgs e) =>
_onNodeMouseDoubleClick?.Invoke(this, e);
- }
///
/// Handles the OnBeforeCheck / OnAfterCheck for keyboard clicks
@@ -2373,20 +2364,20 @@ private bool ShouldSerializeSelectedImageIndex()
{
if (_imageList is not null)
{
- return (SelectedImageIndex != 0);
+ return SelectedImageIndex != 0;
}
- return (SelectedImageIndex != ImageList.Indexer.DefaultIndex);
+ return SelectedImageIndex != ImageList.Indexer.DefaultIndex;
}
private bool ShouldSerializeImageIndex()
{
if (_imageList is not null)
{
- return (ImageIndex != 0);
+ return ImageIndex != 0;
}
- return (ImageIndex != ImageList.Indexer.DefaultIndex);
+ return ImageIndex != ImageList.Indexer.DefaultIndex;
}
///
@@ -2433,14 +2424,14 @@ private unsafe void TvnBeginDrag(MouseButtons buttons, NMTREEVIEWW* nmtv)
OnItemDrag(new ItemDragEventArgs(buttons, node));
}
- private unsafe IntPtr TvnExpanding(NMTREEVIEWW* nmtv)
+ private unsafe nint TvnExpanding(NMTREEVIEWW* nmtv)
{
TVITEMW item = nmtv->itemNew;
// Check for invalid node handle
if (item.hItem == IntPtr.Zero)
{
- return IntPtr.Zero;
+ return 0;
}
TreeViewCancelEventArgs? e = null;
@@ -2455,7 +2446,7 @@ private unsafe IntPtr TvnExpanding(NMTREEVIEWW* nmtv)
OnBeforeCollapse(e);
}
- return (IntPtr)(e.Cancel ? 1 : 0);
+ return e.Cancel ? 1 : 0;
}
private unsafe void TvnExpanded(NMTREEVIEWW* nmtv)
@@ -2484,17 +2475,17 @@ private unsafe void TvnExpanded(NMTREEVIEWW* nmtv)
}
}
- private unsafe IntPtr TvnSelecting(NMTREEVIEWW* nmtv)
+ private unsafe nint TvnSelecting(NMTREEVIEWW* nmtv)
{
if (_treeViewState[TREEVIEWSTATE_ignoreSelects])
{
- return (IntPtr)1;
+ return 1;
}
// Check for invalid node handle
if (nmtv->itemNew.hItem == IntPtr.Zero)
{
- return IntPtr.Zero;
+ return 0;
}
TreeNode? node = NodeFromHandle(nmtv->itemNew.hItem);
@@ -2514,7 +2505,7 @@ private unsafe IntPtr TvnSelecting(NMTREEVIEWW* nmtv)
TreeViewCancelEventArgs e = new(node, false, action);
OnBeforeSelect(e);
- return (IntPtr)(e.Cancel ? 1 : 0);
+ return e.Cancel ? 1 : 0;
}
private unsafe void TvnSelected(NMTREEVIEWW* nmtv)
@@ -2846,14 +2837,14 @@ private unsafe void CustomDraw(ref Message m)
{
g.FillRectangle(SystemBrushes.Highlight, bounds);
ControlPaint.DrawFocusRectangle(g, bounds, color, SystemColors.Highlight);
- TextRenderer.DrawText(g, e.Node!.Text, font, bounds, color, TextFormatFlags.Default);
+ TextRenderer.DrawText(g, node.Text, font, bounds, color, TextFormatFlags.Default);
}
else
{
using var brush = BackColor.GetCachedSolidBrushScope();
g.FillRectangle(brush, bounds);
- TextRenderer.DrawText(g, e.Node!.Text, font, bounds, color, TextFormatFlags.Default);
+ TextRenderer.DrawText(g, node.Text, font, bounds, color, TextFormatFlags.Default);
}
}
}
@@ -3094,7 +3085,7 @@ protected override void OnGotFocus(EventArgs e)
// Raise an event to highlight & announce the selected node.
if (IsAccessibilityObjectCreated)
{
- SelectedNode?.AccessibilityObject.RaiseAutomationEvent(UIA_EVENT_ID.UIA_AutomationFocusChangedEventId);
+ SelectedNode?.AccessibilityObject?.RaiseAutomationEvent(UIA_EVENT_ID.UIA_AutomationFocusChangedEventId);
}
}
@@ -3105,7 +3096,7 @@ protected override void OnLostFocus(EventArgs e)
}
///
- /// Shows the context menu for the Treenode.
+ /// Shows the context menu for the .
///
private void ShowContextMenu(TreeNode treeNode)
{
@@ -3452,7 +3443,7 @@ protected override unsafe void WndProc(ref Message m)
if (m.LParamInternal == PInvoke.UiaRootObjectId && SupportsUiaProviders && !IsAccessibilityObjectCreated && Focused)
{
base.WndProc(ref m);
- SelectedNode?.AccessibilityObject.RaiseAutomationEvent(UIA_EVENT_ID.UIA_AutomationFocusChangedEventId);
+ SelectedNode?.AccessibilityObject?.RaiseAutomationEvent(UIA_EVENT_ID.UIA_AutomationFocusChangedEventId);
}
else
{
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TreeView/TreeViewLabelEditAccessibleObject.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TreeView/TreeViewLabelEditAccessibleObject.cs
index 3737b707efd..ce0ea931335 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TreeView/TreeViewLabelEditAccessibleObject.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/Controls/TreeView/TreeViewLabelEditAccessibleObject.cs
@@ -20,7 +20,7 @@ public TreeViewLabelEditAccessibleObject(TreeView owningTreeView, TreeViewLabelE
private protected override string? AutomationId =>
_owningTreeView.TryGetTarget(out TreeView? target)
- ? target._editNode?.AccessibilityObject.Name
+ ? target._editNode?.AccessibilityObject?.Name
: null;
internal override IRawElementProviderFragmentRoot.Interface? FragmentRoot =>
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs
index 7f56640d19b..54b069fe66b 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/Form.cs
@@ -2317,23 +2317,16 @@ protected override void SetVisibleCore(bool value)
if (ParentInternal is not null && ParentInternal.Visible)
{
- SuspendLayout();
- try
- {
- PInvoke.ShowWindow(this, SHOW_WINDOW_CMD.SW_SHOW);
- CreateControl();
-
- // If this form is mdichild and maximized, we need to redraw the MdiParent non-client area to
- // update the menu bar because we always create the window as if it were not maximized.
- // See comment on CreateHandle about this.
- if (WindowState == FormWindowState.Maximized)
- {
- MdiParentInternal.UpdateWindowIcon(true);
- }
- }
- finally
+ using SuspendLayoutScope scope = new(this);
+ PInvoke.ShowWindow(this, SHOW_WINDOW_CMD.SW_SHOW);
+ CreateControl();
+
+ // If this form is mdichild and maximized, we need to redraw the MdiParent non-client area to
+ // update the menu bar because we always create the window as if it were not maximized.
+ // See comment on CreateHandle about this.
+ if (WindowState == FormWindowState.Maximized)
{
- ResumeLayout();
+ MdiParentInternal.UpdateWindowIcon(true);
}
}
}
@@ -2341,8 +2334,6 @@ protected override void SetVisibleCore(bool value)
OnVisibleChanged(EventArgs.Empty);
}
- // (
-
if (value && !IsMdiChild && (WindowState == FormWindowState.Maximized || TopMost))
{
if (ActiveControl is null)
@@ -4929,26 +4920,21 @@ protected override void Select(bool directed, bool forward)
protected override void ScaleCore(float x, float y)
{
Debug.WriteLineIf(CompModSwitches.RichLayout.TraceInfo, $"{GetType().Name}::ScaleCore({x}, {y})");
- SuspendLayout();
- try
- {
- // Get size values in advance to prevent one change from affecting another.
- Size clientSize = ClientSize;
- ScaleMinMaxSize(x, y);
- ScaleDockPadding(x, y);
- if (WindowState == FormWindowState.Normal)
- {
- ClientSize = ScaleSize(clientSize, x, y);
- }
- foreach (Control control in Controls)
- {
- control?.Scale(x, y);
- }
+ using SuspendLayoutScope scope = new(this);
+
+ // Get size values in advance to prevent one change from affecting another.
+ Size clientSize = ClientSize;
+ ScaleMinMaxSize(x, y);
+ ScaleDockPadding(x, y);
+ if (WindowState == FormWindowState.Normal)
+ {
+ ClientSize = ScaleSize(clientSize, x, y);
}
- finally
+
+ foreach (Control control in Controls)
{
- ResumeLayout();
+ control?.Scale(x, y);
}
}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Layout/Containers/SplitContainer.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Layout/Containers/SplitContainer.cs
index 0be88c30f0a..f528783c53e 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/Layout/Containers/SplitContainer.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/Layout/Containers/SplitContainer.cs
@@ -1596,12 +1596,14 @@ private void ResizeSplitContainer()
Panel2.SuspendLayout();
if (Width == 0)
- { // Set the correct Width iif the WIDTH has changed to ZERO.
+ {
+ // Set the correct Width iif the WIDTH has changed to ZERO.
Panel1.Size = new Size(0, Panel1.Height);
Panel2.Size = new Size(0, Panel2.Height);
}
else if (Height == 0)
- { // Set the correct Height iif the HEIGHT has changed to ZERO.
+ {
+ // Set the correct Height iif the HEIGHT has changed to ZERO.
Panel1.Size = new Size(Panel1.Width, 0);
Panel2.Size = new Size(Panel2.Width, 0);
}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/Layout/LayoutTransaction.cs b/src/System.Windows.Forms/src/System/Windows/Forms/Layout/LayoutTransaction.cs
index e140fe8fae8..908a4ff7409 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/Layout/LayoutTransaction.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/Layout/LayoutTransaction.cs
@@ -116,7 +116,7 @@ public static void DoLayoutIf(bool condition, IArrangedElement? elementToLayout,
}
else
{
- LayoutTransaction.DoLayout(elementToLayout, elementCausingLayout, property);
+ DoLayout(elementToLayout, elementCausingLayout, property);
}
}
}
diff --git a/src/System.Windows.Forms/src/System/Windows/Forms/MDI/MDIClient.cs b/src/System.Windows.Forms/src/System/Windows/Forms/MDI/MDIClient.cs
index 0cde5fbb190..30523e80b35 100644
--- a/src/System.Windows.Forms/src/System/Windows/Forms/MDI/MDIClient.cs
+++ b/src/System.Windows.Forms/src/System/Windows/Forms/MDI/MDIClient.cs
@@ -7,20 +7,21 @@
namespace System.Windows.Forms;
///
-/// Represents the container for multiple-document interface (MDI) child forms.
-/// This class cannot be inherited.
+/// Represents the container for multiple-document interface (MDI) child forms.
+/// This class cannot be inherited.
///
///
-/// Don't create an control.
-/// A form creates and uses the when you set the property to .
+///
+/// Don't create an control. A form creates and uses the when you set
+/// the property to .
+///
///
[ToolboxItem(false)]
[DesignTimeVisible(false)]
public sealed partial class MdiClient : Control
{
- // kept in add order, not ZOrder. Need to return the correct
- // array of items...
- private readonly List