Esempio n. 1
0
void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    // An empty viewport disables rendering.
    if (pixelSnappedBorderBoxRect().isEmpty())
        return;

    // Don't paint, if the context explicitly disabled it.
    if (paintInfo.context->paintingDisabled())
        return;

    // SVG outlines are painted during PaintPhaseForeground.
    if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline)
        return;

    // An empty viewBox also disables rendering.
    // (http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute)
    SVGSVGElement* svg = toSVGSVGElement(node());
    ASSERT(svg);
    if (svg->hasEmptyViewBox())
        return;

    // Don't paint if we don't have kids, except if we have filters we should paint those.
    if (!firstChild()) {
        SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this);
        if (!resources || !resources->filter())
            return;
    }

    // Make a copy of the PaintInfo because applyTransform will modify the damage rect.
    PaintInfo childPaintInfo(paintInfo);
    childPaintInfo.context->save();

    // Apply initial viewport clip
    if (shouldApplyViewportClip())
        childPaintInfo.context->clip(pixelSnappedIntRect(overflowClipRect(paintOffset)));

    // Convert from container offsets (html renderers) to a relative transform (svg renderers).
    // Transform from our paint container's coordinate system to our local coords.
    IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset);
    childPaintInfo.applyTransform(AffineTransform::translation(adjustedPaintOffset.x(), adjustedPaintOffset.y()) * localToBorderBoxTransform());

    // SVGRenderingContext must be destroyed before we restore the childPaintInfo.context, because a filter may have
    // changed the context and it is only reverted when the SVGRenderingContext destructor finishes applying the filter.
    {
        SVGRenderingContext renderingContext;
        bool continueRendering = true;
        if (childPaintInfo.phase == PaintPhaseForeground) {
            renderingContext.prepareToRenderSVGContent(this, childPaintInfo);
            continueRendering = renderingContext.isRenderingPrepared();
        }

        if (continueRendering)
            RenderBox::paint(childPaintInfo, LayoutPoint());
    }

    childPaintInfo.context->restore();
}
Esempio n. 2
0
void SVGRootPainter::paintReplaced(const PaintInfo& paintInfo,
                                   const LayoutPoint& paintOffset) {
  // An empty viewport disables rendering.
  if (pixelSnappedSize(paintOffset).isEmpty())
    return;

  // SVG outlines are painted during PaintPhaseForeground.
  if (shouldPaintSelfOutline(paintInfo.phase))
    return;

  // An empty viewBox also disables rendering.
  // (http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute)
  SVGSVGElement* svg = toSVGSVGElement(m_layoutSVGRoot.node());
  DCHECK(svg);
  if (svg->hasEmptyViewBox())
    return;

  // Apply initial viewport clip.
  Optional<BoxClipper> boxClipper;
  if (m_layoutSVGRoot.shouldApplyViewportClip()) {
    // TODO(pdr): Clip the paint info cull rect here.
    boxClipper.emplace(m_layoutSVGRoot, paintInfo, paintOffset,
                       ForceContentsClip);
  }

  PaintInfo paintInfoBeforeFiltering(paintInfo);
  AffineTransform transformToBorderBox =
      transformToPixelSnappedBorderBox(paintOffset);
  paintInfoBeforeFiltering.updateCullRect(transformToBorderBox);
  SVGTransformContext transformContext(paintInfoBeforeFiltering.context,
                                       m_layoutSVGRoot, transformToBorderBox);

  SVGPaintContext paintContext(m_layoutSVGRoot, paintInfoBeforeFiltering);
  if (paintContext.paintInfo().phase == PaintPhaseForeground &&
      !paintContext.applyClipMaskAndFilterIfNecessary())
    return;

  BoxPainter(m_layoutSVGRoot).paint(paintContext.paintInfo(), LayoutPoint());

  PaintTiming& timing =
      PaintTiming::from(m_layoutSVGRoot.node()->document().topDocument());
  timing.markFirstContentfulPaint();
}
void SVGRootPainter::paint(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    // An empty viewport disables rendering.
    if (m_layoutSVGRoot.pixelSnappedBorderBoxRect().isEmpty())
        return;

    // SVG outlines are painted during PaintPhaseForeground.
    if (shouldPaintSelfOutline(paintInfo.phase))
        return;

    // An empty viewBox also disables rendering.
    // (http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute)
    SVGSVGElement* svg = toSVGSVGElement(m_layoutSVGRoot.node());
    ASSERT(svg);
    if (svg->hasEmptyViewBox())
        return;

    // Don't paint if we don't have kids, except if we have filters we should paint those.
    if (!m_layoutSVGRoot.firstChild()) {
        SVGResources* resources = SVGResourcesCache::cachedResourcesForLayoutObject(&m_layoutSVGRoot);
        if (!resources || !resources->filter())
            return;
    }

    PaintInfo paintInfoBeforeFiltering(paintInfo);

    // At the HTML->SVG boundary, SVGRoot will have a paint offset transform
    // paint property but may not have a PaintLayer, so we need to update the
    // paint properties here since they will not be updated by PaintLayer
    // (See: PaintPropertyTreeBuilder::createPaintOffsetTranslationIfNeeded).
    Optional<ScopedPaintChunkProperties> paintOffsetTranslationPropertyScope;
    if (RuntimeEnabledFeatures::slimmingPaintV2Enabled() && !m_layoutSVGRoot.hasLayer()) {
        const auto* objectProperties = m_layoutSVGRoot.objectPaintProperties();
        if (objectProperties && objectProperties->paintOffsetTranslation()) {
            auto& paintController = paintInfoBeforeFiltering.context.paintController();
            PaintChunkProperties properties(paintController.currentPaintChunkProperties());
            properties.transform = objectProperties->paintOffsetTranslation();
            paintOffsetTranslationPropertyScope.emplace(paintController, properties);
        }
    }

    // Apply initial viewport clip.
    Optional<ClipRecorder> clipRecorder;
    if (m_layoutSVGRoot.shouldApplyViewportClip()) {
        // TODO(pdr): Clip the paint info cull rect here.
        clipRecorder.emplace(paintInfoBeforeFiltering.context, m_layoutSVGRoot, paintInfoBeforeFiltering.displayItemTypeForClipping(), LayoutRect(pixelSnappedIntRect(m_layoutSVGRoot.overflowClipRect(paintOffset))));
    }

    // Convert from container offsets (html layoutObjects) to a relative transform (svg layoutObjects).
    // Transform from our paint container's coordinate system to our local coords.
    IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset);
    AffineTransform paintOffsetToBorderBox = AffineTransform::translation(adjustedPaintOffset.x(), adjustedPaintOffset.y()) * m_layoutSVGRoot.localToBorderBoxTransform();
    paintInfoBeforeFiltering.updateCullRect(paintOffsetToBorderBox);
    TransformRecorder transformRecorder(paintInfoBeforeFiltering.context, m_layoutSVGRoot, paintOffsetToBorderBox);

    SVGPaintContext paintContext(m_layoutSVGRoot, paintInfoBeforeFiltering);
    if (paintContext.paintInfo().phase == PaintPhaseForeground && !paintContext.applyClipMaskAndFilterIfNecessary())
        return;

    BoxPainter(m_layoutSVGRoot).paint(paintContext.paintInfo(), LayoutPoint());

    PaintTiming& timing = PaintTiming::from(m_layoutSVGRoot.node()->document().topDocument());
    timing.markFirstContentfulPaint();
}