d3plus / d3plus-text

A smart SVG text box with line wrapping and automatic font size scaling.
MIT License
105 stars 19 forks source link

add ability to selectively turn off fontExists caching as part of TextBox #99

Open stocksr opened 6 years ago

stocksr commented 6 years ago

Expected Behavior

When you call .font('my custom font') and that font is defined in a @font-face rule in css. Then the font should be downloaded and used.

Current Behavior

When you call .font('my custom font') and that font is defined in a @font-face rule in the css. Then provided some the browser has already finished downloading the font, it works correctly. If however that font is not yet available then the font is blacklisted for the duration of page. (I am writing a SPA so this could be a very long time.)

Steps to Reproduce (for bugs)

  1. Add this css @font-face { font-family: 'X-Custom'; src: url(http://fonts.gstatic.com/s/dancingscript/v9/If2RXTr6YS-zF4S-kcSWSVi_szLgiuQHiC4W.ttf) ; }
  2. Create a text box as usual including .font('X-Custom')
  3. Note that the font is not used.
  4. Now add a

    Sample to the page

  5. Create the SVG text on page load and note that the font does not get used.
  6. Delay the SVG text until the font is loaded and note that it does work.
davelandry commented 6 years ago

I actually just ran into this problem last week in another project! After a full day of searching, the only solution I could find was to convert the font file into base64 (using a converter like this) and declare it using that string. That's the only way to guarantee the font has been loaded into memory by the time the JavaScript runs. For example:

@font-face {
  font-family: 'Pathway Gothic One';
  font-style: normal;
  font-weight: 400;
  src: url(data:font/woff2;base64,d09GMgABAAAAAAQoAA4AAAAACEQAAAPVAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhYbfBwaBmAAVBEICoR8hBILGgABNgIkAzAEIAWEagc6G8cGIxEmfPGE7B8HOZm8uagEPN5l2TNZFMXroHIUN44cqYu2vv/r8TzvfuV9SWb3bwFZASpiYRiMq6ta5Xpq2QGrsvKToTxrUqymR89CTldICjLNAfQLZC8A/udyeqsxde3//FzbGLf96N55awMdxYmVjTFs4+TsuICKiBq2jUojY7k4wz0LZgGKqGaKYIY1dsmTm7QHDBo4Cd/ju1TfT+AzNQUxKDZo2OGwqtJ/Av0n/TuiaAbRjBRAxKSi3KtYYhlmLNRoM82I8qzIcD6vm2t2p4piNDHBpgls/42+ADgSbmaUp/2C+tL7dQTKKsYhrFNQULFIFbRocwSzDIqWiujTL0Myo3dyNLoWNvi18cngmuC04KRg/wh+ZaR3c8EssAxz8JoMAGjr+1UUVVFkDid1ZCgKDWexIkJ1I6SFDCkQMSCIqAVYMY40gjoG+/I6rNE4nJDcwYbfnXhbLLozAQzbvl28/vBPMOzWhDsS6e3bcKJGki6Wpoqkw4vWeAqJfP0LwfEWMAJTQLkSyjQYBDCO0kZgLYAKglkvpuRhCGQdo3bCNqBBRBl2K2JCnHQ1nLgzTPWnYsPvwomxojVlB3kZZFweGddxIf4m/XT+KVD2pJkXzOvq5oLggbEOi3gKskhePthGCMY3NoWaGlszh052ZzTeJYp2tutJ5OkEzVNIZVjvBg5TlFAbS/JPySlDU3VTNaWkwMd+hYurMpqyTPwqbh9uaQi/qgVL5yfxJdzUYRe2JDXXlg2srgtV1nCYOLNHGTdxWx+PidcjrxMqm9JGjLg+q1jD18Q1eBp9sHTLPfFFvCevvI/P+rGW45rt23atKfu9feeu3WVDpYM7vX3edUy9pnxv+dS+JZfyN2xsiW+f22VO/ZLsnGyyd2wgiKc7lkiWaFuVfBsg8yV8+3J6Nn7untfj//9+uM6vBzAoIDBaP0x9N4O8ZxGBZpZpd5yLmCaHwAJfes8UO2KyI33Mi9bS4Nb43/8LZvlhEhREcATA4J4qLRzwjxpik39QzDGG6lQ40OzNXAGwu2YMhGRk2bW0zMm1Sq+vP2W32mgkgTERkiVDpmwpkGpTbz1l8iKi3h6Pfa1tD532FUkPsb4rpaHtPm8aj5lOo6cQ8znl4HPkRCmQvnayDRGYA36qz67GSI3XQyOE3g2ZSDyefnX1vvr+bQtS62XajQh5n+1cytrbdet7ZEqTIUOWYqJ6Hll8RiJzsCKpMPM7iyHORWKmAnavB70iuzcnfkIDASNl99EBZgzYXSLeD7WmI2uaGAD67iwBNQuIU2z2+MnTZwefv1gDAAA=) format('woff2');
  unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
stocksr commented 6 years ago

Actually, i think there is a bug here in that it never rechecks the font, even if called again.

I could accept that the i initial load is incorrect, and simply call the text layouter again with a timeout if this happens. However once a font is not found it remains that way forever.

ABinaryGeek commented 5 years ago

As a note for anyone looking for a workaround where they need it to render and don't mind waiting, you can use webfontloader and start once the font is loaded. Obviously not ideal, but it does ensure the fonts get used every time.