Chromium Code Reviews| 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/logging.h" | |
| 8 #include "skia/ext/platform_canvas.h" | |
| 9 #include "skia/include/SkBitmap.h" | |
| 10 #include "skia/include/SkCanvas.h" | |
| 11 | |
| 7 BackingStore::BackingStore(const gfx::Size& size) | 12 BackingStore::BackingStore(const gfx::Size& size) |
| 8 : size_(size) { | 13 : size_(size) { |
| 9 if (!canvas_.initialize(size.width(), size.height(), true)) | 14 if (!canvas_.initialize(size.width(), size.height(), true)) |
| 10 SK_CRASH(); | 15 SK_CRASH(); |
| 11 } | 16 } |
| 12 | 17 |
| 13 BackingStore::~BackingStore() { | 18 BackingStore::~BackingStore() { |
| 14 } | 19 } |
| 15 | 20 |
| 16 bool BackingStore::PaintRect(base::ProcessHandle process, | 21 bool BackingStore::PaintRect(base::ProcessHandle process, |
| 17 BitmapWireData bitmap, | 22 BitmapWireData bitmap, |
| 18 const gfx::Rect& bitmap_rect) { | 23 const gfx::Rect& bitmap_rect) { |
| 19 if (bitmap.width() != bitmap_rect.width() || | 24 if (bitmap.width() != bitmap_rect.width() || |
| 20 bitmap.height() != bitmap_rect.height() || | 25 bitmap.height() != bitmap_rect.height() || |
| 21 bitmap.config() != SkBitmap::kARGB_8888_Config) { | 26 bitmap.config() != SkBitmap::kARGB_8888_Config) { |
| 22 return false; | 27 return false; |
| 23 } | 28 } |
| 24 | 29 |
| 25 canvas_.drawBitmap(bitmap, bitmap_rect.x(), bitmap_rect.y()); | 30 canvas_.drawBitmap(bitmap, bitmap_rect.x(), bitmap_rect.y()); |
| 26 return true; | 31 return true; |
| 27 } | 32 } |
| 28 | 33 |
| 34 // Return the given value, clipped to 0..max (inclusive) | |
| 35 static int RangeClip(int value, int max) { | |
| 36 return std::min(max, std::max(value, 0)); | |
| 37 } | |
| 38 | |
| 29 void BackingStore::ScrollRect(base::ProcessHandle process, | 39 void BackingStore::ScrollRect(base::ProcessHandle process, |
|
brettw
2009/02/04 20:36:06
Can you make some comment that this is a temporary
| |
| 30 BitmapWireData bitmap, | 40 BitmapWireData bitmap, |
| 31 const gfx::Rect& bitmap_rect, | 41 const gfx::Rect& bitmap_rect, |
| 32 int dx, int dy, | 42 int dx, int dy, |
| 33 const gfx::Rect& clip_rect, | 43 const gfx::Rect& clip_rect, |
| 34 const gfx::Size& view_size) { | 44 const gfx::Size& view_size) { |
| 35 // TODO(port): implement scrolling | 45 // On Windows, there's a ScrollDC call which performs horiz and vertical |
| 36 NOTIMPLEMENTED(); | 46 // scrolling |
| 47 // | |
| 48 // clip_rect: MSDN says "The only bits that will be painted are the | |
| 49 // bits that remain inside this rectangle after the scroll operation has been | |
| 50 // completed." | |
| 51 // | |
| 52 // The Windows code always sets the whole backing store as the source of the | |
| 53 // scroll. Thus, we only have to worry about pixels which will end up inside | |
| 54 // the clipping rectangle. (Note that the clipping rectangle is not | |
| 55 // translated by the scrol.) | |
| 56 | |
| 57 // We only support scrolling in one direction at a time. | |
| 58 DCHECK(dx == 0 || dy == 0); | |
| 59 | |
| 60 if (bitmap.width() != bitmap_rect.width() || | |
| 61 bitmap.height() != bitmap_rect.height() || | |
| 62 bitmap.config() != SkBitmap::kARGB_8888_Config) { | |
| 63 return; | |
| 64 } | |
| 65 | |
| 66 // We assume that |clip_rect| is within the backing store. | |
| 67 | |
| 68 const SkBitmap &backing_bitmap = canvas_.getDevice()->accessBitmap(true); | |
| 69 const int stride = backing_bitmap.rowBytes(); | |
| 70 uint8_t* x = static_cast<uint8_t*>(backing_bitmap.getPixels()); | |
| 71 | |
| 72 if (dx) { | |
| 73 // horizontal scroll. Positive values of |dx| scroll right. | |
| 74 | |
| 75 // We know that |clip_rect| is the destination rectangle. The source | |
| 76 // rectangle, in an infinite world, would be the destination rectangle | |
| 77 // translated by -dx. However, we can't pull pixels from beyound the | |
| 78 // edge of the backing store. By truncating the source rectangle to the | |
| 79 // backing store, we might have made it thinner, thus we find the final | |
| 80 // dest rectangle by translating the resulting source rectangle back. | |
| 81 const int bs_width = canvas_.getDevice()->width(); | |
| 82 const int src_rect_left = RangeClip(clip_rect.x() - dx, bs_width); | |
| 83 const int src_rect_right = RangeClip(clip_rect.right() - dx, bs_width); | |
| 84 | |
| 85 const int dest_rect_left = RangeClip(src_rect_left + dx, bs_width); | |
| 86 const int dest_rect_right = RangeClip(src_rect_right + dx, bs_width); | |
| 87 | |
| 88 DCHECK(dest_rect_right >= dest_rect_left); | |
| 89 DCHECK(src_rect_right >= src_rect_left); | |
| 90 DCHECK(dest_rect_right - dest_rect_left == | |
| 91 src_rect_right - src_rect_left); | |
| 92 | |
| 93 // This is the number of bytes to move per line at 4 bytes per pixel. | |
| 94 const int len = (dest_rect_right - dest_rect_left) * 4; | |
| 95 | |
| 96 // Position the pixel data pointer at the top-left corner of the dest rect | |
| 97 x += clip_rect.y() * stride; | |
| 98 x += clip_rect.x() * 4; | |
| 99 | |
| 100 // This is the number of bytes to reach left in order to find the source | |
| 101 // rectangle. (Will be negative for a left scroll.) | |
| 102 const int left_reach = dest_rect_left - src_rect_left; | |
| 103 | |
| 104 for (int y = clip_rect.y(); y < clip_rect.bottom(); ++y) { | |
| 105 // Note that overlapping regions requires memmove, not memcpy. | |
| 106 memmove(x, x + left_reach, len); | |
| 107 x += stride; | |
| 108 } | |
| 109 } else { | |
| 110 // vertical scroll. Positive values of |dy| scroll down. | |
| 111 | |
| 112 // The logic is very similar to the horizontal case, above. | |
| 113 const int bs_height = canvas_.getDevice()->height(); | |
| 114 const int src_rect_top = RangeClip(clip_rect.y() - dy, bs_height); | |
| 115 const int src_rect_bottom = RangeClip(clip_rect.bottom() - dy, bs_height); | |
| 116 | |
| 117 const int dest_rect_top = RangeClip(src_rect_top + dy, bs_height); | |
| 118 const int dest_rect_bottom = RangeClip(src_rect_bottom + dy, bs_height); | |
| 119 | |
| 120 const int len = clip_rect.width() * 4; | |
| 121 | |
| 122 DCHECK(dest_rect_bottom >= dest_rect_top); | |
| 123 DCHECK(src_rect_bottom >= src_rect_top); | |
| 124 | |
| 125 // We need to consider the two directions separately here because the order | |
| 126 // of copying rows must vary to avoid writing data which we later need to | |
| 127 // read. | |
| 128 if (dy > 0) { | |
| 129 // scrolling down; dest rect is above src rect. | |
|
brettw
2009/02/04 20:36:06
This comment and the next 3 need capital letters a
| |
| 130 | |
| 131 // position the pixel data pointer at the top-left corner of the dest | |
| 132 // rect. | |
| 133 x += dest_rect_top * stride; | |
| 134 x += clip_rect.x() * 4; | |
| 135 | |
| 136 DCHECK(dest_rect_top <= src_rect_top); | |
| 137 const int down_reach_bytes = stride * (src_rect_top - dest_rect_top); | |
| 138 | |
| 139 for (int y = dest_rect_top; y < dest_rect_bottom; ++y) { | |
| 140 memcpy(x, x + down_reach_bytes, len); | |
| 141 x += stride; | |
| 142 } | |
| 143 } else { | |
| 144 // scrolling up; dest rect is below src rect. | |
| 145 | |
| 146 // position the pixel data pointer at the bottom-left corner of the dest | |
| 147 // rect. | |
| 148 x += (dest_rect_bottom - 1) * stride; | |
| 149 x += clip_rect.x() * 4; | |
| 150 | |
| 151 DCHECK(src_rect_top <= dest_rect_top); | |
| 152 const int up_reach_bytes = stride * (dest_rect_bottom - src_rect_bottom); | |
| 153 | |
| 154 for (int y = dest_rect_bottom - 1; y >= dest_rect_top; --y) { | |
| 155 memcpy(x, x - up_reach_bytes, len); | |
| 156 x -= stride; | |
| 157 } | |
| 158 } | |
| 159 } | |
| 160 | |
| 161 // Now paint the new bitmap data. | |
| 162 canvas_.drawBitmap(bitmap, bitmap_rect.x(), bitmap_rect.y()); | |
| 163 return; | |
| 37 } | 164 } |
| OLD | NEW |