show only specific glyphs using opentypejs - css

I am using opentype.js to extract glyphs from google font(Poppin). Currently It shows all the glyphs nicely. but i want only the character and numbers only. such as "A,B,C and 1,2,3 etc.
Is there any way to show only specific items from glyphs table?
thanks in advance

font.stringToGlyphs('ABC') or font.getPaths(chars, 0, 90, 100) would return only selected glyphs.
Use e.g font.stringToGlyphs() if you need to get glyph properties like sidebearings, unicode etc.
font.getPaths() will return path data (commands).
let preview = document.querySelector("#svgPreview");
let chars = "ABCD0123";
let output ='';
// opentype.js accepts woff, ttf and otf
let fontFile = "https://fonts.gstatic.com/s/poppins/v19/pxiByp8kv8JHgFVrLGT9Z1xlEw.woff";
opentype.load(fontFile, function (err, font) {
if (!err) {
//get glyphs as object
let glyphs = font.stringToGlyphs(chars);
console.log(glyphs)
//get glyphs pathdata for previewing
let paths = font.getPaths(chars, 0, 90, 100);
paths.forEach(function(path, i){
output +=path.toSVG(2)
});
preview.innerHTML = output;
let vb = preview.getBBox();
preview.setAttribute('viewBox',[0, 0, (vb.width+vb.x), 120].join(' ') )
console.log(paths);
} else {
console.log("Font could not be loaded: " + err);
}
});
<script src="https://cdn.jsdelivr.net/npm/opentype.js#latest/dist/opentype.min.js"></script>
<style>
svg{
border: 1px solid #ccc;
height:10em;
}
</style>
<svg id="svgPreview" viewBox="0 0 1000 100">
</svg>

Related

Why is my SVG file not using my font file?

