*\r
* @returns the RGB Color object\r
*/\r
- private static Color HSL2RGB(double h, double s, double l, double alpha) {\r
+ public static Color HSL2RGB(double h, double s, double l, double alpha) {\r
// we clamp the values, as it possible to come up with more than 100% sat/lum\r
// (see links in applyColorTransform() for more info)\r
s = Math.max(0, Math.min(100, s));\r
\r
return new double[] {h, s * 100, l * 100};\r
}\r
-\r
+ \r
+ /**\r
+ * Convert sRGB float component [0..1] from sRGB to linear RGB [0..100000]\r
+ * \r
+ * @see Color#getRGBColorComponents(float[])\r
+ */\r
+ public static int srgb2lin(float sRGB) {\r
+ // scRGB has a linear gamma of 1.0, scale the AWT-Color which is in sRGB to linear RGB\r
+ // see https://en.wikipedia.org/wiki/SRGB (the reverse transformation)\r
+ if (sRGB <= 0.04045d) {\r
+ return (int)Math.rint(100000d * sRGB / 12.92d);\r
+ } else {\r
+ return (int)Math.rint(100000d * Math.pow((sRGB + 0.055d) / 1.055d, 2.4d));\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * Convert linear RGB [0..100000] to sRGB float component [0..1]\r
+ * \r
+ * @see Color#getRGBColorComponents(float[])\r
+ */\r
+ public static float lin2srgb(int linRGB) {\r
+ // color in percentage is in linear RGB color space, i.e. needs to be gamma corrected for AWT color\r
+ // see https://en.wikipedia.org/wiki/SRGB (The forward transformation)\r
+ if (linRGB <= 0.0031308d) {\r
+ return (float)(linRGB / 100000d * 12.92d);\r
+ } else {\r
+ return (float)(1.055d * Math.pow(linRGB / 100000d, 1.0d/2.4d) - 0.055d);\r
+ }\r
+ }\r
}
\ No newline at end of file
import org.apache.xmlbeans.XmlObject;\r
import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;\r
import org.openxmlformats.schemas.drawingml.x2006.main.CTHslColor;\r
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveFixedPercentage;\r
import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetColor;\r
import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;\r
import org.openxmlformats.schemas.drawingml.x2006.main.CTScRgbColor;\r
int h = hsl.getHue2();\r
int s = hsl.getSat2();\r
int l = hsl.getLum2();\r
- // This conversion is not correct and differs from PowerPoint.\r
- // TODO: Revisit and improve.\r
- color = Color.getHSBColor(h / 60000f, s / 100000f, l / 100000f);\r
+ color = DrawPaint.HSL2RGB(h / 60000d, s / 1000d, l / 1000d, 1d);\r
} else if (ch instanceof CTPresetColor) {\r
CTPresetColor prst = (CTPresetColor)ch;\r
String colorName = prst.getVal().toString();\r
CTColor ctColor = theme.getCTColor(colorRef);\r
if(ctColor != null) color = toColor(ctColor, null);\r
} else if (ch instanceof CTScRgbColor) {\r
- // same as CTSRgbColor but with values expressed in percents\r
+ // color in percentage is in linear RGB color space, i.e. needs to be gamma corrected for AWT color\r
CTScRgbColor scrgb = (CTScRgbColor)ch;\r
- int r = scrgb.getR();\r
- int g = scrgb.getG();\r
- int b = scrgb.getB();\r
- color = new Color(255 * r / 100000, 255 * g / 100000, 255 * b / 100000);\r
+ color = new Color(DrawPaint.lin2srgb(scrgb.getR()), DrawPaint.lin2srgb(scrgb.getG()), DrawPaint.lin2srgb(scrgb.getB()));\r
} else if (ch instanceof CTSRgbColor) {\r
+ // color in sRGB color space, i.e. same as AWT Color\r
CTSRgbColor srgb = (CTSRgbColor)ch;\r
byte[] val = srgb.getVal();\r
color = new Color(0xFF & val[0], 0xFF & val[1], 0xFF & val[2]);\r
if (fill.isSetSrgbClr()) {\r
fill.unsetSrgbClr();\r
}\r
- \r
- CTSRgbColor rgb = fill.addNewSrgbClr();\r
- \r
- float[] rgbaf = color.getRGBComponents(null);\r
- int r = color.getRed(), g = color.getGreen(), b = color.getBlue();\r
- if (rgbaf[0]*255f == r && rgbaf[1]*255f == g && rgbaf[2]*255f == b) {\r
- rgb.setVal(new byte[]{(byte)r, (byte)g, (byte)b });\r
- } else {\r
- rgb.addNewRed().setVal((int)(100000 * rgbaf[0]));\r
- rgb.addNewGreen().setVal((int)(100000 * rgbaf[1]));\r
- rgb.addNewBlue().setVal((int)(100000 * rgbaf[2]));\r
- }\r
\r
- // alpha (%)\r
- if (rgbaf.length == 4 && rgbaf[3] < 1f) {\r
- rgb.addNewAlpha().setVal((int)(100000 * rgbaf[3]));\r
+ if (fill.isSetScrgbClr()) {\r
+ fill.unsetScrgbClr();\r
}\r
-\r
+ \r
if (fill.isSetHslClr()) {\r
fill.unsetHslClr();\r
}\r
fill.unsetSchemeClr();\r
}\r
\r
- if (fill.isSetScrgbClr()) {\r
- fill.unsetScrgbClr();\r
- }\r
- \r
if (fill.isSetSysClr()) {\r
fill.unsetSysClr();\r
}\r
+\r
+ float[] rgbaf = color.getRGBComponents(null);\r
+ boolean addAlpha = (rgbaf.length == 4 && rgbaf[3] < 1f);\r
+ CTPositiveFixedPercentage alphaPct;\r
+ \r
+ // see office open xml part 4 - 5.1.2.2.30 and 5.1.2.2.32\r
+ if (isInt(rgbaf[0]) && isInt(rgbaf[1]) && isInt(rgbaf[2])) {\r
+ // sRGB has a gamma of 2.2\r
+ CTSRgbColor rgb = fill.addNewSrgbClr();\r
+ \r
+ byte rgbBytes[] = { (byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue() };\r
+ rgb.setVal(rgbBytes);\r
+ alphaPct = (addAlpha) ? rgb.addNewAlpha() : null;\r
+ } else {\r
+ CTScRgbColor rgb = fill.addNewScrgbClr();\r
+ rgb.setR(DrawPaint.srgb2lin(rgbaf[0]));\r
+ rgb.setG(DrawPaint.srgb2lin(rgbaf[1]));\r
+ rgb.setB(DrawPaint.srgb2lin(rgbaf[2]));\r
+ alphaPct = (addAlpha) ? rgb.addNewAlpha() : null;\r
+ }\r
+\r
+ // alpha (%)\r
+ if (alphaPct != null) {\r
+ alphaPct.setVal((int)(100000 * rgbaf[3]));\r
+ }\r
+ }\r
+ \r
+ /**\r
+ * @return true, if this is an integer color value\r
+ */\r
+ private static boolean isInt(float f) {\r
+ return Math.abs((f*255f) - Math.rint(f*255f)) < 0.00001f;\r
}\r
\r
private int getRawValue(String elem) {\r
import org.apache.poi.POIDataSamples;
import org.apache.poi.POIXMLDocumentPart;
import org.apache.poi.POIXMLDocumentPart.RelationPart;
+import org.apache.poi.sl.draw.DrawPaint;
+import org.apache.poi.sl.usermodel.PaintStyle;
import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
import org.apache.poi.sl.usermodel.PictureData;
import org.apache.poi.sl.usermodel.PictureData.PictureType;
import org.apache.poi.sl.usermodel.ShapeType;
+import org.apache.poi.sl.usermodel.VerticalAlignment;
import org.apache.poi.xslf.usermodel.DrawingParagraph;
import org.apache.poi.xslf.usermodel.DrawingTextBody;
import org.apache.poi.xslf.usermodel.XMLSlideShow;
import org.apache.poi.xslf.usermodel.XSLFSlide;
import org.apache.poi.xslf.usermodel.XSLFSlideLayout;
import org.apache.poi.xslf.usermodel.XSLFSlideMaster;
+import org.apache.poi.xslf.usermodel.XSLFTextRun;
import org.junit.Ignore;
import org.junit.Test;
@Test
public void bug58217() throws IOException {
+ Color fillColor = new Color(1f,1f,0f,0.1f);
+ Color lineColor = new Color(25.3f/255f,1f,0f,0.4f);
+ Color textColor = new Color(1f,1f,0f,0.6f);
+
XMLSlideShow ppt1 = new XMLSlideShow();
XSLFSlide sl = ppt1.createSlide();
XSLFAutoShape as = sl.createAutoShape();
as.setShapeType(ShapeType.STAR_10);
as.setAnchor(new Rectangle2D.Double(100,100,300,300));
- as.setFillColor(new Color(1f,1f,0f,0.1f));
- as.setLineColor(new Color(1f,1f,0f,0.4f));
+ as.setFillColor(fillColor);
+ as.setLineColor(lineColor);
as.setText("Alpha");
- as.getTextParagraphs().get(0).getTextRuns().get(0).setFontColor(new Color(1f,1f,0f,0.6f));
+ as.setVerticalAlignment(VerticalAlignment.MIDDLE);
+ as.setHorizontalCentered(true);
+ XSLFTextRun tr = as.getTextParagraphs().get(0).getTextRuns().get(0);
+ tr.setFontSize(32d);
+ tr.setFontColor(textColor);
XMLSlideShow ppt2 = XSLFTestDataSamples.writeOutAndReadBack(ppt1);
ppt1.close();
sl = ppt2.getSlides().get(0);
as = (XSLFAutoShape)sl.getShapes().get(0);
- SolidPaint ps = (SolidPaint)as.getFillStyle().getPaint();
- assertEquals(10000, ps.getSolidColor().getAlpha());
- ps = (SolidPaint)as.getStrokeStyle().getPaint();
- assertEquals(40000, ps.getSolidColor().getAlpha());
- ps = (SolidPaint)as.getTextParagraphs().get(0).getTextRuns().get(0).getFontColor();
- assertEquals(60000, ps.getSolidColor().getAlpha());
+ checkColor(fillColor, as.getFillStyle().getPaint());
+ checkColor(lineColor, as.getStrokeStyle().getPaint());
+ checkColor(textColor, as.getTextParagraphs().get(0).getTextRuns().get(0).getFontColor());
ppt2.close();
}
+
+ private static void checkColor(Color expected, PaintStyle actualStyle) {
+ assertTrue(actualStyle instanceof SolidPaint);
+ SolidPaint ps = (SolidPaint)actualStyle;
+ Color actual = DrawPaint.applyColorTransform(ps.getSolidColor());
+ float expRGB[] = expected.getRGBComponents(null);
+ float actRGB[] = actual.getRGBComponents(null);
+ assertArrayEquals(expRGB, actRGB, 0.0001f);
+ }
}
c.setLum2(50000);\r
\r
XSLFColor color = new XSLFColor(xml, null, null);\r
- assertEquals(new Color(128, 00, 00), color.getColor());\r
+ assertEquals(Color.BLUE, color.getColor());\r
}\r
\r
@Test\r