-
-
Notifications
You must be signed in to change notification settings - Fork 3.4k
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
textAlign(CENTER, CENTER) does not vertically center user-loaded fonts #6593
Comments
After his initial post, I (Naoto) noticed that q5.js simply uses Also, I found that by using textBounds, same alignment as |
Hey, |
@diyaayay feel free to, but can you suggest what steps have to be taken? |
@micuat I noticed on the Discourse thread you mentioned:
Do you think we need to adjust this to treat single lines differently? Lines 305 to 306 in 7587e0a
|
Thanks to @perminder-17 for helping me with this issue. This is what we came up with, which solves the issue. There may be better ways to achieve this still. Let me know if there are any changes that could be a better approach, Thanks. let offset = 0;
if (this._textBaseline === constants.CENTER) {
if (lines.length === 1) {
offset = 6 * (p.textAscent() - (0.9084) * this._textSize);
}
else {
offset = (lines.length - 1) * p.textLeading() / 2;
}
} |
Thanks for this @diyaayay -- can you clarify what those hard-coded numbers (6 and 0.9084) represent ? |
@dhowe This value is used to calculate the offset for vertically centering single lines of text when a text font is not used. It represents the ratio of the text ascent to the text size when the default font is used. This value is hardcoded because it is an empirical observation based on the default font metrics in various browsers. It might not be accurate for all fonts, but it provides a reasonable approximation for cases. 6: It is used to compensate for the difference between the actual text ascent and the value obtained using the 0.9084 ratio. This difference arises due to the variations in font metrics across different browsers and systems. Like we are adjusting the offset. Let's say, we are drawing textFont with an offset of 12 pixels below the original. And the value which we were getting with (p.textAscent() -0. 9084(textSize) =-2) then we multiplied with 6 to get the original value and drew it to the center by aligning vertically. There is another approach that I came across which does not involve hardcoded values: let offset = 0;
if (this._textBaseline === constants.CENTER) {
if (lines.length === 1) {
const textWidth = this.textWidth(lines[0]);
const canvasWidth = this.canvas.width;
offset = (canvasWidth - textWidth) / 2;
} else {
offset = (lines.length - 1) * p.textLeading() / 2;
}
} The screenshots below are the outputs and accuracy achieved from the hardcoded values approach: The screenshots below are the outputs of the second approach that I mentioned above: |
The outputs look correct for the 2nd method, but I'm not sure I understand the code: we are talking about vertically centering a single line of text, but, unless I'm misreading, the calculation uses Also, there are two outputs we could potentially match: a) how we handle centered vertical alignment for browser fonts, and b) how Processing handles this case Below images show that a) and b) are not the same. And, if I remember correctly, we decided, rather early on, to deviate here as Processing's approach appeared to be incorrect. Further, since we don't mess with existing sketches, it would seem we should aim for the first output below as our target. @diyaayay perhaps you can show the results of one or both of your methods, overlayed on the first output, for a few different fonts/sizes ? p5.js browser font: function setup() {
createCanvas(400, 400);
textFont("Georgia", 48);
textAlign(CENTER, CENTER);
line(200, 0, 200, height);
line(0, 200, width, 200);
text("Align", 200, 200);
}
processing .vlw font: size(400, 400);
textFont(loadFont("Georgia-48.vlw"));
textAlign(CENTER, CENTER);
line(200, 0, 200, height);
line(0, 200, width, 200);
text("Align", 200, 200);
function setup() {
createCanvas(400, 400);
loadFont("Georgia.ttf", f => {
textFont(f, 48);
textAlign(CENTER, CENTER);
line(200, 0, 200, height);
line(0, 200, width, 200);
text("Align", 200, 200);
});
} |
@dhowe Sorry for replying so late, I was busy with university exams.
this is what p5.js is currently using for vertically centering multiple lines of text. Should we be handling textLeading for single lines or calculating offset with including textLeading for single lines? Or am I in the wrong direction? |
The issue appears to be with the the y-position adjustment in this line, which is attempting to vertically center the text (without this adjustment, the text is baseline-aligned.) So function setup() {
createCanvas(400, 400);
textFont('Georgia', 48);
doText(100);
loadFont("Georgia.ttf", f => {
textFont(f, 48);
doText(300);
});
}
function doText(x) {
textAlign(CENTER, CENTER);
line(x, 0, x, height);
line(0, 200, width, 200);
text("Align", x, 200);
} |
Idk what is wrong with the calculation of the ascent because the top alignment should have worked right? or is there an extra offset at the ascent because of the nature of user-loaded fonts. |
@diyaayay Looking at your screenshots, could it be that the top and center align text is using the font's bounding box top instead of ascent to calculate its position, accounting for the extra space at the top? |
@limzykenneth Oh! maybe. I will look into this again. I still have the branch where I was working on this issue. Thanks for mentioning another potential cause of why this might be happening. |
closing pending further information |
Most appropriate sub-area of p5.js?
p5.js version
1.8.0
Web browser and version
any
Operating System
any
Steps to reproduce this
below is copied from a topic on discourse by @quinton-ashley : https://discourse.processing.org/t/why-is-text-not-centered-properly-with-textalign-center-center/
textAlign(CENTER, CENTER) does not seem to work when used with user loaded fonts.
Here is a demonstration I made in p5.js:
editor.p5js.org
Here’s the same code run with q5.js showing how the text is supposed to be displayed in the center of the canvas.
editor.p5js.org
I think the problem is caused by the use of OpenType instead of the native canvas text drawing. Text quality is also noticeably worse than native canvas rendering at lower resolutions as shown in the demonstrations.
The text was updated successfully, but these errors were encountered: