@hirokisakabe/pom 5.5.0 → 5.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/calcYogaLayout/calcYogaLayout.d.ts.map +1 -1
- package/dist/calcYogaLayout/calcYogaLayout.js +50 -4
- package/dist/calcYogaLayout/fontLoader.d.ts +4 -0
- package/dist/calcYogaLayout/fontLoader.d.ts.map +1 -1
- package/dist/calcYogaLayout/fontLoader.js +8 -0
- package/dist/calcYogaLayout/measureText.d.ts.map +1 -1
- package/dist/calcYogaLayout/measureText.js +4 -3
- package/dist/registry/definitions/list.d.ts.map +1 -1
- package/dist/registry/definitions/list.js +3 -1
- package/dist/registry/definitions/shape.d.ts.map +1 -1
- package/dist/registry/definitions/shape.js +2 -0
- package/dist/registry/definitions/text.d.ts.map +1 -1
- package/dist/registry/definitions/text.js +3 -1
- package/dist/renderPptx/nodes/image.js +1 -1
- package/dist/renderPptx/nodes/shape.js +1 -1
- package/dist/renderPptx/textOptions.d.ts +6 -6
- package/dist/renderPptx/utils/backgroundBorder.js +1 -1
- package/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"calcYogaLayout.d.ts","sourceRoot":"","sources":["../../src/calcYogaLayout/calcYogaLayout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,
|
|
1
|
+
{"version":3,"file":"calcYogaLayout.d.ts","sourceRoot":"","sources":["../../src/calcYogaLayout/calcYogaLayout.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAc,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAO9C;;;;;;;;GAQG;AACH,wBAAsB,cAAc,CAClC,IAAI,EAAE,OAAO,EACb,SAAS,EAAE;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,EACnC,GAAG,EAAE,YAAY,GAChB,OAAO,CAAC,WAAW,CAAC,CA0BtB"}
|
|
@@ -83,10 +83,50 @@ async function getYoga() {
|
|
|
83
83
|
yogaP = loadYoga();
|
|
84
84
|
return yogaP;
|
|
85
85
|
}
|
|
86
|
+
/**
|
|
87
|
+
* ノードが交差軸方向(幅)で確定サイズを持つかを判定する
|
|
88
|
+
* - 明示的な w がある場合は確定
|
|
89
|
+
* - alignSelf で stretch 以外が指定されている場合は不確定
|
|
90
|
+
* - 親の alignItems で stretch(デフォルト)以外が指定されている場合は不確定
|
|
91
|
+
*/
|
|
92
|
+
function nodeHasDefiniteWidth(node, parentNode) {
|
|
93
|
+
// 明示的な幅がある
|
|
94
|
+
if (node.w !== undefined)
|
|
95
|
+
return true;
|
|
96
|
+
// alignSelf で stretch 以外が明示されている場合は不確定
|
|
97
|
+
if (node.alignSelf !== undefined &&
|
|
98
|
+
node.alignSelf !== "stretch" &&
|
|
99
|
+
node.alignSelf !== "auto") {
|
|
100
|
+
return false;
|
|
101
|
+
}
|
|
102
|
+
// 親がいない場合(ルートノード)は確定
|
|
103
|
+
if (!parentNode)
|
|
104
|
+
return true;
|
|
105
|
+
// 親の alignItems を取得(VStack/HStack のみ持つ、Box 等は undefined でデフォルト stretch)
|
|
106
|
+
let parentAlignItems;
|
|
107
|
+
if (parentNode.type === "vstack") {
|
|
108
|
+
parentAlignItems = parentNode.alignItems;
|
|
109
|
+
}
|
|
110
|
+
else if (parentNode.type === "hstack") {
|
|
111
|
+
parentAlignItems = parentNode.alignItems;
|
|
112
|
+
}
|
|
113
|
+
// VStack/Box(column 方向)の子の場合、交差軸は水平方向
|
|
114
|
+
// alignItems が stretch(デフォルト)なら子は親幅に伸長される
|
|
115
|
+
if (parentNode.type === "vstack" ||
|
|
116
|
+
parentNode.type === "box" ||
|
|
117
|
+
parentNode.type === "layer") {
|
|
118
|
+
return parentAlignItems === undefined || parentAlignItems === "stretch";
|
|
119
|
+
}
|
|
120
|
+
// HStack の子の場合、幅は主軸方向で flex により決まるため確定とみなす
|
|
121
|
+
if (parentNode.type === "hstack") {
|
|
122
|
+
return true;
|
|
123
|
+
}
|
|
124
|
+
return true;
|
|
125
|
+
}
|
|
86
126
|
/**
|
|
87
127
|
* POMNode ツリーを再帰的に走査し、YogaNode ツリーを構築する
|
|
88
128
|
*/
|
|
89
|
-
async function buildPomWithYogaTree(node, parentYoga, ctx, map, parentNode) {
|
|
129
|
+
async function buildPomWithYogaTree(node, parentYoga, ctx, map, parentNode, grandparentNode) {
|
|
90
130
|
const yoga = await getYoga();
|
|
91
131
|
const yn = yoga.Node.create();
|
|
92
132
|
map.set(node, yn); // 対応する YogaNode をマップに登録
|
|
@@ -105,21 +145,27 @@ async function buildPomWithYogaTree(node, parentYoga, ctx, map, parentNode) {
|
|
|
105
145
|
node.type !== "table" &&
|
|
106
146
|
node.type !== "icon") {
|
|
107
147
|
yn.setFlexGrow(1);
|
|
108
|
-
|
|
148
|
+
// HStack が確定幅を持つ場合のみ flexBasis=0 で均等分割
|
|
149
|
+
// HStack が auto-sized(親の alignItems が center/start/end 等)の場合、
|
|
150
|
+
// flexBasis=0 だと子要素の自然な幅が失われてレイアウトが崩れるため、
|
|
151
|
+
// flexBasis=auto(デフォルト)のまま維持する
|
|
152
|
+
if (nodeHasDefiniteWidth(parentNode, grandparentNode)) {
|
|
153
|
+
yn.setFlexBasis(0);
|
|
154
|
+
}
|
|
109
155
|
}
|
|
110
156
|
parentYoga.insertChild(yn, parentYoga.getChildCount());
|
|
111
157
|
const def = getNodeDef(node.type);
|
|
112
158
|
switch (def.category) {
|
|
113
159
|
case "single-child": {
|
|
114
160
|
const boxNode = node;
|
|
115
|
-
await buildPomWithYogaTree(boxNode.children, yn, ctx, map, node);
|
|
161
|
+
await buildPomWithYogaTree(boxNode.children, yn, ctx, map, node, parentNode);
|
|
116
162
|
break;
|
|
117
163
|
}
|
|
118
164
|
case "multi-child":
|
|
119
165
|
case "absolute-child": {
|
|
120
166
|
const containerNode = node;
|
|
121
167
|
for (const child of containerNode.children) {
|
|
122
|
-
await buildPomWithYogaTree(child, yn, ctx, map, node);
|
|
168
|
+
await buildPomWithYogaTree(child, yn, ctx, map, node, parentNode);
|
|
123
169
|
}
|
|
124
170
|
break;
|
|
125
171
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fontLoader.d.ts","sourceRoot":"","sources":["../../src/calcYogaLayout/fontLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"fontLoader.d.ts","sourceRoot":"","sources":["../../src/calcYogaLayout/fontLoader.ts"],"names":[],"mappings":"AAAA;;;GAGG;AA8DH;;GAEG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,QAAQ,GAAG,MAAM,GACxB,MAAM,CAGR;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAgB5E"}
|
|
@@ -46,6 +46,14 @@ function getFont(weight) {
|
|
|
46
46
|
fontCache.set(cacheKey, font);
|
|
47
47
|
return font;
|
|
48
48
|
}
|
|
49
|
+
/** バンドル済みフォント名の一覧 */
|
|
50
|
+
const BUNDLED_FONT_NAMES = new Set(["Noto Sans JP"]);
|
|
51
|
+
/**
|
|
52
|
+
* 指定されたフォントがバンドル済みかどうかを判定する
|
|
53
|
+
*/
|
|
54
|
+
export function isBundledFont(fontFamily) {
|
|
55
|
+
return BUNDLED_FONT_NAMES.has(fontFamily);
|
|
56
|
+
}
|
|
49
57
|
/**
|
|
50
58
|
* 指定したテキストの幅を計測する
|
|
51
59
|
* @param text 計測するテキスト
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"measureText.d.ts","sourceRoot":"","sources":["../../src/calcYogaLayout/measureText.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"measureText.d.ts","sourceRoot":"","sources":["../../src/calcYogaLayout/measureText.ts"],"names":[],"mappings":"AAKA,KAAK,cAAc,GAAG;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,QAAQ,GAAG,MAAM,GAAG,MAAM,CAAC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;AA6HnE;;GAEG;AACH,wBAAgB,WAAW,CACzB,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,cAAc,EACpB,IAAI,GAAE,mBAA4B,GACjC;IACD,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAoBA"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { measureTextWidth as measureTextWidthOpentype } from "./fontLoader.js";
|
|
1
|
+
import { measureTextWidth as measureTextWidthOpentype, isBundledFont, } from "./fontLoader.js";
|
|
2
2
|
/**
|
|
3
3
|
* 文字がCJK(日本語・中国語・韓国語)文字かどうかを判定する
|
|
4
4
|
*/
|
|
@@ -108,6 +108,8 @@ function normalizeFontWeight(weight) {
|
|
|
108
108
|
*/
|
|
109
109
|
export function measureText(text, maxWidthPx, opts, mode = "auto") {
|
|
110
110
|
// 計測方法を決定
|
|
111
|
+
// "opentype" / "fallback" が明示指定された場合はそれを優先
|
|
112
|
+
// "auto" の場合はバンドル外フォントならフォールバック計測を使用
|
|
111
113
|
const shouldUseFallback = (() => {
|
|
112
114
|
switch (mode) {
|
|
113
115
|
case "opentype":
|
|
@@ -115,8 +117,7 @@ export function measureText(text, maxWidthPx, opts, mode = "auto") {
|
|
|
115
117
|
case "fallback":
|
|
116
118
|
return true;
|
|
117
119
|
case "auto":
|
|
118
|
-
|
|
119
|
-
return false;
|
|
120
|
+
return !isBundledFont(opts.fontFamily);
|
|
120
121
|
}
|
|
121
122
|
})();
|
|
122
123
|
if (shouldUseFallback) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/registry/definitions/list.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAQ,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"list.d.ts","sourceRoot":"","sources":["../../../src/registry/definitions/list.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAQ,MAAM,aAAa,CAAC;AA4DxD,eAAO,MAAM,SAAS,EAAE,cAOvB,CAAC;AAEF,eAAO,MAAM,SAAS,EAAE,cAOvB,CAAC"}
|
|
@@ -5,7 +5,7 @@ function applyListYogaStyle(node, yn, yoga, ctx) {
|
|
|
5
5
|
const n = node;
|
|
6
6
|
const combinedText = n.items.map((item) => item.text).join("\n");
|
|
7
7
|
const fontSizePx = n.fontSize ?? 24;
|
|
8
|
-
const fontFamily = "Noto Sans JP";
|
|
8
|
+
const fontFamily = n.fontFamily ?? "Noto Sans JP";
|
|
9
9
|
const fontWeight = n.bold ? "bold" : "normal";
|
|
10
10
|
const spacingMultiple = n.lineHeight ?? 1.3;
|
|
11
11
|
const fontMetricsRatio = measureFontLineHeightRatio(fontWeight);
|
|
@@ -20,6 +20,8 @@ function applyListYogaStyle(node, yn, yoga, ctx) {
|
|
|
20
20
|
case yoga.MEASURE_MODE_EXACTLY:
|
|
21
21
|
case yoga.MEASURE_MODE_AT_MOST:
|
|
22
22
|
return width;
|
|
23
|
+
default:
|
|
24
|
+
return Number.POSITIVE_INFINITY;
|
|
23
25
|
}
|
|
24
26
|
})();
|
|
25
27
|
const textMaxWidthPx = Math.max(0, maxWidthPx - bulletIndentPx);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shape.d.ts","sourceRoot":"","sources":["../../../src/registry/definitions/shape.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAQ,MAAM,aAAa,CAAC;AAMxD,eAAO,MAAM,YAAY,EAAE,
|
|
1
|
+
{"version":3,"file":"shape.d.ts","sourceRoot":"","sources":["../../../src/registry/definitions/shape.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAQ,MAAM,aAAa,CAAC;AAMxD,eAAO,MAAM,YAAY,EAAE,cA4C1B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/registry/definitions/text.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAQ,MAAM,aAAa,CAAC;AAMxD,eAAO,MAAM,WAAW,EAAE,
|
|
1
|
+
{"version":3,"file":"text.d.ts","sourceRoot":"","sources":["../../../src/registry/definitions/text.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAQ,MAAM,aAAa,CAAC;AAMxD,eAAO,MAAM,WAAW,EAAE,cA0CzB,CAAC"}
|
|
@@ -7,7 +7,7 @@ export const textNodeDef = {
|
|
|
7
7
|
const n = node;
|
|
8
8
|
const text = n.text;
|
|
9
9
|
const fontSizePx = n.fontSize ?? 24;
|
|
10
|
-
const fontFamily = "Noto Sans JP";
|
|
10
|
+
const fontFamily = n.fontFamily ?? "Noto Sans JP";
|
|
11
11
|
const fontWeight = n.bold ? "bold" : "normal";
|
|
12
12
|
const lineHeight = 1.3;
|
|
13
13
|
yn.setMeasureFunc((width, widthMode) => {
|
|
@@ -18,6 +18,8 @@ export const textNodeDef = {
|
|
|
18
18
|
case yoga.MEASURE_MODE_EXACTLY:
|
|
19
19
|
case yoga.MEASURE_MODE_AT_MOST:
|
|
20
20
|
return width;
|
|
21
|
+
default:
|
|
22
|
+
return Number.POSITIVE_INFINITY;
|
|
21
23
|
}
|
|
22
24
|
})();
|
|
23
25
|
const { widthPx, heightPx } = measureText(text, maxWidthPx, {
|
|
@@ -24,15 +24,15 @@ export declare function createTextOptions(node: TextNode): {
|
|
|
24
24
|
valign: "top";
|
|
25
25
|
margin: number;
|
|
26
26
|
lineSpacingMultiple: number;
|
|
27
|
-
color: string;
|
|
28
|
-
bold: boolean;
|
|
29
|
-
italic: boolean;
|
|
27
|
+
color: string | undefined;
|
|
28
|
+
bold: boolean | undefined;
|
|
29
|
+
italic: boolean | undefined;
|
|
30
30
|
underline: {
|
|
31
31
|
style?: UnderlineStyle;
|
|
32
32
|
color?: string;
|
|
33
|
-
};
|
|
34
|
-
strike: "sngStrike";
|
|
35
|
-
highlight: string;
|
|
33
|
+
} | undefined;
|
|
34
|
+
strike: "sngStrike" | undefined;
|
|
35
|
+
highlight: string | undefined;
|
|
36
36
|
};
|
|
37
37
|
export {};
|
|
38
38
|
//# sourceMappingURL=textOptions.d.ts.map
|
|
@@ -2,7 +2,7 @@ import { getImageData } from "../../shared/measureImage.js";
|
|
|
2
2
|
import { pxToIn, pxToPt } from "../units.js";
|
|
3
3
|
function convertShadow(shadow) {
|
|
4
4
|
return {
|
|
5
|
-
type: shadow.type,
|
|
5
|
+
type: shadow.type ?? "outer",
|
|
6
6
|
opacity: shadow.opacity,
|
|
7
7
|
blur: shadow.blur,
|
|
8
8
|
angle: shadow.angle,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hirokisakabe/pom",
|
|
3
|
-
"version": "5.5.
|
|
3
|
+
"version": "5.5.1",
|
|
4
4
|
"description": "AI-friendly PowerPoint generation with a Flexbox layout engine.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"prettier": "3.6.2",
|
|
89
89
|
"size-limit": "^12.0.1",
|
|
90
90
|
"tsx": "4.21.0",
|
|
91
|
-
"typescript": "
|
|
91
|
+
"typescript": "6.0.2",
|
|
92
92
|
"typescript-eslint": "^8.47.0",
|
|
93
93
|
"vitest": "^4.1.0"
|
|
94
94
|
},
|