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 #ifndef USE_GRAPHIC_TEXT_GINE
19 #include "txt/paragraph_txt.h"
20 #else
21 #include "rosen_text/typography.h"
22 #endif
23 
24 #include "include/core/SkCanvas.h"
25 #include "include/core/SkSamplingOptions.h"
26 
27 #include "base/geometry/ng/rect_t.h"
28 #include "base/geometry/offset.h"
29 #include "base/image/pixel_map.h"
30 #include "base/log/log_wrapper.h"
31 #include "base/utils/utils.h"
32 #include "core/components/text/render_text.h"
33 #include "core/components_ng/base/frame_node.h"
34 #include "core/components_ng/pattern/text/text_pattern.h"
35 #include "core/components_ng/render/adapter/rosen_render_context.h"
36 #ifndef USE_ROSEN_DRAWING
37 #include "core/components_ng/render/adapter/skia_image.h"
38 #else
39 #include "core/components_ng/render/adapter/rosen/drawing_image.h"
40 #include "core/components_ng/render/drawing.h"
41 #endif
42 #include "core/pipeline_ng/pipeline_context.h"
43 
44 #ifdef USE_ROSEN_DRAWING
45 using namespace OHOS::Rosen;
46 #endif
47 
48 namespace OHOS::Ace {
49 #ifdef ENABLE_ROSEN_BACKEND
50 namespace {
51 // Adapt text dragging background shadows to expand the width of dargwindow
52 const Dimension Window_EXTERN = 10.0_vp;
53 #ifndef USE_ROSEN_DRAWING
ColorSpaceToSkColorSpace(const RefPtr<PixelMap> & pixmap)54 sk_sp<SkColorSpace> ColorSpaceToSkColorSpace(const RefPtr<PixelMap>& pixmap)
55 {
56     return SkColorSpace::MakeSRGB(); // Media::PixelMap has not support wide gamut yet.
57 }
58 #endif
59 
60 #ifndef USE_ROSEN_DRAWING
AlphaTypeToSkAlphaType(const RefPtr<PixelMap> & pixmap)61 SkAlphaType AlphaTypeToSkAlphaType(const RefPtr<PixelMap>& pixmap)
62 {
63     switch (pixmap->GetAlphaType()) {
64         case AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
65             return SkAlphaType::kUnknown_SkAlphaType;
66         case AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
67             return SkAlphaType::kOpaque_SkAlphaType;
68         case AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
69             return SkAlphaType::kPremul_SkAlphaType;
70         case AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
71             return SkAlphaType::kUnpremul_SkAlphaType;
72         default:
73             return SkAlphaType::kUnknown_SkAlphaType;
74     }
75 }
76 #else
AlphaTypeToAlphaType(const RefPtr<PixelMap> & pixmap)77 RSAlphaType AlphaTypeToAlphaType(const RefPtr<PixelMap>& pixmap)
78 {
79     switch (pixmap->GetAlphaType()) {
80         case AlphaType::IMAGE_ALPHA_TYPE_UNKNOWN:
81             return RSAlphaType::ALPHATYPE_UNKNOWN;
82         case AlphaType::IMAGE_ALPHA_TYPE_OPAQUE:
83             return RSAlphaType::ALPHATYPE_OPAQUE;
84         case AlphaType::IMAGE_ALPHA_TYPE_PREMUL:
85             return RSAlphaType::ALPHATYPE_PREMUL;
86         case AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL:
87             return RSAlphaType::ALPHATYPE_UNPREMUL;
88         default:
89             return RSAlphaType::ALPHATYPE_UNKNOWN;
90     }
91 }
92 #endif
93 
94 #ifndef USE_ROSEN_DRAWING
PixelFormatToSkColorType(const RefPtr<PixelMap> & pixmap)95 SkColorType PixelFormatToSkColorType(const RefPtr<PixelMap>& pixmap)
96 {
97     switch (pixmap->GetPixelFormat()) {
98         case PixelFormat::RGB_565:
99             return SkColorType::kRGB_565_SkColorType;
100         case PixelFormat::RGBA_8888:
101             return SkColorType::kRGBA_8888_SkColorType;
102         case PixelFormat::BGRA_8888:
103             return SkColorType::kBGRA_8888_SkColorType;
104         case PixelFormat::ALPHA_8:
105             return SkColorType::kAlpha_8_SkColorType;
106         case PixelFormat::RGBA_F16:
107             return SkColorType::kRGBA_F16_SkColorType;
108         case PixelFormat::UNKNOWN:
109         case PixelFormat::ARGB_8888:
110         case PixelFormat::RGB_888:
111         case PixelFormat::NV21:
112         case PixelFormat::NV12:
113         case PixelFormat::CMYK:
114         default:
115             return SkColorType::kUnknown_SkColorType;
116     }
117 }
118 #else
PixelFormatToColorType(const RefPtr<PixelMap> & pixmap)119 RSColorType PixelFormatToColorType(const RefPtr<PixelMap>& pixmap)
120 {
121     switch (pixmap->GetPixelFormat()) {
122         case PixelFormat::RGB_565:
123             return RSColorType::COLORTYPE_RGB_565;
124         case PixelFormat::RGBA_8888:
125             return RSColorType::COLORTYPE_RGBA_8888;
126         case PixelFormat::BGRA_8888:
127             return RSColorType::COLORTYPE_BGRA_8888;
128         case PixelFormat::ALPHA_8:
129             return RSColorType::COLORTYPE_ALPHA_8;
130         case PixelFormat::RGBA_F16:
131             return RSColorType::COLORTYPE_RGBA_F16;
132         case PixelFormat::UNKNOWN:
133         case PixelFormat::ARGB_8888:
134         case PixelFormat::RGB_888:
135         case PixelFormat::NV21:
136         case PixelFormat::NV12:
137         case PixelFormat::CMYK:
138         default:
139             return RSColorType::COLORTYPE_UNKNOWN;
140     }
141 }
142 #endif
143 
144 #ifndef USE_ROSEN_DRAWING
MakeSkImageInfoFromPixelMap(const RefPtr<PixelMap> & pixmap)145 SkImageInfo MakeSkImageInfoFromPixelMap(const RefPtr<PixelMap>& pixmap)
146 {
147     SkColorType colorType = PixelFormatToSkColorType(pixmap);
148     SkAlphaType alphaType = AlphaTypeToSkAlphaType(pixmap);
149     sk_sp<SkColorSpace> colorSpace = ColorSpaceToSkColorSpace(pixmap);
150     return SkImageInfo::Make(pixmap->GetWidth(), pixmap->GetHeight(), colorType, alphaType, colorSpace);
151 }
152 #else
MakeBitmapFormatFromPixelMap(const RefPtr<PixelMap> & pixmap)153 RSBitmapFormat MakeBitmapFormatFromPixelMap(const RefPtr<PixelMap>& pixmap)
154 {
155     RSBitmapFormat format;
156     format.colorType = PixelFormatToColorType(pixmap);
157     format.alphaType = AlphaTypeToAlphaType(pixmap);
158     return format;
159 }
160 #endif
161 
162 #ifndef USE_ROSEN_DRAWING
DrawSkImage(SkCanvas * canvas,const sk_sp<SkImage> & skImage,int32_t width,int32_t height)163 void DrawSkImage(SkCanvas* canvas, const sk_sp<SkImage>& skImage, int32_t width, int32_t height)
164 {
165     CHECK_NULL_VOID(skImage);
166     SkPaint paint;
167     sk_sp<SkColorSpace> colorSpace = skImage->refColorSpace();
168     paint.setColor(paint.getColor4f(), colorSpace.get());
169     auto skSrcRect = SkRect::MakeXYWH(0, 0, skImage->width(), skImage->height());
170     auto skDstRect = SkRect::MakeXYWH(0, 0, width, height);
171     canvas->drawImageRect(
172         skImage, skSrcRect, skDstRect, SkSamplingOptions(), &paint, SkCanvas::kFast_SrcRectConstraint);
173 }
174 #else
DrawDrawingImage(RSCanvas * canvas,const std::shared_ptr<RSImage> & drawingImage,int32_t width,int32_t height)175 void DrawDrawingImage(RSCanvas* canvas, const std::shared_ptr<RSImage>& drawingImage, int32_t width, int32_t height)
176 {
177     CHECK_NULL_VOID(drawingImage);
178     RSBrush brush;
179     auto colorSpace = RSRecordingColorSpace::CreateRefImage(*drawingImage);
180     brush.SetColor(brush.GetColor4f(), colorSpace);
181     auto srcRect = RSRect(0, 0, drawingImage->GetWidth(), drawingImage->GetHeight());
182     auto dstRect = RSRect(0, 0, width, height);
183     RSSamplingOptions sampling;
184     canvas->AttachBrush(brush);
185     canvas->DrawImageRect(
186         *drawingImage, srcRect, dstRect, sampling, Drawing::SrcRectConstraint::FAST_SRC_RECT_CONSTRAINT);
187     canvas->DetachBrush();
188 }
189 #endif
190 
191 #ifndef USE_ROSEN_DRAWING
DrawPixelMapInner(SkCanvas * canvas,const RefPtr<PixelMap> & pixmap,int32_t width,int32_t height)192 void DrawPixelMapInner(SkCanvas* canvas, const RefPtr<PixelMap>& pixmap, int32_t width, int32_t height)
193 {
194     // Step1: Create SkPixmap
195     auto imageInfo = MakeSkImageInfoFromPixelMap(pixmap);
196     SkPixmap imagePixmap(imageInfo, reinterpret_cast<const void*>(pixmap->GetPixels()), pixmap->GetRowBytes());
197 
198     // Step2: Create SkImage and draw it
199     sk_sp<SkImage> skImage =
200         SkImage::MakeFromRaster(imagePixmap, &PixelMap::ReleaseProc, PixelMap::GetReleaseContext(pixmap));
201     DrawSkImage(canvas, skImage, width, height);
202 }
203 #else
DrawPixelMapInner(RSCanvas * canvas,const RefPtr<PixelMap> & pixmap,int32_t width,int32_t height)204 void DrawPixelMapInner(RSCanvas* canvas, const RefPtr<PixelMap>& pixmap, int32_t width, int32_t height)
205 {
206     // Step1: Create Bitmap
207     auto bitmapFormat = MakeBitmapFormatFromPixelMap(pixmap);
208     auto bitmap = std::make_shared<RSBitmap>();
209     bitmap->Build(pixmap->GetWidth(), pixmap->GetHeight(), bitmapFormat);
210     bitmap->SetPixels(const_cast<void*>(reinterpret_cast<const void*>(pixmap->GetPixels())));
211 
212     // Step2: Create Image and draw it
213     auto image = std::make_shared<RSImage>();
214     image->BuildFromBitmap(*bitmap);
215     DrawDrawingImage(canvas, image, width, height);
216 }
217 #endif
218 } // namespace
219 #endif
220 
CreateDragWindow(const std::string & windowName,int32_t x,int32_t y,uint32_t width,uint32_t height)221 RefPtr<DragWindow> DragWindow::CreateDragWindow(
222     const std::string& windowName, int32_t x, int32_t y, uint32_t width, uint32_t height)
223 {
224     return CreateDragWindow({ windowName, x, y, width, height });
225 }
226 
CreateDragWindow(const DragWindowParams & params)227 RefPtr<DragWindow> DragWindow::CreateDragWindow(const DragWindowParams& params)
228 {
229     int32_t halfWidth = static_cast<int32_t>(params.width) / 2;
230     int32_t halfHeight = static_cast<int32_t>(params.height) / 2;
231 
232     OHOS::sptr<OHOS::Rosen::WindowOption> option = new OHOS::Rosen::WindowOption();
233     option->SetWindowRect({ params.x - halfWidth, params.y - halfHeight, params.width, params.height });
234     option->SetHitOffset(halfWidth, halfHeight);
235     if (params.parentWindowId == -1) {
236         option->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_DRAGGING_EFFECT);
237     } else {
238         option->SetParentId(params.parentWindowId);
239         option->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_APP_SUB_WINDOW);
240     }
241     option->SetWindowMode(OHOS::Rosen::WindowMode::WINDOW_MODE_FLOATING);
242     option->SetFocusable(false);
243     OHOS::sptr<OHOS::Rosen::Window> dragWindow = OHOS::Rosen::Window::Create(params.windowName, option);
244     CHECK_NULL_RETURN(dragWindow, nullptr);
245 
246     OHOS::Rosen::WMError ret = dragWindow->MoveTo(params.x - halfWidth, params.y - halfHeight, true);
247     if (ret != OHOS::Rosen::WMError::WM_OK) {
248         TAG_LOGE(AceLogTag::ACE_DRAG, "DragWindow MoveTo, drag window move failed, ret: %d", ret);
249         return nullptr;
250     }
251 
252     ret = dragWindow->Show();
253     if (ret != OHOS::Rosen::WMError::WM_OK) {
254         TAG_LOGE(AceLogTag::ACE_DRAG, "DragWindow CreateDragWindow, drag window Show() failed, ret: %d", ret);
255         return nullptr;
256     }
257 
258     auto window = AceType::MakeRefPtr<DragWindowOhos>(dragWindow);
259     window->SetSize(params.width, params.height);
260     return window;
261 }
262 
CreateTextDragWindow(const std::string & windowName,int32_t x,int32_t y,uint32_t width,uint32_t height)263 RefPtr<DragWindow> DragWindow::CreateTextDragWindow(
264     const std::string& windowName, int32_t x, int32_t y, uint32_t width, uint32_t height)
265 {
266     int32_t halfWidth = static_cast<int32_t>(width + Window_EXTERN.ConvertToPx() * 2) / 2;
267     int32_t halfHeight = static_cast<int32_t>(height + Window_EXTERN.ConvertToPx() * 2) / 2;
268 
269     OHOS::sptr<OHOS::Rosen::WindowOption> option = new OHOS::Rosen::WindowOption();
270     option->SetWindowRect({ x - Window_EXTERN.ConvertToPx(), y - Window_EXTERN.ConvertToPx(),
271         width + Window_EXTERN.ConvertToPx() * 2, height + Window_EXTERN.ConvertToPx() * 2 });
272     option->SetHitOffset(halfWidth, halfHeight);
273     option->SetWindowType(OHOS::Rosen::WindowType::WINDOW_TYPE_DRAGGING_EFFECT);
274     option->SetWindowMode(OHOS::Rosen::WindowMode::WINDOW_MODE_FLOATING);
275     option->SetFocusable(false);
276     OHOS::sptr<OHOS::Rosen::Window> dragWindow = OHOS::Rosen::Window::Create(windowName, option);
277     CHECK_NULL_RETURN(dragWindow, nullptr);
278 
279     OHOS::Rosen::WMError ret = dragWindow->Show();
280     if (ret != OHOS::Rosen::WMError::WM_OK) {
281         TAG_LOGE(AceLogTag::ACE_DRAG, "DragWindow CreateTextDragWindow, drag window Show() failed, ret: %d", ret);
282     }
283 
284     auto window = AceType::MakeRefPtr<DragWindowOhos>(dragWindow);
285     window->SetSize(width + Window_EXTERN.ConvertToPx() * 2, height + Window_EXTERN.ConvertToPx() * 2);
286     return window;
287 }
288 
MoveTo(int32_t x,int32_t y) const289 void DragWindowOhos::MoveTo(int32_t x, int32_t y) const
290 {
291     CHECK_NULL_VOID(dragWindow_);
292 
293     OHOS::Rosen::WMError ret = dragWindow_->MoveTo(x + offsetX_ - width_ / 2, y + offsetY_ - height_ / 2, true);
294     if (ret != OHOS::Rosen::WMError::WM_OK) {
295         TAG_LOGE(AceLogTag::ACE_DRAG, "DragWindow MoveTo, drag window move failed, ret: %d", ret);
296         return;
297     }
298 
299     ret = dragWindow_->Show();
300     if (ret != OHOS::Rosen::WMError::WM_OK) {
301         TAG_LOGE(AceLogTag::ACE_DRAG, "DragWindow CreateDragWindow, drag window Show() failed, ret: %d", ret);
302     }
303 }
304 
TextDragWindowMove(double x,double y) const305 void DragWindowOhos::TextDragWindowMove(double x, double y) const
306 {
307     CHECK_NULL_VOID(dragWindow_);
308     OHOS::Rosen::WMError ret =
309         dragWindow_->MoveTo(x - Window_EXTERN.ConvertToPx() + offsetX_, y + offsetY_ - Window_EXTERN.ConvertToPx());
310     if (ret != OHOS::Rosen::WMError::WM_OK) {
311         TAG_LOGE(AceLogTag::ACE_DRAG, "DragWindow TextDragWindowMove, drag window move failed, ret: %d", ret);
312         return;
313     }
314 
315     ret = dragWindow_->Show();
316     if (ret != OHOS::Rosen::WMError::WM_OK) {
317         TAG_LOGE(AceLogTag::ACE_DRAG, "DragWindow TextDragWindowMove, drag window Show() failed, ret: %d", ret);
318     }
319 }
320 
Destroy() const321 void DragWindowOhos::Destroy() const
322 {
323     CHECK_NULL_VOID(dragWindow_);
324 
325     OHOS::Rosen::WMError ret = dragWindow_->Destroy();
326     if (ret != OHOS::Rosen::WMError::WM_OK) {
327         TAG_LOGE(AceLogTag::ACE_DRAG, "DragWindow Destroy, drag window destroy failed, ret: %d", ret);
328     }
329 }
330 
DrawFrameNode(const RefPtr<NG::FrameNode> & rootNode)331 void DragWindowOhos::DrawFrameNode(const RefPtr<NG::FrameNode>& rootNode)
332 {
333 #ifdef ENABLE_ROSEN_BACKEND
334     CHECK_NULL_VOID(rootNode);
335 
336     auto surfaceNode = dragWindow_->GetSurfaceNode();
337     rsUiDirector_ = Rosen::RSUIDirector::Create();
338     rsUiDirector_->Init();
339     auto transactionProxy = Rosen::RSTransactionProxy::GetInstance();
340     if (transactionProxy != nullptr) {
341         transactionProxy->FlushImplicitTransaction();
342     }
343     rsUiDirector_->SetRSSurfaceNode(surfaceNode);
344 
345     auto renderContext = AceType::DynamicCast<NG::RosenRenderContext>(rootNode->GetRenderContext());
346     CHECK_NULL_VOID(renderContext);
347     auto rsNode = renderContext->GetRSNode();
348     CHECK_NULL_VOID(rsNode);
349 
350     rsUiDirector_->SetRoot(rsNode->GetId());
351     rsUiDirector_->SendMessages();
352 #endif
353 }
354 
DrawPixelMap(const RefPtr<PixelMap> & pixelmap)355 void DragWindowOhos::DrawPixelMap(const RefPtr<PixelMap>& pixelmap)
356 {
357 #ifdef ENABLE_ROSEN_BACKEND
358     CHECK_NULL_VOID(pixelmap);
359     auto surfaceNode = dragWindow_->GetSurfaceNode();
360     rsUiDirector_ = Rosen::RSUIDirector::Create();
361     rsUiDirector_->Init();
362     auto transactionProxy = Rosen::RSTransactionProxy::GetInstance();
363     if (transactionProxy != nullptr) {
364         transactionProxy->FlushImplicitTransaction();
365     }
366     rsUiDirector_->SetRSSurfaceNode(surfaceNode);
367     rootNode_ = Rosen::RSRootNode::Create();
368     rootNode_->SetBounds(0, 0, static_cast<float>(width_), static_cast<float>(height_));
369     rootNode_->SetFrame(0, 0, static_cast<float>(width_), static_cast<float>(height_));
370     rsUiDirector_->SetRoot(rootNode_->GetId());
371     auto canvasNode = std::static_pointer_cast<Rosen::RSCanvasNode>(rootNode_);
372     auto drawing = canvasNode->BeginRecording(width_, height_);
373     DrawPixelMapInner(drawing, pixelmap, width_, height_);
374     canvasNode->FinishRecording();
375     rsUiDirector_->SendMessages();
376 #endif
377 }
378 
379 #ifndef USE_ROSEN_DRAWING
DrawImage(void * skImage)380 void DragWindowOhos::DrawImage(void* skImage)
381 {
382 #ifdef ENABLE_ROSEN_BACKEND
383     CHECK_NULL_VOID(skImage);
384     auto* canvasImagePtr = reinterpret_cast<RefPtr<NG::CanvasImage>*>(skImage);
385     CHECK_NULL_VOID(canvasImagePtr);
386     RefPtr<NG::SkiaImage> canvasImage = AceType::DynamicCast<NG::SkiaImage>(*canvasImagePtr);
387     CHECK_NULL_VOID(canvasImage);
388     auto surfaceNode = dragWindow_->GetSurfaceNode();
389     rsUiDirector_ = Rosen::RSUIDirector::Create();
390     rsUiDirector_->Init();
391     auto transactionProxy = Rosen::RSTransactionProxy::GetInstance();
392     if (transactionProxy != nullptr) {
393         transactionProxy->FlushImplicitTransaction();
394     }
395     rsUiDirector_->SetRSSurfaceNode(surfaceNode);
396     rootNode_ = Rosen::RSRootNode::Create();
397     rootNode_->SetBounds(0, 0, static_cast<float>(width_), static_cast<float>(height_));
398     rootNode_->SetFrame(0, 0, static_cast<float>(width_), static_cast<float>(height_));
399     rsUiDirector_->SetRoot(rootNode_->GetId());
400     auto canvasNode = std::static_pointer_cast<Rosen::RSCanvasNode>(rootNode_);
401     auto skia = canvasNode->BeginRecording(width_, height_);
402     DrawSkImage(skia, canvasImage->GetImage(), width_, height_);
403     canvasNode->FinishRecording();
404     rsUiDirector_->SendMessages();
405 #endif
406 }
407 #else
DrawImage(void * drawingImage)408 void DragWindowOhos::DrawImage(void* drawingImage)
409 {
410 #ifdef ENABLE_ROSEN_BACKEND
411     CHECK_NULL_VOID(drawingImage);
412     auto* canvasImagePtr = reinterpret_cast<RefPtr<NG::CanvasImage>*>(drawingImage);
413     CHECK_NULL_VOID(canvasImagePtr);
414     RefPtr<NG::DrawingImage> canvasImage = AceType::DynamicCast<NG::DrawingImage>(*canvasImagePtr);
415     CHECK_NULL_VOID(canvasImage);
416     auto surfaceNode = dragWindow_->GetSurfaceNode();
417     rsUiDirector_ = Rosen::RSUIDirector::Create();
418     rsUiDirector_->Init();
419     auto transactionProxy = Rosen::RSTransactionProxy::GetInstance();
420     if (transactionProxy != nullptr) {
421         transactionProxy->FlushImplicitTransaction();
422     }
423     rsUiDirector_->SetRSSurfaceNode(surfaceNode);
424     rootNode_ = Rosen::RSRootNode::Create();
425     rootNode_->SetBounds(0, 0, static_cast<float>(width_), static_cast<float>(height_));
426     rootNode_->SetFrame(0, 0, static_cast<float>(width_), static_cast<float>(height_));
427     rsUiDirector_->SetRoot(rootNode_->GetId());
428     auto canvasNode = std::static_pointer_cast<Rosen::RSCanvasNode>(rootNode_);
429     auto drawing = canvasNode->BeginRecording(width_, height_);
430     auto rsImage = canvasImage->GetImage();
431     DrawDrawingImage(drawing, rsImage, width_, height_);
432     canvasNode->FinishRecording();
433     rsUiDirector_->SendMessages();
434 #endif
435 }
436 #endif
437 
438 #ifndef USE_GRAPHIC_TEXT_GINE
DrawText(std::shared_ptr<txt::Paragraph> paragraph,const Offset & offset,const RefPtr<RenderText> & renderText)439 void DragWindowOhos::DrawText(
440     std::shared_ptr<txt::Paragraph> paragraph, const Offset& offset, const RefPtr<RenderText>& renderText)
441 #else
442 void DragWindowOhos::DrawText(
443     std::shared_ptr<Rosen::Typography> paragraph, const Offset& offset, const RefPtr<RenderText>& renderText)
444 #endif
445 {
446 #ifndef NG_BUILD
447 #ifdef ENABLE_ROSEN_BACKEND
448     CHECK_NULL_VOID(paragraph);
449     auto surfaceNode = dragWindow_->GetSurfaceNode();
450     rsUiDirector_ = Rosen::RSUIDirector::Create();
451     rsUiDirector_->Init();
452     auto transactionProxy = Rosen::RSTransactionProxy::GetInstance();
453     if (transactionProxy != nullptr) {
454         transactionProxy->FlushImplicitTransaction();
455     }
456     rsUiDirector_->SetRSSurfaceNode(surfaceNode);
457     rootNode_ = Rosen::RSRootNode::Create();
458     rootNode_->SetBounds(0, 0, static_cast<float>(width_), static_cast<float>(height_));
459     rootNode_->SetFrame(0, 0, static_cast<float>(width_), static_cast<float>(height_));
460     rsUiDirector_->SetRoot(rootNode_->GetId());
461     auto canvasNode = std::static_pointer_cast<Rosen::RSCanvasNode>(rootNode_);
462 #ifndef USE_ROSEN_DRAWING
463     SkPath path;
464     if (renderText->GetStartOffset().GetY() == renderText->GetEndOffset().GetY()) {
465         path.moveTo(renderText->GetStartOffset().GetX() - renderText->GetGlobalOffset().GetX(),
466             renderText->GetStartOffset().GetY() - renderText->GetGlobalOffset().GetY());
467         path.lineTo(renderText->GetEndOffset().GetX() - renderText->GetGlobalOffset().GetX(),
468             renderText->GetEndOffset().GetY() - renderText->GetGlobalOffset().GetY());
469         path.lineTo(renderText->GetEndOffset().GetX() - renderText->GetGlobalOffset().GetX(),
470             renderText->GetEndOffset().GetY() - renderText->GetSelectHeight() - renderText->GetGlobalOffset().GetY());
471         path.lineTo(renderText->GetStartOffset().GetX() - renderText->GetGlobalOffset().GetX(),
472             renderText->GetStartOffset().GetY() - renderText->GetSelectHeight() - renderText->GetGlobalOffset().GetY());
473         path.lineTo(renderText->GetStartOffset().GetX() - renderText->GetGlobalOffset().GetX(),
474             renderText->GetStartOffset().GetY() - renderText->GetGlobalOffset().GetY());
475     } else {
476         path.moveTo(renderText->GetStartOffset().GetX() - renderText->GetGlobalOffset().GetX(),
477             renderText->GetStartOffset().GetY() - renderText->GetGlobalOffset().GetY());
478         path.lineTo(renderText->GetStartOffset().GetX() - renderText->GetGlobalOffset().GetX(),
479             renderText->GetStartOffset().GetY() - renderText->GetSelectHeight() - renderText->GetGlobalOffset().GetY());
480         path.lineTo(renderText->GetPaintRect().Width(),
481             renderText->GetStartOffset().GetY() - renderText->GetSelectHeight() - renderText->GetGlobalOffset().GetY());
482         path.lineTo(renderText->GetPaintRect().Width(),
483             renderText->GetEndOffset().GetY() - renderText->GetSelectHeight() - renderText->GetGlobalOffset().GetY());
484         path.lineTo(renderText->GetEndOffset().GetX() - renderText->GetGlobalOffset().GetX(),
485             renderText->GetEndOffset().GetY() - renderText->GetSelectHeight() - renderText->GetGlobalOffset().GetY());
486         path.lineTo(renderText->GetEndOffset().GetX() - renderText->GetGlobalOffset().GetX(),
487             renderText->GetEndOffset().GetY() - renderText->GetGlobalOffset().GetY());
488         path.lineTo(renderText->GetPaintRect().Left() - renderText->GetGlobalOffset().GetX(),
489             renderText->GetEndOffset().GetY() - renderText->GetGlobalOffset().GetY());
490         path.lineTo(renderText->GetPaintRect().Left() - renderText->GetGlobalOffset().GetX(),
491             renderText->GetStartOffset().GetY() - renderText->GetGlobalOffset().GetY());
492         path.lineTo(renderText->GetStartOffset().GetX() - renderText->GetGlobalOffset().GetX(),
493             renderText->GetStartOffset().GetY() - renderText->GetGlobalOffset().GetY());
494     }
495 #else
496     RSRecordingPath path;
497     if (renderText->GetStartOffset().GetY() == renderText->GetEndOffset().GetY()) {
498         path.MoveTo(renderText->GetStartOffset().GetX() - renderText->GetGlobalOffset().GetX(),
499             renderText->GetStartOffset().GetY() - renderText->GetGlobalOffset().GetY());
500         path.LineTo(renderText->GetEndOffset().GetX() - renderText->GetGlobalOffset().GetX(),
501             renderText->GetEndOffset().GetY() - renderText->GetGlobalOffset().GetY());
502         path.LineTo(renderText->GetEndOffset().GetX() - renderText->GetGlobalOffset().GetX(),
503             renderText->GetEndOffset().GetY() - renderText->GetSelectHeight() - renderText->GetGlobalOffset().GetY());
504         path.LineTo(renderText->GetStartOffset().GetX() - renderText->GetGlobalOffset().GetX(),
505             renderText->GetStartOffset().GetY() - renderText->GetSelectHeight() - renderText->GetGlobalOffset().GetY());
506         path.LineTo(renderText->GetStartOffset().GetX() - renderText->GetGlobalOffset().GetX(),
507             renderText->GetStartOffset().GetY() - renderText->GetGlobalOffset().GetY());
508     } else {
509         path.MoveTo(renderText->GetStartOffset().GetX() - renderText->GetGlobalOffset().GetX(),
510             renderText->GetStartOffset().GetY() - renderText->GetGlobalOffset().GetY());
511         path.LineTo(renderText->GetStartOffset().GetX() - renderText->GetGlobalOffset().GetX(),
512             renderText->GetStartOffset().GetY() - renderText->GetSelectHeight() - renderText->GetGlobalOffset().GetY());
513         path.LineTo(renderText->GetPaintRect().Right() - renderText->GetGlobalOffset().GetX(),
514             renderText->GetStartOffset().GetY() - renderText->GetSelectHeight() - renderText->GetGlobalOffset().GetY());
515         path.LineTo(renderText->GetPaintRect().Right() - renderText->GetGlobalOffset().GetX(),
516             renderText->GetEndOffset().GetY() - renderText->GetSelectHeight() - renderText->GetGlobalOffset().GetY());
517         path.LineTo(renderText->GetEndOffset().GetX() - renderText->GetGlobalOffset().GetX(),
518             renderText->GetEndOffset().GetY() - renderText->GetSelectHeight() - renderText->GetGlobalOffset().GetY());
519         path.LineTo(renderText->GetEndOffset().GetX() - renderText->GetGlobalOffset().GetX(),
520             renderText->GetEndOffset().GetY() - renderText->GetGlobalOffset().GetY());
521         path.LineTo(renderText->GetPaintRect().Left() - renderText->GetGlobalOffset().GetX(),
522             renderText->GetEndOffset().GetY() - renderText->GetGlobalOffset().GetY());
523         path.LineTo(renderText->GetPaintRect().Left() - renderText->GetGlobalOffset().GetX(),
524             renderText->GetStartOffset().GetY() - renderText->GetGlobalOffset().GetY());
525         path.LineTo(renderText->GetStartOffset().GetX() - renderText->GetGlobalOffset().GetX(),
526             renderText->GetStartOffset().GetY() - renderText->GetGlobalOffset().GetY());
527     }
528 #endif
529     rootNode_->SetClipToBounds(true);
530     rootNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(path));
531     auto recordingCanvas = canvasNode->BeginRecording(width_, height_);
532     paragraph->Paint(recordingCanvas, 0, 0);
533     canvasNode->FinishRecording();
534     rsUiDirector_->SendMessages();
535 #endif
536 #endif
537 }
538 
DrawTextNG(const RefPtr<NG::Paragraph> & paragraph,const RefPtr<NG::TextPattern> & textPattern)539 void DragWindowOhos::DrawTextNG(const RefPtr<NG::Paragraph>& paragraph, const RefPtr<NG::TextPattern>& textPattern)
540 {
541 #ifdef ENABLE_ROSEN_BACKEND
542     CHECK_NULL_VOID(paragraph);
543     auto surfaceNode = dragWindow_->GetSurfaceNode();
544     rsUiDirector_ = Rosen::RSUIDirector::Create();
545     CHECK_NULL_VOID(rsUiDirector_);
546     rsUiDirector_->Init();
547     auto transactionProxy = Rosen::RSTransactionProxy::GetInstance();
548     if (transactionProxy != nullptr) {
549         transactionProxy->FlushImplicitTransaction();
550     }
551     rsUiDirector_->SetRSSurfaceNode(surfaceNode);
552 
553     rootNode_ = Rosen::RSRootNode::Create();
554     CHECK_NULL_VOID(rootNode_);
555     rootNode_->SetBounds(Window_EXTERN.ConvertToPx(), Window_EXTERN.ConvertToPx(), static_cast<float>(width_),
556         static_cast<float>(height_));
557     rootNode_->SetFrame(Window_EXTERN.ConvertToPx(), Window_EXTERN.ConvertToPx(), static_cast<float>(width_),
558         static_cast<float>(height_));
559     rsUiDirector_->SetRoot(rootNode_->GetId());
560     auto canvasNode = std::static_pointer_cast<Rosen::RSCanvasNode>(rootNode_);
561     CHECK_NULL_VOID(canvasNode);
562     Offset globalOffset;
563     textPattern->GetGlobalOffset(globalOffset);
564 #ifndef USE_ROSEN_DRAWING
565     SkPath path;
566     if (textPattern->GetStartOffset().GetY() == textPattern->GetEndOffset().GetY()) {
567         path.moveTo(textPattern->GetStartOffset().GetX() - globalOffset.GetX(),
568             textPattern->GetStartOffset().GetY() - globalOffset.GetY());
569         path.lineTo(textPattern->GetEndOffset().GetX() - globalOffset.GetX(),
570             textPattern->GetEndOffset().GetY() - globalOffset.GetY());
571         path.lineTo(textPattern->GetEndOffset().GetX() - globalOffset.GetX(),
572             textPattern->GetEndOffset().GetY() + textPattern->GetSelectHeight() - globalOffset.GetY());
573         path.lineTo(textPattern->GetStartOffset().GetX() - globalOffset.GetX(),
574             textPattern->GetStartOffset().GetY() + textPattern->GetSelectHeight() - globalOffset.GetY());
575         path.lineTo(textPattern->GetStartOffset().GetX() - globalOffset.GetX(),
576             textPattern->GetStartOffset().GetY() - globalOffset.GetY());
577     } else {
578         path.moveTo(textPattern->GetStartOffset().GetX() - globalOffset.GetX(),
579             textPattern->GetStartOffset().GetY() - globalOffset.GetY());
580         path.lineTo(
581             textPattern->GetTextContentRect().Width(), textPattern->GetStartOffset().GetY() - globalOffset.GetY());
582         path.lineTo(
583             textPattern->GetTextContentRect().Width(), textPattern->GetEndOffset().GetY() - globalOffset.GetY());
584         path.lineTo(textPattern->GetEndOffset().GetX() - globalOffset.GetX(),
585             textPattern->GetEndOffset().GetY() - globalOffset.GetY());
586         path.lineTo(textPattern->GetEndOffset().GetX() - globalOffset.GetX(),
587             textPattern->GetEndOffset().GetY() + textPattern->GetSelectHeight() - globalOffset.GetY());
588         path.lineTo(textPattern->GetTextContentRect().GetX(),
589             textPattern->GetEndOffset().GetY() + textPattern->GetSelectHeight() - globalOffset.GetY());
590         path.lineTo(textPattern->GetTextContentRect().GetX(),
591             textPattern->GetStartOffset().GetY() + textPattern->GetSelectHeight() - globalOffset.GetY());
592         path.lineTo(textPattern->GetStartOffset().GetX() - globalOffset.GetX(),
593             textPattern->GetStartOffset().GetY() + textPattern->GetSelectHeight() - globalOffset.GetY());
594         path.lineTo(textPattern->GetStartOffset().GetX() - globalOffset.GetX(),
595             textPattern->GetStartOffset().GetY() - globalOffset.GetY());
596     }
597     rootNode_->SetClipToBounds(true);
598     rootNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(path));
599 
600     auto skia = canvasNode->BeginRecording(width_, height_);
601     paragraph->Paint(skia, textPattern->GetTextContentRect().GetX(),
602         textPattern->GetTextContentRect().GetY() - std::min(textPattern->GetBaselineOffset(), 0.0f));
603 #else
604     RSRecordingPath path;
605     if (textPattern->GetStartOffset().GetY() == textPattern->GetEndOffset().GetY()) {
606         path.MoveTo(textPattern->GetStartOffset().GetX() - globalOffset.GetX(),
607             textPattern->GetStartOffset().GetY() - globalOffset.GetY());
608         path.LineTo(textPattern->GetEndOffset().GetX() - globalOffset.GetX(),
609             textPattern->GetEndOffset().GetY() - globalOffset.GetY());
610         path.LineTo(textPattern->GetEndOffset().GetX() - globalOffset.GetX(),
611             textPattern->GetEndOffset().GetY() + textPattern->GetSelectHeight() - globalOffset.GetY());
612         path.LineTo(textPattern->GetStartOffset().GetX() - globalOffset.GetX(),
613             textPattern->GetStartOffset().GetY() + textPattern->GetSelectHeight() - globalOffset.GetY());
614         path.LineTo(textPattern->GetStartOffset().GetX() - globalOffset.GetX(),
615             textPattern->GetStartOffset().GetY() - globalOffset.GetY());
616     } else {
617         path.MoveTo(textPattern->GetStartOffset().GetX() - globalOffset.GetX(),
618             textPattern->GetStartOffset().GetY() - globalOffset.GetY());
619         path.LineTo(
620             textPattern->GetTextContentRect().Width(), textPattern->GetStartOffset().GetY() - globalOffset.GetY());
621         path.LineTo(
622             textPattern->GetTextContentRect().Width(), textPattern->GetEndOffset().GetY() - globalOffset.GetY());
623         path.LineTo(textPattern->GetEndOffset().GetX() - globalOffset.GetX(),
624             textPattern->GetEndOffset().GetY() - globalOffset.GetY());
625         path.LineTo(textPattern->GetEndOffset().GetX() - globalOffset.GetX(),
626             textPattern->GetEndOffset().GetY() + textPattern->GetSelectHeight() - globalOffset.GetY());
627         path.LineTo(textPattern->GetTextContentRect().GetX(),
628             textPattern->GetEndOffset().GetY() + textPattern->GetSelectHeight() - globalOffset.GetY());
629         path.LineTo(textPattern->GetTextContentRect().GetX(),
630             textPattern->GetStartOffset().GetY() + textPattern->GetSelectHeight() - globalOffset.GetY());
631         path.LineTo(textPattern->GetStartOffset().GetX() - globalOffset.GetX(),
632             textPattern->GetStartOffset().GetY() + textPattern->GetSelectHeight() - globalOffset.GetY());
633         path.LineTo(textPattern->GetStartOffset().GetX() - globalOffset.GetX(),
634             textPattern->GetStartOffset().GetY() - globalOffset.GetY());
635     }
636     rootNode_->SetClipToBounds(true);
637     rootNode_->SetClipBounds(Rosen::RSPath::CreateRSPath(path));
638     auto recordingCanvas = canvasNode->BeginRecording(width_, height_);
639     paragraph->Paint(*recordingCanvas, textPattern->GetTextContentRect().GetX(),
640         textPattern->GetTextContentRect().GetY() - std::min(textPattern->GetBaselineOffset(), 0.0f));
641 #endif
642     canvasNode->FinishRecording();
643     rsUiDirector_->SendMessages();
644 
645     auto context = NG::PipelineContext::GetCurrentContext();
646     CHECK_NULL_VOID(context);
647     context->RequestFrame();
648 #endif
649 }
650 } // namespace OHOS::Ace
651