* Copyright (c) 2023 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.
*/
#include "ui_rotation.h"
#include "log/log.h"
#include "securec.h"
namespace Updater {
UiRotation &UiRotation::GetInstance(void)
{
static UiRotation uiRotation;
return uiRotation;
}
void UiRotation::InitRotation(int realWidth, int realHeight, uint8_t pixelBytes)
{
LOG(INFO) << "InitRotation realWidth = " << realWidth << ", realHeight = " << realHeight <<
", pixelBytes = " << static_cast<int>(pixelBytes);
pixelBytes_ = pixelBytes;
RotateWidthHeight(realWidth, realHeight);
switch (degree_) {
case UI_ROTATION_DEGREE::UI_ROTATION_90:
sinR_ = 1;
cosR_ = 0;
offsetX_ = height_ - 1;
offsetY_ = 0;
oldRowBytes_ = width_ * pixelBytes_;
newRowBytes_ = height_ * pixelBytes_;
break;
case UI_ROTATION_DEGREE::UI_ROTATION_180:
sinR_ = 0;
cosR_ = -1;
offsetX_ = width_ - 1;
offsetY_ = height_ - 1;
oldRowBytes_ = width_ * pixelBytes_;
newRowBytes_ = width_ * pixelBytes_;
break;
case UI_ROTATION_DEGREE::UI_ROTATION_270:
sinR_ = -1;
cosR_ = 0;
offsetX_ = 0;
offsetY_ = width_ - 1;
oldRowBytes_ = width_ * pixelBytes_;
newRowBytes_ = height_ * pixelBytes_;
break;
default:
sinR_ = 0;
cosR_ = 1;
offsetX_ = 0;
offsetY_ = 0;
oldRowBytes_ = width_ * pixelBytes_;
newRowBytes_ = width_ * pixelBytes_;
}
}
void UiRotation::SetDegree(UI_ROTATION_DEGREE degree)
{
degree_ = degree;
}
int UiRotation::GetWidth(void)
{
return width_;
}
int UiRotation::GetHeight(void)
{
return height_;
}
void UiRotation::RotateWidthHeight(int realWidth, int realHeight)
{
if (degree_ == UI_ROTATION_DEGREE::UI_ROTATION_0 || degree_ == UI_ROTATION_DEGREE::UI_ROTATION_180) {
width_ = realWidth;
height_ = realHeight;
} else {
width_ = realHeight;
height_ = realWidth;
}
}
void UiRotation::SetFlushRange(const OHOS::Rect &rect)
{
rect_ = rect;
}
void UiRotation::RotateBuffer(const uint8_t *origBuf, uint8_t *dstBuf, uint32_t size)
{
if (degree_ == UI_ROTATION_DEGREE::UI_ROTATION_0) {
if (memcpy_s(dstBuf, size, origBuf, size) != EOK) {
LOG(ERROR) << "flip memcpy_s fail";
}
return;
}
int x {};
int y {};
const uint8_t *srcP = nullptr;
uint8_t *dstP = nullptr;
int top = rect_.GetTop();
int bottom = rect_.GetBottom();
int left = rect_.GetLeft();
int right = rect_.GetRight();
for (int h = top; h <= bottom; h++) {
for (int w = left; w <= right; w++) {
x = offsetX_ + w * cosR_ - h * sinR_;
y = offsetY_ + h * cosR_ + w * sinR_;
srcP = origBuf + h * oldRowBytes_ + w * pixelBytes_;
dstP = dstBuf + y * newRowBytes_ + x * pixelBytes_;
if (memcpy_s(dstP, pixelBytes_, srcP, pixelBytes_) != EOK) {
LOG(ERROR) << "flip memcpy_s fail " << "w = " << w << " h = " << h;
return;
} else {
srcP += pixelBytes_;
dstP += pixelBytes_;
}
}
}
}
std::pair<int, int> UiRotation::RotateXY(int x, int y)
{
if (degree_ == UI_ROTATION_DEGREE::UI_ROTATION_0) {
return {x, y};
}
return {cosR_ * (x - offsetX_) + sinR_ * (y - offsetY_), cosR_ * (y - offsetY_) - sinR_ * (x - offsetX_)};
}
}