Skip to content

Commit fd3c98b

Browse files
committed
feat(surfacerenderer): optimized rendering pipeline
1 parent 557677a commit fd3c98b

1 file changed

Lines changed: 46 additions & 30 deletions

File tree

src/support/surfacerenderer.cpp

Lines changed: 46 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -10,22 +10,53 @@ namespace {
1010
QFont g_font;
1111
qreal g_cell_w = 0;
1212
qreal g_cell_h = 0;
13+
qreal g_baseline = 0;
1314

14-
void render_row(QPainter* p, RDRowSlice row, qreal y) {
15-
for(int j = 0; j < static_cast<int>(rd_slice_length(row)); j++) {
16-
RDCell c = rd_slice_at(row, j);
17-
QColor fg = theme_provider::color(c.fg);
18-
QColor bg = theme_provider::color(c.bg);
15+
void render_cells(QPainter* p, RDRowSlice row, usize start_x, qreal y) {
16+
const usize LEN = rd_slice_length(row);
17+
if(start_x >= LEN) return;
1918

19+
const qreal BASELINE = y + g_baseline;
20+
21+
QString text;
22+
usize runstart = 0;
23+
RDThemeKind runfg{}, runbg{};
24+
bool inrun = false;
25+
26+
auto flush = [&]() {
27+
if(text.isEmpty()) return;
28+
29+
QColor fg = theme_provider::color(runfg);
30+
QColor bg = theme_provider::color(runbg);
2031
Q_ASSERT(fg.isValid());
2132
Q_ASSERT(bg.isValid());
2233

23-
QRectF r(j * g_cell_w, y, g_cell_w, g_cell_h);
34+
const qreal X = static_cast<qreal>(runstart) * g_cell_w;
2435

25-
p->fillRect(r, bg);
36+
p->fillRect(QRectF(X, y, text.size() * g_cell_w, g_cell_h), bg);
2637
p->setPen(fg);
27-
p->drawText(r, Qt::AlignCenter, QChar{static_cast<char32_t>(c.cp)});
38+
p->drawText(QPointF(X, BASELINE), text);
39+
40+
text.clear();
41+
};
42+
43+
usize col = 0;
44+
45+
for(usize cx = start_x; cx < LEN; cx++, col++) {
46+
RDCell c = rd_slice_at(row, cx);
47+
48+
if(!inrun || c.fg != runfg || c.bg != runbg) {
49+
flush();
50+
inrun = true;
51+
runfg = c.fg;
52+
runbg = c.bg;
53+
runstart = col;
54+
}
55+
56+
text.append(QChar{static_cast<char32_t>(c.cp)});
2857
}
58+
59+
flush();
2960
}
3061

3162
} // namespace
@@ -36,6 +67,9 @@ void init() {
3667
QFontMetricsF fm{g_font};
3768
g_cell_w = fm.horizontalAdvance(" ");
3869
g_cell_h = fm.height();
70+
71+
const qreal LEADING = g_cell_h - (fm.ascent() + fm.descent());
72+
g_baseline = (LEADING / 2.0) + fm.ascent();
3973
}
4074

4175
RDSurfacePos hit_test(QPoint pt, quint64 start_x) {
@@ -55,35 +89,17 @@ void render(QPainter* p, RDSurface* surface, usize n, usize start_x) {
5589
p->setFont(surface_renderer::g_font);
5690

5791
for(usize i = 0; i < n; i++) {
58-
RDRowSlice row = rd_surface_get_row(surface, i);
59-
qreal y = static_cast<qreal>(i) * surface_renderer::g_cell_h;
60-
61-
usize char_idx = start_x;
62-
63-
for(usize j = 0; char_idx < rd_slice_length(row); j++, char_idx++) {
64-
RDCell c = rd_slice_at(row, char_idx);
65-
QColor fg = theme_provider::color(c.fg);
66-
QColor bg = theme_provider::color(c.bg);
67-
68-
Q_ASSERT(fg.isValid());
69-
Q_ASSERT(bg.isValid());
70-
71-
QRectF r(static_cast<qreal>(j) * g_cell_w, y, g_cell_w, g_cell_h);
72-
73-
p->fillRect(r, bg);
74-
p->setPen(fg);
75-
p->drawText(r, Qt::AlignCenter, QChar{static_cast<char32_t>(c.cp)});
76-
}
92+
render_cells(p, rd_surface_get_row(surface, i), start_x,
93+
static_cast<qreal>(i) * g_cell_h);
7794
}
7895
}
7996

8097
void render_block(QPainter* p, RDSurfaceGraph* surface, usize start, usize n) {
8198
p->setFont(g_font);
8299

83100
for(usize i = 0; i < n; i++) {
84-
RDRowSlice row = rd_surfacegraph_get_row(surface, start + i);
85-
qreal y = static_cast<qreal>(i) * surface_renderer::g_cell_h;
86-
surface_renderer::render_row(p, row, y);
101+
render_cells(p, rd_surfacegraph_get_row(surface, start + i), 0,
102+
static_cast<qreal>(i) * g_cell_h);
87103
}
88104
}
89105

0 commit comments

Comments
 (0)