SVGPaintServer LayoutSVGResourcePattern::preparePaintServer(const LayoutObject& object)
{
    clearInvalidationMask();

    SVGPatternElement* patternElement = toSVGPatternElement(element());
    if (!patternElement)
        return SVGPaintServer::invalid();

    if (m_shouldCollectPatternAttributes) {
        patternElement->synchronizeAnimatedSVGAttribute(anyQName());

#if ENABLE(OILPAN)
        m_attributesWrapper->set(PatternAttributes());
#else
        m_attributes = PatternAttributes();
#endif
        patternElement->collectPatternAttributes(mutableAttributes());
        m_shouldCollectPatternAttributes = false;
    }

    // Spec: When the geometry of the applicable element has no width or height and objectBoundingBox is specified,
    // then the given effect (e.g. a gradient or a filter) will be ignored.
    FloatRect objectBoundingBox = object.objectBoundingBox();
    if (attributes().patternUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX && objectBoundingBox.isEmpty())
        return SVGPaintServer::invalid();

    PatternData* patternData = patternForLayoutObject(object);
    if (!patternData || !patternData->pattern)
        return SVGPaintServer::invalid();

    patternData->pattern->setPatternSpaceTransform(patternData->transform);

    return SVGPaintServer(patternData->pattern);
}
Exemplo n.º 2
0
SVGPaintServer LayoutSVGResourceGradient::preparePaintServer(
    const LayoutObject& object) {
  clearInvalidationMask();

  // Be sure to synchronize all SVG properties on the gradientElement _before_
  // processing any further. Otherwhise the call to collectGradientAttributes()
  // in createTileImage(), may cause the SVG DOM property synchronization to
  // kick in, which causes removeAllClientsFromCache() to be called, which in
  // turn deletes our GradientData object! Leaving out the line below will cause
  // svg/dynamic-updates/SVG*GradientElement-svgdom* to crash.
  SVGGradientElement* gradientElement = toSVGGradientElement(element());
  if (!gradientElement)
    return SVGPaintServer::invalid();

  if (m_shouldCollectGradientAttributes) {
    gradientElement->synchronizeAnimatedSVGAttribute(anyQName());
    if (!collectGradientAttributes(gradientElement))
      return SVGPaintServer::invalid();

    m_shouldCollectGradientAttributes = false;
  }

  // Spec: When the geometry of the applicable element has no width or height
  // and objectBoundingBox is specified, then the given effect (e.g. a gradient
  // or a filter) will be ignored.
  FloatRect objectBoundingBox = object.objectBoundingBox();
  if (gradientUnits() == SVGUnitTypes::kSvgUnitTypeObjectboundingbox &&
      objectBoundingBox.isEmpty())
    return SVGPaintServer::invalid();

  std::unique_ptr<GradientData>& gradientData =
      m_gradientMap.add(&object, nullptr).storedValue->value;
  if (!gradientData)
    gradientData = WTF::wrapUnique(new GradientData);

  // Create gradient object
  if (!gradientData->gradient) {
    gradientData->gradient = buildGradient();

    // We want the text bounding box applied to the gradient space transform
    // now, so the gradient shader can use it.
    if (gradientUnits() == SVGUnitTypes::kSvgUnitTypeObjectboundingbox &&
        !objectBoundingBox.isEmpty()) {
      gradientData->userspaceTransform.translate(objectBoundingBox.x(),
                                                 objectBoundingBox.y());
      gradientData->userspaceTransform.scaleNonUniform(
          objectBoundingBox.width(), objectBoundingBox.height());
    }

    AffineTransform gradientTransform = calculateGradientTransform();
    gradientData->userspaceTransform *= gradientTransform;
  }

  if (!gradientData->gradient)
    return SVGPaintServer::invalid();

  return SVGPaintServer(gradientData->gradient,
                        gradientData->userspaceTransform);
}
void RenderSVGResourceContainer::addClientRenderLayer(Node* node)
{
    ASSERT(node);
    if (!node->renderer() || !node->renderer()->hasLayer())
        return;
    m_clientLayers.add(toRenderLayerModelObject(node->renderer())->layer());
    clearInvalidationMask();
}
bool RenderSVGResourceClipper::applyStatefulResource(RenderObject* object, GraphicsContext*& context, ClipperState& clipperState)
{
    ASSERT(object);
    ASSERT(context);

    clearInvalidationMask();

    return applyClippingToContext(object, object->objectBoundingBox(), object->paintInvalidationRectInLocalCoordinates(), context, clipperState);
}
Exemplo n.º 5
0
void LayoutSVGResourceContainer::layout()
{
    // FIXME: Investigate a way to detect and break resource layout dependency cycles early.
    // Then we can remove this method altogether, and fall back onto LayoutSVGHiddenContainer::layout().
    ASSERT(needsLayout());
    if (m_isInLayout)
        return;

    TemporaryChange<bool> inLayoutChange(m_isInLayout, true);

    LayoutSVGHiddenContainer::layout();

    clearInvalidationMask();
}
Exemplo n.º 6
0
void LayoutSVGResourceMarker::layout() {
  ASSERT(needsLayout());
  if (m_isInLayout)
    return;

  AutoReset<bool> inLayoutChange(&m_isInLayout, true);

  // LayoutSVGHiddenContainer overwrites layout(). We need the
  // layouting of LayoutSVGContainer for calculating  local
  // transformations and paint invalidation.
  LayoutSVGContainer::layout();

  clearInvalidationMask();
}
void RenderSVGResourceMarker::layout()
{
    ASSERT(needsLayout());
    if (m_isInLayout)
        return;

    LayoutRectRecorder recorder(*this);
    TemporaryChange<bool> inLayoutChange(m_isInLayout, true);

    // RenderSVGHiddenContainer overwrites layout(). We need the
    // layouting of RenderSVGContainer for calculating  local
    // transformations and repaint.
    RenderSVGContainer::layout();

    clearInvalidationMask();
}
Exemplo n.º 8
0
bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
{
    ASSERT(object);
    ASSERT(context);
    ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode);

    clearInvalidationMask();

    if (m_filter.contains(object)) {
        FilterData* filterData = m_filter.get(object);
        if (filterData->state == FilterData::PaintingSource)
            filterData->state = FilterData::CycleDetected;
        return false; // Already built, or we're in a cycle. Regardless, just do nothing more now.
    }

    OwnPtr<FilterData> filterData(adoptPtr(new FilterData));
    FloatRect targetBoundingBox = object->objectBoundingBox();

    SVGFilterElement* filterElement = toSVGFilterElement(element());
    filterData->boundaries = SVGLengthContext::resolveRectangle<SVGFilterElement>(filterElement, filterElement->filterUnits()->currentValue()->enumValue(), targetBoundingBox);
    if (filterData->boundaries.isEmpty())
        return false;

    filterData->drawingRegion = object->strokeBoundingBox();
    filterData->drawingRegion.intersect(filterData->boundaries);
    IntRect intDrawingRegion = enclosingIntRect(filterData->drawingRegion);

    // Create the SVGFilter object.
    bool primitiveBoundingBoxMode = filterElement->primitiveUnits()->currentValue()->enumValue() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
    filterData->filter = SVGFilter::create(intDrawingRegion, targetBoundingBox, filterData->boundaries, primitiveBoundingBoxMode);

    // Create all relevant filter primitives.
    filterData->builder = buildPrimitives(filterData->filter.get());
    if (!filterData->builder)
        return false;

    FilterEffect* lastEffect = filterData->builder->lastEffect();
    if (!lastEffect)
        return false;

    lastEffect->determineFilterPrimitiveSubregion(ClipToFilterRegion);

    FilterData* data = filterData.get();
    m_filter.set(object, filterData.release());
    beginDeferredFilter(context, data);
    return true;
}
bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle* style, GraphicsContext*& context, unsigned short resourceMode)
{
    ASSERT(object);
    ASSERT(style);
    ASSERT(context);
    ASSERT(resourceMode != ApplyToDefaultMode);

    clearInvalidationMask();

    // Spec: When the geometry of the applicable element has no width or height and objectBoundingBox is specified,
    // then the given effect (e.g. a gradient or a filter) will be ignored.
    FloatRect objectBoundingBox = object->objectBoundingBox();
    if (m_attributes.patternUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX && objectBoundingBox.isEmpty())
        return false;

    PatternData* patternData = buildPattern(object, resourceMode);
    if (!patternData)
        return false;

    const SVGRenderStyle* svgStyle = style->svgStyle();
    ASSERT(svgStyle);

    AffineTransform computedPatternSpaceTransform = computeResourceSpaceTransform(object, patternData->transform, svgStyle, resourceMode);
    patternData->pattern->setPatternSpaceTransform(computedPatternSpaceTransform);

    // Draw pattern
    context->save();

    if (resourceMode & ApplyToFillMode) {
        context->setAlphaAsFloat(svgStyle->fillOpacity());
        context->setFillPattern(patternData->pattern);
        context->setFillRule(svgStyle->fillRule());
    } else if (resourceMode & ApplyToStrokeMode) {
        context->setAlphaAsFloat(svgStyle->strokeOpacity());
        context->setStrokePattern(patternData->pattern);
        SVGRenderSupport::applyStrokeStyleToContext(context, style, object);
    }

    if (resourceMode & ApplyToTextMode) {
        if (resourceMode & ApplyToFillMode)
            context->setTextDrawingMode(TextModeFill);
        else if (resourceMode & ApplyToStrokeMode)
            context->setTextDrawingMode(TextModeStroke);
    }

    return true;
}
void RenderSVGResourceMarker::draw(PaintInfo& paintInfo, const AffineTransform& transform)
{
    clearInvalidationMask();

    // An empty viewBox disables rendering.
    SVGMarkerElement* marker = toSVGMarkerElement(element());
    ASSERT(marker);
    if (marker->hasAttribute(SVGNames::viewBoxAttr) && marker->viewBox()->currentValue()->isValid() && marker->viewBox()->currentValue()->value().isEmpty())
        return;

    PaintInfo info(paintInfo);
    GraphicsContextStateSaver stateSaver(*info.context, false);
    if (!transform.isIdentity()) {
        stateSaver.save();
        info.applyTransform(transform, false);
    }
    RenderSVGContainer::paint(info, IntPoint());
}
Exemplo n.º 11
0
bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*,
    GraphicsContext*& context, unsigned short resourceMode)
{
    ASSERT(object);
    ASSERT(context);
    ASSERT(style());
    ASSERT_UNUSED(resourceMode, resourceMode == ApplyToDefaultMode);
    ASSERT_WITH_SECURITY_IMPLICATION(!needsLayout());

    clearInvalidationMask();

    FloatRect paintInvalidationRect = object->paintInvalidationRectInLocalCoordinates();
    if (paintInvalidationRect.isEmpty() || !element()->hasChildren())
        return false;

    // Content layer start.
    context->beginTransparencyLayer(1, &paintInvalidationRect);

    return true;
}
Exemplo n.º 12
0
void LayoutSVGResourceContainer::addResourceClient(SVGResourceClient* client)
{
    ASSERT(client);
    m_resourceClients.add(client);
    clearInvalidationMask();
}
Exemplo n.º 13
0
void LayoutSVGResourceContainer::addClient(LayoutObject* client)
{
    ASSERT(client);
    m_clients.add(client);
    clearInvalidationMask();
}
bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle* style, GraphicsContext*& context, unsigned short resourceMode)
{
    ASSERT(object);
    ASSERT(style);
    ASSERT(context);
    ASSERT(resourceMode != ApplyToDefaultMode);

    clearInvalidationMask();

    // Be sure to synchronize all SVG properties on the gradientElement _before_ processing any further.
    // Otherwhise the call to collectGradientAttributes() in createTileImage(), may cause the SVG DOM property
    // synchronization to kick in, which causes removeAllClientsFromCache() to be called, which in turn deletes our
    // GradientData object! Leaving out the line below will cause svg/dynamic-updates/SVG*GradientElement-svgdom* to crash.
    SVGGradientElement* gradientElement = toSVGGradientElement(element());
    if (!gradientElement)
        return false;

    if (m_shouldCollectGradientAttributes) {
        gradientElement->synchronizeAnimatedSVGAttribute(anyQName());
        if (!collectGradientAttributes(gradientElement))
            return false;

        m_shouldCollectGradientAttributes = false;
    }

    // Spec: When the geometry of the applicable element has no width or height and objectBoundingBox is specified,
    // then the given effect (e.g. a gradient or a filter) will be ignored.
    FloatRect objectBoundingBox = object->objectBoundingBox();
    if (gradientUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX && objectBoundingBox.isEmpty())
        return false;

    OwnPtr<GradientData>& gradientData = m_gradientMap.add(object, nullptr).storedValue->value;
    if (!gradientData)
        gradientData = adoptPtr(new GradientData);

    // Create gradient object
    if (!gradientData->gradient) {
        buildGradient(gradientData.get());

        // We want the text bounding box applied to the gradient space transform now, so the gradient shader can use it.
        if (gradientUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX && !objectBoundingBox.isEmpty()) {
            gradientData->userspaceTransform.translate(objectBoundingBox.x(), objectBoundingBox.y());
            gradientData->userspaceTransform.scaleNonUniform(objectBoundingBox.width(), objectBoundingBox.height());
        }

        AffineTransform gradientTransform;
        calculateGradientTransform(gradientTransform);

        gradientData->userspaceTransform *= gradientTransform;
    }

    if (!gradientData->gradient)
        return false;

    const SVGRenderStyle* svgStyle = style->svgStyle();
    ASSERT(svgStyle);

    AffineTransform computedGradientSpaceTransform = computeResourceSpaceTransform(object, gradientData->userspaceTransform, svgStyle, resourceMode);
    gradientData->gradient->setGradientSpaceTransform(computedGradientSpaceTransform);

    // Draw gradient
    context->save();

    if (resourceMode & ApplyToTextMode)
        context->setTextDrawingMode(resourceMode & ApplyToFillMode ? TextModeFill : TextModeStroke);

    if (resourceMode & ApplyToFillMode) {
        context->setAlphaAsFloat(svgStyle->fillOpacity());
        context->setFillGradient(gradientData->gradient);
        context->setFillRule(svgStyle->fillRule());
    } else if (resourceMode & ApplyToStrokeMode) {
        context->setAlphaAsFloat(svgStyle->strokeOpacity());
        context->setStrokeGradient(gradientData->gradient);
        SVGRenderSupport::applyStrokeStyleToContext(context, style, object);
    }

    return true;
}
Exemplo n.º 15
0
void RenderSVGResourceContainer::addClientRenderLayer(RenderLayer* client)
{
    ASSERT(client);
    m_clientLayers.add(client);
    clearInvalidationMask();
}
Exemplo n.º 16
0
void RenderSVGResourceContainer::addClient(RenderObject* client)
{
    ASSERT(client);
    m_clients.add(client);
    clearInvalidationMask();
}