G4P Textfield Font Showing as Boxes

Hi all, I made an app for PC/Mac/Linux with Processing (with Peter Lager’s endless support! Thanks Peter!).

I just noticed that on a Linux machine, some of the special characters are showing as boxes:

For the textfield, I am specifying the font like this:

tfSceneName.setFont(new Font("Noto Sans Bold", G4P.PLAIN, 36));

For the other fonts, I specify them like this:

PFont font;
font = loadFont("NotoSansJP-Regular18.vlw");
textFont(font, 18);

As you can see, the second method works, likely because I have included the .vlw file, along with the special characters inside the .vlw file, with the sketch.

Is there any way to get the textfield to work with the special characters too?

If I turn off this line:

//tfSceneName.setFont(new Font("Noto Sans Bold", G4P.PLAIN, 36));

…then the correct characters show up in the textfield, but they are much smaller.

I’m sure this is a simple thing to fix.

Can anyone share how I can get the special fonts to work correctly in the textfield, with larger size, and not show as boxes?

Including the font is no problem, but I’m not sure how to do that with G4P and the textfield specifically…

Thanks,

Mike

PS, just lucky I suppose, but this issue does not show up in Mac or PC versions that I have tested. Perhaps those test systems just happened to have the right font installed?

Well I’ve been trying to solve this, but no luck.

I ran across this post, and from it gleaned that I could use the following code to set the font for the GTextfield:

Font snFont;//set in variables before setup

  snFont = getFont("NotoSans-Bold.ttf", Font.BOLD, 36);
  if (snFont != null) tfSceneName.setFont(snFont);

And with it use this function:

public Font getFont(String ttf_name, int style, float size) {
  InputStream is = createInput(ttf_name);
  Font awtfont = null;
  try {
    awtfont = Font.createFont(Font.TRUETYPE_FONT, is).deriveFont(style, size);
  }
  catch(Exception e) {
    println("Failed to load font " + ttf_name);
  }
  return awtfont;
}

So this should include the correct font - provided its in the data folder. I did copy the .ttf file into the data folder.

However, behavior is unchanged. So apparently the special characters are not included in the Noto Sans font.

Where it is working, I had created .vlw file and included those special characters.

Which leaves me still not knowing how to proceed. As I said, the special characters show up fine on the test Windows and Mac machines I’ve used, but on the Linux machine, only boxes show for the special characters.

Does anyone have any ideas how to resolve this?

Thanks,

Mike

So the code above worked in Windows and osx but not Linux :disappointed:. This would suggest that the special characters are actually in the font file so it seems that there are two possibilities

  1. Linux is loading the font but not making the special characters available.
  2. The JRE installed on the Linux machine does not load the entire font or ignores extended character sets.

Have you actually installed the font in Linux so it is available to other applications?

  • YES open a word processor and see if the characters are available. If unavailable it appears to be a Linux thing.
  • NO try installing the font rather than load it from the data folder

Thank you so much Peter. I really appreciate it.

I have tried installing the font in Linux. I installed the entire Noto family, and no-go, it doesn’t appear in the app.

I didn’t try opening a Word Processor though; I’ll do that.

Strangely, if I don’t specify the font by using:

tfSceneName.setFont(new Font("Noto Sans Bold", G4P.PLAIN, 36));

(Where tfSceneName is the textfield)

then it works! The special characters show up fine. But the font is very tiny.

So there is obviously SOME way to make this happen, but just not by using the normal way through G4P.

I’m not sure where it’s pulling the correct font and characters when I don’t specify. Perhaps you know - if no font is specified in the code, as in the above line, then how does the textfield know which font to use?

I will try your suggestions too and report back.

I totally appreciate your kind wisdom and support.

Mike

What happens if you increase 36 to 72 or even 96

1 Like

Mmm, misunderstanding…if I don’t use that line, it works.

If I enable it, and change it to 72, it shows the font gigantic, but boxes for the special characters.

I.e, if I do this:

//tfSceneName.setFont(new Font("Noto Sans Bold", G4P.PLAIN, 36));

THEN it works…and font is tiny…

So how does the textfield decide what font to use if I don’t specify it like this (or like the other method I showed above)?

Thanks Peter,

