PassRefPtr<PictureSnapshot> PictureSnapshot::load(const Vector<RefPtr<TilePictureStream>>& tiles) { ASSERT(!tiles.isEmpty()); Vector<sk_sp<SkPicture>> pictures; pictures.reserveCapacity(tiles.size()); FloatRect unionRect; for (const auto& tileStream : tiles) { SkMemoryStream stream(tileStream->data.begin(), tileStream->data.size()); sk_sp<SkPicture> picture = SkPicture::MakeFromStream(&stream, decodeBitmap); if (!picture) return nullptr; FloatRect cullRect(picture->cullRect()); cullRect.moveBy(tileStream->layerOffset); unionRect.unite(cullRect); pictures.append(std::move(picture)); } if (tiles.size() == 1) return adoptRef(new PictureSnapshot(fromSkSp(std::move(pictures[0])))); SkPictureRecorder recorder; SkCanvas* canvas = recorder.beginRecording(unionRect.width(), unionRect.height(), 0, 0); for (size_t i = 0; i < pictures.size(); ++i) { canvas->save(); canvas->translate(tiles[i]->layerOffset.x() - unionRect.x(), tiles[i]->layerOffset.y() - unionRect.y()); pictures[i]->playback(canvas, 0); canvas->restore(); } return adoptRef(new PictureSnapshot(fromSkSp(recorder.finishRecordingAsPicture()))); }
PassRefPtr<SkImageFilter> FEBlend::createImageFilter(SkiaImageFilterBuilder& builder) { RefPtr<SkImageFilter> foreground(builder.build(inputEffect(0), operatingColorSpace())); RefPtr<SkImageFilter> background(builder.build(inputEffect(1), operatingColorSpace())); sk_sp<SkXfermode> mode(SkXfermode::Make(WebCoreCompositeToSkiaComposite(CompositeSourceOver, m_mode))); SkImageFilter::CropRect cropRect = getCropRect(); return fromSkSp(SkXfermodeImageFilter::Make(std::move(mode), background.get(), foreground.get(), &cropRect)); }
PassRefPtr<SkColorFilter> createColorSpaceFilter(ColorSpace srcColorSpace, ColorSpace dstColorSpace) { const uint8_t* lookupTable = getConversionLUT(dstColorSpace, srcColorSpace); if (!lookupTable) return nullptr; return fromSkSp(SkTableColorFilter::MakeARGB(0, lookupTable, lookupTable, lookupTable)); }
PassRefPtr<SkPicture> TestPaintArtifact::DummyRectClient::makePicture() const { SkPictureRecorder recorder; SkCanvas* canvas = recorder.beginRecording(m_rect); SkPaint paint; paint.setColor(m_color.rgb()); canvas->drawRect(m_rect, paint); return fromSkSp(recorder.finishRecordingAsPicture()); }
std::unique_ptr<Vector<char>> PictureSnapshot::replay(unsigned fromStep, unsigned toStep, double scale) const { const SkIRect bounds = m_picture->cullRect().roundOut(); // TODO(fmalita): convert this to SkSurface/SkImage, drop the intermediate SkBitmap. SkBitmap bitmap; bitmap.allocPixels(SkImageInfo::MakeN32Premul(bounds.width(), bounds.height())); bitmap.eraseARGB(0, 0, 0, 0); { ReplayingCanvas canvas(bitmap, fromStep, toStep); // Disable LCD text preemptively, because the picture opacity is unknown. // The canonical API involves SkSurface props, but since we're not SkSurface-based // at this point (see TODO above) we (ab)use saveLayer for this purpose. SkAutoCanvasRestore autoRestore(&canvas, false); canvas.saveLayer(nullptr, nullptr); canvas.scale(scale, scale); canvas.resetStepCount(); m_picture->playback(&canvas, &canvas); } std::unique_ptr<Vector<char>> base64Data = wrapUnique(new Vector<char>()); Vector<char> encodedImage; RefPtr<SkImage> image = fromSkSp(SkImage::MakeFromBitmap(bitmap)); if (!image) return nullptr; ImagePixelLocker pixelLocker(image, kUnpremul_SkAlphaType, kRGBA_8888_SkColorType); ImageDataBuffer imageData(IntSize(image->width(), image->height()), static_cast<const unsigned char*>(pixelLocker.pixels())); if (!PNGImageEncoder::encode(imageData, reinterpret_cast<Vector<unsigned char>*>(&encodedImage))) return nullptr; base64Encode(encodedImage, *base64Data); return base64Data; }
PassRefPtr<SkImage> UnacceleratedImageBufferSurface::newImageSnapshot(AccelerationHint, SnapshotReason) { return fromSkSp(m_surface->makeImageSnapshot()); }
SkShader* Gradient::shader() { if (m_gradient) return m_gradient.get(); sortStopsIfNecessary(); ASSERT(m_stopsSorted); size_t countUsed = totalStopsNeeded(m_stops.data(), m_stops.size()); ASSERT(countUsed >= 2); ASSERT(countUsed >= m_stops.size()); ColorStopOffsetVector pos(countUsed); ColorStopColorVector colors(countUsed); fillStops(m_stops.data(), m_stops.size(), pos, colors); SkShader::TileMode tile = SkShader::kClamp_TileMode; switch (m_spreadMethod) { case SpreadMethodReflect: tile = SkShader::kMirror_TileMode; break; case SpreadMethodRepeat: tile = SkShader::kRepeat_TileMode; break; case SpreadMethodPad: tile = SkShader::kClamp_TileMode; break; } uint32_t shouldDrawInPMColorSpace = m_drawInPMColorSpace ? SkGradientShader::kInterpolateColorsInPremul_Flag : 0; if (m_radial) { if (aspectRatio() != 1) { // CSS3 elliptical gradients: apply the elliptical scaling at the // gradient center point. m_gradientSpaceTransformation.translate(m_p0.x(), m_p0.y()); m_gradientSpaceTransformation.scale(1, 1 / aspectRatio()); m_gradientSpaceTransformation.translate(-m_p0.x(), -m_p0.y()); ASSERT(m_p0 == m_p1); } SkMatrix localMatrix = affineTransformToSkMatrix(m_gradientSpaceTransformation); // Since the two-point radial gradient is slower than the plain radial, // only use it if we have to. if (m_p0 == m_p1 && m_r0 <= 0.0f) { m_gradient = fromSkSp(SkGradientShader::MakeRadial(m_p1.data(), m_r1, colors.data(), pos.data(), static_cast<int>(countUsed), tile, shouldDrawInPMColorSpace, &localMatrix)); } else { // The radii we give to Skia must be positive. If we're given a // negative radius, ask for zero instead. SkScalar radius0 = m_r0 >= 0.0f ? WebCoreFloatToSkScalar(m_r0) : 0; SkScalar radius1 = m_r1 >= 0.0f ? WebCoreFloatToSkScalar(m_r1) : 0; m_gradient = fromSkSp(SkGradientShader::MakeTwoPointConical(m_p0.data(), radius0, m_p1.data(), radius1, colors.data(), pos.data(), static_cast<int>(countUsed), tile, shouldDrawInPMColorSpace, &localMatrix)); } } else { SkPoint pts[2] = { m_p0.data(), m_p1.data() }; SkMatrix localMatrix = affineTransformToSkMatrix(m_gradientSpaceTransformation); m_gradient = fromSkSp(SkGradientShader::MakeLinear(pts, colors.data(), pos.data(), static_cast<int>(countUsed), tile, shouldDrawInPMColorSpace, &localMatrix)); } if (!m_gradient) { // use last color, since our "geometry" was degenerate (e.g. radius==0) m_gradient = fromSkSp(SkShader::MakeColorShader(colors[countUsed - 1])); } return m_gradient.get(); }