| 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 |