Add PDFFunction to IR support + complete ColorSpace SeparationCS IR support
This commit is contained in:
parent
8572c29c55
commit
9dcefe1efc
206
pdf.js
206
pdf.js
@ -5604,12 +5604,12 @@ var ColorSpace = (function() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor.fromIR = function(raw) {
|
constructor.fromIR = function(IR) {
|
||||||
var name;
|
var name;
|
||||||
if (IsArray(raw)) {
|
if (IsArray(IR)) {
|
||||||
name = raw[0];
|
name = IR[0];
|
||||||
} else {
|
} else {
|
||||||
name = raw;
|
name = IR;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (name) {
|
switch (name) {
|
||||||
@ -5620,17 +5620,25 @@ var ColorSpace = (function() {
|
|||||||
case "DeviceCmykCS":
|
case "DeviceCmykCS":
|
||||||
return new DeviceCmykCS();
|
return new DeviceCmykCS();
|
||||||
case "PatternCS":
|
case "PatternCS":
|
||||||
var baseCS = raw[1];
|
var baseCS = IR[1];
|
||||||
if (baseCS == null) {
|
if (baseCS == null) {
|
||||||
return new PatternCS(null);
|
return new PatternCS(null);
|
||||||
} else {
|
} else {
|
||||||
return new PatternCS(ColorSpace.fromIR(baseCS));
|
return new PatternCS(ColorSpace.fromIR(baseCS));
|
||||||
}
|
}
|
||||||
case "Indexed":
|
case "IndexedCS":
|
||||||
var baseCS = raw[1];
|
var baseCS = IR[1];
|
||||||
var hiVal = raw[2];
|
var hiVal = IR[2];
|
||||||
var lookup = raw[3];
|
var lookup = IR[3];
|
||||||
return new IndexedCS(ColorSpace.fromIR(baseCS), hiVal, lookup)
|
return new IndexedCS(ColorSpace.fromIR(baseCS), hiVal, lookup)
|
||||||
|
case "SeparationCS":
|
||||||
|
var alt = IR[1];
|
||||||
|
var tintFnIR = IR[2];
|
||||||
|
|
||||||
|
return new SeparationCS(
|
||||||
|
ColorSpace.fromIR(alt),
|
||||||
|
PDFFunction.fromIR(tintFnIR)
|
||||||
|
);
|
||||||
default:
|
default:
|
||||||
error("Unkown name " + name);
|
error("Unkown name " + name);
|
||||||
}
|
}
|
||||||
@ -5708,14 +5716,9 @@ var ColorSpace = (function() {
|
|||||||
var lookup = xref.fetchIfRef(cs[3]);
|
var lookup = xref.fetchIfRef(cs[3]);
|
||||||
return ["IndexedCS", baseCS, hiVal, lookup];
|
return ["IndexedCS", baseCS, hiVal, lookup];
|
||||||
case 'Separation':
|
case 'Separation':
|
||||||
if (!parseOnly) {
|
var alt = ColorSpace.parseToIR(cs[2], xref, res);
|
||||||
error("Need to implement IR form for SeparationCS");
|
var tintFnIR = PDFFunction.getIR(xref, xref.fetchIfRef(cs[3]));
|
||||||
} else {
|
return ["SeparationCS", alt, tintFnIR];
|
||||||
var name = cs[1];
|
|
||||||
var alt = ColorSpace.parse(cs[2], xref, res);
|
|
||||||
var tintFn = new PDFFunction(xref, xref.fetchIfRef(cs[3]));
|
|
||||||
return new SeparationCS(alt, tintFn);
|
|
||||||
}
|
|
||||||
case 'Lab':
|
case 'Lab':
|
||||||
case 'DeviceN':
|
case 'DeviceN':
|
||||||
default:
|
default:
|
||||||
@ -6059,7 +6062,7 @@ var RadialAxialShading = (function() {
|
|||||||
error('No support for array of functions');
|
error('No support for array of functions');
|
||||||
else if (!IsPDFFunction(fnObj))
|
else if (!IsPDFFunction(fnObj))
|
||||||
error('Invalid function');
|
error('Invalid function');
|
||||||
var fn = new PDFFunction(xref, fnObj);
|
var fn = PDFFunction.parse(xref, fnObj);
|
||||||
|
|
||||||
// 10 samples seems good enough for now, but probably won't work
|
// 10 samples seems good enough for now, but probably won't work
|
||||||
// if there are sharp color changes. Ideally, we would implement
|
// if there are sharp color changes. Ideally, we would implement
|
||||||
@ -6069,7 +6072,7 @@ var RadialAxialShading = (function() {
|
|||||||
|
|
||||||
var colorStops = [];
|
var colorStops = [];
|
||||||
for (var i = t0; i <= t1; i += step) {
|
for (var i = t0; i <= t1; i += step) {
|
||||||
var color = fn.func([i]);
|
var color = fn([i]);
|
||||||
var rgbColor = Util.makeCssRgb.apply(this, cs.getRgb(color));
|
var rgbColor = Util.makeCssRgb.apply(this, cs.getRgb(color));
|
||||||
colorStops.push([(i - t0) / diff, rgbColor]);
|
colorStops.push([(i - t0) / diff, rgbColor]);
|
||||||
}
|
}
|
||||||
@ -6439,26 +6442,76 @@ var PDFImage = (function() {
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
var PDFFunction = (function() {
|
var PDFFunction = (function() {
|
||||||
function constructor(xref, fn) {
|
var CONSTRUCT_SAMPLED = 0;
|
||||||
var dict = fn.dict;
|
var CONSTRUCT_INTERPOLATED = 2;
|
||||||
if (!dict)
|
var CONSTRUCT_STICHED = 3;
|
||||||
dict = fn;
|
var CONSTRUCT_POSTSCRIPT = 4;
|
||||||
|
|
||||||
|
return {
|
||||||
|
getSampleArray: function(size, outputSize, bps, str) {
|
||||||
|
var length = 1;
|
||||||
|
for (var i = 0; i < size.length; i++)
|
||||||
|
length *= size[i];
|
||||||
|
length *= outputSize;
|
||||||
|
|
||||||
var types = [this.constructSampled,
|
var array = [];
|
||||||
null,
|
var codeSize = 0;
|
||||||
this.constructInterpolated,
|
var codeBuf = 0;
|
||||||
this.constructStiched,
|
|
||||||
this.constructPostScript];
|
|
||||||
|
|
||||||
var typeNum = dict.get('FunctionType');
|
var strBytes = str.getBytes((length * bps + 7) / 8);
|
||||||
var typeFn = types[typeNum];
|
var strIdx = 0;
|
||||||
if (!typeFn)
|
for (var i = 0; i < length; i++) {
|
||||||
error('Unknown type of function');
|
var b;
|
||||||
|
while (codeSize < bps) {
|
||||||
|
codeBuf <<= 8;
|
||||||
|
codeBuf |= strBytes[strIdx++];
|
||||||
|
codeSize += 8;
|
||||||
|
}
|
||||||
|
codeSize -= bps;
|
||||||
|
array.push(codeBuf >> codeSize);
|
||||||
|
codeBuf &= (1 << codeSize) - 1;
|
||||||
|
}
|
||||||
|
return array;
|
||||||
|
},
|
||||||
|
|
||||||
typeFn.call(this, fn, dict, xref);
|
getIR: function(xref, fn) {
|
||||||
}
|
var dict = fn.dict;
|
||||||
|
if (!dict)
|
||||||
|
dict = fn;
|
||||||
|
|
||||||
|
var types = [this.constructSampled,
|
||||||
|
null,
|
||||||
|
this.constructInterpolated,
|
||||||
|
this.constructStiched,
|
||||||
|
this.constructPostScript];
|
||||||
|
|
||||||
|
var typeNum = dict.get('FunctionType');
|
||||||
|
var typeFn = types[typeNum];
|
||||||
|
if (!typeFn)
|
||||||
|
error('Unknown type of function');
|
||||||
|
|
||||||
|
return typeFn.call(this, fn, dict, xref);
|
||||||
|
},
|
||||||
|
|
||||||
|
fromIR: function(IR) {
|
||||||
|
var type = IR[0];
|
||||||
|
switch (type) {
|
||||||
|
case CONSTRUCT_SAMPLED:
|
||||||
|
return this.constructSampledFromIR(IR);
|
||||||
|
case CONSTRUCT_INTERPOLATED:
|
||||||
|
return this.constructInterpolatedFromIR(IR);
|
||||||
|
case CONSTRUCT_STICHED:
|
||||||
|
return this.constructStichedFromIR(IR);
|
||||||
|
case CONSTRUCT_POSTSCRIPT:
|
||||||
|
return this.constructPostScriptFromIR(IR);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
parse: function(xref, fn) {
|
||||||
|
var IR = this.getIR(xref, fn);
|
||||||
|
return this.fromIR(IR);
|
||||||
|
},
|
||||||
|
|
||||||
constructor.prototype = {
|
|
||||||
constructSampled: function(str, dict) {
|
constructSampled: function(str, dict) {
|
||||||
var domain = dict.get('Domain');
|
var domain = dict.get('Domain');
|
||||||
var range = dict.get('Range');
|
var range = dict.get('Range');
|
||||||
@ -6495,7 +6548,21 @@ var PDFFunction = (function() {
|
|||||||
|
|
||||||
var samples = this.getSampleArray(size, outputSize, bps, str);
|
var samples = this.getSampleArray(size, outputSize, bps, str);
|
||||||
|
|
||||||
this.func = function(args) {
|
return [ CONSTRUCT_SAMPLED, inputSize, domain, encode, decode, samples, size, outputSize, bps, range ];
|
||||||
|
},
|
||||||
|
|
||||||
|
constructSampledFromIR: function(IR) {
|
||||||
|
var inputSize = IR[1];
|
||||||
|
var domain = IR[2];
|
||||||
|
var encode = IR[3];
|
||||||
|
var decode = IR[4]
|
||||||
|
var samples = IR[5]
|
||||||
|
var size = IR[6]
|
||||||
|
var outputSize= IR[7];
|
||||||
|
var bps = IR[8];
|
||||||
|
var range = IR[9];
|
||||||
|
|
||||||
|
return function(args) {
|
||||||
var clip = function(v, min, max) {
|
var clip = function(v, min, max) {
|
||||||
if (v > max)
|
if (v > max)
|
||||||
v = max;
|
v = max;
|
||||||
@ -6552,33 +6619,9 @@ var PDFFunction = (function() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
};
|
|
||||||
},
|
|
||||||
getSampleArray: function(size, outputSize, bps, str) {
|
|
||||||
var length = 1;
|
|
||||||
for (var i = 0; i < size.length; i++)
|
|
||||||
length *= size[i];
|
|
||||||
length *= outputSize;
|
|
||||||
|
|
||||||
var array = [];
|
|
||||||
var codeSize = 0;
|
|
||||||
var codeBuf = 0;
|
|
||||||
|
|
||||||
var strBytes = str.getBytes((length * bps + 7) / 8);
|
|
||||||
var strIdx = 0;
|
|
||||||
for (var i = 0; i < length; i++) {
|
|
||||||
var b;
|
|
||||||
while (codeSize < bps) {
|
|
||||||
codeBuf <<= 8;
|
|
||||||
codeBuf |= strBytes[strIdx++];
|
|
||||||
codeSize += 8;
|
|
||||||
}
|
|
||||||
codeSize -= bps;
|
|
||||||
array.push(codeBuf >> codeSize);
|
|
||||||
codeBuf &= (1 << codeSize) - 1;
|
|
||||||
}
|
}
|
||||||
return array;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
constructInterpolated: function(str, dict) {
|
constructInterpolated: function(str, dict) {
|
||||||
var c0 = dict.get('C0') || [0];
|
var c0 = dict.get('C0') || [0];
|
||||||
var c1 = dict.get('C1') || [1];
|
var c1 = dict.get('C1') || [1];
|
||||||
@ -6592,7 +6635,14 @@ var PDFFunction = (function() {
|
|||||||
for (var i = 0; i < length; ++i)
|
for (var i = 0; i < length; ++i)
|
||||||
diff.push(c1[i] - c0[i]);
|
diff.push(c1[i] - c0[i]);
|
||||||
|
|
||||||
this.func = function(args) {
|
return [ CONSTRUCT_INTERPOLATED, c0, diff ];
|
||||||
|
},
|
||||||
|
|
||||||
|
constructInterpolatedFromIR: function(IR) {
|
||||||
|
var c0 = IR[1];
|
||||||
|
var diff = IR[2];
|
||||||
|
|
||||||
|
return function(args) {
|
||||||
var x = args[0];
|
var x = args[0];
|
||||||
|
|
||||||
var out = [];
|
var out = [];
|
||||||
@ -6600,8 +6650,10 @@ var PDFFunction = (function() {
|
|||||||
out.push(c0[j] + (x^n * diff[i]));
|
out.push(c0[j] + (x^n * diff[i]));
|
||||||
|
|
||||||
return out;
|
return out;
|
||||||
};
|
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
constructStiched: function(fn, dict, xref) {
|
constructStiched: function(fn, dict, xref) {
|
||||||
var domain = dict.get('Domain');
|
var domain = dict.get('Domain');
|
||||||
var range = dict.get('Range');
|
var range = dict.get('Range');
|
||||||
@ -6616,12 +6668,26 @@ var PDFFunction = (function() {
|
|||||||
var fnRefs = dict.get('Functions');
|
var fnRefs = dict.get('Functions');
|
||||||
var fns = [];
|
var fns = [];
|
||||||
for (var i = 0, ii = fnRefs.length; i < ii; ++i)
|
for (var i = 0, ii = fnRefs.length; i < ii; ++i)
|
||||||
fns.push(new PDFFunction(xref, xref.fetchIfRef(fnRefs[i])));
|
fns.push(PDFFunction.getIR(xref, xref.fetchIfRef(fnRefs[i])));
|
||||||
|
|
||||||
var bounds = dict.get('Bounds');
|
var bounds = dict.get('Bounds');
|
||||||
var encode = dict.get('Encode');
|
var encode = dict.get('Encode');
|
||||||
|
|
||||||
this.func = function(args) {
|
return [ CONSTRUCT_STICHED, domain, bounds, encoding, fns ];
|
||||||
|
},
|
||||||
|
|
||||||
|
constructStichedFromIR: function(IR) {
|
||||||
|
var domain = IR[1];
|
||||||
|
var bounds = IR[2];
|
||||||
|
var encoding = IR[3];
|
||||||
|
var fnsIR = IR[4];
|
||||||
|
var fns = [];
|
||||||
|
|
||||||
|
for (var i = 0; i < fnsIR.length; i++) {
|
||||||
|
fns.push(PDFFunction.fromIR(fnsIR[i]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return function(args) {
|
||||||
var clip = function(v, min, max) {
|
var clip = function(v, min, max) {
|
||||||
if (v > max)
|
if (v > max)
|
||||||
v = max;
|
v = max;
|
||||||
@ -6655,13 +6721,17 @@ var PDFFunction = (function() {
|
|||||||
return fns[i].func([v2]);
|
return fns[i].func([v2]);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
constructPostScript: function() {
|
constructPostScript: function() {
|
||||||
|
return [ CONSTRUCT_POSTSCRIPT ];
|
||||||
|
},
|
||||||
|
|
||||||
|
constructPostScriptFromIR: function(IR) {
|
||||||
TODO('unhandled type of function');
|
TODO('unhandled type of function');
|
||||||
this.func = function() {
|
this.func = function() {
|
||||||
return [255, 105, 180];
|
return [255, 105, 180];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
return constructor;
|
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user