RFR: 8279614: The left line of the TitledBorder is not painted on 150 scale factor [v7]

Alisen Chung achung at openjdk.java.net
Thu Mar 24 21:20:40 UTC 2022


On Wed, 23 Mar 2022 18:24:05 GMT, Alisen Chung <achung at openjdk.org> wrote:

>> Changed the drawing area to be increased by 0.5 on the left side to prevent clipping
>
> Alisen Chung has updated the pull request incrementally with one additional commit since the last revision:
> 
>   scale stroke width at higher scalings

TitledBorder is using EtchedBorder and cutting out a portion to insert some text, so the root of the problem is actually in EtchedBorder and not TitledBorder. Here’s how the TitledBorder should look:
<img width="641" alt="Screen Shot 2022-03-24 at 2 12 00 PM" src="https://user-images.githubusercontent.com/90066231/160011029-54c6a06c-817e-4f78-88e4-ab9cbf22f53e.png">

The black line is the “actual border”, and the white lines are shadows to create a pop-out effect. The original bug was: at n.5x scalings (n = 1,2,3,...), the two lines would overlap, so the white line would overdraw the black line. I think the root cause is that when the coordinate system is scaled up (before painting), Graphics2D object figures out where the lines should be painted based on the old coordinate system, then does some rounding to paint on the new coordinate system. If the two lines happen to round to the same integer, then we have the overdrawing problem.

This thought is a bit ad-hoc, but I think this reasoning can also explain the confusion we had about the unintuitive borderX and borderY values before: the reason the 150% scaling has a smaller borderX is because in both 100% and 150% scalings the location of the border is the same, but it takes less integer steps to reach that location in the 150% scaled image.

<img width="668" alt="Screen Shot 2022-03-24 at 2 12 43 PM" src="https://user-images.githubusercontent.com/90066231/160011116-310eb948-6625-48d8-bd57-b6ff5c34bfa5.png">

The “jumping” of the lines was referring to the increased distance between the integer coordinates at higher scalings not matching up with the size of the stroke of the lines. The result was that when the lines are adjacent in the coordinate space (and not overdrawn), they wouldn’t actually be side-to-side when viewed. In other words, there was no exact integer coordinate the shadow could be such that it was adjacent to but not overdrawing the border.

<img width="415" alt="Screen Shot 2022-03-24 at 2 13 36 PM" src="https://user-images.githubusercontent.com/90066231/160011309-618d7fc8-994e-4699-9952-357547c62be6.png">

The solution Luke came up with was to undo the scaling first to prevent any of the coordinate rounding, then draw the border at 100% scaling, and reapply the scaling after finishing the drawing. Something like this:
<img width="657" alt="Screen Shot 2022-03-24 at 2 16 13 PM" src="https://user-images.githubusercontent.com/90066231/160011618-c526698e-78b3-4f52-93ab-a3b986f87056.png">

The current issue we just ran into was that at higher scalings using this approach, the lines would look too thin, so the stroke thickness needed to be scaled up as well, which would cause some changes in where to place the lines. I’m currently looking for where to place the lines given a stroke length (grabbed from the floor of the scale factor), but if that isn’t robust enough another approach suggested is to use area to draw.

-------------

PR: https://git.openjdk.java.net/jdk/pull/7449



More information about the client-libs-dev mailing list