Skip to content

Commit 2e70984

Browse files
committed
Merge pull request mozilla#829 from jviereck/canvas_currentTransform
Implement ctx.mozCurrentTransform and ctx.mozCurrentTransformInverse shim
2 parents c9a7859 + 36e618c commit 2e70984

File tree

1 file changed

+114
-0
lines changed

1 file changed

+114
-0
lines changed

src/canvas.js

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,116 @@ function ScratchCanvas(width, height) {
5959
return canvas;
6060
}
6161

62+
function addContextCurrentTransform(ctx) {
63+
// If the context doesn't expose a `mozCurrentTransform`, add a JS based on.
64+
if (!ctx.mozCurrentTransform) {
65+
// Store the original context
66+
ctx._originalSave = ctx.save;
67+
ctx._originalRestore = ctx.restore;
68+
ctx._originalRotate = ctx.rotate;
69+
ctx._originalScale = ctx.scale;
70+
ctx._originalTranslate = ctx.translate;
71+
ctx._originalTransform = ctx.transform;
72+
73+
ctx._transformMatrix = [1, 0, 0, 1, 0, 0];
74+
ctx._transformStack = [];
75+
76+
Object.defineProperty(ctx, 'mozCurrentTransform', {
77+
get: function getCurrentTransform() {
78+
return this._transformMatrix;
79+
}
80+
});
81+
82+
Object.defineProperty(ctx, 'mozCurrentTransformInverse', {
83+
get: function getCurrentTransformInverse() {
84+
// Calculation done using WolframAlpha:
85+
// http://www.wolframalpha.com/input/?
86+
// i=Inverse+{{a%2C+c%2C+e}%2C+{b%2C+d%2C+f}%2C+{0%2C+0%2C+1}}
87+
88+
var m = this._transformMatrix;
89+
var a = m[0], b = m[1], c = m[2], d = m[3], e = m[4], f = m[5];
90+
91+
var ad_bc = a * d - b * c;
92+
var bc_ad = b * c - a * d;
93+
94+
return [
95+
d / ad_bc,
96+
b / bc_ad,
97+
c / bc_ad,
98+
a / ad_bc,
99+
(d * e - c * f) / bc_ad,
100+
(b * e - a * f) / ad_bc
101+
];
102+
}
103+
});
104+
105+
ctx.save = function ctxSave() {
106+
var old = this._transformMatrix;
107+
this._transformStack.push(old);
108+
this._transformMatrix = old.slice(0, 6);
109+
110+
this._originalSave();
111+
};
112+
113+
ctx.restore = function ctxRestore() {
114+
var prev = this._transformStack.pop();
115+
if (prev) {
116+
this._transformMatrix = prev;
117+
this._originalRestore();
118+
}
119+
};
120+
121+
ctx.translate = function ctxTranslate(x, y) {
122+
var m = this._transformMatrix;
123+
m[4] = m[0] * x + m[2] * y + m[4];
124+
m[5] = m[1] * x + m[3] * y + m[5];
125+
126+
this._originalTranslate(x, y);
127+
};
128+
129+
ctx.scale = function ctxScale(x, y) {
130+
var m = this._transformMatrix;
131+
m[0] = m[0] * x;
132+
m[1] = m[1] * x;
133+
m[2] = m[2] * y;
134+
m[3] = m[3] * y;
135+
136+
this._originalScale(x, y);
137+
};
138+
139+
ctx.transform = function ctxTransform(a, b, c, d, e, f) {
140+
var m = this._transformMatrix;
141+
this._transformMatrix = [
142+
m[0] * a + m[2] * b,
143+
m[1] * a + m[3] * b,
144+
m[0] * c + m[2] * d,
145+
m[1] * c + m[3] * d,
146+
m[0] * e + m[2] * f + m[4],
147+
m[1] * e + m[3] * f + m[5]
148+
];
149+
150+
ctx._originalTransform(a, b, c, d, e, f);
151+
};
152+
153+
ctx.rotate = function ctxRotate(angle) {
154+
var cosValue = Math.cos(angle);
155+
var sinValue = Math.sin(angle);
156+
157+
var m = this._transformMatrix;
158+
this._transformMatrix = [
159+
m[0] * cosValue + m[2] * sinValue,
160+
m[1] * cosValue + m[3] * sinValue,
161+
m[0] * (-sinValue) + m[2] * cosValue,
162+
m[1] * (-sinValue) + m[3] * cosValue,
163+
m[4],
164+
m[5]
165+
];
166+
167+
this._originalRotate(angle);
168+
};
169+
}
170+
}
171+
62172
var CanvasGraphics = (function canvasGraphics() {
63173
// Defines the time the executeIRQueue is going to be executing
64174
// before it stops and shedules a continue of execution.
@@ -73,6 +183,10 @@ var CanvasGraphics = (function canvasGraphics() {
73183
this.xobjs = null;
74184
this.ScratchCanvas = ScratchCanvas;
75185
this.objs = objs;
186+
187+
if (canvasCtx) {
188+
addContextCurrentTransform(canvasCtx);
189+
}
76190
}
77191

78192
var LINE_CAP_STYLES = ['butt', 'round', 'square'];

0 commit comments

Comments
 (0)