Skip to content
This repository has been archived by the owner on Nov 14, 2018. It is now read-only.

Inform browsers on how to optimize text rendering #6

Closed
wants to merge 1 commit into from
Closed

Inform browsers on how to optimize text rendering #6

wants to merge 1 commit into from

Conversation

alrra
Copy link
Contributor

@alrra alrra commented Jan 3, 2014

The text-rendering svg property provides a hint to the user agent about how to optimize its text rendering.

In this particular case, the value specified for the text-rendering property is geometricPrecision, indicating that the user agent should emphasize geometric precision over legibility and rendering speed.

This is done because certain aspects of fonts — such as kerning — don't scale linearly:

  • In SVG, when text is scaled up or down, browsers calculate the final size of the text (which is the specified font size and the applied scale) and request a font of that computed size from the platform's font system. However, if a user requests a font size of, say, 9 with a scale of 140%, the resulting font size of 12.6 doesn't explicitly exist in the font system, so the browser rounds the font size to 12 instead. This results in stair-step scaling of text.

If geometricPrecision is fully supported by the rendering engine, it will allow users to scale text fluidly, making the text look good.

References:

See also:

The `text-rendering` svg property provides a hint to the user agent
about how to optimize its text rendering.

In this particular case, the value specified for the `text-rendering`
property is `geometricPrecision`, indicating that the user agent should
emphasize geometric precision over legibility and rendering speed.

This is done because certain aspects of fonts — such as kerning — don't
scale linearly:

    In SVG, when text is scaled up or down, browsers calculate the final
    size of the text (which is the specified font size and the applied
    scale) and request a font of that computed size from the platform's
    font system. However, if a user requests a font size of, say, 9 with
    a scale of 140%, the resulting font size of 12.6 doesn't explicitly
    exist in the font system, so the browser rounds the font size to 12
    instead. This results in stair-step scaling of text.

If `geometricPrecision` is fully supported by the rendering engine, it
will allow users to scale text fluidly, making the text look good.

References:

  * http://www.w3.org/TR/SVG/painting.html#TextRenderingProperty
  * https://developer.mozilla.org/en-US/docs/Web/CSS/text-rendering

See also:

  * #5
@espadrine
Copy link
Member

Does it give less blurry results for you? Can you provide a comparison snapshot?

In my case, the result is just as sharp, but the letters are "rearranged" (as a result, I presume, of a suspended kerning) in an improbable way:

No text rendering:
firefox-no-text-rendering

Text rendering applied:
firefox-text-rendering

Note the weird space between "w" and "hiz" in "whiz", and in other places.

I'd love to have more comparisons before we settle on this choice.

@alrra
Copy link
Contributor Author

alrra commented Jan 3, 2014

Does it give less blurry results for you?

There are some browsers where it does, but in most cases, there isn't any difference:

  • The second svg image uses text-rendering="geometricPrecision", and the images were generated when the last commit was 7d1436a.

  • e.g. of browsers where it makes a difference (in a better way):

    • Chrome on OS X:

      • Firefox on Windows 7:

      Note: for the browsers that I've tested for, I haven't seen cases where the addition of text-rendering="geometricPrecision" made the svg look worse.

  • Screenshots:

    OS Browser default view zoomed view
    Android 4.1.2 Chrome
    Default Browser
    Firefox
    Mac OS X 10.9.1 Chrome
    Firefox
    Safari
    iOS 7.0.4 Safari
    Ubuntu 12.04 LTS Chromium
    Firefox
    Opera 12.16
    Windows 7 Chrome
    Firefox
    IE 10

    Note: If the browser version isn't specified, it means that it is the latest stable version.

Note the weird space between "w" and "hiz" in "whiz", and in other places.

Can you specify the browser / OS / device where that happened ? I didn't see this exact behavior in any of the browsers I've tested in.

I'd love to have more comparisons before we settle on this choice.

Of course, that is why I've open this pull request, so we can discuss this potential addition.

@espadrine
Copy link
Member

Thanks a lot for all this work!

It's surprising but very welcome to see that IE10 doesn't have the blur bug.

