Skip to content

Commit

Permalink
Remove active pattern
Browse files Browse the repository at this point in the history
  • Loading branch information
yutannihilation committed Oct 27, 2024
1 parent 2c39cbe commit e5c6534
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 48 deletions.
25 changes: 17 additions & 8 deletions src/rust/src/vello_device/default.rs
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,7 @@ impl DeviceDriver for VelloGraphicsDevice {
raster,
pixels.0 as usize,
pixels.1 as usize,
peniko::Extend::Pad,
alpha,
with_extended_edge,
);
Expand Down Expand Up @@ -374,9 +375,10 @@ impl DeviceDriver for VelloGraphicsDevice {
// Note: with_stops doesn't accept &[ColorStop] or ColorStops. Why?
gradient.stops = color_stops;

VELLO_APP_PROXY
let index = VELLO_APP_PROXY
.scene
.set_pattern(FillPattern::Gradient(gradient));
.register_pattern(FillPattern::Gradient(gradient));
Rf_ScalarInteger(index as i32)
},
2 => unsafe {
let cx1 = R_GE_radialGradientCX1(pattern);
Expand Down Expand Up @@ -406,9 +408,11 @@ impl DeviceDriver for VelloGraphicsDevice {
.with_extend(extend);
// Note: with_stops doesn't accept &[ColorStop] or ColorStops. Why?
gradient.stops = color_stops;
VELLO_APP_PROXY

let index = VELLO_APP_PROXY
.scene
.set_pattern(FillPattern::Gradient(gradient));
.register_pattern(FillPattern::Gradient(gradient));
Rf_ScalarInteger(index as i32)
},
3 => unsafe {
let x = R_GE_tilingPatternX(pattern);
Expand Down Expand Up @@ -442,7 +446,8 @@ impl DeviceDriver for VelloGraphicsDevice {
Rf_eval(call, R_GlobalEnv);
Rf_unprotect(1);

self.request_register_tile().unwrap();
self.request_register_tile(x as f32, y as f32, extend)
.unwrap();
let index = VELLO_APP_PROXY.rx.lock().unwrap().recv().unwrap();

// TODO: use tile and set active pattern
Expand All @@ -453,11 +458,15 @@ impl DeviceDriver for VelloGraphicsDevice {
VELLO_APP_PROXY
.stop_rendering
.store(false, Ordering::Relaxed);

if let Response::PatternRegistered { index } = index {
Rf_ScalarInteger(index as i32)
} else {
R_NilValue
}
},
_ => {}
_ => unsafe { R_NilValue },
}

unsafe { R_NilValue }
}

fn release_pattern(&mut self, _ref: SEXP, _: DevDesc) {
Expand Down
13 changes: 11 additions & 2 deletions src/rust/src/vello_device/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,16 @@ pub trait WindowController {
})
}

fn request_register_tile(&self) -> savvy::Result<()> {
self.send_event(Request::SaveAsTile)
fn request_register_tile(
&self,
x_offset: f32,
y_offset: f32,
extend: peniko::Extend,
) -> savvy::Result<()> {
self.send_event(Request::SaveAsTile {
x_offset,
y_offset,
extend,
})
}
}
34 changes: 27 additions & 7 deletions src/rust/vellogd-shared/src/protocol.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,17 @@
use crate::ffi::R_GE_gcontext;
use crate::ffi::{R_GE_gcontext, R_NilValue, INTEGER};
use serde::{Deserialize, Serialize};

#[derive(Debug, Clone, Deserialize, Serialize)]
pub enum FillBrush {
/// color
Color(peniko::Color),
/// index of the registered pattern
PatternRef(u32),
}

#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct FillParams {
pub color: peniko::Color,
pub brush: FillBrush,
pub use_nonzero_rule: bool,
}

