Modified: trunk/Source/WebKit2/ChangeLog (97154 => 97155)
--- trunk/Source/WebKit2/ChangeLog 2011-10-11 16:13:11 UTC (rev 97154)
+++ trunk/Source/WebKit2/ChangeLog 2011-10-11 16:41:11 UTC (rev 97155)
@@ -1,3 +1,28 @@
+2011-10-11 Alexey Proskuryakov <[email protected]>
+
+ [Mac] Should be able to display multi-page PDFs in subframes
+ https://bugs.webkit.org/show_bug.cgi?id=69804
+
+ Reviewed by Anders Carlsson.
+
+ * WebProcess/Plugins/PDF/BuiltInPDFView.h:
+ * WebProcess/Plugins/PDF/BuiltInPDFView.cpp:
+ (WebKit::BuiltInPDFView::updateScrollbars): Page step should be exactly one page, so that
+ one could step over the document page by page. It certainly shouldn't be a portion of the
+ whole document.
+ (WebKit::BuiltInPDFView::pdfDocumentDidLoad): Moved duplicated code from load callbacks here.
+ (WebKit::BuiltInPDFView::calculateSizes): Calculate document size including gutters, and
+ remember page boxes.
+ (WebKit::BuiltInPDFView::paint): Split into separate functions.
+ (WebKit::BuiltInPDFView::paintBackground): Just paint gray background for the whole dirty rect.
+ (WebKit::BuiltInPDFView::paintContent): Paint pages and shadow under them. This code is still
+ fairly naive, as it doesn't understand annotations or page rotation.
+ Constants for shadows roughly match PDFView, but not quite, since it draws entirely custom
+ shadows.
+ (WebKit::BuiltInPDFView::paintControls): Moved scrollbar and scroll corner painting here.
+ (WebKit::BuiltInPDFView::streamDidFinishLoading): Moved common code into pdfDocumentDidLoad().
+ (WebKit::BuiltInPDFView::manualStreamDidFinishLoading): Ditto.
+
2011-10-11 Gopal Raghavan <[email protected]>
[Qt] WebProcess using proxy settings for localhost as well
Modified: trunk/Source/WebKit2/WebProcess/Plugins/PDF/BuiltInPDFView.cpp (97154 => 97155)
--- trunk/Source/WebKit2/WebProcess/Plugins/PDF/BuiltInPDFView.cpp 2011-10-11 16:13:11 UTC (rev 97154)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PDF/BuiltInPDFView.cpp 2011-10-11 16:41:11 UTC (rev 97155)
@@ -48,6 +48,11 @@
const uint64_t pdfDocumentRequestID = 1; // PluginController supports loading multiple streams, but we only need one for PDF.
+const int gutterHeight = 10;
+const int shadowOffsetX = 0;
+const int shadowOffsetY = -2;
+const int shadowSize = 7;
+
PassRefPtr<BuiltInPDFView> BuiltInPDFView::create(Page* page)
{
return adoptRef(new BuiltInPDFView(page));
@@ -94,18 +99,6 @@
return static_cast<const PluginView*>(controller());
}
-void BuiltInPDFView::calculateDocumentSize()
-{
- CGPDFPageRef pdfPage = CGPDFDocumentGetPage(m_pdfDocument.get(), 1); // FIXME: Draw all pages of a document.
- if (!pdfPage)
- return;
-
- CGRect box = CGPDFPageGetBoxRect(pdfPage, kCGPDFCropBox);
- if (CGRectIsEmpty(box))
- box = CGPDFPageGetBoxRect(pdfPage, kCGPDFMediaBox);
- m_pdfDocumentSize = IntSize(box.size);
-}
-
void BuiltInPDFView::updateScrollbars()
{
if (m_horizontalScrollbar) {
@@ -123,9 +116,7 @@
int horizontalScrollbarHeight = (m_horizontalScrollbar && !m_horizontalScrollbar->isOverlayScrollbar()) ? m_horizontalScrollbar->height() : 0;
int verticalScrollbarWidth = (m_verticalScrollbar && !m_verticalScrollbar->isOverlayScrollbar()) ? m_verticalScrollbar->width() : 0;
- // FIXME: Use document page size for PageDown step.
- int clientHeight = m_pdfDocumentSize.height();
- int pageStep = max(max<int>(clientHeight * Scrollbar::minFractionToStepWhenPaging(), clientHeight - Scrollbar::maxOverlapBetweenPages()), 1);
+ int pageStep = m_pageBoxes.isEmpty() ? 0 : m_pageBoxes[0].height();
if (m_horizontalScrollbar) {
m_horizontalScrollbar->setSteps(Scrollbar::pixelsPerLineStep(), pageStep);
@@ -189,12 +180,32 @@
void BuiltInPDFView::pdfDocumentDidLoad()
{
- calculateDocumentSize();
+ RetainPtr<CGDataProviderRef> pdfDataProvider(AdoptCF, CGDataProviderCreateWithCFData(m_dataBuffer.get()));
+ m_pdfDocument.adoptCF(CGPDFDocumentCreateWithProvider(pdfDataProvider.get()));
+
+ calculateSizes();
updateScrollbars();
controller()->invalidate(IntRect(0, 0, m_frameRect.width(), m_frameRect.height()));
}
+void BuiltInPDFView::calculateSizes()
+{
+ size_t pageCount = CGPDFDocumentGetNumberOfPages(m_pdfDocument.get());
+ for (size_t i = 0; i < pageCount; ++i) {
+ CGPDFPageRef pdfPage = CGPDFDocumentGetPage(m_pdfDocument.get(), i + 1);
+ ASSERT(pdfPage);
+
+ CGRect box = CGPDFPageGetBoxRect(pdfPage, kCGPDFCropBox);
+ if (CGRectIsEmpty(box))
+ box = CGPDFPageGetBoxRect(pdfPage, kCGPDFMediaBox);
+ m_pageBoxes.append(IntRect(box));
+ m_pdfDocumentSize.setWidth(max(m_pdfDocumentSize.width(), static_cast<int>(box.size.width)));
+ m_pdfDocumentSize.expand(0, box.size.height);
+ }
+ m_pdfDocumentSize.expand(0, gutterHeight * (m_pageBoxes.size() - 1));
+}
+
bool BuiltInPDFView::initialize(const Parameters& parameters)
{
// Load the src URL if needed.
@@ -210,41 +221,79 @@
void BuiltInPDFView::paint(GraphicsContext* graphicsContext, const IntRect& dirtyRectInWindowCoordinates)
{
- if (!m_pdfDocument) // FIXME: Draw background and loading progress.
- return;
+ scrollAnimator()->contentAreaWillPaint();
- // FIXME: This function just draws the fist page of a document at top left corner.
- // We should show the whole document, centering small ones.
- CGPDFPageRef pdfPage = CGPDFDocumentGetPage(m_pdfDocument.get(), 1);
- if (!pdfPage)
+ paintBackground(graphicsContext, dirtyRectInWindowCoordinates);
+
+ if (!m_pdfDocument) // FIXME: Draw loading progress.
return;
- scrollAnimator()->contentAreaWillPaint();
+ GraphicsContextStateSaver stateSaver(*graphicsContext);
+ // Undo translation to window coordinates performed by PluginView::paint().
+ IntRect dirtyRect = pluginView()->parent()->windowToContents(dirtyRectInWindowCoordinates);
+ IntPoint documentOriginInWindowCoordinates = pluginView()->parent()->windowToContents(IntPoint());
+ graphicsContext->translate(-documentOriginInWindowCoordinates.x(), -documentOriginInWindowCoordinates.y());
+
+ paintContent(graphicsContext, dirtyRect);
+ paintControls(graphicsContext, dirtyRect);
+}
+
+void BuiltInPDFView::paintBackground(GraphicsContext* graphicsContext, const IntRect& dirtyRect)
+{
+ GraphicsContextStateSaver stateSaver(*graphicsContext);
+ graphicsContext->setFillColor(Color::gray, ColorSpaceDeviceRGB);
+ graphicsContext->fillRect(dirtyRect);
+}
+
+void BuiltInPDFView::paintContent(GraphicsContext* graphicsContext, const IntRect& dirtyRect)
+{
+ GraphicsContextStateSaver stateSaver(*graphicsContext);
CGContextRef context = graphicsContext->platformContext();
- GraphicsContextStateSaver stateSaver(*graphicsContext);
- graphicsContext->clip(dirtyRectInWindowCoordinates);
+
graphicsContext->setImageInterpolationQuality(InterpolationHigh);
graphicsContext->setShouldAntialias(true);
graphicsContext->setShouldSmoothFonts(true);
+ graphicsContext->setFillColor(Color::white, ColorSpaceDeviceRGB);
- CGRect pageBox = CGPDFPageGetBoxRect(pdfPage, kCGPDFCropBox);
- if (CGRectIsEmpty(pageBox))
- pageBox = CGPDFPageGetBoxRect(pdfPage, kCGPDFMediaBox);
+ graphicsContext->clip(dirtyRect);
+ IntRect contentRect(dirtyRect);
+ contentRect.moveBy(-pluginView()->location());
+ contentRect.moveBy(IntPoint(m_scrollOffset));
+ graphicsContext->translate(pluginView()->x() - m_scrollOffset.width(), pluginView()->y() - m_scrollOffset.height());
- CGContextClipToRect(context, CGRectMake(m_frameRect.x(), m_frameRect.y(), m_pdfDocumentSize.width() - m_scrollOffset.width(), m_pdfDocumentSize.height() - m_scrollOffset.height()));
- CGContextTranslateCTM(context, m_frameRect.x() - pageBox.origin.x - m_scrollOffset.width(), m_frameRect.y() + pageBox.origin.y + m_pdfDocumentSize.height() - m_scrollOffset.height());
-
CGContextScaleCTM(context, 1, -1);
- CGContextDrawPDFPage(context, pdfPage);
- stateSaver.restore();
+ int pageTop = 0;
+ for (size_t i = 0; i < m_pageBoxes.size(); ++i) {
+ IntRect pageBox = m_pageBoxes[i];
+ if (pageTop > contentRect.maxY())
+ break;
+ if (pageTop + pageBox.height() >= contentRect.y()) {
+ CGPDFPageRef pdfPage = CGPDFDocumentGetPage(m_pdfDocument.get(), i + 1);
- stateSaver.save();
- // Undo translation to window coordinates performed by PluginView::paint().
- IntRect dirtyRect = pluginView()->parent()->windowToContents(dirtyRectInWindowCoordinates);
- IntPoint documentOriginInWindowCoordinates = pluginView()->parent()->windowToContents(IntPoint());
- graphicsContext->translate(-documentOriginInWindowCoordinates.x(), -documentOriginInWindowCoordinates.y());
+ float extraOffsetForCenteringX = max((m_frameRect.width() - pageBox.width()) / 2.0f, 0.0f);
+ float extraOffsetForCenteringY = (m_pageBoxes.size() == 1) ? max((m_frameRect.height() - pageBox.height() + shadowOffsetY) / 2.0f, 0.0f) : 0;
+
+ graphicsContext->save();
+ graphicsContext->translate(extraOffsetForCenteringX - pageBox.x(), -extraOffsetForCenteringY - pageBox.y() - pageBox.height());
+
+ graphicsContext->setShadow(FloatSize(shadowOffsetX, shadowOffsetY), shadowSize, Color::black, ColorSpaceDeviceRGB);
+ graphicsContext->fillRect(pageBox);
+ graphicsContext->clearShadow();
+
+ graphicsContext->clip(pageBox);
+
+ CGContextDrawPDFPage(context, pdfPage);
+ graphicsContext->restore();
+ }
+ pageTop += pageBox.height() + gutterHeight;
+ CGContextTranslateCTM(context, 0, -pageBox.height() - gutterHeight);
+ }
+}
+
+void BuiltInPDFView::paintControls(GraphicsContext* graphicsContext, const IntRect& dirtyRect)
+{
if (m_horizontalScrollbar)
m_horizontalScrollbar->paint(graphicsContext, dirtyRect);
if (m_verticalScrollbar)
@@ -334,9 +383,6 @@
{
ASSERT_UNUSED(streamID, streamID == pdfDocumentRequestID);
- RetainPtr<CGDataProviderRef> pdfDataProvider(AdoptCF, CGDataProviderCreateWithCFData(m_dataBuffer.get()));
- m_pdfDocument.adoptCF(CGPDFDocumentCreateWithProvider(pdfDataProvider.get()));
-
pdfDocumentDidLoad();
}
@@ -361,9 +407,6 @@
void BuiltInPDFView::manualStreamDidFinishLoading()
{
- RetainPtr<CGDataProviderRef> pdfDataProvider(AdoptCF, CGDataProviderCreateWithCFData(m_dataBuffer.get()));
- m_pdfDocument.adoptCF(CGPDFDocumentCreateWithProvider(pdfDataProvider.get()));
-
pdfDocumentDidLoad();
}
Modified: trunk/Source/WebKit2/WebProcess/Plugins/PDF/BuiltInPDFView.h (97154 => 97155)
--- trunk/Source/WebKit2/WebProcess/Plugins/PDF/BuiltInPDFView.h 2011-10-11 16:13:11 UTC (rev 97154)
+++ trunk/Source/WebKit2/WebProcess/Plugins/PDF/BuiltInPDFView.h 2011-10-11 16:41:11 UTC (rev 97155)
@@ -53,18 +53,21 @@
PluginView* pluginView();
const PluginView* pluginView() const;
- void calculateDocumentSize();
void updateScrollbars();
void didAddHorizontalScrollbar(WebCore::Scrollbar*);
void willRemoveHorizontalScrollbar(WebCore::Scrollbar*);
PassRefPtr<WebCore::Scrollbar> createScrollbar(WebCore::ScrollbarOrientation);
void destroyScrollbar(WebCore::ScrollbarOrientation);
void pdfDocumentDidLoad();
+ void calculateSizes();
+ void paintBackground(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect);
+ void paintContent(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect);
+ void paintControls(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect);
// Plug-in methods
virtual bool initialize(const Parameters&);
virtual void destroy();
- virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRect);
+ virtual void paint(WebCore::GraphicsContext*, const WebCore::IntRect& dirtyRectInWindowCoordinates);
virtual void updateControlTints(WebCore::GraphicsContext*);
virtual PassRefPtr<ShareableBitmap> snapshot();
#if PLATFORM(MAC)
@@ -136,6 +139,7 @@
RetainPtr<CFMutableDataRef> m_dataBuffer;
RetainPtr<CGPDFDocumentRef> m_pdfDocument;
+ Vector<WebCore::IntRect> m_pageBoxes;
WebCore::IntSize m_pdfDocumentSize; // All pages, including gaps.
RefPtr<WebCore::Scrollbar> m_horizontalScrollbar;