Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

Commit ec22edc

Browse files
hughbesafern
authored andcommitted
Share as much Bitmap code with Windows as possible (#25922)
1 parent bd4e892 commit ec22edc

File tree

14 files changed

+627
-954
lines changed

14 files changed

+627
-954
lines changed

src/System.Drawing.Common/src/System.Drawing.Common.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,15 @@
2828
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'netstandard-Release|AnyCPU'" />
2929
<ItemGroup Condition="$(TargetGroup.StartsWith('netcoreapp'))">
3030
<!-- Shared source code, all configurations -->
31+
<Compile Include="System\Drawing\Bitmap.cs" />
3132
<Compile Include="System\Drawing\BitmapSuffixInSameAssemblyAttribute.cs" />
3233
<Compile Include="System\Drawing\BitmapSuffixInSatelliteAssemblyAttribute.cs" />
3334
<Compile Include="System\Drawing\Brushes.cs" />
3435
<Compile Include="System\Drawing\CharacterRange.cs" />
3536
<Compile Include="System\Drawing\ColorTranslator.cs" />
3637
<Compile Include="System\Drawing\ContentAlignment.cs" />
3738
<Compile Include="System\Drawing\IDeviceContext.cs" />
39+
<Compile Include="System\Drawing\Image.cs" />
3840
<Compile Include="System\Drawing\GdiplusNative.cs" />
3941
<Compile Include="System\Drawing\Graphics.cs" />
4042
<Compile Include="System\Drawing\GraphicsUnit.cs" />

src/System.Drawing.Common/src/System/Drawing/Bitmap.Unix.cs

Lines changed: 6 additions & 226 deletions
Original file line numberDiff line numberDiff line change
@@ -50,82 +50,22 @@ namespace System.Drawing
5050
#if !NETCORE
5151
[Editor ("System.Drawing.Design.BitmapEditor, " + Consts.AssemblySystem_Drawing_Design, typeof (System.Drawing.Design.UITypeEditor))]
5252
#endif
53-
public sealed class Bitmap : Image
53+
public sealed partial class Bitmap
5454
{
5555
#region constructors
56-
// constructors
57-
58-
// required for XmlSerializer (#323246)
59-
private Bitmap()
60-
{
61-
}
62-
63-
internal Bitmap(IntPtr ptr)
64-
{
65-
nativeObject = ptr;
66-
}
6756

6857
// Usually called when cloning images that need to have
6958
// not only the handle saved, but also the underlying stream
7059
// (when using MS GDI+ and IStream we must ensure the stream stays alive for all the life of the Image)
7160
internal Bitmap(IntPtr ptr, Stream stream)
7261
{
73-
nativeObject = ptr;
62+
nativeImage = ptr;
7463
}
7564

76-
public Bitmap(int width, int height) : this(width, height, PixelFormat.Format32bppArgb)
77-
{
78-
}
79-
80-
public Bitmap(int width, int height, Graphics g)
81-
{
82-
if (g == null)
83-
throw new ArgumentNullException("g");
84-
85-
IntPtr bmp;
86-
int s = SafeNativeMethods.Gdip.GdipCreateBitmapFromGraphics(width, height, g.nativeObject, out bmp);
87-
SafeNativeMethods.Gdip.CheckStatus(s);
88-
nativeObject = bmp;
89-
}
90-
91-
public Bitmap(int width, int height, PixelFormat format)
92-
{
93-
IntPtr bmp;
94-
int s = SafeNativeMethods.Gdip.GdipCreateBitmapFromScan0(width, height, 0, format, IntPtr.Zero, out bmp);
95-
SafeNativeMethods.Gdip.CheckStatus(s);
96-
nativeObject = bmp;
97-
98-
}
99-
100-
public Bitmap(Image original) : this(original, original.Width, original.Height) { }
101-
102-
public Bitmap(Stream stream) : this(stream, false) { }
103-
104-
public Bitmap(string filename) : this(filename, false) { }
105-
106-
public Bitmap(Image original, Size newSize) : this(original, newSize.Width, newSize.Height) { }
107-
10865
public Bitmap(Stream stream, bool useIcm)
10966
{
11067
// false: stream is owned by user code
111-
nativeObject = InitFromStream(stream);
112-
}
113-
114-
public Bitmap(string filename, bool useIcm)
115-
{
116-
if (filename == null)
117-
throw new ArgumentNullException("filename");
118-
119-
IntPtr imagePtr;
120-
int st;
121-
122-
if (useIcm)
123-
st = SafeNativeMethods.Gdip.GdipCreateBitmapFromFileICM(filename, out imagePtr);
124-
else
125-
st = SafeNativeMethods.Gdip.GdipCreateBitmapFromFile(filename, out imagePtr);
126-
127-
SafeNativeMethods.Gdip.CheckStatus(st);
128-
nativeObject = imagePtr;
68+
nativeImage = InitFromStream(stream);
12969
}
13070

13171
public Bitmap(Type type, string resource)
@@ -144,178 +84,18 @@ public Bitmap(Type type, string resource)
14484
throw new FileNotFoundException(msg);
14585
}
14686

147-
nativeObject = InitFromStream(s);
148-
}
149-
150-
public Bitmap(Image original, int width, int height) : this(width, height, PixelFormat.Format32bppArgb)
151-
{
152-
Graphics graphics = Graphics.FromImage(this);
153-
154-
graphics.DrawImage(original, 0, 0, width, height);
155-
graphics.Dispose();
156-
}
157-
158-
public Bitmap(int width, int height, int stride, PixelFormat format, IntPtr scan0)
159-
{
160-
IntPtr bmp;
161-
162-
int status = SafeNativeMethods.Gdip.GdipCreateBitmapFromScan0(width, height, stride, format, scan0, out bmp);
163-
SafeNativeMethods.Gdip.CheckStatus(status);
164-
nativeObject = bmp;
87+
nativeImage = InitFromStream(s);
16588
}
16689

