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