void SVGShapePainter::paintMarkers(const PaintInfo& paintInfo, const FloatRect& boundingBox)
{
    const Vector<MarkerPosition>* markerPositions = m_layoutSVGShape.markerPositions();
    if (!markerPositions || markerPositions->isEmpty())
        return;

    SVGResources* resources = SVGResourcesCache::cachedResourcesForLayoutObject(&m_layoutSVGShape);
    if (!resources)
        return;

    LayoutSVGResourceMarker* markerStart = resources->markerStart();
    LayoutSVGResourceMarker* markerMid = resources->markerMid();
    LayoutSVGResourceMarker* markerEnd = resources->markerEnd();
    if (!markerStart && !markerMid && !markerEnd)
        return;

    float strokeWidth = m_layoutSVGShape.strokeWidth();
    unsigned size = markerPositions->size();

    for (unsigned i = 0; i < size; ++i) {
        if (LayoutSVGResourceMarker* marker = SVGMarkerData::markerForType((*markerPositions)[i].type, markerStart, markerMid, markerEnd)) {
            SkPictureBuilder pictureBuilder(boundingBox, nullptr, &paintInfo.context);
            PaintInfo markerPaintInfo(pictureBuilder.context(), paintInfo);

            // It's expensive to track the transformed paint cull rect for each
            // marker so just disable culling. The shape paint call will already
            // be culled if it is outside the paint info cull rect.
            markerPaintInfo.m_cullRect.m_rect = LayoutRect::infiniteIntRect();

            paintMarker(markerPaintInfo, *marker, (*markerPositions)[i], strokeWidth);
            pictureBuilder.endRecording()->playback(paintInfo.context.canvas());
        }
    }
}
PassRefPtr<SkPicture> LayoutSVGResourcePattern::asPicture(const FloatRect& tileBounds,
    const AffineTransform& tileTransform) const
{
    ASSERT(!m_shouldCollectPatternAttributes);

    AffineTransform contentTransform;
    if (attributes().patternContentUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX)
        contentTransform = tileTransform;

    FloatRect bounds(FloatPoint(), tileBounds.size());
    SkPictureBuilder pictureBuilder(bounds);

    const LayoutSVGResourceContainer* patternLayoutObject = resolveContentElement();
    ASSERT(patternLayoutObject && !patternLayoutObject->needsLayout());

    SubtreeContentTransformScope contentTransformScope(contentTransform);

    {
        TransformRecorder transformRecorder(pictureBuilder.context(), *patternLayoutObject, tileTransform);
        for (LayoutObject* child = patternLayoutObject->firstChild(); child; child = child->nextSibling())
            SVGPaintContext::paintSubtree(pictureBuilder.context(), child);
    }

    return pictureBuilder.endRecording();
}
Ejemplo n.º 3
0
sk_sp<const SkPicture> LayoutSVGResourceClipper::createContentPicture() {
  ASSERT(frame());
  if (m_clipContentPicture)
    return m_clipContentPicture;

  // Using strokeBoundingBox (instead of visualRectInLocalSVGCoordinates) to
  // avoid the intersection with local clips/mask, which may yield incorrect
  // results when mixing objectBoundingBox and userSpaceOnUse units
  // (http://crbug.com/294900).
  FloatRect bounds = strokeBoundingBox();

  SkPictureBuilder pictureBuilder(bounds, nullptr, nullptr);
  // Switch to a paint behavior where all children of this <clipPath> will be
  // laid out using special constraints:
  // - fill-opacity/stroke-opacity/opacity set to 1
  // - masker/filter not applied when laying out the children
  // - fill is set to the initial fill paint server (solid, black)
  // - stroke is set to the initial stroke paint server (none)
  PaintInfo info(pictureBuilder.context(), LayoutRect::infiniteIntRect(),
                 PaintPhaseForeground, GlobalPaintNormalPhase,
                 PaintLayerPaintingRenderingClipPathAsMask);

  for (const SVGElement& childElement :
       Traversal<SVGElement>::childrenOf(*element())) {
    if (!contributesToClip(childElement))
      continue;
    // Use the LayoutObject of the direct child even if it is a <use>. In that
    // case, we will paint the targeted element indirectly.
    const LayoutObject* layoutObject = childElement.layoutObject();
    layoutObject->paint(info, IntPoint());
  }

  m_clipContentPicture = pictureBuilder.endRecording();
  return m_clipContentPicture;
}
 void printSinglePage(SkCanvas& canvas)
 {
     IntRect pageRect(0, 0, kPageWidth, kPageHeight);
     printContext().begin(pageRect.width(), pageRect.height());
     document().view()->updateAllLifecyclePhases();
     SkPictureBuilder pictureBuilder(pageRect);
     GraphicsContext& context = pictureBuilder.context();
     context.setPrinting(true);
     document().view()->paintContents(&context, GlobalPaintPrinting, pageRect);
     pictureBuilder.endRecording()->playback(&canvas);
     printContext().outputLinkedDestinations(&canvas, pageRect);
     printContext().end();
 }
