]> source.dussan.org Git - poi.git/commitdiff
fix bug 53182 - Reading combined character styling and direct formatting of a charact...
authorSergey Vladimirov <sergey@apache.org>
Mon, 5 Nov 2012 15:51:41 +0000 (15:51 +0000)
committerSergey Vladimirov <sergey@apache.org>
Mon, 5 Nov 2012 15:51:41 +0000 (15:51 +0000)
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1405850 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/status.xml
src/scratchpad/src/org/apache/poi/hwpf/model/CHPX.java
src/scratchpad/src/org/apache/poi/hwpf/sprm/CharacterSprmUncompressor.java
src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterProperties.java
src/scratchpad/src/org/apache/poi/hwpf/usermodel/CharacterRun.java
src/scratchpad/testcases/org/apache/poi/hwpf/converter/TestWordToHtmlConverter.java
test-data/document/Bug53182.doc [new file with mode: 0644]

index bfbabdf77b693df0775d31347794ae47715cd56e..4a76471aee290b7bb6417992a9a6390a2e41948f 100644 (file)
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.9-beta1" date="2012-??-??">
+          <action dev="poi-developers" type="fix">53182 - Reading combined character styling and direct formatting of a character run</action>
           <action dev="poi-developers" type="fix">52311 - Conversion to html : Problem in titles number </action>
           <action dev="poi-developers" type="fix">53914 - TableRow#getTopBorder() return bottom's border</action>
           <action dev="poi-developers" type="fix">53282 - Avoid exception when parsing OPC relationships with non-breaking spaces</action>
index add8ec9b1d0e70a519134c2208674011d01f5ccf..c7d4a30fd5a1be3227f21ba07903711185baaace 100644 (file)
@@ -72,11 +72,8 @@ public final class CHPX extends BytePropertyNode<CHPX>
         }
 
         CharacterProperties baseStyle = ss.getCharacterStyle( istd );
-        if (baseStyle == null)
-            baseStyle = new CharacterProperties();
-
         CharacterProperties props = CharacterSprmUncompressor.uncompressCHP(
-                baseStyle, getGrpprl(), 0 );
+                ss, baseStyle, getGrpprl(), 0 );
         return props;
     }
 
index 423b569308d9a16f2a902b284458f5aa9baea5d1..c1b718709f95f8fc1990b97ae29fae06d579b168 100644 (file)
@@ -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;
index 9d1582aec88dcfb61da0818136cd41246d0807b2..fd6d631c7283affaf0cef306ca6916c9aee8d9df 100644 (file)
@@ -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 );
+        }
     }
 }
index d049969f755fe8b714e718a54b38c5646776f311..77ec0ecd3311aed18bc19687cbd6db9fadaefcd3 100644 (file)
@@ -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.
index a7a8212398603bdecdba659d66c3dadfffc79ca9..74be67b28d77c02dc6527ccb162f1adc9f6e1c2c 100644 (file)
@@ -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, "<span>Before text; </span><a " );
         assertContains( result,
-                "<a href=\"http://testuri.org/\"><span>Hyperlink text</span></a>" );
+                "<a href=\"http://testuri.org/\"><span class=\"s1\">Hyperlink text</span></a>" );
         assertContains( result, "</a><span>; after text</span>" );
     }
 
diff --git a/test-data/document/Bug53182.doc b/test-data/document/Bug53182.doc
new file mode 100644 (file)
index 0000000..c627d02
Binary files /dev/null and b/test-data/document/Bug53182.doc differ