diff options
8 files changed, 117 insertions, 20 deletions
diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp b/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp index bfae398..ce53c4b7 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp +++ b/third_party/WebKit/Source/platform/graphics/GraphicsContext.cpp @@ -34,6 +34,7 @@ #include "platform/graphics/Gradient.h" #include "platform/graphics/ImageBuffer.h" #include "platform/weborigin/KURL.h" +#include "skia/ext/platform_device.h" #include "third_party/skia/include/core/SkAnnotation.h" #include "third_party/skia/include/core/SkColorFilter.h" #include "third_party/skia/include/core/SkData.h" @@ -75,19 +76,19 @@ private: const SkMatrix m_savedMatrix; }; -GraphicsContext::GraphicsContext(DisplayItemList* displayItemList, DisabledMode disableContextOrPainting) - : GraphicsContext(nullptr, displayItemList, disableContextOrPainting) +GraphicsContext::GraphicsContext(DisplayItemList* displayItemList, DisabledMode disableContextOrPainting, SkMetaData* metaData) + : GraphicsContext(nullptr, displayItemList, disableContextOrPainting, metaData) { // TODO(chrishtr): switch the type of the parameter to DisplayItemList&. ASSERT(displayItemList); } -PassOwnPtr<GraphicsContext> GraphicsContext::deprecatedCreateWithCanvas(SkCanvas* canvas, DisabledMode disableContextOrPainting) +PassOwnPtr<GraphicsContext> GraphicsContext::deprecatedCreateWithCanvas(SkCanvas* canvas, DisabledMode disableContextOrPainting, SkMetaData* metaData) { - return adoptPtr(new GraphicsContext(canvas, nullptr, disableContextOrPainting)); + return adoptPtr(new GraphicsContext(canvas, nullptr, disableContextOrPainting, metaData)); } -GraphicsContext::GraphicsContext(SkCanvas* canvas, DisplayItemList* displayItemList, DisabledMode disableContextOrPainting) +GraphicsContext::GraphicsContext(SkCanvas* canvas, DisplayItemList* displayItemList, DisabledMode disableContextOrPainting, SkMetaData* metaData) : m_canvas(canvas) , m_originalCanvas(canvas) , m_displayItemList(displayItemList) @@ -102,7 +103,11 @@ GraphicsContext::GraphicsContext(SkCanvas* canvas, DisplayItemList* displayItemL , m_deviceScaleFactor(1.0f) , m_accelerated(false) , m_printing(false) + , m_hasMetaData(!!metaData) { + if (metaData) + m_metaData = *metaData; + // FIXME: Do some tests to determine how many states are typically used, and allocate // several here. m_paintStateStack.append(GraphicsContextState::create()); @@ -402,12 +407,17 @@ void GraphicsContext::beginRecording(const FloatRect& bounds) if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { m_canvas = m_pictureRecorder.beginRecording(bounds, 0); + if (m_hasMetaData) + skia::getMetaData(*m_canvas) = m_metaData; return; } m_recordingStateStack.append( RecordingState::Create(m_canvas, getTotalMatrix())); + m_canvas = m_recordingStateStack.last()->recorder().beginRecording(bounds, 0); + if (m_hasMetaData) + skia::getMetaData(*m_canvas) = m_metaData; } PassRefPtr<const SkPicture> GraphicsContext::endRecording() diff --git a/third_party/WebKit/Source/platform/graphics/GraphicsContext.h b/third_party/WebKit/Source/platform/graphics/GraphicsContext.h index da04802..4fea938 100644 --- a/third_party/WebKit/Source/platform/graphics/GraphicsContext.h +++ b/third_party/WebKit/Source/platform/graphics/GraphicsContext.h @@ -37,6 +37,7 @@ #include "platform/graphics/ImageOrientation.h" #include "platform/graphics/GraphicsContextState.h" #include "platform/graphics/skia/SkiaUtils.h" +#include "third_party/skia/include/core/SkMetaData.h" #include "third_party/skia/include/core/SkPictureRecorder.h" #include "third_party/skia/include/core/SkRegion.h" #include "wtf/FastAllocBase.h" @@ -73,13 +74,13 @@ public: FullyDisabled = 1 // Do absolutely minimal work to remove the cost of the context from performance tests. }; - explicit GraphicsContext(DisplayItemList*, DisabledMode = NothingDisabled); + explicit GraphicsContext(DisplayItemList*, DisabledMode = NothingDisabled, SkMetaData* = 0); // TODO(chrishtr): Once Slimming Paint launches this should be removed (crbug.com/471333). // A 0 canvas is allowed, but in such cases the context must only have canvas // related commands called when within a beginRecording/endRecording block. // Furthermore, save/restore calls must be balanced any time the canvas is 0. - static PassOwnPtr<GraphicsContext> deprecatedCreateWithCanvas(SkCanvas*, DisabledMode = NothingDisabled); + static PassOwnPtr<GraphicsContext> deprecatedCreateWithCanvas(SkCanvas*, DisabledMode = NothingDisabled, SkMetaData* = 0); ~GraphicsContext(); @@ -306,7 +307,7 @@ public: static PassRefPtr<SkColorFilter> WebCoreColorFilterToSkiaColorFilter(ColorFilter); private: - explicit GraphicsContext(SkCanvas*, DisplayItemList*, DisabledMode = NothingDisabled); + explicit GraphicsContext(SkCanvas*, DisplayItemList*, DisabledMode = NothingDisabled, SkMetaData* = 0); const GraphicsContextState* immutableState() const { return m_paintState; } @@ -370,6 +371,8 @@ private: bool isRecording() const; + const SkMetaData& metaData() const { return m_metaData; } + // null indicates painting is contextDisabled. Never delete this object. SkCanvas* m_canvas; @@ -393,6 +396,8 @@ private: Vector<OwnPtr<RecordingState>> m_recordingStateStack; SkPictureRecorder m_pictureRecorder; + SkMetaData m_metaData; + #if ENABLE(ASSERT) unsigned m_layerCount; bool m_disableDestructionChecks; @@ -405,6 +410,7 @@ private: unsigned m_accelerated : 1; unsigned m_printing : 1; + unsigned m_hasMetaData : 1; }; } // namespace blink diff --git a/third_party/WebKit/Source/platform/graphics/paint/SkPictureBuilder.h b/third_party/WebKit/Source/platform/graphics/paint/SkPictureBuilder.h index 2a8c302..d078245 100644 --- a/third_party/WebKit/Source/platform/graphics/paint/SkPictureBuilder.h +++ b/third_party/WebKit/Source/platform/graphics/paint/SkPictureBuilder.h @@ -18,14 +18,14 @@ class SkPictureBuilder { WTF_MAKE_NONCOPYABLE(SkPictureBuilder); STACK_ALLOCATED(); public: - SkPictureBuilder(const FloatRect& bounds, GraphicsContext::DisabledMode disabledMode = GraphicsContext::NothingDisabled) + SkPictureBuilder(const FloatRect& bounds, GraphicsContext::DisabledMode disabledMode = GraphicsContext::NothingDisabled, SkMetaData* metaData = 0) : m_bounds(bounds) { if (RuntimeEnabledFeatures::slimmingPaintEnabled()) { m_displayItemList = DisplayItemList::create(); - m_context = adoptPtr(new GraphicsContext(m_displayItemList.get(), disabledMode)); + m_context = adoptPtr(new GraphicsContext(m_displayItemList.get(), disabledMode, metaData)); } else { - m_context = GraphicsContext::deprecatedCreateWithCanvas(nullptr, disabledMode); + m_context = GraphicsContext::deprecatedCreateWithCanvas(nullptr, disabledMode, metaData); m_context->beginRecording(m_bounds); } } diff --git a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp index d38d034..ab13d53 100644 --- a/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp +++ b/third_party/WebKit/Source/web/WebLocalFrameImpl.cpp @@ -208,6 +208,7 @@ #include "public/web/WebScriptSource.h" #include "public/web/WebSerializedScriptValue.h" #include "public/web/WebTreeScopeType.h" +#include "skia/ext/platform_device.h" #include "web/AssociatedURLLoader.h" #include "web/CompositionUnderlineVectorBuilder.h" #include "web/FindInPageCoordinates.h" @@ -360,7 +361,8 @@ public: return 0; IntRect pageRect = m_pageRects[pageNumber]; - SkPictureBuilder pictureBuilder(pageRect); + SkPictureBuilder pictureBuilder(pageRect, GraphicsContext::NothingDisabled, &skia::getMetaData(*canvas)); + pictureBuilder.context().setPrinting(true); float scale = spoolPage(pictureBuilder.context(), pageNumber); pictureBuilder.endRecording()->playback(canvas); @@ -385,7 +387,9 @@ public: int totalHeight = numPages * (pageSizeInPixels.height() + 1) - 1; IntRect allPagesRect(0, 0, pageWidth, totalHeight); - SkPictureBuilder pictureBuilder(allPagesRect); + SkPictureBuilder pictureBuilder(allPagesRect, GraphicsContext::NothingDisabled, &skia::getMetaData(*canvas)); + pictureBuilder.context().setPrinting(true); + GraphicsContext& context = pictureBuilder.context(); // Fill the whole background by white. @@ -441,8 +445,6 @@ protected: IntRect pageRect = m_pageRects[pageNumber]; float scale = m_printedPageWidth / pageRect.width(); - context.setPrinting(true); - AffineTransform transform; #if OS(POSIX) && !OS(MACOSX) transform.scale(scale); @@ -520,7 +522,9 @@ protected: // instead. Returns the scale to be applied. virtual float spoolPage(GraphicsContext& context, int pageNumber) override { - m_plugin->printPage(pageNumber, &context); + IntRect pageRect = m_pageRects[pageNumber]; + m_plugin->printPage(pageNumber, &context, pageRect); + return 1.0; } diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp index bf77188..9effa08 100644 --- a/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp +++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.cpp @@ -352,8 +352,11 @@ int WebPluginContainerImpl::printBegin(const WebPrintParams& printParams) const return m_webPlugin->printBegin(printParams); } -bool WebPluginContainerImpl::printPage(int pageNumber, GraphicsContext* gc) +bool WebPluginContainerImpl::printPage(int pageNumber, GraphicsContext* gc, const IntRect& printRect) { + LayoutObjectDrawingRecorder drawingRecorder(*gc, *m_element->layoutObject(), DisplayItem::Type::WebPlugin, printRect); + if (drawingRecorder.canUseCachedDrawing()) + return true; gc->save(); WebCanvas* canvas = gc->canvas(); bool ret = m_webPlugin->printPage(pageNumber, canvas); diff --git a/third_party/WebKit/Source/web/WebPluginContainerImpl.h b/third_party/WebKit/Source/web/WebPluginContainerImpl.h index 976198c..962dcc3 100644 --- a/third_party/WebKit/Source/web/WebPluginContainerImpl.h +++ b/third_party/WebKit/Source/web/WebPluginContainerImpl.h @@ -139,7 +139,7 @@ public: // Sets up printing at the specified WebPrintParams. Returns the number of pages to be printed at these settings. int printBegin(const WebPrintParams&) const; // Prints the page specified by pageNumber (0-based index) into the supplied canvas. - bool printPage(int pageNumber, GraphicsContext*); + bool printPage(int pageNumber, GraphicsContext*, const IntRect& paintRect); // Ends the print operation. void printEnd(); diff --git a/third_party/WebKit/Source/web/tests/FrameTestHelpers.cpp b/third_party/WebKit/Source/web/tests/FrameTestHelpers.cpp index f91064e..ba2cf31 100644 --- a/third_party/WebKit/Source/web/tests/FrameTestHelpers.cpp +++ b/third_party/WebKit/Source/web/tests/FrameTestHelpers.cpp @@ -250,6 +250,7 @@ WebViewImpl* WebViewHelper::initialize(bool enableJavascript, TestWebFrameClient webViewClient = defaultWebViewClient(); m_webView = WebViewImpl::create(webViewClient); m_webView->settings()->setJavaScriptEnabled(enableJavascript); + m_webView->settings()->setPluginsEnabled(true); if (updateSettingsFunc) updateSettingsFunc(m_webView->settings()); else diff --git a/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp b/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp index d391895..ca25c4b 100644 --- a/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp +++ b/third_party/WebKit/Source/web/tests/WebPluginContainerTest.cpp @@ -46,8 +46,10 @@ #include "public/web/WebFrame.h" #include "public/web/WebFrameClient.h" #include "public/web/WebPluginParams.h" +#include "public/web/WebPrintParams.h" #include "public/web/WebSettings.h" #include "public/web/WebView.h" +#include "third_party/skia/include/core/SkPictureRecorder.h" #include "web/WebLocalFrameImpl.h" #include "web/WebPluginContainerImpl.h" #include "web/WebViewImpl.h" @@ -76,28 +78,53 @@ protected: std::string m_baseURL; }; +class TestPluginWebFrameClient; + // Subclass of FakeWebPlugin that has a selection of 'x' as plain text and 'y' as markup text. class TestPlugin : public FakeWebPlugin { public: - TestPlugin(WebFrame* frame, const WebPluginParams& params) + TestPlugin(WebFrame* frame, const WebPluginParams& params, TestPluginWebFrameClient* testClient) : FakeWebPlugin(frame, params) { + m_testClient = testClient; } virtual bool hasSelection() const { return true; } virtual WebString selectionAsText() const { return WebString("x"); } virtual WebString selectionAsMarkup() const { return WebString("y"); } + virtual bool supportsPaginatedPrint() { return true; } + virtual int printBegin(const WebPrintParams& printParams) { return 1; } + virtual bool printPage(int pageNumber, WebCanvas*); +private: + TestPluginWebFrameClient* m_testClient; }; class TestPluginWebFrameClient : public FrameTestHelpers::TestWebFrameClient { virtual WebPlugin* createPlugin(WebLocalFrame* frame, const WebPluginParams& params) override { if (params.mimeType == WebString::fromUTF8("application/x-webkit-test-webplugin")) - return new TestPlugin(frame, params); + return new TestPlugin(frame, params, this); + if (params.mimeType == WebString::fromUTF8("application/pdf")) + return new TestPlugin(frame, params, this); return WebFrameClient::createPlugin(frame, params); } + +public: + void onPrintPage() { m_printedPage = true; } + bool printedAtLeastOnePage() { return m_printedPage; } + +private: + bool m_printedPage = false; }; +bool TestPlugin::printPage(int pageNumber, WebCanvas* canvas) +{ + ASSERT(m_testClient); + m_testClient->onPrintPage(); + return true; +} + + WebPluginContainer* getWebPluginContainer(WebView* webView, const WebString& id) { WebElement element = webView->mainFrame()->document().getElementById(id); @@ -134,6 +161,52 @@ TEST_F(WebPluginContainerTest, WindowToLocalPointTest) ASSERT_EQ(10, point4.y); } +TEST_F(WebPluginContainerTest, PrintOnePage) +{ + URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("test.pdf"), WebString::fromUTF8("application/pdf")); + + FrameTestHelpers::WebViewHelper webViewHelper; + TestPluginWebFrameClient* testClient = new TestPluginWebFrameClient(); + WebView* webView = webViewHelper.initializeAndLoad(m_baseURL + "test.pdf", true, testClient); + ASSERT(webView); + webView->layout(); + runPendingTasks(); + WebFrame* frame = webView->mainFrame(); + + WebPrintParams printParams; + printParams.printContentArea.width = 500; + printParams.printContentArea.height = 500; + + frame->printBegin(printParams); + SkPictureRecorder recorder; + frame->printPage(0, recorder.beginRecording(IntRect())); + frame->printEnd(); + ASSERT(testClient->printedAtLeastOnePage()); +} + +TEST_F(WebPluginContainerTest, PrintAllPages) +{ + URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("test.pdf"), WebString::fromUTF8("application/pdf")); + + FrameTestHelpers::WebViewHelper webViewHelper; + TestPluginWebFrameClient* testClient = new TestPluginWebFrameClient(); + WebView* webView = webViewHelper.initializeAndLoad(m_baseURL + "test.pdf", true, testClient); + ASSERT(webView); + webView->layout(); + runPendingTasks(); + WebFrame* frame = webView->mainFrame(); + + WebPrintParams printParams; + printParams.printContentArea.width = 500; + printParams.printContentArea.height = 500; + + frame->printBegin(printParams); + SkPictureRecorder recorder; + frame->printPagesWithBoundaries(recorder.beginRecording(IntRect()), WebSize()); + frame->printEnd(); + ASSERT(testClient->printedAtLeastOnePage()); +} + TEST_F(WebPluginContainerTest, LocalToWindowPointTest) { URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8("plugin_container.html")); |
