From: Dmitry Timoshkov dmitry@baikal.ru
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 26518d285d9..ff3a079e495 100644 --- a/dlls/win32u/font.c +++ b/dlls/win32u/font.c @@ -228,12 +228,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 @@ -241,34 +239,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 ); @@ -4208,8 +4198,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)) @@ -4423,8 +4413,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) @@ -5398,14 +5388,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" @@ -5461,38 +5451,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) { @@ -5552,7 +5542,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 { @@ -5851,7 +5841,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; @@ -6285,9 +6275,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 @@ -7076,8 +7066,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;