RFR: 8185261: Font fallback sometimes doesn't work in Swing text components [v2]

Phil Race prr at openjdk.java.net
Sun Feb 6 19:57:07 UTC 2022


On Tue, 1 Feb 2022 21:40:53 GMT, Dmitry Batrak <dbatrak at openjdk.org> wrote:

>> The proposed fix makes fonts with and without fallback components distinguishable (in terms of `equals` method), so that
>> font metrics cache (and other similar code) can handle them separately. This is achieved by adding a new boolean field
>> to `Font` class, specifically denoting fonts with fallback components. The latter ones don't need to pretend to be
>> 'created' fonts anymore, to preserve their `Font2D` handle.
>> It's not possible to use the existing `createdFont` field in `equals` implementation, as JCK requires a 'real' created
>> font (the one obtained using `Font.createFont` method) to be equal to the same font after serialization and
>> deserialization.
>
> Dmitry Batrak has updated the pull request incrementally with one additional commit since the last revision:
> 
>   remove 'headful' requirement from test case

> As you say, one could possibly also try to compare font2DHandle-s instead,
 > but that would require forcing the population of that field in equals method,
> which seems to have larger potential for side effects.

Yes, I noted this would present even more problems.

> Of course, there's an alternative method to fix this - make font metrics cache distinguish such fonts explicitly,
> ....  I believe, would just mean waiting for other trouble in future.

I was getting at this with my comment

> I do see that it would be tricky to have some private extra equality testing in the code that finds the right fall back

But it wasn't (isn't) clear to me without tracking this down if some piece of the implementation is making
some assumptions it perhaps shouldn't. But yes, very likely not going to work exactly like that.


Taking a look I think the problem starts with getCompositeFontUIResource()

So another approach is to define a subclass of FontUIResource in which it over-rides hashCode() and equals()
and does the extra comparison needed.

It would only be equal to another  CompositeFontUIResource with the same base font

sun.font.CompositeFontUIResource extends FontUIResource { ...

public void boolean equals(Object o) {
   return (o instanceof  CompositeFontUIResource && super.equals(o);
}

Then in sun.font.FontUtilities we add
      if (compFont == null) {
            compFont = new CompositeFont(physicalFont, dialog2D);
            compMap.put(physicalFont, compFont);
        }
+     fuir = new CompositeFontUIResource(font);
        FontAccess.getFontAccess().setFont2D(fuir, compFont.handle);


The explanation about JCK indicates that JCK could also obtain a font from Swing that has fallbacks,
serialize it and on deserialization currently it would be equal but after this fix it would not.
So I don't see the difference except that there (presumably) happens not to be a JCK test for this scenario ...
However since JCK isn't part of OpenJDK I don't think we can discuss it any further here.

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

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



More information about the client-libs-dev mailing list