I have this SVG file in the same directory as this font's TTF file.
<?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
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
version="1.1"
width="150"
height="100"
viewBox="0 0 150 100"
>
<style type="text/css">
#font-face {
font-family: "easyPrint";
src: url('./easy-print.regular.ttf');
}
</style>
<text
x="10"
y="30"
class="word"
font-family="easyPrint"
font-size="25"
>
TEST
</text>
<text
x="10"
y="80"
font-size="25"
>
TEST
</text>
</svg>
When I do this, I get two different fonts. The one that should be my custom font is the same font you see if you give it gibberish for a font-family. Which is different from the default.
I've tried with an OTF file as well. The specific font isn't important. I'm just trying to produce a bunch of SVG images of text with a specific font.
If you need your svg files to be perfectly self contained,
you should consider embedding the font-files as base64 resource (using a tool like transfonter):
1. Example: font embedded as base64
<p>This svg would always display the custom font (inlined svg, referenced in img element, opened directly in browser.)<br /> (Letter a is not contained in the reduced character subset)</p>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 100">
<style>
#font-face {
font-family: 'easyPrint';
src: url('data:font/woff2;charset=utf-8;base64,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') format('woff2');
font-weight: normal;
}
</style>
<text
x="10"
y="30"
class="word"
font-family="easyPrint"
font-size="25"
>
TESTa
</text>
</svg>
You can significantly reduce file size by subsetting your font:
Only selected characters will be available.
2. Example: Svg2Png
This approach requires the font to be inlined as dataURL.
Otherwise the png output will render a default font like Times.
function svg2Png(selector) {
const svgEl = document.querySelector(selector);
let svgVB = svgEl.getAttribute('viewBox');
let svgVBArr = svgVB ? svgVB.split(' ') : '';
let svgVBW = svgVBArr ? svgVBArr[2] : '';
let svgVBH = svgVBArr ? svgVBArr[3] : '';
let svgClientBB = svgEl.getBoundingClientRect();
let svgClientW = svgClientBB.width;
let svgClientH = svgClientBB.height;
let svgBB = svgEl.getBBox();
let svgW = svgVBW? svgVBW : svgBB.width;
svgW = svgClientW > svgW ? svgClientW : svgW;
let svgH = svgVBH? svgVBH : svgBB.height;
svgH = svgClientH > svgH ? svgClientH : svgH;
let blob = new Blob([svgEl.outerHTML], {type: 'image/svg+xml'});
let URL = window.URL;
let blobURL = URL.createObjectURL(blob);
let tmpImg = new Image();
tmpImg.src = blobURL;
tmpImg.width = svgClientW > svgW ? svgClientW : svgW;
tmpImg.height = svgClientH > svgH ? svgClientH : svgH;
tmpImg.onload = () => {
let canvas = document.createElement("canvas");
canvas.width = svgW;
canvas.height = svgH;
let context = canvas.getContext("2d");
// draw blob img to canvas with some delay
setTimeout(function () {
context.drawImage(tmpImg, 0, 0, svgW, svgH);
let pngDataUrl = canvas.toDataURL();
let svgImg = document.createElement("img");
svgImg.width = svgW;
svgImg.height = svgH;
svgImg.class = "svgImg";
svgImg.src = pngDataUrl;
// just additional wrapping for example usage
let imgWrp = document.createElement("div");
imgWrp.setAttribute("class", "img-wrp");
imgWrp.appendChild(svgImg);
document.body.appendChild(imgWrp);
}, 300);
};
}
svg,
img{
border:1px solid #ccc
}
.svg-wrp{
position:relative;
overflow:auto;
resize:both;
width:50%;
}
<div class="btn-wrp">
<button type="button" onclick="svg2Png('svg')">svg2Png</button>
</div>
<div class="svg-wrp">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 150 100">
<style>
#font-face {
font-family: 'easyPrint';
src: url('data:font/woff2;charset=utf-8;base64,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') format('woff2');
font-weight: normal;
}
</style>
<text
x="10"
y="30"
class="word"
font-family="easyPrint"
font-size="25"
>
TEST
</text>
</svg>
</div>
3. Example: create svg with text rendered as path
This example employs the awesome opentype.js library.
Opentype.js has a handy function font.getPath() allowing you to render string as a svg <path> element based on the before loaded font file.
let svgcontainer = document.querySelector('#svgcontainer');
let inputText = document.querySelector('#inputText');
// opentype.js accepts only ttf and otf
let fontFile = 'https://fonts.gstatic.com/s/firasans/v15/va9E4kDNxMZdWfMOD5Vvl4jO.ttf';
inputText.addEventListener('change', function(e) {
let testString = e.currentTarget.value;
let params = {
string: testString,
font: fontFile,
fontSize: 100,
x: 0,
y: 0,
decimals: 3
}
text2Path(params)
})
//default
let params = {
string: inputText.value,
font: fontFile,
fontSize: 100,
x: 0,
y: 0,
decimals: 3
}
text2Path(params)
function text2Path(params) {
opentype.load(params.font, function(err, font) {
if (!err) {
let options = params.options;
let path = font.getPath(params.string, params.x, params.fontSize, params.fontSize, options);
let textPath = path.toSVG(params.decimals);
let newSvg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
newSvg.classList.add('svgText');
newSvg.setAttribute('xmlns', "http://www.w3.org/2000/svg");
newSvg.insertAdjacentHTML('beforeend', textPath);
svgcontainer.appendChild(newSvg);
// adjust bbox
let bb = newSvg.getBBox();
newSvg.setAttribute('viewBox', '0 0 ' + (bb.width + bb.x) + ' ' + (params.fontSize * 1.5));
//add downloadbtn
let btnDownload = document.createElement("a");
btnDownload.setAttribute('download', 'font-' + params.string + '.svg');
btnDownload.textContent = 'Download';
let dataURl = getDataUrl(newSvg.outerHTML, 'image/svg+xml');
btnDownload.href = dataURl;
svgcontainer.appendChild(btnDownload)
} else {
console.log('Font could not be loaded: ' + err);
}
});
}
function getDataUrl(str, mime) {
let dataUrl = 'data:' + mime + ';base64,' + btoa(unescape(encodeURIComponent(str)))
return dataUrl;
}
.svgText {
height: 10em;
display: inline-block;
border: 1px solid #ccc;
}
a {
display: block
}
<script src="https://cdn.jsdelivr.net/npm/opentype.js#latest/dist/opentype.min.js"></script>
<div class="layout">
<div class="frm-wrp">
<input id="inputText" type="text" value="Test">
</div>
<div class="svgcontainer" id="svgcontainer"></div>
</div>
Alternative: convert text to path in graphic editor
This is probably the most convenient solution.
Make sure the desired font is installed locally (in you OS).
Open your svg in an graphic editor like inkscape.
select you <text> elements and convert them to paths:
inkscape: Path / Object to path
Adobe Illustrator: Type / Create Outlines

How to Format The WordPress Accordion Title into 2 sections

I am using the Divi Builder in WordPress to make a list of patents in the accordion format. However, I would like to format the accordion title (of each accordion element) so that on the left is the patent#, and on the right is the title of the patent.
To do this, I would like to know how I can split the title into 2 separate sections; 1 where I can put the title number, and the other where I can type the name of the patent. Sort of like this:
Another sketch to show what I want it to look like: sketch of the goal
Again I am using Divi Builder to do this as I am a novice using WordPress. But I am assuming I would have to write some custom CSS to format the title in this way in the Divi Builder.
First is it possible to do what I am trying to do?
If so how can I do this (in the Divi Builder environment)?
Unfortunately, not all of our requirements can be met by means of ready-made tools for building a website.
In such cases, we are forced to write "fixes" in such individual cases.
I offer you a js script that does the following:
Searches for titles with text that meets the following requirements:
Starts with #
After a hash without spaces, numbers
Example: #111
Wraps the found in the span with the class specified in the configuration (at the very top of the file)
I tested here
(function() {
// Config
let classFirstHeading = 'my-heading';
let headerSelector = '.et_pb_toggle_title'; // You can replace to your selector of heading
// end config;
var DOMReady = function(callback) {
if (document.readyState === "interactive" || document.readyState === "complete") {
callback();
} else if (document.addEventListener) {
document.addEventListener("DOMContentLoaded", callback);
} else if (document.attachEvent) {
document.attachEvent("onreadystatechange", function() {
if (document.readyState != "loading") {
callback();
}
});
}
}
function updateHeading() {
let headings = document.querySelectorAll(headerSelector);
headings.forEach(el => {
let textHeading = el.innerText;
let regexp = /^\#\d+/;
if(textHeading && regexp.test(textHeading.trim())) {
el.innerHTML = textHeading.replace(regexp, (match) => {
return '<span class="'+classFirstHeading+'">'+match+'</span> ';
});
}
});
}
window.updateHeading = updateHeading; // Give access from outside
DOMReady(() => {
updateHeading();
/* Test, you can remove this section */
let styleEl = document.createElement('style'); styleEl.type = 'text/css';
let css = `
.${classFirstHeading} {
display: inline-block;
font-size: 23px;
font-weight: 700;
margin-right: 15px;
padding: 10px 15px 10px 0;
border-right: 2px solid #000;
}
`;
styleEl.appendChild(document.createTextNode(css));
document.querySelector('head').appendChild(styleEl);
/*************************************/
});
})();
<h5 class="et_pb_toggle_title">#111 What is your refund policy?</h5>
If you don't know where to insert such code, install the Custom CSS and JS in Header & Footer plugin and just copy my js code to your page where you use the accordion

Convert UIFont to css font style string

