1 /* 2 * This program source code file is part of KiCad, a free EDA CAD application. 3 * 4 * Copyright (C) 2019-2020 Reece R. Pollack <reece@his.com> 5 * Copyright (C) 1992-2019 KiCad Developers, see AUTHORS.txt for contributors. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, you may find one here: 19 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html 20 * or you may search the http://www.gnu.org website for the version 2 license, 21 * or you may write to the Free Software Foundation, Inc., 22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA 23 */ 24 25 #ifndef ORIGIN_TRANSFORMS_H_ 26 #define ORIGIN_TRANSFORMS_H_ 27 28 /** 29 * A class to perform either relative or absolute display origin 30 * transforms for a single axis of a point. 31 * 32 * The coordinate argument is transformed between an offset from 33 * the internal origin and an offset from the user-specified origin 34 * and coordinate direction. 35 * 36 * The functions are templated to allow use with any size scalar 37 * parameter: an int, a long long int, or a double. 38 */ 39 class ORIGIN_TRANSFORMS 40 { 41 public: 42 /** 43 * The supported Display Origin Transform types 44 * 45 * Absolute coordinates require both translation and direction 46 * inversion. Relative coordinates require only direction inversion. 47 */ 48 enum COORD_TYPES_T { 49 NOT_A_COORD, //< A non-coordinate value, never transformed 50 ABS_X_COORD, //< An absolute X coordinate 51 ABS_Y_COORD, //< An absolute Y coordinate 52 REL_X_COORD, //< A relative X coordinate 53 REL_Y_COORD, //< A relative Y coordinate 54 }; 55 56 ORIGIN_TRANSFORMS(); 57 58 virtual ~ORIGIN_TRANSFORMS(); 59 60 virtual int ToDisplay( int aValue, 61 COORD_TYPES_T aCoordType ) const; 62 63 virtual long long int ToDisplay( long long int aValue, 64 COORD_TYPES_T aCoordType ) const; 65 66 virtual double ToDisplay( double aValue, 67 COORD_TYPES_T aCoordType ) const; 68 69 virtual int FromDisplay( int aValue, 70 COORD_TYPES_T aCoordType ) const; 71 72 virtual long long int FromDisplay( long long int aValue, 73 COORD_TYPES_T aCoordType ) const; 74 75 virtual double FromDisplay( double aValue, 76 COORD_TYPES_T aCoordType ) const; 77 78 79 template<class T> ToDisplayAbs(const T & aValue)80 T ToDisplayAbs( const T& aValue ) const 81 { 82 T displayValue; 83 84 displayValue.x = ToDisplay( aValue.x, ABS_X_COORD ); 85 displayValue.y = ToDisplay( aValue.y, ABS_Y_COORD ); 86 return displayValue; 87 } 88 89 template<class T> ToDisplayRel(const T & aValue)90 T ToDisplayRel( const T& aValue ) const 91 { 92 T displayValue; 93 94 displayValue.x = ToDisplay( aValue.x, REL_X_COORD ); 95 displayValue.y = ToDisplay( aValue.y, REL_Y_COORD ); 96 return displayValue; 97 } 98 99 100 template<class T> FromDisplayAbs(const T & aValue)101 T FromDisplayAbs( const T& aValue ) const 102 { 103 T displayValue; 104 105 displayValue.x = FromDisplay( aValue.x, ABS_X_COORD ); 106 displayValue.y = FromDisplay( aValue.y, ABS_Y_COORD ); 107 return displayValue; 108 } 109 110 template<class T> FromDisplayRel(const T & aValue)111 T FromDisplayRel( const T& aValue ) const 112 { 113 T displayValue; 114 115 displayValue.x = FromDisplay( aValue.x, REL_X_COORD ); 116 displayValue.y = FromDisplay( aValue.y, REL_Y_COORD ); 117 return displayValue; 118 } 119 120 121 protected: 122 template<class T> inline static ToDisplayRel(T aInternalValue,bool aInvertAxis)123 T ToDisplayRel( T aInternalValue, 124 bool aInvertAxis ) 125 { 126 T displayValue = aInternalValue; 127 128 // Invert the direction if needed 129 if( aInvertAxis && (displayValue != static_cast<T>(0)) ) 130 displayValue = -displayValue; 131 132 return displayValue; 133 } 134 135 136 template<class T> inline static FromDisplayRel(T aDisplayValue,bool aInvertAxis)137 T FromDisplayRel( T aDisplayValue, 138 bool aInvertAxis ) 139 { 140 T internalValue = aDisplayValue; 141 142 // Invert the direction if needed 143 if( aInvertAxis && (internalValue != static_cast<T>(0)) ) 144 internalValue = -internalValue; 145 146 return internalValue; 147 } 148 149 template<class T> inline static ToDisplayAbs(T aInternalValue,int aUserOrigin,bool aInvertAxis)150 T ToDisplayAbs( T aInternalValue, 151 int aUserOrigin, 152 bool aInvertAxis ) 153 { 154 T displayValue = aInternalValue; 155 156 // Make the value relative to the internal origin 157 displayValue -= aUserOrigin; 158 159 // Invert the direction if needed 160 if( aInvertAxis && (displayValue != static_cast<T>(0)) ) 161 displayValue = -displayValue; 162 163 return displayValue; 164 } 165 166 template<class T> inline static FromDisplayAbs(T aDisplayValue,int aUserOrigin,bool aInvertAxis)167 T FromDisplayAbs( T aDisplayValue, 168 int aUserOrigin, 169 bool aInvertAxis ) 170 { 171 T internalValue = aDisplayValue; 172 173 // Invert the direction if needed 174 if( aInvertAxis && (internalValue != static_cast<T>(0)) ) 175 internalValue = -internalValue; 176 177 // Make the value relative to the internal origin 178 internalValue += aUserOrigin; 179 180 return internalValue; 181 } 182 }; 183 184 #endif // ORIGIN_TRANSFORMS_H 185