Home | History | Annotate | Download | only in snapshot
      1 // Copyright (c) 2012 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 "ui/snapshot/snapshot.h"
      6 
      7 #import <Cocoa/Cocoa.h>
      8 
      9 #include "base/logging.h"
     10 #include "base/mac/scoped_cftyperef.h"
     11 #include "base/mac/scoped_nsobject.h"
     12 #include "ui/gfx/rect.h"
     13 
     14 namespace ui {
     15 
     16 bool GrabViewSnapshot(gfx::NativeView view,
     17                       std::vector<unsigned char>* png_representation,
     18                       const gfx::Rect& snapshot_bounds) {
     19   NSWindow* window = [view window];
     20   NSScreen* screen = [[NSScreen screens] objectAtIndex:0];
     21   gfx::Rect screen_bounds = gfx::Rect(NSRectToCGRect([screen frame]));
     22 
     23 
     24   // Get the view bounds relative to the screen
     25   NSRect frame = [view convertRect:[view bounds] toView:nil];
     26   frame.origin = [window convertBaseToScreen:frame.origin];
     27 
     28   gfx::Rect view_bounds = gfx::Rect(NSRectToCGRect(frame));
     29 
     30   // Flip window coordinates based on the primary screen.
     31   view_bounds.set_y(
     32       screen_bounds.height() - view_bounds.y() - view_bounds.height());
     33 
     34   // Convert snapshot bounds relative to window into bounds relative to
     35   // screen.
     36   gfx::Rect screen_snapshot_bounds = snapshot_bounds;
     37   screen_snapshot_bounds.Offset(view_bounds.OffsetFromOrigin());
     38 
     39   DCHECK_LE(screen_snapshot_bounds.right(), view_bounds.right());
     40   DCHECK_LE(screen_snapshot_bounds.bottom(), view_bounds.bottom());
     41 
     42   png_representation->clear();
     43 
     44   base::ScopedCFTypeRef<CGImageRef> windowSnapshot(
     45       CGWindowListCreateImage(screen_snapshot_bounds.ToCGRect(),
     46                               kCGWindowListOptionIncludingWindow,
     47                               [window windowNumber],
     48                               kCGWindowImageBoundsIgnoreFraming));
     49   if (CGImageGetWidth(windowSnapshot) <= 0)
     50     return false;
     51 
     52   base::scoped_nsobject<NSBitmapImageRep> rep(
     53       [[NSBitmapImageRep alloc] initWithCGImage:windowSnapshot]);
     54   NSData* data = [rep representationUsingType:NSPNGFileType properties:nil];
     55   const unsigned char* buf = static_cast<const unsigned char*>([data bytes]);
     56   NSUInteger length = [data length];
     57   if (buf == NULL || length == 0)
     58     return false;
     59 
     60   png_representation->assign(buf, buf + length);
     61   DCHECK(!png_representation->empty());
     62 
     63   return true;
     64 }
     65 
     66 bool GrabWindowSnapshot(gfx::NativeWindow window,
     67                         std::vector<unsigned char>* png_representation,
     68                         const gfx::Rect& snapshot_bounds) {
     69   // Make sure to grab the "window frame" view so we get current tab +
     70   // tabstrip.
     71   return GrabViewSnapshot([[window contentView] superview], png_representation,
     72       snapshot_bounds);
     73 }
     74 
     75 }  // namespace ui
     76