0

PdfMetafileSkia gives out a SkCanvas, not a SkBaseDevice.

Motivation: hide SkPDFDevice and SkPDFDocument behind PdfMetafileSkia class.

pdf_metafile_skia.cc:
    Implement GetVectorCanvasForNewPage.
    Remove StartPageForVectorCanvas.
    Own the SkCanvas pointer (current_page_canvas_).
    Replace page_outstanding_ field with a method that checks to see
    if current_page_canvas_ is NULL.
    Implement SaveTo.

skia::VectorPlatformDeviceSkia
    remove class

print_web_view_helper.cc
    Remove calls to canvas->getTopDevice()->setDrawingArea(...); (SkDFDevice)
    This API is no longer effective.

print_web_view_helper_linux.cc,
print_web_view_helper_mac.mm,
print_web_view_helper_pdf_win.cc:
    call GetVectorCanvasForNewPage rather than StartPageForVectorCanvas

BUG=278148

Review URL: https://codereview.chromium.org/704813002

Cr-Commit-Position: refs/heads/master@{#303522}
This commit is contained in:
halcanary
2014-11-10 14:20:05 -08:00
committed by Commit bot
parent eeb7d1b688
commit 5be808e0b7
12 changed files with 80 additions and 275 deletions

@ -25,7 +25,6 @@
#include "net/base/escape.h"
#include "printing/pdf_metafile_skia.h"
#include "printing/units.h"
#include "skia/ext/vector_platform_device_skia.h"
#include "third_party/WebKit/public/platform/WebSize.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "third_party/WebKit/public/web/WebConsoleMessage.h"
@ -426,10 +425,6 @@ void PrintWebViewHelper::PrintHeaderAndFooter(
const PrintMsg_Print_Params& params) {
#if 0
// TODO(sgurun) android_webview hack
skia::VectorPlatformDeviceSkia* device =
static_cast<skia::VectorPlatformDeviceSkia*>(canvas->getTopDevice());
device->setDrawingArea(SkPDFDevice::kMargin_DrawingArea);
SkAutoCanvasRestore auto_restore(canvas, true);
canvas->scale(1 / webkit_scale_factor, 1 / webkit_scale_factor);
@ -468,8 +463,6 @@ void PrintWebViewHelper::PrintHeaderAndFooter(
web_view->close();
frame->close();
device->setDrawingArea(SkPDFDevice::kContent_DrawingArea);
#endif
}

@ -166,32 +166,26 @@ void PrintWebViewHelper::PrintPageInternal(
gfx::Rect canvas_area =
params.params.display_header_footer ? gfx::Rect(page_size) : content_area;
SkBaseDevice* device = metafile->StartPageForVectorCanvas(page_size,
canvas_area,
scale_factor);
if (!device)
skia::VectorCanvas* canvas =
metafile->GetVectorCanvasForNewPage(page_size, canvas_area, scale_factor);
if (!canvas)
return;
// The printPage method take a reference to the canvas we pass down, so it
// can't be a stack object.
skia::RefPtr<skia::VectorCanvas> canvas =
skia::AdoptRef(new skia::VectorCanvas(device));
MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile);
skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_);
if (params.params.display_header_footer) {
// |page_number| is 0-based, so 1 is added.
// TODO(vitalybuka) : why does it work only with 1.25?
PrintHeaderAndFooter(canvas.get(), params.page_number + 1,
PrintHeaderAndFooter(canvas, params.page_number + 1,
print_preview_context_.total_page_count(),
scale_factor / 1.25,
page_layout_in_points, *header_footer_info_,
params.params);
scale_factor / 1.25, page_layout_in_points,
*header_footer_info_, params.params);
}
RenderPageContent(frame, params.page_number, canvas_area, content_area,
scale_factor, canvas.get());
scale_factor, canvas);
// Done printing. Close the device context to retrieve the compiled metafile.
// Done printing. Close the canvas to retrieve the compiled metafile.
if (!metafile->FinishPage())
NOTREACHED() << "metafile failed";
}

