1/*
2 * tkMacOSXRegion.c --
3 *
4 *	Implements X window calls for manipulating regions
5 *
6 * Copyright (c) 1995-1996 Sun Microsystems, Inc.
7 * Copyright 2001-2009, Apple Inc.
8 * Copyright (c) 2006-2009 Daniel A. Steffen <das@users.sourceforge.net>
9 *
10 * See the file "license.terms" for information on usage and redistribution
11 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
12 *
13 * RCS: @(#) $Id$
14 */
15
16#include "tkMacOSXPrivate.h"
17
18
19/*
20 *----------------------------------------------------------------------
21 *
22 * TkCreateRegion --
23 *
24 *	Implements the equivelent of the X window function XCreateRegion. See
25 *	Xwindow documentation for more details.
26 *
27 * Results:
28 *	Returns an allocated region handle.
29 *
30 * Side effects:
31 *	None.
32 *
33 *----------------------------------------------------------------------
34 */
35
36TkRegion
37TkCreateRegion(void)
38{
39    return (TkRegion) HIShapeCreateMutable();
40}
41
42/*
43 *----------------------------------------------------------------------
44 *
45 * TkDestroyRegion --
46 *
47 *	Implements the equivelent of the X window function XDestroyRegion. See
48 *	Xwindow documentation for more details.
49 *
50 * Results:
51 *	None.
52 *
53 * Side effects:
54 *	Memory is freed.
55 *
56 *----------------------------------------------------------------------
57 */
58
59void
60TkDestroyRegion(
61    TkRegion r)
62{
63    if (r) {
64	CFRelease(r);
65    }
66}
67
68/*
69 *----------------------------------------------------------------------
70 *
71 * TkIntersectRegion --
72 *
73 *	Implements the equivalent of the X window function XIntersectRegion.
74 *	See Xwindow documentation for more details.
75 *
76 * Results:
77 *	None.
78 *
79 * Side effects:
80 *	None.
81 *
82 *----------------------------------------------------------------------
83 */
84
85void
86TkIntersectRegion(
87    TkRegion sra,
88    TkRegion srb,
89    TkRegion dr_return)
90{
91    ChkErr(HIShapeIntersect, (HIShapeRef) sra, (HIShapeRef) srb,
92	   (HIMutableShapeRef) dr_return);
93}
94
95/*
96 *----------------------------------------------------------------------
97 *
98 * TkSubtractRegion --
99 *
100 *	Implements the equivalent of the X window function XSubtractRegion.
101 *	See X window documentation for more details.
102 *
103 * Results:
104 *	None.
105 *
106 * Side effects:
107 *	None.
108 *
109 *----------------------------------------------------------------------
110 */
111
112void
113TkSubtractRegion(
114    TkRegion sra,
115    TkRegion srb,
116    TkRegion dr_return)
117{
118    ChkErr(HIShapeDifference, (HIShapeRef) sra, (HIShapeRef) srb,
119	   (HIMutableShapeRef) dr_return);
120}
121
122/*
123 *----------------------------------------------------------------------
124 *
125 * TkUnionRectWithRegion --
126 *
127 *	Implements the equivelent of the X window function
128 *	XUnionRectWithRegion. See Xwindow documentation for more details.
129 *
130 * Results:
131 *	None.
132 *
133 * Side effects:
134 *	None.
135 *
136 *----------------------------------------------------------------------
137 */
138
139void
140TkUnionRectWithRegion(
141    XRectangle* rectangle,
142    TkRegion src_region,
143    TkRegion dest_region_return)
144{
145    const CGRect r = CGRectMake(rectangle->x, rectangle->y,
146	    rectangle->width, rectangle->height);
147
148    if (src_region == dest_region_return) {
149	ChkErr(TkMacOSHIShapeUnionWithRect,
150		(HIMutableShapeRef) dest_region_return, &r);
151    } else {
152	HIShapeRef rectRgn = HIShapeCreateWithRect(&r);
153
154	ChkErr(TkMacOSHIShapeUnion, rectRgn, (HIShapeRef) src_region,
155		(HIMutableShapeRef) dest_region_return);
156	CFRelease(rectRgn);
157    }
158}
159
160/*
161 *----------------------------------------------------------------------
162 *
163 * TkRectInRegion --
164 *
165 *	Implements the equivelent of the X window function XRectInRegion. See
166 *	Xwindow documentation for more details.
167 *
168 * Results:
169 *	Returns RectanglePart or RectangleOut. Note that this is not a
170 *	complete implementation since it doesn't test for RectangleIn.
171 *
172 * Side effects:
173 *	None.
174 *
175 *----------------------------------------------------------------------
176 */
177
178int
179TkRectInRegion(
180    TkRegion region,
181    int x,
182    int y,
183    unsigned int width,
184    unsigned int height)
185{
186    int result;
187    const CGRect r = CGRectMake(x, y, width, height);
188
189    result = HIShapeIntersectsRect((HIShapeRef) region, &r) ?
190	    RectanglePart : RectangleOut;
191    return result;
192}
193
194/*
195 *----------------------------------------------------------------------
196 *
197 * TkClipBox --
198 *
199 *	Implements the equivelent of the X window function XClipBox. See
200 *	Xwindow documentation for more details.
201 *
202 * Results:
203 *	None.
204 *
205 * Side effects:
206 *	None.
207 *
208 *----------------------------------------------------------------------
209 */
210
211void
212TkClipBox(
213    TkRegion r,
214    XRectangle* rect_return)
215{
216    CGRect rect;
217
218    HIShapeGetBounds((HIShapeRef) r, &rect);
219    rect_return->x = rect.origin.x;
220    rect_return->y = rect.origin.y;
221    rect_return->width = rect.size.width;
222    rect_return->height = rect.size.height;
223}
224
225/*
226 *----------------------------------------------------------------------
227 *
228 * TkpBuildRegionFromAlphaData --
229 *
230 *	Set up a rectangle of the given region based on the supplied alpha
231 *	data.
232 *
233 * Results:
234 *	None
235 *
236 * Side effects:
237 *	The region is updated, with extra pixels added to it.
238 *
239 *----------------------------------------------------------------------
240 */
241
242void
243TkpBuildRegionFromAlphaData(
244    TkRegion region,			/* Region to update. */
245    unsigned int x,			/* Where in region to update. */
246    unsigned int y,			/* Where in region to update. */
247    unsigned int width,			/* Size of rectangle to update. */
248    unsigned int height,		/* Size of rectangle to update. */
249    unsigned char *dataPtr,		/* Data to read from. */
250    unsigned int pixelStride,		/* num bytes from one piece of alpha
251					 * data to the next in the line. */
252    unsigned int lineStride)		/* num bytes from one line of alpha
253					 * data to the next line. */
254{
255    unsigned char *lineDataPtr;
256    unsigned int x1, y1, end;
257    XRectangle rect;
258
259    for (y1 = 0; y1 < height; y1++) {
260	lineDataPtr = dataPtr;
261	for (x1 = 0; x1 < width; x1 = end) {
262	    /*
263	     * Search for first non-transparent pixel.
264	     */
265
266	    while ((x1 < width) && !*lineDataPtr) {
267		x1++;
268		lineDataPtr += pixelStride;
269	    }
270	    end = x1;
271
272	    /*
273	     * Search for first transparent pixel.
274	     */
275
276	    while ((end < width) && *lineDataPtr) {
277		end++;
278		lineDataPtr += pixelStride;
279	    }
280	    if (end > x1) {
281		rect.x = x + x1;
282		rect.y = y + y1;
283		rect.width = end - x1;
284		rect.height = 1;
285		TkUnionRectWithRegion(&rect, region, region);
286	    }
287	}
288	dataPtr += lineStride;
289    }
290}
291
292/*
293 *----------------------------------------------------------------------
294 *
295 * TkpRetainRegion --
296 *
297 *	Increases reference count of region.
298 *
299 * Results:
300 *	None.
301 *
302 * Side effects:
303 *	None.
304 *
305 *----------------------------------------------------------------------
306 */
307
308void
309TkpRetainRegion(
310    TkRegion r)
311{
312    CFRetain(r);
313}
314
315/*
316 *----------------------------------------------------------------------
317 *
318 * TkpReleaseRegion --
319 *
320 *	Decreases reference count of region.
321 *
322 * Results:
323 *	None.
324 *
325 * Side effects:
326 *	May free memory.
327 *
328 *----------------------------------------------------------------------
329 */
330
331void
332TkpReleaseRegion(
333    TkRegion r)
334{
335    CFRelease(r);
336}
337#if 0
338
339/*
340 *----------------------------------------------------------------------
341 *
342 * TkMacOSXEmtpyRegion --
343 *
344 *	Set region to emtpy.
345 *
346 * Results:
347 *	None.
348 *
349 * Side effects:
350 *	None.
351 *
352 *----------------------------------------------------------------------
353 */
354
355void
356TkMacOSXEmtpyRegion(
357    TkRegion r)
358{
359    ChkErr(HIShapeSetEmpty, (HIMutableShapeRef) r);
360}
361
362/*
363 *----------------------------------------------------------------------
364 *
365 * TkMacOSXIsEmptyRegion --
366 *
367 *	Return native region for given tk region.
368 *
369 * Results:
370 *	1 if empty, 0 otherwise.
371 *
372 * Side effects:
373 *	None.
374 *
375 *----------------------------------------------------------------------
376 */
377
378int
379TkMacOSXIsEmptyRegion(
380    TkRegion r)
381{
382    return HIShapeIsEmpty((HIMutableShapeRef) r) ? 1 : 0;
383}
384#endif
385
386/*
387 *----------------------------------------------------------------------
388 *
389 * TkMacOSXGetNativeRegion --
390 *
391 *	Return native region for given tk region.
392 *
393 * Results:
394 *	Native region, CFRelease when done.
395 *
396 * Side effects:
397 *	None.
398 *
399 *----------------------------------------------------------------------
400 */
401
402HIShapeRef
403TkMacOSXGetNativeRegion(
404    TkRegion r)
405{
406    return (HIShapeRef) CFRetain(r);
407}
408
409/*
410 *----------------------------------------------------------------------
411 *
412 * TkMacOSXSetWithNativeRegion --
413 *
414 *	Set region to the native region.
415 *
416 * Results:
417 *	None.
418 *
419 * Side effects:
420 *	None.
421 *
422 *----------------------------------------------------------------------
423 */
424
425void
426TkMacOSXSetWithNativeRegion(
427    TkRegion r,
428    HIShapeRef rgn)
429{
430    ChkErr(TkMacOSXHIShapeSetWithShape, (HIMutableShapeRef) r, rgn);
431}
432
433/*
434 *----------------------------------------------------------------------
435 *
436 * TkMacOSXOffsetRegion --
437 *
438 *	Offsets region by given distances.
439 *
440 * Results:
441 *	None.
442 *
443 * Side effects:
444 *	None.
445 *
446 *----------------------------------------------------------------------
447 */
448
449void
450TkMacOSXOffsetRegion(
451    TkRegion r,
452    short dx,
453    short dy)
454{
455    ChkErr(HIShapeOffset, (HIMutableShapeRef) r, dx, dy);
456}
457
458/*
459 *----------------------------------------------------------------------
460 *
461 * TkMacOSXHIShapeCreateEmpty, TkMacOSXHIShapeCreateMutableWithRect,
462 * TkMacOSXHIShapeSetWithShape, TkMacOSXHIShapeSetWithRect,
463 * TkMacOSHIShapeDifferenceWithRect, TkMacOSHIShapeUnionWithRect,
464 * TkMacOSHIShapeUnion --
465 *
466 *	Wrapper functions for missing/buggy HIShape API
467 *
468 *----------------------------------------------------------------------
469 */
470
471HIShapeRef
472TkMacOSXHIShapeCreateEmpty(void)
473{
474    HIShapeRef result;
475
476    result = HIShapeCreateEmpty();
477    return result;
478}
479
480HIMutableShapeRef
481TkMacOSXHIShapeCreateMutableWithRect(
482    const CGRect *inRect)
483{
484    HIMutableShapeRef result;
485
486    result = HIShapeCreateMutableWithRect(inRect);
487    return result;
488}
489
490OSStatus
491TkMacOSXHIShapeSetWithShape(
492    HIMutableShapeRef inDestShape,
493    HIShapeRef inSrcShape)
494{
495    OSStatus result;
496
497    result = HIShapeSetWithShape(inDestShape, inSrcShape);
498    return result;
499}
500
501#if 0
502OSStatus
503TkMacOSXHIShapeSetWithRect(
504    HIMutableShapeRef inShape,
505    const CGRect *inRect)
506{
507    OSStatus result;
508    HIShapeRef rgn = HIShapeCreateWithRect(inRect);
509
510    result = TkMacOSXHIShapeSetWithShape(inShape, rgn);
511    CFRelease(rgn);
512
513    return result;
514}
515#endif
516
517OSStatus
518TkMacOSHIShapeDifferenceWithRect(
519    HIMutableShapeRef inShape,
520    const CGRect *inRect)
521{
522    OSStatus result;
523    HIShapeRef rgn = HIShapeCreateWithRect(inRect);
524
525    result = HIShapeDifference(inShape, rgn, inShape);
526    CFRelease(rgn);
527
528    return result;
529}
530
531OSStatus
532TkMacOSHIShapeUnionWithRect(
533    HIMutableShapeRef inShape,
534    const CGRect *inRect)
535{
536    OSStatus result;
537
538    result = HIShapeUnionWithRect(inShape, inRect);
539    return result;
540}
541
542OSStatus
543TkMacOSHIShapeUnion(
544    HIShapeRef inShape1,
545    HIShapeRef inShape2,
546    HIMutableShapeRef outResult)
547{
548    OSStatus result;
549
550    result = HIShapeUnion(inShape1, inShape2, outResult);
551    return result;
552}
553
554/*
555 * Local Variables:
556 * mode: c
557 * c-basic-offset: 4
558 * fill-column: 79
559 * coding: utf-8
560 * End:
561 */
562