#64241 - XSLF - Wrong scheme colors used when rendering

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1875499 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2020-03-21 18:25:38 +00:00
parent 8130d2c70f
commit d3de3636cf
4 changed files with 70 additions and 65 deletions

View File

@ -139,13 +139,11 @@ public class DrawSimpleShape extends DrawShape {
} }
protected Paint getFillPaint(Graphics2D graphics) { protected Paint getFillPaint(Graphics2D graphics) {
final PaintStyle ps = getShape().getFillStyle().getPaint();
DrawPaint drawPaint = DrawFactory.getInstance(graphics).getPaint(getShape()); DrawPaint drawPaint = DrawFactory.getInstance(graphics).getPaint(getShape());
return drawPaint.getPaint(graphics, ps); return drawPaint.getPaint(graphics, getShape().getFillStyle().getPaint());
} }
protected Paint getLinePaint(Graphics2D graphics) { protected Paint getLinePaint(Graphics2D graphics) {
final PaintStyle ps = getShape().getFillStyle().getPaint();
DrawPaint drawPaint = DrawFactory.getInstance(graphics).getPaint(getShape()); DrawPaint drawPaint = DrawFactory.getInstance(graphics).getPaint(getShape());
return drawPaint.getPaint(graphics, getShape().getStrokeStyle().getPaint()); return drawPaint.getPaint(graphics, getShape().getStrokeStyle().getPaint());
} }

View File

