1e9297d28Sopenharmony_ci/*
2e9297d28Sopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd.. All rights reserved.
3e9297d28Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e9297d28Sopenharmony_ci * you may not use this file except in compliance with the License.
5e9297d28Sopenharmony_ci * You may obtain a copy of the License at
6e9297d28Sopenharmony_ci *
7e9297d28Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e9297d28Sopenharmony_ci *
9e9297d28Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e9297d28Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e9297d28Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e9297d28Sopenharmony_ci * See the License for the specific language governing permissions and
13e9297d28Sopenharmony_ci * limitations under the License.
14e9297d28Sopenharmony_ci */
15e9297d28Sopenharmony_ci
16e9297d28Sopenharmony_ci#include <cinttypes>
17e9297d28Sopenharmony_ci#include <codecvt>
18e9297d28Sopenharmony_ci#include <cstdio>
19e9297d28Sopenharmony_ci#include <cstdlib>
20e9297d28Sopenharmony_ci#include <fstream>
21e9297d28Sopenharmony_ci#include <iostream>
22e9297d28Sopenharmony_ci#include <locale>
23e9297d28Sopenharmony_ci#include <memory>
24e9297d28Sopenharmony_ci#include <securec.h>
25e9297d28Sopenharmony_ci#include <sstream>
26e9297d28Sopenharmony_ci#include <string>
27e9297d28Sopenharmony_ci#include <surface.h>
28e9297d28Sopenharmony_ci#include <unistd.h>
29e9297d28Sopenharmony_ci
30e9297d28Sopenharmony_ci#include "command/rs_base_node_command.h"
31e9297d28Sopenharmony_ci#include "command/rs_display_node_command.h"
32e9297d28Sopenharmony_ci#include "command/rs_surface_node_command.h"
33e9297d28Sopenharmony_ci#include "common/rs_common_def.h"
34e9297d28Sopenharmony_ci#include "core/transaction/rs_interfaces.h"
35e9297d28Sopenharmony_ci#include "core/ui/rs_display_node.h"
36e9297d28Sopenharmony_ci#include "core/ui/rs_surface_node.h"
37e9297d28Sopenharmony_ci#include "draw/canvas.h"
38e9297d28Sopenharmony_ci#include "draw/pen.h"
39e9297d28Sopenharmony_ci#include "foundation/graphic/graphic_2d/rosen/modules/render_service_base/src/platform/ohos/rs_surface_frame_ohos.h"
40e9297d28Sopenharmony_ci#include "foundation/graphic/graphic_2d/rosen/modules/render_service_base/src/platform/ohos/rs_surface_ohos.h"
41e9297d28Sopenharmony_ci#include "image/bitmap.h"
42e9297d28Sopenharmony_ci#include "pipeline/rs_render_result.h"
43e9297d28Sopenharmony_ci#include "pipeline/rs_render_thread.h"
44e9297d28Sopenharmony_ci#include "rosen_text/properties/text_style.h"
45e9297d28Sopenharmony_ci#include "rosen_text/properties/typography_properties.h"
46e9297d28Sopenharmony_ci#include "rosen_text/ui/font_collection.h"
47e9297d28Sopenharmony_ci#include "rosen_text/ui/typography.h"
48e9297d28Sopenharmony_ci#include "rosen_text/ui/typography_create.h"
49e9297d28Sopenharmony_ci#include "ui/rs_canvas_node.h"
50e9297d28Sopenharmony_ci#include "ui/rs_surface_extractor.h"
51e9297d28Sopenharmony_ci#include "ui/rs_ui_director.h"
52e9297d28Sopenharmony_ci
53e9297d28Sopenharmony_ciusing namespace std;
54e9297d28Sopenharmony_ciusing namespace OHOS;
55e9297d28Sopenharmony_ciusing namespace Rosen;
56e9297d28Sopenharmony_ciusing namespace rosen;
57e9297d28Sopenharmony_ciusing namespace Drawing;
58e9297d28Sopenharmony_ciusing namespace Media;
59e9297d28Sopenharmony_ci
60e9297d28Sopenharmony_cistd::u16string TextToUtf16(std::string str)
61e9297d28Sopenharmony_ci{
62e9297d28Sopenharmony_ci    return std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> {}.from_bytes(str);
63e9297d28Sopenharmony_ci}
64e9297d28Sopenharmony_ci
65e9297d28Sopenharmony_civoid DoDraw(uint8_t *addr, uint32_t width, uint32_t height, size_t index)
66e9297d28Sopenharmony_ci{
67e9297d28Sopenharmony_ci    Bitmap bitmapCache;
68e9297d28Sopenharmony_ci    BitmapFormat format {COLORTYPE_RGBA_8888, ALPHATYPE_OPAQUE};
69e9297d28Sopenharmony_ci    bitmapCache.Build(width, height, format);
70e9297d28Sopenharmony_ci
71e9297d28Sopenharmony_ci    Canvas canvas;
72e9297d28Sopenharmony_ci    canvas.Bind(bitmapCache);
73e9297d28Sopenharmony_ci    canvas.Clear(Drawing::Color::COLOR_WHITE);
74e9297d28Sopenharmony_ci    TypographyStyle typoStype;
75e9297d28Sopenharmony_ci    typoStype.textDirection_ = TextDirection::LTR;
76e9297d28Sopenharmony_ci    typoStype.textAlign_ = TextAlign::START;
77e9297d28Sopenharmony_ci    typoStype.maxLines_ = 1000; // maxLines 1000
78e9297d28Sopenharmony_ci    typoStype.locale_ = "en";
79e9297d28Sopenharmony_ci    typoStype.wordBreakType_ = WordBreakType::WordBreakTypeBreakWord;
80e9297d28Sopenharmony_ci    std::unique_ptr<TypographyCreate> builder = TypographyCreate::CreateRosenBuilder(
81e9297d28Sopenharmony_ci        typoStype, FontCollection::GetInstance());
82e9297d28Sopenharmony_ci    TextStyle textStyle;
83e9297d28Sopenharmony_ci
84e9297d28Sopenharmony_ci    textStyle.fontFamilies_ = std::vector<std::string>(1, "Roboto");
85e9297d28Sopenharmony_ci    textStyle.color_ = Drawing::Color::COLOR_BLACK;
86e9297d28Sopenharmony_ci    builder->PushStyle(textStyle);
87e9297d28Sopenharmony_ci    const std::string utf8 = "hello world!\n";
88e9297d28Sopenharmony_ci
89e9297d28Sopenharmony_ci    const std::u16string u16Text = TextToUtf16(utf8);
90e9297d28Sopenharmony_ci    builder->AddText(u16Text);
91e9297d28Sopenharmony_ci    builder->Pop();
92e9297d28Sopenharmony_ci    // layout
93e9297d28Sopenharmony_ci    std::unique_ptr<rosen::Typography> typography;
94e9297d28Sopenharmony_ci    typography = builder->Build();
95e9297d28Sopenharmony_ci    if (typography == nullptr) {
96e9297d28Sopenharmony_ci        LOGD("typography == nullptr");
97e9297d28Sopenharmony_ci        return;
98e9297d28Sopenharmony_ci    }
99e9297d28Sopenharmony_ci    double lastLayoutMaxWidth = 1000.0; // width 1000.0
100e9297d28Sopenharmony_ci    typography->Layout(lastLayoutMaxWidth);
101e9297d28Sopenharmony_ci    typography->Paint(&canvas, 10.0, 15.0); // pos to paint 10.0, 15.0
102e9297d28Sopenharmony_ci    constexpr uint32_t stride = 4;
103e9297d28Sopenharmony_ci    int32_t addrSize = width * height * stride;
104e9297d28Sopenharmony_ci    auto ret = memcpy_s(addr, addrSize, bitmapCache.GetPixels(), addrSize);
105e9297d28Sopenharmony_ci    if (ret != EOK) {
106e9297d28Sopenharmony_ci        LOGD("memcpy_s failed");
107e9297d28Sopenharmony_ci    }
108e9297d28Sopenharmony_ci}
109e9297d28Sopenharmony_ci
110e9297d28Sopenharmony_civoid DrawSurface(std::shared_ptr<RSSurfaceNode> surfaceNode, int32_t width, int32_t height, size_t index)
111e9297d28Sopenharmony_ci{
112e9297d28Sopenharmony_ci    sptr<OHOS::Surface> surface = surfaceNode->GetSurface();
113e9297d28Sopenharmony_ci    if (surface == nullptr) {
114e9297d28Sopenharmony_ci        return;
115e9297d28Sopenharmony_ci    }
116e9297d28Sopenharmony_ci
117e9297d28Sopenharmony_ci    sptr<OHOS::SurfaceBuffer> buffer;
118e9297d28Sopenharmony_ci    int32_t releaseFence;
119e9297d28Sopenharmony_ci    OHOS::BufferRequestConfig config = {
120e9297d28Sopenharmony_ci        .width = width,
121e9297d28Sopenharmony_ci        .height = height,
122e9297d28Sopenharmony_ci        .strideAlignment = 0x8,
123e9297d28Sopenharmony_ci        .format = GRAPHIC_PIXEL_FMT_RGBA_8888,
124e9297d28Sopenharmony_ci        .usage = BUFFER_USAGE_CPU_READ | BUFFER_USAGE_CPU_WRITE | BUFFER_USAGE_MEM_DMA,
125e9297d28Sopenharmony_ci    };
126e9297d28Sopenharmony_ci
127e9297d28Sopenharmony_ci    OHOS::SurfaceError ret = surface->RequestBuffer(buffer, releaseFence, config);
128e9297d28Sopenharmony_ci    LOGD("request buffer ret is: %{public}s", SurfaceErrorStr(ret).c_str());
129e9297d28Sopenharmony_ci
130e9297d28Sopenharmony_ci    if (buffer == nullptr) {
131e9297d28Sopenharmony_ci        LOGD("request buffer failed: buffer is nullptr");
132e9297d28Sopenharmony_ci        return;
133e9297d28Sopenharmony_ci    }
134e9297d28Sopenharmony_ci    if (buffer->GetVirAddr() == nullptr) {
135e9297d28Sopenharmony_ci        LOGD("get virAddr failed: virAddr is nullptr");
136e9297d28Sopenharmony_ci        return;
137e9297d28Sopenharmony_ci    }
138e9297d28Sopenharmony_ci
139e9297d28Sopenharmony_ci    auto addr = static_cast<uint8_t *>(buffer->GetVirAddr());
140e9297d28Sopenharmony_ci    LOGD("buffer width:%{public}d, height:%{public}d", buffer->GetWidth(), buffer->GetHeight());
141e9297d28Sopenharmony_ci
142e9297d28Sopenharmony_ci    DoDraw(addr, buffer->GetWidth(), buffer->GetHeight(), index);
143e9297d28Sopenharmony_ci    LOGD("DoDraw end");
144e9297d28Sopenharmony_ci
145e9297d28Sopenharmony_ci    OHOS::BufferFlushConfig flushConfig = {
146e9297d28Sopenharmony_ci        .damage = {
147e9297d28Sopenharmony_ci            .w = buffer->GetWidth(),
148e9297d28Sopenharmony_ci            .h = buffer->GetHeight(),
149e9297d28Sopenharmony_ci        },
150e9297d28Sopenharmony_ci    };
151e9297d28Sopenharmony_ci    ret = surface->FlushBuffer(buffer, -1, flushConfig);
152e9297d28Sopenharmony_ci    LOGD("draw pointer FlushBuffer ret is: %{public}s", SurfaceErrorStr(ret).c_str());
153e9297d28Sopenharmony_ci}
154e9297d28Sopenharmony_ci
155e9297d28Sopenharmony_cistd::shared_ptr<RSSurfaceNode> CreateSurface()
156e9297d28Sopenharmony_ci{
157e9297d28Sopenharmony_ci    RSSurfaceNodeConfig config;
158e9297d28Sopenharmony_ci    return RSSurfaceNode::Create(config);
159e9297d28Sopenharmony_ci}
160e9297d28Sopenharmony_ci
161e9297d28Sopenharmony_ciint main(int argc, char** argv)
162e9297d28Sopenharmony_ci{
163e9297d28Sopenharmony_ci    auto surfaceNode = CreateSurface();
164e9297d28Sopenharmony_ci    RSDisplayNodeConfig config;
165e9297d28Sopenharmony_ci    RSDisplayNode::SharedPtr displayNode = RSDisplayNode::Create(config);
166e9297d28Sopenharmony_ci    for (size_t i = 0; i < 5; i++) { // Draw 5 times
167e9297d28Sopenharmony_ci        sleep(2); // delay 2 second
168e9297d28Sopenharmony_ci        displayNode->AddChild(surfaceNode, -1);
169e9297d28Sopenharmony_ci        surfaceNode->SetBounds(0, 0, 2560, 1600); // Draw Range 2560, 1600
170e9297d28Sopenharmony_ci        RSTransactionProxy::GetInstance()->FlushImplicitTransaction();
171e9297d28Sopenharmony_ci        DrawSurface(surfaceNode, 2560, 1600, i); // Draw Range 2560, 1600
172e9297d28Sopenharmony_ci        sleep(4); // delay 4 second
173e9297d28Sopenharmony_ci        displayNode->RemoveChild(surfaceNode);
174e9297d28Sopenharmony_ci        RSTransactionProxy::GetInstance()->FlushImplicitTransaction();
175e9297d28Sopenharmony_ci    }
176e9297d28Sopenharmony_ci    return 0;
177e9297d28Sopenharmony_ci}
178