rndrgn.cpp

Go to the documentation of this file.
00001 // $Id: rndrgn.cpp 1609 2006-07-30 09:47:03Z alex $
00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE
00003 ================================XARAHEADERSTART===========================
00004  
00005                Xara LX, a vector drawing and manipulation program.
00006                     Copyright (C) 1993-2006 Xara Group Ltd.
00007        Copyright on certain contributions may be held in joint with their
00008               respective authors. See AUTHORS file for details.
00009 
00010 LICENSE TO USE AND MODIFY SOFTWARE
00011 ----------------------------------
00012 
00013 This file is part of Xara LX.
00014 
00015 Xara LX is free software; you can redistribute it and/or modify it
00016 under the terms of the GNU General Public License version 2 as published
00017 by the Free Software Foundation.
00018 
00019 Xara LX and its component source files are distributed in the hope
00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the
00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
00022 See the GNU General Public License for more details.
00023 
00024 You should have received a copy of the GNU General Public License along
00025 with Xara LX (see the file GPL in the root directory of the
00026 distribution); if not, write to the Free Software Foundation, Inc., 51
00027 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
00028 
00029 
00030 ADDITIONAL RIGHTS
00031 -----------------
00032 
00033 Conditional upon your continuing compliance with the GNU General Public
00034 License described above, Xara Group Ltd grants to you certain additional
00035 rights. 
00036 
00037 The additional rights are to use, modify, and distribute the software
00038 together with the wxWidgets library, the wxXtra library, and the "CDraw"
00039 library and any other such library that any version of Xara LX relased
00040 by Xara Group Ltd requires in order to compile and execute, including
00041 the static linking of that library to XaraLX. In the case of the
00042 "CDraw" library, you may satisfy obligation under the GNU General Public
00043 License to provide source code by providing a binary copy of the library
00044 concerned and a copy of the license accompanying it.
00045 
00046 Nothing in this section restricts any of the rights you have under
00047 the GNU General Public License.
00048 
00049 
00050 SCOPE OF LICENSE
00051 ----------------
00052 
00053 This license applies to this program (XaraLX) and its constituent source
00054 files only, and does not necessarily apply to other Xara products which may
00055 in part share the same code base, and are subject to their own licensing
00056 terms.
00057 
00058 This license does not apply to files in the wxXtra directory, which
00059 are built into a separate library, and are subject to the wxWindows
00060 license contained within that directory in the file "WXXTRA-LICENSE".
00061 
00062 This license does not apply to the binary libraries (if any) within
00063 the "libs" directory, which are subject to a separate license contained
00064 within that directory in the file "LIBS-LICENSE".
00065 
00066 
00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS
00068 ----------------------------------------------
00069 
00070 Subject to the terms of the GNU Public License (see above), you are
00071 free to do whatever you like with your modifications. However, you may
00072 (at your option) wish contribute them to Xara's source tree. You can
00073 find details of how to do this at:
00074   http://www.xaraxtreme.org/developers/
00075 
00076 Prior to contributing your modifications, you will need to complete our
00077 contributor agreement. This can be found at:
00078   http://www.xaraxtreme.org/developers/contribute/
00079 
00080 Please note that Xara will not accept modifications which modify any of
00081 the text between the start and end of this header (marked
00082 XARAHEADERSTART and XARAHEADEREND).
00083 
00084 
00085 MARKS
00086 -----
00087 
00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara
00089 designs are registered or unregistered trademarks, design-marks, and/or
00090 service marks of Xara Group Ltd. All rights in these marks are reserved.
00091 
00092 
00093       Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK.
00094                         http://www.xara.com/
00095 
00096 =================================XARAHEADEREND============================
00097  */
00098 
00099 /*
00100 */
00101 
00102 // RNDRGN.CPP
00103 //
00104 // Created: 10/5/93 by Phil, Will, Simon
00105 //
00106 
00107 #include "camtypes.h"
00108 //#include "rndrgn.h"          - in camtypes.h [AUTOMATICALLY REMOVED]
00109 
00110 //#include "view.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00111 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00112 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00113 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00114 #include "ccdc.h"
00115 //#include "tim.h"
00116 #include "diagnost.h"
00117 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00118 #include "qualattr.h"
00119 #include "osrndrgn.h"
00120 #include "fuzzclip.h"
00121 #include "textfuns.h"
00122 #include "lineattr.h"
00123 #include "nodebmp.h"
00124 #include "colormgr.h"
00125 #include "isetattr.h"
00126 #include "printctl.h"
00127 #include "pathpcs.h"
00128 #include "strkattr.h"
00129 #include "offattr.h"
00130 #include "ppbrush.h"
00131 #include "clipattr.h"
00132 #include "gradtbl.h"
00133 //#include "capturemanager.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00134 
00135 #include "oilbitmap.h"  // TEMP BODGE for testing
00136 
00137 #include "fthrattr.h" // For a bodge
00138 
00139 #include "scanrr.h"
00140 
00141 #include "rendwnd.h"    // Temporary until DC creation moved to wxOil
00142 
00143 DECLARE_SOURCE("$Revision: 1609 $");
00144 
00145 // Declare smart memory handling in Debug builds
00146 #define new CAM_DEBUG_NEW
00147 
00148 CC_IMPLEMENT_DYNAMIC(RenderRegion, ListItem)
00149 CC_IMPLEMENT_DYNAMIC(SubRenderContext, CCObject)
00150 CC_IMPLEMENT_DYNAMIC(SubTreeRenderContext, SubRenderContext)
00151 
00152 const INT32 CHUNKSIZE = 256;    // Amount to claim when memory block is resized
00153 
00154 // Static vars initialisation
00155 //BOOL RenderRegion::MergeTestWait = FALSE;
00156 //BOOL RenderRegion::MergeShowRects = FALSE;
00157 
00158 /********************************************************************************************
00159 
00160     Some comments from Andy regarding the attribute stack, based on looking at the source.
00161 
00162     When something is pushed onto the ContextStack it looks like this:
00163     [lower memory]
00164     ContextLevel
00165     size of this item (negated), zero means bottom of stack
00166     pointer to restore function
00167     [possibly extra bytes e.g. sizeof(fn ptr) returns 6 in 16-bit compiler]
00168     [extra data, always longwords]
00169 
00170     After pushing A then pushing B, the stack would look something like this:
00171 
00172 [low memory]<------A-------><-------B------->[high]
00173                             |                |
00174     PreviousContext---------/                |
00175     ContextStackOffset-----------------------/
00176 
00177     This pushing gets done in SaveObjectState.
00178 
00179     ContextStackOffset is sort of the stack pointer. PreviousContext is used to
00180     be able to get back. These are offsets because the stack lives in the relocatable
00181     heap so is likely to move.
00182 
00183     Popping of attributes is done in RestoreAttributes.
00184 
00185 ********************************************************************************************/
00186 
00187 
00188 /********************************************************************************************
00189 
00190     Preference: SelectedBlobSize
00191     Section:    Selection Blob Sizes
00192     Range:      0 - 30
00193     Purpose:    The number represents the size of the blobs on the control points of selected
00194                 objects. The Selected Blob Size is the size of the blobs when they have been
00195                 clicked on.
00196     SeeAlso:    UnSelectedBlobSize
00197 
00198 ********************************************************************************************/
00199 UINT32 RenderRegion::SelectedBlobSize   = 3;
00200 UINT32 RenderRegion::MultiStageSelectedBlobSize   = 4;
00201 
00202 /********************************************************************************************
00203 
00204     Preference: UnSelectedBlobSize
00205     Section:    Selection Blob Sizes
00206     Range:      0 - 30
00207     Purpose:    The number represents the size of the blobs on the control points of selected
00208                 objects. The UnSelected Blob Size is the size of the blobs when the object is
00209                 selected, but none of its control points have been clicked on (and are not 
00210                 themselves selected)
00211     SeeAlso:    SelectedBlobSize
00212 
00213 ********************************************************************************************/
00214 UINT32 RenderRegion::UnSelectedBlobSize = 2;
00215 UINT32 RenderRegion::MultiStageUnSelectedBlobSize = 3;
00216 
00217 /********************************************************************************************
00218 
00219 >   UINT32 RenderRegion::ClipViewBlobSize = 8;
00220 
00221     Author:     Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
00222     Created:    22 May 2000
00223     Purpose:    This number represents the size of the ClipView's special selection blobs.
00224                 These blobs are only visible on selected ClipView groups when using the
00225                 selector tool, and are used to select different sections of the group.
00226     SeeAlso:    SelectedBlobSize
00227 
00228 ********************************************************************************************/
00229 UINT32 RenderRegion::ClipViewBlobSize = 8;
00230 
00231 
00232 /********************************************************************************************
00233 
00234 >   void RenderRegion::InitPrefs()
00235 
00236     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00237     Created:    22/9/93
00238     Returns:    TRUE if the Preference section was created ok
00239     Purpose:    Initialises the RenderRegions preferences from the preference file. This is
00240                 called once as Camelot starts up
00241 
00242 ********************************************************************************************/
00243 
00244 BOOL RenderRegion::InitPrefs()
00245 {
00246     Camelot.DeclareSection( _T("Selection Blob Sizes"), 2 );
00247     Camelot.DeclarePref( _T("Selection Blob Sizes"), _T("Selected Blobs"), &SelectedBlobSize, 1, 30 );
00248     Camelot.DeclarePref( _T("Selection Blob Sizes"), _T("UnSelected Blobs"), &UnSelectedBlobSize, 1, 30 );
00249     Camelot.DeclarePref( _T("Selection Blob Sizes"), _T("Multi Stage Selected Blobs"), &MultiStageSelectedBlobSize, 1, 30 );
00250     Camelot.DeclarePref( _T("Selection Blob Sizes"), _T("Multi Stage UnSelected Blobs"), &MultiStageUnSelectedBlobSize, 1, 30 );
00251 
00252     return TRUE;
00253 }
00254 
00255 
00256 /********************************************************************************************
00257 
00258 >   void RenderRegion::SetMergeTestWait(BOOL OnOff)
00259 
00260     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00261     Created:    2/8/93
00262     Inputs:     TRUE to stop backgound redraw from occurring (rectangles are still added to
00263                 the list) until set to FALSE again..
00264     Outputs:    -
00265     Returns:    -
00266     Purpose:    Used by the RectTool to suspend background redrawing.
00267     Errors:     -
00268     SeeAlso:    -
00269 
00270 ********************************************************************************************/
00271 /*
00272 void CCAPI RenderRegion::SetMergeTestWait(BOOL OnOff)
00273 { 
00274     MergeTestWait = OnOff;
00275 }
00276 
00277 */
00278 
00279 /********************************************************************************************
00280 
00281 >   inline INT32 RenderRegion::GetTimeslice()
00282 
00283     Author:     Andy_Pennell (Xara Group Ltd) <camelotdev@xara.com>
00284     Created:    13/4/94
00285     Inputs:     -
00286     Outputs:    -
00287     Returns:    Time (in milliseconds) that should be used as a slice during background
00288                 rendering.
00289     Purpose:    Used by DocView::CanContinue
00290     Errors:     -
00291 
00292 ********************************************************************************************/
00293 
00294 /********************************************************************************************
00295 
00296 >   RenderRegion::RenderRegion()
00297 
00298     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00299     Created:    11/5/93
00300     Inputs:     -
00301     Outputs:    -
00302     Returns:    -
00303     Purpose:    Default Constructor for RenderRegion Class
00304     Errors:     -
00305     SeeAlso:    -
00306 
00307 ********************************************************************************************/
00308 
00309 RenderRegion::RenderRegion()
00310 {
00311     NumCurrentAttrs = 0;
00312     CurrentAttrs = NULL;
00313 
00314     // By default try to render everything
00315     RenderComplexShapes = TRUE;
00316 
00317     TRACEUSER("Gavin",_T("RenderRegion::RenderRegion - RenderFlags.Rendering = FALSE;\n"));
00318     RenderFlags.Printing = FALSE;
00319     RenderFlags.Rendering = FALSE;
00320     RenderFlags.StackClaimed = FALSE;
00321     RenderFlags.ValidDevice = FALSE;
00322     RenderFlags.bImmediateRender = FALSE;
00323     RenderFlags.VeryMono = FALSE;
00324     RenderFlags.SmoothedBitmaps = FALSE;
00325     RenderFlags.HitDetect = FALSE;
00326 
00327     // All fill attributes are invalid to start with.
00328     FillFlags.ValidGeometry         = FALSE;
00329     FillFlags.ValidEffect           = FALSE;
00330     FillFlags.ValidMapping          = FALSE;
00331     FillFlags.ValidTransGeometry    = FALSE;
00332     FillFlags.ValidTransEffect      = FALSE;
00333     FillFlags.ValidTransMapping     = FALSE;
00334 
00335     StrokeFlags.ValidStrokeColour   = FALSE;
00336     StrokeFlags.ValidStrokeTransp   = FALSE;
00337     StrokeFlags.ValidLineWidth      = FALSE;
00338     StrokeFlags.ValidJoinType       = FALSE;
00339     StrokeFlags.ValidDashPattern    = FALSE;
00340     StrokeFlags.ValidLineCap        = FALSE;
00341     StrokeFlags.ValidStartArrow     = FALSE;
00342     StrokeFlags.ValidEndArrow       = FALSE;
00343     StrokeFlags.ValidMitreLimit     = FALSE;
00344 
00345     NeedsOSPaper = TRUE;
00346 
00347     DrawingMode = DM_COPYPEN;
00348     CurrentColContext = NULL;
00349 
00350     // Now setup the render state
00351     CurrentRenderState = NULL;
00352     CurrentSubRenderState = NULL;
00353     SubRenderStateLocked = FALSE;
00354 
00355     // Set the Fuzzy Clipping Rects to something
00356     InnerRect.MakeEmpty();
00357     OuterRect.MakeEmpty();
00358 
00359     // Set up vars to do with banded rendering
00360     RegionRect.MakeEmpty();
00361     IsRegionBanded = FALSE;
00362     CanRegionBeMerged = TRUE;
00363     IsWaitingForRAM = FALSE;
00364     IsLastBand = TRUE;
00365     IsBeingReset = FALSE;
00366     IsInkRenderStarted = FALSE;
00367     IsPaperRendered = FALSE;
00368 
00369     PathProcessorStack = NULL;
00370 
00371     // MarkH 23/7/99 - New Flag to wether or not to use the GDraw BiCompression Field!
00372     m_DoCompression = FALSE;
00373 
00374     m_pFilter = NULL;
00375 
00376     m_pBackmostChangedNode = NULL;
00377     m_timeRenderTreeStartTime.Sample();
00378     m_bRenderTreeTimeSlice = FALSE;
00379     m_countTotal = 0;
00380     m_countStored = 0;
00381 
00382     RenderDC = NULL;
00383     m_fOwned = FALSE;
00384     ScaleFactor = FIXED16(1);
00385 
00386     m_bForceMix = FALSE;
00387 
00388 //  double m_dboostm = 1.0;
00389 //  double m_dboostc = 0.0;
00390 
00391 #ifdef _DEBUG
00392     m_CurrentContextLevel = 0;
00393     m_TraceOutContextLevels = FALSE;
00394 //  m_TraceOutContextLevels = TRUE;
00395 #endif
00396 }
00397 
00398 /********************************************************************************************
00399 
00400 >   RenderRegion::RenderRegion(DocRect ClipRect, Matrix ConvertMatrix, FIXED16 ViewScale)
00401 
00402     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00403     Created:    11/5/93
00404     Inputs:     ClipRect is a DocRect defining the invalid rectangle to be rendered.
00405                 ConvertMatrix is a Matrix for converting Doc coords to OS coords.
00406                 ViewScale is the scale factor of the view, used to calculate how much to
00407                 flatten paths.
00408     Outputs:    -
00409     Returns:    -
00410     Purpose:    Constructor for a RenderRegion, allowing a invalid rectangle to be specified.
00411                 The matrix passed is used to convert Document coords into device coords,
00412                 taking into account scaling, scroll offsets etc.
00413     Errors:     -
00414     SeeAlso:    OSRenderRegion::OSRenderRegion()
00415 
00416 ********************************************************************************************/
00417 
00418 RenderRegion::RenderRegion(DocRect ClipRect, Matrix ConvertMatrix, FIXED16 ViewScale)
00419 {
00420     NumCurrentAttrs = 0;
00421     CurrentAttrs = NULL;
00422 
00423     // By default try to render everything
00424     RenderComplexShapes = TRUE;
00425 
00426     CurrentClipRect = ClipRect;
00427 
00428     RenderMatrix = ConvertMatrix;
00429 
00430 //  TRACE( _T("RR ClipRect = (%d, %d) - (%d, %d)\n"), ClipRect.lo.x, ClipRect.lo.y, ClipRect.hi.x, ClipRect.hi.y);
00431 //  RenderMatrix.Dump();
00432 
00433     ScaleFactor = ViewScale;
00434 
00435     RenderView = NULL;
00436     RenderDC = NULL;
00437     m_fOwned = FALSE;
00438 
00439     TRACEUSER("Gavin",_T("RenderRegion::RenderRegion - RenderFlags.Rendering = FALSE;\n"));
00440     RenderFlags.Printing = FALSE;
00441     RenderFlags.Rendering = FALSE;
00442     RenderFlags.StackClaimed = FALSE;
00443     RenderFlags.ValidDevice = FALSE;
00444     RenderFlags.bImmediateRender = FALSE;
00445     RenderFlags.VeryMono = FALSE;
00446     RenderFlags.SmoothedBitmaps = FALSE;
00447     RenderFlags.HitDetect = FALSE;
00448 
00449     DrawingMode = DM_COPYPEN;
00450 
00451     CurrentColContext = NULL;
00452 
00453     PixelWidth = 1;
00454     ScaledPixelWidth = 1;
00455 
00456     // Now setup the render state
00457     CurrentRenderState = NULL;
00458     CurrentSubRenderState = NULL;
00459     SubRenderStateLocked = FALSE;
00460 
00461     NeedsOSPaper = TRUE;
00462 
00463     // No paper has been rendered yet
00464     IsPaperRendered = FALSE;
00465     IsInkRenderStarted = FALSE;
00466 
00467     Timeslice = 100;                                            // 0.1 of a second
00468 
00469     // Set the Fuzzy Clipping Rects to something
00470     InnerRect.MakeEmpty();
00471     OuterRect.MakeEmpty();
00472 
00473     // Set up vars to do with banded rendering
00474     RegionRect = ClipRect;
00475     IsRegionBanded = FALSE;
00476     CanRegionBeMerged = TRUE;
00477     IsWaitingForRAM = FALSE;
00478     IsLastBand = TRUE;
00479     // Ilan
00480     IsBeingReset = FALSE;
00481 
00482     PathProcessorStack = NULL;
00483 
00484     m_pFilter = NULL;
00485 
00486     m_pBackmostChangedNode = NULL;
00487     m_timeRenderTreeStartTime.Sample();
00488     m_bRenderTreeTimeSlice = FALSE;
00489     m_countTotal = 0;
00490     m_countStored = 0;
00491 
00492     m_bForceMix = FALSE;
00493 
00494 #ifdef _DEBUG
00495     m_CurrentContextLevel = 0;
00496     m_TraceOutContextLevels = FALSE;
00497 //  m_TraceOutContextLevels = TRUE;
00498 #endif
00499 }
00500 
00501 /********************************************************************************************
00502 
00503 >   RenderRegion::RenderRegion(const RenderRegion &other)
00504 
00505     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00506     Created:    15/7/93
00507     Inputs:     The RenderRegion to copy
00508     Outputs:    -
00509     Returns:    -
00510     Purpose:    Copy Constructor for RenderRegion.  This conctructs a RenderRegion based
00511                 on another.  This involves copying all the current attributes and also
00512                 making a copy of the ContextStack.
00513     Errors:     -
00514     SeeAlso:    -
00515 
00516 ********************************************************************************************/
00517 
00518 RenderRegion::RenderRegion(const RenderRegion &other)
00519 {
00520     PathProcessorStack = NULL;      // We don't copy the PPStack - that's done as attrs are copied
00521 
00522     CurrentClipRect = other.CurrentClipRect;
00523 
00524     RenderComplexShapes = other.RenderComplexShapes;
00525 
00526     RenderMatrix = other.RenderMatrix;
00527     ScaleFactor = other.ScaleFactor;
00528 
00529     RenderView = other.RenderView;
00530     RenderDC = other.RenderDC;
00531     m_fOwned = other.m_fOwned;
00532 //  DCHandle = other.DCHandle;
00533 
00534     RenderFlags = other.RenderFlags;
00535 
00536     RenderSpread = other.RenderSpread;
00537     CurrentColContext = other.CurrentColContext;
00538 
00539     PixelWidth = other.PixelWidth;
00540     ScaledPixelWidth = other.ScaledPixelWidth;
00541 
00542     Timeslice = other.Timeslice;
00543     RRQuality = other.RRQuality;
00544 
00545     NeedsOSPaper = other.NeedsOSPaper;
00546 
00547     // No paper has been rendered yet
00548     IsPaperRendered = other.IsPaperRendered;
00549     IsInkRenderStarted = other.IsInkRenderStarted;
00550 
00551 
00552     // Now setup the render state 
00553     CurrentRenderState = other.CurrentRenderState;
00554 //  CurrentSubRenderState = other.CurrentSubRenderState;
00555     CurrentSubRenderState = NULL;
00556     SubRenderStateLocked = FALSE;
00557 
00558     // Copy the current attributes
00559     NumCurrentAttrs = 0;        // We're constructing, so we have no current attrs yet
00560     CurrentAttrs = NULL;
00561     if (!CopyCurrentAttributes(other))
00562     {
00563         // Unable to copy the current attributes
00564         ENSURE(FALSE, "Unable to copy current attributes");
00565         InformError();
00566         return;
00567     }
00568     
00569     // Now make a copy of the ContextSatck
00570     if (!TheStack.Copy(&other.TheStack, this))
00571     {
00572         // Unable to copy the render stack
00573         ENSURE(FALSE, "Unable to copy Rendering stack");
00574         InformError();
00575         return;
00576     }
00577 
00578     DrawingMode = other.DrawingMode;
00579 
00580     // Set the Fuzzy Clipping Rects to something
00581     InnerRect = other.InnerRect;
00582     OuterRect = other.OuterRect;
00583 
00584     // Set up vars to do with banded rendering
00585     RegionRect = other.RegionRect;
00586     IsRegionBanded = other.IsRegionBanded;
00587     CanRegionBeMerged = other.CanRegionBeMerged;
00588     IsWaitingForRAM = other.IsWaitingForRAM;
00589     IsLastBand = other.IsLastBand;
00590     // Ilan
00591     IsBeingReset = FALSE;
00592 
00593     m_pFilter = other.m_pFilter;
00594 
00595     m_pBackmostChangedNode = other.m_pBackmostChangedNode;
00596     m_timeRenderTreeStartTime = other.m_timeRenderTreeStartTime;
00597     m_bRenderTreeTimeSlice = other.m_bRenderTreeTimeSlice;
00598     m_countTotal = other.m_countTotal;
00599     m_countStored = other.m_countStored;
00600 
00601     m_bForceMix = other.m_bForceMix;
00602 
00603 #ifdef _DEBUG
00604     m_CurrentContextLevel = 0;
00605     m_TraceOutContextLevels = FALSE;
00606 //  m_TraceOutContextLevels = TRUE;
00607 #endif
00608 }
00609 
00610 
00611 /********************************************************************************************
00612 
00613 >   BOOL RenderRegion::Init()
00614 
00615     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00616     Created:    27/05/94
00617     Returns:    TRUE if initialised ok;
00618                 FALSE if not.
00619     Purpose:    Initialise the render region.
00620 
00621 ********************************************************************************************/
00622 
00623 BOOL RenderRegion::Init()
00624 {
00625     return TRUE;
00626 }
00627 
00628 /********************************************************************************************
00629 
00630 >   RenderRegion::~RenderRegion()
00631 
00632     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00633     Created:    15/5/93
00634     Inputs:     -
00635     Outputs:    -
00636     Returns:    -
00637     Purpose:    Default Destructor for RenderRegion Class.
00638                 Releases any memory claimed for the ContextStack.
00639     Errors:     -
00640     SeeAlso:    OSRenderRegion::~OSRenderRegion()
00641 
00642 ********************************************************************************************/
00643 
00644 RenderRegion::~RenderRegion()
00645 {
00646     // Ilan
00647     IsBeingReset = TRUE;
00648 
00649     // Get rid of any stacked Captures
00650     Capture* pCapture = GetTopCapture();
00651     while (pCapture)
00652     {
00653         ENSURE(!pCapture->OwnsBitmap(), "Capture unexpectedly owns bitmap in RenderRegion::ResetRegion");
00654 
00655         m_CaptureStack.Pop();
00656 //TRACEUSER( "Phil", _T("~RenderRegion Pop/Delete Capture\n"));
00657         if (pCapture->IsMaster())
00658         {
00659             SetRenderToCapture(pCapture, FALSE, FALSE);
00660         }
00661         else
00662         {
00663             pCapture->FreeDIB();
00664         }
00665         delete pCapture;
00666 
00667         pCapture = GetTopCapture();
00668     }
00669 
00670 
00671     if( m_fOwned )
00672     {
00673         delete RenderDC;
00674         RenderDC = NULL;
00675     }
00676 
00677 // Webster - markn 15/8/97
00678 // This has been taken out of Webster builds as it can cause fatal access violations with Paper render regions.
00679 // It is new path processor code that not's totally bug-free, and as path processors are not used in Webster,
00680 // it can be safely taken out.
00681 // Now taken out via new VECTOR_STROKING flag Neville 2/10/97 
00682 #ifdef VECTOR_STROKING
00683     // Ask the RenderStack to pop all attributes off itself. This gives them a chance
00684     // to clean up properly (remove PathProcessors etc).
00685     TheStack.CleanUpBeforeDestruct(this);
00686 #endif // VECTOR_STROKING
00687 
00688     // Nearly always non-NULL, but e.g. PaperRenderRegions will have deleted
00689     // their attributes before we get here so we check (and hence don't GPF!)
00690     if (CurrentAttrs != NULL)
00691     {
00692         for (INT32 i = 0; i < NumCurrentAttrs; i++)
00693         {
00694 
00695 // WEBSTER - markn 16/7/97
00696 // This hides a bug in the text tool, which won't go off if you don't use Path processors
00697 // The bug - 
00698 //      create a multi-line paragraph text object
00699 //      Select all and apply -5 base line shift
00700 //      Change to a large font
00701 //      Change the font
00702 //      Change the text size
00703 //      Should go bang
00704 //
00705 // I have no idea what the problem is (I'd fix it if I knew), and don't have time to spend on it.
00706 // Should be looked into though...
00707 // Now taken out via new VECTOR_STROKING flag Neville 2/10/97 
00708 #ifdef VECTOR_STROKING
00709             // Tell the attribute that it's being chucked out of scope
00710         //  CurrentAttrs[i].pAttr->GoingOutOfScope(this);
00711 #endif // VECTOR_STROKING
00712 
00713             // And delete it if it's a temporary attr
00714             if (CurrentAttrs[i].Temp)
00715             {
00716                 CC_ASSERT_VALID(CurrentAttrs[i].pAttr);
00717                 delete CurrentAttrs[i].pAttr;
00718             }
00719         }
00720 
00721         // We've finished with this array of attributes now
00722         CCFree(CurrentAttrs);
00723     }
00724 
00725     if (CurrentSubRenderState != NULL)
00726         delete CurrentSubRenderState;
00727 
00728     if (PathProcessorStack != NULL)
00729     {
00730 //      ERROR3("RenderRegion destructed while PathProcessors still active");
00731         while (PathProcessorStack != NULL)
00732             PopPathProcessor();
00733     }
00734 }
00735 
00736 
00737 
00738 
00739 /********************************************************************************************
00740 
00741 >   BOOL CopyRenderInfo( const RenderRegion &Other)
00742 
00743     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
00744     Created:    6/4/94
00745     Inputs:     Other - The render region to get the info out of
00746     Returns:    FALSE if failed, TRUE if worked.
00747     Purpose:    Copies all the parameters from the render region 'Other' into this render
00748                 region. This was written for the region merging code. When a new region
00749                 is created, due to existing regions being split up, it should be based on
00750                 the original region, with a different clipping rectangle
00751 
00752 ********************************************************************************************/
00753 
00754 BOOL RenderRegion::CopyRenderInfo( const RenderRegion &Other)
00755 {
00756     // We're writing over our render info with the other RndRgn's settings, so we must vape
00757     // all of our PathProcessors (if there are any, which probably there shouldn't be)
00758     while (PathProcessorStack != NULL)
00759         PopPathProcessor();
00760 
00761     // Copy params to do with the rendering
00762     CurrentClipRect = Other.CurrentClipRect;
00763     RenderMatrix    = Other.RenderMatrix;
00764     ScaleFactor     = Other.ScaleFactor;
00765     RenderSpread    = Other.RenderSpread;
00766     DrawingMode     = Other.DrawingMode;
00767     CurrentColContext = Other.CurrentColContext;
00768     RenderComplexShapes = Other.RenderComplexShapes;
00769 
00770     // Copy params to do with the window we are rendering into
00771     RenderView      = Other.RenderView;
00772     RenderDC        = Other.RenderDC;
00773 //  DCHandle        = Other.DCHandle;
00774 
00775     // Copy the flags
00776     RenderFlags     = Other.RenderFlags;
00777 
00778     // Copy the pixel width info
00779     PixelWidth      = Other.PixelWidth;
00780     ScaledPixelWidth = Other.ScaledPixelWidth;
00781 
00782     // Copy the rendered state
00783     IsPaperRendered = Other.IsPaperRendered;
00784     IsInkRenderStarted = Other.IsInkRenderStarted;
00785     NeedsOSPaper = Other.NeedsOSPaper;
00786     Timeslice = Other.Timeslice;
00787     RRQuality = Other.RRQuality;
00788 
00789     // Copy the node to render
00790     CurrentRenderState = Other.CurrentRenderState;
00791     CurrentSubRenderState = NULL;
00792     SubRenderStateLocked = FALSE;
00793 
00794     // Copy the current attributes
00795     if (!CopyCurrentAttributes(Other))
00796     {
00797         // Unable to copy the current attributes
00798         ENSURE(FALSE, "Unable to copy current attributes");
00799         InformError();
00800         return FALSE;
00801     }
00802     
00803 
00804     // Now make a copy of the ContextSatck
00805     // Actually don't, or you get some attributes left from this render region at the bottom
00806 /*  if (!TheStack.Copy(&Other.TheStack, this))
00807     {
00808         // Unable to copy the render stack
00809         ENSURE(FALSE, "Unable to copy Rendering stack");
00810         InformError();
00811         return FALSE;
00812     }
00813 */
00814     DrawingMode = Other.DrawingMode;
00815 
00816     // Set the Fuzzy Clipping Rects to something
00817     InnerRect = Other.InnerRect;
00818     OuterRect = Other.OuterRect;
00819 
00820     // Set up vars to do with banded rendering
00821     RegionRect = Other.RegionRect;
00822     IsRegionBanded = Other.IsRegionBanded;
00823     CanRegionBeMerged = Other.CanRegionBeMerged;
00824     IsLastBand = Other.IsLastBand;
00825 
00826     // this is critical to make sure InitDevice gets called on the next StartRender
00827     RenderFlags.ValidDevice = FALSE;
00828 
00829     return TRUE;
00830 }
00831 
00832 
00833 
00834 
00835 
00836 
00837 /********************************************************************************************
00838 
00839 >   BOOL RenderRegion::AttachDevice(View* ViewToAttach, wxDC* DCToAttach,
00840                                             Spread* SpreadToAttach)
00841 
00842     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00843     Created:    11/5/93
00844     Inputs:     A View ptr ,wxDC ptr and Spread ptr to attach to the RenderRegion.
00845                 The View pointer must not be NULL!
00846     Returns:    TRUE if attached successfully;
00847                 FALSE if not.
00848     Purpose:    Attaches View, wxDC and Spread pointers to the RenderRegion.
00849                 The View is used to for general rendering purposes.
00850                 The wxDC is the device that we are rendering to.  We extract the HDC from this
00851                 and store it so we can recreate another wxDC object for background rendering.
00852                 The Spread is just stored for external referance and is used to continue
00853                 rendering during BackGnd redraw.
00854 
00855                 NB. This function should be called before doing anything else in the 
00856                 AttachDevice() function of a derived class.
00857 
00858     Errors:     If ViewToAttach is NULL => ERROR2
00859     SeeAlso:    RenderRegion::InitDevice
00860 
00861 ********************************************************************************************/
00862 
00863 BOOL RenderRegion::AttachDevice(View* ViewToAttach, CCDC* DCToAttach,
00864                                 Spread* SpreadToAttach, bool fOwned /*= false*/)
00865 {
00866     return AttachDevice(ViewToAttach, DCToAttach->GetDC(), SpreadToAttach, fOwned);
00867 }
00868 
00869 BOOL RenderRegion::AttachDevice(View* ViewToAttach, wxDC* DCToAttach,
00870                                 Spread* SpreadToAttach, bool fOwned /*= false*/)
00871 {
00872     RenderSpread = SpreadToAttach;
00873     RenderView   = ViewToAttach;
00874     RenderDC     = DCToAttach;
00875     m_fOwned     = fOwned;
00876 
00877     ERROR2IF(ViewToAttach == NULL, FALSE, "NULL View passed to RenderRegion::AttachDevice()!");
00878 
00879     // Find which view the render region is to be rendering to
00880     if (RenderView != NULL)
00881     {
00882         // We have a render window - calculate the pixel sizes.
00883         PixelWidth = CalcPixelWidth();
00884         ScaledPixelWidth = CalcScaledPixelWidth();
00885     }
00886     else if (IS_KIND_OF(OSRenderRegion))
00887     {
00888         // Only do this for OSRenderRegions because they can be used to
00889         // render into dialogs (GRenderRegions have their own system
00890         // of pixel size).
00891         PixelWidth = CalcPixelWidth();
00892         ScaledPixelWidth = CalcScaledPixelWidth();
00893     }
00894 
00895     // No ink rendering yet.
00896     CurrentRenderState = NULL;
00897     CurrentSubRenderState = NULL;
00898     SubRenderStateLocked = FALSE;
00899 
00900     // Initialise drawing mode.
00901     DrawingMode = DM_COPYPEN;
00902 
00903     // All ok
00904     return TRUE;
00905 }
00906 
00907 /********************************************************************************************
00908 
00909 >   BOOL RenderRegion::InitDevice()
00910 
00911     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00912     Created:    27/05/94
00913     Returns:    TRUE if the device specific initialisation is completed successfully;
00914                 FALSE if not.
00915     Purpose:    Initialises the render region's connection to the device information
00916                 passed in to RenderRegion::AttachDevice.
00917     Errors:     Out of memory, Internal error
00918     SeeAlso:    RenderRegion::AttachDevice
00919 
00920 ********************************************************************************************/
00921 
00922 BOOL RenderRegion::InitDevice()
00923 {
00924     // Find this documents default colour context for the screen (RGB)
00925     if (RenderView != NULL)
00926     {
00927         // Find a colour context for the View we're rendering. This will automatically find
00928         // a suitable local, document, or global context for us to use
00929         CurrentColContext = RenderView->GetColourContext(COLOURMODEL_RGBT);
00930         if (CurrentColContext == NULL)  // should never be a problem!
00931         {
00932             DiagnosticFn( _T("InitDevice:"), _T("No colour context") );
00933             ERROR(_R(IDT_INTERNAL_ERROR), FALSE);
00934         }
00935     }
00936     else
00937     {
00938         ERROR3("View is NULL in RenderRegion::InitDevice()");
00939         return FALSE;
00940     }
00941 
00942     // If this region has been reset, then we may already have
00943     // a CurrentAttrs array that needs to be de-allocated.
00944     if (CurrentAttrs != NULL)
00945     {
00946         // Release any temporary objects used by the 'current attribute' array.
00947         for (INT32 i = 0; i < NumCurrentAttrs; i++)
00948         {
00949             if (CurrentAttrs[i].Temp)
00950             {
00951                 CC_ASSERT_VALID(CurrentAttrs[i].pAttr);
00952                 delete CurrentAttrs[i].pAttr;
00953             }
00954         }
00955 
00956         // We've finished with this array of attributes now
00957         CCFree(CurrentAttrs);
00958         NumCurrentAttrs = 0;
00959     }
00960 
00961     // Set up the attributes for this device.
00962     CurrentAttrs = AttributeManager::GetDefaultAttributes();
00963 
00964     if (CurrentAttrs == NULL)
00965     {
00966         NumCurrentAttrs = 0;
00967         return FALSE;
00968     }
00969 
00970     // Find out how many attributes there are.
00971     NumCurrentAttrs = AttributeManager::GetNumAttributes();
00972 
00973     // Render all non-NULL attributes.
00974     for (INT32 i = 0; i < NumCurrentAttrs; i++)
00975     {
00976         if (CurrentAttrs[i].pAttr != NULL && CurrentAttrs[i].pAttr->CanBeRenderedDirectly())
00977             CurrentAttrs[i].pAttr->Render(this);
00978     }
00979 
00980     // Ilan
00981     // Initialise the current offscreen pointer with a placeholder
00982     // this ensures that there is a default value which can be shifted to TheStack
00983     // so that the Restore() function gets called to to signal when the offscreen
00984     // bitmap rendering process has completed
00985     // NB ATTR_FEATHER used, but any offscreen attr with a conventional Restore() function would do
00986     // NB2 don't need to free mem as it is a pointer to the default val
00987     CurrentOffscreenAttr = (OffscreenAttrValue*) AttributeManager::GetDefaultAttributeVal(ATTR_FEATHER);
00988 
00989     // Override the quality attribute according to the View's setting.
00990     // Don't bother if there is no DocView - e.g. it's a render region that is used
00991     // to export a file.
00992     if (RenderView != NULL)
00993     {
00994         // Create a new quality attribute and install it.
00995         QualityAttribute *pAttr = new QualityAttribute(RenderView->RenderQuality);
00996         ENSURE(pAttr != NULL, "No memory for quality attribute to be created");
00997         if (pAttr == NULL)
00998             return FALSE;
00999 
01000         // TRUE => Temp; delete this attribute when it is popped off the stack.
01001         SetQuality(pAttr, TRUE);
01002     }
01003 
01004     // Everything completed ok
01005     return TRUE;
01006 }
01007 
01008 BOOL RenderRegion::ResetColourContext()
01009 {
01010     // Find this documents default colour context for the screen (RGB)
01011     if (RenderView != NULL)
01012     {
01013         // Find a colour context for the View we're rendering. This will automatically find
01014         // a suitable local, document, or global context for us to use
01015         CurrentColContext = RenderView->GetColourContext(COLOURMODEL_RGBT);
01016         if (CurrentColContext == NULL)  // should never be a problem!
01017         {
01018             DiagnosticFn( _T("InitDevice:"), _T("No colour context") );
01019             ERROR(_R(IDT_INTERNAL_ERROR), FALSE);
01020         }
01021     }
01022     else
01023     {
01024         ERROR3("View is NULL in RenderRegion::InitDevice()");
01025         return FALSE;
01026     }
01027 
01028     return(TRUE);
01029 }
01030 
01031 ColourContext* RenderRegion::GetColourContext()
01032 {
01033     return(CurrentColContext);
01034 }
01035 
01036 
01037 /********************************************************************************************
01038 
01039 >   Node* RenderRegion::GetRenderState()
01040 
01041     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01042     Created:    12/7/93
01043     Inputs:     -
01044     Outputs:    -
01045     Returns:    A Ptr to a Node (or NULL if idle).
01046     Purpose:    Returns the Current Render State of the RenderRegion, which is a pointer
01047                 to the next Node to render. If NULL then it is not currently rendering.
01048     Errors:     -
01049     SeeAlso:    -
01050 
01051 ********************************************************************************************/
01052 
01053 Node* RenderRegion::GetRenderState()
01054 {
01055     return CurrentRenderState;
01056 }
01057 
01058 /********************************************************************************************
01059 
01060 >   BOOL RenderRegion::ImmediateRender()
01061 
01062     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01063     Created:    26/7/93
01064     Inputs:     -
01065     Outputs:    -
01066     Returns:    TRUE if current clip rect is within view (ie whether to render or not).
01067     Purpose:    Used to Draw something immediately.
01068     Errors:     -
01069     SeeAlso:    -
01070 
01071 ********************************************************************************************/
01072 
01073 BOOL RenderRegion::ImmediateRender()
01074 {
01075     RenderFlags.bImmediateRender = TRUE;
01076     if (!StartRender())
01077         return FALSE;
01078 
01079     // Immediate render regions default to 0 line-width because they usually want to
01080     // render drag blobs etc which should be only one pixel wide.
01081     SetLineWidth(0);
01082 
01083     // Immediate render is usually used for blob rendering
01084     // normally we use the default quality, but we mustn't do that on hit-detection bitmaps
01085     // else they render outlined shapes as solid (See GRenderClick classes)
01086     SetDefaultQuality();
01087 
01088     //SetStartCap(LineCapButt);
01089     //SetJoinType(RoundJoin);
01090 
01091     return TRUE;
01092 }
01093 
01094 void RenderRegion::SaveContext()
01095 {
01096     TheStack.SaveContext();
01097 
01098 #ifdef _DEBUG
01099     m_CurrentContextLevel++;
01100 #endif
01101 }
01102 
01103 void RenderRegion::RestoreContext()
01104 {
01105     TheStack.RestoreContext(this);
01106 
01107 #ifdef _DEBUG
01108     m_CurrentContextLevel--;
01109 #endif
01110 }
01111 
01112 /********************************************************************************************
01113 
01114 >   void RenderRegion::DefaultRender(BOOL bForceImmediate = FALSE)
01115 
01116     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01117     Created:    9/7/93
01118     Inputs:     -
01119     Outputs:    -
01120     Returns:    -
01121     Purpose:    Calls the attatched view to render itself.  This is used to continue
01122                 rendering into a suspended RenderRegion.
01123     Errors:     -
01124     SeeAlso:    -
01125 
01126 ********************************************************************************************/
01127 
01128 void RenderRegion::DefaultRender(BOOL bForceImmediate /*= FALSE*/)
01129 {
01130     ENSURE(RenderView != NULL,"RenderRegion::DefaultRender called with invalid RenderView");
01131 
01132     if (RenderView)
01133     {
01134         RenderView->AllocateDC();
01135         RenderDC = RenderView->GetRenderDC();
01136         if (RenderDC)
01137         {
01138             View * pView = RenderView; // as ContinueRenderView can delete the RenderRegion (i.e. "this").
01139             RenderView->SetCurrent();
01140             (RenderView->GetDoc())->SetCurrent();
01141             RenderView->ContinueRenderView(this, RenderSpread, TRUE, TRUE, bForceImmediate);
01142 
01143             // This MUST pair with AllocateDC
01144             pView->DoneWithDC(); // hint that we might like to drop this DC so a fresh one will be created
01145         }
01146         else
01147         {
01148             // This error causes a recursive error condition so I'll just TRACE for now
01149 //          Error::SetError(_R(IDT_INTERNAL_ERROR), 0);
01150 //          InformError();
01151             TRACE(_T("Failed to get a DC for rendering in RenderRegion::DefaultRender\n"));
01152         }
01153     }
01154 }
01155 
01156 
01157 /********************************************************************************************
01158 
01159 >   BOOL RenderRegion::StartRender()
01160 
01161     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
01162     Created:    27/05/94
01163     Purpose:    Initialises the device attachment, if we haven't already done so for this
01164                 render region.  This is so that we can have a two-stage attachment of a
01165                 device to a render region.   This allows us to create render regions
01166                 very quickly, which makes background rendering more efficient as quite
01167                 often we will just throw them away without ever needing a proper connection
01168                 to the device context.
01169     SeeAlso:    RenderRegion::AttachDevice; RenderRegion::InitDevice
01170 
01171 ********************************************************************************************/
01172 
01173 BOOL RenderRegion::StartRender()
01174 {
01175     // If the device has not been Inited, then do it now
01176     if (!RenderFlags.ValidDevice)
01177     {
01178         // Device needs to be initialised
01179         if (!InitDevice())
01180         {
01181             // Something's gone wrong - inform the user.
01182             //InformSeriousError();
01183             TRACE( _T("InitDevice failed in Render Region (Could be not enough mem for Gdraw bitmap)"));
01184             return FALSE;
01185         }
01186 
01187         // Make sure we don't do this again for this render region
01188         RenderFlags.ValidDevice = TRUE;
01189     }
01190 
01191     // Set up the Fuzzy Clipping Rects
01192     // Inner rect is used to clip with, so we need to make it bigger than the region so that
01193     // things like thick lines do not show up
01194     InnerRect = CurrentClipRect;
01195     INT32 ScaleBy = 1000*ScaledPixelWidth;
01196     InnerRect.Inflate(ScaleBy, ScaleBy);
01197 
01198     // The outer rect is used to determine if clipping is needed, so make it
01199     // a few times bigger than the inner rect
01200     OuterRect = InnerRect;
01201     OuterRect.Inflate(InnerRect.Width()*3, InnerRect.Height()*3);
01202 
01203     // Create the default, master capture...
01204     Capture* pNewMasterCapture = NULL;
01205 
01206     if (m_CaptureStack.Empty())
01207     {
01208         pNewMasterCapture = new Capture(this, CAPTUREINFO(ctNESTABLE, cfMASTER | cfPIXWIDTHSCALE), RenderMatrix, CurrentClipRect, GetPixelsPerInch(), CurrentColContext);   // NOTE! Use of ScaledPixelWidth in GetPixelsPerInch in RenderRegion!
01209         if (pNewMasterCapture==NULL) return FALSE;
01210 
01211         m_CaptureStack.Push(pNewMasterCapture);
01212     }
01213 
01214     return TRUE;
01215 }
01216 
01217 /********************************************************************************************
01218 
01219 >   BOOL RenderRegion::CloseDown ()
01220 
01221     Author:     Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
01222     Created:    24/02/00
01223     Inputs:     None.
01224     Returns:    TRUE.
01225     Purpose:    Base class declaration of the CloseDown function. It allows the CloseDown
01226                 functions in the EPS and CMX filters to be virtual over-rides, which means
01227                 that I don't need the IsKindOfs cluttering up the rendering loops.
01228     SeeAlso:    RenderRegion::AttachDevice; RenderRegion::InitDevice
01229 
01230 ********************************************************************************************/
01231 
01232 BOOL RenderRegion::CloseDown ()
01233 {
01234     return TRUE;
01235 }
01236 
01237 /********************************************************************************************
01238 
01239 >   virtual void Region::ConditionalSuicide ( void )
01240 
01241     Author:     Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
01242     Created:    24/2/00
01243     Inputs:     -
01244     Returns:    -
01245     Purpose:    Causes the object to commit suicide. This is to get around using a few
01246                 if IS_A calls elsewhere in Camelot.
01247 
01248 ********************************************************************************************/
01249 
01250 void RenderRegion::ConditionalSuicide ( void )
01251 {
01252     // Yes, this is a legal C++ expression. Just don't attempt to call this object again.
01253     delete this;
01254 }
01255 
01256 /********************************************************************************************
01257 
01258 >   virtual void RenderRegion::SetClean(BOOL bResetChangedBounds, BOOL FillWhite)
01259 
01260     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
01261     Created:    28/06/94
01262     Inputs:     FillWhite is an optional parameter which lets the region fill itself with
01263                 white. This is used during hit-testing.
01264     Purpose:    Virtual function used to inform render region that defers update that it
01265                 should set its render state to be 'clean', i.e. if no more rendering occurs
01266                 then it need not update the device.
01267                 This is used for render regions such as GRenderRegions, where we render
01268                 the paper using the host OS graphics primitives, but we have to render
01269                 the paper into the GRenderRegion too, otherwise we will get garbage.
01270                 Equally though, we don't want the GRenderRegion to do a potentially slow
01271                 blit if all it is going to draw is some paper.  It also allows the 'changed
01272                 box' to be reset, so if we only have a small object on the page, then only
01273                 the area containing the object is updated using a blit.
01274                 The default implementation of this function does nothing - most render
01275                 regions won't need to over-ride this null behaviour.
01276     SeeAlso:    GRenderRegion::SetClean
01277 
01278 ********************************************************************************************/
01279 
01280 void RenderRegion::SetClean(BOOL bResetChangedBounds, BOOL FillWhite)
01281 {
01282 }
01283 
01284 /********************************************************************************************
01285 
01286 >   void RenderRegion::SetMatrix( Matrix& NewMatrix )
01287 
01288     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
01289     Created:    26/10/93
01290     Inputs:     NewMatrix - The matrix that will replace the old RenderMatrix
01291     Purpose:    This can be used to set the RenderRegions transform matrix
01292                 to the given matrix. This should really be used with care!
01293     SeeAlso:    RenderRegion::ConcatenateMatrix
01294 
01295 ********************************************************************************************/
01296 
01297 void RenderRegion::SetMatrix( Matrix& NewMatrix )
01298 {
01299     // Set the Render Matrix to the one provided
01300     RenderMatrix = NewMatrix;
01301     if (GetMasterCapture())
01302     {
01303         GetMasterCapture()->CaptureMatrix = NewMatrix;
01304     }
01305 }
01306 
01307 /********************************************************************************************
01308 
01309 >   Matrix RenderRegion::ConcatenateMatrix( Matrix& NewMatrix )
01310 
01311     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
01312     Created:    26/10/93
01313     Inputs:     NewMatrix - The Matrix that will be combined with the current
01314                 RenderMatrix in the RenderRegion
01315     Returns:    The old RenderRegion Matrix
01316     Purpose:    This can be used to add a transform in to the render regions
01317                 transformation matrix. The function performs the following
01318                 matrix operation :- MonoOn
01319                 RenderMatrix = NewMatrix * RenderMatrix; MonoOff
01320     SeeAlso:    RenderRegion::SetMatrix
01321 
01322 ********************************************************************************************/
01323 
01324 Matrix RenderRegion::ConcatenateMatrix( Matrix& NewMatrix )
01325 {
01326     // Need to remember the old matrix so we can return it
01327     Matrix Temp = RenderMatrix;
01328 
01329     // Add a transform to the matrix we already have
01330     RenderMatrix = NewMatrix * RenderMatrix;
01331 
01332     // return the old matrix to the caller
01333     return Temp;
01334 }
01335 
01336 
01337 
01338 
01339 
01340 
01341 /********************************************************************************************
01342 
01343 >   void RenderRegion::SetClipRect(DocRect &NewClipRect, BOOL ReCalcContextNode = FALSE);
01344 
01345     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01346     Created:    24/6/93
01347     Inputs:     A DocRect describing the tightest bounding box around the clipping region.
01348     Outputs:    -
01349     Returns:    -
01350     Purpose:    Sets the Clipping rectangle of the Render Region.
01351                 Calls InitClipping() to acually set the clip region in an OS specific way.
01352     Errors:     -
01353     SeeAlso:    RenderRegion::GetClipRect(); RenderRegion::RenderRegion()
01354 
01355 ********************************************************************************************/
01356 
01357 void RenderRegion::SetClipRect(DocRect &NewClipRect, BOOL ReCalcContextNode)
01358 {
01359     ENSURE(NewClipRect.IsValid(),"RenderRegion::SetClipRect called with Invalid Rectangle");
01360     CurrentClipRect = NewClipRect;
01361 
01362 ENSURE(GetMasterCapture()==NULL || MasterCaptureIsCurrent(), "SetClipRect being called while child Captures are running\n");
01363 if (GetMasterCapture()!=NULL)
01364 {
01365     if (MasterCaptureIsCurrent())
01366     {
01367         GetMasterCapture()->SetClipRect(NewClipRect);
01368     }
01369 }
01370 
01371     if (RenderFlags.Rendering)
01372     {
01373         // Do some OS specific initialisation of the clipping region
01374         InitClipping(); // This is implemented in the Derived classes (OSRenderRegion etc)
01375     }
01376 
01377     // if we need to recalculate the regions context node then go ahead
01378     if (ReCalcContextNode==TRUE)
01379     {
01380 //      CurrentRenderState = RenderSpread->FindFirstForClippedInkRender(&CurrentClipRect, this);
01381         CurrentRenderState = RenderSpread;  // For use with RenderTree
01382 
01383         // Don't need Node sub context anymore
01384         delete CurrentSubRenderState;
01385         CurrentSubRenderState = NULL;
01386         SubRenderStateLocked = FALSE;
01387     }
01388 }
01389 
01390 /********************************************************************************************
01391 
01392 >   DocRect RenderRegion::GetClipRect()
01393 
01394     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01395     Created:    26/5/93
01396     Inputs:     -
01397     Outputs:    -
01398     Returns:    A DocRect describing the tightest bounding box around the clipping region
01399     Purpose:    Returns the clipping rectangle of the Render Region
01400     Errors:     -
01401     SeeAlso:    RenderRegion::SetClipRect(); RenderRegion::RenderRegion() 
01402 
01403 ********************************************************************************************/
01404 
01405 DocRect RenderRegion::GetClipRect()
01406 {
01407     return CurrentClipRect;
01408 }
01409 /********************************************************************************************
01410 
01411 >   void RenderRegion::SetFillAttributes(ChangeAttrType Type = CHANGEATTR_ALL)
01412 
01413     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
01414     Created:    11/10/94
01415     Inputs:     Type - the type of the fill attribute that has changed, can be:
01416 
01417                     CHANGEATTR_ALL
01418                     CHANGEATTR_GEOMETRY
01419                     CHANGEATTR_EFFECT
01420                     CHANGEATTR_MAPPING
01421                     CHANGEATTR_TRANSP_GEOMETRY
01422                     CHANGEATTR_TRANSP_EFFECT
01423                     CHANGEATTR_TRANSP_MAPPING
01424                     CHANGEATTR_WINDING_RULE
01425 
01426     Purpose:    Inform the render region that an aspect of the path filling attributes
01427                 has changed.  The base class version just updates the RenderRegion
01428                 member variable FillFlags to reflect which aspects of the fill attributes
01429                 have become invalid.  Derived render regions can either call the base class
01430                 or just implement whatever methods they need for keeping track of these
01431                 changes - or a combination of the two, of course.
01432                 Some render regions (e.g. GRenderRegions) don't need to do anything about
01433                 this at all as all attributes are invoked whenever anything is rendered.
01434                 If this is the case, then this should be over-ridden to have a NULL 
01435                 implementation because this will improve rendering speed.
01436     SeeAlso:    ChangeAttrType
01437 
01438 ********************************************************************************************/
01439 
01440 void RenderRegion::SetTextAttributes(ChangeFillAttrType Type)
01441 {
01442     switch (Type)
01443     {
01444         case CHANGEFILLATTR_ALL:
01445             TextFlags.ValidFont         = FALSE;
01446             TextFlags.ValidBold         = FALSE;
01447             TextFlags.ValidItalic       = FALSE;
01448             TextFlags.ValidUnderline    = FALSE;
01449             TextFlags.ValidAspect       = FALSE;
01450             TextFlags.ValidTracking     = FALSE;
01451             TextFlags.ValidFontSize     = FALSE;
01452             TextFlags.ValidJustify      = FALSE;
01453             TextFlags.ValidScript       = FALSE; 
01454             TextFlags.ValidBaseLine     = FALSE;
01455             TextFlags.ValidLineSpace    = FALSE;
01456             TextFlags.ValidLeftMargin   = FALSE;
01457             TextFlags.ValidRightMargin  = FALSE;
01458             TextFlags.ValidFirstIndent  = FALSE;
01459             TextFlags.ValidRuler        = FALSE;
01460             break;
01461 
01462         case CHANGEATTR_FONT:
01463             TextFlags.ValidFont         = FALSE;
01464             break;
01465 
01466         case CHANGEATTR_BOLD:
01467             TextFlags.ValidBold         = FALSE;
01468             break;
01469 
01470         case CHANGEATTR_ITALIC:
01471             TextFlags.ValidItalic       = FALSE;
01472             break;
01473 
01474         case CHANGEATTR_UNDERLINE:
01475             TextFlags.ValidUnderline    = FALSE;
01476             break;
01477 
01478         case CHANGEATTR_ASPECT:
01479             TextFlags.ValidAspect       = FALSE;
01480             break;
01481 
01482         case CHANGEATTR_TRACKING:
01483             TextFlags.ValidTracking     = FALSE;
01484             break;
01485 
01486         case CHANGEATTR_SIZE:
01487             TextFlags.ValidFontSize     = FALSE;
01488             break;
01489         case CHANGEATTR_JUSTIFY:
01490             TextFlags.ValidJustify      = FALSE;
01491             break;
01492         case CHANGEATTR_SCRIPT:
01493             TextFlags.ValidScript       = FALSE;
01494             break;
01495         case CHANGEATTR_BASELINE:
01496             TextFlags.ValidBaseLine     = FALSE;
01497             break;
01498         case CHANGEATTR_LINESPACE:
01499             TextFlags.ValidLineSpace    = FALSE;
01500             break;
01501         case CHANGEATTR_LEFTMARGIN:
01502             TextFlags.ValidLeftMargin   = FALSE;
01503             break;
01504         case CHANGEATTR_RIGHTMARGIN:
01505             TextFlags.ValidRightMargin  = FALSE;
01506             break;
01507         case CHANGEATTR_FIRSTINDENT:
01508             TextFlags.ValidFirstIndent  = FALSE;
01509             break;
01510         case CHANGEATTR_RULER:
01511             TextFlags.ValidRuler        = FALSE;
01512             break;
01513 
01514         default:
01515             ERROR3_PF(("Invalid attribute type (%d) in SetFillAttributes", Type));
01516             break;
01517     }
01518 }
01519 
01520 /********************************************************************************************
01521 
01522 >   void RenderRegion::SetLineAttributes(ChangeAttrType Type = CHANGEATTR_ALL)
01523 
01524     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01525     Created:    15/4/95
01526     Inputs:     Type - the type of the fill attribute that has changed, can be:
01527 
01528                 CHANGEATTR_ALL
01529                 CHANGEATTR_STROKECOL
01530                 CHANGEATTR_STROKETRANSP
01531                 CHANGEATTR_LINEWIDTH
01532                 CHANGEATTR_JOINTYPE
01533                 CHANGEATTR_DASHPATTERN
01534                 CHANGEATTR_LINECAP
01535                 CHANGEATTR_STARTARROW
01536                 CHANGEATTR_ENDARROW
01537                 CHANGEATTR_MITRELIMIT
01538 
01539     Purpose:    Inform the render region that an aspect of the path stroking attributes
01540                 has changed.  The base class version just updates the RenderRegion
01541                 member variable StrokeFlags to reflect which aspects of the stroke attributes
01542                 have become invalid.  Derived render regions can either call the base class
01543                 or just implement whatever methods they need for keeping track of these
01544                 changes - or a combination of the two, of course.
01545                 Some render regions (e.g. GRenderRegions) don't need to do anything about
01546                 this at all as all attributes are invoked whenever anything is rendered.
01547                 If this is the case, then this should be over-ridden to have a NULL 
01548                 implementation because this will improve rendering speed.
01549     SeeAlso:    ChangeLineAttrType
01550 
01551 ********************************************************************************************/
01552 
01553 void RenderRegion::SetLineAttributes(ChangeLineAttrType Type)
01554 {
01555     switch (Type)
01556     {
01557         case CHANGELINEATTR_ALL:
01558             StrokeFlags.ValidStrokeColour   = FALSE;
01559             StrokeFlags.ValidStrokeTransp   = FALSE;
01560             StrokeFlags.ValidLineWidth      = FALSE;
01561             StrokeFlags.ValidJoinType       = FALSE;
01562             StrokeFlags.ValidDashPattern    = FALSE;
01563             StrokeFlags.ValidLineCap        = FALSE;
01564             StrokeFlags.ValidStartArrow     = FALSE;
01565             StrokeFlags.ValidEndArrow       = FALSE;
01566             StrokeFlags.ValidMitreLimit     = FALSE;
01567             break;
01568 
01569         case CHANGEATTR_STROKECOL:
01570             StrokeFlags.ValidStrokeColour   = FALSE;
01571             break;
01572 
01573         case CHANGEATTR_STROKETRANSP:
01574             StrokeFlags.ValidStrokeTransp   = FALSE;
01575             break;
01576 
01577         case CHANGEATTR_LINEWIDTH:
01578             StrokeFlags.ValidLineWidth      = FALSE;
01579             break;
01580 
01581         case CHANGEATTR_JOINTYPE:
01582             StrokeFlags.ValidJoinType       = FALSE;
01583             break;
01584 
01585         case CHANGEATTR_DASHPATTERN:
01586             StrokeFlags.ValidDashPattern    = FALSE;
01587             break;
01588 
01589         case CHANGEATTR_LINECAP:
01590             StrokeFlags.ValidLineCap        = FALSE;
01591             break;
01592 
01593         case CHANGEATTR_STARTARROW:
01594             StrokeFlags.ValidStartArrow     = FALSE;
01595             break;
01596 
01597         case CHANGEATTR_ENDARROW:
01598             StrokeFlags.ValidEndArrow       = FALSE;
01599             break;
01600 
01601         case CHANGEATTR_MITRELIMIT:
01602             StrokeFlags.ValidMitreLimit     = FALSE;
01603             break;
01604 
01605         default:
01606             ERROR3_PF(("Invalid attribute type (%d) in SetLineAttributes", Type));
01607             break;
01608     }
01609 }
01610 
01611 /********************************************************************************************
01612 
01613 >   void RenderRegion::SetFillAttributes(ChangeAttrType Type = CHANGEATTR_ALL)
01614 
01615     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
01616     Created:    11/10/94
01617     Inputs:     Type - the type of the fill attribute that has changed, can be:
01618 
01619                     CHANGEATTR_ALL
01620                     CHANGEATTR_GEOMETRY
01621                     CHANGEATTR_EFFECT
01622                     CHANGEATTR_MAPPING
01623 
01624                     CHANGEATTR_TRANSP_GEOMETRY
01625                     CHANGEATTR_TRANSP_EFFECT
01626                     CHANGEATTR_TRANSP_MAPPING
01627                     CHANGEATTR_WINDING_RULE
01628 
01629     Purpose:    Inform the render region that an aspect of the path filling attributes
01630                 has changed.  The base class version just updates the RenderRegion
01631                 member variable FillFlags to reflect which aspects of the fill attributes
01632                 have become invalid.  Derived render regions can either call the base class
01633                 or just implement whatever methods they need for keeping track of these
01634                 changes - or a combination of the two, of course.
01635                 Some render regions (e.g. GRenderRegions) don't need to do anything about
01636                 this at all as all attributes are invoked whenever anything is rendered.
01637                 If this is the case, then this should be over-ridden to have a NULL 
01638                 implementation because this will improve rendering speed.
01639     SeeAlso:    ChangeAttrType
01640 
01641 ********************************************************************************************/
01642 
01643 void RenderRegion::SetFillAttributes(ChangeAttrType Type)
01644 {
01645     switch (Type)
01646     {
01647         case CHANGEATTR_ALL:
01648             FillFlags.ValidGeometry         = FALSE;
01649             FillFlags.ValidEffect           = FALSE;
01650             FillFlags.ValidMapping          = FALSE;
01651             FillFlags.ValidTransGeometry    = FALSE;
01652             FillFlags.ValidTransEffect      = FALSE;
01653             FillFlags.ValidTransMapping     = FALSE;
01654             FillFlags.ValidWindingRule      = FALSE;
01655             break;
01656 
01657         case CHANGEATTR_GEOMETRY:
01658             FillFlags.ValidGeometry         = FALSE;
01659             break;
01660 
01661         case CHANGEATTR_EFFECT:
01662             FillFlags.ValidEffect           = FALSE;
01663             break;
01664 
01665         case CHANGEATTR_MAPPING:
01666             FillFlags.ValidMapping          = FALSE;
01667             break;
01668 
01669         case CHANGEATTR_TRANSP_GEOMETRY:
01670             FillFlags.ValidTransGeometry    = FALSE;
01671             break;
01672 
01673         case CHANGEATTR_TRANSP_EFFECT:
01674             FillFlags.ValidTransEffect      = FALSE;
01675             break;
01676 
01677         case CHANGEATTR_TRANSP_MAPPING:
01678             FillFlags.ValidTransMapping     = FALSE;
01679             break;
01680 
01681         case CHANGEATTR_WINDING_RULE:
01682             FillFlags.ValidWindingRule      = FALSE;
01683             break;
01684 
01685         default:
01686             ERROR3_PF(("Invalid attribute type (%d) in SetFillAttributes", Type));
01687             break;
01688     }
01689 }
01690 
01691 /********************************************************************************************
01692 
01693 >   BOOL RenderRegion::SaveAttribute(UINT32 Index, AttributeValue *pAttr, BOOL Temp)
01694 
01695     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
01696     Created:    12/04/94
01697     Inputs:     Index - Unique attribute ID (See AttributeManager::RegisterDefaultAttribute).
01698                 pAttr - the new attribute to use as the current one.
01699                 Temp - TRUE if pAttr points to a temporary object, FALSE if not.
01700     Returns:    TRUE if the operation completed successfully, FALSE if not.
01701     Purpose:    Saves the current attribute on the attribute context stack, and installs
01702                 the given attribute as the new attribute.
01703                 If the attribute object is temporary, then it is deleted when the attribute
01704                 is popped off the stack. See RenderRegion::RestoreAttribute
01705     Errors:     Out of memory.
01706     SeeAlso:    AttributeManager::RegisterDefaultAttribute
01707 
01708 ********************************************************************************************/
01709 
01710 BOOL RenderRegion::SaveAttribute(UINT32 Index, AttributeValue *pAttr, BOOL Temp)
01711 {
01712 #ifdef _DEBUG
01713     if(m_TraceOutContextLevels)
01714     {
01715         TRACE( _T("...Saving Level %d Attribute %s 0x%x\n"),m_CurrentContextLevel,(LPCTSTR)pAttr->GetRuntimeClass()->GetClassName(), pAttr);
01716     }
01717 
01718     // Make sure the current Attr is a valid pointer.
01719     CC_ASSERT_VALID((CurrentAttrs[Index].pAttr));
01720     CC_ASSERT_VALID((pAttr));
01721 
01722 #endif
01723 
01724     // Push the current attribute onto the stack, and install the new attribute as
01725     // the 'current' one.
01726     if (TheStack.Push(CurrentAttrs[Index].pAttr, CurrentAttrs[Index].Temp))
01727     {
01728         CurrentAttrs[Index].pAttr = pAttr; 
01729         CurrentAttrs[Index].Temp = Temp;
01730 
01731         // Everything worked ok.
01732         return TRUE;
01733     }
01734 
01735     // Failed
01736     return FALSE;
01737 }
01738 
01739 /********************************************************************************************
01740 
01741 >   void RenderRegion::RestoreAttribute(UINT32 Index, AttributeValue *pAttr, BOOL Temp)
01742 
01743     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
01744     Created:    12/04/94
01745     Inputs:     Index - Unique attribute ID (See AttributeManager::RegisterDefaultAttribute).
01746                 pAttr - the new attribute to use as the current one.
01747                 Temp - TRUE if pAttr points to a temporary object, FALSE if not.
01748     Purpose:    Restore the given attribute to the current attribute array.  This is called
01749                 when the rendering context stack is popped - the current attribute is
01750                 ousted (and deleted if it is a temporary object), and the given one is
01751                 installed in its place.
01752     SeeAlso:    RenderRegion::SaveAttribute
01753 
01754 ********************************************************************************************/
01755 
01756 void RenderRegion::RestoreAttribute(UINT32 Index, AttributeValue *pAttr, BOOL Temp)
01757 {
01758 #ifdef DEBUG
01759     if(m_TraceOutContextLevels)
01760     {
01761         TRACE( _T("Am Resetting %d "), IsBeingReset);
01762         TRACE( _T("...Restoring Level %d Attribute 0x%x with 0x%x"),m_CurrentContextLevel,CurrentAttrs[Index].pAttr, pAttr);
01763     }
01764 
01765     // Make sure the current Attr is a valid pointer.
01766     if(!IsBeingReset)
01767         CC_ASSERT_VALID((CurrentAttrs[Index].pAttr));
01768 
01769     if(m_TraceOutContextLevels)
01770     {
01771         TRACE( _T(" Attribute %s\n"), (LPCTSTR)pAttr->GetRuntimeClass()->m_lpszClassName);
01772     }
01773 #endif
01774 
01775     // Mark Howitt Friday 13th Oct 2000
01776     // I`ve placed this new check in here in order to stop a problem that causes camelot to crash
01777     // when calling the GoingOutOfScope function. The problem is that the attribute that the stack
01778     // is pointing to has been deleted and is pointing at deleted memory!
01779     // This only happens in the case of when an Op is called when the render loop is deep inside
01780     // the tree and the Op affects an attribute above the current context which when restored is
01781     // corrupt!!! The way we are now dealing with this is to basically not call the GoingOutOfScope
01782     // function but just make a call to the PopPathProcessor function. This makes sure that we
01783     // relinquish any memory.
01784     // We`re using the IsBeingReset variable as it only goes TRUE when the region is about to die!
01785     // It`s also an Ilan variable used for the OffScreenRenderRegions!
01786     if(!IsBeingReset)
01787         CurrentAttrs[Index].pAttr->GoingOutOfScope(this);
01788     else
01789         PopPathProcessor();
01790 
01791     // If the current attribute is a temporary one, then delete it as we're about to stop
01792     // using it.
01793     if (CurrentAttrs[Index].Temp) 
01794         delete CurrentAttrs[Index].pAttr;
01795 
01796     // Install the new attribute.
01797     CurrentAttrs[Index].pAttr = pAttr; 
01798     CurrentAttrs[Index].Temp = Temp;
01799 }
01800 
01801 
01802 /********************************************************************************************
01803 
01804 >   BOOL RenderRegion::CopyCurrentAttributes(const RenderRegion &Other)
01805 
01806     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
01807     Created:    12/04/94
01808     Inputs:     Other - the render region to copy from.
01809     Returns:    TRUE if the current attributes are copied ok; FALSE if not.
01810     Purpose:    Copy the current attribute array of another render region into this
01811                 render region.  The copying is intelligent; i.e. if the other array
01812                 contains 'temporary' objects, then it will copy them, so two render
01813                 regions don't try to delete the same object when their destructor is called.
01814     Errors:     Out of memory.
01815 
01816 ********************************************************************************************/
01817 
01818 BOOL RenderRegion::CopyCurrentAttributes(const RenderRegion &Other)
01819 {
01820     // If the source render region has no attributes, this is ok, as we may
01821     // be cloning it before it has started rendering (attributes only get set up when
01822     // some rendering is done).
01823     if (Other.CurrentAttrs == NULL)
01824     {
01825         // No attributes - nothing to do.
01826         CurrentAttrs = NULL;
01827         NumCurrentAttrs = 0;
01828         return TRUE;
01829     }
01830 
01831     // Allocate a current attributes block.
01832     NumCurrentAttrs = Other.NumCurrentAttrs;
01833     ENSURE(NumCurrentAttrs != 0, "Mismatched attribute stack in CopyCurrentAttributes");
01834     INT32 AttrBlkSize = sizeof(AttributeEntry) * NumCurrentAttrs;
01835     CurrentAttrs = (AttributeEntry *) CCMalloc(AttrBlkSize);
01836     if (CurrentAttrs == NULL)
01837         return FALSE;
01838 
01839     // Copy the current attribute values across
01840     memcpy(CurrentAttrs, Other.CurrentAttrs, AttrBlkSize);
01841 
01842     // We must take copies of any temporary objects to avoid multiple deletion problems.
01843     for (INT32 i = 0; i < NumCurrentAttrs; i++)
01844     {
01845         if (CurrentAttrs[i].Temp)
01846         {
01847             // Get the runtime class info on this object
01848             CCRuntimeClass *pCCRuntimeClass = CurrentAttrs[i].pAttr->GetRuntimeClass();
01849     
01850             // Create another object of the same type
01851             AttributeValue *pNewAttr = (AttributeValue *) pCCRuntimeClass->CreateObject();
01852 
01853             if (pNewAttr == NULL)
01854             {
01855                 // Failed to create object - quit with error, but first ensure that all
01856                 // the rest of the attributes are marked as non-temporary.
01857                 // Otherwise the destructor will attempt to delete objects that belong 
01858                 // to the other render region.
01859                 for (INT32 j = i; j < NumCurrentAttrs; j++)
01860                     CurrentAttrs[j].Temp = FALSE;
01861 
01862                 return FALSE;
01863             }
01864 
01865             // Object created ok - get the object to copy its contents across.
01866             pNewAttr->SimpleCopy(CurrentAttrs[i].pAttr);
01867 
01868             // Place this attribute in the array
01869             CurrentAttrs[i].pAttr = pNewAttr;
01870         }
01871     }
01872 
01873     // It all worked
01874     return TRUE;
01875 }
01876 
01877 
01878 
01879 /********************************************************************************************
01880 
01881 >   StrokeColourAttribute *RenderRegion::PrepareLineColour(StrokeColourAttribute *SourceAttr)
01882 
01883     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01884     Created:    30/7/96
01885 
01886     Inputs:     SourceAttr -    NULL (to copy the current rendering line attribute),
01887                                 or the attribute to be "prepared".
01888 
01889     Returns:    NULL if the given attribute needs not be changed before it is stacked, or
01890                 points to a new attribute which should be stacked in place of the given one.
01891                 Note that it is up to the caller to delete the new attribute (so when
01892                 stacking it, you should set the "Temp" flag)
01893 
01894     Purpose:    This function is used to allow 3 special attributes to function correctly.
01895                 => Overprint line, Overprint fill, and Print on all plates.
01896 
01897                 These attributes are specil in that they act as modifiers to the current
01898                 stroke and fill attributes - they convert active colours into either
01899                 no-colour, or a special greyscale value.
01900 
01901                 This is achieved by the following 2 steps:
01902                 (1) Whenever a colour attribute is stacked, it is possibly replaced by a
01903                     copy which has been modified with respect to the current states of the 3
01904                     Imagesetting attributes.
01905                 (2) Whenever an Imagesetting attribute is stacked, the current line and/or
01906                     fill attributes are copied (if necessary) in order to "apply" the new
01907                     attribute effects to the current rendering colours.
01908 
01909                 This function takes the appropriate attribute and determines if it needs
01910                 to be changed. If it does, a new, replacement, attribute is created and
01911                 returned, which the caller should use in place of the 
01912     
01913     SeeAlso:    RenderRegion::SetFillGeometry; RenderRegion::SetLineColour
01914 
01915 ********************************************************************************************/
01916 
01917 StrokeColourAttribute *RenderRegion::PrepareLineColour(StrokeColourAttribute *SourceAttr)
01918 {
01919     // --- Make sure we've got a source attribute to play with
01920     if (SourceAttr == NULL)
01921         SourceAttr = (StrokeColourAttribute *) CurrentAttrs[ATTR_STROKECOLOUR].pAttr;
01922 
01923     if (SourceAttr == NULL)     // No attribute to modify
01924         return(NULL);
01925 
01926     // --- Find the source line colour. If it's transparent or non-separable, we won't change it
01927     DocColour *SourceCol = SourceAttr->GetStartColour();
01928 
01929     if (SourceCol == NULL || SourceCol->IsTransparent() || !SourceCol->IsSeparable())
01930         return(NULL);
01931 
01932     // --- Check for the PrintOnAllPlates attribute
01933     if ( ((PrintOnAllPlatesAttrValue *) CurrentAttrs[ATTR_PRINTONALLPLATES].pAttr)->IsPrintOnAllPlatesOn() )
01934     {
01935         // Get a global default CMYK colour context
01936         ColourContextGreyT *cc = (ColourContextGreyT *) ColourManager::GetColourContext(COLOURMODEL_GREYT);
01937         ERROR3IF(cc == NULL, "No default Greyscale colour context?!");
01938 
01939         // The print on all plates attribute is set, so we convert this into a pre-separated
01940         // Key greyscale DocColour, overriding overprint etc. First get it as a greyscale:
01941         PColourGreyT GreyDef;
01942         cc->ConvertColour(SourceCol, (ColourPacked *) &GreyDef);
01943 
01944         // Then create a new CMYK colour with the grey-level in the Key component
01945         PColourCMYK ColDef;
01946         ColDef.Key = 255 - GreyDef.Intensity;
01947         ColDef.Cyan = ColDef.Magenta = ColDef.Yellow = 0;
01948 
01949         DocColour NewCol;                   // Place the SourceCol into a DocColour, and make
01950         NewCol.SetCMYKValue(&ColDef);       // it non-colour-separable, so that it is dumped
01951         NewCol.SetSeparable(FALSE);         // out to the rendering device as it stands
01952 
01953         // And create and return a new stroke colour attribute
01954         StrokeColourAttribute *NewAttr = new StrokeColourAttribute(NewCol);
01955         return(NewAttr);
01956     }
01957 
01958     // --- Check for a valid ColourPlate - if there is none, then no more effects will apply
01959     ERROR3IF(CurrentColContext == NULL, "No colour context when rendering?!");
01960     ColourPlate *ColPlate = CurrentColContext->GetColourPlate();
01961 
01962     // Is there an active colour plate? If not, no overprint effects will occur
01963     if (ColPlate == NULL || ColPlate->IsDisabled())
01964         return(NULL);
01965 
01966 
01967     // --- Check for overprint
01968     // Is this entire colour plate set to overprint?
01969     BOOL Overprint = CurrentColContext->GetColourPlate()->Overprints();
01970 
01971     // If not, then is there a current "overprint line" attribute in effect?
01972     if (!Overprint)
01973         Overprint = ((OverprintLineAttrValue *) CurrentAttrs[ATTR_OVERPRINTLINE].pAttr)->IsOverprintOn();
01974 
01975     // If not, then is this a CMYK colour?
01976     if (!Overprint && SourceCol->GetColourModel() == COLOURMODEL_CMYK)
01977     {
01978         // It is CMYK - is the "always overprint black objects" flag enabled?
01979         if (RenderView->GetPrintControl() != NULL)
01980         {
01981             TypesetInfo *TPInfo = RenderView->GetPrintControl()->GetTypesetInfo();
01982             
01983             if (TPInfo != NULL && TPInfo->AlwaysOverprintBlack())
01984             {
01985                 // It is enabled, so check if this is a CMYK colour with more than 95% Key in it.
01986                 ColourCMYK ColDef;
01987                 SourceCol->GetSourceColour((ColourGeneric *) &ColDef);
01988 
01989                 if (ColDef.Key.MakeDouble() > 0.95)     // It is "black", so we'll overprint it
01990                     Overprint = TRUE;
01991             }
01992         }
01993     }
01994 
01995     if (Overprint)
01996     {
01997         ERROR3IF(CurrentColContext->GetColourModel() != COLOURMODEL_RGBT,
01998                     "Rendering ColourContext is not RGB. Bummer");
01999 
02000         // If overprint is on, then check if the colour is visible on this plate (i.e. is it white?)
02001         PColourRGBT ColDef;
02002         CurrentColContext->ConvertColour(SourceCol, (ColourPacked *) &ColDef);
02003 
02004         if (ColDef.Red > 254 && ColDef.Green > 254 && ColDef.Blue > 254)
02005         {
02006             DocColour NewCol(COLOUR_TRANS);     // It shouldn't appear on this plate, so return no-colour
02007 
02008             StrokeColourAttribute *NewAttr = new StrokeColourAttribute(NewCol);
02009             return(NewAttr);
02010         }
02011     }
02012 
02013     // No special effects apply - tell the caller to use the original
02014     return(NULL);
02015 }
02016 
02017 
02018 
02019 /********************************************************************************************
02020 
02021 >   ColourFillAttribute *RenderRegion::PrepareFillGeometry(ColourFillAttribute *SourceAttr)
02022 
02023     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02024     Created:    30/7/96
02025 
02026     Inputs:     SourceAttr -    NULL (to copy the current rendering fill attribute),
02027                                 or the attribute to be "prepared".
02028 
02029     Returns:    NULL if the given attribute needs not be changed before it is stacked, or
02030                 points to a new attribute which should be stacked in place of the given one.
02031                 Note that it is up to the caller to delete the new attribute (so when
02032                 stacking it, you should set the "Temp" flag)
02033 
02034     Purpose:    This function is used to allow 3 special attributes to function correctly.
02035                 => Overprint line, Overprint fill, and Print on all plates.
02036 
02037                 These attributes are specil in that they act as modifiers to the current
02038                 stroke and fill attributes - they convert active colours into either
02039                 no-colour, or a special greyscale value.
02040 
02041                 This is achieved by the following 2 steps:
02042                 (1) Whenever a colour attribute is stacked, it is possibly replaced by a
02043                     copy which has been modified with respect to the current states of the 3
02044                     Imagesetting attributes.
02045                 (2) Whenever an Imagesetting attribute is stacked, the current line and/or
02046                     fill attributes are copied (if necessary) in order to "apply" the new
02047                     attribute effects to the current rendering colours.
02048 
02049                 This function takes the appropriate attribute and determines if it needs
02050                 to be changed. If it does, a new, replacement, attribute is created and
02051                 returned, which the caller should use in place of the 
02052 
02053     Notes:      This function has one other purpose: It fixes bogus graduated fills.
02054                 A no-colour to no-colour grad fill is (strangely) rendered as a solid
02055                 black fill, so this methid will convert these silly attributes into flat
02056                 no-colour fills.
02057     
02058     SeeAlso:    RenderRegion::SetFillGeometry; RenderRegion::SetLineColour
02059 
02060 ********************************************************************************************/
02061 
02062 ColourFillAttribute *RenderRegion::PrepareFillGeometry(ColourFillAttribute *SourceAttr)
02063 {
02064     // --- Make sure we've got a source attribute to play with
02065     if (SourceAttr == NULL)     // No provided attribute, so use the current fill attr
02066         SourceAttr = (ColourFillAttribute *) CurrentAttrs[ATTR_FILLGEOMETRY].pAttr;
02067 
02068     if (SourceAttr == NULL)     // No attribute to modify
02069         return(NULL);
02070 
02071     // --- Find the source colours.
02072     DocColour *StartCol = SourceAttr->GetStartColour();
02073     if (StartCol == NULL)                                   // Bitmap fills may be NULL - we leave them be
02074         return(NULL);
02075 
02076     DocColour *EndCol   = SourceAttr->GetEndColour();       // Note: May be NULL if it's a flat fill
02077 
02078     ColourFillAttribute *NewAttr = NULL;
02079 
02080 
02081     // --- Check for bogus grad fills
02082     // A no-colour to no-colour grad fill renders as solid black, so we always convert this
02083     // into a simple no-colour flat fill
02084     if (EndCol != NULL && StartCol->IsTransparent() && EndCol->IsTransparent())
02085     {
02086         NewAttr = new FlatFillAttribute(*StartCol);
02087         return(NewAttr);
02088     }
02089 
02090     // --- Check for bitmap fills
02091     // We can't change the colours for PrintOnAllPlates because when printing these are rendered to
02092     // a masked render region, and then get colour-separated (doh!)
02093     // We can't render bitmaps with overprint, as we can't do a "transparent" colour in an
02094     // arbitrarily transformed bitmap
02095 //  if (SourceAttr->IsKindOf(CC_RUNTIME_CLASS(BitmapFillAttribute)))
02096     if (SourceAttr->IsAKindOfBitmapFill())
02097         return(NULL);
02098 
02099     // --- Check for the PrintOnAllPlates attribute
02100     if ( ((PrintOnAllPlatesAttrValue *) CurrentAttrs[ATTR_PRINTONALLPLATES].pAttr)->IsPrintOnAllPlatesOn() )
02101     {
02102         BOOL HaveNewStartCol = FALSE;
02103         BOOL HaveNewEndCol   = FALSE;
02104 
02105         DocColour NewStartCol;
02106         DocColour NewEndCol;
02107 
02108         // Get a global default CMYK colour context
02109         ColourContextGreyT *cc = (ColourContextGreyT *) ColourManager::GetColourContext(COLOURMODEL_GREYT);
02110         ERROR3IF(cc == NULL, "No default Greyscale colour context?!");
02111 
02112         BOOL bNegate = FALSE;
02113         ColourPlateType Plate = COLOURPLATE_KEY;
02114         if (RenderView && RenderView->GetColourPlate())
02115         {
02116             bNegate = RenderView->GetColourPlate()->IsNegative();
02117             if (!RenderView->GetColourPlate()->IsMonochrome())
02118                 Plate = RenderView->GetColourPlate()->GetType();
02119         }
02120 
02121         // Apply POAP to the start colour, if the colour will be affected
02122         if (!StartCol->IsTransparent() && StartCol->IsSeparable())
02123         {
02124             // The print on all plates attribute is set, so we convert this into a pre-separated
02125             // Key greyscale DocColour, overriding overprint etc. First get it as a greyscale:
02126             PColourGreyT GreyDef;
02127             cc->ConvertColour(StartCol, (ColourPacked *) &GreyDef);
02128 
02129             // Then create a new CMYK colour with the grey-level in the required component
02130             PColourCMYK ColDef = {0, 0, 0, 0};
02131             BYTE InkVal = bNegate ? GreyDef.Intensity : 255 - GreyDef.Intensity;
02132             switch (Plate)
02133             {
02134             case COLOURPLATE_CYAN:
02135                 ColDef.Cyan = InkVal;
02136                 break;
02137             case COLOURPLATE_MAGENTA:
02138                 ColDef.Magenta = InkVal;
02139                 break;
02140             case COLOURPLATE_YELLOW:
02141                 ColDef.Yellow = InkVal;
02142                 break;
02143             default:
02144                 // This handles normal and composite as well as mono, key and spot plates
02145                 ColDef.Key = InkVal;
02146                 break;
02147             }
02148 
02149             NewStartCol.SetCMYKValue(&ColDef);  // Set the new start colour to the CMYK value
02150             NewStartCol.SetSeparable(FALSE);    // And set it non-separable
02151 
02152             HaveNewStartCol = TRUE;             // Flag the fact that it's changed
02153         }
02154 
02155         // Apply POAP to the end colour (if any), if the colour will be affected
02156         if (EndCol != NULL && !EndCol->IsTransparent() && EndCol->IsSeparable())
02157         {
02158             // The print on all plates attribute is set, so we convert this into a pre-separated
02159             // Key greyscale DocColour, overriding overprint etc. First get it as a greyscale:
02160             PColourGreyT GreyDef;
02161             cc->ConvertColour(EndCol, (ColourPacked *) &GreyDef);
02162 
02163             // Then create a new CMYK colour with the grey-level in the required component
02164             PColourCMYK ColDef = {0, 0, 0, 0};
02165             BYTE InkVal = bNegate ? GreyDef.Intensity : 255 - GreyDef.Intensity;
02166             switch (Plate)
02167             {
02168             case COLOURPLATE_CYAN:
02169                 ColDef.Cyan = InkVal;
02170                 break;
02171             case COLOURPLATE_MAGENTA:
02172                 ColDef.Magenta = InkVal;
02173                 break;
02174             case COLOURPLATE_YELLOW:
02175                 ColDef.Yellow = InkVal;
02176                 break;
02177             default:
02178                 // This handles normal and composite as well as mono, key and spot plates
02179                 ColDef.Key = InkVal;
02180                 break;
02181             }
02182 
02183             NewEndCol.SetCMYKValue(&ColDef);    // Set the new start colour to the CMYK value
02184             NewEndCol.SetSeparable(FALSE);      // And set it non-separable
02185 
02186             HaveNewEndCol = TRUE;               // Flag the fact that it's changed
02187         }
02188 
02189         // Have we changed either colour? If so, create a new attribute and return it
02190         if (HaveNewStartCol || HaveNewEndCol)
02191         {
02192             if (EndCol == NULL)
02193             {
02194                 // It was a flat fill, so create a new flat fill attribute
02195                 NewAttr = new FlatFillAttribute(NewStartCol);
02196             }
02197             else
02198             {
02199                 // Create a similar graduated fill attribute with the new colours
02200                 CCRuntimeClass *pCCRuntimeClass = SourceAttr->GetRuntimeClass();
02201                 NewAttr = (ColourFillAttribute *) pCCRuntimeClass->CreateObject();
02202 
02203                 if (NewAttr != NULL)
02204                 {
02205                     // Copy the details of the source attribute
02206                     NewAttr->SimpleCopy(SourceAttr);
02207 
02208                     // Set up the attribute, replacing the colours we've decided to change
02209                     if (HaveNewStartCol)
02210                         NewAttr->SetStartColour(&NewStartCol);
02211 
02212                     if (HaveNewEndCol)
02213                         NewAttr->SetEndColour(&NewEndCol);
02214                 }
02215             }
02216 
02217             return(NewAttr);
02218         }
02219     }
02220 
02221 
02222     // --- Check for a valid ColourPlate - if there is none, then no more effects will apply
02223     ERROR3IF(CurrentColContext == NULL, "No colour context when rendering?!");
02224     ColourPlate *ColPlate = CurrentColContext->GetColourPlate();
02225 
02226     if (ColPlate == NULL || ColPlate->IsDisabled())
02227         return(NULL);
02228 
02229 
02230     // --- Check for overprint
02231     // Is this entire colour plate set to overprint?
02232     BOOL Overprint = CurrentColContext->GetColourPlate()->Overprints();
02233 
02234     // If not, then is there a current "overprint fill" attribute in effect?
02235     if (!Overprint)
02236         Overprint = ((OverprintFillAttrValue *) CurrentAttrs[ATTR_OVERPRINTFILL].pAttr)->IsOverprintOn();
02237 
02238     // If not, then is this a "black" CMYK colour/fill?
02239     // We check if "Always Overprint Black" is enabled, and if the fill is a flat "black" fill, or
02240     // a grad fill between two "black" colours - but the checks are in a special order to try to
02241     // make the code as efficient as possible.
02242     if (!Overprint && StartCol->GetColourModel() == COLOURMODEL_CMYK && !StartCol->IsTransparent())
02243     {
02244         // How about the end colour? If it's a flat fill (no end col), or the end col is also CMYK, we continue
02245         if ( EndCol == NULL || (EndCol->GetColourModel() == COLOURMODEL_CMYK && !EndCol->IsTransparent()) )
02246         {
02247             // Both colours are potentially "black" - is the "always overprint black objects" flag enabled?
02248             if (RenderView->GetPrintControl() != NULL)
02249             {
02250                 TypesetInfo *TPInfo = RenderView->GetPrintControl()->GetTypesetInfo();
02251                 
02252                 if (TPInfo != NULL && TPInfo->AlwaysOverprintBlack())
02253                 {
02254                     // It is enabled, so check if this is a CMYK colour with more than 95% Key in it.
02255                     ColourCMYK ColDef;
02256                     StartCol->GetSourceColour((ColourGeneric *) &ColDef);
02257 
02258                     if (ColDef.Key.MakeDouble() > 0.95)     // It is "black", so we'll overprint it
02259                     {
02260                         if (EndCol == NULL)
02261                             Overprint = TRUE;               // Flat "black" fill, so overprint it
02262                         else
02263                         {
02264                             // The start colour is "black", but is the End colour "black" too?
02265                             EndCol->GetSourceColour((ColourGeneric *) &ColDef);
02266 
02267                             if (ColDef.Key.MakeDouble() > 0.95)     // Both cols are "black" so we'll overprint
02268                                 Overprint = TRUE;
02269                         }
02270                     }
02271                 }
02272             }
02273         }
02274     }
02275 
02276     if (Overprint)
02277     {
02278         ERROR3IF(CurrentColContext->GetColourModel() != COLOURMODEL_RGBT,
02279                     "Rendering ColourContext is not RGB. Bummer");
02280 
02281         // If overprint is on, then check if the colour is visible on this plate (i.e. is it white?)
02282         PColourRGBT ColDef;
02283 
02284         // Check the start colour. If it's white, we'll set it to no-colour (note: the default is to be
02285         // no-colour, so we only have to flag the fact that we want to change it here)
02286         BOOL UseTransStart = FALSE;
02287         if (!StartCol->IsTransparent() && StartCol->IsSeparable())
02288         {
02289             CurrentColContext->ConvertColour(StartCol, (ColourPacked *) &ColDef);
02290             UseTransStart = (ColDef.Red > 254 && ColDef.Green > 254 && ColDef.Blue > 254);
02291         }
02292 
02293         // Check the end colour - same as the start col, except that it may be NULL if it's a flat fill
02294         BOOL UseTransEnd = FALSE;
02295         if (EndCol != NULL && !EndCol->IsTransparent() && EndCol->IsSeparable())
02296         {
02297             CurrentColContext->ConvertColour(EndCol, (ColourPacked *) &ColDef);
02298             UseTransEnd = (ColDef.Red > 254 && ColDef.Green > 254 && ColDef.Blue > 254);
02299         }
02300 
02301         if (UseTransStart || UseTransEnd)       // If we must change either end to transparent...
02302         {
02303             if (EndCol == NULL ||                                       // If it's a flat fill, or
02304                     ((UseTransStart || StartCol->IsTransparent()) &&    // the start and end are both
02305                      (UseTransEnd   || EndCol->IsTransparent()))        // no-colour, make a flat fill
02306                 )
02307             {
02308                 // Make a flat fill
02309                 // (NOTE: this convert-to-flat-fill is necessary for the no-colour to no-colour grad fills
02310                 // that overprint can create, as they otherwise (helpfully) render as a black solid fill
02311                 // rather than the expected no-fill, while a no-colour flat fill works properly)
02312                 DocColour Trans(COLOUR_TRANS);
02313                 NewAttr = new FlatFillAttribute((UseTransStart) ? Trans : *StartCol);
02314                 return(NewAttr);
02315             }
02316 
02317             // NOTE:
02318             // We don't change the fill if it will remain graduated, because a grad fill from a colour
02319             // to no-colour will not make the fill go transparent for overprint, so we might as well
02320             // just leave it alone - i.e. the only case we care about is when the grad fill ends
02321             // up as ultimately a transparent-transparent fill after colour separation.
02322         }
02323     }
02324 
02325     // No special effects apply - tell the caller to use the original
02326     return(NULL);
02327 }
02328 
02329 
02330 
02331 /********************************************************************************************
02332 
02333 >   virtual void RenderRegion::SetLineOverprint(OverprintLineAttrValue *NewAttr, BOOL Temp);
02334 
02335     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02336     Created:    30/7/96
02337 
02338     Inputs:     NewAttr - The new OverPrintLineAttrValue you want to set current
02339                 Temp -  TRUE if this is a temporary object which the render region should
02340                         delete when finished with it;
02341                         FALSE if someone else will delete it (i.e. it's in the document tree)
02342 
02343     Purpose:    Set the line overprint state, pushing the current "overprint line" attribute
02344                 onto the context stack.
02345 
02346     SeeAlso:    RenderRegion::RestoreOverprintLine
02347 
02348 ********************************************************************************************/
02349 
02350 void RenderRegion::SetLineOverprint(OverprintLineAttrValue *NewAttr, BOOL Temp)
02351 {
02352     // Set the new Overprint state
02353     SaveAttribute(ATTR_OVERPRINTLINE, NewAttr, Temp);
02354 
02355     // And make sure the current line colour attribute is affected by the new overprint state
02356     StrokeColourAttribute *NewLineCol = PrepareLineColour();
02357     if (NewLineCol != NULL)
02358         SetLineColour(NewLineCol, TRUE);
02359 }
02360 
02361 
02362 
02363 /********************************************************************************************
02364 
02365 >   virtual void RenderRegion::RestoreLineOverprint(OverprintLineAttrValue *NewAttr, BOOL Temp)
02366 
02367     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02368     Created:    30/7/96
02369 
02370     Inputs:     NewAttr - The new OverPrintLineAttrValue you want to set current
02371                 Temp -  TRUE if this is a temporary object which the render region should
02372                         delete when finished with it;
02373                         FALSE if someone else will delete it (i.e. it's in the document tree)
02374 
02375     Purpose:    Restore the previous Line Overprint state, popping the previous state from
02376                 the rendering stack
02377 
02378     SeeAlso:    RenderRegion::SetOverprintLine
02379 
02380 ********************************************************************************************/
02381 
02382 void RenderRegion::RestoreLineOverprint(OverprintLineAttrValue *NewAttr, BOOL Temp)
02383 {
02384     RestoreAttribute(ATTR_OVERPRINTLINE, NewAttr, Temp);
02385 }
02386 
02387 
02388 
02389 /********************************************************************************************
02390 
02391 >   virtual void RenderRegion::SetFillOverprint(OverprintFillAttrValue *NewAttr, BOOL Temp)
02392 
02393     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02394     Created:    30/7/96
02395 
02396     Inputs:     NewAttr - The new OverPrintFillAttrValue you want to set current
02397                 Temp -  TRUE if this is a temporary object which the render region should
02398                         delete when finished with it;
02399                         FALSE if someone else will delete it (i.e. it's in the document tree)
02400 
02401     Purpose:    Set the fill overprint state, pushing the current "overprint fill" attribute
02402                 onto the context stack.
02403 
02404     SeeAlso:    RenderRegion::RestoreOverprintFill
02405 
02406 ********************************************************************************************/
02407 
02408 void RenderRegion::SetFillOverprint(OverprintFillAttrValue *NewAttr, BOOL Temp)
02409 {
02410     // Set the new Overprint state
02411     SaveAttribute(ATTR_OVERPRINTFILL, NewAttr, Temp);
02412 
02413     // And make sure the current fill colour attribute is affected by the new overprint state
02414     ColourFillAttribute *NewFillGeometry = PrepareFillGeometry();
02415     if (NewFillGeometry != NULL)
02416         SetFillGeometry(NewFillGeometry, TRUE);
02417 }
02418 
02419 
02420 
02421 /********************************************************************************************
02422 
02423 >   virtual void RenderRegion::RestoreFillOverprint(OverprintFillAttrValue *NewAttr, BOOL Temp)
02424 
02425     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02426     Created:    30/7/96
02427 
02428     Inputs:     NewAttr - The new OverPrintLineAttrValue you want to set current
02429                 Temp -  TRUE if this is a temporary object which the render region should
02430                         delete when finished with it;
02431                         FALSE if someone else will delete it (i.e. it's in the document tree)
02432 
02433     Purpose:    Restore the previous Fill Overprint state, popping the previous state from
02434                 the rendering stack
02435 
02436     SeeAlso:    RenderRegion::SetOverprintLine
02437 
02438 ********************************************************************************************/
02439 
02440 void RenderRegion::RestoreFillOverprint(OverprintFillAttrValue *NewAttr, BOOL Temp)
02441 {
02442     RestoreAttribute(ATTR_OVERPRINTFILL, NewAttr, Temp);
02443 }
02444 
02445 
02446 
02447 /********************************************************************************************
02448 
02449 >   virtual void RenderRegion::SetPrintOnAllPlates(PrintOnAllPlatesAttrValue *NewAttr, BOOL Temp);
02450 
02451     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02452     Created:    30/7/96
02453 
02454     Inputs:     NewAttr - The new PrintOnAllPlatesAttrValue you want to set current
02455                 Temp -  TRUE if this is a temporary object which the render region should
02456                         delete when finished with it;
02457                         FALSE if someone else will delete it (i.e. it's in the document tree)
02458 
02459     Purpose:    Set the PrintOnAllPlates state, pushing the current "print on all plates" attribute
02460                 onto the context stack.
02461 
02462     SeeAlso:    RenderRegion::RestorePrintOnAllPlates
02463 
02464 ********************************************************************************************/
02465 
02466 void RenderRegion::SetPrintOnAllPlates(PrintOnAllPlatesAttrValue *NewAttr, BOOL Temp)
02467 {
02468     // Set the new Overprint state
02469     SaveAttribute(ATTR_PRINTONALLPLATES, NewAttr, Temp);
02470 
02471     // And make sure the current line colour attribute is affected by the new state
02472     StrokeColourAttribute *NewLineCol = PrepareLineColour();
02473     if (NewLineCol != NULL)
02474         SetLineColour(NewLineCol, TRUE);
02475 
02476     // And make sure the current fill colour attribute is affected by the new state
02477     ColourFillAttribute *NewFillGeometry = PrepareFillGeometry();
02478     if (NewFillGeometry != NULL)
02479         SetFillGeometry(NewFillGeometry, TRUE);
02480 }
02481 
02482 
02483 
02484 /********************************************************************************************
02485 
02486 >   virtual void RenderRegion::RestorePrintOnAllPlates(PrintOnAllPlatesAttrValue *NewAttr, BOOL Temp)
02487 
02488     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02489     Created:    30/7/96
02490 
02491     Inputs:     NewAttr - The new OverPrintLineAttrValue you want to set current
02492                 Temp -  TRUE if this is a temporary object which the render region should
02493                         delete when finished with it;
02494                         FALSE if someone else will delete it (i.e. it's in the document tree)
02495 
02496     Purpose:    Restore the previous print-on-all-plates state, popping the previous state from
02497                 the rendering stack
02498 
02499     SeeAlso:    RenderRegion::SetOverprintLine
02500 
02501 ********************************************************************************************/
02502 
02503 void RenderRegion::RestorePrintOnAllPlates(PrintOnAllPlatesAttrValue *NewAttr, BOOL Temp)
02504 {
02505     RestoreAttribute(ATTR_PRINTONALLPLATES, NewAttr, Temp);
02506 }
02507 
02508 
02509 
02510 /********************************************************************************************
02511 
02512 >   void RenderRegion::SetLineColour(DocColour &NewLineColour)
02513 
02514     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
02515     Created:    12/04/94
02516     Inputs:     NewLineColour - the colour to set the line colour to.
02517     Purpose:    Set the line colour to a specific colour, pushing the current line colour 
02518                 onto the context stack.
02519     SeeAlso:    RenderRegion::RestoreLineColour
02520 
02521 ********************************************************************************************/
02522 
02523 void RenderRegion::SetLineColour(DocColour &NewLineColour)
02524 {
02525     // Don't bother if it doesn't cause a change
02526     StrokeColourAttribute *pAttr = (StrokeColourAttribute *) CurrentAttrs[ATTR_STROKECOLOUR].pAttr;
02527     if ((pAttr != NULL) && (NewLineColour == pAttr->Colour))
02528         return;
02529 
02530     // Create a temporary attribute and use it to set the line colour.
02531     pAttr = new StrokeColourAttribute(NewLineColour);
02532     SetLineColour(pAttr, TRUE);
02533 }
02534 
02535 
02536 
02537 /********************************************************************************************
02538 
02539 >   void RenderRegion::SetLineColour(StockColour NewLineColour)
02540 
02541     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
02542     Created:    12/04/94
02543     Inputs:     NewLineColour - the colour to set the line colour to.
02544     Purpose:    Set the line colour to a specific colour, pushing the current line colour 
02545                 onto the context stack.
02546     SeeAlso:    RenderRegion::RestoreLineColour
02547 
02548 ********************************************************************************************/
02549 
02550 void RenderRegion::SetLineColour(StockColour New)
02551 {
02552     DocColour NewLineColour(New);
02553 
02554     // Don't bother if it doesn't cause a change
02555     StrokeColourAttribute *pAttr = (StrokeColourAttribute *) CurrentAttrs[ATTR_STROKECOLOUR].pAttr;
02556     if ((pAttr != NULL) && (NewLineColour == pAttr->Colour))
02557         return;
02558 
02559     // Create a temporary attribute and use it to set the line colour.
02560     pAttr = new StrokeColourAttribute(NewLineColour);
02561     SetLineColour(pAttr, TRUE);
02562 }
02563 
02564 
02565 
02566 /********************************************************************************************
02567 
02568 >   void RenderRegion::SetLineColour(StrokeColourAttribute *pAttr, BOOL Temp)
02569 
02570     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
02571     Created:    12/04/94
02572     Inputs:     pAttr - the object specifying the colour to use.
02573                 Tmp - indicates if pAttr points to a temporary attribute that should be
02574                       deleted when it's finished with.
02575     Purpose:    Set the current line colour according to an AttributeValue object, pushing
02576                 the current line colour onto the context stack.
02577     SeeAlso:    RenderRegion::RestoreLineColour
02578 
02579 ********************************************************************************************/
02580 
02581 void RenderRegion::SetLineColour(StrokeColourAttribute *pAttr, BOOL Temp)
02582 {
02583     // Before stacking the attribute, check for overprint and print on all plates - these
02584     // may cause the line colour to change, in which case we replace the given attribute
02585     // with a new modified one.
02586     StrokeColourAttribute *NewAttr = PrepareLineColour(pAttr);
02587 
02588     if (NewAttr != NULL)
02589     {
02590         if (Temp)
02591             delete pAttr;
02592 
02593         pAttr = NewAttr;        // Use the modified attribute
02594         Temp = TRUE;            // ...which is always temporary
02595     }
02596 
02597     // Save the current attribute and set up the new one
02598     if (SaveAttribute(ATTR_STROKECOLOUR, pAttr, Temp))
02599     {
02600         // The line attributes need to be reset before drawing anything.
02601         SetLineAttributes(CHANGEATTR_STROKECOL);
02602     }
02603 }
02604 
02605 /********************************************************************************************
02606 
02607 >   void RenderRegion::RestoreLineColour(StrokeColourAttribute *pAttr, BOOL Temp)
02608 
02609     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
02610     Created:    12/04/94
02611     Inputs:     pAttr - the object specifying the colour to use.
02612                 Tmp - indicates if pAttr points to a temporary attribute that should be
02613                       deleted when it's finished with.
02614     Purpose:    Get rid of the current line colour, and restore the specified line
02615                 colour value.
02616     SeeAlso:    RenderRegion::SetLineColour
02617 
02618 ********************************************************************************************/
02619 
02620 void RenderRegion::RestoreLineColour(StrokeColourAttribute *pAttr, BOOL Temp)
02621 {
02622     // Restore the line colour attribute
02623     RestoreAttribute(ATTR_STROKECOLOUR, pAttr, Temp);
02624 
02625     // The line attributes need to be reset before drawing anything.
02626     SetLineAttributes(CHANGEATTR_STROKECOL);
02627 }
02628 
02629 /********************************************************************************************
02630 
02631 >   void RenderRegion::SetLineTransp(StrokeTranspAttribute *pAttr, BOOL Temp)
02632 
02633     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02634     Created:    30/11/94
02635     Inputs:     pAttr - the object specifying the colour to use.
02636                 Tmp - indicates if pAttr points to a temporary attribute that should be
02637                       deleted when it's finished with.
02638     Purpose:    Set the current line colour according to an AttributeValue object, pushing
02639                 the current line colour onto the context stack.
02640     SeeAlso:    RenderRegion::RestoreLineColour
02641 
02642 ********************************************************************************************/
02643 
02644 void RenderRegion::SetLineTransp(StrokeTranspAttribute *pAttr, BOOL Temp)
02645 {
02646     StrokeTranspAttribute* pNewAttr = NULL;
02647     if (m_bForceMix)
02648     {
02649         UINT32 Type = pAttr->GetTranspType();
02650         if (Type != TT_NoTranspType &&
02651             Type != TT_Mix &&
02652             Type != TT_DARKEN &&
02653             Type != TT_LIGHTEN &&
02654             Type != TT_BRIGHTNESS &&
02655             Type != TT_BEVEL)
02656         {
02657             if (Temp)
02658             {
02659                 pNewAttr = pAttr;
02660             }
02661             else
02662             {
02663                 pNewAttr = (StrokeTranspAttribute*)(pAttr->GetRuntimeClass()->CreateObject());
02664                 if (pNewAttr)
02665                 {
02666                     pNewAttr->SimpleCopy(pAttr);
02667                 }
02668             }
02669 
02670         }
02671     }
02672 
02673     if (pNewAttr)
02674     {
02675         pNewAttr->SetTranspType(TT_Mix);
02676         Temp = TRUE;
02677     }
02678     else
02679         pNewAttr = pAttr;
02680 
02681     // Save the current attribute and set up the new one
02682     if (SaveAttribute(ATTR_STROKETRANSP, pNewAttr, Temp))
02683     {
02684         // The line attributes need to be reset before drawing anything.
02685         SetLineAttributes(CHANGEATTR_STROKETRANSP);
02686     }
02687 }
02688 
02689 /********************************************************************************************
02690 
02691 >   void RenderRegion::RestoreLineTransp(StrokeTranspAttribute *pAttr, BOOL Temp)
02692 
02693     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
02694     Created:    12/04/94
02695     Inputs:     pAttr - the object specifying the colour to use.
02696                 Tmp - indicates if pAttr points to a temporary attribute that should be
02697                       deleted when it's finished with.
02698     Purpose:    Get rid of the current line colour, and restore the specified line
02699                 colour value.
02700     SeeAlso:    RenderRegion::SetLineColour
02701 
02702 ********************************************************************************************/
02703 
02704 void RenderRegion::RestoreLineTransp(StrokeTranspAttribute *pAttr, BOOL Temp)
02705 {
02706     // Restore the line colour attribute
02707     RestoreAttribute(ATTR_STROKETRANSP, pAttr, Temp);
02708 
02709     // The line attributes need to be reset before drawing anything.
02710     SetLineAttributes(CHANGEATTR_STROKETRANSP);
02711 }
02712 
02713 
02714 
02715 /********************************************************************************************
02716 
02717 >   virtual void RenderRegion::SetStrokeType(StrokeTypeAttrValue *pAttr, BOOL Temp)
02718 
02719     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02720     Created:    7/1/97
02721 
02722     Inputs:     pAttr   - the object specifying the colour to use.
02723                 Temp    - indicates if pAttr points to a temporary attribute that
02724                           should be deleted when it's finished with.
02725 
02726     Purpose:    Set the current Stroke Type according to an AttributeValue object, pushing
02727                 the current Stroke Type onto the context stack.
02728 
02729     SeeAlso:    RenderRegion::RestoreStrokeType
02730 
02731 ********************************************************************************************/
02732 
02733 void RenderRegion::SetStrokeType(StrokeTypeAttrValue *pAttr, BOOL Temp)
02734 {
02735     SaveAttribute(ATTR_STROKETYPE, pAttr, Temp);
02736 }
02737 
02738 
02739 
02740 /********************************************************************************************
02741 
02742 >   virtual void RenderRegion::RestoreStrokeType(StrokeTypeAttrValue *pAttr, BOOL Temp)
02743 
02744     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02745     Created:    7/1/97
02746 
02747     Inputs:     pAttr   - the object specifying the new stroke type
02748                 Temp    - indicates if pAttr points to a temporary attribute that
02749                           should be deleted when it's finished with.
02750 
02751     Purpose:    Get rid of the current stroke type, and restore the specified stroke type
02752 
02753     SeeAlso:    RenderRegion::SetStrokeType
02754 
02755 ********************************************************************************************/
02756 
02757 void RenderRegion::RestoreStrokeType(StrokeTypeAttrValue *pAttr, BOOL Temp)
02758 {
02759     RestoreAttribute(ATTR_STROKETYPE, pAttr, Temp);
02760 }
02761 
02762 
02763 
02764 /********************************************************************************************
02765 
02766 >   virtual void RenderRegion::SetVariableWidth(VariableWidthAttrValue *pAttr, BOOL Temp)
02767 
02768     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02769     Created:    7/1/97
02770 
02771     Inputs:     pAttr   - the object specifying the colour to use.
02772                 Temp    - indicates if pAttr points to a temporary attribute that
02773                           should be deleted when it's finished with.
02774 
02775     Purpose:    Set the current VariableWidth according to an AttributeValue object, pushing
02776                 the current VariableWidth onto the context stack.
02777 
02778     SeeAlso:    RenderRegion::RestoreVariableWidth
02779 
02780 ********************************************************************************************/
02781 
02782 void RenderRegion::SetVariableWidth(VariableWidthAttrValue *pAttr, BOOL Temp)
02783 {
02784     SaveAttribute(ATTR_VARWIDTH, pAttr, Temp);
02785 }
02786 
02787 
02788 
02789 /********************************************************************************************
02790 
02791 >   virtual void RenderRegion::RestoreVariableWidth(VariableWidthAttrValue *pAttr, BOOL Temp)
02792 
02793     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02794     Created:    7/1/97
02795 
02796     Inputs:     pAttr   - the object specifying the new stroke type
02797                 Temp    - indicates if pAttr points to a temporary attribute that
02798                           should be deleted when it's finished with.
02799 
02800     Purpose:    Get rid of the current VariableWidth, and restore the specified VariableWidth
02801 
02802     SeeAlso:    RenderRegion::SetVariableWidth
02803 
02804 ********************************************************************************************/
02805 
02806 void RenderRegion::RestoreVariableWidth(VariableWidthAttrValue *pAttr, BOOL Temp)
02807 {
02808     RestoreAttribute(ATTR_VARWIDTH, pAttr, Temp);
02809 }
02810 
02811 
02812 
02813 /********************************************************************************************
02814 
02815 >   void RenderRegion::SetFillColour(DocColour &NewFillColour)
02816 
02817     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
02818     Created:    12/04/94
02819     Inputs:     NewFillColour - the colour to set the fill colour to.
02820     Purpose:    Set the fill colour to a specific colour, pushing the current fill colour 
02821                 onto the context stack.
02822     SeeAlso:    RenderRegion::RestoreFillColour
02823 
02824 ********************************************************************************************/
02825 
02826 void RenderRegion::SetFillColour(DocColour &NewFillColour)
02827 {
02828     // Don't bother if it doesn't cause a change
02829     ColourFillAttribute *pAttr = 
02830         (ColourFillAttribute *) CurrentAttrs[ATTR_FILLGEOMETRY].pAttr;
02831 
02832     if ((pAttr != NULL) && 
02833         (pAttr->GetRuntimeClass() == CC_RUNTIME_CLASS(FlatFillAttribute)) &&
02834         (NewFillColour == ((FlatFillAttribute *) pAttr)->Colour))
02835         return;
02836 
02837     // Create a temporary attribute and use it to set the line colour.
02838     pAttr = new FlatFillAttribute(NewFillColour);
02839     SetFillGeometry(pAttr, TRUE);
02840 }
02841 
02842 
02843 /********************************************************************************************
02844 
02845 >   void RenderRegion::SetFillColour(StockColour NewFillColour)
02846 
02847     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
02848     Created:    12/04/94
02849     Inputs:     NewFillColour - the colour to set the fill colour to.
02850     Purpose:    Set the fill colour to a specific colour, pushing the current fill colour 
02851                 onto the context stack.
02852     SeeAlso:    RenderRegion::RestoreFillColour
02853 
02854 ********************************************************************************************/
02855 
02856 void RenderRegion::SetFillColour(StockColour New)
02857 {
02858     DocColour NewFillColour(New);
02859 
02860     // Don't bother if it doesn't cause a change
02861     ColourFillAttribute *pAttr = 
02862         (ColourFillAttribute *) CurrentAttrs[ATTR_FILLGEOMETRY].pAttr;
02863 
02864     if ((pAttr != NULL) && 
02865         (pAttr->GetRuntimeClass() == CC_RUNTIME_CLASS(FlatFillAttribute)) &&
02866         (NewFillColour == ((FlatFillAttribute *) pAttr)->Colour))
02867         return;
02868 
02869     // Create a temporary attribute and use it to set the line colour.
02870     pAttr = new FlatFillAttribute(NewFillColour);
02871     SetFillGeometry(pAttr, TRUE);
02872 }
02873 
02874 
02875 
02876 /********************************************************************************************
02877 
02878 >   void RenderRegion::SetFillGeometry(FillGeometryAttribute *pAttr, BOOL Temp)
02879 
02880     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
02881     Created:    12/04/94
02882     Inputs:     pAttr - the object specifying the fill type to use.
02883                 Tmp - indicates if pAttr points to a temporary attribute that should be
02884                       deleted when it's finished with.
02885     Purpose:    Set the current fill type according to an AttributeValue object, pushing
02886                 the current fill type onto the context stack.
02887 
02888 
02889     SeeAlso:    RenderRegion::RestoreFillType; RenderRegion::SetFillColour
02890 
02891 ********************************************************************************************/
02892 
02893 void RenderRegion::SetFillGeometry(ColourFillAttribute *pAttr, BOOL Temp)
02894 {
02895     // Before stacking the attribute, check for overprint and print on all plates - these
02896     // may cause the fill colours to change, in which case we replace the given attribute
02897     // with a new modified one.
02898     ColourFillAttribute *NewAttr = PrepareFillGeometry(pAttr);
02899 
02900     if (NewAttr != NULL)
02901     {
02902         if (Temp)
02903             delete pAttr;
02904 
02905         pAttr = NewAttr;        // Use the modified attribute
02906         Temp = TRUE;            // ...which is always temporary
02907     }
02908 
02909     // Save the current attribute
02910     if (SaveAttribute(ATTR_FILLGEOMETRY, pAttr, Temp))
02911     {
02912         // The fill attributes need to be reset before drawing anything.
02913         SetFillAttributes(CHANGEATTR_GEOMETRY);
02914     }
02915 }
02916 
02917 /********************************************************************************************
02918 
02919 >   void RenderRegion::RestoreFillGeometry(FillAttribute *pAttr, BOOL Temp)
02920 
02921     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
02922     Created:    12/04/94
02923     Inputs:     pAttr - the object specifying the fill type to use.
02924                 Tmp - indicates if pAttr points to a temporary attribute that should be
02925                       deleted when it's finished with.
02926     Purpose:    Get rid of the current fill type, and restore the specified fill type.
02927     SeeAlso:    RenderRegion::SetFillType; RenderRegion::SetFillColour
02928 
02929 ********************************************************************************************/
02930 
02931 void RenderRegion::RestoreFillGeometry(ColourFillAttribute *pAttr, BOOL Temp)
02932 {
02933     // Set up the new attribute
02934     RestoreAttribute(ATTR_FILLGEOMETRY, pAttr, Temp);
02935 
02936     // The fill attributes need to be reset before drawing anything.
02937     SetFillAttributes(CHANGEATTR_GEOMETRY);
02938 }
02939 
02940 /********************************************************************************************
02941 
02942 >   void RenderRegion::SetFillMapping(FillMappingAttribute *pAttr, BOOL Temp)
02943 
02944     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
02945     Created:    12/04/94
02946     Inputs:     pAttr - the object specifying the fill type to use.
02947                 Tmp - indicates if pAttr points to a temporary attribute that should be
02948                       deleted when it's finished with.
02949     Purpose:    Set the current fill type according to an AttributeValue object, pushing
02950                 the current fill type onto the context stack.
02951     SeeAlso:    RenderRegion::RestoreFillType; RenderRegion::SetFillColour
02952 
02953 ********************************************************************************************/
02954 
02955 void RenderRegion::SetFillMapping(FillMappingAttribute *pAttr, BOOL Temp)
02956 {
02957     // Save the current attribute
02958     if (SaveAttribute(ATTR_FILLMAPPING, pAttr, Temp))
02959     {
02960         // The fill attributes need to be reset before drawing anything.
02961         SetFillAttributes(CHANGEATTR_MAPPING);
02962     }
02963 }
02964 
02965 
02966 
02967 /********************************************************************************************
02968 
02969 >   void RenderRegion::RestoreFillMapping(FillMappingAttribute *pAttr, BOOL Temp)
02970 
02971     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
02972     Created:    12/04/94
02973     Inputs:     pAttr - the object specifying the fill type to use.
02974                 Tmp - indicates if pAttr points to a temporary attribute that should be
02975                       deleted when it's finished with.
02976     Purpose:    Get rid of the current fill type, and restore the specified fill type.
02977     SeeAlso:    RenderRegion::SetFillType; RenderRegion::SetFillColour
02978 
02979 ********************************************************************************************/
02980 
02981 void RenderRegion::RestoreFillMapping(FillMappingAttribute *pAttr, BOOL Temp)
02982 {
02983     // Set up the new attribute
02984     RestoreAttribute(ATTR_FILLMAPPING, pAttr, Temp);
02985 
02986     // The fill attributes need to be reset before drawing anything.
02987     SetFillAttributes(CHANGEATTR_MAPPING);
02988 }
02989 
02990 
02991 
02992 /********************************************************************************************
02993 
02994 >   void RenderRegion::SetFillEffect(FillEffectAttribute *pAttr, BOOL Temp)
02995 
02996     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
02997     Created:    12/04/94
02998     Inputs:     pAttr - the object specifying the fill type to use.
02999                 Tmp - indicates if pAttr points to a temporary attribute that should be
03000                       deleted when it's finished with.
03001     Purpose:    Set the current fill type according to an AttributeValue object, pushing
03002                 the current fill type onto the context stack.
03003     SeeAlso:    RenderRegion::RestoreFillType; RenderRegion::SetFillColour
03004 
03005 ********************************************************************************************/
03006 
03007 void RenderRegion::SetFillEffect(FillEffectAttribute *pAttr, BOOL Temp)
03008 {
03009     // Save the current attribute
03010     if (SaveAttribute(ATTR_FILLEFFECT, pAttr, Temp))
03011     {
03012         // The fill attributes need to be reset before drawing anything.
03013         SetFillAttributes(CHANGEATTR_EFFECT);
03014     }
03015 }
03016 
03017 /********************************************************************************************
03018 
03019 >   void RenderRegion::RestoreFillEffect(FillEffectAttribute *pAttr, BOOL Temp)
03020 
03021     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
03022     Created:    12/04/94
03023     Inputs:     pAttr - the object specifying the fill type to use.
03024                 Tmp - indicates if pAttr points to a temporary attribute that should be
03025                       deleted when it's finished with.
03026     Purpose:    Get rid of the current fill type, and restore the specified fill type.
03027     SeeAlso:    RenderRegion::SetFillType; RenderRegion::SetFillColour
03028 
03029 ********************************************************************************************/
03030 
03031 void RenderRegion::RestoreFillEffect(FillEffectAttribute *pAttr, BOOL Temp)
03032 {
03033     // Set up the new attribute
03034     RestoreAttribute(ATTR_FILLEFFECT, pAttr, Temp);
03035 
03036     // The fill attributes need to be reset before drawing anything.
03037     SetFillAttributes(CHANGEATTR_EFFECT);
03038 }
03039 
03040 /********************************************************************************************
03041 
03042 >   void RenderRegion::SetTranspFillGeometry(TranspFillAttribute *pAttr, BOOL Temp)
03043 
03044     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03045     Created:    23/8/94
03046     Inputs:     pAttr - the object specifying the fill type to use.
03047                 Tmp - indicates if pAttr points to a temporary attribute that should be
03048                       deleted when it's finished with.
03049     Purpose:    Set the current fill type according to an AttributeValue object, pushing
03050                 the current fill type onto the context stack.
03051     SeeAlso:    RenderRegion::RestoreFillType; RenderRegion::SetFillColour
03052 
03053 ********************************************************************************************/
03054 
03055 void RenderRegion::SetTranspFillGeometry(TranspFillAttribute *pAttr, BOOL Temp)
03056 {
03057     TranspFillAttribute* pNewAttr = NULL;
03058     if (m_bForceMix)
03059     {
03060         UINT32 Type = pAttr->GetTranspType();
03061         if (Type != TT_NoTranspType &&
03062             Type != TT_Mix &&
03063             Type != TT_DARKEN &&
03064             Type != TT_LIGHTEN &&
03065             Type != TT_BRIGHTNESS &&
03066             Type != TT_BEVEL)
03067         {
03068             if (Temp)
03069             {
03070                 pNewAttr = pAttr;
03071             }
03072             else
03073             {
03074                 pNewAttr = (TranspFillAttribute*)(pAttr->GetRuntimeClass()->CreateObject());
03075                 if (pNewAttr)
03076                 {
03077                     pNewAttr->SimpleCopy(pAttr);
03078                 }
03079             }
03080 
03081         }
03082     }
03083 
03084     if (pNewAttr)
03085     {
03086         pNewAttr->SetTranspType(TT_Mix);
03087         Temp = TRUE;
03088     }
03089     else
03090         pNewAttr = pAttr;
03091 
03092     // Save the current attribute
03093     if (SaveAttribute(ATTR_TRANSPFILLGEOMETRY, pNewAttr, Temp))
03094     {
03095         // The fill attributes need to be reset before drawing anything.
03096         SetFillAttributes(CHANGEATTR_TRANSP_GEOMETRY);
03097 
03098         // The capture system needs to know about non-MIX transparencies being set
03099         // because it can't capture them in RGBT bitmaps...
03100         UINT32 ttype = pNewAttr->GetTranspType();
03101         ERROR3IF(ttype<TT_NoTranspType || ttype>TT_MAX, "Someone's trying to set an unknown transp type!");
03102 
03103 //      if (!(ttype==TT_NoTranspType || ttype==TT_Mix))
03104         if (!TranspTypeIsRGBTCompatible(ttype))
03105         {
03106             ChangeCapture(CAPTUREINFO(ctREUSE, cfCOLLAPSETOMASTER), FALSE, TRUE);
03107         }
03108     }
03109 }
03110 
03111 /********************************************************************************************
03112 
03113 >   void RenderRegion::RestoreTranspFillGeometry(FillAttribute *pAttr, BOOL Temp)
03114 
03115     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03116     Created:    23/8/94
03117     Inputs:     pAttr - the object specifying the fill type to use.
03118                 Tmp - indicates if pAttr points to a temporary attribute that should be
03119                       deleted when it's finished with.
03120     Purpose:    Get rid of the current fill type, and restore the specified fill type.
03121     SeeAlso:    RenderRegion::SetFillType; RenderRegion::SetFillColour
03122 
03123 ********************************************************************************************/
03124 
03125 void RenderRegion::RestoreTranspFillGeometry(TranspFillAttribute *pAttr, BOOL Temp)
03126 {
03127     // Set up the new attribute
03128     RestoreAttribute(ATTR_TRANSPFILLGEOMETRY, pAttr, Temp);
03129 
03130     // The fill attributes need to be reset before drawing anything.
03131     SetFillAttributes(CHANGEATTR_TRANSP_GEOMETRY);
03132 }
03133 
03134 /********************************************************************************************
03135 
03136 >   void RenderRegion::SetTranspFillMapping(TranspFillMappingAttribute *pAttr, BOOL Temp)
03137 
03138     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03139     Created:    23/8/94
03140     Inputs:     pAttr - the object specifying the fill type to use.
03141                 Tmp - indicates if pAttr points to a temporary attribute that should be
03142                       deleted when it's finished with.
03143     Purpose:    Set the current fill type according to an AttributeValue object, pushing
03144                 the current fill type onto the context stack.
03145     SeeAlso:    RenderRegion::RestoreFillType; RenderRegion::SetFillColour
03146 
03147 ********************************************************************************************/
03148 
03149 void RenderRegion::SetTranspFillMapping(TranspFillMappingAttribute *pAttr, BOOL Temp)
03150 {
03151     // Save the current attribute
03152     if (SaveAttribute(ATTR_TRANSPFILLMAPPING, pAttr, Temp))
03153     {
03154         // The fill attributes need to be reset before drawing anything.
03155         SetFillAttributes(CHANGEATTR_TRANSP_MAPPING);
03156     }
03157 }
03158 
03159 /********************************************************************************************
03160 
03161 >   void RenderRegion::RestoreTranspFillMapping(TranspFillMappingAttribute *pAttr, BOOL Temp)
03162 
03163     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03164     Created:    23/8/94
03165     Inputs:     pAttr - the object specifying the fill type to use.
03166                 Tmp - indicates if pAttr points to a temporary attribute that should be
03167                       deleted when it's finished with.
03168     Purpose:    Get rid of the current fill type, and restore the specified fill type.
03169     SeeAlso:    RenderRegion::SetFillType; RenderRegion::SetFillColour
03170 
03171 ********************************************************************************************/
03172 
03173 void RenderRegion::RestoreTranspFillMapping(TranspFillMappingAttribute *pAttr, BOOL Temp)
03174 {
03175     // Set up the new attribute
03176     RestoreAttribute(ATTR_TRANSPFILLMAPPING, pAttr, Temp);
03177 
03178     // The fill attributes need to be reset before drawing anything.
03179     SetFillAttributes(CHANGEATTR_TRANSP_MAPPING);
03180 }
03181 
03182 /********************************************************************************************
03183 
03184 >   void RenderRegion::SetLineWidth(MILLIPOINT NewLineWidth)
03185 
03186     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
03187     Created:    12/04/94
03188     Inputs:     NewLineWidth - the size to set the line width to.
03189     Purpose:    Set the line width to a specific size, pushing the current line width 
03190                 onto the context stack.
03191     SeeAlso:    RenderRegion::RestoreLineColour
03192 
03193 ********************************************************************************************/
03194 
03195 void RenderRegion::SetLineWidth(MILLIPOINT NewLineWidth)
03196 {
03197     // Don't bother if it doesn't cause a change
03198     LineWidthAttribute *pAttr = (LineWidthAttribute *) CurrentAttrs[ATTR_LINEWIDTH].pAttr;
03199     if ((pAttr != NULL) && (NewLineWidth == pAttr->LineWidth))
03200         return;
03201 
03202     // Create a temporary attribute and use it to set the line colour.
03203     pAttr = new LineWidthAttribute(NewLineWidth);
03204     SetLineWidth(pAttr, TRUE);
03205 }
03206 
03207 /********************************************************************************************
03208 
03209 >   void RenderRegion::SetLineWidth(LineWidthAttribute *pAttr,BOOL Temp)
03210 
03211     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
03212     Created:    12/04/94
03213     Inputs:     pAttr - the object specifying the line width to use.
03214                 Tmp - indicates if pAttr points to a temporary attribute that should be
03215                       deleted when it's finished with.
03216     Purpose:    Set the current line width according to an AttributeValue object, pushing
03217                 the current linewidth onto the context stack.
03218     SeeAlso:    RenderRegion::RestoreLineWidth
03219 
03220 ********************************************************************************************/
03221 
03222 void RenderRegion::SetLineWidth(LineWidthAttribute *pAttr,BOOL Temp)
03223 {
03224     // Set up the new attribute
03225     if (SaveAttribute(ATTR_LINEWIDTH, pAttr, Temp))
03226     {
03227         // The line attributes need to be reset before drawing anything.
03228         SetLineAttributes(CHANGEATTR_LINEWIDTH);
03229 
03230         // NB We need to invalidate the dash pattern too as this depends
03231         //    on line width (doesn't seem to matter normally, but PostScript
03232         //    gets dash patterns wrong otherwise.
03233         SetLineAttributes(CHANGEATTR_DASHPATTERN);
03234     }
03235 }
03236 
03237 /********************************************************************************************
03238 
03239 >   void RenderRegion::RestoreLineWidth(LineWidthAttribute *pAttr, BOOL Temp)
03240 
03241     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
03242     Created:    12/04/94
03243     Inputs:     pAttr - the object specifying the line width to use.
03244                 Tmp - indicates if pAttr points to a temporary attribute that should be
03245                       deleted when it's finished with.
03246     Purpose:    Get rid of the current line width, and restore the specified line width.
03247     SeeAlso:    RenderRegion::SetLineWidth
03248 
03249 ********************************************************************************************/
03250 
03251 void RenderRegion::RestoreLineWidth(LineWidthAttribute *pAttr, BOOL Temp)
03252 {
03253     // Set up the new attribute
03254     RestoreAttribute(ATTR_LINEWIDTH, pAttr, Temp);
03255 
03256     // The line attributes need to be reset before drawing anything.
03257     SetLineAttributes(CHANGEATTR_LINEWIDTH);
03258 
03259     // NB We need to invalidate the dash pattern too as this depends
03260     //    on line width (doesn't seem to matter normally, but PostScript
03261     //    gets dash patterns wrong otherwise.
03262     SetLineAttributes(CHANGEATTR_DASHPATTERN);
03263 }
03264 
03265 /********************************************************************************************
03266 
03267 >   void RenderRegion::SetDashPattern(DashRec& NewDashPattern)
03268 
03269     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03270     Created:    13/10/94
03271     Inputs:     NewDashPattern - the on-off pattern of the dash.
03272     Purpose:    Set the dash pattern, pushing the current dash pattern 
03273                 onto the context stack.
03274     SeeAlso:    RenderRegion::RestoreDashPattern
03275 
03276 ********************************************************************************************/
03277 
03278 void RenderRegion::SetDashPattern(DashRec& NewDashPattern)
03279 {
03280     // Don't bother if it doesn't cause a change
03281     DashPatternAttribute *pAttr = (DashPatternAttribute *) CurrentAttrs[ATTR_DASHPATTERN].pAttr;
03282     if ((pAttr != NULL) && (NewDashPattern == pAttr->DashPattern))
03283         return;
03284 
03285     // Create a temporary attribute and use it to set the line colour.
03286     pAttr = new DashPatternAttribute();
03287     pAttr->SetDashPattern(NewDashPattern);
03288     SetDashPattern(pAttr, TRUE);
03289 }
03290 
03291 /********************************************************************************************
03292 
03293 >   void RenderRegion::SetDashPattern(StockDash NewDashPattern)
03294 
03295     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03296     Created:    13/10/94
03297     Inputs:     NewDashPattern - the on-off pattern of the dash.
03298     Purpose:    Set the dash pattern, pushing the current dash pattern 
03299                 onto the context stack.
03300     SeeAlso:    RenderRegion::RestoreDashPattern
03301 
03302 ********************************************************************************************/
03303 
03304 void RenderRegion::SetDashPattern(StockDash NewDashPattern)
03305 {
03306     DashPatternAttribute *TempAttr = new DashPatternAttribute();
03307     TempAttr->SetStockDashPattern(NewDashPattern);
03308 
03309     // Don't bother if it doesn't cause a change
03310     DashPatternAttribute *pAttr = (DashPatternAttribute *) CurrentAttrs[ATTR_DASHPATTERN].pAttr;
03311     if ((pAttr != NULL) && (TempAttr->DashPattern == pAttr->DashPattern))
03312     {
03313         delete TempAttr;
03314         return;
03315     }
03316 
03317     // Create a temporary attribute and use it to set the line colour.
03318     SetDashPattern(TempAttr, TRUE);
03319 }
03320 
03321 /********************************************************************************************
03322 
03323 >   void RenderRegion::SetDeviceDashPattern(DashRec& NewDashPattern)
03324 
03325     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03326     Created:    13/10/94
03327     Inputs:     NewDashPattern - the on-off pattern of the dash.
03328     Purpose:    Set the dash pattern, pushing the current dash pattern 
03329                 onto the context stack.
03330     SeeAlso:    RenderRegion::RestoreDashPattern
03331 
03332 ********************************************************************************************/
03333 
03334 void RenderRegion::SetDeviceDashPattern(DashRec& NewDashPattern)
03335 {
03336     // Don't bother if it doesn't cause a change
03337     DashPatternAttribute *pAttr = (DashPatternAttribute *) CurrentAttrs[ATTR_DASHPATTERN].pAttr;
03338     if ((pAttr != NULL) && (NewDashPattern == pAttr->DashPattern))
03339         return;
03340 
03341     // Create a temporary attribute and use it to set the line colour.
03342     pAttr = new DashPatternAttribute();
03343     pAttr->SetDeviceDashPattern(NewDashPattern, GetScaledPixelWidth());
03344     SetDashPattern(pAttr, TRUE);
03345 }
03346 
03347 /********************************************************************************************
03348 
03349 >   void RenderRegion::SetDeviceDashPattern(StockDash NewDashPattern)
03350 
03351     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03352     Created:    13/10/94
03353     Inputs:     NewDashPattern - the on-off pattern of the dash.
03354     Purpose:    Set the dash pattern, pushing the current dash pattern 
03355                 onto the context stack.
03356     SeeAlso:    RenderRegion::RestoreDashPattern
03357 
03358 ********************************************************************************************/
03359 
03360 void RenderRegion::SetDeviceDashPattern(StockDash NewDashPattern)
03361 {
03362     DashPatternAttribute *TempAttr = new DashPatternAttribute();
03363     TempAttr->SetDeviceStockDashPattern(NewDashPattern, GetScaledPixelWidth());
03364 
03365     // Don't bother if it doesn't cause a change
03366     DashPatternAttribute *pAttr = (DashPatternAttribute *) CurrentAttrs[ATTR_DASHPATTERN].pAttr;
03367     if ((pAttr != NULL) && (TempAttr->DashPattern == pAttr->DashPattern))
03368     {
03369         delete TempAttr;
03370         return;
03371     }
03372 
03373     // Create a temporary attribute and use it to set the line colour.
03374     SetDashPattern(TempAttr, TRUE);
03375 }
03376 
03377 /********************************************************************************************
03378 
03379 >   void RenderRegion::SetDashPattern(DashPatternAttribute *pAttr,BOOL Temp)
03380 
03381     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03382     Created:    13/10/94
03383     Inputs:     pAttr - the object specifying the line width to use.
03384                 Tmp - indicates if pAttr points to a temporary attribute that should be
03385                       deleted when it's finished with.
03386     Purpose:    Set the current dash pattern according to an AttributeValue object, pushing
03387                 the current dash pattern onto the context stack.
03388     SeeAlso:    RenderRegion::RestoreDashPattern
03389 
03390 ********************************************************************************************/
03391 
03392 void RenderRegion::SetDashPattern(DashPatternAttribute *pAttr,BOOL Temp)
03393 {
03394     // Set up the new attribute
03395     if (SaveAttribute(ATTR_DASHPATTERN, pAttr, Temp))
03396     {
03397         // The line attributes need to be reset before drawing anything.
03398         SetLineAttributes(CHANGEATTR_DASHPATTERN);
03399     }
03400 }
03401 
03402 /********************************************************************************************
03403 
03404 >   void RenderRegion::RestoreDashPattern(DashPatternAttribute *pAttr, BOOL Temp)
03405 
03406     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03407     Created:    13/10/94
03408     Inputs:     pAttr - the object specifying the dash pattern to use.
03409                 Tmp - indicates if pAttr points to a temporary attribute that should be
03410                       deleted when it's finished with.
03411     Purpose:    Get rid of the current dash pattern, and restore the specified one.
03412     SeeAlso:    RenderRegion::SetDashPattern
03413 
03414 ********************************************************************************************/
03415 
03416 void RenderRegion::RestoreDashPattern(DashPatternAttribute *pAttr, BOOL Temp)
03417 {
03418     // Set up the new attribute
03419     RestoreAttribute(ATTR_DASHPATTERN, pAttr, Temp);
03420 
03421     // The line attributes need to be reset before drawing anything.
03422     SetLineAttributes(CHANGEATTR_DASHPATTERN);
03423 }
03424 
03425 /********************************************************************************************
03426 
03427 >   void RenderRegion::SetStartCap(LineCapType NewStartCap)
03428 
03429     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03430     Created:    5/4/95
03431     Inputs:     NewStartCap, the new LineCap Type to cap lines with.
03432     Purpose:    Set the current Line Cap according to an AttributeValue object, pushing
03433                 the current LineCap the context stack.
03434     SeeAlso:    RenderRegion::RestoreStartCap
03435 
03436 ********************************************************************************************/
03437 
03438 void RenderRegion::SetStartCap(LineCapType NewStartCap)
03439 {
03440     // Don't bother if it doesn't cause a change
03441     StartCapAttribute *pAttr = (StartCapAttribute *) CurrentAttrs[ATTR_STARTCAP].pAttr;
03442     if ((pAttr != NULL) && (NewStartCap == pAttr->StartCap))
03443         return;
03444 
03445     // Create a temporary attribute and use it to set the Start Cap.
03446     pAttr = new StartCapAttribute();
03447     pAttr->StartCap = NewStartCap;
03448     SetStartCap(pAttr, TRUE);
03449 }
03450 
03451 /********************************************************************************************
03452 
03453 >   void RenderRegion::SetStartCap(StartCapAttribute *pAttr, BOOL Temp)
03454 
03455     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03456     Created:    5/4/95
03457     Inputs:     pAttr - the object specifying the dash pattern to use.
03458                 Tmp - indicates if pAttr points to a temporary attribute that should be
03459                       deleted when it's finished with.
03460     Purpose:    Set the current Line Cap according to an AttributeValue object, pushing
03461                 the current LineCap the context stack.
03462     SeeAlso:    RenderRegion::RestoreStartCap
03463 
03464 ********************************************************************************************/
03465 
03466 void RenderRegion::SetStartCap(StartCapAttribute *pAttr, BOOL Temp)
03467 {
03468     // Set up the new attribute
03469     if (SaveAttribute(ATTR_STARTCAP, pAttr, Temp))
03470     {
03471         // The line attributes need to be reset before drawing anything.
03472         SetLineAttributes(CHANGEATTR_LINECAP);
03473     }
03474 }
03475 
03476 /********************************************************************************************
03477 
03478 >   void RenderRegion::RestoreStartCap(StartCapAttribute *pAttr, BOOL Temp)
03479 
03480     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03481     Created:    5/4/95
03482     Inputs:     pAttr - the object specifying the dash pattern to use.
03483                 Tmp - indicates if pAttr points to a temporary attribute that should be
03484                       deleted when it's finished with.
03485     Purpose:    Get rid of the current start cap, and restore the specified one.
03486     SeeAlso:    RenderRegion::SetStartCap
03487 
03488 ********************************************************************************************/
03489 
03490 void RenderRegion::RestoreStartCap(StartCapAttribute *pAttr, BOOL Temp)
03491 {
03492     // Set up the new attribute
03493     RestoreAttribute(ATTR_STARTCAP, pAttr, Temp);
03494 
03495     // The line attributes need to be reset before drawing anything.
03496     SetLineAttributes(CHANGEATTR_LINECAP);
03497 }
03498 
03499 /********************************************************************************************
03500 
03501 >   void RenderRegion::SetJoinType(JointType NewJoinType)
03502 
03503     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03504     Created:    5/4/95
03505     Inputs:     NewJoinType, the new Join Type to join lines with.
03506     Purpose:    Set the current JoinType according to an AttributeValue object, pushing
03507                 the current JoinType the context stack.
03508     SeeAlso:    RenderRegion::RestoreJoinType
03509 
03510 ********************************************************************************************/
03511 
03512 void RenderRegion::SetJoinType(JointType NewJoinType)
03513 {
03514     // Don't bother if it doesn't cause a change
03515     JoinTypeAttribute *pAttr = (JoinTypeAttribute *) CurrentAttrs[ATTR_JOINTYPE].pAttr;
03516     if ((pAttr != NULL) && (NewJoinType == pAttr->JoinType))
03517         return;
03518 
03519     // Create a temporary attribute and use it to set the Join Type.
03520     pAttr = new JoinTypeAttribute();
03521     pAttr->JoinType = NewJoinType;
03522     SetJoinType(pAttr, TRUE);
03523 }
03524 
03525 /********************************************************************************************
03526 
03527 >   void RenderRegion::SetJoinType(JoinTypeAttribute *pAttr, BOOL Temp)
03528 
03529     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03530     Created:    5/4/95
03531     Inputs:     pAttr - the object specifying the dash pattern to use.
03532                 Tmp - indicates if pAttr points to a temporary attribute that should be
03533                       deleted when it's finished with.
03534     Purpose:    Set the current JoinType according to an AttributeValue object, pushing
03535                 the current JoinType the context stack.
03536     SeeAlso:    RenderRegion::RestoreJoinType
03537 
03538 ********************************************************************************************/
03539 
03540 void RenderRegion::SetJoinType(JoinTypeAttribute *pAttr, BOOL Temp)
03541 {
03542     // Set up the new attribute
03543     if (SaveAttribute(ATTR_JOINTYPE, pAttr, Temp))
03544     {
03545         // The line attributes need to be reset before drawing anything.
03546         SetLineAttributes(CHANGEATTR_JOINTYPE);
03547     }
03548 }
03549 
03550 /********************************************************************************************
03551 
03552 >   void RenderRegion::RestoreJoinType(JoinTypeAttribute *pAttr, BOOL Temp)
03553 
03554     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03555     Created:    5/4/95
03556     Inputs:     pAttr - the object specifying the dash pattern to use.
03557                 Tmp - indicates if pAttr points to a temporary attribute that should be
03558                       deleted when it's finished with.
03559     Purpose:    Get rid of the current JoinType, and restore the specified one.
03560     SeeAlso:    RenderRegion::SetJoinType
03561 
03562 ********************************************************************************************/
03563 
03564 void RenderRegion::RestoreJoinType(JoinTypeAttribute *pAttr, BOOL Temp)
03565 {
03566     // Set up the new attribute
03567     RestoreAttribute(ATTR_JOINTYPE, pAttr, Temp);
03568 
03569     // The line attributes need to be reset before drawing anything.
03570     SetLineAttributes(CHANGEATTR_JOINTYPE);
03571 }
03572 
03573 
03574 /********************************************************************************************
03575 
03576 >   void RenderRegion::SetDefaultQuality()
03577 
03578     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
03579     Created:    12/04/94
03580     Purpose:    Set the quality attribute to the default setting, pushing the current 
03581                 quality level onto the context stack.
03582     SeeAlso:    RenderRegion::RestoreQuality
03583 
03584 ********************************************************************************************/
03585 
03586 void RenderRegion::SetDefaultQuality()
03587 {
03588     // Create a temporary attribute and use it to set the default quality..
03589     QualityAttribute *pAttr = new QualityAttribute();
03590     SetQuality(pAttr, TRUE);
03591 }
03592 
03593 /********************************************************************************************
03594 
03595 >   void RenderRegion::SetQuality(QualityAttribute *pAttr,BOOL Temp)
03596 
03597     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
03598     Created:    12/04/94
03599     Inputs:     pAttr - the object specifying the quality to use.
03600                 Tmp - indicates if pAttr points to a temporary attribute that should be
03601                       deleted when it's finished with.
03602     Purpose:    Set the current display quality according to an AttributeValue object, 
03603                 pushing the current quality onto the context stack.
03604     SeeAlso:    RenderRegion::RestoreQuality
03605 
03606 ********************************************************************************************/
03607 
03608 void RenderRegion::SetQuality(QualityAttribute *pAttr,BOOL Temp)
03609 {
03610     // Set up the new attribute
03611     SaveAttribute(ATTR_QUALITY, pAttr, Temp);
03612     RRQuality = pAttr->QualityValue;
03613 
03614     // The render region's rendering objects need to be reset before drawing anything.
03615     SetQualityLevel();
03616 }
03617 
03618 /********************************************************************************************
03619 
03620 >   void RenderRegion::RestoreQuality(QualityAttribute *pAttr, BOOL Temp)
03621 
03622     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
03623     Created:    12/04/94
03624     Inputs:     pAttr - the object specifying the quality level to use.
03625                 Tmp - indicates if pAttr points to a temporary attribute that should be
03626                       deleted when it's finished with.
03627     Purpose:    Get rid of the current quality level, and restore the specified quality 
03628                 level.
03629     SeeAlso:    RenderRegion::SetQuality
03630 
03631 ********************************************************************************************/
03632 
03633 void RenderRegion::RestoreQuality(QualityAttribute *pAttr, BOOL Temp)
03634 {
03635     // Set up the new attribute
03636     RestoreAttribute(ATTR_QUALITY, pAttr, Temp);
03637     RRQuality = pAttr->QualityValue;
03638 
03639     // The render region's rendering objects need to be reset before drawing anything.
03640     SetQualityLevel();
03641 }
03642 
03643 /********************************************************************************************
03644 
03645 >   virtual void RenderRegion::SetQualityLevel()
03646 
03647     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
03648     Created:    6/8/97
03649     Inputs:     -
03650     Purpose:    Does nothing.
03651 
03652                 This used to be a pure function until we found a way of making the base class get called
03653                 (due to the introduction of the path processing code)
03654 
03655     SeeAlso:    RenderRegion::SetQuality
03656 
03657 ********************************************************************************************/
03658 
03659 void RenderRegion::SetQualityLevel()
03660 {
03661 }
03662 
03663 /********************************************************************************************
03664 
03665 >   void RenderRegion::SetWebAddress(WebAddressAttribute *pAttr,BOOL Temp)
03666 
03667     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
03668     Created:    18/3/97
03669     Inputs:     pAttr - pointer to a Web Address to set
03670                 Tmp - indicates if pAttr points to a temporary attribute that should be
03671                       deleted when it's finished with.
03672     Purpose:    Set the current WebAddress
03673 
03674                 This attribute has no effect on rendering, so there's no need to 
03675                 change anything in the rendering system itself when we do this.
03676 
03677     SeeAlso:    RenderRegion::RestoreWebAddress
03678 
03679 ********************************************************************************************/
03680 
03681 void RenderRegion::SetWebAddress(WebAddressAttribute *pAttr,BOOL Temp)
03682 {
03683     // Set up the new attribute
03684     SaveAttribute(ATTR_WEBADDRESS, (AttributeValue*) pAttr, Temp);
03685 }
03686 
03687 /********************************************************************************************
03688 
03689 >   void RenderRegion::RestoreQuality(QualityAttribute *pAttr, BOOL Temp)
03690 
03691     Author:     Graham_Walmsley (Xara Group Ltd) <camelotdev@xara.com>
03692     Created:    18/3/97
03693     Inputs:     pAttr - pointer to a Web Address to set
03694                 Tmp - indicates if pAttr points to a temporary attribute that should be
03695                       deleted when it's finished with.
03696     Purpose:    Restore the Web Address
03697     SeeAlso:    RenderRegion::SetWebAddress
03698 
03699 ********************************************************************************************/
03700 
03701 void RenderRegion::RestoreWebAddress(WebAddressAttribute *pAttr, BOOL Temp)
03702 {
03703     // Set up the new attribute
03704     RestoreAttribute(ATTR_WEBADDRESS, (AttributeValue*) pAttr, Temp);
03705 }
03706 
03707 
03708 /********************************************************************************************
03709 
03710 >   void RenderRegion::SetStartArrow(StockArrow NewStartArrow)
03711 
03712     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03713     Created:    5/4/95
03714     Inputs:     NewStartArrow, the new Arrow to draw on the start of lines.
03715     Purpose:    Set the current StartArrow according to an AttributeValue object, pushing
03716                 the current Arrow the context stack.
03717     SeeAlso:    RenderRegion::RestoreStartArrow
03718 
03719 ********************************************************************************************/
03720 
03721 void RenderRegion::SetStartArrow(StockArrow NewStartArrow)
03722 {
03723     // Don't bother if it doesn't cause a change
03724     StartArrowAttribute *pAttr = (StartArrowAttribute *) CurrentAttrs[ATTR_STARTARROW].pAttr;
03725     if ((pAttr != NULL) && (pAttr->StartArrow == NewStartArrow))
03726         return;
03727 
03728     // Create a temporary attribute and use it to set the Start Arrow.
03729     pAttr = new StartArrowAttribute();
03730     pAttr->StartArrow = NewStartArrow;
03731     SetStartArrow(pAttr, TRUE);
03732 }
03733 
03734 /********************************************************************************************
03735 
03736 >   void RenderRegion::SetStartArrow(ArrowRec &NewStartArrow)
03737 
03738     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03739     Created:    5/4/95
03740     Inputs:     NewStartArrow, the new Arrow to draw on the start of lines.
03741     Purpose:    Set the current StartArrow according to an AttributeValue object, pushing
03742                 the current Arrow the context stack.
03743     SeeAlso:    RenderRegion::RestoreStartArrow
03744 
03745 ********************************************************************************************/
03746 
03747 void RenderRegion::SetStartArrow(ArrowRec &NewStartArrow)
03748 {
03749     // Don't bother if it doesn't cause a change
03750     StartArrowAttribute *pAttr = (StartArrowAttribute *) CurrentAttrs[ATTR_STARTARROW].pAttr;
03751     if ((pAttr != NULL) && (pAttr->StartArrow == NewStartArrow))
03752         return;
03753 
03754     // Create a temporary attribute and use it to set the Start Arrow.
03755     pAttr = new StartArrowAttribute();
03756     pAttr->StartArrow = NewStartArrow;
03757     SetStartArrow(pAttr, TRUE);
03758 }
03759 
03760 /********************************************************************************************
03761 
03762 >   void RenderRegion::SetStartArrow(StartArrowAttribute *pAttr,BOOL Temp)
03763 
03764     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03765     Created:    5/4/95
03766     Inputs:     pAttr - the object specifying the dash pattern to use.
03767                 Tmp - indicates if pAttr points to a temporary attribute that should be
03768                       deleted when it's finished with.
03769     Purpose:    Set the current StartArrow according to an AttributeValue object, pushing
03770                 the current StartArrow the context stack.
03771     SeeAlso:    RenderRegion::RestoreStartArrow
03772 
03773 ********************************************************************************************/
03774 
03775 void RenderRegion::SetStartArrow(StartArrowAttribute *pAttr,BOOL Temp)
03776 {
03777     // Set up the new attribute
03778     if (SaveAttribute(ATTR_STARTARROW, pAttr, Temp))
03779     {
03780         // The line attributes need to be reset before drawing anything.
03781         SetLineAttributes(CHANGEATTR_STARTARROW);
03782     }
03783 }
03784 
03785 /********************************************************************************************
03786 
03787 >   void RenderRegion::RestoreStartArrow(StartArrowAttribute *pAttr,BOOL Temp)
03788 
03789     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03790     Created:    5/4/95
03791     Inputs:     pAttr - the object specifying the dash pattern to use.
03792                 Tmp - indicates if pAttr points to a temporary attribute that should be
03793                       deleted when it's finished with.
03794     Purpose:    Get rid of the current StartArrow, and restore the specified one.
03795     SeeAlso:    RenderRegion::SetStartArrow
03796 
03797 ********************************************************************************************/
03798 
03799 void RenderRegion::RestoreStartArrow(StartArrowAttribute *pAttr,BOOL Temp)
03800 {
03801     // Set up the new attribute
03802     RestoreAttribute(ATTR_STARTARROW, pAttr, Temp);
03803 
03804     // The line attributes need to be reset before drawing anything.
03805     SetLineAttributes(CHANGEATTR_STARTARROW);
03806 }
03807 
03808 
03809 /********************************************************************************************
03810 
03811 >   void RenderRegion::SetEndArrow(StockArrow NewEndArrow)
03812 
03813     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03814     Created:    5/4/95
03815     Inputs:     NewEndArrow, the new Arrow to draw on the end of lines.
03816     Purpose:    Set the current EndArrow according to an AttributeValue object, pushing
03817                 the current Arrow the context stack.
03818     SeeAlso:    RenderRegion::RestoreEndArrow
03819 
03820 ********************************************************************************************/
03821 
03822 void RenderRegion::SetEndArrow(StockArrow NewEndArrow)
03823 {
03824     // Don't bother if it doesn't cause a change
03825     EndArrowAttribute *pAttr = (EndArrowAttribute *) CurrentAttrs[ATTR_ENDARROW].pAttr;
03826     if ((pAttr != NULL) && (pAttr->EndArrow == NewEndArrow))
03827         return;
03828 
03829     // Create a temporary attribute and use it to set the Start Arrow.
03830     pAttr = new EndArrowAttribute();
03831     pAttr->EndArrow = NewEndArrow;
03832     SetEndArrow(pAttr, TRUE);
03833 }
03834 
03835 /********************************************************************************************
03836 
03837 >   void RenderRegion::SetEndArrow(StockArrow NewEndArrow)
03838 
03839     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03840     Created:    5/4/95
03841     Inputs:     NewEndArrow, the new Arrow to draw on the end of lines.
03842     Purpose:    Set the current EndArrow according to an AttributeValue object, pushing
03843                 the current Arrow the context stack.
03844     SeeAlso:    RenderRegion::RestoreEndArrow
03845 
03846 ********************************************************************************************/
03847 
03848 void RenderRegion::SetEndArrow(ArrowRec &NewEndArrow)
03849 {
03850     // Don't bother if it doesn't cause a change
03851     EndArrowAttribute *pAttr = (EndArrowAttribute *) CurrentAttrs[ATTR_ENDARROW].pAttr;
03852     if ((pAttr != NULL) && (pAttr->EndArrow == NewEndArrow))
03853         return;
03854 
03855     // Create a temporary attribute and use it to set the Start Arrow.
03856     pAttr = new EndArrowAttribute();
03857     pAttr->EndArrow = NewEndArrow;
03858     SetEndArrow(pAttr, TRUE);
03859 }
03860 
03861 /********************************************************************************************
03862 
03863 >   void RenderRegion::SetEndArrow(EndArrowAttribute *pAttr,BOOL Temp)
03864 
03865     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03866     Created:    5/4/95
03867     Inputs:     pAttr - the object specifying the dash pattern to use.
03868                 Tmp - indicates if pAttr points to a temporary attribute that should be
03869                       deleted when it's finished with.
03870     Purpose:    Set the current EndArrow according to an AttributeValue object, pushing
03871                 the current EndArrow the context stack.
03872     SeeAlso:    RenderRegion::RestoreEndArrow
03873 
03874 ********************************************************************************************/
03875 
03876 void RenderRegion::SetEndArrow(EndArrowAttribute *pAttr,BOOL Temp)
03877 {
03878     // Set up the new attribute
03879     if (SaveAttribute(ATTR_ENDARROW, pAttr, Temp))
03880     {
03881         // The line attributes need to be reset before drawing anything.
03882         SetLineAttributes(CHANGEATTR_ENDARROW);
03883     }
03884 }
03885 
03886 /********************************************************************************************
03887 
03888 >   void RenderRegion::RestoreEndArrow(EndArrowAttribute *pAttr,BOOL Temp)
03889 
03890     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03891     Created:    5/4/95
03892     Inputs:     pAttr - the object specifying the dash pattern to use.
03893                 Tmp - indicates if pAttr points to a temporary attribute that should be
03894                       deleted when it's finished with.
03895     Purpose:    Get rid of the current EndArrow, and restore the specified one.
03896     SeeAlso:    RenderRegion::SetEndArrow
03897 
03898 ********************************************************************************************/
03899 
03900 void RenderRegion::RestoreEndArrow(EndArrowAttribute *pAttr,BOOL Temp)
03901 {
03902     // Set up the new attribute
03903     RestoreAttribute(ATTR_ENDARROW, pAttr, Temp);
03904 
03905     // The line attributes need to be reset before drawing anything.
03906     SetLineAttributes(CHANGEATTR_ENDARROW);
03907 }
03908 
03909 /********************************************************************************************
03910 
03911 >   void RenderRegion::SetMitreLimit(MILLIPOINT NewMitreLimit)
03912 
03913     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03914     Created:    5/4/95
03915     Inputs:     NewMitreLimit, the new Arrow to draw on the end of lines.
03916     Purpose:    Set the current MitreLimit according to an AttributeValue object, pushing
03917                 the current Arrow the context stack.
03918     SeeAlso:    RenderRegion::RestoreMitreLimit
03919 
03920 ********************************************************************************************/
03921 
03922 void RenderRegion::SetMitreLimit(MILLIPOINT NewMitreLimit)
03923 {
03924     // Don't bother if it doesn't cause a change
03925     MitreLimitAttribute *pAttr = (MitreLimitAttribute *) CurrentAttrs[ATTR_MITRELIMIT].pAttr;
03926     if ((pAttr != NULL) && (pAttr->MitreLimit == NewMitreLimit))
03927         return;
03928 
03929     // Create a temporary attribute and use it to set the Start Arrow.
03930     pAttr = new MitreLimitAttribute();
03931     pAttr->MitreLimit = NewMitreLimit;
03932     SetMitreLimit(pAttr, TRUE);
03933 }
03934 
03935 /********************************************************************************************
03936 
03937 >   void RenderRegion::SetMitreLimit(MitreLimitAttribute *pAttr,BOOL Temp)
03938 
03939     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03940     Created:    5/4/95
03941     Inputs:     pAttr - the object specifying the dash pattern to use.
03942                 Tmp - indicates if pAttr points to a temporary attribute that should be
03943                       deleted when it's finished with.
03944     Purpose:    Set the current MitreLimit according to an AttributeValue object, pushing
03945                 the current MitreLimit the context stack.
03946     SeeAlso:    RenderRegion::RestoreMitreLimit
03947 
03948 ********************************************************************************************/
03949 
03950 void RenderRegion::SetMitreLimit(MitreLimitAttribute *pAttr,BOOL Temp)
03951 {
03952     // Set up the new attribute
03953     if (SaveAttribute(ATTR_MITRELIMIT, pAttr, Temp))
03954     {
03955         // The line attributes need to be reset before drawing anything.
03956         SetLineAttributes(CHANGEATTR_MITRELIMIT);
03957     }
03958 }
03959 
03960 /********************************************************************************************
03961 
03962 >   void RenderRegion::RestoreMitreLimit(MitreLimitAttribute *pAttr,BOOL Temp)
03963 
03964     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
03965     Created:    5/4/95
03966     Inputs:     pAttr - the object specifying the dash pattern to use.
03967                 Tmp - indicates if pAttr points to a temporary attribute that should be
03968                       deleted when it's finished with.
03969     Purpose:    Get rid of the current MitreLimit, and restore the specified one.
03970     SeeAlso:    RenderRegion::SetMitreLimit
03971 
03972 ********************************************************************************************/
03973 
03974 void RenderRegion::RestoreMitreLimit(MitreLimitAttribute *pAttr,BOOL Temp)
03975 {
03976     // Set up the new attribute
03977     RestoreAttribute(ATTR_MITRELIMIT, pAttr, Temp);
03978 
03979     // The line attributes need to be reset before drawing anything.
03980     SetLineAttributes(CHANGEATTR_MITRELIMIT);
03981 }
03982 
03983 
03984 
03985 
03986 /********************************************************************************************
03987 
03988 >   void RenderRegion::SetWindingRule(WindingType NewWindingRule)
03989 
03990     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
03991     Created:    12/04/94
03992     Inputs:     NewWindingRule - the winding rule to use.
03993     Purpose:    Set the winding rule, pushing the current winding rule onto the context 
03994                 stack.
03995     SeeAlso:    RenderRegion::RestoreWindingRule
03996 
03997 ********************************************************************************************/
03998 
03999 void RenderRegion::SetWindingRule(WindingType NewWindingRule)
04000 {
04001     // Don't bother if it doesn't cause a change
04002     WindingRuleAttribute *pAttr = 
04003         (WindingRuleAttribute *) CurrentAttrs[ATTR_WINDINGRULE].pAttr;
04004     if ((pAttr != NULL) && (NewWindingRule == pAttr->WindingRule))
04005         return;
04006 
04007     // Create a temporary attribute and use it to set the drawing mode
04008     pAttr = new WindingRuleAttribute(NewWindingRule);
04009     SetWindingRule(pAttr, TRUE);
04010 }
04011 
04012 /********************************************************************************************
04013 
04014 >   void RenderRegion::SetWindingRule(WindingRuleAttribute *pAttr,BOOL Temp)
04015 
04016     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
04017     Created:    12/04/94
04018     Inputs:     pAttr - the object specifying the winding rule to use.
04019                 Tmp - indicates if pAttr points to a temporary attribute that should be
04020                       deleted when it's finished with.
04021     Purpose:    Set the current winding rule according to an AttributeValue object, pushing
04022                 the current winding rule onto the context stack.
04023     SeeAlso:    RenderRegion::RestoreWindingRule
04024 
04025 ********************************************************************************************/
04026 
04027 void RenderRegion::SetWindingRule(WindingRuleAttribute *pAttr,BOOL Temp)
04028 {
04029     // Save the current attribute
04030     if (SaveAttribute(ATTR_WINDINGRULE, pAttr, Temp))
04031     {
04032         // The fill attributes need to be reset before drawing anything.
04033         SetFillAttributes(CHANGEATTR_WINDING_RULE);
04034     }
04035 }
04036 
04037 /********************************************************************************************
04038 
04039 >   void RenderRegion::RestoreWindingRule(WindingRuleAttribute *pAttr, BOOL Temp)
04040 
04041     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
04042     Created:    12/04/94
04043     Inputs:     pAttr - the object specifying the winding rule to use.
04044                 Tmp - indicates if pAttr points to a temporary attribute that should be
04045                       deleted when it's finished with.
04046     Purpose:    Get rid of the current winding rule, and restore the specified winding rule.
04047     SeeAlso:    RenderRegion::SetWindingRule
04048 
04049 ********************************************************************************************/
04050 
04051 void RenderRegion::RestoreWindingRule(WindingRuleAttribute *pAttr, BOOL Temp)
04052 {
04053     // Set up the new attribute
04054     RestoreAttribute(ATTR_WINDINGRULE, pAttr, Temp);
04055 
04056     // The fill attributes need to be reset before drawing anything.
04057     SetFillAttributes(CHANGEATTR_WINDING_RULE);
04058 }
04059 
04060 
04061 /********************************************************************************************
04062 
04063 >   void RenderRegion::SetDrawingMode(DrawModeType NewDrawingMode)
04064 
04065     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
04066     Created:    12/04/94
04067     Inputs:     NewDrawingMode - the drawing mode to use.
04068     Purpose:    Set the drawing mode, pushing the current drawing mode onto the context 
04069                 stack.
04070     SeeAlso:    RenderRegion::RestoreDrawingMode
04071 
04072 ********************************************************************************************/
04073 
04074 void RenderRegion::SetDrawingMode(DrawModeType NewDrawingMode)
04075 {
04076     // Don't bother if it doesn't cause a change
04077     DrawingModeAttribute *pAttr = 
04078         (DrawingModeAttribute *) CurrentAttrs[DrawingModeAttribute::ID].pAttr;
04079     if ((pAttr != NULL) && (NewDrawingMode == pAttr->DrawingMode))
04080         return;
04081 
04082     // Create a temporary attribute and use it to set the drawing mode
04083     pAttr = new DrawingModeAttribute(NewDrawingMode);
04084     SetDrawingMode(pAttr, TRUE);
04085 }
04086 
04087 /********************************************************************************************
04088 
04089 >   void RenderRegion::SetDrawingMode(DrawingModeAttribute *pAttr, BOOL Temp)
04090 
04091     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
04092     Created:    12/04/94
04093     Inputs:     pAttr - the object specifying the drawing mode to use.
04094                 Tmp - indicates if pAttr points to a temporary attribute that should be
04095                       deleted when it's finished with.
04096     Purpose:    Set the current drawing mode according to an AttributeValue object, pushing
04097                 the current drawing mode onto the context stack.
04098     SeeAlso:    RenderRegion::RestoreDrawingMode
04099 
04100 ********************************************************************************************/
04101 
04102 void RenderRegion::SetDrawingMode(DrawingModeAttribute *pAttr, BOOL Temp)
04103 {
04104     // Save the current attribute
04105     SaveAttribute(DrawingModeAttribute::ID, pAttr, Temp);
04106     DrawingMode = pAttr->DrawingMode;
04107 
04108     // The drawing mode needs to be set
04109     // MarkH - 12/11/99
04110     // First check to see if we`re dealing with a derived class or using the base class as
04111     // the base class ( RenderRegion ) 'SetOSDrawingMode()' is a pure virtual which will
04112     // ultimately crash in a big way if it is called!!!!
04113     if(!IS_A(this,RenderRegion))
04114     {
04115         SetOSDrawingMode();
04116     }
04117 }
04118 
04119 /********************************************************************************************
04120 
04121 >   void RenderRegion::RestoreDrawingMode(DrawingModeAttribute *pAttr, BOOL Temp)
04122 
04123     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
04124     Created:    12/04/94
04125     Inputs:     pAttr - the object specifying the drawing mode to use.
04126                 Tmp - indicates if pAttr points to a temporary attribute that should be
04127                       deleted when it's finished with.
04128     Purpose:    Get rid of the current drawing mode, and restore the specified drawing mode.
04129     SeeAlso:    RenderRegion::SetDrawingMode
04130 
04131 ********************************************************************************************/
04132 
04133 void RenderRegion::RestoreDrawingMode(DrawingModeAttribute *pAttr, BOOL Temp)
04134 {
04135     // Set up the new attribute
04136     RestoreAttribute(DrawingModeAttribute::ID, pAttr, Temp);
04137     DrawingMode = pAttr->DrawingMode;
04138 
04139     // The drawing mode needs to be set
04140     // MarkH - 12/11/99
04141     // First check to see if we`re dealing with a derived class or using the base class as
04142     // the base class ( RenderRegion ) 'SetOSDrawingMode()' is a pure virtual which will
04143     // ultimately crash in a big way if it is called!!!!
04144     if(!IS_A(this,RenderRegion))
04145     {
04146         SetOSDrawingMode();
04147     }
04148 }
04149 
04150 
04151 
04152 
04153 
04154 
04155 /********************************************************************************************
04156 
04157 >   void RenderRegion::SetTxtFontTypeface(TxtFontTypefaceAttribute *pAttr, BOOL Temp)
04158 
04159     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04160     Created:    13/03/95
04161     Inputs:     pAttr - the object specifying the colour to use.
04162                 Tmp - indicates if pAttr points to a temporary attribute that should be
04163                       deleted when it's finished with.
04164     Purpose:    Set the current Text Font Typeface according to an AttributeValue object, 
04165                 pushing the current Font Typeface onto the context stack.
04166     SeeAlso:    RenderRegion::RestoreTxtFontTypeface
04167 
04168 ********************************************************************************************/
04169 
04170 void RenderRegion::SetTxtFontTypeface(TxtFontTypefaceAttribute *pAttr, BOOL Temp)
04171 {
04172     // Save the current attribute and set up the new one
04173     if (SaveAttribute(ATTR_TXTFONTTYPEFACE, (AttributeValue*)pAttr, Temp))
04174     {
04175         SetTextAttributes(CHANGEATTR_FONT);
04176     }
04177 }
04178 
04179 /********************************************************************************************
04180 
04181 >   void RenderRegion::RestoreTxtFontTypeface(TxtFontTypefaceAttribute *pAttr, BOOL Temp)
04182 
04183     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04184     Created:    13/03/95
04185     Inputs:     pAttr - the object specifying the colour to use.
04186                 Tmp - indicates if pAttr points to a temporary attribute that should be
04187                       deleted when it's finished with.
04188     Purpose:    Get rid of the current Text Font Typeface, and restore the specified 
04189                 Typeface value.
04190     SeeAlso:    RenderRegion::SetTxtFontTypeface
04191 
04192 ********************************************************************************************/
04193 
04194 void RenderRegion::RestoreTxtFontTypeface(TxtFontTypefaceAttribute *pAttr, BOOL Temp)
04195 {
04196 //  BOOL NewAttr = pAttr->HTypeface != RR_TXTFONTTYPEFACE();
04197     // Restore the Font Typeface attribute
04198     RestoreAttribute(ATTR_TXTFONTTYPEFACE, (AttributeValue*)pAttr, Temp);
04199 //  if(NewAttr)
04200     SetTextAttributes(CHANGEATTR_FONT);
04201 }
04202 
04203 /********************************************************************************************
04204 
04205 >   void RenderRegion::SetTxtBold(TxtBoldAttribute *pAttr, BOOL Temp)
04206 
04207     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04208     Created:    13/03/95
04209     Inputs:     pAttr - the object specifying the colour to use.
04210                 Tmp - indicates if pAttr points to a temporary attribute that should be
04211                       deleted when it's finished with.
04212     Purpose:    Set the current Text Boldness according to an AttributeValue object, 
04213                 pushing the current Boldness onto the context stack.
04214     SeeAlso:    RenderRegion::RestoreTxtBold
04215 
04216 ********************************************************************************************/
04217 
04218 void RenderRegion::SetTxtBold(TxtBoldAttribute *pAttr, BOOL Temp)
04219 {
04220     // Save the current attribute and set up the new one
04221     if (SaveAttribute(ATTR_TXTBOLD, (AttributeValue*)pAttr, Temp))
04222     {
04223         SetTextAttributes(CHANGEATTR_BOLD);
04224     }
04225 }
04226 
04227 /********************************************************************************************
04228 
04229 >   void RenderRegion::RestoreTxtBold(TxtBoldAttribute *pAttr, BOOL Temp)
04230 
04231     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04232     Created:    13/03/95
04233     Inputs:     pAttr - the object specifying the colour to use.
04234                 Tmp - indicates if pAttr points to a temporary attribute that should be
04235                       deleted when it's finished with.
04236     Purpose:    Get rid of the current Text Boldness, and restore the specified 
04237                 Boldness value.
04238     SeeAlso:    RenderRegion::SetTxtBold
04239 
04240 ********************************************************************************************/
04241 
04242 void RenderRegion::RestoreTxtBold(TxtBoldAttribute *pAttr, BOOL Temp)
04243 {
04244     // Restore the Text Bold attribute
04245     RestoreAttribute(ATTR_TXTBOLD, (AttributeValue*)pAttr, Temp);
04246     SetTextAttributes(CHANGEATTR_BOLD);
04247 }
04248 
04249 
04250 /********************************************************************************************
04251 
04252 >   void RenderRegion::SetTxtItalic(TxtItalicAttribute *pAttr, BOOL Temp)
04253 
04254     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04255     Created:    13/03/95
04256     Inputs:     pAttr - the object specifying the colour to use.
04257                 Tmp - indicates if pAttr points to a temporary attribute that should be
04258                       deleted when it's finished with.
04259     Purpose:    Set the current Text Italicness according to an AttributeValue object, 
04260                 pushing the current Italicness onto the context stack.
04261     SeeAlso:    RenderRegion::RestoreTxtItalic
04262 
04263 ********************************************************************************************/
04264 
04265 void RenderRegion::SetTxtItalic(TxtItalicAttribute *pAttr, BOOL Temp)
04266 {
04267     // Save the current attribute and set up the new one
04268     if (SaveAttribute(ATTR_TXTITALIC, (AttributeValue*)pAttr, Temp))
04269     {
04270         SetTextAttributes(CHANGEATTR_ITALIC);
04271     }
04272 }
04273 
04274 /********************************************************************************************
04275 
04276 >   void RenderRegion::RestoreTxtItalic(TxtItalicAttribute *pAttr, BOOL Temp)
04277 
04278     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04279     Created:    13/03/95
04280     Inputs:     pAttr - the object specifying the colour to use.
04281                 Tmp - indicates if pAttr points to a temporary attribute that should be
04282                       deleted when it's finished with.
04283     Purpose:    Get rid of the current Text Italicness, and restore the specified 
04284                 Italicness value.
04285     SeeAlso:    RenderRegion::SetTxtItalic
04286 
04287 ********************************************************************************************/
04288 
04289 void RenderRegion::RestoreTxtItalic(TxtItalicAttribute *pAttr, BOOL Temp)
04290 {
04291     // Restore the Text Italic attribute
04292     RestoreAttribute(ATTR_TXTITALIC, (AttributeValue*)pAttr, Temp);
04293     SetTextAttributes(CHANGEATTR_ITALIC);
04294 }
04295 
04296 
04297 /********************************************************************************************
04298 
04299 >   void RenderRegion::SetTxtFontSize(TxtFontSizeAttribute *pAttr, BOOL Temp)
04300 
04301     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
04302     Created:    13/03/95
04303     Inputs:     pAttr - the object specifying the font size to use.
04304                 Tmp - indicates if pAttr points to a temporary attribute that should be
04305                       deleted when it's finished with.
04306     Purpose:    Set the current Font Size according to an AttributeValue object, 
04307                 pushing the current font size state onto the context stack.
04308 
04309 ********************************************************************************************/
04310 
04311 void RenderRegion::SetTxtFontSize(TxtFontSizeAttribute *pAttr, BOOL Temp)
04312 {
04313     // Save the current attribute and set up the new one
04314     if (SaveAttribute(ATTR_TXTFONTSIZE, (AttributeValue*)pAttr, Temp))
04315     {
04316         SetTextAttributes(CHANGEATTR_SIZE);
04317     }
04318 }
04319 
04320 
04321 
04322 /********************************************************************************************
04323 
04324 >   void RenderRegion::RestoreTxtFontSize(TxtFontSizeAttribute *pAttr, BOOL Temp)
04325 
04326     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
04327     Created:    13/03/95
04328     Inputs:     pAttr - the object specifying the font size 
04329                 Tmp - indicates if pAttr points to a temporary attribute that should be
04330                       deleted when it's finished with.
04331     Purpose:    Get rid of the current font size, and restore the specified 
04332                 font size
04333     SeeAlso:    RenderRegion::SetTxtFontSize
04334 
04335 ********************************************************************************************/
04336 
04337 void RenderRegion::RestoreTxtFontSize(TxtFontSizeAttribute *pAttr, BOOL Temp)
04338 {
04339     // Restore the Text Italic attribute
04340     RestoreAttribute(ATTR_TXTFONTSIZE, (AttributeValue*)pAttr, Temp);
04341     SetTextAttributes(CHANGEATTR_SIZE);
04342 }
04343 
04344 
04345 
04346 
04347 /********************************************************************************************
04348 
04349 >   void RenderRegion::SetTxtUnderline(TxtUnderlineAttribute *pAttr, BOOL Temp)
04350 
04351     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
04352     Created:    13/03/95
04353     Inputs:     pAttr - the object specifying the colour to use.
04354                 Tmp - indicates if pAttr points to a temporary attribute that should be
04355                       deleted when it's finished with.
04356     Purpose:    Set the current Text Underline state according to an AttributeValue object, 
04357                 pushing the current Underline state onto the context stack.
04358 
04359 ********************************************************************************************/
04360 
04361 void RenderRegion::SetTxtUnderline(TxtUnderlineAttribute *pAttr, BOOL Temp)
04362 {
04363     // Save the current attribute and set up the new one
04364     if (SaveAttribute(ATTR_TXTUNDERLINE, (AttributeValue*)pAttr, Temp))
04365     {
04366         SetTextAttributes(CHANGEATTR_UNDERLINE);
04367     }
04368 }
04369 
04370 /********************************************************************************************
04371 
04372 >   void RenderRegion::RestoreTxtUnderline(TxtItalicAttribute *pAttr, BOOL Temp)
04373 
04374     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
04375     Created:    13/03/95
04376     Inputs:     pAttr - the object specifying the colour to use.
04377                 Tmp - indicates if pAttr points to a temporary attribute that should be
04378                       deleted when it's finished with.
04379     Purpose:    Get rid of the current Text underline state, and restore the specified 
04380                 underline value.
04381     SeeAlso:    RenderRegion::SetTxtUnderline
04382 
04383 ********************************************************************************************/
04384 
04385 void RenderRegion::RestoreTxtUnderline(TxtUnderlineAttribute *pAttr, BOOL Temp)
04386 {
04387     // Restore the Text Italic attribute
04388     RestoreAttribute(ATTR_TXTUNDERLINE, (AttributeValue*)pAttr, Temp);
04389     SetTextAttributes(CHANGEATTR_UNDERLINE);
04390 }
04391 
04392 /********************************************************************************************
04393 
04394 >   void RenderRegion::SetTxtAspectRatio(TxtAspectRatioAttribute *pAttr, BOOL Temp)
04395 
04396     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04397     Created:    13/03/95
04398     Inputs:     pAttr - the object specifying the colour to use.
04399                 Tmp - indicates if pAttr points to a temporary attribute that should be
04400                       deleted when it's finished with.
04401     Purpose:    Set the current Text Aspect Ratio according to an AttributeValue object, 
04402                 pushing the current Aspect Ratio onto the context stack.
04403     SeeAlso:    RenderRegion::RestoreTxtAspectRatio
04404 
04405 ********************************************************************************************/
04406 
04407 void RenderRegion::SetTxtAspectRatio(TxtAspectRatioAttribute *pAttr, BOOL Temp)
04408 {
04409     // Save the current attribute and set up the new one
04410     if (SaveAttribute(ATTR_TXTASPECTRATIO, (AttributeValue*)pAttr, Temp))
04411     {
04412         SetTextAttributes(CHANGEATTR_ASPECT);
04413     }
04414 }
04415 
04416 /********************************************************************************************
04417 
04418 >   void RenderRegion::RestoreTxtAspectRatio(TxtAspectRatioAttribute *pAttr, BOOL Temp)
04419 
04420     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04421     Created:    13/03/95
04422     Inputs:     pAttr - the object specifying the colour to use.
04423                 Tmp - indicates if pAttr points to a temporary attribute that should be
04424                       deleted when it's finished with.
04425     Purpose:    Get rid of the current Text Aspect Ratio, and restore the specified 
04426                 Aspect Ratio value.
04427     SeeAlso:    RenderRegion::SetTxtAspectRatio
04428 
04429 ********************************************************************************************/
04430 
04431 void RenderRegion::RestoreTxtAspectRatio(TxtAspectRatioAttribute *pAttr, BOOL Temp)
04432 {
04433     // Restore the Text Aspect Ratio attribute
04434     RestoreAttribute(ATTR_TXTASPECTRATIO, (AttributeValue*)pAttr, Temp);
04435     SetTextAttributes(CHANGEATTR_ASPECT);
04436 }
04437 
04438 /********************************************************************************************
04439 
04440 >   void RenderRegion::SetTxtJustification(TxtJustificationAttribute *pAttr, BOOL Temp)
04441 
04442     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04443     Created:    13/03/95
04444     Inputs:     pAttr - the object specifying the colour to use.
04445                 Tmp - indicates if pAttr points to a temporary attribute that should be
04446                       deleted when it's finished with.
04447     Purpose:    Set the current Text Justification according to an AttributeValue object, 
04448                 pushing the current Justification onto the context stack.
04449     SeeAlso:    RenderRegion::RestoreTxtJustification
04450 
04451 ********************************************************************************************/
04452 
04453 void RenderRegion::SetTxtJustification(TxtJustificationAttribute *pAttr, BOOL Temp)
04454 {
04455     // Save the current attribute and set up the new one
04456     if (SaveAttribute(ATTR_TXTJUSTIFICATION, (AttributeValue*)pAttr, Temp))
04457     {
04458         SetTextAttributes(CHANGEATTR_JUSTIFY);
04459     }
04460 }
04461 
04462 /********************************************************************************************
04463 
04464 >   void RenderRegion::RestoreTxtJustification(TxtJustificationAttribute *pAttr, BOOL Temp)
04465 
04466     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04467     Created:    13/03/95
04468     Inputs:     pAttr - the object specifying the colour to use.
04469                 Tmp - indicates if pAttr points to a temporary attribute that should be
04470                       deleted when it's finished with.
04471     Purpose:    Get rid of the current Text Justification, and restore the specified 
04472                 Justification value.
04473     SeeAlso:    RenderRegion::SetTxtJustification
04474 
04475 ********************************************************************************************/
04476 
04477 void RenderRegion::RestoreTxtJustification(TxtJustificationAttribute *pAttr, BOOL Temp)
04478 {
04479     // Restore the Text Justification attribute
04480     RestoreAttribute(ATTR_TXTJUSTIFICATION, (AttributeValue*)pAttr, Temp);
04481     SetTextAttributes(CHANGEATTR_JUSTIFY);
04482 }
04483 
04484 /********************************************************************************************
04485 
04486 >   void RenderRegion::SetTxtTracking(TxtTrackingAttribute *pAttr, BOOL Temp)
04487 
04488     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04489     Created:    13/03/95
04490     Inputs:     pAttr - the object specifying the colour to use.
04491                 Tmp - indicates if pAttr points to a temporary attribute that should be
04492                       deleted when it's finished with.
04493     Purpose:    Set the current Text Tracking according to an AttributeValue object, 
04494                 pushing the current Tracking onto the context stack.
04495     SeeAlso:    RenderRegion::RestoreTxtTracking
04496 
04497 ********************************************************************************************/
04498 
04499 void RenderRegion::SetTxtTracking(TxtTrackingAttribute *pAttr, BOOL Temp)
04500 {
04501     // Save the current attribute and set up the new one
04502     if (SaveAttribute(ATTR_TXTTRACKING, (AttributeValue*)pAttr, Temp))
04503     {
04504         SetTextAttributes(CHANGEATTR_TRACKING);
04505     }
04506 }
04507 
04508 /********************************************************************************************
04509 
04510 >   void RenderRegion::RestoreTxtTracking(TxtTrackingAttribute *pAttr, BOOL Temp)
04511 
04512     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04513     Created:    13/03/95
04514     Inputs:     pAttr - the object specifying the colour to use.
04515                 Tmp - indicates if pAttr points to a temporary attribute that should be
04516                       deleted when it's finished with.
04517     Purpose:    Get rid of the current Text Tracking, and restore the specified 
04518                 Tracking value.
04519     SeeAlso:    RenderRegion::SetTxtTracking
04520 
04521 ********************************************************************************************/
04522 
04523 void RenderRegion::RestoreTxtTracking(TxtTrackingAttribute *pAttr, BOOL Temp)
04524 {
04525     // Restore the Text Tracking attribute
04526     RestoreAttribute(ATTR_TXTTRACKING, (AttributeValue*)pAttr, Temp);
04527     SetTextAttributes(CHANGEATTR_TRACKING);
04528 }
04529 
04530 
04531 
04532 /********************************************************************************************
04533 
04534 >   void RenderRegion::SetTxtScript(TxtScriptAttribute *pAttr, BOOL Temp)
04535 
04536     Author:     Simon_Maneggio (Xara Group Ltd) <camelotdev@xara.com>
04537     Created:    11/04/95
04538     Inputs:     pAttr - the object specifying the colour to use.
04539                 Tmp - indicates if pAttr points to a temporary attribute that should be
04540                       deleted when it's finished with.
04541     Purpose:    Set the current Text Script according to an AttributeValue object, 
04542                 pushing the current Script onto the context stack.
04543     SeeAlso:    RenderRegion::RestoreTxtScript
04544 
04545 ********************************************************************************************/
04546 
04547 void RenderRegion::SetTxtScript(TxtScriptAttribute *pAttr, BOOL Temp)
04548 {
04549     // Save the current attribute and set up the new one
04550     if (SaveAttribute(ATTR_TXTSCRIPT, (AttributeValue*)pAttr, Temp))
04551     {
04552         SetTextAttributes(CHANGEATTR_SCRIPT);
04553     }
04554 }
04555 
04556 /********************************************************************************************
04557 
04558 >   void RenderRegion::RestoreTxtScript(TxtScriptAttribute *pAttr, BOOL Temp)
04559 
04560     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04561     Created:    13/03/95
04562     Inputs:     pAttr - the object specifying the colour to use.
04563                 Tmp - indicates if pAttr points to a temporary attribute that should be
04564                       deleted when it's finished with.
04565     Purpose:    Get rid of the current Text Script, and restore the specified 
04566                 Script value.
04567     SeeAlso:    RenderRegion::SetTxtScript
04568 
04569 ********************************************************************************************/
04570 
04571 void RenderRegion::RestoreTxtScript(TxtScriptAttribute *pAttr, BOOL Temp)
04572 {
04573     // Restore the Text Script attribute
04574     RestoreAttribute(ATTR_TXTSCRIPT, (AttributeValue*)pAttr, Temp);
04575     SetTextAttributes(CHANGEATTR_SCRIPT);
04576 }
04577 
04578 
04579 /********************************************************************************************
04580 
04581 >   void RenderRegion::SetTxtBaseLine(TxtBaseLineAttribute *pAttr, BOOL Temp)
04582 
04583     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04584     Created:    13/03/95
04585     Inputs:     pAttr - the object specifying the colour to use.
04586                 Tmp - indicates if pAttr points to a temporary attribute that should be
04587                       deleted when it's finished with.
04588     Purpose:    Set the current Text BaseLine according to an AttributeValue object, 
04589                 pushing the current BaseLine onto the context stack.
04590     SeeAlso:    RenderRegion::RestoreTxtBaseLine
04591 
04592 ********************************************************************************************/
04593 
04594 void RenderRegion::SetTxtBaseLine(TxtBaseLineAttribute *pAttr, BOOL Temp)
04595 {
04596     // Save the current attribute and set up the new one
04597     if (SaveAttribute(ATTR_TXTBASELINE, (AttributeValue*)pAttr, Temp))
04598     {
04599         SetTextAttributes(CHANGEATTR_BASELINE);
04600     }
04601 }
04602 
04603 /********************************************************************************************
04604 
04605 >   void RenderRegion::RestoreTxtBaseLine(TxtBaseLineAttribute *pAttr, BOOL Temp)
04606 
04607     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04608     Created:    13/03/95
04609     Inputs:     pAttr - the object specifying the colour to use.
04610                 Tmp - indicates if pAttr points to a temporary attribute that should be
04611                       deleted when it's finished with.
04612     Purpose:    Get rid of the current Text BaseLine, and restore the specified 
04613                 BaseLine value.
04614     SeeAlso:    RenderRegion::SetTxtBaseLine
04615 
04616 ********************************************************************************************/
04617 
04618 void RenderRegion::RestoreTxtBaseLine(TxtBaseLineAttribute *pAttr, BOOL Temp)
04619 {
04620     // Restore the Text BaseLine attribute
04621     RestoreAttribute(ATTR_TXTBASELINE, (AttributeValue*)pAttr, Temp);
04622     SetTextAttributes(CHANGEATTR_BASELINE);
04623 }
04624 
04625 
04626 /********************************************************************************************
04627 
04628 >   void RenderRegion::SetTxtLineSpace(TxtLineSpaceAttribute *pAttr, BOOL Temp)
04629 
04630     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04631     Created:    13/03/95
04632     Inputs:     pAttr - the object specifying the colour to use.
04633                 Tmp - indicates if pAttr points to a temporary attribute that should be
04634                       deleted when it's finished with.
04635     Purpose:    Set the current Text LineSpace according to an AttributeValue object, 
04636                 pushing the current LineSpace onto the context stack.
04637     SeeAlso:    RenderRegion::RestoreTxtLineSpace
04638 
04639 ********************************************************************************************/
04640 
04641 void RenderRegion::SetTxtLineSpace(TxtLineSpaceAttribute *pAttr, BOOL Temp)
04642 {
04643     // Save the current attribute and set up the new one
04644     if (SaveAttribute(ATTR_TXTLINESPACE, (AttributeValue*)pAttr, Temp))
04645     {
04646         SetTextAttributes(CHANGEATTR_LINESPACE);
04647     }
04648 }
04649 
04650 /********************************************************************************************
04651 
04652 >   void RenderRegion::RestoreTxtLineSpace(TxtLineSpaceAttribute *pAttr, BOOL Temp)
04653 
04654     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
04655     Created:    13/03/95
04656     Inputs:     pAttr - the object specifying the colour to use.
04657                 Tmp - indicates if pAttr points to a temporary attribute that should be
04658                       deleted when it's finished with.
04659     Purpose:    Get rid of the current Text LineSpace, and restore the specified 
04660                 LineSpace value.
04661     SeeAlso:    RenderRegion::SetTxtLineSpace
04662 
04663 ********************************************************************************************/
04664 
04665 void RenderRegion::RestoreTxtLineSpace(TxtLineSpaceAttribute *pAttr, BOOL Temp)
04666 {
04667     // Restore the Text LineSpace attribute
04668     RestoreAttribute(ATTR_TXTLINESPACE, (AttributeValue*)pAttr, Temp);
04669     SetTextAttributes(CHANGEATTR_LINESPACE);
04670 }
04671 
04672 /********************************************************************************************
04673 
04674 >   void RenderRegion::Set/RestoreTxtxxx(TxtXXXAttribute *pAttr, BOOL Temp)
04675 
04676     Author:     Martin Wuerthner <xara@mw-software.com>
04677     Created:    13/06/06
04678     Inputs:     See other Set/Restore routines above
04679     Purpose:    See other Set/Restore routines above
04680 
04681 ********************************************************************************************/
04682 
04683 void RenderRegion::SetTxtLeftMargin(TxtLeftMarginAttribute *pAttr, BOOL Temp)
04684 {
04685     // Save the current attribute and set up the new one
04686     if (SaveAttribute(ATTR_TXTLEFTMARGIN, (AttributeValue*)pAttr, Temp))
04687     {
04688         SetTextAttributes(CHANGEATTR_LEFTMARGIN);
04689     }
04690 }
04691 
04692 void RenderRegion::RestoreTxtLeftMargin(TxtLeftMarginAttribute *pAttr, BOOL Temp)
04693 {
04694     // Restore the attribute
04695     RestoreAttribute(ATTR_TXTLEFTMARGIN, (AttributeValue*)pAttr, Temp);
04696     SetTextAttributes(CHANGEATTR_LEFTMARGIN);
04697 }
04698 
04699 void RenderRegion::SetTxtRightMargin(TxtRightMarginAttribute *pAttr, BOOL Temp)
04700 {
04701     // Save the current attribute and set up the new one
04702     if (SaveAttribute(ATTR_TXTRIGHTMARGIN, (AttributeValue*)pAttr, Temp))
04703     {
04704         SetTextAttributes(CHANGEATTR_RIGHTMARGIN);
04705     }
04706 }
04707 
04708 void RenderRegion::RestoreTxtRightMargin(TxtRightMarginAttribute *pAttr, BOOL Temp)
04709 {
04710     // Restore the attribute
04711     RestoreAttribute(ATTR_TXTRIGHTMARGIN, (AttributeValue*)pAttr, Temp);
04712     SetTextAttributes(CHANGEATTR_RIGHTMARGIN);
04713 }
04714 
04715 void RenderRegion::SetTxtFirstIndent(TxtFirstIndentAttribute *pAttr, BOOL Temp)
04716 {
04717     // Save the current attribute and set up the new one
04718     if (SaveAttribute(ATTR_TXTFIRSTINDENT, (AttributeValue*)pAttr, Temp))
04719     {
04720         SetTextAttributes(CHANGEATTR_FIRSTINDENT);
04721     }
04722 }
04723 
04724 void RenderRegion::RestoreTxtFirstIndent(TxtFirstIndentAttribute *pAttr, BOOL Temp)
04725 {
04726     // Restore the attribute
04727     RestoreAttribute(ATTR_TXTFIRSTINDENT, (AttributeValue*)pAttr, Temp);
04728     SetTextAttributes(CHANGEATTR_FIRSTINDENT);
04729 }
04730 
04731 void RenderRegion::SetTxtRuler(TxtRulerAttribute *pAttr, BOOL Temp)
04732 {
04733     // Save the current attribute and set up the new one
04734     if (SaveAttribute(ATTR_TXTRULER, (AttributeValue*)pAttr, Temp))
04735     {
04736         SetTextAttributes(CHANGEATTR_RULER);
04737     }
04738 }
04739 
04740 void RenderRegion::RestoreTxtRuler(TxtRulerAttribute *pAttr, BOOL Temp)
04741 {
04742     // Restore the attribute
04743     RestoreAttribute(ATTR_TXTRULER, (AttributeValue*)pAttr, Temp);
04744     SetTextAttributes(CHANGEATTR_RULER);
04745 }
04746 
04747 /********************************************************************************************
04748 >   virtual void RenderRegion::SetOffscreen(OffscreenAttrValue* pAttr)
04749     Author:     Ilan_Copelyn (Xara Group Ltd) <camelotdev@xara.com>
04750     Created:    25/1/2000
04751     Inputs:     pAttr   the offscreen attribute (eg AttrFeatherValue) to use.
04752 
04753     Purpose:    Uses attribute stacking to offscreen rendering system notified when
04754                 offscreen bitmap has been rendered (ie occurs when subtree is finished
04755                 rendering and attributes are being restored)
04756 
04757     SeeAlso:    RenderRegion::SaveAttribute;
04758 ********************************************************************************************/
04759 /*void RenderRegion::SetOffscreen(OffscreenAttrValue* pAttr)
04760 {
04761     // Push the current offscreen attribute onto the stack, and install the new attribute as
04762     // the 'current' one. (taken from RenderRegion::SaveAttribute)
04763     // NB I can't imagine a circumstance where you would want to render a Temp offscreen
04764     // attribute so I am forcing Temp = FALSE here
04765     if (TheStack.Push((AttributeValue*)CurrentOffscreenAttr, FALSE))
04766     {
04767         CurrentOffscreenAttr = pAttr;
04768     }
04769 }*/
04770 
04771 void RenderRegion::SetOffscreen(OffscreenAttrValue* pAttr)
04772 {
04773 //  TRACEUSER( "Gerry", _T("RenderRegion::SetOffscreen (0x%08x)\n"), pAttr);
04774 
04775     // Karim 23/07/2000
04776     // Mustn't have feathering overhead for hit-testing, so
04777     // don't bother doing anything if we're a hit-test RR.
04778     if (IsHitDetect())
04779         return;
04780 
04781     // Karim 23/07/2000
04782     // Don't bother with feathering at all if our quality setting is too low.
04783     // Note: this test should probably be made in a Feather override of a Node vfn.
04784     if (RRQuality.GetFillQuality() < Quality::Graduated)
04785         return;
04786 
04787     //---------------------------------------------
04788     // Karim 20/07/2000
04789     // Moved from OffscreenAttrValue::Render(), to avoid checks for render-region types
04790     // in the feathering code.
04791     // The following code works out and sets the offscreen attr's
04792     // offscreen bounding box.
04793 
04794     // Invalid area = intersection of node's and render-region's bounding rects.
04795     //
04796     // Notes:   1.  Inflate the node's bounding rect slightly, so it _completely_
04797     //              encloses the node (sometimes it doesn't quite).
04798     //          2.  Inflate the RR's clip-rect slightly, so that we don't get
04799     //              anti-aliasing edge artifacts in the final feather-bmp render.
04800     //          3.  If printing, then use the GRR's inner rect instead of its clipping
04801     //              rect, to fix stripey printing of feathers.
04802     //              This BODGE is necessary because for some reason CurrentClipRect
04803     //              does not cover a GRR's whole bitmap when printing !?!?
04804 //  MILLIPOINT LargePixelWidth = (MILLIPOINT)ceil(GetScaledPixelWidthDouble());
04805     MILLIPOINT LargePixelWidth = GetScaledPixelWidth();
04806     DocRect NodeBB  = pAttr->GetLinkedNode()->GetBoundingRect();
04807     NodeBB.Inflate( LargePixelWidth );
04808 
04809     DocRect GRegionBB = CurrentClipRect;
04810 // Removed by Phil 2/6/2004
04811 // Seems to be bogus...
04812 //      if (IsPrinting())
04813 //          GRegionBB = InnerRect;
04814 //      else
04815         GRegionBB.Inflate( 2 * LargePixelWidth );
04816 
04817     // If we should be checking the bounds
04818     if (CheckOffscreenBounds())
04819     {
04820         // Then check them
04821         if (!NodeBB.IsIntersectedWith(GRegionBB))
04822             return;
04823     }
04824 
04825     // calculate their intersection.
04826     DocRect drOffBB = NodeBB.Intersection(GRegionBB);
04827 
04828     // Ensure that we have minimum pixel dimensions
04829     // Expand cliprect if more pixels required
04830     // NB expanding by GRR->ScaledPixelWidth will ensure we increase bmp size 
04831     // by exactly the no. of pixels required
04832     UINT32 RequiredWidth, RequiredHeight;
04833     pAttr->GetMinimumOffscreenBmpDimensions(&RequiredWidth,&RequiredHeight);
04834 //  WinRect Rect = CalculateWinRect( drOffBB );
04835     WinRect Rect = OSRenderRegion::DocRectToWin( RenderMatrix, drOffBB, GetPixelsPerInch() );   // NOTE! Use of ScaledPixelWidth in GetPixelsPerInch!
04836     UINT32 ProposedWidth    = Rect.width;
04837     UINT32 ProposedHeight   = Rect.height;
04838     MILLIPOINT ScaledPixelWidth = GetScaledPixelWidth();
04839 
04840     // We have to check if the render matrix involves rotation as we have to
04841     // expand the DocRect in the other direction
04842     // First get the components of the matrix
04843     FIXED16 comps[4];
04844     RenderMatrix.GetComponents(comps, NULL);
04845     // It is rotated if a = d = 0 and b = -c
04846     BOOL bRotated = (comps[0] == FIXED16(0) && comps[3] == FIXED16(0) && comps[1] == -comps[2]);
04847     if(ProposedWidth < (UINT32)RequiredWidth)
04848     {
04849         // make the bitmap wider
04850         // For odd pixel differences, widen rightwards by extra pixel
04851         MILLIPOINT ExtraPixelWidth = (MILLIPOINT)(RequiredWidth - ProposedWidth);
04852         MILLIPOINT Decrement = (ExtraPixelWidth / 2) * ScaledPixelWidth;
04853         MILLIPOINT Increment = Decrement + ((ExtraPixelWidth % 2) * ScaledPixelWidth);
04854 
04855         // if there is a rotation involved we have to increase the height of the DocRect
04856         // otherwise we increase the width
04857         if (bRotated)
04858         {
04859             drOffBB.lo.y -= Decrement;
04860             drOffBB.hi.y += Increment;
04861         }
04862         else
04863         {
04864             drOffBB.lo.x -= Decrement;
04865             drOffBB.hi.x += Increment;
04866         }
04867     }
04868 
04869     if (ProposedHeight < (UINT32)RequiredHeight)
04870     {
04871         // make the bitmap taller
04872         // For odd pixel differences, stretch upwards by extra pixel
04873         MILLIPOINT ExtraPixelHeight = (MILLIPOINT)(RequiredHeight - ProposedHeight);
04874         MILLIPOINT Decrement = (ExtraPixelHeight / 2) * ScaledPixelWidth;
04875         MILLIPOINT Increment = Decrement + ((ExtraPixelHeight & 1) * ScaledPixelWidth);
04876 
04877         // if there is a rotation involved we have to increase the width of the DocRect
04878         // otherwise we increase the height
04879         if (bRotated)
04880         {
04881             drOffBB.lo.x -= Decrement;
04882             drOffBB.hi.x += Increment;
04883         }
04884         else
04885         {
04886             drOffBB.lo.y -= Decrement;
04887             drOffBB.hi.y += Increment;
04888         }
04889     }
04890 
04891     pAttr->SetOffscreenBoundingRect(drOffBB);
04892 
04893     //---------------------------------------------
04894     // Now startup the offscreen capture...
04895     // 
04896     // If a non-mix attribute is already in scope we must not start capturing transparently
04897     // because transparent bitmaps can't render non-mix transparencies correctly
04898     // (See SetTranspFillGeometry and ChangeCapture)
04899     //
04900     // If the Master Capture is itself Transparent, then there's nothing we can do to grab
04901     // any non-mix transparencies correctly so test that first (typical case: Create Bitmap Copy)
04902     //
04903     BOOL bStartTransparently = FALSE;
04904     if (LockedTransparentCaptures())
04905         bStartTransparently = TRUE;
04906     else
04907     {
04908         TranspFillAttribute* pTransAttr = (TranspFillAttribute *) GetCurrentAttribute(ATTR_TRANSPFILLGEOMETRY);
04909         UINT32 ttype = pTransAttr->GetTranspType();
04910         bStartTransparently = (ttype==TT_NoTranspType || ttype==TT_Mix);
04911         // Also, scan down into the tree and see whether this node has any non-mix that would
04912         // cause us to revert to non-transparent capture
04913         // Because it's (probably) quicker to scan the tree than to revert during rendering...
04914         // Urgh.
04915         NodeRenderableInk* pLinkedNode = pAttr->GetLinkedNode()->IsAnObject() ? (NodeRenderableInk*)pAttr->GetLinkedNode() : NULL;
04916         bStartTransparently = bStartTransparently && !(pLinkedNode && pLinkedNode->ContainsNonMixTransparency(this));
04917     }
04918 
04919     Capture* pCapture = StartCapture(pAttr,
04920                                     drOffBB,
04921                                     CAPTUREINFO(ctNESTABLE, cfNONE + cfDEBUG),      // Don't allow collapse to master bitmap, CollapseToMaster=0
04922                                     bStartTransparently,
04923                                     !bStartTransparently
04924                                     );
04925     if (pCapture==NULL)
04926         return;
04927 
04928     // Save pointer to OffscreenAttr, and move current OffscreenAttr to the attr context stack
04929 //  RenderRegion::SetOffscreen(pAttr);
04930 
04931     // Push the current offscreen attribute onto the stack, and install the new attribute as
04932     // the 'current' one. (taken from RenderRegion::SaveAttribute)
04933     // NB I can't imagine a circumstance where you would want to render a Temp offscreen
04934     // attribute so I am forcing Temp = FALSE here
04935     if (TheStack.Push((AttributeValue*)CurrentOffscreenAttr, FALSE))
04936         CurrentOffscreenAttr = pAttr;
04937 }
04938 
04939 
04940 
04941 /********************************************************************************************
04942 >   virtual void RenderRegion::RestoreOffscreen(OffscreenAttrValue* pAttr)
04943     Author:     Ilan_Copelyn (Xara Group Ltd) <camelotdev@xara.com>
04944     Created:    25/1/2000
04945     Inputs:     pAttr   - the object specifying the new feather
04946     Purpose:    Inform current offscreen attribute that its offscreen bmp has been rendered,
04947                 and restore the one supplied
04948     SeeAlso:    RenderRegion::RestoreAttribute
04949 ********************************************************************************************/
04950 /*void RenderRegion::RestoreOffscreen(OffscreenAttrValue* pAttr)
04951 {
04952     // Restore the old attribute.
04953     CurrentOffscreenAttr = pAttr; 
04954 }*/
04955 
04956 
04957 
04958 void RenderRegion::RestoreOffscreen(OffscreenAttrValue* pAttr)
04959 {
04960     // End this capture:
04961     // Don't render captured bitmap back into render region - owner will do that after processing
04962     // Release bitmap here - if this region is being reset
04963     if (!IsBeingReset)
04964     {
04965         LPBITMAPINFO lpCapturedBitmapInfo = NULL;
04966         LPBYTE lpCapturedBits = NULL;
04967         DocRect CaptureRect = CurrentOffscreenAttr->GetOffscreenBoundingRect(); // Initialise to size of feathered object
04968                                                                 // so that StopCapture can return sensible 24BPP bitmap if needed
04969         Capture* pTopCapture = GetTopCapture();
04970         ENSURE(pTopCapture && pTopCapture->GetOwner()==CurrentOffscreenAttr, "RestoreOffscreen attr is not owned by top capture\n");
04971         if (pTopCapture && pTopCapture->GetOwner()==CurrentOffscreenAttr)
04972         {
04973             StopCapture(CurrentOffscreenAttr, FALSE, IsBeingReset, &lpCapturedBitmapInfo, &lpCapturedBits, &CaptureRect);
04974         }
04975 
04976         // Normal restore in process of traversing the tree
04977         // So tell the offscreen attribute to handle the captured bitmap as it sees fit...
04978         CurrentOffscreenAttr->OffscreenRenderingCompleted(this, lpCapturedBitmapInfo, lpCapturedBits, CaptureRect);
04979     }
04980 
04981 //  RenderRegion::RestoreOffscreen(pAttr);
04982 
04983     CurrentOffscreenAttr = pAttr; 
04984 }
04985 
04986 
04987 /********************************************************************************************
04988 
04989 >   void RenderRegion::SetClipRegion(ClipRegionAttribute* pAttr, BOOL Temp)
04990 
04991     Author:     Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
04992     Created:    11 April 2000
04993     Inputs:     pAttr   the new ClipRegionAttribute.
04994                 Temp    whether the new attribute is temporary, and should therefore be
04995                         deleted when it is finished with.
04996     Purpose:    Set this render-region's current clipping region.
04997     See also:   ClipRegionAttribute::Render(), RenderRegion::RestoreClipRegion().
04998 
04999 ********************************************************************************************/
05000 void RenderRegion::SetClipRegion(ClipRegionAttribute* pAttr, BOOL Temp)
05001 {
05002     SaveAttribute(ATTR_CLIPREGION, (AttributeValue *) pAttr, Temp);
05003 }
05004 
05005 
05006 
05007 /********************************************************************************************
05008 
05009 >   void RenderRegion::RestoreClipRegion(ClipRegionAttribute* pAttr, BOOL Temp)
05010 
05011     Author:     Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
05012     Created:    11 April 2000
05013     Inputs:     pAttr   the new ClipRegionAttribute.
05014                 Temp    whether the new attribute is temporary, and should therefore be
05015                         deleted when it is finished with.
05016     Purpose:    Restore this render-region's current clipping region, using the attribute 
05017                 supplied.
05018     See also:   ClipRegionAttribute::Restore(), RenderRegion::SetClipRegion().
05019 
05020 ********************************************************************************************/
05021 void RenderRegion::RestoreClipRegion(ClipRegionAttribute* pAttr, BOOL Temp)
05022 {
05023     RestoreAttribute(ATTR_CLIPREGION, (AttributeValue *) pAttr, Temp);
05024 }
05025 
05026 
05027 
05028 /********************************************************************************************
05029 
05030 >   virtual void RenderRegion::DrawFixedSystemText(StringBase *TheText,
05031                                                         DocRect &BoundsRect, UINT32 uFormat)
05032 
05033     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05034     Created:    12/1/95
05035     Inputs:     TheText - The string to render
05036                 BoundsRect - Determines where the text is to be plotted. The text will also
05037                 be clipped within this bounding rectangle if it exceeds the available space.
05038 
05039     Purpose:    To draw simple text, using the default host-operating-system font.
05040                 The size and style of this font are decided by the host OS (or oil code)
05041                 and cannot be set in any way. To determine how much space is needed to
05042                 display a string with this method, see the SeeAlso.
05043 
05044     Notes:      THIS BASE CLASS METHOD IS UNSUPPORTED! DO NOT CALL IT!
05045                 See OSRenderRegion for the supported versions of this method
05046 
05047     SeeAlso:    OSRenderRegion::DrawFixedSystemText
05048     SeeAlso:    OSRenderRegion::GetFixedSystemTextSize
05049 
05050 ********************************************************************************************/
05051 
05052 void RenderRegion::DrawFixedSystemText(StringBase *TheText, DocRect &BoundsRect, UINT32 uFormat)
05053 {
05054     ERROR2RAW("Attempt to call unsupported RenderRegion::DrawFixedSystemText method");
05055 }
05056 
05057 
05058 
05059 /********************************************************************************************
05060 
05061 >   virtual void RenderRegion::SetFixedSystemTextColours(DocColour *TextCol,
05062                                                          DocColour *Background)
05063 
05064     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05065     Created:    12/1/95
05066     Inputs:     TextCol - The foreground (text) colour (may be NULL)
05067                 Background - The background colour (may be NULL)
05068 
05069     Purpose:    To set the text and background colour(s) for any FixedSystem text rendered
05070                 in this render region in the future (within the current rendering pass).
05071 
05072     Notes:      THIS BASE CLASS METHOD IS UNSUPPORTED! DO NOT CALL IT!
05073                 See OSRenderRegion for the supported versions of this method
05074 
05075                 If either of the colours is passed in as a NULL pointer, that colour will
05076                 not be set, and will remain at the previous setting.
05077 
05078                 Note that these values are passed directly to the host OS at the point
05079                 of calling, so you must call this method every time the colour is changed
05080                 (i.e. don't rely on just changing the DocColours that you passed in
05081                 originally, as they aren't remembered in any way). Note also that if you
05082                 call DrawFixedSystemText without a prior call to this method, the colours
05083                 used are undefined.
05084 
05085     SeeAlso:    OSRenderRegion::DrawFixedSystemText
05086 
05087 ********************************************************************************************/
05088 
05089 void RenderRegion::SetFixedSystemTextColours(DocColour *TextCol, DocColour *Background)
05090 {
05091     ERROR2RAW("Attempt to call unsupported RenderRegion::SetFixedSystemTextColours method");
05092 }
05093 
05094 
05095 
05096 /********************************************************************************************
05097 
05098 >   virtual void RenderRegion::GetFixedSystemTextSize(StringBase *TheText,
05099                                                         DocRect *BoundsRect)
05100 
05101     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05102     Created:    12/1/95
05103     Inputs:     TheText - The string to get the rendered size of
05104 
05105     Outputs:    BoundsRect - Returned with the size of the rectangle needed to display
05106                 said text string. This rect always has one corner at (0,0)
05107     Returns:    -
05108 
05109     Purpose:    To determine how much room is needed to plot a bit of text with
05110                 RenderRegion::DrawFixedSystemText
05111 
05112     Notes:      THIS BASE CLASS METHOD IS UNSUPPORTED! DO NOT CALL IT!
05113                 See OSRenderRegion for the supported versions of this method
05114 
05115     SeeAlso:    OSRenderRegion::DrawFixedSystemText
05116     SeeAlso:    OSRenderRegion::GetFixedSystemTextSize
05117 
05118 ********************************************************************************************/
05119 
05120 void RenderRegion::GetFixedSystemTextSize(StringBase *TheText, DocRect *BoundsRect, double* atDpi)
05121 {
05122     if (BoundsRect != NULL)
05123         *BoundsRect = DocRect(0,0,0,0);
05124 
05125     ERROR2RAW("Attempt to call unsupported RenderRegion::GetFixedSystemTextSize method");
05126 }
05127 
05128 
05129 
05130 /********************************************************************************************
05131 
05132 >   void RenderRegion::DrawPath(Path *pPath, PathProcessor *pCaller = NULL, PathShape shapePath=PATHSHAPE_PATH)
05133 
05134     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05135     Created:    19/12/96
05136     Inputs:     pPath   - Points to the path to be rendered
05137                 pCaller - NULL, or if you're calling this from a path processor,
05138                           pass your 'this' pointer in here to support the recursion
05139                 shapePath - (Graham 14/4/97)
05140                             A tag which describes what shape the path is.
05141 
05142                             For example, if shapeThis=PATHSHAPE_RECTANGLE, then
05143                             RenderRegions that want to treat rectangles
05144                             differently can do so.
05145 
05146                             Ideally we should replace this so that rectangles
05147                             are rendered by calling the DrawRect function, circles
05148                             by calling the DrawCircle function, and so on.
05149 
05150     Purpose:    Renders a path (main entry-point).
05151                 May start a binary-recursive rendering pipeline off by calling
05152                 any active path processors to do their stuff.
05153 
05154     SeeAlso:    RenderRegion::DrawPathToOutputDevice
05155 
05156 ********************************************************************************************/
05157 
05158 void RenderRegion::DrawPath(Path *pPath, PathProcessor *pCaller, PathShape shapePath)
05159 {
05160     ERROR3IF(pPath == NULL, "Illegal NULL param");
05161 
05162     PathProcessor *pNextProcessor = NULL;
05163     if (pCaller == NULL)
05164     {
05165         pNextProcessor = PathProcessorStack;                    // First call
05166     }
05167     else
05168     {
05169         pNextProcessor = pCaller->GetNextProcessor();           // Recursive call
05170     }
05171 
05172     // see if any of our processors actually do anything
05173     while (pNextProcessor != NULL && (!pNextProcessor->DoesActuallyDoAnything(this)))
05174     {
05175         pNextProcessor = pNextProcessor->GetNextProcessor();
05176     }
05177 
05178     // we seem to be getting problems with two path processor brushes on the stack
05179     // if we blend between a brush and a bevel
05180     if (pNextProcessor != NULL && pCaller != NULL &&
05181         pNextProcessor->IsAPathProcessorBrush() && pCaller->IsAPathProcessorBrush())
05182     {
05183         BrushHandle ThisHandle = ((PathProcessorBrush*)pCaller)->GetBrushDefinitionHandle();
05184         BrushHandle NextHandle = ((PathProcessorBrush*)pNextProcessor)->GetBrushDefinitionHandle();
05185         if (NextHandle == ThisHandle)
05186             pNextProcessor = NULL;
05187     }
05188 
05189     // If we found another PathProcessor to call, recursively call it
05190     if (pNextProcessor != NULL)
05191     {
05192         // Does the processor change both fill & stroke independently?
05193         if (pNextProcessor->WillChangeFillAndStrokeSeparately())
05194         {
05195             // Remember current path settings - we have to poke it directly
05196             // to be efficient about changing it.
05197             BOOL WasFilled  = pPath->IsFilled;
05198             BOOL WasStroked = pPath->IsStroked;
05199 
05200             // Call the PathProcessor to only fill the path, if it is filled.
05201             // There's a hideous special case in here for non-contoned bitmaps (which have a 
05202             // fill colour of TRANSPARENT! Arrrrgh!)
05203             if (WasFilled &&
05204                 (!RR_FILLCOLOUR().IsTransparent() ||
05205                  ((ColourFillAttribute   *) CurrentAttrs[ATTR_FILLGEOMETRY].pAttr)->IsABitmapFill()
05206                 )
05207                )
05208             {
05209                 pPath->IsStroked = FALSE;
05210                 pPath->IsFilled = TRUE;
05211                 pNextProcessor->ProcessPath(pPath, this, shapePath);
05212             }
05213 
05214             // And then call it again to only stroke the path
05215             if (WasStroked && !RR_STROKECOLOUR().IsTransparent())
05216             {
05217                 pPath->IsStroked = TRUE;
05218                 pPath->IsFilled = FALSE;
05219                 pNextProcessor->ProcessPath(pPath, this, shapePath);
05220             }
05221             
05222             // Restore previous path settings
05223             pPath->IsFilled  = WasFilled;
05224             pPath->IsStroked = WasStroked;
05225             return;
05226         }
05227 
05228         // It can be passed through as a single path
05229         pNextProcessor->ProcessPath(pPath, this, shapePath);
05230         return;
05231     }
05232 
05233 
05234     // We have now called any active path processors, so simply output the final
05235     // path to the output device
05236 
05237     //Graham 14/4/97: Also pass along the PathShape parameter to let the renderregion
05238     //know if the path is a special shape
05239     DrawPathToOutputDevice(pPath, shapePath);
05240 }
05241 
05242 
05243 
05244 /********************************************************************************************
05245 
05246 >   void RenderRegion::PushPathProcessor(PathProcessor *pProcessor)
05247 
05248     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05249     Created:    20/12/96
05250     Inputs:     pProcessor - the processor to push onto the processor stack
05251                 THIS PROCESSOR IS NOW OWNED BY THE RENDER REGION and will be
05252                 deleted when it is popped.
05253 
05254     Purpose:    Adds a PathProcessor to the rendering PathProcessor stack
05255 
05256     Notes:      The render region must be supplied a new PathProcessor every
05257                 time you push one, because PathProcessors generally have an
05258                 internal state, and this must be preserved when background
05259                 rendering or multi-threading causes the same thing to be 
05260                 rendered "simultaneously".
05261 
05262     SeeAlso:    PathProcessor; RenderRegion::PopPathProcessor
05263 
05264 ********************************************************************************************/
05265 
05266 void RenderRegion::PushPathProcessor(PathProcessor *pProcessor)
05267 {
05268     ERROR3IF(pProcessor == NULL, "Illegal NULL param");
05269 
05270 
05271 #if _DEBUG
05272     // BLOCK
05273     {
05274         // In debug builds, scan the entire PathProcessor stack, checking that this
05275         // processor is ot already in it.
05276         ERROR3IF(pProcessor->GetNextProcessor() != NULL,
05277                     "PushPathProcessor - processor is already in a stack");
05278         PathProcessor *pPP = PathProcessorStack;
05279         while (pPP != NULL)
05280         {
05281 //          TRACEUSER( "Jason", _T("  "));      // More indent for each processor on the stack
05282             ERROR3IF(pPP == pProcessor, "PushPathProcessor - Processor pushed TWICE!");
05283             pPP = pPP->GetNextProcessor();
05284         }
05285     }
05286 
05287 //  TRACEUSER( "Jason", _T("  >> PushPathProcessor %x\n"), pProcessor);
05288 #endif
05289 
05290     if (pProcessor != NULL)
05291     {
05292         pProcessor->SetNextProcessor(PathProcessorStack);       // Make TOS the second
05293         PathProcessorStack = pProcessor;                        // And point TOS at new item
05294     }
05295 }
05296 
05297 
05298 
05299 /********************************************************************************************
05300 
05301 >   void RenderRegion::PopPathProcessor(void)
05302 
05303     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05304     Created:    20/12/96
05305 
05306     Purpose:    Pops a PathProcessor from the top of the rendering PathProcessor stack
05307 
05308     Notes:      The PathProcessor is deleted after being popped.
05309 
05310     SeeAlso:    PathProcessor; RenderRegion::PushPathProcessor
05311 
05312 ********************************************************************************************/
05313 
05314 void RenderRegion::PopPathProcessor(void)
05315 {
05316 #if _DEBUG
05317     // BLOCK
05318     {
05319         PathProcessor *pPP = PathProcessorStack;
05320         while (pPP != NULL)
05321         {
05322 //          TRACEUSER( "Jason", _T("  "));      // More indent for each processor on the stack
05323             pPP = pPP->GetNextProcessor();
05324         }
05325 
05326 //      TRACEUSER( "Jason", _T("<< PopPathProcessor %x\n"), PathProcessorStack);
05327     }
05328 #endif
05329 
05330 
05331     PathProcessor *TOS = PathProcessorStack;
05332 
05333     if (TOS != NULL)
05334     {
05335         PathProcessorStack = TOS->GetNextProcessor();   // Link TOS to 2nd processor in chain
05336         TOS->SetNextProcessor(NULL);                    // And make the popped one "clean"
05337 
05338         // Finally, delete the path processor
05339         delete TOS;
05340     }
05341 }
05342 
05343 /********************************************************************************************
05344 
05345 >   void RenderRegion::EnableAllBrushPathProcessors(BOOL Enable)
05346 
05347     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05348     Created:    20/12/96
05349     Inputs:     Enable - whether we wish to enable the processors or not
05350 
05351     Purpose:    Enables or disables all the brush path processors on the stack.
05352 
05353 ********************************************************************************************/
05354 
05355 void RenderRegion::EnableAllBrushPathProcessors(BOOL Enable)
05356 {
05357     PathProcessor* pPP = PathProcessorStack;
05358 
05359     while (pPP != NULL)
05360     {
05361         if (pPP->IsAPathProcessorBrush())
05362             pPP->SetDisabled(!Enable);
05363         pPP = pPP->GetNextProcessor();
05364     }
05365 }
05366 
05367 /********************************************************************************************
05368 
05369 >   BOOL RenderRegion::DrawPathArrowHeads(DocCoord* Coords, PathVerb* Verbs, INT32 NumCoords)
05370 
05371     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05372     Created:    3/4/95
05373     Inputs:     The path to render the arrow heads onto.
05374     Purpose:    Draws arrows heads on the start or end of an open path,
05375                 according to the current ArrowHead Attributes.
05376     SeeAlso:    -
05377 
05378 ********************************************************************************************/
05379 
05380 BOOL RenderRegion::DrawPathArrowHeads(DocCoord* Coords, PathVerb* Verbs, INT32 NumCoords)
05381 {
05382     BOOL ArrowRendered = FALSE;
05383 
05384     if (!RR_STARTARROW().IsNullArrow())
05385     {
05386         INT32 PathIndex = 0;
05387         DocCoord ArrowCentre;
05388         DocCoord ArrowDirection;
05389         DocCoord ArrowBase;
05390 
05391         // Find the first position of an ArrowHead
05392         BOOL GotPos = ArrowRec::GetFirstArrowPos(TRUE,
05393                                                  Coords, Verbs, NumCoords, 
05394                                                  &PathIndex, &ArrowCentre, &ArrowDirection);
05395 
05396         while (GotPos)
05397         {
05398             DrawArrowHead(RR_STARTARROW(), ArrowCentre, ArrowDirection, &ArrowBase);
05399 
05400             // DMc Update 25/2/99 so that arrows are drawn on the path - not after it !
05401             // find the coord which caused the arrow to be drawn
05402             BOOL bFound = FALSE;
05403 
05404             INT32 i;
05405             for (i = PathIndex - 1  ; i >= 0 && !bFound; i--)
05406             {
05407                 if (Verbs[i] == PT_MOVETO)
05408                 {
05409                     bFound = TRUE;
05410                 }
05411             }
05412 
05413             if (bFound && !(RR_STARTARROW().m_bExtendPath))
05414             {
05415                 // move the coord in the path back by arrow size
05416                 Coords[i+1].x = ArrowBase.x;
05417                 Coords[i+1].y = ArrowBase.y;                        
05418             }
05419 
05420             ArrowRendered = TRUE;
05421 
05422             // Find the next Arrow position (if there are any more subpaths)
05423             GotPos = ArrowRec::GetNextArrowPos(TRUE,
05424                                                Coords, Verbs, NumCoords, 
05425                                                &PathIndex, &ArrowCentre, &ArrowDirection);
05426         }
05427     }
05428 
05429     if (!RR_ENDARROW().IsNullArrow())
05430     {
05431         INT32 PathIndex = 0;
05432         DocCoord ArrowCentre;
05433         DocCoord ArrowDirection;
05434         DocCoord ArrowBase;
05435 
05436         // Find the first position of an ArrowHead
05437         BOOL GotPos = ArrowRec::GetFirstArrowPos(FALSE,
05438                                                  Coords, Verbs, NumCoords, 
05439                                                  &PathIndex, &ArrowCentre, &ArrowDirection);
05440         while (GotPos)
05441         {
05442             DrawArrowHead(RR_ENDARROW(), ArrowCentre, ArrowDirection, &ArrowBase);
05443 
05444             // move the coordinate on the path
05445             if (!(RR_ENDARROW().m_bExtendPath))
05446             {
05447                 Coords[PathIndex-1].x = ArrowBase.x;
05448                 Coords[PathIndex-1].y = ArrowBase.y;
05449             }
05450 
05451             ArrowRendered = TRUE;
05452 
05453             // Find the next Arrow position (if there are any more subpaths)
05454             GotPos = ArrowRec::GetNextArrowPos(FALSE,
05455                                                Coords, Verbs, NumCoords, 
05456                                                &PathIndex, &ArrowCentre, &ArrowDirection);
05457         }
05458     }
05459 
05460     return ArrowRendered;
05461 }
05462 
05463 /********************************************************************************************
05464 
05465 >   BOOL RenderRegion::DrawArrowHead(ArrowRec &ArrowToDraw,
05466                                      DocCoord &Centre, DocCoord &Direction)
05467 
05468     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05469     Created:    3/4/95
05470     Inputs:     An ArrowRec defining the Arrowhead, the Centre point of the Arrow and a 
05471                 point defining the direction of the Arrow.
05472     Purpose:    Draw an Arrow head on the start or end of a line.
05473     SeeAlso:    -
05474 
05475 ********************************************************************************************/
05476 
05477 BOOL RenderRegion::DrawArrowHead(ArrowRec &ArrowToDraw,
05478                                  DocCoord &Centre, DocCoord &Direction, DocCoord * RetnCentre)
05479 {
05480     // Get a matrix to transform the Arrow
05481     Trans2DMatrix Trans;
05482     ArrowToDraw.GetArrowMatrix(Centre, Direction, RR_LINEWIDTH(), &Trans);
05483 
05484     // Get the current Render Matrix, and merge the arrow head
05485     // matrix with it.
05486 //  Matrix NewRenderMatrix = Trans.GetMatrix();
05487 //  NewRenderMatrix *= RenderMatrix;
05488 
05489     Path* TransPath = new Path();
05490     if (TransPath == NULL)
05491         return FALSE;
05492 
05493     BOOL    ok = TransPath->Initialise(ArrowToDraw.ArrowShape->GetNumCoords());
05494     if (ok) ok = TransPath->CopyPathDataFrom(ArrowToDraw.ArrowShape);
05495 
05496     if (!ok)
05497     {
05498         // Tidy up if we failed
05499         delete TransPath;
05500         return FALSE;
05501     }
05502 
05503     // calculate the start point of the arrow & put it into RetnCentre
05504     DocCoord Base;
05505     ArrowToDraw.GetArrowBase(&Base);
05506     
05507     Trans.Transform(&Base, 1);
05508 
05509     if (RetnCentre)
05510     {
05511         *RetnCentre = Base;
05512     }
05513 
05514     Trans.Transform(TransPath->GetCoordArray(), 
05515                     TransPath->GetNumCoords() );
05516 
05517     SaveContext();  // We have to change the Line and Fill colours
05518 
05519     // First make sure we don't try and draw Arrows on our Arrow heads !!!
05520     BOOL OldStartArrowState = RR_STARTARROW().IsNull;               
05521     BOOL OldEndArrowState   = RR_ENDARROW().IsNull;             
05522     RR_STARTARROW().IsNull = TRUE;              
05523     RR_ENDARROW().IsNull   = TRUE;          
05524 
05525     // Set the fill colour to the line colour and the line colour to transparent
05526     SetFillColour(RR_STROKECOLOUR());
05527     SetLineColour(COLOUR_TRANS);
05528 
05529     // Now set the Fill transparency to be a flat transparency, the
05530     // same as the current line transparency.
05531     FlatTranspFillAttribute* pAttr = new FlatTranspFillAttribute;
05532     pAttr->SetStartTransp(RR_STROKETRANSP()->GetStartTransp());
05533     pAttr->SetTranspType(RR_STROKETRANSP()->GetTranspType());
05534     SetTranspFillGeometry(pAttr, TRUE);
05535 
05536     // Make sure the Arrow Path is valid.
05537 //  ArrowToDraw.ArrowShape->IsFilled  = TRUE;
05538 //  ArrowToDraw.ArrowShape->IsStroked = FALSE;
05539     TransPath->IsFilled  = TRUE;
05540     TransPath->IsStroked = FALSE;
05541 
05542     // Draw the Arrow head
05543 //  DrawPath(ArrowToDraw.ArrowShape);
05544 
05545     DrawPath(TransPath);
05546 
05547     RR_STARTARROW().IsNull = OldStartArrowState;                
05548     RR_ENDARROW().IsNull   = OldEndArrowState;          
05549 
05550     RestoreContext();   // Get our Attributes Back.
05551 
05552     // Restore the old Rendering Matrix
05553 
05554     delete TransPath;
05555 
05556     return TRUE;
05557 }
05558 
05559 
05560 BOOL RenderRegion::DrawTransformedBitmap(NodeBitmap *pNodeBitmap)
05561 {
05562     // If we are not drawing complex shapes and this shape is, then return
05563     RRCaps Caps;
05564     GetRenderRegionCaps(&Caps);
05565     if ((!RenderComplexShapes) && (TestForComplexShape(&Caps)))
05566         return TRUE;
05567 
05568     if ((!RenderComplexShapes) && (pNodeBitmap->NeedsTransparency()))
05569         return TRUE;
05570 
05571     KernelBitmap* pkBitmap = pNodeBitmap->GetBitmap();
05572     if (pkBitmap==NULL || pkBitmap->GetWidth()==0 || pkBitmap->GetHeight()==0)
05573         return TRUE;
05574 
05575     // By default, we can't do arbitrarily transformed bitmaps - use a bitmap fill.
05576     SaveContext();
05577 
05578     // No lines on the rectangle
05579     SetLineColour(COLOUR_TRANS);
05580     SetLineWidth(0);
05581 
05582     if (RRQuality.GetFillQuality() == Quality::Bitmaps)
05583     {
05584         // The quality is set to show Bitmaps, with everything else in outline
05585         // mode, so we'll fake this by temorarily setting the quality to 'Solid'
05586         // just while we render this node.
05587 
05588         Quality NewQuality;
05589         NewQuality.SetQuality(31);  // Force solid fills while we render this node
05590 
05591         QualityAttribute* pQualityAttr = new QualityAttribute(NewQuality);
05592         SetQuality(pQualityAttr, TRUE);
05593     }
05594 
05595     // Simple bitmap fill which fills the whole shape
05596     BitmapFillAttribute *pBitmapAttr = new BitmapFillAttribute;
05597     pBitmapAttr->GetBitmapRef()->SetBitmap(pNodeBitmap->GetBitmap());
05598 
05599     if (IsVeryMono() && !pNodeBitmap->NeedsTransparency())
05600     {
05601         // VeryMono, so plot as black (unless it's a masked bitmap)
05602         DocColour ColBlack = COLOUR_BLACK;
05603         pBitmapAttr->SetStartColour(&ColBlack);
05604     }
05605 
05606     // (ChrisG - 7/11/00) Removed as the CanBeContoned bool is not supported. 
05607     //  This default value was stopping derived render regions from overriding
05608     //  this function, so almost all bitmaps were drawn by this code...
05609     // Err no ChrisG the header file used to be CanBeContoned = TRUE
05610     // so we DO RUN THIS CODE all the time ie all bitmaps CAN be contoned (sjk 19/11/00)
05611     else // if(CanBeContoned)
05612     {
05613         if (pNodeBitmap->GetStartColour())
05614             pBitmapAttr->SetStartColour(pNodeBitmap->GetStartColour());
05615     
05616         if (pNodeBitmap->GetEndColour())
05617             pBitmapAttr->SetEndColour(pNodeBitmap->GetEndColour());
05618     }
05619 
05620     DocCoord *Coords = pNodeBitmap->InkPath.GetCoordArray();
05621 
05622     pBitmapAttr->StartPoint = Coords[3];
05623     pBitmapAttr->EndPoint   = Coords[2];
05624     pBitmapAttr->EndPoint2  = Coords[0];
05625 
05626     // Set bitmap attribute, and get the render region to throw it away when it's finished
05627     // with (hence the TRUE parameter).
05628     SetFillGeometry(pBitmapAttr, TRUE);
05629 
05630     // Set the mapping to have no repeat, otherwise we get artifacts at the edges when
05631     // anti-aliasing is enabled (see bug 1391).
05632     FillMappingLinearAttribute *pNoRepeatAttr = new FillMappingLinearAttribute;
05633 
05634     // Repeat value of '3' means 'repeat inverted' (there are no symbolic names for
05635     // these repeat values - shout at Will if you want some!).
05636 //  pNoRepeatAttr->Repeat = 3;
05637     pNoRepeatAttr->Repeat = 0;
05638 
05639     // Set mapping attribute, and get the render region to throw it away when it's finished
05640     // with (hence the TRUE parameter).
05641     SetFillMapping(pNoRepeatAttr, TRUE);
05642 
05643     // Draw the bitmap by rendering a bitmap filled path.
05644     pNodeBitmap->InkPath.IsFilled = TRUE;
05645     DrawPath(&pNodeBitmap->InkPath);
05646 
05647     RestoreContext();
05648 
05649     // All done
05650     return TRUE;
05651 }
05652 
05653 /********************************************************************************************
05654 
05655 >   EFFECTTYPE RenderRegion::GetFillEffect()
05656 
05657     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
05658     Created:    24/8/94
05659     Returns:    TRUE, if should use HSV fades.
05660                 FALSE, if should use RGB fades.
05661     Purpose:    Decide what type of colour fade to use.
05662     Scope:      Public
05663 
05664 ********************************************************************************************/
05665 
05666 EFFECTTYPE RenderRegion::GetFillEffect()
05667 {
05668     // Get the current Fill Effect
05669     FillEffectAttribute* FillEffect = RR_FILLEFFECT();
05670 
05671     // What kind of fill effect is this ?
05672     CCRuntimeClass* Effect = FillEffect->GetRuntimeClass();
05673 
05674     if (Effect == CC_RUNTIME_CLASS(FillEffectFadeAttribute))
05675         return EFFECT_RGB;          // Use RGB space
05676 
05677     if (Effect == CC_RUNTIME_CLASS(FillEffectRainbowAttribute))
05678         return EFFECT_HSV_SHORT;    // Use HSV short path
05679 
05680     if (Effect == CC_RUNTIME_CLASS(FillEffectAltRainbowAttribute))
05681         return EFFECT_HSV_LONG;     // Use HSV INT32 path
05682 
05683     return EFFECT_RGB;              // Default to RGB space 
05684 }
05685 
05686 
05687 
05688 /********************************************************************************************
05689 
05690 >   void RenderRegion::DrawDragBounds(DocRect *RectToRender)
05691 
05692     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
05693     Created:    16/5/95
05694 
05695     Inputs:     RectToRender - The bounding rectangle we wish to render.
05696 
05697     Purpose:    Used to draw a "rectangle" to screen (for dragging). However, the corners of
05698                 the rectangle are passed through the current rendering matrix, so the rect
05699                 may well be rotated or skewed by the time it reaches the screen.
05700 
05701     Notes:      DO NOT confuse this method with DrawDragRect (which will draw a rectangle
05702                 without skew or rotation)
05703 
05704                 OSRenderRegions override this method to provide dotted-line redraw of the
05705                 bounds (note: Not a dash-pattern, a simple on/off pixel dottyness). Note that
05706                 OSRenderRegions CALL THIS METHOD to actually draw the path, so taqke care if
05707                 changing this function.
05708 
05709     SeeAlso:    OSRenderRegion::DrawDragRect; OSRenderRegion::DrawDragBounds;
05710                 Range::RenderXOROutlinesOn
05711 
05712 ********************************************************************************************/
05713 
05714 void RenderRegion::DrawDragBounds(DocRect *RectToRender)
05715 {
05716     Path SquarePath;
05717     SquarePath.Initialise(12, 12);
05718     SquarePath.FindStartOfPath();
05719 
05720     SquarePath.InsertMoveTo(RectToRender->lo);
05721     SquarePath.InsertLineTo(DocCoord(RectToRender->hi.x, RectToRender->lo.y));
05722     SquarePath.InsertLineTo(RectToRender->hi);
05723     SquarePath.InsertLineTo(DocCoord(RectToRender->lo.x, RectToRender->hi.y));
05724     SquarePath.InsertLineTo(RectToRender->lo);
05725     SquarePath.IsFilled = FALSE;
05726 
05727     DrawPath(&SquarePath);
05728 }
05729 
05730 /********************************************************************************************
05731 
05732 >   void RenderRegion::DrawDashLine(const DocCoord &StartPoint, const DocCoord &EndPoint)
05733 
05734     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
05735     Created:    10/10/95
05736     Inputs:     StartPoint  - start of the line
05737                 EndPoint    - end of the line
05738     Purpose:    Draws a dashed line between the two points.
05739                 Uses the technology from DrawDragBounds()
05740 
05741                 NOTE: This is the base class implementation that only partially works.
05742                         Only designed to work correctly in OSRenderRegions
05743 
05744     SeeAlso:    OSRenderRegion::DrawDashLine()
05745 
05746 ********************************************************************************************/
05747 
05748 void RenderRegion::DrawDashLine(const DocCoord &StartPoint, const DocCoord &EndPoint)
05749 {
05750     Path ThePath;
05751     ThePath.Initialise(12, 12);
05752     ThePath.FindStartOfPath();
05753 
05754     ThePath.InsertMoveTo(StartPoint);
05755     ThePath.InsertLineTo(EndPoint);
05756     ThePath.IsFilled = FALSE;
05757 
05758     DrawPath(&ThePath);
05759 }
05760 
05761 /********************************************************************************************
05762 
05763 >   virtual void RenderRegion::DrawPixelRect(DocRect *RectToRender)
05764 
05765     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
05766     Created:    18/1/95
05767     Inputs:     RectToRender - The rectangle we wish to render.
05768     Outputs:    -
05769     Returns:    -
05770     Purpose:    To try and plot a single pixel rectangle outline. It does this by using filled
05771                 rectangles rather than just drawing the line itself. This is required because
05772                 although GDI and GDraw fills can be made to match up, their outlines can't
05773                 (at the time of writing).
05774                 Assumes fill colour and line colour have already been set up along with a line
05775                 width, usually assumed to be zero which means plot single-pixel lines. Usually,
05776                 the fill colour is set to be the required line colour and the line colour is
05777                 set to be transparent (COLOUR_TRANS).
05778     SeeAlso:    OSRenderRegion::DrawRect; GRenderRegion::DrawRect; RenderRegion::DrawPixelLine;
05779 
05780 ********************************************************************************************/
05781 
05782 void RenderRegion::DrawPixelRect(DocRect *RectToRender)
05783 {
05784 // Below is some conditional code.
05785 // The correct code is directly below in the IF clause and just in fact calls the standard
05786 // DrawRect call.
05787 // The bodged version is the code in the ELSE clause and renders the single pixel outline
05788 // using filled rectangles. This is required because although GDI and GDraw fills
05789 // can be made to match up, their outlines can't (at the time of writing).
05790 //
05791 // By the way, Gavin says, it's faster to plot four upright rects than to stroke a path
05792 // to become the outline of the page!!!
05793 //
05794 #if 0
05795         // Draw that page rectangle using the standard call
05796         DrawRect(RectToRender); 
05797 #else
05798         // Get the scaled pixel size for the view
05799         FIXED16 ScaledPixelWidth,
05800                 ScaledPixelHeight;
05801         RenderView->GetScaledPixelSize(&ScaledPixelWidth, &ScaledPixelHeight);
05802 
05803         // Draw a rectangle using 4 filled rectangles.
05804         DocRect VertRect(RectToRender->lo.x,
05805                          RectToRender->lo.y,
05806                          RectToRender->lo.x + ScaledPixelWidth.MakeLong(),
05807                          RectToRender->hi.y + ScaledPixelHeight.MakeLong());
05808         DrawRect(&VertRect);                // Left
05809 
05810         VertRect.Translate(RectToRender->Width(),0);
05811         DrawRect(&VertRect);                // Right
05812 
05813         DocRect HorzRect(RectToRender->lo.x,
05814                          RectToRender->lo.y,
05815                          RectToRender->hi.x,
05816                          RectToRender->lo.y + ScaledPixelHeight.MakeLong());
05817         DrawRect(&HorzRect);                // Bottom
05818 
05819         HorzRect.Translate(0,RectToRender->Height());
05820         DrawRect(&HorzRect);                // Top
05821 #endif
05822 }
05823 
05824 /********************************************************************************************
05825 
05826 >   virtual void RenderRegion::DrawPixelLine(const DocCoord &StartPoint, const DocCoord &EndPoint)
05827 
05828     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
05829     Created:    18/1/95
05830     Inputs:     StartPoint - The starting point to render from.
05831                 EndPoint - The end point to render to.
05832     Outputs:    -
05833     Returns:    -
05834     Purpose:    To try and plot a single pixel line.  It does this by using a filled
05835                 rectangle rather than just drawing the line itself. This is required because
05836                 although GDI and GDraw fills can be made to match up, their outlines can't
05837                 (at the time of writing).
05838                 Assumes fill colour and line colour have already been set up along with a line
05839                 width, usually assumed to be zero which means plot single-pixel lines. Usually,
05840                 the fill colour is set to be the required line colour and the line colour is
05841                 set to be transparent (COLOUR_TRANS).
05842     SeeAlso:    OSRenderRegion::DrawLine; GRenderRegion::DrawLine; RenderRegion::DrawPixelRect;
05843 
05844 ********************************************************************************************/
05845 void RenderRegion::DrawPixelLine(const DocCoord &StartPoint, const DocCoord &EndPoint)
05846 {
05847 // Below is some conditional code.
05848 // The correct code is directly below in the IF clause and just in fact calls the standard
05849 // DrawLine call.
05850 // The bodged version is the code in the ELSE clause and renders the single pixel line
05851 // using a filled rectangle. This is required because although GDI and GDraw fills
05852 // can be made to match up, their outlines can't (at the time of writing).
05853 //
05854 // By the way, Gavin says, it's faster to plot four upright rects than to stroke a path
05855 // to become the outline of the page!!!
05856 //
05857 #if 0
05858         DrawLine(StartPoint, EndPoint); 
05859 #else
05860         // Get the scaled pixel size for the view
05861         FIXED16 ScaledPixelWidth,
05862                 ScaledPixelHeight;
05863         RenderView->GetScaledPixelSize(&ScaledPixelWidth, &ScaledPixelHeight);
05864 
05865         // Draw the line
05866         DocRect VertRect(StartPoint.x,
05867                          StartPoint.y,
05868                          EndPoint.x + ScaledPixelWidth.MakeLong(),
05869                          EndPoint.y + ScaledPixelHeight.MakeLong());
05870         DrawRect(&VertRect);
05871 #endif
05872 }
05873 
05874 
05875 /********************************************************************************************
05876 
05877 >   AttributeValue *RenderRegion::GetCurrentAttribute(UINT32 Index)
05878 
05879     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
05880     Created:    7/2/95
05881     Inputs:     Index - the ID of the attribute to be examined.
05882     Returns:    Pointer to the current attribute of the type requested;
05883                 NULL if the index is out of range.
05884     Purpose:    Get a pointer to one of the render region's current attributes.  The index
05885                 indicates which kind of attribute should be returned.
05886 
05887 ********************************************************************************************/
05888 
05889 AttributeValue *RenderRegion::GetCurrentAttribute(UINT32 Index)
05890 {
05891     // Make sure this is a valid attribute index ID
05892     if (Index < (UINT32)NumCurrentAttrs)
05893         return CurrentAttrs[Index].pAttr;
05894 
05895     // Illegal index - return error
05896     return NULL;
05897 }
05898 
05899 
05900 
05901 
05902 /********************************************************************************************
05903 
05904 >   BOOL RenderRegion::TryToFuzzyClip( Path* pPath, DocCoord* pNewCoords,
05905                                         PathVerb* pNewVerbs, INT32* NewNumCoords)
05906 
05907     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
05908     Created:    9/3/95
05909     Inputs:     pPath - The path to try to clip
05910     Outputs:    pNewCoords - The clipped coords that need rendering
05911                 pNewVerbs - The Clipped set of verbs
05912                 NewNumCoords - The number of coords in this new clipped path
05913     Returns:    TRUE if it needed to clip the path, FALSE if it did nothing
05914     Purpose:    This function works out if clipping is needed (based on scale factor etc)
05915                 and tries to clip the paths. If it works it will return TRUE, meaning that
05916                 you should only try to draw that path info found in pNewCoords etc. If
05917                 FALSE is returned pNewCoords etc will all be NULL.
05918                 If this function returns TRUE it will have allocated memory to put
05919                 the new coords and verbs in. It will be your responsibility to delete
05920                 this memory after you have rendered the path.
05921 
05922 ********************************************************************************************/
05923 
05924 BOOL RenderRegion::TryToFuzzyClip(Path* pPath, DocCoord** pNewCoords, PathVerb** pNewVerbs, 
05925                                   UINT32 *NewNumCoords)
05926 {
05927     // Start out by setting all the return values to something sensible
05928     *pNewCoords = NULL;
05929     *pNewVerbs = NULL;
05930     *NewNumCoords = 0;
05931     
05932     // Decide if we need to clip this path in order to draw it
05933     // Only bother if we are zoomed in a bit (400%)
05934     if (RenderView->GetViewScale() > FIXED16(4))
05935     {
05936         // Make some new coords etc
05937         DocCoord* pOldCoords = pPath->GetCoordArray();
05938         PathVerb* pOldVerbs = pPath->GetVerbArray();
05939         size_t OldNumCoords = (size_t)pPath->GetNumCoords();
05940         
05941         // Allow the new path to have a few extra points in it as this is possible.
05942         // If it gets to be more than this, then it will simply be unclipped
05943         // Usually the number of points is reduced when clipping.
05944         size_t NumCoords = OldNumCoords+20;
05945 
05946         // Get some mem for the coords
05947         DocCoord* Coords = new DocCoord[NumCoords];
05948         if (Coords==NULL)
05949             return FALSE;
05950 
05951         // Get some mem for the verbs
05952         PathVerb* Verbs = new PathVerb[NumCoords];
05953         if (Verbs==NULL)
05954         {
05955             delete [] Coords;
05956             return FALSE;
05957         }
05958 
05959         // Actually clip the path to the rectangles
05960         NumCoords = FuzzyClip( (PPOINT)pOldCoords, pOldVerbs, OldNumCoords, pPath->IsFilled,
05961                                 (RECT*)(&InnerRect), (RECT*)(&OuterRect),
05962                                 (PPOINT)Coords, Verbs, NumCoords);
05963         // See if it worked
05964         if (NumCoords == (size_t)-1)
05965         {
05966             // No it did not, so clean up and return
05967             delete [] Coords;
05968             delete [] Verbs;
05969             return FALSE;
05970         }
05971         else
05972         {
05973             // fill in the correct values for the outputs and return TRUE
05974             *pNewCoords = Coords;
05975             *pNewVerbs = Verbs;
05976             *NewNumCoords = (UINT32)NumCoords;
05977             return TRUE;
05978         }
05979     }
05980 
05981     // There was no need to clip, so return false
05982     return FALSE;
05983 }
05984 
05985 
05986 
05987 /********************************************************************************************
05988 
05989 >   void RenderRegion::SetupFuzzyClipRects()
05990 
05991     Author:     Karim_MacDonald (Xara Group Ltd) <camelotdev@xara.com>
05992     Created:    01/08/2000
05993     Purpose:    Sets up the fuzzy clipping rects, basing them on the CurrentClipRect.
05994                 Don't ask me what they're used for - I'm just moving some useful code into
05995                 a function :o)
05996 
05997 ********************************************************************************************/
05998 void RenderRegion::SetupFuzzyClipRects()
05999 {
06000     // Set up the Fuzzy Clipping Rects.
06001     if (!CurrentClipRect.IsValid())
06002         return;
06003 
06004     // Inner rect is used to clip with, so we need to make it bigger than the region so that
06005     // things like thick lines do not show up.
06006     InnerRect = CurrentClipRect;
06007     INT32 ScaleBy = (RR_LINEWIDTH()/2) + 16 * ScaledPixelWidth;
06008     InnerRect.Inflate(ScaleBy, ScaleBy);
06009 
06010     if (!InnerRect.IsValid())
06011         return;
06012 
06013     // The outer rect is used to determine if clipping is needed, so make it
06014     // a few times bigger than the inner rect.
06015     OuterRect = InnerRect;
06016     OuterRect.Inflate(InnerRect.Width()*3, InnerRect.Height()*3);
06017 }
06018 
06019 
06020 
06021 /********************************************************************************************
06022 >   BOOL RenderRegion::RenderChar(WCHAR ch, Matrix* pMatrix)
06023 
06024     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
06025     Created:    19/3/95
06026     Inputs:     ch      - unicode value of char
06027                 pMatrix - matrix specifying transforms to place char correctly in document
06028     Returns:    FALSE if fails
06029     Purpose:    Render a character,
06030                 using the specified transform and current attributes in the render region
06031 ********************************************************************************************/
06032 
06033 BOOL RenderRegion::RenderChar(WCHAR ch, Matrix* pMatrix)
06034 {
06035     ERROR2IF(pMatrix==NULL,FALSE,"RenderRegion::RenderChar() - pMatrix==NULL");
06036     
06037     // create the char's path
06038     Path* pCharPath=CreateCharPath(ch,pMatrix);
06039     if (pCharPath==NULL)
06040         return FALSE;
06041 
06042     // if at least one point, draw path using current attibutes in render region
06043     if (pCharPath->GetNumCoords()!=0)
06044         DrawPath(pCharPath);
06045 
06046     // clean up
06047     delete pCharPath;
06048 
06049     return TRUE;
06050 }
06051 
06052 /********************************************************************************************
06053 
06054 >   BOOL RenderRegion::WriteNewLine ( void )
06055 
06056     Author:     Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
06057     Created:    27/4/00
06058     Inputs:     -
06059     Returns:    TRUE    - Success.
06060                 FALSE   - Failure.
06061     Purpose:    Writes in a new-line token if necessary. In this class, it's just a stub
06062                 function that's over-ridden in the derived classes.
06063 
06064 ********************************************************************************************/
06065 
06066 BOOL RenderRegion::WriteNewLine ( void )
06067 {
06068     return TRUE;
06069 }
06070 
06071 /********************************************************************************************
06072 >   BOOL RenderRegion::GetAttrdCharBounds(DocRect* pRect, WCHAR ch)
06073 
06074     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
06075     Created:    19/3/95
06076     Inputs:     ch      - unicode value of char
06077     Outputs:    pRect   - bounding box of char in doc
06078     Returns:    FALSE if fails
06079     Purpose:    Get the bounding box of the specified char (from a cache) and apply the
06080                 required transform depending on attributes
06081                 (this is a character relative rect!)
06082 ********************************************************************************************/
06083 
06084 BOOL RenderRegion::GetAttrdCharBounds(DocRect* pBounds, WCHAR ch)
06085 {
06086     ERROR2IF(pBounds==NULL,FALSE,"RenderRegion::GetAttrdCharBounds() - pBounds==NULL");
06087 
06088     // get defualt bounds from cache
06089     CharDescription CharDesc(ch, RR_TXTFONTTYPEFACE(), RR_TXTBOLD(), RR_TXTITALIC());
06090     BOOL ok = FontCache::GetBounds(pBounds,CharDesc);
06091 
06092     // get and apply attribute matrix to bounds
06093     Matrix matrix;
06094     if (ok) ok = GetCharAttributeMatrix(&matrix);
06095     if (ok) ok = matrix.TransformBounds(pBounds);
06096 
06097     // transform inaccuracies cause empty rects to become non-empty
06098     // so for very small ones to be empty (ok as rect char relative)
06099     if (ok && pBounds->Width()<3 && pBounds->Height()<3)
06100         pBounds->MakeEmpty();
06101 
06102     return ok;
06103 }
06104 
06105 
06106 /********************************************************************************************
06107 >   Path* RenderRegion::CreateCharPath(WCHAR ch, Matrix* pMatrix=NULL)
06108 
06109     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
06110     Created:    19/3/95
06111     Inputs:     ch      - unicode value of char
06112                 pMatrix - possible matrix to transform char to correct place in doc
06113     Returns:    pointer to new path (else NULL if fails)
06114     Purpose:    Create a path of the specified char,
06115                 using the specified transform and current attributes in the render region
06116     Note:       The caller is resposible for initialising the path's flags if required
06117 ********************************************************************************************/
06118 
06119 Path* RenderRegion::CreateCharPath(WCHAR ch, Matrix* pMatrix)
06120 {
06121     // get overall matrix - attribute matrix concatenated with given matrix if supplied
06122     Matrix matrix;
06123     if (GetCharAttributeMatrix(&matrix)==FALSE)
06124         return NULL;
06125     if (pMatrix)
06126         matrix*=*pMatrix;
06127 
06128     // create the default char path
06129     CharDescription CharDesc(ch, RR_TXTFONTTYPEFACE(), RR_TXTBOLD(), RR_TXTITALIC());
06130     Path* pPath=FontCache::CreateDefaultCharPath(CharDesc);
06131     if (pPath==NULL)
06132         return NULL;
06133 
06134     // apply overall matrix to path
06135     INT32      points=pPath->GetNumCoords();
06136     DocCoord* pCoords=pPath->GetCoordArray();
06137     BOOL ok=(pCoords!=NULL);
06138     if (ok) matrix.transform((Coord*)pCoords, points);
06139     
06140     // if not OK, delete path and set return value to NULL
06141     if (!ok)
06142     {
06143         delete pPath;
06144         pPath=NULL;
06145     }
06146 
06147     return pPath;
06148 }
06149 
06150 
06151 /********************************************************************************************
06152 >   BOOL GetCharAttributeMatrix(Matrix* pAttrMatrix)
06153 
06154     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
06155     Created:    20/3/95
06156     Outputs:    pAttrMatrix -
06157     Returns:    FALSE if fails
06158     Purpose:    calc attribute matrix based on FontSize, AspectRatio and Script attributes
06159 ********************************************************************************************/
06160 
06161 BOOL RenderRegion::GetCharAttributeMatrix(Matrix* pAttrMatrix)
06162 {
06163     ERROR2IF(pAttrMatrix==NULL,FALSE,"RenderRegion::GetCharAttributeMatrix() - pAttrMatrix==NULL");
06164     TxtScriptAttribute* pScriptAttr=RR_TXTSCRIPT();
06165     ERROR2IF(pScriptAttr==NULL,FALSE,"RenderRegion::GetCharAttributeMatrix() - pScriptAttr==NULL");
06166 
06167     MILLIPOINT FontSize = RR_TXTFONTSIZE();
06168     MILLIPOINT OffsetY  = XLONG(FontSize) * pScriptAttr->Offset;
06169     FIXED16    fScaleY  = pScriptAttr->Size * Div32By32(FontSize, TextManager::GetDefaultHeight());
06170     FIXED16    fScaleX  = fScaleY * RR_TXTASPECTRATIO();
06171 
06172     *pAttrMatrix = Matrix(fScaleX,0,0,fScaleY,0,OffsetY);
06173 
06174     return TRUE;
06175 }
06176 
06177 
06178 /********************************************************************************************
06179 
06180 >   DocRect RenderRegion::GetRegionRect()
06181 
06182     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
06183     Created:    20/3/95
06184     Returns:    The rect of the actual region. 
06185     Purpose:    This function returns the size of the whole render region.
06186                 Note that this may be different from the Clip rect. If the region is banded,
06187                 then the Clip rect will hold the rect of the band that is being rendered,
06188                 while the RegionRect will always hold the rect the whole region.
06189 
06190 ********************************************************************************************/
06191 
06192 DocRect RenderRegion::GetRegionRect()
06193 {
06194     return RegionRect;
06195 }
06196 
06197 
06198 /********************************************************************************************
06199 
06200 >   virtual void RenderRegion::ResizeRegion(DocRect &NewClipRect)
06201 
06202     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
06203     Created:    4/7/95
06204     Purpose:    Called when a Region is changed in size (eg. clipped to the client area)
06205 
06206 ********************************************************************************************/
06207 
06208 void RenderRegion::ResizeRegion(DocRect &NewClipRect)
06209 {
06210     // Just reset the region by default
06211     ResetRegion(NewClipRect);
06212 }
06213 
06214 /********************************************************************************************
06215 
06216 >   virtual void RenderRegion::ResetRegion(DocRect &NewClipRect)
06217 
06218     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
06219     Created:    4/5/95
06220     Purpose:    Resets the render region (after it has been merged), so that it no longer
06221                 thinks it is banded etc. It also takes the Regions rectangle from the 
06222                 Current Clipping rectangle, so set this correctly before calling this
06223                 function
06224 
06225 ********************************************************************************************/
06226 
06227 void RenderRegion::ResetRegion(DocRect &NewClipRect)
06228 {
06229     // Note from Will. We really need to be re-rendering the Paper onto
06230     // the screen, if we have rendered something in this Region, but we
06231     // don't seem to be able to do this during a Paint message, as it
06232     // appears you can only render into the Area specified as invalid by
06233     // the message.  I tried clearing the clipping region etc, but this
06234     // made no difference.  There must be some way to do it though.
06235     // A solution would be to flag that the paper needs re-rendering, 
06236     // and do it on the next 'StartRender' call.
06237 
06238     Capture* pCapture = GetTopCapture();
06239     while (pCapture)
06240     {
06241         ENSURE(!pCapture->OwnsBitmap(), "Capture unexpectedly owns bitmap in RenderRegion::ResetRegion");
06242 
06243         m_CaptureStack.Pop();
06244 //TRACEUSER( "Phil", _T("ResetRegion Pop/Delete Capture\n"));
06245         if (pCapture->IsMaster())
06246         {
06247             SetRenderToCapture(pCapture, FALSE, FALSE);
06248         }
06249         else
06250         {
06251             pCapture->FreeDIB();
06252         }
06253         delete pCapture;
06254 
06255         pCapture = GetTopCapture();
06256     }
06257 
06258     // Set the new clipping rect
06259     SetClipRect(NewClipRect);
06260 
06261     // We set this flag to get the render region to blit the paper on the first
06262     // time past after it is reset.
06263     // Unfortunately this causes large amounts of unecessary blitting when scrolling
06264     // an empty document around with the push tool
06265     // Arrghh.  No we don't.  We clear the IsPaperRendered flag so that the paper is 
06266     // rendered into the region on the next render timeslice if the region requires it
06267     // This should eliminate all unecessary blitting
06268     // Gerry Iles 13/01/2006
06269 //  NeedsOSPaper = FALSE;
06270     IsPaperRendered = FALSE;
06271     
06272     // No Banding please
06273     IsRegionBanded = FALSE;
06274     IsWaitingForRAM = FALSE;
06275     IsLastBand = TRUE;
06276     CanRegionBeMerged = TRUE;
06277 
06278     // Set the region for this render region to match the clip rect
06279     RegionRect = CurrentClipRect;
06280 
06281     // Reset the rendering state
06282     ResetRender();
06283 
06284     // Make sure that that we re-init the device
06285     RenderFlags.ValidDevice = FALSE;
06286 }
06287 
06288 
06289 
06290 /********************************************************************************************
06291 
06292 >   virtual void RenderRegion::ResetRender()
06293 
06294     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
06295     Created:    1/12/2004
06296     Purpose:    Reset the rendering state of this region
06297 
06298 ********************************************************************************************/
06299 
06300 void RenderRegion::ResetRender()
06301 {
06302     IsPaperRendered = FALSE;
06303     IsInkRenderStarted = FALSE;
06304 
06305     IsBeingReset = TRUE;
06306     {
06307         // Copy a blank stack over our old one, in order to wipe it clean.
06308         RenderStack EmptyStack;
06309         if (!TheStack.Copy(&EmptyStack, this))
06310         {
06311             // We failed to copy the empty attribute stack
06312             ERROR3("Empty Attribute Stack could not be copied");
06313         }
06314     }
06315     IsBeingReset = FALSE;
06316 
06317     // And clean up any errant PathProcessors. (If a node, e.g. a Mould, added a PathProcessor
06318     // and we aborted rendering halfway through its subtree, nobody calls the mould back
06319     // to de-initialise, so the PathProcessor would be left lying around)
06320     while (PathProcessorStack != NULL)
06321         PopPathProcessor();
06322 
06323     // Now setup the render state 
06324     CurrentRenderState = NULL;
06325     SubRenderStateLocked = FALSE;
06326     if (CurrentSubRenderState!=NULL)
06327     {
06328         // get rid of any sub-render context we may have.
06329         delete CurrentSubRenderState;
06330         CurrentSubRenderState = NULL;
06331     }
06332 }
06333 
06334 
06335 
06336 /********************************************************************************************
06337 
06338 >   virtual BOOL RenderRegion::SetFirstBand()
06339 
06340     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
06341     Created:    2/5/95
06342     Returns:    TRUE if all went OK, FALSE if there was a problem
06343     Purpose:    This function gives the render region a chance to see if it want to do
06344                 some banding or not. If it decides it does, then this function will set it
06345                 all up ready to start. It should be called before StartRender
06346 
06347 ********************************************************************************************/
06348 
06349 BOOL RenderRegion::SetFirstBand()
06350 {
06351     // No Banding please
06352     IsRegionBanded = FALSE;
06353     IsWaitingForRAM = FALSE;
06354     IsLastBand = TRUE;
06355     CanRegionBeMerged = TRUE;
06356     return TRUE;
06357 }
06358 
06359 
06360 /********************************************************************************************
06361 
06362 >   virtual BOOL RenderRegion::GetNextBand()
06363 
06364     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
06365     Created:    20/3/95
06366     Returns:    TRUE if another band is ready to be rendered, FALSE if there were no more
06367                 bands to render in this region.
06368     Purpose:    This function goes and sets up the next band in the render region ready for
06369                 rendering and returns TRUE if it went OK. If there are no more bands to render
06370                 then the function returns FALSE.
06371     Errors:     Causes an error if it can not get the next render region ready.
06372     SeeAlso:    RenderRegion::IsBanded
06373 
06374 ********************************************************************************************/
06375 
06376 BOOL RenderRegion::GetNextBand()
06377 {
06378     // No more bands here
06379     return FALSE;
06380 }
06381 
06382 
06383 /********************************************************************************************
06384 
06385 >   BOOL RenderRegion::IsBanded()
06386 
06387     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
06388     Created:    20/3/95
06389     Returns:    TRUE if this render region is banded
06390     Purpose:    To find out if the render region is banded.
06391 
06392 ********************************************************************************************/
06393 
06394 BOOL RenderRegion::IsBanded()
06395 {
06396     return IsRegionBanded;
06397 }
06398 
06399 
06400 /********************************************************************************************
06401 
06402 >   BOOL RenderRegion::CanBeMerged()
06403 
06404     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
06405     Created:    20/3/95
06406     Returns:    TRUE if this render region can be merged now. FALSE if it should not be
06407                 merged.
06408     Purpose:    This is used to help simplify the merging code with banded region. A banded
06409                 render region at the start of one of its bands looks similar to a render
06410                 region that has done no rendering yet, and may be merged. This function allows
06411                 banded regions to stop themselves from being merged after they have started
06412                 rendering into their first band.
06413 
06414 ********************************************************************************************/
06415 
06416 BOOL RenderRegion::CanBeMerged()
06417 {
06418     // If we have started rendering ink, then we can not merge
06419     if (IsInkRenderStarted)
06420         return FALSE;
06421 
06422     // if we have not, then we may be between bands in a banded render region
06423     return CanRegionBeMerged;
06424 }
06425 
06426 
06427 
06428 /********************************************************************************************
06429 
06430 >   virtual void RenderRegion::GetRenderRegionCaps(RRCaps* pCaps)
06431 
06432     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
06433     Created:    10/4/95
06434     Outputs:    pCaps - the flags set for the things we are able to render
06435     Purpose:    This function allows a render region to declare what it can render and
06436                 what it can not render. This base class version of the function says that
06437                 it can render none of the options. If your render region can do some of these
06438                 things then you should overide this function and set the appropriate flags.
06439 
06440 ********************************************************************************************/
06441 
06442 void RenderRegion::GetRenderRegionCaps(RRCaps* pCaps)
06443 {
06444     // by default, render regions can do Everything
06445     pCaps->CanDoAll();
06446 }
06447 
06448 
06449 
06450 /********************************************************************************************
06451 
06452 >   BOOL RenderRegion::TestForComplexShape(RRCaps* pCaps)
06453 
06454     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
06455     Created:    10/4/95
06456     Returns:    TRUE if the current state of the attributes make this a complex shape.
06457                 FALSE if the host render region could render this with no trouble
06458     Purpose:    This function is called whenever someone calls one of the primitive render
06459                 functions in a ScanningRenderRegion. This takes a look at all the attributes
06460                 (and anything else it might need to) to see if this represents a complex
06461                 shape or not. If it is a complex shape, all the internal data members of the
06462                 render region are updated accordingly. This function makes use of the RRCaps
06463                 object that was set with the SetHostRRCaps() function to see what things the
06464                 Host render region considers to be complex.
06465     SeeAlso:    SetHostRRCaps()
06466 
06467 ********************************************************************************************/
06468 
06469 BOOL RenderRegion::TestForComplexShape(RRCaps* pCaps)
06470 {
06471     // we will start off assuming that this is not a complex shape we are trying to draw
06472     BOOL IsComplex = FALSE;
06473 
06474     // If we are in very low quality mode then assume everything is simple
06475     if (RRQuality.GetFillQuality() <= Quality::Bitmaps)
06476         return FALSE;
06477 
06478     if (pCaps->DoesRegionDoNothing())
06479         return TRUE;
06480 
06481     // if the host rr can not do transparancy, then see if there is any
06482     if (!pCaps->Transparency)
06483     {
06484         // Find out about the transparancy attribute
06485         TranspFillAttribute* pTransAttr = RR_FILLTRANSP();
06486         UINT32 Type = pTransAttr->GetTranspType();
06487         UINT32* pAmount1 = pTransAttr->GetStartTransp();
06488 
06489         // This may be a grad fill transp
06490         // we will get ready for this by setting up a var for the end transp
06491         UINT32  DefaultAmount = 0;
06492         UINT32* pAmount2 = &DefaultAmount;
06493         UINT32* pAmount3 = &DefaultAmount;
06494         UINT32* pAmount4 = &DefaultAmount;
06495 
06496         // get the end point transparencies (if there are any)
06497         if (pTransAttr->GetEndTransp())
06498             pAmount2 = pTransAttr->GetEndTransp();
06499 
06500         if (pTransAttr->GetEndTransp2())
06501             pAmount3 = pTransAttr->GetEndTransp2();
06502         
06503         if (pTransAttr->GetEndTransp3())
06504             pAmount4 = pTransAttr->GetEndTransp3();
06505 
06506         // See if there is any transparency in it
06507         if ((Type != 1) ||
06508             (*pAmount1 > 1) || 
06509             (*pAmount2 > 1) || 
06510             (*pAmount3 > 1) || 
06511             (*pAmount4 > 1))
06512         {
06513             // we found something that might be a bit transparent
06514             IsComplex = TRUE;
06515         }
06516 
06517         // CGS could - check for transparency profiling here as well
06518         // BUT these no point, since if were dealing with transparency,
06519         // then IsComplex will have just been set to TRUE by the above, which will cause us
06520         // to be rendered correctly anyway ....
06521 
06522         // Get the current fill attr
06523         FillGeometryAttribute* pFillAttr = (FillGeometryAttribute*) CurrentAttrs[ATTR_FILLGEOMETRY].pAttr;
06524 
06525         if (!IsComplex)
06526         {
06527             if (pFillAttr->GetBitmap() != NULL)
06528             {
06529                 KernelBitmap* pBmp = pFillAttr->GetBitmap();
06530                 if (pBmp && pBmp->IsTransparent())
06531                     IsComplex = TRUE;
06532             }
06533         }
06534 
06535         // now check for colour ramp ....
06536 
06537         if (!IsComplex)
06538         {
06539             // if there is a colour ramp, then the shape is complex ....
06540             
06541             if (pFillAttr->GetColourRamp () != NULL)
06542             {
06543                 IsComplex = TRUE;
06544             }
06545         }
06546 
06547         // now lets check for fill profiling ....
06548 
06549         CProfileBiasGain DefaultBiasGain;
06550 
06551         if (!(pFillAttr->GetProfile () == DefaultBiasGain))
06552         {
06553             IsComplex = TRUE;
06554 
06555 
06556 
06557         }
06558     }
06559 
06560     // If it is not complex yet, and we can't do bitmaps, see if we can do them
06561     if ((!IsComplex) && (!pCaps->BitmapFills || !pCaps->PerspectiveBitmapFills))
06562     {
06563         // Get the current fill attr
06564         ColourFillAttribute* pFillAttr = (ColourFillAttribute*) CurrentAttrs[ATTR_FILLGEOMETRY].pAttr;
06565 
06566         // see if it is a bitmap fill, and if it is, mark the shape as complex
06567         if (pFillAttr->IS_KIND_OF(BitmapFillAttribute))
06568         {
06569             // First check for the simple case of clipped bitmaps, as opposed to tiled
06570             // bitmap fills.
06571             FillMappingAttribute* pMapAttr = (FillMappingAttribute*) CurrentAttrs[ATTR_FILLMAPPING].pAttr;
06572             if ((pMapAttr->Repeat == 1) && 
06573                 (pCaps->ClippedSimpleBitmaps || pCaps->ClippedArbitraryBitmaps))
06574             {
06575                 // 'Simple' bitmap fill - is it a simple stretch, or has it been 
06576                 // arbitrarily transformed?
06577                 if (!pCaps->ClippedArbitraryBitmaps)
06578                 {
06579                     // Here we check the start and end points - the default arrangement is this:
06580                     //
06581                     //  EndPoint2
06582                     //      ^
06583                     //      |
06584                     //      |
06585                     //      |
06586                     //      |
06587                     //      +----------->  EndPoint
06588                     //  StartPoint
06589                     //
06590                     // So we check that the start and end points are aligned in the y axis,
06591                     // and then check that the start and second end point are aligned in
06592                     // the x axis.
06593                     //
06594                     DocCoord Geometry[3];
06595                     Geometry[0] = *(pFillAttr->GetStartPoint());
06596                     Geometry[1] = *(pFillAttr->GetEndPoint());
06597                     Geometry[2] = *(pFillAttr->GetEndPoint2());
06598                     if ((Geometry[0].x != Geometry[2].x) ||
06599                         (Geometry[0].y != Geometry[1].y))
06600                     {
06601                         // It's not a simple stretch - we can't do it!
06602                         IsComplex = TRUE;
06603                     }
06604                 }
06605             }
06606             else
06607             {
06608                 if (!pCaps->BitmapFills)
06609                     // We can't do bitmap fills!
06610                     IsComplex = TRUE;
06611                 else if (pFillAttr->IsPerspective() && !pCaps->PerspectiveBitmapFills)
06612                     // Bitmap fill is perspectivised, and we can't do that.
06613                     IsComplex = TRUE;
06614             }
06615         }
06616     }
06617 
06618     // If it is not complex yet, and we can't do Grad Fills, see if we can do them
06619     if ((!IsComplex) && (!pCaps->GradFills || !pCaps->PerspectiveGradFills || !pCaps->Grad3and4Fills))
06620     {
06621         // Get the current fill attr
06622         ColourFillAttribute* pFillAttr = (ColourFillAttribute*) CurrentAttrs[ATTR_FILLGEOMETRY].pAttr;
06623         FillMappingAttribute* pMapAttr = (FillMappingAttribute*) CurrentAttrs[ATTR_FILLMAPPING].pAttr;
06624         
06625         // see if it is a graduated fill, and if it is, mark the shape as complex
06626         if (pFillAttr->IsAGradFill())
06627         {
06628             if (!pCaps->GradFills)
06629                 // We just can't do graduated fills
06630                 IsComplex = TRUE;
06631             else if (pFillAttr->IsPerspective() && !pCaps->PerspectiveGradFills)
06632                 // It's perspectivised, and we can't do that.
06633                 IsComplex = TRUE;
06634             else if (pFillAttr->IsASquareFill() && !pCaps->Grad3and4Fills)
06635                 // We use the same flag rather than put a new one in as this fill type 
06636                 // will probably be supported soon
06637                 IsComplex = TRUE;
06638             else if (pFillAttr->IsAThreeColFill() && !pCaps->Grad3and4Fills)
06639                 IsComplex = TRUE;
06640 //Mark Howitt, 13/10/97. If the fill is a new repeating grad fill, then that`s really complex!
06641             else if (pMapAttr->Repeat == 4)
06642                 IsComplex = TRUE;
06643 //CGS, 24/5/2000  Need to do this for the new multi-stage and profiled fills as well ....
06644             // now check for colour ramp ....
06645             // if there is a colour ramp, then the shape is real complex ....
06646             else if (pFillAttr->GetColourRamp () != NULL)
06647             {
06648                 IsComplex = TRUE;
06649             }
06650             // now check for fill profiling ....
06651             else
06652             {
06653                 CProfileBiasGain DefaultBiasGain;
06654 
06655                 // if their not identical, then were complex!
06656                 if (!(pFillAttr->GetProfile () == DefaultBiasGain))
06657                 {
06658                     IsComplex = TRUE;
06659 
06660 
06661 
06662                 }
06663             }
06664         }
06665     }
06666 
06667     // Test for offscreen attributes.
06668     // We currently do this for all RRs 'cept those which can do everything.
06669     if (!IsComplex && !pCaps->DoesRegionDoAll())
06670     {
06671         OffscreenAttrValue* pOffAttr = CurrentOffscreenAttr;
06672 
06673         // we're complex if the current attr is not the default.
06674         if ( ! ((GeometryLinkedAttrValue*)pOffAttr)->IsDefaultFlagSet() )
06675             IsComplex = TRUE;
06676     }
06677 
06678     // Test to see whether the RR can clip its output to an arbitrary path.
06679     // Currently, only GRenderRegion and PostScript RR's can do this.
06680     if (!IsComplex && !pCaps->ClippedOutput)
06681     {
06682         ClipRegionAttribute* pClipAttr = RR_CLIPREGION();
06683         IsComplex = (pClipAttr->GetClipPath() != NULL);
06684     }
06685 
06686     // we seem to have problems printing variable width strokes, though the problem
06687     // goes away if they are transparent, so treat them as complex
06688     if (PathProcessorStack != NULL && PathProcessorStack->IsAPathProcessorStroke())
06689         IsComplex = TRUE;
06690 
06691 
06692     // return what we found out
06693     return IsComplex;
06694 }
06695 
06696 
06697 
06698 /********************************************************************************************
06699 
06700 >   BOOL RenderRegion::SetRenderComplexShapes(BOOL NewState)
06701 
06702     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
06703     Created:    25/4/95
06704     Inputs:     NewState - The new state for the RenderComplexShapes flag
06705     Returns:    The old state of the flag
06706     Purpose:    This function sets the state of the flag RenderComplexShapes. This flag is
06707                 used by some classes of render region to decide what shapes to draw.
06708                 If the flag is TRUE, then all shapes will be drawn that are asked to be
06709                 drawn. If it is FALSE, only the shapes that are not considered to be
06710                 complex by the render region will rendered. OSRenderRegions use this, as they
06711                 can be used as part of the 3 phase rendering system that needs to render
06712                 only specific nodes.
06713     SeeAlso:    RenderRegion::TestForComplexShape
06714 
06715 ********************************************************************************************/
06716 
06717 BOOL RenderRegion::SetRenderComplexShapes(BOOL NewState)
06718 {
06719     // make a note of the old value
06720     BOOL OldValue = RenderComplexShapes;
06721 
06722     // Set it to the new value
06723     RenderComplexShapes = NewState;
06724 
06725     // return the old value
06726     return OldValue;
06727 }
06728 
06729 
06730 
06731 /********************************************************************************************
06732 
06733 >   virtual SlowJobResult RenderRegion::DrawMaskedBitmap(const DocRect &Rect, KernelBitmap* pBitmap, 
06734                                     MaskedRenderRegion* pMask, ProgressDisplay *Progress)
06735 
06736 
06737     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
06738     Created:    20/4/95
06739     Inputs:     Point - the position to plot the bitmap
06740                 pBitmap - The bitmap that needs plotting
06741                 pMask - The mask render region to use to indicate which bits of pBitmap
06742                 needs to be plotted
06743                 Progress - progress display object used when printing or exporting.
06744     Returns:    Status of operation.
06745     Purpose:    Plots the bitmap using the mask supplied. The base class implementation here
06746                 does nothing.
06747 
06748 ********************************************************************************************/
06749 
06750 SlowJobResult RenderRegion::DrawMaskedBitmap(const DocRect &Rect, KernelBitmap* pBitmap, 
06751                                     MaskedRenderRegion* pMask, ProgressDisplay *Progress)
06752 {
06753     return SLOWJOB_SUCCESS;
06754 }
06755 
06756 
06757 
06758 
06759 
06760 /********************************************************************************************
06761 
06762 >   virtual BOOL RenderRegion::WantsGrids()
06763 
06764     Author:     Rik_Heywood (Xara Group Ltd) <camelotdev@xara.com>
06765     Created:    12/12/95
06766     Returns:    TRUE
06767     Purpose:    This function is designed to help with the rendering of grids, as they are
06768                 not always wanted (eg xara eps). If your class of render region does not
06769                 want grids to appear, then overide this function and get it to return FALSE.
06770                 The default behaviour is to return TRUE, which will allow grids to render
06771                 if they want to.
06772 
06773 ********************************************************************************************/
06774 
06775 BOOL RenderRegion::WantsGrids()
06776 {
06777     return TRUE;
06778 }
06779 
06780 /********************************************************************************************
06781 
06782 >   void RenderRegion::SetBackgroundColour ( DocColour &Colour )
06783 
06784     Author:     Graeme_Sutherland (Xara Group Ltd) <camelotdev@xara.com>
06785     Created:    19/1/00
06786     Input:      Colour - The background colour of the current document.
06787     Returns:    -
06788     Purpose:    Sets the value of mBackground colour, which is used whenever the program
06789                 needs to know what the background colour of a file is.
06790     SeeAlso:    -
06791 
06792 ********************************************************************************************/
06793 
06794 void RenderRegion::SetBackgroundColour ( DocColour &Colour )
06795 {
06796     mBackgroundColour = Colour;
06797 }
06798 
06799 
06800 /********************************************************************************************
06801 
06802 >   void RenderRegion::ColourCorrectBitmap(BitmapFillAttribute* Fill, BITMAPINFO *Info,
06803                                             RGBQUAD **Palette)
06804 
06805     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
06806     Created:    1/6/96
06807     Inputs:     Fill - NULL, or a pointer to a BFA which describes how this bitmap should
06808                         be contoned
06809 
06810                 Info - The bitmap info header
06811 
06812                 Palette - Must point to a (RGBQUAD *) which we can fill in (see outputs)
06813     
06814     Outputs:    Palette - Will be returned NULL if you should use the original bitmap's
06815                 palette, else is a pointer to a CCMalloc'd block of memory containing a
06816                 colour corrected RGBQUAD palette to use instead -in which case you MUST
06817                 CCFree() the new block when you've finished plotting the bitmap.
06818 
06819     Purpose:    Applies colour correction and/or contoning to a paletted bitmap being
06820                 plotted.
06821 
06822                 Contoning and colour-correction of <=8bpp images is achieved by
06823                 replacing the original palette with a corrected version. This means
06824                 that even colour separation can be achieved on <=8bpp with this function.
06825 
06826                 Images of more than 8bpp cannot be contoned.
06827                 Images of more than 8bpp should be colour corrected by setting GDraw
06828                 up to do colour correction on the fly (GD->SetBitmapConversionTable).
06829 
06830                 This function thus takes a bitmap, and returns a pointer to the
06831                 palette to be plot it with - if this pointer differs from the original
06832                 one, it is then your responsibility to CCFree() the returned
06833                 block to release the temporary memory.
06834 
06835 ********************************************************************************************/
06836 
06837 void RenderRegion::ColourCorrectBitmap(BitmapFillAttribute* Fill, BITMAPINFO *Info,
06838                                         RGBQUAD **Palette)
06839 {
06840     ERROR3IF(Info == NULL || Palette == NULL, "illegal NULL params");
06841 
06842     *Palette = NULL;                    // Set up a suitable return default
06843 
06844     // --- If a fill was passed in, check if this is a contoned bitmap
06845     // If it is, we just provide a colour-corrected contone palette and return
06846     if (Fill != NULL && Fill->GetStartColour() != NULL && Fill->GetEndColour() != NULL)
06847     {
06848         *Palette = (RGBQUAD *) CCMalloc(256 * sizeof(RGBQUAD));
06849         if (*Palette == NULL)
06850         {
06851             ERROR3("No memory for palette");
06852             return;
06853         }
06854         GradTable32::BuildGraduatedPalette(*Fill->GetStartColour(), *Fill->GetEndColour(),
06855                                            GetRenderView(), GetFillEffect(),
06856                                            256, *Palette, Fill->GetProfile());
06857         return;
06858     }
06859     // --- If it's a paletted bitmap, then we just colour-correct the palette
06860     if (Info->bmiHeader.biBitCount <= 8)
06861     {
06862         // Not contoned, but should we colour-correct?
06863         if (CurrentColContext->GetColourPlate() != NULL &&
06864             !CurrentColContext->GetColourPlate()->IsDisabled())
06865         {
06866             *Palette = (RGBQUAD *) CCMalloc(256 * sizeof(RGBQUAD));
06867             if (*Palette == NULL)
06868             {
06869                 ERROR3("No memory for palette");
06870                 return;
06871             }
06872 
06873             RGBQUAD *OldPal = Info->bmiColors;
06874 
06875             DocColour temp;
06876             PColourRGBT Converted;
06877 
06878             for (DWORD i = 0; i < Info->bmiHeader.biClrUsed; i++)
06879             {
06880                 temp.SetRGBValue(OldPal[i].rgbRed, OldPal[i].rgbGreen, OldPal[i].rgbBlue);
06881 
06882                 CurrentColContext->ConvertColour(&temp, (ColourPacked *) &Converted);
06883 
06884                 (*Palette)[i].rgbRed        = Converted.Red;
06885                 (*Palette)[i].rgbGreen      = Converted.Green;
06886                 (*Palette)[i].rgbBlue       = Converted.Blue;
06887                 (*Palette)[i].rgbReserved   = OldPal[i].rgbReserved;
06888             }
06889         }
06890         return;
06891     }
06892 }
06893 
06894 
06895 
06896 
06897 /********************************************************************************************
06898 
06899 >   BOOL RenderRegion::RenderTree(Node* pRoot,
06900                                     BOOL bTimeSlice = TRUE,
06901                                     BOOL bClip = TRUE,
06902                                     RenderCallback* pCallback = NULL)
06903 
06904     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
06905     Created:    19/5/93 (16/06/2004)
06906     Inputs:     pRoot - pointer to root node
06907                 bTimeSlice - TRUE if rendering should be time-sliced (interruptible)
06908                 bClip - TRUE if only those objects intersecting the clipping region
06909                         should be rendered
06910                 pCallback - Pointer to RenderCallback object to callback for each object or NULL
06911     Outputs:    TRUE if rendering was interrupted (by reaching the end of a timeslice typically)
06912                 FALSE if rendering was completed
06913     Purpose:    To render a specified subtree in this RenderRegion.
06914                 The dominating factor in this routine is that it renders the document with as 
06915                 little time overhead as possible. Obviously, this is mainly down to 
06916                 RenderRegions and the tree scanning routines working fast but we can do a bit 
06917                 to help.
06918 
06919 ********************************************************************************************/
06920 /*
06921 Technical notes:
06922                 This routine stores and restores its position in the document tree from the 
06923                 RenderRegion.
06924 
06925                 When the routine hits the end of the tree it will pass a NULL in for the 
06926                 RenderRegion to store as its state. This can be used a a signal that rendering 
06927                 in this RenderRegion is complete and that the RenderRegion can be destroyed.
06928 
06929                 The routine contains all the decision making about how the traversal of the
06930                 tree proceeds (not calling out to FindNextForClippedInkRender, for instance)
06931                 so that it can skip across the tree if required.
06932 
06933 ********************************************************************************************/
06934 
06935 BOOL RenderRegion::RenderTree(Node* pRoot,
06936                               BOOL bTimeSlice,
06937                               BOOL bClip,
06938                               RenderCallback* pCallback)
06939 {
06940 //  TRACEUSER( "Gerry", _T("In RenderTree CC = 0x%08x\n"), GetColourContext()->GetColourPlate());
06941     
06942     Node* pNode = NULL;
06943     Node* pRunToNode = NULL;
06944     DocRect ClipRect;
06945 
06946 //  BOOL HasRendered = FALSE;
06947     BOOL Continue = TRUE;
06948 // TEMP BODGE! DO NOT RELEASE!
06949 //bTimeSlice = FALSE;
06950     m_bRenderTreeTimeSlice = bTimeSlice;
06951 
06952 //  CBitmapCache* pBitmapCache = Camelot.GetBitmapCache();
06953 //  double ScaledPixelSize = GetScaledPixelWidth();
06954 
06955     // Record time when rendering started
06956     m_timeRenderTreeStartTime.Sample();
06957 
06958 PORTNOTE("other","PerfCounter not used under Linux")
06959 #if defined(__WXMSW__)
06960     LARGE_INTEGER countStart;
06961     LARGE_INTEGER countEnd;
06962     INT64 countOrigTotal = m_countTotal;
06963     QueryPerformanceCounter(&countStart);
06964 #endif
06965 
06966     // Find where to pick up rendering from...
06967     // Have we started rendering ink?
06968     if (bTimeSlice && IsInkRenderStarted)
06969         pNode = GetRenderState();
06970 
06971     if (!IsInkRenderStarted || pNode==NULL)
06972     {
06973         pNode = pRoot;
06974         SetRenderState(pRoot);
06975         if (CurrentSubRenderState != NULL)
06976         {
06977             // In the middle of rendering so lose this sub-context and set it to NULL
06978             delete CurrentSubRenderState;
06979             SetSubRenderState(NULL);
06980         }
06981 
06982         // We only want to do this once
06983         IsInkRenderStarted = TRUE;
06984     }
06985 
06986 #ifdef _DEBUG
06987     try
06988     {
06989 #endif
06990 
06991     // ---------------------------------------------------
06992     // This is the new rendering loop...
06993     //
06994     // The algorithm is basically this:
06995     //  Do
06996     //      Render A Subtree
06997     //  While more to do
06998     //
06999     //  In a bit more detail:
07000     //  Do
07001     //      Try to find deepest first child subtree of Node (pushing context onto stack, when going down)
07002     //      Else Render Node and Try to move to Next
07003     //          Else Render Parent and Move Next After Parent (pulling context off stack when coming up)
07004     //  While more to do
07005     //
07006     Node* pNextNode = NULL;
07007     Node* pChildNode = NULL;
07008     do
07009     {
07010 //      TRACEUSER( "Gerry", _T("    CC = 0x%08x\n"), GetColourContext()->GetColourPlate());
07011 //      if (GetColourContext()->GetColourPlate() == (ColourPlate*)0xfeeefeee) { __asm {INT32 3}; }
07012         
07013         // At this point pNode ALWAYS refers to a node/subtree that has NOT yet been rendered!
07014         // (Er, unless there's a SubRenderContext stored - in which case we must continue
07015         // to render the current node without entering its subtree.)
07016         //
07017         // -----------------------------------------------
07018         // --- Test Subtree ---
07019         //
07020         // Check whether it's even worth bothering with this subtree...
07021         // (RenderSubtree does clip rect testing)
07022         //
07023 //TRACEUSER( "Phil", _T("RenderTree %x %s\n"), pNode, pNode->GetRuntimeClass()->m_lpszClassName);
07024         SubtreeRenderState state = SUBTREE_ROOTANDCHILDREN;                 // Assume normal depth-first behaviour
07025         SubtreeRenderState callbackstate = SUBTREE_NORENDER;
07026         if (CurrentSubRenderState)                                          // If we're partway through a node
07027             state = CurrentSubRenderState->renderstate;                     // Continue rendering that node (usually SUBTREE_ROOTONLY)
07028         else
07029             if (pCallback && pCallback->BeforeSubtree(this, pNode, &pNextNode, bClip, &callbackstate))
07030                 state = callbackstate;
07031             else
07032             {
07033                 if (pNode->IsRenderable())                                  // If this node is at all renderable
07034                     state = pNode->RenderSubtree(this, &pNextNode, bClip);  // Allow node to decide where to go
07035                 else
07036                     state = SUBTREE_NORENDER;                               // Else don't render anything
07037             }
07038 
07039         // -----------------------------------------------
07040 //      if (GetColourContext()->GetColourPlate() == (ColourPlate*)0xfeeefeee) { __asm {INT32 3}; }
07041 
07042         if (state==SUBTREE_JUMPTO)
07043         {
07044             // Node wants rendering to jump somewhere else
07045             // This isn't really sorted yet - something needs to be done about context
07046             // stacking...
07047             if (pNextNode!=NULL)
07048             {
07049                 pNode = pNextNode;
07050                 continue;
07051             }
07052             // (If pNextNode was NULL then we fall through to finding the next node...)
07053         }
07054 
07055         if (state==SUBTREE_RUNTO)
07056         {
07057             // Node wants rendering to run forward to somewhere else without actually
07058             // rendering any object but maintaining the attribute stack correctly
07059             if (pNextNode!=NULL)
07060             {
07061                 pRunToNode = pNextNode;
07062                 // NOTE! Since we don't preserve pRunToNode outside this routine
07063                 // it must not abort due to timeslicing while pRunToNode!=NULL
07064             }
07065             // (If pNextNode was NULL then we fall through to finding the next node...)
07066         }
07067 
07068         if (state==SUBTREE_ROOTANDCHILDREN || state==SUBTREE_RUNTO)
07069         {
07070             // Depth-first, so check for children first...
07071             // Go down the tree from the current node, looking for child lists to render
07072             pChildNode = pNode->FindFirstChild();
07073             if (pChildNode)
07074             {
07075                 // Then scan the child list
07076                 SaveContext();                                              // <<<< Going down
07077                 //TRACEUSER( "Phil", _T("SaveContext scope = %x\n"), pNode);
07078 
07079                 // Set this child as the next subtree to consider...
07080                 pNode = pChildNode;
07081                 continue;
07082             }
07083         }
07084 
07085         // Finished trying to deal with subtree so render subtree root node
07086         if (state==SUBTREE_ROOTONLY || state==SUBTREE_ROOTANDCHILDREN || state==SUBTREE_RUNTO)
07087         {
07088             // No children or root only so render this node directly...
07089             BOOL bSuspend = RenderNode(pNode, pRunToNode, pCallback);
07090 //          if (GetColourContext()->GetColourPlate() == (ColourPlate*)0xfeeefeee) { __asm {INT32 3}; }
07091             if (bSuspend) break;
07092         }
07093 
07094         // Balance the call to RenderSubtree
07095         if (!(pCallback && pCallback->AfterSubtree(this, pNode)))
07096             pNode->RenderAfterSubtree(this);
07097         
07098         // -----------------------------------------------
07099         // --- Move on to next subtree ---
07100         //
07101         // SUBTREE_NORENDER
07102         //
07103         pNextNode = pNode->FindNext();
07104 
07105         // See if we got here because we set up a subrender context especially to do so
07106         // If so, get rid of this context so that rendering can proceed normally
07107         if (CurrentSubRenderState && CurrentSubRenderState->IsKindOf(CC_RUNTIME_CLASS(SubTreeRenderContext)))
07108         {
07109             delete CurrentSubRenderState;
07110             CurrentSubRenderState = NULL;
07111         }
07112 
07113         // -----------------------------------------------
07114         // --- Render Subtree Parents ---
07115         //
07116         // While no next sibling found, look for parent's next sibling...
07117         if (pNextNode==NULL && pNode!=pRoot && Continue)
07118         {
07119             do
07120             {
07121                 pNode = pNode->FindParent();
07122                 if (pNode)
07123                 {
07124                     // Render the parent node now that its children have all been rendered...
07125                     BOOL bSuspend = RenderNode(pNode, pRunToNode, pCallback);
07126 //                  if (GetColourContext()->GetColourPlate() == (ColourPlate*)0xfeeefeee) { __asm {INT32 3}; }
07127                     if (bSuspend) break;
07128 
07129                     //TRACEUSER( "Phil", _T("RestoreContext scope = %x\n"), pNode);
07130                     RestoreContext();                                           // >>>> Coming up
07131 
07132                     // Slightly unpleasant to have yet another call to the Node
07133                     // but for things to balance correctly, it needs to be given a chance
07134                     // to do stuff /outside/ the attribute scope created by the calls
07135                     // to SaveContext and RestoreContext...
07136                     //
07137                     // Balance the call to RenderSubtree
07138                     if (!(pCallback && pCallback->AfterSubtree(this, pNode)))
07139                         pNode->RenderAfterSubtree(this);
07140 
07141                     pNextNode = pNode->FindNext();
07142 
07143 PORTNOTE("other","PerfCounter not used under Linux")
07144 #if defined(__WXMSW__)
07145                     // I'm not really happy about doing this here but profiling will tell us
07146                     // whether it's really a problem...
07147                     QueryPerformanceCounter(&countEnd);
07148                     m_countTotal = countOrigTotal + countEnd.QuadPart - countStart.QuadPart;
07149 #endif
07150 
07151                     // See if we should stop coming up out of this subtree because we've run out of time
07152                     Continue = RenderTreeCanContinue();
07153                 }
07154             }
07155             while (pNextNode==NULL && pNode!=pRoot && Continue);
07156 
07157             if (!Continue)
07158             {
07159                 // We have run out of time while following parent links
07160                 // so we need to set things up so that when rendering
07161                 // is restarted, it doesn't go DOWN into the subtree again!!!
07162                 // We do this by setting up a subrender state so that the logic above
07163                 // will drop through the SUBTREE_NORENDER path
07164                 //
07165                 // Note: Leave the current node pointer alone
07166                 //
07167                 SubTreeRenderContext* pReturnHereContext = new SubTreeRenderContext();
07168                 SetSubRenderState(pReturnHereContext);
07169                 break;
07170             }
07171         }
07172 
07173         // We should move the current node pointer on if we know that
07174         // the 
07175         if (pNextNode && pNode!=pRoot) pNode = pNextNode;
07176 
07177 PORTNOTE("other","PerfCounter not used under Linux")
07178 #if defined(__WXMSW__)
07179         // I'm not really happy about doing this here but profiling will tell us
07180         // whether it's really a problem...
07181         QueryPerformanceCounter(&countEnd);
07182         m_countTotal = countOrigTotal + countEnd.QuadPart - countStart.QuadPart;
07183 #endif
07184         
07185         // See if we are time slicing and we still have more time available
07186         Continue = RenderTreeCanContinue();
07187     }
07188     while (pNode && pNode!=pRoot && (Continue || pRunToNode!=NULL));
07189     //
07190     // Here endeth the new rendering loop
07191     // ---------------------------------------------------
07192 
07193 
07194 #ifdef _DEBUG
07195     }
07196     catch (...)
07197     {
07198         TRACEUSER( "Phil", _T("Exception during rendering...\n"));
07199     }
07200 #endif
07201 
07202     if (pNode==pRoot) pNode = NULL;
07203 
07204     // Reset state to new posn in tree.
07205     SetRenderState(pNode);
07206 
07207     ENSURE(pRunToNode==NULL, "Expected pRunToNode to be NULL at end of RenderTree\n");
07208 
07209 //TRACEUSER( "Phil", _T("RenderTree exiting %x %s\n", pNode, pNode?pNode->GetRuntimeClass()->m_lpszClassName:"NULL"));
07210 //  if (pbHaveRendered)
07211 //      *pbHaveRendered = *pbHaveRendered || HasRendered;
07212 
07213     return Continue;
07214 }
07215 
07216 
07217 
07218 
07219 /********************************************************************************************
07220 
07221 >   BOOL RenderRegion::RenderNode(Node* pNode, Node* pRunToNode, RenderCallback* pCallback)
07222 
07223     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
07224     Created:    28/6/2004
07225     Inputs:     -
07226     Outputs:    TRUE if RenderTree rendering can continue
07227                 FALSE if RenderTree rendering
07228     Purpose:    Wrap up the common stuff that's done to every node we render
07229                 Render a single node and find out whether we should suspend rendering
07230                 at this point
07231                 Helper function for RenderTree
07232 
07233 ********************************************************************************************/
07234 
07235 BOOL RenderRegion::RenderNode(Node* pNode, Node* pRunToNode, RenderCallback* pCallback)
07236 {
07237     BOOL bSuspendRendering = FALSE;
07238     BOOL bRender = TRUE;
07239 
07240     // Give RenderCallback object a chance to pre-process the rendering...
07241     if (pCallback)
07242         bRender = pCallback->BeforeNode(this, pNode);
07243 
07244     // Allow the loop to run forward to the RunTo node without rendering objects if it's set up...
07245     if (pRunToNode)
07246     {
07247         if (pRunToNode==pNode)              // If we are at the RunTo node
07248             pRunToNode = NULL;              // Then clear the system and allow it to render normally
07249         else
07250             if (pNode->IsAnObject())        // Else if this node is an object
07251                 bRender = FALSE;            // Don't let it render anything yet...
07252     }
07253 
07254     // If we can render this node, go ahead and do it.
07255     if (bRender && pNode->IsRenderedAsInk() && pNode->IsRenderable())
07256     {
07257 //TRACEUSER( "Phil", _T("RenderNode Node %x %s\n"), pNode, pNode->GetRuntimeClass()->m_lpszClassName);
07258         pNode->Render(this);                // Render the node
07259 
07260         if (CurrentSubRenderState!=NULL)    // If the node aborted rendering and set a subrender state
07261             bSuspendRendering = TRUE;       // Then Stop rendering without moving on the node pointer
07262     }
07263 
07264     return bSuspendRendering;
07265 }
07266 
07267 
07268 
07269 
07270 /********************************************************************************************
07271 
07272 >   BOOL RenderRegion::RenderTreeCanContinue()
07273 
07274     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
07275     Created:    28/6/2004
07276     Inputs:     -
07277     Outputs:    TRUE if RenderTree rendering can continue
07278                 FALSE if RenderTree rendering should stop
07279     Purpose:    Decide whether we can continue to render in RenderTree
07280 
07281 ********************************************************************************************/
07282 
07283 BOOL RenderRegion::RenderTreeCanContinue()
07284 {
07285     // If we are currently capturing offscreen stuff then we prefer to continue rendering
07286     // because the overhead of composing offscreen bitmaps together is so great
07287     // so lengthen the timeslice to make this happen less often
07288     INT32 t = Timeslice;
07289     if (GetCaptureDepth()>1) t = t*2;
07290     // if m_bRenderTreeTimeSlice == FALSE
07291     // or the timeslice hasn't elapsed yet then we can continue
07292     return !m_bRenderTreeTimeSlice || !m_timeRenderTreeStartTime.Elapsed(t);
07293 }
07294 
07295 
07296 
07297 
07298 /********************************************************************************************
07299 
07300 >   BOOL RenderRegion::RenderTreeNoCache(Node* pRoot)
07301                     
07302     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
07303     Created:    20/07/2005
07304     Inputs:pNode - pointer to root node of subtree to render
07305     Returns:    FALSE if the render failed
07306                 TRUE if it worked
07307     Purpose:    Renders a subtree with cacheing disabled
07308 
07309 ********************************************************************************************/
07310 BOOL RenderRegion::RenderTreeNoCache(Node* pRoot)
07311 {
07312     if (pRoot == NULL || this == NULL)
07313         return FALSE;
07314 
07315     // pNode may not be in the document tree!
07316     // So all bets are off regarding cacheing.
07317     // Therefore we disable cacheing during this render.
07318     ScopedFlagSetter fsBitmapCacheing(NodeRenderableBounded::bEnableCacheing, FALSE);
07319 
07320     SaveContext();
07321     RenderTree(pRoot, FALSE, FALSE);
07322     RestoreContext();
07323 
07324     return TRUE;
07325 }
07326 
07327 
07328 
07329 
07330 /********************************************************************************************
07331 
07332 >   void RenderRegion::SetBackmostChangedNode(Node* pInvalidNode)
07333 
07334     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
07335     Created:    09/08/2004
07336     Inputs:     -
07337     Outputs:    -
07338     Purpose:    -
07339 
07340 ********************************************************************************************/
07341 
07342 void RenderRegion::SetBackmostChangedNode(Node* pInvalidNode)
07343 {
07344     if (pInvalidNode)
07345     {
07346         if (pInvalidNode->FindParent()==NULL)
07347         {
07348 //          ERROR2RAW("SetBackmostChangedNode called on node with no parent");
07349             return;
07350         }
07351 
07352         if (m_pBackmostChangedNode==NULL || pInvalidNode->IsUnder(m_pBackmostChangedNode))
07353             m_pBackmostChangedNode = pInvalidNode;
07354     }
07355 }
07356 
07357 
07358 
07359 
07360 /********************************************************************************************
07361 
07362 >   void RenderRegion::ClearBackmostChangedNode(Node* pNode)
07363 
07364     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
07365     Created:    10/08/2004
07366     Inputs:     -
07367     Outputs:    -
07368     Purpose:    -
07369 
07370 ********************************************************************************************/
07371 
07372 void RenderRegion::ClearBackmostChangedNode(Node* pNode)
07373 {
07374     if (pNode && (pNode == m_pBackmostChangedNode || pNode->IsNodeInSubtree(m_pBackmostChangedNode)))
07375     {
07376         m_pBackmostChangedNode = pNode->FindParentSpread();
07377     }
07378 }
07379 
07380 
07381 
07382 
07383 /********************************************************************************************
07384 
07385 >   Capture* RenderRegion::StartCapture(CCObject* pOwner,
07386                                      DocRect CaptureRect,
07387                                      CAPTUREINFO cinfo,
07388                                      BOOL bTransparent,
07389                                      BOOL bCaptureBackground,
07390                                      double mpPixelWidth,
07391                                      NodeRenderableInk* pDirectSupplier)
07392 
07393     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
07394     Created:    30/06/2004
07395     Inputs:     pOwnerNode  - Node in tree which "owns" this capture
07396                 CaptureRect - The rectangle to capture
07397                 ctype       - The type of capture required
07398                 bTransparent    - The capture could be transparent RGBT
07399                 bCaptureBackground  - The capture should include the state of the background
07400     Outputs:    -
07401     Returns:    TRUE if a Capture was successfully set up
07402     Purpose:    To start a bitmap capture of whatever is subsequently rendered
07403     SeeAlso:    GRenderRegion::StopCapture
07404 
07405 ********************************************************************************************/
07406 
07407 Capture* RenderRegion::StartCapture(CCObject* pOwner,
07408                                      DocRect CaptureRect,
07409                                      CAPTUREINFO cinfo,
07410                                      BOOL bTransparent,
07411                                      BOOL bCaptureBackground,
07412                                      double dPPI,
07413                                      NodeRenderableInk* pDirectSupplier)
07414 {
07415     ENSURE(cinfo.caType==ctNESTABLE, "We only support nestable captures at the moment\n");
07416 
07417     // 1) alloc new mem, and setup state variables for new offscreen rendering
07418         // mem alloced = bmp
07419         // vars setup = docrect, gmatrix
07420     // 2) save current
07421     // 3) change to new offscreen state
07422 
07423     // If there's already a capture running and this one is nested but wants to change 
07424     // the transparency type then we must notify existing captures of the change...
07425     Capture* pCurrentCapture = GetTopCapture();
07426     if (pCurrentCapture!=NULL && cinfo.caType==ctNESTABLE && !cinfo.caFlags.GrabRendered && pCurrentCapture->IsTransparent() && !bTransparent)
07427     {
07428         ChangeCapture(cinfo, bTransparent, bCaptureBackground);
07429     }
07430 
07431     // If the caller didn't specify the capture resolution in pixels per inch
07432     // Then set it to the default value of the render region
07433     // And use the default matrix in our setup calculations
07434     Matrix CaptureMatrix;
07435     if (dPPI==0)
07436     {
07437 //      dPPI = GetPixelsPerInch();
07438 
07439         // Find current top bitmap capture and copy its res and res scale control flag
07440         Capture* pCap = GetTopCapture();
07441         ERROR2IF(pCap==NULL, NULL, "There MUST be a bitmap capture in the stack - the master capture at least");
07442         dPPI = pCap->dPixelsPerInch;
07443         cinfo.caFlags.CalcScaledPixWidth = pCap->info.caFlags.CalcScaledPixWidth;
07444 
07445         CaptureMatrix = RenderMatrix;
07446     }
07447     else
07448     {
07449         // If the caller specified a particular DPI we will assume he wants the capture
07450         // to grab the rendered objects at 100% scale...
07451         // No need to construct a new matrix in a complex way - the clip rect and
07452         // object are all stored in doccoords.
07453 //      CaptureMatrix = Identity;
07454     }
07455 
07456     // In non-Master Captures, make sure that we use a default colour context
07457     // to prevent multiple colour corrections when rendering bitmaps in "print preview"
07458     // type modes...
07459     ColourContext* pColContext = NULL;
07460     if (!cinfo.caFlags.Master)
07461     {
07462         BOOL bOldForce = RenderView->SetForceDefaultColourContexts();
07463         pColContext = RenderView->GetColourContext(COLOURMODEL_RGBT);
07464         RenderView->SetForceDefaultColourContexts(bOldForce);
07465     }
07466     else
07467     {
07468         // Must get RenderRegion's current colour context for Master Capture
07469         pColContext = CurrentColContext;
07470     }
07471 
07472     // Create a new capture instance...
07473     Capture* pNewCapture = new Capture(pOwner, cinfo, CaptureMatrix, CaptureRect, dPPI, pColContext);
07474     ENSURE(!pNewCapture->IsMaster(), "Can only have one master capture!");
07475 
07476     m_CaptureStack.Push(pNewCapture);
07477 
07478     return pNewCapture;
07479 }
07480 
07481 
07482 
07483 
07484 /********************************************************************************************
07485 
07486 >   BOOL RenderRegion::StopCapture(CCObject* pOwner,
07487                                     BOOL bRender = TRUE,
07488                                     BOOL bReleaseBitmap = FALSE,
07489                                     LPBITMAPINFO* plpBitmapInfo = NULL,
07490                                     LPBYTE* plpBits = NULL,
07491                                     DocRect* pCaptureRect = NULL,
07492                                     Matrix* pmatTransform = NULL,
07493                                     double* pdResolution = NULL)
07494 
07495     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
07496     Created:    30/06/2004
07497     Inputs:     pEndNode    - Node in tree which "owns" this capture
07498     Outputs:    -
07499     Returns:    TRUE if the Capture resulted in a bitmap being usefully created
07500     Purpose:    To stop a bitmap capture
07501     SeeAlso:    GRenderRegion::StartCapture
07502 
07503 ********************************************************************************************/
07504 
07505 BOOL RenderRegion::StopCapture(CCObject* pOwner,
07506                                BOOL bRender,
07507                                BOOL bReleaseBitmap,
07508                                LPBITMAPINFO* plpBitmapInfo,
07509                                LPBYTE* plpBits,
07510                                DocRect* pCaptureRect,
07511                                Matrix* pmatTransform,
07512                                double* pdResolution)
07513 {
07514     Capture* pCapture = GetTopCapture();
07515     if (pCapture==NULL)
07516         return FALSE;
07517 
07518     if (pCapture->IsMaster())
07519     {
07520         ERROR2(FALSE, "StopCapture called on the master capture!\n");
07521         return FALSE;
07522     }
07523 
07524     // Pop the capture off the stack now
07525     m_CaptureStack.Pop();
07526 
07527     delete pCapture;
07528 
07529     return TRUE;
07530 }
07531 
07532     
07533     
07534     
07535 /********************************************************************************************
07536 
07537 >   BOOL RenderRegion::ChangeCapture(CAPTUREINFO cinfo,
07538                                     BOOL bTransparent,
07539                                     BOOL bCaptureBackground)
07540 
07541     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
07542     Created:    09/07/2004
07543     Inputs:     -
07544     Outputs:    -
07545     Purpose:    To inform the capture stack that things (transparency) have changed
07546 
07547 ********************************************************************************************/
07548 
07549 BOOL RenderRegion::ChangeCapture(CAPTUREINFO cinfo,
07550                                 BOOL bTransparent,
07551                                 BOOL bCaptureBackground)
07552 {
07553     // If there's a current RGBT capture active and we are changing to a non-transparent capture
07554     // Then mark that Capture as no longer being transparent
07555     // Blit whatever we have so far into the parent bitmap
07556     // Tell all enclosing captures (further up the stack) that they can no longer be transparent
07557     // either
07558     Capture* pCurrentCapture = GetTopCapture();
07559     if (pCurrentCapture==NULL)
07560         return FALSE;
07561 
07562     if (pCurrentCapture->IsMaster())
07563     {
07564         ENSURE(m_CaptureStack.Size()==1, "Master Capture not bottom capture in ChangeCapture");
07565         return FALSE;
07566     }
07567 
07568     return TRUE;
07569 }
07570 
07571 
07572 
07573 
07574 /********************************************************************************************
07575 
07576 >   BOOL RenderRegion::LockedTransparentCaptures() const
07577 
07578     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
07579     Created:    07/08/2005
07580     Inputs:     -
07581     Outputs:    -
07582     Purpose:    Search down the Capture stack from the top or from the capture specified
07583                 until we find one that owns a bitmap. The master capture at the bottom
07584                 of the stack should ALWAYS own a bitmap!
07585 
07586 ********************************************************************************************/
07587 
07588 BOOL RenderRegion::LockedTransparentCaptures() const
07589 {
07590     const ListT<Capture*>* pList = m_CaptureStack.GetListT();
07591 
07592     Capture* pCapture = NULL;
07593     ListT<Capture*>::ConstIterator it = pList->End();
07594     INT32 nListSize = pList->Size();
07595     INT32 i=0;
07596 
07597     for (i=0; i < nListSize; i++)
07598     {
07599         pCapture = *(--it);
07600         if (pCapture->OwnsBitmap() &&
07601             pCapture->IsTransparent() &&
07602             (pCapture->IsMaster() || pCapture->info.caFlags.LockedTransparent)
07603             )
07604             return TRUE;
07605     }
07606 
07607     return FALSE;
07608 }
07609 
07610 
07611 
07612 
07613 /********************************************************************************************?
07614 
07615 >   BOOL RenderRegion::RenderBits(LPBITMAPINFO lpBitmapInfo, LPBYTE lpBits, DocRect rect, BOOL bForceNoTransp = TRUE, Node* pEffectsOwner = NULL)
07616 
07617     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
07618     Created:    01/07/2004
07619     Inputs:     -
07620     Outputs:    lpBitmapInfo
07621                 lpBits
07622                 rect
07623     Returns:    TRUE if the bitmap was rendered
07624     Purpose:    To blit one bitmap defined by a DocRect into the current RenderRegion
07625     SeeAlso:    GRenderRegion::StartCapture
07626 
07627 ********************************************************************************************/
07628 
07629 BOOL RenderRegion::RenderBits(LPBITMAPINFO lpBitmapInfo, LPBYTE lpBits, DocRect rect, BOOL bForceNoTransp, Node* pEffectsOwner)
07630 {
07631     return RenderBits(lpBitmapInfo, lpBits, (DocCoord*)&rect, 2, bForceNoTransp, pEffectsOwner);
07632 }
07633 
07634     
07635     
07636 /********************************************************************************************
07637 
07638 >   BOOL RenderRegion::RenderBits(LPBITMAPINFO lpBitmapInfo, LPBYTE lpBits, DocCoord* pCoords, INT32 numcoords, BOOL bForceNoTransp = TRUE, Node* pEffectsOwner = NULL)
07639 
07640     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
07641     Created:    01/07/2004
07642     Inputs:     -
07643     Outputs:    lpBitmapInfo
07644                 lpBits
07645                 rect
07646     Returns:    TRUE if the bitmap was rendered
07647     Purpose:    To blit one bitmap defined by a DocRect into the current RenderRegion
07648     SeeAlso:    GRenderRegion::StartCapture
07649 
07650 ********************************************************************************************/
07651 
07652 BOOL RenderRegion::RenderBits(LPBITMAPINFO lpBitmapInfo, LPBYTE lpBits, DocCoord* pCoords, INT32 numcoords, BOOL bForceNoTransp, Node* pEffectsOwner)
07653 {
07654     ERROR2IF(!(numcoords==2 || numcoords==3), FALSE, "Wrong number of coords passed to RenderBits");
07655 
07656     if (lpBitmapInfo->bmiHeader.biWidth==0 || lpBitmapInfo->bmiHeader.biHeight==0)
07657         return FALSE;
07658 
07659 //  TRACEUSER( "Phil", _T("RenderBits %x %d, %d, %d, %d, %d, %d\n"), lpBits, pCoords[0].x, pCoords[0].y, pCoords[1].x, pCoords[1].y, pCoords[2].x, pCoords[2].y);
07660     CWxBitmap          *pBitmap = new CWxBitmap(lpBitmapInfo, lpBits);
07661     KernelBitmap       *pkBitmap = new KernelBitmap(pBitmap, TRUE);
07662     // Assume 8BPP bitmaps must be greyscale...
07663     if (pkBitmap->GetBPP()==8)
07664     {
07665         LPRGBQUAD pPalette = pkBitmap->GetPaletteForBitmap();
07666         for ( INT32 i=0 ; i<0x100 ; i++ )
07667             (UINT32&)pPalette[i] = i*0x010101 ;
07668     }
07669 
07670     RenderBits(pkBitmap, pCoords, numcoords, bForceNoTransp, pEffectsOwner);
07671 
07672     if (pBitmap)
07673     {
07674         pBitmap->BMBytes = ((CWxBitmap*)OILBitmap::Default)->BMBytes;
07675     }
07676     if (pkBitmap)
07677     {
07678         delete pkBitmap;
07679         pkBitmap = NULL;
07680     }
07681 
07682     return TRUE;
07683 }
07684 
07685     
07686     
07687 /********************************************************************************************
07688 
07689 >   BOOL RenderRegion::RenderBits(KernelBitmap* pBitmap, DocCoord* pCoords, INT32 numcoords, BOOL bForceNoTransp = TRUE, Node* pEffectsOwner = NULL)
07690 
07691     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
07692     Created:    01/07/2004
07693     Inputs:     -
07694     Outputs:    -
07695     Returns:    TRUE if the bitmap was rendered
07696     Purpose:    To blit one bitmap defined by a DocRect into the current RenderRegion
07697     SeeAlso:    GRenderRegion::StartCapture
07698 
07699 ********************************************************************************************/
07700 
07701 BOOL RenderRegion::RenderBits(KernelBitmap* pkBitmap, DocCoord* pCoords, INT32 numcoords, BOOL bForceNoTransp, Node* pEffectsOwner)
07702 {
07703     ERROR2IF(!(numcoords==2 || numcoords==3), FALSE, "Wrong number of coords passed to RenderBits");
07704 
07705     if (pkBitmap->GetWidth()==0 || pkBitmap->GetHeight()==0)
07706         return FALSE;
07707 
07708 //  TRACEUSER( "Phil", _T("RenderBits %x %d, %d, %d, %d, %d, %d\n"), lpBits, pCoords[0].x, pCoords[0].y, pCoords[1].x, pCoords[1].y, pCoords[2].x, pCoords[2].y);
07709     SaveContext();
07710 
07711     // No lines on the rectangle
07712     SetLineColour(COLOUR_TRANS);
07713     SetLineWidth(0);
07714 
07715     BitmapFillAttribute *pBitmapAttr = new BitmapFillAttribute;
07716     pBitmapAttr->GetBitmapRef()->SetBitmap(pkBitmap);
07717 
07718     Path InkPath;
07719     if (numcoords==2)
07720     {
07721         //  This code was for upright rectangles only...
07722         InkPath.Initialise();
07723         InkPath.AddMoveTo(pCoords[0]);
07724         InkPath.AddLineTo(DocCoord(pCoords[1].x, pCoords[0].y));
07725         InkPath.AddLineTo(pCoords[1]);
07726         InkPath.AddLineTo(DocCoord(pCoords[0].x, pCoords[1].y));
07727         InkPath.AddLineTo(pCoords[0]);
07728         InkPath.CloseSubPath();
07729 
07730         pBitmapAttr->StartPoint = pCoords[0];
07731         pBitmapAttr->EndPoint   = DocCoord(pCoords[1].x, pCoords[0].y);
07732         pBitmapAttr->EndPoint2  = DocCoord(pCoords[0].x, pCoords[1].y);
07733     }
07734     else
07735     {
07736         // This version of the same code uses the array of 3 coords describing a parallelogram
07737         InkPath.Initialise();
07738         InkPath.AddMoveTo(pCoords[0]);
07739         InkPath.AddLineTo(pCoords[1]);
07740         InkPath.AddLineTo(DocCoord(pCoords[2].x+pCoords[1].x-pCoords[0].x, pCoords[2].y+pCoords[1].y-pCoords[0].y));
07741         InkPath.AddLineTo(pCoords[2]);
07742         InkPath.AddLineTo(pCoords[0]);
07743         InkPath.CloseSubPath();
07744 
07745         pBitmapAttr->StartPoint = pCoords[0];
07746         pBitmapAttr->EndPoint   = pCoords[1];
07747         pBitmapAttr->EndPoint2  = pCoords[2];
07748     }
07749 
07750     // Set bitmap attribute, and get the render region to throw it away when it's finished
07751     // with (hence the TRUE parameter).
07752     SetFillGeometry(pBitmapAttr, TRUE);
07753     SetSmoothingFlags(pBitmapAttr);
07754 
07755     // Set the mapping to have no repeat, otherwise we get artifacts at the edges when
07756     // anti-aliasing is enabled (see bug 1391).
07757     FillMappingLinearAttribute *pNoRepeatAttr = new FillMappingLinearAttribute;
07758 
07759     // Repeat value of '3' means 'repeat inverted' (there are no symbolic names for
07760     // these repeat values - shout at Will if you want some!).
07761 //  pNoRepeatAttr->Repeat = 3;
07762     pNoRepeatAttr->Repeat = 0;
07763 
07764     // Set mapping attribute, and get the render region to throw it away when it's finished
07765     // with (hence the TRUE parameter).
07766     SetFillMapping(pNoRepeatAttr, TRUE);
07767 
07768     // Force a 0% mix transparency (the transparency is in the bitmap)
07769     FlatTranspFillAttribute NoFillTransp(TT_NoTranspType);
07770     StrokeTranspAttribute NoLineTransp(TT_NoTranspType);
07771     if (bForceNoTransp)
07772     {
07773         SetTranspFillGeometry(&NoFillTransp, FALSE);
07774         SetLineTransp(&NoLineTransp, FALSE);
07775     }
07776 
07777     if (pEffectsOwner && pEffectsOwner->IsBounded())
07778         ((NodeRenderableBounded*)pEffectsOwner)->RenderEffectAttributes(this);
07779 
07780     // Draw the bitmap by rendering a bitmap filled path.
07781     InkPath.IsFilled = TRUE;
07782     DrawPath(&InkPath);
07783 
07784     SetSmoothingFlags(NULL);
07785 
07786     RestoreContext();
07787 
07788     return TRUE;
07789 }
07790 
07791     
07792     
07793 #ifdef _DEBUG
07794 void RenderRegion::DebugTrace()
07795 {
07796 }
07797 #endif

Generated on Sat Nov 10 03:46:45 2007 for Camelot by  doxygen 1.4.4