@ -28,7 +28,6 @@
#include "net/base/escape.h"
#include "printing/pdf_metafile_skia.h"
#include "printing/units.h"
#include "skia/ext/vector_platform_device_skia.h"
#include "third_party/WebKit/public/platform/WebSize.h"
#include "third_party/WebKit/public/platform/WebURLRequest.h"
#include "third_party/WebKit/public/web/WebConsoleMessage.h"
@ -453,10 +452,6 @@ void PrintWebViewHelper::PrintHeaderAndFooter(
float webkit_scale_factor,
const PageSizeMargins& page_layout,
const PrintMsg_Print_Params& params) {
skia::VectorPlatformDeviceSkia* device =
static_cast<skia::VectorPlatformDeviceSkia*>(canvas->getTopDevice());
device->setDrawingArea(SkPDFDevice::kMargin_DrawingArea);
SkAutoCanvasRestore auto_restore(canvas, true);
canvas->scale(1 / webkit_scale_factor, 1 / webkit_scale_factor);
@ -503,8 +498,6 @@ void PrintWebViewHelper::PrintHeaderAndFooter(
web_view->close();
frame->close();
device->setDrawingArea(SkPDFDevice::kContent_DrawingArea);
}
#endif // defined(ENABLE_PRINT_PREVIEW)

@ -161,16 +161,11 @@ void PrintWebViewHelper::PrintPageInternal(
gfx::Rect canvas_area =
params.params.display_header_footer ? gfx::Rect(page_size) : content_area;
SkBaseDevice* device = metafile->StartPageForVectorCanvas(page_size,
canvas_area,
scale_factor);
if (!device)
skia::VectorCanvas* canvas =
metafile->GetVectorCanvasForNewPage(page_size, canvas_area, scale_factor);
if (!canvas)
return;
// The printPage method take a reference to the canvas we pass down, so it
// can't be a stack object.
skia::RefPtr<skia::VectorCanvas> canvas =
skia::AdoptRef(new skia::VectorCanvas(device));
MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile);
skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_);
@ -178,20 +173,17 @@ void PrintWebViewHelper::PrintPageInternal(
if (params.params.display_header_footer) {
// |page_number| is 0-based, so 1 is added.
// TODO(vitalybuka) : why does it work only with 1.25?
PrintHeaderAndFooter(canvas.get(),
params.page_number + 1,
print_preview_context_.total_page_count(),
*frame,
scale_factor / 1.25,
page_layout_in_points,
PrintHeaderAndFooter(canvas, params.page_number + 1,
print_preview_context_.total_page_count(), *frame,
scale_factor / 1.25, page_layout_in_points,
params.params);
}
#endif // defined(ENABLE_PRINT_PREVIEW)
RenderPageContent(frame, params.page_number, canvas_area, content_area,
scale_factor, canvas.get());
scale_factor, canvas);
// Done printing. Close the device context to retrieve the compiled metafile.
// Done printing. Close the canvas to retrieve the compiled metafile.
if (!metafile->FinishPage())
NOTREACHED() << "metafile failed";
}

@ -118,29 +118,23 @@ void PrintWebViewHelper::RenderPage(const PrintMsg_Print_Params& params,
params.display_header_footer ? gfx::Rect(*page_size) : content_area;
{
SkBaseDevice* device = metafile->StartPageForVectorCanvas(
skia::VectorCanvas* canvas = metafile->GetVectorCanvasForNewPage(
*page_size, canvas_area, scale_factor);
if (!device)
if (!canvas)
return;
skia::RefPtr<skia::VectorCanvas> canvas =
skia::AdoptRef(new skia::VectorCanvas(device));
blink::WebCanvas* canvas_ptr = canvas.get();
MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile);
skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_);
skia::SetIsPreviewMetafile(*canvas, is_preview);
if (params.display_header_footer) {
PrintHeaderAndFooter(canvas_ptr,
PrintHeaderAndFooter(static_cast<blink::WebCanvas*>(canvas),
page_number + 1,
print_preview_context_.total_page_count(),
*frame,
scale_factor,
page_layout_in_points,
params);
print_preview_context_.total_page_count(), *frame,
scale_factor, page_layout_in_points, params);
}
RenderPageContent(frame, page_number, canvas_area, content_area,
scale_factor, canvas_ptr);
scale_factor, static_cast<blink::WebCanvas*>(canvas));
}
// Done printing. Close the device context to retrieve the compiled metafile.

