1 /* 2 * Copyright (c) 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 FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SHAPE_RECT_PAINT_PROPERTY_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SHAPE_RECT_PAINT_PROPERTY_H 18 19 #include <vector> 20 #include "base/geometry/dimension.h" 21 #include "base/geometry/ng/radius.h" 22 #include "base/log/log_wrapper.h" 23 #include "core/components_ng/base/inspector_filter.h" 24 #include "core/components_ng/layout/layout_property.h" 25 #include "core/components_ng/pattern/shape/shape_paint_property.h" 26 #include "core/components_ng/property/property.h" 27 #include "core/components_ng/render/paint_property.h" 28 29 namespace OHOS::Ace::NG { 30 namespace { 31 // Dimension(0) will update radius, but Dimension(-1) will not. 32 const Dimension DEFAULT_RADIUS_VALUE(0, DimensionUnit::PX); 33 const Dimension DEFAULT_RADIUS_INVALID(-1, DimensionUnit::PX); 34 } // namespace 35 class ACE_EXPORT RectPaintProperty : public ShapePaintProperty { 36 DECLARE_ACE_TYPE(RectPaintProperty, ShapePaintProperty); 37 38 public: 39 RectPaintProperty() = default; 40 ~RectPaintProperty() override = default; Clone()41 RefPtr<PaintProperty> Clone() const override 42 { 43 auto value = MakeRefPtr<RectPaintProperty>(); 44 value->PaintProperty::UpdatePaintProperty(DynamicCast<PaintProperty>(this)); 45 value->propTopLeftRadius_ = CloneTopLeftRadius(); 46 value->propTopRightRadius_ = CloneTopRightRadius(); 47 value->propBottomLeftRadius_ = CloneBottomLeftRadius(); 48 value->propBottomRightRadius_ = CloneBottomRightRadius(); 49 value->propFill_ = CloneFill(); 50 value->propFillOpacity_ = CloneFillOpacity(); 51 value->propStroke_ = CloneStroke(); 52 value->propStrokeWidth_ = CloneStrokeWidth(); 53 value->propStrokeOpacity_ = CloneStrokeOpacity(); 54 value->propStrokeDashArray_ = CloneStrokeDashArray(); 55 value->propStrokeDashOffset_ = CloneStrokeDashOffset(); 56 value->propStrokeLineCap_ = CloneStrokeLineCap(); 57 value->propStrokeLineJoin_ = CloneStrokeLineJoin(); 58 value->propStrokeMiterLimit_ = CloneStrokeMiterLimit(); 59 value->propAntiAlias_ = CloneAntiAlias(); 60 value->SetContentOffset(contentOffset_); 61 value->SetContentSize(contentSize_); 62 return value; 63 } 64 Reset()65 void Reset() override 66 { 67 ShapePaintProperty::Reset(); 68 ResetBottomLeftRadius(); 69 ResetBottomRightRadius(); 70 ResetTopLeftRadius(); 71 ResetTopRightRadius(); 72 } 73 ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)74 void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override 75 { 76 ShapePaintProperty::ToJsonValue(json, filter); 77 /* no fixed attr below, just return */ 78 if (filter.IsFastFilter()) { 79 return; 80 } 81 if (!propTopLeftRadius_.has_value() || !propTopRightRadius_.has_value() || !propBottomLeftRadius_.has_value() || 82 !propBottomRightRadius_.has_value()) { 83 return; 84 } 85 std::vector<std::vector<double>> radiusArray(4); 86 radiusArray[0] = { propTopLeftRadius_.value().GetX().ConvertToPx(), 87 propTopLeftRadius_.value().GetY().ConvertToPx() }; 88 radiusArray[1] = { propTopRightRadius_.value().GetX().ConvertToPx(), 89 propTopRightRadius_.value().GetY().ConvertToPx() }; 90 radiusArray[2] = { propBottomRightRadius_.value().GetX().ConvertToPx(), 91 propBottomRightRadius_.value().GetY().ConvertToPx() }; 92 radiusArray[3] = { propBottomLeftRadius_.value().GetX().ConvertToPx(), 93 propBottomLeftRadius_.value().GetY().ConvertToPx() }; 94 json->PutExtAttr("radius", radiusArray.data(), filter); 95 if (radiusArray[0][0] == radiusArray[1][0] && 96 radiusArray[0][0] == radiusArray[2][0] && 97 radiusArray[0][0] == radiusArray[3][0]) { 98 json->PutExtAttr("radiusWidth", radiusArray[0][0], filter); 99 } else { 100 json->PutExtAttr("radiusWidth", 0, filter); 101 } 102 if (radiusArray[0][1] == radiusArray[1][1] && 103 radiusArray[0][1] == radiusArray[2][1] && 104 radiusArray[0][1] == radiusArray[3][1]) { 105 json->PutExtAttr("radiusHeight", radiusArray[0][1], filter); 106 } else { 107 json->PutExtAttr("radiusHeight", 0, filter); 108 } 109 } 110 GetTopLeftRadius()111 const std::optional<Radius>& GetTopLeftRadius() 112 { 113 return propTopLeftRadius_; 114 } HasTopLeftRadius()115 bool HasTopLeftRadius() const 116 { 117 return propTopLeftRadius_.has_value(); 118 } GetTopLeftRadiusValue()119 const Radius& GetTopLeftRadiusValue() const 120 { 121 return propTopLeftRadius_.value(); 122 } CloneTopLeftRadius()123 const std::optional<Radius>& CloneTopLeftRadius() const 124 { 125 return propTopLeftRadius_; 126 } ResetTopLeftRadius()127 void ResetTopLeftRadius() 128 { 129 return propTopLeftRadius_.reset(); 130 } 131 UpdateTopLeftRadius(const Radius & value)132 void UpdateTopLeftRadius(const Radius& value) 133 { 134 UpdateRadius(propTopLeftRadius_, value); 135 } 136 GetTopRightRadius()137 const std::optional<Radius>& GetTopRightRadius() 138 { 139 return propTopRightRadius_; 140 } HasTopRightRadius()141 bool HasTopRightRadius() const 142 { 143 return propTopRightRadius_.has_value(); 144 } GetTopRightRadiusValue()145 const Radius& GetTopRightRadiusValue() const 146 { 147 return propTopRightRadius_.value(); 148 } CloneTopRightRadius()149 const std::optional<Radius>& CloneTopRightRadius() const 150 { 151 return propTopRightRadius_; 152 } ResetTopRightRadius()153 void ResetTopRightRadius() 154 { 155 return propTopRightRadius_.reset(); 156 } 157 UpdateTopRightRadius(const Radius & value)158 void UpdateTopRightRadius(const Radius& value) 159 { 160 UpdateRadius(propTopRightRadius_, value); 161 } 162 GetBottomRightRadius()163 const std::optional<Radius>& GetBottomRightRadius() 164 { 165 return propBottomRightRadius_; 166 } HasBottomRightRadius()167 bool HasBottomRightRadius() const 168 { 169 return propBottomRightRadius_.has_value(); 170 } GetBottomRightRadiusValue()171 const Radius& GetBottomRightRadiusValue() const 172 { 173 return propBottomRightRadius_.value(); 174 } CloneBottomRightRadius()175 const std::optional<Radius>& CloneBottomRightRadius() const 176 { 177 return propBottomRightRadius_; 178 } ResetBottomRightRadius()179 void ResetBottomRightRadius() 180 { 181 return propBottomRightRadius_.reset(); 182 } 183 UpdateBottomRightRadius(const Radius & value)184 void UpdateBottomRightRadius(const Radius& value) 185 { 186 UpdateRadius(propBottomRightRadius_, value); 187 } 188 GetBottomLeftRadius()189 const std::optional<Radius>& GetBottomLeftRadius() 190 { 191 return propBottomLeftRadius_; 192 } HasBottomLeftRadius()193 bool HasBottomLeftRadius() const 194 { 195 return propBottomLeftRadius_.has_value(); 196 } GetBottomLeftRadiusValue()197 const Radius& GetBottomLeftRadiusValue() const 198 { 199 return propBottomLeftRadius_.value(); 200 } CloneBottomLeftRadius()201 const std::optional<Radius>& CloneBottomLeftRadius() const 202 { 203 return propBottomLeftRadius_; 204 } ResetBottomLeftRadius()205 void ResetBottomLeftRadius() 206 { 207 return propBottomLeftRadius_.reset(); 208 } UpdateBottomLeftRadius(const Radius & value)209 void UpdateBottomLeftRadius(const Radius& value) 210 { 211 UpdateRadius(propBottomLeftRadius_, value); 212 } 213 UpdateRadius(std::optional<Radius> & radiusOpt,const Radius & value)214 void UpdateRadius(std ::optional<Radius>& radiusOpt, const Radius& value) 215 { 216 // Dimension(0) is a valid value in radius. 217 if (!value.GetX().IsNonNegative() && !value.GetY().IsNonNegative()) { 218 return; 219 } 220 bool update = false; 221 if (!radiusOpt.has_value()) { 222 radiusOpt = value; // value 223 update = true; 224 } else { 225 if (value.GetX().IsNonNegative() && !NearEqual(radiusOpt.value_or(Radius()).GetX(), value.GetX())) { 226 radiusOpt->SetX(value.GetX()); 227 update = true; 228 } 229 if (value.GetY().IsNonNegative() && !NearEqual(radiusOpt.value_or(Radius()).GetY(), value.GetY())) { 230 radiusOpt->SetY(value.GetY()); 231 update = true; 232 } 233 } 234 if (update) { 235 UpdatePropertyChangeFlag(PROPERTY_UPDATE_RENDER); 236 } 237 } 238 GetContentOffset()239 OffsetF GetContentOffset() 240 { 241 return contentOffset_; 242 } 243 GetContentSize()244 SizeF GetContentSize() 245 { 246 return contentSize_; 247 } 248 SetContentOffset(const OffsetF & contentOffset)249 void SetContentOffset(const OffsetF& contentOffset) 250 { 251 contentOffset_.SetX(contentOffset.GetX()); 252 contentOffset_.SetY(contentOffset.GetY()); 253 } 254 SetContentSize(const SizeF & contentSize)255 void SetContentSize(const SizeF& contentSize) 256 { 257 contentSize_.SetSizeT(contentSize); 258 } 259 260 private: 261 std::optional<Radius> propTopLeftRadius_; 262 std::optional<Radius> propTopRightRadius_; 263 std::optional<Radius> propBottomLeftRadius_; 264 std::optional<Radius> propBottomRightRadius_; 265 SizeF contentSize_; 266 OffsetF contentOffset_; 267 268 ACE_DISALLOW_COPY_AND_MOVE(RectPaintProperty); 269 }; 270 271 } // namespace OHOS::Ace::NG 272 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SHAPE_RECT_PAINT_PROPERTY_H 273