Bug 1457602 Part 1: Correct shape-outside: image shape-margin calculation for vertical writing modes. r=jfkthame
authorBrad Werth <bwerth@mozilla.com>
Mon, 30 Apr 2018 17:01:24 -0700
changeset 417628 c576126a7c7e75bd94de623ed1c6aa40c0bd9b4f
parent 417627 e5332f31998b9d3cf40114fb21c13c49bb75a9db
child 417629 f706fe09567f4f92a1cfb6420e102c880aa8e8cb
push id33974
push userncsoregi@mozilla.com
push dateThu, 10 May 2018 09:47:43 +0000
treeherdermozilla-central@b52b2eb81d1e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjfkthame
bugs1457602
milestone62.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 1457602 Part 1: Correct shape-outside: image shape-margin calculation for vertical writing modes. r=jfkthame MozReview-Commit-ID: ChUL66vUkHu
layout/generic/nsFloatManager.cpp
--- a/layout/generic/nsFloatManager.cpp
+++ b/layout/generic/nsFloatManager.cpp
@@ -2000,45 +2000,83 @@ nsFloatManager::ImageShapeInfo::ImageSha
           DebugOnly<uint32_t> alphaIndex = col - dfOffset.x +
                                            (row - dfOffset.y) * aStride;
           MOZ_ASSERT(alphaIndex < (aStride * h),
             "Our aAlphaPixels index should be in-bounds.");
 
           df[index] = 0;
         } else {
           // Case 3: Other pixel.
-
-          // Backward-looking neighborhood distance from target pixel X
-          // with chamfer 5-7-11 looks like:
-          //
-          // +--+--+--+--+--+
-          // |  |11|  |11|  |
-          // +--+--+--+--+--+
-          // |11| 7| 5| 7|11|
-          // +--+--+--+--+--+
-          // |  | 5| X|  |  |
-          // +--+--+--+--+--+
-          //
-          // X should be set to the minimum of MAX_MARGIN_5X and the
-          // values of all of the numbered neighbors summed with the
-          // value in that chamfer cell.
-          MOZ_ASSERT(index - (wEx * 2) - 1 < (iSize * bSize) &&
-                     index - wEx - 2 < (iSize * bSize),
-                     "Our distance field most extreme indices should be "
-                     "in-bounds.");
-
-          df[index] = std::min<dfType>(MAX_MARGIN_5X,
-                      std::min<dfType>(df[index - (wEx * 2) - 1] + 11,
-                      std::min<dfType>(df[index - (wEx * 2) + 1] + 11,
-                      std::min<dfType>(df[index - wEx - 2] + 11,
-                      std::min<dfType>(df[index - wEx - 1] + 7,
-                      std::min<dfType>(df[index - wEx] + 5,
-                      std::min<dfType>(df[index - wEx + 1] + 7,
-                      std::min<dfType>(df[index - wEx + 2] + 11,
-                                       df[index - 1] + 5))))))));
+          if (aWM.IsVertical()) {
+            // Column-by-column, starting at the left, each column
+            // top-to-bottom.
+            // Backward-looking neighborhood distance from target pixel X
+            // with chamfer 5-7-11 looks like:
+            //
+            // +--+--+--+
+            // |  |11|  |   |    +
+            // +--+--+--+   |   /|
+            // |11| 7| 5|   |  / |
+            // +--+--+--+   | /  V
+            // |  | 5| X|   |/
+            // +--+--+--+   +
+            // |11| 7|  |
+            // +--+--+--+
+            // |  |11|  |
+            // +--+--+--+
+            //
+            // X should be set to the minimum of MAX_MARGIN_5X and the
+            // values of all of the numbered neighbors summed with the
+            // value in that chamfer cell.
+            MOZ_ASSERT(index - wEx - 2 < (iSize * bSize) &&
+                       index + wEx - 2 < (iSize * bSize) &&
+                       index - (wEx * 2) - 1 < (iSize * bSize),
+                       "Our distance field most extreme indices should be "
+                       "in-bounds.");
+
+            df[index] = std::min<dfType>(MAX_MARGIN_5X,
+                        std::min<dfType>(df[index - wEx - 2] + 11,
+                        std::min<dfType>(df[index + wEx - 2] + 11,
+                        std::min<dfType>(df[index - (wEx * 2) - 1] + 11,
+                        std::min<dfType>(df[index - wEx - 1] + 7,
+                        std::min<dfType>(df[index - 1] + 5,
+                        std::min<dfType>(df[index + wEx - 1] + 7,
+                        std::min<dfType>(df[index + (wEx * 2) - 1] + 11,
+                                         df[index - wEx] + 5))))))));
+          } else {
+            // Row-by-row, starting at the top, each row left-to-right.
+            // Backward-looking neighborhood distance from target pixel X
+            // with chamfer 5-7-11 looks like:
+            //
+            // +--+--+--+--+--+
+            // |  |11|  |11|  |   ----+
+            // +--+--+--+--+--+      /
+            // |11| 7| 5| 7|11|     /
+            // +--+--+--+--+--+    /
+            // |  | 5| X|  |  |   +-->
+            // +--+--+--+--+--+
+            //
+            // X should be set to the minimum of MAX_MARGIN_5X and the
+            // values of all of the numbered neighbors summed with the
+            // value in that chamfer cell.
+            MOZ_ASSERT(index - (wEx * 2) - 1 < (iSize * bSize) &&
+                       index - wEx - 2 < (iSize * bSize),
+                       "Our distance field most extreme indices should be "
+                       "in-bounds.");
+
+            df[index] = std::min<dfType>(MAX_MARGIN_5X,
+                        std::min<dfType>(df[index - (wEx * 2) - 1] + 11,
+                        std::min<dfType>(df[index - (wEx * 2) + 1] + 11,
+                        std::min<dfType>(df[index - wEx - 2] + 11,
+                        std::min<dfType>(df[index - wEx - 1] + 7,
+                        std::min<dfType>(df[index - wEx] + 5,
+                        std::min<dfType>(df[index - wEx + 1] + 7,
+                        std::min<dfType>(df[index - wEx + 2] + 11,
+                                         df[index - 1] + 5))))))));
+          }
         }
       }
     }
 
     // Okay, time for the second pass. This pass is in reverse order from
     // the first pass. All of our opaque pixels have been set to 0, and all
     // of our expanded region pixels have been set to MAX_MARGIN_5X. Other
     // pixels have been set to some value between those two (inclusive) but
