FloatPoint TransformationMatrix::mapPoint(const FloatPoint& p) const { if (isIdentityOrTranslation()) return FloatPoint(p.x() + static_cast<float>(m_matrix[3][0]), p.y() + static_cast<float>(m_matrix[3][1])); double x, y; multVecMatrix(p.x(), p.y(), x, y); return FloatPoint(static_cast<float>(x), static_cast<float>(y)); }
FloatRect TransformationMatrix::mapRect(const FloatRect& r) const { if (isIdentityOrTranslation()) { FloatRect mappedRect(r); mappedRect.move(static_cast<float>(m_matrix[3][0]), static_cast<float>(m_matrix[3][1])); return mappedRect; } FloatQuad resultQuad = mapQuad(FloatQuad(r)); return resultQuad.boundingBox(); }
// *this = *this * translation AffineTransform& AffineTransform::translate(double tx, double ty) { if (isIdentityOrTranslation()) { m_transform[4] += tx; m_transform[5] += ty; return *this; } m_transform[4] += tx * m_transform[0] + ty * m_transform[2]; m_transform[5] += tx * m_transform[1] + ty * m_transform[3]; return *this; }
bool TransformationMatrix::isInvertible() const { if (isIdentityOrTranslation()) return true; double det = WebCore::determinant4x4(m_matrix); if (fabs(det) < SMALL_NUMBER) return false; return true; }
FloatQuad AffineTransform::mapQuad(const FloatQuad& q) const { if (isIdentityOrTranslation()) { FloatQuad mappedQuad(q); mappedQuad.move(narrowPrecisionToFloat(m_transform[4]), narrowPrecisionToFloat(m_transform[5])); return mappedQuad; } FloatQuad result; result.setP1(mapPoint(q.p1())); result.setP2(mapPoint(q.p2())); result.setP3(mapPoint(q.p3())); result.setP4(mapPoint(q.p4())); return result; }
FloatRect AffineTransform::mapRect(const FloatRect& rect) const { if (isIdentityOrTranslation()) { FloatRect mappedRect(rect); mappedRect.move(narrowPrecisionToFloat(m_transform[4]), narrowPrecisionToFloat(m_transform[5])); return mappedRect; } FloatQuad result; result.setP1(mapPoint(rect.location())); result.setP2(mapPoint(FloatPoint(rect.right(), rect.y()))); result.setP3(mapPoint(FloatPoint(rect.right(), rect.bottom()))); result.setP4(mapPoint(FloatPoint(rect.x(), rect.bottom()))); return result.boundingBox(); }
FloatQuad TransformationMatrix::mapQuad(const FloatQuad& q) const { if (isIdentityOrTranslation()) { FloatQuad mappedQuad(q); mappedQuad.move(static_cast<float>(m_matrix[3][0]), static_cast<float>(m_matrix[3][1])); return mappedQuad; } FloatQuad result; result.setP1(mapPoint(q.p1())); result.setP2(mapPoint(q.p2())); result.setP3(mapPoint(q.p3())); result.setP4(mapPoint(q.p4())); return result; }
TransformationMatrix TransformationMatrix::inverse() const { if (isIdentityOrTranslation()) { // identity matrix if (m_matrix[3][0] == 0 && m_matrix[3][1] == 0 && m_matrix[3][2] == 0) return TransformationMatrix(); // translation return TransformationMatrix(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -m_matrix[3][0], -m_matrix[3][1], -m_matrix[3][2], 1); } TransformationMatrix invMat; bool inverted = WebCore::inverse(m_matrix, invMat.m_matrix); if (!inverted) return TransformationMatrix(); return invMat; }
AffineTransform AffineTransform::inverse() const { double determinant = det(); if (determinant == 0.0) return AffineTransform(); AffineTransform result; if (isIdentityOrTranslation()) { result.m_transform[4] = -m_transform[4]; result.m_transform[5] = -m_transform[5]; return result; } result.m_transform[0] = m_transform[3] / determinant; result.m_transform[1] = -m_transform[1] / determinant; result.m_transform[2] = -m_transform[2] / determinant; result.m_transform[3] = m_transform[0] / determinant; result.m_transform[4] = (m_transform[2] * m_transform[5] - m_transform[3] * m_transform[4]) / determinant; result.m_transform[5] = (m_transform[1] * m_transform[4] - m_transform[0] * m_transform[5]) / determinant; return result; }