enable window property transform

Signed-off-by: zhirong <215782872@qq.com>
Change-Id: I24e1790cefe5d11e29f9e9e2862effb79803603f
Signed-off-by: zhirong <215782872@qq.com>
This commit is contained in:
zhirong
2022-07-07 19:29:34 +08:00
parent cce6f33c7e
commit ca69db7505
18 changed files with 796 additions and 23 deletions
+21
View File
@@ -136,6 +136,7 @@ enum class WindowSizeChangeReason : uint32_t {
RESIZE,
MOVE,
HIDE,
TRANSFORM,
};
enum class WindowLayoutMode : uint32_t {
@@ -181,6 +182,20 @@ public:
translateX_(0.f), translateY_(0.f), translateZ_(0.f)
{}
~Transform() {}
bool operator!=(const Transform& right) const
{
return (pivotX_ - right.pivotX_) || (pivotY_ - right.pivotY_) || (scaleX_ - right.scaleX_) ||
(scaleY_ - right.scaleY_) || (rotationX_ - right.rotationX_) || (rotationY_ - right.rotationY_) ||
(rotationZ_ - right.rotationZ_) || (translateX_ - right.translateX_) ||
(translateY_ - right.translateY_) || (translateZ_ - right.translateZ_);
}
bool operator==(const Transform& right) const
{
return !(*this != right);
}
float pivotX_;
float pivotY_;
float scaleX_;
@@ -191,6 +206,12 @@ public:
float translateX_;
float translateY_;
float translateZ_;
static const Transform& Identity()
{
static Transform I;
return I;
}
};
struct SystemBarProperty {
@@ -528,7 +528,7 @@ bool GetAPI7Ability(NativeEngine& engine, AppExecFwk::Ability* &ability)
return true;
}
bool ParseJsDoubleValue(NativeObject* jsObject, NativeEngine& engine, const std::string& name, double data)
bool ParseJsDoubleValue(NativeObject* jsObject, NativeEngine& engine, const std::string& name, double& data)
{
NativeValue* value = jsObject->GetProperty(name.c_str());
if (value->TypeOf() != NATIVE_UNDEFINED) {
@@ -166,7 +166,7 @@ const std::map<ApiOrientation, Orientation> JS_TO_NATIVE_ORIENTATION_MAP {
NativeValue* WindowStageEventTypeInit(NativeEngine* engine);
NativeValue* WindowLayoutModeInit(NativeEngine* engine);
bool GetAPI7Ability(NativeEngine& engine, AppExecFwk::Ability* &ability);
bool ParseJsDoubleValue(NativeObject* jsObject, NativeEngine& engine, const std::string& name, double data);
bool ParseJsDoubleValue(NativeObject* jsObject, NativeEngine& engine, const std::string& name, double& data);
template<class T>
inline bool ConvertNativeValueToVector(NativeEngine& engine, NativeValue* nativeValue, std::vector<T>& out)
{
+1
View File
@@ -39,6 +39,7 @@ ohos_shared_library("libwmutil") {
"src/surface_reader_handler_impl.cpp",
"src/window_property.cpp",
"src/window_transition_info.cpp",
"src/wm_math.cpp",
]
configs = [ ":libwmutil_private_config" ]
+90
View File
@@ -20,6 +20,7 @@
#include "ability_info.h"
#include "wm_common.h"
#include "wm_common_inner.h"
#include "wm_math.h"
namespace OHOS {
namespace Rosen {
@@ -325,6 +326,95 @@ public:
return ret;
}
// Transform a point at screen to its oringin position in 3D world and project to xy plane
// A screen point only has x and y component, so we need a plane to calculate its z component.
// | -- -- -- 0 |
// | -- -- -- 0 |
// There is no need to unify w component since the matrix is like | -- -- -- 0 |
// | -- -- -- 1 |
static PointInfo CalculateOriginPosition(const TransformHelper::Matrix4& transformMat,
const TransformHelper::Plane& plane, const PointInfo& pointPos)
{
TransformHelper::Matrix4 invertMat = transformMat;
invertMat.Invert();
TransformHelper::Vector3 pointAtPlane;
pointAtPlane.x_ = static_cast<float>(pointPos.x);
pointAtPlane.y_ = static_cast<float>(pointPos.y);
pointAtPlane.z_ = plane.ComponentZ(pointAtPlane.x_, pointAtPlane.y_);
TransformHelper::Vector3 originPos = TransformHelper::Transform(pointAtPlane, invertMat);
return PointInfo { static_cast<uint32_t>(originPos.x_), static_cast<uint32_t>(originPos.y_) };
}
static TransformHelper::Matrix4 ComputeRectTransformMat4(const Transform& transform, const Rect& rect)
{
TransformHelper::Vector3 pivotPos = {
rect.posX_ + transform.pivotX_ * rect.width_, rect.posY_ + transform.pivotY_ * rect.height_, 0 };
// move pivot point to (0,0,0)
TransformHelper::Matrix4 ret = TransformHelper::CreateTranslation(-pivotPos);
// set scale
if ((transform.scaleX_ - 1) || (transform.scaleY_ - 1)) {
ret *= TransformHelper::CreateScale(transform.scaleX_, transform.scaleY_, 1.0f);
}
// set rotation
if (transform.rotationX_) {
ret *= TransformHelper::CreateRotationX(MathHelper::ToRadians(transform.rotationX_));
}
if (transform.rotationY_) {
ret *= TransformHelper::CreateRotationY(MathHelper::ToRadians(transform.rotationY_));
}
if (transform.rotationZ_) {
ret *= TransformHelper::CreateRotationZ(MathHelper::ToRadians(transform.rotationZ_));
}
// set translation
if (transform.translateX_ || transform.translateY_ || transform.translateZ_) {
ret *= TransformHelper::CreateTranslation(TransformHelper::Vector3(transform.translateX_,
transform.translateY_, transform.translateZ_));
}
// move pivot point to old position
ret *= TransformHelper::CreateTranslation(pivotPos);
return ret;
}
// Transform rect by matrix and get the circumscribed rect
static Rect TransformRect(const TransformHelper::Matrix4& transformMat, const Rect& rect)
{
TransformHelper::Vector3 a = TransformHelper::Transform(
TransformHelper::Vector3(rect.posX_, rect.posY_, 0), transformMat);
TransformHelper::Vector3 b = TransformHelper::Transform(
TransformHelper::Vector3(rect.posX_ + rect.width_, rect.posY_, 0), transformMat);
TransformHelper::Vector3 c = TransformHelper::Transform(
TransformHelper::Vector3(rect.posX_, rect.posY_ + rect.height_, 0), transformMat);
TransformHelper::Vector3 d = b + c - a;
// Return smallest rect involve transformed rect(abcd)
int32_t xmin = MathHelper::Min(a.x_, b.x_, c.x_, d.x_);
int32_t ymin = MathHelper::Min(a.y_, b.y_, c.y_, d.y_);
int32_t xmax = MathHelper::Max(a.x_, b.x_, c.x_, d.x_);
int32_t ymax = MathHelper::Max(a.y_, b.y_, c.y_, d.y_);
uint32_t w = xmax - xmin;
uint32_t h = ymax - ymin;
return Rect { xmin, ymin, w, h };
}
static TransformHelper::Vector2 CalculateHotZoneScale(const TransformHelper::Matrix4& transformMat,
const TransformHelper::Plane& plane)
{
TransformHelper::Vector2 hotZoneScale;
TransformHelper::Vector3 a = TransformHelper::Transform(TransformHelper::Vector3(0, 0, 0),
transformMat);
TransformHelper::Vector3 b = TransformHelper::Transform(TransformHelper::Vector3(1, 0, 0),
transformMat);
TransformHelper::Vector3 c = TransformHelper::Transform(TransformHelper::Vector3(0, 1, 0),
transformMat);
TransformHelper::Vector3 scale = transformMat.GetScale();
hotZoneScale.x_ = scale.x_ * plane.ParallelDistanceGrad(a, c);
hotZoneScale.y_ = scale.y_ * plane.ParallelDistanceGrad(a, b);
if (std::isnan(hotZoneScale.x_) || std::isnan(hotZoneScale.y_)) {
return TransformHelper::Vector2(1, 1);
} else {
return hotZoneScale;
}
}
static bool CalculateTouchHotAreas(const Rect& windowRect, const std::vector<Rect>& requestRects,
std::vector<Rect>& outRects)
{
+8
View File
@@ -24,6 +24,7 @@
#include "dm_common.h"
#include "wm_common.h"
#include "wm_common_inner.h"
#include "wm_math.h"
namespace OHOS {
namespace Rosen {
@@ -76,6 +77,7 @@ public:
void SetSizeLimits(const WindowSizeLimits& sizeLimits);
WindowSizeChangeReason GetWindowSizeChangeReason() const;
void SetTransform(const Transform& trans);
void ComputeTransform();
const std::string& GetWindowName() const;
Rect GetRequestRect() const;
@@ -114,6 +116,7 @@ public:
uint32_t GetAccessTokenId() const;
Transform GetTransform() const;
WindowSizeLimits GetSizeLimits() const;
const TransformHelper::Matrix4& GetTransformMat() const;
virtual bool Marshalling(Parcel& parcel) const override;
static WindowProperty* Unmarshalling(Parcel& parcel);
@@ -170,8 +173,13 @@ private:
DragType dragType_ = DragType::DRAG_UNDEFINED;
std::vector<Rect> touchHotAreas_; // coordinates relative to window.
uint32_t accessTokenId_ { 0 };
// Transform info
Transform trans_;
bool recomputeTransformMat_ { false };
TransformHelper::Matrix4 transformMat_ = TransformHelper::Matrix4::Identity;
DEFINE_VAR_DEFAULT_FUNC_GET_SET(Orientation, RequestedOrientation, requestedOrientation, Orientation::UNSPECIFIED);
DEFINE_VAR_FUNC_GET_SET(TransformHelper::Plane, Plane, windowPlane);
WindowSizeLimits sizeLimits_;
};
}
+1
View File
@@ -55,6 +55,7 @@ enum class WindowUpdateReason : uint32_t {
UPDATE_TYPE,
NEED_SWITCH_CASCADE_END,
UPDATE_OTHER_PROPS,
UPDATE_TRANSFORM,
};
enum class AvoidPosType : uint32_t {
+222
View File
@@ -0,0 +1,222 @@
/*
* Copyright (c) 2022 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 OHOS_ROSEN_WM_MATH_H
#define OHOS_ROSEN_WM_MATH_H
#include <limits>
#include <cmath>
namespace OHOS {
namespace Rosen {
namespace MathHelper {
constexpr float PI = 3.14159265f;
constexpr float INF = std::numeric_limits<float>::infinity();
constexpr float NAG_INF = -std::numeric_limits<float>::infinity();
constexpr float POS_ZERO = 0.001f;
constexpr float NAG_ZERO = -POS_ZERO;
inline bool NearZero(float val)
{
return val < POS_ZERO && val > NAG_ZERO;
}
inline float ToRadians(float degrees)
{
return degrees * PI / 180.0f;
}
inline float ToDegrees(float radians)
{
return radians * 180.0f / PI;
}
template <typename T>
T Max(const T& a, const T& b)
{
return (a < b ? b : a);
}
template <typename T, typename... Ts>
T Max(const T& a, Ts... bs)
{
T b = Max(bs...);
return (a > b ? a : b);
}
template <typename T>
T Min(const T& a, const T& b)
{
return (a < b ? a : b);
}
template <typename T, typename... Ts>
T Min(const T& a, Ts... bs)
{
T b = Min(bs...);
return (a < b ? a : b);
}
template <typename T>
T Clamp(const T& value, const T& lower, const T& upper)
{
return Min(upper, Max(lower, value));
}
} // namespace MathHelper
namespace TransformHelper {
struct Vector2 {
float x_, y_;
Vector2() : x_(0.0f), y_(0.0f) {}
Vector2(float inX, float inY)
: x_(inX), y_(inY) {}
friend Vector2 operator-(const Vector2& v)
{
return Vector2 { -v.x_, -v.y_ };
}
friend Vector2 operator+(const Vector2& a, const Vector2& b)
{
return Vector2 { a.x_ + b.x_, a.y_ + b.y_ };
}
friend Vector2 operator-(const Vector2& a, const Vector2& b)
{
return Vector2 { a.x_ - b.x_, a.y_ - b.y_ };
}
float LengthSq() const
{
return (x_ * x_ + y_ * y_);
}
float Length() const
{
return (std::sqrt(LengthSq()));
}
};
struct Vector3 {
float x_, y_, z_;
Vector3() : x_(0.0f), y_(0.0f), z_(0.0f) {}
Vector3(float inX, float inY, float inZ)
: x_(inX), y_(inY), z_(inZ) {}
friend Vector3 operator-(const Vector3& v)
{
return Vector3 { -v.x_, -v.y_, -v.z_ };
}
friend Vector3 operator+(const Vector3& a, const Vector3& b)
{
return Vector3 { a.x_ + b.x_, a.y_ + b.y_, a.z_ + b.z_ };
}
friend Vector3 operator-(const Vector3& a, const Vector3& b)
{
return Vector3 { a.x_ - b.x_, a.y_ - b.y_, a.z_ - b.z_ };
}
float LengthSq() const
{
return (x_ * x_ + y_ * y_ + z_ * z_);
}
float Length() const
{
return (std::sqrt(LengthSq()));
}
void Normalize()
{
float length = Length();
if (length > MathHelper::POS_ZERO) {
x_ /= length;
y_ /= length;
z_ /= length;
}
}
static Vector3 Normalize(const Vector3& vec)
{
Vector3 temp = vec;
temp.Normalize();
return temp;
}
static float Dot(const Vector3& a, const Vector3& b)
{
return (a.x_ * b.x_ + a.y_ * b.y_ + a.z_ * b.z_);
}
static Vector3 Cross(const Vector3& a, const Vector3& b)
{
Vector3 temp;
temp.x_ = a.y_ * b.z_ - a.z_ * b.y_;
temp.y_ = a.z_ * b.x_ - a.x_ * b.z_;
temp.z_ = a.x_ * b.y_ - a.y_ * b.x_;
return temp;
}
};
struct Matrix3 {
float mat_[3][3];
friend Matrix3 operator*(const Matrix3& left, const Matrix3& right);
Matrix3& operator*=(const Matrix3& right);
static const Matrix3 Identity;
};
struct Matrix4 {
float mat_[4][4];
friend Matrix4 operator*(const Matrix4& left, const Matrix4& right);
Matrix4& operator*=(const Matrix4& right);
void SwapRow(int row1, int row2);
// Inverse matrix with Gauss-Jordan method
void Invert();
// Extract the scale component from the matrix
Vector3 GetScale() const;
static const Matrix4 Identity;
static constexpr int MAT_SIZE = 4;
};
struct Plane {
Plane() : normal_ { 0, 0, 1 }, d_ { 0 } {}
Plane(const Vector3& normal, float d);
Plane(const Vector3& a, const Vector3& b, const Vector3& c);
float ComponentZ(float x, float y) const;
// Compute the distance of parallel lines projected from this plane to xy plane
// it is assumed that distance of parallel lines in this plane is 1
// a, b determine a line in this plane
float ParallelDistanceGrad(const Vector3& a, const Vector3& b) const;
Vector3 normal_; // Normal vector of plane
float d_; // Signed distance from (0,0,0) to plane
};
// Create a scale matrix with x and y scales(in xy-plane)
Matrix3 CreateScale(float xScale, float yScale);
// Create a rotation matrix about the Z axis
// theta is in radians
Matrix3 CreateRotation(float theta);
// Create a translation matrix (on the xy-plane)
Matrix3 CreateTranslation(const Vector2& trans);
// Create a scale matrix with x, y, and z scales
Matrix4 CreateScale(float xScale, float yScale, float zScale);
// Create a rotation matrix about X axis
// theta is in radians
Matrix4 CreateRotationX(float theta);
// Create a rotation matrix about Y axis
// theta is in radians
Matrix4 CreateRotationY(float theta);
// Create a rotation matrix about Z axis
// theta is in radians
Matrix4 CreateRotationZ(float theta);
// Create a 3D translation matrix
Matrix4 CreateTranslation(const Vector3& trans);
// Transform a Vector2 in xy-plane by matrix3
Vector2 Transform(const Vector2& vec, const Matrix3& mat);
// Transform a Vector3 in 3D world by matrix4
Vector3 Transform(const Vector3& vec, const Matrix4& mat);
} // namespace TransformHelper
} // namespace OHOS
} // namespace Rosen
#endif // OHOS_ROSEN_WM_MATH_H
+27
View File
@@ -31,6 +31,7 @@ void WindowProperty::SetWindowName(const std::string& name)
void WindowProperty::SetWindowRect(const struct Rect& rect)
{
recomputeTransformMat_ = true;
windowRect_ = rect;
}
@@ -108,9 +109,30 @@ void WindowProperty::SetAlpha(float alpha)
void WindowProperty::SetTransform(const Transform& trans)
{
recomputeTransformMat_ = true;
trans_ = trans;
}
void WindowProperty::ComputeTransform()
{
if (recomputeTransformMat_ && (trans_ != Transform::Identity())) {
// Update transform matrix
transformMat_ = WindowHelper::ComputeRectTransformMat4(trans_, windowRect_);
// Update window plane
TransformHelper::Vector3 a = TransformHelper::Transform(
TransformHelper::Vector3 { static_cast<float>(windowRect_.posX_),
static_cast<float>(windowRect_.posY_), 0 }, transformMat_);
TransformHelper::Vector3 b = TransformHelper::Transform(
TransformHelper::Vector3 { static_cast<float>(windowRect_.posX_ + windowRect_.width_),
static_cast<float>(windowRect_.posY_), 0 }, transformMat_);
TransformHelper::Vector3 c = TransformHelper::Transform(
TransformHelper::Vector3 { static_cast<float>(windowRect_.posX_),
static_cast<float>(windowRect_.posY_+ windowRect_.height_), 0 }, transformMat_);
windowPlane_ = TransformHelper::Plane(a, b, c);
recomputeTransformMat_ = false;
}
}
void WindowProperty::SetBrightness(float brightness)
{
brightness_ = brightness;
@@ -411,6 +433,11 @@ WindowSizeLimits WindowProperty::GetSizeLimits() const
return sizeLimits_;
}
const TransformHelper::Matrix4& WindowProperty::GetTransformMat() const
{
return transformMat_;
}
void WindowProperty::SetTouchHotAreas(const std::vector<Rect>& rects)
{
touchHotAreas_ = rects;
+319
View File
@@ -0,0 +1,319 @@
/*
* Copyright (c) 2022 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 "wm_math.h"
#include <memory>
namespace OHOS {
namespace Rosen {
namespace TransformHelper {
const Matrix3 Matrix3::Identity = { {
{ 1, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 1 },
} };
const Matrix4 Matrix4::Identity = { {
{ 1, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 1 },
} };
Matrix3 operator*(const Matrix3& left, const Matrix3& right)
{
return { {
// row 0
{ left.mat_[0][0] * right.mat_[0][0] + left.mat_[0][1] * right.mat_[1][0] + left.mat_[0][2] * right.mat_[2][0],
left.mat_[0][0] * right.mat_[0][1] + left.mat_[0][1] * right.mat_[1][1] + left.mat_[0][2] * right.mat_[2][1],
left.mat_[0][0] * right.mat_[0][2] + left.mat_[0][1] * right.mat_[1][2] + left.mat_[0][2] * right.mat_[2][2] },
// row 1
{ left.mat_[1][0] * right.mat_[0][0] + left.mat_[1][1] * right.mat_[1][0] + left.mat_[1][2] * right.mat_[2][0],
left.mat_[1][0] * right.mat_[0][1] + left.mat_[1][1] * right.mat_[1][1] + left.mat_[1][2] * right.mat_[2][1],
left.mat_[1][0] * right.mat_[0][2] + left.mat_[1][1] * right.mat_[1][2] + left.mat_[1][2] * right.mat_[2][2] },
// row 2
{ left.mat_[2][0] * right.mat_[0][0] + left.mat_[2][1] * right.mat_[1][0] + left.mat_[2][2] * right.mat_[2][0],
left.mat_[2][0] * right.mat_[0][1] + left.mat_[2][1] * right.mat_[1][1] + left.mat_[2][2] * right.mat_[2][1],
left.mat_[2][0] * right.mat_[0][2] + left.mat_[2][1] * right.mat_[1][2] + left.mat_[2][2] * right.mat_[2][2] }
} };
}
Matrix3& Matrix3::operator*=(const Matrix3& right)
{
*this = *this * right;
return *this;
}
Matrix4 operator*(const Matrix4& left, const Matrix4& right)
{
return { {
// row 0
{ left.mat_[0][0] * right.mat_[0][0] + left.mat_[0][1] * right.mat_[1][0] +
left.mat_[0][2] * right.mat_[2][0] + left.mat_[0][3] * right.mat_[3][0],
left.mat_[0][0] * right.mat_[0][1] + left.mat_[0][1] * right.mat_[1][1] +
left.mat_[0][2] * right.mat_[2][1] + left.mat_[0][3] * right.mat_[3][1],
left.mat_[0][0] * right.mat_[0][2] + left.mat_[0][1] * right.mat_[1][2] +
left.mat_[0][2] * right.mat_[2][2] + left.mat_[0][3] * right.mat_[3][2],
left.mat_[0][0] * right.mat_[0][3] + left.mat_[0][1] * right.mat_[1][3] +
left.mat_[0][2] * right.mat_[2][3] + left.mat_[0][3] * right.mat_[3][3] },
// row 1
{ left.mat_[1][0] * right.mat_[0][0] + left.mat_[1][1] * right.mat_[1][0] +
left.mat_[1][2] * right.mat_[2][0] + left.mat_[1][3] * right.mat_[3][0],
left.mat_[1][0] * right.mat_[0][1] + left.mat_[1][1] * right.mat_[1][1] +
left.mat_[1][2] * right.mat_[2][1] + left.mat_[1][3] * right.mat_[3][1],
left.mat_[1][0] * right.mat_[0][2] + left.mat_[1][1] * right.mat_[1][2] +
left.mat_[1][2] * right.mat_[2][2] + left.mat_[1][3] * right.mat_[3][2],
left.mat_[1][0] * right.mat_[0][3] + left.mat_[1][1] * right.mat_[1][3] +
left.mat_[1][2] * right.mat_[2][3] + left.mat_[1][3] * right.mat_[3][3] },
// row 2
{ left.mat_[2][0] * right.mat_[0][0] + left.mat_[2][1] * right.mat_[1][0] +
left.mat_[2][2] * right.mat_[2][0] + left.mat_[2][3] * right.mat_[3][0],
left.mat_[2][0] * right.mat_[0][1] + left.mat_[2][1] * right.mat_[1][1] +
left.mat_[2][2] * right.mat_[2][1] + left.mat_[2][3] * right.mat_[3][1],
left.mat_[2][0] * right.mat_[0][2] + left.mat_[2][1] * right.mat_[1][2] +
left.mat_[2][2] * right.mat_[2][2] + left.mat_[2][3] * right.mat_[3][2],
left.mat_[2][0] * right.mat_[0][3] + left.mat_[2][1] * right.mat_[1][3] +
left.mat_[2][2] * right.mat_[2][3] + left.mat_[2][3] * right.mat_[3][3] },
// row 3
{ left.mat_[3][0] * right.mat_[0][0] + left.mat_[3][1] * right.mat_[1][0] +
left.mat_[3][2] * right.mat_[2][0] + left.mat_[3][3] * right.mat_[3][0],
left.mat_[3][0] * right.mat_[0][1] + left.mat_[3][1] * right.mat_[1][1] +
left.mat_[3][2] * right.mat_[2][1] + left.mat_[3][3] * right.mat_[3][1],
left.mat_[3][0] * right.mat_[0][2] + left.mat_[3][1] * right.mat_[1][2] +
left.mat_[3][2] * right.mat_[2][2] + left.mat_[3][3] * right.mat_[3][2],
left.mat_[3][0] * right.mat_[0][3] + left.mat_[3][1] * right.mat_[1][3] +
left.mat_[3][2] * right.mat_[2][3] + left.mat_[3][3] * right.mat_[3][3] }
} };
}
Matrix4& Matrix4::operator*=(const Matrix4& right)
{
*this = *this * right;
return *this;
}
void Matrix4::SwapRow(int row1, int row2)
{
float *p = mat_[row1];
float *q = mat_[row2];
float tmp = p[0];
p[0] = q[0];
q[0] = tmp;
tmp = p[1];
p[1] = q[1];
q[1] = tmp;
tmp = p[2];
p[2] = q[2];
q[2] = tmp;
tmp = p[3];
p[3] = q[3];
q[3] = tmp;
}
void Matrix4::Invert()
{
// Inverse matrix with Gauss-Jordan method
Matrix4 tmp = Matrix4::Identity;
int i, j, k;
float t, u;
for (k = 0; k < MAT_SIZE; k++) {
t = mat_[k][k];
if (t < MathHelper::POS_ZERO && t > MathHelper::NAG_ZERO) {
for (i = k + 1; i < MAT_SIZE; i++) {
if (mat_[i][k] < MathHelper::NAG_ZERO || mat_[i][k] > MathHelper::POS_ZERO) {
SwapRow(k, i);
tmp.SwapRow(k, i);
break;
}
}
t = mat_[k][k];
}
for (j = 0; j <= k; j++) {
tmp.mat_[k][j] /= t;
}
for (; j < MAT_SIZE; j++) {
mat_[k][j] /= t;
tmp.mat_[k][j] /= t;
}
for (i = 0; i < MAT_SIZE; i++) {
if (i == k) {
continue;
}
u = mat_[i][k];
for (j = 0; j <= k; j++) {
tmp.mat_[i][j] -= tmp.mat_[k][j] * u;
}
for (; j < MAT_SIZE; j++) {
mat_[i][j] -= mat_[k][j] * u;
tmp.mat_[i][j] -= tmp.mat_[k][j] * u;
}
}
}
*this = tmp;
}
Vector3 Matrix4::GetScale() const
{
Vector3 retVal;
retVal.x_ = Vector3(mat_[0][0], mat_[0][1], mat_[0][2]).Length();
retVal.y_ = Vector3(mat_[1][0], mat_[1][1], mat_[1][2]).Length();
retVal.z_ = Vector3(mat_[2][0], mat_[2][1], mat_[2][2]).Length();
return retVal;
}
Plane::Plane(const Vector3& normal, float d)
: normal_(normal), d_(d)
{
}
Plane::Plane(const Vector3& a, const Vector3& b, const Vector3& c)
{
Vector3 ab = b - a;
Vector3 ac = c - a;
normal_ = Vector3::Cross(ab, ac);
normal_.Normalize();
d_ = -Vector3::Dot(a, normal_);
}
float Plane::ComponentZ(float x, float y) const
{
return (-d_ - normal_.x_ * x - normal_.y_ * y) / normal_.z_;
}
float Plane::ParallelDistanceGrad(const Vector3& a, const Vector3& b) const
{
Vector2 axy(a.x_, a.y_), bxy(b.x_, b.y_);
return (b - a).Length() * std::abs(normal_.z_) / (bxy - axy).Length();
}
// Create a scale matrix with x and y scales
Matrix3 CreateScale(float xScale, float yScale)
{
return { {
{ xScale, 0.0f, 0.0f },
{ 0.0f, yScale, 0.0f },
{ 0.0f, 0.0f, 1.0f },
} };
}
// Create a rotation matrix about the Z axis
// theta is in radians
Matrix3 CreateRotation(float theta)
{
return { {
{ std::cos(theta), std::sin(theta), 0.0f },
{ -std::sin(theta), std::cos(theta), 0.0f },
{ 0.0f, 0.0f, 1.0f },
} };
}
// Create a translation matrix (on the xy-plane)
Matrix3 CreateTranslation(const Vector2& trans)
{
return { {
{ 1.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f },
{ trans.x_, trans.y_, 1.0f },
} };
}
// Create a scale matrix with x, y, and z scales
Matrix4 CreateScale(float xScale, float yScale, float zScale)
{
return { {
{ xScale, 0.0f, 0.0f, 0.0f },
{ 0.0f, yScale, 0.0f, 0.0f },
{ 0.0f, 0.0f, zScale, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f },
} };
}
// Create a rotation matrix about X axis
// theta is in radians
Matrix4 CreateRotationX(float theta)
{
return { {
{ 1.0f, 0.0f, 0.0f, 0.0f },
{ 0.0f, std::cos(theta), std::sin(theta), 0.0f },
{ 0.0f, -std::sin(theta), std::cos(theta), 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f },
} };
}
// Create a rotation matrix about Y axis
// theta is in radians
Matrix4 CreateRotationY(float theta)
{
return { {
{ std::cos(theta), 0.0f, -std::sin(theta), 0.0f },
{ 0.0f, 1.0f, 0.0f, 0.0f },
{ std::sin(theta), 0.0f, std::cos(theta), 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f },
} };
}
// Create a rotation matrix about Z axis
// theta is in radians
Matrix4 CreateRotationZ(float theta)
{
return { {
{ std::cos(theta), std::sin(theta), 0.0f, 0.0f },
{ -std::sin(theta), std::cos(theta), 0.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f, 0.0f },
{ 0.0f, 0.0f, 0.0f, 1.0f },
} };
}
// Create a 3D translation matrix
Matrix4 CreateTranslation(const Vector3& trans)
{
return { {
{ 1.0f, 0.0f, 0.0f, 0.0f },
{ 0.0f, 1.0f, 0.0f, 0.0f },
{ 0.0f, 0.0f, 1.0f, 0.0f },
{ trans.x_, trans.y_, trans.z_, 1.0f },
} };
}
// Transform a Vector2 in xy-plane by matrix3
Vector2 Transform(const Vector2& vec, const Matrix3& mat)
{
Vector2 retVal;
retVal.x_ = vec.x_ * mat.mat_[0][0] + vec.y_ * mat.mat_[1][0] + mat.mat_[2][0];
retVal.y_ = vec.x_ * mat.mat_[0][1] + vec.y_ * mat.mat_[1][1] + mat.mat_[2][1];
return retVal;
}
// Transform a Vector3 in 3D world by matrix4
Vector3 Transform(const Vector3& vec, const Matrix4& mat)
{
Vector3 retVal;
retVal.x_ = vec.x_ * mat.mat_[0][0] + vec.y_ * mat.mat_[1][0] +
vec.z_ * mat.mat_[2][0] + mat.mat_[3][0];
retVal.y_ = vec.x_ * mat.mat_[0][1] + vec.y_ * mat.mat_[1][1] +
vec.z_ * mat.mat_[2][1] + mat.mat_[3][1];
retVal.z_ = vec.x_ * mat.mat_[0][2] + vec.y_ * mat.mat_[1][2] +
vec.z_ * mat.mat_[2][2] + mat.mat_[3][2];
return retVal;
}
} // namespace TransformHelper
} // namespace Rosen
} // namespace OHOS
+1
View File
@@ -345,6 +345,7 @@ private:
Rect GetSystemAlarmWindowDefaultSize(Rect defaultRect);
void HandleModeChangeHotZones(int32_t posX, int32_t posY);
WMError NotifyWindowTransition(TransitionReason reason);
void UpdatePointerEvent(std::shared_ptr<MMI::PointerEvent>& pointerEvent);
void UpdatePointerEventForStretchableWindow(std::shared_ptr<MMI::PointerEvent>& pointerEvent);
void UpdateDragType();
void InitListenerHandler();
+42 -8
View File
@@ -1924,6 +1924,28 @@ void WindowImpl::HandleModeChangeHotZones(int32_t posX, int32_t posY)
}
}
void WindowImpl::UpdatePointerEvent(std::shared_ptr<MMI::PointerEvent>& pointerEvent)
{
property_->ComputeTransform();
MMI::PointerEvent::PointerItem pointerItem;
if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
WLOGFW("Point item is invalid");
return;
}
Rect winRect = GetRect();
PointInfo originPos =
WindowHelper::CalculateOriginPosition(property_->GetTransformMat(), property_->GetPlane(),
{ pointerItem.GetDisplayX(), pointerItem.GetDisplayY() });
WLOGI("Pointer event has been updated,window id:%{public}u, before->now:"
"[%{public}d,%{public}d]->[%{public}d,%{public}d]",
property_->GetWindowId(), pointerItem.GetDisplayX(), pointerItem.GetDisplayY(), originPos.x, originPos.y);
pointerItem.SetDisplayX(originPos.x);
pointerItem.SetDisplayY(originPos.y);
pointerItem.SetWindowX(originPos.x - winRect.posX_);
pointerItem.SetWindowY(originPos.y - winRect.posY_);
pointerEvent->UpdatePointerItem(pointerEvent->GetPointerId(), pointerItem);
}
void WindowImpl::UpdatePointerEventForStretchableWindow(std::shared_ptr<MMI::PointerEvent>& pointerEvent)
{
MMI::PointerEvent::PointerItem pointerItem;
@@ -1986,6 +2008,12 @@ void WindowImpl::ReadyToMoveOrDragWindow(int32_t globalX, int32_t globalY, int32
if (pointEventStarted_) {
return;
}
TransformHelper::Vector2 hotZoneScale(1, 1);
if (property_->GetTransform() != Transform::Identity()) {
property_->ComputeTransform();
hotZoneScale = WindowHelper::CalculateHotZoneScale(property_->GetTransformMat(),
property_->GetPlane());
}
startPointRect_ = rect;
startPointPosX_ = globalX;
startPointPosY_ = globalY;
@@ -2002,22 +2030,24 @@ void WindowImpl::ReadyToMoveOrDragWindow(int32_t globalX, int32_t globalY, int32
float virtualPixelRatio = display->GetVirtualPixelRatio();
startRectExceptFrame_.posX_ = startPointRect_.posX_ +
static_cast<int32_t>(WINDOW_FRAME_WIDTH * virtualPixelRatio);
static_cast<int32_t>(WINDOW_FRAME_WIDTH * virtualPixelRatio / hotZoneScale.x_);
startRectExceptFrame_.posY_ = startPointRect_.posY_ +
static_cast<int32_t>(WINDOW_FRAME_WIDTH * virtualPixelRatio);
static_cast<int32_t>(WINDOW_FRAME_WIDTH * virtualPixelRatio / hotZoneScale.y_);
startRectExceptFrame_.width_ = startPointRect_.width_ -
static_cast<uint32_t>((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * virtualPixelRatio);
static_cast<uint32_t>((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * virtualPixelRatio / hotZoneScale.x_);
startRectExceptFrame_.height_ = startPointRect_.height_ -
static_cast<uint32_t>((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * virtualPixelRatio);
static_cast<uint32_t>((WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH) * virtualPixelRatio / hotZoneScale.y_);
startRectExceptCorner_.posX_ = startPointRect_.posX_ +
static_cast<int32_t>(WINDOW_FRAME_CORNER_WIDTH * virtualPixelRatio);
static_cast<int32_t>(WINDOW_FRAME_CORNER_WIDTH * virtualPixelRatio / hotZoneScale.x_);
startRectExceptCorner_.posY_ = startPointRect_.posY_ +
static_cast<int32_t>(WINDOW_FRAME_CORNER_WIDTH * virtualPixelRatio);
static_cast<int32_t>(WINDOW_FRAME_CORNER_WIDTH * virtualPixelRatio / hotZoneScale.y_);
startRectExceptCorner_.width_ = startPointRect_.width_ -
static_cast<uint32_t>((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * virtualPixelRatio);
static_cast<uint32_t>((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) *
virtualPixelRatio / hotZoneScale.x_);
startRectExceptCorner_.height_ = startPointRect_.height_ -
static_cast<uint32_t>((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) * virtualPixelRatio);
static_cast<uint32_t>((WINDOW_FRAME_CORNER_WIDTH + WINDOW_FRAME_CORNER_WIDTH) *
virtualPixelRatio / hotZoneScale.y_);
if (GetType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
startMoveFlag_ = true;
@@ -2103,6 +2133,10 @@ void WindowImpl::AdjustWindowAnimationFlag(bool withAnimation)
void WindowImpl::ConsumePointerEvent(std::shared_ptr<MMI::PointerEvent>& pointerEvent)
{
// If windowRect transformed, transform event back to its origin position
if (property_->GetTransform() != Transform::Identity()) {
UpdatePointerEvent(pointerEvent);
}
int32_t action = pointerEvent->GetPointerAction();
if (action == MMI::PointerEvent::POINTER_ACTION_DOWN || action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
WLOGI("WMS process point down, window: [name:%{public}s, id:%{public}u], action: %{public}d",
+1
View File
@@ -83,6 +83,7 @@ private:
void HandleTurnScreenOn(const sptr<WindowNode>& node);
void ProcessSystemBarChange(const sptr<DisplayInfo>& displayInfo);
WMError UpdateTouchHotAreas(const sptr<WindowNode>& node, const std::vector<Rect>& rects);
WMError UpdateTransform(uint32_t windowId);
void NotifyTouchOutside(const sptr<WindowNode>& node);
uint32_t GetEmbedNodeId(const std::vector<sptr<WindowNode>>& windowNodes, const sptr<WindowNode>& node);
void NotifyWindowPropertyChanged(const sptr<WindowNode>& node);
+2
View File
@@ -72,6 +72,8 @@ public:
void SetOriginRect(const Rect& rect);
void SetTouchHotAreas(const std::vector<Rect>& rects);
void SetWindowSizeLimits(const WindowSizeLimits& sizeLimits);
void ComputeTransform();
void SetTransform(const Transform& trans);
const sptr<IWindow>& GetWindowToken() const;
uint32_t GetWindowId() const;
+15 -3
View File
@@ -19,6 +19,7 @@
#include "display_manager_service_inner.h"
#include "dm_common.h"
#include "window_helper.h"
#include "window_manager_hilog.h"
namespace OHOS {
@@ -128,13 +129,24 @@ void InputWindowMonitor::TraverseWindowNodes(const std::vector<sptr<WindowNode>>
}
std::vector<Rect> touchHotAreas;
windowNode->GetTouchHotAreas(touchHotAreas);
Rect windowRect = windowNode->GetWindowRect();
Rect areaRect = windowNode->GetWindowRect();
if (windowNode->GetWindowProperty()->GetTransform() != Transform::Identity()) {
windowNode->ComputeTransform();
for (Rect& rect : touchHotAreas) {
rect = WindowHelper::TransformRect(windowNode->GetWindowProperty()->GetTransformMat(), rect);
}
WLOGFI("area rect befoe tranform: [%{public}d, %{public}d, %{public}u, %{public}u]",
areaRect.posX_, areaRect.posY_, areaRect.width_, areaRect.height_);
areaRect = WindowHelper::TransformRect(windowNode->GetWindowProperty()->GetTransformMat(), areaRect);
WLOGFI("area rect after tranform: [%{public}d, %{public}d, %{public}u, %{public}u]",
areaRect.posX_, areaRect.posY_, areaRect.width_, areaRect.height_);
}
MMI::WindowInfo windowInfo = {
.id = static_cast<int32_t>(windowNode->GetWindowId()),
.pid = windowNode->GetCallingPid(),
.uid = windowNode->GetCallingUid(),
.area = MMI::Rect{ windowRect.posX_, windowRect.posY_,
static_cast<int32_t>(windowRect.width_), static_cast<int32_t>(windowRect.height_) },
.area = MMI::Rect { areaRect.posX_, areaRect.posY_,
static_cast<int32_t>(areaRect.width_), static_cast<int32_t>(areaRect.height_) },
.agentWindowId = static_cast<int32_t>(windowNode->GetWindowId()),
};
convertRectsToMmiRects(touchHotAreas, windowInfo.defaultHotAreas);
+16
View File
@@ -891,6 +891,12 @@ WMError WindowController::UpdateProperty(sptr<WindowProperty>& property, Propert
UpdateWindowAnimation(node);
break;
}
case PropertyChangeAction::ACTION_UPDATE_TRANSFORM_PROPERTY: {
node->SetTransform(property->GetTransform());
node->SetWindowSizeChangeReason(WindowSizeChangeReason::TRANSFORM);
ret = UpdateTransform(windowId);
break;
}
default:
break;
}
@@ -950,6 +956,16 @@ WMError WindowController::UpdateTouchHotAreas(const sptr<WindowNode>& node, cons
return WMError::WM_OK;
}
WMError WindowController::UpdateTransform(uint32_t windowId)
{
WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_TRANSFORM);
if (res != WMError::WM_OK) {
return res;
}
FlushWindowInfo(windowId);
return WMError::WM_OK;
}
void WindowController::NotifyTouchOutside(const sptr<WindowNode>& node)
{
auto windowNodeContainer = windowRoot_->GetOrCreateWindowNodeContainer(node->GetDisplayId());
+18 -10
View File
@@ -422,23 +422,30 @@ void WindowLayoutPolicy::CalcAndSetNodeHotZone(const Rect& winRect, const sptr<W
{
Rect rect = winRect;
float virtualPixelRatio = GetVirtualPixelRatio(node->GetDisplayId());
uint32_t hotZone = static_cast<uint32_t>(HOTZONE * virtualPixelRatio);
TransformHelper::Vector2 hotZoneScale(1, 1);
if (node->GetWindowProperty()->GetTransform() != Transform::Identity()) {
node->ComputeTransform();
hotZoneScale = WindowHelper::CalculateHotZoneScale(node->GetWindowProperty()->GetTransformMat(),
node->GetWindowProperty()->GetPlane());
}
uint32_t hotZoneX = static_cast<uint32_t>(HOTZONE * virtualPixelRatio / hotZoneScale.x_);
uint32_t hotZoneY = static_cast<uint32_t>(HOTZONE * virtualPixelRatio / hotZoneScale.y_);
if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) {
if (rect.width_ < rect.height_) {
rect.posX_ -= hotZone;
rect.width_ += (hotZone + hotZone);
rect.posX_ -= hotZoneX;
rect.width_ += (hotZoneX + hotZoneX);
} else {
rect.posY_ -= hotZone;
rect.height_ += (hotZone + hotZone);
rect.posY_ -= hotZoneY;
rect.height_ += (hotZoneY + hotZoneY);
}
} else if (node->GetWindowType() == WindowType::WINDOW_TYPE_LAUNCHER_RECENT) {
rect = displayGroupInfo_->GetDisplayRect(node->GetDisplayId());
} else if (WindowHelper::IsMainFloatingWindow(node->GetWindowType(), node->GetWindowMode())) {
rect.posX_ -= hotZone;
rect.posY_ -= hotZone;
rect.width_ += (hotZone + hotZone);
rect.height_ += (hotZone + hotZone);
rect.posX_ -= hotZoneX;
rect.posY_ -= hotZoneY;
rect.width_ += (hotZoneX + hotZoneX);
rect.height_ += (hotZoneY + hotZoneY);
}
node->SetFullWindowHotArea(rect);
std::vector<Rect> requestedHotAreas;
@@ -938,7 +945,8 @@ bool WindowLayoutPolicy::IsFullScreenRecentWindowExist(const std::vector<sptr<Wi
void WindowLayoutPolicy::UpdateSurfaceBounds(const sptr<WindowNode>& node, const Rect& winRect, const Rect& preRect)
{
if (node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT) {
if (node->GetWindowType() == WindowType::WINDOW_TYPE_APP_COMPONENT ||
node->GetWindowSizeChangeReason() == WindowSizeChangeReason::TRANSFORM) {
WLOGFI("not need to update bounds");
return;
}
+10
View File
@@ -201,6 +201,16 @@ void WindowNode::SetWindowSizeLimits(const WindowSizeLimits& sizeLimits)
property_->SetSizeLimits(sizeLimits);
}
void WindowNode::ComputeTransform()
{
property_->ComputeTransform();
}
void WindowNode::SetTransform(const Transform& trans)
{
property_->SetTransform(trans);
}
WindowSizeLimits WindowNode::GetWindowSizeLimits() const
{
return property_->GetSizeLimits();