// $Id: pathtrap.h 1282 2006-06-09 09:46:49Z alex $ /* @@tag:xara-cn@@ DO NOT MODIFY THIS LINE ================================XARAHEADERSTART=========================== Xara LX, a vector drawing and manipulation program. Copyright (C) 1993-2006 Xara Group Ltd. Copyright on certain contributions may be held in joint with their respective authors. See AUTHORS file for details. LICENSE TO USE AND MODIFY SOFTWARE ---------------------------------- This file is part of Xara LX. Xara LX is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. Xara LX and its component source files are distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Xara LX (see the file GPL in the root directory of the distribution); if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA ADDITIONAL RIGHTS ----------------- Conditional upon your continuing compliance with the GNU General Public License described above, Xara Group Ltd grants to you certain additional rights. The additional rights are to use, modify, and distribute the software together with the wxWidgets library, the wxXtra library, and the "CDraw" library and any other such library that any version of Xara LX relased by Xara Group Ltd requires in order to compile and execute, including the static linking of that library to XaraLX. In the case of the "CDraw" library, you may satisfy obligation under the GNU General Public License to provide source code by providing a binary copy of the library concerned and a copy of the license accompanying it. Nothing in this section restricts any of the rights you have under the GNU General Public License. SCOPE OF LICENSE ---------------- This license applies to this program (XaraLX) and its constituent source files only, and does not necessarily apply to other Xara products which may in part share the same code base, and are subject to their own licensing terms. This license does not apply to files in the wxXtra directory, which are built into a separate library, and are subject to the wxWindows license contained within that directory in the file "WXXTRA-LICENSE". This license does not apply to the binary libraries (if any) within the "libs" directory, which are subject to a separate license contained within that directory in the file "LIBS-LICENSE". ARRANGEMENTS FOR CONTRIBUTION OF MODIFICATIONS ---------------------------------------------- Subject to the terms of the GNU Public License (see above), you are free to do whatever you like with your modifications. However, you may (at your option) wish contribute them to Xara's source tree. You can find details of how to do this at: http://www.xaraxtreme.org/developers/ Prior to contributing your modifications, you will need to complete our contributor agreement. This can be found at: http://www.xaraxtreme.org/developers/contribute/ Please note that Xara will not accept modifications which modify any of the text between the start and end of this header (marked XARAHEADERSTART and XARAHEADEREND). MARKS ----- Xara, Xara LX, Xara X, Xara X/Xtreme, Xara Xtreme, the Xtreme and Xara designs are registered or unregistered trademarks, design-marks, and/or service marks of Xara Group Ltd. All rights in these marks are reserved. Xara Group Ltd, Gaddesden Place, Hemel Hempstead, HP2 6EX, UK. http://www.xara.com/ =================================XARAHEADEREND============================ */ // Definition of Path Trapezoid classes (used in stroke providing) #ifndef INC_PATHTRAP #define INC_PATHTRAP #include "pathproc.h" //#include "attr.h" - in camtypes.h [AUTOMATICALLY REMOVED] // Forward declarations class ProcessPathToTrapezoids; class TrapsList; /****************************************************************************************** > enum TrapTravelType Author: Jason_Williams (Xara Group Ltd) Created: 13/1/97 Purpose: Describes how (if at all) to record "travel" in trapezoid lists SeeAlso: ProcessPathToTrapezoids::Process ******************************************************************************************/ typedef enum { TrapTravel_None, // Don't record trapezoid travel at all TrapTravel_Parametric, // Record travel as relative 0.0 to 1.0 parametric range TrapTravel_Millipoint // Record travel as absolute millipoints distance } TrapTravelType; /****************************************************************************************** > enum TrapJoinType Author: Jason_Williams (Xara Group Ltd) Created: 15/1/97 Purpose: Describes what kind of join (if any) the trapezoid between the "previous" TrapEdge and "this" TrapEdge represents. This is used to mark all traps lying within joins, and to indicate the join style to the stroker, as rounded joins are "smoothed" by the stroker, while mitred/bevelled joins must always produce straight lines. ******************************************************************************************/ typedef enum { TrapJoin_None, TrapJoin_Round, TrapJoin_MitredOrBevelled } TrapJoinType; /****************************************************************************************** > class NormCoord : public CC_CLASS_MEMDUMP Author: Jason_Williams (Xara Group Ltd) Created: 30/12/96 Purpose: Normalised vector/coordinate When normalised, the vector is always of unit length Notes: The entire class is inlined to keep these simple operations efficient ******************************************************************************************/ class NormCoord : public CCObject { CC_DECLARE_DYNCREATE(NormCoord); public: // Constructors NormCoord() { x = y = 0.0; }; NormCoord(double X, double Y) { x = X; y = Y; }; NormCoord(NormCoord &Other) { x = Other.x; y = Other.y; }; public: // Normalise this vector to be of unit length void Normalise(void) { double Normalise = sqrt(x*x + y*y); if (Normalise == 0.0) { TRACE( _T("** NormCoord::Normalise - Zero-length vector (%f)\n"), Normalise); } else { Normalise = 1/Normalise; x *= Normalise; y *= Normalise; } } // Averaging of 2 vectors. Both input vectors must be normalised // The result overwrites "this" NormCoord, and is always normalised // If the vectors are exactly equal and opposite, returns a perpendicular to "this" inline void Average(NormCoord &C1, NormCoord &C2) { if (C1.x + C2.x == 0.0 && C1.y + C2.y == 0.0) { double Temp = C1.x; x = C1.y; y = -Temp; } else { x = (C1.x + C2.x) / 2.0; y = (C1.y + C2.y) / 2.0; Normalise(); } } inline double GetLength() { return sqrt(x * x + y * y); } // Make a normalised direction vector for a line from P1 to P2 inline void SetFromLine(DocCoord &P1, DocCoord &P2) { x = P1.x - P2.x; y = P1.y - P2.y; Normalise(); } // Make a normalised perpendicular vector (Normal) for a line from P1 to P2 inline void SetNormalToLine(DocCoord &P1, DocCoord &P2) { x = P1.y - P2.y; y = -(P1.x - P2.x); Normalise(); } // Calculate the dot product of this vector and another. Both inputs must already // have been normalised, or the result will be bogus. inline double DotProduct(NormCoord &Other) { return( (x * Other.x) + (y * Other.y) ); } // Assignment operator inline NormCoord& operator=(const NormCoord &Other) { x = Other.x; y = Other.y; return(*this); } public: double x; double y; }; /****************************************************************************************** > struct TrapEdge Author: Jason_Williams (Xara Group Ltd) Created: 30/12/96 Purpose: Structure defining a trapezoid edge definition. A TrapEdge records the following information: Centre - A centerline point for the edge, which lies on the original path Normal - A normal vector to the curve at this centre point Position - The position of this centre point along the original path During construction of a TrapEdgeList this is a physical MILLIPOINT distance, but at the end of the process it is converted into a parametric position representation in the range 0.0 to 1.0 ******************************************************************************************/ typedef struct { DocCoord Centre; // Centreline position on the destination path NormCoord Normal; // Normal to the curve at this point (points toward "left" side) NormCoord Normal2; // Tertiary normal, mainly used by bevtrap double Position; // The fractional position of this trap along the destination path TrapJoinType PrevTrapJoin; // Indicates what type of join (if any) the previous trap belongs to } TrapEdge; /****************************************************************************************** > class TrapEdgeList : public CC_CLASS_MEMDUMP Author: Jason_Williams (Xara Group Ltd) Created: 30/12/96 Purpose: Simple class to store a list of trapezoid edges (TrapEdge structures) Each source sub-path will be converted to a separate TrapEdgeList Notes: Sorry, Jim, but I've had to use inlining to keep common operations efficient ******************************************************************************************/ class TrapEdgeList : public CCObject { CC_DECLARE_DYNCREATE(TrapEdgeList); public: TrapEdgeList(TrapsList *pParent = NULL); ~TrapEdgeList(); // Default constructor & destructor inline UINT32 GetNumEdges(void) { return(Used); }; // Determine the total number of elements in the list inline TrapEdge *GetTrapEdge(UINT32 index) { ERROR3IF(index >= Used, "Out of range"); return(&pEdges[index]); }; // Retrieve the given element of the list inline TrapEdge *GetLastTrapEdge(void) { return((Used == 0) ? NULL : &pEdges[Used-1]); }; // Retrieve the last element in the list UINT32 FindTrapEdge(double Position, UINT32 LoIndex = 0, UINT32 HiIndex = 0); // Finds the last trapezoid edge with a position less than the given position. // LoIndex/HiIndex indicate the bouds of the array to start searching within (it is // not limited to the bounds - they just make searches in small regions much faster) BOOL AddEdge(DocCoord *pPoint, TrapJoinType JoinType = TrapJoin_None); // Appends a new TrapEdge to the list BOOL ProcessEdgeNormals(ProcessPathToTrapezoids *pProcessor); BOOL ProcessEdgePositions(TrapTravelType TravelType); // Post-processes the entire (completed) list to fill in all the details inline double GetPathLength(void) { return PathLength; }; // Returns the length (in millipoints) of the path represented in this TrapEdgelist protected: BOOL ExpandArray(void); // Expands the array to allow for more entries protected: UINT32 Used; // Number of entries used (index of first free space in array) UINT32 CurrentSize; // Number of entries allocated for the array TrapEdge *pEdges; // Pointer to the edge array double PathLength; // Length (travel) of the represented (sub)path in millipoints TrapsList *pParentList; // Points to the TrapsList in which we reside }; /****************************************************************************************** > class TrapsList : public CC_CLASS_MEMDUMP Author: Jason_Williams (Xara Group Ltd) Created: 30/12/96 Purpose: Simple class containing a list of TrapEdgeLists representing a complex path Each TrapEdgeList represents a sub-path of the overall source path. Notes: Sorry, Jim, but I've had to use inlining to keep common operations efficient ******************************************************************************************/ class TrapsList : public CCObject { CC_DECLARE_DYNCREATE(TrapsList) public: TrapsList(INT32 Repeat = 0); ~TrapsList(); inline UINT32 GetNumTraps(void) { return(Used); }; // Determine the total number of elements in the list inline TrapEdgeList *GetTrapEdgeList(UINT32 index) { ERROR3IF(index >= Used, "Out of range"); return(pTraps[index]); }; // Retrieve the given element of the list inline TrapEdgeList *GetLastTrapEdgeList(void) { return((Used == 0) ? NULL : pTraps[Used-1]); }; // Retrieve the last element in the list TrapEdgeList *AddEdgeList(void); // Adds a new TrapEdgeList to the list, returning it for you to fill in BOOL PostProcessLists(ProcessPathToTrapezoids *pProcessor, TrapTravelType TravelType); // Post-processes all trapezoid lists to complete calculation of all values inline INT32 GetRepeatLength(void) { return(RepeatLength); }; // Retrieve the length of repeating stroke sections (or 0 if there is no repeat) protected: BOOL ExpandArray(void); // Expands the array to allow for more entries protected: UINT32 Used; // Number of entries used (index of first free space in array) UINT32 CurrentSize; // Number of entries allocated for the array TrapEdgeList **pTraps; // Pointer to the EdgeList array INT32 RepeatLength; // Length (in millipoints) after which the stroke should repeat // (or 0 if the stroke should only repeat once) }; /****************************************************************************************** > class ProcessPathToTrapezoids : public ProcessPath Author: Jason_Williams (Xara Group Ltd) Created: 30/12/96 Purpose: Process a path to produce a trapezoid list suitable for variable- width or vector-brushed stroke generation. ******************************************************************************************/ class ProcessPathToTrapezoids : public ProcessPath { friend class TrapEdgeList; public: // Construction & Invocation ProcessPathToTrapezoids(const double flat); // Construct virtual BOOL Init(Path* pSource, TrapsList *pOutputList); // Initialise ready for use virtual BOOL Process(const ProcessFlags &PFlags, TrapTravelType TravelType, JointType JoinStyle = RoundJoin); // Convert the source into trapezoidal strokes in the given style public: // Overridden virtuals called by base class virtual BOOL NewPoint(PathVerb Verb, DocCoord *pCoord); virtual BOOL CloseElement(BOOL done, PathVerb Verb, INT32 Index); virtual void CloseFigure(void); protected: BOOL CalculateMitreIntersection(DocCoord *p1, DocCoord *p2, DocCoord *p3, double *pMitreRatio = NULL); private: TrapsList *pTraps; // List of trapezoids being created BOOL PointFollowsJoin; // TRUE when a NewPoint immediately follows a join (knot) JointType JoinType; // Indicates the join style we wish to use INT32 RepeatLength; // 0 (no repeat), or the length of repeating sections (in millipoints) DocCoord LastPoint; // Used to detect & remove coincident points from the flattened path }; #endif