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); } } }
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()); }
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 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; }
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); }
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); }
// 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(); }
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 }
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; }
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; }
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; }
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 } }
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; }
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(); }
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); }
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; }
// 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(); }
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); }
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()); }
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; }
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(); }
// 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); }
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; }
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); }
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(); } } } }
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++; }
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(); }
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."); }
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++; } }
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); }