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