Skip to content

Commit

Permalink
Use new GetContext overloads
Browse files Browse the repository at this point in the history
Use new Graphics.GetContext overloads that minimize allocations and remove warning suppression.
  • Loading branch information
JeremyKuhne committed Apr 19, 2021
1 parent 374b00e commit 03bd984
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -146,59 +146,62 @@ public unsafe DeviceContextHdcScope(
bool applyTransform = applyGraphicsState.HasFlag(ApplyGraphicsProperties.TranslateTransform);
bool applyClipping = applyGraphicsState.HasFlag(ApplyGraphicsProperties.Clipping);

#pragma warning disable SYSLIB0016 // Type or member is obsolete
// This API is very expensive and cannot be called after GetHdc()
object[]? data = applyTransform || applyClipping ? (object[])graphics.GetContextInfo() : null;
#pragma warning restore SYSLIB0016 // Type or member is obsolete
Region? clipRegion = null;
PointF offset = default;
if (applyClipping)
{
graphics.GetContextInfo(out offset, out clipRegion);
}
else if (applyTransform)
{
graphics.GetContextInfo(out offset);
}

using Region? clipRegion = (Region?)data?[0];
using Matrix? worldTransform = (Matrix?)data?[1];
using (clipRegion)
{
applyTransform = applyTransform && !offset.IsEmpty;
applyClipping = clipRegion is not null;

// elements (XFORM) = [eM11, eM12, eM21, eM22, eDx, eDy], eDx/eDy specify the translation offset.
float[]? elements = applyTransform ? worldTransform?.Elements : null;
int dx = elements is not null ? (int)elements[4] : 0;
int dy = elements is not null ? (int)elements[5] : 0;
applyTransform = applyTransform && elements is not null && (dx != 0 || dy != 0);
using var graphicsRegion = applyClipping ? new Gdi32.RegionScope(clipRegion!, graphics) : default;
applyClipping = applyClipping && !graphicsRegion!.Region.IsNull;

using var graphicsRegion = applyClipping ? new Gdi32.RegionScope(clipRegion!, graphics) : default;
applyClipping = applyClipping && !graphicsRegion!.Region.IsNull;
HDC = (Gdi32.HDC)graphics.GetHdc();

HDC = (Gdi32.HDC)graphics.GetHdc();
if (saveHdcState || applyClipping || applyTransform)
{
_savedHdcState = Gdi32.SaveDC(HDC);
}

if (saveHdcState || applyClipping || applyTransform)
{
_savedHdcState = Gdi32.SaveDC(HDC);
}
if (applyClipping)
{
// If the Graphics object was created from a native DC the actual clipping region is the intersection
// beteween the original DC clip region and the GDI+ one - for display Graphics it is the same as
// Graphics.VisibleClipBounds.

if (applyClipping)
{
// If the Graphics object was created from a native DC the actual clipping region is the intersection
// beteween the original DC clip region and the GDI+ one - for display Graphics it is the same as
// Graphics.VisibleClipBounds.
RegionType type;

RegionType type;
using var dcRegion = new Gdi32.RegionScope(HDC);
if (!dcRegion.IsNull)
{
type = Gdi32.CombineRgn(graphicsRegion!, dcRegion, graphicsRegion!, Gdi32.RGN.AND);
if (type == RegionType.ERROR)
{
throw new Win32Exception();
}
}

using var dcRegion = new Gdi32.RegionScope(HDC);
if (!dcRegion.IsNull)
{
type = Gdi32.CombineRgn(graphicsRegion!, dcRegion, graphicsRegion!, Gdi32.RGN.AND);
type = Gdi32.SelectClipRgn(HDC, graphicsRegion!);
if (type == RegionType.ERROR)
{
throw new Win32Exception();
}
}

type = Gdi32.SelectClipRgn(HDC, graphicsRegion!);
if (type == RegionType.ERROR)
if (applyTransform)
{
throw new Win32Exception();
Gdi32.OffsetViewportOrgEx(HDC, (int)offset.X, (int)offset.Y, null);
}
}

if (applyTransform)
{
Gdi32.OffsetViewportOrgEx(HDC, dx, dy, null);
}
}

public static implicit operator Gdi32.HDC(in DeviceContextHdcScope scope) => scope.HDC;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,18 +156,15 @@ internal static void CheckGraphicsForState(Graphics? graphics, DrawingEventFlags
return;
}

#pragma warning disable SYSLIB0016 // Type or member is obsolete
// Check to see if we've actually corrupted the state
object[] data = (object[])graphics.GetContextInfo();
#pragma warning restore SYSLIB0016 // Type or member is obsolete
graphics.GetContextInfo(out PointF offset, out Region? clip);

using Region clipRegion = (Region)data[0];
using Matrix worldTransform = (Matrix)data[1];

float[] elements = worldTransform?.Elements!;
bool isInfinite = clipRegion.IsInfinite(graphics);
Debug.Assert((int)elements[4] == 0 && (int)elements[5] == 0, "transform has been modified");
Debug.Assert(isInfinite, "clipping as been applied");
using (clip)
{
bool isInfinite = clip?.IsInfinite(graphics) ?? true;
Debug.Assert(offset.IsEmpty, "transform has been modified");
Debug.Assert(isInfinite, "clipping as been applied");
}
}
}
}

0 comments on commit 03bd984

Please sign in to comment.