the-canvas-state.yaml (4720B)
1 - name: 2d.state.saverestore.transformation 2 desc: save()/restore() affects the current transformation matrix 3 code: | 4 ctx.fillStyle = '#0f0'; 5 ctx.fillRect(0, 0, 100, 50); 6 ctx.save(); 7 ctx.translate(200, 0); 8 ctx.restore(); 9 ctx.fillStyle = '#f00'; 10 ctx.fillRect(-200, 0, 100, 50); 11 @assert pixel 50,25 == 0,255,0,255; 12 expected: green 13 14 - name: 2d.state.saverestore.clip 15 desc: save()/restore() affects the clipping path 16 code: | 17 ctx.fillStyle = '#f00'; 18 ctx.fillRect(0, 0, 100, 50); 19 ctx.save(); 20 ctx.rect(0, 0, 1, 1); 21 ctx.clip(); 22 ctx.restore(); 23 ctx.fillStyle = '#0f0'; 24 ctx.fillRect(0, 0, 100, 50); 25 @assert pixel 50,25 == 0,255,0,255; 26 expected: green 27 28 - name: 2d.state.saverestore.clip.2 29 desc: save()/restore() affects the clipping path 30 code: | 31 ctx.fillStyle = '#f00'; 32 ctx.fillRect(0, 0, 100, 50); 33 ctx.save(); 34 ctx.rect(0, 0, 1, 1); 35 ctx.clip(); 36 ctx.clip(); 37 ctx.restore(); 38 ctx.fillStyle = '#0f0'; 39 ctx.fillRect(0, 0, 100, 50); 40 @assert pixel 50,25 == 0,255,0,255; 41 expected: green 42 43 - name: 2d.state.saverestore.path 44 desc: save()/restore() does not affect the current path 45 code: | 46 ctx.fillStyle = '#f00'; 47 ctx.fillRect(0, 0, 100, 50); 48 ctx.save(); 49 ctx.rect(0, 0, 100, 50); 50 ctx.restore(); 51 ctx.fillStyle = '#0f0'; 52 ctx.fill(); 53 @assert pixel 50,25 == 0,255,0,255; 54 expected: green 55 56 - name: 2d.state.saverestore.bitmap 57 desc: save()/restore() does not affect the current bitmap 58 code: | 59 ctx.fillStyle = '#f00'; 60 ctx.fillRect(0, 0, 100, 50); 61 ctx.save(); 62 ctx.fillStyle = '#0f0'; 63 ctx.fillRect(0, 0, 100, 50); 64 ctx.restore(); 65 @assert pixel 50,25 == 0,255,0,255; 66 expected: green 67 68 - name: 2d.state.saverestore.stack 69 desc: save()/restore() can be nested as a stack 70 code: | 71 ctx.lineWidth = 1; 72 ctx.save(); 73 ctx.lineWidth = 2; 74 ctx.save(); 75 ctx.lineWidth = 3; 76 @assert ctx.lineWidth === 3; 77 ctx.restore(); 78 @assert ctx.lineWidth === 2; 79 ctx.restore(); 80 @assert ctx.lineWidth === 1; 81 82 - name: 2d.state.saverestore.stackdepth 83 desc: save()/restore() stack depth is not unreasonably limited 84 code: | 85 var limit = 512; 86 for (var i = 1; i < limit; ++i) 87 { 88 ctx.save(); 89 ctx.lineWidth = i; 90 } 91 for (var i = limit-1; i > 0; --i) 92 { 93 @assert ctx.lineWidth === i; 94 ctx.restore(); 95 } 96 97 - name: 2d.state.saverestore.underflow 98 desc: restore() with an empty stack has no effect 99 code: | 100 for (var i = 0; i < 16; ++i) 101 ctx.restore(); 102 ctx.lineWidth = 0.5; 103 ctx.restore(); 104 @assert ctx.lineWidth === 0.5; 105 106 - name: 2d.state.saverestore 107 variants_layout: [single_file, single_file, multi_files] 108 variants: 109 - restore-undoes-changes: 110 desc: save()/restore() restores {{ variant_names[2] }}, for a canvas of 111 size {{ size }}. 112 code: | 113 const old = ctx.{{ variant_names[2] }}; 114 ctx.save(); 115 ctx.{{ variant_names[2] }} = {{ value }}; 116 ctx.restore(); 117 @assert ctx.{{ variant_names[2] }} === old; 118 save-does-not-modify-values: 119 desc: save() does not modify {{ variant_names[2] }}, for a canvas of size 120 {{ size }}. 121 code: | 122 ctx.{{ variant_names[2] }} = {{ value }}; 123 const old = ctx.{{ variant_names[2] }}; 124 // We're not interested in failures caused by get(set(x)) != x (e.g. 125 // from rounding), so compare against `old` instead of {{ value }}. 126 ctx.save(); 127 @assert ctx.{{ variant_names[2] }} === old; 128 ctx.restore(); 129 - non-zero-size: 130 size: [300, 150] 131 zero-size: 132 size: [0, 0] 133 - &2d_state_test_cases 134 strokeStyle: 135 value: '"#ff0000"' 136 fillStyle: 137 value: '"#ff0000"' 138 globalAlpha: 139 value: 0.5 140 lineWidth: 141 value: 0.5 142 lineCap: 143 value: '"round"' 144 lineJoin: 145 value: '"round"' 146 miterLimit: 147 value: 0.5 148 shadowOffsetX: 149 value: 5 150 shadowOffsetY: 151 value: 5 152 shadowBlur: 153 value: 5 154 shadowColor: 155 value: '"#ff0000"' 156 globalCompositeOperation: 157 value: '"copy"' 158 font: 159 canvas_types: ['HtmlCanvas'] 160 value: '"25px serif"' 161 textAlign: 162 canvas_types: ['HtmlCanvas'] 163 value: '"center"' 164 textBaseline: 165 canvas_types: ['HtmlCanvas'] 166 value: '"bottom"' 167 168 - name: 2d.canvas.host.initial.reset.2dstate 169 desc: Resetting the canvas state resets {{ variant_name }} 170 code: | 171 const default_val = ctx.{{ variant_name }}; 172 ctx.{{ variant_name }} = {{ value }}; 173 canvas.width = 100; 174 @assert ctx.{{ variant_name }} === default_val; 175 variants_layout: [single_file] 176 variants: 177 - *2d_state_test_cases