00001 // $Id: attr.cpp 1361 2006-06-25 16:43:38Z alex $ 00002 /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE 00003 ================================XARAHEADERSTART=========================== 00004 00005 Xara LX, a vector drawing and manipulation program. 00006 Copyright (C) 1993-2006 Xara Group Ltd. 00007 Copyright on certain contributions may be held in joint with their 00008 respective authors. See AUTHORS file for details. 00009 00010 LICENSE TO USE AND MODIFY SOFTWARE 00011 ---------------------------------- 00012 00013 This file is part of Xara LX. 00014 00015 Xara LX is free software; you can redistribute it and/or modify it 00016 under the terms of the GNU General Public License version 2 as published 00017 by the Free Software Foundation. 00018 00019 Xara LX and its component source files are distributed in the hope 00020 that it will be useful, but WITHOUT ANY WARRANTY; without even the 00021 implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 00022 See the GNU General Public License for more details. 00023 00024 You should have received a copy of the GNU General Public License along 00025 with Xara LX (see the file GPL in the root directory of the 00026 distribution); if not, write to the Free Software Foundation, Inc., 51 00027 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00028 00029 00030 ADDITIONAL RIGHTS 00031 ----------------- 00032 00033 Conditional upon your continuing compliance with the GNU General Public 00034 License described above, Xara Group Ltd grants to you certain additional 00035 rights. 00036 00037 The additional rights are to use, modify, and distribute the software 00038 together with the wxWidgets library, the wxXtra library, and the "CDraw" 00039 library and any other such library that any version of Xara LX relased 00040 by Xara Group Ltd requires in order to compile and execute, including 00041 the static linking of that library to XaraLX. In the case of the 00042 "CDraw" library, you may satisfy obligation under the GNU General Public 00043 License to provide source code by providing a binary copy of the library 00044 concerned and a copy of the license accompanying it. 00045 00046 Nothing in this section restricts any of the rights you have under 00047 the GNU General Public License. 00048 00049 00050 SCOPE OF LICENSE 00051 ---------------- 00052 00053 This license applies to this program (XaraLX) and its constituent source 00054 files only, and does not necessarily apply to other Xara products which may 00055 in part share the same code base, and are subject to their own licensing 00056 terms. 00057 00058 This license does not apply to files in the wxXtra directory, which 00059 are built into a separate library, and are subject to the wxWindows 00060 license contained within that directory in the file "WXXTRA-LICENSE". 00061 00062 This license does not apply to the binary libraries (if any) within 00063 the "libs" directory, which are subject to a separate license contained 00064 within that directory in the file "LIBS-LICENSE". 00065 00066 00067 ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS 00068 ---------------------------------------------- 00069 00070 Subject to the terms of the GNU Public License (see above), you are 00071 free to do whatever you like with your modifications. However, you may 00072 (at your option) wish contribute them to Xara's source tree. You can 00073 find details of how to do this at: 00074 http://www.xaraxtreme.org/developers/ 00075 00076 Prior to contributing your modifications, you will need to complete our 00077 contributor agreement. This can be found at: 00078 http://www.xaraxtreme.org/developers/contribute/ 00079 00080 Please note that Xara will not accept modifications which modify any of 00081 the text between the start and end of this header (marked 00082 XARAHEADERSTART and XARAHEADEREND). 00083 00084 00085 MARKS 00086 ----- 00087 00088 Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara 00089 designs are registered or unregistered trademarks, design-marks, and/or 00090 service marks of Xara Group Ltd. All rights in these marks are reserved. 00091 00092 00093 Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. 00094 http://www.xara.com/ 00095 00096 =================================XARAHEADEREND============================ 00097 */ 00098 00099 // The basic Camelot attributes 00100 00101 /* 00102 */ 00103 00104 #include "camtypes.h" 00105 00106 00107 //#include "attr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00108 #include "lineattr.h" 00109 #include "userattr.h" 00110 //#include "ink.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00111 //#include "fillattr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00112 //#include "attrmgr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00113 #include "blendatt.h" 00114 #include "pathstrk.h" 00115 00116 //#include "will2.h" 00117 00118 DECLARE_SOURCE("$Revision: 1361 $"); 00119 00120 CC_IMPLEMENT_DYNAMIC(AttributeValue, CCObject); 00121 CC_IMPLEMENT_DYNCREATE(DashRec, CCObject); 00122 00123 CC_IMPLEMENT_DYNCREATE(LineWidthAttribute, AttributeValue); 00124 CC_IMPLEMENT_DYNCREATE(StartArrowAttribute, AttributeValue); 00125 CC_IMPLEMENT_DYNCREATE(EndArrowAttribute, AttributeValue); 00126 CC_IMPLEMENT_DYNCREATE(StartCapAttribute, AttributeValue); 00127 CC_IMPLEMENT_DYNCREATE(JoinTypeAttribute, AttributeValue); 00128 CC_IMPLEMENT_DYNCREATE(MitreLimitAttribute, AttributeValue); 00129 CC_IMPLEMENT_DYNCREATE(WindingRuleAttribute, AttributeValue); 00130 CC_IMPLEMENT_DYNCREATE(DashPatternAttribute, AttributeValue); 00131 CC_IMPLEMENT_DYNCREATE(DrawingModeAttribute, AttributeValue); 00132 CC_IMPLEMENT_DYNCREATE(UserAttribute, AttributeValue); 00133 00134 CC_IMPLEMENT_MEMDUMP(BlendAttrParam, CC_CLASS_MEMDUMP); 00135 00136 // Declare smart memory handling in Debug builds 00137 #define new CAM_DEBUG_NEW 00138 00139 /******************************************************************************************** 00140 00141 > virtual void AttributeValue::Restore(RenderRegion *pRegion, BOOL Temporary) 00142 00143 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00144 Created: 03/02/94 00145 Inputs: pRegion - the render region to restore the attribute into. 00146 Temporary - TRUE if this is a temporary attribute, FALSE if it is 00147 permanent (e.g. it's in a document tree). 00148 Purpose: Used when restoring attributes from the render region's context stack. 00149 00150 This changes the relevant current rendering attribute to be that described 00151 by this AttributeValue object. 00152 00153 The Temporary flag controls what is done with this object when it is no 00154 longer needed by the stack - i.e. the next time an attribute of this type 00155 is restored from the stack, this attribute value will no longer be 00156 referenced, and so if the Temporary flag is TRUE (i.e. this object was 00157 created to satisfy a direct attribute manipulation request as opposed to 00158 rendering an attribute from a Camelot document tree), then the object is 00159 deleted. 00160 00161 NB. This is a pure virtual function - any attribute value derived from 00162 this class must implement this function so that it restores the 00163 render region's attribute variables and objects to the correct state. 00164 00165 SeeAlso: RenderStack; AttributeValue; NodeAttribute; 00166 AttributeValue::Render; AttributeValue::SimpleCopy 00167 00168 ********************************************************************************************/ 00169 00170 /******************************************************************************************** 00171 00172 > virtual void AttributeValue::Render(RenderRegion *pRegion) 00173 00174 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00175 Created: 03/02/94 00176 Inputs: pRegion - the render region to render this attribute into. 00177 Purpose: Used when a render region needs to change a particular rendering attribute. 00178 00179 This usually occurs either because a tree is being rendered, and an 00180 attribute node has been encountered and hence needs to be rendered, or 00181 because a RenderRegion client (or sometimes the RenderRegion itself) has 00182 asked to change an attribute directly, by name, as it were. Examples of the 00183 latter case might be: 00184 00185 MonoOn 00186 pRegion->SetFillColour(COLOUR_BLACK); 00187 pRegion->SetLineWidth(300); 00188 pRegion->SetDrawingMode(DM_EORPEN); 00189 MonoOff 00190 00191 NB. This is a pure virtual function - any attribute value derived from 00192 this class must implement this function so that it sets the 00193 render region's attribute variables and objects to the correct state. 00194 00195 SeeAlso: RenderStack; AttributeValue; NodeAttribute; 00196 AttributeValue::Restore; AttributeValue::SimpleCopy 00197 00198 ********************************************************************************************/ 00199 00200 /******************************************************************************************** 00201 00202 > virtual void AttributeValue::SimpleCopy(AttributeValue *pAttr) 00203 00204 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00205 Created: 03/02/94 00206 Inputs: pAttr - pointer to the AttributeValue to copy. 00207 Purpose: This function provides a way of copying the contents of an AttributeValue 00208 derived class to another. It is assumed that the source object is the 00209 same class as the destination object. 00210 The data from the object pointed to by pAttr is copied into this object. 00211 This is primarily used when cloning render regions - the context stack 00212 must be copied, and if it points to any temporary objects, then they 00213 must be copied too, to avoid multiple deletion errors. 00214 SeeAlso: RenderStack; AttributeValue; NodeAttribute; 00215 AttributeValue::Render; AttributeValue::Restore 00216 00217 ********************************************************************************************/ 00218 00219 00220 /******************************************************************************************** 00221 00222 > NodeAttribute *AttributeValue::MakeNode() 00223 00224 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00225 Created: 11/04/94 00226 Returns: Pointer to NodeAttribute object, or NULL if out of memory. 00227 Purpose: Given an AttributeValue object, construct the appropriate NodeAttribute 00228 object which can be put into a document tree. 00229 This should be over-ridden for all derived AttributeValue classes, except 00230 those that cannot be put into the document tree (e.g. DrawingModeAttribute). 00231 The base class version (i.e. this one) will always ENSURE because it 00232 should not be called. 00233 Errors: Out of memory. 00234 SeeAlso: NodeAttribute 00235 00236 ********************************************************************************************/ 00237 00238 NodeAttribute* AttributeValue::MakeNode() 00239 { 00240 TRACE( wxT("Error - Base class MakeNode() function called for a %s\n"), 00241 GetRuntimeClass()->GetClassName() ); 00242 return NULL; 00243 } 00244 00245 00246 /******************************************************************************************** 00247 > NodeAttribute* AttributeValue::MakeNode(Node* pContextNode, AttachNodeDirection Direction) 00248 00249 Author: Ed_Cornes (Xara Group Ltd) <camelotdev@xara.com> 00250 Created: 26/5/95 00251 Inputs: pContextNode - 00252 Direction - 00253 Returns: Pointer to NodeAttribute object, or NULL if out of memory. 00254 Purpose: Convert an attribute value into an attribute node and attatch to the context node 00255 SeeAlso: AttributeValue::MakeNode() 00256 ********************************************************************************************/ 00257 00258 NodeAttribute* AttributeValue::MakeNode(Node* pContextNode, AttachNodeDirection Direction) 00259 { 00260 NodeAttribute* pAttrNode=MakeNode(); 00261 if (pAttrNode!=NULL) 00262 pAttrNode->AttachNode(pContextNode, Direction, FALSE); 00263 return pAttrNode; 00264 } 00265 00266 00267 /******************************************************************************************** 00268 00269 > BOOL AttributeValue::IsDifferent(AttributeValue *pAttr) 00270 00271 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00272 Created: 12/04/94 00273 Inputs: pAttr - the attribute to compare against this one. 00274 Returns: TRUE if objects represent different attributes (e.g. one is red and the 00275 other is blue); 00276 FALSE otherwise (i.e. they represent the same attribute, e.g. both 00277 represent 0.25pt lines). 00278 Purpose: Compare two AttributeValue objects. 00279 The base class version always returns TRUE - derived classes should 00280 override this function to provide functionality. 00281 SeeAlso: AttributeManager::ApplyBasedOnDefaults 00282 00283 ********************************************************************************************/ 00284 00285 BOOL AttributeValue::IsDifferent(AttributeValue*) 00286 { 00287 return TRUE; 00288 } 00289 00290 /******************************************************************************************** 00291 00292 > BOOL AttributeValue::Blend(BlendAttrParam *pBlendParam) 00293 00294 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00295 Created: 26/10/94 00296 Inputs: pBlendParam = ptr to param holding all data needed for the attr val to blend 00297 Outputs: if TRUE returned, pBlendParam->GetBlendedAttrVal() will get ptr to the blended attr val 00298 if FALSE returned, pBlendParam->GetBlendedAttrVal() will return NULL 00299 Returns: TRUE if successful, FALSE otherwaie 00300 Purpose: Blends this attr val with the attr val associated with the other NodeAttribute 00301 ptr held in pBlendParam 00302 This base version just returns FALSE, and sets the blended attr val ptr to NULL 00303 Errors: Errors in debug builds 00304 SeeAlso: - 00305 00306 ********************************************************************************************/ 00307 00308 BOOL AttributeValue::Blend(BlendAttrParam *pBlendParam) 00309 { 00310 ERROR3("AttributeValue::Blend() called"); 00311 pBlendParam->SetBlendedAttrVal(NULL); 00312 return FALSE; 00313 } 00314 00315 00316 /******************************************************************************************** 00317 00318 > virtual AttributeValue *AttributeValue::MouldIntoStroke(PathStrokerVector *pMoulder, 00319 double TransScale); 00320 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00321 Created: 23/2/97 00322 00323 Inputs: pMoulder - A PathStrokerVector which knows how to translate points to "mould" them 00324 (May be NULL, in which case moulding of points does not occur) 00325 00326 TransScale - A fraction between 0.0 and 1.0, by which any transparency 00327 values in this geometry will be scaled, allowing the caller to 00328 effectively apply a flat transparency level to everything that is 00329 moulded. Use 1.0 to leave transparency unaltered. 00330 00331 Returns: NULL if there is no need to mould this attribute (so you should just 00332 render the original attribute), else 00333 A pointer to a copy of this object, suitably moulded and adjusted for 00334 the transparency scaling. The caller must delete the copy when finished 00335 with it. 00336 00337 Purpose: Helper function for the PathStrokerVector class, which "moulds" clipart 00338 subtrees to lie along an arbitrary path. 00339 00340 This function is called to mould attributes, so that: 00341 * Fill/Trans geometries can be moulded 00342 * Line Widths can be scaled to an appropriate value 00343 * A global flat transparency can be applied 00344 etc 00345 00346 Notes: The base class does nothing (it returns NULL - by default, attrs assume that 00347 they will work OK when moulded without being changed) 00348 00349 ********************************************************************************************/ 00350 00351 AttributeValue *AttributeValue::MouldIntoStroke(PathStrokerVector *pMoulder, double TransScale) 00352 { 00353 return(NULL); 00354 } 00355 00356 00357 /******************************************************************************************** 00358 > virtual BOOL AttributeValue::CanBeRenderedDirectly() 00359 Author: Ilan_Copelyn (Xara Group Ltd) <camelotdev@xara.com> 00360 Created: 27/4/00 00361 Inputs: 00362 Outputs: 00363 Returns: 00364 Purpose: There is only one case to date where AttributeValue are rendered directly ie 00365 without calling the render function of their associated/containing NodeAttribute 00366 class. This occurs in RenderRegion::InitDevice(). 00367 This function is to determine if the AttributeValue can be rendered independently 00368 of the NodeAttribute. It is only used in RR::InitDevice() at present but I am 00369 defining it in order to highlight this new characteristic of nodes which are geometry 00370 dependent, in order to ensure that this becomes an acknowledged attribute design 00371 consideration (ie so that these special cases get handled correctly by future code 00372 which may need to render AttributeValues directly) 00373 Errors: 00374 SeeAlso: - 00375 ********************************************************************************************/ 00376 BOOL AttributeValue::CanBeRenderedDirectly() 00377 { 00378 return TRUE; 00379 } 00380 00381 00382 //------------------------------------------------------------ 00383 //------------------------------------------------------------ 00384 //------------------------------------------------------------ 00385 00386 LineWidthAttribute::LineWidthAttribute() 00387 { 00388 LineWidth = 500 + 1; // BODGE The 1 added by Simon 25/10/95, so that the default attr 00389 // is different from the current attr. That way line scaling at 00390 // least works in simple cases. 00391 } 00392 00393 /******************************************************************************************** 00394 00395 > void LineWidthAttribute::Render(RenderRegion *pRegion) 00396 00397 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00398 Created: 03/02/94 00399 Inputs: pRegion - the render region to render this attribute into. 00400 Purpose: Sets the line width attribute for the given render region. i.e. all 00401 lines drawn will now be drawn with this line width. 00402 SeeAlso: LineWidthAttribute; RenderStack; AttributeValue; NodeAttribute; 00403 LineWidthAttribute::Restore; LineWidthAttribute::SimpleCopy; 00404 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy 00405 00406 ********************************************************************************************/ 00407 00408 void LineWidthAttribute::Render(RenderRegion *pRegion, BOOL Temp) 00409 { 00410 pRegion->SetLineWidth(this, Temp); 00411 } 00412 00413 /******************************************************************************************** 00414 00415 > void LineWidthAttribute::Restore(RenderRegion *pRegion, BOOL Temp) 00416 00417 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00418 Created: 03/02/94 00419 Inputs: pRegion - the render region to restore the attribute into. 00420 Temp - TRUE if this is a temporary attribute, FALSE if it is 00421 permanent (e.g. it's in a document tree). 00422 Purpose: Restores the line width attribute for the given render region. i.e. all 00423 lines drawn will now be drawn with this line width. 00424 SeeAlso: LineWidthAttribute; RenderStack; AttributeValue; NodeAttribute; 00425 LineWidthAttribute::Render; LineWidthAttribute::SimpleCopy; 00426 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy 00427 00428 ********************************************************************************************/ 00429 00430 void LineWidthAttribute::Restore(RenderRegion *pRegion, BOOL Temp) 00431 { 00432 pRegion->RestoreLineWidth(this, Temp); 00433 } 00434 00435 /******************************************************************************************** 00436 00437 > void LineWidthAttribute::SimpleCopy(AttributeValue *pValue) 00438 00439 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00440 Created: 03/02/94 00441 Inputs: pAttr - pointer to the AttributeValue to copy. 00442 Purpose: See AttributeValue::SimpleCopy 00443 SeeAlso: LineWidthAttribute; RenderStack; AttributeValue; NodeAttribute; 00444 LineWidthAttribute::Render; LineWidthAttribute::Restore; 00445 AttributeValue::Render; AttributeValue::Restore; AttributeValue::SimpleCopy 00446 00447 ********************************************************************************************/ 00448 00449 void LineWidthAttribute::SimpleCopy(AttributeValue *pValue) 00450 { 00451 LineWidth = ((LineWidthAttribute *) pValue)->LineWidth; 00452 } 00453 00454 /******************************************************************************************** 00455 00456 > BOOL LineWidthAttribute::Init() 00457 00458 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00459 Created: 11/04/94 00460 Returns: TRUE - initialised ok; FALSE if not. 00461 Purpose: Registers line width attribute, and provides a default attribute to give 00462 0.25pt lines. 00463 Errors: Out of memory. 00464 SeeAlso: AttributeManager 00465 00466 ********************************************************************************************/ 00467 00468 BOOL LineWidthAttribute::Init() 00469 { 00470 // Default to 0.25pt lines 00471 LineWidthAttribute *pAttr = new LineWidthAttribute; 00472 if (pAttr == NULL) 00473 return FALSE; 00474 00475 UINT32 ID = AttributeManager::RegisterDefaultAttribute(CC_RUNTIME_CLASS(NodeRenderableInk), 00476 pAttr); 00477 if (ID == ATTR_BAD_ID) 00478 return FALSE; 00479 ENSURE(ID == ATTR_LINEWIDTH, "Incorrect ID for attribute!"); 00480 return TRUE; 00481 } 00482 00483 /******************************************************************************************** 00484 00485 > NodeAttribute *LineWidthAttribute::MakeNode() 00486 00487 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00488 Created: 11/04/94 00489 Returns: Pointer to the new node, or NULL if out of memory. 00490 Purpose: Make a AttrLineWidth node from this line width attribute. 00491 Errors: Out of memory 00492 SeeAlso: AttributeValue::MakeNode 00493 00494 ********************************************************************************************/ 00495 00496 NodeAttribute *LineWidthAttribute::MakeNode() 00497 { 00498 // Create new attribute node 00499 AttrLineWidth *pAttr = new AttrLineWidth(); 00500 00501 // Copy attribute value into the new node. 00502 pAttr->Value.SimpleCopy(this); 00503 00504 // Return the new node 00505 return pAttr; 00506 } 00507 00508 /******************************************************************************************** 00509 00510 > BOOL LineWidthAttribute::IsDifferent(AttributeValue *pAttr) 00511 00512 Author: Tim_Browse (Xara Group Ltd) <camelotdev@xara.com> 00513 Created: 12/04/94 00514 Purpose: See base class version. 00515 Errors: The two attributes are not of the same type. 00516 SeeAlso: AttributeValue::IsDifferent 00517 00518 ********************************************************************************************/ 00519 00520 BOOL LineWidthAttribute::IsDifferent(AttributeValue *pAttr) 00521 { 00522 ENSURE(GetRuntimeClass() == pAttr->GetRuntimeClass(), 00523 "Different attribute types in AttributeValue::IsDifferent()"); 00524 return ((LineWidthAttribute *) pAttr)->LineWidth != LineWidth; 00525 } 00526 00527 /******************************************************************************************** 00528 00529 > BOOL LineWidthAttribute::Blend(BlendAttrParam *pBlendParam) 00530 00531 Author: Mark_Neves (Xara Group Ltd) <camelotdev@xara.com> 00532 Created: 26/10/94 00533 Inputs: pBlendParam = ptr to param holding all data needed for the attr val to blend 00534 Outputs: if TRUE returned, pBlendParam->GetBlendedAttrVal() will get ptr to the blended attr val 00535 if FALSE returned, pBlendParam->GetBlendedAttrVal() will return NULL 00536 Returns: TRUE if successful, FALSE otherwaie 00537 Purpose: Blends this attr val with the attr val held in pBlendParam 00538 SeeAlso: - 00539 00540 ********************************************************************************************/ 00541 00542 BOOL LineWidthAttribute::Blend(BlendAttrParam *pBlendParam) 00543 { 00544 // Check entry param 00545 ERROR3IF(pBlendParam == NULL,"NULL entry param"); 00546 if (pBlendParam == NULL) return FALSE; 00547 00548 LineWidthAttribute* pOtherLineAttr = (LineWidthAttribute*) pBlendParam->GetOtherAttrVal(); 00549 00550 // Check that the other line attr val is not NULL, and is a LineWidthAttribute 00551 ERROR3IF(pOtherLineAttr == NULL,"NULL other attr val"); 00552 ERROR3IF(!IS_A(pOtherLineAttr,LineWidthAttribute),"other attr val not a line width attr"); 00553 if (pOtherLineAttr == NULL || !IS_A(pOtherLineAttr,LineWidthAttribute)) return FALSE; 00554 00555 // Get a new LineWidthAttribute to hold the blended version, (return FALSE if this fails) 00556 LineWidthAttribute* pBlendedLineAttr = new LineWidthAttribute; 00557 if (pBlendedLineAttr == NULL) return FALSE; 00558 00559 // The blended line width is done by linearly tending the start line width to the 00560 // end line width, proportionally to the blend ration (0.0 to 1.0) 00561 00562 // DeltaWidth is the amount to subtract from this LineWidth, and is proportional to BlendRatio 00563 MILLIPOINT DeltaWidth = INT32((LineWidth - pOtherLineAttr->LineWidth) * pBlendParam->GetBlendRatio()); 00564 00565 pBlendedLineAttr->LineWidth = LineWidth - DeltaWidth; 00566 00567 // Store the ptr to the new blended line width attr val 00568 pBlendParam->SetBlendedAttrVal(pBlendedLineAttr); 00569 00570 return TRUE; 00571 } 00572 00573 /******************************************************************************************** 00574 00575 > virtual AttributeValue *LineWidthAttribute::MouldIntoStroke(PathStrokerVector *pMoulder, 00576 double TransScale); 00577 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00578 Created: 23/2/97 00579 00580 Inputs: pMoulder - A PathStrokerVector which knows how to translate points to "mould" them 00581 (May be NULL, in which case moulding of points does not occur) 00582 00583 TransScale - A fraction between 0.0 and 1.0, by which any transparency 00584 values in this geometry will be scaled, allowing the caller to 00585 effectively apply a flat transparency level to everything that is 00586 moulded. Use 1.0 to leave transparency unaltered. 00587 00588 Returns: NULL if there is no need to mould this attribute (so you should just 00589 render the original attribute), else 00590 A pointer to a copy of this object, suitably moulded and adjusted for 00591 the transparency scaling. The caller must delete the copy when finished 00592 with it. 00593 00594 Purpose: Helper function for the PathStrokerVector class, which "moulds" clipart 00595 subtrees to lie along an arbitrary path. 00596 00597 This function is called to mould attributes, so that: 00598 * Fill/Trans geometries can be moulded 00599 * Line Widths can be scaled to an appropriate value 00600 * A global flat transparency can be applied 00601 etc 00602 00603 Notes: The base class does nothing (it returns NULL - by default, attrs assume that 00604 they will work OK when moulded without being changed) 00605 00606 ********************************************************************************************/ 00607 00608 AttributeValue *LineWidthAttribute::MouldIntoStroke(PathStrokerVector *pMoulder, double TransScale) 00609 { 00610 #ifdef VECTOR_STROKING // Neville 6/8/97 00611 LineWidthAttribute* pMouldedAttr = new LineWidthAttribute; 00612 if (pMouldedAttr != NULL) 00613 { 00614 double ScaledWidth = pMoulder->GetScaleFactor() * (double)LineWidth; 00615 if (ScaledWidth < 1.0) 00616 ScaledWidth = 1.0; 00617 else if (pMouldedAttr->LineWidth > 1000000.0) 00618 ScaledWidth = 1000000.0; 00619 pMouldedAttr->LineWidth = (INT32)ScaledWidth; 00620 } 00621 00622 return(pMouldedAttr); 00623 #else 00624 return NULL; 00625 #endif 00626 } 00627 00628 00629 00630 //----------------------------------------------------------------------- 00631 //----------------------------------------------------------------------- 00632 //----------------------------------------------------------------------- 00633 //----------------------------------------------------------------------- 00634 00635 /******************************************************************************************** 00636 00637 > DashPatternAttribute::DashPatternAttribute() 00638 00639 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00640 Created: 14/10/94 00641 Purpose: Default Constructor for dash pattern attribute. 00642 Errors: - 00643 SeeAlso: - 00644 00645 ********************************************************************************************/ 00646 00647 DashPatternAttribute::DashPatternAttribute() 00648 { 00649 DashPattern.Elements = 0; 00650 DashPattern.DashStart = 0; 00651 00652 DashPattern.ElementData = NULL; 00653 00654 DashPattern.LineWidth = 72000/4; 00655 } 00656 00657 /******************************************************************************************** 00658 00659 > DashPatternAttribute::~DashPatternAttribute() 00660 00661 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00662 Created: 14/10/94 00663 Purpose: Destructor for dash pattern attribute. 00664 SeeAlso: - 00665 00666 ********************************************************************************************/ 00667 00668 DashPatternAttribute::~DashPatternAttribute() 00669 { 00670 if (DashPattern.ElementData) 00671 delete DashPattern.ElementData; 00672 } 00673 00674 /******************************************************************************************** 00675 00676 > void DashPatternAttribute::Render(RenderRegion *pRegion) 00677 00678 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00679 Created: 21/10/94 00680 Inputs: pRegion - the render region to render this attribute into. 00681 Purpose: Sets the dash pattern attribute for the given render region. i.e. all 00682 lines drawn will now be drawn with this dash pattern. 00683 SeeAlso: - 00684 00685 ********************************************************************************************/ 00686 00687 void DashPatternAttribute::Render(RenderRegion *pRegion, BOOL Temp) 00688 { 00689 pRegion->SetDashPattern(this, Temp); 00690 } 00691 00692 /******************************************************************************************** 00693 00694 > void DashPatternAttribute::Restore(RenderRegion *pRegion, BOOL Temp) 00695 00696 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00697 Created: 21/10/94 00698 Inputs: pRegion - the render region to restore the attribute into. 00699 Temp - TRUE if this is a temporary attribute, FALSE if it is 00700 permanent (e.g. it's in a document tree). 00701 Purpose: Restores the dash pattern attribute for the given render region. i.e. all 00702 lines drawn will now be drawn with this dash pattern. 00703 SeeAlso: - 00704 00705 ********************************************************************************************/ 00706 00707 void DashPatternAttribute::Restore(RenderRegion *pRegion, BOOL Temp) 00708 { 00709 pRegion->RestoreDashPattern(this, Temp); 00710 } 00711 00712 /******************************************************************************************** 00713 00714 > BOOL DashPatternAttribute::SetDashPattern(DashRec& NewDash) 00715 00716 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00717 Created: 14/10/94 00718 Purpose: Sets the dash pattern for this attribute. 00719 Errors: No memory. 00720 SeeAlso: - 00721 00722 ********************************************************************************************/ 00723 00724 BOOL DashPatternAttribute::SetDashPattern(DashRec& NewDash) 00725 { 00726 DashPattern.Elements = NewDash.Elements; 00727 DashPattern.DashStart = NewDash.DashStart; 00728 DashPattern.LineWidth = NewDash.LineWidth; 00729 DashPattern.DashID = NewDash.DashID; 00730 DashPattern.ScaleWithLineWidth = NewDash.ScaleWithLineWidth; 00731 00732 if (NewDash.Elements == 0) 00733 return TRUE; 00734 00735 if (DashPattern.ElementData != NULL) 00736 delete DashPattern.ElementData; 00737 00738 DashPattern.ElementData = new INT32[NewDash.Elements]; 00739 00740 if (DashPattern.ElementData == NULL) 00741 return FALSE; 00742 00743 for (INT32 element = 0; element < NewDash.Elements; element++) 00744 { 00745 DashPattern.ElementData[element] = NewDash.ElementData[element]; 00746 } 00747 00748 return TRUE; 00749 } 00750 00751 /******************************************************************************************** 00752 00753 > BOOL DashPatternAttribute::SetStockDashPattern(StockDash NewDash) 00754 00755 Author: Will_Cowling (Xara Group Ltd) <camelotdev@xara.com> 00756 Created: 14/10/94 00757 Purpose: Sets the dash pattern for this attribute. 00758 Errors: No memory. 00759 SeeAlso: - 00760 00761 ********************************************************************************************/ 00762 00763 BOOL DashPatternAttribute::SetStockDashPattern(StockDash NewDash) 00764 { 00765 DashRec StockDash; 00766 DashElement DashArray[8]; 00767 00768 const INT32 DashUnit = StockDash.LineWidth; 00769 00770 StockDash.DashID = NewDash; 00771 00772 switch (NewDash) 00773 { 00774 case SD_SOLID: 00775 StockDash.Elements = 0; 00776 SetDashPattern(StockDash); 00777 break; 00778 00779 case SD_DASH1: 00780 StockDash.Elements = 2; 00781 StockDash.DashStart = 0; 00782 StockDash.ElementData = DashArray; 00783 DashArray[0] = DashUnit*2; 00784 DashArray[1] = DashUnit*2; 00785 00786 SetDashPattern(StockDash); 00787 break; 00788 00789 case SD_DASH2: 00790 StockDash.Elements = 2; 00791 StockDash.DashStart = 0; 00792 StockDash.ElementData = DashArray; 00793 DashArray[0] = DashUnit*4; 00794 DashArray[1] = DashUnit*2; 00795 00796 SetDashPattern(StockDash); 00797 break; 00798 00799 case SD_DASH3: 00800 StockDash.Elements = 2; 00801 StockDash.DashStart = 0; 00802 StockDash.ElementData = DashArray; 00803 DashArray[0] = DashUnit*8; 00804 DashArray[1] = DashUnit*2; 00805 00806 SetDashPattern(StockDash); 00807 break; 00808 00809 case SD_DASH4: 00810 StockDash.Elements = 2; 00811 StockDash.DashStart = 0; 00812 StockDash.ElementData = DashArray; 00813 DashArray[0] = DashUnit*16; 00814 DashArray[1] = DashUnit*2; 00815 00816 SetDashPattern(StockDash); 00817 break; 00818 00819 case SD_DASH5: 00820 StockDash.Elements = 2; 00821 StockDash.DashStart = 0; 00822 StockDash.ElementData = DashArray; 00823 DashArray[0] = DashUnit*24; 00824 DashArray[1] = DashUnit*2; 00825 00826 SetDashPattern(StockDash); 00827 break; 00828 00829 case SD_DASH6: 00830 StockDash.Elements = 2; 00831 StockDash.DashStart = 0; 00832 StockDash.ElementData = DashArray; 00833 DashArray[0] = DashUnit*4; 00834 DashArray[1] = DashUnit*4; 00835 00836 SetDashPattern(StockDash); 00837 break; 00838 00839 case SD_DASH7: 00840 StockDash.Elements = 2; 00841 StockDash.DashStart = 0; 00842 StockDash.ElementData = DashArray; 00843 DashArray[0] = DashUnit*8; 00844 DashArray[1] = DashUnit*4; 00845 00846 SetDashPattern(StockDash); 00847 break; 00848 00849 case SD_DASH8: 00850 StockDash.Elements = 2; 00851 StockDash.DashStart = 0; 00852 StockDash.ElementData = DashArray; 00853 DashArray[0] = DashUnit*16; 00854 DashArray[1] = DashUnit*4; 00855 00856 SetDashPattern(StockDash); 00857 break; 00858 00859 case SD_DASH9: 00860 StockDash.Elements = 2; 00861 StockDash.DashStart = 0; 00862 StockDash.ElementData = DashArray; 00863 DashArray[0] = DashUnit*8; 00864 DashArray[1] = DashUnit*8; 00865 00866 SetDashPattern(StockDash); 00867 break; 00868 00869 case SD_DASH10: 00870 StockDash.Elements = 2; 00871 StockDash.DashStart = 0; 00872 StockDash.ElementData = DashArray; 00873 DashArray[0] = DashUnit*16; 00874 DashArray[1] = DashUnit*8; 00875 00876 SetDashPattern(StockDash); 00877 break; 00878 00879 case SD_DASH11: 00880 StockDash.Elements = 4; 00881 StockDash.DashStart = 0; 00882 StockDash.ElementData = DashArray; 00883 DashArray[0] = DashUnit*4; 00884 DashArray[1] = DashUnit*2; 00885 DashArray[2] = DashUnit*2; 00886 DashArray[3] = DashUnit*2; 00887 00888 SetDashPattern(StockDash); 00889 break; 00890 00891 case SD_DASH12: 00892 StockDash.Elements = 4; 00893 StockDash.DashStart = 0; 00894 StockDash.ElementData = DashArray; 00895 DashArray[0] = DashUnit*8; 00896 DashArray[1] = DashUnit*2; 00897 DashArray[2] = DashUnit*2; 00898 DashArray[3] = DashUnit*2; 00899 00900 SetDashPattern(StockDash); 00901 break; 00902 00903 case SD_DASH13: 00904 StockDash.Elements = 4; 00905 StockDash.DashStart = 0; 00906 StockDash.ElementData = DashArray; 00907 DashArray[0] = DashUnit*16; 00908 DashArray[1] = DashUnit*2; 00909 DashArray[2] = DashUnit*2; 00910 DashArray[3] = DashUnit*2; 00911 00912 SetDashPattern(StockDash); 00913 break; 00914 00915 case SD_DASH14: 00916 StockDash.Elements = 4; 00917 StockDash.DashStart = 0; 00918 StockDash.ElementData = DashArray; 00919 DashArray[0] = DashUnit*8; 00920 DashArray[1] = DashUnit*2; 00921 DashArray[2] = DashUnit*4; 00922 DashArray[3] = DashUnit*2; 00923 00924 SetDashPattern(StockDash); 00925 break; 00926 00927 case SD_DASH15: 00928 StockDash.Elements = 4; 00929 StockDash.DashStart = 0; 00930 StockDash.ElementData = DashArray; 00931 DashArray[0] = DashUnit*16; 00932 DashArray[1] = DashUnit*2; 00933 DashArray[2] = DashUnit*4; 00934 DashArray[3] = DashUnit*2; 00935 00936 SetDashPattern(StockDash); 00937 break; 00938 00939 case SD_DASH16: 00940 StockDash.Elements = 6; 00941 StockDash.DashStart = 0; 00942 StockDash.ElementData = DashArray; 00943 DashArray[0] = DashUnit*8; 00944 DashArray[1] = DashUnit*2; 00945 DashArray[2] = DashUnit*2; 00946 DashArray[3] = DashUnit*2; 00947 DashArray[4] = DashUnit*2; 00948 DashArray[5] = DashUnit*2; 00949 00950 SetDashPattern(StockDash); 00951 break; 00952 00953 case SD_DASH17: 00954 StockDash.Elements = 6; 00955 StockDash.DashStart = 0; 00956 StockDash.ElementData = DashArray; 00957 DashArray[0] = DashUnit*16; 00958 DashArray[1] = DashUnit*2; 00959 DashArray[2] = DashUnit*2; 00960 DashArray[3] = DashUnit*2; 00961 DashArray[4] = DashUnit*2; 00962 DashArray[5] = DashUnit*2; 00963 00964 SetDashPattern(StockDash); 00965 break; 00966 00967 case SD_DASH18: 00968 StockDash.Elements = 8; 00969 StockDash.DashStart = 0; 00970 StockDash.ElementData = DashArray; 00971 DashArray[0] = DashUnit*8; 00972 DashArray[1] = DashUnit*2; 00973 DashArray[2] = DashUnit*2; 00974 DashArray[3] = DashUnit*2; 00975 DashArray[4] = DashUnit*2; 00976 DashArray[5] = DashUnit*2; 00977 DashArray[6] = DashUnit*2; 00978 DashArray[7] = DashUnit*2; 00979 00980 SetDashPattern(StockDash); 00981 break; 00982 00983 case SD_DASH19: 00984 StockDash.Elements = 8; 00985 StockDash.DashStart = 0; 00986 StockDash.ElementData = DashArray; 00987 DashArray[0] = DashUnit*16; 00988 DashArray[1] = DashUnit*2; 00989 DashArray[2] = DashUnit*2; 00990 DashArray[3] = DashUnit*2; 00991 DashArray[4] = DashUnit*2; 00992 DashArray[5] = DashUnit*2; 00993 DashArray[6] = DashUnit*2; 00994 DashArray[7] = DashUnit*2; 00995 00996 SetDashPattern(StockDash); 00997 break; 00998 00999 case SD_DASH20: 01000 StockDash.Elements = 8; 01001 StockDash.DashStart = 0; 01002 StockDash.ElementData = DashArray; 01003 DashArray[0] = DashUnit*8; 01004 DashArray[1] = DashUnit*2; 01005 DashArray[2] = DashUnit*2; 01006 DashArray[3] = DashUnit*2; 01007 DashArray[4] = DashUnit*4; 01008 DashArray[5] = DashUnit*2; 01009 DashArray[6] = DashUnit*2; 01010 DashArray[7] = DashUnit*2; 01011 01012 SetDashPattern(StockDash); 01013 break; 01014 01015 case SD_DASH_GUIDELAYER: 01016 // This is the dash pattern used to render objects in guide layers with. 01017 // It's different to the others in that the dashed aren't scaled relative to the line width 01018 StockDash.Elements = 2; 01019 StockDash.DashStart = 0; 01020 StockDash.ElementData = DashArray; 01021 StockDash.ScaleWithLineWidth = FALSE; 01022 DashArray[0] = DashUnit*2; 01023 DashArray[1] = DashUnit*2; 01024 01025 SetDashPattern(StockDash); 01026 break; 01027 01028 default: 01029 StockDash.Elements = 0; 01030 StockDash.DashStart = 0; 01031 StockDash.ElementData = NULL; 01032 01033 SetDashPattern(StockDash); 01034 break; 01035 } 01036 01037 return TRUE; 01038 } 01039 01040 DashRec::DashRec() 01041 { 01042 Elements = 0; 01043 DashStart = 0; 01044 ElementData = NULL; 01045 DashID = 0; 01046 ScaleWithLineWidth = TRUE; 01047 01048 LineWidth = 72000/4; 01049 } 01050 01051 String_256 DashRec::GetStockDashName(StockDash DashType) 01052 { 01053 String_256 DashName; 01054 01055 switch (DashType) 01056 { 01057 case SD_SOLID: 01058 DashName.Load(_R(IDS_K_ATTR_SOLIDLINE)); 01059 break; 01060 01061 default: 01062 DashName.Load(_R(IDS_K_ATTR_DASHLINE)); 01063 break; 01064 } 01065 01066 return DashName; 01067 } 01068 01069 /******************************************************************************************** 01070 01071 > void DashRec::CheckAndFix() 01072 01073 Author: Ben_Summers (Xara Group Ltd) <camelotdev@xara.com> 01074 Created: 04/07/95 01075 Purpose: Checks a dash pattern, and fixes it if it's not very nice. 01076 Errors: No errors. 01077 SeeAlso: - 01078 01079 ********************************************************************************************/ 01080 01081 void DashRec::CheckAndFix() 01082 { 01083 // check the dash offset 01084 if(DashStart < 0) 01085 DashStart = 0; 01086 01087 if(Elements == 0) 01088 return; 01089 01090 // check the dash pattern elements 01091 INT32 End = 0; 01092 INT32 l; 01093 01094 for(l = 0; l < Elements; l++) 01095 { 01096 01097 // is this element OK? 01098 if(ElementData[l] > 0) 01099 { 01100 // element is OK... 01101 if(End != l) 01102 { 01103 // move it back if something has been deleted before it 01104 ElementData[End] = ElementData[l]; 01105 } 01106 End++; 01107 } 01108 } 01109 01110 // have we got enough elements? 01111 if(End < 1) 01112 { 01113 // no elements - make it a solid outline 01114 Elements = 0; 01115 DashID = SD_SOLID; 01116 } 01117 else 01118 { 01119 Elements = End; 01120 } 01121 } 01122 01123 /******************************************************************************************** 01124 01125 > void DashRec::CheckIfDefaultPattern() 01126 01127 Author: Neville_Humphrys (Xara Group Ltd) <camelotdev@xara.com> 01128 Created: 26/07/96 01129 Purpose: Checks a dash pattern to see if it is one of the built in ones and if so 01130 then sets the ID to be correct. 01131 Not the best way but a) its quick, b) it works, c) not three million 01132 big rebuilds of 330 files to get it right 01133 01134 This is mainly required for the following reason: 01135 When we save Native files we at present save out a dash pattern ID and then 01136 save out the full dash pattern definition! This is ok apart from wasting space. 01137 The problem happens when we load the information back in, we load the id and apply 01138 the relevent dash pattern and then load the definition and apply it, zapping the 01139 id. 01140 Errors: No errors. 01141 SeeAlso: - 01142 01143 ********************************************************************************************/ 01144 01145 /* Disable the code as completely useless as we scale the line widths when we first save them 01146 in a old format xar file! So the simple fix becomes a nightmare! 01147 01148 void DashRec::CheckIfDefaultPattern() 01149 { 01150 // Check to see if the pattern corresponds to one of our built in ones 01151 // If so then set the DashID accordingly 01152 // Default is do nothing 01153 // SD_SOLID == 0 so if this then do nothing 01154 01155 const INT32 DefLineWidth = 72000/4; 01156 const INT32 DashUnit = DefLineWidth; 01157 01158 // All the useful defaults are defined like this using the default constructed 01159 // values, so if they are different then its not default pattern 01160 if (LineWidth != DefLineWidth || DashID != 0 || DashStart != 0 || Elements == 0) 01161 return; 01162 01163 // The SD_DASH_GUIDELAYER has 2 elements and is the only one to have ScaleWithLineWidth = FALSE 01164 if (ScaleWithLineWidth != TRUE && Elements != 2) 01165 return; 01166 01167 switch (Elements) 01168 { 01169 case 2: 01170 { 01171 switch (ElementData[1]) 01172 { 01173 case DashUnit*2: 01174 { 01175 switch (ElementData[0]) 01176 { 01177 case DashUnit*2: 01178 if (ScaleWithLineWidth) 01179 DashID = SD_DASH1; 01180 else 01181 DashID = SD_DASH_GUIDELAYER; 01182 break; 01183 case DashUnit*4: 01184 DashID = SD_DASH2; 01185 break; 01186 case DashUnit*8: 01187 DashID = SD_DASH3; 01188 break; 01189 case DashUnit*16: 01190 DashID = SD_DASH4; 01191 break; 01192 case DashUnit*24: 01193 DashID = SD_DASH5; 01194 break; 01195 } 01196 } 01197 break; 01198 01199 case DashUnit*4: 01200 { 01201 switch (ElementData[0]) 01202 { 01203 case DashUnit*4: 01204 DashID = SD_DASH6; 01205 break; 01206 case DashUnit*8: 01207 DashID = SD_DASH7; 01208 break; 01209 case DashUnit*16: 01210 DashID = SD_DASH8; 01211 break; 01212 } 01213 } 01214 break; 01215 01216 case DashUnit*8: 01217 { 01218 switch (ElementData[0]) 01219 { 01220 case DashUnit*8: 01221 DashID = SD_DASH9; 01222 break; 01223 case DashUnit*16: 01224 DashID = SD_DASH10; 01225 break; 01226 } 01227 } 01228 break; 01229 } 01230 break; 01231 } 01232 01233 case 4: 01234 { 01235 // All our current definitions have the 1st and 3rd elements == DashUnit*2 01236 if ( 01237 ElementData[1] != DashUnit*2 || 01238 ElementData[3] != DashUnit*2 01239 ) 01240 return; 01241 01242 switch (ElementData[2]) 01243 { 01244 case DashUnit*2: 01245 switch (ElementData[0]) 01246 { 01247 case DashUnit*4: 01248 DashID = SD_DASH11; 01249 break; 01250 case DashUnit*8: 01251 DashID = SD_DASH12; 01252 break; 01253 case DashUnit*16: 01254 DashID = SD_DASH13; 01255 break; 01256 } 01257 break; 01258 case DashUnit*4: 01259 switch (ElementData[0]) 01260 { 01261 case DashUnit*8: 01262 DashID = SD_DASH14; 01263 break; 01264 case DashUnit*16: 01265 DashID = SD_DASH15; 01266 break; 01267 } 01268 break; 01269 } 01270 01271 break; 01272 } 01273 01274 case 6: 01275 { 01276 if ( 01277 ElementData[0] == DashUnit*8 && 01278 ElementData[1] == DashUnit*2 && 01279 ElementData[2] == DashUnit*2 && 01280 ElementData[3] == DashUnit*2 && 01281 ElementData[4] == DashUnit*2 && 01282 ElementData[5] == DashUnit*2 01283 ) 01284 DashID = SD_DASH16; 01285 else if ( 01286 ElementData[0] == DashUnit*16 && 01287 ElementData[1] == DashUnit*2 && 01288 ElementData[2] == DashUnit*2 && 01289 Eleme