コード例 #1
0
void VideoElement::Render(ManagedRenderContext renderContext)
{
	Graphics::Bitmap* bitmap = get_Bitmap();
	if (bitmap)
	{
		if (true)
		{
			gm::RectF dstRect(0.0f, 0.0f, float(bitmap->GetWidth()), float(bitmap->GetHeight()));
			renderContext.DrawBitmap(bitmap, dstRect, get_Opacity());
		}
		else
		{
			Graphics::RenderTarget* rt = renderContext.m_p->GetRT();

			ImmediateRenderContext* imm = static_cast<ImmediateRenderContext*>(renderContext.m_p);
			rt->m_modelView = imm->m_transform;
			rt->m_modelViewProjection = rt->m_projection * rt->m_modelView;

			gm::RectF dstRect(80.0f, 20.0f, float(bitmap->GetWidth()), float(bitmap->GetHeight()));
			//*get_DestRect()

			Graphics::Direct10::s.Render(renderContext.m_p->GetRT(), bitmap, dstRect);
		}
	}
}
コード例 #2
0
ファイル: ImageBitmap.cpp プロジェクト: yuqile/chromium
ImageBitmap::ImageBitmap(HTMLVideoElement* video, const IntRect& cropRect)
    : m_imageElement(nullptr)
    , m_cropRect(cropRect)
    , m_bitmapOffset(IntPoint())
{
    IntSize playerSize;

    if (video->webMediaPlayer())
        playerSize = video->webMediaPlayer()->naturalSize();

    IntRect videoRect = IntRect(IntPoint(), playerSize);
    IntRect srcRect = intersection(cropRect, videoRect);
    IntRect dstRect(IntPoint(), srcRect.size());

    OwnPtr<ImageBuffer> buffer = ImageBuffer::create(videoRect.size());
    if (!buffer)
        return;

    buffer->canvas()->clipRect(dstRect);
    buffer->canvas()->translate(-srcRect.x(), -srcRect.y());

    video->paintCurrentFrame(buffer->canvas(), videoRect, nullptr);
    m_bitmap = buffer->newImageSnapshot();
    m_bitmapRect = IntRect(IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRect.y())), srcRect.size());
}
コード例 #3
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);
}
コード例 #4
0
void
ClientLayerManager::MakeSnapshotIfRequired()
{
  if (!mShadowTarget) {
    return;
  }
  if (mWidget) {
    if (CompositorChild* remoteRenderer = GetRemoteRenderer()) {
      nsIntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents());
      SurfaceDescriptor inSnapshot;
      if (!bounds.IsEmpty() &&
          mForwarder->AllocSurfaceDescriptor(bounds.Size().ToIntSize(),
                                             gfxContentType::COLOR_ALPHA,
                                             &inSnapshot) &&
          remoteRenderer->SendMakeSnapshot(inSnapshot, bounds)) {
        RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(inSnapshot);
        DrawTarget* dt = mShadowTarget->GetDrawTarget();
        Rect dstRect(bounds.x, bounds.y, bounds.width, bounds.height);
        Rect srcRect(0, 0, bounds.width, bounds.height);
        dt->DrawSurface(surf, dstRect, srcRect,
                        DrawSurfaceOptions(),
                        DrawOptions(1.0f, CompositionOp::OP_OVER));
      }
      mForwarder->DestroySharedSurface(&inSnapshot);
    }
  }
  mShadowTarget = nullptr;
}
コード例 #5
0
ファイル: ImageBitmap.cpp プロジェクト: esprehn/mojo
ImageBitmap::ImageBitmap(HTMLVideoElement* video, const IntRect& cropRect)
    : m_imageElement(nullptr)
    , m_cropRect(cropRect)
    , m_bitmapOffset(IntPoint())
{
    IntSize playerSize;

    if (video->webMediaPlayer())
        playerSize = video->webMediaPlayer()->naturalSize();

    IntRect videoRect = IntRect(IntPoint(), playerSize);
    IntRect srcRect = intersection(cropRect, videoRect);
    IntRect dstRect(IntPoint(), srcRect.size());

    OwnPtr<ImageBuffer> buf = ImageBuffer::create(videoRect.size());
    if (!buf)
        return;
    GraphicsContext* c = buf->context();
    c->clip(dstRect);
    c->translate(-srcRect.x(), -srcRect.y());
    video->paintCurrentFrameInContext(c, videoRect);
    m_bitmap = buf->copyImage(DontCopyBackingStore);
    m_bitmapRect = IntRect(IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRect.y())), srcRect.size());

    ScriptWrappable::init(this);
}
コード例 #6
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;
    }

    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);
}
コード例 #7
0
ファイル: ImageQt.cpp プロジェクト: jackiekaon/owb-mirror
// Drawing Routines
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
                       const FloatRect& src, CompositeOperator op)
{
    QPixmap* image = nativeImageForCurrentFrame();
    if (!image)
        return;
    
    if (mayFillWithSolidColor()) {
        fillWithSolidColor(ctxt, dst, solidColor(), op);
        return;
    }

    IntSize selfSize = size();
    FloatRect srcRect(src);
    FloatRect dstRect(dst);

    ctxt->save();

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

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

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

    ctxt->restore();

    startAnimation();
}
コード例 #8
0
ファイル: ImageCairo.cpp プロジェクト: emuikernel/EAWebKit
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
}
コード例 #9
0
ファイル: ImageImpl.cpp プロジェクト: fffonion/V8
HRESULT CImageImpl::CreateHBITMAP(HDC hDC, HBITMAP* pHBITMAP)
{
    USE_CLASS_DATA(CLASS_DATA_MEMBER_LIST);

    if (m_pImage == NULL)
        return S_FALSE;

    if (IsBadWritePtr(pHBITMAP, sizeof(HBITMAP)))
        return E_POINTER;
    *pHBITMAP = NULL;

    INT width = m_pImage->GetWidth();
    INT height = m_pImage->GetHeight();

    HDC hMemDC = NULL;
    HBITMAP hBitmap = NULL;
    if (hDC == NULL) {
        HDC hScreenDC = ::GetDC(NULL);
        if (hScreenDC == NULL)
            return S_FALSE;
        hMemDC = ::CreateCompatibleDC(hScreenDC);
        hBitmap = ::CreateCompatibleBitmap(hScreenDC, width, height);
        ::ReleaseDC(NULL, hScreenDC);
    } else {
        hMemDC = ::CreateCompatibleDC(hDC);
        hBitmap = ::CreateCompatibleBitmap(hDC, width, height);
    }
    HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hMemDC, hBitmap);
    CRect dstRect(0, 0, width, height);
    ::FillRect(hMemDC, &dstRect, (HBRUSH)::GetStockObject(WHITE_BRUSH));
    HRESULT hr = Render(hMemDC, &dstRect, NULL, NULL);
    ::SelectObject(hMemDC, hOldBitmap);
    ::DeleteDC(hMemDC);

    if (hr != S_OK) {
        ::DeleteObject(hBitmap);
        return S_FALSE;
    }

    *pHBITMAP = hBitmap;
    return S_OK;


    //if (m_pImage == NULL)
    //    return S_FALSE;

    //if (IsBadWritePtr(pHBITMAP, sizeof(HBITMAP)))
    //    return E_POINTER;
    //*pHBITMAP = NULL;

    //HBITMAP hBitmap = m_pImage->MakeBitmap(hDC);
    //if (hBitmap == NULL) 
    //    return S_FALSE;

    //*pHBITMAP = hBitmap;
    //return S_OK;
}
コード例 #10
0
void
ClientLayerManager::MakeSnapshotIfRequired()
{
  if (!mShadowTarget) {
    return;
  }
  if (mWidget) {
    if (CompositorBridgeChild* remoteRenderer = GetRemoteRenderer()) {
      // The compositor doesn't draw to a different sized surface
      // when there's a rotation. Instead we rotate the result
      // when drawing into dt
      LayoutDeviceIntRect outerBounds;
      mWidget->GetBounds(outerBounds);

      IntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents());
      if (mTargetRotation) {
        bounds =
          RotateRect(bounds, outerBounds.ToUnknownRect(), mTargetRotation);
      }

      SurfaceDescriptor inSnapshot;
      if (!bounds.IsEmpty() &&
          mForwarder->AllocSurfaceDescriptor(bounds.Size(),
                                             gfxContentType::COLOR_ALPHA,
                                             &inSnapshot)) {

        // Make a copy of |inSnapshot| because the call to send it over IPC
        // will call forget() on the Shmem inside, and zero it out.
        SurfaceDescriptor outSnapshot = inSnapshot;

        if (remoteRenderer->SendMakeSnapshot(inSnapshot, bounds)) {
          RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(outSnapshot);
          DrawTarget* dt = mShadowTarget->GetDrawTarget();

          Rect dstRect(bounds.x, bounds.y, bounds.width, bounds.height);
          Rect srcRect(0, 0, bounds.width, bounds.height);

          gfx::Matrix rotate =
            ComputeTransformForUnRotation(outerBounds.ToUnknownRect(),
                                          mTargetRotation);

          gfx::Matrix oldMatrix = dt->GetTransform();
          dt->SetTransform(rotate * oldMatrix);
          dt->DrawSurface(surf, dstRect, srcRect,
                          DrawSurfaceOptions(),
                          DrawOptions(1.0f, CompositionOp::OP_OVER));
          dt->SetTransform(oldMatrix);
        }
        mForwarder->DestroySurfaceDescriptor(&outSnapshot);
      }
    }
  }
  mShadowTarget = nullptr;
}
コード例 #11
0
bool FBORenderStrategy::render(Content* content, Image* renderImage)
{
    if (!renderImage)
        return false;

    glWidget->makeCurrent();
    QSize size(renderImage->width(), renderImage->height());
    createFBOs(size);

    // Render frame into multisample FBO
    QPainter painter(multisampleFBO);
    painter.setRenderHints(QPainter::Antialiasing |
                           QPainter::TextAntialiasing |
                           QPainter::SmoothPixmapTransform, true);
    content->paintContent(&painter);
    painter.end();

    // Blit from multisample to resolve FBO.
    // Rects are setup so the image is vertically flipped when blitted
    // so when we read the pixels back they are the right way up.
    // OpenGL does everything "upside down".
    QRect srcRect(0, 0, renderImage->width(), renderImage->height());
    QRect dstRect(0, renderImage->height(),
                  renderImage->width(), -renderImage->height());
    QGLFramebufferObject::blitFramebuffer(resolveFBO, srcRect,
                                          multisampleFBO, dstRect);

    // Read back the pixels from the resolve FBO
    resolveFBO->bind();
    glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
    glPixelStorei(GL_PACK_ALIGNMENT, 1);
    
    if (renderImage->hasAlpha()) {
        glPixelStorei(GL_UNPACK_ROW_LENGTH,   0);
        glPixelStorei(GL_UNPACK_ALIGNMENT,    4);
        glReadPixels(0, 0, renderImage->width(), renderImage->height(),
                 GL_RGBA, GL_UNSIGNED_BYTE, renderImage->pixels());
    }
    else {
        glPixelStorei(GL_UNPACK_ROW_LENGTH,   0);
        glPixelStorei(GL_UNPACK_ALIGNMENT,    3);
        glReadPixels(0, 0, renderImage->width(), renderImage->height(),
                 GL_RGB, GL_UNSIGNED_BYTE, renderImage->pixels());
    }
    
    glPopClientAttrib();

    resolveFBO->release();
    glWidget->doneCurrent();

    return true;
}
コード例 #12
0
ファイル: skia_window_win.cpp プロジェクト: jrflga/aseprite
void SkiaWindow::paintImpl(HDC hdc)
{
  switch (m_backend) {

    case Backend::NONE:
      paintHDC(hdc);
      break;

#if SK_SUPPORT_GPU

    case Backend::GL:
    case Backend::ANGLE:
      // Flush operations to the SkCanvas
      {
        SkiaSurface* surface = static_cast<SkiaSurface*>(m_display->getSurface());
        surface->flush();
      }

      // If we are drawing inside an off-screen texture, here we have
      // to blit that texture into the main framebuffer.
      if (m_skSurfaceDirect != m_skSurface) {
        GrBackendObject texID = m_skSurface->getTextureHandle(
          SkSurface::kFlushRead_BackendHandleAccess);

        GrBackendTextureDesc texDesc;
        texDesc.fFlags = kNone_GrBackendTextureFlag;
        texDesc.fOrigin = kBottomLeft_GrSurfaceOrigin;
        texDesc.fWidth = m_lastSize.w / scale();
        texDesc.fHeight = m_lastSize.h / scale();
        texDesc.fConfig = kSkia8888_GrPixelConfig;
        texDesc.fSampleCnt = m_sampleCount;
        texDesc.fTextureHandle = texID;
        SkAutoTUnref<SkImage> image(SkImage::NewFromTexture(m_grCtx, texDesc));

        SkRect dstRect(SkRect::MakeWH(SkIntToScalar(m_lastSize.w),
                                      SkIntToScalar(m_lastSize.h)));

        SkPaint paint;
        m_skSurfaceDirect->getCanvas()->drawImageRect(
          image, dstRect, &paint,
          SkCanvas::kStrict_SrcRectConstraint);

        m_skSurfaceDirect->getCanvas()->flush();
      }

      // Flush GL context
      m_glCtx->gl()->fFunctions.fFlush();
      break;

#endif // SK_SUPPORT_GPU
  }
}
コード例 #13
0
ファイル: sdlw_surface.cpp プロジェクト: degarashi/resonant
	SPSurface Surface::resize(const spn::Size& s) const {
		auto bm = getBlendMode();
		auto* self = const_cast<Surface*>(this);
		self->setBlendMode(SDL_BLENDMODE_NONE);

		auto sz = getSize();
		spn::Rect srcRect(0,sz.width, 0,sz.height),
				dstRect(0,s.width, 0,s.height);
		SPSurface nsfc = Create(s.width, s.height, getFormat().format);
		blitScaled(nsfc, srcRect, dstRect);

		self->setBlendMode(bm);
		return nsfc;
	}
コード例 #14
0
ファイル: text.cpp プロジェクト: arrosado/2d-engine
void Font::BitmapCharacter(float x, float y, float w, float h, int character)
{
	WorldRect dstRect(x, y, w, h);
	ScreenRect* psrcRect;
	psrcRect = &atlas->sourceRectangles[character];
	glBegin(GL_QUADS);
	{
		glTexCoord2d(psrcRect->fLeft(), psrcRect->fTop());	glVertex2f(dstRect.iLeft(), dstRect.iBottom());
		glTexCoord2d(psrcRect->fRight(), psrcRect->fTop());	glVertex2f(dstRect.iRight(), dstRect.iBottom());
		glTexCoord2d(psrcRect->fRight(), psrcRect->fBottom());	glVertex2f(dstRect.iRight(),  dstRect.iTop());
		glTexCoord2d(psrcRect->fLeft(), psrcRect->fBottom());	glVertex2f(dstRect.iLeft(),  dstRect.iTop());
	}
	glEnd();
}
コード例 #15
0
void Win8DeskDuplicationThread::processDirtyRects(size_t dirtyCount,
                                                  WinD3D11Texture2D *acquiredDesktopImage)
{
  _ASSERT(dirtyCount <= m_dirtyRects.size());

  Region changedRegion;

  Rect rect;
  Dimension stageDim(&m_targetRect);
  Rect stageRect = stageDim.getRect();
  for (size_t iRect = 0; iRect < dirtyCount; iRect++) {
    rect.fromWindowsRect(&m_dirtyRects[iRect]);

    if (!stageRect.isFullyContainRect(&rect)) {
      rect = rect.intersection(&stageRect);
      /* Disabled the followed throwing because it realy may happen and better is to see any picture
      // instead of a black screen.
      StringStorage errMess;
      errMess.format(_T("During processDirtyRects has been got a rect (%d, %d, %dx%d) which outside")
                     _T(" from the stage rect (%d, %d, %dx%d)"),
                     rect.left, rect.top, rect.getWidth(), rect.getHeight(),
                     stageRect.left, stageRect.top, stageRect.getWidth(), stageRect.getHeight());
      throw Exception(errMess.getString());
      */
    }

    m_device.copySubresourceRegion(m_stageTexture2D.getTexture(), rect.left, rect.top,
                                   acquiredDesktopImage->getTexture(), &rect, 0, 1);

    WinDxgiSurface surface(m_stageTexture2D.getTexture());
    WinAutoMapDxgiSurface autoMapSurface(&surface, DXGI_MAP_READ);

    Rect dstRect(rect);
    // Translate the rect to the frame buffer coordinates.
    dstRect.move(m_targetRect.left, m_targetRect.top);
    m_log->debug(_T("Destination dirty rect = %d, %d, %dx%d"), dstRect.left, dstRect.top, dstRect.getWidth(), dstRect.getHeight());

    stageDim.width = static_cast<int> (autoMapSurface.getStride() / 4);
    m_auxiliaryFrameBuffer.setPropertiesWithoutResize(&stageDim, &m_targetFb->getPixelFormat());
    m_auxiliaryFrameBuffer.setBuffer(autoMapSurface.getBuffer());
    m_targetFb->copyFrom(&dstRect, &m_auxiliaryFrameBuffer, rect.left, rect.top);
    m_auxiliaryFrameBuffer.setBuffer(0);

    changedRegion.addRect(&dstRect);
  }

  m_duplListener->onFrameBufferUpdate(&changedRegion);
}
コード例 #16
0
void
ClientLayerManager::MakeSnapshotIfRequired()
{
  if (!mShadowTarget) {
    return;
  }
  if (mWidget) {
    if (CompositorChild* remoteRenderer = GetRemoteRenderer()) {
      // The compositor doesn't draw to a different sized surface
      // when there's a rotation. Instead we rotate the result
      // when drawing into dt
      nsIntRect outerBounds;
      mWidget->GetBounds(outerBounds);

      nsIntRect bounds = ToOutsideIntRect(mShadowTarget->GetClipExtents());
      if (mTargetRotation) {
        bounds = RotateRect(bounds, outerBounds, mTargetRotation);
      }

      SurfaceDescriptor inSnapshot;
      if (!bounds.IsEmpty() &&
          mForwarder->AllocSurfaceDescriptor(bounds.Size().ToIntSize(),
                                             gfxContentType::COLOR_ALPHA,
                                             &inSnapshot) &&
          remoteRenderer->SendMakeSnapshot(inSnapshot, bounds)) {
        RefPtr<DataSourceSurface> surf = GetSurfaceForDescriptor(inSnapshot);
        DrawTarget* dt = mShadowTarget->GetDrawTarget();

        Rect dstRect(bounds.x, bounds.y, bounds.width, bounds.height);
        Rect srcRect(0, 0, bounds.width, bounds.height);

        gfx::Matrix rotate = ComputeTransformForUnRotation(outerBounds, mTargetRotation);

        gfx::Matrix oldMatrix = dt->GetTransform();
        dt->SetTransform(oldMatrix * rotate);
        dt->DrawSurface(surf, dstRect, srcRect,
                        DrawSurfaceOptions(),
                        DrawOptions(1.0f, CompositionOp::OP_OVER));
        dt->SetTransform(oldMatrix);
      }
      mForwarder->DestroySharedSurface(&inSnapshot);
    }
  }
  mShadowTarget = nullptr;
}
コード例 #17
0
ファイル: ImageSyllable.cpp プロジェクト: PyroOS/Pyro
// Drawing Routines
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst,
                 const FloatRect& src, CompositeOperator op)
{
    os::Bitmap* image = nativeImageForCurrentFrame();
    if (!image) // If it's too early we won't have an image yet.
        return;
        
    if (mayFillWithSolidColor()) {
        fillWithSolidColor(ctxt, dst, solidColor(), op);
        return;
    }

	//DEBUG( "Image::draw() %f %f\n", image->GetBounds().Width(), image->GetBounds().Height() );

    IntSize selfSize = size();
    FloatRect srcRect(src);
    FloatRect dstRect(dst);

    ctxt->save();

    // Set the compositing operation.
    ctxt->setCompositeOperation(op);
    
    os::View* view = ctxt->platformContext();
    
    os::Rect cSrc = srcRect;
    os::Rect cDst = dstRect;
    cSrc.Resize( 0, 0, -1, -1 );
    cDst.Resize( 0, 0, -1, -1 );
    if( !image->GetBounds().Includes( cSrc ) )
    	DEBUG( "Error: Image::draw(): Source size larger than bitmap\n" );
    view->DrawBitmap( image, cSrc & image->GetBounds(), cDst );

#if 0
    QPainter* painter(ctxt->platformContext());

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

    startAnimation();
}
コード例 #18
0
ImageBitmap::ImageBitmap(HTMLVideoElement* video, const IntRect& cropRect)
    : m_cropRect(cropRect)
    , m_imageElement(0)
    , m_bitmapOffset(IntPoint())
{
    IntRect videoRect = IntRect(IntPoint(), video->player()->naturalSize());
    IntRect srcRect = intersection(cropRect, videoRect);
    IntRect dstRect(IntPoint(), srcRect.size());

    OwnPtr<ImageBuffer> buf = ImageBuffer::create(videoRect.size(), 1, UnacceleratedNonPlatformBuffer);
    GraphicsContext* c = buf->context();
    c->clip(dstRect);
    c->translate(-srcRect.x(), -srcRect.y());
    video->paintCurrentFrameInContext(c, videoRect);
    m_bitmap = buf->copyImage(DontCopyBackingStore);
    m_bitmapRect = IntRect(IntPoint(max(0, -cropRect.x()), max(0, -cropRect.y())), srcRect.size());

    ScriptWrappable::init(this);
}
コード例 #19
0
ファイル: ImageBitmap.cpp プロジェクト: eth-srl/BlinkER
ImageBitmap::ImageBitmap(HTMLVideoElement* video, const IntRect& cropRect)
    : m_imageElement(nullptr)
    , m_cropRect(cropRect)
    , m_bitmapOffset(IntPoint())
{
    IntSize playerSize;

    if (video->webMediaPlayer())
        playerSize = video->webMediaPlayer()->naturalSize();

    IntRect videoRect = IntRect(IntPoint(), playerSize);
    IntRect srcRect = intersection(cropRect, videoRect);
    IntRect dstRect(IntPoint(), srcRect.size());

    OwnPtr<ImageBuffer> buffer = ImageBuffer::create(videoRect.size());
    if (!buffer)
        return;

    OwnPtr<GraphicsContext> extraGraphicsContext;
    OwnPtr<DisplayItemList> displayItemList;
    GraphicsContext* context;
    if (RuntimeEnabledFeatures::slimmingPaintEnabled()) {
        displayItemList = DisplayItemList::create();
        extraGraphicsContext = adoptPtr(new GraphicsContext(0, displayItemList.get()));
        context = extraGraphicsContext.get();
    } else {
        context = buffer->context();
    }

    {
        DrawingRecorder recorder(context, buffer->displayItemClient(), DisplayItem::VideoBitmap, videoRect);
        context->clip(dstRect);
        context->translate(-srcRect.x(), -srcRect.y());
    }

    if (RuntimeEnabledFeatures::slimmingPaintEnabled())
        displayItemList->replay(buffer->context());

    video->paintCurrentFrameInContext(buffer->context(), videoRect);
    m_bitmap = buffer->copyImage(DontCopyBackingStore);
    m_bitmapRect = IntRect(IntPoint(std::max(0, -cropRect.x()), std::max(0, -cropRect.y())), srcRect.size());
}
コード例 #20
0
ファイル: Magnify.cpp プロジェクト: AmirAbrams/haiku
rgb_color
TOSMagnify::ColorAtSelection()
{
	float x, y;
	fParent->SelectionLoc(&x, &y);
	BRect srcRect(x, y, x, y);
	BRect dstRect(0, 0, 0, 0);
	fPixel->Lock();
	fPixelView->DrawBitmap(fBitmap, srcRect, dstRect);
	fPixelView->Sync();
	fPixel->Unlock();

	uint32 pixel = *((uint32*)fPixel->Bits());
	rgb_color c;
	c.alpha = pixel >> 24;
	c.red = (pixel >> 16) & 0xFF;
	c.green = (pixel >> 8) & 0xFF;
	c.blue = pixel & 0xFF;

	return c;
}
コード例 #21
0
ファイル: ImageCairo.cpp プロジェクト: oroisec/ios
void Image::draw(GraphicsContext* ctxt, const FloatRect& dst, const FloatRect& src, CompositeOperator op)
{
    cairo_t* context = ctxt->platformContext();

    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 selfSize = size();                       
    FloatRect srcRect(src);
    FloatRect dstRect(dst);

    cairo_save(context);

    // Set the compositing operation.
    setCompositingOperation(context, op, frameHasAlphaAtIndex(m_currentFrame));
    
    // 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);
    float scaleX = srcRect.width() / dstRect.width();
    float scaleY = srcRect.height() / dstRect.height();
    cairo_matrix_t mat = { scaleX,  0, 0 , scaleY, srcRect.x(), srcRect.y() };
    cairo_pattern_set_matrix(pattern, &mat);

    // Draw the image.
    cairo_translate(context, dstRect.x(), dstRect.y());
    cairo_set_source(context, pattern);
    cairo_rectangle(context, 0, 0, dstRect.width(), dstRect.height());
    cairo_fill(context);

    cairo_restore(context);

    startAnimation();

}
コード例 #22
0
// Drawing Routines
void BitmapImage::draw(GraphicsContext* ctxt, const FloatRect& dst, const FloatRect& src, ColorSpace styleColorSpace, CompositeOperator op)
{
    if (!m_source.initialized())
        return;

    // Spin the animation to the correct frame before we try to draw it, so we
    // don't draw an old frame and then immediately need to draw a newer one,
    // causing flicker and wasting CPU.
    startAnimation();

    BBitmap* image = nativeImageForCurrentFrame();
    if (!image || !image->IsValid()) // If the image hasn't fully loaded.
        return;

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

    ctxt->save();
    ctxt->setCompositeOperation(op);

    BRect srcRect(src);
    BRect dstRect(dst);

    // Test using example site at
    // http://www.meyerweb.com/eric/css/edge/complexspiral/demo.html
    ctxt->platformContext()->SetDrawingMode(B_OP_ALPHA);
    uint32 options = 0;
    if (ctxt->imageInterpolationQuality() == InterpolationDefault
        || ctxt->imageInterpolationQuality() > InterpolationLow) {
        options |= B_FILTER_BITMAP_BILINEAR;
    }
    ctxt->platformContext()->DrawBitmapAsync(image, srcRect, dstRect, options);
    ctxt->restore();

    if (imageObserver())
        imageObserver()->didDraw(this);
}
コード例 #23
0
ファイル: render_strategy.cpp プロジェクト: hatsch/webvfx
bool GLWidgetRenderStrategy::render(Content* content, Image* renderImage)
{
    if (!renderImage)
        return false;

    glWidget->makeCurrent();
    QSize size(renderImage->width(), renderImage->height());
    createFBO(size);

    // Render frame into QGLWidget.
    // This isn't really valid for a hidden QGLWidget due to the OpenGL
    // "pixel ownership test". But it works with some graphics drivers.
    QPainter painter(glWidget);
    painter.setRenderHints(QPainter::Antialiasing |
                           QPainter::TextAntialiasing |
                           QPainter::SmoothPixmapTransform, true);
    content->paintContent(&painter);
    painter.end();

    // Blit from QGLWidget to FBO, flipping image vertically
    QRect srcRect(0, 0, renderImage->width(), renderImage->height());
    QRect dstRect(0, renderImage->height(),
                  renderImage->width(), -renderImage->height());
    QGLFramebufferObject::blitFramebuffer(fbo, srcRect, 0, dstRect);

    // Read back the pixels from the FBO
    fbo->bind();
    glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
    glPixelStorei(GL_PACK_ALIGNMENT, 1);
    glPixelStorei(GL_PACK_ROW_LENGTH, renderImage->bytesPerLine() / 3);
    glReadPixels(0, 0, renderImage->width(), renderImage->height(),
                 GL_RGB, GL_UNSIGNED_BYTE, renderImage->pixels());
    glPopClientAttrib();
    fbo->release();
    glWidget->doneCurrent();

    return true;
}
コード例 #24
0
GrTexture* GaussianBlur(GrContext* context,
                        GrTexture* srcTexture,
                        bool canClobberSrc,
                        const SkRect& rect,
                        bool cropToRect,
                        float sigmaX,
                        float sigmaY) {
    SkASSERT(context);

    SkIRect clearRect;
    int scaleFactorX, radiusX;
    int scaleFactorY, radiusY;
    int maxTextureSize = context->caps()->maxTextureSize();
    sigmaX = adjust_sigma(sigmaX, maxTextureSize, &scaleFactorX, &radiusX);
    sigmaY = adjust_sigma(sigmaY, maxTextureSize, &scaleFactorY, &radiusY);

    SkRect srcRect(rect);
    scale_rect(&srcRect, 1.0f / scaleFactorX, 1.0f / scaleFactorY);
    srcRect.roundOut(&srcRect);
    scale_rect(&srcRect, static_cast<float>(scaleFactorX),
                         static_cast<float>(scaleFactorY));

    // setup new clip
    GrClip clip(SkRect::MakeWH(srcRect.width(), srcRect.height()));

    SkASSERT(kBGRA_8888_GrPixelConfig == srcTexture->config() ||
             kRGBA_8888_GrPixelConfig == srcTexture->config() ||
             kAlpha_8_GrPixelConfig == srcTexture->config());

    GrSurfaceDesc desc;
    desc.fFlags = kRenderTarget_GrSurfaceFlag;
    desc.fWidth = SkScalarFloorToInt(srcRect.width());
    desc.fHeight = SkScalarFloorToInt(srcRect.height());
    desc.fConfig = srcTexture->config();

    GrTexture* dstTexture;
    GrTexture* tempTexture;
    SkAutoTUnref<GrTexture> temp1, temp2;

    temp1.reset(context->textureProvider()->refScratchTexture(
        desc, GrTextureProvider::kApprox_ScratchTexMatch));
    dstTexture = temp1.get();
    if (canClobberSrc) {
        tempTexture = srcTexture;
    } else {
        temp2.reset(context->textureProvider()->refScratchTexture(
            desc, GrTextureProvider::kApprox_ScratchTexMatch));
        tempTexture = temp2.get();
    }

    if (NULL == dstTexture || NULL == tempTexture) {
        return NULL;
    }

    GrDrawContext* drawContext = context->drawContext();
    if (!drawContext) {
        return NULL;
    }

    for (int i = 1; i < scaleFactorX || i < scaleFactorY; i *= 2) {
        GrPaint paint;
        SkMatrix matrix;
        matrix.setIDiv(srcTexture->width(), srcTexture->height());
        SkRect dstRect(srcRect);
        if (cropToRect && i == 1) {
            dstRect.offset(-dstRect.fLeft, -dstRect.fTop);
            SkRect domain;
            matrix.mapRect(&domain, rect);
            domain.inset(i < scaleFactorX ? SK_ScalarHalf / srcTexture->width() : 0.0f,
                         i < scaleFactorY ? SK_ScalarHalf / srcTexture->height() : 0.0f);
            SkAutoTUnref<GrFragmentProcessor> fp(   GrTextureDomainEffect::Create(
                paint.getProcessorDataManager(),
                srcTexture,
                matrix,
                domain,
                GrTextureDomain::kDecal_Mode,
                GrTextureParams::kBilerp_FilterMode));
            paint.addColorProcessor(fp);
        } else {
            GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode);
            paint.addColorTextureProcessor(srcTexture, matrix, params);
        }
        scale_rect(&dstRect, i < scaleFactorX ? 0.5f : 1.0f,
                             i < scaleFactorY ? 0.5f : 1.0f);
        drawContext->drawNonAARectToRect(dstTexture->asRenderTarget(), clip, paint, SkMatrix::I(),
                                         dstRect, srcRect);
        srcRect = dstRect;
        srcTexture = dstTexture;
        SkTSwap(dstTexture, tempTexture);
    }

    const SkIRect srcIRect = srcRect.roundOut();

    // For really small blurs(Certainly no wider than 5x5 on desktop gpus) it is faster to just
    // launch a single non separable kernel vs two launches
    if (sigmaX > 0.0f && sigmaY > 0 &&
            (2 * radiusX + 1) * (2 * radiusY + 1) <= MAX_KERNEL_SIZE) {
        // We shouldn't be scaling because this is a small size blur
        SkASSERT((scaleFactorX == scaleFactorY) == 1);
        SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
        convolve_gaussian_2d(drawContext, dstTexture->asRenderTarget(), clip, srcRect, dstRect,
                             srcTexture, radiusX, radiusY, sigmaX, sigmaY, cropToRect, srcIRect);
        srcTexture = dstTexture;
        srcRect = dstRect;
        SkTSwap(dstTexture, tempTexture);

    } else {
        if (sigmaX > 0.0f) {
            if (scaleFactorX > 1) {
                // Clear out a radius to the right of the srcRect to prevent the
                // X convolution from reading garbage.
                clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
                                              radiusX, srcIRect.height());
                drawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0, false);
            }
            SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
            convolve_gaussian(drawContext, dstTexture->asRenderTarget(), clip, srcRect, dstRect,
                              srcTexture, Gr1DKernelEffect::kX_Direction, radiusX, sigmaX,
                              cropToRect);
            srcTexture = dstTexture;
            srcRect = dstRect;
            SkTSwap(dstTexture, tempTexture);
        }

        if (sigmaY > 0.0f) {
            if (scaleFactorY > 1 || sigmaX > 0.0f) {
                // Clear out a radius below the srcRect to prevent the Y
                // convolution from reading garbage.
                clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
                                              srcIRect.width(), radiusY);
                drawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0, false);
            }

            SkRect dstRect = SkRect::MakeWH(srcRect.width(), srcRect.height());
            convolve_gaussian(drawContext, dstTexture->asRenderTarget(), clip, srcRect,
                              dstRect, srcTexture, Gr1DKernelEffect::kY_Direction, radiusY, sigmaY,
                              cropToRect);
            srcTexture = dstTexture;
            srcRect = dstRect;
            SkTSwap(dstTexture, tempTexture);
        }
    }

    if (scaleFactorX > 1 || scaleFactorY > 1) {
        // Clear one pixel to the right and below, to accommodate bilinear
        // upsampling.
        clearRect = SkIRect::MakeXYWH(srcIRect.fLeft, srcIRect.fBottom,
                                      srcIRect.width() + 1, 1);
        drawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0, false);
        clearRect = SkIRect::MakeXYWH(srcIRect.fRight, srcIRect.fTop,
                                      1, srcIRect.height());
        drawContext->clear(srcTexture->asRenderTarget(), &clearRect, 0x0, false);
        SkMatrix matrix;
        matrix.setIDiv(srcTexture->width(), srcTexture->height());

        GrPaint paint;
        // FIXME:  this should be mitchell, not bilinear.
        GrTextureParams params(SkShader::kClamp_TileMode, GrTextureParams::kBilerp_FilterMode);
        paint.addColorTextureProcessor(srcTexture, matrix, params);

        SkRect dstRect(srcRect);
        scale_rect(&dstRect, (float) scaleFactorX, (float) scaleFactorY);
        drawContext->drawNonAARectToRect(dstTexture->asRenderTarget(), clip, paint,
                                         SkMatrix::I(), dstRect, srcRect);
        srcRect = dstRect;
        srcTexture = dstTexture;
        SkTSwap(dstTexture, tempTexture);
    }
    return SkRef(srcTexture);
}
コード例 #25
0
void
TTeamMenuItem::DrawContent()
{
	BMenu* menu = Menu();
	if (fIcon != NULL) {
		if (fIcon->ColorSpace() == B_RGBA32) {
			menu->SetDrawingMode(B_OP_ALPHA);
			menu->SetBlendingMode(B_PIXEL_ALPHA, B_ALPHA_OVERLAY);
		} else
			menu->SetDrawingMode(B_OP_OVER);

		BRect frame(Frame());
		BRect iconBounds(fIcon->Bounds());
		BRect dstRect(iconBounds);
		float extra = fVertical ? 0.0f : -1.0f;
		BPoint contLoc = ContentLocation();
		BPoint drawLoc = contLoc + BPoint(kHPad, kVPad);

		if (!fDrawLabel || (fVertical && iconBounds.Width() > 32)) {
			float offsetx = contLoc.x
				+ ((frame.Width() - iconBounds.Width()) / 2) + extra;
			float offsety = contLoc.y + 3.0f + extra;

			dstRect.OffsetTo(BPoint(offsetx, offsety));
			menu->DrawBitmapAsync(fIcon, dstRect);

			drawLoc.x = ((frame.Width() - LabelWidth()) / 2);
			drawLoc.y = frame.top + iconBounds.Height() + 4.0f;
		} else {
			float offsetx = contLoc.x + kHPad;
			float offsety = contLoc.y + 
				((frame.Height() - iconBounds.Height()) / 2) + extra;

			dstRect.OffsetTo(BPoint(offsetx, offsety));
			menu->DrawBitmapAsync(fIcon, dstRect);

			float labelHeight = fLabelAscent + fLabelDescent;
			drawLoc.x += iconBounds.Width() + kLabelOffset;
			drawLoc.y = frame.top + ((frame.Height() - labelHeight) / 2) + extra;
		}

		menu->MovePenTo(drawLoc);
	}

	// set the pen to black so that either method will draw in the same color
	// low color is set in inherited::DrawContent, override makes sure its
	// what we want
	if (fDrawLabel) {
		menu->SetDrawingMode(B_OP_OVER);
		menu->SetHighColor(ui_color(B_MENU_ITEM_TEXT_COLOR));

		// override the drawing of the content when the item is disabled
		// the wrong lowcolor is used when the item is disabled since the
		// text color does not change
		DrawContentLabel();
	}

	// Draw the expandable icon.
	TBarView* barView = (static_cast<TBarApp*>(be_app))->BarView();
	if (fVertical && static_cast<TBarApp*>(be_app)->Settings()->superExpando
		&& barView->ExpandoState()) {
		BRect frame(Frame());
		BRect rect(0, 0, kSwitchWidth, 10);
		rect.OffsetTo(BPoint(frame.right - rect.Width(),
			ContentLocation().y + ((frame.Height() - rect.Height()) / 2)));

		if (be_control_look != NULL) {
			uint32 arrowDirection = fExpanded
				? BControlLook::B_UP_ARROW : BControlLook::B_DOWN_ARROW;
			be_control_look->DrawArrowShape(menu, rect, rect, menu->LowColor(),
				arrowDirection, 0, B_DARKEN_3_TINT);
		} else {
			rgb_color outlineColor = {80, 80, 80, 255};
			rgb_color middleColor = {200, 200, 200, 255};

			menu->SetDrawingMode(B_OP_OVER);

			if (!fExpanded) {
				menu->BeginLineArray(6);

				menu->AddLine(BPoint(rect.left + 3, rect.top + 1),
					BPoint(rect.left + 3, rect.bottom - 1), outlineColor);
				menu->AddLine(BPoint(rect.left + 3, rect.top + 1),
					BPoint(rect.left + 7, rect.top + 5), outlineColor);
				menu->AddLine(BPoint(rect.left + 7, rect.top + 5),
					BPoint(rect.left + 3, rect.bottom - 1), outlineColor);

				menu->AddLine(BPoint(rect.left + 4, rect.top + 3),
					BPoint(rect.left + 4, rect.bottom - 3), middleColor);
				menu->AddLine(BPoint(rect.left + 5, rect.top + 4),
					BPoint(rect.left + 5, rect.bottom - 4), middleColor);
				menu->AddLine(BPoint(rect.left + 5, rect.top + 5),
					BPoint(rect.left + 6, rect.top + 5), middleColor);
				menu->EndLineArray();
			} else {
				// expanded state

				menu->BeginLineArray(6);
				menu->AddLine(BPoint(rect.left + 1, rect.top + 3),
					BPoint(rect.right - 3, rect.top + 3), outlineColor);
				menu->AddLine(BPoint(rect.left + 1, rect.top + 3),
					BPoint(rect.left + 5, rect.top + 7), outlineColor);
				menu->AddLine(BPoint(rect.left + 5, rect.top + 7),
					BPoint(rect.right - 3, rect.top + 3), outlineColor);

				menu->AddLine(BPoint(rect.left + 3, rect.top + 4),
					BPoint(rect.right - 5, rect.top + 4), middleColor);
				menu->AddLine(BPoint(rect.left + 4, rect.top + 5),
					BPoint(rect.right - 6, rect.top + 5), middleColor);
				menu->AddLine(BPoint(rect.left + 5, rect.top + 5),
					BPoint(rect.left + 5, rect.top + 6), middleColor);
				menu->EndLineArray();
			}
		}
	}
}
コード例 #26
0
void CAlfPerfAppAvkonTestCaseBasic::NextAnimFrameL()
    {
    // Begin drawing
    RWindow& window = static_cast< RWindow& >( *iAvkonControl->DrawableWindow() );
    CWindowGc& gc = iAvkonControl->SystemGc();
    TRect updateRect(iAvkonControl->Rect());
    window.Invalidate( updateRect );
    window.BeginRedraw( updateRect );
    gc.Activate(window);

    // Draw background
    TRgb color (KRgbWhite);
    gc.SetBrushColor(color);
    gc.SetBrushStyle(CGraphicsContext::ESolidBrush);
    gc.SetPenStyle(CGraphicsContext::ESolidPen);
    gc.SetPenSize(TSize(10,10));
    gc.SetPenColor(color);    
    gc.DrawRect(updateRect);  
       
    // Calc timeline
    TTime now;
    now.UniversalTime();
    TUint millisecondFromCycleStart = now.MicroSecondsFrom(iCycleStartTime).Int64() / 1000;
    double timelinePercentage = (double)millisecondFromCycleStart / KCycleDurationMs; 
    timelinePercentage *= 0.5; // scale it a bit...
   
    // Calc rect
    TRect fullRect(updateRect);
    TSize size(fullRect.Width()*(1.0 - timelinePercentage), fullRect.Height()*(1.0 - timelinePercentage));
    TPoint windowCenter = fullRect.Center();
    TPoint tl(windowCenter.iX - size.iWidth/2, windowCenter.iY - size.iHeight/2);
    TRect rect(tl, size);
        
    // Draw
    gc.SetPenColor(KRgbBlue);
    gc.SetBrushColor(KRgbRed);
    const TPoint Point1(rect.iTl);
    const TPoint Point2(rect.iBr.iX, rect.iTl.iY);
    const TPoint Point3(rect.iBr);
    const TPoint Point4(rect.iTl.iX, rect.iBr.iY);
    const TPoint center(rect.Center());

    switch (iCycleCounter)
        {
        case 1: // DrawEllipse
            {
            gc.DrawEllipse(rect);   
            break;
            }
        case 2: // DrawRect
            {
            gc.DrawRect(rect);    
            break;
            }
        case 3: // DrawRoundRect
            {
            TSize corner(rect.Width()/5, rect.Height()/5);
            gc.DrawRoundRect(rect, corner);   
            break;
            }
        case 4: // Draw lines
            {
            gc.SetPenColor(TRgb(255,0,0));
            gc.DrawLine(Point1, Point2);       
            
            gc.SetPenColor(TRgb(200,50,0));
            gc.DrawLineTo(Point3);
            
            gc.SetPenColor(TRgb(150,100,0));
            gc.DrawLineTo(Point4);
            
            gc.SetPenColor(TRgb(100,150,0));
            gc.DrawLineBy(TPoint(0, -rect.Height()));
            
            gc.SetPenColor(TRgb(50,200,0));
            gc.MoveTo(Point2);
            gc.DrawLineTo(Point4);
                       
            gc.SetPenColor(TRgb(0,255,0));
            gc.MoveBy(TPoint(0, -rect.Height()));
            gc.DrawLineTo(Point3);
            
            gc.SetPenColor(TRgb(255,0,0));
            gc.Plot(center);
            
            break;
           }
            
        case 5: // Draw 
            {
            gc.SetPenColor(TRgb(255,0,0));
            gc.DrawArc(rect, Point2, Point1);
            gc.DrawPie(rect, Point4, Point3);
            break;
            }
            
        case 6: // Draw polygons
            {
            const TInt KNumPoints = 9;
            TPoint pointList[KNumPoints];
            pointList[0] = TPoint(Point1.iX+rect.Width()*0.25, Point1.iY);
            pointList[1] = TPoint(Point1.iX+rect.Width()*0.75, Point1.iY);
            pointList[2] = TPoint(Point2.iX, Point2.iY+rect.Height()*0.25);
            pointList[3] = TPoint(Point2.iX, Point2.iY+rect.Height()*0.75);
            pointList[4] = TPoint(Point3.iX-rect.Width()*0.25, Point3.iY);
            pointList[5] = TPoint(Point3.iX-rect.Width()*0.75, Point3.iY);
            pointList[6] = TPoint(Point4.iX, Point4.iY-rect.Height()*0.25);
            pointList[7] = TPoint(Point4.iX, Point4.iY-rect.Height()*0.75);
            pointList[8] = TPoint(Point1.iX+rect.Width()*0.25, Point1.iY);
            
            CArrayFix<TPoint>* mypoints = new CArrayFixFlat<TPoint>(KNumPoints);
            CleanupStack::PushL(mypoints);
            for(TInt i=0; i<KNumPoints; i++)
                {
                mypoints->AppendL(pointList[i]);
                }

            gc.SetPenColor(TRgb(255,0,0));
            gc.SetPenSize(TSize(20,20));
            gc.DrawPolyLine(mypoints);
            
            gc.SetPenColor(TRgb(0,255,0));
            gc.SetPenSize(TSize(15,15));
            gc.DrawPolyLine(pointList, KNumPoints);
            
            gc.SetPenColor(TRgb(255,255,0));
            gc.SetPenSize(TSize(10,10));
            gc.DrawPolygon(mypoints);
            
            gc.SetPenColor(TRgb(0,0,255));
            gc.SetPenSize(TSize(5,5));
            gc.DrawPolygon(pointList, KNumPoints);
            
            CleanupStack::PopAndDestroy(); // mypoints           
            break;
            }
            
        case 7: // Draw texts
            {
            gc.UseFont(iFont);
            gc.SetDrawMode(CGraphicsContext::EDrawModePEN);
            gc.SetPenStyle(CGraphicsContext::ESolidPen);
            gc.SetBrushStyle(CGraphicsContext::ESolidBrush);    
            
            TInt h = rect.Height() / 3;
            TInt y = rect.iTl.iY;
            TRect tinyBox(rect);
            tinyBox.SetHeight(h);
            TInt fontDescent=iFont->DescentInPixels();
            gc.SetBrushColor(TRgb(0, 0, 255)); // blue
            
            gc.SetPenColor(TRgb(0,255,0)); // green
            gc.DrawText(_L("Ilves"), tinyBox.iTl+TPoint(0, fontDescent));
            
            tinyBox.Move(0,h);
            TInt posY = tinyBox.Height()-fontDescent;
            gc.SetPenColor(TRgb(255,0,0)); 
            gc.DrawText(_L("Tappara"), tinyBox, posY);
            
            gc.SetPenColor(TRgb(0,255,0)); // green
            gc.DrawTextVertical(_L("Ilves"), tinyBox.iTl+TPoint(fontDescent, 0 ), ETrue);
            
            tinyBox.Move(0,h);
            posY = tinyBox.Height()-fontDescent;
            gc.SetPenColor(TRgb(255,0,0)); 
            gc.DrawTextVertical(_L("Tappara"), tinyBox, posY, ETrue);
            
            break;
            }

        case 8: // Draw bitmaps
            {
            TPoint pos(rect.iTl);
            gc.BitBlt(pos, iPictureBm);
            
            pos = TPoint(rect.iTl.iX + rect.Width()/3, rect.iTl.iY);
            gc.BitBlt(pos, iPictureBm, TRect(iPictureBm->SizeInPixels()));

            pos = TPoint(rect.iTl.iX + rect.Width()*2/3, rect.iTl.iY);
            gc.BitBltMasked(pos, iPictureBm, TRect(iPictureBm->SizeInPixels()), iMaskBm, EFalse);

            pos = TPoint(rect.iTl.iX, rect.iTl.iY+ rect.Height()/3);
            TRect dstRect(pos, TSize(rect.Width()/3, rect.Height()/3));
            gc.DrawBitmap(dstRect, iPictureBm, TRect(iPictureBm->SizeInPixels()));

            pos = TPoint(rect.iTl.iX + rect.Width()/3, rect.iTl.iY+ rect.Height()/3);
            dstRect =  TRect(pos, dstRect.Size());
            gc.DrawBitmap(dstRect, iPictureBm);

            pos = TPoint(rect.iTl.iX, rect.iTl.iY+ rect.Height()*2/3);
            gc.DrawBitmap(pos, iPictureBm);

            pos = TPoint(rect.iTl.iX + rect.Width()/3, rect.iTl.iY+ rect.Height()*2/3);
            dstRect =  TRect(pos, dstRect.Size());
            gc.DrawBitmapMasked(dstRect, iPictureBm, TRect(iPictureBm->SizeInPixels()), iMaskBm, EFalse);

            break;
            }
            
         case 9: // Miscellanious
            {
            TRect rect1(rect);
            rect1.SetWidth(rect.Width()/2);
            rect1.SetHeight(rect.Height()/2);
            TRect rect2(rect1);
            rect2.Move(rect1.Width(),0);
            TRect rect3(rect1);
            rect3.Move(0, rect1.Height());
            TRect rect4(rect1);
            rect4.Move(rect1.Width(), rect1.Height());
            
            // Clear
            gc.Clear();
            // Brush pattern
            gc.UseBrushPattern(iPictureBm);
            gc.SetBrushStyle(CGraphicsContext::EPatternedBrush);
            gc.DrawRect(rect1);
            gc.DiscardBrushPattern();
            // Fading & copy rect
            gc.SetFaded(ETrue);
            gc.CopyRect(rect2.iTl, rect1);
            gc.SetFadingParameters(255,0);
            gc.CopyRect(rect3.iTl, rect1);
            // Map colors  
            gc.SetPenColor(KRgbBlue);
            gc.SetBrushColor(KRgbRed);
            gc.DrawRect(rect4);   
            TRgb colors[2] = {KRgbRed, KRgbGreen}; // change brush color
            gc.MapColors(rect4,colors,1,ETrue);
             
            break;
            }
            
     default:
           gc.DrawRect(rect);          
       }

    // End drawing
    gc.Deactivate();
    window.EndRedraw();
 
    iTestCaseFrameCount++;
    }
