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