87 lines
3.2 KiB
C++
87 lines
3.2 KiB
C++
|
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
||
|
// Use of this source code is governed by a BSD-style license that can be
|
||
|
// found in the LICENSE file.
|
||
|
|
||
|
#include "libcef/browser/backing_store_osr.h"
|
||
|
|
||
|
#include "content/public/browser/render_process_host.h"
|
||
|
#include "ui/gfx/gdi_util.h"
|
||
|
#include "ui/gfx/rect.h"
|
||
|
#include "ui/surface/transport_dib.h"
|
||
|
|
||
|
// Portions extracted from content/browser/renderer_host/backing_store_win.cc.
|
||
|
|
||
|
namespace {
|
||
|
|
||
|
void CallStretchDIBits(HDC hdc, int dest_x, int dest_y, int dest_w, int dest_h,
|
||
|
int src_x, int src_y, int src_w, int src_h, void* pixels,
|
||
|
const BITMAPINFO* bitmap_info) {
|
||
|
// When blitting a rectangle that touches the bottom left corner of the bitmap
|
||
|
// StretchDIBits looks at it top-down! For more details, see
|
||
|
// http://wiki.allegro.cc/index.php?title=StretchDIBits.
|
||
|
int rv;
|
||
|
int bitmap_h = -bitmap_info->bmiHeader.biHeight;
|
||
|
int bottom_up_src_y = bitmap_h - src_y - src_h;
|
||
|
if (bottom_up_src_y == 0 && src_x == 0 && src_h != bitmap_h) {
|
||
|
rv = StretchDIBits(hdc,
|
||
|
dest_x, dest_h + dest_y - 1, dest_w, -dest_h,
|
||
|
src_x, bitmap_h - src_y + 1, src_w, -src_h,
|
||
|
pixels, bitmap_info, DIB_RGB_COLORS, SRCCOPY);
|
||
|
} else {
|
||
|
rv = StretchDIBits(hdc,
|
||
|
dest_x, dest_y, dest_w, dest_h,
|
||
|
src_x, bottom_up_src_y, src_w, src_h,
|
||
|
pixels, bitmap_info, DIB_RGB_COLORS, SRCCOPY);
|
||
|
}
|
||
|
DCHECK(rv != GDI_ERROR);
|
||
|
}
|
||
|
|
||
|
} // namespace
|
||
|
|
||
|
void BackingStoreOSR::PaintToBackingStore(
|
||
|
content::RenderProcessHost* process,
|
||
|
TransportDIB::Id bitmap,
|
||
|
const gfx::Rect& bitmap_rect,
|
||
|
const std::vector<gfx::Rect>& copy_rects,
|
||
|
float scale_factor,
|
||
|
const base::Closure& completion_callback,
|
||
|
bool* scheduled_completion_callback) {
|
||
|
*scheduled_completion_callback = false;
|
||
|
TransportDIB* dib = process->GetTransportDIB(bitmap);
|
||
|
if (!dib)
|
||
|
return;
|
||
|
|
||
|
BITMAPINFOHEADER hdr;
|
||
|
gfx::CreateBitmapHeader(bitmap_rect.width(), bitmap_rect.height(), &hdr);
|
||
|
|
||
|
// Account for a bitmap_rect that exceeds the bounds of our view.
|
||
|
gfx::Rect view_rect(size());
|
||
|
HDC temp_dc = bitmap_.GetSurface();
|
||
|
for (size_t i = 0; i < copy_rects.size(); i++) {
|
||
|
gfx::Rect paint_rect(copy_rects[i]);
|
||
|
paint_rect.Intersect(view_rect);
|
||
|
CallStretchDIBits(temp_dc,
|
||
|
paint_rect.x(),
|
||
|
paint_rect.y(),
|
||
|
paint_rect.width(),
|
||
|
paint_rect.height(),
|
||
|
paint_rect.x() - bitmap_rect.x(),
|
||
|
paint_rect.y() - bitmap_rect.y(),
|
||
|
paint_rect.width(),
|
||
|
paint_rect.height(),
|
||
|
dib->memory(),
|
||
|
reinterpret_cast<BITMAPINFO*>(&hdr));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool BackingStoreOSR::CopyFromBackingStore(const gfx::Rect& rect,
|
||
|
skia::PlatformBitmap* output) {
|
||
|
if (!output->Allocate(rect.width(), rect.height(), true))
|
||
|
return false;
|
||
|
|
||
|
HDC src_dc = bitmap_.GetSurface();
|
||
|
HDC dst_dc = output->GetSurface();
|
||
|
return BitBlt(dst_dc, 0, 0, rect.width(), rect.height(),
|
||
|
src_dc, rect.x(), rect.y(), SRCCOPY) ? true : false;
|
||
|
}
|