示例#1
0
void PDFDocumentImage::draw(GraphicsContext* context, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace, CompositeOperator op, BlendMode)
{
    if (!m_document || m_currentPage == -1)
        return;

    {
        GraphicsContextStateSaver stateSaver(*context);

        context->setCompositeOperation(op);

        float hScale = dstRect.width() / srcRect.width();
        float vScale = dstRect.height() / srcRect.height();

        // Scale and translate so the document is rendered in the correct location,
        // including accounting for the fact that a GraphicsContext is always flipped
        // and doing appropriate flipping.
        CGContextTranslateCTM(context->platformContext(), dstRect.x() - srcRect.x() * hScale, dstRect.y() - srcRect.y() * vScale);
        CGContextScaleCTM(context->platformContext(), hScale, vScale);
        CGContextScaleCTM(context->platformContext(), 1, -1);
        CGContextTranslateCTM(context->platformContext(), 0, -srcRect.height());
        CGContextClipToRect(context->platformContext(), CGRectIntegral(srcRect));

        // Rotate translate image into position according to doc properties.
        adjustCTM(context);

        CGContextTranslateCTM(context->platformContext(), -m_mediaBox.x(), -m_mediaBox.y());
        CGContextDrawPDFPage(context->platformContext(), CGPDFDocumentGetPage(m_document, m_currentPage + 1));
    }

    if (imageObserver())
        imageObserver()->didDraw(this);
}
示例#2
0
void BitmapImage::cacheFrame(size_t index)
{
    size_t numFrames = frameCount();
    if (m_frames.size() < numFrames)
        m_frames.grow(numFrames);

    int deltaBytes = totalFrameBytes();


    // We are caching frame snapshots.  This is OK even for partially decoded frames,
    // as they are cleared by dataChanged() when new data arrives.
    m_frames[index].m_frame = m_source.createFrameAtIndex(index);

    m_frames[index].m_orientation = m_source.orientationAtIndex(index);
    m_frames[index].m_haveMetadata = true;
    m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index);
    if (repetitionCount(false) != cAnimationNone)
        m_frames[index].m_duration = m_source.frameDurationAtIndex(index);
    m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index);
    m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index);

    const IntSize frameSize(index ? m_source.frameSizeAtIndex(index) : m_size);
    if (frameSize != m_size)
        m_hasUniformFrameSize = false;

    // We need to check the total bytes before and after the decode call, not
    // just the current frame size, because some multi-frame images may require
    // decoding multiple frames to decode the current frame.
    deltaBytes = totalFrameBytes() - deltaBytes;
    if (deltaBytes && imageObserver())
        imageObserver()->decodedSizeChanged(this, deltaBytes);
}
void PDFDocumentImage::draw(GraphicsContext* context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator op)
{
    if (!m_document || m_currentPage == -1)
        return;

    context->save();

    context->setCompositeOperation(op);

    float hScale = dstRect.width() / srcRect.width();
    float vScale = dstRect.height() / srcRect.height();

    // Scale and translate so the document is rendered in the correct location,
    // including accounting for the fact that a GraphicsContext is always flipped
    // and doing appropriate flipping.
    CGContextTranslateCTM(context->platformContext(), dstRect.x() - srcRect.x() * hScale, dstRect.y() - srcRect.y() * vScale);
    CGContextScaleCTM(context->platformContext(), hScale, vScale);
    CGContextScaleCTM(context->platformContext(), 1, -1);
    CGContextTranslateCTM(context->platformContext(), 0, -srcRect.height());
    CGContextClipToRect(context->platformContext(), CGRectIntegral(srcRect));

    // Rotate translate image into position according to doc properties.
    adjustCTM(context);

    // Media box may have non-zero origin which we ignore. Pass 1 for the page number.
    CGContextDrawPDFDocument(context->platformContext(), FloatRect(FloatPoint(), m_mediaBox.size()),
        m_document, m_currentPage + 1);
    
    context->restore();

    if (imageObserver())
        imageObserver()->didDraw(this);
}
示例#4
0
void BitmapImage::destroyDecodedData(bool incremental)
{
    // Destroy the cached images and release them.
    if (m_frames.size()) {
        int sizeChange = 0;
        int frameSize = m_size.width() * m_size.height() * 4;
        for (unsigned i = incremental ? m_frames.size() - 1 : 0; i < m_frames.size(); i++) {
            if (m_frames[i].m_frame) {
                sizeChange -= frameSize;
                m_frames[i].clear();
            }
        }

        // We just always invalidate our platform data, even in the incremental case.
        // This could be better, but it's not a big deal.
        m_isSolidColor = false;
        invalidatePlatformData();
        
        if (sizeChange) {
            m_decodedSize += sizeChange;
            if (imageObserver())
                imageObserver()->decodedSizeChanged(this, sizeChange);
        }
        
        if (!incremental) {
            // Reset the image source, since Image I/O has an underlying cache that it uses
            // while animating that it seems to never clear.
            m_source.clear();
            m_source.setData(m_data.get(), m_allDataReceived);
        }
    }
}
示例#5
0
void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const FloatRect& srcRect, CompositeOperator compositeOp)
{
    if (!m_frame)
        return;
    
    context->save();
    context->setCompositeOperation(compositeOp);
    context->clip(enclosingIntRect(dstRect));
    if (compositeOp != CompositeSourceOver)
        context->beginTransparencyLayer(1.0f);
    context->translate(dstRect.location().x(), dstRect.location().y());
    context->scale(FloatSize(dstRect.width()/srcRect.width(), dstRect.height()/srcRect.height()));
    
    if (m_frame->view()->needsLayout())
        m_frame->view()->layout();
    m_frame->paint(context, enclosingIntRect(srcRect));

    if (compositeOp != CompositeSourceOver)
        context->endTransparencyLayer();

    context->restore();

    if (imageObserver())
        imageObserver()->didDraw(this);
}
示例#6
0
// Drawing Routines
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
                       const FloatRect& src, CompositeOperator op)
{
    startAnimation();

    QPixmap* image = nativeImageForCurrentFrame();
    if (!image)
        return;

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

    IntSize selfSize = size();

    ctxt->save();

    // Set the compositing operation.
    ctxt->setCompositeOperation(op);

    QPainter* painter(ctxt->platformContext());

    if (!image->hasAlpha() && painter->compositionMode() == QPainter::CompositionMode_SourceOver)
        painter->setCompositionMode(QPainter::CompositionMode_Source);

    // Test using example site at
    // http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html
    painter->drawPixmap(dst, *image, src);

    ctxt->restore();

    if (imageObserver())
        imageObserver()->didDraw(this);
}
示例#7
0
void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const TransformationMatrix& patternTransform,
                        const FloatPoint& phase, CompositeOperator op, const FloatRect& destRect)
{
    QPixmap* framePixmap = nativeImageForCurrentFrame();
    if (!framePixmap) // If it's too early we won't have an image yet.
        return;

    QPixmap pixmap = *framePixmap;
    QRect tr = QRectF(tileRect).toRect();
    if (tr.x() || tr.y() || tr.width() != pixmap.width() || tr.height() != pixmap.height())
        pixmap = pixmap.copy(tr);

    QBrush b(pixmap);
    b.setTransform(patternTransform);
    ctxt->save();
    ctxt->setCompositeOperation(op);
    QPainter* p = ctxt->platformContext();
    if (!pixmap.hasAlpha() && p->compositionMode() == QPainter::CompositionMode_SourceOver)
        p->setCompositionMode(QPainter::CompositionMode_Source);
    p->setBrushOrigin(phase);
    p->fillRect(destRect, b);
    ctxt->restore();

    if (imageObserver())
        imageObserver()->didDraw(this);
}
void PDFDocumentImage::updateCachedImageIfNeeded(GraphicsContext* context, const FloatRect& dstRect, const FloatRect& srcRect)
{
    // If we have an existing image, reuse it if we're doing a low-quality paint, even if cache parameters don't match;
    // we'll rerender when we do the subsequent high-quality paint.
    InterpolationQuality interpolationQuality = context->imageInterpolationQuality();
    bool useLowQualityInterpolation = interpolationQuality == InterpolationNone || interpolationQuality == InterpolationLow;

    if (!m_cachedImageBuffer || (!cacheParametersMatch(context, dstRect, srcRect) && !useLowQualityInterpolation)) {
        m_cachedImageBuffer = context->createCompatibleBuffer(enclosingIntRect(dstRect).size());
        if (!m_cachedImageBuffer)
            return;
        GraphicsContext* bufferContext = m_cachedImageBuffer->context();
        if (!bufferContext) {
            m_cachedImageBuffer = nullptr;
            return;
        }

        transformContextForPainting(bufferContext, dstRect, srcRect);
        drawPDFPage(bufferContext);

        m_cachedTransform = context->getCTM(GraphicsContext::DefinitelyIncludeDeviceScale);
        m_cachedDestinationSize = dstRect.size();
        m_cachedSourceRect = srcRect;

        IntSize internalSize = m_cachedImageBuffer->internalSize();
        size_t oldCachedBytes = m_cachedBytes;
        m_cachedBytes = internalSize.width() * internalSize.height() * 4;

        if (imageObserver())
            imageObserver()->decodedSizeChanged(this, safeCast<int>(m_cachedBytes) - safeCast<int>(oldCachedBytes));
    }
}
void BitmapImage::cacheFrame(size_t index)
{
    size_t numFrames = frameCount();
    ASSERT(m_decodedSize == 0 || numFrames > 1);
    
    if (m_frames.size() < numFrames)
        m_frames.grow(numFrames);

    m_frames[index].m_frame = m_source.createFrameAtIndex(index);
    if (numFrames == 1 && m_frames[index].m_frame)
        checkForSolidColor();

    m_frames[index].m_haveMetadata = true;
    m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index);
    if (repetitionCount(false) != cAnimationNone)
        m_frames[index].m_duration = m_source.frameDurationAtIndex(index);
    m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index);

    const IntSize frameSize(index ? m_source.frameSizeAtIndex(index) : m_size);
    if (frameSize != m_size)
        m_hasUniformFrameSize = false;
    if (m_frames[index].m_frame) {
        const int deltaBytes = frameBytes(frameSize);
        m_decodedSize += deltaBytes;
        if (imageObserver())
            imageObserver()->decodedSizeChanged(this, deltaBytes);
    }
}
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;
    }

    context->save();

    // Set the compositing operation.
    if (op == CompositeSourceOver && !frameHasAlphaAtIndex(m_currentFrame))
        context->setCompositeOperation(CompositeCopy);
    else
        context->setCompositeOperation(op);
    context->platformContext()->drawSurfaceToContext(image, dstRect, srcRect, context);

    context->restore();

    if (imageObserver())
        imageObserver()->didDraw(this);
}
示例#11
0
void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const FloatRect& src, 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(), op);
        return;
    }

    IntSize selfSize = size();

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

    // 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);

    // To avoid the unwanted gradient effect (#14017) we use
    // CAIRO_FILTER_NEAREST now, but the real fix will be to have
    // CAIRO_EXTEND_PAD implemented for surfaces in Cairo allowing us to still
    // use bilinear filtering
    cairo_pattern_set_filter(pattern, CAIRO_FILTER_NEAREST);

    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 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());

    cairo_restore(cr);

    if (imageObserver())
        imageObserver()->didDraw(this);
}
void Image::drawImage(GraphicsContext *gc, const FloatRect &dstRect, const FloatRect &srcRect,
                       ColorSpace, CompositeOperator, BlendMode)
{
    JNIEnv* env = WebCore_GetJavaEnv();

    if (!gc || gc->paintingDisabled()) {
        return;
    }

    NativeImagePtr currFrame = nativeImageForCurrentFrame();
    if (!currFrame) {
        return;
    }

    gc->platformContext()->rq().freeSpace(72)
    << (jint)com_sun_webkit_graphics_GraphicsDecoder_DRAWIMAGE
    << currFrame
    << dstRect.x() << dstRect.y()
    << dstRect.width() << dstRect.height()
    << srcRect.x() << srcRect.y()
    << srcRect.width() << srcRect.height();

    if (imageObserver())
        imageObserver()->didDraw(this);
}
示例#13
0
void BitmapImage::cacheFrame(size_t index)
{
    size_t numFrames = frameCount();
    ASSERT(m_decodedSize == 0 || numFrames > 1);
    
    if (m_frames.size() < numFrames)
        m_frames.grow(numFrames);

    m_frames[index].m_frame = m_source.createFrameAtIndex(index);
    if (numFrames == 1 && m_frames[index].m_frame)
        checkForSolidColor();

    m_frames[index].m_orientation = m_source.orientationAtIndex(index);
    m_frames[index].m_haveMetadata = true;
    m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index);
    if (repetitionCount(false) != cAnimationNone)
        m_frames[index].m_duration = m_source.frameDurationAtIndex(index);
    m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index);
    m_frames[index].m_frameBytes = m_source.frameBytesAtIndex(index);

    const IntSize frameSize(index ? m_source.frameSizeAtIndex(index) : m_size);
    if (frameSize != m_size)
        m_hasUniformFrameSize = false;
    if (m_frames[index].m_frame) {
        int deltaBytes = safeCast<int>(m_frames[index].m_frameBytes);
        m_decodedSize += deltaBytes;
        // The fully-decoded frame will subsume the partially decoded data used
        // to determine image properties.
        deltaBytes -= m_decodedPropertiesSize;
        m_decodedPropertiesSize = 0;
        if (imageObserver())
            imageObserver()->decodedSizeChanged(this, deltaBytes);
    }
}
示例#14
0
void SVGImage::draw(GraphicsContext* context, const FloatRect& dstRect, const FloatRect& srcRect, ColorSpace, CompositeOperator compositeOp)
{
    if (!m_page)
        return;

    FrameView* view = m_page->mainFrame()->view();

    context->save();
    context->setCompositeOperation(compositeOp);
    context->clip(enclosingIntRect(dstRect));
    if (compositeOp != CompositeSourceOver)
        context->beginTransparencyLayer(1);
    context->translate(dstRect.location().x(), dstRect.location().y());
    context->scale(FloatSize(dstRect.width() / srcRect.width(), dstRect.height() / srcRect.height()));

    view->resize(size());

    if (view->needsLayout())
        view->layout();
    view->paint(context, IntRect(0, 0, view->width(), view->height()));

    if (compositeOp != CompositeSourceOver)
        context->endTransparencyLayer();

    context->restore();

    if (imageObserver())
        imageObserver()->didDraw(this);
}
示例#15
0
文件: Image.cpp 项目: oroisec/ios
void Image::cacheFrame(size_t index)
{
    size_t numFrames = frameCount();
    ASSERT(m_decodedSize == 0 || numFrames > 1);
    
    if (!m_frames.size() && shouldAnimate()) {            
        // Snag the repetition count.
        m_repetitionCount = m_source.repetitionCount();
        if (m_repetitionCount == cAnimationNone)
            m_animatingImageType = false;
    }
    
    if (m_frames.size() < numFrames)
        m_frames.resize(numFrames);

    m_frames[index].m_frame = m_source.createFrameAtIndex(index);
    if (numFrames == 1 && m_frames[index].m_frame)
        checkForSolidColor();

    if (shouldAnimate())
        m_frames[index].m_duration = m_source.frameDurationAtIndex(index);
    m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index);
    int sizeChange = m_frames[index].m_frame ? m_size.width() * m_size.height() * 4 : 0;

    if (sizeChange) {
        if (imageObserver())
            imageObserver()->decodedSizeChanging(this, sizeChange);
        m_decodedSize += sizeChange;
        if (imageObserver())
            imageObserver()->decodedSizeChanged(this, sizeChange);
    }
}
示例#16
0
NativeImagePtr BitmapImage::frameImageAtIndex(size_t index, float presentationScaleHint)
{
    if (index >= frameCount())
        return nullptr;

    SubsamplingLevel subsamplingLevel = m_source.subsamplingLevelForScale(presentationScaleHint);

    // We may have cached a frame with a higher subsampling level, in which case we need to
    // re-decode with a lower level.
    if (index < m_frames.size() && m_frames[index].m_image && subsamplingLevel < m_frames[index].m_subsamplingLevel) {
        // If the image is already cached, but at too small a size, re-decode a larger version.
        int sizeChange = -m_frames[index].m_frameBytes;
        m_frames[index].clear(true);
        invalidatePlatformData();
        m_decodedSize += sizeChange;
        if (imageObserver())
            imageObserver()->decodedSizeChanged(this, sizeChange);
    }

    // If we haven't fetched a frame yet, do so.
    if (index >= m_frames.size() || !m_frames[index].m_image)
        cacheFrame(index, subsamplingLevel, CacheMetadataAndFrame);

    return m_frames[index].m_image;
}
示例#17
0
void BitmapImage::cacheFrame(size_t index)
{
    size_t numFrames = frameCount();
    ASSERT(m_decodedSize == 0 || numFrames > 1);
    
    if (m_frames.size() < numFrames)
        m_frames.grow(numFrames);

    m_frames[index].m_frame = m_source.createFrameAtIndex(index);
    if (numFrames == 1 && m_frames[index].m_frame)
        checkForSolidColor();

    m_frames[index].m_haveMetadata = true;
    m_frames[index].m_isComplete = m_source.frameIsCompleteAtIndex(index);
    if (repetitionCount(false) != cAnimationNone)
        m_frames[index].m_duration = m_source.frameDurationAtIndex(index);
    m_frames[index].m_hasAlpha = m_source.frameHasAlphaAtIndex(index);

    int sizeChange;
    if (index) {
        IntSize frameSize = m_source.frameSizeAtIndex(index);
        if (frameSize != m_size)
            m_hasUniformFrameSize = false;
        sizeChange = m_frames[index].m_frame ? frameSize.width() * frameSize.height() * 4 : 0;
    } else
        sizeChange = m_frames[index].m_frame ? m_size.width() * m_size.height() * 4 : 0;

    if (sizeChange) {
        m_decodedSize += sizeChange;
        if (imageObserver())
            imageObserver()->decodedSizeChanged(this, sizeChange);
    }
}
示例#18
0
void Image::drawPattern(GraphicsContext& context, const FloatRect& destRect, const FloatRect& tileRect, const AffineTransform& patternTransform,
    const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, BlendMode blendMode)
{
    context.drawPattern(*this, destRect, tileRect, patternTransform, phase, spacing, op, blendMode);

    if (imageObserver())
        imageObserver()->didDraw(this);
}
示例#19
0
void BitmapImage::destroyMetadataAndNotify(size_t frameBytesCleared)
{
    m_isSolidColor = false;
    m_checkedForSolidColor = false;

    if (frameBytesCleared && imageObserver())
        imageObserver()->decodedSizeChanged(this, -safeCast<int>(frameBytesCleared));
}
void BitmapImage::draw(GraphicsContext& context, const FloatRect& dst, const FloatRect& src, CompositeOperator op,
    BlendMode blendMode, ImageOrientationDescription description)
{
    if (!dst.width() || !dst.height() || !src.width() || !src.height())
        return;

    startAnimation();

    auto surface = frameImageAtIndex(m_currentFrame);
    if (!surface) // If it's too early we won't have an image yet.
        return;

    Color color = singlePixelSolidColor();
    if (color.isValid()) {
        fillWithSolidColor(context, dst, color, op);
        return;
    }

    context.save();

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

#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
    IntSize scaledSize = cairoSurfaceSize(surface.get());
    FloatRect adjustedSrcRect = adjustSourceRectForDownSampling(src, scaledSize);
#else
    FloatRect adjustedSrcRect(src);
#endif

    ImageOrientation frameOrientation(description.imageOrientation());
    if (description.respectImageOrientation() == RespectImageOrientation)
        frameOrientation = frameOrientationAtIndex(m_currentFrame);

    FloatRect dstRect = dst;

    if (frameOrientation != DefaultImageOrientation) {
        // ImageOrientation expects the origin to be at (0, 0).
        context.translate(dstRect.x(), dstRect.y());
        dstRect.setLocation(FloatPoint());
        context.concatCTM(frameOrientation.transformFromDefault(dstRect.size()));
        if (frameOrientation.usesWidthAsHeight()) {
            // The destination rectangle 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.
            dstRect = FloatRect(dstRect.x(), dstRect.y(), dstRect.height(), dstRect.width());
        }
    }

    context.platformContext()->drawSurfaceToContext(surface.get(), dstRect, adjustedSrcRect, context);

    context.restore();

    if (imageObserver())
        imageObserver()->didDraw(this);
}
示例#21
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;

