Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

textBounds on multiline text breaks if global textLeading does not match the provided font size #7147

Open
1 of 17 tasks
davepagurek opened this issue Jul 26, 2024 · 1 comment

Comments

@davepagurek
Copy link
Contributor

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.4

Web browser and version

Firefox, Chrome

Operating system

MacOS

Steps to reproduce this

Steps:

  1. Load a font
  2. Measure the textBounds() of multiline text, passing in a larger font size than the default (e.g. 50)
  3. The resulting box does not cover the text

Snippet:

In this example, I'm setting the font size on a graphic, so the main canvas still has the default text size:

let message
let fnt
let g


function tightBound() {
  const bbox = fnt.textBounds(message.value(), 0, 0,g.textSize());
  g.noFill()
  g.rectMode(CENTER)
  
  g.rect(0,0,bbox.w,bbox.h)
  console.log(message.value())
}

function preload() {
fnt = loadFont("https://fonts.gstatic.com/s/opensans/v40/memSYaGs126MiZpBA-UvWbX2vVnXBbObj2OVZyOOSr4dVJWUgsg-1y4nY1M2xLER.ttf")
}

function setup() {
  
  createCanvas(windowWidth,windowHeight);
  g = createGraphics(width, height)
message = createElement('textarea');
  message.value('test\nanother')
  message.position(20, 20);
  message.size(300, 200);
  g.textAlign(CENTER,CENTER)
}

function draw() {
  g.background(220);
  g.push()
  g.translate(width/2,height/2)
      g.textFont(fnt);
  g.textSize(50)
  g.text(message.value(),0,0)
  tightBound()
  g.pop()
  image(g, 0, 0)
}

Result:
image

Expected:
image

Cause

In the implementation of textBounds, it gets the text leading from the main instance's renderer:

const lineHeight = p._renderer.textLeading();

I'm not sure the best way to fix this; if you're drawing text onto a different renderer like a graphic, there's not a deterministic way to figure out which renderer to use ahead of time. The best option might be to let you pass that value in, which might require a change to the arguments to this function to not have an overwhelmingly long parameter list.

@dhowe
Copy link
Contributor

dhowe commented Jul 28, 2024

Thanks @davepagurek -- this is a known-issue discussed in #6967
The fix, which will hopefully be included in v2.0, is to accept textLeading (and all other relevant params) as part of options

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants