Skip commands that have too few arguments
- Commands that have too few args will be skipped - Commands that have too many args will generate an info, but still execute
This commit is contained in:
parent
4fa82683fa
commit
5ab3bb1e03
194
src/evaluator.js
194
src/evaluator.js
@ -30,101 +30,104 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
this.fontIdCounter = 0;
|
this.fontIdCounter = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Specifies properties for each command
|
||||||
|
//
|
||||||
|
// If variableArgs === true: [0, `numArgs`] expected
|
||||||
|
// If variableArgs === false: exactly `numArgs` expected
|
||||||
var OP_MAP = {
|
var OP_MAP = {
|
||||||
// Graphics state
|
// Graphic state
|
||||||
w: 'setLineWidth',
|
w: { fnName: 'setLineWidth', numArgs: 1, variableArgs: false },
|
||||||
J: 'setLineCap',
|
J: { fnName: 'setLineCap', numArgs: 1, variableArgs: false },
|
||||||
j: 'setLineJoin',
|
j: { fnName: 'setLineJoin', numArgs: 1, variableArgs: false },
|
||||||
M: 'setMiterLimit',
|
M: { fnName: 'setMiterLimit', numArgs: 1, variableArgs: false },
|
||||||
d: 'setDash',
|
d: { fnName: 'setDash', numArgs: 2, variableArgs: false },
|
||||||
ri: 'setRenderingIntent',
|
ri: { fnName: 'setRenderingIntent', numArgs: 1, variableArgs: false },
|
||||||
i: 'setFlatness',
|
i: { fnName: 'setFlatness', numArgs: 1, variableArgs: false },
|
||||||
gs: 'setGState',
|
gs: { fnName: 'setGState', numArgs: 1, variableArgs: false },
|
||||||
q: 'save',
|
q: { fnName: 'save', numArgs: 0, variableArgs: false },
|
||||||
Q: 'restore',
|
Q: { fnName: 'restore', numArgs: 0, variableArgs: false },
|
||||||
cm: 'transform',
|
cm: { fnName: 'transform', numArgs: 6, variableArgs: false },
|
||||||
|
|
||||||
// Path
|
// Path
|
||||||
m: 'moveTo',
|
m: { fnName: 'moveTo', numArgs: 2, variableArgs: false },
|
||||||
l: 'lineTo',
|
l: { fnName: 'lineTo', numArgs: 2, variableArgs: false },
|
||||||
c: 'curveTo',
|
c: { fnName: 'curveTo', numArgs: 6, variableArgs: false },
|
||||||
v: 'curveTo2',
|
v: { fnName: 'curveTo2', numArgs: 4, variableArgs: false },
|
||||||
y: 'curveTo3',
|
y: { fnName: 'curveTo3', numArgs: 4, variableArgs: false },
|
||||||
h: 'closePath',
|
h: { fnName: 'closePath', numArgs: 0, variableArgs: false },
|
||||||
re: 'rectangle',
|
re: { fnName: 'rectangle', numArgs: 4, variableArgs: false },
|
||||||
S: 'stroke',
|
S: { fnName: 'stroke', numArgs: 0, variableArgs: false },
|
||||||
s: 'closeStroke',
|
s: { fnName: 'closeStroke', numArgs: 0, variableArgs: false },
|
||||||
f: 'fill',
|
f: { fnName: 'fill', numArgs: 0, variableArgs: false },
|
||||||
F: 'fill',
|
F: { fnName: 'fill', numArgs: 0, variableArgs: false },
|
||||||
'f*': 'eoFill',
|
'f*': { fnName: 'eoFill', numArgs: 0, variableArgs: false },
|
||||||
B: 'fillStroke',
|
B: { fnName: 'fillStroke', numArgs: 0, variableArgs: false },
|
||||||
'B*': 'eoFillStroke',
|
'B*': { fnName: 'eoFillStroke', numArgs: 0, variableArgs: false },
|
||||||
b: 'closeFillStroke',
|
b: { fnName: 'closeFillStroke', numArgs: 0, variableArgs: false },
|
||||||
'b*': 'closeEOFillStroke',
|
'b*': { fnName: 'closeEOFillStroke', numArgs: 0, variableArgs: false },
|
||||||
n: 'endPath',
|
n: { fnName: 'endPath', numArgs: 0, variableArgs: false },
|
||||||
|
|
||||||
// Clipping
|
// Clipping
|
||||||
W: 'clip',
|
W: { fnName: 'clip', numArgs: 0, variableArgs: false },
|
||||||
'W*': 'eoClip',
|
'W*': { fnName: 'eoClip', numArgs: 0, variableArgs: false },
|
||||||
|
|
||||||
// Text
|
// Text
|
||||||
BT: 'beginText',
|
BT: { fnName: 'beginText', numArgs: 0, variableArgs: false },
|
||||||
ET: 'endText',
|
ET: { fnName: 'endText', numArgs: 0, variableArgs: false },
|
||||||
Tc: 'setCharSpacing',
|
Tc: { fnName: 'setCharSpacing', numArgs: 1, variableArgs: false },
|
||||||
Tw: 'setWordSpacing',
|
Tw: { fnName: 'setWordSpacing', numArgs: 1, variableArgs: false },
|
||||||
Tz: 'setHScale',
|
Tz: { fnName: 'setHScale', numArgs: 1, variableArgs: false },
|
||||||
TL: 'setLeading',
|
TL: { fnName: 'setLeading', numArgs: 1, variableArgs: false },
|
||||||
Tf: 'setFont',
|
Tf: { fnName: 'setFont', numArgs: 2, variableArgs: false },
|
||||||
Tr: 'setTextRenderingMode',
|
Tr: { fnName: 'setTextRenderingMode', numArgs: 1, variableArgs: false },
|
||||||
Ts: 'setTextRise',
|
Ts: { fnName: 'setTextRise', numArgs: 1, variableArgs: false },
|
||||||
Td: 'moveText',
|
Td: { fnName: 'moveText', numArgs: 2, variableArgs: false },
|
||||||
TD: 'setLeadingMoveText',
|
TD: { fnName: 'setLeadingMoveText', numArgs: 2, variableArgs: false },
|
||||||
Tm: 'setTextMatrix',
|
Tm: { fnName: 'setTextMatrix', numArgs: 6, variableArgs: false },
|
||||||
'T*': 'nextLine',
|
'T*': { fnName: 'nextLine', numArgs: 0, variableArgs: false },
|
||||||
Tj: 'showText',
|
Tj: { fnName: 'showText', numArgs: 1, variableArgs: false },
|
||||||
TJ: 'showSpacedText',
|
TJ: { fnName: 'showSpacedText', numArgs: 1, variableArgs: false },
|
||||||
"'": 'nextLineShowText',
|
'\'': { fnName: 'nextLineShowText', numArgs: 1, variableArgs: false },
|
||||||
'"': 'nextLineSetSpacingShowText',
|
'"': { fnName: 'nextLineSetSpacingShowText', numArgs: 3,
|
||||||
|
variableArgs: false },
|
||||||
|
|
||||||
// Type3 fonts
|
// Type3 fonts
|
||||||
d0: 'setCharWidth',
|
d0: { fnName: 'setCharWidth', numArgs: 2, variableArgs: false },
|
||||||
d1: 'setCharWidthAndBounds',
|
d1: { fnName: 'setCharWidthAndBounds', numArgs: 6, variableArgs: false },
|
||||||
|
|
||||||
// Color
|
// Color
|
||||||
CS: 'setStrokeColorSpace',
|
CS: { fnName: 'setStrokeColorSpace', numArgs: 1, variableArgs: false },
|
||||||
cs: 'setFillColorSpace',
|
cs: { fnName: 'setFillColorSpace', numArgs: 1, variableArgs: false },
|
||||||
SC: 'setStrokeColor',
|
SC: { fnName: 'setStrokeColor', numArgs: 4, variableArgs: true },
|
||||||
SCN: 'setStrokeColorN',
|
SCN: { fnName: 'setStrokeColorN', numArgs: 33, variableArgs: true },
|
||||||
sc: 'setFillColor',
|
sc: { fnName: 'setFillColor', numArgs: 4, variableArgs: true },
|
||||||
scn: 'setFillColorN',
|
scn: { fnName: 'setFillColorN', numArgs: 33, variableArgs: true },
|
||||||
G: 'setStrokeGray',
|
G: { fnName: 'setStrokeGray', numArgs: 1, variableArgs: false },
|
||||||
g: 'setFillGray',
|
g: { fnName: 'setFillGray', numArgs: 1, variableArgs: false },
|
||||||
RG: 'setStrokeRGBColor',
|
RG: { fnName: 'setStrokeRGBColor', numArgs: 3, variableArgs: false },
|
||||||
rg: 'setFillRGBColor',
|
rg: { fnName: 'setFillRGBColor', numArgs: 3, variableArgs: false },
|
||||||
K: 'setStrokeCMYKColor',
|
K: { fnName: 'setStrokeCMYKColor', numArgs: 4, variableArgs: false },
|
||||||
k: 'setFillCMYKColor',
|
k: { fnName: 'setFillCMYKColor', numArgs: 4, variableArgs: false },
|
||||||
|
|
||||||
// Shading
|
// Shading
|
||||||
sh: 'shadingFill',
|
sh: { fnName: 'shadingFill', numArgs: 1, variableArgs: false },
|
||||||
|
|
||||||
// Images
|
// Images
|
||||||
BI: 'beginInlineImage',
|
BI: { fnName: 'beginInlineImage', numArgs: 0, variableArgs: false },
|
||||||
ID: 'beginImageData',
|
ID: { fnName: 'beginImageData', numArgs: 0, variableArgs: false },
|
||||||
EI: 'endInlineImage',
|
EI: { fnName: 'endInlineImage', numArgs: 0, variableArgs: false },
|
||||||
|
|
||||||
// XObjects
|
// XObjects
|
||||||
Do: 'paintXObject',
|
Do: { fnName: 'paintXObject', numArgs: 1, variableArgs: false },
|
||||||
|
MP: { fnName: 'markPoint', numArgs: 1, variableArgs: false },
|
||||||
// Marked content
|
DP: { fnName: 'markPointProps', numArgs: 2, variableArgs: false },
|
||||||
MP: 'markPoint',
|
BMC: { fnName: 'beginMarkedContent', numArgs: 1, variableArgs: false },
|
||||||
DP: 'markPointProps',
|
BDC: { fnName: 'beginMarkedContentProps', numArgs: 2, variableArgs: false },
|
||||||
BMC: 'beginMarkedContent',
|
EMC: { fnName: 'endMarkedContent', numArgs: 0, variableArgs: false },
|
||||||
BDC: 'beginMarkedContentProps',
|
|
||||||
EMC: 'endMarkedContent',
|
|
||||||
|
|
||||||
// Compatibility
|
// Compatibility
|
||||||
BX: 'beginCompat',
|
BX: { fnName: 'beginCompat', numArgs: 0, variableArgs: false },
|
||||||
EX: 'endCompat',
|
EX: { fnName: 'endCompat', numArgs: 0, variableArgs: false },
|
||||||
|
|
||||||
// (reserved partial commands for the lexer)
|
// (reserved partial commands for the lexer)
|
||||||
BM: null,
|
BM: null,
|
||||||
@ -314,6 +317,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
resources = resources || new Dict();
|
resources = resources || new Dict();
|
||||||
var xobjs = resources.get('XObject') || new Dict();
|
var xobjs = resources.get('XObject') || new Dict();
|
||||||
var patterns = resources.get('Pattern') || new Dict();
|
var patterns = resources.get('Pattern') || new Dict();
|
||||||
|
// TODO(mduan): pass array of knownCommands rather than OP_MAP
|
||||||
|
// dictionary
|
||||||
var parser = new Parser(new Lexer(stream, OP_MAP), false, xref);
|
var parser = new Parser(new Lexer(stream, OP_MAP), false, xref);
|
||||||
var res = resources;
|
var res = resources;
|
||||||
var args = [], obj;
|
var args = [], obj;
|
||||||
@ -321,13 +326,42 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
obj = parser.getObj();
|
obj = parser.getObj();
|
||||||
if (isEOF(obj))
|
if (isEOF(obj)) {
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (isCmd(obj)) {
|
if (isCmd(obj)) {
|
||||||
var cmd = obj.cmd;
|
var cmd = obj.cmd;
|
||||||
var fn = OP_MAP[cmd];
|
|
||||||
assertWellFormed(fn, 'Unknown command "' + cmd + '"');
|
// Check that the command is valid
|
||||||
|
var opSpec = OP_MAP[cmd];
|
||||||
|
if (!opSpec) {
|
||||||
|
warn('Unknown command "' + cmd + '"');
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
var fn = opSpec.fnName;
|
||||||
|
|
||||||
|
// Validate the number of arguments for the command
|
||||||
|
if (opSpec.variableArgs) {
|
||||||
|
if (args.length > opSpec.numArgs) {
|
||||||
|
info('Command ' + fn + ': expected [0,' + opSpec.numArgs +
|
||||||
|
'] args, but received ' + args.length + ' args');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (args.length < opSpec.numArgs) {
|
||||||
|
// If we receive too few args, it's not possible to possible
|
||||||
|
// to execute the command, so skip the command
|
||||||
|
info('Command ' + fn + ': because expected ' + opSpec.numArgs +
|
||||||
|
' args, but received ' + args.length + ' args; skipping');
|
||||||
|
args = [];
|
||||||
|
continue;
|
||||||
|
} else if (args.length > opSpec.numArgs) {
|
||||||
|
info('Command ' + fn + ': expected ' + opSpec.numArgs +
|
||||||
|
' args, but received ' + args.length + ' args');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// TODO figure out how to type-check vararg functions
|
// TODO figure out how to type-check vararg functions
|
||||||
|
|
||||||
if ((cmd == 'SCN' || cmd == 'scn') && !args[args.length - 1].code) {
|
if ((cmd == 'SCN' || cmd == 'scn') && !args[args.length - 1].code) {
|
||||||
@ -509,8 +543,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
argsArray.push(args);
|
argsArray.push(args);
|
||||||
args = [];
|
args = [];
|
||||||
} else if (obj != null) {
|
} else if (obj != null) {
|
||||||
assertWellFormed(args.length <= 33, 'Too many arguments');
|
|
||||||
args.push(obj instanceof Dict ? obj.getAll() : obj);
|
args.push(obj instanceof Dict ? obj.getAll() : obj);
|
||||||
|
assertWellFormed(args.length <= 33, 'Too many arguments');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -1,6 +1,7 @@
|
|||||||
*.pdf
|
*.pdf
|
||||||
|
|
||||||
!tracemonkey.pdf
|
!tracemonkey.pdf
|
||||||
|
!issue2391-1.pdf
|
||||||
!ArabicCIDTrueType.pdf
|
!ArabicCIDTrueType.pdf
|
||||||
!ThuluthFeatures.pdf
|
!ThuluthFeatures.pdf
|
||||||
!arial_unicode_ab_cidfont.pdf
|
!arial_unicode_ab_cidfont.pdf
|
||||||
|
131
test/pdfs/issue2391-1.pdf
Normal file
131
test/pdfs/issue2391-1.pdf
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
%PDF-1.4
|
||||||
|
%âãÏÓ
|
||||||
|
1 0 obj
|
||||||
|
<<
|
||||||
|
/Pages 2 0 R
|
||||||
|
/Metadata 3 0 R
|
||||||
|
/Type /Catalog
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
2 0 obj
|
||||||
|
<<
|
||||||
|
/Kids [4 0 R]
|
||||||
|
/Count 1
|
||||||
|
/Type /Pages
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
4 0 obj
|
||||||
|
<<
|
||||||
|
/Rotate 0
|
||||||
|
/Parent 2 0 R
|
||||||
|
/Resources
|
||||||
|
<<
|
||||||
|
/ExtGState 5 0 R
|
||||||
|
/Font 6 0 R
|
||||||
|
/ProcSet [/PDF /Text]
|
||||||
|
>>
|
||||||
|
/MediaBox [0 0 595 842]
|
||||||
|
/Contents 7 0 R
|
||||||
|
/Type /Page
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
7 0 obj
|
||||||
|
<<
|
||||||
|
/Length 148
|
||||||
|
>>
|
||||||
|
stream
|
||||||
|
q 0.1 0 0 0.1 0 0 cm
|
||||||
|
/R7 gs
|
||||||
|
0 g
|
||||||
|
q
|
||||||
|
10 0 0 10 0 0 cm BT
|
||||||
|
undefined 10 Tf
|
||||||
|
/R8 10 Tf
|
||||||
|
1 0 0 1 29 805 Tm
|
||||||
|
(test command with wrong number of args)Tj
|
||||||
|
ET
|
||||||
|
Q
|
||||||
|
Q
|
||||||
|
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
8 0 obj
|
||||||
|
<<
|
||||||
|
/Type /ExtGState
|
||||||
|
/OPM 1
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
9 0 obj
|
||||||
|
<<
|
||||||
|
/BaseFont /Courier
|
||||||
|
/Subtype /Type1
|
||||||
|
/Type /Font
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
5 0 obj
|
||||||
|
<<
|
||||||
|
/R7 8 0 R
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
6 0 obj
|
||||||
|
<<
|
||||||
|
/R8 9 0 R
|
||||||
|
>>
|
||||||
|
endobj
|
||||||
|
3 0 obj
|
||||||
|
<<
|
||||||
|
/Subtype /XML
|
||||||
|
/Length 1421
|
||||||
|
/Type /Metadata
|
||||||
|
>>
|
||||||
|
stream
|
||||||
|
<?xpacket begin='' id='W5M0MpCehiHzreSzNTczkc9d'?>
|
||||||
|
<?adobe-xap-filters esc="CRLF"?>
|
||||||
|
<x:xmpmeta xmlns:x='adobe:ns:meta/' x:xmptk='XMP toolkit 2.9.1-13, framework 1.6'>
|
||||||
|
<rdf:RDF xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:iX='http://ns.adobe.com/iX/1.0/'>
|
||||||
|
<rdf:Description rdf:about='uuid:39048ebf-93ad-11ed-0000-3d9120169d5e' xmlns:pdf='http://ns.adobe.com/pdf/1.3/' pdf:Producer='GPL Ghostscript 9.05'/>
|
||||||
|
<rdf:Description rdf:about='uuid:39048ebf-93ad-11ed-0000-3d9120169d5e' xmlns:xmp='http://ns.adobe.com/xap/1.0/'><xmp:ModifyDate>2013-01-10T17:46:10-08:00</xmp:ModifyDate>
|
||||||
|
<xmp:CreateDate>2013-01-10T17:46:10-08:00</xmp:CreateDate>
|
||||||
|
<xmp:CreatorTool>GNU Enscript 1.6.6</xmp:CreatorTool></rdf:Description>
|
||||||
|
<rdf:Description rdf:about='uuid:39048ebf-93ad-11ed-0000-3d9120169d5e' xmlns:xapMM='http://ns.adobe.com/xap/1.0/mm/' xapMM:DocumentID='uuid:39048ebf-93ad-11ed-0000-3d9120169d5e'/>
|
||||||
|
<rdf:Description rdf:about='uuid:39048ebf-93ad-11ed-0000-3d9120169d5e' xmlns:dc='http://purl.org/dc/elements/1.1/' dc:format='application/pdf'><dc:title><rdf:Alt><rdf:li xml:lang='x-default'>Enscript Output</rdf:li></rdf:Alt></dc:title><dc:creator><rdf:Seq><rdf:li>Mack Duan</rdf:li></rdf:Seq></dc:creator></rdf:Description>
|
||||||
|
</rdf:RDF>
|
||||||
|
</x:xmpmeta>
|
||||||
|
|
||||||
|
|
||||||
|
<?xpacket end='w'?>
|
||||||
|
endstream
|
||||||
|
endobj
|
||||||
|
10 0 obj
|
||||||
|
<<
|
||||||
|
/Creator (GNU Enscript 1.6.6)
|
||||||
|
/Title (Enscript Output)
|
||||||
|
/Producer (GPL Ghostscript 9.05)
|
||||||
|
/Author (Mack Duan)
|
||||||
|
/ModDate (D:20130110174610-08'00')
|
||||||
|
/CreationDate (D:20130110174610-08'00')
|
||||||
|
>>
|
||||||
|
endobj xref
|
||||||
|
0 11
|
||||||
|
0000000000 65535 f
|
||||||
|
0000000015 00000 n
|
||||||
|
0000000082 00000 n
|
||||||
|
0000000694 00000 n
|
||||||
|
0000000141 00000 n
|
||||||
|
0000000628 00000 n
|
||||||
|
0000000661 00000 n
|
||||||
|
0000000309 00000 n
|
||||||
|
0000000511 00000 n
|
||||||
|
0000000558 00000 n
|
||||||
|
0000002200 00000 n
|
||||||
|
trailer
|
||||||
|
|
||||||
|
<<
|
||||||
|
/Info 10 0 R
|
||||||
|
/Root 1 0 R
|
||||||
|
/Size 11
|
||||||
|
/ID [<5807376a23851d4cc6096009432892a3> <5807376a23851d4cc6096009432892a3>]
|
||||||
|
>>
|
||||||
|
startxref
|
||||||
|
2406
|
||||||
|
%%EOF
|
@ -17,6 +17,13 @@
|
|||||||
"rounds": 1,
|
"rounds": 1,
|
||||||
"type": "text"
|
"type": "text"
|
||||||
},
|
},
|
||||||
|
{ "id": "issue2391-1",
|
||||||
|
"file": "pdfs/issue2391-1.pdf",
|
||||||
|
"md5": "25ae9cb959612e7b343b55da63af2716",
|
||||||
|
"rounds": 1,
|
||||||
|
"pageLimit": 1,
|
||||||
|
"type": "load"
|
||||||
|
},
|
||||||
{ "id": "html5-canvas-cheat-sheet-load",
|
{ "id": "html5-canvas-cheat-sheet-load",
|
||||||
"file": "pdfs/canvas.pdf",
|
"file": "pdfs/canvas.pdf",
|
||||||
"md5": "59510028561daf62e00bf9f6f066b033",
|
"md5": "59510028561daf62e00bf9f6f066b033",
|
||||||
|
@ -32,13 +32,12 @@ describe('evaluator', function() {
|
|||||||
var evaluator = new PartialEvaluator(new XrefMock(), new HandlerMock(),
|
var evaluator = new PartialEvaluator(new XrefMock(), new HandlerMock(),
|
||||||
'prefix');
|
'prefix');
|
||||||
var stream = new StringStream('qTT');
|
var stream = new StringStream('qTT');
|
||||||
var thrown = false;
|
var result = evaluator.getOperatorList(stream, new ResourcesMock(), []);
|
||||||
try {
|
|
||||||
evaluator.getOperatorList(stream, new ResourcesMock(), []);
|
expect(!!result.fnArray && !!result.argsArray).toEqual(true);
|
||||||
} catch (e) {
|
expect(result.fnArray.length).toEqual(1);
|
||||||
thrown = e;
|
expect(result.fnArray[0]).toEqual('save');
|
||||||
}
|
expect(result.argsArray[0].length).toEqual(0);
|
||||||
expect(thrown).toNotEqual(false);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle one operations', function() {
|
it('should handle one operations', function() {
|
||||||
@ -84,14 +83,14 @@ describe('evaluator', function() {
|
|||||||
'prefix');
|
'prefix');
|
||||||
var resources = new ResourcesMock();
|
var resources = new ResourcesMock();
|
||||||
resources.Res1 = {};
|
resources.Res1 = {};
|
||||||
var stream = new StringStream('B*BBMC');
|
var stream = new StringStream('B*Bf*');
|
||||||
var result = evaluator.getOperatorList(stream, resources, []);
|
var result = evaluator.getOperatorList(stream, resources, []);
|
||||||
|
|
||||||
expect(!!result.fnArray && !!result.argsArray).toEqual(true);
|
expect(!!result.fnArray && !!result.argsArray).toEqual(true);
|
||||||
expect(result.fnArray.length).toEqual(3);
|
expect(result.fnArray.length).toEqual(3);
|
||||||
expect(result.fnArray[0]).toEqual('eoFillStroke');
|
expect(result.fnArray[0]).toEqual('eoFillStroke');
|
||||||
expect(result.fnArray[1]).toEqual('fillStroke');
|
expect(result.fnArray[1]).toEqual('fillStroke');
|
||||||
expect(result.fnArray[2]).toEqual('beginMarkedContent');
|
expect(result.fnArray[2]).toEqual('eoFill');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should handle glued operations and operands', function() {
|
it('should handle glued operations and operands', function() {
|
||||||
@ -112,19 +111,53 @@ describe('evaluator', function() {
|
|||||||
it('should handle glued operations and literals', function() {
|
it('should handle glued operations and literals', function() {
|
||||||
var evaluator = new PartialEvaluator(new XrefMock(), new HandlerMock(),
|
var evaluator = new PartialEvaluator(new XrefMock(), new HandlerMock(),
|
||||||
'prefix');
|
'prefix');
|
||||||
var stream = new StringStream('trueifalserinulli');
|
var stream = new StringStream('trueifalserinullq');
|
||||||
var result = evaluator.getOperatorList(stream, new ResourcesMock(), []);
|
var result = evaluator.getOperatorList(stream, new ResourcesMock(), []);
|
||||||
|
|
||||||
expect(!!result.fnArray && !!result.argsArray).toEqual(true);
|
expect(!!result.fnArray && !!result.argsArray).toEqual(true);
|
||||||
expect(result.fnArray.length).toEqual(3);
|
expect(result.fnArray.length).toEqual(3);
|
||||||
expect(result.fnArray[0]).toEqual('setFlatness');
|
expect(result.fnArray[0]).toEqual('setFlatness');
|
||||||
expect(result.fnArray[1]).toEqual('setRenderingIntent');
|
expect(result.fnArray[1]).toEqual('setRenderingIntent');
|
||||||
expect(result.fnArray[2]).toEqual('setFlatness');
|
expect(result.fnArray[2]).toEqual('save');
|
||||||
expect(result.argsArray.length).toEqual(3);
|
expect(result.argsArray.length).toEqual(3);
|
||||||
expect(result.argsArray[0].length).toEqual(1);
|
expect(result.argsArray[0].length).toEqual(1);
|
||||||
expect(result.argsArray[0][0]).toEqual(true);
|
expect(result.argsArray[0][0]).toEqual(true);
|
||||||
expect(result.argsArray[1].length).toEqual(1);
|
expect(result.argsArray[1].length).toEqual(1);
|
||||||
expect(result.argsArray[1][0]).toEqual(false);
|
expect(result.argsArray[1][0]).toEqual(false);
|
||||||
|
expect(result.argsArray[2].length).toEqual(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('validateNumberOfArgs', function() {
|
||||||
|
it('should execute if correct number of arguments', function() {
|
||||||
|
var evaluator = new PartialEvaluator(new XrefMock(), new HandlerMock(),
|
||||||
|
'prefix');
|
||||||
|
var stream = new StringStream('5 1 d0');
|
||||||
|
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('setCharWidth');
|
||||||
|
});
|
||||||
|
it('should execute if too many arguments', function() {
|
||||||
|
var evaluator = new PartialEvaluator(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(5);
|
||||||
|
expect(result.argsArray[0][1]).toEqual(1);
|
||||||
|
expect(result.argsArray[0][2]).toEqual(4);
|
||||||
|
expect(result.fnArray[0]).toEqual('setCharWidth');
|
||||||
|
});
|
||||||
|
it('should skip if too few arguments', function() {
|
||||||
|
var evaluator = new PartialEvaluator(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([]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user