diff options
| author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
|---|---|---|
| committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
| commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
| tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/tataki/region/mac | |
| parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
| download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz | |
Initial community commit
Diffstat (limited to 'Src/tataki/region/mac')
| -rw-r--r-- | Src/tataki/region/mac/osx_region_hishape.cpp | 217 | ||||
| -rw-r--r-- | Src/tataki/region/mac/region.h | 116 |
2 files changed, 333 insertions, 0 deletions
diff --git a/Src/tataki/region/mac/osx_region_hishape.cpp b/Src/tataki/region/mac/osx_region_hishape.cpp new file mode 100644 index 00000000..348ba1de --- /dev/null +++ b/Src/tataki/region/mac/osx_region_hishape.cpp @@ -0,0 +1,217 @@ +#include <Carbon/Carbon.h> +#include <tataki/region/region.h> +#include <tataki/bitmap/bitmap.h> + +RegionI::RegionI() : rgn(0) +{ +} + +RegionI::RegionI(const RECT *r) : rgn(0) +{ + setRect(r); +} + +RegionI::RegionI(HIMutableShapeRef _rgn) : rgn(_rgn) +{ +} + +RegionI::RegionI(HIShapeRef _rgn) +{ + rgn=HIShapeCreateMutableCopy(_rgn); +} + +RegionI::~RegionI() +{ + if (rgn) + CFRelease(rgn); +} + +RegionI::RegionI(RgnHandle qdrgn) +{ + HIShapeRef shape = HIShapeCreateWithQDRgn(qdrgn); + rgn = HIShapeCreateMutableCopy(shape); + CFRelease(shape); +} + +RegionI::RegionI(SkinBitmap *bitmap) +{ + // TODO: we need to find a much better way to do this + RECT r; + r.left=0; + r.top=0; + r.right=bitmap->getWidth(); + r.bottom=bitmap->getHeight(); + setRect(&r); +} + + +OSREGIONHANDLE RegionI::getOSHandle() +{ + if (!rgn) + rgn = HIShapeCreateMutable(); + return rgn; +} + +api_region *RegionI::clone() +{ + if (!rgn) + return new RegionI(); + else + return new RegionI(HIShapeCreateMutableCopy(rgn)); +} + +void RegionI::disposeClone(api_region *r) +{ + if (r) // yes we need to check for NULL here because r != static_cast<>(r) + delete static_cast<RegionI *>(r); +} + +bool RegionI::ptInRegion(const POINT *pt) +{ + if (!rgn) + return false; + HIPoint hipt = HIPointFromPOINT(pt); + return !!HIShapeContainsPoint(rgn, &hipt); +} + +void RegionI::offset(int x, int y) +{ + if (!rgn) + rgn = HIShapeCreateMutable(); + + HIShapeOffset(rgn, x, y); +} + +void RegionI::getBox(RECT *r) +{ + if (!rgn) // TODO: we could manually set r to 0,0,0,0 + rgn = HIShapeCreateMutable(); + + HIRect rect; + HIShapeGetBounds(rgn, &rect); + *r = RECTFromHIRect(&rect); +} + +void RegionI::subtractRegion(const api_region *r) +{ + if (rgn) + { + api_region *reg = const_cast<api_region *>(r); + HIShapeRef sub = reg->getOSHandle(); + HIShapeDifference(rgn,sub, rgn); + } +} + +void RegionI::subtractRect(const RECT *r) +{ + if (rgn) + { + HIRect rect = HIRectFromRECT(r); + HIShapeRef sub = HIShapeCreateWithRect(&rect); + HIShapeDifference(rgn, sub, rgn); + } +} + +void RegionI::addRect(const RECT *r) +{ + if (!rgn) + rgn = HIShapeCreateMutable(); + HIRect rect = HIRectFromRECT(r); + HIShapeRef add = HIShapeCreateWithRect(&rect); + HIShapeUnion(rgn, add, rgn); +} + +void RegionI::addRegion(const api_region *r) +{ + if (!rgn) + rgn = HIShapeCreateMutable(); + api_region *reg = const_cast<api_region *>(r); + HIShapeRef add = reg->getOSHandle(); + HIShapeUnion(rgn, add, rgn); +} + +void RegionI::andRegion(const api_region *r) +{ + if (rgn) // intersection with empty region will always be empty + { + api_region *reg = const_cast<api_region *>(r); + HIShapeRef intersection = reg->getOSHandle(); + HIShapeIntersect(rgn, intersection, rgn); + } +} + +void RegionI::setRect(const RECT *r) +{ + if (rgn) + CFRelease(rgn); + HIRect rect = HIRectFromRECT(r); + HIShapeRef rectRgn = HIShapeCreateWithRect(&rect); + rgn = HIShapeCreateMutableCopy(rectRgn); + CFRelease(rectRgn); +} + +void RegionI::empty() +{ + if (rgn) + CFRelease(rgn); + rgn=0; +} + +int RegionI::isEmpty() +{ + if (!rgn) + return 1; + return !!HIShapeIsEmpty(rgn); +} + +int RegionI::isRect() +{ + if (!rgn) + return 1; + return !!HIShapeIsRectangular(rgn); +} + +int RegionI::intersectRgn(const api_region *r, api_region *intersection) +{ + intersection->empty(); + intersection->addRegion(this); + intersection->andRegion(r); + return !intersection->isEmpty(); +} + +int RegionI::intersectRect(const RECT *r, api_region *intersection) +{ + intersection->setRect(r); + intersection->andRegion(this); + return !intersection->isEmpty(); +} + +#define CBCLASS RegionI +START_DISPATCH; +CB(REGION_GETOSHANDLE, getOSHandle); +CB(REGION_CLONE, clone); +VCB(REGION_DISPOSECLONE, disposeClone); +CB(REGION_PTINREGION, ptInRegion); +VCB(REGION_OFFSET, offset); +VCB(REGION_GETBOX, getBox); +VCB(REGION_SUBTRACTRGN, subtractRegion); +VCB(REGION_SUBTRACTRECT, subtractRect); +VCB(REGION_ADDRECT, addRect); +VCB(REGION_ADD, addRegion); +VCB(REGION_AND, andRegion); +VCB(REGION_SETRECT, setRect); +VCB(REGION_EMPTY, empty); +CB(REGION_ISEMPTY, isEmpty); +CB(REGION_ISRECT, isRect); +CB(REGION_INTERSECTRGN, intersectRgn); +CB(REGION_INTERSECTRECT, intersectRect); +END_DISPATCH; +#undef CBCLASS + +#define CBCLASS RegionServerI +START_DISPATCH; +VCB(REGIONSERVER_ADDREF, addRef); +VCB(REGIONSERVER_DELREF, delRef); +CB(REGIONSERVER_GETREGION, getRegion); +END_DISPATCH; +#undef CBCLASS
\ No newline at end of file diff --git a/Src/tataki/region/mac/region.h b/Src/tataki/region/mac/region.h new file mode 100644 index 00000000..f3404ea2 --- /dev/null +++ b/Src/tataki/region/mac/region.h @@ -0,0 +1,116 @@ +#ifndef __REGION_H +#define __REGION_H + +#include <tataki/export.h> +#include <Carbon/Carbon.h> +#include <bfc/platform/platform.h> +#include <tataki/region/api_region.h> + +class SkinBitmap; + +class TATAKIAPI RegionI : public api_region +{ +public: + RegionI(); + RegionI(const RECT *r); + RegionI(RgnHandle qdrgn); + RegionI(HIShapeRef _rgn); + RegionI(SkinBitmap *bitmap); + ~RegionI(); + + // api_region + OSREGIONHANDLE getOSHandle(); + api_region *clone(); + void disposeClone(api_region *r); + bool ptInRegion(const POINT *pt); + void offset(int x, int y); + void getBox(RECT *r); + void subtractRegion(const api_region *r); + void subtractRect(const RECT *r); + void addRect(const RECT *r); + void addRegion(const api_region *r); + void andRegion(const api_region *r); + void setRect(const RECT *r); + void empty(); + int isEmpty(); + int equals(const api_region *r); + int enclosed(const api_region *r, api_region *outside = NULL); + int intersectRgn(const api_region *r, api_region *intersection); + int doesIntersectRgn(const api_region *r); + int intersectRect(const RECT *r, api_region *intersection); + + int isRect(); + void scale(double sx, double sy, bool round = 0); + void debug(int async = 0); + OSREGIONHANDLE makeWindowRegion(); // gives you a handle to a clone of the OSREGION object so you can insert it into a window's region with SetWindowRgn. ANY other use is prohibited + + // this is how you can enumerate the subrects that compose to make up the + // entire region + int getNumRects(); + int enumRect(int n, RECT *r); + + +private: + RegionI(HIMutableShapeRef _rgn); + HIMutableShapeRef rgn; + +protected: + RECVS_DISPATCH; +}; + + +// TODO: we could take of advantage of HIShapeRef's built in reference counting to implement this +class RegionServer : public Dispatchable { + +protected: + RegionServer() {} + virtual ~RegionServer() {} + +public: + + void addRef(void *client); + void delRef(void *client); + api_region *getRegion(); + + enum { + REGIONSERVER_ADDREF = 500, + REGIONSERVER_DELREF = 550, + REGIONSERVER_GETREGION = 600, + }; +}; + +inline void RegionServer::addRef(void *client) { + _voidcall(REGIONSERVER_ADDREF, (api_region *)NULL, client); +} + +inline void RegionServer::delRef(void *client) { + _voidcall(REGIONSERVER_DELREF, client); +} + +inline api_region * RegionServer::getRegion() { + return _call(REGIONSERVER_GETREGION, (api_region *)NULL); +} + +class TATAKIAPI RegionServerI : public RegionServer { +public : + + RegionServerI() { numrefs = 0; } + virtual ~RegionServerI() {} + + virtual void addRef(void *client) { numrefs++; } + virtual void delRef(void *client) { numrefs--; } + virtual api_region *getRegion()=0; + + virtual int getNumRefs() { return numrefs; } + +protected: + + RECVS_DISPATCH; + +private: + + int numrefs; +}; +#endif + + |
