feat: 完成 DOCX R4 元素级视觉门禁

建立 Chromium、Word 与 WPS 的可编辑内容、段落几何、页眉页脚、封面、媒体和逐页视觉比较链路。

支持封面独立分节、正文页码重启、主题页边距与横向纸张,并将自然分页差异降为诊断项。

修正代码块内边距和折叠表格单元格边框映射,14 套主题生产矩阵与六组布局视觉矩阵通过。
This commit is contained in:
SkyJourney
2026-08-02 03:27:11 +08:00
parent f9f5fccfc9
commit 58f87cc19f
100 changed files with 10409 additions and 386 deletions
@@ -6,7 +6,9 @@ import { describe, expect, it, vi } from "vitest";
import {
createChromiumPdfAdapter,
createWordDocxRoundTripAdapter,
createWordPdfAdapter,
createWpsDocxRoundTripAdapter,
createWpsPdfAdapter,
preparePdfAdapterRun,
runPdfAdapterVisualDiff,
@@ -58,6 +60,7 @@ describe("Office PDF 适配器", () => {
progId: string;
outputPath: string;
}> = [];
const roundTripCalls: string[] = [];
const backend: OfficeAutomationBackend = {
probe: async () => true,
exportPdf: async (options) => {
@@ -70,6 +73,22 @@ describe("Office PDF 适配器", () => {
});
return { bytes: pdf.byteLength, pageCount: 1 };
},
roundTripDocx: async (options) => {
const docx = Buffer.from("round-trip-docx");
await writeFile(options.outputPath, docx);
roundTripCalls.push(options.client);
return {
bytes: docx.byteLength,
before: [
{ index: 1, widthPt: 100, heightPt: 50, type: 3 },
],
saved: [
{ index: 1, widthPt: 90, heightPt: 45, type: 3 },
],
resizedShapeIndex: 1,
resizeScale: options.resizeScale,
};
},
};
try {
const word = createWordPdfAdapter({ backend });
@@ -78,6 +97,15 @@ describe("Office PDF 适配器", () => {
expect((await wps.probe()).available).toBe(true);
expect((await word.generate({ docxPath })).source.kind).toBe("word");
expect((await wps.generate({ docxPath })).source.kind).toBe("wps");
const wordRoundTrip = await createWordDocxRoundTripAdapter({
backend,
}).generate({ docxPath });
const wpsRoundTrip = await createWpsDocxRoundTripAdapter({
backend,
}).generate({ docxPath });
expect(wordRoundTrip.saved[0]?.widthPt).toBe(90);
expect(wpsRoundTrip.saved[0]?.heightPt).toBe(45);
expect(roundTripCalls).toEqual(["word", "wps"]);
expect(calls.map(({ client, progId }) => ({ client, progId }))).toEqual([
{ client: "word", progId: "Word.Application" },
{ client: "wps", progId: "KWPS.Application" },