mirror of
https://github.com/storytold/vectorcraft.git
synced 2026-11-12 15:52:52 +00:00
Merge main into feat/plugin-effect-paint
This commit is contained in:
@@ -329,6 +329,10 @@ pub struct Scaling {
|
||||
/// Pattern fills and strokes move with the art (Transform Patterns; General › Transform
|
||||
/// Pattern Tiles is its default): their tiles transform too, instead of staying put.
|
||||
pub patterns: bool,
|
||||
/// Gradients fitted to the object stay fitted under a transform that flattens it to a line or
|
||||
/// a point (no area left), as a Transform effect leaves them, instead of being fixed to their
|
||||
/// fit and flattened to one color with the object.
|
||||
pub keep_fit_when_flat: bool,
|
||||
}
|
||||
|
||||
impl Scaling {
|
||||
|
||||
@@ -433,7 +433,7 @@ impl Node {
|
||||
// Type and symbols in perspective keep looking the same, moved by `a`.
|
||||
self.transform_projection(a);
|
||||
// Refitting an unplaced gradient only reproduces moves and uniform scales.
|
||||
if !keeps_gradient_fit(a) {
|
||||
if !keeps_gradient_fit(a) && !(sc.keep_fit_when_flat && flattens(a)) {
|
||||
self.pin_gradients();
|
||||
}
|
||||
let k = Scaling::factor(a);
|
||||
@@ -772,13 +772,24 @@ impl Node {
|
||||
}
|
||||
}
|
||||
|
||||
/// Is `a` a move plus a positive uniform scale (after which a refit gradient still matches)?
|
||||
fn keeps_gradient_fit(a: Affine) -> bool {
|
||||
/// Is `a` a move plus a positive uniform scale (after which a refit gradient still matches)? The
|
||||
/// terms are compared within 1e-12 of the scale (at least of 1). A scale of 0 or less, a turn, a
|
||||
/// reflection and an uneven scale give false, and so does a map that flattens the object
|
||||
/// ([`flattens`]), which callers that keep a fitted gradient there check apart.
|
||||
pub fn keeps_gradient_fit(a: Affine) -> bool {
|
||||
let [m0, m1, m2, m3, _, _] = a.as_coeffs();
|
||||
let eps = 1e-12 * m0.abs().max(1.0);
|
||||
m0 > 0.0 && m1.abs() <= eps && m2.abs() <= eps && (m0 - m3).abs() <= eps
|
||||
}
|
||||
|
||||
/// Does `a` flatten what it maps to a line or a point (its determinant 0, within 1e-12 of the
|
||||
/// squares of its terms), or is it not finite?
|
||||
pub fn flattens(a: Affine) -> bool {
|
||||
let [m0, m1, m2, m3, _, _] = a.as_coeffs();
|
||||
let norm = m0 * m0 + m1 * m1 + m2 * m2 + m3 * m3;
|
||||
!a.is_finite() || a.determinant().abs() <= 1e-12 * norm
|
||||
}
|
||||
|
||||
impl Node {
|
||||
/// Whether a document point lies in this object's filled regions ([`Node::clip_shapes`]; true
|
||||
/// everywhere for objects without them, such as type, whose boxes stand in).
|
||||
|
||||
@@ -221,7 +221,8 @@ fn assert_round_corners(n: &Node, back: Affine, r: f64) {
|
||||
}
|
||||
}
|
||||
|
||||
const KEEP_CORNERS: Scaling = Scaling { strokes: false, effects: None, keep_type_strokes: false, keep_corners: true, patterns: false };
|
||||
const KEEP_CORNERS: Scaling =
|
||||
Scaling { strokes: false, effects: None, keep_type_strokes: false, keep_corners: true, patterns: false, keep_fit_when_flat: false };
|
||||
|
||||
#[test]
|
||||
fn uneven_scales_keep_live_corners_circular() {
|
||||
|
||||
Reference in New Issue
Block a user