示例#1
0
nsIntSize
ClippedImage::OptimalImageSizeForDest(const gfxSize& aDest,
                                      uint32_t aWhichFrame,
                                      SamplingFilter aSamplingFilter,
                                      uint32_t aFlags)
{
  if (!ShouldClip()) {
    return InnerImage()->OptimalImageSizeForDest(aDest, aWhichFrame,
                                                 aSamplingFilter, aFlags);
  }

  int32_t imgWidth, imgHeight;
  bool needScale = false;
  bool forceUniformScaling = false;
  if (mSVGViewportSize && !mSVGViewportSize->IsEmpty()) {
    imgWidth = mSVGViewportSize->width;
    imgHeight = mSVGViewportSize->height;
    needScale = true;
    forceUniformScaling = (aFlags & imgIContainer::FLAG_FORCE_UNIFORM_SCALING);
  } else if (NS_SUCCEEDED(InnerImage()->GetWidth(&imgWidth)) &&
             NS_SUCCEEDED(InnerImage()->GetHeight(&imgHeight))) {
    needScale = true;
  }

  if (needScale) {
    // To avoid ugly sampling artifacts, ClippedImage needs the image size to
    // be chosen such that the clipping region lies on pixel boundaries.

    // First, we select a scale that's good for ClippedImage. An integer
    // multiple of the size of the clipping region is always fine.
    IntSize scale = IntSize::Ceil(aDest.width / mClip.width,
                                  aDest.height / mClip.height);

    if (forceUniformScaling) {
      scale.width = scale.height = max(scale.height, scale.width);
    }

    // Determine the size we'd prefer to render the inner image at, and ask the
    // inner image what size we should actually use.
    gfxSize desiredSize(imgWidth * scale.width, imgHeight * scale.height);
    nsIntSize innerDesiredSize =
      InnerImage()->OptimalImageSizeForDest(desiredSize, aWhichFrame,
                                            aSamplingFilter, aFlags);

    // To get our final result, we take the inner image's desired size and
    // determine how large the clipped region would be at that scale. (Again, we
    // ensure an integer multiple of the size of the clipping region.)
    IntSize finalScale = IntSize::Ceil(double(innerDesiredSize.width) / imgWidth,
                                       double(innerDesiredSize.height) / imgHeight);
    return mClip.Size() * finalScale;
  }

  MOZ_ASSERT(false,
             "If ShouldClip() led us to draw then we should never get here");
  return InnerImage()->OptimalImageSizeForDest(aDest, aWhichFrame,
                                               aSamplingFilter, aFlags);
}
示例#2
0
ClippedImage::GetImageSpaceInvalidationRect(const nsIntRect& aRect)
{
  if (!ShouldClip()) {
    return InnerImage()->GetImageSpaceInvalidationRect(aRect);
  }

  nsIntRect rect(InnerImage()->GetImageSpaceInvalidationRect(aRect));
  rect = rect.Intersect(mClip);
  rect.MoveBy(-mClip.x, -mClip.y);
  return rect;
}
示例#3
0
ClippedImage::Draw(gfxContext* aContext,
                   const nsIntSize& aSize,
                   const ImageRegion& aRegion,
                   uint32_t aWhichFrame,
                   SamplingFilter aSamplingFilter,
                   const Maybe<SVGImageContext>& aSVGContext,
                   uint32_t aFlags,
                   float aOpacity)
{
  if (!ShouldClip()) {
    return InnerImage()->Draw(aContext, aSize, aRegion, aWhichFrame,
                              aSamplingFilter, aSVGContext, aFlags, aOpacity);
  }

  // Check for tiling. If we need to tile then we need to create a
  // gfxCallbackDrawable to handle drawing for us.
  if (MustCreateSurface(aContext, aSize, aRegion, aFlags)) {
    // Create a temporary surface containing a single tile of this image.
    // GetFrame will call DrawSingleTile internally.
    DrawResult result;
    RefPtr<SourceSurface> surface;
    Tie(result, surface) =
      GetFrameInternal(aSize, aSVGContext, aWhichFrame, aFlags, aOpacity);
    if (!surface) {
      MOZ_ASSERT(result != DrawResult::SUCCESS);
      return result;
    }

    // Create a drawable from that surface.
    RefPtr<gfxSurfaceDrawable> drawable =
      new gfxSurfaceDrawable(surface, aSize);

    // Draw.
    gfxUtils::DrawPixelSnapped(aContext, drawable, aSize, aRegion,
                               SurfaceFormat::B8G8R8A8, aSamplingFilter,
                               aOpacity);

    return result;
  }

  return DrawSingleTile(aContext, aSize, aRegion, aWhichFrame,
                        aSamplingFilter, aSVGContext, aFlags, aOpacity);
}
示例#4
0
nsIntSize
ClippedImage::OptimalImageSizeForDest(const gfxSize& aDest,
                                      uint32_t aWhichFrame,
                                      GraphicsFilter aFilter, uint32_t aFlags)
{
  if (!ShouldClip()) {
    return InnerImage()->OptimalImageSizeForDest(aDest, aWhichFrame, aFilter,
                                                 aFlags);
  }

  int32_t imgWidth, imgHeight;
  if (NS_SUCCEEDED(InnerImage()->GetWidth(&imgWidth)) &&
      NS_SUCCEEDED(InnerImage()->GetHeight(&imgHeight))) {
    // To avoid ugly sampling artifacts, ClippedImage needs the image size to
    // be chosen such that the clipping region lies on pixel boundaries.

    // First, we select a scale that's good for ClippedImage. An integer
    // multiple of the size of the clipping region is always fine.
    nsIntSize scale(ceil(aDest.width / mClip.width),
                    ceil(aDest.height / mClip.height));

    // Determine the size we'd prefer to render the inner image at, and ask the
    // inner image what size we should actually use.
    gfxSize desiredSize(imgWidth * scale.width, imgHeight * scale.height);
    nsIntSize innerDesiredSize =
      InnerImage()->OptimalImageSizeForDest(desiredSize, aWhichFrame,
                                            aFilter, aFlags);

    // To get our final result, we take the inner image's desired size and
    // determine how large the clipped region would be at that scale. (Again, we
    // ensure an integer multiple of the size of the clipping region.)
    nsIntSize finalScale(ceil(double(innerDesiredSize.width) / imgWidth),
                         ceil(double(innerDesiredSize.height) / imgHeight));
    return mClip.Size() * finalScale;
  } else {
    MOZ_ASSERT(false,
               "If ShouldClip() led us to draw then we should never get here");
    return InnerImage()->OptimalImageSizeForDest(aDest, aWhichFrame, aFilter,
                                                 aFlags);
  }
}