Пример #1
0
GraphicsContext* SVGFilterPainter::prepareEffect(
    const LayoutObject& object,
    SVGFilterRecordingContext& recordingContext) {
  m_filter.clearInvalidationMask();

  if (FilterData* filterData = m_filter.getFilterDataForLayoutObject(&object)) {
    // If the filterData already exists we do not need to record the content
    // to be filtered. This can occur if the content was previously recorded
    // or we are in a cycle.
    if (filterData->m_state == FilterData::PaintingFilter)
      filterData->m_state = FilterData::PaintingFilterCycleDetected;

    if (filterData->m_state == FilterData::RecordingContent)
      filterData->m_state = FilterData::RecordingContentCycleDetected;

    return nullptr;
  }

  SVGFilterGraphNodeMap* nodeMap = SVGFilterGraphNodeMap::create();
  FilterEffectBuilder builder(nullptr, object.objectBoundingBox(), 1);
  Filter* filter = builder.buildReferenceFilter(
      toSVGFilterElement(*m_filter.element()), nullptr, nodeMap);
  if (!filter || !filter->lastEffect())
    return nullptr;

  IntRect sourceRegion = enclosingIntRect(
      intersection(filter->filterRegion(), object.strokeBoundingBox()));
  filter->getSourceGraphic()->setSourceRect(sourceRegion);

  FilterData* filterData = FilterData::create();
  filterData->lastEffect = filter->lastEffect();
  filterData->nodeMap = nodeMap;

  // TODO(pdr): Can this be moved out of painter?
  m_filter.setFilterDataForLayoutObject(const_cast<LayoutObject*>(&object),
                                        filterData);
  return recordingContext.beginContent(filterData);
}
Пример #2
0
void SVGFilterRecordingContext::endContent(FilterData* filterData) {
  DCHECK_EQ(filterData->m_state, FilterData::RecordingContent);

  Filter* filter = filterData->lastEffect->getFilter();
  SourceGraphic* sourceGraphic = filter->getSourceGraphic();
  DCHECK(sourceGraphic);

  // Use the context that contains the filtered content.
  DCHECK(m_paintController);
  DCHECK(m_context);
  m_context->beginRecording(filter->filterRegion());
  m_paintController->commitNewDisplayItems();
  m_paintController->paintArtifact().replay(*m_context);

  SkiaImageFilterBuilder::buildSourceGraphic(sourceGraphic,
                                             m_context->endRecording());

  // Content is cached by the source graphic so temporaries can be freed.
  m_paintController = nullptr;
  m_context = nullptr;

  filterData->m_state = FilterData::ReadyToPaint;
}