@@ -345,10 +345,6 @@ _html2canvas.Parse = function (images, options) {
345345 } ) ;
346346 }
347347
348- function pathArc ( x , y , cornerX , cornerY , radius ) {
349- return [ "arc" , cornerX , cornerY , x , y , radius ] ;
350- }
351-
352348 var getCurvePoints = ( function ( kappa ) {
353349
354350 return function ( x , y , r1 , r2 ) {
@@ -445,6 +441,20 @@ _html2canvas.Parse = function (images, options) {
445441 } ;
446442 }
447443
444+ function parseCorner ( borderArgs , radius1 , radius2 , corner1 , corner2 , x , y ) {
445+ if ( radius1 [ 0 ] > 0 || radius1 [ 1 ] > 0 ) {
446+ borderArgs . push ( [ "line" , corner1 [ 0 ] . start . x , corner1 [ 0 ] . start . y ] ) ;
447+ corner1 [ 0 ] . curveTo ( borderArgs ) ;
448+ corner1 [ 1 ] . curveTo ( borderArgs ) ;
449+ } else {
450+ borderArgs . push ( [ "line" , x , y ] ) ;
451+ }
452+
453+ if ( radius2 [ 0 ] > 0 || radius2 [ 1 ] > 0 ) {
454+ borderArgs . push ( [ "line" , corner2 [ 0 ] . start . x , corner2 [ 0 ] . start . y ] ) ;
455+ }
456+ }
457+
448458 function drawSide ( borderData , radius1 , radius2 , outer1 , inner1 , outer2 , inner2 ) {
449459 var borderArgs = [ ] ;
450460
@@ -475,10 +485,6 @@ _html2canvas.Parse = function (images, options) {
475485 return borderArgs ;
476486 }
477487
478- function getBorderBounds ( element ) {
479- var backgroundClip = getCSS ( element , 'backgroundClip' ) ;
480- }
481-
482488 function calculateCurvePoints ( bounds , borderRadius , borders ) {
483489
484490 var x = bounds . left ,
@@ -556,36 +562,61 @@ _html2canvas.Parse = function (images, options) {
556562 Math . max ( 0 , blh - borders [ 3 ] . width ) ,
557563 Math . max ( 0 , blv - borders [ 2 ] . width )
558564 ) . bottomLeft . subdivide ( 0.5 )
565+ } ;
566+ }
567+
568+ function getBorderClip ( element , borderPoints , borders , radius , bounds ) {
569+ var backgroundClip = getCSS ( element , 'backgroundClip' ) ,
570+ borderArgs = [ ] ;
571+
572+ switch ( backgroundClip ) {
573+ case "content-box" :
574+ case "padding-box" :
575+ parseCorner ( borderArgs , radius [ 0 ] , radius [ 1 ] , borderPoints . topLeftInner , borderPoints . topRightInner , bounds . left + borders [ 3 ] . width , bounds . top + borders [ 0 ] . width ) ;
576+ parseCorner ( borderArgs , radius [ 1 ] , radius [ 2 ] , borderPoints . topRightInner , borderPoints . bottomRightInner , bounds . left + bounds . width - borders [ 1 ] . width , bounds . top + borders [ 0 ] . width ) ;
577+ parseCorner ( borderArgs , radius [ 2 ] , radius [ 3 ] , borderPoints . bottomRightInner , borderPoints . bottomLeftInner , bounds . left + bounds . width - borders [ 1 ] . width , bounds . top + bounds . height - borders [ 2 ] . width ) ;
578+ parseCorner ( borderArgs , radius [ 3 ] , radius [ 0 ] , borderPoints . bottomLeftInner , borderPoints . topLeftInner , bounds . left + borders [ 3 ] . width , bounds . top + bounds . height - borders [ 2 ] . width ) ;
579+ break ;
580+
581+ default :
582+ parseCorner ( borderArgs , radius [ 0 ] , radius [ 1 ] , borderPoints . topLeftOuter , borderPoints . topRightOuter , bounds . left , bounds . top ) ;
583+ parseCorner ( borderArgs , radius [ 1 ] , radius [ 2 ] , borderPoints . topRightOuter , borderPoints . bottomRightOuter , bounds . left + bounds . width , bounds . top ) ;
584+ parseCorner ( borderArgs , radius [ 2 ] , radius [ 3 ] , borderPoints . bottomRightOuter , borderPoints . bottomLeftOuter , bounds . left + bounds . width , bounds . top + bounds . height ) ;
585+ parseCorner ( borderArgs , radius [ 3 ] , radius [ 0 ] , borderPoints . bottomLeftOuter , borderPoints . topLeftOuter , bounds . left , bounds . top + bounds . height ) ;
586+ break ;
559587 }
588+
589+ return borderArgs ;
560590 }
561591
562- function parseBorders ( element , ctx , bounds , clip , borders ) {
592+ function parseBorders ( element , bounds , borders ) {
563593 var x = bounds . left ,
564594 y = bounds . top ,
565595 width = bounds . width ,
566596 height = bounds . height ,
567597 borderSide ,
568- borderData ,
569598 bx ,
570599 by ,
571600 bw ,
572601 bh ,
573602 borderArgs ,
574- borderBounds ,
575603 // http://www.w3.org/TR/css3-background/#the-border-radius
576604 borderRadius = getBorderRadiusData ( element ) ,
577- borderPoints = calculateCurvePoints ( bounds , borderRadius , borders ) ;
605+ borderPoints = calculateCurvePoints ( bounds , borderRadius , borders ) ,
606+ borderData = {
607+ clip : getBorderClip ( element , borderPoints , borders , borderRadius , bounds ) ,
608+ borders : [ ]
609+ } ;
578610
579611 for ( borderSide = 0 ; borderSide < 4 ; borderSide ++ ) {
580- borderData = borders [ borderSide ] ;
581- borderArgs = [ ] ;
582- if ( borderData . width > 0 ) {
612+
613+ if ( borders [ borderSide ] . width > 0 ) {
583614 bx = x ;
584615 by = y ;
585616 bw = width ;
586617 bh = height - ( borders [ 2 ] . width ) ;
587618
588- switch ( borderSide ) {
619+ switch ( borderSide ) {
589620 case 0 :
590621 // top border
591622 bh = borders [ 0 ] . width ;
@@ -638,33 +669,31 @@ _html2canvas.Parse = function (images, options) {
638669 break ;
639670 }
640671
641- borderBounds = {
642- left :bx ,
643- top :by ,
644- width : bw ,
645- height :bh
646- } ;
672+ borderData . borders . push ( {
673+ args : borderArgs ,
674+ color : borders [ borderSide ] . color
675+ } ) ;
647676
648- if ( clip ) {
649- borderBounds = clipBounds ( borderBounds , clip ) ;
650- }
651- renderBorders ( ctx , borderArgs , borderBounds , borderData . color ) ;
652677 }
653678 }
654679
655- return borders ;
680+ return borderData ;
656681 }
657682
658- function renderBorders ( ctx , borderArgs , borderBounds , color ) {
659- if ( borderBounds . width > 0 && borderBounds . height > 0 ) {
660- if ( color !== "transparent" ) {
661- ctx . setVariable ( "fillStyle" , color ) ;
662- var shape = ctx . drawShape ( ) ;
663- borderArgs . forEach ( function ( border , index ) {
664- shape [ ( index === 0 ) ? "moveTo" : border [ 0 ] + "To" ] . apply ( null , border . slice ( 1 ) ) ;
665- } ) ;
666- numDraws += 1 ;
667- }
683+ function createShape ( ctx , args ) {
684+ var shape = ctx . drawShape ( ) ;
685+ args . forEach ( function ( border , index ) {
686+ shape [ ( index === 0 ) ? "moveTo" : border [ 0 ] + "To" ] . apply ( null , border . slice ( 1 ) ) ;
687+ } ) ;
688+ return shape ;
689+ }
690+
691+ function renderBorders ( ctx , borderArgs , color ) {
692+ if ( color !== "transparent" ) {
693+ ctx . setVariable ( "fillStyle" , color ) ;
694+ createShape ( ctx , borderArgs ) ;
695+ ctx . fill ( ) ;
696+ numDraws += 1 ;
668697 }
669698 }
670699
@@ -930,14 +959,23 @@ _html2canvas.Parse = function (images, options) {
930959 stack = createStack ( element , parentStack , bounds ) ,
931960 borders = stack . borders ,
932961 ctx = stack . ctx ,
933- backgroundBounds = getBackgroundBounds ( borders , bounds , stack . clip ) ;
962+ backgroundBounds = getBackgroundBounds ( borders , bounds , stack . clip ) ,
963+ borderData = parseBorders ( element , bounds , borders ) ,
964+ clipPath = createShape ( ctx , borderData . clip ) ;
965+
966+ ctx . save ( ) ;
967+ ctx . clip ( ) ;
934968
935969 if ( backgroundBounds . height > 0 && backgroundBounds . width > 0 ) {
936- renderBackgroundColor ( ctx , backgroundBounds , bgcolor ) ;
970+ renderBackgroundColor ( ctx , bounds , bgcolor ) ;
937971 renderBackgroundImage ( element , backgroundBounds , ctx ) ;
938972 }
939973
940- parseBorders ( element , ctx , bounds , stack . clip , borders ) ;
974+ ctx . restore ( ) ;
975+
976+ borderData . borders . forEach ( function ( border ) {
977+ renderBorders ( ctx , border . args , border . color ) ;
978+ } ) ;
941979
942980 switch ( element . nodeName ) {
943981 case "IMG" :
0 commit comments