]> git.parisson.com Git - pdf.js.git/commitdiff
Allow parsing of the "glued" commands
authorYury Delendik <ydelendik@mozilla.com>
Sun, 20 May 2012 18:44:03 +0000 (13:44 -0500)
committerYury Delendik <ydelendik@mozilla.com>
Sun, 20 May 2012 18:44:03 +0000 (13:44 -0500)
src/evaluator.js
src/parser.js
test/unit/evaluator_spec.js

index ae443fa81d3cdb473d04ae854121abf51426473f..2c07db88cfe1f92d37ec174f172ac41c56c4116f 100644 (file)
@@ -108,38 +108,12 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
 
     // Compatibility
     BX: 'beginCompat',
-    EX: 'endCompat'
-  };
-
-  function splitCombinedOperations(operations) {
-    // Two or more operations can be combined together, trying to find which
-    // operations were concatenated.
-    var result = [];
-    var opIndex = 0;
-
-    if (!operations) {
-      return null;
-    }
-
-    while (opIndex < operations.length) {
-      var currentOp = '';
-      for (var op in OP_MAP) {
-        if (op == operations.substr(opIndex, op.length) &&
-            op.length > currentOp.length) {
-          currentOp = op;
-        }
-      }
-
-      if (currentOp.length > 0) {
-        result.push(operations.substr(opIndex, currentOp.length));
-        opIndex += currentOp.length;
-      } else {
-        return null;
-      }
-    }
+    EX: 'endCompat',
 
-    return result;
-  }
+    // (reserved partial commands for the lexer)
+    BM: null,
+    BD: null
+  };
 
   PartialEvaluator.prototype = {
     getOperatorList: function PartialEvaluator_getOperatorList(stream,
@@ -284,39 +258,19 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
       resources = resources || new Dict();
       var xobjs = resources.get('XObject') || new Dict();
       var patterns = resources.get('Pattern') || new Dict();
-      var parser = new Parser(new Lexer(stream), false, xref);
+      var parser = new Parser(new Lexer(stream, OP_MAP), false, xref);
       var res = resources;
-      var hasNextObj = false, nextObjs;
       var args = [], obj;
       var TILING_PATTERN = 1, SHADING_PATTERN = 2;
 
       while (true) {
-        if (hasNextObj) {
-          obj = nextObjs.pop();
-          hasNextObj = (nextObjs.length > 0);
-        } else {
-          obj = parser.getObj();
-          if (isEOF(obj))
-            break;
-        }
+        obj = parser.getObj();
+        if (isEOF(obj))
+          break;
 
         if (isCmd(obj)) {
           var cmd = obj.cmd;
           var fn = OP_MAP[cmd];
-          if (!fn) {
-            // invalid content command, trying to recover
-            var cmds = splitCombinedOperations(cmd);
-            if (cmds) {
-              cmd = cmds[0];
-              fn = OP_MAP[cmd];
-              // feeding other command on the next iteration
-              hasNextObj = true;
-              nextObjs = [];
-              for (var idx = 1; idx < cmds.length; idx++) {
-                 nextObjs.push(Cmd.get(cmds[idx]));
-              }
-            }
-          }
           assertWellFormed(fn, 'Unknown command "' + cmd + '"');
           // TODO figure out how to type-check vararg functions
 
index 2855018a612d488dfdd83c750752e3144d2e7819..3a2218f0d5d2f0c7a2178cbe75de3dc75350120a 100644 (file)
@@ -264,8 +264,9 @@ var Parser = (function ParserClosure() {
 })();
 
 var Lexer = (function LexerClosure() {
-  function Lexer(stream) {
+  function Lexer(stream, knownCommands) {
     this.stream = stream;
+    this.knownCommands = knownCommands;
   }
 
   Lexer.isSpace = function Lexer_isSpace(ch) {
@@ -529,12 +530,18 @@ var Lexer = (function LexerClosure() {
 
       // command
       var str = ch;
+      var knownCommands = this.knownCommands;
+      var knownCommandFound = knownCommands && (str in knownCommands);
       while (!!(ch = stream.lookChar()) && !specialChars[ch.charCodeAt(0)]) {
+        // stop if known command is found and next character does not make
+        // the str a command
+        if (knownCommandFound && !((str + ch) in knownCommands))
+          break;
         stream.skip();
         if (str.length == 128)
           error('Command token too long: ' + str.length);
-
         str += ch;
+        knownCommandFound = knownCommands && (str in knownCommands);
       }
       if (str == 'true')
         return true;
index 4ee0768a747d4a0a3738e93ee55ca6e2d0fc459e..286b8158add5a12cf2420d753f17db078d4a3067 100644 (file)
@@ -78,6 +78,36 @@ describe('evaluator', function() {
       expect(result.fnArray[1]).toEqual('save');
       expect(result.fnArray[2]).toEqual('save');
     });
+
+    it('should handle three glued operations #2', function() {
+      var evaluator = new PartialEvaluator(new XrefMock(), new HandlerMock(),
+                                           'prefix');
+      var resources = new ResourcesMock();
+      resources.Res1 = {};
+      var stream = new StringStream('B*BBMC');
+      var result = evaluator.getOperatorList(stream, resources, []);
+
+      expect(!!result.fnArray && !!result.argsArray).toEqual(true);
+      expect(result.fnArray.length).toEqual(3);
+      expect(result.fnArray[0]).toEqual('eoFillStroke');
+      expect(result.fnArray[1]).toEqual('fillStroke');
+      expect(result.fnArray[2]).toEqual('beginMarkedContent');
+    });
+
+    it('should handle glued operations and operands', function() {
+      var evaluator = new PartialEvaluator(new XrefMock(), new HandlerMock(),
+                                           'prefix');
+      var stream = new StringStream('q5 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('save');
+      expect(result.fnArray[1]).toEqual('setTextRise');
+      expect(result.argsArray.length).toEqual(2);
+      expect(result.argsArray[1].length).toEqual(1);
+      expect(result.argsArray[1][0]).toEqual(5);
+    });
   });
 });