-
-
Notifications
You must be signed in to change notification settings - Fork 43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Several Issues #106
Comments
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. |
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 1Screenshot 2Andy |
Sorry to be a pain but still struggling with this :-(
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. I found that by playing around with SetDPI that I could get the rectangle to fill the control area perfectly.
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 |
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);
}
} |
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 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. |
Thanks guys - much appreciated 👍 Andy |
Have tested and it seems to work perfectly 😁 |
Really, really keen to use d2dlib but am very quickly coming across a number of issues:
I have created a custom control that derives from D2DControl in OnRender I do:
When I run it, the rectangle (both filled and the border) do not fill the control bounds. If I drag the window even one pixel it then fills the control area. If I print out this.Bounds, the position and size match the control area but d2dlib does not seem to use those dimensions. I intercept OnResize to keep _componentBounds up to date. In the screenshot below you can see the Cyan rectangle which is 436 pixels high but if I print _componentBounds in OnRender it shows {X=0,Y=0,Width=1069,Height=589}.
I also am having problems with drawing text, specifically:
I use MeasureText to get the size of a string so that I can centre it using the following code:
Note, I am not exactly sure what the last parameter should be - I have set it to the total size of the custom control - perhaps this could be the issue?
The text appears split across two lines (I draw the rectangle using the parameters for MeasureText and it looks like the text should fit.
Also, the quality of the text is poor at smaller font sizes - it is not smooth at all.
Please see the attached screenshot that shows these issues:
Sorry for the rambling :-(
Andy
The text was updated successfully, but these errors were encountered: