Skip to content

Commit

Permalink
Unifying NativeMetafile class interface (as much as possible) for Lin…
Browse files Browse the repository at this point in the history
…ux, Mac, Win

BUG=NONE
TEST=NONE

Review URL: http://codereview.chromium.org/6611032

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@78320 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
dpapad@chromium.org committed Mar 16, 2011
1 parent 0da15e5 commit 8f17cd3
Show file tree
Hide file tree
Showing 22 changed files with 363 additions and 535 deletions.
13 changes: 4 additions & 9 deletions chrome/browser/printing/print_dialog_gtk.cc
Original file line number Diff line number Diff line change
Expand Up @@ -156,15 +156,10 @@ void PrintDialogGtk::SaveDocumentToDisk(const NativeMetafile* metafile,
error = true;
}

if (!error) {
base::FileDescriptor temp_file_fd;
temp_file_fd.fd = open(path_to_pdf_.value().c_str(), O_WRONLY);
temp_file_fd.auto_close = true;
if (!metafile->SaveTo(temp_file_fd)) {
LOG(ERROR) << "Saving metafile failed";
file_util::Delete(path_to_pdf_, false);
error = true;
}
if (!error && !metafile->SaveTo(path_to_pdf_)) {
LOG(ERROR) << "Saving metafile failed";
file_util::Delete(path_to_pdf_, false);
error = true;
}

// Done saving, let PrintDialogGtk::PrintDocument() continue.
Expand Down
8 changes: 4 additions & 4 deletions chrome/common/common_param_traits_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ TEST(IPCMessageTest, Metafile) {
RECT test_rect = {0, 0, 100, 100};
// Create a metafile using the screen DC as a reference.
metafile->CreateDc(NULL, NULL);
metafile->CloseDc();
metafile->Close();

IPC::Message msg(1, 2, IPC::Message::PRIORITY_NORMAL);
IPC::ParamTraits<printing::NativeMetafile>::Write(&msg, *metafile);
Expand All @@ -254,9 +254,9 @@ TEST(IPCMessageTest, Metafile) {
&msg, &iter, output.get()));

EXPECT_EQ(metafile->GetDataSize(), output->GetDataSize());
EXPECT_EQ(metafile->GetBounds(), output->GetBounds());
EXPECT_EQ(::GetDeviceCaps(metafile->hdc(), LOGPIXELSX),
::GetDeviceCaps(output->hdc(), LOGPIXELSX));
EXPECT_EQ(metafile->GetPageBounds(1), output->GetPageBounds(1));
EXPECT_EQ(::GetDeviceCaps(metafile->context(), LOGPIXELSX),
::GetDeviceCaps(output->context(), LOGPIXELSX));

// Also test the corrupt case.
IPC::Message bad_msg(1, 2, IPC::Message::PRIORITY_NORMAL);
Expand Down
4 changes: 2 additions & 2 deletions chrome/plugin/webplugin_delegate_stub.cc
Original file line number Diff line number Diff line change
Expand Up @@ -277,10 +277,10 @@ void WebPluginDelegateStub::OnPrint(base::SharedMemoryHandle* shared_memory,
NOTREACHED();
return;
}
HDC hdc = metafile->hdc();
HDC hdc = metafile->context();
skia::PlatformDevice::InitializeDC(hdc);
delegate_->Print(hdc);
if (!metafile->CloseDc()) {
if (!metafile->Close()) {
NOTREACHED();
return;
}
Expand Down
13 changes: 8 additions & 5 deletions chrome/renderer/print_web_view_helper_linux.cc
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void PrintWebViewHelper::PrintPages(const ViewMsg_PrintPages_Params& params,
&sequence_number))) {
return;
}
if (!metafile->SaveTo(fd))
if (!metafile->SaveToFD(fd))
return;

// Tell the browser we've finished writing the file.
Expand Down Expand Up @@ -214,12 +214,15 @@ void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params,
&margin_bottom_in_points,
&margin_left_in_points);

gfx::Size page_size(
content_width_in_points + margin_right_in_points +
margin_left_in_points,
content_height_in_points + margin_top_in_points +
margin_bottom_in_points);

cairo_t* cairo_context =
metafile->StartPage(content_width_in_points,
content_height_in_points,
metafile->StartPage(page_size,
margin_top_in_points,
margin_right_in_points,
margin_bottom_in_points,
margin_left_in_points);
if (!cairo_context)
return;
Expand Down
20 changes: 10 additions & 10 deletions chrome/renderer/print_web_view_helper_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params,
scoped_ptr<printing::NativeMetafile> metafile(
printing::NativeMetafileFactory::CreateMetafile());
metafile->CreateDc(NULL, NULL);
DCHECK(metafile->hdc());
skia::PlatformDevice::InitializeDC(metafile->hdc());
DCHECK(metafile->context());
skia::PlatformDevice::InitializeDC(metafile->context());

int page_number = params.page_number;

Expand All @@ -85,7 +85,7 @@ void PrintWebViewHelper::PrintPage(const ViewMsg_PrintPage_Params& params,
RenderPage(params.params, &scale_factor, page_number, frame, &metafile);

// Close the device context to retrieve the compiled metafile.
if (!metafile->CloseDc())
if (!metafile->Close())
NOTREACHED();

// Get the size of the compiled metafile.
Expand Down Expand Up @@ -140,8 +140,8 @@ void PrintWebViewHelper::CreatePreviewDocument(
scoped_ptr<printing::NativeMetafile> metafile(
printing::NativeMetafileFactory::CreateMetafile());
metafile->CreateDc(NULL, NULL);
DCHECK(metafile->hdc());
skia::PlatformDevice::InitializeDC(metafile->hdc());
DCHECK(metafile->context());
skia::PlatformDevice::InitializeDC(metafile->context());

// Calculate the dpi adjustment.
float shrink = static_cast<float>(params.params.desired_dpi /
Expand All @@ -163,7 +163,7 @@ void PrintWebViewHelper::CreatePreviewDocument(
}

// Close the device context to retrieve the compiled metafile.
if (!metafile->CloseDc())
if (!metafile->Close())
NOTREACHED();

// Get the size of the compiled metafile.
Expand Down Expand Up @@ -194,7 +194,7 @@ void PrintWebViewHelper::CreatePreviewDocument(
void PrintWebViewHelper::RenderPage(
const ViewMsg_Print_Params& params, float* scale_factor, int page_number,
WebFrame* frame, scoped_ptr<printing::NativeMetafile>* metafile) {
HDC hdc = (*metafile)->hdc();
HDC hdc = (*metafile)->context();
DCHECK(hdc);

double content_width_in_points;
Expand Down Expand Up @@ -259,7 +259,7 @@ void PrintWebViewHelper::RenderPage(
static_cast<skia::VectorPlatformDevice*>(canvas.getDevice());
if (platform_device->alpha_blend_used() && !params.supports_alpha_blend) {
// Close the device context to retrieve the compiled metafile.
if (!(*metafile)->CloseDc())
if (!(*metafile)->Close())
NOTREACHED();

scoped_ptr<printing::NativeMetafile> metafile2(
Expand All @@ -284,11 +284,11 @@ void PrintWebViewHelper::RenderPage(
FillRect(bitmap_dc, &rect, whiteBrush);

metafile2->CreateDc(NULL, NULL);
HDC hdc = metafile2->hdc();
HDC hdc = metafile2->context();
DCHECK(hdc);
skia::PlatformDevice::InitializeDC(hdc);

RECT metafile_bounds = (*metafile)->GetBounds().ToRECT();
RECT metafile_bounds = (*metafile)->GetPageBounds(1).ToRECT();
// Process the old metafile, placing all non-AlphaBlend calls into the
// new metafile, and copying the results of all the AlphaBlend calls
// from the bitmap DC.
Expand Down
10 changes: 5 additions & 5 deletions chrome/utility/utility_thread.cc
Original file line number Diff line number Diff line change
Expand Up @@ -263,12 +263,12 @@ bool UtilityThread::RenderPDFToWinMetafile(
// Since we created the metafile using the screen DPI (but we actually want
// the PDF DLL to print using the passed in render_dpi, we apply the following
// transformation.
SetGraphicsMode(metafile->hdc(), GM_ADVANCED);
SetGraphicsMode(metafile->context(), GM_ADVANCED);
XFORM xform = {0};
int screen_dpi = GetDeviceCaps(GetDC(NULL), LOGPIXELSX);
xform.eM11 = xform.eM22 =
static_cast<float>(screen_dpi) / static_cast<float>(render_dpi);
ModifyWorldTransform(metafile->hdc(), &xform, MWT_LEFTMULTIPLY);
ModifyWorldTransform(metafile->context(), &xform, MWT_LEFTMULTIPLY);

bool ret = false;
std::vector<printing::PageRange>::const_iterator iter;
Expand All @@ -278,16 +278,16 @@ bool UtilityThread::RenderPDFToWinMetafile(
break;
metafile->StartPage();
if (render_proc(&buffer.front(), buffer.size(), page_number,
metafile->hdc(), render_dpi, render_dpi,
metafile->context(), render_dpi, render_dpi,
render_area.x(), render_area.y(), render_area.width(),
render_area.height(), true, false, true, true))
if (*highest_rendered_page_number < page_number)
*highest_rendered_page_number = page_number;
ret = true;
metafile->EndPage();
metafile->FinishPage();
}
}
metafile->CloseDc();
metafile->Close();
return ret;
}
#endif // defined(OS_WIN)
Expand Down
16 changes: 8 additions & 8 deletions printing/emf_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ bool Emf::CreateFromFile(const FilePath& metafile_path) {
}


bool Emf::CloseDc() {
bool Emf::Close() {
DCHECK(!emf_ && hdc_);
emf_ = CloseEnhMetaFile(hdc_);
DCHECK(emf_);
Expand All @@ -106,7 +106,7 @@ bool Emf::Playback(HDC hdc, const RECT* rect) const {
RECT bounds;
if (!rect) {
// Get the natural bounds of the EMF buffer.
bounds = GetBounds().ToRECT();
bounds = GetPageBounds(1).ToRECT();
rect = &bounds;
}
return PlayEnhMetaFile(hdc, emf_, rect) != 0;
Expand All @@ -123,11 +123,12 @@ bool Emf::SafePlayback(HDC context) const {
emf_,
&Emf::SafePlaybackProc,
reinterpret_cast<void*>(&base_matrix),
&GetBounds().ToRECT()) != 0;
&GetPageBounds(1).ToRECT()) != 0;
}

gfx::Rect Emf::GetBounds() const {
gfx::Rect Emf::GetPageBounds(unsigned int page_number) const {
DCHECK(emf_ && !hdc_);
DCHECK_EQ(1U, page_number);
ENHMETAHEADER header;
if (GetEnhMetaFileHeader(emf_, sizeof(header), &header) != sizeof(header)) {
NOTREACHED();
Expand Down Expand Up @@ -173,8 +174,8 @@ bool Emf::GetData(std::vector<uint8>* buffer) const {
return true;
}

bool Emf::SaveTo(const std::wstring& filename) const {
HANDLE file = CreateFile(filename.c_str(), GENERIC_WRITE,
bool Emf::SaveTo(const FilePath& file_path) const {
HANDLE file = CreateFile(file_path.value().c_str(), GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL,
CREATE_ALWAYS, 0, NULL);
if (file == INVALID_HANDLE_VALUE)
Expand Down Expand Up @@ -418,7 +419,7 @@ bool Emf::StartPage() {
reinterpret_cast<const BYTE *>(&record));
}

bool Emf::EndPage() {
bool Emf::FinishPage() {
DCHECK(hdc_);
if (!hdc_)
return false;
Expand All @@ -427,7 +428,6 @@ bool Emf::EndPage() {
reinterpret_cast<const BYTE *>(&record));
}


Emf::Enumerator::Enumerator(const Emf& emf, HDC context, const RECT* rect) {
context_.handle_table = NULL;
context_.objects_count = 0;
Expand Down
88 changes: 28 additions & 60 deletions printing/emf_win.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

#include "base/basictypes.h"
#include "base/gtest_prod_util.h"
#include "printing/native_metafile_win.h"
#include "printing/native_metafile.h"

class FilePath;

Expand All @@ -29,83 +29,51 @@ class Emf : public NativeMetafile {

virtual ~Emf();

// Initializes the Emf with the data in |src_buffer|. Returns true on success.
// NativeMetafile methods.
virtual bool Init() { return true; }
virtual bool Init(const void* src_buffer, uint32 src_buffer_size);

// Generates a virtual HDC that will record every GDI commands and compile it
// in a EMF data stream.
// hdc is used to setup the default DPI and color settings. hdc is optional.
// rect specifies the dimensions (in .01-millimeter units) of the EMF. rect is
// optional.
virtual bool CreateDc(HDC sibling, const RECT* rect);
virtual bool StartPage();
virtual bool FinishPage();
virtual bool Close();

// Similar to the above method but the metafile is backed by a file.
virtual bool CreateFileBackedDc(HDC sibling,
const RECT* rect,
const FilePath& path);
virtual uint32 GetDataSize() const;
virtual bool GetData(void* buffer, uint32 size) const;

// Load an EMF file.
virtual bool CreateFromFile(const FilePath& metafile_path);
// Saves the EMF data to a file as-is. It is recommended to use the .emf file
// extension but it is not enforced. This function synchronously writes to the
// file. For testing only.
virtual bool SaveTo(const FilePath& file_path) const;

// Should be passed to Playback to keep the exact same size.
virtual gfx::Rect GetPageBounds(unsigned int page_number) const;

virtual unsigned int GetPageCount() const {
// TODO(dpapad): count the number of times StartPage() is called
return 1;
}

// TODO(maruel): CreateFromFile(). If ever used. Maybe users would like to
// have the ability to save web pages to an EMF file? Afterward, it is easy to
// convert to PDF or PS.
virtual HDC context() const {
return hdc_;
}

// Closes the HDC created by CreateDc() and generates the compiled EMF
// data.
virtual bool CloseDc();
virtual bool CreateDc(HDC sibling, const RECT* rect);
virtual bool CreateFileBackedDc(HDC sibling,
const RECT* rect,
const FilePath& path);
virtual bool CreateFromFile(const FilePath& file_path);

// Closes the EMF data handle when it is not needed anymore.
virtual void CloseEmf();

// "Plays" the EMF buffer in a HDC. It is the same effect as calling the
// original GDI function that were called when recording the EMF. |rect| is in
// "logical units" and is optional. If |rect| is NULL, the natural EMF bounds
// are used.
// Note: Windows has been known to have stack buffer overflow in its GDI
// functions, whether used directly or indirectly through precompiled EMF
// data. We have to accept the risk here. Since it is used only for printing,
// it requires user intervention.
virtual bool Playback(HDC hdc, const RECT* rect) const;

// The slow version of Playback(). It enumerates all the records and play them
// back in the HDC. The trick is that it skip over the records known to have
// issue with some printers. See Emf::Record::SafePlayback implementation for
// details.
virtual bool SafePlayback(HDC hdc) const;

// Retrieves the bounds of the painted area by this EMF buffer. This value
// should be passed to Playback to keep the exact same size.
virtual gfx::Rect GetBounds() const;

// Retrieves the EMF stream size.
virtual uint32 GetDataSize() const;

// Retrieves the EMF stream.
virtual bool GetData(void* buffer, uint32 size) const;

// Retrieves the EMF stream. It is an helper function.
virtual bool GetData(std::vector<uint8>* buffer) const;

virtual HENHMETAFILE emf() const {
return emf_;
}

virtual HDC hdc() const {
return hdc_;
}

// Inserts a custom GDICOMMENT records indicating StartPage/EndPage calls
// (since StartPage and EndPage do not work in a metafile DC). Only valid
// when hdc_ is non-NULL.
virtual bool StartPage();
virtual bool EndPage();

// Saves the EMF data to a file as-is. It is recommended to use the .emf file
// extension but it is not enforced. This function synchronously writes to the
// file. For testing only.
virtual bool SaveTo(const std::wstring& filename) const;

protected:
Emf();

Expand Down
Loading

0 comments on commit 8f17cd3

Please sign in to comment.