| /* ==================================================================== |
| Licensed to the Apache Software Foundation (ASF) under one or more |
| contributor license agreements. See the NOTICE file distributed with |
| this work for additional information regarding copyright ownership. |
| The ASF licenses this file to You under the Apache License, Version 2.0 |
| (the "License"); you may not use this file except in compliance with |
| the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| ==================================================================== */ |
| package org.apache.poi.xslf.usermodel; |
| |
| import static org.junit.jupiter.api.Assertions.assertEquals; |
| import static org.junit.jupiter.api.Assertions.assertFalse; |
| import static org.junit.jupiter.api.Assertions.assertNotNull; |
| import static org.junit.jupiter.api.Assertions.assertNull; |
| import static org.junit.jupiter.api.Assertions.assertTrue; |
| |
| import java.awt.Color; |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.List; |
| |
| import org.apache.poi.POIDataSamples; |
| import org.apache.poi.sl.usermodel.Placeholder; |
| import org.apache.poi.sl.usermodel.StrokeStyle.LineCap; |
| import org.apache.poi.sl.usermodel.StrokeStyle.LineDash; |
| import org.apache.poi.util.Units; |
| import org.apache.poi.xslf.XSLFTestDataSamples; |
| import org.apache.poi.xslf.util.PPTX2PNG; |
| import org.apache.xmlbeans.XmlObject; |
| import org.junit.jupiter.api.Test; |
| import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleItem; |
| import org.openxmlformats.schemas.drawingml.x2006.main.CTEffectStyleList; |
| import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect; |
| import org.openxmlformats.schemas.drawingml.x2006.main.CTPresetGeometry2D; |
| import org.openxmlformats.schemas.drawingml.x2006.main.CTSchemeColor; |
| import org.openxmlformats.schemas.drawingml.x2006.main.CTShapeProperties; |
| import org.openxmlformats.schemas.drawingml.x2006.main.CTStyleMatrix; |
| import org.openxmlformats.schemas.drawingml.x2006.main.STLineCap; |
| import org.openxmlformats.schemas.drawingml.x2006.main.STPresetLineDashVal; |
| import org.openxmlformats.schemas.drawingml.x2006.main.STShapeType; |
| |
| class TestXSLFSimpleShape { |
| |
| @Test |
| void testLineStyles() throws IOException { |
| try (XMLSlideShow ppt = new XMLSlideShow()) { |
| XSLFSlide slide = ppt.createSlide(); |
| |
| XSLFSimpleShape shape = slide.createAutoShape(); |
| assertEquals(1, slide.getShapes().size()); |
| // line properties are not set by default |
| assertFalse(getSpPr(shape).isSetLn()); |
| |
| assertEquals(0., shape.getLineWidth(), 0); |
| assertNull(shape.getLineColor()); |
| assertNull(shape.getLineDash()); |
| assertNull(shape.getLineCap()); |
| |
| shape.setLineWidth(0); |
| shape.setLineColor(null); |
| shape.setLineDash(null); |
| shape.setLineCap(null); |
| |
| assertTrue(getSpPr(shape).isSetLn()); |
| assertTrue(getSpPr(shape).getLn().isSetNoFill()); |
| |
| // line width |
| shape.setLineWidth(1.0); |
| assertEquals(1.0, shape.getLineWidth(), 0); |
| assertEquals(Units.EMU_PER_POINT, getSpPr(shape).getLn().getW()); |
| shape.setLineWidth(5.5); |
| assertEquals(5.5, shape.getLineWidth(), 0); |
| assertEquals(Units.toEMU(5.5), getSpPr(shape).getLn().getW()); |
| shape.setLineWidth(0.0); |
| // setting line width to zero unsets the W attribute |
| assertFalse(getSpPr(shape).getLn().isSetW()); |
| |
| // line cap |
| shape.setLineCap(LineCap.FLAT); |
| assertEquals(LineCap.FLAT, shape.getLineCap()); |
| assertEquals(STLineCap.FLAT, getSpPr(shape).getLn().getCap()); |
| shape.setLineCap(LineCap.SQUARE); |
| assertEquals(LineCap.SQUARE, shape.getLineCap()); |
| assertEquals(STLineCap.SQ, getSpPr(shape).getLn().getCap()); |
| shape.setLineCap(LineCap.ROUND); |
| assertEquals(LineCap.ROUND, shape.getLineCap()); |
| assertEquals(STLineCap.RND, getSpPr(shape).getLn().getCap()); |
| shape.setLineCap(null); |
| // setting cap to null unsets the Cap attribute |
| assertFalse(getSpPr(shape).getLn().isSetCap()); |
| |
| // line dash |
| shape.setLineDash(LineDash.SOLID); |
| assertEquals(LineDash.SOLID, shape.getLineDash()); |
| assertEquals(STPresetLineDashVal.SOLID, getSpPr(shape).getLn().getPrstDash().getVal()); |
| shape.setLineDash(LineDash.DASH_DOT); |
| assertEquals(LineDash.DASH_DOT, shape.getLineDash()); |
| assertEquals(STPresetLineDashVal.DASH_DOT, getSpPr(shape).getLn().getPrstDash().getVal()); |
| shape.setLineDash(LineDash.LG_DASH_DOT); |
| assertEquals(LineDash.LG_DASH_DOT, shape.getLineDash()); |
| assertEquals(STPresetLineDashVal.LG_DASH_DOT, getSpPr(shape).getLn().getPrstDash().getVal()); |
| shape.setLineDash(null); |
| // setting dash width to null unsets the Dash element |
| assertFalse(getSpPr(shape).getLn().isSetPrstDash()); |
| |
| // line color |
| assertFalse(getSpPr(shape).getLn().isSetSolidFill()); |
| shape.setLineColor(Color.RED); |
| assertEquals(Color.RED, shape.getLineColor()); |
| assertTrue(getSpPr(shape).getLn().isSetSolidFill()); |
| shape.setLineColor(Color.BLUE); |
| assertEquals(Color.BLUE, shape.getLineColor()); |
| assertTrue(getSpPr(shape).getLn().isSetSolidFill()); |
| shape.setLineColor(null); |
| assertNull(shape.getLineColor()); |
| // setting dash width to null unsets the SolidFill element |
| assertFalse(getSpPr(shape).getLn().isSetSolidFill()); |
| |
| XSLFSimpleShape ln2 = slide.createAutoShape(); |
| ln2.setLineDash(LineDash.DOT); |
| assertEquals(LineDash.DOT, ln2.getLineDash()); |
| ln2.setLineWidth(0.); |
| assertEquals(0., ln2.getLineWidth(), 0); |
| |
| XSLFSimpleShape ln3 = slide.createAutoShape(); |
| ln3.setLineWidth(1.); |
| assertEquals(1., ln3.getLineWidth(), 0); |
| ln3.setLineDash(null); |
| assertNull(ln3.getLineDash()); |
| ln3.setLineCap(null); |
| assertNull(ln3.getLineDash()); |
| } |
| } |
| |
| @Test |
| void testFill() throws IOException { |
| try (XMLSlideShow ppt = new XMLSlideShow()) { |
| XSLFSlide slide = ppt.createSlide(); |
| |
| XSLFAutoShape shape = slide.createAutoShape(); |
| // line properties are not set by default |
| assertFalse(getSpPr(shape).isSetSolidFill()); |
| |
| assertNull(shape.getFillColor()); |
| shape.setFillColor(null); |
| assertNull(shape.getFillColor()); |
| assertFalse(getSpPr(shape).isSetSolidFill()); |
| |
| shape.setFillColor(Color.RED); |
| assertEquals(Color.RED, shape.getFillColor()); |
| shape.setFillColor(Color.DARK_GRAY); |
| assertEquals(Color.DARK_GRAY, shape.getFillColor()); |
| assertTrue(getSpPr(shape).isSetSolidFill()); |
| |
| shape.setFillColor(null); |
| assertNull(shape.getFillColor()); |
| assertFalse(getSpPr(shape).isSetSolidFill()); |
| } |
| } |
| |
| @Test |
| void testDefaultProperties() throws IOException { |
| try (XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx")) { |
| XSLFSlide slide6 = ppt.getSlides().get(5); |
| List<XSLFShape> shapes = slide6.getShapes(); |
| for (XSLFShape xs : shapes) { |
| XSLFSimpleShape s = (XSLFSimpleShape) xs; |
| // all shapes have a theme color="accent1" |
| assertEquals("accent1", s.getSpStyle().getFillRef().getSchemeClr().getVal().toString()); |
| assertEquals(2.0, s.getLineWidth(), 0); |
| assertEquals(LineCap.FLAT, s.getLineCap()); |
| assertEquals(new Color(79, 129, 189), s.getLineColor()); |
| } |
| |
| XSLFSimpleShape s0 = (XSLFSimpleShape) shapes.get(0); |
| // fill is not set |
| assertNull(getSpPr(s0).getSolidFill()); |
| //assertEquals(slide6.getTheme().getColor("accent1").getColor(), s0.getFillColor()); |
| assertEquals(new Color(79, 129, 189), s0.getFillColor()); |
| |
| // lighter 80% |
| XSLFSimpleShape s1 = (XSLFSimpleShape) shapes.get(1); |
| CTSchemeColor ref1 = getSpPr(s1).getSolidFill().getSchemeClr(); |
| assertEquals(1, ref1.sizeOfLumModArray()); |
| assertEquals(1, ref1.sizeOfLumOffArray()); |
| assertEquals(20000, ref1.getLumModArray(0).getVal()); |
| assertEquals(80000, ref1.getLumOffArray(0).getVal()); |
| assertEquals("accent1", ref1.getVal().toString()); |
| assertEquals(new Color(220, 230, 242), s1.getFillColor()); |
| |
| // lighter 60% |
| XSLFSimpleShape s2 = (XSLFSimpleShape) shapes.get(2); |
| CTSchemeColor ref2 = getSpPr(s2).getSolidFill().getSchemeClr(); |
| assertEquals(1, ref2.sizeOfLumModArray()); |
| assertEquals(1, ref2.sizeOfLumOffArray()); |
| assertEquals(40000, ref2.getLumModArray(0).getVal()); |
| assertEquals(60000, ref2.getLumOffArray(0).getVal()); |
| assertEquals("accent1", ref2.getVal().toString()); |
| assertEquals(new Color(185, 205, 229), s2.getFillColor()); |
| |
| // lighter 40% |
| XSLFSimpleShape s3 = (XSLFSimpleShape) shapes.get(3); |
| CTSchemeColor ref3 = getSpPr(s3).getSolidFill().getSchemeClr(); |
| assertEquals(1, ref3.sizeOfLumModArray()); |
| assertEquals(1, ref3.sizeOfLumOffArray()); |
| assertEquals(60000, ref3.getLumModArray(0).getVal()); |
| assertEquals(40000, ref3.getLumOffArray(0).getVal()); |
| assertEquals("accent1", ref3.getVal().toString()); |
| assertEquals(new Color(149, 179, 215), s3.getFillColor()); |
| |
| // darker 25% |
| XSLFSimpleShape s4 = (XSLFSimpleShape) shapes.get(4); |
| CTSchemeColor ref4 = getSpPr(s4).getSolidFill().getSchemeClr(); |
| assertEquals(1, ref4.sizeOfLumModArray()); |
| assertEquals(0, ref4.sizeOfLumOffArray()); |
| assertEquals(75000, ref4.getLumModArray(0).getVal()); |
| assertEquals("accent1", ref3.getVal().toString()); |
| assertEquals(new Color(55, 96, 146), s4.getFillColor()); |
| |
| XSLFSimpleShape s5 = (XSLFSimpleShape) shapes.get(5); |
| CTSchemeColor ref5 = getSpPr(s5).getSolidFill().getSchemeClr(); |
| assertEquals(1, ref5.sizeOfLumModArray()); |
| assertEquals(0, ref5.sizeOfLumOffArray()); |
| assertEquals(50000, ref5.getLumModArray(0).getVal()); |
| assertEquals("accent1", ref5.getVal().toString()); |
| assertEquals(new Color(37, 64, 97), s5.getFillColor()); |
| } |
| } |
| |
| @Test |
| void testAnchor() throws IOException { |
| try (XMLSlideShow ppt = XSLFTestDataSamples.openSampleDocument("shapes.pptx")) { |
| List<XSLFSlide> slide = ppt.getSlides(); |
| |
| XSLFSlide slide2 = slide.get(1); |
| XSLFSlideLayout layout2 = slide2.getSlideLayout(); |
| List<XSLFShape> shapes2 = slide2.getShapes(); |
| XSLFTextShape sh1 = (XSLFTextShape) shapes2.get(0); |
| assertEquals(Placeholder.CENTERED_TITLE, sh1.getTextType()); |
| assertEquals("PPTX Title", sh1.getText()); |
| assertFalse(getSpPr(sh1).isSetXfrm()); // xfrm is not set, the query is delegated to the slide layout |
| assertEquals(sh1.getAnchor(), layout2.getTextShapeByType(Placeholder.CENTERED_TITLE).getAnchor()); |
| |
| XSLFTextShape sh2 = (XSLFTextShape) shapes2.get(1); |
| assertEquals("Subtitle\nAnd second line", sh2.getText()); |
| assertEquals(Placeholder.SUBTITLE, sh2.getTextType()); |
| assertFalse(getSpPr(sh2).isSetXfrm()); // xfrm is not set, the query is delegated to the slide layout |
| assertEquals(sh2.getAnchor(), layout2.getTextShapeByType(Placeholder.SUBTITLE).getAnchor()); |
| |
| XSLFSlide slide5 = slide.get(4); |
| XSLFSlideLayout layout5 = slide5.getSlideLayout(); |
| XSLFTextShape shTitle = slide5.getTextShapeByType(Placeholder.TITLE); |
| assertEquals("Hyperlinks", shTitle.getText()); |
| // xfrm is not set, the query is delegated to the slide layout |
| assertFalse(getSpPr(shTitle).isSetXfrm()); |
| // xfrm is not set, the query is delegated to the slide master |
| assertFalse(getSpPr(layout5.getTextShapeByType(Placeholder.TITLE)).isSetXfrm()); |
| assertTrue(getSpPr(layout5.getSlideMaster().getTextShapeByType(Placeholder.TITLE)).isSetXfrm()); |
| assertEquals(shTitle.getAnchor(), layout5.getSlideMaster().getTextShapeByType(Placeholder.TITLE).getAnchor()); |
| } |
| } |
| |
| @SuppressWarnings({"unused", "deprecation"}) |
| @Test |
| void testShadowEffects() throws IOException{ |
| try (XMLSlideShow ppt = new XMLSlideShow()) { |
| XSLFSlide slide = ppt.createSlide(); |
| CTStyleMatrix styleMatrix = slide.getTheme().getXmlObject().getThemeElements().getFmtScheme(); |
| CTEffectStyleList lst = styleMatrix.getEffectStyleLst(); |
| assertNotNull(lst); |
| for (CTEffectStyleItem ef : lst.getEffectStyleArray()) { |
| CTOuterShadowEffect obj = ef.getEffectLst().getOuterShdw(); |
| } |
| } |
| } |
| |
| @Test |
| void testValidGeometry() throws Exception { |
| try (XMLSlideShow ppt = new XMLSlideShow()) { |
| XSLFSlide slide = ppt.createSlide(); |
| |
| XSLFSimpleShape shape = slide.createAutoShape(); |
| CTShapeProperties spPr = getSpPr(shape); |
| |
| CTPresetGeometry2D prstGeom = CTPresetGeometry2D.Factory.newInstance(); |
| prstGeom.setPrst(STShapeType.Enum.forInt(1)); |
| |
| assertNotNull(prstGeom.getPrst()); |
| assertNotNull(prstGeom.getPrst().toString()); |
| assertNotNull(spPr.getPrstGeom()); |
| spPr.setPrstGeom(prstGeom); |
| assertNotNull(spPr.getPrstGeom().getPrst()); |
| assertNotNull(spPr.getPrstGeom().getPrst().toString()); |
| |
| assertNotNull(shape.getGeometry()); |
| } |
| } |
| |
| @Test |
| void testArrayStoreException() throws Exception { |
| File tmpDir = new File("build/tmp/"); |
| |
| // fix maven build errors |
| if (!tmpDir.exists()) { |
| assertTrue(tmpDir.mkdirs()); |
| } |
| |
| File file = POIDataSamples.getSlideShowInstance().getFile("aascu.org_workarea_downloadasset.aspx_id=5864.pptx"); |
| String[] args = { |
| "-format", "null", // png,gif,jpg,svg or null for test |
| "-slide", "-1", // -1 for all |
| "-outdir", tmpDir.getCanonicalPath(), |
| "-quiet", |
| "-fixside", "long", |
| "-scale", "800", |
| file.getAbsolutePath() |
| }; |
| PPTX2PNG.main(args); |
| } |
| |
| static CTShapeProperties getSpPr(XSLFShape shape) { |
| XmlObject xo = shape.getShapeProperties(); |
| assertTrue(xo instanceof CTShapeProperties); |
| return (CTShapeProperties)xo; |
| } |
| } |