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