1 /*
2 * Copyright (c) 2023 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 <include/core/SkCanvas.h>
17 #include <include/effects/SkDashPathEffect.h>
18 #include <skia_framework.h>
19 #include <texgine/typography.h>
20 #include <texgine/utils/exlog.h>
21 #include <texgine/utils/memory_usage_scope.h>
22 #include <texgine/utils/trace.h>
23
24 #include "feature_test/feature_test_framework.h"
25 #include "texgine_canvas.h"
26 #include "texgine_paint.h"
27 #include "texgine_rect.h"
28
29 using namespace OHOS::Rosen::TextEngine;
30
31 namespace {
32 SkColor colors[] = {
33 SK_ColorRED,
34 SK_ColorYELLOW,
35 SK_ColorGREEN,
36 SK_ColorCYAN,
37 SK_ColorBLUE,
38 SK_ColorMAGENTA
39 };
40
41 TexginePaint g_rainbowPaint;
42 TexginePaint g_actualBorderPaint;
43 TexginePaint g_borderPaint;
44
Draw(TexgineCanvas & texgineCanvas,const std::list<struct TypographyData> & typographies,const struct FeatureTestOption & option,double y)45 double Draw(TexgineCanvas &texgineCanvas, const std::list<struct TypographyData> &typographies,
46 const struct FeatureTestOption &option, double y)
47 {
48 double maxHeight = 0;
49 double x = 0;
50 for (const auto &data : typographies) {
51 const auto &typography = data.typography;
52 // 800 is the max width of all test
53 if ((x + typography->GetMaxWidth() >= 800) || (x != 0 && data.atNewline)) {
54 x = 0;
55 y += maxHeight + option.marginTop;
56 maxHeight = 0;
57 }
58 if (data.onPaint) {
59 data.onPaint(data, texgineCanvas, x, y);
60 } else {
61 typography->Paint(texgineCanvas, x, y);
62 }
63
64 if (data.needRainbowChar.value_or(option.needRainbowChar)) {
65 texgineCanvas.Save();
66 texgineCanvas.Translate(x, y);
67 Boundary boundary = {data.rainbowStart, data.rainbowEnd};
68 auto boxes = typography->GetTextRectsByBoundary(boundary, data.hs, data.ws);
69 int32_t rainbowColorIndex = 0;
70 for (auto &box : boxes) {
71 g_rainbowPaint.SetColor(colors[rainbowColorIndex++]);
72 // 255 is the max value of Alpha, 0.2 means the transparency set to 0.2
73 g_rainbowPaint.SetAlpha(255 * 0.2);
74 texgineCanvas.DrawRect(box.rect, g_rainbowPaint);
75 g_rainbowPaint.SetColor(SK_ColorGRAY);
76 // 255 is the max value of Alpha, 0.2 means the transparency set to 0.3
77 g_rainbowPaint.SetAlpha(255 * 0.3);
78 texgineCanvas.DrawRect(box.rect, g_rainbowPaint);
79 rainbowColorIndex %= sizeof(colors) / sizeof(SkColor);
80 }
81 texgineCanvas.Restore();
82 }
83 if (!data.comment.empty()) {
84 SkiaFramework::DrawString(*texgineCanvas.GetCanvas(), data.comment, x, y);
85 }
86 if (option.needBorder) {
87 g_borderPaint.SetColor(option.colorBorder);
88 TexgineRect rect1 = TexgineRect::MakeXYWH(x, y, typography->GetMaxWidth(), typography->GetHeight());
89 texgineCanvas.DrawRect(rect1, g_borderPaint);
90
91 g_actualBorderPaint.SetColor(option.colorBorder);
92 TexgineRect rect2 = TexgineRect::MakeXYWH(x, y, typography->GetActualWidth(), typography->GetHeight());
93 texgineCanvas.DrawRect(rect2, g_actualBorderPaint);
94 }
95 x += typography->GetMaxWidth() + option.marginLeft;
96 maxHeight = std::max(maxHeight, typography->GetHeight());
97 }
98 // The upper and lower intervals of each test content is 50
99 y += maxHeight + option.marginTop + 50;
100
101 return y;
102 }
103
OnDraw(SkCanvas & canvas)104 void OnDraw(SkCanvas &canvas)
105 {
106 g_actualBorderPaint.SetStyle(TexginePaint::STROKE);
107
108 SkPaint borderPaint = g_actualBorderPaint.GetPaint();
109 const SkScalar intervals[2] = {1.0f, 1.0f};
110 // 2 means number of elements in the intervals array
111 borderPaint.setPathEffect(SkDashPathEffect::Make(intervals, 2, 0.0f));
112 TexginePaint paint;
113 paint.SetPaint(borderPaint);
114 g_borderPaint = paint;
115
116 SkPaint testBorderPaint = borderPaint;
117 testBorderPaint.setColor(0xff000000);
118
119 TexginePaint rainbowPaint;
120 rainbowPaint.SetStyle(TexginePaint::Style::FILL);
121
122 canvas.save();
123 // move canvas to (50, 50)
124 canvas.translate(50, 50);
125 double y = 0;
126 TexgineCanvas texgineCanvas;
127 texgineCanvas.SetCanvas(&canvas);
128
129 const auto &tests = FeatureTestCollection::GetInstance().GetTests();
130 for (const auto &ptest : tests) {
131 if (ptest == nullptr) {
132 continue;
133 }
134
135 double yStart = y;
136 canvas.save();
137 canvas.translate(50, 50); // move canvas to (50, 50)
138 const auto &option = ptest->GetFeatureTestOption();
139 const auto &typographies = ptest->GetTypographies();
140 y = Draw(texgineCanvas, typographies, option, y);
141 canvas.restore();
142 // 800 is the max width of all test
143 canvas.drawRect(SkRect::MakeXYWH(0, yStart, 800, y - yStart), testBorderPaint);
144 SkiaFramework::DrawString(canvas, ptest->GetTestName(), 0, yStart);
145 }
146 canvas.restore();
147 }
148 } // namespace
149
main()150 int main()
151 {
152 const auto &tests = FeatureTestCollection::GetInstance().GetTests();
153 for (const auto &ptest : tests) {
154 if (ptest == nullptr) {
155 continue;
156 }
157
158 MemoryUsageScope scope(ptest->GetTestName());
159 ScopedTrace layoutScope(ptest->GetTestName());
160 LOGSCOPED(sl, LOGEX_FUNC_LINE_DEBUG(), ptest->GetTestName());
161 ptest->Layout();
162 for (const auto &typography : ptest->GetTypographies()) {
163 ReportMemoryUsage("typography", *typography.typography, true);
164 }
165 }
166
167 SkiaFramework sf;
168 sf.SetWindowWidth(720); // 720 means the window width
169 sf.SetWindowHeight(1280); // 1280 means the window width
170 sf.SetWindowScale(720.0 / 900.0); // 720 / 900 means tht window's scale
171 sf.SetDrawFunc(OnDraw);
172 sf.Run();
173 return 0;
174 }
175