@ -179,38 +179,26 @@ void PrintWebViewHelper::PrintPageInternal(
frame->getPrintPageShrink(params.page_number);
float scale_factor = css_scale_factor * webkit_page_shrink_factor;
SkBaseDevice* device = metafile->StartPageForVectorCanvas(page_size,
canvas_area,
scale_factor);
if (!device)
skia::VectorCanvas* canvas =
metafile->GetVectorCanvasForNewPage(page_size, canvas_area, scale_factor);
if (!canvas)
return;
// The printPage method take a reference to the canvas we pass down, so it
// can't be a stack object.
skia::RefPtr<skia::VectorCanvas> canvas =
skia::AdoptRef(new skia::VectorCanvas(device));
MetafileSkiaWrapper::SetMetafileOnCanvas(*canvas, metafile);
skia::SetIsDraftMode(*canvas, is_print_ready_metafile_sent_);
if (params.params.display_header_footer) {
// |page_number| is 0-based, so 1 is added.
PrintHeaderAndFooter(canvas.get(),
params.page_number + 1,
print_preview_context_.total_page_count(),
*frame,
scale_factor,
page_layout_in_points,
params.params);
PrintHeaderAndFooter(canvas, params.page_number + 1,
print_preview_context_.total_page_count(), *frame,
scale_factor, page_layout_in_points, params.params);
}
float webkit_scale_factor = RenderPageContent(frame,
params.page_number,
canvas_area,
content_area,
scale_factor,
canvas.get());
float webkit_scale_factor =
RenderPageContent(frame, params.page_number, canvas_area, content_area,
scale_factor, canvas);
DCHECK_GT(webkit_scale_factor, 0.0f);
// Done printing. Close the device context to retrieve the compiled metafile.
// Done printing. Close the canvas to retrieve the compiled metafile.
if (!metafile->FinishPage())
NOTREACHED() << "metafile failed";
}

