• Home
  • History
  • Annotate
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
CFDE_RenderContext()16 CFDE_RenderContext::CFDE_RenderContext()
17     : m_eStatus(FDE_RENDERSTATUS_Reset),
18       m_pRenderDevice(nullptr),
19       m_Transform() {
20   m_Transform.SetIdentity();
21 }
22 
~CFDE_RenderContext()23 CFDE_RenderContext::~CFDE_RenderContext() {
24   StopRender();
25 }
26 
StartRender(CFDE_RenderDevice * pRenderDevice,IFDE_CanvasSet * pCanvasSet,const CFX_Matrix & tmDoc2Device)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 
DoRender(IFX_Pause * pPause)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 
StopRender()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 
RenderText(IFDE_TextSet * pTextSet,FDE_TEXTEDITPIECE * pText)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