tkMacOSXRegion.c
上传用户:rrhhcc
上传日期:2015-12-11
资源大小:54129k
文件大小:13k
源码类别:

通讯编程

开发平台:

Visual C++

  1. /*
  2.  * tkMacOSXRegion.c --
  3.  *
  4.  * Implements X window calls for manipulating regions
  5.  *
  6.  * Copyright (c) 1995-1996 Sun Microsystems, Inc.
  7.  * Copyright 2001, Apple Computer, Inc.
  8.  * Copyright (c) 2006-2007 Daniel A. Steffen <das@users.sourceforge.net>
  9.  *
  10.  * See the file "license.terms" for information on usage and redistribution
  11.  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  12.  *
  13.  * RCS: @(#) $Id: tkMacOSXRegion.c,v 1.2.2.7 2007/11/09 06:26:56 das Exp $
  14.  */
  15. #include "tkMacOSXPrivate.h"
  16. /*
  17.  *----------------------------------------------------------------------
  18.  *
  19.  * TkCreateRegion --
  20.  *
  21.  * Implements the equivelent of the X window function
  22.  * XCreateRegion. See X window documentation for more details.
  23.  *
  24.  * Results:
  25.  * Returns an allocated region handle.
  26.  *
  27.  * Side effects:
  28.  * None.
  29.  *
  30.  *----------------------------------------------------------------------
  31.  */
  32. TkRegion
  33. TkCreateRegion(void)
  34. {
  35.     return (TkRegion) HIShapeCreateMutable();
  36. }
  37. /*
  38.  *----------------------------------------------------------------------
  39.  *
  40.  * TkDestroyRegion --
  41.  *
  42.  * Implements the equivelent of the X window function
  43.  * XDestroyRegion. See X window documentation for more details.
  44.  *
  45.  * Results:
  46.  * None.
  47.  *
  48.  * Side effects:
  49.  * Memory is freed.
  50.  *
  51.  *----------------------------------------------------------------------
  52.  */
  53. void
  54. TkDestroyRegion(
  55.     TkRegion r)
  56. {
  57.     if (r) {
  58. CFRelease(r);
  59.     }
  60. }
  61. /*
  62.  *----------------------------------------------------------------------
  63.  *
  64.  * TkIntersectRegion --
  65.  *
  66.  * Implements the equivalent of the X window function
  67.  * XIntersectRegion. See X window documentation for more details.
  68.  *
  69.  * Results:
  70.  * None.
  71.  *
  72.  * Side effects:
  73.  * None.
  74.  *
  75.  *----------------------------------------------------------------------
  76.  */
  77. void
  78. TkIntersectRegion(
  79.     TkRegion sra,
  80.     TkRegion srb,
  81.     TkRegion dr_return)
  82. {
  83.     ChkErr(HIShapeIntersect, (HIShapeRef) sra, (HIShapeRef) srb,
  84.    (HIMutableShapeRef) dr_return);
  85. }
  86. /*
  87.  *----------------------------------------------------------------------
  88.  *
  89.  * TkSubtractRegion --
  90.  *
  91.  * Implements the equivalent of the X window function
  92.  * XSubtractRegion. See X window documentation for more details.
  93.  *
  94.  * Results:
  95.  * None.
  96.  *
  97.  * Side effects:
  98.  * None.
  99.  *
  100.  *----------------------------------------------------------------------
  101.  */
  102. void
  103. TkSubtractRegion(
  104.     TkRegion sra,
  105.     TkRegion srb,
  106.     TkRegion dr_return)
  107. {
  108.     ChkErr(HIShapeDifference, (HIShapeRef) sra, (HIShapeRef) srb,
  109.    (HIMutableShapeRef) dr_return);
  110. }
  111. /*
  112.  *----------------------------------------------------------------------
  113.  *
  114.  * TkUnionRectWithRegion --
  115.  *
  116.  * Implements the equivelent of the X window function
  117.  * XUnionRectWithRegion. See X window documentation for more
  118.  * details.
  119.  *
  120.  * Results:
  121.  * None.
  122.  *
  123.  * Side effects:
  124.  * None.
  125.  *
  126.  *----------------------------------------------------------------------
  127.  */
  128. void
  129. TkUnionRectWithRegion(
  130.     XRectangle* rectangle,
  131.     TkRegion src_region,
  132.     TkRegion dest_region_return)
  133. {
  134.     const CGRect r = CGRectMake(rectangle->x, rectangle->y,
  135.     rectangle->width, rectangle->height);
  136.     if (src_region == dest_region_return) {
  137. ChkErr(TkMacOSHIShapeUnionWithRect,
  138. (HIMutableShapeRef) dest_region_return, &r);
  139.     } else {
  140. HIShapeRef rectRgn = HIShapeCreateWithRect(&r);
  141. ChkErr(TkMacOSHIShapeUnion, rectRgn, (HIShapeRef) src_region,
  142. (HIMutableShapeRef) dest_region_return);
  143. CFRelease(rectRgn);
  144.     }
  145. }
  146. /*
  147.  *----------------------------------------------------------------------
  148.  *
  149.  * TkRectInRegion --
  150.  *
  151.  * Implements the equivelent of the X window function
  152.  * XRectInRegion. See X window documentation for more details.
  153.  *
  154.  * Results:
  155.  * Returns RectanglePart or RectangleOut. Note that this is not a
  156.  * complete implementation since it doesn't test for RectangleIn.
  157.  *
  158.  * Side effects:
  159.  * None.
  160.  *
  161.  *----------------------------------------------------------------------
  162.  */
  163. int
  164. TkRectInRegion(
  165.     TkRegion region,
  166.     int x,
  167.     int y,
  168.     unsigned int width,
  169.     unsigned int height)
  170. {
  171.     int result;
  172.     const CGRect r = CGRectMake(x, y, width, height);
  173.     TK_IF_MAC_OS_X_API (4, HIShapeIntersectsRect,
  174. result = HIShapeIntersectsRect((HIShapeRef) region, &r) ?
  175. RectanglePart : RectangleOut;
  176.     ) TK_ELSE_MAC_OS_X (4,
  177. HIShapeRef rectRgn = HIShapeCreateWithRect(&r);
  178. HIShapeRef sectRgn = HIShapeCreateIntersection((HIShapeRef) region,
  179. rectRgn);
  180. #if 1
  181. result = !HIShapeIsEmpty(sectRgn) ? RectanglePart : RectangleOut;
  182. #else
  183. /*
  184.  * More expensive full implementation that tests for RectangleIn,
  185.  * unused by Tk at present.
  186.  */
  187. if (!HIShapeIsEmpty(sectRgn)) {
  188.     HIShapeRef diffRgn = HIShapeCreateDifference(rectRgn, sectRgn);
  189.  
  190.     if (HIShapeIsEmpty(diffRgn)) {
  191. result = RectangleIn;
  192.     } else {
  193. result = RectanglePart;
  194.     }
  195.     CFRelease(diffRgn);
  196. } else {
  197.     result = RectangleOut;
  198. }
  199. #endif
  200. CFRelease(sectRgn);
  201. CFRelease(rectRgn);
  202.     ) TK_ENDIF
  203.     return result;
  204. }
  205. /*
  206.  *----------------------------------------------------------------------
  207.  *
  208.  * TkClipBox --
  209.  *
  210.  * Implements the equivelent of the X window function XClipBox.
  211.  * See X window documentation for more details.
  212.  *
  213.  * Results:
  214.  * None.
  215.  *
  216.  * Side effects:
  217.  * None.
  218.  *
  219.  *----------------------------------------------------------------------
  220.  */
  221. void
  222. TkClipBox(
  223.     TkRegion r,
  224.     XRectangle* rect_return)
  225. {
  226.     CGRect rect;
  227.     
  228.     HIShapeGetBounds((HIShapeRef) r, &rect);
  229.     rect_return->x = rect.origin.x;
  230.     rect_return->y = rect.origin.y;
  231.     rect_return->width = rect.size.width;
  232.     rect_return->height = rect.size.height;
  233. }
  234. /*
  235.  *----------------------------------------------------------------------
  236.  *
  237.  * TkpBuildRegionFromAlphaData --
  238.  *
  239.  * Set up a rectangle of the given region based on the supplied
  240.  * alpha data.
  241.  *
  242.  * Results:
  243.  * None
  244.  *
  245.  * Side effects:
  246.  * The region is updated, with extra pixels added to it.
  247.  *
  248.  *----------------------------------------------------------------------
  249.  */
  250. void
  251. TkpBuildRegionFromAlphaData(
  252.     TkRegion region, /* Region to update. */
  253.     unsigned int x, /* Where in region to update. */
  254.     unsigned int y, /* Where in region to update. */
  255.     unsigned int width, /* Size of rectangle to update. */
  256.     unsigned int height, /* Size of rectangle to update. */
  257.     unsigned char *dataPtr, /* Data to read from. */
  258.     unsigned int pixelStride, /* num bytes from one piece of alpha
  259.  * data to the next in the line. */
  260.     unsigned int lineStride) /* num bytes from one line of alpha
  261.  * data to the next line. */
  262. {
  263.     unsigned char *lineDataPtr;
  264.     unsigned int x1, y1, end;
  265.     XRectangle rect;
  266.     for (y1 = 0; y1 < height; y1++) {
  267. lineDataPtr = dataPtr;
  268. for (x1 = 0; x1 < width; x1 = end) {
  269.     /* search for first non-transparent pixel */
  270.     while ((x1 < width) && !*lineDataPtr) {
  271. x1++;
  272. lineDataPtr += pixelStride;
  273.     }
  274.     end = x1;
  275.     /* search for first transparent pixel */
  276.     while ((end < width) && *lineDataPtr) {
  277. end++;
  278. lineDataPtr += pixelStride;
  279.     }
  280.     if (end > x1) {
  281. rect.x = x + x1;
  282. rect.y = y + y1;
  283. rect.width = end - x1;
  284. rect.height = 1;
  285. TkUnionRectWithRegion(&rect, region, region);
  286.     }
  287. }
  288. dataPtr += lineStride;
  289.     }
  290. }
  291. /*
  292.  *----------------------------------------------------------------------
  293.  *
  294.  * TkpRetainRegion --
  295.  *
  296.  * Increases reference count of region.
  297.  *
  298.  * Results:
  299.  * None.
  300.  *
  301.  * Side effects:
  302.  * None.
  303.  *
  304.  *----------------------------------------------------------------------
  305.  */
  306. void
  307. TkpRetainRegion(
  308.     TkRegion r)
  309. {
  310.     CFRetain(r);
  311. }
  312. /*
  313.  *----------------------------------------------------------------------
  314.  *
  315.  * TkpReleaseRegion --
  316.  *
  317.  * Decreases reference count of region.
  318.  *
  319.  * Results:
  320.  * None.
  321.  *
  322.  * Side effects:
  323.  * May free memory.
  324.  *
  325.  *----------------------------------------------------------------------
  326.  */
  327. void
  328. TkpReleaseRegion(
  329.     TkRegion r)
  330. {
  331.     CFRelease(r);
  332. }
  333. #if 0
  334. /*
  335.  *----------------------------------------------------------------------
  336.  *
  337.  * TkMacOSXEmtpyRegion --
  338.  *
  339.  * Set region to emtpy.
  340.  *
  341.  * Results:
  342.  * None.
  343.  *
  344.  * Side effects:
  345.  * None.
  346.  *
  347.  *----------------------------------------------------------------------
  348.  */
  349. void
  350. TkMacOSXEmtpyRegion(
  351.     TkRegion r)
  352. {
  353.     ChkErr(HIShapeSetEmpty, (HIMutableShapeRef) r);
  354. }
  355. /*
  356.  *----------------------------------------------------------------------
  357.  *
  358.  * TkMacOSXIsEmptyRegion --
  359.  *
  360.  * Return native region for given tk region.
  361.  *
  362.  * Results:
  363.  * 1 if empty, 0 otherwise.
  364.  *
  365.  * Side effects:
  366.  * None.
  367.  *
  368.  *----------------------------------------------------------------------
  369.  */
  370. int
  371. TkMacOSXIsEmptyRegion(
  372.     TkRegion r)
  373. {
  374.     return HIShapeIsEmpty((HIMutableShapeRef) r) ? 1 : 0;
  375. }
  376. #endif
  377. /*
  378.  *----------------------------------------------------------------------
  379.  *
  380.  * TkMacOSXGetNativeRegion --
  381.  *
  382.  * Return native region for given tk region.
  383.  *
  384.  * Results:
  385.  * Native region, CFRelease when done.
  386.  *
  387.  * Side effects:
  388.  * None.
  389.  *
  390.  *----------------------------------------------------------------------
  391.  */
  392. HIShapeRef
  393. TkMacOSXGetNativeRegion(
  394.     TkRegion r)
  395. {
  396.     return (HIShapeRef) CFRetain(r);
  397. }
  398. /*
  399.  *----------------------------------------------------------------------
  400.  *
  401.  * TkMacOSXSetWithNativeRegion --
  402.  *
  403.  * Set region to the native region.
  404.  *
  405.  * Results:
  406.  * None.
  407.  *
  408.  * Side effects:
  409.  * None.
  410.  *
  411.  *----------------------------------------------------------------------
  412.  */
  413. void
  414. TkMacOSXSetWithNativeRegion(
  415.     TkRegion r,
  416.     HIShapeRef rgn)
  417. {
  418.     ChkErr(TkMacOSXHIShapeSetWithShape, (HIMutableShapeRef) r, rgn);
  419. }
  420. /*
  421.  *----------------------------------------------------------------------
  422.  *
  423.  * TkMacOSXOffsetRegion --
  424.  *
  425.  * Offsets region by given distances.
  426.  *
  427.  * Results:
  428.  * None.
  429.  *
  430.  * Side effects:
  431.  * None.
  432.  *
  433.  *----------------------------------------------------------------------
  434.  */
  435. void
  436. TkMacOSXOffsetRegion(
  437.     TkRegion r,
  438.     short dx,
  439.     short dy)
  440. {
  441.     ChkErr(HIShapeOffset, (HIMutableShapeRef) r, dx, dy);
  442. }
  443. /*
  444.  *----------------------------------------------------------------------
  445.  *
  446.  * TkMacOSXHIShapeCreateEmpty, TkMacOSXHIShapeCreateMutableWithRect,
  447.  * TkMacOSXHIShapeSetWithShape, TkMacOSXHIShapeSetWithRect,
  448.  * TkMacOSHIShapeDifferenceWithRect, TkMacOSHIShapeUnionWithRect,
  449.  * TkMacOSHIShapeUnion --
  450.  *
  451.  * Wrapper functions for missing/buggy HIShape API
  452.  *
  453.  *----------------------------------------------------------------------
  454.  */
  455. HIShapeRef
  456. TkMacOSXHIShapeCreateEmpty(void)
  457. {
  458.     HIShapeRef result;
  459.     TK_IF_MAC_OS_X_API (4, HIShapeCreateEmpty,
  460. result = HIShapeCreateEmpty();
  461.     ) TK_ELSE_MAC_OS_X (4,
  462. static HIShapeRef emptyRgn = NULL;
  463. if (!emptyRgn) {
  464.     HIMutableShapeRef rgn = HIShapeCreateMutable();
  465.     emptyRgn = HIShapeCreateCopy(rgn);
  466.     CFRelease(rgn);
  467. }
  468. result = HIShapeCreateCopy(emptyRgn);
  469.     ) TK_ENDIF
  470.     return result;
  471. }
  472. HIMutableShapeRef
  473. TkMacOSXHIShapeCreateMutableWithRect(
  474.     const CGRect *inRect)
  475. {
  476.     HIMutableShapeRef result;
  477.     TK_IF_MAC_OS_X_API (5, HIShapeCreateMutableWithRect,
  478. result = HIShapeCreateMutableWithRect(inRect);
  479.     ) TK_ELSE_MAC_OS_X (5,
  480. HIShapeRef rgn = HIShapeCreateWithRect(inRect);
  481. result = HIShapeCreateMutableCopy(rgn);
  482. CFRelease(rgn);
  483.     ) TK_ENDIF
  484.     return result;
  485. }
  486. OSStatus
  487. TkMacOSXHIShapeSetWithShape(
  488.     HIMutableShapeRef inDestShape,
  489.     HIShapeRef inSrcShape)
  490. {
  491.     OSStatus result;
  492.     TK_IF_MAC_OS_X_API (5, HIShapeSetWithShape,
  493. result = HIShapeSetWithShape(inDestShape, inSrcShape);
  494.     ) TK_ELSE_MAC_OS_X (5,
  495. result = HIShapeSetEmpty(inDestShape);
  496. if (result == noErr) {
  497.     result = HIShapeDifference(inSrcShape, inDestShape, inDestShape);
  498. }
  499.     ) TK_ENDIF
  500.     return result;
  501. }
  502. #if 0
  503. OSStatus
  504. TkMacOSXHIShapeSetWithRect(
  505.     HIMutableShapeRef inShape,
  506.     const CGRect *inRect)
  507. {
  508.     OSStatus result;
  509.     HIShapeRef rgn = HIShapeCreateWithRect(inRect);
  510.     result = TkMacOSXHIShapeSetWithShape(inShape, rgn);
  511.     CFRelease(rgn);
  512.     return result;
  513. }
  514. #endif
  515. OSStatus
  516. TkMacOSHIShapeDifferenceWithRect(
  517.     HIMutableShapeRef inShape,
  518.     const CGRect *inRect)
  519. {
  520.     OSStatus result;
  521.     HIShapeRef rgn = HIShapeCreateWithRect(inRect);
  522.     result = HIShapeDifference(inShape, rgn, inShape);
  523.     CFRelease(rgn);
  524.     return result;
  525. }
  526. OSStatus
  527. TkMacOSHIShapeUnionWithRect(
  528.     HIMutableShapeRef inShape,
  529.     const CGRect *inRect)
  530. {
  531.     OSStatus result;
  532.     TK_IF_MAC_OS_X_API (5, HIShapeUnionWithRect,
  533. result = HIShapeUnionWithRect(inShape, inRect);
  534.     ) TK_ELSE_MAC_OS_X (5,
  535. HIShapeRef rgn = HIShapeCreateWithRect(inRect);
  536. result = TkMacOSHIShapeUnion(rgn, inShape, inShape);
  537. CFRelease(rgn);
  538.     ) TK_ENDIF
  539.     return result;
  540. }
  541. OSStatus
  542. TkMacOSHIShapeUnion(
  543.     HIShapeRef inShape1,
  544.     HIShapeRef inShape2,
  545.     HIMutableShapeRef outResult)
  546. {
  547.     OSStatus result;
  548.     TK_IF_HI_TOOLBOX (4,
  549. result = HIShapeUnion(inShape1, inShape2, outResult);
  550.     ) TK_ELSE_HI_TOOLBOX (4,
  551. /* Workaround HIShapeUnion bug in 10.3 and earlier */
  552. HIShapeRef rgn = HIShapeCreateCopy(outResult);
  553. result = HIShapeUnion(inShape1, inShape2, (HIMutableShapeRef) rgn);
  554. if (result == noErr) {
  555.     result = HIShapeSetEmpty(outResult);
  556.     if (result == noErr) {
  557. result = HIShapeDifference(rgn, outResult, outResult);
  558.     }
  559. }
  560. CFRelease(rgn);
  561.     ) TK_ENDIF
  562.     return result;
  563. }