home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / winfe / region.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  8.5 KB  |  384 lines

  1. /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
  2.  *
  3.  * The contents of this file are subject to the Netscape Public License
  4.  * Version 1.0 (the "NPL"); you may not use this file except in
  5.  * compliance with the NPL.  You may obtain a copy of the NPL at
  6.  * http://www.mozilla.org/NPL/
  7.  *
  8.  * Software distributed under the NPL is distributed on an "AS IS" basis,
  9.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
  10.  * for the specific language governing rights and limitations under the
  11.  * NPL.
  12.  *
  13.  * The Initial Developer of this code under the NPL is Netscape
  14.  * Communications Corporation.  Portions created by Netscape are
  15.  * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
  16.  * Reserved.
  17.  */
  18. /* 
  19.  *   region.cpp --- FE specific region operations
  20.  */
  21.  
  22.  
  23.  
  24. #include "stdafx.h"
  25.  
  26. //mwh don't use MFC on Nav 4.0
  27. //#define RGN_USE_MFC
  28.  
  29. /* Creates an empty region. Returns NULL if region can't be created */
  30. FE_Region 
  31. FE_CreateRegion()
  32. {
  33. #ifdef FE_RGN_USE_MFC
  34.     CRgn *pRgn = new CRgn;
  35.  
  36.     pRgn->CreateRectRgn(0, 0, 0, 0);
  37.  
  38.     return (FE_Region)pRgn;
  39. #else
  40.     return (FE_Region)CreateRectRgn(0, 0, 0, 0);
  41. #endif
  42. }
  43.  
  44. /* Creates a region from a rectangle. Returns NULL if region can't be created */
  45. FE_Region
  46. FE_CreateRectRegion(XP_Rect *rect)
  47. {
  48. #ifdef FE_RGN_USE_MFC
  49.     CRgn *pRgn = new CRgn;
  50.     pRgn->CreateRectRgn(rect->left, rect->top, rect->right, rect->bottom);
  51.     return (FE_Region)pRgn;
  52. #else
  53. //    return (FE_Region)CreateRectRgn(rect->left, rect->top, 
  54. //                                    rect->right, rect->bottom);
  55.     HRGN rgn = CreateRectRgn(CASTINT(rect->left), CASTINT(rect->top), 
  56.                                     CASTINT(rect->right), CASTINT(rect->bottom));
  57.     if (rgn) return (FE_Region)rgn;
  58.     else
  59.         return (FE_Region)CreateRectRgn(0, 0, 0, 0);
  60. #endif
  61. }
  62.  
  63. /* Set an existing region to a rectangle */
  64. FE_Region 
  65. FE_SetRectRegion(FE_Region region, XP_Rect *rect)
  66. {
  67.     XP_ASSERT(region);
  68. #ifdef FE_RGN_USE_MFC
  69.     ((CRgn *)region)->SetRectRgn(rect->left, rect->top,
  70.                                rect->right, rect->bottom);
  71.     return region;
  72. #else
  73.     ::SetRectRgn((HRGN)region, CASTINT(rect->left), CASTINT(rect->top),
  74.                                CASTINT(rect->right), CASTINT(rect->bottom));
  75.     return region;
  76. #endif
  77. }
  78.  
  79. /* Destroys region */
  80. void
  81. FE_DestroyRegion(FE_Region region)
  82. {
  83. #ifndef FE_RGN_USE_MFC
  84.     BOOL result;
  85. #endif
  86.     
  87.     XP_ASSERT(region);
  88.     
  89. #ifdef FE_RGN_USE_MFC
  90.     ((CRgn *)region)->DeleteObject();
  91.     delete ((CRgn *)region);
  92. #else
  93.     result = DeleteObject((HRGN)region);
  94.  
  95.     XP_ASSERT(result);
  96. #endif
  97. }
  98.  
  99. /* Make a copy of a region */
  100. FE_Region
  101. FE_CopyRegion(FE_Region src, FE_Region dst)
  102. {
  103.  
  104. #ifdef FE_RGN_USE_MFC
  105.     CRgn * pCopyRgn;
  106.  
  107.     XP_ASSERT(src);
  108.  
  109.     if (dst != NULL) 
  110.         pCopyRgn = (CRgn *)dst;
  111.     else {
  112.         pCopyRgn = new CRgn;
  113.         pCopyRgn->CreateRectRgn(0, 0, 0, 0);
  114.     }
  115.  
  116.     pCopyRgn->CopyRgn((CRgn *)src);
  117.     
  118.     return pCopyRgn;
  119. #else
  120.     HRGN copyRegion;
  121.   
  122.     XP_ASSERT(src);
  123.   
  124.     if (dst != NULL)
  125.       copyRegion = (HRGN)dst;
  126.     else {
  127.         /* Create an empty region */
  128.         copyRegion = CreateRectRgn(0, 0, 0, 0);
  129.         
  130.         if (copyRegion == NULL)
  131.           return NULL;
  132.     }
  133.     
  134.     /* Copy the region */
  135.     if (CombineRgn(copyRegion, 
  136.                    (HRGN)src, 
  137.                    (HRGN)src, 
  138.                    RGN_COPY) == ERROR) {
  139.         DeleteObject(copyRegion);
  140.         return NULL;
  141.     }
  142.   
  143.     return (FE_Region)copyRegion;
  144. #endif
  145. }
  146.  
  147. /* dst = src1 intersect sr2       */
  148. /* dst can be one of src1 or src2 */
  149. void
  150. FE_IntersectRegion(FE_Region src1, FE_Region src2, FE_Region dst)
  151. {
  152.     XP_ASSERT(src1);
  153.     XP_ASSERT(src2);
  154.     XP_ASSERT(dst);
  155.  
  156. #ifdef FE_RGN_USE_MFC
  157.     ((CRgn *)dst)->CombineRgn((CRgn *)src1, (CRgn *)src2, RGN_AND);
  158. #else
  159.     CombineRgn((HRGN)dst, (HRGN)src1, (HRGN)src2, RGN_AND);
  160. #endif
  161. }
  162.  
  163. /* dst = src1 union src2          */
  164. /* dst can be one of src1 or src2 */
  165. void
  166. FE_UnionRegion(FE_Region src1, FE_Region src2, FE_Region dst)
  167. {
  168.     XP_ASSERT(src1);
  169.     XP_ASSERT(src2);
  170.     XP_ASSERT(dst);
  171.  
  172. #ifdef FE_RGN_USE_MFC
  173.     ((CRgn *)dst)->CombineRgn((CRgn *)src1, (CRgn *)src2, RGN_OR);
  174. #else
  175.     CombineRgn((HRGN)dst, (HRGN)src1, (HRGN)src2, RGN_OR);
  176. #endif
  177. }
  178.  
  179. /* dst = src1 - src2              */
  180. /* dst can be one of src1 or src2 */
  181. void
  182. FE_SubtractRegion(FE_Region src1, FE_Region src2, FE_Region dst)
  183. {
  184.     XP_ASSERT(src1);
  185.     XP_ASSERT(src2);
  186.     XP_ASSERT(dst);
  187.  
  188. #ifdef FE_RGN_USE_MFC
  189.     ((CRgn *)dst)->CombineRgn((CRgn *)src1, (CRgn *)src2, RGN_DIFF);
  190. #else
  191.     CombineRgn((HRGN)dst, (HRGN)src1, (HRGN)src2, RGN_DIFF);
  192. #endif
  193. }
  194.  
  195. /* Returns TRUE if the region contains no pixels */
  196. XP_Bool
  197. FE_IsEmptyRegion(FE_Region region)
  198. {
  199.     int result;
  200.     
  201.     XP_ASSERT(region);
  202.     
  203. #ifdef FE_RGN_USE_MFC
  204.     result = ((CRgn *)region)->OffsetRgn(0, 0);
  205. #else
  206.     /* This might not be the best way to find out, but it's one of them */
  207.     result = OffsetRgn((HRGN)region, 0, 0);
  208. #endif
  209.     
  210.     if (result == NULLREGION)
  211.       return TRUE;
  212.     else
  213.       return FALSE;
  214. }
  215.  
  216. /* Returns the bounding rectangle of the region */
  217. void
  218. FE_GetRegionBoundingBox(FE_Region region, XP_Rect *bbox)
  219. {
  220.     RECT rect;
  221.  
  222.     XP_ASSERT(region);
  223.     XP_ASSERT(bbox);
  224.     
  225. #ifdef FE_RGN_USE_MFC
  226.     ((CRgn *)region)->GetRgnBox((LPRECT)&rect);
  227. #else
  228.     GetRgnBox((HRGN)region, (LPRECT)&rect);
  229. #endif
  230.  
  231.     bbox->left = rect.left;
  232.     bbox->top = rect.top;
  233.     bbox->right = rect.right;
  234.     bbox->bottom = rect.bottom;
  235. }
  236.  
  237. /* TRUE if rgn1 == rgn2 */
  238. XP_Bool
  239. FE_IsEqualRegion(FE_Region rgn1, FE_Region rgn2)
  240. {
  241.     XP_ASSERT(rgn1);
  242.     XP_ASSERT(rgn2);
  243.     
  244. #ifdef FE_RGN_USE_MFC
  245.     return ((CRgn *)rgn1)->EqualRgn((CRgn *)rgn2);
  246. #else
  247.     return (EqualRgn((HRGN)rgn1, (HRGN)rgn2));
  248. #endif
  249. }
  250.  
  251. /* Moves a region by the specified offsets */
  252. void
  253. FE_OffsetRegion(FE_Region region, int32 x_offset, int32 y_offset)
  254. {
  255.     int result;
  256.     
  257. #ifdef FE_RGN_USE_MFC
  258.     result = ((CRgn *)region)->OffsetRgn(x_offset, y_offset);
  259. #else
  260.     result = OffsetRgn((HRGN)region, CASTINT(x_offset), CASTINT(y_offset));
  261. #endif
  262.  
  263.     XP_ASSERT(result != ERROR);
  264. }
  265.  
  266. /* Returns TRUE if any part of the rectangle is in the specified region */
  267. XP_Bool
  268. FE_RectInRegion(FE_Region region, XP_Rect *rect)
  269. {
  270.    RECT box;
  271.  
  272.    XP_ASSERT(region);
  273.    XP_ASSERT(rect);
  274.  
  275.    box.left = CASTINT(rect->left);
  276.    box.top = CASTINT(rect->top);
  277.    box.right = CASTINT(rect->right);
  278.    box.bottom = CASTINT(rect->bottom);
  279.  
  280. #ifdef FE_RGN_USE_MFC
  281.    return ((CRgn *)region)->RectInRegion(&box);
  282. #else
  283.    return RectInRegion((HRGN)region, &box);
  284. #endif
  285. }
  286.  
  287. /* Calls the specified function for each rectangle that makes up the region */
  288. void
  289. FE_ForEachRectInRegion(FE_Region region, FE_RectInRegionFunc func, void *closure)
  290. {
  291. #ifndef _WIN32
  292.     /* 
  293.      * For 16-bit Windows, we can't get at the rectangles that make up a region,
  294.      * so we just call the function with the bounding box of the entire region.
  295.      */
  296.     RECT rect;
  297.     XP_Rect xprect;
  298.  
  299. #ifdef FE_RGN_USE_MFC
  300.     ((CRgn *)region)->GetRgnBox((LPRECT)&rect);
  301. #else
  302.     GetRgnBox((HRGN)region, (LPRECT)&rect);
  303. #endif
  304.  
  305.     xprect.left = rect.left;
  306.     xprect.top = rect.top;
  307.     xprect.right = rect.right;
  308.     xprect.bottom = rect.bottom;
  309.     (*func)(closure, &xprect);
  310.     
  311. #else
  312.     LPRGNDATA pRgnData;
  313.     LPRECT pRects;
  314.     DWORD dwCount, dwResult;
  315.     unsigned int num_rects;
  316.     XP_Rect rect;
  317. #ifdef FE_RGN_USE_MFC
  318.     CRgn *pRgn = (CRgn *)region;
  319. #endif
  320.  
  321.     XP_ASSERT(region);
  322.     XP_ASSERT(func);
  323.  
  324.     /* Get the size of the region data */
  325. #ifdef FE_RGN_USE_MFC
  326.     dwCount = pRgn->GetRegionData(NULL, 0);
  327. #else
  328.     dwCount = GetRegionData((HRGN)region, 0, NULL);
  329. #endif
  330.  
  331.     XP_ASSERT(dwCount != 0);
  332.     if (dwCount == 0)
  333.       return;
  334.  
  335.     pRgnData = (LPRGNDATA)XP_ALLOC(dwCount);
  336.  
  337.     XP_ASSERT(pRgnData != NULL);
  338.     if (pRgnData == NULL)
  339.       return;
  340.  
  341. #ifdef FE_RGN_USE_MFC
  342.     dwResult = pRgn->GetRegionData(pRgnData, dwCount);
  343. #else
  344.     dwResult = GetRegionData((HRGN)region, dwCount, pRgnData);
  345. #endif
  346.  
  347.     XP_ASSERT(dwResult != 0);
  348.     if (dwResult == 0) {
  349.         XP_FREE(pRgnData);
  350.         return;
  351.     }
  352.   
  353.     for (pRects = (LPRECT)pRgnData->Buffer, num_rects = 0; 
  354.          num_rects < pRgnData->rdh.nCount; 
  355.          num_rects++, pRects++) {
  356.         rect.left = pRects->left;
  357.         rect.top = pRects->top;
  358.         rect.right = pRects->right;
  359.         rect.bottom = pRects->bottom;
  360.         (*func)(closure, &rect);
  361.     }
  362.  
  363.     XP_FREE(pRgnData);
  364. #endif /* XP_WIN32 */
  365. }
  366.  
  367. void
  368. FE_HighlightRegion(void *pC, FE_Region region, int how_much)
  369. {
  370. #if defined(DEBUG) && defined(_WIN32)
  371.     MWContext *pContext = (MWContext *)pC;
  372.     HDC    hdc = ::GetDC(PANECX(pContext)->GetPane());
  373.  
  374.     InvertRgn(hdc, (HRGN)region);
  375.     Sleep(how_much * 2 / 3);
  376.     InvertRgn(hdc, (HRGN)region);
  377.     Sleep(how_much / 3);
  378.     ::ReleaseDC(PANECX(pContext)->GetPane(), hdc);
  379. #else
  380.     XP_ASSERT(0);                /* Not supported on Win16 */
  381. #endif
  382. }
  383.  
  384.