strkattr.cpp

Go to the documentation of this file.
00001 // $Id: strkattr.cpp 1688 2006-08-10 12:05:20Z gerry $
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 // strkattr.cpp - Path stroking attributes
00099 
00100 #include "camtypes.h"
00101 
00102 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00103 //#include "jason.h"
00104 #include "ppairbsh.h"       // PathProcessorStrokeAirbrush
00105 #include "ppstroke.h"       // PathProcessorStroke
00106 #include "ppvecstr.h"       // PathProcessorStrokeVector
00107 //#include "rndrgn.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00108 #include "strkattr.h"
00109 #include "strkcomp.h"
00110 #include "valfunc.h"
00111 
00112 // Native file load/save includes
00113 //#include "camfiltr.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00114 //#include "cxfdefs.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00115 //#include "cxfrec.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00116 #include "cxftags.h"
00117 //#include "tim.h"          // For _R(IDE_FILE_WRITE_ERROR)
00118 
00119 //#include "becomea.h" - in camtypes.h [AUTOMATICALLY REMOVED]
00120 #include "nodepath.h"
00121 #include "pbecomea.h" // for pathbecomea
00122 // Stroke classes
00123 CC_IMPLEMENT_DYNCREATE(AttrStrokeType, NodeAttribute)
00124 CC_IMPLEMENT_DYNAMIC(StrokeTypeAttrValue, AttributeValue)
00125 
00126 // Variable width classes
00127 CC_IMPLEMENT_DYNCREATE(AttrVariableWidth, NodeAttribute)
00128 CC_IMPLEMENT_DYNAMIC(VariableWidthAttrValue, AttributeValue)
00129 
00130 // Version 2 file format loading handler for all Stroke attributes
00131 CC_IMPLEMENT_DYNAMIC(StrokeAttrRecordHandler, CamelotRecordHandler);
00132 
00133 
00134 // Declare smart memory handling in Debug builds
00135 #define new CAM_DEBUG_NEW
00136 
00137 
00138 
00139 /********************************************************************************************
00140 
00141 >   AttrStrokeType::AttrStrokeType()
00142 
00143     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00144     Created:    7/1/97
00145 
00146     Purpose:    Default constructor for AttrStrokeType
00147 
00148 ********************************************************************************************/
00149 
00150 AttrStrokeType::AttrStrokeType()
00151 {
00152 }
00153 
00154 
00155 
00156 /********************************************************************************************
00157 
00158 >   AttrStrokeType::AttrStrokeType(Node *ContextNode,
00159                                         AttachNodeDirection Direction,
00160                                         BOOL Locked,
00161                                         BOOL Mangled,
00162                                         BOOL Marked,
00163                                         BOOL Selected)
00164     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00165     Created:    7/1/97
00166 
00167     Purpose:    Constructs an AttrStrokeType Attribute
00168 
00169 ********************************************************************************************/
00170 
00171 AttrStrokeType::AttrStrokeType(Node *ContextNode,
00172                                     AttachNodeDirection Direction,
00173                                     BOOL Locked,
00174                                     BOOL Mangled,
00175                                     BOOL Marked,
00176                                     BOOL Selected)
00177                 : NodeAttribute(ContextNode, Direction, Locked, Mangled, Marked, Selected)
00178 {
00179 }
00180 
00181 
00182 
00183 /********************************************************************************************
00184 
00185 >   virtual void AttrStrokeType::Render(RenderRegion *pRender)
00186 
00187     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00188     Created:    7/1/97
00189 
00190     Purpose:    Renders this attribute (by simply calling the Render function of
00191                 its contained AttributeValue)
00192 
00193 ********************************************************************************************/
00194 
00195 void AttrStrokeType::Render(RenderRegion *pRender)
00196 {
00197     GetAttributeValue()->Render(pRender);
00198 }
00199 
00200 
00201 
00202 /***********************************************************************************************
00203 
00204 >   virtual void AttrStrokeType::CopyNodeContents(AttrStrokeType *NodeCopy)
00205 
00206     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00207     Created:    8/1/97
00208 
00209     Outputs:    NodeCopy - returned containing a copy of this node
00210          
00211     Purpose:    Copies the node's contents to the node pointed to by NodeCopy
00212 
00213 ***********************************************************************************************/
00214 
00215 void AttrStrokeType::CopyNodeContents(AttrStrokeType *NodeCopy)
00216 {
00217     // Let the base class do its bit
00218     NodeAttribute::CopyNodeContents(NodeCopy);
00219 
00220     // And then copy our Value
00221     *(NodeCopy->GetAttributeValue()) = *(GetAttributeValue());
00222 }
00223 
00224 
00225 
00226 /***********************************************************************************************
00227 >   void AttrStrokeType::PolyCopyNodeContents(NodeRenderable* pNodeCopy)
00228 
00229     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
00230     Created:    18/12/2003
00231     Outputs:    -
00232     Purpose:    Polymorphically copies the contents of this node to another
00233     Errors:     An assertion failure will occur if NodeCopy is NULL
00234     Scope:      protected
00235                                      
00236 ***********************************************************************************************/
00237 
00238 void AttrStrokeType::PolyCopyNodeContents(NodeRenderable* pNodeCopy)
00239 {
00240     ENSURE(pNodeCopy, "Trying to copy a node's contents into a NULL node");
00241     ENSURE(IS_A(pNodeCopy, AttrStrokeType), "PolyCopyNodeContents given wrong dest node type");
00242 
00243     if (IS_A(pNodeCopy, AttrStrokeType))
00244         CopyNodeContents((AttrStrokeType*)pNodeCopy);
00245 }
00246 
00247 
00248 
00249 /***********************************************************************************************
00250 
00251 >   virtual INT32 AttrStrokeType::operator==(const NodeAttribute &NodeAttrib); 
00252 
00253     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00254     Created:    8/1/97
00255 
00256     Inputs:     NodeAttrib - The node to compare this node to
00257     Returns:    TRUE if the nodes are considered equal
00258 
00259     Purpose:    Comparison operator - determines if the AttributeValues of both objects are ==
00260 
00261 ***********************************************************************************************/
00262 
00263 INT32 AttrStrokeType::operator==(const NodeAttribute &NodeAttrib)
00264 {
00265     // First check they are of the same type
00266     if (((NodeAttribute*)&NodeAttrib)->GetAttributeType() != GetAttributeType())
00267         return FALSE;
00268 
00269     // Make a more sensible pointer
00270     AttrStrokeType *Attr = (AttrStrokeType *) &NodeAttrib;
00271 
00272     // Now let the AttributeValues compare themselves
00273     return( *((StrokeTypeAttrValue *) Attr->GetAttributeValue())  ==
00274             *((StrokeTypeAttrValue *) GetAttributeValue()) );
00275 }
00276 
00277 
00278 
00279 /********************************************************************************************
00280 
00281 >   virtual Node *AttrStrokeType::SimpleCopy()
00282 
00283     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00284     Created:    8/1/97
00285 
00286     Returns:    A copy of the node, or NULL if memory runs out 
00287 
00288     Purpose:    This method returns a shallow copy of the node with all Node pointers NULL. 
00289                 The function is virtual, and must be defined for all derived classes.  
00290 
00291 ********************************************************************************************/
00292 
00293 Node *AttrStrokeType::SimpleCopy()
00294 {
00295     AttrStrokeType* NodeCopy = new AttrStrokeType;
00296     if (NodeCopy == NULL)
00297         return(NULL);
00298 
00299     // Call the base class
00300     NodeAttribute::CopyNodeContents(NodeCopy);
00301 
00302     // And call our AttributeValue to copy itself too
00303     NodeCopy->GetAttributeValue()->SimpleCopy(GetAttributeValue());
00304     
00305     return(NodeCopy);
00306 }
00307 
00308 
00309 
00310 /********************************************************************************************
00311 
00312 >   virtual UINT32 AttrStrokeType::GetAttrNameID(void)
00313 
00314     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00315     Created:    8/1/97
00316 
00317     Returns:    Attribute description string-resource ID
00318 
00319     Purpose:    Retrieves a string resource ID describing this attribute
00320 
00321 ********************************************************************************************/
00322 
00323 UINT32 AttrStrokeType::GetAttrNameID(void)
00324 {
00325     return(_R(IDS_ATTRSTROKETYPE));
00326 }
00327 
00328 /********************************************************************************************
00329 >   virtual BOOL AttrStokeType::NeedsTransparency() const
00330 
00331     Author:     Richard_Millican (Xara Group Ltd) <camelotdev@xara.com>
00332     Created:    7/2/97
00333     Inputs:     -
00334     Outputs:    -
00335     Returns:    TRUE if this Attribute requires transparency mode to render properly.
00336     Purpose:    Strokes like the airbrush require transparency to be turned on to work.
00337     Errors:     -
00338 ********************************************************************************************/
00339 
00340 BOOL AttrStrokeType::NeedsTransparency() const
00341 {
00342     BOOL SoWeDoReallyNeedTransparencyThenDoWe = FALSE;
00343     
00344     PathProcessorStroke *pPathProc = Value.GetPathProcessor();
00345     if(pPathProc != NULL)
00346     {
00347         SoWeDoReallyNeedTransparencyThenDoWe = pPathProc->NeedsTransparency();
00348     }
00349 
00350     return SoWeDoReallyNeedTransparencyThenDoWe;
00351 }
00352 
00353 
00354 /********************************************************************************************
00355 
00356 >   virtual void AttrStrokeType::GetDebugDetails(StringBase *Str)
00357 
00358     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00359     Created:    8/1/97
00360 
00361     Outputs:    On return, Str is filled in with details on this node
00362 
00363     Purpose:    Produces debug details about this node
00364 
00365 ********************************************************************************************/
00366 
00367 void AttrStrokeType::GetDebugDetails(StringBase *Str)
00368 {
00369 #ifdef _DEBUG
00370     NodeAttribute::GetDebugDetails(Str);
00371 
00372     String_256 TempStr;
00373     TempStr._MakeMsg( _T("\r\nStroke type #1%s\r\n"),
00374                         (Value.GetPathProcessor() == NULL) ? _T("old-style line") : _T("new stroke:") );
00375     *Str += TempStr;
00376 
00377     if (Value.GetPathProcessor() != NULL)
00378     {
00379         TempStr._MakeMsg( _T("  #1%s\r\n"),
00380                             Value.GetPathProcessor()->GetRuntimeClass()->GetClassName() );
00381         *Str += TempStr;
00382     }
00383 
00384     TempStr._MakeMsg( _T("\r\nNeedsTransparency=#1%s\r\n"), NeedsTransparency() ? _T("TRUE") : _T("FALSE") );
00385     *Str += TempStr;
00386 
00387 #endif
00388 }
00389 
00390 
00391 /********************************************************************************************
00392 
00393 >   BOOL AttrStrokeType::HasPathProcessor()
00394 
00395     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00396     Created:    17/3/2000
00397     Inputs:     -
00398     Outputs:    -
00399     Returns:    TRUE if attribute value has a path processor, FALSE otherwise
00400     Purpose:    A good way to determine if this is one of the default attributes
00401 
00402 ********************************************************************************************/
00403 
00404 BOOL AttrStrokeType::HasPathProcessor()
00405 {
00406     if (Value.GetPathProcessor() == NULL)
00407         return FALSE;
00408     return TRUE;
00409 }
00410 
00411 
00412 /********************************************************************************************
00413 
00414 >   PathProcessorStroke* AttrStrokeType::GetPathProcessor()
00415 
00416     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00417     Created:    17/3/2000
00418     Inputs:     -
00419     Outputs:    -
00420     Returns:    the path processor of our attribute value
00421     Purpose:    Convenience function
00422 
00423 ********************************************************************************************/
00424 
00425 PathProcessorStroke* AttrStrokeType::GetPathProcessor()
00426 {
00427     return Value.GetPathProcessor();
00428 }
00429 
00430 
00431 
00432 /********************************************************************************************
00433 
00434 >   virtual BOOL AttrStrokeType::DoBecomeA(BecomeA* pBecomeA, Node* pParent)
00435 
00436     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00437     Created:    17/3/2000
00438     Inputs:     pBecomeA - the becomeA object that tells us what to do
00439                 pParent - the node that this attribute is applied to
00440     Outputs:    
00441     Returns:    TRUE if everything went ok,
00442     Purpose:    Its a little unusual for attributes to have their own dobecomea function but 
00443                 this stroke attribute requires one due to all the work it does on paths.
00444 
00445 ********************************************************************************************/
00446 
00447 BOOL AttrStrokeType::DoBecomeA(BecomeA* pBecomeA, Node* pParent)
00448 {
00449     ERROR2IF(pBecomeA == NULL, FALSE, "BecomeA pointer is NULL in AttrBrushType::DoBecomeA");
00450     ERROR2IF(pParent == NULL, FALSE, "Parent node is NULL in AttrBrushType::DoBecomeA");
00451     return Value.DoBecomeA(pBecomeA, pParent);
00452 }
00453 
00454 
00455 /********************************************************************************************
00456 
00457 >   virtual UINT32 AttrStrokeType::GetNodeSize() const
00458 
00459     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00460     Created:    8/1/97
00461 
00462     Returns:    The size of this node, in bytes
00463 
00464     Purpose:    For finding the size of the node, in bytes
00465 
00466 ********************************************************************************************/
00467 
00468 UINT32 AttrStrokeType::GetNodeSize() const
00469 {
00470     return(sizeof(AttrStrokeType));
00471 }
00472 
00473 
00474 
00475 /********************************************************************************************
00476 
00477 >   virtual BOOL AttrStrokeType::WritePreChildrenWeb(BaseCamelotFilter *pFilter)
00478 >   virtual BOOL AttrStrokeType::WritePreChildrenNative(BaseCamelotFilter *pFilter)
00479 
00480     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00481     Created:    8/1/97
00482 
00483     Inputs:     pFilter - filter to write to
00484 
00485     Returns:    TRUE if the Node has written out a record to the filter
00486 
00487     Purpose:    Writes out a record that represents the node, to either Native or Web
00488                 file format.
00489 
00490                 This function is called before any of the AttrStrokeType's children
00491                 are written to the filter.
00492 
00493                 If the AttrStrokeType writes out a record successfully to the file,
00494                 it will return TRUE.
00495 
00496                 If the AttrStrokeType chooses not to write itself to the filter
00497                 (e.g. because it is not appropriate for this filter), then this
00498                 function will return FALSE.
00499 
00500     Notes:      Simple StrokeTypes (not using fancy bitmap/vector brushes) just
00501                 write out a 4-byte (UINT32) record containing the stroke type.
00502                 Defined stroke types at this time are:
00503                     0 - Simple variable width stroke
00504 
00505     SeeAlso:    Node::WritePreChildrenNative; Node::WritePreChildrenWeb;
00506                 StrokeAttrRecordHandler::HandleRecord
00507 
00508 ********************************************************************************************/
00509 
00510 BOOL AttrStrokeType::WritePreChildrenWeb(BaseCamelotFilter *pFilter)
00511 {
00512     return(WritePreChildrenNative(pFilter));
00513 }
00514 
00515 BOOL AttrStrokeType::WritePreChildrenNative(BaseCamelotFilter *pFilter)
00516 {
00517 #ifdef DO_EXPORT
00518     ERROR3IF(pFilter == NULL, "Illegal NULL param");
00519 
00520     BOOL ok = TRUE;
00521     PathProcessorStroke *pProcessor = Value.GetPathProcessor();
00522 
00523     // Jason's being lazy this month, I'm afraid, because he won't be here next month...
00524     if (pProcessor == NULL ||
00525         !pProcessor->IsKindOf(CC_RUNTIME_CLASS(PathProcessorStrokeAirbrush)))
00526     {
00527         // It is a simple var-width stroke, or it is a vector stroke. These both export as
00528         // the same basic record tag, but with different "handle" words
00529         StrokeHandle Handle = 0x02000000;
00530 
00531         // Get the handle of the stroke
00532         if (pProcessor == NULL)
00533             Handle = 0x01000000;
00534         else if (pProcessor->IsKindOf(CC_RUNTIME_CLASS(PathProcessorStrokeVector)))
00535         {
00536             Handle = ((PathProcessorStrokeVector *)pProcessor)->GetStrokeDefinition();
00537             ERROR3IF((Handle & 0xff000000) != 0, "Handle overflow");
00538 
00539             // Make sure the stroke definition has preceeded any references to it
00540             ok = StrokeComponent::ExportStroke(pFilter, Handle);
00541         }
00542         //else
00543         //  it's a simple variable-width (base class) stroker, so we need not do anything
00544 
00545         // And write the record
00546         if (ok)
00547         {
00548             CamelotFileRecord Rec(pFilter, TAG_STROKETYPE, TAG_STROKETYPE_SIZE);
00549 
00550             if (ok) ok = Rec.Init();
00551             if (ok) ok = Rec.WriteUINT32((UINT32) Handle);
00552             if (ok) ok = pFilter->Write(&Rec);
00553         }
00554     }
00555     else
00556     {
00557         PathProcessorStrokeAirbrush *pProcessor = (PathProcessorStrokeAirbrush *)
00558                                                     Value.GetPathProcessor();
00559 
00560         ValueFunction *pFunction = pProcessor->GetIntensityFunction();
00561         ERROR3IF(pFunction == NULL, "No intensity function!?");
00562 
00563         // Currently, an airbrush record consists only of its intensity ValueFunction
00564         CamelotFileRecord *pRec = pFunction->WriteFileRecord(TAG_STROKEAIRBRUSH, 0, pFilter);
00565         if (pRec != NULL)
00566         {
00567             ok = pFilter->Write(pRec);
00568             delete pRec;
00569             pRec = NULL;
00570         }
00571         else
00572             ok = FALSE;
00573     }
00574 
00575     if (!ok)
00576         pFilter->GotError(_R(IDE_FILE_WRITE_ERROR));
00577 
00578     return(ok);
00579 #else
00580     return FALSE;
00581 #endif
00582 }
00583 
00584 
00585 
00586 
00587 
00588 
00589 
00590 
00591 
00592 
00593 
00594 
00595 
00596 
00597 
00598 
00599 /********************************************************************************************
00600 
00601 >   StrokeTypeAttrValue::StrokeTypeAttrValue(PathProcessorStroke *pPathProcessor = NULL);
00602 
00603     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00604     Created:    7/1/97
00605 
00606     Inputs:     pPathProcessor - the stroke path-processor which will do the stroking
00607                 effect "applied" by this attribute. NULL indicates that this attribute
00608                 does no stroking (i.e. that the path should have an old-style "line")
00609 
00610                 NOTE that this object is NOW OWNED by this StrokeTypeAttrValue, and will be
00611                 deleted when the attribute value is deleted.
00612 
00613     Purpose:    Default Constuctor for StrokeTypeAttrValue
00614 
00615 ********************************************************************************************/
00616 
00617 StrokeTypeAttrValue::StrokeTypeAttrValue(PathProcessorStroke *pPathProcessor)
00618 {
00619     // Remember our processor, and let it know that we "own" it
00620     pProcessor = pPathProcessor;
00621     if (pProcessor != NULL)
00622         pProcessor->SetParentAttr(this);
00623 }
00624 
00625 
00626 
00627 /********************************************************************************************
00628 
00629 >   StrokeTypeAttrValue::~StrokeTypeAttrValue()
00630 
00631     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00632     Created:    7/1/97
00633 
00634     Purpose:    Destructor
00635                 Deletes any attached PathProcessor (see the constructor)
00636 
00637 ********************************************************************************************/
00638 
00639 StrokeTypeAttrValue::~StrokeTypeAttrValue()
00640 {
00641     if (pProcessor != NULL)
00642         delete pProcessor;
00643 }
00644 
00645 
00646 
00647 /********************************************************************************************
00648 
00649 >   static BOOL StrokeTypeAttrValue::Init(void)
00650 
00651     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00652     Created:    7/1/97
00653 
00654     Returns:    TRUE if it initilised successfully
00655 
00656     Purpose:    Registers a default attribute of this type with the attribute manager
00657 
00658 ********************************************************************************************/
00659 
00660 BOOL StrokeTypeAttrValue::Init(void)
00661 {
00662     // The default attribute is one that has no effect (i.e. produces old-style "lines")
00663     StrokeTypeAttrValue *pAttr = new StrokeTypeAttrValue;
00664     if (pAttr == NULL)
00665         return FALSE;
00666 
00667     UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(StrokeTypeAttrValue),
00668                                                             pAttr);
00669 
00670     ERROR2IF(ID == ATTR_BAD_ID, FALSE, "Bad ID when Initialising StrokeTypeAttrValue");
00671 
00672     return(TRUE);
00673 }
00674 
00675 
00676 
00677 /********************************************************************************************
00678 
00679 >   virtual void StrokeTypeAttrValue::Render(RenderRegion *pRegion, BOOL Temp)
00680 
00681     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00682     Created:    7/1/97
00683 
00684     Inputs:     pRegion - the render region to render this attribute into.
00685 
00686     Purpose:    Sets the StrokeTypeAttrValue attribute for the given render region.
00687 
00688     Notes:      This attribute makes itself current in the render region, and
00689                 also (possibly) adds a PathProcessor to handle stroking of
00690                 all future rendered paths (until the attr is "restored")
00691 
00692     SeeAlso:    StrokeTypeAttrValue::Restore
00693 
00694 ********************************************************************************************/
00695 
00696 void StrokeTypeAttrValue::Render(RenderRegion *pRegion, BOOL Temp)
00697 {
00698     // Stack the current attribute and set ourselves up as the new one
00699     pRegion->SetStrokeType(this, Temp);
00700 
00701     // Find if we have a path processor to do the stroking, and if we do, 
00702     // stack a copy of it (a copy must be used to be thread-safe & bgrender-safe)
00703     if (pProcessor != NULL)
00704     {
00705         PathProcessorStroke *pNewProcessor = pProcessor->Clone();
00706         if (pNewProcessor != NULL)
00707             pRegion->PushPathProcessor(pNewProcessor);
00708     }
00709 }
00710 
00711 
00712 
00713 /********************************************************************************************
00714 
00715 >   virtual void StrokeTypeAttrValue::Restore(RenderRegion *pRegion, BOOL Temp)
00716 
00717     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00718     Created:    7/1/97
00719 
00720     Inputs:     pRegion - the render region to restore the attribute into.
00721                 Temp    - TRUE if this is a temporary attribute, FALSE if it is
00722                           permanent (e.g. it's in a document tree).
00723 
00724     Purpose:    Restores the StrokeTypeAttrValue attribute for the given render region. 
00725 
00726     Notes:      This attribute makes sure it removes any PathProcessor it added
00727                 to handle path stroking in StrokeTypeAttrValue::Render
00728 
00729 ********************************************************************************************/
00730 
00731 void StrokeTypeAttrValue::Restore(RenderRegion *pRegion, BOOL Temp)
00732 {
00733     pRegion->RestoreStrokeType(this, Temp);
00734 }
00735 
00736 
00737 
00738 /********************************************************************************************
00739 
00740 >   void StrokeTypeAttrValue::GoingOutOfScope(RenderRegion *pRegion)
00741 
00742     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00743     Created:    9/1/97
00744 
00745     Inputs:     pRegion - the render region the attribute is in use by
00746 
00747     Purpose:    A sister function to Render()
00748 
00749                 This is called by a render region when an attribute goes out of
00750                 scope, i.e. when the attribute is no longer in use and is popped
00751                 off the stack for the last time. (Do NOT confuse this with being
00752                 pushed onto the render stack when overridden by another attr)
00753 
00754                 It gives the attribute a chance to remove any PathProcessor(s)
00755                 it added to the RenderRegion when it was Render()ed.
00756 
00757     Notes:      This attribute makes sure it removes any PathProcessor it added
00758                 to handle path stroking in StrokeTypeAttrValue::Render
00759 
00760     SeeAlso:    StrokeTypeAttrValue::Render()
00761 
00762 ********************************************************************************************/
00763 
00764 void StrokeTypeAttrValue::GoingOutOfScope(RenderRegion *pRegion)
00765 {
00766     if (pProcessor != NULL)
00767         pRegion->PopPathProcessor();
00768 }
00769 
00770 
00771 
00772 /********************************************************************************************
00773 
00774 >   virtual void StrokeTypeAttrValue::SimpleCopy(AttributeValue *pValue)
00775 
00776     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00777     Created:    7/1/97
00778 
00779     Inputs:     pValue - pointer to the AttributeValue to copy
00780 
00781     Purpose:    See AttributeValue::SimpleCopy
00782 
00783 ********************************************************************************************/
00784 
00785 void StrokeTypeAttrValue::SimpleCopy(AttributeValue *pValue)
00786 {
00787     ERROR3IF(!IS_A(pValue, StrokeTypeAttrValue),
00788                 "Invalid Attribute value passed to StrokeTypeAttrValue::SimpleCopy");
00789 
00790     // Just uses the assignment operator
00791     *this = *((StrokeTypeAttrValue *) pValue);
00792 }
00793 
00794 
00795 
00796 /********************************************************************************************
00797 
00798 >   virtual NodeAttribute *StrokeTypeAttrValue::MakeNode()
00799 
00800     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00801     Created:    7/1/97
00802 
00803     Returns:    Pointer to the new node, or NULL if out of memory.
00804 
00805     Purpose:    Make a new attribute node for this type of attr value - see base class
00806 
00807     SeeAlso:    AttributeValue::MakeNode
00808 
00809 ********************************************************************************************/
00810 
00811 NodeAttribute *StrokeTypeAttrValue::MakeNode()
00812 {
00813     // Create new attribute node
00814     AttrStrokeType *pAttr = new AttrStrokeType;
00815     if (pAttr == NULL)
00816         return NULL;
00817 
00818     // Copy attribute value (if any) into the new node.
00819     if (pAttr->GetAttributeValue() != NULL)
00820         pAttr->GetAttributeValue()->SimpleCopy(this);
00821 
00822     return(pAttr);
00823 }
00824 
00825 
00826 
00827 /********************************************************************************************
00828 
00829 >   virtual BOOL StrokeTypeAttrValue::IsDifferent(AttributeValue *pAttr)
00830 
00831     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00832     Created:    7/1/97
00833 
00834     Purpose:    Determines if this AttrValue is different from the given one
00835 
00836     Errors:     ERROR3 if the two attributes are not of the same type
00837 
00838     SeeAlso:    AttributeValue::IsDifferent
00839 
00840 ********************************************************************************************/
00841 
00842 BOOL StrokeTypeAttrValue::IsDifferent(AttributeValue *pAttr)
00843 {
00844     ERROR3IF(!pAttr->IsKindOf(CC_RUNTIME_CLASS(StrokeTypeAttrValue)),
00845                 "Different attribute types in StrokeTypeAttrValue::IsDifferent()");
00846 
00847     // Check they are NOT the same using the == operator
00848     return ( !(*((StrokeTypeAttrValue *)pAttr) == *this) );
00849 }
00850 
00851 
00852 
00853 /********************************************************************************************
00854 
00855 >   virtual StrokeTypeAttrValue &StrokeTypeAttrValue::operator=(StrokeTypeAttrValue &Attrib)
00856 
00857     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00858     Created:    7/1/97
00859 
00860     Inputs:     Attrib - the attribute to copy
00861 
00862     Purpose:    Assignment operator
00863 
00864 ********************************************************************************************/
00865 
00866 StrokeTypeAttrValue &StrokeTypeAttrValue::operator=(StrokeTypeAttrValue &Attrib)
00867 {
00868     // Get rid of our old processor (if any)
00869     if (pProcessor != NULL)
00870         delete pProcessor;
00871     pProcessor = NULL;
00872 
00873     // Copy the other attr's processor. If this fails, we'll get back a NULL pointer,
00874     // and will simply "convert" into a simple no-stroke attribute.
00875     if (Attrib.pProcessor != NULL)
00876     {
00877         pProcessor = Attrib.pProcessor->Clone();
00878         if (pProcessor != NULL)
00879             pProcessor->SetParentAttr(this);
00880     }
00881 
00882     return(*this);
00883 }
00884 
00885 
00886 
00887 /********************************************************************************************
00888 
00889 >   virtual INT32 StrokeTypeAttrValue::operator==(const StrokeTypeAttrValue &Attrib)
00890 
00891     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00892     Created:    7/1/97
00893 
00894     Inputs:     Attrib - the attribute to compare this attribute with
00895 
00896     Returns:    TRUE if the attributes are considered equal
00897 
00898     Purpose:    Comparison operator
00899 
00900 ********************************************************************************************/
00901 
00902 INT32 StrokeTypeAttrValue::operator==(const StrokeTypeAttrValue &Attrib)
00903 {
00904     ERROR3IF(!Attrib.IsKindOf(CC_RUNTIME_CLASS(StrokeTypeAttrValue)),
00905                 "Other attribute value isn't an StrokeTypeAttrValue");
00906 
00907     StrokeTypeAttrValue *Other = (StrokeTypeAttrValue *) &Attrib;
00908 
00909     // Equal if they both have same processor (only applies if they are both NULL)
00910     if (pProcessor == Other->pProcessor)
00911         return(TRUE);
00912 
00913     // Otherwise, if one of them is NULL, they can't be the same
00914     if (pProcessor == NULL || Other->pProcessor == NULL)
00915         return(FALSE);
00916 
00917     // Finally, ask the processors if they are of the same type
00918     return(!pProcessor->IsDifferent(Other->pProcessor));
00919 }
00920 
00921 
00922 
00923 /********************************************************************************************
00924 
00925 >   void StrokeTypeAttrValue::SetPathProcessor(PathProcessorStroke *pNewProcessor)
00926 
00927     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
00928     Created:    7/1/97
00929 
00930     Inputs:     pNewProcessor - The new PathProcessorStroke to be used by this attr.
00931                 May be NULL, in which case it sets "old style lines" stroking mode.
00932 
00933     Purpose:    To set the path processor used by this object. The processor is now
00934                 "owned" by this attribute, and will be auto-deleted upon destruction
00935 
00936 ********************************************************************************************/
00937 
00938 void StrokeTypeAttrValue::SetPathProcessor(PathProcessorStroke *pNewProcessor)
00939 {
00940     if (pProcessor != NULL)
00941         delete pProcessor;
00942 
00943     pProcessor = pNewProcessor;
00944     if (pProcessor != NULL)
00945         pProcessor->SetParentAttr(this);
00946 }
00947 
00948 
00949 /********************************************************************************************
00950 
00951 >   BOOL StrokeTypeAttrValue::DoBecomeA(BecomeA* pBecomeA, Node* pParent)
00952 
00953     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
00954     Created:    17/3/2000
00955     Inputs:     pBecomeA - the object that tells us what to become, and recieves the results
00956                 pParent - the node that this attribute is applied to
00957     Outputs:    
00958     Returns:    TRUE if everything went ok,
00959     Purpose:    To convert our stroke into something more palatable.  pParent
00960                 should always be a nodepath 
00961     
00962     Notes:      Due to problems with bevelling and contouring this function does not get
00963                 called in the normal DoBecomeA procedure unless you specifically locate this
00964                 attribute and call this function directly.
00965 ********************************************************************************************/
00966 
00967 BOOL StrokeTypeAttrValue::DoBecomeA(BecomeA* pBecomeA, Node* pParent)
00968 {
00969     ERROR2IF(pBecomeA == NULL, FALSE, "BecomeA pointer is NULL in VariableWidthAttrValue::DoBecomeA");
00970     ERROR2IF(pParent == NULL, FALSE, "Parent node is NULL in VariableWidthAttrValue::DoBecomeA");
00971 
00972     if (pProcessor == NULL)
00973         return FALSE;
00974 
00975     if (!pBecomeA->BAPath())
00976         return FALSE;
00977 
00978     BOOL Success = FALSE;
00979 //  UINT32 Dummy = 0;
00980     // if we have a nodepath then we can simply use its member path, otherwise we
00981     // have to ask it to become a nodepath
00982     if (pParent->IsNodePath())
00983     {   
00984         // we have a special calculation for nodepaths, because we can use their path
00985         Success =  pProcessor->DoBecomeA(pBecomeA, &((NodePath*)pParent)->InkPath, pParent);
00986     }
00987     else if (pParent->CanBecomeA(pBecomeA))
00988     {
00989         // we must be applied to some arbitrary shape.  The thing is that we need to have
00990         // a path to pass to the PPB, so want to get a passback of all the paths in 
00991         // the node 
00992         
00993         // we need to allocate a path
00994         Path* pPath = new Path;
00995         if (pPath != NULL && pPath->Initialise())
00996         {
00997             PathBecomeA BecomeAPath(BECOMEA_PASSBACK, CC_RUNTIME_CLASS(NodePath), NULL, FALSE, pPath);
00998             if (pParent->DoBecomeA(&BecomeAPath))
00999             {
01000                 Success =  pProcessor->DoBecomeA(pBecomeA, pPath, pParent);
01001             }
01002             delete pPath;
01003         }
01004     }
01005     return Success;
01006 }
01007 
01008 
01009 
01010 
01011 
01012 
01013 
01014 
01015 
01016 
01017 /********************************************************************************************
01018 
01019 >   AttrVariableWidth::AttrVariableWidth()
01020 
01021     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01022     Created:    7/1/97
01023 
01024     Purpose:    Default constructor for AttrVariableWidth
01025 
01026 ********************************************************************************************/
01027 
01028 AttrVariableWidth::AttrVariableWidth()
01029 {
01030 }
01031 
01032 
01033 
01034 /********************************************************************************************
01035 
01036 >   AttrVariableWidth::AttrVariableWidth(Node *ContextNode,
01037                                         AttachNodeDirection Direction,
01038                                         BOOL Locked,
01039                                         BOOL Mangled,
01040                                         BOOL Marked,
01041                                         BOOL Selected)
01042     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01043     Created:    7/1/97
01044 
01045     Purpose:    Constructs an AttrVariableWidth Attribute
01046 
01047 ********************************************************************************************/
01048 
01049 AttrVariableWidth::AttrVariableWidth(Node *ContextNode,
01050                                     AttachNodeDirection Direction,
01051                                     BOOL Locked,
01052                                     BOOL Mangled,
01053                                     BOOL Marked,
01054                                     BOOL Selected)
01055                 : NodeAttribute(ContextNode, Direction, Locked, Mangled, Marked, Selected)
01056 {
01057 }
01058 
01059 
01060 
01061 /********************************************************************************************
01062 
01063 >   virtual void AttrVariableWidth::Render(RenderRegion *pRender)
01064 
01065     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01066     Created:    7/1/97
01067 
01068     Purpose:    Renders this attribute (by simply calling the Render function of
01069                 its contained AttributeValue)
01070 
01071 ********************************************************************************************/
01072 
01073 void AttrVariableWidth::Render(RenderRegion *pRender)
01074 {
01075     GetAttributeValue()->Render(pRender);
01076 }
01077 
01078 
01079 
01080 /***********************************************************************************************
01081 
01082 >   virtual void AttrVariableWidth::CopyNodeContents(AttrVariableWidth *NodeCopy)
01083 
01084     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01085     Created:    7/1/97
01086 
01087     Outputs:    NodeCopy - returned containing a copy of this node
01088          
01089     Purpose:    Copies the node's contents to the node pointed to by NodeCopy
01090 
01091 ***********************************************************************************************/
01092 
01093 void AttrVariableWidth::CopyNodeContents(AttrVariableWidth *NodeCopy)
01094 {
01095     // Let the base class do its bit
01096     NodeAttribute::CopyNodeContents(NodeCopy);
01097 
01098     // And then copy our Value
01099     *(NodeCopy->GetAttributeValue()) = *(GetAttributeValue());
01100 }
01101 
01102 
01103 
01104 /***********************************************************************************************
01105 >   void AttrVariableWidth::PolyCopyNodeContents(NodeRenderable* pNodeCopy)
01106 
01107     Author:     Phil_Martin (Xara Group Ltd) <camelotdev@xara.com>
01108     Created:    18/12/2003
01109     Outputs:    -
01110     Purpose:    Polymorphically copies the contents of this node to another
01111     Errors:     An assertion failure will occur if NodeCopy is NULL
01112     Scope:      protected
01113                                      
01114 ***********************************************************************************************/
01115 
01116 void AttrVariableWidth::PolyCopyNodeContents(NodeRenderable* pNodeCopy)
01117 {
01118     ENSURE(pNodeCopy, "Trying to copy a node's contents into a NULL node");
01119     ENSURE(IS_A(pNodeCopy, AttrVariableWidth), "PolyCopyNodeContents given wrong dest node type");
01120 
01121     if (IS_A(pNodeCopy, AttrVariableWidth))
01122         CopyNodeContents((AttrVariableWidth*)pNodeCopy);
01123 }
01124 
01125 
01126 
01127 /***********************************************************************************************
01128 
01129 >   virtual INT32 AttrVariableWidth::operator==(const NodeAttribute &NodeAttrib); 
01130 
01131     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01132     Created:    8/7/97
01133 
01134     Inputs:     NodeAttrib - The node to compare this node to
01135     Returns:    TRUE if the nodes are considered equal
01136 
01137     Purpose:    Comparison operator - determines if the AttributeValues of both objects are ==
01138 
01139 ***********************************************************************************************/
01140 
01141 INT32 AttrVariableWidth::operator==(const NodeAttribute &NodeAttrib)
01142 {
01143     // First check they are of the same type
01144     if (((NodeAttribute*)&NodeAttrib)->GetAttributeType() != GetAttributeType())
01145         return FALSE;
01146 
01147     // Make a more sensible pointer
01148     AttrVariableWidth *Attr = (AttrVariableWidth *) &NodeAttrib;
01149 
01150     // Now let the AttributeValues compare themselves
01151     return( *((VariableWidthAttrValue *) Attr->GetAttributeValue())  ==
01152             *((VariableWidthAttrValue *) GetAttributeValue()) );
01153 }
01154 
01155 
01156 
01157 /********************************************************************************************
01158 
01159 >   virtual Node *AttrVariableWidth::SimpleCopy()
01160 
01161     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01162     Created:    8/1/97
01163 
01164     Returns:    A copy of the node, or NULL if memory runs out 
01165 
01166     Purpose:    This method returns a shallow copy of the node with all Node pointers NULL. 
01167                 The function is virtual, and must be defined for all derived classes.  
01168 
01169 ********************************************************************************************/
01170 
01171 Node *AttrVariableWidth::SimpleCopy()
01172 {
01173     AttrVariableWidth* NodeCopy = new AttrVariableWidth;
01174     if (NodeCopy == NULL)
01175         return(NULL);
01176 
01177     // Call the base class
01178     NodeAttribute::CopyNodeContents(NodeCopy);
01179 
01180     // And call our AttributeValue to copy itself too
01181     NodeCopy->GetAttributeValue()->SimpleCopy(GetAttributeValue());
01182     
01183     return(NodeCopy);
01184 }
01185 
01186 
01187 
01188 /********************************************************************************************
01189 
01190 >   virtual UINT32 AttrVariableWidth::GetAttrNameID(void)
01191 
01192     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01193     Created:    8/1/97
01194 
01195     Returns:    Attribute description string-resource ID
01196 
01197     Purpose:    Retrieves a string resource ID describing this attribute
01198 
01199 ********************************************************************************************/
01200 
01201 UINT32 AttrVariableWidth::GetAttrNameID(void)
01202 {
01203     return(_R(IDS_ATTRVARWIDTH));
01204 }
01205 
01206 
01207 
01208 /********************************************************************************************
01209 
01210 >   virtual void AttrVariableWidth::GetDebugDetails(StringBase *Str)
01211 
01212     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01213     Created:    8/1/97
01214 
01215     Outputs:    On return, Str is filled in with details on this node
01216 
01217     Purpose:    Produces debug details about this node
01218 
01219 ********************************************************************************************/
01220 
01221 void AttrVariableWidth::GetDebugDetails(StringBase *Str)
01222 {
01223 #ifdef _DEBUG
01224     NodeAttribute::GetDebugDetails(Str);
01225 
01226     String_256 TempStr;
01227     TempStr._MakeMsg( _T("\r\nVariable width of type:\r\n") );
01228     *Str += TempStr;
01229 
01230     if (Value.GetWidthFunction() != NULL)
01231     {
01232         TempStr._MakeMsg( _T("  #1%s\r\n"),
01233                             Value.GetWidthFunction()->GetRuntimeClass()->GetClassName() );
01234     }
01235     else
01236         TempStr._MakeMsg( _T("  old-style constant width\r\n") );
01237 
01238     *Str += TempStr;
01239 #endif
01240 }
01241 
01242 
01243 
01244 /********************************************************************************************
01245 
01246 >   virtual UINT32 AttrVariableWidth::GetNodeSize() const
01247 
01248     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01249     Created:    8/1/97
01250 
01251     Returns:    The size of this node, in bytes
01252 
01253     Purpose:    For finding the size of the node, in bytes
01254 
01255 ********************************************************************************************/
01256 
01257 UINT32 AttrVariableWidth::GetNodeSize() const
01258 {
01259     return(sizeof(AttrVariableWidth));
01260 }
01261 
01262 
01263 
01264 /********************************************************************************************
01265 
01266 >   BOOL AttrVariableWidth::HasActiveValueFunction() const
01267 
01268     Author:     Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com>
01269     Created:    27/11/2000
01270 
01271     Returns:    True if our attr value has a value function, false if not
01272 
01273     Purpose:    To find out if this attribute is actually going to do anything or not
01274 
01275 ********************************************************************************************/
01276 
01277 BOOL AttrVariableWidth::HasActiveValueFunction() 
01278 {
01279     return (Value.GetWidthFunction() != NULL);
01280 }
01281 
01282 /********************************************************************************************
01283 
01284 >   virtual BOOL AttrVariableWidth::WritePreChildrenWeb(BaseCamelotFilter *pFilter)
01285 >   virtual BOOL AttrVariableWidth::WritePreChildrenNative(BaseCamelotFilter *pFilter)
01286 
01287     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01288     Created:    8/1/97
01289 
01290     Inputs:     pFilter - filter to write to
01291 
01292     Returns:    TRUE if the Node has written out a record to the filter
01293 
01294     Purpose:    Writes out a record that represents the node, to either Native or Web
01295                 file format.
01296 
01297                 This function is called before any of the AttrVariableWidth's children
01298                 are written to the filter.
01299 
01300                 If the AttrVariableWidth writes out a record successfully to the file,
01301                 it will return TRUE.
01302 
01303                 If the AttrVariableWidth chooses not to write itself to the filter
01304                 (e.g. because it is not appropriate for this filter), then this
01305                 function will return FALSE.
01306 
01307     Notes:      Simple 
01308 
01309     SeeAlso:    Node::WritePreChildrenNative; Node::WritePreChildrenWeb;
01310                 StrokeAttrRecordHandler::HandleRecord
01311 
01312 ********************************************************************************************/
01313 
01314 BOOL AttrVariableWidth::WritePreChildrenWeb(BaseCamelotFilter *pFilter)
01315 {
01316     return(WritePreChildrenNative(pFilter));
01317 }
01318 
01319 BOOL AttrVariableWidth::WritePreChildrenNative(BaseCamelotFilter *pFilter)
01320 {
01321 #ifdef DO_EXPORT
01322     ERROR3IF(pFilter == NULL, "Illegal NULL param");
01323 
01324     BOOL ok = TRUE;
01325     VariableWidthID PredefinedFunctionID = Value.GetWidthFunctionID();
01326 
01327     if (PredefinedFunctionID == VarWidth_NotPredefined)
01328     {
01329         ValueFunction *pFunction = Value.GetWidthFunction();
01330         if (pFunction != NULL)
01331         {
01332             CamelotFileRecord *pRec = pFunction->WriteFileRecord(TAG_VARIABLEWIDTHTABLE, 0, pFilter);
01333             if (pRec != NULL)
01334             {
01335                 pFilter->Write(pRec);
01336                 delete pRec;
01337                 pRec = NULL;
01338             }
01339             else
01340                 ok = FALSE;
01341         }
01342         else
01343         {
01344             // The default attribute (for simple old-style lines) has no ValueFunction
01345             CamelotFileRecord Rec(pFilter, TAG_VARIABLEWIDTHFUNC, TAG_VARIABLEWIDTHFUNC_SIZE);
01346             if (ok) ok = Rec.Init();
01347             if (ok) ok = Rec.WriteUINT32((UINT32) 0);
01348             if (ok) ok = pFilter->Write(&Rec);
01349         }
01350     }
01351     else
01352     {
01353         CamelotFileRecord Rec(pFilter, TAG_VARIABLEWIDTHFUNC, TAG_VARIABLEWIDTHFUNC_SIZE);
01354 
01355         if (ok) ok = Rec.Init();
01356         if (ok) ok = Rec.WriteUINT32((UINT32) PredefinedFunctionID);
01357         if (ok) ok = pFilter->Write(&Rec);
01358     }
01359 
01360     if (!ok)
01361         pFilter->GotError(_R(IDE_FILE_WRITE_ERROR));
01362 
01363     return(ok);
01364 #else
01365     return FALSE;
01366 #endif
01367 }
01368 
01369 
01370 
01371 
01372 
01373 
01374 
01375 
01376 
01377 
01378 
01379 
01380 
01381 
01382 
01383 /********************************************************************************************
01384 
01385 >   VariableWidthAttrValue::VariableWidthAttrValue(ValueFunction *pValueFunction = NULL)
01386 
01387     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01388     Created:    7/1/97
01389 
01390     Inputs:     pValueFunction - NULL (for simple constant-width "line") or a ValueFunction
01391                                  describing the variable width of paths affected by this attr.
01392 
01393                                  NOTE that this object now BELONGS to the new attr, and
01394                                  will be deleted automatically when this object is destructed
01395 
01396     Purpose:    Constuctor for VariableWidthAttrValue
01397 
01398 ********************************************************************************************/
01399 
01400 VariableWidthAttrValue::VariableWidthAttrValue(ValueFunction *pValueFunction)
01401 {
01402     WidthFunction = pValueFunction;
01403     PredefinedFunctionID = VarWidth_NotPredefined;
01404 }
01405 
01406 
01407 
01408 /********************************************************************************************
01409 
01410 >   VariableWidthAttrValue::~VariableWidthAttrValue()
01411 
01412     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01413     Created:    7/1/97
01414 
01415     Purpose:    Destructor for VariableWidthAttrValue
01416 
01417 ********************************************************************************************/
01418 
01419 VariableWidthAttrValue::~VariableWidthAttrValue()
01420 {
01421     if (WidthFunction != NULL)
01422         delete WidthFunction;
01423 }
01424 
01425 
01426 
01427 /********************************************************************************************
01428 
01429 >   static BOOL VariableWidthAttrValue::Init(void)
01430 
01431     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01432     Created:    7/1/97
01433 
01434     Returns:    TRUE if it initilised successfully
01435 
01436     Purpose:    Registers a default attribute of this type with the attribute manager
01437 
01438 ********************************************************************************************/
01439 
01440 BOOL VariableWidthAttrValue::Init(void)
01441 {
01442     // The default attribute is one that has no effect (i.e. produces constant-width "lines")
01443     VariableWidthAttrValue *pAttr = new VariableWidthAttrValue;
01444     if (pAttr == NULL)
01445         return FALSE;
01446 
01447     UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(VariableWidthAttrValue),
01448                                                             pAttr);
01449 
01450     ERROR2IF(ID == ATTR_BAD_ID, FALSE, "Bad ID when Initialising VariableWidthAttrValue");
01451 
01452     return(TRUE);
01453 }
01454 
01455 
01456 
01457 /********************************************************************************************
01458 
01459 >   virtual void VariableWidthAttrValue::Render(RenderRegion *pRegion, BOOL Temp)
01460 
01461     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01462     Created:    7/1/97
01463 
01464     Inputs:     pRegion - the render region to render this attribute into.
01465 
01466     Purpose:    Sets the VariableWidthAttrValue attribute for the given render region.
01467 
01468     Notes:      This attribute is so simple that its state can be read directly off
01469                 the render region's stack. Thus, there is minimal special render region
01470                 support for this attribute - we just stack and unstack it directly here.
01471 
01472 ********************************************************************************************/
01473 
01474 void VariableWidthAttrValue::Render(RenderRegion *pRegion, BOOL Temp)
01475 {
01476     pRegion->SetVariableWidth(this, Temp);
01477 }
01478 
01479 
01480 
01481 /********************************************************************************************
01482 
01483 >   virtual void VariableWidthAttrValue::Restore(RenderRegion *pRegion, BOOL Temp)
01484 
01485     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01486     Created:    7/1/97
01487 
01488     Inputs:     pRegion - the render region to restore the attribute into.
01489                 Temp    - TRUE if this is a temporary attribute, FALSE if it is
01490                           permanent (e.g. it's in a document tree).
01491 
01492     Purpose:    Restores the VariableWidthAttrValue attribute for the given render region. 
01493 
01494     Notes:      This attribute is so simple that its state can be read directly off
01495                 the render region's stack. Thus, there is minimal special render region
01496                 support for this attribute - we just stack and unstack it directly here.
01497 
01498 ********************************************************************************************/
01499 
01500 void VariableWidthAttrValue::Restore(RenderRegion *pRegion, BOOL Temp)
01501 {
01502     pRegion->RestoreVariableWidth(this, Temp);
01503 }
01504 
01505 
01506 
01507 /********************************************************************************************
01508 
01509 >   virtual void VariableWidthAttrValue::SimpleCopy(AttributeValue *pValue)
01510 
01511     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01512     Created:    7/1/97
01513 
01514     Inputs:     pValue - pointer to the AttributeValue to copy
01515 
01516     Purpose:    See AttributeValue::SimpleCopy
01517 
01518 ********************************************************************************************/
01519 
01520 void VariableWidthAttrValue::SimpleCopy(AttributeValue *pValue)
01521 {
01522     ERROR3IF(!IS_A(pValue, VariableWidthAttrValue),
01523                 "Invalid Attribute value passed to VariableWidthAttrValue::SimpleCopy");
01524 
01525     // Just uses the assignment operator
01526     *this = *((VariableWidthAttrValue *) pValue);
01527 }
01528 
01529 
01530 
01531 /********************************************************************************************
01532 
01533 >   virtual NodeAttribute *VariableWidthAttrValue::MakeNode()
01534 
01535     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01536     Created:    7/1/97
01537 
01538     Returns:    Pointer to the new node, or NULL if out of memory.
01539 
01540     Purpose:    Make a new attribute node for this type of attr value - see base class
01541 
01542     SeeAlso:    AttributeValue::MakeNode
01543 
01544 ********************************************************************************************/
01545 
01546 NodeAttribute *VariableWidthAttrValue::MakeNode()
01547 {
01548     // Create new attribute node
01549     AttrVariableWidth *pAttr = new AttrVariableWidth();
01550     if (pAttr == NULL)
01551         return NULL;
01552 
01553     // Copy attribute value (if any) into the new node.
01554     if (pAttr->GetAttributeValue() != NULL)
01555         pAttr->GetAttributeValue()->SimpleCopy(this);
01556 
01557     return(pAttr);
01558 }
01559 
01560 
01561 
01562 /********************************************************************************************
01563 
01564 >   virtual BOOL VariableWidthAttrValue::IsDifferent(AttributeValue *pAttr)
01565 
01566     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01567     Created:    7/1/97
01568 
01569     Purpose:    Determines if this AttrValue is different from the given one
01570 
01571     Errors:     ERROR3 if the two attributes are not of the same type
01572 
01573     SeeAlso:    AttributeValue::IsDifferent
01574 
01575 ********************************************************************************************/
01576 
01577 BOOL VariableWidthAttrValue::IsDifferent(AttributeValue *pAttr)
01578 {
01579     ERROR3IF(!pAttr->IsKindOf(CC_RUNTIME_CLASS(VariableWidthAttrValue)),
01580                 "Different attribute types in VariableWidthAttrValue::IsDifferent()");
01581 
01582     // Check they are NOT the same using the == operator
01583     return ( !(*((VariableWidthAttrValue *)pAttr) == *this) );
01584 }
01585 
01586 
01587 
01588 /********************************************************************************************
01589 
01590 >   virtual VariableWidthAttrValue &VariableWidthAttrValue::operator=(VariableWidthAttrValue &Attrib)
01591 
01592     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01593     Created:    7/1/97
01594 
01595     Inputs:     Attrib - the attribute to copy
01596 
01597     Purpose:    Assignment operator
01598 
01599 ********************************************************************************************/
01600 
01601 VariableWidthAttrValue &VariableWidthAttrValue::operator=(VariableWidthAttrValue &Attrib)
01602 {
01603     // Delete our existing WidthFunction (if any)
01604     if (WidthFunction != NULL)
01605         delete WidthFunction;
01606     WidthFunction = NULL;
01607 
01608     // Try to clone the other attribute's width function. If this fails, we'll just
01609     // end up as a constant-width line (NULL ValueFunction pointer)
01610     if (Attrib.GetWidthFunction() != NULL)
01611         WidthFunction = Attrib.GetWidthFunction()->Clone();
01612 
01613     // And copy its ID member across too
01614     PredefinedFunctionID = Attrib.PredefinedFunctionID;
01615 
01616     return(*this);
01617 }
01618 
01619 
01620 
01621 /********************************************************************************************
01622 
01623 >   virtual INT32 VariableWidthAttrValue::operator==(const VariableWidthAttrValue &Attrib)
01624 
01625     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01626     Created:    7/1/97
01627 
01628     Inputs:     Attrib - the attribute to compare this attribute with
01629 
01630     Returns:    TRUE if the attributes are considered equal
01631 
01632     Purpose:    Comparison operator
01633 
01634 ********************************************************************************************/
01635 
01636 INT32 VariableWidthAttrValue::operator==(const VariableWidthAttrValue &Attrib)
01637 {
01638     ERROR3IF(!Attrib.IsKindOf(CC_RUNTIME_CLASS(VariableWidthAttrValue)),
01639                 "Other attribute value isn't an VariableWidthAttrValue");
01640 
01641 //  VariableWidthAttrValue *Other = (VariableWidthAttrValue *) &Attrib;
01642 
01643     // If both width functions are NULL, we are equal
01644     if (WidthFunction == NULL && Attrib.WidthFunction == NULL)
01645         return(TRUE);
01646 
01647     // If only one function is NULL, we ca't be considered equal
01648     if (WidthFunction == NULL || Attrib.WidthFunction == NULL)
01649         return(FALSE);
01650 
01651     // Finally, if both have a valid width function, ask them if they're equal
01652     return(!WidthFunction->IsDifferent(Attrib.WidthFunction));
01653 }
01654 
01655 
01656 
01657 /********************************************************************************************
01658 
01659 >   void VariableWidthAttrValue::SetWidthFunction(ValueFunction *pNewFunction)
01660 
01661     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01662     Created:    7/1/97
01663 
01664     Inputs:     pNewFunction - The new value function to use for variable-width strokes
01665                 affected by this attribute. May be NULL, in which case all strokes will
01666                 be simple constant-width strokes.
01667 
01668                 NOTE that this object now belongs to this Attr, and will be automatically
01669                 deleted upon destruction of the attr.
01670 
01671     Purpose:    To set the width function used in stroking
01672 
01673     Notes:      See the alternative form of this method - it uses predefined function
01674                 "shapes", which save in a more compact format.
01675 
01676 ********************************************************************************************/
01677 
01678 void VariableWidthAttrValue::SetWidthFunction(ValueFunction *pNewFunction)
01679 {
01680     if (WidthFunction != NULL)
01681         delete WidthFunction;
01682 
01683     WidthFunction = pNewFunction;
01684     PredefinedFunctionID = VarWidth_NotPredefined;
01685 }
01686 
01687 
01688 
01689 /********************************************************************************************
01690 
01691 >   void VariableWidthAttrValue::SetWidthFunction(VariableWidthID PredefinedFuncID)
01692 
01693     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01694     Created:    7/1/97
01695 
01696     Inputs:     PredefinedFuncID - The ID of which predefined width function type you
01697                 wish to use. Predefined types are used to save space in the file format
01698                 when exporting simple variable width attributes.
01699 
01700     Purpose:    To set the width function used in stroking
01701 
01702 ********************************************************************************************/
01703 
01704 void VariableWidthAttrValue::SetWidthFunction(VariableWidthID PredefinedFuncID)
01705 {
01706     ERROR3IF(PredefinedFuncID == VarWidth_NotPredefined, "You what?!");
01707 
01708     // get rid of any old width function
01709     if (WidthFunction != NULL)
01710     {
01711         delete WidthFunction;
01712         WidthFunction = NULL;
01713     }
01714 
01715     // Remember the new predefined-width-function identifier, so that we
01716     // know that our width is a spaecial predefined form which can be saved
01717     // in a much simpler & smaller format
01718     PredefinedFunctionID = PredefinedFuncID;
01719 
01720     switch(PredefinedFunctionID)
01721     {
01722         case VarWidth_Constant:
01723             WidthFunction = new ValueFunctionConstant(1.0);
01724             break;
01725 
01726         case VarWidth_LinRamp:
01727             WidthFunction = new ValueFunctionRampLinear(1.0, 0.0);
01728             break;
01729 
01730         case VarWidth_SRamp:
01731             WidthFunction = new ValueFunctionRampS(1.0, 0.0);
01732             break;
01733 
01734         default:
01735             ERROR3("Unsupported predefined width function");
01736             break;
01737     }
01738 }
01739 
01740 
01741 
01742 
01743 
01744 
01745 
01746 
01747 
01748 /********************************************************************************************
01749 
01750 >   virtual UINT32 *StrokeAttrRecordHandler::GetTagList()
01751 
01752     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01753     Created:    7/1/97
01754 
01755     Returns:    A list of tag values, terminated by CXFRH_TAG_LIST_END
01756 
01757     Purpose:    Provides the record handler system with a list of records handled by this
01758                 handler - all StrokeType attributes:
01759                     Stroke (by type)
01760                     Stroke (by vector subtree definition)
01761                     Stroke (airbrush)
01762                     Variable width function (predefined)
01763                     Variable width function (recorded)
01764 
01765     SeeAlso:    StrokeTypeAttrRecordHandler::HandleRecord
01766 
01767 ********************************************************************************************/
01768 
01769 UINT32 *StrokeAttrRecordHandler::GetTagList()
01770 {
01771     static UINT32 TagList[] =
01772     {
01773         TAG_STROKEDEFINITION,
01774         TAG_STROKETYPE,
01775         TAG_STROKEAIRBRUSH,
01776 
01777         TAG_VARIABLEWIDTHFUNC,
01778         TAG_VARIABLEWIDTHTABLE,
01779 
01780         CXFRH_TAG_LIST_END
01781     };
01782 
01783     return(TagList);
01784 }
01785 
01786 
01787 
01788 /********************************************************************************************
01789 
01790 >   virtual BOOL StrokeAttrRecordHandler::HandleRecord(CXaraFileRecord *pCXaraFileRecord)
01791 
01792     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01793     Created:    7/1/97
01794 
01795     Inputs:     pCXaraFileRecord - The record to handle - may not be NULL
01796     Returns:    TRUE if handled successfuly
01797 
01798     Purpose:    Handles loading of the given StrokeType attribute record
01799 
01800     SeeAlso:    AttrStrokeType::WritePreChildrenNative;
01801                 AttrOverprintFill::WritePreChildrenNative;
01802                 AttrPrintOnAllPlates::WritePreChildrenNative
01803 
01804 ********************************************************************************************/
01805 
01806 BOOL StrokeAttrRecordHandler::HandleRecord(CXaraFileRecord *pCXaraFileRecord)
01807 {
01808     ERROR3IF(pCXaraFileRecord == NULL, "pCXaraFileRecord is NULL");
01809 
01810     NodeAttribute *pNewNode = NULL;
01811     
01812     switch (pCXaraFileRecord->GetTag())
01813     {
01814         case TAG_STROKEDEFINITION:
01815             return(StrokeComponent::StartImportStroke(this, pCXaraFileRecord));
01816 
01817 
01818         case TAG_STROKETYPE:
01819             {
01820                 UINT32 Handle = 0x01000000;
01821                 pCXaraFileRecord->ReadUINT32(&Handle);
01822 
01823                 pNewNode = new AttrStrokeType;
01824                 if (pNewNode != NULL)
01825                 {
01826                     PathProcessorStroke *pProcessor = NULL;
01827 
01828                     switch ((Handle >> 24) & 0xff)
01829                     {
01830                         case 0:
01831                             // Complex vector stroke
01832                             {
01833                                 StrokeHandle NewHandle = StrokeComponent::FindImportedStroke(Handle & 0x00ffffff);
01834                                 if (NewHandle != StrokeHandle_NoStroke)
01835                                     pProcessor = new PathProcessorStrokeVector;
01836 
01837                                 if (pProcessor != NULL)
01838                                     ((PathProcessorStrokeVector *)pProcessor)->SetStrokeDefinition(NewHandle);
01839                             }
01840                             break;
01841 
01842                         case 1:
01843                             // Simple old-style constant width line. Use pProcessor == NULL
01844                             break;
01845 
01846                         case 2:
01847                             // Simple variable-width stroke
01848                             pProcessor = new PathProcessorStroke;
01849                             break;
01850 
01851                         default:
01852                             ERROR3("Unknown/Unsupported stroke type");
01853                             break;
01854                     }
01855 
01856                     if (pProcessor != NULL)
01857                         ((StrokeTypeAttrValue *)pNewNode->GetAttributeValue())->SetPathProcessor(pProcessor);
01858                 }
01859             }
01860             break;
01861 
01862 
01863         case TAG_STROKEAIRBRUSH:
01864             {
01865                 // Airbrushes currently only hold an intensity-function, so we simply read that
01866                 // function and build an airbrush-stroke attribute around it.
01867                 ValueFunction *pValFunc = ValueFunction::ReadFileRecord(pCXaraFileRecord);
01868                 if (pValFunc != NULL)
01869                 {
01870                     pNewNode = new AttrStrokeType;
01871                     if (pNewNode != NULL)
01872                     {
01873                         PathProcessorStrokeAirbrush *pProcessor = new PathProcessorStrokeAirbrush;
01874                         if (pProcessor != NULL)
01875                         {
01876                             pProcessor->SetIntensityFunction(pValFunc);
01877                             ((StrokeTypeAttrValue *)pNewNode->GetAttributeValue())->SetPathProcessor(pProcessor);
01878                         }
01879                         else
01880                         {
01881                             delete pNewNode;
01882                             pNewNode = NULL;
01883                         }
01884                     }
01885                 }
01886 
01887                 if (pNewNode == NULL)   // We failed, so clean up
01888                     delete pValFunc;
01889             }
01890             break;
01891 
01892 
01893         case TAG_VARIABLEWIDTHFUNC:
01894             // Create a new variable-width attribute
01895             pNewNode = new AttrVariableWidth;
01896             if (pNewNode != NULL)
01897             {
01898                 // and fill in the value with the appropriate function definition
01899                 VariableWidthID Function = VarWidth_NotPredefined;
01900                 if (pCXaraFileRecord->ReadUINT32((UINT32 *)&Function))
01901                 {
01902                     if ((UINT32)Function != 0)
01903                         ((VariableWidthAttrValue *)pNewNode->GetAttributeValue())->SetWidthFunction(Function);
01904                 }
01905             }
01906             break;
01907 
01908 
01909         case TAG_VARIABLEWIDTHTABLE:
01910             {
01911                 ValueFunction *pValFunc = ValueFunction::ReadFileRecord(pCXaraFileRecord);
01912                 if (pValFunc != NULL)
01913                 {
01914                     pNewNode = new AttrVariableWidth;
01915                     if (pNewNode != NULL)
01916                         ((VariableWidthAttrValue *)pNewNode->GetAttributeValue())->SetWidthFunction(pValFunc);
01917                     else
01918                         delete pValFunc;
01919                 }
01920             }
01921             break;
01922 
01923         default:
01924             ERROR3_PF(("I don't handle records with the tag (%d)\n", pCXaraFileRecord->GetTag()));
01925             break;
01926     }
01927 
01928     ERROR3IF(pNewNode == NULL, "Failed to load stroke information");
01929 
01930     // Get the base class to insert the new node for us
01931     if (pNewNode != NULL)
01932         InsertNode(pNewNode);
01933     return(TRUE);
01934 }
01935 
01936 
01937 
01938 /********************************************************************************************
01939 
01940 >   virtual BOOL StrokeAttrRecordHandler::BeginSubtree(UINT32 Tag)
01941 
01942     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01943     Created:    4/3/97
01944 
01945     Inputs:     Tag = tag value of the tag this handler last handled
01946     Returns:    TRUE if this func wants exclusive handling of the tag
01947                 FALSE otherwise
01948     Purpose:    Informs the record handler that a subtree is following a tag of type 'Tag'
01949 
01950                 If you override this func and you do not wish other parts of the system to be informed of the
01951                 subtree start, you should return TRUE
01952 
01953 ********************************************************************************************/
01954 
01955 BOOL StrokeAttrRecordHandler::BeginSubtree(UINT32 Tag)
01956 {
01957     // We only want to know about following subtrees when doing stroke definition records.
01958     // If we are doing one, then we grab the subtree so nobody else can faff about with it
01959     if (Tag != TAG_STROKEDEFINITION)
01960         return(FALSE);
01961 
01962     return(TRUE);
01963 }
01964 
01965 
01966 
01967 /********************************************************************************************
01968 
01969 >   virtual BOOL StrokeAttrRecordHandler::EndSubtree(UINT32 Tag)
01970 
01971     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
01972     Created:    4/3/97
01973 
01974     Inputs:     Tag = tag value of the tag this handler last handled
01975     Returns:    TRUE if this func wants exclusive handling of the tag
01976                 FALSE otherwise
01977 
01978     Purpose:    Informs the record handler that a subtree that followed a tag of type 'Tag' has ended
01979 
01980                 If you override this func and you do not wish other parts of the system to be
01981                 informed of the subtree end, you should return TRUE
01982 
01983 ********************************************************************************************/
01984 
01985 BOOL StrokeAttrRecordHandler::EndSubtree(UINT32 Tag)
01986 {
01987     // We only want to know about following subtrees when doing custom print mark records.
01988     // If we are doing one, then we grab the subtree so nobody else can faff about with it
01989     if (Tag != TAG_STROKEDEFINITION)
01990         return(FALSE);
01991 
01992 #if !defined(EXCLUDE_FROM_RALPH)
01993     // OK, it is the end of a stroke definition record, so complete the import
01994     StrokeComponent::EndImportStroke(this);
01995 #endif
01996     
01997     return(TRUE);
01998 }
01999 
02000 
02001 
02002 /********************************************************************************************
02003 
02004 >   virtual void StrokeAttrRecordHandler::GetRecordDescriptionText(CXaraFileRecord* pRecord,StringBase* pStr)
02005 
02006     Author:     Jason_Williams (Xara Group Ltd) <camelotdev@xara.com>
02007     Created:    11/1/97
02008 
02009     Inputs:     pRecord = ptr to a record
02010                 pStr = ptr to string to update
02011 
02012     Returns:    -
02013     Purpose:    Provides descriptions for the stroke attribute records.
02014 
02015     Notes:      This function is only present in _DEBUG builds
02016 
02017 ********************************************************************************************/
02018 
02019 #ifdef XAR_TREE_DIALOG
02020 void StrokeAttrRecordHandler::GetRecordDescriptionText(CXaraFileRecord* pRecord, StringBase* pStr)
02021 {
02022     if (pStr == NULL || pRecord == NULL)
02023         return;
02024 
02025     // Call base class first to output the tag and size
02026     CamelotRecordHandler::GetRecordDescriptionText(pRecord, pStr);
02027 
02028     UINT32 Tag = pRecord->GetTag();
02029 //  INT32 RecordNumber = pRecord->GetRecordNumber();
02030 
02031     switch (Tag)
02032     {
02033         case TAG_STROKETYPE:
02034             *pStr += String_64(_T("New-style stroke (basic type)"));    // Only 1 stroke type so far!
02035             break;
02036 
02037         case TAG_STROKEDEFINITION:
02038             *pStr += String_64(_T("New-style stroke (Vector type)"));
02039             break;
02040 
02041         case TAG_STROKEAIRBRUSH:
02042             {
02043                 // Load the value function and see what type of object we get back!
02044                 ValueFunction *pValFunc = ValueFunction::ReadFileRecord(pRecord);
02045                 if (pValFunc != NULL)
02046                 {
02047                     String_256 Desc;
02048                     Desc._MakeMsg(_T("Airbrush stroke of class #1%s"), 
02049                                     (TCHAR *)pValFunc->GetRuntimeClass()->m_lpszClassName);
02050                     *pStr += Desc;
02051                     delete pValFunc;
02052                 }
02053                 else
02054                     *pStr += String_64(_T("Unknown Airbrush stroke type (failed to load)"));
02055             }
02056             break;
02057             break;
02058 
02059         case TAG_VARIABLEWIDTHFUNC:
02060             {
02061                 VariableWidthID Function = VarWidth_NotPredefined;
02062                 pRecord->ReadUINT32((UINT32 *)&Function);
02063                 switch(Function)
02064                 {
02065                     case VarWidth_Constant:
02066                         *pStr += String_64(_T("Constant predefined stroke width"));
02067                         break;
02068 
02069                     case VarWidth_LinRamp:
02070                         *pStr += String_64(_T("Linear-Ramp predefined stroke width"));
02071                         break;
02072 
02073                     case VarWidth_SRamp:
02074                         *pStr += String_64(_T("S-Ramp predefined stroke width"));
02075                         break;
02076 
02077                     default:
02078                         *pStr += String_64(_T("Unknown predefined stroke width type"));
02079                         break;
02080                 }
02081             }
02082             break;
02083 
02084         case TAG_VARIABLEWIDTHTABLE:
02085             {
02086                 // Load the value function and see what type of object we get back!
02087                 ValueFunction *pValFunc = ValueFunction::ReadFileRecord(pRecord);
02088                 if (pValFunc != NULL)
02089                 {
02090                     String_256 Desc;
02091                     Desc._MakeMsg(_T("VariableWidth of class #1%s"), 
02092                                     (TCHAR *)pValFunc->GetRuntimeClass()->m_lpszClassName);
02093                     *pStr += Desc;
02094                     delete pValFunc;
02095                 }
02096                 else
02097                     *pStr += String_64(_T("Unknown VariableWidth ValueFunction (failed to load)"));
02098             }
02099             break;
02100 
02101         default:
02102             ERROR3(_T("Unknown tag passed to StrokeAttrRecordHandler"));
02103             break;
02104     }
02105 }
02106 
02107 #endif      // _DEBUG

Generated on Sat Nov 10 03:47:05 2007 for Camelot by  doxygen 1.4.4