You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

184 lines
5.6 KiB

  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. #ifndef ORIGIN_TRANSFORMS_H_
  25. #define ORIGIN_TRANSFORMS_H_
  26. /**
  27. * A class to perform either relative or absolute display origin
  28. * transforms for a single axis of a point.
  29. *
  30. * The coordinate argument is transformed between an offset from
  31. * the internal origin and an offset from the user-specified origin
  32. * and coordinate direction.
  33. *
  34. * The functions are templated to allow use with any size scalar
  35. * parameter: an int, a long long int, or a double.
  36. */
  37. class ORIGIN_TRANSFORMS
  38. {
  39. public:
  40. /**
  41. * The supported Display Origin Transform types
  42. *
  43. * Absolute coordinates require both translation and direction
  44. * inversion. Relative coordinates require only direction inversion.
  45. */
  46. enum COORD_TYPES_T {
  47. NOT_A_COORD, //< A non-coordinate value, never transformed
  48. ABS_X_COORD, //< An absolute X coordinate
  49. ABS_Y_COORD, //< An absolute Y coordinate
  50. REL_X_COORD, //< A relative X coordinate
  51. REL_Y_COORD, //< A relative Y coordinate
  52. };
  53. ORIGIN_TRANSFORMS();
  54. virtual ~ORIGIN_TRANSFORMS();
  55. virtual int ToDisplay( int aValue,
  56. COORD_TYPES_T aCoordType ) const;
  57. virtual long long int ToDisplay( long long int aValue,
  58. COORD_TYPES_T aCoordType ) const;
  59. virtual double ToDisplay( double aValue,
  60. COORD_TYPES_T aCoordType ) const;
  61. virtual int FromDisplay( int aValue,
  62. COORD_TYPES_T aCoordType ) const;
  63. virtual long long int FromDisplay( long long int aValue,
  64. COORD_TYPES_T aCoordType ) const;
  65. virtual double FromDisplay( double aValue,
  66. COORD_TYPES_T aCoordType ) const;
  67. template<class T>
  68. T ToDisplayAbs( const T& aValue ) const
  69. {
  70. T displayValue;
  71. displayValue.x = ToDisplay( aValue.x, ABS_X_COORD );
  72. displayValue.y = ToDisplay( aValue.y, ABS_Y_COORD );
  73. return displayValue;
  74. }
  75. template<class T>
  76. T ToDisplayRel( const T& aValue ) const
  77. {
  78. T displayValue;
  79. displayValue.x = ToDisplay( aValue.x, REL_X_COORD );
  80. displayValue.y = ToDisplay( aValue.y, REL_Y_COORD );
  81. return displayValue;
  82. }
  83. template<class T>
  84. T FromDisplayAbs( const T& aValue ) const
  85. {
  86. T displayValue;
  87. displayValue.x = FromDisplay( aValue.x, ABS_X_COORD );
  88. displayValue.y = FromDisplay( aValue.y, ABS_Y_COORD );
  89. return displayValue;
  90. }
  91. template<class T>
  92. T FromDisplayRel( const T& aValue ) const
  93. {
  94. T displayValue;
  95. displayValue.x = FromDisplay( aValue.x, REL_X_COORD );
  96. displayValue.y = FromDisplay( aValue.y, REL_Y_COORD );
  97. return displayValue;
  98. }
  99. protected:
  100. template<class T> inline static
  101. T ToDisplayRel( T aInternalValue,
  102. bool aInvertAxis )
  103. {
  104. T displayValue = aInternalValue;
  105. // Invert the direction if needed
  106. if( aInvertAxis && (displayValue != static_cast<T>(0)) )
  107. displayValue = -displayValue;
  108. return displayValue;
  109. }
  110. template<class T> inline static
  111. T FromDisplayRel( T aDisplayValue,
  112. bool aInvertAxis )
  113. {
  114. T internalValue = aDisplayValue;
  115. // Invert the direction if needed
  116. if( aInvertAxis && (internalValue != static_cast<T>(0)) )
  117. internalValue = -internalValue;
  118. return internalValue;
  119. }
  120. template<class T> inline static
  121. T ToDisplayAbs( T aInternalValue,
  122. int aUserOrigin,
  123. bool aInvertAxis )
  124. {
  125. T displayValue = aInternalValue;
  126. // Make the value relative to the internal origin
  127. displayValue -= aUserOrigin;
  128. // Invert the direction if needed
  129. if( aInvertAxis && (displayValue != static_cast<T>(0)) )
  130. displayValue = -displayValue;
  131. return displayValue;
  132. }
  133. template<class T> inline static
  134. T FromDisplayAbs( T aDisplayValue,
  135. int aUserOrigin,
  136. bool aInvertAxis )
  137. {
  138. T internalValue = aDisplayValue;
  139. // Invert the direction if needed
  140. if( aInvertAxis && (internalValue != static_cast<T>(0)) )
  141. internalValue = -internalValue;
  142. // Make the value relative to the internal origin
  143. internalValue += aUserOrigin;
  144. return internalValue;
  145. }
  146. };
  147. #endif // ORIGIN_TRANSFORMS_H