1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "frameworks/core/components_ng/render/adapter/matrix2d.h"
17 #include "include/core/SkMatrix.h"
18 #include "2d_graphics/include/utils/matrix.h"
19 
20 namespace OHOS::Ace::NG {
21 constexpr double OHOS_SEMI_CIRCLE_ANGEL = 180.0;
ConvertToMatrix(const TransformParam & param,SkMatrix & skMatrix)22 void ConvertToMatrix(const TransformParam& param, SkMatrix& skMatrix)
23 {
24     double scaleX = param.scaleX;
25     double skewX = param.skewX;
26     double skewY = param.skewY;
27     double scaleY = param.scaleY;
28     double translateX = param.translateX;
29     double translateY = param.translateY;
30     skMatrix.setAll(scaleX, skewX, translateX, skewY, scaleY, translateY, 0.0f, 0.0f, 1.0f);
31 }
32 
ConvertToTransformParam(TransformParam & param,const SkMatrix & skMatrix)33 void ConvertToTransformParam(TransformParam& param, const SkMatrix& skMatrix)
34 {
35     param.scaleX = skMatrix.getScaleX();
36     param.skewX = skMatrix.getSkewX();
37     param.skewY = skMatrix.getSkewY();
38     param.scaleY = skMatrix.getScaleY();
39     param.translateX = skMatrix.getTranslateX();
40     param.translateY = skMatrix.getTranslateY();
41 }
42 
Invert(TransformParam & param)43 bool Matrix2D::Invert(TransformParam& param)
44 {
45     SkMatrix skMatrix;
46     ConvertToMatrix(param, skMatrix);
47     if (skMatrix.invert(&skMatrix)) {
48         ConvertToTransformParam(param, skMatrix);
49         return true;
50     }
51     return false;
52 }
53 
Identity(TransformParam & param)54 void Matrix2D::Identity(TransformParam& param)
55 {
56     SkMatrix skMatrix;
57     ConvertToMatrix(param, skMatrix);
58     skMatrix.reset();
59     ConvertToTransformParam(param, skMatrix);
60 }
61 
Scale(TransformParam & param,double sx,double sy)62 void Matrix2D::Scale(TransformParam& param, double sx, double sy)
63 {
64     SkMatrix skMatrix;
65     ConvertToMatrix(param, skMatrix);
66     skMatrix = skMatrix.preScale(sx, sy);
67     ConvertToTransformParam(param, skMatrix);
68 }
69 
Translate(TransformParam & param,double tx,double ty)70 void Matrix2D::Translate(TransformParam& param, double tx, double ty)
71 {
72     SkMatrix skMatrix;
73     ConvertToMatrix(param, skMatrix);
74     skMatrix = skMatrix.postTranslate(tx, ty);
75     ConvertToTransformParam(param, skMatrix);
76 }
77 
Rotate(TransformParam & param,double degree,double rx,double ry)78 void Matrix2D::Rotate(TransformParam& param, double degree, double rx, double ry)
79 {
80     SkMatrix skMatrix;
81     ConvertToMatrix(param, skMatrix);
82     // convert from radians to degree.
83     degree = degree * OHOS_SEMI_CIRCLE_ANGEL / M_PI;
84     skMatrix = skMatrix.preRotate(degree, rx, ry);
85     ConvertToTransformParam(param, skMatrix);
86 }
87 
SetMatrixPolyToPoly(const Matrix4 & matrix,const std::vector<OHOS::Ace::NG::PointT<int32_t>> & totalPoint)88 Matrix4 SetMatrixPolyToPoly(
89     const Matrix4& matrix, const std::vector<OHOS::Ace::NG::PointT<int32_t>>& totalPoint)
90 {
91     auto matrix3d = OHOS::Rosen::Drawing::Matrix();
92     /**
93      * When converting from matrix4 to matrix3
94      * [a b c]    [a b 0 c]
95      * [d e f] -> [d e 0 f]
96      * [g h i]    [0 0 1 0]
97      *            [g h 0 i]
98     */
99     matrix3d.SetMatrix(matrix.Get(0, 0), matrix.Get(1, 0), matrix.Get(3, 0), matrix.Get(0, 1), matrix.Get(1, 1),
100         matrix.Get(3, 1), matrix.Get(0, 3), matrix.Get(1, 3), matrix.Get(3, 3));
101     size_t arrayLength = totalPoint.size() / 2;
102     OHOS::Rosen::Drawing::PointF src[arrayLength];
103     OHOS::Rosen::Drawing::PointF dst[arrayLength];
104     for (size_t i = 0; i < arrayLength; i++) {
105         auto point = totalPoint[i];
106         src[i] = OHOS::Rosen::Drawing::Point(point.GetX(), point.GetY());
107     }
108     for (size_t i = 0; i < arrayLength; i++) {
109         auto point = totalPoint[i + arrayLength];
110         dst[i] = OHOS::Rosen::Drawing::Point(point.GetX(), point.GetY());
111     }
112     matrix3d.SetPolyToPoly(src, dst, arrayLength);
113     Matrix4 retMatrix4(matrix3d.Get(0), matrix3d.Get(1), 0, matrix3d.Get(2), matrix3d.Get(3), matrix3d.Get(4), 0,
114         matrix3d.Get(5), 0, 0, 1, 0, matrix3d.Get(6), matrix3d.Get(7), 0, matrix3d.Get(8));
115     return retMatrix4;
116 }
117 } // namespace OHOS::Ace::NG
118 
119