Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
ccb864e
8269806: Emoji rendering on Linux
YaaZ Jul 15, 2021
5d99aee
8269806: Fix builds with old Freetype (before 2.5)
YaaZ Mar 24, 2022
9dbed75
8269806: Fix emoji rendering with -Dsun.java2d.xrender=false and AA=OFF
YaaZ Mar 30, 2022
f01750b
8269806: Fix glyph advance rounding with FM=OFF
YaaZ Jun 24, 2022
e8b1ada
8269806: Fix rendering of colored glyphs on big font sizes
YaaZ Jun 25, 2022
37f1376
Revert "8269806: Fix rendering of colored glyphs on big font sizes"
YaaZ Jul 13, 2022
4097e18
8269806: Added emoji support for Windows
YaaZ Jul 13, 2022
30067e8
8269806: Fix emoji, ZWJ, variation selectors and font fallback
YaaZ Jul 14, 2022
f8fc165
Fix GlyphRenderData CRLF
YaaZ Jul 15, 2022
3eb8915
Fix other CRLF
YaaZ Jul 15, 2022
29b68f1
Fix pointer to long conversion
YaaZ Jul 15, 2022
1a2b4d6
Optimize bitmap creation in GlyphRenderData
YaaZ Jul 21, 2022
71a6f34
Merge master
YaaZ Jul 21, 2022
07150fb
Disable colored outlines on Linux to be able to build with old system…
YaaZ Jul 23, 2022
83d5da5
Fix rotated text metrics
YaaZ Aug 1, 2022
c2506a3
Fix italic and bold styles for colored outline glyphs
YaaZ Aug 5, 2022
ed77423
Merge branch 'master' into JDK-8269806
YaaZ Oct 25, 2022
8c5b285
Merge branch 'master' into JDK-8269806
YaaZ Nov 30, 2022
4c07805
Fix pointer to jlong conversion on x86
YaaZ Dec 1, 2022
4d4fadb
Skip tests if required font is absent
YaaZ Jan 25, 2023
578e558
Remove ftcolor.c
YaaZ Jan 31, 2023
728f1b5
Merge branch 'master' into JDK-8269806
YaaZ Jan 31, 2023
778f423
Make tests headful.
YaaZ Jan 31, 2023
b3bbc1b
Add braces to ifs.
YaaZ Jan 31, 2023
342dcde
Replace unicodeToUnits with Character.toChars in CCharToGlyphMapper
YaaZ Feb 1, 2023
57c0b57
Dynamic loading of ftcolor.h symbols on Linux.
YaaZ Feb 1, 2023
47f9bb1
Merge branch 'master' into JDK-8269806
YaaZ Apr 5, 2023
df4f0e8
🥸
YaaZ Apr 3, 2023
8a9c83a
Removed getGlyphVectorOutline - it's unused and broken
YaaZ Apr 3, 2023
d84ac24
Get rid of charsToGlyphs[NS] boilerplate.
YaaZ Apr 3, 2023
c1b8f9b
Moved tests to separate directory.
YaaZ Apr 3, 2023
624af03
EmojiFont CRLF -> LF
YaaZ Apr 5, 2023
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
24 changes: 19 additions & 5 deletions src/java.desktop/macosx/classes/sun/font/CCharToGlyphMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ public synchronized boolean charsToGlyphsNS(int count,

if (code < FontUtilities.MIN_LAYOUT_CHARCODE) {
continue;
} else if (FontUtilities.isComplexCharCode(code)) {
} else if (FontUtilities.isComplexCharCode(code) ||
CharToGlyphMapper.isVariationSelector(code)) {
return true;
} else if (code >= 0x10000) {
i += 1; // Empty glyph slot after surrogate
Expand All @@ -88,6 +89,21 @@ public synchronized boolean charsToGlyphsNS(int count,
return false;
}

public synchronized int charToVariationGlyph(int unicode, int variationSelector) {
if (variationSelector == 0) {
return charToGlyph(unicode);
}
final char[] unicodeArray = new char[4];
final int[] glyphArray = new int[4];

int size = Character.toChars(unicode, unicodeArray, 0);
size += Character.toChars(variationSelector, unicodeArray, size);

nativeCharsToGlyphs(fFont.getNativeFontPtr(), size, unicodeArray, glyphArray);

return glyphArray[0];
}

public synchronized int charToGlyph(char unicode) {
final int glyph = cache.get(unicode);
if (glyph != 0) return glyph;
Expand All @@ -105,10 +121,8 @@ public synchronized int charToGlyph(int unicode) {
if (unicode >= 0x10000) {
int[] glyphs = new int[2];
char[] surrogates = new char[2];
int base = unicode - 0x10000;
surrogates[0] = (char)((base >>> 10) + HI_SURROGATE_START);
surrogates[1] = (char)((base % 0x400) + LO_SURROGATE_START);
charsToGlyphs(2, surrogates, glyphs);
int size = Character.toChars(unicode, surrogates, 0);
charsToGlyphs(size, surrogates, glyphs);
return glyphs[0];
} else {
return charToGlyph((char)unicode);
Expand Down
89 changes: 21 additions & 68 deletions src/java.desktop/macosx/classes/sun/font/CCompositeGlyphMapper.java
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,34 @@ public boolean canDisplay(char ch) {
return glyph != missingGlyph;
}

private int convertToGlyph(int unicode) {
@Override
public int charToVariationGlyph(int unicode, int variationSelector) {
if (variationSelector == 0) {
return charToGlyph(unicode);
} else {
int glyph = convertToGlyph(unicode, variationSelector);
if (glyph == missingGlyph) glyph = charToGlyph(unicode);
return glyph;
}
}

@Override
protected int convertToGlyph(int unicode) {
int glyph = convertToGlyph(unicode, 0);
return glyph;
}

@Override
protected int convertToGlyph(int unicode, int variationSelector) {
for (int slot = 0; slot < font.numSlots; slot++) {
CharToGlyphMapper mapper = getSlotMapper(slot);
int glyphCode = mapper.charToGlyph(unicode);
int glyphCode = mapper.charToVariationGlyph(unicode, variationSelector);
// The CFont Mappers will return a negative code
// for fonts that will fill the glyph from fallbacks
// - cascading font in OSX-speak. But we need to be
// know here that only the codes > 0 are really present.
if (glyphCode > 0) {
glyphCode = compositeGlyphCode(slot, glyphCode);
glyphCode = font.compositeGlyphCode(slot, glyphCode);
return glyphCode;
}
}
Expand All @@ -87,69 +105,4 @@ public int charToGlyph(int unicode) {
public int charToGlyph(char unicode) {
return convertToGlyph(unicode);
}

public boolean charsToGlyphsNS(int count, char[] unicodes, int[] glyphs) {

for (int i=0; i<count; i++) {
int code = unicodes[i]; // char is unsigned.

if (code >= HI_SURROGATE_START &&
code <= HI_SURROGATE_END && i < count - 1) {
char low = unicodes[i + 1];

if (low >= LO_SURROGATE_START &&
low <= LO_SURROGATE_END) {
code = (code - HI_SURROGATE_START) *
0x400 + low - LO_SURROGATE_START + 0x10000;
glyphs[i + 1] = INVISIBLE_GLYPH_ID;
}
}

glyphs[i] = convertToGlyph(code);

if (code < FontUtilities.MIN_LAYOUT_CHARCODE) {
continue;
}
else if (FontUtilities.isComplexCharCode(code)) {
return true;
}
else if (code >= 0x10000) {
i += 1; // Empty glyph slot after surrogate
continue;
}
}

return false;
}

public void charsToGlyphs(int count, char[] unicodes, int[] glyphs) {
for (int i=0; i<count; i++) {
int code = unicodes[i]; // char is unsigned.

if (code >= HI_SURROGATE_START &&
code <= HI_SURROGATE_END && i < count - 1) {
char low = unicodes[i + 1];

if (low >= LO_SURROGATE_START &&
low <= LO_SURROGATE_END) {
code = (code - HI_SURROGATE_START) *
0x400 + low - LO_SURROGATE_START + 0x10000;

glyphs[i] = convertToGlyph(code);
i += 1; // Empty glyph slot after surrogate
glyphs[i] = INVISIBLE_GLYPH_ID;
continue;
}
}

glyphs[i] = convertToGlyph(code);
}
}

public void charsToGlyphs(int count, int[] unicodes, int[] glyphs) {
for (int i=0; i<count; i++) {
glyphs[i] = convertToGlyph(unicodes[i]);
}
}

}
6 changes: 0 additions & 6 deletions src/java.desktop/macosx/classes/sun/font/CFont.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,6 @@ GeneralPath getGlyphOutline(long pScalerContext, int glyphCode,
throw new InternalError("Not implemented");
}

GeneralPath getGlyphVectorOutline(long pScalerContext,
int[] glyphs, int numGlyphs,
float x, float y) {
throw new InternalError("Not implemented");
}

@Override
protected byte[] getTableBytes(int tag) {
return getTableBytesNative(getNativeFontPtr(), tag);
Expand Down
13 changes: 10 additions & 3 deletions src/java.desktop/macosx/classes/sun/font/CStrike.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,12 @@ private static native GeneralPath getNativeGlyphOutline(long nativeStrikePtr,
double x,
double y);

private static native void getNativeGlyphRenderData(long nativeStrikePtr,
int glyphCode,
double x,
double y,
GlyphRenderData result);

// returns the bounding rect for a glyph
private static native void getNativeGlyphImageBounds(long nativeStrikePtr,
int glyphCode,
Expand Down Expand Up @@ -214,9 +220,10 @@ GeneralPath getGlyphOutline(int glyphCode, float x, float y) {
return getNativeGlyphOutline(getNativeStrikePtr(), glyphCode, x, y);
}

// should implement, however not called though any path that is publicly exposed
GeneralPath getGlyphVectorOutline(int[] glyphs, float x, float y) {
throw new Error("not implemented yet");
GlyphRenderData getGlyphRenderData(int glyphCode, float x, float y) {
GlyphRenderData result = new GlyphRenderData();
getNativeGlyphRenderData(getNativeStrikePtr(), glyphCode, x, y, result);
return result;
}

// called from the Sun2D renderer
Expand Down
10 changes: 4 additions & 6 deletions src/java.desktop/macosx/classes/sun/font/NativeFont.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,6 @@ public GeneralPath getGlyphOutline(long pScalerContext,
return null;
}

public GeneralPath getGlyphVectorOutline(long pScalerContext,
int[] glyphs, int numGlyphs,
float x, float y) {
return null;
}


long getGlyphImage(long pScalerContext, int glyphCode) {
return 0L;
Expand All @@ -104,4 +98,8 @@ Rectangle2D.Float getGlyphOutlineBounds(long pScalerContext,
int glyphCode) {
return new Rectangle2D.Float(0f, 0f, 0f, 0f);
}

public SlotInfo getSlotInfoForGlyph(int glyphCode) {
return new SlotInfo(getDelegateFont());
}
}
2 changes: 1 addition & 1 deletion src/java.desktop/macosx/classes/sun/font/NativeStrike.java
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ GeneralPath getGlyphOutline(int glyphCode, float x, float y) {
return null;
}

GeneralPath getGlyphVectorOutline(int[] glyphs, float x, float y) {
GlyphRenderData getGlyphRenderData(int glyphCode, float x, float y) {
return null;
}

Expand Down
58 changes: 30 additions & 28 deletions src/java.desktop/macosx/classes/sun/lwawt/macosx/CTextPipe.java
Original file line number Diff line number Diff line change
Expand Up @@ -81,32 +81,26 @@ public void drawString(final SunGraphics2D sg2d, final String s, final double x,
}
}

private boolean hasSlotData(GlyphVector gv) {
private boolean hasSlotData(GlyphVector gv, Font2D font2D) {
final int length = gv.getNumGlyphs();
for (int i = 0; i < length; i++) {
if ((gv.getGlyphCode(i) & CompositeGlyphMapper.SLOTMASK) != 0) {
return true;
if (length > 0) {
int slotMask = font2D
.getSlotInfoForGlyph(gv.getGlyphCode(0))
.getSlotMask();
for (int i = 0; i < length; i++) {
int glyphCode = gv.getGlyphCode(i);
if ((glyphCode & slotMask) != 0) {
return true;
}
}
}
return false;
}

private Font getSlotFont(Font font, int slot) {
Font2D f2d = FontUtilities.getFont2D(font);
if (f2d instanceof CFont) {
CompositeFont cf = ((CFont)f2d).getCompositeFont2D();
PhysicalFont pf = cf.getSlotFont(slot);
Font f = new Font(pf.getFontName(null),
font.getStyle(), font.getSize());
return f;
}
return null;
}

private GlyphVector getGlyphVectorWithRange(final Font font, final GlyphVector gV, int start, int count) {
private GlyphVector getGlyphVectorWithRange(final Font font, final GlyphVector gV, int start, int count, int slotShift) {
int[] glyphs = new int[count];
for (int i = 0; i < count; i++) {
glyphs[i] = gV.getGlyphCode(start+i) & CompositeGlyphMapper.GLYPHMASK;
glyphs[i] = gV.getGlyphCode(start+i) >>> slotShift;
}
// Positions should be null to recalculate by native methods,
// if GV was segmented.
Expand All @@ -119,11 +113,11 @@ private GlyphVector getGlyphVectorWithRange(final Font font, final GlyphVector g
return sgv;
}

private int getLengthOfSameSlot(final GlyphVector gV, final int targetSlot, final int start, final int length) {
private int getLengthOfSameSlot(final GlyphVector gV, final int targetSlot, final int slotMask,
final int start, final int length) {
int count = 1;
for (; start + count < length; count++) {
int slot = (gV.getGlyphCode(start + count) &
CompositeGlyphMapper.SLOTMASK) >> 24;
int slot = gV.getGlyphCode(start + count) & slotMask;
if (targetSlot != slot) {
break;
}
Expand All @@ -143,25 +137,33 @@ private void drawGlyphVectorImpl(final SunGraphics2D sg2d, final GlyphVector gV,

public void drawGlyphVector(final SunGraphics2D sg2d, final GlyphVector gV, final float x, final float y) {
final Font prevFont = sg2d.getFont();
sg2d.setFont(gV.getFont());
Font gvFont = gV.getFont();
Font2D f2d = FontUtilities.getFont2D(gvFont);
if (f2d instanceof FontSubstitution fs) {
f2d = fs.getCompositeFont2D();
}

if (hasSlotData(gV)) {
if (hasSlotData(gV, f2d)) {
final int length = gV.getNumGlyphs();
float[] positions = gV.getGlyphPositions(0, length, null);
int start = 0;
while (start < length) {
int slot = (gV.getGlyphCode(start) &
CompositeGlyphMapper.SLOTMASK) >> 24;
sg2d.setFont(getSlotFont(gV.getFont(), slot));
int count = getLengthOfSameSlot(gV, slot, start, length);
int glyphCode = gV.getGlyphCode(start);
Font2D.SlotInfo slotInfo = f2d.getSlotInfoForGlyph(glyphCode);
int slotMask = slotInfo.getSlotMask();
int slot = glyphCode & slotMask;
sg2d.setFont(new Font(slotInfo.font.getFontName(null),
gvFont.getStyle(), gvFont.getSize()));
int count = getLengthOfSameSlot(gV, slot, slotMask, start, length);
GlyphVector rangeGV = getGlyphVectorWithRange(sg2d.getFont(),
gV, start, count);
gV, start, count, slotInfo.slotShift);
drawGlyphVectorImpl(sg2d, rangeGV,
x + positions[start * 2],
y + positions[start * 2 + 1]);
start += count;
}
} else {
sg2d.setFont(gvFont);
drawGlyphVectorImpl(sg2d, gV, x, y);
}
sg2d.setFont(prevFont);
Expand Down
Loading