/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- / /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ 'use strict'; var isWorker = (typeof window == 'undefined'); /** * Maximum file size of the font. */ var kMaxFontFileSize = 300000; /** * Maximum time to wait for a font to be loaded by font-face rules. */ var kMaxWaitForFontFace = 1000; /** * Hold a map of decoded fonts and of the standard fourteen Type1 * fonts and their acronyms. */ var stdFontMap = { 'Arial': 'Helvetica', 'Arial_Bold': 'Helvetica-Bold', 'Arial_BoldItalic': 'Helvetica-BoldOblique', 'Arial_Italic': 'Helvetica-Oblique', 'Arial_BoldItalicMT': 'Helvetica-BoldOblique', 'Arial_BoldMT': 'Helvetica-Bold', 'Arial_ItalicMT': 'Helvetica-Oblique', 'ArialMT': 'Helvetica', 'Courier_Bold': 'Courier-Bold', 'Courier_BoldItalic': 'Courier-BoldOblique', 'Courier_Italic': 'Courier-Oblique', 'CourierNew': 'Courier', 'CourierNew_Bold': 'Courier-Bold', 'CourierNew_BoldItalic': 'Courier-BoldOblique', 'CourierNew_Italic': 'Courier-Oblique', 'CourierNewPS_BoldItalicMT': 'Courier-BoldOblique', 'CourierNewPS_BoldMT': 'Courier-Bold', 'CourierNewPS_ItalicMT': 'Courier-Oblique', 'CourierNewPSMT': 'Courier', 'Helvetica_Bold': 'Helvetica-Bold', 'Helvetica_BoldItalic': 'Helvetica-BoldOblique', 'Helvetica_Italic': 'Helvetica-Oblique', 'Symbol_Bold': 'Symbol', 'Symbol_BoldItalic': 'Symbol', 'Symbol_Italic': 'Symbol', 'TimesNewRoman': 'Times-Roman', 'TimesNewRoman_Bold': 'Times-Bold', 'TimesNewRoman_BoldItalic': 'Times-BoldItalic', 'TimesNewRoman_Italic': 'Times-Italic', 'TimesNewRomanPS': 'Times-Roman', 'TimesNewRomanPS_Bold': 'Times-Bold', 'TimesNewRomanPS_BoldItalic': 'Times-BoldItalic', 'TimesNewRomanPS_BoldItalicMT': 'Times-BoldItalic', 'TimesNewRomanPS_BoldMT': 'Times-Bold', 'TimesNewRomanPS_Italic': 'Times-Italic', 'TimesNewRomanPS_ItalicMT': 'Times-Italic', 'TimesNewRomanPSMT': 'Times-Roman', 'TimesNewRomanPSMT_Bold': 'Times-Bold', 'TimesNewRomanPSMT_BoldItalic': 'Times-BoldItalic', 'TimesNewRomanPSMT_Italic': 'Times-Italic' }; var FontMeasure = (function FontMeasure() { var kScalePrecision = 50; var ctx = document.createElement('canvas').getContext('2d'); ctx.scale(1 / kScalePrecision, 1); var current; var measureCache; return { setActive: function fonts_setActive(font, size) { if (current = font) { var sizes = current.sizes; if (!(measureCache = sizes[size])) measureCache = sizes[size] = Object.create(null); } else { measureCache = null; } var name = font.loadedName; var bold = font.bold ? 'bold' : 'normal'; var italic = font.italic ? 'italic' : 'normal'; size *= kScalePrecision; var rule = italic + ' ' + bold + ' ' + size + 'px "' + name + '"'; ctx.font = rule; }, measureText: function fonts_measureText(text) { var width; if (measureCache && (width = measureCache[text])) return width; width = ctx.measureText(text).width / kScalePrecision; if (measureCache) measureCache[text] = width; return width; } }; })(); var FontLoader = { listeningForFontLoad: false, bind: function(fonts, callback) { function checkFontsLoaded() { for (var i = 0; i < objs.length; i++) { var fontObj = objs[i]; if (fontObj.loading) { return false; } } document.documentElement.removeEventListener( 'pdfjsFontLoad', checkFontsLoaded, false); callback(); return true; } var rules = [], names = [], objs = []; for (var i = 0; i < fonts.length; i++) { var font = fonts[i]; var obj = new Font(font.name, font.file, font.properties); objs.push(obj); var str = ''; var data = obj.data; if (data) { var length = data.length; for (var j = 0; j < length; j++) str += String.fromCharCode(data[j]); var rule = isWorker ? obj.bindWorker(str) : obj.bindDOM(str); if (rule) { rules.push(rule); names.push(obj.loadedName); } } } this.listeningForFontLoad = false; if (!isWorker && rules.length) { FontLoader.prepareFontLoadEvent(rules, names, objs); } if (!checkFontsLoaded()) { document.documentElement.addEventListener( 'pdfjsFontLoad', checkFontsLoaded, false); } return objs; }, // Set things up so that at least one pdfjsFontLoad event is // dispatched when all the @font-face |rules| for |names| have been // loaded in a subdocument. It's expected that the load of |rules| // has already started in this (outer) document, so that they should // be ordered before the load in the subdocument. prepareFontLoadEvent: function(rules, names, objs) { /** Hack begin */ // There's no event when a font has finished downloading so the // following code is a dirty hack to 'guess' when a font is // ready. This code will be obsoleted by Mozilla bug 471915. // // The only reliable way to know if a font is loaded in Gecko // (at the moment) is document.onload in a document with // a @font-face rule defined in a "static" stylesheet. We use a // subdocument in an