1 /* 2 * Copyright (c) 2022-2023 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_PAPAGRAPH_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_PAPAGRAPH_H 18 19 #include "base/geometry/ng/size_t.h" 20 #include "base/image/pixel_map.h" 21 #include "base/memory/ace_type.h" 22 #include "core/components/common/layout/constants.h" 23 #include "core/components/common/properties/alignment.h" 24 #include "core/components/common/properties/text_style.h" 25 #include "core/components_ng/render/drawing_forward.h" 26 #include "core/components_ng/render/font_collection.h" 27 #include "core/components_v2/inspector/utils.h" 28 #include "core/pipeline_ng/pipeline_context.h" 29 #include "core/components/common/properties/text_layout_info.h" 30 31 namespace OHOS::Ace::NG { 32 33 enum RectHeightPolicy { 34 COVER_TEXT, 35 COVER_LINE 36 }; 37 38 class LeadingMarginSize { 39 public: 40 LeadingMarginSize() = default; 41 ~LeadingMarginSize() = default; 42 LeadingMarginSize(Dimension width,Dimension height)43 LeadingMarginSize(Dimension width, Dimension height) 44 { 45 width_ = UnitFilter(width); 46 height_ = UnitFilter(height); 47 } 48 ToString()49 std::string ToString() const 50 { 51 static const int32_t precision = 2; 52 std::stringstream ss; 53 ss << std::fixed << std::setprecision(precision); 54 ss << "width: " << width_.ToString(); 55 ss << " height: " << height_.ToString(); 56 return ss.str(); 57 } 58 59 bool operator==(const LeadingMarginSize& size) const 60 { 61 return NearEqual(width_, size.width_) && NearEqual(height_, size.height_); 62 } 63 Width()64 Dimension Width() const 65 { 66 return width_; 67 } 68 Height()69 Dimension Height() const 70 { 71 return height_; 72 } 73 74 private: UnitFilter(Dimension & value)75 Dimension UnitFilter(Dimension& value) 76 { 77 return value.Unit() == DimensionUnit::PERCENT ? Dimension(0.0) : value; 78 } 79 80 Dimension width_; 81 Dimension height_; 82 }; 83 84 struct LineMetrics { 85 float ascender = 0.0f; 86 float descender = 0.0f; 87 float capHeight = 0.0f; 88 float xHeight = 0.0f; 89 float width = 0.0f; 90 float height = 0.0f; 91 float x = 0.0f; 92 float y = 0.0f; 93 }; 94 95 struct LeadingMargin { 96 LeadingMarginSize size; 97 RefPtr<PixelMap> pixmap; 98 99 bool operator==(const LeadingMargin& other) const 100 { 101 return size == other.size && pixmap == other.pixmap; 102 } 103 ToStringLeadingMargin104 std::string ToString() const 105 { 106 auto jsonValue = JsonUtil::Create(true); 107 JSON_STRING_PUT_STRINGABLE(jsonValue, size); 108 jsonValue->Put("pixmap", 109 pixmap ? ("size=" + std::to_string(pixmap->GetWidth()) + "," + std::to_string(pixmap->GetHeight())).c_str() 110 : "nullptr"); 111 return jsonValue->ToString(); 112 } 113 CheckLeadingMarginLeadingMargin114 bool CheckLeadingMargin(const LeadingMargin& other) const 115 { 116 auto flag = size == other.size; 117 if (pixmap && other.pixmap) { 118 flag &= pixmap->GetRawPixelMapPtr() == other.pixmap->GetRawPixelMapPtr(); 119 } else if (!other.pixmap && !pixmap) { 120 flag &= true; 121 } else { 122 flag &= false; 123 } 124 return flag; 125 } 126 }; 127 128 struct ParagraphStyle { 129 TextDirection direction = TextDirection::AUTO; 130 TextAlign align = TextAlign::LEFT; 131 uint32_t maxLines = UINT32_MAX; 132 std::string fontLocale; 133 WordBreak wordBreak = WordBreak::NORMAL; 134 EllipsisMode ellipsisMode = EllipsisMode::TAIL; 135 LineBreakStrategy lineBreakStrategy = LineBreakStrategy::GREEDY; 136 TextOverflow textOverflow = TextOverflow::CLIP; 137 std::optional<LeadingMargin> leadingMargin; 138 double fontSize = 14.0; 139 Dimension lineHeight; 140 Dimension indent; 141 Alignment leadingMarginAlign = Alignment::TOP_CENTER; 142 143 bool operator==(const ParagraphStyle others) const 144 { 145 return direction == others.direction && align == others.align && maxLines == others.maxLines && 146 fontLocale == others.fontLocale && wordBreak == others.wordBreak && 147 ellipsisMode == others.ellipsisMode && textOverflow == others.textOverflow && 148 leadingMargin == others.leadingMargin && fontSize == others.fontSize && indent == others.indent; 149 } 150 151 bool operator!=(const ParagraphStyle others) const 152 { 153 return !(*this == others); 154 } 155 ToStringParagraphStyle156 std::string ToString() const 157 { 158 std::string result = "TextAlign: "; 159 result += V2::ConvertWrapTextAlignToString(align); 160 result += ", maxLines: "; 161 result += std::to_string(maxLines); 162 result += ", wordBreak: "; 163 result += V2::ConvertWrapWordBreakToString(wordBreak); 164 result += ", textOverflow: "; 165 result += V2::ConvertWrapTextOverflowToString(textOverflow); 166 result += ", leadingMargin: "; 167 result += leadingMargin.has_value() ? leadingMargin.value().ToString().c_str() : "nullptr"; 168 result += ", fontSize: "; 169 result += std::to_string(fontSize); 170 result += ", indent: "; 171 result += indent.ToString(); 172 return result; 173 } 174 }; 175 176 struct CaretMetricsF { 177 CaretMetricsF() = default; CaretMetricsFCaretMetricsF178 CaretMetricsF(const OffsetF& position, float h) 179 { 180 offset = position; 181 height = h; 182 } ResetCaretMetricsF183 void Reset() 184 { 185 offset.Reset(); 186 height = 0.0; 187 } 188 189 OffsetF offset; 190 // When caret is close to different glyphs, the height will be different. 191 float height = 0.0f; ToStringCaretMetricsF192 std::string ToString() const 193 { 194 std::string result = "Offset: "; 195 result += offset.ToString(); 196 result += ", height: "; 197 result += std::to_string(height); 198 return result; 199 } 200 }; 201 202 struct PositionWithAffinity { PositionWithAffinityPositionWithAffinity203 PositionWithAffinity(size_t pos, TextAffinity affinity) 204 { 205 position_ = pos; 206 affinity_ = affinity; 207 } 208 size_t position_; 209 TextAffinity affinity_; 210 }; 211 212 // Paragraph is interface for drawing text and text paragraph. 213 class Paragraph : public virtual AceType { 214 DECLARE_ACE_TYPE(NG::Paragraph, AceType) 215 216 public: 217 static RefPtr<Paragraph> Create(const ParagraphStyle& paraStyle, const RefPtr<FontCollection>& fontCollection); 218 219 static RefPtr<Paragraph> Create(void* paragraph); 220 // whether the paragraph has been build 221 virtual bool IsValid() = 0; 222 223 // interfaces for build text paragraph 224 virtual void PushStyle(const TextStyle& style) = 0; 225 virtual void PopStyle() = 0; 226 virtual void AddText(const std::u16string& text) = 0; 227 virtual void AddSymbol(const std::uint32_t& symbolId) = 0; 228 virtual int32_t AddPlaceholder(const PlaceholderRun& span) = 0; 229 virtual void Build() = 0; 230 virtual void Reset() = 0; 231 232 // interfaces for layout 233 virtual void Layout(float width) = 0; 234 virtual float GetHeight() = 0; 235 virtual float GetTextWidth() = 0; 236 virtual size_t GetLineCount() = 0; 237 virtual float GetMaxIntrinsicWidth() = 0; 238 virtual bool DidExceedMaxLines() = 0; 239 virtual float GetLongestLine() = 0; 240 virtual float GetLongestLineWithIndent() = 0; 241 virtual float GetMaxWidth() = 0; 242 virtual float GetAlphabeticBaseline() = 0; 243 virtual float GetCharacterWidth(int32_t index) = 0; 244 virtual int32_t GetGlyphIndexByCoordinate(const Offset& offset, bool isSelectionPos = false) = 0; GetGlyphPositionAtCoordinate(const Offset & offset)245 virtual PositionWithAffinity GetGlyphPositionAtCoordinate(const Offset& offset) 246 { 247 PositionWithAffinity finalResult(0, TextAffinity::UPSTREAM); 248 return finalResult; 249 } 250 virtual void GetRectsForRange(int32_t start, int32_t end, std::vector<RectF>& selectedRects) = 0; 251 virtual void GetTightRectsForRange(int32_t start, int32_t end, std::vector<RectF>& selectedRects) = 0; 252 virtual void GetRectsForPlaceholders(std::vector<RectF>& selectedRects) = 0; 253 virtual bool ComputeOffsetForCaretDownstream( 254 int32_t extent, CaretMetricsF& result, bool needLineHighest = true) = 0; 255 virtual bool ComputeOffsetForCaretUpstream(int32_t extent, CaretMetricsF& result, bool needLineHighest = true) = 0; 256 virtual bool CalcCaretMetricsByPosition( 257 int32_t extent, CaretMetricsF& caretCaretMetric, TextAffinity textAffinity, bool needLineHighest = true) = 0; 258 virtual bool CalcCaretMetricsByPosition(int32_t extent, CaretMetricsF& caretCaretMetric, 259 const OffsetF& lastTouchOffset, TextAffinity& textAffinity) = 0; 260 virtual void SetIndents(const std::vector<float>& indents) = 0; 261 virtual bool GetWordBoundary(int32_t offset, int32_t& start, int32_t& end) = 0; 262 virtual std::u16string GetParagraphText() = 0; 263 virtual const ParagraphStyle& GetParagraphStyle() const = 0; 264 // interfaces for pass on Symbol Animation interface 265 virtual void SetParagraphSymbolAnimation(const RefPtr<FrameNode>& frameNode) = 0; 266 // interfaces for painting 267 virtual void Paint(RSCanvas& canvas, float x, float y) = 0; 268 #ifndef USE_ROSEN_DRAWING 269 virtual void Paint(SkCanvas* skCanvas, float x, float y) = 0; 270 #endif 271 virtual LineMetrics GetLineMetricsByRectF(RectF& rect) = 0; 272 virtual TextLineMetrics GetLineMetrics(size_t lineNumber) = 0; 273 virtual RectF GetPaintRegion(float x, float y) = 0; 274 virtual bool GetLineMetricsByCoordinate(const Offset& offset, LineMetrics& lineMetrics) = 0; 275 virtual void UpdateColor(size_t from, size_t to, const Color& color) = 0; 276 virtual void TxtGetRectsForRange(int32_t start, int32_t end, 277 RectHeightStyle heightStyle, RectWidthStyle widthStyle, 278 std::vector<RectF>& selectedRects, std::vector<TextDirection>& textDirections) = 0; 279 }; 280 } // namespace OHOS::Ace::NG 281 282 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_RENDER_PAPAGRAPH_H 283