Commit d21a8a5f authored by pkotwicz@chromium.org's avatar pkotwicz@chromium.org

This replaces the snapshotting code in the pixel tests with the code used to...

This replaces the snapshotting code in the pixel tests with the code used to get screenshots for reporting issues.
Added a bounds parameter to window_snapshot.cc so that we can take a picture of just the tab contents and not have to rebaseline with chrome ui changes.

BUG=None
TEST=None

Review URL: http://codereview.chromium.org/8523022

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@111155 0039d316-1c4b-4281-b951-d872f2087c98
parent 4cdc26a7
......@@ -139,8 +139,11 @@ void ShowHtmlBugReportView(Browser* browser,
last_screenshot_png->clear();
gfx::NativeWindow native_window = browser->window()->GetNativeHandle();
BugReportUtil::SetScreenshotSize(
browser::GrabWindowSnapshot(native_window, last_screenshot_png));
gfx::Rect snapshot_bounds = gfx::Rect(browser->window()->GetBounds().size());
bool success = browser::GrabWindowSnapshot(native_window,
last_screenshot_png,
snapshot_bounds);
BugReportUtil::SetScreenshotSize(success ? snapshot_bounds : gfx::Rect());
std::string bug_report_url = std::string(chrome::kChromeUIBugReportURL) +
"#" + base::IntToString(browser->active_index()) +
......
......@@ -16,10 +16,12 @@ namespace gfx {
namespace browser {
// Grabs a snapshot of the designated window and stores a PNG representation
// into a byte vector. Returns the image bounds.
gfx::Rect GrabWindowSnapshot(gfx::NativeWindow window,
std::vector<unsigned char>* png_representation);
// Grabs a snapshot of the rectangle area |snapshot_bounds| with respect to the
// top left corner of the designated window and stores a PNG representation
// into a byte vector. Returns true if the operation is successful.
bool GrabWindowSnapshot(gfx::NativeWindow window,
std::vector<unsigned char>* png_representation,
const gfx::Rect& snapshot_bounds);
} // namespace browser
......
......@@ -9,11 +9,12 @@
namespace browser {
gfx::Rect GrabWindowSnapshot(gfx::NativeWindow window_handle,
std::vector<unsigned char>* png_representation) {
bool GrabWindowSnapshot(gfx::NativeWindow window_handle,
std::vector<unsigned char>* png_representation,
const gfx::Rect& snapshot_bounds) {
// TODO(saintlou): Stub for Aura.
NOTIMPLEMENTED();
return gfx::Rect();
return false;
}
} // namespace browser
......@@ -24,25 +24,32 @@ static cairo_status_t SnapshotCallback(
return CAIRO_STATUS_SUCCESS;
}
gfx::Rect GrabWindowSnapshot(gfx::NativeWindow gtk_window,
std::vector<unsigned char>* png_representation) {
GdkWindow* gdk_window = GTK_WIDGET(gtk_window)->window;
bool GrabWindowSnapshot(gfx::NativeWindow window_handle,
std::vector<unsigned char>* png_representation,
const gfx::Rect& snapshot_bounds) {
GdkWindow* gdk_window = GTK_WIDGET(window_handle)->window;
Display* display = GDK_WINDOW_XDISPLAY(gdk_window);
XID win = GDK_WINDOW_XID(gdk_window);
XWindowAttributes attr;
if (XGetWindowAttributes(display, win, &attr) == 0) {
LOG(ERROR) << "Couldn't get window attributes";
return gfx::Rect();
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());
XImage* image = XGetImage(
display, win, 0, 0, attr.width, attr.height, AllPlanes, ZPixmap);
display, win, snapshot_bounds.x(), snapshot_bounds.y(),
snapshot_bounds.width(), snapshot_bounds.height(), AllPlanes, ZPixmap);
if (!image) {
LOG(ERROR) << "Couldn't get image";
return gfx::Rect();
return false;
}
if (image->depth != 24) {
LOG(ERROR)<< "Unsupported image depth " << image->depth;
return gfx::Rect();
return false;
}
cairo_surface_t* surface =
cairo_image_surface_create_for_data(
......@@ -54,13 +61,13 @@ gfx::Rect GrabWindowSnapshot(gfx::NativeWindow gtk_window,
if (!surface) {
LOG(ERROR) << "Unable to create Cairo surface from XImage data";
return gfx::Rect();
return false;
}
cairo_surface_write_to_png_stream(
surface, SnapshotCallback, png_representation);
cairo_surface_destroy(surface);
return gfx::Rect(image->width, image->height);
return true;
}
} // namespace browser
......@@ -13,18 +13,36 @@
namespace browser {
gfx::Rect GrabWindowSnapshot(gfx::NativeWindow window,
std::vector<unsigned char>* png_representation) {
bool GrabWindowSnapshot(gfx::NativeWindow window,
std::vector<unsigned char>* png_representation,
const gfx::Rect& snapshot_bounds) {
NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
gfx::Rect screen_bounds = gfx::Rect(NSRectToCGRect([screen frame]));
gfx::Rect window_bounds = gfx::Rect(NSRectToCGRect([window frame]));
// Flip window coordinates based on the primary screen.
window_bounds.set_y(
screen_bounds.height() - window_bounds.y() - window_bounds.height());
// Convert snapshot bounds relative to window into bounds relative to
// screen.
gfx::Rect screen_snapshot_bounds = gfx::Rect(
window_bounds.origin().Add(snapshot_bounds.origin()),
snapshot_bounds.size());
DCHECK_LE(screen_snapshot_bounds.right(), window_bounds.right());
DCHECK_LE(screen_snapshot_bounds.bottom(), window_bounds.bottom());
png_representation->clear();
// Make sure to grab the "window frame" view so we get current tab +
// tabstrip.
NSView* view = [[window contentView] superview];
base::mac::ScopedCFTypeRef<CGImageRef> windowSnapshot(CGWindowListCreateImage(
CGRectNull, kCGWindowListOptionIncludingWindow,
screen_snapshot_bounds.ToCGRect(), kCGWindowListOptionIncludingWindow,
[[view window] windowNumber], kCGWindowImageBoundsIgnoreFraming));
if (CGImageGetWidth(windowSnapshot) <= 0)
return gfx::Rect();
return false;
scoped_nsobject<NSBitmapImageRep> rep(
[[NSBitmapImageRep alloc] initWithCGImage:windowSnapshot]);
......@@ -32,13 +50,12 @@ gfx::Rect GrabWindowSnapshot(gfx::NativeWindow window,
const unsigned char* buf = static_cast<const unsigned char*>([data bytes]);
NSUInteger length = [data length];
if (buf == NULL || length == 0)
return gfx::Rect();
return false;
png_representation->assign(buf, buf + length);
DCHECK(!png_representation->empty());
return gfx::Rect(static_cast<int>([rep pixelsWide]),
static_cast<int>([rep pixelsHigh]));
return true;
}
} // namespace browser
......@@ -30,7 +30,9 @@ TEST_F(GrabWindowSnapshotTest, TestGrabWindowSnapshot) {
scoped_ptr<std::vector<unsigned char> > png_representation(
new std::vector<unsigned char>);
browser::GrabWindowSnapshot(window, png_representation.get());
gfx::Rect bounds = gfx::Rect(0, 0, frame.size.width, frame.size.height);
EXPECT_TRUE(browser::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(
......
......@@ -12,22 +12,35 @@
#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};
::GetWindowRect(window_handle, &content_rect);
content_rect.right++; // Match what PrintWindow wants.
return gfx::Rect(content_rect.right - content_rect.left,
content_rect.bottom - content_rect.top);
}
} // namespace
namespace browser {
gfx::Rect GrabWindowSnapshot(gfx::NativeWindow window_handle,
std::vector<unsigned char>* png_representation) {
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));
// Create a DIB that's the same size as the window.
RECT content_rect = {0, 0, 0, 0};
::GetWindowRect(window_handle, &content_rect);
content_rect.right++; // Match what PrintWindow wants.
int width = content_rect.right - content_rect.left;
int height = content_rect.bottom - content_rect.top;
BITMAPINFOHEADER hdr;
gfx::CreateBitmapHeader(width, height, &hdr);
gfx::CreateBitmapHeader(snapshot_bounds.width(),
snapshot_bounds.height(),
&hdr);
unsigned char *bit_ptr = NULL;
base::win::ScopedBitmap bitmap(
CreateDIBSection(mem_hdc,
......@@ -41,7 +54,8 @@ gfx::Rect GrabWindowSnapshot(gfx::NativeWindow window_handle,
// 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, width, height, WHITENESS);
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);
......@@ -54,22 +68,24 @@ gfx::Rect GrabWindowSnapshot(gfx::NativeWindow window_handle,
// 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).
if (print_window)
if (snapshot_bounds.origin() == gfx::Point() && print_window)
(*print_window)(window_handle, mem_hdc, 0);
else
BitBlt(mem_hdc, 0, 0, width, height, window_hdc, 0, 0, SRCCOPY);
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,
gfx::Size(width, height), width * 4, true,
snapshot_bounds.size(),
snapshot_bounds.width() * 4, true,
std::vector<gfx::PNGCodec::Comment>(),
png_representation);
ReleaseDC(window_handle, window_hdc);
return gfx::Rect(width, height);
return true;
}
} // namespace browser
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment