00001 // $Id: brshcomp.cpp 1732 2006-09-03 14:08:16Z 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 // Brush Component and Brush Definition headers 00100 00101 #include "camtypes.h" 00102 //#include "app.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00103 //#include "camfiltr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00104 #include "brshcomp.h" 00105 #include "linecomp.h" 00106 //#include "colormgr.h" 00107 //#include "cxfrec.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00108 //#include "cxfrech.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00109 #include "cxftags.h" 00110 //#include "fixmem.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00111 #include "layer.h" 00112 //#include "spread.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00113 #include "brushref.h" 00114 #include "freehand.h" 00115 #include "freeinfo.h" 00116 //#include "xlong.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00117 #include "ppbrush.h" 00118 #include "brshattr.h" 00119 #include "sgline.h" 00120 //#include "loadbrsh.h" 00121 #include "fileutil.h" 00122 #include "clipint.h" 00123 #include "nodebldr.h" 00124 #include "bldbrdef.h" 00125 //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00126 //#include "fillval.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00127 #include "lineattr.h" 00128 #include "brshdata.h" 00129 //#include "swfrndr.h" 00130 #include "brshname.h" 00131 //#include "resdll.h" 00132 #include "nodeshad.h" 00133 #include "nodecntr.h" 00134 #include "nodebev.h" 00135 //#include "group.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00136 //#include "opdrbrsh.h" 00137 #include "toollist.h" 00138 //#include "freeinfo.h" 00139 #include "brshbeca.h" 00140 //#include "brdlgres.h" 00141 #include "brushop.h" 00142 00143 DECLARE_SOURCE("$Revision: 1732 $"); 00144 00145 CC_IMPLEMENT_DYNAMIC(BrushDefinition, LineDefinition) 00146 CC_IMPLEMENT_DYNAMIC(BrushComponent, LineComponent) 00147 CC_IMPLEMENT_DYNAMIC(BrushComponentClass, DocComponentClass) 00148 00149 // Declare smart memory handling in Debug builds 00150 #define new CAM_DEBUG_NEW 00151 00152 BOOL BrushComponent::m_bCancelNewBrush = FALSE; 00153 String_32 BrushComponent::m_NewName = TEXT("Unnamed brush"); 00154 00155 00156 const INT32 MAX_TRANSP_VALUE = 255; 00157 /******************************************************************************************** 00158 00159 > BrushDefinition::BrushDefinition(Node *pBrushTree); 00160 00161 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00162 Created: 27/2/97 00163 00164 Inputs: pBrushTree - A pointer to a Spread node which is the root of a clipart 00165 subtree which should be used for this Brush definition. It 00166 must obey these rules: 00167 * It must be a Spread 00168 * It must not be linked into any other parent tree structure 00169 * It should contain at least one ink node (or else the Brush 00170 will appear "blank"). 00171 * It should be attribute complete, or close thereto 00172 00173 Purpose: Constructor 00174 00175 SeeAlso: BrushComponent::AddNewBrush 00176 00177 ********************************************************************************************/ 00178 00179 BrushDefinition::BrushDefinition(Node* pBrushTree) 00180 : LineDefinition(pBrushTree) 00181 { 00182 ResetMembers(); 00183 InitialiseBrushArray(MAX_BRUSH_OBJECTS); 00184 if (!GenerateBrush()) 00185 { 00186 // hmm, not sure what to do here, but you can detect if we failed to initialise 00187 // by calling IsActivated, if that fails you should delete me. 00188 } 00189 00190 } 00191 00192 00193 /******************************************************************************************** 00194 00195 > BrushDefinition::BrushDefinition() 00196 00197 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00198 Created: 27/2/97 00199 00200 Purpose: Default constructor for the purposes of inherited classes, if you just want a 00201 normal brushdef you should really use the constructor above. 00202 00203 5/12/2000 Actually I've just read that it is a poor idea to initialise inside 00204 constructors, so I think that a reorganisation should occur whereby the construcotr 00205 should simply assign the brush tree and we should GenerateBrush after the constructor 00206 returns. 00207 00208 ********************************************************************************************/ 00209 00210 BrushDefinition::BrushDefinition() 00211 { 00212 ResetMembers(); 00213 } 00214 00215 00216 /******************************************************************************************** 00217 00218 > BrushDefinition::~BrushDefinition() 00219 00220 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00221 Created: 27/2/97 00222 00223 Purpose: Destructor 00224 00225 ********************************************************************************************/ 00226 00227 BrushDefinition::~BrushDefinition() 00228 { 00229 for( size_t i = 0; i < m_BrushRefPtrArray.size(); i++ ) 00230 { 00231 // ask the brushref to delete the attribute maps it generated 00232 if (m_BrushRefPtrArray[i] != NULL) 00233 { 00234 // m_BrushRefPtrArray[i]->DeleteAttributeMapsAndAttributes(); 00235 delete m_BrushRefPtrArray[i]; 00236 } 00237 } 00238 m_BrushRefPtrArray.clear(); 00239 00240 00241 00242 } 00243 00244 00245 00246 /*********************************************************************************************** 00247 00248 > void BrushDefinition::ResetMembers() 00249 00250 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00251 Created: 6/10/99 00252 Inputs: - 00253 Returns - 00254 Purpose: Initialises the member variables 00255 00256 ***********************************************************************************************/ 00257 00258 void BrushDefinition::ResetMembers() 00259 { 00260 m_BrushSpacing = 10000; 00261 m_BrushSpacingIncrProp = 1.0; 00262 m_BrushSpacingIncrConst = 0; 00263 m_BrushSpacingMaxRand = 0; 00264 m_BrushSpacingRandSeed = 0; 00265 00266 m_PathOffsetType = OFFSET_NONE; 00267 m_PathOffsetValue = 0; 00268 m_PathOffsetIncrProp = 1.0; 00269 m_PathOffsetIncrConst = 0; 00270 m_OffsetTypeRandSeed = 0; 00271 m_OffsetValueMaxRand = 0; 00272 m_OffsetValueRandSeed = 0; 00273 00274 m_bRotate = TRUE; 00275 m_RotateAngle = 0; 00276 m_RotationMaxRand = 0; 00277 m_RotationRandSeed = 0; 00278 m_RotAngleIncrConst = 0; 00279 m_RotAngleIncrProp = 1.0; 00280 m_RotationMaxPressure = 0; 00281 00282 m_bTile = TRUE; 00283 00284 m_BrushScaling = 1.0; 00285 m_BrushScalingIncr = 1.0; 00286 m_BrushScalingIncrConst = 0.0; 00287 m_BrushScalingMaxRand = 0; 00288 m_BrushScalingRandSeed = 0; 00289 m_ScalingMaxPressure = 35; 00290 00291 m_BrushHueIncrement = 0.0; 00292 m_BrushHueMaxRand = 0; 00293 m_BrushHueRandSeed = 1234; 00294 00295 m_BrushSatIncrement = 0.0; 00296 m_BrushSatMaxRand = 0; 00297 m_BrushSatRandSeed = 5432; 00298 00299 m_SequenceType = SEQ_FORWARD; 00300 m_SequenceRandSeed = 0; 00301 00302 m_NumBrushObjects = 0; 00303 m_bInitOk = FALSE; 00304 00305 m_LargestBoundingBox.MakeEmpty(); 00306 00307 m_Name = TEXT("Custom Brush"); 00308 00309 m_TimeStampPeriod = 0; 00310 00311 m_BrushTransparency = 100; 00312 m_TranspMaxPressure = 0; 00313 00314 m_DefaultFileID = BRUSHFILE_NONE; 00315 00316 m_bActivated = FALSE; 00317 } 00318 00319 00320 00321 /*********************************************************************************************** 00322 00323 > BOOL BrushDefinition::GenerateBrush() 00324 00325 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00326 Created: 13/12/99 00327 Inputs: - 00328 Returns TRUE if successful, FALSE otherwise 00329 Purpose: goes through the input spread and calls AddNewObject() for each ink object found 00330 We try to make some intelligent guesses about what to set the starting spacing and 00331 offset values depending on the nature of the nodes. The following rules apply: 00332 - if there are multiple ink objects then the spacing is 1.1 * the largest dimension 00333 of the largest bounding box 00334 - if there is only one object and it contains a positive line width spacing is as above 00335 - if there is only one object with no line width then spacing is 10000 millipoint 00336 - defaulf offset is always the largest dimension of the largest BBOX. 00337 00338 ***********************************************************************************************/ 00339 00340 BOOL BrushDefinition::GenerateBrush() 00341 { 00342 if (m_pTree == NULL) 00343 return FALSE; 00344 00345 // get a node that points at the first child of the layer 00346 Node* pNode = m_pTree->FindFirstChild(); 00347 pNode = pNode->FindFirstChild(); 00348 00349 00350 AttrLineWidth* pLineWidth = NULL; 00351 while (pNode != NULL) 00352 { 00353 if (pNode->IsAnObject()) 00354 { 00355 // it has been drawn to my attention that it is possible to end up with a brush object 00356 // that has no line width attribute, which leads to all kinds of problems. So here we will 00357 // search for one and if we don't find one we will add one. 00358 ((NodeRenderableInk*)pNode)->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrLineWidth), (NodeAttribute**)&pLineWidth); 00359 if (!pLineWidth) 00360 { 00361 pLineWidth = new AttrLineWidth(pNode, LASTCHILD); 00362 if (pLineWidth) 00363 { 00364 pLineWidth->Value.LineWidth = 501; 00365 pLineWidth = NULL; 00366 } 00367 } 00368 00369 // we don't want to make brushes from brushes, instead we want to convert them 00370 // to shapes first, so use the routine to do that. 00371 NodeGroup* pGroup = NULL; 00372 ReplaceBrushWithGroup((NodeRenderableInk*)pNode, &pGroup); 00373 if (pGroup != NULL) 00374 { 00375 // we got a group, so we have to delete the original node 00376 pGroup->AttachNode(pNode, NEXT); 00377 pGroup->FactorOutCommonChildAttributes(); 00378 // unhook from the tree 00379 pNode->CascadeDelete(); 00380 00381 // swap the pointers 00382 Node* pDelete = pNode; 00383 pNode = pGroup; 00384 00385 delete pDelete; 00386 } 00387 00388 if (!AddNewObject((NodeRenderableInk*)pNode)) 00389 return FALSE; 00390 } 00391 pNode = pNode->FindNext(); 00392 } 00393 CalculateMaxScaling(); 00394 00395 m_bActivated = TRUE; 00396 return TRUE; 00397 00398 } 00399 00400 00401 /*********************************************************************************************** 00402 00403 > BOOL BrushDefinition::ReplaceBrushWithGroup(NodeRenderableInk* pInk, NodeGroup* pGroup) 00404 00405 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00406 Created: 13/12/99 00407 Inputs: pInk - the inknode that we are going to generate a brush from 00408 Outputs: if pInk has a brush attribute applied to it then we will generate a new group 00409 from that brush 00410 Returns TRUE if successful, FALSE otherwise 00411 Purpose: We are no longer allowed to make brushes from brushes, because of problems 00412 when saving and loading. Instead if we have a brush then we will convert 00413 it to shapes and use those instead. 00414 00415 Note: So you actually have to delete pInk yourself if this function outputs a group. 00416 I had to do that to get the recursion to work. Still I'm sure you can handle it. 00417 ***********************************************************************************************/ 00418 00419 BOOL BrushDefinition::ReplaceBrushWithGroup(NodeRenderableInk* pInk, NodeGroup** ppGroup) 00420 { 00421 ERROR2IF(pInk == NULL, FALSE, "Invalid inputs to BrushDefinition::ReplaceBrushWithGroups"); 00422 00423 BOOL ok = TRUE; 00424 // if we're compound then search through all our children first 00425 if (pInk->IsCompound()) 00426 { 00427 NodeGroup* pNodeGroup = NULL; 00428 Node* pChild = pInk->FindFirstChild(); 00429 Node* pDelete = NULL; 00430 00431 while (pChild) 00432 { 00433 if (pChild->IsAnObject()) 00434 { 00435 if (ok) ok = ReplaceBrushWithGroup((NodeRenderableInk*)pChild, &pNodeGroup); 00436 if (pNodeGroup) 00437 { 00438 // attach the new group next to the child 00439 pNodeGroup->AttachNode(pChild, NEXT); 00440 00441 pNodeGroup->FactorOutCommonChildAttributes(); 00442 00443 // unhook the child 00444 pChild->CascadeDelete(); 00445 00446 // we're ready to delete the original child 00447 pDelete = pChild; 00448 00449 // swap the pointer 00450 pChild = pNodeGroup; 00451 00452 delete pDelete; 00453 } 00454 } 00455 pChild = pChild->FindNext(); 00456 pNodeGroup = NULL; 00457 } 00458 } 00459 00460 AttrBrushType* pAttrBrush = NULL; 00461 pInk->FindAppliedAttribute(CC_RUNTIME_CLASS(AttrBrushType), (NodeAttribute**)&pAttrBrush); 00462 00463 if (pAttrBrush && pAttrBrush->GetBrushHandle() != BrushHandle_NoBrush && ok) 00464 { 00465 //Turn the brush into a group with lots of nodepaths 00466 BrushBecomeAGroup BecomeA(BECOMEA_PASSBACK, CC_RUNTIME_CLASS(NodePath), NULL); 00467 ok = pAttrBrush->DoBecomeA(&BecomeA, pInk); 00468 00469 // the brush will create a group out of itself and we want to retrieve that 00470 NodeGroup* pBrushGroup = BecomeA.GetNodeGroup(); 00471 pBrushGroup->FactorOutCommonChildAttributes(); 00472 pBrushGroup->NormaliseAttributes(); 00473 if (pBrushGroup != NULL && ok) 00474 { 00475 *ppGroup = pBrushGroup; 00476 } 00477 } 00478 return ok; 00479 } 00480 00481 /*********************************************************************************************** 00482 00483 > BOOL BrushDefinition::RegenerateBrush() 00484 00485 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00486 Created: 13/12/99 00487 Inputs: - 00488 Returns TRUE if successful, FALSE otherwise 00489 Purpose: This function deletes the existing brushrefs and recreates them from scratch from 00490 m_pTree. 00491 00492 Notes: This function is necessary because of the inaccuracies in our matrix transformation 00493 system which make it impossible to repeatedly scale without either growing our objects. 00494 Therefore it is recommended that after every render where an object is scaled this function 00495 should be called to regenerate the brush. 00496 Obviously the potential for disaster is very high for instance we run out of memory 00497 in the middle of the operation. 00498 00499 ***********************************************************************************************/ 00500 00501 BOOL BrushDefinition::RegenerateBrush() 00502 { 00503 /* As we now always take copies of the brush objects, this is scheduled for demolition... 00504 00505 // first we need to transform all the attributes back to where they began 00506 PreExportSubTree(); 00507 00508 // make a temporary array to hold the existing elements, as we do not wish 00509 // to delete them until we are sure regeneration went ok 00510 CTypedPtrArray <CPtrArray, BrushRef*> TempArray; 00511 00512 TempArray.SetSize(MAX_BRUSH_OBJECTS, -1); 00513 00514 // fill the array with our existing objects 00515 BrushRef* pRef = NULL; 00516 INT32 i = 0; 00517 for (i = 0; i < TempArray.GetSize(); i++) 00518 { 00519 pRef = m_BrushRefPtrArray[i]; 00520 TempArray.SetAt(i, pRef); 00521 m_BrushRefPtrArray.SetAt(i, NULL); // set existing pointer to null 00522 } 00523 00524 m_NumBrushObjects = 0; 00525 00526 // now remake ourselves 00527 if (GenerateBrush() == TRUE) 00528 { 00529 // delete the existing brushrefs 00530 for (i = 0; i < TempArray.GetSize(); i++) 00531 { 00532 if (TempArray[i] != NULL) 00533 { 00534 delete TempArray[i]; 00535 } 00536 } 00537 TempArray.RemoveAll(); 00538 00539 return TRUE; 00540 } 00541 00542 // ok so something went wrong, not much we can do except for restore the original objects 00543 // and hope for the best 00544 ERROR3("Uh oh - Regenerate Brush failed"); 00545 pRef = NULL; 00546 i= 0; 00547 for (i = 0; i < TempArray.GetSize(); i++) 00548 { 00549 pRef = TempArray[i]; 00550 m_BrushRefPtrArray.SetAt(i, pRef); // set existing pointer to null 00551 TempArray[i] = NULL; 00552 } 00553 */ 00554 return TRUE; 00555 } 00556 00557 00558 00559 /*********************************************************************************************** 00560 00561 > BOOL BrushDefinition::IsActivated() 00562 00563 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00564 Created: 13/12/99 00565 Inputs: - 00566 Returns the member indicating whether this definition is active 00567 Purpose: To see if this definition was initialised ok or if it was subsequently deactivated 00568 for some reason 00569 00570 ***********************************************************************************************/ 00571 00572 BOOL BrushDefinition::IsActivated() 00573 { 00574 return m_bActivated; 00575 } 00576 00577 00578 /*********************************************************************************************** 00579 00580 > void BrushDefinition::SetActivated(BOOL Value) 00581 00582 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00583 Created: 13/12/99 00584 Inputs: Value - the value to set 00585 Returns - 00586 Purpose: To set this definition activated or not 00587 00588 ***********************************************************************************************/ 00589 00590 void BrushDefinition::SetActivated(BOOL Value) 00591 { 00592 m_bActivated = Value; 00593 } 00594 00595 /*********************************************************************************************** 00596 00597 > BOOL BrushDefinition::AddNewObject(NodeRenderableInk* pInkNode) 00598 00599 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00600 Created: 13/12/99 00601 Inputs: pInkNode - node to add 00602 Returns TRUE if successful, FALSE otherwise 00603 Purpose: creates a brushref object from the inknode and its attributes, then adds the 00604 brushref to the member array 00605 00606 ***********************************************************************************************/ 00607 00608 BOOL BrushDefinition::AddNewObject(NodeRenderableInk* pInkNode) 00609 { 00610 00611 if (pInkNode == NULL) 00612 { 00613 ERROR3("Ink node is NULL"); 00614 return FALSE; 00615 } 00616 00617 if (m_NumBrushObjects >= MAX_BRUSH_OBJECTS) 00618 { 00619 ERROR3("Cannot exceed MAX_BRUSH_OBJECTS"); 00620 return FALSE; 00621 } 00622 00623 BrushRef *pNewBrushRef = new BrushRef; 00624 00625 if (pNewBrushRef == NULL) 00626 { 00627 ERROR3("Failed to allocate brushref"); 00628 return FALSE; 00629 } 00630 00631 00632 00633 if (!pNewBrushRef->Initialise(pInkNode)) 00634 { 00635 ERROR3("Failed to initialise brushref"); 00636 return FALSE; 00637 } 00638 00639 m_BrushRefPtrArray[m_NumBrushObjects++] = pNewBrushRef; 00640 00641 return TRUE; 00642 00643 } 00644 00645 00646 /*********************************************************************************************** 00647 00648 > void BrushDefinition::InitialiseBrushArray(UINT32 NumObjects) 00649 00650 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00651 Created: 6/10/99 00652 Inputs: Number of objects to size the array at 00653 Returns: - 00654 Purpose: Clears out the m_BrushRefPtrArray if it is not empty, and sets the size 00655 00656 ***********************************************************************************************/ 00657 00658 void BrushDefinition::InitialiseBrushArray(UINT32 NumObjects) 00659 { 00660 size_t i = 0; 00661 while( i < m_BrushRefPtrArray.size() ) 00662 { 00663 delete m_BrushRefPtrArray[i++]; 00664 } 00665 m_BrushRefPtrArray.clear(); 00666 00667 m_BrushRefPtrArray.resize( NumObjects ); 00668 00669 // fill the array with NULL objects so that we can check later 00670 // to see if our allocations have worked 00671 i = 0; 00672 while( i < m_BrushRefPtrArray.size() ) 00673 { 00674 m_BrushRefPtrArray[i++] = NULL; 00675 } 00676 00677 } 00678 00679 00680 /******************************************************************************************** 00681 00682 > BOOL BrushDefinition::IsDifferent(BrushDefinition *pOther) 00683 00684 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00685 Created: 13/12/99 00686 00687 Inputs: pOther - the Brush to compare this Brush to 00688 00689 Returns: TRUE if they're different in any way, 00690 FALSE if they are identical definitions 00691 00692 Purpose: Determine if 2 BrushDefinitions are considered different. 00693 Used when adding Brushes to the global list, so that like Brushes 00694 can be merged. 00695 00696 ********************************************************************************************/ 00697 00698 BOOL BrushDefinition::IsDifferent(LineDefinition *pOther) 00699 { 00700 ERROR3IF(pOther == NULL, "Illegal NULL param"); 00701 00702 // String_32* pName = pOther->GetLineName(); 00703 if (!m_Name.IsIdentical(*pOther->GetLineName())) 00704 return(TRUE); 00705 00706 if (pOther->GetLineTree() == NULL || m_pTree == NULL) 00707 { 00708 ERROR3("BrushDefinition has not been properly initialised"); 00709 return(TRUE); 00710 } 00711 00712 /* 00713 // --- Check to see if the brush bounds are equal 00714 DocRect OtherBounds = ((Spread *)(pOther->GetLineTree()))->GetBoundingRect(); 00715 DocRect Bounds = ((Spread *)m_pTree)->GetBoundingRect(); 00716 if (Bounds != OtherBounds) 00717 return(TRUE); 00718 */ 00719 // --- Check the subtrees node-for-node to see if they are the same 00720 Node *pCurNode1 = m_pTree->FindFirstDepthFirst(); 00721 Node *pCurNode2 = pOther->GetLineTree()->FindFirstDepthFirst(); 00722 00723 while (pCurNode1 != NULL && pCurNode2 != NULL) 00724 { 00725 // if they are fill attributes then we want to translate both attributes to the origin. 00726 // This prevents us getting duplication of brushes when we have the 00727 // same thing in a different place, note that occasionally this fails due to rounding errors. 00728 if (pCurNode1->IsAFillAttr() && pCurNode2->IsAFillAttr() && 00729 !((AttrFillGeometry*)pCurNode1)->IsAStrokeColour() && 00730 !((AttrFillGeometry*)pCurNode1)->IsAStrokeTransp()) 00731 { 00732 AttrFillGeometry* pFill1 = (AttrFillGeometry*)pCurNode1; 00733 AttrFillGeometry* pFill2 = (AttrFillGeometry*)pCurNode2; 00734 DocCoord* pStartPoint1 = pFill1->GetStartPoint(); 00735 DocCoord* pStartPoint2 = pFill2->GetStartPoint(); 00736 00737 // translate them both to 0,0 00738 if (pStartPoint1 && pStartPoint2) 00739 { 00740 Trans2DMatrix Trans1(-pStartPoint1->x, -pStartPoint1->y); 00741 Trans2DMatrix Trans2(-pStartPoint2->x, -pStartPoint2->y); 00742 pFill1->Transform(Trans1); 00743 pFill2->Transform(Trans2); 00744 BOOL Different = FALSE; 00745 if (pCurNode1->IsDifferent(pCurNode2)) 00746 Different = TRUE; 00747 00748 Trans1.Invert(); 00749 Trans2.Invert(); 00750 pFill1->Transform(Trans1); 00751 pFill2->Transform(Trans2); 00752 if (Different == TRUE) 00753 return TRUE; 00754 } 00755 00756 } 00757 else 00758 // likewise if they are an object then translate from the centre of the bounding 00759 // rect to the origin 00760 if (pCurNode1->IsAnObject() && pCurNode2->IsAnObject()) 00761 { 00762 NodeRenderableInk* pInk1 = (NodeRenderableInk*)pCurNode1; 00763 NodeRenderableInk* pInk2 = (NodeRenderableInk*)pCurNode2; 00764 DocRect BRect1 = ((NodeRenderableInk*)pCurNode1)->GetBoundingRect(); 00765 DocRect BRect2 = ((NodeRenderableInk*)pCurNode2)->GetBoundingRect(); 00766 DocCoord Coord1 = BRect1.Centre(); 00767 DocCoord Coord2 = BRect2.Centre(); 00768 Trans2DMatrix Trans1(-Coord1.x, -Coord1.y); 00769 Trans2DMatrix Trans2(-Coord2.x, -Coord2.y); 00770 pInk1->Transform(Trans1); 00771 pInk2->Transform(Trans2); 00772 BOOL Different = FALSE; 00773 if (pCurNode1->IsDifferent(pCurNode2)) 00774 Different = TRUE; 00775 00776 Trans1.Invert(); 00777 Trans2.Invert(); 00778 pInk1->Transform(Trans1); 00779 pInk2->Transform(Trans2); 00780 if (Different ==TRUE) 00781 return TRUE; 00782 } 00783 else 00784 { 00785 // otherwise just use the regular == operator 00786 if (pCurNode1->IsDifferent(pCurNode2)) 00787 return(TRUE); 00788 } 00789 00790 // And go to the next node in both brushes 00791 pCurNode1 = pCurNode1->FindNextDepthFirst(m_pTree); 00792 pCurNode2 = pCurNode2->FindNextDepthFirst(pOther->GetLineTree()); 00793 } 00794 00795 if (!AreBrushParametersIdentical((BrushDefinition*)pOther)) 00796 return TRUE; 00797 00798 // If we did the entire search and both pointers ended up NULL simultaneously, then 00799 // we have an exact match 00800 if (pCurNode1 == NULL && pCurNode2 == NULL) 00801 return(FALSE); 00802 00803 return(TRUE); 00804 } 00805 00806 00807 /******************************************************************************************** 00808 00809 > BOOL BrushDefinition::IsDifferent(BrushDefinition *pOther) 00810 00811 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00812 Created: 13/12/99 00813 00814 Inputs: pOther - the Brush to compare this Brush to 00815 00816 Returns: TRUE if they're different 00817 FALSE if they are identical 00818 00819 Purpose: Compares the member variables of the two brushes 00820 00821 ********************************************************************************************/ 00822 00823 BOOL BrushDefinition::AreBrushParametersIdentical(BrushDefinition* pOther) 00824 { 00825 if (m_BrushSpacing != pOther->m_BrushSpacing || 00826 m_BrushSpacingIncrProp != pOther->m_BrushSpacingIncrProp || 00827 m_BrushSpacingIncrConst != pOther->m_BrushSpacingIncrConst || 00828 m_BrushSpacingMaxRand != pOther->m_BrushSpacingMaxRand || 00829 m_BrushSpacingRandSeed != pOther->m_BrushSpacingRandSeed || 00830 m_SpacingMaxPressure != pOther->m_SpacingMaxPressure || 00831 00832 m_bTile != pOther->m_bTile || 00833 m_bRotate != pOther->m_bRotate || 00834 00835 m_RotateAngle != pOther->m_RotateAngle || 00836 m_RotAngleIncrProp != pOther->m_RotAngleIncrProp || 00837 m_RotAngleIncrConst != pOther->m_RotAngleIncrConst || 00838 m_RotationMaxRand != pOther->m_RotationMaxRand || 00839 m_RotationRandSeed != pOther->m_RotationRandSeed || 00840 m_RotationMaxPressure != pOther->m_RotationMaxPressure || 00841 00842 m_PathOffsetType != pOther->m_PathOffsetType || 00843 m_PathOffsetValue != pOther->m_PathOffsetValue || 00844 m_PathOffsetIncrProp != pOther->m_PathOffsetIncrProp || 00845 m_PathOffsetIncrConst != pOther->m_PathOffsetIncrConst || 00846 m_OffsetTypeRandSeed != pOther->m_OffsetTypeRandSeed || 00847 m_OffsetValueMaxRand != pOther->m_OffsetValueMaxRand || 00848 m_OffsetValueRandSeed != pOther->m_OffsetValueRandSeed || 00849 00850 m_BrushScaling != pOther->m_BrushScaling || 00851 m_BrushScalingIncr != pOther->m_BrushScalingIncr || 00852 m_BrushScalingIncrConst != pOther->m_BrushScalingIncrConst || 00853 m_BrushScalingMaxRand != pOther->m_BrushScalingMaxRand || 00854 m_BrushScalingRandSeed != pOther->m_BrushScalingRandSeed || 00855 m_ScalingMaxPressure != pOther->m_ScalingMaxPressure || 00856 00857 m_BrushHueIncrement != pOther->m_BrushHueIncrement || 00858 m_BrushHueMaxRand != pOther->m_BrushHueMaxRand || 00859 m_BrushHueRandSeed != pOther->m_BrushHueRandSeed || 00860 m_HueMaxPressure != pOther->m_HueMaxPressure || 00861 00862 m_BrushSatIncrement != pOther->m_BrushSatIncrement || 00863 m_BrushSatMaxRand != pOther->m_BrushSatMaxRand || 00864 m_BrushSatRandSeed != pOther->m_BrushSatRandSeed || 00865 m_SatMaxPressure != pOther->m_SatMaxPressure || 00866 00867 m_SequenceType != pOther->m_SequenceType || 00868 m_SequenceRandSeed != pOther->m_SequenceRandSeed || 00869 00870 m_TimeStampPeriod != pOther->m_TimeStampPeriod) 00871 return FALSE; 00872 else 00873 return TRUE; 00874 } 00875 00876 00877 /******************************************************************************************** 00878 00879 > BrushDefinition* BrushDefinition::Copy() 00880 00881 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00882 Created: 22/5/2000 00883 00884 Inputs: - 00885 00886 Returns: Pointer to new brush definition if succesful, NULL if it fails 00887 Purpose: Makes a copy of this definition, inknodes and all. 00888 00889 ********************************************************************************************/ 00890 00891 BrushDefinition* BrushDefinition::Copy() 00892 { 00893 // we need to make a range in order to copy the nodes to the new brush definition 00894 // so we need the start and end nodes of the range 00895 Node* pStart = NULL; 00896 Node* pNext = NULL; 00897 Node* pLast = NULL; 00898 00899 // don't forget we start on a spread 00900 Node* pTree = GetLineTree(); 00901 if (pTree != NULL) 00902 pTree = pTree->FindFirstChild(); // get the layer 00903 if (pTree != NULL) 00904 pTree = pTree->FindFirstChild(); // get the first ink object 00905 00906 if (pTree == NULL) 00907 { 00908 ERROR3("Tree node is NULL in BrushDefinition::Copy()"); 00909 return NULL; 00910 } 00911 00912 pNext = pStart = pTree; 00913 while (pNext != NULL) 00914 { 00915 pNext->SetSelected(FALSE); // we need to do this so that Range::FindFirst doesn't return NULL 00916 pLast = pNext; 00917 pNext = pLast->FindNext(); 00918 } 00919 00920 00921 // make a range out of our subtree as thats the easiest way to copy all the nodes 00922 RangeControl rc; 00923 rc.Unselected = TRUE; 00924 rc.Selected = FALSE; 00925 Range BrushRange(pStart, pLast, rc); 00926 00927 // make a new spread to attach our copy tree to 00928 Spread* pSpread = new Spread; 00929 if (pSpread == NULL) 00930 { 00931 ERROR3("Failed to allocate spread in BrushDefinition::Copy"); 00932 return NULL; 00933 } 00934 00935 Layer *pLayer = new Layer( pSpread, FIRSTCHILD, String_256( TEXT("Diccon did this") ) ); 00936 if (pLayer == NULL) 00937 { 00938 ERROR3("Failed to allocate layer in BrushDefinition::Copy"); 00939 delete pSpread; 00940 return NULL; 00941 } 00942 00943 // we need to reset our attributes in the same way that we need to with exporting. 00944 // If we don't do this then attributes with control points end up vanishing 00945 PreExportSubTree(); 00946 00947 if (!pLayer->CopyComplexRange(BrushRange)) 00948 { 00949 ERROR3("Failed to copy range in BrushDefinition::Copy"); 00950 delete pSpread; 00951 delete pLayer; 00952 return NULL; 00953 } 00954 00955 PostExportSubTree(); 00956 00957 // lets allocate ourselves a new empty definition 00958 BrushDefinition* pNewBrushDef = new BrushDefinition(pSpread); 00959 00960 if (pNewBrushDef == NULL) 00961 { 00962 ERROR3("Failed to allocate brush definition in BrushDefinition* BrushDefinition::Copy"); 00963 delete pSpread; 00964 delete pLayer; 00965 return NULL; 00966 } 00967 00968 if (!pNewBrushDef->IsActivated()) 00969 { 00970 ERROR3("Brush definition failed to initialise"); 00971 delete pNewBrushDef; 00972 delete pSpread; 00973 delete pLayer; 00974 return NULL; 00975 } 00976 00977 return pNewBrushDef; 00978 } 00979 00980 /*********************************************************************************************** 00981 00982 > BOOL BrushDefinition::UsesPressure() 00983 00984 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 00985 Created: 16/6/2000 00986 Inputs: - 00987 Returns TRUE if this brush has one of its pressure variables set 00988 Purpose: as above 00989 ***********************************************************************************************/ 00990 00991 BOOL BrushDefinition::UsesPressure() 00992 { 00993 if (m_ScalingMaxPressure != 0 || 00994 m_RotationMaxPressure != 0 || 00995 m_TranspMaxPressure != 0) 00996 return TRUE; 00997 00998 return FALSE; 00999 } 01000 01001 01002 /*********************************************************************************************** 01003 01004 > static BOOL BrushDefinition::ObjectCanCreateBrush(NodeRenderableInk* pObject) 01005 01006 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01007 Created: 16/6/2000 01008 Inputs: pObject - the object to test 01009 Returns TRUE if we are allowed to make a brush out of this object, FALSE otherwise 01010 Purpose: To determine if this ink node can be made into a brush, currently returns TRUE for 01011 except for bevels, shadows, and contours, which are too damn awkward. 01012 ***********************************************************************************************/ 01013 01014 BOOL BrushDefinition::ObjectCanCreateBrush(NodeRenderableInk* pObject) 01015 { 01016 ERROR2IF(pObject == NULL, FALSE, "Object is NULL in BrushDefinition::ObjectCanCreateBrush"); 01017 01018 // only way to do it is some ugly IKO's 01019 if (pObject->IS_KIND_OF(NodeShadow)) 01020 return FALSE; 01021 if (pObject->IS_KIND_OF(NodeContour)) 01022 return FALSE; 01023 if (pObject->IS_KIND_OF(NodeBevel)) 01024 return FALSE; 01025 01026 // if its compound then check all the children 01027 if (pObject->IsCompound()) 01028 { 01029 Node* pChild = pObject->FindFirstChild(); 01030 while (pChild) 01031 { 01032 if (pChild->IsAnObject()) 01033 { 01034 if (!ObjectCanCreateBrush((NodeRenderableInk*)pChild)) 01035 return FALSE; 01036 } 01037 pChild = pChild->FindNext(); 01038 } 01039 } 01040 01041 return TRUE; 01042 01043 } 01044 01045 01046 /********************************************************************************************* 01047 01048 > BOOL BrushDefinition::StartRender() 01049 01050 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01051 Created: 4/9/2000 01052 Inputs: - 01053 Outputs: - 01054 Returns: TRUE if successful, FALSE if not. If we return FALSE then don't even think 01055 about rendering with this brush. 01056 01057 Purpose: Basically due to imprecision in the arithmetic system we ended up corrupting the 01058 brush data if we used it too much. So to get around this we never transform 01059 the original brush data, instead we make copies of it each time we want to render 01060 a version of this brush. 01061 This function generates the data copies that we need to render this brush, make 01062 sure you call StopRender() to get rid of them. 01063 **********************************************************************************************/ 01064 01065 BOOL BrushDefinition::StartRender() 01066 { 01067 BrushRef* pBrushRef = GetFirstBrushRef(); 01068 BOOL ok = TRUE; 01069 while (pBrushRef != NULL) 01070 { 01071 if (ok) 01072 ok = pBrushRef->MakeCopiesForRendering(); 01073 pBrushRef = GetNextBrushRef(); 01074 } 01075 01076 return ok; 01077 01078 } 01079 01080 01081 01082 /********************************************************************************************* 01083 01084 > void BrushDefinition::StopRender() 01085 01086 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01087 Created: 4/9/2000 01088 Inputs: - 01089 Outputs: - 01090 Returns: - 01091 01092 Purpose: Call this when you have finished rendering a node with this brush, it deletes 01093 the copied data that we used for rendering 01094 **********************************************************************************************/ 01095 01096 void BrushDefinition::StopRender() 01097 { 01098 BrushRef* pBrushRef = GetFirstBrushRef(); 01099 while (pBrushRef != NULL) 01100 { 01101 pBrushRef->DeleteRenderCopies(); 01102 pBrushRef = GetNextBrushRef(); 01103 } 01104 01105 return; 01106 01107 } 01108 01109 /*********************************************************************************************** 01110 01111 > void BrushDefinition::CalculateMaxScaling() 01112 01113 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01114 Created: 13/12/99 01115 Inputs: - 01116 Returns - 01117 Purpose: Calculates the maximum scaling value possible by dividing the maximum size value by 01118 the longest side of the bounding rect of the largest object 01119 ***********************************************************************************************/ 01120 01121 void BrushDefinition::CalculateMaxScaling() 01122 { 01123 DocRect BRect = GetLargestBoundingBox(); 01124 if (BRect.IsEmpty()) 01125 { 01126 //ERROR3("Bounding rect is empty in BrushDefinition::CalculateMaxScaling"); 01127 return; 01128 } 01129 MILLIPOINT LongestSide = BRect.Height() > BRect.Width() ? BRect.Height() : BRect.Width(); 01130 m_MaxScaling = MAX_BRUSH_SIZE / LongestSide; 01131 01132 } 01133 01134 01135 /*********************************************************************************************** 01136 01137 > double BrushDefinition::GetMaxScaling() 01138 01139 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01140 Created: 13/12/99 01141 Inputs: - 01142 Returns the maximum scaling value 01143 Purpose: as above 01144 ***********************************************************************************************/ 01145 01146 double BrushDefinition::GetMaxScaling() 01147 { 01148 return m_MaxScaling; 01149 } 01150 01151 /******************************************************************************************** 01152 01153 > BOOL BrushDefinition::SetBrushSpacing(double Spacing) 01154 01155 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01156 Created: 6/10/99 01157 Inputs: the spacing value to set 01158 Returns: TRUE if successful, FALSE if the spacing is invalid 01159 Purpose: To set the spacing between brush objects 01160 SeeAlso: - 01161 01162 ********************************************************************************************/ 01163 01164 BOOL BrushDefinition::SetSpacing(MILLIPOINT Spacing) 01165 { 01166 if (Spacing < MIN_BRUSH_SPACING || Spacing > MAX_BRUSH_SPACING) 01167 return FALSE; 01168 01169 m_BrushSpacing = Spacing; 01170 01171 return TRUE; 01172 01173 } 01174 01175 01176 01177 /******************************************************************************************** 01178 01179 > MILLIPOINT BrushDefinition::GetBrushSpacing() 01180 01181 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01182 Created: 6/10/99 01183 Returns: the spacing between the brush objects 01184 Purpose: As above 01185 01186 ********************************************************************************************/ 01187 01188 MILLIPOINT BrushDefinition::GetSpacing() 01189 { 01190 return m_BrushSpacing; 01191 } 01192 01193 01194 01195 /******************************************************************************************** 01196 01197 > BOOL PathProcessorBrush::SetSpacingIncrProp(double Incr) 01198 01199 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01200 Created: 6/10/99 01201 Inputs: the spacing increment value to set 01202 Returns: TRUE if we can draw 10 objects, FALSE if the spacing is invalid 01203 Purpose: To set the proportional spacing increment between brush objects 01204 SeeAlso: - 01205 01206 ********************************************************************************************/ 01207 01208 BOOL BrushDefinition::SetSpacingIncrProp(double Incr) 01209 { 01210 if (Incr <= 0) 01211 return FALSE; 01212 01213 if (Incr != 1.0) 01214 { 01215 double TenIncr = pow(Incr, 10.0); 01216 double TenthSpacing = m_BrushSpacing * TenIncr; 01217 if (TenthSpacing >= MAX_BRUSH_SPACING || TenthSpacing < MIN_BRUSH_SPACING) 01218 { 01219 ERROR3("Illegal increment value"); 01220 return FALSE; 01221 } 01222 } 01223 m_BrushSpacingIncrProp = Incr; 01224 return TRUE; 01225 } 01226 01227 01228 01229 /******************************************************************************************** 01230 01231 > MILLIPOINT BrushDefinition::GetSpacingIncrProp() 01232 01233 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01234 Created: 6/10/99 01235 Returns: the proportional spacing increment between the brush objects 01236 Purpose: As above 01237 01238 ********************************************************************************************/ 01239 01240 double BrushDefinition::GetSpacingIncrProp() 01241 { 01242 return m_BrushSpacingIncrProp; 01243 } 01244 01245 01246 /******************************************************************************************** 01247 01248 > BOOL PathProcessorBrush::SetSpacingIncrConst(MILLIPOINT Incr) 01249 01250 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01251 Created: 6/10/99 01252 Inputs: the constant spacing increment value to set 01253 Returns: TRUE if we can draw 10 objects, FALSE if the spacing is invalid 01254 Purpose: To set the proportional spacing increment between brush objects 01255 SeeAlso: - 01256 01257 ********************************************************************************************/ 01258 01259 BOOL BrushDefinition::SetSpacingIncrConst(MILLIPOINT Incr) 01260 { 01261 if (Incr <= 0) 01262 return TRUE; 01263 01264 MILLIPOINT TenthSpacing = 10 * Incr; 01265 if (TenthSpacing >= MAX_BRUSH_SPACING || TenthSpacing < MIN_BRUSH_SPACING) 01266 { 01267 ERROR3("Illegal increment value"); 01268 return FALSE; 01269 } 01270 m_BrushSpacingIncrConst = Incr; 01271 return TRUE; 01272 } 01273 01274 01275 /******************************************************************************************** 01276 01277 > MILLIPOINT BrushDefinition::GetSpacingIncrConst() 01278 01279 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01280 Created: 6/10/99 01281 Returns: the constant spacing increment between the brush objects 01282 Purpose: As above 01283 01284 ********************************************************************************************/ 01285 01286 MILLIPOINT BrushDefinition::GetSpacingIncrConst() 01287 { 01288 return m_BrushSpacingIncrConst; 01289 } 01290 01291 01292 01293 /******************************************************************************************** 01294 01295 > UINT32 BrushDefinition::GetSpacingMaxRand() 01296 01297 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01298 Created: 6/10/99 01299 Returns: the maximum percentage randomness to be applied to spacing 01300 Purpose: As above 01301 01302 ********************************************************************************************/ 01303 01304 UINT32 BrushDefinition::GetSpacingMaxRand() 01305 { 01306 return m_BrushSpacingMaxRand; 01307 } 01308 01309 01310 /******************************************************************************************** 01311 01312 > BOOL BrushDefinition::SetSpacingMaxRand(UINT32 Value) 01313 01314 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01315 Created: 6/10/99 01316 Inputs:: the maximum percentage randomness to be applied to spacing 01317 Returns: TRUE if Value is within the legal limits, otherwise FALSE 01318 Purpose: As above 01319 01320 ********************************************************************************************/ 01321 01322 BOOL BrushDefinition::SetSpacingMaxRand(UINT32 Value) 01323 { 01324 if (Value < MIN_BRUSH_RAND || Value > MAX_BRUSH_RAND) 01325 return FALSE; 01326 01327 m_BrushSpacingMaxRand = Value; 01328 return TRUE; 01329 } 01330 01331 01332 /******************************************************************************************** 01333 01334 > UINT32 BrushDefinition::GetSpacingRandSeed() 01335 01336 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01337 Created: 6/10/99 01338 Returns: the seed used to determine the sequence of random numbers for spacing 01339 Purpose: As above 01340 01341 ********************************************************************************************/ 01342 01343 UINT32 BrushDefinition::GetSpacingRandSeed() 01344 { 01345 return m_BrushSpacingRandSeed; 01346 } 01347 01348 01349 /******************************************************************************************** 01350 01351 > void BrushDefinition::SetSpacingRandSeed(UINT32 Seed) 01352 01353 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01354 Created: 6/10/99 01355 Inputs: the seed to use for our spacing RNG 01356 Returns: - 01357 Purpose: As above 01358 01359 ********************************************************************************************/ 01360 01361 void BrushDefinition::SetSpacingRandSeed(UINT32 Seed) 01362 { 01363 m_BrushSpacingRandSeed=Seed; // "=Seed" added by AMB 2006-01-06 01364 } 01365 01366 /******************************************************************************************** 01367 01368 > PathOffset BrushDefinition::GetPathOffsetType() 01369 01370 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01371 Created: 6/10/99 01372 Inputs: - 01373 Returns: The type of pathoffset this brush is using 01374 Purpose: as above 01375 SeeAlso: - 01376 01377 ********************************************************************************************/ 01378 01379 PathOffset BrushDefinition::GetPathOffsetType() 01380 { 01381 return m_PathOffsetType; 01382 } 01383 01384 01385 01386 /******************************************************************************************** 01387 01388 > void BrushDefinition::SetPathOffsetType(PathOffset Offset) 01389 01390 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01391 Created: 6/10/99 01392 Inputs Offset - the offset type to set 01393 Returns: - 01394 Purpose: to set the offset type for this brush 01395 ********************************************************************************************/ 01396 void BrushDefinition::SetPathOffsetType(PathOffset Offset) 01397 { 01398 m_PathOffsetType = Offset; 01399 } 01400 01401 01402 /******************************************************************************************** 01403 01404 > MILLIPOINT BrushDefinition::GetPathOffsetValue() 01405 01406 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01407 Created: 6/10/99 01408 Inputs: - 01409 Returns: The value of the path offset used by this brush 01410 Purpose: as above 01411 SeeAlso: - 01412 01413 ********************************************************************************************/ 01414 01415 MILLIPOINT BrushDefinition::GetPathOffsetValue() 01416 { 01417 return m_PathOffsetValue; 01418 } 01419 01420 01421 01422 /******************************************************************************************** 01423 01424 > void BrushDefinition::SetPathOffsetValue(MILLIPOINT Value) 01425 01426 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01427 Created: 6/10/99 01428 Inputs Value - the offset value to set 01429 Returns: - 01430 Purpose: to set the offset distance for this brush 01431 ********************************************************************************************/ 01432 void BrushDefinition::SetPathOffsetValue(MILLIPOINT Value) 01433 { 01434 m_PathOffsetValue = Value; 01435 } 01436 01437 01438 /******************************************************************************************** 01439 01440 > MILLIPOINT BrushDefinition::GetPathOffsetIncrConst() 01441 01442 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01443 Created: 6/10/99 01444 Inputs: - 01445 Returns: The value of the constant path offset increment used by this brush 01446 Purpose: as above 01447 SeeAlso: - 01448 01449 ********************************************************************************************/ 01450 01451 MILLIPOINT BrushDefinition::GetPathOffsetIncrConst() 01452 { 01453 return m_PathOffsetIncrConst; 01454 } 01455 01456 01457 01458 /******************************************************************************************** 01459 01460 > BOOL BrushDefinition::SetPathOffsetIncrConst(MILLIPOINT Value) 01461 01462 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01463 Created: 6/10/99 01464 Inputs Value - the offset increment value to set 01465 Returns: - 01466 Purpose: to set the offset distance for this brush 01467 ********************************************************************************************/ 01468 01469 BOOL BrushDefinition::SetPathOffsetIncrConst(MILLIPOINT Value) 01470 { 01471 if (Value < 0 || Value > MAX_BRUSH_SPACING) 01472 return FALSE; 01473 01474 m_PathOffsetIncrConst = Value; 01475 return TRUE; 01476 } 01477 01478 01479 /******************************************************************************************** 01480 01481 > double BrushDefinition::GetPathOffsetIncrProp() 01482 01483 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01484 Created: 6/10/99 01485 Inputs: - 01486 Returns: The value of the proportional path offset increment used by this brush 01487 Purpose: as above 01488 SeeAlso: - 01489 01490 ********************************************************************************************/ 01491 01492 double BrushDefinition::GetPathOffsetIncrProp() 01493 { 01494 return m_PathOffsetIncrProp; 01495 } 01496 01497 01498 01499 /******************************************************************************************** 01500 01501 > BOOL BrushDefinition::SetPathOffsetIncrProp(double Incr) 01502 01503 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01504 Created: 6/10/99 01505 Inputs incr - the proportional offset increment value to set 01506 Returns: - 01507 Purpose: to set the offset distance for this brush 01508 ********************************************************************************************/ 01509 01510 BOOL BrushDefinition::SetPathOffsetIncrProp(double Incr) 01511 { 01512 if (Incr < 0 ) 01513 return FALSE; 01514 // test to see if 10 objects takes us to the limit 01515 double TenIncr = pow(Incr, 10.0); 01516 if ((m_PathOffsetValue * TenIncr) >= MAX_BRUSH_SPACING) 01517 return FALSE; 01518 01519 m_PathOffsetIncrProp = Incr; 01520 return TRUE; 01521 } 01522 01523 01524 /******************************************************************************************** 01525 01526 > UINT32 BrushDefinition::GetOffsetValueMaxRand() 01527 01528 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01529 Created: 6/10/99 01530 Returns: the maximum percentage randomness to be applied to Offset 01531 Purpose: As above 01532 01533 ********************************************************************************************/ 01534 01535 UINT32 BrushDefinition::GetOffsetValueMaxRand() 01536 { 01537 return m_OffsetValueMaxRand; 01538 } 01539 01540 01541 /******************************************************************************************** 01542 01543 > BOOL BrushDefinition::SetOffsetValueMaxRand(UINT32 Value) 01544 01545 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01546 Created: 6/10/99 01547 Inputs:: the maximum percentage randomness to be applied to Offset 01548 Returns: TRUE if Value is within the legal limits, otherwise FALSE 01549 Purpose: As above 01550 01551 ********************************************************************************************/ 01552 01553 BOOL BrushDefinition::SetOffsetValueMaxRand(UINT32 Value) 01554 { 01555 if (Value < MIN_BRUSH_RAND || Value > MAX_BRUSH_RAND) 01556 return FALSE; 01557 01558 m_OffsetValueMaxRand = Value; 01559 return TRUE; 01560 } 01561 01562 01563 /******************************************************************************************** 01564 01565 > UINT32 BrushDefinition::GetOffsetValueRandSeed() 01566 01567 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01568 Created: 6/10/99 01569 Returns: the seed used to determine the sequence of random numbers for offset value 01570 Purpose: As above 01571 01572 ********************************************************************************************/ 01573 01574 UINT32 BrushDefinition::GetOffsetValueRandSeed() 01575 { 01576 return m_OffsetValueRandSeed; 01577 } 01578 01579 01580 /******************************************************************************************** 01581 01582 > BOOL BrushDefinition::SetOffsetValueRandSeed(UINT32 Value) 01583 01584 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01585 Created: 6/10/9 01586 Inputs : the seed used to determine the sequence of random numbers for offset value 01587 Returns: TRUE if Value is valid, which it always is at the moment 01588 Purpose: As above 01589 01590 ********************************************************************************************/ 01591 01592 void BrushDefinition::SetOffsetValueRandSeed(UINT32 Value) 01593 { 01594 m_OffsetValueRandSeed = Value; 01595 01596 } 01597 01598 01599 /******************************************************************************************** 01600 01601 > UINT32 BrushDefinition::GetOffsetTypeRandSeed() 01602 01603 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01604 Created: 6/10/99 01605 Returns: the seed used to determine the sequence of random numbers for offset value 01606 Purpose: As above 01607 01608 ********************************************************************************************/ 01609 01610 UINT32 BrushDefinition::GetOffsetTypeRandSeed() 01611 { 01612 return m_OffsetTypeRandSeed; 01613 } 01614 01615 01616 /******************************************************************************************** 01617 01618 > BOOL BrushDefinition::SetOffsetTypeRandSeed(UINT32 Value) 01619 01620 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01621 Created: 6/10/9 01622 Inputs : the seed used to determine the sequence of random numbers for offset value 01623 Returns: TRUE if Value is valid, which it always is at the moment 01624 Purpose: As above 01625 01626 ********************************************************************************************/ 01627 01628 void BrushDefinition::SetOffsetTypeRandSeed(UINT32 Value) 01629 { 01630 m_OffsetValueRandSeed = Value; 01631 01632 } 01633 01634 01635 /******************************************************************************************** 01636 01637 > void BrushDefinition::SetTiling(BOOL Value) 01638 01639 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01640 Created: 6/10/99 01641 Inputs: whether or not the brush tiles 01642 Returns: - 01643 Purpose: as above 01644 SeeAlso: - 01645 01646 ********************************************************************************************/ 01647 01648 void BrushDefinition::SetTiling(BOOL Value) 01649 { 01650 m_bTile = Value; 01651 } 01652 01653 01654 01655 /******************************************************************************************** 01656 01657 > BOOL BrushDefinition::GetTiling() 01658 01659 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01660 Created: 6/10/99 01661 Inputs: 01662 Returns: whether or not the brush tiles 01663 Purpose: as above 01664 SeeAlso: - 01665 01666 ********************************************************************************************/ 01667 01668 BOOL BrushDefinition::IsTiled() 01669 { 01670 return m_bTile; 01671 } 01672 01673 01674 01675 /******************************************************************************************** 01676 01677 > BOOL BrushDefinition::SetRotationAngle(double Angle) 01678 01679 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01680 Created: 6/10/99 01681 Inputs: the angle of rotation to set 01682 Returns: TRUE if the angle is within the stated bounds 01683 Purpose: as above 01684 SeeAlso: - 01685 01686 ********************************************************************************************/ 01687 01688 BOOL BrushDefinition::SetRotationAngle(double Angle) 01689 { 01690 /* if ((Angle <= MIN_ANGLE) || (Angle >= MAX_ANGLE)) 01691 { 01692 ERROR3("Invalid angle"); 01693 return FALSE; 01694 01695 }*/ 01696 m_RotateAngle = Angle; 01697 return TRUE; 01698 } 01699 01700 /******************************************************************************************** 01701 01702 > double BrushDefinition::GetRotationAngle() 01703 01704 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01705 Created: 6/10/99 01706 Inputs: - 01707 Returns: the angle of rotation that has been set 01708 Purpose: as above 01709 SeeAlso: - 01710 01711 ********************************************************************************************/ 01712 01713 double BrushDefinition::GetRotationAngle() 01714 { 01715 return m_RotateAngle; 01716 } 01717 01718 01719 /******************************************************************************************** 01720 01721 > BOOL BrushDefinition::SetRotAngleIncrConst(double Angle) 01722 01723 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01724 Created: 6/10/99 01725 Inputs: the incremental angle of rotation to set 01726 Returns: TRUE if the angle is within the stated bounds 01727 Purpose: as above 01728 SeeAlso: - 01729 01730 ********************************************************************************************/ 01731 01732 BOOL BrushDefinition::SetRotationIncrConst(double Angle) 01733 { 01734 m_RotAngleIncrConst = Angle; 01735 01736 return TRUE; 01737 } 01738 01739 /******************************************************************************************** 01740 01741 > double BrushDefinition::GetRotAngleIncrConst() 01742 01743 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01744 Created: 6/10/99 01745 Inputs: - 01746 Returns: the increment to the angle of rotation 01747 Purpose: as above 01748 SeeAlso: - 01749 01750 ********************************************************************************************/ 01751 01752 double BrushDefinition::GetRotationIncrConst() 01753 { 01754 return m_RotAngleIncrConst; 01755 } 01756 01757 01758 /******************************************************************************************** 01759 01760 > BOOL BrushDefinition::SetRotAngleIncrProp(double Angle) 01761 01762 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01763 Created: 6/10/99 01764 Inputs: the incremental angle of rotation to set 01765 Returns: TRUE if the angle is within the stated bounds 01766 Purpose: as above 01767 SeeAlso: - 01768 01769 ********************************************************************************************/ 01770 01771 BOOL BrushDefinition::SetRotationIncrProp(double Value) 01772 { 01773 m_RotAngleIncrProp = Value; 01774 01775 return TRUE; 01776 } 01777 01778 /******************************************************************************************** 01779 01780 > double BrushDefinition::GetRotAngleIncrProp() 01781 01782 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01783 Created: 6/10/99 01784 Inputs: - 01785 Returns: the increment to the angle of rotation 01786 Purpose: as above 01787 SeeAlso: - 01788 01789 ********************************************************************************************/ 01790 01791 double BrushDefinition::GetRotationIncrProp() 01792 { 01793 return m_RotAngleIncrProp; 01794 } 01795 01796 /******************************************************************************************** 01797 01798 > UINT32 BrushDefinition::GetRotationMaxRand() 01799 01800 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01801 Created: 6/10/99 01802 Inputs: - 01803 Returns: the maximum amount of randomness to be applied to the rotation angle 01804 Purpose: as above 01805 SeeAlso: - 01806 01807 ********************************************************************************************/ 01808 01809 UINT32 BrushDefinition::GetRotationMaxRand() 01810 { 01811 return m_RotationMaxRand; 01812 } 01813 01814 01815 /******************************************************************************************** 01816 01817 > BOOL BrushDefinition::SetRotationMaxRand(UINT32 Value) 01818 01819 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01820 Created: 6/10/99 01821 Inputs: the maximum amount of randomness (as a %) to be applied to rotation 01822 Returns: - 01823 Purpose: as above 01824 SeeAlso: - 01825 01826 ********************************************************************************************/ 01827 01828 BOOL BrushDefinition::SetRotationMaxRand(UINT32 Value) 01829 { 01830 m_RotationMaxRand = Value; 01831 return TRUE; 01832 } 01833 01834 01835 /******************************************************************************************** 01836 01837 > UINT32 BrushDefinition::GetRotationRandSeed() 01838 01839 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01840 Created: 6/10/99 01841 Inputs: - 01842 Returns: the seed to use to generate the rotation RNG 01843 Purpose: as above 01844 SeeAlso: - 01845 01846 ********************************************************************************************/ 01847 01848 UINT32 BrushDefinition::GetRotationRandSeed() 01849 { 01850 return m_RotationRandSeed; 01851 } 01852 01853 01854 01855 /******************************************************************************************** 01856 01857 > BOOL BrushDefinition::SetRotationRandSeed(UINT32 Seed) 01858 01859 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01860 Created: 6/10/99 01861 Inputs: the seed to use 01862 Returns: - 01863 Purpose: as above 01864 SeeAlso: - 01865 01866 ********************************************************************************************/ 01867 01868 void BrushDefinition::SetRotationRandSeed(UINT32 Seed) 01869 { 01870 m_RotationRandSeed = Seed; 01871 } 01872 01873 /******************************************************************************************** 01874 01875 > UINT32 BrushDefinition::GetRotationMaxPressure() 01876 01877 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01878 Created: 6/10/99 01879 Inputs: - 01880 Returns: the seed to use to generate the rotation RNG 01881 Purpose: as above 01882 SeeAlso: - 01883 01884 ********************************************************************************************/ 01885 01886 UINT32 BrushDefinition::GetRotationMaxPressure() 01887 { 01888 return m_RotationMaxPressure; 01889 } 01890 01891 01892 01893 /******************************************************************************************** 01894 01895 > BOOL BrushDefinition::SetRotationMaxPressure(UINT32 Seed) 01896 01897 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01898 Created: 6/10/99 01899 Inputs: the seed to use 01900 Returns: - 01901 Purpose: as above 01902 SeeAlso: - 01903 01904 ********************************************************************************************/ 01905 01906 BOOL BrushDefinition::SetRotationMaxPressure(UINT32 Value) 01907 { 01908 if (Value < MIN_PRESSURE_EFFECT || Value > MAX_PRESSURE_EFFECT) 01909 return FALSE; 01910 m_RotationMaxPressure = Value; 01911 return TRUE; 01912 } 01913 01914 01915 /******************************************************************************************** 01916 01917 > BOOL BrushDefinition::IsRotated() 01918 01919 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01920 Created: 6/10/99 01921 Inputs: 01922 Returns: whether or not the brush objects are rotated 01923 Purpose: as above 01924 SeeAlso: - 01925 01926 ********************************************************************************************/ 01927 01928 BOOL BrushDefinition::IsRotated() 01929 { 01930 return m_bRotate; 01931 } 01932 01933 01934 /******************************************************************************************** 01935 01936 > void BrushDefinition::SetRotation(BOOL Value) 01937 01938 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01939 Created: 6/10/99 01940 Inputs: whether or not the brush rotates 01941 Returns: - 01942 Purpose: as above 01943 SeeAlso: - 01944 01945 ********************************************************************************************/ 01946 01947 void BrushDefinition::SetRotated(BOOL Value) 01948 { 01949 m_bRotate = Value; 01950 } 01951 01952 01953 01954 /******************************************************************************************** 01955 01956 > bool BrushDefinition::SetScaling(double Scale) 01957 01958 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01959 Created: 6/10/99 01960 Inputs: the scale factor to set 01961 Returns: TRUE if Scale is within the permitted bounds 01962 Purpose: to set the member that determine to what scale of the original object each 01963 brush object is drawn 01964 SeeAlso: - 01965 01966 ********************************************************************************************/ 01967 01968 BOOL BrushDefinition::SetBrushScaling(double Scale) 01969 { 01970 if (Scale <= MIN_BRUSH_SCALE || Scale >= MAX_BRUSH_SCALE) 01971 return FALSE; 01972 01973 m_BrushScaling = Scale; 01974 return TRUE; 01975 } 01976 01977 01978 /******************************************************************************************** 01979 01980 > double BrushDefinition::GetBrushScaling() 01981 01982 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 01983 Created: 6/10/99 01984 Inputs: - 01985 Returns: the scaling factor to use when drawing the objects 01986 Purpose: as above 01987 SeeAlso: - 01988 01989 ********************************************************************************************/ 01990 01991 double BrushDefinition::GetBrushScaling() 01992 { 01993 return m_BrushScaling; 01994 } 01995 01996 01997 /******************************************************************************************** 01998 01999 > double BrushDefinition::GetBrushScalingIncr() 02000 02001 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02002 Created: 6/10/99 02003 Inputs: - 02004 Returns: the scaling factor increment to use when drawing the objects 02005 Purpose: as above 02006 SeeAlso: - 02007 02008 ********************************************************************************************/ 02009 02010 double BrushDefinition::GetBrushScalingIncr() 02011 { 02012 return m_BrushScalingIncr; 02013 } 02014 02015 02016 02017 /******************************************************************************************** 02018 02019 > bool BrushDefinition::SetBrushScalingincr(double incr) 02020 02021 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02022 Created: 6/10/99 02023 Inputs: the scale factor increment to set 02024 Returns: TRUE unless incr is negative 02025 Purpose: to set the member that determine the increment to scaling applied 02026 to each brush object 02027 02028 SeeAlso: - 02029 02030 ********************************************************************************************/ 02031 02032 BOOL BrushDefinition::SetBrushScalingIncr(double Incr) 02033 { 02034 if (Incr <= 0) 02035 { 02036 ERROR3("Negative scaling increment"); 02037 return FALSE; 02038 } 02039 02040 m_BrushScalingIncr = Incr; 02041 return TRUE; 02042 } 02043 02044 02045 /******************************************************************************************** 02046 02047 > double BrushDefinition::GetBrushScalingIncrConst() 02048 02049 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02050 Created: 6/10/99 02051 Inputs: - 02052 Returns: the scaling factor increment to use when drawing the objects 02053 Purpose: as above 02054 SeeAlso: - 02055 02056 ********************************************************************************************/ 02057 02058 double BrushDefinition::GetBrushScalingIncrConst() 02059 { 02060 return m_BrushScalingIncrConst; 02061 } 02062 02063 02064 02065 /******************************************************************************************** 02066 02067 > bool BrushDefinition::SetBrushScalingincrConst(INT32 Incr) 02068 02069 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02070 Created: 6/10/99 02071 Inputs: the scale factor increment to set 02072 Returns: TRUE unless Incr >= 100 02073 Purpose: to set the member that determine the increment to scaling applied 02074 to each brush object 02075 02076 SeeAlso: - 02077 02078 ********************************************************************************************/ 02079 02080 BOOL BrushDefinition::SetBrushScalingIncrConst(double Incr) 02081 { 02082 if (abs((INT32)Incr) >= 100) 02083 { 02084 return FALSE; 02085 } 02086 m_BrushScalingIncrConst = Incr; 02087 return TRUE; 02088 } 02089 02090 /******************************************************************************************** 02091 02092 > UINT32 BrushDefinition::GetScalingMaxRand() 02093 02094 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02095 Created: 6/10/99 02096 Returns: the maximum percentage randomness to be applied to Scaling 02097 Purpose: As above 02098 02099 ********************************************************************************************/ 02100 02101 UINT32 BrushDefinition::GetScalingMaxRand() 02102 { 02103 return m_BrushScalingMaxRand; 02104 } 02105 02106 02107 /******************************************************************************************** 02108 02109 > BOOL BrushDefinition::SetScalingMaxRand(UINT32 Value) 02110 02111 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02112 Created: 6/10/99 02113 Inputs:: the maximum percentage randomness to be applied to Scaling 02114 Returns: TRUE if Value is within the legal limits, otherwise FALSE 02115 Purpose: As above 02116 02117 ********************************************************************************************/ 02118 02119 BOOL BrushDefinition::SetScalingMaxRand(UINT32 Value) 02120 { 02121 if (Value < MIN_BRUSH_RAND || Value > MAX_BRUSH_RAND) 02122 return FALSE; 02123 02124 m_BrushScalingMaxRand = Value; 02125 return TRUE; 02126 } 02127 02128 02129 /******************************************************************************************** 02130 02131 > UINT32 BrushDefinition::GetScalingRandSeed() 02132 02133 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02134 Created: 6/10/99 02135 Returns: the seed used to determine the sequence of random numbers for Scaling 02136 Purpose: As above 02137 02138 ********************************************************************************************/ 02139 02140 UINT32 BrushDefinition::GetScalingRandSeed() 02141 { 02142 return m_BrushScalingRandSeed; 02143 } 02144 02145 02146 /******************************************************************************************** 02147 02148 > void BrushDefinition::SetScalingRandSeed(UINT32 Seed) 02149 02150 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02151 Created: 6/10/99 02152 Inputs: the seed to use for our scaling RNG 02153 Returns: - 02154 Purpose: As above 02155 02156 ********************************************************************************************/ 02157 02158 void BrushDefinition::SetScalingRandSeed(UINT32 Seed) 02159 { 02160 m_BrushScalingRandSeed = Seed; 02161 } 02162 02163 02164 /******************************************************************************************** 02165 02166 > UINT32 BrushDefinition::GetScalingMaxPressure() 02167 02168 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02169 Created: 6/10/99 02170 Returns: the maximum percentage effect that pressure will have on Scaling 02171 Purpose: As above 02172 02173 ********************************************************************************************/ 02174 02175 UINT32 BrushDefinition::GetScalingMaxPressure() 02176 { 02177 return m_ScalingMaxPressure; 02178 } 02179 02180 02181 /******************************************************************************************** 02182 02183 > BOOL BrushDefinition::SetScalingMaxPressure(UINT32 Pressure) 02184 02185 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02186 Created: 6/10/99 02187 Inputs: the maximum percentage effect that pressure will have on Scaling 02188 Returns: - 02189 Purpose: As above 02190 02191 ********************************************************************************************/ 02192 02193 BOOL BrushDefinition::SetScalingMaxPressure(UINT32 Max) 02194 { 02195 if (Max < MIN_PRESSURE_EFFECT || Max > MAX_PRESSURE_EFFECT) 02196 return FALSE; 02197 m_ScalingMaxPressure = Max; 02198 return TRUE; 02199 } 02200 02201 02202 02203 /******************************************************************************************** 02204 02205 > double BrushDefinition::GetHueIncrement() 02206 02207 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02208 Created: 6/10/99 02209 Inputs: - 02210 Returns: the hue increment for this brush 02211 Purpose: as above 02212 SeeAlso: - 02213 02214 ********************************************************************************************/ 02215 02216 double BrushDefinition::GetHueIncrement() 02217 { 02218 return m_BrushHueIncrement; 02219 } 02220 02221 02222 /******************************************************************************************** 02223 02224 > double BrushDefinition::GetHueIncrement() 02225 02226 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02227 Created: 6/10/99 02228 Inputs: the hue increment for this brush 02229 Returns: - 02230 Purpose: as above 02231 SeeAlso: - 02232 02233 ********************************************************************************************/ 02234 02235 BOOL BrushDefinition::SetHueIncrement(double Incr) 02236 { 02237 m_BrushHueIncrement = Incr; 02238 return TRUE; 02239 } 02240 02241 02242 /******************************************************************************************** 02243 02244 > UINT32 BrushDefinition::GetHueMaxRand() 02245 02246 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02247 Created: 6/10/99 02248 Inputs: - 02249 Returns: the hue increment random amount for this brush 02250 Purpose: as above 02251 SeeAlso: - 02252 02253 ********************************************************************************************/ 02254 02255 UINT32 BrushDefinition::GetHueMaxRand() 02256 { 02257 return m_BrushHueMaxRand; 02258 } 02259 02260 02261 02262 /******************************************************************************************** 02263 02264 > BOOL BrushDefinition::SetHueMaxRand(UINT32 Rand) 02265 02266 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02267 Created: 6/10/99 02268 Inputs: the hue increment random amount for this brush 02269 Returns: - 02270 Purpose: as above 02271 SeeAlso: - 02272 02273 ********************************************************************************************/ 02274 02275 BOOL BrushDefinition::SetHueMaxRand(UINT32 Rand) 02276 { 02277 m_BrushHueMaxRand = Rand; 02278 return TRUE; 02279 } 02280 02281 02282 /******************************************************************************************** 02283 02284 > UINT32 BrushDefinition::GetHueRandSeed() 02285 02286 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02287 Created: 6/10/99 02288 Inputs: - 02289 Returns: the hue increment random amount for this brush 02290 Purpose: as above 02291 SeeAlso: - 02292 02293 ********************************************************************************************/ 02294 02295 UINT32 BrushDefinition::GetHueRandSeed() 02296 { 02297 return m_BrushHueRandSeed; 02298 } 02299 02300 02301 02302 /******************************************************************************************** 02303 02304 > BOOL BrushDefinition::SetHueRandSeed(UINT32 Rand) 02305 02306 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02307 Created: 6/10/99 02308 Inputs: the hue increment random amount for this brush 02309 Returns: - 02310 Purpose: as above 02311 SeeAlso: - 02312 02313 ********************************************************************************************/ 02314 02315 BOOL BrushDefinition::SetHueRandSeed(UINT32 Rand) 02316 { 02317 m_BrushHueRandSeed = Rand; 02318 return TRUE; 02319 } 02320 02321 02322 /******************************************************************************************** 02323 02324 > double BrushDefinition::GetSatIncrement() 02325 02326 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02327 Created: 6/10/99 02328 Inputs: - 02329 Returns: the Saturation increment for this brush 02330 Purpose: as above 02331 SeeAlso: - 02332 02333 ********************************************************************************************/ 02334 02335 double BrushDefinition::GetSatIncrement() 02336 { 02337 return m_BrushSatIncrement; 02338 } 02339 02340 02341 /******************************************************************************************** 02342 02343 > double BrushDefinition::GetSatIncrement() 02344 02345 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02346 Created: 6/10/99 02347 Inputs: the Saturation increment for this brush 02348 Returns: - 02349 Purpose: as above 02350 SeeAlso: - 02351 02352 ********************************************************************************************/ 02353 02354 BOOL BrushDefinition::SetSatIncrement(double Incr) 02355 { 02356 m_BrushSatIncrement = Incr; 02357 return TRUE; 02358 } 02359 02360 02361 /******************************************************************************************** 02362 02363 > UINT32 BrushDefinition::GetSatMaxRand() 02364 02365 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02366 Created: 6/10/99 02367 Inputs: - 02368 Returns: the Saturation increment random amount for this brush 02369 Purpose: as above 02370 SeeAlso: - 02371 02372 ********************************************************************************************/ 02373 02374 UINT32 BrushDefinition::GetSatMaxRand() 02375 { 02376 return m_BrushSatMaxRand; 02377 } 02378 02379 02380 02381 /******************************************************************************************** 02382 02383 > BOOL BrushDefinition::SetSatMaxRand(UINT32 Rand) 02384 02385 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02386 Created: 6/10/99 02387 Inputs: the Saturation increment random amount for this brush 02388 Returns: - 02389 Purpose: as above 02390 SeeAlso: - 02391 02392 ********************************************************************************************/ 02393 02394 BOOL BrushDefinition::SetSatMaxRand(UINT32 Rand) 02395 { 02396 m_BrushSatMaxRand = Rand; 02397 return TRUE; 02398 } 02399 02400 02401 /******************************************************************************************** 02402 02403 > UINT32 BrushDefinition::GetSatRandSeed() 02404 02405 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02406 Created: 6/10/99 02407 Inputs: - 02408 Returns: the Saturation increment random amount for this brush 02409 Purpose: as above 02410 SeeAlso: - 02411 02412 ********************************************************************************************/ 02413 02414 UINT32 BrushDefinition::GetSatRandSeed() 02415 { 02416 return m_BrushSatRandSeed; 02417 } 02418 02419 02420 02421 /******************************************************************************************** 02422 02423 > BOOL BrushDefinition::SetSatRandSeed(UINT32 Rand) 02424 02425 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02426 Created: 6/10/99 02427 Inputs: the Saturation increment random amount for this brush 02428 Returns: - 02429 Purpose: as above 02430 SeeAlso: - 02431 02432 ********************************************************************************************/ 02433 02434 BOOL BrushDefinition::SetSatRandSeed(UINT32 Rand) 02435 { 02436 m_BrushSatRandSeed = Rand; 02437 return TRUE; 02438 } 02439 02440 02441 02442 /******************************************************************************************** 02443 02444 > INT32 BrushDefinition::GetBrushTransparency() 02445 02446 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02447 Created: 6/10/99 02448 Inputs: Value - the value to set 02449 Returns: our transparency value 02450 Purpose: as above 02451 SeeAlso: - 02452 02453 ********************************************************************************************/ 02454 02455 INT32 BrushDefinition::GetBrushTransparency() 02456 { 02457 return m_BrushTransparency; 02458 } 02459 02460 /******************************************************************************************** 02461 02462 > BOOL BrushDefinition::SetBrushTransparency(INT32 Value) 02463 02464 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02465 Created: 6/10/99 02466 Inputs: Value - the value to set 02467 Returns: our transparency value (-1 indicates unused) 02468 Purpose: as above 02469 SeeAlso: - 02470 02471 ********************************************************************************************/ 02472 02473 BOOL BrushDefinition::SetBrushTransparency(INT32 Value) 02474 { 02475 if (Value > MAX_TRANSP_VALUE) 02476 return FALSE; 02477 02478 m_BrushTransparency = Value; 02479 return TRUE; 02480 } 02481 02482 02483 /******************************************************************************************** 02484 02485 > BOOL BrushDefinition::SetTransparencyPressure(UINT32 Value) 02486 02487 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02488 Created: 6/10/99 02489 Inputs: Value - the value to set 02490 Returns: 02491 Purpose: Sets the extent to which pressure affects transparency 02492 SeeAlso: - 02493 02494 ********************************************************************************************/ 02495 02496 BOOL BrushDefinition::SetTransparencyPressure(UINT32 Value) 02497 { 02498 m_TranspMaxPressure = Value; 02499 return TRUE; 02500 } 02501 02502 02503 /******************************************************************************************** 02504 02505 > BOOL BrushDefinition::GetTransparencyPressure(UINT32 Value) 02506 02507 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02508 Created: 6/10/99 02509 Inputs: Value - the value to set 02510 Returns: 02511 Purpose: Sets the extent to which pressure affects transparency 02512 SeeAlso: - 02513 02514 ********************************************************************************************/ 02515 02516 UINT32 BrushDefinition::GetTransparencyPressure() 02517 { 02518 return m_TranspMaxPressure; 02519 } 02520 02521 02522 /******************************************************************************************** 02523 02524 > SequenceType BrushDefinition::GetSequenceType() 02525 02526 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02527 Created: 6/10/99 02528 Inputs: - 02529 Returns: the type of sequence we are using for mutliple ink objects 02530 Purpose: as above 02531 SeeAlso: - 02532 02533 ********************************************************************************************/ 02534 02535 SequenceType BrushDefinition::GetSequenceType() 02536 { 02537 return m_SequenceType; 02538 } 02539 02540 02541 /******************************************************************************************** 02542 02543 > void BrushDefinition::SetSequenceType(SequenceType Type) 02544 02545 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02546 Created: 6/10/99 02547 Inputs: the type of sequence to use 02548 Returns: - 02549 Purpose: as above 02550 SeeAlso: - 02551 02552 ********************************************************************************************/ 02553 02554 void BrushDefinition::SetSequenceType(SequenceType Type) 02555 { 02556 m_SequenceType = Type; 02557 } 02558 02559 02560 /******************************************************************************************** 02561 02562 > void BrushDefinition::SetSequenceSeed(UINT32 Seed) 02563 02564 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02565 Created: 6/10/99 02566 Inputs: the random seed to use for sequences 02567 Returns: - 02568 Purpose: as above 02569 SeeAlso: - 02570 02571 ********************************************************************************************/ 02572 02573 void BrushDefinition::SetSequenceSeed(UINT32 Seed) 02574 { 02575 m_SequenceRandSeed = Seed; 02576 } 02577 02578 02579 /******************************************************************************************** 02580 02581 > UINT32 BrushDefinition::GetSequenceSeed) 02582 02583 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02584 Created: 6/10/99 02585 Inputs: - 02586 Returns: the seed we are using to generate random sequences 02587 Purpose: as above 02588 SeeAlso: - 02589 02590 ********************************************************************************************/ 02591 02592 UINT32 BrushDefinition::GetSequenceSeed() 02593 { 02594 return m_SequenceRandSeed; 02595 } 02596 02597 /******************************************************************************************** 02598 02599 > UINT32 BrushDefinition::GetNumBrushObjects() 02600 02601 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02602 Created: 6/10/99 02603 Inputs: - 02604 Returns: the number of brush objects used by this brush 02605 Purpose: as above 02606 SeeAlso: - 02607 02608 ********************************************************************************************/ 02609 02610 UINT32 BrushDefinition::GetNumBrushObjects() const 02611 { 02612 return m_NumBrushObjects; 02613 } 02614 02615 02616 /******************************************************************************************** 02617 02618 > UINT32 BrushDefinition::GetBrushFileID() 02619 02620 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02621 Created: 6/10/99 02622 Inputs: - 02623 Returns: the ID of the default file that this brush was created from (if there is one) 02624 Purpose: as above 02625 SeeAlso: - 02626 02627 ********************************************************************************************/ 02628 02629 UINT32 BrushDefinition::GetBrushFileID() 02630 { 02631 return m_DefaultFileID; 02632 } 02633 02634 /******************************************************************************************** 02635 02636 > void BrushDefinition::SetBrushFileID(UINT32 ID) 02637 02638 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02639 Created: 6/10/99 02640 Inputs: ID - the ID of the default file that this file is being created from 02641 Returns: - 02642 Purpose: as above, this should only be called as part of the start-up process. 02643 ********************************************************************************************/ 02644 02645 void BrushDefinition::SetBrushFileID(UINT32 ID) 02646 { 02647 m_DefaultFileID = ID; 02648 } 02649 02650 /******************************************************************************************** 02651 02652 > BrushRef* BrushDefinition::GetFirstBrushRef() 02653 02654 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02655 Created: 6/10/99 02656 Inputs: - 02657 Returns: the first in the brushref array 02658 Purpose: as above 02659 SeeAlso: - 02660 02661 ********************************************************************************************/ 02662 02663 BrushRef* BrushDefinition::GetFirstBrushRef() 02664 { 02665 if( m_BrushRefPtrArray.empty() ) 02666 { 02667 ERROR3("The array is empty!"); 02668 return NULL; 02669 } 02670 m_LastBrushRefRetrieved = 0; 02671 return m_BrushRefPtrArray[0]; 02672 } 02673 02674 02675 02676 /******************************************************************************************** 02677 02678 > BrushRef* BrushDefinition::GetNextBrushRef() 02679 02680 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02681 Created: 6/10/99 02682 Inputs: - 02683 Returns: the next element in the brushref array, as kept track of by 02684 m_LastBrushRefRetrieved 02685 Purpose: as above 02686 SeeAlso: - 02687 02688 ********************************************************************************************/ 02689 02690 BrushRef* BrushDefinition::GetNextBrushRef() 02691 { 02692 // have we hit the end? 02693 if( m_LastBrushRefRetrieved >= m_NumBrushObjects - 1 ) 02694 return NULL; 02695 02696 // quick check so we don't violate 02697 if( m_LastBrushRefRetrieved >= (UINT32)m_BrushRefPtrArray.size() - 1 ) 02698 { 02699 ERROR3("Overran the array"); 02700 return NULL; 02701 } 02702 return m_BrushRefPtrArray[++m_LastBrushRefRetrieved]; 02703 } 02704 02705 02706 /******************************************************************************************** 02707 0 02708 > BrushRef* BrushDefinition::GetBrushRef(UINT32 Index) 02709 02710 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02711 Created: 6/10/99 02712 Inputs: Index - the array element to get 02713 Returns: the brushref at position Index in the array, or NULL if the index is invalid 02714 Purpose: as above 02715 SeeAlso: - 02716 02717 ********************************************************************************************/ 02718 02719 BrushRef* BrushDefinition::GetBrushRef(UINT32 Index) 02720 { 02721 // check that the index is ok 02722 if( Index > m_NumBrushObjects || Index > (UINT32)( m_BrushRefPtrArray.size() - 1 ) ) 02723 { 02724 ERROR3("Invalid index"); 02725 return NULL; 02726 } 02727 02728 // update our member 02729 m_LastBrushRefRetrieved = Index; 02730 return m_BrushRefPtrArray[Index]; 02731 } 02732 02733 02734 /******************************************************************************************** 02735 02736 > BOOL BrushDefinition::BrushContainsGroup() 02737 02738 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02739 Created: 6/10/99 02740 Inputs: - 02741 Returns: TRUE, if the brush is made from one or more groups, FALSE if not 02742 Purpose: as above 02743 SeeAlso: - 02744 02745 ********************************************************************************************/ 02746 02747 BOOL BrushDefinition::BrushContainsGroup() 02748 { 02749 for (UINT32 i = 0; i < m_NumBrushObjects; i++) 02750 { 02751 if (m_BrushRefPtrArray[i]->GetNumBlendPaths() > 1) 02752 return TRUE; 02753 } 02754 return FALSE; 02755 } 02756 02757 /******************************************************************************************** 02758 02759 > DocRect BrushDefinition::GetLargestBoundingBox() 02760 02761 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02762 Created: 6/10/99 02763 Inputs: - 02764 Returns: the largest bounding box of all the objects in this definition 02765 Purpose: as above 02766 SeeAlso: - 02767 02768 ********************************************************************************************/ 02769 02770 DocRect BrushDefinition::GetLargestBoundingBox() 02771 { 02772 // if the member is not empty then we have done this search so return it now 02773 if (!m_LargestBoundingBox.IsEmpty()) 02774 return m_LargestBoundingBox; 02775 02776 // otherwise search through the brushrefs 02777 BrushRef* pBrushRef = GetFirstBrushRef(); 02778 DocRect BRect; 02779 DocRect BiggestRect; 02780 XLONG BiggestArea = 0; 02781 while (pBrushRef != NULL) 02782 { 02783 BRect = pBrushRef->GetBoundingRect(); 02784 XLONG RectHeight = BRect.Height(); 02785 XLONG RectWidth = BRect.Width(); 02786 XLONG ThisRectArea = RectHeight * RectWidth; 02787 02788 if (ThisRectArea > BiggestArea) 02789 { 02790 BiggestRect = BRect; 02791 BiggestArea = ThisRectArea; 02792 02793 } 02794 pBrushRef = GetNextBrushRef(); 02795 02796 } 02797 m_LargestBoundingBox = BiggestRect; 02798 return BiggestRect; 02799 } 02800 02801 02802 02803 /******************************************************************************************** 02804 02805 > DocRect BrushDefinition::GetLargestPossibleRect(BOOL AdjustForLineWidth = FALSE) 02806 02807 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02808 Created: 6/10/99 02809 Inputs: AdjustForLineWidth - do we include scaling to the current line width in our 02810 calculations? 02811 Returns: the largest bounding box of all the objects in this definition, plus adjustments 02812 for variations in scale 02813 02814 Purpose: To find out the largest possible bounding box that this brush can achieve, this we 02815 get the largest ink rect and then perform the maximum scaling, rotation etc. 02816 Note that ScalingIncrConst will be will be excluded from this test as we will 02817 never be able to know what affect it will have in advance of drawing the path. 02818 02819 Note: Only use this function to determine the size of the bounding box, the location 02820 information should not be used. 02821 SeeAlso: - 02822 02823 ********************************************************************************************/ 02824 02825 DocRect BrushDefinition::GetLargestPossibleRect(BOOL AdjustForLineWidth) 02826 { 02827 DocRect BRect = GetLargestBoundingBox(); 02828 02829 if (BRect.IsEmpty()) // just quit now 02830 return BRect; 02831 02832 double Scale = 1.0; 02833 02834 MILLIPOINT LineWidth = GetDefaultLineWidth(TRUE); 02835 02836 // if we are including the scale to linewidth then work that out here 02837 if (AdjustForLineWidth) 02838 { 02839 MILLIPOINT CurrentLineWidth = OpDrawBrush::GetCurrentLineWidthIfNotDefault(); 02840 if (CurrentLineWidth != -1 && CurrentLineWidth > 501) // -1 indicates the default linewidth, hence no scaling 02841 { 02842 Scale = (double)CurrentLineWidth / (double)LineWidth; 02843 // otherwise use the current line width 02844 LineWidth = CurrentLineWidth; 02845 } 02846 } 02847 02848 // increase the size if we have randomness or pressure 02849 UINT32 MaxRand = GetScalingMaxRand(); 02850 double dRand = ((double)MaxRand * 0.01) + 1.0; 02851 UINT32 MaxPressure = GetScalingMaxPressure(); 02852 double dPressure = ((double)MaxPressure * 0.01) + 1.0; 02853 02854 Scale *= dRand; 02855 Scale *= dPressure; 02856 02857 if (Scale != 1.0) 02858 { 02859 double Height = (double)BRect.Height() * Scale; 02860 double Width = (double)BRect.Width() * Scale; 02861 02862 BRect.lo.x = 0; 02863 BRect.hi.x = (MILLIPOINT)Height; 02864 BRect.lo.y = 0; 02865 BRect.hi.y = (MILLIPOINT)Width; 02866 } 02867 // DocRect BRect(0, 0, LineWidth* 1.1, LineWidth* 1.1); 02868 02869 // as the shape might get rotated we make sure the bitmap is big enough to cope 02870 // so make a temporary rect, rotate it and expand it, and union it with the original 02871 if (m_bRotate || m_RotateAngle || m_RotAngleIncrConst || m_RotationMaxRand) 02872 { 02873 DocRect TempRect = BRect; 02874 BrushAttrValue::RotateBounds(90, &TempRect); 02875 BRect = BRect.Union(TempRect); 02876 TempRect = BRect; 02877 BrushAttrValue::RotateBounds(45, &TempRect); 02878 BRect = BRect.Union(TempRect); 02879 } 02880 02881 02882 return BRect; 02883 } 02884 02885 /******************************************************************************************** 02886 02887 > double BrushDefinition::GetTimeStampingPeriod() 02888 02889 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02890 Created: 6/10/99 02891 Inputs: - 02892 Returns: the time stamping period for this brush, if zero then timestamping is disabled 02893 Purpose: as above 02894 SeeAlso: - 02895 02896 ********************************************************************************************/ 02897 02898 double BrushDefinition::GetTimeStampingPeriod() 02899 { 02900 return m_TimeStampPeriod; 02901 } 02902 02903 02904 02905 /******************************************************************************************** 02906 02907 > BOOL BrushDefinition::SetTimeStampingPeriod(double Period) 02908 02909 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02910 Created: 6/10/99 02911 Inputs: time period to set 02912 Returns: TRUE if period is valid, else FALSE 02913 Purpose: as above 02914 SeeAlso: - 02915 02916 ********************************************************************************************/ 02917 02918 BOOL BrushDefinition::SetTimeStampingPeriod(double Period) 02919 { 02920 if (Period < MIN_TIMESTAMP || Period > MAX_TIMESTAMP) 02921 return FALSE; 02922 02923 m_TimeStampPeriod = Period; 02924 return TRUE; 02925 } 02926 02927 /******************************************************************************************** 02928 02929 > MILLIPOINT BrushDefinition::GetDefaultLineWidth() 02930 02931 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 02932 Created: 6/10/99 02933 Inputs: - 02934 Returns: the height of the largest bounding box, to be used as a default line width 02935 Purpose: as above 02936 SeeAlso: - 02937 02938 ********************************************************************************************/ 02939 02940 MILLIPOINT BrushDefinition::GetDefaultLineWidth(BOOL IgnorePressure) 02941 { 02942 DocRect BRect = GetLargestBoundingBox(); 02943 MILLIPOINT Height = BRect.Height(); 02944 MILLIPOINT Width = BRect.Width(); 02945 // double dHeight = (double)Height; 02946 // double dWidth = (double)Width; 02947 02948 double ScaleFactor = 1.0; 02949 02950 // firstly, if we are rotated, or have random rotation, then use the longest side 02951 // if (m_RotationMaxRand > 0 || m_RotateAngle != 0.0 || !m_bRotate) 02952 { 02953 if (Width > Height) 02954 Height = Width; 02955 } 02956 02957 02958 // next increase by our maximum possible random scaling 02959 if (m_BrushScalingMaxRand > 0) 02960 { 02961 // find out the random range 02962 UINT32 Lower = 0; 02963 UINT32 Upper = 0; 02964 PathProcessorBrush::GetRandomLimits(100, m_BrushScalingMaxRand, &Lower, &Upper); 02965 02966 //Use the upper limit 02967 ScaleFactor *= ((double)Upper * 0.01); 02968 } 02969 02970 // and our maximum possible pressure effect 02971 /* if (m_ScalingMaxPressure > 0 && !IgnorePressure) 02972 { 02973 ScaleFactor *= ((double)m_ScalingMaxPressure * 0.01 + 1); 02974 02975 } 02976 */ 02977 02978 MILLIPOINT NewHeight = (MILLIPOINT)((double)Height * ScaleFactor); 02979 02980 // if we have random offset then there will be some effect, this is separate from the offset amount 02981 if (m_OffsetValueMaxRand > 0) 02982 { 02983 // rand value is a percentage of object size 02984 double RandMultiplier = (double)m_OffsetValueMaxRand * 0.01; 02985 double OffsetAmount = (double)Height * RandMultiplier; 02986 02987 // remember that it goes both sides 02988 MILLIPOINT mpAmount = (MILLIPOINT)(2*OffsetAmount); 02989 NewHeight += mpAmount; 02990 } 02991 02992 // if we are offset then add that amount 02993 switch (m_PathOffsetType) 02994 { 02995 case OFFSET_NONE: 02996 break; 02997 case OFFSET_LEFT: 02998 case OFFSET_RIGHT: 02999 case OFFSET_ALTERNATE: 03000 { 03001 MILLIPOINT OffsetIncr = 2 * m_PathOffsetValue; 03002 NewHeight += OffsetIncr; 03003 } 03004 break; 03005 case OFFSET_RANDOM: 03006 break; 03007 default: 03008 ERROR3("Invalid offset type"); 03009 } 03010 03011 return NewHeight; 03012 } 03013 03014 03015 03016 /******************************************************************************************** 03017 03018 > void BrushDefinition::InitialiseBrushData() 03019 03020 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03021 Created: 6/10/99 03022 Inputs: - 03023 Returns: - 03024 Purpose: retrieves data from the path processor and puts it into our brushdata object 03025 SeeAlso: - 03026 03027 ********************************************************************************************/ 03028 03029 void BrushDefinition::InitialiseBrushData(BrushData* pData) 03030 { 03031 pData->m_BrushHandle = 100; 03032 03033 pData->m_BrushScaling = m_BrushScaling; 03034 pData->m_BrushScalingIncr = m_BrushScalingIncr; 03035 pData->m_BrushScalingMaxRand = m_BrushScalingMaxRand; 03036 pData->m_BrushScalingRandSeed = m_BrushScalingRandSeed; 03037 pData->m_ScalingMaxPressure = m_ScalingMaxPressure; 03038 03039 pData->m_bRotate = m_bRotate; 03040 pData->m_RotateAngle = m_RotateAngle; 03041 pData->m_RotAngleIncrConst = m_RotAngleIncrConst; 03042 pData->m_RotAngleIncrProp = m_RotAngleIncrProp; 03043 pData->m_RotationMaxRand = m_RotationMaxRand; 03044 pData->m_RotationRandSeed = m_RotationRandSeed; 03045 03046 pData->m_BrushSpacing = m_BrushSpacing; 03047 pData->m_BrushSpacingIncrConst = m_BrushSpacingIncrConst; 03048 pData->m_BrushSpacingIncrProp = m_BrushSpacingIncrProp; 03049 pData->m_BrushSpacingMaxRand = m_BrushSpacingMaxRand; 03050 pData->m_BrushSpacingRandSeed = m_BrushSpacingRandSeed; 03051 03052 pData->m_PathOffsetType = m_PathOffsetType; 03053 pData->m_PathOffsetValue = m_PathOffsetValue; 03054 pData->m_PathOffsetIncrConst = m_PathOffsetIncrConst; 03055 pData->m_PathOffsetIncrProp = m_PathOffsetIncrProp; 03056 pData->m_OffsetValueMaxRand = m_OffsetValueMaxRand; 03057 pData->m_OffsetValueRandSeed = m_OffsetValueRandSeed; 03058 pData->m_OffsetTypeRandSeed = m_OffsetTypeRandSeed; 03059 03060 pData->m_bTile = m_bTile; 03061 03062 pData->m_SequenceType = m_SequenceType; 03063 pData->m_SequenceRandSeed = m_SequenceRandSeed; 03064 03065 pData->m_bUseLocalFillColour = FALSE; 03066 03067 pData->m_BrushHueIncrement = m_BrushHueIncrement; 03068 pData->m_BrushHueMaxRand = m_BrushHueMaxRand; 03069 pData->m_BrushHueRandSeed = m_BrushHueRandSeed; 03070 03071 pData->m_BrushSatIncrement = m_BrushSatIncrement; 03072 pData->m_BrushSatMaxRand = m_BrushSatMaxRand; 03073 pData->m_BrushSatRandSeed = m_BrushSatRandSeed; 03074 03075 pData->m_BrushTransparency = m_BrushTransparency; 03076 pData->m_TranspMaxPressure = m_TranspMaxPressure; 03077 03078 if (m_TimeStampPeriod <=0) 03079 { 03080 pData->m_bTimeStampBrushes = FALSE; 03081 pData->m_TimeStampPeriod = UINT32(-1); 03082 } 03083 else 03084 { 03085 pData->m_bTimeStampBrushes = TRUE; 03086 pData->m_TimeStampPeriod = (UINT32)m_TimeStampPeriod; 03087 } 03088 03089 pData->m_Name = *GetLineName(); 03090 } 03091 03092 03093 03094 /******************************************************************************************** 03095 03096 > BrushData BrushDefinition::GetBrushData() 03097 03098 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03099 Created: 6/10/99 03100 Inputs: - 03101 Returns: our brush data object 03102 Purpose: gets the latest data from our path processor, copies it into our BrushData object 03103 which is then returned. Note that you are responsible for deleting this object. 03104 SeeAlso: - 03105 03106 ********************************************************************************************/ 03107 03108 BrushData* BrushDefinition::GetBrushData() 03109 { 03110 BrushData* pNewData = new BrushData; 03111 if (pNewData != NULL) 03112 InitialiseBrushData(pNewData); 03113 return pNewData; 03114 } 03115 03116 /******************************************************************************************** 03117 03118 > BrushData BrushDefinition::GetBrushData() 03119 03120 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03121 Created: 6/10/99 03122 Inputs: - 03123 Returns: our brush data object 03124 Purpose: gets the latest data from our path processor, copies it into our BrushData object 03125 which is then returned. Note that you are responsible for deleting this object. 03126 SeeAlso: - 03127 03128 ********************************************************************************************/ 03129 03130 void BrushDefinition::SetMembersFromData(BrushData Data) 03131 { 03132 m_BrushSpacing = Data.m_BrushSpacing; 03133 m_BrushSpacingIncrProp = Data.m_BrushSpacingIncrProp; 03134 m_BrushSpacingIncrConst = Data.m_BrushSpacingIncrConst; 03135 m_BrushSpacingMaxRand = Data.m_BrushSpacingMaxRand; 03136 m_BrushSpacingRandSeed = Data.m_BrushSpacingRandSeed; 03137 03138 m_PathOffsetType = Data.m_PathOffsetType; 03139 m_PathOffsetValue = Data.m_PathOffsetValue; 03140 m_PathOffsetIncrProp = Data.m_PathOffsetIncrProp; 03141 m_PathOffsetIncrConst = Data.m_PathOffsetIncrConst; 03142 m_OffsetTypeRandSeed = Data.m_OffsetTypeRandSeed; 03143 m_OffsetValueMaxRand = Data.m_OffsetValueMaxRand; 03144 m_OffsetValueRandSeed = Data.m_OffsetValueRandSeed; 03145 03146 m_bRotate = Data.m_bRotate; 03147 m_RotateAngle = Data.m_RotateAngle; 03148 m_RotationMaxRand = Data.m_RotationMaxRand; 03149 m_RotationRandSeed = Data.m_RotationRandSeed; 03150 m_RotAngleIncrConst = Data.m_RotAngleIncrConst; 03151 m_RotAngleIncrProp = Data.m_RotAngleIncrProp; 03152 m_RotationMaxPressure = Data.m_RotationMaxPressure; 03153 03154 m_bTile = Data.m_bTile; 03155 03156 m_BrushScaling = Data.m_BrushScaling; 03157 m_BrushScalingIncr = Data.m_BrushScalingIncr; 03158 m_BrushScalingIncrConst = Data.m_BrushScalingIncrConst; 03159 m_BrushScalingMaxRand = Data.m_BrushScalingMaxRand; 03160 m_BrushScalingRandSeed = Data.m_BrushScalingRandSeed; 03161 m_ScalingMaxPressure = Data.m_ScalingMaxPressure; 03162 03163 m_BrushHueIncrement = Data.m_BrushHueIncrement; 03164 m_BrushHueMaxRand = Data.m_BrushHueMaxRand; 03165 m_BrushHueRandSeed = Data.m_BrushHueRandSeed; 03166 03167 m_BrushSatIncrement = Data.m_BrushSatIncrement; 03168 m_BrushSatMaxRand = Data.m_BrushSatMaxRand; 03169 m_BrushSatRandSeed = Data.m_BrushSatRandSeed; 03170 03171 m_BrushTransparency = Data.m_BrushTransparency; 03172 m_TranspMaxPressure = Data.m_TranspMaxPressure; 03173 03174 m_SequenceType = Data.m_SequenceType; 03175 m_SequenceRandSeed = Data.m_SequenceRandSeed; 03176 03177 m_LargestBoundingBox.MakeEmpty(); 03178 03179 m_Name = TEXT("Custom Brush"); 03180 03181 m_TimeStampPeriod = Data.m_TimeStampPeriod; 03182 03183 03184 } 03185 03186 03187 /******************************************************************************************** 03188 03189 > UINT32 BrushDefinition::GetFirstRandomNumber(UINT32 Seed = 0) 03190 03191 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03192 Created: 6/10/99 03193 Inputs: a seed to use to generate the random number sequence 03194 Returns: the first number in a random number sequence 03195 Purpose: Seeds srand with either the seed supplied or by using time (i.e. a random seed) 03196 SeeAlso: 03197 03198 ********************************************************************************************/ 03199 03200 UINT32 BrushDefinition::GetFirstRandomNumber(UINT32 Seed) 03201 { 03202 // seed the random number generator 03203 if (Seed == 0) 03204 srand( (unsigned)time( NULL ) ); 03205 else 03206 srand((unsigned)Seed); 03207 03208 return (UINT32)rand(); 03209 } 03210 03211 03212 /******************************************************************************************** 03213 03214 > UINT32 BrushDefinition::GetNextRandomNumber() 03215 03216 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03217 Created: 6/10/99 03218 Inputs: - 03219 Returns: the next number in an already seeded random number sequence 03220 Purpose: as above, note that you MUST have already called GetFirstRandomNumber() 03221 SeeAlso: 03222 03223 ********************************************************************************************/ 03224 03225 UINT32 BrushDefinition::GetNextRandomNumber() 03226 { 03227 return (UINT32)rand(); 03228 } 03229 03230 03231 /******************************************************************************************** 03232 03233 > BOOL BrushDefinition::CopyInkTreeToClipboard() 03234 03235 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03236 Created: 6/10/99 03237 Inputs: - 03238 Returns: TRUE if successful, FALSE otherwise 03239 Purpose: copies the ink objects of this brush definition to the clipboard so they can be 03240 used elsewhere 03241 SeeAlso: - 03242 03243 ********************************************************************************************/ 03244 03245 BOOL BrushDefinition::CopyInkTreeToClipboard() 03246 { 03247 // first see if we can get the clipboard 03248 InternalClipboard *Clipboard = InternalClipboard::Instance(); 03249 if (Clipboard == NULL || !Clipboard->PrepareForCopy()) 03250 { 03251 ERROR3("Error copying to clipboard"); 03252 return FALSE; 03253 } 03254 03255 if (m_pTree == NULL) 03256 { 03257 ERROR3("No ink objects"); 03258 return FALSE; 03259 } 03260 03261 // remember that we store the ink nodes in a spread, so the first child 03262 // will be the layer, which we do not want to copy 03263 Node* pFirstNode = m_pTree->FindFirstChild(); 03264 if (pFirstNode == NULL) 03265 { 03266 ERROR3("No layer underneath spread"); 03267 return FALSE; 03268 } 03269 pFirstNode = pFirstNode->FindFirstChild(); 03270 03271 // Just be sure its an ink node 03272 if (pFirstNode == NULL || !pFirstNode->IsAnObject()) 03273 { 03274 ERROR3("No ink object to copy"); 03275 return FALSE; 03276 } 03277 03278 // we want to set up a range to copy to the clipboard, so find the rightmost sibling 03279 // of our node 03280 03281 // We need to set them unselected so that range::findfirst doesn't return NULL 03282 03283 Node* pLastNode = pFirstNode; 03284 Node* pNextNode = pLastNode->FindNext(); 03285 while (pNextNode != NULL) 03286 { 03287 pNextNode->SetSelected(FALSE); 03288 pLastNode = pNextNode; 03289 pNextNode = pLastNode->FindNext(); 03290 } 03291 pFirstNode->SetSelected(FALSE); 03292 DocCoord Centre; 03293 if (pFirstNode->IsKindOf(CC_RUNTIME_CLASS(NodeRenderableInk))) 03294 { 03295 DocRect BRect = ((NodeRenderableInk*)pFirstNode)->GetBoundingRect(); 03296 Centre = BRect.Centre(); 03297 TRACEUSER( "Diccon", _T("Ink node centre = %d, %d\n"), Centre.x, Centre.y); 03298 } 03299 Node* pChild = pFirstNode->FindFirstChild(CC_RUNTIME_CLASS(AttrRadialTranspFill)); 03300 if (pChild != NULL) 03301 { 03302 DocCoord *pStartPoint = ((AttrRadialTranspFill*)pChild)->GetStartPoint(); 03303 if (pStartPoint != NULL) 03304 TRACEUSER( "Diccon", _T("StartPoint pre-export = %d, %d\n"), pStartPoint->x, pStartPoint->y); 03305 } 03306 03307 03308 // that should give us our range, now set up the range control, just use the default 03309 RangeControl rc; 03310 rc.Unselected = TRUE; 03311 rc.Selected = FALSE; 03312 03313 Range BrushRange(pFirstNode, pLastNode, rc); 03314 03315 PreExportSubTree(); 03316 03317 BOOL ok = Clipboard->CopyObjects(BrushRange); 03318 BOOL StillOk = Clipboard->CopyCompleted(); 03319 03320 PostExportSubTree(); 03321 03322 return (ok && StillOk); 03323 } 03324 03325 /******************************************************************************************** 03326 03327 > BOOL BrushDefinition::ExportBrush(BaseCamelotFilter *pFilter) 03328 03329 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03330 Created: 22/12/99 03331 03332 Inputs: pFilter - the BaseCamelotFilter filter that is being used to export a file. 03333 Handle - the handle assigned to the brush 03334 Returns: TRUE if export was successful 03335 FALSE if export was aborted - no error is set, as in this case, it usually 03336 means that the Brush has been deleted, and is being treated as an old-style 03337 line. In this case, the caller should simply not bother exporting the 03338 attribute using the Brush definition. 03339 03340 Purpose: To export a Brush definition. 03341 03342 Notes: Do not call this function directly, it is better to call it via 03343 BrushComponent::ExportBrush as this ensures that each brush is only saved once 03344 03345 ********************************************************************************************/ 03346 03347 BOOL BrushDefinition::ExportBrush(BaseCamelotFilter* pFilter, BrushHandle Handle) 03348 { 03349 ERROR2IF(pFilter == NULL, FALSE, "Filter is null"); 03350 ERROR2IF(Handle == BrushHandle_NoBrush, FALSE, "Trying to export null brush"); 03351 03352 BOOL ok = TRUE; 03353 03354 PreExportSubTree(); 03355 CXaraFileRecord Record(TAG_BRUSHDEFINITION, TAG_BRUSHDEFINITION_SIZE); 03356 if (ok) ok = Record.Init(); 03357 03358 // first write the handle 03359 if (ok) ok = Record.WriteUINT32(Handle); 03360 if (ok) pFilter->Write(&Record); 03361 03362 // then write the subtree - note that this may be moved to the superclass 03363 if (ok) 03364 { 03365 Node* pExportNode = NULL; 03366 if (m_pTree == NULL) 03367 ok = FALSE; 03368 else 03369 { 03370 pExportNode = m_pTree->FindFirstChild(); // Find the Layer 03371 if (pExportNode != NULL) 03372 pExportNode = pExportNode->FindFirstChild(); // Find the inknode 03373 } 03374 03375 // Write out the clipart subtree. We have to encapsulate it in DOWN and UP 03376 // records ourselves 03377 CXaraFileRecord DownRec(TAG_DOWN, 0); 03378 if (ok) pFilter->Write(&DownRec); 03379 03380 if (ok) ok = pFilter->WriteNodes(pExportNode); 03381 03382 CXaraFileRecord UpRec(TAG_UP, 0); 03383 if (ok) pFilter->Write(&UpRec); 03384 03385 } 03386 PostExportSubTree(); 03387 03388 // now write the data, note that the handle is written here also as they 03389 // are retrieved separately and will need to be reconciled 03390 CXaraFileRecord DataRecord((INT32)TAG_BRUSHDATA, (INT32)TAG_BRUSHDATA_SIZE); 03391 if (ok) ok = DataRecord.Init(); 03392 03393 BYTE Flags = 0; 03394 if (m_bTile) 03395 Flags |= TAG_BRUSHTILE_FLAG; 03396 if (m_bRotate) 03397 Flags |= TAG_BRUSHROTATE_FLAG; 03398 03399 03400 INT32 Offset = (INT32)m_PathOffsetType; 03401 03402 if(ok) ok = DataRecord.WriteUINT32((UINT32)Handle); 03403 if (ok) ok = DataRecord.WriteINT32(m_BrushSpacing); 03404 if (ok) ok = DataRecord.WriteBYTE(Flags); 03405 if (ok) ok = DataRecord.WriteDOUBLE(m_RotateAngle); 03406 if (ok) ok = DataRecord.WriteINT32(Offset); 03407 if (ok) ok = DataRecord.WriteINT32(m_PathOffsetValue); 03408 if (ok) ok = DataRecord.WriteUnicode((TCHAR *)*(GetLineName())); 03409 if (ok) ok = DataRecord.WriteDOUBLE(m_BrushScaling); 03410 if (ok) pFilter->Write(&DataRecord); 03411 03412 // write the additional data 03413 CXaraFileRecord NextRec(TAG_MOREBRUSHDATA, TAG_MOREBRUSHDATA_SIZE); 03414 if (ok) ok = NextRec.Init(); 03415 if (ok) ok = NextRec.WriteDOUBLE(m_BrushSpacingIncrProp); 03416 if (ok) ok = NextRec.WriteINT32(m_BrushSpacingIncrConst); 03417 if (ok) ok = NextRec.WriteINT32((INT32)m_BrushSpacingMaxRand); 03418 if (ok) ok = NextRec.WriteINT32((INT32)m_BrushSpacingRandSeed); 03419 03420 if (ok) ok = NextRec.WriteDOUBLE(m_BrushScalingIncr); 03421 if (ok) ok = NextRec.WriteINT32((INT32)m_BrushScalingMaxRand); 03422 if (ok) ok = NextRec.WriteINT32((INT32)m_BrushScalingRandSeed); 03423 03424 if (ok) ok = NextRec.WriteINT32((INT32)m_SequenceType); 03425 if (ok) ok = NextRec.WriteINT32((INT32)m_SequenceRandSeed); 03426 03427 if (ok) ok = NextRec.WriteDOUBLE(m_PathOffsetIncrProp); 03428 if (ok) ok = NextRec.WriteINT32(m_PathOffsetIncrConst); 03429 if (ok) ok = NextRec.WriteINT32((INT32)m_OffsetTypeRandSeed); 03430 if (ok) ok = NextRec.WriteINT32((INT32)m_OffsetValueMaxRand); 03431 if (ok) ok = NextRec.WriteINT32((INT32)m_OffsetValueRandSeed); 03432 if (ok) ok = pFilter->Write(&NextRec); 03433 03434 CXaraFileRecord AnotherRec(TAG_EVENMOREBRUSHDATA, TAG_EVENMOREBRUSHDATA_SIZE); 03435 if (ok) ok = AnotherRec.Init(); 03436 if (ok) ok = AnotherRec.WriteINT32((INT32)m_RotationMaxRand); 03437 if (ok) ok = AnotherRec.WriteINT32((INT32)m_RotationRandSeed); 03438 if (ok) ok = pFilter->Write(&AnotherRec); 03439 03440 CXaraFileRecord PressureRec(TAG_BRUSHPRESSUREINFO, TAG_BRUSHPRESSUREINFO_SIZE); 03441 if (ok) ok = PressureRec.Init(); 03442 if (ok) ok = PressureRec.WriteINT32((INT32)m_ScalingMaxPressure); 03443 if (ok) ok = PressureRec.WriteINT32((INT32)m_SpacingMaxPressure); 03444 if (ok) ok = PressureRec.WriteINT32((INT32)m_OffsetMaxPressure); 03445 if (ok) ok = PressureRec.WriteINT32((INT32)m_RotationMaxPressure); 03446 if (ok) ok = PressureRec.WriteINT32((INT32)m_HueMaxPressure); 03447 if (ok) ok = PressureRec.WriteINT32((INT32)m_SatMaxPressure); 03448 if (ok) ok = PressureRec.WriteINT32((INT32)m_TimeStampMaxPressure); 03449 if (ok) ok = pFilter->Write(&PressureRec); 03450 03451 // now write our transparency info 03452 CXaraFileRecord TranspRec(TAG_BRUSHTRANSPINFO, TAG_BRUSHTRANSPINFO_SIZE); 03453 if (ok) ok = TranspRec.Init(); 03454 if (ok) ok = TranspRec.WriteINT32(INT32(m_BrushTransparency)); 03455 if (ok) ok = TranspRec.WriteINT32(INT32(m_TranspMaxPressure)); 03456 if (ok) ok = TranspRec.WriteDOUBLE(m_RotAngleIncrConst); 03457 if (ok) ok = TranspRec.WriteDOUBLE(m_BrushScalingIncrConst); 03458 if (ok) ok = TranspRec.WriteINT32(INT32(m_BrushHueMaxRand)); 03459 if (ok) ok = TranspRec.WriteINT32(INT32(m_BrushHueRandSeed)); 03460 if (ok) ok = TranspRec.WriteINT32(INT32(m_BrushSatMaxRand)); 03461 if (ok) ok = TranspRec.WriteINT32(INT32(m_BrushSatRandSeed)); 03462 if (ok) ok = pFilter->Write(&TranspRec); 03463 03464 // Finally, mark this stroke as having been written out so we don't do it again 03465 if (ok) SetIOStore(TRUE); 03466 03467 03468 03469 return ok; 03470 03471 } 03472 03473 03474 03475 /******************************************************************************************** 03476 03477 > BOOL BrushDefinition::PreExportSubTree() 03478 03479 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03480 Created: 6/10/99 03481 Inputs: - 03482 Returns: TRUE if successful, FALSE if something went wrong 03483 Purpose: To perform various functions just prior to saving the subtree of the brush definition. 03484 The function loops through the BrushRefs, finding the blendpaths of each and 03485 transforming their attribute maps back to the position that they were in when the 03486 brush was created. 03487 SeeAlso: - 03488 03489 Notes: This function is required because if the attribute map is not saved out at the exact 03490 position it was created it will become 'out of sync' with the blendpath it applies to. 03491 Recall that upon reimporting the brush the blendpaths are generated from scratch 03492 whereas the attributes are not. 03493 ********************************************************************************************/ 03494 03495 BOOL BrushDefinition::PreExportSubTree() 03496 { 03497 BrushRef* pBrushRef = GetFirstBrushRef(); 03498 ERROR2IF(pBrushRef== NULL, FALSE, "No brushref"); 03499 while (pBrushRef != NULL) 03500 { 03501 BlendPath * pBlendPath = pBrushRef->GetFirstBlendPath(); 03502 while (pBlendPath != NULL) 03503 { 03504 if (!pBlendPath->TransformBrushAttributesBeforeSave()) 03505 ERROR2(FALSE, "Somethings gone wrong"); 03506 pBlendPath = pBrushRef->GetNextBlendPath(pBlendPath); 03507 } 03508 pBrushRef = GetNextBrushRef(); 03509 } 03510 return TRUE; 03511 } 03512 03513 03514 03515 /******************************************************************************************** 03516 03517 > BOOL BrushDefinition::PostExportSubTree() 03518 03519 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03520 Created: 6/10/99 03521 Inputs: - 03522 Returns: TRUE if successful, FALSE if something went wrong 03523 Purpose: To perform various functions just prior to saving the subtree of the brush definition. 03524 The function loops through the BrushRefs, finding the blendpaths of each and undoes the 03525 transformation performed by PreExportSubTree. 03526 This is required because to continue using the brush in our current document we want 03527 to use its current position 03528 03529 SeeAlso: - 03530 03531 Notes: This function is required because if the attribute map is not saved out at the exact 03532 position it was created it will become 'out of sync' with the blendpath it applies to. 03533 Recall that upon reimporting the brush the blendpaths are generated from scratch 03534 whereas the attributes are not. 03535 ********************************************************************************************/ 03536 03537 BOOL BrushDefinition::PostExportSubTree() 03538 { 03539 BrushRef* pBrushRef = GetFirstBrushRef(); 03540 03541 while (pBrushRef != NULL) 03542 { 03543 BlendPath * pBlendPath = pBrushRef->GetFirstBlendPath(); 03544 while (pBlendPath != NULL) 03545 { 03546 if (!pBlendPath->TransformBrushAttributesAfterSave()) 03547 ERROR3("Somethings gone wrong"); 03548 pBlendPath = pBrushRef->GetNextBlendPath(pBlendPath); 03549 } 03550 pBrushRef = GetNextBrushRef(); 03551 } 03552 return TRUE; 03553 } 03554 03555 03556 03557 03558 03559 03560 03561 03562 /*------------------------------------------------------------------------------------------- 03563 --------------------------------------------------------------------------------------------- 03564 --------------------------------------------------------------------------------------------- 03565 The BrushComponent Class 03566 03567 */ 03568 03569 03570 /******************************************************************************************** 03571 03572 > BOOL BrushComponentClass::Init() 03573 03574 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03575 Created: 13/12/99 03576 Returns: TRUE if all went well; 03577 FALSE if not. 03578 Purpose: Register the Brush document component with the main application. 03579 Errors: Out of memory. 03580 SeeAlso: DocComponent 03581 03582 ********************************************************************************************/ 03583 03584 BOOL BrushComponentClass::Init() 03585 { 03586 // Instantiate a component class to register with the application. 03587 BrushComponentClass *pClass = new BrushComponentClass; 03588 if (pClass == NULL) 03589 return(FALSE); 03590 03591 // Register it 03592 GetApplication()->RegisterDocComponent(pClass); 03593 03594 return(TRUE); 03595 } 03596 03597 03598 /******************************************************************************************** 03599 03600 > BOOL BrushComponentClass::LoadDefaultBrushes() 03601 03602 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03603 Created: 13/12/99 03604 Returns: TRUE if all went well; 03605 FALSE if not. 03606 Purpose: Loads default brushes from a file 03607 Errors: Fail to load file 03608 03609 ********************************************************************************************/ 03610 03611 BOOL BrushComponentClass::LoadDefaultBrushes() 03612 { 03613 PORTNOTETRACE("other","BrushComponentClass::LoadDefaultBrushes - do nothing"); 03614 #ifndef EXCLUDE_FROM_XARALX 03615 // lets try loading the default brushes here 03616 LoadBrushDirect LoadBrush; 03617 03618 // set up the search path, file util allows us just to pass the path/*.xar 03619 String_256 SearchPath; 03620 CResDll::GetExecutablePath((TCHAR*)SearchPath); 03621 String_256 Path = TEXT("\\Templates\\Brushes\\"); 03622 SearchPath += Path; 03623 String_256 FileSpecifier = SearchPath; 03624 FileSpecifier += TEXT("*.xar"); 03625 03626 BOOL ok = FileUtil::StartFindingFiles(&FileSpecifier); 03627 BrushComponent::BeginLoadingDefaultFiles(); 03628 String_256 Filename; 03629 FilePath oFilePath; 03630 String_16 Extension; 03631 while (ok) 03632 { 03633 // fileutil will give us the next filename 03634 ok = FileUtil::FindNextFile(&Filename); 03635 String_256 FullPath = SearchPath; 03636 FullPath += Filename; 03637 if (ok) 03638 { 03639 oFilePath.SetFilePath(FullPath); 03640 Extension = oFilePath.GetType(); 03641 Extension.toLower(); 03642 if (oFilePath.IsValid() && Extension==String_16("xar")) 03643 { 03644 BrushComponent::LoadNextDefaultFile(); 03645 ok = LoadBrush.Execute((TCHAR*)FullPath); 03646 } 03647 } 03648 } 03649 BrushComponent::EndLoadingDefaults(); 03650 FileUtil::StopFindingFiles(); 03651 #endif 03652 return TRUE; 03653 } 03654 /******************************************************************************************** 03655 03656 > void BrushComponentClass::DeInit() 03657 03658 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03659 Created: 13/12/99 03660 03661 Returns: TRUE if all went well; 03662 FALSE if not. 03663 03664 Purpose: De-initialises the vector Brush provider system 03665 03666 ********************************************************************************************/ 03667 03668 void BrushComponentClass::DeInit() 03669 { 03670 BrushComponent::DeleteList(); 03671 } 03672 03673 03674 03675 /******************************************************************************************** 03676 03677 > BOOL BrushComponentClass::AddComponent(BaseDocument *pDocument) 03678 03679 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03680 Created: 13/12/99 03681 Inputs: pDocument - the document to add the component to. 03682 Returns: TRUE if the Brush component was added ok; 03683 FALSE if not. 03684 Purpose: Add a Brush component to the specified document. 03685 Errors: Out of memory 03686 SeeAlso: PrintComponentClass 03687 03688 ********************************************************************************************/ 03689 03690 BOOL BrushComponentClass::AddComponent(BaseDocument *pDocument) 03691 { 03692 ERROR2IF(pDocument==NULL, FALSE, "NULL document passed to BrushCompClass:Add"); 03693 03694 // Check to see if this document already has a colour list; if so, leave it alone. 03695 if (pDocument->GetDocComponent(CC_RUNTIME_CLASS(BrushComponent)) != NULL) 03696 return(TRUE); 03697 03698 // Ok - create the print mark component. 03699 BrushComponent *pComponent = new BrushComponent; 03700 if (pComponent == NULL) 03701 return(FALSE); 03702 03703 // All ok - add the component to the document. 03704 pDocument->AddDocComponent(pComponent); 03705 03706 return(TRUE); 03707 } 03708 03709 03710 /*-------------------------------------------------------------------------------------------- 03711 ---------------------------------------------------------------------------------------------- 03712 ---------------------------------------------------------------------------------------------- 03713 The BrushComponent class 03714 03715 */ 03716 03717 UINT32 BrushComponent::m_CurrentDefaultFile = BRUSHFILE_NONE; 03718 03719 /******************************************************************************************** 03720 03721 > BrushComponent::BrushComponent() 03722 03723 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03724 Created: 13/12/99 03725 03726 Purpose: Constructor 03727 03728 ********************************************************************************************/ 03729 03730 BrushComponent::BrushComponent() : LineComponent() 03731 { 03732 m_pImportBrushDef = NULL; 03733 03734 } 03735 03736 03737 03738 /******************************************************************************************** 03739 03740 > BrushComponent::~BrushComponent() 03741 03742 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03743 Created: 13/12/99 03744 03745 Purpose: Destructor 03746 03747 ********************************************************************************************/ 03748 03749 BrushComponent::~BrushComponent() 03750 { 03751 if (m_pImportBrushDef != NULL) 03752 delete m_pImportBrushDef; 03753 } 03754 03755 03756 /******************************************************************************************** 03757 03758 > BOOL BrushComponent::BeginLoadingDefaultFiles(UINT32 NumFiles) 03759 03760 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03761 Created: 6/10/99 03762 Inputs: - 03763 Returns: TRUE 03764 Purpose: Lets the component know that we are starting to load default brushes 03765 Notes: What happens here is that every brush added to the component whilst 03766 m_CurrentDefaultBrush != BRUSHFILE_NONE will be assigned m_CurrentDefaultBrush 03767 as its default file ID. 03768 Note again, as you can tell from the code this can only be done once. 03769 ********************************************************************************************/ 03770 03771 BOOL BrushComponent::BeginLoadingDefaultFiles() 03772 { 03773 m_CurrentDefaultFile = BRUSHFILE_NONE; 03774 return TRUE; 03775 } 03776 03777 03778 /******************************************************************************************** 03779 03780 > BOOL BrushComponent::LoadDefaultFile(String_256 Filename) 03781 03782 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03783 Created: 6/10/99 03784 Inputs: - 03785 Returns: TRUE if all goes well 03786 Purpose: Increments our default file counter 03787 SeeAlso: - 03788 03789 ********************************************************************************************/ 03790 03791 BOOL BrushComponent::LoadNextDefaultFile() 03792 { 03793 // is this the first file? 03794 if (m_CurrentDefaultFile == BRUSHFILE_NONE) 03795 m_CurrentDefaultFile = 0; 03796 else 03797 m_CurrentDefaultFile++; 03798 03799 return TRUE; 03800 } 03801 03802 03803 03804 /******************************************************************************************** 03805 03806 > void BrushComponent::EndLoadingDefaults() 03807 03808 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03809 Created: 6/10/99 03810 Inputs: - 03811 Returns: - 03812 Purpose: Finishes loading default files 03813 SeeAlso: - 03814 03815 ********************************************************************************************/ 03816 03817 void BrushComponent::EndLoadingDefaults() 03818 { 03819 m_CurrentDefaultFile = BRUSHFILE_NONE; 03820 } 03821 03822 /******************************************************************************************** 03823 03824 > AttrBrushType* BrushComponent::CreateAttributeNode(BrushHandle Handle) 03825 03826 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03827 Created: 6/10/99 03828 Inputs: Handle to the brush definition which we want to base this brush on 03829 Returns: Attribute node based on this definition 03830 Purpose: - 03831 SeeAlso: - 03832 03833 ********************************************************************************************/ 03834 03835 AttrBrushType* BrushComponent::CreateAttributeNode(BrushHandle Handle) 03836 { 03837 BrushDefinition* pBrushDef = FindBrushDefinition(Handle); 03838 if (pBrushDef == NULL) 03839 return NULL; 03840 03841 AttrBrushType* pNewNode = new AttrBrushType; 03842 if (pNewNode == NULL) 03843 return NULL; 03844 03845 BrushAttrValue* pVal = (BrushAttrValue*)pNewNode->GetAttributeValue(); 03846 if (pVal == NULL) 03847 return NULL; 03848 03849 PathProcessorBrush* pPathProc = new PathProcessorBrush; 03850 if (pPathProc == NULL) 03851 return NULL; 03852 pBrushDef->CopyDataToProcessor(pPathProc); 03853 pVal->SetPathProcessor(pPathProc); 03854 03855 // tell it which brush definition to use 03856 pPathProc->SetBrushDefinition(Handle); 03857 return pNewNode; 03858 } 03859 03860 03861 /******************************************************************************************** 03862 03863 > BOOL BrushComponent::CopyInkObjectsToClipboard(BrushHandle Handle) 03864 03865 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03866 Created: 6/10/99 03867 Inputs: Handle to the brush definition which we want to send to the clipboard 03868 Returns: TRUE if successful, FALSE otherwise 03869 Purpose: copies the ink objects of this brush definition to the clipboard so they can be 03870 used elsewhere 03871 SeeAlso: - 03872 03873 ********************************************************************************************/ 03874 03875 BOOL BrushComponent::CopyInkObjectsToClipboard(BrushHandle Handle) 03876 { 03877 if (Handle == BrushHandle_NoBrush || Handle >= m_Used) 03878 { 03879 ERROR3("Invalid brush handle"); 03880 return FALSE; 03881 } 03882 03883 BrushDefinition* pBrushDef = (BrushDefinition*)m_pLineArray[Handle]; 03884 if (pBrushDef == NULL) 03885 { 03886 ERROR3("Brush definition is NULL"); 03887 return FALSE; 03888 } 03889 03890 return pBrushDef->CopyInkTreeToClipboard(); 03891 } 03892 03893 /******************************************************************************************** 03894 03895 > static AttrBrushType* BrushComponent::CreateNode(BrushHandle Handle) 03896 03897 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03898 Created: 6/10/99 03899 Inputs: Handle to the brush definition which we want to base this brush on 03900 Returns: Attribute node based on this definition 03901 Purpose: static version of above 03902 SeeAlso: - 03903 03904 ********************************************************************************************/ 03905 03906 AttrBrushType* BrushComponent::CreateNode(BrushHandle Handle) 03907 { 03908 BrushDefinition* pBrushDef = FindBrushDefinition(Handle); 03909 if (pBrushDef == NULL) 03910 return NULL; 03911 03912 AttrBrushType* pNewNode = new AttrBrushType; 03913 if (pNewNode == NULL) 03914 return NULL; 03915 03916 BrushAttrValue* pVal = (BrushAttrValue*)pNewNode->GetAttributeValue(); 03917 if (pVal == NULL) 03918 return NULL; 03919 03920 PathProcessorBrush* pPathProc = new PathProcessorBrush; 03921 if (pPathProc == NULL) 03922 return NULL; 03923 pBrushDef->CopyDataToProcessor(pPathProc); 03924 pVal->SetPathProcessor(pPathProc); 03925 03926 // tell it which brush definition to use 03927 pPathProc->SetBrushDefinition(Handle); 03928 return pNewNode; 03929 } 03930 03931 03932 /******************************************************************************************** 03933 03934 > BOOL BrushComponent::StartExport(BaseCamelotFilter *pFilter) 03935 03936 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03937 Created: 13/12/99 03938 03939 Inputs: pFilter - the BaseCamelotFilter filter that is being used to export a file. 03940 Returns: TRUE if the component was able to prepare for exporting; 03941 FALSE if not (e.g. out of memory) 03942 03943 Purpose: Called before an export is started 03944 03945 ********************************************************************************************/ 03946 03947 BOOL BrushComponent::StartExport(BaseCamelotFilter *pFilter) 03948 { 03949 // return TRUE; // for now 03950 #if !defined(EXCLUDE_FROM_RALPH) 03951 03952 if (pFilter == NULL) 03953 { 03954 ERROR3("BrushComponent::StartExport filter is null!"); 03955 return(TRUE); 03956 } 03957 03958 // ****!!!!TODO - if we're multi-threadig, this probably needs to be a critical section 03959 // because the list is global 03960 03961 // Flag all Brushs as not having been saved. When we save one, we set its flag so that 03962 // we don't try to save it a second time. 03963 if (m_pLineArray != NULL) 03964 { 03965 for (UINT32 Index = 0; Index < m_Used; Index++) 03966 { 03967 if (m_pLineArray[Index] != NULL) 03968 m_pLineArray[Index]->SetIOStore(FALSE); 03969 } 03970 03971 // Write out an atomic tag definition in front of the vector Brush definition. 03972 // ****!!!!TODO - This should really only be done just before we export the first 03973 // BrushDEFINITION tag, but it is not properly supported by the export system as yet. 03974 03975 //TODO : Make tags for brush components!! 03976 03977 BOOL ok = TRUE; 03978 CXaraFileRecord Rec(TAG_ATOMICTAGS, TAG_ATOMICTAGS_SIZE); 03979 if (ok) ok = Rec.Init(); 03980 if (ok) ok = Rec.WriteUINT32(TAG_BRUSHDEFINITION); 03981 if (ok) pFilter->Write(&Rec); // And write out the record 03982 03983 } 03984 #endif 03985 return(TRUE); 03986 } 03987 03988 03989 /******************************************************************************************** 03990 03991 > static BOOL ImportLine(CXaraFileRecord* pRecord) 03992 03993 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 03994 Created: 13/12/99 03995 03996 Inputs: pRecord - The TAG_BRUSHDEFINITION record to import 03997 03998 Returns: TRUE if Import was successful 03999 04000 Purpose: To import a vector Line definition 04001 04002 ********************************************************************************************/ 04003 04004 BOOL BrushComponent::StartImportBrush(CamelotRecordHandler *pHandler, CXaraFileRecord *pRecord, 04005 UINT32 ImportHandle) 04006 { 04007 m_ImportHandle = 0xffffffff; 04008 04009 if (m_pImportPreviousContext != NULL) 04010 { 04011 // delete m_pImportPreviousContext; 04012 m_pImportPreviousContext = NULL; 04013 } 04014 04015 if (m_pImportNewLine != NULL) 04016 { 04017 m_pImportNewLine->CascadeDelete(); 04018 m_pImportNewLine = NULL; 04019 } 04020 04021 // Create a spread and set up the import system to import the brush into it 04022 // If this fails, then it'll just find somewhere "sensible" to import into 04023 m_pImportNewLine = new Spread; 04024 if (m_pImportNewLine == NULL) 04025 return(FALSE); 04026 04027 Layer *pLineLayer = new Layer(m_pImportNewLine, FIRSTCHILD, String_256(TEXT("Jason did this"))); 04028 if (pLineLayer == NULL) 04029 { 04030 delete m_pImportNewLine; 04031 m_pImportNewLine = NULL; 04032 return(FALSE); 04033 } 04034 04035 // Now, remember where we were importing into, and point the importer at our brush tree 04036 m_pImportPreviousContext = pHandler->GetInsertContext(); 04037 pHandler->SetInsertContextNode(pLineLayer); 04038 04039 // check to see if our import brushdef already exists, if so delete it 04040 if (m_pImportBrushDef != NULL) 04041 delete m_pImportBrushDef; 04042 // make the new brush definition 04043 m_pImportBrushDef = new BrushDefinition(m_pImportNewLine); 04044 if (m_pImportBrushDef == NULL) 04045 return(FALSE); 04046 04047 04048 04049 // Remember the handle used for the Brush in the file with the Brush so that 04050 // we can map any incoming handles into the real handles we are using internally. 04051 m_pImportBrushDef->SetIOStore(ImportHandle & 0x00ffffff); 04052 04053 04054 /* in case you were wondering, after this function the import goes as follows: 04055 - Ink nodes etc. are imported into m_pImportNewLine 04056 - Brush data is imported 04057 - EndImportBrush is called, where the new brush definition is inserted 04058 */ 04059 04060 04061 04062 return(TRUE); 04063 } 04064 04065 04066 /******************************************************************************************** 04067 04068 > BOOL BrushComponent::EndImportBrush(CamelotRecordHandler *pHandler); 04069 04070 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 04071 Created: 13/12/99 04072 04073 Inputs: pRecord - The TAG_BRUSHDEFINITION record to import 04074 04075 Returns: TRUE if Import was successful 04076 04077 Purpose: To import a vector brush definition 04078 04079 ********************************************************************************************/ 04080 04081 BOOL BrushComponent::EndImportBrush(CamelotRecordHandler *pHandler) 04082 { 04083 ERROR2IF(m_pImportPreviousContext == NULL,FALSE, "EndImportBrush - something hasn't gone too well"); 04084 ERROR2IF(m_pImportBrushDef == NULL, FALSE, "ImportBrushDef is NULL at EndImportBrush"); 04085 04086 // Restore the previous import context node 04087 pHandler->RestoreInsertContext(m_pImportPreviousContext); 04088 delete m_pImportPreviousContext; 04089 m_pImportPreviousContext = NULL; 04090 04091 // --- Now, convert all IndexedColours (which are document-dependent) into standalone DocColours 04092 // This wouldn't be necessary, except that the DocColours we saved have magically been turned 04093 // back into local Indexedcolours by the export/import process. 04094 // BLOCK 04095 04096 LineDefinition::ConvertIndexedColours((Spread*)m_pImportNewLine); 04097 04098 // Create a new Brush definition from the imported brush 04099 if (m_pImportBrushDef->GenerateBrush() != TRUE) 04100 return FALSE; 04101 04102 m_pImportBrushDef->CalculateMaxScaling(); 04103 04104 // add the item, 04105 /*BrushHandle NewHandle =*/ AddNewItem(m_pImportBrushDef); 04106 04107 CleanUpAfterImport(); 04108 04109 return TRUE; 04110 04111 04112 } 04113 04114 04115 04116 04117 04118 04119 /******************************************************************************************** 04120 04121 > BOOL ExportBrush(BaseCamelotFilter *pFilter, BrushHandle Handle) 04122 04123 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 04124 Created: 22/12/99 04125 04126 Inputs: pFilter - the BaseCamelotFilter filter that is being used to export a file. 04127 Handle - The Brush to be exported 04128 04129 Returns: TRUE if export was successful 04130 FALSE if export was aborted - no error is set, as in this case, it usually 04131 means that the Brush has been deleted, and is being treated as an old-style 04132 line. In this case, the caller should simply not bother exporting the 04133 attribute using the Brush definition. 04134 04135 Purpose: To export a vector Brush definition. 04136 04137 Notes: Brush definitions (like colours) are only saved out when a node in the 04138 tree is found which makes use of the Brush. You should call this function 04139 before exporting any attribute which uses the Brush definition. It 04140 automatically checks if the Brush has already been saved, and will not save 04141 the definition more than once. 04142 04143 When saving your reference to the Brush, save out the Brush's Handle 04144 as it's unique ID word. 04145 04146 ********************************************************************************************/ 04147 04148 BOOL BrushComponent::ExportLine(BaseCamelotFilter *pFilter, BrushHandle Handle) 04149 { 04150 ERROR3IF(pFilter == NULL, "Illegal NULL params"); 04151 04152 // Find the stroke, and baulk if it's all gone wrong 04153 BrushDefinition *pBrush = FindBrushDefinition(Handle); 04154 if (pBrush == NULL) 04155 { 04156 ERROR3("Attempt to save a deleted or non-existent stroke"); 04157 return(FALSE); 04158 } 04159 04160 // Check if the definition has already been saved, in which case we don't need to do anything more 04161 if (pBrush->ReadIOStore()) 04162 return(TRUE); 04163 04164 // We've got a stroke definition now, get it to write itself to the file 04165 return pBrush->ExportBrush(pFilter, Handle); 04166 04167 } 04168 04169 04170 /******************************************************************************************** 04171 04172 > static BrushHandle BrushComponent::FindImportedBrush(UINT32 ImportedHandle) 04173 04174 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 04175 Created: 22/12/99 04176 04177 Inputs: Importedhandle - The handle which is used in the file being imported 04178 to reference the stroke. 04179 04180 Returns: The BrushHandle of the loaded stroke, or BrushHandle_NoBrush 04181 if the stroke could not be found. 04182 04183 Purpose: To match up a handle from the currently importing file to the 04184 real internal BrushHandle of the imported BrushDefinition 04185 04186 ********************************************************************************************/ 04187 04188 BrushHandle BrushComponent::FindImportedBrush(UINT32 ImportedHandle) 04189 { 04190 ImportedHandle &= 0x00ffffff; // Only the bottom 24 bits are relevant 04191 for (UINT32 Index = 0; Index < m_Used; Index++) 04192 { 04193 if (m_pLineArray[Index] != NULL && m_pLineArray[Index]->ReadIOStore() == ImportedHandle) 04194 return((BrushHandle)Index); 04195 } 04196 04197 return(BrushHandle_NoBrush); 04198 } 04199 04200 04201 04202 /******************************************************************************************** 04203 04204 > static BrushDefinition *BrushComponent::FindBrushDefinition(UINT32 Handle, BOOL IncludeDeactiveated); 04205 04206 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 04207 Created: 13/12/99 04208 04209 Inputs: Handle - A handle which uniquely identifies the new stroke 04210 IncludeDeactivated - flag to say that we wish to include deactivated definitions, 04211 defaults to false 04212 Returns: A pointer to a StrokeDefinition for that Stroke. 04213 If the stroke has been deleted, NULL will be returned, in which case, 04214 you should gracefully degrade (by rendering an old style Brush in place of 04215 the stroke) 04216 04217 Purpose: Find a Brush definition, given its unique identity handle 04218 04219 ********************************************************************************************/ 04220 04221 BrushDefinition *BrushComponent::FindBrushDefinition(BrushHandle Handle, BOOL IncludeDeactivated) 04222 { 04223 if (Handle < 0) 04224 { 04225 ERROR3("Negative brush handle"); 04226 return NULL; 04227 } 04228 if (Handle == BrushHandle_NoBrush) 04229 return(NULL); 04230 04231 if (Handle >= m_Used) 04232 { 04233 ERROR3("Out of range Brush handle"); 04234 return(NULL); 04235 } 04236 04237 BrushDefinition* pDef = ((BrushDefinition*)m_pLineArray[Handle]); 04238 04239 if (!pDef->IsActivated() && !IncludeDeactivated) 04240 pDef = NULL; 04241 04242 return pDef; 04243 } 04244 04245 04246 /****************************************************************************************** 04247 04248 > static BOOL BrushComponent::ExpandArray(void) 04249 04250 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 04251 Created: 28/2/97 04252 04253 Outputs: On succesful exit, the member array of BrushDefinition pointers will be bigger 04254 Returns: FALSE if it failed to allocate memory 04255 04256 Purpose: (Internal method) 04257 Expands the storage structure of the Brush list to allow more entries to be 04258 used. Called automatically by AddNewBrush as necessary. 04259 04260 Notes: Internal storage is an array of pointers to BrushDefinitions 04261 NULL pointers beyond (& including) "Used" indicate free slots. 04262 NULL pointers before "Used" indicate deleted Brushs - these slots 04263 should NOT be re-used, as there may still be references to them in 04264 the system. 04265 04266 ******************************************************************************************/ 04267 04268 BOOL BrushComponent::ExpandArray(void) 04269 { 04270 // ****!!!!TODO - if we're multi-threading, this probably needs to be a critical section 04271 // because the list is global 04272 04273 const INT32 AllocSize = m_CurrentSize + 64; 04274 04275 if (m_pLineArray == NULL) 04276 { 04277 m_pLineArray = (LineDefinition **) CCMalloc(AllocSize * sizeof(LineDefinition *)); 04278 if (m_pLineArray == NULL) 04279 return(FALSE); 04280 } 04281 else 04282 { 04283 // We have an array - we must make it larger 04284 LineDefinition **pNewBuf = (LineDefinition **) 04285 CCRealloc(m_pLineArray, AllocSize * sizeof(LineDefinition *)); 04286 if (pNewBuf == NULL) 04287 return(FALSE); 04288 04289 m_pLineArray = pNewBuf; 04290 } 04291 04292 // Success. Initalise all the new pointers to NULL 04293 for (UINT32 i = m_Used; i < m_CurrentSize; i++) 04294 m_pLineArray[i] = NULL; 04295 04296 // Update the current size value, and return success 04297 m_CurrentSize = (UINT32)AllocSize; 04298 return(TRUE); 04299 04300 04301 } 04302 04303 04304 04305 04306 /******************************************************************************************** 04307 04308 > BrushDefinition *BrushComponent::GetImportedBrushDefinition() 04309 04310 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 04311 Created: 13/12/99 04312 Inputs: - 04313 Returns: A pointer to the brush definition that is currently in the process of being 04314 imported. 04315 04316 Purpose: As above, note that this function is only useful in the period between 04317 StartImportBrush and EndImportBrush being called. At all other times 04318 m_pImportBrushDef should be NULL. 04319 04320 ********************************************************************************************/ 04321 04322 BrushDefinition* BrushComponent::GetImportBrushDefinition() 04323 { 04324 return m_pImportBrushDef; 04325 } 04326 04327 04328 04329 /******************************************************************************************** 04330 04331 > void BrushComponent::CleanUpAfterImport() 04332 04333 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 04334 Created: 13/12/99 04335 Inputs: - 04336 Returns: - 04337 04338 Purpose: Deletes the objects we created for import. Goes without saying that 04339 calling this function before you have added the brushdef to the component is 04340 pretty silly. 04341 04342 ********************************************************************************************/ 04343 04344 void BrushComponent::CleanUpAfterImport() 04345 { 04346 // don't delete the brushdef as it is now being used in the component 04347 if (m_pImportBrushDef != NULL) 04348 m_pImportBrushDef = NULL; 04349 04350 if (m_pImportNewLine != NULL) 04351 m_pImportNewLine = NULL; 04352 } 04353 04354 04355 /******************************************************************************************** 04356 04357 > void BrushDefinition::CopyDataToPathProcessor(PathProcessorBrush* pPathProc) 04358 04359 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 04360 Created: 6/10/99 04361 Inputs: pPathProc - path processor to receive the data 04362 Returns: - 04363 Purpose: To copy all of the numeric data about this brush to a path processor 04364 SeeAlso: - 04365 04366 ********************************************************************************************/ 04367 04368 void BrushDefinition::CopyDataToProcessor(PathProcessorBrush* pPathProc) 04369 { 04370 if (pPathProc == NULL) 04371 { 04372 ERROR3("Path processor is NULL"); 04373 return; 04374 } 04375 04376 // spacing members 04377 pPathProc->SetSpacing(m_BrushSpacing); 04378 pPathProc->SetSpacingIncrProp(m_BrushSpacingIncrProp); 04379 pPathProc->SetSpacingIncrConst(m_BrushSpacingIncrConst); 04380 pPathProc->SetSpacingMaxRand(m_BrushSpacingMaxRand); 04381 pPathProc->SetSpacingRandSeed(m_BrushSpacingRandSeed); 04382 04383 // offset members 04384 pPathProc->SetPathOffsetType(m_PathOffsetType); 04385 pPathProc->SetPathOffsetValue(m_PathOffsetValue); 04386 pPathProc->SetPathOffsetIncrConst(m_PathOffsetIncrConst); 04387 pPathProc->SetPathOffsetIncrProp(m_PathOffsetIncrProp); 04388 pPathProc->SetOffsetTypeRandSeed(m_OffsetTypeRandSeed); 04389 pPathProc->SetOffsetValueMaxRand(m_OffsetValueMaxRand); 04390 pPathProc->SetOffsetValueRandSeed(m_OffsetValueRandSeed); 04391 04392 04393 // scaling members 04394 pPathProc->SetBrushScaling(m_BrushScaling); 04395 pPathProc->SetScalingMaxRand(m_BrushScalingMaxRand); 04396 pPathProc->SetScalingRandSeed(m_BrushScalingRandSeed); 04397 pPathProc->SetScalingMaxPressure(m_ScalingMaxPressure); 04398 pPathProc->SetMaxScaling(m_MaxScaling); 04399 pPathProc->SetBrushScalingIncr(m_BrushScalingIncr); 04400 pPathProc->SetBrushScalingIncrConst(m_BrushScalingIncrConst); 04401 04402 04403 // rotation 04404 pPathProc->SetRotationMaxRand(m_RotationMaxRand); 04405 pPathProc->SetRotationRandSeed(m_RotationRandSeed); 04406 pPathProc->SetRotationIncrConst(m_RotAngleIncrConst); 04407 pPathProc->SetRotationIncrProp(m_RotAngleIncrProp); 04408 pPathProc->SetRotationMaxPressure(m_RotationMaxPressure); 04409 pPathProc->SetRotationAngle(m_RotateAngle); 04410 04411 04412 // sequence 04413 pPathProc->SetSequenceType(m_SequenceType); 04414 pPathProc->SetSequenceSeed(m_SequenceRandSeed); 04415 04416 // Hue/Saturation 04417 pPathProc->SetHueIncrement(m_BrushHueIncrement); 04418 pPathProc->SetHueMaxRand(m_BrushHueMaxRand); 04419 pPathProc->SetHueRandSeed(m_BrushHueRandSeed); 04420 pPathProc->SetSatIncrement(m_BrushSatIncrement); 04421 pPathProc->SetSatMaxRand(m_BrushSatMaxRand); 04422 pPathProc->SetSatRandSeed(m_BrushSatRandSeed); 04423 04424 // Transparency 04425 pPathProc->SetBrushTransparency(m_BrushTransparency); 04426 pPathProc->SetTransparencyPressure(m_TranspMaxPressure); 04427 04428 // Other 04429 pPathProc->SetRotated(m_bRotate); 04430 pPathProc->SetTiling(m_bTile); 04431 } 04432 04433 04434 /******************************************************************************************** 04435 04436 > static LineHandle LineComponent::AddNewItem(LineDefinition *pLine, BOOL AskName = FALSE) 04437 04438 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 04439 Created: 13/12/99 04440 04441 Inputs: pLine - (may not be NULL) A Line definition to add, which now 04442 belongs to the LineComponent, so you mustn't delete it! 04443 AskName - a flag saying whether or not we should prompt the user for a name, 04444 defaults to FALSE 04445 Returns: A handle which uniquely identifies the new Line, or 04446 LineHandle_NoLine if we ran out of memory for storing Lines 04447 04448 Purpose: Adds the given Line to the global Line list. 04449 04450 Notes: Also read the notes in LineComponent::AddNewItem 04451 This function overrides the base class but actually uses it 04452 to do the actual adding. functinality added here is that 04453 it works out whether or not the brush has actually been added 04454 and if so adds it to the line gallery 04455 04456 ********************************************************************************************/ 04457 04458 LineHandle BrushComponent::AddNewItem(LineDefinition *pItem, BOOL AskName) 04459 { 04460 // just make sure its the right type 04461 ERROR2IF(!pItem->IsKindOf(CC_RUNTIME_CLASS(BrushDefinition)), 04462 BrushHandle_NoBrush, "Attempting to pass in wrong definition"); 04463 String_32 DefaultName(_R(IDS_BRUSH_DEFAULT_NAME)); 04464 m_NewName = DefaultName; 04465 m_bCancelNewBrush = FALSE; 04466 if (AskName == TRUE) 04467 { 04468 // launch the naming dialog, it will either set m_NewName or tell us to cancel 04469 OpDescriptor* pDesc = OpDescriptor::FindOpDescriptor( OPTOKEN_INITNAME_BRUSH_DLG ); 04470 if (pDesc != NULL) 04471 { 04472 pDesc->Invoke(); 04473 } 04474 04475 // did they cancel it? 04476 if (m_bCancelNewBrush) 04477 { 04478 m_bCancelNewBrush = FALSE; 04479 return BrushHandle_NoBrush; 04480 } 04481 04482 pItem->SetLineName(&m_NewName); 04483 } 04484 04485 // stash the old number of brushes, which will be incremented if we make a new one 04486 UINT32 OldNumBrushes = m_Used; 04487 04488 // item is added in the base class 04489 LineHandle NewHandle = LineComponent::AddNewItem(pItem); 04490 04491 // have we actually added a new brush? 04492 if (NewHandle >= OldNumBrushes && NewHandle != BrushHandle_NoBrush) 04493 { 04494 // tell it the filename ID 04495 ((BrushDefinition*)pItem)->SetBrushFileID(m_CurrentDefaultFile); 04496 04497 // make a new atttibute to add to the line gallery 04498 PathProcessorBrush* pNewPathProc = new PathProcessorBrush; 04499 if (pNewPathProc == NULL) 04500 { 04501 ERROR3("Failed to allocate path processor"); 04502 return NewHandle; 04503 } 04504 04505 // tell it which brush definition to use 04506 pNewPathProc->SetBrushDefinition(NewHandle); 04507 04508 // transfer all the data 04509 ((BrushDefinition*)pItem)->CopyDataToProcessor(pNewPathProc); 04510 // make a new attribute value for use by the line gallery 04511 BrushAttrValue* pVal = new BrushAttrValue(pNewPathProc); 04512 if (pVal == NULL) 04513 { 04514 ERROR3("Unable to allocate new BrushAttrVal"); 04515 return NewHandle; 04516 } 04517 04518 // add it to the line gallery 04519 LineGallery::AddNewBrushItem(pVal); 04520 04521 // get the freehand tool 04522 ToolListItem* pToolItem = Tool::Find(TOOLID_FREEHAND); 04523 ERROR2IF(pToolItem == NULL, NewHandle, "Unable to get tool item in DeactivateBrushDefAction::Init"); 04524 04525 FreeHandTool* pTool = (FreeHandTool*)pToolItem->m_pTool; 04526 ERROR2IF(pTool == NULL, NewHandle, "Unable to get tool in DeactivateBrushDefAction::Init"); 04527 04528 // get the infobar 04529 FreeHandInfoBarOp* pInfoBar = ((FreeHandTool*)pTool)->GetInfoBar(); 04530 ERROR2IF(pInfoBar == NULL, NewHandle, "Unable to get InfoBar in DeactivateBrushDefAction::Init"); 04531 04532 // add to the freehand infobar 04533 pInfoBar->AddBrush(NewHandle); 04534 } 04535 return NewHandle; 04536 } 04537 04538 04539 /******************************************************************************************** 04540 04541 > String_32 BrushComponent::GetUniqueName() 04542 04543 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 04544 Created: 13/12/99 04545 Inputs: pName - the name that we wish to use, defaults to NULL in which 04546 case we use the default name 04547 Returns: A unique name which can be given to the brush 04548 04549 Purpose: When naming a new brush we want to give it the name supplied, 04550 however this may well be taken in which case we want to add 04551 a number to the default name 04552 04553 ********************************************************************************************/ 04554 04555 String_32 BrushComponent::GetUniqueName(String_32* pName) 04556 { 04557 // essentially what we're doing is going through all the brush definitions and 04558 // retrieving the portion of name that will could be equal to the default name. 04559 // We count the number of default names that we find and once we're finished 04560 // we use this as the suffix for the new name 04561 04562 // Get the default name from the resources 04563 String_32 DefaultName(_R(IDS_BRUSH_DEFAULT_NAME)); 04564 04565 if (pName == NULL) 04566 pName = &DefaultName; 04567 04568 INT32 DefaultSize = pName->Length(); 04569 04570 BrushDefinition* pDef = NULL; 04571 String_32* pDefName = NULL; 04572 String_32 LeftMost; 04573 UINT32 Counter = 0; 04574 INT32 DefaultCounter = 0; 04575 04576 // loop though the definitions 04577 while (Counter < m_Used) 04578 { 04579 pDef = FindBrushDefinition(Counter); 04580 if (pDef != NULL) 04581 { 04582 pDefName = pDef->GetLineName(); 04583 if (pDefName == NULL) 04584 { 04585 ERROR3("Brush definition with no name in BrushComponent::GetUniqueName"); 04586 break; 04587 } 04588 // test to see if the leftmost portion of the name is the same as our default 04589 pDefName->Left(&LeftMost, DefaultSize); 04590 if (LeftMost.IsIdentical(*pName)) 04591 DefaultCounter++; 04592 04593 LeftMost.Empty(); // wipe the default 04594 } 04595 Counter++; 04596 } 04597 04598 String_32 UniqueName(*pName); 04599 04600 // do we have to concatenate a number? 04601 if (DefaultCounter > 0) 04602 { 04603 String_32 Concat; 04604 Convert::LongToString(DefaultCounter, &Concat); 04605 UniqueName+=Concat; 04606 } 04607 return UniqueName; 04608 } 04609 04610 04611 04612 04613 /******************************************************************************************** 04614 04615 > BOOL LineComponent::NameIsUnique(const String_32& NameString) 04616 04617 Author: Diccon_Yamanaka (Xara Group Ltd) <camelotdev@xara.com> 04618 Created: 3/7/2000 04619 04620 Inputs: NameString - the string to test 04621 Returns: TRUE if none of the definitions in the component have this string as their name, 04622 FALSE if one of them does 04623 04624 Purpose: To find out if someone has already gotten this name 04625 04626 ********************************************************************************************/ 04627 04628 BOOL BrushComponent::NameIsUnique(const String_32& NameString) 04629 { 04630 if (NameString.IsEmpty()) 04631 ERROR3("Empty string in BrushComponent::NameIsUnique"); 04632 04633 BOOL Unique = TRUE; 04634 UINT32 Counter = 0; 04635 String_32* pDefName = NULL; 04636 BrushDefinition* pDef = NULL; 04637 while (Counter < m_Used) 04638 { 04639 pDef = FindBrushDefinition(Counter); 04640 if (pDef != NULL) 04641 { 04642 pDefName = pDef->GetLineName(); 04643 if( pDefName != NULL ) 04644 { 04645 if (NameString == *pDefName) 04646 { 04647 Unique = FALSE; 04648 break; 04649 } 04650 } 04651 } 04652 Counter++; 04653 } 04654 return Unique; 04655 04656 } 04657 04658 void BrushComponent::SetNewName(String_32 NewName) 04659 { 04660 m_NewName = NewName; 04661 } 04662 04663 void BrushComponent::CancelNewBrush() 04664 { 04665 m_bCancelNewBrush = TRUE; 04666 }