]> source.dussan.org Git - poi.git/commitdiff
More on XSSFColor and ARGB vs RGB for bug #50299 - provide methods to let you get...
authorNick Burch <nick@apache.org>
Fri, 25 Feb 2011 21:21:45 +0000 (21:21 +0000)
committerNick Burch <nick@apache.org>
Fri, 25 Feb 2011 21:21:45 +0000 (21:21 +0000)
Includes the new patch from bug #50299 for 3 colour RGB black/white being inverted from Excel

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1074703 13f79535-47bb-0310-9956-ffa450edef68

src/documentation/content/xdocs/status.xml
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFCellStyle.java
src/ooxml/java/org/apache/poi/xssf/usermodel/XSSFColor.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFBugs.java
src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFColor.java [new file with mode: 0644]

index 65601488e272f72430b2a41b034edbdc4a384349..bf64050a3a923dab0d974272a827ac0644fad6bb 100644 (file)
@@ -34,6 +34,7 @@
 
     <changes>
         <release version="3.8-beta1" date="2010-??-??">
+           <action dev="poi-developers" type="fix">50299 - More XSSFColor updates for ARGB vs RGB</action>
            <action dev="poi-developers" type="fix">50581 - Use stax:stax-api instead of org.apache.geronimo.specs:geronimo-stax-api_1.0_spec</action>
            <action dev="poi-developers" type="fix">50786 - Fix XSSFColor to fetch the RGB values of old-style indexed colours</action>
            <action dev="poi-developers" type="fix">50299 - Fix XSSFColor fetching of white and black background themes</action>
index 6358168c67a74cbf013102319649755a4686d4fb..93b4364d15a9afb9e93152b3dff632e705550153 100644 (file)
@@ -1452,6 +1452,7 @@ public class XSSFCellStyle implements CellStyle {
      */
     private void extractColorFromTheme(XSSFColor originalColor){
         XSSFColor themeColor = _theme.getThemeColor(originalColor.getTheme());
-        originalColor.setRgb(themeColor.getRgb());
+        // Set the raw colour, not the adjusted one
+        originalColor.setRgb(themeColor.getCTColor().getRgb());
     }
 }
index 2194a4db17b2e8dceb4fb6752e3088937b4e08db..af5928fbf667d6618c73ca824e1befec947ba4ad 100644 (file)
@@ -80,46 +80,106 @@ public class XSSFColor implements Color {
                ctColor.setIndexed(indexed);
        }
 
+   /**
+    * Standard Red Green Blue ctColor value (RGB).
+    * If there was an A (Alpha) value, it will be stripped.
+    */
+   public byte[] getRgb() {
+      byte[] rgb = getRGBOrARGB();
+      if(rgb == null) return null;
+      
+      if(rgb.length == 4) {
+         // Need to trim off the alpha
+         byte[] tmp = new byte[3];
+         System.arraycopy(rgb, 1, tmp, 0, 3);
+         return tmp;
+      } else {
+         return rgb;
+      }
+   }
+
+   /**
+    * Standard Alpha Red Green Blue ctColor value (ARGB).
+    */
+   public byte[] getARgb() {
+      byte[] rgb = getRGBOrARGB();
+      if(rgb == null) return null;
+      
+      if(rgb.length == 3) {
+         // Pad with the default Alpha
+         byte[] tmp = new byte[4];
+         tmp[0] = -1;
+         System.arraycopy(rgb, 0, tmp, 1, 3);
+         return tmp;
+      } else {
+         return rgb;
+      }
+   }
+   
+   private byte[] getRGBOrARGB() {
+        byte[] rgb = null;
+
+        if (ctColor.isSetIndexed() && ctColor.getIndexed() > 0) {
+            HSSFColor indexed = HSSFColor.getIndexHash().get((int) ctColor.getIndexed());
+            if (indexed != null) {
+               rgb = new byte[3];
+               rgb[0] = (byte) indexed.getTriplet()[0];
+               rgb[1] = (byte) indexed.getTriplet()[1];
+               rgb[2] = (byte) indexed.getTriplet()[2];
+               return rgb;
+            }
+         }
+        
+         if (!ctColor.isSetRgb()) {
+            // No colour is available, sorry
+            return null;
+         }
+
+         // Grab the colour
+         rgb = ctColor.getRgb();
+
+         if(rgb.length == 4) {
+            // Good to go, return it as-is
+            return rgb;
+         }
+         
+         // For RGB colours, but not ARGB (we think...)
+         // Excel gets black and white the wrong way around, so switch them 
+         if (rgb[0] == 0 && rgb[1] == 0 && rgb[2] == 0) {
+            rgb = new byte[] {-1, -1, -1};
+         }
+         else if (rgb[0] == -1 && rgb[1] == -1 && rgb[2] == -1) {
+            rgb = new byte[] {0, 0, 0};
+         }
+         return rgb;
+    }
+
     /**
-     * Standard Alpha Red Green Blue ctColor value (ARGB).
+     * Standard Red Green Blue ctColor value (RGB) with applied tint.
+     * Alpha values are ignored.
      */
