• 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 "drag_window_ohos.h"
17 
18 #include "rosen_text/typography.h"
19 
20 #include "include/core/SkCanvas.h"
21 #include "include/core/SkSamplingOptions.h"
22 
23 #include "base/geometry/ng/rect_t.h"
24 #include "base/geometry/offset.h"
25 #include "base/image/pixel_map.h"
26 #include "base/log/log_wrapper.h"
27 #include "base/utils/utils.h"
28 #include "core/components/text/render_text.h"
29 #include "core/components_ng/base/frame_node.h"
30 #include "core/components_ng/pattern/text/text_pattern.h"
31 #include "core/components_ng/render/adapter/rosen_render_context.h"
32 #include "core/components_ng/render/adapter/rosen/drawing_image.h"
33 #include "core/components_ng/render/drawing.h"
34 #include "core/pipeline_ng/pipeline_context.h"
35 
36 using namespace OHOS::Rosen;
37 
38 namespace OHOS::Ace {
39 #ifdef ENABLE_ROSEN_BACKEND
40 namespace {
41 // Adapt text dragging background shadows to expand the width of dargwindow
42 const Dimension Window_EXTERN = 10.0_vp;
43 
AlphaTypeToAlphaType(const RefPtr<PixelMap> & pixmap)44 RSAlphaType AlphaTypeToAlphaType(const RefPtr<PixelMap>& pixmap)
45 {
46     switch (pixmap->GetAlphaType()) {
47         case AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
48             return RSAlphaType::ALPHATYPE_UNKNOWN;
49         case AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
50             return RSAlphaType::ALPHATYPE_OPAQUE;
51         case AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
52             return RSAlphaType::ALPHATYPE_PREMUL;
53         case AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
54             return RSAlphaType::ALPHATYPE_UNPREMUL;
55         default:
56             return RSAlphaType::ALPHATYPE_UNKNOWN;
57     }
58 }
59 
PixelFormatToColorType(const RefPtr<PixelMap> & pixmap)60 RSColorType PixelFormatToColorType(const RefPtr<PixelMap>& pixmap)
61 {
62     switch (pixmap->GetPixelFormat()) {
63         case PixelFormat::RGB_565:
64             return RSColorType::COLORTYPE_RGB_565;
65         case PixelFormat::RGBA_8888:
66             return RSColorType::COLORTYPE_RGBA_8888;
67         case PixelFormat::BGRA_8888:
68             return RSColorType::COLORTYPE_BGRA_8888;
69         case PixelFormat::ALPHA_8:
70             return RSColorType::COLORTYPE_ALPHA_8;
71         case PixelFormat::RGBA_F16:
72             return RSColorType::COLORTYPE_RGBA_F16;
73         case PixelFormat::UNKNOWN:
74         case PixelFormat::ARGB_8888:
75         case PixelFormat::RGB_888:
76         case PixelFormat::NV21:
77         case PixelFormat::NV12:
78         case PixelFormat::CMYK:
79         default:
80             return RSColorType::COLORTYPE_UNKNOWN;
81     }
82 }
83 
MakeBitmapFormatFromPixelMap(const RefPtr<PixelMap> & pixmap)84 RSBitmapFormat MakeBitmapFormatFromPixelMap(const RefPtr<PixelMap>& pixmap)
85 {
86     RSBitmapFormat format;
87     format.colorType = PixelFormatToColorType(pixmap);
88     format.alphaType = AlphaTypeToAlphaType(pixmap);
89     return format;
90 }
91 
DrawDrawingImage(RSCanvas * canvas,const std::shared_ptr<RSImage> & drawingImage,int32_t width,int32_t height)92 void DrawDrawingImage(RSCanvas* canvas, const std::shared_ptr<RSImage>& drawingImage, int32_t width, int32_t height)
93 {
94     CHECK_NULL_VOID(drawingImage);
95     RSBrush brush;
96     auto colorSpace = RSRecordingColorSpace::CreateRefImage(*drawingImage);
97     brush.SetColor(brush.GetColor4f(), colorSpace);
98     auto srcRect = RSRect(0, 0, drawingImage->GetWidth(), drawingImage->GetHeight());
99     auto dstRect = RSRect(0, 0, width, height);
100     RSSamplingOptions sampling;
101     canvas->AttachBrush(brush);
102     canvas->DrawImageRect(
103         *drawingImage, srcRect, dstRect, sampling, Drawing::SrcRectConstraint::FAST_SRC_RECT_CONSTRAINT);
104     canvas->DetachBrush();
105 }
106 
DrawPixelMapInner(RSCanvas * canvas,const RefPtr<PixelMap> & pixmap,int32_t width,int32_t height)107 void DrawPixelMapInner(RSCanvas* canvas, const RefPtr<PixelMap>& pixmap, int32_t width, int32_t height)
108 {
109     // Step1: Create Bitmap
110     auto bitmapFormat = MakeBitmapFormatFromPixelMap(pixmap);
111     auto bitmap = std::make_shared<RSBitmap>();
112     bitmap->Build(pixmap->GetWidth(), pixmap->GetHeight(), bitmapFormat);
113     bitmap->SetPixels(const_cast<void*>(reinterpret_cast<const void*>(pixmap->GetPixels())));
114 
115     // Step2: Create Image and draw it
116     auto image = std::make_shared<RSImage>();
117     image->BuildFromBitmap(*bitmap);
118     DrawDrawingImage(canvas, image, width, height);
119 }
120 } // namespace
121 #endif
122 
CreateDragWindow(const std::string & windowName,int32_t x,int32_t y,uint32_t width,uint32_t height)123 RefPtr<DragWindow> DragWindow::CreateDragWindow(
124     const std::string& windowName, int32_t x, int32_t y, uint32_t width, uint32_t height)
125 {
126     return CreateDragWindow({ windowName, x, y, width, height });
127 }
128 
CreateDragWindow(const DragWindowParams & params)129 RefPtr<DragWindow> DragWindow::CreateDragWindow(const DragWindowParams& params)
130 {
131     int32_t halfWidth = static_cast<int32_t>(params.width) / 2;
132     int32_t halfHeight = static_cast<int32_t>(params.height) / 2;
133 
134     OHOS::sptr<OHOS::Rosen::WindowOption> option = new OHOS::Rosen::WindowOption();
135     option->SetWindowRect({ params.x - halfWidth, params.y - halfHeight, params.width, params.height });
136     option->SetHitOffset(halfWidth, halfHeight);
137     if (params.parentWindowId == -1) {
138         option->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_DRAGGING_EFFECT);
139     } else {
140         option->SetParentId(params.parentWindowId);
141         option->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW);
142     }
143     option->SetWindowMode(OHOS::Rosen::WindowMode::WINDOW_MODE_FLOATING);
144     option->SetFocusable(false);
145     OHOS::sptr<OHOS::Rosen::Window> dragWindow = OHOS::Rosen::Window::Create(params.windowName, option);
146     CHECK_NULL_RETURN(dragWindow, nullptr);
147 
148     OHOS::Rosen::WMError ret = dragWindow->MoveTo(params.x - halfWidth, params.y - halfHeight, true);
149     if (ret != OHOS::Rosen::WMError::WM_OK) {
150         TAG_LOGE(AceLogTag::ACE_DRAG, "DragWindow MoveTo, drag window move failed, ret: %d", ret);
151         return nullptr;
152     }
153 
154     ret = dragWindow->Show();
155     if (ret != OHOS::Rosen::WMError::WM_OK) {
156         TAG_LOGE(AceLogTag::ACE_DRAG, "DragWindow CreateDragWindow, drag window Show() failed, ret: %d", ret);
157         return nullptr;
158     }
159 
160     auto window = AceType::MakeRefPtr<DragWindowOhos>(dragWindow);
161     window->SetSize(params.width, params.height);
162     return window;
163 }
164 
CreateTextDragWindow(const std::string & windowName,int32_t x,int32_t y,uint32_t width,uint32_t height)165 RefPtr<DragWindow> DragWindow::CreateTextDragWindow(
166     const std::string& windowName, int32_t x, int32_t y, uint32_t width, uint32_t height)
167 {
168     int32_t halfWidth = static_cast<int32_t>(width + Window_EXTERN.ConvertToPx() * 2) / 2;
169     int32_t halfHeight = static_cast<int32_t>(height + Window_EXTERN.ConvertToPx() * 2) / 2;
170 
171     OHOS::sptr<OHOS::Rosen::WindowOption> option = new OHOS::Rosen::WindowOption();
172     option->SetWindowRect({ x - Window_EXTERN.ConvertToPx(), y - Window_EXTERN.ConvertToPx(),
173         width + Window_EXTERN.ConvertToPx() * 2, height + Window_EXTERN.ConvertToPx() * 2 });
174     option->SetHitOffset(halfWidth, halfHeight);
175     option->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_DRAGGING_EFFECT);
176     option->SetWindowMode(OHOS::Rosen::WindowMode::WINDOW_MODE_FLOATING);
177     option->SetFocusable(false);
178     OHOS::sptr<OHOS::Rosen::Window> dragWindow = OHOS::Rosen::Window::Create(windowName, option);
179     CHECK_NULL_RETURN(dragWindow, nullptr);
180 
181     OHOS::Rosen::WMError ret = dragWindow->Show();
182     if (ret != OHOS::Rosen::WMError::WM_OK) {
183         TAG_LOGE(AceLogTag::ACE_DRAG, "DragWindow CreateTextDragWindow, drag window Show() failed, ret: %d", ret);
184     }
185 
186     auto window = AceType::MakeRefPtr<DragWindowOhos>(dragWindow);
187     window->SetSize(width + Window_EXTERN.ConvertToPx() * 2, height + Window_EXTERN.ConvertToPx() * 2);
188     return window;
189 }
190 
MoveTo(int32_t x,int32_t y) const191 void DragWindowOhos::MoveTo(int32_t x, int32_t y) const
192 {
193     CHECK_NULL_VOID(dragWindow_);
194 
195     OHOS::Rosen::WMError ret = dragWindow_->MoveTo(x + offsetX_ - width_ / 2, y + offsetY_ - height_ / 2, true);
196     if (ret != OHOS::Rosen::WMError::WM_OK) {
197         TAG_LOGE(AceLogTag::ACE_DRAG, "DragWindow MoveTo, drag window move failed, ret: %d", ret);
198         return;
199     }
200 
201     ret = dragWindow_->Show();
202     if (ret != OHOS::Rosen::WMError::WM_OK) {
203         TAG_LOGE(AceLogTag::ACE_DRAG, "DragWindow CreateDragWindow, drag window Show() failed, ret: %d", ret);
204     }
205 }
206 
TextDragWindowMove(double x,double y) const207 void DragWindowOhos::TextDragWindowMove(double x, double y) const
208 {
209     CHECK_NULL_VOID(dragWindow_);
210     OHOS::Rosen::WMError ret =
211         dragWindow_->MoveTo(x - Window_EXTERN.ConvertToPx() + offsetX_, y + offsetY_ - Window_EXTERN.ConvertToPx());
212     if (ret != OHOS::Rosen::WMError::WM_OK) {
213         TAG_LOGE(AceLogTag::ACE_DRAG, "DragWindow TextDragWindowMove, drag window move failed, ret: %d", ret);
214         return;
215     }
216 
217     ret = dragWindow_->Show();
218     if (ret != OHOS::Rosen::WMError::WM_OK) {
219         TAG_LOGE(AceLogTag::ACE_DRAG, "DragWindow TextDragWindowMove, drag window Show() failed, ret: %d", ret);
220     }
221 }
222 
Destroy() const223 void DragWindowOhos::Destroy() const
224 {
225     CHECK_NULL_VOID(dragWindow_);
226 
227     OHOS::Rosen::WMError ret = dragWindow_->Destroy();
228     if (ret != OHOS::Rosen::WMError::WM_OK) {
229         TAG_LOGE(AceLogTag::ACE_DRAG, "DragWindow Destroy, drag window destroy failed, ret: %d", ret);
230     }
231 }
232 
DrawFrameNode(const RefPtr<NG::FrameNode> & rootNode)233 void DragWindowOhos::DrawFrameNode(const RefPtr<NG::FrameNode>& rootNode)
234 {
235 #ifdef ENABLE_ROSEN_BACKEND
236     CHECK_NULL_VOID(rootNode);
237 
238     auto surfaceNode = dragWindow_->GetSurfaceNode();
239     rsUiDirector_ = Rosen::RSUIDirector::Create();
240     rsUiDirector_->Init();
241     auto transactionProxy = Rosen::RSTransactionProxy::GetInstance();
242     if (transactionProxy != nullptr) {
243         transactionProxy->FlushImplicitTransaction();
244     }
245     rsUiDirector_->SetRSSurfaceNode(surfaceNode);
246 
247     auto renderContext = AceType::DynamicCast<NG::RosenRenderContext>(rootNode->GetRenderContext());
248     CHECK_NULL_VOID(renderContext);
249     auto rsNode = renderContext->GetRSNode();
250     CHECK_NULL_VOID(rsNode);
251 
252     rsUiDirector_->SetRoot(rsNode->GetId());
253     rsUiDirector_->SendMessages();
254 #endif
255 }
256 
DrawPixelMap(const RefPtr<PixelMap> & pixelmap)257 void DragWindowOhos::DrawPixelMap(const RefPtr<PixelMap>& pixelmap)
258 {
259 #ifdef ENABLE_ROSEN_BACKEND
260     CHECK_NULL_VOID(pixelmap);
261     auto surfaceNode = dragWindow_->GetSurfaceNode();
262     rsUiDirector_ = Rosen::RSUIDirector::Create();
263     rsUiDirector_->Init();
264     auto transactionProxy = Rosen::RSTransactionProxy::GetInstance();
265     if (transactionProxy != nullptr) {
266         transactionProxy->FlushImplicitTransaction();
267     }
268     rsUiDirector_->SetRSSurfaceNode(surfaceNode);
269     rootNode_ = Rosen::RSRootNode::Create();
270     rootNode_->SetBounds(0, 0, static_cast<float>(width_), static_cast<float>(height_));
271     rootNode_->SetFrame(0, 0, static_cast<float>(width_), static_cast<float>(height_));
272     rsUiDirector_->SetRoot(rootNode_->GetId());
273     auto canvasNode = std::static_pointer_cast<Rosen::RSCanvasNode>(rootNode_);
274     auto drawing = canvasNode->BeginRecording(width_, height_);
275     DrawPixelMapInner(drawing, pixelmap, width_, height_);
276     canvasNode->FinishRecording();
277     rsUiDirector_->SendMessages();
278 #endif
279 }
280 
DrawImage(void * drawingImage)281 void DragWindowOhos::DrawImage(void* drawingImage)
282 {
283 #ifdef ENABLE_ROSEN_BACKEND
284     CHECK_NULL_VOID(drawingImage);
285     auto* canvasImagePtr = reinterpret_cast<RefPtr<NG::CanvasImage>*>(drawingImage);
286     CHECK_NULL_VOID(canvasImagePtr);
287     RefPtr<NG::DrawingImage> canvasImage = AceType::DynamicCast<NG::DrawingImage>(*canvasImagePtr);
288     CHECK_NULL_VOID(canvasImage);
289     auto surfaceNode = dragWindow_->GetSurfaceNode();
290     rsUiDirector_ = Rosen::RSUIDirector::Create();
291     rsUiDirector_->Init();
292     auto transactionProxy = Rosen::RSTransactionProxy::GetInstance();
293     if (transactionProxy != nullptr) {
294         transactionProxy->FlushImplicitTransaction();
295     }
296     rsUiDirector_->SetRSSurfaceNode(surfaceNode);
297     rootNode_ = Rosen::RSRootNode::Create();
298     rootNode_->SetBounds(0, 0, static_cast<float>(width_), static_cast<float>(height_));
299     rootNode_->SetFrame(0, 0, static_cast<float>(width_), static_cast<float>(height_));
300     rsUiDirector_->SetRoot(rootNode_->GetId());
301     auto canvasNode = std::static_pointer_cast<Rosen::RSCanvasNode>(rootNode_);
302     auto drawing = canvasNode->BeginRecording(width_, height_);
303     auto rsImage = canvasImage->GetImage();
304     DrawDrawingImage(drawing, rsImage, width_, height_);
305     canvasNode->FinishRecording();
306     rsUiDirector_->SendMessages();
307 #endif
308 }
309 
DrawText(std::shared_ptr<Rosen::Typography> paragraph,const Offset & offset,const RefPtr<RenderText> & renderText)310 void DragWindowOhos::DrawText(
311     std::shared_ptr<Rosen::Typography> paragraph, const Offset& offset, const RefPtr<RenderText>& renderText)
312 {
313 #ifndef NG_BUILD
314 #ifdef ENABLE_ROSEN_BACKEND
315     CHECK_NULL_VOID(paragraph);
316     auto surfaceNode = dragWindow_->GetSurfaceNode();
317     rsUiDirector_ = Rosen::RSUIDirector::Create();
318     rsUiDirector_->Init();
319     auto transactionProxy = Rosen::RSTransactionProxy::GetInstance();
320     if (transactionProxy != nullptr) {
321         transactionProxy->FlushImplicitTransaction();
322     }
323     rsUiDirector_->SetRSSurfaceNode(surfaceNode);
324     rootNode_ = Rosen::RSRootNode::Create();
325     rootNode_->SetBounds(0, 0, static_cast<float>(width_), static_cast<float>(height_));
326     rootNode_->SetFrame(0, 0, static_cast<float>(width_), static_cast<float>(height_));
327     rsUiDirector_->SetRoot(rootNode_->GetId());
328     auto canvasNode = std::static_pointer_cast<Rosen::RSCanvasNode>(rootNode_);
329     RSRecordingPath path;
330     if (renderText->GetStartOffset().GetY() == renderText->GetEndOffset().GetY()) {
331         path.MoveTo(renderText->GetStartOffset().GetX() - renderText->GetGlobalOffset().GetX(),
332             renderText->GetStartOffset().GetY() - renderText->GetGlobalOffset().GetY());
333         path.LineTo(renderText->GetEndOffset().GetX() - renderText->GetGlobalOffset().GetX(),
334             renderText->GetEndOffset().GetY() - renderText->GetGlobalOffset().GetY());
335         path.LineTo(renderText->GetEndOffset().GetX() - renderText->GetGlobalOffset().GetX(),
336             renderText->GetEndOffset().GetY() - renderText->GetSelectHeight() - renderText->GetGlobalOffset().GetY());
337         path.LineTo(renderText->GetStartOffset().GetX() - renderText->GetGlobalOffset().GetX(),
338             renderText->GetStartOffset().GetY() - renderText->GetSelectHeight() - renderText->GetGlobalOffset().GetY());
339         path.LineTo(renderText->GetStartOffset().GetX() - renderText->GetGlobalOffset().GetX(),
340             renderText->GetStartOffset().GetY() - renderText->GetGlobalOffset().GetY());
341     } else {
342         path.MoveTo(renderText->GetStartOffset().GetX() - renderText->GetGlobalOffset().GetX(),
343             renderText->GetStartOffset().GetY() - renderText->GetGlobalOffset().GetY());
344         path.LineTo(renderText->GetStartOffset().GetX() - renderText->GetGlobalOffset().GetX(),
345             renderText->GetStartOffset().GetY() - renderText->GetSelectHeight() - renderText->GetGlobalOffset().GetY());
346         path.LineTo(renderText->GetPaintRect().Right() - renderText->GetGlobalOffset().GetX(),
347             renderText->GetStartOffset().GetY() - renderText->GetSelectHeight() - renderText->GetGlobalOffset().GetY());
348         path.LineTo(renderText->GetPaintRect().Right() - renderText->GetGlobalOffset().GetX(),
349             renderText->GetEndOffset().GetY() - renderText->GetSelectHeight() - renderText->GetGlobalOffset().GetY());
350         path.LineTo(renderText->GetEndOffset().GetX() - renderText->GetGlobalOffset().GetX(),
351             renderText->GetEndOffset().GetY() - renderText->GetSelectHeight() - renderText->GetGlobalOffset().GetY());
352         path.LineTo(renderText->GetEndOffset().GetX() - renderText->GetGlobalOffset().GetX(),
353             renderText->GetEndOffset().GetY() - renderText->GetGlobalOffset().GetY());
354         path.LineTo(renderText->GetPaintRect().Left() - renderText->GetGlobalOffset().GetX(),
355             renderText->GetEndOffset().GetY() - renderText->GetGlobalOffset().GetY());
356         path.LineTo(renderText->GetPaintRect().Left() - renderText->GetGlobalOffset().GetX(),
357             renderText->GetStartOffset().GetY() - renderText->GetGlobalOffset().GetY());
358         path.LineTo(renderText->GetStartOffset().GetX() - renderText->GetGlobalOffset().GetX(),
359             renderText->GetStartOffset().GetY() - renderText->GetGlobalOffset().GetY());
360     }
361     rootNode_->SetClipToBounds(true);
362     rootNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(path));
363     auto recordingCanvas = canvasNode->BeginRecording(width_, height_);
364     paragraph->Paint(recordingCanvas, 0, 0);
365     canvasNode->FinishRecording();
366     rsUiDirector_->SendMessages();
367 #endif
368 #endif
369 }
370 
DrawTextNG(const RefPtr<NG::Paragraph> & paragraph,const RefPtr<NG::TextPattern> & textPattern)371 void DragWindowOhos::DrawTextNG(const RefPtr<NG::Paragraph>& paragraph, const RefPtr<NG::TextPattern>& textPattern)
372 {
373 #ifdef ENABLE_ROSEN_BACKEND
374     CHECK_NULL_VOID(paragraph);
375     auto surfaceNode = dragWindow_->GetSurfaceNode();
376     rsUiDirector_ = Rosen::RSUIDirector::Create();
377     CHECK_NULL_VOID(rsUiDirector_);
378     rsUiDirector_->Init();
379     auto transactionProxy = Rosen::RSTransactionProxy::GetInstance();
380     if (transactionProxy != nullptr) {
381         transactionProxy->FlushImplicitTransaction();
382     }
383     rsUiDirector_->SetRSSurfaceNode(surfaceNode);
384 
385     rootNode_ = Rosen::RSRootNode::Create();
386     CHECK_NULL_VOID(rootNode_);
387     rootNode_->SetBounds(Window_EXTERN.ConvertToPx(), Window_EXTERN.ConvertToPx(), static_cast<float>(width_),
388         static_cast<float>(height_));
389     rootNode_->SetFrame(Window_EXTERN.ConvertToPx(), Window_EXTERN.ConvertToPx(), static_cast<float>(width_),
390         static_cast<float>(height_));
391     rsUiDirector_->SetRoot(rootNode_->GetId());
392     auto canvasNode = std::static_pointer_cast<Rosen::RSCanvasNode>(rootNode_);
393     CHECK_NULL_VOID(canvasNode);
394     Offset globalOffset;
395     textPattern->GetGlobalOffset(globalOffset);
396     RSRecordingPath path;
397     if (textPattern->GetStartOffset().GetY() == textPattern->GetEndOffset().GetY()) {
398         path.MoveTo(textPattern->GetStartOffset().GetX() - globalOffset.GetX(),
399             textPattern->GetStartOffset().GetY() - globalOffset.GetY());
400         path.LineTo(textPattern->GetEndOffset().GetX() - globalOffset.GetX(),
401             textPattern->GetEndOffset().GetY() - globalOffset.GetY());
402         path.LineTo(textPattern->GetEndOffset().GetX() - globalOffset.GetX(),
403             textPattern->GetEndOffset().GetY() + textPattern->GetSelectHeight() - globalOffset.GetY());
404         path.LineTo(textPattern->GetStartOffset().GetX() - globalOffset.GetX(),
405             textPattern->GetStartOffset().GetY() + textPattern->GetSelectHeight() - globalOffset.GetY());
406         path.LineTo(textPattern->GetStartOffset().GetX() - globalOffset.GetX(),
407             textPattern->GetStartOffset().GetY() - globalOffset.GetY());
408     } else {
409         path.MoveTo(textPattern->GetStartOffset().GetX() - globalOffset.GetX(),
410             textPattern->GetStartOffset().GetY() - globalOffset.GetY());
411         path.LineTo(
412             textPattern->GetTextContentRect().Width(), textPattern->GetStartOffset().GetY() - globalOffset.GetY());
413         path.LineTo(
414             textPattern->GetTextContentRect().Width(), textPattern->GetEndOffset().GetY() - globalOffset.GetY());
415         path.LineTo(textPattern->GetEndOffset().GetX() - globalOffset.GetX(),
416             textPattern->GetEndOffset().GetY() - globalOffset.GetY());
417         path.LineTo(textPattern->GetEndOffset().GetX() - globalOffset.GetX(),
418             textPattern->GetEndOffset().GetY() + textPattern->GetSelectHeight() - globalOffset.GetY());
419         path.LineTo(textPattern->GetTextContentRect().GetX(),
420             textPattern->GetEndOffset().GetY() + textPattern->GetSelectHeight() - globalOffset.GetY());
421         path.LineTo(textPattern->GetTextContentRect().GetX(),
422             textPattern->GetStartOffset().GetY() + textPattern->GetSelectHeight() - globalOffset.GetY());
423         path.LineTo(textPattern->GetStartOffset().GetX() - globalOffset.GetX(),
424             textPattern->GetStartOffset().GetY() + textPattern->GetSelectHeight() - globalOffset.GetY());
425         path.LineTo(textPattern->GetStartOffset().GetX() - globalOffset.GetX(),
426             textPattern->GetStartOffset().GetY() - globalOffset.GetY());
427     }
428     rootNode_->SetClipToBounds(true);
429     rootNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(path));
430     auto recordingCanvas = canvasNode->BeginRecording(width_, height_);
431     paragraph->Paint(*recordingCanvas, textPattern->GetTextContentRect().GetX(),
432         textPattern->GetTextContentRect().GetY() - std::min(textPattern->GetBaselineOffset(), 0.0f));
433     canvasNode->FinishRecording();
434     rsUiDirector_->SendMessages();
435 
436     auto context = NG::PipelineContext::GetCurrentContext();
437     CHECK_NULL_VOID(context);
438     context->RequestFrame();
439 #endif
440 }
441 } // namespace OHOS::Ace
442