From cce6e3537c0c1bb610040b6b69b6d0423e760bdb Mon Sep 17 00:00:00 2001 From: Niklas von Hertzen Date: Tue, 26 Jun 2012 15:15:46 +0300 Subject: [PATCH] corrected border drawing with multiple colors initial code for border-radius implemented --- src/Parse.js | 77 ++++++++++++++++++++++++++++++++++------- src/Queue.js | 38 ++++++++++++++++++++ src/renderers/Canvas.js | 17 +++++++-- tests/borders.html | 5 +++ 4 files changed, 123 insertions(+), 14 deletions(-) diff --git a/src/Parse.js b/src/Parse.js index fb8bea1..0914135 100644 --- a/src/Parse.js +++ b/src/Parse.js @@ -4,7 +4,7 @@ http://www.twitter.com/niklasvh Released under MIT License -*/ + */ /* * New function for traversing elements @@ -131,7 +131,7 @@ _html2canvas.Parse = function ( images, options ) { // Drawing a rectangle function renderRect (ctx, x, y, w, h, bgcolor) { - if (bgcolor !=="transparent"){ + if ( bgcolor !== "transparent" ){ ctx.setVariable("fillStyle", bgcolor); ctx.fillRect (x, y, w, h); numDraws+=1; @@ -308,7 +308,7 @@ _html2canvas.Parse = function ( images, options ) { /* need to be defined in the order as defined in http://www.w3.org/TR/CSS21/fonts.html#font-shorthand to properly work in Firefox - */ + */ ctx.setVariable("font", font_style+ " " + font_variant + " " + bold + " " + size + " " + family); if (align){ @@ -450,9 +450,9 @@ _html2canvas.Parse = function ( images, options ) { if ( el.parentNode ) { while( childs[ ++i ] !== el ) { - if ( childs[ i ].nodeType === 1 ) { - count++; - } + if ( childs[ i ].nodeType === 1 ) { + count++; + } } return count; } else { @@ -619,6 +619,7 @@ _html2canvas.Parse = function ( images, options ) { by, bw, bh, + borderArgs, borderBounds, borders = (function(el){ var borders = [], @@ -634,12 +635,24 @@ _html2canvas.Parse = function ( images, options ) { return borders; - }(el)); + }(el)), + borderRadius = (function( el ) { + var borders = [], + sides = ["TopLeft","TopRight","BottomLeft","BottomRight"], + s; + + for (s = 0; s < 4; s+=1){ + borders.push( getCSS(el, 'border' + sides[s] + 'Radius') ); + } + + return borders; + })( el ); - for (borderSide = 0; borderSide < 4; borderSide+=1){ - borderData = borders[borderSide]; + for ( borderSide = 0; borderSide < 4; borderSide+=1 ) { + borderData = borders[ borderSide ]; + borderArgs = []; if (borderData.width>0){ bx = x; by = y; @@ -650,20 +663,44 @@ _html2canvas.Parse = function ( images, options ) { case 0: // top border bh = borders[0].width; + + borderArgs[ 0 ] = [ bx, by ]; // top left + borderArgs[ 1 ] = [ bx + bw, by ]; // top right + borderArgs[ 2 ] = [ bx + bw - borders[ 1 ].width, by + bh ]; // bottom right + borderArgs[ 3 ] = [ bx + borders[ 3 ].width, by + bh ]; // bottom left + break; case 1: // right border bx = x + w - (borders[1].width); bw = borders[1].width; + + borderArgs[ 0 ] = [ bx, by + borders[ 0 ].width]; // top left + borderArgs[ 1 ] = [ bx + bw, by ]; // top right + borderArgs[ 2 ] = [ bx + bw, by + bh + borders[ 2 ].width ]; // bottom right + borderArgs[ 3 ] = [ bx, by + bh ]; // bottom left + break; case 2: // bottom border by = (by + h) - (borders[2].width); bh = borders[2].width; + + borderArgs[ 0 ] = [ bx + borders[ 3 ].width, by ]; // top left + borderArgs[ 1 ] = [ bx + bw - borders[ 2 ].width, by ]; // top right + borderArgs[ 2 ] = [ bx + bw, by + bh ]; // bottom right + borderArgs[ 3 ] = [ bx, by + bh ]; // bottom left + break; case 3: // left border bw = borders[3].width; + + borderArgs[ 0 ] = [ bx, by ]; // top left + borderArgs[ 1 ] = [ bx + bw, by + borders[ 0 ].width ]; // top right + borderArgs[ 2 ] = [ bx + bw, by + bh ]; // bottom right + borderArgs[ 3 ] = [ bx, by + bh + borders[ 2 ].width ]; // bottom left + break; } @@ -679,8 +716,24 @@ _html2canvas.Parse = function ( images, options ) { } - if (borderBounds.width>0 && borderBounds.height>0){ - renderRect(ctx, bx, by, borderBounds.width, borderBounds.height, borderData.color); + if ( borderBounds.width > 0 && borderBounds.height > 0 ) { + + if ( borderData.color !== "transparent" ){ + ctx.setVariable( "fillStyle", borderData.color ); + + var shape = ctx.drawShape(); + shape.moveTo.apply( null, borderArgs[ 0 ] ); // top left + shape.lineTo.apply( null, borderArgs[ 1 ] ); // top right + shape.lineTo.apply( null, borderArgs[ 2 ] ); // bottom right + shape.lineTo.apply( null, borderArgs[ 3 ] ); // bottom left + // ctx.fillRect (x, y, w, h); + numDraws+=1; + } + + + + + // renderRect(ctx, bx, by, borderBounds.width, borderBounds.height, borderData.color); } @@ -1240,7 +1293,7 @@ _html2canvas.Parse = function ( images, options ) { /* SVG powered HTML rendering, non-tainted canvas available from FF 11+ onwards - */ + */ if ( support.svgRendering ) { (function( body ){ diff --git a/src/Queue.js b/src/Queue.js index 3113467..dab212d 100644 --- a/src/Queue.js +++ b/src/Queue.js @@ -18,6 +18,44 @@ function h2cRenderContext(width, height) { 'arguments': arguments }); }, + drawShape: function() { + + var shape = []; + + storage.push({ + type: "function", + name: "drawShape", + 'arguments': shape + }); + + return { + moveTo: function() { + shape.push({ + name: "moveTo", + 'arguments': arguments + }); + }, + lineTo: function() { + shape.push({ + name: "lineTo", + 'arguments': arguments + }); + }, + bezierCurveTo: function() { + shape.push({ + name: "bezierCurveTo", + 'arguments': arguments + }); + }, + quadraticCurveTo: function() { + shape.push({ + name: "quadraticCurveTo", + 'arguments': arguments + }); + } + }; + + }, drawImage: function () { storage.push({ type: "function", diff --git a/src/renderers/Canvas.js b/src/renderers/Canvas.js index 4941fc4..0b1a1bc 100644 --- a/src/renderers/Canvas.js +++ b/src/renderers/Canvas.js @@ -147,11 +147,24 @@ _html2canvas.Renderer.Canvas = function( options ) { if (!usingFlashcanvas || renderItem['arguments'][0] + renderItem['arguments'][2] < flashMaxSize && renderItem['arguments'][1] + renderItem['arguments'][3] < flashMaxSize) { ctx.fillRect.apply( ctx, renderItem['arguments'] ); } - }else if(renderItem.name === "fillText") { + } else if (renderItem.name === "drawShape") { + + ( function( args ) { + + var i, len = args.length; + ctx.beginPath(); + for ( i = 0; i < len; i++ ) { + ctx[ args[ i ].name ].apply( ctx, args[ i ]['arguments'] ); + } + ctx.closePath(); + ctx.fill(); + })( renderItem['arguments'] ); + + } else if (renderItem.name === "fillText") { if (!usingFlashcanvas || renderItem['arguments'][1] < flashMaxSize && renderItem['arguments'][2] < flashMaxSize) { ctx.fillText.apply( ctx, renderItem['arguments'] ); } - }else if(renderItem.name === "drawImage") { + } else if (renderItem.name === "drawImage") { if (renderItem['arguments'][8] > 0 && renderItem['arguments'][7]){ if ( hasCTX && options.taintTest ) { diff --git a/tests/borders.html b/tests/borders.html index 262712a..aad026a 100644 --- a/tests/borders.html +++ b/tests/borders.html @@ -26,6 +26,8 @@ border: 23px double #669966; background-color: #ccffcc; padding-left: 5px; + border-left-color:yellow; + border-right-color: blueviolet; } #div2 { @@ -38,6 +40,9 @@ border: 20px dotted #990000; background-color: #ffdddd; text-align: center; + + border-top-color: blue; + border-top-width:0px; } #div4 {