Look up the printer's port in the registry if neither CreateDC or
[wine] / dlls / wineps / clipping.c
1 /*
2  *      PostScript clipping functions
3  *
4  *      Copyright 1999  Luc Tourangau
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20
21 #include "psdrv.h"
22 #include "wine/debug.h"
23 #include "winbase.h"
24
25 WINE_DEFAULT_DEBUG_CHANNEL(psdrv);
26
27 /***********************************************************************
28  *           PSDRV_SetDeviceClipping
29  */
30 VOID PSDRV_SetDeviceClipping( PSDRV_PDEVICE *physDev, HRGN ignored )
31 {
32     /* We could set a dirty flag here to speed up PSDRV_SetClip */
33     return;
34 }
35
36 /***********************************************************************
37  *           PSDRV_SetClip
38  *
39  * The idea here is that every graphics operation should bracket
40  * output in PSDRV_SetClip/ResetClip calls.  The clip path outside
41  * these calls will be empty; the reason for this is that it is
42  * impossible in PostScript to cleanly make the clip path larger than
43  * the current one.  Also Photoshop assumes that despite having set a
44  * small clip area in the printer dc that it can still write raw
45  * PostScript to the driver and expect this code not to be clipped.
46  */
47 void PSDRV_SetClip( PSDRV_PDEVICE *physDev )
48 {
49     CHAR szArrayName[] = "clippath";
50     DWORD size;
51     RGNDATA *rgndata = NULL;
52     HRGN hrgn = CreateRectRgn(0,0,0,0);
53     BOOL empty;
54
55     TRACE("hdc=%p\n", physDev->hdc);
56
57     empty = !GetClipRgn(physDev->hdc, hrgn);
58
59     if(!empty) {
60         size = GetRegionData(hrgn, 0, NULL);
61         if(!size) {
62             ERR("Invalid region\n");
63             goto end;
64         }
65
66         rgndata = HeapAlloc( GetProcessHeap(), 0, size );
67         if(!rgndata) {
68             ERR("Can't allocate buffer\n");
69             goto end;
70         }
71
72         GetRegionData(hrgn, size, rgndata);
73
74         PSDRV_WriteGSave(physDev);
75
76         /* check for NULL region */
77         if (rgndata->rdh.nCount == 0)
78         {
79             /* set an empty clip path. */
80             PSDRV_WriteRectClip(physDev, 0, 0, 0, 0);
81         }
82         /* optimize when it is a simple region */
83         else if (rgndata->rdh.nCount == 1)
84         {
85             RECT *pRect = (RECT *)rgndata->Buffer;
86
87             PSDRV_WriteRectClip(physDev, pRect->left, pRect->top,
88                                 pRect->right - pRect->left,
89                                 pRect->bottom - pRect->top);
90         }
91         else
92         {
93             INT i;
94             RECT *pRect = (RECT *)rgndata->Buffer;
95
96             PSDRV_WriteArrayDef(physDev, szArrayName, rgndata->rdh.nCount * 4);
97
98             for (i = 0; i < rgndata->rdh.nCount; i++, pRect++)
99             {
100                 PSDRV_WriteArrayPut(physDev, szArrayName, i * 4,
101                                     pRect->left);
102                 PSDRV_WriteArrayPut(physDev, szArrayName, i * 4 + 1,
103                                     pRect->top);
104                 PSDRV_WriteArrayPut(physDev, szArrayName, i * 4 + 2,
105                                     pRect->right - pRect->left);
106                 PSDRV_WriteArrayPut(physDev, szArrayName, i * 4 + 3,
107                                     pRect->bottom - pRect->top);
108             }
109             PSDRV_WriteRectClip2(physDev, szArrayName);
110         }
111     }
112 end:
113     if(rgndata) HeapFree( GetProcessHeap(), 0, rgndata );
114     DeleteObject(hrgn);
115 }
116
117
118 /***********************************************************************
119  *           PSDRV_ResetClip
120  */
121 void PSDRV_ResetClip( PSDRV_PDEVICE *physDev )
122 {
123     HRGN hrgn = CreateRectRgn(0,0,0,0);
124     BOOL empty;
125
126      empty = !GetClipRgn(physDev->hdc, hrgn);
127      if(!empty)
128          PSDRV_WriteGRestore(physDev);
129     DeleteObject(hrgn);
130 }