1*8b851043SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*8b851043SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*8b851043SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*8b851043SAndrew Rist * distributed with this work for additional information 6*8b851043SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*8b851043SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*8b851043SAndrew Rist * "License"); you may not use this file except in compliance 9*8b851043SAndrew Rist * with the License. You may obtain a copy of the License at 10*8b851043SAndrew Rist * 11*8b851043SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*8b851043SAndrew Rist * 13*8b851043SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*8b851043SAndrew Rist * software distributed under the License is distributed on an 15*8b851043SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*8b851043SAndrew Rist * KIND, either express or implied. See the License for the 17*8b851043SAndrew Rist * specific language governing permissions and limitations 18*8b851043SAndrew Rist * under the License. 19*8b851043SAndrew Rist * 20*8b851043SAndrew Rist *************************************************************/ 21*8b851043SAndrew Rist 22*8b851043SAndrew Rist 23cdf0e10cSrcweir #ifndef _TL_POLY_HXX 24cdf0e10cSrcweir #define _TL_POLY_HXX 25cdf0e10cSrcweir 26cdf0e10cSrcweir #include "tools/toolsdllapi.h" 27cdf0e10cSrcweir #include <tools/gen.hxx> 28cdf0e10cSrcweir #include <tools/debug.hxx> 29cdf0e10cSrcweir 30cdf0e10cSrcweir #include <vector> 31cdf0e10cSrcweir 32cdf0e10cSrcweir // ----------- 33cdf0e10cSrcweir // - Defines - 34cdf0e10cSrcweir // ----------- 35cdf0e10cSrcweir 36cdf0e10cSrcweir #define POLY_APPEND (0xFFFF) 37cdf0e10cSrcweir #define POLYPOLY_APPEND (0xFFFF) 38cdf0e10cSrcweir 39cdf0e10cSrcweir // ------------------------------------------------------------------------ 40cdf0e10cSrcweir 41cdf0e10cSrcweir #define POLY_OPTIMIZE_NONE 0x00000000UL 42cdf0e10cSrcweir #define POLY_OPTIMIZE_OPEN 0x00000001UL 43cdf0e10cSrcweir #define POLY_OPTIMIZE_CLOSE 0x00000002UL 44cdf0e10cSrcweir #define POLY_OPTIMIZE_NO_SAME 0x00000004UL 45cdf0e10cSrcweir #define POLY_OPTIMIZE_REDUCE 0x00000008UL 46cdf0e10cSrcweir #define POLY_OPTIMIZE_EDGES 0x00000010UL 47cdf0e10cSrcweir 48cdf0e10cSrcweir // ------------- 49cdf0e10cSrcweir // - PolyStyle - 50cdf0e10cSrcweir // ------------- 51cdf0e10cSrcweir 52cdf0e10cSrcweir enum PolyStyle 53cdf0e10cSrcweir { 54cdf0e10cSrcweir POLY_ARC = 1, 55cdf0e10cSrcweir POLY_PIE = 2, 56cdf0e10cSrcweir POLY_CHORD = 3 57cdf0e10cSrcweir }; 58cdf0e10cSrcweir 59cdf0e10cSrcweir // ------------- 60cdf0e10cSrcweir // - PolyFlags - 61cdf0e10cSrcweir // ------------- 62cdf0e10cSrcweir 63cdf0e10cSrcweir #ifndef ENUM_POLYFLAGS_DECLARED 64cdf0e10cSrcweir #define ENUM_POLYFLAGS_DECLARED 65cdf0e10cSrcweir enum PolyFlags 66cdf0e10cSrcweir { 67cdf0e10cSrcweir POLY_NORMAL, 68cdf0e10cSrcweir POLY_SMOOTH, 69cdf0e10cSrcweir POLY_CONTROL, 70cdf0e10cSrcweir POLY_SYMMTR 71cdf0e10cSrcweir }; 72cdf0e10cSrcweir #endif 73cdf0e10cSrcweir 74cdf0e10cSrcweir // ---------------- 75cdf0e10cSrcweir // - PolyOptimize - 76cdf0e10cSrcweir // ---------------- 77cdf0e10cSrcweir 78cdf0e10cSrcweir class PolyOptimizeData 79cdf0e10cSrcweir { 80cdf0e10cSrcweir private: 81cdf0e10cSrcweir 82cdf0e10cSrcweir enum DataType { DATA_NONE = 0, DATA_ABSOLUT = 1, DATA_PERCENT = 2 }; 83cdf0e10cSrcweir DataType eType; 84cdf0e10cSrcweir union { sal_uIntPtr mnAbsolut; sal_uInt16 mnPercent; }; 85cdf0e10cSrcweir 86cdf0e10cSrcweir public: 87cdf0e10cSrcweir 88cdf0e10cSrcweir PolyOptimizeData() : eType( DATA_NONE ) {} 89cdf0e10cSrcweir PolyOptimizeData( sal_uIntPtr nAbsolut ) : eType( DATA_ABSOLUT ), mnAbsolut( nAbsolut ) {} 90cdf0e10cSrcweir PolyOptimizeData( sal_uInt16 nPercent ) : eType( DATA_PERCENT ), mnPercent( nPercent ) {} 91cdf0e10cSrcweir 92cdf0e10cSrcweir sal_uIntPtr GetAbsValue() const { DBG_ASSERT( eType == DATA_ABSOLUT, "Wrong data type" ); return mnAbsolut; } 93cdf0e10cSrcweir sal_uInt16 GetPercentValue() const { DBG_ASSERT( eType == DATA_PERCENT, "Wrong data type" ); return mnPercent; } 94cdf0e10cSrcweir }; 95cdf0e10cSrcweir 96cdf0e10cSrcweir // ----------- 97cdf0e10cSrcweir // - Polygon - 98cdf0e10cSrcweir // ----------- 99cdf0e10cSrcweir 100cdf0e10cSrcweir class SvStream; 101cdf0e10cSrcweir class ImplPolygon; 102cdf0e10cSrcweir class ImplPolyPolygon; 103cdf0e10cSrcweir class PolyPolygon; 104cdf0e10cSrcweir 105cdf0e10cSrcweir namespace basegfx 106cdf0e10cSrcweir { 107cdf0e10cSrcweir class B2DPolygon; 108cdf0e10cSrcweir class B2DPolyPolygon; 109cdf0e10cSrcweir } // end of namespace basegfx 110cdf0e10cSrcweir 111cdf0e10cSrcweir class TOOLS_DLLPUBLIC Polygon 112cdf0e10cSrcweir { 113cdf0e10cSrcweir private: 114cdf0e10cSrcweir 115cdf0e10cSrcweir ImplPolygon* mpImplPolygon; 116cdf0e10cSrcweir 117cdf0e10cSrcweir TOOLS_DLLPRIVATE inline void ImplMakeUnique(); 118cdf0e10cSrcweir 119cdf0e10cSrcweir //#if 0 // _SOLAR__PRIVATE 120cdf0e10cSrcweir 121cdf0e10cSrcweir public: 122cdf0e10cSrcweir 123cdf0e10cSrcweir Point* ImplGetPointAry(); 124cdf0e10cSrcweir sal_uInt8* ImplGetFlagAry(); 125cdf0e10cSrcweir 126cdf0e10cSrcweir static void ImplReduceEdges( Polygon& rPoly, const double& rArea, sal_uInt16 nPercent ); 127cdf0e10cSrcweir void ImplRead( SvStream& rIStream ); 128cdf0e10cSrcweir void ImplWrite( SvStream& rOStream ) const; 129cdf0e10cSrcweir 130cdf0e10cSrcweir //#endif // __PRIVATE 131cdf0e10cSrcweir 132cdf0e10cSrcweir public: 133cdf0e10cSrcweir Polygon(); 134cdf0e10cSrcweir Polygon( sal_uInt16 nSize ); 135cdf0e10cSrcweir Polygon( sal_uInt16 nPoints, const Point* pPtAry, 136cdf0e10cSrcweir const sal_uInt8* pFlagAry = NULL ); 137cdf0e10cSrcweir Polygon( const Rectangle& rRect ); 138cdf0e10cSrcweir Polygon( const Rectangle& rRect, 139cdf0e10cSrcweir sal_uIntPtr nHorzRound, sal_uIntPtr nVertRound ); 140cdf0e10cSrcweir Polygon( const Point& rCenter, 141cdf0e10cSrcweir long nRadX, long nRadY, 142cdf0e10cSrcweir sal_uInt16 nPoints = 0 ); 143cdf0e10cSrcweir Polygon( const Rectangle& rBound, 144cdf0e10cSrcweir const Point& rStart, const Point& rEnd, 145cdf0e10cSrcweir PolyStyle ePolyStyle = POLY_ARC ); 146cdf0e10cSrcweir Polygon( const Point& rBezPt1, const Point& rCtrlPt1, 147cdf0e10cSrcweir const Point& rBezPt2, const Point& rCtrlPt2, 148cdf0e10cSrcweir sal_uInt16 nPoints = 0 ); 149cdf0e10cSrcweir 150cdf0e10cSrcweir Polygon( const Polygon& rPoly ); 151cdf0e10cSrcweir ~Polygon(); 152cdf0e10cSrcweir 153cdf0e10cSrcweir void SetPoint( const Point& rPt, sal_uInt16 nPos ); 154cdf0e10cSrcweir const Point& GetPoint( sal_uInt16 nPos ) const; 155cdf0e10cSrcweir 156cdf0e10cSrcweir void SetFlags( sal_uInt16 nPos, PolyFlags eFlags ); 157cdf0e10cSrcweir PolyFlags GetFlags( sal_uInt16 nPos ) const; 158cdf0e10cSrcweir sal_Bool HasFlags() const; 159cdf0e10cSrcweir 160cdf0e10cSrcweir sal_Bool IsControl( sal_uInt16 nPos ) const; 161cdf0e10cSrcweir sal_Bool IsSmooth( sal_uInt16 nPos ) const; 162cdf0e10cSrcweir sal_Bool IsRect() const; 163cdf0e10cSrcweir 164cdf0e10cSrcweir void SetSize( sal_uInt16 nNewSize ); 165cdf0e10cSrcweir sal_uInt16 GetSize() const; 166cdf0e10cSrcweir 167cdf0e10cSrcweir void Clear(); 168cdf0e10cSrcweir 169cdf0e10cSrcweir Rectangle GetBoundRect() const; 170cdf0e10cSrcweir double GetArea() const; 171cdf0e10cSrcweir double GetSignedArea() const; 172cdf0e10cSrcweir sal_Bool IsInside( const Point& rPt ) const; 173cdf0e10cSrcweir sal_Bool IsRightOrientated() const; 174cdf0e10cSrcweir double CalcDistance( sal_uInt16 nPt1, sal_uInt16 nPt2 ); 175cdf0e10cSrcweir void Clip( const Rectangle& rRect, sal_Bool bPolygon = sal_True ); 176cdf0e10cSrcweir void Optimize( sal_uIntPtr nOptimizeFlags, const PolyOptimizeData* pData = NULL ); 177cdf0e10cSrcweir 178cdf0e10cSrcweir /** Adaptive subdivision of polygons with curves 179cdf0e10cSrcweir 180cdf0e10cSrcweir This method adaptively subdivides bezier arcs within the 181cdf0e10cSrcweir polygon to straight line segments and returns the resulting 182cdf0e10cSrcweir polygon. 183cdf0e10cSrcweir 184cdf0e10cSrcweir @param rResult 185cdf0e10cSrcweir The resulting subdivided polygon 186cdf0e10cSrcweir 187cdf0e10cSrcweir @param d 188cdf0e10cSrcweir This parameter controls the amount of subdivision. The 189cdf0e10cSrcweir original curve is guaranteed to not differ by more than this 190cdf0e10cSrcweir amount per bezier segment from the subdivided 191cdf0e10cSrcweir lines. Concretely, if the polygon is in device coordinates and 192cdf0e10cSrcweir d equals 1.0, then the difference between the subdivided and 193cdf0e10cSrcweir the original polygon is guaranteed to be smaller than one 194cdf0e10cSrcweir pixel. 195cdf0e10cSrcweir */ 196cdf0e10cSrcweir void AdaptiveSubdivide( Polygon& rResult, const double d = 1.0 ) const; 197cdf0e10cSrcweir 198cdf0e10cSrcweir void GetIntersection( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const; 199cdf0e10cSrcweir void GetUnion( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const; 200cdf0e10cSrcweir void GetDifference( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const; 201cdf0e10cSrcweir void GetXOR( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const; 202cdf0e10cSrcweir 203cdf0e10cSrcweir void Move( long nHorzMove, long nVertMove ); 204cdf0e10cSrcweir void Translate( const Point& rTrans ); 205cdf0e10cSrcweir void Scale( double fScaleX, double fScaleY ); 206cdf0e10cSrcweir void Rotate( const Point& rCenter, double fSin, double fCos ); 207cdf0e10cSrcweir void Rotate( const Point& rCenter, sal_uInt16 nAngle10 ); 208cdf0e10cSrcweir void SlantX( long nYRef, double fSin, double fCos ); 209cdf0e10cSrcweir void SlantY( long nXRef, double fSin, double fCos ); 210cdf0e10cSrcweir void Distort( const Rectangle& rRefRect, const Polygon& rDistortedRect ); 211cdf0e10cSrcweir 212cdf0e10cSrcweir void Insert( sal_uInt16 nPos, const Point& rPt, PolyFlags eFlags = POLY_NORMAL ); 213cdf0e10cSrcweir void Insert( sal_uInt16 nPos, const Polygon& rPoly ); 214cdf0e10cSrcweir void Remove( sal_uInt16 nPos, sal_uInt16 nCount ); 215cdf0e10cSrcweir 216cdf0e10cSrcweir const Point& operator[]( sal_uInt16 nPos ) const { return GetPoint( nPos ); } 217cdf0e10cSrcweir Point& operator[]( sal_uInt16 nPos ); 218cdf0e10cSrcweir 219cdf0e10cSrcweir Polygon& operator=( const Polygon& rPoly ); 220cdf0e10cSrcweir sal_Bool operator==( const Polygon& rPoly ) const; 221cdf0e10cSrcweir sal_Bool operator!=( const Polygon& rPoly ) const 222cdf0e10cSrcweir { return !(Polygon::operator==( rPoly )); } 223cdf0e10cSrcweir sal_Bool IsEqual( const Polygon& rPoly ) const; 224cdf0e10cSrcweir 225cdf0e10cSrcweir // streaming a Polygon does ignore PolyFlags, so use the Write Or Read 226cdf0e10cSrcweir // method to take care of PolyFlags 227cdf0e10cSrcweir TOOLS_DLLPUBLIC friend SvStream& operator>>( SvStream& rIStream, Polygon& rPoly ); 228cdf0e10cSrcweir TOOLS_DLLPUBLIC friend SvStream& operator<<( SvStream& rOStream, const Polygon& rPoly ); 229cdf0e10cSrcweir 230cdf0e10cSrcweir void Read( SvStream& rIStream ); 231cdf0e10cSrcweir void Write( SvStream& rOStream ) const; 232cdf0e10cSrcweir 233cdf0e10cSrcweir const Point* GetConstPointAry() const; 234cdf0e10cSrcweir const sal_uInt8* GetConstFlagAry() const; 235cdf0e10cSrcweir 236cdf0e10cSrcweir // convert to ::basegfx::B2DPolygon and return 237cdf0e10cSrcweir ::basegfx::B2DPolygon getB2DPolygon() const; 238cdf0e10cSrcweir 239cdf0e10cSrcweir // constructor to convert from ::basegfx::B2DPolygon 240cdf0e10cSrcweir // #i76339# made explicit 241cdf0e10cSrcweir explicit Polygon(const ::basegfx::B2DPolygon& rPolygon); 242cdf0e10cSrcweir }; 243cdf0e10cSrcweir 244cdf0e10cSrcweir // --------------- 245cdf0e10cSrcweir // - PolyPolygon - 246cdf0e10cSrcweir // --------------- 247cdf0e10cSrcweir 248cdf0e10cSrcweir class TOOLS_DLLPUBLIC PolyPolygon 249cdf0e10cSrcweir { 250cdf0e10cSrcweir private: 251cdf0e10cSrcweir 252cdf0e10cSrcweir ImplPolyPolygon* mpImplPolyPolygon; 253cdf0e10cSrcweir 254cdf0e10cSrcweir //#if 0 // _SOLAR__PRIVATE 255cdf0e10cSrcweir TOOLS_DLLPRIVATE void ImplDoOperation( const PolyPolygon& rPolyPoly, PolyPolygon& rResult, sal_uIntPtr nOperation ) const; 256cdf0e10cSrcweir TOOLS_DLLPRIVATE void *ImplCreateArtVpath() const; 257cdf0e10cSrcweir TOOLS_DLLPRIVATE void ImplSetFromArtVpath( void *pVpath ); 258cdf0e10cSrcweir //#endif // __PRIVATE 259cdf0e10cSrcweir 260cdf0e10cSrcweir public: 261cdf0e10cSrcweir 262cdf0e10cSrcweir PolyPolygon( sal_uInt16 nInitSize = 16, sal_uInt16 nResize = 16 ); 263cdf0e10cSrcweir PolyPolygon( const Polygon& rPoly ); 264cdf0e10cSrcweir PolyPolygon( sal_uInt16 nPoly, const sal_uInt16* pPointCountAry, 265cdf0e10cSrcweir const Point* pPtAry ); 266cdf0e10cSrcweir PolyPolygon( const PolyPolygon& rPolyPoly ); 267cdf0e10cSrcweir ~PolyPolygon(); 268cdf0e10cSrcweir 269cdf0e10cSrcweir void Insert( const Polygon& rPoly, sal_uInt16 nPos = POLYPOLY_APPEND ); 270cdf0e10cSrcweir void Remove( sal_uInt16 nPos ); 271cdf0e10cSrcweir void Replace( const Polygon& rPoly, sal_uInt16 nPos ); 272cdf0e10cSrcweir const Polygon& GetObject( sal_uInt16 nPos ) const; 273cdf0e10cSrcweir 274cdf0e10cSrcweir sal_Bool IsRect() const; 275cdf0e10cSrcweir 276cdf0e10cSrcweir void Clear(); 277cdf0e10cSrcweir 278cdf0e10cSrcweir sal_uInt16 Count() const; 279cdf0e10cSrcweir Rectangle GetBoundRect() const; 280cdf0e10cSrcweir void Clip( const Rectangle& rRect ); 281cdf0e10cSrcweir void Optimize( sal_uIntPtr nOptimizeFlags, const PolyOptimizeData* pData = NULL ); 282cdf0e10cSrcweir 283cdf0e10cSrcweir /** Adaptive subdivision of polygons with curves 284cdf0e10cSrcweir 285cdf0e10cSrcweir This method adaptively subdivides bezier arcs within the 286cdf0e10cSrcweir polygon to straight line segments and returns the resulting 287cdf0e10cSrcweir polygon. 288cdf0e10cSrcweir 289cdf0e10cSrcweir @param rResult 290cdf0e10cSrcweir The resulting subdivided polygon 291cdf0e10cSrcweir 292cdf0e10cSrcweir @param d 293cdf0e10cSrcweir This parameter controls the amount of subdivision. The 294cdf0e10cSrcweir original curve is guaranteed to not differ by more than this 295cdf0e10cSrcweir amount per bezier segment from the subdivided 296cdf0e10cSrcweir lines. Concretely, if the polygon is in device coordinates and 297cdf0e10cSrcweir d equals 1.0, then the difference between the subdivided and 298cdf0e10cSrcweir the original polygon is guaranteed to be smaller than one 299cdf0e10cSrcweir pixel. 300cdf0e10cSrcweir */ 301cdf0e10cSrcweir void AdaptiveSubdivide( PolyPolygon& rResult, const double d = 1.0 ) const; 302cdf0e10cSrcweir 303cdf0e10cSrcweir void GetIntersection( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const; 304cdf0e10cSrcweir void GetUnion( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const; 305cdf0e10cSrcweir void GetDifference( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const; 306cdf0e10cSrcweir void GetXOR( const PolyPolygon& rPolyPoly, PolyPolygon& rResult ) const; 307cdf0e10cSrcweir 308cdf0e10cSrcweir void Move( long nHorzMove, long nVertMove ); 309cdf0e10cSrcweir void Translate( const Point& rTrans ); 310cdf0e10cSrcweir void Scale( double fScaleX, double fScaleY ); 311cdf0e10cSrcweir void Rotate( const Point& rCenter, double fSin, double fCos ); 312cdf0e10cSrcweir void Rotate( const Point& rCenter, sal_uInt16 nAngle10 ); 313cdf0e10cSrcweir void SlantX( long nYRef, double fSin, double fCos ); 314cdf0e10cSrcweir void SlantY( long nXRef, double fSin, double fCos ); 315cdf0e10cSrcweir void Distort( const Rectangle& rRefRect, const Polygon& rDistortedRect ); 316cdf0e10cSrcweir 317cdf0e10cSrcweir const Polygon& operator[]( sal_uInt16 nPos ) const { return GetObject( nPos ); } 318cdf0e10cSrcweir Polygon& operator[]( sal_uInt16 nPos ); 319cdf0e10cSrcweir 320cdf0e10cSrcweir PolyPolygon& operator=( const PolyPolygon& rPolyPoly ); 321cdf0e10cSrcweir sal_Bool operator==( const PolyPolygon& rPolyPoly ) const; 322cdf0e10cSrcweir sal_Bool operator!=( const PolyPolygon& rPolyPoly ) const 323cdf0e10cSrcweir { return !(PolyPolygon::operator==( rPolyPoly )); } 324cdf0e10cSrcweir 325cdf0e10cSrcweir sal_Bool IsEqual( const PolyPolygon& rPolyPoly ) const; 326cdf0e10cSrcweir 327cdf0e10cSrcweir TOOLS_DLLPUBLIC friend SvStream& operator>>( SvStream& rIStream, PolyPolygon& rPolyPoly ); 328cdf0e10cSrcweir TOOLS_DLLPUBLIC friend SvStream& operator<<( SvStream& rOStream, const PolyPolygon& rPolyPoly ); 329cdf0e10cSrcweir 330cdf0e10cSrcweir void Read( SvStream& rIStream ); 331cdf0e10cSrcweir void Write( SvStream& rOStream ) const; 332cdf0e10cSrcweir 333cdf0e10cSrcweir // convert to ::basegfx::B2DPolyPolygon and return 334cdf0e10cSrcweir ::basegfx::B2DPolyPolygon getB2DPolyPolygon() const; 335cdf0e10cSrcweir 336cdf0e10cSrcweir // constructor to convert from ::basegfx::B2DPolyPolygon 337cdf0e10cSrcweir // #i76339# made explicit 338cdf0e10cSrcweir explicit PolyPolygon(const ::basegfx::B2DPolyPolygon& rPolyPolygon); 339cdf0e10cSrcweir }; 340cdf0e10cSrcweir 341cdf0e10cSrcweir typedef std::vector< PolyPolygon > PolyPolyVector; 342cdf0e10cSrcweir 343cdf0e10cSrcweir #endif // _SV_POLY_HXX 344