Closed jandam closed 8 years ago
Hi, I just fixed it and I updated the released jars v0.7.2.1: https://github.com/bourgesl/marlin-renderer/releases/tag/v0.7.2.1
Please give me more details on the artifacts, please !
In Marlin 0.7.1+, I now implemented a new RLE encoding approach for huge shapes that may have bugs although I tested several maps (regression tests).
Could you send me a screenshot or an image diff ?
Laurent
Thank you latest version works and I got following stack trace Java8u65, Marlin 0.7.2.1: java.lang.Throwable at org.marlin.pisces.IntArrayCache.check(IntArrayCache.java:139) at org.marlin.pisces.IntArrayCache.fill(IntArrayCache.java:128) at org.marlin.pisces.Renderer.dispose(Renderer.java:634) at org.marlin.pisces.MarlinRenderingEngine.getAATileGenerator(MarlinRenderingEngine.java:765) at sun.java2d.pipe.AAShapePipe.renderPath(AAShapePipe.java:152) at sun.java2d.pipe.AAShapePipe.draw(AAShapePipe.java:64) 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)
WARNING: Invalid array value at 0 [14, 0, 0, 0, .... I draw stroked glyph vector to INT_ARGB buffered image:
FontRenderContext fontRenderContext = new FontRenderContext(new AffineTransform(), true, true);
GlyphVector gv = font.createGlyphVector(fontRenderContext, text);
Shape outline = gv.getOutline();
g2.setColor(color);
g2.setStroke(stroke);
g2.draw(outline);
Could you give me a working test that reproduces the bug ? or at least an image that illustrates that case.
According to the traces, the problem concerns: // fill only used part 634: IntArrayCache.fill(edgeBuckets, buckets_minY, buckets_maxY, 0);
So the buckets_minY is wrong !
Drawing independent glyps don't work to: int numGlyphs = gv.getNumGlyphs(); for (int index = 0; index < numGlyphs; index++) { g2.draw(gv.getGlyphOutline(index)); }
Following code works correctly: g2.setColor(color); g2.setStroke(new BasicStroke(0.0f)); g2.fill(stroke.createStrokedShape(outline));
Sorry to ask again, but I am a bit lost.
I never played with glyph vector ... so please just give me a complete test method() that compiles and reproduces the problem.
I may try to create a test class for that purpose but it will be faster if you write it or at least the squeleton.
Looks like problem is in IntArrayCache method fill uses invalid range for checking. I have following parametes. SO check method should be called with range [fromIndex..toIndex] instead of range [0..array.length] Same issue is in ByteArrayCache, IntArrayCache and FloatArrayCache
array = {int[16385]@7610} fromIndex = 749 toIndex = 870 value = 0
static void fill(int[] array, int fromIndex, int toIndex, int value) {
if(toIndex != 0) {
Arrays.fill(array, fromIndex, toIndex, value);
}
if(doChecks) {
check(array, 0, array.length, value);
}
}
Necessary condition to reproduce this issue is that Min Y of transformed bounds to image coordinate system must be greater that image height Rectangle2D bounds = g2.getTransform().createTransformedShape(outline).getBounds2D(); bounds2D.getMinY() >= image.getHeight()
For performance reasons, I do partial array cleanup! It's tricky but the edge bucket arrays MUST be 0 filled in all range !
If doChecks reports an error then it must be fixed but may be related to previous operations too = very difficult to debug !
I really need reproducing the test.
Could you send me some code and your logs to bourges.laurent at gmail ?
OK. I will try to make small test tomorrow morning. Today I have to go :-(
Hi I have small test for this issue: Problem occurs during rendering FIRST glyph vector that leaves non zero value on first index in Renderer.edgeBuckets. Stroker.drawBezApproxForArc computes value 'cv' as NaN. It is during rendering "quadTo" with JOIN_ROUND. Glyph vector is completely outside buffered image area. When I disable antialiasing or round join everything works.
BufferedImage bi = new BufferedImage(256, 256, BufferedImage.TYPE_INT_RGB); // can be TYPE_INT_ARGB
Graphics2D g2 = bi.createGraphics();
try {
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
Font font = g2.getFont();
FontRenderContext fontRenderContext = new FontRenderContext(new AffineTransform(), true, true);
GlyphVector gv1 = font.createGlyphVector(fontRenderContext, "\u00d6");
g2.setStroke(new BasicStroke(4.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
AffineTransform at1 = AffineTransform.getTranslateInstance( -2091202.554154681, 5548.601436981691);
g2.draw(at1.createTransformedShape(gv1.getOutline()));
GlyphVector gv2 = font.createGlyphVector(fontRenderContext, "Test 2");
AffineTransform at2 = AffineTransform.getTranslateInstance( -218.1810476789251, 85.12774919422463);
g2.draw(at2.createTransformedShape(gv2.getOutline()));
} finally {
g2.dispose();
}
Congratulations !
I reproduce the problem and your diagnostic is exact:
I will look at maths to understand what does it mean but I suspect a float precision issue: it happens when the translation is large >2e6.
I will clamp that value in [-0.5,0.5] to avoid NaN first and also submit that bug to OpenJDK pisces.
Thanks again
Fix pushed in the use_Unsafe branch.
I also added your test code.
Will make a new release soon
Thank you for fast fix of the issue
FYI I will submit a bug to openjdk asap. Could you give me your full name to mention in the test class header ?
Do you need a release ?
Thanks a lot to have reported this long-standing issue.
Laurent
I updated my profile on GitHub. New release will be nice. M
Thanks, I updated the @author tag in TextClipErrorTest.
Here is the release v0.7.3: https://github.com/bourgesl/marlin-renderer/releases/tag/v0.7.3
Marlin 7.2.1 says sun.java2d.renderer.doChecks=false when I set value to true.
-Dsun.java2d.renderer.doChecks=true
I have rendering artifacts that I can't debug. (Marlin 7.1, 7.2x)
For example -Dsun.java2d.renderer.useLogger=true works correctly.