// 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 "printing/pdf_metafile_cg_mac.h"

#include <stdint.h>

#include <algorithm>

#include "base/logging.h"
#include "base/mac/mac_util.h"
#include "base/mac/scoped_cftyperef.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/sys_string_conversions.h"
#include "ui/gfx/geometry/rect.h"
#include "ui/gfx/geometry/size.h"

using base::ScopedCFTypeRef;

namespace {

// Rotate a page by |num_rotations| * 90 degrees, counter-clockwise.
void RotatePage(CGContextRef context, const CGRect rect, int num_rotations) {
  switch (num_rotations) {
    case 0:
      break;
    case 1:
      // After rotating by 90 degrees with the axis at the origin, the page
      // content is now "off screen". Shift it right to move it back on screen.
      CGContextTranslateCTM(context, rect.size.width, 0);
      // Rotates counter-clockwise by 90 degrees.
      CGContextRotateCTM(context, M_PI_2);
      break;
    case 2:
      // After rotating by 180 degrees with the axis at the origin, the page
      // content is now "off screen". Shift it right and up to move it back on
      // screen.
      CGContextTranslateCTM(context, rect.size.width, rect.size.height);
      // Rotates counter-clockwise by 90 degrees.
      CGContextRotateCTM(context, M_PI);
      break;
    case 3:
      // After rotating by 270 degrees with the axis at the origin, the page
      // content is now "off screen". Shift it right to move it back on screen.
      CGContextTranslateCTM(context, 0, rect.size.height);
      // Rotates counter-clockwise by 90 degrees.
      CGContextRotateCTM(context, -M_PI_2);
      break;
    default:
      NOTREACHED();
      break;
  }
}

}  // namespace

