Added include protection for unistd.h and sys/time.h.
[wine] / graphics / mapping.c
1 /*
2  * GDI mapping mode functions
3  *
4  * Copyright 1993 Alexandre Julliard
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 "gdi.h"
22 #include "wine/debug.h"
23
24 WINE_DEFAULT_DEBUG_CHANNEL(gdi);
25
26
27 /***********************************************************************
28  *           MAPPING_FixIsotropic
29  *
30  * Fix viewport extensions for isotropic mode.
31  */
32 void MAPPING_FixIsotropic( DC * dc )
33 {
34     double xdim = (double)dc->vportExtX * GetDeviceCaps( dc->hSelf, HORZSIZE ) /
35                   (GetDeviceCaps( dc->hSelf, HORZRES ) * dc->wndExtX);
36     double ydim = (double)dc->vportExtY * GetDeviceCaps( dc->hSelf, VERTSIZE ) /
37                   (GetDeviceCaps( dc->hSelf, VERTRES ) * dc->wndExtY);
38     if (xdim > ydim)
39     {
40         dc->vportExtX = dc->vportExtX * fabs( ydim / xdim );
41         if (!dc->vportExtX) dc->vportExtX = 1;
42     }
43     else
44     {
45         dc->vportExtY = dc->vportExtY * fabs( xdim / ydim );
46         if (!dc->vportExtY) dc->vportExtY = 1;
47     }
48 }
49
50
51 /***********************************************************************
52  *           DPtoLP    (GDI.67)
53  */
54 BOOL16 WINAPI DPtoLP16( HDC16 hdc, LPPOINT16 points, INT16 count )
55 {
56     DC * dc = DC_GetDCPtr( hdc );
57     if (!dc) return FALSE;
58
59     while (count--)
60     {
61         points->x = MulDiv( points->x - dc->vportOrgX, dc->wndExtX, dc->vportExtX ) + dc->wndOrgX;
62         points->y = MulDiv( points->y - dc->vportOrgY, dc->wndExtY, dc->vportExtY ) + dc->wndOrgY;
63         points++;
64     }
65     GDI_ReleaseObj( hdc );
66     return TRUE;
67 }
68
69
70 /***********************************************************************
71  *           DPtoLP    (GDI32.@)
72  */
73 BOOL WINAPI DPtoLP( HDC hdc, LPPOINT points, INT count )
74 {
75     DC * dc = DC_GetDCPtr( hdc );
76     if (!dc) return FALSE;
77
78     if (dc->vport2WorldValid)
79     {
80         while (count--)
81         {
82             FLOAT x = points->x;
83             FLOAT y = points->y;
84             points->x = floor( x * dc->xformVport2World.eM11 +
85                                y * dc->xformVport2World.eM21 +
86                                dc->xformVport2World.eDx + 0.5 );
87             points->y = floor( x * dc->xformVport2World.eM12 +
88                                y * dc->xformVport2World.eM22 +
89                                dc->xformVport2World.eDy + 0.5 );
90             points++;
91         }
92     }
93     GDI_ReleaseObj( hdc );
94     return (count < 0);
95 }
96
97
98 /***********************************************************************
99  *           LPtoDP    (GDI.99)
100  */
101 BOOL16 WINAPI LPtoDP16( HDC16 hdc, LPPOINT16 points, INT16 count )
102 {
103     DC * dc = DC_GetDCPtr( hdc );
104     if (!dc) return FALSE;
105
106     while (count--)
107     {
108         points->x = MulDiv( points->x - dc->wndOrgX, dc->vportExtX, dc->wndExtX ) + dc->vportOrgX;
109         points->y = MulDiv( points->y - dc->wndOrgY, dc->vportExtY, dc->wndExtY ) + dc->vportOrgY;
110         points++;
111     }
112     GDI_ReleaseObj( hdc );
113     return TRUE;
114 }
115
116
117 /***********************************************************************
118  *           LPtoDP    (GDI32.@)
119  */
120 BOOL WINAPI LPtoDP( HDC hdc, LPPOINT points, INT count )
121 {
122     DC * dc = DC_GetDCPtr( hdc );
123     if (!dc) return FALSE;
124
125     while (count--)
126     {
127         FLOAT x = points->x;
128         FLOAT y = points->y;
129         points->x = floor( x * dc->xformWorld2Vport.eM11 +
130                            y * dc->xformWorld2Vport.eM21 +
131                            dc->xformWorld2Vport.eDx + 0.5 );
132         points->y = floor( x * dc->xformWorld2Vport.eM12 +
133                            y * dc->xformWorld2Vport.eM22 +
134                            dc->xformWorld2Vport.eDy + 0.5 );
135         points++;
136     }
137     GDI_ReleaseObj( hdc );
138     return TRUE;
139 }
140
141
142 /***********************************************************************
143  *           SetMapMode    (GDI32.@)
144  */
145 INT WINAPI SetMapMode( HDC hdc, INT mode )
146 {
147     INT prevMode;
148     INT horzSize, vertSize, horzRes, vertRes;
149
150     DC * dc = DC_GetDCPtr( hdc );
151     if (!dc) return 0;
152     if (dc->funcs->pSetMapMode)
153     {
154         prevMode = dc->funcs->pSetMapMode( dc->physDev, mode );
155         goto done;
156     }
157
158     TRACE("%04x %d\n", hdc, mode );
159
160     prevMode = dc->MapMode;
161     horzSize = GetDeviceCaps( hdc, HORZSIZE );
162     vertSize = GetDeviceCaps( hdc, VERTSIZE );
163     horzRes  = GetDeviceCaps( hdc, HORZRES );
164     vertRes  = GetDeviceCaps( hdc, VERTRES );
165     switch(mode)
166     {
167     case MM_TEXT:
168         dc->wndExtX   = 1;
169         dc->wndExtY   = 1;
170         dc->vportExtX = 1;
171         dc->vportExtY = 1;
172         break;
173     case MM_LOMETRIC:
174     case MM_ISOTROPIC:
175         dc->wndExtX   = horzSize;
176         dc->wndExtY   = vertSize;
177         dc->vportExtX = horzRes / 10;
178         dc->vportExtY = vertRes / -10;
179         break;
180     case MM_HIMETRIC:
181         dc->wndExtX   = horzSize * 10;
182         dc->wndExtY   = vertSize * 10;
183         dc->vportExtX = horzRes / 10;
184         dc->vportExtY = vertRes / -10;
185         break;
186     case MM_LOENGLISH:
187         dc->wndExtX   = horzSize;
188         dc->wndExtY   = vertSize;
189         dc->vportExtX = 254L * horzRes / 1000;
190         dc->vportExtY = -254L * vertRes / 1000;
191         break;
192     case MM_HIENGLISH:
193         dc->wndExtX   = horzSize * 10;
194         dc->wndExtY   = vertSize * 10;
195         dc->vportExtX = 254L * horzRes / 1000;
196         dc->vportExtY = -254L * vertRes / 1000;
197         break;
198     case MM_TWIPS:
199         dc->wndExtX   = 144L * horzSize / 10;
200         dc->wndExtY   = 144L * vertSize / 10;
201         dc->vportExtX = 254L * horzRes / 1000;
202         dc->vportExtY = -254L * vertRes / 1000;
203         break;
204     case MM_ANISOTROPIC:
205         break;
206     default:
207         goto done;
208     }
209     dc->MapMode = mode;
210     DC_UpdateXforms( dc );
211  done:
212     GDI_ReleaseObj( hdc );
213     return prevMode;
214 }
215
216
217 /***********************************************************************
218  *           SetViewportExtEx    (GDI32.@)
219  */
220 BOOL WINAPI SetViewportExtEx( HDC hdc, INT x, INT y, LPSIZE size )
221 {
222     BOOL ret = TRUE;
223     DC * dc = DC_GetDCPtr( hdc );
224     if (!dc) return FALSE;
225     if (dc->funcs->pSetViewportExt)
226     {
227         ret = dc->funcs->pSetViewportExt( dc->physDev, x, y );
228         goto done;
229     }
230     if (size)
231     {
232         size->cx = dc->vportExtX;
233         size->cy = dc->vportExtY;
234     }
235     if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
236         goto done;
237     if (!x || !y)
238     {
239         ret = FALSE;
240         goto done;
241     }
242     dc->vportExtX = x;
243     dc->vportExtY = y;
244     if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
245     DC_UpdateXforms( dc );
246  done:
247     GDI_ReleaseObj( hdc );
248     return ret;
249 }
250
251
252 /***********************************************************************
253  *           SetViewportOrgEx    (GDI32.@)
254  */
255 BOOL WINAPI SetViewportOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
256 {
257     BOOL ret = TRUE;
258     DC * dc = DC_GetDCPtr( hdc );
259     if (!dc) return FALSE;
260     if (dc->funcs->pSetViewportOrg)
261         ret = dc->funcs->pSetViewportOrg( dc->physDev, x, y );
262     else
263     {
264         if (pt)
265         {
266             pt->x = dc->vportOrgX;
267             pt->y = dc->vportOrgY;
268         }
269         dc->vportOrgX = x;
270         dc->vportOrgY = y;
271         DC_UpdateXforms( dc );
272     }
273     GDI_ReleaseObj( hdc );
274     return ret;
275 }
276
277
278 /***********************************************************************
279  *           SetWindowExtEx    (GDI32.@)
280  */
281 BOOL WINAPI SetWindowExtEx( HDC hdc, INT x, INT y, LPSIZE size )
282 {
283     BOOL ret = TRUE;
284     DC * dc = DC_GetDCPtr( hdc );
285     if (!dc) return FALSE;
286     if (dc->funcs->pSetWindowExt)
287     {
288         ret = dc->funcs->pSetWindowExt( dc->physDev, x, y );
289         goto done;
290     }
291     if (size)
292     {
293         size->cx = dc->wndExtX;
294         size->cy = dc->wndExtY;
295     }
296     if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
297         goto done;
298     if (!x || !y)
299     {
300         ret = FALSE;
301         goto done;
302     }
303     dc->wndExtX = x;
304     dc->wndExtY = y;
305     if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
306     DC_UpdateXforms( dc );
307  done:
308     GDI_ReleaseObj( hdc );
309     return ret;
310 }
311
312
313 /***********************************************************************
314  *           SetWindowOrgEx    (GDI32.@)
315  */
316 BOOL WINAPI SetWindowOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
317 {
318     BOOL ret = TRUE;
319     DC * dc = DC_GetDCPtr( hdc );
320     if (!dc) return FALSE;
321     if (dc->funcs->pSetWindowOrg) ret = dc->funcs->pSetWindowOrg( dc->physDev, x, y );
322     else
323     {
324         if (pt)
325         {
326             pt->x = dc->wndOrgX;
327             pt->y = dc->wndOrgY;
328         }
329         dc->wndOrgX = x;
330         dc->wndOrgY = y;
331         DC_UpdateXforms( dc );
332     }
333     GDI_ReleaseObj( hdc );
334     return ret;
335 }
336
337
338 /***********************************************************************
339  *           OffsetViewportOrgEx    (GDI32.@)
340  */
341 BOOL WINAPI OffsetViewportOrgEx( HDC hdc, INT x, INT y, LPPOINT pt)
342 {
343     BOOL ret = TRUE;
344     DC * dc = DC_GetDCPtr( hdc );
345     if (!dc) return FALSE;
346     if (dc->funcs->pOffsetViewportOrg)
347         ret = dc->funcs->pOffsetViewportOrg( dc->physDev, x, y );
348     else
349     {
350         if (pt)
351         {
352             pt->x = dc->vportOrgX;
353             pt->y = dc->vportOrgY;
354         }
355         dc->vportOrgX += x;
356         dc->vportOrgY += y;
357         DC_UpdateXforms( dc );
358     }
359     GDI_ReleaseObj( hdc );
360     return ret;
361 }
362
363
364 /***********************************************************************
365  *           OffsetWindowOrgEx    (GDI32.@)
366  */
367 BOOL WINAPI OffsetWindowOrgEx( HDC hdc, INT x, INT y, LPPOINT pt )
368 {
369     BOOL ret = TRUE;
370     DC * dc = DC_GetDCPtr( hdc );
371     if (!dc) return FALSE;
372     if (dc->funcs->pOffsetWindowOrg)
373         ret = dc->funcs->pOffsetWindowOrg( dc->physDev, x, y );
374     else
375     {
376         if (pt)
377         {
378             pt->x = dc->wndOrgX;
379             pt->y = dc->wndOrgY;
380         }
381         dc->wndOrgX += x;
382         dc->wndOrgY += y;
383         DC_UpdateXforms( dc );
384     }
385     GDI_ReleaseObj( hdc );
386     return ret;
387 }
388
389
390 /***********************************************************************
391  *           ScaleViewportExtEx    (GDI32.@)
392  */
393 BOOL WINAPI ScaleViewportExtEx( HDC hdc, INT xNum, INT xDenom,
394                                     INT yNum, INT yDenom, LPSIZE size )
395 {
396     BOOL ret = TRUE;
397     DC * dc = DC_GetDCPtr( hdc );
398     if (!dc) return FALSE;
399     if (dc->funcs->pScaleViewportExt)
400     {
401         ret = dc->funcs->pScaleViewportExt( dc->physDev, xNum, xDenom, yNum, yDenom );
402         goto done;
403     }
404     if (size)
405     {
406         size->cx = dc->vportExtX;
407         size->cy = dc->vportExtY;
408     }
409     if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
410         goto done;
411     if (!xNum || !xDenom || !xNum || !yDenom)
412     {
413         ret = FALSE;
414         goto done;
415     }
416     dc->vportExtX = (dc->vportExtX * xNum) / xDenom;
417     dc->vportExtY = (dc->vportExtY * yNum) / yDenom;
418     if (dc->vportExtX == 0) dc->vportExtX = 1;
419     if (dc->vportExtY == 0) dc->vportExtY = 1;
420     if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
421     DC_UpdateXforms( dc );
422  done:
423     GDI_ReleaseObj( hdc );
424     return ret;
425 }
426
427
428 /***********************************************************************
429  *           ScaleWindowExtEx    (GDI32.@)
430  */
431 BOOL WINAPI ScaleWindowExtEx( HDC hdc, INT xNum, INT xDenom,
432                                   INT yNum, INT yDenom, LPSIZE size )
433 {
434     BOOL ret = TRUE;
435     DC * dc = DC_GetDCPtr( hdc );
436     if (!dc) return FALSE;
437     if (dc->funcs->pScaleWindowExt)
438     {
439         ret = dc->funcs->pScaleWindowExt( dc->physDev, xNum, xDenom, yNum, yDenom );
440         goto done;
441     }
442     if (size)
443     {
444         size->cx = dc->wndExtX;
445         size->cy = dc->wndExtY;
446     }
447     if ((dc->MapMode != MM_ISOTROPIC) && (dc->MapMode != MM_ANISOTROPIC))
448         goto done;
449     if (!xNum || !xDenom || !xNum || !yDenom)
450     {
451         ret = FALSE;
452         goto done;
453     }
454     dc->wndExtX = (dc->wndExtX * xNum) / xDenom;
455     dc->wndExtY = (dc->wndExtY * yNum) / yDenom;
456     if (dc->wndExtX == 0) dc->wndExtX = 1;
457     if (dc->wndExtY == 0) dc->wndExtY = 1;
458     if (dc->MapMode == MM_ISOTROPIC) MAPPING_FixIsotropic( dc );
459     DC_UpdateXforms( dc );
460  done:
461     GDI_ReleaseObj( hdc );
462     return ret;
463 }