diff options
author | maruel@chromium.org <maruel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-19 17:36:22 +0000 |
---|---|---|
committer | maruel@chromium.org <maruel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-19 17:36:22 +0000 |
commit | 88a3eccb5605fc9224ce59c76473b7aae2c31bc8 (patch) | |
tree | 9c31830256ada147c4f19ffb90659da3fb97fa3d | |
parent | f3735c5dc0269579afc173d9e519243c305e1186 (diff) | |
download | chromium_src-88a3eccb5605fc9224ce59c76473b7aae2c31bc8.zip chromium_src-88a3eccb5605fc9224ce59c76473b7aae2c31bc8.tar.gz chromium_src-88a3eccb5605fc9224ce59c76473b7aae2c31bc8.tar.bz2 |
Remove code duplicated from webcore and use the common PrintContext facility.
Review URL: http://codereview.chromium.org/20470
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12100 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/chrome.gyp | 2 | ||||
-rw-r--r-- | chrome/renderer/render_view.cc | 150 | ||||
-rw-r--r-- | chrome/renderer/render_view.h | 20 | ||||
-rw-r--r-- | chrome/renderer/renderer.scons | 1 | ||||
-rw-r--r-- | chrome/test/perf/perftests.scons | 1 | ||||
-rw-r--r-- | chrome/test/unit/unit_tests.scons | 1 | ||||
-rw-r--r-- | webkit/glue/webframe.h | 37 | ||||
-rw-r--r-- | webkit/glue/webframe_impl.cc | 158 | ||||
-rw-r--r-- | webkit/glue/webframe_impl.h | 34 |
9 files changed, 155 insertions, 249 deletions
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index dda58d8..b3cd984 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -1433,6 +1433,7 @@ 'common', 'browser', 'renderer', + '../printing/printing.gyp:printing', ], 'sources': [ # All .cc, .h, .m, and .mm files under app except for tests. @@ -1923,6 +1924,7 @@ 'renderer', 'resources', 'test_support_unit', + '../printing/printing.gyp:printing', '../webkit/webkit.gyp:webkit', '../skia/skia.gyp:skia', '../testing/gtest.gyp:gtest', diff --git a/chrome/renderer/render_view.cc b/chrome/renderer/render_view.cc index dab8043..5954e82 100644 --- a/chrome/renderer/render_view.cc +++ b/chrome/renderer/render_view.cc @@ -41,6 +41,7 @@ #include "grit/renderer_resources.h" #include "net/base/escape.h" #include "net/base/net_errors.h" +#include "printing/units.h" #include "skia/ext/bitmap_platform_device.h" #include "skia/ext/image_operations.h" #include "webkit/default_plugin/default_plugin_shared.h" @@ -178,7 +179,6 @@ RenderView::RenderView(RenderThreadBase* render_thread) opened_by_user_gesture_(true), method_factory_(this), first_default_plugin_(NULL), - printed_document_width_(0), devtools_agent_(NULL), devtools_client_(NULL), history_back_list_count_(0), @@ -453,66 +453,10 @@ void RenderView::SendThumbnail() { Send(new ViewHostMsg_Thumbnail(routing_id_, url, score, thumbnail)); } -int RenderView::SwitchFrameToPrintMediaType(const ViewMsg_Print_Params& params, - WebFrame* frame) { - float ratio = static_cast<float>(params.desired_dpi / params.dpi); - float paper_width = params.printable_size.width() * ratio; - float paper_height = params.printable_size.height() * ratio; - float minLayoutWidth = static_cast<float>(paper_width * params.min_shrink); - float maxLayoutWidth = static_cast<float>(paper_width * params.max_shrink); - - // Safari uses: 765 & 1224. Margins aren't exactly the same either. - // Scale = 2.222 for MDI printer. - int pages; - if (!frame->SetPrintingMode(true, - minLayoutWidth, - maxLayoutWidth, - &printed_document_width_)) { - NOTREACHED(); - pages = 0; - } else { - DCHECK_GT(printed_document_width_, 0); - // Force to recalculate the height, otherwise it reuse the current window - // height as the default. - float effective_shrink = printed_document_width_ / paper_width; - gfx::Size page_size(printed_document_width_, - static_cast<int>(paper_height * effective_shrink) - 1); - WebView* view = frame->GetView(); - if (view) { - // Hack around an issue where if the current view height is higher than - // the page height, empty pages will be printed even if the bottom of the - // web page is empty. - printing_view_size_ = view->GetSize(); - view->Resize(page_size); - view->Layout(); - } - pages = frame->ComputePageRects(params.printable_size); - DCHECK(pages); - } - return pages; -} - -void RenderView::SwitchFrameToDisplayMediaType(WebFrame* frame) { - // Set the layout back to "normal" document; i.e. CSS media type = "screen". - frame->SetPrintingMode(false, 0, 0, NULL); - WebView* view = frame->GetView(); - if (view) { - // Restore from the hack described at SwitchFrameToPrintMediaType(). - view->Resize(printing_view_size_); - view->Layout(); - printing_view_size_.SetSize(0, 0); - } - printed_document_width_ = 0; -} - void RenderView::PrintPage(const ViewMsg_PrintPage_Params& params, + const gfx::Size& canvas_size, WebFrame* frame) { #if defined(OS_WIN) - if (printed_document_width_ <= 0) { - NOTREACHED(); - return; - } - // Generate a memory-based EMF file. The EMF will use the current screen's // DPI. gfx::Emf emf; @@ -521,48 +465,38 @@ void RenderView::PrintPage(const ViewMsg_PrintPage_Params& params, HDC hdc = emf.hdc(); DCHECK(hdc); skia::PlatformDeviceWin::InitializeDC(hdc); - - gfx::Rect rect; - frame->GetPageRect(params.page_number, &rect); - DCHECK(rect.height()); - DCHECK(rect.width()); - double shrink = static_cast<double>(printed_document_width_) / - params.params.printable_size.width(); - // This check would fire each time the page would get truncated on the - // right. This is not worth a DCHECK() but should be looked into, for - // example, wouldn't be worth trying in landscape? - // DCHECK_LE(rect.width(), printed_document_width_); - - // Buffer one page at a time. - int src_size_x = printed_document_width_; - int src_size_y = - static_cast<int>(ceil(params.params.printable_size.height() * - shrink)); + int size_x = canvas_size.width(); + int size_y = canvas_size.height(); + // Calculate the dpi adjustment. + float shrink = static_cast<float>(canvas_size.width()) / + params.params.printable_size.width(); #if 0 // TODO(maruel): This code is kept for testing until the 100% GDI drawing // code is stable. maruels use this code's output as a reference when the // GDI drawing code fails. // Mix of Skia and GDI based. - skia::PlatformCanvasWin canvas(src_size_x, src_size_y, true); + skia::PlatformCanvasWin canvas(size_x, size_y, true); canvas.drawARGB(255, 255, 255, 255, SkPorterDuff::kSrc_Mode); - PlatformContextSkia context(&canvas); - if (!frame->SpoolPage(params.page_number, &context)) { + float webkit_shrink = frame->PrintPage(params.page_number, &canvas); + if (shrink <= 0) { NOTREACHED() << "Printing page " << params.page_number << " failed."; - return; + } else { + // Update the dpi adjustment with the "page shrink" calculated in webkit. + shrink /= webkit_shrink; } // Create a BMP v4 header that we can serialize. BITMAPV4HEADER bitmap_header; - gfx::CreateBitmapV4Header(src_size_x, src_size_y, &bitmap_header); + gfx::CreateBitmapV4Header(size_x, size_y, &bitmap_header); const SkBitmap& src_bmp = canvas.getDevice()->accessBitmap(true); SkAutoLockPixels src_lock(src_bmp); int retval = StretchDIBits(hdc, 0, 0, - src_size_x, src_size_y, + size_x, size_y, 0, 0, - src_size_x, src_size_y, + size_x, size_y, src_bmp.getPixels(), reinterpret_cast<BITMAPINFO*>(&bitmap_header), DIB_RGB_COLORS, @@ -570,14 +504,13 @@ void RenderView::PrintPage(const ViewMsg_PrintPage_Params& params, DCHECK(retval != GDI_ERROR); #else // 100% GDI based. - skia::VectorCanvas canvas(hdc, src_size_x, src_size_y); - // Set the clipping region to be sure to not overflow. - SkRect clip_rect; - clip_rect.set(0, 0, SkIntToScalar(src_size_x), SkIntToScalar(src_size_y)); - canvas.clipRect(clip_rect); - if (!frame->SpoolPage(params.page_number, &canvas)) { + skia::VectorCanvas canvas(hdc, size_x, size_y); + float webkit_shrink = frame->PrintPage(params.page_number, &canvas); + if (shrink <= 0) { NOTREACHED() << "Printing page " << params.page_number << " failed."; - return; + } else { + // Update the dpi adjustment with the "page shrink" calculated in webkit. + shrink /= webkit_shrink; } #endif @@ -640,26 +573,36 @@ void RenderView::OnPrintPages() { void RenderView::PrintPages(const ViewMsg_PrintPages_Params& params, WebFrame* frame) { - int pages = SwitchFrameToPrintMediaType(params.params, frame); + int page_count = 0; + gfx::Size canvas_size; + canvas_size.set_width( + printing::ConvertUnit(params.params.printable_size.width(), + static_cast<int>(params.params.dpi), + params.params.desired_dpi)); + canvas_size.set_height( + printing::ConvertUnit(params.params.printable_size.height(), + static_cast<int>(params.params.dpi), + params.params.desired_dpi)); + frame->BeginPrint(canvas_size, &page_count); Send(new ViewHostMsg_DidGetPrintedPagesCount(routing_id_, params.params.document_cookie, - pages)); - if (pages) { + page_count)); + if (page_count) { ViewMsg_PrintPage_Params page_params; page_params.params = params.params; if (params.pages.empty()) { - for (int i = 0; i < pages; ++i) { + for (int i = 0; i < page_count; ++i) { page_params.page_number = i; - PrintPage(page_params, frame); + PrintPage(page_params, canvas_size, frame); } } else { for (size_t i = 0; i < params.pages.size(); ++i) { page_params.page_number = params.pages[i]; - PrintPage(page_params, frame); + PrintPage(page_params, canvas_size, frame); } } } - SwitchFrameToDisplayMediaType(frame); + frame->EndPrint(); } void RenderView::CapturePageInfo(int load_id, bool preliminary_capture) { @@ -2336,10 +2279,19 @@ void RenderView::ScriptedPrint(WebFrame* frame) { msg = NULL; // Continue only if the settings are valid. if (default_settings.dpi && default_settings.document_cookie) { - int expected_pages_count = SwitchFrameToPrintMediaType(default_settings, - frame); + int expected_pages_count = 0; + gfx::Size canvas_size; + canvas_size.set_width( + printing::ConvertUnit(default_settings.printable_size.width(), + static_cast<int>(default_settings.dpi), + default_settings.desired_dpi)); + canvas_size.set_height( + printing::ConvertUnit(default_settings.printable_size.height(), + static_cast<int>(default_settings.dpi), + default_settings.desired_dpi)); + frame->BeginPrint(canvas_size, &expected_pages_count); DCHECK(expected_pages_count); - SwitchFrameToDisplayMediaType(frame); + frame->EndPrint(); // Ask the browser to show UI to retrieve the final print settings. ViewMsg_PrintPages_Params print_settings; diff --git a/chrome/renderer/render_view.h b/chrome/renderer/render_view.h index 7263cb7..05e94c2 100644 --- a/chrome/renderer/render_view.h +++ b/chrome/renderer/render_view.h @@ -572,17 +572,10 @@ class RenderView : public RenderWidget, // Notification of volume property of an audio output stream. void OnAudioStreamVolume(int stream_id, double left, double right); - // Switches the frame's CSS media type to "print" and calculate the number of - // printed pages that are to be expected. |frame| will be used to calculate - // the number of expected pages for this frame only. - int SwitchFrameToPrintMediaType(const ViewMsg_Print_Params& params, - WebFrame* frame); - - // Switches the frame's CSS media type to "display". - void SwitchFrameToDisplayMediaType(WebFrame* frame); - // Prints the page listed in |params|. - void PrintPage(const ViewMsg_PrintPage_Params& params, WebFrame* frame); + void PrintPage(const ViewMsg_PrintPage_Params& params, + const gfx::Size& canvas_size, + WebFrame* frame); // Prints all the pages listed in |params|. void PrintPages(const ViewMsg_PrintPages_Params& params, WebFrame* frame); @@ -733,13 +726,6 @@ class RenderView : public RenderWidget, // check this to know if they should pump messages/tasks then. scoped_ptr<base::WaitableEvent> modal_dialog_event_; - // Document width when in print CSS media type. 0 otherwise. - int printed_document_width_; - - // Backup the view size before printing since it needs to be overriden. This - // value is set to restore the view size when printing is done. - gfx::Size printing_view_size_; - scoped_refptr<DebugMessageHandler> debug_message_handler_; // Provides access to this renderer from the remote Inspector UI. diff --git a/chrome/renderer/renderer.scons b/chrome/renderer/renderer.scons index 5c6633f..df8d158 100644 --- a/chrome/renderer/renderer.scons +++ b/chrome/renderer/renderer.scons @@ -12,6 +12,7 @@ env.SConscript([ '$ICU38_DIR/using_icu38.scons', '$MEDIA_DIR/using_media.scons', '$NPAPI_DIR/using_npapi.scons', + '$PRINTING_DIR/using_printing.scons', '$SKIA_DIR/using_skia.scons', '$WEBKIT_DIR/build/WebKit/using_webkit.scons', ], {'env':env}) diff --git a/chrome/test/perf/perftests.scons b/chrome/test/perf/perftests.scons index fd404aa..031f386 100644 --- a/chrome/test/perf/perftests.scons +++ b/chrome/test/perf/perftests.scons @@ -26,6 +26,7 @@ env.ApplySConscript([ '$LIBXML_DIR/using_libxml.scons', '$LIBXSLT_DIR/using_libxslt.scons', '$MEDIA_DIR/using_media.scons', + '$PRINTING_DIR/using_printing.scons', '$SDCH_DIR/using_sdch.scons', '$SKIA_DIR/using_skia.scons', '$ZLIB_DIR/using_zlib.scons', diff --git a/chrome/test/unit/unit_tests.scons b/chrome/test/unit/unit_tests.scons index 70d2cc6..2c0ca9a 100644 --- a/chrome/test/unit/unit_tests.scons +++ b/chrome/test/unit/unit_tests.scons @@ -26,6 +26,7 @@ env.SConscript([ '$MEDIA_DIR/using_media.scons', '$NET_DIR/using_net.scons', '$NPAPI_DIR/using_npapi.scons', + '$PRINTING_DIR/using_printing.scons', '$SDCH_DIR/using_sdch.scons', '$SKIA_DIR/using_skia.scons', '$WEBKIT_DIR/build/WebKit/using_webkit.scons', diff --git a/webkit/glue/webframe.h b/webkit/glue/webframe.h index 9be5100..76b50c6 100644 --- a/webkit/glue/webframe.h +++ b/webkit/glue/webframe.h @@ -14,7 +14,6 @@ #include "webkit/glue/find_in_page_request.h" #include "webkit/glue/webscriptsource.h" -class PlatformContextSkia; class WebDataSource; class WebError; class WebRequest; @@ -355,29 +354,23 @@ class WebFrame { // The current scroll offset from the top of frame in pixels. virtual gfx::Size ScrollOffset() const = 0; - // Reformats the web page, i.e. the main frame and its subframes, for printing - // or for screen display, depending on |printing| argument. |page_width_min| - // and |page_width_max| are the minimum and maximum width, in pixels, that the - // layout can try to fit the whole content. |width| is the resulted choosen - // document width in pixel. - // Note: It fails if the main frame failed to load. It will succeed even if a - // child frame failed to load. - virtual bool SetPrintingMode(bool printing, - float page_width_min, - float page_width_max, - int* width) = 0; - - // Layouts the web page on paper. Calculates the rectangle of the web page - // each pages will "see". Then you can retrieve the exact view of a paper page - // with GetPageRect. - // Returns the number of printed pages computed. - virtual int ComputePageRects(const gfx::Size& page_size_px) = 0; - - // Retrieves the paper page's view of the web page. - virtual void GetPageRect(int page, gfx::Rect* page_size) const = 0; + // Reformats the web frame for printing. |page_size_px| is the page size in + // pixels. + // |width| is the resulting document width in pixel. + // |page_count| is the number of printed pages. + // Returns false if it fails. It'll fail if the main frame failed to load but + // will succeed even if a child frame failed to load. + virtual bool BeginPrint(const gfx::Size& page_size_px, + int* page_count) = 0; // Prints one page. |page| is 0-based. - virtual bool SpoolPage(int page, skia::PlatformCanvas* canvas) = 0; + // Returns the page shrinking factor calculated by webkit (usually between + // 1/1.25 and 1/2). Returns 0 if the page number is invalid or not in printing + // mode. + virtual float PrintPage(int page, skia::PlatformCanvas* canvas) = 0; + + // Reformats the web frame for screen display. + virtual void EndPrint() = 0; // Only for test_shell virtual int PendingFrameUnloadEventCount() const = 0; diff --git a/webkit/glue/webframe_impl.cc b/webkit/glue/webframe_impl.cc index 5ad4219..c6f8c4c 100644 --- a/webkit/glue/webframe_impl.cc +++ b/webkit/glue/webframe_impl.cc @@ -99,6 +99,7 @@ MSVC_PUSH_WARNING_LEVEL(0); #include "markup.h" #include "Page.h" #include "PlatformContextSkia.h" +#include "PrintContext.h" #include "RenderFrame.h" #if defined(OS_WIN) #include "RenderThemeChromiumWin.h" @@ -280,6 +281,42 @@ static void FrameContentAsPlainText(int max_chars, Frame* frame, } } +// Simple class to override some of PrintContext behavior. +class ChromePrintContext : public WebCore::PrintContext { + public: + ChromePrintContext(Frame* frame) + : PrintContext(frame), + printed_page_width_(0) { + } + void begin(float width) { + DCHECK(!printed_page_width_); + printed_page_width_ = width; + WebCore::PrintContext::begin(printed_page_width_); + } + // Spools the printed page, a subrect of m_frame. + // Skip the scale step. NativeTheme doesn't play well with scaling. Scaling + // is done browser side instead. + // Returns the scale to be applied. + float spoolPage(GraphicsContext& ctx, int pageNumber) { + IntRect pageRect = m_pageRects[pageNumber]; + float scale = printed_page_width_ / pageRect.width(); + + ctx.save(); + ctx.translate(static_cast<float>(-pageRect.x()), + static_cast<float>(-pageRect.y())); + ctx.clip(pageRect); + m_frame->view()->paintContents(&ctx, pageRect); + ctx.restore(); + return scale; + } + protected: + // Set when printing. + float printed_page_width_; + + private: + DISALLOW_COPY_AND_ASSIGN(ChromePrintContext); +}; + // WebFrameImpl ---------------------------------------------------------------- int WebFrameImpl::live_object_count_ = 0; @@ -300,8 +337,7 @@ MSVC_POP_WARNING() total_matchcount_(-1), frames_scoping_count_(-1), scoping_complete_(false), - next_invalidate_after_(0), - printing_(false) { + next_invalidate_after_(0) { StatsCounter(kWebFrameActiveCount).Increment(); live_object_count_++; } @@ -362,8 +398,8 @@ void WebFrameImpl::InternalLoadRequest(const WebRequest* request, // TODO(darin): Is this the best API to use here? It works and seems good, // but will it change out from under us? - String script = - decodeURLEscapeSequences(kurl.string().substring(sizeof("javascript:")-1)); + String script = decodeURLEscapeSequences( + kurl.string().substring(sizeof("javascript:")-1)); WebCore::ScriptValue result = frame_->loader()->executeScript(script, true); String scriptResult; if (result.getString(scriptResult) && @@ -789,8 +825,8 @@ void WebFrameImpl::BindToWindowObject(const std::wstring& name, JSC::ExecState* exec = window->globalExec(); JSC::Bindings::RootObject* root = frame_->script()->bindingRootObject(); ASSERT(exec); - JSC::RuntimeObjectImp* instance = JSC::Bindings::Instance::createRuntimeObject( - exec, JSC::Bindings::CInstance::create(object, root)); + JSC::RuntimeObjectImp* instance(JSC::Bindings::Instance::createRuntimeObject( + exec, JSC::Bindings::CInstance::create(object, root))); JSC::Identifier id(exec, key.latin1().data()); JSC::PutPropertySlot slot; window->put(exec, id, instance, slot); @@ -1701,15 +1737,6 @@ WebTextInput* WebFrameImpl::GetTextInput() { return webtextinput_impl_.get(); } -void WebFrameImpl::SetPrinting(bool printing, - float page_width_min, - float page_width_max) { - frame_->setPrinting(printing, - page_width_min, - page_width_max, - true); -} - bool WebFrameImpl::Visible() { return frame()->view()->visibleWidth() > 0 && frame()->view()->visibleHeight() > 0; @@ -1753,14 +1780,16 @@ PassRefPtr<Frame> WebFrameImpl::CreateChildFrame( // this child frame. HistoryItem* parent_item = frame_->loader()->currentHistoryItem(); FrameLoadType load_type = frame_->loader()->loadType(); - FrameLoadType child_load_type = WebCore::FrameLoadTypeRedirectWithLockedBackForwardList; + FrameLoadType child_load_type = + WebCore::FrameLoadTypeRedirectWithLockedBackForwardList; KURL new_url = request.resourceRequest().url(); // If we're moving in the backforward list, we might want to replace the // content of this child frame with whatever was there at that point. if (parent_item && parent_item->children().size() != 0 && isBackForwardLoadType(load_type)) { - HistoryItem* child_item = parent_item->childItemWithName(request.frameName()); + HistoryItem* child_item = + parent_item->childItemWithName(request.frameName()); if (child_item) { // Use the original URL to ensure we get all the side-effects, such as // onLoad handlers, of any redirects that happened. An example of where @@ -1847,78 +1876,29 @@ void WebFrameImpl::SetAllowsScrolling(bool flag) { frame_->view()->setCanHaveScrollbars(flag); } -bool WebFrameImpl::SetPrintingMode(bool printing, - float page_width_min, - float page_width_max, - int* width) { - // Make sure main frame is loaded. - WebCore::FrameView* view = frameview(); - if (!view) { - NOTREACHED(); - return false; - } - printing_ = printing; - if (printing) { - view->setScrollbarModes(WebCore::ScrollbarAlwaysOff, - WebCore::ScrollbarAlwaysOff); - } else { - view->setScrollbarModes(WebCore::ScrollbarAuto, - WebCore::ScrollbarAuto); - } +bool WebFrameImpl::BeginPrint(const gfx::Size& page_size_px, + int* page_count) { DCHECK_EQ(frame()->document()->isFrameSet(), false); - SetPrinting(printing, page_width_min, page_width_max); - if (!printing) - pages_.clear(); - - // The document width is well hidden. - if (width) { - WebCore::RenderObject* obj = frame()->document()->renderer(); - *width = WebCore::toRenderBox(obj)->width(); - } + print_context_.reset(new ChromePrintContext(frame())); + WebCore::FloatRect rect(0, 0, + static_cast<float>(page_size_px.width()), + static_cast<float>(page_size_px.height())); + print_context_->begin(rect.width()); + float page_height; + // We ignore the overlays calculation for now since they are generated in the + // browser. page_height is actually an output parameter. + print_context_->computePageRects(rect, 0, 0, 1.0, page_height); + if (page_count) + *page_count = print_context_->pageCount(); return true; } -int WebFrameImpl::ComputePageRects(const gfx::Size& page_size_px) { - if (!printing_ || - !frame() || - !frame()->document()) { - NOTREACHED(); - return 0; - } - // In Safari, they are using: - // (0,0) + soft margins top/left - // (phys width, phys height) - hard margins - - // soft margins top/left - soft margins right/bottom - // TODO(maruel): Weird. We don't do that. - // Everything is in pixels :( - // pages_ and page_height are actually output parameters. - int page_height; - WebCore::IntRect rect(0, 0, page_size_px.width(), page_size_px.height()); - computePageRectsForFrame(frame(), rect, 0, 0, 1.0, pages_, page_height); - return pages_.size(); -} - -void WebFrameImpl::GetPageRect(int page, gfx::Rect* page_size) const { - if (page < 0 || page >= static_cast<int>(pages_.size())) { - NOTREACHED(); - return; - } - *page_size = webkit_glue::FromIntRect(pages_[page]); -} - -bool WebFrameImpl::SpoolPage(int page, skia::PlatformCanvas* canvas) { +float WebFrameImpl::PrintPage(int page, skia::PlatformCanvas* canvas) { // Ensure correct state. - if (!printing_ || - page < 0 || - page >= static_cast<int>(pages_.size())) { - NOTREACHED(); - return false; - } - - if (!frame() || !frame()->document()) { + if (!print_context_.get() || page < 0 || !frame() || !frame()->document()) { NOTREACHED(); - return false; + return 0; } #if defined(OS_WIN) || defined(OS_LINUX) @@ -1929,12 +1909,14 @@ bool WebFrameImpl::SpoolPage(int page, skia::PlatformCanvas* canvas) { GraphicsContext spool(context); #endif - DCHECK(pages_[page].x() == 0); - // Offset to get the right square. - spool.translate(0, -static_cast<float>(pages_[page].y())); - // Make sure we're not printing the ScrollView (with scrollbars!) - frame()->view()->paintContents(&spool, pages_[page]); - return true; + return print_context_->spoolPage(spool, page); +} + +void WebFrameImpl::EndPrint() { + DCHECK(print_context_.get()); + if (print_context_.get()) + print_context_->end(); + print_context_.reset(NULL); } int WebFrameImpl::PendingFrameUnloadEventCount() const { diff --git a/webkit/glue/webframe_impl.h b/webkit/glue/webframe_impl.h index 96045e1..8684cb7 100644 --- a/webkit/glue/webframe_impl.h +++ b/webkit/glue/webframe_impl.h @@ -40,6 +40,7 @@ MSVC_PUSH_WARNING_LEVEL(0); MSVC_POP_WARNING(); class AltErrorPageResourceFetcher; +class ChromePrintContext; class WebDataSourceImpl; class WebErrorImpl; class WebHistoryItemImpl; @@ -157,7 +158,8 @@ class WebFrameImpl : public WebFrame, public base::RefCounted<WebFrameImpl> { virtual WebTextInput* GetTextInput(); - virtual bool ExecuteCoreCommandByName(const std::string& name, const std::string& value); + virtual bool ExecuteCoreCommandByName(const std::string& name, + const std::string& value); virtual bool IsCoreCommandEnabled(const std::string& name); virtual void AddMessageToConsole(const std::wstring& msg, @@ -167,19 +169,10 @@ class WebFrameImpl : public WebFrame, public base::RefCounted<WebFrameImpl> { virtual gfx::Size ScrollOffset() const; - virtual bool SetPrintingMode(bool printing, - float page_width_min, - float page_width_max, - int* width); - virtual int ComputePageRects(const gfx::Size& page_size_px); - virtual void GetPageRect(int page, gfx::Rect* page_size) const; - virtual bool SpoolPage(int page, skia::PlatformCanvas* canvas); - - // Reformats this frame for printing or for screen display, depending on - // |printing| flag. Acts recursively on inner frames. - // Note: It fails if the main frame failed to load. It will succeed even if a - // child frame failed to load. - void SetPrinting(bool printing, float page_width_min, float page_width_max); + virtual bool BeginPrint(const gfx::Size& page_size_px, + int* page_count); + virtual float PrintPage(int page, skia::PlatformCanvas* canvas); + virtual void EndPrint(); PassRefPtr<WebCore::Frame> CreateChildFrame( const WebCore::FrameLoadRequest&, @@ -245,12 +238,9 @@ class WebFrameImpl : public WebFrame, public base::RefCounted<WebFrameImpl> { // Sets whether the WebFrameImpl allows its document to be scrolled. // If the parameter is true, allow the document to be scrolled. - // Otherwise, disallow scrolling + // Otherwise, disallow scrolling. void SetAllowsScrolling(bool flag); - // Returns true if the frame CSS is in "printing" mode. - bool printing() const { return printing_; } - // Registers a listener for the specified user name input element. The // listener will receive notifications for blur and when autocomplete should // be triggered. @@ -411,11 +401,9 @@ class WebFrameImpl : public WebFrame, public base::RefCounted<WebFrameImpl> { // Clears the map of password listeners. void ClearPasswordListeners(); - // In "printing" mode. Used as a state check. - bool printing_; - - // For each printed page, the view of the document in pixels. - Vector<WebCore::IntRect> pages_; + // Valid between calls to BeginPrint() and EndPrint(). Containts the print + // information. Is used by PrintPage(). + scoped_ptr<ChromePrintContext> print_context_; // The input fields that are interested in edit events and their associated // listeners. |