Skip to content

Commit 9cbc8e0

Browse files
committed
vaev-driver: Handle correctly HTML/BODY backgrounds outside of layout builder.
1 parent 38bb772 commit 9cbc8e0

File tree

7 files changed

+137
-10
lines changed

7 files changed

+137
-10
lines changed

src/main.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ Async::Task<> renderAsync(
157157
};
158158

159159
auto media = constructMediaForRender(options.scale, imageSize);
160-
auto [style, layout, paint, frags] = Vaev::Driver::render(*dom, media, {.small = imageSize});
160+
auto [style, layout, paint, frags, canvasColor] = Vaev::Driver::render(*dom, media, {.small = imageSize});
161161

162162
auto image = Gfx::Surface::alloc(
163163
imageSize.cast<isize>() * options.density.toDppx(),
@@ -166,7 +166,7 @@ Async::Task<> renderAsync(
166166

167167
Gfx::CpuCanvas g;
168168
g.begin(*image);
169-
g.clear(Gfx::WHITE);
169+
g.clear(canvasColor);
170170
g.scale(options.density.toDppx());
171171
paint->paint(g);
172172
if (options.wireframe)

src/web/vaev-driver/render.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export struct RenderResult {
2020
Rc<Layout::Box> layout;
2121
Rc<Scene::Node> scenes;
2222
Rc<Layout::Frag> frag;
23+
Gfx::Color canvasColor;
2324
};
2425

2526
export RenderResult render(Gc::Ref<Dom::Document> dom, Style::Media const& media, Layout::Viewport viewport) {
@@ -43,9 +44,11 @@ export RenderResult render(Gc::Ref<Dom::Document> dom, Style::Media const& media
4344
Style::Computer computer{media, stylebook, fontBook};
4445
computer.loadFontFaces();
4546

47+
auto canvasColor = Layout::BGSearch(computer, dom);
48+
4649
Layout::Tree tree = {
4750
Layout::build(computer, dom),
48-
viewport,
51+
viewport
4952
};
5053

5154
elapsed = Sys::now() - start;
@@ -79,7 +82,8 @@ export RenderResult render(Gc::Ref<Dom::Document> dom, Style::Media const& media
7982
std::move(stylebook),
8083
makeRc<Layout::Box>(std::move(tree.root)),
8184
sceneRoot,
82-
makeRc<Layout::Frag>(std::move(root))
85+
makeRc<Layout::Frag>(std::move(root)),
86+
canvasColor
8387
};
8488
}
8589

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
module;
2+
3+
#include <karm-image/loader.h>
4+
#include <karm-text/loader.h>
5+
#include <karm-text/prose.h>
6+
#include <vaev-dom/document.h>
7+
#include <vaev-style/computer.h>
8+
9+
export module Vaev.Layout:backgroundCanvas;
10+
11+
import :values;
12+
13+
namespace Vaev::Layout {
14+
15+
Gfx::Color ColorToGfx(Color color) {
16+
if (auto isRes = color.is<Gfx::Color>()) {
17+
return *isRes;
18+
} else {
19+
logWarn("color was not a Gfx color");
20+
return Gfx::WHITE;
21+
}
22+
}
23+
24+
export Gfx::Color BGSearch(Style::Computer& c, Gc::Ref<Dom::Document> doc) {
25+
auto el = doc->documentElement();
26+
if (!el) {
27+
return Gfx::WHITE;
28+
}
29+
30+
auto style = c.computeFor(Style::Computed::initial(), *el);
31+
if (style->backgrounds->color != Gfx::ALPHA) {
32+
style->backgrounds.cow().color = Gfx::PINK;
33+
return ColorToGfx(style->backgrounds->color);
34+
}
35+
36+
for (auto child = el->firstChild(); child; child = child->nextSibling()) {
37+
if (auto isRes = child->is<Dom::Element>()) {
38+
if (isRes->tagName != Html::BODY) {
39+
continue;
40+
}
41+
42+
auto childStyle = c.computeFor(*style, *isRes);
43+
if (childStyle->backgrounds->color != Gfx::ALPHA) {
44+
childStyle->backgrounds.cow().color = Gfx::PINK;
45+
return ColorToGfx(childStyle->backgrounds->color);
46+
} else {
47+
return Gfx::WHITE;
48+
}
49+
}
50+
}
51+
52+
return Gfx::WHITE;
53+
}
54+
55+
} // namespace Vaev::Layout

src/web/vaev-layout/builder.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,7 @@ static void _buildElement(Style::Computer& c, Gc::Ref<Dom::Element> el, Box& par
275275
}
276276

277277
auto style = c.computeFor(*parent.style, el);
278+
278279
auto font = _lookupFontface(c.fontBook, *style);
279280

280281
auto display = style->display;
@@ -295,12 +296,11 @@ static void _buildNode(Style::Computer& c, Gc::Ref<Dom::Node> node, Box& parent)
295296
_buildElement(c, *el, parent);
296297
} else if (auto text = node->is<Dom::Text>()) {
297298
_buildRun(c, *text, parent);
298-
} else if (auto doc = node->is<Dom::Document>()) {
299-
_buildChildren(c, *doc, parent);
300299
}
301300
}
302301

303302
export Box build(Style::Computer& c, Gc::Ref<Dom::Document> doc) {
303+
304304
if (auto el = doc->documentElement()) {
305305
auto style = c.computeFor(Style::Computed::initial(), *el);
306306
auto font = _lookupFontface(c.fontBook, *style);

src/web/vaev-layout/mod.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -13,3 +13,4 @@ export import :replaced;
1313
export import :table;
1414
export import :values;
1515
export import :writing;
16+
export import :backgroundCanvas;

src/web/vaev-view/view.cpp

+6-4
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ struct View : public Ui::View<View> {
7171
}
7272

7373
void paint(Gfx::Canvas& g, Math::Recti rect) override {
74+
// Painting browser's viewport.
7475
auto viewport = bound().size();
7576
if (not _renderResult) {
7677
auto media = _constructMedia(viewport);
@@ -82,10 +83,11 @@ struct View : public Ui::View<View> {
8283
g.origin(bound().xy.cast<f64>());
8384
g.clip(viewport);
8485

85-
auto [_, layout, paint, frag] = *_renderResult;
86-
g.clear(rect, Gfx::WHITE);
86+
auto [_, layout, paint, frag, canvasColor] = *_renderResult;
87+
auto paintRect = rect.offset(-bound().xy);
88+
g.clear(paintRect, canvasColor);
8789

88-
paint->paint(g, rect.offset(-bound().xy).cast<f64>());
90+
paint->paint(g, paintRect.cast<f64>());
8991
if (_props.wireframe)
9092
Layout::wireframe(*frag, g);
9193

@@ -100,7 +102,7 @@ struct View : public Ui::View<View> {
100102
Math::Vec2i size(Math::Vec2i size, Ui::Hint) override {
101103
// FIXME: This is wasteful, we should cache the result
102104
auto media = _constructMedia(size);
103-
auto [_, layout, _, frag] = Driver::render(*_dom, media, {.small = size.cast<Au>()});
105+
auto [_, layout, _, frag, _] = Driver::render(*_dom, media, {.small = size.cast<Au>()});
104106

105107
return {
106108
frag->metrics.borderBox().width.cast<isize>(),
+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
<test name="html-body-bg">
2+
<container>
3+
<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
4+
5+
<head>
6+
<style>
7+
body {
8+
height: 100svh;
9+
width: 100vw;
10+
margin: 0;
11+
}
12+
13+
html {
14+
height: 100svh;
15+
width: 100vw;
16+
}
17+
18+
#ref {
19+
height: 100svh;
20+
width: 100vw;
21+
background-color: #b98af1;
22+
}
23+
</style>
24+
</head>
25+
26+
<body>
27+
<slot />
28+
</body>
29+
30+
</html>
31+
</container>
32+
33+
<rendering>
34+
<div id="ref" style="height: 100svh;width: 100vw;background-color: #b98af1;"></div>
35+
</rendering>
36+
37+
<rendering>
38+
<style>
39+
html {
40+
background-color: #b98af1;
41+
}
42+
</style>
43+
</rendering>
44+
45+
<rendering>
46+
<style>
47+
body {
48+
background-color: #b98af1;
49+
}
50+
</style>
51+
</rendering>
52+
53+
<rendering>
54+
<style>
55+
html {
56+
background-color: #b98af1;
57+
}
58+
59+
body {
60+
background-color: #ff2b8d;
61+
display: none;
62+
}
63+
</style>
64+
</rendering>
65+
</test>

0 commit comments

Comments
 (0)