Displaying custom fonts in SVG for iOS Chrome and Safari - ios
I'm using an svg with custom fonts from google, but i'm hosting it myself. Here's the SVG file with the following code:
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" width="430" height="590">
<defs>
<style type="text/css"><![CDATA[
#font-face {
font-family: 'Fjalla';
src: url('http://build-podcast.com/fonts/fjalla.eot');
src: url('http://build-podcast.com/fonts/fjalla.eot?#iefix') format('embedded-opentype'),
url('http://build-podcast.com/fonts/fjalla.woff') format('woff'),
url('http://build-podcast.com/fonts/fjalla.ttf') format('truetype'),
url('http://build-podcast.com/fonts/fjalla.svg#fjalla') format('svg');
font-weight: normal;
font-style: normal;
}
text { font-family: Fjalla, sans-serif; font-weight: bold; fill: #4b5568; }
]]>
</style>
</defs>
<g id="logo">
<text x="135" y="60" font-size="210" transform="rotate(45)">/</text>
<text x="115" y="363" font-size="210" transform="rotate(-45)">\</text>
<text x="15" y="341" font-size="200">build</text>
<text x="15" y="475" font-size="127">podcast</text>
<text x="21" y="540" font-size="36">screencasts on tech tools</text>
</g>
</svg>
I'm using the img tag to display it on the main website
<img src="logo.svg">
It is displaying fine on desktop browsers and even on mobile browsers like Android Chrome. But it is not displaying at all in iOS 7 Chrome or Android. Any clue to how I can amend the SVG file code for the part on the custom fonts? Thanks!
I got fed up with trying to make the fonts to properly work in my SVG across all devices/browsers, so with my work around it helped that I have access to the original .ai file (.eps is fine).
My steps included:
- Open the original vector file in Adobe Illustrator.
- Select your text layers. Hold shift when selecting more than one. I find it easier do select multi layers through the Layers panel, which you can find in Menu under Window.
- Then, go to menu option Type and select Create Outlines.
This way we do not have to rely on calling fonts because your text is now just a vector shape. Now all that is left is to save your SVG:
- Select all your vectors.
- Go to menu option Object and select Artboards > Fit to Selected Art.
- Now go to File and select Export Selection....
- A Export for Screens dialog should pop up. On left side above .your Asset(s), click on the Artboards tab above
- On the right side, choose where you want to save.
- IMPORTANT STEP: select your format as *SVG.
- Lastly, click Export Artboard at bottom right.
That's all there is too it, and everything will appear exactly as it should across all devices and browsers!
We recently had the same problem having custom fonts displaying in SVG images. Before implementing this fix, the text would not show up in iOS on certain devices. After A LOT of debugging and trying different ways to solve it, we ended up with a CSS Font Fallback solution. This was the only way for us to solve the same problem as you describe.
Here is how we implemented it:
First we extracted the shapes of the characters using Adobe Illustrator like this:
<font horiz-adv-x="2048">
<font-face font-family="RobotoCondensed-Light" units-per-em="2048" underline-position="-150" underline-thickness="100"/>
<missing-glyph horiz-adv-x="434"/>
<glyph unicode=" " horiz-adv-x="434"/>
<glyph unicode=""" horiz-adv-x="549" d="M217,1341l-36,-261l-68,0l2,254l0,226l102,0M442,1341l-36,-261l-68,0l2,258l0,222l102,0z"/>
<glyph unicode="," horiz-adv-x="346" d="M246,19l-100,-277l-77,0l56,280l0,168l121,0z"/>
<glyph unicode="-" horiz-adv-x="497" d="M445,568l-399,0l0,104l399,0z"/>
<glyph unicode="." horiz-adv-x="440" d="M276,0l-130,0l0,166l130,0z"/>
<glyph unicode="0" horiz-adv-x="978" d="M867,564C867,376 834,232 767,131C700,30 607,-21 490,-21C372,-21 279,30 212,131C144,232 110,377 110,564l0,326C110,1077 144,1221 211,1324C278,1426 370,1477 488,1477C606,1477 699,1426 766,1324C833,1222 867,1077 867,890M747,911C747,1059 725,1173 681,1252C636,1331 572,1371 488,1371C405,1371 341,1331 297,1252C253,1172 231,1058 231,911l0,-366C231,398 253,285 298,204C343,123 407,83 490,83C573,83 637,123 681,204C725,284 747,398 747,545z"/>
<!-- ...... Complete characterset ...... -->
</font>
Then we defined the font using CSS:
<defs>
<style type="text/css">
<![CDATA[
#font-face {
font-family: 'RobotoCondensed-Light-Fallback';
font-style: normal;
font-weight: 300;
src: url(data:application/x-font-woff;charset=utf-8;base64,d09GRg............7yEuAS1Fmtsgn2C3mGC7pcSzGaItVzpDHKXKRoB2nd8b5m1ni67q0DVvtWpxe61sF59tcm+qiK+1YY21P2oWNdkPaA1Nv0meNl0KL0HwqtAmtRKFDaA9/APTVpT1K/YclSp7tiAGxtzbsEoOZYV9u9g8VM0kokz6M/klEI+HecECMVpoFhuIDsL5bmwAAAVSQKFMAAA==) format('woff');
}
]]>
</style>
</defs>
The magic happened once we named the font "RobotoCondensed-Light-Fallback" and then:
<text style="font-family:RobotoCondensed-Light,RobotoCondensed-Light-Fallback,Arial,sans-serif; font-weight: 300" font-size="36">Text</text>
What happens is that iOS uses <font-face> while all other browsers use the fallback font.
Hope this helps!
For your info, we used this definition in the SVG.
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" width="270px" height="303px" viewBox="0 0 270 303" enable-background="new 0 0 270 303" preserveAspectRatio="xMidYMid meet" xml:space="preserve">
FWIW, it's likely that a Tiny PNG-optimised PNG at double-resolution will be waaay smaller than a text-heavy SVG with text converted to curves.
I was getting around 400k for an outlined SVG with about 50 labels of 2 - 6 words, but exported to PNG, ran it through Tiny PNG and got 70k.
So if you just need something for retina screens, consider the PNG route:
https://tinypng.com/
https://www.npmjs.com/package/tinypng-cli
Related
How to make gradient in a line graph?
I want to fill my line graph with a gradient, I use this configuration, but with the option styledMode= true it does not work. I am using Hightcharts 9.0 https://jsfiddle.net/yjqcz42n/92/
As you can read in the docs: When the chart.styledMode option is true, no presentational attributes (like fill, stroke, font styles etc.) are applied to the chart SVG. Instead, the design is applied purely by CSS. It means you need to style series using their CSS classes. Recommended solution: Due to the difficulty of styling gradients for the SVGs, there is a Highcharts guide doc, on how to configure Gradients, shadows, and pattern fills in styled mode https://www.highcharts.com/docs/chart-design-and-style/gradients-shadows-and-patterns#gradients-shadows-and-pattern-fills-in-styled-mode Alternative solution: HTML <svg width="0" height="0" version="1.1" xmlns="http://www.w3.org/2000/svg"> <style type="text/css"> rect{fill:url(#MyGradient)} </style> <defs> <linearGradient id="MyGradient"> <stop offset="5%" stop-color="#F60" /> <stop offset="95%" stop-color="#FF6" /> </linearGradient> </defs> </svg> CSS: .highcharts-series-0 { fill: url(#MyGradient); stroke: url(#MyGradient); } Demo: https://jsfiddle.net/BlackLabel/15rmcfyd/
How to use fontello icons with transparency on iOS
I've a problem with custom font icons generated from svg using fontello. On PC, icons works fine, but on iOS browsers I haven't transparency. All source svg contains fill-rule: evenodd. I can't find solution for my problem, if You know how solve this issue, please help. On PC custom fontello icons works fine, but on iOS I've a problem. I'm not sure if the Android works well, but iOS has a higher priority. <svg xmlns="http://www.w3.org/2000/svg" width="72" height="72" viewBox="0 0 72 72"> <defs> <style> .cls-1 { fill-rule: evenodd; } </style> </defs> <path class="cls-1" d="M0,20V33l2,5,2,4,4,4,3,3,6,3,3,1H33l3-1,6-3,1-2h2v1l1,4L66,72h1l5-5V66L52,46l-2-1-2-1V43l2-3,1-1,1-3,1-3V20l-2-5-2-4L45,7,40,3,38,2,33,0H20L15,2,10,5,7,8,5,10,3,13,1,17Zm16-9-3,3-3,4L9,21,8,27l1,6,2,4,4,4,3,2,2,1,5,1h4l4-1,4-2,4-3,2-4,2-6V25l-1-5-1-2-2-3-3-3-3-2L28,8,21,9l-3,1Z"/> </svg> Effect on Desktop (ok): https://ibb.co/9pfZFnf Effect on iOS (not ok): https://ibb.co/Y846vb0
Apparently it didn't get the css rules. Please try to use the css like this, although I'm not very sure this will work. <style type="text/css"> <![CDATA[ .cls-1 { fill-rule: evenodd; } ]]> </style> Alternatively you can reverse the second part of the d attribute (the hole) so that you don't need to use the fill-rule: evenodd; <svg xmlns="http://www.w3.org/2000/svg" width="72" height="72" viewBox="0 0 72 72"> <path class="cls-1" d="M0,20V33l2,5,2,4,4,4,3,3,6,3,3,1H33l3-1,6-3,1-2h2v1l1,4L66,72h1l5-5V66L52,46l-2-1-2-1V43l2-3,1-1,1-3,1-3V20l-2-5-2-4L45,7,40,3,38,2,33,0H20L15,2,10,5,7,8,5,10,3,13,1,17Z M18,10L21,9L28,8L35,10L38,12L41,15L43,18L44,20L45,25L45,29L43,35L41,39L37,42L33,44L29,45L25,45L20,44L18,43L15,41L11,37L9,33L8,27L9,21L10,18L13,14L16,11z"/> </svg>
Delphi TWebBrowser window.devicePixelRatio property
in our app we use the TWebBrowser component of Delphi to display web content. Now we have a problem if windows has scaled monitors, for example 125% scale. In this case some HTML-controls aren't rendert correctly, because the window.devicePixelRatio property in JavaScript isn't updated but stays on 1, althougt it should be 1.25 on a 125% scaled monitor. Is there any posibillity to fix this issue? From inside JavaScript it is not possible to changes this value, but maybe from the Delphi side? Edit: I tried out an embedded chromium and there it works fine. But currently it is not possible to move from ie to chromium. A sample HTML: <!DOCTYPE html> <html> <body> <div style="width: 100px; height: 25px; border: 1px solid black; border-radius: 4px; overflow: hidden"> <span style="font-size:10pt; white-space: pre">Long sample text</span> </div> </body> </html> In Embedded IE the text ist cut of
Even though it is obsolete, you will find that enabling FEATURE_96DPI_PIXEL for your application will return the correct pixelratio: HKEY_LOCAL_MACHINE (or HKEY_CURRENT_USER) SOFTWARE Microsoft Internet Explorer Main FeatureControl FEATURE_96DPI_PIXEL yourapplication.exe = (DWORD) 00000001 The recommended way is to enable the DOCHOSTUIFLAG_DPI_AWARE flag.
How to save canvas as vector image?
I'm working on application for designing t-shirts on using fabricjs javascript library. T-shirt template(png) is positioned absolute to canvas. So when the canvas is rasterized to SVG, objects on canvas get saved. I'm currently storing SVG data on database for displaying purpose. When the process of designing t-shirt is completed, it needs to be saved as vector image so that while zooming, it persists it's original quality. How this can be done? Or how the system like this saves high quality images?
FabricJS's canvas.toSVG is a very nice feature that takes the drawing commands that created your canvas content and converts them into a fully formed svg element. For example, this code creates green rectangle on the canvas and then uses canvas.toSVG to convert it into a fully formed svg element. canvas.add(new fabric.Rect({ left: 50, top: 50, height: 20, width: 20, fill: 'green' })); console.log(canvas.toSVG()); This is what the resulting svg element looks like: <?xml version="1.0" standalone="no" ?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="800" height="700" xml:space="preserve"><desc>Created with Fabric.js 0.9.21</desc><rect x="-10" y="-10" rx="0" ry="0" width="20" height="20" style="stroke: none; stroke-width: 1; stroke-dasharray: ; fill: green; opacity: 1;" transform="translate(50 50)" /></svg> </body> As an SVG element, it can be scaled by the client with little loss of clarity. Since FabricJS gives you a fully formed svg element, all you have to do is tell your server to include that svg element in the DOM of the webpage being served to the client. It's literally as simple as this (this SVG rectangle scales with little loss of clarity). <!doctype html> <html> <body> <!-- This is the exact SVG produced by canvas.toSVG and which was saved in your DB --> <?xml version="1.0" standalone="no" ?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd"><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="800" height="700" xml:space="preserve"><desc>Created with Fabric.js 0.9.21</desc><rect x="-10" y="-10" rx="0" ry="0" width="20" height="20" style="stroke: none; stroke-width: 1; stroke-dasharray: ; fill: green; opacity: 1;" transform="translate(50 50)" /></svg> </body> </html>
Windows Phone set font-size for Thai in css
I have to show Thai and Roman text in a WebView (with NavigateToString). In CSS I've defined the font-sizes for Roman as 1.0em and for Thai as 1.8em. But Thai is displayed very small, smaller than Roman. If I set the font-size for Thai to 8em, then the result is about I want to have. OK, I can set the font-size to 8.0. But if this wrong behavior an bug in the OS, and Microsoft correct it in the next version, then my customers will have Thai script in 800% that fills up the screen. Is this a bug in the OS? Or am I missing something obvious? Edit: this is the generated html <html> <head> <title>ClickThai</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <style type="text/css"> <!-- .Text { font-size: 1.0em} .News { font-size: 1.0em; font-weight: bold; color: #333333} .ThaiText { font-size: 2.0em; line-height: 2.2em;} .TTiT { font-size: 1.0em; line-height: 1.3em;} .Tones { font-size:80%; position:relative; bottom: 0.1em; letter-spacing: -0.15em; color: #FF0000;} .Tonex { font-size:80%; position:relative; bottom: 0.1em; letter-spacing: -0.15em; color: #00FF00;} .NoWrap { white-space:nowrap;} --> </style> </head> <body bgcolor="#FFFFFF" text="#000000"> <table width="100%" border="0" cellspacing="0" cellpadding="2"> <tr> <td bgcolor="#00FF00"> <p class="ThaiText">ไก่</p> </td> </tr> </table> <p class="News">Transcription</p> Description </body> </html> It works on Internet Explorer and other browsers. Not in WebView on Windows Phone.
now I have found out that the problem is elsewhere. My Thai text will be displayed in a table (just to colorize the background). And there lies the problem: the class definition in tables does not work as expected. This also applies to Roman text. The text size is about 25% of the defined value. Outside tables everything is in order.
Because my app is an universal app I have added my code to the Windows 8.1 area. There the size specifications are correctly rendered. Conclusion: The code is error-free, but there is a bug in Windows Phone 8.1 when rendering the css font sizes within html tables.