#64088 - SlideShow rendering fixes

git-svn-id: https://svn.apache.org/repos/asf/poi/trunk@1872984 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Andreas Beeker 2020-01-19 20:44:36 +00:00
parent 5927fd37f2
commit 0fb322bb92
22 changed files with 580 additions and 345 deletions

View File

@ -245,6 +245,9 @@ public class BitmapImageRenderer implements ImageRenderer {
double h_old = img.getHeight(); double h_old = img.getHeight();
double w_new = dim.getWidth(); double w_new = dim.getWidth();
double h_new = dim.getHeight(); double h_new = dim.getHeight();
if (w_old == w_new && h_old == h_new) {
return img;
}
BufferedImage scaled = new BufferedImage((int)w_new, (int)h_new, BufferedImage.TYPE_INT_ARGB); BufferedImage scaled = new BufferedImage((int)w_new, (int)h_new, BufferedImage.TYPE_INT_ARGB);
AffineTransform at = new AffineTransform(); AffineTransform at = new AffineTransform();
at.scale(w_new/w_old, h_new/h_old); at.scale(w_new/w_old, h_new/h_old);

View File

@ -22,7 +22,10 @@ import static org.apache.poi.sl.draw.geom.ArcToCommand.convertOoxml2AwtAngle;
import java.awt.Color; import java.awt.Color;
import java.awt.Graphics2D; import java.awt.Graphics2D;
import java.awt.LinearGradientPaint; import java.awt.LinearGradientPaint;
import java.awt.MultipleGradientPaint.ColorSpaceType;
import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.Paint; import java.awt.Paint;
import java.awt.Point;
import java.awt.RadialGradientPaint; import java.awt.RadialGradientPaint;
import java.awt.Shape; import java.awt.Shape;
import java.awt.geom.AffineTransform; import java.awt.geom.AffineTransform;
@ -30,15 +33,24 @@ import java.awt.geom.Dimension2D;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D; import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.awt.image.DirectColorModel;
import java.awt.image.Raster;
import java.awt.image.WritableRaster;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.stream.Stream;
import org.apache.poi.sl.usermodel.AbstractColorStyle; import org.apache.poi.sl.usermodel.AbstractColorStyle;
import org.apache.poi.sl.usermodel.ColorStyle; import org.apache.poi.sl.usermodel.ColorStyle;
import org.apache.poi.sl.usermodel.Insets2D;
import org.apache.poi.sl.usermodel.PaintStyle; import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.FlipMode; import org.apache.poi.sl.usermodel.PaintStyle.FlipMode;
import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint; import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;
@ -214,6 +226,9 @@ public class DrawPaint {
} }
private int scale(int value, PaintModifier lessModifier, PaintModifier moreModifier) { private int scale(int value, PaintModifier lessModifier, PaintModifier moreModifier) {
if (value == -1) {
return -1;
}
int delta = (modifier == lessModifier ? 20000 : (modifier == moreModifier ? 40000 : 0)); int delta = (modifier == lessModifier ? 20000 : (modifier == moreModifier ? 40000 : 0));
return Math.min(100000, Math.max(0,value)+delta); return Math.min(100000, Math.max(0,value)+delta);
} }
@ -227,6 +242,8 @@ public class DrawPaint {
switch (fill.getGradientType()) { switch (fill.getGradientType()) {
case linear: case linear:
return createLinearGradientPaint(fill, graphics); return createLinearGradientPaint(fill, graphics);
case rectangular:
// TODO: implement rectangular gradient fill
case circular: case circular:
return createRadialGradientPaint(fill, graphics); return createRadialGradientPaint(fill, graphics);
case shape: case shape:
@ -314,6 +331,8 @@ public class DrawPaint {
image = img; image = img;
} }
image = colorizePattern(fill, image);
Shape s = (Shape)graphics.getRenderingHint(Drawable.GRADIENT_SHAPE); Shape s = (Shape)graphics.getRenderingHint(Drawable.GRADIENT_SHAPE);
// TODO: check why original bitmaps scale/behave differently to vector based images // TODO: check why original bitmaps scale/behave differently to vector based images
@ -324,6 +343,49 @@ public class DrawPaint {
} }
} }
/**
* In case a duotone element is specified, handle image as pattern and replace its color values
* with the corresponding percentile / linear value between fore- and background color
*
* @return the original image if no duotone was found, otherwise the colorized pattern
*/
private static BufferedImage colorizePattern(TexturePaint fill, BufferedImage pattern) {
List<ColorStyle> duoTone = fill.getDuoTone();
if (duoTone == null || duoTone.size() != 2) {
return pattern;
}
// the pattern image is actually a gray scale image, so we simply take the first color component
// as an index into our gradient samples
int blendShades = 1 << pattern.getSampleModel().getSampleSize(0);
int[] gradSample = linearBlendedColors(duoTone, blendShades);
int[] redSample = pattern.getRaster().getSamples(0, 0, pattern.getWidth(), pattern.getHeight(), 0, (int[])null);
for (int i=0; i<redSample.length; i++) {
redSample[i] = gradSample[redSample[i] & 0xFF];
}
DirectColorModel dcm = new DirectColorModel(32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000);
DataBufferInt dbi = new DataBufferInt(redSample, redSample.length);
WritableRaster raster = Raster.createPackedRaster(dbi, pattern.getWidth(), pattern.getHeight(), pattern.getWidth(), new int[]{0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000}, new Point());
return new BufferedImage(dcm, raster, true, null);
}
private static int[] linearBlendedColors(List<ColorStyle> duoTone, final int blendShades) {
Color[] colors = duoTone.stream().map(DrawPaint::applyColorTransform).toArray(Color[]::new);
float[] fractions = { 0, 1 };
// create lookup list of blended colors of back- and foreground
BufferedImage gradBI = new BufferedImage(blendShades, 1, BufferedImage.TYPE_INT_ARGB);
Graphics2D gradG = gradBI.createGraphics();
gradG.setPaint(new LinearGradientPaint(0,0, blendShades,0, fractions, colors));
gradG.fillRect(0,0, blendShades,1);
gradG.dispose();
return gradBI.getRGB(0, 0, blendShades, 1, null, 0, blendShades);
}
/** /**
* Convert color transformations in {@link ColorStyle} to a {@link Color} instance * Convert color transformations in {@link ColorStyle} to a {@link Color} instance
* *
@ -341,7 +403,8 @@ public class DrawPaint {
Color result = color.getColor(); Color result = color.getColor();
double alpha = getAlpha(result, color); double alpha = getAlpha(result, color);
double[] hsl = RGB2HSL(result); // values are in the range [0..100] (usually ...) // values are in the range [0..100] (usually ...)
double[] hsl = RGB2HSL(result);
applyHslModOff(hsl, 0, color.getHueMod(), color.getHueOff()); applyHslModOff(hsl, 0, color.getHueMod(), color.getHueOff());
applyHslModOff(hsl, 1, color.getSatMod(), color.getSatOff()); applyHslModOff(hsl, 1, color.getSatMod(), color.getSatOff());
applyHslModOff(hsl, 2, color.getLumMod(), color.getLumOff()); applyHslModOff(hsl, 2, color.getLumMod(), color.getLumOff());
@ -386,16 +449,11 @@ public class DrawPaint {
* @param off the offset adjustment * @param off the offset adjustment
*/ */
private static void applyHslModOff(double[] hsl, int hslPart, int mod, int off) { private static void applyHslModOff(double[] hsl, int hslPart, int mod, int off) {
if (mod == -1) { if (mod != -1) {
mod = 100000; hsl[hslPart] *= mod / 100_000d;
} }
if (off == -1) { if (off != -1) {
off = 0; hsl[hslPart] += off / 1000d;
}
if (!(mod == 100000 && off == 0)) {
double fOff = off / 1000d;
double fMod = mod / 100000d;
hsl[hslPart] = hsl[hslPart]*fMod+fOff;
} }
} }
@ -410,9 +468,8 @@ public class DrawPaint {
return; return;
} }
double shadePct = shade / 100000.; double shadePct = shade / 100_000.;
hsl[2] *= shadePct;
hsl[2] *= 1. - shadePct;
} }
/** /**
@ -423,13 +480,23 @@ public class DrawPaint {
*/ */
private static void applyTint(double[] hsl, ColorStyle fc) { private static void applyTint(double[] hsl, ColorStyle fc) {
int tint = fc.getTint(); int tint = fc.getTint();
if (tint == -1) { if (tint == -1 || tint == 0) {
return; return;
} }
// see 18.8.19 fgColor (Foreground Color) // see 18.8.19 fgColor (Foreground Color)
double tintPct = tint / 100000.; double tintPct = tint / 100_000.;
hsl[2] = hsl[2]*(1.-tintPct) + (100.-100.*(1.-tintPct));
// The tint value is stored as a double from -1.0 .. 1.0, where -1.0 means 100% darken
// and 1.0 means 100% lighten. Also, 0.0 means no change.
if (tintPct < 0) {
// Lum = Lum * (1.0 + tint)
hsl[2] *= (1 + tintPct);
} else {
// Lum = Lum * (1.0-tint) + (HLSMAX HLSMAX * (1.0-tint))
hsl[2] = hsl[2]*(1-tintPct) + (100-100*(1-tintPct));
}
} }
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
@ -444,6 +511,9 @@ public class DrawPaint {
} }
Rectangle2D anchor = DrawShape.getAnchor(graphics, shape); Rectangle2D anchor = DrawShape.getAnchor(graphics, shape);
if (anchor == null) {
return TRANSPARENT;
}
angle = convertOoxml2AwtAngle(-angle, anchor.getWidth(), anchor.getHeight()); angle = convertOoxml2AwtAngle(-angle, anchor.getWidth(), anchor.getHeight());
@ -467,12 +537,50 @@ public class DrawPaint {
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
protected Paint createRadialGradientPaint(GradientPaint fill, Graphics2D graphics) { protected Paint createRadialGradientPaint(GradientPaint fill, Graphics2D graphics) {
Rectangle2D anchor = DrawShape.getAnchor(graphics, shape); Rectangle2D anchor = DrawShape.getAnchor(graphics, shape);
if (anchor == null) {
return TRANSPARENT;
}
final Point2D pCenter = new Point2D.Double(anchor.getCenterX(), anchor.getCenterY()); Insets2D insets = fill.getFillToInsets();
if (insets == null) {
insets = new Insets2D(0,0,0,0);
}
// TODO: handle negative width/height
final Point2D pCenter = new Point2D.Double(
anchor.getCenterX(), anchor.getCenterY()
);
final Point2D pFocus = new Point2D.Double(
getCenterVal(anchor.getMinX(), anchor.getMaxX(), insets.left, insets.right),
getCenterVal(anchor.getMinY(), anchor.getMaxY(), insets.top, insets.bottom)
);
final float radius = (float)Math.max(anchor.getWidth(), anchor.getHeight()); final float radius = (float)Math.max(anchor.getWidth(), anchor.getHeight());
return safeFractions((f,c)->new RadialGradientPaint(pCenter,radius,f,c), fill); final AffineTransform at = new AffineTransform();
at.translate(pFocus.getX(), pFocus.getY());
at.scale(
getScale(anchor.getMinX(), anchor.getMaxX(), insets.left, insets.right),
getScale(anchor.getMinY(), anchor.getMaxY(), insets.top, insets.bottom)
);
at.translate(-pFocus.getX(), -pFocus.getY());
return safeFractions((f,c)->new RadialGradientPaint(pCenter, radius, pFocus, f, c, CycleMethod.NO_CYCLE, ColorSpaceType.SRGB, at), fill);
}
private static double getScale(double absMin, double absMax, double relMin, double relMax) {
double absDelta = absMax-absMin;
double absStart = absMin+absDelta*relMin;
double absStop = (relMin+relMax <= 1) ? absMax-absDelta*relMax : absMax+absDelta*relMax;
return (absDelta == 0) ? 1 : (absStop-absStart)/absDelta;
}
private static double getCenterVal(double absMin, double absMax, double relMin, double relMax) {
double absDelta = absMax-absMin;
double absStart = absMin+absDelta*relMin;
double absStop = (relMin+relMax <= 1) ? absMax-absDelta*relMax : absMax+absDelta*relMax;
return absStart+(absStop-absStart)/2.;
} }
@SuppressWarnings({"WeakerAccess", "unused"}) @SuppressWarnings({"WeakerAccess", "unused"})
@ -483,29 +591,25 @@ public class DrawPaint {
} }
private Paint safeFractions(BiFunction<float[],Color[],Paint> init, GradientPaint fill) { private Paint safeFractions(BiFunction<float[],Color[],Paint> init, GradientPaint fill) {
float[] fractions = fill.getGradientFractions(); // if style is null, use transparent color to get color of background
final ColorStyle[] styles = fill.getGradientColors(); final Iterator<Color> styles = Stream.of(fill.getGradientColors())
.map(s -> s == null ? TRANSPARENT : applyColorTransform(s))
.iterator();
// need to remap the fractions, because Java doesn't like repeating fraction values // need to remap the fractions, because Java doesn't like repeating fraction values
Map<Float,Color> m = new TreeMap<>(); Map<Float,Color> m = new TreeMap<>();
for (int i = 0; i<fractions.length; i++) { for (float fraction : fill.getGradientFractions()) {
// if fc is null, use transparent color to get color of background m.put(fraction, styles.next());
m.put(fractions[i], (styles[i] == null ? TRANSPARENT : applyColorTransform(styles[i])));
} }
final Color[] colors = new Color[m.size()]; return init.apply(toArray(m.keySet()), m.values().toArray(new Color[0]));
if (fractions.length != m.size()) {
fractions = new float[m.size()];
} }
int i=0; private static float[] toArray(Collection<Float> floatList) {
for (Map.Entry<Float,Color> me : m.entrySet()) { int[] idx = { 0 };
fractions[i] = me.getKey(); float[] ret = new float[floatList.size()];
colors[i] = me.getValue(); floatList.forEach(f -> ret[idx[0]++] = f);
i++; return ret;
}
return init.apply(fractions, colors);
} }
/** /**

View File

@ -20,7 +20,7 @@ package org.apache.poi.sl.usermodel;
import java.awt.geom.Dimension2D; import java.awt.geom.Dimension2D;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.io.InputStream; import java.io.InputStream;
import java.util.List;
public interface PaintStyle { public interface PaintStyle {
@ -87,7 +87,7 @@ public interface PaintStyle {
} }
interface GradientPaint extends PaintStyle { interface GradientPaint extends PaintStyle {
enum GradientType { linear, circular, shape } enum GradientType { linear, circular, rectangular, shape }
/** /**
* @return the angle of the gradient * @return the angle of the gradient
@ -97,6 +97,10 @@ public interface PaintStyle {
float[] getGradientFractions(); float[] getGradientFractions();
boolean isRotatedWithShape(); boolean isRotatedWithShape();
GradientType getGradientType(); GradientType getGradientType();
default Insets2D getFillToInsets() {
return null;
}
} }
interface TexturePaint extends PaintStyle { interface TexturePaint extends PaintStyle {
@ -170,5 +174,14 @@ public interface PaintStyle {
default Insets2D getStretch() { default Insets2D getStretch() {
return null; return null;
} }
/**
* For pattern images, the duo tone defines the black/white pixel color replacement
*/
default List<ColorStyle> getDuoTone() {
return null;
}
} }
} }

