I'm trying to figure out how exactly gdi+ graphics containers works with different graphic units. Take a look at the below code. It compiles, you can paste it into a fresh new form.
void Form2_Paint(object sender, PaintEventArgs e)
{
var gfx = e.Graphics;
System.Diagnostics.Debug.WriteLine("DpiX={0}, DpiY={1}", gfx.DpiX, gfx.DpiY);
gfx.PageUnit = GraphicsUnit.Inch;
var pen = new Pen(Color.Black, 0.01f);
// Create outer container, 2 inches in size with X and Y set to 0.1 inches
var outerContainer = gfx.BeginContainer(
new RectangleF(0.1f, 0.1f, 2, 2),
new RectangleF(0, 0, 2, 2),
GraphicsUnit.Pixel);
// Draw the outer rectangle
gfx.DrawRectangle(pen, new Rectangle(0, 0, 2, 2));
// Create inner container, 1 inch in size with X and Y set to 0.1 inches
var innerContainer = gfx.BeginContainer(
new RectangleF(0.1f, 0.1f, 1, 1),
new RectangleF(0, 0, 1, 1),
GraphicsUnit.Pixel);
// Draw the inner rectangle
gfx.DrawRectangle(pen, new Rectangle(0, 0, 1, 1));
gfx.EndContainer(innerContainer);
gfx.EndContainer(outerContainer);
}
Above code is a pretty simple example of nested graphic containers, I used no scaling transformation. This is how the form looks like when above paint handler is used:
It's pretty simple. Now, I will try to describe what the problem is.
This is a signature of the BeginContainer
method:
public GraphicsContainer BeginContainer(
RectangleF dstrect,
RectangleF srcrect,
GraphicsUnit unit
)
What I'm failing to understand is GraphicsUnit unit
argument.
From MSDN:
Member of the GraphicsUnit enumeration that specifies the unit of measure for the container.
This appears not to be true!
As you can see in my code I'm using Inch units as such: gfx.PageUnit = GraphicsUnit.Inch
.
But, when I'm creating containers this is what I'm passing as units argument to the BeginContainer
method: GraphicsUnit.Pixel
. What happens after the container is created? Inches are being used (what I actually want). But if I pass GraphicsUnit.Inch
(or millimeters or anything else) to the argument, pixels are used. So, it seems that in order to accomplish what I want (use inches) I have to specify pixels?
This makes no sense to me. You can try changing units in BeginContainer
methods in above code and observe strange results. I've read the MSDN and everything I could gather on this but I am still clueless.
I'm writing software which draws a lot of stuff using gdi+ and it's using millimeter units for printing purposes - when I started using containers I was quite surprised that I apparently need to specify pixels as units. I'm really suspicious of any printing code where pixels are mentioned. It must be that I have a big misunderstanding of this matter.
So, all above considered, my question is: what is the purpose of the unit
argument in this method?
Perhaps, you don't need to care about at all.
I failed to pass the right arguments to Graphics.BeginContainer
as well.
However, using the Transform
methods (ResetTransform
in the end) worked perfectly for the problem I had to solve.
So, first consider the Transform
methods before trying to understand containers.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With