Beispiel #1
0
void Image::drawPattern(GraphicsContext& context,
                        const FloatRect& floatSrcRect,
                        const FloatSize& scale,
                        const FloatPoint& phase,
                        SkBlendMode compositeOp,
                        const FloatRect& destRect,
                        const FloatSize& repeatSpacing) {
  TRACE_EVENT0("skia", "Image::drawPattern");

  sk_sp<SkImage> image = imageForCurrentFrame();
  if (!image)
    return;

  FloatRect normSrcRect = floatSrcRect;

  normSrcRect.intersect(FloatRect(0, 0, image->width(), image->height()));
  if (destRect.isEmpty() || normSrcRect.isEmpty())
    return;  // nothing to draw

  SkMatrix localMatrix;
  // We also need to translate it such that the origin of the pattern is the
  // origin of the destination rect, which is what WebKit expects. Skia uses
  // the coordinate system origin as the base for the pattern. If WebKit wants
  // a shifted image, it will shift it from there using the localMatrix.
  const float adjustedX = phase.x() + normSrcRect.x() * scale.width();
  const float adjustedY = phase.y() + normSrcRect.y() * scale.height();
  localMatrix.setTranslate(SkFloatToScalar(adjustedX),
                           SkFloatToScalar(adjustedY));

  // Because no resizing occurred, the shader transform should be
  // set to the pattern's transform, which just includes scale.
  localMatrix.preScale(scale.width(), scale.height());

  // Fetch this now as subsetting may swap the image.
  auto imageID = image->uniqueID();

  image = image->makeSubset(enclosingIntRect(normSrcRect));
  if (!image)
    return;

  {
    SkPaint paint = context.fillPaint();
    paint.setColor(SK_ColorBLACK);
    paint.setBlendMode(static_cast<SkBlendMode>(compositeOp));
    paint.setFilterQuality(
        context.computeFilterQuality(this, destRect, normSrcRect));
    paint.setAntiAlias(context.shouldAntialias());
    paint.setShader(createPatternShader(
        image.get(), localMatrix, paint,
        FloatSize(repeatSpacing.width() / scale.width(),
                  repeatSpacing.height() / scale.height())));
    context.drawRect(destRect, paint);
  }

  if (currentFrameIsLazyDecoded())
    PlatformInstrumentation::didDrawLazyPixelRef(imageID);
}
void BitmapImage::draw(SkCanvas* canvas, const SkPaint& paint, const FloatRect& dstRect, const FloatRect& srcRect, RespectImageOrientationEnum shouldRespectImageOrientation, ImageClampingMode clampMode)
{
    TRACE_EVENT0("skia", "BitmapImage::draw");

    RefPtr<SkImage> image = imageForCurrentFrame();
    if (!image)
        return; // It's too early and we don't have an image yet.

    FloatRect adjustedSrcRect = srcRect;
    adjustedSrcRect.intersect(FloatRect(0, 0, image->width(), image->height()));

    if (adjustedSrcRect.isEmpty() || dstRect.isEmpty())
        return; // Nothing to draw.

    ImageOrientation orientation = DefaultImageOrientation;
    if (shouldRespectImageOrientation == RespectImageOrientation)
        orientation = frameOrientationAtIndex(m_currentFrame);

    int initialSaveCount = canvas->getSaveCount();
    FloatRect adjustedDstRect = dstRect;
    if (orientation != DefaultImageOrientation) {
        canvas->save();

        // ImageOrientation expects the origin to be at (0, 0)
        canvas->translate(adjustedDstRect.x(), adjustedDstRect.y());
        adjustedDstRect.setLocation(FloatPoint());

        canvas->concat(affineTransformToSkMatrix(orientation.transformFromDefault(adjustedDstRect.size())));

        if (orientation.usesWidthAsHeight()) {
            // The destination rect will have it's width and height already reversed for the orientation of
            // the image, as it was needed for page layout, so we need to reverse it back here.
            adjustedDstRect = FloatRect(adjustedDstRect.x(), adjustedDstRect.y(), adjustedDstRect.height(), adjustedDstRect.width());
        }
    }

    SkRect skSrcRect = adjustedSrcRect;
    canvas->drawImageRect(image.get(), skSrcRect, adjustedDstRect, &paint,
        WebCoreClampingModeToSkiaRectConstraint(clampMode));
    canvas->restoreToCount(initialSaveCount);

    if (currentFrameIsLazyDecoded())
        PlatformInstrumentation::didDrawLazyPixelRef(image->uniqueID());

    if (ImageObserver* observer = imageObserver())
        observer->didDraw(this);

    startAnimation();
}
Beispiel #3
0
bool Image::applyShader(SkPaint& paint, const SkMatrix& localMatrix) {
  // Default shader impl: attempt to build a shader based on the current frame
  // SkImage.
  sk_sp<SkImage> image = imageForCurrentFrame();
  if (!image)
    return false;

  paint.setShader(image->makeShader(SkShader::kRepeat_TileMode,
                                    SkShader::kRepeat_TileMode, &localMatrix));

  // Animation is normally refreshed in draw() impls, which we don't call when
  // painting via shaders.
  startAnimation();

  return true;
}
Beispiel #4
0
bool Image::deprecatedBitmapForCurrentFrame(SkBitmap* bitmap)
{
    RefPtr<SkImage> image = imageForCurrentFrame();

    return image && image->asLegacyBitmap(bitmap, SkImage::kRO_LegacyBitmapMode);
}
Beispiel #5
0
bool Image::isTextureBacked()
{
    RefPtr<SkImage> image = imageForCurrentFrame();
    return image ? image->isTextureBacked() : false;
}