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

[Question] How to add Kerning and Line Height to context.fillText() #1404

Closed
shreyasp opened this issue Apr 8, 2019 · 5 comments
Closed

Comments

@shreyasp
Copy link

shreyasp commented Apr 8, 2019

I have a plugin for Sketch App which I use to extract the data from sketch file and convert to JPEG using node-canvas with certain modifiable fields.

Templates (Sketch File) use Kerning (Character Spacing) and Line Height because of which modifiable fields don't replicate the accurate style when compared with templates.

Is there a way to add Kerning and Line Height to context object so that the template can be accurately mirrored with its derivative JPEG?

@asturur
Copy link
Contributor

asturur commented Apr 27, 2019

Not that i know of.
Normal canvas does not even wrap text in lines.

@zbjornson
Copy link
Collaborator

Re: Kerning, see #1014 and feel free to add your thoughts.

Re: Line-height: since there is no text wrapping in HTML canvas, I'm not sure this is applicable, is it?

@chearon
Copy link
Collaborator

chearon commented May 7, 2019

In #1014 it sounds like we aren't going to add letter-spacing. There's some hacky solutions on SO but technically you'd need something like fontkit instead of fillText() since you need grapheme awareness.

Implementing line height isn't difficult but first you have to do line breaking. First you mark which characters can be broken to the next line, then measure the rendered-size (like with ctx.measureText()) up until each breakable character (improvement: do it with a binary search) and greedily fill the available width with lines. For good language support you can use something like linebreak.

When you have your lines determined, use line-height to determine the leading. CSS uses the formula leading = line-height - (ascender + descender), ascender and descender come from the font file. Half the leading goes on the top, then translate down by the ascender and that's the baseline. Draw the text, then add the descender and the other leading/2 and repeat everything for the next line.

@asturur
Copy link
Contributor

asturur commented May 7, 2019

I think linebreak should be another library implementation or an application implementation.

Canvas does not have lineHeight or lineBreak, and shouldn't be implemented here.
There are already other higher level libraries that include this logic on top of canvas, (fabricJS is one) and work under node with node-canvas.

@chearon
Copy link
Collaborator

chearon commented May 7, 2019

Yeah, I don't think OP was suggesting that since it was marked as [Question]. Feel free to continue discussion here but closing since it's been answered and #1014 covers letter spacing.

@chearon chearon closed this as completed May 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants