Implement the Brush without relying on a stamp texture

Test Plan: Test the BrushNode in the editor

Reviewers: Keavon

Reviewed By: Keavon

Pull Request: https://github.com/GraphiteEditor/Graphite/pull/1184
This commit is contained in:
Dennis Kobert
2023-04-29 01:31:14 +02:00
committed by GitHub
parent baeef77b78
commit 666b4cf854
31 changed files with 221 additions and 178 deletions

View File

@@ -24,7 +24,7 @@ struct ModifyInputsContext<'a> {
impl<'a> ModifyInputsContext<'a> {
/// Get the node network from the document
fn new(layer: &'a [LayerId], document: &'a mut Document, node_graph: &'a mut NodeGraphMessageHandler, responses: &'a mut VecDeque<Message>) -> Option<Self> {
document.layer_mut(&layer).ok().and_then(|layer| layer.as_node_graph_mut().ok()).map(|network| Self {
document.layer_mut(layer).ok().and_then(|layer| layer.as_node_graph_mut().ok()).map(|network| Self {
network,
node_graph,
responses,

View File

@@ -1048,19 +1048,19 @@ pub fn wrap_network_in_scope(network: NodeNetwork) -> NodeNetwork {
let nodes = vec![
resolve_document_node_type("Begin Scope")
.expect("Begin Scope node type not found")
.to_document_node(vec![input_type.clone()], DocumentNodeMetadata::default()),
.to_document_node(vec![input_type], DocumentNodeMetadata::default()),
inner_network,
resolve_document_node_type("End Scope")
.expect("End Scope node type not found")
.to_document_node(vec![NodeInput::node(0, 0), NodeInput::node(1, 0)], DocumentNodeMetadata::default()),
];
let network = NodeNetwork {
NodeNetwork {
inputs: vec![0],
outputs: vec![NodeOutput::new(2, 0)],
nodes: nodes.into_iter().enumerate().map(|(id, node)| (id as NodeId, node)).collect(),
..Default::default()
};
network
}
}
pub fn new_image_network(output_offset: i32, output_node_id: NodeId) -> NodeNetwork {
@@ -1121,8 +1121,8 @@ pub fn new_text_network(text: String, font: Font, size: f64) -> NodeNetwork {
text_generator.to_document_node(
[
NodeInput::Network(concrete!(graphene_core::EditorApi)),
NodeInput::value(TaggedValue::String(text.clone()), false),
NodeInput::value(TaggedValue::Font(font.clone()), false),
NodeInput::value(TaggedValue::String(text), false),
NodeInput::value(TaggedValue::Font(font), false),
NodeInput::value(TaggedValue::F64(size), false),
],
DocumentNodeMetadata::position((0, 4)),

View File

@@ -149,10 +149,10 @@ impl ShapeState {
/// Move the selected points by dragging the mouse.
pub fn move_selected_points(&self, document: &Document, delta: DVec2, mirror_distance: bool, responses: &mut VecDeque<Message>) {
for (layer_path, state) in &self.selected_shape_state {
let Ok(layer) = document.layer(&layer_path) else { continue };
let Ok(layer) = document.layer(layer_path) else { continue };
let Some(vector_data) = layer.as_vector_data() else { continue };
let transform = document.multiply_transforms(&layer_path).unwrap_or_default();
let transform = document.multiply_transforms(layer_path).unwrap_or_default();
let delta = transform.inverse().transform_vector2(delta);
for &point in state.selected_points.iter() {

View File

@@ -315,7 +315,7 @@ fn add_brush_render(data: &BrushToolData, tool_data: &DocumentToolData, response
};
let mut network = NodeNetwork::value_network(brush_node);
network.push_output_node();
graph_modification_utils::new_custom_layer(network, layer_path.clone(), responses);
graph_modification_utils::new_custom_layer(network, layer_path, responses);
}
fn load_existing_points(document: &DocumentMessageHandler) -> Option<(Vec<LayerId>, Vec<DVec2>)> {

View File

@@ -223,7 +223,7 @@ fn add_polyline(data: &FreehandToolData, tool_data: &DocumentToolData, responses
graph_modification_utils::new_vector_layer(vec![subpath], layer_path.clone(), responses);
responses.add(GraphOperationMessage::StrokeSet {
layer: layer_path.clone(),
layer: layer_path,
stroke: Stroke::new(tool_data.primary_color, data.weight),
});
}

View File

@@ -164,7 +164,7 @@ impl Fsm for LineToolFsmState {
tool_data.path = Some(layer_path.clone());
graph_modification_utils::new_vector_layer(vec![subpath], layer_path.clone(), responses);
responses.add(GraphOperationMessage::StrokeSet {
layer: layer_path.clone(),
layer: layer_path,
stroke: Stroke::new(global_tool_data.primary_color, tool_options.line_weight),
});

View File

@@ -273,11 +273,9 @@ impl Fsm for PathToolFsmState {
if tool_data.opposing_handle_lengths.is_none() {
tool_data.opposing_handle_lengths = Some(shape_editor.opposing_handle_lengths(&document.document_legacy));
}
} else {
if let Some(opposing_handle_lengths) = &tool_data.opposing_handle_lengths {
shape_editor.reset_opposing_handle_lengths(&document.document_legacy, opposing_handle_lengths, responses);
tool_data.opposing_handle_lengths = None;
}
} else if let Some(opposing_handle_lengths) = &tool_data.opposing_handle_lengths {
shape_editor.reset_opposing_handle_lengths(&document.document_legacy, opposing_handle_lengths, responses);
tool_data.opposing_handle_lengths = None;
}
// Move the selected points by the mouse position
@@ -291,8 +289,7 @@ impl Fsm for PathToolFsmState {
(_, PathToolMessage::DragStop { shift_mirror_distance }) => {
let nearest_point = shape_editor
.find_nearest_point_indices(&document.document_legacy, input.mouse.position, SELECTION_THRESHOLD)
.map(|(_, nearest_point)| nearest_point)
.clone();
.map(|(_, nearest_point)| nearest_point);
let shift_pressed = input.keyboard.get(shift_mirror_distance as usize);
if tool_data.drag_start_pos.distance(input.mouse.position) <= DRAG_THRESHOLD && !shift_pressed {

View File

@@ -475,7 +475,7 @@ impl PenToolData {
modification: VectorDataModification::SetManipulatorPosition { point, position },
});
return Some(DocumentMessage::CommitTransaction);
Some(DocumentMessage::CommitTransaction)
}
}

View File

@@ -762,7 +762,7 @@ impl Fsm for SelectToolFsmState {
if let Some(path) = intersection.last() {
// let folders: Vec<_> = (1..path.len() + 1).map(|i| &path[0..i]).collect();
// let replacement_selected_layers: Vec<_> = document.selected_layers().filter(|&layer| !folders.contains(&layer)).map(|path| path.to_vec()).collect();
let replacement_selected_layers: Vec<_> = document.selected_layers().filter(|&layer| !path.starts_with(&layer)).map(|path| path.to_vec()).collect();
let replacement_selected_layers: Vec<_> = document.selected_layers().filter(|&layer| !path.starts_with(layer)).map(|path| path.to_vec()).collect();
tool_data.layers_dragging.clear();
tool_data.layers_dragging.append(replacement_selected_layers.clone().as_mut());
@@ -999,7 +999,7 @@ fn drag_shallowest_manipulation(
// Checks if the incoming layer's root parent is already selected
// If so we need to update the selected layer to the deeper of the two
let mut layers_without_incoming_parent: Vec<Vec<u64>> = document.selected_layers().filter(|&layer| layer != [incoming_parent].as_slice()).map(|path| path.to_vec()).collect();
if layers.contains(&&[incoming_parent].as_slice()) {
if layers.contains(&[incoming_parent].as_slice()) {
// Add incoming layer
tool_data.layers_dragging.clear();
responses.add(DocumentMessage::DeselectAllLayers);
@@ -1028,7 +1028,7 @@ fn drag_shallowest_manipulation(
// Check if the intersected layer path is already selected
let previous_parents: Vec<_> = (0..layers.len()).map(|i| &layers.get(i).unwrap()[..1]).collect();
let already_selected_parent = previous_parents.contains(&&[incoming_parent].as_slice());
let already_selected_parent = previous_parents.contains(&[incoming_parent].as_slice());
let selected_layers: Vec<_> = document.selected_layers().collect();
let mut search = previous_layer_path.to_vec();
@@ -1042,7 +1042,7 @@ fn drag_shallowest_manipulation(
selected_layer_path_parent = selected_layer_path_parent[..selected_layer_path_parent.len() - 1].to_vec();
}
while selected_layer_path_parent.len() > 0 && !is_parent && !recursive_found {
while !selected_layer_path_parent.is_empty() && !is_parent && !recursive_found {
let selected_children_layer_paths = document.document_legacy.folder_children_paths(&selected_layer_path_parent);
for child in selected_children_layer_paths {
if child == *incoming_layer_path_vector {
@@ -1062,7 +1062,7 @@ fn drag_shallowest_manipulation(
// Check if new layer is already selected
let mut already_selected = false;
if selected_layers.contains(&search.clone().as_slice()) {
if selected_layers.contains(&search.as_slice()) {
already_selected = true;
}
@@ -1086,7 +1086,7 @@ fn drag_shallowest_manipulation(
} else {
// Previous selected layers with the intersect layer path appended to it
let mut combined_layers = selected_layers.clone();
let intersection_temp = intersection.clone();
let intersection_temp = intersection;
let intersection_temp_slice = intersection_temp.as_slice();
combined_layers.push(intersection_temp_slice);
let layers_iter = combined_layers.into_iter();
@@ -1162,7 +1162,7 @@ fn edit_layer_shallowest_manipulation(document: &DocumentMessageHandler, interse
let incoming_parent = *intersect_layer_path.first().unwrap();
let previous_parents: Vec<_> = (0..selected_layers.len()).map(|i| &selected_layers.get(i).unwrap()[..1]).collect();
let mut incoming_parent_selected = false;
if previous_parents.contains(&&[incoming_parent].as_slice()) {
if previous_parents.contains(&[incoming_parent].as_slice()) {
incoming_parent_selected = true;
}
if incoming_parent_selected {
@@ -1225,11 +1225,9 @@ fn recursive_search(document: &DocumentMessageHandler, layer_path: &Vec<u64>, in
for path in layer_paths {
if path == *incoming_layer_path_vector {
return true;
} else if document.document_legacy.is_folder(path.clone()) {
if recursive_search(document, &path, incoming_layer_path_vector) {
return true;
}
} else if document.document_legacy.is_folder(path.clone()) && recursive_search(document, &path, incoming_layer_path_vector) {
return true;
}
}
return false;
false
}

View File

@@ -280,7 +280,7 @@ impl TextToolData {
else if let Some(editing_text) = self.editing_text.as_ref().filter(|_| state == TextToolFsmState::Ready) {
responses.add(DocumentMessage::StartTransaction);
let network = new_text_network(String::new(), editing_text.font.clone(), editing_text.font_size as f64);
let network = new_text_network(String::new(), editing_text.font.clone(), editing_text.font_size);
responses.add(Operation::AddFrame {
path: self.layer_path.clone(),
@@ -320,7 +320,7 @@ impl TextToolData {
resize_overlays(&mut self.overlays, responses, 1);
let editing_text = self.editing_text.as_ref()?;
let buzz_face = render_data.font_cache.get(&editing_text.font).map(|data| load_face(&data));
let buzz_face = render_data.font_cache.get(&editing_text.font).map(|data| load_face(data));
let far = graphene_core::text::bounding_box(&self.new_text, buzz_face, editing_text.font_size, None);
let quad = Quad::from_box([DVec2::ZERO, far]);
@@ -337,8 +337,8 @@ impl TextToolData {
fn get_bounds(&self, text: &str, render_data: &RenderData) -> Option<[DVec2; 2]> {
let editing_text = self.editing_text.as_ref()?;
let buzz_face = render_data.font_cache.get(&editing_text.font).map(|data| load_face(&data));
let subpaths = graphene_core::text::to_path(&text, buzz_face, editing_text.font_size, None);
let buzz_face = render_data.font_cache.get(&editing_text.font).map(|data| load_face(data));
let subpaths = graphene_core::text::to_path(text, buzz_face, editing_text.font_size, None);
let bounds = subpaths.iter().filter_map(|subpath| subpath.bounding_box());
let combined_bounds = bounds.reduce(|a, b| [a[0].min(b[0]), a[1].max(b[1])]).unwrap_or_default();
Some(combined_bounds)
@@ -383,8 +383,8 @@ fn update_overlays(document: &DocumentMessageHandler, tool_data: &mut TextToolDa
let node_id = get_text_node_id(node_graph)?;
let document_node = node_graph.nodes.get(&node_id)?;
let (text, font, font_size) = TextToolData::extract_text_node_inputs(document_node)?;
let buzz_face = render_data.font_cache.get(font).map(|data| load_face(&data));
let far = graphene_core::text::bounding_box(&text, buzz_face, font_size, None);
let buzz_face = render_data.font_cache.get(font).map(|data| load_face(data));
let far = graphene_core::text::bounding_box(text, buzz_face, font_size, None);
let quad = Quad::from_box([DVec2::ZERO, far]);
let multiplied = document.document_legacy.multiply_transforms(path).ok()? * quad;
Some(multiplied.bounding_box())
@@ -474,7 +474,7 @@ impl Fsm for TextToolFsmState {
tool_data.new_text = String::new();
tool_data.layer_path = document.get_path_for_new_layer();
tool_data.interact(state, input.mouse.position, document, &render_data, responses)
tool_data.interact(state, input.mouse.position, document, render_data, responses)
}
(state, TextToolMessage::EditSelected) => {
if let Some(layer_path) = can_edit_selected(document) {

View File

@@ -65,10 +65,10 @@ impl<'a> MessageHandler<TransformLayerMessage, TransformData<'a>> for TransformL
}
if using_path_tool {
if let Ok(layer) = document.document_legacy.layer(&selected_layers[0]) {
if let Ok(layer) = document.document_legacy.layer(selected_layers[0]) {
if let Some(vector_data) = layer.as_vector_data() {
*selected.original_transforms = OriginalTransforms::default();
let viewspace = &mut document.document_legacy.generate_transform_relative_to_viewport(&selected_layers[0]).ok().unwrap_or_default();
let viewspace = &mut document.document_legacy.generate_transform_relative_to_viewport(selected_layers[0]).ok().unwrap_or_default();
let mut point_count: usize = 0;
let count_point = |position| {