underover-parameters-3.html (22207B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="utf-8"> 5 <title>Underscripts and Overscripts parameters</title> 6 <link rel="help" href="https://w3c.github.io/mathml-core/#underscripts-and-overscripts-munder-mover-munderover"> 7 <meta name="assert" content="Elements munder, mover, munderover correctly use underbar/overbar and AccentBaseHeight parameters from the MATH table."> 8 <script src="/resources/testharness.js"></script> 9 <script src="/resources/testharnessreport.js"></script> 10 <script src="/mathml/support/feature-detection.js"></script> 11 <script src="/mathml/support/fonts.js"></script> 12 <style> 13 math, mspace, mo { 14 font-size: 10px; 15 } 16 @font-face { 17 font-family: accentbaseheight4000underbarextradescender5000; 18 src: url("/fonts/math/underover-accentbaseheight4000-underbarextradescender5000.woff"); 19 } 20 @font-face { 21 font-family: accentbaseheight4000underbarverticalgap7000; 22 src: url("/fonts/math/underover-accentbaseheight4000-underbarverticalgap7000.woff"); 23 } 24 @font-face { 25 font-family: accentbaseheight4000overbarextraascender3000; 26 src: url("/fonts/math/underover-accentbaseheight4000-overbarextraascender3000.woff"); 27 } 28 @font-face { 29 font-family: accentbaseheight4000overbarverticalgap11000; 30 src: url("/fonts/math/underover-accentbaseheight4000-overbarverticalgap11000.woff"); 31 } 32 </style> 33 <script> 34 var emToPx = 10 / 1000; // font-size: 10px, font.em = 1000 35 var epsilon = 2; 36 var axisBaseHeight = 4000 * emToPx; 37 var shortBaseHeight = 3000 * emToPx; // shortBaseHeight < axisBaseHeight 38 var tallBaseHeight = 5000 * emToPx; // tallBaseHeight > axisBaseHeight 39 40 function getBox(aId) { 41 return document.getElementById(aId).getBoundingClientRect(); 42 } 43 44 setup({ explicit_done: true }); 45 window.addEventListener("load", () => { loadAllFonts().then(runTests); }); 46 47 function getBooleanValue(element, name) { 48 return (element.getAttribute(name) || "").toLowerCase() === "true"; 49 } 50 let dynamicBooleanAttributeChanges = { 51 "Invert boolean value using absent attribute": function(element, name) { 52 if (getBooleanValue(element, name)) { 53 element.removeAttribute(name); 54 } else { 55 element.setAttribute(name, "true"); 56 } 57 }, 58 59 "Invert boolean value using invalid attribute": function(element, name) { 60 if (getBooleanValue(element, name)) { 61 element.setAttribute(name, "invalid"); 62 } else { 63 element.setAttribute(name, "true"); 64 } 65 }, 66 67 "Change case of boolean attribute": function(element, name) { 68 if (getBooleanValue(element, name)) { 69 element.setAttribute(name, "TrUe"); 70 } else { 71 element.setAttribute(name, "FaLsE"); 72 } 73 } 74 }; 75 76 function runTests() { 77 test(function() { 78 assert_true(MathMLFeatureDetection.has_mspace()); 79 80 for (var i = 1; i <= 4; i++) { 81 for (var j = 1; j <= 6; j++) { 82 var baseId = ("base00" + i) + j; 83 assert_approx_equals(getBox("ref00" + i).bottom, 84 getBox(baseId).bottom, 85 epsilon, 86 "alignment of " + baseId); 87 } 88 } 89 }, "Baseline alignment"); 90 91 test(function() { 92 assert_true(MathMLFeatureDetection.has_mspace()); 93 94 for (var i = 1; i <= 4; i++) { 95 for (var j = 1; j <= 6; j++) { 96 var baseId = ("base00" + i) + j; 97 assert_approx_equals(getBox(baseId).height, 98 j == 2 || j == 5 ? 99 tallBaseHeight :shortBaseHeight, 100 epsilon, 101 "height of " + baseId); 102 } 103 } 104 }, "Heights of bases"); 105 106 test(function() { 107 assert_true(MathMLFeatureDetection.has_mspace()); 108 109 var v = 5000 * emToPx; 110 assert_approx_equals(getBox("ref001").bottom - getBox("over0014").bottom, 111 shortBaseHeight, epsilon, 112 "munderover: nonaccent over short base"); 113 assert_approx_equals(getBox("ref001").bottom - getBox("over0015").bottom, 114 tallBaseHeight, epsilon, 115 "munderover: accent over tall base"); 116 assert_approx_equals(getBox("ref001").bottom - getBox("over0016").bottom, 117 axisBaseHeight, epsilon, 118 "munderover: accent over short base"); 119 for (var j = 1; j <= 6; j++) { 120 var elId = "el001" + j; 121 var baseId = "base001" + j; 122 var underId = "under001" + j; 123 assert_approx_equals(getBox(underId).top - getBox(baseId).bottom, 124 0, epsilon, 125 "gap between " + baseId + " and " + underId); 126 assert_approx_equals(getBox(elId).bottom - getBox(underId).bottom, 127 v, epsilon, 128 "extra descender below " + underId); 129 } 130 }, "AccentBaseHeight, UnderbarExtraDescender"); 131 132 test(function() { 133 assert_true(MathMLFeatureDetection.has_mspace()); 134 135 var v = 7000 * emToPx; 136 assert_approx_equals(getBox("ref002").bottom - getBox("over0024").bottom, 137 shortBaseHeight, epsilon, 138 "munderover: nonaccent over short base"); 139 assert_approx_equals(getBox("ref002").bottom - getBox("over0025").bottom, 140 tallBaseHeight, epsilon, 141 "munderover: accent over tall base"); 142 assert_approx_equals(getBox("ref002").bottom - getBox("over0026").bottom, 143 axisBaseHeight, epsilon, 144 "munderover: accent over short base"); 145 for (var j = 1; j <= 6; j++) { 146 var elId = "el002" + j; 147 var baseId = "base002" + j; 148 var underId = "under002" + j; 149 var gap = (j == 2 || j == 3 ? 0 : v); 150 assert_approx_equals(getBox(underId).top - getBox(baseId).bottom, 151 gap, epsilon, 152 "gap between " + baseId + " and " + underId); 153 } 154 }, "AccentBaseHeight, UnderbarVerticalGap"); 155 156 test(function() { 157 assert_true(MathMLFeatureDetection.has_mspace()); 158 159 var v = 3000 * emToPx; 160 assert_approx_equals(getBox("ref003").bottom - getBox("over0031").bottom, 161 shortBaseHeight, epsilon, 162 "mover: nonaccent over short base"); 163 assert_approx_equals(getBox("ref003").bottom - getBox("over0032").bottom, 164 tallBaseHeight, epsilon, 165 "mover: accent over tall base"); 166 assert_approx_equals(getBox("ref003").bottom - getBox("over0033").bottom, 167 axisBaseHeight, epsilon, 168 "mover: accent over short base"); 169 assert_approx_equals(getBox("ref003").bottom - getBox("over0034").bottom, 170 shortBaseHeight, epsilon, 171 "munderover: nonaccent over short base"); 172 assert_approx_equals(getBox("ref003").bottom - getBox("over0035").bottom, 173 tallBaseHeight, epsilon, 174 "munderover: accent over tall base"); 175 assert_approx_equals(getBox("ref003").bottom - getBox("over0036").bottom, 176 axisBaseHeight, epsilon, 177 "munderover: accent over short base"); 178 for (var j = 1; j <= 6; j++) { 179 var elId = "el003" + j; 180 var baseId = "base003" + j; 181 if (j >= 4) { 182 var underId = "under003" + j; 183 assert_approx_equals(getBox(underId).top - getBox(baseId).bottom, 184 0, epsilon, 185 "gap between " + baseId + " and " + underId); 186 } 187 var overId = "over003" + j; 188 assert_approx_equals(getBox(overId).top - getBox(elId).top, 189 v, epsilon, 190 "extra ascender below " + overId); 191 } 192 }, "AccentBaseHeight, OverbarExtraAscender"); 193 194 test(function() { 195 assert_true(MathMLFeatureDetection.has_mspace()); 196 197 v = 11000 * emToPx; 198 assert_approx_equals(getBox("ref004").bottom - getBox("over0041").bottom, 199 shortBaseHeight + v, epsilon, 200 "mover: nonaccent over short base"); 201 assert_approx_equals(getBox("ref004").bottom - getBox("over0042").bottom, 202 tallBaseHeight, epsilon, 203 "mover: accent over tall base"); 204 assert_approx_equals(getBox("ref004").bottom - getBox("over0043").bottom, 205 axisBaseHeight, epsilon, 206 "mover: accent over short base"); 207 assert_approx_equals(getBox("ref004").bottom - getBox("over0044").bottom, 208 shortBaseHeight + v, epsilon, 209 "munderover: nonaccent over short base"); 210 assert_approx_equals(getBox("ref004").bottom - getBox("over0045").bottom, 211 tallBaseHeight, epsilon, 212 "munderover: accent over tall base"); 213 assert_approx_equals(getBox("ref004").bottom - getBox("over0046").bottom, 214 axisBaseHeight, epsilon, 215 "munderover: accent over short base"); 216 for (var j = 4; j <= 6; j++) { 217 var baseId = "base004" + j; 218 var underId = "under004" + j; 219 assert_approx_equals(getBox(underId).top - getBox(baseId).bottom, 220 0, epsilon, 221 "gap between " + baseId + " and " + underId); 222 } 223 }, "AccentBaseHeight, OverbarVerticalGap"); 224 225 test(function() { 226 assert_true(MathMLFeatureDetection.has_mspace()); 227 var v = 7000 * emToPx; 228 229 for (var j = 1; j <= 4; j++) { 230 var elId = `el005${j}`; 231 var baseId = `base005${j}`; 232 var underId = `under005${j}`; 233 234 for (name in dynamicBooleanAttributeChanges) { 235 let element = document.getElementById(elId); 236 dynamicBooleanAttributeChanges[name](element, "accentunder"); 237 var value = getBooleanValue(element, "accentunder"); 238 var gap = value ? 0 : v; 239 assert_approx_equals(getBox(underId).top - getBox(baseId).bottom, 240 gap, epsilon, 241 `${elId}: gap between base and underscript ; ${name}`); 242 }; 243 } 244 }, "Dynamic change of accentunder attribute"); 245 246 test(function() { 247 assert_true(MathMLFeatureDetection.has_mspace()); 248 v = 11000 * emToPx; 249 for (var j = 1; j <= 4; j++) { 250 var elId = `el006${j}`; 251 var refId = `base006${j}`; 252 var overId = `over006${j}`; 253 for (name in dynamicBooleanAttributeChanges) { 254 let element = document.getElementById(elId); 255 dynamicBooleanAttributeChanges[name](element, "accent"); 256 var value = getBooleanValue(element, "accent"); 257 assert_approx_equals(getBox(refId).bottom - getBox(overId).bottom, 258 value ? axisBaseHeight : shortBaseHeight + v, 259 epsilon, 260 `${elId}: accent=${value} ; short base ; ${name}`); 261 } 262 } 263 }, "Dynamic change of accent attribute"); 264 265 done(); 266 } 267 </script> 268 </head> 269 <body> 270 <div id="log"></div> 271 <p> 272 <math style="font-family: accentbaseheight4000underbarextradescender5000;"> 273 <mspace id="ref001" height="1em" width="3em" style="background: green"/> 274 <munder style="background: cyan" id="el0011"> 275 <mspace id="base0011" height="3em" width="1em" style="background: black"/> 276 <mspace id="under0011" height="1em" width="3em" style="background: blue"/> 277 </munder> 278 <munder style="background: cyan" id="el0012" accentunder="true"> 279 <mspace id="base0012" height="5em" width="1em" style="background: black"/> 280 <mspace id="under0012" height="1em" width="3em" style="background: blue"/> 281 </munder> 282 <munder style="background: cyan" id="el0013" accentunder="true"> 283 <mspace id="base0013" height="3em" width="1em" style="background: black"/> 284 <mspace id="under0013" height="1em" width="3em" style="background: blue"/> 285 </munder> 286 <munderover style="background: cyan" id="el0014"> 287 <mspace id="base0014" height="3em" width="1em" style="background: black"/> 288 <mspace id="under0014" height="1em" width="3em" style="background: blue"/> 289 <mspace id="over0014" height="1em" width="3em" style="background: red"/> 290 </munderover> 291 <munderover style="background: cyan" id="el0015" accent="true"> 292 <mspace id="base0015" height="5em" width="1em" style="background: black"/> 293 <mspace id="under0015" height="1em" width="3em" style="background: blue"/> 294 <mspace id="over0015" height="1em" width="3em" style="background: red"/> 295 </munderover> 296 <munderover style="background: cyan" id="el0016" accent="true"> 297 <mspace id="base0016" height="3em" width="1em" style="background: black"/> 298 <mspace id="under0016" height="1em" width="3em" style="background: blue"/> 299 <mspace id="over0016" height="1em" width="3em" style="background: red"/> 300 </munderover> 301 </math> 302 </p> 303 <hr/> 304 <p> 305 <math style="font-family: accentbaseheight4000underbarverticalgap7000;"> 306 <mspace id="ref002" height="1em" width="3em" style="background: green"/> 307 <munder style="background: cyan" id="el0021"> 308 <mspace id="base0021" height="3em" width="1em" style="background: black"/> 309 <mspace id="under0021" height="1em" width="3em" style="background: blue"/> 310 </munder> 311 <munder style="background: cyan" id="el0022" accentunder="true"> 312 <mspace id="base0022" height="5em" width="1em" style="background: black"/> 313 <mspace id="under0022" height="1em" width="3em" style="background: blue"/> 314 </munder> 315 <munder style="background: cyan" id="el0023" accentunder="true"> 316 <mspace id="base0023" height="3em" width="1em" style="background: black"/> 317 <mspace id="under0023" height="1em" width="3em" style="background: blue"/> 318 </munder> 319 <munderover style="background: cyan" id="el0024"> 320 <mspace id="base0024" height="3em" width="1em" style="background: black"/> 321 <mspace id="under0024" height="1em" width="3em" style="background: blue"/> 322 <mspace id="over0024" height="1em" width="3em" style="background: red"/> 323 </munderover> 324 <munderover style="background: cyan" id="el0025" accent="true"> 325 <mspace id="base0025" height="5em" width="1em" style="background: black"/> 326 <mspace id="under0025" height="1em" width="3em" style="background: blue"/> 327 <mspace id="over0025" height="1em" width="3em" style="background: red"/> 328 </munderover> 329 <munderover style="background: cyan" id="el0026" accent="true"> 330 <mspace id="base0026" height="3em" width="1em" style="background: black"/> 331 <mspace id="under0026" height="1em" width="3em" style="background: blue"/> 332 <mspace id="over0026" height="1em" width="3em" style="background: red"/> 333 </munderover> 334 </math> 335 </p> 336 <hr/> 337 <p> 338 <math style="font-family: accentbaseheight4000overbarextraascender3000;"> 339 <mspace id="ref003" height="1em" width="3em" style="background: green"/> 340 <mover style="background: cyan" id="el0031"> 341 <mspace id="base0031" height="3em" width="1em" style="background: black"/> 342 <mspace id="over0031" height="1em" width="3em" style="background: red"/> 343 </mover> 344 <mover style="background: cyan" id="el0032" accent="true"> 345 <mspace id="base0032" height="5em" width="1em" style="background: black"/> 346 <mspace id="over0032" height="1em" width="3em" style="background: red"/> 347 </mover> 348 <mover style="background: cyan" id="el0033" accent="true"> 349 <mspace id="base0033" height="3em" width="1em" style="background: black"/> 350 <mspace id="over0033" height="1em" width="3em" style="background: red"/> 351 </mover> 352 <munderover style="background: cyan" id="el0034"> 353 <mspace id="base0034" height="3em" width="1em" style="background: black"/> 354 <mspace id="under0034" height="1em" width="3em" style="background: blue"/> 355 <mspace id="over0034" height="1em" width="3em" style="background: red"/> 356 </munderover> 357 <munderover style="background: cyan" id="el0035" accent="true"> 358 <mspace id="base0035" height="5em" width="1em" style="background: black"/> 359 <mspace id="under0035" height="1em" width="3em" style="background: blue"/> 360 <mspace id="over0035" height="1em" width="3em" style="background: red"/> 361 </munderover> 362 <munderover style="background: cyan" id="el0036" accent="true"> 363 <mspace id="base0036" height="3em" width="1em" style="background: black"/> 364 <mspace id="under0036" height="1em" width="3em" style="background: blue"/> 365 <mspace id="over0036" height="1em" width="3em" style="background: red"/> 366 </munderover> 367 </math> 368 </p> 369 <hr/> 370 <p> 371 <math style="font-family: accentbaseheight4000overbarverticalgap11000;"> 372 <mspace id="ref004" height="1em" width="3em" style="background: green"/> 373 <mover style="background: cyan" id="el0041"> 374 <mspace id="base0041" height="3em" width="1em" style="background: black"/> 375 <mspace id="over0041" height="1em" width="3em" style="background: red"/> 376 </mover> 377 <mover style="background: cyan" id="el0042" accent="true"> 378 <mspace id="base0042" height="5em" width="1em" style="background: black"/> 379 <mspace id="over0042" height="1em" width="3em" style="background: red"/> 380 </mover> 381 <mover style="background: cyan" id="el0043" accent="true"> 382 <mspace id="base0043" height="3em" width="1em" style="background: black"/> 383 <mspace id="over0043" height="1em" width="3em" style="background: red"/> 384 </mover> 385 <munderover style="background: cyan" id="el0044"> 386 <mspace id="base0044" height="3em" width="1em" style="background: black"/> 387 <mspace id="under0044" height="1em" width="3em" style="background: blue"/> 388 <mspace id="over0044" height="1em" width="3em" style="background: red"/> 389 </munderover> 390 <munderover style="background: cyan" id="el0045" accent="true"> 391 <mspace id="base0045" height="5em" width="1em" style="background: black"/> 392 <mspace id="under0045" height="1em" width="3em" style="background: blue"/> 393 <mspace id="over0045" height="1em" width="3em" style="background: red"/> 394 </munderover> 395 <munderover style="background: cyan" id="el0046" accent="true"> 396 <mspace id="base0046" height="3em" width="1em" style="background: black"/> 397 <mspace id="under0046" height="1em" width="3em" style="background: blue"/> 398 <mspace id="over0046" height="1em" width="3em" style="background: red"/> 399 </munderover> 400 </math> 401 </p> 402 <hr/> 403 <p> 404 <math style="font-family: accentbaseheight4000underbarverticalgap7000;"> 405 <mspace id="ref005" height="1em" width="3em" style="background: green"/> 406 <munder style="background: cyan" id="el0051"> 407 <mspace id="base0051" height="5em" width="1em" style="background: black"/> 408 <mspace id="under0051" height="1em" width="3em" style="background: blue"/> 409 </munder> 410 <munder style="background: cyan" id="el0052" accentunder="true"> 411 <mspace id="base0052" height="5em" width="1em" style="background: black"/> 412 <mspace id="under0052" height="1em" width="3em" style="background: blue"/> 413 </munder> 414 <munderover style="background: cyan" id="el0053"> 415 <mspace id="base0053" height="5em" width="1em" style="background: black"/> 416 <mspace id="under0053" height="1em" width="3em" style="background: blue"/> 417 <mspace id="over0053" height="1em" width="3em" style="background: red"/> 418 </munderover> 419 <munderover style="background: cyan" id="el0054" accentunder="true"> 420 <mspace id="base0054" height="5em" width="1em" style="background: black"/> 421 <mspace id="under0054" height="1em" width="3em" style="background: blue"/> 422 <mspace id="over0054" height="1em" width="3em" style="background: red"/> 423 </munderover> 424 </math> 425 </p> 426 <hr/> 427 <p> 428 <math style="font-family: accentbaseheight4000overbarverticalgap11000;"> 429 <mspace id="ref006" height="1em" width="3em" style="background: green"/> 430 <mover style="background: cyan" id="el0061"> 431 <mspace id="base0061" height="3em" width="1em" style="background: black"/> 432 <mspace id="over0061" height="1em" width="3em" style="background: red"/> 433 </mover> 434 <mover style="background: cyan" id="el0062" accent="true"> 435 <mspace id="base0062" height="3em" width="1em" style="background: black"/> 436 <mspace id="over0062" height="1em" width="3em" style="background: red"/> 437 </mover> 438 <munderover style="background: cyan" id="el0063"> 439 <mspace id="base0063" height="3em" width="1em" style="background: black"/> 440 <mspace id="under0063" height="1em" width="3em" style="background: blue"/> 441 <mspace id="over0063" height="1em" width="3em" style="background: red"/> 442 </munderover> 443 <munderover style="background: cyan" id="el0064" accent="true"> 444 <mspace id="base0064" height="3em" width="1em" style="background: black"/> 445 <mspace id="under0064" height="1em" width="3em" style="background: blue"/> 446 <mspace id="over0064" height="1em" width="3em" style="background: red"/> 447 </munderover> 448 </math> 449 </p> 450 451 </body> 452 </html>