/* * Copyright (c) 2025 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. */ #ifndef MMI_TRANSFORM_H #define MMI_TRANSFORM_H #include "window_info.h" namespace OHOS { namespace MMI { template struct Vector2D { T x; T y; }; template class SimpleTransform { public: enum class Type { Translate, Rotate, }; const Type type; const T a00; const T a01; const T x0; const T a10; const T a11; const T y0; static SimpleTransform Translate(const Vector2D &v); static SimpleTransform RotateDirection(Direction direction); Vector2D Apply(const Vector2D &v) const; Vector2D Reset(const Vector2D &v) const; }; template SimpleTransform SimpleTransform::Translate(const Vector2D &v) { return SimpleTransform{ .type = Type::Translate, .a00 = 1, .a01 = 0, .x0 = v.x, .a10 = 0, .a11 = 1, .y0 = v.y, }; } template SimpleTransform SimpleTransform::RotateDirection(Direction direction) { // direction 0 1 2 3 // cos 1 0 -1 0 // sin 0 1 0 -1 T cosine = 1; T sine = 0; switch (direction) { case DIRECTION90: cosine = 0; sine = 1; break; case DIRECTION180: cosine = -1; sine = 0; break; case DIRECTION270: cosine = 0; sine = -1; break; case DIRECTION0: default: break; } return SimpleTransform{ .type = Type::Rotate, .a00 = cosine, .a01 = -sine, .x0 = 0, .a10 = sine, .a11 = cosine, .y0 = 0, }; } template Vector2D SimpleTransform::Apply(const Vector2D &v) const { return { .x = a00 * v.x + a01 * v.y + x0, .y = a10 * v.x + a11 * v.y + y0, }; } template Vector2D SimpleTransform::Reset(const Vector2D &v) const { // Since only translate and rotation are supported, // we can assert the inverse of transform matrix is in the following form: return { .x = a00 * v.x + a10 * v.y - x0, .y = a01 * v.x + a11 * v.y - y0, }; } template inline Vector2D ApplyTransformSteps(const std::vector> &steps, const Vector2D &v) { Vector2D result = v; for (const auto &step : steps) { result = step.Apply(result); } return result; } template inline Vector2D ResetTransformSteps(const std::vector> &steps, const Vector2D &v) { Vector2D result = v; for (auto iter = steps.rbegin(); iter != steps.rend(); ++iter) { result = iter->Reset(result); } return result; } template std::vector> RotateAndFitScreen(Direction direction, const Vector2D &size) { std::vector> result; if (direction == DIRECTION0) { return result; } result.emplace_back(SimpleTransform::RotateDirection(direction)); switch (direction) { case DIRECTION90: result.emplace_back(SimpleTransform::Translate({ size.y, 0 })); break; case DIRECTION180: result.emplace_back(SimpleTransform::Translate(size)); break; case DIRECTION270: result.emplace_back(SimpleTransform::Translate({ 0, size.x })); break; case DIRECTION0: default: break; } return result; } template inline Vector2D RotateRect(Direction direction, const Vector2D &size) { switch (direction) { case DIRECTION90: case DIRECTION270: return { size.y, size.x }; case DIRECTION0: case DIRECTION180: default: return size; } } } // namespace MMI } // namespace OHOS #endif /* MMI_TRANSFORM_H */