diff options
Diffstat (limited to 'xfa/fde/cfde_rendercontext.cpp')
-rw-r--r-- | xfa/fde/cfde_rendercontext.cpp | 128 |
1 files changed, 128 insertions, 0 deletions
diff --git a/xfa/fde/cfde_rendercontext.cpp b/xfa/fde/cfde_rendercontext.cpp new file mode 100644 index 0000000000..2e690e0ed9 --- /dev/null +++ b/xfa/fde/cfde_rendercontext.cpp @@ -0,0 +1,128 @@ +// Copyright 2014 PDFium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com + +#include "xfa/fde/cfde_rendercontext.h" + +#include "third_party/base/ptr_util.h" +#include "xfa/fde/cfde_brush.h" +#include "xfa/fde/cfde_renderdevice.h" +#include "xfa/fde/cfde_txtedttextset.h" + +#define FDE_PATHRENDER_Stroke 1 +#define FDE_PATHRENDER_Fill 2 + +CFDE_RenderContext::CFDE_RenderContext() + : m_eStatus(FDE_RENDERSTATUS_Reset), + m_pRenderDevice(nullptr), + m_Transform() { + m_Transform.SetIdentity(); +} + +CFDE_RenderContext::~CFDE_RenderContext() { + StopRender(); +} + +bool CFDE_RenderContext::StartRender(CFDE_RenderDevice* pRenderDevice, + CFDE_TxtEdtPage* pCanvasSet, + const CFX_Matrix& tmDoc2Device) { + if (m_pRenderDevice) + return false; + if (!pRenderDevice) + return false; + if (!pCanvasSet) + return false; + + m_eStatus = FDE_RENDERSTATUS_Paused; + m_pRenderDevice = pRenderDevice; + m_Transform = tmDoc2Device; + if (!m_pIterator) + m_pIterator = pdfium::MakeUnique<CFDE_VisualSetIterator>(); + + return m_pIterator->AttachCanvas(pCanvasSet) && m_pIterator->FilterObjects(); +} + +FDE_RENDERSTATUS CFDE_RenderContext::DoRender(IFX_Pause* pPause) { + if (!m_pRenderDevice) + return FDE_RENDERSTATUS_Failed; + if (!m_pIterator) + return FDE_RENDERSTATUS_Failed; + + FDE_RENDERSTATUS eStatus = FDE_RENDERSTATUS_Paused; + CFX_Matrix rm; + rm.SetReverse(m_Transform); + CFX_RectF rtDocClip = m_pRenderDevice->GetClipRect(); + if (rtDocClip.IsEmpty()) { + rtDocClip.left = rtDocClip.top = 0; + rtDocClip.width = (float)m_pRenderDevice->GetWidth(); + rtDocClip.height = (float)m_pRenderDevice->GetHeight(); + } + rm.TransformRect(rtDocClip); + IFDE_VisualSet* pVisualSet; + FDE_TEXTEDITPIECE* pPiece; + int32_t iCount = 0; + while (true) { + pPiece = m_pIterator->GetNext(pVisualSet); + if (!pPiece || !pVisualSet) { + eStatus = FDE_RENDERSTATUS_Done; + break; + } + if (!rtDocClip.IntersectWith(pVisualSet->GetRect(*pPiece))) + continue; + + switch (pVisualSet->GetType()) { + case FDE_VISUALOBJ_Text: + RenderText(static_cast<CFDE_TxtEdtTextSet*>(pVisualSet), pPiece); + iCount += 5; + break; + case FDE_VISUALOBJ_Canvas: + ASSERT(false); + break; + default: + break; + } + if (iCount >= 100 && pPause && pPause->NeedToPauseNow()) { + eStatus = FDE_RENDERSTATUS_Paused; + break; + } + } + return m_eStatus = eStatus; +} + +void CFDE_RenderContext::StopRender() { + m_eStatus = FDE_RENDERSTATUS_Reset; + m_pRenderDevice = nullptr; + m_Transform.SetIdentity(); + m_pIterator.reset(); + m_pBrush.reset(); + m_CharPos.clear(); +} + +void CFDE_RenderContext::RenderText(CFDE_TxtEdtTextSet* pTextSet, + FDE_TEXTEDITPIECE* pText) { + ASSERT(m_pRenderDevice); + ASSERT(pTextSet && pText); + + CFX_RetainPtr<CFGAS_GEFont> pFont = pTextSet->GetFont(); + if (!pFont) + return; + + int32_t iCount = pTextSet->GetDisplayPos(*pText, nullptr, false); + if (iCount < 1) + return; + + if (!m_pBrush) + m_pBrush = pdfium::MakeUnique<CFDE_Brush>(); + + if (m_CharPos.size() < static_cast<size_t>(iCount)) + m_CharPos.resize(iCount, FXTEXT_CHARPOS()); + + iCount = pTextSet->GetDisplayPos(*pText, m_CharPos.data(), false); + float fFontSize = pTextSet->GetFontSize(); + FX_ARGB dwColor = pTextSet->GetFontColor(); + m_pBrush->SetColor(dwColor); + m_pRenderDevice->DrawString(m_pBrush.get(), pFont, m_CharPos.data(), iCount, + fFontSize, &m_Transform); +} |