// 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/fde_render.h" #include "third_party/base/ptr_util.h" #include "xfa/fde/cfde_txtedttextset.h" #include "xfa/fde/fde_gedevice.h" #include "xfa/fde/fde_object.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(); 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(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 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(); if (m_CharPos.size() < static_cast(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); }