Fix print preview clipping issues due to scaling.
BUG=79941 TEST=none Review URL: http://codereview.chromium.org/6879098 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@83657 0039d316-1c4b-4281-b951-d872f2087c98
This commit is contained in:
DEPS
chrome
renderer
print_web_view_helper.hprint_web_view_helper_linux.ccprint_web_view_helper_mac.mmprint_web_view_helper_win.cc
utility
printing
emf_win.ccemf_win.hemf_win_unittest.ccmetafile.hpdf_metafile_cairo_linux.ccpdf_metafile_cairo_linux.hpdf_metafile_cairo_linux_unittest.ccpdf_metafile_cg_mac.ccpdf_metafile_cg_mac.hpdf_metafile_cg_mac_unittest.ccpdf_metafile_skia.ccpdf_metafile_skia.h
skia/ext
2
DEPS
2
DEPS
@ -15,7 +15,7 @@ vars = {
|
||||
"libjingle_revision": "55",
|
||||
"libvpx_revision": "81610",
|
||||
"ffmpeg_revision": "83236",
|
||||
"skia_revision": "1206",
|
||||
"skia_revision": "1217",
|
||||
"v8_revision": "7688",
|
||||
}
|
||||
|
||||
|
@ -185,7 +185,7 @@ class PrintWebViewHelper : public RenderViewObserver ,
|
||||
int page_number, bool is_preview, WebKit::WebFrame* frame,
|
||||
scoped_ptr<printing::Metafile>* metafile);
|
||||
#elif defined(OS_MACOSX)
|
||||
void RenderPage(const gfx::Size& page_size, const gfx::Point& content_origin,
|
||||
void RenderPage(const gfx::Size& page_size, const gfx::Rect& content_area,
|
||||
const float& scale_factor, int page_number,
|
||||
WebKit::WebFrame* frame, printing::Metafile* metafile);
|
||||
#elif defined(OS_POSIX)
|
||||
|
@ -217,10 +217,11 @@ void PrintWebViewHelper::PrintPageInternal(
|
||||
margin_left_in_points,
|
||||
content_height_in_points + margin_top_in_points +
|
||||
margin_bottom_in_points);
|
||||
gfx::Point content_origin(margin_left_in_points, margin_top_in_points);
|
||||
gfx::Rect content_area(margin_left_in_points, margin_top_in_points,
|
||||
content_width_in_points, content_height_in_points);
|
||||
|
||||
skia::PlatformDevice* device = metafile->StartPageForVectorCanvas(
|
||||
page_size, content_origin, 1.0f);
|
||||
page_size, content_area, 1.0f);
|
||||
if (!device)
|
||||
return;
|
||||
|
||||
|
@ -27,9 +27,9 @@ void PrintWebViewHelper::PrintPageInternal(
|
||||
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);
|
||||
gfx::Rect content_area(params.params.printable_size);
|
||||
RenderPage(params.params.printable_size, content_area, scale_factor,
|
||||
page_number, frame, &metafile);
|
||||
metafile.FinishDocument();
|
||||
|
||||
PrintHostMsg_DidPrintPage_Params page_params;
|
||||
@ -70,17 +70,19 @@ bool PrintWebViewHelper::CreatePreviewDocument(
|
||||
return false;
|
||||
|
||||
float scale_factor = frame->getPrintPageShrink(0);
|
||||
gfx::Point origin(printParams.margin_left, printParams.margin_top);
|
||||
gfx::Rect content_area(printParams.margin_left, printParams.margin_top,
|
||||
printParams.printable_size.width(),
|
||||
printParams.printable_size.height());
|
||||
if (params.pages.empty()) {
|
||||
for (int i = 0; i < page_count; ++i) {
|
||||
RenderPage(printParams.page_size, origin, scale_factor, i, frame,
|
||||
RenderPage(printParams.page_size, content_area, scale_factor, i, frame,
|
||||
&metafile);
|
||||
}
|
||||
} else {
|
||||
for (size_t i = 0; i < params.pages.size(); ++i) {
|
||||
if (params.pages[i] >= page_count)
|
||||
break;
|
||||
RenderPage(printParams.page_size, origin, scale_factor,
|
||||
RenderPage(printParams.page_size, content_area, scale_factor,
|
||||
static_cast<int>(params.pages[i]), frame, &metafile);
|
||||
}
|
||||
}
|
||||
@ -101,10 +103,10 @@ bool PrintWebViewHelper::CreatePreviewDocument(
|
||||
}
|
||||
|
||||
void PrintWebViewHelper::RenderPage(
|
||||
const gfx::Size& page_size, const gfx::Point& content_origin,
|
||||
const gfx::Size& page_size, const gfx::Rect& content_area,
|
||||
const float& scale_factor, int page_number, WebFrame* frame,
|
||||
printing::Metafile* metafile) {
|
||||
bool success = metafile->StartPage(page_size, content_origin, scale_factor);
|
||||
bool success = metafile->StartPage(page_size, content_area, scale_factor);
|
||||
DCHECK(success);
|
||||
|
||||
// printPage can create autoreleased references to |context|. PDF contexts
|
||||
|
@ -207,10 +207,12 @@ void PrintWebViewHelper::RenderPage(
|
||||
}
|
||||
|
||||
gfx::Size page_size(width, height);
|
||||
gfx::Point content_origin(static_cast<int>(margin_left_in_points),
|
||||
static_cast<int>(margin_top_in_points));
|
||||
gfx::Rect content_area(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));
|
||||
skia::PlatformDevice* device = (*metafile)->StartPageForVectorCanvas(
|
||||
page_size, content_origin, frame->getPrintPageShrink(page_number));
|
||||
page_size, content_area, frame->getPrintPageShrink(page_number));
|
||||
DCHECK(device);
|
||||
skia::VectorCanvas canvas(device);
|
||||
|
||||
|
@ -301,7 +301,7 @@ bool UtilityThread::RenderPDFToWinMetafile(
|
||||
break;
|
||||
// The underlying metafile is of type Emf and ignores the arguments passed
|
||||
// to StartPage.
|
||||
metafile.StartPage(gfx::Size(), gfx::Point(), 1);
|
||||
metafile.StartPage(gfx::Size(), gfx::Rect(), 1);
|
||||
if (render_proc(&buffer.front(), buffer.size(), page_number,
|
||||
metafile.context(), render_dpi, render_dpi,
|
||||
render_area.x(), render_area.y(), render_area.width(),
|
||||
|
@ -404,9 +404,9 @@ bool Emf::Record::SafePlayback(const XFORM* base_matrix) const {
|
||||
}
|
||||
|
||||
skia::PlatformDevice* Emf::StartPageForVectorCanvas(
|
||||
const gfx::Size& page_size, const gfx::Point& content_origin,
|
||||
const gfx::Size& page_size, const gfx::Rect& content_area,
|
||||
const float& scale_factor) {
|
||||
if (!StartPage(page_size, content_origin, scale_factor))
|
||||
if (!StartPage(page_size, content_area, scale_factor))
|
||||
return NULL;
|
||||
|
||||
return skia::VectorPlatformDeviceEmfFactory::CreateDevice(page_size.width(),
|
||||
@ -415,7 +415,7 @@ skia::PlatformDevice* Emf::StartPageForVectorCanvas(
|
||||
}
|
||||
|
||||
bool Emf::StartPage(const gfx::Size& /*page_size*/,
|
||||
const gfx::Point& /*content_origin*/,
|
||||
const gfx::Rect& /*content_area*/,
|
||||
const float& /*scale_factor*/) {
|
||||
DCHECK(hdc_);
|
||||
if (!hdc_)
|
||||
|
@ -46,14 +46,14 @@ class Emf : public Metafile {
|
||||
virtual bool InitFromData(const void* src_buffer, uint32 src_buffer_size);
|
||||
|
||||
virtual skia::PlatformDevice* StartPageForVectorCanvas(
|
||||
const gfx::Size& page_size, const gfx::Point& content_origin,
|
||||
const gfx::Size& page_size, const gfx::Rect& content_area,
|
||||
const float& scale_factor);
|
||||
// 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. |page_size|, |content_origin|, and |scale_factor|
|
||||
// are ignored.
|
||||
// when hdc_ is non-NULL. |page_size|, |content_area|, and |scale_factor| are
|
||||
// ignored.
|
||||
virtual bool StartPage(const gfx::Size& page_size,
|
||||
const gfx::Point& content_origin,
|
||||
const gfx::Rect& content_area,
|
||||
const float& scale_factor);
|
||||
virtual bool FinishPage();
|
||||
virtual bool FinishDocument();
|
||||
|
@ -136,7 +136,7 @@ TEST_F(EmfPrintingTest, PageBreak) {
|
||||
EXPECT_TRUE(emf.context() != NULL);
|
||||
int pages = 3;
|
||||
while (pages) {
|
||||
EXPECT_TRUE(emf.StartPage(gfx::Size(), gfx::Point(), 1));
|
||||
EXPECT_TRUE(emf.StartPage(gfx::Size(), gfx::Rect(), 1));
|
||||
::Rectangle(emf.context(), 10, 10, 190, 190);
|
||||
EXPECT_TRUE(emf.FinishPage());
|
||||
--pages;
|
||||
|
@ -57,14 +57,15 @@ class Metafile {
|
||||
// VectorPlatformDevice implementation bound to the context created by
|
||||
// StartPage or NULL on error.
|
||||
virtual skia::PlatformDevice* StartPageForVectorCanvas(
|
||||
const gfx::Size& page_size, const gfx::Point& content_origin,
|
||||
const gfx::Size& page_size,
|
||||
const gfx::Rect& content_area,
|
||||
const float& scale_factor) = 0;
|
||||
|
||||
// Prepares a context for rendering a new page at the specified
|
||||
// |content_origin| with the given |page_size| and a |scale_factor| to use for
|
||||
// the drawing. The units are in points (=1/72 in). Returns true on success.
|
||||
// Prepares a context for rendering a new page with the given |page_size|,
|
||||
// |content_area| and a |scale_factor| to use for the drawing. The units are
|
||||
// in points (=1/72 in). Returns true on success.
|
||||
virtual bool StartPage(const gfx::Size& page_size,
|
||||
const gfx::Point& content_origin,
|
||||
const gfx::Rect& content_area,
|
||||
const float& scale_factor) = 0;
|
||||
|
||||
// Closes the current page and destroys the context used in rendering that
|
||||
|
@ -119,9 +119,9 @@ bool PdfMetafileCairo::InitFromData(const void* src_buffer,
|
||||
}
|
||||
|
||||
skia::PlatformDevice* PdfMetafileCairo::StartPageForVectorCanvas(
|
||||
const gfx::Size& page_size, const gfx::Point& content_origin,
|
||||
const gfx::Size& page_size, const gfx::Rect& content_area,
|
||||
const float& scale_factor) {
|
||||
if (!StartPage(page_size, content_origin, scale_factor))
|
||||
if (!StartPage(page_size, content_area, scale_factor))
|
||||
return NULL;
|
||||
|
||||
return skia::VectorPlatformDeviceCairoFactory::CreateDevice(
|
||||
@ -129,7 +129,7 @@ skia::PlatformDevice* PdfMetafileCairo::StartPageForVectorCanvas(
|
||||
}
|
||||
|
||||
bool PdfMetafileCairo::StartPage(const gfx::Size& page_size,
|
||||
const gfx::Point& content_origin,
|
||||
const gfx::Rect& content_area,
|
||||
const float& scale_factor) {
|
||||
DCHECK(IsSurfaceValid(surface_));
|
||||
DCHECK(IsContextValid(context_));
|
||||
@ -142,8 +142,8 @@ bool PdfMetafileCairo::StartPage(const gfx::Size& page_size,
|
||||
|
||||
// Don't let WebKit draw over the margins.
|
||||
cairo_surface_set_device_offset(surface_,
|
||||
content_origin.x(),
|
||||
content_origin.y());
|
||||
content_area.x(),
|
||||
content_area.y());
|
||||
|
||||
cairo_pdf_surface_set_size(surface_, page_size.width(), page_size.height());
|
||||
return context_ != NULL;
|
||||
|
@ -37,10 +37,10 @@ class PdfMetafileCairo : public Metafile {
|
||||
virtual bool InitFromData(const void* src_buffer, uint32 src_buffer_size);
|
||||
|
||||
virtual skia::PlatformDevice* StartPageForVectorCanvas(
|
||||
const gfx::Size& page_size, const gfx::Point& content_origin,
|
||||
const gfx::Size& page_size, const gfx::Rect& content_area,
|
||||
const float& scale_factor);
|
||||
virtual bool StartPage(const gfx::Size& page_size,
|
||||
const gfx::Point& content_origin,
|
||||
const gfx::Rect& content_area,
|
||||
const float& scale_factor);
|
||||
virtual bool FinishPage();
|
||||
virtual bool FinishDocument();
|
||||
|
@ -13,8 +13,8 @@
|
||||
#include "base/file_util.h"
|
||||
#include "base/string_util.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
#include "ui/gfx/rect.h"
|
||||
#include "ui/gfx/size.h"
|
||||
#include "ui/gfx/point.h"
|
||||
|
||||
typedef struct _cairo cairo_t;
|
||||
|
||||
@ -32,12 +32,12 @@ TEST_F(PdfMetafileCairoTest, Pdf) {
|
||||
EXPECT_TRUE(pdf.Init());
|
||||
|
||||
// Renders page 1.
|
||||
EXPECT_TRUE(pdf.StartPage(gfx::Size(72, 73), gfx::Point(4, 5), 1));
|
||||
EXPECT_TRUE(pdf.StartPage(gfx::Size(72, 73), gfx::Rect(4, 5, 64, 63), 1));
|
||||
// In theory, we should use Cairo to draw something on |context|.
|
||||
EXPECT_TRUE(pdf.FinishPage());
|
||||
|
||||
// Renders page 2.
|
||||
EXPECT_TRUE(pdf.StartPage(gfx::Size(72, 73), gfx::Point(4, 5), 1));
|
||||
EXPECT_TRUE(pdf.StartPage(gfx::Size(72, 73), gfx::Rect(4, 5, 64, 63), 1));
|
||||
// In theory, we should use Cairo to draw something on |context|.
|
||||
EXPECT_TRUE(pdf.FinishPage());
|
||||
|
||||
@ -70,7 +70,7 @@ TEST_F(PdfMetafileCairoTest, Pdf) {
|
||||
// Test overriding the metafile with raw data.
|
||||
printing::PdfMetafileCairo pdf3;
|
||||
EXPECT_TRUE(pdf3.Init());
|
||||
EXPECT_TRUE(pdf3.StartPage(gfx::Size(72, 73), gfx::Point(4, 5), 1));
|
||||
EXPECT_TRUE(pdf3.StartPage(gfx::Size(72, 73), gfx::Rect(4, 5, 64, 63), 1));
|
||||
std::string test_raw_data = "Dummy PDF";
|
||||
EXPECT_TRUE(pdf3.InitFromData(test_raw_data.c_str(), test_raw_data.size()));
|
||||
EXPECT_TRUE(pdf3.FinishPage());
|
||||
|
@ -64,14 +64,14 @@ bool PdfMetafileCg::InitFromData(const void* src_buffer,
|
||||
}
|
||||
|
||||
skia::PlatformDevice* PdfMetafileCg::StartPageForVectorCanvas(
|
||||
const gfx::Size& page_size, const gfx::Point& content_origin,
|
||||
const gfx::Size& page_size, const gfx::Rect& content_area,
|
||||
const float& scale_factor) {
|
||||
NOTIMPLEMENTED();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bool PdfMetafileCg::StartPage(const gfx::Size& page_size,
|
||||
const gfx::Point& content_origin,
|
||||
const gfx::Rect& content_area,
|
||||
const float& scale_factor) {
|
||||
DCHECK(context_.get());
|
||||
DCHECK(!page_is_open_);
|
||||
@ -88,8 +88,8 @@ bool PdfMetafileCg::StartPage(const gfx::Size& page_size,
|
||||
CGContextTranslateCTM(context_, 0, height);
|
||||
CGContextScaleCTM(context_, scale_factor, -scale_factor);
|
||||
|
||||
// Move the context to origin.
|
||||
CGContextTranslateCTM(context_, content_origin.x(), content_origin.y());
|
||||
// Move to the context origin.
|
||||
CGContextTranslateCTM(context_, content_area.x(), content_area.y());
|
||||
|
||||
return context_.get() != NULL;
|
||||
}
|
||||
|
@ -35,10 +35,10 @@ class PdfMetafileCg : public Metafile {
|
||||
|
||||
// Not implemented on mac.
|
||||
virtual skia::PlatformDevice* StartPageForVectorCanvas(
|
||||
const gfx::Size& page_size, const gfx::Point& content_origin,
|
||||
const gfx::Size& page_size, const gfx::Rect& content_area,
|
||||
const float& scale_factor);
|
||||
virtual bool StartPage(const gfx::Size& page_size,
|
||||
const gfx::Point& content_origin,
|
||||
const gfx::Rect& content_area,
|
||||
const float& scale_factor);
|
||||
virtual bool FinishPage();
|
||||
virtual bool FinishDocument();
|
||||
|
@ -20,16 +20,16 @@ TEST(PdfMetafileCgTest, Pdf) {
|
||||
EXPECT_TRUE(pdf.Init());
|
||||
EXPECT_TRUE(pdf.context() != NULL);
|
||||
|
||||
// Render page 1 at origin (10.0, 10.0).
|
||||
gfx::Point origin_1(10.0f, 10.0f);
|
||||
// Render page 1.
|
||||
gfx::Rect rect_1(10, 10, 520, 700);
|
||||
gfx::Size size_1(540, 720);
|
||||
pdf.StartPage(size_1, origin_1, 1.25);
|
||||
pdf.StartPage(size_1, rect_1, 1.25);
|
||||
pdf.FinishPage();
|
||||
|
||||
// Render page 2 at origin (10.0, 10.0).
|
||||
gfx::Point origin_2(10.0f, 10.0f);
|
||||
// Render page 2.
|
||||
gfx::Rect rect_2(10, 10, 520, 700);
|
||||
gfx::Size size_2(720, 540);
|
||||
pdf.StartPage(size_2, origin_2, 2.0);
|
||||
pdf.StartPage(size_2, rect_2, 2.0);
|
||||
pdf.FinishPage();
|
||||
|
||||
pdf.FinishDocument();
|
||||
|
@ -37,26 +37,32 @@ bool PdfMetafileSkia::InitFromData(const void* src_buffer,
|
||||
}
|
||||
|
||||
skia::PlatformDevice* PdfMetafileSkia::StartPageForVectorCanvas(
|
||||
const gfx::Size& page_size, const gfx::Point& content_origin,
|
||||
const gfx::Size& page_size, const gfx::Rect& content_area,
|
||||
const float& scale_factor) {
|
||||
DCHECK(data_->current_page_.get() == NULL);
|
||||
|
||||
// Adjust for the margins and apply the scale factor.
|
||||
SkMatrix transform;
|
||||
transform.setTranslate(SkIntToScalar(content_origin.x()),
|
||||
SkIntToScalar(content_origin.y()));
|
||||
transform.setTranslate(SkIntToScalar(content_area.x()),
|
||||
SkIntToScalar(content_area.y()));
|
||||
transform.preScale(SkFloatToScalar(scale_factor),
|
||||
SkFloatToScalar(scale_factor));
|
||||
|
||||
// TODO(ctguil): Refactor: don't create the PDF device explicitly here.
|
||||
SkISize pdf_page_size = SkISize::Make(page_size.width(), page_size.height());
|
||||
SkISize pdf_content_size =
|
||||
SkISize::Make(content_area.width(), content_area.height());
|
||||
SkRefPtr<SkPDFDevice> pdf_device =
|
||||
new SkPDFDevice(pdf_page_size, pdf_content_size, transform);
|
||||
pdf_device->unref(); // SkRefPtr and new both took a reference.
|
||||
skia::VectorPlatformDeviceSkia* device =
|
||||
new skia::VectorPlatformDeviceSkia(page_size.width(), page_size.height(),
|
||||
transform);
|
||||
new skia::VectorPlatformDeviceSkia(pdf_device.get());
|
||||
data_->current_page_ = device->PdfDevice();
|
||||
return device;
|
||||
}
|
||||
|
||||
bool PdfMetafileSkia::StartPage(const gfx::Size& page_size,
|
||||
const gfx::Point& content_origin,
|
||||
const gfx::Rect& content_area,
|
||||
const float& scale_factor) {
|
||||
NOTREACHED();
|
||||
return NULL;
|
||||
|
@ -31,10 +31,10 @@ class PdfMetafileSkia : public Metafile {
|
||||
|
||||
virtual skia::PlatformDevice* StartPageForVectorCanvas(
|
||||
const gfx::Size& page_size,
|
||||
const gfx::Point& content_origin,
|
||||
const gfx::Rect& content_area,
|
||||
const float& scale_factor);
|
||||
virtual bool StartPage(const gfx::Size& page_size,
|
||||
const gfx::Point& content_origin,
|
||||
const gfx::Rect& content_area,
|
||||
const float& scale_factor);
|
||||
virtual bool FinishPage();
|
||||
virtual bool FinishDocument();
|
||||
@ -66,4 +66,4 @@ class PdfMetafileSkia : public Metafile {
|
||||
|
||||
} // namespace printing
|
||||
|
||||
#endif // PRINTING_PDF_METAFILE_MAC_H_
|
||||
#endif // PRINTING_PDF_METAFILE_SKIA_H_
|
||||
|
@ -25,7 +25,11 @@ SkDevice* VectorPlatformDeviceSkiaFactory::newDevice(SkCanvas* noUsed,
|
||||
initialTransform.setTranslate(0, height);
|
||||
initialTransform.preScale(1, -1);
|
||||
}
|
||||
return new VectorPlatformDeviceSkia(width, height, initialTransform);
|
||||
SkISize size = SkISize::Make(width, height);
|
||||
SkRefPtr<SkPDFDevice> pdf_device =
|
||||
new SkPDFDevice(size, size, initialTransform);
|
||||
pdf_device->unref(); // SkRefPtr and new both took a reference.
|
||||
return new VectorPlatformDeviceSkia(pdf_device.get());
|
||||
}
|
||||
|
||||
static inline SkBitmap makeABitmap(int width, int height) {
|
||||
@ -34,11 +38,9 @@ static inline SkBitmap makeABitmap(int width, int height) {
|
||||
return bitmap;
|
||||
}
|
||||
|
||||
VectorPlatformDeviceSkia::VectorPlatformDeviceSkia(
|
||||
int width, int height, const SkMatrix& initialTransform)
|
||||
: PlatformDevice(makeABitmap(width, height)),
|
||||
pdf_device_(new SkPDFDevice(width, height, initialTransform)) {
|
||||
pdf_device_->unref(); // SkRefPtr and new both took a reference.
|
||||
VectorPlatformDeviceSkia::VectorPlatformDeviceSkia(SkPDFDevice* pdf_device)
|
||||
: PlatformDevice(makeABitmap(pdf_device->width(), pdf_device->height())),
|
||||
pdf_device_(pdf_device) {
|
||||
}
|
||||
|
||||
VectorPlatformDeviceSkia::~VectorPlatformDeviceSkia() {
|
||||
|
@ -31,9 +31,7 @@ class VectorPlatformDeviceSkiaFactory : public SkDeviceFactory {
|
||||
|
||||
class VectorPlatformDeviceSkia : public PlatformDevice {
|
||||
public:
|
||||
SK_API VectorPlatformDeviceSkia(int width,
|
||||
int height,
|
||||
const SkMatrix& initialTransform);
|
||||
SK_API VectorPlatformDeviceSkia(SkPDFDevice* pdf_device);
|
||||
~VectorPlatformDeviceSkia();
|
||||
|
||||
SkPDFDevice* PdfDevice() { return pdf_device_.get(); }
|
||||
|
Reference in New Issue
Block a user