Start decoding the CF color scales for HSSF
git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1691795 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
65b58b1a5d
commit
929ee429ea
@ -19,6 +19,7 @@ package org.apache.poi.hssf.record;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.apache.poi.hssf.record.cf.ColorGradientFormatting;
|
||||
import org.apache.poi.hssf.record.cf.IconMultiStateFormatting;
|
||||
import org.apache.poi.hssf.record.cf.Threshold;
|
||||
import org.apache.poi.hssf.record.common.FtrHeader;
|
||||
@ -56,9 +57,9 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord {
|
||||
private byte[] template_params;
|
||||
|
||||
private IconMultiStateFormatting multistate;
|
||||
private ColorGradientFormatting color_gradient;
|
||||
|
||||
// TODO Parse these
|
||||
private byte[] gradient_data;
|
||||
private byte[] databar_data;
|
||||
private byte[] filter_data;
|
||||
|
||||
@ -176,7 +177,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord {
|
||||
|
||||
byte type = getConditionType();
|
||||
if (type == CONDITION_TYPE_COLOR_SCALE) {
|
||||
gradient_data = in.readRemainder();
|
||||
color_gradient = new ColorGradientFormatting(in);
|
||||
} else if (type == CONDITION_TYPE_DATA_BAR) {
|
||||
databar_data = in.readRemainder();
|
||||
} else if (type == CONDITION_TYPE_FILTER) {
|
||||
@ -261,7 +262,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord {
|
||||
|
||||
byte type = getConditionType();
|
||||
if (type == CONDITION_TYPE_COLOR_SCALE) {
|
||||
out.write(gradient_data);
|
||||
color_gradient.serialize(out);
|
||||
} else if (type == CONDITION_TYPE_DATA_BAR) {
|
||||
out.write(databar_data);
|
||||
} else if (type == CONDITION_TYPE_FILTER) {
|
||||
@ -285,7 +286,7 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord {
|
||||
|
||||
byte type = getConditionType();
|
||||
if (type == CONDITION_TYPE_COLOR_SCALE) {
|
||||
len += gradient_data.length;
|
||||
len += color_gradient.getDataLength();
|
||||
} else if (type == CONDITION_TYPE_DATA_BAR) {
|
||||
len += databar_data.length;
|
||||
} else if (type == CONDITION_TYPE_FILTER) {
|
||||
@ -319,9 +320,11 @@ public final class CFRule12Record extends CFRuleBase implements FutureRecord {
|
||||
buffer.append(" .priority =").append(priority).append("\n");
|
||||
buffer.append(" .template_type =").append(template_type).append("\n");
|
||||
buffer.append(" .template_params=").append(HexDump.toHex(template_params)).append("\n");
|
||||
buffer.append(" .gradient_data =").append(HexDump.toHex(gradient_data)).append("\n");
|
||||
buffer.append(" .databar_data =").append(HexDump.toHex(databar_data)).append("\n");
|
||||
buffer.append(" .filter_data =").append(HexDump.toHex(filter_data)).append("\n");
|
||||
if (color_gradient != null) {
|
||||
buffer.append(color_gradient);
|
||||
}
|
||||
if (multistate != null) {
|
||||
buffer.append(multistate);
|
||||
}
|
||||
|
@ -0,0 +1,134 @@
|
||||
/* ====================================================================
|
||||
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.hssf.record.cf;
|
||||
|
||||
import org.apache.poi.util.BitField;
|
||||
import org.apache.poi.util.BitFieldFactory;
|
||||
import org.apache.poi.util.LittleEndianInput;
|
||||
import org.apache.poi.util.LittleEndianOutput;
|
||||
import org.apache.poi.util.POILogFactory;
|
||||
import org.apache.poi.util.POILogger;
|
||||
|
||||
/**
|
||||
* Color Gradient / Color Scale Conditional Formatting Rule Record.
|
||||
* (Called Color Gradient in the file format docs, but more commonly
|
||||
* Color Scale in the UI)
|
||||
*/
|
||||
public final class ColorGradientFormatting implements Cloneable {
|
||||
private static POILogger log = POILogFactory.getLogger(ColorGradientFormatting.class);
|
||||
|
||||
private byte options = 0;
|
||||
private Threshold[] thresholds;
|
||||
private byte[] colors; // TODO Decode
|
||||
|
||||
private static BitField clamp = BitFieldFactory.getInstance(0x01);
|
||||
private static BitField background = BitFieldFactory.getInstance(0x02);
|
||||
|
||||
public ColorGradientFormatting() {
|
||||
options = 3;
|
||||
thresholds = new Threshold[3];
|
||||
}
|
||||
public ColorGradientFormatting(LittleEndianInput in) {
|
||||
in.readShort(); // Ignored
|
||||
in.readByte(); // Reserved
|
||||
int numI = in.readByte();
|
||||
int numG = in.readByte();
|
||||
if (numI != numG) {
|
||||
log.log(POILogger.WARN, "Inconsistent Color Gradient defintion, found " + numI + " vs " + numG + " entries");
|
||||
}
|
||||
options = in.readByte();
|
||||
|
||||
// TODO Are these correct?
|
||||
thresholds = new Threshold[numI];
|
||||
for (int i=0; i<thresholds.length; i++) {
|
||||
thresholds[i] = new Threshold(in);
|
||||
in.readDouble(); // Rather pointless value...
|
||||
}
|
||||
// TODO Decode colors
|
||||
colors = new byte[in.available()];
|
||||
in.readFully(colors);
|
||||
}
|
||||
|
||||
public Threshold[] getThresholds() {
|
||||
return thresholds;
|
||||
}
|
||||
public void setThresholds(Threshold[] thresholds) {
|
||||
this.thresholds = thresholds;
|
||||
}
|
||||
|
||||
// TODO Colors
|
||||
|
||||
public boolean isClampToCurve() {
|
||||
return getOptionFlag(clamp);
|
||||
}
|
||||
public boolean isAppliesToBackground() {
|
||||
return getOptionFlag(background);
|
||||
}
|
||||
private boolean getOptionFlag(BitField field) {
|
||||
int value = field.getValue(options);
|
||||
return value==0 ? false : true;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.append(" [Color Gradient Formatting]\n");
|
||||
buffer.append(" .clamp = ").append(isClampToCurve()).append("\n");
|
||||
buffer.append(" .background= ").append(isAppliesToBackground()).append("\n");
|
||||
for (Threshold t : thresholds) {
|
||||
buffer.append(t.toString());
|
||||
}
|
||||
buffer.append(" [/Color Gradient Formatting]\n");
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
public Object clone() {
|
||||
ColorGradientFormatting rec = new ColorGradientFormatting();
|
||||
rec.options = options;
|
||||
rec.thresholds = new Threshold[thresholds.length];
|
||||
System.arraycopy(thresholds, 0, rec.thresholds, 0, thresholds.length);
|
||||
// TODO Colors
|
||||
return rec;
|
||||
}
|
||||
|
||||
public int getDataLength() {
|
||||
int len = 6;
|
||||
for (Threshold t : thresholds) {
|
||||
len += t.getDataLength();
|
||||
len += 8;
|
||||
}
|
||||
len += colors.length;
|
||||
return len;
|
||||
}
|
||||
|
||||
public void serialize(LittleEndianOutput out) {
|
||||
out.writeShort(0);
|
||||
out.writeByte(0);
|
||||
out.writeByte(thresholds.length);
|
||||
out.writeByte(thresholds.length);
|
||||
out.writeByte(options);
|
||||
|
||||
double step = 1d / (thresholds.length-1);
|
||||
for (int i=0; i<thresholds.length; i++) {
|
||||
Threshold t = thresholds[i];
|
||||
t.serialize(out);
|
||||
out.writeDouble(step*i);
|
||||
}
|
||||
|
||||
out.write(colors);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user