Added patches for various improvements in wineps.drv.

This commit is contained in:
Sebastian Lackner 2016-04-13 20:40:50 +02:00
parent 141fc0844c
commit 1a8a066920
7 changed files with 514 additions and 1 deletions

View File

@ -51,7 +51,7 @@ usage()
# Get the upstream commit sha
upstream_commit()
{
echo "944190bad442f19fba5e0073d284469bd2329652"
echo "1ccc52169730079414eb3e4d1a18ec1131bb6ed3"
}
# Show version information
@ -366,6 +366,7 @@ patch_enable_all ()
enable_wined3d_Silence_FIXMEs="$1"
enable_winedevice_Fix_Relocation="$1"
enable_winemenubuilder_Desktop_Icon_Path="$1"
enable_wineps_drv_PostScript_Fixes="$1"
enable_winepulse_PulseAudio_Support="$1"
enable_winex11_CandidateWindowPos="$1"
enable_winex11_Clipboard_HTML="$1"
@ -1271,6 +1272,9 @@ patch_enable ()
winemenubuilder-Desktop_Icon_Path)
enable_winemenubuilder_Desktop_Icon_Path="$2"
;;
wineps.drv-PostScript_Fixes)
enable_wineps_drv_PostScript_Fixes="$2"
;;
winepulse-PulseAudio_Support)
enable_winepulse_PulseAudio_Support="$2"
;;
@ -7303,6 +7307,27 @@ if test "$enable_winemenubuilder_Desktop_Icon_Path" -eq 1; then
) >> "$patchlist"
fi
# Patchset wineps.drv-PostScript_Fixes
# |
# | Modified files:
# | * dlls/gdi32/printdrv.c, dlls/gdi32/tests/dc.c, dlls/wineps.drv/download.c, dlls/wineps.drv/escape.c,
# | dlls/wineps.drv/psdrv.h
# |
if test "$enable_wineps_drv_PostScript_Fixes" -eq 1; then
patch_apply wineps.drv-PostScript_Fixes/0001-gdi32-tests-Add-a-simple-test-for-printing-to-a-Post.patch
patch_apply wineps.drv-PostScript_Fixes/0002-gdi32-Trace-full-contents-of-DOCINFO-in-StartDoc.patch
patch_apply wineps.drv-PostScript_Fixes/0003-wineps.drv-Add-stubs-for-escapes-required-by-Adobe-P.patch
patch_apply wineps.drv-PostScript_Fixes/0004-wineps.drv-Add-support-for-GETFACENAME-and-DOWNLOADF.patch
patch_apply wineps.drv-PostScript_Fixes/0005-wineps.drv-PostScript-header-should-be-written-by-St.patch
(
echo '+ { "Dmitry Timoshkov", "gdi32/tests: Add a simple test for printing to a PostScript device.", 1 },';
echo '+ { "Dmitry Timoshkov", "gdi32: Trace full contents of DOCINFO in StartDoc.", 1 },';
echo '+ { "Dmitry Timoshkov", "wineps.drv: Add stubs for escapes required by Adobe PageMaker.", 1 },';
echo '+ { "Dmitry Timoshkov", "wineps.drv: Add support for GETFACENAME and DOWNLOADFACE escapes.", 1 },';
echo '+ { "Dmitry Timoshkov", "wineps.drv: PostScript header should be written by StartDoc instead of StartPage.", 1 },';
) >> "$patchlist"
fi
# Patchset winepulse-PulseAudio_Support
# |
# | This patchset fixes the following Wine bugs:

View File

