• 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 #include "core/components_ng/pattern/text/text_paint_method.h"
17 
18 #include "core/components_ng/pattern/text/text_pattern.h"
19 
20 namespace OHOS::Ace::NG {
TextPaintMethod(const WeakPtr<Pattern> & pattern,float baselineOffset,RefPtr<TextContentModifier> textContentModifier,RefPtr<TextOverlayModifier> textOverlayModifier)21 TextPaintMethod::TextPaintMethod(const WeakPtr<Pattern>& pattern, float baselineOffset,
22     RefPtr<TextContentModifier> textContentModifier, RefPtr<TextOverlayModifier> textOverlayModifier)
23     : pattern_(pattern), baselineOffset_(baselineOffset),
24       textContentModifier_(std::move(textContentModifier)), textOverlayModifier_(std::move(textOverlayModifier))
25 {}
26 
GetContentModifier(PaintWrapper * paintWrapper)27 RefPtr<Modifier> TextPaintMethod::GetContentModifier(PaintWrapper* paintWrapper)
28 {
29     return textContentModifier_;
30 }
31 
UpdateContentModifier(PaintWrapper * paintWrapper)32 void TextPaintMethod::UpdateContentModifier(PaintWrapper* paintWrapper)
33 {
34     CHECK_NULL_VOID(paintWrapper);
35     CHECK_NULL_VOID(textContentModifier_);
36 
37     auto textPattern = DynamicCast<TextPattern>(pattern_.Upgrade());
38     CHECK_NULL_VOID(textPattern);
39     auto paragraph = textPattern->GetParagraph();
40     CHECK_NULL_VOID(paragraph);
41 
42     textContentModifier_->SetParagraph(paragraph);
43 
44     SizeF contentSize = paintWrapper->GetContentSize();
45     textContentModifier_->SetContentSize(contentSize);
46     auto offset = paintWrapper->GetContentOffset();
47     textContentModifier_->SetContentOffset(offset);
48     auto paintOffset = offset - OffsetF(0.0, std::min(baselineOffset_, 0.0f));
49     textContentModifier_->SetPrintOffset(paintOffset);
50 
51     auto frameNode = textPattern->GetHost();
52     CHECK_NULL_VOID(frameNode);
53     auto layoutProperty = frameNode->GetLayoutProperty<TextLayoutProperty>();
54     CHECK_NULL_VOID(layoutProperty);
55     auto renderContext = frameNode->GetRenderContext();
56     CHECK_NULL_VOID(renderContext);
57     auto pattern = frameNode->GetPattern<TextPattern>();
58     CHECK_NULL_VOID(pattern);
59 
60     auto textOverflow = layoutProperty->GetTextOverflow();
61     if (textOverflow.has_value() && textOverflow.value() == TextOverflow::MARQUEE) {
62         if (paragraph->GetTextWidth() > paintWrapper->GetContentSize().Width()) {
63             textContentModifier_->StartTextRace();
64         } else {
65             textContentModifier_->StopTextRace();
66         }
67     } else {
68         textContentModifier_->StopTextRace();
69     }
70 
71     auto reasons = renderContext->GetObscured().value_or(std::vector<ObscuredReasons>());
72     textContentModifier_->SetObscured(reasons);
73     auto spanItemChildren = pattern->GetSpanItemChildren();
74     textContentModifier_->SetIfHaveSpanItemChildren(!spanItemChildren.empty());
75     auto wideTextLength = pattern->GetDisplayWideTextLength();
76     std::vector<RectF> drawObscuredRects;
77     if (wideTextLength != 0) {
78         paragraph->GetRectsForRange(0, wideTextLength, drawObscuredRects);
79     }
80     textContentModifier_->SetDrawObscuredRects(drawObscuredRects);
81     if (renderContext->GetClipEdge().has_value()) {
82         textContentModifier_->SetClip(renderContext->GetClipEdge().value());
83     }
84 
85     PropertyChangeFlag flag = 0;
86     if (textContentModifier_->NeedMeasureUpdate(flag)) {
87         frameNode->MarkDirtyNode(flag);
88     }
89 }
90 
GetOverlayModifier(PaintWrapper * paintWrapper)91 RefPtr<Modifier> TextPaintMethod::GetOverlayModifier(PaintWrapper* paintWrapper)
92 {
93     return textOverlayModifier_;
94 }
95 
UpdateOverlayModifier(PaintWrapper * paintWrapper)96 void TextPaintMethod::UpdateOverlayModifier(PaintWrapper* paintWrapper)
97 {
98     CHECK_NULL_VOID(paintWrapper);
99     CHECK_NULL_VOID(textOverlayModifier_);
100 
101     auto textPattern = DynamicCast<TextPattern>(pattern_.Upgrade());
102     CHECK_NULL_VOID(textPattern);
103     auto paragraph = textPattern->GetParagraph();
104     CHECK_NULL_VOID(paragraph);
105 
106     auto offset = paintWrapper->GetContentOffset();
107     auto paintOffset = offset - OffsetF(0.0, std::min(baselineOffset_, 0.0f));
108     textOverlayModifier_->SetPrintOffset(paintOffset);
109     auto host = textPattern->GetHost();
110     CHECK_NULL_VOID(host);
111     auto context = host->GetRenderContext();
112     CHECK_NULL_VOID(context);
113     const auto& selection = textPattern->GetTextSelector();
114     auto contentRect = textPattern->GetTextContentRect();
115     std::vector<RectF> selectedRects;
116     if (selection.GetTextStart() != selection.GetTextEnd()) {
117         paragraph->GetRectsForRange(selection.GetTextStart(), selection.GetTextEnd(), selectedRects);
118         TextBase::CalculateSelectedRect(selectedRects, contentRect.Width());
119     }
120     textOverlayModifier_->SetContentRect(contentRect);
121     textOverlayModifier_->SetShowSelect(textPattern->GetShowSelect());
122     textOverlayModifier_->SetSelectedRects(selectedRects);
123     auto pipelineContext = PipelineContext::GetCurrentContext();
124     CHECK_NULL_VOID(pipelineContext);
125     auto themeManager = pipelineContext->GetThemeManager();
126     CHECK_NULL_VOID(themeManager);
127     auto theme = themeManager->GetTheme<TextTheme>();
128     auto selectedColor = theme->GetSelectedColor().GetValue();
129     textOverlayModifier_->SetSelectedColor(selectedColor);
130     if (context->GetClipEdge().has_value()) {
131         textOverlayModifier_->SetIsClip(context->GetClipEdge().value());
132     }
133 }
134 } // namespace OHOS::Ace::NG