Mike

I am not an expert in fonts or Linux but try running this sketch in Processing with Linux and report what happens. :thinking:

import g4p_controls.*;
import java.awt.*;

GTextField txf;

void setup() {
  size(480, 160);
  txf = new GTextField(this, 40, 30, 200, 40);
  txf.setFont(new Font("Noto Sans Bold", G4P.PLAIN, 32));
  txf.addEventHandler(this, "txfFix");
}

public void txfFix(GTextField source, GEvent event) {
  if (event == GEvent.CHANGED || event == GEvent.GETS_FOCUS) {
    StyledString ss = txf.getStyledText();
    ss.addAttribute(G4P.SIZE, 32, 0, ss.length());
  }
}

void draw() {
  background(200, 200, 255);
}

I don’t have access to a Linux machine so I can’t try this myself.

1 Like

This is what I see on my Linux system:
fnt

3 Likes

Thank you Peter.

Will test when I’m back at my Linux unit, likely tomorrow.

Many thanks!!

Mike

So, I’m getting same results as Svan. It works with whatever regular type you type into it, but if I copy/paste a special character code, it shows the character code.

Now here’s a modified version. I disabled the line to set the font, and the special character works with the append button:

import g4p_controls.*;
import java.awt.*;

GTextField txf;

void setup() {
  size(480, 160);
  txf = new GTextField(this, 40, 30, 200, 40);
  //txf.setFont(new Font("Noto Sans Bold", G4P.PLAIN, 32));
  txf.addEventHandler(this, "txfFix");
  createGUI();
}

public void txfFix(GTextField source, GEvent event) {
  if (event == GEvent.CHANGED || event == GEvent.GETS_FOCUS) {
    StyledString ss = txf.getStyledText();
    ss.addAttribute(G4P.SIZE, 32, 0, ss.length());
  }
}

void draw() {
  background(200, 200, 255);
}


public void button1_click1(GButton source, GEvent event) { //_CODE_:button1:985216:
  println("button1 - GButton >> GEvent." + event + " @ " + millis());
  txf.appendText("\u266A");
} //_CODE_:button1:985216:



// Create all the GUI controls. 
// autogenerated do not edit
public void createGUI(){
  G4P.messagesEnabled(false);
  G4P.setGlobalColorScheme(GCScheme.BLUE_SCHEME);
  G4P.setMouseOverEnabled(false);
  surface.setTitle("Sketch Window");
  button1 = new GButton(this, 321, 104, 80, 30);
  button1.setText("Append");
  button1.addEventHandler(this, "button1_click1");
}

// Variable declarations 
// autogenerated do not edit
GButton button1; 

Now, if you re-enable the line //txf.setFont(new Font("Noto Sans Bold", G4P.PLAIN, 32));

then it doesn’t work. Only boxes show for the special character.

Of course I should have thought to create a simple, repeatable example. I WILL learn that from you Peter!!

Anyway, at least it’s clear what’s working.

Of course you don’t have to solve this Peter, but if you have any ideas, I would be grateful.

All the best, and thank you.

Mike

PS, also - thank you @svan !

I can’t truly solve it without access to a Linux machine but I can share some thoughts

As I said I am not an expert on fonts but I do have some ideas after some googling -

I notice that you are using Unicode characters so the first thing for you to try is change the line

txf.setFont(new Font("Noto Sans Bold", G4P.PLAIN, 32));
to
txf.setFont(new Font("Arial", G4P.PLAIN, 32));

and try that in Linux (works on my my mac). If it works we might be getting somewhere.

I do have one question - the textfield control usually accepts characters entered from the keyboard - how are you entering the ‘special characters’ into the textfield?

2 Likes

Hi Peter, I tried your suggestion.

Overall, it works!!!

But, mixed results…

On the Linux box, when I use txf.setFont(new Font("Arial", G4P.PLAIN, 32));, the special characters appear fine - and the text is IDENTICAL to the Noto Sans font. I mean to the pixel, even though I’ve disabled the Noto Sans line.

But again, the special characters work. This is actually what I wanted - the Noto Sans font matches the device this connects to, so there is coherence in UI.

HOWEVER…

