| 
					
				 | 
			
			
				@@ -28,8 +28,8 @@ factory((root.pdfjsDistBuildPdfCombined = {})); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   // Use strict in our context only - users might not want it 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   'use strict'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var pdfjsVersion = '1.4.190'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var pdfjsBuild = '34aa915'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var pdfjsVersion = '1.4.192'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var pdfjsBuild = '2dd03e1'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   var pdfjsFilePath = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     typeof document !== 'undefined' && document.currentScript ? 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -30967,5729 +30967,6429 @@ exports.IdentityCMap = IdentityCMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 (function (root, factory) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    factory((root.pdfjsCoreFonts = {}), root.pdfjsSharedUtil, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      root.pdfjsCorePrimitives, root.pdfjsCoreStream, root.pdfjsCoreParser, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      root.pdfjsCoreGlyphList, root.pdfjsCoreCharsets, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      root.pdfjsCoreFontRenderer, root.pdfjsCoreEncodings, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      root.pdfjsCoreStandardFonts, root.pdfjsCoreUnicode, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      root.pdfjsCoreType1Parser, root.pdfjsCoreCFFParser); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    factory((root.pdfjsCorePsParser = {}), root.pdfjsSharedUtil, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      root.pdfjsCoreParser); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}(this, function (exports, sharedUtil, corePrimitives, coreStream, coreParser, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  coreGlyphList, coreCharsets, coreFontRenderer, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  coreEncodings, coreStandardFonts, coreUnicode, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  coreType1Parser, coreCFFParser) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}(this, function (exports, sharedUtil, coreParser) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var FONT_IDENTITY_MATRIX = sharedUtil.FONT_IDENTITY_MATRIX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var FontType = sharedUtil.FontType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var Util = sharedUtil.Util; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var assert = sharedUtil.assert; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var bytesToString = sharedUtil.bytesToString; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 var error = sharedUtil.error; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var info = sharedUtil.info; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var isArray = sharedUtil.isArray; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var isInt = sharedUtil.isInt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var isNum = sharedUtil.isNum; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var readUint32 = sharedUtil.readUint32; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var shadow = sharedUtil.shadow; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var stringToBytes = sharedUtil.stringToBytes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var string32 = sharedUtil.string32; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var warn = sharedUtil.warn; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var MissingDataException = sharedUtil.MissingDataException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var Stream = coreStream.Stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var EOF = coreParser.EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 var Lexer = coreParser.Lexer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var getGlyphsUnicode = coreGlyphList.getGlyphsUnicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var getDingbatsGlyphsUnicode = coreGlyphList.getDingbatsGlyphsUnicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var ISOAdobeCharset = coreCharsets.ISOAdobeCharset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var ExpertCharset = coreCharsets.ExpertCharset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var ExpertSubsetCharset = coreCharsets.ExpertSubsetCharset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var FontRendererFactory = coreFontRenderer.FontRendererFactory; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var WinAnsiEncoding = coreEncodings.WinAnsiEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var StandardEncoding = coreEncodings.StandardEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var MacRomanEncoding = coreEncodings.MacRomanEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var SymbolSetEncoding = coreEncodings.SymbolSetEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var ZapfDingbatsEncoding = coreEncodings.ZapfDingbatsEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var ExpertEncoding = coreEncodings.ExpertEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var getEncoding = coreEncodings.getEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var getStdFontMap = coreStandardFonts.getStdFontMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var getNonStdFontMap = coreStandardFonts.getNonStdFontMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var getGlyphMapForStandardFonts = coreStandardFonts.getGlyphMapForStandardFonts; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var getSupplementalGlyphMapForArialBlack = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  coreStandardFonts.getSupplementalGlyphMapForArialBlack; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var getUnicodeRangeFor = coreUnicode.getUnicodeRangeFor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var mapSpecialUnicodeValues = coreUnicode.mapSpecialUnicodeValues; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var getUnicodeForGlyph = coreUnicode.getUnicodeForGlyph; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var Type1Parser = coreType1Parser.Type1Parser; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var CFFStandardStrings = coreCFFParser.CFFStandardStrings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var CFFParser = coreCFFParser.CFFParser; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var CFFCompiler = coreCFFParser.CFFCompiler; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var CFF = coreCFFParser.CFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var CFFHeader = coreCFFParser.CFFHeader; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var CFFTopDict = coreCFFParser.CFFTopDict; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var CFFPrivateDict = coreCFFParser.CFFPrivateDict; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var CFFStrings = coreCFFParser.CFFStrings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var CFFIndex = coreCFFParser.CFFIndex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var CFFCharset = coreCFFParser.CFFCharset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// Unicode Private Use Area 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var PRIVATE_USE_OFFSET_START = 0xE000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var PRIVATE_USE_OFFSET_END = 0xF8FF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var SKIP_PRIVATE_USE_RANGE_F000_TO_F01F = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var PostScriptParser = (function PostScriptParserClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function PostScriptParser(lexer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.lexer = lexer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.operators = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.token = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.prev = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PostScriptParser.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    nextToken: function PostScriptParser_nextToken() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.prev = this.token; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.token = this.lexer.getToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    accept: function PostScriptParser_accept(type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.token.type === type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.nextToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    expect: function PostScriptParser_expect(type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.accept(type)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      error('Unexpected symbol: found ' + this.token.type + ' expected ' + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        type + '.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    parse: function PostScriptParser_parse() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.nextToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.expect(PostScriptTokenTypes.LBRACE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.parseBlock(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.expect(PostScriptTokenTypes.RBRACE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return this.operators; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    parseBlock: function PostScriptParser_parseBlock() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      while (true) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (this.accept(PostScriptTokenTypes.NUMBER)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.operators.push(this.prev.value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (this.accept(PostScriptTokenTypes.OPERATOR)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.operators.push(this.prev.value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (this.accept(PostScriptTokenTypes.LBRACE)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.parseCondition(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    parseCondition: function PostScriptParser_parseCondition() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Add two place holders that will be updated later 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var conditionLocation = this.operators.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.operators.push(null, null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// PDF Glyph Space Units are one Thousandth of a TextSpace Unit 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// except for Type 3 fonts 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var PDF_GLYPH_SPACE_UNITS = 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.parseBlock(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.expect(PostScriptTokenTypes.RBRACE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.accept(PostScriptTokenTypes.IF)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // The true block is right after the 'if' so it just falls through on 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // true else it jumps and skips the true block. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.operators[conditionLocation] = this.operators.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.operators[conditionLocation + 1] = 'jz'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else if (this.accept(PostScriptTokenTypes.LBRACE)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var jumpLocation = this.operators.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.operators.push(null, null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var endOfTrue = this.operators.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.parseBlock(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.expect(PostScriptTokenTypes.RBRACE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.expect(PostScriptTokenTypes.IFELSE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // The jump is added at the end of the true block to skip the false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // block. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.operators[jumpLocation] = this.operators.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.operators[jumpLocation + 1] = 'j'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// Accented charactars are not displayed properly on Windows, using this flag 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// to control analysis of seac charstrings. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var SEAC_ANALYSIS_ENABLED = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.operators[conditionLocation] = endOfTrue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.operators[conditionLocation + 1] = 'jz'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        error('PS Function: error parsing conditional.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return PostScriptParser; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var FontFlags = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  FixedPitch: 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  Serif: 2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  Symbolic: 4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  Script: 8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  Nonsymbolic: 32, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  Italic: 64, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  AllCap: 65536, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  SmallCap: 131072, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ForceBold: 262144 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var PostScriptTokenTypes = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  LBRACE: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  RBRACE: 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  NUMBER: 2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  OPERATOR: 3, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  IF: 4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  IFELSE: 5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var MacStandardGlyphOrdering = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  '.notdef', '.null', 'nonmarkingreturn', 'space', 'exclam', 'quotedbl', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'numbersign', 'dollar', 'percent', 'ampersand', 'quotesingle', 'parenleft', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'parenright', 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'nine', 'colon', 'semicolon', 'less', 'equal', 'greater', 'question', 'at', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'backslash', 'bracketright', 'asciicircum', 'underscore', 'grave', 'a', 'b', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'asciitilde', 'Adieresis', 'Aring', 'Ccedilla', 'Eacute', 'Ntilde', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'Odieresis', 'Udieresis', 'aacute', 'agrave', 'acircumflex', 'adieresis', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'atilde', 'aring', 'ccedilla', 'eacute', 'egrave', 'ecircumflex', 'edieresis', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'iacute', 'igrave', 'icircumflex', 'idieresis', 'ntilde', 'oacute', 'ograve', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'ocircumflex', 'odieresis', 'otilde', 'uacute', 'ugrave', 'ucircumflex', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'udieresis', 'dagger', 'degree', 'cent', 'sterling', 'section', 'bullet', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'paragraph', 'germandbls', 'registered', 'copyright', 'trademark', 'acute', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'dieresis', 'notequal', 'AE', 'Oslash', 'infinity', 'plusminus', 'lessequal', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'greaterequal', 'yen', 'mu', 'partialdiff', 'summation', 'product', 'pi', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'integral', 'ordfeminine', 'ordmasculine', 'Omega', 'ae', 'oslash', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'questiondown', 'exclamdown', 'logicalnot', 'radical', 'florin', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'approxequal', 'Delta', 'guillemotleft', 'guillemotright', 'ellipsis', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'nonbreakingspace', 'Agrave', 'Atilde', 'Otilde', 'OE', 'oe', 'endash', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'emdash', 'quotedblleft', 'quotedblright', 'quoteleft', 'quoteright', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'divide', 'lozenge', 'ydieresis', 'Ydieresis', 'fraction', 'currency', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'guilsinglleft', 'guilsinglright', 'fi', 'fl', 'daggerdbl', 'periodcentered', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'quotesinglbase', 'quotedblbase', 'perthousand', 'Acircumflex', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'Ecircumflex', 'Aacute', 'Edieresis', 'Egrave', 'Iacute', 'Icircumflex', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'Idieresis', 'Igrave', 'Oacute', 'Ocircumflex', 'apple', 'Ograve', 'Uacute', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'Ucircumflex', 'Ugrave', 'dotlessi', 'circumflex', 'tilde', 'macron', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'breve', 'dotaccent', 'ring', 'cedilla', 'hungarumlaut', 'ogonek', 'caron', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'Lslash', 'lslash', 'Scaron', 'scaron', 'Zcaron', 'zcaron', 'brokenbar', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'Eth', 'eth', 'Yacute', 'yacute', 'Thorn', 'thorn', 'minus', 'multiply', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'onesuperior', 'twosuperior', 'threesuperior', 'onehalf', 'onequarter', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'threequarters', 'franc', 'Gbreve', 'gbreve', 'Idotaccent', 'Scedilla', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  'scedilla', 'Cacute', 'cacute', 'Ccaron', 'ccaron', 'dcroat']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function adjustWidths(properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (!properties.fontMatrix) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (properties.fontMatrix[0] === FONT_IDENTITY_MATRIX[0]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // adjusting width to fontMatrix scale 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var scale = 0.001 / properties.fontMatrix[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var glyphsWidths = properties.widths; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  for (var glyph in glyphsWidths) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    glyphsWidths[glyph] *= scale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  properties.defaultWidth *= scale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function getFontType(type, subtype) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  switch (type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    case 'Type1': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return subtype === 'Type1C' ? FontType.TYPE1C : FontType.TYPE1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    case 'CIDFontType0': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return subtype === 'CIDFontType0C' ? FontType.CIDFONTTYPE0C : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        FontType.CIDFONTTYPE0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    case 'OpenType': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return FontType.OPENTYPE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    case 'TrueType': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return FontType.TRUETYPE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    case 'CIDFontType2': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return FontType.CIDFONTTYPE2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    case 'MMType1': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return FontType.MMTYPE1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    case 'Type0': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return FontType.TYPE0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return FontType.UNKNOWN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var PostScriptToken = (function PostScriptTokenClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function PostScriptToken(type, value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.type = type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.value = value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var Glyph = (function GlyphClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function Glyph(fontChar, unicode, accent, width, vmetric, operatorListId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                 isSpace, isInFont) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.fontChar = fontChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.unicode = unicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.accent = accent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.width = width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.vmetric = vmetric; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.operatorListId = operatorListId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.isSpace = isSpace; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.isInFont = isInFont; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var opCache = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  Glyph.prototype.matchesForCache = function(fontChar, unicode, accent, width, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                             vmetric, operatorListId, isSpace, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                             isInFont) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return this.fontChar === fontChar && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           this.unicode === unicode && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           this.accent === accent && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           this.width === width && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           this.vmetric === vmetric && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           this.operatorListId === operatorListId && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           this.isSpace === isSpace && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           this.isInFont === isInFont; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PostScriptToken.getOperator = function PostScriptToken_getOperator(op) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var opValue = opCache[op]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (opValue) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return opValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return opCache[op] = new PostScriptToken(PostScriptTokenTypes.OPERATOR, op); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return Glyph; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PostScriptToken.LBRACE = new PostScriptToken(PostScriptTokenTypes.LBRACE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '{'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PostScriptToken.RBRACE = new PostScriptToken(PostScriptTokenTypes.RBRACE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    '}'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PostScriptToken.IF = new PostScriptToken(PostScriptTokenTypes.IF, 'IF'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PostScriptToken.IFELSE = new PostScriptToken(PostScriptTokenTypes.IFELSE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'IFELSE'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return PostScriptToken; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 })(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var ToUnicodeMap = (function ToUnicodeMapClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function ToUnicodeMap(cmap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // The elements of this._map can be integers or strings, depending on how 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // |cmap| was created. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this._map = cmap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var PostScriptLexer = (function PostScriptLexerClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function PostScriptLexer(stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.stream = stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.nextChar(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ToUnicodeMap.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    get length() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return this._map.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.strBuf = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  PostScriptLexer.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    nextChar: function PostScriptLexer_nextChar() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return (this.currentChar = this.stream.getByte()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getToken: function PostScriptLexer_getToken() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var comment = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ch = this.currentChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    forEach: function(callback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var charCode in this._map) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        callback(charCode, this._map[charCode].charCodeAt(0)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // skip comments 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      while (true) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ch < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    has: function(i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return this._map[i] !== undefined; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (comment) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (ch === 0x0A || ch === 0x0D) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            comment = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (ch === 0x25) { // '%' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          comment = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (!Lexer.isSpace(ch)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ch = this.nextChar(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      switch (ch | 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: // '0'-'4' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: // '5'-'9' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 0x2B: case 0x2D: case 0x2E: // '+', '-', '.' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return new PostScriptToken(PostScriptTokenTypes.NUMBER, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                     this.getNumber()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 0x7B: // '{' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.nextChar(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return PostScriptToken.LBRACE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 0x7D: // '}' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.nextChar(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return PostScriptToken.RBRACE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // operator 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var strBuf = this.strBuf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      strBuf.length = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      strBuf[0] = String.fromCharCode(ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    get: function(i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return this._map[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      while ((ch = this.nextChar()) >= 0 && // and 'A'-'Z', 'a'-'z' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             ((ch >= 0x41 && ch <= 0x5A) || (ch >= 0x61 && ch <= 0x7A))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        strBuf.push(String.fromCharCode(ch)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var str = strBuf.join(''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      switch (str.toLowerCase()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 'if': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return PostScriptToken.IF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        case 'ifelse': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return PostScriptToken.IFELSE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return PostScriptToken.getOperator(str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getNumber: function PostScriptLexer_getNumber() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ch = this.currentChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var strBuf = this.strBuf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      strBuf.length = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      strBuf[0] = String.fromCharCode(ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    charCodeOf: function(v) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return this._map.indexOf(v); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      while ((ch = this.nextChar()) >= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if ((ch >= 0x30 && ch <= 0x39) || // '0'-'9' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ch === 0x2D || ch === 0x2E) { // '-', '.' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          strBuf.push(String.fromCharCode(ch)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var value = parseFloat(strBuf.join('')); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (isNaN(value)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        error('Invalid floating point number: ' + value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return ToUnicodeMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return PostScriptLexer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 })(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var IdentityToUnicodeMap = (function IdentityToUnicodeMapClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function IdentityToUnicodeMap(firstChar, lastChar) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.firstChar = firstChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.lastChar = lastChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+exports.PostScriptLexer = PostScriptLexer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+exports.PostScriptParser = PostScriptParser; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+})); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(function (root, factory) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    factory((root.pdfjsCoreType1Parser = {}), root.pdfjsSharedUtil, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      root.pdfjsCoreStream, root.pdfjsCoreParser, root.pdfjsCoreEncodings); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}(this, function (exports, sharedUtil, coreStream, coreParser, coreEncodings) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  IdentityToUnicodeMap.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    get length() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return (this.lastChar + 1) - this.firstChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var warn = sharedUtil.warn; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var Stream = coreStream.Stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var Lexer = coreParser.Lexer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var getEncoding = coreEncodings.getEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    forEach: function (callback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var i = this.firstChar, ii = this.lastChar; i <= ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        callback(i, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Hinting is currently disabled due to unknown problems on windows 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// in tracemonkey and various other pdfs with type1 fonts. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var HINTING_ENABLED = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    has: function (i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return this.firstChar <= i && i <= this.lastChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * CharStrings are encoded following the the CharString Encoding sequence 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * describe in Chapter 6 of the "Adobe Type1 Font Format" specification. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * The value in a byte indicates a command, a number, or subsequent bytes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * that are to be interpreted in a special way. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * CharString Number Encoding: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  A CharString byte containing the values from 32 through 255 inclusive 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  indicate an integer. These values are decoded in four ranges. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 1. A CharString byte containing a value, v, between 32 and 246 inclusive, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * indicate the integer v - 139. Thus, the integer values from -107 through 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 107 inclusive may be encoded in single byte. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 2. A CharString byte containing a value, v, between 247 and 250 inclusive, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * indicates an integer involving the next byte, w, according to the formula: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * [(v - 247) x 256] + w + 108 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 3. A CharString byte containing a value, v, between 251 and 254 inclusive, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * indicates an integer involving the next byte, w, according to the formula: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * -[(v - 251) * 256] - w - 108 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 4. A CharString containing the value 255 indicates that the next 4 bytes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * are a two complement signed integer. The first of these bytes contains the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * highest order bits, the second byte contains the next higher order bits 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * and the fourth byte contain the lowest order bits. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * CharString Command Encoding: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  CharStrings commands are encoded in 1 or 2 bytes. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  Single byte commands are encoded in 1 byte that contains a value between 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  0 and 31 inclusive. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  If a command byte contains the value 12, then the value in the next byte 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *  indicates a command. This "escape" mechanism allows many extra commands 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * to be encoded and this encoding technique helps to minimize the length of 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * the charStrings. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var Type1CharString = (function Type1CharStringClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var COMMAND_MAP = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'hstem': [1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'vstem': [3], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'vmoveto': [4], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'rlineto': [5], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'hlineto': [6], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'vlineto': [7], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'rrcurveto': [8], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'callsubr': [10], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'flex': [12, 35], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'drop' : [12, 18], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'endchar': [14], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'rmoveto': [21], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'hmoveto': [22], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'vhcurveto': [30], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    'hvcurveto': [31] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    get: function (i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.firstChar <= i && i <= this.lastChar) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return String.fromCharCode(i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function Type1CharString() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.width = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.lsb = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.flexing = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.output = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.stack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Type1CharString.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    convert: function Type1CharString_convert(encoded, subrs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                              seacAnalysisEnabled) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var count = encoded.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var error = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var wx, sbx, subrNumber; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = 0; i < count; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var value = encoded[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (value < 32) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (value === 12) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            value = (value << 8) + encoded[++i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          switch (value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 1: // hstem 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (!HINTING_ENABLED) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                this.stack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              error = this.executeCommand(2, COMMAND_MAP.hstem); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 3: // vstem 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (!HINTING_ENABLED) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                this.stack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              error = this.executeCommand(2, COMMAND_MAP.vstem); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 4: // vmoveto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (this.flexing) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (this.stack.length < 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  error = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // Add the dx for flex and but also swap the values so they are 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // the right order. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var dy = this.stack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                this.stack.push(0, dy); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              error = this.executeCommand(1, COMMAND_MAP.vmoveto); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 5: // rlineto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              error = this.executeCommand(2, COMMAND_MAP.rlineto); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 6: // hlineto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              error = this.executeCommand(1, COMMAND_MAP.hlineto); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 7: // vlineto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              error = this.executeCommand(1, COMMAND_MAP.vlineto); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 8: // rrcurveto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              error = this.executeCommand(6, COMMAND_MAP.rrcurveto); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 9: // closepath 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // closepath is a Type1 command that does not take argument and is 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // useless in Type2 and it can simply be ignored. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.stack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 10: // callsubr 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (this.stack.length < 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                error = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              subrNumber = this.stack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              error = this.convert(subrs[subrNumber], subrs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                   seacAnalysisEnabled); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 11: // return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              return error; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 13: // hsbw 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (this.stack.length < 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                error = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // To convert to type2 we have to move the width value to the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // first part of the charstring and then use hmoveto with lsb. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              wx = this.stack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              sbx = this.stack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.lsb = sbx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.width = wx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.stack.push(wx, sbx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              error = this.executeCommand(2, COMMAND_MAP.hmoveto); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 14: // endchar 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.output.push(COMMAND_MAP.endchar[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 21: // rmoveto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (this.flexing) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              error = this.executeCommand(2, COMMAND_MAP.rmoveto); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 22: // hmoveto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (this.flexing) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // Add the dy for flex. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                this.stack.push(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              error = this.executeCommand(1, COMMAND_MAP.hmoveto); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 30: // vhcurveto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              error = this.executeCommand(4, COMMAND_MAP.vhcurveto); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case 31: // hvcurveto 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              error = this.executeCommand(4, COMMAND_MAP.hvcurveto); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case (12 << 8) + 0: // dotsection 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // dotsection is a Type1 command to specify some hinting feature 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // for dots that do not take a parameter and it can safely be 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // ignored for Type2. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.stack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case (12 << 8) + 1: // vstem3 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (!HINTING_ENABLED) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                this.stack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // [vh]stem3 are Type1 only and Type2 supports [vh]stem with 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // multiple parameters, so instead of returning [vh]stem3 take a 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // shortcut and return [vhstem] instead. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              error = this.executeCommand(2, COMMAND_MAP.vstem); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case (12 << 8) + 2: // hstem3 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (!HINTING_ENABLED) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 this.stack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // See vstem3. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              error = this.executeCommand(2, COMMAND_MAP.hstem); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case (12 << 8) + 6: // seac 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // seac is like type 2's special endchar but it doesn't use the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // first argument asb, so remove it. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (seacAnalysisEnabled) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                this.seac = this.stack.splice(-4, 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                error = this.executeCommand(0, COMMAND_MAP.endchar); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                error = this.executeCommand(4, COMMAND_MAP.endchar); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case (12 << 8) + 7: // sbw 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (this.stack.length < 4) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                error = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // To convert to type2 we have to move the width value to the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // first part of the charstring and then use rmoveto with 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // (dx, dy). The height argument will not be used for vmtx and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // vhea tables reconstruction -- ignoring it. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              var wy = this.stack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              wx = this.stack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              var sby = this.stack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              sbx = this.stack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.lsb = sbx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.width = wx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.stack.push(wx, sbx, sby); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              error = this.executeCommand(3, COMMAND_MAP.rmoveto); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case (12 << 8) + 12: // div 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (this.stack.length < 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                error = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              var num2 = this.stack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              var num1 = this.stack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.stack.push(num1 / num2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case (12 << 8) + 16: // callothersubr 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (this.stack.length < 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                error = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              subrNumber = this.stack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              var numArgs = this.stack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (subrNumber === 0 && numArgs === 3) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var flexArgs = this.stack.splice(this.stack.length - 17, 17); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                this.stack.push( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  flexArgs[2] + flexArgs[0], // bcp1x + rpx 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  flexArgs[3] + flexArgs[1], // bcp1y + rpy 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  flexArgs[4], // bcp2x 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  flexArgs[5], // bcp2y 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  flexArgs[6], // p2x 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  flexArgs[7], // p2y 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  flexArgs[8], // bcp3x 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  flexArgs[9], // bcp3y 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  flexArgs[10], // bcp4x 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  flexArgs[11], // bcp4y 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  flexArgs[12], // p3x 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  flexArgs[13], // p3y 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  flexArgs[14] // flexDepth 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  // 15 = finalx unused by flex 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  // 16 = finaly unused by flex 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                error = this.executeCommand(13, COMMAND_MAP.flex, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                this.flexing = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                this.stack.push(flexArgs[15], flexArgs[16]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } else if (subrNumber === 1 && numArgs === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                this.flexing = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case (12 << 8) + 17: // pop 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // Ignore this since it is only used with othersubr. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            case (12 << 8) + 33: // setcurrentpoint 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // Ignore for now. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.stack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              warn('Unknown type 1 charstring command of "' + value + '"'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (value <= 246) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          value = value - 139; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (value <= 250) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          value = ((value - 247) * 256) + encoded[++i] + 108; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (value <= 254) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          value = -((value - 251) * 256) - encoded[++i] - 108; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          value = (encoded[++i] & 0xff) << 24 | (encoded[++i] & 0xff) << 16 | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  (encoded[++i] & 0xff) << 8 | (encoded[++i] & 0xff) << 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.stack.push(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return undefined; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return error; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    charCodeOf: function (v) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return (isInt(v) && v >= this.firstChar && v <= this.lastChar) ? v : -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    executeCommand: function(howManyArgs, command, keepStack) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var stackLength = this.stack.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (howManyArgs > stackLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var start = stackLength - howManyArgs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = start; i < stackLength; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var value = this.stack[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (value === (value | 0)) { // int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.output.push(28, (value >> 8) & 0xff, value & 0xff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { // fixed point 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          value = (65536 * value) | 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.output.push(255, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                           (value >> 24) & 0xFF, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                           (value >> 16) & 0xFF, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                           (value >> 8) & 0xFF, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                           value & 0xFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.output.push.apply(this.output, command); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (keepStack) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.stack.splice(start, howManyArgs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.stack.length = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return IdentityToUnicodeMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return Type1CharString; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 })(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var OpenTypeFileBuilder = (function OpenTypeFileBuilderClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function writeInt16(dest, offset, num) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    dest[offset] = (num >> 8) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    dest[offset + 1] = num & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Type1Parser encapsulate the needed code for parsing a Type1 font 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * program. Some of its logic depends on the Type2 charstrings 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * structure. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Note: this doesn't really parse the font since that would require evaluation 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * of PostScript, but it is possible in most cases to extract what we need 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * without a full parse. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var Type1Parser = (function Type1ParserClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * Decrypt a Sequence of Ciphertext Bytes to Produce the Original Sequence 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * of Plaintext Bytes. The function took a key as a parameter which can be 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * for decrypting the eexec block of for decoding charStrings. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var EEXEC_ENCRYPT_KEY = 55665; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var CHAR_STRS_ENCRYPT_KEY = 4330; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function writeInt32(dest, offset, num) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    dest[offset] = (num >> 24) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    dest[offset + 1] = (num >> 16) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    dest[offset + 2] = (num >> 8) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    dest[offset + 3] = num & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function isHexDigit(code) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return code >= 48 && code <= 57 || // '0'-'9' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           code >= 65 && code <= 70 || // 'A'-'F' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           code >= 97 && code <= 102;  // 'a'-'f' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function writeData(dest, offset, data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var i, ii; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (data instanceof Uint8Array) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      dest.set(data, offset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } else if (typeof data === 'string') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (i = 0, ii = data.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        dest[offset++] = data.charCodeAt(i) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function decrypt(data, key, discardNumber) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (discardNumber >= data.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return new Uint8Array(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var r = key | 0, c1 = 52845, c2 = 22719, i, j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (i = 0; i < discardNumber; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      r = ((data[i] + r) * c1 + c2) & ((1 << 16) - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var count = data.length - discardNumber; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var decrypted = new Uint8Array(count); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (i = discardNumber, j = 0; j < count; i++, j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var value = data[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      decrypted[j] = value ^ (r >> 8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      r = ((value + r) * c1 + c2) & ((1 << 16) - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return decrypted; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function decryptAscii(data, key, discardNumber) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var r = key | 0, c1 = 52845, c2 = 22719; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var count = data.length, maybeLength = count >>> 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var decrypted = new Uint8Array(maybeLength); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var i, j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (i = 0, j = 0; i < count; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var digit1 = data[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!isHexDigit(digit1)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // treating everything else as array 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (i = 0, ii = data.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        dest[offset++] = data[i] & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      i++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var digit2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      while (i < count && !isHexDigit(digit2 = data[i])) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        i++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (i < count) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var value = parseInt(String.fromCharCode(digit1, digit2), 16); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        decrypted[j++] = value ^ (r >> 8); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        r = ((value + r) * c1 + c2) & ((1 << 16) - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return Array.prototype.slice.call(decrypted, discardNumber, j); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function OpenTypeFileBuilder(sfnt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.sfnt = sfnt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.tables = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function isSpecial(c) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return c === 0x2F || // '/' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           c === 0x5B || c === 0x5D || // '[', ']' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           c === 0x7B || c === 0x7D || // '{', '}' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           c === 0x28 || c === 0x29; // '(', ')' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  OpenTypeFileBuilder.getSearchParams = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function OpenTypeFileBuilder_getSearchParams(entriesCount, entrySize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var maxPower2 = 1, log2 = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    while ((maxPower2 ^ entriesCount) > maxPower2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      maxPower2 <<= 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      log2++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function Type1Parser(stream, encrypted, seacAnalysisEnabled) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (encrypted) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var data = stream.getBytes(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var isBinary = !(isHexDigit(data[0]) && isHexDigit(data[1]) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       isHexDigit(data[2]) && isHexDigit(data[3])); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      stream = new Stream(isBinary ? decrypt(data, EEXEC_ENCRYPT_KEY, 4) : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          decryptAscii(data, EEXEC_ENCRYPT_KEY, 4)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var searchRange = maxPower2 * entrySize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      range: searchRange, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      entry: log2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      rangeShift: entrySize * entriesCount - searchRange 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.seacAnalysisEnabled = !!seacAnalysisEnabled; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var OTF_HEADER_SIZE = 12; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var OTF_TABLE_ENTRY_SIZE = 16; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.stream = stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.nextChar(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  OpenTypeFileBuilder.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    toArray: function OpenTypeFileBuilder_toArray() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var sfnt = this.sfnt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Type1Parser.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    readNumberArray: function Type1Parser_readNumberArray() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.getToken(); // read '[' or '{' (arrays can start with either) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var array = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      while (true) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var token = this.getToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (token === null || token === ']' || token === '}') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        array.push(parseFloat(token || 0)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return array; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Tables needs to be written by ascendant alphabetic order 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var tables = this.tables; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var tablesNames = Object.keys(tables); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      tablesNames.sort(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var numTables = tablesNames.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    readNumber: function Type1Parser_readNumber() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var token = this.getToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return parseFloat(token || 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var i, j, jj, table, tableName; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // layout the tables data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var offset = OTF_HEADER_SIZE + numTables * OTF_TABLE_ENTRY_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var tableOffsets = [offset]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (i = 0; i < numTables; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        table = tables[tablesNames[i]]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var paddedLength = ((table.length + 3) & ~3) >>> 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        offset += paddedLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tableOffsets.push(offset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    readInt: function Type1Parser_readInt() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Use '| 0' to prevent setting a double into length such as the double 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // does not flow into the loop variable. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var token = this.getToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return parseInt(token || 0, 10) | 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var file = new Uint8Array(offset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // write the table data first (mostly for checksum) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (i = 0; i < numTables; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        table = tables[tablesNames[i]]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        writeData(file, tableOffsets[i], table); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    readBoolean: function Type1Parser_readBoolean() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var token = this.getToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // sfnt version (4 bytes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (sfnt === 'true') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Windows hates the Mac TrueType sfnt version number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        sfnt = string32(0x00010000); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      file[0] = sfnt.charCodeAt(0) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      file[1] = sfnt.charCodeAt(1) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      file[2] = sfnt.charCodeAt(2) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      file[3] = sfnt.charCodeAt(3) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Use 1 and 0 since that's what type2 charstrings use. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return token === 'true' ? 1 : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // numTables (2 bytes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      writeInt16(file, 4, numTables); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    nextChar : function Type1_nextChar() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return (this.currentChar = this.stream.getByte()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var searchParams = OpenTypeFileBuilder.getSearchParams(numTables, 16); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getToken: function Type1Parser_getToken() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Eat whitespace and comments. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var comment = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ch = this.currentChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      while (true) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ch === -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // searchRange (2 bytes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      writeInt16(file, 6, searchParams.range); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // entrySelector (2 bytes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      writeInt16(file, 8, searchParams.entry); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // rangeShift (2 bytes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      writeInt16(file, 10, searchParams.rangeShift); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (comment) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (ch === 0x0A || ch === 0x0D) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            comment = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (ch === 0x25) { // '%' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          comment = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (!Lexer.isSpace(ch)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ch = this.nextChar(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (isSpecial(ch)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.nextChar(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return String.fromCharCode(ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var token = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      do { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        token += String.fromCharCode(ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ch = this.nextChar(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } while (ch >= 0 && !Lexer.isSpace(ch) && !isSpecial(ch)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return token; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      offset = OTF_HEADER_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // writing table entries 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (i = 0; i < numTables; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tableName = tablesNames[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        file[offset] = tableName.charCodeAt(0) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        file[offset + 1] = tableName.charCodeAt(1) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        file[offset + 2] = tableName.charCodeAt(2) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        file[offset + 3] = tableName.charCodeAt(3) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    /* 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * Returns an object containing a Subrs array and a CharStrings 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     * array extracted from and eexec encrypted block of data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+     */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    extractFontProgram: function Type1Parser_extractFontProgram() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var stream = this.stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // checksum 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var checksum = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (j = tableOffsets[i], jj = tableOffsets[i + 1]; j < jj; j += 4) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var quad = readUint32(file, j); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          checksum = (checksum + quad) >>> 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var subrs = [], charstrings = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var privateData = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      privateData['lenIV'] = 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var program = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        subrs: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        charstrings: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        properties: { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          'privateData': privateData 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        writeInt32(file, offset + 4, checksum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var token, length, data, lenIV, encoded; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      while ((token = this.getToken()) !== null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (token !== '/') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        token = this.getToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        switch (token) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'CharStrings': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // The number immediately following CharStrings must be greater or 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // equal to the number of CharStrings. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.getToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.getToken(); // read in 'dict' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.getToken(); // read in 'dup' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.getToken(); // read in 'begin' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            while(true) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              token = this.getToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (token === null || token === 'end') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // offset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        writeInt32(file, offset + 8, tableOffsets[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        writeInt32(file, offset + 12, tables[tableName].length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (token !== '/') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              var glyph = this.getToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              length = this.readInt(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.getToken(); // read in 'RD' or '-|' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              data = stream.makeSubStream(stream.pos, length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              lenIV = program.properties.privateData['lenIV']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              encoded = decrypt(data.getBytes(), CHAR_STRS_ENCRYPT_KEY, lenIV); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // Skip past the required space and binary data. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              stream.skip(length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.nextChar(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              token = this.getToken(); // read in 'ND' or '|-' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (token === 'noaccess') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                this.getToken(); // read in 'def' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              charstrings.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                glyph: glyph, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                encoded: encoded 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'Subrs': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var num = this.readInt(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.getToken(); // read in 'array' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            while ((token = this.getToken()) === 'dup') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              var index = this.readInt(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              length = this.readInt(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.getToken(); // read in 'RD' or '-|' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              data = stream.makeSubStream(stream.pos, length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              lenIV = program.properties.privateData['lenIV']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              encoded = decrypt(data.getBytes(), CHAR_STRS_ENCRYPT_KEY, lenIV); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // Skip past the required space and binary data. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              stream.skip(length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.nextChar(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              token = this.getToken(); // read in 'NP' or '|' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (token === 'noaccess') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                this.getToken(); // read in 'put' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              subrs[index] = encoded; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'BlueValues': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'OtherBlues': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'FamilyBlues': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'FamilyOtherBlues': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var blueArray = this.readNumberArray(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // *Blue* values may contain invalid data: disables reading of 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // those values when hinting is disabled. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (blueArray.length > 0 && (blueArray.length % 2) === 0 && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                HINTING_ENABLED) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              program.properties.privateData[token] = blueArray; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'StemSnapH': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'StemSnapV': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            program.properties.privateData[token] = this.readNumberArray(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'StdHW': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'StdVW': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            program.properties.privateData[token] = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.readNumberArray()[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'BlueShift': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'lenIV': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'BlueFuzz': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'BlueScale': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'LanguageGroup': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'ExpansionFactor': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            program.properties.privateData[token] = this.readNumber(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'ForceBold': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            program.properties.privateData[token] = this.readBoolean(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        offset += OTF_TABLE_ENTRY_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = 0; i < charstrings.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        glyph = charstrings[i].glyph; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        encoded = charstrings[i].encoded; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var charString = new Type1CharString(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var error = charString.convert(encoded, subrs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                       this.seacAnalysisEnabled); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var output = charString.output; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // It seems when FreeType encounters an error while evaluating a glyph 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // that it completely ignores the glyph so we'll mimic that behaviour 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // here and put an endchar to make the validator happy. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          output = [14]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        program.charstrings.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          glyphName: glyph, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          charstring: output, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          width: charString.width, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          lsb: charString.lsb, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          seac: charString.seac 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return file; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return program; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    addTable: function OpenTypeFileBuilder_addTable(tag, data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (tag in this.tables) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        throw new Error('Table ' + tag + ' already exists'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    extractFontHeader: function Type1Parser_extractFontHeader(properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var token; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      while ((token = this.getToken()) !== null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (token !== '/') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        token = this.getToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        switch (token) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'FontMatrix': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var matrix = this.readNumberArray(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            properties.fontMatrix = matrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'Encoding': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var encodingArg = this.getToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var encoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!/^\d+$/.test(encodingArg)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // encoding name is specified 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              encoding = getEncoding(encodingArg); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              encoding = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              var size = parseInt(encodingArg, 10) | 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.getToken(); // read in 'array' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              for (var j = 0; j < size; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                token = this.getToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                // skipping till first dup or def (e.g. ignoring for statement) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                while (token !== 'dup' && token !== 'def') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  token = this.getToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  if (token === null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    return; // invalid header 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (token === 'def') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  break; // read all array data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var index = this.readInt(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                this.getToken(); // read in '/' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                var glyph = this.getToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                encoding[index] = glyph; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                this.getToken(); // read the in 'put' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            properties.builtInEncoding = encoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'FontBBox': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var fontBBox = this.readNumberArray(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // adjusting ascent/descent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            properties.ascent = fontBBox[3]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            properties.descent = fontBBox[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            properties.ascentScaled = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.tables[tag] = data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return OpenTypeFileBuilder; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return Type1Parser; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 })(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// Problematic Unicode characters in the fonts that needs to be moved to avoid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// issues when they are painted on the canvas, e.g. complex-script shaping or 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// control/whitespace characters. The ranges are listed in pairs: the first item 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// is a code of the first problematic code, the second one is the next 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// non-problematic code. The ranges must be in sorted order. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var ProblematicCharRanges = new Int32Array([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // Control characters. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  0x0000, 0x0020, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  0x007F, 0x00A1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  0x00AD, 0x00AE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // Chars that is used in complex-script shaping. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  0x0600, 0x0780, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  0x08A0, 0x10A0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  0x1780, 0x1800, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // General punctuation chars. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  0x2000, 0x2010, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  0x2011, 0x2012, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  0x2028, 0x2030, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  0x205F, 0x2070, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  0x25CC, 0x25CD, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // Chars that is used in complex-script shaping. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  0xAA60, 0xAA80, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // Specials Unicode block. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  0xFFF0, 0x10000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+exports.Type1Parser = Type1Parser; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+})); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * 'Font' is the class the outside world should use, it encapsulate all the font 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * decoding logics whatever type it is (assuming the font type is supported). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * For example to read a Type1 font and to attach it to the document: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- *   var type1Font = new Font("MyFontName", binaryFile, propertiesObject); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- *   type1Font.bind(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var Font = (function FontClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function Font(name, file, properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var charCode, glyphName, unicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.name = name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.loadedName = properties.loadedName; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.isType3Font = properties.isType3Font; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.sizes = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.missingFile = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(function (root, factory) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    factory((root.pdfjsDisplayCanvas = {}), root.pdfjsSharedUtil, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      root.pdfjsDisplayDOMUtils, root.pdfjsDisplayPatternHelper, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      root.pdfjsDisplayWebGL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}(this, function (exports, sharedUtil, displayDOMUtils, displayPatternHelper, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  displayWebGL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.glyphCache = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var FONT_IDENTITY_MATRIX = sharedUtil.FONT_IDENTITY_MATRIX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var IDENTITY_MATRIX = sharedUtil.IDENTITY_MATRIX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var ImageKind = sharedUtil.ImageKind; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var OPS = sharedUtil.OPS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var TextRenderingMode = sharedUtil.TextRenderingMode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var Uint32ArrayView = sharedUtil.Uint32ArrayView; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var Util = sharedUtil.Util; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var assert = sharedUtil.assert; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var info = sharedUtil.info; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var isNum = sharedUtil.isNum; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var isArray = sharedUtil.isArray; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var error = sharedUtil.error; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var shadow = sharedUtil.shadow; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var warn = sharedUtil.warn; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var TilingPattern = displayPatternHelper.TilingPattern; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var getShadingPatternFromIR = displayPatternHelper.getShadingPatternFromIR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var WebGLUtils = displayWebGL.WebGLUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var names = name.split('+'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    names = names.length > 1 ? names[1] : names[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    names = names.split(/[-,_]/g)[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.isSerifFont = !!(properties.flags & FontFlags.Serif); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.isSymbolicFont = !!(properties.flags & FontFlags.Symbolic); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.isMonospace = !!(properties.flags & FontFlags.FixedPitch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// <canvas> contexts store most of the state we need natively. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// However, PDF needs a bit more state, which we store here. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var type = properties.type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var subtype = properties.subtype; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.type = type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Minimal font size that would be used during canvas fillText operations. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var MIN_FONT_SIZE = 16; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Maximum font size that would be used during canvas fillText operations. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var MAX_FONT_SIZE = 100; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var MAX_GROUP_SIZE = 4096; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.fallbackName = (this.isMonospace ? 'monospace' : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                         (this.isSerifFont ? 'serif' : 'sans-serif')); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Heuristic value used when enforcing minimum line widths. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var MIN_WIDTH_FACTOR = 0.65; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.differences = properties.differences; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.widths = properties.widths; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.defaultWidth = properties.defaultWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.composite = properties.composite; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.wideChars = properties.wideChars; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.cMap = properties.cMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.ascent = properties.ascent / PDF_GLYPH_SPACE_UNITS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.descent = properties.descent / PDF_GLYPH_SPACE_UNITS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.fontMatrix = properties.fontMatrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.bbox = properties.bbox; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var COMPILE_TYPE3_GLYPHS = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var MAX_SIZE_TO_COMPILE = 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.toUnicode = properties.toUnicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var FULL_CHUNK_HEIGHT = 16; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.toFontChar = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function createScratchCanvas(width, height) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var canvas = document.createElement('canvas'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  canvas.width = width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  canvas.height = height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return canvas; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (properties.type === 'Type3') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (charCode = 0; charCode < 256; charCode++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.toFontChar[charCode] = (this.differences[charCode] || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                     properties.defaultEncoding[charCode]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.fontType = FontType.TYPE3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function addContextCurrentTransform(ctx) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // If the context doesn't expose a `mozCurrentTransform`, add a JS based one. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!ctx.mozCurrentTransform) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctx._originalSave = ctx.save; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctx._originalRestore = ctx.restore; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctx._originalRotate = ctx.rotate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctx._originalScale = ctx.scale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctx._originalTranslate = ctx.translate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctx._originalTransform = ctx.transform; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctx._originalSetTransform = ctx.setTransform; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.cidEncoding = properties.cidEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.vertical = properties.vertical; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (this.vertical) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.vmetrics = properties.vmetrics; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.defaultVMetrics = properties.defaultVMetrics; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var glyphsUnicodeMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!file || file.isEmpty) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (file) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Some bad PDF generators will include empty font files, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // attempting to recover by assuming that no file exists. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        warn('Font file is empty in "' + name + '" (' + this.loadedName + ')'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctx._transformMatrix = ctx._transformMatrix || [1, 0, 0, 1, 0, 0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctx._transformStack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Object.defineProperty(ctx, 'mozCurrentTransform', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      get: function getCurrentTransform() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return this._transformMatrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.missingFile = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // The file data is not specified. Trying to fix the font name 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // to be used with the canvas.font. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fontName = name.replace(/[,_]/g, '-'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var stdFontMap = getStdFontMap(), nonStdFontMap = getNonStdFontMap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var isStandardFont = !!stdFontMap[fontName] || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        !!(nonStdFontMap[fontName] && stdFontMap[nonStdFontMap[fontName]]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      fontName = stdFontMap[fontName] || nonStdFontMap[fontName] || fontName; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    Object.defineProperty(ctx, 'mozCurrentTransformInverse', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      get: function getCurrentTransformInverse() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Calculation done using WolframAlpha: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // http://www.wolframalpha.com/input/? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //   i=Inverse+{{a%2C+c%2C+e}%2C+{b%2C+d%2C+f}%2C+{0%2C+0%2C+1}} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.bold = (fontName.search(/bold/gi) !== -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.italic = ((fontName.search(/oblique/gi) !== -1) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                     (fontName.search(/italic/gi) !== -1)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var m = this._transformMatrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var a = m[0], b = m[1], c = m[2], d = m[3], e = m[4], f = m[5]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Use 'name' instead of 'fontName' here because the original 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // name ArialBlack for example will be replaced by Helvetica. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.black = (name.search(/Black/g) !== -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var ad_bc = a * d - b * c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var bc_ad = b * c - a * d; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // if at least one width is present, remeasure all chars when exists 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.remeasure = Object.keys(this.widths).length > 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (isStandardFont && type === 'CIDFontType2' && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          properties.cidEncoding.indexOf('Identity-') === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var GlyphMapForStandardFonts = getGlyphMapForStandardFonts(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Standard fonts might be embedded as CID font without glyph mapping. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Building one based on GlyphMapForStandardFonts. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var map = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (charCode in GlyphMapForStandardFonts) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          map[+charCode] = GlyphMapForStandardFonts[charCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (/ArialBlack/i.test(name)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var SupplementalGlyphMapForArialBlack = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            getSupplementalGlyphMapForArialBlack(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (charCode in SupplementalGlyphMapForArialBlack) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            map[+charCode] = SupplementalGlyphMapForArialBlack[charCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var isIdentityUnicode = this.toUnicode instanceof IdentityToUnicodeMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!isIdentityUnicode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          this.toUnicode.forEach(function(charCode, unicodeCharCode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            map[+charCode] = unicodeCharCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.toFontChar = map; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.toUnicode = new ToUnicodeMap(map); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else if (/Symbol/i.test(fontName)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.toFontChar = buildToFontChar(SymbolSetEncoding, getGlyphsUnicode(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                          properties.differences); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else if (/Dingbats/i.test(fontName)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (/Wingdings/i.test(name)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          warn('Non-embedded Wingdings font, falling back to ZapfDingbats.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.toFontChar = buildToFontChar(ZapfDingbatsEncoding, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                          getDingbatsGlyphsUnicode(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                          properties.differences); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else if (isStandardFont) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.toFontChar = buildToFontChar(properties.defaultEncoding, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                          getGlyphsUnicode(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                          properties.differences); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        glyphsUnicodeMap = getGlyphsUnicode(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.toUnicode.forEach(function(charCode, unicodeCharCode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (!this.composite) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            glyphName = (properties.differences[charCode] || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                         properties.defaultEncoding[charCode]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            unicode = getUnicodeForGlyph(glyphName, glyphsUnicodeMap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (unicode !== -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              unicodeCharCode = unicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          this.toFontChar[charCode] = unicodeCharCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }.bind(this)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          d / ad_bc, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          b / bc_ad, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          c / bc_ad, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          a / ad_bc, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (d * e - c * f) / bc_ad, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (b * e - a * f) / ad_bc 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.loadedName = fontName.split('-')[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.loading = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.fontType = getFontType(type, subtype); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Some fonts might use wrong font types for Type1C or CIDFontType0C 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (subtype === 'Type1C' && (type !== 'Type1' && type !== 'MMType1')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Some TrueType fonts by mistake claim Type1C 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (isTrueTypeFile(file)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        subtype = 'TrueType'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        type = 'Type1'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (subtype === 'CIDFontType0C' && type !== 'CIDFontType0') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      type = 'CIDFontType0'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (subtype === 'OpenType') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      type = 'OpenType'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Some CIDFontType0C fonts by mistake claim CIDFontType0. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (type === 'CIDFontType0') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (isType1File(file)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        subtype = 'CIDFontType0'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else if (isOpenTypeFile(file)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Sometimes the type/subtype can be a complete lie (see issue6782.pdf). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        type = subtype = 'OpenType'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        subtype = 'CIDFontType0C'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctx.save = function ctxSave() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var old = this._transformMatrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this._transformStack.push(old); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this._transformMatrix = old.slice(0, 6); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    switch (type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case 'MMType1': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        info('MMType1 font (' + name + '), falling back to Type1.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        /* falls through */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case 'Type1': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case 'CIDFontType0': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.mimetype = 'font/opentype'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this._originalSave(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var cff = (subtype === 'Type1C' || subtype === 'CIDFontType0C') ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          new CFFFont(file, properties) : new Type1Font(name, file, properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctx.restore = function ctxRestore() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var prev = this._transformStack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (prev) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._transformMatrix = prev; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this._originalRestore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        adjustWidths(properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctx.translate = function ctxTranslate(x, y) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var m = this._transformMatrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      m[4] = m[0] * x + m[2] * y + m[4]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      m[5] = m[1] * x + m[3] * y + m[5]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Wrap the CFF data inside an OTF font file 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        data = this.convert(name, cff, properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this._originalTranslate(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case 'OpenType': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case 'TrueType': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      case 'CIDFontType2': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.mimetype = 'font/opentype'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctx.scale = function ctxScale(x, y) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var m = this._transformMatrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      m[0] = m[0] * x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      m[1] = m[1] * x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      m[2] = m[2] * y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      m[3] = m[3] * y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Repair the TrueType file. It is can be damaged in the point of 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // view of the sanitizer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        data = this.checkAndRepair(name, file, properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (this.isOpenType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          adjustWidths(properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this._originalScale(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          type = 'OpenType'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctx.transform = function ctxTransform(a, b, c, d, e, f) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var m = this._transformMatrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this._transformMatrix = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m[0] * a + m[2] * b, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m[1] * a + m[3] * b, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m[0] * c + m[2] * d, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m[1] * c + m[3] * d, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m[0] * e + m[2] * f + m[4], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m[1] * e + m[3] * f + m[5] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        error('Font ' + type + ' is not supported'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx._originalTransform(a, b, c, d, e, f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.data = data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.fontType = getFontType(type, subtype); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this._transformMatrix = [a, b, c, d, e, f]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Transfer some properties again that could change during font conversion 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.fontMatrix = properties.fontMatrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.widths = properties.widths; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.defaultWidth = properties.defaultWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.encoding = properties.baseEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.seacMap = properties.seacMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.loading = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  Font.getFontID = (function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var ID = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return function Font_getFontID() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return String(ID++); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx._originalSetTransform(a, b, c, d, e, f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  })(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function int16(b0, b1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return (b0 << 8) + b1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctx.rotate = function ctxRotate(angle) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var cosValue = Math.cos(angle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var sinValue = Math.sin(angle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function signedInt16(b0, b1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var value = (b0 << 8) + b1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return value & (1 << 15) ? value - 0x10000 : value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var m = this._transformMatrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this._transformMatrix = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m[0] * cosValue + m[2] * sinValue, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m[1] * cosValue + m[3] * sinValue, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m[0] * (-sinValue) + m[2] * cosValue, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m[1] * (-sinValue) + m[3] * cosValue, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m[4], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        m[5] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function int32(b0, b1, b2, b3) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this._originalRotate(angle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function string16(value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return String.fromCharCode((value >> 8) & 0xff, value & 0xff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var CachedCanvases = (function CachedCanvasesClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function CachedCanvases() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.cache = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CachedCanvases.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getCanvas: function CachedCanvases_getCanvas(id, width, height, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                 trackTransform) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var canvasEntry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.cache[id] !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        canvasEntry = this.cache[id]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        canvasEntry.canvas.width = width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        canvasEntry.canvas.height = height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // reset canvas transform for emulated mozCurrentTransform, if needed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        canvasEntry.context.setTransform(1, 0, 0, 1, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var canvas = createScratchCanvas(width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var ctx = canvas.getContext('2d'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (trackTransform) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          addContextCurrentTransform(ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.cache[id] = canvasEntry = {canvas: canvas, context: ctx}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return canvasEntry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    clear: function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var id in this.cache) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var canvasEntry = this.cache[id]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Zeroing the width and height causes Firefox to release graphics 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // resources immediately, which can greatly reduce memory consumption. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        canvasEntry.canvas.width = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        canvasEntry.canvas.height = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete this.cache[id]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return CachedCanvases; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function safeString16(value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // clamp value to the 16-bit int range 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    value = (value > 0x7FFF ? 0x7FFF : (value < -0x8000 ? -0x8000 : value)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return String.fromCharCode((value >> 8) & 0xff, value & 0xff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function compileType3Glyph(imgData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var POINT_TO_PROCESS_LIMIT = 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function isTrueTypeFile(file) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var header = file.peekBytes(4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return readUint32(header, 0) === 0x00010000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var width = imgData.width, height = imgData.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var i, j, j0, width1 = width + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var points = new Uint8Array(width1 * (height + 1)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var POINT_TYPES = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      new Uint8Array([0, 2, 4, 0, 1, 0, 5, 4, 8, 10, 0, 8, 0, 2, 1, 0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function isOpenTypeFile(file) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var header = file.peekBytes(4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return bytesToString(header) === 'OTTO'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // decodes bit-packed mask data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var lineSize = (width + 7) & ~7, data0 = imgData.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var data = new Uint8Array(lineSize * height), pos = 0, ii; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (i = 0, ii = data0.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var mask = 128, elem = data0[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    while (mask > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      data[pos++] = (elem & mask) ? 0 : 255; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      mask >>= 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function isType1File(file) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var header = file.peekBytes(2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // All Type1 font programs must begin with the comment '%!' (0x25 + 0x21). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (header[0] === 0x25 && header[1] === 0x21) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // ... obviously some fonts violate that part of the specification, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // please refer to the comment in |Type1Font| below. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (header[0] === 0x80 && header[1] === 0x01) { // pfb file header. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // finding iteresting points: every point is located between mask pixels, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // so there will be points of the (width + 1)x(height + 1) grid. Every point 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // will have flags assigned based on neighboring mask pixels: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //   4 | 8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //   --P-- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //   2 | 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // We are interested only in points with the flags: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //   - outside corners: 1, 2, 4, 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //   - inside corners: 7, 11, 13, 14; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  //   - and, intersections: 5, 10. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var count = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  pos = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (data[pos] !== 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    points[0] = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ++count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (j = 1; j < width; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (data[pos] !== data[pos + 1]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      points[j] = data[pos] ? 2 : 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ++count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pos++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function buildToFontChar(encoding, glyphsUnicodeMap, differences) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var toFontChar = [], unicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (var i = 0, ii = encoding.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      unicode = getUnicodeForGlyph(encoding[i], glyphsUnicodeMap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (unicode !== -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        toFontChar[i] = unicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (data[pos] !== 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    points[j] = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ++count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (i = 1; i < height; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pos = i * lineSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    j0 = i * width1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (data[pos - lineSize] !== data[pos]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      points[j0] = data[pos] ? 1 : 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ++count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (var charCode in differences) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      unicode = getUnicodeForGlyph(differences[charCode], glyphsUnicodeMap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (unicode !== -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        toFontChar[+charCode] = unicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 'sum' is the position of the current pixel configuration in the 'TYPES' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // array (in order 8-1-2-4, so we can use '>>2' to shift the column). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var sum = (data[pos] ? 4 : 0) + (data[pos - lineSize] ? 8 : 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (j = 1; j < width; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sum = (sum >> 2) + (data[pos + 1] ? 4 : 0) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (data[pos - lineSize + 1] ? 8 : 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (POINT_TYPES[sum]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        points[j0 + j] = POINT_TYPES[sum]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ++count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      pos++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (data[pos - lineSize] !== data[pos]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      points[j0 + j] = data[pos] ? 2 : 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ++count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (count > POINT_TO_PROCESS_LIMIT) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return toFontChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   * Helper function for |adjustMapping|. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   * @return {boolean} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function isProblematicUnicodeLocation(code) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Using binary search to find a range start. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var i = 0, j = ProblematicCharRanges.length - 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    while (i < j) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var c = (i + j + 1) >> 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (code < ProblematicCharRanges[c]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        j = c - 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        i = c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  pos = lineSize * (height - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  j0 = i * width1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (data[pos] !== 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    points[j0] = 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ++count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (j = 1; j < width; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (data[pos] !== data[pos + 1]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      points[j0 + j] = data[pos] ? 4 : 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ++count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Even index means code in problematic range. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return !(i & 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    pos++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (data[pos] !== 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    points[j0 + j] = 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ++count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (count > POINT_TO_PROCESS_LIMIT) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   * Rebuilds the char code to glyph ID map by trying to replace the char codes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   * with their unicode value. It also moves char codes that are in known 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   * problematic locations. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   * @return {Object} Two properties: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   * 'toFontChar' - maps original char codes(the value that will be read 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   * from commands such as show text) to the char codes that will be used in the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   * font that we build 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   * 'charCodeToGlyphId' - maps the new font char codes to glyph ids 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function adjustMapping(charCodeToGlyphId, properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var toUnicode = properties.toUnicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var isSymbolic = !!(properties.flags & FontFlags.Symbolic); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var isIdentityUnicode = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      properties.toUnicode instanceof IdentityToUnicodeMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var newMap = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var toFontChar = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var usedFontCharCodes = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var nextAvailableFontCharCode = PRIVATE_USE_OFFSET_START; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (var originalCharCode in charCodeToGlyphId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      originalCharCode |= 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var glyphId = charCodeToGlyphId[originalCharCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fontCharCode = originalCharCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // First try to map the value to a unicode position if a non identity map 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // was created. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!isIdentityUnicode && toUnicode.has(originalCharCode)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var unicode = toUnicode.get(fontCharCode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // TODO: Try to map ligatures to the correct spot. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (unicode.length === 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          fontCharCode = unicode.charCodeAt(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Try to move control characters, special characters and already mapped 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // characters to the private use area since they will not be drawn by 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // canvas if left in their current position. Also, move characters if the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // font was symbolic and there is only an identity unicode map since the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // characters probably aren't in the correct position (fixes an issue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // with firefox and thuluthfont). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if ((usedFontCharCodes[fontCharCode] !== undefined || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           isProblematicUnicodeLocation(fontCharCode) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           (isSymbolic && isIdentityUnicode)) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          nextAvailableFontCharCode <= PRIVATE_USE_OFFSET_END) { // Room left. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Loop to try and find a free spot in the private use area. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        do { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          fontCharCode = nextAvailableFontCharCode++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // building outlines 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var steps = new Int32Array([0, width1, -1, 0, -width1, 0, 0, 0, 1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var outlines = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (i = 0; count && i <= height; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var p = i * width1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var end = p + width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    while (p < end && !points[p]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      p++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (p === end) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var coords = [p % width1, i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (SKIP_PRIVATE_USE_RANGE_F000_TO_F01F && fontCharCode === 0xF000) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            fontCharCode = 0xF020; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            nextAvailableFontCharCode = fontCharCode + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var type = points[p], p0 = p, pp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    do { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var step = steps[type]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      do { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        p += step; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } while (!points[p]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } while (usedFontCharCodes[fontCharCode] !== undefined && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                 nextAvailableFontCharCode <= PRIVATE_USE_OFFSET_END); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      pp = points[p]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (pp !== 5 && pp !== 10) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // set new direction 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        type = pp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // delete mark 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        points[p] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { // type is 5 or 10, ie, a crossing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // set new direction 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        type = pp & ((0x33 * type) >> 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // set new type for "future hit" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        points[p] &= (type >> 2 | type << 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      newMap[fontCharCode] = glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      toFontChar[originalCharCode] = fontCharCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      usedFontCharCodes[fontCharCode] = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      toFontChar: toFontChar, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      charCodeToGlyphId: newMap, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      nextAvailableFontCharCode: nextAvailableFontCharCode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      coords.push(p % width1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      coords.push((p / width1) | 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      --count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } while (p0 !== p); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    outlines.push(coords); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    --i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function getRanges(glyphs, numGlyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Array.sort() sorts by characters, not numerically, so convert to an 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // array of characters. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var codes = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (var charCode in glyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Remove an invalid glyph ID mappings to make OTS happy. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (glyphs[charCode] >= numGlyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var drawOutline = function(c) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    c.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // the path shall be painted in [0..1]x[0..1] space 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    c.scale(1 / width, -1 / height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    c.translate(0, -height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    c.beginPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (var i = 0, ii = outlines.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var o = outlines[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      c.moveTo(o[0], o[1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var j = 2, jj = o.length; j < jj; j += 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        c.lineTo(o[j], o[j+1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      codes.push({ fontCharCode: charCode | 0, glyphId: glyphs[charCode] }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    codes.sort(function fontGetRangesSort(a, b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return a.fontCharCode - b.fontCharCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    c.fill(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    c.beginPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    c.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Split the sorted codes into ranges. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var ranges = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var length = codes.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (var n = 0; n < length; ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var start = codes[n].fontCharCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var codeIndices = [codes[n].glyphId]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ++n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var end = start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      while (n < length && end + 1 === codes[n].fontCharCode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        codeIndices.push(codes[n].glyphId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ++end; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ++n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (end === 0xFFFF) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ranges.push([start, end, codeIndices]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return drawOutline; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return ranges; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var CanvasExtraState = (function CanvasExtraStateClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function CanvasExtraState(old) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Are soft masks and alpha values shapes or opacities? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.alphaIsShape = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.fontSize = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.fontSizeScale = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.textMatrix = IDENTITY_MATRIX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.textMatrixScale = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.fontMatrix = FONT_IDENTITY_MATRIX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.leading = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Current point (in user coordinates) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.x = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.y = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Start of text line (in text coordinates) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.lineX = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.lineY = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Character and word spacing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.charSpacing = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.wordSpacing = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.textHScale = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.textRenderingMode = TextRenderingMode.FILL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.textRise = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Default fore and background colors 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.fillColor = '#000000'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.strokeColor = '#000000'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.patternFill = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Note: fill alpha applies to all non-stroking operations 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.fillAlpha = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.strokeAlpha = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.lineWidth = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.activeSMask = null; // nonclonable field (see the save method below) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function createCmapTable(glyphs, numGlyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var ranges = getRanges(glyphs, numGlyphs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var numTables = ranges[ranges.length - 1][1] > 0xFFFF ? 2 : 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var cmap = '\x00\x00' + // version 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-               string16(numTables) +  // numTables 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-               '\x00\x03' + // platformID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-               '\x00\x01' + // encodingID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-               string32(4 + numTables * 8); // start of the table record 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.old = old; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var i, ii, j, jj; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (i = ranges.length - 1; i >= 0; --i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (ranges[i][0] <= 0xFFFF) { break; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CanvasExtraState.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    clone: function CanvasExtraState_clone() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return Object.create(this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setCurrentPoint: function CanvasExtraState_setCurrentPoint(x, y) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.x = x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.y = y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var bmpLength = i + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return CanvasExtraState; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (ranges[i][0] < 0xFFFF && ranges[i][1] === 0xFFFF) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ranges[i][1] = 0xFFFE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var CanvasGraphics = (function CanvasGraphicsClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Defines the time the executeOperatorList is going to be executing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // before it stops and shedules a continue of execution. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var EXECUTION_TIME = 15; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Defines the number of steps before checking the execution time 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var EXECUTION_STEPS = 10; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function CanvasGraphics(canvasCtx, commonObjs, objs, imageLayer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.ctx = canvasCtx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.current = new CanvasExtraState(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.stateStack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.pendingClip = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.pendingEOFill = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.res = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.xobjs = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.commonObjs = commonObjs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.objs = objs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.imageLayer = imageLayer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.groupStack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.processingType3 = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Patterns are painted relative to the initial page/form transform, see pdf 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // spec 8.7.2 NOTE 1. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.baseTransform = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.baseTransformStack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.groupLevel = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.smaskStack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.smaskCounter = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.tempSMask = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.cachedCanvases = new CachedCanvases(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (canvasCtx) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // NOTE: if mozCurrentTransform is polyfilled, then the current state of 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // the transformation must already be set in canvasCtx._transformMatrix. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      addContextCurrentTransform(canvasCtx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var trailingRangesCount = ranges[i][1] < 0xFFFF ? 1 : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var segCount = bmpLength + trailingRangesCount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var searchParams = OpenTypeFileBuilder.getSearchParams(segCount, 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.cachedGetSinglePixelWidth = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Fill up the 4 parallel arrays describing the segments. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var startCount = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var endCount = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var idDeltas = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var idRangeOffsets = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var glyphsIds = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var bias = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function putBinaryImageData(ctx, imgData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (typeof ImageData !== 'undefined' && imgData instanceof ImageData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.putImageData(imgData, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var range, start, end, codes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (i = 0, ii = bmpLength; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      range = ranges[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      start = range[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      end = range[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      startCount += string16(start); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      endCount += string16(end); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      codes = range[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var contiguous = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (j = 1, jj = codes.length; j < jj; ++j) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (codes[j] !== codes[j - 1] + 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          contiguous = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!contiguous) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var offset = (segCount - i) * 2 + bias * 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        bias += (end - start + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Put the image data to the canvas in chunks, rather than putting the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // whole image at once.  This saves JS memory, because the ImageData object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // is smaller. It also possibly saves C++ memory within the implementation 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // of putImageData(). (E.g. in Firefox we make two short-lived copies of 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // the data passed to putImageData()). |n| shouldn't be too small, however, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // because too many putImageData() calls will slow things down. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Note: as written, if the last chunk is partial, the putImageData() call 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // will (conceptually) put pixels past the bounds of the canvas.  But 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // that's ok; any such pixels are ignored. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        idDeltas += string16(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        idRangeOffsets += string16(offset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var height = imgData.height, width = imgData.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var partialChunkHeight = height % FULL_CHUNK_HEIGHT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (j = 0, jj = codes.length; j < jj; ++j) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          glyphsIds += string16(codes[j]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var startCode = codes[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var srcPos = 0, destPos; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var src = imgData.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var dest = chunkImgData.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var i, j, thisChunkHeight, elemsInThisChunk; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        idDeltas += string16((startCode - start) & 0xFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        idRangeOffsets += string16(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // There are multiple forms in which the pixel data can be passed, and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // imgData.kind tells us which one this is. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (imgData.kind === ImageKind.GRAYSCALE_1BPP) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Grayscale, 1 bit per pixel (i.e. black-and-white). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var srcLength = src.byteLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var dest32 = PDFJS.hasCanvasTypedArrays ? new Uint32Array(dest.buffer) : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        new Uint32ArrayView(dest); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var dest32DataLength = dest32.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fullSrcDiff = (width + 7) >> 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var white = 0xFFFFFFFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var black = (PDFJS.isLittleEndian || !PDFJS.hasCanvasTypedArrays) ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        0xFF000000 : 0x000000FF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (i = 0; i < totalChunks; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        thisChunkHeight = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (i < fullChunks) ? FULL_CHUNK_HEIGHT : partialChunkHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        destPos = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (j = 0; j < thisChunkHeight; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var srcDiff = srcLength - srcPos; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var k = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var kEnd = (srcDiff > fullSrcDiff) ? width : srcDiff * 8 - 7; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var kEndUnrolled = kEnd & ~7; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var mask = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var srcByte = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (; k < kEndUnrolled; k += 8) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            srcByte = src[srcPos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            dest32[destPos++] = (srcByte & 128) ? white : black; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            dest32[destPos++] = (srcByte & 64) ? white : black; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            dest32[destPos++] = (srcByte & 32) ? white : black; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            dest32[destPos++] = (srcByte & 16) ? white : black; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            dest32[destPos++] = (srcByte & 8) ? white : black; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            dest32[destPos++] = (srcByte & 4) ? white : black; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            dest32[destPos++] = (srcByte & 2) ? white : black; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            dest32[destPos++] = (srcByte & 1) ? white : black; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (; k < kEnd; k++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             if (mask === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               srcByte = src[srcPos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               mask = 128; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (trailingRangesCount > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      endCount += '\xFF\xFF'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      startCount += '\xFF\xFF'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      idDeltas += '\x00\x01'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      idRangeOffsets += '\x00\x00'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            dest32[destPos++] = (srcByte & mask) ? white : black; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mask >>= 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // We ran out of input. Make all remaining pixels transparent. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        while (destPos < dest32DataLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          dest32[destPos++] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else if (imgData.kind === ImageKind.RGBA_32BPP) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // RGBA, 32-bits per pixel. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      j = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      elemsInThisChunk = width * FULL_CHUNK_HEIGHT * 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (i = 0; i < fullChunks; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        srcPos += elemsInThisChunk; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.putImageData(chunkImgData, 0, j); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        j += FULL_CHUNK_HEIGHT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (i < totalChunks) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        elemsInThisChunk = width * partialChunkHeight * 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.putImageData(chunkImgData, 0, j); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else if (imgData.kind === ImageKind.RGB_24BPP) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // RGB, 24-bits per pixel. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      thisChunkHeight = FULL_CHUNK_HEIGHT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      elemsInThisChunk = width * thisChunkHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (i = 0; i < totalChunks; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (i >= fullChunks) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          thisChunkHeight = partialChunkHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          elemsInThisChunk = width * thisChunkHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        destPos = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (j = elemsInThisChunk; j--;) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          dest[destPos++] = src[srcPos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          dest[destPos++] = src[srcPos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          dest[destPos++] = src[srcPos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          dest[destPos++] = 255; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      error('bad image kind: ' + imgData.kind); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var format314 = '\x00\x00' + // language 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    string16(2 * segCount) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    string16(searchParams.range) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    string16(searchParams.entry) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    string16(searchParams.rangeShift) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    endCount + '\x00\x00' + startCount + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    idDeltas + idRangeOffsets + glyphsIds; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function putBinaryImageMask(ctx, imgData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var height = imgData.height, width = imgData.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var partialChunkHeight = height % FULL_CHUNK_HEIGHT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var format31012 = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var header31012 = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (numTables > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      cmap += '\x00\x03' + // platformID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              '\x00\x0A' + // encodingID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              string32(4 + numTables * 8 + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                       4 + format314.length); // start of the table record 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      format31012 = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (i = 0, ii = ranges.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        range = ranges[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        start = range[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        codes = range[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var code = codes[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (j = 1, jj = codes.length; j < jj; ++j) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (codes[j] !== codes[j - 1] + 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            end = range[0] + j - 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            format31012 += string32(start) + // startCharCode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                           string32(end) + // endCharCode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                           string32(code); // startGlyphID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            start = end + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            code = codes[j]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var srcPos = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var src = imgData.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var dest = chunkImgData.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (var i = 0; i < totalChunks; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var thisChunkHeight = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (i < fullChunks) ? FULL_CHUNK_HEIGHT : partialChunkHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Expand the mask so it can be used by the canvas.  Any required 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // inversion has already been handled. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var destPos = 3; // alpha component offset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var j = 0; j < thisChunkHeight; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var mask = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (var k = 0; k < width; k++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (!mask) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var elem = src[srcPos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mask = 128; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          dest[destPos] = (elem & mask) ? 0 : 255; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          destPos += 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          mask >>= 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        format31012 += string32(start) + // startCharCode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                       string32(range[1]) + // endCharCode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                       string32(code); // startGlyphID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      header31012 = '\x00\x0C' + // format 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    '\x00\x00' + // reserved 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    string32(format31012.length + 16) + // length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    '\x00\x00\x00\x00' + // language 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    string32(format31012.length / 12); // nGroups 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return cmap + '\x00\x04' + // format 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  string16(format314.length + 4) + // length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  format314 + header31012 + format31012; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function validateOS2Table(os2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var stream = new Stream(os2.data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var version = stream.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // TODO verify all OS/2 tables fields, but currently we validate only those 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // that give us issues 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    stream.getBytes(60); // skipping type, misc sizes, panose, unicode ranges 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var selection = stream.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (version < 4 && (selection & 0x0300)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var firstChar = stream.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var lastChar = stream.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (firstChar > lastChar) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function copyCtxState(sourceCtx, destCtx) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var properties = ['strokeStyle', 'fillStyle', 'fillRule', 'globalAlpha', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      'lineWidth', 'lineCap', 'lineJoin', 'miterLimit', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      'globalCompositeOperation', 'font']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (var i = 0, ii = properties.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var property = properties[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (sourceCtx[property] !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        destCtx[property] = sourceCtx[property]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    stream.getBytes(6); // skipping sTypoAscender/Descender/LineGap 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var usWinAscent = stream.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (usWinAscent === 0) { // makes font unreadable by windows 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (sourceCtx.setLineDash !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      destCtx.setLineDash(sourceCtx.getLineDash()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      destCtx.lineDashOffset =  sourceCtx.lineDashOffset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else if (sourceCtx.mozDashOffset !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      destCtx.mozDash = sourceCtx.mozDash; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      destCtx.mozDashOffset = sourceCtx.mozDashOffset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // OS/2 appears to be valid, resetting some fields 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    os2.data[8] = os2.data[9] = 0; // IE rejects fonts if fsType != 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function createOS2Table(properties, charstrings, override) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    override = override || { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      unitsPerEm: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      yMax: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      yMin: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ascent: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      descent: 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function composeSMaskBackdrop(bytes, r0, g0, b0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var length = bytes.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (var i = 3; i < length; i += 4) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var alpha = bytes[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (alpha === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bytes[i - 3] = r0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bytes[i - 2] = g0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bytes[i - 1] = b0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else if (alpha < 255) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var alpha_ = 255 - alpha; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bytes[i - 3] = (bytes[i - 3] * alpha + r0 * alpha_) >> 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bytes[i - 2] = (bytes[i - 2] * alpha + g0 * alpha_) >> 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bytes[i - 1] = (bytes[i - 1] * alpha + b0 * alpha_) >> 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var ulUnicodeRange1 = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var ulUnicodeRange2 = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var ulUnicodeRange3 = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var ulUnicodeRange4 = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function composeSMaskAlpha(maskData, layerData, transferMap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var length = maskData.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var scale = 1 / 255; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (var i = 3; i < length; i += 4) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var alpha = transferMap ? transferMap[maskData[i]] : maskData[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      layerData[i] = (layerData[i] * alpha * scale) | 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var firstCharIndex = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var lastCharIndex = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function composeSMaskLuminosity(maskData, layerData, transferMap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var length = maskData.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (var i = 3; i < length; i += 4) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var y = (maskData[i - 3] * 77) +  // * 0.3 / 255 * 0x10000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              (maskData[i - 2] * 152) + // * 0.59 .... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              (maskData[i - 1] * 28);   // * 0.11 .... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      layerData[i] = transferMap ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (layerData[i] * transferMap[y >> 8]) >> 8 : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        (layerData[i] * y) >> 16; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (charstrings) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var code in charstrings) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        code |= 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (firstCharIndex > code || !firstCharIndex) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          firstCharIndex = code; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (lastCharIndex < code) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          lastCharIndex = code; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function genericComposeSMask(maskCtx, layerCtx, width, height, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                               subtype, backdrop, transferMap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var hasBackdrop = !!backdrop; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var r0 = hasBackdrop ? backdrop[0] : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var g0 = hasBackdrop ? backdrop[1] : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var b0 = hasBackdrop ? backdrop[2] : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var position = getUnicodeRangeFor(code); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (position < 32) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ulUnicodeRange1 |= 1 << position; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else if (position < 64) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ulUnicodeRange2 |= 1 << position - 32; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else if (position < 96) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ulUnicodeRange3 |= 1 << position - 64; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else if (position < 123) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ulUnicodeRange4 |= 1 << position - 96; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          error('Unicode ranges Bits > 123 are reserved for internal usage'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var composeFn; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (subtype === 'Luminosity') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      composeFn = composeSMaskLuminosity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // TODO 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      firstCharIndex = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      lastCharIndex = 255; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      composeFn = composeSMaskAlpha; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var bbox = properties.bbox || [0, 0, 0, 0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var unitsPerEm = (override.unitsPerEm || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      1 / (properties.fontMatrix || FONT_IDENTITY_MATRIX)[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // processing image in chunks to save memory 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var PIXELS_TO_PROCESS = 1048576; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var chunkSize = Math.min(height, Math.ceil(PIXELS_TO_PROCESS / width)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (var row = 0; row < height; row += chunkSize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var chunkHeight = Math.min(chunkSize, height - row); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var maskData = maskCtx.getImageData(0, row, width, chunkHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var layerData = layerCtx.getImageData(0, row, width, chunkHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // if the font units differ to the PDF glyph space units 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // then scale up the values 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var scale = (properties.ascentScaled ? 1.0 : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                 unitsPerEm / PDF_GLYPH_SPACE_UNITS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (hasBackdrop) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        composeSMaskBackdrop(maskData.data, r0, g0, b0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      composeFn(maskData.data, layerData.data, transferMap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var typoAscent = (override.ascent || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      Math.round(scale * (properties.ascent || bbox[3]))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var typoDescent = (override.descent || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                       Math.round(scale * (properties.descent || bbox[1]))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (typoDescent > 0 && properties.descent > 0 && bbox[1] < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      typoDescent = -typoDescent; // fixing incorrect descent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      maskCtx.putImageData(layerData, 0, row); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var winAscent = override.yMax || typoAscent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var winDescent = -override.yMin || -typoDescent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return '\x00\x03' + // version 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x02\x24' + // xAvgCharWidth 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x01\xF4' + // usWeightClass 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x00\x05' + // usWidthClass 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x00\x00' + // fstype (0 to let the font loads via font-face on IE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x02\x8A' + // ySubscriptXSize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x02\xBB' + // ySubscriptYSize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x00\x00' + // ySubscriptXOffset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x00\x8C' + // ySubscriptYOffset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x02\x8A' + // ySuperScriptXSize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x02\xBB' + // ySuperScriptYSize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x00\x00' + // ySuperScriptXOffset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x01\xDF' + // ySuperScriptYOffset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x00\x31' + // yStrikeOutSize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x01\x02' + // yStrikeOutPosition 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x00\x00' + // sFamilyClass 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x00\x00\x06' + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           String.fromCharCode(properties.fixedPitch ? 0x09 : 0x00) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x00\x00\x00\x00\x00\x00' + // Panose 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           string32(ulUnicodeRange1) + // ulUnicodeRange1 (Bits 0-31) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           string32(ulUnicodeRange2) + // ulUnicodeRange2 (Bits 32-63) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           string32(ulUnicodeRange3) + // ulUnicodeRange3 (Bits 64-95) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           string32(ulUnicodeRange4) + // ulUnicodeRange4 (Bits 96-127) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x2A\x32\x31\x2A' + // achVendID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           string16(properties.italicAngle ? 1 : 0) + // fsSelection 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           string16(firstCharIndex || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    properties.firstChar) + // usFirstCharIndex 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           string16(lastCharIndex || properties.lastChar) +  // usLastCharIndex 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           string16(typoAscent) + // sTypoAscender 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           string16(typoDescent) + // sTypoDescender 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x00\x64' + // sTypoLineGap (7%-10% of the unitsPerEM value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           string16(winAscent) + // usWinAscent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           string16(winDescent) + // usWinDescent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x00\x00\x00\x00' + // ulCodePageRange1 (Bits 0-31) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x00\x00\x00\x00' + // ulCodePageRange2 (Bits 32-63) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           string16(properties.xHeight) + // sxHeight 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           string16(properties.capHeight) + // sCapHeight 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           string16(0) + // usDefaultChar 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           string16(firstCharIndex || properties.firstChar) + // usBreakChar 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-           '\x00\x03';  // usMaxContext 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function createPostTable(properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var angle = Math.floor(properties.italicAngle * (Math.pow(2, 16))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return ('\x00\x03\x00\x00' + // Version number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            string32(angle) + // italicAngle 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00' + // underlinePosition 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00' + // underlineThickness 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            string32(properties.fixedPitch) + // isFixedPitch 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00\x00\x00' + // minMemType42 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00\x00\x00' + // maxMemType42 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00\x00\x00' + // minMemType1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00\x00\x00');  // maxMemType1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function composeSMask(ctx, smask, layerCtx) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var mask = smask.canvas; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var maskCtx = smask.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function createNameTable(name, proto) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!proto) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      proto = [[], []]; // no strings and unicode strings 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctx.setTransform(smask.scaleX, 0, 0, smask.scaleY, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                     smask.offsetX, smask.offsetY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var strings = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      proto[0][0] || 'Original licence',  // 0.Copyright 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      proto[0][1] || name,                // 1.Font family 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      proto[0][2] || 'Unknown',           // 2.Font subfamily (font weight) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      proto[0][3] || 'uniqueID',          // 3.Unique ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      proto[0][4] || name,                // 4.Full font name 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      proto[0][5] || 'Version 0.11',      // 5.Version 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      proto[0][6] || '',                  // 6.Postscript name 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      proto[0][7] || 'Unknown',           // 7.Trademark 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      proto[0][8] || 'Unknown',           // 8.Manufacturer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      proto[0][9] || 'Unknown'            // 9.Designer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var backdrop = smask.backdrop || null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!smask.transferMap && WebGLUtils.isEnabled) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var composed = WebGLUtils.composeSMask(layerCtx.canvas, mask, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        {subtype: smask.subtype, backdrop: backdrop}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.setTransform(1, 0, 0, 1, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.drawImage(composed, smask.offsetX, smask.offsetY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    genericComposeSMask(maskCtx, layerCtx, mask.width, mask.height, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        smask.subtype, backdrop, smask.transferMap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ctx.drawImage(mask, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Mac want 1-byte per character strings while Windows want 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 2-bytes per character, so duplicate the names table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var stringsUnicode = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var i, ii, j, jj, str; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (i = 0, ii = strings.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      str = proto[1][i] || strings[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var LINE_CAP_STYLES = ['butt', 'round', 'square']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var LINE_JOIN_STYLES = ['miter', 'round', 'bevel']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var NORMAL_CLIP = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var EO_CLIP = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var strBufUnicode = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (j = 0, jj = str.length; j < jj; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        strBufUnicode.push(string16(str.charCodeAt(j))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      stringsUnicode.push(strBufUnicode.join('')); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CanvasGraphics.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var names = [strings, stringsUnicode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var platforms = ['\x00\x01', '\x00\x03']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var encodings = ['\x00\x00', '\x00\x01']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var languages = ['\x00\x00', '\x04\x09']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    beginDrawing: function CanvasGraphics_beginDrawing(transform, viewport, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                       transparency) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // For pdfs that use blend modes we have to clear the canvas else certain 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // blend modes can look wrong since we'd be blending with a white 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // backdrop. The problem with a transparent backdrop though is we then 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // don't get sub pixel anti aliasing on text, creating temporary 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // transparent canvas when we have blend modes. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var width = this.ctx.canvas.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var height = this.ctx.canvas.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var namesRecordCount = strings.length * platforms.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var nameTable = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      '\x00\x00' +                           // format 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      string16(namesRecordCount) +           // Number of names Record 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      string16(namesRecordCount * 12 + 6);   // Storage 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.fillStyle = 'rgb(255, 255, 255)'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.fillRect(0, 0, width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Build the name records field 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var strOffset = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (i = 0, ii = platforms.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var strs = names[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (j = 0, jj = strs.length; j < jj; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        str = strs[j]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var nameRecord = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          platforms[i] + // platform ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          encodings[i] + // encoding ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          languages[i] + // language ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          string16(j) + // name ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          string16(str.length) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          string16(strOffset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        nameTable += nameRecord; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        strOffset += str.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (transparency) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var transparentCanvas = this.cachedCanvases.getCanvas( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          'transparent', width, height, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.compositeCtx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.transparentCanvas = transparentCanvas.canvas; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx = transparentCanvas.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // The transform can be applied before rendering, transferring it to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // the new canvas. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx.transform.apply(this.ctx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 this.compositeCtx.mozCurrentTransform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    nameTable += strings.join('') + stringsUnicode.join(''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return nameTable; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (transform) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx.transform.apply(this.ctx, transform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.transform.apply(this.ctx, viewport.transform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  Font.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    name: null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    font: null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    mimetype: null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    encoding: null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    get renderer() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var renderer = FontRendererFactory.create(this, SEAC_ANALYSIS_ENABLED); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return shadow(this, 'renderer', renderer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.baseTransform = this.ctx.mozCurrentTransform.slice(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    exportData: function Font_exportData() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // TODO remove enumerating of the properties, e.g. hardcode exact names. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var data = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var i in this) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (this.hasOwnProperty(i)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          data[i] = this[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.imageLayer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.imageLayer.beginLayout(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    checkAndRepair: function Font_checkAndRepair(name, font, properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function readTableEntry(file) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var tag = bytesToString(file.getBytes(4)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    executeOperatorList: function CanvasGraphics_executeOperatorList( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    operatorList, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    executionStartIdx, continueCallback, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    stepper) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var argsArray = operatorList.argsArray; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fnArray = operatorList.fnArray; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var i = executionStartIdx || 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var argsArrayLen = argsArray.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var checksum = file.getInt32() >>> 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var offset = file.getInt32() >>> 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var length = file.getInt32() >>> 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Sometimes the OperatorList to execute is empty. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (argsArrayLen === i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Read the table associated data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var previousPosition = file.pos; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        file.pos = file.start ? file.start : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        file.skip(offset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var data = file.getBytes(length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        file.pos = previousPosition; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (tag === 'head') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // clearing checksum adjustment 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          data[8] = data[9] = data[10] = data[11] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          data[17] |= 0x20; //Set font optimized for cleartype flag 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          tag: tag, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          checksum: checksum, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          length: length, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          offset: offset, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          data: data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var chunkOperations = (argsArrayLen - i > EXECUTION_STEPS && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                             typeof continueCallback === 'function'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var endTime = chunkOperations ? Date.now() + EXECUTION_TIME : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var steps = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function readOpenTypeHeader(ttf) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          version: bytesToString(ttf.getBytes(4)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          numTables: ttf.getUint16(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          searchRange: ttf.getUint16(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          entrySelector: ttf.getUint16(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          rangeShift: ttf.getUint16() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var commonObjs = this.commonObjs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var objs = this.objs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fnId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-       * Read the appropriate subtable from the cmap according to 9.6.6.4 from 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-       * PDF spec 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-       */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function readCmapTable(cmap, font, isSymbolicFont, hasEncoding) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!cmap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          warn('No cmap table available.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            platformId: -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            encodingId: -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            mappings: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            hasShortCmap: false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      while (true) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (stepper !== undefined && i === stepper.nextBreakPoint) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          stepper.breakIt(i, continueCallback); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var segment; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var start = (font.start ? font.start : 0) + cmap.offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        font.pos = start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var version = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var numTables = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fnId = fnArray[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var potentialTable; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var canBreak = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // There's an order of preference in terms of which cmap subtable to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // use: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // - non-symbolic fonts the preference is a 3,1 table then a 1,0 table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // - symbolic fonts the preference is a 3,0 table then a 1,0 table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // The following takes advantage of the fact that the tables are sorted 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // to work. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (var i = 0; i < numTables; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var platformId = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var encodingId = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var offset = font.getInt32() >>> 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var useTable = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (fnId !== OPS.dependency) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this[fnId].apply(this, argsArray[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var deps = argsArray[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (var n = 0, nn = deps.length; n < nn; n++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var depObjId = deps[n]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var common = depObjId[0] === 'g' && depObjId[1] === '_'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var objsPool = common ? commonObjs : objs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (platformId === 0 && encodingId === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            useTable = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // Continue the loop since there still may be a higher priority 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // table. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else if (platformId === 1 && encodingId === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            useTable = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // Continue the loop since there still may be a higher priority 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // table. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else if (platformId === 3 && encodingId === 1 && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                     ((!isSymbolicFont && hasEncoding) || !potentialTable)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            useTable = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (!isSymbolicFont) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              canBreak = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // If the promise isn't resolved yet, add the continueCallback 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // to the promise and bail out. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!objsPool.isResolved(depObjId)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              objsPool.get(depObjId, continueCallback); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              return i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else if (isSymbolicFont && platformId === 3 && encodingId === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            useTable = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            canBreak = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (useTable) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            potentialTable = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              platformId: platformId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              encodingId: encodingId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              offset: offset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (canBreak) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (potentialTable) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          font.pos = start + potentialTable.offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!potentialTable || font.peekByte() === -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          warn('Could not find a preferred cmap table.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            platformId: -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            encodingId: -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            mappings: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            hasShortCmap: false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var format = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var length = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var language = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        i++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var hasShortCmap = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var mappings = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var j, glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // If the entire operatorList was executed, stop as were done. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (i === argsArrayLen) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // TODO(mack): refactor this cmap subtable reading logic out 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (format === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (j = 0; j < 256; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var index = font.getByte(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (!index) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            mappings.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              charCode: j, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              glyphId: index 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          hasShortCmap = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else if (format === 4) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // re-creating the table in format 4 since the encoding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // might be changed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var segCount = (font.getUint16() >> 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          font.getBytes(6); // skipping range fields 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var segIndex, segments = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (segIndex = 0; segIndex < segCount; segIndex++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            segments.push({ end: font.getUint16() }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (segIndex = 0; segIndex < segCount; segIndex++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            segments[segIndex].start = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // If the execution took longer then a certain amount of time and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // `continueCallback` is specified, interrupt the execution. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (chunkOperations && ++steps > EXECUTION_STEPS) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (Date.now() > endTime) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            continueCallback(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          steps = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (segIndex = 0; segIndex < segCount; segIndex++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            segments[segIndex].delta = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // If the operatorList isn't executed completely yet OR the execution 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // time was short enough, do another execution round. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var offsetsCount = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (segIndex = 0; segIndex < segCount; segIndex++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            segment = segments[segIndex]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var rangeOffset = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (!rangeOffset) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              segment.offsetIndex = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    endDrawing: function CanvasGraphics_endDrawing() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var offsetIndex = (rangeOffset >> 1) - (segCount - segIndex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            segment.offsetIndex = offsetIndex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            offsetsCount = Math.max(offsetsCount, offsetIndex + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                    segment.end - segment.start + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.transparentCanvas) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx = this.compositeCtx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx.setTransform(1, 0, 0, 1, 0, 0); // Avoid apply transform twice 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx.drawImage(this.transparentCanvas, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.transparentCanvas = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var offsets = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (j = 0; j < offsetsCount; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            offsets.push(font.getUint16()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.cachedCanvases.clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      WebGLUtils.clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (segIndex = 0; segIndex < segCount; segIndex++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            segment = segments[segIndex]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            start = segment.start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var end = segment.end; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var delta = segment.delta; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            offsetIndex = segment.offsetIndex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.imageLayer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.imageLayer.endLayout(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            for (j = start; j <= end; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              if (j === 0xFFFF) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Graphics state 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setLineWidth: function CanvasGraphics_setLineWidth(width) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.lineWidth = width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.lineWidth = width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setLineCap: function CanvasGraphics_setLineCap(style) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.lineCap = LINE_CAP_STYLES[style]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setLineJoin: function CanvasGraphics_setLineJoin(style) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.lineJoin = LINE_JOIN_STYLES[style]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setMiterLimit: function CanvasGraphics_setMiterLimit(limit) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.miterLimit = limit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setDash: function CanvasGraphics_setDash(dashArray, dashPhase) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (ctx.setLineDash !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.setLineDash(dashArray); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.lineDashOffset = dashPhase; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.mozDash = dashArray; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.mozDashOffset = dashPhase; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setRenderingIntent: function CanvasGraphics_setRenderingIntent(intent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Maybe if we one day fully support color spaces this will be important 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // for now we can ignore. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // TODO set rendering intent? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setFlatness: function CanvasGraphics_setFlatness(flatness) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // There's no way to control this with canvas, but we can safely ignore. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // TODO set flatness? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setGState: function CanvasGraphics_setGState(states) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = 0, ii = states.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var state = states[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var key = state[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var value = state[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              glyphId = (offsetIndex < 0 ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                         j : offsets[offsetIndex + j - start]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              glyphId = (glyphId + delta) & 0xFFFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              if (glyphId === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        switch (key) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'LW': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.setLineWidth(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'LC': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.setLineCap(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'LJ': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.setLineJoin(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'ML': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.setMiterLimit(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'D': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.setDash(value[0], value[1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'RI': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.setRenderingIntent(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'FL': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.setFlatness(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'Font': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.setFont(value[0], value[1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'CA': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.current.strokeAlpha = state[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'ca': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.current.fillAlpha = state[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.ctx.globalAlpha = state[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'BM': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (value && value.name && (value.name !== 'Normal')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              var mode = value.name.replace(/([A-Z])/g, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                function(c) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  return '-' + c.toLowerCase(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              ).substring(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.ctx.globalCompositeOperation = mode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (this.ctx.globalCompositeOperation !== mode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                warn('globalCompositeOperation "' + mode + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                     '" is not supported'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				               } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              mappings.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                charCode: j, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                glyphId: glyphId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.ctx.globalCompositeOperation = 'source-over'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else if (format === 6) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // Format 6 is a 2-bytes dense mapping, which means the font data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // lives glue together even if they are pretty far in the unicode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // table. (This looks weird, so I can have missed something), this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // works on Linux but seems to fails on Mac so let's rewrite the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // cmap table to a 3-1-4 style 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var firstCode = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var entryCount = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (j = 0; j < entryCount; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            glyphId = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var charCode = firstCode + j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            mappings.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              charCode: charCode, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              glyphId: glyphId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          warn('cmap table has unsupported format: ' + format); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            platformId: -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            encodingId: -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            mappings: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            hasShortCmap: false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 'SMask': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (this.current.activeSMask) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.endSMaskGroup(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.current.activeSMask = value ? this.tempSMask : null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (this.current.activeSMask) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.beginSMaskGroup(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.tempSMask = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    beginSMaskGroup: function CanvasGraphics_beginSMaskGroup() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // removing duplicate entries 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        mappings.sort(function (a, b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return a.charCode - b.charCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (i = 1; i < mappings.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (mappings[i - 1].charCode === mappings[i].charCode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            mappings.splice(i, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            i--; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var activeSMask = this.current.activeSMask; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var drawnWidth = activeSMask.canvas.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var drawnHeight = activeSMask.canvas.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var cacheId = 'smaskGroupAt' + this.groupLevel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var scratchCanvas = this.cachedCanvases.getCanvas( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cacheId, drawnWidth, drawnHeight, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          platformId: potentialTable.platformId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          encodingId: potentialTable.encodingId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          mappings: mappings, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          hasShortCmap: hasShortCmap 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var currentCtx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var currentTransform = currentCtx.mozCurrentTransform; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function sanitizeMetrics(font, header, metrics, numGlyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!header) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (metrics) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            metrics.data = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var groupCtx = scratchCanvas.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      groupCtx.scale(1 / activeSMask.scaleX, 1 / activeSMask.scaleY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      groupCtx.translate(-activeSMask.offsetX, -activeSMask.offsetY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      groupCtx.transform.apply(groupCtx, currentTransform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        font.pos = (font.start ? font.start : 0) + header.offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        font.pos += header.length - 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var numOfMetrics = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      copyCtxState(currentCtx, groupCtx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx = groupCtx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.setGState([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ['BM', 'Normal'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ['ca', 1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ['CA', 1] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.groupStack.push(currentCtx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.groupLevel++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    endSMaskGroup: function CanvasGraphics_endSMaskGroup() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var groupCtx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.groupLevel--; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx = this.groupStack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (numOfMetrics > numGlyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          info('The numOfMetrics (' + numOfMetrics + ') should not be ' + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-               'greater than the numGlyphs (' + numGlyphs + ')'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // Reduce numOfMetrics if it is greater than numGlyphs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          numOfMetrics = numGlyphs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          header.data[34] = (numOfMetrics & 0xff00) >> 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          header.data[35] = numOfMetrics & 0x00ff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      composeSMask(this.ctx, this.current.activeSMask, groupCtx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      copyCtxState(groupCtx, this.ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    save: function CanvasGraphics_save() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var old = this.current; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.stateStack.push(old); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current = old.clone(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.activeSMask = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    restore: function CanvasGraphics_restore() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.stateStack.length !== 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (this.current.activeSMask !== null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.endSMaskGroup(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var numOfSidebearings = numGlyphs - numOfMetrics; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var numMissing = numOfSidebearings - 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ((metrics.length - numOfMetrics * 4) >> 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.current = this.stateStack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (numMissing > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // For each missing glyph, we set both the width and lsb to 0 (zero). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // Since we need to add two properties for each glyph, this explains 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // the use of |numMissing * 2| when initializing the typed array. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var entries = new Uint8Array(metrics.length + numMissing * 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          entries.set(metrics.data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          metrics.data = entries; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Ensure that the clipping path is reset (fixes issue6413.pdf). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.pendingClip = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.cachedGetSinglePixelWidth = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    transform: function CanvasGraphics_transform(a, b, c, d, e, f) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.transform(a, b, c, d, e, f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function sanitizeGlyph(source, sourceStart, sourceEnd, dest, destStart, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                             hintsValid) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (sourceEnd - sourceStart <= 12) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // glyph with data less than 12 is invalid one 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var glyf = source.subarray(sourceStart, sourceEnd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var contoursCount = (glyf[0] << 8) | glyf[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (contoursCount & 0x8000) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // complex glyph, writing as is 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          dest.set(glyf, destStart); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return glyf.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.cachedGetSinglePixelWidth = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var i, j = 10, flagsCount = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (i = 0; i < contoursCount; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var endPoint = (glyf[j] << 8) | glyf[j + 1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          flagsCount = endPoint + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          j += 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // skipping instructions 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var instructionsStart = j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var instructionsLength = (glyf[j] << 8) | glyf[j + 1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        j += 2 + instructionsLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var instructionsEnd = j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // validating flags 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var coordinatesLength = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (i = 0; i < flagsCount; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var flag = glyf[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (flag & 0xC0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // reserved flags must be zero, cleaning up 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            glyf[j - 1] = flag & 0x3F; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var xyLength = ((flag & 2) ? 1 : (flag & 16) ? 0 : 2) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                         ((flag & 4) ? 1 : (flag & 32) ? 0 : 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          coordinatesLength += xyLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (flag & 8) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var repeat = glyf[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            i += repeat; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            coordinatesLength += repeat * xyLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // glyph without coordinates will be rejected 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (coordinatesLength === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var glyphDataLength = j + coordinatesLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (glyphDataLength > glyf.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // not enough data for coordinates 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!hintsValid && instructionsLength > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          dest.set(glyf.subarray(0, instructionsStart), destStart); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          dest.set([0, 0], destStart + instructionsStart); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          dest.set(glyf.subarray(instructionsEnd, glyphDataLength), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                   destStart + instructionsStart + 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          glyphDataLength -= instructionsLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (glyf.length - glyphDataLength > 3) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            glyphDataLength = (glyphDataLength + 3) & ~3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return glyphDataLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (glyf.length - glyphDataLength > 3) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // truncating and aligning to 4 bytes the long glyph data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          glyphDataLength = (glyphDataLength + 3) & ~3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          dest.set(glyf.subarray(0, glyphDataLength), destStart); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return glyphDataLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Path 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    constructPath: function CanvasGraphics_constructPath(ops, args) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var current = this.current; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var x = current.x, y = current.y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = 0, j = 0, ii = ops.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        switch (ops[i] | 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case OPS.rectangle: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x = args[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            y = args[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var width = args[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var height = args[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (width === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              width = this.getSinglePixelWidth(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (height === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              height = this.getSinglePixelWidth(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var xw = x + width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var yh = y + height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.ctx.moveTo(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.ctx.lineTo(xw, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.ctx.lineTo(xw, yh); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.ctx.lineTo(x, yh); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.ctx.lineTo(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.ctx.closePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case OPS.moveTo: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x = args[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            y = args[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ctx.moveTo(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case OPS.lineTo: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x = args[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            y = args[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ctx.lineTo(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case OPS.curveTo: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x = args[j + 4]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            y = args[j + 5]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ctx.bezierCurveTo(args[j], args[j + 1], args[j + 2], args[j + 3], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                              x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            j += 6; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case OPS.curveTo2: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ctx.bezierCurveTo(x, y, args[j], args[j + 1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                              args[j + 2], args[j + 3]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x = args[j + 2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            y = args[j + 3]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            j += 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case OPS.curveTo3: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x = args[j + 2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            y = args[j + 3]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ctx.bezierCurveTo(args[j], args[j + 1], x, y, x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            j += 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case OPS.closePath: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ctx.closePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // glyph data is fine 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        dest.set(glyf, destStart); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return glyf.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      current.setCurrentPoint(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    closePath: function CanvasGraphics_closePath() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.closePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    stroke: function CanvasGraphics_stroke(consumePath) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      consumePath = typeof consumePath !== 'undefined' ? consumePath : true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var strokeColor = this.current.strokeColor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Prevent drawing too thin lines by enforcing a minimum line width. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.lineWidth = Math.max(this.getSinglePixelWidth() * MIN_WIDTH_FACTOR, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                               this.current.lineWidth); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // For stroke we want to temporarily change the global alpha to the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // stroking alpha. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.globalAlpha = this.current.strokeAlpha; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (strokeColor && strokeColor.hasOwnProperty('type') && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          strokeColor.type === 'Pattern') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // for patterns, we transform to pattern space, calculate 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // the pattern, call stroke, and restore to user space 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.strokeStyle = strokeColor.getPattern(ctx, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.stroke(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.stroke(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (consumePath) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.consumePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Restore the global alpha to the fill alpha 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.globalAlpha = this.current.fillAlpha; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    closeStroke: function CanvasGraphics_closeStroke() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.closePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.stroke(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fill: function CanvasGraphics_fill(consumePath) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      consumePath = typeof consumePath !== 'undefined' ? consumePath : true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fillColor = this.current.fillColor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var isPatternFill = this.current.patternFill; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var needRestore = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function sanitizeHead(head, numGlyphs, locaLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var data = head.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Validate version: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Should always be 0x00010000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var version = int32(data[0], data[1], data[2], data[3]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (version >> 16 !== 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          info('Attempting to fix invalid version in head table: ' + version); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          data[0] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          data[1] = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          data[2] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          data[3] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var indexToLocFormat = int16(data[50], data[51]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (indexToLocFormat < 0 || indexToLocFormat > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          info('Attempting to fix invalid indexToLocFormat in head table: ' + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-               indexToLocFormat); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // The value of indexToLocFormat should be 0 if the loca table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // consists of short offsets, and should be 1 if the loca table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // consists of long offsets. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // The number of entries in the loca table should be numGlyphs + 1. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // Using this information, we can work backwards to deduce if the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // size of each offset in the loca table, and thus figure out the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // appropriate value for indexToLocFormat. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var numGlyphsPlusOne = numGlyphs + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (locaLength === numGlyphsPlusOne << 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // 0x0000 indicates the loca table consists of short offsets 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            data[50] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            data[51] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else if (locaLength === numGlyphsPlusOne << 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // 0x0001 indicates the loca table consists of long offsets 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            data[50] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            data[51] = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            warn('Could not fix indexToLocFormat: ' + indexToLocFormat); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (isPatternFill) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (this.baseTransform) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ctx.setTransform.apply(ctx, this.baseTransform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.fillStyle = fillColor.getPattern(ctx, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        needRestore = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function sanitizeGlyphLocations(loca, glyf, numGlyphs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                      isGlyphLocationsLong, hintsValid, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                      dupFirstEntry) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var itemSize, itemDecode, itemEncode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (isGlyphLocationsLong) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          itemSize = 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          itemDecode = function fontItemDecodeLong(data, offset) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return (data[offset] << 24) | (data[offset + 1] << 16) | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                   (data[offset + 2] << 8) | data[offset + 3]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          itemEncode = function fontItemEncodeLong(data, offset, value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            data[offset] = (value >>> 24) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            data[offset + 1] = (value >> 16) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            data[offset + 2] = (value >> 8) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            data[offset + 3] = value & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.pendingEOFill) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ctx.mozFillRule !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ctx.mozFillRule = 'evenodd'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ctx.fill(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ctx.mozFillRule = 'nonzero'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          itemSize = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          itemDecode = function fontItemDecode(data, offset) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return (data[offset] << 9) | (data[offset + 1] << 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          itemEncode = function fontItemEncode(data, offset, value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            data[offset] = (value >> 9) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            data[offset + 1] = (value >> 1) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var locaData = loca.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var locaDataSize = itemSize * (1 + numGlyphs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // is loca.data too short or long? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (locaData.length !== locaDataSize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          locaData = new Uint8Array(locaDataSize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          locaData.set(loca.data.subarray(0, locaDataSize)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          loca.data = locaData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ctx.fill('evenodd'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // removing the invalid glyphs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var oldGlyfData = glyf.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var oldGlyfDataLength = oldGlyfData.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var newGlyfData = new Uint8Array(oldGlyfDataLength); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var startOffset = itemDecode(locaData, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var writeOffset = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var missingGlyphData = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        itemEncode(locaData, 0, writeOffset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var i, j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var endOffset = itemDecode(locaData, j); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (endOffset > oldGlyfDataLength && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              ((oldGlyfDataLength + 3) & ~3) === endOffset) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // Aspose breaks fonts by aligning the glyphs to the qword, but not 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // the glyf table size, which makes last glyph out of range. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            endOffset = oldGlyfDataLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (endOffset > oldGlyfDataLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // glyph end offset points outside glyf data, rejecting the glyph 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            itemEncode(locaData, j, writeOffset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            startOffset = endOffset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.pendingEOFill = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.fill(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (startOffset === endOffset) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            missingGlyphData[i] = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (needRestore) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (consumePath) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.consumePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    eoFill: function CanvasGraphics_eoFill() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.pendingEOFill = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.fill(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    fillStroke: function CanvasGraphics_fillStroke() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.fill(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.stroke(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var newLength = sanitizeGlyph(oldGlyfData, startOffset, endOffset, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                        newGlyfData, writeOffset, hintsValid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          writeOffset += newLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          itemEncode(locaData, j, writeOffset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          startOffset = endOffset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.consumePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    eoFillStroke: function CanvasGraphics_eoFillStroke() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.pendingEOFill = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.fillStroke(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    closeFillStroke: function CanvasGraphics_closeFillStroke() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.closePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.fillStroke(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    closeEOFillStroke: function CanvasGraphics_closeEOFillStroke() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.pendingEOFill = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.closePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.fillStroke(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    endPath: function CanvasGraphics_endPath() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.consumePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (writeOffset === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // glyf table cannot be empty -- redoing the glyf and loca tables 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // to have single glyph with one point 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var simpleGlyph = new Uint8Array( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            itemEncode(locaData, j, simpleGlyph.length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          glyf.data = simpleGlyph; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return missingGlyphData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Clipping 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    clip: function CanvasGraphics_clip() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.pendingClip = NORMAL_CLIP; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    eoClip: function CanvasGraphics_eoClip() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.pendingClip = EO_CLIP; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (dupFirstEntry) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var firstEntryLength = itemDecode(locaData, itemSize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (newGlyfData.length > firstEntryLength + writeOffset) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            glyf.data = newGlyfData.subarray(0, firstEntryLength + writeOffset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            glyf.data = new Uint8Array(firstEntryLength + writeOffset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            glyf.data.set(newGlyfData.subarray(0, writeOffset)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          glyf.data.set(newGlyfData.subarray(0, firstEntryLength), writeOffset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          itemEncode(loca.data, locaData.length - itemSize, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                     writeOffset + firstEntryLength); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          glyf.data = newGlyfData.subarray(0, writeOffset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return missingGlyphData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Text 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    beginText: function CanvasGraphics_beginText() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.textMatrix = IDENTITY_MATRIX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.textMatrixScale = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.x = this.current.lineX = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.y = this.current.lineY = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    endText: function CanvasGraphics_endText() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var paths = this.pendingTextPaths; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (paths === undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.beginPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function readPostScriptTable(post, properties, maxpNumGlyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var start = (font.start ? font.start : 0) + post.offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        font.pos = start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.beginPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = 0; i < paths.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var path = paths[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.setTransform.apply(ctx, path.transform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.translate(path.x, path.y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        path.addToPath(ctx, path.fontSize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.clip(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.beginPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      delete this.pendingTextPaths; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setCharSpacing: function CanvasGraphics_setCharSpacing(spacing) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.charSpacing = spacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setWordSpacing: function CanvasGraphics_setWordSpacing(spacing) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.wordSpacing = spacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setHScale: function CanvasGraphics_setHScale(scale) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.textHScale = scale / 100; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setLeading: function CanvasGraphics_setLeading(leading) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.leading = -leading; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setFont: function CanvasGraphics_setFont(fontRefName, size) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fontObj = this.commonObjs.get(fontRefName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var current = this.current; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var length = post.length, end = start + length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var version = font.getInt32(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // skip rest to the tables 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        font.getBytes(28); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!fontObj) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        error('Can\'t find font for ' + fontRefName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var glyphNames; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var valid = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      current.fontMatrix = (fontObj.fontMatrix ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            fontObj.fontMatrix : FONT_IDENTITY_MATRIX); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        switch (version) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case 0x00010000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            glyphNames = MacStandardGlyphOrdering; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case 0x00020000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var numGlyphs = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (numGlyphs !== maxpNumGlyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              valid = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var glyphNameIndexes = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            for (i = 0; i < numGlyphs; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              var index = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              if (index >= 32768) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                valid = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              glyphNameIndexes.push(index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (!valid) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var customNames = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var strBuf = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            while (font.pos < end) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              var stringLength = font.getByte(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              strBuf.length = stringLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              for (i = 0; i < stringLength; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                strBuf[i] = String.fromCharCode(font.getByte()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              customNames.push(strBuf.join('')); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            glyphNames = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            for (i = 0; i < numGlyphs; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              var j = glyphNameIndexes[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              if (j < 258) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                glyphNames.push(MacStandardGlyphOrdering[j]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              glyphNames.push(customNames[j - 258]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case 0x00030000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            warn('Unknown/unsupported post table version ' + version); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            valid = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (properties.defaultEncoding) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              glyphNames = properties.defaultEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        properties.glyphNames = glyphNames; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return valid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // A valid matrix needs all main diagonal elements to be non-zero 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // This also ensures we bypass FF bugzilla bug #719844. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (current.fontMatrix[0] === 0 || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          current.fontMatrix[3] === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        warn('Invalid font matrix for font ' + fontRefName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function readNameTable(nameTable) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var start = (font.start ? font.start : 0) + nameTable.offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        font.pos = start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // The spec for Tf (setFont) says that 'size' specifies the font 'scale', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // and in some docs this can be negative (inverted x-y axes). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (size < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        size = -size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        current.fontDirection = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        current.fontDirection = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var names = [[], []]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var length = nameTable.length, end = start + length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var format = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var FORMAT_0_HEADER_LENGTH = 6; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (format !== 0 || length < FORMAT_0_HEADER_LENGTH) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // unsupported name table format or table "too" small 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return names; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var numRecords = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var stringsStart = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var records = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var NAME_RECORD_LENGTH = 12; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var i, ii; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.font = fontObj; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.fontSize = size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (i = 0; i < numRecords && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        font.pos + NAME_RECORD_LENGTH <= end; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var r = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            platform: font.getUint16(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            encoding: font.getUint16(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            language: font.getUint16(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            name: font.getUint16(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            length: font.getUint16(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            offset: font.getUint16() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // using only Macintosh and Windows platform/encoding names 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if ((r.platform === 1 && r.encoding === 0 && r.language === 0) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              (r.platform === 3 && r.encoding === 1 && r.language === 0x409)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            records.push(r); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (i = 0, ii = records.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var record = records[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (record.length <= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            continue; // Nothing to process, ignoring. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var pos = start + stringsStart + record.offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (pos + record.length > end) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            continue; // outside of name table, ignoring 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          font.pos = pos; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var nameIndex = record.name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (record.encoding) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // unicode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var str = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            for (var j = 0, jj = record.length; j < jj; j += 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              str += String.fromCharCode(font.getUint16()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            names[1][nameIndex] = str; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            names[0][nameIndex] = bytesToString(font.getBytes(record.length)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return names; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (fontObj.isType3Font) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; // we don't need ctx.font for Type3 fonts 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var TTOpsStackDeltas = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, 0, 0, -2, -5, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        1, -1, -999, 0, 1, 0, -1, -2, 0, -1, -2, -1, -1, 0, -1, -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        0, 0, -999, -999, -1, -1, -1, -1, -2, -999, -2, -2, -999, 0, -2, -2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        0, 0, -2, 0, -2, 0, 0, 0, -2, -1, -1, 1, 1, 0, 0, -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, 0, -999, -1, -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        -2, -999, -999, -999, -999, -999, -1, -1, -2, -2, 0, 0, 0, 0, -1, -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        -999, -2, -2, 0, 0, -1, -2, -2, 0, 0, 0, -1, -1, -1, -2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 0xC0-DF == -1 and 0xE0-FF == -2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var name = fontObj.loadedName || 'sans-serif'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var bold = fontObj.black ? (fontObj.bold ? '900' : 'bold') : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 (fontObj.bold ? 'bold' : 'normal'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function sanitizeTTProgram(table, ttContext) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var data = table.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var i = 0, j, n, b, funcId, pc, lastEndf = 0, lastDeff = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var stack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var callstack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var functionsCalled = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var tooComplexToFollowFunctions = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ttContext.tooComplexToFollowFunctions; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var inFDEF = false, ifLevel = 0, inELSE = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (var ii = data.length; i < ii;) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var op = data[i++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // The TrueType instruction set docs can be found at 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // https://developer.apple.com/fonts/TTRefMan/RM05/Chap5.html 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (op === 0x40) { // NPUSHB - pushes n bytes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            n = data[i++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (inFDEF || inELSE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              i += n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              for (j = 0; j < n; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                stack.push(data[i++]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else if (op === 0x41) { // NPUSHW - pushes n words 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            n = data[i++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (inFDEF || inELSE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              i += n * 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              for (j = 0; j < n; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                b = data[i++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                stack.push((b << 8) | data[i++]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else if ((op & 0xF8) === 0xB0) { // PUSHB - pushes bytes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            n = op - 0xB0 + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (inFDEF || inELSE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              i += n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              for (j = 0; j < n; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                stack.push(data[i++]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else if ((op & 0xF8) === 0xB8) { // PUSHW - pushes words 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            n = op - 0xB8 + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (inFDEF || inELSE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              i += n * 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              for (j = 0; j < n; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                b = data[i++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                stack.push((b << 8) | data[i++]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else if (op === 0x2B && !tooComplexToFollowFunctions) { // CALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (!inFDEF && !inELSE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              // collecting inforamtion about which functions are used 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              funcId = stack[stack.length - 1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              ttContext.functionsUsed[funcId] = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              if (funcId in ttContext.functionsStackDeltas) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                stack.length += ttContext.functionsStackDeltas[funcId]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } else if (funcId in ttContext.functionsDefined && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                         functionsCalled.indexOf(funcId) < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                callstack.push({data: data, i: i, stackTop: stack.length - 1}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                functionsCalled.push(funcId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                pc = ttContext.functionsDefined[funcId]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                if (!pc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  warn('TT: CALL non-existent function'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  ttContext.hintsValid = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                data = pc.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                i = pc.i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else if (op === 0x2C && !tooComplexToFollowFunctions) { // FDEF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (inFDEF || inELSE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              warn('TT: nested FDEFs not allowed'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              tooComplexToFollowFunctions = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            inFDEF = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // collecting inforamtion about which functions are defined 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            lastDeff = i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            funcId = stack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ttContext.functionsDefined[funcId] = {data: data, i: i}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else if (op === 0x2D) { // ENDF - end of function 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (inFDEF) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              inFDEF = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              lastEndf = i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              pc = callstack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              if (!pc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                warn('TT: ENDF bad stack'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                ttContext.hintsValid = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              funcId = functionsCalled.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              data = pc.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              i = pc.i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              ttContext.functionsStackDeltas[funcId] = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                stack.length - pc.stackTop; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else if (op === 0x89) { // IDEF - instruction definition 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (inFDEF || inELSE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              warn('TT: nested IDEFs not allowed'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              tooComplexToFollowFunctions = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            inFDEF = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // recording it as a function to track ENDF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            lastDeff = i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else if (op === 0x58) { // IF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ++ifLevel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else if (op === 0x1B) { // ELSE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            inELSE = ifLevel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else if (op === 0x59) { // EIF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (inELSE === ifLevel) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              inELSE = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            --ifLevel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else if (op === 0x1C) { // JMPR 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (!inFDEF && !inELSE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              var offset = stack[stack.length - 1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              // only jumping forward to prevent infinite loop 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              if (offset > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                i += offset - 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // Adjusting stack not extactly, but just enough to get function id 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (!inFDEF && !inELSE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var stackDelta = op <= 0x8E ? TTOpsStackDeltas[op] : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              op >= 0xC0 && op <= 0xDF ? -1 : op >= 0xE0 ? -2 : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (op >= 0x71 && op <= 0x75) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              n = stack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              if (n === n) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                stackDelta = -n * 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            while (stackDelta < 0 && stack.length > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              stack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              stackDelta++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            while (stackDelta > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              stack.push(NaN); // pushing any number into stack 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              stackDelta--; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ttContext.tooComplexToFollowFunctions = tooComplexToFollowFunctions; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var content = [data]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (i > data.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          content.push(new Uint8Array(i - data.length)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (lastDeff > lastEndf) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          warn('TT: complementing a missing function tail'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // new function definition started, but not finished 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // complete function by [CLEAR, ENDF] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          content.push(new Uint8Array([0x22, 0x2D])); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        foldTTTable(table, content); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function checkInvalidFunctions(ttContext, maxFunctionDefs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (ttContext.tooComplexToFollowFunctions) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (ttContext.functionsDefined.length > maxFunctionDefs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          warn('TT: more functions defined than expected'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ttContext.hintsValid = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (var j = 0, jj = ttContext.functionsUsed.length; j < jj; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (j > maxFunctionDefs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            warn('TT: invalid function id: ' + j); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ttContext.hintsValid = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (ttContext.functionsUsed[j] && !ttContext.functionsDefined[j]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            warn('TT: undefined function: ' + j); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ttContext.hintsValid = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function foldTTTable(table, content) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (content.length > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // concatenating the content items 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var newLength = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var j, jj; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (j = 0, jj = content.length; j < jj; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            newLength += content[j].length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          newLength = (newLength + 3) & ~3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var result = new Uint8Array(newLength); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var pos = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (j = 0, jj = content.length; j < jj; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            result.set(content[j], pos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            pos += content[j].length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          table.data = result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          table.length = newLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function sanitizeTTPrograms(fpgm, prep, cvt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var ttContext = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          functionsDefined: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          functionsUsed: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          functionsStackDeltas: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          tooComplexToFollowFunctions: false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          hintsValid: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (fpgm) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          sanitizeTTProgram(fpgm, ttContext); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (prep) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          sanitizeTTProgram(prep, ttContext); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (fpgm) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          checkInvalidFunctions(ttContext, maxFunctionDefs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (cvt && (cvt.length & 1)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var cvtData = new Uint8Array(cvt.length + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          cvtData.set(cvt.data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          cvt.data = cvtData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return ttContext.hintsValid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var italic = fontObj.italic ? 'italic' : 'normal'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var typeface = '"' + name + '", ' + fontObj.fallbackName; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // The following steps modify the original font data, making copy 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      font = new Stream(new Uint8Array(font.getBytes())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Some font backends cannot handle fonts below certain size. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Keeping the font at minimal size and using the fontSizeScale to change 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // the current transformation matrix before the fillText/strokeText. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // See https://bugzilla.mozilla.org/show_bug.cgi?id=726227 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var browserFontSize = size < MIN_FONT_SIZE ? MIN_FONT_SIZE : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            size > MAX_FONT_SIZE ? MAX_FONT_SIZE : size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.fontSizeScale = size / browserFontSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var VALID_TABLES = ['OS/2', 'cmap', 'head', 'hhea', 'hmtx', 'maxp', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'name', 'post', 'loca', 'glyf', 'fpgm', 'prep', 'cvt ', 'CFF ']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var rule = italic + ' ' + bold + ' ' + browserFontSize + 'px ' + typeface; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.font = rule; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setTextRenderingMode: function CanvasGraphics_setTextRenderingMode(mode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.textRenderingMode = mode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setTextRise: function CanvasGraphics_setTextRise(rise) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.textRise = rise; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    moveText: function CanvasGraphics_moveText(x, y) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.x = this.current.lineX += x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.y = this.current.lineY += y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setLeadingMoveText: function CanvasGraphics_setLeadingMoveText(x, y) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.setLeading(-y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.moveText(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setTextMatrix: function CanvasGraphics_setTextMatrix(a, b, c, d, e, f) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.textMatrix = [a, b, c, d, e, f]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.textMatrixScale = Math.sqrt(a * a + b * b); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var header = readOpenTypeHeader(font); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var numTables = header.numTables; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var cff, cffFile; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.x = this.current.lineX = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.y = this.current.lineY = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    nextLine: function CanvasGraphics_nextLine() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.moveText(0, this.current.leading); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var tables = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      tables['OS/2'] = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      tables['cmap'] = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      tables['head'] = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      tables['hhea'] = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      tables['hmtx'] = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      tables['maxp'] = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      tables['name'] = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      tables['post'] = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    paintChar: function CanvasGraphics_paintChar(character, x, y) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var current = this.current; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var font = current.font; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var textRenderingMode = current.textRenderingMode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fontSize = current.fontSize / current.fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fillStrokeMode = textRenderingMode & 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        TextRenderingMode.FILL_STROKE_MASK; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var isAddToPathSet = !!(textRenderingMode & 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        TextRenderingMode.ADD_TO_PATH_FLAG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var table; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var i = 0; i < numTables; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        table = readTableEntry(font); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (VALID_TABLES.indexOf(table.tag) < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          continue; // skipping table if it's not a required or optional table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (table.length === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          continue; // skipping empty tables 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tables[table.tag] = table; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var addToPath; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (font.disableFontFace || isAddToPathSet) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        addToPath = font.getPathGenerator(this.commonObjs, character); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var isTrueType = !tables['CFF ']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!isTrueType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // OpenType font 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if ((header.version === 'OTTO' && properties.type !== 'CIDFontType2') || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            !tables['head'] || !tables['hhea'] || !tables['maxp'] || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            !tables['post']) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // no major tables: throwing everything at CFFFont 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          cffFile = new Stream(tables['CFF '].data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          cff = new CFFFont(cffFile, properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          adjustWidths(properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return this.convert(name, cff, properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (font.disableFontFace) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.translate(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.beginPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        addToPath(ctx, fontSize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (fillStrokeMode === TextRenderingMode.FILL || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            fillStrokeMode === TextRenderingMode.FILL_STROKE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ctx.fill(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        delete tables['glyf']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        delete tables['loca']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        delete tables['fpgm']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        delete tables['prep']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        delete tables['cvt ']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.isOpenType = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (fillStrokeMode === TextRenderingMode.STROKE || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            fillStrokeMode === TextRenderingMode.FILL_STROKE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ctx.stroke(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!tables['loca']) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          error('Required "loca" table is not found'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (fillStrokeMode === TextRenderingMode.FILL || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            fillStrokeMode === TextRenderingMode.FILL_STROKE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ctx.fillText(character, x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!tables['glyf']) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          warn('Required "glyf" table is not found -- trying to recover.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // Note: We use `sanitizeGlyphLocations` to add dummy glyf data below. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          tables['glyf'] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            tag: 'glyf', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            data: new Uint8Array(0), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (fillStrokeMode === TextRenderingMode.STROKE || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            fillStrokeMode === TextRenderingMode.FILL_STROKE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ctx.strokeText(character, x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.isOpenType = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!tables['maxp']) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        error('Required "maxp" table is not found'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (isAddToPathSet) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var paths = this.pendingTextPaths || (this.pendingTextPaths = []); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        paths.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          transform: ctx.mozCurrentTransform, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          x: x, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          y: y, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          fontSize: fontSize, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          addToPath: addToPath 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      font.pos = (font.start || 0) + tables['maxp'].offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var version = font.getInt32(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var numGlyphs = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var maxFunctionDefs = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (version >= 0x00010000 && tables['maxp'].length >= 22) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // maxZones can be invalid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        font.pos += 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var maxZones = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (maxZones > 2) { // reset to 2 if font has invalid maxZones 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          tables['maxp'].data[14] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          tables['maxp'].data[15] = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    get isFontSubpixelAAEnabled() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Checks if anti-aliasing is enabled when scaled text is painted. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // On Windows GDI scaled fonts looks bad. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ctx = document.createElement('canvas').getContext('2d'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.scale(1.5, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.fillText('I', 0, 10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var data = ctx.getImageData(0, 0, 10, 10).data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var enabled = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = 3; i < data.length; i += 4) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (data[i] > 0 && data[i] < 255) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          enabled = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        font.pos += 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        maxFunctionDefs = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return shadow(this, 'isFontSubpixelAAEnabled', enabled); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var dupFirstEntry = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (properties.type === 'CIDFontType2' && properties.toUnicode && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          properties.toUnicode.get(0) > '\u0000') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // oracle's defect (see 3427), duplicating first entry 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        dupFirstEntry = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        numGlyphs++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tables['maxp'].data[4] = numGlyphs >> 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tables['maxp'].data[5] = numGlyphs & 255; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    showText: function CanvasGraphics_showText(glyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var current = this.current; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var font = current.font; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (font.isType3Font) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return this.showType3Text(glyphs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var hintsValid = sanitizeTTPrograms(tables['fpgm'], tables['prep'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                          tables['cvt '], maxFunctionDefs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!hintsValid) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        delete tables['fpgm']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        delete tables['prep']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        delete tables['cvt ']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fontSize = current.fontSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (fontSize === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Ensure the hmtx table contains the advance width and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // sidebearings information for numGlyphs in the maxp table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      sanitizeMetrics(font, tables['hhea'], tables['hmtx'], numGlyphs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fontSizeScale = current.fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var charSpacing = current.charSpacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var wordSpacing = current.wordSpacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fontDirection = current.fontDirection; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var textHScale = current.textHScale * fontDirection; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var glyphsLength = glyphs.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var vertical = font.vertical; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var spacingDir = vertical ? 1 : -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var defaultVMetrics = font.defaultVMetrics; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var widthAdvanceScale = fontSize * current.fontMatrix[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!tables['head']) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        error('Required "head" table is not found'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var simpleFillText = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        current.textRenderingMode === TextRenderingMode.FILL && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        !font.disableFontFace; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      sanitizeHead(tables['head'], numGlyphs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                   isTrueType ? tables['loca'].length : 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.transform.apply(ctx, current.textMatrix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.translate(current.x, current.y + current.textRise); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var missingGlyphs = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (isTrueType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var isGlyphLocationsLong = int16(tables['head'].data[50], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                         tables['head'].data[51]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        missingGlyphs = sanitizeGlyphLocations(tables['loca'], tables['glyf'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                               numGlyphs, isGlyphLocationsLong, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                               hintsValid, dupFirstEntry); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (current.patternFill) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // TODO: Some shading patterns are not applied correctly to text, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        //       e.g. issues 3988 and 5432, and ShowText-ShadingPattern.pdf. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.fillStyle = current.fillColor.getPattern(ctx, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!tables['hhea']) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        error('Required "hhea" table is not found'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (fontDirection > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.scale(textHScale, -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.scale(textHScale, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Sanitizer reduces the glyph advanceWidth to the maxAdvanceWidth 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Sometimes it's 0. That needs to be fixed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (tables['hhea'].data[10] === 0 && tables['hhea'].data[11] === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tables['hhea'].data[10] = 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tables['hhea'].data[11] = 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var lineWidth = current.lineWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var scale = current.textMatrixScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (scale === 0 || lineWidth === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var fillStrokeMode = current.textRenderingMode & 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          TextRenderingMode.FILL_STROKE_MASK; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (fillStrokeMode === TextRenderingMode.STROKE || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            fillStrokeMode === TextRenderingMode.FILL_STROKE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.cachedGetSinglePixelWidth = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          lineWidth = this.getSinglePixelWidth() * MIN_WIDTH_FACTOR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        lineWidth /= scale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Extract some more font properties from the OpenType head and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // hhea tables; yMin and descent value are always negative. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var metricsOverride = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        unitsPerEm: int16(tables['head'].data[18], tables['head'].data[19]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        yMax: int16(tables['head'].data[42], tables['head'].data[43]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        yMin: signedInt16(tables['head'].data[38], tables['head'].data[39]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ascent: int16(tables['hhea'].data[4], tables['hhea'].data[5]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        descent: signedInt16(tables['hhea'].data[6], tables['hhea'].data[7]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (fontSizeScale !== 1.0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.scale(fontSizeScale, fontSizeScale); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        lineWidth /= fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // PDF FontDescriptor metrics lie -- using data from actual font. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ascent = metricsOverride.ascent / metricsOverride.unitsPerEm; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.descent = metricsOverride.descent / metricsOverride.unitsPerEm; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.lineWidth = lineWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // The 'post' table has glyphs names. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (tables['post']) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var valid = readPostScriptTable(tables['post'], properties, numGlyphs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!valid) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          tables['post'] = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var x = 0, i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (i = 0; i < glyphsLength; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var glyph = glyphs[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (isNum(glyph)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          x += spacingDir * glyph * fontSize / 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var charCodeToGlyphId = [], charCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var toUnicode = properties.toUnicode, widths = properties.widths; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var skipToUnicode = (toUnicode instanceof IdentityToUnicodeMap || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                           toUnicode.length === 0x10000); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var restoreNeeded = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var character = glyph.fontChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var accent = glyph.accent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var scaledX, scaledY, scaledAccentX, scaledAccentY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var width = glyph.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (vertical) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var vmetric, vx, vy; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          vmetric = glyph.vmetric || defaultVMetrics; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          vx = glyph.vmetric ? vmetric[1] : width * 0.5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          vx = -vx * widthAdvanceScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          vy = vmetric[2] * widthAdvanceScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Helper function to try to skip mapping of empty glyphs. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Note: In some cases, just relying on the glyph data doesn't work, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      //       hence we also use a few heuristics to fix various PDF files. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function hasGlyph(glyphId, charCode, widthCode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!missingGlyphs[glyphId]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!skipToUnicode && charCode >= 0 && toUnicode.has(charCode)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (widths && widthCode >= 0 && isNum(widths[widthCode])) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          width = vmetric ? -vmetric[0] : width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          scaledX = vx / fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          scaledY = (x + vy) / fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          scaledX = x / fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          scaledY = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Some bad PDF generators, e.g. Scribus PDF, include glyph names 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // in a 'uniXXXX' format -- attempting to recover proper ones. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function recoverGlyphName(name, glyphsUnicodeMap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (glyphsUnicodeMap[name] !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (font.remeasure && width > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Some standard fonts may not have the exact width: rescale per 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // character if measured width is greater than expected glyph width 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // and subpixel-aa is enabled, otherwise just center the glyph. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var measuredWidth = ctx.measureText(character).width * 1000 / 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            fontSize * fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (width < measuredWidth && this.isFontSubpixelAAEnabled) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var characterScaleX = width / measuredWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            restoreNeeded = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ctx.scale(characterScaleX, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            scaledX /= characterScaleX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (width !== measuredWidth) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            scaledX += (width - measuredWidth) / 2000 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              fontSize / fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // The glyph name is non-standard, trying to recover. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var unicode = getUnicodeForGlyph(name, glyphsUnicodeMap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (unicode !== -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (var key in glyphsUnicodeMap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (glyphsUnicodeMap[key] === unicode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              return key; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Only attempt to draw the glyph if it is actually in the embedded font 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // file or if there isn't a font file so the fallback font is shown. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (glyph.isInFont || font.missingFile) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (simpleFillText && !accent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // common case 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ctx.fillText(character, scaledX, scaledY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            this.paintChar(character, scaledX, scaledY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (accent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              scaledAccentX = scaledX + accent.offset.x / fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              scaledAccentY = scaledY - accent.offset.y / fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              this.paintChar(accent.fontChar, scaledAccentX, scaledAccentY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        warn('Unable to recover a standard glyph name for: ' + name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (properties.type === 'CIDFontType2') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var cidToGidMap = properties.cidToGidMap || []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var isCidToGidMapEmpty = cidToGidMap.length === 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        properties.cMap.forEach(function(charCode, cid) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          assert(cid <= 0xffff, 'Max size of CID is 65,535'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var glyphId = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (isCidToGidMapEmpty) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            glyphId = cid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else if (cidToGidMap[cid] !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            glyphId = cidToGidMap[cid]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var charWidth = width * widthAdvanceScale + spacing * fontDirection; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        x += charWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (glyphId >= 0 && glyphId < numGlyphs && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              hasGlyph(glyphId, charCode, cid)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            charCodeToGlyphId[charCode] = glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (dupFirstEntry) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          charCodeToGlyphId[0] = numGlyphs - 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (restoreNeeded) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (vertical) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        current.y -= x * textHScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Most of the following logic in this code branch is based on the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // 9.6.6.4 of the PDF spec. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var hasEncoding = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          properties.differences.length > 0 || !!properties.baseEncodingName; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var cmapTable = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          readCmapTable(tables['cmap'], font, this.isSymbolicFont, hasEncoding); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var cmapPlatformId = cmapTable.platformId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var cmapEncodingId = cmapTable.encodingId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var cmapMappings = cmapTable.mappings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var cmapMappingsLength = cmapMappings.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        current.x += x * textHScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // The spec seems to imply that if the font is symbolic the encoding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // should be ignored, this doesn't appear to work for 'preistabelle.pdf' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // where the the font is symbolic and it has an encoding. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (hasEncoding && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (cmapPlatformId === 3 && cmapEncodingId === 1 || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-             cmapPlatformId === 1 && cmapEncodingId === 0) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (cmapPlatformId === -1 && cmapEncodingId === -1 && // Temporary hack 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-             !!getEncoding(properties.baseEncodingName))) {    // Temporary hack 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // When no preferred cmap table was found and |baseEncodingName| is 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // one of the predefined encodings, we seem to obtain a better 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // |charCodeToGlyphId| map from the code below (fixes bug 1057544). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // TODO: Note that this is a hack which should be removed as soon as 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          //       we have proper support for more exotic cmap tables. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    showType3Text: function CanvasGraphics_showType3Text(glyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Type3 fonts - each glyph is a "mini-PDF" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var current = this.current; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var font = current.font; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fontSize = current.fontSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fontDirection = current.fontDirection; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var spacingDir = font.vertical ? 1 : -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var charSpacing = current.charSpacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var wordSpacing = current.wordSpacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var textHScale = current.textHScale * fontDirection; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fontMatrix = current.fontMatrix || FONT_IDENTITY_MATRIX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var glyphsLength = glyphs.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var isTextInvisible = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        current.textRenderingMode === TextRenderingMode.INVISIBLE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var i, glyph, width, spacingLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var baseEncoding = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (properties.baseEncodingName === 'MacRomanEncoding' || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              properties.baseEncodingName === 'WinAnsiEncoding') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            baseEncoding = getEncoding(properties.baseEncodingName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var glyphsUnicodeMap = getGlyphsUnicode(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (charCode = 0; charCode < 256; charCode++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var glyphName, standardGlyphName; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (this.differences && charCode in this.differences) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              glyphName = this.differences[charCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } else if (charCode in baseEncoding && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                       baseEncoding[charCode] !== '') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              glyphName = baseEncoding[charCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              glyphName = StandardEncoding[charCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (!glyphName) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // Ensure that non-standard glyph names are resolved to valid ones. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            standardGlyphName = recoverGlyphName(glyphName, glyphsUnicodeMap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (isTextInvisible || fontSize === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.cachedGetSinglePixelWidth = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var unicodeOrCharCode, isUnicode = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (cmapPlatformId === 3 && cmapEncodingId === 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              unicodeOrCharCode = glyphsUnicodeMap[standardGlyphName]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              isUnicode = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } else if (cmapPlatformId === 1 && cmapEncodingId === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              // TODO: the encoding needs to be updated with mac os table. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              unicodeOrCharCode = MacRomanEncoding.indexOf(standardGlyphName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.transform.apply(ctx, current.textMatrix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.translate(current.x, current.y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var found = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            for (i = 0; i < cmapMappingsLength; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              if (cmapMappings[i].charCode !== unicodeOrCharCode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              var code = isUnicode ? charCode : unicodeOrCharCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              if (hasGlyph(cmapMappings[i].glyphId, code, -1)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                charCodeToGlyphId[charCode] = cmapMappings[i].glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                found = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (!found && properties.glyphNames) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              // Try to map using the post table. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              var glyphId = properties.glyphNames.indexOf(glyphName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              // The post table ought to use the same kind of glyph names as the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              // `differences` array, but check the standard ones as a fallback. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              if (glyphId === -1 && standardGlyphName !== glyphName) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                glyphId = properties.glyphNames.indexOf(standardGlyphName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              if (glyphId > 0 && hasGlyph(glyphId, -1, -1)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                charCodeToGlyphId[charCode] = glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                found = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (!found) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              charCodeToGlyphId[charCode] = 0; // notdef 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else if (cmapPlatformId === 0 && cmapEncodingId === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // Default Unicode semantics, use the charcodes as is. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (i = 0; i < cmapMappingsLength; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            charCodeToGlyphId[cmapMappings[i].charCode] = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              cmapMappings[i].glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // For (3, 0) cmap tables: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // The charcode key being stored in charCodeToGlyphId is the lower 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // byte of the two-byte charcodes of the cmap table since according to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // the spec: 'each byte from the string shall be prepended with the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // high byte of the range [of charcodes in the cmap table], to form 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // a two-byte character, which shall be used to select the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // associated glyph description from the subtable'. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // For (1, 0) cmap tables: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // 'single bytes from the string shall be used to look up the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // associated glyph descriptions from the subtable'. This means 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // charcodes in the cmap will be single bytes, so no-op since 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // glyph.charCode & 0xFF === glyph.charCode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (i = 0; i < cmapMappingsLength; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            charCode = cmapMappings[i].charCode & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            charCodeToGlyphId[charCode] = cmapMappings[i].glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.scale(textHScale, fontDirection); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (i = 0; i < glyphsLength; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        glyph = glyphs[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (isNum(glyph)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          spacingLength = spacingDir * glyph * fontSize / 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.ctx.translate(spacingLength, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          current.x += spacingLength * textHScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (charCodeToGlyphId.length === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // defines at least one glyph 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        charCodeToGlyphId[0] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var operatorList = font.charProcOperatorList[glyph.operatorListId]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!operatorList) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          warn('Type3 character \"' + glyph.operatorListId + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               '\" is not available'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.processingType3 = glyph; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.scale(fontSize, fontSize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.transform.apply(ctx, fontMatrix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.executeOperatorList(operatorList); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Converting glyphs and ids into font's cmap table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var newMapping = adjustMapping(charCodeToGlyphId, properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.toFontChar = newMapping.toFontChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      tables['cmap'] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tag: 'cmap', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        data: createCmapTable(newMapping.charCodeToGlyphId, numGlyphs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var transformed = Util.applyTransform([glyph.width, 0], fontMatrix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        width = transformed[0] * fontSize + spacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!tables['OS/2'] || !validateOS2Table(tables['OS/2'])) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tables['OS/2'] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          tag: 'OS/2', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          data: createOS2Table(properties, newMapping.charCodeToGlyphId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                               metricsOverride) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.translate(width, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        current.x += width * textHScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.processingType3 = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Rewrite the 'post' table if needed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!tables['post']) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tables['post'] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          tag: 'post', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          data: createPostTable(properties) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Type3 fonts 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setCharWidth: function CanvasGraphics_setCharWidth(xWidth, yWidth) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // We can safely ignore this since the width should be the same 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // as the width in the Widths array. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setCharWidthAndBounds: function CanvasGraphics_setCharWidthAndBounds(xWidth, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                                        yWidth, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                                        llx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                                        lly, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                                        urx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                                        ury) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // TODO According to the spec we're also suppose to ignore any operators 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // that set color or include images while processing this type3 font. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.rect(llx, lly, urx - llx, ury - lly); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.clip(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.endPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Color 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getColorN_Pattern: function CanvasGraphics_getColorN_Pattern(IR) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var pattern; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (IR[0] === 'TilingPattern') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var color = IR[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var baseTransform = this.baseTransform || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            this.ctx.mozCurrentTransform.slice(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var self = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var canvasGraphicsFactory = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          createCanvasGraphics: function (ctx) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return new CanvasGraphics(ctx, self.commonObjs, self.objs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        pattern = new TilingPattern(IR, color, this.ctx, canvasGraphicsFactory, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    baseTransform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        pattern = getShadingPatternFromIR(IR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return pattern; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setStrokeColorN: function CanvasGraphics_setStrokeColorN(/*...*/) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.strokeColor = this.getColorN_Pattern(arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setFillColorN: function CanvasGraphics_setFillColorN(/*...*/) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.fillColor = this.getColorN_Pattern(arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.patternFill = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setStrokeRGBColor: function CanvasGraphics_setStrokeRGBColor(r, g, b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var color = Util.makeCssRgb(r, g, b); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.strokeStyle = color; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.strokeColor = color; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    setFillRGBColor: function CanvasGraphics_setFillRGBColor(r, g, b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var color = Util.makeCssRgb(r, g, b); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx.fillStyle = color; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.fillColor = color; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current.patternFill = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!isTrueType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // Trying to repair CFF file 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          cffFile = new Stream(tables['CFF '].data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var parser = new CFFParser(cffFile, properties, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                     SEAC_ANALYSIS_ENABLED); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          cff = parser.parse(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var compiler = new CFFCompiler(cff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          tables['CFF '].data = compiler.compile(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } catch (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          warn('Failed to compile font ' + properties.loadedName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    shadingFill: function CanvasGraphics_shadingFill(patternIR) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Re-creating 'name' table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!tables['name']) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tables['name'] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          tag: 'name', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          data: createNameTable(this.name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var pattern = getShadingPatternFromIR(patternIR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.fillStyle = pattern.getPattern(ctx, this, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var inv = ctx.mozCurrentTransformInverse; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (inv) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var canvas = ctx.canvas; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var width = canvas.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var height = canvas.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var bl = Util.applyTransform([0, 0], inv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var br = Util.applyTransform([0, height], inv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var ul = Util.applyTransform([width, 0], inv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var ur = Util.applyTransform([width, height], inv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var x0 = Math.min(bl[0], br[0], ul[0], ur[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var y0 = Math.min(bl[1], br[1], ul[1], ur[1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var x1 = Math.max(bl[0], br[0], ul[0], ur[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var y1 = Math.max(bl[1], br[1], ul[1], ur[1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx.fillRect(x0, y0, x1 - x0, y1 - y0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // ... using existing 'name' table as prototype 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var namePrototype = readNameTable(tables['name']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tables['name'].data = createNameTable(name, namePrototype); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // HACK to draw the gradient onto an infinite rectangle. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // PDF gradients are drawn across the entire image while 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Canvas only allows gradients to be drawn in a rectangle 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // The following bug should allow us to remove this. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // https://bugzilla.mozilla.org/show_bug.cgi?id=664884 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var builder = new OpenTypeFileBuilder(header.version); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var tableTag in tables) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        builder.addTable(tableTag, tables[tableTag].data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx.fillRect(-1e10, -1e10, 2e10, 2e10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return builder.toArray(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    convert: function Font_convert(fontName, font, properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // TODO: Check the charstring widths to determine this. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      properties.fixedPitch = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Images 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    beginInlineImage: function CanvasGraphics_beginInlineImage() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      error('Should not call beginInlineImage'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    beginImageData: function CanvasGraphics_beginImageData() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      error('Should not call beginImageData'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var mapping = font.getGlyphMapping(properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var newMapping = adjustMapping(mapping, properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.toFontChar = newMapping.toFontChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var numGlyphs = font.numGlyphs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    paintFormXObjectBegin: function CanvasGraphics_paintFormXObjectBegin(matrix, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                                        bbox) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.baseTransformStack.push(this.baseTransform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function getCharCodes(charCodeToGlyphId, glyphId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var charCodes = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (var charCode in charCodeToGlyphId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (glyphId === charCodeToGlyphId[charCode]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (!charCodes) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              charCodes = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            charCodes.push(charCode | 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return charCodes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (isArray(matrix) && 6 === matrix.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.transform.apply(this, matrix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function createCharCode(charCodeToGlyphId, glyphId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (var charCode in charCodeToGlyphId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (glyphId === charCodeToGlyphId[charCode]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return charCode | 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        newMapping.charCodeToGlyphId[newMapping.nextAvailableFontCharCode] = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return newMapping.nextAvailableFontCharCode++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.baseTransform = this.ctx.mozCurrentTransform; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (isArray(bbox) && 4 === bbox.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var width = bbox[2] - bbox[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var height = bbox[3] - bbox[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx.rect(bbox[0], bbox[1], width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.clip(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.endPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var seacs = font.seacs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (SEAC_ANALYSIS_ENABLED && seacs && seacs.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var matrix = properties.fontMatrix || FONT_IDENTITY_MATRIX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var charset = font.getCharset(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var seacMap = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (var glyphId in seacs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          glyphId |= 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var seac = seacs[glyphId]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var baseGlyphName = StandardEncoding[seac[2]]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var accentGlyphName = StandardEncoding[seac[3]]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var baseGlyphId = charset.indexOf(baseGlyphName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var accentGlyphId = charset.indexOf(accentGlyphName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (baseGlyphId < 0 || accentGlyphId < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var accentOffset = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            x: seac[0] * matrix[0] + seac[1] * matrix[2] + matrix[4], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            y: seac[0] * matrix[1] + seac[1] * matrix[3] + matrix[5] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    paintFormXObjectEnd: function CanvasGraphics_paintFormXObjectEnd() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.baseTransform = this.baseTransformStack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var charCodes = getCharCodes(mapping, glyphId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (!charCodes) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // There's no point in mapping it if the char code was never mapped 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // to begin with. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (var i = 0, ii = charCodes.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var charCode = charCodes[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // Find a fontCharCode that maps to the base and accent glyphs. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // If one doesn't exists, create it. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var charCodeToGlyphId = newMapping.charCodeToGlyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var baseFontCharCode = createCharCode(charCodeToGlyphId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                  baseGlyphId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var accentFontCharCode = createCharCode(charCodeToGlyphId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                    accentGlyphId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            seacMap[charCode] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              baseFontCharCode: baseFontCharCode, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              accentFontCharCode: accentFontCharCode, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              accentOffset: accentOffset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        properties.seacMap = seacMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    beginGroup: function CanvasGraphics_beginGroup(group) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var currentCtx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // TODO non-isolated groups - according to Rik at adobe non-isolated 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // group results aren't usually that different and they even have tools 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // that ignore this setting. Notes from Rik on implmenting: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // - When you encounter an transparency group, create a new canvas with 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // the dimensions of the bbox 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // - copy the content from the previous canvas to the new canvas 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // - draw as usual 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // - remove the backdrop alpha: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // alphaNew = 1 - (1 - alpha)/(1 - alphaBackdrop) with 'alpha' the alpha 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // value of your transparency group and 'alphaBackdrop' the alpha of the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // backdrop 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // - remove background color: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // colorNew = color - alphaNew *colorBackdrop /(1 - alphaNew) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!group.isolated) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        info('TODO: Support non-isolated groups.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var unitsPerEm = 1 / (properties.fontMatrix || FONT_IDENTITY_MATRIX)[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // TODO knockout - supposedly possible with the clever use of compositing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // modes. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (group.knockout) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        warn('Knockout groups not supported.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var builder = new OpenTypeFileBuilder('\x4F\x54\x54\x4F'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // PostScript Font Program 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      builder.addTable('CFF ', font.data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // OS/2 and Windows Specific metrics 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      builder.addTable('OS/2', createOS2Table(properties, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                              newMapping.charCodeToGlyphId)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Character to glyphs mapping 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      builder.addTable('cmap', createCmapTable(newMapping.charCodeToGlyphId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                       numGlyphs)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Font header 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      builder.addTable('head', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x01\x00\x00' + // Version number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00\x10\x00' + // fontRevision 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00\x00\x00' + // checksumAdjustement 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x5F\x0F\x3C\xF5' + // magicNumber 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00' + // Flags 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            safeString16(unitsPerEm) + // unitsPerEM 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00\x00\x00\x9e\x0b\x7e\x27' + // creation date 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00\x00\x00\x9e\x0b\x7e\x27' + // modifification date 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00' + // xMin 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            safeString16(properties.descent) + // yMin 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x0F\xFF' + // xMax 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            safeString16(properties.ascent) + // yMax 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            string16(properties.italicAngle ? 2 : 0) + // macStyle 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x11' + // lowestRecPPEM 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00' + // fontDirectionHint 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00' + // indexToLocFormat 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00');  // glyphDataFormat 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Horizontal header 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      builder.addTable('hhea', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x01\x00\x00' + // Version number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            safeString16(properties.ascent) + // Typographic Ascent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            safeString16(properties.descent) + // Typographic Descent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00' + // Line Gap 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\xFF\xFF' + // advanceWidthMax 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00' + // minLeftSidebearing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00' + // minRightSidebearing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00' + // xMaxExtent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            safeString16(properties.capHeight) + // caretSlopeRise 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            safeString16(Math.tan(properties.italicAngle) * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                         properties.xHeight) + // caretSlopeRun 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00' + // caretOffset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00' + // -reserved- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00' + // -reserved- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00' + // -reserved- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00' + // -reserved- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00' + // metricDataFormat 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            string16(numGlyphs)); // Number of HMetrics 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Horizontal metrics 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      builder.addTable('hmtx', (function fontFieldsHmtx() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var charstrings = font.charstrings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var cffWidths = font.cff ? font.cff.widths : null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var hmtx = '\x00\x00\x00\x00'; // Fake .notdef 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (var i = 1, ii = numGlyphs; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var width = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (charstrings) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              var charstring = charstrings[i - 1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              width = 'width' in charstring ? charstring.width : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } else if (cffWidths) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              width = Math.ceil(cffWidths[i] || 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            hmtx += string16(width) + string16(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return hmtx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        })()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var currentTransform = currentCtx.mozCurrentTransform; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (group.matrix) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        currentCtx.transform.apply(currentCtx, group.matrix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      assert(group.bbox, 'Bounding box is required.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Maximum profile 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      builder.addTable('maxp', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            '\x00\x00\x50\x00' + // Version number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            string16(numGlyphs)); // Num of glyphs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Based on the current transform figure out how big the bounding box 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // will actually be. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var bounds = Util.getAxialAlignedBoundingBox( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    group.bbox, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    currentCtx.mozCurrentTransform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Clip the bounding box to the current canvas. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var canvasBounds = [0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          currentCtx.canvas.width, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          currentCtx.canvas.height]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      bounds = Util.intersect(bounds, canvasBounds) || [0, 0, 0, 0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Use ceil in case we're between sizes so we don't create canvas that is 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // too small and make the canvas at least 1x1 pixels. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var offsetX = Math.floor(bounds[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var offsetY = Math.floor(bounds[1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var drawnWidth = Math.max(Math.ceil(bounds[2]) - offsetX, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var drawnHeight = Math.max(Math.ceil(bounds[3]) - offsetY, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var scaleX = 1, scaleY = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (drawnWidth > MAX_GROUP_SIZE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        scaleX = drawnWidth / MAX_GROUP_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        drawnWidth = MAX_GROUP_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (drawnHeight > MAX_GROUP_SIZE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        scaleY = drawnHeight / MAX_GROUP_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        drawnHeight = MAX_GROUP_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Naming tables 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      builder.addTable('name', createNameTable(fontName)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var cacheId = 'groupAt' + this.groupLevel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (group.smask) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Using two cache entries is case if masks are used one after another. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cacheId +=  '_smask_' + ((this.smaskCounter++) % 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var scratchCanvas = this.cachedCanvases.getCanvas( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        cacheId, drawnWidth, drawnHeight, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var groupCtx = scratchCanvas.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // PostScript informations 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      builder.addTable('post', createPostTable(properties)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Since we created a new canvas that is just the size of the bounding box 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // we have to translate the group ctx. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      groupCtx.scale(1 / scaleX, 1 / scaleY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      groupCtx.translate(-offsetX, -offsetY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      groupCtx.transform.apply(groupCtx, currentTransform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return builder.toArray(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (group.smask) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Saving state and cached mask to be used in setGState. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.smaskStack.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          canvas: scratchCanvas.canvas, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          context: groupCtx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          offsetX: offsetX, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          offsetY: offsetY, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          scaleX: scaleX, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          scaleY: scaleY, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          subtype: group.smask.subtype, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          backdrop: group.smask.backdrop, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          transferMap: group.smask.transferMap || null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Setup the current ctx so when the group is popped we draw it at the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // right location. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        currentCtx.setTransform(1, 0, 0, 1, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        currentCtx.translate(offsetX, offsetY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        currentCtx.scale(scaleX, scaleY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // The transparency group inherits all off the current graphics state 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // except the blend mode, soft mask, and alpha constants. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      copyCtxState(currentCtx, groupCtx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx = groupCtx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.setGState([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ['BM', 'Normal'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ['ca', 1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ['CA', 1] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.groupStack.push(currentCtx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.groupLevel++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    get spaceWidth() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if ('_shadowWidth' in this) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return this._shadowWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    endGroup: function CanvasGraphics_endGroup(group) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.groupLevel--; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var groupCtx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ctx = this.groupStack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Turn off image smoothing to avoid sub pixel interpolation which can 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // look kind of blurry for some pdfs. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.ctx.imageSmoothingEnabled !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx.imageSmoothingEnabled = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx.mozImageSmoothingEnabled = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // trying to estimate space character width 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var possibleSpaceReplacements = ['space', 'minus', 'one', 'i']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var i = 0, ii = possibleSpaceReplacements.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var glyphName = possibleSpaceReplacements[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // if possible, getting width by glyph name 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (glyphName in this.widths) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          width = this.widths[glyphName]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var glyphsUnicodeMap = getGlyphsUnicode(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var glyphUnicode = glyphsUnicodeMap[glyphName]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // finding the charcode via unicodeToCID map 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var charcode = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (this.composite) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (this.cMap.contains(glyphUnicode)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            charcode = this.cMap.lookup(glyphUnicode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // ... via toUnicode map 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!charcode && this.toUnicode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          charcode = this.toUnicode.charCodeOf(glyphUnicode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // setting it to unicode if negative or undefined 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (charcode <= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          charcode = glyphUnicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // trying to get width via charcode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        width = this.widths[charcode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (width) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          break; // the non-zero width found 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (group.smask) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.tempSMask = this.smaskStack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx.drawImage(groupCtx.canvas, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      width = width || this.defaultWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Do not shadow the property here. See discussion: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // https://github.com/mozilla/pdf.js/pull/2127#discussion_r1662280 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this._shadowWidth = width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    charToGlyph: function Font_charToGlyph(charcode, isSpace) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fontCharCode, width, operatorListId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    beginAnnotations: function CanvasGraphics_beginAnnotations() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.current = new CanvasExtraState(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var widthCode = charcode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.cMap && this.cMap.contains(charcode)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        widthCode = this.cMap.lookup(charcode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.baseTransform) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx.setTransform.apply(this.ctx, this.baseTransform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      width = this.widths[widthCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      width = isNum(width) ? width : this.defaultWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var vmetric = this.vmetrics && this.vmetrics[widthCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var unicode = this.toUnicode.get(charcode) || charcode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (typeof unicode === 'number') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        unicode = String.fromCharCode(unicode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    endAnnotations: function CanvasGraphics_endAnnotations() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var isInFont = charcode in this.toFontChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // First try the toFontChar map, if it's not there then try falling 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // back to the char code. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      fontCharCode = this.toFontChar[charcode] || charcode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.missingFile) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fontCharCode = mapSpecialUnicodeValues(fontCharCode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    beginAnnotation: function CanvasGraphics_beginAnnotation(rect, transform, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                             matrix) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.isType3Font) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Font char code in this case is actually a glyph name. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        operatorListId = fontCharCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (isArray(rect) && 4 === rect.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var width = rect[2] - rect[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var height = rect[3] - rect[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx.rect(rect[0], rect[1], width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.clip(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.endPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var accent = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.seacMap && this.seacMap[charcode]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        isInFont = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var seac = this.seacMap[charcode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fontCharCode = seac.baseFontCharCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        accent = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          fontChar: String.fromCharCode(seac.accentFontCharCode), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          offset: seac.accentOffset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.transform.apply(this, transform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.transform.apply(this, matrix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    endAnnotation: function CanvasGraphics_endAnnotation() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    paintJpegXObject: function CanvasGraphics_paintJpegXObject(objId, w, h) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var domImage = this.objs.get(objId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!domImage) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        warn('Dependent image isn\'t ready yet'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fontChar = String.fromCharCode(fontCharCode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var glyph = this.glyphCache[charcode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!glyph || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          !glyph.matchesForCache(fontChar, unicode, accent, width, vmetric, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                 operatorListId, isSpace, isInFont)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        glyph = new Glyph(fontChar, unicode, accent, width, vmetric, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                          operatorListId, isSpace, isInFont); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.glyphCache[charcode] = glyph; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // scale the image to the unit square 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.scale(1 / w, -1 / h); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.drawImage(domImage, 0, 0, domImage.width, domImage.height, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    0, -h, w, h); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.imageLayer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var currentTransform = ctx.mozCurrentTransformInverse; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var position = this.getCanvasPosition(0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.imageLayer.appendImage({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          objId: objId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          left: position[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          top: position[1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          width: w / currentTransform[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          height: h / currentTransform[3] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return glyph; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    charsToGlyphs: function Font_charsToGlyphs(chars) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var charsCache = this.charsCache; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var glyphs, glyph, charcode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    paintImageMaskXObject: function CanvasGraphics_paintImageMaskXObject(img) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var width = img.width, height = img.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fillColor = this.current.fillColor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var isPatternFill = this.current.patternFill; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // if we translated this string before, just grab it from the cache 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (charsCache) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        glyphs = charsCache[chars]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (glyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return glyphs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var glyph = this.processingType3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (COMPILE_TYPE3_GLYPHS && glyph && glyph.compiled === undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (width <= MAX_SIZE_TO_COMPILE && height <= MAX_SIZE_TO_COMPILE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          glyph.compiled = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            compileType3Glyph({data: img.data, width: width, height: height}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          glyph.compiled = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // lazily create the translation cache 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!charsCache) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        charsCache = this.charsCache = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (glyph && glyph.compiled) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        glyph.compiled(ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      glyphs = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var charsCacheKey = chars; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var i = 0, ii; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var maskCanvas = this.cachedCanvases.getCanvas('maskCanvas', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                     width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var maskCtx = maskCanvas.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      maskCtx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.cMap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // composite fonts have multi-byte strings convert the string from 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // single-byte to multi-byte 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var c = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        while (i < chars.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          this.cMap.readCharCode(chars, i, c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          charcode = c.charcode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var length = c.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          i += length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // Space is char with code 0x20 and length 1 in multiple-byte codes. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var isSpace = length === 1 && chars.charCodeAt(i - 1) === 0x20; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          glyph = this.charToGlyph(charcode, isSpace); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          glyphs.push(glyph); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (i = 0, ii = chars.length; i < ii; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          charcode = chars.charCodeAt(i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          glyph = this.charToGlyph(charcode, charcode === 0x20); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          glyphs.push(glyph); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      putBinaryImageMask(maskCtx, img); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Enter the translated string into the cache 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return (charsCache[charsCacheKey] = glyphs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      maskCtx.globalCompositeOperation = 'source-in'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return Font; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      maskCtx.fillStyle = isPatternFill ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          fillColor.getPattern(maskCtx, this) : fillColor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      maskCtx.fillRect(0, 0, width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var ErrorFont = (function ErrorFontClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function ErrorFont(error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.error = error; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.loadedName = 'g_font_error'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.loading = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      maskCtx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  ErrorFont.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    charsToGlyphs: function ErrorFont_charsToGlyphs() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.paintInlineImageXObject(maskCanvas.canvas); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    exportData: function ErrorFont_exportData() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return {error: this.error}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return ErrorFont; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    paintImageMaskXObjectRepeat: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function CanvasGraphics_paintImageMaskXObjectRepeat(imgData, scaleX, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                          scaleY, positions) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var width = imgData.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var height = imgData.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fillColor = this.current.fillColor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var isPatternFill = this.current.patternFill; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * Shared logic for building a char code to glyph id mapping for Type1 and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * simple CFF fonts. See section 9.6.6.2 of the spec. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * @param {Object} properties Font properties object. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * @param {Object} builtInEncoding The encoding contained within the actual font 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * data. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * @param {Array} Array of glyph names where the index is the glyph ID. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- * @returns {Object} A char code to glyph ID map. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function type1FontGlyphMapping(properties, builtInEncoding, glyphNames) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var charCodeToGlyphId = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var glyphId, charCode, baseEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var maskCanvas = this.cachedCanvases.getCanvas('maskCanvas', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                     width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var maskCtx = maskCanvas.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      maskCtx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (properties.baseEncodingName) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // If a valid base encoding name was used, the mapping is initialized with 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // that. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    baseEncoding = getEncoding(properties.baseEncodingName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (charCode = 0; charCode < baseEncoding.length; charCode++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      glyphId = glyphNames.indexOf(baseEncoding[charCode]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (glyphId >= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        charCodeToGlyphId[charCode] = glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        charCodeToGlyphId[charCode] = 0; // notdef 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } else if (!!(properties.flags & FontFlags.Symbolic)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // For a symbolic font the encoding should be the fonts built-in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // encoding. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (charCode in builtInEncoding) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      charCodeToGlyphId[charCode] = builtInEncoding[charCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // For non-symbolic fonts that don't have a base encoding the standard 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // encoding should be used. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    baseEncoding = StandardEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (charCode = 0; charCode < baseEncoding.length; charCode++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      glyphId = glyphNames.indexOf(baseEncoding[charCode]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (glyphId >= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        charCodeToGlyphId[charCode] = glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        charCodeToGlyphId[charCode] = 0; // notdef 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      putBinaryImageMask(maskCtx, imgData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // Lastly, merge in the differences. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var differences = properties.differences; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (differences) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (charCode in differences) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var glyphName = differences[charCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      glyphId = glyphNames.indexOf(glyphName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (glyphId >= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        charCodeToGlyphId[charCode] = glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        charCodeToGlyphId[charCode] = 0; // notdef 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return charCodeToGlyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      maskCtx.globalCompositeOperation = 'source-in'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// Type1Font is also a CIDFontType0. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var Type1Font = (function Type1FontClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function findBlock(streamBytes, signature, startIndex) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var streamBytesLength = streamBytes.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var signatureLength = signature.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var scanLength = streamBytesLength - signatureLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      maskCtx.fillStyle = isPatternFill ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          fillColor.getPattern(maskCtx, this) : fillColor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      maskCtx.fillRect(0, 0, width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var i = startIndex, j, found = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    while (i < scanLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      j = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      while (j < signatureLength && streamBytes[i + j] === signature[j]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        j++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (j >= signatureLength) { // `signature` found, skip over whitespace. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        i += j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        while (i < streamBytesLength && Lexer.isSpace(streamBytes[i])) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          i++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        found = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      maskCtx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = 0, ii = positions.length; i < ii; i += 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.transform(scaleX, 0, 0, scaleY, positions[i], positions[i + 1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.scale(1, -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.drawImage(maskCanvas.canvas, 0, 0, width, height, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          0, -1, 1, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      i++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      found: found, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      length: i, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function getHeaderBlock(stream, suggestedLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var EEXEC_SIGNATURE = [0x65, 0x65, 0x78, 0x65, 0x63]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    paintImageMaskXObjectGroup: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function CanvasGraphics_paintImageMaskXObjectGroup(images) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var streamStartPos = stream.pos; // Save the initial stream position. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var headerBytes, headerBytesLength, block; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      headerBytes = stream.getBytes(suggestedLength); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      headerBytesLength = headerBytes.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } catch (ex) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (ex instanceof MissingDataException) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        throw ex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Ignore errors if the `suggestedLength` is huge enough that a Uint8Array 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // cannot hold the result of `getBytes`, and fallback to simply checking 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // the entire stream (fixes issue3928.pdf). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fillColor = this.current.fillColor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var isPatternFill = this.current.patternFill; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = 0, ii = images.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var image = images[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var width = image.width, height = image.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (headerBytesLength === suggestedLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Most of the time `suggestedLength` is correct, so to speed things up we 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // initially only check the last few bytes to see if the header was found. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Otherwise we (potentially) check the entire stream to prevent errors in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // `Type1Parser` (fixes issue5686.pdf). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      block = findBlock(headerBytes, EEXEC_SIGNATURE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        suggestedLength - 2 * EEXEC_SIGNATURE.length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var maskCanvas = this.cachedCanvases.getCanvas('maskCanvas', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                       width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var maskCtx = maskCanvas.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        maskCtx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (block.found && block.length === suggestedLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          stream: new Stream(headerBytes), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          length: suggestedLength, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    warn('Invalid "Length1" property in Type1 font -- trying to recover.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    stream.pos = streamStartPos; // Reset the stream position. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        putBinaryImageMask(maskCtx, image); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var SCAN_BLOCK_LENGTH = 2048; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var actualLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    while (true) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var scanBytes = stream.peekBytes(SCAN_BLOCK_LENGTH); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      block = findBlock(scanBytes, EEXEC_SIGNATURE, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        maskCtx.globalCompositeOperation = 'source-in'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (block.length === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      stream.pos += block.length; // Update the stream position. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (block.found) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        actualLength = stream.pos - streamStartPos; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    stream.pos = streamStartPos; // Reset the stream position. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (actualLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        stream: new Stream(stream.getBytes(actualLength)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        length: actualLength, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    warn('Unable to recover "Length1" property in Type1 font -- using as is.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      stream: new Stream(stream.getBytes(suggestedLength)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      length: suggestedLength, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function getEexecBlock(stream, suggestedLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // We should ideally parse the eexec block to ensure that `suggestedLength` 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // is correct, so we don't truncate the block data if it's too small. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // However, this would also require checking if the fixed-content portion 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // exists (using the 'Length3' property), and ensuring that it's valid. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Given that `suggestedLength` almost always is correct, all the validation 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // would require a great deal of unnecessary parsing for most fonts. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // To save time, we always fetch the entire stream instead, which also avoid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // issues if `suggestedLength` is huge (see comment in `getHeaderBlock`). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // NOTE: This means that the function can include the fixed-content portion 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // in the returned eexec block. In practice this does *not* seem to matter, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // since `Type1Parser_extractFontProgram` will skip over any non-commands. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var eexecBytes = stream.getBytes(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      stream: new Stream(eexecBytes), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      length: eexecBytes.length, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function Type1Font(name, file, properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Some bad generators embed pfb file as is, we have to strip 6-byte header. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Also, length1 and length2 might be off by 6 bytes as well. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // http://www.math.ubc.ca/~cass/piscript/type1.pdf 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var PFB_HEADER_SIZE = 6; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var headerBlockLength = properties.length1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var eexecBlockLength = properties.length2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var pfbHeader = file.peekBytes(PFB_HEADER_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var pfbHeaderPresent = pfbHeader[0] === 0x80 && pfbHeader[1] === 0x01; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (pfbHeaderPresent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      file.skip(PFB_HEADER_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      headerBlockLength = (pfbHeader[5] << 24) | (pfbHeader[4] << 16) | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                          (pfbHeader[3] << 8) | pfbHeader[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Get the data block containing glyphs and subrs informations 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var headerBlock = getHeaderBlock(file, headerBlockLength); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    headerBlockLength = headerBlock.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var headerBlockParser = new Type1Parser(headerBlock.stream, false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                            SEAC_ANALYSIS_ENABLED); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    headerBlockParser.extractFontHeader(properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (pfbHeaderPresent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      pfbHeader = file.getBytes(PFB_HEADER_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      eexecBlockLength = (pfbHeader[5] << 24) | (pfbHeader[4] << 16) | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                         (pfbHeader[3] << 8) | pfbHeader[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Decrypt the data blocks and retrieve it's content 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var eexecBlock = getEexecBlock(file, eexecBlockLength); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    eexecBlockLength = eexecBlock.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var eexecBlockParser = new Type1Parser(eexecBlock.stream, true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                           SEAC_ANALYSIS_ENABLED); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var data = eexecBlockParser.extractFontProgram(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (var info in data.properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      properties[info] = data.properties[info]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var charstrings = data.charstrings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var type2Charstrings = this.getType2Charstrings(charstrings); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var subrs = this.getType2Subrs(data.subrs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.charstrings = charstrings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.data = this.wrap(name, type2Charstrings, this.charstrings, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                          subrs, properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.seacs = this.getSeacs(data.charstrings); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        maskCtx.fillStyle = isPatternFill ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                            fillColor.getPattern(maskCtx, this) : fillColor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        maskCtx.fillRect(0, 0, width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  Type1Font.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    get numGlyphs() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return this.charstrings.length + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        maskCtx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    getCharset: function Type1Font_getCharset() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var charset = ['.notdef']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var charstrings = this.charstrings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var glyphId = 0; glyphId < charstrings.length; glyphId++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        charset.push(charstrings[glyphId].glyphName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.transform.apply(ctx, image.transform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.scale(1, -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.drawImage(maskCanvas.canvas, 0, 0, width, height, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      0, -1, 1, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return charset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    getGlyphMapping: function Type1Font_getGlyphMapping(properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var charstrings = this.charstrings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var glyphNames = ['.notdef'], glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (glyphId = 0; glyphId < charstrings.length; glyphId++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        glyphNames.push(charstrings[glyphId].glyphName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var encoding = properties.builtInEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (encoding) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var builtInEncoding = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (var charCode in encoding) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          glyphId = glyphNames.indexOf(encoding[charCode]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (glyphId >= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            builtInEncoding[charCode] = glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    paintImageXObject: function CanvasGraphics_paintImageXObject(objId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var imgData = this.objs.get(objId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!imgData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        warn('Dependent image isn\'t ready yet'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return type1FontGlyphMapping(properties, builtInEncoding, glyphNames); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.paintInlineImageXObject(imgData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    getSeacs: function Type1Font_getSeacs(charstrings) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var i, ii; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var seacMap = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (i = 0, ii = charstrings.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var charstring = charstrings[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (charstring.seac) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // Offset by 1 for .notdef 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          seacMap[i + 1] = charstring.seac; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    paintImageXObjectRepeat: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function CanvasGraphics_paintImageXObjectRepeat(objId, scaleX, scaleY, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                          positions) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var imgData = this.objs.get(objId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!imgData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        warn('Dependent image isn\'t ready yet'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return seacMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    getType2Charstrings: function Type1Font_getType2Charstrings( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                    type1Charstrings) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var type2Charstrings = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var i = 0, ii = type1Charstrings.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        type2Charstrings.push(type1Charstrings[i].charstring); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var width = imgData.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var height = imgData.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var map = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = 0, ii = positions.length; i < ii; i += 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        map.push({transform: [scaleX, 0, 0, scaleY, positions[i], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 positions[i + 1]], x: 0, y: 0, w: width, h: height}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return type2Charstrings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.paintInlineImageXObjectGroup(imgData, map); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    getType2Subrs: function Type1Font_getType2Subrs(type1Subrs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var bias = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var count = type1Subrs.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (count < 1133) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        bias = 107; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else if (count < 33769) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        bias = 1131; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    paintInlineImageXObject: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function CanvasGraphics_paintInlineImageXObject(imgData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var width = imgData.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var height = imgData.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // scale the image to the unit square 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.scale(1 / width, -1 / height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var currentTransform = ctx.mozCurrentTransformInverse; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var a = currentTransform[0], b = currentTransform[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var widthScale = Math.max(Math.sqrt(a * a + b * b), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var c = currentTransform[2], d = currentTransform[3]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var heightScale = Math.max(Math.sqrt(c * c + d * d), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var imgToPaint, tmpCanvas; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // instanceof HTMLElement does not work in jsdom node.js module 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (imgData instanceof HTMLElement || !imgData.data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        imgToPaint = imgData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        bias = 32768; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tmpCanvas = this.cachedCanvases.getCanvas('inlineImage', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                  width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var tmpCtx = tmpCanvas.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        putBinaryImageData(tmpCtx, imgData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        imgToPaint = tmpCanvas.canvas; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Add a bunch of empty subrs to deal with the Type2 bias 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var type2Subrs = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (i = 0; i < bias; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        type2Subrs.push([0x0B]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var paintWidth = width, paintHeight = height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var tmpCanvasId = 'prescale1'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Vertial or horizontal scaling shall not be more than 2 to not loose the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // pixels during drawImage operation, painting on the temporary canvas(es) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // that are twice smaller in size 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      while ((widthScale > 2 && paintWidth > 1) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             (heightScale > 2 && paintHeight > 1)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var newWidth = paintWidth, newHeight = paintHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (widthScale > 2 && paintWidth > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          newWidth = Math.ceil(paintWidth / 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          widthScale /= paintWidth / newWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (heightScale > 2 && paintHeight > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          newHeight = Math.ceil(paintHeight / 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          heightScale /= paintHeight / newHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tmpCanvas = this.cachedCanvases.getCanvas(tmpCanvasId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                  newWidth, newHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tmpCtx = tmpCanvas.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tmpCtx.clearRect(0, 0, newWidth, newHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tmpCtx.drawImage(imgToPaint, 0, 0, paintWidth, paintHeight, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                     0, 0, newWidth, newHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        imgToPaint = tmpCanvas.canvas; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        paintWidth = newWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        paintHeight = newHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tmpCanvasId = tmpCanvasId === 'prescale1' ? 'prescale2' : 'prescale1'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.drawImage(imgToPaint, 0, 0, paintWidth, paintHeight, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                0, -height, width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (i = 0; i < count; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        type2Subrs.push(type1Subrs[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.imageLayer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var position = this.getCanvasPosition(0, -height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.imageLayer.appendImage({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          imgData: imgData, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          left: position[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          top: position[1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          width: width / currentTransform[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          height: height / currentTransform[3] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return type2Subrs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    wrap: function Type1Font_wrap(name, glyphs, charstrings, subrs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                  properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var cff = new CFF(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      cff.header = new CFFHeader(1, 0, 4, 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      cff.names = [name]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var topDict = new CFFTopDict(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // CFF strings IDs 0...390 are predefined names, so refering 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // to entries in our own String INDEX starts at SID 391. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      topDict.setByName('version', 391); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      topDict.setByName('Notice', 392); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      topDict.setByName('FullName', 393); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      topDict.setByName('FamilyName', 394); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      topDict.setByName('Weight', 395); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      topDict.setByName('Encoding', null); // placeholder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      topDict.setByName('FontMatrix', properties.fontMatrix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      topDict.setByName('FontBBox', properties.bbox); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      topDict.setByName('charset', null); // placeholder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      topDict.setByName('CharStrings', null); // placeholder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      topDict.setByName('Private', null); // placeholder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      cff.topDict = topDict; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var strings = new CFFStrings(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      strings.add('Version 0.11'); // Version 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      strings.add('See original notice'); // Notice 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      strings.add(name); // FullName 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      strings.add(name); // FamilyName 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      strings.add('Medium'); // Weight 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      cff.strings = strings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      cff.globalSubrIndex = new CFFIndex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var count = glyphs.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var charsetArray = [0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var i, ii; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (i = 0; i < count; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var index = CFFStandardStrings.indexOf(charstrings[i].glyphName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // TODO: Insert the string and correctly map it.  Previously it was 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // thought mapping names that aren't in the standard strings to .notdef 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // was fine, however in issue818 when mapping them all to .notdef the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // adieresis glyph no longer worked. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (index === -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          index = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        charsetArray.push((index >> 8) & 0xff, index & 0xff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      cff.charset = new CFFCharset(false, 0, [], charsetArray); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    paintInlineImageXObjectGroup: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function CanvasGraphics_paintInlineImageXObjectGroup(imgData, map) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var w = imgData.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var h = imgData.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var charStringsIndex = new CFFIndex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      charStringsIndex.add([0x8B, 0x0E]); // .notdef 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (i = 0; i < count; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        charStringsIndex.add(glyphs[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      cff.charStrings = charStringsIndex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var tmpCanvas = this.cachedCanvases.getCanvas('inlineImage', w, h); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var tmpCtx = tmpCanvas.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      putBinaryImageData(tmpCtx, imgData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var privateDict = new CFFPrivateDict(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      privateDict.setByName('Subrs', null); // placeholder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fields = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'BlueValues', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'OtherBlues', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'FamilyBlues', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'FamilyOtherBlues', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'StemSnapH', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'StemSnapV', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'BlueShift', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'BlueFuzz', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'BlueScale', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'LanguageGroup', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'ExpansionFactor', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'ForceBold', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'StdHW', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        'StdVW' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (i = 0, ii = fields.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var field = fields[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!(field in properties.privateData)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var value = properties.privateData[field]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (isArray(value)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // All of the private dictionary array data in CFF must be stored as 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // "delta-encoded" numbers. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (var j = value.length - 1; j > 0; j--) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            value[j] -= value[j - 1]; // ... difference from previous value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = 0, ii = map.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var entry = map[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.transform.apply(ctx, entry.transform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.scale(1, -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.drawImage(tmpCanvas.canvas, entry.x, entry.y, entry.w, entry.h, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      0, -1, 1, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (this.imageLayer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var position = this.getCanvasPosition(entry.x, entry.y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.imageLayer.appendImage({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            imgData: imgData, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            left: position[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            top: position[1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            width: w, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            height: h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        privateDict.setByName(field, value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      cff.topDict.privateDict = privateDict; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var subrIndex = new CFFIndex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (i = 0, ii = subrs.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        subrIndex.add(subrs[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      privateDict.subrsIndex = subrIndex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    paintSolidColorImageMask: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function CanvasGraphics_paintSolidColorImageMask() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.ctx.fillRect(0, 0, 1, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var compiler = new CFFCompiler(cff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return compiler.compile(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    paintXObject: function CanvasGraphics_paintXObject() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      warn('Unsupported \'paintXObject\' command.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return Type1Font; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Marked content 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var CFFFont = (function CFFFontClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function CFFFont(file, properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.properties = properties; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    markPoint: function CanvasGraphics_markPoint(tag) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // TODO Marked content. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    markPointProps: function CanvasGraphics_markPointProps(tag, properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // TODO Marked content. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    beginMarkedContent: function CanvasGraphics_beginMarkedContent(tag) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // TODO Marked content. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    beginMarkedContentProps: function CanvasGraphics_beginMarkedContentProps( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                        tag, properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // TODO Marked content. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    endMarkedContent: function CanvasGraphics_endMarkedContent() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // TODO Marked content. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var parser = new CFFParser(file, properties, SEAC_ANALYSIS_ENABLED); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.cff = parser.parse(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var compiler = new CFFCompiler(this.cff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.seacs = this.cff.seacs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.data = compiler.compile(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } catch (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      warn('Failed to compile font ' + properties.loadedName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // There may have just been an issue with the compiler, set the data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // anyway and hope the font loaded. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.data = file; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Compatibility 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  CFFFont.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    get numGlyphs() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return this.cff.charStrings.count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    beginCompat: function CanvasGraphics_beginCompat() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // TODO ignore undefined operators (should we do that anyway?) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    getCharset: function CFFFont_getCharset() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return this.cff.charset.charset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    endCompat: function CanvasGraphics_endCompat() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // TODO stop ignoring undefined operators 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    getGlyphMapping: function CFFFont_getGlyphMapping() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var cff = this.cff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var properties = this.properties; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var charsets = cff.charset.charset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var charCodeToGlyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (properties.composite) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        charCodeToGlyphId = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (cff.isCIDFont) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // If the font is actually a CID font then we should use the charset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // to map CIDs to GIDs. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (glyphId = 0; glyphId < charsets.length; glyphId++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var cid = charsets[glyphId]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var charCode = properties.cMap.charCodeOf(cid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            charCodeToGlyphId[charCode] = glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Helper functions 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    consumePath: function CanvasGraphics_consumePath() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.pendingClip) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (this.pendingClip === EO_CLIP) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (ctx.mozFillRule !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ctx.mozFillRule = 'evenodd'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ctx.clip(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ctx.mozFillRule = 'nonzero'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ctx.clip('evenodd'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // If it is NOT actually a CID font then CIDs should be mapped 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // directly to GIDs. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (glyphId = 0; glyphId < cff.charStrings.count; glyphId++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            charCodeToGlyphId[glyphId] = glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ctx.clip(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return charCodeToGlyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.pendingClip = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var encoding = cff.encoding ? cff.encoding.encoding : null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      charCodeToGlyphId = type1FontGlyphMapping(properties, encoding, charsets); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return charCodeToGlyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ctx.beginPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getSinglePixelWidth: function CanvasGraphics_getSinglePixelWidth(scale) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.cachedGetSinglePixelWidth === null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var inverse = this.ctx.mozCurrentTransformInverse; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // max of the current horizontal and vertical scale 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.cachedGetSinglePixelWidth = Math.sqrt(Math.max( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (inverse[0] * inverse[0] + inverse[1] * inverse[1]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          (inverse[2] * inverse[2] + inverse[3] * inverse[3]))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return this.cachedGetSinglePixelWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getCanvasPosition: function CanvasGraphics_getCanvasPosition(x, y) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var transform = this.ctx.mozCurrentTransform; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        transform[0] * x + transform[2] * y + transform[4], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        transform[1] * x + transform[3] * y + transform[5] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return CFFFont; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// Workaround for seac on Windows. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-(function checkSeacSupport() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (typeof navigator !== 'undefined' && /Windows/.test(navigator.userAgent)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    SEAC_ANALYSIS_ENABLED = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (var op in OPS) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    CanvasGraphics.prototype[OPS[op]] = CanvasGraphics.prototype[op]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// Workaround for Private Use Area characters in Chrome on Windows 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// http://code.google.com/p/chromium/issues/detail?id=122465 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// https://github.com/mozilla/pdf.js/issues/1689 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-(function checkChromeWindows() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (typeof navigator !== 'undefined' && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      /Windows.*Chrome/.test(navigator.userAgent)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    SKIP_PRIVATE_USE_RANGE_F000_TO_F01F = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return CanvasGraphics; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 })(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-exports.SEAC_ANALYSIS_ENABLED = SEAC_ANALYSIS_ENABLED; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-exports.ErrorFont = ErrorFont; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-exports.Font = Font; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-exports.FontFlags = FontFlags; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-exports.IdentityToUnicodeMap = IdentityToUnicodeMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-exports.ToUnicodeMap = ToUnicodeMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-exports.getFontType = getFontType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+exports.CanvasGraphics = CanvasGraphics; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+exports.createScratchCanvas = createScratchCanvas; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 (function (root, factory) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    factory((root.pdfjsCorePsParser = {}), root.pdfjsSharedUtil, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      root.pdfjsCoreParser); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    factory((root.pdfjsCoreFonts = {}), root.pdfjsSharedUtil, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      root.pdfjsCorePrimitives, root.pdfjsCoreStream, root.pdfjsCoreParser, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      root.pdfjsCoreGlyphList, root.pdfjsCoreCharsets, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      root.pdfjsCoreFontRenderer, root.pdfjsCoreEncodings, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      root.pdfjsCoreStandardFonts, root.pdfjsCoreUnicode, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      root.pdfjsCoreType1Parser, root.pdfjsCoreCFFParser); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}(this, function (exports, sharedUtil, coreParser) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+}(this, function (exports, sharedUtil, corePrimitives, coreStream, coreParser, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  coreGlyphList, coreCharsets, coreFontRenderer, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  coreEncodings, coreStandardFonts, coreUnicode, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  coreType1Parser, coreCFFParser) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var FONT_IDENTITY_MATRIX = sharedUtil.FONT_IDENTITY_MATRIX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var FontType = sharedUtil.FontType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var Util = sharedUtil.Util; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var assert = sharedUtil.assert; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var bytesToString = sharedUtil.bytesToString; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 var error = sharedUtil.error; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var EOF = coreParser.EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var info = sharedUtil.info; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var isArray = sharedUtil.isArray; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var isInt = sharedUtil.isInt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var isNum = sharedUtil.isNum; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var readUint32 = sharedUtil.readUint32; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var shadow = sharedUtil.shadow; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var stringToBytes = sharedUtil.stringToBytes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var string32 = sharedUtil.string32; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var warn = sharedUtil.warn; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var MissingDataException = sharedUtil.MissingDataException; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var Stream = coreStream.Stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 var Lexer = coreParser.Lexer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var getGlyphsUnicode = coreGlyphList.getGlyphsUnicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var getDingbatsGlyphsUnicode = coreGlyphList.getDingbatsGlyphsUnicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var ISOAdobeCharset = coreCharsets.ISOAdobeCharset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var ExpertCharset = coreCharsets.ExpertCharset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var ExpertSubsetCharset = coreCharsets.ExpertSubsetCharset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var FontRendererFactory = coreFontRenderer.FontRendererFactory; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var WinAnsiEncoding = coreEncodings.WinAnsiEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var StandardEncoding = coreEncodings.StandardEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var MacRomanEncoding = coreEncodings.MacRomanEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var SymbolSetEncoding = coreEncodings.SymbolSetEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var ZapfDingbatsEncoding = coreEncodings.ZapfDingbatsEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var ExpertEncoding = coreEncodings.ExpertEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var getEncoding = coreEncodings.getEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var getStdFontMap = coreStandardFonts.getStdFontMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var getNonStdFontMap = coreStandardFonts.getNonStdFontMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var getGlyphMapForStandardFonts = coreStandardFonts.getGlyphMapForStandardFonts; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var getSupplementalGlyphMapForArialBlack = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  coreStandardFonts.getSupplementalGlyphMapForArialBlack; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var getUnicodeRangeFor = coreUnicode.getUnicodeRangeFor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var mapSpecialUnicodeValues = coreUnicode.mapSpecialUnicodeValues; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var getUnicodeForGlyph = coreUnicode.getUnicodeForGlyph; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var Type1Parser = coreType1Parser.Type1Parser; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var CFFStandardStrings = coreCFFParser.CFFStandardStrings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var CFFParser = coreCFFParser.CFFParser; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var CFFCompiler = coreCFFParser.CFFCompiler; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var CFF = coreCFFParser.CFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var CFFHeader = coreCFFParser.CFFHeader; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var CFFTopDict = coreCFFParser.CFFTopDict; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var CFFPrivateDict = coreCFFParser.CFFPrivateDict; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var CFFStrings = coreCFFParser.CFFStrings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var CFFIndex = coreCFFParser.CFFIndex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var CFFCharset = coreCFFParser.CFFCharset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var PostScriptParser = (function PostScriptParserClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function PostScriptParser(lexer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.lexer = lexer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.operators = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.token = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.prev = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  PostScriptParser.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    nextToken: function PostScriptParser_nextToken() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.prev = this.token; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.token = this.lexer.getToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    accept: function PostScriptParser_accept(type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.token.type === type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.nextToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    expect: function PostScriptParser_expect(type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.accept(type)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      error('Unexpected symbol: found ' + this.token.type + ' expected ' + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        type + '.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    parse: function PostScriptParser_parse() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.nextToken(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.expect(PostScriptTokenTypes.LBRACE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.parseBlock(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.expect(PostScriptTokenTypes.RBRACE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return this.operators; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    parseBlock: function PostScriptParser_parseBlock() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      while (true) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (this.accept(PostScriptTokenTypes.NUMBER)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          this.operators.push(this.prev.value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else if (this.accept(PostScriptTokenTypes.OPERATOR)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          this.operators.push(this.prev.value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else if (this.accept(PostScriptTokenTypes.LBRACE)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          this.parseCondition(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    parseCondition: function PostScriptParser_parseCondition() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Add two place holders that will be updated later 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var conditionLocation = this.operators.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.operators.push(null, null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Unicode Private Use Area 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var PRIVATE_USE_OFFSET_START = 0xE000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var PRIVATE_USE_OFFSET_END = 0xF8FF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var SKIP_PRIVATE_USE_RANGE_F000_TO_F01F = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.parseBlock(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.expect(PostScriptTokenTypes.RBRACE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.accept(PostScriptTokenTypes.IF)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // The true block is right after the 'if' so it just falls through on 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // true else it jumps and skips the true block. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.operators[conditionLocation] = this.operators.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.operators[conditionLocation + 1] = 'jz'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else if (this.accept(PostScriptTokenTypes.LBRACE)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var jumpLocation = this.operators.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.operators.push(null, null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var endOfTrue = this.operators.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.parseBlock(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.expect(PostScriptTokenTypes.RBRACE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.expect(PostScriptTokenTypes.IFELSE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // The jump is added at the end of the true block to skip the false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // block. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.operators[jumpLocation] = this.operators.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.operators[jumpLocation + 1] = 'j'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// PDF Glyph Space Units are one Thousandth of a TextSpace Unit 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// except for Type 3 fonts 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var PDF_GLYPH_SPACE_UNITS = 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.operators[conditionLocation] = endOfTrue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.operators[conditionLocation + 1] = 'jz'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        error('PS Function: error parsing conditional.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return PostScriptParser; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Accented charactars are not displayed properly on Windows, using this flag 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// to control analysis of seac charstrings. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var SEAC_ANALYSIS_ENABLED = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var PostScriptTokenTypes = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  LBRACE: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  RBRACE: 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  NUMBER: 2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  OPERATOR: 3, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  IF: 4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  IFELSE: 5 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var FontFlags = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  FixedPitch: 1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Serif: 2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Symbolic: 4, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Script: 8, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Nonsymbolic: 32, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Italic: 64, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  AllCap: 65536, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  SmallCap: 131072, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ForceBold: 262144 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var PostScriptToken = (function PostScriptTokenClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function PostScriptToken(type, value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.type = type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.value = value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var MacStandardGlyphOrdering = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  '.notdef', '.null', 'nonmarkingreturn', 'space', 'exclam', 'quotedbl', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'numbersign', 'dollar', 'percent', 'ampersand', 'quotesingle', 'parenleft', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'parenright', 'asterisk', 'plus', 'comma', 'hyphen', 'period', 'slash', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'nine', 'colon', 'semicolon', 'less', 'equal', 'greater', 'question', 'at', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'bracketleft', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'backslash', 'bracketright', 'asciicircum', 'underscore', 'grave', 'a', 'b', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 'braceleft', 'bar', 'braceright', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'asciitilde', 'Adieresis', 'Aring', 'Ccedilla', 'Eacute', 'Ntilde', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'Odieresis', 'Udieresis', 'aacute', 'agrave', 'acircumflex', 'adieresis', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'atilde', 'aring', 'ccedilla', 'eacute', 'egrave', 'ecircumflex', 'edieresis', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'iacute', 'igrave', 'icircumflex', 'idieresis', 'ntilde', 'oacute', 'ograve', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'ocircumflex', 'odieresis', 'otilde', 'uacute', 'ugrave', 'ucircumflex', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'udieresis', 'dagger', 'degree', 'cent', 'sterling', 'section', 'bullet', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'paragraph', 'germandbls', 'registered', 'copyright', 'trademark', 'acute', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'dieresis', 'notequal', 'AE', 'Oslash', 'infinity', 'plusminus', 'lessequal', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'greaterequal', 'yen', 'mu', 'partialdiff', 'summation', 'product', 'pi', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'integral', 'ordfeminine', 'ordmasculine', 'Omega', 'ae', 'oslash', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'questiondown', 'exclamdown', 'logicalnot', 'radical', 'florin', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'approxequal', 'Delta', 'guillemotleft', 'guillemotright', 'ellipsis', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'nonbreakingspace', 'Agrave', 'Atilde', 'Otilde', 'OE', 'oe', 'endash', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'emdash', 'quotedblleft', 'quotedblright', 'quoteleft', 'quoteright', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'divide', 'lozenge', 'ydieresis', 'Ydieresis', 'fraction', 'currency', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'guilsinglleft', 'guilsinglright', 'fi', 'fl', 'daggerdbl', 'periodcentered', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'quotesinglbase', 'quotedblbase', 'perthousand', 'Acircumflex', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'Ecircumflex', 'Aacute', 'Edieresis', 'Egrave', 'Iacute', 'Icircumflex', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'Idieresis', 'Igrave', 'Oacute', 'Ocircumflex', 'apple', 'Ograve', 'Uacute', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'Ucircumflex', 'Ugrave', 'dotlessi', 'circumflex', 'tilde', 'macron', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'breve', 'dotaccent', 'ring', 'cedilla', 'hungarumlaut', 'ogonek', 'caron', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'Lslash', 'lslash', 'Scaron', 'scaron', 'Zcaron', 'zcaron', 'brokenbar', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'Eth', 'eth', 'Yacute', 'yacute', 'Thorn', 'thorn', 'minus', 'multiply', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'onesuperior', 'twosuperior', 'threesuperior', 'onehalf', 'onequarter', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'threequarters', 'franc', 'Gbreve', 'gbreve', 'Idotaccent', 'Scedilla', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  'scedilla', 'Cacute', 'cacute', 'Ccaron', 'ccaron', 'dcroat']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function adjustWidths(properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (!properties.fontMatrix) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (properties.fontMatrix[0] === FONT_IDENTITY_MATRIX[0]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // adjusting width to fontMatrix scale 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var scale = 0.001 / properties.fontMatrix[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var glyphsWidths = properties.widths; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  for (var glyph in glyphsWidths) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    glyphsWidths[glyph] *= scale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  properties.defaultWidth *= scale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var opCache = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function getFontType(type, subtype) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  switch (type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case 'Type1': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return subtype === 'Type1C' ? FontType.TYPE1C : FontType.TYPE1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case 'CIDFontType0': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return subtype === 'CIDFontType0C' ? FontType.CIDFONTTYPE0C : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        FontType.CIDFONTTYPE0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case 'OpenType': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return FontType.OPENTYPE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case 'TrueType': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return FontType.TRUETYPE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case 'CIDFontType2': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return FontType.CIDFONTTYPE2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case 'MMType1': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return FontType.MMTYPE1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    case 'Type0': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return FontType.TYPE0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return FontType.UNKNOWN; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  PostScriptToken.getOperator = function PostScriptToken_getOperator(op) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var opValue = opCache[op]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (opValue) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return opValue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return opCache[op] = new PostScriptToken(PostScriptTokenTypes.OPERATOR, op); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var Glyph = (function GlyphClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function Glyph(fontChar, unicode, accent, width, vmetric, operatorListId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 isSpace, isInFont) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.fontChar = fontChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.unicode = unicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.accent = accent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.width = width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.vmetric = vmetric; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.operatorListId = operatorListId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.isSpace = isSpace; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.isInFont = isInFont; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Glyph.prototype.matchesForCache = function(fontChar, unicode, accent, width, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                             vmetric, operatorListId, isSpace, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                             isInFont) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return this.fontChar === fontChar && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           this.unicode === unicode && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           this.accent === accent && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           this.width === width && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           this.vmetric === vmetric && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           this.operatorListId === operatorListId && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           this.isSpace === isSpace && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           this.isInFont === isInFont; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  PostScriptToken.LBRACE = new PostScriptToken(PostScriptTokenTypes.LBRACE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    '{'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  PostScriptToken.RBRACE = new PostScriptToken(PostScriptTokenTypes.RBRACE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    '}'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  PostScriptToken.IF = new PostScriptToken(PostScriptTokenTypes.IF, 'IF'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  PostScriptToken.IFELSE = new PostScriptToken(PostScriptTokenTypes.IFELSE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    'IFELSE'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return PostScriptToken; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return Glyph; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 })(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var PostScriptLexer = (function PostScriptLexerClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function PostScriptLexer(stream) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.stream = stream; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.nextChar(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.strBuf = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var ToUnicodeMap = (function ToUnicodeMapClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function ToUnicodeMap(cmap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // The elements of this._map can be integers or strings, depending on how 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // |cmap| was created. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this._map = cmap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  PostScriptLexer.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    nextChar: function PostScriptLexer_nextChar() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return (this.currentChar = this.stream.getByte()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    getToken: function PostScriptLexer_getToken() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var comment = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ch = this.currentChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // skip comments 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      while (true) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (ch < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return EOF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ToUnicodeMap.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    get length() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return this._map.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (comment) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (ch === 0x0A || ch === 0x0D) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            comment = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else if (ch === 0x25) { // '%' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          comment = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else if (!Lexer.isSpace(ch)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ch = this.nextChar(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      switch (ch | 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        case 0x30: case 0x31: case 0x32: case 0x33: case 0x34: // '0'-'4' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        case 0x35: case 0x36: case 0x37: case 0x38: case 0x39: // '5'-'9' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        case 0x2B: case 0x2D: case 0x2E: // '+', '-', '.' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return new PostScriptToken(PostScriptTokenTypes.NUMBER, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                     this.getNumber()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        case 0x7B: // '{' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          this.nextChar(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return PostScriptToken.LBRACE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        case 0x7D: // '}' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          this.nextChar(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return PostScriptToken.RBRACE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    forEach: function(callback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var charCode in this._map) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        callback(charCode, this._map[charCode].charCodeAt(0)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // operator 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var strBuf = this.strBuf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      strBuf.length = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      strBuf[0] = String.fromCharCode(ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      while ((ch = this.nextChar()) >= 0 && // and 'A'-'Z', 'a'-'z' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-             ((ch >= 0x41 && ch <= 0x5A) || (ch >= 0x61 && ch <= 0x7A))) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        strBuf.push(String.fromCharCode(ch)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var str = strBuf.join(''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      switch (str.toLowerCase()) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        case 'if': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return PostScriptToken.IF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        case 'ifelse': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return PostScriptToken.IFELSE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return PostScriptToken.getOperator(str); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    has: function(i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return this._map[i] !== undefined; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    getNumber: function PostScriptLexer_getNumber() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ch = this.currentChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var strBuf = this.strBuf; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      strBuf.length = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      strBuf[0] = String.fromCharCode(ch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      while ((ch = this.nextChar()) >= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if ((ch >= 0x30 && ch <= 0x39) || // '0'-'9' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ch === 0x2D || ch === 0x2E) { // '-', '.' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          strBuf.push(String.fromCharCode(ch)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var value = parseFloat(strBuf.join('')); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (isNaN(value)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        error('Invalid floating point number: ' + value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    get: function(i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return this._map[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    charCodeOf: function(v) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return this._map.indexOf(v); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return PostScriptLexer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-exports.PostScriptLexer = PostScriptLexer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-exports.PostScriptParser = PostScriptParser; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-})); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return ToUnicodeMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-(function (root, factory) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    factory((root.pdfjsDisplayCanvas = {}), root.pdfjsSharedUtil, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      root.pdfjsDisplayDOMUtils, root.pdfjsDisplayPatternHelper, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      root.pdfjsDisplayWebGL); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var IdentityToUnicodeMap = (function IdentityToUnicodeMapClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function IdentityToUnicodeMap(firstChar, lastChar) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.firstChar = firstChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.lastChar = lastChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-}(this, function (exports, sharedUtil, displayDOMUtils, displayPatternHelper, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  displayWebGL) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var FONT_IDENTITY_MATRIX = sharedUtil.FONT_IDENTITY_MATRIX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var IDENTITY_MATRIX = sharedUtil.IDENTITY_MATRIX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var ImageKind = sharedUtil.ImageKind; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var OPS = sharedUtil.OPS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var TextRenderingMode = sharedUtil.TextRenderingMode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var Uint32ArrayView = sharedUtil.Uint32ArrayView; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var Util = sharedUtil.Util; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var assert = sharedUtil.assert; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var info = sharedUtil.info; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var isNum = sharedUtil.isNum; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var isArray = sharedUtil.isArray; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var error = sharedUtil.error; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var shadow = sharedUtil.shadow; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var warn = sharedUtil.warn; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var TilingPattern = displayPatternHelper.TilingPattern; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var getShadingPatternFromIR = displayPatternHelper.getShadingPatternFromIR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var WebGLUtils = displayWebGL.WebGLUtils; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// <canvas> contexts store most of the state we need natively. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// However, PDF needs a bit more state, which we store here. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  IdentityToUnicodeMap.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    get length() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return (this.lastChar + 1) - this.firstChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// Minimal font size that would be used during canvas fillText operations. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var MIN_FONT_SIZE = 16; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// Maximum font size that would be used during canvas fillText operations. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var MAX_FONT_SIZE = 100; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var MAX_GROUP_SIZE = 4096; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    forEach: function (callback) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = this.firstChar, ii = this.lastChar; i <= ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        callback(i, i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-// Heuristic value used when enforcing minimum line widths. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var MIN_WIDTH_FACTOR = 0.65; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    has: function (i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return this.firstChar <= i && i <= this.lastChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var COMPILE_TYPE3_GLYPHS = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var MAX_SIZE_TO_COMPILE = 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    get: function (i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.firstChar <= i && i <= this.lastChar) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return String.fromCharCode(i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return undefined; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var FULL_CHUNK_HEIGHT = 16; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    charCodeOf: function (v) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return (isInt(v) && v >= this.firstChar && v <= this.lastChar) ? v : -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function createScratchCanvas(width, height) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var canvas = document.createElement('canvas'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  canvas.width = width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  canvas.height = height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return canvas; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return IdentityToUnicodeMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function addContextCurrentTransform(ctx) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // If the context doesn't expose a `mozCurrentTransform`, add a JS based one. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (!ctx.mozCurrentTransform) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ctx._originalSave = ctx.save; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ctx._originalRestore = ctx.restore; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ctx._originalRotate = ctx.rotate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ctx._originalScale = ctx.scale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ctx._originalTranslate = ctx.translate; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ctx._originalTransform = ctx.transform; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ctx._originalSetTransform = ctx.setTransform; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var OpenTypeFileBuilder = (function OpenTypeFileBuilderClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function writeInt16(dest, offset, num) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    dest[offset] = (num >> 8) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    dest[offset + 1] = num & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ctx._transformMatrix = ctx._transformMatrix || [1, 0, 0, 1, 0, 0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ctx._transformStack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function writeInt32(dest, offset, num) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    dest[offset] = (num >> 24) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    dest[offset + 1] = (num >> 16) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    dest[offset + 2] = (num >> 8) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    dest[offset + 3] = num & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Object.defineProperty(ctx, 'mozCurrentTransform', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      get: function getCurrentTransform() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return this._transformMatrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function writeData(dest, offset, data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var i, ii; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (data instanceof Uint8Array) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      dest.set(data, offset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else if (typeof data === 'string') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (i = 0, ii = data.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dest[offset++] = data.charCodeAt(i) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    Object.defineProperty(ctx, 'mozCurrentTransformInverse', { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      get: function getCurrentTransformInverse() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Calculation done using WolframAlpha: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // http://www.wolframalpha.com/input/? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        //   i=Inverse+{{a%2C+c%2C+e}%2C+{b%2C+d%2C+f}%2C+{0%2C+0%2C+1}} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var m = this._transformMatrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var a = m[0], b = m[1], c = m[2], d = m[3], e = m[4], f = m[5]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // treating everything else as array 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (i = 0, ii = data.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dest[offset++] = data[i] & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var ad_bc = a * d - b * c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var bc_ad = b * c - a * d; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function OpenTypeFileBuilder(sfnt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.sfnt = sfnt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.tables = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          d / ad_bc, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          b / bc_ad, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          c / bc_ad, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          a / ad_bc, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          (d * e - c * f) / bc_ad, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          (b * e - a * f) / ad_bc 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ctx.save = function ctxSave() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var old = this._transformMatrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this._transformStack.push(old); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this._transformMatrix = old.slice(0, 6); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this._originalSave(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  OpenTypeFileBuilder.getSearchParams = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function OpenTypeFileBuilder_getSearchParams(entriesCount, entrySize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var maxPower2 = 1, log2 = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    while ((maxPower2 ^ entriesCount) > maxPower2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      maxPower2 <<= 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      log2++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var searchRange = maxPower2 * entrySize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      range: searchRange, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      entry: log2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      rangeShift: entrySize * entriesCount - searchRange 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ctx.restore = function ctxRestore() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var prev = this._transformStack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (prev) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this._transformMatrix = prev; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this._originalRestore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var OTF_HEADER_SIZE = 12; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var OTF_TABLE_ENTRY_SIZE = 16; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ctx.translate = function ctxTranslate(x, y) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var m = this._transformMatrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      m[4] = m[0] * x + m[2] * y + m[4]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      m[5] = m[1] * x + m[3] * y + m[5]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  OpenTypeFileBuilder.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    toArray: function OpenTypeFileBuilder_toArray() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var sfnt = this.sfnt; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this._originalTranslate(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Tables needs to be written by ascendant alphabetic order 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var tables = this.tables; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var tablesNames = Object.keys(tables); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      tablesNames.sort(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var numTables = tablesNames.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ctx.scale = function ctxScale(x, y) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var m = this._transformMatrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      m[0] = m[0] * x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      m[1] = m[1] * x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      m[2] = m[2] * y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      m[3] = m[3] * y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var i, j, jj, table, tableName; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // layout the tables data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var offset = OTF_HEADER_SIZE + numTables * OTF_TABLE_ENTRY_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var tableOffsets = [offset]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (i = 0; i < numTables; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        table = tables[tablesNames[i]]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var paddedLength = ((table.length + 3) & ~3) >>> 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        offset += paddedLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tableOffsets.push(offset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this._originalScale(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var file = new Uint8Array(offset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // write the table data first (mostly for checksum) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (i = 0; i < numTables; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        table = tables[tablesNames[i]]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        writeData(file, tableOffsets[i], table); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ctx.transform = function ctxTransform(a, b, c, d, e, f) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var m = this._transformMatrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this._transformMatrix = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        m[0] * a + m[2] * b, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        m[1] * a + m[3] * b, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        m[0] * c + m[2] * d, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        m[1] * c + m[3] * d, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        m[0] * e + m[2] * f + m[4], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        m[1] * e + m[3] * f + m[5] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // sfnt version (4 bytes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (sfnt === 'true') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Windows hates the Mac TrueType sfnt version number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        sfnt = string32(0x00010000); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      file[0] = sfnt.charCodeAt(0) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      file[1] = sfnt.charCodeAt(1) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      file[2] = sfnt.charCodeAt(2) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      file[3] = sfnt.charCodeAt(3) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx._originalTransform(a, b, c, d, e, f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // numTables (2 bytes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      writeInt16(file, 4, numTables); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ctx.setTransform = function ctxSetTransform(a, b, c, d, e, f) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this._transformMatrix = [a, b, c, d, e, f]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var searchParams = OpenTypeFileBuilder.getSearchParams(numTables, 16); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx._originalSetTransform(a, b, c, d, e, f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // searchRange (2 bytes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      writeInt16(file, 6, searchParams.range); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // entrySelector (2 bytes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      writeInt16(file, 8, searchParams.entry); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // rangeShift (2 bytes) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      writeInt16(file, 10, searchParams.rangeShift); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ctx.rotate = function ctxRotate(angle) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var cosValue = Math.cos(angle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var sinValue = Math.sin(angle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      offset = OTF_HEADER_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // writing table entries 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (i = 0; i < numTables; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tableName = tablesNames[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        file[offset] = tableName.charCodeAt(0) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        file[offset + 1] = tableName.charCodeAt(1) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        file[offset + 2] = tableName.charCodeAt(2) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        file[offset + 3] = tableName.charCodeAt(3) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var m = this._transformMatrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this._transformMatrix = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        m[0] * cosValue + m[2] * sinValue, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        m[1] * cosValue + m[3] * sinValue, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        m[0] * (-sinValue) + m[2] * cosValue, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        m[1] * (-sinValue) + m[3] * cosValue, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        m[4], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        m[5] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // checksum 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var checksum = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (j = tableOffsets[i], jj = tableOffsets[i + 1]; j < jj; j += 4) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var quad = readUint32(file, j); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          checksum = (checksum + quad) >>> 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        writeInt32(file, offset + 4, checksum); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this._originalRotate(angle); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // offset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        writeInt32(file, offset + 8, tableOffsets[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        writeInt32(file, offset + 12, tables[tableName].length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var CachedCanvases = (function CachedCanvasesClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function CachedCanvases() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.cache = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  CachedCanvases.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    getCanvas: function CachedCanvases_getCanvas(id, width, height, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                 trackTransform) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var canvasEntry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.cache[id] !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        canvasEntry = this.cache[id]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        canvasEntry.canvas.width = width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        canvasEntry.canvas.height = height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // reset canvas transform for emulated mozCurrentTransform, if needed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        canvasEntry.context.setTransform(1, 0, 0, 1, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var canvas = createScratchCanvas(width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var ctx = canvas.getContext('2d'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (trackTransform) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          addContextCurrentTransform(ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.cache[id] = canvasEntry = {canvas: canvas, context: ctx}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        offset += OTF_TABLE_ENTRY_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return canvasEntry; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return file; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    clear: function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var id in this.cache) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var canvasEntry = this.cache[id]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Zeroing the width and height causes Firefox to release graphics 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // resources immediately, which can greatly reduce memory consumption. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        canvasEntry.canvas.width = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        canvasEntry.canvas.height = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        delete this.cache[id]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    addTable: function OpenTypeFileBuilder_addTable(tag, data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (tag in this.tables) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        throw new Error('Table ' + tag + ' already exists'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.tables[tag] = data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return CachedCanvases; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return OpenTypeFileBuilder; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 })(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-function compileType3Glyph(imgData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var POINT_TO_PROCESS_LIMIT = 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Problematic Unicode characters in the fonts that needs to be moved to avoid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// issues when they are painted on the canvas, e.g. complex-script shaping or 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// control/whitespace characters. The ranges are listed in pairs: the first item 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// is a code of the first problematic code, the second one is the next 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// non-problematic code. The ranges must be in sorted order. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var ProblematicCharRanges = new Int32Array([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Control characters. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  0x0000, 0x0020, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  0x007F, 0x00A1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  0x00AD, 0x00AE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Chars that is used in complex-script shaping. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  0x0600, 0x0780, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  0x08A0, 0x10A0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  0x1780, 0x1800, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // General punctuation chars. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  0x2000, 0x2010, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  0x2011, 0x2012, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  0x2028, 0x2030, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  0x205F, 0x2070, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  0x25CC, 0x25CD, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Chars that is used in complex-script shaping. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  0xAA60, 0xAA80, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Specials Unicode block. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  0xFFF0, 0x10000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var width = imgData.width, height = imgData.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var i, j, j0, width1 = width + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var points = new Uint8Array(width1 * (height + 1)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var POINT_TYPES = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      new Uint8Array([0, 2, 4, 0, 1, 0, 5, 4, 8, 10, 0, 8, 0, 2, 1, 0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 'Font' is the class the outside world should use, it encapsulate all the font 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * decoding logics whatever type it is (assuming the font type is supported). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * For example to read a Type1 font and to attach it to the document: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *   var type1Font = new Font("MyFontName", binaryFile, propertiesObject); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ *   type1Font.bind(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var Font = (function FontClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function Font(name, file, properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var charCode, glyphName, unicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // decodes bit-packed mask data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var lineSize = (width + 7) & ~7, data0 = imgData.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var data = new Uint8Array(lineSize * height), pos = 0, ii; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  for (i = 0, ii = data0.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var mask = 128, elem = data0[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    while (mask > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      data[pos++] = (elem & mask) ? 0 : 255; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      mask >>= 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.name = name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.loadedName = properties.loadedName; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.isType3Font = properties.isType3Font; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.sizes = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.missingFile = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // finding iteresting points: every point is located between mask pixels, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // so there will be points of the (width + 1)x(height + 1) grid. Every point 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // will have flags assigned based on neighboring mask pixels: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  //   4 | 8 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  //   --P-- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  //   2 | 1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // We are interested only in points with the flags: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  //   - outside corners: 1, 2, 4, 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  //   - inside corners: 7, 11, 13, 14; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  //   - and, intersections: 5, 10. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var count = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  pos = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (data[pos] !== 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    points[0] = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ++count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  for (j = 1; j < width; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (data[pos] !== data[pos + 1]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      points[j] = data[pos] ? 2 : 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ++count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    pos++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (data[pos] !== 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    points[j] = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ++count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  for (i = 1; i < height; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    pos = i * lineSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    j0 = i * width1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (data[pos - lineSize] !== data[pos]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      points[j0] = data[pos] ? 1 : 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ++count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 'sum' is the position of the current pixel configuration in the 'TYPES' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // array (in order 8-1-2-4, so we can use '>>2' to shift the column). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var sum = (data[pos] ? 4 : 0) + (data[pos - lineSize] ? 8 : 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (j = 1; j < width; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      sum = (sum >> 2) + (data[pos + 1] ? 4 : 0) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            (data[pos - lineSize + 1] ? 8 : 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (POINT_TYPES[sum]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        points[j0 + j] = POINT_TYPES[sum]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ++count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      pos++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (data[pos - lineSize] !== data[pos]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      points[j0 + j] = data[pos] ? 2 : 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ++count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.glyphCache = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (count > POINT_TO_PROCESS_LIMIT) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var names = name.split('+'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    names = names.length > 1 ? names[1] : names[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    names = names.split(/[-,_]/g)[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.isSerifFont = !!(properties.flags & FontFlags.Serif); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.isSymbolicFont = !!(properties.flags & FontFlags.Symbolic); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.isMonospace = !!(properties.flags & FontFlags.FixedPitch); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  pos = lineSize * (height - 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  j0 = i * width1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (data[pos] !== 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    points[j0] = 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ++count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  for (j = 1; j < width; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (data[pos] !== data[pos + 1]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      points[j0 + j] = data[pos] ? 4 : 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ++count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    pos++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (data[pos] !== 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    points[j0 + j] = 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ++count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  if (count > POINT_TO_PROCESS_LIMIT) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    return null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var type = properties.type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var subtype = properties.subtype; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.type = type; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // building outlines 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var steps = new Int32Array([0, width1, -1, 0, -width1, 0, 0, 0, 1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var outlines = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  for (i = 0; count && i <= height; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var p = i * width1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var end = p + width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    while (p < end && !points[p]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      p++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (p === end) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var coords = [p % width1, i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.fallbackName = (this.isMonospace ? 'monospace' : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                         (this.isSerifFont ? 'serif' : 'sans-serif')); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var type = points[p], p0 = p, pp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    do { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var step = steps[type]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      do { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        p += step; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } while (!points[p]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.differences = properties.differences; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.widths = properties.widths; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.defaultWidth = properties.defaultWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.composite = properties.composite; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.wideChars = properties.wideChars; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.cMap = properties.cMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.ascent = properties.ascent / PDF_GLYPH_SPACE_UNITS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.descent = properties.descent / PDF_GLYPH_SPACE_UNITS; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.fontMatrix = properties.fontMatrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.bbox = properties.bbox; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      pp = points[p]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (pp !== 5 && pp !== 10) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // set new direction 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        type = pp; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // delete mark 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        points[p] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { // type is 5 or 10, ie, a crossing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // set new direction 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        type = pp & ((0x33 * type) >> 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // set new type for "future hit" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        points[p] &= (type >> 2 | type << 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.toUnicode = properties.toUnicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      coords.push(p % width1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      coords.push((p / width1) | 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      --count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } while (p0 !== p); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    outlines.push(coords); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    --i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.toFontChar = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var drawOutline = function(c) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    c.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // the path shall be painted in [0..1]x[0..1] space 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    c.scale(1 / width, -1 / height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    c.translate(0, -height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    c.beginPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (var i = 0, ii = outlines.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var o = outlines[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      c.moveTo(o[0], o[1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var j = 2, jj = o.length; j < jj; j += 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        c.lineTo(o[j], o[j+1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (properties.type === 'Type3') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (charCode = 0; charCode < 256; charCode++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.toFontChar[charCode] = (this.differences[charCode] || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                     properties.defaultEncoding[charCode]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.fontType = FontType.TYPE3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    c.fill(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    c.beginPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    c.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return drawOutline; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var CanvasExtraState = (function CanvasExtraStateClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function CanvasExtraState(old) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Are soft masks and alpha values shapes or opacities? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.alphaIsShape = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.fontSize = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.fontSizeScale = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.textMatrix = IDENTITY_MATRIX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.textMatrixScale = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.fontMatrix = FONT_IDENTITY_MATRIX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.leading = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Current point (in user coordinates) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.x = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.y = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Start of text line (in text coordinates) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.lineX = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.lineY = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Character and word spacing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.charSpacing = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.wordSpacing = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.textHScale = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.textRenderingMode = TextRenderingMode.FILL; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.textRise = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Default fore and background colors 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.fillColor = '#000000'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.strokeColor = '#000000'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.patternFill = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Note: fill alpha applies to all non-stroking operations 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.fillAlpha = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.strokeAlpha = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.lineWidth = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.activeSMask = null; // nonclonable field (see the save method below) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.old = old; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  CanvasExtraState.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    clone: function CanvasExtraState_clone() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return Object.create(this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setCurrentPoint: function CanvasExtraState_setCurrentPoint(x, y) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.x = x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.y = y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.cidEncoding = properties.cidEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.vertical = properties.vertical; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (this.vertical) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.vmetrics = properties.vmetrics; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.defaultVMetrics = properties.defaultVMetrics; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return CanvasExtraState; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var glyphsUnicodeMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!file || file.isEmpty) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (file) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Some bad PDF generators will include empty font files, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // attempting to recover by assuming that no file exists. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        warn('Font file is empty in "' + name + '" (' + this.loadedName + ')'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-var CanvasGraphics = (function CanvasGraphicsClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // Defines the time the executeOperatorList is going to be executing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // before it stops and shedules a continue of execution. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var EXECUTION_TIME = 15; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  // Defines the number of steps before checking the execution time 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var EXECUTION_STEPS = 10; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.missingFile = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // The file data is not specified. Trying to fix the font name 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // to be used with the canvas.font. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fontName = name.replace(/[,_]/g, '-'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var stdFontMap = getStdFontMap(), nonStdFontMap = getNonStdFontMap(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var isStandardFont = !!stdFontMap[fontName] || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        !!(nonStdFontMap[fontName] && stdFontMap[nonStdFontMap[fontName]]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      fontName = stdFontMap[fontName] || nonStdFontMap[fontName] || fontName; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function CanvasGraphics(canvasCtx, commonObjs, objs, imageLayer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.ctx = canvasCtx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.current = new CanvasExtraState(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.stateStack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.pendingClip = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.pendingEOFill = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.res = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.xobjs = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.commonObjs = commonObjs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.objs = objs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.imageLayer = imageLayer; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.groupStack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.processingType3 = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Patterns are painted relative to the initial page/form transform, see pdf 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // spec 8.7.2 NOTE 1. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.baseTransform = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.baseTransformStack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.groupLevel = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.smaskStack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.smaskCounter = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.tempSMask = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.cachedCanvases = new CachedCanvases(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (canvasCtx) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // NOTE: if mozCurrentTransform is polyfilled, then the current state of 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // the transformation must already be set in canvasCtx._transformMatrix. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      addContextCurrentTransform(canvasCtx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    this.cachedGetSinglePixelWidth = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.bold = (fontName.search(/bold/gi) !== -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.italic = ((fontName.search(/oblique/gi) !== -1) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                     (fontName.search(/italic/gi) !== -1)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function putBinaryImageData(ctx, imgData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (typeof ImageData !== 'undefined' && imgData instanceof ImageData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.putImageData(imgData, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Use 'name' instead of 'fontName' here because the original 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // name ArialBlack for example will be replaced by Helvetica. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.black = (name.search(/Black/g) !== -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Put the image data to the canvas in chunks, rather than putting the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // whole image at once.  This saves JS memory, because the ImageData object 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // is smaller. It also possibly saves C++ memory within the implementation 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // of putImageData(). (E.g. in Firefox we make two short-lived copies of 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // the data passed to putImageData()). |n| shouldn't be too small, however, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // because too many putImageData() calls will slow things down. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Note: as written, if the last chunk is partial, the putImageData() call 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // will (conceptually) put pixels past the bounds of the canvas.  But 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // that's ok; any such pixels are ignored. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var height = imgData.height, width = imgData.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var partialChunkHeight = height % FULL_CHUNK_HEIGHT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var srcPos = 0, destPos; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var src = imgData.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var dest = chunkImgData.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var i, j, thisChunkHeight, elemsInThisChunk; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // There are multiple forms in which the pixel data can be passed, and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // imgData.kind tells us which one this is. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (imgData.kind === ImageKind.GRAYSCALE_1BPP) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Grayscale, 1 bit per pixel (i.e. black-and-white). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var srcLength = src.byteLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var dest32 = PDFJS.hasCanvasTypedArrays ? new Uint32Array(dest.buffer) : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        new Uint32ArrayView(dest); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var dest32DataLength = dest32.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fullSrcDiff = (width + 7) >> 3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var white = 0xFFFFFFFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var black = (PDFJS.isLittleEndian || !PDFJS.hasCanvasTypedArrays) ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        0xFF000000 : 0x000000FF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (i = 0; i < totalChunks; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        thisChunkHeight = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          (i < fullChunks) ? FULL_CHUNK_HEIGHT : partialChunkHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        destPos = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (j = 0; j < thisChunkHeight; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var srcDiff = srcLength - srcPos; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var k = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var kEnd = (srcDiff > fullSrcDiff) ? width : srcDiff * 8 - 7; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var kEndUnrolled = kEnd & ~7; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var mask = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var srcByte = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (; k < kEndUnrolled; k += 8) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            srcByte = src[srcPos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            dest32[destPos++] = (srcByte & 128) ? white : black; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            dest32[destPos++] = (srcByte & 64) ? white : black; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            dest32[destPos++] = (srcByte & 32) ? white : black; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            dest32[destPos++] = (srcByte & 16) ? white : black; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            dest32[destPos++] = (srcByte & 8) ? white : black; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            dest32[destPos++] = (srcByte & 4) ? white : black; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            dest32[destPos++] = (srcByte & 2) ? white : black; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            dest32[destPos++] = (srcByte & 1) ? white : black; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (; k < kEnd; k++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-             if (mask === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-               srcByte = src[srcPos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-               mask = 128; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            dest32[destPos++] = (srcByte & mask) ? white : black; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            mask >>= 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // if at least one width is present, remeasure all chars when exists 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.remeasure = Object.keys(this.widths).length > 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (isStandardFont && type === 'CIDFontType2' && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          properties.cidEncoding.indexOf('Identity-') === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var GlyphMapForStandardFonts = getGlyphMapForStandardFonts(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Standard fonts might be embedded as CID font without glyph mapping. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Building one based on GlyphMapForStandardFonts. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var map = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (charCode in GlyphMapForStandardFonts) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          map[+charCode] = GlyphMapForStandardFonts[charCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (/ArialBlack/i.test(name)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var SupplementalGlyphMapForArialBlack = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            getSupplementalGlyphMapForArialBlack(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (charCode in SupplementalGlyphMapForArialBlack) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            map[+charCode] = SupplementalGlyphMapForArialBlack[charCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // We ran out of input. Make all remaining pixels transparent. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        while (destPos < dest32DataLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          dest32[destPos++] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var isIdentityUnicode = this.toUnicode instanceof IdentityToUnicodeMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!isIdentityUnicode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.toUnicode.forEach(function(charCode, unicodeCharCode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            map[+charCode] = unicodeCharCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.toFontChar = map; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.toUnicode = new ToUnicodeMap(map); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else if (/Symbol/i.test(fontName)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.toFontChar = buildToFontChar(SymbolSetEncoding, getGlyphsUnicode(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                          properties.differences); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else if (/Dingbats/i.test(fontName)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (/Wingdings/i.test(name)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          warn('Non-embedded Wingdings font, falling back to ZapfDingbats.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.toFontChar = buildToFontChar(ZapfDingbatsEncoding, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                          getDingbatsGlyphsUnicode(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                          properties.differences); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else if (isStandardFont) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.toFontChar = buildToFontChar(properties.defaultEncoding, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                          getGlyphsUnicode(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                          properties.differences); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        glyphsUnicodeMap = getGlyphsUnicode(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.toUnicode.forEach(function(charCode, unicodeCharCode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (!this.composite) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            glyphName = (properties.differences[charCode] || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                         properties.defaultEncoding[charCode]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            unicode = getUnicodeForGlyph(glyphName, glyphsUnicodeMap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (unicode !== -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              unicodeCharCode = unicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.toFontChar[charCode] = unicodeCharCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }.bind(this)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } else if (imgData.kind === ImageKind.RGBA_32BPP) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // RGBA, 32-bits per pixel. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      j = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      elemsInThisChunk = width * FULL_CHUNK_HEIGHT * 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (i = 0; i < fullChunks; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        srcPos += elemsInThisChunk; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.loadedName = fontName.split('-')[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.loading = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.fontType = getFontType(type, subtype); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.putImageData(chunkImgData, 0, j); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        j += FULL_CHUNK_HEIGHT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Some fonts might use wrong font types for Type1C or CIDFontType0C 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (subtype === 'Type1C' && (type !== 'Type1' && type !== 'MMType1')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Some TrueType fonts by mistake claim Type1C 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (isTrueTypeFile(file)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        subtype = 'TrueType'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        type = 'Type1'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (i < totalChunks) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        elemsInThisChunk = width * partialChunkHeight * 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        dest.set(src.subarray(srcPos, srcPos + elemsInThisChunk)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.putImageData(chunkImgData, 0, j); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (subtype === 'CIDFontType0C' && type !== 'CIDFontType0') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      type = 'CIDFontType0'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (subtype === 'OpenType') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      type = 'OpenType'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Some CIDFontType0C fonts by mistake claim CIDFontType0. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (type === 'CIDFontType0') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (isType1File(file)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        subtype = 'CIDFontType0'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else if (isOpenTypeFile(file)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Sometimes the type/subtype can be a complete lie (see issue6782.pdf). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        type = subtype = 'OpenType'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        subtype = 'CIDFontType0C'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } else if (imgData.kind === ImageKind.RGB_24BPP) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // RGB, 24-bits per pixel. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      thisChunkHeight = FULL_CHUNK_HEIGHT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      elemsInThisChunk = width * thisChunkHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (i = 0; i < totalChunks; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (i >= fullChunks) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          thisChunkHeight = partialChunkHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          elemsInThisChunk = width * thisChunkHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    switch (type) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case 'MMType1': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        info('MMType1 font (' + name + '), falling back to Type1.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        /* falls through */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case 'Type1': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case 'CIDFontType0': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.mimetype = 'font/opentype'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        destPos = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (j = elemsInThisChunk; j--;) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          dest[destPos++] = src[srcPos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          dest[destPos++] = src[srcPos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          dest[destPos++] = src[srcPos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          dest[destPos++] = 255; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      error('bad image kind: ' + imgData.kind); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var cff = (subtype === 'Type1C' || subtype === 'CIDFontType0C') ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          new CFFFont(file, properties) : new Type1Font(name, file, properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function putBinaryImageMask(ctx, imgData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var height = imgData.height, width = imgData.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var partialChunkHeight = height % FULL_CHUNK_HEIGHT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var fullChunks = (height - partialChunkHeight) / FULL_CHUNK_HEIGHT; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var totalChunks = partialChunkHeight === 0 ? fullChunks : fullChunks + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        adjustWidths(properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var chunkImgData = ctx.createImageData(width, FULL_CHUNK_HEIGHT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var srcPos = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var src = imgData.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var dest = chunkImgData.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Wrap the CFF data inside an OTF font file 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        data = this.convert(name, cff, properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (var i = 0; i < totalChunks; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var thisChunkHeight = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        (i < fullChunks) ? FULL_CHUNK_HEIGHT : partialChunkHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case 'OpenType': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case 'TrueType': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      case 'CIDFontType2': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.mimetype = 'font/opentype'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Expand the mask so it can be used by the canvas.  Any required 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // inversion has already been handled. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var destPos = 3; // alpha component offset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var j = 0; j < thisChunkHeight; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var mask = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        for (var k = 0; k < width; k++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (!mask) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var elem = src[srcPos++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            mask = 128; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          dest[destPos] = (elem & mask) ? 0 : 255; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          destPos += 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          mask >>= 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Repair the TrueType file. It is can be damaged in the point of 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // view of the sanitizer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        data = this.checkAndRepair(name, file, properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (this.isOpenType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          adjustWidths(properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          type = 'OpenType'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.putImageData(chunkImgData, 0, i * FULL_CHUNK_HEIGHT); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function copyCtxState(sourceCtx, destCtx) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var properties = ['strokeStyle', 'fillStyle', 'fillRule', 'globalAlpha', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      'lineWidth', 'lineCap', 'lineJoin', 'miterLimit', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      'globalCompositeOperation', 'font']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (var i = 0, ii = properties.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var property = properties[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (sourceCtx[property] !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        destCtx[property] = sourceCtx[property]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (sourceCtx.setLineDash !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      destCtx.setLineDash(sourceCtx.getLineDash()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      destCtx.lineDashOffset =  sourceCtx.lineDashOffset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } else if (sourceCtx.mozDashOffset !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      destCtx.mozDash = sourceCtx.mozDash; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      destCtx.mozDashOffset = sourceCtx.mozDashOffset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        error('Font ' + type + ' is not supported'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.data = data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.fontType = getFontType(type, subtype); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Transfer some properties again that could change during font conversion 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.fontMatrix = properties.fontMatrix; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.widths = properties.widths; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.defaultWidth = properties.defaultWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.encoding = properties.baseEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.seacMap = properties.seacMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.loading = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function composeSMaskBackdrop(bytes, r0, g0, b0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var length = bytes.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (var i = 3; i < length; i += 4) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var alpha = bytes[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (alpha === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        bytes[i - 3] = r0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        bytes[i - 2] = g0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        bytes[i - 1] = b0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else if (alpha < 255) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var alpha_ = 255 - alpha; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        bytes[i - 3] = (bytes[i - 3] * alpha + r0 * alpha_) >> 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        bytes[i - 2] = (bytes[i - 2] * alpha + g0 * alpha_) >> 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        bytes[i - 1] = (bytes[i - 1] * alpha + b0 * alpha_) >> 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Font.getFontID = (function () { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var ID = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return function Font_getFontID() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return String(ID++); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  })(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function int16(b0, b1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return (b0 << 8) + b1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function composeSMaskAlpha(maskData, layerData, transferMap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var length = maskData.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var scale = 1 / 255; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (var i = 3; i < length; i += 4) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var alpha = transferMap ? transferMap[maskData[i]] : maskData[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      layerData[i] = (layerData[i] * alpha * scale) | 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function signedInt16(b0, b1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var value = (b0 << 8) + b1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return value & (1 << 15) ? value - 0x10000 : value; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function composeSMaskLuminosity(maskData, layerData, transferMap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var length = maskData.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (var i = 3; i < length; i += 4) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var y = (maskData[i - 3] * 77) +  // * 0.3 / 255 * 0x10000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              (maskData[i - 2] * 152) + // * 0.59 .... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              (maskData[i - 1] * 28);   // * 0.11 .... 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      layerData[i] = transferMap ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        (layerData[i] * transferMap[y >> 8]) >> 8 : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        (layerData[i] * y) >> 16; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function int32(b0, b1, b2, b3) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return (b0 << 24) + (b1 << 16) + (b2 << 8) + b3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function genericComposeSMask(maskCtx, layerCtx, width, height, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                               subtype, backdrop, transferMap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var hasBackdrop = !!backdrop; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var r0 = hasBackdrop ? backdrop[0] : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var g0 = hasBackdrop ? backdrop[1] : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var b0 = hasBackdrop ? backdrop[2] : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function string16(value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return String.fromCharCode((value >> 8) & 0xff, value & 0xff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var composeFn; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (subtype === 'Luminosity') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      composeFn = composeSMaskLuminosity; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      composeFn = composeSMaskAlpha; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function safeString16(value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // clamp value to the 16-bit int range 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    value = (value > 0x7FFF ? 0x7FFF : (value < -0x8000 ? -0x8000 : value)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return String.fromCharCode((value >> 8) & 0xff, value & 0xff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // processing image in chunks to save memory 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var PIXELS_TO_PROCESS = 1048576; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var chunkSize = Math.min(height, Math.ceil(PIXELS_TO_PROCESS / width)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    for (var row = 0; row < height; row += chunkSize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var chunkHeight = Math.min(chunkSize, height - row); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var maskData = maskCtx.getImageData(0, row, width, chunkHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var layerData = layerCtx.getImageData(0, row, width, chunkHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function isTrueTypeFile(file) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var header = file.peekBytes(4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return readUint32(header, 0) === 0x00010000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (hasBackdrop) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        composeSMaskBackdrop(maskData.data, r0, g0, b0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      composeFn(maskData.data, layerData.data, transferMap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function isOpenTypeFile(file) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var header = file.peekBytes(4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return bytesToString(header) === 'OTTO'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      maskCtx.putImageData(layerData, 0, row); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function isType1File(file) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var header = file.peekBytes(2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // All Type1 font programs must begin with the comment '%!' (0x25 + 0x21). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (header[0] === 0x25 && header[1] === 0x21) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // ... obviously some fonts violate that part of the specification, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // please refer to the comment in |Type1Font| below. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (header[0] === 0x80 && header[1] === 0x01) { // pfb file header. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  function composeSMask(ctx, smask, layerCtx) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var mask = smask.canvas; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var maskCtx = smask.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ctx.setTransform(smask.scaleX, 0, 0, smask.scaleY, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                     smask.offsetX, smask.offsetY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    var backdrop = smask.backdrop || null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    if (!smask.transferMap && WebGLUtils.isEnabled) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var composed = WebGLUtils.composeSMask(layerCtx.canvas, mask, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        {subtype: smask.subtype, backdrop: backdrop}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.setTransform(1, 0, 0, 1, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.drawImage(composed, smask.offsetX, smask.offsetY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function buildToFontChar(encoding, glyphsUnicodeMap, differences) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var toFontChar = [], unicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (var i = 0, ii = encoding.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      unicode = getUnicodeForGlyph(encoding[i], glyphsUnicodeMap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (unicode !== -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        toFontChar[i] = unicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    genericComposeSMask(maskCtx, layerCtx, mask.width, mask.height, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                        smask.subtype, backdrop, smask.transferMap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    ctx.drawImage(mask, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (var charCode in differences) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      unicode = getUnicodeForGlyph(differences[charCode], glyphsUnicodeMap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (unicode !== -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        toFontChar[+charCode] = unicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return toFontChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var LINE_CAP_STYLES = ['butt', 'round', 'square']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var LINE_JOIN_STYLES = ['miter', 'round', 'bevel']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var NORMAL_CLIP = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  var EO_CLIP = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  CanvasGraphics.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    beginDrawing: function CanvasGraphics_beginDrawing(transform, viewport, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                       transparency) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // For pdfs that use blend modes we have to clear the canvas else certain 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // blend modes can look wrong since we'd be blending with a white 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // backdrop. The problem with a transparent backdrop though is we then 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // don't get sub pixel anti aliasing on text, creating temporary 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // transparent canvas when we have blend modes. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var width = this.ctx.canvas.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var height = this.ctx.canvas.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.fillStyle = 'rgb(255, 255, 255)'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.fillRect(0, 0, width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (transparency) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var transparentCanvas = this.cachedCanvases.getCanvas( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          'transparent', width, height, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.compositeCtx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.transparentCanvas = transparentCanvas.canvas; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx = transparentCanvas.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // The transform can be applied before rendering, transferring it to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // the new canvas. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx.transform.apply(this.ctx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                 this.compositeCtx.mozCurrentTransform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * Helper function for |adjustMapping|. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * @return {boolean} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function isProblematicUnicodeLocation(code) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Using binary search to find a range start. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var i = 0, j = ProblematicCharRanges.length - 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    while (i < j) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var c = (i + j + 1) >> 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (code < ProblematicCharRanges[c]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        j = c - 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        i = c; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Even index means code in problematic range. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return !(i & 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (transform) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx.transform.apply(this.ctx, transform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * Rebuilds the char code to glyph ID map by trying to replace the char codes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * with their unicode value. It also moves char codes that are in known 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * problematic locations. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * @return {Object} Two properties: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * 'toFontChar' - maps original char codes(the value that will be read 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * from commands such as show text) to the char codes that will be used in the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * font that we build 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   * 'charCodeToGlyphId' - maps the new font char codes to glyph ids 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+   */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function adjustMapping(charCodeToGlyphId, properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var toUnicode = properties.toUnicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var isSymbolic = !!(properties.flags & FontFlags.Symbolic); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var isIdentityUnicode = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      properties.toUnicode instanceof IdentityToUnicodeMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var newMap = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var toFontChar = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var usedFontCharCodes = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var nextAvailableFontCharCode = PRIVATE_USE_OFFSET_START; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (var originalCharCode in charCodeToGlyphId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      originalCharCode |= 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var glyphId = charCodeToGlyphId[originalCharCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fontCharCode = originalCharCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // First try to map the value to a unicode position if a non identity map 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // was created. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!isIdentityUnicode && toUnicode.has(originalCharCode)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var unicode = toUnicode.get(fontCharCode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // TODO: Try to map ligatures to the correct spot. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (unicode.length === 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          fontCharCode = unicode.charCodeAt(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.transform.apply(this.ctx, viewport.transform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Try to move control characters, special characters and already mapped 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // characters to the private use area since they will not be drawn by 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // canvas if left in their current position. Also, move characters if the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // font was symbolic and there is only an identity unicode map since the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // characters probably aren't in the correct position (fixes an issue 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // with firefox and thuluthfont). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if ((usedFontCharCodes[fontCharCode] !== undefined || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           isProblematicUnicodeLocation(fontCharCode) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           (isSymbolic && isIdentityUnicode)) && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          nextAvailableFontCharCode <= PRIVATE_USE_OFFSET_END) { // Room left. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Loop to try and find a free spot in the private use area. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        do { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          fontCharCode = nextAvailableFontCharCode++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.baseTransform = this.ctx.mozCurrentTransform.slice(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (SKIP_PRIVATE_USE_RANGE_F000_TO_F01F && fontCharCode === 0xF000) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            fontCharCode = 0xF020; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            nextAvailableFontCharCode = fontCharCode + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.imageLayer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.imageLayer.beginLayout(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } while (usedFontCharCodes[fontCharCode] !== undefined && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 nextAvailableFontCharCode <= PRIVATE_USE_OFFSET_END); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    executeOperatorList: function CanvasGraphics_executeOperatorList( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                    operatorList, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                    executionStartIdx, continueCallback, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                    stepper) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var argsArray = operatorList.argsArray; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fnArray = operatorList.fnArray; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var i = executionStartIdx || 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var argsArrayLen = argsArray.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      newMap[fontCharCode] = glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      toFontChar[originalCharCode] = fontCharCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      usedFontCharCodes[fontCharCode] = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      toFontChar: toFontChar, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      charCodeToGlyphId: newMap, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      nextAvailableFontCharCode: nextAvailableFontCharCode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Sometimes the OperatorList to execute is empty. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (argsArrayLen === i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function getRanges(glyphs, numGlyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Array.sort() sorts by characters, not numerically, so convert to an 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // array of characters. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var codes = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (var charCode in glyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Remove an invalid glyph ID mappings to make OTS happy. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (glyphs[charCode] >= numGlyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      codes.push({ fontCharCode: charCode | 0, glyphId: glyphs[charCode] }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    codes.sort(function fontGetRangesSort(a, b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return a.fontCharCode - b.fontCharCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var chunkOperations = (argsArrayLen - i > EXECUTION_STEPS && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                             typeof continueCallback === 'function'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var endTime = chunkOperations ? Date.now() + EXECUTION_TIME : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var steps = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Split the sorted codes into ranges. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var ranges = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var length = codes.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (var n = 0; n < length; ) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var start = codes[n].fontCharCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var codeIndices = [codes[n].glyphId]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ++n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var end = start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      while (n < length && end + 1 === codes[n].fontCharCode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        codeIndices.push(codes[n].glyphId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ++end; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ++n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (end === 0xFFFF) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ranges.push([start, end, codeIndices]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var commonObjs = this.commonObjs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var objs = this.objs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fnId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return ranges; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      while (true) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (stepper !== undefined && i === stepper.nextBreakPoint) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          stepper.breakIt(i, continueCallback); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function createCmapTable(glyphs, numGlyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var ranges = getRanges(glyphs, numGlyphs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var numTables = ranges[ranges.length - 1][1] > 0xFFFF ? 2 : 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var cmap = '\x00\x00' + // version 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               string16(numTables) +  // numTables 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               '\x00\x03' + // platformID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               '\x00\x01' + // encodingID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               string32(4 + numTables * 8); // start of the table record 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        fnId = fnArray[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var i, ii, j, jj; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (i = ranges.length - 1; i >= 0; --i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (ranges[i][0] <= 0xFFFF) { break; } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var bmpLength = i + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (fnId !== OPS.dependency) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          this[fnId].apply(this, argsArray[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var deps = argsArray[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          for (var n = 0, nn = deps.length; n < nn; n++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var depObjId = deps[n]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var common = depObjId[0] === 'g' && depObjId[1] === '_'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var objsPool = common ? commonObjs : objs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (ranges[i][0] < 0xFFFF && ranges[i][1] === 0xFFFF) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ranges[i][1] = 0xFFFE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var trailingRangesCount = ranges[i][1] < 0xFFFF ? 1 : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var segCount = bmpLength + trailingRangesCount; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var searchParams = OpenTypeFileBuilder.getSearchParams(segCount, 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // If the promise isn't resolved yet, add the continueCallback 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // to the promise and bail out. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (!objsPool.isResolved(depObjId)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              objsPool.get(depObjId, continueCallback); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              return i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Fill up the 4 parallel arrays describing the segments. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var startCount = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var endCount = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var idDeltas = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var idRangeOffsets = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var glyphsIds = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var bias = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var range, start, end, codes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (i = 0, ii = bmpLength; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      range = ranges[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      start = range[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      end = range[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      startCount += string16(start); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      endCount += string16(end); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      codes = range[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var contiguous = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (j = 1, jj = codes.length; j < jj; ++j) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (codes[j] !== codes[j - 1] + 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          contiguous = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!contiguous) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var offset = (segCount - i) * 2 + bias * 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bias += (end - start + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        i++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        idDeltas += string16(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        idRangeOffsets += string16(offset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // If the entire operatorList was executed, stop as were done. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (i === argsArrayLen) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          return i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (j = 0, jj = codes.length; j < jj; ++j) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          glyphsIds += string16(codes[j]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var startCode = codes[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // If the execution took longer then a certain amount of time and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // `continueCallback` is specified, interrupt the execution. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (chunkOperations && ++steps > EXECUTION_STEPS) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (Date.now() > endTime) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            continueCallback(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        idDeltas += string16((startCode - start) & 0xFFFF); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        idRangeOffsets += string16(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (trailingRangesCount > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      endCount += '\xFF\xFF'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      startCount += '\xFF\xFF'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      idDeltas += '\x00\x01'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      idRangeOffsets += '\x00\x00'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var format314 = '\x00\x00' + // language 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    string16(2 * segCount) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    string16(searchParams.range) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    string16(searchParams.entry) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    string16(searchParams.rangeShift) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    endCount + '\x00\x00' + startCount + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    idDeltas + idRangeOffsets + glyphsIds; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var format31012 = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var header31012 = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (numTables > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      cmap += '\x00\x03' + // platformID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              '\x00\x0A' + // encodingID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              string32(4 + numTables * 8 + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       4 + format314.length); // start of the table record 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      format31012 = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (i = 0, ii = ranges.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        range = ranges[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        start = range[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        codes = range[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var code = codes[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (j = 1, jj = codes.length; j < jj; ++j) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (codes[j] !== codes[j - 1] + 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            end = range[0] + j - 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            format31012 += string32(start) + // startCharCode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                           string32(end) + // endCharCode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                           string32(code); // startGlyphID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            start = end + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            code = codes[j]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          steps = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // If the operatorList isn't executed completely yet OR the execution 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // time was short enough, do another execution round. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        format31012 += string32(start) + // startCharCode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       string32(range[1]) + // endCharCode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       string32(code); // startGlyphID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      header31012 = '\x00\x0C' + // format 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    '\x00\x00' + // reserved 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    string32(format31012.length + 16) + // length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    '\x00\x00\x00\x00' + // language 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    string32(format31012.length / 12); // nGroups 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    endDrawing: function CanvasGraphics_endDrawing() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return cmap + '\x00\x04' + // format 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  string16(format314.length + 4) + // length 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  format314 + header31012 + format31012; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.transparentCanvas) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx = this.compositeCtx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx.setTransform(1, 0, 0, 1, 0, 0); // Avoid apply transform twice 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx.drawImage(this.transparentCanvas, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.transparentCanvas = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function validateOS2Table(os2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var stream = new Stream(os2.data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var version = stream.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // TODO verify all OS/2 tables fields, but currently we validate only those 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // that give us issues 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    stream.getBytes(60); // skipping type, misc sizes, panose, unicode ranges 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var selection = stream.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (version < 4 && (selection & 0x0300)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var firstChar = stream.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var lastChar = stream.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (firstChar > lastChar) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    stream.getBytes(6); // skipping sTypoAscender/Descender/LineGap 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var usWinAscent = stream.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (usWinAscent === 0) { // makes font unreadable by windows 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.cachedCanvases.clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      WebGLUtils.clear(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // OS/2 appears to be valid, resetting some fields 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    os2.data[8] = os2.data[9] = 0; // IE rejects fonts if fsType != 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.imageLayer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.imageLayer.endLayout(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function createOS2Table(properties, charstrings, override) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    override = override || { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      unitsPerEm: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      yMax: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      yMin: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ascent: 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      descent: 0 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Graphics state 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setLineWidth: function CanvasGraphics_setLineWidth(width) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.lineWidth = width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.lineWidth = width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setLineCap: function CanvasGraphics_setLineCap(style) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.lineCap = LINE_CAP_STYLES[style]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setLineJoin: function CanvasGraphics_setLineJoin(style) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.lineJoin = LINE_JOIN_STYLES[style]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setMiterLimit: function CanvasGraphics_setMiterLimit(limit) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.miterLimit = limit; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setDash: function CanvasGraphics_setDash(dashArray, dashPhase) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (ctx.setLineDash !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.setLineDash(dashArray); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.lineDashOffset = dashPhase; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.mozDash = dashArray; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.mozDashOffset = dashPhase; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setRenderingIntent: function CanvasGraphics_setRenderingIntent(intent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Maybe if we one day fully support color spaces this will be important 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // for now we can ignore. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // TODO set rendering intent? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setFlatness: function CanvasGraphics_setFlatness(flatness) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // There's no way to control this with canvas, but we can safely ignore. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // TODO set flatness? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setGState: function CanvasGraphics_setGState(states) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var i = 0, ii = states.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var state = states[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var key = state[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var value = state[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var ulUnicodeRange1 = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var ulUnicodeRange2 = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var ulUnicodeRange3 = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var ulUnicodeRange4 = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        switch (key) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case 'LW': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.setLineWidth(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case 'LC': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.setLineCap(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case 'LJ': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.setLineJoin(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case 'ML': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.setMiterLimit(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case 'D': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.setDash(value[0], value[1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case 'RI': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.setRenderingIntent(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case 'FL': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.setFlatness(value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case 'Font': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.setFont(value[0], value[1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case 'CA': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.current.strokeAlpha = state[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case 'ca': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.current.fillAlpha = state[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.ctx.globalAlpha = state[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case 'BM': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (value && value.name && (value.name !== 'Normal')) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              var mode = value.name.replace(/([A-Z])/g, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                function(c) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                  return '-' + c.toLowerCase(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              ).substring(1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              this.ctx.globalCompositeOperation = mode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              if (this.ctx.globalCompositeOperation !== mode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                warn('globalCompositeOperation "' + mode + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                     '" is not supported'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              this.ctx.globalCompositeOperation = 'source-over'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case 'SMask': 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (this.current.activeSMask) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              this.endSMaskGroup(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.current.activeSMask = value ? this.tempSMask : null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (this.current.activeSMask) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              this.beginSMaskGroup(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.tempSMask = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var firstCharIndex = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var lastCharIndex = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (charstrings) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var code in charstrings) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        code |= 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (firstCharIndex > code || !firstCharIndex) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          firstCharIndex = code; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (lastCharIndex < code) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          lastCharIndex = code; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    beginSMaskGroup: function CanvasGraphics_beginSMaskGroup() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var activeSMask = this.current.activeSMask; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var drawnWidth = activeSMask.canvas.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var drawnHeight = activeSMask.canvas.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var cacheId = 'smaskGroupAt' + this.groupLevel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var scratchCanvas = this.cachedCanvases.getCanvas( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cacheId, drawnWidth, drawnHeight, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var position = getUnicodeRangeFor(code); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (position < 32) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ulUnicodeRange1 |= 1 << position; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (position < 64) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ulUnicodeRange2 |= 1 << position - 32; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (position < 96) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ulUnicodeRange3 |= 1 << position - 64; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (position < 123) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ulUnicodeRange4 |= 1 << position - 96; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          error('Unicode ranges Bits > 123 are reserved for internal usage'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // TODO 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      firstCharIndex = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      lastCharIndex = 255; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var currentCtx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var currentTransform = currentCtx.mozCurrentTransform; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var bbox = properties.bbox || [0, 0, 0, 0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var unitsPerEm = (override.unitsPerEm || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      1 / (properties.fontMatrix || FONT_IDENTITY_MATRIX)[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var groupCtx = scratchCanvas.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      groupCtx.scale(1 / activeSMask.scaleX, 1 / activeSMask.scaleY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      groupCtx.translate(-activeSMask.offsetX, -activeSMask.offsetY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      groupCtx.transform.apply(groupCtx, currentTransform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // if the font units differ to the PDF glyph space units 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // then scale up the values 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var scale = (properties.ascentScaled ? 1.0 : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                 unitsPerEm / PDF_GLYPH_SPACE_UNITS); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      copyCtxState(currentCtx, groupCtx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx = groupCtx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.setGState([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ['BM', 'Normal'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ['ca', 1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ['CA', 1] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.groupStack.push(currentCtx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.groupLevel++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    endSMaskGroup: function CanvasGraphics_endSMaskGroup() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var groupCtx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.groupLevel--; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx = this.groupStack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var typoAscent = (override.ascent || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                      Math.round(scale * (properties.ascent || bbox[3]))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var typoDescent = (override.descent || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       Math.round(scale * (properties.descent || bbox[1]))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (typoDescent > 0 && properties.descent > 0 && bbox[1] < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      typoDescent = -typoDescent; // fixing incorrect descent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var winAscent = override.yMax || typoAscent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var winDescent = -override.yMin || -typoDescent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      composeSMask(this.ctx, this.current.activeSMask, groupCtx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      copyCtxState(groupCtx, this.ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    save: function CanvasGraphics_save() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var old = this.current; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.stateStack.push(old); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current = old.clone(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.activeSMask = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    restore: function CanvasGraphics_restore() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.stateStack.length !== 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (this.current.activeSMask !== null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          this.endSMaskGroup(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return '\x00\x03' + // version 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x02\x24' + // xAvgCharWidth 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x01\xF4' + // usWeightClass 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x00\x05' + // usWidthClass 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x00\x00' + // fstype (0 to let the font loads via font-face on IE) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x02\x8A' + // ySubscriptXSize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x02\xBB' + // ySubscriptYSize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x00\x00' + // ySubscriptXOffset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x00\x8C' + // ySubscriptYOffset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x02\x8A' + // ySuperScriptXSize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x02\xBB' + // ySuperScriptYSize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x00\x00' + // ySuperScriptXOffset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x01\xDF' + // ySuperScriptYOffset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x00\x31' + // yStrikeOutSize 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x01\x02' + // yStrikeOutPosition 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x00\x00' + // sFamilyClass 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x00\x00\x06' + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           String.fromCharCode(properties.fixedPitch ? 0x09 : 0x00) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x00\x00\x00\x00\x00\x00' + // Panose 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           string32(ulUnicodeRange1) + // ulUnicodeRange1 (Bits 0-31) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           string32(ulUnicodeRange2) + // ulUnicodeRange2 (Bits 32-63) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           string32(ulUnicodeRange3) + // ulUnicodeRange3 (Bits 64-95) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           string32(ulUnicodeRange4) + // ulUnicodeRange4 (Bits 96-127) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x2A\x32\x31\x2A' + // achVendID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           string16(properties.italicAngle ? 1 : 0) + // fsSelection 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           string16(firstCharIndex || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                    properties.firstChar) + // usFirstCharIndex 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           string16(lastCharIndex || properties.lastChar) +  // usLastCharIndex 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           string16(typoAscent) + // sTypoAscender 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           string16(typoDescent) + // sTypoDescender 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x00\x64' + // sTypoLineGap (7%-10% of the unitsPerEM value) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           string16(winAscent) + // usWinAscent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           string16(winDescent) + // usWinDescent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x00\x00\x00\x00' + // ulCodePageRange1 (Bits 0-31) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x00\x00\x00\x00' + // ulCodePageRange2 (Bits 32-63) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           string16(properties.xHeight) + // sxHeight 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           string16(properties.capHeight) + // sCapHeight 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           string16(0) + // usDefaultChar 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           string16(firstCharIndex || properties.firstChar) + // usBreakChar 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+           '\x00\x03';  // usMaxContext 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.current = this.stateStack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function createPostTable(properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var angle = Math.floor(properties.italicAngle * (Math.pow(2, 16))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return ('\x00\x03\x00\x00' + // Version number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            string32(angle) + // italicAngle 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00' + // underlinePosition 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00' + // underlineThickness 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            string32(properties.fixedPitch) + // isFixedPitch 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00\x00\x00' + // minMemType42 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00\x00\x00' + // maxMemType42 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00\x00\x00' + // minMemType1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00\x00\x00');  // maxMemType1 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Ensure that the clipping path is reset (fixes issue6413.pdf). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.pendingClip = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function createNameTable(name, proto) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (!proto) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      proto = [[], []]; // no strings and unicode strings 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.cachedGetSinglePixelWidth = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    transform: function CanvasGraphics_transform(a, b, c, d, e, f) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.transform(a, b, c, d, e, f); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var strings = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      proto[0][0] || 'Original licence',  // 0.Copyright 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      proto[0][1] || name,                // 1.Font family 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      proto[0][2] || 'Unknown',           // 2.Font subfamily (font weight) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      proto[0][3] || 'uniqueID',          // 3.Unique ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      proto[0][4] || name,                // 4.Full font name 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      proto[0][5] || 'Version 0.11',      // 5.Version 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      proto[0][6] || '',                  // 6.Postscript name 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      proto[0][7] || 'Unknown',           // 7.Trademark 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      proto[0][8] || 'Unknown',           // 8.Manufacturer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      proto[0][9] || 'Unknown'            // 9.Designer 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.cachedGetSinglePixelWidth = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Mac want 1-byte per character strings while Windows want 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 2-bytes per character, so duplicate the names table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var stringsUnicode = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var i, ii, j, jj, str; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (i = 0, ii = strings.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      str = proto[1][i] || strings[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Path 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    constructPath: function CanvasGraphics_constructPath(ops, args) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var current = this.current; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var x = current.x, y = current.y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var i = 0, j = 0, ii = ops.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        switch (ops[i] | 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case OPS.rectangle: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            x = args[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            y = args[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var width = args[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var height = args[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (width === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              width = this.getSinglePixelWidth(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (height === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              height = this.getSinglePixelWidth(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var strBufUnicode = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (j = 0, jj = str.length; j < jj; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        strBufUnicode.push(string16(str.charCodeAt(j))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      stringsUnicode.push(strBufUnicode.join('')); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var names = [strings, stringsUnicode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var platforms = ['\x00\x01', '\x00\x03']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var encodings = ['\x00\x00', '\x00\x01']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var languages = ['\x00\x00', '\x04\x09']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var namesRecordCount = strings.length * platforms.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var nameTable = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      '\x00\x00' +                           // format 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      string16(namesRecordCount) +           // Number of names Record 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      string16(namesRecordCount * 12 + 6);   // Storage 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Build the name records field 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var strOffset = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (i = 0, ii = platforms.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var strs = names[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (j = 0, jj = strs.length; j < jj; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        str = strs[j]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var nameRecord = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          platforms[i] + // platform ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          encodings[i] + // encoding ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          languages[i] + // language ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          string16(j) + // name ID 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          string16(str.length) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          string16(strOffset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        nameTable += nameRecord; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        strOffset += str.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    nameTable += strings.join('') + stringsUnicode.join(''); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return nameTable; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Font.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    name: null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    font: null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    mimetype: null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    encoding: null, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    get renderer() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var renderer = FontRendererFactory.create(this, SEAC_ANALYSIS_ENABLED); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return shadow(this, 'renderer', renderer); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exportData: function Font_exportData() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // TODO remove enumerating of the properties, e.g. hardcode exact names. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var data = {}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i in this) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (this.hasOwnProperty(i)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          data[i] = this[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    checkAndRepair: function Font_checkAndRepair(name, font, properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function readTableEntry(file) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var tag = bytesToString(file.getBytes(4)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var checksum = file.getInt32() >>> 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var offset = file.getInt32() >>> 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var length = file.getInt32() >>> 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Read the table associated data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var previousPosition = file.pos; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        file.pos = file.start ? file.start : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        file.skip(offset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var data = file.getBytes(length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        file.pos = previousPosition; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (tag === 'head') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // clearing checksum adjustment 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          data[8] = data[9] = data[10] = data[11] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          data[17] |= 0x20; //Set font optimized for cleartype flag 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          tag: tag, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          checksum: checksum, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          length: length, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          offset: offset, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          data: data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function readOpenTypeHeader(ttf) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          version: bytesToString(ttf.getBytes(4)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          numTables: ttf.getUint16(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          searchRange: ttf.getUint16(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          entrySelector: ttf.getUint16(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          rangeShift: ttf.getUint16() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      /** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       * Read the appropriate subtable from the cmap according to 9.6.6.4 from 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       * PDF spec 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+       */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function readCmapTable(cmap, font, isSymbolicFont, hasEncoding) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!cmap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          warn('No cmap table available.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            platformId: -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            encodingId: -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mappings: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            hasShortCmap: false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var segment; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var start = (font.start ? font.start : 0) + cmap.offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.pos = start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var version = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var numTables = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var potentialTable; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var canBreak = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // There's an order of preference in terms of which cmap subtable to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // use: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // - non-symbolic fonts the preference is a 3,1 table then a 1,0 table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // - symbolic fonts the preference is a 3,0 table then a 1,0 table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // The following takes advantage of the fact that the tables are sorted 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // to work. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (var i = 0; i < numTables; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var platformId = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var encodingId = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var offset = font.getInt32() >>> 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var useTable = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (platformId === 0 && encodingId === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            useTable = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // Continue the loop since there still may be a higher priority 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // table. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (platformId === 1 && encodingId === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            useTable = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // Continue the loop since there still may be a higher priority 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // table. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (platformId === 3 && encodingId === 1 && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                     ((!isSymbolicFont && hasEncoding) || !potentialTable)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            useTable = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!isSymbolicFont) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              canBreak = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var xw = x + width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var yh = y + height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.ctx.moveTo(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.ctx.lineTo(xw, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.ctx.lineTo(xw, yh); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.ctx.lineTo(x, yh); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.ctx.lineTo(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.ctx.closePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case OPS.moveTo: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            x = args[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            y = args[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ctx.moveTo(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case OPS.lineTo: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            x = args[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            y = args[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ctx.lineTo(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (isSymbolicFont && platformId === 3 && encodingId === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            useTable = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            canBreak = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (useTable) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            potentialTable = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              platformId: platformId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              encodingId: encodingId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              offset: offset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (canBreak) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case OPS.curveTo: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            x = args[j + 4]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            y = args[j + 5]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ctx.bezierCurveTo(args[j], args[j + 1], args[j + 2], args[j + 3], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                              x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            j += 6; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (potentialTable) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          font.pos = start + potentialTable.offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!potentialTable || font.peekByte() === -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          warn('Could not find a preferred cmap table.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            platformId: -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            encodingId: -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mappings: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            hasShortCmap: false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var format = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var length = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var language = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var hasShortCmap = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var mappings = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var j, glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // TODO(mack): refactor this cmap subtable reading logic out 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (format === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (j = 0; j < 256; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var index = font.getByte(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!index) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mappings.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              charCode: j, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              glyphId: index 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          hasShortCmap = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (format === 4) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // re-creating the table in format 4 since the encoding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // might be changed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var segCount = (font.getUint16() >> 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          font.getBytes(6); // skipping range fields 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var segIndex, segments = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (segIndex = 0; segIndex < segCount; segIndex++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            segments.push({ end: font.getUint16() }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (segIndex = 0; segIndex < segCount; segIndex++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            segments[segIndex].start = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (segIndex = 0; segIndex < segCount; segIndex++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            segments[segIndex].delta = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var offsetsCount = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (segIndex = 0; segIndex < segCount; segIndex++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            segment = segments[segIndex]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var rangeOffset = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!rangeOffset) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              segment.offsetIndex = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var offsetIndex = (rangeOffset >> 1) - (segCount - segIndex); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            segment.offsetIndex = offsetIndex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            offsetsCount = Math.max(offsetsCount, offsetIndex + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    segment.end - segment.start + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var offsets = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (j = 0; j < offsetsCount; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            offsets.push(font.getUint16()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (segIndex = 0; segIndex < segCount; segIndex++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            segment = segments[segIndex]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            start = segment.start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var end = segment.end; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var delta = segment.delta; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            offsetIndex = segment.offsetIndex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (j = start; j <= end; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (j === 0xFFFF) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              glyphId = (offsetIndex < 0 ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                         j : offsets[offsetIndex + j - start]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              glyphId = (glyphId + delta) & 0xFFFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (glyphId === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              mappings.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                charCode: j, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                glyphId: glyphId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (format === 6) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Format 6 is a 2-bytes dense mapping, which means the font data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // lives glue together even if they are pretty far in the unicode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // table. (This looks weird, so I can have missed something), this 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // works on Linux but seems to fails on Mac so let's rewrite the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // cmap table to a 3-1-4 style 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var firstCode = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var entryCount = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (j = 0; j < entryCount; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            glyphId = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var charCode = firstCode + j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mappings.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              charCode: charCode, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              glyphId: glyphId 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          warn('cmap table has unsupported format: ' + format); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            platformId: -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            encodingId: -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mappings: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            hasShortCmap: false 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // removing duplicate entries 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        mappings.sort(function (a, b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return a.charCode - b.charCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (i = 1; i < mappings.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (mappings[i - 1].charCode === mappings[i].charCode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            mappings.splice(i, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            i--; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          platformId: potentialTable.platformId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          encodingId: potentialTable.encodingId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          mappings: mappings, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          hasShortCmap: hasShortCmap 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function sanitizeMetrics(font, header, metrics, numGlyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!header) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (metrics) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            metrics.data = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.pos = (font.start ? font.start : 0) + header.offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.pos += header.length - 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var numOfMetrics = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (numOfMetrics > numGlyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          info('The numOfMetrics (' + numOfMetrics + ') should not be ' + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               'greater than the numGlyphs (' + numGlyphs + ')'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Reduce numOfMetrics if it is greater than numGlyphs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          numOfMetrics = numGlyphs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          header.data[34] = (numOfMetrics & 0xff00) >> 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          header.data[35] = numOfMetrics & 0x00ff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var numOfSidebearings = numGlyphs - numOfMetrics; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var numMissing = numOfSidebearings - 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ((metrics.length - numOfMetrics * 4) >> 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (numMissing > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // For each missing glyph, we set both the width and lsb to 0 (zero). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Since we need to add two properties for each glyph, this explains 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // the use of |numMissing * 2| when initializing the typed array. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var entries = new Uint8Array(metrics.length + numMissing * 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          entries.set(metrics.data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          metrics.data = entries; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function sanitizeGlyph(source, sourceStart, sourceEnd, dest, destStart, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                             hintsValid) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (sourceEnd - sourceStart <= 12) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // glyph with data less than 12 is invalid one 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var glyf = source.subarray(sourceStart, sourceEnd); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var contoursCount = (glyf[0] << 8) | glyf[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (contoursCount & 0x8000) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // complex glyph, writing as is 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          dest.set(glyf, destStart); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return glyf.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var i, j = 10, flagsCount = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (i = 0; i < contoursCount; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var endPoint = (glyf[j] << 8) | glyf[j + 1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          flagsCount = endPoint + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          j += 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // skipping instructions 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var instructionsStart = j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var instructionsLength = (glyf[j] << 8) | glyf[j + 1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        j += 2 + instructionsLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var instructionsEnd = j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // validating flags 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var coordinatesLength = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (i = 0; i < flagsCount; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var flag = glyf[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (flag & 0xC0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // reserved flags must be zero, cleaning up 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            glyf[j - 1] = flag & 0x3F; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var xyLength = ((flag & 2) ? 1 : (flag & 16) ? 0 : 2) + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                         ((flag & 4) ? 1 : (flag & 32) ? 0 : 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          coordinatesLength += xyLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (flag & 8) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var repeat = glyf[j++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            i += repeat; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            coordinatesLength += repeat * xyLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // glyph without coordinates will be rejected 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (coordinatesLength === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var glyphDataLength = j + coordinatesLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (glyphDataLength > glyf.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // not enough data for coordinates 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!hintsValid && instructionsLength > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          dest.set(glyf.subarray(0, instructionsStart), destStart); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          dest.set([0, 0], destStart + instructionsStart); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          dest.set(glyf.subarray(instructionsEnd, glyphDataLength), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                   destStart + instructionsStart + 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          glyphDataLength -= instructionsLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (glyf.length - glyphDataLength > 3) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            glyphDataLength = (glyphDataLength + 3) & ~3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return glyphDataLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (glyf.length - glyphDataLength > 3) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // truncating and aligning to 4 bytes the long glyph data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          glyphDataLength = (glyphDataLength + 3) & ~3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          dest.set(glyf.subarray(0, glyphDataLength), destStart); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return glyphDataLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // glyph data is fine 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dest.set(glyf, destStart); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return glyf.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function sanitizeHead(head, numGlyphs, locaLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var data = head.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Validate version: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Should always be 0x00010000 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var version = int32(data[0], data[1], data[2], data[3]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (version >> 16 !== 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          info('Attempting to fix invalid version in head table: ' + version); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          data[0] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          data[1] = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          data[2] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          data[3] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var indexToLocFormat = int16(data[50], data[51]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (indexToLocFormat < 0 || indexToLocFormat > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          info('Attempting to fix invalid indexToLocFormat in head table: ' + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+               indexToLocFormat); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // The value of indexToLocFormat should be 0 if the loca table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // consists of short offsets, and should be 1 if the loca table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // consists of long offsets. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // The number of entries in the loca table should be numGlyphs + 1. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Using this information, we can work backwards to deduce if the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // size of each offset in the loca table, and thus figure out the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // appropriate value for indexToLocFormat. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var numGlyphsPlusOne = numGlyphs + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (locaLength === numGlyphsPlusOne << 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 0x0000 indicates the loca table consists of short offsets 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data[50] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data[51] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (locaLength === numGlyphsPlusOne << 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // 0x0001 indicates the loca table consists of long offsets 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data[50] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data[51] = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            warn('Could not fix indexToLocFormat: ' + indexToLocFormat); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function sanitizeGlyphLocations(loca, glyf, numGlyphs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                      isGlyphLocationsLong, hintsValid, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                      dupFirstEntry) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var itemSize, itemDecode, itemEncode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (isGlyphLocationsLong) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          itemSize = 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          itemDecode = function fontItemDecodeLong(data, offset) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return (data[offset] << 24) | (data[offset + 1] << 16) | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                   (data[offset + 2] << 8) | data[offset + 3]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          itemEncode = function fontItemEncodeLong(data, offset, value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data[offset] = (value >>> 24) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data[offset + 1] = (value >> 16) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data[offset + 2] = (value >> 8) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data[offset + 3] = value & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          itemSize = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          itemDecode = function fontItemDecode(data, offset) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return (data[offset] << 9) | (data[offset + 1] << 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          itemEncode = function fontItemEncode(data, offset, value) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data[offset] = (value >> 9) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data[offset + 1] = (value >> 1) & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var locaData = loca.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var locaDataSize = itemSize * (1 + numGlyphs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // is loca.data too short or long? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (locaData.length !== locaDataSize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          locaData = new Uint8Array(locaDataSize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          locaData.set(loca.data.subarray(0, locaDataSize)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          loca.data = locaData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // removing the invalid glyphs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var oldGlyfData = glyf.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var oldGlyfDataLength = oldGlyfData.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var newGlyfData = new Uint8Array(oldGlyfDataLength); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var startOffset = itemDecode(locaData, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var writeOffset = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var missingGlyphData = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        itemEncode(locaData, 0, writeOffset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var i, j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var endOffset = itemDecode(locaData, j); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (endOffset > oldGlyfDataLength && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              ((oldGlyfDataLength + 3) & ~3) === endOffset) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // Aspose breaks fonts by aligning the glyphs to the qword, but not 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // the glyf table size, which makes last glyph out of range. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            endOffset = oldGlyfDataLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (endOffset > oldGlyfDataLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // glyph end offset points outside glyf data, rejecting the glyph 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            itemEncode(locaData, j, writeOffset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            startOffset = endOffset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (startOffset === endOffset) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            missingGlyphData[i] = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var newLength = sanitizeGlyph(oldGlyfData, startOffset, endOffset, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                        newGlyfData, writeOffset, hintsValid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          writeOffset += newLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          itemEncode(locaData, j, writeOffset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          startOffset = endOffset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (writeOffset === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // glyf table cannot be empty -- redoing the glyf and loca tables 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // to have single glyph with one point 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var simpleGlyph = new Uint8Array( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            [0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            itemEncode(locaData, j, simpleGlyph.length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          glyf.data = simpleGlyph; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return missingGlyphData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (dupFirstEntry) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var firstEntryLength = itemDecode(locaData, itemSize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (newGlyfData.length > firstEntryLength + writeOffset) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            glyf.data = newGlyfData.subarray(0, firstEntryLength + writeOffset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            glyf.data = new Uint8Array(firstEntryLength + writeOffset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            glyf.data.set(newGlyfData.subarray(0, writeOffset)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          glyf.data.set(newGlyfData.subarray(0, firstEntryLength), writeOffset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          itemEncode(loca.data, locaData.length - itemSize, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                     writeOffset + firstEntryLength); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          glyf.data = newGlyfData.subarray(0, writeOffset); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return missingGlyphData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function readPostScriptTable(post, properties, maxpNumGlyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var start = (font.start ? font.start : 0) + post.offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.pos = start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var length = post.length, end = start + length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var version = font.getInt32(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // skip rest to the tables 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.getBytes(28); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var glyphNames; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var valid = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        switch (version) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 0x00010000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            glyphNames = MacStandardGlyphOrdering; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case OPS.curveTo2: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ctx.bezierCurveTo(x, y, args[j], args[j + 1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                              args[j + 2], args[j + 3]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            x = args[j + 2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            y = args[j + 3]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            j += 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 0x00020000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var numGlyphs = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (numGlyphs !== maxpNumGlyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              valid = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var glyphNameIndexes = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (i = 0; i < numGlyphs; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              var index = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (index >= 32768) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                valid = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              glyphNameIndexes.push(index); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!valid) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var customNames = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var strBuf = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            while (font.pos < end) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              var stringLength = font.getByte(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              strBuf.length = stringLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              for (i = 0; i < stringLength; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                strBuf[i] = String.fromCharCode(font.getByte()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              customNames.push(strBuf.join('')); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            glyphNames = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (i = 0; i < numGlyphs; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              var j = glyphNameIndexes[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (j < 258) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                glyphNames.push(MacStandardGlyphOrdering[j]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              glyphNames.push(customNames[j - 258]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case OPS.curveTo3: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            x = args[j + 2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            y = args[j + 3]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ctx.bezierCurveTo(args[j], args[j + 1], x, y, x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            j += 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          case 0x00030000: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          case OPS.closePath: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ctx.closePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          default: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            warn('Unknown/unsupported post table version ' + version); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            valid = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (properties.defaultEncoding) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              glyphNames = properties.defaultEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        properties.glyphNames = glyphNames; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return valid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      current.setCurrentPoint(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    closePath: function CanvasGraphics_closePath() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.closePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    stroke: function CanvasGraphics_stroke(consumePath) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      consumePath = typeof consumePath !== 'undefined' ? consumePath : true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var strokeColor = this.current.strokeColor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Prevent drawing too thin lines by enforcing a minimum line width. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.lineWidth = Math.max(this.getSinglePixelWidth() * MIN_WIDTH_FACTOR, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                               this.current.lineWidth); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // For stroke we want to temporarily change the global alpha to the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // stroking alpha. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.globalAlpha = this.current.strokeAlpha; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (strokeColor && strokeColor.hasOwnProperty('type') && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          strokeColor.type === 'Pattern') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // for patterns, we transform to pattern space, calculate 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // the pattern, call stroke, and restore to user space 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.strokeStyle = strokeColor.getPattern(ctx, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.stroke(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.stroke(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function readNameTable(nameTable) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var start = (font.start ? font.start : 0) + nameTable.offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.pos = start; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var names = [[], []]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var length = nameTable.length, end = start + length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var format = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var FORMAT_0_HEADER_LENGTH = 6; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (format !== 0 || length < FORMAT_0_HEADER_LENGTH) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // unsupported name table format or table "too" small 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return names; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var numRecords = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var stringsStart = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var records = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var NAME_RECORD_LENGTH = 12; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var i, ii; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (i = 0; i < numRecords && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        font.pos + NAME_RECORD_LENGTH <= end; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var r = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            platform: font.getUint16(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            encoding: font.getUint16(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            language: font.getUint16(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            name: font.getUint16(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            length: font.getUint16(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            offset: font.getUint16() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // using only Macintosh and Windows platform/encoding names 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if ((r.platform === 1 && r.encoding === 0 && r.language === 0) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              (r.platform === 3 && r.encoding === 1 && r.language === 0x409)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            records.push(r); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (i = 0, ii = records.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var record = records[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (record.length <= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            continue; // Nothing to process, ignoring. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var pos = start + stringsStart + record.offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (pos + record.length > end) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            continue; // outside of name table, ignoring 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          font.pos = pos; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var nameIndex = record.name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (record.encoding) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // unicode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var str = ''; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (var j = 0, jj = record.length; j < jj; j += 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              str += String.fromCharCode(font.getUint16()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            names[1][nameIndex] = str; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            names[0][nameIndex] = bytesToString(font.getBytes(record.length)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return names; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (consumePath) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.consumePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var TTOpsStackDeltas = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        0, 0, 0, 0, 0, 0, 0, 0, -2, -2, -2, -2, 0, 0, -2, -5, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, -1, -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        1, -1, -999, 0, 1, 0, -1, -2, 0, -1, -2, -1, -1, 0, -1, -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        0, 0, -999, -999, -1, -1, -1, -1, -2, -999, -2, -2, -999, 0, -2, -2, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        0, 0, -2, 0, -2, 0, 0, 0, -2, -1, -1, 1, 1, 0, 0, -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        -1, -1, -1, -1, -1, -1, 0, 0, -1, 0, -1, -1, 0, -999, -1, -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        -2, -999, -999, -999, -999, -999, -1, -1, -2, -2, 0, 0, 0, 0, -1, -1, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        -999, -2, -2, 0, 0, -1, -2, -2, 0, 0, 0, -1, -1, -1, -2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 0xC0-DF == -1 and 0xE0-FF == -2 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function sanitizeTTProgram(table, ttContext) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var data = table.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var i = 0, j, n, b, funcId, pc, lastEndf = 0, lastDeff = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var stack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var callstack = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var functionsCalled = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var tooComplexToFollowFunctions = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ttContext.tooComplexToFollowFunctions; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var inFDEF = false, ifLevel = 0, inELSE = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (var ii = data.length; i < ii;) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var op = data[i++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // The TrueType instruction set docs can be found at 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // https://developer.apple.com/fonts/TTRefMan/RM05/Chap5.html 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (op === 0x40) { // NPUSHB - pushes n bytes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            n = data[i++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (inFDEF || inELSE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              i += n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              for (j = 0; j < n; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                stack.push(data[i++]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (op === 0x41) { // NPUSHW - pushes n words 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            n = data[i++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (inFDEF || inELSE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              i += n * 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              for (j = 0; j < n; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                b = data[i++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                stack.push((b << 8) | data[i++]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if ((op & 0xF8) === 0xB0) { // PUSHB - pushes bytes 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            n = op - 0xB0 + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (inFDEF || inELSE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              i += n; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              for (j = 0; j < n; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                stack.push(data[i++]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if ((op & 0xF8) === 0xB8) { // PUSHW - pushes words 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            n = op - 0xB8 + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (inFDEF || inELSE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              i += n * 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              for (j = 0; j < n; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                b = data[i++]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                stack.push((b << 8) | data[i++]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (op === 0x2B && !tooComplexToFollowFunctions) { // CALL 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!inFDEF && !inELSE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // collecting inforamtion about which functions are used 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              funcId = stack[stack.length - 1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              ttContext.functionsUsed[funcId] = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (funcId in ttContext.functionsStackDeltas) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                stack.length += ttContext.functionsStackDeltas[funcId]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } else if (funcId in ttContext.functionsDefined && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                         functionsCalled.indexOf(funcId) < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                callstack.push({data: data, i: i, stackTop: stack.length - 1}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                functionsCalled.push(funcId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                pc = ttContext.functionsDefined[funcId]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                if (!pc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  warn('TT: CALL non-existent function'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  ttContext.hintsValid = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                  return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                data = pc.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                i = pc.i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (op === 0x2C && !tooComplexToFollowFunctions) { // FDEF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (inFDEF || inELSE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              warn('TT: nested FDEFs not allowed'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              tooComplexToFollowFunctions = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            inFDEF = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // collecting inforamtion about which functions are defined 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            lastDeff = i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            funcId = stack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ttContext.functionsDefined[funcId] = {data: data, i: i}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (op === 0x2D) { // ENDF - end of function 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (inFDEF) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              inFDEF = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              lastEndf = i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              pc = callstack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (!pc) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                warn('TT: ENDF bad stack'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                ttContext.hintsValid = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              funcId = functionsCalled.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              data = pc.data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              i = pc.i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              ttContext.functionsStackDeltas[funcId] = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                stack.length - pc.stackTop; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (op === 0x89) { // IDEF - instruction definition 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (inFDEF || inELSE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              warn('TT: nested IDEFs not allowed'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              tooComplexToFollowFunctions = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            inFDEF = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // recording it as a function to track ENDF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            lastDeff = i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (op === 0x58) { // IF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ++ifLevel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (op === 0x1B) { // ELSE 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            inELSE = ifLevel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (op === 0x59) { // EIF 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (inELSE === ifLevel) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              inELSE = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            --ifLevel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (op === 0x1C) { // JMPR 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!inFDEF && !inELSE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              var offset = stack[stack.length - 1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // only jumping forward to prevent infinite loop 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (offset > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                i += offset - 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Adjusting stack not extactly, but just enough to get function id 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (!inFDEF && !inELSE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var stackDelta = op <= 0x8E ? TTOpsStackDeltas[op] : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              op >= 0xC0 && op <= 0xDF ? -1 : op >= 0xE0 ? -2 : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (op >= 0x71 && op <= 0x75) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              n = stack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (n === n) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                stackDelta = -n * 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            while (stackDelta < 0 && stack.length > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              stack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              stackDelta++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            while (stackDelta > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              stack.push(NaN); // pushing any number into stack 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              stackDelta--; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ttContext.tooComplexToFollowFunctions = tooComplexToFollowFunctions; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var content = [data]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (i > data.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          content.push(new Uint8Array(i - data.length)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (lastDeff > lastEndf) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          warn('TT: complementing a missing function tail'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // new function definition started, but not finished 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // complete function by [CLEAR, ENDF] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          content.push(new Uint8Array([0x22, 0x2D])); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        foldTTTable(table, content); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Restore the global alpha to the fill alpha 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.globalAlpha = this.current.fillAlpha; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    closeStroke: function CanvasGraphics_closeStroke() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.closePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.stroke(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    fill: function CanvasGraphics_fill(consumePath) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      consumePath = typeof consumePath !== 'undefined' ? consumePath : true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fillColor = this.current.fillColor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var isPatternFill = this.current.patternFill; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var needRestore = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (isPatternFill) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (this.baseTransform) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ctx.setTransform.apply(ctx, this.baseTransform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function checkInvalidFunctions(ttContext, maxFunctionDefs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ttContext.tooComplexToFollowFunctions) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (ttContext.functionsDefined.length > maxFunctionDefs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          warn('TT: more functions defined than expected'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          ttContext.hintsValid = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (var j = 0, jj = ttContext.functionsUsed.length; j < jj; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (j > maxFunctionDefs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            warn('TT: invalid function id: ' + j); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ttContext.hintsValid = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (ttContext.functionsUsed[j] && !ttContext.functionsDefined[j]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            warn('TT: undefined function: ' + j); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            ttContext.hintsValid = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.fillStyle = fillColor.getPattern(ctx, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        needRestore = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.pendingEOFill) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (ctx.mozFillRule !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ctx.mozFillRule = 'evenodd'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ctx.fill(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ctx.mozFillRule = 'nonzero'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ctx.fill('evenodd'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function foldTTTable(table, content) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (content.length > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // concatenating the content items 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var newLength = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var j, jj; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (j = 0, jj = content.length; j < jj; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            newLength += content[j].length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          newLength = (newLength + 3) & ~3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var result = new Uint8Array(newLength); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var pos = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (j = 0, jj = content.length; j < jj; j++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            result.set(content[j], pos); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            pos += content[j].length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          table.data = result; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          table.length = newLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.pendingEOFill = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.fill(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (needRestore) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (consumePath) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.consumePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function sanitizeTTPrograms(fpgm, prep, cvt) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var ttContext = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          functionsDefined: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          functionsUsed: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          functionsStackDeltas: [], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          tooComplexToFollowFunctions: false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          hintsValid: true 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (fpgm) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          sanitizeTTProgram(fpgm, ttContext); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (prep) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          sanitizeTTProgram(prep, ttContext); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (fpgm) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          checkInvalidFunctions(ttContext, maxFunctionDefs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (cvt && (cvt.length & 1)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var cvtData = new Uint8Array(cvt.length + 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          cvtData.set(cvt.data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          cvt.data = cvtData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return ttContext.hintsValid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    eoFill: function CanvasGraphics_eoFill() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.pendingEOFill = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.fill(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    fillStroke: function CanvasGraphics_fillStroke() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.fill(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.stroke(false); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.consumePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    eoFillStroke: function CanvasGraphics_eoFillStroke() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.pendingEOFill = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.fillStroke(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    closeFillStroke: function CanvasGraphics_closeFillStroke() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.closePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.fillStroke(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    closeEOFillStroke: function CanvasGraphics_closeEOFillStroke() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.pendingEOFill = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.closePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.fillStroke(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    endPath: function CanvasGraphics_endPath() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.consumePath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // The following steps modify the original font data, making copy 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      font = new Stream(new Uint8Array(font.getBytes())); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Clipping 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    clip: function CanvasGraphics_clip() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.pendingClip = NORMAL_CLIP; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    eoClip: function CanvasGraphics_eoClip() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.pendingClip = EO_CLIP; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var VALID_TABLES = ['OS/2', 'cmap', 'head', 'hhea', 'hmtx', 'maxp', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        'name', 'post', 'loca', 'glyf', 'fpgm', 'prep', 'cvt ', 'CFF ']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Text 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    beginText: function CanvasGraphics_beginText() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.textMatrix = IDENTITY_MATRIX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.textMatrixScale = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.x = this.current.lineX = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.y = this.current.lineY = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    endText: function CanvasGraphics_endText() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var paths = this.pendingTextPaths; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (paths === undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.beginPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var header = readOpenTypeHeader(font); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var numTables = header.numTables; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var cff, cffFile; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.beginPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var i = 0; i < paths.length; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var path = paths[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.setTransform.apply(ctx, path.transform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.translate(path.x, path.y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        path.addToPath(ctx, path.fontSize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.clip(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.beginPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      delete this.pendingTextPaths; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setCharSpacing: function CanvasGraphics_setCharSpacing(spacing) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.charSpacing = spacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setWordSpacing: function CanvasGraphics_setWordSpacing(spacing) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.wordSpacing = spacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setHScale: function CanvasGraphics_setHScale(scale) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.textHScale = scale / 100; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setLeading: function CanvasGraphics_setLeading(leading) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.leading = -leading; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setFont: function CanvasGraphics_setFont(fontRefName, size) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fontObj = this.commonObjs.get(fontRefName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var current = this.current; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var tables = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      tables['OS/2'] = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      tables['cmap'] = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      tables['head'] = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      tables['hhea'] = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      tables['hmtx'] = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      tables['maxp'] = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      tables['name'] = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      tables['post'] = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!fontObj) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        error('Can\'t find font for ' + fontRefName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var table; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = 0; i < numTables; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        table = readTableEntry(font); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (VALID_TABLES.indexOf(table.tag) < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          continue; // skipping table if it's not a required or optional table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (table.length === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          continue; // skipping empty tables 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tables[table.tag] = table; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      current.fontMatrix = (fontObj.fontMatrix ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            fontObj.fontMatrix : FONT_IDENTITY_MATRIX); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var isTrueType = !tables['CFF ']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!isTrueType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // OpenType font 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if ((header.version === 'OTTO' && properties.type !== 'CIDFontType2') || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            !tables['head'] || !tables['hhea'] || !tables['maxp'] || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            !tables['post']) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // no major tables: throwing everything at CFFFont 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          cffFile = new Stream(tables['CFF '].data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          cff = new CFFFont(cffFile, properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // A valid matrix needs all main diagonal elements to be non-zero 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // This also ensures we bypass FF bugzilla bug #719844. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (current.fontMatrix[0] === 0 || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          current.fontMatrix[3] === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        warn('Invalid font matrix for font ' + fontRefName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          adjustWidths(properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // The spec for Tf (setFont) says that 'size' specifies the font 'scale', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // and in some docs this can be negative (inverted x-y axes). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (size < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        size = -size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        current.fontDirection = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return this.convert(name, cff, properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete tables['glyf']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete tables['loca']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete tables['fpgm']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete tables['prep']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete tables['cvt ']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.isOpenType = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        current.fontDirection = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!tables['loca']) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          error('Required "loca" table is not found'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!tables['glyf']) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          warn('Required "glyf" table is not found -- trying to recover.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Note: We use `sanitizeGlyphLocations` to add dummy glyf data below. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          tables['glyf'] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            tag: 'glyf', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            data: new Uint8Array(0), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.isOpenType = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.font = fontObj; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.fontSize = size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (fontObj.isType3Font) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return; // we don't need ctx.font for Type3 fonts 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!tables['maxp']) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        error('Required "maxp" table is not found'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var name = fontObj.loadedName || 'sans-serif'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var bold = fontObj.black ? (fontObj.bold ? '900' : 'bold') : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                 (fontObj.bold ? 'bold' : 'normal'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var italic = fontObj.italic ? 'italic' : 'normal'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var typeface = '"' + name + '", ' + fontObj.fallbackName; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Some font backends cannot handle fonts below certain size. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Keeping the font at minimal size and using the fontSizeScale to change 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // the current transformation matrix before the fillText/strokeText. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // See https://bugzilla.mozilla.org/show_bug.cgi?id=726227 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var browserFontSize = size < MIN_FONT_SIZE ? MIN_FONT_SIZE : 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            size > MAX_FONT_SIZE ? MAX_FONT_SIZE : size; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.fontSizeScale = size / browserFontSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var rule = italic + ' ' + bold + ' ' + browserFontSize + 'px ' + typeface; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.font = rule; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setTextRenderingMode: function CanvasGraphics_setTextRenderingMode(mode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.textRenderingMode = mode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setTextRise: function CanvasGraphics_setTextRise(rise) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.textRise = rise; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    moveText: function CanvasGraphics_moveText(x, y) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.x = this.current.lineX += x; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.y = this.current.lineY += y; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setLeadingMoveText: function CanvasGraphics_setLeadingMoveText(x, y) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.setLeading(-y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.moveText(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setTextMatrix: function CanvasGraphics_setTextMatrix(a, b, c, d, e, f) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.textMatrix = [a, b, c, d, e, f]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.textMatrixScale = Math.sqrt(a * a + b * b); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.x = this.current.lineX = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.y = this.current.lineY = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    nextLine: function CanvasGraphics_nextLine() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.moveText(0, this.current.leading); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    paintChar: function CanvasGraphics_paintChar(character, x, y) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var current = this.current; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var font = current.font; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var textRenderingMode = current.textRenderingMode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fontSize = current.fontSize / current.fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fillStrokeMode = textRenderingMode & 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        TextRenderingMode.FILL_STROKE_MASK; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var isAddToPathSet = !!(textRenderingMode & 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        TextRenderingMode.ADD_TO_PATH_FLAG); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var addToPath; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (font.disableFontFace || isAddToPathSet) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        addToPath = font.getPathGenerator(this.commonObjs, character); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      font.pos = (font.start || 0) + tables['maxp'].offset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var version = font.getInt32(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var numGlyphs = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var maxFunctionDefs = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (version >= 0x00010000 && tables['maxp'].length >= 22) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // maxZones can be invalid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.pos += 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var maxZones = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (maxZones > 2) { // reset to 2 if font has invalid maxZones 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          tables['maxp'].data[14] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          tables['maxp'].data[15] = 2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        font.pos += 4; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        maxFunctionDefs = font.getUint16(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (font.disableFontFace) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.translate(x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.beginPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        addToPath(ctx, fontSize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (fillStrokeMode === TextRenderingMode.FILL || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            fillStrokeMode === TextRenderingMode.FILL_STROKE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ctx.fill(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (fillStrokeMode === TextRenderingMode.STROKE || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            fillStrokeMode === TextRenderingMode.FILL_STROKE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ctx.stroke(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (fillStrokeMode === TextRenderingMode.FILL || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            fillStrokeMode === TextRenderingMode.FILL_STROKE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ctx.fillText(character, x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (fillStrokeMode === TextRenderingMode.STROKE || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            fillStrokeMode === TextRenderingMode.FILL_STROKE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ctx.strokeText(character, x, y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var dupFirstEntry = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (properties.type === 'CIDFontType2' && properties.toUnicode && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          properties.toUnicode.get(0) > '\u0000') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // oracle's defect (see 3427), duplicating first entry 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        dupFirstEntry = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        numGlyphs++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tables['maxp'].data[4] = numGlyphs >> 8; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tables['maxp'].data[5] = numGlyphs & 255; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (isAddToPathSet) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var paths = this.pendingTextPaths || (this.pendingTextPaths = []); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        paths.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          transform: ctx.mozCurrentTransform, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          x: x, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          y: y, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          fontSize: fontSize, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          addToPath: addToPath 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var hintsValid = sanitizeTTPrograms(tables['fpgm'], tables['prep'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                          tables['cvt '], maxFunctionDefs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!hintsValid) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete tables['fpgm']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete tables['prep']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        delete tables['cvt ']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    get isFontSubpixelAAEnabled() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Checks if anti-aliasing is enabled when scaled text is painted. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // On Windows GDI scaled fonts looks bad. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ctx = document.createElement('canvas').getContext('2d'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.scale(1.5, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.fillText('I', 0, 10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var data = ctx.getImageData(0, 0, 10, 10).data; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var enabled = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var i = 3; i < data.length; i += 4) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (data[i] > 0 && data[i] < 255) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          enabled = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Ensure the hmtx table contains the advance width and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // sidebearings information for numGlyphs in the maxp table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sanitizeMetrics(font, tables['hhea'], tables['hmtx'], numGlyphs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!tables['head']) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        error('Required "head" table is not found'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return shadow(this, 'isFontSubpixelAAEnabled', enabled); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    showText: function CanvasGraphics_showText(glyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var current = this.current; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var font = current.font; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (font.isType3Font) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return this.showType3Text(glyphs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      sanitizeHead(tables['head'], numGlyphs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                   isTrueType ? tables['loca'].length : 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var missingGlyphs = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (isTrueType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var isGlyphLocationsLong = int16(tables['head'].data[50], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                         tables['head'].data[51]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        missingGlyphs = sanitizeGlyphLocations(tables['loca'], tables['glyf'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                               numGlyphs, isGlyphLocationsLong, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                               hintsValid, dupFirstEntry); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fontSize = current.fontSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (fontSize === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!tables['hhea']) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        error('Required "hhea" table is not found'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fontSizeScale = current.fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var charSpacing = current.charSpacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var wordSpacing = current.wordSpacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fontDirection = current.fontDirection; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var textHScale = current.textHScale * fontDirection; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var glyphsLength = glyphs.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var vertical = font.vertical; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var spacingDir = vertical ? 1 : -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var defaultVMetrics = font.defaultVMetrics; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var widthAdvanceScale = fontSize * current.fontMatrix[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Sanitizer reduces the glyph advanceWidth to the maxAdvanceWidth 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Sometimes it's 0. That needs to be fixed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (tables['hhea'].data[10] === 0 && tables['hhea'].data[11] === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tables['hhea'].data[10] = 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tables['hhea'].data[11] = 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var simpleFillText = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        current.textRenderingMode === TextRenderingMode.FILL && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        !font.disableFontFace; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Extract some more font properties from the OpenType head and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // hhea tables; yMin and descent value are always negative. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var metricsOverride = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        unitsPerEm: int16(tables['head'].data[18], tables['head'].data[19]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        yMax: int16(tables['head'].data[42], tables['head'].data[43]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        yMin: signedInt16(tables['head'].data[38], tables['head'].data[39]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        ascent: int16(tables['hhea'].data[4], tables['hhea'].data[5]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        descent: signedInt16(tables['hhea'].data[6], tables['hhea'].data[7]) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.transform.apply(ctx, current.textMatrix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.translate(current.x, current.y + current.textRise); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // PDF FontDescriptor metrics lie -- using data from actual font. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.ascent = metricsOverride.ascent / metricsOverride.unitsPerEm; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.descent = metricsOverride.descent / metricsOverride.unitsPerEm; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (current.patternFill) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // TODO: Some shading patterns are not applied correctly to text, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        //       e.g. issues 3988 and 5432, and ShowText-ShadingPattern.pdf. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.fillStyle = current.fillColor.getPattern(ctx, this); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // The 'post' table has glyphs names. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (tables['post']) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var valid = readPostScriptTable(tables['post'], properties, numGlyphs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!valid) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          tables['post'] = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (fontDirection > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.scale(textHScale, -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.scale(textHScale, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var charCodeToGlyphId = [], charCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var toUnicode = properties.toUnicode, widths = properties.widths; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var skipToUnicode = (toUnicode instanceof IdentityToUnicodeMap || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                           toUnicode.length === 0x10000); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Helper function to try to skip mapping of empty glyphs. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Note: In some cases, just relying on the glyph data doesn't work, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      //       hence we also use a few heuristics to fix various PDF files. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function hasGlyph(glyphId, charCode, widthCode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!missingGlyphs[glyphId]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!skipToUnicode && charCode >= 0 && toUnicode.has(charCode)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (widths && widthCode >= 0 && isNum(widths[widthCode])) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var lineWidth = current.lineWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var scale = current.textMatrixScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (scale === 0 || lineWidth === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var fillStrokeMode = current.textRenderingMode & 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          TextRenderingMode.FILL_STROKE_MASK; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (fillStrokeMode === TextRenderingMode.STROKE || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            fillStrokeMode === TextRenderingMode.FILL_STROKE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          this.cachedGetSinglePixelWidth = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          lineWidth = this.getSinglePixelWidth() * MIN_WIDTH_FACTOR; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Some bad PDF generators, e.g. Scribus PDF, include glyph names 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // in a 'uniXXXX' format -- attempting to recover proper ones. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function recoverGlyphName(name, glyphsUnicodeMap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (glyphsUnicodeMap[name] !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // The glyph name is non-standard, trying to recover. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var unicode = getUnicodeForGlyph(name, glyphsUnicodeMap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (unicode !== -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (var key in glyphsUnicodeMap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (glyphsUnicodeMap[key] === unicode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              return key; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        lineWidth /= scale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (fontSizeScale !== 1.0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.scale(fontSizeScale, fontSizeScale); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        lineWidth /= fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        warn('Unable to recover a standard glyph name for: ' + name); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return name; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.lineWidth = lineWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var x = 0, i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (i = 0; i < glyphsLength; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var glyph = glyphs[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (isNum(glyph)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          x += spacingDir * glyph * fontSize / 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (properties.type === 'CIDFontType2') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var cidToGidMap = properties.cidToGidMap || []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var isCidToGidMapEmpty = cidToGidMap.length === 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var restoreNeeded = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var character = glyph.fontChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var accent = glyph.accent; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var scaledX, scaledY, scaledAccentX, scaledAccentY; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var width = glyph.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (vertical) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var vmetric, vx, vy; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          vmetric = glyph.vmetric || defaultVMetrics; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          vx = glyph.vmetric ? vmetric[1] : width * 0.5; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          vx = -vx * widthAdvanceScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          vy = vmetric[2] * widthAdvanceScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        properties.cMap.forEach(function(charCode, cid) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          assert(cid <= 0xffff, 'Max size of CID is 65,535'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var glyphId = -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (isCidToGidMapEmpty) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            glyphId = cid; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } else if (cidToGidMap[cid] !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            glyphId = cidToGidMap[cid]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          width = vmetric ? -vmetric[0] : width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          scaledX = vx / fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          scaledY = (x + vy) / fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          scaledX = x / fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          scaledY = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (glyphId >= 0 && glyphId < numGlyphs && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              hasGlyph(glyphId, charCode, cid)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            charCodeToGlyphId[charCode] = glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (dupFirstEntry) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          charCodeToGlyphId[0] = numGlyphs - 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Most of the following logic in this code branch is based on the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // 9.6.6.4 of the PDF spec. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var hasEncoding = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          properties.differences.length > 0 || !!properties.baseEncodingName; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var cmapTable = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          readCmapTable(tables['cmap'], font, this.isSymbolicFont, hasEncoding); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var cmapPlatformId = cmapTable.platformId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var cmapEncodingId = cmapTable.encodingId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var cmapMappings = cmapTable.mappings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var cmapMappingsLength = cmapMappings.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (font.remeasure && width > 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // Some standard fonts may not have the exact width: rescale per 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // character if measured width is greater than expected glyph width 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          // and subpixel-aa is enabled, otherwise just center the glyph. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var measuredWidth = ctx.measureText(character).width * 1000 / 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            fontSize * fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (width < measuredWidth && this.isFontSubpixelAAEnabled) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            var characterScaleX = width / measuredWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            restoreNeeded = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ctx.scale(characterScaleX, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            scaledX /= characterScaleX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else if (width !== measuredWidth) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            scaledX += (width - measuredWidth) / 2000 * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              fontSize / fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // The spec seems to imply that if the font is symbolic the encoding 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // should be ignored, this doesn't appear to work for 'preistabelle.pdf' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // where the the font is symbolic and it has an encoding. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (hasEncoding && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (cmapPlatformId === 3 && cmapEncodingId === 1 || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             cmapPlatformId === 1 && cmapEncodingId === 0) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            (cmapPlatformId === -1 && cmapEncodingId === -1 && // Temporary hack 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+             !!getEncoding(properties.baseEncodingName))) {    // Temporary hack 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // When no preferred cmap table was found and |baseEncodingName| is 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // one of the predefined encodings, we seem to obtain a better 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // |charCodeToGlyphId| map from the code below (fixes bug 1057544). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // TODO: Note that this is a hack which should be removed as soon as 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          //       we have proper support for more exotic cmap tables. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var baseEncoding = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (properties.baseEncodingName === 'MacRomanEncoding' || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              properties.baseEncodingName === 'WinAnsiEncoding') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            baseEncoding = getEncoding(properties.baseEncodingName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var glyphsUnicodeMap = getGlyphsUnicode(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (charCode = 0; charCode < 256; charCode++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var glyphName, standardGlyphName; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (this.differences && charCode in this.differences) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              glyphName = this.differences[charCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else if (charCode in baseEncoding && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       baseEncoding[charCode] !== '') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              glyphName = baseEncoding[charCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              glyphName = StandardEncoding[charCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!glyphName) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // Ensure that non-standard glyph names are resolved to valid ones. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            standardGlyphName = recoverGlyphName(glyphName, glyphsUnicodeMap); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Only attempt to draw the glyph if it is actually in the embedded font 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // file or if there isn't a font file so the fallback font is shown. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (glyph.isInFont || font.missingFile) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (simpleFillText && !accent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            // common case 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ctx.fillText(character, scaledX, scaledY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            this.paintChar(character, scaledX, scaledY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            if (accent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              scaledAccentX = scaledX + accent.offset.x / fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              scaledAccentY = scaledY - accent.offset.y / fontSizeScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-              this.paintChar(accent.fontChar, scaledAccentX, scaledAccentY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var unicodeOrCharCode, isUnicode = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (cmapPlatformId === 3 && cmapEncodingId === 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              unicodeOrCharCode = glyphsUnicodeMap[standardGlyphName]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              isUnicode = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else if (cmapPlatformId === 1 && cmapEncodingId === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // TODO: the encoding needs to be updated with mac os table. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              unicodeOrCharCode = MacRomanEncoding.indexOf(standardGlyphName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var found = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            for (i = 0; i < cmapMappingsLength; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (cmapMappings[i].charCode !== unicodeOrCharCode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              var code = isUnicode ? charCode : unicodeOrCharCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (hasGlyph(cmapMappings[i].glyphId, code, -1)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                charCodeToGlyphId[charCode] = cmapMappings[i].glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                found = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!found && properties.glyphNames) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // Try to map using the post table. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              var glyphId = properties.glyphNames.indexOf(glyphName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // The post table ought to use the same kind of glyph names as the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              // `differences` array, but check the standard ones as a fallback. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (glyphId === -1 && standardGlyphName !== glyphName) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                glyphId = properties.glyphNames.indexOf(standardGlyphName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              if (glyphId > 0 && hasGlyph(glyphId, -1, -1)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                charCodeToGlyphId[charCode] = glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                found = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!found) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              charCodeToGlyphId[charCode] = 0; // notdef 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				             } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else if (cmapPlatformId === 0 && cmapEncodingId === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Default Unicode semantics, use the charcodes as is. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (i = 0; i < cmapMappingsLength; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            charCodeToGlyphId[cmapMappings[i].charCode] = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              cmapMappings[i].glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // For (3, 0) cmap tables: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // The charcode key being stored in charCodeToGlyphId is the lower 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // byte of the two-byte charcodes of the cmap table since according to 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // the spec: 'each byte from the string shall be prepended with the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // high byte of the range [of charcodes in the cmap table], to form 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // a two-byte character, which shall be used to select the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // associated glyph description from the subtable'. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // For (1, 0) cmap tables: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // 'single bytes from the string shall be used to look up the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // associated glyph descriptions from the subtable'. This means 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // charcodes in the cmap will be single bytes, so no-op since 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // glyph.charCode & 0xFF === glyph.charCode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (i = 0; i < cmapMappingsLength; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            charCode = cmapMappings[i].charCode & 0xFF; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            charCodeToGlyphId[charCode] = cmapMappings[i].glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var charWidth = width * widthAdvanceScale + spacing * fontDirection; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        x += charWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (charCodeToGlyphId.length === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // defines at least one glyph 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        charCodeToGlyphId[0] = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (restoreNeeded) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Converting glyphs and ids into font's cmap table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var newMapping = adjustMapping(charCodeToGlyphId, properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.toFontChar = newMapping.toFontChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      tables['cmap'] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tag: 'cmap', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        data: createCmapTable(newMapping.charCodeToGlyphId, numGlyphs) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!tables['OS/2'] || !validateOS2Table(tables['OS/2'])) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tables['OS/2'] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          tag: 'OS/2', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          data: createOS2Table(properties, newMapping.charCodeToGlyphId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                               metricsOverride) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Rewrite the 'post' table if needed 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!tables['post']) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tables['post'] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          tag: 'post', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          data: createPostTable(properties) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!isTrueType) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Trying to repair CFF file 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          cffFile = new Stream(tables['CFF '].data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var parser = new CFFParser(cffFile, properties, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                     SEAC_ANALYSIS_ENABLED); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          cff = parser.parse(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var compiler = new CFFCompiler(cff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          tables['CFF '].data = compiler.compile(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } catch (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          warn('Failed to compile font ' + properties.loadedName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (vertical) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        current.y -= x * textHScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Re-creating 'name' table 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!tables['name']) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tables['name'] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          tag: 'name', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          data: createNameTable(this.name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        current.x += x * textHScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // ... using existing 'name' table as prototype 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var namePrototype = readNameTable(tables['name']); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        tables['name'].data = createNameTable(name, namePrototype); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    showType3Text: function CanvasGraphics_showType3Text(glyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Type3 fonts - each glyph is a "mini-PDF" 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var current = this.current; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var font = current.font; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fontSize = current.fontSize; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fontDirection = current.fontDirection; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var spacingDir = font.vertical ? 1 : -1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var charSpacing = current.charSpacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var wordSpacing = current.wordSpacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var textHScale = current.textHScale * fontDirection; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fontMatrix = current.fontMatrix || FONT_IDENTITY_MATRIX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var glyphsLength = glyphs.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var isTextInvisible = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        current.textRenderingMode === TextRenderingMode.INVISIBLE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var i, glyph, width, spacingLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (isTextInvisible || fontSize === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var builder = new OpenTypeFileBuilder(header.version); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var tableTag in tables) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        builder.addTable(tableTag, tables[tableTag].data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.cachedGetSinglePixelWidth = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return builder.toArray(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.transform.apply(ctx, current.textMatrix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.translate(current.x, current.y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    convert: function Font_convert(fontName, font, properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // TODO: Check the charstring widths to determine this. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      properties.fixedPitch = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.scale(textHScale, fontDirection); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var mapping = font.getGlyphMapping(properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var newMapping = adjustMapping(mapping, properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.toFontChar = newMapping.toFontChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var numGlyphs = font.numGlyphs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (i = 0; i < glyphsLength; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        glyph = glyphs[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (isNum(glyph)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          spacingLength = spacingDir * glyph * fontSize / 1000; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          this.ctx.translate(spacingLength, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          current.x += spacingLength * textHScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function getCharCodes(charCodeToGlyphId, glyphId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var charCodes = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (var charCode in charCodeToGlyphId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (glyphId === charCodeToGlyphId[charCode]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (!charCodes) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              charCodes = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            charCodes.push(charCode | 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return charCodes; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var spacing = (glyph.isSpace ? wordSpacing : 0) + charSpacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var operatorList = font.charProcOperatorList[glyph.operatorListId]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (!operatorList) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          warn('Type3 character \"' + glyph.operatorListId + 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-               '\" is not available'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      function createCharCode(charCodeToGlyphId, glyphId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (var charCode in charCodeToGlyphId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (glyphId === charCodeToGlyphId[charCode]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            return charCode | 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.processingType3 = glyph; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.scale(fontSize, fontSize); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.transform.apply(ctx, fontMatrix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.executeOperatorList(operatorList); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var transformed = Util.applyTransform([glyph.width, 0], fontMatrix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        width = transformed[0] * fontSize + spacing; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.translate(width, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        current.x += width * textHScale; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        newMapping.charCodeToGlyphId[newMapping.nextAvailableFontCharCode] = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return newMapping.nextAvailableFontCharCode++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.processingType3 = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Type3 fonts 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setCharWidth: function CanvasGraphics_setCharWidth(xWidth, yWidth) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // We can safely ignore this since the width should be the same 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // as the width in the Widths array. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setCharWidthAndBounds: function CanvasGraphics_setCharWidthAndBounds(xWidth, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                                        yWidth, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                                        llx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                                        lly, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                                        urx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                                        ury) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // TODO According to the spec we're also suppose to ignore any operators 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // that set color or include images while processing this type3 font. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.rect(llx, lly, urx - llx, ury - lly); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.clip(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.endPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var seacs = font.seacs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (SEAC_ANALYSIS_ENABLED && seacs && seacs.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var matrix = properties.fontMatrix || FONT_IDENTITY_MATRIX; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var charset = font.getCharset(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var seacMap = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (var glyphId in seacs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          glyphId |= 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var seac = seacs[glyphId]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var baseGlyphName = StandardEncoding[seac[2]]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var accentGlyphName = StandardEncoding[seac[3]]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var baseGlyphId = charset.indexOf(baseGlyphName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var accentGlyphId = charset.indexOf(accentGlyphName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (baseGlyphId < 0 || accentGlyphId < 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var accentOffset = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            x: seac[0] * matrix[0] + seac[1] * matrix[2] + matrix[4], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            y: seac[0] * matrix[1] + seac[1] * matrix[3] + matrix[5] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Color 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    getColorN_Pattern: function CanvasGraphics_getColorN_Pattern(IR) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var pattern; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (IR[0] === 'TilingPattern') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var color = IR[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var baseTransform = this.baseTransform || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            this.ctx.mozCurrentTransform.slice(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var self = this; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var canvasGraphicsFactory = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          createCanvasGraphics: function (ctx) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            return new CanvasGraphics(ctx, self.commonObjs, self.objs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var charCodes = getCharCodes(mapping, glyphId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (!charCodes) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // There's no point in mapping it if the char code was never mapped 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // to begin with. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        pattern = new TilingPattern(IR, color, this.ctx, canvasGraphicsFactory, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                    baseTransform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        pattern = getShadingPatternFromIR(IR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (var i = 0, ii = charCodes.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var charCode = charCodes[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // Find a fontCharCode that maps to the base and accent glyphs. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            // If one doesn't exists, create it. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var charCodeToGlyphId = newMapping.charCodeToGlyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var baseFontCharCode = createCharCode(charCodeToGlyphId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                  baseGlyphId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var accentFontCharCode = createCharCode(charCodeToGlyphId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                                    accentGlyphId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            seacMap[charCode] = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              baseFontCharCode: baseFontCharCode, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              accentFontCharCode: accentFontCharCode, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              accentOffset: accentOffset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        properties.seacMap = seacMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return pattern; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setStrokeColorN: function CanvasGraphics_setStrokeColorN(/*...*/) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.strokeColor = this.getColorN_Pattern(arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setFillColorN: function CanvasGraphics_setFillColorN(/*...*/) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.fillColor = this.getColorN_Pattern(arguments); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.patternFill = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setStrokeRGBColor: function CanvasGraphics_setStrokeRGBColor(r, g, b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var color = Util.makeCssRgb(r, g, b); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.strokeStyle = color; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.strokeColor = color; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    setFillRGBColor: function CanvasGraphics_setFillRGBColor(r, g, b) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var color = Util.makeCssRgb(r, g, b); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx.fillStyle = color; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.fillColor = color; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current.patternFill = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    shadingFill: function CanvasGraphics_shadingFill(patternIR) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var pattern = getShadingPatternFromIR(patternIR); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.fillStyle = pattern.getPattern(ctx, this, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var unitsPerEm = 1 / (properties.fontMatrix || FONT_IDENTITY_MATRIX)[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var inv = ctx.mozCurrentTransformInverse; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (inv) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var canvas = ctx.canvas; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var width = canvas.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var height = canvas.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var builder = new OpenTypeFileBuilder('\x4F\x54\x54\x4F'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // PostScript Font Program 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      builder.addTable('CFF ', font.data); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // OS/2 and Windows Specific metrics 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      builder.addTable('OS/2', createOS2Table(properties, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                              newMapping.charCodeToGlyphId)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Character to glyphs mapping 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      builder.addTable('cmap', createCmapTable(newMapping.charCodeToGlyphId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                       numGlyphs)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Font header 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      builder.addTable('head', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x01\x00\x00' + // Version number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00\x10\x00' + // fontRevision 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00\x00\x00' + // checksumAdjustement 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x5F\x0F\x3C\xF5' + // magicNumber 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00' + // Flags 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            safeString16(unitsPerEm) + // unitsPerEM 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00\x00\x00\x9e\x0b\x7e\x27' + // creation date 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00\x00\x00\x9e\x0b\x7e\x27' + // modifification date 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00' + // xMin 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            safeString16(properties.descent) + // yMin 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x0F\xFF' + // xMax 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            safeString16(properties.ascent) + // yMax 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            string16(properties.italicAngle ? 2 : 0) + // macStyle 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x11' + // lowestRecPPEM 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00' + // fontDirectionHint 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00' + // indexToLocFormat 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00');  // glyphDataFormat 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var bl = Util.applyTransform([0, 0], inv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var br = Util.applyTransform([0, height], inv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var ul = Util.applyTransform([width, 0], inv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var ur = Util.applyTransform([width, height], inv); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Horizontal header 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      builder.addTable('hhea', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x01\x00\x00' + // Version number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            safeString16(properties.ascent) + // Typographic Ascent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            safeString16(properties.descent) + // Typographic Descent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00' + // Line Gap 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\xFF\xFF' + // advanceWidthMax 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00' + // minLeftSidebearing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00' + // minRightSidebearing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00' + // xMaxExtent 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            safeString16(properties.capHeight) + // caretSlopeRise 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            safeString16(Math.tan(properties.italicAngle) * 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                         properties.xHeight) + // caretSlopeRun 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00' + // caretOffset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00' + // -reserved- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00' + // -reserved- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00' + // -reserved- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00' + // -reserved- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00' + // metricDataFormat 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            string16(numGlyphs)); // Number of HMetrics 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var x0 = Math.min(bl[0], br[0], ul[0], ur[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var y0 = Math.min(bl[1], br[1], ul[1], ur[1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var x1 = Math.max(bl[0], br[0], ul[0], ur[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var y1 = Math.max(bl[1], br[1], ul[1], ur[1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Horizontal metrics 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      builder.addTable('hmtx', (function fontFieldsHmtx() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var charstrings = font.charstrings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var cffWidths = font.cff ? font.cff.widths : null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var hmtx = '\x00\x00\x00\x00'; // Fake .notdef 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (var i = 1, ii = numGlyphs; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var width = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            if (charstrings) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              var charstring = charstrings[i - 1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              width = 'width' in charstring ? charstring.width : 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } else if (cffWidths) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+              width = Math.ceil(cffWidths[i] || 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            hmtx += string16(width) + string16(0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return hmtx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        })()); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx.fillRect(x0, y0, x1 - x0, y1 - y0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // HACK to draw the gradient onto an infinite rectangle. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // PDF gradients are drawn across the entire image while 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Canvas only allows gradients to be drawn in a rectangle 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // The following bug should allow us to remove this. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // https://bugzilla.mozilla.org/show_bug.cgi?id=664884 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Maximum profile 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      builder.addTable('maxp', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            '\x00\x00\x50\x00' + // Version number 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            string16(numGlyphs)); // Num of glyphs 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx.fillRect(-1e10, -1e10, 2e10, 2e10); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Naming tables 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      builder.addTable('name', createNameTable(fontName)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // PostScript informations 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      builder.addTable('post', createPostTable(properties)); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Images 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    beginInlineImage: function CanvasGraphics_beginInlineImage() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      error('Should not call beginInlineImage'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    beginImageData: function CanvasGraphics_beginImageData() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      error('Should not call beginImageData'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return builder.toArray(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    paintFormXObjectBegin: function CanvasGraphics_paintFormXObjectBegin(matrix, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                                        bbox) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.baseTransformStack.push(this.baseTransform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (isArray(matrix) && 6 === matrix.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.transform.apply(this, matrix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    get spaceWidth() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if ('_shadowWidth' in this) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return this._shadowWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.baseTransform = this.ctx.mozCurrentTransform; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (isArray(bbox) && 4 === bbox.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var width = bbox[2] - bbox[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var height = bbox[3] - bbox[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx.rect(bbox[0], bbox[1], width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.clip(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.endPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // trying to estimate space character width 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var possibleSpaceReplacements = ['space', 'minus', 'one', 'i']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = 0, ii = possibleSpaceReplacements.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var glyphName = possibleSpaceReplacements[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // if possible, getting width by glyph name 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (glyphName in this.widths) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          width = this.widths[glyphName]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var glyphsUnicodeMap = getGlyphsUnicode(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var glyphUnicode = glyphsUnicodeMap[glyphName]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // finding the charcode via unicodeToCID map 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var charcode = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (this.composite) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (this.cMap.contains(glyphUnicode)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            charcode = this.cMap.lookup(glyphUnicode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // ... via toUnicode map 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!charcode && this.toUnicode) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          charcode = this.toUnicode.charCodeOf(glyphUnicode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // setting it to unicode if negative or undefined 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (charcode <= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          charcode = glyphUnicode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // trying to get width via charcode 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        width = this.widths[charcode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (width) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          break; // the non-zero width found 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      width = width || this.defaultWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Do not shadow the property here. See discussion: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // https://github.com/mozilla/pdf.js/pull/2127#discussion_r1662280 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this._shadowWidth = width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    paintFormXObjectEnd: function CanvasGraphics_paintFormXObjectEnd() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.baseTransform = this.baseTransformStack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    charToGlyph: function Font_charToGlyph(charcode, isSpace) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fontCharCode, width, operatorListId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    beginGroup: function CanvasGraphics_beginGroup(group) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var currentCtx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // TODO non-isolated groups - according to Rik at adobe non-isolated 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // group results aren't usually that different and they even have tools 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // that ignore this setting. Notes from Rik on implmenting: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // - When you encounter an transparency group, create a new canvas with 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // the dimensions of the bbox 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // - copy the content from the previous canvas to the new canvas 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // - draw as usual 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // - remove the backdrop alpha: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // alphaNew = 1 - (1 - alpha)/(1 - alphaBackdrop) with 'alpha' the alpha 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // value of your transparency group and 'alphaBackdrop' the alpha of the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // backdrop 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // - remove background color: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // colorNew = color - alphaNew *colorBackdrop /(1 - alphaNew) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!group.isolated) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        info('TODO: Support non-isolated groups.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var widthCode = charcode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.cMap && this.cMap.contains(charcode)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        widthCode = this.cMap.lookup(charcode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      width = this.widths[widthCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      width = isNum(width) ? width : this.defaultWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var vmetric = this.vmetrics && this.vmetrics[widthCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // TODO knockout - supposedly possible with the clever use of compositing 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // modes. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (group.knockout) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        warn('Knockout groups not supported.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var unicode = this.toUnicode.get(charcode) || charcode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (typeof unicode === 'number') { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        unicode = String.fromCharCode(unicode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var currentTransform = currentCtx.mozCurrentTransform; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (group.matrix) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        currentCtx.transform.apply(currentCtx, group.matrix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var isInFont = charcode in this.toFontChar; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // First try the toFontChar map, if it's not there then try falling 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // back to the char code. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      fontCharCode = this.toFontChar[charcode] || charcode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.missingFile) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fontCharCode = mapSpecialUnicodeValues(fontCharCode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      assert(group.bbox, 'Bounding box is required.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Based on the current transform figure out how big the bounding box 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // will actually be. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var bounds = Util.getAxialAlignedBoundingBox( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    group.bbox, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    currentCtx.mozCurrentTransform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Clip the bounding box to the current canvas. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var canvasBounds = [0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                          0, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                          currentCtx.canvas.width, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                          currentCtx.canvas.height]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      bounds = Util.intersect(bounds, canvasBounds) || [0, 0, 0, 0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Use ceil in case we're between sizes so we don't create canvas that is 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // too small and make the canvas at least 1x1 pixels. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var offsetX = Math.floor(bounds[0]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var offsetY = Math.floor(bounds[1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var drawnWidth = Math.max(Math.ceil(bounds[2]) - offsetX, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var drawnHeight = Math.max(Math.ceil(bounds[3]) - offsetY, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var scaleX = 1, scaleY = 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (drawnWidth > MAX_GROUP_SIZE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        scaleX = drawnWidth / MAX_GROUP_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        drawnWidth = MAX_GROUP_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (drawnHeight > MAX_GROUP_SIZE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        scaleY = drawnHeight / MAX_GROUP_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        drawnHeight = MAX_GROUP_SIZE; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.isType3Font) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // Font char code in this case is actually a glyph name. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        operatorListId = fontCharCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var cacheId = 'groupAt' + this.groupLevel; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (group.smask) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Using two cache entries is case if masks are used one after another. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cacheId +=  '_smask_' + ((this.smaskCounter++) % 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var accent = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.seacMap && this.seacMap[charcode]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        isInFont = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var seac = this.seacMap[charcode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        fontCharCode = seac.baseFontCharCode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        accent = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          fontChar: String.fromCharCode(seac.accentFontCharCode), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          offset: seac.accentOffset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var scratchCanvas = this.cachedCanvases.getCanvas( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        cacheId, drawnWidth, drawnHeight, true); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var groupCtx = scratchCanvas.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Since we created a new canvas that is just the size of the bounding box 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // we have to translate the group ctx. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      groupCtx.scale(1 / scaleX, 1 / scaleY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      groupCtx.translate(-offsetX, -offsetY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      groupCtx.transform.apply(groupCtx, currentTransform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fontChar = String.fromCharCode(fontCharCode); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (group.smask) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Saving state and cached mask to be used in setGState. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.smaskStack.push({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          canvas: scratchCanvas.canvas, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          context: groupCtx, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          offsetX: offsetX, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          offsetY: offsetY, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          scaleX: scaleX, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          scaleY: scaleY, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          subtype: group.smask.subtype, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          backdrop: group.smask.backdrop, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          transferMap: group.smask.transferMap || null 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // Setup the current ctx so when the group is popped we draw it at the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // right location. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        currentCtx.setTransform(1, 0, 0, 1, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        currentCtx.translate(offsetX, offsetY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        currentCtx.scale(scaleX, scaleY); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var glyph = this.glyphCache[charcode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!glyph || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          !glyph.matchesForCache(fontChar, unicode, accent, width, vmetric, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                 operatorListId, isSpace, isInFont)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        glyph = new Glyph(fontChar, unicode, accent, width, vmetric, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          operatorListId, isSpace, isInFont); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        this.glyphCache[charcode] = glyph; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // The transparency group inherits all off the current graphics state 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // except the blend mode, soft mask, and alpha constants. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      copyCtxState(currentCtx, groupCtx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx = groupCtx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.setGState([ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ['BM', 'Normal'], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ['ca', 1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ['CA', 1] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.groupStack.push(currentCtx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.groupLevel++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return glyph; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    endGroup: function CanvasGraphics_endGroup(group) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.groupLevel--; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var groupCtx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.ctx = this.groupStack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Turn off image smoothing to avoid sub pixel interpolation which can 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // look kind of blurry for some pdfs. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.ctx.imageSmoothingEnabled !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx.imageSmoothingEnabled = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx.mozImageSmoothingEnabled = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    charsToGlyphs: function Font_charsToGlyphs(chars) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var charsCache = this.charsCache; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var glyphs, glyph, charcode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // if we translated this string before, just grab it from the cache 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (charsCache) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        glyphs = charsCache[chars]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (glyphs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          return glyphs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (group.smask) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.tempSMask = this.smaskStack.pop(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx.drawImage(groupCtx.canvas, 0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // lazily create the translation cache 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (!charsCache) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        charsCache = this.charsCache = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    beginAnnotations: function CanvasGraphics_beginAnnotations() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.current = new CanvasExtraState(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      glyphs = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var charsCacheKey = chars; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var i = 0, ii; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.baseTransform) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx.setTransform.apply(this.ctx, this.baseTransform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (this.cMap) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // composite fonts have multi-byte strings convert the string from 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // single-byte to multi-byte 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var c = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        while (i < chars.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          this.cMap.readCharCode(chars, i, c); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          charcode = c.charcode; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var length = c.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          i += length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Space is char with code 0x20 and length 1 in multiple-byte codes. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          var isSpace = length === 1 && chars.charCodeAt(i - 1) === 0x20; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          glyph = this.charToGlyph(charcode, isSpace); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          glyphs.push(glyph); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (i = 0, ii = chars.length; i < ii; ++i) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          charcode = chars.charCodeAt(i); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          glyph = this.charToGlyph(charcode, charcode === 0x20); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          glyphs.push(glyph); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    endAnnotations: function CanvasGraphics_endAnnotations() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Enter the translated string into the cache 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return (charsCache[charsCacheKey] = glyphs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    beginAnnotation: function CanvasGraphics_beginAnnotation(rect, transform, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                             matrix) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return Font; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (isArray(rect) && 4 === rect.length) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var width = rect[2] - rect[0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var height = rect[3] - rect[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx.rect(rect[0], rect[1], width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.clip(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.endPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var ErrorFont = (function ErrorFontClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function ErrorFont(error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.error = error; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.loadedName = 'g_font_error'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.loading = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.transform.apply(this, transform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.transform.apply(this, matrix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  ErrorFont.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    charsToGlyphs: function ErrorFont_charsToGlyphs() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    exportData: function ErrorFont_exportData() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return {error: this.error}; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    endAnnotation: function CanvasGraphics_endAnnotation() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return ErrorFont; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    paintJpegXObject: function CanvasGraphics_paintJpegXObject(objId, w, h) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var domImage = this.objs.get(objId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!domImage) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        warn('Dependent image isn\'t ready yet'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+/** 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * Shared logic for building a char code to glyph id mapping for Type1 and 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * simple CFF fonts. See section 9.6.6.2 of the spec. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param {Object} properties Font properties object. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param {Object} builtInEncoding The encoding contained within the actual font 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * data. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @param {Array} Array of glyph names where the index is the glyph ID. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ * @returns {Object} A char code to glyph ID map. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ */ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+function type1FontGlyphMapping(properties, builtInEncoding, glyphNames) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var charCodeToGlyphId = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var glyphId, charCode, baseEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (properties.baseEncodingName) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // If a valid base encoding name was used, the mapping is initialized with 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // that. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    baseEncoding = getEncoding(properties.baseEncodingName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (charCode = 0; charCode < baseEncoding.length; charCode++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      glyphId = glyphNames.indexOf(baseEncoding[charCode]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (glyphId >= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        charCodeToGlyphId[charCode] = glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        charCodeToGlyphId[charCode] = 0; // notdef 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else if (!!(properties.flags & FontFlags.Symbolic)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // For a symbolic font the encoding should be the fonts built-in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // encoding. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (charCode in builtInEncoding) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      charCodeToGlyphId[charCode] = builtInEncoding[charCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // For non-symbolic fonts that don't have a base encoding the standard 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // encoding should be used. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    baseEncoding = StandardEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (charCode = 0; charCode < baseEncoding.length; charCode++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      glyphId = glyphNames.indexOf(baseEncoding[charCode]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (glyphId >= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        charCodeToGlyphId[charCode] = glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        charCodeToGlyphId[charCode] = 0; // notdef 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  // Lastly, merge in the differences. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  var differences = properties.differences; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (differences) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (charCode in differences) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var glyphName = differences[charCode]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      glyphId = glyphNames.indexOf(glyphName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (glyphId >= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        charCodeToGlyphId[charCode] = glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        charCodeToGlyphId[charCode] = 0; // notdef 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return charCodeToGlyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // scale the image to the unit square 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.scale(1 / w, -1 / h); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Type1Font is also a CIDFontType0. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var Type1Font = (function Type1FontClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function findBlock(streamBytes, signature, startIndex) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var streamBytesLength = streamBytes.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var signatureLength = signature.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var scanLength = streamBytesLength - signatureLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.drawImage(domImage, 0, 0, domImage.width, domImage.height, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                    0, -h, w, h); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.imageLayer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var currentTransform = ctx.mozCurrentTransformInverse; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var position = this.getCanvasPosition(0, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.imageLayer.appendImage({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          objId: objId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          left: position[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          top: position[1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          width: w / currentTransform[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          height: h / currentTransform[3] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var i = startIndex, j, found = false; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    while (i < scanLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      j = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      while (j < signatureLength && streamBytes[i + j] === signature[j]) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        j++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    paintImageMaskXObject: function CanvasGraphics_paintImageMaskXObject(img) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var width = img.width, height = img.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fillColor = this.current.fillColor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var isPatternFill = this.current.patternFill; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (j >= signatureLength) { // `signature` found, skip over whitespace. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        i += j; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        while (i < streamBytesLength && Lexer.isSpace(streamBytes[i])) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          i++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        found = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      i++; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      found: found, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      length: i, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var glyph = this.processingType3; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function getHeaderBlock(stream, suggestedLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var EEXEC_SIGNATURE = [0x65, 0x65, 0x78, 0x65, 0x63]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (COMPILE_TYPE3_GLYPHS && glyph && glyph.compiled === undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (width <= MAX_SIZE_TO_COMPILE && height <= MAX_SIZE_TO_COMPILE) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          glyph.compiled = 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            compileType3Glyph({data: img.data, width: width, height: height}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          glyph.compiled = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var streamStartPos = stream.pos; // Save the initial stream position. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var headerBytes, headerBytesLength, block; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      headerBytes = stream.getBytes(suggestedLength); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      headerBytesLength = headerBytes.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } catch (ex) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (ex instanceof MissingDataException) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        throw ex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Ignore errors if the `suggestedLength` is huge enough that a Uint8Array 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // cannot hold the result of `getBytes`, and fallback to simply checking 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // the entire stream (fixes issue3928.pdf). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (glyph && glyph.compiled) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        glyph.compiled(ctx); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (headerBytesLength === suggestedLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Most of the time `suggestedLength` is correct, so to speed things up we 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // initially only check the last few bytes to see if the header was found. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Otherwise we (potentially) check the entire stream to prevent errors in 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // `Type1Parser` (fixes issue5686.pdf). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      block = findBlock(headerBytes, EEXEC_SIGNATURE, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                        suggestedLength - 2 * EEXEC_SIGNATURE.length); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (block.found && block.length === suggestedLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          stream: new Stream(headerBytes), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          length: suggestedLength, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    warn('Invalid "Length1" property in Type1 font -- trying to recover.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    stream.pos = streamStartPos; // Reset the stream position. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var maskCanvas = this.cachedCanvases.getCanvas('maskCanvas', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                     width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var maskCtx = maskCanvas.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      maskCtx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var SCAN_BLOCK_LENGTH = 2048; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var actualLength; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    while (true) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var scanBytes = stream.peekBytes(SCAN_BLOCK_LENGTH); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      block = findBlock(scanBytes, EEXEC_SIGNATURE, 0); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      putBinaryImageMask(maskCtx, img); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (block.length === 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      stream.pos += block.length; // Update the stream position. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      maskCtx.globalCompositeOperation = 'source-in'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (block.found) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        actualLength = stream.pos - streamStartPos; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        break; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    stream.pos = streamStartPos; // Reset the stream position. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      maskCtx.fillStyle = isPatternFill ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                          fillColor.getPattern(maskCtx, this) : fillColor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      maskCtx.fillRect(0, 0, width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (actualLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        stream: new Stream(stream.getBytes(actualLength)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        length: actualLength, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    warn('Unable to recover "Length1" property in Type1 font -- using as is.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      stream: new Stream(stream.getBytes(suggestedLength)), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      length: suggestedLength, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      maskCtx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function getEexecBlock(stream, suggestedLength) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // We should ideally parse the eexec block to ensure that `suggestedLength` 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // is correct, so we don't truncate the block data if it's too small. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // However, this would also require checking if the fixed-content portion 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // exists (using the 'Length3' property), and ensuring that it's valid. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Given that `suggestedLength` almost always is correct, all the validation 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // would require a great deal of unnecessary parsing for most fonts. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // To save time, we always fetch the entire stream instead, which also avoid 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // issues if `suggestedLength` is huge (see comment in `getHeaderBlock`). 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // NOTE: This means that the function can include the fixed-content portion 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // in the returned eexec block. In practice this does *not* seem to matter, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // since `Type1Parser_extractFontProgram` will skip over any non-commands. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var eexecBytes = stream.getBytes(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    return { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      stream: new Stream(eexecBytes), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      length: eexecBytes.length, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.paintInlineImageXObject(maskCanvas.canvas); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function Type1Font(name, file, properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Some bad generators embed pfb file as is, we have to strip 6-byte header. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Also, length1 and length2 might be off by 6 bytes as well. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // http://www.math.ubc.ca/~cass/piscript/type1.pdf 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var PFB_HEADER_SIZE = 6; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var headerBlockLength = properties.length1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var eexecBlockLength = properties.length2; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var pfbHeader = file.peekBytes(PFB_HEADER_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var pfbHeaderPresent = pfbHeader[0] === 0x80 && pfbHeader[1] === 0x01; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (pfbHeaderPresent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      file.skip(PFB_HEADER_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      headerBlockLength = (pfbHeader[5] << 24) | (pfbHeader[4] << 16) | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          (pfbHeader[3] << 8) | pfbHeader[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    paintImageMaskXObjectRepeat: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function CanvasGraphics_paintImageMaskXObjectRepeat(imgData, scaleX, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                          scaleY, positions) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var width = imgData.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var height = imgData.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fillColor = this.current.fillColor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var isPatternFill = this.current.patternFill; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Get the data block containing glyphs and subrs informations 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var headerBlock = getHeaderBlock(file, headerBlockLength); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    headerBlockLength = headerBlock.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var headerBlockParser = new Type1Parser(headerBlock.stream, false, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                            SEAC_ANALYSIS_ENABLED); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    headerBlockParser.extractFontHeader(properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var maskCanvas = this.cachedCanvases.getCanvas('maskCanvas', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                     width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var maskCtx = maskCanvas.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      maskCtx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    if (pfbHeaderPresent) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      pfbHeader = file.getBytes(PFB_HEADER_SIZE); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      eexecBlockLength = (pfbHeader[5] << 24) | (pfbHeader[4] << 16) | 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                         (pfbHeader[3] << 8) | pfbHeader[2]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      putBinaryImageMask(maskCtx, imgData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    // Decrypt the data blocks and retrieve it's content 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var eexecBlock = getEexecBlock(file, eexecBlockLength); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    eexecBlockLength = eexecBlock.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var eexecBlockParser = new Type1Parser(eexecBlock.stream, true, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                           SEAC_ANALYSIS_ENABLED); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var data = eexecBlockParser.extractFontProgram(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    for (var info in data.properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      properties[info] = data.properties[info]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      maskCtx.globalCompositeOperation = 'source-in'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var charstrings = data.charstrings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var type2Charstrings = this.getType2Charstrings(charstrings); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var subrs = this.getType2Subrs(data.subrs); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      maskCtx.fillStyle = isPatternFill ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                          fillColor.getPattern(maskCtx, this) : fillColor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      maskCtx.fillRect(0, 0, width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.charstrings = charstrings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.data = this.wrap(name, type2Charstrings, this.charstrings, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                          subrs, properties); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.seacs = this.getSeacs(data.charstrings); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      maskCtx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  Type1Font.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    get numGlyphs() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return this.charstrings.length + 1; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var i = 0, ii = positions.length; i < ii; i += 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.transform(scaleX, 0, 0, scaleY, positions[i], positions[i + 1]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.scale(1, -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.drawImage(maskCanvas.canvas, 0, 0, width, height, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          0, -1, 1, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getCharset: function Type1Font_getCharset() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var charset = ['.notdef']; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var charstrings = this.charstrings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var glyphId = 0; glyphId < charstrings.length; glyphId++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        charset.push(charstrings[glyphId].glyphName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return charset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    paintImageMaskXObjectGroup: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function CanvasGraphics_paintImageMaskXObjectGroup(images) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var fillColor = this.current.fillColor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var isPatternFill = this.current.patternFill; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var i = 0, ii = images.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var image = images[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var width = image.width, height = image.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var maskCanvas = this.cachedCanvases.getCanvas('maskCanvas', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                       width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var maskCtx = maskCanvas.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        maskCtx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        putBinaryImageMask(maskCtx, image); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        maskCtx.globalCompositeOperation = 'source-in'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        maskCtx.fillStyle = isPatternFill ? 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                            fillColor.getPattern(maskCtx, this) : fillColor; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        maskCtx.fillRect(0, 0, width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getGlyphMapping: function Type1Font_getGlyphMapping(properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var charstrings = this.charstrings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var glyphNames = ['.notdef'], glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (glyphId = 0; glyphId < charstrings.length; glyphId++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        glyphNames.push(charstrings[glyphId].glyphName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var encoding = properties.builtInEncoding; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (encoding) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var builtInEncoding = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        for (var charCode in encoding) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          glyphId = glyphNames.indexOf(encoding[charCode]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          if (glyphId >= 0) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            builtInEncoding[charCode] = glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        maskCtx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return type1FontGlyphMapping(properties, builtInEncoding, glyphNames); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.transform.apply(ctx, image.transform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.scale(1, -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.drawImage(maskCanvas.canvas, 0, 0, width, height, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      0, -1, 1, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getSeacs: function Type1Font_getSeacs(charstrings) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var i, ii; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var seacMap = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (i = 0, ii = charstrings.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var charstring = charstrings[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (charstring.seac) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // Offset by 1 for .notdef 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          seacMap[i + 1] = charstring.seac; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return seacMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    paintImageXObject: function CanvasGraphics_paintImageXObject(objId) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var imgData = this.objs.get(objId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!imgData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        warn('Dependent image isn\'t ready yet'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getType2Charstrings: function Type1Font_getType2Charstrings( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                    type1Charstrings) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var type2Charstrings = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (var i = 0, ii = type1Charstrings.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        type2Charstrings.push(type1Charstrings[i].charstring); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.paintInlineImageXObject(imgData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return type2Charstrings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    paintImageXObjectRepeat: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function CanvasGraphics_paintImageXObjectRepeat(objId, scaleX, scaleY, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                          positions) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var imgData = this.objs.get(objId); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (!imgData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        warn('Dependent image isn\'t ready yet'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        return; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getType2Subrs: function Type1Font_getType2Subrs(type1Subrs) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var bias = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var count = type1Subrs.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (count < 1133) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bias = 107; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else if (count < 33769) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bias = 1131; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        bias = 32768; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var width = imgData.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var height = imgData.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var map = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var i = 0, ii = positions.length; i < ii; i += 2) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        map.push({transform: [scaleX, 0, 0, scaleY, positions[i], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                 positions[i + 1]], x: 0, y: 0, w: width, h: height}); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // Add a bunch of empty subrs to deal with the Type2 bias 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var type2Subrs = []; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var i; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (i = 0; i < bias; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        type2Subrs.push([0x0B]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.paintInlineImageXObjectGroup(imgData, map); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (i = 0; i < count; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        type2Subrs.push(type1Subrs[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return type2Subrs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    paintInlineImageXObject: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function CanvasGraphics_paintInlineImageXObject(imgData) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var width = imgData.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var height = imgData.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    wrap: function Type1Font_wrap(name, glyphs, charstrings, subrs, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+                                  properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var cff = new CFF(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      cff.header = new CFFHeader(1, 0, 4, 4); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // scale the image to the unit square 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.scale(1 / width, -1 / height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      cff.names = [name]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var currentTransform = ctx.mozCurrentTransformInverse; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var a = currentTransform[0], b = currentTransform[1]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var widthScale = Math.max(Math.sqrt(a * a + b * b), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var c = currentTransform[2], d = currentTransform[3]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var heightScale = Math.max(Math.sqrt(c * c + d * d), 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var topDict = new CFFTopDict(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // CFF strings IDs 0...390 are predefined names, so refering 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // to entries in our own String INDEX starts at SID 391. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      topDict.setByName('version', 391); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      topDict.setByName('Notice', 392); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      topDict.setByName('FullName', 393); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      topDict.setByName('FamilyName', 394); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      topDict.setByName('Weight', 395); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      topDict.setByName('Encoding', null); // placeholder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      topDict.setByName('FontMatrix', properties.fontMatrix); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      topDict.setByName('FontBBox', properties.bbox); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      topDict.setByName('charset', null); // placeholder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      topDict.setByName('CharStrings', null); // placeholder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      topDict.setByName('Private', null); // placeholder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      cff.topDict = topDict; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var imgToPaint, tmpCanvas; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // instanceof HTMLElement does not work in jsdom node.js module 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (imgData instanceof HTMLElement || !imgData.data) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        imgToPaint = imgData; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tmpCanvas = this.cachedCanvases.getCanvas('inlineImage', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                  width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var tmpCtx = tmpCanvas.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        putBinaryImageData(tmpCtx, imgData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        imgToPaint = tmpCanvas.canvas; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var strings = new CFFStrings(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      strings.add('Version 0.11'); // Version 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      strings.add('See original notice'); // Notice 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      strings.add(name); // FullName 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      strings.add(name); // FamilyName 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      strings.add('Medium'); // Weight 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      cff.strings = strings; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var paintWidth = width, paintHeight = height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var tmpCanvasId = 'prescale1'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // Vertial or horizontal scaling shall not be more than 2 to not loose the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // pixels during drawImage operation, painting on the temporary canvas(es) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // that are twice smaller in size 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      while ((widthScale > 2 && paintWidth > 1) || 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-             (heightScale > 2 && paintHeight > 1)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var newWidth = paintWidth, newHeight = paintHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (widthScale > 2 && paintWidth > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          newWidth = Math.ceil(paintWidth / 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          widthScale /= paintWidth / newWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (heightScale > 2 && paintHeight > 1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          newHeight = Math.ceil(paintHeight / 2); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          heightScale /= paintHeight / newHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      cff.globalSubrIndex = new CFFIndex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var count = glyphs.length; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var charsetArray = [0]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var i, ii; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (i = 0; i < count; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var index = CFFStandardStrings.indexOf(charstrings[i].glyphName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // TODO: Insert the string and correctly map it.  Previously it was 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // thought mapping names that aren't in the standard strings to .notdef 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // was fine, however in issue818 when mapping them all to .notdef the 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        // adieresis glyph no longer worked. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (index === -1) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          index = 0; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tmpCanvas = this.cachedCanvases.getCanvas(tmpCanvasId, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                                  newWidth, newHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tmpCtx = tmpCanvas.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tmpCtx.clearRect(0, 0, newWidth, newHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tmpCtx.drawImage(imgToPaint, 0, 0, paintWidth, paintHeight, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                     0, 0, newWidth, newHeight); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        imgToPaint = tmpCanvas.canvas; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        paintWidth = newWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        paintHeight = newHeight; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        tmpCanvasId = tmpCanvasId === 'prescale1' ? 'prescale2' : 'prescale1'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        charsetArray.push((index >> 8) & 0xff, index & 0xff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.drawImage(imgToPaint, 0, 0, paintWidth, paintHeight, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                0, -height, width, height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      cff.charset = new CFFCharset(false, 0, [], charsetArray); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.imageLayer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var position = this.getCanvasPosition(0, -height); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.imageLayer.appendImage({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          imgData: imgData, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          left: position[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          top: position[1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          width: width / currentTransform[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          height: height / currentTransform[3] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var charStringsIndex = new CFFIndex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      charStringsIndex.add([0x8B, 0x0E]); // .notdef 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (i = 0; i < count; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        charStringsIndex.add(glyphs[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      this.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    paintInlineImageXObjectGroup: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function CanvasGraphics_paintInlineImageXObjectGroup(imgData, map) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var w = imgData.width; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var h = imgData.height; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var tmpCanvas = this.cachedCanvases.getCanvas('inlineImage', w, h); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var tmpCtx = tmpCanvas.context; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      putBinaryImageData(tmpCtx, imgData); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      cff.charStrings = charStringsIndex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      for (var i = 0, ii = map.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var entry = map[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.save(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.transform.apply(ctx, entry.transform); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.scale(1, -1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.drawImage(tmpCanvas.canvas, entry.x, entry.y, entry.w, entry.h, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                      0, -1, 1, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (this.imageLayer) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          var position = this.getCanvasPosition(entry.x, entry.y); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          this.imageLayer.appendImage({ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            imgData: imgData, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            left: position[0], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            top: position[1], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            width: w, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            height: h 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          }); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var privateDict = new CFFPrivateDict(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      privateDict.setByName('Subrs', null); // placeholder 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var fields = [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        'BlueValues', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        'OtherBlues', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        'FamilyBlues', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        'FamilyOtherBlues', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        'StemSnapH', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        'StemSnapV', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        'BlueShift', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        'BlueFuzz', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        'BlueScale', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        'LanguageGroup', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        'ExpansionFactor', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        'ForceBold', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        'StdHW', 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        'StdVW' 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (i = 0, ii = fields.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var field = fields[i]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (!(field in properties.privateData)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          continue; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        ctx.restore(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        var value = properties.privateData[field]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (isArray(value)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // All of the private dictionary array data in CFF must be stored as 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // "delta-encoded" numbers. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (var j = value.length - 1; j > 0; j--) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            value[j] -= value[j - 1]; // ... difference from previous value 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        privateDict.setByName(field, value); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      cff.topDict.privateDict = privateDict; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    paintSolidColorImageMask: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      function CanvasGraphics_paintSolidColorImageMask() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.ctx.fillRect(0, 0, 1, 1); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var subrIndex = new CFFIndex(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      for (i = 0, ii = subrs.length; i < ii; i++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        subrIndex.add(subrs[i]); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      privateDict.subrsIndex = subrIndex; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    paintXObject: function CanvasGraphics_paintXObject() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      warn('Unsupported \'paintXObject\' command.'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var compiler = new CFFCompiler(cff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return compiler.compile(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Marked content 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return Type1Font; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    markPoint: function CanvasGraphics_markPoint(tag) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // TODO Marked content. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    markPointProps: function CanvasGraphics_markPointProps(tag, properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // TODO Marked content. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    beginMarkedContent: function CanvasGraphics_beginMarkedContent(tag) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // TODO Marked content. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    beginMarkedContentProps: function CanvasGraphics_beginMarkedContentProps( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-                                        tag, properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // TODO Marked content. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    endMarkedContent: function CanvasGraphics_endMarkedContent() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // TODO Marked content. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+var CFFFont = (function CFFFontClosure() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  function CFFFont(file, properties) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.properties = properties; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Compatibility 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var parser = new CFFParser(file, properties, SEAC_ANALYSIS_ENABLED); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.cff = parser.parse(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    var compiler = new CFFCompiler(this.cff); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    this.seacs = this.cff.seacs; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    try { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.data = compiler.compile(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } catch (e) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      warn('Failed to compile font ' + properties.loadedName); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // There may have just been an issue with the compiler, set the data 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      // anyway and hope the font loaded. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      this.data = file; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    beginCompat: function CanvasGraphics_beginCompat() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // TODO ignore undefined operators (should we do that anyway?) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  CFFFont.prototype = { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    get numGlyphs() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return this.cff.charStrings.count; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    endCompat: function CanvasGraphics_endCompat() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      // TODO stop ignoring undefined operators 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getCharset: function CFFFont_getCharset() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return this.cff.charset.charset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    getGlyphMapping: function CFFFont_getGlyphMapping() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var cff = this.cff; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var properties = this.properties; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var charsets = cff.charset.charset; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var charCodeToGlyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    // Helper functions 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				- 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    consumePath: function CanvasGraphics_consumePath() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var ctx = this.ctx; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.pendingClip) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        if (this.pendingClip === EO_CLIP) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          if (ctx.mozFillRule !== undefined) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ctx.mozFillRule = 'evenodd'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ctx.clip(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ctx.mozFillRule = 'nonzero'; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-            ctx.clip('evenodd'); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      if (properties.composite) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        charCodeToGlyphId = Object.create(null); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        if (cff.isCIDFont) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // If the font is actually a CID font then we should use the charset 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // to map CIDs to GIDs. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (glyphId = 0; glyphId < charsets.length; glyphId++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var cid = charsets[glyphId]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            var charCode = properties.cMap.charCodeOf(cid); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            charCodeToGlyphId[charCode] = glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				           } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } else { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          ctx.clip(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // If it is NOT actually a CID font then CIDs should be mapped 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          // directly to GIDs. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          for (glyphId = 0; glyphId < cff.charStrings.count; glyphId++) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+            charCodeToGlyphId[glyphId] = glyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+          } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				         } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.pendingClip = null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ctx.beginPath(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    getSinglePixelWidth: function CanvasGraphics_getSinglePixelWidth(scale) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      if (this.cachedGetSinglePixelWidth === null) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        var inverse = this.ctx.mozCurrentTransformInverse; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        // max of the current horizontal and vertical scale 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        this.cachedGetSinglePixelWidth = Math.sqrt(Math.max( 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          (inverse[0] * inverse[0] + inverse[1] * inverse[1]), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-          (inverse[2] * inverse[2] + inverse[3] * inverse[3]))); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+        return charCodeToGlyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				       } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return this.cachedGetSinglePixelWidth; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    }, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    getCanvasPosition: function CanvasGraphics_getCanvasPosition(x, y) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      var transform = this.ctx.mozCurrentTransform; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      return [ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        transform[0] * x + transform[2] * y + transform[4], 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-        transform[1] * x + transform[3] * y + transform[5] 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-      ]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      var encoding = cff.encoding ? cff.encoding.encoding : null; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      charCodeToGlyphId = type1FontGlyphMapping(properties, encoding, charsets); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      return charCodeToGlyphId; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				     } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   }; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  for (var op in OPS) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-    CanvasGraphics.prototype[OPS[op]] = CanvasGraphics.prototype[op]; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  return CFFFont; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Workaround for seac on Windows. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(function checkSeacSupport() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (typeof navigator !== 'undefined' && /Windows/.test(navigator.userAgent)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SEAC_ANALYSIS_ENABLED = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				   } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+})(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-  return CanvasGraphics; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// Workaround for Private Use Area characters in Chrome on Windows 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// http://code.google.com/p/chromium/issues/detail?id=122465 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+// https://github.com/mozilla/pdf.js/issues/1689 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+(function checkChromeWindows() { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  if (typeof navigator !== 'undefined' && 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+      /Windows.*Chrome/.test(navigator.userAgent)) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+    SKIP_PRIVATE_USE_RANGE_F000_TO_F01F = true; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+  } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 })(); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-exports.CanvasGraphics = CanvasGraphics; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-exports.createScratchCanvas = createScratchCanvas; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+exports.SEAC_ANALYSIS_ENABLED = SEAC_ANALYSIS_ENABLED; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+exports.ErrorFont = ErrorFont; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+exports.Font = Font; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+exports.FontFlags = FontFlags; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+exports.IdentityToUnicodeMap = IdentityToUnicodeMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+exports.ToUnicodeMap = ToUnicodeMap; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+exports.getFontType = getFontType; 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 })); 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 |