I have some UIFonts like this:
let regularFont = UIFont.systemFont(ofSize: 18, weight: .regular)
let mediumFont = UIFont.systemFont(ofSize: 18, weight: .medium)
I use them in my UIKit components like UILabel.
Now I want to render some text in a WKWebView using the same fonts.
I generate some html template in code but I can't figure out how to setup the css font styles to match my given UIFonts.
With some guesswork I came up with the following which kind of works for my given examples:
<html>
<head>
<style>
body {
font-family: '.AppleSystemUIFont';
font-size: 18.0;
font-weight: normal;
}
b {
font-family: '.AppleSystemUIFont';
font-size: 18.0;
font-weight: bolder;
}
</style>
</head>
<body>
<p>
Regular font <b>Medium font</b> Regular font
</p>
</body>
</html>
It works ok-ish but clearly this does not scale (how about other weights?).
Also I can already see my designer coming at me, claiming that font weight is off by .1 or something.
This is my current effort. It works on a limited subset of properties (bold, italic) but it does not handle font weight. Also I haven't tested for custom fonts yet but my guess is it won't work like that.
extension UIFont {
func cssStyleString(color: UIColor) -> String {
let colorString = "rgb( \(CIColor(color: color).red * 255), \(CIColor(color: color).green * 255), \(CIColor(color: color).blue * 255) )"
// not sure this is right
let fontFamily = self.fontName == self.familyName
let fontSize = self.pointSize
// trait is not quite right for translation into weight. suggestions?
let fontWeight = self.fontDescriptor.symbolicTraits.contains(.traitBold) ? "bold" : "normal"
// works for italic only.
let fontStyle = self.fontDescriptor.symbolicTraits.contains(.traitItalic) ? "italic" : "normal"
return "font-family: '\(fontFamily)'; font-size: \(fontSize); font-weight: \(fontWeight); font-style: \(fontStyle); color: \(colorString); "
}
}
So hence my question:
What is the best way to create css styles from a given UIFont, especially with respect to font weight?

Using SVG Icons

I'm using use my own SVG icons and I'm trying to find the best way of using them.
I would like to keep the color but also adjust it if needed to match a theme or on when using hover.
I have tried using the following script which changes the following into an embedded SVG but as I load my scripts at the bottom of my HTML doc, I get a horrible jumping effect.
$(function(){
jQuery('img.svg').each(function(){
var $img = jQuery(this);
var imgID = $img.attr('id');
var imgClass = $img.attr('class');
var imgURL = $img.attr('src');
jQuery.get(imgURL, function(data) {
// Get the SVG tag, ignore the rest
var $svg = jQuery(data).find('svg');
// Add replaced image's ID to the new SVG
if(typeof imgID !== 'undefined') {
$svg = $svg.attr('id', imgID);
}
// Add replaced image's classes to the new SVG
if(typeof imgClass !== 'undefined') {
$svg = $svg.attr('class', imgClass+' replaced-svg');
}
// Remove any invalid XML tags as per http://validator.w3.org
$svg = $svg.removeAttr('xmlns:a');
// Check if the viewport is set, else we gonna set it if we can.
if(!$svg.attr('viewBox') && $svg.attr('height') && $svg.attr('width')) {
$svg.attr('viewBox', '0 0 ' + $svg.attr('height') + ' ' + $svg.attr('width'))
}
// Replace image with new SVG
$img.replaceWith($svg);
}, 'xml');
});
});
svg {width: 350px; height: 350px;}
svg path {fill: #000 !important;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<img src="https://upload.wikimedia.org/wikipedia/commons/f/f8/Windows_logo_-_2012_%28red%29.svg" alt="Microsoft" width="350" />
I've then tried to embed the the SVG by copying the code from Illustrator but the only way I can edit the colours is if I delete them in the html doc as my css won't override them.
What is the best way while keeping them from jumping?
Inline SVGs would be best IMO.
Export your SVGs using Illustrator (if you have troubles, follow this excellent guide by Colin Lord).
Then remove the colors from your SVG code and set them only using CSS.
If you have trouble overriding your colors you can give your SVGs IDs for more specifity.
If you go down the embedded route (which is my preferred option) - you don't actually need the majority of the HTML that Illustrator usually throws out.
Here is an example of your SVG with the most minimal code, then you can just use CSS to change the colours how you wish :-)
svg {
width: 350px;
height: 350px;
}
svg path {
fill: #000;
transform-origin: 0 0;
transform: scale(3)
}
#svg3 path {
fill: turquoise;
}
#svg3:hover path {
fill: green;
}
<svg id="svg2">
<path d="m0,12.402,35.687-4.8602,0.0156,34.423-35.67,0.20313zm35.67,33.529,0.0277,34.453-35.67-4.9041-0.002-29.78zm4.3261-39.025,47.318-6.906,0,41.527-47.318,0.37565zm47.329,39.349-0.0111,41.34-47.318-6.6784-0.0663-34.739z" id="path4"/>
</svg>
<!-- Another exmaple below using CSS to change the colours -->
<svg id="svg3">
<path d="m0,12.402,35.687-4.8602,0.0156,34.423-35.67,0.20313zm35.67,33.529,0.0277,34.453-35.67-4.9041-0.002-29.78zm4.3261-39.025,47.318-6.906,0,41.527-47.318,0.37565zm47.329,39.349-0.0111,41.34-47.318-6.6784-0.0663-34.739z" id="path4"/>
</svg>