//+EAWebKitChange
//5/30/2012
#if ENABLE(IMAGE_COMPRESSION)
    // Check if this is a compressed surface. 
    const void* pCompressedSurfaceUserData = cairo_surface_get_user_data (image, (cairo_user_data_key_t*) ImageCompressionGetUserDataKey());
#endif
//-EAWebKitChange

    if (mayFillWithSolidColor()) {
        fillWithSolidColor(context, dstRect, solidColor(), styleColorSpace, op);
        
//+EAWebKitChange
//5/30/2012
#if ENABLE(IMAGE_COMPRESSION)
        if (pCompressedSurfaceUserData)
            cairo_surface_destroy(image);
#endif
//-EAWebKitChange
        return;
    }

    context->save();

    // Set the compositing operation.
    if (op == CompositeSourceOver && !frameHasAlphaAtIndex(m_currentFrame))
        context->setCompositeOperation(CompositeCopy);
    else
        context->setCompositeOperation(op);
    context->platformContext()->drawSurfaceToContext(image, dstRect, srcRect, context);

    context->restore();

    if (imageObserver())
        imageObserver()->didDraw(this);

//+EAWebKitChange
//5/30/2012
#if ENABLE(IMAGE_COMPRESSION)
    if (pCompressedSurfaceUserData)
        cairo_surface_destroy(image);   
