Merge font and processor working into one worker and fix some bugs in font-loading-data-ready code
This commit is contained in:
		
							parent
							
								
									e9b6ffbaf6
								
							
						
					
					
						commit
						d7521f758a
					
				
							
								
								
									
										11
									
								
								fonts.js
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								fonts.js
									
									
									
									
									
								
							| @ -211,6 +211,17 @@ var FontLoader = { | ||||
|   }, | ||||
| 
 | ||||
|   bind: function fontLoaderBind(fonts, callback, objects) { | ||||
|     var fontsToLoad = {}; | ||||
|     // check if there are twice the same font.
 | ||||
|     for (var i = 0; i < fonts.length; i++) { | ||||
|       var fontName = fonts[i].loadedName; | ||||
|       if (fontsToLoad[fontName]) { | ||||
|         throw "Got twice the same font!"; | ||||
|       } else { | ||||
|         fontsToLoad[fontName] = true; | ||||
|       } | ||||
|     } | ||||
|      | ||||
|     function checkFontsLoaded() { | ||||
|       for (var i = 0; i < objs.length; i++) { | ||||
|         var fontObj = objs[i]; | ||||
|  | ||||
							
								
								
									
										2
									
								
								pdf.js
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								pdf.js
									
									
									
									
									
								
							| @ -3387,7 +3387,7 @@ var Page = (function() { | ||||
|     }, | ||||
|      | ||||
|     ensureFonts: function(fonts, callback) { | ||||
|       console.log('--ensureFonts--'); | ||||
|       console.log('--ensureFonts--', '' + fonts); | ||||
|       // Convert the font names to the corresponding font obj.
 | ||||
|       for (var i = 0; i < fonts.length; i++) { | ||||
|         // HACK FOR NOW. Access the data directly. This isn't allowed as the
 | ||||
|  | ||||
| @ -14,7 +14,6 @@ | ||||
|         <script type="text/javascript" src="../worker.js"></script> | ||||
|         <script type="text/javascript" src="../worker/message_handler.js"></script> | ||||
|         <script type="text/javascript" src="../worker/processor_handler.js"></script> | ||||
|         <script type="text/javascript" src="../worker/font_handler.js"></script> | ||||
|   </head> | ||||
| 
 | ||||
|   <body> | ||||
|  | ||||
							
								
								
									
										42
									
								
								worker.js
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								worker.js
									
									
									
									
									
								
							| @ -264,8 +264,7 @@ var WorkerPDFDoc = (function() { | ||||
|     this.pageCache = []; | ||||
|      | ||||
|     if (useWorker) { | ||||
|       var worker = this.worker = new Worker("../worker/processor_boot.js"); | ||||
|       var fontWorker = this.fontWorker = new Worker('../worker/font_boot.js'); | ||||
|       var worker = this.worker = new Worker("../worker/pdf_worker_loader.js"); | ||||
|     } else { | ||||
|       // If we don't use a worker, just post/sendMessage to the main thread.
 | ||||
|       var worker = { | ||||
| @ -273,12 +272,9 @@ var WorkerPDFDoc = (function() { | ||||
|           worker.onmessage({data: obj}); | ||||
|         } | ||||
|       } | ||||
|       var fontWorker = { | ||||
|         postMessage: function(obj) { | ||||
|           fontWorker.onmessage({data: obj}); | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|      | ||||
|     this.fontsLoading = {}; | ||||
| 
 | ||||
|     var processorHandler = this.processorHandler = new MessageHandler("main", worker); | ||||
|     processorHandler.on("page", function(data) { | ||||
| @ -289,23 +285,43 @@ var WorkerPDFDoc = (function() { | ||||
|       // are all the fonts that are required to render the page AND that
 | ||||
|       // aren't loaded on the page yet.
 | ||||
|       var depFonts = data.depFonts; | ||||
|       var fontsToLoad = []; | ||||
|       var objs = this.objs; | ||||
|       var fontsToLoad = []; | ||||
|       var fontsLoading = this.fontsLoading; | ||||
|       // The `i` for the checkFontData is stored here to keep the state in
 | ||||
|       // the closure.
 | ||||
|       var i = 0;   | ||||
|                    | ||||
| 
 | ||||
|       function checkFontData() { | ||||
|         // Check if all fontObjs have been processed. If not, shedule a
 | ||||
|         // callback that is called once the data arrives and that checks
 | ||||
|         // the next fonts.
 | ||||
|         for (var i = 0; i < depFonts.length; i++) { | ||||
|         for (i; i < depFonts.length; i++) { | ||||
|           var fontName = depFonts[i]; | ||||
|           if (!objs.hasData(fontName)) { | ||||
|             console.log('need to wait for fontData', fontName); | ||||
|             objs.onData(fontObj, checkFontData); | ||||
|             objs.onData(fontName, checkFontData); | ||||
|             return; | ||||
|           } else if (!objs.isResolved(fontName)) { | ||||
|             fontsToLoad.push(fontName); | ||||
|           } | ||||
|         } | ||||
|          | ||||
|         // There can be edge cases where two pages wait for one font and then
 | ||||
|         // call startRenderingFromIRQueue twice with the same font. That makes
 | ||||
|         // the font getting loaded twice and throw an error later as the font
 | ||||
|         // promise gets resolved twice.
 | ||||
|         // This prevents thats fonts are loaded really only once.
 | ||||
|         for (var j = 0; j < fontsToLoad.length; j++) { | ||||
|           var fontName = fontsToLoad[j]; | ||||
|           if (fontsLoading[fontName]) { | ||||
|             fontsToLoad.splice(j, 1); | ||||
|             j--; | ||||
|           } else { | ||||
|             fontsLoading[fontName] = true; | ||||
|           } | ||||
|         } | ||||
| 
 | ||||
|         // At this point, all font data ia loaded. Start the actuall rendering.
 | ||||
|         page.startRenderingFromIRQueue(data.IRQueue, fontsToLoad); | ||||
| @ -329,15 +345,14 @@ var WorkerPDFDoc = (function() { | ||||
|           var file = data[3]; | ||||
|           var properties = data[4]; | ||||
| 
 | ||||
|           fontHandler.send("font", [objId, name, file, properties]); | ||||
|           processorHandler.send("font", [objId, name, file, properties]); | ||||
|         break; | ||||
|         default: | ||||
|           throw "Got unkown object type " + objType; | ||||
|       } | ||||
|     }, this); | ||||
| 
 | ||||
|     var fontHandler = this.fontHandler = new MessageHandler('font', fontWorker); | ||||
|     fontHandler.on('font_ready', function(data) { | ||||
|     processorHandler.on('font_ready', function(data) { | ||||
|       var objId   = data[0]; | ||||
|       var fontObj = new FontShape(data[1]); | ||||
| 
 | ||||
| @ -355,7 +370,6 @@ var WorkerPDFDoc = (function() { | ||||
|       // If the main thread is our worker, setup the handling for the messages
 | ||||
|       // the main thread sends to it self.
 | ||||
|       WorkerProcessorHandler.setup(processorHandler); | ||||
|       WorkerFontHandler.setup(fontHandler); | ||||
|     } | ||||
|      | ||||
|     processorHandler.send("doc", data); | ||||
|  | ||||
| @ -1,16 +0,0 @@ | ||||
| /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- / | ||||
| /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ | ||||
| 
 | ||||
| 'use strict'; | ||||
| 
 | ||||
| importScripts('console.js'); | ||||
| importScripts('message_handler.js'); | ||||
| importScripts('../pdf.js'); | ||||
| importScripts('../fonts.js'); | ||||
| importScripts('../crypto.js'); | ||||
| importScripts('../glyphlist.js'); | ||||
| importScripts('font_handler.js'); | ||||
| 
 | ||||
| 
 | ||||
| var handler = new MessageHandler("worker_font", this); | ||||
| WorkerFontHandler.setup(handler); | ||||
| @ -1,52 +0,0 @@ | ||||
| var WorkerFontHandler = { | ||||
|   setup: function(handler) { | ||||
|     handler.on("font", function(data) {   | ||||
|       var objId      = data[0]; | ||||
|       var name       = data[1]; | ||||
|       var file       = data[2]; | ||||
|       var properties = data[3]; | ||||
| 
 | ||||
|       var font = { | ||||
|         name: name, | ||||
|         file: file, | ||||
|         properties: properties | ||||
|       }; | ||||
| 
 | ||||
|       // Some fonts don't have a file, e.g. the build in ones like Arial.
 | ||||
|       if (file) { | ||||
|         var fontFileDict = new Dict(); | ||||
|         fontFileDict.map = file.dict.map; | ||||
| 
 | ||||
|         var fontFile = new Stream(file.bytes, file.start, | ||||
|                                   file.end - file.start, fontFileDict); | ||||
|                           | ||||
|         // Check if this is a FlateStream. Otherwise just use the created 
 | ||||
|         // Stream one. This makes complex_ttf_font.pdf work.
 | ||||
|         var cmf = file.bytes[0]; | ||||
|         if ((cmf & 0x0f) == 0x08) { | ||||
|           font.file = new FlateStream(fontFile); | ||||
|         } else { | ||||
|           font.file = fontFile; | ||||
|         }           | ||||
|       } | ||||
| 
 | ||||
|       var obj = new Font(font.name, font.file, font.properties); | ||||
| 
 | ||||
|       var str = ''; | ||||
|       var data = obj.data; | ||||
|       if (data) { | ||||
|         var length = data.length; | ||||
|         for (var j = 0; j < length; j++) | ||||
|           str += String.fromCharCode(data[j]); | ||||
|       } | ||||
| 
 | ||||
|       obj.str = str; | ||||
| 
 | ||||
|       // Remove the data array form the font object, as it's not needed
 | ||||
|       // anymore as we sent over the ready str.
 | ||||
|       delete obj.data; | ||||
| 
 | ||||
|       handler.send("font_ready", [objId, obj]); | ||||
|     }); | ||||
|   } | ||||
| } | ||||
| @ -63,5 +63,54 @@ var WorkerProcessorHandler = { | ||||
|         depFonts: Object.keys(fonts) | ||||
|       }); | ||||
|     }, this); | ||||
|      | ||||
|     handler.on("font", function(data) {   | ||||
|       var objId      = data[0]; | ||||
|       var name       = data[1]; | ||||
|       var file       = data[2]; | ||||
|       var properties = data[3]; | ||||
| 
 | ||||
|       var font = { | ||||
|         name: name, | ||||
|         file: file, | ||||
|         properties: properties | ||||
|       }; | ||||
| 
 | ||||
|       // Some fonts don't have a file, e.g. the build in ones like Arial.
 | ||||
|       if (file) { | ||||
|         var fontFileDict = new Dict(); | ||||
|         fontFileDict.map = file.dict.map; | ||||
| 
 | ||||
|         var fontFile = new Stream(file.bytes, file.start, | ||||
|                                   file.end - file.start, fontFileDict); | ||||
|                           | ||||
|         // Check if this is a FlateStream. Otherwise just use the created 
 | ||||
|         // Stream one. This makes complex_ttf_font.pdf work.
 | ||||
|         var cmf = file.bytes[0]; | ||||
|         if ((cmf & 0x0f) == 0x08) { | ||||
|           font.file = new FlateStream(fontFile); | ||||
|         } else { | ||||
|           font.file = fontFile; | ||||
|         }           | ||||
|       } | ||||
| 
 | ||||
|       var obj = new Font(font.name, font.file, font.properties); | ||||
| 
 | ||||
|       var str = ''; | ||||
|       var data = obj.data; | ||||
|       if (data) { | ||||
|         var length = data.length; | ||||
|         for (var j = 0; j < length; j++) | ||||
|           str += String.fromCharCode(data[j]); | ||||
|       } | ||||
| 
 | ||||
|       obj.str = str; | ||||
| 
 | ||||
|       // Remove the data array form the font object, as it's not needed
 | ||||
|       // anymore as we sent over the ready str.
 | ||||
|       delete obj.data; | ||||
| 
 | ||||
|       handler.send("font_ready", [objId, obj]); | ||||
|     }); | ||||
|   } | ||||
| } | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user