attr.cpp

Go to the documentation of this file.
00001 // $Id: attr.cpp 1361 2006-06-25 16:43:38Z 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 // The basic Camelot attributes
00100 
00101 /*
00102 */
00103 
00104 #include "camtypes.h"
00105 
00106 
00107 //#include "attr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00108 #include "lineattr.h"
00109 #include "userattr.h"
00110 //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00111 //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00112 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00113 #include "blendatt.h"
00114 #include "pathstrk.h"
00115 
00116 //#include "will2.h"
00117 
00118 DECLARE_SOURCE("$Revision: 1361 $");
00119 
00120 CC_IMPLEMENT_DYNAMIC(AttributeValue, CCObject);
00121 CC_IMPLEMENT_DYNCREATE(DashRec, CCObject);
00122 
00123 CC_IMPLEMENT_DYNCREATE(LineWidthAttribute,      AttributeValue);
00124 CC_IMPLEMENT_DYNCREATE(StartArrowAttribute,     AttributeValue);
00125 CC_IMPLEMENT_DYNCREATE(EndArrowAttribute,       AttributeValue);
00126 CC_IMPLEMENT_DYNCREATE(StartCapAttribute,       AttributeValue);
00127 CC_IMPLEMENT_DYNCREATE(JoinTypeAttribute,       AttributeValue);
00128 CC_IMPLEMENT_DYNCREATE(MitreLimitAttribute,     AttributeValue);
00129 CC_IMPLEMENT_DYNCREATE(WindingRuleAttribute,    AttributeValue);
00130 CC_IMPLEMENT_DYNCREATE(DashPatternAttribute,    AttributeValue);
00131 CC_IMPLEMENT_DYNCREATE(DrawingModeAttribute,    AttributeValue);
00132 CC_IMPLEMENT_DYNCREATE(UserAttribute,           AttributeValue);
00133 
00134 CC_IMPLEMENT_MEMDUMP(BlendAttrParam,            CC_CLASS_MEMDUMP);
00135 
00136 // Declare smart memory handling in Debug builds
00137 #define new CAM_DEBUG_NEW
00138 
00139 /********************************************************************************************
00140 
00141 >   virtual void AttributeValue::Restore(RenderRegion *pRegion, BOOL Temporary)
00142 
00143     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00144     Created:    03/02/94
00145     Inputs:     pRegion - the render region to restore the attribute into.
00146                 Temporary - TRUE if this is a temporary attribute, FALSE if it is
00147                             permanent (e.g. it's in a document tree).
00148     Purpose:    Used when restoring attributes from the render region's context stack.
00149 
00150                 This changes the relevant current rendering attribute to be that described
00151                 by this AttributeValue object.
00152                 
00153                 The Temporary flag controls what is done with this object when it is no
00154                 longer needed by the stack - i.e. the next time an attribute of this type
00155                 is restored from the stack, this attribute value will no longer be 
00156                 referenced, and so if the Temporary flag is TRUE (i.e. this object was
00157                 created to satisfy a direct attribute manipulation request as opposed to
00158                 rendering an attribute from a Camelot document tree), then the object is
00159                 deleted.
00160 
00161                 NB. This is a pure virtual function - any attribute value derived from
00162                     this class must implement this function so that it restores the
00163                     render region's attribute variables and objects to the correct state.
00164 
00165     SeeAlso:    RenderStack; AttributeValue; NodeAttribute;
00166                 AttributeValue::Render; AttributeValue::SimpleCopy
00167 
00168 ********************************************************************************************/
00169 
00170 /********************************************************************************************
00171 
00172 >   virtual void AttributeValue::Render(RenderRegion *pRegion)
00173 
00174     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00175     Created:    03/02/94
00176     Inputs:     pRegion - the render region to render this attribute into.
00177     Purpose:    Used when a render region needs to change a particular rendering attribute.
00178 
00179                 This usually occurs either because a tree is being rendered, and an
00180                 attribute node has been encountered and hence needs to be rendered, or
00181                 because a RenderRegion client (or sometimes the RenderRegion itself) has
00182                 asked to change an attribute directly, by name, as it were.  Examples of the
00183                 latter case might be:
00184 
00185                 MonoOn
00186                 pRegion->SetFillColour(COLOUR_BLACK);
00187                 pRegion->SetLineWidth(300);
00188                 pRegion->SetDrawingMode(DM_EORPEN);
00189                 MonoOff
00190 
00191                 NB. This is a pure virtual function - any attribute value derived from
00192                     this class must implement this function so that it sets the
00193                     render region's attribute variables and objects to the correct state.
00194                 
00195     SeeAlso:    RenderStack; AttributeValue; NodeAttribute;
00196                 AttributeValue::Restore; AttributeValue::SimpleCopy
00197 
00198 ********************************************************************************************/
00199 
00200 /********************************************************************************************
00201 
00202 >   virtual void AttributeValue::SimpleCopy(AttributeValue *pAttr)
00203 
00204     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00205     Created:    03/02/94
00206     Inputs:     pAttr - pointer to the AttributeValue to copy.
00207     Purpose:    This function provides a way of copying the contents of an AttributeValue
00208                 derived class to another.  It is assumed that the source object is the
00209                 same class as the destination object.
00210                 The data from the object pointed to by pAttr is copied into this object.
00211                 This is primarily used when cloning render regions - the context stack
00212                 must be copied, and if it points to any temporary objects, then they
00213                 must be copied too, to avoid multiple deletion errors.
00214     SeeAlso:    RenderStack; AttributeValue; NodeAttribute;
00215                 AttributeValue::Render; AttributeValue::Restore
00216 
00217 ********************************************************************************************/
00218 
00219 
00220 /********************************************************************************************
00221 
00222 >   NodeAttribute *AttributeValue::MakeNode()
00223 
00224     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00225     Created:    11/04/94
00226     Returns:    Pointer to NodeAttribute object, or NULL if out of memory.
00227     Purpose:    Given an AttributeValue object, construct the appropriate NodeAttribute
00228                 object which can be put into a document tree.
00229                 This should be over-ridden for all derived AttributeValue classes, except
00230                 those that cannot be put into the document tree (e.g. DrawingModeAttribute).
00231                 The base class version (i.e. this one) will always ENSURE because it
00232                 should not be called.
00233     Errors:     Out of memory.
00234     SeeAlso:    NodeAttribute
00235 
00236 ********************************************************************************************/
00237 
00238 NodeAttribute* AttributeValue::MakeNode()
00239 {
00240     TRACE( wxT("Error - Base class MakeNode() function called for a %s\n"),
00241           GetRuntimeClass()->GetClassName() );
00242     return NULL;
00243 }
00244 
00245 
00246 /********************************************************************************************
00247 >   NodeAttribute* AttributeValue::MakeNode(Node* pContextNode, AttachNodeDirection Direction)
00248 
00249     Author:     Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com>
00250     Created:    26/5/95
00251     Inputs:     pContextNode - 
00252                 Direction    - 
00253     Returns:    Pointer to NodeAttribute object, or NULL if out of memory.
00254     Purpose:    Convert an attribute value into an attribute node and attatch to the context node
00255     SeeAlso:    AttributeValue::MakeNode()
00256 ********************************************************************************************/
00257 
00258 NodeAttribute* AttributeValue::MakeNode(Node* pContextNode, AttachNodeDirection Direction)
00259 {
00260     NodeAttribute* pAttrNode=MakeNode();
00261     if (pAttrNode!=NULL)
00262         pAttrNode->AttachNode(pContextNode, Direction, FALSE);
00263     return pAttrNode;
00264 }
00265 
00266 
00267 /********************************************************************************************
00268 
00269 >   BOOL AttributeValue::IsDifferent(AttributeValue *pAttr)
00270 
00271     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00272     Created:    12/04/94
00273     Inputs:     pAttr - the attribute to compare against this one.
00274     Returns:    TRUE if objects represent different attributes (e.g. one is red and the 
00275                      other is blue);
00276                 FALSE otherwise (i.e. they represent the same attribute, e.g. both 
00277                       represent 0.25pt lines).
00278     Purpose:    Compare two AttributeValue objects.
00279                 The base class version always returns TRUE - derived classes should
00280                 override this function to provide functionality.
00281     SeeAlso:    AttributeManager::ApplyBasedOnDefaults
00282 
00283 ********************************************************************************************/
00284 
00285 BOOL AttributeValue::IsDifferent(AttributeValue*)
00286 {
00287     return TRUE;
00288 }
00289 
00290 /********************************************************************************************
00291 
00292 >   BOOL AttributeValue::Blend(BlendAttrParam *pBlendParam)
00293 
00294     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00295     Created:    26/10/94
00296     Inputs:     pBlendParam = ptr to param holding all data needed for the attr val to blend
00297     Outputs:    if TRUE  returned, pBlendParam->GetBlendedAttrVal() will get ptr to the blended attr val
00298                 if FALSE returned, pBlendParam->GetBlendedAttrVal() will return NULL
00299     Returns:    TRUE if successful, FALSE otherwaie
00300     Purpose:    Blends this attr val with the attr val associated with the other NodeAttribute
00301                 ptr held in pBlendParam
00302                 This base version just returns FALSE, and sets the blended attr val ptr to NULL
00303     Errors:     Errors in debug builds
00304     SeeAlso:    -
00305 
00306 ********************************************************************************************/
00307 
00308 BOOL AttributeValue::Blend(BlendAttrParam *pBlendParam)
00309 {
00310     ERROR3("AttributeValue::Blend() called");
00311     pBlendParam->SetBlendedAttrVal(NULL);
00312     return FALSE;
00313 }
00314 
00315 
00316 /********************************************************************************************
00317 
00318 >   virtual AttributeValue *AttributeValue::MouldIntoStroke(PathStrokerVector *pMoulder,
00319                                                                 double TransScale);
00320     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00321     Created:    23/2/97
00322 
00323     Inputs:     pMoulder    - A PathStrokerVector which knows how to translate points to "mould" them
00324                               (May be NULL, in which case moulding of points does not occur)
00325 
00326                 TransScale  - A fraction between 0.0 and 1.0, by which any transparency
00327                               values in this geometry will be scaled, allowing the caller to
00328                               effectively apply a flat transparency level to everything that is
00329                               moulded. Use 1.0 to leave transparency unaltered.
00330 
00331     Returns:    NULL if there is no need to mould this attribute (so you should just
00332                 render the original attribute), else
00333                 A pointer to a copy of this object, suitably moulded and adjusted for
00334                 the transparency scaling. The caller must delete the copy when finished
00335                 with it.
00336 
00337     Purpose:    Helper function for the PathStrokerVector class, which "moulds" clipart
00338                 subtrees to lie along an arbitrary path.
00339 
00340                 This function is called to mould attributes, so that:
00341                     * Fill/Trans geometries can be moulded
00342                     * Line Widths can be scaled to an appropriate value
00343                     * A global flat transparency can be applied
00344                     etc
00345 
00346     Notes:      The base class does nothing (it returns NULL - by default, attrs assume that
00347                 they will work OK when moulded without being changed)
00348 
00349 ********************************************************************************************/
00350 
00351 AttributeValue *AttributeValue::MouldIntoStroke(PathStrokerVector *pMoulder, double TransScale)
00352 {
00353     return(NULL);
00354 }
00355 
00356 
00357 /********************************************************************************************
00358 >   virtual BOOL AttributeValue::CanBeRenderedDirectly()
00359     Author:     Ilan_Copelyn (Xara Group Ltd) <camelotdev@xara.com>
00360     Created:    27/4/00
00361     Inputs:     
00362     Outputs:    
00363     Returns:    
00364     Purpose:    There is only one case to date where AttributeValue are rendered directly ie 
00365                 without calling the render function of their associated/containing NodeAttribute
00366                 class. This occurs in RenderRegion::InitDevice().
00367                 This function is to determine if the AttributeValue can be rendered independently
00368                 of the NodeAttribute. It is only used in RR::InitDevice() at present but I am
00369                 defining it in order to highlight this new characteristic of nodes which are geometry
00370                 dependent, in order to ensure that this becomes an acknowledged attribute design
00371                 consideration (ie so that these special cases get handled correctly by future code
00372                 which may need to render AttributeValues directly)
00373     Errors:     
00374     SeeAlso:    -
00375 ********************************************************************************************/
00376 BOOL AttributeValue::CanBeRenderedDirectly()
00377 {
00378     return TRUE;
00379 }
00380 
00381 
00382 //------------------------------------------------------------
00383 //------------------------------------------------------------
00384 //------------------------------------------------------------
00385 
00386 LineWidthAttribute::LineWidthAttribute()
00387 {
00388     LineWidth = 500 + 1;  // BODGE The 1 added by Simon 25/10/95, so that the default attr 
00389                           // is different from the current attr. That way line scaling at 
00390                           // least works in simple cases.
00391 }
00392 
00393 /********************************************************************************************
00394 
00395 >   void LineWidthAttribute::Render(RenderRegion *pRegion)
00396 
00397     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00398     Created:    03/02/94
00399     Inputs:     pRegion - the render region to render this attribute into.
00400     Purpose:    Sets the line width attribute for the given render region. i.e. all
00401                 lines drawn will now be drawn with this line width.
00402     SeeAlso:    LineWidthAttribute; RenderStack; AttributeValue; NodeAttribute;
00403                 LineWidthAttribute::Restore; LineWidthAttribute::SimpleCopy;
00404                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
00405 
00406 ********************************************************************************************/
00407 
00408 void LineWidthAttribute::Render(RenderRegion *pRegion, BOOL Temp)
00409 {
00410     pRegion->SetLineWidth(this, Temp);
00411 }
00412 
00413 /********************************************************************************************
00414 
00415 >   void LineWidthAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
00416 
00417     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00418     Created:    03/02/94
00419     Inputs:     pRegion - the render region to restore the attribute into.
00420                 Temp    - TRUE if this is a temporary attribute, FALSE if it is
00421                           permanent (e.g. it's in a document tree).
00422     Purpose:    Restores the line width attribute for the given render region. i.e. all
00423                 lines drawn will now be drawn with this line width.
00424     SeeAlso:    LineWidthAttribute; RenderStack; AttributeValue; NodeAttribute;
00425                 LineWidthAttribute::Render; LineWidthAttribute::SimpleCopy;
00426                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
00427 
00428 ********************************************************************************************/
00429 
00430 void LineWidthAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
00431 {
00432     pRegion->RestoreLineWidth(this, Temp);
00433 }
00434 
00435 /********************************************************************************************
00436 
00437 >   void LineWidthAttribute::SimpleCopy(AttributeValue *pValue)
00438 
00439     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00440     Created:    03/02/94
00441     Inputs:     pAttr - pointer to the AttributeValue to copy.
00442     Purpose:    See AttributeValue::SimpleCopy
00443     SeeAlso:    LineWidthAttribute; RenderStack; AttributeValue; NodeAttribute;
00444                 LineWidthAttribute::Render; LineWidthAttribute::Restore;
00445                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
00446 
00447 ********************************************************************************************/
00448 
00449 void LineWidthAttribute::SimpleCopy(AttributeValue *pValue)
00450 {
00451     LineWidth = ((LineWidthAttribute *) pValue)->LineWidth;
00452 }
00453 
00454 /********************************************************************************************
00455 
00456 >   BOOL LineWidthAttribute::Init()
00457 
00458     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00459     Created:    11/04/94
00460     Returns:    TRUE - initialised ok; FALSE if not.
00461     Purpose:    Registers line width attribute, and provides a default attribute to give
00462                 0.25pt lines.
00463     Errors:     Out of memory.
00464     SeeAlso:    AttributeManager
00465 
00466 ********************************************************************************************/
00467 
00468 BOOL LineWidthAttribute::Init()
00469 {
00470     // Default to 0.25pt lines
00471     LineWidthAttribute *pAttr = new LineWidthAttribute;
00472     if (pAttr == NULL)
00473         return FALSE;
00474 
00475     UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), 
00476                                                          pAttr);
00477     if (ID == ATTR_BAD_ID)
00478         return FALSE;
00479     ENSURE(ID == ATTR_LINEWIDTH, "Incorrect ID for attribute!");
00480     return TRUE;
00481 }
00482 
00483 /********************************************************************************************
00484 
00485 >   NodeAttribute *LineWidthAttribute::MakeNode()
00486 
00487     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00488     Created:    11/04/94
00489     Returns:    Pointer to the new node, or NULL if out of memory.
00490     Purpose:    Make a AttrLineWidth node from this line width attribute.
00491     Errors:     Out of memory
00492     SeeAlso:    AttributeValue::MakeNode
00493 
00494 ********************************************************************************************/
00495 
00496 NodeAttribute *LineWidthAttribute::MakeNode()
00497 {
00498     // Create new attribute node
00499     AttrLineWidth *pAttr = new AttrLineWidth();
00500 
00501     // Copy attribute value into the new node.
00502     pAttr->Value.SimpleCopy(this);
00503 
00504     // Return the new node
00505     return pAttr;
00506 }
00507 
00508 /********************************************************************************************
00509 
00510 >   BOOL LineWidthAttribute::IsDifferent(AttributeValue *pAttr)
00511 
00512     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
00513     Created:    12/04/94
00514     Purpose:    See base class version.
00515     Errors:     The two attributes are not of the same type.
00516     SeeAlso:    AttributeValue::IsDifferent
00517 
00518 ********************************************************************************************/
00519 
00520 BOOL LineWidthAttribute::IsDifferent(AttributeValue *pAttr)
00521 {
00522     ENSURE(GetRuntimeClass() == pAttr->GetRuntimeClass(), 
00523            "Different attribute types in AttributeValue::IsDifferent()");
00524     return ((LineWidthAttribute *) pAttr)->LineWidth != LineWidth;
00525 }
00526 
00527 /********************************************************************************************
00528 
00529 >   BOOL LineWidthAttribute::Blend(BlendAttrParam *pBlendParam)
00530 
00531     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
00532     Created:    26/10/94
00533     Inputs:     pBlendParam = ptr to param holding all data needed for the attr val to blend
00534     Outputs:    if TRUE  returned, pBlendParam->GetBlendedAttrVal() will get ptr to the blended attr val
00535                 if FALSE returned, pBlendParam->GetBlendedAttrVal() will return NULL
00536     Returns:    TRUE if successful, FALSE otherwaie
00537     Purpose:    Blends this attr val with the attr val held in pBlendParam
00538     SeeAlso:    -
00539 
00540 ********************************************************************************************/
00541 
00542 BOOL LineWidthAttribute::Blend(BlendAttrParam *pBlendParam)
00543 {
00544     // Check entry param
00545     ERROR3IF(pBlendParam == NULL,"NULL entry param");
00546     if (pBlendParam == NULL) return FALSE;
00547 
00548     LineWidthAttribute* pOtherLineAttr = (LineWidthAttribute*) pBlendParam->GetOtherAttrVal();
00549 
00550     // Check that the other line attr val is not NULL, and is a LineWidthAttribute
00551     ERROR3IF(pOtherLineAttr == NULL,"NULL other attr val");
00552     ERROR3IF(!IS_A(pOtherLineAttr,LineWidthAttribute),"other attr val not a line width attr");
00553     if (pOtherLineAttr == NULL || !IS_A(pOtherLineAttr,LineWidthAttribute)) return FALSE;
00554 
00555     // Get a new LineWidthAttribute to hold the blended version, (return FALSE if this fails)
00556     LineWidthAttribute* pBlendedLineAttr = new LineWidthAttribute;
00557     if (pBlendedLineAttr == NULL) return FALSE;
00558 
00559     // The blended line width is done by linearly tending the start line width to the
00560     // end line width, proportionally to the blend ration (0.0 to 1.0)
00561 
00562     // DeltaWidth is the amount to subtract from this LineWidth, and is proportional to BlendRatio
00563     MILLIPOINT DeltaWidth = INT32((LineWidth - pOtherLineAttr->LineWidth) * pBlendParam->GetBlendRatio());
00564 
00565     pBlendedLineAttr->LineWidth = LineWidth - DeltaWidth;
00566 
00567     // Store the ptr to the new blended line width attr val
00568     pBlendParam->SetBlendedAttrVal(pBlendedLineAttr);
00569 
00570     return TRUE;
00571 }
00572 
00573 /********************************************************************************************
00574 
00575 >   virtual AttributeValue *LineWidthAttribute::MouldIntoStroke(PathStrokerVector *pMoulder,
00576                                                                 double TransScale);
00577     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00578     Created:    23/2/97
00579 
00580     Inputs:     pMoulder    - A PathStrokerVector which knows how to translate points to "mould" them
00581                               (May be NULL, in which case moulding of points does not occur)
00582 
00583                 TransScale  - A fraction between 0.0 and 1.0, by which any transparency
00584                               values in this geometry will be scaled, allowing the caller to
00585                               effectively apply a flat transparency level to everything that is
00586                               moulded. Use 1.0 to leave transparency unaltered.
00587 
00588     Returns:    NULL if there is no need to mould this attribute (so you should just
00589                 render the original attribute), else
00590                 A pointer to a copy of this object, suitably moulded and adjusted for
00591                 the transparency scaling. The caller must delete the copy when finished
00592                 with it.
00593 
00594     Purpose:    Helper function for the PathStrokerVector class, which "moulds" clipart
00595                 subtrees to lie along an arbitrary path.
00596 
00597                 This function is called to mould attributes, so that:
00598                     * Fill/Trans geometries can be moulded
00599                     * Line Widths can be scaled to an appropriate value
00600                     * A global flat transparency can be applied
00601                     etc
00602 
00603     Notes:      The base class does nothing (it returns NULL - by default, attrs assume that
00604                 they will work OK when moulded without being changed)
00605 
00606 ********************************************************************************************/
00607 
00608 AttributeValue *LineWidthAttribute::MouldIntoStroke(PathStrokerVector *pMoulder, double TransScale)
00609 {
00610 #ifdef VECTOR_STROKING // Neville 6/8/97
00611     LineWidthAttribute* pMouldedAttr = new LineWidthAttribute;
00612     if (pMouldedAttr != NULL)
00613     {
00614         double ScaledWidth = pMoulder->GetScaleFactor() * (double)LineWidth;
00615         if (ScaledWidth < 1.0)
00616             ScaledWidth = 1.0;
00617         else if (pMouldedAttr->LineWidth > 1000000.0)
00618             ScaledWidth = 1000000.0;
00619         pMouldedAttr->LineWidth = (INT32)ScaledWidth;
00620     }
00621 
00622     return(pMouldedAttr);
00623 #else
00624     return NULL;
00625 #endif
00626 }
00627 
00628 
00629 
00630 //-----------------------------------------------------------------------
00631 //-----------------------------------------------------------------------
00632 //-----------------------------------------------------------------------
00633 //-----------------------------------------------------------------------
00634 
00635 /********************************************************************************************
00636 
00637 >   DashPatternAttribute::DashPatternAttribute()
00638 
00639     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00640     Created:    14/10/94
00641     Purpose:    Default Constructor for dash pattern attribute.
00642     Errors:     -
00643     SeeAlso:    -
00644 
00645 ********************************************************************************************/
00646 
00647 DashPatternAttribute::DashPatternAttribute()
00648 {
00649     DashPattern.Elements = 0;
00650     DashPattern.DashStart = 0;
00651 
00652     DashPattern.ElementData = NULL;
00653 
00654     DashPattern.LineWidth = 72000/4;
00655 }
00656 
00657 /********************************************************************************************
00658 
00659 >   DashPatternAttribute::~DashPatternAttribute()
00660 
00661     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00662     Created:    14/10/94
00663     Purpose:    Destructor for dash pattern attribute.
00664     SeeAlso:    -
00665 
00666 ********************************************************************************************/
00667 
00668 DashPatternAttribute::~DashPatternAttribute()
00669 {
00670     if (DashPattern.ElementData)
00671         delete DashPattern.ElementData;
00672 }
00673 
00674 /********************************************************************************************
00675 
00676 >   void DashPatternAttribute::Render(RenderRegion *pRegion)
00677 
00678     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00679     Created:    21/10/94
00680     Inputs:     pRegion - the render region to render this attribute into.
00681     Purpose:    Sets the dash pattern attribute for the given render region. i.e. all
00682                 lines drawn will now be drawn with this dash pattern.
00683     SeeAlso:    -
00684 
00685 ********************************************************************************************/
00686 
00687 void DashPatternAttribute::Render(RenderRegion *pRegion, BOOL Temp)
00688 {
00689     pRegion->SetDashPattern(this, Temp);
00690 }
00691 
00692 /********************************************************************************************
00693 
00694 >   void DashPatternAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
00695 
00696     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00697     Created:    21/10/94
00698     Inputs:     pRegion - the render region to restore the attribute into.
00699                 Temp    - TRUE if this is a temporary attribute, FALSE if it is
00700                           permanent (e.g. it's in a document tree).
00701     Purpose:    Restores the dash pattern attribute for the given render region. i.e. all
00702                 lines drawn will now be drawn with this dash pattern.
00703     SeeAlso:    -
00704 
00705 ********************************************************************************************/
00706 
00707 void DashPatternAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
00708 {
00709     pRegion->RestoreDashPattern(this, Temp);
00710 }
00711 
00712 /********************************************************************************************
00713 
00714 >   BOOL DashPatternAttribute::SetDashPattern(DashRec& NewDash)
00715 
00716     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00717     Created:    14/10/94
00718     Purpose:    Sets the dash pattern for this attribute.
00719     Errors:     No memory.
00720     SeeAlso:    -
00721 
00722 ********************************************************************************************/
00723 
00724 BOOL DashPatternAttribute::SetDashPattern(DashRec& NewDash)
00725 {
00726     DashPattern.Elements            = NewDash.Elements;
00727     DashPattern.DashStart           = NewDash.DashStart;
00728     DashPattern.LineWidth           = NewDash.LineWidth;
00729     DashPattern.DashID              = NewDash.DashID;
00730     DashPattern.ScaleWithLineWidth  = NewDash.ScaleWithLineWidth;
00731 
00732     if (NewDash.Elements == 0)
00733         return TRUE;
00734 
00735     if (DashPattern.ElementData != NULL)
00736         delete DashPattern.ElementData;
00737 
00738     DashPattern.ElementData = new INT32[NewDash.Elements];
00739 
00740     if (DashPattern.ElementData == NULL)
00741         return FALSE;
00742 
00743     for (INT32 element = 0; element < NewDash.Elements; element++)
00744     {
00745         DashPattern.ElementData[element] = NewDash.ElementData[element];
00746     }
00747 
00748     return TRUE;
00749 }
00750 
00751 /********************************************************************************************
00752 
00753 >   BOOL DashPatternAttribute::SetStockDashPattern(StockDash NewDash)
00754 
00755     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
00756     Created:    14/10/94
00757     Purpose:    Sets the dash pattern for this attribute.
00758     Errors:     No memory.
00759     SeeAlso:    -
00760 
00761 ********************************************************************************************/
00762 
00763 BOOL DashPatternAttribute::SetStockDashPattern(StockDash NewDash)
00764 {
00765     DashRec StockDash;
00766     DashElement DashArray[8];
00767 
00768     const INT32 DashUnit = StockDash.LineWidth;
00769 
00770     StockDash.DashID = NewDash;
00771 
00772     switch (NewDash)
00773     {
00774         case SD_SOLID:
00775             StockDash.Elements = 0;
00776             SetDashPattern(StockDash);
00777             break;
00778 
00779         case SD_DASH1:
00780             StockDash.Elements = 2;
00781             StockDash.DashStart = 0;
00782             StockDash.ElementData = DashArray;
00783             DashArray[0] = DashUnit*2;
00784             DashArray[1] = DashUnit*2;
00785 
00786             SetDashPattern(StockDash);
00787             break;
00788 
00789         case SD_DASH2:
00790             StockDash.Elements = 2;
00791             StockDash.DashStart = 0;
00792             StockDash.ElementData = DashArray;
00793             DashArray[0] = DashUnit*4;
00794             DashArray[1] = DashUnit*2;
00795 
00796             SetDashPattern(StockDash);
00797             break;
00798 
00799         case SD_DASH3:
00800             StockDash.Elements = 2;
00801             StockDash.DashStart = 0;
00802             StockDash.ElementData = DashArray;
00803             DashArray[0] = DashUnit*8;
00804             DashArray[1] = DashUnit*2;
00805 
00806             SetDashPattern(StockDash);
00807             break;
00808 
00809         case SD_DASH4:
00810             StockDash.Elements = 2;
00811             StockDash.DashStart = 0;
00812             StockDash.ElementData = DashArray;
00813             DashArray[0] = DashUnit*16;
00814             DashArray[1] = DashUnit*2;
00815 
00816             SetDashPattern(StockDash);
00817             break;
00818 
00819         case SD_DASH5:
00820             StockDash.Elements = 2;
00821             StockDash.DashStart = 0;
00822             StockDash.ElementData = DashArray;
00823             DashArray[0] = DashUnit*24;
00824             DashArray[1] = DashUnit*2;
00825 
00826             SetDashPattern(StockDash);
00827             break;
00828 
00829         case SD_DASH6:
00830             StockDash.Elements = 2;
00831             StockDash.DashStart = 0;
00832             StockDash.ElementData = DashArray;
00833             DashArray[0] = DashUnit*4;
00834             DashArray[1] = DashUnit*4;
00835 
00836             SetDashPattern(StockDash);
00837             break;
00838 
00839         case SD_DASH7:
00840             StockDash.Elements = 2;
00841             StockDash.DashStart = 0;
00842             StockDash.ElementData = DashArray;
00843             DashArray[0] = DashUnit*8;
00844             DashArray[1] = DashUnit*4;
00845 
00846             SetDashPattern(StockDash);
00847             break;
00848 
00849         case SD_DASH8:
00850             StockDash.Elements = 2;
00851             StockDash.DashStart = 0;
00852             StockDash.ElementData = DashArray;
00853             DashArray[0] = DashUnit*16;
00854             DashArray[1] = DashUnit*4;
00855 
00856             SetDashPattern(StockDash);
00857             break;
00858 
00859         case SD_DASH9:
00860             StockDash.Elements = 2;
00861             StockDash.DashStart = 0;
00862             StockDash.ElementData = DashArray;
00863             DashArray[0] = DashUnit*8;
00864             DashArray[1] = DashUnit*8;
00865 
00866             SetDashPattern(StockDash);
00867             break;
00868 
00869         case SD_DASH10:
00870             StockDash.Elements = 2;
00871             StockDash.DashStart = 0;
00872             StockDash.ElementData = DashArray;
00873             DashArray[0] = DashUnit*16;
00874             DashArray[1] = DashUnit*8;
00875 
00876             SetDashPattern(StockDash);
00877             break;
00878 
00879         case SD_DASH11:
00880             StockDash.Elements = 4;
00881             StockDash.DashStart = 0;
00882             StockDash.ElementData = DashArray;
00883             DashArray[0] = DashUnit*4;
00884             DashArray[1] = DashUnit*2;
00885             DashArray[2] = DashUnit*2;
00886             DashArray[3] = DashUnit*2;
00887 
00888             SetDashPattern(StockDash);
00889             break;
00890 
00891         case SD_DASH12:
00892             StockDash.Elements = 4;
00893             StockDash.DashStart = 0;
00894             StockDash.ElementData = DashArray;
00895             DashArray[0] = DashUnit*8;
00896             DashArray[1] = DashUnit*2;
00897             DashArray[2] = DashUnit*2;
00898             DashArray[3] = DashUnit*2;
00899 
00900             SetDashPattern(StockDash);
00901             break;
00902 
00903         case SD_DASH13:
00904             StockDash.Elements = 4;
00905             StockDash.DashStart = 0;
00906             StockDash.ElementData = DashArray;
00907             DashArray[0] = DashUnit*16;
00908             DashArray[1] = DashUnit*2;
00909             DashArray[2] = DashUnit*2;
00910             DashArray[3] = DashUnit*2;
00911 
00912             SetDashPattern(StockDash);
00913             break;
00914 
00915         case SD_DASH14:
00916             StockDash.Elements = 4;
00917             StockDash.DashStart = 0;
00918             StockDash.ElementData = DashArray;
00919             DashArray[0] = DashUnit*8;
00920             DashArray[1] = DashUnit*2;
00921             DashArray[2] = DashUnit*4;
00922             DashArray[3] = DashUnit*2;
00923 
00924             SetDashPattern(StockDash);
00925             break;
00926 
00927         case SD_DASH15:
00928             StockDash.Elements = 4;
00929             StockDash.DashStart = 0;
00930             StockDash.ElementData = DashArray;
00931             DashArray[0] = DashUnit*16;
00932             DashArray[1] = DashUnit*2;
00933             DashArray[2] = DashUnit*4;
00934             DashArray[3] = DashUnit*2;
00935 
00936             SetDashPattern(StockDash);
00937             break;
00938 
00939         case SD_DASH16:
00940             StockDash.Elements = 6;
00941             StockDash.DashStart = 0;
00942             StockDash.ElementData = DashArray;
00943             DashArray[0] = DashUnit*8;
00944             DashArray[1] = DashUnit*2;
00945             DashArray[2] = DashUnit*2;
00946             DashArray[3] = DashUnit*2;
00947             DashArray[4] = DashUnit*2;
00948             DashArray[5] = DashUnit*2;
00949 
00950             SetDashPattern(StockDash);
00951             break;
00952 
00953         case SD_DASH17:
00954             StockDash.Elements = 6;
00955             StockDash.DashStart = 0;
00956             StockDash.ElementData = DashArray;
00957             DashArray[0] = DashUnit*16;
00958             DashArray[1] = DashUnit*2;
00959             DashArray[2] = DashUnit*2;
00960             DashArray[3] = DashUnit*2;
00961             DashArray[4] = DashUnit*2;
00962             DashArray[5] = DashUnit*2;
00963 
00964             SetDashPattern(StockDash);
00965             break;
00966 
00967         case SD_DASH18:
00968             StockDash.Elements = 8;
00969             StockDash.DashStart = 0;
00970             StockDash.ElementData = DashArray;
00971             DashArray[0] = DashUnit*8;
00972             DashArray[1] = DashUnit*2;
00973             DashArray[2] = DashUnit*2;
00974             DashArray[3] = DashUnit*2;
00975             DashArray[4] = DashUnit*2;
00976             DashArray[5] = DashUnit*2;
00977             DashArray[6] = DashUnit*2;
00978             DashArray[7] = DashUnit*2;
00979 
00980             SetDashPattern(StockDash);
00981             break;
00982 
00983         case SD_DASH19:
00984             StockDash.Elements = 8;
00985             StockDash.DashStart = 0;
00986             StockDash.ElementData = DashArray;
00987             DashArray[0] = DashUnit*16;
00988             DashArray[1] = DashUnit*2;
00989             DashArray[2] = DashUnit*2;
00990             DashArray[3] = DashUnit*2;
00991             DashArray[4] = DashUnit*2;
00992             DashArray[5] = DashUnit*2;
00993             DashArray[6] = DashUnit*2;
00994             DashArray[7] = DashUnit*2;
00995 
00996             SetDashPattern(StockDash);
00997             break;
00998 
00999         case SD_DASH20:
01000             StockDash.Elements = 8;
01001             StockDash.DashStart = 0;
01002             StockDash.ElementData = DashArray;
01003             DashArray[0] = DashUnit*8;
01004             DashArray[1] = DashUnit*2;
01005             DashArray[2] = DashUnit*2;
01006             DashArray[3] = DashUnit*2;
01007             DashArray[4] = DashUnit*4;
01008             DashArray[5] = DashUnit*2;
01009             DashArray[6] = DashUnit*2;
01010             DashArray[7] = DashUnit*2;
01011 
01012             SetDashPattern(StockDash);
01013             break;
01014 
01015         case SD_DASH_GUIDELAYER:
01016             // This is the dash pattern used to render objects in guide layers with.
01017             // It's different to the others in that the dashed aren't scaled relative to the line width
01018             StockDash.Elements = 2;
01019             StockDash.DashStart = 0;
01020             StockDash.ElementData = DashArray;
01021             StockDash.ScaleWithLineWidth = FALSE;
01022             DashArray[0] = DashUnit*2;
01023             DashArray[1] = DashUnit*2;
01024 
01025             SetDashPattern(StockDash);
01026             break;
01027 
01028         default:
01029             StockDash.Elements = 0;
01030             StockDash.DashStart = 0;
01031             StockDash.ElementData = NULL;
01032 
01033             SetDashPattern(StockDash);
01034             break;
01035     }
01036 
01037     return TRUE;
01038 }
01039 
01040 DashRec::DashRec()
01041 {
01042     Elements = 0;
01043     DashStart = 0;
01044     ElementData = NULL;
01045     DashID = 0;
01046     ScaleWithLineWidth = TRUE;
01047 
01048     LineWidth = 72000/4;
01049 }
01050 
01051 String_256 DashRec::GetStockDashName(StockDash DashType)
01052 {
01053     String_256 DashName;
01054 
01055     switch (DashType)
01056     {
01057         case SD_SOLID:
01058             DashName.Load(_R(IDS_K_ATTR_SOLIDLINE));
01059             break;
01060 
01061         default:
01062             DashName.Load(_R(IDS_K_ATTR_DASHLINE));
01063             break;
01064     }
01065 
01066     return DashName;
01067 }
01068 
01069 /********************************************************************************************
01070 
01071 >   void DashRec::CheckAndFix()
01072 
01073     Author:     Ben_Summers (Xara Group Ltd) <camelotdev@xara.com>
01074     Created:    04/07/95
01075     Purpose:    Checks a dash pattern, and fixes it if it's not very nice.
01076     Errors:     No errors.
01077     SeeAlso:    -
01078 
01079 ********************************************************************************************/
01080 
01081 void DashRec::CheckAndFix()
01082 {
01083     // check the dash offset
01084     if(DashStart < 0)
01085         DashStart = 0;
01086 
01087     if(Elements == 0)
01088         return;
01089 
01090     // check the dash pattern elements
01091     INT32 End = 0;
01092     INT32 l;
01093 
01094     for(l = 0; l < Elements; l++)
01095     {
01096 
01097         // is this element OK?
01098         if(ElementData[l] > 0)
01099         {
01100             // element is OK...
01101             if(End != l)
01102             {
01103                 // move it back if something has been deleted before it
01104                 ElementData[End] = ElementData[l];
01105             }
01106             End++;
01107         }
01108     }
01109 
01110     // have we got enough elements?
01111     if(End < 1)
01112     {
01113         // no elements - make it a solid outline
01114         Elements = 0;
01115         DashID = SD_SOLID;
01116     }
01117     else
01118     {
01119         Elements = End;
01120     }
01121 }
01122 
01123 /********************************************************************************************
01124 
01125 >   void DashRec::CheckIfDefaultPattern()
01126 
01127     Author:     Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com>
01128     Created:    26/07/96
01129     Purpose:    Checks a dash pattern to see if it is one of the built in ones and if so
01130                 then sets the ID to be correct.
01131                 Not the best way but a) its quick, b) it works, c) not three million
01132                 big rebuilds of 330 files to get it right
01133 
01134                 This is mainly required for the following reason:
01135                 When we save Native files we at present save out a dash pattern ID and then
01136                 save out the full dash pattern definition! This is ok apart from wasting space.
01137                 The problem happens when we load the information back in, we load the id and apply
01138                 the relevent dash pattern and then load the definition and apply it, zapping the
01139                 id.
01140     Errors:     No errors.
01141     SeeAlso:    -
01142 
01143 ********************************************************************************************/
01144 
01145 /* Disable the code as completely useless as we scale the line widths when we first save them
01146    in a old format xar file! So the simple fix becomes a nightmare!
01147 
01148 void DashRec::CheckIfDefaultPattern()
01149 {
01150     // Check to see if the pattern corresponds to one of our built in ones
01151     // If so then set the DashID accordingly
01152     // Default is do nothing
01153     // SD_SOLID == 0 so if this then do nothing
01154 
01155     const INT32 DefLineWidth = 72000/4;
01156     const INT32 DashUnit = DefLineWidth;
01157 
01158     // All the useful defaults are defined like this using the default constructed
01159     // values, so if they are different then its not default pattern
01160     if (LineWidth != DefLineWidth || DashID != 0 || DashStart != 0 || Elements == 0)
01161         return;
01162     
01163     // The SD_DASH_GUIDELAYER has 2 elements and is the only one to have ScaleWithLineWidth = FALSE
01164     if (ScaleWithLineWidth != TRUE && Elements != 2)
01165         return;
01166 
01167     switch (Elements)
01168     {
01169         case 2:
01170         {
01171             switch (ElementData[1])
01172             {
01173                 case DashUnit*2:
01174                 {
01175                     switch (ElementData[0])
01176                     {
01177                         case DashUnit*2:
01178                             if (ScaleWithLineWidth)
01179                                 DashID = SD_DASH1;
01180                             else
01181                                 DashID = SD_DASH_GUIDELAYER;
01182                             break;
01183                         case DashUnit*4:
01184                             DashID = SD_DASH2;
01185                             break;
01186                         case DashUnit*8:
01187                             DashID = SD_DASH3;
01188                             break;
01189                         case DashUnit*16:
01190                             DashID = SD_DASH4;
01191                             break;
01192                         case DashUnit*24:
01193                             DashID = SD_DASH5;
01194                             break;
01195                     }
01196                 }
01197                 break;
01198 
01199                 case DashUnit*4:
01200                 {
01201                     switch (ElementData[0])
01202                     {
01203                         case DashUnit*4:
01204                             DashID = SD_DASH6;
01205                             break;
01206                         case DashUnit*8:
01207                             DashID = SD_DASH7;
01208                             break;
01209                         case DashUnit*16:
01210                             DashID = SD_DASH8;
01211                             break;
01212                     }
01213                 }
01214                 break;
01215 
01216                 case DashUnit*8:
01217                 {
01218                     switch (ElementData[0])
01219                     {
01220                         case DashUnit*8:
01221                             DashID = SD_DASH9;
01222                             break;
01223                         case DashUnit*16:
01224                             DashID = SD_DASH10;
01225                             break;
01226                     }
01227                 }
01228                 break;
01229             }
01230             break;
01231         }
01232 
01233         case 4:
01234         { 
01235             // All our current definitions have the 1st and 3rd elements == DashUnit*2 
01236             if (
01237                     ElementData[1] != DashUnit*2 ||
01238                     ElementData[3] != DashUnit*2
01239                )
01240                 return;
01241             
01242             switch (ElementData[2])
01243             {
01244                 case DashUnit*2:
01245                     switch (ElementData[0])
01246                     {
01247                         case DashUnit*4:
01248                             DashID = SD_DASH11;
01249                             break;
01250                         case DashUnit*8:
01251                             DashID = SD_DASH12;
01252                             break;
01253                         case DashUnit*16:
01254                             DashID = SD_DASH13;
01255                             break;
01256                     }
01257                     break;
01258                 case DashUnit*4:
01259                     switch (ElementData[0])
01260                     {
01261                         case DashUnit*8:
01262                             DashID = SD_DASH14;
01263                             break;
01264                         case DashUnit*16:
01265                             DashID = SD_DASH15;
01266                             break;
01267                     }
01268                     break;
01269             }
01270 
01271             break;
01272         }
01273 
01274         case 6: 
01275         {
01276             if (
01277                     ElementData[0] == DashUnit*8 &&
01278                     ElementData[1] == DashUnit*2 &&
01279                     ElementData[2] == DashUnit*2 &&
01280                     ElementData[3] == DashUnit*2 &&
01281                     ElementData[4] == DashUnit*2 &&
01282                     ElementData[5] == DashUnit*2
01283                 )
01284                     DashID = SD_DASH16;
01285             else if (
01286                         ElementData[0] == DashUnit*16 &&
01287                         ElementData[1] == DashUnit*2 &&
01288                         ElementData[2] == DashUnit*2 &&
01289                         ElementData[3] == DashUnit*2 &&
01290                         ElementData[4] == DashUnit*2 &&
01291                         ElementData[5] == DashUnit*2
01292                     )
01293                         DashID = SD_DASH17;
01294             break;
01295         }
01296 
01297         case 8:
01298         {
01299             if (
01300                 ElementData[0] == DashUnit*8 &&
01301                 ElementData[1] == DashUnit*2 &&
01302                 ElementData[2] == DashUnit*2 &&
01303                 ElementData[3] == DashUnit*2 &&
01304                 ElementData[4] == DashUnit*2 &&
01305                 ElementData[5] == DashUnit*2 &&
01306                 ElementData[6] == DashUnit*2 &&
01307                 ElementData[7] == DashUnit*2
01308                )
01309                 DashID == SD_DASH18;
01310             else if (
01311                         ElementData[0] == DashUnit*16 &&
01312                         ElementData[1] == DashUnit*2 &&
01313                         ElementData[2] == DashUnit*2 &&
01314                         ElementData[3] == DashUnit*2 &&
01315                         ElementData[4] == DashUnit*2 &&
01316                         ElementData[5] == DashUnit*2 &&
01317                         ElementData[6] == DashUnit*2 &&
01318                         ElementData[7] == DashUnit*2
01319                     )
01320                         DashID == SD_DASH19;
01321             else if (
01322                         ElementData[0] == DashUnit*8 &&
01323                         ElementData[1] == DashUnit*2 &&
01324                         ElementData[2] == DashUnit*2 &&
01325                         ElementData[3] == DashUnit*2 &&
01326                         ElementData[4] == DashUnit*4 &&
01327                         ElementData[5] == DashUnit*2 &&
01328                         ElementData[6] == DashUnit*2 &&
01329                         ElementData[7] == DashUnit*2
01330                     )
01331                         DashID == SD_DASH20;
01332             break;
01333         }
01334     }
01335 } */
01336 
01337 /********************************************************************************************
01338 
01339 >   BOOL DashPatternAttribute::SetDeviceDashPattern(DashRec& NewDash, INT32 PixelSize)
01340 
01341     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01342     Created:    14/10/94
01343     Purpose:    Sets the dash pattern for this attribute.
01344     Errors:     No memory.
01345     SeeAlso:    -
01346 
01347 ********************************************************************************************/
01348 
01349 BOOL DashPatternAttribute::SetDeviceDashPattern(DashRec& NewDash, INT32 PixelSize)
01350 {
01351     SetDashPattern(NewDash);
01352 
01353     if (DashPattern.Elements == 0)
01354         return TRUE;
01355 
01356     DashPattern.DashStart *= PixelSize;
01357 
01358     for (INT32 element = 0; element < DashPattern.Elements; element++)
01359     {
01360         DashPattern.ElementData[element] *= PixelSize;
01361     }
01362 
01363     return TRUE;
01364 }
01365 
01366 /********************************************************************************************
01367 
01368 >   BOOL DashPatternAttribute::SetDeviceStockDashPattern(StockDash NewDash, INT32 PixelSize)
01369 
01370     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01371     Created:    14/10/94
01372     Purpose:    Sets the dash pattern for this attribute.
01373     Errors:     No memory.
01374     SeeAlso:    -
01375 
01376 ********************************************************************************************/
01377 
01378 BOOL DashPatternAttribute::SetDeviceStockDashPattern(StockDash NewDash, INT32 PixelSize)
01379 {
01380     SetStockDashPattern(NewDash);
01381 
01382     if (DashPattern.Elements == 0)
01383         return TRUE;
01384 
01385     const INT32 DashUnit = DashPattern.LineWidth;
01386 
01387     DashPattern.DashStart = (DashPattern.DashStart/DashUnit) * (PixelSize);
01388 
01389     for (INT32 element = 0; element < DashPattern.Elements; element++)
01390     {
01391         DashPattern.ElementData[element] = (DashPattern.ElementData[element]/DashUnit) * (PixelSize);
01392     }
01393 
01394     return TRUE;
01395 }
01396 
01397 /********************************************************************************************
01398 
01399 >   INT32 DashRec::operator==(DashRec& Other)
01400 
01401     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01402     Created:    14/10/94
01403     Purpose:    Equality operator, checks that the two dash patterns are the same.
01404     Errors:     -
01405     SeeAlso:    -
01406 
01407 ********************************************************************************************/
01408 
01409 INT32 DashRec::operator==(DashRec& Other)
01410 {
01411     if (Elements == 0 && Other.Elements == 0)
01412         return TRUE;
01413 
01414     if (Elements != Other.Elements ||
01415         DashStart != Other.DashStart)
01416         return FALSE;
01417 
01418     if (LineWidth != Other.LineWidth)
01419         return FALSE;
01420 
01421     // They both have the same number of elements and the same dash start
01422     // But are all the elements the same ?
01423     for (INT32 element = 0; element < Elements; element++)
01424     {
01425         if (ElementData[element] != Other.ElementData[element])
01426             return FALSE;
01427     }
01428 
01429     return TRUE;
01430 }
01431 
01432 /********************************************************************************************
01433 
01434 >   DashRec& DashRec::operator=(DashRec& Other)
01435 
01436     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01437     Created:    14/10/94
01438     Purpose:    Equals operator, makes one dash pattern the same as another.
01439     Errors:     -
01440     SeeAlso:    -
01441 
01442 ********************************************************************************************/
01443 
01444 DashRec& DashRec::operator=(DashRec& Other)
01445 {
01446     DashID = Other.DashID;
01447     Elements = Other.Elements;
01448 
01449     if (Elements == 0)
01450         return *this;
01451 
01452     DashStart = Other.DashStart;
01453     LineWidth = Other.LineWidth;
01454     ScaleWithLineWidth = Other.ScaleWithLineWidth;
01455 
01456     if (ElementData != NULL)
01457         delete ElementData;
01458 
01459     ElementData = new INT32[Elements];
01460 
01461     if (ElementData == NULL)
01462         return *this;
01463 
01464     for (INT32 element = 0; element < Elements; element++)
01465     {
01466         ElementData[element] = Other.ElementData[element];
01467     }
01468 
01469     return *this;
01470 }
01471 
01472 /********************************************************************************************
01473 
01474 >   INT32 DashRec::operator==(StockDash Other)
01475 
01476     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01477     Created:    14/10/94
01478     Purpose:    Equality operator, checks that the two dash patterns are the same.
01479     Errors:     -
01480     SeeAlso:    -
01481 
01482 ********************************************************************************************/
01483 
01484 INT32 DashRec::operator==(StockDash Other)
01485 {
01486     return DashID == Other;
01487 }
01488 
01489 /********************************************************************************************
01490 
01491 >   DashRec& DashRec::operator=(StockDash Other)
01492 
01493     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01494     Created:    14/10/94
01495     Purpose:    Equals operator, makes one dash pattern the same as another.
01496     Errors:     -
01497     SeeAlso:    -
01498 
01499 ********************************************************************************************/
01500 
01501 DashRec& DashRec::operator=(StockDash Other)
01502 {
01503     return *this;
01504 }
01505 
01506 /********************************************************************************************
01507 >   virtual NodeAttribute* DashPatternAttribute::MakeNode()
01508 
01509     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01510     Created:    1/7/94
01511     Inputs:     -
01512     Outputs:    -
01513     Returns:    A pointer to a NodeAttribute.
01514     Purpose:    Makes the appropriate NodeAttribute-derivative from an dash-pattern
01515                 attribute.
01516     Errors:     -
01517     SeeAlso:    AttributeValue::MakeNode
01518 ********************************************************************************************/
01519 
01520 NodeAttribute* DashPatternAttribute::MakeNode()
01521 {
01522     AttrDashPattern* pAttr = new AttrDashPattern;
01523     pAttr->Value.SimpleCopy(this);
01524     return pAttr;
01525 }
01526 
01527 /********************************************************************************************
01528 
01529 >   BOOL DashPatternAttribute::Init()
01530 
01531     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01532     Created:    14/10/94
01533     Returns:    TRUE - initialised ok; FALSE if not.
01534     Purpose:    Registers line width attribute, and provides a default attribute to give
01535                 non-dotted lines.
01536     Errors:     Out of memory.
01537     SeeAlso:    AttributeManager
01538 
01539 ********************************************************************************************/
01540 
01541 BOOL DashPatternAttribute::Init()
01542 {
01543     // Default to non-dotted lines
01544     DashPatternAttribute *pAttr = new DashPatternAttribute;
01545     if (pAttr == NULL)
01546         return FALSE;
01547 
01548     UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), 
01549                                                          pAttr);
01550     if (ID == ATTR_BAD_ID)
01551         return FALSE;
01552     ENSURE(ID == ATTR_DASHPATTERN, "Incorrect ID for dash pattern attribute!");
01553     return TRUE;
01554 }
01555 
01556 void DashPatternAttribute::SimpleCopy(AttributeValue *pValue)
01557 {
01558     DashPattern = ((DashPatternAttribute *) pValue)->DashPattern;
01559 }
01560 
01561 BOOL DashPatternAttribute::IsDifferent(AttributeValue *pAttr)
01562 {
01563     ENSURE(GetRuntimeClass() == pAttr->GetRuntimeClass(), 
01564            "Different attribute types in AttributeValue::IsDifferent()");
01565     return !(((DashPatternAttribute *) pAttr)->DashPattern == DashPattern);
01566 }
01567 
01568 
01569 void EndArrowAttribute::Render(RenderRegion *pRegion, BOOL Temp)
01570 {
01571     pRegion->SetEndArrow(this, Temp);
01572 }
01573 
01574 void EndArrowAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
01575 {
01576     pRegion->RestoreEndArrow(this, Temp);
01577 }
01578 
01579 void EndArrowAttribute::SimpleCopy(AttributeValue *pValue)
01580 {
01581     EndArrow = ((EndArrowAttribute *) pValue)->EndArrow;
01582     EndArrow.m_bExtendPath = ((EndArrowAttribute *) pValue)->EndArrow.m_bExtendPath;
01583 }
01584 
01585 BOOL EndArrowAttribute::IsDifferent(AttributeValue *pAttr)
01586 {
01587     ENSURE(GetRuntimeClass() == pAttr->GetRuntimeClass(), 
01588            "Different attribute types in AttributeValue::IsDifferent()");
01589     return !(((EndArrowAttribute *) pAttr)->EndArrow == EndArrow);
01590 }
01591 
01592 /********************************************************************************************
01593 >   virtual NodeAttribute* EndArrowAttribute::MakeNode()
01594 
01595     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01596     Created:    1/7/94
01597     Inputs:     -
01598     Outputs:    -
01599     Returns:    A pointer to a NodeAttribute.
01600     Purpose:    Makes the appropriate NodeAttribute-derivative from an end-arrow
01601                 attribute.
01602     Errors:     -
01603     SeeAlso:    AttributeValue::MakeNode
01604 ********************************************************************************************/
01605 
01606 NodeAttribute* EndArrowAttribute::MakeNode()
01607 {
01608     AttrEndArrow* pAttr = new AttrEndArrow;
01609     pAttr->Value.SimpleCopy(this);
01610     return pAttr;
01611 }
01612 
01613 /********************************************************************************************
01614 
01615 >   BOOL EndArrowAttribute::Init()
01616 
01617     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
01618     Created:    14/10/94
01619     Returns:    TRUE - initialised ok; FALSE if not.
01620     Purpose:    Registers line width attribute, and provides a default attribute to give
01621                 non-dotted lines.
01622     Errors:     Out of memory.
01623     SeeAlso:    AttributeManager
01624 
01625 ********************************************************************************************/
01626 
01627 BOOL EndArrowAttribute::Init()
01628 {
01629     // Default to non-dotted lines
01630     EndArrowAttribute *pAttr = new EndArrowAttribute;
01631     if (pAttr == NULL)
01632         return FALSE;
01633 
01634 /*
01635     SA_STRAIGHTARROW,
01636     SA_ANGLEDARROW,
01637     SA_ROUNDEDARROW,
01638     SA_SPOT,
01639     SA_DIAMOND,
01640     SA_ARROWFEATHER,
01641     SA_ARROWFEATHER2,
01642     SA_HOLLOWDIAMOND,
01643 */
01644 
01645 //  pAttr->EndArrow.CreateStockArrow(SA_ANGLEDARROW);
01646 
01647     UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), 
01648                                                          pAttr);
01649     if (ID == ATTR_BAD_ID)
01650         return FALSE;
01651     ENSURE(ID == ATTR_ENDARROW, "Incorrect ID for End Arrow attribute!");
01652     return TRUE;
01653 }
01654 
01655 
01656 
01657 /********************************************************************************************
01658 
01659 >   void DrawingModeAttribute::Render(RenderRegion *pRegion)
01660 
01661     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
01662     Created:    03/02/94
01663     Inputs:     pRegion - the render region to render this attribute into.
01664     Purpose:    Sets the drawing mode attribute for the given render region. i.e. all
01665                 objects drawn will now be drawn using this drawing mode.
01666     SeeAlso:    DrawingModeAttribute; RenderStack; AttributeValue; NodeAttribute;
01667                 DrawingModeAttribute::Restore; DrawingModeAttribute::SimpleCopy;
01668                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
01669 
01670 ********************************************************************************************/
01671 
01672 void DrawingModeAttribute::Render(RenderRegion *pRegion, BOOL Temp)
01673 {
01674     pRegion->SetDrawingMode(this, Temp);
01675 }
01676 
01677 /********************************************************************************************
01678 
01679 >   void DrawingModeAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
01680 
01681     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
01682     Created:    03/02/94
01683     Inputs:     pRegion - the render region to restore the attribute into.
01684                 Temp    - TRUE if this is a temporary attribute, FALSE if it is
01685                           permanent (e.g. it's in a document tree).
01686     Purpose:    Restores the drawing mode attribute for the given render region. i.e. all
01687                 objects drawn will now be drawn using this drawing mode.
01688     SeeAlso:    DrawingModeAttribute; RenderStack; AttributeValue; NodeAttribute;
01689                 DrawingModeAttribute::Render; DrawingModeAttribute::SimpleCopy;
01690                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
01691 
01692 ********************************************************************************************/
01693 
01694 void DrawingModeAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
01695 {
01696     pRegion->RestoreDrawingMode(this, Temp);
01697 }
01698 
01699 /********************************************************************************************
01700 
01701 >   void DrawingModeAttribute::SimpleCopy(AttributeValue *pValue)
01702 
01703     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
01704     Created:    03/02/94
01705     Inputs:     pAttr - pointer to the AttributeValue to copy.
01706     Purpose:    See AttributeValue::SimpleCopy
01707     SeeAlso:    DrawingModeAttribute; RenderStack; AttributeValue; NodeAttribute;
01708                 DrawingModeAttribute::Render; DrawingModeAttribute::Restore;
01709                 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy
01710 
01711 ********************************************************************************************/
01712 
01713 void DrawingModeAttribute::SimpleCopy(AttributeValue *pValue)
01714 {
01715     DrawingMode = ((DrawingModeAttribute *) pValue)->DrawingMode;
01716 }
01717 
01718 BOOL DrawingModeAttribute::IsDifferent(AttributeValue *pAttr)
01719 {
01720     ENSURE(GetRuntimeClass() == pAttr->GetRuntimeClass(), 
01721            "Different attribute types in AttributeValue::IsDifferent()");
01722     return TRUE;
01723 }
01724 
01725 NodeAttribute* DrawingModeAttribute::MakeNode()
01726 {
01727     return NULL;
01728 }
01729 
01730 UINT32 DrawingModeAttribute::ID = ATTR_BAD_ID;
01731 
01732 
01733 MitreLimitAttribute::MitreLimitAttribute()
01734 {
01735     MitreLimit = 4000;
01736 }
01737 
01738 void MitreLimitAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
01739 {
01740     pRegion->RestoreMitreLimit(this, Temp);
01741 }
01742 
01743 void MitreLimitAttribute::Render(RenderRegion *pRegion, BOOL Temp)
01744 {
01745     pRegion->SetMitreLimit(this, Temp);
01746 }
01747 
01748 void MitreLimitAttribute::SimpleCopy(AttributeValue *pValue)
01749 {
01750     MitreLimit = ((MitreLimitAttribute *) pValue)->MitreLimit;
01751 }
01752 
01753 BOOL MitreLimitAttribute::IsDifferent(AttributeValue *pAttr)
01754 {
01755     ENSURE(GetRuntimeClass() == pAttr->GetRuntimeClass(), 
01756            "Different attribute types in AttributeValue::IsDifferent()");
01757     return ((MitreLimitAttribute *) pAttr)->MitreLimit != MitreLimit;
01758 }
01759 
01760 /********************************************************************************************
01761 
01762 >   virtual NodeAttribute* MireLimitAttribute::MakeNode()
01763 
01764     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
01765     Created:    1/7/94
01766     Inputs:     -
01767     Outputs:    -
01768     Returns:    A pointer to a NodeAttribute.
01769     Purpose:    Makes the appropriate NodeAttribute-derivative from a mitre-limit
01770                 attribute.
01771     Errors:     -
01772     SeeAlso:    AttributeValue::MakeNode
01773 ********************************************************************************************/
01774 
01775 NodeAttribute* MitreLimitAttribute::MakeNode()
01776 {
01777     AttrMitreLimit* pAttr = new AttrMitreLimit;
01778     pAttr->Value.SimpleCopy(this);
01779     return pAttr;
01780 }
01781 
01782 BOOL MitreLimitAttribute::Init()
01783 {
01784     MitreLimitAttribute *pAttr = new MitreLimitAttribute;
01785     if (pAttr == NULL)
01786         return FALSE;
01787 
01788     pAttr->MitreLimit = 4000;
01789 
01790     UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), 
01791                                                          pAttr);
01792     if (ID == ATTR_BAD_ID)
01793         return FALSE;
01794     ENSURE(ID == ATTR_MITRELIMIT, "Incorrect ID for attribute!");
01795     return TRUE;
01796 }
01797 
01798 
01799 WindingRuleAttribute::WindingRuleAttribute()
01800 {
01801     // Default to even-odd winding
01802     WindingRule = EvenOddWinding;
01803 }
01804 
01805 void WindingRuleAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
01806 {
01807     pRegion->RestoreWindingRule(this, Temp);
01808 }
01809 
01810 void WindingRuleAttribute::Render(RenderRegion *pRegion, BOOL Temp)
01811 {
01812     pRegion->SetWindingRule(this, Temp);
01813 }
01814 
01815 void WindingRuleAttribute::SimpleCopy(AttributeValue *pValue)
01816 {
01817     WindingRule = ((WindingRuleAttribute *) pValue)->WindingRule;
01818 }
01819 
01820 NodeAttribute *WindingRuleAttribute::MakeNode()
01821 {
01822     // Create new attribute node
01823     AttrWindingRule *pAttr = new AttrWindingRule;
01824 
01825     // Copy attribute value into the new node.
01826     pAttr->Value.SimpleCopy(this);
01827 
01828     // Return the new node
01829     return pAttr;
01830 }
01831 
01832 /********************************************************************************************
01833 
01834 >   BOOL WindingRuleAttribute::IsDifferent(AttributeValue *pAttr)
01835 
01836     Author:     Tim_Browse (Xara Group Ltd) <camelotdev@xara.com>
01837     Created:    12/04/94
01838     Purpose:    See base class version.
01839     Errors:     The two attributes are not of the same type.
01840     SeeAlso:    AttributeValue::IsDifferent
01841 
01842 ********************************************************************************************/
01843 
01844 BOOL WindingRuleAttribute::IsDifferent(AttributeValue *pAttr)
01845 {
01846     ENSURE(GetRuntimeClass() == pAttr->GetRuntimeClass(), 
01847            "Different attribute types in AttributeValue::IsDifferent()");
01848     return ((WindingRuleAttribute *) pAttr)->WindingRule != WindingRule;
01849 }
01850 
01851 BOOL WindingRuleAttribute::Init()
01852 {
01853     WindingRuleAttribute *pAttr = new WindingRuleAttribute;
01854     if (pAttr == NULL)
01855         return FALSE;
01856 
01857     // Default to even-odd winding
01858     pAttr->WindingRule = EvenOddWinding;
01859     UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), 
01860                                                          pAttr);
01861     if (ID == ATTR_BAD_ID)
01862         return FALSE;
01863     ENSURE(ID == ATTR_WINDINGRULE, "Incorrect ID for attribute!");
01864     return TRUE;
01865 }
01866 
01867 
01868 StartCapAttribute::StartCapAttribute()
01869 {
01870     // Default to butt line caps (because ArtWorks does).
01871     StartCap = LineCapButt;
01872 }
01873 
01874 BOOL StartCapAttribute::IsDifferent(AttributeValue *pAttr)
01875 {
01876     ENSURE(GetRuntimeClass() == pAttr->GetRuntimeClass(), 
01877            "Different attribute types in AttributeValue::IsDifferent()");
01878     return ((StartCapAttribute *) pAttr)->StartCap != StartCap;
01879 }
01880 
01881 void StartCapAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
01882 {
01883     pRegion->RestoreStartCap(this, Temp);
01884 }
01885 
01886 void StartCapAttribute::Render(RenderRegion *pRegion, BOOL Temp)
01887 {
01888     pRegion->SetStartCap(this, Temp);
01889 }
01890 
01891 void StartCapAttribute::SimpleCopy(AttributeValue *pValue)
01892 {
01893     StartCap = ((StartCapAttribute *) pValue)->StartCap;
01894 }
01895 
01896 NodeAttribute *StartCapAttribute::MakeNode()
01897 {
01898     // Create new attribute node
01899     AttrStartCap *pAttr = new AttrStartCap;
01900 
01901     // Copy attribute value into the new node.
01902     pAttr->Value.SimpleCopy(this);
01903 
01904     // Return the new node
01905     return pAttr;
01906 }
01907 
01908 BOOL StartCapAttribute::Init()
01909 {
01910     StartCapAttribute *pAttr = new StartCapAttribute;
01911     if (pAttr == NULL)
01912         return FALSE;
01913 
01914     // Default to butt line caps (because ArtWorks does).
01915     pAttr->StartCap = LineCapButt;
01916 
01917     UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), 
01918                                                          pAttr);
01919     if (ID == ATTR_BAD_ID)
01920         return FALSE;
01921     ENSURE(ID == ATTR_STARTCAP, "Incorrect ID for attribute!");
01922     return TRUE;
01923 }
01924 
01925 
01926 
01927 JoinTypeAttribute::JoinTypeAttribute()
01928 {
01929     // Default to Bevelled line joins.
01930     JoinType = BevelledJoin;
01931 }
01932 
01933 BOOL JoinTypeAttribute::IsDifferent(AttributeValue *pAttr)
01934 {
01935     ENSURE(GetRuntimeClass() == pAttr->GetRuntimeClass(), 
01936            "Different attribute types in AttributeValue::IsDifferent()");
01937     return ((JoinTypeAttribute *) pAttr)->JoinType != JoinType;
01938 }
01939 
01940 void JoinTypeAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
01941 {
01942     pRegion->RestoreJoinType(this, Temp);
01943 }
01944 
01945 void JoinTypeAttribute::Render(RenderRegion *pRegion, BOOL Temp)
01946 {
01947     pRegion->SetJoinType(this, Temp);
01948 }
01949 
01950 void JoinTypeAttribute::SimpleCopy(AttributeValue *pValue)
01951 {
01952     JoinType = ((JoinTypeAttribute *) pValue)->JoinType;
01953 }
01954 
01955 NodeAttribute *JoinTypeAttribute::MakeNode()
01956 {
01957     // Create new attribute node
01958     AttrJoinType *pAttr = new AttrJoinType;
01959 
01960     // Copy attribute value into the new node.
01961     pAttr->Value.SimpleCopy(this);
01962 
01963     // Return the new node
01964     return pAttr;
01965 }
01966 
01967 BOOL JoinTypeAttribute::Init()
01968 {
01969     JoinTypeAttribute *pAttr = new JoinTypeAttribute;
01970     if (pAttr == NULL)
01971         return FALSE;
01972 
01973     // Default to Bevelled line joins.
01974     pAttr->JoinType =   BevelledJoin;
01975 
01976     UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), 
01977                                                          pAttr);
01978     if (ID == ATTR_BAD_ID)
01979         return FALSE;
01980     ENSURE(ID == ATTR_JOINTYPE, "Incorrect ID for attribute!");
01981     return TRUE;
01982 }
01983 
01984 
01985 
01986 
01987 void StartArrowAttribute::Render(RenderRegion *pRegion, BOOL Temp)
01988 {
01989     pRegion->SetStartArrow(this, Temp);
01990 }
01991 
01992 void StartArrowAttribute::Restore(RenderRegion *pRegion, BOOL Temp)
01993 {
01994     pRegion->RestoreStartArrow(this, Temp);
01995 }
01996 
01997 void StartArrowAttribute::SimpleCopy(AttributeValue *pValue)
01998 {
01999     StartArrow = ((StartArrowAttribute *) pValue)->StartArrow;
02000     StartArrow.m_bExtendPath = ((StartArrowAttribute *) pValue)->StartArrow.m_bExtendPath;
02001 }
02002 
02003 BOOL StartArrowAttribute::IsDifferent(AttributeValue *pAttr)
02004 {
02005     ENSURE(GetRuntimeClass() == pAttr->GetRuntimeClass(), 
02006            "Different attribute types in AttributeValue::IsDifferent()");
02007     return !(((StartArrowAttribute *) pAttr)->StartArrow == StartArrow);
02008 }
02009 
02010 /********************************************************************************************
02011 
02012 >   virtual NodeAttribute* StartArrowAttribute::MakeNode()
02013 
02014     Author:     Justin_Flude (Xara Group Ltd) <camelotdev@xara.com>
02015     Created:    1/7/94
02016     Inputs:     -
02017     Outputs:    -
02018     Returns:    A pointer to a NodeAttribute.
02019     Purpose:    Makes the appropriate NodeAttribute-derivative from a fill-type attribute.
02020     Errors:     -
02021     SeeAlso:    AttributeValue::MakeNode
02022 
02023 ********************************************************************************************/
02024 
02025 NodeAttribute* StartArrowAttribute::MakeNode()
02026 {
02027     AttrStartArrow* pAttr = new AttrStartArrow;
02028     pAttr->Value.SimpleCopy(this);
02029     return pAttr;
02030 }
02031 
02032 /********************************************************************************************
02033 
02034 >   BOOL StartArrowAttribute::Init()
02035 
02036     Author:     Will_Cowling (Xara Group Ltd) <camelotdev@xara.com>
02037     Created:    14/10/94
02038     Returns:    TRUE - initialised ok; FALSE if not.
02039     Purpose:    Registers line width attribute, and provides a default attribute to give
02040                 non-dotted lines.
02041     Errors:     Out of memory.
02042     SeeAlso:    AttributeManager
02043 
02044 ********************************************************************************************/
02045 
02046 BOOL StartArrowAttribute::Init()
02047 {
02048     // Default to non-dotted lines
02049     StartArrowAttribute *pAttr = new StartArrowAttribute;
02050     if (pAttr == NULL)
02051         return FALSE;
02052 
02053 /*
02054     SA_STRAIGHTARROW,
02055     SA_ANGLEDARROW,
02056     SA_ROUNDEDARROW,
02057     SA_SPOT,
02058     SA_DIAMOND,
02059     SA_ARROWFEATHER,
02060     SA_ARROWFEATHER2,
02061     SA_HOLLOWDIAMOND,
02062 */
02063 
02064 //  pAttr->StartArrow.CreateStockArrow(SA_ARROWFEATHER2);
02065 
02066     UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), 
02067                                                          pAttr);
02068     if (ID == ATTR_BAD_ID)
02069         return FALSE;
02070     ENSURE(ID == ATTR_STARTARROW, "Incorrect ID for End Arrow attribute!");
02071     return TRUE;
02072 }
02073 
02074 //--------------------------------------------------------------------------------------
02075 //--------------------------------------------------------------------------------------
02076 //--------------------------------------------------------------------------------------
02077 //--------------------------------------------------------------------------------------
02078 
02079 
02080 /********************************************************************************************
02081 >   BlendAttrParam::BlendAttrParam()
02082 
02083     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02084     Created:    26/10/94
02085     Inputs:     -
02086     Outputs:    -
02087     Returns:    -
02088     Purpose:    Default constructor.
02089     Errors:     -
02090     SeeAlso:    -
02091 
02092 ********************************************************************************************/
02093 
02094 BlendAttrParam::BlendAttrParam()
02095 {
02096     pRenderRegion   = NULL;
02097     pOtherNodeAttr  = NULL;
02098     pOtherAttrVal   = NULL;
02099     BlendRatio      = 0.0;
02100     pBlendedNodeAttr= NULL;
02101     pBlendedAttrVal = NULL;
02102     ColourBlend     = COLOURBLEND_FADE;
02103     objectRatio     = 0.0;
02104     objectProfileProcessing = FALSE;
02105 }
02106 
02107 /********************************************************************************************
02108 >   BlendAttrParam::~BlendAttrParam()
02109 
02110     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02111     Created:    26/10/94
02112     Inputs:     -
02113     Outputs:    -
02114     Returns:    -
02115     Purpose:    Destructor
02116                 This will delete pBlendedNodeAttr and pBlendedAttrVal if these values are not NULL
02117     Errors:     -
02118     SeeAlso:    -
02119 
02120 ********************************************************************************************/
02121 
02122 BlendAttrParam::~BlendAttrParam()
02123 {
02124     if (pBlendedNodeAttr != NULL) delete pBlendedNodeAttr;
02125     if (pBlendedAttrVal  != NULL) delete pBlendedAttrVal;
02126 }
02127 
02128 
02129 /********************************************************************************************
02130 >   BOOL BlendAttrParam::Init(RenderRegion *pThisRenderRegion,
02131                             NodeAttribute* pThisOtherAttr, double ThisBlendRatio,ColourBlendType ColBlend,
02132                             CCAttrMap* pStartAttrMap, CCAttrMap* pEndAttrMap)
02133 
02134     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02135     Created:    26/10/94
02136     Inputs:     pRenderRegion   = the render region we are rendering into (this is currently
02137                                     used for finding the rendering ColourContext for blending colour)
02138                                     This may be NULL, but if you're rendering you must pass it in,
02139                                     so we separate tints properly as often as possible.
02140                 pThisOtherAttr  = the node attr that you want to blend to
02141                 ThisBlendRatio  = the amount you want to blend by (0.0 < ThisBlendRatio < 1.0)
02142                 ColBlend        = the way in which colours should be blended
02143     Outputs:    -
02144     Returns:    TRUE if initialised correctly, FALSE otherwise
02145     Purpose:    This inits the object with the given params.
02146                 Fails if pThisOtherAttr is NULL or ThisBlendRatio is out of range.
02147                 If ok the following is true -
02148                     GetRenderRegion     will return pThisRenderRegion
02149                     GetOtherAttr()      will return pThisOtherAttr
02150                     GetBlendRatio()     will return ThisBlendRatio
02151                     GetOtherAttrVal()   will return pThisOtherAttr->GetAttributeValue() (can be NULL!!)
02152                     GetBlendedAttr()    will return NULL
02153                     GetBlendedAttrVal() will return NULL
02154     Errors:     -
02155     SeeAlso:    -
02156 
02157 ********************************************************************************************/
02158 
02159 BOOL BlendAttrParam::Init(RenderRegion *pThisRenderRegion,
02160                           NodeAttribute* pThisOtherAttr, double ThisBlendRatio,ColourBlendType ColBlend,
02161                           CCAttrMap* pStartAttrMap, CCAttrMap* pEndAttrMap, BOOL LastStep)
02162 {
02163     // Check that this is the first time it's been called
02164     ERROR3IF(pOtherNodeAttr != NULL,"This has already been initialised");
02165     if (pOtherNodeAttr != NULL) return FALSE;
02166 
02167     // check valid entry params
02168     ERROR3IF(pThisOtherAttr == NULL || (ThisBlendRatio <= 0.0) || (ThisBlendRatio >= 1.0),"Dodgy entry params");
02169     if (pThisOtherAttr == NULL || (ThisBlendRatio <= 0.0) || (ThisBlendRatio >= 1.0)) return FALSE;
02170 
02171     // Remember the render region
02172     pRenderRegion = pThisRenderRegion;
02173 
02174     // Store the other NodeAttribute's ptr
02175     pOtherNodeAttr = pThisOtherAttr;
02176 
02177     // Store the way colours should be blended
02178     ColourBlend = ColBlend;
02179 
02180     // Get pOtherNodeAttr's attr value ptr
02181     // NOTE!!   This can be NULL as not all NodeAttributes implement this function.
02182     //          This is OK as the ones that don't support GetAttributeValue() won't have a Blend() 
02183     //          function either, and if they do have a Blend() func, it will error when it's called
02184     pOtherAttrVal = pThisOtherAttr->GetAttributeValue();
02185 
02186     // Set up the other member vars
02187     BlendRatio      = ThisBlendRatio;
02188     pBlendedNodeAttr= NULL;
02189     pBlendedAttrVal = NULL;
02190 
02191     pAttrMapStart   = pStartAttrMap;    
02192     pAttrMapEnd     = pEndAttrMap;
02193 
02194     m_bLastStep = LastStep;
02195 
02196     return TRUE;
02197 }
02198 
02199 /********************************************************************************************
02200 >   BOOL BlendAttrParam::Init(RenderRegion *pThisRenderRegion, NodeAttribute* pThisOtherAttr,
02201                           double ThisBlendRatio, double thisObjectRatio, BOOL objProcess,
02202                           ColourBlendType ColBlend, CCAttrMap* pStartAttrMap,
02203                           CCAttrMap* pEndAttrMap, BOOL LastStep)
02204 
02205     Author:     Chris_Snook (Xara Group Ltd) <camelotdev@xara.com>
02206     Created:    27/7/2000
02207     Inputs:     pRenderRegion   = the render region we are rendering into (this is currently
02208                                     used for finding the rendering ColourContext for blending colour)
02209                                     This may be NULL, but if you're rendering you must pass it in,
02210                                     so we separate tints properly as often as possible.
02211                 pThisOtherAttr  = the node attr that you want to blend to
02212                 ThisBlendRatio  = the amount you want to blend by (0.0 < ThisBlendRatio < 1.0)
02213                 thisObjectRatio = the amount you to to blend object (i.e.  position data) by
02214                 objProcess      = whether we are blending with respect to position within attributes
02215                 ColBlend        = the way in which colours should be blended
02216     Outputs:    -
02217     Returns:    TRUE if initialised correctly, FALSE otherwise
02218     Purpose:    This inits the object with the given params.
02219     Errors:     -
02220     SeeAlso:    -
02221 
02222 ********************************************************************************************/
02223 
02224 BOOL BlendAttrParam::Init(RenderRegion *pThisRenderRegion, NodeAttribute* pThisOtherAttr,
02225                           double ThisBlendRatio, double thisObjectRatio, BOOL objProcess,
02226                           ColourBlendType ColBlend, CCAttrMap* pStartAttrMap,
02227                           CCAttrMap* pEndAttrMap, BOOL LastStep)
02228 {
02229     // Check that this is the first time it's been called
02230     ERROR3IF(pOtherNodeAttr != NULL,"This has already been initialised");
02231     if (pOtherNodeAttr != NULL) return FALSE;
02232 
02233     // check valid entry params
02234     ERROR3IF(pThisOtherAttr == NULL || (ThisBlendRatio <= 0.0) || (ThisBlendRatio >= 1.0),"Dodgy entry params");
02235     if (pThisOtherAttr == NULL || (ThisBlendRatio <= 0.0) || (ThisBlendRatio >= 1.0)) return FALSE;
02236 
02237     // Remember the render region
02238     pRenderRegion = pThisRenderRegion;
02239 
02240     // Store the other NodeAttribute's ptr
02241     pOtherNodeAttr = pThisOtherAttr;
02242 
02243     // Store the way colours should be blended
02244     ColourBlend = ColBlend;
02245 
02246     // Get pOtherNodeAttr's attr value ptr
02247     // NOTE!!   This can be NULL as not all NodeAttributes implement this function.
02248     //          This is OK as the ones that don't support GetAttributeValue() won't have a Blend() 
02249     //          function either, and if they do have a Blend() func, it will error when it's called
02250     pOtherAttrVal = pThisOtherAttr->GetAttributeValue();
02251 
02252     // Set up the other member vars
02253     BlendRatio      = ThisBlendRatio;
02254     pBlendedNodeAttr= NULL;
02255     pBlendedAttrVal = NULL;
02256 
02257     pAttrMapStart   = pStartAttrMap;    
02258     pAttrMapEnd     = pEndAttrMap;
02259 
02260     m_bLastStep = LastStep;
02261 
02262     objectRatio = thisObjectRatio;
02263     
02264     objectProfileProcessing = objProcess;
02265 
02266     return TRUE;
02267 }
02268 
02269 /********************************************************************************************
02270 >   NodeAttribute* BlendAttrParam::GetBlendedAttr()
02271 
02272     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02273     Created:    26/10/94
02274     Inputs:     -
02275     Outputs:    -
02276     Returns:    Ptr to NodeAttribute, or NULL if it doesn't have one
02277     Purpose:    When you call this, the pointer passed back becomes your responsibility (if its not NULL).
02278                 This means that you will have to delete it if you don't want to cause memory leaks.
02279                 Also, you will get NULL for all subsequent calls, until a new value is set by SetBlendedAttr()
02280                 
02281                 I.e. GetBlendedAttr() returns it's internal node attr ptr, then sets it to NULL
02282 
02283     Errors:     In debug builds, it'll error if it returns NULL
02284     SeeAlso:    -
02285 
02286 ********************************************************************************************/
02287 
02288 NodeAttribute* BlendAttrParam::GetBlendedAttr()
02289 {
02290     ERROR3IF(pBlendedNodeAttr == NULL,"pBlendedNodeAttr is NULL");
02291 
02292     NodeAttribute* p = pBlendedNodeAttr;
02293     pBlendedNodeAttr = NULL;
02294     return (p);
02295 }
02296 
02297 /********************************************************************************************
02298 >   AttributeValue* BlendAttrParam::GetBlendedAttrVal()
02299 
02300     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02301     Created:    26/10/94
02302     Inputs:     -
02303     Outputs:    -
02304     Returns:    Ptr to AttributeValue, or NULL if it doesn't have one
02305     Purpose:    When you call this, the pointer passed back becomes your responsibility (if its not NULL).
02306                 This means that you will have to delete it if you don't want to cause memory leaks.
02307                 Also, you will get NULL for all subsequent calls, until a new value is set by SetBlendedAttrVal()
02308                 
02309                 I.e. GetBlendedAttrVal() returns it's internal attr value ptr, then sets it to NULL
02310 
02311     Errors:     In debug builds, it'll error if it returns NULL
02312     SeeAlso:    -
02313 
02314 ********************************************************************************************/
02315 
02316 AttributeValue* BlendAttrParam::GetBlendedAttrVal()
02317 {
02318     ERROR3IF(pBlendedAttrVal == NULL,"pBlendedAttrVal is NULL");
02319 
02320     AttributeValue* p = pBlendedAttrVal;
02321     pBlendedAttrVal = NULL;
02322     return (p);
02323 }
02324 
02325 /********************************************************************************************
02326 >   void BlendAttrParam::SetBlendedAttr(NodeAttribute* pAttr)
02327 
02328     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02329     Created:    26/10/94
02330     Inputs:     pAttr = ptr to a node attr
02331     Outputs:    -
02332     Returns:    -
02333     Purpose:    When you call this func, the object you pass it becomes the property of the BlendAttrParam object.
02334                 If it's internal pointer is the same as the entry param, nothing happends
02335                 If it's internal pointer is not NULL and different to the entry param, the old one is deleted first.
02336     Errors:     -
02337     SeeAlso:    -
02338 
02339 ********************************************************************************************/
02340 
02341 void BlendAttrParam::SetBlendedAttr(NodeAttribute* pAttr)
02342 {
02343     if (pBlendedNodeAttr != pAttr)
02344     {
02345         if (pBlendedNodeAttr != NULL) delete pBlendedNodeAttr;
02346         pBlendedNodeAttr = pAttr;
02347     }
02348 }
02349 
02350 /********************************************************************************************
02351 >   void BlendAttrParam::SetBlendedAttrVal(AttributeValue* pAttrVal)
02352 
02353     Author:     Mark_Neves (Xara Group Ltd) <camelotdev@xara.com>
02354     Created:    26/10/94
02355     Inputs:     pAttrVal = ptr to a attr value
02356     Outputs:    -
02357     Returns:    -
02358     Purpose:    When you call this func, the object you pass it becomes the property of the BlendAttrParam object.
02359                 If it's internal pointer is the same as the entry param, nothing happends
02360                 If it's internal pointer is not NULL and different to the entry param, the old one is deleted first.
02361     Errors:     -
02362     SeeAlso:    -
02363 
02364 ********************************************************************************************/
02365 
02366 void BlendAttrParam::SetBlendedAttrVal(AttributeValue* pAttrVal)
02367 {
02368     if (pBlendedAttrVal != pAttrVal)
02369     {
02370         if (pBlendedAttrVal != NULL) delete pBlendedAttrVal;
02371         pBlendedAttrVal = pAttrVal;
02372     }
02373 }
02374 

Generated on Sat Nov 10 03:44:12 2007 for Camelot by  doxygen 1.4.4