axis_transform2d.h 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. // Copyright (c) 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef UI_GFX_GEOMETRY_AXIS_TRANSFORM2D_H_
  5. #define UI_GFX_GEOMETRY_AXIS_TRANSFORM2D_H_
  6. #include "base/check_op.h"
  7. #include "ui/gfx/geometry/geometry_export.h"
  8. #include "ui/gfx/geometry/rect_f.h"
  9. #include "ui/gfx/geometry/vector2d_f.h"
  10. namespace gfx {
  11. // This class implements the subset of 2D linear transforms that only
  12. // translation and uniform scaling are allowed.
  13. // Internally this is stored as a vector for pre-scale, and another vector
  14. // for post-translation. The class constructor and member accessor follows
  15. // the same convention, but a scalar scale factor is also accepted.
  16. class GEOMETRY_EXPORT AxisTransform2d {
  17. public:
  18. constexpr AxisTransform2d() = default;
  19. constexpr AxisTransform2d(float scale, const Vector2dF& translation)
  20. : scale_(scale, scale), translation_(translation) {}
  21. constexpr AxisTransform2d(const Vector2dF& scale,
  22. const Vector2dF& translation)
  23. : scale_(scale), translation_(translation) {}
  24. bool operator==(const AxisTransform2d& other) const {
  25. return scale_ == other.scale_ && translation_ == other.translation_;
  26. }
  27. bool operator!=(const AxisTransform2d& other) const {
  28. return !(*this == other);
  29. }
  30. void PreScale(const Vector2dF& scale) { scale_.Scale(scale.x(), scale.y()); }
  31. void PostScale(const Vector2dF& scale) {
  32. scale_.Scale(scale.x(), scale.y());
  33. translation_.Scale(scale.x(), scale.y());
  34. }
  35. void PreTranslate(const Vector2dF& translation) {
  36. translation_ += ScaleVector2d(translation, scale_.x(), scale_.y());
  37. }
  38. void PostTranslate(const Vector2dF& translation) {
  39. translation_ += translation;
  40. }
  41. void PreConcat(const AxisTransform2d& pre) {
  42. PreTranslate(pre.translation_);
  43. PreScale(pre.scale_);
  44. }
  45. void PostConcat(const AxisTransform2d& post) {
  46. PostScale(post.scale_);
  47. PostTranslate(post.translation_);
  48. }
  49. void Invert() {
  50. DCHECK(scale_.x());
  51. DCHECK(scale_.y());
  52. scale_ = Vector2dF(1.f / scale_.x(), 1.f / scale_.y());
  53. translation_.Scale(-scale_.x(), -scale_.y());
  54. }
  55. PointF MapPoint(const PointF& p) const {
  56. return ScalePoint(p, scale_.x(), scale_.y()) + translation_;
  57. }
  58. PointF InverseMapPoint(const PointF& p) const {
  59. return ScalePoint(p - translation_, 1.f / scale_.x(), 1.f / scale_.y());
  60. }
  61. RectF MapRect(const RectF& r) const {
  62. DCHECK_GE(scale_.x(), 0.f);
  63. DCHECK_GE(scale_.y(), 0.f);
  64. return ScaleRect(r, scale_.x(), scale_.y()) + translation_;
  65. }
  66. RectF InverseMapRect(const RectF& r) const {
  67. DCHECK_GT(scale_.x(), 0.f);
  68. DCHECK_GT(scale_.y(), 0.f);
  69. return ScaleRect(r - translation_, 1.f / scale_.x(), 1.f / scale_.y());
  70. }
  71. const Vector2dF& scale() const { return scale_; }
  72. const Vector2dF& translation() const { return translation_; }
  73. std::string ToString() const;
  74. private:
  75. // Scale is applied before translation, i.e.
  76. // this->Transform(p) == scale_ * p + translation_
  77. Vector2dF scale_{1.f, 1.f};
  78. Vector2dF translation_;
  79. };
  80. inline AxisTransform2d PreScaleAxisTransform2d(const AxisTransform2d& t,
  81. float scale) {
  82. AxisTransform2d result(t);
  83. result.PreScale(Vector2dF(scale, scale));
  84. return result;
  85. }
  86. inline AxisTransform2d PostScaleAxisTransform2d(const AxisTransform2d& t,
  87. float scale) {
  88. AxisTransform2d result(t);
  89. result.PostScale(Vector2dF(scale, scale));
  90. return result;
  91. }
  92. inline AxisTransform2d PreTranslateAxisTransform2d(
  93. const AxisTransform2d& t,
  94. const Vector2dF& translation) {
  95. AxisTransform2d result(t);
  96. result.PreTranslate(translation);
  97. return result;
  98. }
  99. inline AxisTransform2d PostTranslateAxisTransform2d(
  100. const AxisTransform2d& t,
  101. const Vector2dF& translation) {
  102. AxisTransform2d result(t);
  103. result.PostTranslate(translation);
  104. return result;
  105. }
  106. inline AxisTransform2d ConcatAxisTransform2d(const AxisTransform2d& post,
  107. const AxisTransform2d& pre) {
  108. AxisTransform2d result(post);
  109. result.PreConcat(pre);
  110. return result;
  111. }
  112. inline AxisTransform2d InvertAxisTransform2d(const AxisTransform2d& t) {
  113. AxisTransform2d result = t;
  114. result.Invert();
  115. return result;
  116. }
  117. // This is declared here for use in gtest-based unit tests but is defined in
  118. // the //ui/gfx:test_support target. Depend on that to use this in your unit
  119. // test. This should not be used in production code - call ToString() instead.
  120. void PrintTo(const AxisTransform2d&, ::std::ostream* os);
  121. } // namespace gfx
  122. #endif // UI_GFX_GEOMETRY_AXIS_TRANSFORM2D_H_