home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / lib / mac / UserInterface / CSharedPatternWorld.cp < prev    next >
Encoding:
Text File  |  1998-04-08  |  9.5 KB  |  324 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. #include "CSharedPatternWorld.h"
  20. #include "UGraphicGizmos.h"
  21.  
  22. #include <LArray.h>
  23. #include <LArrayIterator.h>
  24.  
  25. LArray* CSharedPatternWorld::sPatterns = NULL;
  26. Boolean CSharedPatternWorld::sUseUtilityPattern = false;
  27.  
  28. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  29. //    Ñ    CreateSharedPatternWorld                            [ static ]
  30. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  31.  
  32. CSharedPatternWorld* CSharedPatternWorld::CreateSharedPatternWorld(ResIDT inPatternID)
  33. {
  34.     CSharedPatternWorld* thePatternWorld = NULL;
  35.     
  36.     if (sUseUtilityPattern)
  37.         inPatternID = cUtilityPatternResID;
  38.     
  39.     try
  40.         {
  41.         if (sPatterns == NULL)
  42.             sPatterns = new LArray(sizeof(CSharedPatternWorld*));
  43.         
  44.         CSharedPatternWorld* theIndexWorld = NULL;    
  45.         LArrayIterator theIter(*sPatterns, LArrayIterator::from_Start);
  46.         while (theIter.Next(&theIndexWorld))
  47.             {
  48.             if (theIndexWorld->mPatternID == inPatternID)
  49.                 {
  50.                 thePatternWorld = theIndexWorld;
  51.                 break;
  52.                 }
  53.             }
  54.         
  55.         if (thePatternWorld == NULL)
  56.             thePatternWorld = new CSharedPatternWorld(inPatternID);
  57.         }
  58.     catch (...)
  59.         {
  60.         delete thePatternWorld;
  61.         thePatternWorld = NULL;        
  62.         }
  63.  
  64.     return thePatternWorld;
  65. }
  66.  
  67. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  68. //    Ñ    CalcRelativePoint                                [ static ]
  69. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  70.  
  71. void CSharedPatternWorld::CalcRelativePoint(
  72.     LPane*                    inForPane,
  73.     EPatternOrientation        inOrientation,
  74.     Point&                     outPoint)
  75. {
  76.     // the downward scale from 32 to 16 bit coordinate spaces
  77.     // in converting from SPoint32 to plain old Point
  78.     // is ok because we are guaranteed to be in bounds since we
  79.     // wont be drawing if we cant FocusExposed().
  80.  
  81.     switch (inOrientation)
  82.         {
  83.         case CSharedPatternWorld::eOrientation_Self:
  84.             {
  85.             SPoint32 theFrameLocation;
  86.             inForPane->GetFrameLocation(theFrameLocation);
  87.             outPoint.h = theFrameLocation.h;
  88.             outPoint.v = theFrameLocation.v;
  89.             inForPane->PortToLocalPoint(outPoint);
  90.             }
  91.             break;
  92.             
  93.         case CSharedPatternWorld::eOrientation_Superview:
  94.             {
  95.             SPoint32 theFrameLocation;
  96.             inForPane->GetSuperView()->GetFrameLocation(theFrameLocation);
  97.             outPoint.h = -theFrameLocation.h;
  98.             outPoint.v = -theFrameLocation.v;
  99.             inForPane->PortToLocalPoint(outPoint);
  100.             }
  101.             break;
  102.             
  103.         case CSharedPatternWorld::eOrientation_Port:
  104.             {
  105.             SPoint32 theFrameLocation;
  106.             inForPane->GetFrameLocation(theFrameLocation);
  107.             outPoint.h = -theFrameLocation.h;
  108.             outPoint.v = -theFrameLocation.v;
  109.             }
  110.             break;
  111.         }
  112. }
  113.  
  114.  
  115.  
  116. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  117. //    Ñ    CSharedPatternWorld
  118. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  119.  
  120. CSharedPatternWorld::CSharedPatternWorld(ResIDT inPatternID)
  121. {
  122.     PixPatHandle thePattern = NULL;
  123.     
  124.     mPatternWorld = NULL;
  125.     mPatternHandle = NULL;
  126.  
  127.     try
  128.         {
  129.         mPatternID = inPatternID;
  130.         thePattern  = ::GetPixPat(inPatternID);
  131.         ThrowIfResFail_(thePattern);
  132.         
  133.         // If our pix map is 8 bits or less deep we can avoid making an
  134.         // offscreen world to store the pattern.
  135.         PixMapHandle thePatPixMap = (*thePattern)->patMap;    
  136.         mIsShallow = ((*thePatPixMap)->pixelSize <= 8);
  137.  
  138.         if (!IsShallow())
  139.             {
  140.             // We have a pattern that is deeper than 8 bits.  As documented
  141.             // in the header file, QuickDraw will draw the pattern differently
  142.             // in this case.  We need to create an offscreen copy of the pattern
  143.             // so that we can draw it ourselves.
  144.             
  145.             // Get the pattern's rect from its pix map and normalize
  146.             Rect thePatternFrame = (*thePatPixMap)->bounds;
  147.             ::OffsetRect(&thePatternFrame, -thePatternFrame.left, -thePatternFrame.top);
  148.     
  149.             // make an offscreen world the same size as the pattern
  150.             mPatternWorld = new CGWorld(thePatternFrame, (*thePatPixMap)->pixelSize, 0, (*thePatPixMap)->pmTable);
  151.     
  152.             // and draw into it
  153.             ThrowIfNot_(mPatternWorld->BeginDrawing());
  154.             ::FillCRect(&thePatternFrame, thePattern);
  155.             mPatternWorld->EndDrawing();        
  156.  
  157.             // Ok, we've successfully copied the pattern so we can get
  158.             // rid of the pattern handle.
  159.             ::DisposePixPat(thePattern);
  160.             }
  161.         else
  162.             {
  163.             // the pattern is 8 bits or less.  We'll just keep the pattern
  164.             // handle around for drawing.
  165.             mPatternHandle = thePattern;            
  166.             }
  167.         // add this to static shared pattern list
  168.         Assert_(sPatterns);
  169.         sPatterns->InsertItemsAt(1, LArray::index_Last, &this);
  170.         }
  171.     catch (...)
  172.         {
  173.         delete mPatternWorld;
  174.         mPatternWorld = NULL;
  175.         
  176.         if (thePattern != NULL)
  177.             ::DisposePixPat(thePattern);
  178.         
  179.         throw;
  180.         }
  181. }
  182.  
  183. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  184. //    Ñ    ~CSharedPatternWorld
  185. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  186.  
  187. CSharedPatternWorld::~CSharedPatternWorld()
  188. {
  189.     // remove this from static shared pattern list
  190.     Assert_(sPatterns);
  191.     sPatterns->Remove(&this);
  192.     
  193.     if (mPatternHandle != NULL)
  194.         ::DisposePixPat(mPatternHandle);
  195.  
  196.     delete mPatternWorld;
  197. }
  198.  
  199.  
  200. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  201. //    Ñ    Fill             (Rect)
  202. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  203.  
  204. void CSharedPatternWorld::Fill(
  205.     CGrafPtr                inPort,
  206.     const Rect&             inBounds,
  207.     Point                    inAlignTo)
  208. {
  209.     if (IsShallow())
  210.         FillShallow(inPort, inBounds, inAlignTo);
  211.     else
  212.         FillDeep(inPort, inBounds, inAlignTo);
  213. }
  214.  
  215. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  216. //    Ñ    Fill            (Region)
  217. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  218.  
  219. void CSharedPatternWorld::Fill(
  220.     CGrafPtr                inPort,
  221.     RgnHandle                 inRegion,
  222.     Point                    inAlignTo)
  223. {
  224.     StClipRgnState theClipSaver;
  225.     ::SetClip(inRegion);
  226.     Rect theBounds = (*inRegion)->rgnBBox;
  227.     if (IsShallow())
  228.         FillShallow(inPort, theBounds, inAlignTo);
  229.     else
  230.         FillDeep(inPort, theBounds, inAlignTo);
  231. }
  232.  
  233. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  234. //    Ñ    FillShallow
  235. //
  236. //    Here we fill a rect with a pattern that is 8 bits or less in depth.  See
  237. //    the header file for why this is necessary.
  238. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  239.  
  240. void CSharedPatternWorld::FillShallow(
  241.     CGrafPtr                inPort,
  242.     const Rect&             inBounds,
  243.     Point                    inAlignTo)
  244. {
  245.     StClipRgnState theClipSaver;
  246.     theClipSaver.ClipToIntersection(inBounds);
  247.     
  248.     StPortOriginState theOriginSaver((GrafPtr)inPort);
  249.     Point theOldOrigin = topLeft(inPort->portRect);
  250.     
  251.     Point theNewOrigin;
  252.     theNewOrigin.h = theOldOrigin.h - inAlignTo.h;
  253.     theNewOrigin.v = theOldOrigin.v - inAlignTo.v;
  254.  
  255.     Point theDelta;
  256.     theDelta.h = theNewOrigin.h - theOldOrigin.h;
  257.     theDelta.v = theNewOrigin.v - theOldOrigin.v; 
  258.     
  259.     StRegion theClip;
  260.     ::GetClip(theClip);
  261.     ::OffsetRgn(theClip, theDelta.h, theDelta.v);
  262.     ::SetClip(theClip);
  263.     
  264.     Rect theOffsetBounds = inBounds;
  265.     ::OffsetRect(&theOffsetBounds, theDelta.h, theDelta.v);
  266.     
  267.     ::SetOrigin(theNewOrigin.h, theNewOrigin.v);
  268.     ::FillCRect(&theOffsetBounds, mPatternHandle);
  269. }
  270.  
  271.  
  272. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  273. //    Ñ    FillDeep
  274. //
  275. //    Here we fill a rect with a pattern that is deeper than 8 bits.  See
  276. //    the header file for why this is necessary.
  277. // ╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤╤
  278.  
  279. void CSharedPatternWorld::FillDeep(
  280.     CGrafPtr                inPort,
  281.     const Rect&             inBounds,
  282.     Point                    inAlignTo)
  283. {
  284.     PixMapHandle thePatternMap = ::GetGWorldPixMap(mPatternWorld->GetMacGWorld());
  285.     PixMapHandle theDestMap = inPort->portPixMap;
  286.  
  287.     StClipRgnState theClipSaver;
  288.     theClipSaver.ClipToIntersection(inBounds);
  289.     
  290.     StRegion theClip;
  291.     ::GetClip(theClip);
  292.     
  293.     Rect thePatternFrame = (*thePatternMap)->bounds;
  294.     Int16 thePatternWidth = RectWidth(thePatternFrame);
  295.     Int16 thePatternHeight = RectHeight(thePatternFrame);
  296.     
  297.     Int32 theStampLeft = inAlignTo.h + thePatternWidth * ((inBounds.left - inAlignTo.h) / thePatternWidth);
  298.     Int32 theStampTop = inAlignTo.v + thePatternHeight * ((inBounds.top - inAlignTo.v) / thePatternHeight);
  299.  
  300.     Rect theStamp;
  301.     theStamp.top = theStampTop;
  302.     theStamp.left = theStampLeft;
  303.     theStamp.bottom = theStamp.top + thePatternHeight;
  304.     theStamp.right = theStamp.left + thePatternWidth;
  305.     
  306.     while (theStamp.top <= inBounds.bottom)
  307.         {
  308.         while (theStamp.left <= inBounds.right)
  309.             {
  310.             if (::RectInRgn(&theStamp, theClip))
  311.                 ::CopyBits((BitMap*)(*thePatternMap), (BitMap*)(*theDestMap), &thePatternFrame, &theStamp, srcCopy, NULL);
  312.                 
  313.             theStamp.left += thePatternWidth;
  314.             theStamp.right += thePatternWidth;
  315.             }
  316.     
  317.         theStamp.left = theStampLeft;
  318.         theStamp.top += thePatternHeight;
  319.         theStamp.bottom = theStamp.top + thePatternHeight;
  320.         theStamp.right = theStamp.left + thePatternWidth;
  321.         }
  322. }
  323.  
  324.