mirror of
https://github.com/GraphiteEditor/Graphite.git
synced 2026-09-18 18:38:05 +08:00
Refactor transform decomposition API with skew support, add 'Decompose Skew' node, and fix stroke transform interpolation (#3973)
* Refactor transform decomposition API with skew support, add Decompose Skew node, and fix stroke transform interpolation * Fix bug in master with skew changing Area node calculated value * Code review simplification * More code review fixes * Rename cases where "shear" terminology was used in place of "skew"
This commit is contained in:
@@ -22,7 +22,7 @@ pub async fn pixel_preview<'a: 'n>(
|
||||
let physical_scale = render_params.scale;
|
||||
|
||||
let footprint = *ctx.footprint();
|
||||
let viewport_zoom = footprint.decompose_scale().x * physical_scale;
|
||||
let viewport_zoom = footprint.scale_magnitudes().x * physical_scale;
|
||||
|
||||
if render_params.render_mode != RenderMode::PixelPreview || !matches!(render_params.render_output_type, RenderOutputTypeRequest::Vello) || viewport_zoom <= 1. {
|
||||
let context = OwnedContextImpl::from(ctx).into_context();
|
||||
|
||||
@@ -393,7 +393,7 @@ pub async fn render_output_cache<'a: 'n>(
|
||||
}
|
||||
|
||||
let device_scale = render_params.scale;
|
||||
let zoom = footprint.decompose_scale().x;
|
||||
let zoom = footprint.scale_magnitudes().x;
|
||||
let rotation = footprint.decompose_rotation();
|
||||
|
||||
let viewport_origin_offset = footprint.transform.translation;
|
||||
|
||||
@@ -108,7 +108,7 @@ async fn create_context<'a: 'n>(
|
||||
render_output_type,
|
||||
footprint: Footprint::default(),
|
||||
scale: render_config.scale,
|
||||
viewport_zoom: footprint.decompose_scale().x,
|
||||
viewport_zoom: footprint.scale_magnitudes().x,
|
||||
..Default::default()
|
||||
};
|
||||
|
||||
|
||||
@@ -203,7 +203,7 @@ pub fn mask(
|
||||
.into_iter()
|
||||
.filter_map(|mut row| {
|
||||
let image_size = DVec2::new(row.element.width as f64, row.element.height as f64);
|
||||
let mask_size = stencil.transform.decompose_scale();
|
||||
let mask_size = stencil.transform.scale_magnitudes();
|
||||
|
||||
if mask_size == DVec2::ZERO {
|
||||
return None;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use core::f64;
|
||||
use core_types::color::Color;
|
||||
use core_types::table::Table;
|
||||
use core_types::transform::{ApplyTransform, Transform};
|
||||
use core_types::transform::{ApplyTransform, ScaleType, Transform};
|
||||
use core_types::{CloneVarArgs, Context, Ctx, ExtractAll, InjectFootprint, ModifyFootprint, OwnedContextImpl};
|
||||
use glam::{DAffine2, DMat2, DVec2};
|
||||
use graphic_types::Graphic;
|
||||
@@ -77,7 +77,7 @@ fn reset_transform<T>(
|
||||
row.transform.matrix2 = DMat2::IDENTITY;
|
||||
}
|
||||
(true, false) => {
|
||||
let scale = row.transform.decompose_scale();
|
||||
let scale = row.transform.scale_magnitudes();
|
||||
row.transform.matrix2 = DMat2::from_diagonal(scale);
|
||||
}
|
||||
(false, true) => {
|
||||
@@ -143,15 +143,24 @@ fn decompose_translation(_: impl Ctx, transform: DAffine2) -> DVec2 {
|
||||
}
|
||||
|
||||
/// Extracts the rotation component (in degrees) from the input transform.
|
||||
/// This, together with the "Decompose Scale" node, also may jointly represent any shear component in the original transform.
|
||||
#[node_macro::node(category("Math: Transform"))]
|
||||
fn decompose_rotation(_: impl Ctx, transform: DAffine2) -> f64 {
|
||||
transform.decompose_rotation().to_degrees()
|
||||
}
|
||||
|
||||
/// Extracts the scale component from the input transform.
|
||||
/// This, together with the "Decompose Rotation" node, also may jointly represent any shear component in the original transform.
|
||||
/// **Magnitude** returns the visual length of each axis (always positive, includes any skew contribution).
|
||||
/// **Pure** returns the isolated scale factors with rotation and skew stripped away (can be negative for flipped axes).
|
||||
#[node_macro::node(category("Math: Transform"))]
|
||||
fn decompose_scale(_: impl Ctx, transform: DAffine2) -> DVec2 {
|
||||
transform.decompose_scale()
|
||||
fn decompose_scale(_: impl Ctx, transform: DAffine2, scale_type: ScaleType) -> DVec2 {
|
||||
match scale_type {
|
||||
ScaleType::Magnitude => transform.scale_magnitudes(),
|
||||
ScaleType::Pure => transform.decompose_scale(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Extracts the skew angle (in degrees) from the input transform.
|
||||
#[node_macro::node(category("Math: Transform"))]
|
||||
fn decompose_skew(_: impl Ctx, transform: DAffine2) -> f64 {
|
||||
transform.decompose_skew().atan().to_degrees()
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use core::hash::{Hash, Hasher};
|
||||
use core_types::bounds::{BoundingBox, RenderBoundingBox};
|
||||
use core_types::registry::types::{Angle, Length, Multiplier, Percentage, PixelLength, Progression, SeedValue};
|
||||
use core_types::table::{Table, TableRow, TableRowMut};
|
||||
use core_types::transform::{Footprint, Transform};
|
||||
use core_types::transform::Footprint;
|
||||
use core_types::{CloneVarArgs, Color, Context, Ctx, ExtractAll, OwnedContextImpl};
|
||||
use glam::{DAffine2, DVec2};
|
||||
use graphic_types::Vector;
|
||||
@@ -2534,8 +2534,8 @@ async fn area(ctx: impl Ctx + CloneVarArgs + ExtractAll, content: impl Node<Cont
|
||||
vector
|
||||
.iter()
|
||||
.map(|row| {
|
||||
let scale = row.transform.decompose_scale();
|
||||
row.element.stroke_bezpath_iter().map(|subpath| subpath.area() * scale.x * scale.y).sum::<f64>()
|
||||
let area_scale = row.transform.matrix2.determinant().abs();
|
||||
row.element.stroke_bezpath_iter().map(|subpath| subpath.area() * area_scale).sum::<f64>()
|
||||
})
|
||||
.sum()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user