1 // Copyright 2014 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 "public/fpdf_progressive.h"
8
9 #include <memory>
10 #include <utility>
11
12 #include "core/fpdfapi/page/cpdf_page.h"
13 #include "core/fpdfapi/render/cpdf_pagerendercontext.h"
14 #include "core/fpdfapi/render/cpdf_progressiverenderer.h"
15 #include "core/fxge/cfx_defaultrenderdevice.h"
16 #include "fpdfsdk/cpdfsdk_helpers.h"
17 #include "fpdfsdk/cpdfsdk_pauseadapter.h"
18 #include "fpdfsdk/cpdfsdk_renderpage.h"
19 #include "public/fpdfview.h"
20
21 // These checks are here because core/ and public/ cannot depend on each other.
22 static_assert(CPDF_ProgressiveRenderer::kReady == FPDF_RENDER_READY,
23 "CPDF_ProgressiveRenderer::kReady value mismatch");
24 static_assert(CPDF_ProgressiveRenderer::kToBeContinued ==
25 FPDF_RENDER_TOBECONTINUED,
26 "CPDF_ProgressiveRenderer::kToBeContinued value mismatch");
27 static_assert(CPDF_ProgressiveRenderer::kDone == FPDF_RENDER_DONE,
28 "CPDF_ProgressiveRenderer::kDone value mismatch");
29 static_assert(CPDF_ProgressiveRenderer::kFailed == FPDF_RENDER_FAILED,
30 "CPDF_ProgressiveRenderer::kFailed value mismatch");
31
32 namespace {
33
ToFPDFStatus(CPDF_ProgressiveRenderer::Status status)34 int ToFPDFStatus(CPDF_ProgressiveRenderer::Status status) {
35 return static_cast<int>(status);
36 }
37
38 } // namespace
39
40 FPDF_EXPORT int FPDF_CALLCONV
FPDF_RenderPageBitmapWithColorScheme_Start(FPDF_BITMAP bitmap,FPDF_PAGE page,int start_x,int start_y,int size_x,int size_y,int rotate,int flags,const FPDF_COLORSCHEME * color_scheme,IFSDK_PAUSE * pause)41 FPDF_RenderPageBitmapWithColorScheme_Start(FPDF_BITMAP bitmap,
42 FPDF_PAGE page,
43 int start_x,
44 int start_y,
45 int size_x,
46 int size_y,
47 int rotate,
48 int flags,
49 const FPDF_COLORSCHEME* color_scheme,
50 IFSDK_PAUSE* pause) {
51 if (!bitmap || !pause || pause->version != 1)
52 return FPDF_RENDER_FAILED;
53
54 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
55 if (!pPage)
56 return FPDF_RENDER_FAILED;
57
58 auto pOwnedContext = std::make_unique<CPDF_PageRenderContext>();
59 CPDF_PageRenderContext* pContext = pOwnedContext.get();
60 pPage->SetRenderContext(std::move(pOwnedContext));
61
62 RetainPtr<CFX_DIBitmap> pBitmap(CFXDIBitmapFromFPDFBitmap(bitmap));
63 auto pOwnedDevice = std::make_unique<CFX_DefaultRenderDevice>();
64 CFX_DefaultRenderDevice* pDevice = pOwnedDevice.get();
65 pContext->m_pDevice = std::move(pOwnedDevice);
66 pDevice->AttachWithRgbByteOrder(pBitmap, !!(flags & FPDF_REVERSE_BYTE_ORDER));
67
68 CPDFSDK_PauseAdapter pause_adapter(pause);
69 CPDFSDK_RenderPageWithContext(pContext, pPage, start_x, start_y, size_x,
70 size_y, rotate, flags, color_scheme,
71 /*need_to_restore=*/false, &pause_adapter);
72
73 #if defined(_SKIA_SUPPORT_)
74 if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer()) {
75 pBitmap->UnPreMultiply();
76 }
77 #endif // defined(_SKIA_SUPPORT_)
78
79 if (!pContext->m_pRenderer)
80 return FPDF_RENDER_FAILED;
81
82 return ToFPDFStatus(pContext->m_pRenderer->GetStatus());
83 }
84
FPDF_RenderPageBitmap_Start(FPDF_BITMAP bitmap,FPDF_PAGE page,int start_x,int start_y,int size_x,int size_y,int rotate,int flags,IFSDK_PAUSE * pause)85 FPDF_EXPORT int FPDF_CALLCONV FPDF_RenderPageBitmap_Start(FPDF_BITMAP bitmap,
86 FPDF_PAGE page,
87 int start_x,
88 int start_y,
89 int size_x,
90 int size_y,
91 int rotate,
92 int flags,
93 IFSDK_PAUSE* pause) {
94 return FPDF_RenderPageBitmapWithColorScheme_Start(
95 bitmap, page, start_x, start_y, size_x, size_y, rotate, flags,
96 /*color_scheme=*/nullptr, pause);
97 }
98
FPDF_RenderPage_Continue(FPDF_PAGE page,IFSDK_PAUSE * pause)99 FPDF_EXPORT int FPDF_CALLCONV FPDF_RenderPage_Continue(FPDF_PAGE page,
100 IFSDK_PAUSE* pause) {
101 if (!pause || pause->version != 1)
102 return FPDF_RENDER_FAILED;
103
104 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
105 if (!pPage)
106 return FPDF_RENDER_FAILED;
107
108 auto* pContext =
109 static_cast<CPDF_PageRenderContext*>(pPage->GetRenderContext());
110 if (!pContext || !pContext->m_pRenderer)
111 return FPDF_RENDER_FAILED;
112
113 CPDFSDK_PauseAdapter pause_adapter(pause);
114 pContext->m_pRenderer->Continue(&pause_adapter);
115
116 #if defined(_SKIA_SUPPORT_)
117 if (CFX_DefaultRenderDevice::SkiaIsDefaultRenderer()) {
118 pContext->m_pDevice->GetBitmap()->UnPreMultiply();
119 }
120 #endif // defined(_SKIA_SUPPORT_)
121 return ToFPDFStatus(pContext->m_pRenderer->GetStatus());
122 }
123
FPDF_RenderPage_Close(FPDF_PAGE page)124 FPDF_EXPORT void FPDF_CALLCONV FPDF_RenderPage_Close(FPDF_PAGE page) {
125 CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
126 if (pPage)
127 pPage->ClearRenderContext();
128 }
129