@@ -2073,44 +2111,83 @@ nsFloatManager::ImageShapeInfo::ImageSha
         const uint32_t row = aWM.IsVertical() ? i : b;
         const uint32_t index = col + row * wEx;
         MOZ_ASSERT(index < (wEx * hEx),
                    "Our distance field index should be in-bounds.");
 
         // Only apply the chamfer calculation if the df value is not
         // already 0, since the chamfer can only reduce the value.
         if (df[index]) {
-          // Forward-looking neighborhood distance from target pixel X
-          // with chamfer 5-7-11 looks like:
-          //
-          // +--+--+--+--+--+
-          // |  |  | X| 5|  |
-          // +--+--+--+--+--+
-          // |11| 7| 5| 7|11|
-          // +--+--+--+--+--+
-          // |  |11|  |11|  |
-          // +--+--+--+--+--+
-          //
-          // X should be set to the minimum of its current value and
-          // the values of all of the numbered neighbors summed with
-          // the value in that chamfer cell.
-          MOZ_ASSERT(index + (wEx * 2) + 1 < (wEx * hEx) &&
-                     index + wEx + 2 < (wEx * hEx),
-                     "Our distance field most extreme indices should be "
-                     "in-bounds.");
-
-          df[index] = std::min<dfType>(df[index],
-                      std::min<dfType>(df[index + (wEx * 2) + 1] + 11,
-                      std::min<dfType>(df[index + (wEx * 2) - 1] + 11,
-                      std::min<dfType>(df[index + wEx + 2] + 11,
-                      std::min<dfType>(df[index + wEx + 1] + 7,
-                      std::min<dfType>(df[index + wEx] + 5,
-                      std::min<dfType>(df[index + wEx - 1] + 7,
-                      std::min<dfType>(df[index + wEx - 2] + 11,
-                                       df[index + 1] + 5))))))));
+          if (aWM.IsVertical()) {
+            // Column-by-column, starting at the right, each column
+            // bottom-to-top.
+            // Forward-looking neighborhood distance from target pixel X
+            // with chamfer 5-7-11 looks like:
+            //
+            // +--+--+--+
+            // |  |11|  |        +
+            // +--+--+--+       /|
+            // |  | 7|11|   A  / |
+            // +--+--+--+   | /  |
+            // | X| 5|  |   |/   |
+            // +--+--+--+   +    |
+            // | 5| 7|11|
+            // +--+--+--+
+            // |  |11|  |
+            // +--+--+--+
+            //
+            // X should be set to the minimum of its current value and
+            // the values of all of the numbered neighbors summed with
+            // the value in that chamfer cell.
+            MOZ_ASSERT(index + wEx + 2 < (wEx * hEx) &&
+                       index + (wEx * 2) + 1 < (wEx * hEx) &&
+                       index - (wEx * 2) + 1 < (wEx * hEx),
+                       "Our distance field most extreme indices should be "
+                       "in-bounds.");
+
+            df[index] = std::min<dfType>(df[index],
+                        std::min<dfType>(df[index + wEx + 2] + 11,
+                        std::min<dfType>(df[index - wEx + 2] + 11,
+                        std::min<dfType>(df[index + (wEx * 2) + 1] + 11,
+                        std::min<dfType>(df[index + wEx + 1] + 7,
+                        std::min<dfType>(df[index + 1] + 5,
+                        std::min<dfType>(df[index - wEx + 1] + 7,
+                        std::min<dfType>(df[index - (wEx * 2) + 1] + 11,
+                                         df[index + wEx] + 5))))))));
+          } else {
+            // Row-by-row, starting at the bottom, each row right-to-left.
+            // Forward-looking neighborhood distance from target pixel X
+            // with chamfer 5-7-11 looks like:
+            //
+            // +--+--+--+--+--+
+            // |  |  | X| 5|  |    <--+
+            // +--+--+--+--+--+      /
+            // |11| 7| 5| 7|11|     /
+            // +--+--+--+--+--+    /
+            // |  |11|  |11|  |   +----
+            // +--+--+--+--+--+
+            //
+            // X should be set to the minimum of its current value and
+            // the values of all of the numbered neighbors summed with
+            // the value in that chamfer cell.
+            MOZ_ASSERT(index + (wEx * 2) + 1 < (wEx * hEx) &&
+                       index + wEx + 2 < (wEx * hEx),
+                       "Our distance field most extreme indices should be "
+                       "in-bounds.");
+
+            df[index] = std::min<dfType>(df[index],
+                        std::min<dfType>(df[index + (wEx * 2) + 1] + 11,
+                        std::min<dfType>(df[index + (wEx * 2) - 1] + 11,
+                        std::min<dfType>(df[index + wEx + 2] + 11,
+                        std::min<dfType>(df[index + wEx + 1] + 7,
+                        std::min<dfType>(df[index + wEx] + 5,
+                        std::min<dfType>(df[index + wEx - 1] + 7,
+                        std::min<dfType>(df[index + wEx - 2] + 11,
+                                         df[index + 1] + 5))))))));
+          }
         }
 
         // Finally, we can check the df value and see if it's less than
         // or equal to the usedMargin5X value.
         if (df[index] <= usedMargin5X) {
           if (iMax == -1) {
             iMax = i;
           }