Changeset 252747 in webkit
- Timestamp:
- Nov 21, 2019 1:11:07 PM (4 years ago)
- Location:
- trunk
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/LayoutTests/ChangeLog
r252744 r252747 1 2019-11-21 Nikita Vasilyev <nvasilyev@apple.com> 2 3 Web Inspector: Outline sRGB-safe areas on P3 color picker 4 https://bugs.webkit.org/show_bug.cgi?id=203533 5 <rdar://problem/56688057> 6 7 Reviewed by Brian Burg. 8 9 Test WI.Color.displayP3toSRGB. 10 11 LayoutTests: 12 * inspector/model/color-expected.txt: 13 * inspector/model/color.html: 14 1 15 2019-11-21 Kate Cheney <katherine_cheney@apple.com> 2 16 -
trunk/LayoutTests/inspector/model/color-expected.txt
r252168 r252747 519 519 PASS: Should convert [-1,0,0] to [0,0,0]. 520 520 521 -- Running test case: WI.Color.displayP3toSRGB 522 PASS: Should convert [0,0,0] to [0,0,0]. 523 PASS: Should convert [1,1,1] to [0.9999300658875597,1.0000101408119602,1.0001054916006267]. 524 PASS: Should convert [1,0,0] to [1.0929902391315327,-0.5433883521407902,-0.2537782522695441]. 525 PASS: Should convert [0,1,0] to [-2.9057643199691516,1.0182759798644396,-1.0162215225472337]. 526 PASS: Should convert [0,0,1] to [2.3902361583783006e-7,-2.0487738563140788e-7,1.0421313171983129]. 527 PASS: Should convert [2,0,0] to [1.0929902391315327,-0.5433883521407902,-0.2537782522695441]. 528 PASS: Should convert [-1,0,0] to [0,0,0]. 529 -
trunk/LayoutTests/inspector/model/color.html
r252168 r252747 613 613 }); 614 614 615 suite.addTestCase({ 616 name: "WI.Color.displayP3toSRGB", 617 description: "Test conversion from display-P3 gamut to sRGB.", 618 test() { 619 testColorConversion(WI.Color.displayP3toSRGB, [0, 0, 0], [0, 0, 0]); 620 testColorConversion(WI.Color.displayP3toSRGB, [1, 1, 1], [0.9999300658875597, 1.0000101408119602, 1.0001054916006267]); 621 testColorConversion(WI.Color.displayP3toSRGB, [1, 0, 0], [1.0929902391315327, -0.5433883521407902, -0.2537782522695441]); 622 testColorConversion(WI.Color.displayP3toSRGB, [0, 1, 0], [-2.9057643199691516, 1.0182759798644396, -1.0162215225472337]); 623 testColorConversion(WI.Color.displayP3toSRGB, [0, 0, 1], [2.3902361583783006e-7, -2.0487738563140788e-7, 1.0421313171983129]); 624 625 // Out-of-bounds inputs. 626 testColorConversion(WI.Color.displayP3toSRGB, [2, 0, 0], [1.0929902391315327, -0.5433883521407902, -0.2537782522695441]); 627 testColorConversion(WI.Color.displayP3toSRGB, [-1, 0, 0], [0, 0, 0]); 628 629 return true; 630 } 631 }); 632 615 633 suite.runTestCasesAndFinish(); 616 634 } -
trunk/Source/WebInspectorUI/ChangeLog
r252745 r252747 1 2019-11-21 Nikita Vasilyev <nvasilyev@apple.com> 2 3 Web Inspector: Outline sRGB-safe areas on P3 color picker 4 https://bugs.webkit.org/show_bug.cgi?id=203533 5 <rdar://problem/56688057> 6 7 Reviewed by Brian Burg. 8 9 Visualize the edge of sRGB gamut as a white line. 10 11 * Localizations/en.lproj/localizedStrings.js: 12 13 * UserInterface/Models/Color.js: 14 (WI.Color.displayP3toSRGB.multiplyMatrixByVector): 15 (WI.Color.displayP3toSRGB): 16 (WI.Color._toLinearLight): 17 (WI.Color._gammaCorrect): 18 Use equations from CSS Color Module Level 4. 19 20 * UserInterface/Views/ColorSquare.css: 21 (.color-square): 22 (.color-square > .crosshair): 23 Place the crosshair above the sRGB edge line. 24 25 (.color-square .svg-root): 26 (.color-square .srgb-edge): 27 (.color-square .srgb-label): 28 (.color-square .srgb-label:hover): 29 (.color-square .srgb-label:hover + .svg-root > .srgb-edge): 30 (@media (-webkit-device-pixel-ratio: 1)): 31 Make the optical weight of the line on non-retina screens the same as on retina screens. 32 33 * UserInterface/Views/ColorSquare.js: 34 (WI.ColorSquare): 35 (WI.ColorSquare.prototype.set tintedColor): 36 (WI.ColorSquare.prototype._updateBaseColor): 37 (WI.ColorSquare.prototype._drawSRGBOutline): 38 1 39 2019-11-21 Devin Rousso <drousso@apple.com> 2 40 -
trunk/Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
r252745 r252747 1176 1176 localizedStrings["This is what the result of a warning test with no data looks like."] = "This is what the result of a warning test with no data looks like."; 1177 1177 localizedStrings["This is what the result of an unsupported test with no data looks like."] = "This is what the result of an unsupported test with no data looks like."; 1178 /* Label for a guide within the color picker */ 1179 localizedStrings["This line marks the edge of sRGB color space"] = "This line marks the edge of sRGB color space"; 1178 1180 localizedStrings["This object is a root"] = "This object is a root"; 1179 1181 localizedStrings["This object is referenced by internal objects"] = "This object is referenced by internal objects"; -
trunk/Source/WebInspectorUI/UserInterface/Models/Color.js
r252448 r252747 347 347 } 348 348 return [fraction(5), fraction(3), fraction(1)]; 349 } 350 351 // https://www.w3.org/TR/css-color-4/#color-conversion-code 352 static displayP3toSRGB(r, g, b) 353 { 354 r = Number.constrain(r, 0, 1); 355 g = Number.constrain(g, 0, 1); 356 b = Number.constrain(b, 0, 1); 357 358 let linearP3 = WI.Color._toLinearLight([r, g, b]); 359 360 // https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Matrix_math_for_the_web#Multiplying_a_matrix_and_a_point 361 function multiplyMatrixByVector(matrix, vector) { 362 let height = matrix.length; 363 let width = matrix[0].length; 364 console.assert(width === vector.length); 365 366 let result = Array(width).fill(0); 367 for (let i = 0; i < width; i++) 368 for (let rowIndex = 0; rowIndex < height; rowIndex++) 369 result[i] += vector[rowIndex] * matrix[i][rowIndex]; 370 371 return result; 372 } 373 374 // Convert an array of linear-light display-p3 values to CIE XYZ 375 // using D65 (no chromatic adaptation). 376 // http://www.brucelindbloom.com/index.html?Eqn_RGB_XYZ_Matrix.html 377 let matrix = [ 378 [0.4865709486482162, 0.26566769316909306, 0.1982172852343625], 379 [0.2289745640697488, 0.6917385218365064, 0.079286914093745], 380 [0.0000000000000000, 0.04511338185890264, 1.043944368900976] 381 ]; 382 let xyz = multiplyMatrixByVector(matrix, linearP3); 383 384 // Convert XYZ to linear-light sRGB. 385 matrix = [ 386 [ 3.2404542, -1.5371385, -0.4985314], 387 [-0.9692660, 1.8760108, 0.0415560], 388 [ 0.0556434, -0.2040259, 1.0572252] 389 ]; 390 let linearSRGB = multiplyMatrixByVector(matrix, xyz); 391 392 return WI.Color._gammaCorrect(linearSRGB); 393 } 394 395 // Convert gamma-corrected sRGB or Display-P3 to linear light form. 396 static _toLinearLight(rgb) 397 { 398 return rgb.map(function(value) { 399 if (value < 0.04045) 400 return value / 12.92; 401 402 return Math.pow((value + 0.055) / 1.055, 2.4); 403 }); 404 } 405 406 // Convert linear-light sRGB or Display-P3 to gamma corrected form. 407 // Inverse of `toLinearLight`. 408 static _gammaCorrect(rgb) 409 { 410 return rgb.map(function(value) { 411 if (value > 0.0031308) 412 return 1.055 * Math.pow(value, 1 / 2.4) - 0.055; 413 414 return 12.92 * value; 415 }); 349 416 } 350 417 -
trunk/Source/WebInspectorUI/UserInterface/Views/ColorSquare.css
r252168 r252747 26 26 .color-square { 27 27 position: relative; 28 29 --stroke-opacity: 0.8; 28 30 } 29 31 … … 54 56 border-radius: 3px; 55 57 pointer-events: none; 58 z-index: 9; 56 59 57 60 --border-width: 1px; 58 61 --crosshair-size: 7px; 59 62 } 63 64 .color-square .svg-root { 65 position: absolute; 66 top: 0; 67 left: 0; 68 width: 100%; 69 height: 100%; 70 pointer-events: none; 71 } 72 73 .color-square .srgb-edge { 74 fill: none; 75 stroke: white; 76 stroke-width: 0.5px; 77 stroke-opacity: var(--stroke-opacity); 78 } 79 80 .color-square .srgb-label { 81 position: absolute; 82 padding-right: 3px; 83 color: hsla(0, 0%, 100%, var(--stroke-opacity)); 84 font-size: 10px; 85 } 86 87 .color-square .srgb-label:hover { 88 color: white; 89 } 90 91 .color-square .srgb-label:hover + .svg-root > .srgb-edge { 92 stroke-width: 1px; 93 } 94 95 @media (-webkit-device-pixel-ratio: 1) { 96 .color-square .srgb-edge { 97 stroke-width: 1px; 98 stroke-opacity: var(--stroke-opacity) / 2; 99 } 100 } -
trunk/Source/WebInspectorUI/UserInterface/Views/ColorSquare.js
r252168 r252747 45 45 lightnessGradientElement.className = "lightness-gradient fill"; 46 46 47 this._srgbLabelElement = null; 48 this._svgElement = null; 49 this._polylineElement = null; 50 47 51 this._element.addEventListener("mousedown", this); 48 52 … … 107 111 let y = (1 - (hsv[2] / 100)) * this._dimension; 108 112 this._setCrosshairPosition(new WI.Point(x, y)); 113 if (this._gamut === WI.Color.Gamut.DisplayP3) 114 this._drawSRGBOutline(); 109 115 } else { 110 116 let hsl = tintedColor.hsl; … … 208 214 209 215 this._updateCrosshairBackground(); 216 217 if (this._gamut === WI.Color.Gamut.DisplayP3) 218 this._drawSRGBOutline(); 210 219 } 211 220 … … 214 223 this._crosshairElement.style.backgroundColor = this.tintedColor.toString(); 215 224 } 225 226 _drawSRGBOutline() 227 { 228 if (!this._svgElement) { 229 this._srgbLabelElement = this._element.appendChild(document.createElement("span")); 230 this._srgbLabelElement.className = "srgb-label"; 231 this._srgbLabelElement.textContent = WI.unlocalizedString("sRGB"); 232 this._srgbLabelElement.title = WI.UIString("This line marks the edge of sRGB color space", "Label for a guide within the color picker"); 233 234 const svgNamespace = "http://www.w3.org/2000/svg"; 235 this._svgElement = document.createElementNS(svgNamespace, "svg"); 236 this._svgElement.classList.add("svg-root"); 237 this._element.append(this._svgElement); 238 239 this._polylineElement = this._svgElement.appendChild(document.createElementNS(svgNamespace, "polyline")); 240 this._polylineElement.classList.add("srgb-edge"); 241 } 242 243 let points = []; 244 let step = 1 / window.devicePixelRatio; 245 let x = 0; 246 for (let y = 0; y < this._dimension; y += step) { 247 let value = 100 - (y / this._dimension) * 100; 248 249 // Optimization: instead of starting from x = 0, we can benefit from the fact that the next point 250 // always has x >= of the current x. This minimizes processing time over 100 times. 251 for (; x < this._dimension; x += step) { 252 let saturation = x / this._dimension * 100; 253 let rgb = WI.Color.hsv2rgb(this._hue, saturation, value); 254 let srgb = WI.Color.displayP3toSRGB(rgb[0], rgb[1], rgb[2]); 255 if (srgb.some((value) => value > 1 || value < 0)) { 256 // The point is outside of sRGB. 257 points.push({x, y}); 258 break; 259 } 260 } 261 } 262 263 if (points.lastValue.y < this._dimension * 0.95) { 264 // For `color(display-p3 0 0 1)`, the line is almost horizontal. 265 // Position the label directly under the line. 266 points.push({x: this._dimension, y: points.lastValue.y}); 267 this._srgbLabelElement.style.removeProperty("bottom"); 268 this._srgbLabelElement.style.top = `${points.lastValue.y}px`; 269 } else { 270 this._srgbLabelElement.style.removeProperty("top"); 271 this._srgbLabelElement.style.bottom = "0px"; 272 } 273 274 this._srgbLabelElement.style.right = `${this._dimension - points.lastValue.x}px`; 275 276 this._polylineElement.points.clear(); 277 for (let point of points) { 278 let svgPoint = this._svgElement.createSVGPoint(); 279 svgPoint.x = point.x; 280 svgPoint.y = point.y; 281 this._polylineElement.points.appendItem(svgPoint); 282 } 283 } 216 284 };
Note: See TracChangeset
for help on using the changeset viewer.