Ejemplo n.º 5
0
sk_sp<const SkPicture> LayoutSVGResourceMasker::createContentPicture(
    AffineTransform& contentTransformation,
    const FloatRect& targetBoundingBox,
    GraphicsContext& context) {
    SVGUnitTypes::SVGUnitType contentUnits = toSVGMaskElement(element())
            ->maskContentUnits()
            ->currentValue()
            ->enumValue();
    if (contentUnits == SVGUnitTypes::kSvgUnitTypeObjectboundingbox) {
        contentTransformation.translate(targetBoundingBox.x(),
                                        targetBoundingBox.y());
        contentTransformation.scaleNonUniform(targetBoundingBox.width(),
                                              targetBoundingBox.height());
    }

    if (m_maskContentPicture)
        return m_maskContentPicture;

    SubtreeContentTransformScope contentTransformScope(contentTransformation);

    // Using strokeBoundingBox instead of visualRectInLocalCoordinates
    // to avoid the intersection with local clips/mask, which may yield incorrect
    // results when mixing objectBoundingBox and userSpaceOnUse units.
    // http://crbug.com/294900
    FloatRect bounds = strokeBoundingBox();

    SkPictureBuilder pictureBuilder(bounds, nullptr, &context);

    ColorFilter maskContentFilter =
        style()->svgStyle().colorInterpolation() == CI_LINEARRGB
        ? ColorFilterSRGBToLinearRGB
        : ColorFilterNone;
    pictureBuilder.context().setColorFilter(maskContentFilter);

    for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element());
            childElement;
            childElement = Traversal<SVGElement>::nextSibling(*childElement)) {
        LayoutObject* layoutObject = childElement->layoutObject();
        if (!layoutObject)
            continue;
        const ComputedStyle* style = layoutObject->style();
        if (!style || style->display() == EDisplay::None ||
                style->visibility() != EVisibility::Visible)
            continue;

        SVGPaintContext::paintSubtree(pictureBuilder.context(), layoutObject);
    }

    m_maskContentPicture = pictureBuilder.endRecording();
    return m_maskContentPicture;
}
void InspectorLayerTreeAgent::makeSnapshot(ErrorString* errorString, const String& layerId, String* snapshotId)
{
    GraphicsLayer* layer = layerById(errorString, layerId);
    if (!layer)
        return;

    IntSize size = expandedIntSize(layer->size());

    SkPictureBuilder pictureBuilder(FloatRect(0, 0, size.width(), size.height()));
    layer->paint(pictureBuilder.context(), IntRect(IntPoint(0, 0), size));

    RefPtr<PictureSnapshot> snapshot = adoptRef(new PictureSnapshot(pictureBuilder.endRecording()));

    *snapshotId = String::number(++s_lastSnapshotId);
    bool newEntry = m_snapshotById.add(*snapshotId, snapshot).isNewEntry;
    ASSERT_UNUSED(newEntry, newEntry);
}
Ejemplo n.º 7
0
void WebFont::drawText(WebCanvas* canvas, const WebTextRun& run,
    const WebFloatPoint& leftBaseline, WebColor color, const WebRect& clip) const
{
    FontCachePurgePreventer fontCachePurgePreventer;
    FloatRect textClipRect(clip);
    TextRun textRun(run);
    TextRunPaintInfo runInfo(textRun);
    runInfo.bounds = textClipRect;

    IntRect intRect(clip);
    SkPictureBuilder pictureBuilder(intRect);
    GraphicsContext& context = pictureBuilder.context();

    {
        DrawingRecorder drawingRecorder(context, pictureBuilder, DisplayItem::WebFont, intRect);
        context.save();
        context.setFillColor(color);
        context.clip(textClipRect);
        context.drawText(m_private->getFont(), runInfo, leftBaseline);
        context.restore();
    }

    pictureBuilder.endRecording()->playback(canvas);
}
PassRefPtr<const SkPicture> LayoutSVGResourceClipper::createContentPicture(AffineTransform& contentTransformation, const FloatRect& targetBoundingBox,
    GraphicsContext& context)
{
    ASSERT(frame());

    if (clipPathUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) {
        contentTransformation.translate(targetBoundingBox.x(), targetBoundingBox.y());
        contentTransformation.scaleNonUniform(targetBoundingBox.width(), targetBoundingBox.height());
    }

    if (m_clipContentPicture)
        return m_clipContentPicture;

    SubtreeContentTransformScope contentTransformScope(contentTransformation);

    // Using strokeBoundingBox (instead of paintInvalidationRectInLocalCoordinates) to avoid the intersection
    // with local clips/mask, which may yield incorrect results when mixing objectBoundingBox and
    // userSpaceOnUse units (http://crbug.com/294900).
    FloatRect bounds = strokeBoundingBox();

    SkPictureBuilder pictureBuilder(bounds, nullptr, &context);

    for (SVGElement* childElement = Traversal<SVGElement>::firstChild(*element()); childElement; childElement = Traversal<SVGElement>::nextSibling(*childElement)) {
        LayoutObject* layoutObject = childElement->layoutObject();
        if (!layoutObject)
            continue;

        const ComputedStyle* style = layoutObject->style();
        if (!style || style->display() == NONE || style->visibility() != VISIBLE)
            continue;

        bool isUseElement = isSVGUseElement(*childElement);
        if (isUseElement) {
            const SVGGraphicsElement* clippingElement = toSVGUseElement(*childElement).targetGraphicsElementForClipping();
            if (!clippingElement)
                continue;

            layoutObject = clippingElement->layoutObject();
            if (!layoutObject)
                continue;
        }

        // Only shapes, paths and texts are allowed for clipping.
        if (!layoutObject->isSVGShape() && !layoutObject->isSVGText())
            continue;

        if (isUseElement)
            layoutObject = childElement->layoutObject();

        // Switch to a paint behavior where all children of this <clipPath> will be laid out using special constraints:
        // - fill-opacity/stroke-opacity/opacity set to 1
        // - masker/filter not applied when laying out the children
        // - fill is set to the initial fill paint server (solid, black)
        // - stroke is set to the initial stroke paint server (none)
        PaintInfo info(pictureBuilder.context(), LayoutRect::infiniteIntRect(), PaintPhaseForeground, GlobalPaintNormalPhase, PaintLayerPaintingRenderingClipPathAsMask);
        layoutObject->paint(info, IntPoint());
    }

    m_clipContentPicture = pictureBuilder.endRecording();
    return m_clipContentPicture;
}