RSyntaxTextArea icon indicating copy to clipboard operation
RSyntaxTextArea copied to clipboard

Cannot enable ligatures (JetBrains Mono font)

Open tferr opened this issue 2 years ago • 4 comments

JetBrains mono is a much-improved font for coding, featuring many readability features such as coding-specific ligatures. I am not able to use this font properly in RSyntaxTextArea.

Take this snippet that requires FlatLaf and the FlatLaf JetBrains Mono distribution (direct downloadable jars for both dependencies: flatlaf, flatlaf-fonts-jetbrains-mono):

import java.awt.Font;
import java.awt.font.TextAttribute;
import java.util.*;
import javax.swing.*;

import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;

import com.formdev.flatlaf.fonts.jetbrains_mono.FlatJetBrainsMonoFont;
import com.formdev.flatlaf.util.FontUtils;

public class Test {

	public Test() {
		FlatJetBrainsMonoFont.install();
		run(new JTextArea());
		run(new RSyntaxTextArea());
	}

	void run(final JTextArea ta) {
		final Font f = FontUtils.getCompositeFont(FlatJetBrainsMonoFont.FAMILY, Font.PLAIN, 40);
		final Map<TextAttribute, Object> textAttributes = new HashMap<>();
		textAttributes.put(TextAttribute.KERNING, TextAttribute.KERNING_ON);
		textAttributes.put(TextAttribute.LIGATURES, TextAttribute.LIGATURES_ON);
		ta.setFont(f.deriveFont(textAttributes));
		ta.setText("Current font: " + ta.getFont().getFontName() + "\nligatures: ## <> => ++ ~~ <= >= <=> ->>");
		JFrame frame = new JFrame(ta.getClass().getSimpleName());
		frame.getContentPane().add(ta);
		frame.pack();
		frame.setVisible(true);
	}

	public static void main(final String[] args) {
		new Test();
	}

The ligatures do render in JTextArea: image

..but not in a RSyntaxTextArea:

image

Why is that? I could not find any obvious signs that TextAttributes are being overridden in the code base.

tferr avatar Apr 21 '23 16:04 tferr

pinging @DevCharly in case they have experienced this elsewhere

tferr avatar Apr 21 '23 16:04 tferr

I'm actually surprised that ligatures work in Swing 😮 Didn't know TextAttribute.LIGATURES...

So I tried to enable ligatures in FlatLaf Theme Editor, which uses RSyntaxTextArea, and it works 😮

image

I think the reason is that FlatLaf Theme Editor uses a subclass of org.fife.ui.rsyntaxtextarea.SyntaxScheme, which always uses the same font that has the ligatures attribute.

There are several places in SyntaxScheme where a new font is created using family, style and size, but without attributes. I think the ligature attribute is lost there. E.g.

https://github.com/bobbylight/RSyntaxTextArea/blob/9097e51fc5e289d761dca139a3a08459bf12614a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/SyntaxScheme.java#L445-L449

or

https://github.com/bobbylight/RSyntaxTextArea/blob/9097e51fc5e289d761dca139a3a08459bf12614a/RSyntaxTextArea/src/main/java/org/fife/ui/rsyntaxtextarea/SyntaxScheme.java#L109-L110

To fix this, and keep the usage of StyleContext.getFont(), it is probably necessary to additionally invoke font.deriveFont(Map attributes) to reapply some font attributes of the base font.

DevCharly avatar Apr 23 '23 12:04 DevCharly

Thanks a lot for this. I'm closing it, as this is a reasonable workaround.

tferr avatar Jun 05 '23 15:06 tferr

I'll reopen this to make the necessary changes in SyntaxScheme pointed out above. Thanks folks for this!

bobbylight avatar Jul 09 '23 20:07 bobbylight

Fixed in #554 and #559.

bobbylight avatar Jul 13 '24 16:07 bobbylight