// $Id: cstroke.h 751 2006-03-31 15:43: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============================ */ /************************************************************************/ // // GStroke.h // /************************************************************************/ typedef bool GBOOL ; typedef __int64 DLONG ; typedef __uint64 UDLONG ; typedef double DOUBLE ; struct FPOINT ; struct GPOINT ; #define TypeDef(name) \ typedef const name c##name ; \ typedef name* p##name ; \ typedef const name* pc##name ; \ typedef name* const cp##name ; \ typedef const name* const cpc##name ; \ typedef name** pp##name ; \ typedef const name** ppc##name ; TypeDef( GBOOL ) TypeDef( INT32 ) TypeDef( UINT32 ) TypeDef( DLONG ) TypeDef( UDLONG ) TypeDef( BYTE ) TypeDef( WORD ) TypeDef( DWORD ) TypeDef( FLOAT ) TypeDef( DOUBLE ) TypeDef( POINT ) TypeDef( FPOINT ) TypeDef( GPOINT ) struct FPOINT { double X ; double Y ; FPOINT() {} ; FPOINT( cDOUBLE X,cDOUBLE Y ) : X(X),Y(Y) {} ; FPOINT( cGPOINT P ) ; bool operator==(cFPOINT& P) const { return X==P.X && Y==P.Y ; } bool operator!=(cFPOINT& P) const { return X!=P.X || Y!=P.Y ; } FPOINT operator+ (cFPOINT& P) const { return FPOINT(X+P.X,Y+P.Y) ; } FPOINT operator- (cFPOINT& P) const { return FPOINT(X-P.X,Y-P.Y) ; } FPOINT operator* (cFPOINT& P) const { return FPOINT(X*P.X,Y*P.Y) ; } FPOINT operator* (cDOUBLE& F) const { return FPOINT(X*F ,Y*F ) ; } // In the event of 32 bit build problems, make the next line // conditional upon SIZEOF_LONG != SIZEOF_INT FPOINT operator* (cINT32& I) const { return FPOINT(X*I ,Y*I ) ; } FPOINT operator/ (cDOUBLE& F) const { cDOUBLE R=1/F ; return FPOINT(X*R ,Y*R ) ; } FPOINT operator+ () const { return *this ; } FPOINT operator- () const { return FPOINT(-X,-Y) ; } DOUBLE Length () const { return sqrt(X*X+Y*Y) ; } FPOINT Normalise () const { cDOUBLE L=Length() ; return L>0 ? *this/L : FPOINT(0,0) ; } } ; inline FPOINT operator*(cDOUBLE& F,cFPOINT& P) { return P*F ; } // In the event of 32 bit build problems, make the next line // conditional upon SIZEOF_LONG != SIZEOF_INT inline FPOINT operator*(cINT32& I,cFPOINT& P) { return P*I ; } struct GPOINT { INT32 X ; INT32 Y ; GPOINT() {} ; GPOINT( cINT32 X,cINT32 Y ) : X(X),Y(Y) {} ; GPOINT( cFPOINT P ) : X((INT32)P.X),Y((INT32)P.Y) {} ; bool operator==(cGPOINT& P) const { return X==P.X && Y==P.Y ; } bool operator!=(cGPOINT& P) const { return X!=P.X || Y!=P.Y ; } GPOINT operator+ (cGPOINT& P) const { return GPOINT(X+P.X,Y+P.Y) ; } GPOINT operator- (cGPOINT& P) const { return GPOINT(X-P.X,Y-P.Y) ; } GPOINT operator* ( cINT32& I) const { return GPOINT(X*I ,Y*I ) ; } GPOINT operator<<( cINT32& I) const { return GPOINT(X<>( cINT32& I) const { return GPOINT(X>>I ,Y>>I ) ; } GPOINT operator+ () const { return *this ; } GPOINT operator- () const { return GPOINT(-X,-Y) ; } } ; inline GPOINT operator*(cINT32& I,cGPOINT& P) { return P*I ; } inline FPOINT::FPOINT( cGPOINT P ) : X(P.X),Y(P.Y) {} /************************************************************************/ class CBezier { public : CBezier( cpcFPOINT C ) ; double Length( cDOUBLE T ) ; private : double BLength( cDOUBLE T ) ; double P0,P1,P2,P3,P4 ; } ; /************************************************************************/ struct BEVEL_FACE { GPOINT aFace[4] ; GBOOL bTriangle ; FPOINT Normal ; } ; struct DASH { DWORD Length ; DWORD Offset ; DWORD Array[8] ; } ; TypeDef( BEVEL_FACE ) TypeDef( DASH ) /************************************************************************/ class GenStroke { public : virtual ~GenStroke() { } enum { MAX_DASH_LENGTH = 8 } ; // // Returns path length (>=0) or error (<0). // // Errors are // -1 CalcBBox failed. // -2 Bad source path // -3 Out of path space // -4 Out of memory // INT32 StrokePathToPath( cpcPOINT pIPoints, cpcBYTE pITypes, UINT32 nILength, ppPOINT ppOPoints, ppBYTE ppOTypes, BOOL bClose, UINT32 nLineWidth, UINT32 nMitreLimit, // UINT32 nFlatness, DOUBLE nFlatness, const CapStyles LineCaps, const JoinStyles LineJoin, cpcDASH pDash ) ; protected : enum eEndStyle { // End of line styles END_UNDEFINED, END_JOIN, END_SMOOTH, END_START_CAP, END_END_CAP } ; CapStyles CapStyle ; JoinStyles JoinStyle ; DOUBLE FFlatness ; // Flatness DOUBLE FFlatness8 ; // Flatness*8 DOUBLE FLineWidth ; // LineWidth/2 DOUBLE FSqrLineWidth ; // LineWidth/4 DOUBLE FDivLineWidth ; // 2/LineWidth DOUBLE FDivSqrLineWidth ; // (1<<24)/(LineWidth/4) DOUBLE FMitreLimit ; // LineWidth/(2*MitreLimit)<<32 DOUBLE FSmoothLimit ; DOUBLE FStrokeLimit ; // LineWidth*3/4*0.001 pGPOINT pOutputPoints ; // -> Output path points pBYTE pOutputTypes ; // -> Output path types UINT32 nOutputLength ; // Length of output arrays UINT32 nMaxOutputLength ; // Maximum allowed length of output arrays FPOINT FirstPoint1 ; // First point not equal to StartPoint FPOINT FirstPoint2 ; // First point not equal to StartPoint FPOINT FirstPoint ; // First point not equal to StartPoint FPOINT SecondPoint1 ; // Next point not equal to FirstPoint FPOINT SecondPoint2 ; // Next point not equal to FirstPoint FPOINT SecondPoint ; // Next point not equal to FirstPoint FPOINT ThisPoint1 ; // Current point of path FPOINT ThisPoint2 ; // Current point of path FPOINT ThisPoint ; // Current point of path FPOINT PrevPoint1 ; // Previous point to ThisPoint, but not same as ThisPoint FPOINT PrevPoint2 ; // Previous point to ThisPoint, but not same as ThisPoint FPOINT PrevPoint ; // Previous point to ThisPoint, but not same as ThisPoint FPOINT LastPoint1 ; // Previous point to PrevPoint, but not same as PrevPoint FPOINT LastPoint2 ; // Previous point to PrevPoint, but not same as PrevPoint FPOINT LastPoint ; // Previous point to PrevPoint, but not same as PrevPoint FPOINT FirstOffsetS ; // Offset for line from StartPoint to FirstPoint FPOINT FirstOffsetE ; // Offset for line from StartPoint to FirstPoint FPOINT SecondOffsetS ; // Offset for line from FirstPoint to SecondPoint FPOINT SecondOffsetE ; // Offset for line from FirstPoint to SecondPoint FPOINT ThisOffsetS ; // Offset for line from PrevPoint to ThisPoint FPOINT ThisOffsetE ; // Offset for line from PrevPoint to ThisPoint FPOINT PrevOffsetS ; // Offset for line from LastPoint to PrevPoint FPOINT PrevOffsetE ; // Offset for line from LastPoint to PrevPoint FPOINT ThisMitre ; // Offset from PrevPoint to mitre FPOINT PrevMitre ; // Offset from LastPoint to mitre DOUBLE ThisSin ; // Positive if bend at PrevPoint to left else negative DOUBLE PrevSin ; // Positive if bend at LastPoint to left else negative DOUBLE ThisCos ; // COS of angle at PrevPoint DOUBLE FirstLengthS ; // Length of line from StartPoint to FirstPoint DOUBLE FirstLengthE ; // Length of line from StartPoint to FirstPoint DOUBLE SecondLengthS ; // Length of line from FirstPoint to SecondPoint DOUBLE SecondLengthE ; // Length of line from FirstPoint to SecondPoint DOUBLE ThisLengthS ; // Length of line from PrevPoint to ThisPoint DOUBLE ThisLengthE ; // Length of line from PrevPoint to ThisPoint DOUBLE PrevLengthE ; // Length of line from LastPoint to PrevPoint GBOOL ThisMitreFlag ; // Set if mitre length at PrevPoint less than MitreLimit GBOOL PrevMitreFlag ; // Set if mitre length at LastPoint less than MitreLimit GBOOL ThisLengthFlag ; // Set if dashed or lines shorter than mitre at PrevPoint GBOOL PrevLengthFlag ; // Set if dashed or lines shorter than mitre at LastPoint eEndStyle FirstLineEnd ; // At FirstPoint : Line end type eEndStyle ThisLineEnd ; // At ThisPoint : Line end type eEndStyle PrevLineEnd ; // At PrevPoint : Line end type eEndStyle LastLineEnd ; // At LastPoint : Line end type GBOOL FirstIsCurve ; GBOOL SecondIsCurve ; GBOOL ThisIsCurve ; GBOOL PrevIsCurve ; GBOOL LastIsCurve ; GBOOL FirstOSign ; GBOOL FirstISign ; GBOOL SecondOSign ; GBOOL SecondISign ; GBOOL ThisOSign ; GBOOL ThisISign ; GBOOL PrevOSign ; GBOOL PrevISign ; GBOOL LastOSign ; GBOOL LastISign ; size_t DashArrayLength ; INT32 DashStartRemain ; DOUBLE DashRemain ; UINT32 DashStartCount ; UINT32 DashCount ; GBOOL DashStartState ; GBOOL DashState ; GBOOL DashFlag ; UINT32 DashTotalLength ; UINT32 aDashArray[MAX_DASH_LENGTH] ; GBOOL bInner ; GBOOL bOuter ; FPOINT PrevCOffset ; FPOINT ThisCOffset ; static cFLOAT aArcTable[0x201] ; static cpcFLOAT pArcTable ; void StrokePath( cpcGPOINT pInputPoints, cpcBYTE pInputTypes, cUINT32 InputLength, cGBOOL bClose, cUINT32 LineWidth, cUINT32 MitreLimit, // cUINT32 nFlatness, cDOUBLE nFlatness, const CapStyles LineCaps, const JoinStyles LineJoin, cpcDASH pDash ) ; void StrokeLine ( cFPOINT EndPoint, const eEndStyle End = END_JOIN ) ; void StrokeCurve( FPOINT C[4] ) ; void StrokeCurve( cpcFPOINT FPoint, cGBOOL bOSign,cGBOOL bISign ) ; void StrokeCurve( cpcFPOINT FPoint, const eEndStyle End, cGBOOL bOSign,cGBOOL bISign ) ; void GenSection( cFPOINT Point1,cFPOINT Point2,cFPOINT Point, cFPOINT OffsetS,cDOUBLE LengthS, cFPOINT OffsetE,cDOUBLE LengthE, const eEndStyle LineEnd, cGBOOL IsCurve, cGBOOL bOSign,cGBOOL bISign ) ; virtual void GenLineEdge() ; void GenStrokeCurves( cFPOINT P0,cFPOINT P1,cFPOINT P2,cFPOINT P3, cFPOINT N00,cFPOINT N33 ) ; void GenStrokeInnerCurves( cFPOINT P0,cFPOINT P1,cFPOINT P2,cFPOINT P3, cFPOINT N00,cFPOINT N33 ) ; void DoStrokeCurves( cINT32 Depth, cFPOINT P06,cFPOINT P26,cFPOINT P46,cFPOINT P66, cFPOINT PC1,cFPOINT PC2, cFPOINT T06,cFPOINT T26,cFPOINT T46,cFPOINT T66, cFPOINT N06,cFPOINT N26,cFPOINT N46,cFPOINT N66 ) ; void SplitCurve( cpFPOINT C0, cpFPOINT C1, cDOUBLE T ) ; void GenRoundCap( cFPOINT C,cFPOINT O ) ; void CalcCurveOffset() ; void AddPoint( UINT32 n ) ; virtual void MoveTo_Start( cDOUBLE X,cDOUBLE Y ) ; virtual void LineTo_Start( cDOUBLE X,cDOUBLE Y ) ; virtual void LineTo_End ( cDOUBLE X,cDOUBLE Y ) ; virtual void Close() ; virtual void LineTo( cFPOINT C0,cFPOINT C1, cFPOINT P0,cFPOINT P1 ) ; virtual void CurveTo( cFPOINT C0,cFPOINT C1,cFPOINT C2,cFPOINT C3, cFPOINT P0,cFPOINT P1,cFPOINT P2,cFPOINT P3 ) ; void Set_Prev( cFPOINT P ) ; virtual void PathOpen () {} ; virtual void PathClose() {} ; enum { PT_PATHELEMENT = 6 // Path element mask } ; inline GBOOL IsClosed ( cBYTE Type ) { return (Type & PT_CLOSEFIGURE) ; } inline GBOOL IsntClosed ( cBYTE Type ) { return !(Type & PT_CLOSEFIGURE) ; } inline GBOOL IsMoveTo ( cBYTE Type ) { return (Type & PT_PATHELEMENT)==PT_MOVETO ; } ; inline GBOOL IsntMoveTo ( cBYTE Type ) { return (Type & PT_PATHELEMENT)!=PT_MOVETO ; } ; inline GBOOL IsLineTo ( cBYTE Type ) { return (Type & PT_PATHELEMENT)==PT_LINETO ; } ; inline GBOOL IsntLineTo ( cBYTE Type ) { return (Type & PT_PATHELEMENT)!=PT_LINETO ; } ; inline GBOOL IsBezierTo( cBYTE Type ) { return (Type & PT_PATHELEMENT)==PT_BEZIERTO ; } ; inline GBOOL IsntBezierTo( cBYTE Type ) { return (Type & PT_PATHELEMENT)!=PT_BEZIERTO ; } ; } ; /************************************************************************/ class GenPathContour : public GenStroke { public : // // Set bOuter for outer contour. // // Returns path length (>=0) or error (<0). // // Errors are // -1 CalcBBox failed. // -2 Bad source path // -3 Out of path space // -4 Out of memory // INT32 ContourPath( cpcPOINT pIPoints, cpcBYTE pITypes, UINT32 nILength, ppPOINT ppOPoints, ppBYTE ppOTypes, UINT32 LineWidth, UINT32 MitreLimit, // UINT32 nFlatness, DOUBLE nFlatness, const JoinStyles LineJoin, bool bOuter ) ; protected : bool bStart ; void GenLineEdge() ; void GenOuterEdge() ; void GenInnerEdge() ; void LineTo_Start( cDOUBLE X,cDOUBLE Y ) ; void PathOpen () { bStart = true ; } void PathClose() { if (!bStart) Close() ; } } ; /************************************************************************/ class GenBevelFaces : public GenStroke { public : // // Set bOuter for outer contour. // // Returns number of bevel faces (>=0) or error (<0). // // Errors are // -1 CalcBBox failed. // -2 Bad source path // -3 Out of path space // -4 Out of memory // INT32 BevelPath( cpcPOINT pIPoints, cpcBYTE pITypes, UINT32 ILength, ppBEVEL_FACE ppOutputFaces, UINT32 LineWidth, UINT32 MitreLimit, // UINT32 nFlatness, DOUBLE nFlatness, const JoinStyles LineJoin, bool bOuter ) ; protected : pBEVEL_FACE pBFaces ; // -> Bevel faces UINT32 nMaxBFaces ; // Maximum number of bevel faces. UINT32 nBFaces ; // Current number of bevel faces. pBEVEL_FACE NewBFace() ; void GenLineEdge() ; void GenOuterEdge() ; void GenInnerEdge() ; void LineTo( cFPOINT C0,cFPOINT C1, cFPOINT P0,cFPOINT P1 ) ; void CurveTo( cFPOINT C0,cFPOINT C1,cFPOINT C2,cFPOINT C3, cFPOINT P0,cFPOINT P1,cFPOINT P2,cFPOINT P3 ) ; void CurveTo( cFPOINT C, cFPOINT P0,cFPOINT P1,cFPOINT P2,cFPOINT P3 ) ; } ; /************************************************************************/