Skip to content

Commit 28b9fba

Browse files
committed
Fix conflicts
1 parent 86bd180 commit 28b9fba

5 files changed

Lines changed: 80 additions & 44 deletions

File tree

node-graph/libraries/core-types/src/list.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ pub const ATTR_SPREAD_METHOD: &str = "spread_method";
7777
/// Gradient's `GradientType` (`Linear` or `Radial`).
7878
pub const ATTR_GRADIENT_TYPE: &str = "gradient_type";
7979

80+
/// Table<Graphic> data for fill.
81+
pub const ATTR_FILL_GRAPHIC: &str = "fill_graphic";
82+
8083
// ========================
8184
// TRAIT: AnyAttributeValue
8285
// ========================

node-graph/libraries/graphic-types/src/graphic.rs

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use core_types::bounds::{BoundingBox, RenderBoundingBox};
22
use core_types::graphene_hash::CacheHash;
3-
use core_types::list::List;
3+
use core_types::list::{Item, List};
44
use core_types::ops::ListConvert;
55
use core_types::render_complexity::RenderComplexity;
66
use core_types::uuid::NodeId;
@@ -170,20 +170,20 @@ fn flatten_graphic_list<T>(content: List<Graphic>, extract_variant: fn(Graphic)
170170
output
171171
}
172172

