15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/pdf_metafile_skia.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
77d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/containers/hash_tables.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h"
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/numerics/safe_conversions.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/posix/eintr_wrapper.h"
1290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "skia/ext/refptr.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "skia/ext/vector_platform_device_skia.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkData.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkRefCnt.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkScalar.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkStream.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/core/SkTypeface.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/pdf/SkPDFDevice.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/skia/include/pdf/SkPDFDocument.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/point.h"
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h"
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/size.h"
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "printing/pdf_metafile_cg_mac.h"
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
29a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#if defined(OS_POSIX)
30a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "base/file_descriptor_posix.h"
31a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#endif
32a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace printing {
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PdfMetafileSkiaData {
3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  skia::RefPtr<SkPDFDevice> current_page_;
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPDFDocument pdf_doc_;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkDynamicMemoryWStream pdf_stream_;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PdfMetafileCg pdf_cg_;
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PdfMetafileSkia::~PdfMetafileSkia() {}
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PdfMetafileSkia::Init() {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PdfMetafileSkia::InitFromData(const void* src_buffer,
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                   uint32 src_buffer_size) {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return data_->pdf_stream_.write(src_buffer, src_buffer_size);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)SkBaseDevice* PdfMetafileSkia::StartPageForVectorCanvas(
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const gfx::Size& page_size, const gfx::Rect& content_area,
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const float& scale_factor) {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!page_outstanding_);
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_outstanding_ = true;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Adjust for the margins and apply the scale factor.
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkMatrix transform;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transform.setTranslate(SkIntToScalar(content_area.x()),
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         SkIntToScalar(content_area.y()));
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  transform.preScale(SkFloatToScalar(scale_factor),
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                     SkFloatToScalar(scale_factor));
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkISize pdf_page_size = SkISize::Make(page_size.width(), page_size.height());
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkISize pdf_content_size =
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SkISize::Make(content_area.width(), content_area.height());
7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  skia::RefPtr<SkPDFDevice> pdf_device =
7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      skia::AdoptRef(new skia::VectorPlatformDeviceSkia(
7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)          pdf_page_size, pdf_content_size, transform));
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->current_page_ = pdf_device;
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return pdf_device.get();
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PdfMetafileSkia::StartPage(const gfx::Size& page_size,
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const gfx::Rect& content_area,
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                const float& scale_factor) {
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PdfMetafileSkia::FinishPage() {
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(data_->current_page_.get());
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->pdf_doc_.appendPage(data_->current_page_.get());
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  page_outstanding_ = false;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PdfMetafileSkia::FinishDocument() {
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Don't do anything if we've already set the data in InitFromData.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (data_->pdf_stream_.getOffset())
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (page_outstanding_)
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    FinishPage();
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  data_->current_page_.clear();
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  int font_counts[SkAdvancedTypefaceMetrics::kOther_Font + 2];
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  data_->pdf_doc_.getCountOfFontTypes(font_counts);
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (int type = 0;
105a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)       type <= SkAdvancedTypefaceMetrics::kOther_Font + 1;
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       type++) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int count = 0; count < font_counts[type]; count++) {
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      UMA_HISTOGRAM_ENUMERATION(
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          "PrintPreview.FontType", type,
110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)          SkAdvancedTypefaceMetrics::kOther_Font + 2);
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return data_->pdf_doc_.emitPDF(&data_->pdf_stream_);
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint32 PdfMetafileSkia::GetDataSize() const {
1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)  return base::checked_cast<uint32>(data_->pdf_stream_.getOffset());
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PdfMetafileSkia::GetData(void* dst_buffer,
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              uint32 dst_buffer_size) const {
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (dst_buffer_size < GetDataSize())
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkAutoDataUnref data(data_->pdf_stream_.copyToData());
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(dst_buffer, data->bytes(), dst_buffer_size);
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool PdfMetafileSkia::SaveTo(const base::FilePath& file_path) const {
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(data_->pdf_stream_.getOffset(), 0U);
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkAutoDataUnref data(data_->pdf_stream_.copyToData());
134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (base::WriteFile(file_path,
135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      reinterpret_cast<const char*>(data->data()),
136a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                      GetDataSize()) != static_cast<int>(GetDataSize())) {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "Failed to save file " << file_path.value().c_str();
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::Rect PdfMetafileSkia::GetPageBounds(unsigned int page_number) const {
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(vandebo) add a method to get the page size for a given page to
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // SkPDFDocument.
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTIMPLEMENTED();
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return gfx::Rect();
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)unsigned int PdfMetafileSkia::GetPageCount() const {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(vandebo) add a method to get the number of pages to SkPDFDocument.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTIMPLEMENTED();
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return 0;
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)gfx::NativeDrawingContext PdfMetafileSkia::context() const {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PdfMetafileSkia::Playback(gfx::NativeDrawingContext hdc,
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                               const RECT* rect) const {
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PdfMetafileSkia::SafePlayback(gfx::NativeDrawingContext hdc) const {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HENHMETAFILE PdfMetafileSkia::emf() const {
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NOTREACHED();
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX)
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)/* TODO(caryclark): The set up of PluginInstance::PrintPDFOutput may result in
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   rasterized output.  Even if that flow uses PdfMetafileCg::RenderPage,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   the drawing of the PDF into the canvas may result in a rasterized output.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   PDFMetafileSkia::RenderPage should be not implemented as shown and instead
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   should do something like the following CL in PluginInstance::PrintPDFOutput:
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)http://codereview.chromium.org/7200040/diff/1/webkit/plugins/ppapi/ppapi_plugin_instance.cc
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)*/
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PdfMetafileSkia::RenderPage(unsigned int page_number,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 CGContextRef context,
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const CGRect rect,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const MacRenderPageParams& params) const {
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(data_->pdf_stream_.getOffset(), 0U);
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (data_->pdf_cg_.GetDataSize() == 0) {
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    SkAutoDataUnref data(data_->pdf_stream_.copyToData());
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    data_->pdf_cg_.InitFromData(data->bytes(), data->size());
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return data_->pdf_cg_.RenderPage(page_number, context, rect, params);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1983551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)#if defined(OS_CHROMEOS) || defined(OS_ANDROID)
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PdfMetafileSkia::SaveToFD(const base::FileDescriptor& fd) const {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK_GT(data_->pdf_stream_.getOffset(), 0U);
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (fd.fd < 0) {
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "Invalid file descriptor!";
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool result = true;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkAutoDataUnref data(data_->pdf_stream_.copyToData());
209a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  if (base::WriteFileDescriptor(fd.fd,
210a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                reinterpret_cast<const char*>(data->data()),
211a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)                                GetDataSize()) !=
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<int>(GetDataSize())) {
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DLOG(ERROR) << "Failed to save file with fd " << fd.fd;
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result = false;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (fd.auto_close) {
218a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    if (IGNORE_EINTR(close(fd.fd)) < 0) {
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DPLOG(WARNING) << "close";
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      result = false;
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PdfMetafileSkia::PdfMetafileSkia()
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : data_(new PdfMetafileSkiaData),
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      page_outstanding_(false) {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PdfMetafileSkia* PdfMetafileSkia::GetMetafileForCurrentPage() {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkPDFDocument pdf_doc(SkPDFDocument::kDraftMode_Flags);
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkDynamicMemoryWStream pdf_stream;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pdf_doc.appendPage(data_->current_page_.get()))
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!pdf_doc.emitPDF(&pdf_stream))
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SkAutoDataUnref data(pdf_stream.copyToData());
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (data->size() == 0)
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  PdfMetafileSkia* metafile = new PdfMetafileSkia;
2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  metafile->InitFromData(data->bytes(),
2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)                         base::checked_cast<uint32>(data->size()));
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return metafile;
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace printing
252