Expand description
Draws Crabshell windows on the CPU: backgrounds, rounded corners, borders and opacity with tiny-skia, glyphs from cosmic-text, and icons from SVG, PNG or raw pixels. Only what changed is repainted.
The platform keeps one Renderer, a DamageHistory per window and
a BufferAge per buffer. Each frame it hands the renderer the window’s
view and damage and a Canvas over the buffer’s memory, and reports
the returned rectangles to the compositor:
use crabshell_reactive::Runtime;
use crabshell_render::{BufferAge, Canvas, DamageHistory, PixelFormat, Renderer};
use crabshell_ui::prelude::*;
let runtime = Runtime::current();
let cx = Cx::new(runtime.new_owner());
let bar = PanelWindow::new(&Output::new("DP-1"))
.style(Style::new().background(Color::rgb(0x1e, 0x1e, 0x2e)))
.child(Text::new("hello"));
let window = Window::new(&cx, bar);
let mut text = TextSystem::new();
window.set_size(Size::new(200.0, 30.0));
runtime.flush();
window.layout(&mut text);
let mut renderer = Renderer::new();
let mut history = DamageHistory::new();
let mut age = BufferAge::default();
let scale = 1.5;
let (width, height) = (300, 45); // 200 x 30 logical pixels at 1.5
let mut buffer = vec![0; width * height * 4];
let damage = window.take_damage();
let report = renderer.draw(
&window.view(),
&damage,
&mut text,
&mut history,
Canvas {
pixels: &mut buffer,
width: width as u32,
height: height as u32,
scale,
format: PixelFormat::Argb8888,
age: &mut age,
},
)?;
assert_eq!(report.len(), 1); // a new buffer is drawn whole§How it works
- Damage arrives in logical pixels and becomes buffer pixels, rounded outward. Overlapping areas are merged, a buffer that skipped frames also repaints what changed in them, and when more than half of the buffer is dirty, all of it is repainted.
- The areas are drawn from scratch in 64-pixel tiles of a fixed grid, each into an RGBA pixmap of its own that clips the drawing, and copied into the buffer in the buffer’s byte order. A pixel is always drawn in the same tile, so a repaint gives the same pixels as drawing everything, even where a tile’s edge cuts a curve.
- Rectangles snap to whole pixels, so edges stay sharp at fractional scales. A border is drawn inside the edge. Opacity applies to a widget and everything inside it as one layer.
- Text is drawn from the cosmic-text buffer layout measured, as grayscale masks, with the baseline on a whole pixel. It isn’t clipped: the window’s damage covers text that overflows its widget.
- Icons are rasterized at their size in pixels and cached by source and that size.
- A screencopy view’s frame is scaled to its box and kept, one per
view, until a new frame or box replaces it.
capture_frameturns a compositor’s buffer into such a frame, scaled down to the view. quantize_colorsdecodes an image file asImagedoes and finds its main colors by median cut, as for a theme taken from a wallpaper.
Structs§
- Buffer
Age - The frame a buffer last held. Keep one next to each buffer, starting
with
BufferAge::defaultfor a new one. - Canvas
- A buffer to draw a window into.
- Canvas
Error - A canvas whose bytes don’t fit its size, or whose scale isn’t a positive number.
- Damage
History - What changed in one window’s recent frames. Keep one per window.
- Pixel
Rect - A rectangle of buffer pixels.
- Renderer
- Draws windows. One serves every window; it holds the glyph and icon caches.
- Turn
- How the compositor turned a captured buffer, as
wl_output.transformsays: rotated counter-clockwise by a quarter turn or more, and flipped around the vertical axis before that.
Enums§
- Pixel
Format - How a buffer stores each pixel, as
wl_shmnames the formats. Both are 32 bits per pixel with premultiplied alpha.
Constants§
- DEFAULT_
ICON_ THEME - The theme icon names are looked up in when the config doesn’t set one.
Functions§
- capture_
frame - The frame a view keeps of a
widthbyheightbuffer of premultiplied pixels informat, which the compositorturned. Withopaque, as inXRGB8888andXBGR8888, the fourth byte is ignored. The frame is turned back upright and scaled down toframe_sizeforcover.Noneifpixelsdoesn’t holdwidth * heightpixels. - frame_
size - The size a
sourcesized frame is kept at to show in a box ofcoverpixels: scaled down, keeping its shape, to the smallest size that still covers the box, so any fit draws it without scaling up. It is never scaled up, and keeps at least one pixel a side. - quantize_
colors - The main colors of the image file at
path, most common first.