mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-27 08:28:11 +08:00
Refactor internal shape and reduce reliance on Kurbo (#617)
* Dissolve Points from path * Add handling for removing the first anchor * Add function to turn handles into bez_paths * Created overlay manager, wip * WIP Refactor of VectorShape / Overlays / ShapeEditor * WIP stripping vector shape, anchor, point. * WIP Removed kurbo deps from vector shape, anchor, point * WIP Further work to make vector shapes / anchors / points more standalone. * WIP more pruning * WIP Progress on overlay_renderer * WIP more overlay_renderer work * WIP more pruning, cleared warnings * WIP decided ShapeRenderer wasn't an accurate name, ShapeAdapter now. Error squashing continues. * WIP squashed more errors, now need to decide if anchors should have unique IDs * WIP Errors squashed, now to actually make it work. * WIP Moved vector structs to graphene, beginning to remove bezpath from shape_layer * Refactoring: disentangle kurbo from apply_affine * Refactor internal shape and remove reliance on Kurbo (PR #617) - Disentangle Kurbo (#619) * Refactoring: disentangle kurbo from apply_affine * Broke boolean operations, refactor in state which compiles * "fixed" boolean operation refactor related errors * fixed apply_affine, which would not have applied any type of affine * Small Cleanup, readability * Fix issue with overlay styles no longer showing selection state. * Resolved error with point option * WIP, figuring out how to have one source of truth for VectorShape. Trying to avoid cloning. * WIP work on single source of truth vectorshapes * More steps toward single source of truth VectorShape * Continued wip on making VectorShapes mutably accessible without cloning * Wip using paths to reference vectorshapes instead, need to restructure ShapeEditor * Decided to allow temporary copies of vectorshapes. * Removed HashSet for selected shape indices * Added @TrueDoctor's id_storage.rs with some heavy modification. Added it to VectorShape. Isn't yet used for folders. * Integrated UniqueElements<T> with VectorShape to store VectorAnchors * Improved storage_id.rs perf and cleaned up it's interface * Iterator Implementations and fixes (#637) * Refactoring: disentangle kurbo from apply_affine * Broke boolean operations, refactor in state which compiles * "fixed" boolean operation refactor related errors * fixed apply_affine, which would not have applied any type of affine * implemented transforms for VectorAnchors implemented Not for VectorControlPointType * started adding Vector Shape implementations of shape prototypes * added several useful implemtations to UniqueElements * added another implemnation for UniqueElements to make working with iterators easier, fixed vector-shape errors * package-lock.json * clean up rebase, added back Layer paths * added deref implementation for VectorShape * unnecesary variable * simplify code by removing levels of indirection * fixed errors * merge cleanup * removed package-lock.json * Removed .selected from VectorShape, it isn't needed as layers are selected not shapes specifically. * Removed transform and layer_path from VectorShape * Auto-saving tentitively working. Work toward Overlay transform issues. * Overlays properly hiding and caching. Not clearing cache yet and some tool switching issues remain, but progress. * Putting layers in folders changes their unique ID. This is problematic. Assumed this was not the case. * Removed need for closed bool, changed VectorShape to a tuple struct. * WIP Switched to layer paths as opposed to VectorShapes. Next up add messages for changing VectorShapes. * Added initial messages to edit VectorShape points. * DeleteSelectedPoints messages implemented, selection isn't working currently though. * Selection messages arriving in document, but transform is wrong. * Selection, Deselection working, delete working for first point. * Working towards moving points again * Removed extra vec from UniqueElements, attempting to squash ordering bug. Still appears to occur though. * Delete more stable, clean up, renamed to HandleIn, HandleOut * Further vec_unique cleanup * Further cleanup * Removed Deref / DerefMut from VectorShape * Document version++, will likely revert before merge into master * Seleting / deleting handles tentitively working again. * Version number bump, fixed tests. * Fixed comment in VecUnique * Improved VecUnique descriptor comment * Renamed VecUnique to IdBackedVec to further clarify usage. * Resolved formatting. * WIP Fixing dragging points * Fixed an instance where an OverlayMessage could be sent to the main document incorrectly. * Deleting all of a shapes points now gracefully deletes the layer instead of crashing. * Fixed handle configurations that would panic on deletion * Single anchor dragging restored with multi-dragging next plus handles * sides.into() * Handle and Multi-point dragging working * WIP Handle symmetry working again * Handle mirroring functional again. * Cleaned up warnings * Fixed overlay outline not matching shape * Git branch fix of compatibility with new master * Fixed closed shape bug, replaced kurbo ellipse * Removed unused func, updated comments * Deleting points can undo, multiple shape selection deletes now working * Removed AddOverlay* operations * Partial fix for select drift, added helpers * Don't snap against dragging points * Properly cleanup path outline with multiple shapes * Clear all points in other selected shapes * Actually don't snap against dragging points * Fix path tool & add snap angle and break handle * Fix handle being set to NaN causing render issues * Fix cached overlays not showing line -> curve * Add operations for modifying paths * Remove kurbo from pen tool * Do not snap against handles when anchor selected * Fix overlays not being cleaned up on path tool * Fix handle position after dragging * Use `Anchor` for text & no kurbo in operations * Replace kurbo to_svg function * Ngon no longer center scales by default, still some weird behaviour when holding alt * Cleanup overlays * Fix render and bounding box doctests * Fix fun to_svg error * Fix compile error * Some code review * Remove legacy `SelectPoint` on doubleclick * Remove font from test document * Fix the pen tool selection changed * Reorder imports Co-authored-by: Dennis <dennis@kobert.dev> Co-authored-by: Caleb Dennis <caleb.dennis429@gmail.com> Co-authored-by: caleb <56044292+caleb-ad@users.noreply.github.com> Co-authored-by: Keavon Chambers <keavon@keavon.com> Co-authored-by: 0hypercube <0hypercube@gmail.com> Co-authored-by: 0HyperCube <78500760+0HyperCube@users.noreply.github.com>
This commit is contained in:
committed by
Keavon Chambers
co-authored by
Dennis
Caleb Dennis
caleb
Keavon Chambers
0hypercube
0HyperCube
parent
3c2fff4465
commit
58675eb64d
@@ -1,21 +1,17 @@
|
||||
use super::layer_info::LayerData;
|
||||
use super::style::{PathStyle, RenderData, ViewMode};
|
||||
use super::vector::vector_shape::VectorShape;
|
||||
use crate::intersection::{intersect_quad_bez_path, Quad};
|
||||
use crate::LayerId;
|
||||
pub use font_cache::{Font, FontCache};
|
||||
|
||||
use glam::{DAffine2, DMat2, DVec2};
|
||||
use kurbo::{Affine, BezPath, Rect, Shape};
|
||||
use rustybuzz::Face;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fmt::Write;
|
||||
|
||||
mod font_cache;
|
||||
mod to_kurbo;
|
||||
|
||||
fn glam_to_kurbo(transform: DAffine2) -> Affine {
|
||||
Affine::new(transform.to_cols_array())
|
||||
}
|
||||
mod to_path;
|
||||
|
||||
/// A line, or multiple lines, of text drawn in the document.
|
||||
/// Like [ShapeLayers](super::shape_layer::ShapeLayer), [TextLayer] are rendered as
|
||||
@@ -33,7 +29,7 @@ pub struct TextLayer {
|
||||
#[serde(skip)]
|
||||
pub editable: bool,
|
||||
#[serde(skip)]
|
||||
pub cached_path: Option<BezPath>,
|
||||
pub cached_path: Option<VectorShape>,
|
||||
}
|
||||
|
||||
impl LayerData for TextLayer {
|
||||
@@ -72,12 +68,12 @@ impl LayerData for TextLayer {
|
||||
} else {
|
||||
let buzz_face = self.load_face(render_data.font_cache);
|
||||
|
||||
let mut path = self.to_bez_path(buzz_face);
|
||||
let mut path = self.to_vector_path(buzz_face);
|
||||
|
||||
let kurbo::Rect { x0, y0, x1, y1 } = path.bounding_box();
|
||||
let bounds = [(x0, y0).into(), (x1, y1).into()];
|
||||
|
||||
path.apply_affine(glam_to_kurbo(transform));
|
||||
path.apply_affine(transform);
|
||||
|
||||
let kurbo::Rect { x0, y0, x1, y1 } = path.bounding_box();
|
||||
let transformed_bounds = [(x0, y0).into(), (x1, y1).into()];
|
||||
@@ -95,21 +91,17 @@ impl LayerData for TextLayer {
|
||||
fn bounding_box(&self, transform: glam::DAffine2, font_cache: &FontCache) -> Option<[DVec2; 2]> {
|
||||
let buzz_face = Some(self.load_face(font_cache)?);
|
||||
|
||||
let mut path = self.bounding_box(&self.text, buzz_face).to_path(0.1);
|
||||
|
||||
if transform.matrix2 == DMat2::ZERO {
|
||||
return None;
|
||||
}
|
||||
path.apply_affine(glam_to_kurbo(transform));
|
||||
|
||||
let kurbo::Rect { x0, y0, x1, y1 } = path.bounding_box();
|
||||
Some([(x0, y0).into(), (x1, y1).into()])
|
||||
Some((transform * self.bounding_box(&self.text, buzz_face)).bounding_box())
|
||||
}
|
||||
|
||||
fn intersects_quad(&self, quad: Quad, path: &mut Vec<LayerId>, intersections: &mut Vec<Vec<LayerId>>, font_cache: &FontCache) {
|
||||
let buzz_face = self.load_face(font_cache);
|
||||
|
||||
if intersect_quad_bez_path(quad, &self.bounding_box(&self.text, buzz_face).to_path(0.), true) {
|
||||
if intersect_quad_bez_path(quad, &self.bounding_box(&self.text, buzz_face).path(), true) {
|
||||
intersections.push(path.clone());
|
||||
}
|
||||
}
|
||||
@@ -144,10 +136,10 @@ impl TextLayer {
|
||||
new
|
||||
}
|
||||
|
||||
/// Converts to a [BezPath], populating the cache if necessary.
|
||||
/// Converts to a [VectorShape], populating the cache if necessary.
|
||||
#[inline]
|
||||
pub fn to_bez_path(&mut self, buzz_face: Option<Face>) -> BezPath {
|
||||
if self.cached_path.as_ref().filter(|x| !x.is_empty()).is_none() {
|
||||
pub fn to_vector_path(&mut self, buzz_face: Option<Face>) -> VectorShape {
|
||||
if self.cached_path.as_ref().filter(|x| !x.anchors().is_empty()).is_none() {
|
||||
let path = self.generate_path(buzz_face);
|
||||
self.cached_path = Some(path.clone());
|
||||
return path;
|
||||
@@ -155,23 +147,23 @@ impl TextLayer {
|
||||
self.cached_path.clone().unwrap()
|
||||
}
|
||||
|
||||
/// Converts to a [BezPath], without populating the cache.
|
||||
/// Converts to a [VectorShape], without populating the cache.
|
||||
#[inline]
|
||||
pub fn to_bez_path_nonmut(&self, font_cache: &FontCache) -> BezPath {
|
||||
pub fn to_vector_path_nonmut(&self, font_cache: &FontCache) -> VectorShape {
|
||||
let buzz_face = self.load_face(font_cache);
|
||||
|
||||
self.cached_path.clone().filter(|x| !x.is_empty()).unwrap_or_else(|| self.generate_path(buzz_face))
|
||||
self.cached_path.clone().filter(|x| !x.anchors().is_empty()).unwrap_or_else(|| self.generate_path(buzz_face))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn generate_path(&self, buzz_face: Option<Face>) -> BezPath {
|
||||
to_kurbo::to_kurbo(&self.text, buzz_face, self.size, self.line_width)
|
||||
pub fn generate_path(&self, buzz_face: Option<Face>) -> VectorShape {
|
||||
to_path::to_path(&self.text, buzz_face, self.size, self.line_width)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn bounding_box(&self, text: &str, buzz_face: Option<Face>) -> Rect {
|
||||
let far = to_kurbo::bounding_box(text, buzz_face, self.size, self.line_width);
|
||||
Rect::new(0., 0., far.x, far.y)
|
||||
pub fn bounding_box(&self, text: &str, buzz_face: Option<Face>) -> Quad {
|
||||
let far = to_path::bounding_box(text, buzz_face, self.size, self.line_width);
|
||||
Quad::from_box([DVec2::ZERO, far])
|
||||
}
|
||||
|
||||
pub fn update_text(&mut self, text: String, font_cache: &FontCache) {
|
||||
|
||||
Reference in New Issue
Block a user