home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / cmd / macfe / gui / CDeviceLoop.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  5.6 KB  |  170 lines

  1. /* -*- Mode: C++; tab-width: 4; 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.  
  20. /*====================================================================================*/
  21.     #pragma mark INCLUDE FILES
  22. /*====================================================================================*/
  23.  
  24. #include "CDeviceLoop.h"
  25.  
  26.  
  27. /*====================================================================================*/
  28.     #pragma mark TYPEDEFS
  29. /*====================================================================================*/
  30.  
  31.  
  32. /*====================================================================================*/
  33.     #pragma mark CONSTANTS
  34. /*====================================================================================*/
  35.  
  36.  
  37. /*====================================================================================*/
  38.     #pragma mark INTERNAL CLASS DECLARATIONS
  39. /*====================================================================================*/
  40.  
  41.  
  42. /*====================================================================================*/
  43.     #pragma mark INTERNAL FUNCTION PROTOTYPES
  44. /*====================================================================================*/
  45.  
  46.  
  47. /*====================================================================================*/
  48.     #pragma mark CLASS IMPLEMENTATIONS
  49. /*====================================================================================*/
  50.  
  51. #pragma mark -
  52.  
  53. /*======================================================================================
  54.     Constructor.
  55. ======================================================================================*/
  56.  
  57. CDeviceLoop::CDeviceLoop(const Rect &inLocalRect, Int16 &outFirstDepth) {
  58.  
  59.     mSaveClip = nil;
  60.     mGlobalRect = inLocalRect;            // Convert to Global coords
  61.     ::LocalToGlobal(&topLeft(mGlobalRect));
  62.     ::LocalToGlobal(&botRight(mGlobalRect));
  63.     mCurrentDevice = nil;
  64.     
  65.     outFirstDepth = 0;
  66.     NextDepth(outFirstDepth);
  67. }
  68.     
  69.  
  70. /*======================================================================================
  71.     Destructor.
  72. ======================================================================================*/
  73.  
  74. CDeviceLoop::~CDeviceLoop(void) {
  75.  
  76.     if ( mSaveClip != nil ) {                // Restore clipping region
  77.         ::SetClip(mSaveClip);
  78.         ::DisposeRgn(mSaveClip);
  79.         mSaveClip = nil;
  80.     }
  81. }
  82.  
  83.  
  84. /*======================================================================================
  85.     Get the next drawing depth, return false if none.
  86. ======================================================================================*/
  87.  
  88. static Boolean RectEnclosesRect(const Rect *inEnclosingRect, const Rect *inTestRect) {
  89.  
  90.     return ((inEnclosingRect->top <= inTestRect->top) && 
  91.             (inEnclosingRect->left <= inTestRect->left) &&
  92.             (inEnclosingRect->right >= inTestRect->right) &&
  93.             (inEnclosingRect->bottom >= inTestRect->bottom));
  94. }
  95.  
  96. Boolean CDeviceLoop::NextDepth(Int16 &outNextDepth) {
  97.  
  98.     if ( mCurrentDevice ) {
  99.         if ( !mSaveClip ) {
  100.             // The first device we found that contained any portion of the specified
  101.             // rectangle actually contained ALL of the rectangle, so exit here.
  102.             return false;
  103.         }
  104.         mCurrentDevice = GetNextDevice(mCurrentDevice);
  105.     } else {
  106.         mCurrentDevice = GetDeviceList();
  107.     }
  108.  
  109.     // Locate the first device for processing
  110.     
  111.     while ( mCurrentDevice ) {
  112.     
  113.         if ( ::TestDeviceAttribute(mCurrentDevice, screenDevice) &&
  114.              ::TestDeviceAttribute(mCurrentDevice, screenActive) ) {
  115.             
  116.             Rect deviceRect = (**mCurrentDevice).gdRect, intersection;
  117.             
  118.             if ( ::SectRect(&mGlobalRect, &deviceRect, &intersection) ) {
  119.             
  120.                 // Some portion of the device rect encloses the specified rect
  121.             
  122.                 outNextDepth = (**((**mCurrentDevice).gdPMap)).pixelSize;
  123.  
  124.                 if ( !mSaveClip ) {
  125.                     if ( RectEnclosesRect(&deviceRect, &mGlobalRect) ) {
  126.                         // Specified rectangle is completely enclosed within this device
  127.                         // DON'T create a clipping region and exit here
  128.                         break;
  129.                     } else {
  130.                         mSaveClip = ::NewRgn();                // Save clipping region
  131.                         if ( mSaveClip ) {
  132.                             ::GetClip(mSaveClip);
  133.                         }
  134.                     }
  135.                 }
  136.                 
  137.                 // Set clipping region to the intersection of the target
  138.                 // rectangle, the screen rectangle, and the original
  139.                 // clipping region
  140.  
  141.                 ::GlobalToLocal(&topLeft(intersection));
  142.                 ::GlobalToLocal(&botRight(intersection));
  143.                 ClipToIntersection(intersection);
  144.                 break;                // Exit device loop
  145.             }
  146.         }
  147.         
  148.         mCurrentDevice = ::GetNextDevice(mCurrentDevice);
  149.     }
  150.     
  151.     return (mCurrentDevice != nil);
  152. }
  153.     
  154.  
  155. /*======================================================================================
  156.     Draw the control.
  157. ======================================================================================*/
  158.  
  159. void CDeviceLoop::ClipToIntersection(const Rect &inLocalRect) {
  160.  
  161.     if ( mSaveClip ) {
  162.         RgnHandle overlap = ::NewRgn();
  163.         ::RectRgn(overlap, &inLocalRect);
  164.         ::SectRgn(mSaveClip, overlap, overlap);
  165.         ::SetClip(overlap);
  166.         ::DisposeRgn(overlap);
  167.     }
  168. }
  169.  
  170.