void RenderSVGResourceMasker::drawMaskForRenderer(GraphicsContext* context, const FloatRect& targetBoundingBox)
{
    ASSERT(context);

    AffineTransform contentTransformation;
    SVGUnitTypes::SVGUnitType contentUnits = toSVGMaskElement(element())->maskContentUnits()->currentValue()->enumValue();
    if (contentUnits == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
        contentTransformation.translate(targetBoundingBox.x(), targetBoundingBox.y());
        contentTransformation.scaleNonUniform(targetBoundingBox.width(), targetBoundingBox.height());
        context->concatCTM(contentTransformation);
    }

    if (!m_maskContentDisplayList)
        m_maskContentDisplayList = asDisplayList(context, contentTransformation);
    ASSERT(m_maskContentDisplayList);
    context->drawDisplayList(m_maskContentDisplayList.get());
}
PassOwnPtr<PatternData> RenderSVGResourcePattern::buildPatternData(const RenderObject& object)
{
    // If we couldn't determine the pattern content element root, stop here.
    if (!m_attributes.patternContentElement())
        return nullptr;

    // An empty viewBox disables rendering.
    if (m_attributes.hasViewBox() && m_attributes.viewBox().isEmpty())
        return nullptr;

    ASSERT(element());
    // Compute tile metrics.
    FloatRect clientBoundingBox = object.objectBoundingBox();
    FloatRect tileBounds = SVGLengthContext::resolveRectangle(element(),
        m_attributes.patternUnits(), clientBoundingBox,
        m_attributes.x(), m_attributes.y(), m_attributes.width(), m_attributes.height());
    if (tileBounds.isEmpty())
        return nullptr;

    AffineTransform tileTransform;
    if (m_attributes.hasViewBox()) {
        if (m_attributes.viewBox().isEmpty())
            return nullptr;
        tileTransform = SVGFitToViewBox::viewBoxToViewTransform(m_attributes.viewBox(),
            m_attributes.preserveAspectRatio(), tileBounds.width(), tileBounds.height());
    } else {
        // A viewbox overrides patternContentUnits, per spec.
        if (m_attributes.patternContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
            tileTransform.scale(clientBoundingBox.width(), clientBoundingBox.height());
    }

    OwnPtr<PatternData> patternData = adoptPtr(new PatternData);
    patternData->pattern = Pattern::createDisplayListPattern(asDisplayList(tileBounds, tileTransform));

    // Compute pattern space transformation.
    patternData->transform.translate(tileBounds.x(), tileBounds.y());
    AffineTransform patternTransform = m_attributes.patternTransform();
    if (!patternTransform.isIdentity())
        patternData->transform = patternTransform * patternData->transform;

    return patternData.release();
}