#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) {
final PaintStyle ps = getShape().getFillStyle().getPaint();
DrawPaint drawPaint = DrawFactory.getInstance(graphics).getPaint(getShape());
return drawPaint.getPaint(graphics, ps);
return drawPaint.getPaint(graphics, getShape().getFillStyle().getPaint());
}
protected Paint getLinePaint(Graphics2D graphics) {
final PaintStyle ps = getShape().getFillStyle().getPaint();
DrawPaint drawPaint = DrawFactory.getInstance(graphics).getPaint(getShape());
return drawPaint.getPaint(graphics, getShape().getStrokeStyle().getPaint());
}

View File

@ -568,7 +568,7 @@ public class DrawTextParagraph implements Drawable {
text = new StringBuilder();
}
PlaceableShape<?,?> ps = getParagraphShape();
final DrawPaint dp = new DrawPaint(getParagraphShape());
DrawFontManager dfm = DrawFactory.getInstance(graphics).getFontManager(graphics);
assert(dfm != null);
@ -587,7 +587,7 @@ public class DrawTextParagraph implements Drawable {
int endIndex = text.length();
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));
Double fontSz = run.getFontSize();

View File

@ -19,9 +19,8 @@
package org.apache.poi.xslf.usermodel;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import javax.xml.namespace.QName;
import org.apache.poi.sl.draw.DrawPaint;
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.POILogFactory;
import org.apache.poi.util.POILogger;
import org.apache.xmlbeans.XmlCursor;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
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.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
@ -50,7 +49,8 @@ import org.w3c.dom.Node;
@Beta
@Internal
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 Color _color;
@ -133,37 +133,48 @@ public class XSLFColor {
}
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;
List<XmlObject> xo = new ArrayList<>();
xo.add(obj);
xo.addAll(Arrays.asList(obj.selectPath("*")));
boolean isFirst = true;
for (XmlObject ch : xo) {
if (ch instanceof CTHslColor) {
color = toColor((CTHslColor)ch);
} else if (ch instanceof CTPresetColor) {
color = toColor((CTPresetColor)ch);
} else if (ch instanceof CTSchemeColor) {
color = toColor((CTSchemeColor)ch, theme);
} else if (ch instanceof CTScRgbColor) {
color = toColor((CTScRgbColor)ch);
} else if (ch instanceof CTSRgbColor) {
color = toColor((CTSRgbColor)ch);
} else if (ch instanceof CTSystemColor) {
color = toColor((CTSystemColor)ch);
} else if (!(ch instanceof CTFontReference)) {
if (!isFirst) {
try {
XmlObject ch;
for (int idx=0; color == null && (ch = nextObject(obj, cur, idx)) != null; idx++) {
if (ch instanceof CTHslColor) {
color = toColor((CTHslColor)ch);
} else if (ch instanceof CTPresetColor) {
color = toColor((CTPresetColor)ch);
} else if (ch instanceof CTSchemeColor) {
color = toColor((CTSchemeColor)ch, theme);
} else if (ch instanceof CTScRgbColor) {
color = toColor((CTScRgbColor)ch);
} else if (ch instanceof CTSRgbColor) {
color = toColor((CTSRgbColor)ch);
} else if (ch instanceof CTSystemColor) {
color = toColor((CTSystemColor)ch);
} else if (!(ch instanceof CTFontReference) && idx > 0) {
throw new IllegalArgumentException("Unexpected color choice: " + ch.getClass());
}
}
if (color != null) {
break;
}
isFirst = false;
} finally {
cur.dispose();
}
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
*
@ -234,29 +245,26 @@ public class XSLFColor {
}
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;
XmlObject[] obj;
// first ask the context color and if not found, ask the actual color bean
if (phClr != null){
obj = phClr.selectPath(query);
if (obj.length == 1){
Node attr = obj[0].getDomNode().getAttributes().getNamedItem("val");
if(attr != null) {
return Integer.parseInt(attr.getNodeValue());
for (XmlObject obj : new XmlObject[]{xmlObject,phClr}) {
if (obj == null) {
continue;
}
XmlCursor cur = obj.newCursor();
try {
if (!(
cur.toChild(XSLFRelation.NS_DRAWINGML, elem) ||
(cur.toFirstChild() && cur.toChild(XSLFRelation.NS_DRAWINGML, elem))
)) {
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;
}

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.CTStyleMatrix;
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.CTPicture;
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);
} else if (fp.isSetMatrixStyle()) {
return selectPaint(fp.getMatrixStyle(), theme, fp.isLineStyle(), hasPlaceholder);
} else if (phClr != null) {
return selectPaint(phClr, theme);
} else {
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")
protected PaintStyle selectPaint(CTSolidColorFillProperties solidFill, CTSchemeColor phClr, final XSLFTheme theme) {
if (solidFill.isSetSchemeClr()) {
// if there's a reference to the placeholder color,
// stop evaluating further and let the caller select
// 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);
CTSchemeColor nestedPhClr = solidFill.getSchemeClr();
boolean useNested = nestedPhClr != null && nestedPhClr.getVal() != null && !STSchemeColorVal.PH_CLR.equals(nestedPhClr.getVal());
final XSLFColor c = new XSLFColor(solidFill, theme, useNested ? nestedPhClr : phClr, _sheet);
return DrawPaint.createSolidPaint(c.getColorStyle());
}