[PATCH v4 0/1] MR10736: gdiplus: Don't add X margin to Center/Far for GdipMeasureCharacterRanges
We should shift X position only for StringAlignmentNear. -- v4: gdiplus: Don't add X margin on Center/Far for GdipMeasureCharacterRanges and GdipDrawString https://gitlab.winehq.org/wine/wine/-/merge_requests/10736
From: Bartosz Kosiorek <gang65@poczta.onet.pl> We should shift X position only for StringAlignmentNear. For Center and Far alignment, is is already correctly set by gdip_format_string. --- dlls/gdiplus/graphics.c | 31 +++++++++++------ dlls/gdiplus/tests/graphics.c | 63 +++++++++++++++++------------------ 2 files changed, 51 insertions(+), 43 deletions(-) diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 0faac1325d2..e4d00e329f7 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -6030,16 +6030,22 @@ GpStatus WINGDIPAPI GdipMeasureCharacterRanges(GpGraphics* graphics, margin_x = stringFormat->generic_typographic ? 0.0 : font->emSize / 6.0; margin_x *= units_scale(font->unit, graphics->unit, graphics->xres, graphics->printer_display); transform_properties(graphics, NULL, TRUE, &args.rel_width, &args.rel_height, NULL); - scaled_rect.X = (layoutRect->X + margin_x) * args.rel_width; + scaled_rect.Y = (layoutRect->Y + offsety) * args.rel_height; scaled_rect.Width = layoutRect->Width * args.rel_width; scaled_rect.Height = layoutRect->Height * args.rel_height; - if (scaled_rect.Width >= 0.5f) + if (stringFormat->align == StringAlignmentNear) { - scaled_rect.Width -= margin_x * 2.0f * args.rel_width; - if (scaled_rect.Width < 0.5f) /* doesn't fit */ - scaled_rect.Width = 0.5f; + scaled_rect.X = (layoutRect->X + margin_x) * args.rel_width; + if (scaled_rect.Width >= 0.5f) + { + scaled_rect.Width -= margin_x * 2.0f * args.rel_width; + if (scaled_rect.Width < 0.5f) /* doesn't fit */ + scaled_rect.Width = 0.5f; + } } + else + scaled_rect.X = layoutRect->X * args.rel_width; if (scaled_rect.Width >= 1 << 23) scaled_rect.Width = 1 << 23; if (scaled_rect.Height >= 1 << 23) scaled_rect.Height = 1 << 23; @@ -6368,16 +6374,21 @@ GpStatus WINGDIPAPI GdipDrawString(GpGraphics *graphics, GDIPCONST WCHAR *string margin_x = (format && format->generic_typographic) ? 0.0 : font->emSize / 6.0; margin_x *= units_scale(font->unit, graphics->unit, graphics->xres, graphics->printer_display); - scaled_rect.X = margin_x * rel_width; scaled_rect.Y = 0.0; scaled_rect.Width = rel_width * rect->Width; scaled_rect.Height = rel_height * rect->Height; - if (scaled_rect.Width >= 0.5) + if (!format || format->align == StringAlignmentNear) { - scaled_rect.Width -= margin_x * 2.0 * rel_width; - if (scaled_rect.Width < 0.5) /* doesn't fit */ - goto end; + scaled_rect.X = margin_x * rel_width; + if (scaled_rect.Width >= 0.5f) + { + scaled_rect.Width -= margin_x * 2.0f * rel_width; + if (scaled_rect.Width < 0.5f) /* doesn't fit */ + goto end; + } } + else + scaled_rect.X = 0.0f; if (scaled_rect.Width >= 1 << 23) scaled_rect.Width = 1 << 23; if (scaled_rect.Height >= 1 << 23) scaled_rect.Height = 1 << 23; diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c index 8703081070f..9685ee851ab 100644 --- a/dlls/gdiplus/tests/graphics.c +++ b/dlls/gdiplus/tests/graphics.c @@ -4693,9 +4693,9 @@ static void test_measure_string(void) set_rect_empty(&bounds); status = GdipGetRegionBounds(region, graphics, &bounds); expect(Ok, status); - expectf_(5.0 + margin_x, bounds.X, 1.0); + expectf(5.0 + margin_x, bounds.X); expectf(5.0, bounds.Y); - expectf_(width - margin_x*2.0, bounds.Width, 1.0); + expectf(width - margin_x*2.0, bounds.Width); todo_wine expectf_(height - margin_y, bounds.Height, 1.0); @@ -4715,7 +4715,7 @@ static void test_measure_string(void) set_rect_empty(&bounds); status = GdipGetRegionBounds(region, graphics, &bounds); expect(Ok, status); - expectf_(margin_x, bounds.X, 1.0); + expectf(margin_x, bounds.X); expectf(0.0, bounds.Y); ok(bounds.Width < width_rgn / 2.0, "width of 1 glyph is wrong\n"); expectf(height_rgn, bounds.Height); @@ -4769,7 +4769,7 @@ static void test_measure_string(void) set_rect_empty(&bounds); status = GdipGetRegionBounds(region, graphics, &bounds); expect(Ok, status); - expectf_(5.0 + margin_x, bounds.X, 1.0); + expectf(5.0 + margin_x, bounds.X); expectf(5.0, bounds.Y); expectf(width_rgn, bounds.Width); expectf(height_rgn, bounds.Height); @@ -4905,9 +4905,9 @@ static void test_measure_string(void) set_rect_empty(&bounds); status = GdipGetRegionBounds(region, graphics, &bounds); expect(Ok, status); - expectf_(5.0 + margin_x, bounds.X, 1.0); + expectf(5.0 + margin_x, bounds.X); expectf(5.0, bounds.Y); - expectf_(width - margin_x*2.0, bounds.Width, 1.0); + expectf(width - margin_x*2.0, bounds.Width); todo_wine expectf_(height - margin_y, bounds.Height, 1.0); @@ -4955,10 +4955,10 @@ static void test_measure_string(void) set_rect_empty(&bounds); status = GdipGetRegionBounds(region, graphics, &bounds); expect(Ok, status); - expectf_(5.0 + width_rgn/2.0, bounds.X, 1.0); - expectf_(5.0 + height_rgn/2.0, bounds.Y, 1.0); - expectf_(width_rgn, bounds.Width, 1.0); - expectf_(height_rgn, bounds.Height, 1.0); + expectf(5.0 + width_rgn/2.0, bounds.X); + expectf(5.0 + height_rgn/2.0, bounds.Y); + expectf(width_rgn, bounds.Width); + expectf(height_rgn, bounds.Height); rect.X = 5.0; rect.Y = 5.0; @@ -4969,11 +4969,10 @@ static void test_measure_string(void) set_rect_empty(&bounds); status = GdipGetRegionBounds(region, graphics, &bounds); expect(Ok, status); - todo_wine - expectf_(5.0 - width_rgn/2.0, bounds.X, 1.0); - expectf_(5.0 - height_rgn/2.0, bounds.Y, 1.0); - expectf_(width_rgn, bounds.Width, 1.0); - expectf_(height_rgn, bounds.Height, 1.0); + expectf(5.0 - width_rgn/2.0, bounds.X); + expectf(5.0 - height_rgn/2.0, bounds.Y); + expectf(width_rgn, bounds.Width); + expectf(height_rgn, bounds.Height); /* Far alignment */ GdipSetStringFormatAlign(format, StringAlignmentFar); @@ -5016,11 +5015,10 @@ static void test_measure_string(void) set_rect_empty(&bounds); status = GdipGetRegionBounds(region, graphics, &bounds); expect(Ok, status); - todo_wine - expectf_(5.0 + width_rgn, bounds.X, 2.0); - expectf_(5.0 + height_rgn, bounds.Y, 1.0); - expectf_(width_rgn, bounds.Width, 1.0); - expectf_(height_rgn, bounds.Height, 1.0); + expectf(5.0 + width_rgn, bounds.X); + expectf(5.0 + height_rgn, bounds.Y); + expectf(width_rgn, bounds.Width); + expectf(height_rgn, bounds.Height); rect.X = 5.0; rect.Y = 5.0; @@ -5031,11 +5029,10 @@ static void test_measure_string(void) set_rect_empty(&bounds); status = GdipGetRegionBounds(region, graphics, &bounds); expect(Ok, status); - todo_wine - expectf_(5.0 - width_rgn, bounds.X, 2.0); - expectf_(5.0 - height_rgn, bounds.Y, 1.0); - expectf_(width_rgn, bounds.Width, 1.0); - expectf_(height_rgn, bounds.Height, 1.0); + expectf(5.0 - width_rgn, bounds.X); + expectf(5.0 - height_rgn, bounds.Y); + expectf(width_rgn, bounds.Width); + expectf(height_rgn, bounds.Height); /* Measure "MM" */ rect.X = 5.0; @@ -5777,10 +5774,10 @@ static void test_clipping(void) status = GdipGetClipBounds(graphics, &rect); expect(Ok, status); - expectf_(-28.100956, rect.X, 1.0); - expectf_(7.806488, rect.Y, 1.5); - expectf_(25.612978, rect.Width, 1.0); - expectf_(12.806489, rect.Height, 1.0); + expectf(-28.100956, rect.X); + expectf(7.806488, rect.Y); + expectf(25.612978, rect.Width); + expectf(12.806489, rect.Height); status = GdipSetEmpty(region); expect(Ok, status); @@ -5789,10 +5786,10 @@ static void test_clipping(void) status = GdipGetRegionBounds(region, graphics, &rect); expect(Ok, status); /* rounding under Wine is slightly different */ - expectf_(-28.100956, rect.X, 1.0); - expectf_(7.806488, rect.Y, 1.5); - expectf_(25.612978, rect.Width, 1.0); - expectf_(12.806489, rect.Height, 1.0); + expectf(-28.100956, rect.X); + expectf(7.806488, rect.Y); + expectf(25.612978, rect.Width); + expectf(12.806489, rect.Height); status = GdipGetRegionBounds(region100x100, graphics, &rect); expect(Ok, status); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10736
I don't how it is happen, but the expected values are wrong. I tested with: https://testbot.winehq.org/JobDetails.pl?Key=162769 Can I update these values (in separate PR)? -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10736#note_138027
On Tue Apr 28 18:30:48 2026 +0000, Bartosz Kosiorek wrote:
I don't how it is happen, but the expected values are wrong. I tested with: https://testbot.winehq.org/JobDetails.pl?Key=162769 Can I update these values (in separate PR)? I'd want to hear if @dmitry has an opinion on that, since he added them originally.
I'm ambivalent about having these at all. Given that the effective margins are going to vary with details of the font and how hinting affects the glyph sizes, I'm not sure we should assume they're stable even on Windows. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10736#note_138029
participants (3)
-
Bartosz Kosiorek -
Bartosz Kosiorek (@gang65) -
Esme Povirk (@madewokherd)