Home | History | Annotate | Download | only in fde
      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 "xfa/fde/fde_render.h"
      8 
      9 #include "third_party/base/ptr_util.h"
     10 #include "xfa/fde/fde_gedevice.h"
     11 #include "xfa/fde/fde_object.h"
     12 
     13 #define FDE_PATHRENDER_Stroke 1
     14 #define FDE_PATHRENDER_Fill 2
     15 
     16 CFDE_RenderContext::CFDE_RenderContext()
     17     : m_eStatus(FDE_RENDERSTATUS_Reset),
     18       m_pRenderDevice(nullptr),
     19       m_Transform() {
     20   m_Transform.SetIdentity();
     21 }
     22 
     23 CFDE_RenderContext::~CFDE_RenderContext() {
     24   StopRender();
     25 }
     26 
     27 bool CFDE_RenderContext::StartRender(CFDE_RenderDevice* pRenderDevice,
     28                                      IFDE_CanvasSet* pCanvasSet,
     29                                      const CFX_Matrix& tmDoc2Device) {
     30   if (m_pRenderDevice)
     31     return false;
     32   if (!pRenderDevice)
     33     return false;
     34   if (!pCanvasSet)
     35     return false;
     36 
     37   m_eStatus = FDE_RENDERSTATUS_Paused;
     38   m_pRenderDevice = pRenderDevice;
     39   m_Transform = tmDoc2Device;
     40   if (!m_pIterator)
     41     m_pIterator = pdfium::MakeUnique<CFDE_VisualSetIterator>();
     42 
     43   return m_pIterator->AttachCanvas(pCanvasSet) && m_pIterator->FilterObjects();
     44 }
     45 
     46 FDE_RENDERSTATUS CFDE_RenderContext::DoRender(IFX_Pause* pPause) {
     47   if (!m_pRenderDevice)
     48     return FDE_RENDERSTATUS_Failed;
     49   if (!m_pIterator)
     50     return FDE_RENDERSTATUS_Failed;
     51 
     52   FDE_RENDERSTATUS eStatus = FDE_RENDERSTATUS_Paused;
     53   CFX_Matrix rm;
     54   rm.SetReverse(m_Transform);
     55   CFX_RectF rtDocClip = m_pRenderDevice->GetClipRect();
     56   if (rtDocClip.IsEmpty()) {
     57     rtDocClip.left = rtDocClip.top = 0;
     58     rtDocClip.width = (FX_FLOAT)m_pRenderDevice->GetWidth();
     59     rtDocClip.height = (FX_FLOAT)m_pRenderDevice->GetHeight();
     60   }
     61   rm.TransformRect(rtDocClip);
     62   IFDE_VisualSet* pVisualSet;
     63   FDE_TEXTEDITPIECE* pPiece;
     64   int32_t iCount = 0;
     65   while (true) {
     66     pPiece = m_pIterator->GetNext(pVisualSet);
     67     if (!pPiece || !pVisualSet) {
     68       eStatus = FDE_RENDERSTATUS_Done;
     69       break;
     70     }
     71     if (!rtDocClip.IntersectWith(pVisualSet->GetRect(*pPiece)))
     72       continue;
     73 
     74     switch (pVisualSet->GetType()) {
     75       case FDE_VISUALOBJ_Text:
     76         RenderText(static_cast<IFDE_TextSet*>(pVisualSet), pPiece);
     77         iCount += 5;
     78         break;
     79       case FDE_VISUALOBJ_Canvas:
     80         ASSERT(false);
     81         break;
     82       default:
     83         break;
     84     }
     85     if (iCount >= 100 && pPause && pPause->NeedToPauseNow()) {
     86       eStatus = FDE_RENDERSTATUS_Paused;
     87       break;
     88     }
     89   }
     90   return m_eStatus = eStatus;
     91 }
     92 
     93 void CFDE_RenderContext::StopRender() {
     94   m_eStatus = FDE_RENDERSTATUS_Reset;
     95   m_pRenderDevice = nullptr;
     96   m_Transform.SetIdentity();
     97   m_pIterator.reset();
     98   m_pBrush.reset();
     99   m_CharPos.clear();
    100 }
    101 
    102 void CFDE_RenderContext::RenderText(IFDE_TextSet* pTextSet,
    103                                     FDE_TEXTEDITPIECE* pText) {
    104   ASSERT(m_pRenderDevice);
    105   ASSERT(pTextSet && pText);
    106 
    107   CFX_RetainPtr<CFGAS_GEFont> pFont = pTextSet->GetFont();
    108   if (!pFont)
    109     return;
    110 
    111   int32_t iCount = pTextSet->GetDisplayPos(*pText, nullptr, false);
    112   if (iCount < 1)
    113     return;
    114 
    115   if (!m_pBrush)
    116     m_pBrush = pdfium::MakeUnique<CFDE_Brush>();
    117 
    118   if (m_CharPos.size() < static_cast<size_t>(iCount))
    119     m_CharPos.resize(iCount, FXTEXT_CHARPOS());
    120 
    121   iCount = pTextSet->GetDisplayPos(*pText, m_CharPos.data(), false);
    122   FX_FLOAT fFontSize = pTextSet->GetFontSize();
    123   FX_ARGB dwColor = pTextSet->GetFontColor();
    124   m_pBrush->SetColor(dwColor);
    125   m_pRenderDevice->DrawString(m_pBrush.get(), pFont, m_CharPos.data(), iCount,
    126                               fFontSize, &m_Transform);
    127 }
    128 
    129