pptx-glimpse 0.1.3 → 0.2.0
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/index.cjs +429 -74
- package/dist/index.js +429 -74
- package/package.json +5 -5
package/dist/index.cjs
CHANGED
|
@@ -1144,6 +1144,14 @@ function buildMarkerDef(id, endpoint, color, alpha) {
|
|
|
1144
1144
|
return `<marker id="${id}" markerWidth="${mw}" markerHeight="${mh}" refX="${mw}" refY="${mh / 2}" orient="auto" markerUnits="userSpaceOnUse"><path d="${path}" ${fillAttr2}${alphaAttr}/></marker>`;
|
|
1145
1145
|
}
|
|
1146
1146
|
|
|
1147
|
+
// src/utils/unit-types.ts
|
|
1148
|
+
function asEmu(value) {
|
|
1149
|
+
return value;
|
|
1150
|
+
}
|
|
1151
|
+
function asHundredthPt(value) {
|
|
1152
|
+
return value;
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1147
1155
|
// src/data/font-metrics.ts
|
|
1148
1156
|
var metricsData = {
|
|
1149
1157
|
Carlito: {
|
|
@@ -3020,7 +3028,7 @@ function computeSpAutofitHeight(textBody, transform) {
|
|
|
3020
3028
|
const requiredHeightPx = textHeight + marginTopPx + marginBottomPx;
|
|
3021
3029
|
if (requiredHeightPx <= height) return null;
|
|
3022
3030
|
const DEFAULT_DPI2 = 96;
|
|
3023
|
-
return requiredHeightPx / DEFAULT_DPI2 * EMU_PER_INCH;
|
|
3031
|
+
return asEmu(requiredHeightPx / DEFAULT_DPI2 * EMU_PER_INCH);
|
|
3024
3032
|
}
|
|
3025
3033
|
function computeShrinkToFitScale(paragraphs, defaultFontSize, fontScale, lnSpcReduction, textWidth, availableHeight) {
|
|
3026
3034
|
if (availableHeight <= 0) return fontScale;
|
|
@@ -3127,7 +3135,7 @@ function renderTextDecorations(x, y, segmentWidth, fontSizePx, props) {
|
|
|
3127
3135
|
}
|
|
3128
3136
|
return lines;
|
|
3129
3137
|
}
|
|
3130
|
-
function renderSegmentAsPath(text, props, x, y, fontScale, defaultFontSize, fontResolver) {
|
|
3138
|
+
function renderSegmentAsPath(text, props, x, y, fontScale, defaultFontSize, fontResolver, vert) {
|
|
3131
3139
|
const fontSize = (props.fontSize ?? defaultFontSize) * fontScale;
|
|
3132
3140
|
const fontSizePx = fontSize * PX_PER_PT2;
|
|
3133
3141
|
const parts = [];
|
|
@@ -3160,7 +3168,50 @@ function renderSegmentAsPath(text, props, x, y, fontScale, defaultFontSize, font
|
|
|
3160
3168
|
}
|
|
3161
3169
|
totalWidth += segWidth;
|
|
3162
3170
|
};
|
|
3163
|
-
|
|
3171
|
+
const processCjkUpright = (segText, fontFamily, fontFamilyEa) => {
|
|
3172
|
+
if (segText.length === 0) return;
|
|
3173
|
+
const font = fontResolver.resolveFont(fontFamily, fontFamilyEa);
|
|
3174
|
+
const fillAttrs = buildPathFillAttrs(props);
|
|
3175
|
+
for (const char of segText) {
|
|
3176
|
+
const charWidth = getTextMeasurer().measureTextWidth(
|
|
3177
|
+
char,
|
|
3178
|
+
fontSize,
|
|
3179
|
+
props.bold,
|
|
3180
|
+
fontFamily,
|
|
3181
|
+
fontFamilyEa
|
|
3182
|
+
);
|
|
3183
|
+
if (font) {
|
|
3184
|
+
const charX = x + totalWidth;
|
|
3185
|
+
const path = font.getPath(char, charX, effectiveY, fontSizePx);
|
|
3186
|
+
const pathData = path.toPathData(2);
|
|
3187
|
+
if (pathData && pathData.length > 0) {
|
|
3188
|
+
const cx = charX + charWidth / 2;
|
|
3189
|
+
const cy = effectiveY - fontSizePx * (font.ascender + font.descender) / 2 / font.unitsPerEm;
|
|
3190
|
+
parts.push(
|
|
3191
|
+
`<g transform="rotate(-90, ${cx.toFixed(2)}, ${cy.toFixed(2)})"><path d="${pathData}" ${fillAttrs}/></g>`
|
|
3192
|
+
);
|
|
3193
|
+
}
|
|
3194
|
+
}
|
|
3195
|
+
if (props.underline || props.strikethrough) {
|
|
3196
|
+
parts.push(
|
|
3197
|
+
...renderTextDecorations(x + totalWidth, effectiveY, charWidth, fontSizePx, props)
|
|
3198
|
+
);
|
|
3199
|
+
}
|
|
3200
|
+
totalWidth += charWidth;
|
|
3201
|
+
}
|
|
3202
|
+
};
|
|
3203
|
+
if (vert === "eaVert") {
|
|
3204
|
+
const scriptParts = splitByScript(processedText);
|
|
3205
|
+
for (const part of scriptParts) {
|
|
3206
|
+
const ff = part.isEa ? props.fontFamilyEa ?? props.fontFamily : props.fontFamily;
|
|
3207
|
+
const ffEa = part.isEa ? props.fontFamilyEa : props.fontFamilyEa;
|
|
3208
|
+
if (part.isEa) {
|
|
3209
|
+
processCjkUpright(part.text, ff, ffEa);
|
|
3210
|
+
} else {
|
|
3211
|
+
processSegment(part.text, ff, ffEa);
|
|
3212
|
+
}
|
|
3213
|
+
}
|
|
3214
|
+
} else if (needsScriptSplit(props)) {
|
|
3164
3215
|
const scriptParts = splitByScript(processedText);
|
|
3165
3216
|
for (const part of scriptParts) {
|
|
3166
3217
|
const ff = part.isEa ? props.fontFamilyEa : props.fontFamily;
|
|
@@ -3326,7 +3377,8 @@ function renderTextBodyAsPath(textBody, transform, fontResolver) {
|
|
|
3326
3377
|
currentY,
|
|
3327
3378
|
fontScale,
|
|
3328
3379
|
defaultFontSize,
|
|
3329
|
-
fontResolver
|
|
3380
|
+
fontResolver,
|
|
3381
|
+
bodyProperties.vert
|
|
3330
3382
|
);
|
|
3331
3383
|
if (result.svg) elements.push(result.svg);
|
|
3332
3384
|
currentX += result.width;
|
|
@@ -3373,7 +3425,8 @@ function renderTextBodyAsPath(textBody, transform, fontResolver) {
|
|
|
3373
3425
|
currentY,
|
|
3374
3426
|
fontScale,
|
|
3375
3427
|
defaultFontSize,
|
|
3376
|
-
fontResolver
|
|
3428
|
+
fontResolver,
|
|
3429
|
+
bodyProperties.vert
|
|
3377
3430
|
);
|
|
3378
3431
|
if (result.svg) elements.push(result.svg);
|
|
3379
3432
|
currentX += result.width;
|
|
@@ -3816,6 +3869,15 @@ function renderChart(element) {
|
|
|
3816
3869
|
case "radar":
|
|
3817
3870
|
parts.push(renderRadarChart(chart, plotX, plotY, plotW, plotH));
|
|
3818
3871
|
break;
|
|
3872
|
+
case "stock":
|
|
3873
|
+
parts.push(renderStockChart(chart, plotX, plotY, plotW, plotH));
|
|
3874
|
+
break;
|
|
3875
|
+
case "surface":
|
|
3876
|
+
parts.push(renderSurfaceChart(chart, plotX, plotY, plotW, plotH));
|
|
3877
|
+
break;
|
|
3878
|
+
case "ofPie":
|
|
3879
|
+
parts.push(renderOfPieChart(chart, plotX, plotY, plotW, plotH));
|
|
3880
|
+
break;
|
|
3819
3881
|
}
|
|
3820
3882
|
}
|
|
3821
3883
|
if (chart.legend && chart.series.length > 0) {
|
|
@@ -4187,9 +4249,237 @@ function renderRadarChart(chart, x, y, w, h) {
|
|
|
4187
4249
|
}
|
|
4188
4250
|
return parts.join("");
|
|
4189
4251
|
}
|
|
4252
|
+
function renderStockChart(chart, x, y, w, h) {
|
|
4253
|
+
const parts = [];
|
|
4254
|
+
const { series, categories } = chart;
|
|
4255
|
+
if (series.length < 3) return "";
|
|
4256
|
+
const highSeries = series[0];
|
|
4257
|
+
const lowSeries = series[1];
|
|
4258
|
+
const closeSeries = series[2];
|
|
4259
|
+
const catCount = categories.length || highSeries.values.length;
|
|
4260
|
+
if (catCount === 0) return "";
|
|
4261
|
+
let maxVal = 0;
|
|
4262
|
+
let minVal = Infinity;
|
|
4263
|
+
for (const s of [highSeries, lowSeries, closeSeries]) {
|
|
4264
|
+
for (const v of s.values) {
|
|
4265
|
+
maxVal = Math.max(maxVal, v);
|
|
4266
|
+
minVal = Math.min(minVal, v);
|
|
4267
|
+
}
|
|
4268
|
+
}
|
|
4269
|
+
if (maxVal === minVal) return "";
|
|
4270
|
+
parts.push(
|
|
4271
|
+
`<line x1="${round3(x)}" y1="${round3(y + h)}" x2="${round3(x + w)}" y2="${round3(y + h)}" stroke="#D9D9D9" stroke-width="1"/>`
|
|
4272
|
+
);
|
|
4273
|
+
parts.push(
|
|
4274
|
+
`<line x1="${round3(x)}" y1="${round3(y)}" x2="${round3(x)}" y2="${round3(y + h)}" stroke="#D9D9D9" stroke-width="1"/>`
|
|
4275
|
+
);
|
|
4276
|
+
for (let c = 0; c < catCount; c++) {
|
|
4277
|
+
const label = categories[c] ?? "";
|
|
4278
|
+
const labelX = x + (c + 0.5) * (w / catCount);
|
|
4279
|
+
parts.push(
|
|
4280
|
+
`<text x="${round3(labelX)}" y="${round3(y + h + 15)}" text-anchor="middle" font-size="10" fill="#595959">${escapeXml2(label)}</text>`
|
|
4281
|
+
);
|
|
4282
|
+
}
|
|
4283
|
+
const range = maxVal - minVal;
|
|
4284
|
+
for (let c = 0; c < catCount; c++) {
|
|
4285
|
+
const cx = x + (c + 0.5) * (w / catCount);
|
|
4286
|
+
const highVal = highSeries.values[c] ?? 0;
|
|
4287
|
+
const lowVal = lowSeries.values[c] ?? 0;
|
|
4288
|
+
const closeVal = closeSeries.values[c] ?? 0;
|
|
4289
|
+
const highY = y + h - (highVal - minVal) / range * h;
|
|
4290
|
+
const lowY = y + h - (lowVal - minVal) / range * h;
|
|
4291
|
+
const closeY = y + h - (closeVal - minVal) / range * h;
|
|
4292
|
+
parts.push(
|
|
4293
|
+
`<line x1="${round3(cx)}" y1="${round3(highY)}" x2="${round3(cx)}" y2="${round3(lowY)}" stroke="#404040" stroke-width="2"/>`
|
|
4294
|
+
);
|
|
4295
|
+
const tickW = w / catCount * 0.2;
|
|
4296
|
+
parts.push(
|
|
4297
|
+
`<line x1="${round3(cx)}" y1="${round3(closeY)}" x2="${round3(cx + tickW)}" y2="${round3(closeY)}" stroke="#404040" stroke-width="2"/>`
|
|
4298
|
+
);
|
|
4299
|
+
}
|
|
4300
|
+
return parts.join("");
|
|
4301
|
+
}
|
|
4302
|
+
function renderSurfaceChart(chart, x, y, w, h) {
|
|
4303
|
+
const parts = [];
|
|
4304
|
+
const { series, categories } = chart;
|
|
4305
|
+
if (series.length === 0) return "";
|
|
4306
|
+
const rows = series.length;
|
|
4307
|
+
const cols = categories.length || Math.max(...series.map((s) => s.values.length));
|
|
4308
|
+
if (cols === 0) return "";
|
|
4309
|
+
let minVal = Infinity;
|
|
4310
|
+
let maxVal = -Infinity;
|
|
4311
|
+
for (const s of series) {
|
|
4312
|
+
for (const v of s.values) {
|
|
4313
|
+
minVal = Math.min(minVal, v);
|
|
4314
|
+
maxVal = Math.max(maxVal, v);
|
|
4315
|
+
}
|
|
4316
|
+
}
|
|
4317
|
+
if (minVal === maxVal) maxVal = minVal + 1;
|
|
4318
|
+
const cellW = w / cols;
|
|
4319
|
+
const cellH = h / rows;
|
|
4320
|
+
for (let r = 0; r < rows; r++) {
|
|
4321
|
+
for (let c = 0; c < cols; c++) {
|
|
4322
|
+
const val = series[r].values[c] ?? 0;
|
|
4323
|
+
const t = (val - minVal) / (maxVal - minVal);
|
|
4324
|
+
const color = heatmapColor(t);
|
|
4325
|
+
const cx = x + c * cellW;
|
|
4326
|
+
const cy = y + r * cellH;
|
|
4327
|
+
parts.push(
|
|
4328
|
+
`<rect x="${round3(cx)}" y="${round3(cy)}" width="${round3(cellW)}" height="${round3(cellH)}" fill="${color}" stroke="#FFFFFF" stroke-width="0.5"/>`
|
|
4329
|
+
);
|
|
4330
|
+
}
|
|
4331
|
+
}
|
|
4332
|
+
for (let c = 0; c < cols; c++) {
|
|
4333
|
+
const label = categories[c] ?? "";
|
|
4334
|
+
if (label) {
|
|
4335
|
+
const labelX = x + (c + 0.5) * cellW;
|
|
4336
|
+
parts.push(
|
|
4337
|
+
`<text x="${round3(labelX)}" y="${round3(y + h + 15)}" text-anchor="middle" font-size="10" fill="#595959">${escapeXml2(label)}</text>`
|
|
4338
|
+
);
|
|
4339
|
+
}
|
|
4340
|
+
}
|
|
4341
|
+
for (let r = 0; r < rows; r++) {
|
|
4342
|
+
const label = series[r].name ?? "";
|
|
4343
|
+
if (label) {
|
|
4344
|
+
const labelY = y + (r + 0.5) * cellH;
|
|
4345
|
+
parts.push(
|
|
4346
|
+
`<text x="${round3(x - 5)}" y="${round3(labelY + 4)}" text-anchor="end" font-size="10" fill="#595959">${escapeXml2(label)}</text>`
|
|
4347
|
+
);
|
|
4348
|
+
}
|
|
4349
|
+
}
|
|
4350
|
+
return parts.join("");
|
|
4351
|
+
}
|
|
4352
|
+
function heatmapColor(t) {
|
|
4353
|
+
const clamped = Math.max(0, Math.min(1, t));
|
|
4354
|
+
let r, g, b;
|
|
4355
|
+
if (clamped < 0.25) {
|
|
4356
|
+
const s = clamped / 0.25;
|
|
4357
|
+
r = 0;
|
|
4358
|
+
g = Math.round(s * 255);
|
|
4359
|
+
b = 255;
|
|
4360
|
+
} else if (clamped < 0.5) {
|
|
4361
|
+
const s = (clamped - 0.25) / 0.25;
|
|
4362
|
+
r = 0;
|
|
4363
|
+
g = 255;
|
|
4364
|
+
b = Math.round((1 - s) * 255);
|
|
4365
|
+
} else if (clamped < 0.75) {
|
|
4366
|
+
const s = (clamped - 0.5) / 0.25;
|
|
4367
|
+
r = Math.round(s * 255);
|
|
4368
|
+
g = 255;
|
|
4369
|
+
b = 0;
|
|
4370
|
+
} else {
|
|
4371
|
+
const s = (clamped - 0.75) / 0.25;
|
|
4372
|
+
r = 255;
|
|
4373
|
+
g = Math.round((1 - s) * 255);
|
|
4374
|
+
b = 0;
|
|
4375
|
+
}
|
|
4376
|
+
return `#${r.toString(16).padStart(2, "0")}${g.toString(16).padStart(2, "0")}${b.toString(16).padStart(2, "0")}`;
|
|
4377
|
+
}
|
|
4378
|
+
function renderOfPieChart(chart, x, y, w, h) {
|
|
4379
|
+
const parts = [];
|
|
4380
|
+
const series = chart.series[0];
|
|
4381
|
+
if (!series || series.values.length === 0) return "";
|
|
4382
|
+
const total = series.values.reduce((sum, v) => sum + v, 0);
|
|
4383
|
+
if (total === 0) return "";
|
|
4384
|
+
const splitPos = chart.splitPos ?? 2;
|
|
4385
|
+
const secondPieSize = chart.secondPieSize ?? 75;
|
|
4386
|
+
const isBarOfPie = chart.ofPieType === "bar";
|
|
4387
|
+
const splitIdx = Math.max(0, series.values.length - splitPos);
|
|
4388
|
+
const primaryValues = series.values.slice(0, splitIdx);
|
|
4389
|
+
const secondaryValues = series.values.slice(splitIdx);
|
|
4390
|
+
const secondaryTotal = secondaryValues.reduce((sum, v) => sum + v, 0);
|
|
4391
|
+
const pieW = w * 0.45;
|
|
4392
|
+
const pieCx = x + pieW / 2;
|
|
4393
|
+
const pieCy = y + h / 2;
|
|
4394
|
+
const pieR = Math.min(pieW, h) / 2 * 0.85;
|
|
4395
|
+
let currentAngle = -Math.PI / 2;
|
|
4396
|
+
for (let i = 0; i < primaryValues.length; i++) {
|
|
4397
|
+
const val = primaryValues[i];
|
|
4398
|
+
const sliceAngle = val / total * 2 * Math.PI;
|
|
4399
|
+
const color = getPieSliceColor(i, chart);
|
|
4400
|
+
const x1 = pieCx + pieR * Math.cos(currentAngle);
|
|
4401
|
+
const y1 = pieCy + pieR * Math.sin(currentAngle);
|
|
4402
|
+
const x2 = pieCx + pieR * Math.cos(currentAngle + sliceAngle);
|
|
4403
|
+
const y2 = pieCy + pieR * Math.sin(currentAngle + sliceAngle);
|
|
4404
|
+
const largeArc = sliceAngle > Math.PI ? 1 : 0;
|
|
4405
|
+
parts.push(
|
|
4406
|
+
`<path d="M${round3(pieCx)},${round3(pieCy)} L${round3(x1)},${round3(y1)} A${round3(pieR)},${round3(pieR)} 0 ${largeArc},1 ${round3(x2)},${round3(y2)} Z" ${fillAttr(color)}/>`
|
|
4407
|
+
);
|
|
4408
|
+
currentAngle += sliceAngle;
|
|
4409
|
+
}
|
|
4410
|
+
const otherAngleStart = currentAngle;
|
|
4411
|
+
const otherSliceAngle = secondaryTotal / total * 2 * Math.PI;
|
|
4412
|
+
const otherColor = { hex: "#D9D9D9", alpha: 1 };
|
|
4413
|
+
if (primaryValues.length === 0 && secondaryValues.length > 0) {
|
|
4414
|
+
parts.push(
|
|
4415
|
+
`<circle cx="${round3(pieCx)}" cy="${round3(pieCy)}" r="${round3(pieR)}" ${fillAttr(otherColor)}/>`
|
|
4416
|
+
);
|
|
4417
|
+
} else if (secondaryTotal > 0) {
|
|
4418
|
+
const x1 = pieCx + pieR * Math.cos(otherAngleStart);
|
|
4419
|
+
const y1 = pieCy + pieR * Math.sin(otherAngleStart);
|
|
4420
|
+
const x2 = pieCx + pieR * Math.cos(otherAngleStart + otherSliceAngle);
|
|
4421
|
+
const y2 = pieCy + pieR * Math.sin(otherAngleStart + otherSliceAngle);
|
|
4422
|
+
const largeArc = otherSliceAngle > Math.PI ? 1 : 0;
|
|
4423
|
+
parts.push(
|
|
4424
|
+
`<path d="M${round3(pieCx)},${round3(pieCy)} L${round3(x1)},${round3(y1)} A${round3(pieR)},${round3(pieR)} 0 ${largeArc},1 ${round3(x2)},${round3(y2)} Z" ${fillAttr(otherColor)}/>`
|
|
4425
|
+
);
|
|
4426
|
+
}
|
|
4427
|
+
const secW = w * 0.25;
|
|
4428
|
+
const secH = h * (secondPieSize / 100) * 0.85;
|
|
4429
|
+
const secX = x + w * 0.65;
|
|
4430
|
+
const secCy = y + h / 2;
|
|
4431
|
+
const lineStartX = pieCx + pieR * Math.cos(otherAngleStart);
|
|
4432
|
+
const lineStartY = pieCy + pieR * Math.sin(otherAngleStart);
|
|
4433
|
+
const lineEndStartX = pieCx + pieR * Math.cos(otherAngleStart + otherSliceAngle);
|
|
4434
|
+
const lineEndStartY = pieCy + pieR * Math.sin(otherAngleStart + otherSliceAngle);
|
|
4435
|
+
parts.push(
|
|
4436
|
+
`<line x1="${round3(lineStartX)}" y1="${round3(lineStartY)}" x2="${round3(secX)}" y2="${round3(secCy - secH / 2)}" stroke="#A6A6A6" stroke-width="1"/>`
|
|
4437
|
+
);
|
|
4438
|
+
parts.push(
|
|
4439
|
+
`<line x1="${round3(lineEndStartX)}" y1="${round3(lineEndStartY)}" x2="${round3(secX)}" y2="${round3(secCy + secH / 2)}" stroke="#A6A6A6" stroke-width="1"/>`
|
|
4440
|
+
);
|
|
4441
|
+
if (isBarOfPie) {
|
|
4442
|
+
let barY = secCy - secH / 2;
|
|
4443
|
+
for (let i = 0; i < secondaryValues.length; i++) {
|
|
4444
|
+
const val = secondaryValues[i];
|
|
4445
|
+
const barH = secondaryTotal > 0 ? val / secondaryTotal * secH : 0;
|
|
4446
|
+
const color = getPieSliceColor(splitIdx + i, chart);
|
|
4447
|
+
parts.push(
|
|
4448
|
+
`<rect x="${round3(secX)}" y="${round3(barY)}" width="${round3(secW)}" height="${round3(barH)}" ${fillAttr(color)}/>`
|
|
4449
|
+
);
|
|
4450
|
+
barY += barH;
|
|
4451
|
+
}
|
|
4452
|
+
} else {
|
|
4453
|
+
const secPieCx = secX + secW / 2;
|
|
4454
|
+
const secR = Math.min(secW, secH) / 2;
|
|
4455
|
+
let secAngle = -Math.PI / 2;
|
|
4456
|
+
if (secondaryValues.length === 1) {
|
|
4457
|
+
const color = getPieSliceColor(splitIdx, chart);
|
|
4458
|
+
parts.push(
|
|
4459
|
+
`<circle cx="${round3(secPieCx)}" cy="${round3(secCy)}" r="${round3(secR)}" ${fillAttr(color)}/>`
|
|
4460
|
+
);
|
|
4461
|
+
} else {
|
|
4462
|
+
for (let i = 0; i < secondaryValues.length; i++) {
|
|
4463
|
+
const val = secondaryValues[i];
|
|
4464
|
+
const sliceAngle = secondaryTotal > 0 ? val / secondaryTotal * 2 * Math.PI : 0;
|
|
4465
|
+
const color = getPieSliceColor(splitIdx + i, chart);
|
|
4466
|
+
const sx1 = secPieCx + secR * Math.cos(secAngle);
|
|
4467
|
+
const sy1 = secCy + secR * Math.sin(secAngle);
|
|
4468
|
+
const sx2 = secPieCx + secR * Math.cos(secAngle + sliceAngle);
|
|
4469
|
+
const sy2 = secCy + secR * Math.sin(secAngle + sliceAngle);
|
|
4470
|
+
const largeArc = sliceAngle > Math.PI ? 1 : 0;
|
|
4471
|
+
parts.push(
|
|
4472
|
+
`<path d="M${round3(secPieCx)},${round3(secCy)} L${round3(sx1)},${round3(sy1)} A${round3(secR)},${round3(secR)} 0 ${largeArc},1 ${round3(sx2)},${round3(sy2)} Z" ${fillAttr(color)}/>`
|
|
4473
|
+
);
|
|
4474
|
+
secAngle += sliceAngle;
|
|
4475
|
+
}
|
|
4476
|
+
}
|
|
4477
|
+
}
|
|
4478
|
+
return parts.join("");
|
|
4479
|
+
}
|
|
4190
4480
|
function renderLegend(chart, chartW, chartH, position) {
|
|
4191
4481
|
const parts = [];
|
|
4192
|
-
const entries2 = chart.chartType === "pie" || chart.chartType === "doughnut" ? chart.categories.map((cat, i) => ({
|
|
4482
|
+
const entries2 = chart.chartType === "pie" || chart.chartType === "doughnut" || chart.chartType === "ofPie" ? chart.categories.map((cat, i) => ({
|
|
4193
4483
|
label: cat,
|
|
4194
4484
|
color: getPieSliceColor(i, chart)
|
|
4195
4485
|
})) : chart.series.map((s, i) => ({
|
|
@@ -4295,8 +4585,8 @@ function renderTable(element) {
|
|
|
4295
4585
|
}
|
|
4296
4586
|
if (cell.textBody) {
|
|
4297
4587
|
const cellTransform = {
|
|
4298
|
-
offsetX: 0,
|
|
4299
|
-
offsetY: 0,
|
|
4588
|
+
offsetX: asEmu(0),
|
|
4589
|
+
offsetY: asEmu(0),
|
|
4300
4590
|
extentWidth: pixelsToEmu(cellW),
|
|
4301
4591
|
extentHeight: pixelsToEmu(cellH),
|
|
4302
4592
|
rotation: 0,
|
|
@@ -4324,7 +4614,7 @@ function computeSpannedSize(sizes, startIdx, span) {
|
|
|
4324
4614
|
return total;
|
|
4325
4615
|
}
|
|
4326
4616
|
function pixelsToEmu(px) {
|
|
4327
|
-
return px / 96 * 914400;
|
|
4617
|
+
return asEmu(px / 96 * 914400);
|
|
4328
4618
|
}
|
|
4329
4619
|
|
|
4330
4620
|
// src/renderer/svg-renderer.ts
|
|
@@ -4628,7 +4918,7 @@ function parseDefaultRunProperties(defRPr, colorResolver) {
|
|
|
4628
4918
|
if (!defRPr) return void 0;
|
|
4629
4919
|
const result = {};
|
|
4630
4920
|
if (defRPr["@_sz"] !== void 0) {
|
|
4631
|
-
result.fontSize = hundredthPointToPoint(Number(defRPr["@_sz"]));
|
|
4921
|
+
result.fontSize = hundredthPointToPoint(asHundredthPt(Number(defRPr["@_sz"])));
|
|
4632
4922
|
}
|
|
4633
4923
|
const latin = defRPr.latin;
|
|
4634
4924
|
if (latin?.["@_typeface"] !== void 0) {
|
|
@@ -4672,10 +4962,10 @@ function parseParagraphLevelProperties(node, colorResolver) {
|
|
|
4672
4962
|
result.alignment = node["@_algn"];
|
|
4673
4963
|
}
|
|
4674
4964
|
if (node["@_marL"] !== void 0) {
|
|
4675
|
-
result.marginLeft = Number(node["@_marL"]);
|
|
4965
|
+
result.marginLeft = asEmu(Number(node["@_marL"]));
|
|
4676
4966
|
}
|
|
4677
4967
|
if (node["@_indent"] !== void 0) {
|
|
4678
|
-
result.indent = Number(node["@_indent"]);
|
|
4968
|
+
result.indent = asEmu(Number(node["@_indent"]));
|
|
4679
4969
|
}
|
|
4680
4970
|
const defRPr = parseDefaultRunProperties(node.defRPr, colorResolver);
|
|
4681
4971
|
if (defRPr) {
|
|
@@ -4716,8 +5006,8 @@ function resolveThemeFont(typeface, fontScheme) {
|
|
|
4716
5006
|
}
|
|
4717
5007
|
|
|
4718
5008
|
// src/parser/presentation-parser.ts
|
|
4719
|
-
var DEFAULT_SLIDE_WIDTH = 9144e3;
|
|
4720
|
-
var DEFAULT_SLIDE_HEIGHT = 5143500;
|
|
5009
|
+
var DEFAULT_SLIDE_WIDTH = asEmu(9144e3);
|
|
5010
|
+
var DEFAULT_SLIDE_HEIGHT = asEmu(5143500);
|
|
4721
5011
|
function parsePresentation(xml) {
|
|
4722
5012
|
const parsed = parseXml(xml);
|
|
4723
5013
|
const pres = parsed.presentation;
|
|
@@ -4738,8 +5028,8 @@ function parsePresentation(xml) {
|
|
|
4738
5028
|
slideSize = { width: DEFAULT_SLIDE_WIDTH, height: DEFAULT_SLIDE_HEIGHT };
|
|
4739
5029
|
} else {
|
|
4740
5030
|
slideSize = {
|
|
4741
|
-
width: Number(sldSz["@_cx"]),
|
|
4742
|
-
height: Number(sldSz["@_cy"])
|
|
5031
|
+
width: asEmu(Number(sldSz["@_cx"])),
|
|
5032
|
+
height: asEmu(Number(sldSz["@_cy"]))
|
|
4743
5033
|
};
|
|
4744
5034
|
}
|
|
4745
5035
|
const sldIdLst = pres.sldIdLst;
|
|
@@ -4897,8 +5187,8 @@ function parseBlipFill(blipFillNode, context) {
|
|
|
4897
5187
|
const imageData = uint8ArrayToBase64(mediaData);
|
|
4898
5188
|
const tileNode = blipFillNode.tile;
|
|
4899
5189
|
const tile = tileNode ? {
|
|
4900
|
-
tx: Number(tileNode["@_tx"] ?? 0),
|
|
4901
|
-
ty: Number(tileNode["@_ty"] ?? 0),
|
|
5190
|
+
tx: asEmu(Number(tileNode["@_tx"] ?? 0)),
|
|
5191
|
+
ty: asEmu(Number(tileNode["@_ty"] ?? 0)),
|
|
4902
5192
|
sx: Number(tileNode["@_sx"] ?? 1e5) / 1e5,
|
|
4903
5193
|
sy: Number(tileNode["@_sy"] ?? 1e5) / 1e5,
|
|
4904
5194
|
flip: tileNode["@_flip"] ?? "none",
|
|
@@ -4955,7 +5245,7 @@ function parseOutline(lnNode, colorResolver) {
|
|
|
4955
5245
|
if (lnNode.pattFill) {
|
|
4956
5246
|
warn("ln.pattFill", "pattern line fill not implemented");
|
|
4957
5247
|
}
|
|
4958
|
-
const width = Number(lnNode["@_w"] ?? 12700);
|
|
5248
|
+
const width = asEmu(Number(lnNode["@_w"] ?? 12700));
|
|
4959
5249
|
let fill = null;
|
|
4960
5250
|
if (lnNode.solidFill) {
|
|
4961
5251
|
const color = colorResolver.resolve(lnNode.solidFill);
|
|
@@ -5036,8 +5326,8 @@ function parseOuterShadow(node, colorResolver) {
|
|
|
5036
5326
|
const color = colorResolver.resolve(node);
|
|
5037
5327
|
if (!color) return null;
|
|
5038
5328
|
return {
|
|
5039
|
-
blurRadius: Number(node["@_blurRad"] ?? 0),
|
|
5040
|
-
distance: Number(node["@_dist"] ?? 0),
|
|
5329
|
+
blurRadius: asEmu(Number(node["@_blurRad"] ?? 0)),
|
|
5330
|
+
distance: asEmu(Number(node["@_dist"] ?? 0)),
|
|
5041
5331
|
direction: Number(node["@_dir"] ?? 0) / 6e4,
|
|
5042
5332
|
color,
|
|
5043
5333
|
alignment: node["@_algn"] ?? "b",
|
|
@@ -5049,8 +5339,8 @@ function parseInnerShadow(node, colorResolver) {
|
|
|
5049
5339
|
const color = colorResolver.resolve(node);
|
|
5050
5340
|
if (!color) return null;
|
|
5051
5341
|
return {
|
|
5052
|
-
blurRadius: Number(node["@_blurRad"] ?? 0),
|
|
5053
|
-
distance: Number(node["@_dist"] ?? 0),
|
|
5342
|
+
blurRadius: asEmu(Number(node["@_blurRad"] ?? 0)),
|
|
5343
|
+
distance: asEmu(Number(node["@_dist"] ?? 0)),
|
|
5054
5344
|
direction: Number(node["@_dir"] ?? 0) / 6e4,
|
|
5055
5345
|
color
|
|
5056
5346
|
};
|
|
@@ -5060,14 +5350,14 @@ function parseGlow(node, colorResolver) {
|
|
|
5060
5350
|
const color = colorResolver.resolve(node);
|
|
5061
5351
|
if (!color) return null;
|
|
5062
5352
|
return {
|
|
5063
|
-
radius: Number(node["@_rad"] ?? 0),
|
|
5353
|
+
radius: asEmu(Number(node["@_rad"] ?? 0)),
|
|
5064
5354
|
color
|
|
5065
5355
|
};
|
|
5066
5356
|
}
|
|
5067
5357
|
function parseSoftEdge(node) {
|
|
5068
5358
|
if (!node) return null;
|
|
5069
5359
|
return {
|
|
5070
|
-
radius: Number(node["@_rad"] ?? 0)
|
|
5360
|
+
radius: asEmu(Number(node["@_rad"] ?? 0))
|
|
5071
5361
|
};
|
|
5072
5362
|
}
|
|
5073
5363
|
|
|
@@ -5536,7 +5826,7 @@ function parseBiLevel(node) {
|
|
|
5536
5826
|
function parseBlur(node) {
|
|
5537
5827
|
if (!node) return null;
|
|
5538
5828
|
return {
|
|
5539
|
-
radius: Number(node["@_rad"] ?? 0),
|
|
5829
|
+
radius: asEmu(Number(node["@_rad"] ?? 0)),
|
|
5540
5830
|
grow: node["@_grow"] !== "0"
|
|
5541
5831
|
};
|
|
5542
5832
|
}
|
|
@@ -5586,7 +5876,11 @@ var CHART_TYPE_MAP = [
|
|
|
5586
5876
|
["bubbleChart", "bubble"],
|
|
5587
5877
|
["areaChart", "area"],
|
|
5588
5878
|
["area3DChart", "area"],
|
|
5589
|
-
["radarChart", "radar"]
|
|
5879
|
+
["radarChart", "radar"],
|
|
5880
|
+
["stockChart", "stock"],
|
|
5881
|
+
["surfaceChart", "surface"],
|
|
5882
|
+
["surface3DChart", "surface"],
|
|
5883
|
+
["ofPieChart", "ofPie"]
|
|
5590
5884
|
];
|
|
5591
5885
|
function parseChart(chartXml, colorResolver) {
|
|
5592
5886
|
const parsed = parseXml(chartXml);
|
|
@@ -5597,7 +5891,17 @@ function parseChart(chartXml, colorResolver) {
|
|
|
5597
5891
|
const plotArea = chart.plotArea;
|
|
5598
5892
|
if (!plotArea) return null;
|
|
5599
5893
|
const title = parseChartTitle(chart.title);
|
|
5600
|
-
const {
|
|
5894
|
+
const {
|
|
5895
|
+
chartType,
|
|
5896
|
+
series,
|
|
5897
|
+
categories,
|
|
5898
|
+
barDirection,
|
|
5899
|
+
holeSize,
|
|
5900
|
+
radarStyle,
|
|
5901
|
+
ofPieType,
|
|
5902
|
+
secondPieSize,
|
|
5903
|
+
splitPos
|
|
5904
|
+
} = parseChartTypeAndData(plotArea, colorResolver);
|
|
5601
5905
|
if (!chartType) return null;
|
|
5602
5906
|
const legend = parseLegend(chart.legend);
|
|
5603
5907
|
return {
|
|
@@ -5608,6 +5912,9 @@ function parseChart(chartXml, colorResolver) {
|
|
|
5608
5912
|
...barDirection !== void 0 && { barDirection },
|
|
5609
5913
|
...holeSize !== void 0 && { holeSize },
|
|
5610
5914
|
...radarStyle !== void 0 && { radarStyle },
|
|
5915
|
+
...ofPieType !== void 0 && { ofPieType },
|
|
5916
|
+
...secondPieSize !== void 0 && { secondPieSize },
|
|
5917
|
+
...splitPos !== void 0 && { splitPos },
|
|
5611
5918
|
legend
|
|
5612
5919
|
};
|
|
5613
5920
|
}
|
|
@@ -5626,15 +5933,23 @@ function parseChartTypeAndData(plotArea, colorResolver) {
|
|
|
5626
5933
|
const holeSize = chartType === "doughnut" ? Number(holeSizeNode?.["@_val"] ?? 50) : void 0;
|
|
5627
5934
|
const radarStyleNode = chartNode.radarStyle;
|
|
5628
5935
|
const radarStyle = chartType === "radar" ? radarStyleNode?.["@_val"] ?? "standard" : void 0;
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5635
|
-
|
|
5636
|
-
|
|
5637
|
-
|
|
5936
|
+
const ofPieTypeNode = chartNode.ofPieType;
|
|
5937
|
+
const ofPieType = chartType === "ofPie" ? ofPieTypeNode?.["@_val"] ?? "pie" : void 0;
|
|
5938
|
+
const secondPieSizeNode = chartNode.secondPieSize;
|
|
5939
|
+
const secondPieSize = chartType === "ofPie" ? Number(secondPieSizeNode?.["@_val"] ?? 75) : void 0;
|
|
5940
|
+
const splitPosNode = chartNode.splitPos;
|
|
5941
|
+
const splitPos = chartType === "ofPie" ? Number(splitPosNode?.["@_val"] ?? 2) : void 0;
|
|
5942
|
+
return {
|
|
5943
|
+
chartType,
|
|
5944
|
+
series,
|
|
5945
|
+
categories,
|
|
5946
|
+
barDirection,
|
|
5947
|
+
holeSize,
|
|
5948
|
+
radarStyle,
|
|
5949
|
+
ofPieType,
|
|
5950
|
+
secondPieSize,
|
|
5951
|
+
splitPos
|
|
5952
|
+
};
|
|
5638
5953
|
}
|
|
5639
5954
|
return { chartType: null, series: [], categories: [] };
|
|
5640
5955
|
}
|
|
@@ -6002,28 +6317,31 @@ function parseTable(tblNode, colorResolver, fontScheme) {
|
|
|
6002
6317
|
if (!tblNode) return null;
|
|
6003
6318
|
const columns = parseColumns(tblNode.tblGrid);
|
|
6004
6319
|
if (columns.length === 0) return null;
|
|
6005
|
-
const
|
|
6320
|
+
const tblPr = tblNode.tblPr;
|
|
6321
|
+
const hasTableStyle = tblPr?.tableStyleId !== void 0;
|
|
6322
|
+
const defaultBorders = hasTableStyle ? createDefaultBorders() : null;
|
|
6323
|
+
const rows = parseRows(tblNode.tr, colorResolver, fontScheme, defaultBorders);
|
|
6006
6324
|
return { rows, columns };
|
|
6007
6325
|
}
|
|
6008
6326
|
function parseColumns(tblGrid) {
|
|
6009
6327
|
if (!tblGrid) return [];
|
|
6010
6328
|
const gridCols = tblGrid.gridCol ?? [];
|
|
6011
6329
|
return gridCols.map((col) => ({
|
|
6012
|
-
width: Number(col["@_w"] ?? 0)
|
|
6330
|
+
width: asEmu(Number(col["@_w"] ?? 0))
|
|
6013
6331
|
}));
|
|
6014
6332
|
}
|
|
6015
|
-
function parseRows(trList, colorResolver, fontScheme) {
|
|
6333
|
+
function parseRows(trList, colorResolver, fontScheme, defaultBorders) {
|
|
6016
6334
|
if (!trList) return [];
|
|
6017
6335
|
const trArr = Array.isArray(trList) ? trList : [trList];
|
|
6018
6336
|
const rows = [];
|
|
6019
6337
|
for (const tr of trArr) {
|
|
6020
|
-
const height = Number(tr["@_h"] ?? 0);
|
|
6021
|
-
const cells = parseCells(tr.tc, colorResolver, fontScheme);
|
|
6338
|
+
const height = asEmu(Number(tr["@_h"] ?? 0));
|
|
6339
|
+
const cells = parseCells(tr.tc, colorResolver, fontScheme, defaultBorders);
|
|
6022
6340
|
rows.push({ height, cells });
|
|
6023
6341
|
}
|
|
6024
6342
|
return rows;
|
|
6025
6343
|
}
|
|
6026
|
-
function parseCells(tcList, colorResolver, fontScheme) {
|
|
6344
|
+
function parseCells(tcList, colorResolver, fontScheme, defaultBorders) {
|
|
6027
6345
|
if (!tcList) return [];
|
|
6028
6346
|
const tcArr = Array.isArray(tcList) ? tcList : [tcList];
|
|
6029
6347
|
const cells = [];
|
|
@@ -6031,7 +6349,8 @@ function parseCells(tcList, colorResolver, fontScheme) {
|
|
|
6031
6349
|
const textBody = parseTextBody(tc.txBody, colorResolver, void 0, fontScheme);
|
|
6032
6350
|
const tcPr = tc.tcPr;
|
|
6033
6351
|
const fill = tcPr ? parseFillFromNode(tcPr, colorResolver) : null;
|
|
6034
|
-
const
|
|
6352
|
+
const inlineBorders = tcPr ? parseCellBorders(tcPr, colorResolver) : null;
|
|
6353
|
+
const borders = inlineBorders ?? defaultBorders ?? null;
|
|
6035
6354
|
const gridSpan = Number(tc["@_gridSpan"] ?? 1);
|
|
6036
6355
|
const rowSpan = Number(tc["@_rowSpan"] ?? 1);
|
|
6037
6356
|
const hMerge = tcPr?.["@_hMerge"] === "1" || tcPr?.["@_hMerge"] === "true";
|
|
@@ -6045,9 +6364,29 @@ function parseCellBorders(tcPr, colorResolver) {
|
|
|
6045
6364
|
const bottom = parseOutline(tcPr.lnB, colorResolver);
|
|
6046
6365
|
const left = parseOutline(tcPr.lnL, colorResolver);
|
|
6047
6366
|
const right = parseOutline(tcPr.lnR, colorResolver);
|
|
6367
|
+
for (const border of [top, bottom, left, right]) {
|
|
6368
|
+
if (border && !border.fill) {
|
|
6369
|
+
border.fill = { type: "solid", color: { hex: "#000000", alpha: 1 } };
|
|
6370
|
+
}
|
|
6371
|
+
}
|
|
6048
6372
|
if (!top && !bottom && !left && !right) return null;
|
|
6049
6373
|
return { top, bottom, left, right };
|
|
6050
6374
|
}
|
|
6375
|
+
function createDefaultBorders() {
|
|
6376
|
+
const defaultOutline = {
|
|
6377
|
+
width: asEmu(12700),
|
|
6378
|
+
fill: { type: "solid", color: { hex: "#000000", alpha: 1 } },
|
|
6379
|
+
dashStyle: "solid",
|
|
6380
|
+
headEnd: null,
|
|
6381
|
+
tailEnd: null
|
|
6382
|
+
};
|
|
6383
|
+
return {
|
|
6384
|
+
top: { ...defaultOutline },
|
|
6385
|
+
bottom: { ...defaultOutline },
|
|
6386
|
+
left: { ...defaultOutline },
|
|
6387
|
+
right: { ...defaultOutline }
|
|
6388
|
+
};
|
|
6389
|
+
}
|
|
6051
6390
|
|
|
6052
6391
|
// src/parser/slide-parser.ts
|
|
6053
6392
|
var SHAPE_TAGS = /* @__PURE__ */ new Set(["sp", "pic", "cxnSp", "grpSp", "graphicFrame"]);
|
|
@@ -6475,8 +6814,8 @@ function parseStretchFillRect(stretchNode) {
|
|
|
6475
6814
|
function parseTileInfo(node) {
|
|
6476
6815
|
if (!node) return null;
|
|
6477
6816
|
return {
|
|
6478
|
-
tx: Number(node["@_tx"] ?? 0),
|
|
6479
|
-
ty: Number(node["@_ty"] ?? 0),
|
|
6817
|
+
tx: asEmu(Number(node["@_tx"] ?? 0)),
|
|
6818
|
+
ty: asEmu(Number(node["@_ty"] ?? 0)),
|
|
6480
6819
|
sx: Number(node["@_sx"] ?? 1e5) / 1e5,
|
|
6481
6820
|
sy: Number(node["@_sy"] ?? 1e5) / 1e5,
|
|
6482
6821
|
flip: node["@_flip"] ?? "none",
|
|
@@ -6508,10 +6847,10 @@ function parseGroup(grp, rels, slidePath, archive, colorResolver, parentFillCont
|
|
|
6508
6847
|
const childOff = xfrm?.chOff;
|
|
6509
6848
|
const childExt = xfrm?.chExt;
|
|
6510
6849
|
const childTransform = {
|
|
6511
|
-
offsetX: Number(childOff?.["@_x"] ?? 0),
|
|
6512
|
-
offsetY: Number(childOff?.["@_y"] ?? 0),
|
|
6513
|
-
extentWidth: Number(childExt?.["@_cx"] ?? transform.extentWidth),
|
|
6514
|
-
extentHeight: Number(childExt?.["@_cy"] ?? transform.extentHeight),
|
|
6850
|
+
offsetX: asEmu(Number(childOff?.["@_x"] ?? 0)),
|
|
6851
|
+
offsetY: asEmu(Number(childOff?.["@_y"] ?? 0)),
|
|
6852
|
+
extentWidth: asEmu(Number(childExt?.["@_cx"] ?? transform.extentWidth)),
|
|
6853
|
+
extentHeight: asEmu(Number(childExt?.["@_cy"] ?? transform.extentHeight)),
|
|
6515
6854
|
rotation: 0,
|
|
6516
6855
|
flipH: false,
|
|
6517
6856
|
flipV: false
|
|
@@ -6632,10 +6971,10 @@ function parseSmartArt(graphicData, transform, rels, slidePath, archive, colorRe
|
|
|
6632
6971
|
const childOff = grpXfrm?.chOff;
|
|
6633
6972
|
const childExt = grpXfrm?.chExt;
|
|
6634
6973
|
const childTransform = {
|
|
6635
|
-
offsetX: Number(childOff?.["@_x"] ?? 0),
|
|
6636
|
-
offsetY: Number(childOff?.["@_y"] ?? 0),
|
|
6637
|
-
extentWidth: Number(childExt?.["@_cx"] ?? transform.extentWidth),
|
|
6638
|
-
extentHeight: Number(childExt?.["@_cy"] ?? transform.extentHeight),
|
|
6974
|
+
offsetX: asEmu(Number(childOff?.["@_x"] ?? 0)),
|
|
6975
|
+
offsetY: asEmu(Number(childOff?.["@_y"] ?? 0)),
|
|
6976
|
+
extentWidth: asEmu(Number(childExt?.["@_cx"] ?? transform.extentWidth)),
|
|
6977
|
+
extentHeight: asEmu(Number(childExt?.["@_cy"] ?? transform.extentHeight)),
|
|
6639
6978
|
rotation: 0,
|
|
6640
6979
|
flipH: false,
|
|
6641
6980
|
flipV: false
|
|
@@ -6672,26 +7011,26 @@ function parseTransform(xfrm) {
|
|
|
6672
7011
|
const off = xfrm.off;
|
|
6673
7012
|
const ext = xfrm.ext;
|
|
6674
7013
|
if (!off || !ext) return null;
|
|
6675
|
-
let offsetX = Number(off["@_x"] ?? 0);
|
|
6676
|
-
let offsetY = Number(off["@_y"] ?? 0);
|
|
6677
|
-
let extentWidth = Number(ext["@_cx"] ?? 0);
|
|
6678
|
-
let extentHeight = Number(ext["@_cy"] ?? 0);
|
|
7014
|
+
let offsetX = asEmu(Number(off["@_x"] ?? 0));
|
|
7015
|
+
let offsetY = asEmu(Number(off["@_y"] ?? 0));
|
|
7016
|
+
let extentWidth = asEmu(Number(ext["@_cx"] ?? 0));
|
|
7017
|
+
let extentHeight = asEmu(Number(ext["@_cy"] ?? 0));
|
|
6679
7018
|
let rotation = Number(xfrm["@_rot"] ?? 0);
|
|
6680
7019
|
if (Number.isNaN(offsetX)) {
|
|
6681
7020
|
debug("transform.nan", "NaN detected in transform offsetX, defaulting to 0");
|
|
6682
|
-
offsetX = 0;
|
|
7021
|
+
offsetX = asEmu(0);
|
|
6683
7022
|
}
|
|
6684
7023
|
if (Number.isNaN(offsetY)) {
|
|
6685
7024
|
debug("transform.nan", "NaN detected in transform offsetY, defaulting to 0");
|
|
6686
|
-
offsetY = 0;
|
|
7025
|
+
offsetY = asEmu(0);
|
|
6687
7026
|
}
|
|
6688
7027
|
if (Number.isNaN(extentWidth)) {
|
|
6689
7028
|
debug("transform.nan", "NaN detected in transform extentWidth, defaulting to 0");
|
|
6690
|
-
extentWidth = 0;
|
|
7029
|
+
extentWidth = asEmu(0);
|
|
6691
7030
|
}
|
|
6692
7031
|
if (Number.isNaN(extentHeight)) {
|
|
6693
7032
|
debug("transform.nan", "NaN detected in transform extentHeight, defaulting to 0");
|
|
6694
|
-
extentHeight = 0;
|
|
7033
|
+
extentHeight = asEmu(0);
|
|
6695
7034
|
}
|
|
6696
7035
|
if (Number.isNaN(rotation)) {
|
|
6697
7036
|
debug("transform.nan", "NaN detected in transform rotation, defaulting to 0");
|
|
@@ -6756,10 +7095,10 @@ function parseTextBody(txBody, colorResolver, rels, fontScheme, lstStyleOverride
|
|
|
6756
7095
|
}
|
|
6757
7096
|
const bodyProperties = {
|
|
6758
7097
|
anchor: bodyPr?.["@_anchor"] ?? "t",
|
|
6759
|
-
marginLeft: Number(bodyPr?.["@_lIns"] ?? 91440),
|
|
6760
|
-
marginRight: Number(bodyPr?.["@_rIns"] ?? 91440),
|
|
6761
|
-
marginTop: Number(bodyPr?.["@_tIns"] ?? 45720),
|
|
6762
|
-
marginBottom: Number(bodyPr?.["@_bIns"] ?? 45720),
|
|
7098
|
+
marginLeft: asEmu(Number(bodyPr?.["@_lIns"] ?? 91440)),
|
|
7099
|
+
marginRight: asEmu(Number(bodyPr?.["@_rIns"] ?? 91440)),
|
|
7100
|
+
marginTop: asEmu(Number(bodyPr?.["@_tIns"] ?? 45720)),
|
|
7101
|
+
marginBottom: asEmu(Number(bodyPr?.["@_bIns"] ?? 45720)),
|
|
6763
7102
|
wrap: bodyPr?.["@_wrap"] ?? "square",
|
|
6764
7103
|
autoFit,
|
|
6765
7104
|
fontScale,
|
|
@@ -6828,13 +7167,13 @@ function parseBullet(pPr, colorResolver) {
|
|
|
6828
7167
|
function parseSpacing(spc) {
|
|
6829
7168
|
if (spc?.spcPts) {
|
|
6830
7169
|
const spcPts = spc.spcPts;
|
|
6831
|
-
return { type: "pts", value: Number(spcPts["@_val"]) };
|
|
7170
|
+
return { type: "pts", value: asHundredthPt(Number(spcPts["@_val"])) };
|
|
6832
7171
|
}
|
|
6833
7172
|
if (spc?.spcPct) {
|
|
6834
7173
|
const spcPct = spc.spcPct;
|
|
6835
7174
|
return { type: "pct", value: Number(spcPct["@_val"]) };
|
|
6836
7175
|
}
|
|
6837
|
-
return { type: "pts", value: 0 };
|
|
7176
|
+
return { type: "pts", value: asHundredthPt(0) };
|
|
6838
7177
|
}
|
|
6839
7178
|
function parseTabStops(pPr) {
|
|
6840
7179
|
const tabLst = pPr?.tabLst;
|
|
@@ -6843,7 +7182,7 @@ function parseTabStops(pPr) {
|
|
|
6843
7182
|
if (!tabs) return [];
|
|
6844
7183
|
const tabArr = Array.isArray(tabs) ? tabs : [tabs];
|
|
6845
7184
|
return tabArr.map((tab) => ({
|
|
6846
|
-
position: Number(tab["@_pos"] ?? 0),
|
|
7185
|
+
position: asEmu(Number(tab["@_pos"] ?? 0)),
|
|
6847
7186
|
alignment: tab["@_algn"] ?? "l"
|
|
6848
7187
|
}));
|
|
6849
7188
|
}
|
|
@@ -6893,8 +7232,8 @@ function parseParagraph(p, colorResolver, rels, fontScheme, lstStyle, orderedPCh
|
|
|
6893
7232
|
bulletFont,
|
|
6894
7233
|
bulletColor,
|
|
6895
7234
|
bulletSizePct,
|
|
6896
|
-
marginLeft: pPr?.["@_marL"] !== void 0 ? Number(pPr["@_marL"]) : lstLevelProps?.marginLeft ?? 0,
|
|
6897
|
-
indent: pPr?.["@_indent"] !== void 0 ? Number(pPr["@_indent"]) : lstLevelProps?.indent ?? 0,
|
|
7235
|
+
marginLeft: pPr?.["@_marL"] !== void 0 ? asEmu(Number(pPr["@_marL"])) : lstLevelProps?.marginLeft ?? asEmu(0),
|
|
7236
|
+
indent: pPr?.["@_indent"] !== void 0 ? asEmu(Number(pPr["@_indent"])) : lstLevelProps?.indent ?? asEmu(0),
|
|
6898
7237
|
tabStops
|
|
6899
7238
|
};
|
|
6900
7239
|
const pPrDefRPr = parseDefaultRunProperties(pPr?.defRPr);
|
|
@@ -7036,7 +7375,7 @@ function parseRunProperties(rPr, colorResolver, rels, fontScheme, defaults) {
|
|
|
7036
7375
|
const latin = rPr.latin;
|
|
7037
7376
|
const ea = rPr.ea;
|
|
7038
7377
|
const cs = rPr.cs;
|
|
7039
|
-
const fontSize = rPr["@_sz"] ? hundredthPointToPoint(Number(rPr["@_sz"])) : defaults?.fontSize ?? null;
|
|
7378
|
+
const fontSize = rPr["@_sz"] ? hundredthPointToPoint(asHundredthPt(Number(rPr["@_sz"]))) : defaults?.fontSize ?? null;
|
|
7040
7379
|
const fontFamily = resolveThemeFont(
|
|
7041
7380
|
latin?.["@_typeface"] ?? defaults?.fontFamily ?? null,
|
|
7042
7381
|
fontScheme
|
|
@@ -7063,7 +7402,7 @@ function parseRunProperties(rPr, colorResolver, rels, fontScheme, defaults) {
|
|
|
7063
7402
|
const ln = rPr.ln;
|
|
7064
7403
|
let outline = null;
|
|
7065
7404
|
if (ln) {
|
|
7066
|
-
const lnWidth = Number(ln["@_w"] ?? 12700);
|
|
7405
|
+
const lnWidth = asEmu(Number(ln["@_w"] ?? 12700));
|
|
7067
7406
|
const lnFill = ln.solidFill;
|
|
7068
7407
|
const lnColor = lnFill ? colorResolver.resolve(lnFill) : null;
|
|
7069
7408
|
if (lnColor) {
|
|
@@ -7353,7 +7692,23 @@ function findMatchingPlaceholderStyle(placeholderType, placeholderIdx, styles) {
|
|
|
7353
7692
|
if (byIdx?.lstStyle) return byIdx.lstStyle;
|
|
7354
7693
|
}
|
|
7355
7694
|
const byType = styles.find((s) => s.placeholderType === placeholderType);
|
|
7356
|
-
|
|
7695
|
+
if (byType?.lstStyle) return byType.lstStyle;
|
|
7696
|
+
const fallbackType = getPlaceholderFallbackType(placeholderType);
|
|
7697
|
+
if (fallbackType) {
|
|
7698
|
+
const byFallback = styles.find((s) => s.placeholderType === fallbackType);
|
|
7699
|
+
return byFallback?.lstStyle;
|
|
7700
|
+
}
|
|
7701
|
+
return void 0;
|
|
7702
|
+
}
|
|
7703
|
+
function getPlaceholderFallbackType(type) {
|
|
7704
|
+
switch (type) {
|
|
7705
|
+
case "ctrTitle":
|
|
7706
|
+
return "title";
|
|
7707
|
+
case "subTitle":
|
|
7708
|
+
return "body";
|
|
7709
|
+
default:
|
|
7710
|
+
return void 0;
|
|
7711
|
+
}
|
|
7357
7712
|
}
|
|
7358
7713
|
function getTxStyleForPlaceholder(placeholderType, txStyles) {
|
|
7359
7714
|
if (!txStyles) return void 0;
|