When I try this on my M3 Mac, while in both cases the special characters appear, it does switch the fonts from Noto Sans to Arial (as expected I might add).

So the real puzzler is, why does the Linux box use the Noto Sans font but allow special characters when using the Arial font setter, and why does the Mac correctly switch the font with the same code?

I am pleased to have “A” solution - even if it’s not complete or understandable. But I hate not understanding things, and it points potential problems in other installations of the app.

Again, so strange that if you don’t specify the font at all for the txf, the special characters work perfectly but the font is tiny.

How does the textfield decide what font to use if you don’t specify it? How is the size set and font decided, if you don’t use txf.setFont(new Font("Arial", G4P.PLAIN, 32));?

And to answer your question, the special characters are only entered with a little menu that appends the characters to the end of the textfield text:

Whew!

Thank you for your support Peter; already you’ve given me a workaround I can use, if nothing else, and I so appreciate it.

Mike

Since you are not using the keyboard I would remove the function txffix and line
txf.addEventHandler(this, "txfFix");

because they are redundant, and to prevent the textfield getting focus use the setTextEditEnabled method so your example becomes

import g4p_controls.*;
import java.awt.*;

GTextField txf;

void setup() {
  size(480, 160);
  txf = new GTextField(this, 40, 30, 200, 40);
  txf.setFont(new Font("Arial", G4P.PLAIN, 32));
  txf.setTextEditEnabled(false); //  disable keyboard editing
  createGUI();
}

void draw() {
  background(200, 200, 255);
}

public void button1_click1(GButton source, GEvent event) {
  txf.appendText("\u266A");
}

public void createGUI() {
  G4P.messagesEnabled(false);
  G4P.setGlobalColorScheme(GCScheme.BLUE_SCHEME);
  G4P.setMouseOverEnabled(false);
  surface.setTitle("Sketch Window");
  button1 = new GButton(this, 321, 104, 80, 30);
  button1.setText("Append");
  button1.addEventHandler(this, "button1_click1");
}

GButton button1;

As I said, I am no expert on fonts but my googling shows that not all fonts support Unicode characters. My conclusions are

  1. The Noto Sans Bold font does not support Unicode characters
  2. The Arial font does support Unicode characters
  3. In Windows and osx the OS detects that you are using Unicode characters and selects a different font that does support them.
  4. In Linux the OS does not swap fonts so shows Unicode characters as boxes.

Of course I could be wrong and if so I am sure that someone will point out the error of my ways. :innocent:

2 Likes

Many thanks Peter.

Actually, the user needs to be able to change the textfield using the keyboard, and/or append the special characters, so the textfield needs to remain editable. But I appreciate your vigilance.

As usual, you are thinking holistically and about best practices, so thank you.

You must be right about the font characters.

But I still can’t get away from the question,

How does your textfield set the font size and typeface if I never specify it?

Because for all intents and purposes, it works great without that line, except for the size being tiny.

Can you share how your textfield control sets its font size and typeface if it is not explicitly set in the code?

Again, thank you so much kind sir.

Mike

G4P provides a number of default fonts (exert from G4P.java)

	// Font used for all text input controls
	static Font inputFont = new Font("Arial", Font.PLAIN, 12);
	// Font used for all text controls
	static Font displayFont = new Font("Arial", Font.PLAIN, 12);
	// Font used for slider numbers
	static Font sliderFont = new Font("Arial", Font.BOLD, 11);
	// Font used for all text controls
	static Font tooltipFont = new Font("Arial", Font.PLAIN, 12);

and you can change these with the methods

G4P.setInputFont(String familyName, int style, int size);
G4P.setDisplayFont(String familyName, int style, int size);
G4P.setSliderFont(String familyName, int style, int size);
G4P.setTipFont(String familyName, int style, int size);

You can also set these in GUI Builder

2 Likes

Absolutely wonderful information Peter; thank you so much!

I have marked your previous post as the solution.

As per usual, you’ve managed to fix a tricky situation, even when you weren’t an “expert” at fonts.

Thank you again. You are amazing.

Mike

Just to cap this query, I was able to implement the font fix for the Linux boxes. So far on the one Linux box I’ve tested, it works perfectly.

Thank you again @quark and @svan ! :smiling_face_with_three_hearts: