Merge remote-tracking branch 'mozilla/master' into bidi
Conflicts: web/viewer.html
This commit is contained in:
commit
28b4dac2d8
5
Makefile
5
Makefile
@ -60,7 +60,7 @@ test: shell-test browser-test
|
||||
production: | bundle
|
||||
@echo "Preparing web/viewer-production.html"; \
|
||||
cd web; \
|
||||
sed '/PDFJSSCRIPT_REMOVE/d' viewer.html > viewer-1.tmp; \
|
||||
sed '/PDFJSSCRIPT_REMOVE_CORE/d' viewer.html > viewer-1.tmp; \
|
||||
sed '/PDFJSSCRIPT_INCLUDE_BUILD/ r viewer-snippet.html' viewer-1.tmp > viewer-production.html; \
|
||||
rm -f *.tmp; \
|
||||
cd ..
|
||||
@ -216,6 +216,7 @@ EXTENSION_WEB_FILES = \
|
||||
web/viewer.js \
|
||||
web/viewer.html \
|
||||
web/viewer-production.html \
|
||||
web/debugger.js \
|
||||
$(NULL)
|
||||
|
||||
FIREFOX_BUILD_DIR := $(BUILD_DIR)/firefox
|
||||
@ -257,7 +258,7 @@ extension: | production
|
||||
# Modify the viewer so it does all the extension only stuff.
|
||||
@cd $(FIREFOX_BUILD_CONTENT)/web; \
|
||||
sed -i.bak '/PDFJSSCRIPT_INCLUDE_BUNDLE/ r ../build/pdf.js' viewer-snippet-firefox-extension.html; \
|
||||
sed -i.bak '/PDFJSSCRIPT_REMOVE/d' viewer.html; \
|
||||
sed -i.bak '/PDFJSSCRIPT_REMOVE_CORE/d' viewer.html; \
|
||||
sed -i.bak '/PDFJSSCRIPT_REMOVE_FIREFOX_EXTENSION/d' viewer.html; \
|
||||
sed -i.bak '/PDFJSSCRIPT_INCLUDE_FIREFOX_EXTENSION/ r viewer-snippet-firefox-extension.html' viewer.html; \
|
||||
rm -f *.bak;
|
||||
|
@ -37,8 +37,8 @@ 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`.
|
||||
Then open Chrome with the flag `--enable-experimental-extension-apis`, go to `Tools > Extension`
|
||||
and load the (unpackaged) extension from the directory `extensions/chrome`.
|
||||
Then open Chrome, go to `Tools > Extension` and load the (unpackaged) extension
|
||||
from the directory `build/chrome`.
|
||||
|
||||
### Getting the code
|
||||
|
||||
|
@ -3,7 +3,7 @@
|
||||
"version": "0.1",
|
||||
"description": "Read PDF Document",
|
||||
"permissions": [
|
||||
"experimental",
|
||||
"webRequest", "webRequestBlocking",
|
||||
"http://*/*.pdf",
|
||||
"file:///*/*.pdf"
|
||||
],
|
||||
|
@ -1,6 +1,6 @@
|
||||
<!doctype html>
|
||||
<script>
|
||||
chrome.experimental.webRequest.onBeforeRequest.addListener(
|
||||
chrome.webRequest.onBeforeRequest.addListener(
|
||||
function(details) {
|
||||
var viewerPage = 'content/web/viewer.html';
|
||||
var url = chrome.extension.getURL(viewerPage) + '?file=' + details.url;
|
||||
|
@ -17,11 +17,15 @@ var TextRenderingMode = {
|
||||
ADD_TO_PATH: 7
|
||||
};
|
||||
|
||||
// Minimal font size that would be used during canvas fillText operations.
|
||||
var MIN_FONT_SIZE = 1;
|
||||
|
||||
var CanvasExtraState = (function CanvasExtraStateClosure() {
|
||||
function CanvasExtraState(old) {
|
||||
// Are soft masks and alpha values shapes or opacities?
|
||||
this.alphaIsShape = false;
|
||||
this.fontSize = 0;
|
||||
this.fontSizeScale = 1;
|
||||
this.textMatrix = IDENTITY_MATRIX;
|
||||
this.fontMatrix = IDENTITY_MATRIX;
|
||||
this.leading = 0;
|
||||
@ -265,7 +269,8 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
},
|
||||
|
||||
executeIRQueue: function canvasGraphicsExecuteIRQueue(codeIR,
|
||||
executionStartIdx, continueCallback) {
|
||||
executionStartIdx, continueCallback,
|
||||
stepper) {
|
||||
var argsArray = codeIR.argsArray;
|
||||
var fnArray = codeIR.fnArray;
|
||||
var i = executionStartIdx || 0;
|
||||
@ -284,6 +289,11 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
var slowCommands = this.slowCommands;
|
||||
|
||||
while (true) {
|
||||
if (stepper && i === stepper.nextBreakPoint) {
|
||||
stepper.breakIt(i, continueCallback);
|
||||
return i;
|
||||
}
|
||||
|
||||
fnName = fnArray[i];
|
||||
|
||||
if (fnName !== 'dependency') {
|
||||
@ -577,6 +587,9 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
this.current.font = fontObj;
|
||||
this.current.fontSize = size;
|
||||
|
||||
if (fontObj.coded)
|
||||
return; // we don't need ctx.font for Type3 fonts
|
||||
|
||||
var name = fontObj.loadedName || 'sans-serif';
|
||||
var bold = fontObj.black ? (fontObj.bold ? 'bolder' : 'bold') :
|
||||
(fontObj.bold ? 'bold' : 'normal');
|
||||
@ -584,7 +597,16 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
var italic = fontObj.italic ? 'italic' : 'normal';
|
||||
var serif = fontObj.isSerifFont ? 'serif' : 'sans-serif';
|
||||
var typeface = '"' + name + '", ' + serif;
|
||||
var rule = italic + ' ' + bold + ' ' + size + 'px ' + typeface;
|
||||
|
||||
// Some font backends cannot handle fonts below certain size.
|
||||
// Keeping the font at minimal size and using the fontSizeScale to change
|
||||
// the current transformation matrix before the fillText/strokeText.
|
||||
// See https://bugzilla.mozilla.org/show_bug.cgi?id=726227
|
||||
var browserFontSize = size >= MIN_FONT_SIZE ? size : MIN_FONT_SIZE;
|
||||
this.current.fontSizeScale = browserFontSize != MIN_FONT_SIZE ? 1.0 :
|
||||
size / MIN_FONT_SIZE;
|
||||
|
||||
var rule = italic + ' ' + bold + ' ' + browserFontSize + 'px ' + typeface;
|
||||
this.ctx.font = rule;
|
||||
},
|
||||
setTextRenderingMode: function canvasGraphicsSetTextRenderingMode(mode) {
|
||||
@ -647,6 +669,7 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
var font = current.font;
|
||||
var glyphs = font.charsToGlyphs(str);
|
||||
var fontSize = current.fontSize;
|
||||
var fontSizeScale = current.fontSizeScale;
|
||||
var charSpacing = current.charSpacing;
|
||||
var wordSpacing = current.wordSpacing;
|
||||
var textHScale = current.textHScale;
|
||||
@ -710,11 +733,16 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
else
|
||||
lineWidth /= scale;
|
||||
|
||||
ctx.lineWidth = lineWidth;
|
||||
|
||||
if (textSelection)
|
||||
text.geom = this.getTextGeometry();
|
||||
|
||||
if (fontSizeScale != 1.0) {
|
||||
ctx.scale(fontSizeScale, fontSizeScale);
|
||||
lineWidth /= fontSizeScale;
|
||||
}
|
||||
|
||||
ctx.lineWidth = lineWidth;
|
||||
|
||||
var x = 0;
|
||||
for (var i = 0; i < glyphsLength; ++i) {
|
||||
var glyph = glyphs[i];
|
||||
@ -728,20 +756,21 @@ var CanvasGraphics = (function CanvasGraphicsClosure() {
|
||||
var charWidth = glyph.width * fontSize * 0.001 +
|
||||
Util.sign(current.fontMatrix[0]) * charSpacing;
|
||||
|
||||
var scaledX = x / fontSizeScale;
|
||||
switch (textRenderingMode) {
|
||||
default: // other unsupported rendering modes
|
||||
case TextRenderingMode.FILL:
|
||||
case TextRenderingMode.FILL_ADD_TO_PATH:
|
||||
ctx.fillText(char, x, 0);
|
||||
ctx.fillText(char, scaledX, 0);
|
||||
break;
|
||||
case TextRenderingMode.STROKE:
|
||||
case TextRenderingMode.STROKE_ADD_TO_PATH:
|
||||
ctx.strokeText(char, x, 0);
|
||||
ctx.strokeText(char, scaledX, 0);
|
||||
break;
|
||||
case TextRenderingMode.FILL_STROKE:
|
||||
case TextRenderingMode.FILL_STROKE_ADD_TO_PATH:
|
||||
ctx.fillText(char, x, 0);
|
||||
ctx.strokeText(char, x, 0);
|
||||
ctx.fillText(char, scaledX, 0);
|
||||
ctx.strokeText(char, scaledX, 0);
|
||||
break;
|
||||
case TextRenderingMode.INVISIBLE:
|
||||
break;
|
||||
|
39
src/core.js
39
src/core.js
@ -57,6 +57,7 @@ function getPdf(arg, callback) {
|
||||
xhr.send(null);
|
||||
}
|
||||
globalScope.PDFJS.getPdf = getPdf;
|
||||
globalScope.PDFJS.pdfBug = false;
|
||||
|
||||
var Page = (function PageClosure() {
|
||||
function Page(xref, pageNumber, pageDict, ref) {
|
||||
@ -104,25 +105,35 @@ var Page = (function PageClosure() {
|
||||
return shadow(this, 'mediaBox', obj);
|
||||
},
|
||||
get view() {
|
||||
var obj = this.inheritPageProp('CropBox');
|
||||
var cropBox = this.inheritPageProp('CropBox');
|
||||
var view = {
|
||||
x: 0,
|
||||
y: 0,
|
||||
width: this.width,
|
||||
height: this.height
|
||||
};
|
||||
if (!isArray(cropBox) || cropBox.length !== 4)
|
||||
return shadow(this, 'view', view);
|
||||
|
||||
var mediaBox = this.mediaBox;
|
||||
var offsetX = mediaBox[0], offsetY = mediaBox[1];
|
||||
if (isArray(obj) && obj.length == 4) {
|
||||
var tl = this.rotatePoint(obj[0] - offsetX, obj[1] - offsetY);
|
||||
var br = this.rotatePoint(obj[2] - offsetX, obj[3] - offsetY);
|
||||
view.x = Math.min(tl.x, br.x);
|
||||
view.y = Math.min(tl.y, br.y);
|
||||
view.width = Math.abs(tl.x - br.x);
|
||||
view.height = Math.abs(tl.y - br.y);
|
||||
}
|
||||
|
||||
return shadow(this, 'cropBox', view);
|
||||
// From the spec, 6th ed., p.963:
|
||||
// "The crop, bleed, trim, and art boxes should not ordinarily
|
||||
// extend beyond the boundaries of the media box. If they do, they are
|
||||
// effectively reduced to their intersection with the media box."
|
||||
cropBox = Util.intersect(cropBox, mediaBox);
|
||||
if (!cropBox)
|
||||
return shadow(this, 'view', view);
|
||||
|
||||
var tl = this.rotatePoint(cropBox[0] - offsetX, cropBox[1] - offsetY);
|
||||
var br = this.rotatePoint(cropBox[2] - offsetX, cropBox[3] - offsetY);
|
||||
view.x = Math.min(tl.x, br.x);
|
||||
view.y = Math.min(tl.y, br.y);
|
||||
view.width = Math.abs(tl.x - br.x);
|
||||
view.height = Math.abs(tl.y - br.y);
|
||||
|
||||
return shadow(this, 'view', view);
|
||||
},
|
||||
get annotations() {
|
||||
return shadow(this, 'annotations', this.inheritPageProp('Annots'));
|
||||
@ -244,10 +255,16 @@ var Page = (function PageClosure() {
|
||||
var startIdx = 0;
|
||||
var length = this.IRQueue.fnArray.length;
|
||||
var IRQueue = this.IRQueue;
|
||||
var stepper = null;
|
||||
if (PDFJS.pdfBug && StepperManager.enabled) {
|
||||
stepper = StepperManager.create(this.pageNumber);
|
||||
stepper.init(IRQueue);
|
||||
stepper.nextBreakPoint = stepper.getNextBreakPoint();
|
||||
}
|
||||
|
||||
var self = this;
|
||||
function next() {
|
||||
startIdx = gfx.executeIRQueue(IRQueue, startIdx, next);
|
||||
startIdx = gfx.executeIRQueue(IRQueue, startIdx, next, stepper);
|
||||
if (startIdx == length) {
|
||||
self.stats.render = Date.now();
|
||||
gfx.endDrawing();
|
||||
|
84
src/fonts.js
84
src/fonts.js
@ -1565,6 +1565,61 @@ var Font = (function FontClosure() {
|
||||
}
|
||||
};
|
||||
|
||||
function sanitizeGlyph(source, sourceStart, sourceEnd, dest, destStart) {
|
||||
if (sourceEnd - sourceStart <= 12) {
|
||||
// glyph with data less than 12 is invalid one
|
||||
return 0;
|
||||
}
|
||||
var glyf = source.subarray(sourceStart, sourceEnd);
|
||||
var contoursCount = (glyf[0] << 8) | glyf[1];
|
||||
if (contoursCount & 0x8000) {
|
||||
// complex glyph, writing as is
|
||||
dest.set(glyf, destStart);
|
||||
return glyf.length;
|
||||
}
|
||||
|
||||
var j = 10, flagsCount = 0;
|
||||
for (var i = 0; i < contoursCount; i++) {
|
||||
var endPoint = (glyf[j] << 8) | glyf[j + 1];
|
||||
flagsCount = endPoint + 1;
|
||||
j += 2;
|
||||
}
|
||||
// skipping instructions
|
||||
var instructionsLength = (glyf[j] << 8) | glyf[j + 1];
|
||||
j += 2 + instructionsLength;
|
||||
// validating flags
|
||||
var coordinatesLength = 0;
|
||||
for (var i = 0; i < flagsCount; i++) {
|
||||
var flag = glyf[j++];
|
||||
if (flag & 0xC0) {
|
||||
// reserved flags must be zero, rejecting
|
||||
return 0;
|
||||
}
|
||||
var xyLength = ((flag & 2) ? 1 : (flag & 16) ? 0 : 2) +
|
||||
((flag & 4) ? 1 : (flag & 32) ? 0 : 2);
|
||||
coordinatesLength += xyLength;
|
||||
if (flag & 8) {
|
||||
var repeat = glyf[j++];
|
||||
i += repeat;
|
||||
coordinatesLength += repeat * xyLength;
|
||||
}
|
||||
}
|
||||
var glyphDataLength = j + coordinatesLength;
|
||||
if (glyphDataLength > glyf.length) {
|
||||
// not enough data for coordinates
|
||||
return 0;
|
||||
}
|
||||
if (glyf.length - glyphDataLength > 3) {
|
||||
// truncating and aligning to 4 bytes the long glyph data
|
||||
glyphDataLength = (glyphDataLength + 3) & ~3;
|
||||
dest.set(glyf.subarray(0, glyphDataLength), destStart);
|
||||
return glyphDataLength;
|
||||
}
|
||||
// glyph data is fine
|
||||
dest.set(glyf, destStart);
|
||||
return glyf.length;
|
||||
}
|
||||
|
||||
function sanitizeGlyphLocations(loca, glyf, numGlyphs,
|
||||
isGlyphLocationsLong) {
|
||||
var itemSize, itemDecode, itemEncode;
|
||||
@ -1591,21 +1646,21 @@ var Font = (function FontClosure() {
|
||||
};
|
||||
}
|
||||
var locaData = loca.data;
|
||||
// removing the invalid glyphs
|
||||
var oldGlyfData = glyf.data;
|
||||
var newGlyfData = new Uint8Array(oldGlyfData.length);
|
||||
var startOffset = itemDecode(locaData, 0);
|
||||
var firstOffset = itemDecode(locaData, itemSize);
|
||||
if (firstOffset - startOffset < 12 || startOffset > 0) {
|
||||
// removing first glyph
|
||||
glyf.data = glyf.data.subarray(firstOffset);
|
||||
glyf.length -= firstOffset;
|
||||
|
||||
itemEncode(locaData, 0, 0);
|
||||
var i, pos = itemSize;
|
||||
for (i = 1; i <= numGlyphs; ++i) {
|
||||
itemEncode(locaData, pos,
|
||||
itemDecode(locaData, pos) - firstOffset);
|
||||
pos += itemSize;
|
||||
}
|
||||
var writeOffset = 0;
|
||||
itemEncode(locaData, 0, writeOffset);
|
||||
for (var i = 0, j = itemSize; i < numGlyphs; i++, j += itemSize) {
|
||||
var endOffset = itemDecode(locaData, j);
|
||||
var newLength = sanitizeGlyph(oldGlyfData, startOffset, endOffset,
|
||||
newGlyfData, writeOffset);
|
||||
writeOffset += newLength;
|
||||
itemEncode(locaData, j, writeOffset);
|
||||
startOffset = endOffset;
|
||||
}
|
||||
glyf.data = newGlyfData.subarray(0, writeOffset);
|
||||
}
|
||||
|
||||
function readGlyphNameMap(post, properties) {
|
||||
@ -2195,6 +2250,9 @@ var Font = (function FontClosure() {
|
||||
var styleSheet = styleElement.sheet;
|
||||
styleSheet.insertRule(rule, styleSheet.cssRules.length);
|
||||
|
||||
if (PDFJS.pdfBug && FontInspector.enabled)
|
||||
FontInspector.fontAdded(this, url);
|
||||
|
||||
return rule;
|
||||
},
|
||||
|
||||
|
@ -162,6 +162,10 @@ var Parser = (function ParserClosure() {
|
||||
|
||||
return imageStream;
|
||||
},
|
||||
fetchIfRef: function parserFetchIfRef(obj) {
|
||||
// not relying on the xref.fetchIfRef -- xref might not be set
|
||||
return isRef(obj) ? this.xref.fetch(obj) : obj;
|
||||
},
|
||||
makeStream: function parserMakeStream(dict, cipherTransform) {
|
||||
var lexer = this.lexer;
|
||||
var stream = lexer.stream;
|
||||
@ -171,10 +175,7 @@ var Parser = (function ParserClosure() {
|
||||
var pos = stream.pos;
|
||||
|
||||
// get length
|
||||
var length = dict.get('Length');
|
||||
var xref = this.xref;
|
||||
if (xref)
|
||||
length = xref.fetchIfRef(length);
|
||||
var length = this.fetchIfRef(dict.get('Length'));
|
||||
if (!isInt(length)) {
|
||||
error('Bad ' + length + ' attribute in stream');
|
||||
length = 0;
|
||||
@ -196,8 +197,8 @@ var Parser = (function ParserClosure() {
|
||||
return stream;
|
||||
},
|
||||
filter: function parserFilter(stream, dict, length) {
|
||||
var filter = dict.get('Filter', 'F');
|
||||
var params = dict.get('DecodeParms', 'DP');
|
||||
var filter = this.fetchIfRef(dict.get('Filter', 'F'));
|
||||
var params = this.fetchIfRef(dict.get('DecodeParms', 'DP'));
|
||||
if (isName(filter))
|
||||
return this.makeFilter(stream, filter.name, length, params);
|
||||
if (isArray(filter)) {
|
||||
|
@ -623,7 +623,6 @@ var PredictorStream = (function PredictorStreamClosure() {
|
||||
|
||||
var bufferLength = this.bufferLength;
|
||||
var buffer = this.ensureBuffer(bufferLength + rowBytes);
|
||||
var currentRow = buffer.subarray(bufferLength, bufferLength + rowBytes);
|
||||
|
||||
var bits = this.bits;
|
||||
var colors = this.colors;
|
||||
@ -632,6 +631,7 @@ var PredictorStream = (function PredictorStreamClosure() {
|
||||
|
||||
var inbuf = 0, outbuf = 0;
|
||||
var inbits = 0, outbits = 0;
|
||||
var pos = bufferLength;
|
||||
|
||||
if (bits === 1) {
|
||||
for (var i = 0; i < rowBytes; ++i) {
|
||||
@ -639,19 +639,21 @@ var PredictorStream = (function PredictorStreamClosure() {
|
||||
inbuf = (inbuf << 8) | c;
|
||||
// bitwise addition is exclusive or
|
||||
// first shift inbuf and then add
|
||||
currentRow[i] = (c ^ (inbuf >> colors)) & 0xFF;
|
||||
buffer[pos++] = (c ^ (inbuf >> colors)) & 0xFF;
|
||||
// truncate inbuf (assumes colors < 16)
|
||||
inbuf &= 0xFFFF;
|
||||
}
|
||||
} else if (bits === 8) {
|
||||
for (var i = 0; i < colors; ++i)
|
||||
currentRow[i] = rawBytes[i];
|
||||
for (; i < rowBytes; ++i)
|
||||
currentRow[i] = currentRow[i - colors] + rawBytes[i];
|
||||
buffer[pos++] = rawBytes[i];
|
||||
for (; i < rowBytes; ++i) {
|
||||
buffer[pos] = buffer[pos - colors] + rawBytes[i];
|
||||
pos++;
|
||||
}
|
||||
} else {
|
||||
var compArray = new Uint8Array(colors + 1);
|
||||
var bitMask = (1 << bits) - 1;
|
||||
var j = 0, k = 0;
|
||||
var j = 0, k = bufferLength;
|
||||
var columns = this.columns;
|
||||
for (var i = 0; i < columns; ++i) {
|
||||
for (var kk = 0; kk < colors; ++kk) {
|
||||
@ -665,13 +667,13 @@ var PredictorStream = (function PredictorStreamClosure() {
|
||||
outbuf = (outbuf << bits) | compArray[kk];
|
||||
outbits += bits;
|
||||
if (outbits >= 8) {
|
||||
currentRow[k++] = (outbuf >> (outbits - 8)) & 0xFF;
|
||||
buffer[k++] = (outbuf >> (outbits - 8)) & 0xFF;
|
||||
outbits -= 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (outbits > 0) {
|
||||
currentRow[k++] = (outbuf << (8 - outbits)) +
|
||||
buffer[k++] = (outbuf << (8 - outbits)) +
|
||||
(inbuf & ((1 << (8 - outbits)) - 1));
|
||||
}
|
||||
}
|
||||
@ -690,32 +692,35 @@ var PredictorStream = (function PredictorStreamClosure() {
|
||||
var bufferLength = this.bufferLength;
|
||||
var buffer = this.ensureBuffer(bufferLength + rowBytes);
|
||||
|
||||
var currentRow = buffer.subarray(bufferLength, bufferLength + rowBytes);
|
||||
var prevRow = buffer.subarray(bufferLength - rowBytes, bufferLength);
|
||||
if (prevRow.length == 0)
|
||||
prevRow = new Uint8Array(rowBytes);
|
||||
|
||||
var j = bufferLength;
|
||||
switch (predictor) {
|
||||
case 0:
|
||||
for (var i = 0; i < rowBytes; ++i)
|
||||
currentRow[i] = rawBytes[i];
|
||||
buffer[j++] = rawBytes[i];
|
||||
break;
|
||||
case 1:
|
||||
for (var i = 0; i < pixBytes; ++i)
|
||||
currentRow[i] = rawBytes[i];
|
||||
for (; i < rowBytes; ++i)
|
||||
currentRow[i] = (currentRow[i - pixBytes] + rawBytes[i]) & 0xFF;
|
||||
buffer[j++] = rawBytes[i];
|
||||
for (; i < rowBytes; ++i) {
|
||||
buffer[j] = (buffer[j - pixBytes] + rawBytes[i]) & 0xFF;
|
||||
j++;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
for (var i = 0; i < rowBytes; ++i)
|
||||
currentRow[i] = (prevRow[i] + rawBytes[i]) & 0xFF;
|
||||
buffer[j++] = (prevRow[i] + rawBytes[i]) & 0xFF;
|
||||
break;
|
||||
case 3:
|
||||
for (var i = 0; i < pixBytes; ++i)
|
||||
currentRow[i] = (prevRow[i] >> 1) + rawBytes[i];
|
||||
buffer[j++] = (prevRow[i] >> 1) + rawBytes[i];
|
||||
for (; i < rowBytes; ++i) {
|
||||
currentRow[i] = (((prevRow[i] + currentRow[i - pixBytes]) >> 1) +
|
||||
buffer[j] = (((prevRow[i] + buffer[j - pixBytes]) >> 1) +
|
||||
rawBytes[i]) & 0xFF;
|
||||
j++;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
@ -724,12 +729,12 @@ var PredictorStream = (function PredictorStreamClosure() {
|
||||
for (var i = 0; i < pixBytes; ++i) {
|
||||
var up = prevRow[i];
|
||||
var c = rawBytes[i];
|
||||
currentRow[i] = up + c;
|
||||
buffer[j++] = up + c;
|
||||
}
|
||||
for (; i < rowBytes; ++i) {
|
||||
var up = prevRow[i];
|
||||
var upLeft = prevRow[i - pixBytes];
|
||||
var left = currentRow[i - pixBytes];
|
||||
var left = buffer[j - pixBytes];
|
||||
var p = left + up - upLeft;
|
||||
|
||||
var pa = p - left;
|
||||
@ -744,11 +749,11 @@ var PredictorStream = (function PredictorStreamClosure() {
|
||||
|
||||
var c = rawBytes[i];
|
||||
if (pa <= pb && pa <= pc)
|
||||
currentRow[i] = left + c;
|
||||
buffer[j++] = left + c;
|
||||
else if (pb <= pc)
|
||||
currentRow[i] = up + c;
|
||||
buffer[j++] = up + c;
|
||||
else
|
||||
currentRow[i] = upLeft + c;
|
||||
buffer[j++] = upLeft + c;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
56
src/util.js
56
src/util.js
@ -111,6 +111,62 @@ var Util = (function UtilClosure() {
|
||||
];
|
||||
}
|
||||
|
||||
// Normalize rectangle rect=[x1, y1, x2, y2] so that (x1,y1) < (x2,y2)
|
||||
// For coordinate systems whose origin lies in the bottom-left, this
|
||||
// means normalization to (BL,TR) ordering. For systems with origin in the
|
||||
// top-left, this means (TL,BR) ordering.
|
||||
Util.normalizeRect = function normalizeRect(rect) {
|
||||
var r = rect.slice(0); // clone rect
|
||||
if (rect[0] > rect[2]) {
|
||||
r[0] = rect[2];
|
||||
r[2] = rect[0];
|
||||
}
|
||||
if (rect[1] > rect[3]) {
|
||||
r[1] = rect[3];
|
||||
r[3] = rect[1];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
// Returns a rectangle [x1, y1, x2, y2] corresponding to the
|
||||
// intersection of rect1 and rect2. If no intersection, returns 'false'
|
||||
// The rectangle coordinates of rect1, rect2 should be [x1, y1, x2, y2]
|
||||
Util.intersect = function intersect(rect1, rect2) {
|
||||
function compare(a, b) {
|
||||
return a - b;
|
||||
};
|
||||
|
||||
// Order points along the axes
|
||||
var orderedX = [rect1[0], rect1[2], rect2[0], rect2[2]].sort(compare),
|
||||
orderedY = [rect1[1], rect1[3], rect2[1], rect2[3]].sort(compare),
|
||||
result = [];
|
||||
|
||||
rect1 = Util.normalizeRect(rect1);
|
||||
rect2 = Util.normalizeRect(rect2);
|
||||
|
||||
// X: first and second points belong to different rectangles?
|
||||
if ((orderedX[0] === rect1[0] && orderedX[1] === rect2[0]) ||
|
||||
(orderedX[0] === rect2[0] && orderedX[1] === rect1[0])) {
|
||||
// Intersection must be between second and third points
|
||||
result[0] = orderedX[1];
|
||||
result[2] = orderedX[2];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Y: first and second points belong to different rectangles?
|
||||
if ((orderedY[0] === rect1[1] && orderedY[1] === rect2[1]) ||
|
||||
(orderedY[0] === rect2[1] && orderedY[1] === rect1[1])) {
|
||||
// Intersection must be between second and third points
|
||||
result[1] = orderedY[1];
|
||||
result[3] = orderedY[2];
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Util.sign = function sign(num) {
|
||||
return num < 0 ? -1 : 1;
|
||||
};
|
||||
|
1
test/pdfs/html5checker.pdf.link
Normal file
1
test/pdfs/html5checker.pdf.link
Normal file
@ -0,0 +1 @@
|
||||
http://hsivonen.iki.fi/thesis/html5-conformance-checker.pdf
|
1
test/pdfs/issue1155.pdf.link
Normal file
1
test/pdfs/issue1155.pdf.link
Normal file
@ -0,0 +1 @@
|
||||
http://www.madbad.altervista.org/_altervista_ht/2142.pdf
|
1
test/pdfs/issue1169.pdf.link
Normal file
1
test/pdfs/issue1169.pdf.link
Normal file
@ -0,0 +1 @@
|
||||
http://www.cs.txstate.edu/~mb92/papers/gpgpu11.pdf
|
@ -14,7 +14,7 @@
|
||||
<Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>3.0</em:minVersion>
|
||||
<em:maxVersion>7.0a1</em:maxVersion>
|
||||
<em:maxVersion>13.0a1</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
|
||||
|
@ -64,7 +64,9 @@ MIMEs = {
|
||||
'.svg': 'image/svg+xml',
|
||||
'.pdf': 'application/pdf',
|
||||
'.xhtml': 'application/xhtml+xml',
|
||||
'.gif': 'image/gif',
|
||||
'.ico': 'image/x-icon',
|
||||
'.png': 'image/png',
|
||||
'.log': 'text/plain'
|
||||
}
|
||||
|
||||
|
@ -438,6 +438,13 @@
|
||||
"link": true,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "issue1169",
|
||||
"file": "pdfs/issue1169.pdf",
|
||||
"md5": "3df3ed21fd43ac7fdb21e2015c8a7809",
|
||||
"rounds": 1,
|
||||
"link": true,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "zerowidthline",
|
||||
"file": "pdfs/zerowidthline.pdf",
|
||||
"md5": "295d26e61a85635433f8e4b768953f60",
|
||||
@ -445,6 +452,14 @@
|
||||
"link": false,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "html5checker",
|
||||
"file": "pdfs/html5checker.pdf",
|
||||
"md5": "74bbd80d1e7eb5f2951582233ef9ebab",
|
||||
"rounds": 1,
|
||||
"pageLimit": 7,
|
||||
"link": true,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "issue1133",
|
||||
"file": "pdfs/issue1133.pdf",
|
||||
"md5": "d1b61580cb100e3df93d33703af1773a",
|
||||
@ -458,5 +473,12 @@
|
||||
"rounds": 1,
|
||||
"link": true,
|
||||
"type": "eq"
|
||||
},
|
||||
{ "id": "issue1155",
|
||||
"file": "pdfs/issue1155.pdf",
|
||||
"md5": "b732ef25c16c9c20a77e40edef5aa6fe",
|
||||
"rounds": 1,
|
||||
"link": true,
|
||||
"type": "eq"
|
||||
}
|
||||
]
|
||||
|
396
web/debugger.js
Normal file
396
web/debugger.js
Normal file
@ -0,0 +1,396 @@
|
||||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||
|
||||
'use strict';
|
||||
|
||||
var FontInspector = (function FontInspectorClosure() {
|
||||
var fonts;
|
||||
var panelWidth = 300;
|
||||
var active = false;
|
||||
var fontAttribute = 'data-font-name';
|
||||
function removeSelection() {
|
||||
var divs = document.querySelectorAll('div[' + fontAttribute + ']');
|
||||
for (var i = 0, ii = divs.length; i < ii; ++i) {
|
||||
var div = divs[i];
|
||||
div.className = '';
|
||||
}
|
||||
}
|
||||
function resetSelection() {
|
||||
var divs = document.querySelectorAll('div[' + fontAttribute + ']');
|
||||
for (var i = 0, ii = divs.length; i < ii; ++i) {
|
||||
var div = divs[i];
|
||||
div.className = 'debuggerHideText';
|
||||
}
|
||||
}
|
||||
function selectFont(fontName, show) {
|
||||
var divs = document.querySelectorAll('div[' + fontAttribute + '=' +
|
||||
fontName + ']');
|
||||
for (var i = 0, ii = divs.length; i < ii; ++i) {
|
||||
var div = divs[i];
|
||||
div.className = show ? 'debuggerShowText' : 'debuggerHideText';
|
||||
}
|
||||
}
|
||||
function textLayerClick(e) {
|
||||
if (!e.target.dataset.fontName || e.target.tagName != 'DIV')
|
||||
return;
|
||||
var fontName = e.target.dataset.fontName;
|
||||
var selects = document.getElementsByTagName('input');
|
||||
for (var i = 0; i < selects.length; ++i) {
|
||||
var select = selects[i];
|
||||
if (select.dataset.fontName != fontName) continue;
|
||||
select.checked = !select.checked;
|
||||
selectFont(fontName, select.checked);
|
||||
select.scrollIntoView();
|
||||
}
|
||||
}
|
||||
return {
|
||||
// Poperties/functions needed by PDFBug.
|
||||
id: 'FontInspector',
|
||||
name: 'Font Inspector',
|
||||
panel: null,
|
||||
manager: null,
|
||||
init: function init() {
|
||||
var panel = this.panel;
|
||||
panel.setAttribute('style', 'padding: 5px;');
|
||||
var tmp = document.createElement('button');
|
||||
tmp.addEventListener('click', resetSelection);
|
||||
tmp.textContent = 'Refresh';
|
||||
panel.appendChild(tmp);
|
||||
|
||||
fonts = document.createElement('div');
|
||||
panel.appendChild(fonts);
|
||||
},
|
||||
enabled: false,
|
||||
get active() {
|
||||
return active;
|
||||
},
|
||||
set active(value) {
|
||||
active = value;
|
||||
if (active) {
|
||||
document.body.addEventListener('click', textLayerClick, true);
|
||||
resetSelection();
|
||||
} else {
|
||||
document.body.removeEventListener('click', textLayerClick, true);
|
||||
removeSelection();
|
||||
}
|
||||
},
|
||||
// FontInspector specific functions.
|
||||
fontAdded: function fontAdded(fontObj, url) {
|
||||
function properties(obj, list) {
|
||||
var moreInfo = document.createElement('table');
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
var tr = document.createElement('tr');
|
||||
var td1 = document.createElement('td');
|
||||
td1.textContent = list[i];
|
||||
tr.appendChild(td1);
|
||||
var td2 = document.createElement('td');
|
||||
td2.textContent = obj[list[i]].toString();
|
||||
tr.appendChild(td2);
|
||||
moreInfo.appendChild(tr);
|
||||
}
|
||||
return moreInfo;
|
||||
}
|
||||
var moreInfo = properties(fontObj, ['name', 'type']);
|
||||
var m = /url\(['"]?([^\)"']+)/.exec(url);
|
||||
var fontName = fontObj.loadedName;
|
||||
var font = document.createElement('div');
|
||||
var name = document.createElement('span');
|
||||
name.textContent = fontName;
|
||||
var download = document.createElement('a');
|
||||
download.href = m[1];
|
||||
download.textContent = 'Download';
|
||||
var logIt = document.createElement('a');
|
||||
logIt.href = '';
|
||||
logIt.textContent = 'Log';
|
||||
logIt.addEventListener('click', function(event) {
|
||||
event.preventDefault();
|
||||
console.log(fontObj);
|
||||
});
|
||||
var select = document.createElement('input');
|
||||
select.setAttribute('type', 'checkbox');
|
||||
select.dataset.fontName = fontName;
|
||||
select.addEventListener('click', (function(select, fontName) {
|
||||
return (function() {
|
||||
selectFont(fontName, select.checked);
|
||||
});
|
||||
})(select, fontName));
|
||||
font.appendChild(select);
|
||||
font.appendChild(name);
|
||||
font.appendChild(document.createTextNode(' '));
|
||||
font.appendChild(download);
|
||||
font.appendChild(document.createTextNode(' '));
|
||||
font.appendChild(logIt);
|
||||
font.appendChild(moreInfo);
|
||||
fonts.appendChild(font);
|
||||
// Somewhat of a hack, should probably add a hook for when the text layer
|
||||
// is done rendering.
|
||||
setTimeout(function() {
|
||||
if (this.active)
|
||||
resetSelection();
|
||||
}.bind(this), 2000);
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
// Manages all the page steppers.
|
||||
var StepperManager = (function StepperManagerClosure() {
|
||||
var steppers = [];
|
||||
var stepperDiv = null;
|
||||
var stepperControls = null;
|
||||
var stepperChooser = null;
|
||||
var breakPoints = {};
|
||||
return {
|
||||
// Poperties/functions needed by PDFBug.
|
||||
id: 'Stepper',
|
||||
name: 'Stepper',
|
||||
panel: null,
|
||||
manager: null,
|
||||
init: function init() {
|
||||
var self = this;
|
||||
this.panel.setAttribute('style', 'padding: 5px;');
|
||||
stepperControls = document.createElement('div');
|
||||
stepperChooser = document.createElement('select');
|
||||
stepperChooser.addEventListener('change', function(event) {
|
||||
self.selectStepper(this.value);
|
||||
});
|
||||
stepperControls.appendChild(stepperChooser);
|
||||
stepperDiv = document.createElement('div');
|
||||
this.panel.appendChild(stepperControls);
|
||||
this.panel.appendChild(stepperDiv);
|
||||
if (sessionStorage.getItem('pdfjsBreakPoints'))
|
||||
breakPoints = JSON.parse(sessionStorage.getItem('pdfjsBreakPoints'));
|
||||
},
|
||||
enabled: false,
|
||||
active: false,
|
||||
// Stepper specific functions.
|
||||
create: function create(pageNumber) {
|
||||
var debug = document.createElement('div');
|
||||
debug.id = 'stepper' + pageNumber;
|
||||
debug.setAttribute('hidden', true);
|
||||
debug.className = 'stepper';
|
||||
stepperDiv.appendChild(debug);
|
||||
var b = document.createElement('option');
|
||||
b.textContent = 'Page ' + (pageNumber + 1);
|
||||
b.value = pageNumber;
|
||||
stepperChooser.appendChild(b);
|
||||
var initBreakPoints = breakPoints[pageNumber] || [];
|
||||
var stepper = new Stepper(debug, pageNumber, initBreakPoints);
|
||||
steppers.push(stepper);
|
||||
if (steppers.length === 1)
|
||||
this.selectStepper(pageNumber, false);
|
||||
return stepper;
|
||||
},
|
||||
selectStepper: function selectStepper(pageNumber, selectPanel) {
|
||||
if (selectPanel)
|
||||
this.manager.selectPanel(1);
|
||||
for (var i = 0; i < steppers.length; ++i) {
|
||||
var stepper = steppers[i];
|
||||
if (stepper.pageNumber == pageNumber)
|
||||
stepper.panel.removeAttribute('hidden');
|
||||
else
|
||||
stepper.panel.setAttribute('hidden', true);
|
||||
}
|
||||
},
|
||||
saveBreakPoints: function saveBreakPoints(pageNumber, bps) {
|
||||
breakPoints[pageNumber] = bps;
|
||||
sessionStorage.setItem('pdfjsBreakPoints', JSON.stringify(breakPoints));
|
||||
}
|
||||
};
|
||||
})();
|
||||
|
||||
// The stepper for each page's IRQueue.
|
||||
var Stepper = (function StepperClosure() {
|
||||
function Stepper(panel, pageNumber, initialBreakPoints) {
|
||||
this.panel = panel;
|
||||
this.len;
|
||||
this.breakPoint = 0;
|
||||
this.nextBreakPoint = null;
|
||||
this.pageNumber = pageNumber;
|
||||
this.breakPoints = initialBreakPoints;
|
||||
this.currentIdx = -1;
|
||||
}
|
||||
Stepper.prototype = {
|
||||
init: function init(IRQueue) {
|
||||
// Shorter way to create element and optionally set textContent.
|
||||
function c(tag, textContent) {
|
||||
var d = document.createElement(tag);
|
||||
if (textContent)
|
||||
d.textContent = textContent;
|
||||
return d;
|
||||
}
|
||||
var panel = this.panel;
|
||||
this.len = IRQueue.fnArray.length;
|
||||
var content = c('div', 'c=continue, s=step');
|
||||
var table = c('table');
|
||||
content.appendChild(table);
|
||||
table.cellSpacing = 0;
|
||||
var headerRow = c('tr');
|
||||
table.appendChild(headerRow);
|
||||
headerRow.appendChild(c('th', 'Break'));
|
||||
headerRow.appendChild(c('th', 'Idx'));
|
||||
headerRow.appendChild(c('th', 'fn'));
|
||||
headerRow.appendChild(c('th', 'args'));
|
||||
|
||||
for (var i = 0; i < IRQueue.fnArray.length; i++) {
|
||||
var line = c('tr');
|
||||
line.className = 'line';
|
||||
line.id = 'idx' + i;
|
||||
table.appendChild(line);
|
||||
var checked = this.breakPoints.indexOf(i) != -1;
|
||||
var args = IRQueue.argsArray[i] ? IRQueue.argsArray[i] : [];
|
||||
|
||||
var breakCell = c('td');
|
||||
var cbox = c('input');
|
||||
cbox.type = 'checkbox';
|
||||
cbox.className = 'points';
|
||||
cbox.checked = checked;
|
||||
var self = this;
|
||||
cbox.onclick = (function(x) {
|
||||
return function() {
|
||||
if (this.checked)
|
||||
self.breakPoints.push(x);
|
||||
else
|
||||
self.breakPoints.splice(self.breakPoints.indexOf(x), 1);
|
||||
StepperManager.saveBreakPoints(self.pageNumber, self.breakPoints);
|
||||
}
|
||||
})(i);
|
||||
|
||||
breakCell.appendChild(cbox);
|
||||
line.appendChild(breakCell);
|
||||
line.appendChild(c('td', i.toString()));
|
||||
line.appendChild(c('td', IRQueue.fnArray[i]));
|
||||
line.appendChild(c('td', args.join(', ')));
|
||||
}
|
||||
panel.appendChild(content);
|
||||
var self = this;
|
||||
},
|
||||
getNextBreakPoint: function getNextBreakPoint() {
|
||||
this.breakPoints.sort(function(a, b) { return a - b; });
|
||||
for (var i = 0; i < this.breakPoints.length; i++) {
|
||||
if (this.breakPoints[i] > this.currentIdx)
|
||||
return this.breakPoints[i];
|
||||
}
|
||||
return null;
|
||||
},
|
||||
breakIt: function breakIt(idx, callback) {
|
||||
StepperManager.selectStepper(this.pageNumber, true);
|
||||
var self = this;
|
||||
var dom = document;
|
||||
self.currentIdx = idx;
|
||||
var listener = function(e) {
|
||||
switch (e.keyCode) {
|
||||
case 83: // step
|
||||
dom.removeEventListener('keydown', listener, false);
|
||||
self.nextBreakPoint = self.currentIdx + 1;
|
||||
self.goTo(-1);
|
||||
callback();
|
||||
break;
|
||||
case 67: // continue
|
||||
dom.removeEventListener('keydown', listener, false);
|
||||
var breakPoint = self.getNextBreakPoint();
|
||||
self.nextBreakPoint = breakPoint;
|
||||
self.goTo(-1);
|
||||
callback();
|
||||
break;
|
||||
}
|
||||
}
|
||||
dom.addEventListener('keydown', listener, false);
|
||||
self.goTo(idx);
|
||||
},
|
||||
goTo: function goTo(idx) {
|
||||
var allRows = this.panel.getElementsByClassName('line');
|
||||
for (var x = 0; x < allRows.length; x++) {
|
||||
allRows[x].style.backgroundColor = null;
|
||||
}
|
||||
var row = document.getElementById('idx' + idx);
|
||||
if (row) {
|
||||
row.style.backgroundColor = 'rgb(251,250,207)';
|
||||
row.scrollIntoView();
|
||||
}
|
||||
}
|
||||
};
|
||||
return Stepper;
|
||||
})();
|
||||
|
||||
// Manages all the debugging tools.
|
||||
var PDFBug = (function PDFBugClosure() {
|
||||
var panelWidth = 300;
|
||||
var buttons = [];
|
||||
var activePanel = null;
|
||||
|
||||
return {
|
||||
tools: [
|
||||
FontInspector,
|
||||
StepperManager
|
||||
],
|
||||
init: function init() {
|
||||
/*
|
||||
* Basic Layout:
|
||||
* PDFBug
|
||||
* Controls
|
||||
* Panels
|
||||
* Panel
|
||||
* Panel
|
||||
* ...
|
||||
*/
|
||||
var ui = document.createElement('div');
|
||||
ui.id = 'PDFBug';
|
||||
|
||||
var controls = document.createElement('div');
|
||||
controls.setAttribute('class', 'controls');
|
||||
ui.appendChild(controls);
|
||||
|
||||
var panels = document.createElement('div');
|
||||
panels.setAttribute('class', 'panels');
|
||||
ui.appendChild(panels);
|
||||
|
||||
document.body.appendChild(ui);
|
||||
document.body.style.paddingRight = panelWidth + 'px';
|
||||
|
||||
// Initialize all the debugging tools.
|
||||
var tools = this.tools;
|
||||
for (var i = 0; i < tools.length; ++i) {
|
||||
var tool = tools[i];
|
||||
var panel = document.createElement('div');
|
||||
var panelButton = document.createElement('button');
|
||||
panelButton.textContent = tool.name;
|
||||
var self = this;
|
||||
panelButton.addEventListener('click', (function(selected) {
|
||||
return function(event) {
|
||||
event.preventDefault();
|
||||
self.selectPanel(selected);
|
||||
};
|
||||
})(i));
|
||||
controls.appendChild(panelButton);
|
||||
panels.appendChild(panel);
|
||||
tool.panel = panel;
|
||||
tool.manager = this;
|
||||
if (tool.enabled)
|
||||
tool.init();
|
||||
else
|
||||
panel.textContent = tool.name + ' is disabled. To enable add ' +
|
||||
' "' + tool.id + '" to the pdfBug parameter ' +
|
||||
'and refresh (seperate multiple by commas).';
|
||||
buttons.push(panelButton);
|
||||
}
|
||||
this.selectPanel(0);
|
||||
},
|
||||
selectPanel: function selectPanel(index) {
|
||||
if (index === activePanel)
|
||||
return;
|
||||
activePanel = index;
|
||||
var tools = this.tools;
|
||||
for (var j = 0; j < tools.length; ++j) {
|
||||
if (j == index) {
|
||||
buttons[j].setAttribute('class', 'active');
|
||||
tools[j].active = true;
|
||||
tools[j].panel.removeAttribute('hidden');
|
||||
} else {
|
||||
buttons[j].setAttribute('class', '');
|
||||
tools[j].active = false;
|
||||
tools[j].panel.setAttribute('hidden', 'true');
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
})();
|
297
web/images/pin-down.svg
Normal file
297
web/images/pin-down.svg
Normal file
@ -0,0 +1,297 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="48"
|
||||
height="48"
|
||||
id="svg3075"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="pin-down.svg"
|
||||
viewPort="0 0 48 48">
|
||||
<defs
|
||||
id="defs3077">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
id="linearGradient3804">
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3806" />
|
||||
<stop
|
||||
style="stop-color:#000000;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop3808" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3965">
|
||||
<stop
|
||||
id="stop3967"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
offset="1"
|
||||
id="stop3969" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3885">
|
||||
<stop
|
||||
style="stop-color:#a8b5e9;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3889" />
|
||||
<stop
|
||||
id="stop3891"
|
||||
offset="1"
|
||||
style="stop-color:#1d4488;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3865">
|
||||
<stop
|
||||
style="stop-color:#0e0ec3;stop-opacity:0"
|
||||
offset="0"
|
||||
id="stop3867" />
|
||||
<stop
|
||||
id="stop3883"
|
||||
offset="0.5"
|
||||
style="stop-color:#95b1e4;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#0d29c0;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3869" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3853">
|
||||
<stop
|
||||
style="stop-color:#717171;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3855" />
|
||||
<stop
|
||||
id="stop3861"
|
||||
offset="0.5"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#818181;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3857" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="radialGradient3792"
|
||||
cx="13.508819"
|
||||
cy="30.521608"
|
||||
fx="13.508819"
|
||||
fy="30.521608"
|
||||
r="13.254341"
|
||||
gradientTransform="matrix(1,0,0,1.045977,0,-1.4434017)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="linearGradient3802"
|
||||
x1="15.306904"
|
||||
y1="13.407407"
|
||||
x2="29.35461"
|
||||
y2="30.15519"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.2304178,0,0,1.1235308,-2.1158755,998.83747)" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3804"
|
||||
id="radialGradient3812"
|
||||
cx="20.111172"
|
||||
cy="28.238274"
|
||||
fx="20.111172"
|
||||
fy="28.238274"
|
||||
r="7.6291947"
|
||||
gradientTransform="matrix(1.2304178,0,0,1.1452771,-2.1158755,998.22337)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="radialGradient3822"
|
||||
cx="23.985939"
|
||||
cy="24.847366"
|
||||
fx="23.985939"
|
||||
fy="24.847366"
|
||||
r="10.593476"
|
||||
gradientTransform="matrix(0.63682384,0.44303926,-1.1714282,1.6838088,35.523491,-26.055439)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter3856"
|
||||
x="-0.30370581"
|
||||
width="1.6074116"
|
||||
y="-0.32771564"
|
||||
height="1.6554313">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="4.7808869"
|
||||
id="feGaussianBlur3858" />
|
||||
</filter>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="radialGradient3865"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,1.045977,0,-1.4434017)"
|
||||
cx="13.508819"
|
||||
cy="30.521608"
|
||||
fx="13.508819"
|
||||
fy="30.521608"
|
||||
r="13.254341" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="linearGradient3867"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.2304178,0,0,1.1235308,-2.1158755,998.83747)"
|
||||
x1="15.306904"
|
||||
y1="13.407407"
|
||||
x2="29.35461"
|
||||
y2="30.15519" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3804"
|
||||
id="radialGradient3869"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.2304178,0,0,1.1452771,-2.1158755,998.22337)"
|
||||
cx="20.111172"
|
||||
cy="28.238274"
|
||||
fx="20.111172"
|
||||
fy="28.238274"
|
||||
r="7.6291947" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="radialGradient3871"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.63682384,0.44303926,-1.1714282,1.6838088,35.523491,-26.055439)"
|
||||
cx="23.985939"
|
||||
cy="24.847366"
|
||||
fx="23.985939"
|
||||
fy="24.847366"
|
||||
r="10.593476" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="linearGradient3875"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.98683814,0,0,0.9524914,3.4991888,1004.1467)"
|
||||
x1="15.306904"
|
||||
y1="13.407407"
|
||||
x2="29.35461"
|
||||
y2="30.15519" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3804"
|
||||
id="radialGradient3877"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.195641,0.23932984,-0.18533175,0.95255553,4.5333676,999.33159)"
|
||||
cx="20.111172"
|
||||
cy="28.238274"
|
||||
fx="20.111172"
|
||||
fy="28.238274"
|
||||
r="7.6291947" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="radialGradient3880"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.5847553,0.52693722,-0.99805104,2.7064773,14.11088,-45.304477)"
|
||||
cx="18.133854"
|
||||
cy="19.778509"
|
||||
fx="18.133854"
|
||||
fy="19.778509"
|
||||
r="10.593476" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="radialGradient3882"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,1.045977,0,-1.4434017)"
|
||||
cx="13.508819"
|
||||
cy="30.521608"
|
||||
fx="13.508819"
|
||||
fy="30.521608"
|
||||
r="13.254341" />
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="4.9558805"
|
||||
inkscape:cx="3.0237013"
|
||||
inkscape:cy="17.287267"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1291"
|
||||
inkscape:window-height="776"
|
||||
inkscape:window-x="16"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata3080">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1004.3622)">
|
||||
<path
|
||||
style="fill:#ffffff;fill-opacity:1;stroke:none;filter:url(#filter3856)"
|
||||
d="m 14.326415,1019.2702 c -8.3327876,4.0675 -9.8235436,10.8833 -8.8783416,15.1336 4.6840646,7.9754 8.3608166,13.8165 24.0118786,12.9139 9.657617,-3.7312 12.9762,-9.3269 13.519293,-15.7389 -0.547269,-4.3839 -1.957958,-9.3396 -5.649854,-14.9317 -3.965534,-2.471 -6.300859,-4.4246 -10.290805,-4.2374 -8.25193,0.5026 -8.752485,4.4502 -12.712171,6.8605 z"
|
||||
id="path3826"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccccc"
|
||||
transform="matrix(0.69099294,0,0,0.75978808,7.3427938,249.11025)" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:url(#radialGradient3882);fill-opacity:1;stroke:none"
|
||||
id="path3011"
|
||||
sodipodi:cx="21.176477"
|
||||
sodipodi:cy="31.393986"
|
||||
sodipodi:rx="13.254341"
|
||||
sodipodi:ry="13.863736"
|
||||
d="m 34.430819,31.393986 a 13.254341,13.863736 0 1 1 -26.5086827,0 13.254341,13.863736 0 1 1 26.5086827,0 z"
|
||||
transform="matrix(0.98683814,0,0,0.83062636,2.696034,1005.3655)" />
|
||||
<path
|
||||
style="fill:url(#linearGradient3875);fill-opacity:1;stroke:url(#radialGradient3877);stroke-width:0.9695127;stroke-opacity:1"
|
||||
d="m 17.246758,1026.7905 c -1.7156,4.5052 -2.482464,10.6205 8.726963,10.7476 4.849099,-1.8941 3.522783,-5.3561 6.021544,-11.8282 l -10.973104,-1.5977 z"
|
||||
id="path3794"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="ccccc" />
|
||||
<path
|
||||
sodipodi:type="arc"
|
||||
style="fill:url(#radialGradient3880);fill-opacity:1;stroke:none"
|
||||
id="path3814"
|
||||
sodipodi:cx="24.718111"
|
||||
sodipodi:cy="23.38278"
|
||||
sodipodi:rx="10.593476"
|
||||
sodipodi:ry="9.6854639"
|
||||
d="m 35.311587,23.38278 a 10.593476,9.6854639 0 1 1 -21.186952,0 10.593476,9.6854639 0 1 1 21.186952,0 z"
|
||||
transform="matrix(0.85425691,0,0,0.84187503,3.9779774,1006.7561)" />
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 9.6 KiB |
230
web/images/pin-up.svg
Normal file
230
web/images/pin-up.svg
Normal file
@ -0,0 +1,230 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="48"
|
||||
height="48"
|
||||
id="svg3075"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.1 r9760"
|
||||
sodipodi:docname="pin-up.svg"
|
||||
viewPort="0 0 48 48">
|
||||
<defs
|
||||
id="defs3077">
|
||||
<linearGradient
|
||||
id="linearGradient3965">
|
||||
<stop
|
||||
id="stop3967"
|
||||
offset="0"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
offset="1"
|
||||
id="stop3969" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3885">
|
||||
<stop
|
||||
style="stop-color:#a8b5e9;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3889" />
|
||||
<stop
|
||||
id="stop3891"
|
||||
offset="1"
|
||||
style="stop-color:#1d4488;stop-opacity:1;" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3865">
|
||||
<stop
|
||||
style="stop-color:#0e0ec3;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3867" />
|
||||
<stop
|
||||
id="stop3883"
|
||||
offset="0.5"
|
||||
style="stop-color:#95b1e4;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#0d29c0;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3869" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3853">
|
||||
<stop
|
||||
style="stop-color:#717171;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop3855" />
|
||||
<stop
|
||||
id="stop3861"
|
||||
offset="0.5"
|
||||
style="stop-color:#ffffff;stop-opacity:1;" />
|
||||
<stop
|
||||
style="stop-color:#818181;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop3857" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3853"
|
||||
id="linearGradient3859"
|
||||
x1="7.7696066"
|
||||
y1="34.979828"
|
||||
x2="11.854106"
|
||||
y2="39.107044"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(4.8388015,1001.6582)" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="radialGradient3871"
|
||||
cx="14.801222"
|
||||
cy="1030.6609"
|
||||
fx="14.801222"
|
||||
fy="1030.6609"
|
||||
r="10.177785"
|
||||
gradientTransform="matrix(1,0,0,1.0108042,4.8388015,-13.880529)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3865"
|
||||
id="linearGradient3881"
|
||||
x1="15.012629"
|
||||
y1="11.922465"
|
||||
x2="31.098303"
|
||||
y2="28.858271"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1,0,0,0.97315436,4.8388015,1002.4769)" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3885"
|
||||
id="radialGradient3909"
|
||||
cx="16.437693"
|
||||
cy="22.596292"
|
||||
fx="16.437693"
|
||||
fy="22.596292"
|
||||
r="1.7789712"
|
||||
gradientTransform="matrix(1,0,0,8.3599999,0,-166.30871)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3865"
|
||||
id="linearGradient3927"
|
||||
x1="26.47109"
|
||||
y1="1010.7343"
|
||||
x2="35.294788"
|
||||
y2="1019.8425"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(4.5541661,-2.1347654)" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3965"
|
||||
id="radialGradient3995"
|
||||
cx="23.189369"
|
||||
cy="25.704245"
|
||||
fx="23.189369"
|
||||
fy="25.704245"
|
||||
r="37.336674"
|
||||
gradientTransform="matrix(1,0,0,1.0332422,0,-0.85446479)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<filter
|
||||
inkscape:collect="always"
|
||||
id="filter4009"
|
||||
x="-0.19299152"
|
||||
width="1.385983"
|
||||
y="-0.18351803"
|
||||
height="1.3670361">
|
||||
<feGaussianBlur
|
||||
inkscape:collect="always"
|
||||
stdDeviation="3.8667902"
|
||||
id="feGaussianBlur4011" />
|
||||
</filter>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="3.2819435"
|
||||
inkscape:cx="18.697469"
|
||||
inkscape:cy="17.287267"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="970"
|
||||
inkscape:window-height="778"
|
||||
inkscape:window-x="284"
|
||||
inkscape:window-y="0"
|
||||
inkscape:window-maximized="0" />
|
||||
<metadata
|
||||
id="metadata3080">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(0,-1004.3622)">
|
||||
<path
|
||||
style="fill:url(#radialGradient3995);stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1.0;filter:url(#filter4009)"
|
||||
d="M -0.85390618,50.988672 14.231769,27.790888 C 12.21393,25.133052 9.5514307,24.605255 9.9622384,18.824874 13.947134,14.236899 17.362759,16.258973 21.347654,16.54779 l 8.966014,-8.6813789 c 1.467204,-2.4778468 -1.023584,-4.6422045 0.569271,-7.25820222 4.802307,-0.84764718 6.662499,1.15219542 11.527733,6.26197842 4.061691,4.1873637 5.648882,7.0611607 4.411848,9.5352857 -1.075122,2.776443 -4.518349,-0.692782 -5.835025,0.56927 l -9.108332,10.104556 c -0.418785,3.74872 2.078647,7.861968 -1.280859,11.243098 -4.132171,0.818036 -6.734336,-1.933944 -9.819921,-3.557942 z"
|
||||
id="path3955"
|
||||
inkscape:connector-curvature="0"
|
||||
transform="translate(0,1004.3622)"
|
||||
sodipodi:nodetypes="ccccccccccccc" />
|
||||
<g
|
||||
id="g3929">
|
||||
<path
|
||||
sodipodi:nodetypes="cccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3083"
|
||||
d="m 3.2884874,1051.0662 c 3.1862139,-6.2911 11.3693156,-15.19 15.4471616,-20.0327 l 2.86533,3.0086 c -3.476851,3.6575 -10.192375,10.8664 -18.3124916,17.0241 z"
|
||||
style="fill:url(#linearGradient3859);fill-opacity:1;stroke:#a5a5a5;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3863"
|
||||
d="m 11.10078,1023.3294 c 5.038264,10.1095 11.83652,14.8875 18.358981,18.2167 1.196291,-2.5422 1.454996,-5.6203 0,-9.6776 l -8.539061,-8.6814 c -3.704654,-1.8936 -6.871076,-1.3652 -9.81992,0.1423 z"
|
||||
style="fill:url(#radialGradient3871);fill-opacity:1;stroke:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3873"
|
||||
d="m 33.729292,1011.5171 -13.235545,11.4952 c 2.869602,4.2703 6.221839,7.4544 9.108332,9.1408 l 11.385416,-13.0187 z"
|
||||
style="fill:url(#linearGradient3881);fill-opacity:1;stroke:none" />
|
||||
<path
|
||||
sodipodi:nodetypes="ccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path3893"
|
||||
d="m 33.228885,1011.6148 c 1.843189,2.7806 3.431654,5.6597 7.19852,7.6953 l 5.398891,1.7423 c -7.6738,-4.7914 -10.989683,-9.5828 -13.947133,-14.3741 z"
|
||||
style="fill:url(#linearGradient3927);fill-opacity:1;stroke:none" />
|
||||
<path
|
||||
transform="matrix(0.68275275,-0.5590416,0.45791123,0.47036287,17.42507,1012.2127)"
|
||||
d="m 18.216664,22.596292 a 1.7789712,14.872199 0 1 1 -3.557943,0 1.7789712,14.872199 0 1 1 3.557943,0 z"
|
||||
sodipodi:ry="14.872199"
|
||||
sodipodi:rx="1.7789712"
|
||||
sodipodi:cy="22.596292"
|
||||
sodipodi:cx="16.437693"
|
||||
id="path3901"
|
||||
style="fill:url(#radialGradient3909);fill-opacity:1;stroke:none"
|
||||
sodipodi:type="arc" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 8.1 KiB |
@ -89,7 +89,8 @@ span#info {
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
#sidebar:hover {
|
||||
#sidebar:hover,
|
||||
#sidebar.pinned {
|
||||
left: 0px;
|
||||
transition: left 0.25s ease-in-out 0s;
|
||||
-o-transition: left 0.25s ease-in-out 0s;
|
||||
@ -97,6 +98,26 @@ span#info {
|
||||
-webkit-transition: left 0.25s ease-in-out 0s;
|
||||
}
|
||||
|
||||
#pinIcon {
|
||||
position: absolute;
|
||||
top: 4px;
|
||||
right: 55px;
|
||||
width: 15px;
|
||||
height: 15px;
|
||||
background: center no-repeat;
|
||||
background-image: url('images/pin-up.svg');
|
||||
background-size: 15px 15px;
|
||||
}
|
||||
|
||||
#pinIcon:hover {
|
||||
background-color: rgba(255,255,255,0.35);
|
||||
}
|
||||
|
||||
#sidebar.pinned #pinIcon {
|
||||
background-image: url('images/pin-down.svg');
|
||||
background-size: 15px 15px;
|
||||
}
|
||||
|
||||
#sidebarBox {
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
width: 300px;
|
||||
@ -116,7 +137,7 @@ span#info {
|
||||
position: absolute;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
top: 10px;
|
||||
top: 20px;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
width: 280px;
|
||||
@ -147,7 +168,7 @@ span#info {
|
||||
position: absolute;
|
||||
background-color: #fff;
|
||||
overflow: auto;
|
||||
top: 10px;
|
||||
top: 20px;
|
||||
bottom: 10px;
|
||||
left: 10px;
|
||||
width: 280px;
|
||||
@ -381,6 +402,43 @@ canvas {
|
||||
}
|
||||
|
||||
#loading {
|
||||
margin: 100px 0;
|
||||
text-align: center;
|
||||
margin: 100px 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#PDFBug {
|
||||
font-size: 10px;
|
||||
position: fixed;
|
||||
top: 35px;
|
||||
bottom: 5px;
|
||||
right: 2px;
|
||||
width: 300px;
|
||||
background: white;
|
||||
border: 1px solid #666;
|
||||
padding: 0;
|
||||
}
|
||||
#PDFBug .controls {
|
||||
border-bottom: 1px solid #666;
|
||||
padding: 3px;
|
||||
background: -moz-linear-gradient(center bottom, #eee 0%, #fff 100%);
|
||||
}
|
||||
#PDFBug .panels {
|
||||
overflow: auto;
|
||||
position: absolute;
|
||||
top: 27px;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
}
|
||||
#PDFBug button.active {
|
||||
font-weight: bold;
|
||||
}
|
||||
.debuggerShowText {
|
||||
background: yellow;
|
||||
color: blue;
|
||||
opacity: 0.3;
|
||||
}
|
||||
.debuggerHideText:hover {
|
||||
background: yellow;
|
||||
opacity: 0.3;
|
||||
}
|
||||
|
@ -9,30 +9,32 @@
|
||||
<script type="text/javascript" src="compatibility.js"></script> <!-- PDFJSSCRIPT_REMOVE_FIREFOX_EXTENSION -->
|
||||
|
||||
<!-- PDFJSSCRIPT_INCLUDE_BUILD -->
|
||||
<script type="text/javascript" src="../src/core.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/util.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/canvas.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/obj.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/function.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/charsets.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/cidmaps.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/colorspace.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/crypto.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/evaluator.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/fonts.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/glyphlist.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/image.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/metrics.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/parser.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/pattern.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="../external/jpgjs/jpg.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/jpx.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/bidi.js"></script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript">PDFJS.workerSrc = '../src/worker_loader.js';</script> <!-- PDFJSSCRIPT_REMOVE -->
|
||||
<script type="text/javascript" src="../src/core.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/util.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/canvas.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/obj.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/function.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/charsets.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/cidmaps.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/colorspace.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/crypto.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/evaluator.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/fonts.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/glyphlist.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/image.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/metrics.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/parser.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/pattern.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/stream.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/worker.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../external/jpgjs/jpg.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/jpx.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="../src/bidi.js"></script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript">PDFJS.workerSrc = '../src/worker_loader.js';</script> <!-- PDFJSSCRIPT_REMOVE_CORE -->
|
||||
<script type="text/javascript" src="debugger.js"></script>
|
||||
<script type="text/javascript" src="viewer.js"></script>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
@ -123,6 +125,7 @@
|
||||
|
||||
<div id="sidebar">
|
||||
<div id="sidebarBox">
|
||||
<div id="pinIcon" onClick="PDFView.pinSidebar()"></div>
|
||||
<div id="sidebarScrollView">
|
||||
<div id="sidebarView"></div>
|
||||
</div>
|
||||
@ -137,7 +140,7 @@
|
||||
<img src="images/nav-outline.svg" align="top" height="16" alt="Document Outline" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div id="loading">Loading... 0%</div>
|
||||
|
@ -37,10 +37,6 @@ var RenderingQueue = (function RenderingQueueClosure() {
|
||||
if (!item.drawingRequired())
|
||||
return; // as no redraw required, no need for queueing.
|
||||
|
||||
if ('rendering' in item)
|
||||
return; // is already in the queue
|
||||
|
||||
item.rendering = true;
|
||||
this.items.push(item);
|
||||
if (this.items.length > 1)
|
||||
return; // not first item
|
||||
@ -49,7 +45,6 @@ var RenderingQueue = (function RenderingQueueClosure() {
|
||||
},
|
||||
continueExecution: function RenderingQueueContinueExecution() {
|
||||
var item = this.items.shift();
|
||||
delete item.rendering;
|
||||
|
||||
if (this.items.length == 0)
|
||||
return; // queue is empty
|
||||
@ -325,7 +320,8 @@ var PDFView = {
|
||||
if (pageNumber) {
|
||||
var pdfOpenParams = PDFView.getAnchorUrl('#page=' + pageNumber);
|
||||
var destKind = dest[1];
|
||||
if ('name' in destKind && destKind.name == 'XYZ') {
|
||||
if (typeof destKind === 'object' && 'name' in destKind &&
|
||||
destKind.name == 'XYZ') {
|
||||
var scale = (dest[4] || this.currentScale);
|
||||
pdfOpenParams += '&zoom=' + (scale * 100);
|
||||
if (dest[2] || dest[3]) {
|
||||
@ -509,13 +505,7 @@ var PDFView = {
|
||||
return;
|
||||
|
||||
if (hash.indexOf('=') >= 0) {
|
||||
// parsing query string
|
||||
var paramsPairs = hash.split('&');
|
||||
var params = {};
|
||||
for (var i = 0; i < paramsPairs.length; ++i) {
|
||||
var paramPair = paramsPairs[i].split('=');
|
||||
params[paramPair[0]] = paramPair[1];
|
||||
}
|
||||
var params = PDFView.parseQueryString(hash);
|
||||
// borrowing syntax from "Parameters for Opening PDF Files"
|
||||
if ('nameddest' in params) {
|
||||
PDFView.navigateTo(params.nameddest);
|
||||
@ -571,6 +561,10 @@ var PDFView = {
|
||||
}
|
||||
},
|
||||
|
||||
pinSidebar: function pdfViewPinSidebar() {
|
||||
document.getElementById('sidebar').classList.toggle('pinned');
|
||||
},
|
||||
|
||||
getVisiblePages: function pdfViewGetVisiblePages() {
|
||||
var pages = this.pages;
|
||||
var kBottomMargin = 10;
|
||||
@ -623,6 +617,19 @@ var PDFView = {
|
||||
}
|
||||
|
||||
return visibleThumbs;
|
||||
},
|
||||
|
||||
// Helper function to parse query string (e.g. ?param1=value&parm2=...).
|
||||
parseQueryString: function pdfViewParseQueryString(query) {
|
||||
var parts = query.split('&');
|
||||
var params = {};
|
||||
for (var i = 0, ii = parts.length; i < parts.length; ++i) {
|
||||
var param = parts[i].split('=');
|
||||
var key = param[0];
|
||||
var value = param.length > 1 ? param[1] : null;
|
||||
params[unescape(key)] = unescape(value);
|
||||
}
|
||||
return params;
|
||||
}
|
||||
};
|
||||
|
||||
@ -865,7 +872,10 @@ var PageView = function pageView(container, content, id, pageWidth, pageHeight,
|
||||
var self = this;
|
||||
stats.begin = Date.now();
|
||||
this.content.startRendering(ctx, function pageViewDrawCallback(error) {
|
||||
div.removeChild(self.loadingIconDiv);
|
||||
if (self.loadingIconDiv) {
|
||||
div.removeChild(self.loadingIconDiv);
|
||||
delete self.loadingIconDiv;
|
||||
}
|
||||
|
||||
if (error)
|
||||
PDFView.error('An error occurred while rendering the page.', error);
|
||||
@ -965,7 +975,7 @@ var ThumbnailView = function thumbnailView(container, page, id, pageRatio) {
|
||||
};
|
||||
|
||||
this.setImage = function thumbnailViewSetImage(img) {
|
||||
if (this.hasImage)
|
||||
if (this.hasImage || !img)
|
||||
return;
|
||||
|
||||
var ctx = getPageDrawContext();
|
||||
@ -1082,6 +1092,7 @@ var TextLayerBuilder = function textLayerBuilder(textLayerDiv) {
|
||||
// vScale and hScale already contain the scaling to pixel units
|
||||
var fontHeight = fontSize * text.geom.vScale;
|
||||
textDiv.dataset.canvasWidth = text.canvasWidth * text.geom.hScale;
|
||||
textDiv.dataset.fontName = fontName;
|
||||
|
||||
textDiv.style.fontSize = fontHeight + 'px';
|
||||
textDiv.style.left = text.geom.x + 'px';
|
||||
@ -1094,16 +1105,11 @@ var TextLayerBuilder = function textLayerBuilder(textLayerDiv) {
|
||||
};
|
||||
|
||||
window.addEventListener('load', function webViewerLoad(evt) {
|
||||
var params = document.location.search.substring(1).split('&');
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var param = params[i].split('=');
|
||||
params[unescape(param[0])] = unescape(param[1]);
|
||||
}
|
||||
var params = PDFView.parseQueryString(document.location.search.substring(1));
|
||||
|
||||
var scale = ('scale' in params) ? params.scale : 0;
|
||||
var file = PDFJS.isFirefoxExtension ?
|
||||
window.location.toString() : params.file || kDefaultURL;
|
||||
PDFView.open(file, parseFloat(scale));
|
||||
PDFView.open(file, 0);
|
||||
|
||||
if (PDFJS.isFirefoxExtension || !window.File || !window.FileReader ||
|
||||
!window.FileList || !window.Blob) {
|
||||
@ -1114,11 +1120,32 @@ window.addEventListener('load', function webViewerLoad(evt) {
|
||||
document.getElementById('fileInput').value = null;
|
||||
}
|
||||
|
||||
if ('disableWorker' in params)
|
||||
PDFJS.disableWorker = (params['disableWorker'] === 'true');
|
||||
// Special debugging flags in the hash section of the URL.
|
||||
var hash = document.location.hash.substring(1);
|
||||
var hashParams = PDFView.parseQueryString(hash);
|
||||
|
||||
if ('disableTextLayer' in params)
|
||||
PDFJS.disableTextLayer = (params['disableTextLayer'] === 'true');
|
||||
if ('disableWorker' in hashParams)
|
||||
PDFJS.disableWorker = (hashParams['disableWorker'] === 'true');
|
||||
|
||||
if ('disableTextLayer' in hashParams)
|
||||
PDFJS.disableTextLayer = (hashParams['disableTextLayer'] === 'true');
|
||||
|
||||
if ('pdfBug' in hashParams) {
|
||||
PDFJS.pdfBug = true;
|
||||
var pdfBug = hashParams['pdfBug'];
|
||||
var all = false, enabled = [];
|
||||
if (pdfBug === 'all')
|
||||
all = true;
|
||||
else
|
||||
enabled = pdfBug.split(',');
|
||||
var debugTools = PDFBug.tools;
|
||||
for (var i = 0; i < debugTools.length; ++i) {
|
||||
var tool = debugTools[i];
|
||||
if (all || enabled.indexOf(tool.id) !== -1)
|
||||
tool.enabled = true;
|
||||
}
|
||||
PDFBug.init();
|
||||
}
|
||||
|
||||
var sidebarScrollView = document.getElementById('sidebarScrollView');
|
||||
sidebarScrollView.addEventListener('scroll', updateThumbViewArea, true);
|
||||
@ -1205,7 +1232,6 @@ window.addEventListener('scroll', function webViewerScroll(evt) {
|
||||
updateViewarea();
|
||||
}, true);
|
||||
|
||||
|
||||
var thumbnailTimer;
|
||||
|
||||
function updateThumbViewArea() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user