Dmitry Timoshkov : gdiplus: GdipMeasureString operates internally in pixels but in/ out rectangles are in device units.

Vincent Povirk madewokherd at
Mon Jul 23 09:25:36 CDT 2012

>> OK, this is starting to make sense to me. If I'm understanding this,
>> the point of your series is that the font has a consistent size based
>> on the unit stored in the font. If it's a physical unit like inches
>> then the font's size in world coordinates changes based on the
>> graphics page unit, so that it maintains the same physical size. Since
>> GdipMeasureString reports world coordinates you see the measurement
>> change while the pixel size should stay the same based on the device
>> dpi.
> Points, inches, meters and the like are logical units, pixel is the physical
> unit measure.

Oh. Then what I mean to say is that if you specify the size in logical
units, the size in pixels depends on the dpi of the graphics object.
The size in world coordinates depends on the size in pixels, the page
unit, page scale, and the world transform.

At least this is the way your tests lead me to believe native behaves.
Builtin does not behave that way, so I think you have partially fixed
some cases and broken others.

> convert_unit() is a very poorly named helper, and its meening and behaviour
> has changed in time it seems. convert_unit() needs to be removed completely,
> and conversion between pixels and device/font units should be generalized.

Well, we should mostly be using GdipTransformPoints instead (so that
we can account for world transform, page scale, and page unit in a
general way) and avoiding convert_unit directly. I see we're
essentially duplicating that logic in prepare_dc and

In cases where we need to convert a logical measurement to a device
measurement (maybe including in GdipTransformPoints) I think
units_to_pixels/pixels_to_units is appropriate, but it should really
take a Graphics object rather than a dpi (since the correct dpi cannot
be known without a Graphics object). And we need testing to decide
whether to account for the page scale in that calculation.

> For instance setting device unit to millimeters with GdipSetPageUnit() and
> then calling GdipDrawImageI() leads to completely wrong results because
> down in the path there is huge confusion between device units, source
> coordinates units and device/world transforms applied to both of them
> using only device X resolution and completely ignoring image resolution.
> What a mess.

Yes, I'm aware that the DrawImage functions that don't take a
destination size should be using the image resolution. I've been
putting that off. But I think this only matters for images, fonts, and
perhaps texture brushes. All other cases should use world coordinates.

More information about the wine-devel mailing list