fix(format): keep vertical trim on .fig import (#466)

Figma's schema has leadingTrim on NodeChange (NONE, CAP_HEIGHT), and
the REST importer already reads style.leadingTrim, but the .fig mapping
never copied it, so text set to "Cap height to baseline" imported
untrimmed in its trimmed box. text_style now copies it with the other
text fields, from the layer or its text style.
This commit is contained in:
vxMacDev
2026-10-15 18:45:06 -05:00
parent 4ee413acde
commit c56a65f58b
2 changed files with 5 additions and 1 deletions
+1
View File
@@ -1729,6 +1729,7 @@ fn text_style(v: &View, size: Option<f64>) -> Obj {
copy_num(&mut s, v, "paragraphIndent", "paragraphIndent");
copy_str(&mut s, v, "textCase", "textCase");
copy_str(&mut s, v, "textDecoration", "textDecoration");
copy_str(&mut s, v, "leadingTrim", "leadingTrim");
let font_size = v.num("fontSize").or(size).unwrap_or(12.0);
if let Some(ls) = v.get("letterSpacing") {
let val = num(ls, "value").unwrap_or(0.0);
+4 -1
View File
@@ -33,6 +33,7 @@ enum NavigationType NAVIGATE OVERLAY
enum TransitionType INSTANT_TRANSITION DISSOLVE SMART_ANIMATE
enum EasingType IN_CUBIC OUT_CUBIC
enum ConstraintType MIN CENTER MAX STRETCH SCALE
enum LeadingTrim NONE CAP_HEIGHT
struct GUID uint sessionID, uint localID
struct Color float r, float g, float b, float a
struct Vector float x, float y
@@ -72,7 +73,7 @@ message Event InteractionType interactionType
message Action GUID transitionNodeID, TransitionType transitionType, float transitionDuration, EasingType easingType, ConnectionType connectionType, NavigationType navigationType, VariableTarget targetVariable, VariableData targetVariableData, VariableSetID targetVariableSetID, GUID targetVariableModeID, ConditionalActions[] conditionalActions
message Interaction Event event, Action[] actions
message StartingPoint string name, string position
message NodeChange GUID guid, ParentIndex parentIndex, NodeType type, string name, bool visible, float opacity, Vector size, Matrix transform, Paint[] fillPaints, Paint[] strokePaints, float strokeWeight, float cornerRadius, bool resizeToFit, bool internalOnly, float fontSize, FontName fontName, TextData textData, uint styleID, Path[] fillGeometry, Path[] strokeGeometry, StyleType styleType, StyleId styleIdForFill, SymbolData symbolData, PropDef[] componentPropDefs, PropAssignment[] componentPropAssignments, VariableDataMap parameterConsumptionMap, SetMode[] variableSetModes, VariableID variableSetID, ResolvedType variableResolvedType, Values variableDataValues, ModeMap variableModeBySetMap, Interaction[] prototypeInteractions, StartingPoint prototypeStartingPoint, GUIDPath guidPath, StackMode stackMode, float stackSpacing, float stackHorizontalPadding, float stackVerticalPadding, uint count, float starInnerScale, VectorData vectorData, StrokeCap strokeCap, StrokeJoin strokeJoin, VectorMirror handleMirroring, ShapeWithTextType shapeWithTextType, ConnectorEndpoint connectorStart, ConnectorEndpoint connectorEnd, StrokeCap connectorStartCap, StrokeCap connectorEndCap, ConnectorLineStyle connectorLineStyle, ConstraintType horizontalConstraint, ConstraintType verticalConstraint, NodeChange[] derivedSymbolData, string key, string version
message NodeChange GUID guid, ParentIndex parentIndex, NodeType type, string name, bool visible, float opacity, Vector size, Matrix transform, Paint[] fillPaints, Paint[] strokePaints, float strokeWeight, float cornerRadius, bool resizeToFit, bool internalOnly, float fontSize, FontName fontName, TextData textData, uint styleID, Path[] fillGeometry, Path[] strokeGeometry, StyleType styleType, StyleId styleIdForFill, SymbolData symbolData, PropDef[] componentPropDefs, PropAssignment[] componentPropAssignments, VariableDataMap parameterConsumptionMap, SetMode[] variableSetModes, VariableID variableSetID, ResolvedType variableResolvedType, Values variableDataValues, ModeMap variableModeBySetMap, Interaction[] prototypeInteractions, StartingPoint prototypeStartingPoint, GUIDPath guidPath, StackMode stackMode, float stackSpacing, float stackHorizontalPadding, float stackVerticalPadding, uint count, float starInnerScale, VectorData vectorData, StrokeCap strokeCap, StrokeJoin strokeJoin, VectorMirror handleMirroring, ShapeWithTextType shapeWithTextType, ConnectorEndpoint connectorStart, ConnectorEndpoint connectorEnd, StrokeCap connectorStartCap, StrokeCap connectorEndCap, ConnectorLineStyle connectorLineStyle, ConstraintType horizontalConstraint, ConstraintType verticalConstraint, NodeChange[] derivedSymbolData, string key, string version, LeadingTrim leadingTrim
message Blob byte[] bytes
message Message NodeChange[] nodeChanges, Blob[] blobs
";
@@ -283,6 +284,7 @@ fn message() -> Kv<'static> {
("fillPaints", arr(vec![solid(0.0, 0.0, 0.0)])),
("fontSize", f(16.0)),
("fontName", font("Regular")),
("leadingTrim", e("CAP_HEIGHT")),
("textData", text),
],
),
@@ -477,6 +479,7 @@ fn imports_the_fixture() {
let NodeKind::Text(t) = &named(&doc, "Title").kind else { panic!("not text") };
assert_eq!(t.characters, "Hi there");
assert_eq!(t.style.font_size, 16.0);
assert_eq!(t.leading_trim, figcraft_doc::LeadingTrim::CapHeight, "vertical trim (#466)");
assert_eq!(t.runs.len(), 1);
assert_eq!((t.runs[0].start, t.runs[0].end, t.runs[0].style.font_style.as_str()), (3, 6, "Bold"));
// The group's children keep their place on the page (group at 100, 100).