/
complextextlayout.cpp
169 lines (141 loc) · 4.46 KB
/
complextextlayout.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// LAF Library
// Copyright (c) 2019-2021 Igara Studio S.A.
//
// This file is released under the terms of the MIT license.
// Read LICENSE.txt for more information.
#include "os/os.h"
#include <cstdio>
class MyDrawTextDelegate : public os::DrawTextDelegate {
gfx::Point m_mousePos;
public:
MyDrawTextDelegate(const gfx::Point& mousePos) : m_mousePos(mousePos) { }
void preProcessChar(const int index,
const int codepoint,
gfx::Color& fg,
gfx::Color& bg,
const gfx::Rect& charBounds) override {
if (charBounds.contains(m_mousePos)) {
fg = gfx::rgba(0, 0, 0);
bg = gfx::rgba(255, 255, 255);
}
else {
fg = gfx::rgba(255, 255, 255);
bg = gfx::rgba(0, 0, 0, 0);
}
}
};
os::FontRef font = nullptr;
void draw_display(os::Display* display,
const gfx::Point& mousePos)
{
os::Surface* surface = display->surface();
os::SurfaceLock lock(surface);
const gfx::Rect rc = surface->bounds();
os::SurfaceRef backSurface = os::instance()->makeSurface(rc.w, rc.h);
os::SurfaceLock lock2(backSurface.get());
os::Paint p;
p.color(gfx::rgba(0, 0, 0));
p.style(os::Paint::Fill);
backSurface->drawRect(rc, p);
p.color(gfx::rgba(255, 255, 255));
const wchar_t* lines[] = { L"English",
L"Русский язык", // Russian
L"汉语", // Simplified Chinese
L"日本語", // Japanese
L"한국어", // Korean
L"العَرَبِيَّة" }; // Arabic
MyDrawTextDelegate delegate(mousePos);
gfx::Point pos(0, 0);
for (auto line : lines) {
std::string s = base::to_utf8(line);
base::utf8_const utf8(s);
os::draw_text(
backSurface.get(), font.get(),
utf8.begin(), utf8.end(),
gfx::rgba(255, 255, 255), gfx::ColorNone,
pos.x, pos.y,
&delegate);
pos.y += font->height() + 4;
}
// Flip the back surface to the display surface
surface->drawSurface(backSurface.get(), 0, 0);
// Invalidates the whole display to show it on the screen.
display->invalidateRegion(gfx::Region(rc));
}
int app_main(int argc, char* argv[])
{
os::SystemRef system = os::make_system();
system->setAppMode(os::AppMode::GUI);
os::DisplayRef display = system->makeDisplay(400, 300);
// TODO use new fonts (SkFont wrappers with system->fontManager())
font = os::instance()->loadTrueTypeFont("/Library/Fonts/Arial Unicode.ttf", 32);
if (!font) {
std::printf("Font not found\n");
return 1;
}
display->setNativeMouseCursor(os::kArrowCursor);
display->setTitle("CTL");
system->finishLaunching();
system->activateApp();
// Wait until a key is pressed or the window is closed
os::EventQueue* queue = system->eventQueue();
gfx::Point mousePos;
bool running = true;
bool redraw = true;
while (running) {
if (redraw) {
redraw = false;
draw_display(display.get(), mousePos);
}
// Wait for an event in the queue, the "true" parameter indicates
// that we'll wait for a new event, and the next line will not be
// processed until we receive a new event. If we use "false" and
// there is no events in the queue, we receive an "ev.type() == Event::None
os::Event ev;
queue->getEvent(ev, true);
switch (ev.type()) {
case os::Event::CloseDisplay:
running = false;
break;
case os::Event::KeyDown:
switch (ev.scancode()) {
case os::kKeyEsc:
running = false;
break;
case os::kKey1:
case os::kKey2:
case os::kKey3:
case os::kKey4:
case os::kKey5:
case os::kKey6:
case os::kKey7:
case os::kKey8:
case os::kKey9:
// Set scale
display->setScale(1 + (int)(ev.scancode() - os::kKey1));
redraw = true;
break;
default:
// Do nothing for other cases
break;
}
break;
case os::Event::ResizeDisplay:
redraw = true;
break;
case os::Event::MouseEnter:
case os::Event::MouseMove:
mousePos = ev.position();
redraw = true;
break;
case os::Event::MouseLeave:
mousePos = gfx::Point(-1, -1);
redraw = true;
break;
default:
// Do nothing
break;
}
}
return 0;
}