#58217 - XSLF: support alpha channel on solid colors (fill, line, text)

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1745101 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2016-05-22 23:58:07 +00:00
parent dae1a761fd
commit 592f22882f
6 changed files with 175 additions and 84 deletions

View File

@ -36,58 +36,60 @@ public enum PresetColor {
// default colors for theme-depending colors taken from ... (last post):
// https://social.technet.microsoft.com/Forums/windows/en-US/ac76cc56-6ff2-4778-b260-8141d7170a3b/windows-7-highlight-text-color-or-selected-text-color-in-aero
// see ST_SystemColorVal for system color names
/** The system-defined color of the active window's border. */
ActiveBorder (0xffb4b4b4, 1, null),
ActiveBorder (0xffb4b4b4, 1, "activeBorder"),
/** The system-defined color of the background of the active window's title bar. */
ActiveCaption (0xff99b4d1, 2, null),
ActiveCaption (0xff99b4d1, 2, "activeCaption"),
/** The system-defined color of the text in the active window's title bar. */
ActiveCaptionText (0xff000000, 3, null),
ActiveCaptionText (0xff000000, 3, "captionText"),
/** The application workspace is the area in a multiple-document view that is not being occupied by documents. */
AppWorkspace (0xffababab, 4, null),
AppWorkspace (0xffababab, 4, "appWorkspace"),
/** The system-defined face color of a 3-D element. */
Control (0xfff0f0f0, 5, null),
Control (0xfff0f0f0, 5, "btnFace"),
/** The system-defined shadow color of a 3-D element. The shadow color is applied to parts of a 3-D element that face away from the light source. */
ControlDark (0xff696969, 6, null),
ControlDark (0xff696969, 6, "btnShadow"),
/** The system-defined color that is the dark shadow color of a 3-D element. The dark shadow color is applied to the parts of a 3-D element that are the darkest color. */
ControlDarkDark (0xff000000, 7, null),
ControlDarkDark (0xff000000, 7, "3dDkShadow"),
/** The system-defined color that is the light color of a 3-D element. The light color is applied to parts of a 3-D element that face the light source. */
ControlLight (0xffe3e3e3, 8, null),
ControlLight (0xffe3e3e3, 8, "btnHighlight"),
/** The system-defined highlight color of a 3-D element. The highlight color is applied to the parts of a 3-D element that are the lightest color. */
ControlLightLight (0xffe3e3e3, 9, null),
ControlLightLight (0xffe3e3e3, 9, "3dLight"),
/** The system-defined color of text in a 3-D element. */
ControlText (0xff000000, 10, null),
ControlText (0xff000000, 10, "btnText"),
/** The system-defined color of the desktop. */
Desktop (0xff000000, 11, null),
Desktop (0xff000000, 11, "background"),
/** The system-defined color of dimmed text. Items in a list that are disabled are displayed in dimmed text. */
GrayText (0xff6d6d6d, 12, null),
GrayText (0xff6d6d6d, 12, "grayText"),
/** The system-defined color of the background of selected items. This includes selected menu items as well as selected text. */
Highlight (0xff3399ff, 13, null),
Highlight (0xff3399ff, 13, "highlight"),
/** The system-defined color of the text of selected items. */
HighlightText (0xffffffff, 14, null),
HighlightText (0xffffffff, 14, "highlightText"),
/** The system-defined color used to designate a hot-tracked item. Single-clicking a hot-tracked item executes the item. */
HotTrack (0xff0066cc, 15, null),
HotTrack (0xff0066cc, 15, "hotLight"),
/** The system-defined color of an inactive window's border. */
InactiveBorder (0xfff4f7fc, 16, null),
InactiveBorder (0xfff4f7fc, 16, "inactiveBorder"),
/** The system-defined color of the background of an inactive window's title bar. */
InactiveCaption (0xffbfcddb, 17, null),
InactiveCaption (0xffbfcddb, 17, "inactiveCaption"),
/** The system-defined color of the text in an inactive window's title bar. */
InactiveCaptionText (0xff000000, 18, null),
InactiveCaptionText (0xff000000, 18, "inactiveCaptionText"),
/** The system-defined color of the background of a ToolTip. */
Info (0xffffffe1, 19, null),
Info (0xffffffe1, 19, "infoBk"),
/** The system-defined color of the text of a ToolTip. */
InfoText (0xff000000, 20, null),
InfoText (0xff000000, 20, "infoText"),
/** The system-defined color of a menu's background. */
Menu (0xfff0f0f0, 21, null),
Menu (0xfff0f0f0, 21, "menu"),
/** The system-defined color of a menu's text. */
MenuText (0xff000000, 22, null),
MenuText (0xff000000, 22, "menuText"),
/** The system-defined color of the background of a scroll bar. */
ScrollBar (0xffc8c8c8, 23, null),
ScrollBar (0xffc8c8c8, 23, "scrollBar"),
/** The system-defined color of the background in the client area of a window. */
Window (0xffffffff, 24, null),
Window (0xffffffff, 24, "window"),
/** The system-defined color of a window frame. */
WindowFrame (0xff646464, 25, null),
WindowFrame (0xff646464, 25, "windowFrame"),
/** The system-defined color of the text in the client area of a window. */
WindowText (0xff000000, 26, null),
WindowText (0xff000000, 26, "windowText"),
Transparent (0x00ffffff, 27, null),
AliceBlue (0xfff0f8ff, 28, "aliceBlue"),
AntiqueWhite (0xfffaebd7, 29, "antiqueWhite"),
@ -236,13 +238,13 @@ public enum PresetColor {
/** The system-defined color that is the shadow color of a 3-D element. This color is applied to parts of a 3-D element that face away from the light source. */
ButtonShadow (0xffa0a0a0, 170, null),
/** The system-defined color of the lightest color in the color gradient of an active window's title bar. */
GradientActiveCaption (0xffb9d1ea, 171, null),
GradientActiveCaption (0xffb9d1ea, 171, "gradientActiveCaption"),
/** The system-defined color of the lightest color in the color gradient of an inactive window's title bar. */
GradientInactiveCaption (0xffd7e4f2, 172, null),
GradientInactiveCaption (0xffd7e4f2, 172, "gradientInactiveCaption"),
/** The system-defined color of the background of a menu bar. */
MenuBar (0xfff0f0f0, 173, null),
MenuBar (0xfff0f0f0, 173, "menuBar"),
/** The system-defined color used to highlight menu items when the menu appears as a flat menu. */
MenuHighlight (0xff3399ff, 174, null)
MenuHighlight (0xff3399ff, 174, "menuHighlight")
;
public Color color;

View File

@ -25,6 +25,8 @@ import org.apache.poi.sl.usermodel.ColorStyle;
import org.apache.poi.sl.usermodel.PresetColor;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Internal;
import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTHslColor;
@ -32,17 +34,18 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTScRgbColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSystemColor;
import org.w3c.dom.Node;
/**
* Encapsulates logic to read color definitions from DrawingML and convert them to java.awt.Color
*
* @author Yegor Kozlov
*/
@Beta
@Internal
public class XSLFColor {
private static POILogger LOGGER = POILogFactory.getLogger(XSLFColor.class);
private XmlObject _xmlObject;
private Color _color;
private CTSchemeColor _phClr;
@ -156,10 +159,14 @@ public class XSLFColor {
byte[] val = sys.getLastClr();
color = new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]);
} else {
// YK: color is a string like "menuText" or "windowText", we return black for such cases
@SuppressWarnings("unused")
String colorName = sys.getVal().toString();
color = Color.black;
PresetColor pc = PresetColor.valueOfOoxmlId(colorName);
if (pc != null) {
color = pc.color;
}
if (color == null) {
color = Color.black;
}
}
} else {
throw new IllegalArgumentException("Unexpected color choice: " + ch.getClass());
@ -168,6 +175,60 @@ public class XSLFColor {
return color;
}
/**
* Sets the solid color
*
* @param color solid color
*/
@Internal
protected void setColor(Color color) {
if (!(_xmlObject instanceof CTSolidColorFillProperties)) {
LOGGER.log(POILogger.ERROR, "XSLFColor.setColor currently only supports CTSolidColorFillProperties");
return;
}
CTSolidColorFillProperties fill = (CTSolidColorFillProperties)_xmlObject;
if (fill.isSetSrgbClr()) {
fill.unsetSrgbClr();
}
CTSRgbColor rgb = fill.addNewSrgbClr();
float[] rgbaf = color.getRGBComponents(null);
int r = color.getRed(), g = color.getGreen(), b = color.getBlue();
if (rgbaf[0]*255f == r && rgbaf[1]*255f == g && rgbaf[2]*255f == b) {
rgb.setVal(new byte[]{(byte)r, (byte)g, (byte)b });
} else {
rgb.addNewRed().setVal((int)(100000 * rgbaf[0]));
rgb.addNewGreen().setVal((int)(100000 * rgbaf[1]));
rgb.addNewBlue().setVal((int)(100000 * rgbaf[2]));
}
// alpha (%)
if (rgbaf.length == 4 && rgbaf[3] < 1f) {
rgb.addNewAlpha().setVal((int)(100000 * rgbaf[3]));
}
if (fill.isSetHslClr()) {
fill.unsetHslClr();
}
if (fill.isSetPrstClr()) {
fill.unsetPrstClr();
}
if (fill.isSetSchemeClr()) {
fill.unsetSchemeClr();
}
if (fill.isSetScrgbClr()) {
fill.unsetScrgbClr();
}
if (fill.isSetSysClr()) {
fill.unsetSysClr();
}
}
private int getRawValue(String elem) {
String query = "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' $this//a:" + elem;

View File

@ -59,7 +59,6 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetLineDashProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle;
@ -218,25 +217,31 @@ public abstract class XSLFSimpleShape extends XSLFShape
*/
public void setLineColor(Color color) {
CTShapeProperties spPr = getSpPr();
CTLineProperties ln = spPr.getLn();
if (color == null) {
if (spPr.isSetLn() && spPr.getLn().isSetSolidFill())
spPr.getLn().unsetSolidFill();
if (ln == null) {
return;
}
if (ln.isSetSolidFill()) {
ln.unsetSolidFill();
}
if (!ln.isSetNoFill()) {
ln.addNewNoFill();
}
} else {
CTLineProperties ln = spPr.isSetLn() ? spPr.getLn() : spPr
.addNewLn();
if (ln == null) {
ln = spPr.addNewLn();
}
if (ln.isSetNoFill()) {
ln.unsetNoFill();
}
CTSolidColorFillProperties fill = ln.isSetSolidFill() ? ln.getSolidFill() : ln.addNewSolidFill();
CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();
rgb.setVal(new byte[]{(byte) color.getRed(),
(byte) color.getGreen(), (byte) color.getBlue()});
CTSolidColorFillProperties fill = ln.isSetSolidFill() ? ln
.getSolidFill() : ln.addNewSolidFill();
fill.setSrgbClr(rgb);
if(fill.isSetHslClr()) fill.unsetHslClr();
if(fill.isSetPrstClr()) fill.unsetPrstClr();
if(fill.isSetSchemeClr()) fill.unsetSchemeClr();
if(fill.isSetScrgbClr()) fill.unsetScrgbClr();
if(fill.isSetSysClr()) fill.unsetSysClr();
XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr());
col.setColor(color);
}
}
@ -548,25 +553,22 @@ public abstract class XSLFSimpleShape extends XSLFShape
public void setFillColor(Color color) {
CTShapeProperties spPr = getSpPr();
if (color == null) {
if (spPr.isSetSolidFill()) spPr.unsetSolidFill();
if (spPr.isSetSolidFill()) {
spPr.unsetSolidFill();
}
if (!spPr.isSetNoFill()) spPr.addNewNoFill();
if (!spPr.isSetNoFill()) {
spPr.addNewNoFill();
}
} else {
if (spPr.isSetNoFill()) spPr.unsetNoFill();
if (spPr.isSetNoFill()) {
spPr.unsetNoFill();
}
CTSolidColorFillProperties fill = spPr.isSetSolidFill() ? spPr
.getSolidFill() : spPr.addNewSolidFill();
CTSRgbColor rgb = CTSRgbColor.Factory.newInstance();
rgb.setVal(new byte[]{(byte) color.getRed(),
(byte) color.getGreen(), (byte) color.getBlue()});
fill.setSrgbClr(rgb);
if(fill.isSetHslClr()) fill.unsetHslClr();
if(fill.isSetPrstClr()) fill.unsetPrstClr();
if(fill.isSetSchemeClr()) fill.unsetSchemeClr();
if(fill.isSetScrgbClr()) fill.unsetScrgbClr();
if(fill.isSetSysClr()) fill.unsetSysClr();
CTSolidColorFillProperties fill = spPr.isSetSolidFill() ? spPr.getSolidFill() : spPr.addNewSolidFill();
XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr());
col.setColor(color);
}
}

