home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1996 October: Mac OS SDK / Dev.CD Oct 96 SDK / Dev.CD Oct 96 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / OS / FWGraphx / Sources / PRGDev.cpp < prev    next >
Encoding:
Text File  |  1996-08-16  |  35.9 KB  |  1,366 lines  |  [TEXT/MPS ]

  1. //========================================================================================
  2. //
  3. //    File:                FWGDev.cpp
  4. //    Release Version:    $ ODF 1 $
  5. //
  6. //    Copyright:    (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
  7. //
  8. //========================================================================================
  9.  
  10. #include "FWOS.hpp"
  11.  
  12. #if defined(FW_PROFILER_CALLS) && defined(__MWERKS__)
  13. #pragma profile on
  14. #endif
  15.  
  16. #ifndef FWEXCEPT_H
  17. #include "FWExcept.h"
  18. #endif
  19.  
  20. #ifndef FWODEXCE_H
  21. #includ "FWODExce.h"
  22. #endif
  23.  
  24. #ifndef PRGDEV_H
  25. #include "PRGDev.h"
  26. #endif
  27.  
  28. #ifndef SLREGION_H
  29. #include "SLRegion.h"
  30. #endif
  31.  
  32. #ifndef FWPAT_H
  33. #include "FWPat.h"
  34. #endif
  35.  
  36. #ifndef SLGRGLOB_H
  37. #include "SLGrGlob.h"
  38. #endif
  39.  
  40. #ifndef FWINK_H
  41. #include "FWInk.h"
  42. #endif
  43.  
  44. #ifndef FWSTYLE_H
  45. #include "FWStyle.h"
  46. #endif
  47.  
  48. #ifndef FWFONT_H
  49. #include "FWFont.h"
  50. #endif
  51.  
  52. #ifndef FWGC_H
  53. #include "FWGC.h"
  54. #endif
  55.  
  56. #ifndef FWGRUTIL_H
  57. #include "FWGrUtil.h"
  58. #endif
  59.  
  60. #ifndef FWODGEOM_H
  61. #include "FWODGeom.h"
  62. #endif
  63.  
  64. #ifndef PRSHATTR_H
  65. #include "PRShAttr.h"
  66. #endif
  67.  
  68. // ----- Platform Includes -----
  69.  
  70. #if defined(FW_BUILD_MAC) && !defined(__LOWMEM__)
  71. #include <LowMem.h>
  72. #endif
  73.  
  74. #if defined(FW_BUILD_MAC) && !defined(__PRINTING_)
  75. #include <Printing.h>
  76. #endif
  77.  
  78. #ifdef FW_BUILD_MAC
  79. #include <stdio.h>    // Need sprintf for PostScript clipping
  80. #endif
  81.  
  82. // ----- OpenDoc Includes -----
  83.  
  84. #ifndef SOM_ODCanvas_xh
  85. #include <Canvas.xh>
  86. #endif
  87.  
  88. #ifndef SOM_ODTransform_xh
  89. #include <Trnsform.xh>
  90. #endif
  91.  
  92. // ----- Standard C Includes -----
  93.  
  94. #include <math.h>
  95.  
  96. //========================================================================================
  97. //    RunTime Info
  98. //========================================================================================
  99.  
  100. #ifdef FW_BUILD_MAC
  101. #pragma segment FWGraphics_Device
  102. #endif
  103.  
  104. FW_DEFINE_AUTO(FW_CPrivGraphicsDevice)
  105.  
  106. //========================================================================================
  107. // Transfer mode constants
  108. //========================================================================================
  109.  
  110. #ifdef FW_BUILD_MAC
  111. static const short             FW_gTransferModes[] =
  112. {
  113.     patCopy,            //    FW_kCopy
  114.     notPatCopy,            //    FW_kNotCopy
  115.     patOr,                //    FW_kOr
  116.     notPatOr,            //    FW_kNotOr
  117.     patXor,                //    FW_kXOr
  118.     notPatXor,            //    FW_kNotXOr
  119.     patBic,                //    FW_kClear
  120.     notPatBic,            //    FW_kNotClear
  121.     hilitetransfermode,    //    FW_kHilite
  122.     patCopy,            //    FW_kErase
  123.     patCopy,            //    FW_kInvert
  124. };
  125. #endif
  126.  
  127. #ifdef FW_BUILD_WIN
  128. // Don't forget than on windows black and white are inverted.
  129. //    That's why it seems that the xxNOTxx is at the wrong place
  130. static const int             FW_gTransferModes[] =
  131. {
  132.     R2_COPYPEN,            //    FW_kCopy
  133.     R2_NOTCOPYPEN,         //    FW_kNotCopy
  134.     R2_NOTMERGEPEN,     //    FW_kOr
  135.     R2_MERGEPEN,        //    FW_kNotOr
  136.     R2_NOTXORPEN,         //    FW_kXOr
  137.     R2_XORPEN,            //    FW_kNotXOr        
  138.     R2_NOTMASKPEN,         //    FW_kClear
  139.     R2_MASKPEN,            //    FW_kNotClear
  140.     R2_NOTXORPEN,         //    FW_kHilite
  141.     R2_COPYPEN,             //    FW_kErase
  142.     R2_NOTXORPEN         //    FW_kInvert
  143. };
  144. #endif
  145.  
  146. //========================================================================================
  147. // Macros
  148. //========================================================================================
  149.  
  150. #ifdef FW_BUILD_WIN
  151.  
  152. #define FW_CHECK_PLATFORM_CANVAS \
  153.     FW_ASSERT(fPlatformCanvas != NULL);
  154.  
  155. #endif
  156.  
  157. #ifdef FW_BUILD_MAC
  158.  
  159. #define FW_CHECK_PLATFORM_CANVAS \
  160.     FW_ASSERT(fPlatformCanvas != NULL); \
  161.     FW_ASSERT(fPlatformCanvas == FW_QDGlobals.thePort);
  162.  
  163. #endif
  164.  
  165. //========================================================================================
  166. //    class FW_CPrivGraphicsDevice
  167. //========================================================================================
  168.  
  169. //----------------------------------------------------------------------------------------
  170. //    FW_CPrivGraphicsDevice::FW_CPrivGraphicsDevice
  171. //----------------------------------------------------------------------------------------
  172.  
  173. FW_CPrivGraphicsDevice::FW_CPrivGraphicsDevice(Environment *ev, ODCanvas* odCanvas) :
  174.     fODCanvas(odCanvas),
  175.     fPlatformCanvas(NULL),
  176. #ifdef FW_BUILD_MAC
  177.     fPattern(FW_NEW(FW_CPrivBWPatternRep, (FW_kBlackPat))),
  178. #endif
  179.     fOpenDeviceCount(0),
  180.     fSuspended(FALSE),
  181.     fContext(NULL),
  182.     fResolution(FW_kZeroPoint),
  183.     fEV(ev)
  184. {
  185.     FW_ASSERT(fODCanvas != NULL);
  186.     FW_END_CONSTRUCTOR
  187. }
  188.  
  189. //----------------------------------------------------------------------------------------
  190. //    FW_CPrivGraphicsDevice::FW_CPrivGraphicsDevice
  191. //----------------------------------------------------------------------------------------
  192.  
  193. FW_CPrivGraphicsDevice::FW_CPrivGraphicsDevice(Environment *ev, ODPlatformCanvas platformCanvas) :
  194.     fODCanvas(NULL),
  195.     fPlatformCanvas(platformCanvas),
  196. #ifdef FW_BUILD_MAC
  197.     fPattern(FW_NEW(FW_CPrivBWPatternRep, (FW_kBlackPat))),
  198. #endif
  199.     fOpenDeviceCount(0),
  200.     fSuspended(FALSE),
  201.     fContext(NULL),
  202.     fResolution(FW_kZeroPoint),
  203.     fEV(ev)
  204. {
  205.     FW_ASSERT(fPlatformCanvas != NULL);
  206.     FW_END_CONSTRUCTOR
  207. }
  208.  
  209. //---------------------------------------------------------------------------------------
  210. //     FW_CPrivGraphicsDevice::~FW_CPrivGraphicsDevice
  211. //---------------------------------------------------------------------------------------
  212.  
  213. FW_CPrivGraphicsDevice::~FW_CPrivGraphicsDevice()
  214. {
  215.     FW_START_DESTRUCTOR
  216.     FW_ASSERT(fOpenDeviceCount == 0);
  217.     FW_ASSERT(!fSuspended);
  218. }
  219.  
  220. //----------------------------------------------------------------------------------------
  221. //    FW_CPrivGraphicsDevice::GetResolution
  222. //----------------------------------------------------------------------------------------
  223. FW_CPoint FW_CPrivGraphicsDevice::GetResolution() const
  224. {
  225.     if (fResolution == FW_kZeroPoint)
  226.     {
  227.         FW_ASSERT(fPlatformCanvas != NULL);
  228.         
  229.         FW_CPrivGraphicsDevice* self = (FW_CPrivGraphicsDevice *) this;
  230.  
  231. #ifdef FW_BUILD_WIN
  232.         self->fResolution.x = FW_IntToFixed(::GetDeviceCaps(fPlatformCanvas, LOGPIXELSX));
  233.         self->fResolution.y = FW_IntToFixed(::GetDeviceCaps(fPlatformCanvas, LOGPIXELSY));
  234. #endif
  235. #ifdef FW_BUILD_MAC
  236.         self->fResolution.x = FW_IntToFixed(72);
  237.         self->fResolution.y = FW_IntToFixed(72);
  238. #endif
  239.     }
  240.  
  241.     return fResolution;
  242. }
  243.  
  244. //----------------------------------------------------------------------------------------
  245. //    FW_CPrivGraphicsDevice::SetResolution
  246. //----------------------------------------------------------------------------------------
  247.  
  248. void FW_CPrivGraphicsDevice::SetResolution(FW_Fixed x, FW_Fixed y)
  249. {
  250.     fResolution.x = x;
  251.     fResolution.y = y;
  252. }
  253.  
  254. #ifdef FW_BUILD_WIN
  255. //----------------------------------------------------------------------------------------
  256. //    FW_CPrivGraphicsDevice::IsMetaFileCanvas
  257. //----------------------------------------------------------------------------------------
  258.  
  259. FW_Boolean FW_CPrivGraphicsDevice::IsMetaFileCanvas() const
  260. {
  261.     FW_ASSERT(fPlatformCanvas);
  262.     return ::GetDeviceCaps(fPlatformCanvas, TECHNOLOGY) == DT_METAFILE;
  263. }
  264. #endif
  265.  
  266. //---------------------------------------------------------------------------------------
  267. //    FW_CPrivGraphicsDevice::OpenDevice
  268. //---------------------------------------------------------------------------------------
  269.  
  270. FW_SPrivDeviceState* FW_CPrivGraphicsDevice::OpenDevice(Environment *ev, FW_SGraphicContext* context)
  271. {
  272. // [KVV]    FW_ASSERT(!fSuspended);
  273.  
  274.     FW_ASSERT(fContext == NULL);
  275.     fContext = context;
  276.  
  277.     // ----- Get the platform canvas -----
  278.     if (fPlatformCanvas == NULL)
  279.     {
  280. #ifdef FW_BUILD_WIN
  281.         fPlatformCanvas = fODCanvas->GetPlatformCanvas(ev, kODWindows);    
  282. #endif
  283. #ifdef FW_BUILD_MAC
  284.         fPlatformCanvas = fODCanvas->GetPlatformCanvas(ev, kODQuickDraw);    
  285. #endif
  286.     }        
  287.     FW_ASSERT(fPlatformCanvas != NULL);
  288.  
  289.     // ----- Save first the current state -----
  290.     FW_SPrivDeviceState* deviceState = GetState();        // GetState set the port
  291.  
  292.     // ----- Reset Settings -----
  293.     if (fOpenDeviceCount == 0)
  294.     {
  295.         // Update the resolution
  296.         FW_CPoint res = GetResolution();
  297.         
  298. #ifdef FW_BUILD_WIN
  299.         fTextColor = ::GetTextColor(fPlatformCanvas);
  300.         fBkColor = ::GetBkColor(fPlatformCanvas);
  301.         fPenSize.Set(0, 0);
  302.         
  303.         ::SetMapMode(fPlatformCanvas, MM_TEXT);
  304. #endif
  305. #ifdef FW_BUILD_MAC
  306.         ResetSettings();
  307.         fMacPostScriptClip = FALSE;
  308. #endif
  309.     }
  310.     
  311.     fSuspended = FALSE;        // we are opening it so it is not suspended
  312.     fOpenDeviceCount++;
  313.  
  314.     // ----- Set the origin offset -----
  315.     UpdateOriginForContext(ev);
  316.  
  317.     return deviceState;
  318. }
  319.  
  320. //---------------------------------------------------------------------------------------
  321. //    FW_CPrivGraphicsDevice::CloseDevice
  322. //---------------------------------------------------------------------------------------
  323.  
  324. void FW_CPrivGraphicsDevice::CloseDevice(Environment *ev, FW_SPrivDeviceState* deviceState)
  325. {
  326. FW_UNUSED(ev);
  327. // ----- [LSD] can't check "fPlatformCanvas == FW_QDGlobals.thePort" here because we may
  328. //                 have already opened another window
  329. //    FW_CHECK_PLATFORM_CANVAS
  330.     FW_ASSERT(fPlatformCanvas != NULL);
  331. #ifdef FW_BUILD_MAC
  332.     ::SetPort(fPlatformCanvas);
  333. #endif    
  334.  
  335.     FW_ASSERT(!fSuspended);
  336.     FW_ASSERT(fOpenDeviceCount != 0);
  337.  
  338. #ifdef FW_BUILD_MAC
  339. // ----- [HLX] OpenDoc Bug 
  340.     // I should not have to restore the Grafport but
  341.     // ODFacet::DrawActiveBorder doesn't reset the foreground
  342.     // and background color correctly so....
  343.     ::PenNormal();
  344.     
  345. #if defined(__MWERKS__) && GENERATING68K
  346.     RGBColor macBlackColor;
  347.     macBlackColor.red = macBlackColor.green = macBlackColor.blue = 0x0000;
  348. #else
  349.     RGBColor macBlackColor = { 0x0000, 0x0000, 0x0000 };
  350. #endif
  351.     ::RGBForeColor(&macBlackColor);
  352.     
  353. #if defined(__MWERKS__) && GENERATING68K
  354.     RGBColor macWhiteColor;
  355.     macWhiteColor.red = macWhiteColor.green = macWhiteColor.blue = 0xFFFF;
  356. #else
  357.     RGBColor macWhiteColor = { 0xFFFF, 0xFFFF, 0xFFFF };
  358. #endif
  359.  
  360.     ::RGBBackColor(&macWhiteColor);
  361. // ----- [HLX] OpenDoc Bug
  362. #endif
  363.  
  364.     // ----- Restore origin and clip -----
  365. #ifdef FW_BUILD_WIN
  366.     ::SetWindowOrgEx(fPlatformCanvas, deviceState->fWindOrg.x, deviceState->fWindOrg.y, NULL);
  367.     ::SetMapMode(fPlatformCanvas, deviceState->fMapMode);
  368. #endif
  369. #ifdef FW_BUILD_MAC
  370.     if (fMacPostScriptClip)
  371.         MacEndPostScriptClip();
  372.  
  373.     ::SetOrigin(deviceState->fOrigin.h, deviceState->fOrigin.v);
  374.  
  375.     if (FW_MacIsColorPort(FW_QDGlobals.thePort))    // [LW7]
  376.     {
  377.         ::SetClip(deviceState->fClip);
  378.     }
  379.  
  380.     ::DisposeRgn(deviceState->fClip);
  381.     deviceState->fClip = NULL;
  382.  
  383.     // ----- Restore previous port -----
  384.     ::SetPort(deviceState->fPreviousPlatformCanvas);
  385. #endif
  386.  
  387. #ifdef FW_BUILD_MAC
  388.     // ----- Restore the suspended flag
  389.     // [KVV] CloseDevice should set fSuspended to FALSE!
  390.     fSuspended = deviceState->fSuspended;
  391. #endif
  392.  
  393.     // ----- Decrement fOpenDeviceCount -----
  394.     fOpenDeviceCount--;
  395.     
  396.     // ----- If fOpenDeviceCount == 0 the device is not used anymore.
  397.     if (fOpenDeviceCount == 0)
  398.     {    
  399. #ifdef FW_BUILD_WIN
  400.         // ----- Unselect our object -----
  401.         fGDIPen.UnselectObject(fPlatformCanvas);
  402.         fGDIBrush.UnselectObject(fPlatformCanvas);
  403.         fGDIFont.UnselectObject(fPlatformCanvas);
  404.         
  405.         // ----- Reset also textColor, bkColor etc to their default value -----
  406.         ::SetTextColor(fPlatformCanvas, RGB(0x00, 0x00, 0x00));
  407.         ::SetBkColor(fPlatformCanvas, RGB(0xFF, 0xFF, 0xFF));
  408.         ::SetROP2(fPlatformCanvas, R2_COPYPEN);
  409.         ::SetBkMode(fPlatformCanvas, OPAQUE);
  410. #endif
  411.  
  412.         if (fODCanvas != NULL)
  413.         {
  414. #ifdef FW_BUILD_WIN
  415.             fODCanvas->ReleasePlatformCanvas(ev);
  416. #endif
  417.         }
  418.         
  419.         fPlatformCanvas = NULL;
  420.     }
  421.  
  422.     // ----- We don't need the deviceState anymore -----
  423.     delete deviceState;
  424.  
  425.     // ----- Not valid anymore -----
  426.     fContext = NULL;
  427. }
  428.  
  429. //---------------------------------------------------------------------------------------
  430. //    FW_CPrivGraphicsDevice::GetState
  431. //---------------------------------------------------------------------------------------
  432.  
  433. FW_SPrivDeviceState* FW_CPrivGraphicsDevice::GetState()
  434. {
  435.     FW_ASSERT(fPlatformCanvas != NULL);
  436.     FW_SPrivDeviceState* deviceState = new FW_SPrivDeviceState;
  437.     
  438. #ifdef FW_BUILD_WIN
  439.     deviceState->fMapMode = ::GetMapMode(fPlatformCanvas);
  440.     ::GetWindowOrgEx(fPlatformCanvas, &deviceState->fWindOrg);
  441. #endif
  442. #ifdef FW_BUILD_MAC
  443.     // ----- Save previous grafport -----
  444.     ::GetPort(&deviceState->fPreviousPlatformCanvas);
  445.     FW_ASSERT(deviceState->fPreviousPlatformCanvas != NULL);
  446.     
  447.     // ----- Set the new grafport -----
  448.     ::SetPort(fPlatformCanvas);
  449.     
  450.     // ----- Save the origin and the clip of our port     
  451.     deviceState->fOrigin.h = fPlatformCanvas->portRect.left;
  452.     deviceState->fOrigin.v = fPlatformCanvas->portRect.top;
  453.  
  454.     deviceState->fClip = ::FW_CopyRegion(fPlatformCanvas->clipRgn);
  455.  
  456.     deviceState->fSuspended = fSuspended;
  457. #endif
  458.  
  459.     return deviceState;
  460. }
  461.  
  462. //---------------------------------------------------------------------------------------
  463. //    FW_CPrivGraphicsDevice::Suspend
  464. //---------------------------------------------------------------------------------------
  465.  
  466. FW_SPrivSuspendResumeState* FW_CPrivGraphicsDevice::Suspend()
  467. {
  468. // [KVV]    FW_ASSERT(!fSuspended);
  469.     FW_ASSERT(fOpenDeviceCount != 0);    // Should not have to Suspend if not opened
  470.  
  471. //    [KVV] When called from the drag manager, the current port has already been changed
  472. //    FW_CHECK_PLATFORM_CANVAS
  473.  
  474. #ifdef FW_BUILD_WIN
  475.     FW_SPrivSuspendResumeState* deviceState = new FW_SPrivSuspendResumeState;
  476.     deviceState->fSavedDC = ::SaveDC(fPlatformCanvas);
  477. #endif
  478. #ifdef FW_BUILD_MAC
  479.     FW_SPrivSuspendResumeState* deviceState = GetState();
  480. #endif
  481.  
  482.     deviceState->fSavedContext = fContext;
  483.     fContext = NULL;
  484.  
  485.     fSuspended = TRUE;
  486.  
  487.     return deviceState;
  488. }
  489.  
  490. //---------------------------------------------------------------------------------------
  491. //    FW_CPrivGraphicsDevice::Resume
  492. //---------------------------------------------------------------------------------------
  493.  
  494. void FW_CPrivGraphicsDevice::Resume(FW_SPrivSuspendResumeState* deviceState)
  495. {    
  496. // [KVV]    FW_ASSERT(fSuspended);
  497.     FW_ASSERT(fPlatformCanvas != NULL);
  498.     
  499.     FW_ASSERT(fContext == NULL);
  500.     fContext = deviceState->fSavedContext;
  501.  
  502. #ifdef FW_BUILD_WIN
  503.     ::RestoreDC(fPlatformCanvas, deviceState->fSavedDC);
  504. #endif
  505. #ifdef FW_BUILD_MAC
  506. //    [KVV] Drag and drop (also see comment in Suspend)
  507. //    FW_ASSERT(deviceState->fPreviousPlatformCanvas == fPlatformCanvas);
  508.  
  509.     ::SetPort(fPlatformCanvas);    // The port may have changed
  510.     
  511.     ::SetOrigin(deviceState->fOrigin.h, deviceState->fOrigin.v);
  512.     ::SetClip(deviceState->fClip);
  513.     ::DisposeRgn(deviceState->fClip);
  514.     deviceState->fClip = NULL;
  515.  
  516.     fSuspended = deviceState->fSuspended;        // [KVV] Resume should "fSuspended = FALSE"
  517.  
  518.     // ----- We need to reset our settings
  519.     ResetSettings();        
  520. #endif
  521.     
  522.     // ----- We don't need the suspendResumeState anymore -----
  523.     delete deviceState;
  524.     
  525.     // ----- We are not suspended anymore -----
  526.     fSuspended = FALSE;
  527. }
  528.  
  529. //---------------------------------------------------------------------------------------
  530. //    FW_CPrivGraphicsDevice::CanvasChanged
  531. //---------------------------------------------------------------------------------------
  532.  
  533. void FW_CPrivGraphicsDevice::CanvasChanged(Environment* ev, ODCanvas* newCanvas)
  534. {
  535.     FW_ASSERT(!fSuspended);
  536.     FW_ASSERT(fOpenDeviceCount == 0);
  537.     FW_ASSERT(fODCanvas != NULL);    // Should not change the canvas if didn't have a canvas already
  538.     
  539. #ifdef FW_BUILD_WIN
  540.     if(fPlatformCanvas != NULL)
  541.     {
  542.         fODCanvas->ReleasePlatformCanvas(ev);
  543.         fPlatformCanvas = NULL;
  544.     }
  545. #endif
  546.     
  547.     fODCanvas = newCanvas;
  548.     
  549. #ifdef FW_BUILD_WIN
  550.     fPlatformCanvas = fODCanvas->GetPlatformCanvas(ev, kODWindows);
  551. #endif
  552. #ifdef FW_BUILD_MAC
  553.     fPlatformCanvas = fODCanvas->GetPlatformCanvas(ev, kODQuickDraw);
  554. #endif
  555. }
  556.  
  557. //---------------------------------------------------------------------------------------
  558. //    FW_CPrivGraphicsDevice::MappingChanged
  559. //---------------------------------------------------------------------------------------
  560.  
  561. void FW_CPrivGraphicsDevice::MappingChanged(Environment* ev)
  562. {
  563.     // ----- Set the origin offset -----
  564.     UpdateOriginForContext(ev);
  565. }
  566.  
  567. //---------------------------------------------------------------------------------------
  568. //    FW_CPrivGraphicsDevice::UpdateOriginForContext
  569. //---------------------------------------------------------------------------------------
  570.  
  571. void FW_CPrivGraphicsDevice::UpdateOriginForContext(Environment* ev)
  572. {
  573.     FW_CPlatformPoint offsetOrigin;
  574.     FW_PrivGC_GetOriginOffset(ev, *fContext, offsetOrigin);
  575.     FW_FailOnEvError(ev);
  576.     
  577.     offsetOrigin.Set(-offsetOrigin.X(), -offsetOrigin.Y());
  578.  
  579.     SetOrigin(offsetOrigin);
  580. }
  581.  
  582. //---------------------------------------------------------------------------------------
  583. //    FW_CPrivGraphicsDevice::SetOrigin
  584. //---------------------------------------------------------------------------------------
  585.  
  586. void FW_CPrivGraphicsDevice::SetOrigin(FW_CPlatformPoint origin)
  587. {
  588.     FW_ASSERT(!fSuspended);
  589.     FW_ASSERT(fOpenDeviceCount != 0);
  590.  
  591.     FW_CHECK_PLATFORM_CANVAS
  592.  
  593. #ifdef FW_BUILD_WIN
  594.     ::SetWindowOrgEx(fPlatformCanvas, origin.x, origin.y, NULL);
  595. #endif
  596. #ifdef FW_BUILD_MAC
  597.     GrafPtr curPort;
  598.     ::GetPort(&curPort);
  599.  
  600.     FW_CPlatformPoint oldOrigin(curPort->portRect.left, curPort->portRect.top);
  601.     if(oldOrigin.h != origin.h || oldOrigin.v != origin.v)
  602.     {
  603.         // Set the port origin
  604.         ::SetOrigin(origin.h, origin.v);
  605.  
  606.         // Shift the clip region
  607.         ODRgnHandle rgn = GetClip();
  608.         ::OffsetRgn(rgn, origin.h - oldOrigin.h, origin.v - oldOrigin.v);
  609.         SetClip(rgn);
  610.         ::DisposeRgn(rgn);
  611.     }
  612. #endif
  613. }
  614.  
  615. //---------------------------------------------------------------------------------------
  616. //    FW_CPrivGraphicsDevice::SetClip
  617. //---------------------------------------------------------------------------------------
  618.  
  619. void FW_CPrivGraphicsDevice::SetClip(ODRgnHandle clipRegion)
  620. {
  621.     FW_ASSERT(!fSuspended);
  622.     FW_ASSERT(fOpenDeviceCount != 0);
  623.  
  624.     FW_CHECK_PLATFORM_CANVAS
  625.  
  626. #ifdef FW_BUILD_WIN
  627.     ::SelectClipRgn(fPlatformCanvas, clipRegion);
  628. #endif
  629. #ifdef FW_BUILD_MAC
  630.     if (fMacPostScriptClip)
  631.         MacEndPostScriptClip();
  632.     
  633.     if (FW_MacIsColorPort(FW_QDGlobals.thePort))    // [LW7]
  634.     {
  635.         ::SetClip(clipRegion);        // SetClip copies the region
  636.     }
  637.  
  638.     if (fODCanvas != NULL && fODCanvas->HasPlatformPrintJob(fEV, kODQuickDraw))
  639.     {
  640. #define bDevLaser            3    // copied from "PrPrivate.a"
  641.  
  642.         THPrint thPrint = (THPrint) fODCanvas->GetPlatformPrintJob(fEV, kODQuickDraw);
  643.         FW_Boolean bPostScript = (((**thPrint).prStl.wDev >> 8) == bDevLaser);
  644.         
  645.         if (bPostScript && (*clipRegion)->rgnSize != 10)
  646.         {
  647.             // If the region is not rectangular
  648.             MacBeginPostScriptClip(clipRegion);
  649.         }
  650.     }
  651. #endif
  652. }
  653.  
  654. //---------------------------------------------------------------------------------------
  655. //    FW_CPrivGraphicsDevice::GetClip
  656. //---------------------------------------------------------------------------------------
  657.  
  658. ODRgnHandle FW_CPrivGraphicsDevice::GetClip() const
  659. {
  660.     FW_ASSERT(!fSuspended);
  661.     FW_ASSERT(fOpenDeviceCount != 0);
  662.  
  663.     FW_CHECK_PLATFORM_CANVAS
  664.  
  665. #ifdef FW_BUILD_WIN
  666.     HRGN clipHandle = ::CreateRectRgn(0, 0, 0, 0);
  667.     ::GetClipRgn(fPlatformCanvas, clipHandle);
  668. #endif
  669. #ifdef FW_BUILD_MAC
  670.     ODRgnHandle clipHandle = ::NewRgn();
  671.     ::GetClip(clipHandle);
  672. #endif
  673.  
  674.     return clipHandle;
  675. }
  676.  
  677. //---------------------------------------------------------------------------------------
  678. //    FW_CPrivGraphicsDevice::SetClipRect
  679. //---------------------------------------------------------------------------------------
  680.  
  681. void FW_CPrivGraphicsDevice::SetClipRect(const FW_CPlatformRect& clipRect)
  682. {
  683.     FW_ASSERT(!fSuspended);
  684.     FW_ASSERT(fOpenDeviceCount != 0);
  685.  
  686.     FW_CHECK_PLATFORM_CANVAS
  687.  
  688. #ifdef FW_BUILD_WIN
  689.     ODRgnHandle clipRegion = ::CreateRectRgnIndirect(&clipRect);
  690.     ::SelectClipRgn(fPlatformCanvas, clipRegion);
  691.     ::DeleteObject(clipRegion);
  692. #endif
  693. #ifdef FW_BUILD_MAC
  694.     if (fMacPostScriptClip)
  695.         MacEndPostScriptClip();
  696.  
  697.     ::ClipRect(&clipRect);
  698. #endif
  699. }
  700.  
  701. //---------------------------------------------------------------------------------------
  702. //    FW_CPrivGraphicsDevice::IntersectClipRect
  703. //---------------------------------------------------------------------------------------
  704.  
  705. void FW_CPrivGraphicsDevice::IntersectClipRect(const FW_CPlatformRect& clipRect)
  706. {
  707.     FW_ASSERT(!fSuspended);
  708.     FW_ASSERT(fOpenDeviceCount != 0);
  709.  
  710.     FW_CHECK_PLATFORM_CANVAS
  711.  
  712. #ifdef FW_BUILD_WIN
  713.     ::IntersectClipRect(fPlatformCanvas,
  714.                         clipRect.left, clipRect.top, 
  715.                         clipRect.right, clipRect.bottom);
  716. #endif
  717. #ifdef FW_BUILD_MAC
  718.     if (fMacPostScriptClip)
  719.         MacEndPostScriptClip();
  720.  
  721.     ODRgnHandle rgn = ::NewRgn();
  722.     ::RectRgn(rgn, &clipRect);
  723.     ODRgnHandle curClip = GetClip();
  724.     ::SectRgn(curClip, rgn, curClip);
  725.     ::DisposeRgn(rgn);
  726.     SetClip(curClip);
  727.     ::DisposeRgn(curClip);
  728. #endif
  729. }
  730.  
  731. //---------------------------------------------------------------------------------------
  732. //    FW_CPrivGraphicsDevice::GetClipRect
  733. //---------------------------------------------------------------------------------------
  734.  
  735. void FW_CPrivGraphicsDevice::GetClipRect(FW_CPlatformRect& clipRect) const
  736. {
  737.     FW_ASSERT(!fSuspended);
  738.     FW_ASSERT(fOpenDeviceCount != 0);
  739.  
  740.     FW_CHECK_PLATFORM_CANVAS
  741.  
  742. #ifdef FW_BUILD_WIN
  743.     ::GetClipBox(fPlatformCanvas, &clipRect);
  744. #endif
  745. #ifdef FW_BUILD_MAC
  746.     clipRect = (*FW_QDGlobals.thePort->clipRgn)->rgnBBox;
  747. #endif
  748. }
  749.  
  750. #ifdef FW_BUILD_MAC
  751. //----------------------------------------------------------------------------------------
  752. //    FW_CPrivGraphicsDevice::SetInGrafPort
  753. //----------------------------------------------------------------------------------------
  754. //    [HLX] Maybe it is as fast to just set than testing and setting???
  755.  
  756. void FW_CPrivGraphicsDevice::SetInGrafPort()
  757. {
  758.     FW_ASSERT(!fSuspended);
  759.     FW_ASSERT((fOpenDeviceCount != 0) && (fPlatformCanvas == FW_QDGlobals.thePort));
  760.     
  761.     RGBColor macColor;
  762.  
  763.     if (fChangeFlag & FW_kForeColorChanged)
  764.     {
  765.         macColor = fForeColor;
  766.         ::RGBForeColor(&macColor);
  767.     }
  768.         
  769.     if (fChangeFlag & FW_kBackColorChanged)
  770.     {
  771.         macColor = fBackColor;
  772.         ::RGBBackColor(&macColor);
  773.     }
  774.         
  775.     if (fChangeFlag & FW_kHiliteColorChanged)
  776.     {
  777.         if (fHiliteColor != FW_kRGBBlack)    // for black hilite use standard hilite color
  778.         {
  779.             macColor = fHiliteColor;
  780.             ::HiliteColor(&macColor);
  781.         }
  782.         else
  783.         {
  784.             LMGetHiliteRGB(&macColor);
  785.             ::HiliteColor(&macColor);
  786.         }
  787.     }
  788.         
  789.     if (fChangeFlag & FW_kPatternChanged)
  790.         fPattern->MacSetInCurPort();
  791.         
  792.     if (fPlatformCanvas->pnSize.h != fHPenSize || fPlatformCanvas->pnSize.v != fVPenSize)
  793.         ::PenSize(fHPenSize, fVPenSize);
  794.         
  795.     if (fPlatformCanvas->txFont != fFontID)
  796.         ::TextFont(fFontID);
  797.         
  798.     if (fPlatformCanvas->txSize != fFontSize)
  799.         ::TextSize(fFontSize);
  800.         
  801.     if (fPlatformCanvas->txFace != fFontStyle)
  802.         ::TextFace(fFontStyle);
  803.         
  804.     if (fPlatformCanvas->pnMode != fPenMode)
  805.         ::PenMode(fPenMode);
  806.         
  807.     if (fPlatformCanvas->txMode != fTextMode)
  808.         ::TextMode(fTextMode);
  809.     
  810.     fChangeFlag = 0;
  811. }
  812. #endif
  813.  
  814. #ifdef FW_BUILD_MAC
  815. //----------------------------------------------------------------------------------------
  816. //    FW_CPrivGraphicsDevice::ResetSettings
  817. //----------------------------------------------------------------------------------------
  818.  
  819. void FW_CPrivGraphicsDevice::ResetSettings()
  820. {
  821.     FW_ASSERT((fPlatformCanvas == FW_QDGlobals.thePort));
  822.  
  823.     RGBColor macColor;
  824.     
  825.     ::GetForeColor(&macColor);
  826.     fForeColor = macColor;
  827.     
  828.     ::GetBackColor(&macColor);
  829.     fBackColor = macColor;
  830.     
  831.     LMGetHiliteRGB(&macColor);        // [HLX] I am not sure about that
  832.     ::HiliteColor(&macColor);
  833.     fHiliteColor = macColor;
  834.     
  835.     fPattern = FW_NEW(FW_CPrivBWPatternRep, (FW_kBlackPat));
  836.     fPattern->MacSetInCurPort();
  837.     
  838.     fHPenSize = fPlatformCanvas->pnSize.h;
  839.     fVPenSize = fPlatformCanvas->pnSize.v;
  840.     fFontID = fPlatformCanvas->txFont;
  841.     fFontSize = fPlatformCanvas->txSize;
  842.     fFontStyle = fPlatformCanvas->txFace;
  843.     fPenMode = fPlatformCanvas->pnMode;
  844.     fTextMode = fPlatformCanvas->txMode;
  845.     
  846.     fChangeFlag = 0;
  847. }
  848. #endif
  849.  
  850. #ifdef FW_BUILD_MAC
  851. //----------------------------------------------------------------------------------------
  852. //    GetMacTransferMode
  853. //----------------------------------------------------------------------------------------
  854.  
  855. static short GetMacTransferMode(FW_TransferModes transferMode)
  856. {
  857.     if ((transferMode & 0xFFFF0000) == 0)
  858.         return (short)transferMode;        // Native transfer mode
  859.     else
  860.     {
  861.         FW_ASSERT(transferMode <= FW_kLastTransferMode);
  862.         return FW_gTransferModes[transferMode & 0x0000FFFF];
  863.     }
  864. }
  865. #endif
  866.  
  867. #ifdef FW_BUILD_MAC
  868. //----------------------------------------------------------------------------------------
  869. //    FW_CPrivGraphicsDevice::SelectInk
  870. //----------------------------------------------------------------------------------------
  871.  
  872. void FW_CPrivGraphicsDevice::SelectInk(const FW_HInk ink, 
  873.                                 FW_EPrivShapeCategories shapeCategory, 
  874.                                 FW_ERenderVerbs renderVerb)
  875. {
  876.     FW_ASSERT(ink != NULL);
  877.  
  878.     FW_CColor foreColor, backColor;
  879.     FW_TransferModes transferMode = ink->GetTransferMode();
  880.     
  881.     ink->GetForeColor(foreColor);
  882.     ink->GetBackColor(backColor);
  883.     
  884.     if (transferMode == FW_kHilite)
  885.         SetHiliteColor(foreColor);
  886.     
  887.     switch (shapeCategory)
  888.     {
  889.         case FW_kLineShape:
  890.             if (transferMode == FW_kErase)
  891.             {
  892.                 SetForeColor(backColor);
  893.                 SetBackColor(backColor);
  894.                 SetPenMode(GetMacTransferMode(transferMode));
  895.             }
  896.             else if (transferMode == FW_kInvert)
  897.             {
  898.                 SetForeColor(foreColor);
  899.                 SetBackColor(backColor);
  900.                 SetPenMode(patXor);
  901.             }
  902.             else
  903.             {
  904.                 SetForeColor(foreColor);
  905.                 SetBackColor(backColor);
  906.                 SetPenMode(GetMacTransferMode(transferMode));
  907.             }
  908.             break;
  909.             
  910.         case FW_kGeometricShape:
  911.             if (renderVerb == FW_kFrame)
  912.             {
  913.                 if (transferMode == FW_kErase)
  914.                 {
  915.                     SetForeColor(backColor);
  916.                     SetBackColor(backColor);
  917.                     SetPenMode(patCopy);
  918.                 }
  919.                 else if (transferMode == FW_kInvert)
  920.                 {
  921.                     SetForeColor(foreColor);
  922.                     SetBackColor(backColor);
  923.                     SetPenMode(patXor);
  924.                 }
  925.                 else
  926.                 {
  927.                     SetForeColor(foreColor);
  928.                     SetBackColor(backColor);
  929.                     SetPenMode(GetMacTransferMode(transferMode));
  930.                 }
  931.                 break;
  932.             }
  933.             else
  934.             {
  935.                 SetForeColor(foreColor);
  936.                 SetBackColor(backColor);
  937.                 if (transferMode == FW_kInvert || transferMode == FW_kErase)
  938.                     SetPenMode(patCopy);    // I will use ::InvertXXX or ::EraseXXX
  939.                 else
  940.                     SetPenMode(GetMacTransferMode(transferMode));
  941.             }
  942.             
  943.             break;
  944.             
  945.         case FW_kTypographicShape:
  946.             SetBackColor(backColor);
  947.             if (transferMode == FW_kInvert)
  948.             {
  949.                 SetForeColor(foreColor);
  950.                 SetPenMode(patXor);
  951.             }
  952.             else if (transferMode == FW_kErase)
  953.             {
  954.                 SetForeColor(backColor);
  955.                 SetPenMode(patCopy);
  956.             }
  957.             else
  958.             {
  959.                 SetForeColor(foreColor);
  960.                 SetTextMode(GetMacTransferMode(transferMode));
  961.             }
  962.             break;
  963.         
  964.         case FW_kImageShape:
  965.             SetForeColor(foreColor);
  966.             SetBackColor(backColor);
  967.             SetPenMode(GetMacTransferMode(transferMode));
  968.             break;
  969.     }
  970. }
  971. #endif
  972.  
  973. #ifdef FW_BUILD_MAC
  974. //----------------------------------------------------------------------------------------
  975. //    FW_CPrivGraphicsDevice::SelectStyle
  976. //----------------------------------------------------------------------------------------
  977.  
  978. FW_Boolean FW_CPrivGraphicsDevice::SelectStyle(const FW_HStyle style, 
  979.                                     FW_TransferModes transferMode)
  980. {
  981.     FW_ASSERT((const void*)style != NULL);
  982.  
  983.     if (transferMode == FW_kInvert || transferMode == FW_kErase)
  984.         SetPattern(FW_CPattern(FW_kBlackPat));
  985.     else
  986.         SetPattern(style->GetPattern());
  987.     
  988.     FW_EStyleDash dash = style->GetDashStyle();
  989.     FW_Fixed penSize = style->GetPenSize();
  990.     
  991.     FW_CPlatformPoint plfmPt;
  992.     if (penSize == FW_kFixed0)
  993.     {
  994.         plfmPt.Set(1, 1);
  995.     }
  996.     else
  997.     {
  998.         Environment *ev = fContext->fEnvironment;
  999.         FW_PrivGC_LogicalToDeviceSize(ev, *fContext, penSize, penSize, plfmPt);
  1000.         FW_FailOnEvError(ev);
  1001.         
  1002.         if (plfmPt.h == 0)
  1003.             plfmPt.h = 1;
  1004.             
  1005.         if (plfmPt.v == 0)
  1006.             plfmPt.v = 1;
  1007.     }
  1008.  
  1009.     SetPenSize(plfmPt.h, plfmPt.v);
  1010.     
  1011.     return dash != FW_kSolidLine && plfmPt.h <= 1 && plfmPt.v <= 1;
  1012. }
  1013. #endif
  1014.  
  1015. #ifdef FW_BUILD_MAC
  1016. //----------------------------------------------------------------------------------------
  1017. //    FW_CPrivGraphicsDevice::SetPattern
  1018. //----------------------------------------------------------------------------------------
  1019.  
  1020. void FW_CPrivGraphicsDevice::SetPattern(const FW_HPattern pattern)
  1021. {
  1022.     fPattern = (FW_CPrivPatternRep*) pattern;
  1023.     fChangeFlag |= FW_kPatternChanged;
  1024. }
  1025. #endif
  1026.  
  1027. #ifdef FW_BUILD_MAC
  1028.  
  1029. #define kPostScriptBegin    190        // Picture-comments for PostScript printing
  1030. #define kPostScriptEnd        191
  1031. #define kTextIsPostScript    194
  1032.  
  1033. //----------------------------------------------------------------------------------------
  1034. //    FW_CPrivGraphicsDevice::MacBeginPostScriptClip
  1035. //----------------------------------------------------------------------------------------
  1036.  
  1037. void FW_CPrivGraphicsDevice::MacBeginPostScriptClip(RgnHandle rgn)
  1038. {
  1039.     FW_ASSERT(!fMacPostScriptClip);
  1040.  
  1041.     //    In order for the PostScript commands we'll be emitting below to sync up
  1042.     //    properly with other PS code the driver emits, we have to get something else
  1043.     //    to emit right now as a flush. So we'll draw a tiny rectangle and make sure
  1044.     //    it falls outside the clipping bounds.
  1045.     
  1046.     Rect bbox = (*rgn)->rgnBBox;
  1047.  
  1048.     Rect r;
  1049.     r.right = bbox.left;
  1050.     if (r.right == -32767)
  1051.         r.right = bbox.right + 1;
  1052.     r.bottom = bbox.top;
  1053.     if (r.bottom == -32767)
  1054.         r.bottom = bbox.bottom + 1;
  1055.     r.left = r.right - 1;
  1056.     r.top  = r.bottom - 1;
  1057.     ::PaintRect(&r);
  1058.  
  1059.     // Copy a region to a shape so it can be converted to a polygon
  1060.     RgnHandle rgnCopy = ::NewRgn();
  1061.     ::CopyRgn(rgn, rgnCopy);
  1062.     ODShape* shape = FW_NewODShape(fEV, rgnCopy);
  1063.  
  1064.     // Now emit the polygon as a PostScript path and clip to it
  1065.     ODPolygon poly;
  1066.     shape->CopyPolygon(fEV, &poly);
  1067.     
  1068.     ::PicComment(kPostScriptBegin, 0, kODNULL);
  1069.     ::PicComment(kTextIsPostScript, 0, kODNULL);
  1070.  
  1071.     ::DrawString("\ppse gsave");            // Cancels out the 'psb' generated by the LW driver
  1072.     ::DrawString("\pnewpath");
  1073.  
  1074.     char buf[128];
  1075.     ODContour* cont = poly.FirstContour();
  1076.     for (long n = poly.GetNContours(); n > 0; -- n, cont = cont->NextContour())
  1077.     {
  1078.         const ODPoint* v = cont->vertex;
  1079.         long m = cont->nVertices;
  1080.         if (m > 2)
  1081.         {
  1082.             ::DrawText(buf, 0,
  1083.                 sprintf(buf, "%.2f %.2f moveto", ODFixedToFloat(v->x), ODFixedToFloat(v->y)));
  1084.  
  1085.             while (--m > 0)
  1086.             {
  1087.                 ++ v;
  1088.                 ::DrawText(buf, 0,
  1089.                     sprintf(buf,"%.2f %.2f lineto", ODFixedToFloat(v->x), ODFixedToFloat(v->y)));
  1090.             }
  1091.         }
  1092.     }
  1093.  
  1094.     ::DrawString("\pclosepath clip");    // Adding newpath would be nice but LW7 no likee
  1095.  
  1096.     ::DrawString("\ppsb");                // Cancels out the forthcoming 'pse'
  1097.     ::PicComment(kPostScriptEnd, 0,kODNULL);
  1098.  
  1099.     shape->Release(fEV);
  1100.  
  1101.     fMacPostScriptClip = TRUE;
  1102. }
  1103. #endif
  1104.  
  1105. #ifdef FW_BUILD_MAC
  1106. //----------------------------------------------------------------------------------------
  1107. //    FW_CPrivGraphicsDevice::MacEndPostScriptClip
  1108. //----------------------------------------------------------------------------------------
  1109.  
  1110. void FW_CPrivGraphicsDevice::MacEndPostScriptClip()
  1111. {
  1112.     FW_ASSERT(fMacPostScriptClip);
  1113.  
  1114.     PicComment(kPostScriptBegin, 0,kODNULL);
  1115.     PicComment(kTextIsPostScript, 0,kODNULL);
  1116.     DrawString("\ppse currentpoint grestore moveto psb");
  1117.     PicComment(kPostScriptEnd, 0,kODNULL);
  1118.  
  1119.     fMacPostScriptClip = FALSE;
  1120. }
  1121. #endif
  1122.  
  1123. //----------------------------------------------------------------------------------------
  1124. //    FW_CPrivGraphicsDevice::SelectFont
  1125. //----------------------------------------------------------------------------------------
  1126.  
  1127. void FW_CPrivGraphicsDevice::SelectFont(const FW_HFont font, FW_Boolean scale)
  1128. {
  1129.     FW_ASSERT(!fSuspended);
  1130.     FW_ASSERT(fOpenDeviceCount != 0);
  1131.     
  1132.     FW_CHECK_PLATFORM_CANVAS
  1133.  
  1134.     FW_ASSERT((const void*)font != NULL);
  1135.  
  1136. #ifdef FW_BUILD_WIN
  1137.     FW_CString255 fontName;
  1138.     font->GetFontName(fontName);
  1139.     char szFontName[256];
  1140.     fontName.ExportCString(szFontName);
  1141.     fGDIFont.SetFontName(szFontName);
  1142.     fGDIFont.SetFontStyle(font->GetFontStyle());
  1143. #endif
  1144. #ifdef FW_BUILD_MAC
  1145.     SetFontID(font->MacGetFontID());
  1146.     SetFontStyle(font->MacGetFontStyle());
  1147. #endif
  1148.  
  1149.     FW_Fixed fontSize = font->GetFontSize();
  1150.     if (scale)
  1151.     {
  1152.         FW_CPlatformPoint pt;
  1153.         Environment* ev = fContext->fEnvironment;
  1154.         FW_PrivGC_LogicalToDeviceSize(ev, *fContext, fontSize, fontSize, pt);
  1155.         FW_FailOnEvError(ev);
  1156.         fontSize = FW_IntToFixed(pt.Y());
  1157.     }
  1158.  
  1159. #ifdef FW_BUILD_WIN
  1160.     fGDIFont.SetFontSize(FW_FixedToInt(fontSize));
  1161.     fGDIFont.SelectObject(fPlatformCanvas);
  1162. #endif        
  1163. #ifdef FW_BUILD_MAC
  1164.     SetFontSize(FW_FixedToInt(fontSize));
  1165.     SetInGrafPort();
  1166. #endif
  1167. }
  1168.  
  1169. #ifdef FW_BUILD_WIN
  1170. //----------------------------------------------------------------------------------------
  1171. //    FW_CPrivGraphicsDevice::SelectInkAndFont
  1172. //----------------------------------------------------------------------------------------
  1173. //    Only call for Text shapes
  1174.  
  1175. void FW_CPrivGraphicsDevice::SelectInkAndFont(const FW_HInk ink, const FW_HFont font)
  1176. {
  1177.     SetTextColor(ink->GetForeColor());
  1178.     SetBkColor(ink->GetBackColor());
  1179.     SetBkMode(ink->GetTransferMode() == FW_kOr ? TRANSPARENT : OPAQUE);
  1180.     
  1181.     SelectFont(font, TRUE);
  1182. }
  1183. #endif
  1184.  
  1185. #ifdef FW_BUILD_WIN
  1186. //----------------------------------------------------------------------------------------
  1187. //    FW_CPrivGraphicsDevice::SetTextColor
  1188. //----------------------------------------------------------------------------------------
  1189.  
  1190. void FW_CPrivGraphicsDevice::SetTextColor(COLORREF textColor)
  1191. {
  1192.     FW_ASSERT(!fSuspended);
  1193.     FW_ASSERT(fOpenDeviceCount != 0);
  1194.     
  1195.     FW_CHECK_PLATFORM_CANVAS
  1196.  
  1197.     if (fTextColor != textColor)
  1198.     {
  1199.         fTextColor = textColor;
  1200.         ::SetTextColor(fPlatformCanvas, textColor);
  1201.     }
  1202. }
  1203. #endif
  1204.  
  1205. #ifdef FW_BUILD_WIN
  1206. //----------------------------------------------------------------------------------------
  1207. //    FW_CPrivGraphicsDevice::SetBkColor
  1208. //----------------------------------------------------------------------------------------
  1209.  
  1210. void FW_CPrivGraphicsDevice::SetBkColor(COLORREF bkColor)
  1211. {
  1212.     FW_ASSERT(!fSuspended);
  1213.     FW_ASSERT(fOpenDeviceCount != 0);
  1214.     
  1215.     FW_CHECK_PLATFORM_CANVAS
  1216.  
  1217.     if (fBkColor != bkColor)
  1218.     {
  1219.         fBkColor = bkColor;
  1220.         ::SetBkColor(fPlatformCanvas, bkColor);
  1221.     }
  1222. }
  1223. #endif
  1224.  
  1225. #ifdef FW_BUILD_WIN
  1226. //----------------------------------------------------------------------------------------
  1227. //    PrivWinROP2
  1228. //----------------------------------------------------------------------------------------
  1229.  
  1230. int static PrivWinROP2(FW_TransferModes transferMode)
  1231. {
  1232.     if ((transferMode & 0xFFFF0000L) == 0)
  1233.         return (int)transferMode;        // Native transfer mode
  1234.     else
  1235.     {
  1236.         FW_ASSERT(transferMode <= FW_kLastTransferMode);
  1237.         return FW_gTransferModes[transferMode & 0x0000FFFFL];
  1238.     }
  1239. }
  1240. #endif
  1241.  
  1242. #ifdef FW_BUILD_WIN
  1243. //----------------------------------------------------------------------------------------
  1244. //    FW_CPrivGraphicsDevice::SelectInkAndStyle
  1245. //----------------------------------------------------------------------------------------
  1246. // Only call for shapeCategory == FW_kGeometricShape or FW_kGeometricShapeWithInvert
  1247.  
  1248. FW_Boolean FW_CPrivGraphicsDevice::SelectInkAndStyle(const FW_HInk ink, 
  1249.                                                    const FW_HStyle style,
  1250.                                                    FW_EPrivShapeCategories shapeCategory, 
  1251.                                                    FW_ERenderVerbs renderVerb)
  1252. {
  1253.     FW_ASSERT(!fSuspended);
  1254.     FW_ASSERT(fOpenDeviceCount != 0);
  1255.     
  1256.     FW_CHECK_PLATFORM_CANVAS
  1257.  
  1258.     FW_ASSERT((const void*)ink != NULL);
  1259.     FW_ASSERT((const void*)style != NULL);
  1260.     
  1261.     FW_Boolean frameWithBrush = FALSE;
  1262.     
  1263.     // ----- Set transfer mode -----
  1264.     if (shapeCategory == FW_kGeometricShapeWithInvert && 
  1265.         ink->GetTransferMode() == FW_kInvert || 
  1266.         ink->GetTransferMode() == FW_kHilite)
  1267.     {
  1268.         SetDrawingMode(R2_COPYPEN);
  1269.     }
  1270.     else
  1271.         SetDrawingMode(::PrivWinROP2(ink->GetTransferMode()));
  1272.  
  1273.     // ----- Set pen size (even if filling)    
  1274.     FW_Fixed penSize = style->GetPenSize();
  1275.     if (penSize == FW_kFixed0)
  1276.         fPenSize.Set(1,1);
  1277.     else
  1278.         FW_PrivGC_LogicalToDeviceSize(*fContext, penSize, penSize, fPenSize);
  1279.  
  1280.     // ----- Set pen and brush -----
  1281.     int nBkMode = OPAQUE;
  1282.     if (renderVerb == FW_kFrame)
  1283.     {
  1284.         FW_EStyleDash dash = style->GetDashStyle();
  1285.         frameWithBrush = (dash == FW_kSolidLine) &&
  1286.             (!ink->PrivSpecialTransferMode()) &&
  1287.             (!style->GetPattern()->IsBlack());
  1288.  
  1289.         if (frameWithBrush)
  1290.         {
  1291.             // NOTE: I don't set the Pen because we will not use it
  1292.             
  1293.             // ----- Set foreground and background Color -----
  1294.             SetTextColor(ink->GetForeColor());
  1295.             SetBkColor(ink->GetBackColor());
  1296.     
  1297.             // ----- Set Brush -----
  1298.             fGDIBrush.SetBrushPattern(style->GetPattern());
  1299.         }
  1300.         else
  1301.         {
  1302.             // ----- Set the Brush -----
  1303.             fGDIBrush.SetStockID(NULL_BRUSH);
  1304.  
  1305.             // ----- Set the pen -----
  1306.             fGDIPen.SetPenSize(fPenSize.y);
  1307.             fGDIPen.SetPenStyle(dash);
  1308.             fGDIPen.SetPenColor(ink->GetTransferMode() == FW_kErase ? ink->GetBackColor() : ink->GetForeColor());
  1309.             
  1310.             if ((dash & FW_kOpaque) == 0)
  1311.                 nBkMode = TRANSPARENT;
  1312.             else
  1313.                 SetBkColor(ink->GetBackColor());
  1314.         }
  1315.     }
  1316.     else
  1317.     {
  1318.         // ----- Set the pen -----
  1319.         fGDIPen.SetStockID(NULL_PEN);
  1320.  
  1321.         // ----- Set the Brush -----
  1322.         FW_TransferModes transferMode = ink->GetTransferMode();
  1323.         if (transferMode == FW_kErase)
  1324.         {
  1325.             SetTextColor(RGB(0x00, 0x00, 0x00));
  1326.             SetBkColor(RGB(0xFF, 0xFF, 0xFF));
  1327.             fGDIBrush.SetBrushColor(ink->GetBackColor());
  1328.         }
  1329.         else if (transferMode == FW_kInvert || transferMode == FW_kHilite)
  1330.         {
  1331.             SetTextColor(RGB(0x00, 0x00, 0x00));
  1332.             SetBkColor(RGB(0xFF, 0xFF, 0xFF));
  1333.             fGDIBrush.SetStockID(BLACK_BRUSH);
  1334.         }
  1335.         else
  1336.         {
  1337.             const FW_PPrivPattern pattern = style->GetPattern();
  1338.  
  1339.             if (pattern->IsBlack())
  1340.             {
  1341.                 // If pattern is black let just use a solid brush
  1342.                 SetTextColor(RGB(0x00, 0x00, 0x00));
  1343.                 SetBkColor(RGB(0xFF, 0xFF, 0xFF));
  1344.                 fGDIBrush.SetBrushColor(ink->GetForeColor());
  1345.             }
  1346.             else
  1347.             {
  1348.                 SetTextColor(ink->GetForeColor());
  1349.                 SetBkColor(ink->GetBackColor());
  1350.                 fGDIBrush.SetBrushPattern(pattern);
  1351.             }
  1352.         }
  1353.     }
  1354.  
  1355.     SetBkMode(nBkMode);
  1356.  
  1357.     if (!frameWithBrush)
  1358.     {
  1359.         fGDIPen.SelectObject(fPlatformCanvas);
  1360.         fGDIBrush.SelectObject(fPlatformCanvas);
  1361.     }
  1362.  
  1363.     return frameWithBrush;
  1364. }
  1365. #endif
  1366.