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