@ -0,0 +1,159 @@
From 8b546221cfb857a09dae4654efee19c8b771935e Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Wed, 13 Apr 2016 15:34:42 +0800
Subject: gdi32/tests: Add a simple test for printing to a PostScript device.
---
dlls/gdi32/tests/dc.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 123 insertions(+), 1 deletion(-)
diff --git a/dlls/gdi32/tests/dc.c b/dlls/gdi32/tests/dc.c
index c9b7b31..4a50594 100644
--- a/dlls/gdi32/tests/dc.c
+++ b/dlls/gdi32/tests/dc.c
@@ -2,7 +2,7 @@
* Unit tests for dc functions
*
* Copyright (c) 2005 Huw Davies
- * Copyright (c) 2005 Dmitry Timoshkov
+ * Copyright (c) 2005,2016 Dmitry Timoshkov
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -1386,6 +1386,127 @@ static void test_printer_dc(void)
DeleteObject( bmp );
}
+static void print_something(HDC hdc)
+{
+ static const char psadobe[10] = "%!PS-Adobe";
+ char buf[1024], *p;
+ char temp_path[MAX_PATH], file_name[MAX_PATH];
+ DOCINFOA di;
+ DWORD ret;
+ HANDLE hfile;
+
+ GetTempPathA(sizeof(temp_path), temp_path);
+ GetTempFileNameA(temp_path, "ps", 0, file_name);
+
+ di.cbSize = sizeof(di);
+ di.lpszDocName = "Let's dance";
+ di.lpszOutput = file_name;
+ di.lpszDatatype = NULL;
+ di.fwType = 0;
+ ret = StartDocA(hdc, &di);
+ ok(ret > 0, "StartDoc failed: %d\n", ret);
+
+ strcpy(buf + 2, "\n% ===> before DOWNLOADHEADER <===\n");
+ *(WORD *)buf = strlen(buf + 2);
+ ret = Escape(hdc, POSTSCRIPT_PASSTHROUGH, 0, buf, NULL);
+ ok(ret == *(WORD *)buf, "POSTSCRIPT_PASSTHROUGH failed: %d\n", ret);
+
+ strcpy(buf, "deadbeef");
+ ret = ExtEscape(hdc, DOWNLOADHEADER, 0, NULL, sizeof(buf), buf );
+todo_wine
+ ok(ret == 1, "DOWNLOADHEADER failed\n");
+todo_wine
+ ok(strcmp(buf, "deadbeef") != 0, "DOWNLOADHEADER failed\n");
+
+ strcpy(buf + 2, "\n% ===> after DOWNLOADHEADER <===\n");
+ *(WORD *)buf = strlen(buf + 2);
+ ret = Escape(hdc, POSTSCRIPT_PASSTHROUGH, 0, buf, NULL);
+ ok(ret == *(WORD *)buf, "POSTSCRIPT_PASSTHROUGH failed: %d\n", ret);
+
+ ret = EndDoc(hdc);
+ ok(ret == 1, "EndDoc failed\n");
+
+ hfile = CreateFileA(file_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
+ ok(hfile != INVALID_HANDLE_VALUE, "CreateFile failed\n");
+ memset(buf, 0, sizeof(buf));
+ ret = ReadFile(hfile, buf, sizeof(buf), &ret, NULL);
+ ok(ret, "ReadFile failed\n");
+ CloseHandle(hfile);
+
+ /* skip the HP PCL language selector */
+ buf[sizeof(buf) - 1] = 0;
+ p = buf;
+ while (*p)
+ {
+ if (!(p[0] == 0x1b && p[1] == '%') && memcmp(p, "@PJL", 4) != 0)
+ break;
+
+ p = strchr(p, '\n');
+ if (!p) break;
+
+ while (*p == '\r' || *p == '\n') p++;
+ }
+todo_wine
+ ok(p && !memcmp(p, psadobe, sizeof(psadobe)), "wrong signature: %.14s\n", p ? p : buf);
+
+ DeleteFileA(file_name);
+}
+
+static void test_pscript_printer_dc(void)
+{
+ HDC hdc;
+ char buf[256];
+ DWORD query, ret;
+
+ hdc = create_printer_dc(100, FALSE);
+
+ if (!hdc) return;
+
+ if (!is_postscript_printer(hdc))
+ {
+ skip("Default printer is not a PostScript device\n");
+ DeleteDC( hdc );
+ return;
+ }
+
+ query = GETFACENAME;
+ ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
+ ok(!ret, "GETFACENAME is supported\n");
+
+ query = DOWNLOADFACE;
+ ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
+todo_wine
+ ok(ret == 1, "DOWNLOADFACE is not supported\n");
+
+ query = OPENCHANNEL;
+ ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
+todo_wine
+ ok(ret == 1, "OPENCHANNEL is not supported\n");
+
+ query = DOWNLOADHEADER;
+ ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
+todo_wine
+ ok(ret == 1, "DOWNLOADHEADER is not supported\n");
+
+ query = CLOSECHANNEL;
+ ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
+todo_wine
+ ok(ret == 1, "CLOSECHANNEL is not supported\n");
+
+ query = POSTSCRIPT_PASSTHROUGH;
+ ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
+ ok(ret == 1, "POSTSCRIPT_PASSTHROUGH is not supported\n");
+
+ ret = ExtEscape(hdc, GETFACENAME, 0, NULL, sizeof(buf), buf);
+todo_wine
+ ok(ret == 1, "GETFACENAME failed\n");
+ trace("face name: %s\n", buf);
+
+ print_something(hdc);
+
+ DeleteDC(hdc);
+}
+
START_TEST(dc)
{
pSetLayout = (void *)GetProcAddress( GetModuleHandleA("gdi32.dll"), "SetLayout");
@@ -1400,4 +1521,5 @@ START_TEST(dc)
test_desktop_colorres();
test_gamma();
test_printer_dc();
+ test_pscript_printer_dc();
}
--
2.7.1

View File

@ -0,0 +1,28 @@
From c0cf857381cd4af33ce454a96d9e48f896ed5027 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Wed, 13 Apr 2016 15:36:56 +0800
Subject: gdi32: Trace full contents of DOCINFO in StartDoc.
---
dlls/gdi32/printdrv.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/gdi32/printdrv.c b/dlls/gdi32/printdrv.c
index 3cfdc47..d2f4076 100644
--- a/dlls/gdi32/printdrv.c
+++ b/dlls/gdi32/printdrv.c
@@ -72,9 +72,9 @@ INT WINAPI StartDocW(HDC hdc, const DOCINFOW* doc)
INT ret;
DC *dc = get_dc_ptr( hdc );
- TRACE("DocName = %s Output = %s Datatype = %s\n",
+ TRACE("DocName %s, Output %s, Datatype %s, fwType %#x\n",
debugstr_w(doc->lpszDocName), debugstr_w(doc->lpszOutput),
- debugstr_w(doc->lpszDatatype));
+ debugstr_w(doc->lpszDatatype), doc->fwType);
if(!dc) return SP_ERROR;
--
2.7.1

View File

@ -0,0 +1,118 @@
From c9912e16ab7c0c5add52913cdc38e98dc81f8690 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Wed, 13 Apr 2016 15:48:10 +0800
Subject: wineps.drv: Add stubs for escapes required by Adobe PageMaker.
---
dlls/gdi32/tests/dc.c | 7 -------
dlls/wineps.drv/escape.c | 41 +++++++++++++++++++++++++++++++++++++++++
2 files changed, 41 insertions(+), 7 deletions(-)
diff --git a/dlls/gdi32/tests/dc.c b/dlls/gdi32/tests/dc.c
index 4a50594..939f33e 100644
--- a/dlls/gdi32/tests/dc.c
+++ b/dlls/gdi32/tests/dc.c
@@ -1413,9 +1413,7 @@ static void print_something(HDC hdc)
strcpy(buf, "deadbeef");
ret = ExtEscape(hdc, DOWNLOADHEADER, 0, NULL, sizeof(buf), buf );
-todo_wine
ok(ret == 1, "DOWNLOADHEADER failed\n");
-todo_wine
ok(strcmp(buf, "deadbeef") != 0, "DOWNLOADHEADER failed\n");
strcpy(buf + 2, "\n% ===> after DOWNLOADHEADER <===\n");
@@ -1475,22 +1473,18 @@ static void test_pscript_printer_dc(void)
query = DOWNLOADFACE;
ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
-todo_wine
ok(ret == 1, "DOWNLOADFACE is not supported\n");
query = OPENCHANNEL;
ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
-todo_wine
ok(ret == 1, "OPENCHANNEL is not supported\n");
query = DOWNLOADHEADER;
ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
-todo_wine
ok(ret == 1, "DOWNLOADHEADER is not supported\n");
query = CLOSECHANNEL;
ret = Escape(hdc, QUERYESCSUPPORT, sizeof(query), (LPCSTR)&query, NULL);
-todo_wine
ok(ret == 1, "CLOSECHANNEL is not supported\n");
query = POSTSCRIPT_PASSTHROUGH;
@@ -1498,7 +1492,6 @@ todo_wine
ok(ret == 1, "POSTSCRIPT_PASSTHROUGH is not supported\n");
ret = ExtEscape(hdc, GETFACENAME, 0, NULL, sizeof(buf), buf);
-todo_wine
ok(ret == 1, "GETFACENAME failed\n");
trace("face name: %s\n", buf);
diff --git a/dlls/wineps.drv/escape.c b/dlls/wineps.drv/escape.c
index 6e89837..2f3ddfc 100644
--- a/dlls/wineps.drv/escape.c
+++ b/dlls/wineps.drv/escape.c
@@ -100,14 +100,55 @@ INT PSDRV_ExtEscape( PHYSDEV dev, INT nEscape, INT cbInput, LPCVOID in_data,
case CLIP_TO_PATH:
case END_PATH:
/*case DRAWPATTERNRECT:*/
+
+ /* PageMaker checks for it */
+ case DOWNLOADHEADER:
+
+ /* PageMaker doesn't check for DOWNLOADFACE and GETFACENAME but
+ * uses them, they are supposed to be supported by any PS printer.
+ */
+ case DOWNLOADFACE:
+
+ /* PageMaker checks for these as a part of process of detecting
+ * a "fully compatible" PS printer, but doesn't actually use them.
+ */
+ case OPENCHANNEL:
+ case CLOSECHANNEL:
return TRUE;
+ /* Windows PS driver reports 0, but still supports this escape */
+ case GETFACENAME:
+ return FALSE; /* suppress the FIXME below */
+
default:
FIXME("QUERYESCSUPPORT(%d) - not supported.\n", num);
return FALSE;
}
}
+ case OPENCHANNEL:
+ FIXME("OPENCHANNEL: stub\n");
+ return 1;
+
+ case CLOSECHANNEL:
+ FIXME("CLOSECHANNEL: stub\n");
+ return 1;
+
+ case DOWNLOADHEADER:
+ FIXME("DOWNLOADHEADER: stub\n");
+ /* should return name of the downloaded procset */
+ *(char *)out_data = 0;
+ return 1;
+
+ case GETFACENAME:
+ FIXME("GETFACENAME: stub\n");
+ lstrcpynA(out_data, "Courier", cbOutput);
+ return 1;
+
+ case DOWNLOADFACE:
+ FIXME("DOWNLOADFACE: stub\n");
+ return 1;
+
case MFCOMMENT:
{
FIXME("MFCOMMENT(%p, %d)\n", in_data, cbInput);
--
2.7.1

View File

@ -0,0 +1,98 @@
From 89144b9ac2938a343d9165f16f4b7b594fa98782 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Wed, 13 Apr 2016 15:52:38 +0800
Subject: wineps.drv: Add support for GETFACENAME and DOWNLOADFACE escapes.
---
dlls/wineps.drv/download.c | 26 ++++++++++++++++++++++++++
dlls/wineps.drv/escape.c | 21 ++++++++++++++++++---
dlls/wineps.drv/psdrv.h | 1 +
3 files changed, 45 insertions(+), 3 deletions(-)
diff --git a/dlls/wineps.drv/download.c b/dlls/wineps.drv/download.c
index dc77cf1..86188d2 100644
--- a/dlls/wineps.drv/download.c
+++ b/dlls/wineps.drv/download.c
@@ -259,6 +259,32 @@ static BOOL is_fake_italic( HDC hdc )
return !(mac_style & 2);
}
+char *PSDRV_get_download_name(PHYSDEV dev, BOOL vertical)
+{
+ PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
+ char *ps_name;
+ LPOUTLINETEXTMETRICA potm;
+ DWORD len = GetOutlineTextMetricsA(dev->hdc, 0, NULL);
+ LOGFONTW lf;
+
+ assert(physDev->font.fontloc == Download);
+
+ if (!GetObjectW(GetCurrentObject(dev->hdc, OBJ_FONT), sizeof(lf), &lf))
+ return NULL;
+
+ potm = HeapAlloc(GetProcessHeap(), 0, len);
+ if (!potm)
+ return NULL;
+
+ GetOutlineTextMetricsA(dev->hdc, len, potm);
+
+ ps_name = NULL;
+ get_download_name(dev, potm, &ps_name, vertical);
+ HeapFree(GetProcessHeap(), 0, potm);
+
+ return ps_name;
+}
+
/****************************************************************************
* PSDRV_WriteSetDownloadFont
*
diff --git a/dlls/wineps.drv/escape.c b/dlls/wineps.drv/escape.c
index 2f3ddfc..86a94fd 100644
--- a/dlls/wineps.drv/escape.c
+++ b/dlls/wineps.drv/escape.c
@@ -141,12 +141,27 @@ INT PSDRV_ExtEscape( PHYSDEV dev, INT nEscape, INT cbInput, LPCVOID in_data,
return 1;
case GETFACENAME:
- FIXME("GETFACENAME: stub\n");
- lstrcpynA(out_data, "Courier", cbOutput);
+ if (physDev->font.fontloc == Download)
+ {
+ char *name = PSDRV_get_download_name(dev, physDev->font.set);
+ if (name)
+ {
+ TRACE("font name: %s\n", debugstr_a(name));
+ lstrcpynA(out_data, name, cbOutput);
+ HeapFree(GetProcessHeap(), 0, name);
+ }
+ else
+ lstrcpynA(out_data, "Courier", cbOutput);
+ }
+ else
+ {
+ TRACE("font name: %s\n", debugstr_a(physDev->font.fontinfo.Builtin.afm->FontName));
+ lstrcpynA(out_data, physDev->font.fontinfo.Builtin.afm->FontName, cbOutput);
+ }
return 1;
case DOWNLOADFACE:
- FIXME("DOWNLOADFACE: stub\n");
+ PSDRV_SetFont(dev, physDev->font.set);
return 1;
case MFCOMMENT:
diff --git a/dlls/wineps.drv/psdrv.h b/dlls/wineps.drv/psdrv.h
index 75c062a..c806d52 100644
--- a/dlls/wineps.drv/psdrv.h
+++ b/dlls/wineps.drv/psdrv.h
@@ -547,6 +547,7 @@ extern BOOL PSDRV_SelectBuiltinFont(PHYSDEV dev, HFONT hfont,
extern BOOL PSDRV_WriteSetBuiltinFont(PHYSDEV dev) DECLSPEC_HIDDEN;
extern BOOL PSDRV_WriteBuiltinGlyphShow(PHYSDEV dev, LPCWSTR str, INT count) DECLSPEC_HIDDEN;
+extern char *PSDRV_get_download_name(PHYSDEV dev, BOOL vertical) DECLSPEC_HIDDEN;
extern BOOL PSDRV_SelectDownloadFont(PHYSDEV dev) DECLSPEC_HIDDEN;
extern BOOL PSDRV_WriteSetDownloadFont(PHYSDEV dev, BOOL vertical) DECLSPEC_HIDDEN;
extern BOOL PSDRV_WriteDownloadGlyphShow(PHYSDEV dev, const WORD *glpyhs, UINT count) DECLSPEC_HIDDEN;
--
2.7.1

View File

@ -0,0 +1,84 @@
From f723db2c924b592d8c6e073a2d1b566a035fde92 Mon Sep 17 00:00:00 2001
From: Dmitry Timoshkov <dmitry@baikal.ru>
Date: Wed, 13 Apr 2016 15:58:36 +0800
Subject: wineps.drv: PostScript header should be written by StartDoc instead
of StartPage.
Otherwise a being created file has wrong signature if an application
directly injects PostScript code. This patch fixes printing from
Adobe PageMaker.
---
dlls/gdi32/tests/dc.c | 1 -
dlls/wineps.drv/escape.c | 18 ++++++++++++++----
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/dlls/gdi32/tests/dc.c b/dlls/gdi32/tests/dc.c
index 939f33e..bab99e3 100644
--- a/dlls/gdi32/tests/dc.c
+++ b/dlls/gdi32/tests/dc.c
@@ -1444,7 +1444,6 @@ static void print_something(HDC hdc)
while (*p == '\r' || *p == '\n') p++;
}
-todo_wine
ok(p && !memcmp(p, psadobe, sizeof(psadobe)), "wrong signature: %.14s\n", p ? p : buf);
DeleteFileA(file_name);
diff --git a/dlls/wineps.drv/escape.c b/dlls/wineps.drv/escape.c
index 86a94fd..9cf0277 100644
--- a/dlls/wineps.drv/escape.c
+++ b/dlls/wineps.drv/escape.c
@@ -431,15 +431,14 @@ INT PSDRV_StartPage( PHYSDEV dev )
{
PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
+ TRACE("%p\n", dev->hdc);
+
if(!physDev->job.OutOfPage) {
FIXME("Already started a page?\n");
return 1;
}
- if(physDev->job.PageNo++ == 0) {
- if(!PSDRV_WriteHeader( dev, physDev->job.doc_name ))
- return 0;
- }
+ physDev->job.PageNo++;
if(!PSDRV_WriteNewPage( dev ))
return 0;
@@ -455,6 +454,8 @@ INT PSDRV_EndPage( PHYSDEV dev )
{
PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
+ TRACE("%p\n", dev->hdc);
+
if(physDev->job.OutOfPage) {
FIXME("Already ended a page?\n");
return 1;
@@ -515,6 +516,13 @@ INT PSDRV_StartDoc( PHYSDEV dev, const DOCINFOW *doc )
ClosePrinter(physDev->job.hprinter);
return 0;
}
+
+ if (!PSDRV_WriteHeader( dev, doc->lpszDocName )) {
+ WARN("Failed to write header\n");
+ ClosePrinter(physDev->job.hprinter);
+ return 0;
+ }
+
physDev->job.banding = FALSE;
physDev->job.OutOfPage = TRUE;
physDev->job.PageNo = 0;
@@ -534,6 +542,8 @@ INT PSDRV_EndDoc( PHYSDEV dev )
PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
INT ret = 1;
+ TRACE("%p\n", dev->hdc);
+
if(!physDev->job.id) {
FIXME("hJob == 0. Now what?\n");
return 0;
--
2.7.1

View File

@ -0,0 +1 @@
Fixes: Various improvements for wineps.drv for Adobe PageMaker compatibility