Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2025, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2026, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
Expand Down Expand Up @@ -1436,14 +1436,16 @@ boolean hasGlyph(int gid) {
}
}

ColorGlyphStrike[] sbixStrikes = null;
private volatile ColorGlyphStrike[] sbixStrikes;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have time to look at this for jfx27, so I recommend leaving it for after the fork, but I see at one other related threading issue. Both should be fixed at the same time (else there is little point in changing anything). The buildSbixStrikeTables() could be called twice, since it isn't inside the inner if (sbixStrikes == null). It won't be called concurrently, but will still do the initialization more than once which is, at best, unnecessary.

Minor: I prefer to leave the = null that you removed, since code is checking / relying on the initial value (yes I know it doesn't actually matter, but I find it more self-documenting with the explicit initialization).

@andy-goryachev-oracle andy-goryachev-oracle Jul 8, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, the whole thing is funky. I've restructured the code to make sure it is a proper double check locking and the buildSbixStrikeTables() is called only once.

For the null field, it's not necessary per JLS 4.12.5
https://docs.oracle.com/javase/specs/jls/se26/html/jls-4.html#jls-4.12.5 :

For all reference types (§4.3), the default value is null.

Besides, it annoys me when the debugger steps at each pointless assignments each time.


private boolean isSbixGlyph(int glyphID) {
if (sbixStrikes == null) {
synchronized (this) {
buildSbixStrikeTables();
if (sbixStrikes == null) {
sbixStrikes = new ColorGlyphStrike[0];
sbixStrikes = buildSbixStrikeTables();
if (sbixStrikes == null) {
sbixStrikes = new ColorGlyphStrike[0];
}
}
}
}
Expand All @@ -1455,31 +1457,30 @@ private boolean isSbixGlyph(int glyphID) {
return false;
}

private void buildSbixStrikeTables() {

private ColorGlyphStrike[] buildSbixStrikeTables() {
Buffer sbixTable = readTable(sbixTag);

if (sbixTable == null) {
return;
return null;
}

int sz = sbixTable.capacity();
sbixTable.skip(4); // past version and flags
int numStrikes = sbixTable.getInt() & UINT_MASK;
if (numStrikes <= 0 || numStrikes >= sz) {
return;
return null;
}
int[] strikeOffsets = new int[numStrikes];
for (int i=0; i<numStrikes; i++) {
strikeOffsets[i] = sbixTable.getInt() & UINT_MASK;
if (strikeOffsets[i] >= sz) {
return;
return null;
}
}
int numGlyphs = getNumGlyphs();
ColorGlyphStrike[] strikes = new ColorGlyphStrike[numStrikes];
for (int i=0; i<numStrikes; i++) {
if (strikeOffsets[i] + 4 + (4*(numGlyphs+1)) > sz) {
return;
return null;
}
sbixTable.position(strikeOffsets[i]);

Expand All @@ -1491,7 +1492,6 @@ private void buildSbixStrikeTables() {
}
strikes[i] = new ColorGlyphStrike(ppem, ppi, glyphDataOffsets);
}
sbixStrikes = strikes;
return strikes;
}

}