File indexing completed on 2024-05-19 04:25:11
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 #include "kritaglobal_export.h" 0015 0016 #include <QString> 0017 #include <QDebug> 0018 #include <QMetaType> 0019 0020 #include <math.h> // for floor 0021 #include <boost/operators.hpp> 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 * Krita 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 : public boost::equality_comparable<KoUnit> 0071 { 0072 public: 0073 /** Length units supported by Krita. */ 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 m_type == other.m_type && 0114 (m_type != Pixel || 0115 qFuzzyCompare(m_pixelConversion, other.m_pixelConversion)); 0116 } 0117 0118 KoUnit::Type type() const { 0119 return m_type; 0120 } 0121 0122 void setFactor(qreal factor) { 0123 m_pixelConversion = factor; 0124 } 0125 0126 0127 /** 0128 * convert the given value directly from one unit to another 0129 */ 0130 static qreal convertFromUnitToUnit(const qreal value, const KoUnit &fromUnit, const KoUnit &toUnit, qreal factor = 1.0); 0131 0132 /** 0133 * Convert the value @p ptValue to the unit and round it. 0134 * This method is meant to be used to display a value in a dialog. 0135 * \return the converted and rounded value 0136 */ 0137 0138 qreal toUserValueRounded(const qreal value) const; 0139 /** 0140 * Convert the value @p ptValue to the unit (without rounding) 0141 * This method is meant to be used in complex calculations. 0142 * \return the converted value 0143 */ 0144 qreal toUserValuePrecise(const qreal ptValue) const; 0145 0146 /** 0147 * Convert the value @p ptValue with or with rounding as indicated by @p rounding. 0148 * This method is a proxy to toUserValuePrecise and toUserValueRounded. 0149 * \return the value @p ptValue converted to unit 0150 */ 0151 qreal toUserValue(qreal ptValue, bool rounding = true) const; 0152 0153 0154 0155 /// This method is the one to use to display a value in a dialog 0156 /// @return the value @p ptValue converted the unit and rounded, ready to be displayed 0157 QString toUserStringValue(qreal ptValue) const; 0158 0159 /// This method is the one to use to read a value from a dialog 0160 /// @return the value converted to points for internal use 0161 qreal fromUserValue(qreal value) const; 0162 0163 /// This method is the one to use to read a value from a dialog 0164 /// @param value value entered by the user 0165 /// @param ok if set, the pointed bool is set to true if the value could be 0166 /// converted to a qreal, and to false otherwise. 0167 /// @return the value converted to points for internal use 0168 qreal fromUserValue(const QString &value, bool *ok = 0) const; 0169 0170 /// Get the description string of the given unit 0171 static QString unitDescription(KoUnit::Type type); 0172 0173 /// Get the symbol string of the unit 0174 QString symbol() const; 0175 0176 /// Returns the list of unit types for the UI, controlled with the given @p listOptions. 0177 static QStringList listOfUnitNameForUi(ListOptions listOptions = ListAll); 0178 0179 /// Get the index of this unit in the list of unit types for the UI, 0180 /// if it is controlled with the given @p listOptions. 0181 int indexInListForUi(ListOptions listOptions = ListAll) const; 0182 0183 /// parse common Krita and Odf values, like "10cm", "5mm" to pt 0184 static qreal parseValue(const QString &value, qreal defaultVal = 0.0); 0185 0186 /// parse an angle to its value in degrees 0187 static qreal parseAngle(const QString &value, qreal defaultVal = 0.0); 0188 0189 QString toString() const { 0190 return symbol(); 0191 } 0192 0193 /** 0194 * Get an approximate scale of a unit vector that was converted by 0195 * the transformation. 0196 * 0197 * Please note that exact values are guaranteed only for 0198 * combinations of Translate, Rotation and Uniform Scale 0199 * matrices. For combinations having shears and perspective the 0200 * value will be average for the point near CS origin. 0201 */ 0202 static qreal approxTransformScale(const QTransform &t); 0203 0204 /** 0205 * Adjust the unit by pixel transformation applied to the 0206 * describing object. It multiplies the pixel coefficient by the 0207 * average scale of the matrix. 0208 */ 0209 void adjustByPixelTransform(const QTransform &t); 0210 0211 private: 0212 Type m_type; 0213 qreal m_pixelConversion; 0214 }; 0215 0216 #ifndef QT_NO_DEBUG_STREAM 0217 KRITAGLOBAL_EXPORT QDebug operator<<(QDebug, const KoUnit &); 0218 #endif 0219 0220 Q_DECLARE_METATYPE(KoUnit) 0221 Q_DECLARE_OPERATORS_FOR_FLAGS(KoUnit::ListOptions) 0222 0223 #endif