Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

TestXSLFBugs.java 52KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243
  1. /* ====================================================================
  2. Licensed to the Apache Software Foundation (ASF) under one or more
  3. contributor license agreements. See the NOTICE file distributed with
  4. this work for additional information regarding copyright ownership.
  5. The ASF licenses this file to You under the Apache License, Version 2.0
  6. (the "License"); you may not use this file except in compliance with
  7. the License. You may obtain a copy of the License at
  8. http://www.apache.org/licenses/LICENSE-2.0
  9. Unless required by applicable law or agreed to in writing, software
  10. distributed under the License is distributed on an "AS IS" BASIS,
  11. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. See the License for the specific language governing permissions and
  13. limitations under the License.
  14. ==================================================================== */
  15. package org.apache.poi.xslf;
  16. import static org.apache.poi.POITestCase.assertContains;
  17. import static org.apache.poi.sl.draw.DrawTextParagraph.HYPERLINK_HREF;
  18. import static org.apache.poi.sl.draw.DrawTextParagraph.HYPERLINK_LABEL;
  19. import static org.apache.poi.xslf.XSLFTestDataSamples.openSampleDocument;
  20. import static org.apache.poi.xslf.XSLFTestDataSamples.writeOutAndReadBack;
  21. import static org.junit.jupiter.api.Assertions.*;
  22. import static org.junit.jupiter.api.Assumptions.assumeFalse;
  23. import java.awt.Color;
  24. import java.awt.LinearGradientPaint;
  25. import java.awt.MultipleGradientPaint;
  26. import java.awt.Paint;
  27. import java.awt.RadialGradientPaint;
  28. import java.awt.geom.Point2D;
  29. import java.awt.geom.Rectangle2D;
  30. import java.io.File;
  31. import java.io.FileInputStream;
  32. import java.io.IOException;
  33. import java.net.URI;
  34. import java.text.AttributedCharacterIterator;
  35. import java.text.AttributedCharacterIterator.Attribute;
  36. import java.text.CharacterIterator;
  37. import java.util.ArrayList;
  38. import java.util.Arrays;
  39. import java.util.Collection;
  40. import java.util.List;
  41. import java.util.Map;
  42. import java.util.Optional;
  43. import java.util.function.Function;
  44. import java.util.stream.Collectors;
  45. import java.util.stream.Stream;
  46. import org.apache.commons.io.output.NullOutputStream;
  47. import org.apache.commons.io.output.NullPrintStream;
  48. import org.apache.poi.POIDataSamples;
  49. import org.apache.poi.common.usermodel.HyperlinkType;
  50. import org.apache.poi.extractor.ExtractorFactory;
  51. import org.apache.poi.ooxml.HyperlinkRelationship;
  52. import org.apache.poi.ooxml.POIXMLDocumentPart;
  53. import org.apache.poi.ooxml.POIXMLDocumentPart.RelationPart;
  54. import org.apache.poi.ooxml.ReferenceRelationship;
  55. import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
  56. import org.apache.poi.openxml4j.opc.OPCPackage;
  57. import org.apache.poi.openxml4j.opc.PackagePartName;
  58. import org.apache.poi.openxml4j.opc.PackagingURIHelper;
  59. import org.apache.poi.sl.draw.DrawFactory;
  60. import org.apache.poi.sl.draw.DrawPaint;
  61. import org.apache.poi.sl.extractor.SlideShowExtractor;
  62. import org.apache.poi.sl.usermodel.Hyperlink;
  63. import org.apache.poi.sl.usermodel.PaintStyle;
  64. import org.apache.poi.sl.usermodel.PaintStyle.SolidPaint;
  65. import org.apache.poi.sl.usermodel.PaintStyle.TexturePaint;
  66. import org.apache.poi.sl.usermodel.PictureData;
  67. import org.apache.poi.sl.usermodel.PictureData.PictureType;
  68. import org.apache.poi.sl.usermodel.PictureShape;
  69. import org.apache.poi.sl.usermodel.Shape;
  70. import org.apache.poi.sl.usermodel.ShapeType;
  71. import org.apache.poi.sl.usermodel.Slide;
  72. import org.apache.poi.sl.usermodel.SlideShow;
  73. import org.apache.poi.sl.usermodel.SlideShowFactory;
  74. import org.apache.poi.sl.usermodel.TextParagraph;
  75. import org.apache.poi.sl.usermodel.TextRun;
  76. import org.apache.poi.sl.usermodel.TextShape;
  77. import org.apache.poi.sl.usermodel.VerticalAlignment;
  78. import org.apache.poi.xslf.usermodel.*;
  79. import org.apache.poi.xslf.util.DummyGraphics2d;
  80. import org.apache.poi.xssf.XSSFTestDataSamples;
  81. import org.junit.jupiter.api.BeforeAll;
  82. import org.junit.jupiter.api.Disabled;
  83. import org.junit.jupiter.api.Test;
  84. import org.junit.jupiter.api.function.ThrowingSupplier;
  85. import org.junit.jupiter.params.ParameterizedTest;
  86. import org.junit.jupiter.params.provider.ValueSource;
  87. import org.openxmlformats.schemas.drawingml.x2006.main.CTOuterShadowEffect;
  88. import org.openxmlformats.schemas.presentationml.x2006.main.CTShape;
  89. class TestXSLFBugs {
  90. private static final POIDataSamples slTests = POIDataSamples.getSlideShowInstance();
  91. private static boolean xslfOnly;
  92. @BeforeAll
  93. public static void checkHslf() {
  94. try {
  95. Class.forName("org.apache.poi.hslf.usermodel.HSLFSlideShow");
  96. } catch (Exception e) {
  97. xslfOnly = true;
  98. }
  99. }
  100. @Test
  101. void bug62929() throws Exception {
  102. try (XMLSlideShow ss1 = openSampleDocument("missing-blip-fill.pptx")) {
  103. assertEquals(1, ss1.getSlides().size());
  104. XSLFSlide slide = ss1.getSlides().get(0);
  105. assertEquals(1,slide.getShapes().size());
  106. XSLFPictureShape picture = (XSLFPictureShape) slide.getShapes().get(0);
  107. assertEquals(662, picture.getShapeId());
  108. assertFalse(picture.isExternalLinkedPicture());
  109. assertNull(picture.getPictureData());
  110. assertNull(picture.getPictureLink());
  111. assertNull(picture.getClipping());
  112. }
  113. }
  114. @Test
  115. void bug62736() throws Exception {
  116. try (XMLSlideShow ss1 = openSampleDocument("bug62736.pptx")) {
  117. assertEquals(1, ss1.getSlides().size());
  118. XSLFSlide slide0 = ss1.getSlides().get(0);
  119. assertEquals(4, slide0.getShapes().size());
  120. assertRelation(slide0, "/ppt/slides/slide1.xml", null);
  121. assertRelation(slide0, "/ppt/slideLayouts/slideLayout1.xml", "rId1");
  122. assertRelation(slide0, "/ppt/media/image1.png", "rId2");
  123. assertEquals(2, slide0.getRelations().size());
  124. List<XSLFPictureShape> pictures = new ArrayList<>();
  125. for (XSLFShape shape : slide0.getShapes()) {
  126. if (shape instanceof XSLFPictureShape) {
  127. pictures.add((XSLFPictureShape) shape);
  128. }
  129. }
  130. assertEquals(2, pictures.size());
  131. assertEquals("image1.png", pictures.get(0).getPictureData().getFileName());
  132. assertEquals("image1.png", pictures.get(1).getPictureData().getFileName());
  133. // blipId is rId2 of both pictures
  134. // remove just the first picture
  135. slide0.removeShape(pictures.get(0));
  136. assertEquals(3, slide0.getShapes().size());
  137. assertRelation(slide0, "/ppt/slides/slide1.xml", null);
  138. assertRelation(slide0, "/ppt/slideLayouts/slideLayout1.xml", "rId1");
  139. // the bug is that the following relation is gone
  140. assertRelation(slide0, "/ppt/media/image1.png", "rId2");
  141. assertEquals(2, slide0.getRelations().size());
  142. // Save and re-load
  143. try (XMLSlideShow ss2 = writeOutAndReadBack(ss1)) {
  144. assertEquals(1, ss2.getSlides().size());
  145. slide0 = ss2.getSlides().get(0);
  146. assertRelation(slide0, "/ppt/slides/slide1.xml", null);
  147. assertRelation(slide0, "/ppt/slideLayouts/slideLayout1.xml", "rId1");
  148. assertRelation(slide0, "/ppt/media/image1.png", "rId2");
  149. assertEquals(2, slide0.getRelations().size());
  150. pictures.clear();
  151. for (XSLFShape shape : slide0.getShapes()) {
  152. if (shape instanceof XSLFPictureShape) {
  153. pictures.add((XSLFPictureShape) shape);
  154. }
  155. }
  156. assertEquals(1, pictures.size());
  157. assertEquals("image1.png", pictures.get(0).getPictureData().getFileName());
  158. slide0.removeShape(pictures.get(0));
  159. assertEquals(2, slide0.getShapes().size());
  160. assertRelation(slide0, "/ppt/slides/slide1.xml", null);
  161. assertRelation(slide0, "/ppt/slideLayouts/slideLayout1.xml", "rId1");
  162. assertNull(slide0.getRelationById("rId2"));
  163. assertEquals(1, slide0.getRelations().size());
  164. // Save and re-load
  165. try (XMLSlideShow ss3 = writeOutAndReadBack(ss2)) {
  166. assertEquals(1, ss3.getSlides().size());
  167. slide0 = ss3.getSlides().get(0);
  168. assertRelation(slide0, "/ppt/slides/slide1.xml", null);
  169. assertRelation(slide0, "/ppt/slideLayouts/slideLayout1.xml", "rId1");
  170. assertEquals(2, slide0.getShapes().size());
  171. }
  172. }
  173. }
  174. }
  175. @Test
  176. void bug61589() throws IOException {
  177. try (XMLSlideShow src = new XMLSlideShow();
  178. XMLSlideShow dest = new XMLSlideShow()) {
  179. XSLFSlide slide = src.createSlide();
  180. XSLFSlide slide2 = src.createSlide();
  181. XSLFTextBox shape = slide.createTextBox();
  182. shape.setAnchor(new Rectangle2D.Double(100, 100, 400, 100));
  183. XSLFTextParagraph p = shape.addNewTextParagraph();
  184. XSLFTextRun r = p.addNewTextRun();
  185. p.addLineBreak();
  186. r.setText("Apache POI");
  187. r.createHyperlink().setAddress("https://poi.apache.org");
  188. // create hyperlink pointing to a page, which isn't available at the time of importing the content
  189. r = p.addNewTextRun();
  190. r.setText("Slide 2");
  191. r.createHyperlink().linkToSlide(slide2);
  192. shape = slide2.createTextBox();
  193. shape.setAnchor(new Rectangle2D.Double(100, 100, 400, 100));
  194. shape.setText("slide 2");
  195. dest.createSlide().importContent(slide);
  196. dest.createSlide().importContent(slide2);
  197. try (XMLSlideShow ppt3 = writeOutAndReadBack(dest)) {
  198. XSLFSlide slide3 = ppt3.getSlides().get(0);
  199. XSLFTextBox shape3 = (XSLFTextBox) slide3.getShapes().get(0);
  200. XSLFTextParagraph p3 = shape3.getTextParagraphs().get(1);
  201. XSLFHyperlink h1 = p3.getTextRuns().get(0).getHyperlink();
  202. assertNotNull(h1);
  203. assertEquals("https://poi.apache.org", h1.getAddress());
  204. XSLFHyperlink h2 = p3.getTextRuns().get(2).getHyperlink();
  205. assertNotNull(h2);
  206. // relative url will be resolved to an absolute url, therefore this doesn't equals to "slide2.xml"
  207. assertEquals("/ppt/slides/slide2.xml", h2.getAddress());
  208. RelationPart sldRef = slide3.getRelationPartById(h2.getXmlObject().getId());
  209. assertTrue(sldRef.getDocumentPart() instanceof XSLFSlide);
  210. }
  211. }
  212. }
  213. @Test
  214. void bug62587() throws IOException {
  215. Object[][] pics = {
  216. {"santa.wmf", PictureType.WMF, XSLFRelation.IMAGE_WMF},
  217. {"tomcat.png", PictureType.PNG, XSLFRelation.IMAGE_PNG},
  218. {"clock.jpg", PictureType.JPEG, XSLFRelation.IMAGE_JPEG}
  219. };
  220. try (XMLSlideShow ppt1 = new XMLSlideShow()) {
  221. Slide<?, ?> slide = ppt1.createSlide();
  222. XSLFPictureData pd1 = ppt1.addPicture(slTests.getFile("wrench.emf"), PictureType.EMF);
  223. PictureShape<?, ?> ps1 = slide.createPicture(pd1);
  224. ps1.setAnchor(new Rectangle2D.Double(100, 100, 100, 100));
  225. try (XMLSlideShow ppt2 = writeOutAndReadBack(ppt1)) {
  226. XSLFSlide s1 = ppt2.getSlides().get(0);
  227. for (Object[] p : pics) {
  228. XSLFSlide s2 = ppt2.createSlide();
  229. s2.importContent(s1);
  230. XSLFPictureData pd2 = ppt2.addPicture(slTests.getFile((String) p[0]), (PictureType) p[1]);
  231. XSLFPictureShape ps2 = (XSLFPictureShape) s2.getShapes().get(0);
  232. Rectangle2D anchor2 = ps2.getAnchor();
  233. s2.removeShape(ps2);
  234. ps2 = s2.createPicture(pd2);
  235. ps2.setAnchor(anchor2);
  236. }
  237. try (XMLSlideShow ppt3 = writeOutAndReadBack(ppt2)) {
  238. for (XSLFSlide sl : ppt3.getSlides()) {
  239. List<RelationPart> rels = sl.getRelationParts();
  240. assertEquals(2, rels.size());
  241. RelationPart rel0 = rels.get(0);
  242. assertEquals("rId1", rel0.getRelationship().getId());
  243. assertEquals(XSLFRelation.SLIDE_LAYOUT.getRelation(), rel0.getRelationship().getRelationshipType());
  244. RelationPart rel1 = rels.get(1);
  245. assertNotEquals("rId1", rel1.getRelationship().getId());
  246. assertEquals(XSLFRelation.IMAGES.getRelation(), rel1.getRelationship().getRelationshipType());
  247. }
  248. }
  249. }
  250. }
  251. }
  252. @Test
  253. void bug60499() throws IOException, InvalidFormatException {
  254. PackagePartName ppn = PackagingURIHelper.createPartName("/ppt/media/image1.png");
  255. try (XMLSlideShow ppt1 = openSampleDocument("bug60499.pptx")) {
  256. XSLFSlide slide1 = ppt1.getSlides().get(0);
  257. Optional<XSLFShape> shapeToDelete1 =
  258. slide1.getShapes().stream().filter(s -> s instanceof XSLFPictureShape).findFirst();
  259. assertTrue(shapeToDelete1.isPresent());
  260. slide1.removeShape(shapeToDelete1.get());
  261. assertTrue(slide1.getRelationParts().stream()
  262. .allMatch(rp -> "rId1,rId3".contains(rp.getRelationship().getId())));
  263. assertNotNull(ppt1.getPackage().getPart(ppn));
  264. }
  265. try (XMLSlideShow ppt2 = openSampleDocument("bug60499.pptx")) {
  266. XSLFSlide slide2 = ppt2.getSlides().get(0);
  267. Optional<XSLFShape> shapeToDelete2 =
  268. slide2.getShapes().stream().filter(s -> s instanceof XSLFPictureShape).skip(1).findFirst();
  269. assertTrue(shapeToDelete2.isPresent());
  270. slide2.removeShape(shapeToDelete2.get());
  271. assertTrue(slide2.getRelationParts().stream()
  272. .allMatch(rp -> "rId1,rId2".contains(rp.getRelationship().getId())));
  273. assertNotNull(ppt2.getPackage().getPart(ppn));
  274. }
  275. try (XMLSlideShow ppt3 = openSampleDocument("bug60499.pptx")) {
  276. XSLFSlide slide3 = ppt3.getSlides().get(0);
  277. slide3.getShapes().stream()
  278. .filter(s -> s instanceof XSLFPictureShape)
  279. .collect(Collectors.toList())
  280. .forEach(slide3::removeShape);
  281. assertNull(ppt3.getPackage().getPart(ppn));
  282. }
  283. }
  284. @Test
  285. void bug51187() throws Exception {
  286. try (XMLSlideShow ss1 = openSampleDocument("51187.pptx")) {
  287. assertEquals(1, ss1.getSlides().size());
  288. // Check the relations on it
  289. // Note - rId3 is a self reference
  290. XSLFSlide slide0 = ss1.getSlides().get(0);
  291. assertRelation(slide0, "/ppt/slides/slide1.xml", null);
  292. assertRelation(slide0, "/ppt/slideLayouts/slideLayout12.xml", "rId1");
  293. assertRelation(slide0, "/ppt/notesSlides/notesSlide1.xml", "rId2");
  294. assertRelation(slide0, "/ppt/slides/slide1.xml", "rId3");
  295. assertRelation(slide0, "/ppt/media/image1.png", "rId4");
  296. // Save and re-load
  297. try (XMLSlideShow ss2 = writeOutAndReadBack(ss1)) {
  298. assertEquals(1, ss2.getSlides().size());
  299. slide0 = ss2.getSlides().get(0);
  300. assertRelation(slide0, "/ppt/slides/slide1.xml", null);
  301. assertRelation(slide0, "/ppt/slideLayouts/slideLayout12.xml", "rId1");
  302. assertRelation(slide0, "/ppt/notesSlides/notesSlide1.xml", "rId2");
  303. // TODO Fix this
  304. assertRelation(slide0, "/ppt/slides/slide1.xml", "rId3");
  305. assertRelation(slide0, "/ppt/media/image1.png", "rId4");
  306. }
  307. }
  308. }
  309. private static void assertRelation(XSLFSlide slide, String exp, String rId) {
  310. POIXMLDocumentPart pd = (rId != null) ? slide.getRelationById(rId) : slide;
  311. assertNotNull(pd);
  312. assertEquals(exp, pd.getPackagePart().getPartName().getName());
  313. }
  314. /**
  315. * Slide relations with anchors in them
  316. */
  317. @Test
  318. void tika705() throws Exception {
  319. try (XMLSlideShow ss = openSampleDocument("with_japanese.pptx")) {
  320. // Should have one slide
  321. assertEquals(1, ss.getSlides().size());
  322. XSLFSlide slide = ss.getSlides().get(0);
  323. // Check the relations from this
  324. Collection<RelationPart> rels = slide.getRelationParts();
  325. Collection<ReferenceRelationship> referenceRelationships = slide.getReferenceRelationships();
  326. // Should have 6 relations:
  327. // 1 external hyperlink (skipped from list)
  328. // 4 internal hyperlinks
  329. // 1 slide layout
  330. assertEquals(1, rels.size());
  331. assertEquals(5, referenceRelationships.size());
  332. int layouts = 0;
  333. int hyperlinks = 0;
  334. int extHyperLinks = 0;
  335. for (RelationPart p : rels) {
  336. if (p.getDocumentPart() instanceof XSLFSlideLayout) {
  337. layouts++;
  338. }
  339. }
  340. for (ReferenceRelationship ref : referenceRelationships) {
  341. if (ref instanceof HyperlinkRelationship) {
  342. if (ref.isExternal()) extHyperLinks++;
  343. else hyperlinks++;
  344. }
  345. }
  346. assertEquals(1, layouts);
  347. assertEquals(4, hyperlinks);
  348. assertEquals(1, extHyperLinks);
  349. // Hyperlinks should all be to #_ftn1 or #ftnref1
  350. for (RelationPart p : rels) {
  351. if (p.getRelationship().getRelationshipType().equals(XSLFRelation.HYPERLINK.getRelation())) {
  352. URI target = p.getRelationship().getTargetURI();
  353. String frag = target.getFragment();
  354. assertTrue(frag.equals("_ftn1") || frag.equals("_ftnref1"), "Invalid target " + frag + " on " + target);
  355. }
  356. }
  357. }
  358. }
  359. /**
  360. * A slideshow can have more than one rID pointing to a given
  361. * slide, eg presentation.xml rID1 -> slide1.xml, but slide1.xml
  362. * rID2 -> slide3.xml
  363. */
  364. @Test
  365. void bug54916() throws IOException {
  366. try (XMLSlideShow ss = openSampleDocument("OverlappingRelations.pptx")) {
  367. XSLFSlide slide;
  368. // Should find 4 slides
  369. assertEquals(4, ss.getSlides().size());
  370. // Check the text, to see we got them in order
  371. slide = ss.getSlides().get(0);
  372. assertContains(getSlideText(ss, slide), "POI cannot read this");
  373. slide = ss.getSlides().get(1);
  374. assertContains(getSlideText(ss, slide), "POI can read this");
  375. assertContains(getSlideText(ss, slide), "Has a relationship to another slide");
  376. slide = ss.getSlides().get(2);
  377. assertContains(getSlideText(ss, slide), "POI can read this");
  378. slide = ss.getSlides().get(3);
  379. assertContains(getSlideText(ss, slide), "POI can read this");
  380. }
  381. }
  382. /**
  383. * When the picture is not embedded but inserted only as a "link to file",
  384. * there is no data available and XSLFPictureShape.getPictureData()
  385. * gives a NPE, see bug #56812
  386. */
  387. @Test
  388. void bug56812() throws Exception {
  389. try (XMLSlideShow ppt = openSampleDocument("56812.pptx")) {
  390. int internalPictures = 0;
  391. int externalPictures = 0;
  392. for (XSLFSlide slide : ppt.getSlides()) {
  393. for (XSLFShape shape : slide.getShapes()) {
  394. assertNotNull(shape);
  395. if (shape instanceof XSLFPictureShape) {
  396. XSLFPictureShape picture = (XSLFPictureShape) shape;
  397. if (picture.isExternalLinkedPicture()) {
  398. externalPictures++;
  399. assertNotNull(picture.getPictureLink());
  400. } else {
  401. internalPictures++;
  402. XSLFPictureData data = picture.getPictureData();
  403. assertNotNull(data);
  404. assertNotNull(data.getFileName());
  405. }
  406. }
  407. }
  408. }
  409. assertEquals(2, internalPictures);
  410. assertEquals(1, externalPictures);
  411. }
  412. }
  413. private String getSlideText(XMLSlideShow ppt, XSLFSlide slide) throws IOException {
  414. try (SlideShowExtractor<XSLFShape, XSLFTextParagraph> extr = new SlideShowExtractor<>(ppt)) {
  415. // do not auto-close the slideshow
  416. extr.setCloseFilesystem(false);
  417. extr.setSlidesByDefault(true);
  418. extr.setNotesByDefault(false);
  419. extr.setMasterByDefault(false);
  420. return extr.getText(slide);
  421. }
  422. }
  423. @Test
  424. void bug57250() throws Exception {
  425. try (XMLSlideShow ss = new XMLSlideShow()) {
  426. for (String s : new String[]{"Slide1", "Slide2"}) {
  427. ss.createSlide().createTextBox().setText(s);
  428. }
  429. validateSlides(ss, false, "Slide1", "Slide2");
  430. XSLFSlide slide = ss.createSlide();
  431. slide.createTextBox().setText("New slide");
  432. validateSlides(ss, true, "Slide1", "Slide2", "New slide");
  433. // Move backward
  434. ss.setSlideOrder(slide, 0);
  435. validateSlides(ss, true, "New slide", "Slide1", "Slide2");
  436. // Move forward
  437. ss.setSlideOrder(slide, 1);
  438. validateSlides(ss, true, "Slide1", "New slide", "Slide2");
  439. // Move to end
  440. ss.setSlideOrder(slide, 0);
  441. ss.setSlideOrder(slide, 2);
  442. validateSlides(ss, true, "Slide1", "Slide2", "New slide");
  443. }
  444. }
  445. /**
  446. * When working with >9 images, make sure the sorting ensures
  447. * that image10.foo isn't between image1.foo and image2.foo
  448. */
  449. @Test
  450. void test57552() throws Exception {
  451. try (XMLSlideShow ss = new XMLSlideShow()) {
  452. for (String s : new String[]{"Slide1", "Slide2"}) {
  453. ss.createSlide().createTextBox().setText(s);
  454. }
  455. // Slide starts with just layout relation
  456. XSLFSlide slide = ss.getSlides().get(0);
  457. assertEquals(0, ss.getPictureData().size());
  458. assertEquals(1, slide.getShapes().size());
  459. assertEquals(1, slide.getRelations().size());
  460. final XSLFRelation expected = XSLFRelation.SLIDE_LAYOUT;
  461. final POIXMLDocumentPart relation = slide.getRelations().get(0);
  462. assertEquals(expected.getContentType(), relation.getPackagePart().getContentType());
  463. assertEquals(expected.getFileName(expected.getFileNameIndex(relation)), relation.getPackagePart().getPartName().getName());
  464. // Some dummy pictures
  465. byte[][] pics = new byte[15][3];
  466. for (int i = 0; i < pics.length; i++) {
  467. Arrays.fill(pics[i], (byte) i);
  468. }
  469. // Add a few pictures
  470. addPictures(ss, slide, pics, 0, 10);
  471. // Re-fetch the pictures and check
  472. for (int i = 0; i < 10; i++) {
  473. XSLFPictureShape shape = (XSLFPictureShape) slide.getShapes().get(i + 1);
  474. assertNotNull(shape.getPictureData());
  475. assertArrayEquals(pics[i], shape.getPictureData().getData());
  476. }
  477. // Add past 10
  478. addPictures(ss, slide, pics, 10, 15);
  479. // Check all pictures
  480. for (int i = 0; i < 15; i++) {
  481. XSLFPictureShape shape = (XSLFPictureShape) slide.getShapes().get(i + 1);
  482. assertNotNull(shape.getPictureData());
  483. assertArrayEquals(pics[i], shape.getPictureData().getData());
  484. }
  485. // Add a duplicate, check the right one is picked
  486. XSLFPictureData data = ss.addPicture(pics[3], PictureType.JPEG);
  487. assertEquals(3, data.getIndex());
  488. assertEquals(15, ss.getPictureData().size());
  489. XSLFPictureShape shape = slide.createPicture(data);
  490. assertNotNull(shape.getPictureData());
  491. assertArrayEquals(pics[3], shape.getPictureData().getData());
  492. assertEquals(17, slide.getShapes().size());
  493. // Save and re-load
  494. try (XMLSlideShow ss2 = writeOutAndReadBack(ss)) {
  495. slide = ss2.getSlides().get(0);
  496. // Check the 15 individual ones added
  497. for (int i = 0; i < 15; i++) {
  498. shape = (XSLFPictureShape) slide.getShapes().get(i + 1);
  499. assertNotNull(shape.getPictureData());
  500. assertArrayEquals(pics[i], shape.getPictureData().getData());
  501. }
  502. // Check the duplicate
  503. shape = (XSLFPictureShape) slide.getShapes().get(16);
  504. assertNotNull(shape.getPictureData());
  505. assertArrayEquals(pics[3], shape.getPictureData().getData());
  506. // Add another duplicate
  507. data = ss2.addPicture(pics[5], PictureType.JPEG);
  508. assertEquals(5, data.getIndex());
  509. assertEquals(15, ss2.getPictureData().size());
  510. shape = slide.createPicture(data);
  511. assertNotNull(shape.getPictureData());
  512. assertArrayEquals(pics[5], shape.getPictureData().getData());
  513. assertEquals(18, slide.getShapes().size());
  514. }
  515. }
  516. }
  517. private void addPictures(XMLSlideShow ss, XSLFSlide slide, byte[][] pics, int start, int end) {
  518. for (int i = start; i < end; i++) {
  519. XSLFPictureData data = ss.addPicture(pics[i], PictureType.JPEG);
  520. assertEquals(i, data.getIndex());
  521. assertEquals(i + 1, ss.getPictureData().size());
  522. XSLFPictureShape shape = slide.createPicture(data);
  523. assertNotNull(shape.getPictureData());
  524. assertArrayEquals(pics[i], shape.getPictureData().getData());
  525. assertEquals(i + 2, slide.getShapes().size());
  526. }
  527. }
  528. private void validateSlides(XMLSlideShow ss, boolean saveAndReload, String... slideTexts) throws IOException {
  529. if (saveAndReload) {
  530. try (XMLSlideShow ss2 = writeOutAndReadBack(ss)) {
  531. validateSlides(ss2, slideTexts);
  532. }
  533. } else {
  534. validateSlides(ss, slideTexts);
  535. }
  536. }
  537. private void validateSlides(XMLSlideShow ss, String... slideTexts) throws IOException {
  538. assertEquals(slideTexts.length, ss.getSlides().size());
  539. for (int i = 0; i < slideTexts.length; i++) {
  540. XSLFSlide slide = ss.getSlides().get(i);
  541. assertContains(getSlideText(ss, slide), slideTexts[i]);
  542. }
  543. }
  544. @Test
  545. void bug58205() throws IOException {
  546. try (XMLSlideShow ss = openSampleDocument("themes.pptx")) {
  547. int i = 1;
  548. for (XSLFSlideMaster sm : ss.getSlideMasters()) {
  549. assertEquals("rId" + (i++), ss.getRelationId(sm));
  550. }
  551. }
  552. }
  553. @ParameterizedTest
  554. @ValueSource(strings = {"45541_Footer.pptx", "SampleShow.pptx"})
  555. void bug55791(String fileName) throws IOException {
  556. try (XMLSlideShow ppt = openSampleDocument(fileName)) {
  557. assertTrue(ppt.getSlides().size() > 1);
  558. ppt.removeSlide(1);
  559. assertNotNull(ppt.createSlide());
  560. }
  561. }
  562. @Test
  563. void blibFillAlternateContent() throws IOException {
  564. try (XMLSlideShow ppt = openSampleDocument("2411-Performance_Up.pptx")) {
  565. XSLFPictureShape ps = (XSLFPictureShape) ppt.getSlides().get(4).getShapes().get(0);
  566. assertNotNull(ps.getPictureData());
  567. }
  568. }
  569. @Test
  570. void bug59434() throws IOException {
  571. String url1 = "https://poi.apache.org/changes.html";
  572. String url2 = "https://poi.apache.org/faq.html";
  573. try (XMLSlideShow ppt1 = new XMLSlideShow()) {
  574. PictureData pd1 = ppt1.addPicture(slTests.readFile("tomcat.png"), PictureType.PNG);
  575. PictureData pd2 = ppt1.addPicture(slTests.readFile("santa.wmf"), PictureType.WMF);
  576. XSLFSlide slide = ppt1.createSlide();
  577. XSLFPictureShape ps1 = slide.createPicture(pd1);
  578. ps1.setAnchor(new Rectangle2D.Double(20, 20, 100, 100));
  579. XSLFHyperlink hl1 = ps1.createHyperlink();
  580. hl1.linkToUrl(url1);
  581. XSLFPictureShape ps2 = slide.createPicture(pd2);
  582. ps2.setAnchor(new Rectangle2D.Double(120, 120, 100, 100));
  583. XSLFHyperlink hl2 = ps2.createHyperlink();
  584. hl2.linkToUrl(url2);
  585. try (XMLSlideShow ppt2 = writeOutAndReadBack(ppt1)) {
  586. slide = ppt2.getSlides().get(0);
  587. ps1 = (XSLFPictureShape) slide.getShapes().get(0);
  588. ps2 = (XSLFPictureShape) slide.getShapes().get(1);
  589. assertEquals(url1, ps1.getHyperlink().getAddress());
  590. assertEquals(url2, ps2.getHyperlink().getAddress());
  591. }
  592. }
  593. }
  594. @Test
  595. void bug58217() throws IOException {
  596. Color fillColor = new Color(1f, 1f, 0f, 0.1f);
  597. Color lineColor = new Color(25.3f / 255f, 1f, 0f, 0.4f);
  598. Color textColor = new Color(1f, 1f, 0f, 0.6f);
  599. try (XMLSlideShow ppt1 = new XMLSlideShow()) {
  600. XSLFSlide sl = ppt1.createSlide();
  601. XSLFAutoShape as = sl.createAutoShape();
  602. as.setShapeType(ShapeType.STAR_10);
  603. as.setAnchor(new Rectangle2D.Double(100, 100, 300, 300));
  604. as.setFillColor(fillColor);
  605. as.setLineColor(lineColor);
  606. as.setText("Alpha");
  607. as.setVerticalAlignment(VerticalAlignment.MIDDLE);
  608. as.setHorizontalCentered(true);
  609. XSLFTextRun tr = as.getTextParagraphs().get(0).getTextRuns().get(0);
  610. tr.setFontSize(32d);
  611. tr.setFontColor(textColor);
  612. try (XMLSlideShow ppt2 = writeOutAndReadBack(ppt1)) {
  613. sl = ppt2.getSlides().get(0);
  614. as = (XSLFAutoShape) sl.getShapes().get(0);
  615. checkColor(fillColor, as.getFillStyle().getPaint());
  616. checkColor(lineColor, as.getStrokeStyle().getPaint());
  617. checkColor(textColor, as.getTextParagraphs().get(0).getTextRuns().get(0).getFontColor());
  618. }
  619. }
  620. }
  621. private static void checkColor(Color expected, PaintStyle actualStyle) {
  622. assertTrue(actualStyle instanceof SolidPaint);
  623. SolidPaint ps = (SolidPaint) actualStyle;
  624. Color actual = DrawPaint.applyColorTransform(ps.getSolidColor());
  625. float[] expRGB = expected.getRGBComponents(null);
  626. float[] actRGB = actual.getRGBComponents(null);
  627. assertArrayEquals(expRGB, actRGB, 0.0001f);
  628. }
  629. @Test
  630. void bug55714() throws IOException {
  631. try (XMLSlideShow srcPptx = openSampleDocument("pptx2svg.pptx");
  632. XMLSlideShow newPptx = new XMLSlideShow()) {
  633. XSLFSlide srcSlide = srcPptx.getSlides().get(0);
  634. XSLFSlide newSlide = newPptx.createSlide();
  635. XSLFSlideLayout srcSlideLayout = srcSlide.getSlideLayout();
  636. XSLFSlideLayout newSlideLayout = newSlide.getSlideLayout();
  637. newSlideLayout.importContent(srcSlideLayout);
  638. XSLFSlideMaster srcSlideMaster = srcSlide.getSlideMaster();
  639. XSLFSlideMaster newSlideMaster = newSlide.getSlideMaster();
  640. newSlideMaster.importContent(srcSlideMaster);
  641. newSlide.importContent(srcSlide);
  642. try (XMLSlideShow rwPptx = writeOutAndReadBack(newPptx)) {
  643. PaintStyle ps = rwPptx.getSlides().get(0).getBackground().getFillStyle().getPaint();
  644. assertTrue(ps instanceof TexturePaint);
  645. }
  646. }
  647. }
  648. @Test
  649. void bug59273() throws IOException {
  650. try (XMLSlideShow ppt = openSampleDocument("bug59273.potx")) {
  651. ppt.getPackage().replaceContentType(
  652. XSLFRelation.PRESENTATIONML_TEMPLATE.getContentType(),
  653. XSLFRelation.MAIN.getContentType()
  654. );
  655. try (XMLSlideShow rwPptx = writeOutAndReadBack(ppt)) {
  656. OPCPackage pkg = rwPptx.getPackage();
  657. int size = pkg.getPartsByContentType(XSLFRelation.MAIN.getContentType()).size();
  658. assertEquals(1, size);
  659. size = pkg.getPartsByContentType(XSLFRelation.PRESENTATIONML_TEMPLATE.getContentType()).size();
  660. assertEquals(0, size);
  661. }
  662. }
  663. }
  664. @Test
  665. void bug60373() throws IOException {
  666. try (XMLSlideShow ppt = new XMLSlideShow()) {
  667. XSLFSlide sl = ppt.createSlide();
  668. XSLFTable t = sl.createTable();
  669. XSLFTableRow r = t.addRow();
  670. bug60373_addCell(r);
  671. bug60373_addCell(r);
  672. r = t.addRow();
  673. XSLFTableCell c = bug60373_addCell(r);
  674. // call getTextHeight, when table is not fully populated
  675. double th = c.getTextHeight();
  676. assertTrue(th > 10);
  677. }
  678. }
  679. private static XSLFTableCell bug60373_addCell(XSLFTableRow r) {
  680. XSLFTableCell cell = r.addCell();
  681. XSLFTextParagraph p = cell.addNewTextParagraph();
  682. XSLFTextRun tr = p.addNewTextRun();
  683. tr.setText("t");
  684. return cell;
  685. }
  686. @Test
  687. void bug60715() throws IOException {
  688. try (XMLSlideShow ppt = openSampleDocument("bug60715.pptx")) {
  689. assertDoesNotThrow((ThrowingSupplier<XSLFSlide>) ppt::createSlide);
  690. }
  691. }
  692. @Test
  693. void bug60662() throws IOException {
  694. try (XMLSlideShow src = new XMLSlideShow();
  695. XMLSlideShow dst = new XMLSlideShow()) {
  696. XSLFSlide sl = src.createSlide();
  697. XSLFGroupShape gs = sl.createGroup();
  698. gs.setAnchor(new Rectangle2D.Double(100, 100, 100, 100));
  699. gs.setInteriorAnchor(new Rectangle2D.Double(0, 0, 100, 100));
  700. XSLFAutoShape as = gs.createAutoShape();
  701. as.setAnchor(new Rectangle2D.Double(0, 0, 100, 100));
  702. as.setShapeType(ShapeType.STAR_24);
  703. as.setFillColor(Color.YELLOW);
  704. CTShape csh = (CTShape) as.getXmlObject();
  705. CTOuterShadowEffect shadow = csh.getSpPr().addNewEffectLst().addNewOuterShdw();
  706. shadow.setDir(270000);
  707. shadow.setDist(100000);
  708. shadow.addNewSrgbClr().setVal(new byte[]{0x00, (byte) 0xFF, 0x00});
  709. XSLFSlide sl2 = dst.createSlide();
  710. sl2.importContent(sl);
  711. XSLFGroupShape gs2 = (XSLFGroupShape) sl2.getShapes().get(0);
  712. XSLFAutoShape as2 = (XSLFAutoShape) gs2.getShapes().get(0);
  713. CTShape csh2 = (CTShape) as2.getXmlObject();
  714. assertTrue(csh2.getSpPr().isSetEffectLst());
  715. }
  716. }
  717. @Test
  718. void test60810() throws IOException {
  719. try (XMLSlideShow ppt = openSampleDocument("60810.pptx")) {
  720. for (XSLFSlide slide : ppt.getSlides()) {
  721. XSLFNotes notesSlide = ppt.getNotesSlide(slide);
  722. assertNotNull(notesSlide);
  723. }
  724. }
  725. }
  726. @Test
  727. void test60042() throws IOException {
  728. try (XMLSlideShow ppt = openSampleDocument("60042.pptx")) {
  729. ppt.removeSlide(0);
  730. ppt.createSlide();
  731. assertEquals(2, ppt.getSlides().size());
  732. }
  733. }
  734. @Test
  735. void test61515() throws IOException {
  736. try (XMLSlideShow ppt = openSampleDocument("61515.pptx")) {
  737. ppt.removeSlide(0);
  738. assertEquals(1, ppt.createSlide().getRelations().size());
  739. try (XMLSlideShow saved = writeOutAndReadBack(ppt)) {
  740. assertEquals(1, saved.getSlides().size());
  741. XSLFSlide slide = saved.getSlides().get(0);
  742. assertEquals(1, slide.getRelations().size());
  743. }
  744. }
  745. }
  746. @Test
  747. void testAptia() throws IOException {
  748. try (XMLSlideShow ppt = openSampleDocument("aptia.pptx");
  749. XMLSlideShow saved = writeOutAndReadBack(ppt)) {
  750. assertEquals(ppt.getSlides().size(), saved.getSlides().size());
  751. }
  752. }
  753. @Disabled
  754. @Test
  755. void testDivinoRevelado() throws IOException {
  756. try (XMLSlideShow ppt = openSampleDocument("Divino_Revelado.pptx");
  757. XMLSlideShow saved = writeOutAndReadBack(ppt)) {
  758. assertEquals(ppt.getSlides().size(), saved.getSlides().size());
  759. }
  760. }
  761. @Test
  762. void bug62051() throws IOException {
  763. final Function<List<XSLFShape>, int[]> ids = (shapes) ->
  764. shapes.stream().mapToInt(Shape::getShapeId).toArray();
  765. try (final XMLSlideShow ppt = new XMLSlideShow()) {
  766. final XSLFSlide slide = ppt.createSlide();
  767. final List<XSLFShape> shapes = new ArrayList<>();
  768. shapes.add(slide.createAutoShape());
  769. final XSLFGroupShape g1 = slide.createGroup();
  770. shapes.add(g1);
  771. final XSLFGroupShape g2 = g1.createGroup();
  772. shapes.add(g2);
  773. shapes.add(g2.createAutoShape());
  774. shapes.add(slide.createAutoShape());
  775. shapes.add(g2.createAutoShape());
  776. shapes.add(g1.createAutoShape());
  777. assertArrayEquals(new int[]{2, 3, 4, 5, 6, 7, 8}, ids.apply(shapes));
  778. g1.removeShape(g2);
  779. shapes.remove(5);
  780. shapes.remove(3);
  781. shapes.remove(2);
  782. shapes.add(g1.createAutoShape());
  783. assertArrayEquals(new int[]{2, 3, 6, 8, 4}, ids.apply(shapes));
  784. }
  785. }
  786. @Test
  787. void bug63200() throws Exception {
  788. try (XMLSlideShow ss1 = openSampleDocument("63200.pptx")) {
  789. assertEquals(1, ss1.getSlides().size());
  790. XSLFSlide slide = ss1.getSlides().get(0);
  791. assertEquals(1, slide.getShapes().size());
  792. XSLFGroupShape group = (XSLFGroupShape) slide.getShapes().get(0);
  793. assertEquals(2, group.getShapes().size());
  794. XSLFAutoShape oval = (XSLFAutoShape) group.getShapes().get(0);
  795. XSLFAutoShape arrow = (XSLFAutoShape) group.getShapes().get(1);
  796. assertNull(oval.getFillColor());
  797. assertNull(arrow.getFillColor());
  798. }
  799. }
  800. @Test
  801. void alternateContent() throws Exception {
  802. try (XMLSlideShow ppt = openSampleDocument("alterman_security.pptx")) {
  803. XSLFSlideMaster slide = ppt.getSlideMasters().get(0);
  804. XSLFObjectShape os = (XSLFObjectShape) slide.getShapes().get(0);
  805. // ctOleObject is nested in AlternateContent in this file
  806. // if there are casting errors, we would fail early and wouldn't reach this point anyway
  807. assertNotNull(os.getCTOleObject());
  808. // accessing the picture data of the AlternateContent fallback part
  809. XSLFPictureData picData = os.getPictureData();
  810. assertNotNull(picData);
  811. }
  812. try (XMLSlideShow ppt = openSampleDocument("2411-Performance_Up.pptx")) {
  813. XSLFSlide slide = ppt.getSlides().get(4);
  814. XSLFPictureShape ps = (XSLFPictureShape) slide.getShapes().get(0);
  815. assertEquals("image4.png", ps.getPictureData().getFileName());
  816. assertEquals("Picture 5", ps.getShapeName());
  817. }
  818. }
  819. @Test
  820. void bug57796() throws IOException {
  821. assumeFalse(xslfOnly);
  822. try (SlideShow<?, ?> ppt = SlideShowFactory.create(slTests.getFile("WithLinks.ppt"))) {
  823. Slide<?, ?> slide = ppt.getSlides().get(0);
  824. TextShape<?, ?> shape = (TextShape<?, ?>) slide.getShapes().get(1);
  825. TextRun r = shape.getTextParagraphs().get(1).getTextRuns().get(0);
  826. Hyperlink<?, ?> hlRun = r.getHyperlink();
  827. assertNotNull(hlRun);
  828. assertEquals("http://jakarta.apache.org/poi/", hlRun.getAddress());
  829. assertEquals("http://jakarta.apache.org/poi/", hlRun.getLabel());
  830. assertEquals(HyperlinkType.URL, hlRun.getType());
  831. final List<Object> strings = new ArrayList<>();
  832. DummyGraphics2d dgfx = new DummyGraphics2d(NullPrintStream.INSTANCE) {
  833. @Override
  834. public void drawString(AttributedCharacterIterator iterator, float x, float y) {
  835. // For the test file, common sl draws textruns one by one and not mixed
  836. // so we evaluate the whole iterator
  837. Map<Attribute, Object> attributes = null;
  838. StringBuilder sb = new StringBuilder();
  839. for (char c = iterator.first();
  840. c != CharacterIterator.DONE;
  841. c = iterator.next()) {
  842. sb.append(c);
  843. attributes = iterator.getAttributes();
  844. }
  845. if ("Jakarta HSSF".equals(sb.toString())) {
  846. // this is a test for a manually modified ppt, for real hyperlink label
  847. // one would need to access the screen tip record
  848. Attribute[] obj = {HYPERLINK_HREF, HYPERLINK_LABEL};
  849. assertNotNull(attributes);
  850. Stream.of(obj).map(attributes::get).forEach(strings::add);
  851. }
  852. }
  853. };
  854. ppt.getSlides().get(1).draw(dgfx);
  855. assertEquals(2, strings.size());
  856. assertEquals("http://jakarta.apache.org/poi/hssf/", strings.get(0));
  857. assertEquals("Open Jakarta POI HSSF module test ", strings.get(1));
  858. }
  859. }
  860. @Test
  861. void bug59056() throws IOException {
  862. assumeFalse(xslfOnly);
  863. final double[][] clips = {
  864. { 50.999999999999986, 51.0, 298.0, 98.0 },
  865. { 51.00000000000003, 51.0, 298.0, 98.0 },
  866. { 51.0, 51.0, 298.0, 98.0 },
  867. { 250.02000796164992, 93.10370370370373, 78.61839367617523, 55.89629629629627 },
  868. { 79.58198774450841, 53.20887318960063, 109.13118501448272, 9.40935058567127 },
  869. };
  870. DummyGraphics2d dgfx = new DummyGraphics2d(NullPrintStream.INSTANCE) {
  871. int idx = 0;
  872. @Override
  873. public void clip(java.awt.Shape s) {
  874. assertTrue(s instanceof Rectangle2D);
  875. Rectangle2D r = (Rectangle2D)s;
  876. double[] clip = clips[idx++];
  877. assertEquals(clip[0], r.getX(), 0.5);
  878. assertEquals(clip[1], r.getY(), 0.5);
  879. assertEquals(clip[2], r.getWidth(), 0.5);
  880. assertEquals(clip[3], r.getHeight(), 0.5);
  881. }
  882. };
  883. Rectangle2D box = new Rectangle2D.Double(51, 51, 298, 98);
  884. DrawFactory df = DrawFactory.getInstance(dgfx);
  885. try (SlideShow<?,?> ppt = SlideShowFactory.create(slTests.getFile("54541_cropped_bitmap.ppt"))) {
  886. ppt.getSlides().get(0).getShapes().forEach(shape -> df.drawShape(dgfx, shape, box));
  887. }
  888. }
  889. @Test
  890. public void bug65228() throws IOException {
  891. try (XMLSlideShow ppt = openSampleDocument("bug65228.pptx")) {
  892. TextRun.TextCap act = ppt.getSlides().stream()
  893. .flatMap(s -> s.getShapes().stream())
  894. .filter(s -> "März 2021\u2026".equals(s.getShapeName()))
  895. .map(XSLFTextShape.class::cast)
  896. .flatMap(s -> s.getTextParagraphs().stream())
  897. .flatMap(s -> s.getTextRuns().stream())
  898. .map(XSLFTextRun::getTextCap)
  899. .findFirst().orElse(null);
  900. assertEquals(TextRun.TextCap.ALL, act);
  901. }
  902. }
  903. @Test
  904. public void bug65523() throws IOException {
  905. try (XMLSlideShow sourcePresentation = openSampleDocument("bug65523.pptx")) {
  906. assertEquals(2, sourcePresentation.getPictureData().size());
  907. XMLSlideShow targetPresentation = new XMLSlideShow();
  908. XSLFSlide targetPresentationSlide = targetPresentation.createSlide();
  909. XSLFSlide sourceSlide = sourcePresentation.getSlides().get(0);
  910. targetPresentationSlide.getSlideMaster().importContent(sourceSlide.getSlideMaster());
  911. targetPresentationSlide.getSlideLayout().importContent(sourceSlide.getSlideLayout());
  912. targetPresentationSlide.importContent(sourceSlide);
  913. XSLFSlide targetSlide = targetPresentation.getSlides().get(0);
  914. assertNotNull(targetSlide);
  915. assertEquals(2, targetPresentation.getPictureData().size());
  916. targetPresentation.write(NullOutputStream.INSTANCE);
  917. }
  918. }
  919. @Test
  920. public void bug65551() throws IOException {
  921. try (XMLSlideShow ppt = openSampleDocument("bug65551.pptx")) {
  922. XSLFTextShape shape = (XSLFTextShape)ppt.getSlideMasters().get(0).getShapes().get(1);
  923. XSLFTextParagraph tp = shape.getTextParagraphs().get(0);
  924. assertEquals(TextParagraph.TextAlign.RIGHT, tp.getTextAlign());
  925. XSLFTextRun tr = tp.getTextRuns().get(0);
  926. PaintStyle fc = tr.getFontColor();
  927. assertTrue(fc instanceof SolidPaint);
  928. SolidPaint sp = (SolidPaint)fc;
  929. assertEquals(Color.RED, sp.getSolidColor().getColor());
  930. }
  931. }
  932. @Test
  933. void bug65634() throws IOException {
  934. File file = XSSFTestDataSamples.getSampleFile("workbook.xml");
  935. try (FileInputStream fis = new FileInputStream(file)) {
  936. IOException ex = assertThrows(IOException.class, () -> SlideShowFactory.create(fis));
  937. assertEquals("Can't open slideshow - unsupported file type: XML", ex.getMessage());
  938. }
  939. IOException ie = assertThrows(IOException.class, () -> SlideShowFactory.create(file));
  940. assertEquals("Can't open slideshow - unsupported file type: XML", ie.getMessage());
  941. try (FileInputStream fis = new FileInputStream(file)) {
  942. IOException ex = assertThrows(IOException.class, () -> ExtractorFactory.createExtractor(fis));
  943. assertEquals("Can't create extractor - unsupported file type: XML", ex.getMessage());
  944. }
  945. ie = assertThrows(IOException.class, () -> ExtractorFactory.createExtractor(file));
  946. assertEquals("Can't create extractor - unsupported file type: XML", ie.getMessage());
  947. }
  948. @Test
  949. void bug65673() throws IOException {
  950. try (XMLSlideShow slideShowModel = openSampleDocument("bug65673.pptx")) {
  951. final XSLFSlide modelSlide = slideShowModel.getSlides().get(0);
  952. try (XMLSlideShow newSlideShow = new XMLSlideShow()) {
  953. XSLFSlide slide = newSlideShow.createSlide().importContent(modelSlide);
  954. assertNotNull(slide);
  955. }
  956. }
  957. }
  958. @Test
  959. void tika2605() throws IOException {
  960. try (XMLSlideShow slideShowModel = openSampleDocument("tika-2605.pptx")) {
  961. for (XSLFSlide slide : slideShowModel.getSlides()) {
  962. assertNotNull(slide);
  963. for (XSLFShape shape : slide.getShapes()) {
  964. assertNotNull(shape);
  965. }
  966. }
  967. }
  968. }
  969. @Test
  970. void loadPptxWithArtisticEffect() throws IOException {
  971. try (XMLSlideShow slideShowModel = openSampleDocument("ArtisticEffectSample.pptx")) {
  972. for (XSLFSlide slide : slideShowModel.getSlides()) {
  973. assertNotNull(slide);
  974. for (XSLFShape shape : slide.getShapes()) {
  975. assertNotNull(shape);
  976. }
  977. }
  978. }
  979. }
  980. @Test
  981. void identicalGradientStopsBug() throws IOException {
  982. final ArrayList<LinearGradientPaint> linearGradients = new ArrayList<>();
  983. final ArrayList<RadialGradientPaint> radialGradients = new ArrayList<>();
  984. final DummyGraphics2d dgfx = new DummyGraphics2d(NullPrintStream.INSTANCE)
  985. {
  986. public void setPaint(final Paint paint) {
  987. if (paint instanceof LinearGradientPaint) {
  988. linearGradients.add((LinearGradientPaint) paint);
  989. }
  990. if (paint instanceof RadialGradientPaint) {
  991. radialGradients.add((RadialGradientPaint) paint);
  992. }
  993. }
  994. };
  995. final List<LinearGradientPaint> expectedLinearGradients = Arrays.asList(
  996. new LinearGradientPaint(new Point2D.Double(30.731732283464567, 138.7317322834646),
  997. new Point2D.Double(122.91549846753813, 46.54796609939099),
  998. new float[] { 0.0f, 0.99999994f, 1.0f },
  999. new Color[] { new Color(81, 124, 252, 255),
  1000. new Color(81, 124, 252, 255),
  1001. new Color(17,21,27, 204) }),
  1002. new LinearGradientPaint(new Point2D.Double(174.7317322834646, 138.73173228346457),
  1003. new Point2D.Double(266.9154984675381, 46.547966099391004),
  1004. new float[] { 0.0f, 0.00000005f, 1.0f },
  1005. new Color[] { new Color(17,21,27, 204),
  1006. new Color(81, 124, 252, 255),
  1007. new Color(81, 124, 252, 255) }),
  1008. new LinearGradientPaint(new Point2D.Double(318.73173228346457, 138.73173228346462),
  1009. new Point2D.Double(410.9154984675381, 46.547966099391004),
  1010. new float[] { 0.0f, 0.5f, 0.50000006f, 1.0f },
  1011. new Color[] { new Color(17,21,27, 204),
  1012. new Color(17,21,27, 204),
  1013. new Color(81, 124, 252, 255),
  1014. new Color(81, 124, 252, 255) })
  1015. );
  1016. final List<RadialGradientPaint> expectedRadialGradients = Arrays.asList(
  1017. new RadialGradientPaint(new Point2D.Double(30.731732283464567, 138.7317322834646),
  1018. 108.0f, new Point2D.Double(122.91549846753813, 46.54796609939099),
  1019. new float[] { 0.0f, 0.5f, 0.50000006f, 1.0f },
  1020. new Color[] { new Color(17,21,27, 204),
  1021. new Color(17,21,27, 204),
  1022. new Color(81, 124, 252, 255),
  1023. new Color(81, 124, 252, 255) },
  1024. MultipleGradientPaint.CycleMethod.NO_CYCLE),
  1025. new RadialGradientPaint(new Point2D.Double(228.73173228346457, 226.9755905511811),
  1026. 108.0f, new Point2D.Double(282.73173228346457, 280.9755905511811),
  1027. new float[] { 0.0f, 0.00000005f, 1.0f },
  1028. new Color[] { new Color(17,21,27, 204),
  1029. new Color(81, 124, 252, 255),
  1030. new Color(81, 124, 252, 255) },
  1031. MultipleGradientPaint.CycleMethod.NO_CYCLE),
  1032. new RadialGradientPaint(new Point2D.Double(84.73173228346457, 226.9755905511811),
  1033. 108.0f, new Point2D.Double(138.73173228346457, 280.9755905511811),
  1034. new float[] { 0.0f, 0.99999994f, 1.0f },
  1035. new Color[] { new Color(81, 124, 252, 255),
  1036. new Color(81, 124, 252, 255),
  1037. new Color(17,21,27, 204) },
  1038. MultipleGradientPaint.CycleMethod.NO_CYCLE)
  1039. );
  1040. try (XMLSlideShow slideShowModel = openSampleDocument("minimal-gradient-fill-issue.pptx")) {
  1041. // Render the first (and only) slide.
  1042. slideShowModel.getSlides().get(0).draw(dgfx);
  1043. // Test that the linear gradients have the expected data (stops modified)
  1044. assertEquals(3, linearGradients.size());
  1045. for (int i = 0 ; i < expectedLinearGradients.size() ; i++) {
  1046. final LinearGradientPaint expected = expectedLinearGradients.get(i);
  1047. final LinearGradientPaint actual = linearGradients.get(i);
  1048. assertEquals(expected.getStartPoint(), expected.getStartPoint());
  1049. assertEquals(expected.getEndPoint(), expected.getEndPoint());
  1050. assertArrayEquals(expected.getFractions(), actual.getFractions());
  1051. assertArrayEquals(expected.getColors(), actual.getColors());
  1052. }
  1053. // Test that the radial gradients have the expected data (stops modified)
  1054. assertEquals(3, radialGradients.size());
  1055. for (int i = 0 ; i < expectedRadialGradients.size() ; i++) {
  1056. final RadialGradientPaint expected = expectedRadialGradients.get(i);
  1057. final RadialGradientPaint actual = radialGradients.get(i);
  1058. assertEquals(expected.getCenterPoint(), expected.getCenterPoint());
  1059. assertEquals(expected.getFocusPoint(), expected.getFocusPoint());
  1060. assertArrayEquals(expected.getFractions(), actual.getFractions());
  1061. assertArrayEquals(expected.getColors(), actual.getColors());
  1062. }
  1063. }
  1064. }
  1065. }