mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
Added win32u-NtGdiExtTextOutW-rotation patchset
This commit is contained in:
parent
44f9ec9761
commit
02792d0328
@ -0,0 +1,232 @@
|
||||
From de25c3d088ef5feba4c45ca9e885451604781749 Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Timoshkov <dmitry@baikal.ru>
|
||||
Date: Wed, 7 Feb 2024 19:14:29 +0300
|
||||
Subject: [PATCH 1/2] win32u: Fix device<->world width/height converters.
|
||||
|
||||
Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru>
|
||||
---
|
||||
dlls/win32u/font.c | 130 +++++++++++++++++++++------------------------
|
||||
1 file changed, 60 insertions(+), 70 deletions(-)
|
||||
|
||||
diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c
|
||||
index 62a4dc51035..8fbd8dc3f01 100644
|
||||
--- a/dlls/win32u/font.c
|
||||
+++ b/dlls/win32u/font.c
|
||||
@@ -229,12 +229,10 @@ static inline int facename_compare( const WCHAR *str1, const WCHAR *str2, SIZE_T
|
||||
*/
|
||||
static inline INT INTERNAL_XDSTOWS(DC *dc, INT width)
|
||||
{
|
||||
- double floatWidth;
|
||||
+ float scale_x;
|
||||
|
||||
- /* Perform operation with floating point */
|
||||
- floatWidth = (double)width * dc->xformVport2World.eM11;
|
||||
- /* Round to integers */
|
||||
- return GDI_ROUND(floatWidth);
|
||||
+ scale_x = hypotf(dc->xformWorld2Vport.eM11, dc->xformWorld2Vport.eM12);
|
||||
+ return GDI_ROUND( (float)width / scale_x );
|
||||
}
|
||||
|
||||
/* Performs a device to world transformation on the specified size (which
|
||||
@@ -242,34 +240,26 @@ static inline INT INTERNAL_XDSTOWS(DC *dc, INT width)
|
||||
*/
|
||||
static inline INT INTERNAL_YDSTOWS(DC *dc, INT height)
|
||||
{
|
||||
- double floatHeight;
|
||||
+ float scale_y;
|
||||
|
||||
- /* Perform operation with floating point */
|
||||
- floatHeight = (double)height * dc->xformVport2World.eM22;
|
||||
- /* Round to integers */
|
||||
- return GDI_ROUND(floatHeight);
|
||||
+ scale_y = hypotf(dc->xformWorld2Vport.eM21, dc->xformWorld2Vport.eM22);
|
||||
+ return GDI_ROUND( (float)height / scale_y );
|
||||
}
|
||||
|
||||
-/* scale width and height but don't mirror them */
|
||||
-
|
||||
-static inline INT width_to_LP( DC *dc, INT width )
|
||||
+static inline INT INTERNAL_XWSTODS(DC *dc, INT width)
|
||||
{
|
||||
- return GDI_ROUND( (double)width * fabs( dc->xformVport2World.eM11 ));
|
||||
-}
|
||||
+ float scale_x;
|
||||
|
||||
-static inline INT height_to_LP( DC *dc, INT height )
|
||||
-{
|
||||
- return GDI_ROUND( (double)height * fabs( dc->xformVport2World.eM22 ));
|
||||
+ scale_x = hypotf(dc->xformWorld2Vport.eM11, dc->xformWorld2Vport.eM12);
|
||||
+ return GDI_ROUND( (float)width / scale_x );
|
||||
}
|
||||
|
||||
static inline INT INTERNAL_YWSTODS(DC *dc, INT height)
|
||||
{
|
||||
- POINT pt[2];
|
||||
- pt[0].x = pt[0].y = 0;
|
||||
- pt[1].x = 0;
|
||||
- pt[1].y = height;
|
||||
- lp_to_dp(dc, pt, 2);
|
||||
- return pt[1].y - pt[0].y;
|
||||
+ float scale_y;
|
||||
+
|
||||
+ scale_y = hypotf(dc->xformWorld2Vport.eM21, dc->xformWorld2Vport.eM22);
|
||||
+ return GDI_ROUND( (float)height / scale_y );
|
||||
}
|
||||
|
||||
static INT FONT_GetObjectW( HGDIOBJ handle, INT count, LPVOID buffer );
|
||||
@@ -4215,8 +4205,8 @@ static void scale_outline_font_metrics( const struct gdi_font *font, OUTLINETEXT
|
||||
else
|
||||
scale_x = font->scale_y;
|
||||
|
||||
- scale_x *= fabs(font->matrix.eM11);
|
||||
- scale_y = font->scale_y * fabs(font->matrix.eM22);
|
||||
+ scale_x *= hypotf(font->matrix.eM11, font->matrix.eM12);
|
||||
+ scale_y = font->scale_y * hypotf(font->matrix.eM21, font->matrix.eM22);
|
||||
|
||||
/* Windows scales these values as signed integers even if they are unsigned */
|
||||
#define SCALE_X(x) (x) = GDI_ROUND((int)(x) * (scale_x))
|
||||
@@ -4430,8 +4420,8 @@ static void scale_font_metrics( struct gdi_font *font, TEXTMETRICW *tm )
|
||||
else
|
||||
scale_x = font->scale_y;
|
||||
|
||||
- scale_x *= fabs(font->matrix.eM11);
|
||||
- scale_y = font->scale_y * fabs(font->matrix.eM22);
|
||||
+ scale_x *= hypotf(font->matrix.eM11, font->matrix.eM12);
|
||||
+ scale_y = font->scale_y * hypotf(font->matrix.eM21, font->matrix.eM22);
|
||||
|
||||
#define SCALE_X(x) (x) = GDI_ROUND((x) * scale_x)
|
||||
#define SCALE_Y(y) (y) = GDI_ROUND((y) * scale_y)
|
||||
@@ -5400,14 +5390,14 @@ BOOL WINAPI NtGdiGetTextMetricsW( HDC hdc, TEXTMETRICW *metrics, ULONG flags )
|
||||
|
||||
metrics->tmDigitizedAspectX = NtGdiGetDeviceCaps(hdc, LOGPIXELSX);
|
||||
metrics->tmDigitizedAspectY = NtGdiGetDeviceCaps(hdc, LOGPIXELSY);
|
||||
- metrics->tmHeight = height_to_LP( dc, metrics->tmHeight );
|
||||
- metrics->tmAscent = height_to_LP( dc, metrics->tmAscent );
|
||||
- metrics->tmDescent = height_to_LP( dc, metrics->tmDescent );
|
||||
- metrics->tmInternalLeading = height_to_LP( dc, metrics->tmInternalLeading );
|
||||
- metrics->tmExternalLeading = height_to_LP( dc, metrics->tmExternalLeading );
|
||||
- metrics->tmAveCharWidth = width_to_LP( dc, metrics->tmAveCharWidth );
|
||||
- metrics->tmMaxCharWidth = width_to_LP( dc, metrics->tmMaxCharWidth );
|
||||
- metrics->tmOverhang = width_to_LP( dc, metrics->tmOverhang );
|
||||
+ metrics->tmHeight = INTERNAL_YDSTOWS( dc, metrics->tmHeight );
|
||||
+ metrics->tmAscent = INTERNAL_YDSTOWS( dc, metrics->tmAscent );
|
||||
+ metrics->tmDescent = INTERNAL_YDSTOWS( dc, metrics->tmDescent );
|
||||
+ metrics->tmInternalLeading = INTERNAL_YDSTOWS( dc, metrics->tmInternalLeading );
|
||||
+ metrics->tmExternalLeading = INTERNAL_YDSTOWS( dc, metrics->tmExternalLeading );
|
||||
+ metrics->tmAveCharWidth = INTERNAL_XDSTOWS( dc, metrics->tmAveCharWidth );
|
||||
+ metrics->tmMaxCharWidth = INTERNAL_XDSTOWS( dc, metrics->tmMaxCharWidth );
|
||||
+ metrics->tmOverhang = INTERNAL_XDSTOWS( dc, metrics->tmOverhang );
|
||||
ret = TRUE;
|
||||
|
||||
TRACE("text metrics:\n"
|
||||
@@ -5463,38 +5453,38 @@ UINT WINAPI NtGdiGetOutlineTextMetricsInternalW( HDC hdc, UINT cbData,
|
||||
{
|
||||
output->otmTextMetrics.tmDigitizedAspectX = NtGdiGetDeviceCaps(hdc, LOGPIXELSX);
|
||||
output->otmTextMetrics.tmDigitizedAspectY = NtGdiGetDeviceCaps(hdc, LOGPIXELSY);
|
||||
- output->otmTextMetrics.tmHeight = height_to_LP( dc, output->otmTextMetrics.tmHeight );
|
||||
- output->otmTextMetrics.tmAscent = height_to_LP( dc, output->otmTextMetrics.tmAscent );
|
||||
- output->otmTextMetrics.tmDescent = height_to_LP( dc, output->otmTextMetrics.tmDescent );
|
||||
- output->otmTextMetrics.tmInternalLeading = height_to_LP( dc, output->otmTextMetrics.tmInternalLeading );
|
||||
- output->otmTextMetrics.tmExternalLeading = height_to_LP( dc, output->otmTextMetrics.tmExternalLeading );
|
||||
- output->otmTextMetrics.tmAveCharWidth = width_to_LP( dc, output->otmTextMetrics.tmAveCharWidth );
|
||||
- output->otmTextMetrics.tmMaxCharWidth = width_to_LP( dc, output->otmTextMetrics.tmMaxCharWidth );
|
||||
- output->otmTextMetrics.tmOverhang = width_to_LP( dc, output->otmTextMetrics.tmOverhang );
|
||||
- output->otmAscent = height_to_LP( dc, output->otmAscent);
|
||||
- output->otmDescent = height_to_LP( dc, output->otmDescent);
|
||||
+ output->otmTextMetrics.tmHeight = INTERNAL_YDSTOWS( dc, output->otmTextMetrics.tmHeight );
|
||||
+ output->otmTextMetrics.tmAscent = INTERNAL_YDSTOWS( dc, output->otmTextMetrics.tmAscent );
|
||||
+ output->otmTextMetrics.tmDescent = INTERNAL_YDSTOWS( dc, output->otmTextMetrics.tmDescent );
|
||||
+ output->otmTextMetrics.tmInternalLeading = INTERNAL_YDSTOWS( dc, output->otmTextMetrics.tmInternalLeading );
|
||||
+ output->otmTextMetrics.tmExternalLeading = INTERNAL_YDSTOWS( dc, output->otmTextMetrics.tmExternalLeading );
|
||||
+ output->otmTextMetrics.tmAveCharWidth = INTERNAL_XDSTOWS( dc, output->otmTextMetrics.tmAveCharWidth );
|
||||
+ output->otmTextMetrics.tmMaxCharWidth = INTERNAL_XDSTOWS( dc, output->otmTextMetrics.tmMaxCharWidth );
|
||||
+ output->otmTextMetrics.tmOverhang = INTERNAL_XDSTOWS( dc, output->otmTextMetrics.tmOverhang );
|
||||
+ output->otmAscent = INTERNAL_YDSTOWS( dc, output->otmAscent);
|
||||
+ output->otmDescent = INTERNAL_YDSTOWS( dc, output->otmDescent);
|
||||
output->otmLineGap = INTERNAL_YDSTOWS(dc, output->otmLineGap);
|
||||
output->otmsCapEmHeight = INTERNAL_YDSTOWS(dc, output->otmsCapEmHeight);
|
||||
output->otmsXHeight = INTERNAL_YDSTOWS(dc, output->otmsXHeight);
|
||||
- output->otmrcFontBox.top = height_to_LP( dc, output->otmrcFontBox.top);
|
||||
- output->otmrcFontBox.bottom = height_to_LP( dc, output->otmrcFontBox.bottom);
|
||||
- output->otmrcFontBox.left = width_to_LP( dc, output->otmrcFontBox.left);
|
||||
- output->otmrcFontBox.right = width_to_LP( dc, output->otmrcFontBox.right);
|
||||
- output->otmMacAscent = height_to_LP( dc, output->otmMacAscent);
|
||||
- output->otmMacDescent = height_to_LP( dc, output->otmMacDescent);
|
||||
+ output->otmrcFontBox.top = INTERNAL_YDSTOWS( dc, output->otmrcFontBox.top);
|
||||
+ output->otmrcFontBox.bottom = INTERNAL_YDSTOWS( dc, output->otmrcFontBox.bottom);
|
||||
+ output->otmrcFontBox.left = INTERNAL_XDSTOWS( dc, output->otmrcFontBox.left);
|
||||
+ output->otmrcFontBox.right = INTERNAL_XDSTOWS( dc, output->otmrcFontBox.right);
|
||||
+ output->otmMacAscent = INTERNAL_YDSTOWS( dc, output->otmMacAscent);
|
||||
+ output->otmMacDescent = INTERNAL_YDSTOWS( dc, output->otmMacDescent);
|
||||
output->otmMacLineGap = INTERNAL_YDSTOWS(dc, output->otmMacLineGap);
|
||||
- output->otmptSubscriptSize.x = width_to_LP( dc, output->otmptSubscriptSize.x);
|
||||
- output->otmptSubscriptSize.y = height_to_LP( dc, output->otmptSubscriptSize.y);
|
||||
- output->otmptSubscriptOffset.x = width_to_LP( dc, output->otmptSubscriptOffset.x);
|
||||
- output->otmptSubscriptOffset.y = height_to_LP( dc, output->otmptSubscriptOffset.y);
|
||||
- output->otmptSuperscriptSize.x = width_to_LP( dc, output->otmptSuperscriptSize.x);
|
||||
- output->otmptSuperscriptSize.y = height_to_LP( dc, output->otmptSuperscriptSize.y);
|
||||
- output->otmptSuperscriptOffset.x = width_to_LP( dc, output->otmptSuperscriptOffset.x);
|
||||
- output->otmptSuperscriptOffset.y = height_to_LP( dc, output->otmptSuperscriptOffset.y);
|
||||
+ output->otmptSubscriptSize.x = INTERNAL_XDSTOWS( dc, output->otmptSubscriptSize.x);
|
||||
+ output->otmptSubscriptSize.y = INTERNAL_YDSTOWS( dc, output->otmptSubscriptSize.y);
|
||||
+ output->otmptSubscriptOffset.x = INTERNAL_XDSTOWS( dc, output->otmptSubscriptOffset.x);
|
||||
+ output->otmptSubscriptOffset.y = INTERNAL_YDSTOWS( dc, output->otmptSubscriptOffset.y);
|
||||
+ output->otmptSuperscriptSize.x = INTERNAL_XDSTOWS( dc, output->otmptSuperscriptSize.x);
|
||||
+ output->otmptSuperscriptSize.y = INTERNAL_YDSTOWS( dc, output->otmptSuperscriptSize.y);
|
||||
+ output->otmptSuperscriptOffset.x = INTERNAL_XDSTOWS( dc, output->otmptSuperscriptOffset.x);
|
||||
+ output->otmptSuperscriptOffset.y = INTERNAL_YDSTOWS( dc, output->otmptSuperscriptOffset.y);
|
||||
output->otmsStrikeoutSize = INTERNAL_YDSTOWS(dc, output->otmsStrikeoutSize);
|
||||
- output->otmsStrikeoutPosition = height_to_LP( dc, output->otmsStrikeoutPosition);
|
||||
- output->otmsUnderscoreSize = height_to_LP( dc, output->otmsUnderscoreSize);
|
||||
- output->otmsUnderscorePosition = height_to_LP( dc, output->otmsUnderscorePosition);
|
||||
+ output->otmsStrikeoutPosition = INTERNAL_YDSTOWS( dc, output->otmsStrikeoutPosition);
|
||||
+ output->otmsUnderscoreSize = INTERNAL_YDSTOWS( dc, output->otmsUnderscoreSize);
|
||||
+ output->otmsUnderscorePosition = INTERNAL_YDSTOWS( dc, output->otmsUnderscorePosition);
|
||||
|
||||
if(output != lpOTM)
|
||||
{
|
||||
@@ -5554,7 +5544,7 @@ BOOL WINAPI NtGdiGetCharWidthW( HDC hdc, UINT first, UINT last, WCHAR *chars,
|
||||
INT *buffer = buf;
|
||||
/* convert device units to logical */
|
||||
for (i = 0; i < count; i++)
|
||||
- buffer[i] = width_to_LP( dc, buffer[i] );
|
||||
+ buffer[i] = INTERNAL_XDSTOWS( dc, buffer[i] );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -5853,7 +5843,7 @@ BOOL nulldrv_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *rect
|
||||
*/
|
||||
static inline int get_line_width( DC *dc, int metric_size )
|
||||
{
|
||||
- int width = abs( INTERNAL_YWSTODS( dc, metric_size ));
|
||||
+ int width = abs( INTERNAL_XWSTODS( dc, metric_size ));
|
||||
if (width == 0) width = 1;
|
||||
if (metric_size < 0) width = -width;
|
||||
return width;
|
||||
@@ -6287,9 +6277,9 @@ BOOL WINAPI NtGdiGetCharABCWidthsW( HDC hdc, UINT first, UINT last, WCHAR *chars
|
||||
/* convert device units to logical */
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
- abc[i].abcA = width_to_LP( dc, abc[i].abcA );
|
||||
- abc[i].abcB = width_to_LP( dc, abc[i].abcB );
|
||||
- abc[i].abcC = width_to_LP( dc, abc[i].abcC );
|
||||
+ abc[i].abcA = INTERNAL_XDSTOWS( dc, abc[i].abcA );
|
||||
+ abc[i].abcB = INTERNAL_XDSTOWS( dc, abc[i].abcB );
|
||||
+ abc[i].abcC = INTERNAL_XDSTOWS( dc, abc[i].abcC );
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -7078,8 +7068,8 @@ BOOL WINAPI NtGdiGetCharWidthInfo( HDC hdc, struct char_width_info *info )
|
||||
|
||||
if (ret)
|
||||
{
|
||||
- info->lsb = width_to_LP( dc, info->lsb );
|
||||
- info->rsb = width_to_LP( dc, info->rsb );
|
||||
+ info->lsb = INTERNAL_XDSTOWS( dc, info->lsb );
|
||||
+ info->rsb = INTERNAL_XDSTOWS( dc, info->rsb );
|
||||
}
|
||||
release_dc_ptr(dc);
|
||||
return ret;
|
||||
--
|
||||
2.46.0
|
||||
|
@ -0,0 +1,55 @@
|
||||
From 33d132644a7398e4a3a17f1745dcb626ea6694af Mon Sep 17 00:00:00 2001
|
||||
From: Dmitry Timoshkov <dmitry@baikal.ru>
|
||||
Date: Wed, 22 Nov 2023 11:51:23 +0300
|
||||
Subject: [PATCH 2/2] win32u: NtGdiExtTextOutW() should translate x,y from
|
||||
logical to device units at the last step.
|
||||
|
||||
Bug: https://bugs.winehq.org/show_bug.cgi?id=33190
|
||||
|
||||
Signed-off-by: Dmitry Timoshkov <dmitry@baikal.ru>
|
||||
---
|
||||
dlls/win32u/font.c | 14 ++++++--------
|
||||
1 file changed, 6 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c
|
||||
index 8fbd8dc3f01..f32becbe669 100644
|
||||
--- a/dlls/win32u/font.c
|
||||
+++ b/dlls/win32u/font.c
|
||||
@@ -5972,12 +5972,6 @@ BOOL WINAPI NtGdiExtTextOutW( HDC hdc, INT x, INT y, UINT flags, const RECT *lpr
|
||||
goto done;
|
||||
}
|
||||
|
||||
- pt.x = x;
|
||||
- pt.y = y;
|
||||
- lp_to_dp(dc, &pt, 1);
|
||||
- x = pt.x;
|
||||
- y = pt.y;
|
||||
-
|
||||
char_extra = dc->attr->char_extra;
|
||||
if (char_extra && lpDx && NtGdiGetDeviceCaps( hdc, TECHNOLOGY ) == DT_RASPRINTER)
|
||||
char_extra = 0; /* Printer drivers don't add char_extra if lpDx is supplied */
|
||||
@@ -6074,8 +6068,6 @@ BOOL WINAPI NtGdiExtTextOutW( HDC hdc, INT x, INT y, UINT flags, const RECT *lpr
|
||||
width = desired[1];
|
||||
}
|
||||
|
||||
- tm.tmAscent = abs(INTERNAL_YWSTODS(dc, tm.tmAscent));
|
||||
- tm.tmDescent = abs(INTERNAL_YWSTODS(dc, tm.tmDescent));
|
||||
switch( align & (TA_LEFT | TA_RIGHT | TA_CENTER) )
|
||||
{
|
||||
case TA_LEFT:
|
||||
@@ -6143,6 +6135,12 @@ BOOL WINAPI NtGdiExtTextOutW( HDC hdc, INT x, INT y, UINT flags, const RECT *lpr
|
||||
}
|
||||
}
|
||||
|
||||
+ pt.x = x;
|
||||
+ pt.y = y;
|
||||
+ lp_to_dp(dc, &pt, 1);
|
||||
+ x = pt.x;
|
||||
+ y = pt.y;
|
||||
+
|
||||
ret = physdev->funcs->pExtTextOut( physdev, x, y, (flags & ~ETO_OPAQUE), &rc,
|
||||
str, count, (INT*)deltas );
|
||||
|
||||
--
|
||||
2.46.0
|
||||
|
3
patches/win32u-NtGdiExtTextOutW-rotation/definition
Normal file
3
patches/win32u-NtGdiExtTextOutW-rotation/definition
Normal file
@ -0,0 +1,3 @@
|
||||
Fixes [33190]: win32u - Fix rendering of the rotated and scaled text.
|
||||
|
||||
# Merge Request !5068
|
Loading…
Reference in New Issue
Block a user