1 /* 2 * Copyright (c) 2021-2022 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 #ifndef RENDER_SERVICE_CLIENT_CORE_COMMON_RS_RECT_H 17 #define RENDER_SERVICE_CLIENT_CORE_COMMON_RS_RECT_H 18 #include <cmath> 19 #include <unordered_set> 20 21 #include "common/rs_common_def.h" 22 #include "common/rs_vector2.h" 23 #include "common/rs_vector4.h" 24 #include "platform/common/rs_log.h" 25 #include "transaction/rs_marshalling_helper.h" 26 27 namespace OHOS { 28 namespace Rosen { 29 template<typename T> 30 class RectT { 31 public: 32 union { 33 struct { 34 T left_; 35 T top_; 36 T width_; 37 T height_; 38 }; 39 T data_[4]; // 4 is size of data or structure 40 }; 41 RectT()42 RectT() 43 { 44 data_[0] = 0; 45 data_[1] = 0; 46 data_[2] = 0; 47 data_[3] = 0; 48 } RectT(T left,T top,T width,T height)49 RectT(T left, T top, T width, T height) 50 { 51 data_[0] = left; 52 data_[1] = top; 53 data_[2] = width; 54 data_[3] = height; 55 } RectT(Vector4<T> vector)56 RectT(Vector4<T> vector) 57 { 58 data_[0] = vector[0]; 59 data_[1] = vector[1]; 60 data_[2] = vector[2]; 61 data_[3] = vector[3]; 62 } RectT(const T * v)63 explicit RectT(const T* v) 64 { 65 data_[0] = v[0]; 66 data_[1] = v[1]; 67 data_[2] = v[2]; 68 data_[3] = v[3]; 69 } 70 ~RectT() = default; 71 72 inline bool operator==(const RectT<T>& rect) const 73 { 74 return ROSEN_EQ<T>(left_, rect.left_) && ROSEN_EQ<T>(top_, rect.top_) && 75 ROSEN_EQ<T>(width_, rect.width_) && ROSEN_EQ<T>(height_, rect.height_); 76 } 77 78 inline bool operator!=(const RectT<T>& rect) const 79 { 80 return !operator==(rect); 81 } 82 83 inline RectT& operator=(const RectT& other) 84 { 85 const T* oData = other.data_; 86 data_[0] = oData[0]; 87 data_[1] = oData[1]; 88 data_[2] = oData[2]; 89 data_[3] = oData[3]; 90 return *this; 91 } SetAll(T left,T top,T width,T height)92 void SetAll(T left, T top, T width, T height) 93 { 94 data_[0] = left; 95 data_[1] = top; 96 data_[2] = width; 97 data_[3] = height; 98 } GetRight()99 T GetRight() const 100 { 101 return left_ + width_; 102 } GetLeft()103 T GetLeft() const 104 { 105 return left_; 106 } GetBottom()107 T GetBottom() const 108 { 109 return top_ + height_; 110 } GetTop()111 T GetTop() const 112 { 113 return top_; 114 } GetWidth()115 T GetWidth() const 116 { 117 return width_; 118 } GetHeight()119 T GetHeight() const 120 { 121 return height_; 122 } SetRight(T right)123 void SetRight(T right) 124 { 125 width_ = right - left_; 126 } SetBottom(T bottom)127 void SetBottom(T bottom) 128 { 129 height_ = bottom - top_; 130 } Move(T x,T y)131 void Move(T x, T y) 132 { 133 left_ += x; 134 top_ += y; 135 } Clear()136 void Clear() 137 { 138 left_ = 0; 139 top_ = 0; 140 width_ = 0; 141 height_ = 0; 142 } IsEmpty()143 bool IsEmpty() const 144 { 145 return width_ <= 0 || height_ <= 0; 146 } Intersect(T x,T y)147 bool Intersect(T x, T y) const 148 { 149 return (x >= left_) && (x < GetRight()) && (y >= top_) && (y < GetBottom()); 150 } IsInsideOf(const RectT<T> & rect)151 bool IsInsideOf(const RectT<T>& rect) const 152 { 153 return (top_ >= rect.top_ && left_ >= rect.left_ && 154 GetBottom() <= rect.GetBottom() && GetRight() <= rect.GetRight()); 155 } IntersectRect(const RectT<T> & rect)156 RectT<T> IntersectRect(const RectT<T>& rect) const 157 { 158 T left = std::max(left_, rect.left_); 159 T top = std::max(top_, rect.top_); 160 T width = std::min(GetRight(), rect.GetRight()) - left; 161 T height = std::min(GetBottom(), rect.GetBottom()) - top; 162 return ((width <= 0) || (height <= 0)) ? RectT<T>() : RectT<T>(left, top, width, height); 163 } JoinRect(const RectT<T> & rect)164 RectT<T> JoinRect(const RectT<T>& rect) const 165 { 166 if (rect.IsEmpty()) { 167 return RectT<T>(left_, top_, width_, height_); 168 } 169 if (IsEmpty()) { 170 return rect; 171 } 172 T left = std::min(left_, rect.left_); 173 T top = std::min(top_, rect.top_); 174 T width = std::max(GetRight(), rect.GetRight()) - left; 175 T height = std::max(GetBottom(), rect.GetBottom()) - top; 176 return ((width <= 0) || (height <= 0)) ? RectT<T>() : RectT<T>(left, top, width, height); 177 } Offset(const T x,const T y)178 RectT<T> Offset(const T x, const T y) const 179 { 180 return RectT<T>(left_ + x, top_ + y, width_, height_); 181 } 182 template<typename P> ConvertTo()183 RectT<P> ConvertTo() 184 { 185 return RectT<P>(static_cast<P>(left_), static_cast<P>(top_), static_cast<P>(width_), static_cast<P>(height_)); 186 } ToString()187 std::string ToString() const 188 { 189 return std::string("(") + std::to_string(left_) + ", " + std::to_string(top_) + ", " + 190 std::to_string(width_) + ", " + std::to_string(height_) + ")"; 191 } 192 193 #ifdef ROSEN_OHOS Marshalling(Parcel & parcel)194 bool Marshalling(Parcel& parcel) const 195 { 196 if (!(RSMarshallingHelper::Marshalling(parcel, left_) && 197 RSMarshallingHelper::Marshalling(parcel, top_) && 198 RSMarshallingHelper::Marshalling(parcel, width_) && 199 RSMarshallingHelper::Marshalling(parcel, height_))) { 200 ROSEN_LOGE("RectT::Marshalling failed!"); 201 return false; 202 } 203 return true; 204 } 205 Unmarshalling(Parcel & parcel)206 [[nodiscard]] static RectT<T>* Unmarshalling(Parcel& parcel) 207 { 208 auto rect = std::make_unique<RectT<T>>(); 209 if (!(RSMarshallingHelper::Unmarshalling(parcel, rect->left_) && 210 RSMarshallingHelper::Unmarshalling(parcel, rect->top_) && 211 RSMarshallingHelper::Unmarshalling(parcel, rect->width_) && 212 RSMarshallingHelper::Unmarshalling(parcel, rect->height_))) { 213 ROSEN_LOGE("RectT::Unmarshalling failed!"); 214 return nullptr; 215 } 216 return rect.release(); 217 } 218 #endif 219 }; 220 221 typedef RectT<int> RectI; 222 typedef RectT<float> RectF; 223 224 /* 225 RectIComparator: Used for comparing rects 226 RectI_Hash_Func: provide hash value for rect comparing 227 */ 228 struct RectIComparator { operatorRectIComparator229 bool operator()(const RectI& r1, const RectI& r2) const 230 { 231 return r2.IsInsideOf(r1); 232 } 233 }; 234 235 struct RectI_Hash_Func { operatorRectI_Hash_Func236 size_t operator()(const RectI& _r) const 237 { 238 // this is set for all rects can be compared 239 int hash_value = 0; 240 return std::hash<int>()(hash_value); 241 } 242 }; 243 244 typedef std::unordered_set<RectI, RectI_Hash_Func, RectIComparator> OcclusionRectISet; 245 246 template<typename T> 247 class RRectT { 248 public: 249 RectT<T> rect_ = RectT<T>(); 250 Vector2f radius_[4] = { { 0, 0 } }; 251 RRectT()252 RRectT() {} 253 ~RRectT() = default; 254 RRectT(RectT<T> rect,float rx,float ry)255 RRectT(RectT<T> rect, float rx, float ry) 256 { 257 rect_ = rect; 258 Vector2f vec = Vector2f(rx, ry); 259 radius_[0] = vec; 260 radius_[1] = vec; 261 radius_[2] = vec; 262 radius_[3] = vec; 263 } RRectT(RectT<T> rect,const Vector2f * radius)264 RRectT(RectT<T> rect, const Vector2f* radius) 265 { 266 rect_ = rect; 267 radius_[0] = radius[0]; 268 radius_[1] = radius[1]; 269 radius_[2] = radius[2]; 270 radius_[3] = radius[3]; 271 } RRectT(RectT<T> rect,const Vector4f & radius)272 RRectT(RectT<T> rect, const Vector4f& radius) 273 { 274 rect_ = rect; 275 radius_[0] = { radius[0], radius[0] }; 276 radius_[1] = { radius[1], radius[1] }; 277 radius_[2] = { radius[2], radius[2] }; 278 radius_[3] = { radius[3], radius[3] }; 279 } 280 SetValues(RectT<T> rect,const Vector2f * radius)281 void SetValues(RectT<T> rect, const Vector2f* radius) 282 { 283 rect_ = rect; 284 radius_[0] = radius[0]; 285 radius_[1] = radius[1]; 286 radius_[2] = radius[2]; 287 radius_[3] = radius[3]; 288 } 289 290 RRectT operator-(const RRectT<T>& other) const; 291 RRectT operator+(const RRectT<T>& other) const; 292 RRectT operator/(float scale) const; 293 RRectT operator*(float scale) const; 294 RRectT& operator-=(const RRectT<T>& other); 295 RRectT& operator+=(const RRectT<T>& other); 296 RRectT& operator*=(float scale); 297 RRectT& operator=(const RRectT<T>& other); 298 bool operator==(const RRectT& other) const; 299 bool operator!=(const RRectT& other) const; 300 }; 301 302 typedef RRectT<float> RRect; 303 304 template<typename T> 305 RRectT<T> RRectT<T>::operator-(const RRectT<T>& other) const 306 { 307 RRectT<T> rrect; 308 rrect.rect_.SetAll(rect_.GetLeft() - other.rect_.GetLeft(), rect_.GetTop() - other.rect_.GetTop(), 309 rect_.GetWidth() - other.rect_.GetWidth(), rect_.GetHeight() - other.rect_.GetHeight()); 310 for (int index = 0; index < 4; index++) { 311 rrect.radius_[index] = radius_[index] - other.radius_[index]; 312 } 313 return rrect; 314 } 315 316 template<typename T> 317 RRectT<T> RRectT<T>::operator+(const RRectT<T>& other) const 318 { 319 RRectT<T> rrect; 320 rrect.rect_.SetAll(rect_.GetLeft() + other.rect_.GetLeft(), rect_.GetTop() + other.rect_.GetTop(), 321 rect_.GetWidth() + other.rect_.GetWidth(), rect_.GetHeight() + other.rect_.GetHeight()); 322 for (int index = 0; index < 4; index++) { 323 rrect.radius_[index] = radius_[index] + other.radius_[index]; 324 } 325 return rrect; 326 } 327 328 template<typename T> 329 RRectT<T> RRectT<T>::operator/(float scale) const 330 { 331 if (ROSEN_EQ<float>(scale, 0)) { 332 return *this; 333 } 334 RRectT<T> rrect; 335 rrect.rect_.SetAll(rect_.GetLeft() / scale, rect_.GetTop() / scale, 336 rect_.GetWidth() / scale, rect_.GetHeight() / scale); 337 for (int index = 0; index < 4; index++) { 338 rrect.radius_[index] = radius_[index] / scale; 339 } 340 return rrect; 341 } 342 343 template<typename T> 344 RRectT<T> RRectT<T>::operator*(float scale) const 345 { 346 RRectT<T> rrect; 347 rrect.rect_.SetAll(rect_.GetLeft() * scale, rect_.GetTop() * scale, 348 rect_.GetWidth() * scale, rect_.GetHeight() * scale); 349 for (int index = 0; index < 4; index++) { 350 rrect.radius_[index] = radius_[index] * scale; 351 } 352 return rrect; 353 } 354 355 template<typename T> 356 RRectT<T>& RRectT<T>::operator-=(const RRectT<T>& other) 357 { 358 rect_.SetAll(rect_.GetLeft() - other.rect_.GetLeft(), rect_.GetTop() - other.rect_.GetTop(), 359 rect_.GetWidth() - other.rect_.GetWidth(), rect_.GetHeight() - other.rect_.GetHeight()); 360 for (int index = 0; index < 4; index++) { 361 radius_[index] = radius_[index] - other.radius_[index]; 362 } 363 return *this; 364 } 365 366 template<typename T> 367 RRectT<T>& RRectT<T>::operator+=(const RRectT<T>& other) 368 { 369 rect_.SetAll(rect_.GetLeft() + other.rect_.GetLeft(), rect_.GetTop() + other.rect_.GetTop(), 370 rect_.GetWidth() + other.rect_.GetWidth(), rect_.GetHeight() + other.rect_.GetHeight()); 371 for (int index = 0; index < 4; index++) { 372 radius_[index] = radius_[index] + other.radius_[index]; 373 } 374 return *this; 375 } 376 377 template<typename T> 378 RRectT<T>& RRectT<T>::operator*=(float scale) 379 { 380 rect_.SetAll(rect_.GetLeft() * scale, rect_.GetTop() * scale, 381 rect_.GetWidth() * scale, rect_.GetHeight() * scale); 382 for (int index = 0; index < 4; index++) { 383 radius_[index] = radius_[index] * scale; 384 } 385 return *this; 386 } 387 388 template<typename T> 389 RRectT<T>& RRectT<T>::operator=(const RRectT<T>& other) 390 { 391 rect_ = other.rect_; 392 for (int index = 0; index < 4; index++) { 393 radius_[index] = other.radius_[index]; 394 } 395 return *this; 396 } 397 398 template<typename T> 399 inline bool RRectT<T>::operator==(const RRectT& other) const 400 { 401 return (rect_ == other.rect_) && (radius_[0] == other.radius_[0]) && 402 (radius_[1] == other.radius_[1]) && (radius_[2] == other.radius_[2]) && 403 (radius_[3] == other.radius_[3]); 404 } 405 406 template<typename T> 407 inline bool RRectT<T>::operator!=(const RRectT& other) const 408 { 409 return !operator==(other); 410 } 411 } // namespace Rosen 412 } // namespace OHOS 413 #endif 414