16790
private Bitmap(SerializationInfo info, StreamingContext context)
16891
: base(info, context)
16992
{
17093
}
17194
#endregion
172-
// methods
173-
public Color GetPixel(int x, int y)
174-
{
175-
176-
int argb;
177-
178-
int s = SafeNativeMethods.Gdip.GdipBitmapGetPixel(nativeObject, x, y, out argb);
179-
SafeNativeMethods.Gdip.CheckStatus(s);
180-
181-
return Color.FromArgb(argb);
182-
}
183-
184-
public void SetPixel(int x, int y, Color color)
185-
{
186-
int s = SafeNativeMethods.Gdip.GdipBitmapSetPixel(nativeObject, x, y, color.ToArgb());
187-
if (s == SafeNativeMethods.Gdip.InvalidParameter)
188-
{
189-
// check is done in case of an error only to avoid another
190-
// unmanaged call for normal (successful) calls
191-
if ((this.PixelFormat & PixelFormat.Indexed) != 0)
192-
{
193-
string msg = "SetPixel cannot be called on indexed bitmaps.";
194-
throw new InvalidOperationException(msg);
195-
}
196-
}
197-
SafeNativeMethods.Gdip.CheckStatus(s);
198-
}
199-
200-
public Bitmap Clone(Rectangle rect, PixelFormat format)
201-
{
202-
IntPtr bmp;
203-
int status = SafeNativeMethods.Gdip.GdipCloneBitmapAreaI(rect.X, rect.Y, rect.Width, rect.Height,
204-
format, nativeObject, out bmp);
205-
SafeNativeMethods.Gdip.CheckStatus(status);
206-
return new Bitmap(bmp);
207-
}
208-
209-
public Bitmap Clone(RectangleF rect, PixelFormat format)
210-
{
211-
IntPtr bmp;
212-
int status = SafeNativeMethods.Gdip.GdipCloneBitmapArea(rect.X, rect.Y, rect.Width, rect.Height,
213-
format, nativeObject, out bmp);
214-
SafeNativeMethods.Gdip.CheckStatus(status);
215-
return new Bitmap(bmp);
216-
}
217-
218-
public static Bitmap FromHicon(IntPtr hicon)
219-
{
220-
IntPtr bitmap;
221-
int status = SafeNativeMethods.Gdip.GdipCreateBitmapFromHICON(hicon, out bitmap);
222-
SafeNativeMethods.Gdip.CheckStatus(status);
223-
return new Bitmap(bitmap);
224-
}
225-
226-
public static Bitmap FromResource(IntPtr hinstance, string bitmapName) //TODO: Untested
227-
{
228-
IntPtr bitmap;
229-
int status = SafeNativeMethods.Gdip.GdipCreateBitmapFromResource(hinstance, bitmapName, out bitmap);
230-
SafeNativeMethods.Gdip.CheckStatus(status);
231-
return new Bitmap(bitmap);
232-
}
233-
234-
[EditorBrowsable(EditorBrowsableState.Advanced)]
235-
public IntPtr GetHbitmap()
236-
{
237-
return GetHbitmap(Color.Gray);
238-
}
239-
240-
[EditorBrowsable(EditorBrowsableState.Advanced)]
241-
public IntPtr GetHbitmap(Color background)
242-
{
243-
IntPtr HandleBmp;
244-
245-
int status = SafeNativeMethods.Gdip.GdipCreateHBITMAPFromBitmap(nativeObject, out HandleBmp, background.ToArgb());
246-
SafeNativeMethods.Gdip.CheckStatus(status);
247-
248-
return HandleBmp;
249-
}
250-
251-
[EditorBrowsable(EditorBrowsableState.Advanced)]
252-
public IntPtr GetHicon()
253-
{
254-
IntPtr HandleIcon;
255-
256-
int status = SafeNativeMethods.Gdip.GdipCreateHICONFromBitmap(nativeObject, out HandleIcon);
257-
SafeNativeMethods.Gdip.CheckStatus(status);
258-
259-
return HandleIcon;
260-
}
261-
262-
public BitmapData LockBits(Rectangle rect, ImageLockMode flags, PixelFormat format)
263-
{
264-
BitmapData result = new BitmapData();
265-
return LockBits(rect, flags, format, result);
266-
}
267-
268-
public
269-
BitmapData LockBits(Rectangle rect, ImageLockMode flags, PixelFormat format, BitmapData bitmapData)
270-
{
271-
int status = SafeNativeMethods.Gdip.GdipBitmapLockBits(nativeObject, ref rect, flags, format, bitmapData);
272-
if (status == 7)
273-
{
274-
status = 8; // libgdiplus has the wrong error code mapping for this state.
275-
}
276-
//NOTE: scan0 points to piece of memory allocated in the unmanaged space
277-
SafeNativeMethods.Gdip.CheckStatus(status);
278-
279-
return bitmapData;
280-
}
281-
282-
public void MakeTransparent()
283-
{
284-
Color clr = GetPixel(0, 0);
285-
MakeTransparent(clr);
286-
}
287-
288-
public void MakeTransparent(Color transparentColor)
289-
{
290-
// We have to draw always over a 32-bitmap surface that supports alpha channel
291-
Bitmap bmp = new Bitmap(Width, Height, PixelFormat.Format32bppArgb);
292-
Graphics gr = Graphics.FromImage(bmp);
293-
Rectangle destRect = new Rectangle(0, 0, Width, Height);
294-
ImageAttributes imageAttr = new ImageAttributes();
295-
296-
imageAttr.SetColorKey(transparentColor, transparentColor);
297-
298-
gr.DrawImage(this, destRect, 0, 0, Width, Height, GraphicsUnit.Pixel, imageAttr);
299-
300-
IntPtr oldBmp = nativeObject;
301-
nativeObject = bmp.nativeObject;
302-
bmp.nativeObject = oldBmp;
303-
304-
gr.Dispose();
305-
bmp.Dispose();
306-
imageAttr.Dispose();
307-
}
308-
309-
public void SetResolution(float xDpi, float yDpi)
310-
{
311-
int status = SafeNativeMethods.Gdip.GdipBitmapSetResolution(nativeObject, xDpi, yDpi);
312-
SafeNativeMethods.Gdip.CheckStatus(status);
313-
}
31495

315-
public void UnlockBits(BitmapData bitmapdata)
96+
private void ValidateBitmap(IntPtr bitmap)
31697
{
317-
int status = SafeNativeMethods.Gdip.GdipBitmapUnlockBits(nativeObject, bitmapdata);
318-
SafeNativeMethods.Gdip.CheckStatus(status);
98+
// No validation is performed on Unix.
31999
}
320100
}
321101
}

0 commit comments

Comments
 (0)