From: Piotr Caban piotr@codeweavers.com
--- dlls/localspl/provider.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/dlls/localspl/provider.c b/dlls/localspl/provider.c index 56014461012..9e990c75e0f 100644 --- a/dlls/localspl/provider.c +++ b/dlls/localspl/provider.c @@ -3816,7 +3816,8 @@ static BOOL WINAPI fpScheduleJob(HANDLE hprinter, DWORD job_id) pp->close(hpp); print_proc_unload(pp);
- DeleteFileW(job->filename); + if (!(printer->info->attributes & PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS)) + DeleteFileW(job->filename); free_job(job); LeaveCriticalSection(&printer->info->jobs_cs); return ret;
From: Piotr Caban piotr@codeweavers.com
--- dlls/gdi32/dc.c | 90 ++++++++++++++++++++++++++++++++++++---- dlls/gdi32/emfdc.c | 14 ------- dlls/gdi32/gdi_private.h | 2 + dlls/gdi32/text.c | 1 + 4 files changed, 85 insertions(+), 22 deletions(-)
diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c index 011bded3523..72e30647943 100644 --- a/dlls/gdi32/dc.c +++ b/dlls/gdi32/dc.c @@ -51,10 +51,17 @@ struct graphics_driver driver_entry_point entry_point; };
+enum print_flags +{ + CALL_START_PAGE = 0x1, + CALL_END_PAGE = 0x2 +}; + struct print { HANDLE printer; WCHAR *output; + enum print_flags flags; };
DC_ATTR *get_dc_attr( HDC hdc ) @@ -288,6 +295,7 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output, } print->printer = hspool; print->output = port; + print->flags = 0; dc_attr->print = (UINT_PTR)print; } else if (hspool) @@ -410,6 +418,13 @@ static inline struct print *get_dc_print( DC_ATTR *dc_attr ) return (struct print *)(UINT_PTR)dc_attr->print; }
+void print_call_start_page( DC_ATTR *dc_attr ) +{ + struct print *print = get_dc_print( dc_attr ); + + if (print->flags & CALL_START_PAGE) StartPage( UlongToHandle(dc_attr->hdc) ); +} + static void delete_print_dc( DC_ATTR *dc_attr ) { struct print *print = get_dc_print( dc_attr ); @@ -1284,6 +1299,7 @@ COLORREF WINAPI SetPixel( HDC hdc, INT x, INT y, COLORREF color )
if (is_meta_dc( hdc )) return METADC_SetPixel( hdc, x, y, color ); if (!(dc_attr = get_dc_attr( hdc ))) return CLR_INVALID; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_SetPixel( dc_attr, x, y, color )) return CLR_INVALID; return NtGdiSetPixel( hdc, x, y, color ); } @@ -1307,6 +1323,7 @@ BOOL WINAPI LineTo( HDC hdc, INT x, INT y )
if (is_meta_dc( hdc )) return METADC_LineTo( hdc, x, y ); if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_LineTo( dc_attr, x, y )) return FALSE; return NtGdiLineTo( hdc, x, y ); } @@ -1342,6 +1359,7 @@ BOOL WINAPI Arc( HDC hdc, INT left, INT top, INT right, INT bottom, xstart, ystart, xend, yend );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_ArcChordPie( dc_attr, left, top, right, bottom, xstart, ystart, xend, yend, EMR_ARC )) return FALSE; @@ -1362,6 +1380,7 @@ BOOL WINAPI ArcTo( HDC hdc, INT left, INT top, INT right, INT bottom, right, bottom, xstart, ystart, xend, yend );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_ArcChordPie( dc_attr, left, top, right, bottom, xstart, ystart, xend, yend, EMR_ARCTO )) return FALSE; @@ -1386,6 +1405,7 @@ BOOL WINAPI Chord( HDC hdc, INT left, INT top, INT right, INT bottom, xstart, ystart, xend, yend );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_ArcChordPie( dc_attr, left, top, right, bottom, xstart, ystart, xend, yend, EMR_CHORD )) return FALSE; @@ -1410,6 +1430,7 @@ BOOL WINAPI Pie( HDC hdc, INT left, INT top, INT right, INT bottom, xstart, ystart, xend, yend );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_ArcChordPie( dc_attr, left, top, right, bottom, xstart, ystart, xend, yend, EMR_PIE )) return FALSE; @@ -1428,6 +1449,7 @@ BOOL WINAPI AngleArc( HDC hdc, INT x, INT y, DWORD radius, FLOAT start_angle, FL TRACE( "%p, (%d, %d), %lu, %f, %f\n", hdc, x, y, radius, start_angle, sweep_angle );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_AngleArc( dc_attr, x, y, radius, start_angle, sweep_angle )) return FALSE; return NtGdiAngleArc( hdc, x, y, radius, start_angle, sweep_angle ); @@ -1444,6 +1466,7 @@ BOOL WINAPI Ellipse( HDC hdc, INT left, INT top, INT right, INT bottom )
if (is_meta_dc( hdc )) return METADC_Ellipse( hdc, left, top, right, bottom ); if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_Ellipse( dc_attr, left, top, right, bottom )) return FALSE; return NtGdiEllipse( hdc, left, top, right, bottom ); } @@ -1459,6 +1482,7 @@ BOOL WINAPI Rectangle( HDC hdc, INT left, INT top, INT right, INT bottom )
if (is_meta_dc( hdc )) return METADC_Rectangle( hdc, left, top, right, bottom ); if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_Rectangle( dc_attr, left, top, right, bottom )) return FALSE; return NtGdiRectangle( hdc, left, top, right, bottom ); } @@ -1478,6 +1502,7 @@ BOOL WINAPI RoundRect( HDC hdc, INT left, INT top, INT right, return METADC_RoundRect( hdc, left, top, right, bottom, ell_width, ell_height );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_RoundRect( dc_attr, left, top, right, bottom, ell_width, ell_height )) return FALSE; @@ -1496,6 +1521,7 @@ BOOL WINAPI Polygon( HDC hdc, const POINT *points, INT count )
if (is_meta_dc( hdc )) return METADC_Polygon( hdc, points, count ); if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_Polygon( dc_attr, points, count )) return FALSE; return NtGdiPolyPolyDraw( hdc, points, (const ULONG *)&count, 1, NtGdiPolyPolygon ); } @@ -1511,6 +1537,7 @@ BOOL WINAPI PolyPolygon( HDC hdc, const POINT *points, const INT *counts, UINT p
if (is_meta_dc( hdc )) return METADC_PolyPolygon( hdc, points, counts, polygons ); if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_PolyPolygon( dc_attr, points, counts, polygons )) return FALSE; return NtGdiPolyPolyDraw( hdc, points, (const ULONG *)counts, polygons, NtGdiPolyPolygon ); } @@ -1526,6 +1553,7 @@ BOOL WINAPI Polyline( HDC hdc, const POINT *points, INT count )
if (is_meta_dc( hdc )) return METADC_Polyline( hdc, points, count ); if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_Polyline( dc_attr, points, count )) return FALSE; return NtGdiPolyPolyDraw( hdc, points, (const ULONG *)&count, 1, NtGdiPolyPolyline ); } @@ -1540,6 +1568,7 @@ BOOL WINAPI PolyPolyline( HDC hdc, const POINT *points, const DWORD *counts, DWO TRACE( "%p, %p, %p, %lu\n", hdc, points, counts, polylines );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_PolyPolyline( dc_attr, points, counts, polylines )) return FALSE; return NtGdiPolyPolyDraw( hdc, points, counts, polylines, NtGdiPolyPolyline ); } @@ -1554,6 +1583,7 @@ BOOL WINAPI PolyBezier( HDC hdc, const POINT *points, DWORD count ) TRACE( "%p, %p, %lu\n", hdc, points, count );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_PolyBezier( dc_attr, points, count )) return FALSE; return NtGdiPolyPolyDraw( hdc, points, &count, 1, NtGdiPolyBezier ); } @@ -1568,6 +1598,7 @@ BOOL WINAPI PolyBezierTo( HDC hdc, const POINT *points, DWORD count ) TRACE( "%p, %p, %lu\n", hdc, points, count );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_PolyBezierTo( dc_attr, points, count )) return FALSE; return NtGdiPolyPolyDraw( hdc, points, &count, 1, NtGdiPolyBezierTo ); } @@ -1582,6 +1613,7 @@ BOOL WINAPI PolylineTo( HDC hdc, const POINT *points, DWORD count ) TRACE( "%p, %p, %lu\n", hdc, points, count );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_PolylineTo( dc_attr, points, count )) return FALSE; return NtGdiPolyPolyDraw( hdc, points, &count, 1, NtGdiPolylineTo ); } @@ -1596,6 +1628,7 @@ BOOL WINAPI PolyDraw( HDC hdc, const POINT *points, const BYTE *types, DWORD cou TRACE( "%p, %p, %p, %lu\n", hdc, points, types, count );
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_PolyDraw( dc_attr, points, types, count )) return FALSE; return NtGdiPolyDraw( hdc, points, types, count ); } @@ -1611,6 +1644,7 @@ BOOL WINAPI FillRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush )
if (is_meta_dc( hdc )) return METADC_FillRgn( hdc, hrgn, hbrush ); if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_FillRgn( dc_attr, hrgn, hbrush )) return FALSE; return NtGdiFillRgn( hdc, hrgn, hbrush ); } @@ -1626,6 +1660,7 @@ BOOL WINAPI PaintRgn( HDC hdc, HRGN hrgn )
if (is_meta_dc( hdc )) return METADC_PaintRgn( hdc, hrgn ); if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_PaintRgn( dc_attr, hrgn )) return FALSE; return NtGdiFillRgn( hdc, hrgn, GetCurrentObject( hdc, OBJ_BRUSH )); } @@ -1641,6 +1676,7 @@ BOOL WINAPI FrameRgn( HDC hdc, HRGN hrgn, HBRUSH hbrush, INT width, INT height )
if (is_meta_dc( hdc )) return METADC_FrameRgn( hdc, hrgn, hbrush, width, height ); if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_FrameRgn( dc_attr, hrgn, hbrush, width, height )) return FALSE; return NtGdiFrameRgn( hdc, hrgn, hbrush, width, height ); @@ -1657,6 +1693,7 @@ BOOL WINAPI InvertRgn( HDC hdc, HRGN hrgn )
if (is_meta_dc( hdc )) return METADC_InvertRgn( hdc, hrgn ); if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_InvertRgn( dc_attr, hrgn )) return FALSE; return NtGdiInvertRgn( hdc, hrgn ); } @@ -1672,6 +1709,7 @@ BOOL WINAPI ExtFloodFill( HDC hdc, INT x, INT y, COLORREF color, UINT fill_type
if (is_meta_dc( hdc )) return METADC_ExtFloodFill( hdc, x, y, color, fill_type ); if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_ExtFloodFill( dc_attr, x, y, color, fill_type )) return FALSE; return NtGdiExtFloodFill( hdc, x, y, color, fill_type ); } @@ -1700,6 +1738,7 @@ BOOL WINAPI GdiGradientFill( HDC hdc, TRIVERTEX *vert_array, ULONG nvert, SetLastError( ERROR_INVALID_PARAMETER ); return FALSE; } + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_GradientFill( dc_attr, vert_array, nvert, grad_array, ngrad, mode )) return FALSE; @@ -1729,6 +1768,7 @@ BOOL WINAPI PatBlt( HDC hdc, INT left, INT top, INT width, INT height, DWORD rop
if (is_meta_dc( hdc )) return METADC_PatBlt( hdc, left, top, width, height, rop ); if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_PatBlt( dc_attr, left, top, width, height, rop )) return FALSE; return NtGdiPatBlt( hdc, left, top, width, height, rop ); @@ -1745,6 +1785,7 @@ BOOL WINAPI DECLSPEC_HOTPATCH BitBlt( HDC hdc_dst, INT x_dst, INT y_dst, INT wid if (is_meta_dc( hdc_dst )) return METADC_BitBlt( hdc_dst, x_dst, y_dst, width, height, hdc_src, x_src, y_src, rop ); if (!(dc_attr = get_dc_attr( hdc_dst ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_BitBlt( dc_attr, x_dst, y_dst, width, height, hdc_src, x_src, y_src, rop )) return FALSE; @@ -1765,6 +1806,7 @@ BOOL WINAPI StretchBlt( HDC hdc, INT x_dst, INT y_dst, INT width_dst, INT height hdc_src, x_src, y_src, width_src, height_src, rop ); if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_StretchBlt( dc_attr, x_dst, y_dst, width_dst, height_dst, hdc_src, x_src, y_src, width_src, height_src, rop )) @@ -1784,6 +1826,7 @@ BOOL WINAPI MaskBlt( HDC hdc, INT x_dst, INT y_dst, INT width_dst, INT height_ds DC_ATTR *dc_attr;
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_MaskBlt( dc_attr, x_dst, y_dst, width_dst, height_dst, hdc_src, x_src, y_src, mask, x_mask, y_mask, rop )) return FALSE; @@ -1800,6 +1843,7 @@ BOOL WINAPI PlgBlt( HDC hdc, const POINT *points, HDC hdc_src, INT x_src, INT y_ DC_ATTR *dc_attr;
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_PlgBlt( dc_attr, points, hdc_src, x_src, y_src, width, height, mask, x_mask, y_mask )) return FALSE; @@ -1817,6 +1861,7 @@ BOOL WINAPI GdiTransparentBlt( HDC hdc, int x_dst, int y_dst, int width_dst, int DC_ATTR *dc_attr;
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_TransparentBlt( dc_attr, x_dst, y_dst, width_dst, height_dst, hdc_src, x_src, y_src, width_src, height_src, color )) return FALSE; @@ -1834,6 +1879,7 @@ BOOL WINAPI GdiAlphaBlend( HDC hdc_dst, int x_dst, int y_dst, int width_dst, int DC_ATTR *dc_attr;
if (!(dc_attr = get_dc_attr( hdc_dst ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_AlphaBlend( dc_attr, x_dst, y_dst, width_dst, height_dst, hdc_src, x_src, y_src, width_src, height_src, blend_function )) @@ -1857,6 +1903,7 @@ INT WINAPI SetDIBitsToDevice( HDC hdc, INT x_dst, INT y_dst, DWORD cx, return METADC_SetDIBitsToDevice( hdc, x_dst, y_dst, cx, cy, x_src, y_src, startscan, lines, bits, bmi, coloruse ); if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_SetDIBitsToDevice( dc_attr, x_dst, y_dst, cx, cy, x_src, y_src, startscan, lines, bits, bmi, coloruse )) return 0; @@ -1879,6 +1926,7 @@ INT WINAPI DECLSPEC_HOTPATCH StretchDIBits( HDC hdc, INT x_dst, INT y_dst, INT w return METADC_StretchDIBits( hdc, x_dst, y_dst, width_dst, height_dst, x_src, y_src, width_src, height_src, bits, bmi, coloruse, rop ); if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_StretchDIBits( dc_attr, x_dst, y_dst, width_dst, height_dst, x_src, y_src, width_src, height_src, bits, bmi, coloruse, rop )) @@ -1944,6 +1992,7 @@ BOOL WINAPI FillPath( HDC hdc ) DC_ATTR *dc_attr;
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_FillPath( dc_attr )) return FALSE; return NtGdiFillPath( hdc ); } @@ -1956,6 +2005,7 @@ BOOL WINAPI StrokeAndFillPath( HDC hdc ) DC_ATTR *dc_attr;
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_StrokeAndFillPath( dc_attr )) return FALSE; return NtGdiStrokeAndFillPath( hdc ); } @@ -1968,6 +2018,7 @@ BOOL WINAPI StrokePath( HDC hdc ) DC_ATTR *dc_attr;
if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_StrokePath( dc_attr )) return FALSE; return NtGdiStrokePath( hdc ); } @@ -2266,6 +2317,7 @@ INT WINAPI StartDocW( HDC hdc, const DOCINFOW *doc ) ret = 0; } HeapFree( GetProcessHeap(), 0, output ); + print->flags |= CALL_START_PAGE; return ret; } } @@ -2273,6 +2325,7 @@ INT WINAPI StartDocW( HDC hdc, const DOCINFOW *doc )
ret = NtGdiStartDoc( hdc, &info, NULL, 0 ); HeapFree( GetProcessHeap(), 0, output ); + if (ret && print) print->flags |= CALL_START_PAGE; return ret; }
@@ -2329,8 +2382,13 @@ INT WINAPI StartPage( HDC hdc ) DC_ATTR *dc_attr;
if (!(dc_attr = get_dc_attr( hdc ))) return SP_ERROR; - if ((print = get_dc_print( dc_attr )) && dc_attr->emf) - return spool_start_page( dc_attr, print->printer ); + print = get_dc_print( dc_attr ); + if (print) + { + print->flags = (print->flags & ~CALL_START_PAGE) | CALL_END_PAGE; + if (dc_attr->emf) + return spool_start_page( dc_attr, print->printer ); + } return NtGdiStartPage( hdc ); }
@@ -2343,8 +2401,13 @@ INT WINAPI EndPage( HDC hdc ) DC_ATTR *dc_attr;
if (!(dc_attr = get_dc_attr( hdc ))) return SP_ERROR; - if ((print = get_dc_print( dc_attr )) && dc_attr->emf) - return spool_end_page( dc_attr, print->printer ); + print = get_dc_print( dc_attr ); + if (print) + { + print->flags = (print->flags & ~CALL_END_PAGE) | CALL_START_PAGE; + if (dc_attr->emf) + return spool_end_page( dc_attr, print->printer ); + } return NtGdiEndPage( hdc ); }
@@ -2357,8 +2420,14 @@ INT WINAPI EndDoc( HDC hdc ) DC_ATTR *dc_attr;
if (!(dc_attr = get_dc_attr( hdc ))) return SP_ERROR; - if ((print = get_dc_print( dc_attr )) && dc_attr->emf) - return spool_end_doc( dc_attr, print->printer ); + print = get_dc_print( dc_attr ); + if (print) + { + if (print->flags & CALL_END_PAGE) EndPage( hdc ); + print->flags &= ~CALL_START_PAGE; + if (dc_attr->emf) + return spool_end_doc( dc_attr, print->printer ); + } return NtGdiEndDoc( hdc ); }
@@ -2371,8 +2440,13 @@ INT WINAPI AbortDoc( HDC hdc ) DC_ATTR *dc_attr;
if (!(dc_attr = get_dc_attr( hdc ))) return SP_ERROR; - if ((print = get_dc_print( dc_attr )) && dc_attr->emf) - return spool_abort_doc( dc_attr, print->printer ); + print = get_dc_print( dc_attr ); + if (print) + { + print->flags &= ~(CALL_START_PAGE | CALL_END_PAGE); + if (dc_attr->emf) + return spool_abort_doc( dc_attr, print->printer ); + } return NtGdiAbortDoc( hdc ); }
diff --git a/dlls/gdi32/emfdc.c b/dlls/gdi32/emfdc.c index 9690bee2a17..f580f21fc1e 100644 --- a/dlls/gdi32/emfdc.c +++ b/dlls/gdi32/emfdc.c @@ -44,12 +44,6 @@ struct emf DWORD palette_size; DWORD palette_used; PALETTEENTRY *palette; - enum - { - DOCUMENT_NOT_STARTED, - NEEDS_START_PAGE, - NEEDS_END_PAGE - } document_state; };
typedef enum @@ -2505,7 +2499,6 @@ static void emf_reset( DC_ATTR *dc_attr, const RECT *rect ) emf->dc_pen = 0; emf->path = FALSE; emf->palette_used = 0; - emf->document_state = DOCUMENT_NOT_STARTED;
dc_attr->emf_bounds.left = dc_attr->emf_bounds.top = 0; dc_attr->emf_bounds.right = dc_attr->emf_bounds.bottom = -1; @@ -2772,13 +2765,11 @@ BOOL spool_start_doc( DC_ATTR *dc_attr, HANDLE hspool, const DOCINFOW *doc_info
emf = emf_create( dc_attr_handle(dc_attr), NULL, NULL ); if (!emf) return FALSE; - emf->document_state = NEEDS_START_PAGE; return TRUE; }
int spool_start_page( DC_ATTR *dc_attr, HANDLE hspool ) { - struct emf *emf = get_dc_emf( dc_attr ); HDC hdc = dc_attr_handle( dc_attr ); POINT pos = { 0 }; XFORM xform; @@ -2813,7 +2804,6 @@ int spool_start_page( DC_ATTR *dc_attr, HANDLE hspool ) if (xform.eM11 != 1 || xform.eM22 != 1 || xform.eM12 || xform.eM21 || xform.eDx || xform.eDy) EMFDC_SetWorldTransform( dc_attr, &xform );
- emf->document_state = NEEDS_END_PAGE; return StartPagePrinter( hspool ); }
@@ -2847,7 +2837,6 @@ int spool_end_page( DC_ATTR *dc_attr, HANDLE hspool ) if (!WritePrinter( hspool, &metafile_ext, sizeof(metafile_ext), &written )) return 0;
emf_reset( dc_attr, NULL ); - emf->document_state = NEEDS_START_PAGE; return EndPagePrinter( hspool ); }
@@ -2861,11 +2850,8 @@ int spool_abort_doc( DC_ATTR *dc_attr, HANDLE hspool )
int spool_end_doc( DC_ATTR *dc_attr, HANDLE hspool ) { - struct emf *emf = get_dc_emf( dc_attr ); - TRACE( "(%p %p)\n", dc_attr, hspool );
- if (emf->document_state == NEEDS_END_PAGE) spool_end_page( dc_attr, hspool ); EMFDC_DeleteDC( dc_attr ); return EndDocPrinter( hspool ); } diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 157e438c687..6f8f4630b6f 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -287,6 +287,8 @@ extern int spool_end_page( DC_ATTR *dc_attr, HANDLE hspool ) DECLSPEC_HIDDEN; extern int spool_end_doc( DC_ATTR *dc_attr, HANDLE hspool ) DECLSPEC_HIDDEN; extern int spool_abort_doc( DC_ATTR *dc_attr, HANDLE hspool ) DECLSPEC_HIDDEN;
+extern void print_call_start_page( DC_ATTR *dc_attr ) DECLSPEC_HIDDEN; + static inline int get_dib_stride( int width, int bpp ) { return ((width * bpp + 31) >> 3) & ~3; diff --git a/dlls/gdi32/text.c b/dlls/gdi32/text.c index b0134e529f5..3dd50491e08 100644 --- a/dlls/gdi32/text.c +++ b/dlls/gdi32/text.c @@ -939,6 +939,7 @@ BOOL WINAPI ExtTextOutW( HDC hdc, INT x, INT y, UINT flags, const RECT *rect, if (count > INT_MAX) return FALSE; if (is_meta_dc( hdc )) return METADC_ExtTextOut( hdc, x, y, flags, rect, str, count, dx ); if (!(dc_attr = get_dc_attr( hdc ))) return FALSE; + if (dc_attr->print) print_call_start_page( dc_attr ); if (dc_attr->emf && !EMFDC_ExtTextOut( dc_attr, x, y, flags, rect, str, count, dx )) return FALSE;
From: Piotr Caban piotr@codeweavers.com
--- dlls/gdi32/dc.c | 51 +++++++++++++++++++++++++++++++++++----- dlls/gdi32/emfdc.c | 13 +++++++++- dlls/gdi32/gdi_private.h | 3 ++- 3 files changed, 59 insertions(+), 8 deletions(-)
diff --git a/dlls/gdi32/dc.c b/dlls/gdi32/dc.c index 72e30647943..b1ca342f8e3 100644 --- a/dlls/gdi32/dc.c +++ b/dlls/gdi32/dc.c @@ -54,7 +54,8 @@ struct graphics_driver enum print_flags { CALL_START_PAGE = 0x1, - CALL_END_PAGE = 0x2 + CALL_END_PAGE = 0x2, + WRITE_DEVMODE = 0x4, };
struct print @@ -62,6 +63,7 @@ struct print HANDLE printer; WCHAR *output; enum print_flags flags; + DEVMODEW *devmode; };
DC_ATTR *get_dc_attr( HDC hdc ) @@ -202,6 +204,29 @@ done: return driver->entry_point; }
+static BOOL print_copy_devmode( struct print *print, const DEVMODEW *devmode ) +{ + size_t size; + + if (!print) return TRUE; + if (!print->devmode && !devmode) return TRUE; + HeapFree( GetProcessHeap(), 0, print->devmode ); + + if (!devmode) + { + print->devmode = NULL; + print->flags |= WRITE_DEVMODE; + return TRUE; + } + + size = devmode->dmSize + devmode->dmDriverExtra; + print->devmode = HeapAlloc( GetProcessHeap(), 0, size ); + if (!print->devmode) return FALSE; + memcpy(print->devmode, devmode, size); + print->flags |= WRITE_DEVMODE; + return TRUE; +} + /*********************************************************************** * CreateDCW (GDI32.@) */ @@ -262,10 +287,13 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output, ClosePrinter( hspool ); return 0; } - else if (!(print = HeapAlloc( GetProcessHeap(), 0, sizeof(*print) ))) + else if (!(print = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*print) )) || + !print_copy_devmode( print, devmode )) { + HeapFree( GetProcessHeap(), 0, print ); ClosePrinter( hspool ); HeapFree( GetProcessHeap(), 0, port ); + return 0; }
if (display) @@ -295,13 +323,13 @@ HDC WINAPI CreateDCW( LPCWSTR driver, LPCWSTR device, LPCWSTR output, } print->printer = hspool; print->output = port; - print->flags = 0; dc_attr->print = (UINT_PTR)print; } else if (hspool) { ClosePrinter( hspool ); HeapFree( GetProcessHeap(), 0, port ); + HeapFree( GetProcessHeap(), 0, print->devmode ); HeapFree( GetProcessHeap(), 0, print ); }
@@ -431,6 +459,7 @@ static void delete_print_dc( DC_ATTR *dc_attr )
ClosePrinter( print->printer ); HeapFree( GetProcessHeap(), 0, print->output ); + HeapFree( GetProcessHeap(), 0, print->devmode ); HeapFree( GetProcessHeap(), 0, print ); dc_attr->print = 0; } @@ -471,7 +500,15 @@ HDC WINAPI ResetDCA( HDC hdc, const DEVMODEA *devmode ) */ HDC WINAPI ResetDCW( HDC hdc, const DEVMODEW *devmode ) { - return NtGdiResetDC( hdc, devmode, NULL, NULL, NULL ) ? hdc : 0; + struct print *print; + DC_ATTR *dc_attr; + + if (!(dc_attr = get_dc_attr( hdc ))) return 0; + print = get_dc_print( dc_attr ); + if (print && print->flags & CALL_END_PAGE) return 0; + if (!NtGdiResetDC( hdc, devmode, NULL, NULL, NULL )) return 0; + if (print && !print_copy_devmode( print, devmode )) return 0; + return hdc; }
/*********************************************************************** @@ -2404,9 +2441,11 @@ INT WINAPI EndPage( HDC hdc ) print = get_dc_print( dc_attr ); if (print) { - print->flags = (print->flags & ~CALL_END_PAGE) | CALL_START_PAGE; + BOOL write = print->flags & WRITE_DEVMODE; + + print->flags = (print->flags & ~(CALL_END_PAGE | WRITE_DEVMODE)) | CALL_START_PAGE; if (dc_attr->emf) - return spool_end_page( dc_attr, print->printer ); + return spool_end_page( dc_attr, print->printer, print->devmode, write ); } return NtGdiEndPage( hdc ); } diff --git a/dlls/gdi32/emfdc.c b/dlls/gdi32/emfdc.c index f580f21fc1e..ef316fe42a1 100644 --- a/dlls/gdi32/emfdc.c +++ b/dlls/gdi32/emfdc.c @@ -2807,7 +2807,7 @@ int spool_start_page( DC_ATTR *dc_attr, HANDLE hspool ) return StartPagePrinter( hspool ); }
-int spool_end_page( DC_ATTR *dc_attr, HANDLE hspool ) +int spool_end_page( DC_ATTR *dc_attr, HANDLE hspool, const DEVMODEW *devmode, BOOL write_devmode ) { struct record_hdr { @@ -2831,9 +2831,20 @@ int spool_end_page( DC_ATTR *dc_attr, HANDLE hspool ) if (!WritePrinter( hspool, &record_hdr, sizeof(record_hdr), &written )) return 0; if (!WritePrinter( hspool, emf->emh, emf->emh->nBytes, &written )) return 0;
+ if (write_devmode) + { + record_hdr.ulID = EMRI_DEVMODE; + record_hdr.cjSize = devmode ? devmode->dmSize + devmode->dmDriverExtra : 0; + if (!WritePrinter( hspool, &record_hdr, sizeof(record_hdr), &written )) return 0; + if (devmode && !WritePrinter( hspool, (BYTE *)devmode, + record_hdr.cjSize, &written )) return 0; + } + metafile_ext.hdr.ulID = EMRI_METAFILE_EXT; metafile_ext.hdr.cjSize = sizeof(metafile_ext) - sizeof(struct record_hdr); metafile_ext.pos.QuadPart = emf->emh->nBytes + sizeof(record_hdr); + if (write_devmode) + metafile_ext.pos.QuadPart += record_hdr.cjSize + sizeof(record_hdr); if (!WritePrinter( hspool, &metafile_ext, sizeof(metafile_ext), &written )) return 0;
emf_reset( dc_attr, NULL ); diff --git a/dlls/gdi32/gdi_private.h b/dlls/gdi32/gdi_private.h index 6f8f4630b6f..b8f914fe1f4 100644 --- a/dlls/gdi32/gdi_private.h +++ b/dlls/gdi32/gdi_private.h @@ -283,7 +283,8 @@ extern HENHMETAFILE EMF_Create_HENHMETAFILE( ENHMETAHEADER *emh, DWORD filesize, extern BOOL spool_start_doc( DC_ATTR *dc_attr, HANDLE hspool, const DOCINFOW *doc_info ) DECLSPEC_HIDDEN; extern int spool_start_page( DC_ATTR *dc_attr, HANDLE hspool ) DECLSPEC_HIDDEN; -extern int spool_end_page( DC_ATTR *dc_attr, HANDLE hspool ) DECLSPEC_HIDDEN; +extern int spool_end_page( DC_ATTR *dc_attr, HANDLE hspool, const DEVMODEW *devmode, + BOOL write_devmode ) DECLSPEC_HIDDEN; extern int spool_end_doc( DC_ATTR *dc_attr, HANDLE hspool ) DECLSPEC_HIDDEN; extern int spool_abort_doc( DC_ATTR *dc_attr, HANDLE hspool ) DECLSPEC_HIDDEN;
From: Piotr Caban piotr@codeweavers.com
--- dlls/wineps.drv/init.c | 2 +- dlls/wineps.drv/printproc.c | 26 +++++++++++++++++++++++++- dlls/wineps.drv/psdrv.h | 1 + 3 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/dlls/wineps.drv/init.c b/dlls/wineps.drv/init.c index 01cfa07e591..39c7e2a4a7f 100644 --- a/dlls/wineps.drv/init.c +++ b/dlls/wineps.drv/init.c @@ -436,7 +436,7 @@ static BOOL CDECL PSDRV_DeleteDC( PHYSDEV dev ) /********************************************************************** * ResetDC (WINEPS.@) */ -static BOOL CDECL PSDRV_ResetDC( PHYSDEV dev, const DEVMODEW *lpInitData ) +BOOL CDECL PSDRV_ResetDC( PHYSDEV dev, const DEVMODEW *lpInitData ) { PSDRV_PDEVICE *physDev = get_psdrv_dev( dev );
diff --git a/dlls/wineps.drv/printproc.c b/dlls/wineps.drv/printproc.c index 9b96b2c1465..9786f5f83df 100644 --- a/dlls/wineps.drv/printproc.c +++ b/dlls/wineps.drv/printproc.c @@ -3228,6 +3228,30 @@ BOOL WINAPI PrintDocumentOnPrintProcessor(HANDLE pp, WCHAR *doc_name)
switch (record.ulID) { + case EMRI_DEVMODE: + { + DEVMODEW *devmode = NULL; + + if (record.cjSize) + { + devmode = malloc(record.cjSize); + if (!devmode) + goto cleanup; + ret = ReadPrinter(spool_data, devmode, record.cjSize, &r); + if (ret && r != record.cjSize) + { + SetLastError(ERROR_INVALID_DATA); + ret = FALSE; + } + } + + if (ret) + ret = PSDRV_ResetDC(&data->pdev->dev, devmode); + free(devmode); + if (!ret) + goto cleanup; + break; + } case EMRI_METAFILE_DATA: pos.QuadPart = record.cjSize; ret = SeekPrinter(spool_data, pos, NULL, FILE_CURRENT, FALSE); @@ -3242,7 +3266,7 @@ BOOL WINAPI PrintDocumentOnPrintProcessor(HANDLE pp, WCHAR *doc_name) { cur.QuadPart += record.cjSize; ret = ReadPrinter(spool_data, &pos, sizeof(pos), &r); - if (r != sizeof(pos)) + if (ret && r != sizeof(pos)) { SetLastError(ERROR_INVALID_DATA); ret = FALSE; diff --git a/dlls/wineps.drv/psdrv.h b/dlls/wineps.drv/psdrv.h index 81cb0206e7e..bfa2807ce6f 100644 --- a/dlls/wineps.drv/psdrv.h +++ b/dlls/wineps.drv/psdrv.h @@ -467,6 +467,7 @@ extern INT CDECL PSDRV_StartDoc( PHYSDEV dev, const DOCINFOW *doc ) DECLSPEC_HID extern BOOL CDECL PSDRV_StrokeAndFillPath( PHYSDEV dev ) DECLSPEC_HIDDEN; extern BOOL CDECL PSDRV_StrokePath( PHYSDEV dev ) DECLSPEC_HIDDEN;
+extern BOOL CDECL PSDRV_ResetDC( PHYSDEV dev, const DEVMODEW *lpInitData ) DECLSPEC_HIDDEN; extern void PSDRV_MergeDevmodes(PSDRV_DEVMODE *dm1, const PSDRV_DEVMODE *dm2, PRINTERINFO *pi) DECLSPEC_HIDDEN; extern BOOL PSDRV_GetFontMetrics(void) DECLSPEC_HIDDEN;
This merge request was approved by Huw Davies.