Changeset 76470 in webkit
- Timestamp:
- Jan 23, 2011 2:28:01 PM (13 years ago)
- Location:
- trunk/Source/WebKit2
- Files:
-
- 2 added
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebKit2/ChangeLog
r76453 r76470 1 2011-01-23 Alexey Proskuryakov <ap@apple.com> 2 3 Reviewed by Dan Bernstein. 4 5 https://bugs.webkit.org/show_bug.cgi?id=52968 6 Use a separate NSView for printing 7 8 Also addresses <rdar://problem/8900148> Improper check for 9 -[NSGraphicsContext currentContextDrawingToScreen] 10 11 * UIProcess/API/mac/WKPrintingView.h: Added. 12 * UIProcess/API/mac/WKPrintingView.mm: Added. 13 (-[WKPrintingView initWithFrameProxy:]): 14 (-[WKPrintingView isFlipped]): 15 (-[WKPrintingView _adjustPrintingMarginsForHeaderAndFooter]): 16 (-[WKPrintingView knowsPageRange:]): 17 (-[WKPrintingView _recursiveDisplayRectIfNeededIgnoringOpacity:isVisibleRect:rectIsVisibleRectForView:topView:]): 18 (-[WKPrintingView drawPageBorderWithSize:]): 19 (-[WKPrintingView _provideTotalScaleFactorForPrintOperation:]): 20 (-[WKPrintingView rectForPage:]): 21 * UIProcess/API/mac/WKView.mm: 22 (-[WKView drawRect:]): 23 (-[WKView canChangeFrameLayout:]): 24 (-[WKView printOperationWithPrintInfo:forFrame:]): 25 * WebKit2.xcodeproj/project.pbxproj: 26 Moved printing code to a separate view, simplifying as appropriate. The view is currently not 27 referenced by anything in WebKit2 directly, being owned by NSPrintOperation. 28 1 29 2011-01-22 Anders Carlsson <andersca@apple.com> 2 30 -
trunk/Source/WebKit2/UIProcess/API/mac/WKView.mm
r76433 r76470 37 37 #import "PageClientImpl.h" 38 38 #import "PasteboardTypes.h" 39 #import "PrintInfo.h"40 39 #import "Region.h" 41 40 #import "RunLoop.h" … … 43 42 #import "TextCheckerState.h" 44 43 #import "WKAPICast.h" 44 #import "WKPrintingView.h" 45 45 #import "WKStringCF.h" 46 46 #import "WKTextInputWindowController.h" … … 72 72 @end 73 73 74 @interface NSView (Details)75 - (void)_recursiveDisplayRectIfNeededIgnoringOpacity:(NSRect)rect isVisibleRect:(BOOL)isVisibleRect rectIsVisibleRectForView:(NSView *)visibleView topView:(BOOL)topView;76 @end77 78 74 @interface NSWindow (Details) 79 75 - (NSRect)_growBoxRect; … … 97 93 98 94 } 99 100 NSString* const WebKitOriginalTopPrintingMarginKey = @"WebKitOriginalTopMargin";101 NSString* const WebKitOriginalBottomPrintingMarginKey = @"WebKitOriginalBottomMargin";102 95 103 96 @interface WKViewData : NSObject { … … 136 129 unsigned _selectionEnd; 137 130 138 Vector<IntRect> _printingPageRects;139 double _totalScaleFactorForPrinting;140 141 131 bool _inBecomeFirstResponder; 142 132 bool _inResignFirstResponder; … … 149 139 @implementation WKViewData 150 140 @end 151 152 @interface WebFrameWrapper : NSObject {153 @public154 RefPtr<WebFrameProxy> _frame;155 }156 157 - (id)initWithFrameProxy:(WebFrameProxy*)frame;158 - (WebFrameProxy*)webFrame;159 @end160 161 @implementation WebFrameWrapper162 163 - (id)initWithFrameProxy:(WebFrameProxy*)frame164 {165 self = [super init];166 if (!self)167 return nil;168 169 _frame = frame;170 return self;171 }172 173 - (WebFrameProxy*)webFrame174 {175 return _frame.get();176 }177 178 @end179 180 NSString * const PrintedFrameKey = @"WebKitPrintedFrameKey";181 141 182 142 @interface NSObject (NSTextInputContextDetails) … … 1268 1228 { 1269 1229 LOG(View, "drawRect: x:%g, y:%g, width:%g, height:%g", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); 1230 _data->_page->endPrinting(); 1270 1231 if (useNewDrawingArea()) { 1271 1232 if (DrawingAreaProxyImpl* drawingArea = static_cast<DrawingAreaProxyImpl*>(_data->_page->drawingArea())) { … … 1366 1327 } 1367 1328 1368 static void setFrameBeingPrinted(NSPrintOperation *printOperation, WebFrameProxy* frame) 1369 { 1370 RetainPtr<WebFrameWrapper> frameWrapper(AdoptNS, [[WebFrameWrapper alloc] initWithFrameProxy:frame]); 1371 [[[printOperation printInfo] dictionary] setObject:frameWrapper.get() forKey:PrintedFrameKey]; 1372 } 1373 1374 static WebFrameProxy* frameBeingPrinted() 1375 { 1376 return [[[[[NSPrintOperation currentOperation] printInfo] dictionary] objectForKey:PrintedFrameKey] webFrame]; 1377 } 1378 1379 static float currentPrintOperationScale() 1380 { 1381 ASSERT([NSPrintOperation currentOperation]); 1382 ASSERT([[[[NSPrintOperation currentOperation] printInfo] dictionary] objectForKey:NSPrintScalingFactor]); 1383 return [[[[[NSPrintOperation currentOperation] printInfo] dictionary] objectForKey:NSPrintScalingFactor] floatValue]; 1384 } 1385 1386 - (void)_adjustPrintingMarginsForHeaderAndFooter 1387 { 1388 NSPrintOperation *printOperation = [NSPrintOperation currentOperation]; 1389 NSPrintInfo *info = [printOperation printInfo]; 1390 NSMutableDictionary *infoDictionary = [info dictionary]; 1391 1392 // We need to modify the top and bottom margins in the NSPrintInfo to account for the space needed by the 1393 // header and footer. Because this method can be called more than once on the same NSPrintInfo (see 5038087), 1394 // we stash away the unmodified top and bottom margins the first time this method is called, and we read from 1395 // those stashed-away values on subsequent calls. 1396 float originalTopMargin; 1397 float originalBottomMargin; 1398 NSNumber *originalTopMarginNumber = [infoDictionary objectForKey:WebKitOriginalTopPrintingMarginKey]; 1399 if (!originalTopMarginNumber) { 1400 ASSERT(![infoDictionary objectForKey:WebKitOriginalBottomPrintingMarginKey]); 1401 originalTopMargin = [info topMargin]; 1402 originalBottomMargin = [info bottomMargin]; 1403 [infoDictionary setObject:[NSNumber numberWithFloat:originalTopMargin] forKey:WebKitOriginalTopPrintingMarginKey]; 1404 [infoDictionary setObject:[NSNumber numberWithFloat:originalBottomMargin] forKey:WebKitOriginalBottomPrintingMarginKey]; 1405 } else { 1406 ASSERT([originalTopMarginNumber isKindOfClass:[NSNumber class]]); 1407 ASSERT([[infoDictionary objectForKey:WebKitOriginalBottomPrintingMarginKey] isKindOfClass:[NSNumber class]]); 1408 originalTopMargin = [originalTopMarginNumber floatValue]; 1409 originalBottomMargin = [[infoDictionary objectForKey:WebKitOriginalBottomPrintingMarginKey] floatValue]; 1410 } 1411 1412 float scale = currentPrintOperationScale(); 1413 [info setTopMargin:originalTopMargin + _data->_page->headerHeight(frameBeingPrinted()) * scale]; 1414 [info setBottomMargin:originalBottomMargin + _data->_page->footerHeight(frameBeingPrinted()) * scale]; 1329 1330 - (BOOL)canChangeFrameLayout:(WKFrameRef)frameRef 1331 { 1332 // PDF documents are already paginated, so we can't change them to add headers and footers. 1333 return !toImpl(frameRef)->isMainFrame() || !_data->_pdfViewController; 1415 1334 } 1416 1335 … … 1418 1337 { 1419 1338 LOG(View, "Creating an NSPrintOperation for frame '%s'", toImpl(frameRef)->url().utf8().data()); 1420 NSPrintOperation *printOperation;1421 1339 1422 1340 // Only the top frame can currently contain a PDF view. 1423 1341 if (_data->_pdfViewController) { 1424 ASSERT(toImpl(frameRef)->isMainFrame()); 1425 printOperation = _data->_pdfViewController->makePrintOperation(printInfo); 1426 } else 1427 printOperation = [NSPrintOperation printOperationWithView:self printInfo:printInfo]; 1428 1429 setFrameBeingPrinted(printOperation, toImpl(frameRef)); 1430 return printOperation; 1431 } 1432 1433 - (BOOL)canChangeFrameLayout:(WKFrameRef)frameRef 1434 { 1435 // PDF documents are already paginated, so we can't change them to add headers and footers. 1436 return !toImpl(frameRef)->isMainFrame() || !_data->_pdfViewController; 1437 } 1438 1439 // Return the number of pages available for printing 1440 - (BOOL)knowsPageRange:(NSRangePointer)range 1441 { 1442 LOG(View, "knowsPageRange:"); 1443 WebFrameProxy* frame = frameBeingPrinted(); 1444 ASSERT(frame); 1445 1446 if (frame->isMainFrame() && _data->_pdfViewController) 1447 return [super knowsPageRange:range]; 1448 1449 [self _adjustPrintingMarginsForHeaderAndFooter]; 1450 1451 _data->_page->computePagesForPrinting(frame, PrintInfo([[NSPrintOperation currentOperation] printInfo]), _data->_printingPageRects, _data->_totalScaleFactorForPrinting); 1452 1453 *range = NSMakeRange(1, _data->_printingPageRects.size()); 1454 return YES; 1455 } 1456 1457 // Take over printing. AppKit applies incorrect clipping, and doesn't print pages beyond the first one. 1458 - (void)_recursiveDisplayRectIfNeededIgnoringOpacity:(NSRect)rect isVisibleRect:(BOOL)isVisibleRect rectIsVisibleRectForView:(NSView *)visibleView topView:(BOOL)topView 1459 { 1460 // FIXME: This check isn't right for some non-printing cases, such as capturing into a buffer using cacheDisplayInRect:toBitmapImageRep:. 1461 if ([NSGraphicsContext currentContextDrawingToScreen]) { 1462 _data->_page->endPrinting(); 1463 [super _recursiveDisplayRectIfNeededIgnoringOpacity:rect isVisibleRect:isVisibleRect rectIsVisibleRectForView:visibleView topView:topView]; 1464 return; 1465 } 1466 1467 LOG(View, "Printing rect x:%g, y:%g, width:%g, height:%g", rect.origin.x, rect.origin.y, rect.size.width, rect.size.height); 1468 1469 ASSERT(self == visibleView); 1470 ASSERT(frameBeingPrinted()); 1471 1472 WebFrameProxy* frame = frameBeingPrinted(); 1473 ASSERT(frame); 1474 1475 _data->_page->beginPrinting(frame, PrintInfo([[NSPrintOperation currentOperation] printInfo])); 1476 1477 // FIXME: This is optimized for print preview. Get the whole document at once when actually printing. 1478 Vector<uint8_t> pdfData; 1479 _data->_page->drawRectToPDF(frame, IntRect(rect), pdfData); 1480 1481 RetainPtr<CGDataProviderRef> pdfDataProvider(AdoptCF, CGDataProviderCreateWithData(0, pdfData.data(), pdfData.size(), 0)); 1482 RetainPtr<CGPDFDocumentRef> pdfDocument(AdoptCF, CGPDFDocumentCreateWithProvider(pdfDataProvider.get())); 1483 if (!pdfDocument) { 1484 LOG_ERROR("Couldn't create a PDF document with data passed for printing"); 1485 return; 1486 } 1487 1488 CGPDFPageRef pdfPage = CGPDFDocumentGetPage(pdfDocument.get(), 1); 1489 if (!pdfPage) { 1490 LOG_ERROR("Printing data doesn't have page 1"); 1491 return; 1492 } 1493 1494 NSGraphicsContext *nsGraphicsContext = [NSGraphicsContext currentContext]; 1495 CGContextRef context = static_cast<CGContextRef>([nsGraphicsContext graphicsPort]); 1496 1497 CGContextSaveGState(context); 1498 // Flip the destination. 1499 CGContextScaleCTM(context, 1, -1); 1500 CGContextTranslateCTM(context, 0, -CGPDFPageGetBoxRect(pdfPage, kCGPDFMediaBox).size.height); 1501 CGContextDrawPDFPage(context, pdfPage); 1502 CGContextRestoreGState(context); 1503 } 1504 1505 - (void)drawPageBorderWithSize:(NSSize)borderSize 1506 { 1507 ASSERT(NSEqualSizes(borderSize, [[[NSPrintOperation currentOperation] printInfo] paperSize])); 1508 1509 // The header and footer rect height scales with the page, but the width is always 1510 // all the way across the printed page (inset by printing margins). 1511 NSPrintOperation *printOperation = [NSPrintOperation currentOperation]; 1512 NSPrintInfo *printInfo = [printOperation printInfo]; 1513 float scale = currentPrintOperationScale(); 1514 NSSize paperSize = [printInfo paperSize]; 1515 float headerFooterLeft = [printInfo leftMargin] / scale; 1516 float headerFooterWidth = (paperSize.width - ([printInfo leftMargin] + [printInfo rightMargin])) / scale; 1517 WebFrameProxy* frame = frameBeingPrinted(); 1518 NSRect footerRect = NSMakeRect(headerFooterLeft, [printInfo bottomMargin] / scale - _data->_page->footerHeight(frame), headerFooterWidth, _data->_page->footerHeight(frame)); 1519 NSRect headerRect = NSMakeRect(headerFooterLeft, (paperSize.height - [printInfo topMargin]) / scale, headerFooterWidth, _data->_page->headerHeight(frame)); 1520 1521 NSGraphicsContext *currentContext = [NSGraphicsContext currentContext]; 1522 [currentContext saveGraphicsState]; 1523 NSRectClip(headerRect); 1524 _data->_page->drawHeader(frame, headerRect); 1525 [currentContext restoreGraphicsState]; 1526 1527 [currentContext saveGraphicsState]; 1528 NSRectClip(footerRect); 1529 _data->_page->drawFooter(frame, footerRect); 1530 [currentContext restoreGraphicsState]; 1531 } 1532 1533 // FIXME 3491344: This is an AppKit-internal method that we need to override in order 1534 // to get our shrink-to-fit to work with a custom pagination scheme. We can do this better 1535 // if AppKit makes it SPI/API. 1536 - (CGFloat)_provideTotalScaleFactorForPrintOperation:(NSPrintOperation *)printOperation 1537 { 1538 return _data->_totalScaleFactorForPrinting; 1539 } 1540 1541 // Return the drawing rectangle for a particular page number 1542 - (NSRect)rectForPage:(NSInteger)page 1543 { 1544 WebFrameProxy* frame = frameBeingPrinted(); 1545 ASSERT(frame); 1546 1547 if (frame->isMainFrame() && _data->_pdfViewController) 1548 return [super rectForPage:page]; 1549 1550 LOG(View, "rectForPage:%d -> x %d, y %d, width %d, height %d\n", (int)page, _data->_printingPageRects[page - 1].x(), _data->_printingPageRects[page - 1].y(), _data->_printingPageRects[page - 1].width(), _data->_printingPageRects[page - 1].height()); 1551 return _data->_printingPageRects[page - 1]; 1342 if (!toImpl(frameRef)->isMainFrame()) 1343 return 0; 1344 return _data->_pdfViewController->makePrintOperation(printInfo); 1345 } else { 1346 RetainPtr<WKPrintingView> printingView(AdoptNS, [[WKPrintingView alloc] initWithFrameProxy:toImpl(frameRef)]); 1347 // NSPrintOperation takes ownership of the view. 1348 return [NSPrintOperation printOperationWithView:printingView.get()]; 1349 } 1552 1350 } 1553 1351 -
trunk/Source/WebKit2/WebKit2.xcodeproj/project.pbxproj
r76186 r76470 669 669 D3B9484811FF4B6500032B39 /* WebSearchPopupMenu.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D3B9484411FF4B6500032B39 /* WebSearchPopupMenu.cpp */; }; 670 670 D3B9484911FF4B6500032B39 /* WebSearchPopupMenu.h in Headers */ = {isa = PBXBuildFile; fileRef = D3B9484511FF4B6500032B39 /* WebSearchPopupMenu.h */; }; 671 E134F01712EA5D33004EC58D /* WKPrintingView.h in Headers */ = {isa = PBXBuildFile; fileRef = E134F01512EA5D11004EC58D /* WKPrintingView.h */; }; 672 E134F01A12EA5D99004EC58D /* WKPrintingView.mm in Sources */ = {isa = PBXBuildFile; fileRef = E134F01912EA5D99004EC58D /* WKPrintingView.mm */; }; 671 673 E18C92F412DB9E7100CF2AEB /* PrintInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E18C92F312DB9E7100CF2AEB /* PrintInfo.cpp */; }; 672 674 E18C92F512DB9E7A00CF2AEB /* PrintInfo.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E18C92F312DB9E7100CF2AEB /* PrintInfo.cpp */; }; … … 1432 1434 D3B9484411FF4B6500032B39 /* WebSearchPopupMenu.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WebSearchPopupMenu.cpp; sourceTree = "<group>"; }; 1433 1435 D3B9484511FF4B6500032B39 /* WebSearchPopupMenu.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WebSearchPopupMenu.h; sourceTree = "<group>"; }; 1436 E134F01512EA5D11004EC58D /* WKPrintingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WKPrintingView.h; sourceTree = "<group>"; }; 1437 E134F01912EA5D99004EC58D /* WKPrintingView.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = WKPrintingView.mm; sourceTree = "<group>"; }; 1434 1438 E18C92F312DB9E7100CF2AEB /* PrintInfo.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PrintInfo.cpp; sourceTree = "<group>"; }; 1435 1439 E1CC1B8E12D7EADF00625838 /* PrintInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrintInfo.h; sourceTree = "<group>"; }; … … 2318 2322 BC111B4B112F619200337BAB /* PageClientImpl.h */, 2319 2323 BC111B4C112F619200337BAB /* PageClientImpl.mm */, 2324 E134F01512EA5D11004EC58D /* WKPrintingView.h */, 2325 E134F01912EA5D99004EC58D /* WKPrintingView.mm */, 2320 2326 1A4A9AA612B7E796008FE984 /* WKTextInputWindowController.h */, 2321 2327 1A4A9AA712B7E796008FE984 /* WKTextInputWindowController.mm */, … … 3070 3076 1AA2E51D12E4C05E00BC4966 /* CGUtilities.h in Headers */, 3071 3077 C574A58112E66681002DFE98 /* PasteboardTypes.h in Headers */, 3078 E134F01712EA5D33004EC58D /* WKPrintingView.h in Headers */, 3072 3079 ); 3073 3080 runOnlyForDeploymentPostprocessing = 0; … … 3533 3540 C574A37712E6099D002DFE98 /* WebDragClientMac.mm in Sources */, 3534 3541 C574A58212E66681002DFE98 /* PasteboardTypes.mm in Sources */, 3542 E134F01A12EA5D99004EC58D /* WKPrintingView.mm in Sources */, 3535 3543 ); 3536 3544 runOnlyForDeploymentPostprocessing = 0;
Note: See TracChangeset
for help on using the changeset viewer.