Merge remote-tracking branch 'origin/master' into mozilla
This commit is contained in:
commit
5600cf93a0
5
Makefile
5
Makefile
@ -226,6 +226,7 @@ FIREFOX_CONTENT_DIR := $(EXTENSION_SRC)/firefox/$(CONTENT_DIR)/
|
|||||||
FIREFOX_EXTENSION_FILES_TO_COPY = \
|
FIREFOX_EXTENSION_FILES_TO_COPY = \
|
||||||
*.js \
|
*.js \
|
||||||
*.rdf \
|
*.rdf \
|
||||||
|
*.png \
|
||||||
install.rdf.in \
|
install.rdf.in \
|
||||||
README.mozilla \
|
README.mozilla \
|
||||||
components \
|
components \
|
||||||
@ -234,12 +235,16 @@ FIREFOX_EXTENSION_FILES_TO_COPY = \
|
|||||||
FIREFOX_EXTENSION_FILES = \
|
FIREFOX_EXTENSION_FILES = \
|
||||||
bootstrap.js \
|
bootstrap.js \
|
||||||
install.rdf \
|
install.rdf \
|
||||||
|
icon.png \
|
||||||
|
icon64.png \
|
||||||
components \
|
components \
|
||||||
content \
|
content \
|
||||||
LICENSE \
|
LICENSE \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
FIREFOX_MC_EXTENSION_FILES = \
|
FIREFOX_MC_EXTENSION_FILES = \
|
||||||
bootstrap.js \
|
bootstrap.js \
|
||||||
|
icon.png \
|
||||||
|
icon64.png \
|
||||||
components \
|
components \
|
||||||
content \
|
content \
|
||||||
LICENSE \
|
LICENSE \
|
||||||
|
18
extensions/firefox/bootstrap.js
vendored
18
extensions/firefox/bootstrap.js
vendored
@ -10,10 +10,14 @@ let Cc = Components.classes;
|
|||||||
let Ci = Components.interfaces;
|
let Ci = Components.interfaces;
|
||||||
let Cm = Components.manager;
|
let Cm = Components.manager;
|
||||||
let Cu = Components.utils;
|
let Cu = Components.utils;
|
||||||
|
let application = Cc['@mozilla.org/fuel/application;1']
|
||||||
|
.getService(Ci.fuelIApplication);
|
||||||
|
|
||||||
Cu.import('resource://gre/modules/Services.jsm');
|
Cu.import('resource://gre/modules/Services.jsm');
|
||||||
|
|
||||||
function log(str) {
|
function log(str) {
|
||||||
|
if (!application.prefs.getValue(EXT_PREFIX + '.pdfBugEnabled', false))
|
||||||
|
return;
|
||||||
dump(str + '\n');
|
dump(str + '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,12 +64,7 @@ function startup(aData, aReason) {
|
|||||||
var ioService = Services.io;
|
var ioService = Services.io;
|
||||||
var resProt = ioService.getProtocolHandler('resource')
|
var resProt = ioService.getProtocolHandler('resource')
|
||||||
.QueryInterface(Ci.nsIResProtocolHandler);
|
.QueryInterface(Ci.nsIResProtocolHandler);
|
||||||
var aliasFile = Cc['@mozilla.org/file/local;1']
|
var aliasURI = ioService.newURI('content/', 'UTF-8', aData.resourceURI);
|
||||||
.createInstance(Ci.nsILocalFile);
|
|
||||||
var componentPath = aData.installPath.clone();
|
|
||||||
componentPath.append('content');
|
|
||||||
aliasFile.initWithPath(componentPath.path);
|
|
||||||
var aliasURI = ioService.newFileURI(aliasFile);
|
|
||||||
resProt.setSubstitution(RESOURCE_NAME, aliasURI);
|
resProt.setSubstitution(RESOURCE_NAME, aliasURI);
|
||||||
|
|
||||||
// Load the component and register it.
|
// Load the component and register it.
|
||||||
@ -73,12 +72,9 @@ function startup(aData, aReason) {
|
|||||||
'components/PdfStreamConverter.js';
|
'components/PdfStreamConverter.js';
|
||||||
Cu.import(pdfStreamConverterUrl);
|
Cu.import(pdfStreamConverterUrl);
|
||||||
Factory.register(PdfStreamConverter);
|
Factory.register(PdfStreamConverter);
|
||||||
Services.prefs.setBoolPref('extensions.pdf.js.active', true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function shutdown(aData, aReason) {
|
function shutdown(aData, aReason) {
|
||||||
if (Services.prefs.getBoolPref('extensions.pdf.js.active'))
|
|
||||||
Services.prefs.setBoolPref('extensions.pdf.js.active', false);
|
|
||||||
if (aReason == APP_SHUTDOWN)
|
if (aReason == APP_SHUTDOWN)
|
||||||
return;
|
return;
|
||||||
var ioService = Services.io;
|
var ioService = Services.io;
|
||||||
@ -89,18 +85,14 @@ function shutdown(aData, aReason) {
|
|||||||
// Remove the contract/component.
|
// Remove the contract/component.
|
||||||
Factory.unregister();
|
Factory.unregister();
|
||||||
// Unload the converter
|
// Unload the converter
|
||||||
if (pdfStreamConverterUrl) {
|
|
||||||
Cu.unload(pdfStreamConverterUrl);
|
Cu.unload(pdfStreamConverterUrl);
|
||||||
pdfStreamConverterUrl = null;
|
pdfStreamConverterUrl = null;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function install(aData, aReason) {
|
function install(aData, aReason) {
|
||||||
Services.prefs.setBoolPref('extensions.pdf.js.active', false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function uninstall(aData, aReason) {
|
function uninstall(aData, aReason) {
|
||||||
Services.prefs.clearUserPref('extensions.pdf.js.active');
|
|
||||||
application.prefs.setValue(EXT_PREFIX + '.database', '{}');
|
application.prefs.setValue(EXT_PREFIX + '.database', '{}');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,15 @@ const MAX_DATABASE_LENGTH = 4096;
|
|||||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||||
Cu.import('resource://gre/modules/Services.jsm');
|
Cu.import('resource://gre/modules/Services.jsm');
|
||||||
|
|
||||||
|
let application = Cc['@mozilla.org/fuel/application;1']
|
||||||
|
.getService(Ci.fuelIApplication);
|
||||||
|
let privateBrowsing = Cc['@mozilla.org/privatebrowsing;1']
|
||||||
|
.getService(Ci.nsIPrivateBrowsingService);
|
||||||
|
let inPrivateBrowswing = privateBrowsing.privateBrowsingEnabled;
|
||||||
|
|
||||||
function log(aMsg) {
|
function log(aMsg) {
|
||||||
|
if (!application.prefs.getValue(EXT_PREFIX + '.pdfBugEnabled', false))
|
||||||
|
return;
|
||||||
let msg = 'PdfStreamConverter.js: ' + (aMsg.join ? aMsg.join('') : aMsg);
|
let msg = 'PdfStreamConverter.js: ' + (aMsg.join ? aMsg.join('') : aMsg);
|
||||||
Services.console.logStringMessage(msg);
|
Services.console.logStringMessage(msg);
|
||||||
dump(msg + '\n');
|
dump(msg + '\n');
|
||||||
@ -40,11 +48,6 @@ function topWindow(win) {
|
|||||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||||
.getInterface(Ci.nsIDOMWindow);
|
.getInterface(Ci.nsIDOMWindow);
|
||||||
}
|
}
|
||||||
let application = Cc['@mozilla.org/fuel/application;1']
|
|
||||||
.getService(Ci.fuelIApplication);
|
|
||||||
let privateBrowsing = Cc['@mozilla.org/privatebrowsing;1']
|
|
||||||
.getService(Ci.nsIPrivateBrowsingService);
|
|
||||||
let inPrivateBrowswing = privateBrowsing.privateBrowsingEnabled;
|
|
||||||
|
|
||||||
// All the priviledged actions.
|
// All the priviledged actions.
|
||||||
function ChromeActions() {
|
function ChromeActions() {
|
||||||
@ -125,9 +128,6 @@ PdfStreamConverter.prototype = {
|
|||||||
|
|
||||||
// nsIStreamConverter::asyncConvertData
|
// nsIStreamConverter::asyncConvertData
|
||||||
asyncConvertData: function(aFromType, aToType, aListener, aCtxt) {
|
asyncConvertData: function(aFromType, aToType, aListener, aCtxt) {
|
||||||
if (!Services.prefs.getBoolPref('extensions.pdf.js.active'))
|
|
||||||
throw Cr.NS_ERROR_NOT_IMPLEMENTED;
|
|
||||||
|
|
||||||
// Ignoring HTTP POST requests -- pdf.js has to repeat the request.
|
// Ignoring HTTP POST requests -- pdf.js has to repeat the request.
|
||||||
var skipConversion = false;
|
var skipConversion = false;
|
||||||
try {
|
try {
|
||||||
|
BIN
extensions/firefox/icon.png
Normal file
BIN
extensions/firefox/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.5 KiB |
BIN
extensions/firefox/icon64.png
Normal file
BIN
extensions/firefox/icon64.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 5.7 KiB |
@ -5,9 +5,8 @@
|
|||||||
|
|
||||||
<Description about="urn:mozilla:install-manifest">
|
<Description about="urn:mozilla:install-manifest">
|
||||||
<em:id>uriloader@pdf.js</em:id>
|
<em:id>uriloader@pdf.js</em:id>
|
||||||
<em:name>pdf.js</em:name>
|
<em:name>PDF Viewer</em:name>
|
||||||
<em:version>PDFJSSCRIPT_VERSION</em:version>
|
<em:version>PDFJSSCRIPT_VERSION</em:version>
|
||||||
<em:iconURL>chrome://pdf.js/skin/logo.png</em:iconURL>
|
|
||||||
<em:targetApplication>
|
<em:targetApplication>
|
||||||
<Description>
|
<Description>
|
||||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||||
@ -16,9 +15,8 @@
|
|||||||
</Description>
|
</Description>
|
||||||
</em:targetApplication>
|
</em:targetApplication>
|
||||||
<em:bootstrap>true</em:bootstrap>
|
<em:bootstrap>true</em:bootstrap>
|
||||||
<em:unpack>true</em:unpack>
|
<em:creator>Mozilla</em:creator>
|
||||||
<em:creator>Mozilla Labs</em:creator>
|
<em:description>Uses HTML5 to display PDF files directly in Firefox.</em:description>
|
||||||
<em:description>pdf.js uri loader</em:description>
|
|
||||||
<em:homepageURL>https://github.com/mozilla/pdf.js/</em:homepageURL>
|
<em:homepageURL>https://github.com/mozilla/pdf.js/</em:homepageURL>
|
||||||
<em:type>2</em:type>
|
<em:type>2</em:type>
|
||||||
<!-- Use the raw link for updates so we we can use SSL. -->
|
<!-- Use the raw link for updates so we we can use SSL. -->
|
||||||
|
@ -7,22 +7,20 @@
|
|||||||
|
|
||||||
<Description about="urn:mozilla:install-manifest">
|
<Description about="urn:mozilla:install-manifest">
|
||||||
<em:id>uriloader@pdf.js</em:id>
|
<em:id>uriloader@pdf.js</em:id>
|
||||||
<em:name>pdf.js</em:name>
|
<em:name>PDF Viewer</em:name>
|
||||||
<em:version>PDFJSSCRIPT_VERSION</em:version>
|
<em:version>PDFJSSCRIPT_VERSION</em:version>
|
||||||
<em:iconURL>chrome://pdf.js/skin/logo.png</em:iconURL>
|
|
||||||
<em:targetApplication>
|
<em:targetApplication>
|
||||||
<Description>
|
<Description>
|
||||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id>
|
||||||
<em:minVersion>@FIREFOX_VERSION@</em:minVersion>
|
<em:minVersion>@FIREFOX_VERSION@</em:minVersion>
|
||||||
<em:maxVersion>@FIREFOX_VERSION@</em:maxVersion>
|
<em:maxVersion>@FIREFOX_VERSION@</em:maxVersion>
|
||||||
<em:strictCompatibility>true</em:strictCompatibility>
|
|
||||||
</Description>
|
</Description>
|
||||||
</em:targetApplication>
|
</em:targetApplication>
|
||||||
|
<em:strictCompatibility>true</em:strictCompatibility>
|
||||||
<em:bootstrap>true</em:bootstrap>
|
<em:bootstrap>true</em:bootstrap>
|
||||||
<em:unpack>true</em:unpack>
|
<em:creator>Mozilla</em:creator>
|
||||||
<em:creator>Mozilla Labs</em:creator>
|
<em:description>Uses HTML5 to display PDF files directly in Firefox.</em:description>
|
||||||
<em:description>pdf.js uri loader</em:description>
|
<em:homepageURL>http://support.mozilla.org/kb/using-mozilla-pdf-viewer</em:homepageURL>
|
||||||
<em:homepageURL>https://github.com/mozilla/pdf.js/</em:homepageURL>
|
|
||||||
<em:type>2</em:type>
|
<em:type>2</em:type>
|
||||||
</Description>
|
</Description>
|
||||||
</RDF>
|
</RDF>
|
||||||
|
5
make.js
5
make.js
@ -220,6 +220,7 @@ target.firefox = function() {
|
|||||||
FIREFOX_EXTENSION_FILES_TO_COPY =
|
FIREFOX_EXTENSION_FILES_TO_COPY =
|
||||||
['*.js',
|
['*.js',
|
||||||
'*.rdf',
|
'*.rdf',
|
||||||
|
'*.png',
|
||||||
'install.rdf.in',
|
'install.rdf.in',
|
||||||
'README.mozilla',
|
'README.mozilla',
|
||||||
'components',
|
'components',
|
||||||
@ -227,11 +228,15 @@ target.firefox = function() {
|
|||||||
FIREFOX_EXTENSION_FILES =
|
FIREFOX_EXTENSION_FILES =
|
||||||
['bootstrap.js',
|
['bootstrap.js',
|
||||||
'install.rdf',
|
'install.rdf',
|
||||||
|
'icon.png',
|
||||||
|
'icon64.png',
|
||||||
'components',
|
'components',
|
||||||
'content',
|
'content',
|
||||||
'LICENSE'];
|
'LICENSE'];
|
||||||
FIREFOX_MC_EXTENSION_FILES =
|
FIREFOX_MC_EXTENSION_FILES =
|
||||||
['bootstrap.js',
|
['bootstrap.js',
|
||||||
|
'icon.png',
|
||||||
|
'icon64.png',
|
||||||
'components',
|
'components',
|
||||||
'content',
|
'content',
|
||||||
'LICENSE'];
|
'LICENSE'];
|
||||||
|
@ -124,7 +124,7 @@ var bidi = PDFJS.bidi = (function bidiClosure() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (function bidi(text, startLevel) {
|
function bidi(text, startLevel) {
|
||||||
var str = text.str;
|
var str = text.str;
|
||||||
var strLength = str.length;
|
var strLength = str.length;
|
||||||
if (strLength == 0)
|
if (strLength == 0)
|
||||||
@ -429,5 +429,8 @@ var bidi = PDFJS.bidi = (function bidiClosure() {
|
|||||||
result += ch;
|
result += ch;
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
});
|
}
|
||||||
|
|
||||||
|
return bidi;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ var CanvasExtraState = (function CanvasExtraStateClosure() {
|
|||||||
return CanvasExtraState;
|
return CanvasExtraState;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
function ScratchCanvas(width, height) {
|
function createScratchCanvas(width, height) {
|
||||||
var canvas = document.createElement('canvas');
|
var canvas = document.createElement('canvas');
|
||||||
canvas.width = width;
|
canvas.width = width;
|
||||||
canvas.height = height;
|
canvas.height = height;
|
||||||
@ -188,9 +188,9 @@ function addContextCurrentTransform(ctx) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var CanvasGraphics = (function CanvasGraphicsClosure() {
|
var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||||
// Defines the time the executeIRQueue is going to be executing
|
// Defines the time the executeOperatorList is going to be executing
|
||||||
// before it stops and shedules a continue of execution.
|
// before it stops and shedules a continue of execution.
|
||||||
var kExecutionTime = 50;
|
var kExecutionTime = 15;
|
||||||
|
|
||||||
function CanvasGraphics(canvasCtx, objs, textLayer) {
|
function CanvasGraphics(canvasCtx, objs, textLayer) {
|
||||||
this.ctx = canvasCtx;
|
this.ctx = canvasCtx;
|
||||||
@ -199,7 +199,6 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
this.pendingClip = null;
|
this.pendingClip = null;
|
||||||
this.res = null;
|
this.res = null;
|
||||||
this.xobjs = null;
|
this.xobjs = null;
|
||||||
this.ScratchCanvas = ScratchCanvas;
|
|
||||||
this.objs = objs;
|
this.objs = objs;
|
||||||
this.textLayer = textLayer;
|
this.textLayer = textLayer;
|
||||||
if (canvasCtx) {
|
if (canvasCtx) {
|
||||||
@ -229,7 +228,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
'setStrokeColor': true,
|
'setStrokeColor': true,
|
||||||
'setStrokeColorN': true,
|
'setStrokeColorN': true,
|
||||||
'setFillColor': true,
|
'setFillColor': true,
|
||||||
'setFillColorN_IR': true,
|
'setFillColorN': true,
|
||||||
'setStrokeGray': true,
|
'setStrokeGray': true,
|
||||||
'setFillGray': true,
|
'setFillGray': true,
|
||||||
'setStrokeRGBColor': true,
|
'setStrokeRGBColor': true,
|
||||||
@ -268,15 +267,16 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
this.textLayer.beginLayout();
|
this.textLayer.beginLayout();
|
||||||
},
|
},
|
||||||
|
|
||||||
executeIRQueue: function canvasGraphicsExecuteIRQueue(codeIR,
|
executeOperatorList: function canvasGraphicsExecuteOperatorList(
|
||||||
|
operatorList,
|
||||||
executionStartIdx, continueCallback,
|
executionStartIdx, continueCallback,
|
||||||
stepper) {
|
stepper) {
|
||||||
var argsArray = codeIR.argsArray;
|
var argsArray = operatorList.argsArray;
|
||||||
var fnArray = codeIR.fnArray;
|
var fnArray = operatorList.fnArray;
|
||||||
var i = executionStartIdx || 0;
|
var i = executionStartIdx || 0;
|
||||||
var argsArrayLen = argsArray.length;
|
var argsArrayLen = argsArray.length;
|
||||||
|
|
||||||
// Sometimes the IRQueue to execute is empty.
|
// Sometimes the OperatorList to execute is empty.
|
||||||
if (argsArrayLen == i) {
|
if (argsArrayLen == i) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -314,7 +314,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
// If the entire IRQueue was executed, stop as were done.
|
// If the entire operatorList was executed, stop as were done.
|
||||||
if (i == argsArrayLen) {
|
if (i == argsArrayLen) {
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
@ -327,8 +327,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If the IRQueue isn't executed completly yet OR the execution time
|
// If the operatorList isn't executed completely yet OR the execution
|
||||||
// was short enough, do another execution round.
|
// time was short enough, do another execution round.
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -556,7 +556,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
this.current.leading = -leading;
|
this.current.leading = -leading;
|
||||||
},
|
},
|
||||||
setFont: function canvasGraphicsSetFont(fontRefName, size) {
|
setFont: function canvasGraphicsSetFont(fontRefName, size) {
|
||||||
var fontObj = this.objs.get(fontRefName).fontObj;
|
var fontObj = this.objs.get(fontRefName);
|
||||||
var current = this.current;
|
var current = this.current;
|
||||||
|
|
||||||
if (!fontObj)
|
if (!fontObj)
|
||||||
@ -707,7 +707,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
this.save();
|
this.save();
|
||||||
ctx.scale(fontSize, fontSize);
|
ctx.scale(fontSize, fontSize);
|
||||||
ctx.transform.apply(ctx, fontMatrix);
|
ctx.transform.apply(ctx, fontMatrix);
|
||||||
this.executeIRQueue(glyph.codeIRQueue);
|
this.executeOperatorList(glyph.operatorList);
|
||||||
this.restore();
|
this.restore();
|
||||||
|
|
||||||
var transformed = Util.applyTransform([glyph.width, 0], fontMatrix);
|
var transformed = Util.applyTransform([glyph.width, 0], fontMatrix);
|
||||||
@ -908,7 +908,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
this.ctx.strokeStyle = color;
|
this.ctx.strokeStyle = color;
|
||||||
this.current.strokeColor = color;
|
this.current.strokeColor = color;
|
||||||
},
|
},
|
||||||
getColorN_IR_Pattern: function canvasGraphicsGetColorN_IR_Pattern(IR, cs) {
|
getColorN_Pattern: function canvasGraphicsGetColorN_Pattern(IR, cs) {
|
||||||
if (IR[0] == 'TilingPattern') {
|
if (IR[0] == 'TilingPattern') {
|
||||||
var args = IR[1];
|
var args = IR[1];
|
||||||
var base = cs.base;
|
var base = cs.base;
|
||||||
@ -930,11 +930,11 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
}
|
}
|
||||||
return pattern;
|
return pattern;
|
||||||
},
|
},
|
||||||
setStrokeColorN_IR: function canvasGraphicsSetStrokeColorN(/*...*/) {
|
setStrokeColorN: function canvasGraphicsSetStrokeColorN(/*...*/) {
|
||||||
var cs = this.current.strokeColorSpace;
|
var cs = this.current.strokeColorSpace;
|
||||||
|
|
||||||
if (cs.name == 'Pattern') {
|
if (cs.name == 'Pattern') {
|
||||||
this.current.strokeColor = this.getColorN_IR_Pattern(arguments, cs);
|
this.current.strokeColor = this.getColorN_Pattern(arguments, cs);
|
||||||
} else {
|
} else {
|
||||||
this.setStrokeColor.apply(this, arguments);
|
this.setStrokeColor.apply(this, arguments);
|
||||||
}
|
}
|
||||||
@ -946,11 +946,11 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
this.ctx.fillStyle = color;
|
this.ctx.fillStyle = color;
|
||||||
this.current.fillColor = color;
|
this.current.fillColor = color;
|
||||||
},
|
},
|
||||||
setFillColorN_IR: function canvasGraphicsSetFillColorN(/*...*/) {
|
setFillColorN: function canvasGraphicsSetFillColorN(/*...*/) {
|
||||||
var cs = this.current.fillColorSpace;
|
var cs = this.current.fillColorSpace;
|
||||||
|
|
||||||
if (cs.name == 'Pattern') {
|
if (cs.name == 'Pattern') {
|
||||||
this.current.fillColor = this.getColorN_IR_Pattern(arguments, cs);
|
this.current.fillColor = this.getColorN_Pattern(arguments, cs);
|
||||||
} else {
|
} else {
|
||||||
this.setFillColor.apply(this, arguments);
|
this.setFillColor.apply(this, arguments);
|
||||||
}
|
}
|
||||||
@ -1116,7 +1116,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
// scale the image to the unit square
|
// scale the image to the unit square
|
||||||
ctx.scale(1 / w, -1 / h);
|
ctx.scale(1 / w, -1 / h);
|
||||||
|
|
||||||
var tmpCanvas = new this.ScratchCanvas(w, h);
|
var tmpCanvas = createScratchCanvas(w, h);
|
||||||
var tmpCtx = tmpCanvas.getContext('2d');
|
var tmpCtx = tmpCanvas.getContext('2d');
|
||||||
|
|
||||||
var fillColor = this.current.fillColor;
|
var fillColor = this.current.fillColor;
|
||||||
@ -1147,7 +1147,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
|||||||
// scale the image to the unit square
|
// scale the image to the unit square
|
||||||
ctx.scale(1 / w, -1 / h);
|
ctx.scale(1 / w, -1 / h);
|
||||||
|
|
||||||
var tmpCanvas = new this.ScratchCanvas(w, h);
|
var tmpCanvas = createScratchCanvas(w, h);
|
||||||
var tmpCtx = tmpCanvas.getContext('2d');
|
var tmpCtx = tmpCanvas.getContext('2d');
|
||||||
this.putBinaryImageData(tmpCtx, imgData, w, h);
|
this.putBinaryImageData(tmpCtx, imgData, w, h);
|
||||||
|
|
||||||
|
@ -135,6 +135,7 @@ var ColorSpace = (function ColorSpaceClosure() {
|
|||||||
basePatternCS = ColorSpace.parseToIR(basePatternCS, xref, res);
|
basePatternCS = ColorSpace.parseToIR(basePatternCS, xref, res);
|
||||||
return ['PatternCS', basePatternCS];
|
return ['PatternCS', basePatternCS];
|
||||||
case 'Indexed':
|
case 'Indexed':
|
||||||
|
case 'I':
|
||||||
var baseIndexedCS = ColorSpace.parseToIR(cs[1], xref, res);
|
var baseIndexedCS = ColorSpace.parseToIR(cs[1], xref, res);
|
||||||
var hiVal = cs[2] + 1;
|
var hiVal = cs[2] + 1;
|
||||||
var lookup = xref.fetchIfRef(cs[3]);
|
var lookup = xref.fetchIfRef(cs[3]);
|
||||||
|
82
src/core.js
82
src/core.js
@ -170,10 +170,10 @@ var Page = (function PageClosure() {
|
|||||||
return shadow(this, 'rotate', rotate);
|
return shadow(this, 'rotate', rotate);
|
||||||
},
|
},
|
||||||
|
|
||||||
startRenderingFromIRQueue: function pageStartRenderingFromIRQueue(
|
startRenderingFromOperatorList: function pageStartRenderingFromOperatorList(
|
||||||
IRQueue, fonts) {
|
operatorList, fonts) {
|
||||||
var self = this;
|
var self = this;
|
||||||
this.IRQueue = IRQueue;
|
this.operatorList = operatorList;
|
||||||
|
|
||||||
var displayContinuation = function pageDisplayContinuation() {
|
var displayContinuation = function pageDisplayContinuation() {
|
||||||
// Always defer call to display() to work around bug in
|
// Always defer call to display() to work around bug in
|
||||||
@ -184,15 +184,16 @@ var Page = (function PageClosure() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
this.ensureFonts(fonts,
|
this.ensureFonts(fonts,
|
||||||
function pageStartRenderingFromIRQueueEnsureFonts() {
|
function pageStartRenderingFromOperatorListEnsureFonts() {
|
||||||
displayContinuation();
|
displayContinuation();
|
||||||
});
|
}
|
||||||
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
getIRQueue: function pageGetIRQueue(handler, dependency) {
|
getOperatorList: function pageGetOperatorList(handler, dependency) {
|
||||||
if (this.IRQueue) {
|
if (this.operatorList) {
|
||||||
// content was compiled
|
// content was compiled
|
||||||
return this.IRQueue;
|
return this.operatorList;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.stats.time('Build IR Queue');
|
this.stats.time('Build IR Queue');
|
||||||
@ -213,11 +214,10 @@ var Page = (function PageClosure() {
|
|||||||
|
|
||||||
var pe = this.pe = new PartialEvaluator(
|
var pe = this.pe = new PartialEvaluator(
|
||||||
xref, handler, 'p' + this.pageNumber + '_');
|
xref, handler, 'p' + this.pageNumber + '_');
|
||||||
var IRQueue = {};
|
|
||||||
this.IRQueue = pe.getIRQueue(content, resources, IRQueue, dependency);
|
|
||||||
|
|
||||||
|
this.operatorList = pe.getOperatorList(content, resources, dependency);
|
||||||
this.stats.timeEnd('Build IR Queue');
|
this.stats.timeEnd('Build IR Queue');
|
||||||
return this.IRQueue;
|
return this.operatorList;
|
||||||
},
|
},
|
||||||
|
|
||||||
ensureFonts: function pageEnsureFonts(fonts, callback) {
|
ensureFonts: function pageEnsureFonts(fonts, callback) {
|
||||||
@ -228,14 +228,13 @@ var Page = (function PageClosure() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load all the fonts
|
// Load all the fonts
|
||||||
var fontObjs = FontLoader.bind(
|
FontLoader.bind(
|
||||||
fonts,
|
fonts,
|
||||||
function pageEnsureFontsFontObjs(fontObjs) {
|
function pageEnsureFontsFontObjs(fontObjs) {
|
||||||
this.stats.timeEnd('Font Loading');
|
this.stats.timeEnd('Font Loading');
|
||||||
|
|
||||||
callback.call(this);
|
callback.call(this);
|
||||||
}.bind(this),
|
}.bind(this)
|
||||||
this.objs
|
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -255,18 +254,19 @@ var Page = (function PageClosure() {
|
|||||||
rotate: this.rotate });
|
rotate: this.rotate });
|
||||||
|
|
||||||
var startIdx = 0;
|
var startIdx = 0;
|
||||||
var length = this.IRQueue.fnArray.length;
|
var length = this.operatorList.fnArray.length;
|
||||||
var IRQueue = this.IRQueue;
|
var operatorList = this.operatorList;
|
||||||
var stepper = null;
|
var stepper = null;
|
||||||
if (PDFJS.pdfBug && StepperManager.enabled) {
|
if (PDFJS.pdfBug && StepperManager.enabled) {
|
||||||
stepper = StepperManager.create(this.pageNumber);
|
stepper = StepperManager.create(this.pageNumber);
|
||||||
stepper.init(IRQueue);
|
stepper.init(operatorList);
|
||||||
stepper.nextBreakPoint = stepper.getNextBreakPoint();
|
stepper.nextBreakPoint = stepper.getNextBreakPoint();
|
||||||
}
|
}
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
function next() {
|
function next() {
|
||||||
startIdx = gfx.executeIRQueue(IRQueue, startIdx, next, stepper);
|
startIdx =
|
||||||
|
gfx.executeOperatorList(operatorList, startIdx, next, stepper);
|
||||||
if (startIdx == length) {
|
if (startIdx == length) {
|
||||||
gfx.endDrawing();
|
gfx.endDrawing();
|
||||||
stats.timeEnd('Rendering');
|
stats.timeEnd('Rendering');
|
||||||
@ -436,13 +436,14 @@ var Page = (function PageClosure() {
|
|||||||
startRendering: function pageStartRendering(ctx, callback, textLayer) {
|
startRendering: function pageStartRendering(ctx, callback, textLayer) {
|
||||||
var stats = this.stats;
|
var stats = this.stats;
|
||||||
stats.time('Overall');
|
stats.time('Overall');
|
||||||
// If there is no displayReadyPromise yet, then the IRQueue was never
|
// If there is no displayReadyPromise yet, then the operatorList was never
|
||||||
// requested before. Make the request and create the promise.
|
// requested before. Make the request and create the promise.
|
||||||
if (!this.displayReadyPromise) {
|
if (!this.displayReadyPromise) {
|
||||||
this.pdf.startRendering(this);
|
this.pdf.startRendering(this);
|
||||||
this.displayReadyPromise = new Promise();
|
this.displayReadyPromise = new Promise();
|
||||||
}
|
}
|
||||||
// Once the IRQueue and fonts are loaded, perform the actual rendering.
|
|
||||||
|
// Once the operatorList and fonts are loaded, do the actual rendering.
|
||||||
this.displayReadyPromise.then(
|
this.displayReadyPromise.then(
|
||||||
function pageDisplayReadyPromise() {
|
function pageDisplayReadyPromise() {
|
||||||
var gfx = new CanvasGraphics(ctx, this.objs, textLayer);
|
var gfx = new CanvasGraphics(ctx, this.objs, textLayer);
|
||||||
@ -474,9 +475,6 @@ var Page = (function PageClosure() {
|
|||||||
* Right now there exists one PDFDocModel on the main thread + one object
|
* Right now there exists one PDFDocModel on the main thread + one object
|
||||||
* for each worker. If there is no worker support enabled, there are two
|
* for each worker. If there is no worker support enabled, there are two
|
||||||
* `PDFDocModel` objects on the main thread created.
|
* `PDFDocModel` objects on the main thread created.
|
||||||
* TODO: Refactor the internal object structure, such that there is no
|
|
||||||
* need for the `PDFDocModel` anymore and there is only one object on the
|
|
||||||
* main thread and not one entire copy on each worker instance.
|
|
||||||
*/
|
*/
|
||||||
var PDFDocModel = (function PDFDocModelClosure() {
|
var PDFDocModel = (function PDFDocModelClosure() {
|
||||||
function PDFDocModel(arg, callback) {
|
function PDFDocModel(arg, callback) {
|
||||||
@ -645,9 +643,9 @@ var PDFDoc = (function PDFDocClosure() {
|
|||||||
|
|
||||||
this.data = data;
|
this.data = data;
|
||||||
this.stream = stream;
|
this.stream = stream;
|
||||||
this.pdf = new PDFDocModel(stream);
|
this.pdfModel = new PDFDocModel(stream);
|
||||||
this.fingerprint = this.pdf.getFingerprint();
|
this.fingerprint = this.pdfModel.getFingerprint();
|
||||||
this.catalog = this.pdf.catalog;
|
this.catalog = this.pdfModel.catalog;
|
||||||
this.objs = new PDFObjects();
|
this.objs = new PDFObjects();
|
||||||
|
|
||||||
this.pageCache = [];
|
this.pageCache = [];
|
||||||
@ -733,8 +731,9 @@ var PDFDoc = (function PDFDocClosure() {
|
|||||||
var pageNum = data.pageNum;
|
var pageNum = data.pageNum;
|
||||||
var page = this.pageCache[pageNum];
|
var page = this.pageCache[pageNum];
|
||||||
var depFonts = data.depFonts;
|
var depFonts = data.depFonts;
|
||||||
|
|
||||||
page.stats.timeEnd('Page Request');
|
page.stats.timeEnd('Page Request');
|
||||||
page.startRenderingFromIRQueue(data.IRQueue, depFonts);
|
page.startRenderingFromOperatorList(data.operatorList, depFonts);
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
messageHandler.on('obj', function pdfDocObj(data) {
|
messageHandler.on('obj', function pdfDocObj(data) {
|
||||||
@ -761,31 +760,16 @@ var PDFDoc = (function PDFDocClosure() {
|
|||||||
file = new Stream(file, 0, file.length, fontFileDict);
|
file = new Stream(file, 0, file.length, fontFileDict);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For now, resolve the font object here direclty. The real font
|
// At this point, only the font object is created but the font is
|
||||||
// object is then created in FontLoader.bind().
|
// not yet attached to the DOM. This is done in `FontLoader.bind`.
|
||||||
this.objs.resolve(id, {
|
var font = new Font(name, file, properties);
|
||||||
name: name,
|
this.objs.resolve(id, font);
|
||||||
file: file,
|
|
||||||
properties: properties
|
|
||||||
});
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
error('Got unkown object type ' + type);
|
error('Got unkown object type ' + type);
|
||||||
}
|
}
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
messageHandler.on('font_ready', function pdfDocFontReady(data) {
|
|
||||||
var id = data[0];
|
|
||||||
var font = new FontShape(data[1]);
|
|
||||||
|
|
||||||
// If there is no string, then there is nothing to attach to the DOM.
|
|
||||||
if (!font.str) {
|
|
||||||
this.objs.resolve(id, font);
|
|
||||||
} else {
|
|
||||||
this.objs.setData(id, font);
|
|
||||||
}
|
|
||||||
}.bind(this));
|
|
||||||
|
|
||||||
messageHandler.on('page_error', function pdfDocError(data) {
|
messageHandler.on('page_error', function pdfDocError(data) {
|
||||||
var page = this.pageCache[data.pageNum];
|
var page = this.pageCache[data.pageNum];
|
||||||
if (page.displayReadyPromise)
|
if (page.displayReadyPromise)
|
||||||
@ -807,7 +791,7 @@ var PDFDoc = (function PDFDocClosure() {
|
|||||||
var size = width * height;
|
var size = width * height;
|
||||||
var rgbaLength = size * 4;
|
var rgbaLength = size * 4;
|
||||||
var buf = new Uint8Array(size * components);
|
var buf = new Uint8Array(size * components);
|
||||||
var tmpCanvas = new ScratchCanvas(width, height);
|
var tmpCanvas = createScratchCanvas(width, height);
|
||||||
var tmpCtx = tmpCanvas.getContext('2d');
|
var tmpCtx = tmpCanvas.getContext('2d');
|
||||||
tmpCtx.drawImage(img, 0, 0);
|
tmpCtx.drawImage(img, 0, 0);
|
||||||
var data = tmpCtx.getImageData(0, 0, width, height).data;
|
var data = tmpCtx.getImageData(0, 0, width, height).data;
|
||||||
@ -836,7 +820,7 @@ var PDFDoc = (function PDFDocClosure() {
|
|||||||
},
|
},
|
||||||
|
|
||||||
get numPages() {
|
get numPages() {
|
||||||
return this.pdf.numPages;
|
return this.pdfModel.numPages;
|
||||||
},
|
},
|
||||||
|
|
||||||
startRendering: function pdfDocStartRendering(page) {
|
startRendering: function pdfDocStartRendering(page) {
|
||||||
@ -851,7 +835,7 @@ var PDFDoc = (function PDFDocClosure() {
|
|||||||
if (this.pageCache[n])
|
if (this.pageCache[n])
|
||||||
return this.pageCache[n];
|
return this.pageCache[n];
|
||||||
|
|
||||||
var page = this.pdf.getPage(n);
|
var page = this.pdfModel.getPage(n);
|
||||||
// Add a reference to the objects such that Page can forward the reference
|
// Add a reference to the objects such that Page can forward the reference
|
||||||
// to the CanvasGraphics and so on.
|
// to the CanvasGraphics and so on.
|
||||||
page.objs = this.objs;
|
page.objs = this.objs;
|
||||||
|
@ -570,7 +570,6 @@ var CipherTransformFactory = (function CipherTransformFactoryClosure() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
error('Unknown crypto method');
|
error('Unknown crypto method');
|
||||||
return null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CipherTransformFactory.prototype = {
|
CipherTransformFactory.prototype = {
|
||||||
|
@ -112,8 +112,8 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
PartialEvaluator.prototype = {
|
PartialEvaluator.prototype = {
|
||||||
getIRQueue: function partialEvaluatorGetIRQueue(stream, resources,
|
getOperatorList: function partialEvaluatorGetOperatorList(stream, resources,
|
||||||
queue, dependency) {
|
dependency, queue) {
|
||||||
|
|
||||||
var self = this;
|
var self = this;
|
||||||
var xref = this.xref;
|
var xref = this.xref;
|
||||||
@ -136,8 +136,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
|
|
||||||
var fontRes = resources.get('Font');
|
var fontRes = resources.get('Font');
|
||||||
|
|
||||||
// TODO: TOASK: Is it possible to get here? If so, what does
|
|
||||||
// args[0].name should be like???
|
|
||||||
assert(fontRes, 'fontRes not available');
|
assert(fontRes, 'fontRes not available');
|
||||||
|
|
||||||
fontRes = xref.fetchIfRef(fontRes);
|
fontRes = xref.fetchIfRef(fontRes);
|
||||||
@ -177,7 +175,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
|
|
||||||
// Ensure the font is ready before the font is set
|
// Ensure the font is ready before the font is set
|
||||||
// and later on used for drawing.
|
// and later on used for drawing.
|
||||||
// TODO: This should get insert to the IRQueue only once per
|
// OPTIMIZE: This should get insert to the operatorList only once per
|
||||||
// page.
|
// page.
|
||||||
insertDependency([loadedName]);
|
insertDependency([loadedName]);
|
||||||
return loadedName;
|
return loadedName;
|
||||||
@ -239,6 +237,9 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
}, handler, xref, resources, image, inline);
|
}, handler, xref, resources, image, inline);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!queue)
|
||||||
|
queue = {};
|
||||||
|
|
||||||
if (!queue.argsArray) {
|
if (!queue.argsArray) {
|
||||||
queue.argsArray = [];
|
queue.argsArray = [];
|
||||||
}
|
}
|
||||||
@ -280,9 +281,6 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
// 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) {
|
||||||
// Use the IR version for setStroke/FillColorN.
|
|
||||||
fn += '_IR';
|
|
||||||
|
|
||||||
// compile tiling patterns
|
// compile tiling patterns
|
||||||
var patternName = args[args.length - 1];
|
var patternName = args[args.length - 1];
|
||||||
// SCN/scn applies patterns along with normal colors
|
// SCN/scn applies patterns along with normal colors
|
||||||
@ -295,15 +293,14 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
if (typeNum == TILING_PATTERN) {
|
if (typeNum == TILING_PATTERN) {
|
||||||
// Create an IR of the pattern code.
|
// Create an IR of the pattern code.
|
||||||
var depIdx = dependencyArray.length;
|
var depIdx = dependencyArray.length;
|
||||||
var queueObj = {};
|
var operatorList = this.getOperatorList(pattern,
|
||||||
var codeIR = this.getIRQueue(pattern, dict.get('Resources') ||
|
dict.get('Resources') || resources, dependencyArray);
|
||||||
resources, queueObj, dependencyArray);
|
|
||||||
|
|
||||||
// Add the dependencies that are required to execute the
|
// Add the dependencies that are required to execute the
|
||||||
// codeIR.
|
// operatorList.
|
||||||
insertDependency(dependencyArray.slice(depIdx));
|
insertDependency(dependencyArray.slice(depIdx));
|
||||||
|
|
||||||
args = TilingPattern.getIR(codeIR, dict, args);
|
args = TilingPattern.getIR(operatorList, dict, args);
|
||||||
}
|
}
|
||||||
else if (typeNum == SHADING_PATTERN) {
|
else if (typeNum == SHADING_PATTERN) {
|
||||||
var shading = xref.fetchIfRef(dict.get('Shading'));
|
var shading = xref.fetchIfRef(dict.get('Shading'));
|
||||||
@ -337,14 +334,18 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
fnArray.push('paintFormXObjectBegin');
|
fnArray.push('paintFormXObjectBegin');
|
||||||
argsArray.push([matrix, bbox]);
|
argsArray.push([matrix, bbox]);
|
||||||
|
|
||||||
// This adds the IRQueue of the xObj to the current queue.
|
// This adds the operatorList of the xObj to the current queue.
|
||||||
var depIdx = dependencyArray.length;
|
var depIdx = dependencyArray.length;
|
||||||
|
|
||||||
this.getIRQueue(xobj, xobj.dict.get('Resources') || resources,
|
// Pass in the current `queue` object. That means the `fnArray`
|
||||||
queue, dependencyArray);
|
// and the `argsArray` in this scope is reused and new commands
|
||||||
|
// are added to them.
|
||||||
|
this.getOperatorList(xobj,
|
||||||
|
xobj.dict.get('Resources') || resources,
|
||||||
|
dependencyArray, queue);
|
||||||
|
|
||||||
// Add the dependencies that are required to execute the
|
// Add the dependencies that are required to execute the
|
||||||
// codeIR.
|
// operatorList.
|
||||||
insertDependency(dependencyArray.slice(depIdx));
|
insertDependency(dependencyArray.slice(depIdx));
|
||||||
|
|
||||||
fn = 'paintFormXObjectEnd';
|
fn = 'paintFormXObjectEnd';
|
||||||
@ -454,10 +455,7 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return queue;
|
||||||
fnArray: fnArray,
|
|
||||||
argsArray: argsArray
|
|
||||||
};
|
|
||||||
},
|
},
|
||||||
|
|
||||||
extractDataStructures: function
|
extractDataStructures: function
|
||||||
@ -855,12 +853,11 @@ var PartialEvaluator = (function PartialEvaluatorClosure() {
|
|||||||
var charProcs = xref.fetchIfRef(dict.get('CharProcs'));
|
var charProcs = xref.fetchIfRef(dict.get('CharProcs'));
|
||||||
var fontResources = xref.fetchIfRef(dict.get('Resources')) || resources;
|
var fontResources = xref.fetchIfRef(dict.get('Resources')) || resources;
|
||||||
properties.resources = fontResources;
|
properties.resources = fontResources;
|
||||||
properties.charProcIRQueues = {};
|
properties.charProcOperatorList = {};
|
||||||
for (var key in charProcs.map) {
|
for (var key in charProcs.map) {
|
||||||
var glyphStream = xref.fetchIfRef(charProcs.map[key]);
|
var glyphStream = xref.fetchIfRef(charProcs.map[key]);
|
||||||
var queueObj = {};
|
properties.charProcOperatorList[key] =
|
||||||
properties.charProcIRQueues[key] =
|
this.getOperatorList(glyphStream, fontResources, dependency);
|
||||||
this.getIRQueue(glyphStream, fontResources, queueObj, dependency);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
1536
src/fonts.js
1536
src/fonts.js
File diff suppressed because it is too large
Load Diff
@ -514,7 +514,6 @@ var XRef = (function XRefClosure() {
|
|||||||
return dict;
|
return dict;
|
||||||
// nothing helps
|
// nothing helps
|
||||||
error('Invalid PDF structure');
|
error('Invalid PDF structure');
|
||||||
return null;
|
|
||||||
},
|
},
|
||||||
readXRef: function readXref(startXRef) {
|
readXRef: function readXref(startXRef) {
|
||||||
var stream = this.stream;
|
var stream = this.stream;
|
||||||
@ -723,12 +722,10 @@ var PDFObjects = (function PDFObjectsClosure() {
|
|||||||
|
|
||||||
// If there isn't an object yet or the object isn't resolved, then the
|
// If there isn't an object yet or the object isn't resolved, then the
|
||||||
// data isn't ready yet!
|
// data isn't ready yet!
|
||||||
if (!obj || !obj.isResolved) {
|
if (!obj || !obj.isResolved)
|
||||||
error('Requesting object that isn\'t resolved yet ' + objId);
|
error('Requesting object that isn\'t resolved yet ' + objId);
|
||||||
return null;
|
|
||||||
} else {
|
|
||||||
return obj.data;
|
return obj.data;
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -53,16 +53,15 @@ var Parser = (function ParserClosure() {
|
|||||||
this.shift();
|
this.shift();
|
||||||
var dict = new Dict();
|
var dict = new Dict();
|
||||||
while (!isCmd(this.buf1, '>>') && !isEOF(this.buf1)) {
|
while (!isCmd(this.buf1, '>>') && !isEOF(this.buf1)) {
|
||||||
if (!isName(this.buf1)) {
|
if (!isName(this.buf1))
|
||||||
error('Dictionary key must be a name object');
|
error('Dictionary key must be a name object');
|
||||||
} else {
|
|
||||||
var key = this.buf1.name;
|
var key = this.buf1.name;
|
||||||
this.shift();
|
this.shift();
|
||||||
if (isEOF(this.buf1))
|
if (isEOF(this.buf1))
|
||||||
break;
|
break;
|
||||||
dict.set(key, this.getObj(cipherTransform));
|
dict.set(key, this.getObj(cipherTransform));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (isEOF(this.buf1))
|
if (isEOF(this.buf1))
|
||||||
error('End of file inside dictionary');
|
error('End of file inside dictionary');
|
||||||
|
|
||||||
@ -106,16 +105,15 @@ var Parser = (function ParserClosure() {
|
|||||||
// parse dictionary
|
// parse dictionary
|
||||||
var dict = new Dict();
|
var dict = new Dict();
|
||||||
while (!isCmd(this.buf1, 'ID') && !isEOF(this.buf1)) {
|
while (!isCmd(this.buf1, 'ID') && !isEOF(this.buf1)) {
|
||||||
if (!isName(this.buf1)) {
|
if (!isName(this.buf1))
|
||||||
error('Dictionary key must be a name object');
|
error('Dictionary key must be a name object');
|
||||||
} else {
|
|
||||||
var key = this.buf1.name;
|
var key = this.buf1.name;
|
||||||
this.shift();
|
this.shift();
|
||||||
if (isEOF(this.buf1))
|
if (isEOF(this.buf1))
|
||||||
break;
|
break;
|
||||||
dict.set(key, this.getObj(cipherTransform));
|
dict.set(key, this.getObj(cipherTransform));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// parse image stream
|
// parse image stream
|
||||||
var startPos = stream.pos;
|
var startPos = stream.pos;
|
||||||
@ -176,10 +174,8 @@ var Parser = (function ParserClosure() {
|
|||||||
|
|
||||||
// get length
|
// get length
|
||||||
var length = this.fetchIfRef(dict.get('Length'));
|
var length = this.fetchIfRef(dict.get('Length'));
|
||||||
if (!isInt(length)) {
|
if (!isInt(length))
|
||||||
error('Bad ' + length + ' attribute in stream');
|
error('Bad ' + length + ' attribute in stream');
|
||||||
length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
// skip over the stream data
|
// skip over the stream data
|
||||||
stream.pos = pos + length;
|
stream.pos = pos + length;
|
||||||
@ -208,7 +204,7 @@ var Parser = (function ParserClosure() {
|
|||||||
filter = filterArray[i];
|
filter = filterArray[i];
|
||||||
if (!isName(filter))
|
if (!isName(filter))
|
||||||
error('Bad filter name: ' + filter);
|
error('Bad filter name: ' + filter);
|
||||||
else {
|
|
||||||
params = null;
|
params = null;
|
||||||
if (isArray(paramsArray) && (i in paramsArray))
|
if (isArray(paramsArray) && (i in paramsArray))
|
||||||
params = paramsArray[i];
|
params = paramsArray[i];
|
||||||
@ -217,7 +213,6 @@ var Parser = (function ParserClosure() {
|
|||||||
length = null;
|
length = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return stream;
|
return stream;
|
||||||
},
|
},
|
||||||
makeFilter: function parserMakeFilter(stream, name, length, params) {
|
makeFilter: function parserMakeFilter(stream, name, length, params) {
|
||||||
@ -527,17 +522,15 @@ var Lexer = (function LexerClosure() {
|
|||||||
// fall through
|
// fall through
|
||||||
case ')':
|
case ')':
|
||||||
error('Illegal character: ' + ch);
|
error('Illegal character: ' + ch);
|
||||||
return Error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// command
|
// command
|
||||||
var str = ch;
|
var str = ch;
|
||||||
while (!!(ch = stream.lookChar()) && !specialChars[ch.charCodeAt(0)]) {
|
while (!!(ch = stream.lookChar()) && !specialChars[ch.charCodeAt(0)]) {
|
||||||
stream.skip();
|
stream.skip();
|
||||||
if (str.length == 128) {
|
if (str.length == 128)
|
||||||
error('Command token too long: ' + str.length);
|
error('Command token too long: ' + str.length);
|
||||||
break;
|
|
||||||
}
|
|
||||||
str += ch;
|
str += ch;
|
||||||
}
|
}
|
||||||
if (str == 'true')
|
if (str == 'true')
|
||||||
@ -594,7 +587,6 @@ var Linearization = (function LinearizationClosure() {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
error('"' + name + '" field in linearization table is invalid');
|
error('"' + name + '" field in linearization table is invalid');
|
||||||
return 0;
|
|
||||||
},
|
},
|
||||||
getHint: function linearizationGetHint(index) {
|
getHint: function linearizationGetHint(index) {
|
||||||
var linDict = this.linDict;
|
var linDict = this.linDict;
|
||||||
@ -607,7 +599,6 @@ var Linearization = (function LinearizationClosure() {
|
|||||||
return obj2;
|
return obj2;
|
||||||
}
|
}
|
||||||
error('Hints table in linearization table is invalid: ' + index);
|
error('Hints table in linearization table is invalid: ' + index);
|
||||||
return 0;
|
|
||||||
},
|
},
|
||||||
get length() {
|
get length() {
|
||||||
if (!isDict(this.linDict))
|
if (!isDict(this.linDict))
|
||||||
|
@ -82,7 +82,7 @@ Shadings.RadialAxial = (function RadialAxialClosure() {
|
|||||||
fnObj = xref.fetchIfRef(fnObj);
|
fnObj = xref.fetchIfRef(fnObj);
|
||||||
if (isArray(fnObj))
|
if (isArray(fnObj))
|
||||||
error('No support for array of functions');
|
error('No support for array of functions');
|
||||||
else if (!isPDFFunction(fnObj))
|
if (!isPDFFunction(fnObj))
|
||||||
error('Invalid function');
|
error('Invalid function');
|
||||||
var fn = PDFFunction.parse(xref, fnObj);
|
var fn = PDFFunction.parse(xref, fnObj);
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ var TilingPattern = (function TilingPatternClosure() {
|
|||||||
var MAX_PATTERN_SIZE = 512;
|
var MAX_PATTERN_SIZE = 512;
|
||||||
|
|
||||||
function TilingPattern(IR, color, ctx, objs) {
|
function TilingPattern(IR, color, ctx, objs) {
|
||||||
var IRQueue = IR[2];
|
var operatorList = IR[2];
|
||||||
this.matrix = IR[3];
|
this.matrix = IR[3];
|
||||||
var bbox = IR[4];
|
var bbox = IR[4];
|
||||||
var xstep = IR[5];
|
var xstep = IR[5];
|
||||||
@ -222,7 +222,7 @@ var TilingPattern = (function TilingPatternClosure() {
|
|||||||
width = height = MAX_PATTERN_SIZE;
|
width = height = MAX_PATTERN_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
var tmpCanvas = new ScratchCanvas(width, height);
|
var tmpCanvas = createScratchCanvas(width, height);
|
||||||
|
|
||||||
// set the new canvas element context as the graphics context
|
// set the new canvas element context as the graphics context
|
||||||
var tmpCtx = tmpCanvas.getContext('2d');
|
var tmpCtx = tmpCanvas.getContext('2d');
|
||||||
@ -259,12 +259,12 @@ var TilingPattern = (function TilingPatternClosure() {
|
|||||||
graphics.endPath();
|
graphics.endPath();
|
||||||
}
|
}
|
||||||
|
|
||||||
graphics.executeIRQueue(IRQueue);
|
graphics.executeOperatorList(operatorList);
|
||||||
|
|
||||||
this.canvas = tmpCanvas;
|
this.canvas = tmpCanvas;
|
||||||
}
|
}
|
||||||
|
|
||||||
TilingPattern.getIR = function tiling_getIR(codeIR, dict, args) {
|
TilingPattern.getIR = function tiling_getIR(operatorList, dict, args) {
|
||||||
var matrix = dict.get('Matrix');
|
var matrix = dict.get('Matrix');
|
||||||
var bbox = dict.get('BBox');
|
var bbox = dict.get('BBox');
|
||||||
var xstep = dict.get('XStep');
|
var xstep = dict.get('XStep');
|
||||||
@ -272,7 +272,7 @@ var TilingPattern = (function TilingPatternClosure() {
|
|||||||
var paintType = dict.get('PaintType');
|
var paintType = dict.get('PaintType');
|
||||||
|
|
||||||
return [
|
return [
|
||||||
'TilingPattern', args, codeIR, matrix, bbox, xstep, ystep, paintType
|
'TilingPattern', args, operatorList, matrix, bbox, xstep, ystep, paintType
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -79,7 +79,7 @@ MessageHandler.prototype = {
|
|||||||
|
|
||||||
var WorkerMessageHandler = {
|
var WorkerMessageHandler = {
|
||||||
setup: function wphSetup(handler) {
|
setup: function wphSetup(handler) {
|
||||||
var pdfDoc = null;
|
var pdfModel = null;
|
||||||
|
|
||||||
handler.on('test', function wphSetupTest(data) {
|
handler.on('test', function wphSetupTest(data) {
|
||||||
handler.send('test', data instanceof Uint8Array);
|
handler.send('test', data instanceof Uint8Array);
|
||||||
@ -88,7 +88,7 @@ var WorkerMessageHandler = {
|
|||||||
handler.on('doc', function wphSetupDoc(data) {
|
handler.on('doc', function wphSetupDoc(data) {
|
||||||
// Create only the model of the PDFDoc, which is enough for
|
// Create only the model of the PDFDoc, which is enough for
|
||||||
// processing the content of the pdf.
|
// processing the content of the pdf.
|
||||||
pdfDoc = new PDFDocModel(new Stream(data));
|
pdfModel = new PDFDocModel(new Stream(data));
|
||||||
});
|
});
|
||||||
|
|
||||||
handler.on('page_request', function wphSetupPageRequest(pageNum) {
|
handler.on('page_request', function wphSetupPageRequest(pageNum) {
|
||||||
@ -103,14 +103,14 @@ var WorkerMessageHandler = {
|
|||||||
var start = Date.now();
|
var start = Date.now();
|
||||||
|
|
||||||
var dependency = [];
|
var dependency = [];
|
||||||
var IRQueue = null;
|
var operatorList = null;
|
||||||
try {
|
try {
|
||||||
var page = pdfDoc.getPage(pageNum);
|
var page = pdfModel.getPage(pageNum);
|
||||||
// Pre compile the pdf page and fetch the fonts/images.
|
// Pre compile the pdf page and fetch the fonts/images.
|
||||||
IRQueue = page.getIRQueue(handler, dependency);
|
operatorList = page.getOperatorList(handler, dependency);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
var minimumStackMessage =
|
var minimumStackMessage =
|
||||||
'worker.js: while trying to getPage() and getIRQueue()';
|
'worker.js: while trying to getPage() and getOperatorList()';
|
||||||
|
|
||||||
// Turn the error into an obj that can be serialized
|
// Turn the error into an obj that can be serialized
|
||||||
if (typeof e === 'string') {
|
if (typeof e === 'string') {
|
||||||
@ -137,8 +137,8 @@ var WorkerMessageHandler = {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('page=%d - getIRQueue: time=%dms, len=%d', pageNum,
|
console.log('page=%d - getOperatorList: time=%dms, len=%d', pageNum,
|
||||||
Date.now() - start, IRQueue.fnArray.length);
|
Date.now() - start, operatorList.fnArray.length);
|
||||||
|
|
||||||
// Filter the dependecies for fonts.
|
// Filter the dependecies for fonts.
|
||||||
var fonts = {};
|
var fonts = {};
|
||||||
@ -151,59 +151,10 @@ var WorkerMessageHandler = {
|
|||||||
|
|
||||||
handler.send('page', {
|
handler.send('page', {
|
||||||
pageNum: pageNum,
|
pageNum: pageNum,
|
||||||
IRQueue: IRQueue,
|
operatorList: operatorList,
|
||||||
depFonts: Object.keys(fonts)
|
depFonts: Object.keys(fonts)
|
||||||
});
|
});
|
||||||
}, this);
|
}, this);
|
||||||
|
|
||||||
handler.on('font', function wphSetupFont(data) {
|
|
||||||
var objId = data[0];
|
|
||||||
var name = data[1];
|
|
||||||
var file = data[2];
|
|
||||||
var properties = data[3];
|
|
||||||
|
|
||||||
var font = {
|
|
||||||
name: name,
|
|
||||||
file: file,
|
|
||||||
properties: properties
|
|
||||||
};
|
|
||||||
|
|
||||||
// Some fonts don't have a file, e.g. the build in ones like Arial.
|
|
||||||
if (file) {
|
|
||||||
var fontFileDict = new Dict();
|
|
||||||
fontFileDict.map = file.dict.map;
|
|
||||||
|
|
||||||
var fontFile = new Stream(file.bytes, file.start,
|
|
||||||
file.end - file.start, fontFileDict);
|
|
||||||
|
|
||||||
// Check if this is a FlateStream. Otherwise just use the created
|
|
||||||
// Stream one. This makes complex_ttf_font.pdf work.
|
|
||||||
var cmf = file.bytes[0];
|
|
||||||
if ((cmf & 0x0f) == 0x08) {
|
|
||||||
font.file = new FlateStream(fontFile);
|
|
||||||
} else {
|
|
||||||
font.file = fontFile;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var obj = new Font(font.name, font.file, font.properties);
|
|
||||||
|
|
||||||
var str = '';
|
|
||||||
var objData = obj.data;
|
|
||||||
if (objData) {
|
|
||||||
var length = objData.length;
|
|
||||||
for (var j = 0; j < length; ++j)
|
|
||||||
str += String.fromCharCode(objData[j]);
|
|
||||||
}
|
|
||||||
|
|
||||||
obj.str = str;
|
|
||||||
|
|
||||||
// Remove the data array form the font object, as it's not needed
|
|
||||||
// anymore as we sent over the ready str.
|
|
||||||
delete obj.data;
|
|
||||||
|
|
||||||
handler.send('font_ready', [objId, obj]);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
2
test/pdfs/.gitignore
vendored
2
test/pdfs/.gitignore
vendored
@ -20,10 +20,12 @@
|
|||||||
!scan-bad.pdf
|
!scan-bad.pdf
|
||||||
!freeculture.pdf
|
!freeculture.pdf
|
||||||
!pdfkit_compressed.pdf
|
!pdfkit_compressed.pdf
|
||||||
|
!TAMReview.pdf
|
||||||
!issue918.pdf
|
!issue918.pdf
|
||||||
!issue1249.pdf
|
!issue1249.pdf
|
||||||
!smaskdim.pdf
|
!smaskdim.pdf
|
||||||
!type4psfunc.pdf
|
!type4psfunc.pdf
|
||||||
!S2.pdf
|
!S2.pdf
|
||||||
!zerowidthline.pdf
|
!zerowidthline.pdf
|
||||||
|
!issue1002.pdf
|
||||||
!issue925.pdf
|
!issue925.pdf
|
||||||
|
BIN
test/pdfs/TAMReview.pdf
Normal file
BIN
test/pdfs/TAMReview.pdf
Normal file
Binary file not shown.
BIN
test/pdfs/issue1002.pdf
Normal file
BIN
test/pdfs/issue1002.pdf
Normal file
Binary file not shown.
@ -472,6 +472,14 @@
|
|||||||
"rounds": 1,
|
"rounds": 1,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{ "id": "tamreview",
|
||||||
|
"file": "pdfs/TAMReview.pdf",
|
||||||
|
"md5": "8039aba56790d3597d2bc8c794a51301",
|
||||||
|
"rounds": 1,
|
||||||
|
"pageLimit": 5,
|
||||||
|
"link": true,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "issue925",
|
{ "id": "issue925",
|
||||||
"file": "pdfs/issue925.pdf",
|
"file": "pdfs/issue925.pdf",
|
||||||
"md5": "f58fe943090aff89dcc8e771bc0db4c2",
|
"md5": "f58fe943090aff89dcc8e771bc0db4c2",
|
||||||
@ -500,6 +508,13 @@
|
|||||||
"link": true,
|
"link": true,
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
|
{ "id": "issue1002",
|
||||||
|
"file": "pdfs/issue1002.pdf",
|
||||||
|
"md5": "af62d6cd95079322d4af18edd960d15c",
|
||||||
|
"rounds": 1,
|
||||||
|
"link": false,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "issue1243",
|
{ "id": "issue1243",
|
||||||
"file": "pdfs/issue1243.pdf",
|
"file": "pdfs/issue1243.pdf",
|
||||||
"md5": "130c849b83513d5ac5e03c6421fc7489",
|
"md5": "130c849b83513d5ac5e03c6421fc7489",
|
||||||
|
223
test/unit/font_spec.js
Normal file
223
test/unit/font_spec.js
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
/* -*- 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('font', function() {
|
||||||
|
function hexDump(bytes) {
|
||||||
|
var line = '';
|
||||||
|
for (var i = 0, ii = bytes.length; i < ii; ++i) {
|
||||||
|
var b = bytes[i].toString(16);
|
||||||
|
if (b.length < 2)
|
||||||
|
b = '0' + b;
|
||||||
|
line += b.toString(16);
|
||||||
|
}
|
||||||
|
return line;
|
||||||
|
}
|
||||||
|
// This example font comes from the CFF spec:
|
||||||
|
// http://www.adobe.com/content/dam/Adobe/en/devnet/font/pdfs/5176.CFF.pdf
|
||||||
|
var exampleFont = '0100040100010101134142434445462b' +
|
||||||
|
'54696d65732d526f6d616e000101011f' +
|
||||||
|
'f81b00f81c02f81d03f819041c6f000d' +
|
||||||
|
'fb3cfb6efa7cfa1605e911b8f1120003' +
|
||||||
|
'01010813183030312e30303754696d65' +
|
||||||
|
'7320526f6d616e54696d657300000002' +
|
||||||
|
'010102030e0e7d99f92a99fb7695f773' +
|
||||||
|
'8b06f79a93fc7c8c077d99f85695f75e' +
|
||||||
|
'9908fb6e8cf87393f7108b09a70adf0b' +
|
||||||
|
'f78e14';
|
||||||
|
var fontData = [];
|
||||||
|
for (var i = 0; i < exampleFont.length; i += 2) {
|
||||||
|
var hex = exampleFont.substr(i, 2);
|
||||||
|
fontData.push(parseInt(hex, 16));
|
||||||
|
}
|
||||||
|
var bytes = new Uint8Array(fontData);
|
||||||
|
fontData = {getBytes: function() { return bytes}};
|
||||||
|
|
||||||
|
function bytesToString(bytesArray) {
|
||||||
|
var str = '';
|
||||||
|
for (var i = 0, ii = bytesArray.length; i < ii; i++)
|
||||||
|
str += String.fromCharCode(bytesArray[i]);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('CFFParser', function() {
|
||||||
|
var parser = new CFFParser(fontData);
|
||||||
|
var cff = parser.parse();
|
||||||
|
|
||||||
|
it('parses header', function() {
|
||||||
|
var header = cff.header;
|
||||||
|
expect(header.major).toEqual(1);
|
||||||
|
expect(header.minor).toEqual(0);
|
||||||
|
expect(header.hdrSize).toEqual(4);
|
||||||
|
expect(header.offSize).toEqual(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parses name index', function() {
|
||||||
|
var names = cff.names;
|
||||||
|
expect(names.length).toEqual(1);
|
||||||
|
expect(names[0]).toEqual('ABCDEF+Times-Roman');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('sanitizes name index', function() {
|
||||||
|
var index = new CFFIndex();
|
||||||
|
index.add(['['.charCodeAt(0), 'a'.charCodeAt(0)]);
|
||||||
|
|
||||||
|
var names = parser.parseNameIndex(index);
|
||||||
|
expect(names).toEqual(['_a']);
|
||||||
|
|
||||||
|
index = new CFFIndex();
|
||||||
|
var longName = [];
|
||||||
|
for (var i = 0; i < 129; i++)
|
||||||
|
longName.push(0);
|
||||||
|
index.add(longName);
|
||||||
|
names = parser.parseNameIndex(index);
|
||||||
|
expect(names[0].length).toEqual(127);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parses string index', function() {
|
||||||
|
var strings = cff.strings;
|
||||||
|
expect(strings.count).toEqual(3);
|
||||||
|
expect(strings.get(0)).toEqual('.notdef');
|
||||||
|
expect(strings.get(391)).toEqual('001.007');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parses top dict', function() {
|
||||||
|
var topDict = cff.topDict;
|
||||||
|
// 391 version 392 FullName 393 FamilyName 389 Weight 28416 UniqueID
|
||||||
|
// -168 -218 1000 898 FontBBox 94 CharStrings 45 102 Private
|
||||||
|
expect(topDict.getByName('version')).toEqual(391);
|
||||||
|
expect(topDict.getByName('FullName')).toEqual(392);
|
||||||
|
expect(topDict.getByName('FamilyName')).toEqual(393);
|
||||||
|
expect(topDict.getByName('Weight')).toEqual(389);
|
||||||
|
expect(topDict.getByName('UniqueID')).toEqual(28416);
|
||||||
|
expect(topDict.getByName('FontBBox')).toEqual([-168, -218, 1000, 898]);
|
||||||
|
expect(topDict.getByName('CharStrings')).toEqual(94);
|
||||||
|
expect(topDict.getByName('Private')).toEqual([45, 102]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parses predefined charsets', function() {
|
||||||
|
var charset = parser.parseCharsets(0, 0, null, true);
|
||||||
|
expect(charset.predefined).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parses charset format 0', function() {
|
||||||
|
// The first three bytes make the offset large enough to skip predefined.
|
||||||
|
var bytes = new Uint8Array([0x00, 0x00, 0x00,
|
||||||
|
0x00, // format
|
||||||
|
0x00, 0x02 // sid/cid
|
||||||
|
]);
|
||||||
|
parser.bytes = bytes;
|
||||||
|
var charset = parser.parseCharsets(3, 2, new CFFStrings(), false);
|
||||||
|
expect(charset.charset[1]).toEqual('exclam');
|
||||||
|
|
||||||
|
// CID font
|
||||||
|
var charset = parser.parseCharsets(3, 2, new CFFStrings(), true);
|
||||||
|
expect(charset.charset[1]).toEqual(2);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parses charset format 1', function() {
|
||||||
|
// The first three bytes make the offset large enough to skip predefined.
|
||||||
|
var bytes = new Uint8Array([0x00, 0x00, 0x00,
|
||||||
|
0x01, // format
|
||||||
|
0x00, 0x08, // sid/cid start
|
||||||
|
0x01 // sid/cid left
|
||||||
|
]);
|
||||||
|
parser.bytes = bytes;
|
||||||
|
var charset = parser.parseCharsets(3, 2, new CFFStrings(), false);
|
||||||
|
expect(charset.charset).toEqual(['.notdef', 'quoteright', 'parenleft']);
|
||||||
|
|
||||||
|
// CID font
|
||||||
|
var charset = parser.parseCharsets(3, 2, new CFFStrings(), true);
|
||||||
|
expect(charset.charset).toEqual(['.notdef', 8, 9]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parses charset format 2', function() {
|
||||||
|
// format 2 is the same as format 1 but the left is card16
|
||||||
|
// The first three bytes make the offset large enough to skip predefined.
|
||||||
|
var bytes = new Uint8Array([0x00, 0x00, 0x00,
|
||||||
|
0x02, // format
|
||||||
|
0x00, 0x08, // sid/cid start
|
||||||
|
0x00, 0x01 // sid/cid left
|
||||||
|
]);
|
||||||
|
parser.bytes = bytes;
|
||||||
|
var charset = parser.parseCharsets(3, 2, new CFFStrings(), false);
|
||||||
|
expect(charset.charset).toEqual(['.notdef', 'quoteright', 'parenleft']);
|
||||||
|
|
||||||
|
// CID font
|
||||||
|
var charset = parser.parseCharsets(3, 2, new CFFStrings(), true);
|
||||||
|
expect(charset.charset).toEqual(['.notdef', 8, 9]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parses encoding format 0', function() {
|
||||||
|
// The first two bytes make the offset large enough to skip predefined.
|
||||||
|
var bytes = new Uint8Array([0x00, 0x00,
|
||||||
|
0x00, // format
|
||||||
|
0x01, // count
|
||||||
|
0x08 // start
|
||||||
|
]);
|
||||||
|
parser.bytes = bytes;
|
||||||
|
var encoding = parser.parseEncoding(2, {}, new CFFStrings(), null);
|
||||||
|
expect(encoding.encoding).toEqual({0x8: 1});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parses encoding format 1', function() {
|
||||||
|
// The first two bytes make the offset large enough to skip predefined.
|
||||||
|
var bytes = new Uint8Array([0x00, 0x00,
|
||||||
|
0x01, // format
|
||||||
|
0x01, // num ranges
|
||||||
|
0x07, // range1 start
|
||||||
|
0x01 // range2 left
|
||||||
|
]);
|
||||||
|
parser.bytes = bytes;
|
||||||
|
var encoding = parser.parseEncoding(2, {}, new CFFStrings(), null);
|
||||||
|
expect(encoding.encoding).toEqual({0x7: 0x01, 0x08: 0x02});
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parses fdselect format 0', function() {
|
||||||
|
var bytes = new Uint8Array([0x00, // format
|
||||||
|
0x00, // gid: 0 fd: 0
|
||||||
|
0x01 // gid: 1 fd: 1
|
||||||
|
]);
|
||||||
|
parser.bytes = bytes;
|
||||||
|
var fdSelect = parser.parseFDSelect(0, 2);
|
||||||
|
expect(fdSelect.fdSelect).toEqual([0, 1]);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('parses fdselect format 3', function() {
|
||||||
|
var bytes = new Uint8Array([0x03, // format
|
||||||
|
0x00, 0x02, // range count
|
||||||
|
0x00, 0x00, // first gid
|
||||||
|
0x09, // font dict 1 id
|
||||||
|
0x00, 0x02, // nex gid
|
||||||
|
0x0a, // font dict 2 gid
|
||||||
|
0x00, 0x04 // sentinel (last gid)
|
||||||
|
]);
|
||||||
|
parser.bytes = bytes;
|
||||||
|
var fdSelect = parser.parseFDSelect(0, 2);
|
||||||
|
expect(fdSelect.fdSelect).toEqual([9, 9, 0xa, 0xa]);
|
||||||
|
});
|
||||||
|
// TODO fdArray
|
||||||
|
});
|
||||||
|
describe('CFFCompiler', function() {
|
||||||
|
it('encodes integers', function() {
|
||||||
|
var c = new CFFCompiler();
|
||||||
|
// all the examples from the spec
|
||||||
|
expect(c.encodeInteger(0)).toEqual([0x8b]);
|
||||||
|
expect(c.encodeInteger(100)).toEqual([0xef]);
|
||||||
|
expect(c.encodeInteger(-100)).toEqual([0x27]);
|
||||||
|
expect(c.encodeInteger(1000)).toEqual([0xfa, 0x7c]);
|
||||||
|
expect(c.encodeInteger(-1000)).toEqual([0xfe, 0x7c]);
|
||||||
|
expect(c.encodeInteger(10000)).toEqual([0x1c, 0x27, 0x10]);
|
||||||
|
expect(c.encodeInteger(-10000)).toEqual([0x1c, 0xd8, 0xf0]);
|
||||||
|
expect(c.encodeInteger(100000)).toEqual([0x1d, 0x00, 0x01, 0x86, 0xa0]);
|
||||||
|
expect(c.encodeInteger(-100000)).toEqual([0x1d, 0xff, 0xfe, 0x79, 0x60]);
|
||||||
|
});
|
||||||
|
it('encodes floats', function() {
|
||||||
|
var c = new CFFCompiler();
|
||||||
|
expect(c.encodeFloat(-2.25)).toEqual([0x1e, 0xe2, 0xa2, 0x5f]);
|
||||||
|
expect(c.encodeFloat(5e-11)).toEqual([0x1e, 0x5c, 0x11, 0xff]);
|
||||||
|
});
|
||||||
|
// TODO a lot more compiler tests
|
||||||
|
});
|
||||||
|
});
|
@ -25,6 +25,7 @@ load:
|
|||||||
- ../../src/bidi.js
|
- ../../src/bidi.js
|
||||||
- ../../external/jpgjs/jpg.js
|
- ../../external/jpgjs/jpg.js
|
||||||
- ../unit/obj_spec.js
|
- ../unit/obj_spec.js
|
||||||
|
- ../unit/font_spec.js
|
||||||
- ../unit/function_spec.js
|
- ../unit/function_spec.js
|
||||||
- ../unit/crypto_spec.js
|
- ../unit/crypto_spec.js
|
||||||
- ../unit/stream_spec.js
|
- ../unit/stream_spec.js
|
||||||
|
Loading…
Reference in New Issue
Block a user