diff options
author | bajones@chromium.org <bajones@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-15 22:20:09 +0000 |
---|---|---|
committer | bajones@chromium.org <bajones@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-12-15 22:20:09 +0000 |
commit | c9bc8f1104914818e054b7f9f2b928ce78bc9dd8 (patch) | |
tree | 65db09fb71c6f73383285b406fe25aaf7d206dc9 /ui | |
parent | d72acb0dd473cd8dd0d3d420e22a03c766d76623 (diff) | |
download | chromium_src-c9bc8f1104914818e054b7f9f2b928ce78bc9dd8.zip chromium_src-c9bc8f1104914818e054b7f9f2b928ce78bc9dd8.tar.gz chromium_src-c9bc8f1104914818e054b7f9f2b928ce78bc9dd8.tar.bz2 |
Implemented GetWindowSnapshot on RenderViewImpl
This necessitated the relocation of the previous chrome::GrabWindowSnapshot code
to ui/snapshot, which has been turned into it's own component to avoid circular dependencies with aura.
A new variant of GrabWindowSnapshot, GrabViewSnapshot, has been added as well to facilitate easier usage by views. chrome::GrabWindowSnapshotForUser was left in place to accomodate existing calls
to the API, but now calls up to the ui/snapshot code.
This is a subset of the prior CL 11362023, which has been broken apart to facilitate easier reviews
BUG=157479
Review URL: https://chromiumcodereview.appspot.com/11399002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@173329 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ui')
-rw-r--r-- | ui/snapshot/DEPS | 7 | ||||
-rw-r--r-- | ui/snapshot/snapshot.gyp | 65 | ||||
-rw-r--r-- | ui/snapshot/snapshot.h | 34 | ||||
-rw-r--r-- | ui/snapshot/snapshot_android.cc | 25 | ||||
-rw-r--r-- | ui/snapshot/snapshot_aura.cc | 58 | ||||
-rw-r--r-- | ui/snapshot/snapshot_export.h | 32 | ||||
-rw-r--r-- | ui/snapshot/snapshot_gtk.cc | 85 | ||||
-rw-r--r-- | ui/snapshot/snapshot_ios.mm | 25 | ||||
-rw-r--r-- | ui/snapshot/snapshot_mac.mm | 73 | ||||
-rw-r--r-- | ui/snapshot/snapshot_mac_unittest.mm | 62 | ||||
-rw-r--r-- | ui/snapshot/snapshot_win.cc | 106 |
11 files changed, 572 insertions, 0 deletions
diff --git a/ui/snapshot/DEPS b/ui/snapshot/DEPS new file mode 100644 index 0000000..13c975d --- /dev/null +++ b/ui/snapshot/DEPS @@ -0,0 +1,7 @@ +include_rules = [ + "+skia", + "+ui/aura", + "+ui/base", + "+ui/compositor", + "+ui/gfx", +]
\ No newline at end of file diff --git a/ui/snapshot/snapshot.gyp b/ui/snapshot/snapshot.gyp new file mode 100644 index 0000000..40744bf --- /dev/null +++ b/ui/snapshot/snapshot.gyp @@ -0,0 +1,65 @@ +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'variables': { + 'chromium_code': 1, + }, + 'targets': [ + { + 'target_name': 'snapshot', + 'type': '<(component)', + 'dependencies': [ + '../../skia/skia.gyp:skia', + '../../base/base.gyp:base', + '../ui.gyp:ui', + ], + 'defines': [ + 'SNAPSHOT_IMPLEMENTATION', + ], + 'sources': [ + 'snapshot.h', + 'snapshot_android.cc', + 'snapshot_aura.cc', + 'snapshot_export.h', + 'snapshot_gtk.cc', + 'snapshot_ios.mm', + 'snapshot_mac.mm', + 'snapshot_win.cc', + ], + 'include_dirs': [ + '..', + ], + 'conditions': [ + ['use_aura==1', { + 'dependencies': [ + '../aura/aura.gyp:aura', + '../compositor/compositor.gyp:compositor', + ], + }], + ['use_aura==1 and OS=="win"', { + 'sources/': [ + ['exclude', 'snapshot_win.cc'], + ], + }], + ], + }, + { + 'target_name': 'snapshot_unittests', + 'type': '<(gtest_target_type)', + 'dependencies': [ + '../../skia/skia.gyp:skia', + '../../base/base.gyp:base', + '../../testing/gtest.gyp:gtest', + '../../testing/gmock.gyp:gmock', + '../../testing/gtest.gyp:gtest', + '../ui.gyp:ui', + 'snapshot' + ], + 'sources': [ + 'snapshot_mac_unittest.mm', + ] + }, + ], +} diff --git a/ui/snapshot/snapshot.h b/ui/snapshot/snapshot.h new file mode 100644 index 0000000..356309d --- /dev/null +++ b/ui/snapshot/snapshot.h @@ -0,0 +1,34 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_SNAPSHOT_SNAPSHOT_H_ +#define UI_SNAPSHOT_SNAPSHOT_H_ + +#include <vector> + +#include "ui/gfx/native_widget_types.h" +#include "ui/snapshot/snapshot_export.h" + +namespace gfx { +class Rect; +} + +namespace ui { + +// Grabs a snapshot of the window/view. No security checks are done. +// This is intended to be used for debugging purposes where no BrowserProcess +// instance is available (ie. tests). DO NOT use in a result of user action. +SNAPSHOT_EXPORT bool GrabWindowSnapshot( + gfx::NativeWindow window, + std::vector<unsigned char>* png_representation, + const gfx::Rect& snapshot_bounds); + +SNAPSHOT_EXPORT bool GrabViewSnapshot( + gfx::NativeView view, + std::vector<unsigned char>* png_representation, + const gfx::Rect& snapshot_bounds); + +} // namespace ui + +#endif // UI_SNAPSHOT_SNAPSHOT_H_ diff --git a/ui/snapshot/snapshot_android.cc b/ui/snapshot/snapshot_android.cc new file mode 100644 index 0000000..4e89c9d --- /dev/null +++ b/ui/snapshot/snapshot_android.cc @@ -0,0 +1,25 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/snapshot/snapshot.h" + +#include "ui/gfx/rect.h" + +namespace ui { + +bool GrabViewSnapshot(gfx::NativeView view, + std::vector<unsigned char>* png_representation, + const gfx::Rect& snapshot_bounds) { + // TODO(bajones): Implement Android snapshot functionality + return false; +} + +bool GrabWindowSnapshot(gfx::NativeWindow window, + std::vector<unsigned char>* png_representation, + const gfx::Rect& snapshot_bounds) { + // TODO(bajones): Implement Android snapshot functionality + return false; +} + +} // namespace ui diff --git a/ui/snapshot/snapshot_aura.cc b/ui/snapshot/snapshot_aura.cc new file mode 100644 index 0000000..1eca6d5 --- /dev/null +++ b/ui/snapshot/snapshot_aura.cc @@ -0,0 +1,58 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/snapshot/snapshot.h" + +#include "base/logging.h" +#include "third_party/skia/include/core/SkBitmap.h" +#include "ui/aura/window.h" +#include "ui/compositor/compositor.h" +#include "ui/compositor/dip_util.h" +#include "ui/compositor/layer.h" +#include "ui/gfx/codec/png_codec.h" +#include "ui/gfx/rect.h" + +namespace ui { + +bool GrabViewSnapshot(gfx::NativeView view, + std::vector<unsigned char>* png_representation, + const gfx::Rect& snapshot_bounds) { + return GrabWindowSnapshot(view, png_representation, snapshot_bounds); +} + +bool GrabWindowSnapshot(gfx::NativeWindow window, + std::vector<unsigned char>* png_representation, + const gfx::Rect& snapshot_bounds) { + ui::Compositor* compositor = window->layer()->GetCompositor(); + + gfx::Rect read_pixels_bounds = snapshot_bounds; + + // When not in compact mode we must take into account the window's position on + // the desktop. + read_pixels_bounds.Offset(window->bounds().OffsetFromOrigin()); + gfx::Rect read_pixels_bounds_in_pixel = + ui::ConvertRectToPixel(window->layer(), read_pixels_bounds); + + // Sometimes (i.e. when using Aero on Windows) the compositor's size is + // smaller than the window bounds. So trim appropriately. + read_pixels_bounds_in_pixel.Intersect(gfx::Rect(compositor->size())); + + DCHECK_LE(0, read_pixels_bounds.x()); + DCHECK_LE(0, read_pixels_bounds.y()); + + SkBitmap bitmap; + if (!compositor->ReadPixels(&bitmap, read_pixels_bounds_in_pixel)) + return false; + + unsigned char* pixels = reinterpret_cast<unsigned char*>(bitmap.getPixels()); + + gfx::PNGCodec::Encode(pixels, gfx::PNGCodec::FORMAT_BGRA, + read_pixels_bounds_in_pixel.size(), + bitmap.rowBytes(), true, + std::vector<gfx::PNGCodec::Comment>(), + png_representation); + return true; +} + +} // namespace ui diff --git a/ui/snapshot/snapshot_export.h b/ui/snapshot/snapshot_export.h new file mode 100644 index 0000000..9e27370 --- /dev/null +++ b/ui/snapshot/snapshot_export.h @@ -0,0 +1,32 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_SNAPSHOT_SNAPSHOT_EXPORT_H +#define UI_SNAPSHOT_SNAPSHOT_EXPORT_H + +// Defines SNAPSHOT_EXPORT so that functionality implemented by the snapshot +// module can be exported to consumers. + +#if defined(COMPONENT_BUILD) +#if defined(WIN32) + +#if defined(SNAPSHOT_IMPLEMENTATION) +#define SNAPSHOT_EXPORT __declspec(dllexport) +#else +#define SNAPSHOT_EXPORT __declspec(dllimport) +#endif // defined(SNAPSHOT_IMPLEMENTATION) + +#else // defined(WIN32) +#if defined(SNAPSHOT_IMPLEMENTATION) +#define SNAPSHOT_EXPORT __attribute__((visibility("default"))) +#else +#define SNAPSHOT_EXPORT +#endif +#endif + +#else // defined(COMPONENT_BUILD) +#define SNAPSHOT_EXPORT +#endif + +#endif // UI_SNAPSHOT_SNAPSHOT_EXPORT_H diff --git a/ui/snapshot/snapshot_gtk.cc b/ui/snapshot/snapshot_gtk.cc new file mode 100644 index 0000000..8a2f8c1 --- /dev/null +++ b/ui/snapshot/snapshot_gtk.cc @@ -0,0 +1,85 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/snapshot/snapshot.h" + +#include <gdk/gdkx.h> +#include <gtk/gtk.h> + +#include "base/logging.h" +#include "ui/base/x/x11_util.h" +#include "ui/gfx/rect.h" + +namespace { + +cairo_status_t SnapshotCallback(void* closure, + const unsigned char* data, + unsigned int length) { + std::vector<unsigned char>* png_representation = + static_cast<std::vector<unsigned char>*>(closure); + + size_t old_size = png_representation->size(); + png_representation->resize(old_size + length); + memcpy(&(*png_representation)[old_size], data, length); + return CAIRO_STATUS_SUCCESS; +} + +} // namespace + +namespace ui { + +bool GrabViewSnapshot(gfx::NativeView view_handle, + std::vector<unsigned char>* png_representation, + const gfx::Rect& snapshot_bounds) { + GdkWindow* gdk_window = gtk_widget_get_window(view_handle); + Display* display = GDK_WINDOW_XDISPLAY(gdk_window); + XID win = GDK_WINDOW_XID(gdk_window); + + gfx::Rect window_bounds; + if (ui::GetWindowRect(win, &window_bounds) == 0) { + LOG(ERROR) << "Couldn't get window bounds"; + return false; + } + + DCHECK_LE(snapshot_bounds.right(), window_bounds.width()); + DCHECK_LE(snapshot_bounds.bottom(), window_bounds.height()); + + ui::XScopedImage image(XGetImage( + display, win, snapshot_bounds.x(), snapshot_bounds.y(), + snapshot_bounds.width(), snapshot_bounds.height(), AllPlanes, ZPixmap)); + if (!image.get()) { + LOG(ERROR) << "Couldn't get image"; + return false; + } + if (image->depth != 24) { + LOG(ERROR)<< "Unsupported image depth " << image->depth; + return false; + } + cairo_surface_t* surface = + cairo_image_surface_create_for_data( + reinterpret_cast<unsigned char*>(image->data), + CAIRO_FORMAT_RGB24, + image->width, + image->height, + image->bytes_per_line); + + if (!surface) { + LOG(ERROR) << "Unable to create Cairo surface from XImage data"; + return false; + } + cairo_surface_write_to_png_stream( + surface, SnapshotCallback, png_representation); + cairo_surface_destroy(surface); + + return true; +} + +bool GrabWindowSnapshot(gfx::NativeWindow window_handle, + std::vector<unsigned char>* png_representation, + const gfx::Rect& snapshot_bounds) { + return GrabViewSnapshot(GTK_WIDGET(window_handle), png_representation, + snapshot_bounds); +} + +} // namespace ui diff --git a/ui/snapshot/snapshot_ios.mm b/ui/snapshot/snapshot_ios.mm new file mode 100644 index 0000000..b373a03 --- /dev/null +++ b/ui/snapshot/snapshot_ios.mm @@ -0,0 +1,25 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/snapshot/snapshot.h" + +#include "ui/gfx/rect.h" + +namespace ui { + +bool GrabViewSnapshot(gfx::NativeView view, + std::vector<unsigned char>* png_representation, + const gfx::Rect& snapshot_bounds) { + // TODO(bajones): Implement iOS snapshot functionality + return false; +} + +bool GrabWindowSnapshot(gfx::NativeWindow window, + std::vector<unsigned char>* png_representation, + const gfx::Rect& snapshot_bounds) { + // TODO(bajones): Implement iOS snapshot functionality + return false; +} + +} // namespace ui diff --git a/ui/snapshot/snapshot_mac.mm b/ui/snapshot/snapshot_mac.mm new file mode 100644 index 0000000..5833704 --- /dev/null +++ b/ui/snapshot/snapshot_mac.mm @@ -0,0 +1,73 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/snapshot/snapshot.h" + +#import <Cocoa/Cocoa.h> + +#include "base/logging.h" +#include "base/mac/scoped_cftyperef.h" +#include "base/memory/scoped_nsobject.h" +#include "ui/gfx/rect.h" + +namespace ui { + +bool GrabViewSnapshot(gfx::NativeView view, + std::vector<unsigned char>* png_representation, + const gfx::Rect& snapshot_bounds) { + NSWindow* window = [view window]; + NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; + gfx::Rect screen_bounds = gfx::Rect(NSRectToCGRect([screen frame])); + + + // Get the view bounds relative to the screen + NSRect frame = [view convertRect:[view bounds] toView:nil]; + frame.origin = [window convertBaseToScreen:frame.origin]; + + gfx::Rect view_bounds = gfx::Rect(NSRectToCGRect(frame)); + + // Flip window coordinates based on the primary screen. + view_bounds.set_y( + screen_bounds.height() - view_bounds.y() - view_bounds.height()); + + // Convert snapshot bounds relative to window into bounds relative to + // screen. + gfx::Rect screen_snapshot_bounds = snapshot_bounds; + screen_snapshot_bounds.Offset(view_bounds.OffsetFromOrigin()); + + DCHECK_LE(screen_snapshot_bounds.right(), view_bounds.right()); + DCHECK_LE(screen_snapshot_bounds.bottom(), view_bounds.bottom()); + + png_representation->clear(); + + base::mac::ScopedCFTypeRef<CGImageRef> windowSnapshot(CGWindowListCreateImage( + screen_snapshot_bounds.ToCGRect(), kCGWindowListOptionIncludingWindow, + [window windowNumber], kCGWindowImageBoundsIgnoreFraming)); + if (CGImageGetWidth(windowSnapshot) <= 0) + return false; + + scoped_nsobject<NSBitmapImageRep> rep( + [[NSBitmapImageRep alloc] initWithCGImage:windowSnapshot]); + NSData* data = [rep representationUsingType:NSPNGFileType properties:nil]; + const unsigned char* buf = static_cast<const unsigned char*>([data bytes]); + NSUInteger length = [data length]; + if (buf == NULL || length == 0) + return false; + + png_representation->assign(buf, buf + length); + DCHECK(!png_representation->empty()); + + return true; +} + +bool GrabWindowSnapshot(gfx::NativeWindow window, + std::vector<unsigned char>* png_representation, + const gfx::Rect& snapshot_bounds) { + // Make sure to grab the "window frame" view so we get current tab + + // tabstrip. + return GrabViewSnapshot([[window contentView] superview], png_representation, + snapshot_bounds); +} + +} // namespace ui diff --git a/ui/snapshot/snapshot_mac_unittest.mm b/ui/snapshot/snapshot_mac_unittest.mm new file mode 100644 index 0000000..90061733 --- /dev/null +++ b/ui/snapshot/snapshot_mac_unittest.mm @@ -0,0 +1,62 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/snapshot/snapshot.h" + +#import <Cocoa/Cocoa.h> + +#include "base/memory/scoped_nsobject.h" +#include "base/memory/scoped_ptr.h" +#include "testing/platform_test.h" +#include "ui/gfx/rect.h" + +#if !defined(MAC_OS_X_VERSION_10_7) || \ + MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7 + +@interface NSWindow (LionAPI) +- (CGFloat)backingScaleFactor; +@end + +#endif // 10.7 + +namespace ui { +namespace { + +typedef PlatformTest GrabWindowSnapshotTest; + +TEST_F(GrabWindowSnapshotTest, TestGrabWindowSnapshot) { + // Launch a test window so we can take a snapshot. + NSRect frame = NSMakeRect(0, 0, 400, 400); + scoped_nsobject<NSWindow> window( + [[NSWindow alloc] initWithContentRect:frame + styleMask:NSBorderlessWindowMask + backing:NSBackingStoreBuffered + defer:NO]); + [window setBackgroundColor:[NSColor whiteColor]]; + [window makeKeyAndOrderFront:NSApp]; + + scoped_ptr<std::vector<unsigned char> > png_representation( + new std::vector<unsigned char>); + gfx::Rect bounds = gfx::Rect(0, 0, frame.size.width, frame.size.height); + EXPECT_TRUE(ui::GrabWindowSnapshot(window, png_representation.get(), + bounds)); + + // Copy png back into NSData object so we can make sure we grabbed a png. + scoped_nsobject<NSData> image_data( + [[NSData alloc] initWithBytes:&(*png_representation)[0] + length:png_representation->size()]); + NSBitmapImageRep* rep = [NSBitmapImageRep imageRepWithData:image_data.get()]; + EXPECT_TRUE([rep isKindOfClass:[NSBitmapImageRep class]]); + CGFloat scaleFactor = 1.0f; + if ([window respondsToSelector:@selector(backingScaleFactor)]) + scaleFactor = [window backingScaleFactor]; + EXPECT_EQ(400 * scaleFactor, CGImageGetWidth([rep CGImage])); + NSColor* color = [rep colorAtX:200 * scaleFactor y:200 * scaleFactor]; + CGFloat red = 0, green = 0, blue = 0, alpha = 0; + [color getRed:&red green:&green blue:&blue alpha:&alpha]; + EXPECT_GE(red + green + blue, 3.0); +} + +} // namespace +} // namespace ui diff --git a/ui/snapshot/snapshot_win.cc b/ui/snapshot/snapshot_win.cc new file mode 100644 index 0000000..3a8d1e7 --- /dev/null +++ b/ui/snapshot/snapshot_win.cc @@ -0,0 +1,106 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/snapshot/snapshot.h" + +#include "base/win/scoped_gdi_object.h" +#include "base/win/scoped_hdc.h" +#include "base/win/scoped_select_object.h" +#include "ui/gfx/codec/png_codec.h" +#include "ui/gfx/gdi_util.h" +#include "ui/gfx/rect.h" +#include "ui/gfx/size.h" + +namespace { + +gfx::Rect GetWindowBounds(gfx::NativeWindow window_handle) { + RECT content_rect = {0, 0, 0, 0}; + if (window_handle) { + ::GetWindowRect(window_handle, &content_rect); + } else { + MONITORINFO monitor_info = {}; + monitor_info.cbSize = sizeof(monitor_info); + if (GetMonitorInfo(MonitorFromWindow(NULL, MONITOR_DEFAULTTOPRIMARY), + &monitor_info)) { + content_rect = monitor_info.rcMonitor; + } + } + content_rect.right++; // Match what PrintWindow wants. + + return gfx::Rect(content_rect.right - content_rect.left, + content_rect.bottom - content_rect.top); +} + +} // namespace + +namespace ui { + +bool GrabViewSnapshot(gfx::NativeView view_handle, + std::vector<unsigned char>* png_representation, + const gfx::Rect& snapshot_bounds) { + return GrabWindowSnapshot(view_handle, png_representation, snapshot_bounds); +} + +bool GrabWindowSnapshot(gfx::NativeWindow window_handle, + std::vector<unsigned char>* png_representation, + const gfx::Rect& snapshot_bounds) { + DCHECK(snapshot_bounds.right() <= GetWindowBounds(window_handle).right()); + DCHECK(snapshot_bounds.bottom() <= GetWindowBounds(window_handle).bottom()); + + // Create a memory DC that's compatible with the window. + HDC window_hdc = GetWindowDC(window_handle); + base::win::ScopedCreateDC mem_hdc(CreateCompatibleDC(window_hdc)); + + BITMAPINFOHEADER hdr; + gfx::CreateBitmapHeader(snapshot_bounds.width(), + snapshot_bounds.height(), + &hdr); + unsigned char *bit_ptr = NULL; + base::win::ScopedBitmap bitmap( + CreateDIBSection(mem_hdc, + reinterpret_cast<BITMAPINFO*>(&hdr), + DIB_RGB_COLORS, + reinterpret_cast<void **>(&bit_ptr), + NULL, 0)); + + base::win::ScopedSelectObject select_bitmap(mem_hdc, bitmap); + // Clear the bitmap to white (so that rounded corners on windows + // show up on a white background, and strangely-shaped windows + // look reasonable). Not capturing an alpha mask saves a + // bit of space. + PatBlt(mem_hdc, 0, 0, snapshot_bounds.width(), snapshot_bounds.height(), + WHITENESS); + // Grab a copy of the window + // First, see if PrintWindow is defined (it's not in Windows 2000). + typedef BOOL (WINAPI *PrintWindowPointer)(HWND, HDC, UINT); + PrintWindowPointer print_window = + reinterpret_cast<PrintWindowPointer>( + GetProcAddress(GetModuleHandle(L"User32.dll"), "PrintWindow")); + + // If PrintWindow is defined, use it. It will work on partially + // obscured windows, and works better for out of process sub-windows. + // Otherwise grab the bits we can get with BitBlt; it's better + // than nothing and will work fine in the average case (window is + // completely on screen). Always BitBlt when grabbing the whole screen. + if (snapshot_bounds.origin() == gfx::Point() && print_window && window_handle) + (*print_window)(window_handle, mem_hdc, 0); + else + BitBlt(mem_hdc, 0, 0, snapshot_bounds.width(), snapshot_bounds.height(), + window_hdc, snapshot_bounds.x(), snapshot_bounds.y(), SRCCOPY); + + // We now have a copy of the window contents in a DIB, so + // encode it into a useful format for posting to the bug report + // server. + gfx::PNGCodec::Encode(bit_ptr, gfx::PNGCodec::FORMAT_BGRA, + snapshot_bounds.size(), + snapshot_bounds.width() * 4, true, + std::vector<gfx::PNGCodec::Comment>(), + png_representation); + + ReleaseDC(window_handle, window_hdc); + + return true; +} + +} // namespace ui |