summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormaruel@chromium.org <maruel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-19 17:36:22 +0000
committermaruel@chromium.org <maruel@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-03-19 17:36:22 +0000
commit88a3eccb5605fc9224ce59c76473b7aae2c31bc8 (patch)
tree9c31830256ada147c4f19ffb90659da3fb97fa3d
parentf3735c5dc0269579afc173d9e519243c305e1186 (diff)
downloadchromium_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.gyp2
-rw-r--r--chrome/renderer/render_view.cc150
-rw-r--r--chrome/renderer/render_view.h20
-rw-r--r--chrome/renderer/renderer.scons1
-rw-r--r--chrome/test/perf/perftests.scons1
-rw-r--r--chrome/test/unit/unit_tests.scons1
-rw-r--r--webkit/glue/webframe.h37
-rw-r--r--webkit/glue/webframe_impl.cc158
-rw-r--r--webkit/glue/webframe_impl.h34
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.