feat: 完成 DOCX R4 元素级视觉门禁
建立 Chromium、Word 与 WPS 的可编辑内容、段落几何、页眉页脚、封面、媒体和逐页视觉比较链路。 支持封面独立分节、正文页码重启、主题页边距与横向纸张,并将自然分页差异降为诊断项。 修正代码块内边距和折叠表格单元格边框映射,14 套主题生产矩阵与六组布局视觉矩阵通过。
This commit is contained in:
@@ -463,11 +463,21 @@ function normalizeComputedSlot(
|
||||
};
|
||||
}
|
||||
}
|
||||
if (widthSlots.has(context.slot) && context.documentWidthPx) {
|
||||
const containingBlockWidthPt = computed.containingBlockWidth
|
||||
? parseCssLengthToPt(computed.containingBlockWidth)
|
||||
: undefined;
|
||||
const relativeWidthPx =
|
||||
containingBlockWidthPt !== undefined
|
||||
? containingBlockWidthPt / 0.75
|
||||
: context.documentWidthPx;
|
||||
if (
|
||||
(widthSlots.has(context.slot) || context.kind === "structure") &&
|
||||
relativeWidthPx
|
||||
) {
|
||||
const widthPt = parseCssLengthToPt(computed.width);
|
||||
const widthPx = widthPt === undefined ? undefined : widthPt / 0.75;
|
||||
if (widthPx !== undefined) {
|
||||
const percent = (widthPx / context.documentWidthPx) * 100;
|
||||
const percent = (widthPx / relativeWidthPx) * 100;
|
||||
style.widthPercent = Math.round(
|
||||
Math.max(0, Math.min(100, percent))
|
||||
);
|
||||
@@ -482,6 +492,27 @@ function normalizeComputedSlot(
|
||||
}
|
||||
}
|
||||
}
|
||||
if (context.kind === "structure" && context.documentWidthPx) {
|
||||
const percentage = /^([+-]?(?:\d+\.?\d*|\.\d+))%$/u.exec(
|
||||
computed.minWidth
|
||||
);
|
||||
const minimumWidthPercent = percentage
|
||||
? Number.parseFloat(percentage[1]!)
|
||||
: (() => {
|
||||
const minimumWidthPt = parseCssLengthToPt(computed.minWidth);
|
||||
return minimumWidthPt === undefined
|
||||
? undefined
|
||||
: ((minimumWidthPt / 0.75) / context.documentWidthPx) * 100;
|
||||
})();
|
||||
if (
|
||||
minimumWidthPercent !== undefined &&
|
||||
minimumWidthPercent > 0
|
||||
) {
|
||||
style.minimumWidthPercent = roundDocxValue(
|
||||
Math.min(100, minimumWidthPercent)
|
||||
);
|
||||
}
|
||||
}
|
||||
const minimumHeightPt = length(
|
||||
context,
|
||||
"min-height",
|
||||
@@ -491,6 +522,15 @@ function normalizeComputedSlot(
|
||||
if (minimumHeightPt !== undefined && minimumHeightPt > 0) {
|
||||
style.minimumHeightPt = minimumHeightPt;
|
||||
}
|
||||
const contentPaddingLeftPt = computed.contentPaddingLeft
|
||||
? length(context, "content-padding-left", computed.contentPaddingLeft, {
|
||||
allowAuto: true,
|
||||
nonNegative: true
|
||||
})
|
||||
: undefined;
|
||||
if (contentPaddingLeftPt !== undefined && contentPaddingLeftPt > 0) {
|
||||
style.contentPaddingLeftPt = contentPaddingLeftPt;
|
||||
}
|
||||
if (computed.display === "none") {
|
||||
style.hidden = true;
|
||||
}
|
||||
@@ -512,6 +552,35 @@ function normalizeComputedSlot(
|
||||
if (resolved) {
|
||||
style.verticalAlignment = resolved;
|
||||
}
|
||||
const childAlignment = {
|
||||
"flex-start": "left",
|
||||
start: "left",
|
||||
center: "center",
|
||||
"flex-end": "right",
|
||||
end: "right",
|
||||
stretch: "stretch"
|
||||
} as const;
|
||||
const resolvedChildAlignment =
|
||||
childAlignment[
|
||||
computed.alignItems as keyof typeof childAlignment
|
||||
];
|
||||
if (resolvedChildAlignment) {
|
||||
style.childAlignment = resolvedChildAlignment;
|
||||
}
|
||||
}
|
||||
const selfAlignment = {
|
||||
"flex-start": "left",
|
||||
start: "left",
|
||||
center: "center",
|
||||
"flex-end": "right",
|
||||
end: "right",
|
||||
stretch: "stretch"
|
||||
} as const;
|
||||
const resolvedSelfAlignment = computed.alignSelf
|
||||
? selfAlignment[computed.alignSelf as keyof typeof selfAlignment]
|
||||
: undefined;
|
||||
if (resolvedSelfAlignment) {
|
||||
style.selfAlignment = resolvedSelfAlignment;
|
||||
}
|
||||
if (computed.display === "flex" || computed.display === "grid") {
|
||||
diagnostic(context, {
|
||||
|
||||
Reference in New Issue
Block a user