Files
Graphite/node-graph/nodes/graphic/src/artboard.rs
Jatin Bharti 5f100946f2 Add String[] as a graphic type for typography (#4141)
* feat: Render List<String> as raw paths in SVG and Vell mode

* chore: code review

* chore: change the hardcoded layout bounds to parley's

* chore: code review

* feat: Split text node to text_layer and text_to_vector node

* fix: CI fail because of difference in nature of Mac and github action

* chore: fix

* chore: replace FontStack as it got removed in parley 0.9

* chore: fmt

* chore: migrate the rendering as of new resource architechture

* chore: add text_layer node to text tool for testing

* code review

* Make boolean ops support the Text type

* chore: Move fallback_font_resource authority from editor to text node

* Fix 'Text Layer' node missing font dropdown

* Change node doc comments from Vec<T> to T[]

* Add migrations from the old Text node to Text -> Text to Vector

* Consolidate

* Rename the text attributes and reorder tilt to come before max_width/height

* Detect legacy Text nodes in the split migration by their trailing separate_glyphs input

* Code review

* Frame Text layer thumbnails by laying out their text for bounds

* Give Text layers click targets and selection outlines via collect_metadata

* Route Text tool through Text to Vector with fill, fixing editing-preview placement

---------

Co-authored-by: Keavon Chambers <keavon@keavon.com>
2026-06-19 19:39:52 +00:00

61 lines
2.5 KiB
Rust

use core_types::list::{Item, List};
use core_types::transform::TransformMut;
use core_types::{ATTR_BACKGROUND, ATTR_CLIP, ATTR_DIMENSIONS, ATTR_LOCATION, CloneVarArgs, Color, Context, Ctx, ExtractAll, OwnedContextImpl};
use glam::{DAffine2, DVec2};
use graphic_types::graphic::{Graphic, IntoGraphicList};
use graphic_types::{Artboard, Vector};
use raster_types::{CPU, GPU, Raster};
use vector_types::GradientStops;
/// Constructs a single-element `Artboard[]` with the given content and metadata stored as row attributes.
#[node_macro::node(category(""))]
pub async fn create_artboard<T: IntoGraphicList + 'n>(
ctx: impl ExtractAll + CloneVarArgs + Ctx,
/// Graphics to include within the artboard.
#[implementations(
Context -> List<Graphic>,
Context -> List<Vector>,
Context -> List<String>,
Context -> List<Raster<CPU>>,
Context -> List<Raster<GPU>>,
Context -> List<Color>,
Context -> List<GradientStops>,
Context -> DAffine2,
)]
content: impl Node<Context<'static>, Output = T>,
/// Coordinate of the top-left corner of the artboard within the document.
location: DVec2,
/// Width and height of the artboard within the document.
dimensions: DVec2,
/// Color of the artboard background.
background: List<Color>,
/// Whether to cut off the contained content that extends outside the artboard, or keep it visible.
#[default(true)]
clip: bool,
) -> List<Artboard> {
let footprint = ctx.try_footprint().copied();
let mut new_ctx = OwnedContextImpl::from(ctx);
if let Some(mut footprint) = footprint {
footprint.translate(location);
new_ctx = new_ctx.with_footprint(footprint);
}
let content = content.eval(new_ctx.into_context()).await.into_graphic_list();
// Normalize so `location` is the top-left corner and `dimensions` are positive (allowing negative input
// dimensions to represent dragging from the opposite corner). Compute the corner using the raw signed
// dimensions before clamping, otherwise negative inputs collapse to the original corner instead of inverting.
let normalized_location = location.min(location + dimensions);
let normalized_dimensions = dimensions.abs().max(DVec2::ONE);
let background = background.element(0).copied().unwrap_or(Color::WHITE);
// Name is not stored here, it's resolved live from the parent layer's display name
List::new_from_item(
Item::new_from_element(Artboard::new(content))
.with_attribute(ATTR_LOCATION, normalized_location)
.with_attribute(ATTR_DIMENSIONS, normalized_dimensions)
.with_attribute(ATTR_BACKGROUND, background)
.with_attribute(ATTR_CLIP, clip),
)
}