173-
/// Converts a `Fill` enum into the `Table<Graphic>` representation used as paint storage.
174-
/// TODO: Remove once all paint sources flow through `Table<Graphic>` directly without going through the `Fill` enum.
175-
pub fn fill_to_paint(fill: &Fill) -> Option<Table<Graphic>> {
173+
/// Converts a `Fill` enum into the `List<Graphic>` representation used as paint storage.
174+
/// TODO: Remove once all paint sources flow through `List<Graphic>` directly without going through the `Fill` enum.
175+
pub fn fill_to_graphic_list(fill: &Fill) -> Option<List<Graphic>> {
176176
match fill {
177177
Fill::None => None,
178-
Fill::Solid(color) => Some(Table::new_from_element((*color).into())),
178+
Fill::Solid(color) => Some(List::new_from_element((*color).into())),
179179
Fill::Gradient(gradient) => {
180-
let gradient_row = TableRow::new_from_element(gradient.stops.clone())
180+
let gradient_row = Item::new_from_element(gradient.stops.clone())
181181
.with_attribute(ATTR_TRANSFORM, gradient.to_transform())
182182
.with_attribute(ATTR_GRADIENT_TYPE, gradient.gradient_type)
183183
.with_attribute(ATTR_SPREAD_METHOD, gradient.spread_method);
184-
let gradient_table = Table::new_from_row(gradient_row);
184+
let gradient_list = List::new_from_item(gradient_row);
185185

186-
Some(Table::new_from_element(Graphic::Gradient(gradient_table)))
186+
Some(List::new_from_element(Graphic::Gradient(gradient_list)))
187187
}
188188
}
189189
}

node-graph/libraries/rendering/src/render_ext.rs

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
use crate::renderer::{RenderParams, format_transform_matrix};
2-
use core_types::table::Table;
2+
use core_types::list::List;
33
use core_types::uuid::generate_uuid;
44
use core_types::{ATTR_GRADIENT_TYPE, ATTR_SPREAD_METHOD, ATTR_TRANSFORM, Color};
55
use glam::{DAffine2, DVec2};
66
use graphic_types::Graphic;
7-
use graphic_types::graphic::fill_to_paint;
7+
use graphic_types::graphic::fill_to_graphic_list;
88
use graphic_types::vector_types::gradient::GradientType;
99
use graphic_types::vector_types::vector::style::{Fill, PaintOrder, PathStyle, Stroke, StrokeAlign, StrokeCap, StrokeJoin};
1010
use std::fmt::Write;
@@ -16,7 +16,7 @@ pub trait RenderExt {
1616
fn render(&self, svg_defs: &mut String, element_transform: DAffine2, stroke_transform: DAffine2, bounds: DAffine2, transformed_bounds: DAffine2, render_params: &RenderParams) -> Self::Output;
1717
}
1818

19-
impl RenderExt for Table<Color> {
19+
impl RenderExt for List<Color> {
2020
type Output = String;
2121

2222
fn render(
@@ -39,7 +39,7 @@ impl RenderExt for Table<Color> {
3939
}
4040
}
4141

42-
impl RenderExt for Table<GradientStops> {
42+
impl RenderExt for List<GradientStops> {
4343
type Output = u64;
4444

4545
/// Adds the gradient def through mutating the first argument, returning the gradient ID.
@@ -117,13 +117,13 @@ impl RenderExt for Fill {
117117

118118
/// Renders the fill, adding necessary defs through mutating the first argument.
119119
fn render(&self, svg_defs: &mut String, element_transform: DAffine2, stroke_transform: DAffine2, bounds: DAffine2, transformed_bounds: DAffine2, render_params: &RenderParams) -> Self::Output {
120-
let Some(paint_table) = fill_to_paint(self) else { return r#" fill="none""#.to_string() };
121-
let Some(paint) = paint_table.element(0) else { return String::new() };
120+
let Some(paint_list) = fill_to_graphic_list(self) else { return r#" fill="none""#.to_string() };
121+
let Some(paint) = paint_list.element(0) else { return String::new() };
122122

123123
match paint {
124-
Graphic::Color(color_table) => color_table.render(svg_defs, element_transform, stroke_transform, bounds, transformed_bounds, render_params),
125-
Graphic::Gradient(stops_table) => {
126-
let gradient_id = stops_table.render(svg_defs, element_transform, stroke_transform, bounds, transformed_bounds, render_params);
124+
Graphic::Color(color_list) => color_list.render(svg_defs, element_transform, stroke_transform, bounds, transformed_bounds, render_params),
125+
Graphic::Gradient(stops_list) => {
126+
let gradient_id = stops_list.render(svg_defs, element_transform, stroke_transform, bounds, transformed_bounds, render_params);
127127
format!(r##" fill="url('#{gradient_id}')""##)
128128
}
129129
_ => {

node-graph/libraries/rendering/src/renderer.rs

Lines changed: 35 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use core_types::blending::BlendMode;
55
use core_types::bounds::BoundingBox;
66
use core_types::bounds::RenderBoundingBox;
77
use core_types::color::Color;
8-
use core_types::list::{Item, List};
8+
use core_types::list::{ATTR_FILL_GRAPHIC, Item, List};
99
use core_types::math::quad::Quad;
1010
use core_types::render_complexity::RenderComplexity;
1111
use core_types::transform::Footprint;
@@ -17,7 +17,7 @@ use core_types::{
1717
use dyn_any::DynAny;
1818
use glam::{DAffine2, DVec2};
1919
use graphene_hash::CacheHashWrapper;
20-
use graphic_types::graphic::fill_to_paint;
20+
use graphic_types::graphic::fill_to_graphic_list;
2121
use graphic_types::raster_types::{BitmapMut, CPU, GPU, Image, Raster};
2222
use graphic_types::vector_types::gradient::{GradientStops, GradientType};
2323
use graphic_types::vector_types::subpath::Subpath;
@@ -1109,7 +1109,7 @@ impl Render for List<Vector> {
11091109
}
11101110
}
11111111

1112-
fn render_to_vello(&self, scene: &mut Scene, parent_transform: DAffine2, _context: &mut RenderContext, render_params: &RenderParams) {
1112+
fn render_to_vello(&self, scene: &mut Scene, parent_transform: DAffine2, context: &mut RenderContext, render_params: &RenderParams) {
11131113
use graphic_types::vector_types::vector::style::{GradientType, StrokeCap, StrokeJoin};
11141114

11151115
for index in 0..self.len() {
@@ -1180,26 +1180,32 @@ impl Render for List<Vector> {
11801180
let use_layer = can_draw_aligned_stroke;
11811181
let wants_stroke_below = stroke.as_ref().is_some_and(|s| s.paint_order == vector::style::PaintOrder::StrokeBelow);
11821182

1183-
// TODO: This conversion is only necessary during the transition period from Fill to Table<Graphic>
1184-
let do_fill_path = |scene: &mut Scene, path: &kurbo::BezPath, fill_rule: peniko::Fill| {
1185-
let Some(paint_table) = fill_to_paint(element.style.fill()) else {
1183+
let do_fill_path = |scene: &mut Scene, context: &mut RenderContext, path: &kurbo::BezPath, fill_rule: peniko::Fill| {
1184+
// Try to use ATTR_FILL_GRAPHIC attribute, which is set by `fill_graphic` debug node, then fall back to Fill enum.
1185+
// TODO: Drop the Fill fall back once the Fill node becomes ready to store corresponding Graphic list directly.
1186+
let Some(fill_graphic) = self
1187+
.attribute::<List<Graphic>>(ATTR_FILL_GRAPHIC, index)
1188+
.filter(|t| !t.is_empty())
1189+
.cloned()
1190+
.or_else(|| fill_to_graphic_list(element.style.fill()))
1191+
else {
11861192
return;
11871193
};
11881194

1189-
for paint_idx in 0..paint_table.len() {
1190-
let Some(paint) = paint_table.element(paint_idx) else { continue };
1195+
for paint_idx in 0..fill_graphic.len() {
1196+
let Some(paint) = fill_graphic.element(paint_idx) else { continue };
11911197
match paint {
1192-
Graphic::Color(table) => {
1193-
let Some(color) = table.element(0) else { continue };
1198+
Graphic::Color(list) => {
1199+
let Some(color) = list.element(0) else { continue };
11941200

11951201
let fill = peniko::Brush::Solid(peniko::Color::new([color.r(), color.g(), color.b(), color.a()]));
11961202
scene.fill(fill_rule, kurbo::Affine::new(element_transform.to_cols_array()), &fill, None, path);
11971203
}
1198-
Graphic::Gradient(stops_table) => {
1199-
let Some(stops) = stops_table.element(0) else { continue };
1200-
let gradient_type: GradientType = stops_table.attribute_cloned_or_default(ATTR_GRADIENT_TYPE, 0);
1201-
let gradient_transform: DAffine2 = stops_table.attribute_cloned_or_default(ATTR_TRANSFORM, 0);
1202-
let spread_method: GradientSpreadMethod = stops_table.attribute_cloned_or_default(ATTR_SPREAD_METHOD, 0);
1204+
Graphic::Gradient(stops_list) => {
1205+
let Some(stops) = stops_list.element(0) else { continue };
1206+
let gradient_type: GradientType = stops_list.attribute_cloned_or_default(ATTR_GRADIENT_TYPE, 0);
1207+
let gradient_transform: DAffine2 = stops_list.attribute_cloned_or_default(ATTR_TRANSFORM, 0);
1208+
let spread_method: GradientSpreadMethod = stops_list.attribute_cloned_or_default(ATTR_SPREAD_METHOD, 0);
12031209

12041210
let mut peniko_stops = peniko::ColorStops::new();
12051211
for (position, color, _) in stops.interpolated_samples() {
@@ -1257,27 +1263,31 @@ impl Render for List<Vector> {
12571263
let brush_transform = kurbo::Affine::new((inverse_element_transform * parent_transform).to_cols_array());
12581264
scene.fill(fill_rule, kurbo::Affine::new(element_transform.to_cols_array()), &fill, Some(brush_transform), path);
12591265
}
1260-
_ => todo!(),
1266+
Graphic::Vector(_) | Graphic::RasterCPU(_) | Graphic::RasterGPU(_) | Graphic::Graphic(_) => {
1267+
scene.push_clip_layer(fill_rule, kurbo::Affine::new(element_transform.to_cols_array()), path);
1268+
paint.render_to_vello(scene, multiplied_transform, context, render_params);
1269+
scene.pop_layer();
1270+
}
12611271
};
12621272
}
12631273
};
12641274

12651275
// Branching vectors without regions (e.g. mesh grids) need face-by-face fill rendering.
12661276
let use_face_fill = element.use_face_fill();
1267-
let do_fill = |scene: &mut Scene| {
1277+
let do_fill = |scene: &mut Scene, context: &mut RenderContext| {
12681278
if use_face_fill {
12691279
for mut face_path in element.construct_faces().filter(|face| face.area() >= 0.) {
12701280
face_path.apply_affine(Affine::new(applied_stroke_transform.to_cols_array()));
12711281
let mut kurbo_path = kurbo::BezPath::new();
12721282
for element in face_path {
12731283
kurbo_path.push(element);
12741284
}
1275-
do_fill_path(scene, &kurbo_path, peniko::Fill::NonZero);
1285+
do_fill_path(scene, context, &kurbo_path, peniko::Fill::NonZero);
12761286
}
12771287
} else if element.is_branching() {
1278-
do_fill_path(scene, &path, peniko::Fill::EvenOdd);
1288+
do_fill_path(scene, context, &path, peniko::Fill::EvenOdd);
12791289
} else {
1280-
do_fill_path(scene, &path, peniko::Fill::NonZero);
1290+
do_fill_path(scene, context, &path, peniko::Fill::NonZero);
12811291
}
12821292
};
12831293

@@ -1347,21 +1357,21 @@ impl Render for List<Vector> {
13471357

13481358
if wants_stroke_below {
13491359
scene.push_layer(peniko::Fill::NonZero, peniko::Mix::Normal, 1., kurbo::Affine::IDENTITY, &rect);
1350-
vector_list.render_to_vello(scene, parent_transform, _context, &render_params.for_alignment(applied_stroke_transform));
1360+
vector_list.render_to_vello(scene, parent_transform, context, &render_params.for_alignment(applied_stroke_transform));
13511361
scene.push_layer(peniko::Fill::NonZero, peniko::BlendMode::new(peniko::Mix::Normal, compose), 1., kurbo::Affine::IDENTITY, &rect);
13521362

13531363
do_stroke(scene, 2.);
13541364

13551365
scene.pop_layer();
13561366
scene.pop_layer();
13571367

1358-
do_fill(scene);
1368+
do_fill(scene, context);
13591369
} else {
13601370
// Fill first (unclipped), then stroke (clipped) above
1361-
do_fill(scene);
1371+
do_fill(scene, context);
13621372

13631373
scene.push_layer(peniko::Fill::NonZero, peniko::Mix::Normal, 1., kurbo::Affine::IDENTITY, &rect);
1364-
vector_list.render_to_vello(scene, parent_transform, _context, &render_params.for_alignment(applied_stroke_transform));
1374+
vector_list.render_to_vello(scene, parent_transform, context, &render_params.for_alignment(applied_stroke_transform));
13651375
scene.push_layer(peniko::Fill::NonZero, peniko::BlendMode::new(peniko::Mix::Normal, compose), 1., kurbo::Affine::IDENTITY, &rect);
13661376

13671377
do_stroke(scene, 2.);
@@ -1383,7 +1393,7 @@ impl Render for List<Vector> {
13831393

13841394
for operation in &order {
13851395
match operation {
1386-
Op::Fill => do_fill(scene),
1396+
Op::Fill => do_fill(scene, context),
13871397
Op::Stroke => do_stroke(scene, 1.),
13881398
}
13891399
}

node-graph/nodes/math/src/lib.rs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
use core_types::Context;
2-
use core_types::list::List;
2+
use core_types::list::{ATTR_FILL_GRAPHIC, List};
33
use core_types::registry::types::{Fraction, Percentage, PixelSize};
44
use core_types::transform::Footprint;
55
use core_types::{Color, Ctx, num_traits};
66
use glam::{DAffine2, DVec2};
77
use graphic_types::raster_types::{CPU, GPU, Raster};
8-
use graphic_types::{Artboard, Graphic, Vector};
8+
use graphic_types::{Artboard, Graphic, IntoGraphicList, Vector};
99
use log::warn;
1010
use math_parser::ast;
1111
use math_parser::context::{EvalContext, NothingMap, ValueProvider};
@@ -984,6 +984,29 @@ fn normalize(_: impl Ctx, vector: DVec2) -> DVec2 {
984984
vector.normalize_or_zero()
985985
}
986986

987+
/// Sets the `fill_graphic` attribute on each item of the input vector list.
988+
/// Used for testing of clipping-based fill rendering until the proper Fill node refactor lands.
989+
#[node_macro::node(category("Debug"))]
990+
fn fill_graphic<P: IntoGraphicList + 'n + Send>(
991+
_: impl Ctx,
992+
mut vectors: List<Vector>,
993+
#[implementations(
994+
List<Graphic>,
995+
List<Vector>,
996+
List<Raster<CPU>>,
997+
List<Raster<GPU>>,
998+
List<Color>,
999+
List<GradientStops>,
1000+
)]
1001+
fill_graphic: P,
1002+
) -> List<Vector> {
1003+
let paint_list = fill_graphic.into_graphic_list();
1004+
for row_idx in 0..vectors.len() {
1005+
vectors.set_attribute(ATTR_FILL_GRAPHIC, row_idx, paint_list.clone());
1006+
}
1007+
vectors
1008+
}
1009+
9871010
#[cfg(test)]
9881011
mod test {
9891012
use super::*;

0 commit comments

Comments
 (0)