gdip_format_string doesn't write newline characters. It writes line by line making sure to skip the newline characters. This means we can resolve this issue(at least as far gdiplus is concerned) without concerning ourselves with the issue in GetTextExtentExPointW(which should be dealt with as a different bug).
This patch implements a fix but there might be possible improvements in the code so yeah, input is most welcome.
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54962
Signed-off-by: David Kahurani k.kahurani@gmail.com
From: David Kahurani k.kahurani@gmail.com
Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=54962 Signed-off-by: David Kahurani k.kahurani@gmail.com --- dlls/gdiplus/graphics.c | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-)
diff --git a/dlls/gdiplus/graphics.c b/dlls/gdiplus/graphics.c index 6831cfcb247..f49e26af2d2 100644 --- a/dlls/gdiplus/graphics.c +++ b/dlls/gdiplus/graphics.c @@ -5185,7 +5185,7 @@ GpStatus gdip_format_string(HDC hdc, INT *hotkeyprefix_offsets=NULL; INT hotkeyprefix_count=0; INT hotkeyprefix_pos=0, hotkeyprefix_end_pos=0; - BOOL seen_prefix = FALSE; + BOOL seen_prefix = FALSE, unix_newline = TRUE;
if(length == -1) length = lstrlenW(string);
@@ -5258,9 +5258,19 @@ GpStatus gdip_format_string(HDC hdc, if(fit == 0) break;
- for(lret = 0; lret < fit; lret++) - if(*(stringdup + sum + lret) == '\n') + for(lret = 0; lret < fit; lret++) { + /* Unix style new line */ + if(*(stringdup + sum + lret) == '\n'){ + unix_newline = TRUE; break; + } + + /* Windows style new line */ + if(*(stringdup + sum + lret) == '\r' && *(stringdup + sum + lret + 1) == '\n'){ + unix_newline = FALSE; + break; + } + }
/* Line break code (may look strange, but it imitates windows). */ if(lret < fit) @@ -5331,7 +5341,12 @@ GpStatus gdip_format_string(HDC hdc, if (stat != Ok) break;
- sum += fit + (lret < fitcpy ? 1 : 0); + + if (unix_newline) + sum += fit + (lret < fitcpy ? 1 : 0); + else + sum += fit + (lret < fitcpy ? 2 : 0); + height += size.cy; lineno++;
Esme Povirk (@madewokherd) commented about dlls/gdiplus/graphics.c:
if(fit == 0) break;
for(lret = 0; lret < fit; lret++)
if(*(stringdup + sum + lret) == '\n')
for(lret = 0; lret < fit; lret++) {
/* Unix style new line */
if(*(stringdup + sum + lret) == '\n'){
unix_newline = TRUE; break;
}
/* Windows style new line */
if(*(stringdup + sum + lret) == '\r' && *(stringdup + sum + lret + 1) == '\n'){
This needs to do bounds checking in case the string ends with \r.
I'm curious what happens with mac-style newlines (\r on its own).
Tests (using `GdipMeasureString`) would be nice but not required.