From 71b0727125850c2c8a84baefdf78183d29c9e341 Mon Sep 17 00:00:00 2001 From: MoyuScript Date: Sat, 16 Jul 2011 23:56:49 +0300 Subject: [PATCH] fixed text draw issue for opera --- build/html2canvas.js | 30 +++++++++++++++++------- build/html2canvas.min.js | 5 ++-- build/jquery.plugin.html2canvas.js | 5 ++-- src/Background.js | 4 ++-- src/Core.js | 13 +++++++--- src/Draw.js | 3 ++- src/Text.js | 10 ++++++-- src/plugins/jquery.plugin.html2canvas.js | 5 ++-- tests/text-underline.html | 1 + 9 files changed, 54 insertions(+), 22 deletions(-) diff --git a/build/html2canvas.js b/build/html2canvas.js index 05a7a6e..4c90e42 100644 --- a/build/html2canvas.js +++ b/build/html2canvas.js @@ -63,11 +63,15 @@ function html2canvas(el, userOptions) { // test how to measure text bounding boxes this.useRangeBounds = false; + + // Check disabled as Opera doesn't provide bounds.height/bottom even though it supports the method. + // TODO take the check back into use, but fix the issue for Opera + /* if (document.createRange){ var r = document.createRange(); this.useRangeBounds = new Boolean(r.getBoundingClientRect); - } - + }*/ + // Start script this.init(); } @@ -143,6 +147,8 @@ html2canvas.prototype.start = function(){ if (this.images.length == 0 || this.imagesLoaded==this.images.length/2){ this.log('Started parsing'); + this.bodyOverflow = document.getElementsByTagName('body')[0].style.overflow; + document.getElementsByTagName('body')[0].style.overflow = "hidden"; this.newElement(this.element); this.parseElement(this.element); @@ -157,7 +163,8 @@ html2canvas.prototype.start = function(){ html2canvas.prototype.finish = function(){ this.log("Finished rendering"); - + document.getElementsByTagName('body')[0].style.overflow = this.bodyOverflow; + if (this.opts.renderViewport){ // let's crop it to viewport only then var newCanvas = document.createElement('canvas'); @@ -194,11 +201,11 @@ html2canvas.prototype.drawBackground = function(el,bounds){ case "repeat-x": this.drawbackgroundRepeatX(image,bgp,bounds.left,bounds.top,bounds.width,bounds.height); break; - + case "repeat-y": this.drawbackgroundRepeatY(image,bgp,bounds.left,bounds.top,bounds.width,bounds.height); break; - + case "no-repeat": this.drawBackgroundRepeat(image,bgp.left+bounds.left,bgp.top+bounds.top,Math.min(bounds.width,image.width),Math.min(bounds.height,image.height),bounds.left,bounds.top); @@ -499,7 +506,7 @@ html2canvas.prototype.newElement = function(el){ */ html2canvas.prototype.printText = function(currentText,x,y){ - if (this.trim(currentText).length>0){ + if (this.trim(currentText).length>0){ this.ctx.fillText(currentText,x,y); } } @@ -507,6 +514,7 @@ html2canvas.prototype.printText = function(currentText,x,y){ // Drawing a rectangle html2canvas.prototype.newRect = function(x,y,w,h,bgcolor){ + if (bgcolor!="transparent"){ this.ctx.fillStyle = bgcolor; this.ctx.fillRect (x, y, w, h); @@ -643,13 +651,19 @@ html2canvas.prototype.newText = function(el,textNode){ wrapElement.appendChild(oldTextNode.cloneNode(true)); parent.replaceChild(wrapElement,oldTextNode); - var bounds = this.getBounds(wrapElement); + + + var bounds = this.getBounds(wrapElement); + + parent.replaceChild(backupText,wrapElement); } - + + + this.printText(oldTextNode.nodeValue,bounds.left,bounds.bottom); diff --git a/build/html2canvas.min.js b/build/html2canvas.min.js index dd3f5ae..60aa7a6 100644 --- a/build/html2canvas.min.js +++ b/build/html2canvas.min.js @@ -6,9 +6,10 @@ * Released under MIT License */ -function html2canvas(a,b){this.opts=this.extendObj(b||{},{logging:!1,ready:function(a){document.body.appendChild(a)},renderViewport:!0});this.element=a;this.imagesLoaded=0;this.images=[];this.fontData=[];this.ignoreElements="IFRAME|OBJECT|PARAM";this.useRangeBounds=!1;if(document.createRange){var c=document.createRange();this.useRangeBounds=new Boolean(c.getBoundingClientRect)}this.init()} +function html2canvas(a,b){this.opts=this.extendObj(b||{},{logging:!1,ready:function(a){document.body.appendChild(a)},renderViewport:!0});this.element=a;this.imagesLoaded=0;this.images=[];this.fontData=[];this.ignoreElements="IFRAME|OBJECT|PARAM";this.useRangeBounds=!1;this.init()} html2canvas.prototype.init=function(){var a=this;this.canvas=document.createElement("canvas");this.canvas.width=$(document).width();this.canvas.height=$(document).height()+10;if(this.canvas.getContext)this.ctx=this.canvas.getContext("2d");this.ctx?(this.ctx.textBaseline="bottom",this.log("Finding background images"),this.getImages(this.element),this.log("Finding images"),this.each(document.images,function(b,c){a.preloadImage(a.getAttr(c,"src"))}),this.images.length==0&&this.start()):this.log("Canvas not available")}; -html2canvas.prototype.start=function(){if(this.images.length==0||this.imagesLoaded==this.images.length/2)this.log("Started parsing"),this.newElement(this.element),this.parseElement(this.element)};html2canvas.prototype.finish=function(){this.log("Finished rendering");if(this.opts.renderViewport){var a=document.createElement("canvas");a.getContext("2d");a.width=window.innerWidth;a.height=window.innerHeight}this.opts.ready(this.canvas)}; +html2canvas.prototype.start=function(){if(this.images.length==0||this.imagesLoaded==this.images.length/2)this.log("Started parsing"),this.bodyOverflow=document.getElementsByTagName("body")[0].style.overflow,document.getElementsByTagName("body")[0].style.overflow="hidden",this.newElement(this.element),this.parseElement(this.element)}; +html2canvas.prototype.finish=function(){this.log("Finished rendering");document.getElementsByTagName("body")[0].style.overflow=this.bodyOverflow;if(this.opts.renderViewport){var a=document.createElement("canvas");a.getContext("2d");a.width=window.innerWidth;a.height=window.innerHeight}this.opts.ready(this.canvas)}; html2canvas.prototype.drawBackground=function(a,b){var c=this.getCSS(a,"background-image"),e=this.getCSS(a,"background-repeat");if(typeof c!="undefined"&&/^(1|none)$/.test(c)==!1){var c=this.backgroundImageUrl(c),d=this.loadImage(c),h=this.getBackgroundPosition(a,b,d);if(d)switch(e){case "repeat-x":this.drawbackgroundRepeatX(d,h,b.left,b.top,b.width,b.height);break;case "repeat-y":this.drawbackgroundRepeatY(d,h,b.left,b.top,b.width,b.height);break;case "no-repeat":this.drawBackgroundRepeat(d,h.left+ b.left,h.top+b.top,Math.min(b.width,d.width),Math.min(b.height,d.height),b.left,b.top);break;default:var g;h.top-=Math.ceil(h.top/d.height)*d.height;for(c=b.top+h.top;c<=b.height+b.top;)e=Math.min(d.height,b.height+b.top-c),e=Math.floor(c+d.height)>e+c?e+c-c:d.height,c0&&(h.top+=g),c=Math.floor(c+d.height)-g}else this.log("Error loading background:"+c)}}; html2canvas.prototype.backgroundImageUrl=function(a){a.substr(0,5)=='url("'?(a=a.substr(5),a=a.substr(0,a.length-2)):(a=a.substr(4),a=a.substr(0,a.length-1));return a};html2canvas.prototype.getBackgroundPosition=function(a,b,c){var e=this.getCSS(a,"background-position").split(" "),d;e[0].indexOf("%")!=-1?(d=parseFloat(e[0])/100,a=b.width*d-c.width*d):a=parseInt(e[0],10);e[1].indexOf("%")!=-1?(d=parseFloat(e[1])/100,b=b.height*d-c.height*d):b=parseInt(e[1],10);return{top:b,left:a}}; diff --git a/build/jquery.plugin.html2canvas.js b/build/jquery.plugin.html2canvas.js index 53a7bde..6f1f863 100644 --- a/build/jquery.plugin.html2canvas.js +++ b/build/jquery.plugin.html2canvas.js @@ -41,8 +41,9 @@ timeoutTimer, timer = date.getTime(); - new html2canvas(this.get(0),{ - ready:function(canvas){ + new html2canvas(this.get(0), { + loggine: true, + ready: function(canvas) { var finishTime = new Date(); // console.log((finishTime.getTime()-timer)/1000); diff --git a/src/Background.js b/src/Background.js index 2e961af..fee5c4b 100644 --- a/src/Background.js +++ b/src/Background.js @@ -22,11 +22,11 @@ html2canvas.prototype.drawBackground = function(el,bounds){ case "repeat-x": this.drawbackgroundRepeatX(image,bgp,bounds.left,bounds.top,bounds.width,bounds.height); break; - + case "repeat-y": this.drawbackgroundRepeatY(image,bgp,bounds.left,bounds.top,bounds.width,bounds.height); break; - + case "no-repeat": this.drawBackgroundRepeat(image,bgp.left+bounds.left,bgp.top+bounds.top,Math.min(bounds.width,image.width),Math.min(bounds.height,image.height),bounds.left,bounds.top); diff --git a/src/Core.js b/src/Core.js index bd0f540..ed12102 100644 --- a/src/Core.js +++ b/src/Core.js @@ -33,11 +33,15 @@ function html2canvas(el, userOptions) { // test how to measure text bounding boxes this.useRangeBounds = false; + + // Check disabled as Opera doesn't provide bounds.height/bottom even though it supports the method. + // TODO take the check back into use, but fix the issue for Opera + /* if (document.createRange){ var r = document.createRange(); this.useRangeBounds = new Boolean(r.getBoundingClientRect); - } - + }*/ + // Start script this.init(); } @@ -113,6 +117,8 @@ html2canvas.prototype.start = function(){ if (this.images.length == 0 || this.imagesLoaded==this.images.length/2){ this.log('Started parsing'); + this.bodyOverflow = document.getElementsByTagName('body')[0].style.overflow; + document.getElementsByTagName('body')[0].style.overflow = "hidden"; this.newElement(this.element); this.parseElement(this.element); @@ -127,7 +133,8 @@ html2canvas.prototype.start = function(){ html2canvas.prototype.finish = function(){ this.log("Finished rendering"); - + document.getElementsByTagName('body')[0].style.overflow = this.bodyOverflow; + if (this.opts.renderViewport){ // let's crop it to viewport only then var newCanvas = document.createElement('canvas'); diff --git a/src/Draw.js b/src/Draw.js index 2386489..4242510 100644 --- a/src/Draw.js +++ b/src/Draw.js @@ -98,7 +98,7 @@ html2canvas.prototype.newElement = function(el){ */ html2canvas.prototype.printText = function(currentText,x,y){ - if (this.trim(currentText).length>0){ + if (this.trim(currentText).length>0){ this.ctx.fillText(currentText,x,y); } } @@ -106,6 +106,7 @@ html2canvas.prototype.printText = function(currentText,x,y){ // Drawing a rectangle html2canvas.prototype.newRect = function(x,y,w,h,bgcolor){ + if (bgcolor!="transparent"){ this.ctx.fillStyle = bgcolor; this.ctx.fillRect (x, y, w, h); diff --git a/src/Text.js b/src/Text.js index cb82a9a..517a3c3 100644 --- a/src/Text.js +++ b/src/Text.js @@ -61,13 +61,19 @@ html2canvas.prototype.newText = function(el,textNode){ wrapElement.appendChild(oldTextNode.cloneNode(true)); parent.replaceChild(wrapElement,oldTextNode); - var bounds = this.getBounds(wrapElement); + + + var bounds = this.getBounds(wrapElement); + + parent.replaceChild(backupText,wrapElement); } - + + + this.printText(oldTextNode.nodeValue,bounds.left,bounds.bottom); diff --git a/src/plugins/jquery.plugin.html2canvas.js b/src/plugins/jquery.plugin.html2canvas.js index a81f006..c62cbc5 100644 --- a/src/plugins/jquery.plugin.html2canvas.js +++ b/src/plugins/jquery.plugin.html2canvas.js @@ -11,8 +11,9 @@ timeoutTimer, timer = date.getTime(); - new html2canvas(this.get(0),{ - ready:function(canvas){ + new html2canvas(this.get(0), { + loggine: true, + ready: function(canvas) { var finishTime = new Date(); // console.log((finishTime.getTime()-timer)/1000); diff --git a/tests/text-underline.html b/tests/text-underline.html index ec2c43e..87086e6 100644 --- a/tests/text-underline.html +++ b/tests/text-underline.html @@ -15,6 +15,7 @@