Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -152,11 +152,15 @@ static Obfuscated obfuscate(byte[] font, UUID uuid) {
* @return the key the first bytes of the font are exclusive-ored against
*/
static byte[] keyOf(UUID uuid) {
String hex = uuid.toString().replace("-", "");
// The GUID's digits read backwards by pair are its sixteen bytes read backwards: the
// low half's least significant byte first. Taken from the bits rather than from the
// printed form, so there is no text to parse.
long most = uuid.getMostSignificantBits();
long least = uuid.getLeastSignificantBits();
byte[] key = new byte[16];
for (int index = 0; index < key.length; index++) {
int at = hex.length() - 2 - index * 2;
key[index] = (byte) Integer.parseInt(hex.substring(at, at + 2), 16);
for (int index = 0; index < 8; index++) {
key[index] = (byte) (least >>> (8 * index));
key[8 + index] = (byte) (most >>> (8 * index));
}
return key;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@
import com.demcha.compose.font.FontName;
import org.apache.poi.util.Units;
import org.apache.poi.xwpf.usermodel.BreakType;
import org.apache.poi.xwpf.usermodel.IRunBody;
import org.apache.poi.xwpf.usermodel.ParagraphAlignment;
import com.demcha.compose.document.node.PageFieldKind;
import com.demcha.compose.document.node.PageFieldNode;
Expand Down Expand Up @@ -1787,7 +1788,7 @@ private static String chipLost(InlineBackground background) {
* unstyled cell holding a chip would come away carrying an empty one.</p>
*/
private java.awt.Color colourUnder(XWPFRun run) {
XWPFParagraph para = run.getParagraph();
XWPFParagraph para = run.getParent() instanceof XWPFParagraph parent ? parent : null;
CTPPr paragraphProperties = para == null || !para.getCTP().isSetPPr()
? null
: para.getCTP().getPPr();
Expand All @@ -1813,17 +1814,13 @@ private java.awt.Color colourUnder(XWPFRun run) {
* identity, which parses as no colour at all and silently flattens against white.</p>
*/
private static java.awt.Color shadingFillOf(CTShd shading) {
// A written RGB comes back as its three bytes. Anything else — Word's "auto", or a
// value this export did not write — is no colour it can composite against.
Object fill = shading == null ? null : shading.getFill();
if (fill == null) {
if (!(fill instanceof byte[] rgb) || rgb.length != 3) {
return null;
}
String hex = fill instanceof byte[] bytes
? java.util.HexFormat.of().formatHex(bytes)
: String.valueOf(fill).trim();
if (!hex.matches("(?i)[0-9a-f]{6}")) {
return null;
}
return new java.awt.Color(Integer.parseInt(hex, 16));
return new java.awt.Color(rgb[0] & 0xFF, rgb[1] & 0xFF, rgb[2] & 0xFF);
}

/**
Expand Down Expand Up @@ -1876,7 +1873,9 @@ private XWPFRun newRun(XWPFParagraph para, DocumentLinkTarget target) {
if (name != null) {
CTHyperlink link = para.getCTP().addNewHyperlink();
link.setAnchor(name);
return new XWPFRun(link.addNewR(), para);
// Through the IRunBody constructor: the XWPFParagraph overload is deprecated,
// and an unqualified paragraph argument would pick it.
return new XWPFRun(link.addNewR(), (IRunBody) para);
}
}
return para.createRun();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ private static long[] margins(XWPFTableCell cell) {
private static long width(CTTblWidth margin) {
return margin == null || margin.getW() == null
? -1
: Long.parseLong(String.valueOf(margin.getW()));
: DocxTwips.of(margin.getW());
}

private static XWPFTableCell firstCell(Consumer<PageFlowBuilder> content) throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -101,10 +101,10 @@ void aNestedTableIsGivenTheWidthOfTheColumnItSitsIn() throws Exception {
.rowCells(DocumentTableCell.text("Breakdown"),
DocumentTableCell.node(innerTable()))));

long column = Long.parseLong(String.valueOf(cell.getTableRow().getTable()
.getCTTbl().getTblGrid().getGridColArray(1).getW()));
long nested = Long.parseLong(String.valueOf(cell.getTables().get(0)
.getCTTbl().getTblPr().getTblW().getW()));
long column = DocxTwips.of(cell.getTableRow().getTable()
.getCTTbl().getTblGrid().getGridColArray(1).getW());
long nested = DocxTwips.of(cell.getTables().get(0)
.getCTTbl().getTblPr().getTblW().getW());

assertThat(cell.getTables().get(0).getCTTbl().getTblPr().getTblW().getType().toString())
.as("stated, not left to Word")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ private static List<Integer> indentsOf(XWPFDocument document) {
* {@code Object} and hands back whichever member matched.</p>
*/
private static int twips(Object measure) {
return Integer.parseInt(String.valueOf(measure));
return (int) DocxTwips.of(measure);
}

private static XWPFDocument export(Consumer<PageFlowBuilder> author) throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ private static XWPFDocument withLayout(Consumer<PageFlowBuilder> content) throws
}

private static long lineTwips(XWPFParagraph paragraph) {
return Long.parseLong(String.valueOf(paragraph.getCTP().getPPr().getSpacing().getLine()));
return DocxTwips.of(paragraph.getCTP().getPPr().getSpacing().getLine());
}

private static String lineRule(XWPFParagraph paragraph) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ void oneParagraphPerItemRegardlessOfLengthBecauseDocxDoesNotWrap() throws Except
* {@code Object} and hands back whichever member matched.</p>
*/
private static int twips(Object measure) {
return Integer.parseInt(String.valueOf(measure));
return (int) DocxTwips.of(measure);
}

/** True when a line begins with an ASCII space or carries a non-breaking one. */
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,17 @@ private static DocumentPageZone zone(DocumentHeaderFooterZone kind, double heigh

private static long footerDistance(DocumentPageZone zone) throws Exception {
CTPageMar margin = marginOf(exportWithLayout(zone));
return margin.getFooter() == null ? -1 : Long.parseLong(String.valueOf(margin.getFooter()));
return margin.getFooter() == null ? -1 : DocxTwips.of(margin.getFooter());
}

private static long headerDistance(DocumentPageZone zone) throws Exception {
CTPageMar margin = marginOf(exportWithLayout(zone));
return margin.getHeader() == null ? -1 : Long.parseLong(String.valueOf(margin.getHeader()));
return margin.getHeader() == null ? -1 : DocxTwips.of(margin.getHeader());
}

private static long footerDistanceWithoutLayout(DocumentPageZone zone) throws Exception {
CTPageMar margin = marginOf(exportWithoutLayout(zone));
return margin.getFooter() == null ? -1 : Long.parseLong(String.valueOf(margin.getFooter()));
return margin.getFooter() == null ? -1 : DocxTwips.of(margin.getFooter());
}

private static CTPageMar marginOf(byte[] docx) throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void weightsAndTheGapDecideTheColumnsAndTheCellMargins() throws Exception {
// column's width and comes back out as that cell's right margin: the text box is
// the slot, and the second column starts exactly where the second slot does.
XWPFTable table = onlyTable(page -> page.addRow(r -> r
.gap(20)
.spacing(20)
.weights(3, 2)
.addParagraph(p -> p.text("Scope"))
.addParagraph(p -> p.text("Period"))));
Expand Down Expand Up @@ -154,7 +154,7 @@ void theMeasuredSplitAgreesWithTheStatedOneWhereBothCanAnswer() throws Exception
// Weights are arithmetic either way, so the two paths have to arrive at the same
// columns — if they ever part, one of them is reading the row wrong.
Consumer<PageFlowBuilder> weighted = page -> page.addRow(r -> r
.gap(20)
.spacing(20)
.weights(3, 2)
.addParagraph(p -> p.text("Scope"))
.addParagraph(p -> p.text("Period")));
Expand Down Expand Up @@ -210,7 +210,7 @@ private static long sum(List<Long> values) {

/** {@code ST_TwipsMeasure} is an xmlbeans union, so the accessor is typed Object. */
private static long twips(Object measure) {
return Long.parseLong(String.valueOf(measure));
return DocxTwips.of(measure);
}

private static int occurrences(String haystack, String needle) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ private static String widthType(XWPFTable table) {

/** {@code ST_TwipsMeasure} is an xmlbeans union, so the accessor is typed Object. */
private static long twips(Object measure) {
return Long.parseLong(String.valueOf(measure));
return DocxTwips.of(measure);
}

/** The table as written with nothing measured behind it. */
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.demcha.compose.document.backend.semantic.docx;

import static org.assertj.core.api.Assertions.assertThat;

/**
* Reads a twip value back out of an exported file.
*
* <p>XmlBeans hands a measure back as the schema's union, and the export only ever writes
* plain twips, which come back as a {@link Number}. Reading one as text and parsing it —
* what these tests used to do, each helper its own copy — works until the value is not a
* number, and then fails as a parse error far from what was wrong. Asserting the type says
* what was wrong.</p>
*
* @author Artem Demchyshyn
*/
final class DocxTwips {

private DocxTwips() {
}

/**
* @param measure a measure read from the file
* @return its value in twips
*/
static long of(Object measure) {
assertThat(measure)
.as("a twip value this export writes as a plain number")
.isInstanceOf(Number.class);
return ((Number) measure).longValue();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -318,15 +318,15 @@ private static long before(XWPFParagraph paragraph) {
if (properties == null || !properties.isSetSpacing() || !properties.getSpacing().isSetBefore()) {
return 0;
}
return Long.parseLong(String.valueOf(properties.getSpacing().getBefore()));
return DocxTwips.of(properties.getSpacing().getBefore());
}

private static long after(XWPFParagraph paragraph) {
CTPPr properties = paragraph.getCTP().getPPr();
if (properties == null || !properties.isSetSpacing() || !properties.getSpacing().isSetAfter()) {
return 0;
}
return Long.parseLong(String.valueOf(properties.getSpacing().getAfter()));
return DocxTwips.of(properties.getSpacing().getAfter());
}

private static List<XWPFParagraph> bodyOf(Consumer<PageFlowBuilder> content) throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ public static DocumentSession mixedTwoPager(Path pdfFile) {

session.chrome().zone(DocumentPageZone.footer(30, page -> new RowBuilder()
.name("FooterZone")
.gap(8)
.spacing(8)
.addParagraph(p -> p.text("Editable export probe").textStyle(CHROME))
.flexSpacer()
.add(page.pageNumber(CHROME))
Expand Down Expand Up @@ -123,7 +123,7 @@ public static DocumentSession mixedTwoPager(Path pdfFile) {

// Two columns of unequal length: the row must keep them side by side and
// must not lose the longer column's tail at a page boundary.
page.addRow("TwoColumns", r -> r.gap(18).columns(weight(3), weight(2))
page.addRow("TwoColumns", r -> r.spacing(18).columns(weight(3), weight(2))
.padding(DocumentInsets.symmetric(14, 0))
.addSection(left -> left
.addParagraph(p -> p.text("Scope").textStyle(HEADING))
Expand Down
Loading