View File

@ -106,7 +106,7 @@ public class XSLFBackground extends XSLFSimpleShape
CTSolidColorFillProperties fill = bgPr.isSetSolidFill() ? bgPr.getSolidFill() : bgPr.addNewSolidFill(); CTSolidColorFillProperties fill = bgPr.isSetSolidFill() ? bgPr.getSolidFill() : bgPr.addNewSolidFill();
XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr()); XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr(), getSheet());
col.setColor(color); col.setColor(color);
} }
} }

View File

@ -19,6 +19,9 @@
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 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;
@ -52,11 +55,13 @@ public class XSLFColor {
private XmlObject _xmlObject; private XmlObject _xmlObject;
private Color _color; private Color _color;
private CTSchemeColor _phClr; private CTSchemeColor _phClr;
private XSLFSheet _sheet;
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
public XSLFColor(XmlObject obj, XSLFTheme theme, CTSchemeColor phClr) { public XSLFColor(XmlObject obj, XSLFTheme theme, CTSchemeColor phClr, XSLFSheet sheet) {
_xmlObject = obj; _xmlObject = obj;
_phClr = phClr; _phClr = phClr;
_sheet = sheet;
_color = toColor(obj, theme); _color = toColor(obj, theme);
} }
@ -74,117 +79,88 @@ public class XSLFColor {
return DrawPaint.applyColorTransform(getColorStyle()); return DrawPaint.applyColorTransform(getColorStyle());
} }
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
public ColorStyle getColorStyle() { public ColorStyle getColorStyle() {
return new AbstractColorStyle() { return new XSLFColorStyle(_xmlObject, _color, _phClr);
@Override
public Color getColor() {
return _color;
} }
@Override private Color toColor(CTHslColor hsl) {
public int getAlpha() { return DrawPaint.HSL2RGB(
return getRawValue("alpha"); hsl.getHue2() / 60000d,
hsl.getSat2() / 1000d,
hsl.getLum2() / 1000d,
1d);
} }
@Override private Color toColor(CTPresetColor prst) {
public int getHueOff() {
return getRawValue("hueOff");
}
@Override
public int getHueMod() {
return getRawValue("hueMod");
}
@Override
public int getSatOff() {
return getRawValue("satOff");
}
@Override
public int getSatMod() {
return getRawValue("satMod");
}
@Override
public int getLumOff() {
return getRawValue("lumOff");
}
@Override
public int getLumMod() {
return getRawValue("lumMod");
}
@Override
public int getShade() {
return getRawValue("shade");
}
@Override
public int getTint() {
return getRawValue("tint");
}
};
}
private Color toColor(XmlObject obj, XSLFTheme theme) {
Color color = null;
for (XmlObject ch : obj.selectPath("*")) {
if (ch instanceof CTHslColor) {
CTHslColor hsl = (CTHslColor)ch;
int h = hsl.getHue2();
int s = hsl.getSat2();
int l = hsl.getLum2();
color = DrawPaint.HSL2RGB(h / 60000d, s / 1000d, l / 1000d, 1d);
} else if (ch instanceof CTPresetColor) {
CTPresetColor prst = (CTPresetColor)ch;
String colorName = prst.getVal().toString(); String colorName = prst.getVal().toString();
PresetColor pc = PresetColor.valueOfOoxmlId(colorName); PresetColor pc = PresetColor.valueOfOoxmlId(colorName);
if (pc != null) { return (pc != null) ? pc.color : null;
color = pc.color;
} }
} else if (ch instanceof CTSchemeColor) {
CTSchemeColor schemeColor = (CTSchemeColor)ch; private Color toColor(CTSchemeColor schemeColor, XSLFTheme theme) {
String colorRef = schemeColor.getVal().toString(); String colorRef = schemeColor.getVal().toString();
if(_phClr != null) { if(_phClr != null) {
// context color overrides the theme // context color overrides the theme
colorRef = _phClr.getVal().toString(); colorRef = _phClr.getVal().toString();
} }
// find referenced CTColor in the theme and convert it to java.awt.Color via a recursive call // find referenced CTColor in the theme and convert it to java.awt.Color via a recursive call
CTColor ctColor = theme == null ? null : theme.getCTColor(colorRef); CTColor ctColor = theme == null ? null : theme.getCTColor(_sheet.mapSchemeColor(colorRef));
if(ctColor != null) { return (ctColor != null) ? toColor(ctColor, null) : null;
color = toColor(ctColor, null);
} }
} else if (ch instanceof CTScRgbColor) {
private Color toColor(CTScRgbColor scrgb) {
// color in percentage is in linear RGB color space, i.e. needs to be gamma corrected for AWT color // color in percentage is in linear RGB color space, i.e. needs to be gamma corrected for AWT color
CTScRgbColor scrgb = (CTScRgbColor)ch; return new Color(DrawPaint.lin2srgb(scrgb.getR()), DrawPaint.lin2srgb(scrgb.getG()), DrawPaint.lin2srgb(scrgb.getB()));
color = new Color(DrawPaint.lin2srgb(scrgb.getR()), DrawPaint.lin2srgb(scrgb.getG()), DrawPaint.lin2srgb(scrgb.getB())); }
} else if (ch instanceof CTSRgbColor) {
private Color toColor(CTSRgbColor srgb) {
// color in sRGB color space, i.e. same as AWT Color // color in sRGB color space, i.e. same as AWT Color
CTSRgbColor srgb = (CTSRgbColor)ch;
byte[] val = srgb.getVal(); byte[] val = srgb.getVal();
color = new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]); return new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]);
} else if (ch instanceof CTSystemColor) { }
CTSystemColor sys = (CTSystemColor)ch;
if(sys.isSetLastClr()) { private Color toColor(CTSystemColor sys) {
if (sys.isSetLastClr()) {
byte[] val = sys.getLastClr(); byte[] val = sys.getLastClr();
color = new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]); return new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]);
} else { } else {
String colorName = sys.getVal().toString(); String colorName = sys.getVal().toString();
PresetColor pc = PresetColor.valueOfOoxmlId(colorName); PresetColor pc = PresetColor.valueOfOoxmlId(colorName);
if (pc != null) { return (pc != null && pc.color != null) ? pc.color : Color.black;
color = pc.color;
}
if (color == null) {
color = Color.black;
} }
} }
private Color toColor(XmlObject obj, XSLFTheme theme) {
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)) { } else if (!(ch instanceof CTFontReference)) {
if (!isFirst) {
throw new IllegalArgumentException("Unexpected color choice: " + ch.getClass()); throw new IllegalArgumentException("Unexpected color choice: " + ch.getClass());
} }
} }
if (color != null) {
break;
}
isFirst = false;
}
return color; return color;
} }
@ -257,14 +233,14 @@ public class XSLFColor {
return Math.abs((f*255d) - Math.rint(f*255d)) < 0.00001; return Math.abs((f*255d) - Math.rint(f*255d)) < 0.00001;
} }
private int getRawValue(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; String query = "declare namespace a='http://schemas.openxmlformats.org/drawingml/2006/main' $this//a:" + elem;
XmlObject[] obj; XmlObject[] obj;
// first ask the context color and if not found, ask the actual color bean // first ask the context color and if not found, ask the actual color bean
if (_phClr != null){ if (phClr != null){
obj = _phClr.selectPath(query); obj = phClr.selectPath(query);
if (obj.length == 1){ if (obj.length == 1){
Node attr = obj[0].getDomNode().getAttributes().getNamedItem("val"); Node attr = obj[0].getDomNode().getAttributes().getNamedItem("val");
if(attr != null) { if(attr != null) {
@ -273,7 +249,7 @@ public class XSLFColor {
} }
} }
obj = _xmlObject.selectPath(query); obj = xmlObject.selectPath(query);
if (obj.length == 1){ if (obj.length == 1){
Node attr = obj[0].getDomNode().getAttributes().getNamedItem("val"); Node attr = obj[0].getDomNode().getAttributes().getNamedItem("val");
if(attr != null) { if(attr != null) {
@ -294,7 +270,7 @@ public class XSLFColor {
* @return the percentage value in the range [0 .. 100] * @return the percentage value in the range [0 .. 100]
*/ */
private int getPercentageValue(String elem){ private int getPercentageValue(String elem){
int val = getRawValue(elem); int val = getRawValue(_phClr, _xmlObject, elem);
return (val == -1) ? val : (val / 1000); return (val == -1) ? val : (val / 1000);
} }
@ -333,7 +309,7 @@ public class XSLFColor {
@SuppressWarnings("unused") @SuppressWarnings("unused")
int getHue(){ int getHue(){
int val = getRawValue("hue"); int val = getRawValue(_phClr, _xmlObject, "hue");
return (val == -1) ? val : (val / 60000); return (val == -1) ? val : (val / 60000);
} }
@ -500,4 +476,66 @@ public class XSLFColor {
public int getTint(){ public int getTint(){
return getPercentageValue("tint"); return getPercentageValue("tint");
} }
private static class XSLFColorStyle extends AbstractColorStyle {
private XmlObject xmlObject;
private Color color;
private CTSchemeColor phClr;
XSLFColorStyle(XmlObject xmlObject, Color color, CTSchemeColor phClr) {
this.xmlObject = xmlObject;
this.color = color;
this.phClr = phClr;
}
@Override
public Color getColor() {
return color;
}
@Override
public int getAlpha() {
return getRawValue(phClr, xmlObject, "alpha");
}
@Override
public int getHueOff() {
return getRawValue(phClr, xmlObject, "hueOff");
}
@Override
public int getHueMod() {
return getRawValue(phClr, xmlObject, "hueMod");
}
@Override
public int getSatOff() {
return getRawValue(phClr, xmlObject, "satOff");
}
@Override
public int getSatMod() {
return getRawValue(phClr, xmlObject, "satMod");
}
@Override
public int getLumOff() {
return getRawValue(phClr, xmlObject, "lumOff");
}
@Override
public int getLumMod() {
return getRawValue(phClr, xmlObject, "lumMod");
}
@Override
public int getShade() {
return getRawValue(phClr, xmlObject, "shade");
}
@Override
public int getTint() {
return getRawValue(phClr, xmlObject, "tint");
}
}
} }

View File

@ -20,10 +20,12 @@ package org.apache.poi.xslf.usermodel;
import java.util.Arrays; import java.util.Arrays;
import org.apache.poi.sl.usermodel.ColorStyle; import org.apache.poi.sl.usermodel.ColorStyle;
import org.apache.poi.sl.usermodel.Insets2D;
import org.apache.poi.sl.usermodel.PaintStyle; import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientFillProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientStop; import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientStop;
import org.openxmlformats.schemas.drawingml.x2006.main.CTRelativeRect;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
import org.openxmlformats.schemas.drawingml.x2006.main.STPathShadeType; import org.openxmlformats.schemas.drawingml.x2006.main.STPathShadeType;
@ -34,7 +36,7 @@ public class XSLFGradientPaint implements PaintStyle.GradientPaint {
final ColorStyle[] cs; final ColorStyle[] cs;
final float[] fractions; final float[] fractions;
public XSLFGradientPaint(final CTGradientFillProperties gradFill, CTSchemeColor phClr, final XSLFTheme theme) { public XSLFGradientPaint(final CTGradientFillProperties gradFill, CTSchemeColor phClr, final XSLFTheme theme, final XSLFSheet sheet) {
this.gradFill = gradFill; this.gradFill = gradFill;
final CTGradientStop[] gs = gradFill.getGsLst() == null ? final CTGradientStop[] gs = gradFill.getGsLst() == null ?
@ -55,7 +57,7 @@ public class XSLFGradientPaint implements PaintStyle.GradientPaint {
if (phClrCgs == null && cgs.isSetSchemeClr()) { if (phClrCgs == null && cgs.isSetSchemeClr()) {
phClrCgs = cgs.getSchemeClr(); phClrCgs = cgs.getSchemeClr();
} }
cs[i] = new XSLFColor(cgs, theme, phClrCgs).getColorStyle(); cs[i] = new XSLFColor(cgs, theme, phClrCgs, sheet).getColorStyle();
fractions[i] = cgs.getPos() / 100000.f; fractions[i] = cgs.getPos() / 100000.f;
i++; i++;
} }
@ -98,10 +100,21 @@ public class XSLFGradientPaint implements PaintStyle.GradientPaint {
return PaintStyle.GradientPaint.GradientType.circular; return PaintStyle.GradientPaint.GradientType.circular;
} else if (ps == STPathShadeType.SHAPE) { } else if (ps == STPathShadeType.SHAPE) {
return PaintStyle.GradientPaint.GradientType.shape; return PaintStyle.GradientPaint.GradientType.shape;
} else if (ps == STPathShadeType.RECT) {
return PaintStyle.GradientPaint.GradientType.rectangular;
} }
} }
return PaintStyle.GradientPaint.GradientType.linear; return PaintStyle.GradientPaint.GradientType.linear;
} }
@Override
public Insets2D getFillToInsets() {
if (gradFill.isSetPath() && gradFill.getPath().isSetFillToRect()) {
final double base = 100_000;
CTRelativeRect rect = gradFill.getPath().getFillToRect();
return new Insets2D(rect.getT()/base, rect.getL()/base, rect.getB()/base, rect.getR()/base);
}
return null;
}
} }

View File

@ -40,7 +40,6 @@ implements Notes<XSLFShape,XSLFTextParagraph> {
* Create a new notes * Create a new notes
*/ */
XSLFNotes() { XSLFNotes() {
super();
_notes = prototype(); _notes = prototype();
} }
@ -105,4 +104,9 @@ implements Notes<XSLFShape,XSLFTextParagraph> {
} }
return tp; return tp;
} }
@Override
String mapSchemeColor(String schemeColor) {
return mapSchemeColor(_notes.getClrMapOvr(), schemeColor);
}
} }

