home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 January: Mac OS SDK / Dev.CD Jan 97 SDK2.toast / Development Kits (Disc 2) / OpenDoc Development Framework / ODFDev / ODF / OS / FWGraphx / PRGDev.cpp < prev    next >
Encoding:
Text File  |  1996-09-17  |  34.3 KB  |  1,303 lines  |  [TEXT/MPS ]

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