OLD | NEW |
---|---|
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/renderer_host/backing_store.h" | 5 #include "chrome/browser/renderer_host/backing_store.h" |
6 | 6 |
7 #include "base/gfx/gdi_util.h" | 7 #include "base/gfx/gdi_util.h" |
8 #include "chrome/browser/renderer_host/render_widget_host.h" | 8 #include "chrome/browser/renderer_host/render_widget_host.h" |
9 #include "chrome/common/transport_dib.h" | 9 #include "chrome/common/transport_dib.h" |
10 | 10 |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
47 } | 47 } |
48 if (backing_store_dib_) { | 48 if (backing_store_dib_) { |
49 DeleteObject(backing_store_dib_); | 49 DeleteObject(backing_store_dib_); |
50 backing_store_dib_ = NULL; | 50 backing_store_dib_ = NULL; |
51 } | 51 } |
52 DeleteDC(hdc_); | 52 DeleteDC(hdc_); |
53 } | 53 } |
54 | 54 |
55 void BackingStore::PaintRect(base::ProcessHandle process, | 55 void BackingStore::PaintRect(base::ProcessHandle process, |
56 TransportDIB* bitmap, | 56 TransportDIB* bitmap, |
57 const gfx::Rect& bitmap_rect) { | 57 const gfx::Rect& bitmap_rect, |
58 const gfx::Rect& paint_rect) { | |
59 DCHECK(bitmap_rect.Contains(paint_rect) && | |
60 paint_rect.x() < kMaxBitmapLengthAllowed && | |
61 paint_rect.y() < kMaxBitmapLengthAllowed); | |
58 if (!backing_store_dib_) { | 62 if (!backing_store_dib_) { |
59 backing_store_dib_ = CreateDIB(hdc_, size_.width(), | 63 backing_store_dib_ = CreateDIB(hdc_, size_.width(), |
60 size_.height(), color_depth_); | 64 size_.height(), color_depth_); |
61 if (!backing_store_dib_) { | 65 if (!backing_store_dib_) { |
62 NOTREACHED(); | 66 NOTREACHED(); |
63 return; | 67 return; |
64 } | 68 } |
65 original_bitmap_ = SelectObject(hdc_, backing_store_dib_); | 69 original_bitmap_ = SelectObject(hdc_, backing_store_dib_); |
66 } | 70 } |
67 | 71 |
68 BITMAPINFOHEADER hdr; | 72 BITMAPINFOHEADER hdr; |
69 gfx::CreateBitmapHeader(bitmap_rect.width(), bitmap_rect.height(), &hdr); | 73 gfx::CreateBitmapHeader(bitmap_rect.width(), bitmap_rect.height(), &hdr); |
70 // Account for a bitmap_rect that exceeds the bounds of our view | 74 // Account for a paint_rect that exceeds the bounds of our view. |
71 gfx::Rect view_rect(0, 0, size_.width(), size_.height()); | 75 gfx::Rect view_rect(0, 0, size_.width(), size_.height()); |
72 gfx::Rect paint_rect = view_rect.Intersect(bitmap_rect); | 76 gfx::Rect paint_view_rect = view_rect.Intersect(paint_rect); |
73 | 77 |
74 int rv = StretchDIBits(hdc_, | 78 // CreateBitmapHeader specifies a negative height, |
75 paint_rect.x(), paint_rect.y(), | 79 // so the y destination is from the bottom. |
76 paint_rect.width(), paint_rect.height(), | 80 int source_x = paint_view_rect.x() - bitmap_rect.x(); |
77 0, 0, // source x,y. | 81 int source_y = bitmap_rect.bottom() - paint_view_rect.bottom(); |
78 paint_rect.width(), paint_rect.height(), | 82 int source_height = paint_view_rect.height(); |
79 bitmap->memory(), | 83 int destination_y = paint_view_rect.y(); |
84 int destination_height = paint_view_rect.height(); | |
85 if (source_y == 0 && source_x == 0 && | |
86 paint_view_rect.height() != bitmap_rect.height()) { | |
87 // StretchDIBits has a bug where it won't take the proper source | |
88 // rect if it starts at (0, 0) in the source but not in the destination, | |
89 // 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.
| |
90 // http://wiki.allegro.cc/index.php?title=StretchDIBits | |
91 destination_y += destination_height - 1; | |
92 destination_height = -destination_height; | |
93 source_y = bitmap_rect.height() - paint_view_rect.y() + 1; | |
94 source_height = -source_height; | |
95 } | |
96 | |
97 int rv = StretchDIBits(hdc_, paint_view_rect.x(), destination_y, | |
98 paint_view_rect.width(), destination_height, | |
99 source_x, source_y, paint_view_rect.width(), | |
100 source_height, bitmap->memory(), | |
80 reinterpret_cast<BITMAPINFO*>(&hdr), | 101 reinterpret_cast<BITMAPINFO*>(&hdr), |
81 DIB_RGB_COLORS, SRCCOPY); | 102 DIB_RGB_COLORS, SRCCOPY); |
82 DCHECK(rv != GDI_ERROR); | 103 DCHECK(rv != GDI_ERROR); |
83 } | 104 } |
84 | 105 |
85 void BackingStore::ScrollRect(base::ProcessHandle process, | 106 void BackingStore::ScrollRect(base::ProcessHandle process, |
86 TransportDIB* bitmap, | 107 TransportDIB* bitmap, |
87 const gfx::Rect& bitmap_rect, | 108 const gfx::Rect& bitmap_rect, |
88 int dx, int dy, | 109 int dx, int dy, |
89 const gfx::Rect& clip_rect, | 110 const gfx::Rect& clip_rect, |
90 const gfx::Size& view_size) { | 111 const gfx::Size& view_size) { |
91 RECT damaged_rect, r = clip_rect.ToRECT(); | 112 RECT damaged_rect, r = clip_rect.ToRECT(); |
92 ScrollDC(hdc_, dx, dy, NULL, &r, NULL, &damaged_rect); | 113 ScrollDC(hdc_, dx, dy, NULL, &r, NULL, &damaged_rect); |
93 | 114 |
94 // TODO(darin): this doesn't work if dx and dy are both non-zero! | 115 // TODO(darin): this doesn't work if dx and dy are both non-zero! |
95 DCHECK(dx == 0 || dy == 0); | 116 DCHECK(dx == 0 || dy == 0); |
96 | 117 |
97 // We expect that damaged_rect should equal bitmap_rect. | 118 // We expect that damaged_rect should equal bitmap_rect. |
98 DCHECK(gfx::Rect(damaged_rect) == bitmap_rect); | 119 DCHECK(gfx::Rect(damaged_rect) == bitmap_rect); |
99 | 120 |
100 PaintRect(process, bitmap, bitmap_rect); | 121 PaintRect(process, bitmap, bitmap_rect, bitmap_rect); |
101 } | 122 } |
OLD | NEW |