/*
* Copyright (c) 2020-2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @addtogroup UI_Utils
* @{
*
* @brief Defines basic UI utils.
*
* @since 1.0
* @version 1.0
*/
/**
* @file transform.h
*
* @brief Provides functions to transform components, points, and line segments, including rotation and scaling.
*
* @since 1.0
* @version 1.0
*/
#ifndef GRAPHIC_LITE_TRANSFORM_H
#define GRAPHIC_LITE_TRANSFORM_H
#include "gfx_utils/geometry2d.h"
#include "gfx_utils/graphic_math.h"
namespace OHOS {
/**
* @brief Transforms a rectangle, including rotation and scaling.
* @since 1.0
* @version 1.0
*/
class TransformMap : public HeapBase {
public:
/**
* @brief The default constructor used to create a TransformMap instance.
* @since 1.0
* @version 1.0
*/
TransformMap();
/**
* @brief A constructor used to create a TransformMap instance.
*
* @param rect Indicates the rectangle to transform.
* @since 1.0
* @version 1.0
*/
explicit TransformMap(const Rect& rect);
/**
* @brief A destructor used to delete the TransformMap instance.
* @since 1.0
* @version 1.0
*/
virtual ~TransformMap() {}
/**
* @brief Checks whether the vertex coordinates of a polygon are clockwise.
*
* @return Returns true if the vertex coordinates are clockwise; returns false otherwise.
* @since 1.0
* @version 1.0
*/
bool GetClockWise() const;
/**
* @brief Sets a polygon after rectangle transformation.
* @param polygon Indicates the polygon to set.
* @since 1.0
* @version 1.0
*/
void SetPolygon(const Polygon& polygon)
{
polygon_ = polygon;
}
/**
* @brief Obtains the polygon after rectangle transformation.
* @return Returns the polygon.
* @since 1.0
* @version 1.0
*/
Polygon GetPolygon() const
{
return polygon_;
}
/**
* @brief Obtains the pivot for the rotation or scaling operation.
* @return Returns the pivot.
* @since 1.0
* @version 1.0
*/
const Vector3& GetPivot() const
{
return scalePivot_;
}
void SetTransMapRect(const Rect& rect);
const Rect& GetTransMapRect() const
{
return rect_;
}
void SetInvalid(bool state)
{
isInvalid_ = state;
}
/**
* @brief Checks whether the TransformMap instance is invalid. When the vertices are all 0, the
* TransformMap is invalid.
* @return Returns true if TransformMap is invalid; returns false otherwise.
* @since 1.0
* @version 1.0
*/
bool IsInvalid() const;
/**
* @brief Obtains the minimum rectangle that can contain a polygon. All vertices of the polygon are inside this
* rectangle.
* @return Returns the minimum rectangle that can contain the polygon.
* @since 1.0
* @version 1.0
*/
Rect GetBoxRect() const
{
return polygon_.MakeAABB();
}
/**
* @brief Obtains a three-dimensional homogeneous transformation matrix.
* @return Returns the three-dimensional homogeneous transformation matrix.
* @since 1.0
* @version 1.0
*/
const Matrix4& GetTransformMatrix() const
{
return matrix_;
}
const Matrix4& GetOrigTransformMatrix() const
{
return matrixOrig_;
}
const Matrix4& GetRotateMatrix() const
{
return rotate_;
}
const Matrix4& GetScaleMatrix() const
{
return scale_;
}
const Matrix4& GetTranslateMatrix() const
{
return translate_;
}
const Matrix4& GetShearMatrix() const
{
return shear_;
}
const Matrix4& GetPerspectiveMatrix() const
{
return perspectiveMatrix_;
}
int16_t GetRotateAngle() const
{
return angle_;
}
Point GetOrigPoint(const Point& point, const Rect& relativeRect);
/**
* @brief Rotates the rectangle.
* @param angle Indicates the angle to rotate.
* @param pivot Indicates the rotation pivot.
* @since 1.0
* @version 1.0
*/
void Rotate(int16_t angle, const Vector2& pivot);
void Rotate(int16_t angle, const Vector3& rotatePivotStart, const Vector3& rotatePivotEnd);
/**
* @brief Scales the rectangle.
*
* @param scale Indicates the scaling factors of the x-axis and y-axis.
* @param pivot Indicates the pivot for scaling.
* @since 1.0
* @version 1.0
*/
void Scale(const Vector2& scale, const Vector2& pivot);
void Scale(const Vector3& scale, const Vector3& pivot);
void Translate(const Vector2& trans);
void Translate(const Vector3& trans);
void Translate(const Vector2& trans);
void Translate(const Vector3& trans);
void Shear(const Vector2& shearX, const Vector2& shearY, const Vector2& shearZ);
bool operator==(const TransformMap& other) const;
void SetMatrix(const Matrix4& matrix, bool isInternalMatrix = false);
void SetCameraDistance(int16_t distance);
void SetCameraPosition(const Vector2& position);
Matrix3 invMatrix_;
bool Is3DTransform() const;
private:
void UpdateMap();
void AddOp(uint8_t op);
enum : uint8_t {
ROTATE = 0,
SCALE,
SHEAR,
TRANSLATE,
TRANS_NUM,
};
Rect rect_ = {0, 0, 0, 0}; /* orig rect */
Polygon polygon_ = Polygon(Rect(0, 0, 0, 0)); /* transformed from rect and 'rotate_' 'translate_' 'scale_' */
int16_t angle_ = 0;
int16_t cameraDistance_ = 1000; // 1000 : default distance
bool isInvalid_ = false;
bool isIdentity_ = false;
bool is3d_ = false;
bool isInternalMatrix_ = true;
Vector2 cameraPosition_ = {0, 0};
Vector3 scaleCoeff_ = {1.0f, 1.0f, 1.0f};
Vector3 scalePivot_ = {0, 0, 0};
Vector3 rotatePivotStart_ = {0, 0, 0};
Vector3 rotatePivotEnd_ = {0, 0, 0};
Vector2 shearX_ = {0, 0};
Vector2 shearY_ = {0, 0};
Vector2 shearZ_ = {0, 0};
Matrix4 scale_;
Matrix4 rotate_;
Matrix4 shear_;
Matrix4 translate_;
Matrix4* trans_[TRANS_NUM];
uint8_t opOrder_[TRANS_NUM];
Matrix4 matrix_;
Matrix4 perspectiveMatrix_;
Matrix4 matrixOrig_;
};
/**
* @brief Rotates a point around the pivot by a certain angle.
* @param point Indicates the point to rotate.
* @param angle Indicates the angle to rotate.
* @param pivot Indicates the rotation pivot.
* @param out Indicates the point generated after rotation.
* @since 1.0
* @version 1.0
*/
void Rotate(const Vector2& point, int16_t angle, const Vector2& pivot, Vector2& out);
/**
* @brief Rotates a line around the pivot by a certain angle.
* @param origLine Indicates the line segment to rotate.
* @param angle Indicates the angle to rotate.
* @param pivot Indicates the rotation pivot.
* @param out Indicates the line generated after rotation.
* @since 1.0
* @version 1.0
*/
void Rotate(const Line& origLine, int16_t angle, const Vector2& pivot, Line& out);
/**
* @brief Rotates a rectangle around the pivot by a certain angle.
* @param origRect Indicates the rectangle to rotate.
* @param angle Indicates the angle to rotate.
* @param pivot Indicates the rotation pivot.
* @param out Indicates the polygon generated after the rectangle is rotated.
* @since 1.0
* @version 1.0
*/
void Rotate(const Rect& origRect, int16_t angle, const Vector2& pivot, Polygon& out);
} // namespace OHOS
#endif // GRAPHIC_LITE_TRANSFORM_H