United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6533413 REGRESSION:JEudlid bean crashes with font sizes 180 and greater
JDK-6533413 : REGRESSION:JEudlid bean crashes with font sizes 180 and greater

Submit Date:
Updated Date:
Project Name:
Resolved Date:
Affected Versions:
Fixed Versions:

Related Reports

Sub Tasks

Using the open source JEuclid bean, the VM 1.6.0_01-ea-b03 crashes with font sizes 
180 and greater. Please find attached a few error report files of such crashes as 
well as a test class which can be run with the JEuclid jar file in the classpath 
which will reproduce the error. You can start the test with follow command line:
    java -cp jeuclid-2.9.4.jar;commons-logging-1.1.jar;. JMathTest
We have test it on WinXP, Windows 2000 and Windows 2003. With Java 1.5 it is 
not crashing that it is a regression.



I can reproduce crash with 6.0 and 6.0u1 but for some reason it does not crash with 
jdk 7 (tried b01, b04, b05. b06, b07). 

This is weird because 7.0b01 is not very different from release build of 6.0.

However, problem is not fixed. Result drawing from 7.0 is very different from what 
i am getting using 5.0u7. Subscript indices and brakets are missing (testcase
was modified to use font size 200 instead of 120 after i failed to reproduce crash 
with original testcase).

In JDK7 some glyphs are not drawn because processing of huge "{" char causes internal 
memory allocation error that is in turn causes scaler to be replaced with NULL scaler.
So, as soon as this error happens no glyphs are actually processed.

While trying to generate bitmap for this glyph we are trying to allocate 99Mb chunk
for bitmap and it does not work.

It is still unclear why this happens - probably due to overflow while calculating edges 
to approximate countour some of coordinates are too big. 

On other hand it is not clear why we are trying to generate bitmap for this char in the 
native library. In theory for very large glyphs we are supposed to return outline from native lib and rasterize outline as regular GeneralPath.

This looks like regression after fix for 6408162.

Technically, it is probably not bug in the fix itself. However, as the sideeffect of this
fix rasterizer is requested to generated bitmaps for huge text as part of 
work to generate metrics. I believe that for huge sizes we used to request 
outlines only and draw them as shapes.

In particular, for given testcase we are trying to measure bounds (and generate bitmap) 
for bracket ("{} of size 20000pt. Something goes wrong in the rasterizer. 
Probably overflow or we are getting out of memory. At this moment it is not clear yet.

Removing segmentedCache from 
  getImageWithAdvance = at.getScaleY() <= 48.0 || segmentedCache;
line eliminates bitmap request and test is working fine with jdk7 builds.
I have not verified this fixes crash on jdk 6.0 but it seems very likely.

So far it seems that while it has sense to enable bitmap pre-generation
for some large sizes (as it was done by fix for 6408162), 
it might have sense to disable it for huge sizes.
(after all t2k scan conversion is rather slow on large shapes)

Reassigning to the author of the fix for 6408162 for further investigation.

We almost always want to cache the advances of glyphs as they
may be requested repeatedly during layout of some text components.
The advance cache is a simple array that may be sparsely populated.
However the image cache also contains advance data and can be segmented, 
so as to use much less space when dealing with CJK fonts with many 
Consequently, for these fonts with many glyphs we can leverage
the glyph cache to act as a segmented advance cache.
Hence segmentedCache always implies getImageWithAdvance.
This means there is no limit to the pixel size that may be used.
But it is wasteful to get an image if we are never going to
render it, so there should be an upper limit pixel size no greater than
the value specified by sun.java2d.pipe.OutlineTextRenderer.THRESHOLD.

The simple fix is to apply such an upper limit ie modify the expression
to be
  getImageWithAdvance = at.getScaleY() <= 48.0 ||
	 (segmentedCache &&
         at.getScaleY() <= OutlineTextRenderer.THRESHOLD);

The obvious downside to this is that fonts greater than
that size and with many glyphs (more than the advance
cache will accept) will need to be scaled each time
their advance is requested. Since OutlineTextRenderer.THRESHOLD
is very large, the most likely affected case is printing, where
the device scale is such that pixel sizes can exceed that
threshold. However we probably don't want the images in that
case anyway since the printer will usually provide the images.
If this is needed, we'd have to implement segmenting of the
advance cache to match segmenting of the image cache.
This isn't difficult so may be we should just do it.

Hardware and Software, Engineered to Work Together