mirror of
https://github.com/storytold/figcraft.git
synced 2026-11-08 19:42:05 +00:00
.fig import: the round-trip test asserts the scaled size; text on a path takes the instance's size (#2100 review)
The scaled-instance round-trip test now asserts the scaled width and height instead of printing them. text_path read the layer's raw size, so a text on a path inside a scaled instance kept the main's path length; it now uses the scaled or fitted size. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Model-Effort: Opus 5.5 drove; Opus 5.5 briefed; Sonnet 5.5 wrote at medium
This commit is contained in:
1 parent
c7c5a4f87d
commit
9303b73991
3 files changed
+60
-8
No files matched your search
@@ -1048,6 +1048,9 @@ fn a_scaled_instance_keeps_its_radius_through_a_round_trip() {
|
||||
let (back, _) = import(&bytes, "x").unwrap();
|
||||
let inst = back.nodes().find(|n| n.name == "Scaled").unwrap();
|
||||
let b = inst.children.iter().map(|c| back.node(*c).unwrap()).find(|n| n.name == "Box").unwrap();
|
||||
eprintln!("scaled box back: {}x{} radii {:?}", b.width, b.height, b.corners.radii);
|
||||
// The 40 px box at the instance's 1.5 scale. The exporter writes every scaled value of a layer
|
||||
// in a derived row, so there is no main-layer value left unwritten here to round-trip; the
|
||||
// scaling of values with no row stays covered by `scale_factor_tests`.
|
||||
assert_eq!((b.width, b.height), (60.0, 60.0));
|
||||
assert_eq!(b.corners.radii, [15.0; 4]);
|
||||
}
|
||||
@@ -186,11 +186,7 @@ impl<'a> Mapper<'a> {
|
||||
fail(self, "has invalid normalized size");
|
||||
return;
|
||||
};
|
||||
let Some(size) = v.get("size") else {
|
||||
fail(self, "has invalid dimensions");
|
||||
return;
|
||||
};
|
||||
let (Some(nx), Some(ny), Some(w), Some(h)) = (num(norm, "x"), num(norm, "y"), num(size, "x"), num(size, "y")) else {
|
||||
let (Some(nx), Some(ny), Some((w, h))) = (num(norm, "x"), num(norm, "y"), v.size()) else {
|
||||
fail(self, "has invalid dimensions");
|
||||
return;
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use super::kiwi::Kv;
|
||||
|
||||
const SCHEMA: &str = "
|
||||
enum NodeType DOCUMENT CANVAS TEXT TEXT_PATH
|
||||
enum NodeType DOCUMENT CANVAS TEXT TEXT_PATH SYMBOL INSTANCE
|
||||
enum StyleType NONE TEXT
|
||||
enum TextDecoration NONE UNDERLINE STRIKETHROUGH
|
||||
struct GUID uint sessionID, uint localID
|
||||
@@ -17,7 +17,8 @@ message TextData string characters, uint[] characterStyleIDs, TextOverride[] sty
|
||||
message TextPathStart float tValue, bool forward
|
||||
message VectorData uint vectorNetworkBlob, Vector normalizedSize
|
||||
message Blob byte[] bytes
|
||||
message NodeChange GUID guid, ParentIndex parentIndex, NodeType type, string name, Vector size, Matrix transform, TextData textData, float fontSize, FontName fontName, TextPathStart textPathStart, VectorData vectorData, StyleType styleType, StyleId styleIdForText, TextDecoration textDecoration
|
||||
message SymbolData GUID symbolID, float uniformScaleFactor
|
||||
message NodeChange GUID guid, ParentIndex parentIndex, NodeType type, string name, Vector size, Matrix transform, TextData textData, float fontSize, FontName fontName, TextPathStart textPathStart, VectorData vectorData, StyleType styleType, StyleId styleIdForText, TextDecoration textDecoration, SymbolData symbolData
|
||||
message Message NodeChange[] nodeChanges, Blob[] blobs
|
||||
";
|
||||
use figcraft_doc::{NodeKind, TextPath};
|
||||
@@ -209,3 +210,55 @@ fn linked_text_style_decoration_warns_from_effective_mapped_style() {
|
||||
assert_eq!(json["document"]["children"][0]["children"][0]["style"]["textDecoration"], "UNDERLINE");
|
||||
assert!(warnings.iter().any(|w| w == "text path underline or strikethrough decoration is not rendered"), "{warnings:?}");
|
||||
}
|
||||
|
||||
/// A component holding a text on a path (path 100 long) and a half-scale instance of it.
|
||||
fn scaled_instance_message() -> Kv<'static> {
|
||||
let identity = || o(vec![("m00", f(1.0)), ("m01", f(0.0)), ("m02", f(0.0)), ("m10", f(0.0)), ("m11", f(1.0)), ("m12", f(0.0))]);
|
||||
let nodes = vec![
|
||||
node(0, None, "DOCUMENT", vec![]),
|
||||
node(1, Some(0), "CANVAS", vec![]),
|
||||
node(5, Some(1), "SYMBOL", vec![("name", s("Main")), ("size", point(100.0, 100.0)), ("transform", identity())]),
|
||||
node(
|
||||
6,
|
||||
Some(5),
|
||||
"TEXT_PATH",
|
||||
vec![
|
||||
("name", s("arc")),
|
||||
("size", point(100.0, 0.0)),
|
||||
("transform", identity()),
|
||||
("textData", o(vec![("characters", s("alpha"))])),
|
||||
("fontSize", f(24.0)),
|
||||
("fontName", o(vec![("family", s("Inter")), ("style", s("Regular"))])),
|
||||
("textPathStart", o(vec![("tValue", f(0.5)), ("forward", Kv::Bool(true))])),
|
||||
("vectorData", o(vec![("vectorNetworkBlob", u(0)), ("normalizedSize", point(100.0, 0.0))])),
|
||||
],
|
||||
),
|
||||
node(
|
||||
9,
|
||||
Some(1),
|
||||
"INSTANCE",
|
||||
vec![
|
||||
("name", s("Half")),
|
||||
("size", point(50.0, 50.0)),
|
||||
("transform", identity()),
|
||||
("symbolData", o(vec![("symbolID", guid(5)), ("uniformScaleFactor", f(0.5))])),
|
||||
],
|
||||
),
|
||||
];
|
||||
o(vec![("nodeChanges", a(nodes)), ("blobs", a(vec![o(vec![("bytes", Kv::Bytes(blob()))])]))])
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn a_text_on_a_path_in_a_scaled_instance_has_its_path_scaled() {
|
||||
let (json, warnings, _) = super::map::to_rest(&scaled_instance_message(), "Scaled path", crate::rest::MAX_NODES);
|
||||
assert!(!warnings.iter().any(|w| w.contains("text path")), "{warnings:?}");
|
||||
let (doc, _) = crate::rest::import_fig(&json, &|_| None).unwrap();
|
||||
let path_of = |parent: &str| {
|
||||
let parent = doc.nodes().find(|n| n.name == parent).unwrap();
|
||||
let node = doc.node(parent.children[0]).unwrap();
|
||||
let NodeKind::Text(text) = &node.kind else { panic!("expected text") };
|
||||
text.path.as_deref().unwrap().d.clone()
|
||||
};
|
||||
assert_eq!(path_of("Main"), "M0,0 L100,0");
|
||||
assert_eq!(path_of("Half"), "M0,0 L50,0");
|
||||
}
|
||||
Reference in new issue
Block a user