osx_region_hishape.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. #include <Carbon/Carbon.h>
  2. #include <tataki/region/region.h>
  3. #include <tataki/bitmap/bitmap.h>
  4. RegionI::RegionI() : rgn(0)
  5. {
  6. }
  7. RegionI::RegionI(const RECT *r) : rgn(0)
  8. {
  9. setRect(r);
  10. }
  11. RegionI::RegionI(HIMutableShapeRef _rgn) : rgn(_rgn)
  12. {
  13. }
  14. RegionI::RegionI(HIShapeRef _rgn)
  15. {
  16. rgn=HIShapeCreateMutableCopy(_rgn);
  17. }
  18. RegionI::~RegionI()
  19. {
  20. if (rgn)
  21. CFRelease(rgn);
  22. }
  23. RegionI::RegionI(RgnHandle qdrgn)
  24. {
  25. HIShapeRef shape = HIShapeCreateWithQDRgn(qdrgn);
  26. rgn = HIShapeCreateMutableCopy(shape);
  27. CFRelease(shape);
  28. }
  29. RegionI::RegionI(SkinBitmap *bitmap)
  30. {
  31. // TODO: we need to find a much better way to do this
  32. RECT r;
  33. r.left=0;
  34. r.top=0;
  35. r.right=bitmap->getWidth();
  36. r.bottom=bitmap->getHeight();
  37. setRect(&r);
  38. }
  39. OSREGIONHANDLE RegionI::getOSHandle()
  40. {
  41. if (!rgn)
  42. rgn = HIShapeCreateMutable();
  43. return rgn;
  44. }
  45. api_region *RegionI::clone()
  46. {
  47. if (!rgn)
  48. return new RegionI();
  49. else
  50. return new RegionI(HIShapeCreateMutableCopy(rgn));
  51. }
  52. void RegionI::disposeClone(api_region *r)
  53. {
  54. if (r) // yes we need to check for NULL here because r != static_cast<>(r)
  55. delete static_cast<RegionI *>(r);
  56. }
  57. bool RegionI::ptInRegion(const POINT *pt)
  58. {
  59. if (!rgn)
  60. return false;
  61. HIPoint hipt = HIPointFromPOINT(pt);
  62. return !!HIShapeContainsPoint(rgn, &hipt);
  63. }
  64. void RegionI::offset(int x, int y)
  65. {
  66. if (!rgn)
  67. rgn = HIShapeCreateMutable();
  68. HIShapeOffset(rgn, x, y);
  69. }
  70. void RegionI::getBox(RECT *r)
  71. {
  72. if (!rgn) // TODO: we could manually set r to 0,0,0,0
  73. rgn = HIShapeCreateMutable();
  74. HIRect rect;
  75. HIShapeGetBounds(rgn, &rect);
  76. *r = RECTFromHIRect(&rect);
  77. }
  78. void RegionI::subtractRegion(const api_region *r)
  79. {
  80. if (rgn)
  81. {
  82. api_region *reg = const_cast<api_region *>(r);
  83. HIShapeRef sub = reg->getOSHandle();
  84. HIShapeDifference(rgn,sub, rgn);
  85. }
  86. }
  87. void RegionI::subtractRect(const RECT *r)
  88. {
  89. if (rgn)
  90. {
  91. HIRect rect = HIRectFromRECT(r);
  92. HIShapeRef sub = HIShapeCreateWithRect(&rect);
  93. HIShapeDifference(rgn, sub, rgn);
  94. }
  95. }
  96. void RegionI::addRect(const RECT *r)
  97. {
  98. if (!rgn)
  99. rgn = HIShapeCreateMutable();
  100. HIRect rect = HIRectFromRECT(r);
  101. HIShapeRef add = HIShapeCreateWithRect(&rect);
  102. HIShapeUnion(rgn, add, rgn);
  103. }
  104. void RegionI::addRegion(const api_region *r)
  105. {
  106. if (!rgn)
  107. rgn = HIShapeCreateMutable();
  108. api_region *reg = const_cast<api_region *>(r);
  109. HIShapeRef add = reg->getOSHandle();
  110. HIShapeUnion(rgn, add, rgn);
  111. }
  112. void RegionI::andRegion(const api_region *r)
  113. {
  114. if (rgn) // intersection with empty region will always be empty
  115. {
  116. api_region *reg = const_cast<api_region *>(r);
  117. HIShapeRef intersection = reg->getOSHandle();
  118. HIShapeIntersect(rgn, intersection, rgn);
  119. }
  120. }
  121. void RegionI::setRect(const RECT *r)
  122. {
  123. if (rgn)
  124. CFRelease(rgn);
  125. HIRect rect = HIRectFromRECT(r);
  126. HIShapeRef rectRgn = HIShapeCreateWithRect(&rect);
  127. rgn = HIShapeCreateMutableCopy(rectRgn);
  128. CFRelease(rectRgn);
  129. }
  130. void RegionI::empty()
  131. {
  132. if (rgn)
  133. CFRelease(rgn);
  134. rgn=0;
  135. }
  136. int RegionI::isEmpty()
  137. {
  138. if (!rgn)
  139. return 1;
  140. return !!HIShapeIsEmpty(rgn);
  141. }
  142. int RegionI::isRect()
  143. {
  144. if (!rgn)
  145. return 1;
  146. return !!HIShapeIsRectangular(rgn);
  147. }
  148. int RegionI::intersectRgn(const api_region *r, api_region *intersection)
  149. {
  150. intersection->empty();
  151. intersection->addRegion(this);
  152. intersection->andRegion(r);
  153. return !intersection->isEmpty();
  154. }
  155. int RegionI::intersectRect(const RECT *r, api_region *intersection)
  156. {
  157. intersection->setRect(r);
  158. intersection->andRegion(this);
  159. return !intersection->isEmpty();
  160. }
  161. #define CBCLASS RegionI
  162. START_DISPATCH;
  163. CB(REGION_GETOSHANDLE, getOSHandle);
  164. CB(REGION_CLONE, clone);
  165. VCB(REGION_DISPOSECLONE, disposeClone);
  166. CB(REGION_PTINREGION, ptInRegion);
  167. VCB(REGION_OFFSET, offset);
  168. VCB(REGION_GETBOX, getBox);
  169. VCB(REGION_SUBTRACTRGN, subtractRegion);
  170. VCB(REGION_SUBTRACTRECT, subtractRect);
  171. VCB(REGION_ADDRECT, addRect);
  172. VCB(REGION_ADD, addRegion);
  173. VCB(REGION_AND, andRegion);
  174. VCB(REGION_SETRECT, setRect);
  175. VCB(REGION_EMPTY, empty);
  176. CB(REGION_ISEMPTY, isEmpty);
  177. CB(REGION_ISRECT, isRect);
  178. CB(REGION_INTERSECTRGN, intersectRgn);
  179. CB(REGION_INTERSECTRECT, intersectRect);
  180. END_DISPATCH;
  181. #undef CBCLASS
  182. #define CBCLASS RegionServerI
  183. START_DISPATCH;
  184. VCB(REGIONSERVER_ADDREF, addRef);
  185. VCB(REGIONSERVER_DELREF, delRef);
  186. CB(REGIONSERVER_GETREGION, getRegion);
  187. END_DISPATCH;
  188. #undef CBCLASS