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