• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_RENDER_OVERLAY_MODIFIER_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_OVERLAY_MODIFIER_H
18 
19 #include <memory>
20 #include <string>
21 
22 #include "modifier/rs_animatable_arithmetic.h"
23 #include "render_service_client/core/modifier/rs_property.h"
24 #include "render_service_client/core/modifier_ng/overlay/rs_overlay_style_modifier.h"
25 
26 #include "base/geometry/ng/offset_t.h"
27 #include "base/i18n/localization.h"
28 #include "base/memory/referenced.h"
29 #include "core/common/font_manager.h"
30 #include "core/components/common/properties/alignment.h"
31 #include "core/components_ng/property/overlay_property.h"
32 #include "core/components_ng/render/drawing.h"
33 #include "core/components_ng/render/drawing_prop_convertor.h"
34 #include "core/components_ng/render/font_collection.h"
35 #include "core/pipeline/pipeline_base.h"
36 
37 namespace OHOS::Ace::NG {
38 
39 class OverlayTextData : public Rosen::RSArithmetic<OverlayTextData> {
40 public:
41     OverlayTextData() = default;
OverlayTextData(const OverlayOptions & overlay)42     explicit OverlayTextData(const OverlayOptions& overlay) : overlay_(overlay) {}
43     ~OverlayTextData() override = default;
44 
IsEqual(const OverlayTextData & other)45     bool IsEqual(const OverlayTextData& other) const override
46     {
47         return overlay_ == other.overlay_;
48     }
49 
GetOverlayOptions()50     OverlayOptions GetOverlayOptions()
51     {
52         return overlay_;
53     }
54 
55 private:
56     OverlayOptions overlay_;
57 };
58 
59 using RSOverlayStyleModifier = Rosen::ModifierNG::RSOverlayStyleModifier;
60 using RSDrawingContext = Rosen::ModifierNG::RSDrawingContext;
61 
62 class OverlayTextModifier : public RSOverlayStyleModifier {
63 public:
64     OverlayTextModifier() = default;
65     ~OverlayTextModifier() override = default;
66 
Draw(RSDrawingContext & context)67     void Draw(RSDrawingContext& context) const override
68     {
69         CHECK_NULL_VOID(property_);
70         auto overlayOptions = property_->Get().GetOverlayOptions();
71         auto paragraph = GetParagraph(context.width);
72         CHECK_NULL_VOID(paragraph);
73         OffsetF offset = OverlayTextModifier::GetTextPosition(SizeF(context.width, context.height),
74             SizeF(static_cast<float>(paragraph->GetActualWidth()), static_cast<float>(paragraph->GetHeight())),
75             overlayOptions);
76 #ifndef USE_ROSEN_DRAWING
77         std::shared_ptr<SkCanvas> skCanvas { context.canvas, [](SkCanvas*) {} };
78         RSCanvas canvas(&skCanvas);
79         CHECK_NULL_VOID(&canvas);
80         paragraph->Paint(&canvas, offset.GetX(), offset.GetY());
81 #else
82         CHECK_NULL_VOID(context.canvas);
83         paragraph->Paint(context.canvas, offset.GetX(), offset.GetY());
84 #endif
85     }
86 
GetParagraph(double contextWidth)87     std::unique_ptr<Rosen::Typography> GetParagraph(double contextWidth) const
88     {
89         CHECK_NULL_RETURN(property_, nullptr);
90         const Dimension fontSize = Dimension(40);
91         auto overlayOptions = property_->Get().GetOverlayOptions();
92         // create paragraph
93         TextStyle textStyle;
94         textStyle.SetFontSize(fontSize);
95         RSParagraphStyle paraStyle;
96         paraStyle.textAlign = ToRSTextAlign(textStyle.GetTextAlign());
97         paraStyle.maxLines = textStyle.GetMaxLines();
98         paraStyle.locale = Localization::GetInstance()->GetFontLocale();
99         paraStyle.wordBreakType = ToRSWordBreakType(textStyle.GetWordBreak());
100         paraStyle.fontSize = fontSize.Value();
101         auto builder = RSParagraphBuilder::Create(paraStyle, RSFontCollection::Create());
102         CHECK_NULL_RETURN(builder, nullptr);
103         auto pipelineContext = PipelineBase::GetCurrentContext();
104         CHECK_NULL_RETURN(pipelineContext, nullptr);
105         builder->PushStyle(ToRSTextStyle(pipelineContext, textStyle));
106         builder->AppendText(StringUtils::Str8ToStr16(overlayOptions.content));
107         builder->PopStyle();
108         auto paragraph = builder->CreateTypography();
109         CHECK_NULL_RETURN(paragraph, nullptr);
110         paragraph->Layout(contextWidth);
111         return paragraph;
112     }
113 
GetParagraphSize(double contextWidth)114     SizeF GetParagraphSize(double contextWidth) const
115     {
116         auto paragraph = GetParagraph(contextWidth);
117         CHECK_NULL_RETURN(paragraph, SizeF());
118         return SizeF(static_cast<float>(paragraph->GetActualWidth()), static_cast<float>(paragraph->GetHeight()));
119     }
120 
SetCustomData(const OverlayTextData & data)121     void SetCustomData(const OverlayTextData& data)
122     {
123         if (!property_) {
124             property_ = std::make_shared<Rosen::RSProperty<OverlayTextData>>(data);
125             AttachProperty(property_);
126         } else {
127             property_->Set(data);
128         }
129     }
130 
GetOverlayOffset()131     OffsetF GetOverlayOffset()
132     {
133         OffsetF overlayOffset;
134         if (property_) {
135             auto overlayOptions = property_->Get().GetOverlayOptions();
136             auto dx = overlayOptions.x.ConvertToPx();
137             auto dy = overlayOptions.y.ConvertToPx();
138             overlayOffset = OffsetF(dx, dy);
139         }
140         return overlayOffset;
141     }
142 
IsCustomFont()143     bool IsCustomFont()
144     {
145         auto pipelineContext = PipelineBase::GetCurrentContext();
146         CHECK_NULL_RETURN(pipelineContext, false);
147         auto fontManager = pipelineContext->GetFontManager();
148         CHECK_NULL_RETURN(fontManager, false);
149         return fontManager->IsDefaultFontChanged();
150     }
151 
152 private:
GetTextPosition(const SizeF & parentSize,const SizeF & childSize,OverlayOptions & overlay)153     static OffsetF GetTextPosition(const SizeF& parentSize, const SizeF& childSize, OverlayOptions& overlay)
154     {
155         const double dx = overlay.x.ConvertToPx();
156         const double dy = overlay.y.ConvertToPx();
157         const Alignment align = overlay.align;
158         OffsetF const offset = Alignment::GetAlignPosition(parentSize, childSize, align);
159         const float fx = static_cast<float>(dx) + offset.GetX();
160         const float fy = static_cast<float>(dy) + offset.GetY();
161         return { fx, fy };
162     }
163 
164     std::shared_ptr<Rosen::RSProperty<OverlayTextData>> property_;
165 };
166 } // namespace OHOS::Ace::NG
167 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_OVERLAY_MODIFIER_H
168