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

Word spacing is handled differently for default font compared to the same font loaded from file #1958

Closed
cqx931 opened this issue May 23, 2017 · 15 comments
Assignees

Comments

@cqx931
Copy link

cqx931 commented May 23, 2017

Test case: http://chenqianxun.com/testcases/p5textTest.html
In default font:
Line 1: The whole string is written with text()
Line 2: Each word is written separately with an offset of the space width
Two lines are exactly the same.

In loaded Helvetica_light.ttf (which is the default sans-serif font on mac)
Line 3: The whole string is written with text(), the spacing is different compared with default font
Line 4: Same as line 2, Each word is written separately with an offset of the space width

@stalgiag
Copy link
Contributor

Hmm after an embarrassingly long time spent looking through the code for parsing glyphs, I decided to just look at the advanceWidth property for each of the glyphs. Strangely the advancedWidth property is the exact same (278) for the space in the default and the loaded font in the given example. So I assume that this means the mistake in width isn't happening when reading info from the font table. I will keep working on this but will post as I go in case someone with more experience coding for text display wants to jump in and offer advice.

@dhowe
Copy link
Contributor

dhowe commented May 27, 2017

A couple of things to note here. First, due to a bug in the opentype library when this was initially written, spaces are handled separately from other glyphs in loaded fonts. I requested an update to opentype in p5 once this was fixed, which I think was done here. Since space-handling changed in opentype (and now should work correctly) you might just want to try removing this special casing ([here](https://github.com/processing/p5.js/blob/master/src/typography/p5.Font.js#L137 and https://github.com/processing/p5.js/blob/master/src/typography/p5.Font.js#L412)).

@dhowe
Copy link
Contributor

dhowe commented May 27, 2017

Glancing at the code, I also notice what appears to be another small bug in textBounds (called by textWidth), which I am fixing now (though I don't think it will affect this issue). See: #1970

@dhowe
Copy link
Contributor

dhowe commented May 27, 2017

Actually, I'm not even sure this is a bug. There is an assumption here that the spacing between words is only determined by the width of a space (and does not take into account things like kerning), but this may well be incorrect, at least for some fonts

@stalgiag
Copy link
Contributor

Hm yeah I don't know enough about type to know whether this is expected behavior. Removing the special casing you mentioned doesn't give a different result on the extra wide line but it does break the calls to textWidth(' ') on the loaded font.

@dhowe
Copy link
Contributor

dhowe commented May 28, 2017

I don't see the 'break' behavior you mention. Can you try the same test with the 'dhowe-fix-to-bounds-detection' branch (which doesn't include the special-casing for spaces) ?

@stalgiag
Copy link
Contributor

Yeah so the 'break' I mentioned doesn't happen with that branch. I probably accidentally changed something else when I was removing the lines you mentioned. Everything looks exactly as it does in the current release in my tests on that branch. With that said, the spacing is still different on the loaded font from @cqx931's example so maybe this is expected behavior?

@dhowe
Copy link
Contributor

dhowe commented May 28, 2017

Let's say I have a sentence, 'Foo bar baz'. How do I get the spacing size, in pixels, between the words "Foo" and "bar" [in a TTF font]?

You need to know the horizontal advance of the space character and kerning between "o" and " ", and between " " and "b".

from How do I calculate the space in between two glyphs in a TTF font?

Note that this appears not to be the case for (at least some of the) simple canvas font rendering cases, either b/c there is no kerning data or b/c kerning is disabled, and thus only the width of the space character is needed

Though in @cqx931's example it seems only the word-spacing is affected, not the actual letter-to-letter kerning.

Interestingly this can all be controlled via CSS in canvas as well, through combinations of the properties below (from here):

canvas {
    font-kerning : normal;
    word-spacing: 1em;
    text-rendering: optimizeLegibility;
}

@dhowe
Copy link
Contributor

dhowe commented May 28, 2017

In any case, I might recommend reposting @cqx931's question as an opentype issue (using the same test without p5.js, based on the short example code in their README)

@stalgiag
Copy link
Contributor

stalgiag commented Jun 1, 2017

@cqx931 maybe do you want to take @dhowe's advice for the time being? As it stands it is feeling like this isn't a p5 specific issue. I am going to close for now but feel free to comment on this issue or open another one if any new information arises.

@stalgiag stalgiag closed this as completed Jun 1, 2017
@dhowe
Copy link
Contributor

dhowe commented Jun 2, 2017

Here's a test of the 3 cases (p5/default, p5/custom, and opentype): opentype shows the same behavior as what we are getting in p5:

screen shot 2017-06-02 at 9 55 34 pm

@dhowe
Copy link
Contributor

dhowe commented Jun 2, 2017

I've done a bit more digging and the spacing above is cause by the fact that opentype does the layout using advance-width, rather than bounding-box.width, and for some glyphs, like spaces, these values are different. Here is the manually corrected result of the test above (the difference is that the 2 lines in the 3rd set are now spaced the same):

image

Kerning and letter-spacing are also taken into account, if present, but do not affect the examples above.

@dhowe
Copy link
Contributor

dhowe commented Jun 2, 2017

The issue remaining is that this means of (correctly) calculating the advance is not included in the the version of opentype that we are using (v0.6.9), so we need to update to the current 0.7.1 (see #1976 )

@dhowe
Copy link
Contributor

dhowe commented Jun 2, 2017

With the help of @cqx931 (who also provided a font whose glyph widths match the default rendering), here's a PR that address this issue and #1976:

screen shot 2017-06-02 at 11 38 37 pm

@lmccart
Copy link
Member

lmccart commented Jun 3, 2017

awesome @dhowe and @cqx931! closed with #1976

@lmccart lmccart closed this as completed Jun 3, 2017
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

4 participants