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