namespace printing {

PdfMetafileCg::PdfMetafileCg() : page_is_open_(false) {}

PdfMetafileCg::~PdfMetafileCg() {}

bool PdfMetafileCg::Init() {
  // Ensure that Init hasn't already been called.
  DCHECK(!context_.get());
  DCHECK(!pdf_data_.get());

  pdf_data_.reset(CFDataCreateMutable(kCFAllocatorDefault, 0));
  if (!pdf_data_.get()) {
    LOG(ERROR) << "Failed to create pdf data for metafile";
    return false;
  }
  ScopedCFTypeRef<CGDataConsumerRef> pdf_consumer(
      CGDataConsumerCreateWithCFData(pdf_data_));
  if (!pdf_consumer.get()) {
    LOG(ERROR) << "Failed to create data consumer for metafile";
    pdf_data_.reset();
    return false;
  }
  context_.reset(CGPDFContextCreate(pdf_consumer, nullptr, nullptr));
  if (!context_.get()) {
    LOG(ERROR) << "Failed to create pdf context for metafile";
    pdf_data_.reset();
  }

  return true;
}

bool PdfMetafileCg::InitFromData(const void* src_buffer,
                                 size_t src_buffer_size) {
  DCHECK(!context_.get());
  DCHECK(!pdf_data_.get());

  if (!src_buffer || !src_buffer_size)
    return false;

  if (!base::IsValueInRangeForNumericType<CFIndex>(src_buffer_size))
    return false;

  pdf_data_.reset(CFDataCreateMutable(kCFAllocatorDefault, src_buffer_size));
  CFDataAppendBytes(pdf_data_, static_cast<const UInt8*>(src_buffer),
                    src_buffer_size);

  return true;
}

void PdfMetafileCg::StartPage(const gfx::Size& page_size,
                              const gfx::Rect& content_area,
                              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;
  CGContextSaveGState(context_);

  // Move to the context origin.
  CGContextTranslateCTM(context_, content_area.x(), -content_area.y());

  // Flip the context.
  CGContextTranslateCTM(context_, 0, height);
  CGContextScaleCTM(context_, scale_factor, -scale_factor);
}

bool PdfMetafileCg::FinishPage() {
  DCHECK(context_.get());
  DCHECK(page_is_open_);

  CGContextRestoreGState(context_);
  CGContextEndPage(context_);
  page_is_open_ = false;
  return true;
}

bool PdfMetafileCg::FinishDocument() {
  DCHECK(context_.get());
  DCHECK(!page_is_open_);

#ifndef NDEBUG
  // Check that the context will be torn down properly; if it's not, pdf_data_
  // will be incomplete and generate invalid PDF files/documents.
  if (context_.get()) {
    CFIndex extra_retain_count = CFGetRetainCount(context_.get()) - 1;
    if (extra_retain_count > 0) {
      LOG(ERROR) << "Metafile context has " << extra_retain_count
                 << " extra retain(s) on Close";
    }
  }
#endif
  CGPDFContextClose(context_.get());
  context_.reset();
  return true;
}

/* TODO(caryclark): The set up of PluginInstance::PrintPDFOutput may result in
   rasterized output.  Even if that flow uses PdfMetafileCg::RenderPage,
   the drawing of the PDF into the canvas may result in a rasterized output.
   PDFMetafileSkia::RenderPage should be not implemented as shown and instead
   should do something like the following CL in PluginInstance::PrintPDFOutput:
   http://codereview.chromium.org/7200040/diff/1/webkit/plugins/ppapi/ppapi_plugin_instance.cc
*/
bool PdfMetafileCg::RenderPage(const std::vector<char>& src_buffer,
                               unsigned int page_number,
                               CGContextRef context,
                               const CGRect rect,
                               const PdfMetafileCg::RenderPageParams& params) {
  PdfMetafileCg metafile;
  if (!metafile.InitFromData(src_buffer.data(), src_buffer.size())) {
    LOG(ERROR) << "Unable to initialize PDF document from data";
    return false;
  }
  return metafile.OnRenderPage(page_number, context, rect, params);
}

bool PdfMetafileCg::OnRenderPage(
    unsigned int page_number,
    CGContextRef context,
    const CGRect rect,
    const PdfMetafileCg::RenderPageParams& params) {
  CGPDFDocumentRef pdf_doc = GetPDFDocument();
  if (!pdf_doc) {
    LOG(ERROR) << "Unable to create PDF document from data";
    return false;
  }
  CGPDFPageRef pdf_page = CGPDFDocumentGetPage(pdf_doc, page_number);
  CGRect source_rect = CGPDFPageGetBoxRect(pdf_page, kCGPDFCropBox);
  int pdf_src_rotation = CGPDFPageGetRotationAngle(pdf_page);
  float scaling_factor = 1.0;
  const bool source_is_landscape =
        (source_rect.size.width > source_rect.size.height);
  const bool dest_is_landscape = (rect.size.width > rect.size.height);
  const bool rotate =
      params.autorotate ? (source_is_landscape != dest_is_landscape) : false;
  const float source_width =
      rotate ? source_rect.size.height : source_rect.size.width;
  const float source_height =
      rotate ? source_rect.size.width : source_rect.size.height;

  // See if we need to scale the output.
  const bool scaling_needed =
      (params.shrink_to_fit && ((source_width > rect.size.width) ||
                                (source_height > rect.size.height))) ||
      (params.stretch_to_fit && ((source_width < rect.size.width) &&
                                 (source_height < rect.size.height)));
  if (scaling_needed) {
    float x_scaling_factor = rect.size.width / source_width;
    float y_scaling_factor = rect.size.height / source_height;
    scaling_factor = std::min(x_scaling_factor, y_scaling_factor);
  }
  // Some PDFs have a non-zero origin. Need to take that into account and align
  // the PDF to the origin.
  const float x_origin_offset = -1 * source_rect.origin.x;
  const float y_origin_offset = -1 * source_rect.origin.y;

  // If the PDF needs to be centered, calculate the offsets here.
  float x_offset = params.center_horizontally ?
      ((rect.size.width - (source_width * scaling_factor)) / 2) : 0;
  if (rotate)
    x_offset = -x_offset;

  float y_offset = params.center_vertically ?
      ((rect.size.height - (source_height * scaling_factor)) / 2) : 0;

  CGContextSaveGState(context);

  // The transform operations specified here gets applied in reverse order.
  // i.e. the origin offset translation happens first.
  // Origin is at bottom-left.
  CGContextTranslateCTM(context, x_offset, y_offset);

  int num_rotations = 0;
  if (rotate) {
    if (pdf_src_rotation == 0 || pdf_src_rotation == 270) {
      num_rotations = 1;
    } else {
      num_rotations = 3;
    }
  } else {
    if (pdf_src_rotation == 180 || pdf_src_rotation == 270) {
      num_rotations = 2;
    }
  }
  RotatePage(context, rect, num_rotations);

  CGContextScaleCTM(context, scaling_factor, scaling_factor);
  CGContextTranslateCTM(context, x_origin_offset, y_origin_offset);

  CGContextDrawPDFPage(context, pdf_page);
  CGContextRestoreGState(context);

  return true;
}

unsigned int PdfMetafileCg::GetPageCount() const {
  CGPDFDocumentRef pdf_doc = GetPDFDocument();
  return pdf_doc ? CGPDFDocumentGetNumberOfPages(pdf_doc) : 0;
}

gfx::Rect PdfMetafileCg::GetPageBounds(unsigned int page_number) const {
  CGPDFDocumentRef pdf_doc = GetPDFDocument();
  if (!pdf_doc) {
    LOG(ERROR) << "Unable to create PDF document from data";
    return gfx::Rect();
  }
  if (page_number > GetPageCount()) {
    LOG(ERROR) << "Invalid page number: " << page_number;
    return gfx::Rect();
  }
  CGPDFPageRef pdf_page = CGPDFDocumentGetPage(pdf_doc, page_number);
  CGRect page_rect = CGPDFPageGetBoxRect(pdf_page, kCGPDFMediaBox);
  return gfx::Rect(page_rect);
}

uint32_t PdfMetafileCg::GetDataSize() const {
  // PDF data is only valid/complete once the context is released.
  DCHECK(!context_);

  if (!pdf_data_)
    return 0;
  return static_cast<uint32_t>(CFDataGetLength(pdf_data_));
}

bool PdfMetafileCg::GetData(void* dst_buffer, uint32_t dst_buffer_size) const {
  // PDF data is only valid/complete once the context is released.
  DCHECK(!context_);
  DCHECK(pdf_data_);
  DCHECK(dst_buffer);
  DCHECK_GT(dst_buffer_size, 0U);

  uint32_t data_size = GetDataSize();
  if (dst_buffer_size > data_size) {
    return false;
  }

  CFDataGetBytes(pdf_data_, CFRangeMake(0, dst_buffer_size),
                 static_cast<UInt8*>(dst_buffer));
  return true;
}

CGContextRef PdfMetafileCg::context() const {
  return context_.get();
}

CGPDFDocumentRef PdfMetafileCg::GetPDFDocument() const {
  // Make sure that we have data, and that it's not being modified any more.
  DCHECK(pdf_data_.get());
  DCHECK(!context_.get());

  if (!pdf_doc_.get()) {
    ScopedCFTypeRef<CGDataProviderRef> pdf_data_provider(
        CGDataProviderCreateWithCFData(pdf_data_));
    pdf_doc_.reset(CGPDFDocumentCreateWithProvider(pdf_data_provider));
  }
  return pdf_doc_.get();
}

}  // namespace printing
