Пример #1
0
CGImageRef BitmapImage::getCGImageRef()
{
    return frameAtIndex(0);
}
Пример #2
0
PassNativeImagePtr BitmapImage::nativeImageForCurrentFrame()
{
    return frameAtIndex(currentFrame());
}
Пример #3
0
bool BitmapImage::currentFrameIsLazyDecoded()
{
    RefPtr<SkImage> image = frameAtIndex(currentFrame());
    return image && image->isLazyGenerated();
}
Пример #4
0
void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op)
{
    FloatRect srcRect(src);
    FloatRect dstRect(dst);

    if (dstRect.width() == 0.0f || dstRect.height() == 0.0f ||
        srcRect.width() == 0.0f || srcRect.height() == 0.0f)
        return;

    startAnimation();

    cairo_surface_t* image = frameAtIndex(m_currentFrame);
    if (!image) // If it's too early we won't have an image yet.
        return;

    if (mayFillWithSolidColor()) {
        fillWithSolidColor(context, dstRect, solidColor(), styleColorSpace, op);
        return;
    }

    IntSize selfSize = size();

    cairo_t* cr = context->platformContext();
    context->save();

    // Set the compositing operation.
    if (op == CompositeSourceOver && !frameHasAlphaAtIndex(m_currentFrame))
        context->setCompositeOperation(CompositeCopy);
    else
        context->setCompositeOperation(op);

    // If we're drawing a sub portion of the image or scaling then create
    // a pattern transformation on the image and draw the transformed pattern.
    // Test using example site at http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html
    cairo_pattern_t* pattern = cairo_pattern_create_for_surface(image);

    cairo_pattern_set_extend(pattern, CAIRO_EXTEND_PAD);

    float scaleX = srcRect.width() / dstRect.width();
    float scaleY = srcRect.height() / dstRect.height();
    cairo_matrix_t matrix = { scaleX, 0, 0, scaleY, srcRect.x(), srcRect.y() };
    cairo_pattern_set_matrix(pattern, &matrix);

    // Draw the shadow
#if ENABLE(FILTERS)
    FloatSize shadowOffset;
    float shadowBlur;
    Color shadowColor;
    if (context->getShadow(shadowOffset, shadowBlur, shadowColor)) {
        IntSize shadowBufferSize;
        FloatRect shadowRect;
        float radius = 0;
        context->calculateShadowBufferDimensions(shadowBufferSize, shadowRect, radius, dstRect, shadowOffset, shadowBlur);
        shadowColor = colorWithOverrideAlpha(shadowColor.rgb(), (shadowColor.alpha() *  context->getAlpha()) / 255.f);

        //draw shadow into a new ImageBuffer
        OwnPtr<ImageBuffer> shadowBuffer = ImageBuffer::create(shadowBufferSize);
        cairo_t* shadowContext = shadowBuffer->context()->platformContext();
        cairo_set_source(shadowContext, pattern);
        cairo_translate(shadowContext, -dstRect.x(), -dstRect.y());
        cairo_rectangle(shadowContext, 0, 0, dstRect.width(), dstRect.height());
        cairo_fill(shadowContext);

        context->applyPlatformShadow(shadowBuffer.release(), shadowColor, shadowRect, radius);
    }
#endif

    // Draw the image.
    cairo_translate(cr, dstRect.x(), dstRect.y());
    cairo_set_source(cr, pattern);
    cairo_pattern_destroy(pattern);
    cairo_rectangle(cr, 0, 0, dstRect.width(), dstRect.height());
    cairo_clip(cr);
    cairo_paint_with_alpha(cr, context->getAlpha());

    context->restore();

    if (imageObserver())
        imageObserver()->didDraw(this);
}
Пример #5
0
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator compositeOp)
{
    startAnimation();

    CGImageRef image = frameAtIndex(m_currentFrame);
    if (!image) // If it's too early we won't have an image yet.
        return;
    
    if (mayFillWithSolidColor()) {
        fillWithSolidColor(ctxt, destRect, solidColor(), compositeOp);
        return;
    }

    float currHeight = CGImageGetHeight(image);
    if (currHeight <= srcRect.y())
        return;

    CGContextRef context = ctxt->platformContext();
    ctxt->save();

    bool shouldUseSubimage = false;

    // If the source rect is a subportion of the image, then we compute an inflated destination rect that will hold the entire image
    // and then set a clip to the portion that we want to display.
    FloatRect adjustedDestRect = destRect;
    FloatSize selfSize = currentFrameSize();
    if (srcRect.size() != selfSize) {
        CGInterpolationQuality interpolationQuality = CGContextGetInterpolationQuality(context);
        // When the image is scaled using high-quality interpolation, we create a temporary CGImage
        // containing only the portion we want to display. We need to do this because high-quality
        // interpolation smoothes sharp edges, causing pixels from outside the source rect to bleed
        // into the destination rect. See <rdar://problem/6112909>.
        shouldUseSubimage = (interpolationQuality == kCGInterpolationHigh || interpolationQuality == kCGInterpolationDefault) && srcRect.size() != destRect.size();
        float xScale = srcRect.width() / destRect.width();
        float yScale = srcRect.height() / destRect.height();
        if (shouldUseSubimage) {
            FloatRect subimageRect = srcRect;
            float leftPadding = srcRect.x() - floorf(srcRect.x());
            float topPadding = srcRect.y() - floorf(srcRect.y());

            subimageRect.move(-leftPadding, -topPadding);
            adjustedDestRect.move(-leftPadding / xScale, -topPadding / yScale);

            subimageRect.setWidth(ceilf(subimageRect.width() + leftPadding));
            adjustedDestRect.setWidth(subimageRect.width() / xScale);

            subimageRect.setHeight(ceilf(subimageRect.height() + topPadding));
            adjustedDestRect.setHeight(subimageRect.height() / yScale);

            image = CGImageCreateWithImageInRect(image, subimageRect);
            if (currHeight < srcRect.bottom()) {
                ASSERT(CGImageGetHeight(image) == currHeight - CGRectIntegral(srcRect).origin.y);
                adjustedDestRect.setHeight(CGImageGetHeight(image) / yScale);
            }
        } else {
            adjustedDestRect.setLocation(FloatPoint(destRect.x() - srcRect.x() / xScale, destRect.y() - srcRect.y() / yScale));
            adjustedDestRect.setSize(FloatSize(selfSize.width() / xScale, selfSize.height() / yScale));
        }

        CGContextClipToRect(context, destRect);
    }

    // If the image is only partially loaded, then shrink the destination rect that we're drawing into accordingly.
    if (!shouldUseSubimage && currHeight < selfSize.height())
        adjustedDestRect.setHeight(adjustedDestRect.height() * currHeight / selfSize.height());

    ctxt->setCompositeOperation(compositeOp);

    // Flip the coords.
    CGContextScaleCTM(context, 1, -1);
    adjustedDestRect.setY(-adjustedDestRect.bottom());

    // Draw the image.
    CGContextDrawImage(context, adjustedDestRect, image);

    if (shouldUseSubimage)
        CGImageRelease(image);

    ctxt->restore();

    if (imageObserver())
        imageObserver()->didDraw(this);
}
Пример #6
0
PassRefPtr<SkImage> BitmapImage::imageForCurrentFrame()
{
    return frameAtIndex(currentFrame());
}
Пример #7
0
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op)
{
    if (!m_source.initialized())
        return;

    if (mayFillWithSolidColor()) {
        fillWithSolidColor(ctxt, dst, solidColor(), styleColorSpace, op);
        return;
    }

#if USE(WXGC)
    wxGCDC* context = (wxGCDC*)ctxt->platformContext();
    wxGraphicsContext* gc = context->GetGraphicsContext();
    wxGraphicsBitmap* bitmap = frameAtIndex(m_currentFrame);
#else
    wxDC* context = ctxt->platformContext();
    wxBitmap* bitmap = frameAtIndex(m_currentFrame);
#endif

    startAnimation();
    if (!bitmap) // If it's too early we won't have an image yet.
        return;
    
    // If we're drawing a sub portion of the image or scaling then create
    // a pattern transformation on the image and draw the transformed pattern.
    // Test using example site at http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html
    // FIXME: NYI
   
    ctxt->save();

    // Set the compositing operation.
    ctxt->setCompositeOperation(op);
    
#if USE(WXGC)
    float scaleX = src.width() / dst.width();
    float scaleY = src.height() / dst.height();

    FloatRect adjustedDestRect = dst;
    FloatSize selfSize = currentFrameSize();
    
    if (src.size() != selfSize) {
        adjustedDestRect.setLocation(FloatPoint(dst.x() - src.x() / scaleX, dst.y() - src.y() / scaleY));
        adjustedDestRect.setSize(FloatSize(selfSize.width() / scaleX, selfSize.height() / scaleY));
    }

    gc->Clip(dst.x(), dst.y(), dst.width(), dst.height());
#if wxCHECK_VERSION(2,9,0)
    gc->DrawBitmap(*bitmap, adjustedDestRect.x(), adjustedDestRect.y(), adjustedDestRect.width(), adjustedDestRect.height());
#else
    gc->DrawGraphicsBitmap(*bitmap, adjustedDestRect.x(), adjustedDestRect.y(), adjustedDestRect.width(), adjustedDestRect.height());
#endif

#else // USE(WXGC)
    bitmap = getCachedResizedBitmap(bitmap, dst.size(), src);
    context->DrawBitmap(*bitmap, dst.x(), dst.y(), true);
#endif

    ctxt->restore();

    if (ImageObserver* observer = imageObserver())
        observer->didDraw(this);
}
Пример #8
0
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, const FloatRect& src, CompositeOperator op)
{
    if (!m_source.initialized())
        return;

    if (mayFillWithSolidColor()) {
        fillWithSolidColor(ctxt, dst, solidColor(), op);
        return;
    }

#if USE(WXGC)
    wxGCDC* context = (wxGCDC*)ctxt->platformContext();
    wxGraphicsContext* gc = context->GetGraphicsContext();
#else
    wxWindowDC* context = ctxt->platformContext();
#endif

    startAnimation();

    wxBitmap* bitmap = frameAtIndex(m_currentFrame);
    if (!bitmap) // If it's too early we won't have an image yet.
        return;
    
    // If we're drawing a sub portion of the image or scaling then create
    // a pattern transformation on the image and draw the transformed pattern.
    // Test using example site at http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html
    // FIXME: NYI
   
    ctxt->save();

    // Set the compositing operation.
    ctxt->setCompositeOperation(op);
    
#if USE(WXGC)
    float scaleX = src.width() / dst.width();
    float scaleY = src.height() / dst.height();

    FloatRect adjustedDestRect = dst;
    FloatSize selfSize = currentFrameSize();
    
    if (src.size() != selfSize) {
        adjustedDestRect.setLocation(FloatPoint(dst.x() - src.x() / scaleX, dst.y() - src.y() / scaleY));
        adjustedDestRect.setSize(FloatSize(selfSize.width() / scaleX, selfSize.height() / scaleY));
    }
    
    // If the image is only partially loaded, then shrink the destination rect that we're drawing into accordingly.
    int currHeight = bitmap->GetHeight(); 
    if (currHeight < selfSize.height())
        adjustedDestRect.setHeight(adjustedDestRect.height() * currHeight / selfSize.height());

    gc->DrawBitmap(*bitmap, adjustedDestRect.x(), adjustedDestRect.y(), adjustedDestRect.width(), adjustedDestRect.height());
#else
    IntRect srcIntRect(src);
    IntRect dstIntRect(dst);
    bool rescaling = false;
    if ((dstIntRect.width() != srcIntRect.width()) || (dstIntRect.height() != srcIntRect.height()))
    {
        rescaling = true;
        wxImage img = bitmap->ConvertToImage();
        img.Rescale(dstIntRect.width(), dstIntRect.height());
        bitmap = new wxBitmap(img);
    } 
    
    wxMemoryDC mydc; 
    ASSERT(bitmap->GetRefData());
    mydc.SelectObject(*bitmap); 
    
    context->Blit((wxCoord)dstIntRect.x(),(wxCoord)dstIntRect.y(), (wxCoord)dstIntRect.width(), (wxCoord)dstIntRect.height(), &mydc, 
                    (wxCoord)srcIntRect.x(), (wxCoord)srcIntRect.y(), wxCOPY, true); 
    mydc.SelectObject(wxNullBitmap);
    
    // NB: delete is causing crashes during page load, but not during the deletion
    // itself. It occurs later on when a valid bitmap created in frameAtIndex
    // suddenly becomes invalid after returning. It's possible these errors deal
    // with reentrancy and threding problems.
    //delete bitmap;
    if (rescaling)
    {
        delete bitmap;
        bitmap = NULL;
    }
#endif

    ctxt->restore();
}
Пример #9
0
void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const FloatRect& src, CompositeOperator op)
{
    SDL_Surface* image = frameAtIndex(m_currentFrame);
    if (!image) // If it's too early we won't have an image yet.
        return;

    FloatRect sourceRect(src);
    FloatRect destRect(dst);

    if (mayFillWithSolidColor()) {
        fillWithSolidColor(context, destRect, solidColor(), op);
        return;
    }

    // Set the compositing operation.
    if (op == CompositeSourceOver && !frameHasAlphaAtIndex(m_currentFrame))
        context->setCompositeOperation(CompositeCopy);
    else
        context->setCompositeOperation(op);

    SDL_Surface* cr = context->platformContext();

    float scaleX = destRect.width() / sourceRect.width();
    float scaleY = destRect.height() / sourceRect.height();

    // Draw the image.
    SDL_Rect srcRect, dstRect;

    srcRect.x = static_cast<Sint16>(src.x());
    srcRect.y = static_cast<Sint16>(src.y());
    if (0 == sourceRect.width())
        srcRect.w = image->w;
    else
        srcRect.w = static_cast<Uint16>(sourceRect.width());
    if (0 == sourceRect.height())
        srcRect.h = image->h;
    else
        srcRect.h = static_cast<Uint16>(sourceRect.height());


    dstRect.x = static_cast<Sint16>(destRect.x() + context->origin().x());
    dstRect.y = static_cast<Sint16>(destRect.y() + context->origin().y());
    dstRect.w = static_cast<Sint16>(destRect.width());
    dstRect.h = static_cast<Sint16>(destRect.height());

    if ((scaleX != 1.0)||(scaleY != 1.0)) {
        srcRect.x = static_cast<Sint16>(src.x() * scaleX);
        srcRect.y = static_cast<Sint16>(src.y() * scaleY);
        srcRect.w = dstRect.w;
        srcRect.h = dstRect.h;
    }


    if (sourceRect != destRect) {
        if (context->transparencyLayer() == 1.0) {
            if ((scaleX != 1.0) || (scaleY != 1.0)) {
                SDL_Surface *surface = zoomSurface(image, scaleX, scaleY, SMOOTHING_OFF);
                SDL_BlitSurface(surface, &srcRect, cr, &dstRect);
                SDL_FreeSurface(surface);
            } else
                SDL_BlitSurface(image, &srcRect, cr, &dstRect);
        }
        else {
            SDL_Surface *surfaceWithAlpha = applyTransparency(image, static_cast<int> (context->transparencyLayer() * 255));
            if ((scaleX != 1.0) || (scaleY != 1.0)) {
                SDL_Surface *surface = zoomSurface(surfaceWithAlpha, scaleX, scaleY, SMOOTHING_OFF);
                SDL_BlitSurface(surface, &srcRect, cr, &dstRect);
                SDL_FreeSurface(surface);
            } else
                SDL_BlitSurface(surfaceWithAlpha, &srcRect, cr, &dstRect);

            SDL_FreeSurface(surfaceWithAlpha);
        }
    } else if (context->transparencyLayer() == 1.0)
        SDL_BlitSurface(image, &srcRect, cr, &dstRect);
    else {
        SDL_Surface *surfaceWithAlpha = applyTransparency(image, static_cast<int> (context->transparencyLayer() * 255));
        SDL_BlitSurface(surfaceWithAlpha, &srcRect, cr, &dstRect);
        SDL_FreeSurface(surfaceWithAlpha);
    }

    startAnimation();

    if (imageObserver())
        imageObserver()->didDraw(this);
}
Пример #10
0
PassRefPtr<NativeImageSkia> BitmapImage::nativeImageForCurrentFrame()
{
    return frameAtIndex(currentFrame());
}
Пример #11
0
GdkPixbuf* BitmapImage::getGdkPixbuf()
{
    return cairoImageSurfaceToGdkPixbuf(frameAtIndex(currentFrame()));
}
Пример #12
0
void Image::drawTiled(GraphicsContext* ctxt, const FloatRect& dstRect, const FloatPoint& srcPoint,
    const FloatSize& tileSize, CompositeOperator op)
{
    if (!m_source.initialized())
        return;

    cairo_surface_t* image = frameAtIndex(m_currentFrame);
    if (!image) // If it's too early we won't have an image yet.
        return;

    IntSize intrinsicImageSize = size();                       
    FloatRect srcRect(srcPoint, intrinsicImageSize);
    FloatPoint point = srcPoint;

    // Check and see if a single draw of the image can cover the entire area we are supposed to tile.
    float tileWidth = size().width();
    float tileHeight = size().height();
    
    // If the scale is not equal to the intrinsic size of the image, set transform matrix
    // to the appropriate scalar matrix, scale the source point, and set the size of the
    // scaled tile. 
    float scaleX = 1.0;
    float scaleY = 1.0;
    cairo_matrix_t mat;
    cairo_matrix_init_identity(&mat);
    if (tileSize.width() != intrinsicImageSize.width() || tileSize.height() != intrinsicImageSize.height()) {
        scaleX = intrinsicImageSize.width() / tileSize.width();
        scaleY = intrinsicImageSize.height() / tileSize.height();
        cairo_matrix_init_scale(&mat, scaleX, scaleY);
        
        tileWidth = tileSize.width();
        tileHeight = tileSize.height();
    }
   
    // We could get interesting source offsets (negative ones or positive ones.  Deal with both
    // out of bounds cases.
    float dstTileX = dstRect.x() + fmodf(fmodf(-point.x(), tileWidth) - tileWidth, tileWidth);
    float dstTileY = dstRect.y() + fmodf(fmodf(-point.y(), tileHeight) - tileHeight, tileHeight);
    FloatRect dstTileRect(dstTileX, dstTileY, tileWidth, tileHeight);
    
    float srcX = dstRect.x() - dstTileRect.x();
    float srcY = dstRect.y() - dstTileRect.y();

    // If the single image draw covers the whole area, then just draw once.
    if (dstTileRect.contains(dstRect)) {
        draw(ctxt, dstRect,
             FloatRect(srcX * scaleX, srcY * scaleY, dstRect.width() * scaleX, dstRect.height() * scaleY), op);
        return;
    }

    // We have to tile.
    cairo_t* context = ctxt->platformContext();

    cairo_save(context);

    // Set the compositing operation.
    setCompositingOperation(context, op, frameHasAlphaAtIndex(m_currentFrame));

    cairo_translate(context, dstTileRect.x(), dstTileRect.y());
    cairo_pattern_t* pattern = cairo_pattern_create_for_surface(image);
    cairo_pattern_set_matrix(pattern, &mat);
    cairo_pattern_set_extend(pattern, CAIRO_EXTEND_REPEAT);

    // Draw the image.
    cairo_set_source(context, pattern);
    cairo_rectangle(context, srcX, srcY, dstRect.width(), dstRect.height());
    cairo_fill(context);
    cairo_restore(context);

    startAnimation();
}
Пример #13
0
bool BitmapImage::bitmapForCurrentFrame(SkBitmap* bitmap)
{
    return frameAtIndex(currentFrame(), bitmap);
}