View File

@ -26,7 +26,6 @@ import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.sl.usermodel.MasterSheet; import org.apache.poi.sl.usermodel.MasterSheet;
import org.apache.poi.util.Beta; import org.apache.poi.util.Beta;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMapping;
import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesMaster; import org.openxmlformats.schemas.presentationml.x2006.main.CTNotesMaster;
import org.openxmlformats.schemas.presentationml.x2006.main.NotesMasterDocument; import org.openxmlformats.schemas.presentationml.x2006.main.NotesMasterDocument;
@ -106,7 +105,8 @@ import org.openxmlformats.schemas.presentationml.x2006.main.NotesMasterDocument;
} }
@Override @Override
CTColorMapping getColorMapping() { String mapSchemeColor(String schemeColor) {
return _slide.getClrMap(); String notesMasterColor = mapSchemeColor(_slide.getClrMap(), schemeColor);
return notesMasterColor == null ? schemeColor : notesMasterColor;
} }
} }

View File

@ -100,7 +100,7 @@ public class XSLFShadow extends XSLFShape implements Shadow<XSLFShape,XSLFTextPa
if(ct == null) return null; if(ct == null) return null;
CTSchemeColor phClr = ct.getSchemeClr(); CTSchemeColor phClr = ct.getSchemeClr();
final XSLFColor xc = new XSLFColor(ct, theme, phClr); final XSLFColor xc = new XSLFColor(ct, theme, phClr, getSheet());
return DrawPaint.createSolidPaint(xc.getColorStyle()); return DrawPaint.createSolidPaint(xc.getColorStyle());
} }
} }

