Bug 1303158 - handle browser zoom and density display in CssGridHighlighter; r=gl
authorMatteo Ferretti <mferretti@mozilla.com>
Sat, 11 Mar 2017 22:51:57 +0100
changeset 395156 7602bb3a528aaf1ae3222b6271de8044c468da3a
parent 395155 8364027e1ae51422b27362d80fa3f63ce944aec6
child 395157 d2ed3ad38c268f09df104506b228c2a74d23cc23
push id7391
push usermtabara@mozilla.com
push dateMon, 12 Jun 2017 13:08:53 +0000
treeherdermozilla-beta@2191d7f87e2e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgl
bugs1303158, 1303156
milestone55.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1303158 - handle browser zoom and density display in CssGridHighlighter; r=gl That also fixed bug 1303156, since handling better the device pixel ratio makes also the lines crisp. MozReview-Commit-ID: Iyl6YLFFp5b
devtools/server/actors/highlighters/css-grid.js
--- a/devtools/server/actors/highlighters/css-grid.js
+++ b/devtools/server/actors/highlighters/css-grid.js
@@ -47,21 +47,17 @@ const GRID_LINES_PROPERTIES = {
 const GRID_GAP_PATTERN_WIDTH = 14;
 const GRID_GAP_PATTERN_HEIGHT = 14;
 const GRID_GAP_PATTERN_LINE_DASH = [5, 3];
 const GRID_GAP_ALPHA = 0.5;
 
 /**
  * Cached used by `CssGridHighlighter.getGridGapPattern`.
  */
-const gCachedGridPattern = new WeakMap();
-// WeakMap key for the Row grid pattern.
-const ROW_KEY = {};
-// WeakMap key for the Column grid pattern.
-const COLUMN_KEY = {};
+const gCachedGridPattern = new Map();
 
 // That's the maximum size we can allocate for the canvas, in bytes. See:
 // http://searchfox.org/mozilla-central/source/gfx/thebes/gfxPrefs.h#401
 // It might become accessible as user preference, but at the moment we have to hard code
 // it (see: https://bugzilla.mozilla.org/show_bug.cgi?id=1282656).
 const MAX_ALLOC_SIZE = 500000000;
 // One pixel on canvas is using 4 bytes (R, G, B and Alpha); we use this to calculate the
 // proper memory allocation below
@@ -357,54 +353,68 @@ CssGridHighlighter.prototype = extend(Au
     return this.getElement("canvas");
   },
 
   get color() {
     return this.options.color || DEFAULT_GRID_COLOR;
   },
 
   /**
-   * Gets the grid gap pattern used to render the gap regions.
+   * Gets the grid gap pattern used to render the gap regions based on the device
+   * pixel ratio given.
    *
+   * @param {Number} devicePixelRatio
+   *         The device pixel ratio we want the pattern for.
    * @param  {Object} dimension
-   *         Refers to the WeakMap key for the grid dimension type which is either the
-   *         constant COLUMN or ROW.
+   *         Refers to the Map key for the grid dimension type which is either the
+   *         constant COLUMNS or ROWS.
    * @return {CanvasPattern} grid gap pattern.
    */
-  getGridGapPattern(dimension) {
-    if (gCachedGridPattern.has(dimension)) {
-      return gCachedGridPattern.get(dimension);
+  getGridGapPattern(devicePixelRatio, dimension) {
+    let gridPatternMap = null;
+
+    if (gCachedGridPattern.has(devicePixelRatio)) {
+      gridPatternMap = gCachedGridPattern.get(devicePixelRatio);
+    } else {
+      gridPatternMap = new Map();
+    }
+
+    if (gridPatternMap.has(dimension)) {
+      return gridPatternMap.get(dimension);
     }
 
     // Create the diagonal lines pattern for the rendering the grid gaps.
     let canvas = createNode(this.win, { nodeType: "canvas" });
-    canvas.width = GRID_GAP_PATTERN_WIDTH;
-    canvas.height = GRID_GAP_PATTERN_HEIGHT;
+    let width = canvas.width = GRID_GAP_PATTERN_WIDTH * devicePixelRatio;
+    let height = canvas.height = GRID_GAP_PATTERN_HEIGHT * devicePixelRatio;
 
     let ctx = canvas.getContext("2d");
     ctx.save();
     ctx.setLineDash(GRID_GAP_PATTERN_LINE_DASH);
     ctx.beginPath();
     ctx.translate(.5, .5);
 
-    if (dimension === COLUMN_KEY) {
+    if (dimension === COLUMNS) {
       ctx.moveTo(0, 0);
-      ctx.lineTo(GRID_GAP_PATTERN_WIDTH, GRID_GAP_PATTERN_HEIGHT);
+      ctx.lineTo(width, height);
     } else {
-      ctx.moveTo(GRID_GAP_PATTERN_WIDTH, 0);
-      ctx.lineTo(0, GRID_GAP_PATTERN_HEIGHT);
+      ctx.moveTo(width, 0);
+      ctx.lineTo(0, height);
     }
 
     ctx.strokeStyle = this.color;
     ctx.globalAlpha = GRID_GAP_ALPHA;
     ctx.stroke();
     ctx.restore();
 
     let pattern = ctx.createPattern(canvas, "repeat");
-    gCachedGridPattern.set(dimension, pattern);
+
+    gridPatternMap.set(dimension, pattern);
+    gCachedGridPattern.set(devicePixelRatio, gridPatternMap);
+
     return pattern;
   },
 
   /**
    * Called when the page navigates. Used to clear the cached gap patterns and avoid
    * using DeadWrapper objects as gap patterns the next time.
    */
   onNavigate() {
@@ -428,18 +438,17 @@ CssGridHighlighter.prototype = extend(Au
 
     // Hide the canvas, grid element highlights and infobar.
     this._hide();
 
     return this._update();
   },
 
   _clearCache() {
-    gCachedGridPattern.delete(ROW_KEY);
-    gCachedGridPattern.delete(COLUMN_KEY);
+    gCachedGridPattern.clear();
   },
 
   /**
    * Shows the grid area highlight for the given area name.
    *
    * @param  {String} areaName
    *         Grid area name.
    */
@@ -690,17 +699,16 @@ CssGridHighlighter.prototype = extend(Au
                             "for further information.");
     }
 
     // Resize the canvas taking the dpr into account so as to have crisp lines.
     this.canvas.setAttribute("width", width);
     this.canvas.setAttribute("height", height);
     this.canvas.setAttribute("style",
       `width:${width / ratio}px;height:${height / ratio}px;`);
-    this.ctx.scale(ratio, ratio);
 
     this.ctx.clearRect(0, 0, width, height);
   },
 
   getFirstRowLinePos(fragment) {
     return fragment.rows.lines[0].start;
   },
 
@@ -816,16 +824,22 @@ CssGridHighlighter.prototype = extend(Au
    * @param  {Number} endPos
    *         The end position of the cross side of the grid line.
    * @param  {String} dimensionType
    *         The grid dimension type which is either the constant COLUMNS or ROWS.
    * @param  {String} lineType
    *         The grid line type - "edge", "explicit", or "implicit".
    */
   renderLine(linePos, startPos, endPos, dimensionType, lineType) {
+    let ratio = this.win.devicePixelRatio;
+
+    linePos = Math.round(linePos * ratio);
+    startPos = Math.round(startPos * ratio);
+    endPos = Math.round(endPos * ratio);
+
     this.ctx.save();
     this.ctx.setLineDash(GRID_LINES_PROPERTIES[lineType].lineDash);
     this.ctx.beginPath();
     this.ctx.translate(.5, .5);
 
     if (dimensionType === COLUMNS) {
       this.ctx.moveTo(linePos, startPos);
       this.ctx.lineTo(linePos, endPos);
@@ -850,16 +864,21 @@ CssGridHighlighter.prototype = extend(Au
    *         The line position along the x-axis for a column grid line and
    *         y-axis for a row grid line.
    * @param  {Number} startPos
    *         The start position of the cross side of the grid line.
    * @param  {String} dimensionType
    *         The grid dimension type which is either the constant COLUMNS or ROWS.
    */
   renderGridLineNumber(lineNumber, linePos, startPos, dimensionType) {
+    let ratio = this.win.devicePixelRatio;
+
+    linePos = Math.round(linePos * ratio);
+    startPos = Math.round(startPos * ratio);
+
     this.ctx.save();
 
     let textWidth = this.ctx.measureText(lineNumber).width;
     // Guess the font height based on the measured width
     let textHeight = textWidth * 2;
 
     if (dimensionType === COLUMNS) {
       let yPos = Math.max(startPos, textHeight);
@@ -883,26 +902,31 @@ CssGridHighlighter.prototype = extend(Au
    * @param  {Number} endPos
    *         The end position of the cross side of the grid line.
    * @param  {Number} breadth
    *         The grid line breadth value.
    * @param  {String} dimensionType
    *         The grid dimension type which is either the constant COLUMNS or ROWS.
    */
   renderGridGap(linePos, startPos, endPos, breadth, dimensionType) {
+    let ratio = this.win.devicePixelRatio;
+
+    linePos = Math.round(linePos * ratio);
+    startPos = Math.round(startPos * ratio);
+    endPos = Math.round(endPos * ratio);
+    breadth = Math.round(breadth * ratio);
+
     this.ctx.save();
+    this.ctx.fillStyle = this.getGridGapPattern(ratio, dimensionType);
 
     if (dimensionType === COLUMNS) {
-      this.ctx.fillStyle = this.getGridGapPattern(COLUMN_KEY);
       this.ctx.fillRect(linePos, startPos, breadth, endPos - startPos);
     } else {
-      this.ctx.fillStyle = this.getGridGapPattern(ROW_KEY);
       this.ctx.fillRect(startPos, linePos, endPos - startPos, breadth);
     }
-
     this.ctx.restore();
   },
 
   /**
    * Render the grid area highlight for the given area name or for all the grid areas.
    *
    * @param  {String} areaName
    *         Name of the grid area to be highlighted. If no area name is provided, all