summaryrefslogtreecommitdiffstats
path: root/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebKit2/WebProcess/WebPage/WebPage.cpp')
-rw-r--r--Source/WebKit2/WebProcess/WebPage/WebPage.cpp321
1 files changed, 274 insertions, 47 deletions
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
index af236e9..462d352 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
@@ -23,6 +23,7 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
+#include "config.h"
#include "WebPage.h"
#include "Arguments.h"
@@ -254,6 +255,16 @@ void WebPage::initializeInjectedBundleLoaderClient(WKBundlePageLoaderClient* cli
m_loaderClient.initialize(client);
}
+void WebPage::initializeInjectedBundlePolicyClient(WKBundlePagePolicyClient* client)
+{
+ m_policyClient.initialize(client);
+}
+
+void WebPage::initializeInjectedBundleResourceLoadClient(WKBundlePageResourceLoadClient* client)
+{
+ m_resourceLoadClient.initialize(client);
+}
+
void WebPage::initializeInjectedBundleUIClient(WKBundlePageUIClient* client)
{
m_uiClient.initialize(client);
@@ -313,6 +324,11 @@ void WebPage::changeAcceleratedCompositingMode(WebCore::GraphicsLayer* layer)
if (m_isClosed)
return;
+ // With the new drawing area we don't need to inform the UI process when the accelerated
+ // compositing mode changes.
+ if (m_drawingArea->info().type == DrawingAreaInfo::Impl)
+ return;
+
bool compositing = layer;
// Tell the UI process that accelerated compositing changed. It may respond by changing
@@ -342,6 +358,7 @@ void WebPage::enterAcceleratedCompositingMode(GraphicsLayer* layer)
void WebPage::exitAcceleratedCompositingMode()
{
changeAcceleratedCompositingMode(0);
+ m_drawingArea->setRootCompositingLayer(0);
}
#endif
@@ -463,20 +480,26 @@ void WebPage::reload(bool reloadFromOrigin)
m_mainFrame->coreFrame()->loader()->reload(reloadFromOrigin);
}
-void WebPage::goForward(uint64_t backForwardItemID)
+void WebPage::goForward(uint64_t backForwardItemID, const SandboxExtension::Handle& sandboxExtensionHandle)
{
+ m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
+
HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
m_page->goToItem(item, FrameLoadTypeForward);
}
-void WebPage::goBack(uint64_t backForwardItemID)
+void WebPage::goBack(uint64_t backForwardItemID, const SandboxExtension::Handle& sandboxExtensionHandle)
{
+ m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
+
HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
m_page->goToItem(item, FrameLoadTypeBack);
}
-void WebPage::goToBackForwardItem(uint64_t backForwardItemID)
+void WebPage::goToBackForwardItem(uint64_t backForwardItemID, const SandboxExtension::Handle& sandboxExtensionHandle)
{
+ m_sandboxExtensionTracker.beginLoad(m_mainFrame.get(), sandboxExtensionHandle);
+
HistoryItem* item = WebBackForwardListProxy::itemForID(backForwardItemID);
m_page->goToItem(item, FrameLoadTypeIndexedBackForward);
}
@@ -553,6 +576,27 @@ void WebPage::resizeToContentsIfNeeded()
}
#endif
+void WebPage::scrollMainFrameIfNotAtMaxScrollPosition(const IntSize& scrollOffset)
+{
+ Frame* frame = m_page->mainFrame();
+
+ IntPoint scrollPosition = frame->view()->scrollPosition();
+ IntPoint maximumScrollPosition = frame->view()->maximumScrollPosition();
+
+ // If the current scroll position in a direction is the max scroll position
+ // we don't want to scroll at all.
+ IntSize newScrollOffset;
+ if (scrollPosition.x() < maximumScrollPosition.x())
+ newScrollOffset.setWidth(scrollOffset.width());
+ if (scrollPosition.y() < maximumScrollPosition.y())
+ newScrollOffset.setHeight(scrollOffset.height());
+
+ if (newScrollOffset.isZero())
+ return;
+
+ frame->view()->setScrollPosition(frame->view()->scrollPosition() + newScrollOffset);
+}
+
void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect)
{
graphicsContext.save();
@@ -560,12 +604,19 @@ void WebPage::drawRect(GraphicsContext& graphicsContext, const IntRect& rect)
m_mainFrame->coreFrame()->view()->paint(&graphicsContext, rect);
graphicsContext.restore();
- if (m_pageOverlay) {
- graphicsContext.save();
- graphicsContext.clip(rect);
- m_pageOverlay->drawRect(graphicsContext, rect);
- graphicsContext.restore();
- }
+ // FIXME: Remove this code once we're using the new drawing area on mac and windows.
+ if (m_pageOverlay && m_drawingArea->info().type != DrawingAreaInfo::Impl)
+ drawPageOverlay(graphicsContext, rect);
+}
+
+void WebPage::drawPageOverlay(GraphicsContext& graphicsContext, const IntRect& rect)
+{
+ ASSERT(m_pageOverlay);
+
+ graphicsContext.save();
+ graphicsContext.clip(rect);
+ m_pageOverlay->drawRect(graphicsContext, rect);
+ graphicsContext.restore();
}
double WebPage::textZoomFactor() const
@@ -614,6 +665,8 @@ void WebPage::scaleWebView(double scale, const IntPoint& origin)
if (!frame)
return;
frame->scalePage(scale, origin);
+
+ send(Messages::WebPageProxy::ViewScaleFactorDidChange(scale));
}
double WebPage::viewScaleFactor() const
@@ -660,6 +713,9 @@ void WebPage::installPageOverlay(PassRefPtr<PageOverlay> pageOverlay)
m_pageOverlay = pageOverlay;
m_pageOverlay->setPage(this);
+
+ m_drawingArea->didInstallPageOverlay();
+
m_pageOverlay->setNeedsDisplay();
}
@@ -670,7 +726,8 @@ void WebPage::uninstallPageOverlay(PageOverlay* pageOverlay)
m_pageOverlay->setPage(0);
m_pageOverlay = nullptr;
- m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize));
+
+ m_drawingArea->didUninstallPageOverlay();
}
PassRefPtr<WebImage> WebPage::snapshotInViewCoordinates(const IntRect& rect, ImageOptions options)
@@ -697,7 +754,7 @@ PassRefPtr<WebImage> WebPage::snapshotInViewCoordinates(const IntRect& rect, Ima
return snapshot.release();
}
-PassRefPtr<WebImage> WebPage::snapshotInDocumentCoordinates(const IntRect& rect, ImageOptions options)
+PassRefPtr<WebImage> WebPage::scaledSnapshotInDocumentCoordinates(const IntRect& rect, double scaleFactor, ImageOptions options)
{
FrameView* frameView = m_mainFrame->coreFrame()->view();
if (!frameView)
@@ -708,10 +765,18 @@ PassRefPtr<WebImage> WebPage::snapshotInDocumentCoordinates(const IntRect& rect,
PaintBehavior oldBehavior = frameView->paintBehavior();
frameView->setPaintBehavior(oldBehavior | PaintBehaviorFlattenCompositingLayers);
- RefPtr<WebImage> snapshot = WebImage::create(rect.size(), options);
- OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext();
+ bool scale = scaleFactor != 1;
+ IntSize size = rect.size();
+ if (scale)
+ size = IntSize(ceil(rect.width() * scaleFactor), ceil(rect.height() * scaleFactor));
+ RefPtr<WebImage> snapshot = WebImage::create(size, options);
+ OwnPtr<WebCore::GraphicsContext> graphicsContext = snapshot->bitmap()->createGraphicsContext();
graphicsContext->save();
+
+ if (scale)
+ graphicsContext->scale(FloatSize(scaleFactor, scaleFactor));
+
graphicsContext->translate(-rect.x(), -rect.y());
frameView->paintContents(graphicsContext.get(), rect);
graphicsContext->restore();
@@ -721,6 +786,11 @@ PassRefPtr<WebImage> WebPage::snapshotInDocumentCoordinates(const IntRect& rect,
return snapshot.release();
}
+PassRefPtr<WebImage> WebPage::snapshotInDocumentCoordinates(const IntRect& rect, ImageOptions options)
+{
+ return scaledSnapshotInDocumentCoordinates(rect, 1, options);
+}
+
void WebPage::pageDidScroll()
{
// Hide the find indicator.
@@ -909,6 +979,26 @@ void WebPage::keyEvent(const WebKeyboardEvent& keyboardEvent)
send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(keyboardEvent.type()), handled));
}
+#if ENABLE(GESTURE_EVENTS)
+static bool handleGestureEvent(const WebGestureEvent& gestureEvent, Page* page)
+{
+ Frame* frame = page->mainFrame();
+ if (!frame->view())
+ return false;
+
+ PlatformGestureEvent platformGestureEvent = platform(gestureEvent);
+ return frame->eventHandler()->handleGestureEvent(platformGestureEvent);
+}
+
+void WebPage::gestureEvent(const WebGestureEvent& gestureEvent)
+{
+ CurrentEvent currentEvent(gestureEvent);
+
+ bool handled = handleGestureEvent(gestureEvent, m_page.get());
+ send(Messages::WebPageProxy::DidReceiveEvent(static_cast<uint32_t>(gestureEvent.type()), handled));
+}
+#endif
+
void WebPage::validateMenuItem(const String& commandName)
{
bool isEnabled = false;
@@ -952,10 +1042,10 @@ uint64_t WebPage::restoreSession(const SessionState& sessionState)
return currentItemID;
}
-void WebPage::restoreSessionAndNavigateToCurrentItem(const SessionState& sessionState)
+void WebPage::restoreSessionAndNavigateToCurrentItem(const SessionState& sessionState, const SandboxExtension::Handle& sandboxExtensionHandle)
{
if (uint64_t currentItemID = restoreSession(sessionState))
- goToBackForwardItem(currentItemID);
+ goToBackForwardItem(currentItemID, sandboxExtensionHandle);
}
#if ENABLE(TOUCH_EVENTS)
@@ -1022,6 +1112,30 @@ void WebPage::setDrawsTransparentBackground(bool drawsTransparentBackground)
m_drawingArea->setNeedsDisplay(IntRect(IntPoint(0, 0), m_viewSize));
}
+void WebPage::viewWillStartLiveResize()
+{
+ if (!m_page)
+ return;
+
+ // FIXME: This should propagate to all ScrollableAreas.
+ if (Frame* frame = m_page->focusController()->focusedOrMainFrame()) {
+ if (FrameView* view = frame->view())
+ view->willStartLiveResize();
+ }
+}
+
+void WebPage::viewWillEndLiveResize()
+{
+ if (!m_page)
+ return;
+
+ // FIXME: This should propagate to all ScrollableAreas.
+ if (Frame* frame = m_page->focusController()->focusedOrMainFrame()) {
+ if (FrameView* view = frame->view())
+ view->willEndLiveResize();
+ }
+}
+
void WebPage::setFocused(bool isFocused)
{
m_page->focusController()->setFocused(isFocused);
@@ -1161,7 +1275,7 @@ void WebPage::getResourceDataFromFrame(uint64_t frameID, const String& resourceU
if (WebFrame* frame = WebProcess::shared().webFrame(frameID)) {
if (DocumentLoader* loader = frame->coreFrame()->loader()->documentLoader()) {
if (RefPtr<ArchiveResource> subresource = loader->subresource(KURL(KURL(), resourceURL))) {
- if (buffer = subresource->data())
+ if ((buffer = subresource->data()))
dataReference = CoreIPC::DataReference(reinterpret_cast<const uint8_t*>(buffer->data()), buffer->size());
}
}
@@ -1187,6 +1301,12 @@ void WebPage::getWebArchiveOfFrame(uint64_t frameID, uint64_t callbackID)
send(Messages::WebPageProxy::DataCallback(dataReference, callbackID));
}
+void WebPage::forceRepaint(uint64_t callbackID)
+{
+ m_drawingArea->forceRepaint();
+ send(Messages::WebPageProxy::VoidCallback(callbackID));
+}
+
void WebPage::preferencesDidChange(const WebPreferencesStore& store)
{
WebPreferencesStore::removeTestRunnerOverrides();
@@ -1224,12 +1344,15 @@ void WebPage::updatePreferences(const WebPreferencesStore& store)
settings->setJavaScriptCanOpenWindowsAutomatically(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanOpenWindowsAutomaticallyKey()));
settings->setForceFTPDirectoryListings(store.getBoolValueForKey(WebPreferencesKey::forceFTPDirectoryListingsKey()));
settings->setDNSPrefetchingEnabled(store.getBoolValueForKey(WebPreferencesKey::dnsPrefetchingEnabledKey()));
+#if ENABLE(WEB_ARCHIVE)
settings->setWebArchiveDebugModeEnabled(store.getBoolValueForKey(WebPreferencesKey::webArchiveDebugModeEnabledKey()));
+#endif
settings->setLocalFileContentSniffingEnabled(store.getBoolValueForKey(WebPreferencesKey::localFileContentSniffingEnabledKey()));
settings->setUsesPageCache(store.getBoolValueForKey(WebPreferencesKey::usesPageCacheKey()));
settings->setAuthorAndUserStylesEnabled(store.getBoolValueForKey(WebPreferencesKey::authorAndUserStylesEnabledKey()));
settings->setPaginateDuringLayoutEnabled(store.getBoolValueForKey(WebPreferencesKey::paginateDuringLayoutEnabledKey()));
settings->setDOMPasteAllowed(store.getBoolValueForKey(WebPreferencesKey::domPasteAllowedKey()));
+ settings->setJavaScriptCanAccessClipboard(store.getBoolValueForKey(WebPreferencesKey::javaScriptCanAccessClipboardKey()));
settings->setShouldPrintBackgrounds(store.getBoolValueForKey(WebPreferencesKey::shouldPrintBackgroundsKey()));
settings->setMinimumFontSize(store.getUInt32ValueForKey(WebPreferencesKey::minimumFontSizeKey()));
@@ -1245,6 +1368,7 @@ void WebPage::updatePreferences(const WebPreferencesStore& store)
#endif
settings->setShowDebugBorders(store.getBoolValueForKey(WebPreferencesKey::compositingBordersVisibleKey()));
settings->setShowRepaintCounter(store.getBoolValueForKey(WebPreferencesKey::compositingRepaintCountersVisibleKey()));
+ settings->setWebGLEnabled(store.getBoolValueForKey(WebPreferencesKey::webGLEnabledKey()));
#if ENABLE(DATABASE)
AbstractDatabase::setIsAvailable(store.getBoolValueForKey(WebPreferencesKey::databasesEnabledKey()));
@@ -1259,7 +1383,7 @@ WebInspector* WebPage::inspector()
if (m_isClosed)
return 0;
if (!m_inspector)
- m_inspector = adoptPtr(new WebInspector(this));
+ m_inspector = WebInspector::create(this);
return m_inspector.get();
}
#endif
@@ -1296,6 +1420,37 @@ bool WebPage::handleEditingKeyboardEvent(KeyboardEvent* evt)
}
#endif
+#if PLATFORM(WIN)
+void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const WebCore::DragDataMap& dataMap, uint32_t flags)
+{
+ if (!m_page) {
+ send(Messages::WebPageProxy::DidPerformDragControllerAction(DragOperationNone));
+ return;
+ }
+
+ DragData dragData(dataMap, clientPosition, globalPosition, static_cast<DragOperation>(draggingSourceOperationMask), static_cast<DragApplicationFlags>(flags));
+ switch (action) {
+ case DragControllerActionEntered:
+ send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragEntered(&dragData)));
+ break;
+
+ case DragControllerActionUpdated:
+ send(Messages::WebPageProxy::DidPerformDragControllerAction(m_page->dragController()->dragUpdated(&dragData)));
+ break;
+
+ case DragControllerActionExited:
+ m_page->dragController()->dragExited(&dragData);
+ break;
+
+ case DragControllerActionPerformDrag:
+ m_page->dragController()->performDrag(&dragData);
+ break;
+
+ default:
+ ASSERT_NOT_REACHED();
+ }
+}
+#else
void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t draggingSourceOperationMask, const String& dragStorageName, uint32_t flags)
{
if (!m_page) {
@@ -1325,6 +1480,7 @@ void WebPage::performDragControllerAction(uint64_t action, WebCore::IntPoint cli
ASSERT_NOT_REACHED();
}
}
+#endif
void WebPage::dragEnded(WebCore::IntPoint clientPosition, WebCore::IntPoint globalPosition, uint64_t operation)
{
@@ -1433,6 +1589,13 @@ void WebPage::didCancelForOpenPanel()
m_activeOpenPanelResultListener = 0;
}
+#if ENABLE(WEB_PROCESS_SANDBOX)
+void WebPage::extendSandboxForFileFromOpenPanel(const SandboxExtension::Handle& handle)
+{
+ SandboxExtension::create(handle)->consumePermanently();
+}
+#endif
+
void WebPage::didReceiveGeolocationPermissionDecision(uint64_t geolocationID, bool allowed)
{
m_geolocationPermissionRequestManager.didReceiveGeolocationPermissionDecision(geolocationID, allowed);
@@ -1563,7 +1726,7 @@ void WebPage::didReceiveMessage(CoreIPC::Connection* connection, CoreIPC::Messag
return;
}
-#ifdef __APPLE__
+#if PLATFORM(MAC) || PLATFORM(WIN)
if (messageID.is<CoreIPC::MessageClassDrawingArea>()) {
if (m_drawingArea)
m_drawingArea->didReceiveDrawingAreaMessage(connection, messageID, arguments);
@@ -1650,11 +1813,39 @@ void WebPage::SandboxExtensionTracker::beginLoad(WebFrame* frame, const SandboxE
m_pendingProvisionalSandboxExtension = SandboxExtension::create(handle);
}
+static bool shouldReuseCommittedSandboxExtension(WebFrame* frame)
+{
+ ASSERT(frame->isMainFrame());
+
+ FrameLoader* frameLoader = frame->coreFrame()->loader();
+ FrameLoadType frameLoadType = frameLoader->loadType();
+
+ // If the page is being reloaded, it should reuse whatever extension is committed.
+ if (frameLoadType == FrameLoadTypeReload || frameLoadType == FrameLoadTypeReloadFromOrigin)
+ return true;
+
+ DocumentLoader* documentLoader = frameLoader->documentLoader();
+ DocumentLoader* provisionalDocumentLoader = frameLoader->provisionalDocumentLoader();
+ if (!documentLoader || !provisionalDocumentLoader)
+ return false;
+
+ if (documentLoader->url().isLocalFile() && provisionalDocumentLoader->url().isLocalFile()
+ && provisionalDocumentLoader->triggeringAction().type() == NavigationTypeLinkClicked)
+ return true;
+
+ return false;
+}
+
void WebPage::SandboxExtensionTracker::didStartProvisionalLoad(WebFrame* frame)
{
if (!frame->isMainFrame())
return;
+ if (shouldReuseCommittedSandboxExtension(frame)) {
+ m_pendingProvisionalSandboxExtension = m_committedSandboxExtension.release();
+ ASSERT(!m_committedSandboxExtension);
+ }
+
ASSERT(!m_provisionalSandboxExtension);
m_provisionalSandboxExtension = m_pendingProvisionalSandboxExtension.release();
@@ -1749,6 +1940,9 @@ void WebPage::beginPrinting(uint64_t frameID, const PrintInfo& printInfo)
m_printContext = adoptPtr(new PrintContext(coreFrame));
m_printContext->begin(printInfo.availablePaperWidth, printInfo.availablePaperHeight);
+
+ float fullPageHeight;
+ m_printContext->computePageRects(FloatRect(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight), 0, 0, printInfo.pageSetupScaleFactor, fullPageHeight, true);
}
void WebPage::endPrinting()
@@ -1756,57 +1950,90 @@ void WebPage::endPrinting()
m_printContext = nullptr;
}
-void WebPage::computePagesForPrinting(uint64_t frameID, const PrintInfo& printInfo, Vector<IntRect>& resultPageRects, double& resultTotalScaleFactorForPrinting)
+void WebPage::computePagesForPrinting(uint64_t frameID, const PrintInfo& printInfo, uint64_t callbackID)
{
- beginPrinting(frameID, printInfo);
+ Vector<IntRect> resultPageRects;
+ double resultTotalScaleFactorForPrinting = 1;
- WebFrame* frame = WebProcess::shared().webFrame(frameID);
- if (!frame)
- return;
-
- float fullPageHeight;
- m_printContext->computePageRects(FloatRect(0, 0, printInfo.availablePaperWidth, printInfo.availablePaperHeight), 0, 0, printInfo.pageSetupScaleFactor, fullPageHeight, true);
+ beginPrinting(frameID, printInfo);
- resultTotalScaleFactorForPrinting = m_printContext->computeAutomaticScaleFactor(printInfo.availablePaperWidth) * printInfo.pageSetupScaleFactor;
- resultPageRects = m_printContext->pageRects();
+ if (m_printContext) {
+ resultPageRects = m_printContext->pageRects();
+ resultTotalScaleFactorForPrinting = m_printContext->computeAutomaticScaleFactor(FloatSize(printInfo.availablePaperWidth, printInfo.availablePaperHeight)) * printInfo.pageSetupScaleFactor;
+ }
// If we're asked to print, we should actually print at least a blank page.
if (resultPageRects.isEmpty())
resultPageRects.append(IntRect(0, 0, 1, 1));
+
+ send(Messages::WebPageProxy::ComputedPagesCallback(resultPageRects, resultTotalScaleFactorForPrinting, callbackID));
}
#if PLATFORM(MAC)
// FIXME: Find a better place for Mac specific code.
-void WebPage::drawRectToPDF(uint64_t frameID, const WebCore::IntRect& rect, Vector<uint8_t>& pdfData)
+void WebPage::drawRectToPDF(uint64_t frameID, const WebCore::IntRect& rect, uint64_t callbackID)
{
WebFrame* frame = WebProcess::shared().webFrame(frameID);
- if (!frame)
- return;
+ Frame* coreFrame = frame ? frame->coreFrame() : 0;
- Frame* coreFrame = frame->coreFrame();
- if (!coreFrame)
- return;
+ RetainPtr<CFMutableDataRef> pdfPageData(AdoptCF, CFDataCreateMutable(0, 0));
- ASSERT(coreFrame->document()->printing());
+ if (coreFrame) {
+ ASSERT(coreFrame->document()->printing());
+
+ // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data.
+ RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get()));
+
+ CGRect mediaBox = CGRectMake(0, 0, rect.width(), rect.height());
+ RetainPtr<CGContextRef> context(AdoptCF, CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0));
+ RetainPtr<CFDictionaryRef> pageInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ CGPDFContextBeginPage(context.get(), pageInfo.get());
+
+ GraphicsContext ctx(context.get());
+ ctx.scale(FloatSize(1, -1));
+ ctx.translate(0, -rect.height());
+ m_printContext->spoolRect(ctx, rect);
+
+ CGPDFContextEndPage(context.get());
+ CGPDFContextClose(context.get());
+ }
+
+ send(Messages::WebPageProxy::DataCallback(CoreIPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID));
+}
+
+void WebPage::drawPagesToPDF(uint64_t frameID, uint32_t first, uint32_t count, uint64_t callbackID)
+{
+ WebFrame* frame = WebProcess::shared().webFrame(frameID);
+ Frame* coreFrame = frame ? frame->coreFrame() : 0;
RetainPtr<CFMutableDataRef> pdfPageData(AdoptCF, CFDataCreateMutable(0, 0));
- // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data.
- RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get()));
+ if (coreFrame) {
+ ASSERT(coreFrame->document()->printing());
- CGRect mediaBox = CGRectMake(0, 0, frame->size().width(), frame->size().height());
- RetainPtr<CGContextRef> context(AdoptCF, CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0));
- CFDictionaryRef pageInfo = CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
- CGPDFContextBeginPage(context.get(), pageInfo);
+ // FIXME: Use CGDataConsumerCreate with callbacks to avoid copying the data.
+ RetainPtr<CGDataConsumerRef> pdfDataConsumer(AdoptCF, CGDataConsumerCreateWithCFData(pdfPageData.get()));
- GraphicsContext ctx(context.get());
- m_printContext->spoolRect(ctx, rect);
+ CGRect mediaBox = m_printContext->pageCount() ? m_printContext->pageRect(0) : CGRectMake(0, 0, 1, 1);
+ RetainPtr<CGContextRef> context(AdoptCF, CGPDFContextCreate(pdfDataConsumer.get(), &mediaBox, 0));
+ for (uint32_t page = first; page < first + count; ++page) {
+ if (page >= m_printContext->pageCount())
+ break;
- CGPDFContextEndPage(context.get());
- CGPDFContextClose(context.get());
+ RetainPtr<CFDictionaryRef> pageInfo(AdoptCF, CFDictionaryCreateMutable(0, 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
+ CGPDFContextBeginPage(context.get(), pageInfo.get());
+
+ GraphicsContext ctx(context.get());
+ ctx.scale(FloatSize(1, -1));
+ ctx.translate(0, -m_printContext->pageRect(page).height());
+ m_printContext->spoolPage(ctx, page, m_printContext->pageRect(page).width());
+
+ CGPDFContextEndPage(context.get());
+ }
+ CGPDFContextClose(context.get());
+ }
- pdfData.resize(CFDataGetLength(pdfPageData.get()));
- CFDataGetBytes(pdfPageData.get(), CFRangeMake(0, pdfData.size()), pdfData.data());
+ send(Messages::WebPageProxy::DataCallback(CoreIPC::DataReference(CFDataGetBytePtr(pdfPageData.get()), CFDataGetLength(pdfPageData.get())), callbackID));
}
#endif