File indexing completed on 2024-05-12 15:57:04
0001 /* This file is part of the KDE project 0002 SPDX-FileCopyrightText: 1998, 1999 Reginald Stadlbauer <reggie@kde.org> 0003 SPDX-FileCopyrightText: 1998, 1999 Torben Weis <weis@kde.org> 0004 SPDX-FileCopyrightText: 2004 Nicolas GOUTTE <goutte@kde.org> 0005 SPDX-FileCopyrightText: 2010 Thomas Zander <zander@kde.org> 0006 SPDX-FileCopyrightText: 2012 Friedrich W. H. Kossebau <kossebau@kde.org> 0007 0008 SPDX-License-Identifier: LGPL-2.0-or-later 0009 */ 0010 0011 #ifndef KOUNIT_H 0012 #define KOUNIT_H 0013 0014 // Calligra 0015 #include "kritaglobal_export.h" 0016 // Qt 0017 #include <QString> 0018 #include <QDebug> 0019 #include <QMetaType> 0020 // std 0021 #include <math.h> // for floor 0022 0023 class QStringList; 0024 0025 // 1 inch ^= 72 pt 0026 // 1 inch ^= 25.399956 mm (-pedantic ;p) 0027 // 1 pt = 1/12 pi 0028 // 1 pt ^= 0.0077880997 cc 0029 // 1 cc = 12 dd 0030 0031 constexpr qreal POINT_TO_MM(qreal px) {return (px)*0.352777167;} 0032 constexpr qreal MM_TO_POINT(qreal mm) {return mm*2.83465058;} 0033 constexpr qreal POINT_TO_CM(qreal px) {return (px)*0.0352777167;} 0034 constexpr qreal CM_TO_POINT(qreal cm) {return (cm)*28.3465058;} 0035 constexpr qreal POINT_TO_DM(qreal px) {return (px)*0.00352777167;} 0036 constexpr qreal DM_TO_POINT(qreal dm) {return (dm)*283.465058;} 0037 constexpr qreal POINT_TO_INCH(qreal px) {return (px)*0.01388888888889;} 0038 constexpr qreal INCH_TO_POINT(qreal inch) {return (inch)*72.0;} 0039 constexpr qreal MM_TO_INCH(qreal mm) {return (mm)*0.039370147;} 0040 constexpr qreal INCH_TO_MM(qreal inch) {return (inch)*25.399956;} 0041 constexpr qreal POINT_TO_PI(qreal px) {return (px)*0.083333333;} 0042 constexpr qreal POINT_TO_CC(qreal px) {return (px)*0.077880997;} 0043 constexpr qreal PI_TO_POINT(qreal pi) {return (pi)*12;} 0044 constexpr qreal CC_TO_POINT(qreal cc) {return (cc)*12.840103;} 0045 0046 0047 static const qreal PT_ROUNDING {1000.0}; 0048 //static const qreal PX_ROUNDING {1000.0}; // pixel value is not to be rounded 0049 0050 static const qreal CM_ROUNDING {10000.0}; 0051 static const qreal DM_ROUNDING {10000.0}; 0052 static const qreal MM_ROUNDING {10000.0}; 0053 0054 static const qreal IN_ROUNDING {100000.0}; 0055 0056 static const qreal PI_ROUNDING {100000.0}; // pico 0057 static const qreal CC_ROUNDING {100000.0}; // cicero 0058 0059 0060 /** 0061 * %Calligra stores everything in pt (using "qreal") internally. 0062 * When displaying a value to the user, the value is converted to the user's unit 0063 * of choice, and rounded to a reasonable precision to avoid 0.999999 0064 * 0065 * For implementing the selection of a unit type in the UI use the *ForUi() methods. 0066 * They ensure the same order of the unit types in all places, with the order not 0067 * bound to the order in the enum (so ABI-compatible extension is possible) and 0068 * with the order and scope of listed types controlled by the @c ListOptions parameter. 0069 */ 0070 class KRITAGLOBAL_EXPORT KoUnit 0071 { 0072 public: 0073 /** Length units supported by Calligra. */ 0074 enum Type { 0075 Millimeter = 0, 0076 Point, ///< Postscript point, 1/72th of an Inco 0077 Inch, 0078 Centimeter, 0079 Decimeter, 0080 Pica, 0081 Cicero, 0082 Pixel, 0083 TypeCount ///< @internal 0084 }; 0085 0086 /// Used to control the scope of the unit types listed in the UI 0087 enum ListOption { 0088 ListAll = 0, 0089 HidePixel = 1, 0090 HideMask = HidePixel 0091 }; 0092 Q_DECLARE_FLAGS(ListOptions, ListOption) 0093 0094 /** Returns a KoUnit instance with the type at the @p index of the UI list with the given @p listOptions. */ 0095 static KoUnit fromListForUi(int index, ListOptions listOptions = ListAll, qreal factor = 1.0); 0096 0097 /// Convert a unit symbol string into a KoUnit 0098 /// @param symbol symbol to convert 0099 /// @param ok if set, it will be true if the unit was known, false if unknown 0100 static KoUnit fromSymbol(const QString &symbol, bool *ok = 0); 0101 0102 /** Construction requires initialization. The factor is for variable factor units like pixel */ 0103 explicit KoUnit(Type unit = Point, qreal factor = 1.0) { 0104 m_type = unit; 0105 m_pixelConversion = factor; 0106 } 0107 0108 KoUnit& operator=(Type unit) { 0109 m_type = unit; m_pixelConversion = 1.0; return *this; 0110 } 0111 0112 bool operator!=(const KoUnit &other) const { 0113 return !operator==(other); 0114 } 0115 0116 bool operator==(const KoUnit &other) const { 0117 return m_type == other.m_type && 0118 (m_type != Pixel || 0119 qFuzzyCompare(m_pixelConversion, other.m_pixelConversion)); 0120 } 0121 0122 KoUnit::Type type() const { 0123 return m_type; 0124 } 0125 0126 void setFactor(qreal factor) { 0127 m_pixelConversion = factor; 0128 } 0129 0130 0131 /** 0132 * convert the given value directly from one unit to another 0133 */ 0134 static qreal convertFromUnitToUnit(const qreal value, const KoUnit &fromUnit, const KoUnit &toUnit, qreal factor = 1.0); 0135 0136 /** 0137 * Convert the value @p ptValue to the unit and round it. 0138 * This method is meant to be used to display a value in a dialog. 0139 * \return the converted and rounded value 0140 */ 0141 0142 qreal toUserValueRounded(const qreal value) const; 0143 /** 0144 * Convert the value @p ptValue to the unit (without rounding) 0145 * This method is meant to be used in complex calculations. 0146 * \return the converted value 0147 */ 0148 qreal toUserValuePrecise(const qreal ptValue) const; 0149 0150 /** 0151 * Convert the value @p ptValue with or with rounding as indicated by @p rounding. 0152 * This method is a proxy to toUserValuePrecise and toUserValueRounded. 0153 * \return the value @p ptValue converted to unit 0154 */ 0155 qreal toUserValue(qreal ptValue, bool rounding = true) const; 0156 0157 0158 0159 /// This method is the one to use to display a value in a dialog 0160 /// @return the value @p ptValue converted the unit and rounded, ready to be displayed 0161 QString toUserStringValue(qreal ptValue) const; 0162 0163 /// This method is the one to use to read a value from a dialog 0164 /// @return the value converted to points for internal use 0165 qreal fromUserValue(qreal value) const; 0166 0167 /// This method is the one to use to read a value from a dialog 0168 /// @param value value entered by the user 0169 /// @param ok if set, the pointed bool is set to true if the value could be 0170 /// converted to a qreal, and to false otherwise. 0171 /// @return the value converted to points for internal use 0172 qreal fromUserValue(const QString &value, bool *ok = 0) const; 0173 0174 /// Get the description string of the given unit 0175 static QString unitDescription(KoUnit::Type type); 0176 0177 /// Get the symbol string of the unit 0178 QString symbol() const; 0179 0180 /// Returns the list of unit types for the UI, controlled with the given @p listOptions. 0181 static QStringList listOfUnitNameForUi(ListOptions listOptions = ListAll); 0182 0183 /// Get the index of this unit in the list of unit types for the UI, 0184 /// if it is controlled with the given @p listOptions. 0185 int indexInListForUi(ListOptions listOptions = ListAll) const; 0186 0187 /// parse common %Calligra and Odf values, like "10cm", "5mm" to pt 0188 static qreal parseValue(const QString &value, qreal defaultVal = 0.0); 0189 0190 /// parse an angle to its value in degrees 0191 static qreal parseAngle(const QString &value, qreal defaultVal = 0.0); 0192 0193 QString toString() const { 0194 return symbol(); 0195 } 0196 0197 /** 0198 * Get an approximate scale of a unit vector that was converted by 0199 * the transformation. 0200 * 0201 * Please note that exact values are guaranteed only for 0202 * combinations of Translate, Rotation and Uniform Scale 0203 * matrices. For combinations having shears and perspective the 0204 * value will be average for the point near CS origin. 0205 */ 0206 static qreal approxTransformScale(const QTransform &t); 0207 0208 /** 0209 * Adjust the unit by pixel transformation applied to the 0210 * describing object. It multiplies the pixel coefficient by the 0211 * average scale of the matrix. 0212 */ 0213 void adjustByPixelTransform(const QTransform &t); 0214 0215 private: 0216 Type m_type; 0217 qreal m_pixelConversion; 0218 }; 0219 0220 #ifndef QT_NO_DEBUG_STREAM 0221 KRITAGLOBAL_EXPORT QDebug operator<<(QDebug, const KoUnit &); 0222 #endif 0223 0224 Q_DECLARE_METATYPE(KoUnit) 0225 Q_DECLARE_OPERATORS_FOR_FLAGS(KoUnit::ListOptions) 0226 0227 #endif