Commit 15f3cc95 authored by olau@iola.dk's avatar olau@iola.dk

Updated excanvas from SVN, with the patch in issue 50...

Updated excanvas from SVN, with the patch in issue 50 (http://code.google.com/p/explorercanvas/issues/detail?id=50) applied


git-svn-id: https://flot.googlecode.com/svn/trunk@217 1e0a6537-2640-0410-bfb7-f154510ff394
parent 563349c9
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
// Known Issues: // Known Issues:
// //
// * Patterns are not implemented. // * Patterns only support repeat.
// * Radial gradient are not implemented. The VML version of these look very // * Radial gradient are not implemented. The VML version of these look very
// different from the canvas one. // different from the canvas one.
// * Clipping paths are not implemented. // * Clipping paths are not implemented.
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
// or use Box Sizing Behavior from WebFX // or use Box Sizing Behavior from WebFX
// (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html) // (http://webfx.eae.net/dhtml/boxsizing/boxsizing.html)
// * Non uniform scaling does not correctly scale strokes. // * Non uniform scaling does not correctly scale strokes.
// * Filling very large shapes (above 5000 points) is buggy.
// * Optimize. There is always room for speed improvements. // * Optimize. There is always room for speed improvements.
// Only add this code if we do not already have a canvas implementation // Only add this code if we do not already have a canvas implementation
...@@ -83,6 +84,35 @@ if (!document.createElement('canvas').getContext) { ...@@ -83,6 +84,35 @@ if (!document.createElement('canvas').getContext) {
}; };
} }
function encodeHtmlAttribute(s) {
return String(s).replace(/&/g, '&').replace(/"/g, '"');
}
function addNamespacesAndStylesheet(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}';
}
}
// Add namespaces and stylesheet at startup.
addNamespacesAndStylesheet(document);
var G_vmlCanvasManager_ = { var G_vmlCanvasManager_ = {
init: function(opt_doc) { init: function(opt_doc) {
if (/MSIE/.test(navigator.userAgent) && !window.opera) { if (/MSIE/.test(navigator.userAgent) && !window.opera) {
...@@ -95,29 +125,6 @@ if (!document.createElement('canvas').getContext) { ...@@ -95,29 +125,6 @@ if (!document.createElement('canvas').getContext) {
}, },
init_: function(doc) { 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 // find all canvas elements
var els = doc.getElementsByTagName('canvas'); var els = doc.getElementsByTagName('canvas');
for (var i = 0; i < els.length; i++) { for (var i = 0; i < els.length; i++) {
...@@ -135,9 +142,11 @@ if (!document.createElement('canvas').getContext) { ...@@ -135,9 +142,11 @@ if (!document.createElement('canvas').getContext) {
*/ */
initElement: function(el) { initElement: function(el) {
if (!el.getContext) { if (!el.getContext) {
el.getContext = getContext; el.getContext = getContext;
// Add namespaces and stylesheet to document of the element.
addNamespacesAndStylesheet(el.ownerDocument);
// Remove fallback content. There is no way to hide text nodes so we // Remove fallback content. There is no way to hide text nodes so we
// just remove all childNodes. We could hide all elements and remove // just remove all childNodes. We could hide all elements and remove
// text nodes but who really cares about the fallback content. // text nodes but who really cares about the fallback content.
...@@ -173,12 +182,15 @@ if (!document.createElement('canvas').getContext) { ...@@ -173,12 +182,15 @@ if (!document.createElement('canvas').getContext) {
switch (e.propertyName) { switch (e.propertyName) {
case 'width': case 'width':
el.style.width = el.attributes.width.nodeValue + 'px';
el.getContext().clearRect(); el.getContext().clearRect();
el.style.width = el.attributes.width.nodeValue + 'px';
// In IE8 this does not trigger onresize.
el.firstChild.style.width = el.clientWidth + 'px';
break; break;
case 'height': case 'height':
el.style.height = el.attributes.height.nodeValue + 'px';
el.getContext().clearRect(); el.getContext().clearRect();
el.style.height = el.attributes.height.nodeValue + 'px';
el.firstChild.style.height = el.clientHeight + 'px';
break; break;
} }
} }
...@@ -194,10 +206,10 @@ if (!document.createElement('canvas').getContext) { ...@@ -194,10 +206,10 @@ if (!document.createElement('canvas').getContext) {
G_vmlCanvasManager_.init(); G_vmlCanvasManager_.init();
// precompute "00" to "FF" // precompute "00" to "FF"
var dec2hex = []; var decToHex = [];
for (var i = 0; i < 16; i++) { for (var i = 0; i < 16; i++) {
for (var j = 0; j < 16; j++) { for (var j = 0; j < 16; j++) {
dec2hex[i * 16 + j] = i.toString(16) + j.toString(16); decToHex[i * 16 + j] = i.toString(16) + j.toString(16);
} }
} }
...@@ -238,33 +250,304 @@ if (!document.createElement('canvas').getContext) { ...@@ -238,33 +250,304 @@ if (!document.createElement('canvas').getContext) {
o2.shadowOffsetY = o1.shadowOffsetY; o2.shadowOffsetY = o1.shadowOffsetY;
o2.strokeStyle = o1.strokeStyle; o2.strokeStyle = o1.strokeStyle;
o2.globalAlpha = o1.globalAlpha; o2.globalAlpha = o1.globalAlpha;
o2.font = o1.font;
o2.textAlign = o1.textAlign;
o2.textBaseline = o1.textBaseline;
o2.arcScaleX_ = o1.arcScaleX_; o2.arcScaleX_ = o1.arcScaleX_;
o2.arcScaleY_ = o1.arcScaleY_; o2.arcScaleY_ = o1.arcScaleY_;
o2.lineScale_ = o1.lineScale_; o2.lineScale_ = o1.lineScale_;
} }
var colorData = {
aliceblue: '#F0F8FF',
antiquewhite: '#FAEBD7',
aquamarine: '#7FFFD4',
azure: '#F0FFFF',
beige: '#F5F5DC',
bisque: '#FFE4C4',
black: '#000000',
blanchedalmond: '#FFEBCD',
blueviolet: '#8A2BE2',
brown: '#A52A2A',
burlywood: '#DEB887',
cadetblue: '#5F9EA0',
chartreuse: '#7FFF00',
chocolate: '#D2691E',
coral: '#FF7F50',
cornflowerblue: '#6495ED',
cornsilk: '#FFF8DC',
crimson: '#DC143C',
cyan: '#00FFFF',
darkblue: '#00008B',
darkcyan: '#008B8B',
darkgoldenrod: '#B8860B',
darkgray: '#A9A9A9',
darkgreen: '#006400',
darkgrey: '#A9A9A9',
darkkhaki: '#BDB76B',
darkmagenta: '#8B008B',
darkolivegreen: '#556B2F',
darkorange: '#FF8C00',
darkorchid: '#9932CC',
darkred: '#8B0000',
darksalmon: '#E9967A',
darkseagreen: '#8FBC8F',
darkslateblue: '#483D8B',
darkslategray: '#2F4F4F',
darkslategrey: '#2F4F4F',
darkturquoise: '#00CED1',
darkviolet: '#9400D3',
deeppink: '#FF1493',
deepskyblue: '#00BFFF',
dimgray: '#696969',
dimgrey: '#696969',
dodgerblue: '#1E90FF',
firebrick: '#B22222',
floralwhite: '#FFFAF0',
forestgreen: '#228B22',
gainsboro: '#DCDCDC',
ghostwhite: '#F8F8FF',
gold: '#FFD700',
goldenrod: '#DAA520',
grey: '#808080',
greenyellow: '#ADFF2F',
honeydew: '#F0FFF0',
hotpink: '#FF69B4',
indianred: '#CD5C5C',
indigo: '#4B0082',
ivory: '#FFFFF0',
khaki: '#F0E68C',
lavender: '#E6E6FA',
lavenderblush: '#FFF0F5',
lawngreen: '#7CFC00',
lemonchiffon: '#FFFACD',
lightblue: '#ADD8E6',
lightcoral: '#F08080',
lightcyan: '#E0FFFF',
lightgoldenrodyellow: '#FAFAD2',
lightgreen: '#90EE90',
lightgrey: '#D3D3D3',
lightpink: '#FFB6C1',
lightsalmon: '#FFA07A',
lightseagreen: '#20B2AA',
lightskyblue: '#87CEFA',
lightslategray: '#778899',
lightslategrey: '#778899',
lightsteelblue: '#B0C4DE',
lightyellow: '#FFFFE0',
limegreen: '#32CD32',
linen: '#FAF0E6',
magenta: '#FF00FF',
mediumaquamarine: '#66CDAA',
mediumblue: '#0000CD',
mediumorchid: '#BA55D3',
mediumpurple: '#9370DB',
mediumseagreen: '#3CB371',
mediumslateblue: '#7B68EE',
mediumspringgreen: '#00FA9A',
mediumturquoise: '#48D1CC',
mediumvioletred: '#C71585',
midnightblue: '#191970',
mintcream: '#F5FFFA',
mistyrose: '#FFE4E1',
moccasin: '#FFE4B5',
navajowhite: '#FFDEAD',
oldlace: '#FDF5E6',
olivedrab: '#6B8E23',
orange: '#FFA500',
orangered: '#FF4500',
orchid: '#DA70D6',
palegoldenrod: '#EEE8AA',
palegreen: '#98FB98',
paleturquoise: '#AFEEEE',
palevioletred: '#DB7093',
papayawhip: '#FFEFD5',
peachpuff: '#FFDAB9',
peru: '#CD853F',
pink: '#FFC0CB',
plum: '#DDA0DD',
powderblue: '#B0E0E6',
rosybrown: '#BC8F8F',
royalblue: '#4169E1',
saddlebrown: '#8B4513',
salmon: '#FA8072',
sandybrown: '#F4A460',
seagreen: '#2E8B57',
seashell: '#FFF5EE',
sienna: '#A0522D',
skyblue: '#87CEEB',
slateblue: '#6A5ACD',
slategray: '#708090',
slategrey: '#708090',
snow: '#FFFAFA',
springgreen: '#00FF7F',
steelblue: '#4682B4',
tan: '#D2B48C',
thistle: '#D8BFD8',
tomato: '#FF6347',
turquoise: '#40E0D0',
violet: '#EE82EE',
wheat: '#F5DEB3',
whitesmoke: '#F5F5F5',
yellowgreen: '#9ACD32'
};
function getRgbHslContent(styleString) {
var start = styleString.indexOf('(', 3);
var end = styleString.indexOf(')', start + 1);
var parts = styleString.substring(start + 1, end).split(',');
// add alpha if needed
if (parts.length == 4 && styleString.substr(3, 1) == 'a') {
alpha = Number(parts[3]);
} else {
parts[3] = 1;
}
return parts;
}
function percent(s) {
return parseFloat(s) / 100;
}
function clamp(v, min, max) {
return Math.min(max, Math.max(min, v));
}
function hslToRgb(parts){
var r, g, b;
h = parseFloat(parts[0]) / 360 % 360;
if (h < 0)
h++;
s = clamp(percent(parts[1]), 0, 1);
l = clamp(percent(parts[2]), 0, 1);
if (s == 0) {
r = g = b = l; // achromatic
} else {
var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
var p = 2 * l - q;
r = hueToRgb(p, q, h + 1 / 3);
g = hueToRgb(p, q, h);
b = hueToRgb(p, q, h - 1 / 3);
}
return '#' + decToHex[Math.floor(r * 255)] +
decToHex[Math.floor(g * 255)] +
decToHex[Math.floor(b * 255)];
}
function hueToRgb(m1, m2, h) {
if (h < 0)
h++;
if (h > 1)
h--;
if (6 * h < 1)
return m1 + (m2 - m1) * 6 * h;
else if (2 * h < 1)
return m2;
else if (3 * h < 2)
return m1 + (m2 - m1) * (2 / 3 - h) * 6;
else
return m1;
}
function processStyle(styleString) { function processStyle(styleString) {
var str, alpha = 1; var str, alpha = 1;
styleString = String(styleString); styleString = String(styleString);
if (styleString.substring(0, 3) == 'rgb') { if (styleString.charAt(0) == '#') {
var start = styleString.indexOf('(', 3); str = styleString;
var end = styleString.indexOf(')', start + 1); } else if (/^rgb/.test(styleString)) {
var guts = styleString.substring(start + 1, end).split(','); var parts = getRgbHslContent(styleString);
var str = '#', n;
str = '#';
for (var i = 0; i < 3; i++) { for (var i = 0; i < 3; i++) {
str += dec2hex[Number(guts[i])]; if (parts[i].indexOf('%') != -1) {
n = Math.floor(percent(parts[i]) * 255);
} else {
n = Number(parts[i]);
}
str += decToHex[clamp(n, 0, 255)];
} }
alpha = parts[3];
} else if (/^hsl/.test(styleString)) {
var parts = getRgbHslContent(styleString);
str = hslToRgb(parts);
alpha = parts[3];
} else {
str = colorData[styleString] || styleString;
}
return {color: str, alpha: alpha};
}
if (guts.length == 4 && styleString.substr(3, 1) == 'a') { var DEFAULT_STYLE = {
alpha = guts[3]; style: 'normal',
} variant: 'normal',
weight: 'normal',
size: 10,
family: 'sans-serif'
};
// Internal text style cache
var fontStyleCache = {};
function processFontStyle(styleString) {
if (fontStyleCache[styleString]) {
return fontStyleCache[styleString];
}
var el = document.createElement('div');
var style = el.style;
try {
style.font = styleString;
} catch (ex) {
// Ignore failures to set to invalid font.
}
return fontStyleCache[styleString] = {
style: style.fontStyle || DEFAULT_STYLE.style,
variant: style.fontVariant || DEFAULT_STYLE.variant,
weight: style.fontWeight || DEFAULT_STYLE.weight,
size: style.fontSize || DEFAULT_STYLE.size,
family: style.fontFamily || DEFAULT_STYLE.family
};
}
function getComputedStyle(style, element) {
var computedStyle = {};
for (var p in style) {
computedStyle[p] = style[p];
}
// Compute the size
var canvasFontSize = parseFloat(element.currentStyle.fontSize),
fontSize = parseFloat(style.size);
if (typeof style.size == 'number') {
computedStyle.size = style.size;
} else if (style.size.indexOf('px') != -1) {
computedStyle.size = fontSize;
} else if (style.size.indexOf('em') != -1) {
computedStyle.size = canvasFontSize * fontSize;
} else if(style.size.indexOf('%') != -1) {
computedStyle.size = (canvasFontSize / 100) * fontSize;
} else if (style.size.indexOf('pt') != -1) {
computedStyle.size = fontSize / .75;
} else { } else {
str = styleString; computedStyle.size = canvasFontSize;
} }
return {color: str, alpha: alpha}; // Different scaling between normal text and VML text. This was found using
// trial and error to get the same size as non VML text.
computedStyle.size *= 0.981;
return computedStyle;
}
function buildStyle(style) {
return style.style + ' ' + style.variant + ' ' + style.weight + ' ' +
style.size + 'px ' + style.family;
} }
function processLineCap(lineCap) { function processLineCap(lineCap) {
...@@ -301,6 +584,9 @@ if (!document.createElement('canvas').getContext) { ...@@ -301,6 +584,9 @@ if (!document.createElement('canvas').getContext) {
this.lineCap = 'butt'; this.lineCap = 'butt';
this.miterLimit = Z * 1; this.miterLimit = Z * 1;
this.globalAlpha = 1; this.globalAlpha = 1;
this.font = '10px sans-serif';
this.textAlign = 'left';
this.textBaseline = 'alphabetic';
this.canvas = surfaceElement; this.canvas = surfaceElement;
var el = surfaceElement.ownerDocument.createElement('div'); var el = surfaceElement.ownerDocument.createElement('div');
...@@ -318,6 +604,10 @@ if (!document.createElement('canvas').getContext) { ...@@ -318,6 +604,10 @@ if (!document.createElement('canvas').getContext) {
var contextPrototype = CanvasRenderingContext2D_.prototype; var contextPrototype = CanvasRenderingContext2D_.prototype;
contextPrototype.clearRect = function() { contextPrototype.clearRect = function() {
if (this.textMeasureEl_) {
this.textMeasureEl_.removeNode(true);
this.textMeasureEl_ = null;
}
this.element_.innerHTML = ''; this.element_.innerHTML = '';
}; };
...@@ -539,7 +829,8 @@ if (!document.createElement('canvas').getContext) { ...@@ -539,7 +829,8 @@ if (!document.createElement('canvas').getContext) {
// The following check doesn't account for skews (which don't exist // The following check doesn't account for skews (which don't exist
// in the canvas spec (yet) anyway. // in the canvas spec (yet) anyway.
if (this.m_[0][0] != 1 || this.m_[0][1]) { if (this.m_[0][0] != 1 || this.m_[0][1] ||
this.m_[1][1] != 1 || this.m_[1][0]) {
var filter = []; var filter = [];
// Note the 12/21 reversal // Note the 12/21 reversal
...@@ -562,7 +853,8 @@ if (!document.createElement('canvas').getContext) { ...@@ -562,7 +853,8 @@ if (!document.createElement('canvas').getContext) {
vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z), vmlStr.push('padding:0 ', mr(max.x / Z), 'px ', mr(max.y / Z),
'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(', 'px 0;filter:progid:DXImageTransform.Microsoft.Matrix(',
filter.join(''), ", sizingmethod='clip');") filter.join(''), ", sizingmethod='clip');");
} else { } else {
vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;'); vmlStr.push('top:', mr(d.y / Z), 'px;left:', mr(d.x / Z), 'px;');
} }
...@@ -570,7 +862,7 @@ if (!document.createElement('canvas').getContext) { ...@@ -570,7 +862,7 @@ if (!document.createElement('canvas').getContext) {
vmlStr.push(' ">' , vmlStr.push(' ">' ,
'<g_vml_:image src="', image.src, '"', '<g_vml_:image src="', image.src, '"',
' style="width:', Z * dw, 'px;', ' style="width:', Z * dw, 'px;',
' height:', Z * dh, 'px;"', ' height:', Z * dh, 'px"',
' cropleft="', sx / w, '"', ' cropleft="', sx / w, '"',
' croptop="', sy / h, '"', ' croptop="', sy / h, '"',
' cropright="', (w - sx - sw) / w, '"', ' cropright="', (w - sx - sw) / w, '"',
...@@ -578,108 +870,138 @@ if (!document.createElement('canvas').getContext) { ...@@ -578,108 +870,138 @@ if (!document.createElement('canvas').getContext) {
' />', ' />',
'</g_vml_:group>'); '</g_vml_:group>');
this.element_.insertAdjacentHTML('BeforeEnd', this.element_.insertAdjacentHTML('BeforeEnd', vmlStr.join(''));
vmlStr.join(''));
}; };
contextPrototype.stroke = function(aFill) { contextPrototype.stroke = function(aFill) {
var lineStr = [];
var lineOpen = false;
var a = processStyle(aFill ? this.fillStyle : this.strokeStyle);
var color = a.color;
var opacity = a.alpha * this.globalAlpha;
var W = 10; var W = 10;
var H = 10; var H = 10;
// Divide the shape into chunks if it's too long because IE has a limit
// somewhere for how long a VML shape can be. This simple division does
// not work with fills, only strokes, unfortunately.
var chunkSize = 5000;
lineStr.push('<g_vml_:shape',
' filled="', !!aFill, '"',
' style="position:absolute;width:', W, 'px;height:', H, 'px;"',
' coordorigin="0 0" coordsize="', Z * W, ' ', Z * H, '"',
' stroked="', !aFill, '"',
' path="');
var newSeq = false;
var min = {x: null, y: null}; var min = {x: null, y: null};
var max = {x: null, y: null}; var max = {x: null, y: null};
for (var i = 0; i < this.currentPath_.length; i++) { for (var j = 0; j < this.currentPath_.length; j += chunkSize) {
var p = this.currentPath_[i]; var lineStr = [];
var c; var lineOpen = false;
switch (p.type) {
case 'moveTo':
c = 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 ');
p = 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.x - this.arcScaleX_ * p.radius), ',',
mr(p.y - this.arcScaleY_ * p.radius), ' ',
mr(p.x + this.arcScaleX_ * p.radius), ',',
mr(p.y + this.arcScaleY_ * p.radius), ' ',
mr(p.xStart), ',', mr(p.yStart), ' ',
mr(p.xEnd), ',', mr(p.yEnd));
break;
}
lineStr.push('<g_vml_:shape',
' filled="', !!aFill, '"',
' style="position:absolute;width:', W, 'px;height:', H, 'px;"',
' coordorigin="0,0"',
' coordsize="', Z * W, ',', Z * H, '"',
' stroked="', !aFill, '"',
' path="');
// TODO: Following is broken for curves due to var newSeq = false;
// move to proper paths.
// Figure out dimensions so we can do gradient fills for (var i = j; i < Math.min(j + chunkSize, this.currentPath_.length); i++) {
// properly if (i % chunkSize == 0 && i > 0) { // move into position for next chunk
if (p) { lineStr.push(' m ', mr(this.currentPath_[i-1].x), ',', mr(this.currentPath_[i-1].y));
if (min.x == null || p.x < min.x) {
min.x = p.x;
} }
if (max.x == null || p.x > max.x) {
max.x = p.x; var p = this.currentPath_[i];
} var c;
if (min.y == null || p.y < min.y) {
min.y = p.y; switch (p.type) {
case 'moveTo':
c = 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 ');
p = 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.x - this.arcScaleX_ * p.radius), ',',
mr(p.y - this.arcScaleY_ * p.radius), ' ',
mr(p.x + this.arcScaleX_ * p.radius), ',',
mr(p.y + this.arcScaleY_ * p.radius), ' ',
mr(p.xStart), ',', mr(p.yStart), ' ',
mr(p.xEnd), ',', mr(p.yEnd));
break;
} }
if (max.y == null || p.y > max.y) {
max.y = p.y;
// 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.x == null || p.x < min.x) {
min.x = p.x;
}
if (max.x == null || p.x > max.x) {
max.x = p.x;
}
if (min.y == null || p.y < min.y) {
min.y = p.y;
}
if (max.y == null || p.y > max.y) {
max.y = p.y;
}
} }
} }
lineStr.push(' ">');
if (!aFill) {
appendStroke(this, lineStr);
} else {
appendFill(this, lineStr, min, max);
}
lineStr.push('</g_vml_:shape>');
this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
} }
lineStr.push(' ">'); };
if (!aFill) { function appendStroke(ctx, lineStr) {
var lineWidth = this.lineScale_ * this.lineWidth; var a = processStyle(ctx.strokeStyle);
var color = a.color;
var opacity = a.alpha * ctx.globalAlpha;
var lineWidth = ctx.lineScale_ * ctx.lineWidth;
// VML cannot correctly render a line if the width is less than 1px. // 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. // In that case, we dilute the color to make the line look thinner.
if (lineWidth < 1) { if (lineWidth < 1) {
opacity *= lineWidth; opacity *= lineWidth;
} }
lineStr.push(
'<g_vml_:stroke',
' opacity="', opacity, '"',
' joinstyle="', ctx.lineJoin, '"',
' miterlimit="', ctx.miterLimit, '"',
' endcap="', processLineCap(ctx.lineCap), '"',
' weight="', lineWidth, 'px"',
' color="', color, '" />'
);
}
lineStr.push( function appendFill(ctx, lineStr, min, max) {
'<g_vml_:stroke', var fillStyle = ctx.fillStyle;
' opacity="', opacity, '"', var arcScaleX = ctx.arcScaleX_;
' joinstyle="', this.lineJoin, '"', var arcScaleY = ctx.arcScaleY_;
' miterlimit="', this.miterLimit, '"', var width = max.x - min.x;
' endcap="', processLineCap(this.lineCap), '"', var height = max.y - min.y;
' weight="', lineWidth, 'px"', if (fillStyle instanceof CanvasGradient_) {
' color="', color, '" />' // TODO: Gradients transformed with the transformation matrix.
);
} else if (typeof this.fillStyle == 'object') {
var fillStyle = this.fillStyle;
var angle = 0; var angle = 0;
var focus = {x: 0, y: 0}; var focus = {x: 0, y: 0};
...@@ -689,12 +1011,12 @@ if (!document.createElement('canvas').getContext) { ...@@ -689,12 +1011,12 @@ if (!document.createElement('canvas').getContext) {
var expansion = 1; var expansion = 1;
if (fillStyle.type_ == 'gradient') { if (fillStyle.type_ == 'gradient') {
var x0 = fillStyle.x0_ / this.arcScaleX_; var x0 = fillStyle.x0_ / arcScaleX;
var y0 = fillStyle.y0_ / this.arcScaleY_; var y0 = fillStyle.y0_ / arcScaleY;
var x1 = fillStyle.x1_ / this.arcScaleX_; var x1 = fillStyle.x1_ / arcScaleX;
var y1 = fillStyle.y1_ / this.arcScaleY_; var y1 = fillStyle.y1_ / arcScaleY;
var p0 = this.getCoords_(x0, y0); var p0 = ctx.getCoords_(x0, y0);
var p1 = this.getCoords_(x1, y1); var p1 = ctx.getCoords_(x1, y1);
var dx = p1.x - p0.x; var dx = p1.x - p0.x;
var dy = p1.y - p0.y; var dy = p1.y - p0.y;
angle = Math.atan2(dx, dy) * 180 / Math.PI; angle = Math.atan2(dx, dy) * 180 / Math.PI;
...@@ -710,16 +1032,14 @@ if (!document.createElement('canvas').getContext) { ...@@ -710,16 +1032,14 @@ if (!document.createElement('canvas').getContext) {
angle = 0; angle = 0;
} }
} else { } else {
var p0 = this.getCoords_(fillStyle.x0_, fillStyle.y0_); var p0 = ctx.getCoords_(fillStyle.x0_, fillStyle.y0_);
var width = max.x - min.x;
var height = max.y - min.y;
focus = { focus = {
x: (p0.x - min.x) / width, x: (p0.x - min.x) / width,
y: (p0.y - min.y) / height y: (p0.y - min.y) / height
}; };
width /= this.arcScaleX_ * Z; width /= arcScaleX * Z;
height /= this.arcScaleY_ * Z; height /= arcScaleY * Z;
var dimension = m.max(width, height); var dimension = m.max(width, height);
shift = 2 * fillStyle.r0_ / dimension; shift = 2 * fillStyle.r0_ / dimension;
expansion = 2 * fillStyle.r1_ / dimension - shift; expansion = 2 * fillStyle.r1_ / dimension - shift;
...@@ -735,8 +1055,8 @@ if (!document.createElement('canvas').getContext) { ...@@ -735,8 +1055,8 @@ if (!document.createElement('canvas').getContext) {
var length = stops.length; var length = stops.length;
var color1 = stops[0].color; var color1 = stops[0].color;
var color2 = stops[length - 1].color; var color2 = stops[length - 1].color;
var opacity1 = stops[0].alpha * this.globalAlpha; var opacity1 = stops[0].alpha * ctx.globalAlpha;
var opacity2 = stops[length - 1].alpha * this.globalAlpha; var opacity2 = stops[length - 1].alpha * ctx.globalAlpha;
var colors = []; var colors = [];
for (var i = 0; i < length; i++) { for (var i = 0; i < length; i++) {
...@@ -755,19 +1075,31 @@ if (!document.createElement('canvas').getContext) { ...@@ -755,19 +1075,31 @@ if (!document.createElement('canvas').getContext) {
' g_o_:opacity2="', opacity1, '"', ' g_o_:opacity2="', opacity1, '"',
' angle="', angle, '"', ' angle="', angle, '"',
' focusposition="', focus.x, ',', focus.y, '" />'); ' focusposition="', focus.x, ',', focus.y, '" />');
} else if (fillStyle instanceof CanvasPattern_) {
if (width && height) {
var deltaLeft = -min.x;
var deltaTop = -min.y;
lineStr.push('<g_vml_:fill',
' position="',
deltaLeft / width * arcScaleX * arcScaleX, ',',
deltaTop / height * arcScaleY * arcScaleY, '"',
' type="tile"',
// TODO: Figure out the correct size to fit the scale.
//' size="', w, 'px ', h, 'px"',
' src="', fillStyle.src_, '" />');
}
} else { } else {
var a = processStyle(ctx.fillStyle);
var color = a.color;
var opacity = a.alpha * ctx.globalAlpha;
lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity, lineStr.push('<g_vml_:fill color="', color, '" opacity="', opacity,
'" />'); '" />');
} }
}
lineStr.push('</g_vml_:shape>');
this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
};
contextPrototype.fill = function() { contextPrototype.fill = function() {
this.stroke(true); this.stroke(true);
} };
contextPrototype.closePath = function() { contextPrototype.closePath = function() {
this.currentPath_.push({type: 'close'}); this.currentPath_.push({type: 'close'});
...@@ -781,7 +1113,7 @@ if (!document.createElement('canvas').getContext) { ...@@ -781,7 +1113,7 @@ if (!document.createElement('canvas').getContext) {
return { return {
x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2, x: Z * (aX * m[0][0] + aY * m[1][0] + m[2][0]) - Z2,
y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2 y: Z * (aX * m[0][1] + aY * m[1][1] + m[2][1]) - Z2
} };
}; };
contextPrototype.save = function() { contextPrototype.save = function() {
...@@ -793,19 +1125,16 @@ if (!document.createElement('canvas').getContext) { ...@@ -793,19 +1125,16 @@ if (!document.createElement('canvas').getContext) {
}; };
contextPrototype.restore = function() { contextPrototype.restore = function() {
copyState(this.aStack_.pop(), this); if (this.aStack_.length) {
this.m_ = this.mStack_.pop(); copyState(this.aStack_.pop(), this);
this.m_ = this.mStack_.pop();
}
}; };
function matrixIsFinite(m) { function matrixIsFinite(m) {
for (var j = 0; j < 3; j++) { return isFinite(m[0][0]) && isFinite(m[0][1]) &&
for (var k = 0; k < 2; k++) { isFinite(m[1][0]) && isFinite(m[1][1]) &&
if (!isFinite(m[j][k]) || isNaN(m[j][k])) { isFinite(m[2][0]) && isFinite(m[2][1]);
return false;
}
}
}
return true;
} }
function setM(ctx, m, updateLineScale) { function setM(ctx, m, updateLineScale) {
...@@ -879,6 +1208,124 @@ if (!document.createElement('canvas').getContext) { ...@@ -879,6 +1208,124 @@ if (!document.createElement('canvas').getContext) {
setM(this, m, true); setM(this, m, true);
}; };
/**
* The text drawing function.
* The maxWidth argument isn't taken in account, since no browser supports
* it yet.
*/
contextPrototype.drawText_ = function(text, x, y, maxWidth, stroke) {
var m = this.m_,
delta = 1000,
left = 0,
right = delta,
offset = {x: 0, y: 0},
lineStr = [];
var fontStyle = getComputedStyle(processFontStyle(this.font),
this.element_);
var fontStyleString = buildStyle(fontStyle);
var elementStyle = this.element_.currentStyle;
var textAlign = this.textAlign.toLowerCase();
switch (textAlign) {
case 'left':
case 'center':
case 'right':
break;
case 'end':
textAlign = elementStyle.direction == 'ltr' ? 'right' : 'left';
break;
case 'start':
textAlign = elementStyle.direction == 'rtl' ? 'right' : 'left';
break;
default:
textAlign = 'left';
}
// 1.75 is an arbitrary number, as there is no info about the text baseline
switch (this.textBaseline) {
case 'hanging':
case 'top':
offset.y = fontStyle.size / 1.75;
break;
case 'middle':
break;
default:
case null:
case 'alphabetic':
case 'ideographic':
case 'bottom':
offset.y = -fontStyle.size / 2.25;
break;
}
switch(textAlign) {
case 'right':
left = delta;
right = 0.05;
break;
case 'center':
left = right = delta / 2;
break;
}
var d = this.getCoords_(x + offset.x, y + offset.y);
lineStr.push('<g_vml_:line from="', -left ,' 0" to="', right ,' 0.05" ',
' coordsize="100 100" coordorigin="0 0"',
' filled="', !stroke, '" stroked="', !!stroke,
'" style="position:absolute;width:1px;height:1px;">');
if (stroke) {
appendStroke(this, lineStr);
} else {
// TODO: Fix the min and max params.
appendFill(this, lineStr, {x: -left, y: 0},
{x: right, y: fontStyle.size});
}
var skewM = m[0][0].toFixed(3) + ',' + m[1][0].toFixed(3) + ',' +
m[0][1].toFixed(3) + ',' + m[1][1].toFixed(3) + ',0,0';
var skewOffset = mr(d.x / Z) + ',' + mr(d.y / Z);
lineStr.push('<g_vml_:skew on="t" matrix="', skewM ,'" ',
' offset="', skewOffset, '" origin="', left ,' 0" />',
'<g_vml_:path textpathok="true" />',
'<g_vml_:textpath on="true" string="',
encodeHtmlAttribute(text),
'" style="v-text-align:', textAlign,
';font:', encodeHtmlAttribute(fontStyleString),
'" /></g_vml_:line>');
this.element_.insertAdjacentHTML('beforeEnd', lineStr.join(''));
};
contextPrototype.fillText = function(text, x, y, maxWidth) {
this.drawText_(text, x, y, maxWidth, false);
};
contextPrototype.strokeText = function(text, x, y, maxWidth) {
this.drawText_(text, x, y, maxWidth, true);
};
contextPrototype.measureText = function(text) {
if (!this.textMeasureEl_) {
var s = '<span style="position:absolute;' +
'top:-20000px;left:0;padding:0;margin:0;border:none;' +
'white-space:pre;"></span>';
this.element_.insertAdjacentHTML('beforeEnd', s);
this.textMeasureEl_ = this.element_.lastChild;
}
var doc = this.element_.ownerDocument;
this.textMeasureEl_.innerHTML = '';
this.textMeasureEl_.style.font = this.font;
// Don't use innerHTML or innerText because they allow markup/whitespace.
this.textMeasureEl_.appendChild(doc.createTextNode(text));
return {width: this.textMeasureEl_.offsetWidth};
};
/******** STUBS ********/ /******** STUBS ********/
contextPrototype.clip = function() { contextPrototype.clip = function() {
// TODO: Implement // TODO: Implement
...@@ -888,8 +1335,8 @@ if (!document.createElement('canvas').getContext) { ...@@ -888,8 +1335,8 @@ if (!document.createElement('canvas').getContext) {
// TODO: Implement // TODO: Implement
}; };
contextPrototype.createPattern = function() { contextPrototype.createPattern = function(image, repetition) {
return new CanvasPattern_; return new CanvasPattern_(image, repetition);
}; };
// Gradient / Pattern Stubs // Gradient / Pattern Stubs
...@@ -911,14 +1358,70 @@ if (!document.createElement('canvas').getContext) { ...@@ -911,14 +1358,70 @@ if (!document.createElement('canvas').getContext) {
alpha: aColor.alpha}); alpha: aColor.alpha});
}; };
function CanvasPattern_() {} function CanvasPattern_(image, repetition) {
assertImageIsValid(image);
switch (repetition) {
case 'repeat':
case null:
case '':
this.repetition_ = 'repeat';
break
case 'repeat-x':
case 'repeat-y':
case 'no-repeat':
this.repetition_ = repetition;
break;
default:
throwException('SYNTAX_ERR');
}
this.src_ = image.src;
this.width_ = image.width;
this.height_ = image.height;
}
function throwException(s) {
throw new DOMException_(s);
}
function assertImageIsValid(img) {
if (!img || img.nodeType != 1 || img.tagName != 'IMG') {
throwException('TYPE_MISMATCH_ERR');
}
if (img.readyState != 'complete') {
throwException('INVALID_STATE_ERR');
}
}
function DOMException_(s) {
this.code = this[s];
this.message = s +': DOM Exception ' + this.code;
}
var p = DOMException_.prototype = new Error;
p.INDEX_SIZE_ERR = 1;
p.DOMSTRING_SIZE_ERR = 2;
p.HIERARCHY_REQUEST_ERR = 3;
p.WRONG_DOCUMENT_ERR = 4;
p.INVALID_CHARACTER_ERR = 5;
p.NO_DATA_ALLOWED_ERR = 6;
p.NO_MODIFICATION_ALLOWED_ERR = 7;
p.NOT_FOUND_ERR = 8;
p.NOT_SUPPORTED_ERR = 9;
p.INUSE_ATTRIBUTE_ERR = 10;
p.INVALID_STATE_ERR = 11;
p.SYNTAX_ERR = 12;
p.INVALID_MODIFICATION_ERR = 13;
p.NAMESPACE_ERR = 14;
p.INVALID_ACCESS_ERR = 15;
p.VALIDATION_ERR = 16;
p.TYPE_MISMATCH_ERR = 17;
// set up externs // set up externs
G_vmlCanvasManager = G_vmlCanvasManager_; G_vmlCanvasManager = G_vmlCanvasManager_;
CanvasRenderingContext2D = CanvasRenderingContext2D_; CanvasRenderingContext2D = CanvasRenderingContext2D_;
CanvasGradient = CanvasGradient_; CanvasGradient = CanvasGradient_;
CanvasPattern = CanvasPattern_; CanvasPattern = CanvasPattern_;
DOMException = DOMException_;
})(); })();
} // if } // if
if(!document.createElement("canvas").getContext){(function(){var S=Math;var T=S.round;var P=S.sin;var c=S.cos;var K=S.abs;var b=S.sqrt;var A=10;var L=A/2;function H(){return this.context_||(this.context_=new N(this))}var R=Array.prototype.slice;function d(e,g,h){var Z=R.call(arguments,2);return function(){return e.apply(g,Z.concat(R.call(arguments)))}}var I={init:function(Z){if(/MSIE/.test(navigator.userAgent)&&!window.opera){var e=Z||document;e.createElement("canvas");e.attachEvent("onreadystatechange",d(this.init_,this,e))}},init_:function(g){if(!g.namespaces.g_vml_){g.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml","#default#VML")}if(!g.namespaces.g_o_){g.namespaces.add("g_o_","urn:schemas-microsoft-com:office:office","#default#VML")}if(!g.styleSheets.ex_canvas_){var f=g.createStyleSheet();f.owningElement.id="ex_canvas_";f.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}g_vml_\\:*{behavior:url(#default#VML)}g_o_\\:*{behavior:url(#default#VML)}"}var e=g.getElementsByTagName("canvas");for(var Z=0;Z<e.length;Z++){this.initElement(e[Z])}},initElement:function(e){if(!e.getContext){e.getContext=H;e.innerHTML="";e.attachEvent("onpropertychange",a);e.attachEvent("onresize",B);var Z=e.attributes;if(Z.width&&Z.width.specified){e.style.width=Z.width.nodeValue+"px"}else{e.width=e.clientWidth}if(Z.height&&Z.height.specified){e.style.height=Z.height.nodeValue+"px"}else{e.height=e.clientHeight}}return e}};function a(f){var Z=f.srcElement;switch(f.propertyName){case"width":Z.style.width=Z.attributes.width.nodeValue+"px";Z.getContext().clearRect();break;case"height":Z.style.height=Z.attributes.height.nodeValue+"px";Z.getContext().clearRect();break}}function B(f){var Z=f.srcElement;if(Z.firstChild){Z.firstChild.style.width=Z.clientWidth+"px";Z.firstChild.style.height=Z.clientHeight+"px"}}I.init();var E=[];for(var W=0;W<16;W++){for(var V=0;V<16;V++){E[W*16+V]=W.toString(16)+V.toString(16)}}function O(){return[[1,0,0],[0,1,0],[0,0,1]]}function D(g,f){var e=O();for(var Z=0;Z<3;Z++){for(var j=0;j<3;j++){var h=0;for(var i=0;i<3;i++){h+=g[Z][i]*f[i][j]}e[Z][j]=h}}return e}function U(e,Z){Z.fillStyle=e.fillStyle;Z.lineCap=e.lineCap;Z.lineJoin=e.lineJoin;Z.lineWidth=e.lineWidth;Z.miterLimit=e.miterLimit;Z.shadowBlur=e.shadowBlur;Z.shadowColor=e.shadowColor;Z.shadowOffsetX=e.shadowOffsetX;Z.shadowOffsetY=e.shadowOffsetY;Z.strokeStyle=e.strokeStyle;Z.globalAlpha=e.globalAlpha;Z.arcScaleX_=e.arcScaleX_;Z.arcScaleY_=e.arcScaleY_;Z.lineScale_=e.lineScale_}function C(e){var h,g=1;e=String(e);if(e.substring(0,3)=="rgb"){var k=e.indexOf("(",3);var Z=e.indexOf(")",k+1);var j=e.substring(k+1,Z).split(",");h="#";for(var f=0;f<3;f++){h+=E[Number(j[f])]}if(j.length==4&&e.substr(3,1)=="a"){g=j[3]}}else{h=e}return{color:h,alpha:g}}function Q(Z){switch(Z){case"butt":return"flat";case"round":return"round";case"square":default:return"square"}}function N(e){this.m_=O();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=A*1;this.globalAlpha=1;this.canvas=e;var Z=e.ownerDocument.createElement("div");Z.style.width=e.clientWidth+"px";Z.style.height=e.clientHeight+"px";Z.style.overflow="hidden";Z.style.position="absolute";e.appendChild(Z);this.element_=Z;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var J=N.prototype;J.clearRect=function(){this.element_.innerHTML=""};J.beginPath=function(){this.currentPath_=[]};J.moveTo=function(e,Z){var f=this.getCoords_(e,Z);this.currentPath_.push({type:"moveTo",x:f.x,y:f.y});this.currentX_=f.x;this.currentY_=f.y};J.lineTo=function(e,Z){var f=this.getCoords_(e,Z);this.currentPath_.push({type:"lineTo",x:f.x,y:f.y});this.currentX_=f.x;this.currentY_=f.y};J.bezierCurveTo=function(f,e,l,k,j,h){var Z=this.getCoords_(j,h);var i=this.getCoords_(f,e);var g=this.getCoords_(l,k);M(this,i,g,Z)};function M(Z,g,f,e){Z.currentPath_.push({type:"bezierCurveTo",cp1x:g.x,cp1y:g.y,cp2x:f.x,cp2y:f.y,x:e.x,y:e.y});Z.currentX_=e.x;Z.currentY_=e.y}J.quadraticCurveTo=function(j,f,e,Z){var i=this.getCoords_(j,f);var h=this.getCoords_(e,Z);var k={x:this.currentX_+2/3*(i.x-this.currentX_),y:this.currentY_+2/3*(i.y-this.currentY_)};var g={x:k.x+(h.x-this.currentX_)/3,y:k.y+(h.y-this.currentY_)/3};M(this,k,g,h)};J.arc=function(m,k,l,h,e,f){l*=A;var r=f?"at":"wa";var n=m+c(h)*l-L;var q=k+P(h)*l-L;var Z=m+c(e)*l-L;var o=k+P(e)*l-L;if(n==Z&&!f){n+=0.125}var g=this.getCoords_(m,k);var j=this.getCoords_(n,q);var i=this.getCoords_(Z,o);this.currentPath_.push({type:r,x:g.x,y:g.y,radius:l,xStart:j.x,yStart:j.y,xEnd:i.x,yEnd:i.y})};J.rect=function(f,e,Z,g){this.moveTo(f,e);this.lineTo(f+Z,e);this.lineTo(f+Z,e+g);this.lineTo(f,e+g);this.closePath()};J.strokeRect=function(f,e,Z,g){var h=this.currentPath_;this.beginPath();this.moveTo(f,e);this.lineTo(f+Z,e);this.lineTo(f+Z,e+g);this.lineTo(f,e+g);this.closePath();this.stroke();this.currentPath_=h};J.fillRect=function(f,e,Z,g){var h=this.currentPath_;this.beginPath();this.moveTo(f,e);this.lineTo(f+Z,e);this.lineTo(f+Z,e+g);this.lineTo(f,e+g);this.closePath();this.fill();this.currentPath_=h};J.createLinearGradient=function(e,g,Z,f){var h=new X("gradient");h.x0_=e;h.y0_=g;h.x1_=Z;h.y1_=f;return h};J.createRadialGradient=function(g,i,f,e,h,Z){var j=new X("gradientradial");j.x0_=g;j.y0_=i;j.r0_=f;j.x1_=e;j.y1_=h;j.r1_=Z;return j};J.drawImage=function(t,f){var m,k,o,AB,r,p,v,AD;var n=t.runtimeStyle.width;var s=t.runtimeStyle.height;t.runtimeStyle.width="auto";t.runtimeStyle.height="auto";var l=t.width;var z=t.height;t.runtimeStyle.width=n;t.runtimeStyle.height=s;if(arguments.length==3){m=arguments[1];k=arguments[2];r=p=0;v=o=l;AD=AB=z}else{if(arguments.length==5){m=arguments[1];k=arguments[2];o=arguments[3];AB=arguments[4];r=p=0;v=l;AD=z}else{if(arguments.length==9){r=arguments[1];p=arguments[2];v=arguments[3];AD=arguments[4];m=arguments[5];k=arguments[6];o=arguments[7];AB=arguments[8]}else{throw Error("Invalid number of arguments")}}}var AC=this.getCoords_(m,k);var g=v/2;var e=AD/2;var AA=[];var Z=10;var j=10;AA.push(" <g_vml_:group",' coordsize="',A*Z,",",A*j,'"',' coordorigin="0,0"',' style="width:',Z,"px;height:",j,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]){var i=[];i.push("M11=",this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",T(AC.x/A),",","Dy=",T(AC.y/A),"");var y=AC;var x=this.getCoords_(m+o,k);var u=this.getCoords_(m,k+AB);var q=this.getCoords_(m+o,k+AB);y.x=S.max(y.x,x.x,u.x,q.x);y.y=S.max(y.y,x.y,u.y,q.y);AA.push("padding:0 ",T(y.x/A),"px ",T(y.y/A),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",i.join(""),", sizingmethod='clip');")}else{AA.push("top:",T(AC.y/A),"px;left:",T(AC.x/A),"px;")}AA.push(' ">','<g_vml_:image src="',t.src,'"',' style="width:',A*o,"px;"," height:",A*AB,'px;"',' cropleft="',r/l,'"',' croptop="',p/z,'"',' cropright="',(l-r-v)/l,'"',' cropbottom="',(z-p-AD)/z,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",AA.join(""))};J.stroke=function(AF){var k=[];var l=false;var AQ=C(AF?this.fillStyle:this.strokeStyle);var AB=AQ.color;var AL=AQ.alpha*this.globalAlpha;var g=10;var n=10;k.push("<g_vml_:shape",' filled="',!!AF,'"',' style="position:absolute;width:',g,"px;height:",n,'px;"',' coordorigin="0 0" coordsize="',A*g," ",A*n,'"',' stroked="',!AF,'"',' path="');var m=false;var AP={x:null,y:null};var x={x:null,y:null};for(var AK=0;AK<this.currentPath_.length;AK++){var AJ=this.currentPath_[AK];var AO;switch(AJ.type){case"moveTo":AO=AJ;k.push(" m ",T(AJ.x),",",T(AJ.y));break;case"lineTo":k.push(" l ",T(AJ.x),",",T(AJ.y));break;case"close":k.push(" x ");AJ=null;break;case"bezierCurveTo":k.push(" c ",T(AJ.cp1x),",",T(AJ.cp1y),",",T(AJ.cp2x),",",T(AJ.cp2y),",",T(AJ.x),",",T(AJ.y));break;case"at":case"wa":k.push(" ",AJ.type," ",T(AJ.x-this.arcScaleX_*AJ.radius),",",T(AJ.y-this.arcScaleY_*AJ.radius)," ",T(AJ.x+this.arcScaleX_*AJ.radius),",",T(AJ.y+this.arcScaleY_*AJ.radius)," ",T(AJ.xStart),",",T(AJ.yStart)," ",T(AJ.xEnd),",",T(AJ.yEnd));break}if(AJ){if(AP.x==null||AJ.x<AP.x){AP.x=AJ.x}if(x.x==null||AJ.x>x.x){x.x=AJ.x}if(AP.y==null||AJ.y<AP.y){AP.y=AJ.y}if(x.y==null||AJ.y>x.y){x.y=AJ.y}}}k.push(' ">');if(!AF){var w=this.lineScale_*this.lineWidth;if(w<1){AL*=w}k.push("<g_vml_:stroke",' opacity="',AL,'"',' joinstyle="',this.lineJoin,'"',' miterlimit="',this.miterLimit,'"',' endcap="',Q(this.lineCap),'"',' weight="',w,'px"',' color="',AB,'" />')}else{if(typeof this.fillStyle=="object"){var o=this.fillStyle;var u=0;var AI={x:0,y:0};var AC=0;var s=1;if(o.type_=="gradient"){var r=o.x0_/this.arcScaleX_;var e=o.y0_/this.arcScaleY_;var q=o.x1_/this.arcScaleX_;var AR=o.y1_/this.arcScaleY_;var AN=this.getCoords_(r,e);var AM=this.getCoords_(q,AR);var j=AM.x-AN.x;var h=AM.y-AN.y;u=Math.atan2(j,h)*180/Math.PI;if(u<0){u+=360}if(u<0.000001){u=0}}else{var AN=this.getCoords_(o.x0_,o.y0_);var Z=x.x-AP.x;var f=x.y-AP.y;AI={x:(AN.x-AP.x)/Z,y:(AN.y-AP.y)/f};Z/=this.arcScaleX_*A;f/=this.arcScaleY_*A;var AH=S.max(Z,f);AC=2*o.r0_/AH;s=2*o.r1_/AH-AC}var AA=o.colors_;AA.sort(function(p,i){return p.offset-i.offset});var v=AA.length;var z=AA[0].color;var y=AA[v-1].color;var AE=AA[0].alpha*this.globalAlpha;var AD=AA[v-1].alpha*this.globalAlpha;var AG=[];for(var AK=0;AK<v;AK++){var t=AA[AK];AG.push(t.offset*s+AC+" "+t.color)}k.push('<g_vml_:fill type="',o.type_,'"',' method="none" focus="100%"',' color="',z,'"',' color2="',y,'"',' colors="',AG.join(","),'"',' opacity="',AD,'"',' g_o_:opacity2="',AE,'"',' angle="',u,'"',' focusposition="',AI.x,",",AI.y,'" />')}else{k.push('<g_vml_:fill color="',AB,'" opacity="',AL,'" />')}}k.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",k.join(""))};J.fill=function(){this.stroke(true)};J.closePath=function(){this.currentPath_.push({type:"close"})};J.getCoords_=function(f,e){var Z=this.m_;return{x:A*(f*Z[0][0]+e*Z[1][0]+Z[2][0])-L,y:A*(f*Z[0][1]+e*Z[1][1]+Z[2][1])-L}};J.save=function(){var Z={};U(this,Z);this.aStack_.push(Z);this.mStack_.push(this.m_);this.m_=D(O(),this.m_)};J.restore=function(){U(this.aStack_.pop(),this);this.m_=this.mStack_.pop()};function G(Z){for(var f=0;f<3;f++){for(var e=0;e<2;e++){if(!isFinite(Z[f][e])||isNaN(Z[f][e])){return false}}}return true}function Y(e,Z,f){if(!G(Z)){return }e.m_=Z;if(f){var g=Z[0][0]*Z[1][1]-Z[0][1]*Z[1][0];e.lineScale_=b(K(g))}}J.translate=function(f,e){var Z=[[1,0,0],[0,1,0],[f,e,1]];Y(this,D(Z,this.m_),false)};J.rotate=function(e){var g=c(e);var f=P(e);var Z=[[g,f,0],[-f,g,0],[0,0,1]];Y(this,D(Z,this.m_),false)};J.scale=function(f,e){this.arcScaleX_*=f;this.arcScaleY_*=e;var Z=[[f,0,0],[0,e,0],[0,0,1]];Y(this,D(Z,this.m_),true)};J.transform=function(h,g,j,i,e,Z){var f=[[h,g,0],[j,i,0],[e,Z,1]];Y(this,D(f,this.m_),true)};J.setTransform=function(h,g,j,i,f,e){var Z=[[h,g,0],[j,i,0],[f,e,1]];Y(this,Z,true)};J.clip=function(){};J.arcTo=function(){};J.createPattern=function(){return new F};function X(Z){this.type_=Z;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}X.prototype.addColorStop=function(e,Z){Z=C(Z);this.colors_.push({offset:e,color:Z.color,alpha:Z.alpha})};function F(){}G_vmlCanvasManager=I;CanvasRenderingContext2D=N;CanvasGradient=X;CanvasPattern=F})()}; if(!document.createElement("canvas").getContext){(function(){var z=Math;var K=z.round;var J=z.sin;var U=z.cos;var b=z.abs;var k=z.sqrt;var D=10;var F=D/2;function T(){return this.context_||(this.context_=new W(this))}var O=Array.prototype.slice;function G(i,j,m){var Z=O.call(arguments,2);return function(){return i.apply(j,Z.concat(O.call(arguments)))}}function AD(Z){return String(Z).replace(/&/g,"&amp;").replace(/"/g,"&quot;")}function r(i){if(!i.namespaces.g_vml_){i.namespaces.add("g_vml_","urn:schemas-microsoft-com:vml","#default#VML")}if(!i.namespaces.g_o_){i.namespaces.add("g_o_","urn:schemas-microsoft-com:office:office","#default#VML")}if(!i.styleSheets.ex_canvas_){var Z=i.createStyleSheet();Z.owningElement.id="ex_canvas_";Z.cssText="canvas{display:inline-block;overflow:hidden;text-align:left;width:300px;height:150px}"}}r(document);var E={init:function(Z){if(/MSIE/.test(navigator.userAgent)&&!window.opera){var i=Z||document;i.createElement("canvas");i.attachEvent("onreadystatechange",G(this.init_,this,i))}},init_:function(m){var j=m.getElementsByTagName("canvas");for(var Z=0;Z<j.length;Z++){this.initElement(j[Z])}},initElement:function(i){if(!i.getContext){i.getContext=T;r(i.ownerDocument);i.innerHTML="";i.attachEvent("onpropertychange",S);i.attachEvent("onresize",w);var Z=i.attributes;if(Z.width&&Z.width.specified){i.style.width=Z.width.nodeValue+"px"}else{i.width=i.clientWidth}if(Z.height&&Z.height.specified){i.style.height=Z.height.nodeValue+"px"}else{i.height=i.clientHeight}}return i}};function S(i){var Z=i.srcElement;switch(i.propertyName){case"width":Z.getContext().clearRect();Z.style.width=Z.attributes.width.nodeValue+"px";Z.firstChild.style.width=Z.clientWidth+"px";break;case"height":Z.getContext().clearRect();Z.style.height=Z.attributes.height.nodeValue+"px";Z.firstChild.style.height=Z.clientHeight+"px";break}}function w(i){var Z=i.srcElement;if(Z.firstChild){Z.firstChild.style.width=Z.clientWidth+"px";Z.firstChild.style.height=Z.clientHeight+"px"}}E.init();var I=[];for(var AC=0;AC<16;AC++){for(var AB=0;AB<16;AB++){I[AC*16+AB]=AC.toString(16)+AB.toString(16)}}function V(){return[[1,0,0],[0,1,0],[0,0,1]]}function d(m,j){var i=V();for(var Z=0;Z<3;Z++){for(var AF=0;AF<3;AF++){var p=0;for(var AE=0;AE<3;AE++){p+=m[Z][AE]*j[AE][AF]}i[Z][AF]=p}}return i}function Q(i,Z){Z.fillStyle=i.fillStyle;Z.lineCap=i.lineCap;Z.lineJoin=i.lineJoin;Z.lineWidth=i.lineWidth;Z.miterLimit=i.miterLimit;Z.shadowBlur=i.shadowBlur;Z.shadowColor=i.shadowColor;Z.shadowOffsetX=i.shadowOffsetX;Z.shadowOffsetY=i.shadowOffsetY;Z.strokeStyle=i.strokeStyle;Z.globalAlpha=i.globalAlpha;Z.font=i.font;Z.textAlign=i.textAlign;Z.textBaseline=i.textBaseline;Z.arcScaleX_=i.arcScaleX_;Z.arcScaleY_=i.arcScaleY_;Z.lineScale_=i.lineScale_}var B={aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aquamarine:"#7FFFD4",azure:"#F0FFFF",beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000000",blanchedalmond:"#FFEBCD",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9EA0",chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#00FFFF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgreen:"#006400",darkgrey:"#A9A9A9",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",darkturquoise:"#00CED1",darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",gold:"#FFD700",goldenrod:"#DAA520",grey:"#808080",greenyellow:"#ADFF2F",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"#FFFFF0",khaki:"#F0E68C",lavender:"#E6E6FA",lavenderblush:"#FFF0F5",lawngreen:"#7CFC00",lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgreen:"#90EE90",lightgrey:"#D3D3D3",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#B0C4DE",lightyellow:"#FFFFE0",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#FF00FF",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370DB",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",oldlace:"#FDF5E6",olivedrab:"#6B8E23",orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#DB7093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#DDA0DD",powderblue:"#B0E0E6",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",skyblue:"#87CEEB",slateblue:"#6A5ACD",slategray:"#708090",slategrey:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",whitesmoke:"#F5F5F5",yellowgreen:"#9ACD32"};function g(i){var m=i.indexOf("(",3);var Z=i.indexOf(")",m+1);var j=i.substring(m+1,Z).split(",");if(j.length==4&&i.substr(3,1)=="a"){alpha=Number(j[3])}else{j[3]=1}return j}function C(Z){return parseFloat(Z)/100}function N(i,j,Z){return Math.min(Z,Math.max(j,i))}function c(AF){var j,i,Z;h=parseFloat(AF[0])/360%360;if(h<0){h++}s=N(C(AF[1]),0,1);l=N(C(AF[2]),0,1);if(s==0){j=i=Z=l}else{var m=l<0.5?l*(1+s):l+s-l*s;var AE=2*l-m;j=A(AE,m,h+1/3);i=A(AE,m,h);Z=A(AE,m,h-1/3)}return"#"+I[Math.floor(j*255)]+I[Math.floor(i*255)]+I[Math.floor(Z*255)]}function A(i,Z,j){if(j<0){j++}if(j>1){j--}if(6*j<1){return i+(Z-i)*6*j}else{if(2*j<1){return Z}else{if(3*j<2){return i+(Z-i)*(2/3-j)*6}else{return i}}}}function Y(Z){var AE,p=1;Z=String(Z);if(Z.charAt(0)=="#"){AE=Z}else{if(/^rgb/.test(Z)){var m=g(Z);var AE="#",AF;for(var j=0;j<3;j++){if(m[j].indexOf("%")!=-1){AF=Math.floor(C(m[j])*255)}else{AF=Number(m[j])}AE+=I[N(AF,0,255)]}p=m[3]}else{if(/^hsl/.test(Z)){var m=g(Z);AE=c(m);p=m[3]}else{AE=B[Z]||Z}}}return{color:AE,alpha:p}}var L={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"};var f={};function X(Z){if(f[Z]){return f[Z]}var m=document.createElement("div");var j=m.style;try{j.font=Z}catch(i){}return f[Z]={style:j.fontStyle||L.style,variant:j.fontVariant||L.variant,weight:j.fontWeight||L.weight,size:j.fontSize||L.size,family:j.fontFamily||L.family}}function P(j,i){var Z={};for(var AF in j){Z[AF]=j[AF]}var AE=parseFloat(i.currentStyle.fontSize),m=parseFloat(j.size);if(typeof j.size=="number"){Z.size=j.size}else{if(j.size.indexOf("px")!=-1){Z.size=m}else{if(j.size.indexOf("em")!=-1){Z.size=AE*m}else{if(j.size.indexOf("%")!=-1){Z.size=(AE/100)*m}else{if(j.size.indexOf("pt")!=-1){Z.size=m/0.75}else{Z.size=AE}}}}}Z.size*=0.981;return Z}function AA(Z){return Z.style+" "+Z.variant+" "+Z.weight+" "+Z.size+"px "+Z.family}function t(Z){switch(Z){case"butt":return"flat";case"round":return"round";case"square":default:return"square"}}function W(i){this.m_=V();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle="#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=D*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=i;var Z=i.ownerDocument.createElement("div");Z.style.width=i.clientWidth+"px";Z.style.height=i.clientHeight+"px";Z.style.overflow="hidden";Z.style.position="absolute";i.appendChild(Z);this.element_=Z;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var M=W.prototype;M.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};M.beginPath=function(){this.currentPath_=[]};M.moveTo=function(i,Z){var j=this.getCoords_(i,Z);this.currentPath_.push({type:"moveTo",x:j.x,y:j.y});this.currentX_=j.x;this.currentY_=j.y};M.lineTo=function(i,Z){var j=this.getCoords_(i,Z);this.currentPath_.push({type:"lineTo",x:j.x,y:j.y});this.currentX_=j.x;this.currentY_=j.y};M.bezierCurveTo=function(j,i,AI,AH,AG,AE){var Z=this.getCoords_(AG,AE);var AF=this.getCoords_(j,i);var m=this.getCoords_(AI,AH);e(this,AF,m,Z)};function e(Z,m,j,i){Z.currentPath_.push({type:"bezierCurveTo",cp1x:m.x,cp1y:m.y,cp2x:j.x,cp2y:j.y,x:i.x,y:i.y});Z.currentX_=i.x;Z.currentY_=i.y}M.quadraticCurveTo=function(AG,j,i,Z){var AF=this.getCoords_(AG,j);var AE=this.getCoords_(i,Z);var AH={x:this.currentX_+2/3*(AF.x-this.currentX_),y:this.currentY_+2/3*(AF.y-this.currentY_)};var m={x:AH.x+(AE.x-this.currentX_)/3,y:AH.y+(AE.y-this.currentY_)/3};e(this,AH,m,AE)};M.arc=function(AJ,AH,AI,AE,i,j){AI*=D;var AN=j?"at":"wa";var AK=AJ+U(AE)*AI-F;var AM=AH+J(AE)*AI-F;var Z=AJ+U(i)*AI-F;var AL=AH+J(i)*AI-F;if(AK==Z&&!j){AK+=0.125}var m=this.getCoords_(AJ,AH);var AG=this.getCoords_(AK,AM);var AF=this.getCoords_(Z,AL);this.currentPath_.push({type:AN,x:m.x,y:m.y,radius:AI,xStart:AG.x,yStart:AG.y,xEnd:AF.x,yEnd:AF.y})};M.rect=function(j,i,Z,m){this.moveTo(j,i);this.lineTo(j+Z,i);this.lineTo(j+Z,i+m);this.lineTo(j,i+m);this.closePath()};M.strokeRect=function(j,i,Z,m){var p=this.currentPath_;this.beginPath();this.moveTo(j,i);this.lineTo(j+Z,i);this.lineTo(j+Z,i+m);this.lineTo(j,i+m);this.closePath();this.stroke();this.currentPath_=p};M.fillRect=function(j,i,Z,m){var p=this.currentPath_;this.beginPath();this.moveTo(j,i);this.lineTo(j+Z,i);this.lineTo(j+Z,i+m);this.lineTo(j,i+m);this.closePath();this.fill();this.currentPath_=p};M.createLinearGradient=function(i,m,Z,j){var p=new v("gradient");p.x0_=i;p.y0_=m;p.x1_=Z;p.y1_=j;return p};M.createRadialGradient=function(m,AE,j,i,p,Z){var AF=new v("gradientradial");AF.x0_=m;AF.y0_=AE;AF.r0_=j;AF.x1_=i;AF.y1_=p;AF.r1_=Z;return AF};M.drawImage=function(AO,j){var AH,AF,AJ,AV,AM,AK,AQ,AX;var AI=AO.runtimeStyle.width;var AN=AO.runtimeStyle.height;AO.runtimeStyle.width="auto";AO.runtimeStyle.height="auto";var AG=AO.width;var AT=AO.height;AO.runtimeStyle.width=AI;AO.runtimeStyle.height=AN;if(arguments.length==3){AH=arguments[1];AF=arguments[2];AM=AK=0;AQ=AJ=AG;AX=AV=AT}else{if(arguments.length==5){AH=arguments[1];AF=arguments[2];AJ=arguments[3];AV=arguments[4];AM=AK=0;AQ=AG;AX=AT}else{if(arguments.length==9){AM=arguments[1];AK=arguments[2];AQ=arguments[3];AX=arguments[4];AH=arguments[5];AF=arguments[6];AJ=arguments[7];AV=arguments[8]}else{throw Error("Invalid number of arguments")}}}var AW=this.getCoords_(AH,AF);var m=AQ/2;var i=AX/2;var AU=[];var Z=10;var AE=10;AU.push(" <g_vml_:group",' coordsize="',D*Z,",",D*AE,'"',' coordorigin="0,0"',' style="width:',Z,"px;height:",AE,"px;position:absolute;");if(this.m_[0][0]!=1||this.m_[0][1]||this.m_[1][1]!=1||this.m_[1][0]){var p=[];p.push("M11=",this.m_[0][0],",","M12=",this.m_[1][0],",","M21=",this.m_[0][1],",","M22=",this.m_[1][1],",","Dx=",K(AW.x/D),",","Dy=",K(AW.y/D),"");var AS=AW;var AR=this.getCoords_(AH+AJ,AF);var AP=this.getCoords_(AH,AF+AV);var AL=this.getCoords_(AH+AJ,AF+AV);AS.x=z.max(AS.x,AR.x,AP.x,AL.x);AS.y=z.max(AS.y,AR.y,AP.y,AL.y);AU.push("padding:0 ",K(AS.x/D),"px ",K(AS.y/D),"px 0;filter:progid:DXImageTransform.Microsoft.Matrix(",p.join(""),", sizingmethod='clip');")}else{AU.push("top:",K(AW.y/D),"px;left:",K(AW.x/D),"px;")}AU.push(' ">','<g_vml_:image src="',AO.src,'"',' style="width:',D*AJ,"px;"," height:",D*AV,'px"',' cropleft="',AM/AG,'"',' croptop="',AK/AT,'"',' cropright="',(AG-AM-AQ)/AG,'"',' cropbottom="',(AT-AK-AX)/AT,'"'," />","</g_vml_:group>");this.element_.insertAdjacentHTML("BeforeEnd",AU.join(""))};M.stroke=function(AM){var m=10;var AN=10;var AE=5000;var AG={x:null,y:null};var AL={x:null,y:null};for(var AH=0;AH<this.currentPath_.length;AH+=AE){var AK=[];var AF=false;AK.push("<g_vml_:shape",' filled="',!!AM,'"',' style="position:absolute;width:',m,"px;height:",AN,'px;"',' coordorigin="0,0"',' coordsize="',D*m,",",D*AN,'"',' stroked="',!AM,'"',' path="');var AO=false;for(var AI=AH;AI<Math.min(AH+AE,this.currentPath_.length);AI++){if(AI%AE==0&&AI>0){AK.push(" m ",K(this.currentPath_[AI-1].x),",",K(this.currentPath_[AI-1].y))}var Z=this.currentPath_[AI];var AJ;switch(Z.type){case"moveTo":AJ=Z;AK.push(" m ",K(Z.x),",",K(Z.y));break;case"lineTo":AK.push(" l ",K(Z.x),",",K(Z.y));break;case"close":AK.push(" x ");Z=null;break;case"bezierCurveTo":AK.push(" c ",K(Z.cp1x),",",K(Z.cp1y),",",K(Z.cp2x),",",K(Z.cp2y),",",K(Z.x),",",K(Z.y));break;case"at":case"wa":AK.push(" ",Z.type," ",K(Z.x-this.arcScaleX_*Z.radius),",",K(Z.y-this.arcScaleY_*Z.radius)," ",K(Z.x+this.arcScaleX_*Z.radius),",",K(Z.y+this.arcScaleY_*Z.radius)," ",K(Z.xStart),",",K(Z.yStart)," ",K(Z.xEnd),",",K(Z.yEnd));break}if(Z){if(AG.x==null||Z.x<AG.x){AG.x=Z.x}if(AL.x==null||Z.x>AL.x){AL.x=Z.x}if(AG.y==null||Z.y<AG.y){AG.y=Z.y}if(AL.y==null||Z.y>AL.y){AL.y=Z.y}}}AK.push(' ">');if(!AM){R(this,AK)}else{a(this,AK,AG,AL)}AK.push("</g_vml_:shape>");this.element_.insertAdjacentHTML("beforeEnd",AK.join(""))}};function R(j,AE){var i=Y(j.strokeStyle);var m=i.color;var p=i.alpha*j.globalAlpha;var Z=j.lineScale_*j.lineWidth;if(Z<1){p*=Z}AE.push("<g_vml_:stroke",' opacity="',p,'"',' joinstyle="',j.lineJoin,'"',' miterlimit="',j.miterLimit,'"',' endcap="',t(j.lineCap),'"',' weight="',Z,'px"',' color="',m,'" />')}function a(AO,AG,Ah,AP){var AH=AO.fillStyle;var AY=AO.arcScaleX_;var AX=AO.arcScaleY_;var Z=AP.x-Ah.x;var m=AP.y-Ah.y;if(AH instanceof v){var AL=0;var Ac={x:0,y:0};var AU=0;var AK=1;if(AH.type_=="gradient"){var AJ=AH.x0_/AY;var j=AH.y0_/AX;var AI=AH.x1_/AY;var Aj=AH.y1_/AX;var Ag=AO.getCoords_(AJ,j);var Af=AO.getCoords_(AI,Aj);var AE=Af.x-Ag.x;var p=Af.y-Ag.y;AL=Math.atan2(AE,p)*180/Math.PI;if(AL<0){AL+=360}if(AL<0.000001){AL=0}}else{var Ag=AO.getCoords_(AH.x0_,AH.y0_);Ac={x:(Ag.x-Ah.x)/Z,y:(Ag.y-Ah.y)/m};Z/=AY*D;m/=AX*D;var Aa=z.max(Z,m);AU=2*AH.r0_/Aa;AK=2*AH.r1_/Aa-AU}var AS=AH.colors_;AS.sort(function(Ak,i){return Ak.offset-i.offset});var AN=AS.length;var AR=AS[0].color;var AQ=AS[AN-1].color;var AW=AS[0].alpha*AO.globalAlpha;var AV=AS[AN-1].alpha*AO.globalAlpha;var Ab=[];for(var Ae=0;Ae<AN;Ae++){var AM=AS[Ae];Ab.push(AM.offset*AK+AU+" "+AM.color)}AG.push('<g_vml_:fill type="',AH.type_,'"',' method="none" focus="100%"',' color="',AR,'"',' color2="',AQ,'"',' colors="',Ab.join(","),'"',' opacity="',AV,'"',' g_o_:opacity2="',AW,'"',' angle="',AL,'"',' focusposition="',Ac.x,",",Ac.y,'" />')}else{if(AH instanceof u){if(Z&&m){var AF=-Ah.x;var AZ=-Ah.y;AG.push("<g_vml_:fill",' position="',AF/Z*AY*AY,",",AZ/m*AX*AX,'"',' type="tile"',' src="',AH.src_,'" />')}}else{var Ai=Y(AO.fillStyle);var AT=Ai.color;var Ad=Ai.alpha*AO.globalAlpha;AG.push('<g_vml_:fill color="',AT,'" opacity="',Ad,'" />')}}}M.fill=function(){this.stroke(true)};M.closePath=function(){this.currentPath_.push({type:"close"})};M.getCoords_=function(j,i){var Z=this.m_;return{x:D*(j*Z[0][0]+i*Z[1][0]+Z[2][0])-F,y:D*(j*Z[0][1]+i*Z[1][1]+Z[2][1])-F}};M.save=function(){var Z={};Q(this,Z);this.aStack_.push(Z);this.mStack_.push(this.m_);this.m_=d(V(),this.m_)};M.restore=function(){if(this.aStack_.length){Q(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function H(Z){return isFinite(Z[0][0])&&isFinite(Z[0][1])&&isFinite(Z[1][0])&&isFinite(Z[1][1])&&isFinite(Z[2][0])&&isFinite(Z[2][1])}function y(i,Z,j){if(!H(Z)){return }i.m_=Z;if(j){var p=Z[0][0]*Z[1][1]-Z[0][1]*Z[1][0];i.lineScale_=k(b(p))}}M.translate=function(j,i){var Z=[[1,0,0],[0,1,0],[j,i,1]];y(this,d(Z,this.m_),false)};M.rotate=function(i){var m=U(i);var j=J(i);var Z=[[m,j,0],[-j,m,0],[0,0,1]];y(this,d(Z,this.m_),false)};M.scale=function(j,i){this.arcScaleX_*=j;this.arcScaleY_*=i;var Z=[[j,0,0],[0,i,0],[0,0,1]];y(this,d(Z,this.m_),true)};M.transform=function(p,m,AF,AE,i,Z){var j=[[p,m,0],[AF,AE,0],[i,Z,1]];y(this,d(j,this.m_),true)};M.setTransform=function(AE,p,AG,AF,j,i){var Z=[[AE,p,0],[AG,AF,0],[j,i,1]];y(this,Z,true)};M.drawText_=function(AK,AI,AH,AN,AG){var AM=this.m_,AQ=1000,i=0,AP=AQ,AF={x:0,y:0},AE=[];var Z=P(X(this.font),this.element_);var j=AA(Z);var AR=this.element_.currentStyle;var p=this.textAlign.toLowerCase();switch(p){case"left":case"center":case"right":break;case"end":p=AR.direction=="ltr"?"right":"left";break;case"start":p=AR.direction=="rtl"?"right":"left";break;default:p="left"}switch(this.textBaseline){case"hanging":case"top":AF.y=Z.size/1.75;break;case"middle":break;default:case null:case"alphabetic":case"ideographic":case"bottom":AF.y=-Z.size/2.25;break}switch(p){case"right":i=AQ;AP=0.05;break;case"center":i=AP=AQ/2;break}var AO=this.getCoords_(AI+AF.x,AH+AF.y);AE.push('<g_vml_:line from="',-i,' 0" to="',AP,' 0.05" ',' coordsize="100 100" coordorigin="0 0"',' filled="',!AG,'" stroked="',!!AG,'" style="position:absolute;width:1px;height:1px;">');if(AG){R(this,AE)}else{a(this,AE,{x:-i,y:0},{x:AP,y:Z.size})}var AL=AM[0][0].toFixed(3)+","+AM[1][0].toFixed(3)+","+AM[0][1].toFixed(3)+","+AM[1][1].toFixed(3)+",0,0";var AJ=K(AO.x/D)+","+K(AO.y/D);AE.push('<g_vml_:skew on="t" matrix="',AL,'" ',' offset="',AJ,'" origin="',i,' 0" />','<g_vml_:path textpathok="true" />','<g_vml_:textpath on="true" string="',AD(AK),'" style="v-text-align:',p,";font:",AD(j),'" /></g_vml_:line>');this.element_.insertAdjacentHTML("beforeEnd",AE.join(""))};M.fillText=function(j,Z,m,i){this.drawText_(j,Z,m,i,false)};M.strokeText=function(j,Z,m,i){this.drawText_(j,Z,m,i,true)};M.measureText=function(j){if(!this.textMeasureEl_){var Z='<span style="position:absolute;top:-20000px;left:0;padding:0;margin:0;border:none;white-space:pre;"></span>';this.element_.insertAdjacentHTML("beforeEnd",Z);this.textMeasureEl_=this.element_.lastChild}var i=this.element_.ownerDocument;this.textMeasureEl_.innerHTML="";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(i.createTextNode(j));return{width:this.textMeasureEl_.offsetWidth}};M.clip=function(){};M.arcTo=function(){};M.createPattern=function(i,Z){return new u(i,Z)};function v(Z){this.type_=Z;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}v.prototype.addColorStop=function(i,Z){Z=Y(Z);this.colors_.push({offset:i,color:Z.color,alpha:Z.alpha})};function u(i,Z){q(i);switch(Z){case"repeat":case null:case"":this.repetition_="repeat";break;case"repeat-x":case"repeat-y":case"no-repeat":this.repetition_=Z;break;default:n("SYNTAX_ERR")}this.src_=i.src;this.width_=i.width;this.height_=i.height}function n(Z){throw new o(Z)}function q(Z){if(!Z||Z.nodeType!=1||Z.tagName!="IMG"){n("TYPE_MISMATCH_ERR")}if(Z.readyState!="complete"){n("INVALID_STATE_ERR")}}function o(Z){this.code=this[Z];this.message=Z+": DOM Exception "+this.code}var x=o.prototype=new Error;x.INDEX_SIZE_ERR=1;x.DOMSTRING_SIZE_ERR=2;x.HIERARCHY_REQUEST_ERR=3;x.WRONG_DOCUMENT_ERR=4;x.INVALID_CHARACTER_ERR=5;x.NO_DATA_ALLOWED_ERR=6;x.NO_MODIFICATION_ALLOWED_ERR=7;x.NOT_FOUND_ERR=8;x.NOT_SUPPORTED_ERR=9;x.INUSE_ATTRIBUTE_ERR=10;x.INVALID_STATE_ERR=11;x.SYNTAX_ERR=12;x.INVALID_MODIFICATION_ERR=13;x.NAMESPACE_ERR=14;x.INVALID_ACCESS_ERR=15;x.VALIDATION_ERR=16;x.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=E;CanvasRenderingContext2D=W;CanvasGradient=v;CanvasPattern=u;DOMException=o})()};
\ No newline at end of file \ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment