Skip to content

Commit b6a2a64

Browse files
committed
Set correct image widths for em and rem dimensions
1 parent 0e606f1 commit b6a2a64

File tree

3 files changed

+84
-47
lines changed

3 files changed

+84
-47
lines changed

Diff for: src/helpers/xml-builder.ts

+70-43
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ import {
3636
import {
3737
cmRegex,
3838
cmToTWIP,
39+
emRegex,
40+
emToEmu,
3941
HIPToTWIP,
4042
inchRegex,
4143
inchToTWIP,
@@ -49,6 +51,8 @@ import {
4951
pointToEIP,
5052
pointToHIP,
5153
pointToTWIP,
54+
remRegex,
55+
remToEmu,
5256
TWIPToEMU,
5357
} from "../utils/unit-conversion.ts"
5458
import { isValidUrl } from "../utils/url.ts"
@@ -1093,42 +1097,52 @@ function computeImageDimensions(vNode: VNode, attributes: Attributes) {
10931097
let modifiedWidth
10941098

10951099
if (vNode.properties && vNode.properties.style) {
1096-
if (vNode.properties.style.width) {
1097-
if (vNode.properties.style.width !== "auto") {
1098-
if (pixelRegex.test(vNode.properties.style.width)) {
1099-
modifiedWidth = pixelToEMU(
1100-
vNode.properties.style.width.match(pixelRegex)[1],
1101-
)
1100+
const styleWidth = vNode.properties.style.width
1101+
const styleHeight = vNode.properties.style.height
1102+
1103+
if (styleWidth) {
1104+
if (styleWidth !== "auto") {
1105+
if (pixelRegex.test(styleWidth)) {
1106+
modifiedWidth = pixelToEMU(styleWidth.match(pixelRegex)[1])
1107+
}
1108+
else if (emRegex.test(styleWidth)) {
1109+
modifiedWidth = emToEmu(styleWidth.match(emRegex)[1])
11021110
}
1103-
else if (percentageRegex.test(vNode.properties.style.width)) {
1104-
const percentageValue =
1105-
vNode.properties.style.width.match(percentageRegex)[1]
1111+
else if (remRegex.test(styleWidth)) {
1112+
modifiedWidth = remToEmu(styleWidth.match(remRegex)[1])
1113+
}
1114+
else if (percentageRegex.test(styleWidth)) {
1115+
const percentageValue = styleWidth.match(percentageRegex)[1]
11061116

11071117
modifiedWidth = Math.round(
11081118
(percentageValue / 100) * originalWidthInEMU,
11091119
)
11101120
}
1121+
else {
1122+
modifiedWidth = originalWidthInEMU
1123+
modifiedHeight = originalHeightInEMU
1124+
}
11111125
}
11121126
else {
1113-
if (
1114-
vNode.properties.style.height &&
1115-
vNode.properties.style.height === "auto"
1116-
) {
1127+
if (styleHeight && styleHeight === "auto") {
11171128
modifiedWidth = originalWidthInEMU
11181129
modifiedHeight = originalHeightInEMU
11191130
}
11201131
}
11211132
}
1122-
if (vNode.properties.style.height) {
1123-
if (vNode.properties.style.height !== "auto") {
1124-
if (pixelRegex.test(vNode.properties.style.height)) {
1125-
modifiedHeight = pixelToEMU(
1126-
vNode.properties.style.height.match(pixelRegex)[1],
1127-
)
1133+
if (styleHeight) {
1134+
if (styleHeight !== "auto") {
1135+
if (pixelRegex.test(styleHeight)) {
1136+
modifiedHeight = pixelToEMU(styleHeight.match(pixelRegex)[1])
1137+
}
1138+
else if (emRegex.test(styleWidth)) {
1139+
modifiedWidth = emToEmu(styleWidth.match(emRegex)[1])
11281140
}
1129-
else if (percentageRegex.test(vNode.properties.style.height)) {
1130-
const percentageValue =
1131-
vNode.properties.style.width.match(percentageRegex)[1]
1141+
else if (remRegex.test(styleWidth)) {
1142+
modifiedWidth = emToEmu(styleWidth.match(remRegex)[1])
1143+
}
1144+
else if (percentageRegex.test(styleHeight)) {
1145+
const percentageValue = styleWidth.match(percentageRegex)[1]
11321146

11331147
modifiedHeight = Math.round(
11341148
(percentageValue / 100) * originalHeightInEMU,
@@ -1156,14 +1170,18 @@ function computeImageDimensions(vNode: VNode, attributes: Attributes) {
11561170
else if (modifiedHeight && !modifiedWidth) {
11571171
modifiedWidth = Math.round(modifiedHeight * aspectRatio)
11581172
}
1173+
else {
1174+
modifiedWidth = originalWidthInEMU
1175+
modifiedHeight = originalHeightInEMU
1176+
}
11591177
}
11601178
else {
11611179
modifiedWidth = originalWidthInEMU
11621180
modifiedHeight = originalHeightInEMU
11631181
}
11641182

11651183
attributes.width = modifiedWidth
1166-
attributes.height = modifiedHeight || 0
1184+
attributes.height = modifiedHeight
11671185
}
11681186

11691187
async function buildParagraph(
@@ -2093,16 +2111,16 @@ function buildTableProperties(attributes: Attributes) {
20932111
}
20942112
case "tableCellSpacing": {
20952113
const tableCellSpacingFragment = buildTableCellSpacing(
2096-
attributes[key],
2114+
attributes.tableCellSpacing,
20972115
)
20982116
tablePropertiesFragment.import(tableCellSpacingFragment)
20992117

21002118
delete attributes.tableCellSpacing
21012119
break
21022120
}
21032121
case "width": {
2104-
if (attributes[key]) {
2105-
const tableWidthFragment = buildTableWidth(attributes[key])
2122+
if (attributes.width) {
2123+
const tableWidthFragment = buildTableWidth(attributes.width)
21062124
tablePropertiesFragment.import(tableWidthFragment)
21072125
}
21082126

@@ -2376,11 +2394,14 @@ function buildPresetGeometry() {
23762394
.up()
23772395
}
23782396

2379-
function buildExtents({ width = 0, height = 0 }) {
2397+
function buildExtents({ width, height }: { width?: number; height?: number }) {
2398+
if (!width && !height) {
2399+
return
2400+
}
23802401
return fragment({ namespaceAlias: { a: namespaces.a } })
23812402
.ele("@a", "ext")
2382-
.att("cx", String(width))
2383-
.att("cy", String(height))
2403+
.att("cx", String(width || ""))
2404+
.att("cy", String(height || ""))
23842405
.up()
23852406
}
23862407

@@ -2393,27 +2414,26 @@ function buildOffset() {
23932414
}
23942415

23952416
function buildGraphicFrameTransform(
2396-
attributes: { width: number; height: number },
2417+
attributes: { width?: number; height?: number },
23972418
) {
23982419
const graphicFrameTransformFragment = fragment({
23992420
namespaceAlias: { a: namespaces.a },
24002421
})
2401-
.ele(
2402-
"@a",
2403-
"xfrm",
2404-
)
2422+
.ele("@a", "xfrm")
24052423

24062424
const offsetFragment = buildOffset()
24072425
graphicFrameTransformFragment.import(offsetFragment)
24082426
const extentsFragment = buildExtents(attributes)
2409-
graphicFrameTransformFragment.import(extentsFragment)
2427+
if (extentsFragment) {
2428+
graphicFrameTransformFragment.import(extentsFragment)
2429+
}
24102430

24112431
graphicFrameTransformFragment.up()
24122432

24132433
return graphicFrameTransformFragment
24142434
}
24152435

2416-
function buildShapeProperties(attributes: { width: number; height: number }) {
2436+
function buildShapeProperties(attributes: { width?: number; height?: number }) {
24172437
const shapeProperties = fragment({ namespaceAlias: { pic: namespaces.pic } })
24182438
.ele("@pic", "spPr")
24192439

@@ -2538,8 +2558,8 @@ function buildPicture(
25382558
fileNameWithExtension,
25392559
description,
25402560
relationshipId,
2541-
width = 0,
2542-
height = 0,
2561+
width,
2562+
height,
25432563
}: Attributes,
25442564
) {
25452565
const pictureFragment = fragment({ namespaceAlias: { pic: namespaces.pic } })
@@ -2624,11 +2644,14 @@ function buildEffectExtentFragment() {
26242644
.up()
26252645
}
26262646

2627-
function buildExtent({ width = 0, height = 0 }) {
2647+
function buildExtent({ width, height }: { width?: number; height?: number }) {
2648+
if (!width && !height) {
2649+
return
2650+
}
26282651
return fragment({ namespaceAlias: { wp: namespaces.wp } })
26292652
.ele("@wp", "extent")
2630-
.att("cx", String(width))
2631-
.att("cy", String(height))
2653+
.att("cx", String(width || ""))
2654+
.att("cy", String(height || ""))
26322655
.up()
26332656
}
26342657

@@ -2684,7 +2707,9 @@ function buildAnchoredDrawing(graphicType: "picture", attributes: Attributes) {
26842707
width: attributes.width,
26852708
height: attributes.height,
26862709
})
2687-
anchoredDrawingFragment.import(extentFragment)
2710+
if (extentFragment) {
2711+
anchoredDrawingFragment.import(extentFragment)
2712+
}
26882713
const effectExtentFragment = buildEffectExtentFragment()
26892714
anchoredDrawingFragment.import(effectExtentFragment)
26902715
const wrapSquareFragment = buildWrapSquare()
@@ -2717,7 +2742,9 @@ function buildInlineDrawing(graphicType: "picture", attributes: Attributes) {
27172742
width: attributes.width,
27182743
height: attributes.height,
27192744
})
2720-
inlineDrawingFragment.import(extentFragment)
2745+
if (extentFragment) {
2746+
inlineDrawingFragment.import(extentFragment)
2747+
}
27212748
const effectExtentFragment = buildEffectExtentFragment()
27222749
inlineDrawingFragment.import(effectExtentFragment)
27232750
const drawingObjectNonVisualPropertiesFragment =

Diff for: src/utils/unit-conversion.ts

+10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
export const pixelRegex = /([\d.]+)px/i
2+
export const emRegex = /([\d.]+)em/i
3+
export const remRegex = /([\d.]+)rem/i
24
export const percentageRegex = /([\d.]+)%/i
35
export const pointRegex = /([\d.]+)pt/i
46
export const cmRegex = /([\d.]+)cm/i
@@ -10,6 +12,14 @@ export function pixelToEMU(pixelValue: number) {
1012
return Math.round(pixelValue * 9525)
1113
}
1214

15+
export function emToEmu(emValue: number) {
16+
return pixelToEMU(emValue * 16)
17+
}
18+
19+
export function remToEmu(remValue: number) {
20+
return pixelToEMU(remValue * 16)
21+
}
22+
1323
export function EMUToPixel(EMUValue: number) {
1424
return Math.round(EMUValue / 9525)
1525
}

Diff for: tests/image-no-extension-document.xml

+4-4
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<w:rPr/>
1919
<w:drawing>
2020
<wp:inline distB="0" distL="0" distR="0" distT="0">
21-
<wp:extent cx="2438400" cy="2438400"/>
21+
<wp:extent cx="609600" cy="609600"/>
2222
<wp:effectExtent b="0" l="0" r="0" t="0"/>
2323
<wp:docPr id="2" name="image-Cdtm5x7SnB0WE0EADv3KO.png"/>
2424
<a:graphic>
@@ -38,7 +38,7 @@
3838
<pic:spPr>
3939
<a:xfrm>
4040
<a:off x="0" y="0"/>
41-
<a:ext cx="2438400" cy="2438400"/>
41+
<a:ext cx="609600" cy="609600"/>
4242
</a:xfrm>
4343
<a:prstGeom prst="rect"/>
4444
</pic:spPr>
@@ -66,7 +66,7 @@
6666
<w:rPr/>
6767
<w:drawing>
6868
<wp:inline distB="0" distL="0" distR="0" distT="0">
69-
<wp:extent cx="2438400" cy="2438400"/>
69+
<wp:extent cx="609600" cy="609600"/>
7070
<wp:effectExtent b="0" l="0" r="0" t="0"/>
7171
<wp:docPr id="4" name="image.png"/>
7272
<a:graphic>
@@ -86,7 +86,7 @@
8686
<pic:spPr>
8787
<a:xfrm>
8888
<a:off x="0" y="0"/>
89-
<a:ext cx="2438400" cy="2438400"/>
89+
<a:ext cx="609600" cy="609600"/>
9090
</a:xfrm>
9191
<a:prstGeom prst="rect"/>
9292
</pic:spPr>

0 commit comments

Comments
 (0)