From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/gdi32/tests/font.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index 82cec09e982..d062914d761 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -1399,7 +1399,7 @@ static void test_GetCharABCWidths(void)
static void test_text_extents(void) { - static const WCHAR wt[] = L"One\ntwo 3"; + static const WCHAR wt[] = L"One\r\ntwo 3\nfour"; LPINT extents; INT i, len, fit1, fit2, extents2[3]; LOGFONTA lf; @@ -1462,11 +1462,20 @@ static void test_text_extents(void) ok(extents[len-1] == sz1.cx, "GetTextExtentExPointW extents and size don't match\n"); ok(0 <= fit1 && fit1 <= len, "GetTextExtentExPointW generated illegal value %d for fit\n", fit1); ok(0 < fit1, "GetTextExtentExPointW says we can't even fit one letter in 32767 logical units\n"); + todo_wine + ok(extents[2] == extents[3], "Carriage return has width: %d != %d\n", extents[2], extents[3]); + todo_wine + ok(extents[3] == extents[4], "Line feed has width: %d != %d\n", extents[3], extents[4]); + todo_wine + ok(extents[9] == extents[10], "Unix-style newline has width: %d != %d\n", extents[3], extents[4]); GetTextExtentExPointW(hdc, wt, len, extents[2], &fit2, NULL, &sz2); ok(sz1.cx == sz2.cx && sz1.cy == sz2.cy, "GetTextExtentExPointW returned different sizes for the same string\n"); ok(fit2 == 3, "GetTextExtentExPointW extents isn't consistent with fit\n"); GetTextExtentExPointW(hdc, wt, len, extents[2]-1, &fit2, NULL, &sz2); ok(fit2 == 2, "GetTextExtentExPointW extents isn't consistent with fit\n"); + GetTextExtentExPointW(hdc, wt, len, extents[2]+1, &fit2, NULL, &sz2); + todo_wine + ok(fit2 == 5, "GetTextExtentExPointW newline doesn't fit in 1-pixel space\n"); GetTextExtentExPointW(hdc, wt, 2, 0, NULL, extents + 2, &sz2); ok(extents[0] == extents[2] && extents[1] == extents[3], "GetTextExtentExPointW with lpnFit == NULL returns incorrect results\n");
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/gdi32/tests/font.c | 4 ---- dlls/gdiplus/tests/graphics.c | 2 +- dlls/win32u/font.c | 15 ++++++++++++--- 3 files changed, 13 insertions(+), 8 deletions(-)
diff --git a/dlls/gdi32/tests/font.c b/dlls/gdi32/tests/font.c index d062914d761..b6a266ede30 100644 --- a/dlls/gdi32/tests/font.c +++ b/dlls/gdi32/tests/font.c @@ -1462,11 +1462,8 @@ static void test_text_extents(void) ok(extents[len-1] == sz1.cx, "GetTextExtentExPointW extents and size don't match\n"); ok(0 <= fit1 && fit1 <= len, "GetTextExtentExPointW generated illegal value %d for fit\n", fit1); ok(0 < fit1, "GetTextExtentExPointW says we can't even fit one letter in 32767 logical units\n"); - todo_wine ok(extents[2] == extents[3], "Carriage return has width: %d != %d\n", extents[2], extents[3]); - todo_wine ok(extents[3] == extents[4], "Line feed has width: %d != %d\n", extents[3], extents[4]); - todo_wine ok(extents[9] == extents[10], "Unix-style newline has width: %d != %d\n", extents[3], extents[4]); GetTextExtentExPointW(hdc, wt, len, extents[2], &fit2, NULL, &sz2); ok(sz1.cx == sz2.cx && sz1.cy == sz2.cy, "GetTextExtentExPointW returned different sizes for the same string\n"); @@ -1474,7 +1471,6 @@ static void test_text_extents(void) GetTextExtentExPointW(hdc, wt, len, extents[2]-1, &fit2, NULL, &sz2); ok(fit2 == 2, "GetTextExtentExPointW extents isn't consistent with fit\n"); GetTextExtentExPointW(hdc, wt, len, extents[2]+1, &fit2, NULL, &sz2); - todo_wine ok(fit2 == 5, "GetTextExtentExPointW newline doesn't fit in 1-pixel space\n"); GetTextExtentExPointW(hdc, wt, 2, 0, NULL, extents + 2, &sz2); ok(extents[0] == extents[2] && extents[1] == extents[3], diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c index 0456a451970..51b2c324031 100644 --- a/dlls/gdiplus/tests/graphics.c +++ b/dlls/gdiplus/tests/graphics.c @@ -3356,7 +3356,7 @@ static void test_string_functions(void) expectf_(char_bounds.Width, bounds.Width, 0.01); expectf_(char_bounds.Height + char_height * 3, bounds.Height, 0.05); expect(6, codepointsfitted); - todo_wine expect(4, linesfilled); + expect(4, linesfilled);
for (i = 0; i < 4; i++) regions[i] = (GpRegion *)0xdeadbeef; diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c index 4a341453012..1b35747b043 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -4327,8 +4327,11 @@ static BOOL font_GetTextExtentExPoint( PHYSDEV dev, const WCHAR *str, INT count, pthread_mutex_lock( &font_lock ); for (i = pos = 0; i < count; i++) { - get_glyph_outline( physdev->font, str[i], GGO_METRICS, NULL, &abc, 0, NULL, NULL ); - pos += abc.abcA + abc.abcB + abc.abcC; + if (str[i] != '\r' && str[i] != '\n') + { + get_glyph_outline( physdev->font, str[i], GGO_METRICS, NULL, &abc, 0, NULL, NULL ); + pos += abc.abcA + abc.abcB + abc.abcC; + } dxs[i] = pos; } pthread_mutex_unlock( &font_lock ); @@ -5347,7 +5350,13 @@ BOOL WINAPI NtGdiGetTextExtentExW( HDC hdc, const WCHAR *str, INT count, INT max { unsigned int dx = abs( INTERNAL_XDSTOWS( dc, pos[i] )) + (i + 1) * dc->attr->char_extra; - if (nfit && dx > (unsigned int)max_ext) break; + if (nfit) + { + unsigned int max_ext2 = (unsigned int)max_ext; + if (str[i] == '\r' || str[i] == '\n') + max_ext2 -= 1; + if (dx > max_ext2) break; + } if (dxs) dxs[i] = dx; } if (nfit) *nfit = i;
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/gdiplus/tests/graphics.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c index 51b2c324031..de3154a6a93 100644 --- a/dlls/gdiplus/tests/graphics.c +++ b/dlls/gdiplus/tests/graphics.c @@ -3358,6 +3358,20 @@ static void test_string_functions(void) expect(6, codepointsfitted); expect(4, linesfilled);
+ rc.Width = 0; + rc.Height = 0; + + status = GdipMeasureString(graphics, L"\n", -1, font, &rc, NULL, &bounds, &codepointsfitted, &linesfilled); + expect(Ok, status); + expectf(0.0, bounds.X); + expectf(0.0, bounds.Y); + expectf_(3.33, bounds.Width, 0.01); + todo_wine + expectf_(char_bounds.Height, bounds.Height, 0.05); + todo_wine + expect(1, codepointsfitted); + expect(1, linesfilled); + for (i = 0; i < 4; i++) regions[i] = (GpRegion *)0xdeadbeef;
From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/gdiplus/graphics.c | 10 ++++++---- dlls/gdiplus/tests/graphics.c | 4 +--- 2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 758889eca06..fad2e700fee 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -5245,6 +5245,7 @@ GpStatus gdip_format_string(HDC hdc, if(*(stringdup + sum + lret) == '\n') { unixstyle_newline = TRUE; + lret += 1; break; }
@@ -5252,13 +5253,14 @@ GpStatus gdip_format_string(HDC hdc, && *(stringdup + sum + lret + 1) == '\n') { unixstyle_newline = FALSE; + lret += 2; break; } }
/* Line break code (may look strange, but it imitates windows). */ - if(lret < fit) - lineend = fit = lret; /* this is not an off-by-one error */ + if(lret > 0 && *(stringdup + sum + lret - 1) == '\n') + lineend = fit = lret; else if(fit < (length - sum)){ if(*(stringdup + sum + fit) == ' ') while(*(stringdup + sum + fit) == ' ') @@ -5330,13 +5332,13 @@ GpStatus gdip_format_string(HDC hdc, { height += size.cy; lineno++; - sum += fit + (lret < fitcpy ? 1 : 0); + sum += fit; } else { height += size.cy; lineno++; - sum += fit + (lret < fitcpy ? 2 : 0); + sum += fit; }
hotkeyprefix_pos = hotkeyprefix_end_pos; diff --git a/dlls/gdiplus/tests/graphics.c b/dlls/gdiplus/tests/graphics.c index de3154a6a93..9fcc620d538 100644 --- a/dlls/gdiplus/tests/graphics.c +++ b/dlls/gdiplus/tests/graphics.c @@ -3319,7 +3319,7 @@ static void test_string_functions(void) expect(Ok, status); expectf(0.0, bounds.X); expectf(0.0, bounds.Y); - todo_wine expect(5, codepointsfitted); + expect(5, codepointsfitted); todo_wine expect(1, linesfilled);
/* Cut off everything after the first space. */ @@ -3366,9 +3366,7 @@ static void test_string_functions(void) expectf(0.0, bounds.X); expectf(0.0, bounds.Y); expectf_(3.33, bounds.Width, 0.01); - todo_wine expectf_(char_bounds.Height, bounds.Height, 0.05); - todo_wine expect(1, codepointsfitted); expect(1, linesfilled);
Hello,
I tried pulling from your git branch to test but couldn't. I believe it is something about the ``/`` which has to be escaped or something. Either it is not possible to pull from that branch or my git skills aren't very great. I was forced to download the patches from email which, of course, is less convenient.
I have two comments on this patchset:
i) The zero character width rule applies to all whitespace. This means that while your patchset in the direction of fixing the gdiplus issues, it might need to be revisited to fix the width for all whitespace.
ii)The changes you have made to gdiplus now mean that the draw functions(DrawString and AddPathString) are now broken in that they render whitespace. The related gdi functions do not recognize whitespace and so they will now produce artifacts on the screen/image similar to what you would expect if a rendered character is missing from a font. See the tiny attached image which is rendered/drawn from the string `Hello\nWorld`
![gdiplus-test-string.png](/uploads/3b4f7d47f82013b93275ccd0c49f4967/gdiplus-test-string.png)