Module: wine Branch: master Commit: 4446db72ebdaa768ba218940dd286c0edaedf6e8 URL: https://gitlab.winehq.org/wine/wine/-/commit/4446db72ebdaa768ba218940dd286c0...
Author: Piotr Caban piotr@codeweavers.com Date: Wed Nov 29 20:48:55 2023 +0100
gdi32: Add ETO_PDY flag support in EMFDC_ExtTextOut.
---
dlls/gdi32/emfdc.c | 38 +++++++++++++++++++++++++++----------- dlls/gdi32/tests/metafile.c | 30 +++++++++++++++++++++++++++--- 2 files changed, 54 insertions(+), 14 deletions(-)
diff --git a/dlls/gdi32/emfdc.c b/dlls/gdi32/emfdc.c index 63110f57eeb..b2d1c894359 100644 --- a/dlls/gdi32/emfdc.c +++ b/dlls/gdi32/emfdc.c @@ -1336,13 +1336,15 @@ BOOL EMFDC_ExtTextOut( DC_ATTR *dc_attr, INT x, INT y, UINT flags, const RECT *r HDC hdc = dc_attr_handle( dc_attr ); FLOAT ex_scale, ey_scale; EMREXTTEXTOUTW *emr; - int text_height = 0; + int text_height = 0, top = y, bottom = y; int text_width = 0; TEXTMETRICW tm; - DWORD size; + DWORD dx_len, size; BOOL ret;
- size = sizeof(*emr) + ((count+1) & ~1) * sizeof(WCHAR) + count * sizeof(INT); + if (!dx && flags & ETO_PDY) return FALSE; + dx_len = flags & ETO_PDY ? count * 2 : count; + size = sizeof(*emr) + ((count+1) & ~1) * sizeof(WCHAR) + dx_len * sizeof(INT);
TRACE( "%s %s count %d size = %ld\n", debugstr_wn(str, count), wine_dbgstr_rect(rect), count, size ); @@ -1399,10 +1401,24 @@ BOOL EMFDC_ExtTextOut( DC_ATTR *dc_attr, INT x, INT y, UINT flags, const RECT *r { UINT i; SIZE str_size; - memcpy( (char*)emr + emr->emrtext.offDx, dx, count * sizeof(INT) ); - for (i = 0; i < count; i++) text_width += dx[i]; + memcpy( (char*)emr + emr->emrtext.offDx, dx, dx_len * sizeof(INT) ); if (GetTextExtentPoint32W( hdc, str, count, &str_size )) text_height = str_size.cy; + if (flags & ETO_PDY) + { + int cur_y = y; + for (i = 0; i < count; i++) + { + top = min( top, cur_y ); + bottom = max( bottom, cur_y ); + text_width += dx[2 * i]; + cur_y -= dx[2 * i + 1]; + } + } + else + { + for (i = 0; i < count; i++) text_width += dx[i]; + } } else { @@ -1451,18 +1467,18 @@ BOOL EMFDC_ExtTextOut( DC_ATTR *dc_attr, INT x, INT y, UINT flags, const RECT *r if (!GetTextMetricsW( hdc, &tm )) tm.tmDescent = 0; /* Play safe here... it's better to have a bounding box */ /* that is too big than too small. */ - emr->rclBounds.top = y - text_height - 1; - emr->rclBounds.bottom = y + tm.tmDescent + 1; + emr->rclBounds.top = top - text_height - 1; + emr->rclBounds.bottom = bottom + tm.tmDescent + 1; break;
case TA_BOTTOM: - emr->rclBounds.top = y - text_height - 1; - emr->rclBounds.bottom = y; + emr->rclBounds.top = top - text_height - 1; + emr->rclBounds.bottom = bottom; break;
default: /* TA_TOP */ - emr->rclBounds.top = y; - emr->rclBounds.bottom = y + text_height + 1; + emr->rclBounds.top = top; + emr->rclBounds.bottom = bottom + text_height + 1; } emfdc_update_bounds( emf, &emr->rclBounds );
diff --git a/dlls/gdi32/tests/metafile.c b/dlls/gdi32/tests/metafile.c index 9abd98b0f92..ab7882f9641 100644 --- a/dlls/gdi32/tests/metafile.c +++ b/dlls/gdi32/tests/metafile.c @@ -141,10 +141,23 @@ static int CALLBACK eto_emf_enum_proc(HDC hdc, HANDLETABLE *handle_table, ok(emr_ExtTextOutW->rclBounds.bottom != -1, "emr_ExtTextOutW->rclBounds.bottom = %ld\n", emr_ExtTextOutW->rclBounds.bottom);
- for(i = 0; i < emr_ExtTextOutW->emrtext.nChars; i++) + if(emr_ExtTextOutW->emrtext.fOptions & ETO_PDY) { - ok(orig_dx[i] == dx[i], "pass %d: dx[%ld] (%d) didn't match %d\n", - n_record, i, dx[i], orig_dx[i]); + ok(emr_ExtTextOutW->rclBounds.top < 0, "emr_ExtTextOutW->rclBounds.top = %ld\n", + emr_ExtTextOutW->rclBounds.top); + for(i = 0; i < emr_ExtTextOutW->emrtext.nChars * 2; i++) + { + ok(orig_dx[i] == dx[i], "pass %d: dx[%ld] (%d) didn't match %d\n", + n_record, i, dx[i], orig_dx[i]); + } + } + else + { + for(i = 0; i < emr_ExtTextOutW->emrtext.nChars; i++) + { + ok(orig_dx[2 * i] == dx[i], "pass %d: dx[%ld] (%d) didn't match %d\n", + n_record, i, dx[i], orig_dx[i]); + } } n_record++; emr_processed = TRUE; @@ -214,10 +227,21 @@ static void test_ExtTextOut(void) ret = ExtTextOutA(hdcMetafile, 0, 0, 0, &rc, text, lstrlenA(text), NULL); ok( ret, "ExtTextOutA error %ld\n", GetLastError());
+ ret = ExtTextOutA(hdcMetafile, 0, 0, ETO_PDY, &rc, text, len, NULL); + ok( !ret, "ExtTextOutA succeeded\n"); + /* 2. pass custom lpDx */ ret = ExtTextOutA(hdcMetafile, 0, 20, 0, &rc, text, lstrlenA(text), dx); ok( ret, "ExtTextOutA error %ld\n", GetLastError());
+ for (i = len - 1; i >= 0; i--) + { + dx[2 * i] = dx[i]; + dx[2 * i + 1] = 1; + } + ret = ExtTextOutA(hdcMetafile, 0, 20, ETO_PDY, &rc, text, len, dx); + ok( ret, "ExtTextOutA error %ld\n", GetLastError()); + /* 3. pass NULL lprc */ ret = ExtTextOutA(hdcMetafile, 0, 40, 0, NULL, text, lstrlenA(text), NULL); ok( ret, "ExtTextOutA error %ld\n", GetLastError());