1 /* 2 * Copyright (c) 2021 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_TEXT_FIELD_ROSEN_RENDER_TEXT_FIELD_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TEXT_FIELD_ROSEN_RENDER_TEXT_FIELD_H 18 19 #include <memory> 20 #include <string> 21 22 #include "rosen_text/font_collection.h" 23 #include "rosen_text/typography.h" 24 #include "rosen_text/typography_style.h" 25 #ifndef USE_ROSEN_DRAWING 26 #include "third_party/skia/include/core/SkBitmap.h" 27 #include "third_party/skia/include/core/SkCanvas.h" 28 #else 29 #include "core/components_ng/render/drawing.h" 30 #endif 31 32 #include "core/components/common/properties/decoration.h" 33 #include "core/components/text_field/render_text_field.h" 34 35 namespace OHOS::Rosen { 36 class FontCollection; 37 struct TypographyStyle; 38 struct TextStyle; 39 } // namespace OHOS::Rosen 40 namespace OHOS::Ace { 41 42 class Component; 43 44 class RosenRenderTextField final : public RenderTextField { 45 DECLARE_ACE_TYPE(RosenRenderTextField, RenderTextField); 46 47 public: 48 RosenRenderTextField() = default; 49 ~RosenRenderTextField() override = default; 50 51 void Paint(RenderContext& context, const Offset& offset) override; 52 GetCaretRect()53 const Rect& GetCaretRect() const 54 { 55 return caretRect_; 56 } 57 GetStartRect()58 const Rect& GetStartRect() const 59 { 60 return startCaretRect_; 61 } 62 63 #ifndef USE_ROSEN_DRAWING GetBitmap()64 const SkBitmap& GetBitmap() const 65 #else 66 const RSBitmap& GetBitmap() const 67 #endif 68 { 69 return canvasCache_; 70 } 71 72 protected: 73 int32_t GetCursorPositionForMoveUp() override; 74 int32_t GetCursorPositionForMoveDown() override; 75 int32_t GetCursorPositionForClick(const Offset& offset) override; 76 int32_t AdjustCursorAndSelection(int32_t currentCursorPosition) override; 77 DirectionStatus GetDirectionStatusOfPosition(int32_t position) const override; 78 Offset GetHandleOffset(int32_t extend) override; 79 Size ComputeDeflateSizeOfErrorAndCountText() const override; 80 void ResetStatus() override; 81 82 private: 83 std::unique_ptr<Rosen::TypographyStyle> CreateParagraphStyle(bool isErrorText = false); 84 std::unique_ptr<Rosen::TextStyle> CreateTextStyle(const TextStyle& style, bool isPlaceholder = false); 85 86 double PreferredLineHeight() override; 87 void UpdateCaretProto(); 88 // Case of upstream affinity, which means the caret size should fit with the glyphs before [extent]. 89 bool ComputeOffsetForCaretUpstream(int32_t extent, CaretMetrics& result) const; 90 bool ComputeOffsetForCaretDownstream(int32_t extent, CaretMetrics& result) const; 91 bool ComputeOffsetForCaretCloserToClick(int32_t extent, CaretMetrics& result) const; 92 // Make an offset when no text exists. The position of caret depends on the [textAlign_] && [textDirection_]. 93 Offset MakeEmptyOffset() const; 94 Size Measure() override; 95 double MeasureParagraph( 96 const std::unique_ptr<Rosen::TypographyStyle>& paragraphStyle, std::unique_ptr<Rosen::TextStyle>& txtStyle); 97 Size ComputeLayoutSize(const Size& size, double decorationHeight); 98 99 Rect GetInnerRect(const Decoration& decoration, const Rect& outer, double dipScale) const; 100 bool GetCaretRect(int32_t extent, Rect& caretRect, double caretHeightOffset = 0.0) const override; 101 // Compute the offset of caret and text. Must be called after paragraph built. 102 void ComputeOffsetAfterLayout(); 103 // Compute the offset to align text and icon to vertical center. 104 Offset ComputeVerticalOffsetForCenter(double outerHeight, double innerHeight) const; 105 void SetShaderIfNeeded(std::unique_ptr<Rosen::TypographyStyle> paragraphStyle, 106 std::unique_ptr<Rosen::TextStyle> txtStyle, double textAreaWidth); 107 #ifndef USE_ROSEN_DRAWING 108 sk_sp<SkShader> MakeGradientShader(double shadeWidth) const; 109 #else 110 std::shared_ptr<RSShaderEffect> MakeGradientShader(double shadeWidth) const; 111 #endif 112 std::shared_ptr<Rosen::FontCollection> GetFontCollection(); 113 void ResetParagraphIfNeeded(); 114 void ComputeExtendHeight(double decorationHeight); 115 double GetBoundaryOfParagraph(bool isLeftBoundary) const; 116 bool AdjustCursorAndSelectionForLtr(bool isBeforeCharRtl, bool isAfterCharRtl, const std::wstring& textBeforeCursor, 117 const std::wstring& textAfterCursor, int32_t& result); 118 bool AdjustCursorAndSelectionForRtl(bool isBeforeCharRtl, bool isAfterCharRtl, const std::wstring& textBeforeCursor, 119 const std::wstring& textAfterCursor, int32_t& result); 120 bool NeedAdjustPosition(const std::wstring& textBeforeCursor); 121 122 // Paint cursor at the extent position. When [affinity] supported, extends this function. 123 #ifndef USE_ROSEN_DRAWING 124 void PaintCaret(SkCanvas& canvas, const Rect& caretRect); 125 void PaintDecoration(const Offset& offset, SkCanvas* canvas, const Size& size, RenderContext& context); 126 void PaintSelectCaret(SkCanvas* canvas); 127 void PaintIcon(const Offset& offset, RenderContext& context); 128 void PaintSelection(SkCanvas* canvas) const; 129 void PaintTextAndPlaceholder(SkCanvas* canvas) const; 130 void PaintErrorText(SkCanvas* canvas) const; 131 void PaintCountText(SkCanvas* canvas) const; 132 void PaintOverlayForHoverAndPress(const Offset& offset, SkCanvas* canvas) const; 133 void PaintTextField(const Offset& offset, RenderContext& context, SkCanvas* canvas, bool isMagnifier = false); 134 SkVector GetSkRadii(const Radius& radius) const; 135 #else 136 void PaintCaret(RSCanvas& canvas, const Rect& caretRect); 137 void PaintDecoration(const Offset& offset, RSCanvas* canvas, const Size& size, RenderContext& context); 138 void PaintSelectCaret(RSCanvas* canvas); 139 void PaintIcon(const Offset& offset, RenderContext& context); 140 void PaintSelection(RSCanvas* canvas) const; 141 void PaintTextAndPlaceholder(RSCanvas* canvas) const; 142 void PaintErrorText(RSCanvas* canvas) const; 143 void PaintCountText(RSCanvas* canvas) const; 144 void PaintOverlayForHoverAndPress(const Offset& offset, RSCanvas* canvas) const; 145 void PaintTextField(const Offset& offset, RenderContext& context, RSCanvas* canvas, bool isMagnifier = false); 146 RSPoint GetRSRadii(const Radius& radius) const; 147 #endif 148 void PaintFocus(const Offset& offset, const Size& widthHeight, RenderContext& context); 149 150 std::unique_ptr<Rosen::Typography> paragraph_; 151 std::unique_ptr<Rosen::Typography> errorParagraph_; 152 std::unique_ptr<Rosen::Typography> countParagraph_; 153 std::unique_ptr<Rosen::Typography> placeholderParagraph_; 154 // Used to estimate size. 155 std::unique_ptr<Rosen::Typography> template_; 156 157 Rect startCaretRect_; 158 Size lastLayoutSize_; 159 double originInnerWidth_ = 0.0; 160 161 #ifndef USE_ROSEN_DRAWING 162 SkBitmap canvasCache_ {}; 163 std::unique_ptr<SkCanvas> magnifierCanvas_; 164 #else 165 RSBitmap canvasCache_ {}; 166 std::unique_ptr<RSCanvas> magnifierCanvas_; 167 #endif 168 }; 169 170 } // namespace OHOS::Ace 171 172 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_TEXT_FIELD_ROSEN_RENDER_TEXT_FIELD_H 173