Bug 65314 - draw method hangs on Hemf dashed stroke graphics
Summary: draw method hangs on Hemf dashed stroke graphics
Status: NEW
Alias: None
Product: POI
Classification: Unclassified
Component: XSLF (show other bugs)
Version: 4.1.2-FINAL
Hardware: PC All
: P2 blocker (vote)
Target Milestone: ---
Assignee: POI Developers List
Depends on:
Reported: 2021-05-18 19:32 UTC by Eric Schoen
Modified: 2021-05-19 14:16 UTC (History)
1 user (show)


Note You need to log in before you can comment on or make changes to this bug.
Description Eric Schoen 2021-05-18 19:32:56 UTC
This is similar to issue 64806, but involves:
1. An WEMF embedded in an Excel worksheet embedded in a PPTX file.
2. Either the Pisces or Marlin 2D renderer.
3. A dashed line that never completes rendering.  

I don't have permission from the file owner to attach the original document.  I tried to isolate the problem by pasting the embedded metafile into its own document, but doing so causes the renderer to work correctly.  In fact, any innocuous change I make, such as opening the PPTX, double clicking the embedded spreadsheet, using the Update command to update the spreadsheet in the PPTX but making no other changes to it and then saving the updated PPTX, fixes the problem.  

Here's a stack trace, should it be helpful for narrowing down an investigation.  Each time I query the process with jstack, the top frame on the thread's stack is the sun.java2d.pipe.ShapeSpanIterator.lineTo method.

  java.lang.Thread.State: RUNNABLE
	at sun.java2d.pipe.ShapeSpanIterator.lineTo(Native Method)
	at sun.java2d.marlin.TransformingPathConsumer2D$DeltaScaleFilter.lineTo(TransformingPathConsumer2D.java:355)
	at sun.java2d.marlin.Stroker$PolyStack.popAll(Stroker.java:1349)
	at sun.java2d.marlin.Stroker.emitReverse(Stroker.java:484)
	at sun.java2d.marlin.Stroker.finish(Stroker.java:511)
	at sun.java2d.marlin.Stroker.moveTo(Stroker.java:416)
	at sun.java2d.marlin.Dasher.goTo(Dasher.java:235)
	at sun.java2d.marlin.Dasher.lineTo(Dasher.java:301)
	at sun.java2d.marlin.TransformingPathConsumer2D$DeltaScaleFilter.lineTo(TransformingPathConsumer2D.java:355)
	at sun.java2d.marlin.MarlinRenderingEngine.pathToLoop(MarlinRenderingEngine.java:651)
	at sun.java2d.marlin.MarlinRenderingEngine.pathTo(MarlinRenderingEngine.java:636)
	at sun.java2d.marlin.MarlinRenderingEngine.strokeTo(MarlinRenderingEngine.java:420)
	at sun.java2d.marlin.MarlinRenderingEngine.strokeTo(MarlinRenderingEngine.java:189)
	at sun.java2d.marlin.MarlinRenderingEngine.strokeTo(MarlinRenderingEngine.java:163)
	at sun.java2d.pipe.LoopPipe.getStrokeSpans(LoopPipe.java:278)
	at sun.java2d.pipe.LoopPipe.draw(LoopPipe.java:201)
	at sun.java2d.pipe.PixelToParallelogramConverter.draw(PixelToParallelogramConverter.java:148)
	at sun.java2d.pipe.ValidatePipe.draw(ValidatePipe.java:154)
	at sun.java2d.SunGraphics2D.draw(SunGraphics2D.java:2497)
	at org.apache.poi.hwmf.draw.HwmfGraphics.draw(HwmfGraphics.java:170)
	at org.apache.poi.hemf.record.emfplus.HemfPlusDraw$EmfPlusDrawPath.draw(HemfPlusDraw.java:220)
	at org.apache.poi.hemf.draw.HemfGraphics.draw(HemfGraphics.java:123)
	at org.apache.poi.hemf.record.emf.HemfComment$EmfCommentDataPlus$$Lambda$443/1995987237.accept(Unknown Source)
	at java.util.ArrayList.forEach(ArrayList.java:1259)
	at org.apache.poi.hemf.record.emf.HemfComment$EmfCommentDataPlus.draw(HemfComment.java:307)
	at org.apache.poi.hemf.record.emf.HemfComment$EmfComment.draw(HemfComment.java:128)
	at org.apache.poi.hemf.draw.HemfGraphics.draw(HemfGraphics.java:116)
	at org.apache.poi.hemf.usermodel.HemfPicture.draw(HemfPicture.java:179)
	at org.apache.poi.hemf.draw.HemfImageRenderer.drawImage(HemfImageRenderer.java:117)
	at org.apache.poi.sl.draw.DrawPictureShape.drawContent(DrawPictureShape.java:64)
	at org.apache.poi.sl.draw.DrawSimpleShape.draw(DrawSimpleShape.java:107)
	at org.apache.poi.sl.draw.DrawGraphicalFrame.draw(DrawGraphicalFrame.java:38)
	at org.apache.poi.sl.draw.DrawSheet.draw(DrawSheet.java:71)
	at org.apache.poi.sl.draw.DrawSlide.draw(DrawSlide.java:41)
	at org.apache.poi.xslf.usermodel.XSLFSlide.draw(XSLFSlide.java:373)

This is happening on Windows x64 with OpenJDK 8 build 282 and on Debian Linux x64 with OpenJDK 8 build 292. It is also reproducible on OpenJDK 16 (latest) on MacOS, also with the Marlin rendering engine.
Comment 1 Andreas Beeker 2021-05-18 22:21:00 UTC
If you want and have permission to, you can send me the pptx privately. This is not the first case, where I fix rendering issues without open sourcing the sample files ...
Comment 2 Eric Schoen 2021-05-19 14:16:49 UTC
I'll work on getting permission to provide the file on a confidential basis.

I found what seems to be a workaround.  Enabling anti-aliasing when rendering the slide image causes the code to run to completion, rather than hang. Following example #3 from this page made the code work:


For what it's worth, I did try extracting two EMF images embedded in the pptx file, and both rendered fine in isolation with and without anti-aliasing, using the example code from the above link.  So unless the overall dimensions of the output (buffered) image impact the stroke drawing loop, I'm not sure how to explain why the EMFs render OK alone.