View File

@ -144,7 +144,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
if (shape instanceof XSLFPictureShape) { if (shape instanceof XSLFPictureShape) {
CTPicture pic = (CTPicture)shape.getXmlObject(); CTPicture pic = (CTPicture)shape.getXmlObject();
if (pic.getBlipFill() != null) { if (pic.getBlipFill() != null) {
setValue(selectPaint(pic.getBlipFill(), pp)); setValue(selectPaint(pic.getBlipFill(), pp, null, theme));
return true; return true;
} }
} }
@ -360,13 +360,13 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
* @return the applied Paint or null if none was applied * @return the applied Paint or null if none was applied
*/ */
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
protected static PaintStyle selectPaint(XSLFFillProperties fp, final CTSchemeColor phClr, final PackagePart parentPart, final XSLFTheme theme, boolean hasPlaceholder) { protected PaintStyle selectPaint(XSLFFillProperties fp, final CTSchemeColor phClr, final PackagePart parentPart, final XSLFTheme theme, boolean hasPlaceholder) {
if (fp == null || fp.isSetNoFill()) { if (fp == null || fp.isSetNoFill()) {
return null; return null;
} else if (fp.isSetSolidFill()) { } else if (fp.isSetSolidFill()) {
return selectPaint(fp.getSolidFill(), phClr, theme); return selectPaint(fp.getSolidFill(), phClr, theme);
} else if (fp.isSetBlipFill()) { } else if (fp.isSetBlipFill()) {
return selectPaint(fp.getBlipFill(), parentPart); return selectPaint(fp.getBlipFill(), parentPart, phClr, theme);
} else if (fp.isSetGradFill()) { } else if (fp.isSetGradFill()) {
return selectPaint(fp.getGradFill(), phClr, theme); return selectPaint(fp.getGradFill(), phClr, theme);
} else if (fp.isSetMatrixStyle()) { } else if (fp.isSetMatrixStyle()) {
@ -377,7 +377,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
} }
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
protected static PaintStyle selectPaint(CTSolidColorFillProperties solidFill, CTSchemeColor phClr, final XSLFTheme theme) { protected PaintStyle selectPaint(CTSolidColorFillProperties solidFill, CTSchemeColor phClr, final XSLFTheme theme) {
if (solidFill.isSetSchemeClr()) { if (solidFill.isSetSchemeClr()) {
// if there's a reference to the placeholder color, // if there's a reference to the placeholder color,
// stop evaluating further and let the caller select // stop evaluating further and let the caller select
@ -389,22 +389,22 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
phClr = solidFill.getSchemeClr(); phClr = solidFill.getSchemeClr();
} }
} }
final XSLFColor c = new XSLFColor(solidFill, theme, phClr); final XSLFColor c = new XSLFColor(solidFill, theme, phClr, _sheet);
return DrawPaint.createSolidPaint(c.getColorStyle()); return DrawPaint.createSolidPaint(c.getColorStyle());
} }
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
protected static PaintStyle selectPaint(final CTBlipFillProperties blipFill, final PackagePart parentPart) { protected PaintStyle selectPaint(final CTBlipFillProperties blipFill, final PackagePart parentPart, CTSchemeColor phClr, final XSLFTheme theme) {
return new XSLFTexturePaint(blipFill, parentPart); return new XSLFTexturePaint(blipFill, parentPart, phClr, theme, _sheet);
} }
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
protected static PaintStyle selectPaint(final CTGradientFillProperties gradFill, CTSchemeColor phClr, final XSLFTheme theme) { protected PaintStyle selectPaint(final CTGradientFillProperties gradFill, CTSchemeColor phClr, final XSLFTheme theme) {
return new XSLFGradientPaint(gradFill, phClr, theme); return new XSLFGradientPaint(gradFill, phClr, theme, _sheet);
} }
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
protected static PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme, boolean isLineStyle, boolean hasPlaceholder) { protected PaintStyle selectPaint(CTStyleMatrixReference fillRef, final XSLFTheme theme, boolean isLineStyle, boolean hasPlaceholder) {
if (fillRef == null) { if (fillRef == null) {
return null; return null;
} }
@ -441,7 +441,7 @@ public abstract class XSLFShape implements Shape<XSLFShape,XSLFTextParagraph> {
if (res != null || hasPlaceholder) { if (res != null || hasPlaceholder) {
return res; return res;
} }
XSLFColor col = new XSLFColor(fillRef, theme, phClr); XSLFColor col = new XSLFColor(fillRef, theme, phClr, _sheet);
return DrawPaint.createSolidPaint(col.getColorStyle()); return DrawPaint.createSolidPaint(col.getColorStyle());
} }

View File

@ -29,7 +29,6 @@ import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Optional;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
@ -60,6 +59,8 @@ import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions; import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl; import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMapping; import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMapping;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMappingOverride;
import org.openxmlformats.schemas.drawingml.x2006.main.STColorSchemeIndex;
import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector; import org.openxmlformats.schemas.presentationml.x2006.main.CTConnector;
import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame; import org.openxmlformats.schemas.presentationml.x2006.main.CTGraphicalObjectFrame;
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape; import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
@ -497,15 +498,11 @@ implements XSLFShapeContainer, Sheet<XSLFShape,XSLFTextParagraph> {
return _theme; return _theme;
} }
final Optional<XSLFTheme> t = getRelations().stream()
getRelations().stream().filter((p) -> p instanceof XSLFTheme).map((p) -> (XSLFTheme) p).findAny(); .filter(p -> p instanceof XSLFTheme)
if (t.isPresent()) { .findAny()
_theme = t.get(); .ifPresent(p -> _theme = (XSLFTheme)p);
final CTColorMapping cmap = getColorMapping();
if (cmap != null) {
_theme.initColorMap(cmap);
}
}
return _theme; return _theme;
} }
@ -521,7 +518,7 @@ implements XSLFShapeContainer, Sheet<XSLFShape,XSLFTextParagraph> {
/** /**
* @return the color mapping for this slide type * @return the color mapping for this slide type
*/ */
CTColorMapping getColorMapping() { String mapSchemeColor(String schemeColor) {
return null; return null;
} }
@ -744,4 +741,60 @@ implements XSLFShapeContainer, Sheet<XSLFShape,XSLFTextParagraph> {
getDrawing().addChart(rp.getRelationship().getId(), rect2D); getDrawing().addChart(rp.getRelationship().getId(), rect2D);
} }
protected String mapSchemeColor(CTColorMappingOverride cmapOver, String schemeColor) {
String slideColor = mapSchemeColor((cmapOver == null) ? null : cmapOver.getOverrideClrMapping(), schemeColor);
if (slideColor != null) {
return slideColor;
}
XSLFSheet master = (XSLFSheet)getMasterSheet();
String masterColor = (master == null) ? null : master.mapSchemeColor(schemeColor);
return (masterColor == null) ? schemeColor : masterColor;
}
protected String mapSchemeColor(CTColorMapping cmap, String schemeColor) {
STColorSchemeIndex.Enum schemeMap = null;
if (cmap != null && schemeColor != null) {
switch (schemeColor) {
case "accent1":
schemeMap = cmap.getAccent1();
break;
case "accent2":
schemeMap = cmap.getAccent2();
break;
case "accent3":
schemeMap = cmap.getAccent3();
break;
case "accent4":
schemeMap = cmap.getAccent4();
break;
case "accent5":
schemeMap = cmap.getAccent5();
break;
case "accent6":
schemeMap = cmap.getAccent6();
break;
case "bg1":
schemeMap = cmap.getBg1();
break;
case "bg2":
schemeMap = cmap.getBg2();
break;
case "folHlink":
schemeMap = cmap.getFolHlink();
break;
case "hlink":
schemeMap = cmap.getHlink();
break;
case "tx1":
schemeMap = cmap.getTx1();
break;
case "tx2":
schemeMap = cmap.getTx2();
break;
default:
break;
}
}
return (schemeMap == null) ? null : schemeMap.toString();
}
} }

