More on XSSFColor and ARGB vs RGB for bug #50299 - provide methods to let you get at either 3 byte RGB, or 4 byte ARGB, whichever you prefer for your needs.
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
This commit is contained in:
parent
3937b2f310
commit
5792826402
@ -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>
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
@ -80,46 +80,106 @@ public class XSSFColor implements Color {
|
||||
ctColor.setIndexed(indexed);
|
||||
}
|
||||
|
||||
/**
|
||||
* Standard Alpha Red Green Blue ctColor value (ARGB).
|
||||
*/
|
||||
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();
|
||||
}
|
||||
/**
|
||||
* 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) with applied tint.
|
||||
* Standard Red Green Blue ctColor value (RGB) with applied tint.
|
||||
* Alpha values are ignored.
|
||||
*/
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the ARGB value in hex format, eg FF00FF00.
|
||||
* Works for both regular and indexed colours.
|
||||
*/
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
@ -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");
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user