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

font-variant, small-caps support in pango and fake small-caps #894

Open
lulu-berlin opened this issue Mar 18, 2017 · 4 comments
Open

font-variant, small-caps support in pango and fake small-caps #894

lulu-berlin opened this issue Mar 18, 2017 · 4 comments

Comments

@lulu-berlin
Copy link
Contributor

lulu-berlin commented Mar 18, 2017

My recently merged pull request #891 fixed the issue with correctly parsing the font style. The font-variant was ignored, and caused the font not to be correctly parsed.

I tried to also pass the variant to pango, but it seems that it is being ignored. Most fonts don't support small-caps (which is the only variant besides normal that is available in pango), and it seems to me that pango might not support it when it's there.

Here is my failed attempt to pass the font-variant to pango: lulu-berlin@f002e1a

I played with pangocairo on python with similar results. I couldn't find any font that would show any different when the font variant is set to VARIANT_SMALL_CAPS.

Font rendering on the web uses mostly fake small caps. I think that the general approach is to replace the lowercase characters with uppercase ones and scale them down to 70%. Do we want this also in node-canvas to imitate the browser's behavior? This will not be provided by pango and should be implemented separately.

@chearon
Copy link
Collaborator

chearon commented Mar 18, 2017

If there's no small caps support on Pango for Linux I wouldn't count on it ever happening, and it would have to be done inside node-canvas. If small caps do work on Linux they might be open to patches, which IMO is the best place to fix it although it can be hard to get your patch accepted.

I also have a TODO in the code to get the font-stretch working. I haven't tested that in Pango.

@lulu-berlin
Copy link
Contributor Author

I had no font to test it with. I found this website that mentioned lack of small caps support on Pango, but it's from 2008. I took a pick at their code and found that there's a function that tests the small caps capabilities of a font: https://git.gnome.org/browse/pango/tree/pango/pangocoretext-fontmap.c#n338
I'll try to run it on all of my fonts and see what I get.

I assume that most fonts won't have built-in support for small caps anyway. Do I understand correctly that you would like to have fake small caps implemented?

@chearon
Copy link
Collaborator

chearon commented Mar 19, 2017

So it sounds like Pango does support fonts that have the small caps feature, which would mean your unmerged commit should work on such a font. I don't know how to find that font, though.

As for the synthesized small caps... I was just saying that ideally that code is in Pango (or Pango leverages an OS feature that does that). If that ends up being impossible then it might be worth experimenting with doing it inside node-canvas. It's up to you, I don't think it's a common need but I'm sure it would be a welcomed change.

@samizdatco
Copy link
Contributor

samizdatco commented Jun 24, 2020

I did some testing using @YEver's approach of adding PANGO_VARIANT_SMALL_CAPS to the font description, but found that even when a font had small-cap glyphs they still weren't being used. On the other hand, if you turn on the smcp OpenType feature and add it to the layout object's attributes it works like a charm: samizdatco@48059a5

For example,

registerFont('./examples/crimsonFont/Crimson-Roman.ttf', {family: 'Crimson', weight:500, style:'normal'})
registerFont('./examples/crimsonFont/Crimson-Italic.ttf', {family: 'Crimson', weight:500, style:'italic'})
registerFont('./examples/crimsonFont/Crimson-Bold.ttf', {family: 'Crimson', weight:900, style:'normal'})

let canvas = createCanvas(800,400),
    ctx = canvas.getContext('2d');

ctx.fillStyle = 'white'
ctx.fillRect(0,0, canvas.width, canvas.height)

let fonts = [
  'small-caps 72px Crimson',
  'italic 72px Crimson',
  'small-caps italic 72px Crimson',
  '700 72px Crimson'
]

ctx.fillStyle = 'black'
fonts.forEach(font => {
  ctx.font = font
  ctx.fillText('Hamburgefonstiv 12379', 12, 70)
  ctx.translate(0, 90)
})

results in:
output

#1611

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