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_SVG_PARSE_SVG_GRAPHIC_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SVG_PARSE_SVG_GRAPHIC_H 18 19 #include "include/core/SkMaskFilter.h" 20 21 #include "base/utils/utils.h" 22 #include "core/components/common/properties/decoration.h" 23 #include "core/components_ng/render/drawing_forward.h" 24 #ifndef USE_ROSEN_DRAWING 25 #include "include/core/SkPaint.h" 26 #else 27 #include "core/components_ng/render/drawing.h" 28 #endif 29 30 #include "frameworks/core/components_ng/svg/parse/svg_node.h" 31 32 namespace OHOS::Ace::NG { 33 34 class SvgGraphic : public SvgNode { 35 DECLARE_ACE_TYPE(SvgGraphic, SvgNode); 36 37 public: SvgGraphic()38 SvgGraphic() : SvgNode() 39 { 40 InitGraphicFlag(); 41 } 42 ~SvgGraphic() override = default; 43 44 void OnDraw(RSCanvas& canvas, const Size& layout, const std::optional<Color>& color) override; 45 protected: OnGraphicFill()46 void OnGraphicFill() 47 { 48 #ifndef USE_ROSEN_DRAWING 49 if (skCanvas_) { 50 auto smoothEdge = GetSmoothEdge(); 51 if (GreatNotEqual(smoothEdge, 0.0f)) { 52 auto filter = SkMaskFilter::MakeBlur(SkBlurStyle::kNormal_SkBlurStyle, smoothEdge, false); 53 auto tmpFillPaint = fillPaint_; 54 tmpFillPaint.setMaskFilter(filter); 55 skCanvas_->drawPath(path_, tmpFillPaint); 56 tmpFillPaint.setMaskFilter(nullptr); 57 } else { 58 skCanvas_->drawPath(path_, fillPaint_); 59 } 60 } 61 #else 62 if (rsCanvas_) { 63 auto smoothEdge = GetSmoothEdge(); 64 if (SystemProperties::GetDebugEnabled()) { 65 TAG_LOGD(AceLogTag::ACE_IMAGE, "svg path:%{public}s, smoothEdge = %{public}f", 66 path_.ConvertToSVGString().c_str(), smoothEdge); 67 } 68 if (!path_.IsValid()) { 69 TAG_LOGW(AceLogTag::ACE_IMAGE, "svg path is invalid"); 70 } 71 if (GreatNotEqual(smoothEdge, 0.0f)) { 72 RSFilter filter; 73 filter.SetMaskFilter(RSMaskFilter::CreateBlurMaskFilter( 74 RSBlurType::NORMAL, static_cast<double>(smoothEdge), false 75 )); 76 auto tmpFillBrush = fillBrush_; 77 tmpFillBrush.SetFilter(filter); 78 rsCanvas_->AttachBrush(tmpFillBrush); 79 rsCanvas_->DrawPath(path_); 80 rsCanvas_->DetachBrush(); 81 } else { 82 rsCanvas_->AttachBrush(fillBrush_); 83 rsCanvas_->DrawPath(path_); 84 rsCanvas_->DetachBrush(); 85 } 86 } 87 #endif 88 } 89 OnGraphicStroke()90 void OnGraphicStroke() 91 { 92 #ifndef USE_ROSEN_DRAWING 93 if (skCanvas_) { 94 auto smoothEdge = GetSmoothEdge(); 95 if (GreatNotEqual(smoothEdge, 0.0f)) { 96 auto filter = SkMaskFilter::MakeBlur(SkBlurStyle::kNormal_SkBlurStyle, smoothEdge, false); 97 auto tmpStrokePaint = strokePaint_; 98 tmpStrokePaint.setMaskFilter(filter); 99 skCanvas_->drawPath(path_, tmpStrokePaint); 100 tmpStrokePaint.setMaskFilter(nullptr); 101 } else { 102 skCanvas_->drawPath(path_, strokePaint_); 103 } 104 } 105 #else 106 if (rsCanvas_) { 107 auto smoothEdge = GetSmoothEdge(); 108 if (SystemProperties::GetDebugEnabled()) { 109 TAG_LOGD(AceLogTag::ACE_IMAGE, "svg path:%{public}s, smoothEdge = %{public}f", 110 path_.ConvertToSVGString().c_str(), smoothEdge); 111 } 112 if (!path_.IsValid()) { 113 TAG_LOGW(AceLogTag::ACE_IMAGE, "svg path is invalid"); 114 } 115 if (GreatNotEqual(smoothEdge, 0.0f)) { 116 RSFilter filter; 117 filter.SetMaskFilter(RSMaskFilter::CreateBlurMaskFilter( 118 RSBlurType::NORMAL, static_cast<double>(smoothEdge), false 119 )); 120 auto tmpStrokePen = strokePen_; 121 tmpStrokePen.SetFilter(filter); 122 rsCanvas_->AttachPen(tmpStrokePen); 123 rsCanvas_->DrawPath(path_); 124 rsCanvas_->DetachPen(); 125 } else { 126 rsCanvas_->AttachPen(strokePen_); 127 rsCanvas_->DrawPath(path_); 128 rsCanvas_->DetachPen(); 129 } 130 } 131 #endif 132 } 133 134 // rect line polygon path circle ellipse InitGraphicFlag()135 void InitGraphicFlag() 136 { 137 hrefFill_ = true; 138 hrefRender_ = true; 139 passStyle_ = false; 140 inheritStyle_ = true; 141 drawTraversed_ = true; 142 } 143 144 // Update fillStates & strokeStates 145 void UpdateFillGradient(const Size& viewPort); 146 void UpdateStrokeGradient(const Size& viewPort); 147 bool UpdateFillStyle(const std::optional<Color>& color, bool antiAlias = true); 148 bool UpdateStrokeStyle(bool antiAlias = true); 149 void SetStrokeGradientStyle(double opacity); 150 bool SetGradientStyle(double opacity); 151 void UpdateLineDash(); 152 void SetLinearGradient(const Size& viewPort, Gradient& gradient); 153 void SetRadialGradient(const Size& viewPort, Gradient& gradient); 154 155 #ifndef USE_ROSEN_DRAWING 156 SkPath path_; 157 SkPaint fillPaint_; 158 SkPaint strokePaint_; 159 #else 160 RSRecordingPath path_; 161 RSBrush fillBrush_; 162 RSPen strokePen_; 163 #endif 164 FillState fillState_; 165 166 private: 167 void UpdateColorFilter(RSFilter& filter); 168 }; 169 170 } // namespace OHOS::Ace::NG 171 172 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_SVG_PARSE_SVG_GRAPHIC_H