The real motivation for the patches is to stop using PRINTERINFO structure in unixlib. I was planning to move AFM handling to unixlib initially but it depends on string to float parsing.
From: Piotr Caban piotr@codeweavers.com
--- dlls/wineps.drv/builtin.c | 26 ++++++++++++++++++++++++-- dlls/wineps.drv/unixlib.c | 7 ++++--- dlls/wineps.drv/unixlib.h | 2 +- 3 files changed, 29 insertions(+), 6 deletions(-)
diff --git a/dlls/wineps.drv/builtin.c b/dlls/wineps.drv/builtin.c index 2a2c9106f12..d62d4fc134f 100644 --- a/dlls/wineps.drv/builtin.c +++ b/dlls/wineps.drv/builtin.c @@ -50,14 +50,36 @@ BOOL PSDRV_WriteSetBuiltinFont(print_ctx *ctx) font_info.escapement, FALSE); }
+static int __cdecl agl_by_uv(const void *a, const void *b) +{ + return (int)(((const UNICODEGLYPH *)a)->UV - ((const UNICODEGLYPH *)b)->UV); +} + +static const char *find_ag_name(WCHAR wch) +{ + UNICODEGLYPH key = { .UV = wch }; + UNICODEGLYPH *needle; + + needle = bsearch(&key, PSDRV_AGLbyUV, PSDRV_AGLbyUVSize, sizeof(key), agl_by_uv); + return needle ? needle->name->sz : NULL; +} + BOOL PSDRV_WriteBuiltinGlyphShow(print_ctx *ctx, LPCWSTR str, INT count) { - char name[32]; + const char *name; + WCHAR wch; int i;
for (i = 0; i < count; ++i) { - ExtEscape(ctx->hdc, PSDRV_GET_GLYPH_NAME, sizeof(str[i]), (const char *)&str[i], sizeof(name), name); + ExtEscape(ctx->hdc, PSDRV_CHECK_WCHAR, sizeof(str[i]), + (const char *)&str[i], sizeof(wch), (char *)&wch); + name = find_ag_name(wch); + if (!name) + { + ERR("can't find glyph name for %x\n", wch); + continue; + } PSDRV_WriteGlyphShow(ctx, name); }
diff --git a/dlls/wineps.drv/unixlib.c b/dlls/wineps.drv/unixlib.c index 792a2ad69d3..b67a1848270 100644 --- a/dlls/wineps.drv/unixlib.c +++ b/dlls/wineps.drv/unixlib.c @@ -839,13 +839,14 @@ static int CDECL ext_escape(PHYSDEV dev, int escape, int input_size, const void case CLIP_TO_PATH: return 1;
- case PSDRV_GET_GLYPH_NAME: + case PSDRV_CHECK_WCHAR: { PSDRV_PDEVICE *pdev = get_psdrv_dev(dev); WCHAR *uv = (WCHAR *)input; - const char *name = uv_metrics(*uv, pdev->afm)->N->sz; + WCHAR out = uv_metrics(*uv, pdev->afm)->UV;
- lstrcpynA(output, name, output_size); + if ((out & 0xff00) == 0xf000) out &= ~0xf000; + *(WCHAR *)output = out; return 1; }
diff --git a/dlls/wineps.drv/unixlib.h b/dlls/wineps.drv/unixlib.h index 931bc14c152..a3b1a233a4e 100644 --- a/dlls/wineps.drv/unixlib.h +++ b/dlls/wineps.drv/unixlib.h @@ -20,7 +20,7 @@ #include "wine/unixlib.h"
/* escapes */ -#define PSDRV_GET_GLYPH_NAME 0x10000 +#define PSDRV_CHECK_WCHAR 0x10000 #define PSDRV_GET_BUILTIN_FONT_INFO 0x10001
struct font_info
From: Piotr Caban piotr@codeweavers.com
--- dlls/wineps.drv/init.c | 16 ++++++++++++++-- dlls/wineps.drv/psdrv.h | 1 + dlls/wineps.drv/unixlib.h | 5 +++++ 3 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c index 0da75ac60c9..7c2b71b46dd 100644 --- a/dlls/wineps.drv/init.c +++ b/dlls/wineps.drv/init.c @@ -503,11 +503,12 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCWSTR name) WCHAR *ppd_filename = NULL; char *nameA = NULL; BOOL using_default_devmode = FALSE; - int i, len, input_slots, resolutions, page_sizes, font_subs, size; + int i, len, input_slots, resolutions, page_sizes, font_subs, installed_fonts, size; struct input_slot *dm_slot; struct resolution *dm_res; struct page_size *dm_page; struct font_sub *dm_sub; + struct installed_font *dm_font; INPUTSLOT *slot; RESOLUTION *res; PAGESIZE *page; @@ -551,11 +552,13 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCWSTR name) resolutions = list_count( &pi->ppd->Resolutions ); page_sizes = list_count( &pi->ppd->PageSizes ); font_subs = pi->FontSubTableSize; + installed_fonts = list_count( &pi->ppd->InstalledFonts ); size = FIELD_OFFSET(PSDRV_DEVMODE, data[ input_slots * sizeof(struct input_slot) + resolutions * sizeof(struct resolution) + page_sizes * sizeof(struct page_size) + - font_subs * sizeof(struct font_sub)]); + font_subs * sizeof(struct font_sub) + + installed_fonts * sizeof(struct installed_font)]);
pi->Devmode = get_devmode( hPrinter, name, &using_default_devmode, size ); if (!pi->Devmode) goto fail; @@ -590,6 +593,8 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCWSTR name) pi->Devmode->input_slots = input_slots; pi->Devmode->resolutions = resolutions; pi->Devmode->page_sizes = page_sizes; + pi->Devmode->font_subs = font_subs; + pi->Devmode->installed_fonts = installed_fonts;
dm_slot = (struct input_slot *)pi->Devmode->data; LIST_FOR_EACH_ENTRY( slot, &pi->ppd->InputSlots, INPUTSLOT, entry ) @@ -637,6 +642,13 @@ PRINTERINFO *PSDRV_FindPrinterInfo(LPCWSTR name) lstrcpynW(dm_sub->sub, (WCHAR *)pi->FontSubTable[i].pData, ARRAY_SIZE(dm_sub->sub)); dm_sub++; } + + dm_font = (struct installed_font *)dm_sub; + LIST_FOR_EACH_ENTRY( font, &pi->ppd->InstalledFonts, FONTNAME, entry ) + { + lstrcpynA(dm_font->name, font->Name, ARRAY_SIZE(dm_font->name)); + dm_font++; + } }
/* Duplex is indicated by the setting of the DM_DUPLEX bit in dmFields. diff --git a/dlls/wineps.drv/psdrv.h b/dlls/wineps.drv/psdrv.h index 29ce1e80d9d..1d6ff1c69dc 100644 --- a/dlls/wineps.drv/psdrv.h +++ b/dlls/wineps.drv/psdrv.h @@ -228,6 +228,7 @@ typedef struct { int resolutions; int page_sizes; int font_subs; + int installed_fonts; BYTE data[1]; } PSDRV_DEVMODE;
diff --git a/dlls/wineps.drv/unixlib.h b/dlls/wineps.drv/unixlib.h index a3b1a233a4e..9c56452585b 100644 --- a/dlls/wineps.drv/unixlib.h +++ b/dlls/wineps.drv/unixlib.h @@ -66,6 +66,11 @@ struct font_sub WCHAR sub[LF_FACESIZE]; };
+struct installed_font +{ + char name[LF_FACESIZE]; +}; + /* Unix calls */ enum wineps_funcs {
From: Piotr Caban piotr@codeweavers.com
--- include/Makefile.in | 1 + include/ddk/winddi.h | 100 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 101 insertions(+) create mode 100644 include/ddk/winddi.h
diff --git a/include/Makefile.in b/include/Makefile.in index 0dae4cab2bf..e9f0aa8d5fb 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -213,6 +213,7 @@ SOURCES = \ ddk/usbioctl.h \ ddk/usbiodef.h \ ddk/wdm.h \ + ddk/winddi.h \ ddk/winddiui.h \ ddk/winsplp.h \ ddk/wsk.h \ diff --git a/include/ddk/winddi.h b/include/ddk/winddi.h new file mode 100644 index 00000000000..8f3a38e0b84 --- /dev/null +++ b/include/ddk/winddi.h @@ -0,0 +1,100 @@ +/* + * Definitions for Graphics Device Drivers interface + * + * Copyright 2023 Piotr Caban + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#ifndef _WINDDI_ +#define _WINDDI_ + +typedef LONG PTRDIFF; +typedef SHORT FWORD; + +#define FM_SEL_ITALIC 0x1 +#define FM_SEL_UNDERSCORE 0x2 +#define FM_SEL_NEGATIVE 0x4 +#define FM_SEL_OUTLINED 0x8 +#define FM_SEL_STRIKEOUT 0x10 +#define FM_SEL_BOLD 0x20 +#define FM_SEL_REGULAR 0x40 + +typedef struct _IFIMETRICS { + ULONG cjThis; + ULONG cjIfiExtra; + PTRDIFF dpwszFamilyName; + PTRDIFF dpwszStyleName; + PTRDIFF dpwszFaceName; + PTRDIFF dpwszUniqueName; + PTRDIFF dpFontSim; + LONG lEmbedId; + LONG lItalicAngle; + LONG lCharBias; + PTRDIFF dpCharSets; + BYTE jWinCharSet; + BYTE jWinPitchAndFamily; + USHORT usWinWeight; + ULONG flInfo; + USHORT fsSelection; + USHORT fsType; + FWORD fwdUnitsPerEm; + FWORD fwdLowestPPEm; + FWORD fwdWinAscender; + FWORD fwdWinDescender; + FWORD fwdMacAscender; + FWORD fwdMacDescender; + FWORD fwdMacLineGap; + FWORD fwdTypoAscender; + FWORD fwdTypoDescender; + FWORD fwdTypoLineGap; + FWORD fwdAveCharWidth; + FWORD fwdMaxCharInc; + FWORD fwdCapHeight; + FWORD fwdXHeight; + FWORD fwdSubscriptXSize; + FWORD fwdSubscriptYSize; + FWORD fwdSubscriptXOffset; + FWORD fwdSubscriptYOffset; + FWORD fwdSuperscriptXSize; + FWORD fwdSuperscriptYSize; + FWORD fwdSuperscriptXOffset; + FWORD fwdSuperscriptYOffset; + FWORD fwdUnderscoreSize; + FWORD fwdUnderscorePosition; + FWORD fwdStrikeoutSize; + FWORD fwdStrikeoutPosition; + BYTE chFirstChar; + BYTE chLastChar; + BYTE chDefaultChar; + BYTE chBreakChar; + WCHAR wcFirstChar; + WCHAR wcLastChar; + WCHAR wcDefaultChar; + WCHAR wcBreakChar; + POINTL ptlBaseline; + POINTL ptlAspect; + POINTL ptlCaret; + RECTL rclFontBox; + BYTE achVendId[4]; + ULONG cKerningPairs; + ULONG ulPanoseCulture; + PANOSE panose; +#ifdef _WIN64 + PVOID Align; +#endif +} IFIMETRICS, *PIFIMETRICS; + +#endif /* _WINDDI_ */
From: Piotr Caban piotr@codeweavers.com
--- dlls/wineps.drv/init.c | 52 ++++ dlls/wineps.drv/ntf.h | 87 +++++++ dlls/wineps.drv/unixlib.c | 518 +++++++++++++++++++++++++++++++++++++- dlls/wineps.drv/unixlib.h | 7 + 4 files changed, 655 insertions(+), 9 deletions(-) create mode 100644 dlls/wineps.drv/ntf.h
diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c index 7c2b71b46dd..e1b6ffeb2cb 100644 --- a/dlls/wineps.drv/init.c +++ b/dlls/wineps.drv/init.c @@ -87,6 +87,51 @@ static const PSDRV_DEVMODE DefaultDevmode = HINSTANCE PSDRV_hInstance = 0; HANDLE PSDRV_Heap = 0;
+static BOOL import_ntf_from_reg(void) +{ + struct import_ntf_params params; + HANDLE hfile, hmap = NULL; + WCHAR path[MAX_PATH]; + LARGE_INTEGER size; + char *data = NULL; + LSTATUS status; + HKEY hkey; + DWORD len; + BOOL ret; + + if (RegOpenKeyW(HKEY_CURRENT_USER, L"Software\Wine\Fonts", &hkey)) + return TRUE; + status = RegQueryValueExW(hkey, L"NTFFile", NULL, NULL, (BYTE *)path, &len); + RegCloseKey(hkey); + if (status) + return TRUE; + + hfile = CreateFileW(path, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0); + if (hfile != INVALID_HANDLE_VALUE) + { + if (!GetFileSizeEx(hfile, &size)) + size.QuadPart = 0; + hmap = CreateFileMappingW(hfile, NULL, PAGE_READONLY, 0, 0, NULL); + CloseHandle(hfile); + } + if (hmap) + { + data = MapViewOfFile(hmap, FILE_MAP_READ, 0, 0, 0); + CloseHandle(hmap); + } + if (!data) + { + WARN("Error loading NTF file: %s\n", debugstr_w(path)); + return TRUE; + } + + params.data = data; + params.size = size.QuadPart; + ret = WINE_UNIX_CALL(unix_import_ntf, ¶ms); + UnmapViewOfFile(data); + return ret; +} + /********************************************************************* * DllMain * @@ -115,6 +160,13 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) HeapDestroy(PSDRV_Heap); return FALSE; } + + if (!import_ntf_from_reg()) + { + WINE_UNIX_CALL(unix_free_printer_info, NULL); + HeapDestroy(PSDRV_Heap); + return FALSE; + } break; }
diff --git a/dlls/wineps.drv/ntf.h b/dlls/wineps.drv/ntf.h new file mode 100644 index 00000000000..4431a72b527 --- /dev/null +++ b/dlls/wineps.drv/ntf.h @@ -0,0 +1,87 @@ +/* + * Copyright 2022 Piotr Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +struct ntf_header +{ + int signature; + int driver_type; + int version; + int unk[5]; + int glyph_set_count; + int glyph_set_off; + int font_mtx_count; + int font_mtx_off; +}; + +struct list_entry +{ + int name_off; + int hash; + int size; + int off; + int unk[4]; +}; + +#define GLYPH_SET_OMMIT_CP 1 +struct glyph_set +{ + int size; + int version; + int flags; + int name_off; + int glyph_count; + int run_count; + int run_off; + int cp_count; + int cp_off; + int glyph_set_off; + int unk[2]; +}; + +struct code_page +{ + int cp; + int win_char_set; + int name_off; + int unk[2]; +}; + +struct font_mtx +{ + int size; + int version; + int flags; + int name_off; + int display_off; + int font_version; + int glyph_set_name_off; + int glyph_count; + int metrics_off; + int unk; + int width_count; + int width_off; + int def_width; + /* TODO: there are more fields */ +}; + +struct width_range +{ + short first; + short count; + int width; +}; diff --git a/dlls/wineps.drv/unixlib.c b/dlls/wineps.drv/unixlib.c index b67a1848270..ccef38fe5b6 100644 --- a/dlls/wineps.drv/unixlib.c +++ b/dlls/wineps.drv/unixlib.c @@ -31,9 +31,11 @@ #include "windef.h" #include "winbase.h"
+#include "ntf.h" #include "psdrv.h" #include "unixlib.h" #include "ntgdi.h" +#include "ddk/winddi.h" #include "wine/gdi_driver.h" #include "wine/debug.h" #include "wine/wingdi16.h" @@ -51,6 +53,25 @@ static const WCHAR courier_newW[] = {'C','o','u','r','i','e','r',' ','N','e','w'
static const struct gdi_dc_funcs psdrv_funcs;
+struct glyph_info +{ + WCHAR wch; + int width; +}; + +struct font_data +{ + struct list entry; + + char *name; + IFIMETRICS *metrics; + int glyph_count; + struct glyph_info *glyphs; + struct glyph_info def_glyph; +}; + +static struct list fonts = LIST_INIT(fonts); + struct printer_info { struct list entry; @@ -58,7 +79,7 @@ struct printer_info PRINTERINFO *pi; };
-static struct list printer_info_list = LIST_INIT( printer_info_list ); +static struct list printer_info_list = LIST_INIT(printer_info_list);
typedef struct { @@ -70,6 +91,7 @@ typedef struct BOOL builtin; SIZE size; const AFM *afm; + const struct font_data *font; float scale; TEXTMETRICW tm; int escapement; @@ -558,6 +580,35 @@ static BOOL CDECL reset_dc(PHYSDEV dev, const DEVMODEW *devmode) return TRUE; }
+static int cmp_glyph_info(const void *a, const void *b) +{ + return (int)((const struct glyph_info *)a)->wch - + (int)((const struct glyph_info *)b)->wch; +} + +const struct glyph_info *uv_metrics_ntf(WCHAR wch, const struct font_data *font) +{ + const struct glyph_info *needle; + struct glyph_info 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 ((font->glyphs->wch & 0xff00) == 0xf000 && wch < 0x100) + wch |= 0xf000; + + key.wch = wch; + needle = bsearch(&key, font->glyphs, font->glyph_count, sizeof(*font->glyphs), cmp_glyph_info); + if (!needle) + { + WARN("No glyph for U+%.4X in '%s'\n", wch, font->name); + needle = font->glyphs; + } + return needle; +} + static int metrics_by_uv(const void *a, const void *b) { return (int)(((const AFMMETRICS *)a)->UV - ((const AFMMETRICS *)b)->UV); @@ -843,7 +894,7 @@ static int CDECL ext_escape(PHYSDEV dev, int escape, int input_size, const void { PSDRV_PDEVICE *pdev = get_psdrv_dev(dev); WCHAR *uv = (WCHAR *)input; - WCHAR out = uv_metrics(*uv, pdev->afm)->UV; + WCHAR out = pdev->font ? uv_metrics_ntf(*uv, pdev->font)->wch : uv_metrics(*uv, pdev->afm)->UV;
if ((out & 0xff00) == 0xf000) out &= ~0xf000; *(WCHAR *)output = out; @@ -858,7 +909,10 @@ static int CDECL ext_escape(PHYSDEV dev, int escape, int input_size, const void if (!pdev->builtin) return 0;
- lstrcpynA(font_info->font_name, pdev->afm->FontName, sizeof(font_info->font_name)); + if (pdev->font) + lstrcpynA(font_info->font_name, pdev->font->name, sizeof(font_info->font_name)); + else + lstrcpynA(font_info->font_name, pdev->afm->FontName, sizeof(font_info->font_name)); font_info->size = pdev->size; font_info->escapement = pdev->escapement; return 1; @@ -875,6 +929,89 @@ static inline float gdi_round(float f) return f > 0 ? f + 0.5 : f - 0.5; }
+static void scale_font_ntf(PSDRV_PDEVICE *pdev, const struct font_data *font, LONG height, TEXTMETRICW *tm) +{ + SHORT ascender, descender, line_gap, avg_char_width; + USHORT units_per_em, win_ascent, win_descent; + const IFIMETRICS *m = font->metrics; + float scale; + SIZE size; + + TRACE("'%s' %i\n", font->name, (int)height); + + if (height < 0) /* match em height */ + scale = -(height / (float)m->fwdUnitsPerEm); + else /* match cell height */ + scale = height / (float)(m->fwdWinAscender + m->fwdWinDescender); + + size.cx = (INT)gdi_round(scale * (float)m->fwdUnitsPerEm); + size.cy = -(INT)gdi_round(scale * (float)m->fwdUnitsPerEm); + + units_per_em = (USHORT)gdi_round((float)m->fwdUnitsPerEm * scale); + ascender = (SHORT)gdi_round((float)m->fwdMacAscender * scale); + descender = (SHORT)gdi_round((float)m->fwdMacDescender * scale); + line_gap = (SHORT)gdi_round((float)m->fwdMacLineGap * scale); + win_ascent = (USHORT)gdi_round((float)m->fwdWinAscender * scale); + win_descent = (USHORT)gdi_round((float)m->fwdWinDescender * scale); + avg_char_width = (SHORT)gdi_round((float)m->fwdAveCharWidth * scale); + + tm->tmAscent = (LONG)win_ascent; + tm->tmDescent = (LONG)win_descent; + tm->tmHeight = tm->tmAscent + tm->tmDescent; + + tm->tmInternalLeading = tm->tmHeight - (LONG)units_per_em; + if (tm->tmInternalLeading < 0) + tm->tmInternalLeading = 0; + + tm->tmExternalLeading = + (LONG)(ascender - descender + line_gap) - tm->tmHeight; + if (tm->tmExternalLeading < 0) + tm->tmExternalLeading = 0; + + tm->tmAveCharWidth = (LONG)avg_char_width; + + tm->tmWeight = m->usWinWeight; + tm->tmItalic = !!(m->fsSelection & FM_SEL_ITALIC); + tm->tmUnderlined = !!(m->fsSelection & FM_SEL_UNDERSCORE); + tm->tmStruckOut = !!(m->fsSelection & FM_SEL_STRIKEOUT); + tm->tmFirstChar = font->glyphs[0].wch; + tm->tmLastChar = font->glyphs[font->glyph_count - 1].wch; + tm->tmDefaultChar = 0x001f; /* Win2K does this - FIXME? */ + tm->tmBreakChar = tm->tmFirstChar; /* should be 'space' */ + + tm->tmPitchAndFamily = TMPF_DEVICE | TMPF_VECTOR; + if (!(m->jWinPitchAndFamily & FIXED_PITCH)) + tm->tmPitchAndFamily |= TMPF_FIXED_PITCH; /* yes, it's backwards */ + if (m->fwdUnitsPerEm != 1000) + tm->tmPitchAndFamily |= TMPF_TRUETYPE; + + tm->tmCharSet = ANSI_CHARSET; /* FIXME */ + tm->tmOverhang = 0; + + /* + * This is kludgy. font->scale is used in several places in the driver + * to adjust PostScript-style metrics. Since these metrics have been + * "normalized" to an em-square size of 1000, font->scale needs to be + * similarly adjusted.. + */ + + scale *= (float)m->fwdUnitsPerEm / 1000.0; + + tm->tmMaxCharWidth = (LONG)gdi_round((m->rclFontBox.right - m->rclFontBox.left) * scale); + + if (pdev) + { + pdev->scale = scale; + pdev->size = size; + } + + TRACE("Selected PS font '%s' size %d weight %d.\n", font->name, + (int)size.cx, (int)tm->tmWeight); + TRACE("H = %d As = %d Des = %d IL = %d EL = %d\n", (int)tm->tmHeight, + (int)tm->tmAscent, (int)tm->tmDescent, (int)tm->tmInternalLeading, + (int)tm->tmExternalLeading); +} + static void scale_font(PSDRV_PDEVICE *pdev, const AFM *afm, LONG height, TEXTMETRICW *tm) { const WINMETRICS *wm = &(afm->WinMetrics); @@ -968,14 +1105,130 @@ static inline BOOL is_stock_font(HFONT font) return FALSE; }
-static BOOL select_builtin_font(PHYSDEV dev, HFONT hfont, LOGFONTW *plf) +static struct font_data *find_font_data(const char *name) +{ + struct font_data *font; + + LIST_FOR_EACH_ENTRY(font, &fonts, struct font_data, entry) + { + if (!strcmp(font->name, name)) + return font; + } + return NULL; +} + +static struct font_data *find_builtin_font(PSDRV_PDEVICE *pdev, + const WCHAR *facename, BOOL it, BOOL bd) +{ + PSDRV_DEVMODE *devmode = pdev->devmode; + struct installed_font *installed_font; + BOOL best_it, best_bd, cur_it, cur_bd; + struct font_data *best = NULL, *cur; + const WCHAR *name; + int i; + + installed_font = (struct installed_font *)(devmode->data + + devmode->input_slots * sizeof(struct input_slot) + + devmode->resolutions * sizeof(struct resolution) + + devmode->page_sizes * sizeof(struct page_size) + + devmode->font_subs * sizeof(struct font_sub)); + for (i = 0; i < devmode->installed_fonts; i++) + { + cur = find_font_data(installed_font[i].name); + if (!cur) continue; + + name = (WCHAR *)((char *)cur->metrics + cur->metrics->dpwszFaceName); + cur_it = !!(cur->metrics->fsSelection & FM_SEL_ITALIC); + cur_bd = !!(cur->metrics->fsSelection & FM_SEL_BOLD); + + if (!facename && it == cur_it && bd == cur_bd) + return cur; + if (facename && !wcscmp(facename, name) && it == cur_it && bd == cur_bd) + return cur; + if (facename && wcscmp(facename, name)) + continue; + + if (!best || (best_it != it && cur_it == it) || + (best_it != it && best_bd != bd && cur_bd == bd)) + { + best = cur; + best_it = cur_it; + best_bd = cur_bd; + } + } + + return best; +} + +static BOOL select_builtin_font_ntf(PSDRV_PDEVICE *pdev, HFONT hfont, LOGFONTW *plf) +{ + struct font_data *font_data; + BOOL bd = FALSE, it = FALSE; + LONG height; + + TRACE("Trying to find facename %s\n", debugstr_w(plf->lfFaceName)); + + if (plf->lfItalic) + it = TRUE; + if (plf->lfWeight > 550) + bd = TRUE; + + /* Look for a matching font family */ + font_data = find_builtin_font(pdev, plf->lfFaceName, it, bd); + if (!font_data) + { + /* Fallback for Window's font families to common PostScript families */ + if (!wcscmp(plf->lfFaceName, arialW)) + wcscpy(plf->lfFaceName, helveticaW); + else if (!wcscmp(plf->lfFaceName, systemW)) + wcscpy(plf->lfFaceName, helveticaW); + else if (!wcscmp(plf->lfFaceName, times_new_romanW)) + wcscpy(plf->lfFaceName, timesW); + else if (!wcscmp(plf->lfFaceName, courier_newW)) + wcscpy(plf->lfFaceName, courierW); + + font_data = find_builtin_font(pdev, plf->lfFaceName, it, bd); + } + /* If all else fails, use the first font defined for the printer */ + if (!font_data) + font_data = find_builtin_font(pdev, NULL, it, bd); + + TRACE("Got family %s font '%s'\n", debugstr_w((WCHAR *)((char *)font_data->metrics + + font_data->metrics->dpwszFaceName)), font_data->name); + + pdev->builtin = TRUE; + pdev->font = NULL; + pdev->afm = NULL; + pdev->font = font_data; + + height = plf->lfHeight; + /* stock fonts ignore the mapping mode */ + if (!is_stock_font(hfont)) + { + POINT pts[2]; + pts[0].x = pts[0].y = pts[1].x = 0; + pts[1].y = height; + NtGdiTransformPoints(pdev->dev.hdc, pts, pts, 2, NtGdiLPtoDP); + height = pts[1].y - pts[0].y; + } + scale_font_ntf(pdev, font_data, height, &pdev->tm); + + /* Does anyone know if these are supposed to be reversed like this? */ + pdev->tm.tmDigitizedAspectX = pdev->log_pixels_y; + pdev->tm.tmDigitizedAspectY = pdev->log_pixels_x; + return TRUE; +} + +static BOOL select_builtin_font(PSDRV_PDEVICE *pdev, HFONT hfont, LOGFONTW *plf) { - PSDRV_PDEVICE *pdev = get_psdrv_dev(dev); AFMLISTENTRY *afmle; FONTFAMILY *family; BOOL bd = FALSE, it = FALSE; LONG height;
+ if (select_builtin_font_ntf(pdev, hfont, plf)) + return TRUE; + TRACE("Trying to find facename %s\n", debugstr_w(plf->lfFaceName));
/* Look for a matching font family */ @@ -1027,6 +1280,7 @@ static BOOL select_builtin_font(PHYSDEV dev, HFONT hfont, LOGFONTW *plf)
pdev->builtin = TRUE; pdev->afm = afmle->afm; + pdev->font = NULL;
height = plf->lfHeight; /* stock fonts ignore the mapping mode */ @@ -1035,7 +1289,7 @@ static BOOL select_builtin_font(PHYSDEV dev, HFONT hfont, LOGFONTW *plf) POINT pts[2]; pts[0].x = pts[0].y = pts[1].x = 0; pts[1].y = height; - NtGdiTransformPoints(dev->hdc, pts, pts, 2, NtGdiLPtoDP); + NtGdiTransformPoints(pdev->dev.hdc, pts, pts, 2, NtGdiLPtoDP); height = pts[1].y - pts[0].y; } scale_font(pdev, pdev->afm, height, &pdev->tm); @@ -1132,7 +1386,7 @@ static HFONT CDECL select_font(PHYSDEV dev, HFONT hfont, UINT *aa_flags) return ret; }
- select_builtin_font(dev, hfont, &lf); + select_builtin_font(pdev, hfont, &lf); next->funcs->pSelectFont(next, 0, aa_flags); /* tell next driver that we selected a device font */ return hfont; } @@ -1232,7 +1486,8 @@ static BOOL CDECL get_char_width(PHYSDEV dev, UINT first, UINT count, const WCHA if (c > 0xffff) return FALSE;
- *buffer = floor(uv_metrics(c, pdev->afm)->WX * pdev->scale + 0.5); + *buffer = floor((pdev->font ? uv_metrics_ntf(c, pdev->font)->width : + uv_metrics(c, pdev->afm)->WX) * pdev->scale + 0.5); TRACE("U+%.4X: %i\n", i, *buffer); ++buffer; } @@ -1269,7 +1524,8 @@ static BOOL CDECL get_text_extent_ex_point(PHYSDEV dev, const WCHAR *str, int co
for (i = 0; i < count; ++i) { - width += uv_metrics(str[i], pdev->afm)->WX; + width += pdev->font ? uv_metrics_ntf(str[i], pdev->font)->width : + uv_metrics(str[i], pdev->afm)->WX; dx[i] = width * pdev->scale; } return TRUE; @@ -1384,6 +1640,243 @@ static const struct gdi_dc_funcs psdrv_funcs = .priority = GDI_PRIORITY_GRAPHICS_DRV };
+static BOOL check_ntf_str(const char *data, UINT64 size, const char *str) +{ + if (str < data || str >= data + size) + return FALSE; + size -= str - data; + while (*str && size) + { + size--; + str++; + } + return size != 0; +} + +static void free_font_data(struct font_data *font_data) +{ + free(font_data->name); + free(font_data->metrics); + free(font_data->glyphs); + free(font_data); +} + +static WCHAR convert_ntf_cp(unsigned short c, unsigned short cp) +{ + static const WCHAR map_fff1[256] = { + 0x0000, 0x02d8, 0x02c7, 0x02d9, 0x0131, 0xfb01, 0xfb02, 0x2044, + 0x02dd, 0x0141, 0x0142, 0x2212, 0x02db, 0x02da, 0x017d, 0x017e, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, + 0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, + 0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, + 0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, + 0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x0000, + 0x20ac, 0x0000, 0x201a, 0x0192, 0x201e, 0x2026, 0x2020, 0x2021, + 0x02c6, 0x2030, 0x0160, 0x2039, 0x0152, 0x0000, 0x0000, 0x0000, + 0x0000, 0x2018, 0x2019, 0x201c, 0x201d, 0x2022, 0x2013, 0x2014, + 0x02dc, 0x2122, 0x0161, 0x203a, 0x0153, 0x0000, 0x0000, 0x0178, + 0x0000, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7, + 0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x0000, 0x00ae, 0x00af, + 0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7, + 0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf, + 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, + 0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, + 0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7, + 0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df, + 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7, + 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef, + 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7, + 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff, + }; + WCHAR ret = 0; + + switch (cp) + { + case 0xfff1: + ret = c < ARRAY_SIZE(map_fff1) ? map_fff1[c] : 0; + break; + } + + if (!ret && c) + FIXME("unrecognized character %x in %x\n", c, cp); + return ret; +} + +static BOOL map_glyph_to_unicode(struct font_data *font_data, + const char *data, UINT64 size, const char *name) +{ + const struct ntf_header *header = (const struct ntf_header *)data; + const struct list_entry *list_elem; + const struct glyph_set *glyph_set; + const unsigned short *p; + int i, j; + + list_elem = (const struct list_entry *)(data + header->glyph_set_off); + for (i = 0; i < header->glyph_set_count; i++) + { + if (!check_ntf_str(data, size, data + list_elem->name_off)) + return FALSE; + if (strcmp(data + list_elem->name_off, name)) + { + list_elem++; + continue; + } + if (list_elem->off + list_elem->size > size) + return FALSE; + + glyph_set = (const struct glyph_set *)(data + list_elem->off); + if (font_data->glyph_count > glyph_set->glyph_count) + return FALSE; + + p = (const unsigned short *)((const char *)glyph_set + glyph_set->glyph_set_off); + if (glyph_set->flags & GLYPH_SET_OMMIT_CP) + { + const struct code_page *code_page = (const struct code_page *)((const char *)glyph_set + glyph_set->cp_off); + unsigned short def_cp; + + if (glyph_set->cp_off + sizeof(*code_page) * glyph_set->cp_count > list_elem->size) + return FALSE; + if (glyph_set->cp_count != 1) + return FALSE; + if (glyph_set->glyph_set_off + sizeof(short) * font_data->glyph_count > list_elem->size) + return FALSE; + + def_cp = code_page->cp; + for (j = 0; j < font_data->glyph_count; j++) + { + font_data->glyphs[j].wch = convert_ntf_cp(p[0], def_cp); + p++; + } + } + else + { + if (glyph_set->glyph_set_off + sizeof(short[2]) * font_data->glyph_count > list_elem->size) + return FALSE; + + for (j = 0; j < font_data->glyph_count; j++) + { + font_data->glyphs[j].wch = convert_ntf_cp(p[0], p[1]); + p += 2; + } + } + return TRUE; + } + + return FALSE; +} + +static BOOL add_ntf_fonts(const char *data, int size) +{ + const struct ntf_header *header = (const struct ntf_header *)data; + const struct width_range *width_range; + const struct list_entry *list_elem; + const struct font_mtx *font_mtx; + struct font_data *font_data; + const IFIMETRICS *metrics; + const char *name; + int i, j, k; + + if (size < sizeof(*header) || + size < header->glyph_set_off + header->glyph_set_count * sizeof(*list_elem) || + size < header->font_mtx_off + header->font_mtx_count * sizeof(*list_elem)) + return FALSE; + + list_elem = (const struct list_entry *)(data + header->font_mtx_off); + for (i = 0; i < header->font_mtx_count; i++) + { + name = data + list_elem->name_off; + if (!check_ntf_str(data, size, name)) + return FALSE; + TRACE("adding %s font\n", name); + + if (list_elem->size + list_elem->off > size) + return FALSE; + font_mtx = (const struct font_mtx *)(data + list_elem->off); + if (list_elem->off + font_mtx->metrics_off + FIELD_OFFSET(IFIMETRICS, panose) > size) + return FALSE; + metrics = (const IFIMETRICS *)((const char *)font_mtx + font_mtx->metrics_off); + if (list_elem->off + font_mtx->metrics_off + metrics->cjThis > size) + return FALSE; + if (list_elem->off + font_mtx->width_off + sizeof(*width_range) * font_mtx->width_count > size) + return FALSE; + width_range = (const struct width_range *)((const char *)font_mtx + font_mtx->width_off); + if (!check_ntf_str(data, size, (const char *)font_mtx + font_mtx->glyph_set_name_off)) + return FALSE; + + if (!font_mtx->glyph_count) + { + list_elem++; + continue; + } + + font_data = calloc(sizeof(*font_data), 1); + if (!font_data) + return FALSE; + + font_data->glyph_count = font_mtx->glyph_count; + font_data->name = malloc(strlen(name) + 1); + font_data->metrics = malloc(metrics->cjThis); + font_data->glyphs = malloc(sizeof(*font_data->glyphs) * font_data->glyph_count); + if (!font_data->name || !font_data->metrics || !font_data->glyphs) + { + free_font_data(font_data); + return FALSE; + } + memcpy(font_data->name, name, strlen(name) + 1); + memcpy(font_data->metrics, metrics, metrics->cjThis); + + for (j = 0; j < font_mtx->glyph_count; j++) + font_data->glyphs[j].width = font_mtx->def_width; + for (j = 0; j < font_mtx->width_count; j++) + { + /* Use default width */ + if (width_range[j].width == 0x80000008) + continue; + + for (k = 0; k < width_range[j].count; k++) + { + if (width_range[j].first + k >= font_data->glyph_count) + break; + font_data->glyphs[width_range[j].first + k].width = width_range[j].width; + } + } + + if (!map_glyph_to_unicode(font_data, data, size, + (const char *)font_mtx + font_mtx->glyph_set_name_off)) + { + free_font_data(font_data); + WARN("error loading %s font\n", name); + list_elem++; + continue; + } + font_data->def_glyph = font_data->glyphs[0]; + + qsort(font_data->glyphs, font_data->glyph_count, + sizeof(*font_data->glyphs), cmp_glyph_info); + list_add_head(&fonts, &font_data->entry); + list_elem++; + TRACE("%s font added\n", name); + } + + return TRUE; +} + +static NTSTATUS import_ntf(void *arg) +{ + struct import_ntf_params *params = arg; + + return add_ntf_fonts(params->data, params->size); +} + static NTSTATUS init_dc(void *arg) { struct init_dc_params *params = arg; @@ -1406,17 +1899,24 @@ static NTSTATUS init_dc(void *arg)
static NTSTATUS free_printer_info(void *arg) { + struct font_data *font, *font_next; struct printer_info *pi, *next;
LIST_FOR_EACH_ENTRY_SAFE(pi, next, &printer_info_list, struct printer_info, entry) { free(pi); } + + LIST_FOR_EACH_ENTRY_SAFE(font, font_next, &fonts, struct font_data, entry) + { + free_font_data(font); + } return 0; }
const unixlib_entry_t __wine_unix_call_funcs[] = { + import_ntf, init_dc, free_printer_info, }; diff --git a/dlls/wineps.drv/unixlib.h b/dlls/wineps.drv/unixlib.h index 9c56452585b..67fe0287169 100644 --- a/dlls/wineps.drv/unixlib.h +++ b/dlls/wineps.drv/unixlib.h @@ -74,11 +74,18 @@ struct installed_font /* Unix calls */ enum wineps_funcs { + unix_import_ntf, unix_init_dc, unix_free_printer_info, unix_funcs_count, };
+struct import_ntf_params +{ + const char *data; + int size; +}; + struct init_dc_params { const struct gdi_dc_funcs *funcs;
From: Piotr Caban piotr@codeweavers.com
--- dlls/wineps.drv/unixlib.c | 70 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 65 insertions(+), 5 deletions(-)
diff --git a/dlls/wineps.drv/unixlib.c b/dlls/wineps.drv/unixlib.c index ccef38fe5b6..766d5e8fe80 100644 --- a/dlls/wineps.drv/unixlib.c +++ b/dlls/wineps.drv/unixlib.c @@ -1391,6 +1391,30 @@ static HFONT CDECL select_font(PHYSDEV dev, HFONT hfont, UINT *aa_flags) return hfont; }
+static UINT get_font_metric_ntf(const struct font_data *font, + NEWTEXTMETRICEXW *ntmx, ENUMLOGFONTEXW *elfx) +{ + /* ntmx->ntmTm is NEWTEXTMETRICW; compatible w/ TEXTMETRICW per Win32 doc */ + TEXTMETRICW *tm = (TEXTMETRICW *)&(ntmx->ntmTm); + LOGFONTW *lf = &(elfx->elfLogFont); + + memset(ntmx, 0, sizeof(*ntmx)); + memset(elfx, 0, sizeof(*elfx)); + + scale_font_ntf(NULL, font, -(LONG)font->metrics->fwdUnitsPerEm, tm); + + lf->lfHeight = tm->tmHeight; + lf->lfWidth = tm->tmAveCharWidth; + lf->lfWeight = tm->tmWeight; + lf->lfItalic = tm->tmItalic; + lf->lfCharSet = tm->tmCharSet; + + lf->lfPitchAndFamily = font->metrics->jWinPitchAndFamily & FIXED_PITCH ? FIXED_PITCH : VARIABLE_PITCH; + + lstrcpynW(lf->lfFaceName, (WCHAR *)((char *)font->metrics + font->metrics->dpwszFaceName), LF_FACESIZE); + return DEVICE_FONTTYPE; +} + static UINT get_font_metric(const AFM *afm, NEWTEXTMETRICEXW *ntmx, ENUMLOGFONTEXW *elfx) { /* ntmx->ntmTm is NEWTEXTMETRICW; compatible w/ TEXTMETRICW per Win32 doc */ @@ -1418,18 +1442,45 @@ static BOOL CDECL enum_fonts(PHYSDEV dev, LPLOGFONTW plf, FONTENUMPROCW proc, LP { PSDRV_PDEVICE *pdev = get_psdrv_dev(dev); PHYSDEV next = GET_NEXT_PHYSDEV(dev, pEnumFonts); + PSDRV_DEVMODE *devmode = pdev->devmode; + struct installed_font *installed_font; + struct font_data *cur; ENUMLOGFONTEXW lf; NEWTEXTMETRICEXW tm; - BOOL ret; AFMLISTENTRY *afmle; FONTFAMILY *family; + const WCHAR *name; + BOOL ret; + UINT fm; + int i;
ret = next->funcs->pEnumFonts(next, plf, proc, lp); if (!ret) return FALSE;
+ installed_font = (struct installed_font *)(devmode->data + + devmode->input_slots * sizeof(struct input_slot) + + devmode->resolutions * sizeof(struct resolution) + + devmode->page_sizes * sizeof(struct page_size) + + devmode->font_subs * sizeof(struct font_sub)); if (plf && plf->lfFaceName[0]) { TRACE("lfFaceName = %s\n", debugstr_w(plf->lfFaceName)); + + for (i = 0; i < devmode->installed_fonts; i++) + { + cur = find_font_data(installed_font[i].name); + if (!cur) continue; + + name = (WCHAR *)((char *)cur->metrics + cur->metrics->dpwszFaceName); + if (wcsncmp(plf->lfFaceName, name, wcslen(name))) + continue; + + TRACE("Got '%s'\n", cur->name); + fm = get_font_metric_ntf(cur, &tm, &lf); + if (!(ret = (*proc)(&lf.elfLogFont, (TEXTMETRICW *)&tm, fm, lp))) + return ret; + } + for (family = pdev->pi->pi->Fonts; family; family = family->next) { if (!wcsncmp(plf->lfFaceName, family->FamilyName, @@ -1440,8 +1491,6 @@ static BOOL CDECL enum_fonts(PHYSDEV dev, LPLOGFONTW plf, FONTENUMPROCW proc, LP { for (afmle = family->afmlist; afmle; afmle = afmle->next) { - UINT fm; - TRACE("Got '%s'\n", afmle->afm->FontName); fm = get_font_metric(afmle->afm, &tm, &lf); if (!(ret = (*proc)(&lf.elfLogFont, (TEXTMETRICW *)&tm, fm, lp))) @@ -1452,10 +1501,21 @@ static BOOL CDECL enum_fonts(PHYSDEV dev, LPLOGFONTW plf, FONTENUMPROCW proc, LP else { TRACE("lfFaceName = NULL\n"); - for (family = pdev->pi->pi->Fonts; family; family = family->next) + + for (i = 0; i < devmode->installed_fonts; i++) { - UINT fm; + cur = find_font_data(installed_font[i].name); + if (!cur) continue;
+ name = (WCHAR *)((char *)cur->metrics + cur->metrics->dpwszFaceName); + TRACE("Got '%s'\n", cur->name); + fm = get_font_metric_ntf(cur, &tm, &lf); + if (!(ret = (*proc)(&lf.elfLogFont, (TEXTMETRICW *)&tm, fm, lp))) + return ret; + } + + for (family = pdev->pi->pi->Fonts; family; family = family->next) + { afmle = family->afmlist; TRACE("Got '%s'\n", afmle->afm->FontName); fm = get_font_metric(afmle->afm, &tm, &lf);
From: Piotr Caban piotr@codeweavers.com
--- dlls/wineps.drv/init.c | 146 +++++++++++++++++++++++++++++++++++++- dlls/wineps.drv/unixlib.c | 3 + 2 files changed, 148 insertions(+), 1 deletion(-)
diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c index e1b6ffeb2cb..73e95b116ba 100644 --- a/dlls/wineps.drv/init.c +++ b/dlls/wineps.drv/init.c @@ -29,6 +29,8 @@ #include "winnls.h" #include "winuser.h" #include "psdrv.h" +#include "ddk/winddi.h" +#include "ntf.h" #include "unixlib.h" #include "winspool.h" #include "wine/debug.h" @@ -132,6 +134,148 @@ static BOOL import_ntf_from_reg(void) return ret; }
+static BOOL convert_afm_to_ntf(void) +{ + int i, count, size, off, metrics_size; + struct import_ntf_params params; + struct width_range *width_range; + struct glyph_set *glyph_set; + struct ntf_header *header; + struct font_mtx *font_mtx; + struct list_entry *list; + struct code_page *cp; + char glyph_set_name[9]; + char *data, *new_data; + AFMLISTENTRY *afmle; + IFIMETRICS *metrics; + FONTFAMILY *family; + + count = 0; + for (family = PSDRV_AFMFontList; family; family = family->next) + { + for(afmle = family->afmlist; afmle; afmle = afmle->next) + count++; + } + size = sizeof(*header) + sizeof(*list) * count * 2; + data = calloc(size, 1); + + if (!data) + return FALSE; + header = (void *)data; + header->glyph_set_count = count; + header->glyph_set_off = sizeof(*header); + header->font_mtx_count = count; + header->font_mtx_off = header->glyph_set_off + sizeof(*list) * count; + + count = 0; + off = size; + for (family = PSDRV_AFMFontList; family; family = family->next) + { + for(afmle = family->afmlist; afmle; afmle = afmle->next) + { + sprintf(glyph_set_name, "%x", count); + + list = (void *)(data + header->glyph_set_off + sizeof(*list) * count); + list->name_off = off + sizeof(*glyph_set); + list->size = sizeof(*glyph_set) + strlen(glyph_set_name) + 1 + sizeof(*cp) + + sizeof(short) * afmle->afm->NumofMetrics; + list->off = off; + size += list->size; + new_data = realloc(data, size); + if (!new_data) + { + free(data); + return FALSE; + } + data = new_data; + header = (void *)data; + memset(data + off, 0, size - off); + + glyph_set = (void *)(data + off); + glyph_set->size = size - off; + glyph_set->flags = 1; + glyph_set->name_off = sizeof(*glyph_set); + glyph_set->glyph_count = afmle->afm->NumofMetrics; + glyph_set->cp_count = 1; + glyph_set->cp_off = glyph_set->name_off + strlen(glyph_set_name) + 1; + glyph_set->glyph_set_off = glyph_set->cp_off + sizeof(*cp); + strcpy(data + off + glyph_set->name_off, glyph_set_name); + cp = (void *)(data + off + glyph_set->cp_off); + cp->cp = 0xffff; + for (i = 0; i < afmle->afm->NumofMetrics; i++) + *(WCHAR*)(data + off + glyph_set->glyph_set_off + i * sizeof(short)) = afmle->afm->Metrics[i].UV; + off = size; + + metrics_size = sizeof(IFIMETRICS) + + (wcslen(afmle->afm->FullName) + 1) * sizeof(WCHAR); + list = (void *)(data + header->font_mtx_off + sizeof(*list) * count); + list->name_off = off + sizeof(*font_mtx); + list->size = sizeof(*font_mtx) + strlen(afmle->afm->FontName) + 1 + + strlen(glyph_set_name) + 1 + metrics_size + + (afmle->afm->IsFixedPitch ? 0 : sizeof(*width_range) * afmle->afm->NumofMetrics); + list->off = off; + size += list->size; + new_data = realloc(data, size); + if (!new_data) + { + free(data); + return FALSE; + } + data = new_data; + header = (void *)data; + memset(data + off, 0, size - off); + + font_mtx = (void *)(data + off); + font_mtx->size = size - off; + font_mtx->name_off = sizeof(*font_mtx); + font_mtx->glyph_set_name_off = font_mtx->name_off + strlen(afmle->afm->FontName) + 1; + font_mtx->glyph_count = afmle->afm->NumofMetrics; + font_mtx->metrics_off = font_mtx->glyph_set_name_off + strlen(glyph_set_name) + 1; + font_mtx->width_count = afmle->afm->IsFixedPitch ? 0 : afmle->afm->NumofMetrics; + font_mtx->width_off = font_mtx->metrics_off + metrics_size; + font_mtx->def_width = afmle->afm->Metrics[0].WX; + strcpy(data + off + font_mtx->name_off, afmle->afm->FontName); + strcpy(data + off + font_mtx->glyph_set_name_off, glyph_set_name); + metrics = (void *)(data + off + font_mtx->metrics_off); + metrics->cjThis = metrics_size; + metrics->dpwszFaceName = sizeof(*metrics); + if (afmle->afm->IsFixedPitch) + metrics->jWinPitchAndFamily |= FIXED_PITCH; + metrics->usWinWeight = afmle->afm->Weight; + if (afmle->afm->ItalicAngle != 0.0) + metrics->fsSelection |= FM_SEL_ITALIC; + if (afmle->afm->Weight == FW_BOLD) + metrics->fsSelection |= FM_SEL_BOLD; + metrics->fwdUnitsPerEm = afmle->afm->WinMetrics.usUnitsPerEm; + metrics->fwdWinAscender = afmle->afm->WinMetrics.usWinAscent; + metrics->fwdWinDescender = afmle->afm->WinMetrics.usWinDescent; + metrics->fwdMacAscender = afmle->afm->WinMetrics.sAscender; + metrics->fwdMacDescender = afmle->afm->WinMetrics.sDescender; + metrics->fwdMacLineGap = afmle->afm->WinMetrics.sLineGap; + metrics->fwdAveCharWidth = afmle->afm->WinMetrics.sAvgCharWidth; + metrics->rclFontBox.left = afmle->afm->FontBBox.llx; + metrics->rclFontBox.top = afmle->afm->FontBBox.ury; + metrics->rclFontBox.right = afmle->afm->FontBBox.urx; + metrics->rclFontBox.bottom = afmle->afm->FontBBox.lly; + wcscpy((WCHAR *)((char *)metrics + metrics->dpwszFaceName), afmle->afm->FullName); + width_range = (void *)(data + off + font_mtx->width_off); + for (i = 0; i < font_mtx->width_count; i++) + { + width_range[i].first = i; + width_range[i].count = 1; + width_range[i].width = afmle->afm->Metrics[i].WX; + } + off = size; + + count++; + } + } + + params.data = data; + params.size = size; + return WINE_UNIX_CALL(unix_import_ntf, ¶ms); +} + /********************************************************************* * DllMain * @@ -161,7 +305,7 @@ BOOL WINAPI DllMain( HINSTANCE hinst, DWORD reason, LPVOID reserved ) return FALSE; }
- if (!import_ntf_from_reg()) + if (!convert_afm_to_ntf() || !import_ntf_from_reg()) { WINE_UNIX_CALL(unix_free_printer_info, NULL); HeapDestroy(PSDRV_Heap); diff --git a/dlls/wineps.drv/unixlib.c b/dlls/wineps.drv/unixlib.c index 766d5e8fe80..d7d545097f8 100644 --- a/dlls/wineps.drv/unixlib.c +++ b/dlls/wineps.drv/unixlib.c @@ -1764,6 +1764,9 @@ static WCHAR convert_ntf_cp(unsigned short c, unsigned short cp) case 0xfff1: ret = c < ARRAY_SIZE(map_fff1) ? map_fff1[c] : 0; break; + case 0xffff: /* Wine extension */ + ret = c; + break; }
if (!ret && c)
From: Piotr Caban piotr@codeweavers.com
--- dlls/wineps.drv/init.c | 5 +- dlls/wineps.drv/unixlib.c | 310 ++++---------------------------------- dlls/wineps.drv/unixlib.h | 5 +- 3 files changed, 35 insertions(+), 285 deletions(-)
diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c index 73e95b116ba..136856d5dc0 100644 --- a/dlls/wineps.drv/init.c +++ b/dlls/wineps.drv/init.c @@ -902,7 +902,7 @@ fail: const struct gdi_dc_funcs * CDECL PSDRV_get_gdi_driver( unsigned int version, const WCHAR *name ) { PRINTERINFO *pi = PSDRV_FindPrinterInfo( name ); - struct init_dc_params params = { NULL, pi, pi->friendly_name }; + struct init_dc_params params;
if (!pi) return NULL; @@ -911,6 +911,9 @@ const struct gdi_dc_funcs * CDECL PSDRV_get_gdi_driver( unsigned int version, co ERR( "version mismatch, gdi32 wants %u but wineps has %u\n", version, WINE_GDI_DRIVER_VERSION ); return NULL; } + params.name = pi->friendly_name; + params.devmode = pi->Devmode; + params.funcs = NULL; if (!WINE_UNIX_CALL( unix_init_dc, ¶ms )) return FALSE; return params.funcs; diff --git a/dlls/wineps.drv/unixlib.c b/dlls/wineps.drv/unixlib.c index d7d545097f8..68509025eac 100644 --- a/dlls/wineps.drv/unixlib.c +++ b/dlls/wineps.drv/unixlib.c @@ -76,7 +76,7 @@ struct printer_info { struct list entry; const WCHAR *name; - PRINTERINFO *pi; + PSDRV_DEVMODE *devmode; };
static struct list printer_info_list = LIST_INIT(printer_info_list); @@ -90,7 +90,6 @@ typedef struct /* builtin font info */ BOOL builtin; SIZE size; - const AFM *afm; const struct font_data *font; float scale; TEXTMETRICW tm; @@ -305,10 +304,10 @@ static inline int paper_size_from_points(float size) static const struct input_slot *unix_find_slot(const struct printer_info *pi, const DEVMODEW *dm) { - const struct input_slot *slot = (const struct input_slot *)pi->pi->Devmode->data; + const struct input_slot *slot = (const struct input_slot *)pi->devmode->data; int i;
- for (i = 0; i < pi->pi->Devmode->input_slots; i++) + for (i = 0; i < pi->devmode->input_slots; i++) { if (slot[i].win_bin == dm->dmDefaultSource) return slot + i; @@ -322,10 +321,10 @@ static const struct page_size *unix_find_pagesize(const struct printer_info *pi, const struct page_size *page; int i;
- page = (const struct page_size *)(pi->pi->Devmode->data + - pi->pi->Devmode->input_slots * sizeof(struct input_slot) + - pi->pi->Devmode->resolutions * sizeof(struct resolution)); - for (i = 0; i < pi->pi->Devmode->page_sizes; i++) + page = (const struct page_size *)(pi->devmode->data + + pi->devmode->input_slots * sizeof(struct input_slot) + + pi->devmode->resolutions * sizeof(struct resolution)); + for (i = 0; i < pi->devmode->page_sizes; i++) { if (page[i].win_page == dm->dmPaperSize) return page + i; @@ -423,7 +422,7 @@ static void merge_devmodes(PSDRV_DEVMODE *dm1, const DEVMODEW *dm2, dm1->dmPublic.dmPrintQuality = dm2->dmPrintQuality; if (dm2->dmFields & DM_COLOR) dm1->dmPublic.dmColor = dm2->dmColor; - if (dm2->dmFields & DM_DUPLEX && pi->pi->Devmode->duplex) + if (dm2->dmFields & DM_DUPLEX && pi->devmode->duplex) dm1->dmPublic.dmDuplex = dm2->dmDuplex; if (dm2->dmFields & DM_YRESOLUTION) dm1->dmPublic.dmYResolution = dm2->dmYResolution; @@ -586,7 +585,7 @@ static int cmp_glyph_info(const void *a, const void *b) (int)((const struct glyph_info *)b)->wch; }
-const struct glyph_info *uv_metrics_ntf(WCHAR wch, const struct font_data *font) +const struct glyph_info *uv_metrics(WCHAR wch, const struct font_data *font) { const struct glyph_info *needle; struct glyph_info key; @@ -609,34 +608,6 @@ const struct glyph_info *uv_metrics_ntf(WCHAR wch, const struct font_data *font) return needle; }
-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 int CDECL ext_escape(PHYSDEV dev, int escape, int input_size, const void *input, int output_size, void *output) { @@ -894,7 +865,7 @@ static int CDECL ext_escape(PHYSDEV dev, int escape, int input_size, const void { PSDRV_PDEVICE *pdev = get_psdrv_dev(dev); WCHAR *uv = (WCHAR *)input; - WCHAR out = pdev->font ? uv_metrics_ntf(*uv, pdev->font)->wch : uv_metrics(*uv, pdev->afm)->UV; + WCHAR out = uv_metrics(*uv, pdev->font)->wch;
if ((out & 0xff00) == 0xf000) out &= ~0xf000; *(WCHAR *)output = out; @@ -909,10 +880,7 @@ static int CDECL ext_escape(PHYSDEV dev, int escape, int input_size, const void if (!pdev->builtin) return 0;
- if (pdev->font) - lstrcpynA(font_info->font_name, pdev->font->name, sizeof(font_info->font_name)); - else - lstrcpynA(font_info->font_name, pdev->afm->FontName, sizeof(font_info->font_name)); + lstrcpynA(font_info->font_name, pdev->font->name, sizeof(font_info->font_name)); font_info->size = pdev->size; font_info->escapement = pdev->escapement; return 1; @@ -929,7 +897,7 @@ static inline float gdi_round(float f) return f > 0 ? f + 0.5 : f - 0.5; }
-static void scale_font_ntf(PSDRV_PDEVICE *pdev, const struct font_data *font, LONG height, TEXTMETRICW *tm) +static void scale_font(PSDRV_PDEVICE *pdev, const struct font_data *font, LONG height, TEXTMETRICW *tm) { SHORT ascender, descender, line_gap, avg_char_width; USHORT units_per_em, win_ascent, win_descent; @@ -1012,89 +980,6 @@ static void scale_font_ntf(PSDRV_PDEVICE *pdev, const struct font_data *font, LO (int)tm->tmExternalLeading); }
-static void scale_font(PSDRV_PDEVICE *pdev, const AFM *afm, LONG height, TEXTMETRICW *tm) -{ - const WINMETRICS *wm = &(afm->WinMetrics); - USHORT units_per_em, win_ascent, win_descent; - SHORT ascender, descender, line_gap, avg_char_width; - float scale; - SIZE size; - - TRACE("'%s' %i\n", afm->FontName, (int)height); - - if (height < 0) /* match em height */ - scale = -(height / (float)wm->usUnitsPerEm); - else /* match cell height */ - scale = height / (float)(wm->usWinAscent + wm->usWinDescent); - - size.cx = (INT)gdi_round(scale * (float)wm->usUnitsPerEm); - size.cy = -(INT)gdi_round(scale * (float)wm->usUnitsPerEm); - - units_per_em = (USHORT)gdi_round((float)wm->usUnitsPerEm * scale); - ascender = (SHORT)gdi_round((float)wm->sAscender * scale); - descender = (SHORT)gdi_round((float)wm->sDescender * scale); - line_gap = (SHORT)gdi_round((float)wm->sLineGap * scale); - win_ascent = (USHORT)gdi_round((float)wm->usWinAscent * scale); - win_descent = (USHORT)gdi_round((float)wm->usWinDescent * scale); - avg_char_width = (SHORT)gdi_round((float)wm->sAvgCharWidth * scale); - - tm->tmAscent = (LONG)win_ascent; - tm->tmDescent = (LONG)win_descent; - tm->tmHeight = tm->tmAscent + tm->tmDescent; - - tm->tmInternalLeading = tm->tmHeight - (LONG)units_per_em; - if (tm->tmInternalLeading < 0) - tm->tmInternalLeading = 0; - - tm->tmExternalLeading = - (LONG)(ascender - descender + line_gap) - tm->tmHeight; - if (tm->tmExternalLeading < 0) - tm->tmExternalLeading = 0; - - tm->tmAveCharWidth = (LONG)avg_char_width; - - tm->tmWeight = afm->Weight; - tm->tmItalic = (afm->ItalicAngle != 0.0); - tm->tmUnderlined = 0; - tm->tmStruckOut = 0; - tm->tmFirstChar = (WCHAR)(afm->Metrics[0].UV); - tm->tmLastChar = (WCHAR)(afm->Metrics[afm->NumofMetrics - 1].UV); - tm->tmDefaultChar = 0x001f; /* Win2K does this - FIXME? */ - tm->tmBreakChar = tm->tmFirstChar; /* should be 'space' */ - - tm->tmPitchAndFamily = TMPF_DEVICE | TMPF_VECTOR; - if (!afm->IsFixedPitch) - tm->tmPitchAndFamily |= TMPF_FIXED_PITCH; /* yes, it's backwards */ - if (wm->usUnitsPerEm != 1000) - tm->tmPitchAndFamily |= TMPF_TRUETYPE; - - tm->tmCharSet = ANSI_CHARSET; /* FIXME */ - tm->tmOverhang = 0; - - /* - * This is kludgy. font->scale is used in several places in the driver - * to adjust PostScript-style metrics. Since these metrics have been - * "normalized" to an em-square size of 1000, font->scale needs to be - * similarly adjusted.. - */ - - scale *= (float)wm->usUnitsPerEm / 1000.0; - - tm->tmMaxCharWidth = (LONG)gdi_round((afm->FontBBox.urx - afm->FontBBox.llx) * scale); - - if (pdev) - { - pdev->scale = scale; - pdev->size = size; - } - - TRACE("Selected PS font '%s' size %d weight %d.\n", afm->FontName, - (int)size.cx, (int)tm->tmWeight); - TRACE("H = %d As = %d Des = %d IL = %d EL = %d\n", (int)tm->tmHeight, - (int)tm->tmAscent, (int)tm->tmDescent, (int)tm->tmInternalLeading, - (int)tm->tmExternalLeading); -} - static inline BOOL is_stock_font(HFONT font) { int i; @@ -1117,10 +1002,9 @@ static struct font_data *find_font_data(const char *name) return NULL; }
-static struct font_data *find_builtin_font(PSDRV_PDEVICE *pdev, +static struct font_data *find_builtin_font(PSDRV_DEVMODE *devmode, const WCHAR *facename, BOOL it, BOOL bd) { - PSDRV_DEVMODE *devmode = pdev->devmode; struct installed_font *installed_font; BOOL best_it, best_bd, cur_it, cur_bd; struct font_data *best = NULL, *cur; @@ -1160,7 +1044,7 @@ static struct font_data *find_builtin_font(PSDRV_PDEVICE *pdev, return best; }
-static BOOL select_builtin_font_ntf(PSDRV_PDEVICE *pdev, HFONT hfont, LOGFONTW *plf) +static BOOL select_builtin_font(PSDRV_PDEVICE *pdev, HFONT hfont, LOGFONTW *plf) { struct font_data *font_data; BOOL bd = FALSE, it = FALSE; @@ -1174,7 +1058,7 @@ static BOOL select_builtin_font_ntf(PSDRV_PDEVICE *pdev, HFONT hfont, LOGFONTW * bd = TRUE;
/* Look for a matching font family */ - font_data = find_builtin_font(pdev, plf->lfFaceName, it, bd); + font_data = find_builtin_font(pdev->devmode, plf->lfFaceName, it, bd); if (!font_data) { /* Fallback for Window's font families to common PostScript families */ @@ -1187,18 +1071,17 @@ static BOOL select_builtin_font_ntf(PSDRV_PDEVICE *pdev, HFONT hfont, LOGFONTW * else if (!wcscmp(plf->lfFaceName, courier_newW)) wcscpy(plf->lfFaceName, courierW);
- font_data = find_builtin_font(pdev, plf->lfFaceName, it, bd); + font_data = find_builtin_font(pdev->devmode, plf->lfFaceName, it, bd); } /* If all else fails, use the first font defined for the printer */ if (!font_data) - font_data = find_builtin_font(pdev, NULL, it, bd); + font_data = find_builtin_font(pdev->devmode, NULL, it, bd);
TRACE("Got family %s font '%s'\n", debugstr_w((WCHAR *)((char *)font_data->metrics + font_data->metrics->dpwszFaceName)), font_data->name);
pdev->builtin = TRUE; pdev->font = NULL; - pdev->afm = NULL; pdev->font = font_data;
height = plf->lfHeight; @@ -1211,89 +1094,7 @@ static BOOL select_builtin_font_ntf(PSDRV_PDEVICE *pdev, HFONT hfont, LOGFONTW * NtGdiTransformPoints(pdev->dev.hdc, pts, pts, 2, NtGdiLPtoDP); height = pts[1].y - pts[0].y; } - scale_font_ntf(pdev, font_data, height, &pdev->tm); - - /* Does anyone know if these are supposed to be reversed like this? */ - pdev->tm.tmDigitizedAspectX = pdev->log_pixels_y; - pdev->tm.tmDigitizedAspectY = pdev->log_pixels_x; - return TRUE; -} - -static BOOL select_builtin_font(PSDRV_PDEVICE *pdev, HFONT hfont, LOGFONTW *plf) -{ - AFMLISTENTRY *afmle; - FONTFAMILY *family; - BOOL bd = FALSE, it = FALSE; - LONG height; - - if (select_builtin_font_ntf(pdev, hfont, plf)) - return TRUE; - - TRACE("Trying to find facename %s\n", debugstr_w(plf->lfFaceName)); - - /* Look for a matching font family */ - for (family = pdev->pi->pi->Fonts; family; family = family->next) - { - if (!wcsicmp(plf->lfFaceName, family->FamilyName)) - break; - } - - if (!family) - { - /* Fallback for Window's font families to common PostScript families */ - if (!wcscmp(plf->lfFaceName, arialW)) - wcscpy(plf->lfFaceName, helveticaW); - else if (!wcscmp(plf->lfFaceName, systemW)) - wcscpy(plf->lfFaceName, helveticaW); - else if (!wcscmp(plf->lfFaceName, times_new_romanW)) - wcscpy(plf->lfFaceName, timesW); - else if (!wcscmp(plf->lfFaceName, courier_newW)) - wcscpy(plf->lfFaceName, courierW); - - for (family = pdev->pi->pi->Fonts; family; family = family->next) - { - if (!wcscmp(plf->lfFaceName, family->FamilyName)) - break; - } - } - /* If all else fails, use the first font defined for the printer */ - if (!family) - family = pdev->pi->pi->Fonts; - - TRACE("Got family %s\n", debugstr_w(family->FamilyName)); - - if (plf->lfItalic) - it = TRUE; - if (plf->lfWeight > 550) - bd = TRUE; - - for (afmle = family->afmlist; afmle; afmle = afmle->next) - { - if (bd == (afmle->afm->Weight == FW_BOLD) && - it == (afmle->afm->ItalicAngle != 0.0)) - break; - } - if (!afmle) - afmle = family->afmlist; /* not ideal */ - - TRACE("Got font '%s'\n", afmle->afm->FontName); - - pdev->builtin = TRUE; - pdev->afm = afmle->afm; - pdev->font = NULL; - - height = plf->lfHeight; - /* stock fonts ignore the mapping mode */ - if (!is_stock_font(hfont)) - { - POINT pts[2]; - pts[0].x = pts[0].y = pts[1].x = 0; - pts[1].y = height; - NtGdiTransformPoints(pdev->dev.hdc, pts, pts, 2, NtGdiLPtoDP); - height = pts[1].y - pts[0].y; - } - scale_font(pdev, pdev->afm, height, &pdev->tm); - + scale_font(pdev, font_data, height, &pdev->tm);
/* Does anyone know if these are supposed to be reversed like this? */ pdev->tm.tmDigitizedAspectX = pdev->log_pixels_y; @@ -1391,7 +1192,7 @@ static HFONT CDECL select_font(PHYSDEV dev, HFONT hfont, UINT *aa_flags) return hfont; }
-static UINT get_font_metric_ntf(const struct font_data *font, +static UINT get_font_metric(const struct font_data *font, NEWTEXTMETRICEXW *ntmx, ENUMLOGFONTEXW *elfx) { /* ntmx->ntmTm is NEWTEXTMETRICW; compatible w/ TEXTMETRICW per Win32 doc */ @@ -1401,7 +1202,7 @@ static UINT get_font_metric_ntf(const struct font_data *font, memset(ntmx, 0, sizeof(*ntmx)); memset(elfx, 0, sizeof(*elfx));
- scale_font_ntf(NULL, font, -(LONG)font->metrics->fwdUnitsPerEm, tm); + scale_font(NULL, font, -(LONG)font->metrics->fwdUnitsPerEm, tm);
lf->lfHeight = tm->tmHeight; lf->lfWidth = tm->tmAveCharWidth; @@ -1415,29 +1216,6 @@ static UINT get_font_metric_ntf(const struct font_data *font, return DEVICE_FONTTYPE; }
-static UINT get_font_metric(const AFM *afm, NEWTEXTMETRICEXW *ntmx, ENUMLOGFONTEXW *elfx) -{ - /* ntmx->ntmTm is NEWTEXTMETRICW; compatible w/ TEXTMETRICW per Win32 doc */ - TEXTMETRICW *tm = (TEXTMETRICW *)&(ntmx->ntmTm); - LOGFONTW *lf = &(elfx->elfLogFont); - - memset(ntmx, 0, sizeof(*ntmx)); - memset(elfx, 0, sizeof(*elfx)); - - scale_font(NULL, afm, -(LONG)afm->WinMetrics.usUnitsPerEm, tm); - - lf->lfHeight = tm->tmHeight; - lf->lfWidth = tm->tmAveCharWidth; - lf->lfWeight = tm->tmWeight; - lf->lfItalic = tm->tmItalic; - lf->lfCharSet = tm->tmCharSet; - - lf->lfPitchAndFamily = afm->IsFixedPitch ? FIXED_PITCH : VARIABLE_PITCH; - - lstrcpynW(lf->lfFaceName, afm->FamilyName, LF_FACESIZE); - return DEVICE_FONTTYPE; -} - static BOOL CDECL enum_fonts(PHYSDEV dev, LPLOGFONTW plf, FONTENUMPROCW proc, LPARAM lp) { PSDRV_PDEVICE *pdev = get_psdrv_dev(dev); @@ -1447,8 +1225,6 @@ static BOOL CDECL enum_fonts(PHYSDEV dev, LPLOGFONTW plf, FONTENUMPROCW proc, LP struct font_data *cur; ENUMLOGFONTEXW lf; NEWTEXTMETRICEXW tm; - AFMLISTENTRY *afmle; - FONTFAMILY *family; const WCHAR *name; BOOL ret; UINT fm; @@ -1476,27 +1252,10 @@ static BOOL CDECL enum_fonts(PHYSDEV dev, LPLOGFONTW plf, FONTENUMPROCW proc, LP continue;
TRACE("Got '%s'\n", cur->name); - fm = get_font_metric_ntf(cur, &tm, &lf); + fm = get_font_metric(cur, &tm, &lf); if (!(ret = (*proc)(&lf.elfLogFont, (TEXTMETRICW *)&tm, fm, lp))) - return ret; - } - - for (family = pdev->pi->pi->Fonts; family; family = family->next) - { - if (!wcsncmp(plf->lfFaceName, family->FamilyName, - wcslen(family->FamilyName))) break; } - if (family) - { - for (afmle = family->afmlist; afmle; afmle = afmle->next) - { - TRACE("Got '%s'\n", afmle->afm->FontName); - fm = get_font_metric(afmle->afm, &tm, &lf); - if (!(ret = (*proc)(&lf.elfLogFont, (TEXTMETRICW *)&tm, fm, lp))) - break; - } - } } else { @@ -1509,16 +1268,7 @@ static BOOL CDECL enum_fonts(PHYSDEV dev, LPLOGFONTW plf, FONTENUMPROCW proc, LP
name = (WCHAR *)((char *)cur->metrics + cur->metrics->dpwszFaceName); TRACE("Got '%s'\n", cur->name); - fm = get_font_metric_ntf(cur, &tm, &lf); - if (!(ret = (*proc)(&lf.elfLogFont, (TEXTMETRICW *)&tm, fm, lp))) - return ret; - } - - for (family = pdev->pi->pi->Fonts; family; family = family->next) - { - afmle = family->afmlist; - TRACE("Got '%s'\n", afmle->afm->FontName); - fm = get_font_metric(afmle->afm, &tm, &lf); + fm = get_font_metric(cur, &tm, &lf); if (!(ret = (*proc)(&lf.elfLogFont, (TEXTMETRICW *)&tm, fm, lp))) break; } @@ -1546,8 +1296,7 @@ static BOOL CDECL get_char_width(PHYSDEV dev, UINT first, UINT count, const WCHA if (c > 0xffff) return FALSE;
- *buffer = floor((pdev->font ? uv_metrics_ntf(c, pdev->font)->width : - uv_metrics(c, pdev->afm)->WX) * pdev->scale + 0.5); + *buffer = floor(uv_metrics(c, pdev->font)->width * pdev->scale + 0.5); TRACE("U+%.4X: %i\n", i, *buffer); ++buffer; } @@ -1584,8 +1333,7 @@ static BOOL CDECL get_text_extent_ex_point(PHYSDEV dev, const WCHAR *str, int co
for (i = 0; i < count; ++i) { - width += pdev->font ? uv_metrics_ntf(str[i], pdev->font)->width : - uv_metrics(str[i], pdev->afm)->WX; + width += uv_metrics(str[i], pdev->font)->width; dx[i] = width * pdev->scale; } return TRUE; @@ -1610,7 +1358,7 @@ static PSDRV_PDEVICE *create_physdev(HDC hdc, const WCHAR *device, PSDRV_PDEVICE *pdev;
if (!pi) return NULL; - if (!pi->pi->Fonts) + if (!find_builtin_font(pi->devmode, NULL, FALSE, FALSE)) { RASTERIZER_STATUS status; if (!NtGdiGetRasterizerCaps(&status, sizeof(status)) || @@ -1626,15 +1374,15 @@ static PSDRV_PDEVICE *create_physdev(HDC hdc, const WCHAR *device, pdev = malloc(sizeof(*pdev)); if (!pdev) return NULL;
- pdev->devmode = malloc(pi->pi->Devmode->dmPublic.dmSize + pi->pi->Devmode->dmPublic.dmDriverExtra); + pdev->devmode = malloc(pi->devmode->dmPublic.dmSize + pi->devmode->dmPublic.dmDriverExtra); if (!pdev->devmode) { free(pdev); return NULL; }
- memcpy(pdev->devmode, pi->pi->Devmode, pi->pi->Devmode->dmPublic.dmSize + - pi->pi->Devmode->dmPublic.dmDriverExtra); + memcpy(pdev->devmode, pi->devmode, pi->devmode->dmPublic.dmSize + + pi->devmode->dmPublic.dmDriverExtra); pdev->pi = pi; pdev->log_pixels_x = pdev->devmode->default_resolution; pdev->log_pixels_y = pdev->devmode->default_resolution; @@ -1952,7 +1700,7 @@ static NTSTATUS init_dc(void *arg) if (!pi) return FALSE;
pi->name = params->name; - pi->pi = params->pi; + pi->devmode = params->devmode; list_add_head(&printer_info_list, &pi->entry); }
diff --git a/dlls/wineps.drv/unixlib.h b/dlls/wineps.drv/unixlib.h index 67fe0287169..03459590dc6 100644 --- a/dlls/wineps.drv/unixlib.h +++ b/dlls/wineps.drv/unixlib.h @@ -88,8 +88,7 @@ struct import_ntf_params
struct init_dc_params { - const struct gdi_dc_funcs *funcs; - PRINTERINFO *pi; - const WCHAR *name; + PSDRV_DEVMODE *devmode; + const struct gdi_dc_funcs *funcs; };
This merge request was approved by Huw Davies.