Files
cpython-source-deps/macosx/tkMacOSXRegion.c
2021-03-30 00:54:10 +01:00

566 lines
11 KiB
C
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* tkMacOSXRegion.c --
*
* Implements X window calls for manipulating regions
*
* Copyright (c) 1995-1996 Sun Microsystems, Inc.
* Copyright 2001-2009, Apple Inc.
* Copyright (c) 2006-2009 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"
static void RetainRegion(TkRegion r);
static void ReleaseRegion(TkRegion r);
#ifdef DEBUG
static int totalRegions = 0;
static int totalRegionRetainCount = 0;
#define DebugLog(msg, ...) fprintf(stderr, (msg), ##__VA_ARGS__)
#else
#define DebugLog(msg, ...)
#endif
/*
*----------------------------------------------------------------------
*
* 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)
{
TkRegion region = (TkRegion) HIShapeCreateMutable();
DebugLog("Created region: total regions = %d\n", ++totalRegions);
RetainRegion(region);
return region;
}
/*
*----------------------------------------------------------------------
*
* TkDestroyRegion --
*
* Implements the equivelent of the X window function XDestroyRegion. See
* Xwindow documentation for more details.
*
* Results:
* None.
*
* Side effects:
* Memory is freed.
*
*----------------------------------------------------------------------
*/
int
TkDestroyRegion(
TkRegion r)
{
if (r) {
DebugLog("Destroyed region: total regions = %d\n", --totalRegions);
ReleaseRegion(r);
}
return Success;
}
/*
*----------------------------------------------------------------------
*
* TkIntersectRegion --
*
* Implements the equivalent of the X window function XIntersectRegion.
* See Xwindow documentation for more details.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
TkIntersectRegion(
TkRegion sra,
TkRegion srb,
TkRegion dr_return)
{
ChkErr(HIShapeIntersect, (HIShapeRef) sra, (HIShapeRef) srb,
(HIMutableShapeRef) dr_return);
return Success;
}
/*
*----------------------------------------------------------------------
*
* TkSubtractRegion --
*
* Implements the equivalent of the X window function XSubtractRegion.
* See X window documentation for more details.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
TkSubtractRegion(
TkRegion sra,
TkRegion srb,
TkRegion dr_return)
{
ChkErr(HIShapeDifference, (HIShapeRef) sra, (HIShapeRef) srb,
(HIMutableShapeRef) dr_return);
return Success;
}
/*
*----------------------------------------------------------------------
*
* TkUnionRectWithRegion --
*
* Implements the equivelent of the X window function
* XUnionRectWithRegion. See Xwindow documentation for more details.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
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);
}
return Success;
}
/*
*----------------------------------------------------------------------
*
* TkMacOSXIsEmptyRegion --
*
* Return native region for given tk region.
*
* Results:
* 1 if empty, 0 otherwise.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static int
TkMacOSXIsEmptyRegion(
TkRegion r)
{
return HIShapeIsEmpty((HIMutableShapeRef) r) ? 1 : 0;
}
/*
*----------------------------------------------------------------------
*
* 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)
{
if (TkMacOSXIsEmptyRegion(region)) {
return RectangleOut;
} else {
const CGRect r = CGRectMake(x, y, width, height);
return HIShapeIntersectsRect((HIShapeRef) region, &r) ?
RectanglePart : RectangleOut;
}
}
/*
*----------------------------------------------------------------------
*
* TkClipBox --
*
* Implements the equivelent of the X window function XClipBox. See
* Xwindow documentation for more details.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
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;
return Success;
}
/*
*----------------------------------------------------------------------
*
* 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;
}
}
/*
*----------------------------------------------------------------------
*
* RetainRegion --
*
* Increases reference count of region.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
static void
RetainRegion(
TkRegion r)
{
CFRetain(r);
DebugLog("Retained region: total count is %d\n", ++totalRegionRetainCount);
}
/*
*----------------------------------------------------------------------
*
* ReleaseRegion --
*
* Decreases reference count of region.
*
* Results:
* None.
*
* Side effects:
* May free memory.
*
*----------------------------------------------------------------------
*/
static void
ReleaseRegion(
TkRegion r)
{
CFRelease(r);
DebugLog("Released region: total count is %d\n", --totalRegionRetainCount);
}
/*
*----------------------------------------------------------------------
*
* TkMacOSXSetEmptyRegion --
*
* Set region to emtpy.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
void
TkMacOSXSetEmptyRegion(
TkRegion r)
{
ChkErr(HIShapeSetEmpty, (HIMutableShapeRef) r);
}
/*
*----------------------------------------------------------------------
*
* 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);
}
/*
*----------------------------------------------------------------------
*
* XOffsetRegion --
*
* Offsets region by given distances.
*
* Results:
* None.
*
* Side effects:
* None.
*
*----------------------------------------------------------------------
*/
int
XOffsetRegion(
void *r,
int dx,
int dy)
{
ChkErr(HIShapeOffset, (HIMutableShapeRef) r, dx, dy);
return Success;
}
/*
*----------------------------------------------------------------------
*
* TkMacOSXHIShapeCreateEmpty, TkMacOSXHIShapeCreateMutableWithRect,
* TkMacOSXHIShapeSetWithShape,
* TkMacOSHIShapeDifferenceWithRect, TkMacOSHIShapeUnionWithRect,
* TkMacOSHIShapeUnion --
*
* Wrapper functions for missing/buggy HIShape API
*
*----------------------------------------------------------------------
*/
HIShapeRef
TkMacOSXHIShapeCreateEmpty(void)
{
HIShapeRef result;
result = HIShapeCreateEmpty();
return result;
}
HIMutableShapeRef
TkMacOSXHIShapeCreateMutableWithRect(
const CGRect *inRect)
{
HIMutableShapeRef result;
result = HIShapeCreateMutableWithRect(inRect);
return result;
}
OSStatus
TkMacOSXHIShapeSetWithShape(
HIMutableShapeRef inDestShape,
HIShapeRef inSrcShape)
{
OSStatus result;
result = HIShapeSetWithShape(inDestShape, inSrcShape);
return result;
}
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;
result = HIShapeUnionWithRect(inShape, inRect);
return result;
}
OSStatus
TkMacOSHIShapeUnion(
HIShapeRef inShape1,
HIShapeRef inShape2,
HIMutableShapeRef outResult)
{
OSStatus result;
result = HIShapeUnion(inShape1, inShape2, outResult);
return result;
}
/*
* Local Variables:
* mode: objc
* c-basic-offset: 4
* fill-column: 79
* coding: utf-8
* End:
*/