// Copyright 2016 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "core/fpdfapi/render/cpdf_devicebuffer.h"

#include <utility>

#include "build/build_config.h"
#include "core/fpdfapi/page/cpdf_pageobject.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/render/cpdf_renderoptions.h"
#include "core/fxge/cfx_defaultrenderdevice.h"
#include "core/fxge/cfx_renderdevice.h"
#include "core/fxge/dib/cfx_dibitmap.h"
#include "core/fxge/dib/fx_dib.h"

#if BUILDFLAG(IS_WIN)
#include "core/fpdfapi/render/cpdf_rendercontext.h"
#else
#include "core/fxcrt/notreached.h"
#endif

// static
CFX_Matrix CPDF_DeviceBuffer::CalculateMatrix(CFX_RenderDevice* pDevice,
                                              const FX_RECT& rect,
                                              int max_dpi) {
  CFX_Matrix matrix;
  matrix.Translate(-rect.left, -rect.top);
#if BUILDFLAG(IS_WIN)
  int horz_size = pDevice->GetHorzSize();
  int vert_size = pDevice->GetVertSize();
  if (horz_size && vert_size && max_dpi) {
    int dpih = pDevice->GetWidth() * 254 / (horz_size * 10);
    int dpiv = pDevice->GetHeight() * 254 / (vert_size * 10);
    if (dpih > max_dpi) {
      matrix.Scale(static_cast<float>(max_dpi) / dpih, 1.0f);
    }
    if (dpiv > max_dpi) {
      matrix.Scale(1.0f, static_cast<float>(max_dpi) / dpiv);
    }
  }
#endif  // BUILDFLAG(IS_WIN)
  return matrix;
}

CPDF_DeviceBuffer::CPDF_DeviceBuffer(CPDF_RenderContext* context,
                                     CFX_RenderDevice* pDevice,
                                     const FX_RECT& rect,
                                     const CPDF_PageObject* pObj,
                                     int max_dpi)
    : device_(pDevice),
#if BUILDFLAG(IS_WIN)
      context_(context),
#endif
      object_(pObj),
      bitmap_(pdfium::MakeRetain<CFX_DIBitmap>()),
      rect_(rect),
      matrix_(CalculateMatrix(pDevice, rect, max_dpi)) {
}

CPDF_DeviceBuffer::~CPDF_DeviceBuffer() = default;

RetainPtr<CFX_DIBitmap> CPDF_DeviceBuffer::Initialize() {
  FX_RECT bitmap_rect =
      matrix_.TransformRect(CFX_FloatRect(rect_)).GetOuterRect();
  // TODO(crbug.com/355630557): Consider adding support for
  // `FXDIB_Format::kBgraPremul`
  if (!bitmap_->Create(bitmap_rect.Width(), bitmap_rect.Height(),
                       FXDIB_Format::kBgra)) {
    return nullptr;
  }
  return bitmap_;
}

void CPDF_DeviceBuffer::OutputToDevice() {
  if (device_->RenderCapGetBits()) {
    if (matrix_.a == 1.0f && matrix_.d == 1.0f) {
      device_->SetDIBits(bitmap_, rect_.left, rect_.top);
      return;
    }

#if BUILDFLAG(IS_WIN)
    device_->StretchDIBits(bitmap_, rect_.left, rect_.top, rect_.Width(),
                           rect_.Height());
    return;
#else
    NOTREACHED();
#endif
  }

#if BUILDFLAG(IS_WIN)
  auto buffer = pdfium::MakeRetain<CFX_DIBitmap>();
  if (!device_->CreateCompatibleBitmap(buffer, bitmap_->GetWidth(),
                                       bitmap_->GetHeight())) {
    return;
  }
  context_->GetBackgroundToBitmap(buffer, object_, matrix_);
  buffer->CompositeBitmap(0, 0, buffer->GetWidth(), buffer->GetHeight(),
                          bitmap_, 0, 0, BlendMode::kNormal);
  device_->StretchDIBits(std::move(buffer), rect_.left, rect_.top,
                         rect_.Width(), rect_.Height());
#else
  NOTREACHED();
#endif
}
