зеркало из https://github.com/mozilla/pjs.git
Camino only - Bug 395033: Use Gecko-based thumbnailing to prevent Tabspose chrashes with plugins. r=josh sr=pink
This commit is contained in:
Родитель
fe46f9182c
Коммит
df1f89a8c9
|
@ -60,7 +60,6 @@ CGColorSpaceRef getTheGreyColorSpace(void);
|
|||
- (void)updateGridSizeFor:(int)num;
|
||||
- (void)layoutThumbnails;
|
||||
- (void)createThumbnailViews;
|
||||
- (NSImage*)imageWithScreenShotInTabViewItem:(BrowserTabViewItem*)tabViewItem;
|
||||
@end
|
||||
|
||||
@implementation TabThumbnailGridView
|
||||
|
@ -104,7 +103,9 @@ CGColorSpaceRef getTheGreyColorSpace(void);
|
|||
BrowserTabViewItem* tabViewItem;
|
||||
|
||||
while ((tabViewItem = [tabEnum nextObject])) {
|
||||
NSImage* thumb = [self imageWithScreenShotInTabViewItem:tabViewItem];
|
||||
NSImage* thumb = [[[tabViewItem view] getBrowserView] snapshot];
|
||||
if (!thumb)
|
||||
continue;
|
||||
ThumbnailView* curThumbView = [[[ThumbnailView alloc] init] autorelease];
|
||||
|
||||
if (curThumbView) {
|
||||
|
@ -195,47 +196,6 @@ CGColorSpaceRef getTheGreyColorSpace(void);
|
|||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Draws the given view on a window placed offscreen and takes a screenshot
|
||||
//
|
||||
- (NSImage*)imageWithScreenShotInTabViewItem:(BrowserTabViewItem*)tabViewItem
|
||||
{
|
||||
BrowserWrapper* browserWrapper = [[[tabViewItem view] retain] autorelease];
|
||||
NSRect bounds = [browserWrapper bounds];
|
||||
NSSize windowSize = bounds.size;
|
||||
|
||||
NSRect offscreenRect = NSMakeRect(0, 0, windowSize.width, windowSize.height);
|
||||
|
||||
NSWindow* offscreenWindow = [[NSWindow alloc] initWithContentRect:offscreenRect
|
||||
styleMask:NSBorderlessWindowMask
|
||||
backing:NSBackingStoreRetained
|
||||
defer:NO];
|
||||
|
||||
NSView* placeholderView = [[[NSView alloc] initWithFrame:[browserWrapper frame]] autorelease];
|
||||
[tabViewItem setView:placeholderView];
|
||||
|
||||
[offscreenWindow setContentView:browserWrapper];
|
||||
[[offscreenWindow contentView] display];
|
||||
|
||||
// Create the NSBitmapImageRep
|
||||
[[offscreenWindow contentView] lockFocus];
|
||||
NSBitmapImageRep* rep = [[NSBitmapImageRep alloc] initWithFocusedViewRect:offscreenRect];
|
||||
|
||||
// Puts the tab's view back where it came from
|
||||
[tabViewItem setView:browserWrapper];
|
||||
|
||||
// Clean up and delete the window, which is no longer needed.
|
||||
[[offscreenWindow contentView] unlockFocus];
|
||||
[offscreenWindow release];
|
||||
|
||||
// Create an image with the representation
|
||||
NSImage* image = [[[NSImage alloc] initWithSize:[rep size]] autorelease];
|
||||
[image addRepresentation:rep];
|
||||
[rep release];
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
#pragma mark Core Graphics
|
||||
|
||||
//
|
||||
|
|
|
@ -284,6 +284,9 @@ typedef enum {
|
|||
|
||||
- (NSString*)getFocusedURLString;
|
||||
|
||||
// Gets an NSImage representation of the currently visible section of the page.
|
||||
- (NSImage*)snapshot;
|
||||
|
||||
// charset
|
||||
- (IBAction)reloadWithNewCharset:(NSString*)charset;
|
||||
- (NSString*)currentCharset;
|
||||
|
|
|
@ -128,6 +128,11 @@
|
|||
#include "nsICommandManager.h"
|
||||
#include "nsICommandParams.h"
|
||||
|
||||
// Thumbnailing
|
||||
#include "gfxContext.h"
|
||||
#include "gfxImageSurface.h"
|
||||
#include "nsPresContext.h"
|
||||
|
||||
#include "GeckoUtils.h"
|
||||
|
||||
|
||||
|
@ -674,6 +679,97 @@ const char kDirServiceContractID[] = "@mozilla.org/file/directory_service;1";
|
|||
return domElement;
|
||||
}
|
||||
|
||||
- (NSImage*)snapshot
|
||||
{
|
||||
NSSize viewportSize = [self bounds].size;
|
||||
// We don't draw scrollbars, so set the snapshot width to be the smaller of
|
||||
// the view width and the dom width to prevent a blank strip in the snapshot.
|
||||
nsCOMPtr<nsIDOMWindow> domWindow = [self getContentWindow];
|
||||
if (!domWindow)
|
||||
return nil;
|
||||
int pageWidth;
|
||||
int pageHeight;
|
||||
GeckoUtils::GetIntrisicSize(domWindow, &pageWidth, &pageHeight);
|
||||
NSSize snapshotSize = NSMakeSize(MIN(pageWidth, viewportSize.width),
|
||||
viewportSize.height);
|
||||
|
||||
// Create a context to draw into.
|
||||
// TODO: use a quartz-based surface, so that widgets will draw onto it.
|
||||
nsRefPtr<gfxImageSurface> surface = new gfxImageSurface(gfxIntSize(snapshotSize.width,
|
||||
snapshotSize.height),
|
||||
gfxImageSurface::ImageFormatARGB32);
|
||||
if (!surface)
|
||||
return nil;
|
||||
nsRefPtr<gfxContext> context = new gfxContext(surface);
|
||||
if (!context)
|
||||
return nil;
|
||||
|
||||
// Get the page presentation.
|
||||
nsCOMPtr<nsIDocShell> docShell = [self getDocShell];
|
||||
if (!docShell)
|
||||
return nil;
|
||||
nsCOMPtr<nsPresContext> presContext;
|
||||
docShell->GetPresContext(getter_AddRefs(presContext));
|
||||
if (!presContext)
|
||||
return nil;
|
||||
nsIPresShell* presShell = presContext->PresShell();
|
||||
if (!presShell)
|
||||
return nil;
|
||||
|
||||
// Draw the desired section of the page into our context.
|
||||
PRInt32 scrollX, scrollY;
|
||||
domWindow->GetScrollX(&scrollX);
|
||||
domWindow->GetScrollY(&scrollY);
|
||||
PRInt32 appUnitsPerPixel = presContext->AppUnitsPerDevPixel();
|
||||
nsRect viewRect(NSIntPixelsToAppUnits(scrollX, appUnitsPerPixel),
|
||||
NSIntPixelsToAppUnits(scrollY, appUnitsPerPixel),
|
||||
NSIntPixelsToAppUnits(viewportSize.width, appUnitsPerPixel),
|
||||
NSIntPixelsToAppUnits(viewportSize.height, appUnitsPerPixel));
|
||||
presShell->RenderDocument(viewRect, PR_FALSE, PR_TRUE, NS_RGB(255, 255, 255), context);
|
||||
|
||||
// The data is ARGB, in host endianness, which doesn't convert nicely to an
|
||||
// NSImage, so pass it through CGImage to extract the data.
|
||||
size_t bitsPerComponent = 8;
|
||||
size_t componentsPerPixel = 4;
|
||||
size_t imageBytes = componentsPerPixel * snapshotSize.width * snapshotSize.height;
|
||||
CGDataProviderRef dataProvider = CGDataProviderCreateWithData(NULL,
|
||||
surface->Data(),
|
||||
imageBytes,
|
||||
NULL);
|
||||
if (!dataProvider)
|
||||
return nil;
|
||||
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
|
||||
if (!colorSpace) {
|
||||
CGDataProviderRelease(dataProvider);
|
||||
return nil;
|
||||
}
|
||||
CGImageRef cgImage = CGImageCreate(snapshotSize.width, snapshotSize.height,
|
||||
bitsPerComponent,
|
||||
bitsPerComponent * componentsPerPixel,
|
||||
surface->Stride(),
|
||||
colorSpace,
|
||||
kCGImageAlphaFirst | kCGBitmapByteOrder32Host,
|
||||
dataProvider,
|
||||
NULL, // no decode
|
||||
true, // enable interpolation
|
||||
kCGRenderingIntentDefault);
|
||||
CGDataProviderRelease(dataProvider);
|
||||
CGColorSpaceRelease(colorSpace);
|
||||
if (!cgImage)
|
||||
return nil;
|
||||
|
||||
// Finally, get it into an NSImage.
|
||||
NSImage* snapshot = [[[NSImage alloc] initWithSize:snapshotSize] autorelease];
|
||||
NSRect imageRect = NSMakeRect(0, 0, snapshotSize.width, snapshotSize.height);
|
||||
[snapshot lockFocus];
|
||||
CGContextDrawImage((CGContextRef)[[NSGraphicsContext currentContext] graphicsPort],
|
||||
*(CGRect*)&imageRect, cgImage);
|
||||
[snapshot unlockFocus];
|
||||
CGImageRelease(cgImage);
|
||||
|
||||
return snapshot;
|
||||
}
|
||||
|
||||
-(void) saveInternal: (nsIURI*)aURI
|
||||
withDocument: (nsIDOMDocument*)aDocument
|
||||
suggestedFilename: (NSString*)aFileName
|
||||
|
|
Загрузка…
Ссылка в новой задаче