Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
427 views
in Technique[技术] by (71.8m points)

html - Custom font not displaying in SVG pattern used as background-image

I'm working with an SVG pattern that uses a custom font, so as to use that pattern as a background image on an HTML page.

Everything renders fine in Chrome and Safari but it starts to get funny in Firefox:

  • Firefox renders the SVG along with the custom font text just fine when I open the SVG file itself (so far so good!);
  • However, Firefox does NOT render the custom font anymore when that same SVG file is used as the background to an HTML element (!)

I've spent hours trying to isolate the issue and a fresh pair of eyes would be welcome.

Here's what I've got in short:

CSS:

@import url(http://fonts.googleapis.com/css?family=Indie+Flower);

body {
    background: url(pattern-google.svg);
}

SVG file:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" xmlns:xlink="http://www.w3.org/1999/xlink" height="200" width="200">
    <style type="text/css">@import url(http://fonts.googleapis.com/css?family=Indie+Flower);</style>
    <defs>
        <!-- Geometry -->
        <g>
            <rect id="square" x="0" y="0" width="200" height="200" />
        </g>

        <!-- Patterns with Text -->
        <pattern id="pattern" x="0" y="0" width="40" height="40" patternUnits="userSpaceOnUse" text-anchor="middle" font-size="20" font-family="Indie Flower, sans-serif" style="font-family: Indie Flower, sans-serif;">
            <rect x="00" y="00" width="40" height="40" fill="transparent" />
            <text x="00" y="00" fill="#777">S</text>
            <text x="40" y="00" fill="#777">S</text>
            <text x="20" y="20" fill="#777">S</text>
            <text x="00" y="40" fill="#777">S</text>
            <text x="40" y="40" fill="#777">S</text>
        </pattern>
    </defs>

    <!-- Graphics -->
    <use xlink:href="#square" transform="translate(0, 0)" fill="url(#pattern)"/>
</svg>

The HTML itself does not really matter but I've linked it below. I did not produce a jsfiddle in the end because I could not host the SVG file there.

(Outside of the demo, the real-world application here is that I want to use a custom font to display phonetic symbols. (As background image, to help people learn them.) Doing so in SVG saves me the hassle to export to bitmap anytime I make a change in design.)

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You are using SVG in an image context. I.e. either via the html <img> tag, the SVG <image> tag or in your case as a background image.

In Firefox (and likely in other UAs at some point) images must consist of a single file only. Any data external to the image file (pattern-google.svg) is ignored. If you display the SVG directly then external data is loaded/used.

So what can you do...

Load the data as a data URI. I.e. base64 encode http://fonts.googleapis.com/css?family=Indie+Flower but read the final paragraph before you do this and then stick that data directly in the svg file itself.

So the import would look like this...

@import url('data:text/css;base64,whatever the base 64 encoded data looks like...')

Do be careful though because http://fonts.googleapis.com/css?family=Indie+Flower itself has external data so that data itself must itself be encoded as a data URI. I.e. you must go all the way down the rabbit hole. And change that file as I've sketched out below.

@font-face {
  font-family: 'Indie Flower';
  font-style: normal;
  font-weight: 400;
  src: local('Indie Flower'), local('IndieFlower'), url(**convert this file to a data URI too before you convert the whole file to a data URI**) format('woff');
}

Once you've done that you can then encode the whole file as a data URI and @import it.

So, to reiterate step by step...

  1. Convert http://themes.googleusercontent.com/static/fonts/indieflower/v5/10JVD_humAd5zP2yrFqw6nhCUOGz7vYGh680lGh-uXM.woff to a data URI
  2. Replace http://fonts.googleapis.com/css?family=Indie+Flower with a version that has the data URI from step 1
  3. Convert the file in step 2 to a data URI
  4. @import the data URI from step 3

There are plenty of sites online that will create data URIs.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...