-    public byte[] getRgb() {
-       if(ctColor.isSetIndexed() && ctColor.getIndexed() > 0) {
-          HSSFColor indexed = HSSFColor.getIndexHash().get((int)ctColor.getIndexed());
-          if(indexed != null) {
-             // Convert it to ARGB form
-             byte[] rgb = new byte[4];
-             rgb[0] = 0;
-             rgb[1] = (byte)indexed.getTriplet()[0];
-             rgb[2] = (byte)indexed.getTriplet()[1];
-             rgb[3] = (byte)indexed.getTriplet()[2];
-             return rgb;
-          } else {
-             // Your indexed value isn't a standard one, sorry...
-             return null;
-          }
-       }
-                return ctColor.getRgb();
-       }
+    public byte[] getRgbWithTint() {
+        byte[] rgb = ctColor.getRgb();
+        if (rgb != null) {
+            if(rgb.length == 4) {
+               byte[] tmp = new byte[3];
+               System.arraycopy(rgb, 1, tmp, 0, 3);
+               rgb = tmp;
+            }
+            for (int i = 0; i < rgb.length; i++){
+                rgb[i] = applyTint(rgb[i] & 0xFF, ctColor.getTint());
+            }
+        }
+        return rgb;
+    }
        
     /**
-     * Standard Alpha Red Green Blue ctColor value (ARGB) with applied tint.
+     * Return the ARGB value in hex format, eg FF00FF00.
+     * Works for both regular and indexed colours. 
      */
-       public byte[] getRgbWithTint() {
-               byte[] rgb =ctColor.getRgb();
-               for(int i = 0; i < rgb.length; i++){
-                       rgb[i] = applyTint(rgb[i] & 0xFF, ctColor.getTint());
-               }
-               return rgb;
-       }
-       
-       /**
-        * Return the ARGB value in hex format, eg FF00FF00.
-        * Works for both regular and indexed colours. 
-        */
        public String getARGBHex() {
           StringBuffer sb = new StringBuffer();
-          byte[] rgb = getRgb();
+          byte[] rgb = getARgb();
           if(rgb == null) {
              return null;
           }
index b36a92a4ddad64b0f7b4e6176f55c663a6bd7502..3b17b9ac0d47452ab36a2f4eff63af38f94b7086 100644 (file)
@@ -696,7 +696,8 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
        }
        
        // Check one bit in detail
-       // TODO Is this correct, shouldn't one be white and one black?
+       // Check that we get back foreground=0 for the theme colours,
+       //  and background=64 for the auto colouring
        Sheet s = wb.getSheetAt(0);
        assertEquals(0,  s.getRow(0).getCell(8).getCellStyle().getFillForegroundColor());
        assertEquals(64, s.getRow(0).getCell(8).getCellStyle().getFillBackgroundColor());
@@ -721,13 +722,15 @@ public final class TestXSSFBugs extends BaseTestBugzillaIssues {
        assertEquals(42, cs.getFillForegroundColor());
        assertEquals(42, cs.getFillForegroundColorColor().getIndexed());
        assertNotNull(cs.getFillForegroundColorColor().getRgb());
-       assertEquals("00CCFFCC", cs.getFillForegroundColorColor().getARGBHex());
+       assertEquals("FFCCFFCC", cs.getFillForegroundColorColor().getARGBHex());
     }
     
     /**
      * Fonts where their colours come from the theme rather
      *  then being set explicitly still should allow the
-     *  fetching of the RGB 
+     *  fetching of the RGB.
+     * TODO Allow XSSFFont to get at the themes table, so it can do
+     *  the same trick that XSSFCellStyle does with theme colours 
      */
     public void DISABLEDtest50784() throws Exception {
        XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50784-font_theme_colours.xlsx");
diff --git a/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFColor.java b/src/ooxml/testcases/org/apache/poi/xssf/usermodel/TestXSSFColor.java
new file mode 100644 (file)
index 0000000..17b1d0d
--- /dev/null
@@ -0,0 +1,159 @@
+/* ====================================================================
+   Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed with
+   this work for additional information regarding copyright ownership.
+   The ASF licenses this file to You under the Apache License, Version 2.0
+   (the "License"); you may not use this file except in compliance with
+   the License.  You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
+==================================================================== */
+
+package org.apache.poi.xssf.usermodel;
+
+import junit.framework.TestCase;
+
+import org.apache.poi.ss.usermodel.*;
+import org.apache.poi.xssf.XSSFITestDataProvider;
+import org.apache.poi.xssf.XSSFTestDataSamples;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTBooleanProperty;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTColor;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFont;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontName;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontScheme;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTFontSize;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTIntProperty;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTUnderlineProperty;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTVerticalAlignFontProperty;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STFontScheme;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STUnderlineValues;
+import org.openxmlformats.schemas.spreadsheetml.x2006.main.STVerticalAlignRun;
+
+public final class TestXSSFColor extends TestCase {
+   public void testIndexedColour() throws Exception {
+      XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48779.xlsx");
+      
+      // Check the CTColor is as expected
+      XSSFColor indexed = wb.getCellStyleAt((short)1).getFillBackgroundXSSFColor();
+      assertEquals(true, indexed.getCTColor().isSetIndexed());
+      assertEquals(64, indexed.getCTColor().getIndexed());
+      assertEquals(false, indexed.getCTColor().isSetRgb());
+      assertEquals(null, indexed.getCTColor().getRgb());
+      
+      // Now check the XSSFColor
+      // Note - 64 is a special "auto" one with no rgb equiv
+      assertEquals(64, indexed.getIndexed());
+      assertEquals(null, indexed.getRgb());
+      assertEquals(null, indexed.getRgbWithTint());
+      assertEquals(null, indexed.getARGBHex());
+      
+      // Now move to one with indexed rgb values
+      indexed.setIndexed(59);
+      assertEquals(true, indexed.getCTColor().isSetIndexed());
+      assertEquals(59, indexed.getCTColor().getIndexed());
+      assertEquals(false, indexed.getCTColor().isSetRgb());
+      assertEquals(null, indexed.getCTColor().getRgb());
+      
+      assertEquals(59, indexed.getIndexed());
+      assertEquals("FF333300", indexed.getARGBHex());
+      
+      assertEquals(3, indexed.getRgb().length);
+      assertEquals(0x33, indexed.getRgb()[0]);
+      assertEquals(0x33, indexed.getRgb()[1]);
+      assertEquals(0x00, indexed.getRgb()[2]);
+      
+      assertEquals(4, indexed.getARgb().length);
+      assertEquals(-1, indexed.getARgb()[0]);
+      assertEquals(0x33, indexed.getARgb()[1]);
+      assertEquals(0x33, indexed.getARgb()[2]);
+      assertEquals(0x00, indexed.getARgb()[3]);
+      
+      // You don't get tinted indexed colours, sorry...
+      assertEquals(null, indexed.getRgbWithTint());
+   }
+   
+   public void testRGBColour() throws Exception {
+      XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("50299.xlsx");
+      
+      // Check the CTColor is as expected
+      XSSFColor rgb3 = wb.getCellStyleAt((short)25).getFillForegroundXSSFColor();
+      assertEquals(false, rgb3.getCTColor().isSetIndexed());
+      assertEquals(0,     rgb3.getCTColor().getIndexed());
+      assertEquals(true,  rgb3.getCTColor().isSetTint());
+      assertEquals(-0.34999, rgb3.getCTColor().getTint(), 0.00001);
+      assertEquals(true,  rgb3.getCTColor().isSetRgb());
+      assertEquals(3,     rgb3.getCTColor().getRgb().length);
+      
+      // Now check the XSSFColor
+      assertEquals(0, rgb3.getIndexed());
+      assertEquals(-0.34999, rgb3.getTint(), 0.00001);
+      
+      assertEquals("FFFFFFFF", rgb3.getARGBHex());
+      assertEquals(3, rgb3.getRgb().length);
+      assertEquals(-1, rgb3.getRgb()[0]);
+      assertEquals(-1, rgb3.getRgb()[1]);
+      assertEquals(-1,  rgb3.getRgb()[2]);
+      
+      assertEquals(4, rgb3.getARgb().length);
+      assertEquals(-1, rgb3.getARgb()[0]);
+      assertEquals(-1, rgb3.getARgb()[1]);
+      assertEquals(-1,  rgb3.getARgb()[2]);
+      assertEquals(-1,  rgb3.getARgb()[3]);
+      
+      // Tint doesn't have the alpha
+      assertEquals(3, rgb3.getRgbWithTint().length);
+      assertEquals(0, rgb3.getRgbWithTint()[0]);
+      assertEquals(0,  rgb3.getRgbWithTint()[1]);
+      assertEquals(0,  rgb3.getRgbWithTint()[2]);
+   }
+   
+   public void testARGBColour() throws Exception {
+      XSSFWorkbook wb = XSSFTestDataSamples.openSampleWorkbook("48779.xlsx");
+      
+      // Check the CTColor is as expected
+      XSSFColor rgb4 = wb.getCellStyleAt((short)1).getFillForegroundXSSFColor();
+      assertEquals(false, rgb4.getCTColor().isSetIndexed());
+      assertEquals(0,     rgb4.getCTColor().getIndexed());
+      assertEquals(true, rgb4.getCTColor().isSetRgb());
+      assertEquals(4, rgb4.getCTColor().getRgb().length);
+      
+      // Now check the XSSFColor
+      assertEquals(0, rgb4.getIndexed());
+      assertEquals(0.0, rgb4.getTint());
+      
+      assertEquals("FFFF0000", rgb4.getARGBHex());
+      assertEquals(3, rgb4.getRgb().length);
+      assertEquals(-1, rgb4.getRgb()[0]);
+      assertEquals(0,  rgb4.getRgb()[1]);
+      assertEquals(0,  rgb4.getRgb()[2]);
+      
+      assertEquals(4, rgb4.getARgb().length);
+      assertEquals(-1, rgb4.getARgb()[0]);
+      assertEquals(-1, rgb4.getARgb()[1]);
+      assertEquals(0,  rgb4.getARgb()[2]);
+      assertEquals(0,  rgb4.getARgb()[3]);
+      
+      // Tint doesn't have the alpha
+      assertEquals(3, rgb4.getRgbWithTint().length);
+      assertEquals(-1, rgb4.getRgbWithTint()[0]);
+      assertEquals(0,  rgb4.getRgbWithTint()[1]);
+      assertEquals(0,  rgb4.getRgbWithTint()[2]);
+
+      
+      // Turn on tinting, and check it behaves
+      // TODO These values are suspected to be wrong...
+      rgb4.setTint(0.4);
+      assertEquals(0.4, rgb4.getTint());
+      
+      assertEquals(3, rgb4.getRgbWithTint().length);
+      assertEquals(-1, rgb4.getRgbWithTint()[0]);
+      assertEquals(102,  rgb4.getRgbWithTint()[1]);
+      assertEquals(102,  rgb4.getRgbWithTint()[2]);
+   }
+}