Home | History | Annotate | Download | only in fpdfsdk
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      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 <utility>
     10 
     11 #include "core/fpdfapi/cpdf_pagerendercontext.h"
     12 #include "core/fpdfapi/page/cpdf_page.h"
     13 #include "core/fpdfapi/render/cpdf_progressiverenderer.h"
     14 #include "core/fxcrt/fx_memory.h"
     15 #include "core/fxge/cfx_defaultrenderdevice.h"
     16 #include "core/fxge/cfx_renderdevice.h"
     17 #include "fpdfsdk/fsdk_define.h"
     18 #include "fpdfsdk/fsdk_pauseadapter.h"
     19 #include "public/fpdfview.h"
     20 #include "third_party/base/ptr_util.h"
     21 
     22 // These checks are here because core/ and public/ cannot depend on each other.
     23 static_assert(CPDF_ProgressiveRenderer::Ready == FPDF_RENDER_READY,
     24               "CPDF_ProgressiveRenderer::Ready value mismatch");
     25 static_assert(CPDF_ProgressiveRenderer::ToBeContinued ==
     26                   FPDF_RENDER_TOBECONTINUED,
     27               "CPDF_ProgressiveRenderer::ToBeContinued value mismatch");
     28 static_assert(CPDF_ProgressiveRenderer::Done == FPDF_RENDER_DONE,
     29               "CPDF_ProgressiveRenderer::Done value mismatch");
     30 static_assert(CPDF_ProgressiveRenderer::Failed == FPDF_RENDER_FAILED,
     31               "CPDF_ProgressiveRenderer::Failed value mismatch");
     32 
     33 FPDF_EXPORT int FPDF_CALLCONV FPDF_RenderPageBitmap_Start(FPDF_BITMAP bitmap,
     34                                                           FPDF_PAGE page,
     35                                                           int start_x,
     36                                                           int start_y,
     37                                                           int size_x,
     38                                                           int size_y,
     39                                                           int rotate,
     40                                                           int flags,
     41                                                           IFSDK_PAUSE* pause) {
     42   if (!bitmap || !pause || pause->version != 1)
     43     return FPDF_RENDER_FAILED;
     44 
     45   CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
     46   if (!pPage)
     47     return FPDF_RENDER_FAILED;
     48 
     49   auto pOwnedContext = pdfium::MakeUnique<CPDF_PageRenderContext>();
     50   CPDF_PageRenderContext* pContext = pOwnedContext.get();
     51   pPage->SetRenderContext(std::move(pOwnedContext));
     52 
     53   RetainPtr<CFX_DIBitmap> pBitmap(CFXBitmapFromFPDFBitmap(bitmap));
     54   auto pOwnedDevice = pdfium::MakeUnique<CFX_DefaultRenderDevice>();
     55   CFX_DefaultRenderDevice* pDevice = pOwnedDevice.get();
     56   pContext->m_pDevice = std::move(pOwnedDevice);
     57   pDevice->Attach(pBitmap, !!(flags & FPDF_REVERSE_BYTE_ORDER), nullptr, false);
     58 
     59   IFSDK_PAUSE_Adapter IPauseAdapter(pause);
     60   FPDF_RenderPage_Retail(pContext, page, start_x, start_y, size_x, size_y,
     61                          rotate, flags, false, &IPauseAdapter);
     62 
     63 #ifdef _SKIA_SUPPORT_PATHS_
     64   pDevice->Flush(false);
     65   pBitmap->UnPreMultiply();
     66 #endif
     67   if (pContext->m_pRenderer) {
     68     return CPDF_ProgressiveRenderer::ToFPDFStatus(
     69         pContext->m_pRenderer->GetStatus());
     70   }
     71   return FPDF_RENDER_FAILED;
     72 }
     73 
     74 FPDF_EXPORT int FPDF_CALLCONV FPDF_RenderPage_Continue(FPDF_PAGE page,
     75                                                        IFSDK_PAUSE* pause) {
     76   if (!pause || pause->version != 1)
     77     return FPDF_RENDER_FAILED;
     78 
     79   CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
     80   if (!pPage)
     81     return FPDF_RENDER_FAILED;
     82 
     83   CPDF_PageRenderContext* pContext = pPage->GetRenderContext();
     84   if (pContext && pContext->m_pRenderer) {
     85     IFSDK_PAUSE_Adapter IPauseAdapter(pause);
     86     pContext->m_pRenderer->Continue(&IPauseAdapter);
     87 #ifdef _SKIA_SUPPORT_PATHS_
     88     CFX_RenderDevice* pDevice = pContext->m_pDevice.get();
     89     pDevice->Flush(false);
     90     pDevice->GetBitmap()->UnPreMultiply();
     91 #endif
     92     return CPDF_ProgressiveRenderer::ToFPDFStatus(
     93         pContext->m_pRenderer->GetStatus());
     94   }
     95   return FPDF_RENDER_FAILED;
     96 }
     97 
     98 FPDF_EXPORT void FPDF_CALLCONV FPDF_RenderPage_Close(FPDF_PAGE page) {
     99   CPDF_Page* pPage = CPDFPageFromFPDFPage(page);
    100   if (pPage) {
    101 #ifdef _SKIA_SUPPORT_PATHS_
    102     CPDF_PageRenderContext* pContext = pPage->GetRenderContext();
    103     if (pContext && pContext->m_pRenderer) {
    104       CFX_RenderDevice* pDevice = pContext->m_pDevice.get();
    105       pDevice->Flush(true);
    106       pDevice->GetBitmap()->UnPreMultiply();
    107     }
    108 #endif
    109     pPage->SetRenderContext(nullptr);
    110   }
    111 }
    112