Comments (7)
In the example below, [A] and [B] do the job for the first run and when the control is resized.
Don't hardcode DPI. Instead Configure your app for high DPI support (read this). Then, as in the example below, [C] de-scales the rectangle given by Windows before drawing.
Markhus
public class TryD2DControl : D2DControl
{
public TryD2DControl() : base()
{
// [A] ask to redraw this control when resized
this.ResizeRedraw = true;
}
/// <summary>
/// [B] resize the device when the control is resized
/// </summary>
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
this.Device.Resize();
}
/// <summary>
/// Return the given control's DPI factor.
/// For example, for a 120 DPI, if multiply (1.25, 1.25), else (0.8, 0.8)
/// </summary>
public D2DSize GetDPIScale(Control ctrl, bool multiply)
{
D2DSize dpiScale = new D2DSize(1f, 1f);
Graphics g = ctrl.CreateGraphics();
try
{
//int dpi = ctrl.DeviceDpi; /// .net >= 4.8 required
dpiScale.width = g.DpiX / 96f;
dpiScale.height = g.DpiY / 96f;
if (!multiply)
{
dpiScale.width = 1f / dpiScale.width;
dpiScale.height = 1f / dpiScale.height;
}
}
finally
{
g.Dispose();
}
return dpiScale;
}
protected override void OnRender(D2DGraphics g)
{
// all coordinates and sizes reported by Windows are DPI scaled
D2DRect rect = this.ClientRectangle;
// [C] de-scale client rectangle
D2DSize dpiScale = GetDPIScale(this, false);
rect.Width *= dpiScale.width;
rect.Height *= dpiScale.height;
g.FillRectangle(rect, D2DColor.Blue);
g.DrawRectangle(rect, D2DColor.Chocolate);
g.DrawLine(new D2DPoint(rect.left, rect.top), new D2DPoint(rect.right, rect.bottom), D2DColor.Chocolate);
g.DrawLine(new D2DPoint(rect.right, rect.top), new D2DPoint(rect.left, rect.bottom), D2DColor.Chocolate);
Rectangle r = (Rectangle) rect;
g.DrawText(r.ToString(), D2DColor.WhiteSmoke, 10, 10);
}
}
from d2dlib.
It maybe a DPI problem, you may change the DPI before the rendering.
g.SetDPI(96, 96);
Try change the value to 72 or 120 and check the result.
Usually if you are using a high resolution display and your .NET program not be set to support high resolution or the settings are not matched, you might get the a problem like this. See document like this.
from d2dlib.
Okay, that does have an effect - it is strange though, when I first run my application (first screenshot) you can see a comparison with the same string in the same font, size and style drawn in a PictureBox control. Then if I resize the window, the d2d control redraws and the text looks a lot better - very strange. It seems that if I use g.SetDPI( 128,128) the two strings seem to closely match in size. FYI, I am running on a 2K monitor with Windows scaling set to 100%.
Screenshot 1
Screenshot 2
Andy
from d2dlib.
Sorry to be a pain but still struggling with this :-(
This is my simple custom control code:
public class CustomD2D : D2DControl
{
public CustomD2D()
{
_componentBounds = new Rectangle();
this.ShowFPS = true;
}
protected override void OnResize( EventArgs e )
{
_componentBounds.Width = this.ClientRectangle.Width - 1;
_componentBounds.Height = this.ClientRectangle.Height - 1;
Invalidate();
}
protected override void OnSizeChanged( EventArgs e )
{
_componentBounds.Width = this.ClientRectangle.Width - 1;
_componentBounds.Height = this.ClientRectangle.Height - 1;
Invalidate();
}
protected override void OnRender( D2DGraphics g )
{
g.Antialias = true;
//g.SetDPI( 123, 164 );
g.FillRectangle( _componentBounds, D2DColor.Cyan );
g.DrawRectangle( _componentBounds, D2DColor.Blue );
g.DrawLine( _componentBounds.Left, _componentBounds.Top, _componentBounds.Right, _componentBounds.Bottom, D2DColor.Green );
g.DrawLine( _componentBounds.Right, _componentBounds.Top, _componentBounds.Left, _componentBounds.Bottom, D2DColor.Green );
var elapsed = DateTime.Now.Subtract( _lastRender );
using ( var font = new Font( "Arial", 22 ) )
{
string s = $"{_componentBounds.ToString()}\r\n{elapsed.TotalMilliseconds.ToString()}";
g.DrawText( s, D2DColor.Black, font, _componentBounds.Left + 20, _componentBounds.Top + 20 );
}
_lastRender = DateTime.Now;
}
/// <summary>
/// Holds the bounding rectangle of the chart control.
/// </summary>
protected Rectangle _componentBounds;
private DateTime _lastRender = DateTime.Now;
}
If I set the background of this control to Orange and dock it as Fill in a WinForms application and run it I get:
You can see that _componentBounds holds the correct size but the graphics are not rendering accordingly.
If I drag the main WinForms window the control resizes perfectly.
I found that by playing around with SetDPI that I could get the rectangle to fill the control area perfectly.
g.SetDPI( 123, 164 );
As you can see:
But as soon as I resize the main window, it all goes wrong :-(
It is also odd that when the application first runs, nothing is anti-aliased (see the text and lines) but as soon as I resize the window the text and lines become anti-aliased. I should also point out that I call Invalidate on the custom control from a timer in the main application once per millisecond so it is not subsequent calls to OnRender that is changing the functionality, it is something to do with resizing the client area ?
I would appreciate any guidance or comments.
Andy
from d2dlib.
Thanks @MarkhusGenferei!
I have tested this, as @FraserElectronics said, seems the D2DControl can't calculate the DPI correctly during initialization.
As a workaround, by calling the Reisze
method will resolve this.
public partial class MyControl : D2DControl
{
public MyControl()
{
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
this.Device.Resize(); // call Resize during OnResize
}
protected override void OnRender(D2DGraphics g)
{
// get correct size
g.DrawRectangle(this.ClientRectangle, D2DColor.DarkOrange);
base.OnRender(g);
}
}
Try to fix this in next versions.
from d2dlib.
Thanks guys - much appreciated 👍
Andy
from d2dlib.
Have tested and it seems to work perfectly 😁
I will close the issue.
from d2dlib.
Related Issues (20)
- Potential Perf Gain: Use `LibraryImport` instead of `DllImport` when using .NET 7
- Drawing lines and rectangles HOT 8
- Printing output HOT 2
- Direct pixel access to D2DBitmap
- Does it support screen capture?
- Why carry an unmanaged library instead of just wrapping Direct2D in pure C#? HOT 2
- Cannot compile in pure .NET FW HOT 1
- Effects HOT 1
- D2DControl usage HOT 1
- CreateTextLayout causes Memory Leak HOT 1
- Feature request: DrawPie and FillPie HOT 3
- Bug: FillPath and DrawPath do not work on Memory Bitmap HOT 2
- Render YUV image HOT 2
- Any reason not to publish signed assemblies to NuGet? HOT 1
- Text Outline (Stroke) HOT 2
- Bold text? HOT 2
- Missing clip rect in OnRender
- Example how to draw a Memory Bitmap with transparent part on another Memory Bitmap HOT 1
- DrawPath and FillPath throw exception HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from d2dlib.