00001 // $Id: pathtrap.h 1282 2006-06-09 09:46:49Z 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 // Definition of Path Trapezoid classes (used in stroke providing) 00099 00100 #ifndef INC_PATHTRAP 00101 #define INC_PATHTRAP 00102 00103 #include "pathproc.h" 00104 //#include "attr.h" - in camtypes.h [AUTOMATICALLY REMOVED] 00105 00106 00107 // Forward declarations 00108 class ProcessPathToTrapezoids; 00109 class TrapsList; 00110 00111 /****************************************************************************************** 00112 00113 > enum TrapTravelType 00114 00115 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00116 Created: 13/1/97 00117 00118 Purpose: Describes how (if at all) to record "travel" in trapezoid lists 00119 00120 SeeAlso: ProcessPathToTrapezoids::Process 00121 00122 ******************************************************************************************/ 00123 00124 typedef enum 00125 { 00126 TrapTravel_None, // Don't record trapezoid travel at all 00127 TrapTravel_Parametric, // Record travel as relative 0.0 to 1.0 parametric range 00128 TrapTravel_Millipoint // Record travel as absolute millipoints distance 00129 } TrapTravelType; 00130 00131 00132 00133 /****************************************************************************************** 00134 00135 > enum TrapJoinType 00136 00137 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00138 Created: 15/1/97 00139 00140 Purpose: Describes what kind of join (if any) the trapezoid between the "previous" 00141 TrapEdge and "this" TrapEdge represents. This is used to mark all traps 00142 lying within joins, and to indicate the join style to the stroker, as 00143 rounded joins are "smoothed" by the stroker, while mitred/bevelled joins 00144 must always produce straight lines. 00145 00146 ******************************************************************************************/ 00147 00148 typedef enum 00149 { 00150 TrapJoin_None, 00151 TrapJoin_Round, 00152 TrapJoin_MitredOrBevelled 00153 } TrapJoinType; 00154 00155 00156 00157 /****************************************************************************************** 00158 00159 > class NormCoord : public CC_CLASS_MEMDUMP 00160 00161 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00162 Created: 30/12/96 00163 00164 Purpose: Normalised vector/coordinate 00165 When normalised, the vector is always of unit length 00166 00167 Notes: The entire class is inlined to keep these simple operations efficient 00168 00169 ******************************************************************************************/ 00170 00171 class NormCoord : public CCObject 00172 { 00173 CC_DECLARE_DYNCREATE(NormCoord); 00174 00175 public: // Constructors 00176 NormCoord() { x = y = 0.0; }; 00177 NormCoord(double X, double Y) { x = X; y = Y; }; 00178 NormCoord(NormCoord &Other) { x = Other.x; y = Other.y; }; 00179 00180 public: 00181 // Normalise this vector to be of unit length 00182 void Normalise(void) 00183 { 00184 double Normalise = sqrt(x*x + y*y); 00185 if (Normalise == 0.0) 00186 { 00187 TRACE( _T("** NormCoord::Normalise - Zero-length vector (%f)\n"), Normalise); 00188 } 00189 else 00190 { 00191 Normalise = 1/Normalise; 00192 x *= Normalise; 00193 y *= Normalise; 00194 } 00195 } 00196 00197 // Averaging of 2 vectors. Both input vectors must be normalised 00198 // The result overwrites "this" NormCoord, and is always normalised 00199 // If the vectors are exactly equal and opposite, returns a perpendicular to "this" 00200 inline void Average(NormCoord &C1, NormCoord &C2) 00201 { 00202 if (C1.x + C2.x == 0.0 && C1.y + C2.y == 0.0) 00203 { 00204 double Temp = C1.x; 00205 x = C1.y; 00206 y = -Temp; 00207 } 00208 else 00209 { 00210 x = (C1.x + C2.x) / 2.0; 00211 y = (C1.y + C2.y) / 2.0; 00212 Normalise(); 00213 } 00214 } 00215 00216 inline double GetLength() 00217 { 00218 return sqrt(x * x + y * y); 00219 } 00220 00221 // Make a normalised direction vector for a line from P1 to P2 00222 inline void SetFromLine(DocCoord &P1, DocCoord &P2) 00223 { 00224 x = P1.x - P2.x; 00225 y = P1.y - P2.y; 00226 Normalise(); 00227 } 00228 00229 // Make a normalised perpendicular vector (Normal) for a line from P1 to P2 00230 inline void SetNormalToLine(DocCoord &P1, DocCoord &P2) 00231 { 00232 x = P1.y - P2.y; 00233 y = -(P1.x - P2.x); 00234 Normalise(); 00235 } 00236 00237 // Calculate the dot product of this vector and another. Both inputs must already 00238 // have been normalised, or the result will be bogus. 00239 inline double DotProduct(NormCoord &Other) 00240 { 00241 return( (x * Other.x) + (y * Other.y) ); 00242 } 00243 00244 // Assignment operator 00245 inline NormCoord& operator=(const NormCoord &Other) 00246 { 00247 x = Other.x; 00248 y = Other.y; 00249 return(*this); 00250 } 00251 00252 public: 00253 double x; 00254 double y; 00255 }; 00256 00257 00258 00259 /****************************************************************************************** 00260 00261 > struct TrapEdge 00262 00263 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00264 Created: 30/12/96 00265 00266 Purpose: Structure defining a trapezoid edge definition. 00267 A TrapEdge records the following information: 00268 00269 Centre - A centerline point for the edge, which lies on the original path 00270 00271 Normal - A normal vector to the curve at this centre point 00272 00273 Position - The position of this centre point along the original path 00274 During construction of a TrapEdgeList this is a physical 00275 MILLIPOINT distance, but at the end of the process it is 00276 converted into a parametric position representation in 00277 the range 0.0 to 1.0 00278 00279 ******************************************************************************************/ 00280 00281 typedef struct 00282 { 00283 DocCoord Centre; // Centreline position on the destination path 00284 NormCoord Normal; // Normal to the curve at this point (points toward "left" side) 00285 NormCoord Normal2; // Tertiary normal, mainly used by bevtrap 00286 double Position; // The fractional position of this trap along the destination path 00287 TrapJoinType PrevTrapJoin; // Indicates what type of join (if any) the previous trap belongs to 00288 } TrapEdge; 00289 00290 00291 00292 /****************************************************************************************** 00293 00294 > class TrapEdgeList : public CC_CLASS_MEMDUMP 00295 00296 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00297 Created: 30/12/96 00298 00299 Purpose: Simple class to store a list of trapezoid edges (TrapEdge structures) 00300 Each source sub-path will be converted to a separate TrapEdgeList 00301 00302 Notes: Sorry, Jim, but I've had to use inlining to keep common operations efficient 00303 00304 ******************************************************************************************/ 00305 00306 class TrapEdgeList : public CCObject 00307 { 00308 CC_DECLARE_DYNCREATE(TrapEdgeList); 00309 00310 public: 00311 TrapEdgeList(TrapsList *pParent = NULL); 00312 ~TrapEdgeList(); 00313 // Default constructor & destructor 00314 00315 inline UINT32 GetNumEdges(void) { return(Used); }; 00316 // Determine the total number of elements in the list 00317 00318 inline TrapEdge *GetTrapEdge(UINT32 index) { ERROR3IF(index >= Used, "Out of range"); return(&pEdges[index]); }; 00319 // Retrieve the given element of the list 00320 00321 inline TrapEdge *GetLastTrapEdge(void) { return((Used == 0) ? NULL : &pEdges[Used-1]); }; 00322 // Retrieve the last element in the list 00323 00324 UINT32 FindTrapEdge(double Position, UINT32 LoIndex = 0, UINT32 HiIndex = 0); 00325 // Finds the last trapezoid edge with a position less than the given position. 00326 // LoIndex/HiIndex indicate the bouds of the array to start searching within (it is 00327 // not limited to the bounds - they just make searches in small regions much faster) 00328 00329 BOOL AddEdge(DocCoord *pPoint, TrapJoinType JoinType = TrapJoin_None); 00330 // Appends a new TrapEdge to the list 00331 00332 BOOL ProcessEdgeNormals(ProcessPathToTrapezoids *pProcessor); 00333 BOOL ProcessEdgePositions(TrapTravelType TravelType); 00334 // Post-processes the entire (completed) list to fill in all the details 00335 00336 inline double GetPathLength(void) { return PathLength; }; 00337 // Returns the length (in millipoints) of the path represented in this TrapEdgelist 00338 00339 protected: 00340 BOOL ExpandArray(void); 00341 // Expands the array to allow for more entries 00342 00343 protected: 00344 UINT32 Used; // Number of entries used (index of first free space in array) 00345 UINT32 CurrentSize; // Number of entries allocated for the array 00346 TrapEdge *pEdges; // Pointer to the edge array 00347 00348 double PathLength; // Length (travel) of the represented (sub)path in millipoints 00349 00350 TrapsList *pParentList; // Points to the TrapsList in which we reside 00351 }; 00352 00353 00354 00355 /****************************************************************************************** 00356 00357 > class TrapsList : public CC_CLASS_MEMDUMP 00358 00359 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00360 Created: 30/12/96 00361 00362 Purpose: Simple class containing a list of TrapEdgeLists representing a complex path 00363 Each TrapEdgeList represents a sub-path of the overall source path. 00364 00365 Notes: Sorry, Jim, but I've had to use inlining to keep common operations efficient 00366 00367 ******************************************************************************************/ 00368 00369 class TrapsList : public CCObject 00370 { 00371 CC_DECLARE_DYNCREATE(TrapsList) 00372 00373 public: 00374 TrapsList(INT32 Repeat = 0); 00375 ~TrapsList(); 00376 00377 inline UINT32 GetNumTraps(void) { return(Used); }; 00378 // Determine the total number of elements in the list 00379 00380 inline TrapEdgeList *GetTrapEdgeList(UINT32 index) 00381 { ERROR3IF(index >= Used, "Out of range"); return(pTraps[index]); }; 00382 // Retrieve the given element of the list 00383 00384 inline TrapEdgeList *GetLastTrapEdgeList(void) 00385 { return((Used == 0) ? NULL : pTraps[Used-1]); }; 00386 // Retrieve the last element in the list 00387 00388 TrapEdgeList *AddEdgeList(void); 00389 // Adds a new TrapEdgeList to the list, returning it for you to fill in 00390 00391 BOOL PostProcessLists(ProcessPathToTrapezoids *pProcessor, TrapTravelType TravelType); 00392 // Post-processes all trapezoid lists to complete calculation of all values 00393 00394 inline INT32 GetRepeatLength(void) { return(RepeatLength); }; 00395 // Retrieve the length of repeating stroke sections (or 0 if there is no repeat) 00396 00397 protected: 00398 BOOL ExpandArray(void); 00399 // Expands the array to allow for more entries 00400 00401 protected: 00402 UINT32 Used; // Number of entries used (index of first free space in array) 00403 UINT32 CurrentSize; // Number of entries allocated for the array 00404 TrapEdgeList **pTraps; // Pointer to the EdgeList array 00405 00406 INT32 RepeatLength; // Length (in millipoints) after which the stroke should repeat 00407 // (or 0 if the stroke should only repeat once) 00408 }; 00409 00410 00411 00412 /****************************************************************************************** 00413 00414 > class ProcessPathToTrapezoids : public ProcessPath 00415 00416 Author: Jason_Williams (Xara Group Ltd) <camelotdev@xara.com> 00417 Created: 30/12/96 00418 00419 Purpose: Process a path to produce a trapezoid list suitable for variable- 00420 width or vector-brushed stroke generation. 00421 00422 ******************************************************************************************/ 00423 00424 class ProcessPathToTrapezoids : public ProcessPath 00425 { 00426 friend class TrapEdgeList; 00427 00428 public: // Construction & Invocation 00429 ProcessPathToTrapezoids(const double flat); 00430 // Construct 00431 00432 virtual BOOL Init(Path* pSource, TrapsList *pOutputList); 00433 // Initialise ready for use 00434 00435 virtual BOOL Process(const ProcessFlags &PFlags, 00436 TrapTravelType TravelType, JointType JoinStyle = RoundJoin); 00437 // Convert the source into trapezoidal strokes in the given style 00438 00439 00440 public: // Overridden virtuals called by base class 00441 virtual BOOL NewPoint(PathVerb Verb, DocCoord *pCoord); 00442 virtual BOOL CloseElement(BOOL done, PathVerb Verb, INT32 Index); 00443 virtual void CloseFigure(void); 00444 00445 00446 protected: 00447 BOOL CalculateMitreIntersection(DocCoord *p1, DocCoord *p2, DocCoord *p3, 00448 double *pMitreRatio = NULL); 00449 00450 private: 00451 TrapsList *pTraps; // List of trapezoids being created 00452 BOOL PointFollowsJoin; // TRUE when a NewPoint immediately follows a join (knot) 00453 JointType JoinType; // Indicates the join style we wish to use 00454 INT32 RepeatLength; // 0 (no repeat), or the length of repeating sections (in millipoints) 00455 DocCoord LastPoint; // Used to detect & remove coincident points from the flattened path 00456 }; 00457 00458 00459 #endif 00460