Expand Down Expand Up @@ -61,7 +69,11 @@ pub enum Request {
PrepareForSaveAsTile {
height: u32,
},
SaveAsTile,
SaveAsTile {
x_offset: f32,
y_offset: f32,
extend: peniko::Extend,
},

SetBaseColor {
color: u32,
Expand Down Expand Up @@ -110,7 +122,7 @@ pub enum Request {
pub enum Response {
WindowSizes { width: u32, height: u32 },
Connect { server_name: String },
TileRegistered { index: usize },
PatternRegistered { index: usize },
}

pub trait AppResponseRelay {
Expand Down Expand Up @@ -206,10 +218,18 @@ impl FillParams {
if gc.fill == 0 {
return None;
}
let [r, g, b, a] = gc.fill.to_ne_bytes();
let color = peniko::Color::rgba8(r, g, b, a);

let brush = if unsafe { gc.patternFill != R_NilValue } {
let index = unsafe { *INTEGER(gc.patternFill) };
FillBrush::PatternRef(index as u32)
} else {
let [r, g, b, a] = gc.fill.to_ne_bytes();
let color = peniko::Color::rgba8(r, g, b, a);
FillBrush::Color(color)
};

Some(Self {
color,
brush,
use_nonzero_rule,
})
}
Expand Down
82 changes: 51 additions & 31 deletions src/rust/vellogd-shared/src/winit_app/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ use winit::{
};

use crate::{
protocol::{AppResponseRelay, FillParams, GlyphParams, Request, Response, StrokeParams},
protocol::{
AppResponseRelay, FillBrush, FillParams, GlyphParams, Request, Response, StrokeParams,
},
text_layouter::{fontface_to_weight_and_style, TextLayouter},
};

Expand All @@ -45,7 +47,7 @@ pub enum RenderState<'a> {
#[derive(Debug)]
pub enum FillPattern {
Gradient(peniko::Gradient),
Tiling, // TODO
Tiling(peniko::Image), // TODO
}

#[derive(Clone)]
Expand All @@ -57,7 +59,7 @@ pub struct SceneDrawer {
/// tile pattern).
edited_scene: Arc<Mutex<Scene>>,

tiles: Arc<Mutex<Vec<peniko::Image>>>,
patterns: Arc<Mutex<Vec<FillPattern>>>,

// This is a bit tricky. Scene doesn't need to know the window size, but,
// since R requires a flipped Y-axis, SceneDrawer needs to know how to flip,
Expand All @@ -69,8 +71,6 @@ pub struct SceneDrawer {
y_transform: Arc<Mutex<vello::kurbo::Affine>>,
window_height: Arc<AtomicU32>,

active_pattern: Arc<Mutex<Option<FillPattern>>>,

needs_redraw: Arc<AtomicBool>,
}

Expand All @@ -84,10 +84,9 @@ impl SceneDrawer {
Self {
on_screen_scene: scene.clone(),
edited_scene: scene,
tiles: Arc::new(Mutex::new(Vec::new())),
patterns: Arc::new(Mutex::new(Vec::new())),
y_transform,
window_height,
active_pattern: Arc::new(Mutex::new(None)),
needs_redraw,
}
}
Expand Down Expand Up @@ -121,20 +120,27 @@ impl SceneDrawer {
fn draw_fill_inner(
&self,
fill_rule: peniko::Fill,
color: peniko::Color,
brush: FillBrush,
shape: &impl kurbo::Shape,
) {
let scene = &mut self.edited_scene.lock().unwrap();
let y_transform = *self.y_transform.lock().unwrap();
let fill_pattern = self.active_pattern.lock().unwrap();
let brush: peniko::BrushRef = match fill_pattern.as_ref() {
Some(ptn) => match ptn {
FillPattern::Gradient(gradient) => gradient.into(),
FillPattern::Tiling => todo!(),
},
None => color.into(),
match brush {
FillBrush::Color(color) => {
scene.fill(fill_rule, y_transform, color, None, shape);
}
FillBrush::PatternRef(index) => {
let patterns = self.patterns.lock().unwrap();
match patterns.get(index as usize).unwrap() {
FillPattern::Gradient(gradient) => {
scene.fill(fill_rule, y_transform, gradient, None, shape);
}
FillPattern::Tiling(image) => {
scene.fill(fill_rule, y_transform, image, None, shape);
}
}
}
};
scene.fill(fill_rule, y_transform, brush, None, shape);
}

pub fn draw_circle(
Expand All @@ -147,7 +153,7 @@ impl SceneDrawer {
let circle = vello::kurbo::Circle::new(center, radius);

if let Some(fill_params) = fill_params {
self.draw_fill_inner(peniko::Fill::NonZero, fill_params.color, &circle);
self.draw_fill_inner(peniko::Fill::NonZero, fill_params.brush, &circle);
}

if let Some(stroke_params) = stroke_params {
Expand Down Expand Up @@ -180,7 +186,7 @@ impl SceneDrawer {
} else {
peniko::Fill::EvenOdd
};
self.draw_fill_inner(style, fill_params.color, &path);
self.draw_fill_inner(style, fill_params.brush, &path);
}

if let Some(stroke_params) = stroke_params {
Expand All @@ -200,7 +206,7 @@ impl SceneDrawer {
let rect = vello::kurbo::Rect::new(p0.x, p0.y, p1.x, p1.y);

if let Some(fill_params) = fill_params {
self.draw_fill_inner(peniko::Fill::NonZero, fill_params.color, &rect);
self.draw_fill_inner(peniko::Fill::NonZero, fill_params.brush, &rect);
}

if let Some(stroke_params) = stroke_params {
Expand Down Expand Up @@ -352,12 +358,15 @@ impl SceneDrawer {
scene.pop_layer();
}

pub fn set_pattern(&self, pattern: FillPattern) {
self.active_pattern.lock().unwrap().replace(pattern);
pub fn register_pattern(&self, pattern: FillPattern) -> usize {
let mut patterns = self.patterns.lock().unwrap();
patterns.push(pattern);

patterns.len() - 1 // index
}

pub fn release_pattern(&self) {
self.active_pattern.lock().unwrap().take();
// TODO
}
}

Expand All @@ -369,6 +378,7 @@ pub fn convert_to_image(
raster: &[u8],
width: usize,
height: usize,
extend: peniko::Extend,
alpha: u8,
with_extended_edge: bool,
) -> peniko::Image {
Expand Down Expand Up @@ -398,7 +408,7 @@ pub fn convert_to_image(
format: peniko::Format::Rgba8,
width,
height,
extend: peniko::Extend::Pad,
extend,
alpha,
}
}
Expand Down Expand Up @@ -754,7 +764,11 @@ impl<'a, T: AppResponseRelay> ApplicationHandler<Request> for VelloApp<'a, T> {
// *self.scene.edited_scene.lock().unwrap() = Scene::new()
}

Request::SaveAsTile => {
Request::SaveAsTile {
x_offset: _, // TODO
y_offset: _, // TODO
extend,
} => {
let width = self.width.load(Ordering::Relaxed);
let height = self.height.load(Ordering::Relaxed);

Expand All @@ -763,13 +777,19 @@ impl<'a, T: AppResponseRelay> ApplicationHandler<Request> for VelloApp<'a, T> {

// register to tiles

let image =
convert_to_image(&data, width as usize, height as usize, u8::MAX, false);
let mut tiles = self.scene.tiles.lock().unwrap();
tiles.push(image);
let index = tiles.len() - 1;

self.tx.respond(Response::TileRegistered { index });
let image = convert_to_image(
&data,
width as usize,
height as usize,
extend,
u8::MAX,
false,
);
let mut patterns = self.scene.patterns.lock().unwrap();
patterns.push(FillPattern::Tiling(image));
let index = patterns.len() - 1;

self.tx.respond(Response::PatternRegistered { index });
}

// ignore other events
Expand Down

0 comments on commit e5c6534

Please sign in to comment.