Skip to content

Commit efb3cbe

Browse files
committed
feat: type-safe API with FontHandle, DrawContext, enums and default trait methods
1 parent 0ed7264 commit efb3cbe

6 files changed

Lines changed: 418 additions & 276 deletions

File tree

TODO.md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# Vello GPU Rendering Backend
2+
3+
## Cargo.toml
4+
- [ ] Add `vello` feature flag: `vello = ["dep:vello", "dep:parley", "dep:image"]`
5+
- [ ] Add `vello = { version = "0.7", optional = true }`
6+
- [ ] Add `parley = { version = "0.7", optional = true }`
7+
- [ ] Add dev-deps: `pollster = "0.4"`, `winit = "0.30"`, `wgpu = "27"`
8+
- [ ] Add `[[example]] name = "render_vello"` with `required-features = ["vello"]`
9+
10+
## lib.rs
11+
- [ ] Add `#[cfg(feature = "vello")] pub mod vello_backend;`
12+
13+
## vello_backend.rs — Struct + Constructors
14+
- [ ] `VelloContainer` struct (scene, font_ctx, layout_ctx, fonts, clip_stack, images, viewport, etc.)
15+
- [ ] `new(width, height)` / `new_with_scale(width, height, scale)`
16+
- [ ] `scene(&self)` / `into_scene(self)` / `clear(&mut self)`
17+
- [ ] `resize(&mut self, width, height)`
18+
- [ ] `load_image_data(&mut self, url, data)` — decode + store as `peniko::Image`
19+
- [ ] `scale_factor(&self)` getter
20+
21+
## vello_backend.rs — Font Management
22+
- [ ] `FontData` internal struct (family, size, weight, style, metrics)
23+
- [ ] `create_font` — store metadata, measure metrics via parley Layout
24+
- [ ] `delete_font` — remove from HashMap
25+
- [ ] `text_width` — build parley Layout, return `layout.width()`
26+
27+
## vello_backend.rs — Text Drawing
28+
- [ ] `draw_text` — build parley Layout, iterate glyph runs, `scene.draw_glyphs()`
29+
30+
## vello_backend.rs — Fill / Gradient / Image
31+
- [ ] `draw_solid_fill``scene.fill()` with solid brush on rounded rect
32+
- [ ] `draw_linear_gradient``Gradient::new_linear().with_stops()``scene.fill()`
33+
- [ ] `draw_radial_gradient``Gradient::new_radial().with_stops()``scene.fill()`
34+
- [ ] `draw_conic_gradient``Gradient::new_sweep().with_stops()``scene.fill()`
35+
- [ ] `draw_image``scene.draw_image()` with transform
36+
37+
## vello_backend.rs — Borders + Clipping
38+
- [ ] `draw_borders` — build `kurbo::BezPath` per side, `scene.stroke()` with dash patterns
39+
- [ ] `draw_list_marker` — disc/circle/square fills, numbered via `draw_text`
40+
- [ ] `set_clip``scene.push_layer(Mix::Clip, ...)` or `push_clip_layer`
41+
- [ ] `del_clip``scene.pop_layer()`
42+
43+
## vello_backend.rs — Remaining Trait Methods
44+
- [ ] `set_caption` / `set_base_url` / `on_anchor_click` / `set_cursor`
45+
- [ ] `get_viewport` — return stored viewport
46+
- [ ] `get_media_features` — return features with scale-adjusted resolution
47+
- [ ] `transform_text` — uppercase/lowercase/capitalize
48+
- [ ] `load_image` / `get_image_size`
49+
50+
## vello_backend.rs — Headless Helper
51+
- [ ] `render_to_rgba(html, width, height)` — wgpu headless → RGBA buffer
52+
- [ ] `render_to_rgba_scaled(html, width, height, scale)` — same with scale factor
53+
54+
## Example
55+
- [ ] `render_vello.rs` — winit window, wgpu surface, `vello::Renderer::render_to_surface()`
56+
57+
## Verification
58+
- [ ] `cargo check --features vello` compiles
59+
- [ ] Example renders sample HTML in a window

litehtml/examples/browse.rs

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use litehtml::pixbuf::PixbufContainer;
1515
use litehtml::selection::Selection;
1616
use litehtml::{
1717
BackgroundLayer, BorderRadiuses, Borders, Color, ConicGradient, DocumentContainer,
18-
FontDescription, FontMetrics, LinearGradient, ListMarker, MediaFeatures, Position,
19-
RadialGradient, Size, TextTransform,
18+
DrawContext, FontDescription, FontHandle, FontMetrics, LinearGradient, ListMarker,
19+
MediaFeatures, Position, RadialGradient, Size, TextTransform,
2020
};
2121

2222
const USER_AGENT: &str = "Mozilla/5.0 (X11; Linux x86_64; rv:122.0) Gecko/20100101 Firefox/122.0";
@@ -83,19 +83,19 @@ impl BrowseContainer {
8383

8484
// Delegate everything to inner, override import_css, set_base_url, load_image
8585
impl DocumentContainer for BrowseContainer {
86-
fn create_font(&mut self, descr: &FontDescription) -> (usize, FontMetrics) {
86+
fn create_font(&mut self, descr: &FontDescription) -> (FontHandle, FontMetrics) {
8787
self.inner.create_font(descr)
8888
}
89-
fn delete_font(&mut self, font: usize) {
89+
fn delete_font(&mut self, font: FontHandle) {
9090
self.inner.delete_font(font);
9191
}
92-
fn text_width(&self, text: &str, font: usize) -> f32 {
92+
fn text_width(&self, text: &str, font: FontHandle) -> f32 {
9393
self.inner.text_width(text, font)
9494
}
95-
fn draw_text(&mut self, hdc: usize, text: &str, font: usize, color: Color, pos: Position) {
95+
fn draw_text(&mut self, hdc: DrawContext, text: &str, font: FontHandle, color: Color, pos: Position) {
9696
self.inner.draw_text(hdc, text, font, color, pos);
9797
}
98-
fn draw_list_marker(&mut self, hdc: usize, marker: &ListMarker) {
98+
fn draw_list_marker(&mut self, hdc: DrawContext, marker: &ListMarker) {
9999
self.inner.draw_list_marker(hdc, marker);
100100
}
101101
fn load_image(&mut self, src: &str, baseurl: &str, redraw_on_ready: bool) {
@@ -110,42 +110,39 @@ impl DocumentContainer for BrowseContainer {
110110
fn get_image_size(&self, src: &str, baseurl: &str) -> Size {
111111
self.inner.get_image_size(src, baseurl)
112112
}
113-
fn draw_image(&mut self, hdc: usize, layer: &BackgroundLayer, url: &str, base_url: &str) {
113+
fn draw_image(&mut self, hdc: DrawContext, layer: &BackgroundLayer, url: &str, base_url: &str) {
114114
self.inner.draw_image(hdc, layer, url, base_url);
115115
}
116-
fn draw_solid_fill(&mut self, hdc: usize, layer: &BackgroundLayer, color: Color) {
116+
fn draw_solid_fill(&mut self, hdc: DrawContext, layer: &BackgroundLayer, color: Color) {
117117
self.inner.draw_solid_fill(hdc, layer, color);
118118
}
119119
fn draw_linear_gradient(
120120
&mut self,
121-
hdc: usize,
121+
hdc: DrawContext,
122122
layer: &BackgroundLayer,
123123
gradient: &LinearGradient,
124124
) {
125125
self.inner.draw_linear_gradient(hdc, layer, gradient);
126126
}
127127
fn draw_radial_gradient(
128128
&mut self,
129-
hdc: usize,
129+
hdc: DrawContext,
130130
layer: &BackgroundLayer,
131131
gradient: &RadialGradient,
132132
) {
133133
self.inner.draw_radial_gradient(hdc, layer, gradient);
134134
}
135135
fn draw_conic_gradient(
136136
&mut self,
137-
hdc: usize,
137+
hdc: DrawContext,
138138
layer: &BackgroundLayer,
139139
gradient: &ConicGradient,
140140
) {
141141
self.inner.draw_conic_gradient(hdc, layer, gradient);
142142
}
143-
fn draw_borders(&mut self, hdc: usize, borders: &Borders, draw_pos: Position, root: bool) {
143+
fn draw_borders(&mut self, hdc: DrawContext, borders: &Borders, draw_pos: Position, root: bool) {
144144
self.inner.draw_borders(hdc, borders, draw_pos, root);
145145
}
146-
fn set_caption(&mut self, caption: &str) {
147-
self.inner.set_caption(caption);
148-
}
149146
fn set_base_url(&mut self, base_url: &str) {
150147
if let Ok(u) = Url::parse(base_url) {
151148
self.base_url = u;
@@ -154,12 +151,6 @@ impl DocumentContainer for BrowseContainer {
154151
}
155152
self.inner.set_base_url(base_url);
156153
}
157-
fn on_anchor_click(&mut self, url: &str) {
158-
self.inner.on_anchor_click(url);
159-
}
160-
fn set_cursor(&mut self, cursor: &str) {
161-
self.inner.set_cursor(cursor);
162-
}
163154
fn transform_text(&self, text: &str, tt: TextTransform) -> String {
164155
self.inner.transform_text(text, tt)
165156
}
@@ -397,7 +388,7 @@ fn main() {
397388
if let Ok(mut doc) = litehtml::Document::from_html(&html, &mut container, None, None) {
398389
let _ = doc.render(width as f32);
399390
doc.draw(
400-
0,
391+
DrawContext::default(),
401392
0.0,
402393
0.0,
403394
Some(Position {

litehtml/examples/render.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::{env, fs, process};
88

99
use litehtml::pixbuf::PixbufContainer;
1010
use litehtml::selection::Selection;
11-
use litehtml::{Document, Position};
11+
use litehtml::{Document, DrawContext, Position};
1212

1313
/// Minimum drag distance (px) before selection starts.
1414
const DRAG_THRESHOLD: f32 = 4.0;
@@ -64,7 +64,7 @@ fn main() {
6464
if let Ok(mut doc) = Document::from_html(&html, &mut container, None, None) {
6565
let _ = doc.render(width as f32);
6666
doc.draw(
67-
0,
67+
DrawContext::default(),
6868
0.0,
6969
0.0,
7070
Some(Position {

0 commit comments

Comments
 (0)