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); }