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