Initial commit - from Precise source
[freerdp-ubuntu-pcb-backport.git] / libfreerdp-gdi / clipping.c
1 /**
2  * FreeRDP: A Remote Desktop Protocol Client
3  * GDI Clipping Functions
4  *
5  * Copyright 2010-2011 Marc-Andre Moreau <marcandre.moreau@gmail.com>
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 #include <stdio.h>
21 #include <string.h>
22 #include <stdlib.h>
23 #include <freerdp/freerdp.h>
24 #include <freerdp/gdi/gdi.h>
25
26 #include <freerdp/gdi/region.h>
27
28 #include <freerdp/gdi/clipping.h>
29
30 int gdi_SetClipRgn(HGDI_DC hdc, int nXLeft, int nYLeft, int nWidth, int nHeight)
31 {
32         return gdi_SetRgn(hdc->clip, nXLeft, nYLeft, nWidth, nHeight);
33 }
34
35 /**
36  * Get the current clipping region.\n
37  * @msdn{dd144866}
38  * @param hdc device context
39  * @return clipping region
40  */
41
42 HGDI_RGN gdi_GetClipRgn(HGDI_DC hdc)
43 {
44         return hdc->clip;
45 }
46
47 /**
48  * Set the current clipping region to null.
49  * @param hdc device context
50  * @return
51  */
52
53 int gdi_SetNullClipRgn(HGDI_DC hdc)
54 {
55         gdi_SetClipRgn(hdc, 0, 0, 0, 0);
56         hdc->clip->null = 1;
57         return 0;
58 }
59
60 /**
61  * Clip coordinates according to clipping region
62  * @param hdc device context
63  * @param x x1
64  * @param y y1
65  * @param w width
66  * @param h height
67  * @param srcx source x1
68  * @param srcy source y1
69  * @return 1 if there is something to draw, 0 otherwise
70  */
71
72 int gdi_ClipCoords(HGDI_DC hdc, int *x, int *y, int *w, int *h, int *srcx, int *srcy)
73 {
74         GDI_RECT bmp;
75         GDI_RECT clip;
76         GDI_RECT coords;
77         HGDI_BITMAP hBmp;
78
79         int dx = 0;
80         int dy = 0;
81         int draw = 1;
82
83         if (hdc == NULL)
84                 return 0;
85
86         hBmp = (HGDI_BITMAP) hdc->selectedObject;
87
88         if (hBmp != NULL)
89         {
90                 if (hdc->clip->null)
91                 {
92                         gdi_CRgnToRect(0, 0, hBmp->width, hBmp->height, &clip);
93                 }
94                 else
95                 {
96                         gdi_RgnToRect(hdc->clip, &clip);
97                         gdi_CRgnToRect(0, 0, hBmp->width, hBmp->height, &bmp);
98
99                         if (clip.left < bmp.left)
100                                 clip.left = bmp.left;
101
102                         if (clip.right > bmp.right)
103                                 clip.right = bmp.right;
104
105                         if (clip.top < bmp.top)
106                                 clip.top = bmp.top;
107
108                         if (clip.bottom > bmp.bottom)
109                                 clip.bottom = bmp.bottom;
110                 }
111         }
112         else
113         {
114                 gdi_RgnToRect(hdc->clip, &clip);
115         }
116
117         gdi_CRgnToRect(*x, *y, *w, *h, &coords);
118
119         if (coords.right >= clip.left && coords.left <= clip.right &&
120                 coords.bottom >= clip.top && coords.top <= clip.bottom)
121         {
122                 /* coordinates overlap with clipping region */
123
124                 if (coords.left < clip.left)
125                 {
126                         dx = (clip.left - coords.left) + 1;
127                         coords.left = clip.left;
128                 }
129
130                 if (coords.right > clip.right)
131                         coords.right = clip.right;
132
133                 if (coords.top < clip.top)
134                 {
135                         dy = (clip.top - coords.top) + 1;
136                         coords.top = clip.top;
137                 }
138
139                 if (coords.bottom > clip.bottom)
140                         coords.bottom = clip.bottom;
141         }
142         else
143         {
144                 /* coordinates do not overlap with clipping region */
145
146                 coords.left = 0;
147                 coords.right = 0;
148                 coords.top = 0;
149                 coords.bottom = 0;
150                 draw = 0;
151         }
152
153         if (srcx != NULL)
154         {
155                 if (dx > 0)
156                 {
157                         *srcx += dx - 1;
158                 }
159         }
160
161         if (srcy != NULL)
162         {
163                 if (dy > 0)
164                 {
165                         *srcy += dy - 1;
166                 }
167         }
168
169         gdi_RectToCRgn(&coords, x, y, w, h);
170
171         return draw;
172 }