On Wed, 5 Apr 2023 14:31:34 GMT, Nikita Gubarkov <ngubar...@openjdk.org> wrote:

>> It was implemented in JetBrains Runtime a year ago and was ported & 
>> refactored for this PR
>> It includes:
>> - Bitmap glyph loading via Freetype
>> - Manual scaling & transformation of bitmap glyphs with nearest-neighbor or 
>> bilinear-mipmap style algorithms depending on the text antialiasing hint
>> - Storing BGRA glyphs in glyph cache & rendering them as plain images, as 
>> currently used XRender text drawing functions doesn't support colored glyphs
>> - Small fixes in related code like null-checks which could cause NPE & 
>> comment typos
>
> Nikita Gubarkov has updated the pull request incrementally with one 
> additional commit since the last revision:
> 
>   EmojiFont CRLF -> LF

I thought we are on the same page with this, but I will try to explain my idea.

We have two PhysicalFonts for mono end colored emoji. Inside fallback sequence 
we want them to be preferred over one another depending on specific glyph and 
variation selector used. This is necessary to support emoji and VS the *proper* 
way. Cheating and using only colored font, forcing monochrome presentation in 
certain cases is an option, but out of topic. In short: it would require a 
bunch of new hacks, which we are trying to get rid of, while the result looking 
not quite how user would expect.

Current CompositeFont implementation is strictly linear - all component fonts 
are tried in sequence, all must be PhysicalFonts (which is an artificial 
limitation). Anyway, current implementation doesn't permit the desired behavior 
(leaving aside hacks with exclusion ranges, which are ignored in presence of 
VS).

Natural solution to achieve what we want is to encapsulate our two 
PhysicalFonts into single virtual emoji font. However then it wouldn't be a 
PhysicalFont and therefore cannot be used inside CompositeFont. I want to 
emphasise this - the problem is not with emoji font, but with CompositeFont. 
Being able to put arbitrary Font2D into CompositeFont is completely logical and 
legitimate, the restriction is artificial.

CompositeFont is too limited for the job, but it can be fixed - the only thing 
preventing CompositeFont from being able to contain Font2Ds is generally 
non-bijective mapping of glyph codes. CompositeFont goes easy way and encodes 
slot index in high byte, leaving others for original glyph code (essentially 
sequential indices). Of course nesting CompositeFonts would encode slot index 
into already used high byte, breaking the thing. My solution is to encode glyph 
codes in such way, that slot index is always inserted in low bits, shifting the 
original code, thus being able to recursively "wrap" glyph codes (unless we 
overflow, but we currently don't handle such case anyway).

I personally don't see anything bad with it being implemented "just for emoji", 
because changes to CompositeFont have nothing to do with emoji - it's just a 
generalization to cover more usage scenaros. I don't know who else could need 
such complex fallback approaches, but they would at least be possible now. 
There is one thing which I considered while implementing this though - 
sometimes users want to configure font fallback behavior, it would be very nice 
to allow them to construct custom fallback chains (trees, whatever), which 
would require some refactoring to CompositeFont, and this change is a small 
step in that direction too.

Finally, I understand your concerns that such changes are risky, but the tests 
are green and changes are battle-tested in JBR, for example, Linux users of 
JetBrains products are enjoying emoji for around 3 years already 😀 I keep this 
PR in sync and include all fixed bugs and regressions, of course.

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

PR Comment: https://git.openjdk.org/jdk/pull/4798#issuecomment-1751769222

Reply via email to