diff options
author | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-11 03:02:44 +0000 |
---|---|---|
committer | estade@chromium.org <estade@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-02-11 03:02:44 +0000 |
commit | cccbe29c642c47816478b8ba3df9329fcee03728 (patch) | |
tree | e44c92548f7aed7f716f73298537c9f00ad906e1 /chrome | |
parent | d1ec590811a1d4e593c1ba7ad52cee26cef16305 (diff) | |
download | chromium_src-cccbe29c642c47816478b8ba3df9329fcee03728.zip chromium_src-cccbe29c642c47816478b8ba3df9329fcee03728.tar.gz chromium_src-cccbe29c642c47816478b8ba3df9329fcee03728.tar.bz2 |
Implement browser scrolling on posix.
This code still has not been tested on nested scroll frames (e.g. webkit/data/test_shell/iframes/test1.html) because they don't render correctly yet. But it does work for scrolling horizontally and vertically on the main frame.
Review URL: http://codereview.chromium.org/20244
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@9550 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r-- | chrome/browser/renderer_host/backing_store_posix.cc | 99 | ||||
-rw-r--r-- | chrome/browser/renderer_host/render_widget_host_view_gtk.cc | 6 | ||||
-rw-r--r-- | chrome/renderer/render_widget.cc | 2 |
3 files changed, 35 insertions, 72 deletions
diff --git a/chrome/browser/renderer_host/backing_store_posix.cc b/chrome/browser/renderer_host/backing_store_posix.cc index 0407ba4..1ff62be 100644 --- a/chrome/browser/renderer_host/backing_store_posix.cc +++ b/chrome/browser/renderer_host/backing_store_posix.cc @@ -31,11 +31,6 @@ bool BackingStore::PaintRect(base::ProcessHandle process, return true; } -// Return the given value, clipped to 0..max (inclusive) -static int RangeClip(int value, int max) { - return std::min(max, std::max(value, 0)); -} - void BackingStore::ScrollRect(base::ProcessHandle process, BitmapWireData bitmap, const gfx::Rect& bitmap_rect, @@ -55,107 +50,73 @@ void BackingStore::ScrollRect(base::ProcessHandle process, // The Windows code always sets the whole backing store as the source of the // scroll. Thus, we only have to worry about pixels which will end up inside // the clipping rectangle. (Note that the clipping rectangle is not - // translated by the scrol.) + // translated by the scroll.) // We only support scrolling in one direction at a time. DCHECK(dx == 0 || dy == 0); + // We assume |clip_rect| is contained within the backing store. + DCHECK(clip_rect.bottom() <= canvas_.getDevice()->height()); + DCHECK(clip_rect.right() <= canvas_.getDevice()->width()); + if (bitmap.width() != bitmap_rect.width() || bitmap.height() != bitmap_rect.height() || bitmap.config() != SkBitmap::kARGB_8888_Config) { return; } - // We assume that |clip_rect| is within the backing store. - const SkBitmap &backing_bitmap = canvas_.getDevice()->accessBitmap(true); const int stride = backing_bitmap.rowBytes(); uint8_t* x = static_cast<uint8_t*>(backing_bitmap.getPixels()); if (dx) { - // Horizontal scroll. Positive values of |dx| scroll right. - - // We know that |clip_rect| is the destination rectangle. The source - // rectangle, in an infinite world, would be the destination rectangle - // translated by -dx. However, we can't pull pixels from beyound the - // edge of the backing store. By truncating the source rectangle to the - // backing store, we might have made it thinner, thus we find the final - // dest rectangle by translating the resulting source rectangle back. - const int bs_width = canvas_.getDevice()->width(); - const int src_rect_left = RangeClip(clip_rect.x() - dx, bs_width); - const int src_rect_right = RangeClip(clip_rect.right() - dx, bs_width); - - const int dest_rect_left = RangeClip(src_rect_left + dx, bs_width); - const int dest_rect_right = RangeClip(src_rect_right + dx, bs_width); - - DCHECK(dest_rect_right >= dest_rect_left); - DCHECK(src_rect_right >= src_rect_left); - DCHECK(dest_rect_right - dest_rect_left == - src_rect_right - src_rect_left); + // Horizontal scroll. According to msdn, positive values of |dx| scroll + // left, but in practice this seems reversed. TODO(port): figure this + // out. For now just reverse the sign. + dx *= -1; // This is the number of bytes to move per line at 4 bytes per pixel. - const int len = (dest_rect_right - dest_rect_left) * 4; + const int len = (clip_rect.width() - abs(dx)) * 4; - // Position the pixel data pointer at the top-left corner of the dest rect + // Move |x| to the first pixel of the first row. x += clip_rect.y() * stride; x += clip_rect.x() * 4; - // This is the number of bytes to reach left in order to find the source - // rectangle. (Will be negative for a left scroll.) - const int left_reach = dest_rect_left - src_rect_left; + // If we are scrolling left, move |x| to the |dx|^th pixel. + if (dx < 0) { + x -= dx * 4; + } - for (int y = clip_rect.y(); y < clip_rect.bottom(); ++y) { + for (int i = clip_rect.y(); i < clip_rect.bottom(); ++i) { // Note that overlapping regions requires memmove, not memcpy. - memmove(x, x + left_reach, len); + memmove(x, x + dx * 4, len); x += stride; } } else { - // Vertical scroll. Positive values of |dy| scroll down. - - // The logic is very similar to the horizontal case, above. - const int bs_height = canvas_.getDevice()->height(); - const int src_rect_top = RangeClip(clip_rect.y() - dy, bs_height); - const int src_rect_bottom = RangeClip(clip_rect.bottom() - dy, bs_height); - - const int dest_rect_top = RangeClip(src_rect_top + dy, bs_height); - const int dest_rect_bottom = RangeClip(src_rect_bottom + dy, bs_height); + // Vertical scroll. According to msdn, positive values of |dy| scroll down, + // but in practice this seems reversed. TODO(port): figure this out. For now + // just reverse the sign. + dy *= -1; const int len = clip_rect.width() * 4; - DCHECK(dest_rect_bottom >= dest_rect_top); - DCHECK(src_rect_bottom >= src_rect_top); - - // We need to consider the two directions separately here because the order - // of copying rows must vary to avoid writing data which we later need to - // read. + // For down scrolls, we copy bottom-up (in screen coordinates). + // For up scrolls, we copy top-down. if (dy > 0) { - // Scrolling down; dest rect is above src rect. - - // Position the pixel data pointer at the top-left corner of the dest - // rect. - x += dest_rect_top * stride; + // Move |x| to the first pixel of this row. x += clip_rect.x() * 4; - DCHECK(dest_rect_top <= src_rect_top); - const int down_reach_bytes = stride * (src_rect_top - dest_rect_top); - - for (int y = dest_rect_top; y < dest_rect_bottom; ++y) { - memcpy(x, x + down_reach_bytes, len); + for (int i = clip_rect.y(); i < clip_rect.height() - dy; ++i) { + memcpy(x, x + stride * dy, len); x += stride; } } else { - // Scrolling up; dest rect is below src rect. - - // Position the pixel data pointer at the bottom-left corner of the dest - // rect. - x += (dest_rect_bottom - 1) * stride; + // Move |x| to the first pixel of the last row of the clip rect. x += clip_rect.x() * 4; + x += clip_rect.bottom() * stride; - DCHECK(src_rect_top <= dest_rect_top); - const int up_reach_bytes = stride * (dest_rect_bottom - src_rect_bottom); - - for (int y = dest_rect_bottom - 1; y >= dest_rect_top; --y) { - memcpy(x, x - up_reach_bytes, len); + for (int i = clip_rect.y(); i < clip_rect.height() + dy; ++i) { + memcpy(x, x + stride * dy, len); x -= stride; } } diff --git a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc index 31f14ad..58cf519 100644 --- a/chrome/browser/renderer_host/render_widget_host_view_gtk.cc +++ b/chrome/browser/renderer_host/render_widget_host_view_gtk.cc @@ -206,12 +206,12 @@ void RenderWidgetHostViewGtk::IMEUpdateStatus(int control, } void RenderWidgetHostViewGtk::DidPaintRect(const gfx::Rect& rect) { - NOTIMPLEMENTED(); + Paint(rect); } void RenderWidgetHostViewGtk::DidScrollRect(const gfx::Rect& rect, int dx, int dy) { - NOTIMPLEMENTED(); + Paint(rect); } void RenderWidgetHostViewGtk::RendererGone() { @@ -223,7 +223,7 @@ void RenderWidgetHostViewGtk::Destroy() { } void RenderWidgetHostViewGtk::SetTooltipText(const std::wstring& tooltip_text) { - NOTIMPLEMENTED(); + // TODO(port): implement this } void RenderWidgetHostViewGtk::Paint(const gfx::Rect& damage_rect) { diff --git a/chrome/renderer/render_widget.cc b/chrome/renderer/render_widget.cc index 83732eb..fd5dcff 100644 --- a/chrome/renderer/render_widget.cc +++ b/chrome/renderer/render_widget.cc @@ -301,10 +301,12 @@ void RenderWidget::OnPaintRectAck() { } void RenderWidget::OnScrollRectAck() { +#if defined(OS_WIN) DCHECK(scroll_reply_pending()); RenderProcess::FreeSharedMemory(current_scroll_buf_); current_scroll_buf_ = NULL; +#endif // Continue scrolling if necessary... DoDeferredScroll(); |