Example #1
0
static void paintFilteredContent(GraphicsContext& context,
                                 const LayoutObject& object,
                                 FilterData* filterData) {
  if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(
          context, object, DisplayItem::kSVGFilter))
    return;

  FloatRect filterBounds =
      filterData ? filterData->lastEffect->getFilter()->filterRegion()
                 : FloatRect();
  LayoutObjectDrawingRecorder recorder(context, object, DisplayItem::kSVGFilter,
                                       filterBounds);
  if (!filterData || filterData->m_state != FilterData::ReadyToPaint)
    return;
  DCHECK(filterData->lastEffect->getFilter()->getSourceGraphic());

  filterData->m_state = FilterData::PaintingFilter;

  FilterEffect* lastEffect = filterData->lastEffect;
  sk_sp<SkImageFilter> imageFilter =
      SkiaImageFilterBuilder::build(lastEffect, ColorSpaceDeviceRGB);
  context.save();

  // Clip drawing of filtered image to the minimum required paint rect.
  context.clipRect(lastEffect->mapRect(object.strokeBoundingBox()));

  context.beginLayer(1, SkBlendMode::kSrcOver, &filterBounds, ColorFilterNone,
                     std::move(imageFilter));
  context.endLayer();
  context.restore();

  filterData->m_state = FilterData::ReadyToPaint;
}
void BeginFilterDisplayItem::replay(GraphicsContext& context) const
{
    FloatRect imageFilterBounds(FloatPoint(), m_bounds.size());
    context.save();
    context.translate(m_bounds.x(), m_bounds.y());
    context.beginLayer(1, SkXfermode::kSrcOver_Mode, &imageFilterBounds, ColorFilterNone, m_imageFilter.get());
    context.translate(-m_bounds.x(), -m_bounds.y());
}
void InlinePainter::paintOutline(const PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
    const ComputedStyle& styleToUse = m_layoutInline.styleRef();
    if (!styleToUse.hasOutline())
        return;

    if (styleToUse.outlineStyleIsAuto()) {
        if (!LayoutTheme::theme().shouldDrawDefaultFocusRing(&m_layoutInline))
            return;
        if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(*paintInfo.context, m_layoutInline, paintInfo.phase))
            return;

        Vector<LayoutRect> focusRingRects;
        m_layoutInline.addOutlineRects(focusRingRects, paintOffset);

        LayoutObjectDrawingRecorder recorder(*paintInfo.context, m_layoutInline, paintInfo.phase, outlinePaintRect(focusRingRects, LayoutPoint()));
        // Only paint the focus ring by hand if the theme isn't able to draw the focus ring.
        ObjectPainter(m_layoutInline).paintFocusRing(paintInfo, styleToUse, focusRingRects);
        return;
    }

    if (styleToUse.outlineStyle() == BNONE)
        return;

    GraphicsContext* graphicsContext = paintInfo.context;
    if (LayoutObjectDrawingRecorder::useCachedDrawingIfPossible(*graphicsContext, m_layoutInline, paintInfo.phase))
        return;

    Vector<LayoutRect> rects;

    rects.append(LayoutRect());
    for (InlineFlowBox* curr = m_layoutInline.firstLineBox(); curr; curr = curr->nextLineBox()) {
        RootInlineBox& root = curr->root();
        LayoutUnit top = std::max<LayoutUnit>(root.lineTop(), curr->logicalTop());
        LayoutUnit bottom = std::min<LayoutUnit>(root.lineBottom(), curr->logicalBottom());
        rects.append(LayoutRect(curr->x(), top, curr->logicalWidth(), bottom - top));
    }
    rects.append(LayoutRect());

    Color outlineColor = m_layoutInline.resolveColor(styleToUse, CSSPropertyOutlineColor);
    bool useTransparencyLayer = outlineColor.hasAlpha();

    LayoutObjectDrawingRecorder recorder(*graphicsContext, m_layoutInline, paintInfo.phase, outlinePaintRect(rects, paintOffset));
    if (useTransparencyLayer) {
        graphicsContext->beginLayer(static_cast<float>(outlineColor.alpha()) / 255);
        outlineColor = Color(outlineColor.red(), outlineColor.green(), outlineColor.blue());
    }

    for (unsigned i = 1; i < rects.size() - 1; i++)
        paintOutlineForLine(graphicsContext, paintOffset, rects.at(i - 1), rects.at(i), rects.at(i + 1), outlineColor);

    if (useTransparencyLayer)
        graphicsContext->endLayer();
}
bool MediaControlsPainter::paintMediaSlider(const LayoutObject& object, const PaintInfo& paintInfo, const IntRect& rect)
{
    const HTMLMediaElement* mediaElement = toParentMediaElement(object);
    if (!mediaElement)
        return false;

    GraphicsContext* context = paintInfo.context;

    // Should we paint the slider partially transparent?
    bool drawUiGrayed = !hasSource(mediaElement) && RuntimeEnabledFeatures::newMediaPlaybackUiEnabled();
    if (drawUiGrayed)
        context->beginLayer(kDisabledAlpha);

    paintMediaSliderInternal(object, paintInfo, rect);

    if (drawUiGrayed)
        context->endLayer();

    return true;
}
static void paintFilteredContent(const LayoutObject& object, GraphicsContext& context, FilterData* filterData)
{
    ASSERT(filterData->m_state == FilterData::ReadyToPaint);
    ASSERT(filterData->filter->sourceGraphic());

    filterData->m_state = FilterData::PaintingFilter;

    SkiaImageFilterBuilder builder;
    RefPtr<SkImageFilter> imageFilter = builder.build(filterData->filter->lastEffect(), ColorSpaceDeviceRGB);
    FloatRect boundaries = filterData->filter->filterRegion();
    context.save();

    // Clip drawing of filtered image to the minimum required paint rect.
    FilterEffect* lastEffect = filterData->filter->lastEffect();
    context.clipRect(lastEffect->determineAbsolutePaintRect(lastEffect->maxEffectRect()));

#ifdef CHECK_CTM_FOR_TRANSFORMED_IMAGEFILTER
    // TODO: Remove this workaround once skew/rotation support is added in Skia
    // (https://code.google.com/p/skia/issues/detail?id=3288, crbug.com/446935).
    // If the CTM contains rotation or shearing, apply the filter to
    // the unsheared/unrotated matrix, and do the shearing/rotation
    // as a final pass.
    AffineTransform ctm = SVGLayoutSupport::deprecatedCalculateTransformToLayer(&object);
    if (ctm.b() || ctm.c()) {
        AffineTransform scaleAndTranslate;
        scaleAndTranslate.translate(ctm.e(), ctm.f());
        scaleAndTranslate.scale(ctm.xScale(), ctm.yScale());
        ASSERT(scaleAndTranslate.isInvertible());
        AffineTransform shearAndRotate = scaleAndTranslate.inverse();
        shearAndRotate.multiply(ctm);
        context.concatCTM(shearAndRotate.inverse());
        imageFilter = builder.buildTransform(shearAndRotate, imageFilter.get());
    }
#endif

    context.beginLayer(1, SkXfermode::kSrcOver_Mode, &boundaries, ColorFilterNone, imageFilter.get());
    context.endLayer();
    context.restore();

    filterData->m_state = FilterData::ReadyToPaint;
}
void BeginCompositingDisplayItem::replay(GraphicsContext& context) const
{
    context.beginLayer(m_opacity, m_xferMode, m_hasBounds ? &m_bounds : nullptr, m_colorFilter);
}