diff --git a/CHANGELOG.md b/CHANGELOG.md index 03b1ba691..b40465d9f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,12 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## Unreleased + +### Fixed + +- Text `margin` arrays now map as documented TRBL `[top, right, bottom, left]` instead of LRBT (`lIns`/`tIns` were swapped) + ## [4.0.1](https://github.com/gitbrent/PptxGenJS/releases/tag/v4.0.1) - 2025-06-25 ### Fixed diff --git a/demos/modules/demo_text.mjs b/demos/modules/demo_text.mjs index 6f292055d..b30002571 100644 --- a/demos/modules/demo_text.mjs +++ b/demos/modules/demo_text.mjs @@ -59,6 +59,20 @@ function genSlide01(pptx) { { x: 10, y: 2.25, w: 3.0, h: 1.0, color: "FFFFFF", fill: { color: "C00000" }, valign: "bottom", align: "right", margin: 0 } ); + // TEST-CASE: text margin arrays are TRBL [top, right, bottom, left] + // Left inset should be large here (not top). Regression: LRBT mapping swapped ends. + slide.addText("margin:[5,5,5,40]\n(left=40pt)", { + x: 10, + y: 3.35, + w: 3.0, + h: 0.9, + color: "363636", + fill: { color: "F1F1F1" }, + fontSize: 12, + valign: "middle", + margin: [5, 5, 5, 40], + }); + slide.addText("^ (50%/50%)", { x: "50%", y: "50%", w: 2 }); slide.addText("Plain x/y coords", { x: 10, y: 4.35, w: 3 }); @@ -202,6 +216,7 @@ function genSlide02(pptx) { }); // 4: Line-Spacing (bullets) + // TEST-CASE: margin [0,0,0,10] = left 10pt (TRBL), not top slide.addText("Line-Spacing (bullets):", { x: 7.0, y: 5.6, w: "40%", h: 0.3, margin: 0, color: pptx.colors.ACCENT1 }); slide.addText([{ text: "lineSpacing\n35pt", options: { fontSize: 24, bullet: true, color: "99ABCC", lineSpacing: 35 } }], { x: 7.0, diff --git a/src/gen-xml.ts b/src/gen-xml.ts index f1e3ecd9f..1f1f77819 100644 --- a/src/gen-xml.ts +++ b/src/gen-xml.ts @@ -391,13 +391,13 @@ function slideObjectToXml (slide: PresSlide | SlideLayout): string { // Lines can have zero cy, but text should not if (!slideItemObj.options.line && cy === 0) cy = EMU * 0.3 - // Margin/Padding/Inset for textboxes + // Margin/Padding/Inset for textboxes (TRBL: [top, right, bottom, left]) if (!slideItemObj.options._bodyProp) slideItemObj.options._bodyProp = {} if (slideItemObj.options.margin && Array.isArray(slideItemObj.options.margin)) { - slideItemObj.options._bodyProp.lIns = valToPts(slideItemObj.options.margin[0] || 0) + slideItemObj.options._bodyProp.tIns = valToPts(slideItemObj.options.margin[0] || 0) slideItemObj.options._bodyProp.rIns = valToPts(slideItemObj.options.margin[1] || 0) slideItemObj.options._bodyProp.bIns = valToPts(slideItemObj.options.margin[2] || 0) - slideItemObj.options._bodyProp.tIns = valToPts(slideItemObj.options.margin[3] || 0) + slideItemObj.options._bodyProp.lIns = valToPts(slideItemObj.options.margin[3] || 0) } else if (typeof slideItemObj.options.margin === 'number') { slideItemObj.options._bodyProp.lIns = valToPts(slideItemObj.options.margin) slideItemObj.options._bodyProp.rIns = valToPts(slideItemObj.options.margin)