1// Copyright 2021 Google LLC.
2
3#include "experimental/sktext/editor/Editor.h"
4#include "experimental/sktext/src/Paint.h"
5#include "include/core/SkCanvas.h"
6#include "include/core/SkColorFilter.h"
7#include "include/core/SkFontMgr.h"
8#include "include/core/SkGraphics.h"
9#include "include/core/SkPath.h"
10#include "include/core/SkRegion.h"
11#include "include/core/SkShader.h"
12#include "include/core/SkStream.h"
13#include "include/core/SkTime.h"
14#include "samplecode/Sample.h"
15#include "src/core/SkOSFile.h"
16#include "src/shaders/SkColorShader.h"
17#include "src/utils/SkOSPath.h"
18#include "src/utils/SkUTF.h"
19#include "tools/Resources.h"
20#include "tools/flags/CommandLineFlags.h"
21
22using namespace skia::text;
23using namespace skia::editor;
24
25namespace {
26class TextSample_HelloWorld : public Sample {
27protected:
28    SkString name() override { return SkString("TextSample_HelloWorld"); }
29
30    void onDrawContent(SkCanvas* canvas) override {
31        canvas->drawColor(SK_ColorWHITE);
32        skia::text::Paint::drawText(u"Hello word", canvas, 0, 0);
33    }
34
35private:
36    using INHERITED = Sample;
37};
38
39class TextSample_Align_Dir : public Sample {
40
41public:
42    TextSample_Align_Dir() : fUnicode(SkUnicode::Make()) { }
43protected:
44    SkString name() override { return SkString("TextSample_Align_Dir"); }
45
46    void drawLine(SkCanvas* canvas, SkScalar w, SkScalar h,
47                  const std::u16string& text,
48                  TextAlign align,
49                  TextDirection direction = TextDirection::kLtr) {
50        const std::u16string& ellipsis = u"\u2026";
51        SkScalar margin = 20;
52
53        SkAutoCanvasRestore acr(canvas, true);
54
55        canvas->clipRect(SkRect::MakeWH(w, h));
56        canvas->drawColor(SK_ColorWHITE);
57
58        SkPaint foregroundPaint(SkColors::kBlack);
59        SkPaint backgroundPaint(SkColors::kLtGray);
60        Paint::drawText(direction == TextDirection::kRtl ? mirror(text) : normal(text),
61                        canvas,
62                        direction, align,
63                        foregroundPaint, backgroundPaint,
64                        SkString("Roboto"), 12.0f, SkFontStyle::Normal(),
65                        0, 0);
66    }
67
68    std::u16string mirror(const std::u16string& text) {
69        std::u16string result;
70        result += u"\u202E";
71        for (auto i = text.size(); i > 0; --i) {
72            result += text[i - 1];
73        }
74        //for (auto ch : text) {
75        //    result += ch;
76        //}
77        result += u"\u202C";
78        return result;
79    }
80
81    std::u16string normal(const std::u16string& text) {
82        std::u16string result;
83        //result += u"\u202D";
84        for (auto ch : text) {
85            result += ch;
86        }
87        //result += u"\u202C";
88        return result;
89    }
90
91    void onDrawContent(SkCanvas* canvas) override {
92
93        canvas->drawColor(SK_ColorDKGRAY);
94        SkScalar width = this->width() / 4;
95        SkScalar height = this->height() / 2;
96
97        const std::u16string line = u"One line of text";
98
99        drawLine(canvas, width, height, line, TextAlign::kLeft, TextDirection::kLtr);
100        canvas->translate(width, 0);
101        drawLine(canvas, width, height, line, TextAlign::kRight, TextDirection::kLtr);
102        canvas->translate(width, 0);
103        drawLine(canvas, width, height, line, TextAlign::kCenter, TextDirection::kLtr);
104        canvas->translate(width, 0);
105        drawLine(canvas, width, height, line, TextAlign::kJustify, TextDirection::kLtr);
106        canvas->translate(-width * 3, height);
107
108        drawLine(canvas, width, height, line, TextAlign::kLeft, TextDirection::kRtl);
109        canvas->translate(width, 0);
110        drawLine(canvas, width, height, line, TextAlign::kRight, TextDirection::kRtl);
111        canvas->translate(width, 0);
112        drawLine(canvas, width, height, line, TextAlign::kCenter, TextDirection::kRtl);
113        canvas->translate(width, 0);
114        drawLine(canvas, width, height, line, TextAlign::kJustify, TextDirection::kRtl);
115        canvas->translate(width, 0);
116
117    }
118
119private:
120    using INHERITED = Sample;
121    std::unique_ptr<SkUnicode> fUnicode;
122};
123
124class TextSample_LongLTR : public Sample {
125protected:
126    SkString name() override { return SkString("TextSample_LongLTR"); }
127
128    void onDrawContent(SkCanvas* canvas) override {
129        canvas->drawColor(SK_ColorWHITE);
130        Paint::drawText(u"A very_very_very_very_very_very_very_very_very_very "
131                "very_very_very_very_very_very_very_very_very_very very very very very very very "
132                "very very very very very very very very very very very very very very very very "
133                "very very very very very very very very very very very very very long text", canvas, this->width());
134
135    }
136
137private:
138    using INHERITED = Sample;
139    std::unique_ptr<SkUnicode> fUnicode;
140};
141
142class TextSample_LongRTL1 : public Sample {
143protected:
144    SkString name() override { return SkString("TextSample_LongRTL"); }
145
146    std::u16string mirror(const std::string& text) {
147        std::u16string result;
148        result += u"\u202E";
149        for (auto i = text.size(); i > 0; --i) {
150          result += text[i - 1];
151        }
152        for (auto ch : text) {
153            result += ch;
154        }
155        result += u"\u202C";
156        return result;
157    }
158
159    void onDrawContent(SkCanvas* canvas) override {
160        canvas->drawColor(SK_ColorWHITE);
161        Paint::drawText(mirror("LONG MIRRORED TEXT SHOULD SHOW RIGHT TO LEFT (AS NORMAL)"), canvas, 0, 0);
162    }
163
164private:
165    using INHERITED = Sample;
166    std::unique_ptr<SkUnicode> fUnicode;
167};
168
169class TextSample_LongRTL2 : public Sample {
170protected:
171    SkString name() override { return SkString("TextSample_LongRTL"); }
172
173    void onDrawContent(SkCanvas* canvas) override {
174        canvas->drawColor(SK_ColorWHITE);
175        std::u16string utf16(u"يَهْدِيْكُمُ اللَّهُ وَيُصْلِحُ بَالَكُمُيَهْدِيْكُمُ اللَّهُ وَيُصْلِحُ بَالَكُمُ يَهْدِيْكُمُ اللَّهُ وَيُصْلِحُ بَالَكُمُ يَهْدِيْكُمُ اللَّهُ وَيُصْلِحُ بَالَكُمُ يَهْدِيْكُمُ اللَّهُ وَيُصْلِحُ بَالَكُمُيَهْدِيْكُمُ اللَّهُ وَيُصْلِحُ بَالَكُمُ يَهْدِيْكُمُ اللَّهُ وَيُصْلِحُ بَالَكُمُ يَهْدِيْكُمُ اللَّهُ وَيُصْلِحُ بَالَكُمُ");
176        Paint::drawText(utf16, canvas,
177                        TextDirection::kRtl, TextAlign::kRight,
178                        SkPaint(SkColors::kBlack), SkPaint(SkColors::kLtGray),
179                        SkString("Noto Naskh Arabic"), 40.0f, SkFontStyle::Normal(),
180                        SkSize::Make(800, 800), 0, 0);
181    }
182
183private:
184    using INHERITED = Sample;
185    std::unique_ptr<SkUnicode> fUnicode;
186};
187
188}  // namespace
189
190DEF_SAMPLE(return new TextSample_HelloWorld();)
191DEF_SAMPLE(return new TextSample_Align_Dir();)
192DEF_SAMPLE(return new TextSample_LongLTR();)
193DEF_SAMPLE(return new TextSample_LongRTL1();)
194DEF_SAMPLE(return new TextSample_LongRTL2();)
195