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 #import <Cocoa/Cocoa.h> | 5 #import <Cocoa/Cocoa.h> |
6 | 6 |
7 #include "content/browser/renderer_host/backing_store_mac.h" | 7 #include "content/browser/renderer_host/backing_store_mac.h" |
8 | 8 |
9 #include "base/logging.h" | 9 #include "base/logging.h" |
10 #include "base/mac/mac_util.h" | 10 #include "base/mac/mac_util.h" |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
145 } | 145 } |
146 | 146 |
147 bool BackingStoreMac::CopyFromBackingStore(const gfx::Rect& rect, | 147 bool BackingStoreMac::CopyFromBackingStore(const gfx::Rect& rect, |
148 skia::PlatformCanvas* output) { | 148 skia::PlatformCanvas* output) { |
149 // TODO(thakis): Make sure this works with HiDPI backing stores. | 149 // TODO(thakis): Make sure this works with HiDPI backing stores. |
150 if (!output->initialize(rect.width(), rect.height(), true)) | 150 if (!output->initialize(rect.width(), rect.height(), true)) |
151 return false; | 151 return false; |
152 | 152 |
153 skia::ScopedPlatformPaint scoped_platform_paint(output); | 153 skia::ScopedPlatformPaint scoped_platform_paint(output); |
154 CGContextRef temp_context = scoped_platform_paint.GetPlatformSurface(); | 154 CGContextRef temp_context = scoped_platform_paint.GetPlatformSurface(); |
155 CGContextSaveGState(temp_context); | 155 gfx::ScopedCGContextSaveGState save_gstate(temp_context); |
156 CGContextTranslateCTM(temp_context, 0.0, size().height()); | 156 CGContextTranslateCTM(temp_context, 0.0, size().height()); |
157 CGContextScaleCTM(temp_context, 1.0, -1.0); | 157 CGContextScaleCTM(temp_context, 1.0, -1.0); |
158 CGContextDrawLayerAtPoint(temp_context, CGPointMake(rect.x(), rect.y()), | 158 CGContextDrawLayerAtPoint(temp_context, CGPointMake(rect.x(), rect.y()), |
159 cg_layer()); | 159 cg_layer()); |
160 CGContextRestoreGState(temp_context); | |
161 return true; | 160 return true; |
162 } | 161 } |
163 | 162 |
164 // Scroll the contents of our CGLayer | 163 // Scroll the contents of our CGLayer |
165 void BackingStoreMac::ScrollBackingStore(int dx, int dy, | 164 void BackingStoreMac::ScrollBackingStore(int dx, int dy, |
166 const gfx::Rect& clip_rect, | 165 const gfx::Rect& clip_rect, |
167 const gfx::Size& view_size) { | 166 const gfx::Size& view_size) { |
168 DCHECK_NE(static_cast<bool>(cg_layer()), static_cast<bool>(cg_bitmap())); | 167 DCHECK_NE(static_cast<bool>(cg_layer()), static_cast<bool>(cg_bitmap())); |
169 | 168 |
170 // "Scroll" the contents of the layer by creating a new CGLayer, | 169 // "Scroll" the contents of the layer by creating a new CGLayer, |
171 // copying the contents of the old one into the new one offset by the scroll | 170 // copying the contents of the old one into the new one offset by the scroll |
172 // amount, swapping in the new CGLayer, and then painting in the new data. | 171 // amount, swapping in the new CGLayer, and then painting in the new data. |
173 // | 172 // |
174 // The Windows code always sets the whole backing store as the source of the | 173 // The Windows code always sets the whole backing store as the source of the |
175 // scroll. Thus, we only have to worry about pixels which will end up inside | 174 // scroll. Thus, we only have to worry about pixels which will end up inside |
176 // the clipping rectangle. (Note that the clipping rectangle is not | 175 // the clipping rectangle. (Note that the clipping rectangle is not |
177 // translated by the scroll.) | 176 // translated by the scroll.) |
178 | 177 |
179 // We assume |clip_rect| is contained within the backing store. | 178 // We assume |clip_rect| is contained within the backing store. |
180 DCHECK(clip_rect.bottom() <= size().height()); | 179 DCHECK(clip_rect.bottom() <= size().height()); |
181 DCHECK(clip_rect.right() <= size().width()); | 180 DCHECK(clip_rect.right() <= size().width()); |
182 | 181 |
183 if ((dx || dy) && abs(dx) < size().width() && abs(dy) < size().height()) { | 182 if ((dx || dy) && abs(dx) < size().width() && abs(dy) < size().height()) { |
184 if (cg_layer()) { | 183 if (cg_layer()) { |
185 CGContextRef layer = CGLayerGetContext(cg_layer()); | 184 CGContextRef layer = CGLayerGetContext(cg_layer()); |
186 CGContextSaveGState(layer); | 185 gfx::ScopedCGContextSaveGState save_gstate(layer); |
187 CGContextClipToRect(layer, | 186 CGContextClipToRect(layer, |
188 CGRectMake(clip_rect.x(), | 187 CGRectMake(clip_rect.x(), |
189 size().height() - clip_rect.bottom(), | 188 size().height() - clip_rect.bottom(), |
190 clip_rect.width(), | 189 clip_rect.width(), |
191 clip_rect.height())); | 190 clip_rect.height())); |
192 CGContextDrawLayerAtPoint(layer, CGPointMake(dx, -dy), cg_layer()); | 191 CGContextDrawLayerAtPoint(layer, CGPointMake(dx, -dy), cg_layer()); |
193 CGContextRestoreGState(layer); | |
194 } else { | 192 } else { |
195 // We don't have a layer, so scroll the contents of the CGBitmapContext. | 193 // We don't have a layer, so scroll the contents of the CGBitmapContext. |
196 base::mac::ScopedCFTypeRef<CGImageRef> bitmap_image( | 194 base::mac::ScopedCFTypeRef<CGImageRef> bitmap_image( |
197 CGBitmapContextCreateImage(cg_bitmap_)); | 195 CGBitmapContextCreateImage(cg_bitmap_)); |
198 CGContextSaveGState(cg_bitmap_); | 196 gfx::ScopedCGContextSaveGState save_gstate(cg_bitmap_); |
199 CGContextClipToRect(cg_bitmap_, | 197 CGContextClipToRect(cg_bitmap_, |
200 CGRectMake(clip_rect.x(), | 198 CGRectMake(clip_rect.x(), |
201 size().height() - clip_rect.bottom(), | 199 size().height() - clip_rect.bottom(), |
202 clip_rect.width(), | 200 clip_rect.width(), |
203 clip_rect.height())); | 201 clip_rect.height())); |
204 CGContextDrawImage(cg_bitmap_, | 202 CGContextDrawImage(cg_bitmap_, |
205 CGRectMake(dx, -dy, size().width(), size().height()), | 203 CGRectMake(dx, -dy, size().width(), size().height()), |
206 bitmap_image); | 204 bitmap_image); |
207 CGContextRestoreGState(cg_bitmap_); | |
208 } | 205 } |
209 } | 206 } |
210 } | 207 } |
211 | 208 |
212 void BackingStoreMac::CopyFromBackingStoreToCGContext(const CGRect& dest_rect, | 209 void BackingStoreMac::CopyFromBackingStoreToCGContext(const CGRect& dest_rect, |
213 CGContextRef context) { | 210 CGContextRef context) { |
214 gfx::ScopedCGContextSaveGState CGContextSaveGState(context); | 211 gfx::ScopedCGContextSaveGState save_gstate(context); |
215 CGContextSetInterpolationQuality(context, kCGInterpolationHigh); | 212 CGContextSetInterpolationQuality(context, kCGInterpolationHigh); |
216 if (cg_layer_) { | 213 if (cg_layer_) { |
217 CGContextDrawLayerInRect(context, dest_rect, cg_layer_); | 214 CGContextDrawLayerInRect(context, dest_rect, cg_layer_); |
218 } else { | 215 } else { |
219 base::mac::ScopedCFTypeRef<CGImageRef> image( | 216 base::mac::ScopedCFTypeRef<CGImageRef> image( |
220 CGBitmapContextCreateImage(cg_bitmap_)); | 217 CGBitmapContextCreateImage(cg_bitmap_)); |
221 CGContextDrawImage(context, dest_rect, image); | 218 CGContextDrawImage(context, dest_rect, image); |
222 } | 219 } |
223 } | 220 } |
224 | 221 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
260 8, pixel_size.width() * 4, | 257 8, pixel_size.width() * 4, |
261 base::mac::GetSystemColorSpace(), | 258 base::mac::GetSystemColorSpace(), |
262 kCGImageAlphaPremultipliedFirst | | 259 kCGImageAlphaPremultipliedFirst | |
263 kCGBitmapByteOrder32Host); | 260 kCGBitmapByteOrder32Host); |
264 DCHECK(context); | 261 DCHECK(context); |
265 | 262 |
266 return context; | 263 return context; |
267 } | 264 } |
268 | 265 |
269 } // namespace content | 266 } // namespace content |
OLD | NEW |