From: Dmitry Timoshkov dmitry@baikal.ru
Signed-off-by: Dmitry Timoshkov dmitry@baikal.ru --- dlls/win32u/font.c | 48 ++++++++++++++++++++++++---------------------- 1 file changed, 25 insertions(+), 23 deletions(-)
diff --git a/dlls/win32u/font.c b/dlls/win32u/font.c index 9ee89f1b5c4..1726165e778 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 = sqrtf(dc->xformWorld2Vport.eM11 * dc->xformWorld2Vport.eM11 + dc->xformWorld2Vport.eM12 * dc->xformWorld2Vport.eM12); + return GDI_ROUND( (float)width / scale_x ); }
/* Performs a device to world transformation on the specified size (which @@ -241,34 +239,38 @@ 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 = sqrtf(dc->xformWorld2Vport.eM21 * dc->xformWorld2Vport.eM21 + dc->xformWorld2Vport.eM22 * 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 ) { - return GDI_ROUND( (double)width * fabs( dc->xformVport2World.eM11 )); + return INTERNAL_XDSTOWS( dc, width ); }
static inline INT height_to_LP( DC *dc, INT height ) { - return GDI_ROUND( (double)height * fabs( dc->xformVport2World.eM22 )); + return INTERNAL_YDSTOWS( dc, height ); +} + +static inline INT INTERNAL_XWSTODS(DC *dc, INT width) +{ + float scale_x; + + scale_x = sqrtf(dc->xformVport2World.eM11 * dc->xformVport2World.eM11 + dc->xformVport2World.eM12 * dc->xformVport2World.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 = sqrtf(dc->xformVport2World.eM21 * dc->xformVport2World.eM21 + dc->xformVport2World.eM22 * dc->xformVport2World.eM22); + return GDI_ROUND( (float)height / scale_y ); }
static INT FONT_GetObjectW( HGDIOBJ handle, INT count, LPVOID buffer ); @@ -4195,8 +4197,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 *= sqrtf(font->matrix.eM11 * font->matrix.eM11 + font->matrix.eM12 * font->matrix.eM12); + scale_y = font->scale_y * sqrtf(font->matrix.eM21 * font->matrix.eM21 + font->matrix.eM22 * 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)) @@ -4410,8 +4412,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 *= sqrtf(font->matrix.eM11 * font->matrix.eM11 + font->matrix.eM12 * font->matrix.eM12); + scale_y = font->scale_y * sqrtf(font->matrix.eM21 * font->matrix.eM21 + font->matrix.eM22 * font->matrix.eM22);
#define SCALE_X(x) (x) = GDI_ROUND((x) * scale_x) #define SCALE_Y(y) (y) = GDI_ROUND((y) * scale_y) @@ -5838,7 +5840,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;