From 6acdf1791cdb8775024db1d7e6b87181fc9cbf83 Mon Sep 17 00:00:00 2001 From: Dmitry Kataev Date: Wed, 9 May 2012 21:29:50 +0400 Subject: [PATCH 1/2] Two or more operations can be combined together like qqBT --- src/evaluator.js | 44 +++++++++++++++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/src/evaluator.js b/src/evaluator.js index 23c9d1f65..ae443fa81 100644 --- a/src/evaluator.js +++ b/src/evaluator.js @@ -112,14 +112,33 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { }; function splitCombinedOperations(operations) { - // Two operations can be combined together, trying to find which two + // Two or more operations can be combined together, trying to find which // operations were concatenated. - for (var i = operations.length - 1; i > 0; i--) { - var op1 = operations.substring(0, i), op2 = operations.substring(i); - if (op1 in OP_MAP && op2 in OP_MAP) - return [op1, op2]; // operations found + var result = []; + var opIndex = 0; + + if (!operations) { + return null; } - 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; + } + } + + return result; } PartialEvaluator.prototype = { @@ -267,14 +286,14 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { var patterns = resources.get('Pattern') || new Dict(); var parser = new Parser(new Lexer(stream), false, xref); var res = resources; - var hasNextObj = false, nextObj; + var hasNextObj = false, nextObjs; var args = [], obj; var TILING_PATTERN = 1, SHADING_PATTERN = 2; while (true) { if (hasNextObj) { - obj = nextObj; - hasNextObj = false; + obj = nextObjs.pop(); + hasNextObj = (nextObjs.length > 0); } else { obj = parser.getObj(); if (isEOF(obj)) @@ -290,9 +309,12 @@ var PartialEvaluator = (function PartialEvaluatorClosure() { if (cmds) { cmd = cmds[0]; fn = OP_MAP[cmd]; - // feeding other command on the next interation + // feeding other command on the next iteration hasNextObj = true; - nextObj = Cmd.get(cmds[1]); + nextObjs = []; + for (var idx = 1; idx < cmds.length; idx++) { + nextObjs.push(Cmd.get(cmds[idx])); + } } } assertWellFormed(fn, 'Unknown command "' + cmd + '"'); From 324b867183f3c9b6cff15129644570b1d7047209 Mon Sep 17 00:00:00 2001 From: Yury Delendik Date: Thu, 10 May 2012 16:11:27 -0500 Subject: [PATCH 2/2] Adds evaluator tests --- test/unit/evaluator_spec.js | 83 +++++++++++++++++++++++++++++++++++++ test/unit/unit_test.html | 1 + 2 files changed, 84 insertions(+) create mode 100644 test/unit/evaluator_spec.js diff --git a/test/unit/evaluator_spec.js b/test/unit/evaluator_spec.js new file mode 100644 index 000000000..4ee0768a7 --- /dev/null +++ b/test/unit/evaluator_spec.js @@ -0,0 +1,83 @@ +/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */ + +'use strict'; + +describe('evaluator', function() { + function XrefMock(queue) { + this.queue = queue; + } + XrefMock.prototype = { + fetchIfRef: function() { + return this.queue.shift(); + } + }; + function HandlerMock() { + this.inputs = []; + } + HandlerMock.prototype = { + send: function(name, data) { + this.inputs({name: name, data: data}); + } + }; + function ResourcesMock() { } + ResourcesMock.prototype = { + get: function(name) { + return this[name]; + } + }; + + describe('splitCombinedOperations', function() { + it('should reject unknown operations', function() { + var evaluator = new PartialEvaluator(new XrefMock(), new HandlerMock(), + 'prefix'); + var stream = new StringStream('qTT'); + var thrown = false; + try { + evaluator.getOperatorList(stream, new ResourcesMock(), []); + } catch (e) { + thrown = e; + } + expect(thrown).toNotEqual(false); + }); + + it('should handle one operations', function() { + var evaluator = new PartialEvaluator(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('restore'); + }); + + it('should handle two glued operations', function() { + var evaluator = new PartialEvaluator(new XrefMock(), new HandlerMock(), + 'prefix'); + 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('paintXObject'); + expect(result.fnArray[1]).toEqual('restore'); + }); + + it('should handle tree glued operations', function() { + var evaluator = new PartialEvaluator(new XrefMock(), new HandlerMock(), + 'prefix'); + var stream = new StringStream('qqq'); + 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('save'); + expect(result.fnArray[1]).toEqual('save'); + expect(result.fnArray[2]).toEqual('save'); + }); + }); +}); + diff --git a/test/unit/unit_test.html b/test/unit/unit_test.html index cdd0c297f..ca0a1aed1 100644 --- a/test/unit/unit_test.html +++ b/test/unit/unit_test.html @@ -39,6 +39,7 @@ +