@ -10,7 +10,7 @@
#include "base/numerics/safe_conversions.h"
#include "base/posix/eintr_wrapper.h"
#include "skia/ext/refptr.h"
#include "skia/ext/vector_platform_device_skia.h"
#include "skia/ext/vector_canvas.h"
#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkRefCnt.h"
#include "third_party/skia/include/core/SkScalar.h"
@ -34,6 +34,7 @@ namespace printing {
struct PdfMetafileSkiaData {
skia::RefPtr<SkPDFDevice> current_page_;
skia::RefPtr<SkCanvas> current_page_canvas_;
SkPDFDocument pdf_doc_;
SkDynamicMemoryWStream pdf_stream_;
#if defined(OS_MACOSX)
@ -51,11 +52,10 @@ bool PdfMetafileSkia::InitFromData(const void* src_buffer,
return data_->pdf_stream_.write(src_buffer, src_buffer_size);
}
SkBaseDevice* PdfMetafileSkia::StartPageForVectorCanvas(
const gfx::Size& page_size, const gfx::Rect& content_area,
const float& scale_factor) {
DCHECK(!page_outstanding_);
page_outstanding_ = true;
bool PdfMetafileSkia::StartPage(const gfx::Size& page_size,
const gfx::Rect& content_area,
const float& scale_factor) {
DCHECK(!data_->current_page_canvas_);
// Adjust for the margins and apply the scale factor.
SkMatrix transform;
@ -67,25 +67,29 @@ SkBaseDevice* PdfMetafileSkia::StartPageForVectorCanvas(
SkISize pdf_page_size = SkISize::Make(page_size.width(), page_size.height());
SkISize pdf_content_size =
SkISize::Make(content_area.width(), content_area.height());
skia::RefPtr<SkPDFDevice> pdf_device =
skia::AdoptRef(new skia::VectorPlatformDeviceSkia(
pdf_page_size, pdf_content_size, transform));
data_->current_page_ = pdf_device;
return pdf_device.get();
data_->current_page_ = skia::AdoptRef(
new SkPDFDevice(pdf_page_size, pdf_content_size, transform));
data_->current_page_canvas_ =
skia::AdoptRef(new SkCanvas(data_->current_page_.get()));
return true;
}
bool PdfMetafileSkia::StartPage(const gfx::Size& page_size,
const gfx::Rect& content_area,
const float& scale_factor) {
NOTREACHED();
return false;
skia::VectorCanvas* PdfMetafileSkia::GetVectorCanvasForNewPage(
const gfx::Size& page_size,
const gfx::Rect& content_area,
const float& scale_factor) {
if (!StartPage(page_size, content_area, scale_factor))
return nullptr;
return data_->current_page_canvas_.get();
}
bool PdfMetafileSkia::FinishPage() {
DCHECK(data_->current_page_.get());
DCHECK(data_->current_page_canvas_);
DCHECK(data_->current_page_);
data_->current_page_canvas_.clear(); // Unref SkCanvas.
data_->pdf_doc_.appendPage(data_->current_page_.get());
page_outstanding_ = false;
return true;
}
@ -94,7 +98,7 @@ bool PdfMetafileSkia::FinishDocument() {
if (data_->pdf_stream_.getOffset())
return true;
if (page_outstanding_)
if (data_->current_page_canvas_)
FinishPage();
data_->current_page_.clear();
@ -179,6 +183,17 @@ bool PdfMetafileSkia::RenderPage(unsigned int page_number,
}
#endif
bool PdfMetafileSkia::SaveTo(base::File* file) const {
if (GetDataSize() == 0U)
return false;
SkAutoDataUnref data(data_->pdf_stream_.copyToData());
// TODO(halcanary): rewrite this function without extra data copy
// using SkStreamAsset.
const char* ptr = reinterpret_cast<const char*>(data->data());
int size = base::checked_cast<int>(data->size());
return file->WriteAtCurrentPos(ptr, size) == size;
}
#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
bool PdfMetafileSkia::SaveToFD(const base::FileDescriptor& fd) const {
DCHECK_GT(data_->pdf_stream_.getOffset(), 0U);
@ -188,10 +203,7 @@ bool PdfMetafileSkia::SaveToFD(const base::FileDescriptor& fd) const {
return false;
}
base::File file(fd.fd);
SkAutoDataUnref data(data_->pdf_stream_.copyToData());
bool result =
file.WriteAtCurrentPos(reinterpret_cast<const char*>(data->data()),
GetDataSize()) == static_cast<int>(GetDataSize());
bool result = SaveTo(&file);
DLOG_IF(ERROR, !result) << "Failed to save file with fd " << fd.fd;
if (!fd.auto_close)
@ -200,9 +212,7 @@ bool PdfMetafileSkia::SaveToFD(const base::FileDescriptor& fd) const {
}
#endif
PdfMetafileSkia::PdfMetafileSkia()
: data_(new PdfMetafileSkiaData),
page_outstanding_(false) {
PdfMetafileSkia::PdfMetafileSkia() : data_(new PdfMetafileSkiaData) {
}
scoped_ptr<PdfMetafileSkia> PdfMetafileSkia::GetMetafileForCurrentPage() {

@ -10,6 +10,7 @@
#include "base/memory/scoped_ptr.h"
#include "build/build_config.h"
#include "printing/metafile.h"
#include "skia/ext/vector_canvas.h"
#if defined(OS_WIN)
#include <windows.h>
@ -62,6 +63,8 @@ class PRINTING_EXPORT PdfMetafileSkia : public Metafile {
const MacRenderPageParams& params) const override;
#endif
bool SaveTo(base::File* file) const override;
#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
// TODO(vitalybuka): replace with SaveTo().
bool SaveToFD(const base::FileDescriptor& fd) const;
@ -71,17 +74,18 @@ class PRINTING_EXPORT PdfMetafileSkia : public Metafile {
scoped_ptr<PdfMetafileSkia> GetMetafileForCurrentPage();
// This method calls StartPage and then returns an appropriate
// VectorPlatformDevice implementation bound to the context created by
// StartPage or NULL on error.
SkBaseDevice* StartPageForVectorCanvas(const gfx::Size& page_size,
const gfx::Rect& content_area,
const float& scale_factor);
// VectorCanvas implementation bound to the context created by
// StartPage or NULL on error. The skia::VectorCanvas pointer that
// is returned is owned by this PdfMetafileSkia object and does not
// need to be ref()ed or unref()ed. The canvas will remain valid
// until FinishPage() or FinishDocument() is called.
skia::VectorCanvas* GetVectorCanvasForNewPage(const gfx::Size& page_size,
const gfx::Rect& content_area,
const float& scale_factor);
private:
scoped_ptr<PdfMetafileSkiaData> data_;
// True when finish page is outstanding for current page.
bool page_outstanding_;
DISALLOW_COPY_AND_ASSIGN(PdfMetafileSkia);
};

@ -312,8 +312,6 @@ component("skia") {
"ext/vector_canvas.h",
"ext/vector_platform_device_emf_win.cc",
"ext/vector_platform_device_emf_win.h",
"ext/vector_platform_device_skia.cc",
"ext/vector_platform_device_skia.h",
]
# The skia gypi values are relative to the skia_dir, so we need to rebase.
@ -426,16 +424,12 @@ component("skia") {
if (is_posix) {
sources -= [ "ext/SkThread_chrome.cc" ]
}
if (is_ios) {
sources -= [ "ext/vector_platform_device_skia.cc" ]
}
if (is_win) {
sources -= [ "ext/SkThread_chrome.cc" ]
}
if (is_android && (!enable_basic_printing && !enable_print_preview)) {
sources -= [
"ext/skia_utils_base.cc",
"ext/vector_platform_device_skia.cc"
]
}

@ -1,88 +0,0 @@
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "skia/ext/vector_platform_device_skia.h"
#include "skia/ext/bitmap_platform_device.h"
#include "third_party/skia/include/core/SkClipStack.h"
#include "third_party/skia/include/core/SkDraw.h"
#include "third_party/skia/include/core/SkRect.h"
#include "third_party/skia/include/core/SkRegion.h"
#include "third_party/skia/include/core/SkScalar.h"
namespace skia {
static inline SkBitmap makeABitmap(int width, int height) {
SkBitmap bitmap;
bitmap.setInfo(SkImageInfo::MakeUnknown(width, height));
return bitmap;
}
VectorPlatformDeviceSkia::VectorPlatformDeviceSkia(
const SkISize& pageSize,
const SkISize& contentSize,
const SkMatrix& initialTransform)
: SkPDFDevice(pageSize, contentSize, initialTransform) {
SetPlatformDevice(this, this);
}
VectorPlatformDeviceSkia::~VectorPlatformDeviceSkia() {
}
bool VectorPlatformDeviceSkia::SupportsPlatformPaint() {
return false;
}
PlatformSurface VectorPlatformDeviceSkia::BeginPlatformPaint() {
// Even when drawing a vector representation of the page, we have to
// provide a raster surface for plugins to render into - they don't have
// a vector interface. Therefore we create a BitmapPlatformDevice here
// and return the context from it, then layer on the raster data as an
// image in EndPlatformPaint.
DCHECK(raster_surface_ == NULL);
raster_surface_ = skia::AdoptRef(
BitmapPlatformDevice::CreateAndClear(width(), height(), false));
return raster_surface_->BeginPlatformPaint();
}
void VectorPlatformDeviceSkia::EndPlatformPaint() {
DCHECK(raster_surface_ != NULL);
SkPaint paint;
// SkPDFDevice checks the passed SkDraw for an empty clip (only). Fake
// it out by setting a non-empty clip.
SkDraw draw;
SkRegion clip(SkIRect::MakeWH(width(), height()));
draw.fClip=&clip;
drawSprite(draw, raster_surface_->accessBitmap(false), 0, 0, paint);
// BitmapPlatformDevice matches begin and end calls.
raster_surface_->EndPlatformPaint();
raster_surface_.clear();
}
#if defined(OS_WIN)
void VectorPlatformDeviceSkia::DrawToNativeContext(HDC dc,
int x,
int y,
const RECT* src_rect) {
SkASSERT(false);
}
#elif defined(OS_MACOSX)
void VectorPlatformDeviceSkia::DrawToNativeContext(CGContext* context, int x,
int y, const CGRect* src_rect) {
SkASSERT(false);
}
CGContextRef VectorPlatformDeviceSkia::GetBitmapContext() {
SkASSERT(false);
return NULL;
}
#elif defined(OS_POSIX)
void VectorPlatformDeviceSkia::DrawToNativeContext(
PlatformSurface surface, int x, int y, const PlatformRect* src_rect) {
// Should never be called on Linux.
SkASSERT(false);
}
#endif
} // namespace skia

@ -1,59 +0,0 @@
// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef SKIA_EXT_VECTOR_PLATFORM_DEVICE_SKIA_H_
#define SKIA_EXT_VECTOR_PLATFORM_DEVICE_SKIA_H_
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/logging.h"
#include "skia/ext/platform_device.h"
#include "skia/ext/refptr.h"
#include "third_party/skia/include/pdf/SkPDFDevice.h"
class SkMatrix;
namespace skia {
class BitmapPlatformDevice;
class VectorPlatformDeviceSkia : public SkPDFDevice, public PlatformDevice {
public:
SK_API VectorPlatformDeviceSkia(const SkISize& pageSize,
const SkISize& contentSize,
const SkMatrix& initialTransform);
~VectorPlatformDeviceSkia() override;
// PlatformDevice methods.
bool SupportsPlatformPaint() override;
PlatformSurface BeginPlatformPaint() override;
void EndPlatformPaint() override;
#if defined(OS_WIN)
virtual void DrawToNativeContext(HDC dc,
int x,
int y,
const RECT* src_rect) override;
#elif defined(OS_MACOSX)
void DrawToNativeContext(CGContext* context,
int x,
int y,
const CGRect* src_rect) override;
CGContextRef GetBitmapContext() override;
#elif defined(OS_POSIX)
virtual void DrawToNativeContext(PlatformSurface surface,
int x,
int y,
const PlatformRect* src_rect) override;
#endif
private:
skia::RefPtr<BitmapPlatformDevice> raster_surface_;
DISALLOW_COPY_AND_ASSIGN(VectorPlatformDeviceSkia);
};
} // namespace skia
#endif // SKIA_EXT_VECTOR_PLATFORM_DEVICE_SKIA_H_

@ -83,8 +83,6 @@
'ext/vector_canvas.h',
'ext/vector_platform_device_emf_win.cc',
'ext/vector_platform_device_emf_win.h',
'ext/vector_platform_device_skia.cc',
'ext/vector_platform_device_skia.h',
],
'conditions': [
[ 'OS == "android" and '
@ -93,15 +91,7 @@
'ext/skia_utils_base.cc',
],
}],
[ 'enable_basic_printing==0 and enable_print_preview==0', {
'sources!': [
'ext/vector_platform_device_skia.cc',
],
}],
['OS == "ios"', {
'sources/': [
['exclude', '^ext/vector_platform_device_skia\\.'],
],
'dependencies!': [
'skia_chrome_opts',
],