M3: glass's docs say which centre splay bends away from and where a shape gets no core

Splay bends away from the centre of the layer's bounds, as the reference
tool's does: on a ring or an L that centre lies outside the shape, so an
inner edge bends towards the hole. Checked side by side on a ring and an
L at Splay 0% and 100%. The module doc still said splay 0 bends along the
edge's normal; it bends towards the core since #1889.

`MAX_SHAPE_PX` now says it is 4M px on the desktop and 1M on the web, and
that a bigger shape gets no core, so a large glass text or vector can bend
differently once zoomed into, in a 2× export, or on the web.

Docs only.
This commit is contained in:
Oleksii Sukholita
2026-11-06 20:29:14 +01:00
parent 0b97f3f180
commit 3d41394bfc
3 changed files with 21 additions and 13 deletions
+3 -1
View File
@@ -663,7 +663,9 @@ pub struct Glass {
/// Blur of the backdrop (a blur radius, document units, 0–[`Self::MAX_FROST`]).
pub frost: f64,
/// Which way the curved edge bends the backdrop: towards the shape's core (0; along the edge's
/// normal for a shape too big to work one out) to away from the layer's centre (1).
/// normal for a shape too big to work one out) to away from the centre of the layer's bounds
/// (1; on a ring or an L, whose centre lies outside the shape, an inner edge bends towards the
/// hole, as the reference tool's does).
pub splay: f64,
}
+16 -11
View File
@@ -3,13 +3,15 @@
//! Within `depth` of the outline the surface curves like a thick lens: the backdrop there is bent
//! towards the inside, most a [`BEVEL`] in from the edge (`refraction` × `depth` far), falling off
//! as the 3.5th power of the way out of the curve and gone `depth` further in, with a fifth as
//! much on the bevel itself ([`bend_at`]). `splay` turns which way it bends, from along the edge's
//! normal (0) to away from the layer's centre (1). Each colour channel bends by a different amount
//! (`dispersion`, a rainbow fringe: red furthest, blue least, each smeared along the bend). The
//! bevel catches the light as a thin line added to the backdrop ([`rim_light_at`]): fully where the
//! edge faces `light_angle`, none below 0.35 of facing it, 0.6 as much on the opposite side; and a
//! faint gradient runs across the curve, 5% darker where it faces the light and lighter opposite.
//! `frost` blurs the backdrop first. Distances to the outline come from an exact Euclidean
//! much on the bevel itself ([`bend_at`]). `splay` turns which way it bends, from towards the
//! shape's core (0; along the edge's normal for a shape too big to keep, see [`MAX_SHAPE_PX`]) to
//! away from the centre of the layer's bounds (1), as the reference tool's: on a ring or an L,
//! whose centre lies outside the shape, an inner edge bends towards the hole. Each colour channel
//! bends by a different amount (`dispersion`, a rainbow fringe: red furthest, blue least, each
//! smeared along the bend). The bevel catches the light as a thin line added to the backdrop
//! ([`rim_light_at`]): fully where the edge faces `light_angle`, none below 0.35 of facing it, 0.6
//! as much on the opposite side; and a faint gradient runs across the curve, 5% darker where it
//! faces the light and lighter opposite. `frost` blurs the backdrop first. Distances to the outline come from an exact Euclidean
//! distance transform of the shape's coverage.
//!
//! The shape's coverage, distances and normals depend only on the shape and the zoom. Once a
@@ -575,8 +577,11 @@ struct ShapeKey {
r: usize,
}
/// The cached fields of a shape whose window holds at most this many pixels; bigger shapes (a
/// pane far larger than the view) are worked out for the part a render shows each time.
/// The cached fields of a shape whose window holds at most this many pixels: 4M on the desktop, 1M
/// on the web. Bigger shapes (a pane far larger than the view) are worked out for the part a render
/// shows each time, with no core: they bend along their edge normals. So a large glass text or
/// vector can bend differently once zoomed into, in a 2× export than on the canvas, and on the web
/// than on the desktop. A rounded rectangle works out its core in closed form at any size.
#[cfg(not(target_arch = "wasm32"))]
const MAX_SHAPE_PX: u64 = 4 << 20;
#[cfg(target_arch = "wasm32")]
@@ -919,8 +924,8 @@ pub fn glass(g: &Glass, frame: EffectFrame<'_>, rect: Option<RoundedRect>) -> Op
fx::blur(&mut frosted, g.frost / 2.0 * scale);
let ang = g.light_angle.to_radians();
let light = (ang.sin() as f32, -ang.cos() as f32);
// The layer's centre in its own frame (see `own_frame`), which `splay` bends away from: the
// direction to it is the same wherever a render puts or cuts the layer.
// The centre of the layer's bounds in its own frame (see `own_frame`), which `splay` bends away
// from: the direction to it is the same wherever a render puts or cuts the layer.
let local_centre = shape.0.bounding_box().center();
let ((sx, sy), centre) = match own_frame(xf) {
Some(own) => (own.shift, own.xf * local_centre),
File diff suppressed because one or more lines are too long