[LayoutNG] Nested fixedpos in nested multicol w/ CB in outer multicol

Nested fixedpos elements in a nested multicol were handled previously
by CL:2791850 and CL:2823871. However, if a fixedpos was nested in an
OOF element inside a nested multicol, and the containing block for
the fixedpos was in an outer multicol, the fixedpos was never laid out.
The reason being that when we add an inner multicol with pending OOFs,
we don't make any changes to its OOF descendants. So if the fixedpos
containing block existed outside the inner multicol but inside the
outer multicol, fixedpos_containing_block in NGOutOfFlowPositionedNode
would never be set.

In order to fix this, we need to store a fixedpos_containing_block along
with any inner multicols with pending OOFs, if one exists. A new
struct, NGMulticolWithPendingOOFs, was added to store this information.
The fixedpos_containing_block gets set the first time the inner multicol
reaches a potential fixedpos containing block.

The multicol_offset variable of NGMulticolWithPendingOOFs was added for
two purposes:
  1. Similarly to CL:2836226, the static position was incorrect for
    nested fixedpos elements in a nested fragmentation
    context, and whose containing block was outside both multicols.
    (See fixed-in-nested-multicol-with-transform-container.html for an
    example).
    In this case, multicol_offset is the accumulate multicol offset
    relative to the outer fragmentation context. This gets added
    to the static pos of any fixedpos descendants in
    NGContainerFragmentBuilder::TransferOutOfFlowCandidates().
  2. In the case where the inner multicol found a fixedpos containing
    block, multicol_offset will be the offset from the multicol
    to the top of the fixedpos containing block. This is also used
    in NGContainerFragmentBuilder::TransferOutOfFlowCandidates() to
    ensure that the fixedpos static position is correctly updated.

MulticolCollection was updated from a HeapHashSet of inner multicol
LayoutBoxes to a HeapHashMap from inner multicol LayoutBoxes to
NGMulticolWithPendingOOFs.

In order to avoid creating two NGMulticolWithPendingOOFs structs (one
for the logical space and one for the physical space), the
NGContainingBlock struct was also updated to a templated struct.

Note: this CL does not handle the case of more than two layers
of nesting. For example, in the following case, the fixedpos would
not be laid out at the correct offset:
  multicol
    multicol
      transform
        multicol
          relpos
            abspos
              fixedpos

In order to get this case working, we'd also need to store a reference
to the multicol that the fixedpos containing block was found in inside
NGMulticolWithPendingOOFs. However, this use-case doesn't seem worth
handling at this time.

Bug: 1198674,1200324
Change-Id: I213c35514fecf84fc62e55fe5531cff8b0830429
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2844299
Reviewed-by: Morten Stenshorne <mstensho@chromium.org>
Commit-Queue: Alison Maher <almaher@microsoft.com>
Cr-Commit-Position: refs/heads/master@{#875257}
diff --git a/css/css-break/out-of-flow-in-multicolumn-040.html b/css/css-break/out-of-flow-in-multicolumn-040.html
new file mode 100644
index 0000000..6b6a73a
--- /dev/null
+++ b/css/css-break/out-of-flow-in-multicolumn-040.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<title>
+  Nested fixedpos static position in a nested multicol with transform container
+  in outer multicol.
+</title>
+<link rel="help" href="https://www.w3.org/TR/css-position-3/#abspos-breaking">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<style>
+.multicol {
+  column-count: 2;
+  column-fill: auto;
+  column-gap: 0px;
+}
+#outer {
+  height: 100px;
+  width: 100px;
+  margin-left: -100px;
+}
+#inner {
+  width: 50px;
+  height: 700px;
+  margin-left: -425px;
+}
+.rel {
+  position: relative;
+}
+.abs {
+  position: absolute;
+}
+.fixed {
+  position: fixed;
+  width: 50px;
+  height: 200px;
+  background: green;
+}
+</style>
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div class="multicol" id="outer">
+  <div style="height: 200px;"></div>
+  <div style="transform: translateX(0);">
+    <div style="height: 200px; background-color: red;"></div>
+    <div class="multicol" id="inner">
+      <div class="rel">
+        <div style="height: 800px;"></div>
+        <div class="abs">
+          <div style="height: 400px;"></div>
+          <div class="fixed"></div>
+        </div>
+      </div>
+    </div>
+  </div>
+</div>
diff --git a/css/css-break/out-of-flow-in-multicolumn-041.html b/css/css-break/out-of-flow-in-multicolumn-041.html
new file mode 100644
index 0000000..6bf7ffb
--- /dev/null
+++ b/css/css-break/out-of-flow-in-multicolumn-041.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<title>
+  Nested fixedpos in a nested multicol with transform container in outer multicol.
+</title>
+<link rel="help" href="https://www.w3.org/TR/css-position-3/#abspos-breaking">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<style>
+  .multicol {
+    column-count: 2;
+    column-fill: auto;
+    column-gap: 0px;
+  }
+  #outer {
+    height: 100px;
+    width: 100px;
+    margin-left: -100px;
+  }
+  #inner {
+    width: 50px;
+    height: 700px;
+  }
+  .rel {
+    position: relative;
+  }
+  .abs {
+    position: absolute;
+  }
+  .fixed {
+    position: fixed;
+    width: 50px;
+    height: 200px;
+    background: green;
+    top: 0px;
+    left: 0px;
+  }
+</style>
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div class="multicol" id="outer">
+  <div style="height: 200px;"></div>
+  <div style="transform: translateX(0);">
+    <div style="height: 200px; background-color: red;"></div>
+    <div class="multicol" id="inner">
+        <div class="rel">
+          <div style="height: 800px;"></div>
+          <div class="abs">
+            <div style="height: 400px;"></div>
+            <div class="fixed"></div>
+          </div>
+        </div>
+    </div>
+  </div>
+</div>
diff --git a/css/css-multicol/fixed-in-nested-multicol-with-transform-container.html b/css/css-multicol/fixed-in-nested-multicol-with-transform-container.html
new file mode 100644
index 0000000..df836c1
--- /dev/null
+++ b/css/css-multicol/fixed-in-nested-multicol-with-transform-container.html
@@ -0,0 +1,52 @@
+<!DOCTYPE html>
+<title>
+  Nested fixedpos static position in a nested multicol with transform containing
+  block.
+</title>
+<link rel="help" href="https://www.w3.org/TR/css-position-3/#abspos-breaking">
+<link rel="match" href="../reference/ref-filled-green-100px-square.xht">
+<style>
+  .multicol {
+    column-count: 2;
+    column-fill: auto;
+    column-gap: 0px;
+  }
+  #outer {
+    height: 100px;
+    width: 100px;
+    margin-top: -200px;
+    margin-left: -275px;
+  }
+  #inner {
+    width: 50px;
+    height: 400px;
+  }
+  .rel {
+    position: relative;
+  }
+  .abs {
+    position: absolute;
+  }
+  .fixed {
+    position: fixed;
+    width: 100px;
+    height: 100px;
+    background: green;
+  }
+</style>
+<p>Test passes if there is a filled green square and <strong>no red</strong>.</p>
+<div style="transform: translateX(0);">
+  <div style="height: 100px; width: 100px; background-color: red;"></div>
+  <div class="multicol" id="outer">
+      <div style="height: 200px;"></div>
+      <div class="multicol" id="inner">
+          <div class="rel">
+            <div style="height: 400px;"></div>
+            <div class="abs">
+              <div style="height: 400px; width:25px;"></div>
+              <div class="fixed"></div>
+            </div>
+          </div>
+      </div>
+    </div>
+  </div>