Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 4707774
Votes 4
Synopsis Graphics.drawString( String, int, int ) not precise for large ints
Category java:classes_2d
Reported Against 1.4.1 , 1.3.1_03 , hopper-beta
Release Fixed 1.4.1_03
State 10-Fix Delivered, Needs Verification, bug
Priority: 4-Low
Related Bugs
Submit Date 25-JUN-2002
Description




FULL PRODUCT VERSION :
java version "1.3.1_03"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.1_03-b03)
Java HotSpot(TM) Client VM (build 1.3.1_03-b03, mixed mode)

FULL OPERATING SYSTEM VERSION :
4NT  3.01A   Windows NT 5.00

A DESCRIPTION OF THE PROBLEM :
Trying to line up labels drawn with Graphics.drawString(
String, int x, int y) with lines drawn with
Graphics.drawLine(int x, int y, int, int) doesn't work for
large x & y values (i.e. greater than 2^24). Looking at
sun.java2d.SunGraphics2D.drawString shows that the int
parameters are being cast to float and losing precision.

Graphics.drawString( String, int, int) should not cast
arguments to float. If range is an issue, they should
either be cast to double or long.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Look at source for sun.java2d.SunGraphics2D.drawString(
String, int, int)
2. Note that arguments are cast to float
3.

REPRODUCIBILITY :
This bug can be reproduced always.
(Review ID: 153922) 
======================================================================


 xxxxx@xxxxx  2002-11-08

Here's a sample that shows the problem. The numbers should centered under
the ticks, but as one moves the scroll handle to the right (past 1/5 or so)
the numbers are no longer precisely centered under the ticks. With the
scroll handle at the far right, labels are far from ticks and some labels
are superimposed because they are "clumping" around values that can be
exactly represented by float.

This problem occurs because drawString casts int x and y parameters to
float, and float numbers only have 24 manitssa bits compared to 32 bits for
ints, so precision is lost with large numbers, making it impossible to
correctly label lines drawn with drawLine.

Note that the problem is still noticeable if one comments out the line to
center the label under a tick.

I made 2 changes to make the problem more apparent:

- Changed labels to be left justified under tick, rather than centered.
It's easier to see now when a tick doesn't line up with the start of a
label. (Left the code to center it as a comment.)

- Set the scrollbar's unit increment to be the same as the tick increment.
Now click-and-hold on the scroll bar arrow shows that the ticks are evenly
spaced, but the labels aren't (once you get past 1/8 or so of the scroll
range).

Here's is the updated file:

(See attached file: DrawStringTest.java)
Work Around
N/A
Evaluation
Problem becomes more appearent from Integer value 67108900 (rounding value of 2^26 to immediate next multiple of 100). I tested this by setting MAX_WIDTH =67109000 (2 ticks more that 2^26 tick).

The bug is reproducible on Solaris as well as Windows platform. However, textpipe.drawString() invocation in drawString(String, int, int) from SunGraphics2D.java invokes 2 different implementations. For Solaris, 'textpipe' is of type 'sun.awt.font.X11TextRenderer' whereas for windows it is of type 'sun.java2d.pipe.SolidTextRenderer'.

Standard API of J2SDK 1.4.x, provides drawString() method of java.awt.Graphics2D  with arguments of type float or int. However, the actual implementation of draw String() method accepts only float type arguments (implemented in GlyphListPipe.java).

I believe, this bug can be resolved by using 'double' instead of 'float' as  parameters to drawString() implementation in GlyphListPipe. And of course, changingmethods wherever these values are passed.

However, use of double instead of float could result into 'PERFORMANCE' degradation as processing double values requires more time than float.

 xxxxx@xxxxx  2002-11-12


I did quick build of 1.4.1 workspace by looking at high level and replacing float with double. This did resolve the problem at some extent. Like, I see that strings are aligned properly with ticks upto 2139881800 (slightly less than 2^31 i.e. total no. of ticks).

I guess this will solve this issue. But needs to see the tradeoff between performance and severity of the issue. 

Other suggestion from sybase is use of 'long' instead of 'double' to solve this issue. However as double or long requires 64 bits, there could be performance degradation as compared to current implementation which uses float/int requiring 32-bit data manipulation.

 xxxxx@xxxxx  2002-11-13
Comments
  
  Include a link with my name & email   

Submitted On 14-NOV-2002
gjbh
If the performance hit is significant, then I would suggest 
adding overloaded methods that use double, instead of 
replacing float with double, and have drawString( Sting, int, 
int) call the float version when both int parameters are less 
than 2^24. That would keep the performance for small values 
and give the correct results for large values.



PLEASE NOTE: JDK6 is formerly known as Project Mustang