1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 5 * This Source Code Form is subject to the terms of the Mozilla Public 6 * License, v. 2.0. If a copy of the MPL was not distributed with this 7 * file, You can obtain one at http://mozilla.org/MPL/2.0/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 11 * Licensed to the Apache Software Foundation (ASF) under one or more 12 * contributor license agreements. See the NOTICE file distributed 13 * with this work for additional information regarding copyright 14 * ownership. The ASF licenses this file to you under the Apache 15 * License, Version 2.0 (the "License"); you may not use this file 16 * except in compliance with the License. You may obtain a copy of 17 * the License at http://www.apache.org/licenses/LICENSE-2.0 . 18 */ 19 20 #pragma once 21 22 #include <basegfx/point/b2dpoint.hxx> 23 #include <basegfx/polygon/b3dpolypolygon.hxx> 24 #include <com/sun/star/drawing/PointSequenceSequence.hpp> 25 #include <vector> 26 #include <basegfx/basegfxdllapi.h> 27 #include <o3tl/sorted_vector.hxx> 28 29 namespace com::sun::star::drawing { struct PolyPolygonBezierCoords; } 30 31 namespace basegfx 32 { 33 class B2DPolyPolygon; 34 class B2DRange; 35 } 36 37 namespace basegfx::utils 38 { 39 // B2DPolyPolygon tools 40 41 // Check and evtl. correct orientations of all contained Polygons so that 42 // the orientations of contained polygons will variate to express areas and 43 // holes 44 BASEGFX_DLLPUBLIC B2DPolyPolygon correctOrientations(const B2DPolyPolygon& rCandidate); 45 46 // make sure polygon with index 0L is not a hole. This may evtl. change the 47 // sequence of polygons, but allows to use polygon with index 0L to 48 // get the correct normal for the whole polyPolygon 49 BASEGFX_DLLPUBLIC B2DPolyPolygon correctOutmostPolygon(const B2DPolyPolygon& rCandidate); 50 51 // Subdivide all contained curves. Use distanceBound value if given. 52 BASEGFX_DLLPUBLIC B2DPolyPolygon adaptiveSubdivideByDistance(const B2DPolyPolygon& rCandidate, double fDistanceBound, int nRecurseLimit = 30); 53 54 // Subdivide all contained curves. Use distanceBound value if given. Else, a convenient one 55 // is created. 56 BASEGFX_DLLPUBLIC B2DPolyPolygon adaptiveSubdivideByAngle(const B2DPolyPolygon& rCandidate, double fAngleBound = 0.0); 57 58 // isInside test for B2dPoint. On border is not inside as long as not true is given 59 // in bWithBorder flag. It is assumed that the orientations of the given polygon are correct. 60 BASEGFX_DLLPUBLIC bool isInside(const B2DPolyPolygon& rCandidate, const B2DPoint& rPoint, bool bWithBorder = false); 61 62 /** Get the range of a polyPolygon 63 64 For detailed description look at getRange(const B2DPolygon&). 65 This method just expands by the range of every sub-Polygon. 66 67 @param rCandidate 68 The B2DPolyPolygon possibly containing bezier segments 69 70 @return 71 The outer range of the polygon 72 */ 73 BASEGFX_DLLPUBLIC B2DRange getRange(const B2DPolyPolygon& rCandidate); 74 75 // get signed area of polygon 76 BASEGFX_DLLPUBLIC double getSignedArea(const B2DPolyPolygon& rCandidate); 77 78 // get area of polygon 79 BASEGFX_DLLPUBLIC double getArea(const B2DPolyPolygon& rCandidate); 80 81 /** Apply given LineDashing to given polyPolygon 82 83 For a description see applyLineDashing in b2dpolygontoos.hxx 84 */ 85 BASEGFX_DLLPUBLIC void applyLineDashing( 86 const B2DPolyPolygon& rCandidate, 87 const ::std::vector<double>& rDotDashArray, 88 B2DPolyPolygon* pLineTarget, 89 double fFullDashDotLen = 0.0); 90 91 // test if point is inside epsilon-range around the given PolyPolygon. Can be used 92 // for HitTesting. The epsilon-range is defined to be the tube around the PolyPolygon 93 // with distance fDistance and rounded edges (start and end point). 94 BASEGFX_DLLPUBLIC bool isInEpsilonRange(const B2DPolyPolygon& rCandidate, const B2DPoint& rTestPosition, double fDistance); 95 96 /** Helper class to transport PointIndices to a PolyPolygon, 97 with an operator< for convenient sorting in a std::set usage 98 */ 99 class SAL_WARN_UNUSED BASEGFX_DLLPUBLIC PointIndex 100 { 101 private: 102 sal_uInt32 mnPolygonIndex; 103 sal_uInt32 mnPointIndex; 104 105 public: PointIndex(sal_uInt32 nPolygonIndex,sal_uInt32 nPointIndex)106 PointIndex(sal_uInt32 nPolygonIndex, sal_uInt32 nPointIndex) 107 : mnPolygonIndex(nPolygonIndex), 108 mnPointIndex(nPointIndex) 109 {} 110 getPolygonIndex() const111 sal_uInt32 getPolygonIndex() const { return mnPolygonIndex; } getPointIndex() const112 sal_uInt32 getPointIndex() const { return mnPointIndex; } 113 bool operator<(const PointIndex& rComp) const; 114 }; 115 116 /** the PointIndexSet itself; it allows to define a 'selection'of 117 points in a tools::PolyPolygon by giving the polygon and point index. 118 Adding points double makes no sense, hence the std::set 119 */ 120 typedef o3tl::sorted_vector< PointIndex > PointIndexSet; 121 122 /** Read poly-polygon from SVG. 123 124 This function imports a poly-polygon from an SVG-D 125 attribute. 126 127 @param o_rPolyPoly 128 The output poly-polygon 129 130 @param rSvgDAttribute 131 A valid SVG-D attribute string 132 133 @param bHandleRelativeNextPointCompatible 134 If set to true, the old error that after a relative 'z' command 135 the current point was not reset to the first point of the current 136 polygon is kept; this is needed to read odf files. 137 If false, pure svg is used; this is needed for svg import. 138 139 @param pHelpPointIndexSet 140 If given, all points created in the target PolyPolygon 141 which are only helper points are added here using their 142 point indices; this are currently points created from 143 import of the 'a' and 'A' svg:d statements which create 144 bezier curve info as representation and maybe points 145 which are no 'real' svg:d points, but helper points. It 146 is necessary to identify these e.g. when markers need to 147 be created in the svg import 148 149 @return true, if the string was successfully parsed 150 */ 151 BASEGFX_DLLPUBLIC bool importFromSvgD( 152 B2DPolyPolygon& o_rPolyPoly, 153 std::u16string_view rSvgDAttribute, 154 bool bHandleRelativeNextPointCompatible, 155 PointIndexSet* pHelpPointIndexSet); 156 157 // grow for polyPolygon. Move all geometry in each point in the direction of the normal in that point 158 // with the given amount. Value may be negative. 159 BASEGFX_DLLPUBLIC B2DPolyPolygon growInNormalDirection(const B2DPolyPolygon& rCandidate, double fValue); 160 161 // force all sub-polygons to a point count of nSegments 162 BASEGFX_DLLPUBLIC B2DPolyPolygon reSegmentPolyPolygon(const B2DPolyPolygon& rCandidate, sal_uInt32 nSegments); 163 164 // create polygon state at t from 0.0 to 1.0 between the two polygons. Both polygons must have the same 165 // organisation, e.g. same amount of polygons 166 BASEGFX_DLLPUBLIC B2DPolyPolygon interpolate(const B2DPolyPolygon& rOld1, const B2DPolyPolygon& rOld2, double t); 167 168 // create 3d tools::PolyPolygon from given 2d PolyPolygon. The given fZCoordinate is used to expand the 169 // third coordinate. 170 BASEGFX_DLLPUBLIC B3DPolyPolygon createB3DPolyPolygonFromB2DPolyPolygon(const B2DPolyPolygon& rCandidate, double fZCoordinate = 0.0); 171 172 // create 2d tools::PolyPolygon from given 3d PolyPolygon. All coordinates are transformed using the given 173 // matrix and the resulting x,y is used to form the new polygon. 174 BASEGFX_DLLPUBLIC B2DPolyPolygon createB2DPolyPolygonFromB3DPolyPolygon(const B3DPolyPolygon& rCandidate, const B3DHomMatrix& rMat); 175 176 // for each contained edge in each contained polygon calculate the smallest distance. Return the index to the smallest 177 // edge in rEdgeIndex and the index to the polygon in rPolygonIndex. The relative position on the edge is returned in rCut. 178 // If nothing was found (e.g. empty input plygon), DBL_MAX is returned. 179 BASEGFX_DLLPUBLIC double getSmallestDistancePointToPolyPolygon(const B2DPolyPolygon& rCandidate, const B2DPoint& rTestPoint, sal_uInt32& rPolygonIndex, sal_uInt32& rEdgeIndex, double& rCut); 180 181 // distort PolyPolygon. rOriginal describes the original range, where the given points describe the distorted 182 // corresponding points. 183 BASEGFX_DLLPUBLIC B2DPolyPolygon distort(const B2DPolyPolygon& rCandidate, const B2DRange& rOriginal, const B2DPoint& rTopLeft, const B2DPoint& rTopRight, const B2DPoint& rBottomLeft, const B2DPoint& rBottomRight); 184 185 // expand all segments (which are not yet) to curve segments. This is done with setting the control 186 // vectors on the 1/3 resp. 2/3 distances on each segment. 187 BASEGFX_DLLPUBLIC B2DPolyPolygon expandToCurve(const B2DPolyPolygon& rCandidate); 188 189 /** Predicate whether a given poly-polygon is a rectangle. 190 191 @param rPoly 192 tools::PolyPolygon to check 193 194 @return true, if the poly-polygon describes a rectangle 195 (contains exactly one polygon, polygon is closed, and the 196 points are either cw or ccw enumerations of a rectangle's 197 vertices). Note that intermediate points and duplicate 198 points are ignored. 199 */ 200 BASEGFX_DLLPUBLIC bool isRectangle( const B2DPolyPolygon& rPoly ); 201 202 /** Export poly-polygon to SVG. 203 204 This function exports a poly-polygon into an SVG-D 205 statement. Currently, output of relative point sequences 206 is not yet supported (might cause slightly larger output) 207 208 @param rPolyPoly 209 The poly-polygon to export 210 211 @param bUseRelativeCoordinates 212 When true, all coordinate values are exported as relative 213 to the current position. This tends to save some space, 214 since fewer digits needs to be written. 215 216 @param bDetectQuadraticBeziers 217 When true, the export tries to detect cubic bezier 218 segments in the input polygon, which can be represented by 219 quadratic bezier segments. Note that the generated string 220 causes versions prior to OOo2.0 to crash. 221 222 @param bHandleRelativeNextPointCompatible 223 If set to true, the old error that after a relative 'z' command 224 the current point was not reset to the first point of the current 225 polygon is kept; this is needed to read odf files. 226 If false, pure svg is used; this is needed for svg import. 227 228 @param bOOXMLMotionPath 229 If set to true, export string format that is acceptable for 230 for animation motion path for PowerPoint: always space delimited, 231 never neglect command char, always end with E, and do not export 232 H or V. 233 234 @return the generated SVG-D statement (the XML d attribute 235 value alone, without any "<path ...>" or "d="...") 236 */ 237 BASEGFX_DLLPUBLIC OUString exportToSvgD( 238 const B2DPolyPolygon& rPolyPoly, 239 bool bUseRelativeCoordinates, 240 bool bDetectQuadraticBeziers, 241 bool bHandleRelativeNextPointCompatible, 242 bool bOOXMLMotionPath = false); 243 244 // #i76891# Try to remove existing curve segments if they are simply edges 245 BASEGFX_DLLPUBLIC B2DPolyPolygon simplifyCurveSegments(const B2DPolyPolygon& rCandidate); 246 247 /** Creates polypolygon for seven-segment display number 248 249 This function takes an integer number between 0 and 9 and 250 convert it into the well-known seven-segment display 251 number (like most digital clocks show their numbers). The 252 digit will exactly fit the unit rectangle. The polypolygon 253 will be a line polygon, i.e. if you need the segment parts 254 to have width, use createAreaGeometry() on the result. 255 256 @param cNumber 257 Number from '0' to '9' as ASCII char, or '-', 'E' and '.' 258 to convert to 7 segment code 259 260 @param bLitSegments 261 When true, return a polygon containing the segments that 262 are 'lit' for the given number. Return un-lit segments 263 otherwise. 264 */ 265 B2DPolyPolygon createSevenSegmentPolyPolygon(char cNumber, bool bLitSegments); 266 267 /** snap some polygon coordinates to discrete coordinates 268 269 This method allows to snap some polygon points to discrete (integer) values 270 which equals e.g. a snap to discrete coordinates. It will snap points of 271 horizontal and vertical edges 272 273 @param rCandidate 274 The source polygon 275 276 @return 277 The modified version of the source polygon 278 */ 279 BASEGFX_DLLPUBLIC B2DPolyPolygon snapPointsOfHorizontalOrVerticalEdges(const B2DPolyPolygon& rCandidate); 280 281 /// converters for css::drawing::PointSequence 282 BASEGFX_DLLPUBLIC B2DPolyPolygon UnoPointSequenceSequenceToB2DPolyPolygon( 283 const css::drawing::PointSequenceSequence& rPointSequenceSequenceSource); 284 BASEGFX_DLLPUBLIC void B2DPolyPolygonToUnoPointSequenceSequence( 285 const B2DPolyPolygon& rPolyPolygon, 286 css::drawing::PointSequenceSequence& rPointSequenceSequenceRetval); 287 288 /// converters for css::drawing::PolyPolygonBezierCoords (curved polygons) 289 BASEGFX_DLLPUBLIC B2DPolyPolygon UnoPolyPolygonBezierCoordsToB2DPolyPolygon( 290 const css::drawing::PolyPolygonBezierCoords& rPolyPolygonBezierCoordsSource); 291 BASEGFX_DLLPUBLIC void B2DPolyPolygonToUnoPolyPolygonBezierCoords( 292 const B2DPolyPolygon& rPolyPolygon, 293 css::drawing::PolyPolygonBezierCoords& rPolyPolygonBezierCoordsRetval); 294 295 } // end of namespace basegfx::utils 296 297 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 298