Merge branch 'master' into issue-1090
This commit is contained in:
commit
51d7ad06c4
1
Makefile
1
Makefile
@ -36,6 +36,7 @@ PDF_JS_FILES = \
|
|||||||
stream.js \
|
stream.js \
|
||||||
worker.js \
|
worker.js \
|
||||||
../external/jpgjs/jpg.js \
|
../external/jpgjs/jpg.js \
|
||||||
|
jpx.js \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
# make server
|
# make server
|
||||||
|
28
README.md
28
README.md
@ -1,9 +1,6 @@
|
|||||||
# pdf.js
|
# PDF.JS
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Overview
|
|
||||||
|
|
||||||
pdf.js is an HTML5 technology experiment that explores building a faithful
|
pdf.js is an HTML5 technology experiment that explores building a faithful
|
||||||
and efficient Portable Document Format (PDF) renderer without native code
|
and efficient Portable Document Format (PDF) renderer without native code
|
||||||
assistance.
|
assistance.
|
||||||
@ -16,7 +13,7 @@ successful.
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Getting started
|
# Getting started
|
||||||
|
|
||||||
### Online demo
|
### Online demo
|
||||||
|
|
||||||
@ -29,11 +26,12 @@ using the pdf.js API.
|
|||||||
|
|
||||||
### Extension
|
### Extension
|
||||||
|
|
||||||
An up-to-date Firefox extension is also available:
|
A Firefox extension is also available:
|
||||||
|
|
||||||
+ http://mozilla.github.com/pdf.js/extensions/firefox/pdf.js.xpi
|
+ http://mozilla.github.com/pdf.js/extensions/firefox/pdf.js.xpi
|
||||||
|
|
||||||
(The above link is updated upon every merge to our master branch).
|
Note that this extension is self-updating, and by default Firefox will auto-update extensions on a
|
||||||
|
daily basis (you can change this through the `extensions.update.interval` option in `about:config`).
|
||||||
|
|
||||||
For an experimental Chrome extension, get the code as explained below and issue `make extension`.
|
For an experimental Chrome extension, get the code as explained below and issue `make extension`.
|
||||||
Then open Chrome with the flag `--enable-experimental-extension-apis`, go to `Tools > Extension`
|
Then open Chrome with the flag `--enable-experimental-extension-apis`, go to `Tools > Extension`
|
||||||
@ -68,12 +66,12 @@ In order to bundle all `src/` files into a final `pdf.js`, issue:
|
|||||||
This will generate the file `build/pdf.js` that can be included in your final project. (WARNING: That's a large file! Consider minifying it).
|
This will generate the file `build/pdf.js` that can be included in your final project. (WARNING: That's a large file! Consider minifying it).
|
||||||
|
|
||||||
|
|
||||||
## Learning
|
# Learning
|
||||||
|
|
||||||
Here are some initial pointers to help contributors get off the ground.
|
Here are some initial pointers to help contributors get off the ground.
|
||||||
Additional resources are available in a separate section below.
|
Additional resources are available in a separate section below.
|
||||||
|
|
||||||
#### Hello world
|
### Hello world
|
||||||
|
|
||||||
For a "hello world" example, take a look at:
|
For a "hello world" example, take a look at:
|
||||||
|
|
||||||
@ -82,7 +80,7 @@ For a "hello world" example, take a look at:
|
|||||||
This example illustrates the bare minimum ingredients for integrating pdf.js
|
This example illustrates the bare minimum ingredients for integrating pdf.js
|
||||||
in a custom project.
|
in a custom project.
|
||||||
|
|
||||||
#### Introductory video
|
### Introductory video
|
||||||
|
|
||||||
Check out the presentation by our contributor Julian Viereck on the inner
|
Check out the presentation by our contributor Julian Viereck on the inner
|
||||||
workings of PDF and pdf.js:
|
workings of PDF and pdf.js:
|
||||||
@ -92,7 +90,7 @@ workings of PDF and pdf.js:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Contributing
|
# Contributing
|
||||||
|
|
||||||
pdf.js is a community-driven project, so contributors are always welcome.
|
pdf.js is a community-driven project, so contributors are always welcome.
|
||||||
Simply fork our repo and contribute away. Good starting places for picking
|
Simply fork our repo and contribute away. Good starting places for picking
|
||||||
@ -122,7 +120,7 @@ You can add your name to it! :)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Running the tests
|
# Running the tests
|
||||||
|
|
||||||
pdf.js comes with browser-level regression tests that allow one to probe
|
pdf.js comes with browser-level regression tests that allow one to probe
|
||||||
whether it's able to successfully parse PDFs, as well as compare its output
|
whether it's able to successfully parse PDFs, as well as compare its output
|
||||||
@ -148,7 +146,7 @@ images. The test type `load` simply tests whether the file loads without
|
|||||||
raising any errors.
|
raising any errors.
|
||||||
|
|
||||||
|
|
||||||
## Running tests through our bot
|
### Running tests through our bot
|
||||||
|
|
||||||
If you are a reviewer, you can use our remote bot to issue comprehensive tests
|
If you are a reviewer, you can use our remote bot to issue comprehensive tests
|
||||||
against reference images before merging pull requests.
|
against reference images before merging pull requests.
|
||||||
@ -158,7 +156,7 @@ See the bot repo for details:
|
|||||||
+ https://github.com/mozilla/pdf.js-bot
|
+ https://github.com/mozilla/pdf.js-bot
|
||||||
|
|
||||||
|
|
||||||
## Additional resources
|
# Additional resources
|
||||||
|
|
||||||
Gallery of user projects and modifications:
|
Gallery of user projects and modifications:
|
||||||
|
|
||||||
@ -188,7 +186,7 @@ Follow us on twitter: @pdfjs
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
## PDF-related resources
|
### PDF-related resources
|
||||||
|
|
||||||
A really basic overview of PDF is described here:
|
A really basic overview of PDF is described here:
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
<script type="text/javascript" src="../../src/stream.js"></script>
|
<script type="text/javascript" src="../../src/stream.js"></script>
|
||||||
<script type="text/javascript" src="../../src/worker.js"></script>
|
<script type="text/javascript" src="../../src/worker.js"></script>
|
||||||
<script type="text/javascript" src="../../external/jpgjs/jpg.js"></script>
|
<script type="text/javascript" src="../../external/jpgjs/jpg.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/jpx.js"></script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
// Specify the main script used to create a new PDF.JS web worker.
|
// Specify the main script used to create a new PDF.JS web worker.
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
<script type="text/javascript" src="../../src/stream.js"></script>
|
<script type="text/javascript" src="../../src/stream.js"></script>
|
||||||
<script type="text/javascript" src="../../src/worker.js"></script>
|
<script type="text/javascript" src="../../src/worker.js"></script>
|
||||||
<script type="text/javascript" src="../../external/jpgjs/jpg.js"></script>
|
<script type="text/javascript" src="../../external/jpgjs/jpg.js"></script>
|
||||||
|
<script type="text/javascript" src="../../src/jpx.js"></script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
// Specify the main script used to create a new PDF.JS web worker.
|
// Specify the main script used to create a new PDF.JS web worker.
|
||||||
|
10
src/fonts.js
10
src/fonts.js
@ -3340,15 +3340,9 @@ var Type2CFF = (function Type2CFFClosure() {
|
|||||||
inverseEncoding[encoding[charcode]] = charcode | 0;
|
inverseEncoding[encoding[charcode]] = charcode | 0;
|
||||||
for (var i = 0, ii = charsets.length; i < ii; i++) {
|
for (var i = 0, ii = charsets.length; i < ii; i++) {
|
||||||
var glyph = charsets[i];
|
var glyph = charsets[i];
|
||||||
if (glyph == '.notdef') {
|
if (glyph == '.notdef')
|
||||||
charstrings.push({
|
|
||||||
unicode: 0,
|
|
||||||
code: 0,
|
|
||||||
gid: i,
|
|
||||||
glyph: glyph
|
|
||||||
});
|
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
var code = inverseEncoding[i];
|
var code = inverseEncoding[i];
|
||||||
if (!code || isSpecialUnicode(code)) {
|
if (!code || isSpecialUnicode(code)) {
|
||||||
unassignedUnicodeItems.push(i);
|
unassignedUnicodeItems.push(i);
|
||||||
|
1854
src/jpx.js
Normal file
1854
src/jpx.js
Normal file
File diff suppressed because it is too large
Load Diff
@ -240,6 +240,10 @@ var Parser = (function ParserClosure() {
|
|||||||
var bytes = stream.getBytes(length);
|
var bytes = stream.getBytes(length);
|
||||||
return new JpegStream(bytes, stream.dict, this.xref);
|
return new JpegStream(bytes, stream.dict, this.xref);
|
||||||
}
|
}
|
||||||
|
if (name == 'JPXDecode' || name == 'JPX') {
|
||||||
|
var bytes = stream.getBytes(length);
|
||||||
|
return new JpxStream(bytes, stream.dict);
|
||||||
|
}
|
||||||
if (name == 'ASCII85Decode' || name == 'A85') {
|
if (name == 'ASCII85Decode' || name == 'A85') {
|
||||||
return new Ascii85Stream(stream);
|
return new Ascii85Stream(stream);
|
||||||
}
|
}
|
||||||
@ -249,6 +253,9 @@ var Parser = (function ParserClosure() {
|
|||||||
if (name == 'CCITTFaxDecode' || name == 'CCF') {
|
if (name == 'CCITTFaxDecode' || name == 'CCF') {
|
||||||
return new CCITTFaxStream(stream, params);
|
return new CCITTFaxStream(stream, params);
|
||||||
}
|
}
|
||||||
|
if (name == 'RunLengthDecode') {
|
||||||
|
return new RunLengthStream(stream);
|
||||||
|
}
|
||||||
warn('filter "' + name + '" not supported yet');
|
warn('filter "' + name + '" not supported yet');
|
||||||
return stream;
|
return stream;
|
||||||
}
|
}
|
||||||
|
148
src/stream.js
148
src/stream.js
@ -835,7 +835,7 @@ var JpegStream = (function JpegStreamClosure() {
|
|||||||
return bytesToString(this.bytes);
|
return bytesToString(this.bytes);
|
||||||
};
|
};
|
||||||
JpegStream.prototype.getChar = function jpegStreamGetChar() {
|
JpegStream.prototype.getChar = function jpegStreamGetChar() {
|
||||||
error('internal error: getChar is not valid on JpegStream');
|
error('internal error: getChar is not valid on JpegStream');
|
||||||
};
|
};
|
||||||
/**
|
/**
|
||||||
* Checks if the image can be decoded and displayed by the browser without any
|
* Checks if the image can be decoded and displayed by the browser without any
|
||||||
@ -869,6 +869,107 @@ var JpegStream = (function JpegStreamClosure() {
|
|||||||
return JpegStream;
|
return JpegStream;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For JPEG 2000's we use a library to decode these images and
|
||||||
|
* the stream behaves like all the other DecodeStreams.
|
||||||
|
*/
|
||||||
|
var JpxStream = (function JpxStreamClosure() {
|
||||||
|
function JpxStream(bytes, dict) {
|
||||||
|
this.dict = dict;
|
||||||
|
this.bytes = bytes;
|
||||||
|
|
||||||
|
DecodeStream.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
JpxStream.prototype = Object.create(DecodeStream.prototype);
|
||||||
|
|
||||||
|
JpxStream.prototype.ensureBuffer = function jpxStreamEnsureBuffer(req) {
|
||||||
|
if (this.bufferLength)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var jpxImage = new JpxImage();
|
||||||
|
jpxImage.parse(this.bytes);
|
||||||
|
|
||||||
|
var width = jpxImage.width;
|
||||||
|
var height = jpxImage.height;
|
||||||
|
var componentsCount = jpxImage.componentsCount;
|
||||||
|
if (componentsCount != 1 && componentsCount != 3 && componentsCount != 4)
|
||||||
|
error('JPX with ' + componentsCount + ' components is not supported');
|
||||||
|
|
||||||
|
var data = new Uint8Array(width * height * componentsCount);
|
||||||
|
|
||||||
|
for (var k = 0, kk = jpxImage.tiles.length; k < kk; k++) {
|
||||||
|
var tileCompoments = jpxImage.tiles[k];
|
||||||
|
var tileWidth = tileCompoments[0].width;
|
||||||
|
var tileHeight = tileCompoments[0].height;
|
||||||
|
var tileLeft = tileCompoments[0].left;
|
||||||
|
var tileTop = tileCompoments[0].top;
|
||||||
|
|
||||||
|
var dataPosition, sourcePosition, data0, data1, data2, data3, rowFeed;
|
||||||
|
switch (componentsCount) {
|
||||||
|
case 1:
|
||||||
|
data0 = tileCompoments[0].items;
|
||||||
|
|
||||||
|
dataPosition = width * tileTop + tileLeft;
|
||||||
|
rowFeed = width - tileWidth;
|
||||||
|
sourcePosition = 0;
|
||||||
|
for (var j = 0; j < tileHeight; j++) {
|
||||||
|
for (var i = 0; i < tileWidth; i++)
|
||||||
|
data[dataPosition++] = data0[sourcePosition++];
|
||||||
|
dataPosition += rowFeed;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
data0 = tileCompoments[0].items;
|
||||||
|
data1 = tileCompoments[1].items;
|
||||||
|
data2 = tileCompoments[2].items;
|
||||||
|
|
||||||
|
dataPosition = (width * tileTop + tileLeft) * 3;
|
||||||
|
rowFeed = (width - tileWidth) * 3;
|
||||||
|
sourcePosition = 0;
|
||||||
|
for (var j = 0; j < tileHeight; j++) {
|
||||||
|
for (var i = 0; i < tileWidth; i++) {
|
||||||
|
data[dataPosition++] = data0[sourcePosition];
|
||||||
|
data[dataPosition++] = data1[sourcePosition];
|
||||||
|
data[dataPosition++] = data2[sourcePosition];
|
||||||
|
sourcePosition++;
|
||||||
|
}
|
||||||
|
dataPosition += rowFeed;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
data0 = tileCompoments[0].items;
|
||||||
|
data1 = tileCompoments[1].items;
|
||||||
|
data2 = tileCompoments[2].items;
|
||||||
|
data3 = tileCompoments[3].items;
|
||||||
|
|
||||||
|
dataPosition = (width * tileTop + tileLeft) * 4;
|
||||||
|
rowFeed = (width - tileWidth) * 4;
|
||||||
|
sourcePosition = 0;
|
||||||
|
for (var j = 0; j < tileHeight; j++) {
|
||||||
|
for (var i = 0; i < tileWidth; i++) {
|
||||||
|
data[dataPosition++] = data0[sourcePosition];
|
||||||
|
data[dataPosition++] = data1[sourcePosition];
|
||||||
|
data[dataPosition++] = data2[sourcePosition];
|
||||||
|
data[dataPosition++] = data3[sourcePosition];
|
||||||
|
sourcePosition++;
|
||||||
|
}
|
||||||
|
dataPosition += rowFeed;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
this.buffer = data;
|
||||||
|
this.bufferLength = data.length;
|
||||||
|
};
|
||||||
|
JpxStream.prototype.getChar = function jpxStreamGetChar() {
|
||||||
|
error('internal error: getChar is not valid on JpxStream');
|
||||||
|
};
|
||||||
|
|
||||||
|
return JpxStream;
|
||||||
|
})();
|
||||||
|
|
||||||
var DecryptStream = (function DecryptStreamClosure() {
|
var DecryptStream = (function DecryptStreamClosure() {
|
||||||
function DecryptStream(str, decrypt) {
|
function DecryptStream(str, decrypt) {
|
||||||
this.str = str;
|
this.str = str;
|
||||||
@ -1041,6 +1142,51 @@ var AsciiHexStream = (function AsciiHexStreamClosure() {
|
|||||||
return AsciiHexStream;
|
return AsciiHexStream;
|
||||||
})();
|
})();
|
||||||
|
|
||||||
|
var RunLengthStream = (function RunLengthStreamClosure() {
|
||||||
|
function RunLengthStream(str) {
|
||||||
|
this.str = str;
|
||||||
|
this.dict = str.dict;
|
||||||
|
|
||||||
|
DecodeStream.call(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
RunLengthStream.prototype = Object.create(DecodeStream.prototype);
|
||||||
|
|
||||||
|
RunLengthStream.prototype.readBlock = function runLengthStreamReadBlock() {
|
||||||
|
// The repeatHeader has following format. The first byte defines type of run
|
||||||
|
// and amount of bytes to repeat/copy: n = 0 through 127 - copy next n bytes
|
||||||
|
// (in addition to the second byte from the header), n = 129 through 255 -
|
||||||
|
// duplicate the second byte from the header (257 - n) times, n = 128 - end.
|
||||||
|
var repeatHeader = this.str.getBytes(2);
|
||||||
|
if (!repeatHeader || repeatHeader.length < 2 || repeatHeader[0] == 128) {
|
||||||
|
this.eof = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var bufferLength = this.bufferLength;
|
||||||
|
var n = repeatHeader[0];
|
||||||
|
if (n < 128) {
|
||||||
|
// copy n bytes
|
||||||
|
var buffer = this.ensureBuffer(bufferLength + n + 1);
|
||||||
|
buffer[bufferLength++] = repeatHeader[1];
|
||||||
|
if (n > 0) {
|
||||||
|
var source = this.str.getBytes(n);
|
||||||
|
buffer.set(source, bufferLength);
|
||||||
|
bufferLength += n;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
n = 257 - n;
|
||||||
|
var b = repeatHeader[1];
|
||||||
|
var buffer = this.ensureBuffer(bufferLength + n + 1);
|
||||||
|
for (var i = 0; i < n; i++)
|
||||||
|
buffer[bufferLength++] = b;
|
||||||
|
}
|
||||||
|
this.bufferLength = bufferLength;
|
||||||
|
};
|
||||||
|
|
||||||
|
return RunLengthStream;
|
||||||
|
})();
|
||||||
|
|
||||||
var CCITTFaxStream = (function CCITTFaxStreamClosure() {
|
var CCITTFaxStream = (function CCITTFaxStreamClosure() {
|
||||||
|
|
||||||
var ccittEOL = -2;
|
var ccittEOL = -2;
|
||||||
|
@ -23,7 +23,8 @@ var files = [
|
|||||||
'pattern.js',
|
'pattern.js',
|
||||||
'stream.js',
|
'stream.js',
|
||||||
'worker.js',
|
'worker.js',
|
||||||
'../external/jpgjs/jpg.js'
|
'../external/jpgjs/jpg.js',
|
||||||
|
'jpx.js'
|
||||||
];
|
];
|
||||||
|
|
||||||
// Load all the files.
|
// Load all the files.
|
||||||
|
1
test/pdfs/.gitignore
vendored
1
test/pdfs/.gitignore
vendored
@ -22,4 +22,5 @@
|
|||||||
!issue918.pdf
|
!issue918.pdf
|
||||||
!smaskdim.pdf
|
!smaskdim.pdf
|
||||||
!type4psfunc.pdf
|
!type4psfunc.pdf
|
||||||
|
!S2.pdf
|
||||||
!zerowidthline.pdf
|
!zerowidthline.pdf
|
||||||
|
2549
test/pdfs/S2.pdf
Normal file
2549
test/pdfs/S2.pdf
Normal file
File diff suppressed because one or more lines are too long
@ -176,7 +176,6 @@
|
|||||||
"md5": "eb7b224107205db4fea9f7df0185f77d",
|
"md5": "eb7b224107205db4fea9f7df0185f77d",
|
||||||
"link": true,
|
"link": true,
|
||||||
"rounds": 1,
|
"rounds": 1,
|
||||||
"skipPages": [12,31],
|
|
||||||
"type": "eq"
|
"type": "eq"
|
||||||
},
|
},
|
||||||
{ "id": "fips197",
|
{ "id": "fips197",
|
||||||
@ -411,6 +410,12 @@
|
|||||||
"link": true,
|
"link": true,
|
||||||
"type": "load"
|
"type": "load"
|
||||||
},
|
},
|
||||||
|
{ "id": "S2-eq",
|
||||||
|
"file": "pdfs/S2.pdf",
|
||||||
|
"md5": "d0b6137846df6e0fe058f234a87fb588",
|
||||||
|
"rounds": 1,
|
||||||
|
"type": "eq"
|
||||||
|
},
|
||||||
{ "id": "issue1055",
|
{ "id": "issue1055",
|
||||||
"file": "pdfs/issue1055.pdf",
|
"file": "pdfs/issue1055.pdf",
|
||||||
"md5": "3ba56c2e48dce81da8669b1b9cf98ff0",
|
"md5": "3ba56c2e48dce81da8669b1b9cf98ff0",
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
<script type="text/javascript" src="/src/stream.js"></script>
|
<script type="text/javascript" src="/src/stream.js"></script>
|
||||||
<script type="text/javascript" src="/src/worker.js"></script>
|
<script type="text/javascript" src="/src/worker.js"></script>
|
||||||
<script type="text/javascript" src="/external/jpgjs/jpg.js"></script>
|
<script type="text/javascript" src="/external/jpgjs/jpg.js"></script>
|
||||||
|
<script type="text/javascript" src="/src/jpx.js"></script>
|
||||||
<script type="text/javascript" src="driver.js"></script>
|
<script type="text/javascript" src="driver.js"></script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
<script type="text/javascript" src="../src/stream.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
<script type="text/javascript" src="../src/stream.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||||
<script type="text/javascript" src="../src/worker.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
<script type="text/javascript" src="../src/worker.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||||
<script type="text/javascript" src="../external/jpgjs/jpg.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
<script type="text/javascript" src="../external/jpgjs/jpg.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||||
|
<script type="text/javascript" src="../src/jpx.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||||
<script type="text/javascript">PDFJS.workerSrc = '../src/worker_loader.js';</script> <!-- PDFJSSCRIPT_REMOVE -->
|
<script type="text/javascript">PDFJS.workerSrc = '../src/worker_loader.js';</script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||||
<script type="text/javascript" src="viewer.js"></script>
|
<script type="text/javascript" src="viewer.js"></script>
|
||||||
|
|
||||||
|
@ -960,22 +960,55 @@ var TextLayerBuilder = function textLayerBuilder(textLayerDiv) {
|
|||||||
var self = this;
|
var self = this;
|
||||||
var textDivs = this.textDivs;
|
var textDivs = this.textDivs;
|
||||||
var textLayerDiv = this.textLayerDiv;
|
var textLayerDiv = this.textLayerDiv;
|
||||||
this.textLayerTimer = setInterval(function renderTextLayer() {
|
var renderTimer = null;
|
||||||
|
var renderingDone = false;
|
||||||
|
var renderInterval = 0;
|
||||||
|
var resumeInterval = 500; // in ms
|
||||||
|
|
||||||
|
// Render the text layer, one div at a time
|
||||||
|
function renderTextLayer() {
|
||||||
if (textDivs.length === 0) {
|
if (textDivs.length === 0) {
|
||||||
clearInterval(self.textLayerTimer);
|
clearInterval(renderTimer);
|
||||||
|
renderingDone = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var textDiv = textDivs.shift();
|
var textDiv = textDivs.shift();
|
||||||
if (textDiv.dataset.textLength >= 1) { // avoid div by zero
|
if (textDiv.dataset.textLength > 0) {
|
||||||
textLayerDiv.appendChild(textDiv);
|
textLayerDiv.appendChild(textDiv);
|
||||||
// Adjust div width (via letterSpacing) to match canvas text
|
|
||||||
// Due to the .offsetWidth calls, this is slow
|
if (textDiv.dataset.textLength > 1) { // avoid div by zero
|
||||||
textDiv.style.letterSpacing =
|
// Adjust div width (via letterSpacing) to match canvas text
|
||||||
((textDiv.dataset.canvasWidth - textDiv.offsetWidth) /
|
// Due to the .offsetWidth calls, this is slow
|
||||||
(textDiv.dataset.textLength - 1)) + 'px';
|
// This needs to come after appending to the DOM
|
||||||
|
textDiv.style.letterSpacing =
|
||||||
|
((textDiv.dataset.canvasWidth - textDiv.offsetWidth) /
|
||||||
|
(textDiv.dataset.textLength - 1)) + 'px';
|
||||||
|
}
|
||||||
|
} // textLength > 0
|
||||||
|
}
|
||||||
|
renderTimer = setInterval(renderTextLayer, renderInterval);
|
||||||
|
|
||||||
|
// Stop rendering when user scrolls. Resume after XXX milliseconds
|
||||||
|
// of no scroll events
|
||||||
|
var scrollTimer = null;
|
||||||
|
function textLayerOnScroll() {
|
||||||
|
if (renderingDone) {
|
||||||
|
window.removeEventListener('scroll', textLayerOnScroll, false);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
}, 0);
|
|
||||||
};
|
// Immediately pause rendering
|
||||||
|
clearInterval(renderTimer);
|
||||||
|
|
||||||
|
clearTimeout(scrollTimer);
|
||||||
|
scrollTimer = setTimeout(function textLayerScrollTimer() {
|
||||||
|
// Resume rendering
|
||||||
|
renderTimer = setInterval(renderTextLayer, renderInterval);
|
||||||
|
}, resumeInterval);
|
||||||
|
}; // textLayerOnScroll
|
||||||
|
|
||||||
|
window.addEventListener('scroll', textLayerOnScroll, false);
|
||||||
|
}; // endLayout
|
||||||
|
|
||||||
this.appendText = function textLayerBuilderAppendText(text,
|
this.appendText = function textLayerBuilderAppendText(text,
|
||||||
fontName, fontSize) {
|
fontName, fontSize) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user