return canvas;
}
+function addCtxCurrentTransform(ctx) {
+ // If the context doesn't expose a `mozCurrentTransform`, add a JS based on.
+ if (!ctx.mozCurrentTransform) {
+ // Store the original context
+ ctx._originalSave = ctx.save;
+ ctx._originalRestore = ctx.restore;
+ ctx._originalRotate = ctx.rotate;
+ ctx._originalScale = ctx.scale;
+ ctx._originalTranslate = ctx.translate;
+ ctx._originalTransform = ctx.transform;
+
+ ctx._transformMatrix = [1, 0, 0, 1, 0, 0];
+ ctx._transformStack = [];
+
+ ctx.__defineGetter__('mozCurrentTransform', function getCurrentTransform() {
+ return this._transformMatrix;
+ });
+
+ ctx.__defineGetter__('mozCurrentTransformInverse',
+ function getCurrentTransformInverse() {
+ // Calculation done using WolframAlpha:
+ // http://www.wolframalpha.com/input/?
+ // i=Inverse+{{a%2C+c%2C+e}%2C+{b%2C+d%2C+f}%2C+{0%2C+0%2C+1}}
+
+ var m = this._transformMatrix;
+ var a = m[0], b = m[1], c = m[2], d = m[3], e = m[4], f = m[5];
+
+ return [
+ d / (a * d - b * c),
+ b / (b * c - a * d),
+ c / (b * c - a * d),
+ a / (a * d - b * c),
+ (d * e - c * f) / (b * c - a * d),
+ (b * e - a * f) / (a * d - b * c)
+ ];
+ }
+ );
+
+ ctx.save = function ctxSave() {
+ var old = this._transformMatrix;
+ this._transformStack.push(old);
+ this._transformMatrix = old.slice(0, 6);
+
+ this._originalSave();
+ };
+
+ ctx.restore = function ctxRestore() {
+ var prev = this._transformStack.pop();
+ if (prev) {
+ this._transformMatrix = prev;
+ this._originalRestore();
+ }
+ }
+
+ ctx.translate = function ctxTranslate(x, y) {
+ var m = this._transformMatrix;
+ m[4] = m[0] * x + m[2] * y + m[4];
+ m[5] = m[1] * x + m[3] * y + m[5];
+
+ this._originalTranslate(x, y);
+ }
+
+ ctx.scale = function ctxScale(x, y) {
+ var m = this._transformMatrix;
+ m[0] = m[0] * x;
+ m[1] = m[1] * x;
+ m[2] = m[2] * y;
+ m[3] = m[3] * y;
+
+ this._originalScale(x, y);
+ }
+
+ ctx.transform = function ctxTransform(a, b, c, d, e, f) {
+ var m = this._transformMatrix;
+ this._transformMatrix = [
+ m[0] * a + m[2] * b,
+ m[1] * a + m[3] * b,
+ m[0] * c + m[2] * d,
+ m[1] * c + m[3] * d,
+ m[0] * e + m[2] * f + m[4],
+ m[1] * e + m[3] * f + m[5]
+ ];
+
+ ctx._originalTransform(a, b, c, d, e, f);
+ }
+
+ ctx.rotate = function ctxRotate(angle) {
+ var cosValue = Math.cos(angle);
+ var sinValue = Math.sin(angle);
+
+ var m = this._transformMatrix;
+ this._transformMatrix = [
+ m[0] * cosValue + m[2] * sinValue,
+ m[1] * cosValue + m[3] * sinValue,
+ m[0] * (-sinValue) + m[2] * cosValue,
+ m[1] * (-sinValue) + m[3] * cosValue,
+ m[4],
+ m[5]
+ ];
+
+ this._originalRotate(angle);
+ }
+ }
+}
+
var CanvasGraphics = (function canvasGraphics() {
// Defines the time the executeIRQueue is going to be executing
// before it stops and shedules a continue of execution.
this.xobjs = null;
this.ScratchCanvas = ScratchCanvas;
this.objs = objs;
+
+ if (canvasCtx) {
+ addCtxCurrentTransform(canvasCtx);
+ }
}
var LINE_CAP_STYLES = ['butt', 'round', 'square'];