poi-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kiwiwi...@apache.org
Subject svn commit: r1745412 - in /poi/trunk/src: java/org/apache/poi/sl/draw/ ooxml/java/org/apache/poi/xslf/usermodel/ ooxml/testcases/org/apache/poi/xslf/ ooxml/testcases/org/apache/poi/xslf/usermodel/
Date Tue, 24 May 2016 23:39:24 GMT
Author: kiwiwings
Date: Tue May 24 23:39:23 2016
New Revision: 1745412

URL: http://svn.apache.org/viewvc?rev=1745412&view=rev
Log:
fix handling of hsl and linear rgb (%-values)

Modified:
    poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java
    poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java
    poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java
    poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFColor.java

Modified: poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java?rev=1745412&r1=1745411&r2=1745412&view=diff
==============================================================================
--- poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java (original)
+++ poi/trunk/src/java/org/apache/poi/sl/draw/DrawPaint.java Tue May 24 23:39:23 2016
@@ -384,7 +384,7 @@ public class DrawPaint {
      *
      *  @returns the RGB Color object
      */
-    private static Color HSL2RGB(double h, double s, double l, double alpha) {
+    public static Color HSL2RGB(double h, double s, double l, double alpha) {
         // we clamp the values, as it possible to come up with more than 100% sat/lum
         // (see links in applyColorTransform() for more info)
         s = Math.max(0, Math.min(100, s));
@@ -491,5 +491,34 @@ public class DrawPaint {
 
         return new double[] {h, s * 100, l * 100};
     }
-
+    
+    /**
+     * Convert sRGB float component [0..1] from sRGB to linear RGB [0..100000]
+     * 
+     * @see Color#getRGBColorComponents(float[])
+     */
+    public static int srgb2lin(float sRGB) {
+        // scRGB has a linear gamma of 1.0, scale the AWT-Color which is in sRGB to linear
RGB
+        // see https://en.wikipedia.org/wiki/SRGB (the reverse transformation)
+        if (sRGB <= 0.04045d) {
+            return (int)Math.rint(100000d * sRGB / 12.92d);
+        } else {
+            return (int)Math.rint(100000d * Math.pow((sRGB + 0.055d) / 1.055d, 2.4d));
+        }
+    }
+    
+    /**
+     * Convert linear RGB [0..100000] to sRGB float component [0..1]
+     * 
+     * @see Color#getRGBColorComponents(float[])
+     */
+    public static float lin2srgb(int linRGB) {
+        // color in percentage is in linear RGB color space, i.e. needs to be gamma corrected
for AWT color
+        // see https://en.wikipedia.org/wiki/SRGB (The forward transformation)
+        if (linRGB <= 0.0031308d) {
+            return (float)(linRGB / 100000d * 12.92d);
+        } else {
+            return (float)(1.055d * Math.pow(linRGB / 100000d, 1.0d/2.4d) - 0.055d);
+        }
+    }
 }
\ No newline at end of file

Modified: poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java?rev=1745412&r1=1745411&r2=1745412&view=diff
==============================================================================
--- poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java (original)
+++ poi/trunk/src/ooxml/java/org/apache/poi/xslf/usermodel/XSLFColor.java Tue May 24 23:39:23
2016
@@ -30,6 +30,7 @@ import org.apache.poi.util.POILogger;
 import org.apache.xmlbeans.XmlObject;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTColor;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTHslColor;
+import org.openxmlformats.schemas.drawingml.x2006.main.CTPositiveFixedPercentage;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetColor;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTSRgbColor;
 import org.openxmlformats.schemas.drawingml.x2006.main.CTScRgbColor;
@@ -122,9 +123,7 @@ public class XSLFColor {
                 int h = hsl.getHue2();
                 int s = hsl.getSat2();
                 int l = hsl.getLum2();
-                // This conversion is not correct and differs from PowerPoint.
-                // TODO: Revisit and improve.
-                color = Color.getHSBColor(h / 60000f, s / 100000f, l / 100000f);
+                color = DrawPaint.HSL2RGB(h / 60000d, s / 1000d, l / 1000d, 1d);
             } else if (ch instanceof CTPresetColor) {
                 CTPresetColor prst = (CTPresetColor)ch;
                 String colorName = prst.getVal().toString();
@@ -143,13 +142,11 @@ public class XSLFColor {
                 CTColor ctColor = theme.getCTColor(colorRef);
                 if(ctColor != null) color = toColor(ctColor, null);
             } else if (ch instanceof CTScRgbColor) {
-                // same as CTSRgbColor but with values expressed in percents
+                // color in percentage is in linear RGB color space, i.e. needs to be gamma
corrected for AWT color
                 CTScRgbColor scrgb = (CTScRgbColor)ch;
-                int r = scrgb.getR();
-                int g = scrgb.getG();
-                int b = scrgb.getB();
-                color = new Color(255 * r / 100000, 255 * g / 100000, 255 * b / 100000);
+                color = new Color(DrawPaint.lin2srgb(scrgb.getR()), DrawPaint.lin2srgb(scrgb.getG()),
DrawPaint.lin2srgb(scrgb.getB()));
             } 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]);
@@ -190,24 +187,11 @@ public class XSLFColor {
         if (fill.isSetSrgbClr()) {
             fill.unsetSrgbClr();
         }
-        
-        CTSRgbColor rgb = fill.addNewSrgbClr();
-        
-        float[] rgbaf = color.getRGBComponents(null);
-        int r = color.getRed(), g = color.getGreen(), b = color.getBlue();
-        if (rgbaf[0]*255f == r && rgbaf[1]*255f == g && rgbaf[2]*255f ==
b) {
-            rgb.setVal(new byte[]{(byte)r, (byte)g, (byte)b });
-        } else {
-            rgb.addNewRed().setVal((int)(100000 * rgbaf[0]));
-            rgb.addNewGreen().setVal((int)(100000 * rgbaf[1]));
-            rgb.addNewBlue().setVal((int)(100000 * rgbaf[2]));
-        }
 
-        // alpha (%)
-        if (rgbaf.length == 4 && rgbaf[3] < 1f) {
-            rgb.addNewAlpha().setVal((int)(100000 * rgbaf[3]));
+        if (fill.isSetScrgbClr()) {
+            fill.unsetScrgbClr();
         }
-
+        
         if (fill.isSetHslClr()) {
             fill.unsetHslClr();
         }
@@ -220,13 +204,41 @@ public class XSLFColor {
             fill.unsetSchemeClr();
         }
         
-        if (fill.isSetScrgbClr()) {
-            fill.unsetScrgbClr();
-        }
-        
         if (fill.isSetSysClr()) {
             fill.unsetSysClr();
         }
+
+        float[] rgbaf = color.getRGBComponents(null);
+        boolean addAlpha = (rgbaf.length == 4 && rgbaf[3] < 1f);
+        CTPositiveFixedPercentage alphaPct;
+        
+        // see office open xml part 4 - 5.1.2.2.30 and 5.1.2.2.32
+        if (isInt(rgbaf[0]) && isInt(rgbaf[1]) && isInt(rgbaf[2])) {
+            // sRGB has a gamma of 2.2
+            CTSRgbColor rgb = fill.addNewSrgbClr();
+            
+            byte rgbBytes[] = { (byte)color.getRed(), (byte)color.getGreen(), (byte)color.getBlue()
};
+            rgb.setVal(rgbBytes);
+            alphaPct = (addAlpha) ? rgb.addNewAlpha() : null;
+        } else {
+            CTScRgbColor rgb = fill.addNewScrgbClr();
+            rgb.setR(DrawPaint.srgb2lin(rgbaf[0]));
+            rgb.setG(DrawPaint.srgb2lin(rgbaf[1]));
+            rgb.setB(DrawPaint.srgb2lin(rgbaf[2]));
+            alphaPct = (addAlpha) ? rgb.addNewAlpha() : null;
+        }
+
+        // alpha (%)
+        if (alphaPct != null) {
+            alphaPct.setVal((int)(100000 * rgbaf[3]));
+        }
+    }
+    
+    /**
+     * @return true, if this is an integer color value
+     */
+    private static boolean isInt(float f) {
+        return Math.abs((f*255f) - Math.rint(f*255f)) < 0.00001f;
     }
     
     private int getRawValue(String elem) {

Modified: poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java?rev=1745412&r1=1745411&r2=1745412&view=diff
==============================================================================
--- poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java (original)
+++ poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/TestXSLFBugs.java Tue May 24 23:39:23
2016
@@ -40,10 +40,13 @@ import javax.imageio.ImageIO;
 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;
@@ -56,6 +59,7 @@ import org.apache.poi.xslf.usermodel.XSL
 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;
 
@@ -478,25 +482,39 @@ public class TestXSLFBugs {
 
     @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);
+    }
 }

Modified: poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFColor.java
URL: http://svn.apache.org/viewvc/poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFColor.java?rev=1745412&r1=1745411&r2=1745412&view=diff
==============================================================================
--- poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFColor.java (original)
+++ poi/trunk/src/ooxml/testcases/org/apache/poi/xslf/usermodel/TestXSLFColor.java Tue May
24 23:39:23 2016
@@ -104,7 +104,7 @@ public class TestXSLFColor {
         c.setLum2(50000);
 
         XSLFColor color = new XSLFColor(xml, null, null);
-        assertEquals(new Color(128, 00, 00), color.getColor());
+        assertEquals(Color.BLUE, color.getColor());
     }
 
     @Test



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@poi.apache.org
For additional commands, e-mail: commits-help@poi.apache.org


Mime
View raw message