/* * tkWinRegion.c -- * * Tk Region emulation code. * * Copyright (c) 1995 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * RCS: @(#) $Id: tkWinRegion.c,v 1.5 2004/10/26 14:07:57 patthoyts Exp $ */ #include "tkWinInt.h" /* *---------------------------------------------------------------------- * * TkCreateRegion -- * * Construct an empty region. * * Results: * Returns a new region handle. * * Side effects: * None. * *---------------------------------------------------------------------- */ TkRegion TkCreateRegion() { RECT rect; memset(&rect, 0, sizeof(RECT)); return (TkRegion) CreateRectRgnIndirect(&rect); } /* *---------------------------------------------------------------------- * * TkDestroyRegion -- * * Destroy the specified region. * * Results: * None. * * Side effects: * Frees the storage associated with the specified region. * *---------------------------------------------------------------------- */ void TkDestroyRegion(r) TkRegion r; { DeleteObject((HRGN) r); } /* *---------------------------------------------------------------------- * * TkClipBox -- * * Computes the bounding box of a region. * * Results: * Sets rect_return to the bounding box of the region. * * Side effects: * None. * *---------------------------------------------------------------------- */ void TkClipBox(r, rect_return) TkRegion r; XRectangle* rect_return; { RECT rect; GetRgnBox((HRGN)r, &rect); rect_return->x = (short) rect.left; rect_return->y = (short) rect.top; rect_return->width = (short) (rect.right - rect.left); rect_return->height = (short) (rect.bottom - rect.top); } /* *---------------------------------------------------------------------- * * TkIntersectRegion -- * * Compute the intersection of two regions. * * Results: * Returns the result in the dr_return region. * * Side effects: * None. * *---------------------------------------------------------------------- */ void TkIntersectRegion(sra, srb, dr_return) TkRegion sra; TkRegion srb; TkRegion dr_return; { CombineRgn((HRGN) dr_return, (HRGN) sra, (HRGN) srb, RGN_AND); } /* *---------------------------------------------------------------------- * * TkUnionRectWithRegion -- * * Create the union of a source region and a rectangle. * * Results: * Returns the result in the dr_return region. * * Side effects: * None. * *---------------------------------------------------------------------- */ void TkUnionRectWithRegion(rectangle, src_region, dest_region_return) XRectangle* rectangle; TkRegion src_region; TkRegion dest_region_return; { HRGN rectRgn = CreateRectRgn(rectangle->x, rectangle->y, rectangle->x + rectangle->width, rectangle->y + rectangle->height); CombineRgn((HRGN) dest_region_return, (HRGN) src_region, (HRGN) rectRgn, RGN_OR); DeleteObject(rectRgn); } /* *---------------------------------------------------------------------- * * 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(region, x, y, width, height, dataPtr, pixelStride, lineStride) TkRegion region; unsigned int x, y; /* Where in region to update. */ unsigned int width, 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; HRGN rectRgn = CreateRectRgn(0,0,1,1); /* Workspace region. */ 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) { /* * Manipulate Win32 regions directly; it's more efficient. */ SetRectRgn(rectRgn, x+x1, y+y1, x+end, y+y1+1); CombineRgn((HRGN) region, (HRGN) region, rectRgn, RGN_OR); } } dataPtr += lineStride; } DeleteObject(rectRgn); } /* *---------------------------------------------------------------------- * * TkRectInRegion -- * * Test whether a given rectangle overlaps with a region. * * 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(r, x, y, width, height) TkRegion r; int x; int y; unsigned int width; unsigned int height; { RECT rect; rect.top = y; rect.left = x; rect.bottom = y+height; rect.right = x+width; return RectInRegion((HRGN)r, &rect) ? RectanglePart : RectangleOut; } /* *---------------------------------------------------------------------- * * TkSubtractRegion -- * * Compute the set-difference of two regions. * * Results: * Returns the result in the dr_return region. * * Side effects: * None. * *---------------------------------------------------------------------- */ void TkSubtractRegion(sra, srb, dr_return) TkRegion sra; TkRegion srb; TkRegion dr_return; { CombineRgn((HRGN) dr_return, (HRGN) sra, (HRGN) srb, RGN_DIFF); }