View File

@ -51,33 +51,7 @@ import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFEffectProperties
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties; import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties;
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFGeometryProperties; import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFGeometryProperties;
import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBaseStyles; import org.openxmlformats.schemas.drawingml.x2006.main.*;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleItem;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGeomGuide;
import org.openxmlformats.schemas.drawingml.x2006.main.CTLineEndProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTLineStyleList;
import org.openxmlformats.schemas.drawingml.x2006.main.CTNonVisualDrawingProps;
import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect;
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.CTSchemeColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties;
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.CTTransform2D;
import org.openxmlformats.schemas.drawingml.x2006.main.STCompoundLine;
import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;
import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndLength;
import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndType;
import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndWidth;
import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;
import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType;
/** /**
* Represents a single (non-group) shape in a .pptx slide show * Represents a single (non-group) shape in a .pptx slide show
@ -291,7 +265,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
ln.addNewNoFill(); ln.addNewNoFill();
} else { } else {
CTSolidColorFillProperties fill = ln.addNewSolidFill(); CTSolidColorFillProperties fill = ln.addNewSolidFill();
XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr()); XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr(), getSheet());
col.setColor(color); col.setColor(color);
} }
} }
@ -664,7 +638,7 @@ public abstract class XSLFSimpleShape extends XSLFShape
CTSolidColorFillProperties fill = fp.isSetSolidFill() ? fp.getSolidFill() : fp.addNewSolidFill(); CTSolidColorFillProperties fill = fp.isSetSolidFill() ? fp.getSolidFill() : fp.addNewSolidFill();
XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr()); XSLFColor col = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr(), getSheet());
col.setColor(color); col.setColor(color);
} }
} }

View File

@ -24,6 +24,7 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.poi.ooxml.POIXMLDocumentPart; import org.apache.poi.ooxml.POIXMLDocumentPart;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.sl.draw.DrawFactory; import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.Drawable; import org.apache.poi.sl.draw.Drawable;
@ -31,7 +32,6 @@ import org.apache.poi.sl.usermodel.Notes;
import org.apache.poi.sl.usermodel.Placeholder; import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.Slide; import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.util.Beta; import org.apache.poi.util.Beta;
import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.util.NotImplemented; import org.apache.poi.util.NotImplemented;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;
@ -403,4 +403,9 @@ implements Slide<XSLFShape,XSLFTextParagraph> {
final CTCommonSlideData cSld = getXmlObject().getCSld(); final CTCommonSlideData cSld = getXmlObject().getCSld();
return cSld.isSetName() ? cSld.getName() : "Slide"+getSlideNumber(); return cSld.isSetName() ? cSld.getName() : "Slide"+getSlideNumber();
} }
@Override
String mapSchemeColor(String schemeColor) {
return mapSchemeColor(_slide.getClrMapOvr(), schemeColor);
}
} }

View File

@ -145,4 +145,10 @@ implements MasterSheet<XSLFShape,XSLFTextParagraph> {
int ordinal = _layout.getType().intValue() - 1; int ordinal = _layout.getType().intValue() - 1;
return SlideLayout.values()[ordinal]; return SlideLayout.values()[ordinal];
} }
@Override
String mapSchemeColor(String schemeColor) {
return mapSchemeColor(_layout.getClrMapOvr(), schemeColor);
}
} }

View File

@ -29,7 +29,6 @@ import org.apache.poi.sl.usermodel.MasterSheet;
import org.apache.poi.sl.usermodel.Placeholder; import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.util.Beta; import org.apache.poi.util.Beta;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMapping;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle; import org.openxmlformats.schemas.drawingml.x2006.main.CTTextListStyle;
import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground; import org.openxmlformats.schemas.presentationml.x2006.main.CTBackground;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMaster; import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMaster;
@ -169,7 +168,8 @@ import org.openxmlformats.schemas.presentationml.x2006.main.SldMasterDocument;
} }
@Override @Override
CTColorMapping getColorMapping() { String mapSchemeColor(String schemeColor) {
return _slide.getClrMap(); String masterColor = mapSchemeColor(_slide.getClrMap(), schemeColor);
return masterColor == null ? schemeColor : masterColor;
} }
} }

View File

@ -37,33 +37,7 @@ import org.apache.poi.xddf.usermodel.text.XDDFTextBody;
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties; import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties;
import org.apache.poi.xslf.usermodel.XSLFTableStyle.TablePartStyle; import org.apache.poi.xslf.usermodel.XSLFTableStyle.TablePartStyle;
import org.apache.xmlbeans.XmlObject; import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.drawingml.x2006.main.CTFontReference; import org.openxmlformats.schemas.drawingml.x2006.main.*;
import org.openxmlformats.schemas.drawingml.x2006.main.CTLineEndProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTLineProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPoint2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveSize2D;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSolidColorFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTable;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCell;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableCellProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTablePartStyle;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableStyleCellStyle;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTableStyleTextStyle;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextBody;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTextParagraph;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTransform2D;
import org.openxmlformats.schemas.drawingml.x2006.main.STCompoundLine;
import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap;
import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndLength;
import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndType;
import org.openxmlformats.schemas.drawingml.x2006.main.STLineEndWidth;
import org.openxmlformats.schemas.drawingml.x2006.main.STOnOffStyleType;
import org.openxmlformats.schemas.drawingml.x2006.main.STPenAlignment;
import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextAnchoringType;
import org.openxmlformats.schemas.drawingml.x2006.main.STTextVerticalType;
/** /**
* Represents a cell of a table in a .pptx presentation * Represents a cell of a table in a .pptx presentation
@ -319,7 +293,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
CTLineProperties ln = setBorderDefaults(edge); CTLineProperties ln = setBorderDefaults(edge);
CTSolidColorFillProperties fill = ln.addNewSolidFill(); CTSolidColorFillProperties fill = ln.addNewSolidFill();
XSLFColor c = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr()); XSLFColor c = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr(), getSheet());
c.setColor(color); c.setColor(color);
} }
@ -331,7 +305,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
} }
CTSolidColorFillProperties fill = ln.getSolidFill(); CTSolidColorFillProperties fill = ln.getSolidFill();
XSLFColor c = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr()); XSLFColor c = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr(), getSheet());
return c.getColor(); return c.getColor();
} }
@ -415,7 +389,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
} }
} else { } else {
CTSolidColorFillProperties fill = spPr.isSetSolidFill() ? spPr.getSolidFill() : spPr.addNewSolidFill(); CTSolidColorFillProperties fill = spPr.isSetSolidFill() ? spPr.getSolidFill() : spPr.addNewSolidFill();
XSLFColor c = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr()); XSLFColor c = new XSLFColor(fill, getSheet().getTheme(), fill.getSchemeClr(), getSheet());
c.setColor(color); c.setColor(color);
} }
} }
@ -470,7 +444,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
fp = XSLFPropertiesDelegate.getFillDelegate(props); fp = XSLFPropertiesDelegate.getFillDelegate(props);
if (fp != null) { if (fp != null) {
PaintStyle paint = XSLFShape.selectPaint(fp, null, slideShow.getPackagePart(), theme, hasPlaceholder); PaintStyle paint = selectPaint(fp, null, slideShow.getPackagePart(), theme, hasPlaceholder);
if (paint != null) { if (paint != null) {
return paint; return paint;
} }
@ -758,7 +732,7 @@ public class XSLFTableCell extends XSLFTextShape implements TableCell<XSLFShape,
} }
XSLFTheme theme = getSheet().getTheme(); XSLFTheme theme = getSheet().getTheme();
final XSLFColor c = new XSLFColor(txStyle, theme, phClr); final XSLFColor c = new XSLFColor(txStyle, theme, phClr, getSheet());
return DrawPaint.createSolidPaint(c.getColorStyle()); return DrawPaint.createSolidPaint(c.getColorStyle());
} }

View File

@ -279,7 +279,7 @@ public class XSLFTextParagraph implements TextParagraph<XSLFShape,XSLFTextParagr
@Override @Override
public boolean fetch(CTTextParagraphProperties props){ public boolean fetch(CTTextParagraphProperties props){
if(props.isSetBuClr()){ if(props.isSetBuClr()){
XSLFColor c = new XSLFColor(props.getBuClr(), theme, null); XSLFColor c = new XSLFColor(props.getBuClr(), theme, null, _shape.getSheet());
setValue(c.getColor()); setValue(c.getColor());
return true; return true;
} }

View File

@ -123,7 +123,8 @@ public class XSLFTextRun implements TextRun {
CTTextCharacterProperties rPr = getRPr(true); CTTextCharacterProperties rPr = getRPr(true);
CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? rPr.getSolidFill() : rPr.addNewSolidFill(); CTSolidColorFillProperties fill = rPr.isSetSolidFill() ? rPr.getSolidFill() : rPr.addNewSolidFill();
XSLFColor col = new XSLFColor(fill, getParentParagraph().getParentShape().getSheet().getTheme(), fill.getSchemeClr()); XSLFSheet sheet = getParentParagraph().getParentShape().getSheet();
XSLFColor col = new XSLFColor(fill, sheet.getTheme(), fill.getSchemeClr(), sheet);
col.setColor(c); col.setColor(c);
} }
@ -148,7 +149,7 @@ public class XSLFTextRun implements TextRun {
XSLFSheet sheet = shape.getSheet(); XSLFSheet sheet = shape.getSheet();
PackagePart pp = sheet.getPackagePart(); PackagePart pp = sheet.getPackagePart();
XSLFTheme theme = sheet.getTheme(); XSLFTheme theme = sheet.getTheme();
PaintStyle ps = XSLFShape.selectPaint(fp, phClr, pp, theme, hasPlaceholder); PaintStyle ps = shape.selectPaint(fp, phClr, pp, theme, hasPlaceholder);
if (ps != null) { if (ps != null) {
setValue(ps); setValue(ps);

View File

@ -21,11 +21,14 @@ import java.awt.geom.Dimension2D;
import java.awt.geom.Point2D; import java.awt.geom.Point2D;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.PackagePart; import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.openxml4j.opc.PackageRelationship; import org.apache.poi.openxml4j.opc.PackageRelationship;
import org.apache.poi.sl.usermodel.ColorStyle;
import org.apache.poi.sl.usermodel.Insets2D; import org.apache.poi.sl.usermodel.Insets2D;
import org.apache.poi.sl.usermodel.PaintStyle; import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.util.Dimension2DDouble; import org.apache.poi.util.Dimension2DDouble;
@ -33,7 +36,9 @@ import org.apache.poi.util.Internal;
import org.apache.poi.util.Units; import org.apache.poi.util.Units;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip; import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTBlipFillProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.CTDuotoneEffect;
import org.openxmlformats.schemas.drawingml.x2006.main.CTRelativeRect; import org.openxmlformats.schemas.drawingml.x2006.main.CTRelativeRect;
import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTileInfoProperties; import org.openxmlformats.schemas.drawingml.x2006.main.CTTileInfoProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.STTileFlipMode; import org.openxmlformats.schemas.drawingml.x2006.main.STTileFlipMode;
@ -42,11 +47,17 @@ public class XSLFTexturePaint implements PaintStyle.TexturePaint {
private final CTBlipFillProperties blipFill; private final CTBlipFillProperties blipFill;
private final PackagePart parentPart; private final PackagePart parentPart;
private final CTBlip blip; private final CTBlip blip;
private final CTSchemeColor phClr;
private final XSLFTheme theme;
private final XSLFSheet sheet;
public XSLFTexturePaint(final CTBlipFillProperties blipFill, final PackagePart parentPart) { public XSLFTexturePaint(final CTBlipFillProperties blipFill, final PackagePart parentPart, CTSchemeColor phClr, final XSLFTheme theme, final XSLFSheet sheet) {
this.blipFill = blipFill; this.blipFill = blipFill;
this.parentPart = parentPart; this.parentPart = parentPart;
blip = blipFill.getBlip(); blip = blipFill.getBlip();
this.phClr = phClr;
this.theme = theme;
this.sheet = sheet;
} }
@ -139,6 +150,20 @@ public class XSLFTexturePaint implements PaintStyle.TexturePaint {
return getRectVal(blipFill.isSetStretch() ? blipFill.getStretch().getFillRect() : null); return getRectVal(blipFill.isSetStretch() ? blipFill.getStretch().getFillRect() : null);
} }
@Override
public List<ColorStyle> getDuoTone() {
if (blip.sizeOfDuotoneArray() == 0) {
return null;
}
List<ColorStyle> colors = new ArrayList<>();
CTDuotoneEffect duoEff = blip.getDuotoneArray(0);
for (CTSchemeColor phClrDuo : duoEff.getSchemeClrArray()) {
colors.add(new XSLFColor(phClrDuo, theme, phClr, sheet).getColorStyle());
}
return colors;
}
private static Insets2D getRectVal(CTRelativeRect rect) { private static Insets2D getRectVal(CTRelativeRect rect) {
return rect == null ? null : new Insets2D( return rect == null ? null : new Insets2D(
getRectVal(rect::isSetT, rect::getT), getRectVal(rect::isSetT, rect::getT),

View File

@ -20,8 +20,6 @@ import static org.apache.poi.ooxml.POIXMLTypeLoader.DEFAULT_XML_OPTIONS;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import javax.xml.namespace.QName; import javax.xml.namespace.QName;
@ -30,27 +28,21 @@ import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.util.Beta; import org.apache.poi.util.Beta;
import org.apache.poi.util.Internal; import org.apache.poi.util.Internal;
import org.apache.xmlbeans.XmlException; import org.apache.xmlbeans.XmlException;
import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions; import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBaseStyles; import org.openxmlformats.schemas.drawingml.x2006.main.CTBaseStyles;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColor; import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColorMapping;
import org.openxmlformats.schemas.drawingml.x2006.main.CTColorScheme; import org.openxmlformats.schemas.drawingml.x2006.main.CTColorScheme;
import org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeStyleSheet; import org.openxmlformats.schemas.drawingml.x2006.main.CTOfficeStyleSheet;
import org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument; import org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument;
/** /**
* A shared style sheet in a .pptx slide show * A shared style sheet in a .pptx slide show
*
* @author Yegor Kozlov
*/ */
@Beta @Beta
public class XSLFTheme extends POIXMLDocumentPart { public class XSLFTheme extends POIXMLDocumentPart {
private CTOfficeStyleSheet _theme; private CTOfficeStyleSheet _theme;
private Map<String, CTColor> _schemeColors;
XSLFTheme() { XSLFTheme() {
super();
_theme = CTOfficeStyleSheet.Factory.newInstance(); _theme = CTOfficeStyleSheet.Factory.newInstance();
} }
@ -62,37 +54,11 @@ public class XSLFTheme extends POIXMLDocumentPart {
ThemeDocument doc = ThemeDocument doc =
ThemeDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS); ThemeDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS);
_theme = doc.getTheme(); _theme = doc.getTheme();
initialize();
} }
@SuppressWarnings("WeakerAccess") @SuppressWarnings("WeakerAccess")
public void importTheme(XSLFTheme theme) { public void importTheme(XSLFTheme theme) {
_theme = theme.getXmlObject(); _theme = theme.getXmlObject();
_schemeColors = theme._schemeColors;
}
private void initialize(){
CTBaseStyles elems = _theme.getThemeElements();
CTColorScheme scheme = elems.getClrScheme();
// The color scheme is responsible for defining a list of twelve colors.
_schemeColors = new HashMap<>(12);
for(XmlObject o : scheme.selectPath("*")){
CTColor c = (CTColor)o;
String name = c.getDomNode().getLocalName();
_schemeColors.put(name, c);
}
}
/**
* re-map colors
*
* @param cmap color map defined in the master slide referencing this theme
*/
void initColorMap(CTColorMapping cmap) {
_schemeColors.put("bg1", _schemeColors.get(cmap.getBg1().toString()));
_schemeColors.put("bg2", _schemeColors.get(cmap.getBg2().toString()));
_schemeColors.put("tx1", _schemeColors.get(cmap.getTx1().toString()));
_schemeColors.put("tx2", _schemeColors.get(cmap.getTx2().toString()));
} }
/** /**
@ -118,8 +84,45 @@ public class XSLFTheme extends POIXMLDocumentPart {
* @return a theme color or <code>null</code> if not found * @return a theme color or <code>null</code> if not found
*/ */
@Internal @Internal
public CTColor getCTColor(String name){ public CTColor getCTColor(String name) {
return _schemeColors.get(name); CTBaseStyles elems = _theme.getThemeElements();
CTColorScheme scheme = (elems == null) ? null : elems.getClrScheme();
return getMapColor(name, scheme);
}
private static CTColor getMapColor(String mapName, CTColorScheme scheme) {
if (mapName == null || scheme == null) {
return null;
}
switch (mapName) {
case "accent1":
return scheme.getAccent1();
case "accent2":
return scheme.getAccent2();
case "accent3":
return scheme.getAccent3();
case "accent4":
return scheme.getAccent4();
case "accent5":
return scheme.getAccent5();
case "accent6":
return scheme.getAccent6();
case "dk1":
return scheme.getDk1();
case "dk2":
return scheme.getDk2();
case "folHlink":
return scheme.getFolHlink();
case "hlink":
return scheme.getHlink();
case "lt1":
return scheme.getLt1();
case "lt2":
return scheme.getLt2();
default:
return null;
}
} }
/** /**

View File

@ -40,7 +40,7 @@ public class TestXSLFColor {
CTSRgbColor c = xml.addNewSrgbClr(); CTSRgbColor c = xml.addNewSrgbClr();
c.setVal(new byte[]{(byte)0xFF, 0, 0}); c.setVal(new byte[]{(byte)0xFF, 0, 0});
XSLFColor color = new XSLFColor(xml, null, null); XSLFColor color = new XSLFColor(xml, null, null, null);
assertEquals(-1, color.getAlpha()); assertEquals(-1, color.getAlpha());
c.addNewAlpha().setVal(50000); c.addNewAlpha().setVal(50000);
@ -103,7 +103,7 @@ public class TestXSLFColor {
c.setSat2(100000); c.setSat2(100000);
c.setLum2(50000); c.setLum2(50000);
XSLFColor color = new XSLFColor(xml, null, null); XSLFColor color = new XSLFColor(xml, null, null, null);
assertEquals(Color.BLUE, color.getColor()); assertEquals(Color.BLUE, color.getColor());
} }
@ -112,31 +112,32 @@ public class TestXSLFColor {
CTColor xml = CTColor.Factory.newInstance(); CTColor xml = CTColor.Factory.newInstance();
xml.addNewSrgbClr().setVal(new byte[]{ (byte)0xFF, (byte)0xFF, 0}); xml.addNewSrgbClr().setVal(new byte[]{ (byte)0xFF, (byte)0xFF, 0});
XSLFColor color = new XSLFColor(xml, null, null); XSLFColor color = new XSLFColor(xml, null, null, null);
assertEquals(new Color(0xFF, 0xFF, 0), color.getColor()); assertEquals(new Color(0xFF, 0xFF, 0), color.getColor());
} }
@Test @Test
public void testSchemeColor() throws IOException { public void testSchemeColor() throws IOException {
XMLSlideShow ppt = new XMLSlideShow(); XMLSlideShow ppt = new XMLSlideShow();
XSLFTheme theme = ppt.createSlide().getTheme(); XSLFSheet slide = ppt.createSlide();
XSLFTheme theme = slide.getTheme();
CTColor xml = CTColor.Factory.newInstance(); CTColor xml = CTColor.Factory.newInstance();
xml.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_2); xml.addNewSchemeClr().setVal(STSchemeColorVal.ACCENT_2);
XSLFColor color = new XSLFColor(xml, theme, null); XSLFColor color = new XSLFColor(xml, theme, null, slide);
// accent2 is theme1.xml is <a:srgbClr val="C0504D"/> // accent2 is theme1.xml is <a:srgbClr val="C0504D"/>
assertEquals(Color.decode("0xC0504D"), color.getColor()); assertEquals(Color.decode("0xC0504D"), color.getColor());
xml = CTColor.Factory.newInstance(); xml = CTColor.Factory.newInstance();
xml.addNewSchemeClr().setVal(STSchemeColorVal.LT_1); xml.addNewSchemeClr().setVal(STSchemeColorVal.LT_1);
color = new XSLFColor(xml, theme, null); color = new XSLFColor(xml, theme, null, slide);
// <a:sysClr val="window" lastClr="FFFFFF"/> // <a:sysClr val="window" lastClr="FFFFFF"/>
assertEquals(Color.decode("0xFFFFFF"), color.getColor()); assertEquals(Color.decode("0xFFFFFF"), color.getColor());
xml = CTColor.Factory.newInstance(); xml = CTColor.Factory.newInstance();
xml.addNewSchemeClr().setVal(STSchemeColorVal.DK_1); xml.addNewSchemeClr().setVal(STSchemeColorVal.DK_1);
color = new XSLFColor(xml, theme, null); color = new XSLFColor(xml, theme, null, slide);
// <a:sysClr val="windowText" lastClr="000000"/> // <a:sysClr val="windowText" lastClr="000000"/>
assertEquals(Color.decode("0x000000"), color.getColor()); assertEquals(Color.decode("0x000000"), color.getColor());
@ -147,7 +148,7 @@ public class TestXSLFColor {
public void testPresetColor() { public void testPresetColor() {
CTColor xml = CTColor.Factory.newInstance(); CTColor xml = CTColor.Factory.newInstance();
xml.addNewPrstClr().setVal(STPresetColorVal.AQUAMARINE); xml.addNewPrstClr().setVal(STPresetColorVal.AQUAMARINE);
XSLFColor color = new XSLFColor(xml, null, null); XSLFColor color = new XSLFColor(xml, null, null, null);
assertEquals(new Color(127, 255, 212), color.getColor()); assertEquals(new Color(127, 255, 212), color.getColor());
@ -162,7 +163,7 @@ public class TestXSLFColor {
} else { } else {
xml.addNewSysClr().setVal(sysVal); xml.addNewSysClr().setVal(sysVal);
} }
color = new XSLFColor(xml, null, null); color = new XSLFColor(xml, null, null, null);
assertEquals(pc.color, color.getColor()); assertEquals(pc.color, color.getColor());
} }
} }
@ -172,13 +173,13 @@ public class TestXSLFColor {
CTColor xml = CTColor.Factory.newInstance(); CTColor xml = CTColor.Factory.newInstance();
CTSystemColor sys = xml.addNewSysClr(); CTSystemColor sys = xml.addNewSysClr();
sys.setVal(STSystemColorVal.CAPTION_TEXT); sys.setVal(STSystemColorVal.CAPTION_TEXT);
XSLFColor color = new XSLFColor(xml, null, null); XSLFColor color = new XSLFColor(xml, null, null, null);
assertEquals(Color.black, color.getColor()); assertEquals(Color.black, color.getColor());
xml = CTColor.Factory.newInstance(); xml = CTColor.Factory.newInstance();
sys = xml.addNewSysClr(); sys = xml.addNewSysClr();
sys.setLastClr(new byte[]{(byte)0xFF, 0, 0}); sys.setLastClr(new byte[]{(byte)0xFF, 0, 0});
color = new XSLFColor(xml, null, null); color = new XSLFColor(xml, null, null, null);
assertEquals(Color.red, color.getColor()); assertEquals(Color.red, color.getColor());
} }
} }

View File

@ -41,7 +41,25 @@ import org.apache.poi.hslf.model.textproperties.TextPFException9;
import org.apache.poi.hslf.model.textproperties.TextProp; import org.apache.poi.hslf.model.textproperties.TextProp;
import org.apache.poi.hslf.model.textproperties.TextPropCollection; import org.apache.poi.hslf.model.textproperties.TextPropCollection;
import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType; import org.apache.poi.hslf.model.textproperties.TextPropCollection.TextPropType;
import org.apache.poi.hslf.record.*; import org.apache.poi.hslf.record.ColorSchemeAtom;
import org.apache.poi.hslf.record.EscherTextboxWrapper;
import org.apache.poi.hslf.record.InteractiveInfo;
import org.apache.poi.hslf.record.MasterTextPropAtom;
import org.apache.poi.hslf.record.OutlineTextRefAtom;
import org.apache.poi.hslf.record.PPDrawing;
import org.apache.poi.hslf.record.RecordContainer;
import org.apache.poi.hslf.record.RecordTypes;
import org.apache.poi.hslf.record.RoundTripHFPlaceholder12;
import org.apache.poi.hslf.record.SlideListWithText;
import org.apache.poi.hslf.record.SlidePersistAtom;
import org.apache.poi.hslf.record.StyleTextProp9Atom;
import org.apache.poi.hslf.record.StyleTextPropAtom;
import org.apache.poi.hslf.record.TextBytesAtom;
import org.apache.poi.hslf.record.TextCharsAtom;
import org.apache.poi.hslf.record.TextHeaderAtom;
import org.apache.poi.hslf.record.TextRulerAtom;
import org.apache.poi.hslf.record.TextSpecInfoAtom;
import org.apache.poi.hslf.record.TxInteractiveInfoAtom;
import org.apache.poi.sl.draw.DrawPaint; import org.apache.poi.sl.draw.DrawPaint;
import org.apache.poi.sl.usermodel.AutoNumberingScheme; import org.apache.poi.sl.usermodel.AutoNumberingScheme;
import org.apache.poi.sl.usermodel.PaintStyle; import org.apache.poi.sl.usermodel.PaintStyle;
@ -141,7 +159,7 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
_byteAtom = tba; _byteAtom = tba;
_charAtom = tca; _charAtom = tca;
this.parentList = parentList; this.parentList = parentList;
_paragraphStyle = new TextPropCollection(1, TextPropType.paragraph); setParagraphStyle(new TextPropCollection(1, TextPropType.paragraph));
} }
/* package */HSLFTextParagraph(HSLFTextParagraph other) { /* package */HSLFTextParagraph(HSLFTextParagraph other) {
@ -152,8 +170,8 @@ public final class HSLFTextParagraph implements TextParagraph<HSLFShape,HSLFText
_sheet = other._sheet; _sheet = other._sheet;
_ruler = other._ruler; _ruler = other._ruler;
shapeId = other.shapeId; shapeId = other.shapeId;
_paragraphStyle = other._paragraphStyle;
parentList = other.parentList; parentList = other.parentList;
setParagraphStyle(other._paragraphStyle);
} }
public void addTextRun(HSLFTextRun run) { public void addTextRun(HSLFTextRun run) {