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