Chromium Code Reviews| Index: chrome/browser/renderer_host/backing_store_win.cc |
| =================================================================== |
| --- chrome/browser/renderer_host/backing_store_win.cc (revision 17347) |
| +++ chrome/browser/renderer_host/backing_store_win.cc (working copy) |
| @@ -54,7 +54,11 @@ |
| void BackingStore::PaintRect(base::ProcessHandle process, |
| TransportDIB* bitmap, |
| - const gfx::Rect& bitmap_rect) { |
| + const gfx::Rect& bitmap_rect, |
| + const gfx::Rect& paint_rect) { |
| + DCHECK(bitmap_rect.Contains(paint_rect) && |
| + paint_rect.x() < kMaxBitmapLengthAllowed && |
| + paint_rect.y() < kMaxBitmapLengthAllowed); |
| if (!backing_store_dib_) { |
| backing_store_dib_ = CreateDIB(hdc_, size_.width(), |
| size_.height(), color_depth_); |
| @@ -67,16 +71,33 @@ |
| BITMAPINFOHEADER hdr; |
| gfx::CreateBitmapHeader(bitmap_rect.width(), bitmap_rect.height(), &hdr); |
| - // Account for a bitmap_rect that exceeds the bounds of our view |
| + // Account for a paint_rect that exceeds the bounds of our view. |
| gfx::Rect view_rect(0, 0, size_.width(), size_.height()); |
| - gfx::Rect paint_rect = view_rect.Intersect(bitmap_rect); |
| + gfx::Rect paint_view_rect = view_rect.Intersect(paint_rect); |
| - int rv = StretchDIBits(hdc_, |
| - paint_rect.x(), paint_rect.y(), |
| - paint_rect.width(), paint_rect.height(), |
| - 0, 0, // source x,y. |
| - paint_rect.width(), paint_rect.height(), |
| - bitmap->memory(), |
| + // CreateBitmapHeader specifies a negative height, |
| + // so the y destination is from the bottom. |
| + int source_x = paint_view_rect.x() - bitmap_rect.x(); |
| + int source_y = bitmap_rect.bottom() - paint_view_rect.bottom(); |
| + int source_height = paint_view_rect.height(); |
| + int destination_y = paint_view_rect.y(); |
| + int destination_height = paint_view_rect.height(); |
| + if (source_y == 0 && source_x == 0 && |
| + paint_view_rect.height() != bitmap_rect.height()) { |
| + // StretchDIBits has a bug where it won't take the proper source |
| + // rect if it starts at (0, 0) in the source but not in the destination, |
| + // so we must a mirror blit trick as proposed here: |
|
darin (slow to review)
2009/06/10 17:23:24
nit: // so we must [use] a mirror blit...
MAD
2009/06/10 19:00:13
Done.
|
| + // http://wiki.allegro.cc/index.php?title=StretchDIBits |
| + destination_y += destination_height - 1; |
| + destination_height = -destination_height; |
| + source_y = bitmap_rect.height() - paint_view_rect.y() + 1; |
| + source_height = -source_height; |
| + } |
| + |
| + int rv = StretchDIBits(hdc_, paint_view_rect.x(), destination_y, |
| + paint_view_rect.width(), destination_height, |
| + source_x, source_y, paint_view_rect.width(), |
| + source_height, bitmap->memory(), |
| reinterpret_cast<BITMAPINFO*>(&hdr), |
| DIB_RGB_COLORS, SRCCOPY); |
| DCHECK(rv != GDI_ERROR); |
| @@ -97,5 +118,5 @@ |
| // We expect that damaged_rect should equal bitmap_rect. |
| DCHECK(gfx::Rect(damaged_rect) == bitmap_rect); |
| - PaintRect(process, bitmap, bitmap_rect); |
| + PaintRect(process, bitmap, bitmap_rect, bitmap_rect); |
| } |