diff options
Diffstat (limited to 'poi-scratchpad/src')
22 files changed, 557 insertions, 460 deletions
diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hdgf/streams/PointerContainingStream.java b/poi-scratchpad/src/main/java/org/apache/poi/hdgf/streams/PointerContainingStream.java index 69964427fa..387cb8580d 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hdgf/streams/PointerContainingStream.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hdgf/streams/PointerContainingStream.java @@ -17,8 +17,6 @@ package org.apache.poi.hdgf.streams; -import org.apache.logging.log4j.Logger; -import org.apache.poi.logging.PoiLogManager; import org.apache.poi.hdgf.chunks.ChunkFactory; import org.apache.poi.hdgf.pointers.Pointer; import org.apache.poi.hdgf.pointers.PointerFactory; @@ -28,8 +26,6 @@ import org.apache.poi.hdgf.pointers.PointerFactory; * other data too. */ public class PointerContainingStream extends Stream { // TODO - instantiable superclass - private static final Logger LOG = PoiLogManager.getLogger(PointerContainingStream.class); - private static int MAX_CHILDREN_NESTING = 500; private final Pointer[] childPointers; @@ -68,9 +64,9 @@ public class PointerContainingStream extends Stream { // TODO - instantiable sup } private void findChildren(byte[] documentData, int nesting) { - if (nesting > MAX_CHILDREN_NESTING) { + if (nesting > getMaxChildrenNesting()) { throw new IllegalArgumentException("Encountered too deep nesting, cannot process stream " + - "with more than " + MAX_CHILDREN_NESTING + " nested children. " + + "with more than " + getMaxChildrenNesting() + " nested children. " + "Some data could not be parsed. You can call setMaxChildrenNesting() to adjust " + "this limit."); } diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hmef/attribute/MAPIDateAttribute.java b/poi-scratchpad/src/main/java/org/apache/poi/hmef/attribute/MAPIDateAttribute.java index c267bd82ed..00f92545f8 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hmef/attribute/MAPIDateAttribute.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hmef/attribute/MAPIDateAttribute.java @@ -70,7 +70,7 @@ public final class MAPIDateAttribute extends MAPIAttribute { } /** - * Returns the Date of a Attribute, converting as appropriate + * Returns the Date of an Attribute, converting as appropriate */ public static Date getAsDate(MAPIAttribute attr) { if(attr == null) { diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hmef/attribute/MAPIStringAttribute.java b/poi-scratchpad/src/main/java/org/apache/poi/hmef/attribute/MAPIStringAttribute.java index c30ec513cb..9e3d6d0cb9 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hmef/attribute/MAPIStringAttribute.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hmef/attribute/MAPIStringAttribute.java @@ -64,7 +64,7 @@ public final class MAPIStringAttribute extends MAPIAttribute { } /** - * Returns the string of a Attribute, converting as appropriate + * Returns the string of an Attribute, converting as appropriate */ public static String getAsString(MAPIAttribute attr) { if(attr == null) { diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hmef/attribute/TNEFDateAttribute.java b/poi-scratchpad/src/main/java/org/apache/poi/hmef/attribute/TNEFDateAttribute.java index ea6382b461..7c27f76fbe 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hmef/attribute/TNEFDateAttribute.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hmef/attribute/TNEFDateAttribute.java @@ -85,7 +85,7 @@ public final class TNEFDateAttribute extends TNEFAttribute { } /** - * Returns the Date of a Attribute, converting as appropriate + * Returns the Date of an Attribute, converting as appropriate */ public static Date getAsDate(TNEFAttribute attr) { if(attr == null) { diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hmef/attribute/TNEFStringAttribute.java b/poi-scratchpad/src/main/java/org/apache/poi/hmef/attribute/TNEFStringAttribute.java index c403754edb..99c4cf4412 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hmef/attribute/TNEFStringAttribute.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hmef/attribute/TNEFStringAttribute.java @@ -68,7 +68,7 @@ public final class TNEFStringAttribute extends TNEFAttribute { } /** - * Returns the string of a Attribute, converting as appropriate + * Returns the string of an Attribute, converting as appropriate */ public static String getAsString(TNEFAttribute attr) { if(attr == null) { diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hmef/extractor/HMEFContentsExtractor.java b/poi-scratchpad/src/main/java/org/apache/poi/hmef/extractor/HMEFContentsExtractor.java index 59cbe79e91..8e01252c64 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hmef/extractor/HMEFContentsExtractor.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hmef/extractor/HMEFContentsExtractor.java @@ -141,10 +141,10 @@ public final class HMEFContentsExtractor { // Decide what to call it String filename = att.getLongFilename(); - if(filename == null || filename.length() == 0) { + if(filename == null || filename.isEmpty()) { filename = att.getFilename(); } - if(filename == null || filename.length() == 0) { + if(filename == null || filename.isEmpty()) { filename = "attachment" + count; if(att.getExtension() != null) { filename += att.getExtension(); diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFFill.java b/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFFill.java index 3f9f84b6d6..3a8c767e6d 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFFill.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFFill.java @@ -576,9 +576,7 @@ public final class HSLFFill { } else { EscherBSERecord bse = (EscherBSERecord) bstore.getChild(idx - 1); for (HSLFPictureData pd : pict) { - - // Reference equals is safe because these BSE belong to the same slideshow - if (pd.bse == bse) { + if (pd.getOffset() == bse.getOffset()) { return pd; } } diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFPictureShape.java b/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFPictureShape.java index 71e67084e1..e10a54cb55 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFPictureShape.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFPictureShape.java @@ -124,9 +124,7 @@ public class HSLFPictureShape extends HSLFSimpleShape implements PictureShape<HS LOG.atError().log("no reference to picture data found "); } else { for (HSLFPictureData pd : pict) { - - // Reference equals is safe because these BSE belong to the same slideshow - if (pd.bse == bse) { + if (pd.getOffset() == bse.getOffset()) { return pd; } } diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFShapePlaceholderDetails.java b/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFShapePlaceholderDetails.java index 8a467dfedc..348d901235 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFShapePlaceholderDetails.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFShapePlaceholderDetails.java @@ -47,6 +47,68 @@ import org.apache.poi.util.LocaleUtil; * @since POI 4.0.0 */ public class HSLFShapePlaceholderDetails extends HSLFPlaceholderDetails { + + static void updateSPRecord(final HSLFSimpleShape shape, final Placeholder placeholder) { + final EscherSpRecord spRecord = shape.getEscherChild(EscherSpRecord.RECORD_ID); + int flags = spRecord.getFlags(); + if (placeholder == null) { + flags ^= EscherSpRecord.FLAG_HAVEMASTER; + } else { + flags |= EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HAVEMASTER; + } + spRecord.setFlags(flags); + + // Placeholders can't be grouped + shape.setEscherProperty(EscherPropertyTypes.PROTECTION__LOCKAGAINSTGROUPING, (placeholder == null ? -1 : 262144)); + } + + static void removePlaceholder(final HSLFSimpleShape shape) { + final HSLFEscherClientDataRecord clientData = shape.getClientData(false); + if (clientData != null) { + clientData.removeChild(OEPlaceholderAtom.class); + clientData.removeChild(RoundTripHFPlaceholder12.class); + // remove client data if the placeholder was the only child to be carried + if (clientData.getChildRecords().isEmpty()) { + shape.getSpContainer().removeChildRecord(clientData); + } + } + } + + static OEPlaceholderAtom createOEPlaceholderAtom(final HSLFEscherClientDataRecord clientData) { + return createOEPlaceholderAtom(clientData, (byte) 0); + } + + static OEPlaceholderAtom createOEPlaceholderAtom(final HSLFEscherClientDataRecord clientData, + final byte placeholderId) { + OEPlaceholderAtom oePlaceholderAtom = new OEPlaceholderAtom(); + oePlaceholderAtom.setPlaceholderSize((byte)OEPlaceholderAtom.PLACEHOLDER_FULLSIZE); + // TODO: placement id only "SHOULD" be unique ... check other placeholders on sheet for unique id + oePlaceholderAtom.setPlacementId(-1); + oePlaceholderAtom.setPlaceholderId(placeholderId); + clientData.addChild(oePlaceholderAtom); + return oePlaceholderAtom; + } + + static byte getPlaceholderId(final HSLFSheet sheet, final Placeholder placeholder) { + if (placeholder == null) { + return 0; + } + byte phId; + // TODO: implement/switch NotesMaster + if (sheet instanceof HSLFSlideMaster) { + phId = (byte) placeholder.nativeSlideMasterId; + } else if (sheet instanceof HSLFNotes) { + phId = (byte) placeholder.nativeNotesId; + } else { + phId = (byte) placeholder.nativeSlideId; + } + + if (phId == -2) { + throw new HSLFException("Placeholder " + placeholder.name() + " not supported for this sheet type (" + sheet.getClass() + ")"); + } + return phId; + } + private enum PlaceholderContainer { slide, master, notes, notesMaster } @@ -78,7 +140,7 @@ public class HSLFShapePlaceholderDetails extends HSLFPlaceholderDetails { @Override public Placeholder getPlaceholder() { - updatePlaceholderAtom(false); + updatePlaceholderAtom(null, false); final int phId; if (oePlaceholderAtom != null) { phId = oePlaceholderAtom.getPlaceholderId(); @@ -105,17 +167,7 @@ public class HSLFShapePlaceholderDetails extends HSLFPlaceholderDetails { @Override public void setPlaceholder(final Placeholder placeholder) { - final EscherSpRecord spRecord = shape.getEscherChild(EscherSpRecord.RECORD_ID); - int flags = spRecord.getFlags(); - if (placeholder == null) { - flags ^= EscherSpRecord.FLAG_HAVEMASTER; - } else { - flags |= EscherSpRecord.FLAG_HAVEANCHOR | EscherSpRecord.FLAG_HAVEMASTER; - } - spRecord.setFlags(flags); - - // Placeholders can't be grouped - shape.setEscherProperty(EscherPropertyTypes.PROTECTION__LOCKAGAINSTGROUPING, (placeholder == null ? -1 : 262144)); + updateSPRecord(shape, placeholder); if (placeholder == null) { removePlaceholder(); @@ -123,7 +175,7 @@ public class HSLFShapePlaceholderDetails extends HSLFPlaceholderDetails { } // init client data - updatePlaceholderAtom(true); + updatePlaceholderAtom(placeholder, true); final byte phId = getPlaceholderId(placeholder); oePlaceholderAtom.setPlaceholderId(phId); @@ -158,7 +210,7 @@ public class HSLFShapePlaceholderDetails extends HSLFPlaceholderDetails { if (ph == null || size == null) { return; } - updatePlaceholderAtom(true); + updatePlaceholderAtom(ph, true); final byte ph_size; switch (size) { @@ -209,20 +261,12 @@ public class HSLFShapePlaceholderDetails extends HSLFPlaceholderDetails { } private void removePlaceholder() { - final HSLFEscherClientDataRecord clientData = shape.getClientData(false); - if (clientData != null) { - clientData.removeChild(OEPlaceholderAtom.class); - clientData.removeChild(RoundTripHFPlaceholder12.class); - // remove client data if the placeholder was the only child to be carried - if (clientData.getChildRecords().isEmpty()) { - shape.getSpContainer().removeChildRecord(clientData); - } - } + removePlaceholder(shape); oePlaceholderAtom = null; roundTripHFPlaceholder12 = null; } - private void updatePlaceholderAtom(final boolean create) { + private void updatePlaceholderAtom(final Placeholder placeholder, final boolean create) { localDateTime = null; if (shape instanceof HSLFTextBox) { EscherTextboxWrapper txtBox = ((HSLFTextBox)shape).getEscherTextboxWrapper(); @@ -255,11 +299,8 @@ public class HSLFShapePlaceholderDetails extends HSLFPlaceholderDetails { } if (oePlaceholderAtom == null) { - oePlaceholderAtom = new OEPlaceholderAtom(); - oePlaceholderAtom.setPlaceholderSize((byte)OEPlaceholderAtom.PLACEHOLDER_FULLSIZE); - // TODO: placement id only "SHOULD" be unique ... check other placeholders on sheet for unique id - oePlaceholderAtom.setPlacementId(-1); - clientData.addChild(oePlaceholderAtom); + final byte phId = getPlaceholderId(shape.getSheet(), placeholder); + oePlaceholderAtom = createOEPlaceholderAtom(clientData, phId); } if (roundTripHFPlaceholder12 == null) { roundTripHFPlaceholder12 = new RoundTripHFPlaceholder12(); diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java b/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java index da930b6899..aa85a65a92 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hslf/usermodel/HSLFSimpleShape.java @@ -20,6 +20,9 @@ package org.apache.poi.hslf.usermodel; import java.awt.Color; import org.apache.logging.log4j.Logger; +import org.apache.poi.hslf.record.HSLFEscherClientDataRecord; +import org.apache.poi.hslf.record.OEPlaceholderAtom; +import org.apache.poi.hslf.record.RoundTripHFPlaceholder12; import org.apache.poi.logging.PoiLogManager; import org.apache.poi.ddf.AbstractEscherOptRecord; import org.apache.poi.ddf.EscherChildAnchorRecord; @@ -53,6 +56,11 @@ import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; import org.apache.poi.util.LittleEndian; import org.apache.poi.util.Units; +import static org.apache.poi.hslf.usermodel.HSLFShapePlaceholderDetails.createOEPlaceholderAtom; +import static org.apache.poi.hslf.usermodel.HSLFShapePlaceholderDetails.getPlaceholderId; +import static org.apache.poi.hslf.usermodel.HSLFShapePlaceholderDetails.removePlaceholder; +import static org.apache.poi.hslf.usermodel.HSLFShapePlaceholderDetails.updateSPRecord; + /** * An abstract simple (non-group) shape. * This is the parent class for all primitive shapes like Line, Rectangle, etc. @@ -80,6 +88,8 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H */ protected HSLFHyperlink _hyperlink; + protected HSLFShapePlaceholderDetails _placeholderDetails; + /** * Create a SimpleShape object and initialize it from the supplied Record container. * @@ -564,10 +574,12 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H @Override public HSLFShapePlaceholderDetails getPlaceholderDetails() { - return new HSLFShapePlaceholderDetails(this); + if (_placeholderDetails == null) { + _placeholderDetails = new HSLFShapePlaceholderDetails(this); + } + return _placeholderDetails; } - @Override public Placeholder getPlaceholder() { return getPlaceholderDetails().getPlaceholder(); @@ -575,9 +587,62 @@ public abstract class HSLFSimpleShape extends HSLFShape implements SimpleShape<H @Override public void setPlaceholder(Placeholder placeholder) { - getPlaceholderDetails().setPlaceholder(placeholder); - } + // reset the placeholder details so that the next call to getPlaceholderDetails() will reinitialize it + _placeholderDetails = null; + updateSPRecord(this, placeholder); + if (placeholder == null) { + removePlaceholder(this); + return; + } + + HSLFEscherClientDataRecord clientData = getClientData(true); + + // OEPlaceholderAtom tells powerpoint that this shape is a placeholder + OEPlaceholderAtom oep = null; + RoundTripHFPlaceholder12 rtp = null; + for (org.apache.poi.hslf.record.Record r : clientData.getHSLFChildRecords()) { + if (r instanceof OEPlaceholderAtom) { + oep = (OEPlaceholderAtom) r; + break; + } + if (r instanceof RoundTripHFPlaceholder12) { + rtp = (RoundTripHFPlaceholder12) r; + break; + } + } + + /** + * Extract from MSDN: + * + * There is a special case when the placeholder does not have a position in the layout. + * This occurs when the user has moved the placeholder from its original position. + * In this case the placeholder ID is -1. + */ + final byte phId = getPlaceholderId(getSheet(), placeholder); + + switch (placeholder) { + case HEADER: + case FOOTER: + if (rtp == null) { + rtp = new RoundTripHFPlaceholder12(); + rtp.setPlaceholderId(phId); + clientData.addChild(rtp); + } + if (oep != null) { + clientData.removeChild(OEPlaceholderAtom.class); + } + break; + default: + if (rtp != null) { + clientData.removeChild(RoundTripHFPlaceholder12.class); + } + if (oep == null) { + oep = createOEPlaceholderAtom(clientData, phId); + } + break; + } + } @Override public void setStrokeStyle(Object... styles) { diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hsmf/extractor/OutlookTextExtractor.java b/poi-scratchpad/src/main/java/org/apache/poi/hsmf/extractor/OutlookTextExtractor.java index 62b09b374e..e87185ec93 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hsmf/extractor/OutlookTextExtractor.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hsmf/extractor/OutlookTextExtractor.java @@ -177,7 +177,7 @@ public class OutlookTextExtractor implements POIOLE2TextExtractor { * {@code "Nick <nick@example.com>; Jim <jim@example.com>"} */ protected void handleEmails(StringBuilder s, String type, String displayText, Iterator<String> emails) { - if (displayText == null || displayText.length() == 0) { + if (displayText == null || displayText.isEmpty()) { return; } diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hssf/converter/AbstractExcelUtils.java b/poi-scratchpad/src/main/java/org/apache/poi/hssf/converter/AbstractExcelUtils.java index 88498ea39e..3485f40911 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hssf/converter/AbstractExcelUtils.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hssf/converter/AbstractExcelUtils.java @@ -174,7 +174,7 @@ class AbstractExcelUtils { } static boolean isEmpty(String str) { - return str == null || str.length() == 0; + return str == null || str.isEmpty(); } static boolean isNotEmpty(String str) { diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/AbstractWordConverter.java b/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/AbstractWordConverter.java index aefe15d9da..0eca5fb49a 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/AbstractWordConverter.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/AbstractWordConverter.java @@ -310,8 +310,7 @@ public abstract class AbstractWordConverter { continue; } String text = characterRun.text(); - if (text == null || text.length() == 0 - || text.charAt(0) != FIELD_BEGIN_MARK) { + if (text == null || text.isEmpty() || text.charAt(0) != FIELD_BEGIN_MARK) { continue; } diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/AbstractWordUtils.java b/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/AbstractWordUtils.java index 9ef569fc6b..b2bd30f808 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/AbstractWordUtils.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/AbstractWordUtils.java @@ -417,7 +417,7 @@ public class AbstractWordUtils { static boolean isEmpty( String str ) { - return str == null || str.length() == 0; + return str == null || str.isEmpty(); } static boolean isNotEmpty( String str ) diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/DefaultFontReplacer.java b/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/DefaultFontReplacer.java index b9845fd348..2df337e1d3 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/DefaultFontReplacer.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hwpf/converter/DefaultFontReplacer.java @@ -87,7 +87,7 @@ public class DefaultFontReplacer implements FontReplacer private static boolean isEmpty( String str ) { - return str == null || str.length() == 0; + return str == null || str.isEmpty(); } private static boolean isNotEmpty( String str ) diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hwpf/extractor/WordExtractor.java b/poi-scratchpad/src/main/java/org/apache/poi/hwpf/extractor/WordExtractor.java index 880c4e2d38..06c4a202ae 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hwpf/extractor/WordExtractor.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hwpf/extractor/WordExtractor.java @@ -139,7 +139,7 @@ public final class WordExtractor implements POIOLE2TextExtractor { * Add the header/footer text, if it's not empty */ private void appendHeaderFooter( String text, StringBuilder out ) { - if ( text == null || text.length() == 0 ) + if ( text == null || text.isEmpty()) return; text = text.replace( '\r', '\n' ); diff --git a/poi-scratchpad/src/main/java/org/apache/poi/hwpf/sprm/ParagraphSprmUncompressor.java b/poi-scratchpad/src/main/java/org/apache/poi/hwpf/sprm/ParagraphSprmUncompressor.java index 9ee25a7fb0..da16b69ce7 100644 --- a/poi-scratchpad/src/main/java/org/apache/poi/hwpf/sprm/ParagraphSprmUncompressor.java +++ b/poi-scratchpad/src/main/java/org/apache/poi/hwpf/sprm/ParagraphSprmUncompressor.java @@ -46,423 +46,400 @@ public final class ParagraphSprmUncompressor extends SprmUncompressor { private static final Logger LOG = PoiLogManager.getLogger(ParagraphSprmUncompressor.class); - public ParagraphSprmUncompressor() - { - } + public ParagraphSprmUncompressor() { + } - public static ParagraphProperties uncompressPAP(ParagraphProperties parent, - byte[] grpprl, - int offset) - { - ParagraphProperties newProperties = parent.copy(); - SprmIterator sprmIt = new SprmIterator(grpprl, offset); + public static ParagraphProperties uncompressPAP(ParagraphProperties parent, + byte[] grpprl, + int offset) { + ParagraphProperties newProperties = parent.copy(); + SprmIterator sprmIt = new SprmIterator(grpprl, offset); - while (sprmIt.hasNext()) - { - SprmOperation sprm = sprmIt.next(); + while (sprmIt.hasNext()) { + SprmOperation sprm = sprmIt.next(); - // PAPXs can contain table sprms if the paragraph marks the end of a - // table row - if (sprm.getType() == SprmOperation.TYPE_PAP) - { - try - { - unCompressPAPOperation( newProperties, sprm ); - } - catch ( Exception exc ) - { - LOG.atError().withThrowable(exc).log("Unable to apply SPRM operation '{}'", box(sprm.getOperation())); - } - } - } + // PAPXs can contain table sprms if the paragraph marks the end of a + // table row + if (sprm.getType() == SprmOperation.TYPE_PAP) { + try { + unCompressPAPOperation(newProperties, sprm); + } catch (Exception exc) { + LOG.atError().withThrowable(exc).log("Unable to apply SPRM operation '{}'", box(sprm.getOperation())); + } + } + } - return newProperties; - } + return newProperties; + } - /** - * Performs an operation on a ParagraphProperties object. Used to uncompress - * from a papx. - * - * @param newPAP The ParagraphProperties object to perform the operation on. - * @param sprm sn SPRM operation. - */ - static void unCompressPAPOperation (ParagraphProperties newPAP, SprmOperation sprm) - { - switch (sprm.getOperation()) - { - case 0: - newPAP.setIstd (sprm.getOperand()); - break; - case 0x1: + /** + * Performs an operation on a ParagraphProperties object. Used to uncompress + * from a papx. + * + * @param newPAP The ParagraphProperties object to perform the operation on. + * @param sprm sn SPRM operation. + */ + static void unCompressPAPOperation(ParagraphProperties newPAP, SprmOperation sprm) { + switch (sprm.getOperation()) { + case 0: + newPAP.setIstd(sprm.getOperand()); + break; + case 0x1: - // Used only for piece table grpprl's not for PAPX + // Used only for piece table grpprl's not for PAPX // int istdFirst = LittleEndian.getShort (varParam, 2); // int istdLast = LittleEndian.getShort (varParam, 4); // if ((newPAP.getIstd () > istdFirst) || (newPAP.getIstd () <= istdLast)) // { // permuteIstd (newPAP, varParam, opSize); // } - break; - case 0x2: - if (newPAP.getIstd () <= 9 || newPAP.getIstd () >= 1) - { - byte paramTmp = (byte) sprm.getOperand(); - newPAP.setIstd (newPAP.getIstd () + paramTmp); - newPAP.setLvl ((byte) (newPAP.getLvl () + paramTmp)); + break; + case 0x2: + if (newPAP.getIstd() <= 9 || newPAP.getIstd() >= 1) { + byte paramTmp = (byte) sprm.getOperand(); + newPAP.setIstd(newPAP.getIstd() + paramTmp); + newPAP.setLvl((byte) (newPAP.getLvl() + paramTmp)); - if (((paramTmp >> 7) & 0x01) == 1) - { - newPAP.setIstd (Math.max (newPAP.getIstd (), 1)); - } - else - { - newPAP.setIstd (Math.min (newPAP.getIstd (), 9)); - } + if (((paramTmp >> 7) & 0x01) == 1) { + newPAP.setIstd(Math.max(newPAP.getIstd(), 1)); + } else { + newPAP.setIstd(Math.min(newPAP.getIstd(), 9)); + } - } - break; - case 0x3: - // Physical justification of the paragraph - newPAP.setJc ((byte) sprm.getOperand()); - break; - case 0x4: - newPAP.setFSideBySide (sprm.getOperand() != 0); - break; - case 0x5: - newPAP.setFKeep (sprm.getOperand() != 0); - break; - case 0x6: - newPAP.setFKeepFollow (sprm.getOperand() != 0); - break; - case 0x7: - newPAP.setFPageBreakBefore (sprm.getOperand() != 0); - break; - case 0x8: - newPAP.setBrcl ((byte) sprm.getOperand()); - break; - case 0x9: - newPAP.setBrcp ((byte) sprm.getOperand()); - break; - case 0xa: - newPAP.setIlvl ((byte) sprm.getOperand()); - break; - case 0xb: - /* sprmPIlfo -- 0x460B */ - newPAP.setIlfo( sprm.getOperandShortSigned() ); - break; - case 0xc: - newPAP.setFNoLnn (sprm.getOperand() != 0); - break; - case 0xd: - // handle tabs . variable parameter. seperate processing needed - handleTabs(newPAP, sprm); - break; - case 0xe: - newPAP.setDxaRight (sprm.getOperand()); - break; - case 0xf: - newPAP.setDxaLeft (sprm.getOperand()); - break; - case 0x10: + } + break; + case 0x3: + // Physical justification of the paragraph + newPAP.setJc((byte) sprm.getOperand()); + break; + case 0x4: + newPAP.setFSideBySide(sprm.getOperand() != 0); + break; + case 0x5: + newPAP.setFKeep(sprm.getOperand() != 0); + break; + case 0x6: + newPAP.setFKeepFollow(sprm.getOperand() != 0); + break; + case 0x7: + newPAP.setFPageBreakBefore(sprm.getOperand() != 0); + break; + case 0x8: + newPAP.setBrcl((byte) sprm.getOperand()); + break; + case 0x9: + newPAP.setBrcp((byte) sprm.getOperand()); + break; + case 0xa: + newPAP.setIlvl((byte) sprm.getOperand()); + break; + case 0xb: + /* sprmPIlfo -- 0x460B */ + newPAP.setIlfo(sprm.getOperandShortSigned()); + break; + case 0xc: + newPAP.setFNoLnn(sprm.getOperand() != 0); + break; + case 0xd: + // handle tabs . variable parameter. separate processing needed + handleTabs(newPAP, sprm); + break; + case 0xe: + newPAP.setDxaRight(sprm.getOperand()); + break; + case 0xf: + newPAP.setDxaLeft(sprm.getOperand()); + break; + case 0x10: - // sprmPNest is only stored in grpprls linked to a piece table. - newPAP.setDxaLeft (newPAP.getDxaLeft () + sprm.getOperand()); - newPAP.setDxaLeft (Math.max (0, newPAP.getDxaLeft ())); - break; - case 0x11: - newPAP.setDxaLeft1 (sprm.getOperand()); - break; - case 0x12: - newPAP.setLspd(new LineSpacingDescriptor(sprm.getGrpprl(), sprm.getGrpprlOffset())); - break; - case 0x13: - newPAP.setDyaBefore (sprm.getOperand()); - break; - case 0x14: - newPAP.setDyaAfter (sprm.getOperand()); - break; - case 0x15: - // fast saved only - //applySprmPChgTabs (newPAP, varParam, opSize); - break; - case 0x16: - // sprmPFInTable -- 0x2416 - newPAP.setFInTable( sprm.getOperand() != 0); - break; - case 0x17: - newPAP.setFTtp ( sprm.getOperand() != 0); - break; - case 0x18: - newPAP.setDxaAbs (sprm.getOperand()); - break; - case 0x19: - newPAP.setDyaAbs (sprm.getOperand()); - break; - case 0x1a: - newPAP.setDxaWidth (sprm.getOperand()); - break; - case 0x1b: - byte param = (byte)sprm.getOperand(); - // TODO: handle paragraph postioning - byte pcVert = (byte) ((param & 0x0c) >> 2); - byte pcHorz = (byte) (param & 0x03); - if (pcVert != 3) - { - newPAP.setPcVert (pcVert); - } - if (pcHorz != 3) - { - newPAP.setPcHorz (pcHorz); - } - break; + // sprmPNest is only stored in grpprls linked to a piece table. + newPAP.setDxaLeft(newPAP.getDxaLeft() + sprm.getOperand()); + newPAP.setDxaLeft(Math.max(0, newPAP.getDxaLeft())); + break; + case 0x11: + newPAP.setDxaLeft1(sprm.getOperand()); + break; + case 0x12: + newPAP.setLspd(new LineSpacingDescriptor(sprm.getGrpprl(), sprm.getGrpprlOffset())); + break; + case 0x13: + newPAP.setDyaBefore(sprm.getOperand()); + break; + case 0x14: + newPAP.setDyaAfter(sprm.getOperand()); + break; + case 0x15: + // fast saved only + //applySprmPChgTabs (newPAP, varParam, opSize); + break; + case 0x16: + // sprmPFInTable -- 0x2416 + newPAP.setFInTable(sprm.getOperand() != 0); + break; + case 0x17: + newPAP.setFTtp(sprm.getOperand() != 0); + break; + case 0x18: + newPAP.setDxaAbs(sprm.getOperand()); + break; + case 0x19: + newPAP.setDyaAbs(sprm.getOperand()); + break; + case 0x1a: + newPAP.setDxaWidth(sprm.getOperand()); + break; + case 0x1b: + byte param = (byte) sprm.getOperand(); + // TODO: handle paragraph postioning + byte pcVert = (byte) ((param & 0x0c) >> 2); + byte pcHorz = (byte) (param & 0x03); + if (pcVert != 3) { + newPAP.setPcVert(pcVert); + } + if (pcHorz != 3) { + newPAP.setPcHorz(pcHorz); + } + break; - // BrcXXX1 is older Version. Brc is used - // case 0x1c: - // newPAP.setBrcTop1((short)param); - // break; - // case 0x1d: - // newPAP.setBrcLeft1((short)param); - // break; - // case 0x1e: - // newPAP.setBrcBottom1((short)param); - // break; - // case 0x1f: - // newPAP.setBrcRight1((short)param); - // break; - // case 0x20: - // newPAP.setBrcBetween1((short)param); - // break; - // case 0x21: - // newPAP.setBrcBar1((byte)param); - // break; + // BrcXXX1 is older Version. Brc is used + // case 0x1c: + // newPAP.setBrcTop1((short)param); + // break; + // case 0x1d: + // newPAP.setBrcLeft1((short)param); + // break; + // case 0x1e: + // newPAP.setBrcBottom1((short)param); + // break; + // case 0x1f: + // newPAP.setBrcRight1((short)param); + // break; + // case 0x20: + // newPAP.setBrcBetween1((short)param); + // break; + // case 0x21: + // newPAP.setBrcBar1((byte)param); + // break; - case 0x22: - newPAP.setDxaFromText (sprm.getOperand()); - break; - case 0x23: - newPAP.setWr((byte)sprm.getOperand()); - break; - case 0x24: - newPAP.setBrcTop(new BorderCode(sprm.getGrpprl(), sprm.getGrpprlOffset())); - break; - case 0x25: - newPAP.setBrcLeft(new BorderCode(sprm.getGrpprl(), sprm.getGrpprlOffset())); - break; - case 0x26: - newPAP.setBrcBottom (new BorderCode(sprm.getGrpprl(), sprm.getGrpprlOffset())); - break; - case 0x27: - newPAP.setBrcRight (new BorderCode(sprm.getGrpprl(), sprm.getGrpprlOffset())); - break; - case 0x28: - newPAP.setBrcBetween (new BorderCode(sprm.getGrpprl(), sprm.getGrpprlOffset())); - break; - case 0x29: - newPAP.setBrcBar (new BorderCode(sprm.getGrpprl(), sprm.getGrpprlOffset())); - break; - case 0x2a: - newPAP.setFNoAutoHyph (sprm.getOperand() != 0); - break; - case 0x2b: - newPAP.setDyaHeight (sprm.getOperand()); - break; - case 0x2c: - newPAP.setDcs (new DropCapSpecifier((short)sprm.getOperand())); - break; - case 0x2d: - newPAP.setShd( new ShadingDescriptor80( (short) sprm.getOperand() ) - .toShadingDescriptor() ); + case 0x22: + newPAP.setDxaFromText(sprm.getOperand()); + break; + case 0x23: + newPAP.setWr((byte) sprm.getOperand()); + break; + case 0x24: + newPAP.setBrcTop(new BorderCode(sprm.getGrpprl(), sprm.getGrpprlOffset())); + break; + case 0x25: + newPAP.setBrcLeft(new BorderCode(sprm.getGrpprl(), sprm.getGrpprlOffset())); + break; + case 0x26: + newPAP.setBrcBottom(new BorderCode(sprm.getGrpprl(), sprm.getGrpprlOffset())); + break; + case 0x27: + newPAP.setBrcRight(new BorderCode(sprm.getGrpprl(), sprm.getGrpprlOffset())); + break; + case 0x28: + newPAP.setBrcBetween(new BorderCode(sprm.getGrpprl(), sprm.getGrpprlOffset())); + break; + case 0x29: + newPAP.setBrcBar(new BorderCode(sprm.getGrpprl(), sprm.getGrpprlOffset())); + break; + case 0x2a: + newPAP.setFNoAutoHyph(sprm.getOperand() != 0); + break; + case 0x2b: + newPAP.setDyaHeight(sprm.getOperand()); + break; + case 0x2c: + newPAP.setDcs(new DropCapSpecifier((short) sprm.getOperand())); + break; + case 0x2d: + newPAP.setShd(new ShadingDescriptor80((short) sprm.getOperand()) + .toShadingDescriptor()); + break; + case 0x2e: + newPAP.setDyaFromText(sprm.getOperand()); + break; + case 0x2f: + newPAP.setDxaFromText(sprm.getOperand()); + break; + case 0x30: + newPAP.setFLocked(sprm.getOperand() != 0); + break; + case 0x31: + newPAP.setFWidowControl(sprm.getOperand() != 0); + break; + case 0x33: + newPAP.setFKinsoku(sprm.getOperand() != 0); + break; + case 0x34: + newPAP.setFWordWrap(sprm.getOperand() != 0); + break; + case 0x35: + newPAP.setFOverflowPunct(sprm.getOperand() != 0); + break; + case 0x36: + newPAP.setFTopLinePunct(sprm.getOperand() != 0); + break; + case 0x37: + newPAP.setFAutoSpaceDE(sprm.getOperand() != 0); + break; + case 0x38: + newPAP.setFAutoSpaceDN(sprm.getOperand() != 0); + break; + case 0x39: + newPAP.setWAlignFont(sprm.getOperand()); + break; + case 0x3a: + newPAP.setFontAlign((short) sprm.getOperand()); + break; + case 0x3b: + //obsolete + break; + case 0x3e: { + // TODO: REMOVEME + byte[] buf = Arrays.copyOfRange(sprm.getGrpprl(), sprm.getGrpprlOffset(), sprm.getGrpprlOffset() + (sprm.size() - 3)); + newPAP.setAnld(buf); + break; + } + case 0x3f: + //don't really need this. spec is confusing regarding this + //sprm + byte[] varParam = sprm.getGrpprl(); + int offset = sprm.getGrpprlOffset(); + newPAP.setFPropRMark(varParam[offset] != 0); + newPAP.setIbstPropRMark(LittleEndian.getShort(varParam, offset + 1)); + newPAP.setDttmPropRMark(new DateAndTime(varParam, offset + 3)); + break; + case 0x40: + // This condition commented out, as Word seems to set outline levels even for + // paragraph with other styles than Heading 1..9, even though specification + // does not say so. See bug 49820 for discussion. + //if (newPAP.getIstd () < 1 && newPAP.getIstd () > 9) + { + newPAP.setLvl((byte) sprm.getOperand()); + } break; - case 0x2e: - newPAP.setDyaFromText (sprm.getOperand()); - break; - case 0x2f: - newPAP.setDxaFromText (sprm.getOperand()); - break; - case 0x30: - newPAP.setFLocked (sprm.getOperand() != 0); - break; - case 0x31: - newPAP.setFWidowControl (sprm.getOperand() != 0); - break; - case 0x33: - newPAP.setFKinsoku (sprm.getOperand() != 0); - break; - case 0x34: - newPAP.setFWordWrap (sprm.getOperand() != 0); - break; - case 0x35: - newPAP.setFOverflowPunct (sprm.getOperand() != 0); - break; - case 0x36: - newPAP.setFTopLinePunct (sprm.getOperand() != 0); - break; - case 0x37: - newPAP.setFAutoSpaceDE (sprm.getOperand() != 0); - break; - case 0x38: - newPAP.setFAutoSpaceDN (sprm.getOperand() != 0); - break; - case 0x39: - newPAP.setWAlignFont (sprm.getOperand()); - break; - case 0x3a: - newPAP.setFontAlign ((short) sprm.getOperand()); - break; - case 0x3b: - //obsolete - break; - case 0x3e: { - // TODO: REMOVEME - byte[] buf = Arrays.copyOfRange(sprm.getGrpprl(), sprm.getGrpprlOffset(), sprm.getGrpprlOffset() + (sprm.size() - 3)); - newPAP.setAnld(buf); - break; - } - case 0x3f: - //don't really need this. spec is confusing regarding this - //sprm - byte[] varParam = sprm.getGrpprl(); - int offset = sprm.getGrpprlOffset(); - newPAP.setFPropRMark (varParam[offset] != 0 ); - newPAP.setIbstPropRMark (LittleEndian.getShort (varParam, offset + 1)); - newPAP.setDttmPropRMark (new DateAndTime(varParam, offset + 3)); - break; - case 0x40: - // This condition commented out, as Word seems to set outline levels even for - // paragraph with other styles than Heading 1..9, even though specification - // does not say so. See bug 49820 for discussion. - //if (newPAP.getIstd () < 1 && newPAP.getIstd () > 9) - { - newPAP.setLvl ((byte) sprm.getOperand()); - } - break; - case 0x41: - // sprmPFBiDi - newPAP.setFBiDi(sprm.getOperand() != 0); - break; - case 0x43: + case 0x41: + // sprmPFBiDi + newPAP.setFBiDi(sprm.getOperand() != 0); + break; + case 0x43: - //pap.fNumRMIns - newPAP.setFNumRMIns (sprm.getOperand() != 0); - break; - case 0x44: + //pap.fNumRMIns + newPAP.setFNumRMIns(sprm.getOperand() != 0); + break; + case 0x44: - //undocumented - break; - case 0x45: - if (sprm.getSizeCode() == 6) - { - byte[] buf = new byte[sprm.size() - 3]; - System.arraycopy(buf, 0, sprm.getGrpprl(), sprm.getGrpprlOffset(), buf.length); - newPAP.setNumrm (buf); - } - else - { - /**@todo handle large PAPX from data stream*/ - } - break; + //undocumented + break; + case 0x45: + if (sprm.getSizeCode() == 6) { + byte[] buf = new byte[sprm.size() - 3]; + System.arraycopy(buf, 0, sprm.getGrpprl(), sprm.getGrpprlOffset(), buf.length); + newPAP.setNumrm(buf); + } else { + /**@todo handle large PAPX from data stream*/ + } + break; - case 0x47: - newPAP.setFUsePgsuSettings (sprm.getOperand() != 0); - break; - case 0x48: - newPAP.setFAdjustRight (sprm.getOperand() != 0); - break; - case 0x49: - // sprmPItap -- 0x6649 - newPAP.setItap( sprm.getOperand() ); - break; - case 0x4a: - // sprmPDtap -- 0x664a - newPAP.setItap( (byte) ( newPAP.getItap() + sprm.getOperand() ) ); - break; - case 0x4b: - // sprmPFInnerTableCell -- 0x244b - newPAP.setFInnerTableCell( sprm.getOperand() != 0); - break; - case 0x4c: - // sprmPFInnerTtp -- 0x244c - newPAP.setFTtpEmbedded( sprm.getOperand() != 0); - break; - case 0x4d: - // sprmPShd -- 0xc64d - ShadingDescriptor shadingDescriptor = new ShadingDescriptor( - sprm.getGrpprl(), 3 ); - newPAP.setShading( shadingDescriptor ); - break; - case 0x5d: - // sprmPDxaRight -- 0x845d - newPAP.setDxaRight( sprm.getOperand() ); - break; - case 0x5e: - // sprmPDxaLeft -- 0x845e - newPAP.setDxaLeft( sprm.getOperand() ); - break; - case 0x60: - // sprmPDxaLeft1 -- 0x8460 - newPAP.setDxaLeft1( sprm.getOperand() ); - break; - case 0x61: - // sprmPJc - newPAP.setJustificationLogical((byte) sprm.getOperand()); - break; - case 0x67: - // sprmPRsid -- 0x6467 - newPAP.setRsid( sprm.getOperand() ); - break; - default: - LOG.atDebug().log("Unknown PAP sprm ignored: {}", sprm); - break; + case 0x47: + newPAP.setFUsePgsuSettings(sprm.getOperand() != 0); + break; + case 0x48: + newPAP.setFAdjustRight(sprm.getOperand() != 0); + break; + case 0x49: + // sprmPItap -- 0x6649 + newPAP.setItap(sprm.getOperand()); + break; + case 0x4a: + // sprmPDtap -- 0x664a + newPAP.setItap((byte) (newPAP.getItap() + sprm.getOperand())); + break; + case 0x4b: + // sprmPFInnerTableCell -- 0x244b + newPAP.setFInnerTableCell(sprm.getOperand() != 0); + break; + case 0x4c: + // sprmPFInnerTtp -- 0x244c + newPAP.setFTtpEmbedded(sprm.getOperand() != 0); + break; + case 0x4d: + // sprmPShd -- 0xc64d + ShadingDescriptor shadingDescriptor = new ShadingDescriptor( + sprm.getGrpprl(), 3); + newPAP.setShading(shadingDescriptor); + break; + case 0x5d: + // sprmPDxaRight -- 0x845d + newPAP.setDxaRight(sprm.getOperand()); + break; + case 0x5e: + // sprmPDxaLeft -- 0x845e + newPAP.setDxaLeft(sprm.getOperand()); + break; + case 0x60: + // sprmPDxaLeft1 -- 0x8460 + newPAP.setDxaLeft1(sprm.getOperand()); + break; + case 0x61: + // sprmPJc + newPAP.setJustificationLogical((byte) sprm.getOperand()); + break; + case 0x67: + // sprmPRsid -- 0x6467 + newPAP.setRsid(sprm.getOperand()); + break; + default: + LOG.atDebug().log("Unknown PAP sprm ignored: {}", sprm); + break; } - } + } - private static void handleTabs(ParagraphProperties pap, SprmOperation sprm) - { - byte[] grpprl = sprm.getGrpprl(); - int offset = sprm.getGrpprlOffset(); - int delSize = grpprl[offset++]; - int[] tabPositions = pap.getRgdxaTab(); - TabDescriptor[] tabDescriptors = pap.getRgtbd(); + private static void handleTabs(ParagraphProperties pap, SprmOperation sprm) { + byte[] grpprl = sprm.getGrpprl(); + int offset = sprm.getGrpprlOffset(); + int delSize = grpprl[offset++]; + int[] tabPositions = pap.getRgdxaTab(); + TabDescriptor[] tabDescriptors = pap.getRgtbd(); - Map<Integer, TabDescriptor> tabMap = new HashMap<>(); - for (int x = 0; x < tabPositions.length; x++) - { - tabMap.put(tabPositions[x], tabDescriptors[x]); - } + Map<Integer, TabDescriptor> tabMap = new HashMap<>(); + for (int x = 0; x < tabPositions.length; x++) { + tabMap.put(tabPositions[x], tabDescriptors[x]); + } - for (int x = 0; x < delSize; x++) - { - tabMap.remove((int) LittleEndian.getShort(grpprl, offset)); - offset += LittleEndianConsts.SHORT_SIZE; - } + for (int x = 0; x < delSize; x++) { + tabMap.remove((int) LittleEndian.getShort(grpprl, offset)); + offset += LittleEndianConsts.SHORT_SIZE; + } - int addSize = grpprl[offset++]; - int start = offset; - for (int x = 0; x < addSize; x++) - { - Integer key = (int) LittleEndian.getShort(grpprl, offset); - TabDescriptor val = new TabDescriptor( grpprl, start + ((TBDAbstractType.getSize() * addSize) + x) ); - tabMap.put(key, val); - offset += LittleEndianConsts.SHORT_SIZE; - } + int addSize = grpprl[offset++]; + int start = offset; + for (int x = 0; x < addSize; x++) { + Integer key = (int) LittleEndian.getShort(grpprl, offset); + TabDescriptor val = new TabDescriptor(grpprl, start + ((TBDAbstractType.getSize() * addSize) + x)); + tabMap.put(key, val); + offset += LittleEndianConsts.SHORT_SIZE; + } - tabPositions = new int[tabMap.size()]; - tabDescriptors = new TabDescriptor[tabPositions.length]; + tabPositions = new int[tabMap.size()]; + tabDescriptors = new TabDescriptor[tabPositions.length]; - List<Integer> list = new ArrayList<>(tabMap.keySet()); - Collections.sort(list); + List<Integer> list = new ArrayList<>(tabMap.keySet()); + Collections.sort(list); - for (int x = 0; x < tabPositions.length; x++) - { - Integer key = list.get(x); - tabPositions[x] = key; - if (tabMap.containsKey( key )) - tabDescriptors[x] = tabMap.get(key); - else - tabDescriptors[x] = new TabDescriptor(); - } + for (int x = 0; x < tabPositions.length; x++) { + Integer key = list.get(x); + tabPositions[x] = key; + if (tabMap.containsKey(key)) + tabDescriptors[x] = tabMap.get(key); + else + tabDescriptors[x] = new TabDescriptor(); + } - pap.setRgdxaTab(tabPositions); - pap.setRgtbd(tabDescriptors); - } + pap.setRgdxaTab(tabPositions); + pap.setRgtbd(tabDescriptors); + } } diff --git a/poi-scratchpad/src/main/java9/module-info.java b/poi-scratchpad/src/main/java9/module-info.java index ea505f6c1c..10e92f26aa 100644 --- a/poi-scratchpad/src/main/java9/module-info.java +++ b/poi-scratchpad/src/main/java9/module-info.java @@ -21,6 +21,7 @@ module org.apache.poi.scratchpad { requires commons.math3; requires org.apache.commons.io; requires org.apache.commons.codec; + requires org.apache.commons.collections4; requires org.apache.logging.log4j; uses org.apache.poi.sl.usermodel.MetroShapeProvider; diff --git a/poi-scratchpad/src/test/java/org/apache/poi/hslf/model/TestLine.java b/poi-scratchpad/src/test/java/org/apache/poi/hslf/model/TestLine.java index 0384b19043..e26793bde5 100644 --- a/poi-scratchpad/src/test/java/org/apache/poi/hslf/model/TestLine.java +++ b/poi-scratchpad/src/test/java/org/apache/poi/hslf/model/TestLine.java @@ -18,6 +18,8 @@ package org.apache.poi.hslf.model; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; +import static org.junit.jupiter.api.Assertions.assertNotNull; import java.awt.Color; import java.awt.Rectangle; @@ -27,9 +29,11 @@ import java.util.Arrays; import org.apache.poi.hslf.HSLFTestDataSamples; import org.apache.poi.hslf.usermodel.HSLFLine; +import org.apache.poi.hslf.usermodel.HSLFPlaceholder; import org.apache.poi.hslf.usermodel.HSLFShape; import org.apache.poi.hslf.usermodel.HSLFSlide; import org.apache.poi.hslf.usermodel.HSLFSlideShow; +import org.apache.poi.hslf.usermodel.HSLFTextBox; import org.apache.poi.sl.usermodel.StrokeStyle.LineCompound; import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; import org.junit.jupiter.api.Test; @@ -62,9 +66,14 @@ public final class TestLine { @Test void testCreateLines() throws IOException { + final String title = "Lines tester"; try (HSLFSlideShow ppt1 = new HSLFSlideShow()) { HSLFSlide slide1 = ppt1.createSlide(); - slide1.addTitle().setText("Lines tester"); + HSLFTextBox titleBox = slide1.addTitle(); + titleBox.setText(title); + assertInstanceOf(HSLFPlaceholder.class, titleBox); + HSLFPlaceholder pl = (HSLFPlaceholder) titleBox; + assertNotNull(pl.getPlaceholder()); for (Object[] line : lines) { HSLFLine hslfLine = new HSLFLine(); @@ -85,6 +94,7 @@ public final class TestLine { try (HSLFSlideShow ppt2 = HSLFTestDataSamples.writeOutAndReadBack(ppt1)) { HSLFSlide slide2 = ppt2.getSlides().get(0); + assertEquals(title, slide2.getTitle()); int idx = 0; for (HSLFShape shape : slide2.getShapes().subList(1,14)) { diff --git a/poi-scratchpad/src/test/java/org/apache/poi/hslf/usermodel/TestBugs.java b/poi-scratchpad/src/test/java/org/apache/poi/hslf/usermodel/TestBugs.java index 1cd5be3cf6..575d443b5b 100644 --- a/poi-scratchpad/src/test/java/org/apache/poi/hslf/usermodel/TestBugs.java +++ b/poi-scratchpad/src/test/java/org/apache/poi/hslf/usermodel/TestBugs.java @@ -68,19 +68,10 @@ import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.poifs.macros.VBAMacroReader; import org.apache.poi.sl.draw.DrawPaint; import org.apache.poi.sl.extractor.SlideShowExtractor; -import org.apache.poi.sl.usermodel.ColorStyle; -import org.apache.poi.sl.usermodel.PaintStyle; +import org.apache.poi.sl.usermodel.*; import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint; import org.apache.poi.sl.usermodel.PictureData.PictureType; -import org.apache.poi.sl.usermodel.Placeholder; -import org.apache.poi.sl.usermodel.ShapeType; -import org.apache.poi.sl.usermodel.Slide; -import org.apache.poi.sl.usermodel.SlideShow; -import org.apache.poi.sl.usermodel.SlideShowFactory; -import org.apache.poi.sl.usermodel.TextBox; -import org.apache.poi.sl.usermodel.TextParagraph; import org.apache.poi.sl.usermodel.TextParagraph.TextAlign; -import org.apache.poi.sl.usermodel.TextRun; import org.apache.poi.util.LittleEndian; import org.apache.poi.util.StringUtil; import org.apache.poi.util.Units; @@ -904,4 +895,22 @@ public final class TestBugs { assertEquals(ShapeType.NOT_PRIMITIVE, shList.get(2).getShapeType()); } } + + @Test + void test69697() throws Exception { + try (HSLFSlideShow ppt = open("bug69697.ppt")) { + HSLFSlide slide = ppt.getSlides().get(0); + for (HSLFShape sh : slide.getShapes()) { + if (sh instanceof HSLFPictureShape) { + HSLFPictureShape pict = (HSLFPictureShape) sh; + HSLFPictureData pictData = pict.getPictureData(); + assertNotNull(pictData, "PictureData should not be null for shape: " + pict.getShapeName()); + byte[] data = pictData.getData(); + assertNotNull(data, "Picture data should not be null for shape: " + pict.getShapeName()); + PictureData.PictureType type = pictData.getType(); + assertNotNull(type, "Picture type should not be null for shape: " + pict.getShapeName()); + } + } + } + } } diff --git a/poi-scratchpad/src/test/java/org/apache/poi/hslf/usermodel/TestPictures.java b/poi-scratchpad/src/test/java/org/apache/poi/hslf/usermodel/TestPictures.java index 2b90916775..5474c7f8d0 100644 --- a/poi-scratchpad/src/test/java/org/apache/poi/hslf/usermodel/TestPictures.java +++ b/poi-scratchpad/src/test/java/org/apache/poi/hslf/usermodel/TestPictures.java @@ -29,6 +29,8 @@ import java.awt.geom.Dimension2D; import java.awt.image.BufferedImage; import java.io.ByteArrayInputStream; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import java.net.URL; import java.util.Arrays; import java.util.Collections; @@ -271,9 +273,9 @@ public final class TestPictures { @Test @Disabled("requires an internet connection to a 3rd party site") // As of 2017-06-20, the file still exists at the specified URL and the test passes. - void testZeroPictureLength() throws IOException { + void testZeroPictureLength() throws IOException, URISyntaxException { // take the data from www instead of test directory - URL url = new URL("http://www.cs.sfu.ca/~anoop/courses/CMPT-882-Fall-2002/chris.ppt"); + URL url = new URI("http://www.cs.sfu.ca/~anoop/courses/CMPT-882-Fall-2002/chris.ppt").toURL(); HSLFSlideShowImpl hslf = new HSLFSlideShowImpl(url.openStream()); /* Assume that the file could retrieved... InputStream is; diff --git a/poi-scratchpad/src/test/java9/module-info.java b/poi-scratchpad/src/test/java9/module-info.java index 35dbc01a3e..748a2244a7 100644 --- a/poi-scratchpad/src/test/java9/module-info.java +++ b/poi-scratchpad/src/test/java9/module-info.java @@ -21,6 +21,7 @@ module org.apache.poi.scratchpad { requires commons.math3; requires org.apache.commons.io; requires org.apache.commons.codec; + requires org.apache.commons.collections4; requires org.apache.logging.log4j; uses org.apache.poi.sl.usermodel.MetroShapeProvider; |