[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc

mihaip at chromium.org mihaip at chromium.org
Wed Dec 22 16:02:36 UTC 2010


The following commit has been merged in the debian/experimental branch:
commit 39d687f262a308d02835dc2180b224c2b1351a3c
Author: mihaip at chromium.org <mihaip at chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date:   Thu Nov 18 00:42:24 2010 +0000

    2010-11-17  Mihai Parparita  <mihaip at chromium.org>
    
            Reviewed by Tony Chang.
    
            Rebaseline server: add loupe for image diffs
            https://bugs.webkit.org/show_bug.cgi?id=49692
    
            Add a loupe (magnifiying glass) for inspecting image diffs. Shows an
            enlarged area of the expected, actual and diff images side by side.
    
            * Scripts/webkitpy/tool/commands/data/rebaselineserver/index.html:
            * Scripts/webkitpy/tool/commands/data/rebaselineserver/loupe.js: Added.
            * Scripts/webkitpy/tool/commands/data/rebaselineserver/main.js:
            * Scripts/webkitpy/tool/commands/rebaselineserver.py:
    
    git-svn-id: http://svn.webkit.org/repository/webkit/trunk@72262 268f45cc-cd09-0410-ab3c-d52691b4dbfc

diff --git a/WebKitTools/ChangeLog b/WebKitTools/ChangeLog
index a2c829e..663f551 100644
--- a/WebKitTools/ChangeLog
+++ b/WebKitTools/ChangeLog
@@ -1,3 +1,18 @@
+2010-11-17  Mihai Parparita  <mihaip at chromium.org>
+
+        Reviewed by Tony Chang.
+
+        Rebaseline server: add loupe for image diffs
+        https://bugs.webkit.org/show_bug.cgi?id=49692
+        
+        Add a loupe (magnifiying glass) for inspecting image diffs. Shows an
+        enlarged area of the expected, actual and diff images side by side.
+
+        * Scripts/webkitpy/tool/commands/data/rebaselineserver/index.html:
+        * Scripts/webkitpy/tool/commands/data/rebaselineserver/loupe.js: Added.
+        * Scripts/webkitpy/tool/commands/data/rebaselineserver/main.js:
+        * Scripts/webkitpy/tool/commands/rebaselineserver.py:
+
 2010-11-17  Steve Falkenburg  <sfalken at apple.com>
 
         Reviewed by Adam Roben.
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/index.html b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/index.html
index afd2fff..8cc48c1 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/index.html
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/index.html
@@ -33,6 +33,7 @@
   <title>Layout Test Rebaseline Server</title>
   <link rel="stylesheet" href="/main.css" type="text/css">
   <script src="/util.js"></script>
+  <script src="/loupe.js"></script>
   <script src="/main.js"></script>
 </head>
 <body class="loading">
@@ -100,5 +101,39 @@
   </tbody>
 </table>
 
+<table id="loupe" style="display: none">
+  <tr>
+    <td colspan="3" id="loupe-info">
+      <span id="loupe-close" class="link">Close</span>
+      <label>Coordinate: <span id="loupe-coordinate"></span></label>
+    </td>
+  </tr>
+  <tr>
+    <td>
+      <div class="loupe-container">
+        <canvas id="expected-loupe" width="210" height="210"></canvas>
+        <div class="center-highlight"></div>
+      </div>
+    </td>
+    <td>
+      <div class="loupe-container">
+        <canvas id="actual-loupe" width="210" height="210"></canvas>
+        <div class="center-highlight"></div>
+      </div>
+    </td>
+    <td>
+      <div class="loupe-container">
+        <canvas id="diff-loupe" width="210" height="210"></canvas>
+        <div class="center-highlight"></div>
+      </div>
+    </td>
+  </tr>
+  <tr id="loupe-colors">
+    <td><label>Exp. color: <span id="expected-loupe-color"></span></label></td>
+    <td><label>Actual color: <span id="actual-loupe-color"></span></label></td>
+    <td><label>Diff color: <span id="diff-loupe-color"></span></label></td>
+  </tr>
+</table>
+
 </body>
 </html>
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/loupe.js b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/loupe.js
new file mode 100644
index 0000000..41f977a
--- /dev/null
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/loupe.js
@@ -0,0 +1,144 @@
+/*
+ * Copyright (c) 2010 Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ *     * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *     * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+var LOUPE_MAGNIFICATION_FACTOR = 10;
+
+function Loupe()
+{
+    this._node = $('loupe');
+    this._currentCornerX = -1;
+    this._currentCornerY = -1;
+
+    var self = this;
+
+    function handleOutputClick(event) { self._handleOutputClick(event); }
+    $('expected-image').addEventListener('click', handleOutputClick);
+    $('actual-image').addEventListener('click', handleOutputClick);
+    $('diff-canvas').addEventListener('click', handleOutputClick);
+
+    function handleLoupeClick(event) { self._handleLoupeClick(event); }
+    $('expected-loupe').addEventListener('click', handleLoupeClick);
+    $('actual-loupe').addEventListener('click', handleLoupeClick);
+    $('diff-loupe').addEventListener('click', handleLoupeClick);
+
+    function hide(event) { self.hide(); }
+    $('loupe-close').addEventListener('click', hide);
+}
+
+Loupe.prototype._handleOutputClick = function(event)
+{
+    // The -1 compensates for the border around the image/canvas.
+    this._showFor(event.offsetX - 1, event.offsetY - 1);
+};
+
+Loupe.prototype._handleLoupeClick = function(event)
+{
+    var deltaX = Math.floor(event.offsetX/LOUPE_MAGNIFICATION_FACTOR);
+    var deltaY = Math.floor(event.offsetY/LOUPE_MAGNIFICATION_FACTOR);
+
+    this._showFor(
+        this._currentCornerX + deltaX, this._currentCornerY + deltaY);
+}
+
+Loupe.prototype.hide = function()
+{
+    this._node.style.display = 'none';
+};
+
+Loupe.prototype._showFor = function(x, y)
+{
+    this._fillFromImage(x, y, 'expected', $('expected-image'));
+    this._fillFromImage(x, y, 'actual', $('actual-image'));
+    this._fillFromCanvas(x, y, 'diff', $('diff-canvas'));
+
+    this._node.style.display = '';
+};
+
+Loupe.prototype._fillFromImage = function(x, y, type, sourceImage)
+{
+    var tempCanvas = document.createElement('canvas');
+    tempCanvas.width = sourceImage.width;
+    tempCanvas.height = sourceImage.height;
+    var tempContext = tempCanvas.getContext('2d');
+
+    tempContext.drawImage(sourceImage, 0, 0);
+
+    this._fillFromCanvas(x, y, type, tempCanvas);
+};
+
+Loupe.prototype._fillFromCanvas = function(x, y, type, canvas)
+{
+    var context = canvas.getContext('2d');
+    var sourceImageData =
+        context.getImageData(0, 0, canvas.width, canvas.height);
+
+    var targetCanvas = $(type + '-loupe');
+    var targetContext = targetCanvas.getContext('2d');
+    targetContext.fillStyle = 'rgba(255, 255, 255, 1)';
+    targetContext.fillRect(0, 0, targetCanvas.width, targetCanvas.height);
+
+    var sourceXOffset = (targetCanvas.width/LOUPE_MAGNIFICATION_FACTOR - 1)/2;
+    var sourceYOffset = (targetCanvas.height/LOUPE_MAGNIFICATION_FACTOR - 1)/2;
+
+    function readPixelComponent(x, y, component) {
+        var offset = (y * sourceImageData.width + x) * 4 + component;
+        return sourceImageData.data[offset];
+    }
+
+    for (var i = -sourceXOffset; i <= sourceXOffset; i++) {
+        for (var j = -sourceYOffset; j <= sourceYOffset; j++) {
+            var sourceX = x + i;
+            var sourceY = y + j;
+
+            var sourceR = readPixelComponent(sourceX, sourceY, 0);
+            var sourceG = readPixelComponent(sourceX, sourceY, 1);
+            var sourceB = readPixelComponent(sourceX, sourceY, 2);
+            var sourceA = readPixelComponent(sourceX, sourceY, 3)/255;
+            sourceA = Math.round(sourceA * 10)/10;
+
+            var targetX = (i + sourceXOffset) * LOUPE_MAGNIFICATION_FACTOR;
+            var targetY = (j + sourceYOffset) * LOUPE_MAGNIFICATION_FACTOR;
+            var colorString =
+                sourceR + ', ' + sourceG + ', ' + sourceB + ', ' + sourceA;
+            targetContext.fillStyle = 'rgba(' + colorString + ')';
+            targetContext.fillRect(
+                targetX, targetY,
+                LOUPE_MAGNIFICATION_FACTOR, LOUPE_MAGNIFICATION_FACTOR);
+
+            if (i == 0 && j == 0) {
+                $('loupe-coordinate').textContent = sourceX + ', ' + sourceY;
+                $(type + '-loupe-color').textContent = colorString;
+            }
+        }
+    }
+
+    this._currentCornerX = x - sourceXOffset;
+    this._currentCornerY = y - sourceYOffset;
+};
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.css b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.css
index bd2cd98..6e90fe4 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.css
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.css
@@ -120,6 +120,7 @@ a, .link {
   border: solid 1px #ddd;
   -webkit-user-select: none;
   -webkit-user-drag: none;
+  cursor: crosshair;  
 }
 
 #image-outputs img.loading,
@@ -148,3 +149,65 @@ a, .link {
   margin: 0;
   background: #eee;
 }
+
+#loupe {
+  -webkit-box-shadow: 2px 2px 5px rgba(0, 0, 0, .5);
+  position: absolute;
+  width: 634px;
+  top: 50%;
+  left: 50%;
+  margin-left: -151px;
+  margin-top: -50px;
+  background: #fff;
+  border-spacing: 0;
+  border-collapse: collapse;
+}
+
+#loupe td {
+  padding: 0;
+  border: solid 1px #ccc;     
+}
+
+#loupe label {
+  color: #999;
+  padding-right: 1em;
+}
+
+#loupe span {
+  color: #000;
+  font-weight: bold;
+}
+
+#loupe canvas {
+  cursor: crosshair;
+}
+
+#loupe #loupe-close {
+  float: right;
+}
+
+#loupe #loupe-info {
+  background: #eee;
+  padding: .3em .5em;
+}
+
+#loupe #loupe-colors td {
+  text-align: center;
+}
+
+#loupe .loupe-container {
+  position: relative;
+  width: 210px;
+  height: 210px;
+}
+
+#loupe .center-highlight {
+  position: absolute;
+  width: 10px;
+  height: 10px;
+  top: 50%;
+  left: 50%;
+  margin-left: -5px;
+  margin-top: -5px;
+  outline: solid 1px #999;
+}
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.js b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.js
index 21d18b7..fa037b3 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.js
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/data/rebaselineserver/main.js
@@ -34,6 +34,7 @@ var results;
 var testsByFailureType = {};
 var testsByDirectory = {};
 var selectedTests = [];
+var loupe;
 
 function main()
 {
@@ -43,6 +44,8 @@ function main()
     $('next-test').addEventListener('click', nextTest);
     $('previous-test').addEventListener('click', previousTest);
 
+    loupe = new Loupe();
+
     document.addEventListener('keydown', function(event) {
         if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) {
             return;
@@ -210,6 +213,7 @@ function selectTest()
     }
 
     updateState();
+    loupe.hide();
 }
 
 function updateState()
@@ -241,7 +245,7 @@ function displayImageResults(testName)
         && currentExpectedImageTest == testName) {
         return;
     }
-    
+
     function displayImageResult(mode, callback) {
         var image = $(mode);
         image.className = 'loading';
@@ -274,45 +278,45 @@ function displayImageResults(testName)
 function updateImageDiff() {
     if (currentExpectedImageTest != currentActualImageTest)
         return;
-        
+
     var expectedImage = $('expected-image');
     var actualImage = $('actual-image');
-    
+
     function getImageData(image) {
         var imageCanvas = document.createElement('canvas');
         imageCanvas.width = image.width;
         imageCanvas.height = image.height;
         imageCanvasContext = imageCanvas.getContext('2d');
-        
+
         imageCanvasContext.fillStyle = 'rgba(255, 255, 255, 1)';
         imageCanvasContext.fillRect(
             0, 0, image.width, image.height);
-            
+
         imageCanvasContext.drawImage(image, 0, 0);
         return imageCanvasContext.getImageData(
-            0, 0, image.width, image.height);  
+            0, 0, image.width, image.height);
     }
-    
+
     var expectedImageData = getImageData(expectedImage);
     var actualImageData = getImageData(actualImage);
-    
+
     var diffCanvas = $('diff-canvas');
     var diffCanvasContext = diffCanvas.getContext('2d');
     var diffImageData =
         diffCanvasContext.createImageData(diffCanvas.width, diffCanvas.height);
-  
+
     // Avoiding property lookups for all these during the per-pixel loop below
     // provides a significant performance benefit.
     var expectedWidth = expectedImage.width;
     var expectedHeight = expectedImage.height;
     var expected = expectedImageData.data;
-    
+
     var actualWidth = actualImage.width;
     var actual = actualImageData.data;
-  
+
     var diffWidth = diffImageData.width;
     var diff = diffImageData.data;
-    
+
     for (var x = 0; x < expectedWidth; x++) {
         for (var y = 0; y < expectedHeight; y++) {
             var expectedOffset = (y * expectedWidth + x) * 4;
@@ -334,7 +338,7 @@ function updateImageDiff() {
             }
         }
     }
-    
+
     diffCanvasContext.putImageData(
         diffImageData,
         0, 0,
diff --git a/WebKitTools/Scripts/webkitpy/tool/commands/rebaselineserver.py b/WebKitTools/Scripts/webkitpy/tool/commands/rebaselineserver.py
index 3aa464a..abb2af4 100644
--- a/WebKitTools/Scripts/webkitpy/tool/commands/rebaselineserver.py
+++ b/WebKitTools/Scripts/webkitpy/tool/commands/rebaselineserver.py
@@ -58,6 +58,7 @@ class RebaselineHTTPServer(BaseHTTPServer.HTTPServer):
 class RebaselineHTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler):
     STATIC_FILE_NAMES = frozenset([
         "index.html",
+        "loupe.js",
         "main.js",
         "main.css",
         "util.js",

-- 
WebKit Debian packaging



More information about the Pkg-webkit-commits mailing list