#endif
//-EAWebKitChange
}
示例#22
0
void Image::drawPattern(GraphicsContext* ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform,
                        const FloatPoint& phase, ColorSpace, CompositeOperator op, const FloatRect& destRect)
{
    QPixmap* framePixmap = nativeImageForCurrentFrame();
    if (!framePixmap) // If it's too early we won't have an image yet.
        return;

    // Qt interprets 0 width/height as full width/height so just short circuit.
    QRectF dr = QRectF(destRect).normalized();
    QRect tr = QRectF(tileRect).toRect().normalized();
    if (!dr.width() || !dr.height() || !tr.width() || !tr.height())
        return;

    QPixmap pixmap = *framePixmap;
    if (tr.x() || tr.y() || tr.width() != pixmap.width() || tr.height() != pixmap.height())
        pixmap = pixmap.copy(tr);

    CompositeOperator previousOperator = ctxt->compositeOperation();

    ctxt->setCompositeOperation(!pixmap.hasAlpha() && op == CompositeSourceOver ? CompositeCopy : op);

    QPainter* p = ctxt->platformContext();
    QTransform transform(patternTransform);

    // If this would draw more than one scaled tile, we scale the pixmap first and then use the result to draw.
    if (transform.type() == QTransform::TxScale) {
        QRectF tileRectInTargetCoords = (transform * QTransform().translate(phase.x(), phase.y())).mapRect(tr);

        bool tileWillBePaintedOnlyOnce = tileRectInTargetCoords.contains(dr);
        if (!tileWillBePaintedOnlyOnce) {
            QSizeF scaledSize(float(pixmap.width()) * transform.m11(), float(pixmap.height()) * transform.m22());
            QPixmap scaledPixmap(scaledSize.toSize());
            if (pixmap.hasAlpha())
                scaledPixmap.fill(Qt::transparent);
            {
                QPainter painter(&scaledPixmap);
                painter.setCompositionMode(QPainter::CompositionMode_Source);
                painter.setRenderHints(p->renderHints());
                painter.drawPixmap(QRect(0, 0, scaledPixmap.width(), scaledPixmap.height()), pixmap);
            }
            pixmap = scaledPixmap;
            transform = QTransform::fromTranslate(transform.dx(), transform.dy());
        }
    }

    /* Translate the coordinates as phase is not in world matrix coordinate space but the tile rect origin is. */
    transform *= QTransform().translate(phase.x(), phase.y());
    transform.translate(tr.x(), tr.y());

    QBrush b(pixmap);
    b.setTransform(transform);
    p->fillRect(dr, b);

    ctxt->setCompositeOperation(previousOperator);

    if (imageObserver())
        imageObserver()->didDraw(this);
}
示例#23
0
void BitmapImage::draw(GraphicsContext* context, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op,
                       BlendMode, RespectImageOrientationEnum shouldRespectImageOrientation)
{
    if (!dst.width() || !dst.height() || !src.width() || !src.height())
        return;

    startAnimation();

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

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

    context->save();

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

#if ENABLE(IMAGE_DECODER_DOWN_SAMPLING)
    cairo_surface_t* surface = nativeImage->surface();
    IntSize scaledSize(cairo_image_surface_get_width(surface), cairo_image_surface_get_height(surface));
    FloatRect adjustedSrcRect = adjustSourceRectForDownSampling(src, scaledSize);
#else
    FloatRect adjustedSrcRect(src);
#endif

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

    FloatRect dstRect = dst;

    if (orientation != DefaultImageOrientation) {
        // ImageOrientation expects the origin to be at (0, 0).
        context->translate(dstRect.x(), dstRect.y());
        dstRect.setLocation(FloatPoint());
        context->concatCTM(orientation.transformFromDefault(dstRect.size()));
        if (orientation.usesWidthAsHeight()) {
            // The destination rectangle 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.
            dstRect = FloatRect(dstRect.x(), dstRect.y(), dstRect.height(), dstRect.width());
        }
    }

    context->platformContext()->drawSurfaceToContext(nativeImage->surface(), dstRect, adjustedSrcRect, context);

    context->restore();

    if (imageObserver())
        imageObserver()->didDraw(this);
}
示例#24
0
void PDFDocumentImage::destroyDecodedData(bool)
{
    m_cachedImageBuffer = nullptr;

    if (imageObserver())
        imageObserver()->decodedSizeChanged(this, -safeCast<int>(m_cachedBytes));

    m_cachedBytes = 0;
}
void BitmapImage::destroyMetadataAndNotify(int framesCleared)
{
    m_isSolidColor = false;
    invalidatePlatformData();

    const int deltaBytes = framesCleared * -frameBytes(m_size);
    m_decodedSize += deltaBytes;
    if (deltaBytes && imageObserver())
        imageObserver()->decodedSizeChanged(this, deltaBytes);
}
示例#26
0
void Image::drawPattern(GraphicsContext& ctxt, const FloatRect& tileRect, const AffineTransform& patternTransform,
    const FloatPoint& phase, const FloatSize& spacing, CompositeOperator op, const FloatRect& destRect, BlendMode blendMode)
{
    if (!nativeImageForCurrentFrame())
        return;

    ctxt.drawPattern(*this, tileRect, patternTransform, phase, spacing, op, destRect, blendMode);

    if (imageObserver())
        imageObserver()->didDraw(this);
}
void Image::drawPattern(GraphicsContext* context, const FloatRect& tileRect, const AffineTransform& patternTransform,
                        const FloatPoint& phase, ColorSpace colorSpace, CompositeOperator op, const FloatRect& destRect)
{
    cairo_surface_t* image = nativeImageForCurrentFrame();
    if (!image) // If it's too early we won't have an image yet.
        return;

    cairo_t* cr = context->platformContext()->cr();
    drawPatternToCairoContext(cr, image, size(), tileRect, patternTransform, phase, toCairoOperator(op), destRect);

    if (imageObserver())
        imageObserver()->didDraw(this);
}
示例#28
0
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& destRect, const FloatRect& srcRect, CompositeOperator compositeOp)
{
    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;
    }

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

    // 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.
    CGSize selfSize = size();
    FloatRect adjustedDestRect = destRect;
    if (srcRect.width() != selfSize.width || srcRect.height() != selfSize.height) {
        // A subportion of the image is drawing.  Adjust the destination rect to
        // account for this.
        float xScale = srcRect.width() / destRect.width();
        float yScale = srcRect.height() / destRect.height();
        
        adjustedDestRect.setLocation(FloatPoint(destRect.x() - srcRect.x() / xScale, destRect.y() - srcRect.y() / yScale));
        adjustedDestRect.setSize(FloatSize(size().width() / xScale, size().height() / yScale));
        
        CGContextClipToRect(context, destRect);
    }

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

    // Flip the coords.
    ctxt->setCompositeOperation(compositeOp);
    CGContextTranslateCTM(context, adjustedDestRect.x(), adjustedDestRect.bottom());
    CGContextScaleCTM(context, 1, -1);
    adjustedDestRect.setLocation(FloatPoint());

    // Draw the image.
    CGContextDrawImage(context, adjustedDestRect, image);
        
    ctxt->restore();
    
    startAnimation();

    if (imageObserver())
        imageObserver()->didDraw(this);
}
示例#29
0
void BitmapImage::destroyMetadataAndNotify(int framesCleared)
{
    m_isSolidColor = false;
    m_checkedForSolidColor = false;
    invalidatePlatformData();

    int deltaBytes = framesCleared * -frameBytes(m_size);
    m_decodedSize += deltaBytes;
    if (framesCleared > 0) {
        deltaBytes -= m_decodedPropertiesSize;
        m_decodedPropertiesSize = 0;
    }
    if (deltaBytes && imageObserver())
        imageObserver()->decodedSizeChanged(this, deltaBytes);
}
示例#30
0
void BitmapImage::destroyMetadataAndNotify(unsigned frameBytesCleared)
{
    m_isSolidColor = false;
    m_checkedForSolidColor = false;
    invalidatePlatformData();

    ASSERT(m_decodedSize >= frameBytesCleared);
    m_decodedSize -= frameBytesCleared;
    if (frameBytesCleared > 0) {
        frameBytesCleared += m_decodedPropertiesSize;
        m_decodedPropertiesSize = 0;
    }
    if (frameBytesCleared && imageObserver())
        imageObserver()->decodedSizeChanged(this, -safeCast<int>(frameBytesCleared));
}