Code Monkey home page Code Monkey logo

Comments (7)

MarkhusGenferei avatar MarkhusGenferei commented on August 18, 2024 1

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.

jingwood avatar jingwood commented on August 18, 2024

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.

FraserElectronics avatar FraserElectronics commented on August 18, 2024

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

d2dlib_1

Screenshot 2

d2dlib_2

Andy

from d2dlib.

FraserElectronics avatar FraserElectronics commented on August 18, 2024

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:

1

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.

2

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:

3

But as soon as I resize the main window, it all goes wrong :-(

4

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.

jingwood avatar jingwood commented on August 18, 2024

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.

FraserElectronics avatar FraserElectronics commented on August 18, 2024

Thanks guys - much appreciated 👍

Andy

from d2dlib.

FraserElectronics avatar FraserElectronics commented on August 18, 2024

Have tested and it seems to work perfectly 😁
I will close the issue.

from d2dlib.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.