OLD | NEW |
| (Empty) |
1 // Copyright (c) 2010 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 #ifndef NP_NO_QUICKDRAW | |
6 | |
7 #include "webkit/glue/plugins/quickdraw_drawing_manager_mac.h" | |
8 | |
9 #include "webkit/glue/plugins/coregraphics_private_symbols_mac.h" | |
10 | |
11 // Turn off GCC warnings about deprecated functions (since QuickDraw is a | |
12 // deprecated API). According to the GCC documentation, this can only be done | |
13 // per file, not pushed and popped like some options can be. | |
14 #pragma GCC diagnostic ignored "-Wdeprecated-declarations" | |
15 | |
16 QuickDrawDrawingManager::QuickDrawDrawingManager() | |
17 : plugin_window_(NULL), target_context_(NULL), fast_path_enabled_(false), | |
18 current_port_(NULL), target_world_(NULL), plugin_world_(NULL) {} | |
19 | |
20 QuickDrawDrawingManager::~QuickDrawDrawingManager() { | |
21 DestroyGWorlds(); | |
22 } | |
23 | |
24 void QuickDrawDrawingManager::SetFastPathEnabled(bool enabled) { | |
25 if (fast_path_enabled_ == enabled) | |
26 return; | |
27 | |
28 fast_path_enabled_ = enabled; | |
29 if (enabled) { | |
30 if (!target_world_) | |
31 UpdateGWorlds(); | |
32 // Copy our last window snapshot into our new source, since the plugin | |
33 // may not repaint everything. | |
34 CopyGWorldBits(target_world_, plugin_world_, plugin_size_); | |
35 current_port_ = plugin_world_; | |
36 } else { | |
37 current_port_ = GetWindowPort(plugin_window_); | |
38 } | |
39 } | |
40 | |
41 void QuickDrawDrawingManager::SetTargetContext(CGContextRef context, | |
42 const gfx::Size& plugin_size) { | |
43 target_context_ = context; | |
44 if (plugin_size != plugin_size_) { | |
45 plugin_size_ = plugin_size; | |
46 // Pitch the old GWorlds, since they are the wrong size now. | |
47 DestroyGWorlds(); | |
48 if (fast_path_enabled_) | |
49 UpdateGWorlds(); | |
50 } | |
51 } | |
52 | |
53 void QuickDrawDrawingManager::SetPluginWindow(WindowRef window) { | |
54 plugin_window_ = window; | |
55 if (!fast_path_enabled_) | |
56 current_port_ = GetWindowPort(window); | |
57 } | |
58 | |
59 void QuickDrawDrawingManager::UpdateContext() { | |
60 if (fast_path_enabled_) | |
61 CopyGWorldBits(plugin_world_, target_world_, plugin_size_); | |
62 else | |
63 ScrapeWindow(plugin_window_, target_context_, plugin_size_); | |
64 } | |
65 | |
66 bool QuickDrawDrawingManager::IsFastPathEnabled() { | |
67 return fast_path_enabled_; | |
68 } | |
69 | |
70 void QuickDrawDrawingManager::MakePortCurrent() { | |
71 if (fast_path_enabled_) | |
72 SetGWorld(current_port_, NULL); | |
73 else | |
74 SetPort(current_port_); | |
75 } | |
76 | |
77 void QuickDrawDrawingManager::DestroyGWorlds() { | |
78 if (plugin_world_) { | |
79 DisposeGWorld(plugin_world_); | |
80 plugin_world_ = NULL; | |
81 } | |
82 if (target_world_) { | |
83 DisposeGWorld(target_world_); | |
84 target_world_ = NULL; | |
85 } | |
86 } | |
87 | |
88 void QuickDrawDrawingManager::UpdateGWorlds() { | |
89 DestroyGWorlds(); | |
90 if (!target_context_) | |
91 return; | |
92 | |
93 Rect window_bounds = { | |
94 0, 0, plugin_size_.height(), plugin_size_.width() | |
95 }; | |
96 // Create a GWorld pointing at the same bits as our target context. | |
97 if (target_context_) { | |
98 NewGWorldFromPtr( | |
99 &target_world_, k32BGRAPixelFormat, &window_bounds, NULL, NULL, 0, | |
100 static_cast<Ptr>(CGBitmapContextGetData(target_context_)), | |
101 static_cast<SInt32>(CGBitmapContextGetBytesPerRow(target_context_))); | |
102 } | |
103 // Create a GWorld for the plugin to paint into whenever it wants; since | |
104 // QuickDraw plugins don't draw at known times, they can't be allowed to draw | |
105 // directly into the shared memory. | |
106 NewGWorld(&plugin_world_, k32ARGBPixelFormat, &window_bounds, | |
107 NULL, NULL, kNativeEndianPixMap); | |
108 if (fast_path_enabled_) | |
109 current_port_ = plugin_world_; | |
110 } | |
111 | |
112 void QuickDrawDrawingManager::ScrapeWindow(WindowRef window, | |
113 CGContextRef target_context, | |
114 const gfx::Size& plugin_size) { | |
115 if (!target_context) | |
116 return; | |
117 | |
118 CGRect window_bounds = CGRectMake(0, 0, | |
119 plugin_size.width(), | |
120 plugin_size.height()); | |
121 CGWindowID window_id = HIWindowGetCGWindowID(window); | |
122 CGContextSaveGState(target_context); | |
123 CGContextTranslateCTM(target_context, 0, plugin_size.height()); | |
124 CGContextScaleCTM(target_context, 1.0, -1.0); | |
125 CGContextCopyWindowCaptureContentsToRect(target_context, window_bounds, | |
126 _CGSDefaultConnection(), | |
127 window_id, 0); | |
128 CGContextRestoreGState(target_context); | |
129 } | |
130 | |
131 void QuickDrawDrawingManager::CopyGWorldBits(GWorldPtr source, GWorldPtr dest, | |
132 const gfx::Size& plugin_size) { | |
133 if (!(source && dest)) | |
134 return; | |
135 | |
136 Rect window_bounds = { 0, 0, plugin_size.height(), plugin_size.width() }; | |
137 PixMapHandle source_pixmap = GetGWorldPixMap(source); | |
138 if (LockPixels(source_pixmap)) { | |
139 PixMapHandle dest_pixmap = GetGWorldPixMap(dest); | |
140 if (LockPixels(dest_pixmap)) { | |
141 SetGWorld(dest, NULL); | |
142 // Set foreground and background colors to avoid "colorizing" the image. | |
143 ForeColor(blackColor); | |
144 BackColor(whiteColor); | |
145 CopyBits(reinterpret_cast<BitMap*>(*source_pixmap), | |
146 reinterpret_cast<BitMap*>(*dest_pixmap), | |
147 &window_bounds, &window_bounds, srcCopy, NULL); | |
148 UnlockPixels(dest_pixmap); | |
149 } | |
150 UnlockPixels(source_pixmap); | |
151 } | |
152 } | |
153 | |
154 #endif // !NP_NO_QUICKDRAW | |
OLD | NEW |