It usually doesn't make a difference, but if it makes it that much better in Firefox, it's worth it.

However, it seems like it changes the width of the text significantly. On HEAD, we are computing that dynamically (using canvas). Is there a way to ensure that what is computed matches?

@espadrine
Copy link
Member

Note the weird space between "w" and "hiz" in "whiz", and in other places.

Can you specify the browser / OS / device ? I didn't see this exact behavior in any of the browser I've tested in.

Firefox + Linux KDE + Thinkpad (desktop)

@alrra
Copy link
Contributor Author

alrra commented Jan 3, 2014

However, it seems like it changes the width of the text significantly. On HEAD, we are computing that dynamically (using canvas). Is there a way to ensure that what is computed matches?

Maybe I'm missing something (and I apologize for that), but isn't the font-size hard-coded into template.svg ?

Theoretically, geometricPrecision should ensure the text is rendered at the correct size, but the other way around, doesn't always happen.

From MDN:

In SVG, when text is scaled up or down, browsers calculate the final size of the text (which is the specified font size and the applied scale) and request a font of that computed size from the platform's font system. But if you request a font size of, say, 9 with a scale of 140%, the resulting font size of 12.6 doesn't explicitly exist in the font system, so the browser rounds the font size to 12 instead. This results in stair-step scaling of text.

But the geometricPrecision property—when fully supported by the rendering engine—lets you scale your text fluidly. For large scale factors, you might see less-than-beautiful text rendering, but the size is what you would expect—neither rounded up nor down to the nearest font size supported by Windows or Linux.

WebKit precisely applies the specified value, but Gecko treats the value the same as optimizeLegibility.

Note the weird space between "w" and "hiz" in "whiz", and in other places.

Can you specify the browser / OS / device ? I didn't see this exact behavior in any of the browser I've tested in.

Firefox + Linux KDE + Thinkpad (desktop)

Ok, thanks.

Updated my previous comment to include screenshots for Ubuntu (it seems, for this OS, Firefox also doesn't have any problems).

@espadrine @mathiasbynens just a heads-up (if you haven't notice already): <filter> doesn't work for most of the default Android browsers (personally, don't think this is a major issue, but I thought it would be best to point it out).

@espadrine
Copy link
Member

Maybe I'm missing something (and I apologize for that), but isn't the font-size hard-coded into template.svg ?

Yes, that's correct. However, I am talking about the width of the text used, not the height. For instance, "dependencies" is something like thrice as wide as "build".

@espadrine @mathiasbynens just a heads-up (if you haven't notice already): doesn't work for most of the default Android browsers (personally, don't think this is a major issue, but I thought it would be best to point it out).

Good to know!
So, that's also why it isn't blurry… All the better. Android updates are rarer than Chrome updates.

@alrra
Copy link
Contributor Author

alrra commented Jan 3, 2014

However, I am talking about the width of the text used, not the height.

Ok, I now understand what you where referring to.

On HEAD, we are computing that dynamically (using canvas). Is there a way to ensure that what is computed matches?

Don't think so.

Do note that: the result of node-canvas's measureText(text).width differs significantly from want browsers report. So, even now, you're not getting the same values as what you would get in browsers. Plus, to make things worse, different browsers report different values!

  • e.g.: for the text dependencies, using this test page:

    OS Browser Value
    Android 4.1.2 Chrome 62.3388671875
    Default Browser 62.3388671875
    Firefox 61.96666717529297
    Mac OS X Chrome 67
    Firefox 68.3499984741211
    Opera 68.33984375
    Safari 68.33984375
    Windows 7 Chrome 77
    Firefox 77
    IE 10 68

    The value returned by the code from this repository is: 78.33984375 (run on Mac OS X).

@espadrine
Copy link
Member

A 10px difference is much bigger than I expected. I guess I didn't see it because both Firefox and node-canvas use the Cairo library as their backend.

I'm back to the drawing board. Might there be a way in SVG to force the rectangle to be of the size of a specified text?

@espadrine
Copy link
Member

Closing because this repo is no longer the main one.

@espadrine espadrine closed this Feb 23, 2014
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants