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 |