#552: write and read space evenly as SPACE_EVENLY_CSS

The format's SPACE_EVENLY is its older name for equal gaps without edge
space, so files keep reading it as space between; true space evenly is
SPACE_EVENLY_CSS, which the export now writes.
This commit is contained in:
bflatastic
2026-10-17 22:39:10 +07:00
parent 6afcfc2641
commit 9a69f79861
3 changed files with 33 additions and 7 deletions
@@ -1,8 +1,8 @@
//! How auto layout frames and text size on import (hug or fixed), on encoded `.fig` files built in
//! code and REST file JSON: the sizing a file records, an auto layout frame that records none, and
//! text that hugs by its resize mode.
//! text that hugs by its resize mode. Also how distributed main-axis alignment reads.
use figcraft_doc::{Document, Sizing};
use figcraft_doc::{Document, MainAlign, Sizing};
use serde_json::{Value, json};
use super::kiwi::{Kv, Schema};
@@ -11,6 +11,7 @@ const SCHEMA: &str = "
enum NodeType NONE DOCUMENT CANVAS FRAME TEXT SYMBOL INSTANCE
enum StackMode NONE HORIZONTAL VERTICAL
enum StackSize FIXED RESIZE_TO_FIT RESIZE_TO_FIT_WITH_IMPLICIT_SIZE
enum StackJustify MIN CENTER MAX SPACE_EVENLY SPACE_BETWEEN SPACE_AROUND SPACE_EVENLY_CSS
enum TextAutoResize NONE WIDTH_AND_HEIGHT HEIGHT
struct GUID uint sessionID, uint localID
struct Vector float x, float y
@@ -18,7 +19,7 @@ struct Matrix float m00, float m01, float m02, float m10, float m11, float m12
message ParentIndex GUID guid, string position
message TextData string characters
message SymbolData GUID symbolID
message NodeChange GUID guid, ParentIndex parentIndex, NodeType type, string name, Vector size, Matrix transform, StackMode stackMode, StackSize stackPrimarySizing, StackSize stackCounterSizing, TextAutoResize textAutoResize, float fontSize, TextData textData, SymbolData symbolData
message NodeChange GUID guid, ParentIndex parentIndex, NodeType type, string name, Vector size, Matrix transform, StackMode stackMode, StackSize stackPrimarySizing, StackSize stackCounterSizing, StackJustify stackPrimaryAlignItems, TextAutoResize textAutoResize, float fontSize, TextData textData, SymbolData symbolData
message Message NodeChange[] nodeChanges
";
@@ -191,3 +192,27 @@ fn rest_files_read_left_out_sizing_modes_as_hug_and_text_by_its_resize_mode() {
assert_eq!(sizing(&doc, name), want, "{name}");
}
}
#[test]
fn distributed_alignment_reads_the_older_evenly_name_as_space_between() {
let rows = [
("Between", "SPACE_BETWEEN", MainAlign::SpaceBetween),
("Older evenly", "SPACE_EVENLY", MainAlign::SpaceBetween),
("Around", "SPACE_AROUND", MainAlign::SpaceAround),
("Evenly", "SPACE_EVENLY_CSS", MainAlign::SpaceEvenly),
];
let nodes = rows
.iter()
.enumerate()
.flat_map(|(i, (name, align, _))| {
let mut fields = stack("HORIZONTAL", None, None);
fields.push(("stackPrimaryAlignItems", Kv::Enum(align)));
component(10 + 2 * i as u64, 50.0 * i as f64, name, fields, None)
})
.collect();
let doc = import(nodes);
for (name, _, want) in rows {
let n = doc.nodes().find(|n| n.name == name).unwrap_or_else(|| panic!("no layer {name}"));
assert_eq!(n.layout.as_ref().map(|l| l.main_align), Some(want), "{name}");
}
}
+2 -2
View File
@@ -73,7 +73,7 @@ enum StrokeJoin MITER=0 BEVEL=1 ROUND=2
enum ConstraintType MIN=0 CENTER=1 MAX=2 STRETCH=3 SCALE=4
enum StackMode NONE=0 HORIZONTAL=1 VERTICAL=2 GRID=3
enum StackAlign MIN=0 CENTER=1 MAX=2 BASELINE=3
enum StackJustify MIN=0 CENTER=1 MAX=2 SPACE_EVENLY=3 SPACE_BETWEEN=4 SPACE_AROUND=5
enum StackJustify MIN=0 CENTER=1 MAX=2 SPACE_EVENLY=3 SPACE_BETWEEN=4 SPACE_AROUND=5 SPACE_EVENLY_CSS=6
enum StackCounterAlign MIN=0 CENTER=1 MAX=2 STRETCH=3 AUTO=4 BASELINE=5
enum StackSize FIXED=0 RESIZE_TO_FIT=1
enum StackWrap NO_WRAP=0 WRAP=1
@@ -1371,7 +1371,7 @@ impl<'d> Exporter<'d> {
MainAlign::Max => "MAX",
MainAlign::SpaceBetween => "SPACE_BETWEEN",
MainAlign::SpaceAround => "SPACE_AROUND",
MainAlign::SpaceEvenly => "SPACE_EVENLY",
MainAlign::SpaceEvenly => "SPACE_EVENLY_CSS",
};
let cross = match l.cross_align {
CrossAlign::Min => "MIN",
+3 -2
View File
@@ -1405,8 +1405,9 @@ impl<'a> Mapper<'a> {
Some("CENTER") => "CENTER",
Some("MAX") => "MAX",
Some("SPACE_AROUND") => "SPACE_AROUND",
Some("SPACE_EVENLY") => "SPACE_EVENLY",
Some("SPACE_BETWEEN" | "SPACE_EVENLY_CSS") => "SPACE_BETWEEN",
// `SPACE_EVENLY` is the format's older name for equal gaps without edge space.
Some("SPACE_EVENLY_CSS") => "SPACE_EVENLY",
Some("SPACE_BETWEEN" | "SPACE_EVENLY") => "SPACE_BETWEEN",
_ => "MIN",
};
o.insert("primaryAxisAlignItems".into(), json!(main));