// 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_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
}
