• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2016 The PDFium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6 
7 #include "core/fpdfapi/render/cpdf_scaledrenderbuffer.h"
8 
9 #include "build/build_config.h"
10 #include "core/fpdfapi/parser/cpdf_dictionary.h"
11 #include "core/fpdfapi/render/cpdf_devicebuffer.h"
12 #include "core/fpdfapi/render/cpdf_rendercontext.h"
13 #include "core/fxge/cfx_defaultrenderdevice.h"
14 #include "core/fxge/dib/cfx_dibitmap.h"
15 
16 namespace {
17 
18 constexpr size_t kImageSizeLimitBytes = 30 * 1024 * 1024;
19 
20 }  // namespace
21 
CPDF_ScaledRenderBuffer(CFX_RenderDevice * device,const FX_RECT & rect)22 CPDF_ScaledRenderBuffer::CPDF_ScaledRenderBuffer(CFX_RenderDevice* device,
23                                                  const FX_RECT& rect)
24     : device_(device),
25       bitmap_device_(std::make_unique<CFX_DefaultRenderDevice>()),
26       rect_(rect) {}
27 
28 CPDF_ScaledRenderBuffer::~CPDF_ScaledRenderBuffer() = default;
29 
Initialize(CPDF_RenderContext * pContext,const CPDF_PageObject * pObj,const CPDF_RenderOptions & options,int max_dpi)30 bool CPDF_ScaledRenderBuffer::Initialize(CPDF_RenderContext* pContext,
31                                          const CPDF_PageObject* pObj,
32                                          const CPDF_RenderOptions& options,
33                                          int max_dpi) {
34   matrix_ = CPDF_DeviceBuffer::CalculateMatrix(device_, rect_, max_dpi,
35                                                /*scale=*/true);
36   bool bIsAlpha =
37       !!(device_->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_ALPHA_OUTPUT);
38   FXDIB_Format dibFormat = bIsAlpha ? FXDIB_Format::kBgra : FXDIB_Format::kBgr;
39   while (true) {
40     FX_RECT bitmap_rect =
41         matrix_.TransformRect(CFX_FloatRect(rect_)).GetOuterRect();
42     int32_t width = bitmap_rect.Width();
43     int32_t height = bitmap_rect.Height();
44     // Set to 0 to make CalculatePitchAndSize() calculate it.
45     constexpr uint32_t kNoPitch = 0;
46     std::optional<CFX_DIBitmap::PitchAndSize> pitch_size =
47         CFX_DIBitmap::CalculatePitchAndSize(width, height, dibFormat, kNoPitch);
48     if (!pitch_size.has_value())
49       return false;
50 
51     if (pitch_size.value().size <= kImageSizeLimitBytes &&
52         bitmap_device_->Create(width, height, dibFormat)) {
53       break;
54     }
55     matrix_.Scale(0.5f, 0.5f);
56   }
57   pContext->GetBackgroundToDevice(bitmap_device_.get(), pObj, &options,
58                                   matrix_);
59   return true;
60 }
61 
GetDevice()62 CFX_DefaultRenderDevice* CPDF_ScaledRenderBuffer::GetDevice() {
63   return bitmap_device_.get();
64 }
65 
OutputToDevice()66 void CPDF_ScaledRenderBuffer::OutputToDevice() {
67 #if defined(PDF_USE_SKIA)
68   bitmap_device_->SyncInternalBitmaps();
69 #endif
70   device_->StretchDIBits(bitmap_device_->GetBitmap(), rect_.left, rect_.top,
71                          rect_.Width(), rect_.Height());
72 }
73