| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "ui/gfx/blit.h" | 5 #include "ui/gfx/blit.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "build/build_config.h" | 8 #include "build/build_config.h" |
| 9 #include "skia/ext/platform_canvas.h" | 9 #include "skia/ext/platform_canvas.h" |
| 10 #include "ui/gfx/point.h" | 10 #include "ui/gfx/point.h" |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 122 DCHECK(skia::SupportsPlatformPaint(dst_canvas)); | 122 DCHECK(skia::SupportsPlatformPaint(dst_canvas)); |
| 123 DCHECK(skia::SupportsPlatformPaint(src_canvas)); | 123 DCHECK(skia::SupportsPlatformPaint(src_canvas)); |
| 124 BlitContextToContext(skia::BeginPlatformPaint(dst_canvas), dst_rect, | 124 BlitContextToContext(skia::BeginPlatformPaint(dst_canvas), dst_rect, |
| 125 skia::BeginPlatformPaint(src_canvas), src_origin); | 125 skia::BeginPlatformPaint(src_canvas), src_origin); |
| 126 skia::EndPlatformPaint(src_canvas); | 126 skia::EndPlatformPaint(src_canvas); |
| 127 skia::EndPlatformPaint(dst_canvas); | 127 skia::EndPlatformPaint(dst_canvas); |
| 128 } | 128 } |
| 129 | 129 |
| 130 void ScrollCanvas(SkCanvas* canvas, | 130 void ScrollCanvas(SkCanvas* canvas, |
| 131 const gfx::Rect& in_clip, | 131 const gfx::Rect& in_clip, |
| 132 const gfx::Vector2d& amount) { | 132 const gfx::Vector2d& offset) { |
| 133 DCHECK(!HasClipOrTransform(*canvas)); // Don't support special stuff. | 133 DCHECK(!HasClipOrTransform(*canvas)); // Don't support special stuff. |
| 134 #if defined(OS_WIN) | 134 #if defined(OS_WIN) |
| 135 // If we have a PlatformCanvas, we should use ScrollDC. Otherwise, fall | 135 // If we have a PlatformCanvas, we should use ScrollDC. Otherwise, fall |
| 136 // through to the software implementation. | 136 // through to the software implementation. |
| 137 if (skia::SupportsPlatformPaint(canvas)) { | 137 if (skia::SupportsPlatformPaint(canvas)) { |
| 138 skia::ScopedPlatformPaint scoped_platform_paint(canvas); | 138 skia::ScopedPlatformPaint scoped_platform_paint(canvas); |
| 139 HDC hdc = scoped_platform_paint.GetPlatformSurface(); | 139 HDC hdc = scoped_platform_paint.GetPlatformSurface(); |
| 140 | 140 |
| 141 RECT damaged_rect; | 141 RECT damaged_rect; |
| 142 RECT r = in_clip.ToRECT(); | 142 RECT r = in_clip.ToRECT(); |
| 143 ScrollDC(hdc, amount.x(), amount.y(), NULL, &r, NULL, &damaged_rect); | 143 ScrollDC(hdc, offset.x(), offset.y(), NULL, &r, NULL, &damaged_rect); |
| 144 return; | 144 return; |
| 145 } | 145 } |
| 146 #endif // defined(OS_WIN) | 146 #endif // defined(OS_WIN) |
| 147 // For non-windows, always do scrolling in software. | 147 // For non-windows, always do scrolling in software. |
| 148 // Cairo has no nice scroll function so we do our own. On Mac it's possible to | 148 // Cairo has no nice scroll function so we do our own. On Mac it's possible to |
| 149 // use platform scroll code, but it's complex so we just use the same path | 149 // use platform scroll code, but it's complex so we just use the same path |
| 150 // here. Either way it will be software-only, so it shouldn't matter much. | 150 // here. Either way it will be software-only, so it shouldn't matter much. |
| 151 SkBitmap& bitmap = const_cast<SkBitmap&>( | 151 SkBitmap& bitmap = const_cast<SkBitmap&>( |
| 152 skia::GetTopDevice(*canvas)->accessBitmap(true)); | 152 skia::GetTopDevice(*canvas)->accessBitmap(true)); |
| 153 SkAutoLockPixels lock(bitmap); | 153 SkAutoLockPixels lock(bitmap); |
| 154 | 154 |
| 155 // We expect all coords to be inside the canvas, so clip here. | 155 // We expect all coords to be inside the canvas, so clip here. |
| 156 gfx::Rect clip = gfx::IntersectRects( | 156 gfx::Rect clip = gfx::IntersectRects( |
| 157 in_clip, gfx::Rect(0, 0, bitmap.width(), bitmap.height())); | 157 in_clip, gfx::Rect(0, 0, bitmap.width(), bitmap.height())); |
| 158 | 158 |
| 159 // Compute the set of pixels we'll actually end up painting. | 159 // Compute the set of pixels we'll actually end up painting. |
| 160 gfx::Rect dest_rect = clip; | 160 gfx::Rect dest_rect = gfx::IntersectRects(clip + offset, clip); |
| 161 dest_rect.Offset(amount); | 161 if (dest_rect.size().IsEmpty()) |
| 162 dest_rect.Intersect(clip); | |
| 163 if (dest_rect.size() == gfx::Size()) | |
| 164 return; // Nothing to do. | 162 return; // Nothing to do. |
| 165 | 163 |
| 166 // Compute the source pixels that will map to the dest_rect | 164 // Compute the source pixels that will map to the dest_rect |
| 167 gfx::Rect src_rect = dest_rect; | 165 gfx::Rect src_rect = dest_rect - offset; |
| 168 src_rect.Offset(-amount.x(), -amount.y()); | |
| 169 | 166 |
| 170 size_t row_bytes = dest_rect.width() * 4; | 167 size_t row_bytes = dest_rect.width() * 4; |
| 171 if (amount.y() > 0) { | 168 if (offset.y() > 0) { |
| 172 // Data is moving down, copy from the bottom up. | 169 // Data is moving down, copy from the bottom up. |
| 173 for (int y = dest_rect.height() - 1; y >= 0; y--) { | 170 for (int y = dest_rect.height() - 1; y >= 0; y--) { |
| 174 memcpy(bitmap.getAddr32(dest_rect.x(), dest_rect.y() + y), | 171 memcpy(bitmap.getAddr32(dest_rect.x(), dest_rect.y() + y), |
| 175 bitmap.getAddr32(src_rect.x(), src_rect.y() + y), | 172 bitmap.getAddr32(src_rect.x(), src_rect.y() + y), |
| 176 row_bytes); | 173 row_bytes); |
| 177 } | 174 } |
| 178 } else if (amount.y() < 0) { | 175 } else if (offset.y() < 0) { |
| 179 // Data is moving up, copy from the top down. | 176 // Data is moving up, copy from the top down. |
| 180 for (int y = 0; y < dest_rect.height(); y++) { | 177 for (int y = 0; y < dest_rect.height(); y++) { |
| 181 memcpy(bitmap.getAddr32(dest_rect.x(), dest_rect.y() + y), | 178 memcpy(bitmap.getAddr32(dest_rect.x(), dest_rect.y() + y), |
| 182 bitmap.getAddr32(src_rect.x(), src_rect.y() + y), | 179 bitmap.getAddr32(src_rect.x(), src_rect.y() + y), |
| 183 row_bytes); | 180 row_bytes); |
| 184 } | 181 } |
| 185 } else if (amount.x() != 0) { | 182 } else if (offset.x() != 0) { |
| 186 // Horizontal-only scroll. We can do it in either top-to-bottom or bottom- | 183 // Horizontal-only scroll. We can do it in either top-to-bottom or bottom- |
| 187 // to-top, but have to be careful about the order for copying each row. | 184 // to-top, but have to be careful about the order for copying each row. |
| 188 // Fortunately, memmove already handles this for us. | 185 // Fortunately, memmove already handles this for us. |
| 189 for (int y = 0; y < dest_rect.height(); y++) { | 186 for (int y = 0; y < dest_rect.height(); y++) { |
| 190 memmove(bitmap.getAddr32(dest_rect.x(), dest_rect.y() + y), | 187 memmove(bitmap.getAddr32(dest_rect.x(), dest_rect.y() + y), |
| 191 bitmap.getAddr32(src_rect.x(), src_rect.y() + y), | 188 bitmap.getAddr32(src_rect.x(), src_rect.y() + y), |
| 192 row_bytes); | 189 row_bytes); |
| 193 } | 190 } |
| 194 } | 191 } |
| 195 } | 192 } |
| 196 | 193 |
| 197 } // namespace gfx | 194 } // namespace gfx |
| OLD | NEW |