blob: 0574813f2224b952fb9903bfdbed6aedf6785ede [file] [log] [blame]
caryclark3257c122015-11-16 13:36:08 -08001var canvas;
2var ctx;
3var canvasGradients = {};
4
5function canvas_rbga(color) {
6 var a = canvas_opacity(color);
7 var r = (color >> 16) & 0xFF;
8 var g = (color >> 8) & 0xFF;
9 var b = (color >> 0) & 0xFF;
10 return "rgba(" + r + "," + g + "," + b + "," + a + ")";
11}
12
13function canvas_opacity(color) {
14 var a = (color >> 24) & 0xFF;
15 return a / 255.;
16}
17
18function displayCanvas(displayList) {
19 if (displayList.clear) {
20 ctx.clearRect(0, 0, canvas.width, canvas.height);
21 }
22 for (var index = 0; index < displayList.length; ++index) {
23 drawToCanvas(displayList[index]);
24 }
25}
26
27function drawToCanvas(action) {
28 ctx.save();
29 var paint = paintToCanvas(action.paint);
30 var draw = action.draw;
31 if ('string' == typeof(draw)) {
32 draw = (new Function("return " + draw))();
33 }
34 if (isArray(draw)) {
35 assert(draw.length > 0);
36 var picture = 'draw' in draw[0];
37 if (picture) {
38 for (var index = 0; index < draw.length; ++index) {
39 drawToCanvas(draw[index]);
40 }
41 return;
42 }
43 ctx.beginPath();
44 for (var index = 0; index < draw.length; ++index) {
45 for (var prop in draw[index]) {
46 var v = draw[index][prop];
47 switch (prop) {
48 case 'arcTo':
49 ctx.arcTo(v[0], v[1], v[2], v[3], v[4]);
50 break;
51 case 'close':
52 ctx.closePath();
53 break;
54 case 'cubic':
55 ctx.moveTo(v[0], v[1]);
56 ctx.bezierCurveTo(v[2], v[3], v[4], v[5], v[6], v[7]);
57 break;
58 case 'line':
59 ctx.moveTo(v[0], v[1]);
60 ctx.lineTo(v[2], v[3]);
61 break;
62 case 'quad':
63 ctx.moveTo(v[0], v[1]);
64 ctx.quadraticCurveTo(v[2], v[3], v[4], v[5]);
65 break;
66 default:
67 assert(0);
68 }
69 }
70 }
71 if ('fill' == paint.style) {
72 ctx.fill();
73 } else {
74 assert('stroke' == paint.style);
75 ctx.stroke();
76 }
77 } else {
78 assert('string' in draw);
79 if ('fill' == paint.style) {
80 ctx.fillText(draw.string, draw.x, draw.y);
81 } else {
82 assert('stroke' == paint.style);
83 ctx.strokeText(draw.string, draw.x, draw.y);
84 }
85 }
86 ctx.restore();
87}
88
89function keyframeCanvasInit(displayList, first) {
90 if ('canvas' in first && 'clear' == first.canvas) {
91 displayList.clear = true;
92 }
93}
94
95function paintToCanvas(paint) {
96 var color;
97 var inPicture = 'string' == typeof(paint);
98 if (inPicture) {
99 paint = (new Function("return " + paint))();
100 assert('object' == typeof(paint) && !isArray(paint));
101 }
102 if ('gradient' in paint) {
103 var gradient = paint.gradient.split('.');
104 var gradName = gradient[1];
105 if (!canvasGradients[gradName]) {
106 var g = window[gradient[0]][gradient[1]];
107 var grad = ctx.createRadialGradient(g.cx, g.cy, 0, g.cx, g.cy, g.r);
108 var stopLen = g.stops.length;
109 for (var index = 0; index < stopLen; ++index) {
110 var stop = g.stops[index];
111 var color = canvas_rbga(stop.color);
112 grad.addColorStop(index, color);
113 }
114 canvasGradients[gradName] = grad;
115 }
116 color = canvasGradients[gradName];
117 if (!inPicture) {
118 ctx.globalAlpha = canvas_opacity(paint.color);
119 }
120 } else {
121 color = canvas_rbga(paint.color);
122 }
123 if ('fill' == paint.style) {
124 ctx.fillStyle = color;
125 } else if ('stroke' == paint.style) {
126 ctx.strokeStyle = color;
127 } else {
128 ctx.globalAlpha = canvas_opacity(paint.color);
129 }
130 if ('strokeWidth' in paint) {
131 ctx.lineWidth = paint.strokeWidth;
132 }
133 if ('typeface' in paint) {
134 var typeface = typefaces[paint.typeface];
135 var font = typeface.style;
136 if ('textSize' in paint) {
137 font += " " + paint.textSize;
138 }
139 if ('family' in typeface) {
140 font += " " + typeface.family;
141 }
142 ctx.font = font;
143 if ('textAlign' in paint) {
144 ctx.textAlign = paint.textAlign;
145 }
146 if ('textBaseline' in paint) {
147 ctx.textBaseline = paint.textBaseline;
148 }
149 }
150 return paint;
151}
152
153function setupCanvas() {
154 canvas = document.getElementById("canvas");
155 ctx = canvas ? canvas.getContext("2d") : null;
156 assert(ctx);
157 var resScale = window.devicePixelRatio ? window.devicePixelRatio : 1;
158 var unscaledWidth = canvas.width;
159 var unscaledHeight = canvas.height;
160 canvas.width = unscaledWidth * resScale;
161 canvas.height = unscaledHeight * resScale;
162 canvas.style.width = unscaledWidth + 'px';
163 canvas.style.height = unscaledHeight + 'px';
164 if (resScale != 1) {
165 ctx.scale(resScale, resScale);
166 }
167}