@ -568,7 +568,7 @@ public class DrawTextParagraph implements Drawable {
text = new StringBuilder(); text = new StringBuilder();
} }
PlaceableShape<?,?> ps = getParagraphShape(); final DrawPaint dp = new DrawPaint(getParagraphShape());
DrawFontManager dfm = DrawFactory.getInstance(graphics).getFontManager(graphics); DrawFontManager dfm = DrawFactory.getInstance(graphics).getFontManager(graphics);
assert(dfm != null); assert(dfm != null);
@ -587,7 +587,7 @@ public class DrawTextParagraph implements Drawable {
int endIndex = text.length(); int endIndex = text.length();
PaintStyle fgPaintStyle = run.getFontColor(); PaintStyle fgPaintStyle = run.getFontColor();
Paint fgPaint = new DrawPaint(ps).getPaint(graphics, fgPaintStyle); Paint fgPaint = dp.getPaint(graphics, fgPaintStyle);
attList.add(new AttributedStringData(TextAttribute.FOREGROUND, fgPaint, beginIndex, endIndex)); attList.add(new AttributedStringData(TextAttribute.FOREGROUND, fgPaint, beginIndex, endIndex));
Double fontSz = run.getFontSize(); Double fontSz = run.getFontSize();

View File

@ -19,9 +19,8 @@
package org.apache.poi.xslf.usermodel; package org.apache.poi.xslf.usermodel;
import java.awt.Color; import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays; import javax.xml.namespace.QName;
import java.util.List;
import org.apache.poi.sl.draw.DrawPaint; import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.AbstractColorStyle; import org.apache.poi.sl.usermodel.AbstractColorStyle;
@ -31,6 +30,7 @@ import org.apache.poi.util.Beta;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;
import org.apache.poi.util.POILogFactory; import org.apache.poi.util.POILogFactory;
import org.apache.poi.util.POILogger; import org.apache.poi.util.POILogger;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColor; import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTFontReference; import org.openxmlformats.schemas.drawingml.x2006.main.CTFontReference;
@ -42,7 +42,6 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTScRgbColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSystemColor; 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 * Encapsulates logic to read color definitions from DrawingML and convert them to java.awt.Color
@ -50,7 +49,8 @@ import org.w3c.dom.Node;
@Beta @Beta
@Internal @Internal
public class XSLFColor { public class XSLFColor {
private final static POILogger LOGGER = POILogFactory.getLogger(XSLFColor.class); private static final POILogger LOGGER = POILogFactory.getLogger(XSLFColor.class);
private static final QName VAL_ATTR = new QName("val");
private XmlObject _xmlObject; private XmlObject _xmlObject;
private Color _color; private Color _color;
@ -133,12 +133,15 @@ public class XSLFColor {
} }
private Color toColor(XmlObject obj, XSLFTheme theme) { private Color toColor(XmlObject obj, XSLFTheme theme) {
if (obj == null) {
return _phClr == null ? null : toColor(_phClr, theme);
}
final XmlCursor cur = obj.newCursor();
Color color = null; Color color = null;
List<XmlObject> xo = new ArrayList<>(); try {
xo.add(obj); XmlObject ch;
xo.addAll(Arrays.asList(obj.selectPath("*"))); for (int idx=0; color == null && (ch = nextObject(obj, cur, idx)) != null; idx++) {
boolean isFirst = true;
for (XmlObject ch : xo) {
if (ch instanceof CTHslColor) { if (ch instanceof CTHslColor) {
color = toColor((CTHslColor)ch); color = toColor((CTHslColor)ch);
} else if (ch instanceof CTPresetColor) { } else if (ch instanceof CTPresetColor) {
@ -151,19 +154,27 @@ public class XSLFColor {
color = toColor((CTSRgbColor)ch); color = toColor((CTSRgbColor)ch);
} else if (ch instanceof CTSystemColor) { } else if (ch instanceof CTSystemColor) {
color = toColor((CTSystemColor)ch); color = toColor((CTSystemColor)ch);
} else if (!(ch instanceof CTFontReference)) { } else if (!(ch instanceof CTFontReference) && idx > 0) {
if (!isFirst) {
throw new IllegalArgumentException("Unexpected color choice: " + ch.getClass()); throw new IllegalArgumentException("Unexpected color choice: " + ch.getClass());
} }
} }
if (color != null) { } finally {
break; cur.dispose();
}
isFirst = false;
} }
return color; return color;
} }
private static XmlObject nextObject(XmlObject obj, XmlCursor cur, int idx) {
switch (idx) {
case 0:
return obj;
case 1:
return cur.toFirstChild() ? cur.getObject() : null;
default:
return cur.toNextSibling() ? cur.getObject() : null;
}
}
/** /**
* Sets the solid color * Sets the solid color
* *
@ -234,29 +245,26 @@ public class XSLFColor {
} }
private static int getRawValue(CTSchemeColor phClr, XmlObject xmlObject, String elem) { private static int getRawValue(CTSchemeColor phClr, XmlObject xmlObject, String elem) {
String query = "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' $this//a:" + elem; for (XmlObject obj : new XmlObject[]{xmlObject,phClr}) {
if (obj == null) {
XmlObject[] obj; continue;
}
// first ask the context color and if not found, ask the actual color bean XmlCursor cur = obj.newCursor();
if (phClr != null){ try {
obj = phClr.selectPath(query); if (!(
if (obj.length == 1){ cur.toChild(XSLFRelation.NS_DRAWINGML, elem) ||
Node attr = obj[0].getDomNode().getAttributes().getNamedItem("val"); (cur.toFirstChild() && cur.toChild(XSLFRelation.NS_DRAWINGML, elem))
if(attr != null) { )) {
return Integer.parseInt(attr.getNodeValue()); continue;
}
String str = cur.getAttributeText(VAL_ATTR);
if (str != null && !"".equals(str)) {
return Integer.parseInt(str);
}
} finally {
cur.dispose();
} }
} }
}
obj = xmlObject.selectPath(query);
if (obj.length == 1){
Node attr = obj[0].getDomNode().getAttributes().getNamedItem("val");
if(attr != null) {
return Integer.parseInt(attr.getNodeValue());
}
}
return -1; return -1;
} }

View File

@ -56,6 +56,7 @@ import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeStyle;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix; import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix;
import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference; import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrixReference;
import org.openxmlformats.schemas.drawingml.x2006.main.STSchemeColorVal;
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties; import org.openxmlformats.schemas.presentationml.x2006.main.CTBackgroundProperties;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture; import org.openxmlformats.schemas.presentationml.x2006.main.CTPicture;
import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder; import org.openxmlformats.schemas.presentationml.x2006.main.CTPlaceholder;
@ -565,25 +566,23 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
return selectPaint(fp.getGradFill(), phClr, theme); return selectPaint(fp.getGradFill(), phClr, theme);
} else if (fp.isSetMatrixStyle()) { } else if (fp.isSetMatrixStyle()) {
return selectPaint(fp.getMatrixStyle(), theme, fp.isLineStyle(), hasPlaceholder); return selectPaint(fp.getMatrixStyle(), theme, fp.isLineStyle(), hasPlaceholder);
} else if (phClr != null) {
return selectPaint(phClr, theme);
} else { } else {
return null; return null;
} }
} }
protected PaintStyle selectPaint(CTSchemeColor phClr, final XSLFTheme theme) {
final XSLFColor c = new XSLFColor(null, theme, phClr, _sheet);
return DrawPaint.createSolidPaint(c.getColorStyle());
}
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
protected PaintStyle selectPaint(CTSolidColorFillProperties solidFill, CTSchemeColor phClr, final XSLFTheme theme) { protected PaintStyle selectPaint(CTSolidColorFillProperties solidFill, CTSchemeColor phClr, final XSLFTheme theme) {
if (solidFill.isSetSchemeClr()) { CTSchemeColor nestedPhClr = solidFill.getSchemeClr();
// if there's a reference to the placeholder color, boolean useNested = nestedPhClr != null && nestedPhClr.getVal() != null && !STSchemeColorVal.PH_CLR.equals(nestedPhClr.getVal());
// stop evaluating further and let the caller select final XSLFColor c = new XSLFColor(solidFill, theme, useNested ? nestedPhClr : phClr, _sheet);
// the next style inheritance level
// if (STSchemeColorVal.PH_CLR.equals(solidFill.getSchemeClr().getVal())) {
// return null;
// }
if (phClr == null) {
phClr = solidFill.getSchemeClr();
}
}
final XSLFColor c = new XSLFColor(solidFill, theme, phClr, _sheet);
return DrawPaint.createSolidPaint(c.getColorStyle()); return DrawPaint.createSolidPaint(c.getColorStyle());
} }