Вход Регистрация
Файл: public_html/admin/vendors/easypiechart/examples/excanvas.js
Строк: 850
<?php
// Copyright 2006 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.


// Known Issues:
//
// * Patterns are not implemented.
// * Radial gradient are not implemented. The VML version of these look very
//   different from the canvas one.
// * Clipping paths are not implemented.
// * Coordsize. The width and height attribute have higher priority than the
//   width and height style values which isn't correct.
// * Painting mode isn't implemented.
// * Canvas width/height should is using content-box by default. IE in
//   Quirks mode will draw the canvas using border-box. Either change your
//   doctype to HTML5
//   (http://www.whatwg.org/specs/web-apps/current-work/#the-doctype)
//   or use Box Sizing Behavior from WebFX
//   (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
// * Non uniform scaling does not correctly scale strokes.
// * Optimize. There is always room for speed improvements.

// Only add this code if we do not already have a canvas implementation
if (!document.createElement('canvas').getContext) {

(function() {

  
// alias some functions to make (compiled) code shorter
  
var Math;
  var 
mr m.round;
  var 
ms m.sin;
  var 
mc m.cos;
  var 
abs m.abs;
  var 
sqrt m.sqrt;

  
// this is used for sub pixel precision
  
var 10;
  var 
Z2 2;

  
/**
   * This funtion is assigned to the <canvas> elements as element.getContext().
   * @this {HTMLElement}
   * @return {CanvasRenderingContext2D_}
   */
  
function getContext() {
    return 
this.context_ ||
        (
this.context_ = new CanvasRenderingContext2D_(this));
  }

  var 
slice = Array.prototype.slice;

  
/**
   * Binds a function to an object. The returned function will always use the
   * passed in {@code obj} as {@code this}.
   *
   * Example:
   *
   *   g = bind(f, obj, a, b)
   *   g(c, d) // will do f.call(obj, a, b, c, d)
   *
   * @param {Function} f The function to bind the object to
   * @param {Object} obj The object that should act as this when the function
   *     is called
   * @param {*} var_args Rest arguments that will be used as the initial
   *     arguments when the function is called
   * @return {Function} A new function that has bound this
   */
  
function bind(fobjvar_args) {
    var 
slice.call(arguments2);
    return function() {
      return 
f.apply(obja.concat(slice.call(arguments)));
    };
  }

  var 
G_vmlCanvasManager_ = {
    
init: function(opt_doc) {
      if (/
MSIE/.test(navigator.userAgent) && !window.opera) {
        var 
doc opt_doc || document;
        
// Create a dummy element so that IE will allow canvas elements to be
        // recognized.
        
doc.createElement('canvas');
        
doc.attachEvent('onreadystatechange'bind(this.init_thisdoc));
      }
    },

    
init_: function(doc) {
      
// create xmlns
      
if (!doc.namespaces['g_vml_']) {
        
doc.namespaces.add('g_vml_''urn:schemas-microsoft-com:vml',
                           
'#default#VML');

      }
      if (!
doc.namespaces['g_o_']) {
        
doc.namespaces.add('g_o_''urn:schemas-microsoft-com:office:office',
                           
'#default#VML');
      }

      
// Setup default CSS.  Only add one style sheet per document
      
if (!doc.styleSheets['ex_canvas_']) {
        var 
ss doc.createStyleSheet();
        
ss.owningElement.id 'ex_canvas_';
        
ss.cssText 'canvas{display:inline-block;overflow:hidden;' +
            
// default size is 300x150 in Gecko and Opera
            
'text-align:left;width:300px;height:150px}' +
            
'g_vml_\:*{behavior:url(#default#VML)}' +
            
'g_o_\:*{behavior:url(#default#VML)}';

      }

      
// find all canvas elements
      
var els doc.getElementsByTagName('canvas');
      for (var 
0els.lengthi++) {
        
this.initElement(els[i]);
      }
    },

    
/**
     * Public initializes a canvas element so that it can be used as canvas
     * element from now on. This is called automatically before the page is
     * loaded but if you are creating elements using createElement you need to
     * make sure this is called on the element.
     * @param {HTMLElement} el The canvas element to initialize.
     * @return {HTMLElement} the element that was created.
     */
    
initElement: function(el) {
      if (!
el.getContext) {

        
el.getContext getContext;

        
// Remove fallback content. There is no way to hide text nodes so we
        // just remove all childNodes. We could hide all elements and remove
        // text nodes but who really cares about the fallback content.
        
el.innerHTML '';

        
// do not use inline function because that will leak memory
        
el.attachEvent('onpropertychange'onPropertyChange);
        
el.attachEvent('onresize'onResize);

        var 
attrs el.attributes;
        if (
attrs.width && attrs.width.specified) {
          
// TODO: use runtimeStyle and coordsize
          // el.getContext().setWidth_(attrs.width.nodeValue);
          
el.style.width attrs.width.nodeValue 'px';
        } else {
          
el.width el.clientWidth;
        }
        if (
attrs.height && attrs.height.specified) {
          
// TODO: use runtimeStyle and coordsize
          // el.getContext().setHeight_(attrs.height.nodeValue);
          
el.style.height attrs.height.nodeValue 'px';
        } else {
          
el.height el.clientHeight;
        }
        
//el.getContext().setCoordsize_()
      
}
      return 
el;
    }
  };

  function 
onPropertyChange(e) {
    var 
el e.srcElement;

    switch (
e.propertyName) {
      case 
'width':
        
el.style.width el.attributes.width.nodeValue 'px';
        
el.getContext().clearRect();
        break;
      case 
'height':
        
el.style.height el.attributes.height.nodeValue 'px';
        
el.getContext().clearRect();
        break;
    }
  }

  function 
onResize(e) {
    var 
el e.srcElement;
    if (
el.firstChild) {
      
el.firstChild.style.width =  el.clientWidth 'px';
      
el.firstChild.style.height el.clientHeight 'px';
    }
  }

  
G_vmlCanvasManager_.init();

  
// precompute "00" to "FF"
  
var dec2hex = [];
  for (var 
016i++) {
    for (var 
016j++) {
      
dec2hex[16 j] = i.toString(16) + j.toString(16);
    }
  }

  function 
createMatrixIdentity() {
    return [
      [
100],
      [
010],
      [
001]
    ];
  }

  function 
matrixMultiply(m1m2) {
    var 
result createMatrixIdentity();

    for (var 
03x++) {
      for (var 
03y++) {
        var 
sum 0;

        for (var 
03z++) {
          
sum += m1[x][z] * m2[z][y];
        }

        
result[x][y] = sum;
      }
    }
    return 
result;
  }

  function 
copyState(o1o2) {
    
o2.fillStyle     o1.fillStyle;
    
o2.lineCap       o1.lineCap;
    
o2.lineJoin      o1.lineJoin;
    
o2.lineWidth     o1.lineWidth;
    
o2.miterLimit    o1.miterLimit;
    
o2.shadowBlur    o1.shadowBlur;
    
o2.shadowColor   o1.shadowColor;
    
o2.shadowOffsetX o1.shadowOffsetX;
    
o2.shadowOffsetY o1.shadowOffsetY;
    
o2.strokeStyle   o1.strokeStyle;
    
o2.globalAlpha   o1.globalAlpha;
    
o2.arcScaleX_    o1.arcScaleX_;
    
o2.arcScaleY_    o1.arcScaleY_;
    
o2.lineScale_    o1.lineScale_;
  }

  function 
processStyle(styleString) {
    var 
stralpha 1;

    
styleString String(styleString);
    if (
styleString.substring(03) == 'rgb') {
      var 
start styleString.indexOf('('3);
      var 
end styleString.indexOf(')'start 1);
      var 
guts styleString.substring(start 1end).split(',');

      
str '#';
      for (var 
03i++) {
        
str += dec2hex[Number(guts[i])];
      }

      if (
guts.length == && styleString.substr(31) == 'a') {
        
alpha guts[3];
      }
    } else {
      
str styleString;
    }

    return {
colorstralphaalpha};
  }

  function 
processLineCap(lineCap) {
    switch (
lineCap) {
      case 
'butt':
        return 
'flat';
      case 
'round':
        return 
'round';
      case 
'square':
      default:
        return 
'square';
    }
  }

  
/**
   * This class implements CanvasRenderingContext2D interface as described by
   * the WHATWG.
   * @param {HTMLElement} surfaceElement The element that the 2D context should
   * be associated with
   */
  
function CanvasRenderingContext2D_(surfaceElement) {
    
this.m_ createMatrixIdentity();

    
this.mStack_ = [];
    
this.aStack_ = [];
    
this.currentPath_ = [];

    
// Canvas context properties
    
this.strokeStyle '#000';
    
this.fillStyle '#000';

    
this.lineWidth 1;
    
this.lineJoin 'miter';
    
this.lineCap 'butt';
    
this.miterLimit 1;
    
this.globalAlpha 1;
    
this.canvas surfaceElement;

    var 
el surfaceElement.ownerDocument.createElement('div');
    
el.style.width =  surfaceElement.clientWidth 'px';
    
el.style.height surfaceElement.clientHeight 'px';
    
el.style.overflow 'hidden';
    
el.style.position 'absolute';
    
surfaceElement.appendChild(el);

    
this.element_ el;
    
this.arcScaleX_ 1;
    
this.arcScaleY_ 1;
    
this.lineScale_ 1;
  }

  var 
contextPrototype CanvasRenderingContext2D_.prototype;
  
contextPrototype.clearRect = function() {
    
this.element_.innerHTML '';
  };

  
contextPrototype.beginPath = function() {
    
// TODO: Branch current matrix so that save/restore has no effect
    //       as per safari docs.
    
this.currentPath_ = [];
  };

  
contextPrototype.moveTo = function(aXaY) {
    var 
this.getCoords_(aXaY);
    
this.currentPath_.push({type'moveTo'xp.xyp.y});
    
this.currentX_ p.x;
    
this.currentY_ p.y;
  };

  
contextPrototype.lineTo = function(aXaY) {
    var 
this.getCoords_(aXaY);
    
this.currentPath_.push({type'lineTo'xp.xyp.y});

    
this.currentX_ p.x;
    
this.currentY_ p.y;
  };

  
contextPrototype.bezierCurveTo = function(aCP1xaCP1y,
                                            
aCP2xaCP2y,
                                            
aXaY) {
    var 
this.getCoords_(aXaY);
    var 
cp1 this.getCoords_(aCP1xaCP1y);
    var 
cp2 this.getCoords_(aCP2xaCP2y);
    
bezierCurveTo(thiscp1cp2p);
  };

  
// Helper function that takes the already fixed cordinates.
  
function bezierCurveTo(selfcp1cp2p) {
    
self.currentPath_.push({
      
type'bezierCurveTo',
      
cp1xcp1.x,
      
cp1ycp1.y,
      
cp2xcp2.x,
      
cp2ycp2.y,
      
xp.x,
      
yp.y
    
});
    
self.currentX_ p.x;
    
self.currentY_ p.y;
  }

  
contextPrototype.quadraticCurveTo = function(aCPxaCPyaXaY) {
    
// the following is lifted almost directly from
    // http://developer.mozilla.org/en/docs/Canvas_tutorial:Drawing_shapes

    
var cp this.getCoords_(aCPxaCPy);
    var 
this.getCoords_(aXaY);

    var 
cp1 = {
      
xthis.currentX_ 2.0 3.0 * (cp.this.currentX_),
      
ythis.currentY_ 2.0 3.0 * (cp.this.currentY_)
    };
    var 
cp2 = {
      
xcp1.+ (p.this.currentX_) / 3.0,
      
ycp1.+ (p.this.currentY_) / 3.0
    
};

    
bezierCurveTo(thiscp1cp2p);
  };

  
contextPrototype.arc = function(aXaYaRadius,
                                  
aStartAngleaEndAngleaClockwise) {
    
aRadius *= Z;
    var 
arcType aClockwise 'at' 'wa';

    var 
xStart aX mc(aStartAngle) * aRadius Z2;
    var 
yStart aY ms(aStartAngle) * aRadius Z2;

    var 
xEnd aX mc(aEndAngle) * aRadius Z2;
    var 
yEnd aY ms(aEndAngle) * aRadius Z2;

    
// IE won't render arches drawn counter clockwise if xStart == xEnd.
    
if (xStart == xEnd && !aClockwise) {
      
xStart += 0.125// Offset xStart by 1/80 of a pixel. Use something
                       // that can be represented in binary
    
}

    var 
this.getCoords_(aXaY);
    var 
pStart this.getCoords_(xStartyStart);
    var 
pEnd this.getCoords_(xEndyEnd);

    
this.currentPath_.push({typearcType,
                           
xp.x,
                           
yp.y,
                           
radiusaRadius,
                           
xStartpStart.x,
                           
yStartpStart.y,
                           
xEndpEnd.x,
                           
yEndpEnd.y});

  };

  
contextPrototype.rect = function(aXaYaWidthaHeight) {
    
this.moveTo(aXaY);
    
this.lineTo(aX aWidthaY);
    
this.lineTo(aX aWidthaY aHeight);
    
this.lineTo(aXaY aHeight);
    
this.closePath();
  };

  
contextPrototype.strokeRect = function(aXaYaWidthaHeight) {
    var 
oldPath this.currentPath_;
    
this.beginPath();

    
this.moveTo(aXaY);
    
this.lineTo(aX aWidthaY);
    
this.lineTo(aX aWidthaY aHeight);
    
this.lineTo(aXaY aHeight);
    
this.closePath();
    
this.stroke();

    
this.currentPath_ oldPath;
  };

  
contextPrototype.fillRect = function(aXaYaWidthaHeight) {
    var 
oldPath this.currentPath_;
    
this.beginPath();

    
this.moveTo(aXaY);
    
this.lineTo(aX aWidthaY);
    
this.lineTo(aX aWidthaY aHeight);
    
this.lineTo(aXaY aHeight);
    
this.closePath();
    
this.fill();

    
this.currentPath_ oldPath;
  };

  
contextPrototype.createLinearGradient = function(aX0aY0aX1aY1) {
    var 
gradient = new CanvasGradient_('gradient');
    
gradient.x0_ aX0;
    
gradient.y0_ aY0;
    
gradient.x1_ aX1;
    
gradient.y1_ aY1;
    return 
gradient;
  };

  
contextPrototype.createRadialGradient = function(aX0aY0aR0,
                                                   
aX1aY1aR1) {
    var 
gradient = new CanvasGradient_('gradientradial');
    
gradient.x0_ aX0;
    
gradient.y0_ aY0;
    
gradient.r0_ aR0;
    
gradient.x1_ aX1;
    
gradient.y1_ aY1;
    
gradient.r1_ aR1;
    return 
gradient;
  };

  
contextPrototype.drawImage = function(imagevar_args) {
    var 
dxdydwdhsxsyswsh;

    
// to find the original width we overide the width and height
    
var oldRuntimeWidth image.runtimeStyle.width;
    var 
oldRuntimeHeight image.runtimeStyle.height;
    
image.runtimeStyle.width 'auto';
    
image.runtimeStyle.height 'auto';

    
// get the original size
    
var image.width;
    var 
image.height;

    
// and remove overides
    
image.runtimeStyle.width oldRuntimeWidth;
    
image.runtimeStyle.height oldRuntimeHeight;

    if (
arguments.length == 3) {
      
dx arguments[1];
      
dy arguments[2];
      
sx sy 0;
      
sw dw w;
      
sh dh h;
    } else if (
arguments.length == 5) {
      
dx arguments[1];
      
dy arguments[2];
      
dw arguments[3];
      
dh arguments[4];
      
sx sy 0;
      
sw w;
      
sh h;
    } else if (
arguments.length == 9) {
      
sx arguments[1];
      
sy arguments[2];
      
sw arguments[3];
      
sh arguments[4];
      
dx arguments[5];
      
dy arguments[6];
      
dw arguments[7];
      
dh arguments[8];
    } else {
      throw 
Error('Invalid number of arguments');
    }

    var 
this.getCoords_(dxdy);

    var 
w2 sw 2;
    var 
h2 sh 2;

    var 
vmlStr = [];

    var 
10;
    var 
10;

    
// For some reason that I've now forgotten, using divs didn't work
    
vmlStr.push(' <g_vml_:group',
                
' coordsize="'W','H'"',
                
' coordorigin="0,0"' ,
                
' style="width:'W'px;height:'H'px;position:absolute;');

    
// If filters are necessary (rotation exists), create them
    // filters are bog-slow, so only create them if abbsolutely necessary
    // The following check doesn't account for skews (which don't exist
    // in the canvas spec (yet) anyway.

    
if (this.m_[0][0] != || this.m_[0][1]) {
      var 
filter = [];

      
// Note the 12/21 reversal
      
filter.push('M11='this.m_[0][0], ',',
                  
'M12='this.m_[1][0], ',',
                  
'M21='this.m_[0][1], ',',
                  
'M22='this.m_[1][1], ',',
                  
'Dx='mr(d.Z), ',',
                  
'Dy='mr(d.Z), '');

      
// Bounding box calculation (need to minimize displayed area so that
      // filters don't waste time on unused pixels.
      
var max d;
      var 
c2 this.getCoords_(dx dwdy);
      var 
c3 this.getCoords_(dxdy dh);
      var 
c4 this.getCoords_(dx dwdy dh);

      
max.m.max(max.xc2.xc3.xc4.x);
      
max.m.max(max.yc2.yc3.yc4.y);

      
vmlStr.push('padding:0 'mr(max.Z), 'px 'mr(max.Z),
                  
'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(',
                  
filter.join(''), ", sizingmethod='clip');")
    } else {
      
vmlStr.push('top:'mr(d.Z), 'px;left:'mr(d.Z), 'px;');
    }

    
vmlStr.push(' ">' ,
                
'<g_vml_:image src="'image.src'"',
                
' style="width:'dw'px;',
                
' height:'dh'px;"',
                
' cropleft="'sx w'"',
                
' croptop="'sy h'"',
                
' cropright="', (sx sw) / w'"',
                
' cropbottom="', (sy sh) / h'"',
                
' />',
                
'</g_vml_:group>');

    
this.element_.insertAdjacentHTML('BeforeEnd',
                                    
vmlStr.join(''));
  };

  
contextPrototype.stroke = function(aFill) {
    var 
lineStr = [];
    var 
lineOpen false;
    var 
processStyle(aFill this.fillStyle this.strokeStyle);
    var 
color a.color;
    var 
opacity a.alpha this.globalAlpha;

    var 
10;
    var 
10;

    
lineStr.push('<g_vml_:shape',
                 
' filled="', !!aFill'"',
                 
' style="position:absolute;width:'W'px;height:'H'px;"',
                 
' coordorigin="0 0" coordsize="'W' 'H'"',
                 
' stroked="', !aFill'"',
                 
' path="');

    var 
newSeq false;
    var 
min = {xnullynull};
    var 
max = {xnullynull};

    for (var 
0this.currentPath_.lengthi++) {
      var 
this.currentPath_[i];
      var 
c;

      switch (
p.type) {
        case 
'moveTo':
          
p;
          
lineStr.push(' m 'mr(p.x), ','mr(p.y));
          break;
        case 
'lineTo':
          
lineStr.push(' l 'mr(p.x), ','mr(p.y));
          break;
        case 
'close':
          
lineStr.push(' x ');
          
null;
          break;
        case 
'bezierCurveTo':
          
lineStr.push(' c ',
                       
mr(p.cp1x), ','mr(p.cp1y), ',',
                       
mr(p.cp2x), ','mr(p.cp2y), ',',
                       
mr(p.x), ','mr(p.y));
          break;
        case 
'at':
        case 
'wa':
          
lineStr.push(' 'p.type' ',
                       
mr(p.this.arcScaleX_ p.radius), ',',
                       
mr(p.this.arcScaleY_ p.radius), ' ',
                       
mr(p.this.arcScaleX_ p.radius), ',',
                       
mr(p.this.arcScaleY_ p.radius), ' ',
                       
mr(p.xStart), ','mr(p.yStart), ' ',
                       
mr(p.xEnd), ','mr(p.yEnd));
          break;
      }


      
// TODO: Following is broken for curves due to
      //       move to proper paths.

      // Figure out dimensions so we can do gradient fills
      // properly
      
if (p) {
        if (
min.== null || p.min.x) {
          
min.p.x;
        }
        if (
max.== null || p.max.x) {
          
max.p.x;
        }
        if (
min.== null || p.min.y) {
          
min.p.y;
        }
        if (
max.== null || p.max.y) {
          
max.p.y;
        }
      }
    }
    
lineStr.push(' ">');

    if (!
aFill) {
      var 
lineWidth this.lineScale_ this.lineWidth;

      
// VML cannot correctly render a line if the width is less than 1px.
      // In that case, we dilute the color to make the line look thinner.
      
if (lineWidth 1) {
        
opacity *= lineWidth;
      }

      
lineStr.push(
        
'<g_vml_:stroke',
        
' opacity="'opacity'"',
        
' joinstyle="'this.lineJoin'"',
        
' miterlimit="'this.miterLimit'"',
        
' endcap="'processLineCap(this.lineCap), '"',
        
' weight="'lineWidth'px"',
        
' color="'color'" />'
      
);
    } else if (
typeof this.fillStyle == 'object') {
      var 
fillStyle this.fillStyle;
      var 
angle 0;
      var 
focus = {x0y0};

      
// additional offset
      
var shift 0;
      
// scale factor for offset
      
var expansion 1;

      if (
fillStyle.type_ == 'gradient') {
        var 
x0 fillStyle.x0_ this.arcScaleX_;
        var 
y0 fillStyle.y0_ this.arcScaleY_;
        var 
x1 fillStyle.x1_ this.arcScaleX_;
        var 
y1 fillStyle.y1_ this.arcScaleY_;
        var 
p0 this.getCoords_(x0y0);
        var 
p1 this.getCoords_(x1y1);
        var 
dx p1.p0.x;
        var 
dy p1.p0.y;
        
angle Math.atan2(dxdy) * 180 Math.PI;

        
// The angle should be a non-negative number.
        
if (angle 0) {
          
angle += 360;
        }

        
// Very small angles produce an unexpected result because they are
        // converted to a scientific notation string.
        
if (angle 1e-6) {
          
angle 0;
        }
      } else {
        var 
p0 this.getCoords_(fillStyle.x0_fillStyle.y0_);
        var 
width  max.min.x;
        var 
height max.min.y;
        
focus = {
          
x: (p0.min.x) / width,
          
y: (p0.min.y) / height
        
};

        
width  /= this.arcScaleX_ Z;
        
height /= this.arcScaleY_ Z;
        var 
dimension m.max(widthheight);
        
shift fillStyle.r0_ dimension;
        
expansion fillStyle.r1_ dimension shift;
      }

      
// We need to sort the color stops in ascending order by offset,
      // otherwise IE won't interpret it correctly.
      
var stops fillStyle.colors_;
      
stops.sort(function(cs1cs2) {
        return 
cs1.offset cs2.offset;
      });

      var 
length stops.length;
      var 
color1 stops[0].color;
      var 
color2 stops[length 1].color;
      var 
opacity1 stops[0].alpha this.globalAlpha;
      var 
opacity2 stops[length 1].alpha this.globalAlpha;

      var 
colors = [];
      for (var 
0lengthi++) {
        var 
stop stops[i];
        
colors.push(stop.offset expansion shift ' ' stop.color);
      }

      
// When colors attribute is used, the meanings of opacity and o:opacity2
      // are reversed.
      
lineStr.push('<g_vml_:fill type="'fillStyle.type_'"',
                   
' method="none" focus="100%"',
                   
' color="'color1'"',
                   
' color2="'color2'"',
                   
' colors="'colors.join(','), '"',
                   
' opacity="'opacity2'"',
                   
' g_o_:opacity2="'opacity1'"',
                   
' angle="'angle'"',
                   
' focusposition="'focus.x','focus.y'" />');
    } else {
      
lineStr.push('<g_vml_:fill color="'color'" opacity="'opacity,
                   
'" />');
    }

    
lineStr.push('</g_vml_:shape>');

    
this.element_.insertAdjacentHTML('beforeEnd'lineStr.join(''));
  };

  
contextPrototype.fill = function() {
    
this.stroke(true);
  }

  
contextPrototype.closePath = function() {
    
this.currentPath_.push({type'close'});
  };

  
/**
   * @private
   */
  
contextPrototype.getCoords_ = function(aXaY) {
    var 
this.m_;
    return {
      
x* (aX m[0][0] + aY m[1][0] + m[2][0]) - Z2,
      
y* (aX m[0][1] + aY m[1][1] + m[2][1]) - Z2
    
}
  };

  
contextPrototype.save = function() {
    var 
= {};
    
copyState(thiso);
    
this.aStack_.push(o);
    
this.mStack_.push(this.m_);
    
this.m_ matrixMultiply(createMatrixIdentity(), this.m_);
  };

  
contextPrototype.restore = function() {
    
copyState(this.aStack_.pop(), this);
    
this.m_ this.mStack_.pop();
  };

  function 
matrixIsFinite(m) {
    for (var 
03j++) {
      for (var 
02k++) {
        if (!
isFinite(m[j][k]) || isNaN(m[j][k])) {
          return 
false;
        }
      }
    }
    return 
true;
  }

  function 
setM(ctxmupdateLineScale) {
    if (!
matrixIsFinite(m)) {
      return;
    }
    
ctx.m_ m;

    if (
updateLineScale) {
      
// Get the line scale.
      // Determinant of this.m_ means how much the area is enlarged by the
      // transformation. So its square root can be used as a scale factor
      // for width.
      
var det m[0][0] * m[1][1] - m[0][1] * m[1][0];
      
ctx.lineScale_ sqrt(abs(det));
    }
  }

  
contextPrototype.translate = function(aXaY) {
    var 
m1 = [
      [
1,  0,  0],
      [
0,  1,  0],
      [
aXaY1]
    ];

    
setM(thismatrixMultiply(m1this.m_), false);
  };

  
contextPrototype.rotate = function(aRot) {
    var 
mc(aRot);
    var 
ms(aRot);

    var 
m1 = [
      [
c,  s0],
      [-
sc0],
      [
0,  01]
    ];

    
setM(thismatrixMultiply(m1this.m_), false);
  };

  
contextPrototype.scale = function(aXaY) {
    
this.arcScaleX_ *= aX;
    
this.arcScaleY_ *= aY;
    var 
m1 = [
      [
aX0,  0],
      [
0,  aY0],
      [
0,  0,  1]
    ];

    
setM(thismatrixMultiply(m1this.m_), true);
  };

  
contextPrototype.transform = function(m11m12m21m22dxdy) {
    var 
m1 = [
      [
m11m120],
      [
m21m220],
      [
dx,  dy,  1]
    ];

    
setM(thismatrixMultiply(m1this.m_), true);
  };

  
contextPrototype.setTransform = function(m11m12m21m22dxdy) {
    var 
= [
      [
m11m120],
      [
m21m220],
      [
dx,  dy,  1]
    ];

    
setM(thismtrue);
  };

  
/******** STUBS ********/
  
contextPrototype.clip = function() {
    
// TODO: Implement
  
};

  
contextPrototype.arcTo = function() {
    
// TODO: Implement
  
};

  
contextPrototype.createPattern = function() {
    return new 
CanvasPattern_;
  };

  
// Gradient / Pattern Stubs
  
function CanvasGradient_(aType) {
    
this.type_ aType;
    
this.x0_ 0;
    
this.y0_ 0;
    
this.r0_ 0;
    
this.x1_ 0;
    
this.y1_ 0;
    
this.r1_ 0;
    
this.colors_ = [];
  }

  
CanvasGradient_.prototype.addColorStop = function(aOffsetaColor) {
    
aColor processStyle(aColor);
    
this.colors_.push({offsetaOffset,
                       
coloraColor.color,
                       
alphaaColor.alpha});
  };

  function 
CanvasPattern_() {}

  
// set up externs
  
G_vmlCanvasManager G_vmlCanvasManager_;
  
CanvasRenderingContext2D CanvasRenderingContext2D_;
  
CanvasGradient CanvasGradient_;
  
CanvasPattern CanvasPattern_;

})();

// if
?>
Онлайн: 2
Реклама