Cannot load font 'Press Start 2P' in SVG - svg

I have the following svg I need to render in as a standalone svg file:
<svg width="89" height="55" viewBox="0 0 89 55" fill="none" xmlns="http://www.w3.org/2000/svg">
<style>
#font-face {
font-family: 'Press Start 2P';
src: url('https://fonts.googleapis.com/css?family=Press+Start+2P');
}
</style>
<rect width="89" height="55" fill="black" />
<rect x="5.5" y="5.5" width="78" height="44" fill="#0000FF" />
<text text-anchor="middle" x="44.5" y="31" fill=" white" font-family="Press Start 2P" font-size="12" letter-spacing="0em">1234</text>
<rect x="78" y="45" width="9" height="8" fill="#FF4F0A" />
<rect x="5.5" y="5.5" width="78" height="44" stroke="#FF4F0A" stroke-width="3" />
<path d="M81.4286 51V50.4286H81V49.8571H81.8571V50.4286H83.1429V49.2857H81.4286V48.7143H81V47.5714H81.4286V47H83.5714V47.5714H84V48.1429H83.1429V47.5714H81.8571V48.7143H83.5714V49.2857H84V50.4286H83.5714V51H81.4286Z" fill="#0000FF" />
</svg>
I am trying to use a given font (Press Start 2P) but it does not render, neither locally when I open the svg file nor with the following data uri
data:image/svg+xml,%3Csvg%20width%3D%2289%22%20height%3D%2255%22%20viewBox%3D%220%200%2089%2055%22%20fill%3D%22none%22%20xmlns%3D%22http%3A//www.w3.org/2000/svg%22%3E%20%20%20%20%3Cstyle%3E%20%20%20%20%40font-face%20%7B%20%20%20%20%20%20%20%20font-family%3A%20%27Press%20Start%202P%27%3B%20%20%20%20%20%20%20%20src%3A%20url%28%27https%3A//fonts.googleapis.com/css%3Ffamily%3DPress%2BStart%2B2P%27%29%3B%20%20%20%20%7D%20%20%20%20%3C/style%3E%20%20%20%20%3Crect%20width%3D%2289%22%20height%3D%2255%22%20fill%3D%22black%22%20/%3E%20%20%20%20%3Crect%20x%3D%225.5%22%20y%3D%225.5%22%20width%3D%2278%22%20height%3D%2244%22%20fill%3D%22%230000FF%22%20/%3E%20%20%20%20%3Ctext%20text-anchor%3D%22middle%22%20x%3D%2244.5%22%20y%3D%2231%22%20fill%3D%22%20white%22%20font-family%3D%22Press%20Start%202P%22%20font-size%3D%2212%22%20letter-spacing%3D%220em%22%3E1234%3C/text%3E%20%20%20%20%3Crect%20x%3D%2278%22%20y%3D%2245%22%20width%3D%229%22%20height%3D%228%22%20fill%3D%22%23FF4F0A%22%20/%3E%20%20%20%20%3Crect%20x%3D%225.5%22%20y%3D%225.5%22%20width%3D%2278%22%20height%3D%2244%22%20stroke%3D%22%23FF4F0A%22%20stroke-width%3D%223%22%20/%3E%20%20%20%20%3Cpath%20d%3D%22M81.4286%2051V50.4286H81V49.8571H81.8571V50.4286H83.1429V49.2857H81.4286V48.7143H81V47.5714H81.4286V47H83.5714V47.5714H84V48.1429H83.1429V47.5714H81.8571V48.7143H83.5714V49.2857H84V50.4286H83.5714V51H81.4286Z%22%20fill%3D%22%230000FF%22%20/%3E%3C/svg%3E
EDIT
After comment, I tried to embed the whole font but still does not work
<svg width="89" height="55" viewBox="0 0 89 55" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
#font-face {
font-family: "Press Start 2P";
src: url(data:application/font-woff;charset=utf-8;base64,..) format("woff");
font-weight:normal;font-style:normal;
}
</style>
</defs>
<rect width="89" height="55" fill="#E5E5E5" />
<rect width="89" height="55" fill="#29296E" />
<rect x="5.5" y="5.5" width="78" height="44" fill="#0000FF" />
<text text-anchor="middle" x="44.5" y="31" fill=" white" font-family="Press Start 2P" font-size="12">
{}azer
</text>
<rect x="5.5" y="5.5" width="78" height="44" stroke="#FF4F0A" stroke-width="3" />
<rect x="47" y="45" width="41" height="8" fill="#FF4F0A" />
<text text-anchor="end" x="86" y="52" fill=" white" font-family="Press Start 2P" font-size="8" letter-spacing="0em">
{}
</text>
</svg>
the base64 comes from the base64 encoding of the .ttf file

Your first example doesn't work since you're using a css URL as a font file URL.
Open your google font URL and copy the actual #font-face rule
The returned css depends on your current browser – yeah, user agent sniffing!
#font-face {
font-family: 'Press Start 2P';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/pressstart2p/v14/e3t4euO8T-267oIAQAu6jDQyK3nVivM.woff2) format('woff2');
}
Otherwise use a service like google web fonts helper to get the actual font file URLs.
False friends: css properties vs. svg attributes
Svg's font related attributes like font-family apparently don't work well with css style definitions.
Better apply font-family within the <style> element like so:
<svg viewBox="0 0 89 55" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
#font-face {
font-family: 'Press Start 2P';
font-style: normal;
font-weight: 400;
src: url(https://fonts.gstatic.com/s/pressstart2p/v14/e3t4euO8T-267oIAQAu6jDQyK3nVivM.woff2) format('woff2');
}
text {
font-family: 'Press Start 2P';
font-size: 12;
}
</style>
</defs>
<rect width="89" height="55" fill="black" />
<rect x="5.5" y="5.5" width="78" height="44" fill="#0000FF" />
<text text-anchor="middle" x="44.5" y="31" fill=" white">1234</text>
<rect x="78" y="45" width="9" height="8" fill="#FF4F0A" />
<rect x="5.5" y="5.5" width="78" height="44" stroke="#FF4F0A" stroke-width="3" />
</svg>
Embedded fonts
Some services provide a way to generate/convert font files to base64 data URLs like transfonter
Embedded font example
<svg viewBox="0 0 89 55" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
#font-face {
font-family: 'Press Start 2P';
font-style: normal;
font-weight: 400;
src: url('data:font/woff2;charset=utf-8;base64,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') format('woff2');
font-weight: normal;
font-style: normal;
}
text {
font-family: 'Press Start 2P';
font-size: 12;
}
</style>
</defs>
<rect width="89" height="55" fill="black" />
<rect x="5.5" y="5.5" width="78" height="44" fill="#0000FF" />
<text text-anchor="middle" x="44.5" y="31" fill=" white">1234</text>
<rect x="78" y="45" width="9" height="8" fill="#FF4F0A" />
<rect x="5.5" y="5.5" width="78" height="44" stroke="#FF4F0A" stroke-width="3" />
</svg>
If your svg only uses google webfonts, you can also try vecta's nano optimiser – it can retrieve these fonts and include them as font subsets ( including only needed characters/glyphs).

Related

What's the difference between Dominant-baseline and Alignment-baseline?

I've googled but got this:
https://codepen.io/felipe_matos/pen/pMrXpK
html, body, svg {
height: 200px;
}
text {
font: bold 8px Verdana, Helvetica, Arial, sans-serif;
}
.flex {
display: flex;
}
<!-- Learn about this code on MDN: https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/dominant-baseline -->
<div class="flex">
<div>
<h2>Dominant-baseline</h2>
<svg viewBox="0 0 200 120" xmlns="http://www.w3.org/2000/svg">
<path d="M20,15 L180,15 M20,30 L180,30 M20,45 L180,45 M20,60 L180,60 M20,75 L180,75 M20,90 L180,90" stroke="grey" />
<text dominant-baseline="ideographic" x="30" y="30">Ideographic</text>
<text dominant-baseline="baseline" x="30" y="45">Baseline</text>
<text dominant-baseline="middle" x="30" y="60">Middle</text>
<text dominant-baseline="hanging" x="30" y="75">Hanging</text>
<text dominant-baseline="text-before-edge" x="30" y="90">text-before-edge</text>
<text dominant-baseline="text-after-edge" x="30" y="15">text-after-edge</text>
</svg>
</div>
<div>
<h2>Alignment-baseline</h2>
<svg viewBox="0 0 200 120" xmlns="http://www.w3.org/2000/svg">
<path d="M20,15 L180,15 M20,30 L180,30 M20,45 L180,45 M20,60 L180,60 M20,75 L180,75 M20,90 L180,90" stroke="grey" />
<text alignment-baseline="ideographic" x="30" y="30">Ideographic</text>
<text alignment-baseline="baseline" x="30" y="45">Baseline</text>
<text alignment-baseline="middle" x="30" y="60">Middle</text>
<text alignment-baseline="hanging" x="30" y="75">Hanging</text>
<text alignment-baseline="text-before-edge" x="30" y="90">text-before-edge</text>
<text alignment-baseline="text-after-edge" x="30" y="15">text-after-edge</text>
</svg>
</div>
</div>
it seems the two properties are exactly the same. Then why do we have two different types?
The distinction is that dominant-baseline is the baseline used to calculate the baseline table. Specifically the distinction will be found when you mix different fonts, for example, if you are using a roman font like English and quote something in an Indic Script, "অসমীয়া লিপিবাংলা লিপি". The baseline in the script is visible there, but it's different than the English baseline. Though in practice it tends to do the same thing probably because the distinction is pretty minor and involves building an adjustment table first vs. adjusting for the baseline.

How to create an SVG icon consisting of two overlapping shapes, one with a hole?

I have made a progress bar icon from two partially overlapping SVG shapes.
I would like the icon to have the same color as the surrounding text, so I set stroke and fill to currentColor.
The icon is displayed correctly if the color of the surrounding text doesn't have alpha channel e.g. color: black. However, if the color of the surrounding text has alpha channel e.g. color: rgba (0, 0, 0, 0.7), then the icon is darker where the shapes overlap.
How can I get the same color at each point of the icon?
body { background-color: #eee; color: rgba(0, 0, 0, 0.7); }
<svg viewBox="0 0 44 18" width="220" height="90">
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="currentColor" stroke-width="2" fill="transparent" />
<rect x="2" y="2.5" width="24" height="10" fill="currentColor" />
</svg>
Question Prevent overlapping figures with alpha channel from shading each other? is very similar, but the accepted answer doesn't work in this case:
body { background-color: #eee; color: rgba(0, 0, 0, 0.7); }
<svg viewBox="0 0 44 18" width="220" height="90">
<defs>
<clipPath id="myClip">
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="black" stroke-width="2" fill="transparent" />
<rect x="2" y="2.5" width="24" height="10" />
</clipPath>
</defs>
<rect width="100%" height="100%" fill="currentColor" clip-path="url(#myClip)"/>
</svg>
Update:
I decided to draw the icon without overlapping parts, because it is much easier and it also looks good:
body { background-color: #eee; color: rgba(0, 0, 0, 0.7); }
<svg viewBox="0 0 44 18" width="220" height="90">
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="currentColor" stroke-width="2" fill="transparent" />
<rect x="4" y="4" width="23" height="7" rx="2" ry="2" fill="currentColor" />
</svg>
One solution is to user a mask. But if you don't change the geometry, you will get the same issue as with #InvisibleGorilla's solution: you will get antialiasing artifacts.
body { background-color: #eee; color: rgba(0, 0, 0, 0.7); }
<svg viewBox="0 0 44 18" width="220" height="90">
<defs>
<mask id="cutout">
<rect width="100%" height="100%" fill="white" />
<use xlink:href="#bar" fill="black" />
</mask>
<rect id="bar" x="2" y="2.5" width="24" height="10" />
</defs>
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="currentColor" stroke-width="2" fill="transparent"
mask="url(#cutout)" />
<use xlink:href="#bar" fill="currentColor" />
</svg>
To fix the antialiasing artifacts, move your bar so that it is positioned at a whole pixel (y="2") instead of a half pixel (y="2.5"). You still might still see very slight artifacts at some scales. But it should be a lot better.
body { background-color: #eee; color: rgba(0, 0, 0, 0.7); }
<svg viewBox="0 0 44 18" width="220" height="90">
<defs>
<mask id="cutout">
<rect width="100%" height="100%" fill="white" />
<use xlink:href="#bar" fill="black" />
</mask>
<rect id="bar" x="2" y="2" width="24" height="10" />
</defs>
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="currentColor" stroke-width="2" fill="transparent"
mask="url(#cutout)" />
<use xlink:href="#bar" fill="currentColor" />
</svg>
Before the rect where fill has currentColor, add a rect with the exact same attributes but with a white fill directly before it (so that it gets drawn underneath it in the svg).
See snipped below:
<style>
body { background-color: #eee; color: rgba(0, 0, 0, 0.7); }
</style>
<svg viewBox="0 0 44 18" width="220" height="90">
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="currentColor" stroke-width="2" fill="transparent" />
<rect x="2" y="2.5" width="24" height="10" fill="white" />
<rect x="2" y="2.5" width="24" height="10" fill="currentColor" />
</svg>
You could also change the order of your rects and add a matching white rect under the one where the stroke has currentColor.
Here's the updated snippet using background color and underlying both rects. I've tested on Chrome and Firefox on Mac and I don't see any lines from the background color rects.
<style>
body { background-color: #232b32; color: rgba(240, 240, 240, 0.7); }
</style>
<svg viewBox="0 0 44 18" width="220" height="90">
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="#232b32" stroke-width="2" fill="transparent" />
<rect x="2" y="2" width="40" height="11" rx="3" ry="3"
stroke="currentColor" stroke-width="2" fill="transparent" />
<rect x="2" y="2.5" width="24" height="10" fill="#232b32" />
<rect x="2" y="2.5" width="24" height="10" fill="currentColor" />
</svg>
<p>Some text</p>
Here's a screenshot of when I run this snippet.

SVG Horizontal lines too big

I tried to draw a shape using html/svg. It is a volume control, see below
<svg height="20" width="90" style="background-color: #ccc;">
<g>
<rect x="10" y="0" width="80" height="20" style="stroke: #000; stroke-width: 1; fill: #fff;"></rect>
<!-- Example two of four -->
<polygon points="10,20 50,10 50,20" style="fill: rgba(128,128,128,128)"></polygon>
<line x1="30" y1="0" x2="30" y2="20" style="stroke: #000; stroke-width: 1;"></line>
<line x1="50" y1="0" x2="50" y2="20" style="stroke: #000; stroke-width: 1;"></line>
<line x1="70" y1="0" x2="70" y2="20" style="stroke: #000; stroke-width: 1;"></line>
</g>
</svg>
All browsers draw the horzontal lines double width, except the last one. I even added "stroke-width: 1", but that doesn't work.
I guess anti-aliasing? How can I fix this?

How to apply svg pattern to different rectangles using objectBoundingBox coordinate system and keep aspect ratio?

I.e. in this code the pattern applied with gap between the tiles or overlaping.
<svg width="400" height="400">
<defs>
<pattern id="pattern1"
x="0" y="0" width="0.1" height="0.2"
patternUnits="objectBoundingBox"
>
<circle cx="10" cy="10" r="10" style="stroke: none; fill: #0000ff" />
</pattern>
</defs>
<rect x="10" y="10" width="170" height="100"
style="stroke: #000000; fill: url(#pattern1);" />
<rect x="10" y="110" width="235" height="100"
style="stroke: #000000; fill: url(#pattern1);" />
</svg>
How to do that tiles were placed side by side and the last tile which is not fit in rectangle will be sliced?
You can't do what you want with objectBoundingBox units. You need to use patternUnits="userSpaceOnUse".
<svg width="400" height="400">
<defs>
<pattern id="pattern1" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<circle cx="10" cy="10" r="10" style="stroke: none; fill: #0000ff" />
</pattern>
</defs>
<rect x="10" y="10" width="170" height="100"
style="stroke: #000000; fill: url(#pattern1);" />
<rect x="10" y="110" width="235" height="100"
style="stroke: #000000; fill: url(#pattern1);" />
</svg>
But, as you can see, the default pattern origin is at the origin of the SVG document (the top left). To change that so that the pattern is aligned with the rectangles, you'll need to define the rectangles at the origin and move them into position with a transform.
<svg width="400" height="400">
<defs>
<pattern id="pattern1" x="0" y="0" width="20" height="20" patternUnits="userSpaceOnUse">
<circle cx="10" cy="10" r="10" style="stroke: none; fill: #0000ff" />
</pattern>
</defs>
<rect x="0" y="0" width="170" height="100" transform="translate(10,10)"
style="stroke: #000000; fill: url(#pattern1);" />
<rect x="0" y="0" width="235" height="100" transform="translate(10,110)"
style="stroke: #000000; fill: url(#pattern1);" />
</svg>

How to properly use patternContentUnits="objectBoundingBox" for svg element?

I want to apply a pattern to a few svg elements, the pattern should apply from the (0,0) point for each element.
First I try code like this
<svg width="400" height="400">
<defs>
<pattern id="pattern1"
x="0" y="0" width="25" height="25"
patternUnits="userSpaceOnUse"
>
<circle cx="10" cy="10" r="10" style="stroke: none; fill: #0000ff" />
</pattern>
</defs>
<rect x="10" y="10" width="100" height="100"
style="stroke: #000000; fill: url(#pattern1);" />
<rect x="110" y="17" width="100" height="100"
style="stroke: #000000; fill: url(#pattern1);" />
<rect x="210" y="0" width="100" height="100"
style="stroke: #000000; fill: url(#pattern1);" />
<rect x="0" y="110" width="100" height="100"
style="stroke: #000000; fill: url(#pattern1);" />
</svg>
The issue in this example is that the pattern for each element starts from the (0,0) point of the svg document not of each element.
Ok, lets try (setting the patternUnits="objectBoundingBox" attribute to the pattern definition so that the coordinate system for the pattern starts from the (0,0) point of each element)[https://jsfiddle.net/gwrgd1wf/1/]
The Coordinate system start point is changed as I want it, but the pattern has stopped tiling and the width and height attribute of pattern stop working properly. You can see I set height="2", but it does not change the height of the pattern.
So my question is how to properly use the patternUnits="objectBoundingBox" attribute?
In objectBoundingBox units 1 unit is the size of the shape so if you write 2 that means the pattern is 2 times the size of the shape so 1/2 the pattern fills the shape and you get no tiling.
If you want tiling you'll need to make the pattern smaller than the shape e.g. with 0.2 you'll get 5 circles displayed. E.g.
<svg width="400" height="400">
<defs>
<pattern id="pattern1"
x="0" y="0" width="0.2" height="0.2"
patternUnits="objectBoundingBox"
>
<circle cx="10" cy="10" r="10" style="stroke: none; fill: #0000ff" />
</pattern>
</defs>
<rect x="10" y="10" width="100" height="100"
style="stroke: #000000; fill: url(#pattern1);" />
<rect x="110" y="17" width="100" height="100"
style="stroke: #000000; fill: url(#pattern1);" />
<rect x="210" y="0" width="100" height="100"
style="stroke: #000000; fill: url(#pattern1);" />
<rect x="0" y="110" width="100" height="100"
style="stroke: #000000; fill: url(#pattern1);" />
</svg>

Resources