// Copyright (c) 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef UI_GFX_GEOMETRY_AXIS_TRANSFORM2D_H_ #define UI_GFX_GEOMETRY_AXIS_TRANSFORM2D_H_ #include "ui/gfx/geometry/rect_f.h" #include "ui/gfx/geometry/vector2d_f.h" #include "ui/gfx/gfx_export.h" namespace gfx { // This class implements the subset of 2D linear transforms that only // translation and uniform scaling are allowed. // Internally this is stored as a scalar pre-scale factor, and a vector // for post-translation. The class constructor and member accessor follows // the same convention. class GFX_EXPORT AxisTransform2d { public: constexpr AxisTransform2d() = default; constexpr AxisTransform2d(float scale, const Vector2dF& translation) : scale_(scale), translation_(translation) {} bool operator==(const AxisTransform2d& other) const { return scale_ == other.scale_ && translation_ == other.translation_; } bool operator!=(const AxisTransform2d& other) const { return !(*this == other); } void PreScale(float scale) { scale_ *= scale; } void PostScale(float scale) { scale_ *= scale; translation_.Scale(scale); } void PreTranslate(const Vector2dF& translation) { translation_ += ScaleVector2d(translation, scale_); } void PostTranslate(const Vector2dF& translation) { translation_ += translation; } void PreConcat(const AxisTransform2d& pre) { PreTranslate(pre.translation_); PreScale(pre.scale_); } void PostConcat(const AxisTransform2d& post) { PostScale(post.scale_); PostTranslate(post.translation_); } void Invert() { DCHECK(scale_); scale_ = 1.f / scale_; translation_.Scale(-scale_); } PointF MapPoint(const PointF& p) const { return ScalePoint(p, scale_) + translation_; } PointF InverseMapPoint(const PointF& p) const { return ScalePoint(p - translation_, 1.f / scale_); } RectF MapRect(const RectF& r) const { DCHECK(scale_ >= 0.f); return ScaleRect(r, scale_) + translation_; } RectF InverseMapRect(const RectF& r) const { DCHECK(scale_ > 0.f); return ScaleRect(r - translation_, 1.f / scale_); } float scale() const { return scale_; } const Vector2dF& translation() const { return translation_; } std::string ToString() const; private: // Scale is applied before translation, i.e. // this->Transform(p) == scale_ * p + translation_ float scale_ = 1.f; Vector2dF translation_; }; static inline AxisTransform2d PreScaleAxisTransform2d(const AxisTransform2d& t, float scale) { AxisTransform2d result(t); result.PreScale(scale); return result; } static inline AxisTransform2d PostScaleAxisTransform2d(const AxisTransform2d& t, float scale) { AxisTransform2d result(t); result.PostScale(scale); return result; } static inline AxisTransform2d PreTranslateAxisTransform2d( const AxisTransform2d& t, const Vector2dF& translation) { AxisTransform2d result(t); result.PreTranslate(translation); return result; } static inline AxisTransform2d PostTranslateAxisTransform2d( const AxisTransform2d& t, const Vector2dF& translation) { AxisTransform2d result(t); result.PostTranslate(translation); return result; } static inline AxisTransform2d ConcatAxisTransform2d( const AxisTransform2d& post, const AxisTransform2d& pre) { AxisTransform2d result(post); result.PreConcat(pre); return result; } static inline AxisTransform2d InvertAxisTransform2d(const AxisTransform2d& t) { AxisTransform2d result = t; result.Invert(); return result; } // This is declared here for use in gtest-based unit tests but is defined in // the //ui/gfx:test_support target. Depend on that to use this in your unit // test. This should not be used in production code - call ToString() instead. void PrintTo(const AxisTransform2d&, ::std::ostream* os); } // namespace gfx #endif // UI_GFX_GEOMETRY_AXIS_TRANSFORM2D_H_