processing/p5.js

textFont() doesn't work for WebGL outside of preload() for loading fonts unlike P2D which isn't specified

Closed this issue · 10 comments

Most appropriate sub-area of p5.js?

  • Accessibility
  • Color
  • Core/Environment/Rendering
  • Data
  • DOM
  • Events
  • Image
  • IO
  • Math
  • Typography
  • Utilities
  • WebGL
  • Build process
  • Unit testing
  • Internationalization
  • Friendly errors
  • Other (specify if possible)

p5.js version

1.9.3

Web browser and version

115.6.0esr

Operating system

Debian 12

Steps to reproduce this

Steps:

  1. Create a WebGL canvas
  2. Set a font using textFont as requested by the error, but not in the preload() function:
    WEBGL: you must load and set a font before drawing text. See `loadFont` and `textFont` for more details.
  3. Try to draw text and get the error:
    WEBGL: you must load and set a font before drawing text. See `loadFont` and `textFont` for more details.

Snippet:

function setup() {
  createCanvas(100, 100, WEBGL);
  
  background(200);
  textFont('Courier New');
  textSize(24);
  text('hi', 35, 55);

  describe('The text "hi" written in a black, monospace font on a gray background.');
}

This should be better clarified in the error message since using textFont() outside of preload() is valid in P2D/Canvas mode or work outside of the preload() function (I doubt that's the path we should go down though).
The fact that textFont() only works in preload() mode isn't even present on its documentation page

I think this error is misleading but for a different reason: it's allowed in setup, but in WebGL, you must use a loadFont font instead of a font name string.

I think this error is misleading but for a different reason: it's allowed in setup, but in WebGL, you must use a loadFont font instead of a font name string.

Yeah, I didn't differentiate between loading an already loaded font and loading a new font so I changed the updated more specific error msg of the PR to be:

WEBGL: you must load and set a font before drawing text. See `loadFont` and `textFont` (both of which have to be executed in preload() for WebGL mode when loading a new font) for more details.

both of which have to be executed in preload() for WebGL mode when loading a new font

Is this true? I think textFont works outside of preload, e.g. in https://openprocessing.org/sketch/2241717

both of which have to be executed in preload() for WebGL mode when loading a new font

Is this true? I think textFont works outside of preload, e.g. in https://openprocessing.org/sketch/2241717

That example is of textFont() loading an already loaded font. When loading a new font like 'Courier New' in WEBGL mode textFont() has to be used in preload().

I'm not sure I'm following the distinction between an already loaded font and a new font. I don't think we support string font names at all in WebGL, which is what the current error message is trying to say. If you set the font to a string font in preload, I don't think it will have direct behavior even though it doesn't give an error -- it just doesn't know yet that you're trying to create a WebGL sketch.

I'm not sure I'm following the distinction between an already loaded font and a new font. I don't think we support string font names at all in WebGL, which is what the current error message is trying to say. If you set the font to a string font in preload, I don't think it will have direct behavior even though it doesn't give an error -- it just doesn't know yet that you're trying to create a WebGL sketch.

Ah, I see. It looks like what's actually going on here is it's creating a WebGL canvas in the preload function before ignoring it and creating a P2D canvas automatically without a createCanvas() statement which is how the font's actually getting loaded with no errors reporting what happened.

Example Code:

// WEBGL Example
function preload() {
  createCanvas(100, 100, WEBGL); // In WebGL textFont has to be executed in preload
  textFont('Courier New');
}
 
function setup() {
  background(200);
  textSize(24);
  text('hi', 35, 55);
  
  describe('The text "hi" written in a black, monospace font on a gray background.');
}

Sketch: https://editor.p5js.org/PotatoBoy/sketches/fSU62FlS3

Sorry about that, I didn't know that it would automatically create a P2D canvas alongside the WebGL canvas explicitly created and then use that instead if I tried to use textFont(). I've closed the PR and I'm closing the issue now.

Ah ok, yeah it's pretty confusing that that example still renders a canvas! Just the wrong one. Definitely open to suggestions on how to make that clearer (maybe catching instances of canvases created in preload, since I think the library assumes it will only be made in setup?)

Ah ok, yeah it's pretty confusing that that example still renders a canvas! Just the wrong one. Definitely open to suggestions on how to make that clearer (maybe catching instances of canvases created in preload, since I think the library assumes it will only be made in setup?)

Yeah, adding a check for whether or not a canvas has been created in preload() and adding a note to the preload() page's documentation sounds great, but I'm not sure if the library only assumes that it'll be made in setup since there isn't any documentation against it and it does work.