summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-21 22:30:10 +0000
committerkmadhusu@chromium.org <kmadhusu@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-12-21 22:30:10 +0000
commit15c2bb32e4b2a436e404695ee7b5ea564cc9c60b (patch)
tree3b5208034639c45ba114eb2d8b7c729ee38eeeef
parent6e74a3bcc45e25f4a249649953b5120324facf16 (diff)
downloadchromium_src-15c2bb32e4b2a436e404695ee7b5ea564cc9c60b.zip
chromium_src-15c2bb32e4b2a436e404695ee7b5ea564cc9c60b.tar.gz
chromium_src-15c2bb32e4b2a436e404695ee7b5ea564cc9c60b.tar.bz2
Refactor mac printing workflow.
To support print preview, made code changes to create a single metafile for the entire printing document. BUG=64121 TEST=printing works after code changes. Review URL: http://codereview.chromium.org/5892002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@69885 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/renderer_host/render_view_host.cc38
-rw-r--r--chrome/browser/renderer_host/render_view_host.h4
-rw-r--r--chrome/common/render_messages.h1
-rw-r--r--chrome/common/render_messages_internal.h11
-rw-r--r--chrome/common/render_messages_params.cc35
-rw-r--r--chrome/common/render_messages_params.h23
-rw-r--r--chrome/renderer/print_web_view_helper.cc83
-rw-r--r--chrome/renderer/print_web_view_helper.h26
-rw-r--r--chrome/renderer/print_web_view_helper_linux.cc6
-rw-r--r--chrome/renderer/print_web_view_helper_mac.mm149
-rw-r--r--printing/pdf_metafile_mac.cc11
-rw-r--r--printing/pdf_metafile_mac.h10
-rw-r--r--printing/pdf_metafile_mac_unittest.cc15
-rw-r--r--printing/printed_document_mac.cc2
14 files changed, 292 insertions, 122 deletions
diff --git a/chrome/browser/renderer_host/render_view_host.cc b/chrome/browser/renderer_host/render_view_host.cc
index 83b1f8c..5833296 100644
--- a/chrome/browser/renderer_host/render_view_host.cc
+++ b/chrome/browser/renderer_host/render_view_host.cc
@@ -53,6 +53,7 @@
#include "chrome/common/web_apps.h"
#include "gfx/native_widget_types.h"
#include "net/base/net_util.h"
+#include "printing/native_metafile.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFindOptions.h"
#include "webkit/glue/context_menu.h"
@@ -2256,25 +2257,38 @@ TabContents* RenderViewHost::GetOrCreatePrintPreviewTab() {
return NULL;
}
-void RenderViewHost::OnPagesReadyForPreview(int document_cookie,
- int fd_in_browser) {
+void RenderViewHost::OnPagesReadyForPreview(
+ const ViewHostMsg_DidPreviewDocument_Params& params) {
+#if defined(OS_MACOSX)
+ base::SharedMemory shared_buf(params.metafile_data_handle, true);
+ if (!shared_buf.Map(params.data_size)) {
+ NOTREACHED();
+ return;
+ }
+ scoped_ptr<printing::NativeMetafile> metafile(new printing::NativeMetafile());
+ if (!metafile->Init(shared_buf.memory(), params.data_size)) {
+ NOTREACHED();
+ return;
+ }
+
+ // TODO(kmadhusu): Add more functionality for the preview tab to access this
+ // |metafile| data.
+#endif
+
// Get/Create print preview tab.
TabContents* print_preview_tab = GetOrCreatePrintPreviewTab();
DCHECK(print_preview_tab);
- // TODO(kmadhusu): Function definition needs to be changed.
- // fd_in_browser should be the file descriptor of the metafile.
-
scoped_refptr<printing::PrinterQuery> printer_query;
- g_browser_process->print_job_manager()->PopPrinterQuery(document_cookie,
- &printer_query);
+ g_browser_process->print_job_manager()->PopPrinterQuery(
+ params.document_cookie, &printer_query);
if (printer_query.get()) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- NewRunnableMethod(printer_query.get(),
- &printing::PrinterQuery::StopWorker));
+ BrowserThread::PostTask(
+ BrowserThread::IO, FROM_HERE,
+ NewRunnableMethod(printer_query.get(),
+ &printing::PrinterQuery::StopWorker));
}
// Send the printingDone msg for now.
- Send(new ViewMsg_PrintingDone(routing_id(), -1, true));
+ Send(new ViewMsg_PrintingDone(routing_id(), params.document_cookie, true));
}
diff --git a/chrome/browser/renderer_host/render_view_host.h b/chrome/browser/renderer_host/render_view_host.h
index 4a23704..163039b 100644
--- a/chrome/browser/renderer_host/render_view_host.h
+++ b/chrome/browser/renderer_host/render_view_host.h
@@ -39,6 +39,7 @@ struct ContextMenuParams;
struct MediaPlayerAction;
struct ThumbnailScore;
struct ViewHostMsg_AccessibilityNotification_Params;
+struct ViewHostMsg_DidPreviewDocument_Params;
struct ViewHostMsg_DidPrintPage_Params;
struct ViewHostMsg_DomMessage_Params;
struct ViewHostMsg_PageHasOSDD_Type;
@@ -733,7 +734,8 @@ class RenderViewHost : public RenderWidgetHost {
const SkBitmap& thumbnail);
void OnScriptEvalResponse(int id, const ListValue& result);
void OnUpdateContentRestrictions(int restrictions);
- void OnPagesReadyForPreview(int document_cookie, int fd_in_browser);
+ void OnPagesReadyForPreview(
+ const ViewHostMsg_DidPreviewDocument_Params& params);
#if defined(OS_MACOSX)
void OnMsgShowPopup(const ViewHostMsg_ShowPopup_Params& params);
diff --git a/chrome/common/render_messages.h b/chrome/common/render_messages.h
index 06e597c..e06a667 100644
--- a/chrome/common/render_messages.h
+++ b/chrome/common/render_messages.h
@@ -100,6 +100,7 @@ struct ViewHostMsg_Resource_Request;
struct ViewMsg_Print_Params;
struct ViewMsg_PrintPage_Params;
struct ViewMsg_PrintPages_Params;
+struct ViewHostMsg_DidPreviewDocument_Params;
struct ViewHostMsg_DidPrintPage_Params;
struct ViewHostMsg_Audio_CreateStream_Params;
struct ViewHostMsg_ShowPopup_Params;
diff --git a/chrome/common/render_messages_internal.h b/chrome/common/render_messages_internal.h
index 01fc555..f94f1ed 100644
--- a/chrome/common/render_messages_internal.h
+++ b/chrome/common/render_messages_internal.h
@@ -170,12 +170,11 @@ IPC_MESSAGE_ROUTED2(ViewMsg_PrintingDone,
// requested pages for print preview.
IPC_MESSAGE_ROUTED0(ViewMsg_PrintPreview)
-// Sends back to the browser the rendered "printed page" for preview that was
-// requested by a ViewMsg_PrintPage message or from scripted printing. The
-// memory handle in this message is already valid in the browser process.
-IPC_MESSAGE_ROUTED2(ViewHostMsg_PagesReadyForPreview,
- int /* document cookie */,
- int /* fd in browser */)
+// Sends back to the browser the rendered "printed document" for preview that
+// was requested by a ViewMsg_PrintPreview message. The memory handle in this
+// message is already valid in the browser process.
+IPC_MESSAGE_ROUTED1(ViewHostMsg_PagesReadyForPreview,
+ ViewHostMsg_DidPreviewDocument_Params /* params */)
// Tells the renderer to dump as much memory as it can, perhaps because we
// have memory pressure or the renderer is (or will be) paged out. This
diff --git a/chrome/common/render_messages_params.cc b/chrome/common/render_messages_params.cc
index 618ca8e..7fab193 100644
--- a/chrome/common/render_messages_params.cc
+++ b/chrome/common/render_messages_params.cc
@@ -118,6 +118,21 @@ ViewMsg_PrintPages_Params::ViewMsg_PrintPages_Params() {
ViewMsg_PrintPages_Params::~ViewMsg_PrintPages_Params() {
}
+ViewHostMsg_DidPreviewDocument_Params::ViewHostMsg_DidPreviewDocument_Params()
+ : data_size(0) {
+#if defined(OS_WIN)
+ // Initialize |metafile_data_handle| only on Windows because it maps
+ // base::SharedMemoryHandle to HANDLE. We do not need to initialize this
+ // variable on Posix because it maps base::SharedMemoryHandle to
+ // FileDescriptior, which has the default constructor.
+ metafile_data_handle = INVALID_HANDLE_VALUE;
+#endif
+}
+
+ViewHostMsg_DidPreviewDocument_Params::
+ ~ViewHostMsg_DidPreviewDocument_Params() {
+}
+
ViewHostMsg_DidPrintPage_Params::ViewHostMsg_DidPrintPage_Params()
: data_size(0),
document_cookie(0),
@@ -995,6 +1010,26 @@ void ParamTraits<ViewMsg_PrintPages_Params>::Log(const param_type& p,
l->append("<ViewMsg_PrintPages_Params>");
}
+void ParamTraits<ViewHostMsg_DidPreviewDocument_Params>::Write(Message* m,
+ const param_type& p) {
+ WriteParam(m, p.metafile_data_handle);
+ WriteParam(m, p.data_size);
+ WriteParam(m, p.document_cookie);
+}
+
+bool ParamTraits<ViewHostMsg_DidPreviewDocument_Params>::Read(const Message* m,
+ void** iter,
+ param_type* p) {
+ return ReadParam(m, iter, &p->metafile_data_handle) &&
+ ReadParam(m, iter, &p->data_size) &&
+ ReadParam(m, iter, &p->document_cookie);
+}
+
+void ParamTraits<ViewHostMsg_DidPreviewDocument_Params>::Log(
+ const param_type& p, std::string* l) {
+ l->append("<ViewHostMsg_DidPreviewDocument_Params>");
+}
+
void ParamTraits<ViewHostMsg_DidPrintPage_Params>::Write(Message* m,
const param_type& p) {
WriteParam(m, p.metafile_data_handle);
diff --git a/chrome/common/render_messages_params.h b/chrome/common/render_messages_params.h
index 911e3ae..97817d2 100644
--- a/chrome/common/render_messages_params.h
+++ b/chrome/common/render_messages_params.h
@@ -552,6 +552,21 @@ struct ViewMsg_PrintPages_Params {
std::vector<int> pages;
};
+//Parameters to describe a rendered document.
+struct ViewHostMsg_DidPreviewDocument_Params {
+ ViewHostMsg_DidPreviewDocument_Params();
+ ~ViewHostMsg_DidPreviewDocument_Params();
+
+ // A shared memory handle to metafile data.
+ base::SharedMemoryHandle metafile_data_handle;
+
+ // Size of metafile data.
+ uint32 data_size;
+
+ // Cookie for the document to ensure correctness.
+ int document_cookie;
+};
+
// Parameters to describe a rendered page.
struct ViewHostMsg_DidPrintPage_Params {
ViewHostMsg_DidPrintPage_Params();
@@ -986,6 +1001,14 @@ struct ParamTraits<ViewMsg_PrintPages_Params> {
};
template <>
+struct ParamTraits<ViewHostMsg_DidPreviewDocument_Params> {
+ typedef ViewHostMsg_DidPreviewDocument_Params param_type;
+ static void Write(Message* m, const param_type& p);
+ static bool Read(const Message* m, void** iter, param_type* p);
+ static void Log(const param_type& p, std::string* l);
+};
+
+template <>
struct ParamTraits<ViewHostMsg_DidPrintPage_Params> {
typedef ViewHostMsg_DidPrintPage_Params param_type;
static void Write(Message* m, const param_type& p);
diff --git a/chrome/renderer/print_web_view_helper.cc b/chrome/renderer/print_web_view_helper.cc
index 751b9ec..d5b0a79 100644
--- a/chrome/renderer/print_web_view_helper.cc
+++ b/chrome/renderer/print_web_view_helper.cc
@@ -6,6 +6,7 @@
#include "app/l10n_util.h"
#include "base/logging.h"
+#include "base/process_util.h"
#include "base/utf_string_conversions.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/render_messages_params.h"
@@ -149,7 +150,11 @@ void PrintWebViewHelper::Print(WebFrame* frame,
// Render Pages for printing.
if (!print_cancelled) {
- RenderPagesForPrint(frame);
+ if (is_preview_)
+ RenderPagesForPreview(frame);
+ else
+ RenderPagesForPrint(frame);
+
// Reset cancel counter on first successful print.
user_cancelled_scripted_print_count_ = 0;
return; // All went well.
@@ -227,11 +232,9 @@ void PrintWebViewHelper::PrintPages(const ViewMsg_PrintPages_Params& params,
frame->view());
int page_count = prep_frame_view.GetExpectedPageCount();
- if (!is_preview_) {
- Send(new ViewHostMsg_DidGetPrintedPagesCount(routing_id(),
- printParams.document_cookie,
- page_count));
- }
+ Send(new ViewHostMsg_DidGetPrintedPagesCount(routing_id(),
+ printParams.document_cookie,
+ page_count));
if (!page_count)
return;
@@ -251,13 +254,6 @@ void PrintWebViewHelper::PrintPages(const ViewMsg_PrintPages_Params& params,
PrintPage(page_params, canvas_size, frame);
}
}
-
- if (is_preview_) {
- // TODO(kmadhusu) Put this in the right place when fixing bug 64121.
- Send(new ViewHostMsg_PagesReadyForPreview(routing_id(),
- printParams.document_cookie,
- -1));
- }
}
#endif // OS_MACOSX || OS_WIN
@@ -359,14 +355,24 @@ void PrintWebViewHelper::UpdatePrintableSizeInPrintParameters(
WebFrame* frame, ViewMsg_Print_Params* params) {
double content_width_in_points;
double content_height_in_points;
+ double margin_top_in_points;
+ double margin_right_in_points;
+ double margin_bottom_in_points;
+ double margin_left_in_points;
PrepareFrameAndViewForPrint prepare(*params, frame, frame->view());
PrintWebViewHelper::GetPageSizeAndMarginsInPoints(frame, 0, *params,
- &content_width_in_points,
- &content_height_in_points,
- NULL, NULL, NULL, NULL);
+ &content_width_in_points, &content_height_in_points,
+ &margin_top_in_points, &margin_right_in_points,
+ &margin_bottom_in_points, &margin_left_in_points);
+
#if defined(OS_MACOSX)
- params->printable_size = gfx::Size(
- static_cast<int>(content_width_in_points),
+ params->page_size = gfx::Size(
+ static_cast<int>(content_width_in_points +
+ margin_left_in_points + margin_right_in_points),
+ static_cast<int>(content_height_in_points +
+ margin_top_in_points + margin_bottom_in_points));
+
+ params->printable_size = gfx::Size(static_cast<int>(content_width_in_points),
static_cast<int>(content_height_in_points));
#else
params->printable_size = gfx::Size(
@@ -375,6 +381,8 @@ void PrintWebViewHelper::UpdatePrintableSizeInPrintParameters(
static_cast<int>(ConvertUnitDouble(
content_height_in_points, printing::kPointsPerInch, params->dpi)));
#endif
+ params->margin_top = static_cast<int>(margin_top_in_points);
+ params->margin_left = static_cast<int>(margin_left_in_points);
}
bool PrintWebViewHelper::InitPrintSettings(WebFrame* frame) {
@@ -455,3 +463,42 @@ void PrintWebViewHelper::RenderPagesForPrint(WebFrame *frame) {
PrintPages(print_settings, frame);
}
}
+
+void PrintWebViewHelper::RenderPagesForPreview(WebFrame *frame) {
+ ViewMsg_PrintPages_Params print_settings = *print_pages_params_;
+ ViewHostMsg_DidPreviewDocument_Params print_params;
+ CreatePreviewDocument(print_settings, frame, &print_params);
+ Send(new ViewHostMsg_PagesReadyForPreview(routing_id(), print_params));
+}
+
+#if !defined(OS_MACOSX)
+void PrintWebViewHelper::CreatePreviewDocument(
+ const ViewMsg_PrintPages_Params& params,
+ WebFrame* frame,
+ ViewHostMsg_DidPreviewDocument_Params* print_params) {
+ // TODO(kmadhusu): Implement this function for windows & linux.
+ print_params->document_cookie = params.params.document_cookie;
+}
+#endif
+
+#if defined(OS_MACOSX)
+bool PrintWebViewHelper::CopyMetafileDataToSharedMem(
+ printing::NativeMetafile* metafile,
+ base::SharedMemoryHandle* shared_mem_handle) {
+ uint32 buf_size = metafile->GetDataSize();
+ base::SharedMemoryHandle mem_handle;
+ if (Send(new ViewHostMsg_AllocateSharedMemoryBuffer(buf_size, &mem_handle))) {
+ if (base::SharedMemory::IsHandleValid(mem_handle)) {
+ base::SharedMemory shared_buf(mem_handle, false);
+ if (shared_buf.Map(buf_size)) {
+ metafile->GetData(shared_buf.memory(), buf_size);
+ shared_buf.GiveToProcess(base::GetCurrentProcessHandle(),
+ shared_mem_handle);
+ return true;
+ }
+ }
+ }
+ NOTREACHED();
+ return false;
+}
+#endif
diff --git a/chrome/renderer/print_web_view_helper.h b/chrome/renderer/print_web_view_helper.h
index 5fee3b9..c473e72 100644
--- a/chrome/renderer/print_web_view_helper.h
+++ b/chrome/renderer/print_web_view_helper.h
@@ -11,9 +11,14 @@
#include "base/scoped_ptr.h"
#include "base/time.h"
#include "gfx/size.h"
+#include "printing/native_metafile.h"
#include "third_party/WebKit/WebKit/chromium/public/WebFrameClient.h"
#include "third_party/WebKit/WebKit/chromium/public/WebViewClient.h"
+#if defined(OS_MACOSX)
+#include "base/shared_memory.h"
+#endif // defined(OS_MACOSX)
+
namespace gfx {
class Size;
}
@@ -22,17 +27,11 @@ namespace IPC {
class Message;
}
-#if defined(USE_X11)
-namespace printing {
-class PdfPsMetafile;
-typedef PdfPsMetafile NativeMetafile;
-}
-#endif
-
class RenderView;
struct ViewMsg_Print_Params;
struct ViewMsg_PrintPage_Params;
struct ViewMsg_PrintPages_Params;
+struct ViewHostMsg_DidPreviewDocument_Params;
// Class that calls the Begin and End print functions on the frame and changes
// the size of the view temporarily to support full page printing..
@@ -147,6 +146,19 @@ class PrintWebViewHelper : public WebKit::WebViewClient,
// Render the frame for printing.
void RenderPagesForPrint(WebKit::WebFrame* frame);
+ // Render the frame for preview.
+ void RenderPagesForPreview(WebKit::WebFrame* frame);
+ void CreatePreviewDocument(const ViewMsg_PrintPages_Params& params,
+ WebKit::WebFrame* frame,
+ ViewHostMsg_DidPreviewDocument_Params* print_params);
+#if defined(OS_MACOSX)
+ void RenderPage(const gfx::Size& page_size, const gfx::Point& content_origin,
+ const float& scale_factor, int page_number,
+ WebKit::WebFrame* frame, printing::NativeMetafile* metafile);
+ bool CopyMetafileDataToSharedMem(printing::NativeMetafile* metafile,
+ base::SharedMemoryHandle* shared_mem_handle);
+#endif
+
RenderView* render_view_;
WebKit::WebView* print_web_view_;
scoped_ptr<ViewMsg_PrintPages_Params> print_pages_params_;
diff --git a/chrome/renderer/print_web_view_helper_linux.cc b/chrome/renderer/print_web_view_helper_linux.cc
index 4624db1..06e98b2 100644
--- a/chrome/renderer/print_web_view_helper_linux.cc
+++ b/chrome/renderer/print_web_view_helper_linux.cc
@@ -52,12 +52,6 @@ void PrintWebViewHelper::PrintPages(const ViewMsg_PrintPages_Params& params,
metafile.Close();
int fd_in_browser = -1;
- if (is_preview_) {
- Send(new ViewHostMsg_PagesReadyForPreview(routing_id(),
- params.params.document_cookie,
- fd_in_browser));
- return;
- }
// Get the size of the resulting metafile.
uint32 buf_size = metafile.GetDataSize();
DCHECK_GT(buf_size, 0u);
diff --git a/chrome/renderer/print_web_view_helper_mac.mm b/chrome/renderer/print_web_view_helper_mac.mm
index 77b8972..592ff38 100644
--- a/chrome/renderer/print_web_view_helper_mac.mm
+++ b/chrome/renderer/print_web_view_helper_mac.mm
@@ -8,7 +8,6 @@
#include "app/l10n_util.h"
#include "base/logging.h"
-#include "base/process_util.h"
#include "chrome/common/render_messages.h"
#include "chrome/common/render_messages_params.h"
#include "chrome/renderer/render_view.h"
@@ -28,80 +27,108 @@ void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params,
const gfx::Size& canvas_size,
WebFrame* frame) {
printing::NativeMetafile metafile;
- CGContextRef context = metafile.Init();
+ if (!metafile.Init())
+ return;
float scale_factor = frame->getPrintPageShrink(params.page_number);
- double content_width_in_points;
- double content_height_in_points;
- double margin_top_in_points;
- double margin_right_in_points;
- double margin_bottom_in_points;
- double margin_left_in_points;
- GetPageSizeAndMarginsInPoints(frame,
- params.page_number,
- params.params,
- &content_width_in_points,
- &content_height_in_points,
- &margin_top_in_points,
- &margin_right_in_points,
- &margin_bottom_in_points,
- &margin_left_in_points);
- metafile.StartPage(content_width_in_points,
- content_height_in_points,
- scale_factor);
-
- // printPage can create autoreleased references to |canvas|. PDF contexts
- // don't write all their data until they are destroyed, so we need to make
- // certain that there are no lingering references.
- NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
- frame->printPage(params.page_number, context);
- [pool release];
+ double width = params.params.printable_size.width();
+ double height = params.params.printable_size.height();
+ int page_number = params.page_number;
+
+ // Render page for printing.
+ gfx::Point origin(0.0f, 0.0f);
+ RenderPage(params.params.printable_size, origin, scale_factor, page_number,
+ frame, &metafile);
- metafile.FinishPage();
metafile.Close();
+ double margin_left = params.params.margin_left;
+ double margin_top = params.params.margin_top;
+
// Get the size of the compiled metafile.
ViewHostMsg_DidPrintPage_Params page_params;
page_params.data_size = 0;
- page_params.page_number = params.page_number;
+ page_params.page_number = page_number;
page_params.document_cookie = params.params.document_cookie;
page_params.actual_shrink = scale_factor;
- base::SharedMemory shared_buf;
-
- page_params.page_size = gfx::Size(
- static_cast<int>(content_width_in_points +
- margin_left_in_points + margin_right_in_points),
- static_cast<int>(content_height_in_points +
- margin_top_in_points + margin_bottom_in_points));
- page_params.content_area = gfx::Rect(
- static_cast<int>(margin_left_in_points),
- static_cast<int>(margin_top_in_points),
- static_cast<int>(content_width_in_points),
- static_cast<int>(content_height_in_points));
+
+ page_params.page_size = params.params.page_size;
+ page_params.content_area = gfx::Rect(margin_left, margin_top, width, height);
// Ask the browser to create the shared memory for us.
- uint32 buf_size = metafile.GetDataSize();
- base::SharedMemoryHandle shared_mem_handle;
- if (Send(new ViewHostMsg_AllocateSharedMemoryBuffer(buf_size,
- &shared_mem_handle))) {
- if (base::SharedMemory::IsHandleValid(shared_mem_handle)) {
- base::SharedMemory shared_buf(shared_mem_handle, false);
- if (shared_buf.Map(buf_size)) {
- metafile.GetData(shared_buf.memory(), buf_size);
- page_params.data_size = buf_size;
- shared_buf.GiveToProcess(base::GetCurrentProcessHandle(),
- &(page_params.metafile_data_handle));
- } else {
- NOTREACHED() << "Map failed";
- }
- } else {
- NOTREACHED() << "Browser failed to allocate shared memory";
+ if (!CopyMetafileDataToSharedMem(&metafile,
+ &(page_params.metafile_data_handle))) {
+ NOTREACHED();
+ return;
+ }
+
+ page_params.data_size = metafile.GetDataSize();
+ Send(new ViewHostMsg_DidPrintPage(routing_id(), page_params));
+}
+
+void PrintWebViewHelper::CreatePreviewDocument(
+ const ViewMsg_PrintPages_Params& params,
+ WebFrame* frame,
+ ViewHostMsg_DidPreviewDocument_Params* print_params) {
+ ViewMsg_Print_Params printParams = params.params;
+ UpdatePrintableSizeInPrintParameters(frame, &printParams);
+
+ PrepareFrameAndViewForPrint prep_frame_view(printParams,
+ frame, frame->view());
+ int page_count = prep_frame_view.GetExpectedPageCount();
+
+ if (!page_count)
+ return;
+
+ float scale_factor = frame->getPrintPageShrink(0);
+ double originX = printParams.margin_left;
+ double originY = printParams.margin_top;
+
+ printing::NativeMetafile metafile;
+ if (!metafile.Init())
+ return;
+
+ gfx::Point origin(originX, originY);
+
+ if (params.pages.empty()) {
+ for (int i = 0; i < page_count; ++i) {
+ RenderPage(printParams.page_size, origin, scale_factor, i, frame,
+ &metafile);
}
} else {
- NOTREACHED() << "Browser allocation request message failed";
+ for (size_t i = 0; i < params.pages.size(); ++i) {
+ if (params.pages[i] >= page_count)
+ break;
+ RenderPage(printParams.page_size, origin, scale_factor,
+ static_cast<int>(params.pages[i]), frame, &metafile);
+ }
}
-
- if (!is_preview_)
- Send(new ViewHostMsg_DidPrintPage(routing_id(), page_params));
+ metafile.Close();
+ // Ask the browser to create the shared memory for us.
+ if (!CopyMetafileDataToSharedMem(&metafile,
+ &(print_params->metafile_data_handle))) {
+ NOTREACHED();
+ return;
+ }
+ print_params->document_cookie = params.params.document_cookie;
+ print_params->data_size = metafile.GetDataSize();
}
+void PrintWebViewHelper::RenderPage(
+ const gfx::Size& page_size, const gfx::Point& content_origin,
+ const float& scale_factor, int page_number, WebFrame* frame,
+ printing::NativeMetafile* metafile) {
+ CGContextRef context = metafile->StartPage(page_size, content_origin,
+ scale_factor);
+ DCHECK(context);
+
+ // printPage can create autoreleased references to |context|. PDF contexts
+ // don't write all their data until they are destroyed, so we need to make
+ // certain that there are no lingering references.
+ NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
+ frame->printPage(page_number, context);
+ [pool release];
+
+ // Done printing. Close the device context to retrieve the compiled metafile.
+ metafile->FinishPage();
+}
diff --git a/printing/pdf_metafile_mac.cc b/printing/pdf_metafile_mac.cc
index d09721f..2533205 100644
--- a/printing/pdf_metafile_mac.cc
+++ b/printing/pdf_metafile_mac.cc
@@ -59,10 +59,14 @@ bool PdfMetafile::Init(const void* src_buffer, uint32 src_buffer_size) {
return true;
}
-void PdfMetafile::StartPage(double width, double height, double scale_factor) {
+CGContextRef PdfMetafile::StartPage(const gfx::Size& page_size,
+ const gfx::Point& content_origin, const float& scale_factor) {
DCHECK(context_.get());
DCHECK(!page_is_open_);
+ double height = page_size.height();
+ double width = page_size.width();
+
CGRect bounds = CGRectMake(0, 0, width, height);
CGContextBeginPage(context_, &bounds);
page_is_open_ = true;
@@ -71,6 +75,11 @@ void PdfMetafile::StartPage(double width, double height, double scale_factor) {
// Flip the context.
CGContextTranslateCTM(context_, 0, height);
CGContextScaleCTM(context_, scale_factor, -scale_factor);
+
+ // Move the context to origin.
+ CGContextTranslateCTM(context_, content_origin.x(), content_origin.y());
+
+ return context_.get();
}
void PdfMetafile::FinishPage() {
diff --git a/printing/pdf_metafile_mac.h b/printing/pdf_metafile_mac.h
index 8872d99..38be634 100644
--- a/printing/pdf_metafile_mac.h
+++ b/printing/pdf_metafile_mac.h
@@ -13,6 +13,8 @@
namespace gfx {
class Rect;
+class Size;
+class Point;
}
class FilePath;
@@ -38,9 +40,11 @@ class PdfMetafile {
// Initializes a copy of metafile from PDF data. Returns true on success.
bool Init(const void* src_buffer, uint32 src_buffer_size);
- // Prepares a new pdf page with the given width and height and a scale
- // factor to use for the drawing.
- void StartPage(double width, double height, double scale_factor);
+ // Prepares a new pdf page at specified |content_origin| with the given
+ // |page_size| and a |scale_factor| to use for the drawing.
+ CGContextRef StartPage(const gfx::Size& page_size,
+ const gfx::Point& content_origin,
+ const float& scale_factor);
// Closes the current page.
void FinishPage();
diff --git a/printing/pdf_metafile_mac_unittest.cc b/printing/pdf_metafile_mac_unittest.cc
index fdf833c..c72b265 100644
--- a/printing/pdf_metafile_mac_unittest.cc
+++ b/printing/pdf_metafile_mac_unittest.cc
@@ -15,15 +15,18 @@
TEST(PdfMetafileTest, Pdf) {
// Test in-renderer constructor.
printing::PdfMetafile pdf;
- CGContextRef context = pdf.Init();
- EXPECT_TRUE(context != NULL);
+ EXPECT_TRUE(pdf.Init() != NULL);
- // Render page 1.
- pdf.StartPage(540, 720, 1.25);
+ // Render page 1 at origin (10.0, 10.0).
+ gfx::Point origin_1(10.0f, 10.0f);
+ gfx::Size size_1(540, 720);
+ pdf.StartPage(size_1, origin_1, 1.25);
pdf.FinishPage();
- // Render page 2.
- pdf.StartPage(720, 540, 2.0);
+ // Render page 2 at origin (10.0, 10.0).
+ gfx::Point origin_2(10.0f, 10.0f);
+ gfx::Size size_2(720, 540);
+ pdf.StartPage(size_2, origin_2, 2.0);
pdf.FinishPage();
pdf.Close();
diff --git a/printing/printed_document_mac.cc b/printing/printed_document_mac.cc
index d429109..3c5a401 100644
--- a/printing/printed_document_mac.cc
+++ b/printing/printed_document_mac.cc
@@ -34,7 +34,7 @@ void PrintedDocument::RenderPrintedPage(
// Each NativeMetafile is a one-page PDF, and pages use 1-based indexing.
const int page_number = 1;
metafile->RenderPage(page_number, context, content_area.ToCGRect(),
- true, false, false, false);
+ false, false, false, false);
// TODO(stuartmorgan): Print the header and footer.
}