Most working, but once you add the font-css file to the web page, there is no font drawn at all
This commit is contained in:
parent
f346014c12
commit
a8dcb0dcd6
@ -42,11 +42,17 @@ function CanvasProxy(width, height) {
|
||||
"stroke",
|
||||
"clip",
|
||||
"measureText",
|
||||
"isPointInPath"
|
||||
"isPointInPath",
|
||||
|
||||
"$setCurrentX",
|
||||
"$addCurrentX",
|
||||
"$saveCurrentX",
|
||||
"$restoreCurrentX",
|
||||
"$showText"
|
||||
];
|
||||
function buildFuncCall(name) {
|
||||
return function() {
|
||||
console.log("funcCall", name)
|
||||
// console.log("funcCall", name)
|
||||
stack.push([name, Array.prototype.slice.call(arguments)]);
|
||||
}
|
||||
}
|
||||
@ -103,6 +109,8 @@ function CanvasProxy(width, height) {
|
||||
}
|
||||
|
||||
CanvasProxy.prototype.flush = function() {
|
||||
// postMessage("log");
|
||||
// postMessage(JSON.stringify([this.$stack.length]));
|
||||
postMessage("canvas_proxy_stack");
|
||||
postMessage(JSON.stringify(this.$stack));
|
||||
this.$stack.length = 0;
|
||||
|
146
fonts.js
146
fonts.js
@ -759,91 +759,109 @@ 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);
|
||||
// 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 = " ";
|
||||
// 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);
|
||||
// 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 || [];
|
||||
// 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());
|
||||
// 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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
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;
|
||||
// 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";
|
||||
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;
|
||||
}
|
||||
// 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);
|
||||
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]);
|
||||
|
||||
var base64 = window.btoa(str);
|
||||
if (isWorker) {
|
||||
postMessage("font");
|
||||
postMessage(JSON.stringify({
|
||||
str: str,
|
||||
mimetype: this.mimetype,
|
||||
fontName: fontName,
|
||||
}));
|
||||
|
||||
// Add the @font-face rule to the document
|
||||
var url = "url(data:" + this.mimetype + ";base64," + base64 + ");";
|
||||
var rule = "@font-face { font-family:'" + fontName + "';src:" + url + "}";
|
||||
var styleSheet = document.styleSheets[0];
|
||||
styleSheet.insertRule(rule, styleSheet.length);
|
||||
setTimeout(function() {
|
||||
Fonts[fontName].loading = false;
|
||||
}, kMaxWaitForFontFace);
|
||||
} else {
|
||||
var base64 = window.btoa(str);
|
||||
|
||||
// Add the @font-face rule to the document
|
||||
var url = "url(data:" + this.mimetype + ";base64," + base64 + ");";
|
||||
var rule = "@font-face { font-family:'" + fontName + "';src:" + url + "}";
|
||||
var styleSheet = document.styleSheets[0];
|
||||
styleSheet.insertRule(rule, styleSheet.length);
|
||||
console.log("added font", fontName);
|
||||
console.log(rule);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
34
pdf.js
34
pdf.js
@ -2674,12 +2674,18 @@ var CanvasGraphics = (function() {
|
||||
},
|
||||
save: function() {
|
||||
this.ctx.save();
|
||||
if (this.ctx.$saveCurrentX) {
|
||||
this.ctx.$saveCurrentX();
|
||||
}
|
||||
this.stateStack.push(this.current);
|
||||
this.current = new CanvasExtraState();
|
||||
},
|
||||
restore: function() {
|
||||
var prev = this.stateStack.pop();
|
||||
if (prev) {
|
||||
if (this.ctx.$restoreCurrentX) {
|
||||
this.ctx.$restoreCurrentX();
|
||||
}
|
||||
this.current = prev;
|
||||
this.ctx.restore();
|
||||
}
|
||||
@ -2760,6 +2766,9 @@ var CanvasGraphics = (function() {
|
||||
// Text
|
||||
beginText: function() {
|
||||
this.current.textMatrix = IDENTITY_MATRIX;
|
||||
if (this.ctx.$setCurrentX) {
|
||||
this.ctx.$setCurrentX(0)
|
||||
}
|
||||
this.current.x = this.current.lineX = 0;
|
||||
this.current.y = this.current.lineY = 0;
|
||||
},
|
||||
@ -2814,6 +2823,9 @@ var CanvasGraphics = (function() {
|
||||
moveText: function (x, y) {
|
||||
this.current.x = this.current.lineX += x;
|
||||
this.current.y = this.current.lineY += y;
|
||||
if (this.ctx.$setCurrentX) {
|
||||
this.ctx.$setCurrentX(this.current.x)
|
||||
}
|
||||
},
|
||||
setLeadingMoveText: function(x, y) {
|
||||
this.setLeading(-y);
|
||||
@ -2821,6 +2833,10 @@ var CanvasGraphics = (function() {
|
||||
},
|
||||
setTextMatrix: function(a, b, c, d, e, f) {
|
||||
this.current.textMatrix = [ a, b, c, d, e, f ];
|
||||
|
||||
if (this.ctx.$setCurrentX) {
|
||||
this.$setCurrentX(0)
|
||||
}
|
||||
this.current.x = this.current.lineX = 0;
|
||||
this.current.y = this.current.lineY = 0;
|
||||
},
|
||||
@ -2831,11 +2847,15 @@ var CanvasGraphics = (function() {
|
||||
this.ctx.save();
|
||||
this.ctx.transform.apply(this.ctx, this.current.textMatrix);
|
||||
this.ctx.scale(1, -1);
|
||||
this.ctx.translate(0, -2 * this.current.y);
|
||||
|
||||
text = Fonts.charsToUnicode(text);
|
||||
this.ctx.fillText(text, this.current.x, this.current.y);
|
||||
this.current.x += this.ctx.measureText(text).width;
|
||||
if (this.ctx.$showText) {
|
||||
this.ctx.$showText(this.current.y, Fonts.charsToUnicode(text));
|
||||
} else {
|
||||
console.log(text, this.current.x);
|
||||
text = Fonts.charsToUnicode(text);
|
||||
this.ctx.fillText(text, 0, 0);
|
||||
this.current.x += this.ctx.measureText(text).width;
|
||||
}
|
||||
|
||||
this.ctx.restore();
|
||||
},
|
||||
@ -2843,7 +2863,11 @@ var CanvasGraphics = (function() {
|
||||
for (var i = 0; i < arr.length; ++i) {
|
||||
var e = arr[i];
|
||||
if (IsNum(e)) {
|
||||
this.current.x -= e * 0.001 * this.current.fontSize;
|
||||
if (this.ctx.$addCurrentX) {
|
||||
this.ctx.$addCurrentX(-e * 0.001 * this.current.fontSize)
|
||||
} else {
|
||||
this.current.x -= e * 0.001 * this.current.fontSize;
|
||||
}
|
||||
} else if (IsString(e)) {
|
||||
this.showText(e);
|
||||
} else {
|
||||
|
@ -11,11 +11,63 @@ var myWorker = new Worker('worker.js');
|
||||
const WAIT = 0;
|
||||
const CANVAS_PROXY_STACK = 1;
|
||||
const LOG = 2;
|
||||
const FONT = 3;
|
||||
|
||||
var currentX = 0;
|
||||
var currentXStack = [];
|
||||
var special = {
|
||||
"$setCurrentX": function(value) {
|
||||
currentX = value;
|
||||
},
|
||||
|
||||
"$addCurrentX": function(value) {
|
||||
currentX += value;
|
||||
},
|
||||
|
||||
"$saveCurrentX": function() {
|
||||
currentXStack.push(currentX);
|
||||
},
|
||||
|
||||
"$restoreCurrentX": function() {
|
||||
currentX = currentXStack.pop();
|
||||
},
|
||||
|
||||
"$showText": function(y, text) {
|
||||
console.log(text, currentX, y, this.measureText(text).width);
|
||||
|
||||
this.translate(currentX, -1 * y);
|
||||
this.fillText(text, 0, 0);
|
||||
currentX += this.measureText(text).width;
|
||||
}
|
||||
}
|
||||
|
||||
function renderProxyCanvas(stack) {
|
||||
// for (var i = 0; i < stack.length; i++) {
|
||||
for (var i = 0; i < 1000; i++) {
|
||||
var opp = stack[i];
|
||||
if (opp[0] == "$") {
|
||||
// console.log("set property", opp[1], opp[2]);
|
||||
if (opp[1] == "font") {
|
||||
ctx[opp[1]] = opp[2];
|
||||
// console.log("font", opp[2]);
|
||||
} else {
|
||||
ctx[opp[1]] = opp[2];
|
||||
}
|
||||
|
||||
} else if (opp[0] in special) {
|
||||
// console.log("sepcial", opp[0], opp[1])
|
||||
special[opp[0]].apply(ctx, opp[1]);
|
||||
} else {
|
||||
// console.log("execute", opp[0], opp[1]);
|
||||
ctx[opp[0]].apply(ctx, opp[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var onMessageState = WAIT;
|
||||
myWorker.onmessage = function(event) {
|
||||
var data = event.data;
|
||||
console.log("onMessageRaw", data);
|
||||
// console.log("onMessageRaw", data);
|
||||
switch (onMessageState) {
|
||||
case WAIT:
|
||||
if (typeof data != "string") {
|
||||
@ -28,11 +80,31 @@ myWorker.onmessage = function(event) {
|
||||
case "canvas_proxy_stack":
|
||||
onMessageState = CANVAS_PROXY_STACK;
|
||||
return;
|
||||
case "font":
|
||||
onMessageState = FONT;
|
||||
return;
|
||||
default:
|
||||
throw "unkown state: " + data
|
||||
}
|
||||
break;
|
||||
|
||||
case FONT:
|
||||
data = JSON.parse(data);
|
||||
var base64 = window.btoa(data.str);
|
||||
|
||||
// Add the @font-face rule to the document
|
||||
var url = "url(data:" + data.mimetype + ";base64," + base64 + ");";
|
||||
var rule = "@font-face { font-family:'" + data.fontName + "';src:" + url + "}";
|
||||
var styleSheet = document.styleSheets[0];
|
||||
|
||||
// ONCE you uncomment this, there is no font painted at all :(
|
||||
// styleSheet.insertRule(rule, styleSheet.length);
|
||||
|
||||
console.log("added font", data.fontName);
|
||||
// console.log(rule);
|
||||
onMessageState = WAIT;
|
||||
break;
|
||||
|
||||
case LOG:
|
||||
console.log.apply(console, JSON.parse(data));
|
||||
onMessageState = WAIT;
|
||||
@ -40,17 +112,14 @@ myWorker.onmessage = function(event) {
|
||||
|
||||
case CANVAS_PROXY_STACK:
|
||||
var stack = JSON.parse(data);
|
||||
for (var i = 0; i < stack.length; i++) {
|
||||
var opp = stack[i];
|
||||
if (opp[0] == "$") {
|
||||
console.log("set property", opp[1], opp[2]);
|
||||
ctx[opp[1]] = opp[2];
|
||||
} else {
|
||||
console.log("execute", opp[0], opp[1]);
|
||||
ctx[opp[0]].apply(ctx, opp[1]);
|
||||
}
|
||||
}
|
||||
console.log("canvas stack", stack.length)
|
||||
// console.log(stack.length);
|
||||
onMessageState = WAIT;
|
||||
// return;
|
||||
|
||||
setTimeout(function() {
|
||||
renderProxyCanvas(stack);
|
||||
}, 2000);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -75,6 +144,10 @@ function open(url) {
|
||||
|
||||
window.onload = function() {
|
||||
var ctx = window.ctx = document.getElementById("canvas").getContext("2d");
|
||||
ctx.save();
|
||||
ctx.fillStyle = "rgb(255, 255, 255)";
|
||||
ctx.fillRect(0, 0, canvas.width, canvas.height);
|
||||
ctx.restore();
|
||||
// for (var name in ctx) {
|
||||
// if (!(ctx[name] instanceof Function)) {
|
||||
// console.log('"' + name + '": "' + ctx[name] + '",');
|
||||
|
56
worker.js
56
worker.js
@ -40,6 +40,7 @@ var canvas = new CanvasProxy(1224, 1584);
|
||||
// canvas.flush();
|
||||
log("test");
|
||||
|
||||
var pageInterval;
|
||||
onmessage = function(event) {
|
||||
var data = event.data;
|
||||
var pdfDocument = new PDFDoc(new Stream(data));
|
||||
@ -59,36 +60,39 @@ onmessage = function(event) {
|
||||
|
||||
//
|
||||
var fontsReady = true;
|
||||
// Inspect fonts and translate the missing one
|
||||
var count = fonts.length;
|
||||
for (var i = 0; i < count; i++) {
|
||||
var font = fonts[i];
|
||||
if (Fonts[font.name]) {
|
||||
fontsReady = fontsReady && !Fonts[font.name].loading;
|
||||
continue;
|
||||
}
|
||||
// Inspect fonts and translate the missing one
|
||||
var count = fonts.length;
|
||||
for (var i = 0; i < count; i++) {
|
||||
var font = fonts[i];
|
||||
if (Fonts[font.name]) {
|
||||
fontsReady = fontsReady && !Fonts[font.name].loading;
|
||||
continue;
|
||||
}
|
||||
|
||||
new Font(font.name, font.file, font.properties);
|
||||
fontsReady = false;
|
||||
}
|
||||
new Font(font.name, font.file, font.properties);
|
||||
fontsReady = false;
|
||||
}
|
||||
|
||||
function delayLoadFont() {
|
||||
for (var i = 0; i < count; i++) {
|
||||
if (Fonts[font.name].loading)
|
||||
return;
|
||||
}
|
||||
clearInterval(pageInterval);
|
||||
page.display(gfx);
|
||||
// function delayLoadFont() {
|
||||
// for (var i = 0; i < count; i++) {
|
||||
// if (Fonts[font.name].loading)
|
||||
// return;
|
||||
// }
|
||||
// clearInterval(pageInterval);
|
||||
// page.display(gfx);
|
||||
//
|
||||
// log("flush");
|
||||
// canvas.flush();
|
||||
// };
|
||||
|
||||
canvas.flush();
|
||||
};
|
||||
// if (fontsReady) {
|
||||
// delayLoadFont();
|
||||
// } else {
|
||||
// pageInterval = setInterval(delayLoadFont, 10);
|
||||
// }
|
||||
|
||||
if (fontsReady) {
|
||||
delayLoadFont();
|
||||
} else {
|
||||
pageInterval = setInterval(delayLoadFont, 10);
|
||||
}
|
||||
postMessage(page.code.src);
|
||||
page.display(gfx);
|
||||
canvas.flush();
|
||||
}
|
||||
|
||||
// function open(url) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user