コード例 #27
0
ファイル: ContentHost.cpp プロジェクト: brendanlong/gecko-dev
void
ContentHostIncremental::TextureCreationRequest::Execute(ContentHostIncremental* aHost)
{
  RefPtr<DeprecatedTextureHost> newHost =
    DeprecatedTextureHost::CreateDeprecatedTextureHost(SurfaceDescriptor::TShmem,
                                   mTextureInfo.mDeprecatedTextureHostFlags,
                                   mTextureInfo.mTextureFlags,
                                   nullptr);
  Compositor* compositor = aHost->GetCompositor();
  if (compositor) {
    newHost->SetCompositor(compositor);
  }
  RefPtr<DeprecatedTextureHost> newHostOnWhite;
  if (mTextureInfo.mTextureFlags & TEXTURE_COMPONENT_ALPHA) {
    newHostOnWhite =
      DeprecatedTextureHost::CreateDeprecatedTextureHost(SurfaceDescriptor::TShmem,
                                     mTextureInfo.mDeprecatedTextureHostFlags,
                                     mTextureInfo.mTextureFlags,
                                     nullptr);
    Compositor* compositor = aHost->GetCompositor();
    if (compositor) {
      newHostOnWhite->SetCompositor(compositor);
    }
  }

  if (mTextureInfo.mDeprecatedTextureHostFlags & TEXTURE_HOST_COPY_PREVIOUS) {
    nsIntRect bufferRect = aHost->mBufferRect;
    nsIntPoint bufferRotation = aHost->mBufferRotation;
    nsIntRect overlap;

    // The buffer looks like:
    //  ______
    // |1  |2 |  Where the center point is offset by mBufferRotation from the top-left corner.
    // |___|__|
    // |3  |4 |
    // |___|__|
    //
    // This is drawn to the screen as:
    //  ______
    // |4  |3 |  Where the center point is { width - mBufferRotation.x, height - mBufferRotation.y } from
    // |___|__|  from the top left corner - rotationPoint.
    // |2  |1 |
    // |___|__|
    //

    // The basic idea below is to take all quadrant rectangles from the src and transform them into rectangles
    // in the destination. Unfortunately, it seems it is overly complex and could perhaps be simplified.

    nsIntRect srcBufferSpaceBottomRight(bufferRotation.x, bufferRotation.y, bufferRect.width - bufferRotation.x, bufferRect.height - bufferRotation.y);
    nsIntRect srcBufferSpaceTopRight(bufferRotation.x, 0, bufferRect.width - bufferRotation.x, bufferRotation.y);
    nsIntRect srcBufferSpaceTopLeft(0, 0, bufferRotation.x, bufferRotation.y);
    nsIntRect srcBufferSpaceBottomLeft(0, bufferRotation.y, bufferRotation.x, bufferRect.height - bufferRotation.y);

    overlap.IntersectRect(bufferRect, mBufferRect);

    nsIntRect srcRect(overlap), dstRect(overlap);
    srcRect.MoveBy(- bufferRect.TopLeft() + bufferRotation);

    nsIntRect srcRectDrawTopRight(srcRect);
    nsIntRect srcRectDrawTopLeft(srcRect);
    nsIntRect srcRectDrawBottomLeft(srcRect);
    // transform into the different quadrants
    srcRectDrawTopRight  .MoveBy(-nsIntPoint(0, bufferRect.height));
    srcRectDrawTopLeft   .MoveBy(-nsIntPoint(bufferRect.width, bufferRect.height));
    srcRectDrawBottomLeft.MoveBy(-nsIntPoint(bufferRect.width, 0));

    // Intersect with the quadrant
    srcRect               = srcRect              .Intersect(srcBufferSpaceBottomRight);
    srcRectDrawTopRight   = srcRectDrawTopRight  .Intersect(srcBufferSpaceTopRight);
    srcRectDrawTopLeft    = srcRectDrawTopLeft   .Intersect(srcBufferSpaceTopLeft);
    srcRectDrawBottomLeft = srcRectDrawBottomLeft.Intersect(srcBufferSpaceBottomLeft);

    dstRect = srcRect;
    nsIntRect dstRectDrawTopRight(srcRectDrawTopRight);
    nsIntRect dstRectDrawTopLeft(srcRectDrawTopLeft);
    nsIntRect dstRectDrawBottomLeft(srcRectDrawBottomLeft);

    // transform back to src buffer space
    dstRect              .MoveBy(-bufferRotation);
    dstRectDrawTopRight  .MoveBy(-bufferRotation + nsIntPoint(0, bufferRect.height));
    dstRectDrawTopLeft   .MoveBy(-bufferRotation + nsIntPoint(bufferRect.width, bufferRect.height));
    dstRectDrawBottomLeft.MoveBy(-bufferRotation + nsIntPoint(bufferRect.width, 0));

    // transform back to draw coordinates
    dstRect              .MoveBy(bufferRect.TopLeft());
    dstRectDrawTopRight  .MoveBy(bufferRect.TopLeft());
    dstRectDrawTopLeft   .MoveBy(bufferRect.TopLeft());
    dstRectDrawBottomLeft.MoveBy(bufferRect.TopLeft());

    // transform to destBuffer space
    dstRect              .MoveBy(-mBufferRect.TopLeft());
    dstRectDrawTopRight  .MoveBy(-mBufferRect.TopLeft());
    dstRectDrawTopLeft   .MoveBy(-mBufferRect.TopLeft());
    dstRectDrawBottomLeft.MoveBy(-mBufferRect.TopLeft());

    newHost->EnsureBuffer(mBufferRect.Size(),
                          ContentForFormat(aHost->mDeprecatedTextureHost->GetFormat()));

    aHost->mDeprecatedTextureHost->CopyTo(srcRect, newHost, dstRect);
    if (bufferRotation != nsIntPoint(0, 0)) {
      // Draw the remaining quadrants. We call BlitTextureImage 3 extra
      // times instead of doing a single draw call because supporting that
      // with a tiled source is quite tricky.

      if (!srcRectDrawTopRight.IsEmpty())
        aHost->mDeprecatedTextureHost->CopyTo(srcRectDrawTopRight,
                                          newHost, dstRectDrawTopRight);
      if (!srcRectDrawTopLeft.IsEmpty())
        aHost->mDeprecatedTextureHost->CopyTo(srcRectDrawTopLeft,
                                          newHost, dstRectDrawTopLeft);
      if (!srcRectDrawBottomLeft.IsEmpty())
        aHost->mDeprecatedTextureHost->CopyTo(srcRectDrawBottomLeft,
                                          newHost, dstRectDrawBottomLeft);
    }

    if (newHostOnWhite) {
      newHostOnWhite->EnsureBuffer(mBufferRect.Size(),
                                   ContentForFormat(aHost->mDeprecatedTextureHostOnWhite->GetFormat()));
      aHost->mDeprecatedTextureHostOnWhite->CopyTo(srcRect, newHostOnWhite, dstRect);
      if (bufferRotation != nsIntPoint(0, 0)) {
        // draw the remaining quadrants
        if (!srcRectDrawTopRight.IsEmpty())
          aHost->mDeprecatedTextureHostOnWhite->CopyTo(srcRectDrawTopRight,
                                                   newHostOnWhite, dstRectDrawTopRight);
        if (!srcRectDrawTopLeft.IsEmpty())
          aHost->mDeprecatedTextureHostOnWhite->CopyTo(srcRectDrawTopLeft,
                                                   newHostOnWhite, dstRectDrawTopLeft);
        if (!srcRectDrawBottomLeft.IsEmpty())
          aHost->mDeprecatedTextureHostOnWhite->CopyTo(srcRectDrawBottomLeft,
                                                   newHostOnWhite, dstRectDrawBottomLeft);
      }
    }
  }

  aHost->mDeprecatedTextureHost = newHost;
  aHost->mDeprecatedTextureHostOnWhite = newHostOnWhite;

  aHost->mBufferRect = mBufferRect;
  aHost->mBufferRotation = nsIntPoint();
}
コード例 #28
0
void BleImageProcessThread::run()
{
    CvSize dstSize;
    dstSize.width = m_width;
    dstSize.height = m_height;
    IplImage* dstImg = cvCreateImage(dstSize, IPL_DEPTH_8U, 3);
    cvZero(dstImg);

    QRect dstRect(0, 0, m_width, m_height);

    while (!m_stop) {
        QElapsedTimer elapsedTimer;
        elapsedTimer.start();

        m_updateMutex.lock();
        for (int i = 0; i < m_sources.size(); ++i) {
            SourcePair & pair = m_sources[i];

            BleImage bleImage = pair.source->getImage();
            if (bleImage.dataSize <= 0) continue;

            IplImage *cvImage = cvCreateImageHeader(cvSize(bleImage.width, bleImage.height), 8, 3);
            cvImage->imageData = bleImage.data;
            cvImage->imageDataOrigin = bleImage.data;

            // if the image size not qual to area size
            // then resize it.
            IplImage *resizedImage = cvImage;
            if (cvImage->width != pair.rect.width() ||
                    cvImage->height != pair.rect.height())
            {
                resizedImage = cvCreateImage(cvSize(pair.rect.width(), pair.rect.height()), cvImage->depth, cvImage->nChannels);
                cvResize(cvImage, resizedImage, CV_INTER_LINEAR);
            }

            if (bleImage.format != BleImage_Format_BGR24) {
                cvConvertImage(resizedImage, resizedImage, CV_CVTIMG_SWAP_RB);
            }

            // get the intersection of dst rect
            if (!dstRect.intersects(pair.rect)) continue;

            QRect intersectionRect_1 = dstRect.intersected(pair.rect);
            QRect intersectionRect_2 = pair.rect.intersected(dstRect);

            // intersectionRect_2 should relative to pair.rect
            intersectionRect_2.moveTopLeft(QPoint(intersectionRect_2.x() - pair.rect.x(),
                                       intersectionRect_2.y() - pair.rect.y()));

            cvSetImageROI(dstImg, QRect2CvRect(intersectionRect_1));
            cvSetImageROI(resizedImage, QRect2CvRect(intersectionRect_2));

            cvCopy(resizedImage, dstImg);

            cvResetImageROI(dstImg);
            cvResetImageROI(resizedImage);

            // if resizedImage is cvCreateImage created ?
            if (resizedImage != cvImage) {
                cvReleaseImage(&resizedImage);
            }
            cvReleaseImageHeader(&cvImage);
        }
        m_updateMutex.unlock();

        m_modifyOutputMutex.lock();

        // if delayed about 1s , then discard some image.
        if (m_outputQueue.size() > 20) {
            log_trace("queue has many mang image, maybe your encoder is too slow!");
            goto end;
        }

        if (true) {
            // to BleImage
            BleImage *be = new BleImage;
            be->width = dstImg->width;
            be->height = dstImg->height;

            be->data = new char[dstImg->imageSize];
            memcpy(be->data, dstImg->imageData, dstImg->imageSize);

            be->dataSize = dstImg->imageSize;

            be->format = BleImage_Format_BGR24;

            m_timestampBuilder.setVideoCaptureInternal(m_internal);
            be->pts = m_timestampBuilder.addVideoFrame();

            m_outputQueue.enqueue(be);
        }

end:
        m_modifyOutputMutex.unlock();

        int elapsedMs = elapsedTimer.elapsed();
        int needSleepMs = m_internal - elapsedMs;
        if (needSleepMs < 0) {
            needSleepMs = 0;
        }
        msleep(needSleepMs);

        // reset bg image to black
        cvZero(dstImg);
    }

    log_trace("BleImageProcessThread exit normally.");
}
コード例 #29
0
ファイル: gfxbase.cpp プロジェクト: AReim1982/scummvm
void Gfx::bltMaskScale(const Common::Rect& r, byte *data, Graphics::Surface *surf, uint16 z, uint scale, byte transparentColor) {
	if (scale == 100) {
		// use optimized path
		bltMaskNoScale(r, data, surf, z, transparentColor);
		return;
	}

	// unscaled rectangle size
	uint width = r.width();
	uint height = r.height();

	// scaled rectangle size
	uint scaledWidth = r.width() * scale / 100;
	uint scaledHeight = r.height() * scale / 100;

	// scaled rectangle origin
	uint scaledLeft = r.left + (width - scaledWidth) / 2;
	uint scaledTop = r.top + (height - scaledHeight);

	// clipped scaled destination rectangle
	Common::Rect dstRect(scaledWidth, scaledHeight);
	dstRect.moveTo(scaledLeft, scaledTop);

	Common::Rect clipper(surf->w, surf->h);
	dstRect.clip(clipper);
	if (!dstRect.isValidRect()) return;

	// clipped source rectangle
	Common::Rect srcRect;
	srcRect.left = (dstRect.left - scaledLeft)  * 100 / scale;
	srcRect.top = (dstRect.top - scaledTop) * 100 / scale;
	srcRect.setWidth(dstRect.width() * 100 / scale);
	srcRect.setHeight(dstRect.height() * 100 / scale);
	if (!srcRect.isValidRect()) return;

	Common::Point dp;
	dp.x = dstRect.left;
	dp.y = dstRect.top;

	byte *s = data + srcRect.left + srcRect.top * width;
	byte *d = (byte *)surf->getBasePtr(dp.x, dp.y);

	uint line = 0, col = 0;

	uint xAccum = 0, yAccum = 0;
	uint inc = width * (100 - scale);
	uint thr = width * 100;

	for (uint16 i = 0; i < srcRect.height(); i++) {
		yAccum += inc;

		if (yAccum >= thr) {
			yAccum -= thr;
			s += width;
			continue;
		}

		xAccum = 0;
		byte *d2 = d;
		col = 0;

		for (uint16 j = 0; j < srcRect.width(); j++) {
			xAccum += inc;

			if (xAccum >= thr) {
				xAccum -= thr;
				s++;
				continue;
			}

			if (*s != transparentColor) {
				if (_backgroundInfo->hasMask()) {
					byte v = _backgroundInfo->_mask->getValue(dp.x + col, dp.y + line);
					if (z >= v) *d2 = *s;
				} else {
					*d2 = *s;
				}
			}

			s++;
			d2++;
			col++;
		}

		s += width - srcRect.width();
		d += surf->w;
		line++;
	}

}
コード例 #30
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);
}