UNPKG

@belvo-finance/belvo-vue-components

Version:

## Project setup ``` npm install ```

296 lines (269 loc) 11.6 kB
var FontManager = (function(){ var maxWaitingTime = 5000; var emptyChar = { w: 0, size:0, shapes:[] }; var combinedCharacters = []; //Hindi characters combinedCharacters = combinedCharacters.concat([2304, 2305, 2306, 2307, 2362, 2363, 2364, 2364, 2366 , 2367, 2368, 2369, 2370, 2371, 2372, 2373, 2374, 2375, 2376, 2377, 2378, 2379 , 2380, 2381, 2382, 2383, 2387, 2388, 2389, 2390, 2391, 2402, 2403]); function setUpNode(font, family){ var parentNode = createTag('span'); parentNode.style.fontFamily = family; var node = createTag('span'); // Characters that vary significantly among different fonts node.innerHTML = 'giItT1WQy@!-/#'; // Visible - so we can measure it - but not on the screen parentNode.style.position = 'absolute'; parentNode.style.left = '-10000px'; parentNode.style.top = '-10000px'; // Large font size makes even subtle changes obvious parentNode.style.fontSize = '300px'; // Reset any font properties parentNode.style.fontVariant = 'normal'; parentNode.style.fontStyle = 'normal'; parentNode.style.fontWeight = 'normal'; parentNode.style.letterSpacing = '0'; parentNode.appendChild(node); document.body.appendChild(parentNode); // Remember width with no applied web font var width = node.offsetWidth; node.style.fontFamily = font + ', '+family; return {node:node, w:width, parent:parentNode}; } function checkLoadedFonts() { var i, len = this.fonts.length; var node, w; var loadedCount = len; for(i=0;i<len; i+= 1){ if(this.fonts[i].loaded){ loadedCount -= 1; continue; } if(this.fonts[i].fOrigin === 'n' || this.fonts[i].origin === 0){ this.fonts[i].loaded = true; } else{ node = this.fonts[i].monoCase.node; w = this.fonts[i].monoCase.w; if(node.offsetWidth !== w){ loadedCount -= 1; this.fonts[i].loaded = true; }else{ node = this.fonts[i].sansCase.node; w = this.fonts[i].sansCase.w; if(node.offsetWidth !== w){ loadedCount -= 1; this.fonts[i].loaded = true; } } if(this.fonts[i].loaded){ this.fonts[i].sansCase.parent.parentNode.removeChild(this.fonts[i].sansCase.parent); this.fonts[i].monoCase.parent.parentNode.removeChild(this.fonts[i].monoCase.parent); } } } if(loadedCount !== 0 && Date.now() - this.initTime < maxWaitingTime){ setTimeout(this.checkLoadedFonts.bind(this),20); }else{ setTimeout(function(){this.isLoaded = true;}.bind(this),0); } } function createHelper(def, fontData){ var tHelper = createNS('text'); tHelper.style.fontSize = '100px'; //tHelper.style.fontFamily = fontData.fFamily; tHelper.setAttribute('font-family', fontData.fFamily); tHelper.setAttribute('font-style', fontData.fStyle); tHelper.setAttribute('font-weight', fontData.fWeight); tHelper.textContent = '1'; if(fontData.fClass){ tHelper.style.fontFamily = 'inherit'; tHelper.setAttribute('class', fontData.fClass); } else { tHelper.style.fontFamily = fontData.fFamily; } def.appendChild(tHelper); var tCanvasHelper = createTag('canvas').getContext('2d'); tCanvasHelper.font = fontData.fWeight + ' ' + fontData.fStyle + ' 100px '+ fontData.fFamily; //tCanvasHelper.font = ' 100px '+ fontData.fFamily; return tHelper; } function addFonts(fontData, defs){ if(!fontData){ this.isLoaded = true; return; } if(this.chars){ this.isLoaded = true; this.fonts = fontData.list; return; } var fontArr = fontData.list; var i, len = fontArr.length; var _pendingFonts = len; for(i=0; i<len; i+= 1){ var shouldLoadFont = true; var loadedSelector; var j; fontArr[i].loaded = false; fontArr[i].monoCase = setUpNode(fontArr[i].fFamily,'monospace'); fontArr[i].sansCase = setUpNode(fontArr[i].fFamily,'sans-serif'); if(!fontArr[i].fPath) { fontArr[i].loaded = true; _pendingFonts -= 1; }else if(fontArr[i].fOrigin === 'p' || fontArr[i].origin === 3){ loadedSelector = document.querySelectorAll('style[f-forigin="p"][f-family="'+ fontArr[i].fFamily +'"], style[f-origin="3"][f-family="'+ fontArr[i].fFamily +'"]'); if (loadedSelector.length > 0) { shouldLoadFont = false; } if (shouldLoadFont) { var s = createTag('style'); s.setAttribute('f-forigin', fontArr[i].fOrigin); s.setAttribute('f-origin', fontArr[i].origin); s.setAttribute('f-family', fontArr[i].fFamily); s.type = "text/css"; s.innerHTML = "@font-face {" + "font-family: "+fontArr[i].fFamily+"; font-style: normal; src: url('"+fontArr[i].fPath+"');}"; defs.appendChild(s); } } else if(fontArr[i].fOrigin === 'g' || fontArr[i].origin === 1){ loadedSelector = document.querySelectorAll('link[f-forigin="g"], link[f-origin="1"]'); for (j = 0; j < loadedSelector.length; j++) { if (loadedSelector[j].href.indexOf(fontArr[i].fPath) !== -1) { // Font is already loaded shouldLoadFont = false; } } if (shouldLoadFont) { var l = createTag('link'); l.setAttribute('f-forigin', fontArr[i].fOrigin); l.setAttribute('f-origin', fontArr[i].origin); l.type = "text/css"; l.rel = "stylesheet"; l.href = fontArr[i].fPath; document.body.appendChild(l); } } else if(fontArr[i].fOrigin === 't' || fontArr[i].origin === 2){ loadedSelector = document.querySelectorAll('script[f-forigin="t"], script[f-origin="2"]'); for (j = 0; j < loadedSelector.length; j++) { if (fontArr[i].fPath === loadedSelector[j].src) { // Font is already loaded shouldLoadFont = false; } } if (shouldLoadFont) { var sc = createTag('link'); sc.setAttribute('f-forigin', fontArr[i].fOrigin); sc.setAttribute('f-origin', fontArr[i].origin); sc.setAttribute('rel','stylesheet'); sc.setAttribute('href',fontArr[i].fPath); defs.appendChild(sc); } } fontArr[i].helper = createHelper(defs,fontArr[i]); fontArr[i].cache = {}; this.fonts.push(fontArr[i]); } if (_pendingFonts === 0) { this.isLoaded = true; } else { //On some cases even if the font is loaded, it won't load correctly when measuring text on canvas. //Adding this timeout seems to fix it setTimeout(this.checkLoadedFonts.bind(this), 100); } } function addChars(chars){ if(!chars){ return; } if(!this.chars){ this.chars = []; } var i, len = chars.length; var j, jLen = this.chars.length, found; for(i=0;i<len;i+=1){ j = 0; found = false; while(j<jLen){ if(this.chars[j].style === chars[i].style && this.chars[j].fFamily === chars[i].fFamily && this.chars[j].ch === chars[i].ch){ found = true; } j += 1; } if(!found){ this.chars.push(chars[i]); jLen += 1; } } } function getCharData(char, style, font){ var i = 0, len = this.chars.length; while( i < len) { if(this.chars[i].ch === char && this.chars[i].style === style && this.chars[i].fFamily === font){ return this.chars[i]; } i+= 1; } if((typeof char === 'string' && char.charCodeAt(0) !== 13 || !char) && console && console.warn) { console.warn('Missing character from exported characters list: ', char, style, font); } return emptyChar; } function measureText(char, fontName, size) { var fontData = this.getFontByName(fontName); var index = char.charCodeAt(0); if(!fontData.cache[index + 1]) { var tHelper = fontData.helper; //Canvas version //fontData.cache[index] = tHelper.measureText(char).width / 100; //SVG version //console.log(tHelper.getBBox().width) if (char === ' ') { tHelper.textContent = '|' + char + '|'; var doubleSize = tHelper.getComputedTextLength(); tHelper.textContent = '||'; var singleSize = tHelper.getComputedTextLength(); fontData.cache[index + 1] = (doubleSize - singleSize)/100; } else { tHelper.textContent = char; fontData.cache[index + 1] = (tHelper.getComputedTextLength())/100; } } return fontData.cache[index + 1] * size; } function getFontByName(name){ var i = 0, len = this.fonts.length; while(i<len){ if(this.fonts[i].fName === name) { return this.fonts[i]; } i += 1; } return this.fonts[0]; } function getCombinedCharacterCodes() { return combinedCharacters; } function loaded() { return this.isLoaded; } var Font = function(){ this.fonts = []; this.chars = null; this.typekitLoaded = 0; this.isLoaded = false; this.initTime = Date.now(); }; //TODO: for now I'm adding these methods to the Class and not the prototype. Think of a better way to implement it. Font.getCombinedCharacterCodes = getCombinedCharacterCodes; Font.prototype.addChars = addChars; Font.prototype.addFonts = addFonts; Font.prototype.getCharData = getCharData; Font.prototype.getFontByName = getFontByName; Font.prototype.measureText = measureText; Font.prototype.checkLoadedFonts = checkLoadedFonts; Font.prototype.loaded = loaded; return Font; }());