tdf#148470 if macOS glyph fallback provided a partial result flag what failed
[LibreOffice.git] / include / svx / svdtrans.hxx
blob67741e77728be2345575888ed743e602237329b4
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #pragma once
22 #include <rtl/ustring.hxx>
23 #include <svx/svxdllapi.h>
24 #include <tools/degree.hxx>
25 #include <tools/fldunit.hxx>
26 #include <tools/fract.hxx>
27 #include <tools/gen.hxx>
28 #include <tools/helpers.hxx>
29 #include <tools/mapunit.hxx>
30 #include <tools/poly.hxx>
32 // That maximum shear angle
33 constexpr Degree100 SDRMAXSHEAR(8900);
35 class XPolygon;
36 class XPolyPolygon;
38 inline void MovePoly(tools::Polygon& rPoly, const Size& S) { rPoly.Move(S.Width(),S.Height()); }
39 void MoveXPoly(XPolygon& rPoly, const Size& S);
41 SVXCORE_DLLPUBLIC void ResizeRect(tools::Rectangle& rRect, const Point& rRef, const Fraction& xFact, const Fraction& yFact);
42 inline void ResizePoint(Point& rPnt, const Point& rRef, const Fraction& xFract, const Fraction& yFract);
43 void ResizePoly(tools::Polygon& rPoly, const Point& rRef, const Fraction& xFact, const Fraction& yFact);
44 void ResizeXPoly(XPolygon& rPoly, const Point& rRef, const Fraction& xFact, const Fraction& yFact);
46 inline void RotatePoint(Point& rPnt, const Point& rRef, double sn, double cs);
47 SVXCORE_DLLPUBLIC void RotatePoly(tools::Polygon& rPoly, const Point& rRef, double sn, double cs);
48 void RotateXPoly(XPolygon& rPoly, const Point& rRef, double sn, double cs);
49 void RotateXPoly(XPolyPolygon& rPoly, const Point& rRef, double sn, double cs);
51 void MirrorPoint(Point& rPnt, const Point& rRef1, const Point& rRef2);
52 void MirrorXPoly(XPolygon& rPoly, const Point& rRef1, const Point& rRef2);
54 inline void ShearPoint(Point& rPnt, const Point& rRef, double tn, bool bVShear = false);
55 SVXCORE_DLLPUBLIC void ShearPoly(tools::Polygon& rPoly, const Point& rRef, double tn);
56 void ShearXPoly(XPolygon& rPoly, const Point& rRef, double tn, bool bVShear = false);
58 /**
59 * rPnt.X/rPnt.Y is set to rCenter.X or rCenter.Y!
60 * We then only need to rotate rPnt by rCenter.
62 * @return the returned angle is in rad
64 inline double GetCrookAngle(Point& rPnt, const Point& rCenter, const Point& rRad, bool bVertical);
66 /**
67 * The following methods accept a point of an XPolygon, whereas the neighbouring
68 * control points of the actual point are passed in pC1/pC2.
69 * Via rSin/rCos, sin(nAngle) and cos(nAngle) are returned.
71 * @return the returned angle is in rad
73 double CrookRotateXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCenter,
74 const Point& rRad, double& rSin, double& rCos, bool bVert);
75 double CrookSlantXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCenter,
76 const Point& rRad, double& rSin, double& rCos, bool bVert);
77 double CrookStretchXPoint(Point& rPnt, Point* pC1, Point* pC2, const Point& rCenter,
78 const Point& rRad, double& rSin, double& rCos, bool bVert,
79 const tools::Rectangle& rRefRect);
81 void CrookRotatePoly(XPolygon& rPoly, const Point& rCenter, const Point& rRad, bool bVert);
82 void CrookSlantPoly(XPolygon& rPoly, const Point& rCenter, const Point& rRad, bool bVert);
83 void CrookStretchPoly(XPolygon& rPoly, const Point& rCenter, const Point& rRad, bool bVert, const tools::Rectangle& rRefRect);
85 void CrookRotatePoly(XPolyPolygon& rPoly, const Point& rCenter, const Point& rRad, bool bVert);
86 void CrookSlantPoly(XPolyPolygon& rPoly, const Point& rCenter, const Point& rRad, bool bVert);
87 void CrookStretchPoly(XPolyPolygon& rPoly, const Point& rCenter, const Point& rRad, bool bVert, const tools::Rectangle& rRefRect);
89 /**************************************************************************************************/
90 /* Inline */
91 /**************************************************************************************************/
93 inline void ResizePoint(Point& rPnt, const Point& rRef, const Fraction& xFract, const Fraction& yFract)
95 double nxFract = xFract.IsValid() ? static_cast<double>(xFract) : 1.0;
96 double nyFract = yFract.IsValid() ? static_cast<double>(yFract) : 1.0;
97 rPnt.setX(rRef.X() + FRound( (rPnt.X() - rRef.X()) * nxFract ));
98 rPnt.setY(rRef.Y() + FRound( (rPnt.Y() - rRef.Y()) * nyFract ));
101 inline void RotatePoint(Point& rPnt, const Point& rRef, double sn, double cs)
103 tools::Long dx=rPnt.X()-rRef.X();
104 tools::Long dy=rPnt.Y()-rRef.Y();
105 rPnt.setX(FRound(rRef.X()+dx*cs+dy*sn));
106 rPnt.setY(FRound(rRef.Y()+dy*cs-dx*sn));
109 inline void ShearPoint(Point& rPnt, const Point& rRef, double tn, bool bVShear)
111 if (!bVShear) { // Horizontal
112 if (rPnt.Y()!=rRef.Y()) { // else not needed
113 rPnt.AdjustX(-FRound((rPnt.Y()-rRef.Y())*tn));
115 } else { // or else vertical
116 if (rPnt.X()!=rRef.X()) { // else not needed
117 rPnt.AdjustY(-FRound((rPnt.X()-rRef.X())*tn));
122 inline double GetCrookAngle(Point& rPnt, const Point& rCenter, const Point& rRad, bool bVertical)
124 double nAngle;
125 if (bVertical) {
126 tools::Long dy=rPnt.Y()-rCenter.Y();
127 nAngle=static_cast<double>(dy)/static_cast<double>(rRad.Y());
128 rPnt.setY(rCenter.Y());
129 } else {
130 tools::Long dx=rCenter.X()-rPnt.X();
131 nAngle=static_cast<double>(dx)/static_cast<double>(rRad.X());
132 rPnt.setX(rCenter.X());
134 return nAngle;
137 /**************************************************************************************************/
138 /**************************************************************************************************/
141 * The Y axis points down!
142 * The function negates the Y axis, when calculating the angle, such
143 * that GetAngle(Point(0,-1))=90 deg.
144 * GetAngle(Point(0,0)) returns 0.
146 * @return the returned value is in the range of -180.00..179.99 deg
147 * and is in 1/100 deg units
149 SVXCORE_DLLPUBLIC Degree100 GetAngle(const Point& rPnt);
151 Degree100 NormAngle18000(Degree100 a); /// Normalize angle to -180.00..179.99
153 SVXCORE_DLLPUBLIC Degree100 NormAngle36000(Degree100 a); /// Normalize angle to 0.00..359.99
155 sal_uInt16 GetAngleSector(Degree100 nAngle); /// Determine sector within the cartesian coordinate system
158 * Calculates the length of (0,0) via a^2 + b^2 = c^2
159 * In order to avoid overflows, we ignore some decimal places.
161 tools::Long GetLen(const Point& rPnt);
164 * The transformation of a rectangle into a polygon, by
165 * using angle parameters from GeoStat. ------------
166 * The point of reference is always the Point 0, meaning /1 2/
167 * the upper left corner of the initial rectangle. / /
168 * When calculating the polygon, the order is first / /
169 * shear and then the rotation. / /
170 * / / \
171 * / / |
172 * A) Initial rectangle aRect B) After applying Shear /0 3/ Rot|
173 * +------------------+ -------------------- ------------------
174 * |0 1| \0 1\ C) After applying Rotate
175 * | | \ \
176 * | | | \ \
177 * |3 2| | \3 2\
178 * +------------------+ | --------------------
179 * |Shr
181 * When converting the polygon back into a rect, the order is necessarily the
182 * other way around:
183 * - Calculating the rotation angle: angle of the line 0-1 in figure C) to the horizontal
184 * - Turning the sheared rect back (we get figure B)
185 * - Determining the width of the rect = length of the line 0-1 in figure B)
186 * - Determining the height of the rect = vertical distance between the points 0 and 3
187 * of figure B)
188 * - Determining the shear angle from the line 0-3 to the perpendicular line.
190 * We need to keep in mind that the polygon can be mirrored when it was
191 * transformed in the meantime (e.g. mirror or resize with negative factor).
192 * In that case, we first need to normalize, by swapping points (0 with 3 and 1
193 * with 2), so that it has the right orientation.
195 * Note: a positive shear angle means a shear with a positive visible curvature
196 * on the screen. Mathematically, that would be a negative curvature, as the
197 * Y axis runs from top to bottom on the screen.
198 * Rotation angle: positive means a visible left rotation.
201 class GeoStat { // Geometric state for a rect
202 public:
203 Degree100 nRotationAngle;
204 Degree100 nShearAngle;
205 double mfTanShearAngle; // tan(nShearAngle)
206 double mfSinRotationAngle; // sin(nRotationAngle)
207 double mfCosRotationAngle; // cos(nRotationAngle)
209 GeoStat(): nRotationAngle(0),nShearAngle(0),mfTanShearAngle(0.0),mfSinRotationAngle(0.0),mfCosRotationAngle(1.0) {}
210 void RecalcSinCos();
211 void RecalcTan();
214 tools::Polygon Rect2Poly(const tools::Rectangle& rRect, const GeoStat& rGeo);
215 void Poly2Rect(const tools::Polygon& rPol, tools::Rectangle& rRect, GeoStat& rGeo);
217 void OrthoDistance8(const Point& rPt0, Point& rPt, bool bBigOrtho);
218 void OrthoDistance4(const Point& rPt0, Point& rPt, bool bBigOrtho);
220 // Multiplication and subsequent division
221 // Calculation and intermediate values are in BigInt
222 SVXCORE_DLLPUBLIC tools::Long BigMulDiv(tools::Long nVal, tools::Long nMul, tools::Long nDiv);
224 class FrPair {
225 Fraction aX;
226 Fraction aY;
227 public:
228 FrPair(const Fraction& rBoth) : aX(rBoth),aY(rBoth) {}
229 FrPair(const Fraction& rX, const Fraction& rY) : aX(rX),aY(rY) {}
230 FrPair(tools::Long nMul, tools::Long nDiv) : aX(nMul,nDiv),aY(nMul,nDiv) {}
231 FrPair(tools::Long xMul, tools::Long xDiv, tools::Long yMul, tools::Long yDiv): aX(xMul,xDiv),aY(yMul,yDiv) {}
232 const Fraction& X() const { return aX; }
233 const Fraction& Y() const { return aY; }
234 Fraction& X() { return aX; }
235 Fraction& Y() { return aY; }
238 // To convert units of measurement
239 SVXCORE_DLLPUBLIC FrPair GetMapFactor(MapUnit eS, MapUnit eD);
240 FrPair GetMapFactor(FieldUnit eS, FieldUnit eD);
242 inline bool IsMetric(MapUnit eU) {
243 return (eU==MapUnit::Map100thMM || eU==MapUnit::Map10thMM || eU==MapUnit::MapMM || eU==MapUnit::MapCM);
246 inline bool IsInch(MapUnit eU) {
247 return (eU==MapUnit::Map1000thInch || eU==MapUnit::Map100thInch || eU==MapUnit::Map10thInch || eU==MapUnit::MapInch ||
248 eU==MapUnit::MapPoint || eU==MapUnit::MapTwip);
251 inline bool IsMetric(FieldUnit eU) {
252 return (eU == FieldUnit::MM || eU == FieldUnit::CM || eU == FieldUnit::M
253 || eU == FieldUnit::KM || eU == FieldUnit::MM_100TH);
256 inline bool IsInch(FieldUnit eU) {
257 return (eU == FieldUnit::TWIP || eU == FieldUnit::POINT
258 || eU == FieldUnit::PICA || eU == FieldUnit::INCH
259 || eU == FieldUnit::FOOT || eU == FieldUnit::MILE);
262 class SVXCORE_DLLPUBLIC SdrFormatter {
263 tools::Long nMul_;
264 tools::Long nDiv_;
265 short nComma_;
266 bool bDirty;
267 MapUnit eSrcMU;
268 MapUnit eDstMU;
269 private:
270 SVX_DLLPRIVATE void Undirty();
271 public:
272 SdrFormatter(MapUnit eSrc, MapUnit eDst)
273 : nMul_(0)
274 , nDiv_(0)
275 , nComma_(0)
276 , bDirty(true)
277 , eSrcMU(eSrc)
278 , eDstMU(eDst)
281 OUString GetStr(tools::Long nVal) const;
282 static OUString GetUnitStr(MapUnit eUnit);
283 static OUString GetUnitStr(FieldUnit eUnit);
286 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */