diff --git a/.isu/issues.json b/.isu/issues.json index f5a57a1..9d8648e 100644 --- a/.isu/issues.json +++ b/.isu/issues.json @@ -1,5 +1,5 @@ { - "next_id": 309, + "next_id": 311, "issues": [ { "id": 1, @@ -3749,6 +3749,28 @@ "author": "piefev", "state": "open", "created_at": "2026-05-28T23:27:04Z" + }, + { + "id": 309, + "repo": "we", + "title": "fix pixelated/glitchy font rendering", + "body": null, + "labels": [], + "assigned": [], + "author": "piefev", + "state": "closed", + "created_at": "2026-05-29T12:16:44Z" + }, + { + "id": 310, + "repo": "we", + "title": "Render browser chrome as HTML/CSS/SVG; add border-radius + HiDPI/antialiased rendering", + "body": "Re-architect the toolbar (nav buttons + address bar) to render through the engine's own parse->style->layout->paint pipeline as an HTML/CSS document with inline SVG icons, instead of hand-built PaintCommands. Includes engine work: CSS border-radius; device-resolution (HiDPI) rendering; supersampled/antialiased SVG + scale-correct SVG text; SVG viewBox attribute case fix; GPU text-baseline fix; input vertical centering and glyph-accurate caret.", + "labels": [], + "assigned": [], + "author": "piefev", + "state": "closed", + "created_at": "2026-05-29T14:47:52Z" } ] } diff --git a/crates/browser/src/chrome_ui.rs b/crates/browser/src/chrome_ui.rs new file mode 100644 index 0000000..2052a6b --- /dev/null +++ b/crates/browser/src/chrome_ui.rs @@ -0,0 +1,177 @@ +//! Browser-chrome markup generation. +//! +//! The toolbar (navigation buttons + address bar) is rendered by the engine +//! itself: this module produces the HTML document and CSS for it, with inline +//! SVG icons. `main.rs` parses the document, seeds the address-bar `` +//! with the live edit state, lays it out, and composites it above the page — +//! so the browser's own UI exercises the same parse → style → layout → paint +//! pipeline as any web page. + +/// Toolbar height in CSS px. Mirrors the content offset applied to the page. +pub const CHROME_HEIGHT: f32 = 40.0; + +/// Font size (px) for the address-bar text. Kept in sync with the CSS below so +/// caret hit-testing can reshape the same glyphs. +pub const CHROME_FONT_SIZE: f32 = 14.0; + +/// Stable element ids for the interactive chrome controls. +pub const ID_BACK: &str = "back"; +pub const ID_FORWARD: &str = "forward"; +pub const ID_RELOAD: &str = "reload"; +pub const ID_URLBAR: &str = "urlbar"; + +/// Author stylesheet for the chrome document (macOS Tahoe-ish styling). The +/// UA stylesheet is added automatically by `resolve_styles`. +pub const CHROME_CSS: &str = "\ +html, body { margin: 0; padding: 0; } +#bar { + display: flex; + align-items: center; + height: 40px; + background: #f6f6f8; + padding: 0 8px; +} +.btn { + display: flex; + align-items: center; + justify-content: center; + width: 32px; + height: 28px; + margin-right: 4px; + border-radius: 8px; +} +#reload { margin-right: 8px; } +#urlbar { + flex-grow: 1; + height: 28px; + font-size: 14px; + color: #28282a; + background: #ffffff; + border: 1px solid rgba(0,0,0,0.22); + border-radius: 14px; + padding: 0 12px; +} +"; + +// Material-style filled icon path data (24x24 viewBox). +const PATH_BACK: &str = "M20 11H7.83l5.59-5.59L12 4l-8 8 8 8 1.41-1.41L7.83 13H20v-2z"; +const PATH_FORWARD: &str = "M12 4l-1.41 1.41L16.17 11H4v2h12.17l-5.58 5.59L12 20l8-8z"; +const PATH_STOP: &str = + "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 \ + 17.59 13.41 12z"; +const PATH_RELOAD: &str = "M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 \ + 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 \ + 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"; + +/// Enabled (dark) and disabled (dim) icon fill colors. +const ICON_ENABLED: &str = "#28282a"; +const ICON_DISABLED: &str = "#bcbcc0"; + +/// The faint pill behind an enabled nav button; disabled buttons show no pill. +const PILL_ENABLED: &str = "background: rgba(0,0,0,0.06);"; +const PILL_NONE: &str = "background: transparent;"; + +fn svg_icon(path: &str, fill: &str) -> String { + format!( + "" + ) +} + +fn nav_button(id: &str, path: &str, enabled: bool) -> String { + let fill = if enabled { ICON_ENABLED } else { ICON_DISABLED }; + let pill = if enabled { PILL_ENABLED } else { PILL_NONE }; + format!( + "