Initial community commit

This commit is contained in:
Jef
2024-09-24 14:54:57 +02:00
parent 537bcbc862
commit 20d28e80a5
16810 changed files with 4640254 additions and 2 deletions

View File

@ -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

View File

@ -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