Fix matrix3d transform under page zoom

The math for adjusting a matrix3d transform when the page is zoomed is incorrect in at least 3 different places.

There was a previous attempt at fixing this but they did it the same way as the 2d matrix case and forgot about the translateZ component (ceddaab902432728b12a17fcbf2c42283c7dfe68). But it would've been incorrect even if they did take translateZ into account.

The real problem is that the last column can't be interpeted as the translation at all if the matrix is non-affine!

To get the general correction for matrix3d, intuitively, we want to first scale down to the original units, do the transform, then scale back up. So checking with octave/matlab it should actually be:

    octave:1> pkg load symbolic;
    octave:2> A = sym('a', [3, 3]); B = sym('b', [3, 1]); C = sym('c', [1, 3]); D = sym('d', [1, 1]); s = sym('s');
    octave:3> M = [A, B; C D]
    M = (sym 4×4 matrix)

      ⎡a₁₁  a₁₂  a₁₃  b₁₁⎤
      ⎢                  ⎥
      ⎢a₂₁  a₂₂  a₂₃  b₂₁⎥
      ⎢                  ⎥
      ⎢a₃₁  a₃₂  a₃₃  b₃₁⎥
      ⎢                  ⎥
      ⎣c₁₁  c₁₂  c₁₃  d₁₁⎦

    octave:4> scaleDown = [[eye(3) / s, zeros(3, 1)]; [zeros(1, 3), 1]]
    scaleDown = (sym 4×4 matrix)

      ⎡1         ⎤
      ⎢─  0  0  0⎥
      ⎢s         ⎥
      ⎢          ⎥
      ⎢   1      ⎥
      ⎢0  ─  0  0⎥
      ⎢   s      ⎥
      ⎢          ⎥
      ⎢      1   ⎥
      ⎢0  0  ─  0⎥
      ⎢      s   ⎥
      ⎢          ⎥
      ⎣0  0  0  1⎦

    octave:5> scaleUp = [[s * eye(3), zeros(3, 1)]; [zeros(1, 3), 1]]
    scaleUp = (sym 4×4 matrix)

      ⎡s  0  0  0⎤
      ⎢          ⎥
      ⎢0  s  0  0⎥
      ⎢          ⎥
      ⎢0  0  s  0⎥
      ⎢          ⎥
      ⎣0  0  0  1⎦

    octave:6> scaleUp * M * scaleDown
    ans = (sym 4×4 matrix)

      ⎡a₁₁  a₁₂  a₁₃  b₁₁⋅s⎤
      ⎢                    ⎥
      ⎢a₂₁  a₂₂  a₂₃  b₂₁⋅s⎥
      ⎢                    ⎥
      ⎢a₃₁  a₃₂  a₃₃  b₃₁⋅s⎥
      ⎢                    ⎥
      ⎢c₁₁  c₁₂  c₁₃       ⎥
      ⎢───  ───  ───   d₁₁ ⎥
      ⎣ s    s    s        ⎦

So in the above matrix, if it is affine (which is exactly when the `c` entries are 0 and `d` is 1) you can get away with just scaling the last column interpreting `b` as the translation.

But for a general matrix3d you still need a few more divides on the bottom row!

Sidenote: The perspective transform is the only other CSS transform that is non-affine and it gets the zoom division implicitly when the parameter is scaled up since it's in the form of:

  ⎡1  0   0   0⎤
  ⎢            ⎥
  ⎢0  1   0   0⎥
  ⎢            ⎥
  ⎢0  0   1   0⎥
  ⎢            ⎥
  ⎢      -1    ⎥
  ⎢0  0  ───  1⎥
  ⎣       p    ⎦

The reported issue is solved by fixing TransformBuilder as described above. But the same type of bug also appeared in getComputedStyle and animations with matrix3d. I also fixed them in this CL but a longer term solution should probably refactor all them (maybe into TransformOperation::zoom) so that this tricky bit of logic isn't duplicated in so many places.

BUG=242685
R=pdr,alancutter

Review-Url: https://codereview.chromium.org/2482753002
Cr-Commit-Position: refs/heads/master@{#431208}
13 files changed