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