OLD | NEW |
| (Empty) |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "base/gfx/blit.h" | |
6 | |
7 #if defined(OS_LINUX) | |
8 #include <cairo/cairo.h> | |
9 #endif | |
10 | |
11 #include "base/gfx/point.h" | |
12 #include "base/gfx/rect.h" | |
13 #if defined(OS_MACOSX) | |
14 #include "base/scoped_cftyperef.h" | |
15 #endif | |
16 #include "skia/ext/platform_canvas.h" | |
17 #include "skia/ext/platform_device.h" | |
18 | |
19 namespace gfx { | |
20 | |
21 void BlitContextToContext(NativeDrawingContext dst_context, | |
22 const Rect& dst_rect, | |
23 NativeDrawingContext src_context, | |
24 const Point& src_origin) { | |
25 #if defined(OS_WIN) | |
26 BitBlt(dst_context, dst_rect.x(), dst_rect.y(), | |
27 dst_rect.width(), dst_rect.height(), | |
28 src_context, src_origin.x(), src_origin.y(), SRCCOPY); | |
29 #elif defined(OS_MACOSX) | |
30 // Only translations and/or vertical flips in the source context are | |
31 // supported; more complex source context transforms will be ignored. | |
32 | |
33 // If there is a translation on the source context, we need to account for | |
34 // it ourselves since CGBitmapContextCreateImage will bypass it. | |
35 Rect src_rect(src_origin, dst_rect.size()); | |
36 CGAffineTransform transform = CGContextGetCTM(src_context); | |
37 bool flipped = fabs(transform.d + 1) < 0.0001; | |
38 CGFloat delta_y = flipped ? CGBitmapContextGetHeight(src_context) - | |
39 transform.ty | |
40 : transform.ty; | |
41 src_rect.Offset(transform.tx, delta_y); | |
42 | |
43 scoped_cftyperef<CGImageRef> | |
44 src_image(CGBitmapContextCreateImage(src_context)); | |
45 scoped_cftyperef<CGImageRef> src_sub_image( | |
46 CGImageCreateWithImageInRect(src_image, src_rect.ToCGRect())); | |
47 CGContextDrawImage(dst_context, dst_rect.ToCGRect(), src_sub_image); | |
48 #elif defined(OS_LINUX) | |
49 // Only translations in the source context are supported; more complex | |
50 // source context transforms will be ignored. | |
51 cairo_save(dst_context); | |
52 double surface_x = src_origin.x(); | |
53 double surface_y = src_origin.y(); | |
54 cairo_user_to_device(src_context, &surface_x, &surface_y); | |
55 cairo_set_source_surface(dst_context, cairo_get_target(src_context), | |
56 dst_rect.x()-surface_x, dst_rect.y()-surface_y); | |
57 cairo_rectangle(dst_context, dst_rect.x(), dst_rect.y(), | |
58 dst_rect.width(), dst_rect.height()); | |
59 cairo_clip(dst_context); | |
60 cairo_paint(dst_context); | |
61 cairo_restore(dst_context); | |
62 #endif | |
63 } | |
64 | |
65 static NativeDrawingContext GetContextFromCanvas( | |
66 skia::PlatformCanvas *canvas) { | |
67 skia::PlatformDevice& device = canvas->getTopPlatformDevice(); | |
68 #if defined(OS_WIN) | |
69 return device.getBitmapDC(); | |
70 #elif defined(OS_MACOSX) | |
71 return device.GetBitmapContext(); | |
72 #elif defined(OS_LINUX) | |
73 return device.beginPlatformPaint(); | |
74 #endif | |
75 } | |
76 | |
77 void BlitContextToCanvas(skia::PlatformCanvas *dst_canvas, | |
78 const Rect& dst_rect, | |
79 NativeDrawingContext src_context, | |
80 const Point& src_origin) { | |
81 BlitContextToContext(GetContextFromCanvas(dst_canvas), dst_rect, | |
82 src_context, src_origin); | |
83 } | |
84 | |
85 void BlitCanvasToContext(NativeDrawingContext dst_context, | |
86 const Rect& dst_rect, | |
87 skia::PlatformCanvas *src_canvas, | |
88 const Point& src_origin) { | |
89 BlitContextToContext(dst_context, dst_rect, | |
90 GetContextFromCanvas(src_canvas), src_origin); | |
91 } | |
92 | |
93 void BlitCanvasToCanvas(skia::PlatformCanvas *dst_canvas, | |
94 const Rect& dst_rect, | |
95 skia::PlatformCanvas *src_canvas, | |
96 const Point& src_origin) { | |
97 BlitContextToContext(GetContextFromCanvas(dst_canvas), dst_rect, | |
98 GetContextFromCanvas(src_canvas), src_origin); | |
99 } | |
100 | |
101 } // namespace gfx | |
OLD | NEW |