blob: 64e5b83b7388e8edae4fd5f4be6f3ea5d41eb094 [file] [log] [blame]
// Copyright (c) 2012 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_TRANSFORM_H_
#define UI_GFX_TRANSFORM_H_
#include "base/compiler_specific.h"
#include "third_party/skia/include/utils/SkMatrix44.h"
#include "ui/base/ui_export.h"
namespace gfx {
class RectF;
class Point;
class Point3F;
// 4x4 transformation matrix. Transform is cheap and explicitly allows
// copy/assign.
class UI_EXPORT Transform {
public:
Transform();
~Transform();
bool operator==(const Transform& rhs) const;
bool operator!=(const Transform& rhs) const;
// NOTE: The 'Set' functions overwrite the previously set transformation
// parameters. The 'Concat' functions apply a transformation (e.g. rotation,
// scale, translate) on top of the existing transforms, instead of overwriting
// them.
// NOTE: The order of the 'Set' function calls do not matter. However, the
// order of the 'Concat' function calls do matter, especially when combined
// with the 'Set' functions.
// Sets the rotation of the transformation.
void SetRotate(double degree);
// Sets the rotation of the transform (about a vector).
void SetRotateAbout(const Point3F& point, double degree);
// Sets the scaling parameters.
void SetScaleX(double x);
void SetScaleY(double y);
void SetScaleZ(double z);
void SetScale(double x, double y);
void SetScale3d(double x, double y, double z);
// Sets the translation parameters.
void SetTranslateX(double x);
void SetTranslateY(double y);
void SetTranslateZ(double z);
void SetTranslate(double x, double y);
void SetTranslate3d(double x, double y, double z);
// Sets the skew parameters.
void SetSkewX(double angle);
void SetSkewY(double angle);
// Creates a perspective matrix.
// Based on the 'perspective' operation from
// http://www.w3.org/TR/css3-3d-transforms/#transform-functions
void SetPerspectiveDepth(double depth);
// Applies a rotation on the current transformation.
void ConcatRotate(double degree);
// Applies an axis-angle rotation on the current transformation.
void ConcatRotateAbout(const Point3F& point, double degree);
// Applies scaling on current transform.
void ConcatScale(double x, double y);
void ConcatScale3d(double x, double y, double z);
// Applies translation on current transform.
void ConcatTranslate(double x, double y);
void ConcatTranslate3d(double x, double y, double z);
// Applies a perspective on current transform.
void ConcatPerspectiveDepth(double depth);
// Applies a skew on the current transform.
void ConcatSkewX(double angle_x);
void ConcatSkewY(double angle_y);
// Applies the current transformation on a rotation and assigns the result
// to |this|.
void PreconcatRotate(double degree);
// Applies the current transformation on an axis-angle rotation and assigns
// the result to |this|.
void PreconcatRotateAbout(const Point3F& point, double degree);
// Applies the current transformation on a scaling and assigns the result
// to |this|.
void PreconcatScale(double x, double y);
void PreconcatScale3d(double x, double y, double z);
// Applies the current transformation on a translation and assigns the result
// to |this|.
void PreconcatTranslate(double x, double y);
void PreconcatTranslate3d(double x, double y, double z);
// Applies the current transformation on a skew and assigns the result
// to |this|.
void PreconcatSkewX(double angle_x);
void PreconcatSkewY(double angle_y);
// Applies the current transformation on a perspective transform and assigns
// the result to |this|.
void PreconcatPerspectiveDepth(double depth);
// Applies a transformation on the current transformation
// (i.e. 'this = this * transform;').
void PreconcatTransform(const Transform& transform);
// Applies a transformation on the current transformation
// (i.e. 'this = transform * this;').
void ConcatTransform(const Transform& transform);
// Returns true if this is the identity matrix.
bool IsIdentity() const;
// Returns true if this transform is non-singular.
bool IsInvertible() const;
// Inverts the transform which is passed in. Returns true if successful.
bool GetInverse(Transform* transform) const WARN_UNUSED_RESULT;
// Transposes this transform in place.
void Transpose();
// Applies the transformation on the point. Returns true if the point is
// transformed successfully.
void TransformPoint(Point3F& point) const;
// Applies the transformation on the point. Returns true if the point is
// transformed successfully. Rounds the result to the nearest point.
void TransformPoint(Point& point) const;
// Applies the reverse transformation on the point. Returns true if the
// transformation can be inverted.
bool TransformPointReverse(Point3F& point) const;
// Applies the reverse transformation on the point. Returns true if the
// transformation can be inverted. Rounds the result to the nearest point.
bool TransformPointReverse(Point& point) const;
// Applies transformation on the rectangle. Returns true if the transformed
// rectangle was axis aligned. If it returns false, rect will be the
// smallest axis aligned bounding box containing the transformed rect.
void TransformRect(RectF* rect) const;
// Applies the reverse transformation on the rectangle. Returns true if
// the transformed rectangle was axis aligned. If it returns false,
// rect will be the smallest axis aligned bounding box containing the
// transformed rect.
bool TransformRectReverse(RectF* rect) const;
// Decomposes |this| and |from|, interpolates the decomposed values, and
// sets |this| to the reconstituted result. Returns false if either matrix
// can't be decomposed. Uses routines described in this spec:
// http://www.w3.org/TR/css3-3d-transforms/.
//
// Note: this call is expensive since we need to decompose the transform. If
// you're going to be calling this rapidly (e.g., in an animation) you should
// decompose once using gfx::DecomposeTransforms and reuse your
// DecomposedTransform.
bool Blend(const Transform& from, double progress);
// Returns the underlying matrix.
const SkMatrix44& matrix() const { return matrix_; }
SkMatrix44& matrix() { return matrix_; }
private:
void TransformPointInternal(const SkMatrix44& xform,
Point& point) const;
void TransformPointInternal(const SkMatrix44& xform,
Point3F& point) const;
SkMatrix44 matrix_;
// copy/assign are allowed.
};
} // namespace gfx
#endif // UI_GFX_TRANSFORM_H_