View File

@ -96,19 +96,13 @@ public class XSLFTextRun implements TextRun {
throw new IllegalArgumentException("Currently only SolidPaint is supported!");
}
SolidPaint sp = (SolidPaint)color;
Color c = DrawPaint.applyColorTransform(sp.getSolidColor());
CTTextCharacterProperties rPr = getRPr();
CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? rPr.getSolidFill() : rPr.addNewSolidFill();
CTSRgbColor clr = fill.isSetSrgbClr() ? fill.getSrgbClr() : fill.addNewSrgbClr();
Color c = DrawPaint.applyColorTransform(sp.getSolidColor());
clr.setVal(new byte[]{(byte)c.getRed(), (byte)c.getGreen(), (byte)c.getBlue()});
if(fill.isSetHslClr()) fill.unsetHslClr();
if(fill.isSetPrstClr()) fill.unsetPrstClr();
if(fill.isSetSchemeClr()) fill.unsetSchemeClr();
if(fill.isSetScrgbClr()) fill.unsetScrgbClr();
if(fill.isSetSysClr()) fill.unsetSysClr();
XSLFColor col = new XSLFColor(fill, getParentParagraph().getParentShape().getSheet().getTheme(), fill.getSchemeClr());
col.setColor(c);
}
@Override

View File

@ -16,9 +16,9 @@
==================================================================== */
package org.apache.poi.xslf;
import static junit.framework.TestCase.assertEquals;
import static org.apache.poi.POITestCase.assertContains;
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@ -40,11 +40,14 @@ import javax.imageio.ImageIO;
import org.apache.poi.POIDataSamples;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLDocumentPart.RelationPart;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.sl.usermodel.PictureData.PictureType;
import org.apache.poi.sl.usermodel.ShapeType;
import org.apache.poi.xslf.usermodel.DrawingParagraph;
import org.apache.poi.xslf.usermodel.DrawingTextBody;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFAutoShape;
import org.apache.poi.xslf.usermodel.XSLFHyperlink;
import org.apache.poi.xslf.usermodel.XSLFPictureData;
import org.apache.poi.xslf.usermodel.XSLFPictureShape;
@ -472,4 +475,28 @@ public class TestXSLFBugs {
ppt2.close();
}
@Test
public void bug58217() throws IOException {
XMLSlideShow ppt1 = new XMLSlideShow();
XSLFSlide sl = ppt1.createSlide();
XSLFAutoShape as = sl.createAutoShape();
as.setShapeType(ShapeType.STAR_10);
as.setAnchor(new Rectangle2D.Double(100,100,300,300));
as.setFillColor(new Color(1f,1f,0f,0.1f));
as.setLineColor(new Color(1f,1f,0f,0.4f));
as.setText("Alpha");
as.getTextParagraphs().get(0).getTextRuns().get(0).setFontColor(new Color(1f,1f,0f,0.6f));
XMLSlideShow ppt2 = XSLFTestDataSamples.writeOutAndReadBack(ppt1);
ppt1.close();
sl = ppt2.getSlides().get(0);
as = (XSLFAutoShape)sl.getShapes().get(0);
SolidPaint ps = (SolidPaint)as.getFillStyle().getPaint();
assertEquals(10000, ps.getSolidColor().getAlpha());
ps = (SolidPaint)as.getStrokeStyle().getPaint();
assertEquals(40000, ps.getSolidColor().getAlpha());
ps = (SolidPaint)as.getTextParagraphs().get(0).getTextRuns().get(0).getFontColor();
assertEquals(60000, ps.getSolidColor().getAlpha());
ppt2.close();
}
}

