/* * 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