processing / p5.js

p5.js is a client-side JS platform that empowers artists, designers, students, and anyone to learn to code and express themselves creatively on the web. It is based on the core principles of Processing. http://twitter.com/p5xjs —
http://p5js.org/
GNU Lesser General Public License v2.1
21.12k stars 3.22k forks source link

TextToPoints() ignores text alignment #6893

Open araid opened 3 months ago

araid commented 3 months ago

Most appropriate sub-area of p5.js?

p5.js version

1.9.1

Web browser and version

Chrome 122.0.6261.129

Operating system

macOS

Steps to reproduce this

Steps:

  1. Load an external font
  2. Define a multiline text string (use the character \n)
  3. Call textAlign(CENTER, BASELINE) and then textToPoints on that string.
  4. Observe how the points are always left-aligned.

Snippet:

see https://editor.p5js.org/araid/sketches/S7DRlqtvP


let pts;
let font;
let str = 'Text\nto\npoints';

function preload(){
  font = loadFont('Inter-Black.otf');
}

function setup() {
  createCanvas(600, 600);

  textAlign(LEFT, BASELINE);
  textAlign(CENTER, BASELINE); // this doesn't work
  textSize(80);
  textFont(font);

  pts = font.textToPoints(str, 200, 0, 80, {
    sampleFactor: 0.25
  });
}

function draw() {
  background(200);
  translate(20, 140);

  // draw text
  fill(255);
  text(str, 200, 0);

  // draw points
  fill(28);
  noStroke();

  for(let i =0; i< pts.length; i++){
    ellipse(pts[i].x, pts[i].y, 2,2); 
  }
}
RuimingShen commented 3 months ago

This is not a bug from p5 code, it is an issue from textAlign property. Please reach out to developers for textAlign for this problem! More info can be found here [https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/textAlign] The only piece of code realted to textAlign is here, and it doesn't edit anything about LEFT, RIGHT,CENTER for this.

araid commented 3 months ago

@RuimingShen I'm not sure I understand your answer. What's the issue with textAlign?

My report refers to textToPoints(). When I step through the function, I don't see alignment being considered at any moment. That means that for multiline strings, the text layout and points are misaligned.

textAlign(LEFT, BASELINE) textAlign(CENTER, BASELINE)
text_to_points_left text_to_points_ctr

I updated the sketch to make it clearer. Please let me know if that makes sense.

dhowe commented 3 months ago

@RuimingShen may be confused about how textAlign works. But to provide some clarity on the issue, when textToPoints() was initially written, it did not include support for multiple text lines. If you needed multiple lines, you would call it multiple times. At some point, support for splitting a string on line breaks was added, but without corresponding support for the various alignments. Fixing this would require only (I think) using the existing _handleAlignment() function from textBounds() in textToPoints() as well

mathewpan2 commented 2 months ago

I'd like to work on this.