Style an ordered list with Cyrillic letters

There are many possible values for list-style-type CSS property (e. g. decimal, lower-latin, upper-greek and so on). However there are none for the Cyrillic alphabet (which, btw, has different variations for different languages).
What is the best way to style an ordered list with Cyrillic letters?
(I'm providing a solution I ended up with despite I'm not very happy with it.)
I know nothing about Cyrillic list schemes so I’m at risk of a bit of cultural embarrassment here, but CSS3 Lists module (still in working draft) defines quite a few Cyrillic alphabetic list types: lower-belorussian, lower-bulgarian, lower-macedonian, lower-russian, lower-russian-full, lower-serbo-croatian, lower-ukrainian, lower-ukrainian-full, upper-belorussian, upper-bulgarian, upper-macedonian, upper-russian, upper-russian-full, upper-serbo-croatian, upper-ukrainian, upper-ukrainian-full. As expected, the state of support for these is deplorable currently (certainly nothing in Gecko or WebKit), but hopefully going forwards these will start to be implemented.
Update: some changes have been made – the definition of list types has been moved into the CSS3 Counter Styles module whose current draft (Feb 2015) has unfortunately lost all alphabetical Cyrillic types. This is in Candidate Recommendation stage so it’s unlikely that additions will be made at the point. Perhaps in CSS4 List Styles?
In this method I'm using CSS-generated content in before each list item.
.lower-ukrainian {
list-style-type: none;
}
.lower-ukrainian li:before {
display: inline-block;
margin-left: -1.5em;
margin-right: .55em;
text-align: right;
width: .95em;
}
.lower-ukrainian li:first-child:before {
content: "а.";
}
.lower-ukrainian li:nth-child(2):before {
content: "б.";
}
/* and so on */
Disadvantages
Hardcoded, restrict list to a certain max length.
Not pixel-perfect as compared to a regular order list
Here is another solution for Cyrillic letters with pretty clear code: jsfiddle.net
(() => {
const selector = 'ol.cyrillic',
style = document.createElement('style');
document.head.appendChild( style );
'абвгдежзиклмнопрстуфхцчшщэюя'.split('').forEach((c, i) =>
style.sheet.insertRule(
`${selector} > li:nth-child(${i+1})::before {
content: "${c})"
}`, 0)
);
})();
PS. You can convert this next-gen code to old one with Babel: babeljs.io
I'm surprised that there is no Cyrillic numbering. Here's a quick JS solution for you:
function base_convert(n, base) {
var dictionary = '0123456789abcdefghijklmnopqrstuvwxyz';
var m = n.toString(base);
var digits = [];
for (var i = 0; i < m.length; i++) {
digits.push(dictionary.indexOf(m.charAt(i)) - 1);
}
return digits;
}
var letters = {
'russian': {
'lower': 'абвгдеёжзийклмнопрстуфхцчшщъыьэюя',
'upper': 'АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ'
}
}
$('ul, ol').each(function() {
if (!(results = $(this).prop('class').match(/(upper|lower)-([a-z]+)/i))) return;
var characters = letters[results[2]][results[1]];
$('> li', this).each(function(index, element) {
var number = '', converted = base_convert(++index, characters.length);
for (var i = 0; i < converted.length; i++) {
number += characters.charAt(converted[i]);
}
$(this).attr('data-letter', number);
});
});​
My written Russian is admittedly bad, as you can see by my inability to count with letters, so change the letters object appropriately.
Demo: http://jsfiddle.net/JFFqn/14/

Resources