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 #ifndef FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_RRECT_H 17 #define FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_RRECT_H 18 19 #include <algorithm> 20 #include <cstdint> 21 #include <cstring> 22 23 #include "base/geometry/rect.h" 24 #include "core/components/common/properties/radius.h" 25 26 namespace OHOS::Ace { 27 28 struct Corner { 29 Radius topLeftRadius; 30 Radius topRightRadius; 31 Radius bottomRightRadius; 32 Radius bottomLeftRadius; 33 }; 34 35 class RRect final { 36 public: 37 RRect() = default; 38 ~RRect() = default; 39 RRect(const Rect & rect)40 explicit RRect(const Rect& rect) : rect_(rect) {} RRect(double x,double y,double width,double height)41 RRect(double x, double y, double width, double height) 42 { 43 rect_.SetRect(x, y, width, height); 44 } 45 MakeRect(const Rect & rect)46 static RRect MakeRect(const Rect& rect) 47 { 48 RRect rrect; 49 rrect.SetRect(rect); 50 return rrect; 51 } 52 MakeRRect(const Rect & rect,const Radius & radius)53 static RRect MakeRRect(const Rect& rect, const Radius& radius) 54 { 55 RRect rrect; 56 rrect.SetRectWithSimpleRadius(rect, radius.GetX().Value(), radius.GetY().Value()); 57 return rrect; 58 } 59 MakeRRect(const Rect & rect,double x,double y)60 static RRect MakeRRect(const Rect& rect, double x, double y) 61 { 62 RRect rrect; 63 rrect.SetRectWithSimpleRadius(rect, x, y); 64 return rrect; 65 } 66 MakeOval(const Rect & rect)67 static RRect MakeOval(const Rect& rect) 68 { 69 RRect rrect; 70 rrect.SetOval(rect); 71 return rrect; 72 } 73 GetRect()74 const Rect& GetRect() const 75 { 76 return rect_; 77 } 78 GetCorner()79 const Corner& GetCorner() const 80 { 81 return corner_; 82 } 83 SetRect(const Rect & rect)84 void SetRect(const Rect& rect) 85 { 86 rect_ = rect; 87 } 88 SetCorner(const Corner & corner)89 void SetCorner(const Corner& corner) 90 { 91 corner_ = corner; 92 } 93 SetRectWithSimpleRadius(const Rect & rect,double xRadius,double yRadius)94 void SetRectWithSimpleRadius(const Rect& rect, double xRadius, double yRadius) 95 { 96 rect_ = rect; 97 if (xRadius <= 0 || yRadius <= 0) { 98 return; 99 } 100 if (rect_.Width() < (xRadius + xRadius) || rect.Height() < (yRadius + yRadius)) { 101 double scale = std::min(rect.Width() / (xRadius + xRadius), rect.Height() / (yRadius + yRadius)); 102 xRadius *= scale; 103 yRadius *= scale; 104 } 105 auto radius = Radius(xRadius, yRadius); 106 corner_ = { radius, radius, radius, radius }; 107 } 108 ApplyScaleAndRound(float scale)109 void ApplyScaleAndRound(float scale) 110 { 111 rect_.ApplyScaleAndRound(Size(scale, scale)); 112 corner_.topLeftRadius.ApplyScaleAndRound(scale); 113 corner_.topRightRadius.ApplyScaleAndRound(scale); 114 corner_.bottomRightRadius.ApplyScaleAndRound(scale); 115 corner_.bottomLeftRadius.ApplyScaleAndRound(scale); 116 } 117 SetOval(const Rect & rect)118 void SetOval(const Rect& rect) 119 { 120 rect_ = rect; 121 double xRadius = rect.Width() / 2; 122 double yRadius = rect.Height() / 2; 123 auto radius = Radius(xRadius, yRadius); 124 corner_ = { radius, radius, radius, radius }; 125 } 126 Width()127 double Width() const 128 { 129 return rect_.Width(); 130 } 131 Height()132 double Height() const 133 { 134 return rect_.Height(); 135 } 136 137 bool operator==(const RRect& rrect) const 138 { 139 return rrect.GetCorner().bottomLeftRadius == corner_.bottomLeftRadius && 140 rrect.GetCorner().bottomRightRadius == corner_.bottomRightRadius && 141 rrect.GetCorner().topLeftRadius == corner_.topLeftRadius && 142 rrect.GetCorner().topRightRadius == corner_.topRightRadius && rrect.GetRect() == rect_; 143 } 144 145 RRect& operator+=(const Offset& offset) 146 { 147 rect_ += offset; 148 return *this; 149 } 150 151 private: 152 Corner corner_ { { 0.0, 0.0 }, { 0.0, 0.0 }, { 0.0, 0.0 }, { 0.0, 0.0 } }; 153 Rect rect_; 154 }; 155 156 } // namespace OHOS::Ace 157 158 #endif // FOUNDATION_ACE_FRAMEWORKS_BASE_GEOMETRY_RRECT_H 159