summaryrefslogtreecommitdiffstats
path: root/carbon/tkMacOSXRegion.c
diff options
context:
space:
mode:
Diffstat (limited to 'carbon/tkMacOSXRegion.c')
-rw-r--r--carbon/tkMacOSXRegion.c644
1 files changed, 644 insertions, 0 deletions
diff --git a/carbon/tkMacOSXRegion.c b/carbon/tkMacOSXRegion.c
new file mode 100644
index 0000000..e2faab0
--- /dev/null
+++ b/carbon/tkMacOSXRegion.c
@@ -0,0 +1,644 @@
+/*
+ * tkMacOSXRegion.c --
+ *
+ * Implements X window calls for manipulating regions
+ *
+ * Copyright (c) 1995-1996 Sun Microsystems, Inc.
+ * Copyright 2001, Apple Computer, Inc.
+ * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net>
+ *
+ * See the file "license.terms" for information on usage and redistribution of
+ * this file, and for a DISCLAIMER OF ALL WARRANTIES.
+ */
+
+#include "tkMacOSXPrivate.h"
+
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkCreateRegion --
+ *
+ * Implements the equivelent of the X window function XCreateRegion. See
+ * Xwindow documentation for more details.
+ *
+ * Results:
+ * Returns an allocated region handle.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+TkRegion
+TkCreateRegion(void)
+{
+ return (TkRegion) HIShapeCreateMutable();
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkDestroyRegion --
+ *
+ * Implements the equivelent of the X window function XDestroyRegion. See
+ * Xwindow documentation for more details.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * Memory is freed.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkDestroyRegion(
+ TkRegion r)
+{
+ if (r) {
+ CFRelease(r);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkIntersectRegion --
+ *
+ * Implements the equivalent of the X window function XIntersectRegion.
+ * See Xwindow documentation for more details.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkIntersectRegion(
+ TkRegion sra,
+ TkRegion srb,
+ TkRegion dr_return)
+{
+ ChkErr(HIShapeIntersect, (HIShapeRef) sra, (HIShapeRef) srb,
+ (HIMutableShapeRef) dr_return);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkSubtractRegion --
+ *
+ * Implements the equivalent of the X window function XSubtractRegion.
+ * See X window documentation for more details.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkSubtractRegion(
+ TkRegion sra,
+ TkRegion srb,
+ TkRegion dr_return)
+{
+ ChkErr(HIShapeDifference, (HIShapeRef) sra, (HIShapeRef) srb,
+ (HIMutableShapeRef) dr_return);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkUnionRectWithRegion --
+ *
+ * Implements the equivelent of the X window function
+ * XUnionRectWithRegion. See Xwindow documentation for more details.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkUnionRectWithRegion(
+ XRectangle* rectangle,
+ TkRegion src_region,
+ TkRegion dest_region_return)
+{
+ const CGRect r = CGRectMake(rectangle->x, rectangle->y,
+ rectangle->width, rectangle->height);
+
+ if (src_region == dest_region_return) {
+ ChkErr(TkMacOSHIShapeUnionWithRect,
+ (HIMutableShapeRef) dest_region_return, &r);
+ } else {
+ HIShapeRef rectRgn = HIShapeCreateWithRect(&r);
+
+ ChkErr(TkMacOSHIShapeUnion, rectRgn, (HIShapeRef) src_region,
+ (HIMutableShapeRef) dest_region_return);
+ CFRelease(rectRgn);
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkRectInRegion --
+ *
+ * Implements the equivelent of the X window function XRectInRegion. See
+ * Xwindow documentation for more details.
+ *
+ * Results:
+ * Returns RectanglePart or RectangleOut. Note that this is not a
+ * complete implementation since it doesn't test for RectangleIn.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkRectInRegion(
+ TkRegion region,
+ int x,
+ int y,
+ unsigned int width,
+ unsigned int height)
+{
+ int result;
+ const CGRect r = CGRectMake(x, y, width, height);
+
+ TK_IF_MAC_OS_X_API (4, HIShapeIntersectsRect,
+ result = HIShapeIntersectsRect((HIShapeRef) region, &r) ?
+ RectanglePart : RectangleOut;
+ ) TK_ELSE_MAC_OS_X (4,
+ HIShapeRef rectRgn = HIShapeCreateWithRect(&r);
+ HIShapeRef sectRgn = HIShapeCreateIntersection((HIShapeRef) region,
+ rectRgn);
+
+#if 1
+ result = !HIShapeIsEmpty(sectRgn) ? RectanglePart : RectangleOut;
+#else
+ /*
+ * More expensive full implementation that tests for RectangleIn,
+ * unused by Tk at present.
+ */
+
+ if (!HIShapeIsEmpty(sectRgn)) {
+ HIShapeRef diffRgn = HIShapeCreateDifference(rectRgn, sectRgn);
+
+ if (HIShapeIsEmpty(diffRgn)) {
+ result = RectangleIn;
+ } else {
+ result = RectanglePart;
+ }
+ CFRelease(diffRgn);
+ } else {
+ result = RectangleOut;
+ }
+#endif
+ CFRelease(sectRgn);
+ CFRelease(rectRgn);
+ ) TK_ENDIF;
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkClipBox --
+ *
+ * Implements the equivelent of the X window function XClipBox. See
+ * Xwindow documentation for more details.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkClipBox(
+ TkRegion r,
+ XRectangle* rect_return)
+{
+ CGRect rect;
+
+ HIShapeGetBounds((HIShapeRef) r, &rect);
+ rect_return->x = rect.origin.x;
+ rect_return->y = rect.origin.y;
+ rect_return->width = rect.size.width;
+ rect_return->height = rect.size.height;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpBuildRegionFromAlphaData --
+ *
+ * Set up a rectangle of the given region based on the supplied alpha
+ * data.
+ *
+ * Results:
+ * None
+ *
+ * Side effects:
+ * The region is updated, with extra pixels added to it.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpBuildRegionFromAlphaData(
+ TkRegion region, /* Region to update. */
+ unsigned int x, /* Where in region to update. */
+ unsigned int y, /* Where in region to update. */
+ unsigned int width, /* Size of rectangle to update. */
+ unsigned int height, /* Size of rectangle to update. */
+ unsigned char *dataPtr, /* Data to read from. */
+ unsigned int pixelStride, /* num bytes from one piece of alpha
+ * data to the next in the line. */
+ unsigned int lineStride) /* num bytes from one line of alpha
+ * data to the next line. */
+{
+ unsigned char *lineDataPtr;
+ unsigned int x1, y1, end;
+ XRectangle rect;
+
+ for (y1 = 0; y1 < height; y1++) {
+ lineDataPtr = dataPtr;
+ for (x1 = 0; x1 < width; x1 = end) {
+ /*
+ * Search for first non-transparent pixel.
+ */
+
+ while ((x1 < width) && !*lineDataPtr) {
+ x1++;
+ lineDataPtr += pixelStride;
+ }
+ end = x1;
+
+ /*
+ * Search for first transparent pixel.
+ */
+
+ while ((end < width) && *lineDataPtr) {
+ end++;
+ lineDataPtr += pixelStride;
+ }
+ if (end > x1) {
+ rect.x = x + x1;
+ rect.y = y + y1;
+ rect.width = end - x1;
+ rect.height = 1;
+ TkUnionRectWithRegion(&rect, region, region);
+ }
+ }
+ dataPtr += lineStride;
+ }
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpRetainRegion --
+ *
+ * Increases reference count of region.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpRetainRegion(
+ TkRegion r)
+{
+ CFRetain(r);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkpReleaseRegion --
+ *
+ * Decreases reference count of region.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * May free memory.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkpReleaseRegion(
+ TkRegion r)
+{
+ CFRelease(r);
+}
+#if 0
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXEmtpyRegion --
+ *
+ * Set region to emtpy.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXEmtpyRegion(
+ TkRegion r)
+{
+ ChkErr(HIShapeSetEmpty, (HIMutableShapeRef) r);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXIsEmptyRegion --
+ *
+ * Return native region for given tk region.
+ *
+ * Results:
+ * 1 if empty, 0 otherwise.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TkMacOSXIsEmptyRegion(
+ TkRegion r)
+{
+ return HIShapeIsEmpty((HIMutableShapeRef) r) ? 1 : 0;
+}
+#endif
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXGetNativeRegion --
+ *
+ * Return native region for given tk region.
+ *
+ * Results:
+ * Native region, CFRelease when done.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+HIShapeRef
+TkMacOSXGetNativeRegion(
+ TkRegion r)
+{
+ return (HIShapeRef) CFRetain(r);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXSetWithNativeRegion --
+ *
+ * Set region to the native region.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXSetWithNativeRegion(
+ TkRegion r,
+ HIShapeRef rgn)
+{
+ ChkErr(TkMacOSXHIShapeSetWithShape, (HIMutableShapeRef) r, rgn);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXOffsetRegion --
+ *
+ * Offsets region by given distances.
+ *
+ * Results:
+ * None.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+void
+TkMacOSXOffsetRegion(
+ TkRegion r,
+ short dx,
+ short dy)
+{
+ ChkErr(HIShapeOffset, (HIMutableShapeRef) r, dx, dy);
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * TkMacOSXHIShapeCreateEmpty, TkMacOSXHIShapeCreateMutableWithRect,
+ * TkMacOSXHIShapeSetWithShape, TkMacOSXHIShapeSetWithRect,
+ * TkMacOSHIShapeDifferenceWithRect, TkMacOSHIShapeUnionWithRect,
+ * TkMacOSHIShapeUnion --
+ *
+ * Wrapper functions for missing/buggy HIShape API
+ *
+ *----------------------------------------------------------------------
+ */
+
+HIShapeRef
+TkMacOSXHIShapeCreateEmpty(void)
+{
+ HIShapeRef result;
+
+ TK_IF_MAC_OS_X_API (4, HIShapeCreateEmpty,
+ result = HIShapeCreateEmpty();
+ ) TK_ELSE_MAC_OS_X (4,
+ static HIShapeRef emptyRgn = NULL;
+
+ if (!emptyRgn) {
+ HIMutableShapeRef rgn = HIShapeCreateMutable();
+
+ emptyRgn = HIShapeCreateCopy(rgn);
+ CFRelease(rgn);
+ }
+ result = HIShapeCreateCopy(emptyRgn);
+ ) TK_ENDIF;
+
+ return result;
+}
+
+HIMutableShapeRef
+TkMacOSXHIShapeCreateMutableWithRect(
+ const CGRect *inRect)
+{
+ HIMutableShapeRef result;
+
+ TK_IF_MAC_OS_X_API (5, HIShapeCreateMutableWithRect,
+ result = HIShapeCreateMutableWithRect(inRect);
+ ) TK_ELSE_MAC_OS_X (5,
+ HIShapeRef rgn = HIShapeCreateWithRect(inRect);
+
+ result = HIShapeCreateMutableCopy(rgn);
+ CFRelease(rgn);
+ ) TK_ENDIF;
+
+ return result;
+}
+
+OSStatus
+TkMacOSXHIShapeSetWithShape(
+ HIMutableShapeRef inDestShape,
+ HIShapeRef inSrcShape)
+{
+ OSStatus result;
+
+ TK_IF_MAC_OS_X_API (5, HIShapeSetWithShape,
+ result = HIShapeSetWithShape(inDestShape, inSrcShape);
+ ) TK_ELSE_MAC_OS_X (5,
+ result = HIShapeSetEmpty(inDestShape);
+ if (result == noErr) {
+ result = HIShapeDifference(inSrcShape, inDestShape, inDestShape);
+ }
+ ) TK_ENDIF;
+
+ return result;
+}
+
+#if 0
+OSStatus
+TkMacOSXHIShapeSetWithRect(
+ HIMutableShapeRef inShape,
+ const CGRect *inRect)
+{
+ OSStatus result;
+ HIShapeRef rgn = HIShapeCreateWithRect(inRect);
+
+ result = TkMacOSXHIShapeSetWithShape(inShape, rgn);
+ CFRelease(rgn);
+
+ return result;
+}
+#endif
+
+OSStatus
+TkMacOSHIShapeDifferenceWithRect(
+ HIMutableShapeRef inShape,
+ const CGRect *inRect)
+{
+ OSStatus result;
+ HIShapeRef rgn = HIShapeCreateWithRect(inRect);
+
+ result = HIShapeDifference(inShape, rgn, inShape);
+ CFRelease(rgn);
+
+ return result;
+}
+
+OSStatus
+TkMacOSHIShapeUnionWithRect(
+ HIMutableShapeRef inShape,
+ const CGRect *inRect)
+{
+ OSStatus result;
+
+ TK_IF_MAC_OS_X_API (5, HIShapeUnionWithRect,
+ result = HIShapeUnionWithRect(inShape, inRect);
+ ) TK_ELSE_MAC_OS_X (5,
+ HIShapeRef rgn = HIShapeCreateWithRect(inRect);
+
+ result = TkMacOSHIShapeUnion(rgn, inShape, inShape);
+ CFRelease(rgn);
+ ) TK_ENDIF;
+
+ return result;
+}
+
+OSStatus
+TkMacOSHIShapeUnion(
+ HIShapeRef inShape1,
+ HIShapeRef inShape2,
+ HIMutableShapeRef outResult)
+{
+ OSStatus result;
+
+ TK_IF_HI_TOOLBOX (4,
+ result = HIShapeUnion(inShape1, inShape2, outResult);
+ ) TK_ELSE_HI_TOOLBOX (4,
+ /*
+ * Workaround HIShapeUnion bug in 10.3 and earlier.
+ */
+
+ HIShapeRef rgn = HIShapeCreateCopy(outResult);
+
+ result = HIShapeUnion(inShape1, inShape2, (HIMutableShapeRef) rgn);
+ if (result == noErr) {
+ result = HIShapeSetEmpty(outResult);
+ if (result == noErr) {
+ result = HIShapeDifference(rgn, outResult, outResult);
+ }
+ }
+ CFRelease(rgn);
+ ) TK_ENDIF;
+
+ return result;
+}
+
+/*
+ * Local Variables:
+ * mode: c
+ * c-basic-offset: 4
+ * fill-column: 78
+ * coding: utf-8
+ * End:
+ */