[Pkg-javascript-commits] [pdf.js] 159/210: Adds Promise to the getOperatorList

David Prévot taffit at moszumanska.debian.org
Thu Jun 5 14:21:13 UTC 2014


This is an automated email from the git hooks/post-receive script.

taffit pushed a commit to branch upstream
in repository pdf.js.

commit d8eb8b1de134d7ee1d56b7c9b53279609d377e18
Author: Yury Delendik <ydelendik at mozilla.com>
Date:   Fri May 9 20:21:15 2014 -0500

    Adds Promise to the getOperatorList
---
 src/core/core.js            |  33 +-
 src/core/evaluator.js       | 768 +++++++++++++++++++++++---------------------
 src/core/obj.js             |  14 +-
 src/core/worker.js          |   3 +-
 src/shared/annotation.js    |  34 +-
 test/unit/evaluator_spec.js | 186 ++++++-----
 6 files changed, 559 insertions(+), 479 deletions(-)

diff --git a/src/core/core.js b/src/core/core.js
index 1f054ac..e3a8210 100644
--- a/src/core/core.js
+++ b/src/core/core.js
@@ -156,13 +156,6 @@ var Page = (function PageClosure() {
 
     getOperatorList: function Page_getOperatorList(handler, intent) {
       var self = this;
-      var capability = createPromiseCapability();
-
-      function reject(e) {
-        capability.reject(e);
-      }
-
-      var pageListCapability = createPromiseCapability();
 
       var pdfManager = this.pdfManager;
       var contentStreamPromise = pdfManager.ensure(this, 'getContentStream',
@@ -184,9 +177,8 @@ var Page = (function PageClosure() {
                                                   this.idCounters,
                                                   this.fontCache);
 
-      var dataPromises = Promise.all([contentStreamPromise, resourcesPromise],
-                                     reject);
-      dataPromises.then(function(data) {
+      var dataPromises = Promise.all([contentStreamPromise, resourcesPromise]);
+      var pageListPromise = dataPromises.then(function(data) {
         var contentStream = data[0];
         var opList = new OperatorList(intent, handler, self.pageIndex);
 
@@ -195,31 +187,30 @@ var Page = (function PageClosure() {
           pageIndex: self.pageIndex,
           intent: intent
         });
-        partialEvaluator.getOperatorList(contentStream, self.resources, opList);
-        pageListCapability.resolve(opList);
+        return partialEvaluator.getOperatorList(contentStream, self.resources,
+          opList).then(function () {
+            return opList;
+          });
       });
 
       var annotationsPromise = pdfManager.ensure(this, 'annotations');
-      Promise.all([pageListCapability.promise, annotationsPromise]).then(
+      return Promise.all([pageListPromise, annotationsPromise]).then(
           function(datas) {
         var pageOpList = datas[0];
         var annotations = datas[1];
 
         if (annotations.length === 0) {
           pageOpList.flush(true);
-          capability.resolve(pageOpList);
-          return;
+          return pageOpList;
         }
 
         var annotationsReadyPromise = Annotation.appendToOperatorList(
           annotations, pageOpList, pdfManager, partialEvaluator, intent);
-        annotationsReadyPromise.then(function () {
+        return annotationsReadyPromise.then(function () {
           pageOpList.flush(true);
-          capability.resolve(pageOpList);
-        }, reject);
-      }, reject);
-
-      return capability.promise;
+          return pageOpList;
+        });
+      });
     },
 
     extractTextContent: function Page_extractTextContent() {
diff --git a/src/core/evaluator.js b/src/core/evaluator.js
index 29411bb..9c2a8dc 100644
--- a/src/core/evaluator.js
+++ b/src/core/evaluator.js
@@ -22,7 +22,7 @@
            stdFontMap, symbolsFonts, getTilingPatternIR, warn, Util, Promise,
            RefSetCache, isRef, TextRenderingMode, CMapFactory, OPS,
            UNSUPPORTED_FEATURES, UnsupportedManager, NormalizedUnicodes,
-           IDENTITY_MATRIX, reverseIfRtl */
+           IDENTITY_MATRIX, reverseIfRtl, createPromiseCapability */
 
 'use strict';
 
@@ -121,13 +121,15 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
 
       operatorList.addOp(OPS.paintFormXObjectBegin, [matrix, bbox]);
 
-      this.getOperatorList(xobj, (xobj.dict.get('Resources') || resources),
-                           operatorList, initialState);
-      operatorList.addOp(OPS.paintFormXObjectEnd, []);
+      return this.getOperatorList(xobj,
+        (xobj.dict.get('Resources') || resources), operatorList, initialState).
+        then(function () {
+          operatorList.addOp(OPS.paintFormXObjectEnd, []);
 
-      if (group) {
-        operatorList.addOp(OPS.endGroup, [groupOptions]);
-      }
+          if (group) {
+            operatorList.addOp(OPS.endGroup, [groupOptions]);
+          }
+        });
     },
 
     buildPaintImageXObject:
@@ -236,7 +238,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
         subtype: smask.get('S').name,
         backdrop: smask.get('BC')
       };
-      this.buildFormXObject(resources, smaskContent, smaskOptions,
+      return this.buildFormXObject(resources, smaskContent, smaskOptions,
                             operatorList, stateManager.state.clone());
     },
 
@@ -245,15 +247,18 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
                                                    pattern, patternDict,
                                                    operatorList) {
       // Create an IR of the pattern code.
-      var tilingOpList = this.getOperatorList(pattern,
-        (patternDict.get('Resources') || resources));
-      // Add the dependencies to the parent operator list so they are resolved
-      // before sub operator list is executed synchronously.
-      operatorList.addDependencies(tilingOpList.dependencies);
-      operatorList.addOp(fn, getTilingPatternIR({
-                               fnArray: tilingOpList.fnArray,
-                               argsArray: tilingOpList.argsArray
-                             }, patternDict, args));
+      var tilingOpList = new OperatorList();
+      return this.getOperatorList(pattern,
+        (patternDict.get('Resources') || resources), tilingOpList).
+        then(function () {
+          // Add the dependencies to the parent operator list so they are
+          // resolved before sub operator list is executed synchronously.
+          operatorList.addDependencies(tilingOpList.dependencies);
+          operatorList.addOp(fn, getTilingPatternIR({
+            fnArray: tilingOpList.fnArray,
+            argsArray: tilingOpList.argsArray
+          }, patternDict, args));
+        });
     },
 
     handleSetFont:
@@ -266,22 +271,23 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
         fontName = fontArgs[0].name;
       }
       var self = this;
-      var font = this.loadFont(fontName, fontRef, this.xref, resources,
-                               operatorList);
-      state.font = font;
-      var loadedName = font.loadedName;
-      if (!font.sent) {
-        var fontData = font.translated.exportData();
-
-        self.handler.send('commonobj', [
-          loadedName,
-          'Font',
-          fontData
-        ]);
-        font.sent = true;
-      }
-
-      return loadedName;
+      return this.loadFont(fontName, fontRef, this.xref, resources,
+                               operatorList).then(function (font) {
+          state.font = font;
+          var loadedName = font.loadedName;
+          if (!font.sent) {
+            var fontData = font.translated.exportData();
+
+            self.handler.send('commonobj', [
+              loadedName,
+              'Font',
+              fontData
+            ]);
+            font.sent = true;
+          }
+
+          return loadedName;
+        });
     },
 
     handleText: function PartialEvaluator_handleText(chars, state) {
@@ -324,7 +330,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
                                                    operatorList, xref,
                                                    stateManager) {
 
-      var self = this;
       // TODO(mack): This should be rewritten so that this function returns
       // what should be added to the queue during each iteration
       function setGStateForKey(gStateObj, key, value) {
@@ -343,11 +348,14 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
             gStateObj.push([key, value]);
             break;
           case 'Font':
-            var loadedName = self.handleSetFont(resources, null, value[0],
-                                                operatorList,
-                                                stateManager.state);
-            operatorList.addDependency(loadedName);
-            gStateObj.push([key, [loadedName, value[1]]]);
+            promise = promise.then(function () {
+              return self.handleSetFont(resources, null, value[0],
+                                        operatorList, stateManager.state).
+                then(function (loadedName) {
+                  operatorList.addDependency(loadedName);
+                  gStateObj.push([key, [loadedName, value[1]]]);
+                });
+            });
             break;
           case 'BM':
             gStateObj.push([key, value]);
@@ -359,7 +367,10 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
             }
             var dict = xref.fetchIfRef(value);
             if (isDict(dict)) {
-              self.handleSMask(dict, resources, operatorList, stateManager);
+              promise = promise.then(function () {
+                return self.handleSMask(dict, resources, operatorList,
+                                        stateManager);
+              });
               gStateObj.push([key, true]);
             } else {
               warn('Unsupported SMask type');
@@ -394,12 +405,15 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
       // This array holds the converted/processed state data.
       var gStateObj = [];
       var gStateMap = gState.map;
+      var self = this;
+      var promise = Promise.resolve();
       for (var key in gStateMap) {
         var value = gStateMap[key];
         setGStateForKey(gStateObj, key, value);
       }
-
-      operatorList.addOp(OPS.setGState, [gStateObj]);
+      return promise.then(function () {
+        operatorList.addOp(OPS.setGState, [gStateObj]);
+      });
     },
 
     loadFont: function PartialEvaluator_loadFont(fontName, font, xref,
@@ -407,10 +421,10 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
                                                  parentOperatorList) {
 
       function errorFont() {
-        return {
+        return Promise.resolve({
           translated: new ErrorFont('Font ' + fontName + ' is not available'),
           loadedName: 'g_font_error'
-        };
+        });
       }
 
       var fontRef;
@@ -435,6 +449,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
         return errorFont();
       }
 
+      var fontCapability = createPromiseCapability();
+
       var preEvaluatedFont = this.preEvaluateFont(font, xref);
       var descriptor = preEvaluatedFont.descriptor;
       var fontID = fontRef.num + '_' + fontRef.gen;
@@ -471,7 +487,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
       // fontName in font.loadedName below.
       var fontRefIsDict = isDict(fontRef);
       if (!fontRefIsDict) {
-        this.fontCache.put(fontRef, font);
+        this.fontCache.put(fontRef, fontCapability.promise);
       }
 
       // Keep track of each font we translated so the caller can
@@ -490,27 +506,38 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
         font.translated = translated;
       }
 
+      var loadCharProcsPromise = Promise.resolve();
       if (font.translated.loadCharProcs) {
         var charProcs = font.get('CharProcs').getAll();
         var fontResources = (font.get('Resources') || resources);
         var charProcKeys = Object.keys(charProcs);
         var charProcOperatorList = {};
         for (var i = 0, n = charProcKeys.length; i < n; ++i) {
-          var key = charProcKeys[i];
-          var glyphStream = charProcs[key];
-          var operatorList = this.getOperatorList(glyphStream, fontResources);
-          charProcOperatorList[key] = operatorList.getIR();
-          if (!parentOperatorList) {
-            continue;
-          }
-          // Add the dependencies to the parent operator list so they are
-          // resolved before sub operator list is executed synchronously.
-          parentOperatorList.addDependencies(charProcOperatorList.dependencies);
+          loadCharProcsPromise = loadCharProcsPromise.then(function (key) {
+            var glyphStream = charProcs[key];
+            var operatorList = new OperatorList();
+            return this.getOperatorList(glyphStream, fontResources,
+                                        operatorList).
+              then(function () {
+                charProcOperatorList[key] = operatorList.getIR();
+
+                // Add the dependencies to the parent operator list so they are
+                // resolved before sub operator list is executed synchronously.
+                if (parentOperatorList) {
+                  parentOperatorList.addDependencies(operatorList.dependencies);
+                }
+              });
+          }.bind(this, charProcKeys[i]));
         }
-        font.translated.charProcOperatorList = charProcOperatorList;
+        loadCharProcsPromise = loadCharProcsPromise.then(function () {
+          font.translated.charProcOperatorList = charProcOperatorList;
+        });
       }
-      font.loaded = true;
-      return font;
+      return loadCharProcsPromise.then(function () {
+        font.loaded = true;
+        fontCapability.resolve(font);
+        return fontCapability.promise;
+      }, fontCapability.reject);
     },
 
     buildPath: function PartialEvaluator_buildPath(operatorList, fn, args) {
@@ -534,182 +561,187 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
       var xref = this.xref;
       var imageCache = {};
 
-      operatorList = (operatorList || new OperatorList());
+      assert(operatorList);
 
       resources = (resources || Dict.empty);
       var xobjs = (resources.get('XObject') || Dict.empty);
       var patterns = (resources.get('Pattern') || Dict.empty);
       var stateManager = new StateManager(initialState || new EvalState());
       var preprocessor = new EvaluatorPreprocessor(stream, xref, stateManager);
-
-      var operation, i, ii;
-      while ((operation = preprocessor.read())) {
-        var args = operation.args;
-        var fn = operation.fn;
-        var shading;
-
-        switch (fn | 0) {
-          case OPS.setStrokeColorN:
-          case OPS.setFillColorN:
-            if (args[args.length - 1].code) {
+      var shading;
+
+      return new Promise(function next(resolve, reject) {
+        var operation, i, ii;
+        while ((operation = preprocessor.read())) {
+          var args = operation.args;
+          var fn = operation.fn;
+
+          switch (fn | 0) {
+            case OPS.setStrokeColorN:
+            case OPS.setFillColorN:
+              if (args[args.length - 1].code) {
+                break;
+              }
+              // compile tiling patterns
+              var patternName = args[args.length - 1];
+              // SCN/scn applies patterns along with normal colors
+              var pattern;
+              if (isName(patternName) &&
+                  (pattern = patterns.get(patternName.name))) {
+                var dict = (isStream(pattern) ? pattern.dict : pattern);
+                var typeNum = dict.get('PatternType');
+
+                if (typeNum == TILING_PATTERN) {
+                  return self.handleTilingType(fn, args, resources, pattern,
+                                               dict, operatorList).then(
+                    function() {
+                      next(resolve, reject);
+                    }, reject);
+                } else if (typeNum == SHADING_PATTERN) {
+                  shading = dict.get('Shading');
+                  var matrix = dict.get('Matrix');
+                  pattern = Pattern.parseShading(shading, matrix, xref,
+                    resources);
+                  args = pattern.getIR();
+                } else {
+                  error('Unknown PatternType ' + typeNum);
+                }
+              }
               break;
-            }
-            // compile tiling patterns
-            var patternName = args[args.length - 1];
-            // SCN/scn applies patterns along with normal colors
-            var pattern;
-            if (isName(patternName) &&
-                (pattern = patterns.get(patternName.name))) {
-              var dict = (isStream(pattern) ? pattern.dict : pattern);
-              var typeNum = dict.get('PatternType');
-
-              if (typeNum == TILING_PATTERN) {
-                self.handleTilingType(fn, args, resources, pattern, dict,
-                                      operatorList);
+            case OPS.paintXObject:
+              if (args[0].code) {
+                break;
+              }
+              // eagerly compile XForm objects
+              var name = args[0].name;
+              if (imageCache.key === name) {
+                operatorList.addOp(imageCache.fn, imageCache.args);
                 args = [];
                 continue;
-              } else if (typeNum == SHADING_PATTERN) {
-                shading = dict.get('Shading');
-                var matrix = dict.get('Matrix');
-                pattern = Pattern.parseShading(shading, matrix, xref,
-                                               resources);
-                args = pattern.getIR();
-              } else {
-                error('Unkown PatternType ' + typeNum);
               }
-            }
-            break;
-          case OPS.paintXObject:
-            if (args[0].code) {
-              break;
-            }
-            // eagerly compile XForm objects
-            var name = args[0].name;
-            if (imageCache.key === name) {
-              operatorList.addOp(imageCache.fn, imageCache.args);
-              args = [];
-              continue;
-            }
-
-            var xobj = xobjs.get(name);
-            if (xobj) {
-              assert(isStream(xobj), 'XObject should be a stream');
-
-              var type = xobj.dict.get('Subtype');
-              assert(isName(type),
-                'XObject should have a Name subtype');
 
-              if ('Form' == type.name) {
-                stateManager.save();
-                self.buildFormXObject(resources, xobj, null, operatorList,
-                                      stateManager.state.clone());
-                args = [];
-                stateManager.restore();
-                continue;
-              } else if ('Image' == type.name) {
-                self.buildPaintImageXObject(resources, xobj, false,
-                                            operatorList, name, imageCache);
+              var xobj = xobjs.get(name);
+              if (xobj) {
+                assert(isStream(xobj), 'XObject should be a stream');
+
+                var type = xobj.dict.get('Subtype');
+                assert(isName(type),
+                  'XObject should have a Name subtype');
+
+                if ('Form' == type.name) {
+                  stateManager.save();
+                  return self.buildFormXObject(resources, xobj, null,
+                                               operatorList,
+                                               stateManager.state.clone()).
+                    then(function () {
+                      stateManager.restore();
+                      next(resolve, reject);
+                    }, reject);
+                } else if ('Image' == type.name) {
+                  self.buildPaintImageXObject(resources, xobj, false,
+                    operatorList, name, imageCache);
+                  args = [];
+                  continue;
+                } else {
+                  error('Unhandled XObject subtype ' + type.name);
+                }
+              }
+              break;
+            case OPS.setFont:
+              var fontSize = args[1];
+              // eagerly collect all fonts
+              return self.handleSetFont(resources, args, null,
+                                        operatorList, stateManager.state).
+                then(function (loadedName) {
+                  operatorList.addDependency(loadedName);
+                  operatorList.addOp(OPS.setFont, [loadedName, fontSize]);
+                  next(resolve, reject);
+                }, reject);
+            case OPS.endInlineImage:
+              var cacheKey = args[0].cacheKey;
+              if (cacheKey && imageCache.key === cacheKey) {
+                operatorList.addOp(imageCache.fn, imageCache.args);
                 args = [];
                 continue;
-              } else {
-                error('Unhandled XObject subtype ' + type.name);
               }
-            }
-            break;
-          case OPS.setFont:
-            // eagerly collect all fonts
-            var loadedName = self.handleSetFont(resources, args, null,
-                                                operatorList,
-                                                stateManager.state);
-            operatorList.addDependency(loadedName);
-            args[0] = loadedName;
-            break;
-          case OPS.endInlineImage:
-            var cacheKey = args[0].cacheKey;
-            if (cacheKey && imageCache.key === cacheKey) {
-              operatorList.addOp(imageCache.fn, imageCache.args);
+              self.buildPaintImageXObject(resources, args[0], true,
+                operatorList, cacheKey, imageCache);
               args = [];
               continue;
-            }
-            self.buildPaintImageXObject(resources, args[0], true,
-                                        operatorList, cacheKey, imageCache);
-            args = [];
-            continue;
-          case OPS.showText:
-            args[0] = this.handleText(args[0], stateManager.state);
-            break;
-          case OPS.showSpacedText:
-            var arr = args[0];
-            var arrLength = arr.length;
-            for (i = 0; i < arrLength; ++i) {
-              if (isString(arr[i])) {
-                arr[i] = this.handleText(arr[i], stateManager.state);
+            case OPS.showText:
+              args[0] = self.handleText(args[0], stateManager.state);
+              break;
+            case OPS.showSpacedText:
+              var arr = args[0];
+              var arrLength = arr.length;
+              for (i = 0; i < arrLength; ++i) {
+                if (isString(arr[i])) {
+                  arr[i] = self.handleText(arr[i], stateManager.state);
+                }
+              }
+              break;
+            case OPS.nextLineShowText:
+              args[0] = self.handleText(args[0], stateManager.state);
+              break;
+            case OPS.nextLineSetSpacingShowText:
+              args[2] = self.handleText(args[2], stateManager.state);
+              break;
+            case OPS.setTextRenderingMode:
+              stateManager.state.textRenderingMode = args[0];
+              break;
+            // Parse the ColorSpace data to a raw format.
+            case OPS.setFillColorSpace:
+            case OPS.setStrokeColorSpace:
+              args = [ColorSpace.parseToIR(args[0], xref, resources)];
+              break;
+            case OPS.shadingFill:
+              var shadingRes = resources.get('Shading');
+              if (!shadingRes) {
+                error('No shading resource found');
               }
-            }
-            break;
-          case OPS.nextLineShowText:
-            args[0] = this.handleText(args[0], stateManager.state);
-            break;
-          case OPS.nextLineSetSpacingShowText:
-            args[2] = this.handleText(args[2], stateManager.state);
-            break;
-          case OPS.setTextRenderingMode:
-            stateManager.state.textRenderingMode = args[0];
-            break;
-          // Parse the ColorSpace data to a raw format.
-          case OPS.setFillColorSpace:
-          case OPS.setStrokeColorSpace:
-            args = [ColorSpace.parseToIR(args[0], xref, resources)];
-            break;
-          case OPS.shadingFill:
-            var shadingRes = resources.get('Shading');
-            if (!shadingRes) {
-              error('No shading resource found');
-            }
-
-            shading = shadingRes.get(args[0].name);
-            if (!shading) {
-              error('No shading object found');
-            }
 
-            var shadingFill = Pattern.parseShading(shading, null, xref,
-                                                   resources);
-            var patternIR = shadingFill.getIR();
-            args = [patternIR];
-            fn = OPS.shadingFill;
-            break;
-          case OPS.setGState:
-            var dictName = args[0];
-            var extGState = resources.get('ExtGState');
+              shading = shadingRes.get(args[0].name);
+              if (!shading) {
+                error('No shading object found');
+              }
 
-            if (!isDict(extGState) || !extGState.has(dictName.name)) {
+              var shadingFill = Pattern.parseShading(shading, null, xref,
+                resources);
+              var patternIR = shadingFill.getIR();
+              args = [patternIR];
+              fn = OPS.shadingFill;
               break;
-            }
-
-            var gState = extGState.get(dictName.name);
-            self.setGState(resources, gState, operatorList, xref,
-                           stateManager);
-            args = [];
-            continue;
-          case OPS.moveTo:
-          case OPS.lineTo:
-          case OPS.curveTo:
-          case OPS.curveTo2:
-          case OPS.curveTo3:
-          case OPS.closePath:
-            self.buildPath(operatorList, fn, args);
-            continue;
-        }
-        operatorList.addOp(fn, args);
-      }
+            case OPS.setGState:
+              var dictName = args[0];
+              var extGState = resources.get('ExtGState');
 
-      // Some PDFs don't close all restores inside object/form.
-      // Closing those for them.
-      for (i = 0, ii = preprocessor.savedStatesDepth; i < ii; i++) {
-        operatorList.addOp(OPS.restore, []);
-      }
+              if (!isDict(extGState) || !extGState.has(dictName.name)) {
+                break;
+              }
 
-      return operatorList;
+              var gState = extGState.get(dictName.name);
+              return self.setGState(resources, gState, operatorList, xref,
+                stateManager).then(function() {
+                  next(resolve, reject);
+                }, reject);
+            case OPS.moveTo:
+            case OPS.lineTo:
+            case OPS.curveTo:
+            case OPS.curveTo2:
+            case OPS.curveTo3:
+            case OPS.closePath:
+              self.buildPath(operatorList, fn, args);
+              continue;
+          }
+          operatorList.addOp(fn, args);
+        }
+        // Some PDFs don't close all restores inside object/form.
+        // Closing those for them.
+        for (i = 0, ii = preprocessor.savedStatesDepth; i < ii; i++) {
+          operatorList.addOp(OPS.restore, []);
+        }
+        resolve();
+      });
     },
 
     getTextContent: function PartialEvaluator_getTextContent(stream, resources,
@@ -767,10 +799,13 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
       }
 
       function handleSetFont(fontName, fontRef) {
-        var font = textState.font = self.loadFont(fontName, fontRef, xref,
-                                                  resources, null).translated;
-        textState.fontMatrix = font.fontMatrix ? font.fontMatrix :
-                                 FONT_IDENTITY_MATRIX;
+        return self.loadFont(fontName, fontRef, xref, resources, null).
+          then(function (font) {
+            var fontTranslated = textState.font = font.translated;
+            textState.fontMatrix = fontTranslated.fontMatrix ?
+              fontTranslated.fontMatrix :
+              FONT_IDENTITY_MATRIX;
+          });
       }
 
       function buildTextGeometry(chars, textChunk) {
@@ -865,171 +900,182 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
         return textChunk;
       }
 
-      while ((operation = preprocessor.read())) {
-        textState = stateManager.state;
-        var fn = operation.fn;
-        var args = operation.args;
-        switch (fn | 0) {
-          case OPS.setFont:
-            handleSetFont(args[0].name);
-            textState.fontSize = args[1];
-            break;
-          case OPS.setTextRise:
-            textState.textRise = args[0];
-            break;
-          case OPS.setHScale:
-            textState.textHScale = args[0] / 100;
-            break;
-          case OPS.setLeading:
-            textState.leading = args[0];
-            break;
-          case OPS.moveText:
-            textState.translateTextLineMatrix(args[0], args[1]);
-            textState.textMatrix = textState.textLineMatrix.slice();
-            break;
-          case OPS.setLeadingMoveText:
-            textState.leading = -args[1];
-            textState.translateTextLineMatrix(args[0], args[1]);
-            textState.textMatrix = textState.textLineMatrix.slice();
-            break;
-          case OPS.nextLine:
-            textState.carriageReturn();
-            break;
-          case OPS.setTextMatrix:
-            textState.setTextMatrix(args[0], args[1], args[2], args[3],
-                                    args[4], args[5]);
-            textState.setTextLineMatrix(args[0], args[1], args[2], args[3],
-                                        args[4], args[5]);
-            break;
-          case OPS.setCharSpacing:
-            textState.charSpacing = args[0];
-            break;
-          case OPS.setWordSpacing:
-            textState.wordSpacing = args[0];
-            break;
-          case OPS.beginText:
-            textState.textMatrix = IDENTITY_MATRIX.slice();
-            textState.textLineMatrix = IDENTITY_MATRIX.slice();
-            break;
-          case OPS.showSpacedText:
-            var items = args[0];
-            var textChunk = newTextChunk();
-            var offset;
-            for (var j = 0, jj = items.length; j < jj; j++) {
-              if (typeof items[j] === 'string') {
-                buildTextGeometry(items[j], textChunk);
-              } else {
-                var val = items[j] / 1000;
-                if (!textState.font.vertical) {
-                  offset = -val * textState.fontSize * textState.textHScale *
-                           textState.textMatrix[0];
-                  textState.translateTextMatrix(offset, 0);
-                  textChunk.width += offset;
+      return new Promise(function next(resolve, reject) {
+        while ((operation = preprocessor.read())) {
+          textState = stateManager.state;
+          var fn = operation.fn;
+          var args = operation.args;
+          switch (fn | 0) {
+            case OPS.setFont:
+              textState.fontSize = args[1];
+              return handleSetFont(args[0].name).then(function() {
+                next(resolve, reject);
+              }, reject);
+            case OPS.setTextRise:
+              textState.textRise = args[0];
+              break;
+            case OPS.setHScale:
+              textState.textHScale = args[0] / 100;
+              break;
+            case OPS.setLeading:
+              textState.leading = args[0];
+              break;
+            case OPS.moveText:
+              textState.translateTextLineMatrix(args[0], args[1]);
+              textState.textMatrix = textState.textLineMatrix.slice();
+              break;
+            case OPS.setLeadingMoveText:
+              textState.leading = -args[1];
+              textState.translateTextLineMatrix(args[0], args[1]);
+              textState.textMatrix = textState.textLineMatrix.slice();
+              break;
+            case OPS.nextLine:
+              textState.carriageReturn();
+              break;
+            case OPS.setTextMatrix:
+              textState.setTextMatrix(args[0], args[1], args[2], args[3],
+                args[4], args[5]);
+              textState.setTextLineMatrix(args[0], args[1], args[2], args[3],
+                args[4], args[5]);
+              break;
+            case OPS.setCharSpacing:
+              textState.charSpacing = args[0];
+              break;
+            case OPS.setWordSpacing:
+              textState.wordSpacing = args[0];
+              break;
+            case OPS.beginText:
+              textState.textMatrix = IDENTITY_MATRIX.slice();
+              textState.textLineMatrix = IDENTITY_MATRIX.slice();
+              break;
+            case OPS.showSpacedText:
+              var items = args[0];
+              var textChunk = newTextChunk();
+              var offset;
+              for (var j = 0, jj = items.length; j < jj; j++) {
+                if (typeof items[j] === 'string') {
+                  buildTextGeometry(items[j], textChunk);
                 } else {
-                  offset = -val * textState.fontSize * textState.textMatrix[3];
-                  textState.translateTextMatrix(0, offset);
-                  textChunk.height += offset;
-                }
-                if (items[j] < 0 && textState.font.spaceWidth > 0) {
-                  var fakeSpaces = -items[j] / textState.font.spaceWidth;
-                  if (fakeSpaces > MULTI_SPACE_FACTOR) {
-                    fakeSpaces = Math.round(fakeSpaces);
-                    while (fakeSpaces--) {
+                  var val = items[j] / 1000;
+                  if (!textState.font.vertical) {
+                    offset = -val * textState.fontSize * textState.textHScale *
+                      textState.textMatrix[0];
+                    textState.translateTextMatrix(offset, 0);
+                    textChunk.width += offset;
+                  } else {
+                    offset = -val * textState.fontSize *
+                      textState.textMatrix[3];
+                    textState.translateTextMatrix(0, offset);
+                    textChunk.height += offset;
+                  }
+                  if (items[j] < 0 && textState.font.spaceWidth > 0) {
+                    var fakeSpaces = -items[j] / textState.font.spaceWidth;
+                    if (fakeSpaces > MULTI_SPACE_FACTOR) {
+                      fakeSpaces = Math.round(fakeSpaces);
+                      while (fakeSpaces--) {
+                        textChunk.str += ' ';
+                      }
+                    } else if (fakeSpaces > SPACE_FACTOR) {
                       textChunk.str += ' ';
                     }
-                  } else if (fakeSpaces > SPACE_FACTOR) {
-                    textChunk.str += ' ';
                   }
                 }
               }
-            }
-            bidiTexts.push(runBidi(textChunk));
-            break;
-          case OPS.showText:
-            bidiTexts.push(runBidi(buildTextGeometry(args[0])));
-            break;
-          case OPS.nextLineShowText:
-            textState.carriageReturn();
-            bidiTexts.push(runBidi(buildTextGeometry(args[0])));
-            break;
-          case OPS.nextLineSetSpacingShowText:
-            textState.wordSpacing = args[0];
-            textState.charSpacing = args[1];
-            textState.carriageReturn();
-            bidiTexts.push(runBidi(buildTextGeometry(args[2])));
-            break;
-          case OPS.paintXObject:
-            if (args[0].code) {
+              bidiTexts.push(runBidi(textChunk));
               break;
-            }
+            case OPS.showText:
+              bidiTexts.push(runBidi(buildTextGeometry(args[0])));
+              break;
+            case OPS.nextLineShowText:
+              textState.carriageReturn();
+              bidiTexts.push(runBidi(buildTextGeometry(args[0])));
+              break;
+            case OPS.nextLineSetSpacingShowText:
+              textState.wordSpacing = args[0];
+              textState.charSpacing = args[1];
+              textState.carriageReturn();
+              bidiTexts.push(runBidi(buildTextGeometry(args[2])));
+              break;
+            case OPS.paintXObject:
+              if (args[0].code) {
+                break;
+              }
 
-            if (!xobjs) {
-              xobjs = (resources.get('XObject') || Dict.empty);
-            }
+              if (!xobjs) {
+                xobjs = (resources.get('XObject') || Dict.empty);
+              }
 
-            var name = args[0].name;
-            if (xobjsCache.key === name) {
-              if (xobjsCache.texts) {
-                Util.concatenateToArray(bidiTexts, xobjsCache.texts.items);
-                Util.extendObj(textContent.styles, xobjsCache.texts.styles);
+              var name = args[0].name;
+              if (xobjsCache.key === name) {
+                if (xobjsCache.texts) {
+                  Util.concatenateToArray(bidiTexts, xobjsCache.texts.items);
+                  Util.extendObj(textContent.styles, xobjsCache.texts.styles);
+                }
+                break;
               }
-              break;
-            }
 
-            var xobj = xobjs.get(name);
-            if (!xobj) {
-              break;
-            }
-            assert(isStream(xobj), 'XObject should be a stream');
+              var xobj = xobjs.get(name);
+              if (!xobj) {
+                break;
+              }
+              assert(isStream(xobj), 'XObject should be a stream');
 
-            var type = xobj.dict.get('Subtype');
-            assert(isName(type),
-              'XObject should have a Name subtype');
+              var type = xobj.dict.get('Subtype');
+              assert(isName(type),
+                'XObject should have a Name subtype');
 
-            if ('Form' !== type.name) {
-              xobjsCache.key = name;
-              xobjsCache.texts = null;
-              break;
-            }
+              if ('Form' !== type.name) {
+                xobjsCache.key = name;
+                xobjsCache.texts = null;
+                break;
+              }
 
-            stateManager.save();
-            var matrix = xobj.dict.get('Matrix');
-            if (isArray(matrix) && matrix.length === 6) {
-              stateManager.transform(matrix);
-            }
+              stateManager.save();
+              var matrix = xobj.dict.get('Matrix');
+              if (isArray(matrix) && matrix.length === 6) {
+                stateManager.transform(matrix);
+              }
 
-            var formTextContent = this.getTextContent(
-              xobj,
-              xobj.dict.get('Resources') || resources,
-              stateManager
-            );
-            Util.concatenateToArray(bidiTexts, formTextContent.items);
-            Util.extendObj(textContent.styles, formTextContent.styles);
-            stateManager.restore();
-
-            xobjsCache.key = name;
-            xobjsCache.texts = formTextContent;
-            break;
-          case OPS.setGState:
-            var dictName = args[0];
-            var extGState = resources.get('ExtGState');
+              return self.getTextContent(xobj,
+                xobj.dict.get('Resources') || resources, stateManager).
+                then(function (formTextContent) {
+                  Util.concatenateToArray(bidiTexts, formTextContent.items);
+                  Util.extendObj(textContent.styles, formTextContent.styles);
+                  stateManager.restore();
 
-            if (!isDict(extGState) || !extGState.has(dictName.name)) {
-              break;
-            }
+                  xobjsCache.key = name;
+                  xobjsCache.texts = formTextContent;
 
-            var gsState = extGState.get(dictName.name);
+                  next(resolve, reject);
+                }, reject);
+            case OPS.setGState:
+              var dictName = args[0];
+              var extGState = resources.get('ExtGState');
 
-            for (var i = 0; i < gsState.length; i++) {
-              if (gsState[i] === 'Font') {
-                handleSetFont(args[0].name);
+              if (!isDict(extGState) || !extGState.has(dictName.name)) {
+                break;
               }
-            }
-            break;
-        } // switch
-      } // while
 
-      return textContent;
+              var gsStateMap = extGState.get(dictName.name);
+              var gsStateFont = null;
+              for (var key in gsStateMap) {
+                if (key === 'Font') {
+                  assert(!gsStateFont);
+                  gsStateFont = gsStateMap[key];
+                }
+              }
+              if (gsStateFont) {
+                textState.fontSize = gsStateFont[1];
+                return handleSetFont(gsStateFont[0]).then(function() {
+                  next(resolve, reject);
+                }, reject);
+              }
+              break;
+          } // switch
+        } // while
+
+        resolve(textContent);
+      });
     },
 
     extractDataStructures: function
diff --git a/src/core/obj.js b/src/core/obj.js
index 9c2c77f..9a19b87 100644
--- a/src/core/obj.js
+++ b/src/core/obj.js
@@ -507,11 +507,17 @@ var Catalog = (function CatalogClosure() {
     },
 
     cleanup: function Catalog_cleanup() {
-      this.fontCache.forEach(function (font) {
-        delete font.sent;
-        delete font.translated;
+      var promises = [];
+      this.fontCache.forEach(function (promise) {
+        promises.push(promise);
       });
-      this.fontCache.clear();
+      return Promise.all(promises).then(function (fonts) {
+        for (var i = 0, ii = fonts.length; i < ii; i++) {
+          delete fonts[i].sent;
+          delete fonts[i].translated;
+        }
+        this.fontCache.clear();
+      }.bind(this));
     },
 
     getPage: function Catalog_getPage(pageIndex) {
diff --git a/src/core/worker.js b/src/core/worker.js
index 15207a7..6d9fba2 100644
--- a/src/core/worker.js
+++ b/src/core/worker.js
@@ -387,8 +387,7 @@ var WorkerMessageHandler = PDFJS.WorkerMessageHandler = {
     });
 
     handler.on('Cleanup', function wphCleanup(data) {
-      pdfManager.cleanup();
-      return true;
+      return pdfManager.cleanup();
     });
 
     handler.on('Terminate', function wphTerminate(data) {
diff --git a/src/shared/annotation.js b/src/shared/annotation.js
index af3fa9f..7e1c256 100644
--- a/src/shared/annotation.js
+++ b/src/shared/annotation.js
@@ -219,11 +219,9 @@ var Annotation = (function AnnotationClosure() {
     },
 
     getOperatorList: function Annotation_getOperatorList(evaluator) {
-      var capability = createPromiseCapability();
 
       if (!this.appearance) {
-        capability.resolve(new OperatorList());
-        return capability.promise;
+        return Promise.resolve(new OperatorList());
       }
 
       var data = this.data;
@@ -242,18 +240,18 @@ var Annotation = (function AnnotationClosure() {
       var bbox = appearanceDict.get('BBox') || [0, 0, 1, 1];
       var matrix = appearanceDict.get('Matrix') || [1, 0, 0, 1, 0 ,0];
       var transform = getTransformMatrix(data.rect, bbox, matrix);
-
-      resourcesPromise.then(function(resources) {
-        var opList = new OperatorList();
-        opList.addOp(OPS.beginAnnotation, [data.rect, transform, matrix]);
-        evaluator.getOperatorList(this.appearance, resources, opList);
-        opList.addOp(OPS.endAnnotation, []);
-        capability.resolve(opList);
-
-        this.appearance.reset();
-      }.bind(this), capability.reject);
-
-      return capability.promise;
+      var self = this;
+
+      return resourcesPromise.then(function(resources) {
+          var opList = new OperatorList();
+          opList.addOp(OPS.beginAnnotation, [data.rect, transform, matrix]);
+          return evaluator.getOperatorList(self.appearance, resources, opList).
+            then(function () {
+              opList.addOp(OPS.endAnnotation, []);
+              self.appearance.reset();
+              return opList;
+            });
+        });
     }
   };
 
@@ -512,8 +510,10 @@ var TextWidgetAnnotation = (function TextWidgetAnnotationClosure() {
       }
 
       var stream = new Stream(stringToBytes(data.defaultAppearance));
-      evaluator.getOperatorList(stream, this.fieldResources, opList);
-      return Promise.resolve(opList);
+      return evaluator.getOperatorList(stream, this.fieldResources, opList).
+        then(function () {
+          return opList;
+        });
     }
   });
 
diff --git a/test/unit/evaluator_spec.js b/test/unit/evaluator_spec.js
index 1786ceb..26c04c7 100644
--- a/test/unit/evaluator_spec.js
+++ b/test/unit/evaluator_spec.js
@@ -1,6 +1,7 @@
 /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
-/* globals expect, it, describe, PartialEvaluator, StringStream, OPS */
+/* globals expect, it, describe, PartialEvaluator, StringStream, OPS,
+           OperatorList, waitsFor, runs */
 
 'use strict';
 
@@ -30,17 +31,34 @@ describe('evaluator', function() {
 
   function PdfManagerMock() { }
 
+  function runOperatorListCheck(evaluator, stream, resources, check) {
+    var done = false;
+    runs(function () {
+      var result = new OperatorList();
+      evaluator.getOperatorList(stream, resources, result).then(function () {
+        check(result);
+        done = true;
+      });
+    });
+    waitsFor(function () {
+      return done;
+    });
+  }
+
   describe('splitCombinedOperations', function() {
     it('should reject unknown operations', function() {
       var evaluator = new PartialEvaluator(new PdfManagerMock(),
                                            new XrefMock(), new HandlerMock(),
                                            'prefix');
       var stream = new StringStream('fTT');
-      var result = evaluator.getOperatorList(stream, new ResourcesMock());
-      expect(!!result.fnArray && !!result.argsArray).toEqual(true);
-      expect(result.fnArray.length).toEqual(1);
-      expect(result.fnArray[0]).toEqual(OPS.fill);
-      expect(result.argsArray[0].length).toEqual(0);
+
+      runOperatorListCheck(evaluator, stream, new ResourcesMock(),
+          function(result) {
+        expect(!!result.fnArray && !!result.argsArray).toEqual(true);
+        expect(result.fnArray.length).toEqual(1);
+        expect(result.fnArray[0]).toEqual(OPS.fill);
+        expect(result.argsArray[0].length).toEqual(0);
+      });
     });
 
     it('should handle one operations', function() {
@@ -48,10 +66,12 @@ describe('evaluator', function() {
                                            new XrefMock(), new HandlerMock(),
                                            'prefix');
       var stream = new StringStream('Q');
-      var result = evaluator.getOperatorList(stream, new ResourcesMock());
-      expect(!!result.fnArray && !!result.argsArray).toEqual(true);
-      expect(result.fnArray.length).toEqual(1);
-      expect(result.fnArray[0]).toEqual(OPS.restore);
+      runOperatorListCheck(evaluator, stream, new ResourcesMock(),
+          function(result) {
+        expect(!!result.fnArray && !!result.argsArray).toEqual(true);
+        expect(result.fnArray.length).toEqual(1);
+        expect(result.fnArray[0]).toEqual(OPS.restore);
+      });
     });
 
     it('should handle two glued operations', function() {
@@ -61,11 +81,12 @@ describe('evaluator', function() {
       var resources = new ResourcesMock();
       resources.Res1 = {};
       var stream = new StringStream('/Res1 DoQ');
-      var result = evaluator.getOperatorList(stream, resources);
-      expect(!!result.fnArray && !!result.argsArray).toEqual(true);
-      expect(result.fnArray.length).toEqual(2);
-      expect(result.fnArray[0]).toEqual(OPS.paintXObject);
-      expect(result.fnArray[1]).toEqual(OPS.restore);
+      runOperatorListCheck(evaluator, stream, resources, function (result) {
+        expect(!!result.fnArray && !!result.argsArray).toEqual(true);
+        expect(result.fnArray.length).toEqual(2);
+        expect(result.fnArray[0]).toEqual(OPS.paintXObject);
+        expect(result.fnArray[1]).toEqual(OPS.restore);
+      });
     });
 
     it('should handle tree glued operations', function() {
@@ -73,12 +94,14 @@ describe('evaluator', function() {
                                            new XrefMock(), new HandlerMock(),
                                            'prefix');
       var stream = new StringStream('fff');
-      var result = evaluator.getOperatorList(stream, new ResourcesMock());
-      expect(!!result.fnArray && !!result.argsArray).toEqual(true);
-      expect(result.fnArray.length).toEqual(3);
-      expect(result.fnArray[0]).toEqual(OPS.fill);
-      expect(result.fnArray[1]).toEqual(OPS.fill);
-      expect(result.fnArray[2]).toEqual(OPS.fill);
+      runOperatorListCheck(evaluator, stream, new ResourcesMock(),
+          function (result) {
+        expect(!!result.fnArray && !!result.argsArray).toEqual(true);
+        expect(result.fnArray.length).toEqual(3);
+        expect(result.fnArray[0]).toEqual(OPS.fill);
+        expect(result.fnArray[1]).toEqual(OPS.fill);
+        expect(result.fnArray[2]).toEqual(OPS.fill);
+      });
     });
 
     it('should handle three glued operations #2', function() {
@@ -88,12 +111,13 @@ describe('evaluator', function() {
       var resources = new ResourcesMock();
       resources.Res1 = {};
       var stream = new StringStream('B*Bf*');
-      var result = evaluator.getOperatorList(stream, resources);
-      expect(!!result.fnArray && !!result.argsArray).toEqual(true);
-      expect(result.fnArray.length).toEqual(3);
-      expect(result.fnArray[0]).toEqual(OPS.eoFillStroke);
-      expect(result.fnArray[1]).toEqual(OPS.fillStroke);
-      expect(result.fnArray[2]).toEqual(OPS.eoFill);
+      runOperatorListCheck(evaluator, stream, resources, function (result) {
+        expect(!!result.fnArray && !!result.argsArray).toEqual(true);
+        expect(result.fnArray.length).toEqual(3);
+        expect(result.fnArray[0]).toEqual(OPS.eoFillStroke);
+        expect(result.fnArray[1]).toEqual(OPS.fillStroke);
+        expect(result.fnArray[2]).toEqual(OPS.eoFill);
+      });
     });
 
     it('should handle glued operations and operands', function() {
@@ -101,14 +125,16 @@ describe('evaluator', function() {
                                            new XrefMock(), new HandlerMock(),
                                            'prefix');
       var stream = new StringStream('f5 Ts');
-      var result  = evaluator.getOperatorList(stream, new ResourcesMock());
-      expect(!!result.fnArray && !!result.argsArray).toEqual(true);
-      expect(result.fnArray.length).toEqual(2);
-      expect(result.fnArray[0]).toEqual(OPS.fill);
-      expect(result.fnArray[1]).toEqual(OPS.setTextRise);
-      expect(result.argsArray.length).toEqual(2);
-      expect(result.argsArray[1].length).toEqual(1);
-      expect(result.argsArray[1][0]).toEqual(5);
+      runOperatorListCheck(evaluator, stream, new ResourcesMock(),
+          function (result) {
+        expect(!!result.fnArray && !!result.argsArray).toEqual(true);
+        expect(result.fnArray.length).toEqual(2);
+        expect(result.fnArray[0]).toEqual(OPS.fill);
+        expect(result.fnArray[1]).toEqual(OPS.setTextRise);
+        expect(result.argsArray.length).toEqual(2);
+        expect(result.argsArray[1].length).toEqual(1);
+        expect(result.argsArray[1][0]).toEqual(5);
+      });
     });
 
     it('should handle glued operations and literals', function() {
@@ -116,18 +142,20 @@ describe('evaluator', function() {
                                            new XrefMock(), new HandlerMock(),
                                            'prefix');
       var stream = new StringStream('trueifalserinulln');
-      var result = evaluator.getOperatorList(stream, new ResourcesMock());
-      expect(!!result.fnArray && !!result.argsArray).toEqual(true);
-      expect(result.fnArray.length).toEqual(3);
-      expect(result.fnArray[0]).toEqual(OPS.setFlatness);
-      expect(result.fnArray[1]).toEqual(OPS.setRenderingIntent);
-      expect(result.fnArray[2]).toEqual(OPS.endPath);
-      expect(result.argsArray.length).toEqual(3);
-      expect(result.argsArray[0].length).toEqual(1);
-      expect(result.argsArray[0][0]).toEqual(true);
-      expect(result.argsArray[1].length).toEqual(1);
-      expect(result.argsArray[1][0]).toEqual(false);
-      expect(result.argsArray[2].length).toEqual(0);
+      runOperatorListCheck(evaluator, stream, new ResourcesMock(),
+          function (result) {
+        expect(!!result.fnArray && !!result.argsArray).toEqual(true);
+        expect(result.fnArray.length).toEqual(3);
+        expect(result.fnArray[0]).toEqual(OPS.setFlatness);
+        expect(result.fnArray[1]).toEqual(OPS.setRenderingIntent);
+        expect(result.fnArray[2]).toEqual(OPS.endPath);
+        expect(result.argsArray.length).toEqual(3);
+        expect(result.argsArray[0].length).toEqual(1);
+        expect(result.argsArray[0][0]).toEqual(true);
+        expect(result.argsArray[1].length).toEqual(1);
+        expect(result.argsArray[1][0]).toEqual(false);
+        expect(result.argsArray[2].length).toEqual(0);
+      });
     });
   });
 
@@ -138,57 +166,67 @@ describe('evaluator', function() {
                                            'prefix');
       var stream = new StringStream('5 1 d0');
       console.log('here!');
-      var result = evaluator.getOperatorList(stream, new ResourcesMock());
-      expect(result.argsArray[0][0]).toEqual(5);
-      expect(result.argsArray[0][1]).toEqual(1);
-      expect(result.fnArray[0]).toEqual(OPS.setCharWidth);
+      runOperatorListCheck(evaluator, stream, new ResourcesMock(),
+          function (result) {
+        expect(result.argsArray[0][0]).toEqual(5);
+        expect(result.argsArray[0][1]).toEqual(1);
+        expect(result.fnArray[0]).toEqual(OPS.setCharWidth);
+      });
     });
     it('should execute if too many arguments', function() {
       var evaluator = new PartialEvaluator(new PdfManagerMock(),
                                            new XrefMock(), new HandlerMock(),
                                            'prefix');
       var stream = new StringStream('5 1 4 d0');
-      var result = evaluator.getOperatorList(stream, new ResourcesMock());
-      expect(result.argsArray[0][0]).toEqual(1);
-      expect(result.argsArray[0][1]).toEqual(4);
-      expect(result.fnArray[0]).toEqual(OPS.setCharWidth);
+      runOperatorListCheck(evaluator, stream, new ResourcesMock(),
+          function (result) {
+        expect(result.argsArray[0][0]).toEqual(1);
+        expect(result.argsArray[0][1]).toEqual(4);
+        expect(result.fnArray[0]).toEqual(OPS.setCharWidth);
+      });
     });
     it('should execute if nested commands', function() {
       var evaluator = new PartialEvaluator(new PdfManagerMock(),
                                            new XrefMock(), new HandlerMock(),
                                            'prefix');
       var stream = new StringStream('/F2 /GS2 gs 5.711 Tf');
-      var result = evaluator.getOperatorList(stream, new ResourcesMock());
-      expect(result.fnArray.length).toEqual(3);
-      expect(result.fnArray[0]).toEqual(OPS.setGState);
-      expect(result.fnArray[1]).toEqual(OPS.dependency);
-      expect(result.fnArray[2]).toEqual(OPS.setFont);
-      expect(result.argsArray.length).toEqual(3);
-      expect(result.argsArray[0].length).toEqual(1);
-      expect(result.argsArray[1].length).toEqual(1);
-      expect(result.argsArray[2].length).toEqual(2);
+      runOperatorListCheck(evaluator, stream, new ResourcesMock(),
+          function (result) {
+        expect(result.fnArray.length).toEqual(3);
+        expect(result.fnArray[0]).toEqual(OPS.setGState);
+        expect(result.fnArray[1]).toEqual(OPS.dependency);
+        expect(result.fnArray[2]).toEqual(OPS.setFont);
+        expect(result.argsArray.length).toEqual(3);
+        expect(result.argsArray[0].length).toEqual(1);
+        expect(result.argsArray[1].length).toEqual(1);
+        expect(result.argsArray[2].length).toEqual(2);
+      });
     });
     it('should skip if too few arguments', function() {
       var evaluator = new PartialEvaluator(new PdfManagerMock(),
                                            new XrefMock(), new HandlerMock(),
                                            'prefix');
       var stream = new StringStream('5 d0');
-      var result = evaluator.getOperatorList(stream, new ResourcesMock());
-      expect(result.argsArray).toEqual([]);
-      expect(result.fnArray).toEqual([]);
+      runOperatorListCheck(evaluator, stream, new ResourcesMock(),
+          function (result) {
+        expect(result.argsArray).toEqual([]);
+        expect(result.fnArray).toEqual([]);
+      });
     });
     it('should close opened saves', function() {
       var evaluator = new PartialEvaluator(new PdfManagerMock(),
         new XrefMock(), new HandlerMock(),
         'prefix');
       var stream = new StringStream('qq');
-      var result = evaluator.getOperatorList(stream, new ResourcesMock());
-      expect(!!result.fnArray && !!result.argsArray).toEqual(true);
-      expect(result.fnArray.length).toEqual(4);
-      expect(result.fnArray[0]).toEqual(OPS.save);
-      expect(result.fnArray[1]).toEqual(OPS.save);
-      expect(result.fnArray[2]).toEqual(OPS.restore);
-      expect(result.fnArray[3]).toEqual(OPS.restore);
+      runOperatorListCheck(evaluator, stream, new ResourcesMock(),
+          function (result) {
+        expect(!!result.fnArray && !!result.argsArray).toEqual(true);
+        expect(result.fnArray.length).toEqual(4);
+        expect(result.fnArray[0]).toEqual(OPS.save);
+        expect(result.fnArray[1]).toEqual(OPS.save);
+        expect(result.fnArray[2]).toEqual(OPS.restore);
+        expect(result.fnArray[3]).toEqual(OPS.restore);
+      });
     });
   });
 });

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/pdf.js.git



More information about the Pkg-javascript-commits mailing list