1 /*
2 * tkWinRegion.c --
3 *
4 * Tk Region emulation code.
5 *
6 * Copyright (c) 1995 Sun Microsystems, Inc.
7 *
8 * See the file "license.terms" for information on usage and redistribution of
9 * this file, and for a DISCLAIMER OF ALL WARRANTIES.
10 */
11
12 #include "tkWinInt.h"
13
14 #undef TkCreateRegion
15 #undef TkDestroyRegion
16 #undef TkClipBox
17 #undef TkIntersectRegion
18 #undef TkUnionRectWithRegion
19 #undef TkRectInRegion
20 #undef TkSubtractRegion
21
22 /*
23 *----------------------------------------------------------------------
24 *
25 * TkCreateRegion --
26 *
27 * Construct an empty region.
28 *
29 * Results:
30 * Returns a new region handle.
31 *
32 * Side effects:
33 * None.
34 *
35 *----------------------------------------------------------------------
36 */
37
38 TkRegion
TkCreateRegion(void)39 TkCreateRegion(void)
40 {
41 RECT rect;
42 memset(&rect, 0, sizeof(RECT));
43 return (TkRegion) CreateRectRgnIndirect(&rect);
44 }
45
46 /*
47 *----------------------------------------------------------------------
48 *
49 * TkDestroyRegion --
50 *
51 * Destroy the specified region.
52 *
53 * Results:
54 * None.
55 *
56 * Side effects:
57 * Frees the storage associated with the specified region.
58 *
59 *----------------------------------------------------------------------
60 */
61
62 void
TkDestroyRegion(TkRegion r)63 TkDestroyRegion(
64 TkRegion r)
65 {
66 DeleteObject((HRGN) r);
67 }
68
69 /*
70 *----------------------------------------------------------------------
71 *
72 * TkClipBox --
73 *
74 * Computes the bounding box of a region.
75 *
76 * Results:
77 * Sets rect_return to the bounding box of the region.
78 *
79 * Side effects:
80 * None.
81 *
82 *----------------------------------------------------------------------
83 */
84
85 void
TkClipBox(TkRegion r,XRectangle * rect_return)86 TkClipBox(
87 TkRegion r,
88 XRectangle* rect_return)
89 {
90 RECT rect;
91
92 GetRgnBox((HRGN)r, &rect);
93 rect_return->x = (short) rect.left;
94 rect_return->y = (short) rect.top;
95 rect_return->width = (short) (rect.right - rect.left);
96 rect_return->height = (short) (rect.bottom - rect.top);
97 }
98
99 /*
100 *----------------------------------------------------------------------
101 *
102 * TkIntersectRegion --
103 *
104 * Compute the intersection of two regions.
105 *
106 * Results:
107 * Returns the result in the dr_return region.
108 *
109 * Side effects:
110 * None.
111 *
112 *----------------------------------------------------------------------
113 */
114
115 void
TkIntersectRegion(TkRegion sra,TkRegion srb,TkRegion dr_return)116 TkIntersectRegion(
117 TkRegion sra,
118 TkRegion srb,
119 TkRegion dr_return)
120 {
121 CombineRgn((HRGN) dr_return, (HRGN) sra, (HRGN) srb, RGN_AND);
122 }
123
124 /*
125 *----------------------------------------------------------------------
126 *
127 * TkUnionRectWithRegion --
128 *
129 * Create the union of a source region and a rectangle.
130 *
131 * Results:
132 * Returns the result in the dr_return region.
133 *
134 * Side effects:
135 * None.
136 *
137 *----------------------------------------------------------------------
138 */
139
140 void
TkUnionRectWithRegion(XRectangle * rectangle,TkRegion src_region,TkRegion dest_region_return)141 TkUnionRectWithRegion(
142 XRectangle *rectangle,
143 TkRegion src_region,
144 TkRegion dest_region_return)
145 {
146 HRGN rectRgn = CreateRectRgn(rectangle->x, rectangle->y,
147 rectangle->x + rectangle->width, rectangle->y + rectangle->height);
148
149 CombineRgn((HRGN) dest_region_return, (HRGN) src_region,
150 (HRGN) rectRgn, RGN_OR);
151 DeleteObject(rectRgn);
152 }
153
154 /*
155 *----------------------------------------------------------------------
156 *
157 * TkpBuildRegionFromAlphaData --
158 *
159 * Set up a rectangle of the given region based on the supplied alpha
160 * data.
161 *
162 * Results:
163 * None
164 *
165 * Side effects:
166 * The region is updated, with extra pixels added to it.
167 *
168 *----------------------------------------------------------------------
169 */
170
171 void
TkpBuildRegionFromAlphaData(TkRegion region,unsigned int x,unsigned int y,unsigned int width,unsigned int height,unsigned char * dataPtr,unsigned int pixelStride,unsigned int lineStride)172 TkpBuildRegionFromAlphaData(
173 TkRegion region,
174 unsigned int x, unsigned int y,
175 /* Where in region to update. */
176 unsigned int width, unsigned int height,
177 /* Size of rectangle to update. */
178 unsigned char *dataPtr, /* Data to read from. */
179 unsigned int pixelStride, /* Num bytes from one piece of alpha data to
180 * the next in the line. */
181 unsigned int lineStride) /* Num bytes from one line of alpha data to
182 * the next line. */
183 {
184 unsigned char *lineDataPtr;
185 unsigned int x1, y1, end;
186 HRGN rectRgn = CreateRectRgn(0,0,1,1); /* Workspace region. */
187
188 for (y1 = 0; y1 < height; y1++) {
189 lineDataPtr = dataPtr;
190 for (x1 = 0; x1 < width; x1 = end) {
191 /*
192 * Search for first non-transparent pixel.
193 */
194
195 while ((x1 < width) && !*lineDataPtr) {
196 x1++;
197 lineDataPtr += pixelStride;
198 }
199 end = x1;
200
201 /*
202 * Search for first transparent pixel.
203 */
204
205 while ((end < width) && *lineDataPtr) {
206 end++;
207 lineDataPtr += pixelStride;
208 }
209 if (end > x1) {
210 /*
211 * Manipulate Win32 regions directly; it's more efficient.
212 */
213
214 SetRectRgn(rectRgn, (int) (x+x1), (int) (y+y1),
215 (int) (x+end), (int) (y+y1+1));
216 CombineRgn((HRGN) region, (HRGN) region, rectRgn, RGN_OR);
217 }
218 }
219 dataPtr += lineStride;
220 }
221
222 DeleteObject(rectRgn);
223 }
224
225 /*
226 *----------------------------------------------------------------------
227 *
228 * TkRectInRegion --
229 *
230 * Test whether a given rectangle overlaps with a region.
231 *
232 * Results:
233 * Returns RectanglePart or RectangleOut. Note that this is not a
234 * complete implementation since it doesn't test for RectangleIn.
235 *
236 * Side effects:
237 * None.
238 *
239 *----------------------------------------------------------------------
240 */
241
242 int
TkRectInRegion(TkRegion r,int x,int y,unsigned int width,unsigned int height)243 TkRectInRegion(
244 TkRegion r, /* Region to inspect */
245 int x, int y, /* Top-left of rectangle */
246 unsigned int width, /* Width of rectangle */
247 unsigned int height) /* Height of rectangle */
248 {
249 RECT rect;
250 rect.top = y;
251 rect.left = x;
252 rect.bottom = y+height;
253 rect.right = x+width;
254 return RectInRegion((HRGN)r, &rect) ? RectanglePart : RectangleOut;
255 }
256
257 /*
258 *----------------------------------------------------------------------
259 *
260 * TkSubtractRegion --
261 *
262 * Compute the set-difference of two regions.
263 *
264 * Results:
265 * Returns the result in the dr_return region.
266 *
267 * Side effects:
268 * None.
269 *
270 *----------------------------------------------------------------------
271 */
272
273 void
TkSubtractRegion(TkRegion sra,TkRegion srb,TkRegion dr_return)274 TkSubtractRegion(
275 TkRegion sra,
276 TkRegion srb,
277 TkRegion dr_return)
278 {
279 CombineRgn((HRGN) dr_return, (HRGN) sra, (HRGN) srb, RGN_DIFF);
280 }
281
282 /*
283 * Local Variables:
284 * mode: c
285 * c-basic-offset: 4
286 * fill-column: 78
287 * End:
288 */
289