update for improved kurbo/peniko ergonomics

also removes some annoying lingering tabs from blend.wgsl
This commit is contained in:
Chad Brokaw 2022-11-23 12:50:28 -05:00
parent c1e91cb233
commit fc1a6e9e4e
6 changed files with 68 additions and 59 deletions

9
Cargo.lock generated
View file

@ -710,8 +710,9 @@ dependencies = [
[[package]]
name = "kurbo"
version = "0.8.3"
source = "git+https://github.com/linebender/kurbo#79e5787a57f12d4965fcea01ab9442ecf6795775"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e119590a03caff1f7a582e8ee8c2164ddcc975791701188132fd1d1b518d3871"
dependencies = [
"arrayvec 0.7.2",
]
@ -1070,9 +1071,9 @@ dependencies = [
[[package]]
name = "peniko"
version = "0.1.0"
source = "git+https://github.com/linebender/peniko?rev=aca2934#aca29349e7dcbd31f598172953ea88b5ddcd86df"
source = "git+https://github.com/linebender/peniko#b83821720aa51a3942be5d20c71525a1ae61ac0a"
dependencies = [
"kurbo 0.8.3",
"kurbo 0.9.0",
"smallvec",
]

View file

@ -1,45 +1,45 @@
use crate::PicoSvg;
use piet_scene::kurbo::{Affine, BezPath, Ellipse, PathEl, Point, Rect};
use piet_scene::kurbo::{Affine, Ellipse, PathEl, Point, Rect};
use piet_scene::*;
use crate::SimpleText;
pub fn render_funky_paths(sb: &mut SceneBuilder) {
use PathEl::*;
let missing_movetos = &[
let missing_movetos = [
LineTo((100.0, 100.0).into()),
LineTo((100.0, 200.0).into()),
ClosePath,
LineTo((0.0, 400.0).into()),
LineTo((100.0, 400.0).into()),
][..];
let only_movetos = &[MoveTo((0.0, 0.0).into()), MoveTo((100.0, 100.0).into())][..];
let empty: &[PathEl] = &[];
];
let only_movetos = [MoveTo((0.0, 0.0).into()), MoveTo((100.0, 100.0).into())];
let empty: [PathEl; 0] = [];
sb.fill(
Fill::NonZero,
Affine::translate((100.0, 100.0)),
&Color::rgb8(0, 0, 255).into(),
Color::rgb8(0, 0, 255),
None,
&missing_movetos,
);
sb.fill(
Fill::NonZero,
Affine::IDENTITY,
&Color::rgb8(0, 0, 255).into(),
Color::rgb8(0, 0, 255),
None,
&empty,
);
sb.fill(
Fill::NonZero,
Affine::IDENTITY,
&Color::rgb8(0, 0, 255).into(),
Color::rgb8(0, 0, 255),
None,
&only_movetos,
);
sb.stroke(
&Stroke::new(8.0),
Affine::translate((100.0, 100.0)),
&Color::rgb8(0, 255, 255).into(),
Color::rgb8(0, 255, 255),
None,
&missing_movetos,
);
@ -58,7 +58,7 @@ pub fn render_svg(sb: &mut SceneBuilder, svg: &PicoSvg, print_stats: bool) {
sb.fill(
Fill::NonZero,
Affine::IDENTITY,
&fill.color.into(),
fill.color,
None,
&fill.path,
);
@ -67,7 +67,7 @@ pub fn render_svg(sb: &mut SceneBuilder, svg: &PicoSvg, print_stats: bool) {
sb.stroke(
&Stroke::new(stroke.width as f32),
Affine::IDENTITY,
&stroke.color.into(),
stroke.color,
None,
&stroke.path,
);
@ -120,7 +120,7 @@ fn render_cardioid(sb: &mut SceneBuilder) {
sb.stroke(
&Stroke::new(2.0),
Affine::IDENTITY,
&Brush::Solid(Color::rgb8(0, 0, 0)),
Color::rgb8(0, 0, 0),
None,
&&path[..],
);
@ -138,15 +138,15 @@ fn render_clip_test(sb: &mut SceneBuilder) {
let step = 1.0 / ((N + 1) as f64);
for i in 0..N {
let t = ((i + 1) as f64) * step;
let path = &[
let path = [
PathEl::MoveTo((X0, Y0).into()),
PathEl::LineTo((X1, Y0).into()),
PathEl::LineTo((X1, Y0 + t * (Y1 - Y0)).into()),
PathEl::LineTo((X1 + t * (X0 - X1), Y1).into()),
PathEl::LineTo((X0, Y1).into()),
PathEl::ClosePath,
][..];
sb.push_layer(Mix::Clip.into(), Affine::IDENTITY, &path);
];
sb.push_layer(Mix::Clip, Affine::IDENTITY, &path);
}
let rect = Rect::new(X0, Y0, X1, Y1);
sb.fill(
@ -167,26 +167,26 @@ fn render_alpha_test(sb: &mut SceneBuilder) {
sb.fill(
Fill::NonZero,
Affine::IDENTITY,
&Color::rgb8(255, 0, 0).into(),
Color::rgb8(255, 0, 0),
None,
&&make_diamond(1024.0, 100.0)[..],
);
sb.fill(
Fill::NonZero,
Affine::IDENTITY,
&Color::rgba8(0, 255, 0, 0x80).into(),
Color::rgba8(0, 255, 0, 0x80),
None,
&&make_diamond(1024.0, 125.0)[..],
);
sb.push_layer(
Mix::Clip.into(),
Mix::Clip,
Affine::IDENTITY,
&&make_diamond(1024.0, 150.0)[..],
);
sb.fill(
Fill::NonZero,
Affine::IDENTITY,
&Color::rgba8(0, 0, 255, 0x80).into(),
Color::rgba8(0, 0, 255, 0x80),
None,
&&make_diamond(1024.0, 175.0)[..],
);
@ -227,7 +227,7 @@ fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affin
// Inspired by https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
let rect = Rect::from_origin_size(Point::new(0., 0.), (200., 200.));
let linear = LinearGradient::new((0.0, 0.0), (200.0, 0.0)).stops([Color::BLACK, Color::WHITE]);
sb.fill(Fill::NonZero, transform, &linear.into(), None, &rect);
sb.fill(Fill::NonZero, transform, &linear, None, &rect);
const GRADIENTS: &[(f64, f64, Color)] = &[
(150., 0., Color::rgb8(255, 240, 64)),
(175., 100., Color::rgb8(255, 96, 240)),
@ -237,14 +237,14 @@ fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affin
let mut color2 = c.clone();
color2.a = 0;
let radial = RadialGradient::new((*x, *y), 100.0).stops([*c, color2]);
sb.fill(Fill::NonZero, transform, &radial.into(), None, &rect);
sb.fill(Fill::NonZero, transform, &radial, None, &rect);
}
const COLORS: &[Color] = &[
Color::rgb8(255, 0, 0),
Color::rgb8(0, 255, 0),
Color::rgb8(0, 0, 255),
];
sb.push_layer(Mix::Normal.into(), transform, &rect);
sb.push_layer(Mix::Normal, transform, &rect);
for (i, c) in COLORS.iter().enumerate() {
let linear = LinearGradient::new((0.0, 0.0), (0.0, 200.0)).stops([Color::WHITE, *c]);
sb.push_layer(blend, transform, &rect);
@ -257,7 +257,7 @@ fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affin
sb.fill(
Fill::NonZero,
a,
&linear.into(),
&linear,
None,
&Ellipse::new((100., 100.), (90., 90.), 0.),
);
@ -319,9 +319,11 @@ pub fn render_anim_frame(sb: &mut SceneBuilder, text: &mut SimpleText, i: usize)
#[allow(unused)]
pub fn render_brush_transform(sb: &mut SceneBuilder, i: usize) {
let th = (std::f64::consts::PI / 180.0) * (i as f64);
let linear = LinearGradient::new((0.0, 0.0), (0.0, 200.0))
.stops([Color::RED, Color::GREEN, Color::BLUE])
.into();
let linear = LinearGradient::new((0.0, 0.0), (0.0, 200.0)).stops([
Color::RED,
Color::GREEN,
Color::BLUE,
]);
sb.fill(
Fill::NonZero,
Affine::translate((200.0, 200.0)),

View file

@ -20,7 +20,7 @@ pub use moscato::pinot;
use crate::scene::{SceneBuilder, SceneFragment};
use peniko::kurbo::{Affine, Rect};
use peniko::{Brush, Color, Fill};
use peniko::{Brush, Color, Fill, Mix};
use moscato::{Context, Scaler};
use pinot::{types::Tag, FontRef};
@ -123,13 +123,13 @@ impl<'a> GlyphProvider<'a> {
let path = glyph.path(*path_index)?;
if let Some(xform) = xform_stack.last() {
builder.push_layer(
Default::default(),
Mix::Clip,
Affine::IDENTITY,
&convert_transformed_path(path.elements(), xform),
);
} else {
builder.push_layer(
Default::default(),
Mix::Clip,
Affine::IDENTITY,
&convert_path(path.elements()),
);
@ -144,7 +144,7 @@ impl<'a> GlyphProvider<'a> {
max = *xform * max;
}
let rect = Rect::from_points(min, max);
builder.push_layer(Default::default(), Affine::IDENTITY, &rect);
builder.push_layer(Mix::Normal, Affine::IDENTITY, &rect);
}
Command::PopLayer => builder.pop_layer(),
Command::BeginBlend(bounds, mode) => {
@ -212,7 +212,7 @@ fn convert_transformed_path(
fn convert_blend(mode: moscato::CompositeMode) -> peniko::BlendMode {
use moscato::CompositeMode;
use peniko::{BlendMode, Compose, Mix};
use peniko::{BlendMode, Compose};
let mut mix = Mix::Normal;
let mut compose = Compose::SrcOver;
match mode {

View file

@ -18,7 +18,7 @@ use super::{conv, Scene, SceneData, SceneFragment};
use crate::ResourcePatch;
use bytemuck::{Pod, Zeroable};
use peniko::kurbo::{Affine, PathEl, Shape};
use peniko::{BlendMode, Brush, ColorStop, Fill, Stroke};
use peniko::{BlendMode, BrushRef, ColorStop, Fill, Stroke};
use smallvec::SmallVec;
/// Builder for constructing a scene or scene fragment.
@ -51,7 +51,13 @@ impl<'a> SceneBuilder<'a> {
/// Pushes a new layer bound by the specifed shape and composed with
/// previous layers using the specified blend mode.
pub fn push_layer(&mut self, blend: BlendMode, transform: Affine, shape: &impl Shape) {
pub fn push_layer(
&mut self,
blend: impl Into<BlendMode>,
transform: Affine,
shape: &impl Shape,
) {
let blend = blend.into();
self.maybe_encode_transform(transform);
self.linewidth(-1.0);
if self.encode_path(shape, true) {
@ -75,11 +81,11 @@ impl<'a> SceneBuilder<'a> {
}
/// Fills a shape using the specified style and brush.
pub fn fill(
pub fn fill<'b>(
&mut self,
_style: Fill,
transform: Affine,
brush: &Brush,
brush: impl Into<BrushRef<'b>>,
brush_transform: Option<Affine>,
shape: &impl Shape,
) {
@ -97,11 +103,11 @@ impl<'a> SceneBuilder<'a> {
}
/// Strokes a shape using the specified style and brush.
pub fn stroke(
pub fn stroke<'b>(
&mut self,
style: &Stroke,
transform: Affine,
brush: &Brush,
brush: impl Into<BrushRef<'b>>,
brush_transform: Option<Affine>,
shape: &impl Shape,
) {
@ -194,16 +200,16 @@ impl<'a> SceneBuilder<'a> {
}
}
fn encode_brush(&mut self, brush: &Brush) {
match brush {
Brush::Solid(color) => {
fn encode_brush<'b>(&mut self, brush: impl Into<BrushRef<'b>>) {
match brush.into() {
BrushRef::Solid(color) => {
self.scene.drawtag_stream.push(DRAWTAG_FILLCOLOR);
let rgba_color = color.to_premul_u32();
self.scene
.drawdata_stream
.extend(bytemuck::bytes_of(&FillColor { rgba_color }));
}
Brush::LinearGradient(gradient) => {
BrushRef::LinearGradient(gradient) => {
let index = self.add_ramp(&gradient.stops);
self.scene.drawtag_stream.push(DRAWTAG_FILLLINGRADIENT);
self.scene
@ -214,7 +220,7 @@ impl<'a> SceneBuilder<'a> {
p1: conv::point_to_f32(gradient.end),
}));
}
Brush::RadialGradient(gradient) => {
BrushRef::RadialGradient(gradient) => {
let index = self.add_ramp(&gradient.stops);
self.scene.drawtag_stream.push(DRAWTAG_FILLRADGRADIENT);
self.scene
@ -227,7 +233,7 @@ impl<'a> SceneBuilder<'a> {
r1: gradient.end_radius,
}));
}
Brush::SweepGradient(_gradient) => todo!("sweep gradients aren't done yet!"),
BrushRef::SweepGradient(_gradient) => todo!("sweep gradients aren't done yet!"),
}
}

View file

@ -45,11 +45,11 @@ fn color_burn(cb: f32, cs: f32) -> f32 {
}
fn hard_light(cb: vec3<f32>, cs: vec3<f32>) -> vec3<f32> {
return mix(
screen(cb, 2.0 * cs - 1.0),
cb * 2.0 * cs,
return mix(
screen(cb, 2.0 * cs - 1.0),
cb * 2.0 * cs,
vec3<f32>(cs <= vec3<f32>(0.5))
);
);
}
fn soft_light(cb: vec3<f32>, cs: vec3<f32>) -> vec3<f32> {

View file

@ -28,13 +28,13 @@ pub fn gen_test_scene() -> Scene {
let scene_ix = 1;
match scene_ix {
0 => {
let path = &[
let path = [
PathEl::MoveTo(Point::new(100.0, 100.0)),
PathEl::LineTo(Point::new(500.0, 120.0)),
PathEl::LineTo(Point::new(300.0, 150.0)),
PathEl::LineTo(Point::new(200.0, 260.0)),
PathEl::LineTo(Point::new(150.0, 210.0)),
][..];
];
let brush = Brush::Solid(Color::rgb8(0x40, 0x40, 0xff));
builder.fill(Fill::NonZero, Affine::IDENTITY, &brush, None, &path);
let transform = Affine::translate((50.0, 50.0));
@ -79,7 +79,7 @@ pub fn render_svg(sb: &mut SceneBuilder, svg: &PicoSvg, print_stats: bool) {
sb.fill(
Fill::NonZero,
Affine::IDENTITY,
&fill.color.into(),
fill.color,
None,
&fill.path,
);
@ -88,7 +88,7 @@ pub fn render_svg(sb: &mut SceneBuilder, svg: &PicoSvg, print_stats: bool) {
sb.stroke(
&Stroke::new(stroke.width as f32),
Affine::IDENTITY,
&stroke.color.into(),
stroke.color,
None,
&stroke.path,
);
@ -134,7 +134,7 @@ fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affin
// Inspired by https://developer.mozilla.org/en-US/docs/Web/CSS/mix-blend-mode
let rect = Rect::from_origin_size(Point::new(0., 0.), (200., 200.));
let linear = LinearGradient::new((0.0, 0.0), (200.0, 0.0)).stops([Color::BLACK, Color::WHITE]);
sb.fill(Fill::NonZero, transform, &linear.into(), None, &rect);
sb.fill(Fill::NonZero, transform, &linear, None, &rect);
const GRADIENTS: &[(f64, f64, Color)] = &[
(150., 0., Color::rgb8(255, 240, 64)),
(175., 100., Color::rgb8(255, 96, 240)),
@ -144,14 +144,14 @@ fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affin
let mut color2 = c.clone();
color2.a = 0;
let radial = RadialGradient::new((*x, *y), 100.0).stops([*c, color2]);
sb.fill(Fill::NonZero, transform, &radial.into(), None, &rect);
sb.fill(Fill::NonZero, transform, &radial, None, &rect);
}
const COLORS: &[Color] = &[
Color::rgb8(255, 0, 0),
Color::rgb8(0, 255, 0),
Color::rgb8(0, 0, 255),
];
sb.push_layer(Mix::Normal.into(), transform, &rect);
sb.push_layer(Mix::Normal, transform, &rect);
for (i, c) in COLORS.iter().enumerate() {
let linear = LinearGradient::new((0.0, 0.0), (0.0, 200.0)).stops([Color::WHITE, *c]);
sb.push_layer(blend, transform, &rect);
@ -164,7 +164,7 @@ fn render_blend_square(sb: &mut SceneBuilder, blend: BlendMode, transform: Affin
sb.fill(
Fill::NonZero,
a,
&linear.into(),
&linear,
None,
&Ellipse::new((100., 100.), (90., 90.), 0.),
);