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

#include <utility>

#include "build/build_config.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/render/cpdf_devicebuffer.h"
#include "core/fpdfapi/render/cpdf_rendercontext.h"
#include "core/fxge/cfx_renderdevice.h"
#include "core/fxge/dib/cfx_dibitmap.h"

namespace {

constexpr size_t kImageSizeLimitBytes = 30 * 1024 * 1024;

}  // namespace

CPDF_ScaledRenderBuffer::CPDF_ScaledRenderBuffer(CFX_RenderDevice* device,
                                                 const FX_RECT& rect)
    : device_(device),
      rect_(rect) {}

CPDF_ScaledRenderBuffer::~CPDF_ScaledRenderBuffer() = default;

bool CPDF_ScaledRenderBuffer::Initialize(CPDF_RenderContext* context,
                                         const CPDF_PageObject* pObj,
                                         const CPDF_RenderOptions& options,
                                         int max_dpi) {
  matrix_ = CPDF_DeviceBuffer::CalculateMatrix(device_, rect_, max_dpi);
  FXDIB_Format dibFormat = device_->RenderCapAlphaOutput() ? FXDIB_Format::kBgra
                                                           : FXDIB_Format::kBgr;
  while (true) {
    FX_RECT bitmap_rect =
        matrix_.TransformRect(CFX_FloatRect(rect_)).GetOuterRect();
    int32_t width = bitmap_rect.Width();
    int32_t height = bitmap_rect.Height();

    // Set to 0 to make CalculatePitchAndSize() calculate it.
    constexpr uint32_t kNoPitch = 0;
    std::optional<CFX_DIBitmap::PitchAndSize> pitch_size =
        CFX_DIBitmap::CalculatePitchAndSize(width, height, dibFormat, kNoPitch);
    if (!pitch_size.has_value()) {
      return false;
    }

    if (pitch_size.value().size <= kImageSizeLimitBytes) {
      auto bitmap = pdfium::MakeRetain<CFX_DIBitmap>();
      if (bitmap->Create(width, height, dibFormat)) {
        bitmap_device_ = CFX_RenderDevice::CreateForBitmap(std::move(bitmap));
        if (bitmap_device_) {
          context->GetBackgroundToDevice(bitmap_device_.get(), pObj, &options,
                                         matrix_);
          return true;
        }
      }
    }

    // Once dimensions are at a minimum, further scaling cannot help.
    if (width <= 1 && height <= 1) {
      return false;
    }
    matrix_.Scale(0.5f, 0.5f);
  }
}

CFX_RenderDevice* CPDF_ScaledRenderBuffer::GetDevice() {
  return bitmap_device_.get();
}

void CPDF_ScaledRenderBuffer::OutputToDevice() {
#if defined(PDF_USE_SKIA)
  bitmap_device_->SyncInternalBitmaps();
#endif
  device_->StretchDIBits(bitmap_device_->GetBitmap(), rect_.left, rect_.top,
                         rect_.Width(), rect_.Height());
}
