TransformPrimitive.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. /*
  2. * This source file is part of libRocket, the HTML/CSS Interface Middleware
  3. *
  4. * For the latest information, see http://www.librocket.com
  5. *
  6. * Copyright (c) 2014 Markus Schöngart
  7. *
  8. * Permission is hereby granted, free of charge, to any person obtaining a copy
  9. * of this software and associated documentation files (the "Software"), to deal
  10. * in the Software without restriction, including without limitation the rights
  11. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  12. * copies of the Software, and to permit persons to whom the Software is
  13. * furnished to do so, subject to the following conditions:
  14. *
  15. * The above copyright notice and this permission notice shall be included in
  16. * all copies or substantial portions of the Software.
  17. *
  18. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  21. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  22. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  23. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  24. * THE SOFTWARE.
  25. *
  26. */
  27. #ifndef ROCKETCORETRANSFORMPRIMITIVE_H
  28. #define ROCKETCORETRANSFORMPRIMITIVE_H
  29. #include "Header.h"
  30. #include "Types.h"
  31. #include "Property.h"
  32. #include <variant>
  33. #include <array>
  34. namespace Rocket {
  35. namespace Core {
  36. namespace Transforms {
  37. struct NumericValue
  38. {
  39. /// Non-initializing constructor.
  40. NumericValue() noexcept;
  41. /// Construct from a float and a Unit.
  42. NumericValue(float number, Property::Unit unit) noexcept;
  43. /// Resolve a numeric property value for an element.
  44. float Resolve(Element& e, float base) const noexcept;
  45. /// Resolve a numeric property value with the element's width as relative base value.
  46. float ResolveWidth(Element& e) const noexcept;
  47. /// Resolve a numeric property value with the element's height as relative base value.
  48. float ResolveHeight(Element& e) const noexcept;
  49. /// Resolve a numeric property value with the element's depth as relative base value.
  50. float ResolveDepth(Element& e) const noexcept;
  51. /// Returns the numeric value converted to base_unit, or 'number' if no relationship defined.
  52. /// Defined for: {Number, Deg, %} -> Rad
  53. float ResolveAbsoluteUnit(Property::Unit base_unit) const noexcept;
  54. float number;
  55. Property::Unit unit;
  56. };
  57. template< size_t N >
  58. struct ResolvedPrimitive
  59. {
  60. ResolvedPrimitive(const float* values) noexcept
  61. {
  62. for (size_t i = 0; i < N; ++i)
  63. this->values[i] = values[i];
  64. }
  65. ResolvedPrimitive(const NumericValue* values) noexcept
  66. {
  67. for (size_t i = 0; i < N; ++i)
  68. this->values[i] = values[i].number;
  69. }
  70. ResolvedPrimitive(const NumericValue* values, std::array<Property::Unit, N> base_units) noexcept
  71. {
  72. for (size_t i = 0; i < N; ++i)
  73. this->values[i] = values[i].ResolveAbsoluteUnit(base_units[i]);
  74. }
  75. float values[N];
  76. };
  77. template< size_t N >
  78. struct UnresolvedPrimitive
  79. {
  80. UnresolvedPrimitive(const NumericValue* values) noexcept
  81. {
  82. memcpy(this->values, values, sizeof(this->values));
  83. }
  84. NumericValue values[N];
  85. };
  86. struct Matrix2D : public ResolvedPrimitive< 6 >
  87. {
  88. Matrix2D(const NumericValue* values) noexcept : ResolvedPrimitive(values) { }
  89. };
  90. struct Matrix3D : public ResolvedPrimitive< 16 >
  91. {
  92. Matrix3D(const Matrix4f& matrix) noexcept : ResolvedPrimitive(matrix.data()) { }
  93. Matrix3D(const NumericValue* values) noexcept : ResolvedPrimitive(values) { }
  94. };
  95. struct TranslateX : public UnresolvedPrimitive< 1 >
  96. {
  97. TranslateX(const NumericValue* values) noexcept : UnresolvedPrimitive(values) { }
  98. };
  99. struct TranslateY : public UnresolvedPrimitive< 1 >
  100. {
  101. TranslateY(const NumericValue* values) noexcept : UnresolvedPrimitive(values) { }
  102. };
  103. struct TranslateZ : public UnresolvedPrimitive< 1 >
  104. {
  105. TranslateZ(const NumericValue* values) noexcept : UnresolvedPrimitive(values) { }
  106. };
  107. struct Translate2D : public UnresolvedPrimitive< 2 >
  108. {
  109. Translate2D(const NumericValue* values) noexcept : UnresolvedPrimitive(values) { }
  110. };
  111. struct Translate3D : public UnresolvedPrimitive< 3 >
  112. {
  113. Translate3D(const NumericValue* values) noexcept : UnresolvedPrimitive(values) { }
  114. };
  115. struct ScaleX : public ResolvedPrimitive< 1 >
  116. {
  117. ScaleX(const NumericValue* values) noexcept : ResolvedPrimitive(values) { }
  118. };
  119. struct ScaleY : public ResolvedPrimitive< 1 >
  120. {
  121. ScaleY(const NumericValue* values) noexcept : ResolvedPrimitive(values) { }
  122. };
  123. struct ScaleZ : public ResolvedPrimitive< 1 >
  124. {
  125. ScaleZ(const NumericValue* values) noexcept : ResolvedPrimitive(values) { }
  126. };
  127. struct Scale2D : public ResolvedPrimitive< 2 >
  128. {
  129. Scale2D(const NumericValue* values) noexcept : ResolvedPrimitive(values) { }
  130. };
  131. struct Scale3D : public ResolvedPrimitive< 3 >
  132. {
  133. Scale3D(const NumericValue* values) noexcept : ResolvedPrimitive(values) { }
  134. };
  135. struct RotateX : public ResolvedPrimitive< 1 >
  136. {
  137. RotateX(const NumericValue* values) noexcept : ResolvedPrimitive(values, { Property::RAD }) { }
  138. };
  139. struct RotateY : public ResolvedPrimitive< 1 >
  140. {
  141. RotateY(const NumericValue* values) noexcept : ResolvedPrimitive(values, { Property::RAD }) {}
  142. };
  143. struct RotateZ : public ResolvedPrimitive< 1 >
  144. {
  145. RotateZ(const NumericValue* values) noexcept : ResolvedPrimitive(values, { Property::RAD }) { }
  146. };
  147. struct Rotate2D : public ResolvedPrimitive< 1 >
  148. {
  149. Rotate2D(const NumericValue* values) noexcept : ResolvedPrimitive(values, { Property::RAD }) { }
  150. };
  151. struct Rotate3D : public ResolvedPrimitive< 4 >
  152. {
  153. Rotate3D(const NumericValue* values) noexcept : ResolvedPrimitive(values, { Property::NUMBER, Property::NUMBER, Property::NUMBER, Property::RAD }) { }
  154. };
  155. struct SkewX : public ResolvedPrimitive< 1 >
  156. {
  157. SkewX(const NumericValue* values) noexcept : ResolvedPrimitive(values, { Property::RAD }) { }
  158. };
  159. struct SkewY : public ResolvedPrimitive< 1 >
  160. {
  161. SkewY(const NumericValue* values) noexcept : ResolvedPrimitive(values, { Property::RAD }) { }
  162. };
  163. struct Skew2D : public ResolvedPrimitive< 2 >
  164. {
  165. Skew2D(const NumericValue* values) noexcept : ResolvedPrimitive(values, { Property::RAD, Property::RAD }) { }
  166. };
  167. struct Perspective : public UnresolvedPrimitive< 1 >
  168. {
  169. Perspective(const NumericValue* values) noexcept : UnresolvedPrimitive(values) { }
  170. };
  171. using PrimitiveVariant = std::variant<
  172. Matrix2D, Matrix3D,
  173. TranslateX, TranslateY, TranslateZ, Translate2D, Translate3D,
  174. ScaleX, ScaleY, ScaleZ, Scale2D, Scale3D,
  175. RotateX, RotateY, RotateZ, Rotate2D, Rotate3D,
  176. SkewX, SkewY, Skew2D,
  177. Perspective>;
  178. /**
  179. The Primitive struct is the base struct of geometric transforms such as rotations, scalings and translations.
  180. Instances of this struct are added to a Rocket::Core::Transform instance
  181. by the Rocket::Core::PropertyParserTransform, which is responsible for
  182. parsing the `transform' property.
  183. @author Markus Schöngart
  184. @see Rocket::Core::Transform
  185. @see Rocket::Core::PropertyParserTransform
  186. */
  187. struct Primitive
  188. {
  189. PrimitiveVariant primitive;
  190. bool ResolveTransform(Matrix4f& m, Element& e) const noexcept;
  191. bool ResolvePerspective(float &p, Element& e) const noexcept;
  192. // Promote units to basic types which can be interpolated, that is, convert 'length -> pixel' for unresolved primitives.
  193. bool ResolveUnits(Element& e) noexcept;
  194. bool InterpolateWith(const Primitive& other, float alpha) noexcept;
  195. void SetIdentity() noexcept;
  196. };
  197. }
  198. }
  199. }
  200. #endif