From: Sergey Vladimirov Date: Mon, 5 Nov 2012 15:51:41 +0000 (+0000) Subject: fix bug 53182 - Reading combined character styling and direct formatting of a charact... X-Git-Tag: 3.10-beta1~101 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=303de7dab65105eff48307a94410c3d6e72e2a61;p=poi.git fix bug 53182 - Reading combined character styling and direct formatting of a character run git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1405850 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/src/documentation/content/xdocs/status.xml b/src/documentation/content/xdocs/status.xml index bfbabdf77b..4a76471aee 100644 --- a/src/documentation/content/xdocs/status.xml +++ b/src/documentation/content/xdocs/status.xml @@ -34,6 +34,7 @@ + 53182 - Reading combined character styling and direct formatting of a character run 52311 - Conversion to html : Problem in titles number 53914 - TableRow#getTopBorder() return bottom's border 53282 - Avoid exception when parsing OPC relationships with non-breaking spaces diff --git a/src/scratchpad/src/org/apache/poi/hwpf/model/CHPX.java b/src/scratchpad/src/org/apache/poi/hwpf/model/CHPX.java index add8ec9b1d..c7d4a30fd5 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/model/CHPX.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/model/CHPX.java @@ -72,11 +72,8 @@ public final class CHPX extends BytePropertyNode } CharacterProperties baseStyle = ss.getCharacterStyle( istd ); - if (baseStyle == null) - baseStyle = new CharacterProperties(); - CharacterProperties props = CharacterSprmUncompressor.uncompressCHP( - baseStyle, getGrpprl(), 0 ); + ss, baseStyle, getGrpprl(), 0 ); return props; } diff --git a/src/scratchpad/src/org/apache/poi/hwpf/sprm/CharacterSprmUncompressor.java b/src/scratchpad/src/org/apache/poi/hwpf/sprm/CharacterSprmUncompressor.java index 423b569308..c1b718709f 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/sprm/CharacterSprmUncompressor.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/sprm/CharacterSprmUncompressor.java @@ -21,6 +21,7 @@ import org.apache.poi.hwpf.usermodel.ShadingDescriptor80; import org.apache.poi.hwpf.model.Colorref; import org.apache.poi.hwpf.model.Hyphenation; +import org.apache.poi.hwpf.model.StyleSheet; import org.apache.poi.hwpf.usermodel.BorderCode; import org.apache.poi.hwpf.usermodel.CharacterProperties; import org.apache.poi.hwpf.usermodel.DateAndTime; @@ -40,35 +41,89 @@ public final class CharacterSprmUncompressor extends SprmUncompressor { } - public static CharacterProperties uncompressCHP(CharacterProperties parent, - byte[] grpprl, - int offset) - { - CharacterProperties newProperties = null; - try + @Deprecated + public static CharacterProperties uncompressCHP( + CharacterProperties parent, byte[] grpprl, int offset ) { - newProperties = (CharacterProperties) parent.clone(); + CharacterProperties newProperties = parent.clone(); + applySprms( parent, grpprl, offset, true, newProperties ); + return newProperties; } - catch (CloneNotSupportedException cnse) + + public static CharacterProperties uncompressCHP( StyleSheet styleSheet, + CharacterProperties parStyle, byte[] grpprl, int offset ) { - throw new RuntimeException("There is no way this exception should happen!!"); + CharacterProperties newProperties; + if ( parStyle == null ) + { + parStyle = new CharacterProperties(); + newProperties = new CharacterProperties(); + } + else + { + newProperties = parStyle.clone(); + } + + /* + * not fully conform to specification, but the fastest way to make it + * work. Shall be rewritten if any errors would be found -- vlsergey + */ + Integer style = getIstd( grpprl, offset ); + if ( style != null ) + { + applySprms( parStyle, styleSheet.getCHPX( style ), 0, false, + newProperties ); + } + + CharacterProperties styleProperties = newProperties; + newProperties = styleProperties.clone(); + + applySprms( styleProperties, grpprl, offset, true, newProperties ); + return newProperties; } - SprmIterator sprmIt = new SprmIterator(grpprl, offset); - while (sprmIt.hasNext()) + private static void applySprms( CharacterProperties parentProperties, + byte[] grpprl, int offset, boolean warnAboutNonChpSprms, + CharacterProperties targetProperties ) { - SprmOperation sprm = sprmIt.next(); + SprmIterator sprmIt = new SprmIterator( grpprl, offset ); + + while ( sprmIt.hasNext() ) + { + SprmOperation sprm = sprmIt.next(); - if (sprm.getType() != 2) { - logger.log( POILogger.WARN, "Non-CHP SPRM returned by SprmIterator: " + sprm ); - continue; - } + if ( sprm.getType() != 2 ) + { + if ( warnAboutNonChpSprms ) + { + logger.log( POILogger.WARN, + "Non-CHP SPRM returned by SprmIterator: " + sprm ); + } + continue; + } - unCompressCHPOperation(parent, newProperties, sprm); + unCompressCHPOperation( parentProperties, targetProperties, sprm ); + } } - return newProperties; - } + private static Integer getIstd( byte[] grpprl, int offset ) + { + Integer style = null; + { + SprmIterator sprmIt = new SprmIterator( grpprl, offset ); + while ( sprmIt.hasNext() ) + { + SprmOperation sprm = sprmIt.next(); + + if ( sprm.getType() == 2 && sprm.getOperation() == 0x30 ) + { + // sprmCIstd (0x4A30) + style = Integer.valueOf( sprm.getOperand() ); + } + } + } + return style; + } /** * Used in decompression of a chpx. This performs an operation defined by @@ -238,9 +293,10 @@ public final class CharacterSprmUncompressor extends SprmUncompressor break; case 0x2f: break; - case 0x30: - newCHP.setIstd (sprm.getOperand()); - break; + case 0x30: + newCHP.setIstd( sprm.getOperand() ); + // 0x30 is supported by uncompressCHP(...) + break; case 0x31: //permutation vector for fast saves, who cares! @@ -257,20 +313,12 @@ public final class CharacterSprmUncompressor extends SprmUncompressor newCHP.setKul ((byte) 0); newCHP.setIco ((byte) 0); break; - case 0x33: - try - { - // preserve the fSpec setting from the original CHP - boolean fSpec = newCHP.isFSpec (); - newCHP = (CharacterProperties) oldCHP.clone (); - newCHP.setFSpec (fSpec); - - } - catch (CloneNotSupportedException e) - { - //do nothing - } - return; + case 0x33: + // preserve the fSpec setting from the original CHP + boolean fSpec = newCHP.isFSpec(); + newCHP = oldCHP.clone(); + newCHP.setFSpec( fSpec ); + return; case 0x34: // sprmCKcd break; diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterProperties.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterProperties.java index 9d1582aec8..fd6d631c72 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterProperties.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterProperties.java @@ -370,19 +370,27 @@ public final class CharacterProperties setCv( new Colorref( colour24 & 0xFFFFFF ) ); } - public Object clone() throws CloneNotSupportedException + public CharacterProperties clone() { - CharacterProperties cp = (CharacterProperties) super.clone(); - - cp.setCv( getCv().clone() ); - cp.setDttmRMark( (DateAndTime) getDttmRMark().clone() ); - cp.setDttmRMarkDel( (DateAndTime) getDttmRMarkDel().clone() ); - cp.setDttmPropRMark( (DateAndTime) getDttmPropRMark().clone() ); - cp.setDttmDispFldRMark( (DateAndTime) getDttmDispFldRMark().clone() ); - cp.setXstDispFldRMark( getXstDispFldRMark().clone() ); - cp.setShd( (ShadingDescriptor) getShd().clone() ); - cp.setBrc( (BorderCode) getBrc().clone() ); - - return cp; + try + { + CharacterProperties cp = (CharacterProperties) super.clone(); + + cp.setCv( getCv().clone() ); + cp.setDttmRMark( (DateAndTime) getDttmRMark().clone() ); + cp.setDttmRMarkDel( (DateAndTime) getDttmRMarkDel().clone() ); + cp.setDttmPropRMark( (DateAndTime) getDttmPropRMark().clone() ); + cp.setDttmDispFldRMark( (DateAndTime) getDttmDispFldRMark().clone() ); + cp.setXstDispFldRMark( getXstDispFldRMark().clone() ); + cp.setShd( (ShadingDescriptor) getShd().clone() ); + cp.setBrc( (BorderCode) getBrc().clone() ); + + return cp; + } + catch ( CloneNotSupportedException exc ) + { + throw new UnsupportedOperationException( + "Impossible CloneNotSupportedException occured", exc ); + } } } diff --git a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterRun.java b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterRun.java index d049969f75..77ec0ecd33 100644 --- a/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterRun.java +++ b/src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterRun.java @@ -535,20 +535,18 @@ public final class CharacterRun _props.setIco24(colour24); } - /** - * clone the CharacterProperties object associated with this - * characterRun so that you can apply it to another CharacterRun - * - * @deprecated This method shall not be public and should not be called from high-level code - */ - @Deprecated - public CharacterProperties cloneProperties() { - try { - return (CharacterProperties)_props.clone(); - } catch(java.lang.CloneNotSupportedException e) { - throw new RuntimeException(e); + /** + * clone the CharacterProperties object associated with this characterRun so + * that you can apply it to another CharacterRun + * + * @deprecated This method shall not be public and should not be called from + * high-level code + */ + @Deprecated + public CharacterProperties cloneProperties() + { + return _props.clone(); } - } /** * Used to create a deep copy of this object. diff --git a/src/scratchpad/testcases/org/apache/poi/hwpf/converter/TestWordToHtmlConverter.java b/src/scratchpad/testcases/org/apache/poi/hwpf/converter/TestWordToHtmlConverter.java index a7a8212398..74be67b28d 100644 --- a/src/scratchpad/testcases/org/apache/poi/hwpf/converter/TestWordToHtmlConverter.java +++ b/src/scratchpad/testcases/org/apache/poi/hwpf/converter/TestWordToHtmlConverter.java @@ -141,6 +141,12 @@ public class TestWordToHtmlConverter extends TestCase getHtmlText( "Bug48075.doc" ); } + public void testBug53182() throws Exception + { + String result = getHtmlText( "Bug53182.doc" ); + assertFalse( result.contains( "italic" ) ); + } + public void testDocumentProperties() throws Exception { String result = getHtmlText( "documentProperties.doc" ); @@ -183,7 +189,7 @@ public class TestWordToHtmlConverter extends TestCase assertContains( result, "Before text; Hyperlink text" ); + "Hyperlink text" ); assertContains( result, "; after text" ); } diff --git a/test-data/document/Bug53182.doc b/test-data/document/Bug53182.doc new file mode 100644 index 0000000000..c627d02633 Binary files /dev/null and b/test-data/document/Bug53182.doc differ