From: Piotr Caban piotr@codeweavers.com
--- dlls/wineps.drv/Makefile.in | 2 +- dlls/wineps.drv/builtin.c | 35 ---------------------- dlls/wineps.drv/init.c | 1 - dlls/wineps.drv/printproc.c | 13 -------- dlls/wineps.drv/psdrv.h | 1 - dlls/wineps.drv/unixlib.c | 59 +++++++++++++++++++++++++++++++++++++ 6 files changed, 60 insertions(+), 51 deletions(-)
diff --git a/dlls/wineps.drv/Makefile.in b/dlls/wineps.drv/Makefile.in index aa6bdf60996..97e75bf02b8 100644 --- a/dlls/wineps.drv/Makefile.in +++ b/dlls/wineps.drv/Makefile.in @@ -1,7 +1,7 @@ MODULE = wineps.drv UNIXLIB = wineps.so IMPORTS = user32 gdi32 winspool advapi32 win32u -UNIX_LIBS = -lwin32u +UNIX_LIBS = -lwin32u -lm
C_SRCS = \ afm.c \ diff --git a/dlls/wineps.drv/builtin.c b/dlls/wineps.drv/builtin.c index f661aeaa591..270ce1bef8a 100644 --- a/dlls/wineps.drv/builtin.c +++ b/dlls/wineps.drv/builtin.c @@ -339,38 +339,3 @@ BOOL CDECL PSDRV_GetTextExtentExPoint(PHYSDEV dev, LPCWSTR str, INT count, LPINT } return TRUE; } - -/*********************************************************************** - * PSDRV_GetCharWidth - */ -BOOL CDECL PSDRV_GetCharWidth(PHYSDEV dev, UINT first, UINT count, const WCHAR *chars, INT *buffer) -{ - PSDRV_PDEVICE *physDev = get_psdrv_dev( dev ); - UINT i, c; - - if (physDev->font.fontloc == Download) - { - dev = GET_NEXT_PHYSDEV( dev, pGetCharWidth ); - return dev->funcs->pGetCharWidth( dev, first, count, chars, buffer ); - } - - TRACE("U+%.4X +%u\n", first, count); - - for (i = 0; i < count; ++i) - { - c = chars ? chars[i] : first + i; - - if (c > 0xffff) - { - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; - } - - *buffer = floor( PSDRV_UVMetrics(c, physDev->font.fontinfo.Builtin.afm)->WX - * physDev->font.fontinfo.Builtin.scale + 0.5 ); - TRACE("U+%.4X: %i\n", i, *buffer); - ++buffer; - } - - return TRUE; -} diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c index 576021c6b1e..8c2c6d4af4b 100644 --- a/dlls/wineps.drv/init.c +++ b/dlls/wineps.drv/init.c @@ -693,7 +693,6 @@ static struct gdi_dc_funcs psdrv_funcs = .pCreateCompatibleDC = PSDRV_CreateCompatibleDC, .pCreateDC = PSDRV_CreateDC, .pDeleteDC = PSDRV_DeleteDC, - .pGetCharWidth = PSDRV_GetCharWidth, .pGetTextExtentExPoint = PSDRV_GetTextExtentExPoint, .pGetTextMetrics = PSDRV_GetTextMetrics, .priority = GDI_PRIORITY_GRAPHICS_DRV diff --git a/dlls/wineps.drv/printproc.c b/dlls/wineps.drv/printproc.c index bd4e79bb96f..417766d4093 100644 --- a/dlls/wineps.drv/printproc.c +++ b/dlls/wineps.drv/printproc.c @@ -155,18 +155,6 @@ static struct pp_data* get_handle_data(HANDLE pp) return ret; }
-static BOOL CDECL font_GetCharWidth(PHYSDEV dev, UINT first, UINT count, const WCHAR *chars, INT *buffer) -{ - XFORM old, xform = { .eM11 = 1.0f }; - BOOL ret; - - GetWorldTransform(dev->hdc, &old); - SetWorldTransform(dev->hdc, &xform); - ret = NtGdiGetCharWidthW(dev->hdc, first, count, (WCHAR *)chars, NTGDI_GETCHARWIDTH_INT, buffer); - SetWorldTransform(dev->hdc, &old); - return ret; -} - static BOOL CDECL font_GetTextExtentExPoint(PHYSDEV dev, const WCHAR *str, INT count, INT *dxs) { SIZE size; @@ -199,7 +187,6 @@ static HFONT CDECL font_SelectFont(PHYSDEV dev, HFONT hfont, UINT *aa_flags)
static const struct gdi_dc_funcs font_funcs = { - .pGetCharWidth = font_GetCharWidth, .pGetTextExtentExPoint = font_GetTextExtentExPoint, .pGetTextMetrics = font_GetTextMetrics, .pSelectFont = font_SelectFont, diff --git a/dlls/wineps.drv/psdrv.h b/dlls/wineps.drv/psdrv.h index add30651043..a1eb444ad14 100644 --- a/dlls/wineps.drv/psdrv.h +++ b/dlls/wineps.drv/psdrv.h @@ -434,7 +434,6 @@ extern INT CDECL PSDRV_ExtEscape( PHYSDEV dev, INT nEscape, INT cbInput, LPCVOID extern BOOL CDECL PSDRV_ExtTextOut( PHYSDEV dev, INT x, INT y, UINT flags, const RECT *lprect, LPCWSTR str, UINT count, const INT *lpDx ) DECLSPEC_HIDDEN; extern BOOL CDECL PSDRV_FillPath( PHYSDEV dev ) DECLSPEC_HIDDEN; -extern BOOL CDECL PSDRV_GetCharWidth(PHYSDEV dev, UINT first, UINT count, const WCHAR *chars, INT *buffer) DECLSPEC_HIDDEN; extern BOOL CDECL PSDRV_GetTextExtentExPoint(PHYSDEV dev, LPCWSTR str, INT count, LPINT alpDx) DECLSPEC_HIDDEN; extern BOOL CDECL PSDRV_GetTextMetrics(PHYSDEV dev, TEXTMETRICW *metrics) DECLSPEC_HIDDEN; extern BOOL CDECL PSDRV_LineTo(PHYSDEV dev, INT x, INT y) DECLSPEC_HIDDEN; diff --git a/dlls/wineps.drv/unixlib.c b/dlls/wineps.drv/unixlib.c index 1dd9aafadb0..283c5b8d4a7 100644 --- a/dlls/wineps.drv/unixlib.c +++ b/dlls/wineps.drv/unixlib.c @@ -25,6 +25,8 @@ #endif
#include <stdarg.h> +#include <stdlib.h> +#include <math.h>
#include "windef.h" #include "winbase.h" @@ -1133,6 +1135,62 @@ static BOOL CDECL enum_fonts(PHYSDEV dev, LPLOGFONTW plf, FONTENUMPROCW proc, LP return ret; }
+static int metrics_by_uv(const void *a, const void *b) +{ + return (int)(((const AFMMETRICS *)a)->UV - ((const AFMMETRICS *)b)->UV); +} + +const AFMMETRICS *uv_metrics(LONG uv, const AFM *afm) +{ + const AFMMETRICS *needle; + AFMMETRICS key; + + /* + * Ugly work-around for symbol fonts. Wine is sending characters which + * belong in the Unicode private use range (U+F020 - U+F0FF) as ASCII + * characters (U+0020 - U+00FF). + */ + if ((afm->Metrics->UV & 0xff00) == 0xf000 && uv < 0x100) + uv |= 0xf000; + + key.UV = uv; + needle = bsearch(&key, afm->Metrics, afm->NumofMetrics, sizeof(AFMMETRICS), metrics_by_uv); + if (!needle) + { + WARN("No glyph for U+%.4X in '%s'\n", (int)uv, afm->FontName); + needle = afm->Metrics; + } + return needle; +} + +static BOOL CDECL get_char_width(PHYSDEV dev, UINT first, UINT count, const WCHAR *chars, INT *buffer) +{ + PSDRV_PDEVICE *pdev = get_psdrv_dev(dev); + UINT i, c; + + if (pdev->font.fontloc == Download) + { + dev = GET_NEXT_PHYSDEV(dev, pGetCharWidth); + return dev->funcs->pGetCharWidth(dev, first, count, chars, buffer); + } + + TRACE("U+%.4X +%u\n", first, count); + + for (i = 0; i < count; ++i) + { + c = chars ? chars[i] : first + i; + + if (c > 0xffff) + return FALSE; + + *buffer = floor(uv_metrics(c, pdev->font.fontinfo.Builtin.afm)->WX + * pdev->font.fontinfo.Builtin.scale + 0.5); + TRACE("U+%.4X: %i\n", i, *buffer); + ++buffer; + } + return TRUE; +} + static NTSTATUS init_dc(void *arg) { struct init_dc_params *params = arg; @@ -1142,6 +1200,7 @@ static NTSTATUS init_dc(void *arg) params->funcs->pExtEscape = ext_escape; params->funcs->pSelectFont = select_font; params->funcs->pEnumFonts = enum_fonts; + params->funcs->pGetCharWidth = get_char_width; return TRUE; }