• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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 "common/rs_obj_abs_geometry.h"
17 
18 #ifndef USE_ROSEN_DRAWING
19 #include "include/utils/SkCamera.h"
20 #ifdef NEW_SKIA
21 #include "include/core/SkM44.h"
22 #else
23 #include "include/core/SkMatrix44.h"
24 #endif
25 #else // USE_ROSEN_DRAWING
26 #include "utils/camera3d.h"
27 #include "utils/matrix44.h"
28 #endif
29 
30 namespace OHOS {
31 namespace Rosen {
32 constexpr unsigned RECT_POINT_NUM = 4;
33 constexpr unsigned LEFT_TOP_POINT = 0;
34 constexpr unsigned RIGHT_TOP_POINT = 1;
35 constexpr unsigned RIGHT_BOTTOM_POINT = 2;
36 constexpr unsigned LEFT_BOTTOM_POINT = 3;
37 constexpr float INCH_TO_PIXEL = 72;
38 constexpr float EPSILON = 1e-4f;
39 constexpr float DEGREE_TO_RADIAN = M_PI / 180;
40 
41 RSObjAbsGeometry::RSObjAbsGeometry() = default;
42 RSObjAbsGeometry::~RSObjAbsGeometry() = default;
43 
44 #ifndef USE_ROSEN_DRAWING
ConcatMatrix(const SkMatrix & matrix)45 void RSObjAbsGeometry::ConcatMatrix(const SkMatrix& matrix)
46 {
47     if (matrix.isIdentity()) {
48         return;
49     }
50     matrix_.preConcat(matrix);
51     if (absMatrix_.has_value()) {
52         absMatrix_->preConcat(matrix);
53     }
54     SetAbsRect();
55 }
56 #else
ConcatMatrix(const Drawing::Matrix & matrix)57 void RSObjAbsGeometry::ConcatMatrix(const Drawing::Matrix& matrix)
58 {
59     matrix_ = matrix_ * matrix;
60     if (absMatrix_.has_value()) {
61         *absMatrix_ = (*absMatrix_) * matrix;
62     }
63     SetAbsRect();
64 }
65 #endif
66 
67 /**
68  * @brief Updates the matrix of the view with respect to its parent view.
69  *
70  * @param parent The parent view of the current view.
71  * @param offset The offset of the current view with respect to its parent.
72  * @param clipRect The optional clipping rectangle of the current view.
73  */
74 #ifndef USE_ROSEN_DRAWING
UpdateMatrix(const std::shared_ptr<RSObjAbsGeometry> & parent,const std::optional<SkPoint> & offset,const std::optional<SkRect> & clipRect)75 void RSObjAbsGeometry::UpdateMatrix(const std::shared_ptr<RSObjAbsGeometry>& parent,
76     const std::optional<SkPoint>& offset, const std::optional<SkRect>& clipRect)
77 #else
78 void RSObjAbsGeometry::UpdateMatrix(const std::shared_ptr<RSObjAbsGeometry>& parent,
79     const std::optional<Drawing::Point>& offset, const std::optional<Drawing::Rect>& clipRect)
80 #endif
81 {
82     // Initialize the absolute matrix with the absolute matrix of the parent view if the parent view exists
83     if (parent == nullptr) {
84         absMatrix_.reset();
85     } else {
86 #ifndef USE_ROSEN_DRAWING
87         absMatrix_ = parent->GetAbsMatrix();
88 #else
89         absMatrix_ = Drawing::Matrix();
90         for (int i = 0; i < Drawing::Matrix::MATRIX_SIZE; i++) {
91             auto& matrix = parent->GetAbsMatrix();
92             absMatrix_->Set(static_cast<Drawing::Matrix::Index>(i), matrix.Get(i));
93         }
94 #endif
95     }
96 #ifndef USE_ROSEN_DRAWING
97     if (absMatrix_.has_value() && offset.has_value() && !offset.value().isZero()) {
98         absMatrix_->preTranslate(offset->x(), offset->y());
99     }
100 #else
101     if (absMatrix_.has_value() && offset.has_value() &&
102         !((offset.value().GetX() == 0) && (offset.value().GetY() == 0))) {
103         absMatrix_->PreTranslate(offset->GetX(), offset->GetY());
104     }
105 #endif
106     // Reset the matrix of the current view
107 #ifndef USE_ROSEN_DRAWING
108     matrix_.reset();
109 #else
110     matrix_ = Drawing::Matrix();
111 #endif
112     // filter invalid width and height
113     if (IsEmpty()) {
114         return;
115     }
116     // If the view has no transformations or only 2D transformations, update the absolute matrix with 2D
117     // transformations
118     if (!trans_ || (ROSEN_EQ(trans_->translateZ_, 0.f) && ROSEN_EQ(trans_->rotationX_, 0.f) &&
119         ROSEN_EQ(trans_->rotationY_, 0.f) && trans_->quaternion_.IsIdentity())) {
120         UpdateAbsMatrix2D();
121     } else {
122         // Otherwise, update the absolute matrix with 3D transformations
123         UpdateAbsMatrix3D();
124     }
125     // If the absolute matrix of the current view exists, update it with the context matrix and the current matrix
126     if (absMatrix_.has_value()) {
127 #ifndef USE_ROSEN_DRAWING
128         if (contextMatrix_.has_value()) {
129             absMatrix_->preConcat(*contextMatrix_);
130         }
131         absMatrix_->preConcat(matrix_);
132 #else
133         if (contextMatrix_.has_value()) {
134             *absMatrix_ = (*absMatrix_) * (*contextMatrix_);
135         }
136         *absMatrix_ = (*absMatrix_) * matrix_;
137 #endif
138     }
139     // if clipRect is valid, update rect with clipRect
140 #ifndef USE_ROSEN_DRAWING
141     if (clipRect.has_value() && !clipRect.value().isEmpty()) {
142 #else
143     if (clipRect.has_value() && !clipRect.value().IsValid()) {
144 #endif
145         auto mappedClipRect = clipRect.value();
146 #ifndef USE_ROSEN_DRAWING
147         if (!matrix_.isIdentity()) {
148             SkMatrix invertMatrix;
149             if (matrix_.invert(&invertMatrix)) {
150                 mappedClipRect = invertMatrix.mapRect(mappedClipRect);
151             }
152             // matrix_ already includes bounds offset, we need to revert it
153             mappedClipRect.offset(GetX(), GetY());
154         }
155 
156 #ifdef NEW_SKIA
157         if (!mappedClipRect.intersect({x_, y_, x_ + width_, y_ + height_})) {
158 #else
159         if (!mappedClipRect.intersect(x_, y_, x_ + width_, y_ + height_)) {
160 #endif
161             // No visible area
162             x_ = y_ = width_ = height_ = 0.0f;
163             return;
164         }
165         x_ = mappedClipRect.left();
166         y_ = mappedClipRect.top();
167         width_ = mappedClipRect.width();
168         height_ = mappedClipRect.height();
169 #else
170         if (matrix_.Get(Drawing::Matrix::Index::SCALE_X) == 1 && matrix_.Get(Drawing::Matrix::Index::SCALE_Y) == 1 &&
171             matrix_.Get(Drawing::Matrix::Index::PERSP_2) == 1) {
172             Drawing::Matrix invertMatrix;
173             if (matrix_.Invert(invertMatrix)) {
174                 invertMatrix.MapRect(mappedClipRect, mappedClipRect);
175             }
176             // matrix_ already includes bounds offset, we need to revert it
177             mappedClipRect.Offset(GetX(), GetY());
178         }
179 
180         if (!mappedClipRect.Intersect({ x_, y_, x_ + width_, y_ + height_ })) {
181             // No visible area
182             x_ = y_ = width_ = height_ = 0.0f;
183             return;
184         }
185         x_ = mappedClipRect.GetLeft();
186         y_ = mappedClipRect.GetTop();
187         width_ = mappedClipRect.GetWidth();
188         height_ = mappedClipRect.GetHeight();
189 #endif
190     }
191     // If the context matrix of the current view exists, update the current matrix with it
192     if (contextMatrix_.has_value()) {
193 #ifndef USE_ROSEN_DRAWING
194         matrix_.preConcat(*contextMatrix_);
195 #else
196         matrix_ = matrix_ * (*contextMatrix_);
197 #endif
198     }
199     // Update the absolute rectangle of the current view
200     SetAbsRect();
201 }
202 
203 /**
204  * @brief Updates the matrix of the view without its parent view.
205  */
206 void RSObjAbsGeometry::UpdateByMatrixFromSelf()
207 {
208     absMatrix_.reset();
209 #ifndef USE_ROSEN_DRAWING
210     matrix_.reset();
211 #else
212     matrix_ = Drawing::Matrix();
213 #endif
214 
215     // If the view has no transformations or only 2D transformations, update the absolute matrix with 2D transformations
216     if (!trans_ || (ROSEN_EQ(trans_->translateZ_, 0.f) && ROSEN_EQ(trans_->rotationX_, 0.f) &&
217         ROSEN_EQ(trans_->rotationY_, 0.f) && trans_->quaternion_.IsIdentity())) {
218         UpdateAbsMatrix2D();
219     } else {
220         // Otherwise, update the absolute matrix with 3D transformations
221         UpdateAbsMatrix3D();
222     }
223 
224     // If the context matrix of the view exists, update the current matrix with it
225     if (contextMatrix_.has_value()) {
226 #ifndef USE_ROSEN_DRAWING
227         matrix_.preConcat(*contextMatrix_);
228 #else
229         matrix_ = matrix_ * (*contextMatrix_);
230 #endif
231     }
232 
233     // Update the absolute rectangle of the view
234     SetAbsRect();
235 }
236 
237 bool RSObjAbsGeometry::IsNeedClientCompose() const
238 {
239     if (!trans_) {
240         return false;
241     }
242     // return false if rotation degree is times of 90
243     return !ROSEN_EQ(std::remainder(trans_->rotation_, 90.f), 0.f, EPSILON);
244 }
245 
246 void RSObjAbsGeometry::UpdateAbsMatrix2D()
247 {
248     if (!trans_) {
249 #ifndef USE_ROSEN_DRAWING
250         matrix_.preTranslate(x_, y_);
251 #else
252         matrix_.PreTranslate(x_, y_);
253 #endif
254     } else {
255         // Translate
256         if ((x_ + trans_->translateX_ != 0) || (y_ + trans_->translateY_ != 0)) {
257 #ifndef USE_ROSEN_DRAWING
258             matrix_.preTranslate(x_ + trans_->translateX_, y_ + trans_->translateY_);
259 #else
260             matrix_.PreTranslate(x_ + trans_->translateX_, y_ + trans_->translateY_);
261 #endif
262         }
263         // rotation
264         if (!ROSEN_EQ(trans_->rotation_, 0.f, EPSILON)) {
265 #ifndef USE_ROSEN_DRAWING
266             matrix_.preRotate(trans_->rotation_, trans_->pivotX_ * width_, trans_->pivotY_ * height_);
267 #else
268             Drawing::Matrix other;
269             other.Rotate(trans_->rotation_, trans_->pivotX_ * width_, trans_->pivotY_ * height_);
270             matrix_.PreConcat(other);
271 #endif
272         }
273         // Scale
274         if (!ROSEN_EQ(trans_->scaleX_, 1.f) || !ROSEN_EQ(trans_->scaleY_, 1.f)) {
275 #ifndef USE_ROSEN_DRAWING
276             matrix_.preScale(trans_->scaleX_, trans_->scaleY_, trans_->pivotX_ * width_, trans_->pivotY_ * height_);
277 #else
278             if (!(1 == trans_->scaleX_ && 1 == trans_->scaleY_)) {
279                 Drawing::Matrix other;
280                 other.Scale(trans_->scaleX_, trans_->scaleY_, trans_->pivotX_ * width_, trans_->pivotY_ * height_);
281                 matrix_.PreConcat(other);
282             }
283 #endif
284         }
285     }
286 }
287 
288 /**
289  * Update the absolute matrix in 3D space
290  */
291 void RSObjAbsGeometry::UpdateAbsMatrix3D()
292 {
293     // If the view has a non-identity quaternion, apply 3D transformations
294     if (!trans_->quaternion_.IsIdentity()) {
295 #ifndef USE_ROSEN_DRAWING
296 #ifdef NEW_SKIA
297         SkM44 matrix3D;
298 #else
299         SkMatrix44 matrix3D;
300 #endif
301         // Translate
302         matrix3D.setTranslate(trans_->pivotX_ * width_ + x_ + trans_->translateX_,
303             trans_->pivotY_ * height_ + y_ + trans_->translateY_, z_ + trans_->translateZ_);
304 #else // USE_ROSEN_DRAWING
305         Drawing::Matrix44 matrix3D;
306         // Translate
307         matrix3D.Translate(trans_->pivotX_ * width_ + x_ + trans_->translateX_,
308             trans_->pivotY_ * height_ + y_ + trans_->translateY_, z_ + trans_->translateZ_);
309 #endif
310         // Rotate
311         float x = trans_->quaternion_[0];
312         float y = trans_->quaternion_[1];
313         float z = trans_->quaternion_[2];
314         float w = trans_->quaternion_[3];
315 #ifndef USE_ROSEN_DRAWING
316 #ifdef NEW_SKIA
317         SkScalar r[16] = {
318             1.f - 2.f * (y * y + z * z), 2.f * (x * y + z * w), 2.f * (x * z - y * w), 0,
319             2.f * (x * y - z * w), 1.f - 2.f * (x * x + z * z), 2.f * (y * z + x * w), 0,
320             2.f * (x * z + y * w), 2.f * (y * z - x * w), 1.f - 2.f * (x * x + y * y), 0,
321             0, 0, 0, 1
322         };
323         SkM44 matrix4 = SkM44::ColMajor(r);
324 #else
325         SkMatrix44 matrix4;
326         matrix4.set3x3(
327             1.f - 2.f * (y * y + z * z), 2.f * (x * y + z * w), 2.f * (x * z - y * w),
328             2.f * (x * y - z * w), 1.f - 2.f * (x * x + z * z), 2.f * (y * z + x * w),
329             2.f * (x * z + y * w), 2.f * (y * z - x * w), 1.f - 2.f * (x * x + y * y));
330 #endif
331 #else // USE_ROSEN_DRAWING
332         Drawing::Matrix44::Buffer buffer = {
333             1.f - 2.f * (y * y + z * z), 2.f * (x * y + z * w), 2.f * (x * z - y * w), 0,   // m00 ~ m30
334             2.f * (x * y - z * w), 1.f - 2.f * (x * x + z * z), 2.f * (y * z + x * w), 0,   // m01 ~ m31
335             2.f * (x * z + y * w), 2.f * (y * z - x * w), 1.f - 2.f * (x * x + y * y), 0,   // m02 ~ m32
336             0, 0, 0, 1 };                                                                   // m03 ~ m33
337         Drawing::Matrix44 matrix4;
338         matrix4.SetMatrix44(buffer);
339 #endif
340         matrix3D = matrix3D * matrix4;
341         // Scale
342         if (!ROSEN_EQ(trans_->scaleX_, 1.f) || !ROSEN_EQ(trans_->scaleY_, 1.f)) {
343 #ifndef USE_ROSEN_DRAWING
344             matrix3D.preScale(trans_->scaleX_, trans_->scaleY_, 1.f);
345 #else
346             Drawing::Matrix44 matrix44;
347             matrix44.Scale(trans_->scaleX_, trans_->scaleY_, 1.f);
348             matrix3D = matrix3D * matrix44;
349 #endif
350         }
351         // Translate
352 #ifndef USE_ROSEN_DRAWING
353         matrix3D.preTranslate(-trans_->pivotX_ * width_, -trans_->pivotY_ * height_, 0);
354 
355         // Concatenate the 3D matrix with the 2D matrix
356 #ifdef NEW_SKIA
357         matrix_.preConcat(matrix3D.asM33());
358 #else
359         matrix_.preConcat(SkMatrix(matrix3D));
360 #endif
361 #else // USE_ROSEN_DRAWING
362         Drawing::Matrix44 drMatrix44;
363         drMatrix44.Translate(-trans_->pivotX_ * width_, -trans_->pivotY_ * height_, 0);
364         matrix3D = matrix3D * drMatrix44;
365         matrix_ = matrix_ * Drawing::Matrix(matrix3D);
366 #endif
367     } else {
368 #ifndef USE_ROSEN_DRAWING
369         SkMatrix matrix3D;
370         Sk3DView camera;
371 
372         // Z Position
373         camera.translate(0, 0, z_ + trans_->translateZ_);
374         // Set camera distance
375         if (trans_->cameraDistance_ == 0) {
376             float zOffSet = sqrt(width_ * width_ + height_ * height_) / 2;
377             camera.setCameraLocation(0, 0, camera.getCameraLocationZ() - zOffSet / INCH_TO_PIXEL);
378         } else {
379             camera.setCameraLocation(0, 0, trans_->cameraDistance_);
380         }
381 
382         // Rotate
383         if (trans_->pivotZ_ != 0.f) {
384             camera.translate(sin(trans_->rotationY_ * DEGREE_TO_RADIAN) * trans_->pivotZ_,
385                 sin(trans_->rotationX_ * DEGREE_TO_RADIAN) * trans_->pivotZ_,
386                 (cos(trans_->rotationX_ * DEGREE_TO_RADIAN) + cos(trans_->rotationY_ * DEGREE_TO_RADIAN)) *
387                     trans_->pivotZ_);
388         }
389         camera.rotateX(-trans_->rotationX_);
390         camera.rotateY(-trans_->rotationY_);
391         camera.rotateZ(-trans_->rotation_);
392         camera.getMatrix(&matrix3D);
393 #else
394         Drawing::Matrix matrix3D;
395         Drawing::Camera3D camera;
396         // Z Position
397         camera.Translate(0, 0, z_ + trans_->translateZ_);
398 
399         // Set camera distance
400         if (trans_->cameraDistance_ == 0) {
401             float zOffSet = sqrt(width_ * width_ + height_ * height_) / 2;
402             camera.SetCameraPos(0, 0, camera.GetCameraPosZ() - zOffSet / INCH_TO_PIXEL);
403         } else {
404             camera.SetCameraPos(0, 0, trans_->cameraDistance_);
405         }
406         // Rotate
407         if (trans_->pivotZ_ != 0.f) {
408             camera.Translate(sin(trans_->rotationY_ * DEGREE_TO_RADIAN) * trans_->pivotZ_,
409                 sin(trans_->rotationX_ * DEGREE_TO_RADIAN) * trans_->pivotZ_,
410                 (cos(trans_->rotationX_ * DEGREE_TO_RADIAN) + cos(trans_->rotationY_ * DEGREE_TO_RADIAN)) *
411                     trans_->pivotZ_);
412         }
413         camera.RotateXDegrees(-trans_->rotationX_);
414         camera.RotateYDegrees(-trans_->rotationY_);
415         camera.RotateZDegrees(-trans_->rotation_);
416         camera.ApplyToMatrix(matrix3D);
417 #endif
418         // Scale
419         if (!ROSEN_EQ(trans_->scaleX_, 1.f) || !ROSEN_EQ(trans_->scaleY_, 1.f)) {
420 #ifndef USE_ROSEN_DRAWING
421             matrix3D.preScale(trans_->scaleX_, trans_->scaleY_);
422 #else
423             matrix3D.PreScale(trans_->scaleX_, trans_->scaleY_);
424 #endif
425         }
426         // Translate
427 #ifndef USE_ROSEN_DRAWING
428         matrix3D.preTranslate(-trans_->pivotX_ * width_, -trans_->pivotY_ * height_);
429 
430         // Concatenate the 3D matrix with the 2D matrix
431         matrix3D.postTranslate(
432             trans_->pivotX_ * width_ + x_ + trans_->translateX_, trans_->pivotY_ * height_ + y_ + trans_->translateY_);
433         matrix_.preConcat(matrix3D);
434 #else
435         matrix3D.PreTranslate(-trans_->pivotX_ * width_, -trans_->pivotY_ * height_);
436 
437         // Concatenate the 3D matrix with the 2D matrix
438         Drawing::Matrix matrix;
439         matrix = Drawing::Matrix();
440         matrix.Translate(
441             trans_->pivotX_ * width_ + x_ + trans_->translateX_, trans_->pivotY_ * height_ + y_ + trans_->translateY_);
442         matrix3D = matrix * matrix3D;
443         matrix_ = matrix_ * matrix3D;
444 #endif
445     }
446 }
447 
448 void RSObjAbsGeometry::SetAbsRect()
449 {
450     absRect_ = MapAbsRect(RectF(0.f, 0.f, width_, height_));
451 }
452 
453 /**
454  * Map the absolute rectangle
455  * @param rect the rectangle to map
456  * @return the mapped absolute rectangle
457  */
458 RectI RSObjAbsGeometry::MapAbsRect(const RectF& rect) const
459 {
460     RectI absRect;
461     auto& matrix = GetAbsMatrix();
462 #ifndef USE_ROSEN_DRAWING
463     // Check if the matrix has skew or negative scaling
464     if (!ROSEN_EQ(matrix.getSkewX(), 0.f) || (matrix.getScaleX() < 0) ||
465         !ROSEN_EQ(matrix.getSkewY(), 0.f) || (matrix.getScaleY() < 0)) {
466         // Map the rectangle's points to the absolute matrix
467         SkPoint p[RECT_POINT_NUM];
468         p[LEFT_TOP_POINT].set(rect.left_, rect.top_);
469         p[RIGHT_TOP_POINT].set(rect.left_ + rect.width_, rect.top_);
470         p[RIGHT_BOTTOM_POINT].set(rect.left_ + rect.width_, rect.top_ + rect.height_);
471         p[LEFT_BOTTOM_POINT].set(rect.left_, rect.top_ + rect.height_);
472         matrix.mapPoints(p, RECT_POINT_NUM);
473 
474         // Get the data range of the mapped points
475         Vector2f xRange = GetDataRange(p[LEFT_TOP_POINT].x(), p[RIGHT_TOP_POINT].x(),
476             p[RIGHT_BOTTOM_POINT].x(), p[LEFT_BOTTOM_POINT].x());
477         Vector2f yRange = GetDataRange(p[LEFT_TOP_POINT].y(), p[RIGHT_TOP_POINT].y(),
478             p[RIGHT_BOTTOM_POINT].y(), p[LEFT_BOTTOM_POINT].y());
479 #else
480     // Check if the matrix has skew or negative scaling
481     if (!ROSEN_EQ(matrix.Get(Drawing::Matrix::SKEW_X), 0.f) || (matrix.Get(Drawing::Matrix::SCALE_X) < 0) ||
482         !ROSEN_EQ(matrix.Get(Drawing::Matrix::SKEW_Y), 0.f) || (matrix.Get(Drawing::Matrix::SCALE_Y) < 0)) {
483         // Map the rectangle's points to the absolute matrix
484         std::vector<Drawing::Point> p(RECT_POINT_NUM);
485         p[LEFT_TOP_POINT] = {rect.left_, rect.top_};
486         p[RIGHT_TOP_POINT] = {rect.left_ + rect.width_, rect.top_};
487         p[RIGHT_BOTTOM_POINT] = {rect.left_ + rect.width_, rect.top_ + rect.height_};
488         p[LEFT_BOTTOM_POINT] = {rect.left_, rect.top_ + rect.height_};
489         matrix.MapPoints(p, p, RECT_POINT_NUM);
490 
491         Vector2f xRange = GetDataRange(p[LEFT_TOP_POINT].GetX(), p[RIGHT_TOP_POINT].GetX(),
492             p[RIGHT_BOTTOM_POINT].GetX(), p[LEFT_BOTTOM_POINT].GetX());
493         Vector2f yRange = GetDataRange(p[LEFT_TOP_POINT].GetY(), p[RIGHT_TOP_POINT].GetY(),
494             p[RIGHT_BOTTOM_POINT].GetY(), p[LEFT_BOTTOM_POINT].GetY());
495 #endif
496 
497         // Set the absolute rectangle's properties
498         absRect.left_ = static_cast<int>(xRange[0]);
499         absRect.top_ = static_cast<int>(yRange[0]);
500         absRect.width_ = static_cast<int>(std::ceil(xRange[1] - absRect.left_));
501         absRect.height_ = static_cast<int>(std::ceil(yRange[1] - absRect.top_));
502     } else {
503         // Calculate the absolute rectangle based on the matrix's translation and scaling
504 #ifndef USE_ROSEN_DRAWING
505         absRect.left_ = static_cast<int>(rect.left_ + matrix.getTranslateX());
506         absRect.top_ = static_cast<int>(rect.top_ + matrix.getTranslateY());
507         float right = rect.left_ + matrix.getTranslateX() + rect.width_ * matrix.getScaleX();
508         float bottom = rect.top_ + matrix.getTranslateY() + rect.height_ * matrix.getScaleY();
509         absRect.width_ = static_cast<int>(std::ceil(right - absRect.left_));
510         absRect.height_ = static_cast<int>(std::ceil(bottom - absRect.top_));
511 #else
512         absRect.left_ = static_cast<int>(rect.left_ + matrix.Get(Drawing::Matrix::TRANS_X));
513         absRect.top_ = static_cast<int>(rect.top_ + matrix.Get(Drawing::Matrix::TRANS_Y));
514         float right = rect.left_ + matrix.Get(Drawing::Matrix::TRANS_X) +
515             rect.width_ * matrix.Get(Drawing::Matrix::SCALE_X);
516         float bottom = rect.top_ + matrix.Get(Drawing::Matrix::TRANS_Y) +
517             rect.height_ * matrix.Get(Drawing::Matrix::SCALE_Y);
518         absRect.width_ = static_cast<int>(std::ceil(right - absRect.left_));
519         absRect.height_ = static_cast<int>(std::ceil(bottom - absRect.top_));
520 #endif
521     }
522     return absRect;
523 }
524 
525 Vector2f RSObjAbsGeometry::GetDataRange(float d0, float d1, float d2, float d3) const
526 {
527     float min = d0;
528     float max = d0;
529     if (d0 > d1) {
530         min = d1;
531     } else {
532         max = d1;
533     }
534     if (d2 > d3) {
535         if (min > d3) {
536             min = d3;
537         }
538         if (max < d2) {
539             max = d2;
540         }
541     } else {
542         if (min > d2) {
543             min = d2;
544         }
545         if (max < d3) {
546             max = d3;
547         }
548     }
549     return Vector2f(min, max);
550 }
551 
552 #ifndef USE_ROSEN_DRAWING
553 void RSObjAbsGeometry::SetContextMatrix(const std::optional<SkMatrix>& matrix)
554 #else
555 void RSObjAbsGeometry::SetContextMatrix(const std::optional<Drawing::Matrix>& matrix)
556 #endif
557 {
558     contextMatrix_ = matrix;
559 }
560 
561 #ifndef USE_ROSEN_DRAWING
562 const SkMatrix& RSObjAbsGeometry::GetMatrix() const
563 #else
564 const Drawing::Matrix& RSObjAbsGeometry::GetMatrix() const
565 #endif
566 {
567     return matrix_;
568 }
569 
570 #ifndef USE_ROSEN_DRAWING
571 const SkMatrix& RSObjAbsGeometry::GetAbsMatrix() const
572 #else
573 const Drawing::Matrix& RSObjAbsGeometry::GetAbsMatrix() const
574 #endif
575 {
576     // if absMatrix_ is empty, return matrix_ instead
577     return absMatrix_ ? *absMatrix_ : matrix_;
578 }
579 } // namespace Rosen
580 } // namespace OHOS
581