public void loadImage(byte[] data, String contentType) throws IOException {
img = readImage(new ByteArrayInputStream(data), contentType);
}
-
+
/**
* Read the image data via ImageIO and optionally try to workaround metadata errors.
* The resulting image is of image type {@link BufferedImage#TYPE_INT_ARGB}
}
try {
-
+
switch (mode) {
case 0:
reader.setInput(iis, false, true);
reader.setInput(iis, false, true);
int height = reader.getHeight(0);
int width = reader.getWidth(0);
-
+
Iterator<ImageTypeSpecifier> imageTypes = reader.getImageTypes(0);
if (imageTypes.hasNext()) {
ImageTypeSpecifier imageTypeSpecifier = imageTypes.next();
img = argbImg;
}
}
- }
+ }
break;
}
}
-
+
} catch (IOException e) {
if (mode < 2) {
lastException = e;
} finally {
iis.close();
}
-
+
// If you don't have an image at the end of all readers
if (img == null) {
if (lastException != null) {
g.dispose();
return argbImg;
}
-
+
return img;
}
}
return 0;
}
-
-
+
+
@Override
public BufferedImage getImage() {
return img;
double h_old = img.getHeight();
double w_new = dim.getWidth();
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);
AffineTransform at = new AffineTransform();
at.scale(w_new/w_old, h_new/h_old);
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.LinearGradientPaint;
+import java.awt.MultipleGradientPaint.ColorSpaceType;
+import java.awt.MultipleGradientPaint.CycleMethod;
import java.awt.Paint;
+import java.awt.Point;
import java.awt.RadialGradientPaint;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
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.InputStream;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.TreeMap;
import java.util.function.BiFunction;
+import java.util.stream.Stream;
import org.apache.poi.sl.usermodel.AbstractColorStyle;
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.FlipMode;
import org.apache.poi.sl.usermodel.PaintStyle.GradientPaint;
}
private int scale(int value, PaintModifier lessModifier, PaintModifier moreModifier) {
+ if (value == -1) {
+ return -1;
+ }
int delta = (modifier == lessModifier ? 20000 : (modifier == moreModifier ? 40000 : 0));
return Math.min(100000, Math.max(0,value)+delta);
}
switch (fill.getGradientType()) {
case linear:
return createLinearGradientPaint(fill, graphics);
+ case rectangular:
+ // TODO: implement rectangular gradient fill
case circular:
return createRadialGradientPaint(fill, graphics);
case shape:
image = img;
}
+ image = colorizePattern(fill, image);
+
Shape s = (Shape)graphics.getRenderingHint(Drawable.GRADIENT_SHAPE);
// TODO: check why original bitmaps scale/behave differently to vector based images
}
}
+ /**
+ * 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
*
Color result = color.getColor();
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, 1, color.getSatMod(), color.getSatOff());
applyHslModOff(hsl, 2, color.getLumMod(), color.getLumOff());
* @param off the offset adjustment
*/
private static void applyHslModOff(double[] hsl, int hslPart, int mod, int off) {
- if (mod == -1) {
- mod = 100000;
- }
- if (off == -1) {
- off = 0;
+ if (mod != -1) {
+ hsl[hslPart] *= mod / 100_000d;
}
- if (!(mod == 100000 && off == 0)) {
- double fOff = off / 1000d;
- double fMod = mod / 100000d;
- hsl[hslPart] = hsl[hslPart]*fMod+fOff;
+ if (off != -1) {
+ hsl[hslPart] += off / 1000d;
}
}
return;
}
- double shadePct = shade / 100000.;
-
- hsl[2] *= 1. - shadePct;
+ double shadePct = shade / 100_000.;
+ hsl[2] *= shadePct;
}
/**
*/
private static void applyTint(double[] hsl, ColorStyle fc) {
int tint = fc.getTint();
- if (tint == -1) {
+ if (tint == -1 || tint == 0) {
return;
}
// see 18.8.19 fgColor (Foreground Color)
- double tintPct = tint / 100000.;
- hsl[2] = hsl[2]*(1.-tintPct) + (100.-100.*(1.-tintPct));
+ double tintPct = tint / 100_000.;
+
+
+ // 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")
}
Rectangle2D anchor = DrawShape.getAnchor(graphics, shape);
+ if (anchor == null) {
+ return TRANSPARENT;
+ }
angle = convertOoxml2AwtAngle(-angle, anchor.getWidth(), anchor.getHeight());
@SuppressWarnings("WeakerAccess")
protected Paint createRadialGradientPaint(GradientPaint fill, Graphics2D graphics) {
Rectangle2D anchor = DrawShape.getAnchor(graphics, shape);
+ if (anchor == null) {
+ return TRANSPARENT;
+ }
+
+ 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 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());
- 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"})
}
private Paint safeFractions(BiFunction<float[],Color[],Paint> init, GradientPaint fill) {
- float[] fractions = fill.getGradientFractions();
- final ColorStyle[] styles = fill.getGradientColors();
+ // if style is null, use transparent color to get color of background
+ 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
Map<Float,Color> m = new TreeMap<>();
- for (int i = 0; i<fractions.length; i++) {
- // if fc is null, use transparent color to get color of background
- m.put(fractions[i], (styles[i] == null ? TRANSPARENT : applyColorTransform(styles[i])));
+ for (float fraction : fill.getGradientFractions()) {
+ m.put(fraction, styles.next());
}
- final Color[] colors = new Color[m.size()];
- if (fractions.length != m.size()) {
- fractions = new float[m.size()];
- }
-
- int i=0;
- for (Map.Entry<Float,Color> me : m.entrySet()) {
- fractions[i] = me.getKey();
- colors[i] = me.getValue();
- i++;
- }
+ return init.apply(toArray(m.keySet()), m.values().toArray(new Color[0]));
+ }
- return init.apply(fractions, colors);
+ private static float[] toArray(Collection<Float> floatList) {
+ int[] idx = { 0 };
+ float[] ret = new float[floatList.size()];
+ floatList.forEach(f -> ret[idx[0]++] = f);
+ return ret;
}
/**
import java.awt.geom.Dimension2D;
import java.awt.geom.Point2D;
import java.io.InputStream;
-
+import java.util.List;
public interface PaintStyle {
}
interface GradientPaint extends PaintStyle {
- enum GradientType { linear, circular, shape }
-
+ enum GradientType { linear, circular, rectangular, shape }
+
/**
* @return the angle of the gradient
*/
float[] getGradientFractions();
boolean isRotatedWithShape();
GradientType getGradientType();
- }
-
+
+ default Insets2D getFillToInsets() {
+ return null;
+ }
+ }
+
interface TexturePaint extends PaintStyle {
/**
* @return the raw image stream
* @return the content type of the image data
*/
String getContentType();
-
+
/**
* @return the alpha mask in percents [0..100000]
*/
default Insets2D getStretch() {
return null;
}
+
+
+ /**
+ * For pattern images, the duo tone defines the black/white pixel color replacement
+ */
+ default List<ColorStyle> getDuoTone() {
+ return null;
+ }
+
}
}
/**
* background does not have a associated transform, therefore we return null
- *
+ *
* @param create ignored
*
* @return null
protected CTTransform2D getXfrm(boolean create) {
return null;
}
-
+
@Override
public void setPlaceholder(Placeholder placeholder) {
// extending XSLFSimpleShape is a bit unlucky ...
}
return bg.getBgPr();
}
-
+
public void setFillColor(Color color) {
CTBackgroundProperties bgPr = getBgPr(true);
}
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);
}
}
package org.apache.poi.xslf.usermodel;
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.usermodel.AbstractColorStyle;
private XmlObject _xmlObject;
private Color _color;
private CTSchemeColor _phClr;
+ private XSLFSheet _sheet;
@SuppressWarnings("WeakerAccess")
- public XSLFColor(XmlObject obj, XSLFTheme theme, CTSchemeColor phClr) {
+ public XSLFColor(XmlObject obj, XSLFTheme theme, CTSchemeColor phClr, XSLFSheet sheet) {
_xmlObject = obj;
_phClr = phClr;
+ _sheet = sheet;
_color = toColor(obj, theme);
}
return DrawPaint.applyColorTransform(getColorStyle());
}
+
@SuppressWarnings("WeakerAccess")
public ColorStyle getColorStyle() {
- return new AbstractColorStyle() {
- @Override
- public Color getColor() {
- return _color;
- }
-
- @Override
- public int getAlpha() {
- return getRawValue("alpha");
- }
-
- @Override
- public int getHueOff() {
- return getRawValue("hueOff");
- }
-
- @Override
- public int getHueMod() {
- return getRawValue("hueMod");
- }
+ return new XSLFColorStyle(_xmlObject, _color, _phClr);
+ }
- @Override
- public int getSatOff() {
- return getRawValue("satOff");
- }
+ private Color toColor(CTHslColor hsl) {
+ return DrawPaint.HSL2RGB(
+ hsl.getHue2() / 60000d,
+ hsl.getSat2() / 1000d,
+ hsl.getLum2() / 1000d,
+ 1d);
+ }
- @Override
- public int getSatMod() {
- return getRawValue("satMod");
- }
+ private Color toColor(CTPresetColor prst) {
+ String colorName = prst.getVal().toString();
+ PresetColor pc = PresetColor.valueOfOoxmlId(colorName);
+ return (pc != null) ? pc.color : null;
+ }
- @Override
- public int getLumOff() {
- return getRawValue("lumOff");
- }
+ private Color toColor(CTSchemeColor schemeColor, XSLFTheme theme) {
+ String colorRef = schemeColor.getVal().toString();
+ if(_phClr != null) {
+ // context color overrides the theme
+ colorRef = _phClr.getVal().toString();
+ }
+ // find referenced CTColor in the theme and convert it to java.awt.Color via a recursive call
+ CTColor ctColor = theme == null ? null : theme.getCTColor(_sheet.mapSchemeColor(colorRef));
+ return (ctColor != null) ? toColor(ctColor, null) : null;
+ }
- @Override
- public int getLumMod() {
- return getRawValue("lumMod");
- }
+ private Color toColor(CTScRgbColor scrgb) {
+ // color in percentage is in linear RGB color space, i.e. needs to be gamma corrected for AWT color
+ return new Color(DrawPaint.lin2srgb(scrgb.getR()), DrawPaint.lin2srgb(scrgb.getG()), DrawPaint.lin2srgb(scrgb.getB()));
+ }
- @Override
- public int getShade() {
- return getRawValue("shade");
- }
+ private Color toColor(CTSRgbColor srgb) {
+ // color in sRGB color space, i.e. same as AWT Color
+ byte[] val = srgb.getVal();
+ return new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]);
+ }
- @Override
- public int getTint() {
- return getRawValue("tint");
- }
- };
+ private Color toColor(CTSystemColor sys) {
+ if (sys.isSetLastClr()) {
+ byte[] val = sys.getLastClr();
+ return new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]);
+ } else {
+ String colorName = sys.getVal().toString();
+ PresetColor pc = PresetColor.valueOfOoxmlId(colorName);
+ return (pc != null && pc.color != null) ? pc.color : Color.black;
+ }
}
private Color toColor(XmlObject obj, XSLFTheme theme) {
Color color = null;
- for (XmlObject ch : obj.selectPath("*")) {
+ 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) {
- 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);
+ color = toColor((CTHslColor)ch);
} else if (ch instanceof CTPresetColor) {
- CTPresetColor prst = (CTPresetColor)ch;
- String colorName = prst.getVal().toString();
- PresetColor pc = PresetColor.valueOfOoxmlId(colorName);
- if (pc != null) {
- color = pc.color;
- }
+ color = toColor((CTPresetColor)ch);
} else if (ch instanceof CTSchemeColor) {
- CTSchemeColor schemeColor = (CTSchemeColor)ch;
- String colorRef = schemeColor.getVal().toString();
- if(_phClr != null) {
- // context color overrides the theme
- colorRef = _phClr.getVal().toString();
- }
- // 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);
- if(ctColor != null) {
- color = toColor(ctColor, null);
- }
+ color = toColor((CTSchemeColor)ch, theme);
} else if (ch instanceof CTScRgbColor) {
- // color in percentage is in linear RGB color space, i.e. needs to be gamma corrected for AWT color
- CTScRgbColor scrgb = (CTScRgbColor)ch;
- color = new Color(DrawPaint.lin2srgb(scrgb.getR()), DrawPaint.lin2srgb(scrgb.getG()), DrawPaint.lin2srgb(scrgb.getB()));
+ color = toColor((CTScRgbColor)ch);
} else if (ch instanceof CTSRgbColor) {
- // color in sRGB color space, i.e. same as AWT Color
- CTSRgbColor srgb = (CTSRgbColor)ch;
- byte[] val = srgb.getVal();
- color = new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]);
+ color = toColor((CTSRgbColor)ch);
} else if (ch instanceof CTSystemColor) {
- CTSystemColor sys = (CTSystemColor)ch;
- if(sys.isSetLastClr()) {
- byte[] val = sys.getLastClr();
- color = new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]);
- } else {
- String colorName = sys.getVal().toString();
- PresetColor pc = PresetColor.valueOfOoxmlId(colorName);
- if (pc != null) {
- color = pc.color;
- }
- if (color == null) {
- color = Color.black;
- }
- }
+ color = toColor((CTSystemColor)ch);
} else if (!(ch instanceof CTFontReference)) {
- throw new IllegalArgumentException("Unexpected color choice: " + ch.getClass());
+ if (!isFirst) {
+ throw new IllegalArgumentException("Unexpected color choice: " + ch.getClass());
+ }
+ }
+ if (color != null) {
+ break;
}
+ isFirst = false;
}
return color;
}
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;
XmlObject[] obj;
// first ask the context color and if not found, ask the actual color bean
- if (_phClr != null){
- obj = _phClr.selectPath(query);
+ if (phClr != null){
+ obj = phClr.selectPath(query);
if (obj.length == 1){
Node attr = obj[0].getDomNode().getAttributes().getNamedItem("val");
if(attr != null) {
}
}
- obj = _xmlObject.selectPath(query);
+ obj = xmlObject.selectPath(query);
if (obj.length == 1){
Node attr = obj[0].getDomNode().getAttributes().getNamedItem("val");
if(attr != null) {
* @return the percentage value in the range [0 .. 100]
*/
private int getPercentageValue(String elem){
- int val = getRawValue(elem);
+ int val = getRawValue(_phClr, _xmlObject, elem);
return (val == -1) ? val : (val / 1000);
}
@SuppressWarnings("unused")
int getHue(){
- int val = getRawValue("hue");
+ int val = getRawValue(_phClr, _xmlObject, "hue");
return (val == -1) ? val : (val / 60000);
}
public int getTint(){
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");
+ }
+ }
}
import java.util.Arrays;
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.util.Internal;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGradientFillProperties;
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.STPathShadeType;
final ColorStyle[] cs;
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;
final CTGradientStop[] gs = gradFill.getGsLst() == null ?
if (phClrCgs == null && cgs.isSetSchemeClr()) {
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;
i++;
}
return PaintStyle.GradientPaint.GradientType.circular;
} else if (ps == STPathShadeType.SHAPE) {
return PaintStyle.GradientPaint.GradientType.shape;
+ } else if (ps == STPathShadeType.RECT) {
+ return PaintStyle.GradientPaint.GradientType.rectangular;
}
}
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;
+ }
}
* Create a new notes
*/
XSLFNotes() {
- super();
_notes = prototype();
}
}
return tp;
}
+
+ @Override
+ String mapSchemeColor(String schemeColor) {
+ return mapSchemeColor(_notes.getClrMapOvr(), schemeColor);
+ }
}
import org.apache.poi.sl.usermodel.MasterSheet;
import org.apache.poi.util.Beta;
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.NotesMasterDocument;
NotesMasterDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS);
_slide = doc.getNotesMaster();
}
-
+
private static CTNotesMaster prototype() {
InputStream is = XSLFNotesMaster.class.getResourceAsStream("notesMaster.xml");
if (is == null) {
throw new POIXMLException("Missing resource 'notesMaster.xml'");
- }
+ }
try {
try {
return doc.getNotesMaster();
} finally {
is.close();
- }
+ }
} catch (Exception e) {
throw new POIXMLException("Can't initialize NotesMaster", e);
}
}
-
+
@Override
public CTNotesMaster getXmlObject() {
return _slide;
}
@Override
- CTColorMapping getColorMapping() {
- return _slide.getClrMap();
+ String mapSchemeColor(String schemeColor) {
+ String notesMasterColor = mapSchemeColor(_slide.getClrMap(), schemeColor);
+ return notesMasterColor == null ? schemeColor : notesMasterColor;
}
}
\ No newline at end of file
*/
public double getDistance(){
CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject();
- return ct.isSetDist() ? Units.toPoints(ct.getDist()) : 0;
+ return ct.isSetDist() ? Units.toPoints(ct.getDist()) : 0;
}
/**
- *
+ *
* @return the direction to offset the shadow in angles
*/
public double getAngle(){
}
/**
- *
+ *
* @return the blur radius of the shadow
- * TODO: figure out how to make sense of this property when rendering shadows
+ * TODO: figure out how to make sense of this property when rendering shadows
*/
public double getBlur(){
CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject();
}
/**
- * @return the color of this shadow.
+ * @return the color of this shadow.
* Depending whether the parent shape is filled or stroked, this color is used to fill or stroke this shadow
*/
public Color getFillColor() {
XSLFTheme theme = getSheet().getTheme();
CTOuterShadowEffect ct = (CTOuterShadowEffect)getXmlObject();
if(ct == null) return null;
-
+
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());
}
}
\ No newline at end of file
if (shape instanceof XSLFPictureShape) {
CTPicture pic = (CTPicture)shape.getXmlObject();
if (pic.getBlipFill() != null) {
- setValue(selectPaint(pic.getBlipFill(), pp));
+ setValue(selectPaint(pic.getBlipFill(), pp, null, theme));
return true;
}
}
* @return the applied Paint or null if none was applied
*/
@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()) {
return null;
} else if (fp.isSetSolidFill()) {
return selectPaint(fp.getSolidFill(), phClr, theme);
} else if (fp.isSetBlipFill()) {
- return selectPaint(fp.getBlipFill(), parentPart);
+ return selectPaint(fp.getBlipFill(), parentPart, phClr, theme);
} else if (fp.isSetGradFill()) {
return selectPaint(fp.getGradFill(), phClr, theme);
} else if (fp.isSetMatrixStyle()) {
}
@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 there's a reference to the placeholder color,
// stop evaluating further and let the caller select
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());
}
@SuppressWarnings("WeakerAccess")
- protected static PaintStyle selectPaint(final CTBlipFillProperties blipFill, final PackagePart parentPart) {
- return new XSLFTexturePaint(blipFill, parentPart);
+ protected PaintStyle selectPaint(final CTBlipFillProperties blipFill, final PackagePart parentPart, CTSchemeColor phClr, final XSLFTheme theme) {
+ return new XSLFTexturePaint(blipFill, parentPart, phClr, theme, _sheet);
}
@SuppressWarnings("WeakerAccess")
- protected static PaintStyle selectPaint(final CTGradientFillProperties gradFill, CTSchemeColor phClr, final XSLFTheme theme) {
- return new XSLFGradientPaint(gradFill, phClr, theme);
+ protected PaintStyle selectPaint(final CTGradientFillProperties gradFill, CTSchemeColor phClr, final XSLFTheme theme) {
+ return new XSLFGradientPaint(gradFill, phClr, theme, _sheet);
}
@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) {
return null;
}
if (res != null || hasPlaceholder) {
return res;
}
- XSLFColor col = new XSLFColor(fillRef, theme, phClr);
+ XSLFColor col = new XSLFColor(fillRef, theme, phClr, _sheet);
return DrawPaint.createSolidPaint(col.getColorStyle());
}
import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import java.util.Optional;
import javax.xml.namespace.QName;
import org.apache.xmlbeans.XmlOptions;
import org.apache.xmlbeans.impl.values.XmlAnyTypeImpl;
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.CTGraphicalObjectFrame;
import org.openxmlformats.schemas.presentationml.x2006.main.CTGroupShape;
return _theme;
}
- final Optional<XSLFTheme> t =
- getRelations().stream().filter((p) -> p instanceof XSLFTheme).map((p) -> (XSLFTheme) p).findAny();
- if (t.isPresent()) {
- _theme = t.get();
- final CTColorMapping cmap = getColorMapping();
- if (cmap != null) {
- _theme.initColorMap(cmap);
- }
- }
+ getRelations().stream()
+ .filter(p -> p instanceof XSLFTheme)
+ .findAny()
+ .ifPresent(p -> _theme = (XSLFTheme)p);
+
return _theme;
}
/**
* @return the color mapping for this slide type
*/
- CTColorMapping getColorMapping() {
+ String mapSchemeColor(String schemeColor) {
return null;
}
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();
+ }
}
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties;
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFGeometryProperties;
import org.apache.xmlbeans.XmlObject;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTBaseStyles;
-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;
+import org.openxmlformats.schemas.drawingml.x2006.main.*;
/**
* Represents a single (non-group) shape in a .pptx slide show
}
};
fetchShapeProperty(fetcher);
-
+
CTTransform2D xfrm = fetcher.getValue();
if (!create || xfrm != null) {
return xfrm;
ln.unsetNoFill();
}
-
+
if (color == null) {
ln.addNewNoFill();
} else {
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);
}
}
setValue(null);
return true;
}
-
+
PackagePart pp = shape.getSheet().getPackagePart();
PaintStyle paint = selectPaint(fp, null, pp, theme, hasPlaceholder);
if (paint != null) {
paint = getThemePaint(style, pp);
}
}
-
+
if (paint != null) {
setValue(paint);
return true;
}
-
+
return false;
}
if (lnPr == null) {
return;
}
-
+
if (width == 0.) {
if (lnPr.isSetW()) {
lnPr.unsetW();
if (ln == null) {
return;
}
-
+
if (cap == null) {
if (ln.isSetCap()) {
ln.unsetCap();
if (fp.isSetSolidFill()) {
fp.unsetSolidFill();
}
-
+
if (fp.isSetGradFill()) {
fp.unsetGradFill();
}
if (fp.isSetPattFill()) {
fp.unsetGradFill();
}
-
+
if (fp.isSetBlipFill()) {
fp.unsetBlipFill();
}
-
+
if (!fp.isSetNoFill()) {
fp.addNewNoFill();
}
}
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);
}
}
@Override
public CustomGeometry getGeometry() {
XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties());
-
+
if (gp == null) {
return null;
}
-
+
CustomGeometry geom;
PresetGeometries dict = PresetGeometries.getInstance();
if(gp.isSetPrstGeom()){
/**
* Specifies the line end decoration, such as a triangle or arrowhead.
- *
+ *
* @param style the line end docoration style
*/
@SuppressWarnings("WeakerAccess")
/**
* specifies decoration width of the head of a line.
- *
- * @param style the decoration width
+ *
+ * @param style the decoration width
*/
@SuppressWarnings("WeakerAccess")
public void setLineHeadWidth(DecorationSize style) {
if (ln == null) {
return;
}
-
+
CTLineEndProperties lnEnd = ln.isSetHeadEnd() ? ln.getHeadEnd() : ln.addNewHeadEnd();
if (style == null) {
if (lnEnd.isSetLen()) {
@SuppressWarnings("WeakerAccess")
public DecorationSize getLineHeadLength() {
CTLineProperties ln = getLn(this, false);
-
+
DecorationSize ds = DecorationSize.MEDIUM;
if (ln != null && ln.isSetHeadEnd() && ln.getHeadEnd().isSetLen()) {
ds = DecorationSize.fromOoxmlId(ln.getHeadEnd().getLen().intValue());
}
- return ds;
+ return ds;
}
/**
@SuppressWarnings("WeakerAccess")
public DecorationShape getLineTailDecoration() {
CTLineProperties ln = getLn(this, false);
-
+
DecorationShape ds = DecorationShape.NONE;
if (ln != null && ln.isSetTailEnd() && ln.getTailEnd().isSetType()) {
ds = DecorationShape.fromOoxmlId(ln.getTailEnd().getType().intValue());
if (ln == null) {
return;
}
-
+
CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
if (style == null) {
if (lnEnd.isSetW()) {
if (ln == null) {
return;
}
-
+
CTLineEndProperties lnEnd = ln.isSetTailEnd() ? ln.getTailEnd() : ln.addNewTailEnd();
if (style == null) {
if (lnEnd.isSetLen()) {
@SuppressWarnings("WeakerAccess")
public DecorationSize getLineTailLength() {
CTLineProperties ln = getLn(this, false);
-
+
DecorationSize ds = DecorationSize.MEDIUM;
if (ln != null && ln.isSetTailEnd() && ln.getTailEnd().isSetLen()) {
ds = DecorationSize.fromOoxmlId(ln.getTailEnd().getLen().intValue());
}
- return ds;
+ return ds;
}
@Override
public Guide getAdjustValue(String name) {
XSLFGeometryProperties gp = XSLFPropertiesDelegate.getGeometryDelegate(getShapeProperties());
-
+
if (gp != null && gp.isSetPrstGeom() && gp.getPrstGeom().isSetAvLst()) {
//noinspection deprecation
for (CTGeomGuide g : gp.getPrstGeom().getAvLst().getGdArray()) {
setLineColor(null);
return;
}
-
+
// TODO: handle PaintStyle
for (Object st : styles) {
if (st instanceof Number) {
}
}
}
-
+
@Override
public XSLFHyperlink getHyperlink() {
CTNonVisualDrawingProps cNvPr = getCNvPr();
}
return new XSLFHyperlink(cNvPr.getHlinkClick(), getSheet());
}
-
+
@Override
public XSLFHyperlink createHyperlink() {
XSLFHyperlink hl = getHyperlink();
LOG.log(POILogger.WARN, shape.getClass() +" doesn't have line properties");
return null;
}
-
+
CTShapeProperties spr = (CTShapeProperties)pr;
return (spr.isSetLn() || !create) ? spr.getLn() : spr.addNewLn();
}
import java.util.List;
import org.apache.poi.ooxml.POIXMLDocumentPart;
+import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.openxml4j.opc.PackagePart;
import org.apache.poi.sl.draw.DrawFactory;
import org.apache.poi.sl.draw.Drawable;
import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.sl.usermodel.Slide;
import org.apache.poi.util.Beta;
-import org.apache.poi.ooxml.util.DocumentHelper;
import org.apache.poi.util.NotImplemented;
import org.apache.xmlbeans.XmlException;
import org.openxmlformats.schemas.drawingml.x2006.main.CTGroupShapeProperties;
public boolean getFollowMasterObjects() {
return getFollowMasterGraphics();
}
-
+
@Override
public void setFollowMasterObjects(boolean follow) {
setFollowMasterGraphics(follow);
public boolean getFollowMasterBackground() {
return false;
}
-
+
@Override
@NotImplemented
public void setFollowMasterBackground(boolean follow) {
public boolean getFollowMasterColourScheme() {
return false;
}
-
+
@Override
@NotImplemented
public void setFollowMasterColourScheme(boolean follow) {
return false;
}
-
+
@Override
public void setHidden(boolean hidden) {
CTSlide sld = getXmlObject();
}
}
}
-
+
@Override
public boolean isHidden() {
CTSlide sld = getXmlObject();
final CTCommonSlideData cSld = getXmlObject().getCSld();
return cSld.isSetName() ? cSld.getName() : "Slide"+getSlideNumber();
}
+
+ @Override
+ String mapSchemeColor(String schemeColor) {
+ return mapSchemeColor(_slide.getClrMapOvr(), schemeColor);
+ }
}
int ordinal = _layout.getType().intValue() - 1;
return SlideLayout.values()[ordinal];
}
+
+
+ @Override
+ String mapSchemeColor(String schemeColor) {
+ return mapSchemeColor(_layout.getClrMapOvr(), schemeColor);
+ }
}
\ No newline at end of file
import org.apache.poi.sl.usermodel.Placeholder;
import org.apache.poi.util.Beta;
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.presentationml.x2006.main.CTBackground;
import org.openxmlformats.schemas.presentationml.x2006.main.CTSlideMaster;
SldMasterDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS);
_slide = doc.getSldMaster();
}
-
+
@Override
public CTSlideMaster getXmlObject() {
return _slide;
}
@Override
- CTColorMapping getColorMapping() {
- return _slide.getClrMap();
+ String mapSchemeColor(String schemeColor) {
+ String masterColor = mapSchemeColor(_slide.getClrMap(), schemeColor);
+ return masterColor == null ? schemeColor : masterColor;
}
}
import org.apache.poi.xslf.usermodel.XSLFPropertiesDelegate.XSLFFillProperties;
import org.apache.poi.xslf.usermodel.XSLFTableStyle.TablePartStyle;
import org.apache.xmlbeans.XmlObject;
-import org.openxmlformats.schemas.drawingml.x2006.main.CTFontReference;
-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;
+import org.openxmlformats.schemas.drawingml.x2006.main.*;
/**
* Represents a cell of a table in a .pptx presentation
CTLineProperties ln = setBorderDefaults(edge);
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);
}
}
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();
}
}
} else {
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);
}
}
fp = XSLFPropertiesDelegate.getFillDelegate(props);
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) {
return paint;
}
}
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());
}
@Override
public boolean fetch(CTTextParagraphProperties props){
if(props.isSetBuClr()){
- XSLFColor c = new XSLFColor(props.getBuClr(), theme, null);
+ XSLFColor c = new XSLFColor(props.getBuClr(), theme, null, _shape.getSheet());
setValue(c.getColor());
return true;
}
CTTextCharacterProperties rPr = getRPr(true);
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);
}
XSLFSheet sheet = shape.getSheet();
PackagePart pp = sheet.getPackagePart();
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) {
setValue(ps);
import java.awt.geom.Point2D;
import java.io.IOException;
import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.List;
import java.util.function.Supplier;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.opc.PackagePart;
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.PaintStyle;
import org.apache.poi.util.Dimension2DDouble;
import org.apache.poi.util.Units;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBlip;
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.CTSchemeColor;
import org.openxmlformats.schemas.drawingml.x2006.main.CTTileInfoProperties;
import org.openxmlformats.schemas.drawingml.x2006.main.STTileFlipMode;
private final CTBlipFillProperties blipFill;
private final PackagePart parentPart;
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.parentPart = parentPart;
blip = blipFill.getBlip();
+ this.phClr = phClr;
+ this.theme = theme;
+ this.sheet = sheet;
}
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) {
return rect == null ? null : new Insets2D(
getRectVal(rect::isSetT, rect::getT),
import java.io.IOException;
import java.io.OutputStream;
-import java.util.HashMap;
-import java.util.Map;
import javax.xml.namespace.QName;
import org.apache.poi.util.Beta;
import org.apache.poi.util.Internal;
import org.apache.xmlbeans.XmlException;
-import org.apache.xmlbeans.XmlObject;
import org.apache.xmlbeans.XmlOptions;
import org.openxmlformats.schemas.drawingml.x2006.main.CTBaseStyles;
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.CTOfficeStyleSheet;
import org.openxmlformats.schemas.drawingml.x2006.main.ThemeDocument;
/**
* A shared style sheet in a .pptx slide show
- *
- * @author Yegor Kozlov
*/
@Beta
public class XSLFTheme extends POIXMLDocumentPart {
private CTOfficeStyleSheet _theme;
- private Map<String, CTColor> _schemeColors;
XSLFTheme() {
- super();
_theme = CTOfficeStyleSheet.Factory.newInstance();
}
ThemeDocument doc =
ThemeDocument.Factory.parse(getPackagePart().getInputStream(), DEFAULT_XML_OPTIONS);
_theme = doc.getTheme();
- initialize();
}
@SuppressWarnings("WeakerAccess")
public void importTheme(XSLFTheme theme) {
_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()));
}
/**
* @return a theme color or <code>null</code> if not found
*/
@Internal
- public CTColor getCTColor(String name){
- return _schemeColors.get(name);
+ public CTColor getCTColor(String 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;
+ }
}
/**
CTSRgbColor c = xml.addNewSrgbClr();
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());
c.addNewAlpha().setVal(50000);
c.setSat2(100000);
c.setLum2(50000);
- XSLFColor color = new XSLFColor(xml, null, null);
+ XSLFColor color = new XSLFColor(xml, null, null, null);
assertEquals(Color.BLUE, color.getColor());
}
CTColor xml = CTColor.Factory.newInstance();
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());
}
@Test
public void testSchemeColor() throws IOException {
XMLSlideShow ppt = new XMLSlideShow();
- XSLFTheme theme = ppt.createSlide().getTheme();
+ XSLFSheet slide = ppt.createSlide();
+ XSLFTheme theme = slide.getTheme();
CTColor xml = CTColor.Factory.newInstance();
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"/>
assertEquals(Color.decode("0xC0504D"), color.getColor());
xml = CTColor.Factory.newInstance();
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"/>
assertEquals(Color.decode("0xFFFFFF"), color.getColor());
xml = CTColor.Factory.newInstance();
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"/>
assertEquals(Color.decode("0x000000"), color.getColor());
public void testPresetColor() {
CTColor xml = CTColor.Factory.newInstance();
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());
} else {
xml.addNewSysClr().setVal(sysVal);
}
- color = new XSLFColor(xml, null, null);
+ color = new XSLFColor(xml, null, null, null);
assertEquals(pc.color, color.getColor());
}
}
CTColor xml = CTColor.Factory.newInstance();
CTSystemColor sys = xml.addNewSysClr();
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());
xml = CTColor.Factory.newInstance();
sys = xml.addNewSysClr();
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());
}
}
\ No newline at end of file
import org.apache.poi.hslf.model.textproperties.TextProp;
import org.apache.poi.hslf.model.textproperties.TextPropCollection;
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.usermodel.AutoNumberingScheme;
import org.apache.poi.sl.usermodel.PaintStyle;
_byteAtom = tba;
_charAtom = tca;
this.parentList = parentList;
- _paragraphStyle = new TextPropCollection(1, TextPropType.paragraph);
+ setParagraphStyle(new TextPropCollection(1, TextPropType.paragraph));
}
/* package */HSLFTextParagraph(HSLFTextParagraph other) {
_sheet = other._sheet;
_ruler = other._ruler;
shapeId = other.shapeId;
- _paragraphStyle = other._paragraphStyle;
parentList = other.parentList;
+ setParagraphStyle(other._paragraphStyle);
}
public void addTextRun(HSLFTextRun run) {