--- 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;
}