diff --git a/canvas_proxy.js b/canvas_proxy.js index 83b57682f..0b7681bfe 100644 --- a/canvas_proxy.js +++ b/canvas_proxy.js @@ -1,3 +1,7 @@ +/* -*- 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 JpegStreamProxyCounter = 0; // WebWorker Proxy for JpegStream. @@ -29,16 +33,16 @@ var JpegStreamProxy = (function() { // Really simple GradientProxy. There is currently only one active gradient at // the time, meaning you can't create a gradient, create a second one and then // use the first one again. As this isn't used in pdf.js right now, it's okay. -function GradientProxy(stack, x0, y0, x1, y1) { - stack.push(["$createLinearGradient", [x0, y0, x1, y1]]); +function GradientProxy(cmdQueue, x0, y0, x1, y1) { + cmdQueue.push(["$createLinearGradient", [x0, y0, x1, y1]]); this.addColorStop = function(i, rgba) { - stack.push(["$addColorStop", [i, rgba]]); + cmdQueue.push(["$addColorStop", [i, rgba]]); } } // Really simple PatternProxy. var patternProxyCounter = 0; -function PatternProxy(stack, object, kind) { +function PatternProxy(cmdQueue, object, kind) { this.id = patternProxyCounter++; if (!(object instanceof CanvasProxy) ) { @@ -49,7 +53,7 @@ function PatternProxy(stack, object, kind) { // TODO: Make some kind of dependency management, such that the object // gets flushed only if needed. object.flush(); - stack.push(["$createPatternFromCanvas", [this.id, object.id, kind]]); + cmdQueue.push(["$createPatternFromCanvas", [this.id, object.id, kind]]); } var canvasProxyCounter = 0; @@ -57,7 +61,7 @@ function CanvasProxy(width, height) { this.id = canvasProxyCounter++; // The `stack` holds the rendering calls and gets flushed to the main thead. - var stack = this.$stack = []; + var cmdQueue = this.cmdQueue = []; // Dummy context that gets exposed. var ctx = {}; @@ -119,7 +123,7 @@ function CanvasProxy(width, height) { function buildFuncCall(name) { return function() { // console.log("funcCall", name) - stack.push([name, Array.prototype.slice.call(arguments)]); + cmdQueue.push([name, Array.prototype.slice.call(arguments)]); } } var name; @@ -131,11 +135,11 @@ function CanvasProxy(width, height) { // Some function calls that need more work. ctx.createPattern = function(object, kind) { - return new PatternProxy(stack, object, kind); + return new PatternProxy(cmdQueue, object, kind); } ctx.createLinearGradient = function(x0, y0, x1, y1) { - return new GradientProxy(stack, x0, y0, x1, y1); + return new GradientProxy(cmdQueue, x0, y0, x1, y1); } ctx.getImageData = function(x, y, w, h) { @@ -147,16 +151,16 @@ function CanvasProxy(width, height) { } ctx.putImageData = function(data, x, y, width, height) { - stack.push(["$putImageData", [data, x, y, width, height]]); + cmdQueue.push(["$putImageData", [data, x, y, width, height]]); } ctx.drawImage = function(image, x, y, width, height, sx, sy, swidth, sheight) { if (image instanceof CanvasProxy) { // Send the image/CanvasProxy to the main thread. image.flush(); - stack.push(["$drawCanvas", [image.id, x, y, sx, sy, swidth, sheight]]); + cmdQueue.push(["$drawCanvas", [image.id, x, y, sx, sy, swidth, sheight]]); } else if(image instanceof JpegStreamProxy) { - stack.push(["$drawImage", [image.id, x, y, sx, sy, swidth, sheight]]) + cmdQueue.push(["$drawImage", [image.id, x, y, sx, sy, swidth, sheight]]) } else { throw "unkown type to drawImage"; } @@ -192,11 +196,26 @@ function CanvasProxy(width, height) { function buildSetter(name) { return function(value) { - stack.push(["$", name, value]); + cmdQueue.push(["$", name, value]); return ctx["$" + name] = value; } } + // Setting the value to `stroke|fillStyle` needs special handling, as it + // might gets an gradient/pattern. + function buildSetterStyle(name) { + return function(value) { + if (value instanceof GradientProxy) { + cmdQueue.push(["$" + name + "Gradient"]); + } else if (value instanceof PatternProxy) { + cmdQueue.push(["$" + name + "Pattern", [value.id]]); + } else { + cmdQueue.push(["$", name, value]); + return ctx["$" + name] = value; + } + } + } + for (var name in ctxProp) { ctx["$" + name] = ctxProp[name]; ctx.__defineGetter__(name, buildGetter(name)); @@ -204,18 +223,6 @@ function CanvasProxy(width, height) { // Special treatment for `fillStyle` and `strokeStyle`: The passed style // might be a gradient. Need to check for that. if (name == "fillStyle" || name == "strokeStyle") { - function buildSetterStyle(name) { - return function(value) { - if (value instanceof GradientProxy) { - stack.push(["$" + name + "Gradient"]); - } else if (value instanceof PatternProxy) { - stack.push(["$" + name + "Pattern", [value.id]]); - } else { - stack.push(["$", name, value]); - return ctx["$" + name] = value; - } - } - } ctx.__defineSetter__(name, buildSetterStyle(name)); } else { ctx.__defineSetter__(name, buildSetter(name)); @@ -224,16 +231,16 @@ function CanvasProxy(width, height) { } /** -* Sends the current stack of the CanvasProxy over to the main thread and -* resets the stack. +* Sends the current cmdQueue of the CanvasProxy over to the main thread and +* resets the cmdQueue. */ CanvasProxy.prototype.flush = function() { - postMessage("canvas_proxy_stack"); + postMessage("canvas_proxy_cmd_queue"); postMessage({ - id: this.id, - stack: this.$stack, - width: this.width, - height: this.height + id: this.id, + cmdQueue: this.cmdQueue, + width: this.width, + height: this.height }); - this.$stack.length = 0; + this.cmdQueue.length = 0; } diff --git a/fonts.js b/fonts.js index 9c9201b72..a3604c6b9 100644 --- a/fonts.js +++ b/fonts.js @@ -759,88 +759,15 @@ var Font = (function () { var data = this.font; var fontName = this.name; - var isWorker = (typeof window == "undefined"); - /** Hack begin */ - if (!isWorker) { - - // Actually there is not event when a font has finished downloading so - // the following code are a dirty hack to 'guess' when a font is ready - var canvas = document.createElement("canvas"); - var style = "border: 1px solid black; position:absolute; top: " + - (debug ? (100 * fontCount) : "-200") + "px; left: 2px; width: 340px; height: 100px"; - canvas.setAttribute("style", style); - canvas.setAttribute("width", 340); - canvas.setAttribute("heigth", 100); - document.body.appendChild(canvas); - - // Get the font size canvas think it will be for 'spaces' - var ctx = canvas.getContext("2d"); - ctx.font = "bold italic 20px " + fontName + ", Symbol, Arial"; - var testString = " "; - - // When debugging use the characters provided by the charsets to visually - // see what's happening instead of 'spaces' - var debug = false; - if (debug) { - var name = document.createElement("font"); - name.setAttribute("style", "position: absolute; left: 20px; top: " + - (100 * fontCount + 60) + "px"); - name.innerHTML = fontName; - document.body.appendChild(name); - - // Retrieve font charset - var charset = Fonts[fontName].properties.charset || []; - - // if the charset is too small make it repeat a few times - var count = 30; - while (count-- && charset.length <= 30) - charset = charset.concat(charset.slice()); - - for (var i = 0; i < charset.length; i++) { - var unicode = GlyphsUnicode[charset[i]]; - if (!unicode) - continue; - testString += String.fromCharCode(unicode); - } - - ctx.fillText(testString, 20, 20); - } - - // Periodicaly check for the width of the testString, it will be - // different once the real font has loaded - var textWidth = ctx.measureText(testString).width; - - var interval = window.setInterval(function canvasInterval(self) { - this.start = this.start || Date.now(); - ctx.font = "bold italic 20px " + fontName + ", Symbol, Arial"; - - // For some reasons the font has not loaded, so mark it loaded for the - // page to proceed but cry - if ((Date.now() - this.start) >= kMaxWaitForFontFace) { - window.clearInterval(interval); - Fonts[fontName].loading = false; - warn("Is " + fontName + " for charset: " + charset + " loaded?"); - this.start = 0; - } else if (textWidth != ctx.measureText(testString).width) { - window.clearInterval(interval); - Fonts[fontName].loading = false; - this.start = 0; - } - - if (debug) - ctx.fillText(testString, 20, 50); - }, 30, this); - } - - /** Hack end */ - // // Get the base64 encoding of the binary font data var str = ""; var length = data.length; for (var i = 0; i < length; ++i) str += String.fromCharCode(data[i]); - if (isWorker) { + // Insert the font-face css on the page. In a web worker, this needs to + // be forwareded on the main thread. + if (typeof window == "undefined") { postMessage("font"); postMessage(JSON.stringify({ str: str, @@ -855,6 +782,19 @@ var Font = (function () { var rule = "@font-face { font-family:'" + fontName + "';src:" + url + "}"; var styleSheet = document.styleSheets[0]; styleSheet.insertRule(rule, styleSheet.length); + + var div = document.createElement("div"); + div.innerHTML += "