View File

@ -17,7 +17,7 @@
package org.apache.poi.xslf.usermodel;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.awt.Color;
import java.io.IOException;
@ -154,9 +154,14 @@ public class TestXSLFColor {
for(PresetColor pc : PresetColor.values()) {
if (pc.ooxmlId == null) continue;
xml = CTColor.Factory.newInstance();
STPresetColorVal.Enum val = STPresetColorVal.Enum.forString(pc.ooxmlId);
assertNotNull(pc.ooxmlId, val);
xml.addNewPrstClr().setVal(val);
STPresetColorVal.Enum preVal = STPresetColorVal.Enum.forString(pc.ooxmlId);
STSystemColorVal.Enum sysVal = STSystemColorVal.Enum.forString(pc.ooxmlId);
assertTrue(pc.ooxmlId, preVal != null || sysVal != null);
if (preVal != null) {
xml.addNewPrstClr().setVal(preVal);
} else {
xml.addNewSysClr().setVal(sysVal);
}
color = new XSLFColor(xml, null, null);
assertEquals(pc.color, color.getColor());
}
@ -166,7 +171,7 @@ public class TestXSLFColor {
public void testSys() {
CTColor xml = CTColor.Factory.newInstance();
CTSystemColor sys = xml.addNewSysClr();
sys.setVal(STSystemColorVal.GRAY_TEXT);
sys.setVal(STSystemColorVal.CAPTION_TEXT);
XSLFColor color = new XSLFColor(xml, null, null);
assertEquals(Color.black, color.getColor());