// 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 "../../../include/fpdfapi/fpdf_module.h"
#include "../../../include/fpdfapi/fpdf_render.h"
#include "../../../include/fxge/fx_ge.h"
#include "../fpdf_page/pageint.h"
#include "render_int.h"

CPDF_DocRenderData::CPDF_DocRenderData(CPDF_Document* pPDFDoc)
    : m_pPDFDoc(pPDFDoc),
      m_pFontCache(new CFX_FontCache)
{
}

CPDF_DocRenderData::~CPDF_DocRenderData()
{
    Clear(true);
}

void CPDF_DocRenderData::Clear(bool bRelease)
{
    for (auto it = m_Type3FaceMap.begin(); it != m_Type3FaceMap.end();) {
        auto curr_it = it++;
        CPDF_CountedObject<CPDF_Type3Cache>* cache = curr_it->second;
        if (bRelease || cache->use_count() < 2) {
            delete cache->get();
            delete cache;
            m_Type3FaceMap.erase(curr_it);
        }
    }

    for (auto it = m_TransferFuncMap.begin(); it != m_TransferFuncMap.end();) {
        auto curr_it = it++;
        CPDF_CountedObject<CPDF_TransferFunc>* value = curr_it->second;
        if (bRelease || value->use_count() < 2) {
            delete value->get();
            delete value;
            m_TransferFuncMap.erase(curr_it);
        }
    }

    if (m_pFontCache) {
        if (bRelease) {
            delete m_pFontCache;
            m_pFontCache = NULL;
        } else {
            m_pFontCache->FreeCache(false);
        }
    }
}

CPDF_Type3Cache* CPDF_DocRenderData::GetCachedType3(CPDF_Type3Font* pFont)
{
    CPDF_CountedObject<CPDF_Type3Cache>* pCache;
    auto it = m_Type3FaceMap.find(pFont);
    if (it == m_Type3FaceMap.end()) {
        CPDF_Type3Cache* pType3 = new CPDF_Type3Cache(pFont);
        pCache = new CPDF_CountedObject<CPDF_Type3Cache>(pType3);
        m_Type3FaceMap[pFont] = pCache;
    } else {
        pCache = it->second;
    }
    return pCache->AddRef();
}

void CPDF_DocRenderData::ReleaseCachedType3(CPDF_Type3Font* pFont)
{
    auto it = m_Type3FaceMap.find(pFont);
    if (it != m_Type3FaceMap.end())
        it->second->RemoveRef();
}

class CPDF_RenderModule : public IPDF_RenderModule
{
public:
   CPDF_RenderModule() {}

private:
    ~CPDF_RenderModule() override {}

    CPDF_DocRenderData* CreateDocData(CPDF_Document* pDoc) override;
    void DestroyDocData(CPDF_DocRenderData* p) override;
    void ClearDocData(CPDF_DocRenderData* p) override;

    CPDF_DocRenderData* GetRenderData() override
    {
        return &m_RenderData;
    }

    CPDF_PageRenderCache* CreatePageCache(CPDF_Page* pPage) override
    {
        return new CPDF_PageRenderCache(pPage);
    }

    void DestroyPageCache(CPDF_PageRenderCache* pCache) override;

    CPDF_RenderConfig* GetConfig() override
    {
        return &m_RenderConfig;
    }

    CPDF_DocRenderData m_RenderData;
    CPDF_RenderConfig m_RenderConfig;
};

CPDF_DocRenderData*	CPDF_RenderModule::CreateDocData(CPDF_Document* pDoc)
{
    return new CPDF_DocRenderData(pDoc);
}
void CPDF_RenderModule::DestroyDocData(CPDF_DocRenderData* pDocData)
{
    delete pDocData;
}
void CPDF_RenderModule::ClearDocData(CPDF_DocRenderData* p)
{
    if (p) {
        p->Clear(false);
    }
}
void CPDF_RenderModule::DestroyPageCache(CPDF_PageRenderCache* pCache)
{
    delete pCache;
}

void CPDF_ModuleMgr::InitRenderModule()
{
    m_pRenderModule.reset(new CPDF_RenderModule);
}

CPDF_RenderOptions::CPDF_RenderOptions()
    : m_ColorMode(RENDER_COLOR_NORMAL)
    , m_Flags(RENDER_CLEARTYPE)
    , m_Interpolation(0)
    , m_AddFlags(0)
    , m_pOCContext(NULL)
    , m_dwLimitCacheSize(1024 * 1024 * 100)
    , m_HalftoneLimit(-1)
{
}
FX_ARGB CPDF_RenderOptions::TranslateColor(FX_ARGB argb) const
{
    if (m_ColorMode == RENDER_COLOR_NORMAL) {
        return argb;
    }
    if (m_ColorMode == RENDER_COLOR_ALPHA) {
        return argb;
    }
    int a, r, g, b;
    ArgbDecode(argb, a, r, g, b);
    int gray = FXRGB2GRAY(r, g, b);
    if (m_ColorMode == RENDER_COLOR_TWOCOLOR) {
        int color = (r - gray) * (r - gray) + (g - gray) * (g - gray) + (b - gray) * (b - gray);
        if (gray < 35 && color < 20) {
            return ArgbEncode(a, m_ForeColor);
        }
        if (gray > 221 && color < 20) {
            return ArgbEncode(a, m_BackColor);
        }
        return argb;
    }
    int fr = FXSYS_GetRValue(m_ForeColor);
    int fg = FXSYS_GetGValue(m_ForeColor);
    int fb = FXSYS_GetBValue(m_ForeColor);
    int br = FXSYS_GetRValue(m_BackColor);
    int bg = FXSYS_GetGValue(m_BackColor);
    int bb = FXSYS_GetBValue(m_BackColor);
    r = (br - fr) * gray / 255 + fr;
    g = (bg - fg) * gray / 255 + fg;
    b = (bb - fb) * gray / 255 + fb;
    return ArgbEncode(a, r, g, b);
}

// static
int CPDF_RenderStatus::s_CurrentRecursionDepth = 0;

CPDF_RenderStatus::CPDF_RenderStatus()
{
    m_pContext = NULL;
    m_bStopped = false;
    m_pDevice = NULL;
    m_pCurObj = NULL;
    m_pStopObj = NULL;
    m_HalftoneLimit = 0;
    m_pObjectRenderer = NULL;
    m_bPrint = false;
    m_Transparency = 0;
    m_DitherBits = 0;
    m_bDropObjects = false;
    m_bStdCS = false;
    m_GroupFamily = 0;
    m_bLoadMask = false;
    m_pType3Char = NULL;
    m_T3FillColor = 0;
    m_pFormResource = NULL;
    m_pPageResource = NULL;
    m_curBlend = FXDIB_BLEND_NORMAL;
}

CPDF_RenderStatus::~CPDF_RenderStatus()
{
    delete m_pObjectRenderer;
}

bool CPDF_RenderStatus::Initialize(CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice,
                                      const CFX_AffineMatrix* pDeviceMatrix, const CPDF_PageObject* pStopObj,
                                      const CPDF_RenderStatus* pParentState, const CPDF_GraphicStates* pInitialStates,
                                      const CPDF_RenderOptions* pOptions, int transparency, bool bDropObjects,
                                      CPDF_Dictionary* pFormResource, bool bStdCS, CPDF_Type3Char* pType3Char,
                                      FX_ARGB fill_color, FX_DWORD GroupFamily,
                                      bool bLoadMask)
{
    m_pContext = pContext;
    m_pDevice = pDevice;
    m_DitherBits = pDevice->GetDeviceCaps(FXDC_DITHER_BITS);
    m_bPrint = m_pDevice->GetDeviceClass() != FXDC_DISPLAY;
    if (pDeviceMatrix) {
        m_DeviceMatrix = *pDeviceMatrix;
    }
    m_pStopObj = pStopObj;
    if (pOptions) {
        m_Options = *pOptions;
    }
    m_bDropObjects = bDropObjects;
    m_bStdCS = bStdCS;
    m_T3FillColor = fill_color;
    m_pType3Char = pType3Char;
    m_GroupFamily = GroupFamily;
    m_bLoadMask = bLoadMask;
    m_pFormResource = pFormResource;
    m_pPageResource = m_pContext->m_pPageResources;
    if (pInitialStates && !m_pType3Char) {
        m_InitialStates.CopyStates(*pInitialStates);
        if (pParentState) {
            CPDF_ColorStateData* pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)m_InitialStates.m_ColorState;
            CPDF_ColorStateData* pParentData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)pParentState->m_InitialStates.m_ColorState;
            if (!pColorData || pColorData->m_FillColor.IsNull()) {
                CPDF_ColorStateData* pData = m_InitialStates.m_ColorState.GetModify();
                pData->m_FillRGB = pParentData->m_FillRGB;
                pData->m_FillColor.Copy(&pParentData->m_FillColor);
            }
            if (!pColorData || pColorData->m_StrokeColor.IsNull()) {
                CPDF_ColorStateData* pData = m_InitialStates.m_ColorState.GetModify();
                pData->m_StrokeRGB = pParentData->m_FillRGB;
                pData->m_StrokeColor.Copy(&pParentData->m_StrokeColor);
            }
        }
    } else {
        m_InitialStates.DefaultStates();
    }
    m_pObjectRenderer = NULL;
    m_Transparency = transparency;
    return true;
}
void CPDF_RenderStatus::RenderObjectList(const CPDF_PageObjects* pObjs, const CFX_AffineMatrix* pObj2Device)
{
    CFX_FloatRect clip_rect = m_pDevice->GetClipBox();
    CFX_AffineMatrix device2object;
    device2object.SetReverse(*pObj2Device);
    device2object.TransformRect(clip_rect);
    int index = 0;
    FX_POSITION pos = pObjs->GetFirstObjectPosition();
    while(pos) {
        index ++;
        CPDF_PageObject* pCurObj = pObjs->GetNextObject(pos);
        if (pCurObj == m_pStopObj) {
            m_bStopped = true;
            return;
        }
        if (!pCurObj) {
            continue;
        }
        if(pCurObj == NULL || pCurObj->m_Left > clip_rect.right || pCurObj->m_Right < clip_rect.left ||
                pCurObj->m_Bottom > clip_rect.top || pCurObj->m_Top < clip_rect.bottom) {
            continue;
        }
        RenderSingleObject(pCurObj, pObj2Device);
        if (m_bStopped) {
            return;
        }
    }
}
void CPDF_RenderStatus::RenderSingleObject(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device)
{
    CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth);
    if (++s_CurrentRecursionDepth > kRenderMaxRecursionDepth) {
        return;
    }
    m_pCurObj = pObj;
    if (m_Options.m_pOCContext && pObj->m_ContentMark.NotNull()) {
        if (!m_Options.m_pOCContext->CheckObjectVisible(pObj)) {
            return;
        }
    }
    ProcessClipPath(pObj->m_ClipPath, pObj2Device);
    if (ProcessTransparency(pObj, pObj2Device)) {
        return;
    }
    ProcessObjectNoClip(pObj, pObj2Device);
}
bool CPDF_RenderStatus::ContinueSingleObject(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, IFX_Pause* pPause)
{
    if (m_pObjectRenderer) {
        if (m_pObjectRenderer->Continue(pPause)) {
            return true;
        }
        if (!m_pObjectRenderer->m_Result) {
            DrawObjWithBackground(pObj, pObj2Device);
        }
        delete m_pObjectRenderer;
        m_pObjectRenderer = NULL;
        return false;
    }
    m_pCurObj = pObj;
    if (m_Options.m_pOCContext && pObj->m_ContentMark.NotNull())
        if (!m_Options.m_pOCContext->CheckObjectVisible(pObj)) {
            return false;
        }
    ProcessClipPath(pObj->m_ClipPath, pObj2Device);
    if (ProcessTransparency(pObj, pObj2Device)) {
        return false;
    }
    if (pObj->m_Type == PDFPAGE_IMAGE) {
        m_pObjectRenderer = IPDF_ObjectRenderer::Create(pObj->m_Type);
        if (!m_pObjectRenderer->Start(this, pObj, pObj2Device, false)) {
            if (!m_pObjectRenderer->m_Result) {
                DrawObjWithBackground(pObj, pObj2Device);
            }
            delete m_pObjectRenderer;
            m_pObjectRenderer = NULL;
            return false;
        }
        return ContinueSingleObject(pObj, pObj2Device, pPause);
    }
    ProcessObjectNoClip(pObj, pObj2Device);
    return false;
}
IPDF_ObjectRenderer* IPDF_ObjectRenderer::Create(int type)
{
    if (type != PDFPAGE_IMAGE) {
        return NULL;
    }
    return new CPDF_ImageRenderer;
}
bool CPDF_RenderStatus::GetObjectClippedRect(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, bool bLogical, FX_RECT &rect) const
{
    rect = pObj->GetBBox(pObj2Device);
    FX_RECT rtClip = m_pDevice->GetClipBox();
    if (!bLogical) {
        CFX_Matrix dCTM = m_pDevice->GetCTM();
        FX_FLOAT a = FXSYS_fabs(dCTM.a);
        FX_FLOAT d = FXSYS_fabs(dCTM.d);
        if (a != 1.0f || d != 1.0f) {
            rect.right = rect.left + (int32_t)FXSYS_ceil((FX_FLOAT)rect.Width() * a);
            rect.bottom = rect.top + (int32_t)FXSYS_ceil((FX_FLOAT)rect.Height() * d);
            rtClip.right = rtClip.left + (int32_t)FXSYS_ceil((FX_FLOAT)rtClip.Width() * a);
            rtClip.bottom = rtClip.top + (int32_t)FXSYS_ceil((FX_FLOAT)rtClip.Height() * d);
        }
    }
    rect.Intersect(rtClip);
    return rect.IsEmpty();
}
void CPDF_RenderStatus::DitherObjectArea(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device)
{
    CFX_DIBitmap* pBitmap = m_pDevice->GetBitmap();
    if (pBitmap == NULL) {
        return;
    }
    FX_RECT rect;
    if (GetObjectClippedRect(pObj, pObj2Device, false, rect)) {
        return;
    }
    if (m_DitherBits == 2) {
        static FX_ARGB pal[4] = {0, 85, 170, 255};
        pBitmap->DitherFS(pal, 4, &rect);
    } else if (m_DitherBits == 3) {
        static FX_ARGB pal[8] = {0, 36, 73, 109, 146, 182, 219, 255};
        pBitmap->DitherFS(pal, 8, &rect);
    } else if (m_DitherBits == 4) {
        static FX_ARGB pal[16] = {0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};
        pBitmap->DitherFS(pal, 16, &rect);
    }
}
void CPDF_RenderStatus::ProcessObjectNoClip(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device)
{
    bool bRet = false;
    switch (pObj->m_Type) {
        case PDFPAGE_TEXT:
            bRet = ProcessText((CPDF_TextObject*)pObj, pObj2Device, NULL);
            break;
        case PDFPAGE_PATH:
            bRet = ProcessPath((CPDF_PathObject*)pObj, pObj2Device);
            break;
        case PDFPAGE_IMAGE:
            bRet = ProcessImage((CPDF_ImageObject*)pObj, pObj2Device);
            break;
        case PDFPAGE_SHADING:
            bRet = ProcessShading((CPDF_ShadingObject*)pObj, pObj2Device);
            break;
        case PDFPAGE_FORM:
            bRet = ProcessForm((CPDF_FormObject*)pObj, pObj2Device);
            break;
    }
    if (!bRet) {
        DrawObjWithBackground(pObj, pObj2Device);
    }
}
bool CPDF_RenderStatus::DrawObjWithBlend(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device)
{
    bool bRet = false;
    switch (pObj->m_Type) {
        case PDFPAGE_PATH:
            bRet = ProcessPath((CPDF_PathObject*)pObj, pObj2Device);
            break;
        case PDFPAGE_IMAGE:
            bRet = ProcessImage((CPDF_ImageObject *)pObj, pObj2Device);
            break;
        case PDFPAGE_FORM:
            bRet = ProcessForm((CPDF_FormObject*)pObj, pObj2Device);
            break;
    }
    return bRet;
}
void CPDF_RenderStatus::GetScaledMatrix(CFX_Matrix &matrix) const
{
    CFX_Matrix dCTM = m_pDevice->GetCTM();
    matrix.a *= FXSYS_fabs(dCTM.a);
    matrix.d *= FXSYS_fabs(dCTM.d);
}
void CPDF_RenderStatus::DrawObjWithBackground(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device)
{
    FX_RECT rect;
    if (GetObjectClippedRect(pObj, pObj2Device, false, rect)) {
        return;
    }
    int res = 300;
    if (pObj->m_Type == PDFPAGE_IMAGE && m_pDevice->GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER) {
        res = 0;
    }
    CPDF_ScaledRenderBuffer buffer;
    if (!buffer.Initialize(m_pContext, m_pDevice, &rect, pObj, &m_Options, res)) {
        return;
    }
    CFX_AffineMatrix matrix = *pObj2Device;
    matrix.Concat(*buffer.GetMatrix());
    GetScaledMatrix(matrix);
    CPDF_Dictionary* pFormResource = NULL;
    if (pObj->m_Type == PDFPAGE_FORM) {
        CPDF_FormObject* pFormObj = (CPDF_FormObject*)pObj;
        if (pFormObj->m_pForm && pFormObj->m_pForm->m_pFormDict) {
            pFormResource = pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources"));
        }
    }
    CPDF_RenderStatus status;
    status.Initialize(m_pContext, buffer.GetDevice(), buffer.GetMatrix(), NULL, NULL, NULL, &m_Options, m_Transparency, m_bDropObjects, pFormResource);
    status.RenderSingleObject(pObj, &matrix);
    buffer.OutputToDevice();
}
bool CPDF_RenderStatus::ProcessForm(CPDF_FormObject* pFormObj, const CFX_AffineMatrix* pObj2Device)
{
    CPDF_Dictionary* pOC = pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("OC"));
    if (pOC && m_Options.m_pOCContext && !m_Options.m_pOCContext->CheckOCGVisible(pOC)) {
        return true;
    }
    CFX_AffineMatrix matrix = pFormObj->m_FormMatrix;
    matrix.Concat(*pObj2Device);
    CPDF_Dictionary* pResources = NULL;
    if (pFormObj->m_pForm && pFormObj->m_pForm->m_pFormDict) {
        pResources = pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources"));
    }
    CPDF_RenderStatus status;
    status.Initialize(m_pContext, m_pDevice, NULL, m_pStopObj,
                      this, pFormObj, &m_Options, m_Transparency, m_bDropObjects, pResources, false);
    status.m_curBlend = m_curBlend;
    m_pDevice->SaveState();
    status.RenderObjectList(pFormObj->m_pForm, &matrix);
    m_bStopped = status.m_bStopped;
    m_pDevice->RestoreState();
    return true;
}
bool IsAvailableMatrix(const CFX_AffineMatrix& matrix)
{
    if (matrix.a == 0 || matrix.d == 0) {
        return matrix.b != 0 && matrix.c != 0;
    }
    if (matrix.b == 0 || matrix.c == 0) {
        return matrix.a != 0 && matrix.d != 0;
    }
    return true;
}
bool CPDF_RenderStatus::ProcessPath(CPDF_PathObject* pPathObj, const CFX_AffineMatrix* pObj2Device)
{
    int FillType = pPathObj->m_FillType;
    bool bStroke = pPathObj->m_bStroke;
    ProcessPathPattern(pPathObj, pObj2Device, FillType, bStroke);
    if (FillType == 0 && !bStroke) {
        return true;
    }
    FX_DWORD fill_argb = 0;
    if (FillType) {
        fill_argb = GetFillArgb(pPathObj);
    }
    FX_DWORD stroke_argb = 0;
    if (bStroke) {
        stroke_argb = GetStrokeArgb(pPathObj);
    }
    CFX_AffineMatrix path_matrix = pPathObj->m_Matrix;
    path_matrix.Concat(*pObj2Device);
    if (!IsAvailableMatrix(path_matrix)) {
        return true;
    }
    if (FillType && (m_Options.m_Flags & RENDER_RECT_AA)) {
        FillType |= FXFILL_RECT_AA;
    }
    if (m_Options.m_Flags & RENDER_FILL_FULLCOVER) {
        FillType |= FXFILL_FULLCOVER;
    }
    if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) {
        FillType |= FXFILL_NOPATHSMOOTH;
    }
    if (bStroke) {
        FillType |= FX_FILL_STROKE;
    }
    const CPDF_GeneralStateData* pGeneralData = ((CPDF_PageObject*)pPathObj)->m_GeneralState;
    if (pGeneralData && pGeneralData->m_StrokeAdjust) {
        FillType |= FX_STROKE_ADJUST;
    }
    if (m_pType3Char) {
        FillType |= FX_FILL_TEXT_MODE;
    }
    CFX_GraphStateData graphState(*pPathObj->m_GraphState);
    if (m_Options.m_Flags & RENDER_THINLINE) {
        graphState.m_LineWidth = 0;
    }
    return m_pDevice->DrawPath(pPathObj->m_Path, &path_matrix, &graphState, fill_argb, stroke_argb, FillType, 0, NULL, m_curBlend);
}
CPDF_TransferFunc* CPDF_RenderStatus::GetTransferFunc(CPDF_Object* pObj) const
{
    ASSERT(pObj != NULL);
    CPDF_DocRenderData* pDocCache = m_pContext->m_pDocument->GetRenderData();
    if (!pDocCache) {
        return NULL;
    }
    return pDocCache->GetTransferFunc(pObj);
}
FX_ARGB CPDF_RenderStatus::GetFillArgb(const CPDF_PageObject* pObj, bool bType3) const
{
    CPDF_ColorStateData* pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)pObj->m_ColorState;
    if (m_pType3Char && !bType3 && (!m_pType3Char->m_bColored || (m_pType3Char->m_bColored && (!pColorData || pColorData->m_FillColor.IsNull())))) {
        return m_T3FillColor;
    }
    if (!pColorData || pColorData->m_FillColor.IsNull()) {
        pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)m_InitialStates.m_ColorState;
    }
    FX_COLORREF rgb = pColorData->m_FillRGB;
    if (rgb == (FX_DWORD) - 1) {
        return 0;
    }
    const CPDF_GeneralStateData* pGeneralData = pObj->m_GeneralState;
    int alpha;
    if (pGeneralData) {
        alpha = (int32_t)(pGeneralData->m_FillAlpha * 255);
        if (pGeneralData->m_pTR) {
            if (!pGeneralData->m_pTransferFunc) {
                ((CPDF_GeneralStateData*)pGeneralData)->m_pTransferFunc = GetTransferFunc(pGeneralData->m_pTR);
            }
            if (pGeneralData->m_pTransferFunc) {
                rgb = pGeneralData->m_pTransferFunc->TranslateColor(rgb);
            }
        }
    } else {
        alpha = 255;
    }
    return m_Options.TranslateColor(ArgbEncode(alpha, rgb));
}
FX_ARGB CPDF_RenderStatus::GetStrokeArgb(const CPDF_PageObject* pObj) const
{
    CPDF_ColorStateData* pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)pObj->m_ColorState;
    if (m_pType3Char && (!m_pType3Char->m_bColored || (m_pType3Char->m_bColored && (!pColorData || pColorData->m_StrokeColor.IsNull())))) {
        return m_T3FillColor;
    }
    if (!pColorData || pColorData->m_StrokeColor.IsNull()) {
        pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)m_InitialStates.m_ColorState;
    }
    FX_COLORREF rgb = pColorData->m_StrokeRGB;
    if (rgb == (FX_DWORD) - 1) {
        return 0;
    }
    const CPDF_GeneralStateData* pGeneralData = pObj->m_GeneralState;
    int alpha;
    if (pGeneralData) {
        alpha = (int32_t)(pGeneralData->m_StrokeAlpha * 255);
        if (pGeneralData->m_pTR) {
            if (!pGeneralData->m_pTransferFunc) {
                ((CPDF_GeneralStateData*)pGeneralData)->m_pTransferFunc = GetTransferFunc(pGeneralData->m_pTR);
            }
            if (pGeneralData->m_pTransferFunc) {
                rgb = pGeneralData->m_pTransferFunc->TranslateColor(rgb);
            }
        }
    } else {
        alpha = 255;
    }
    return m_Options.TranslateColor(ArgbEncode(alpha, rgb));
}
void CPDF_RenderStatus::ProcessClipPath(CPDF_ClipPath ClipPath, const CFX_AffineMatrix* pObj2Device)
{
    if (ClipPath.IsNull()) {
        if (m_LastClipPath.IsNull()) {
            return;
        }
        m_pDevice->RestoreState(true);
        m_LastClipPath.SetNull();
        return;
    }
    if (m_LastClipPath == ClipPath) {
        return;
    }
    m_LastClipPath = ClipPath;
    m_pDevice->RestoreState(true);
    int nClipPath = ClipPath.GetPathCount();
    int i;
    for (i = 0; i < nClipPath; i++) {
        const CFX_PathData* pPathData = ClipPath.GetPath(i);
        if (pPathData == NULL) {
            continue;
        }
        if (pPathData->GetPointCount() == 0) {
            CFX_PathData EmptyPath;
            EmptyPath.AppendRect(-1, -1, 0, 0);
            int fill_mode = FXFILL_WINDING;
            m_pDevice->SetClip_PathFill(&EmptyPath, NULL, fill_mode);
        } else {
            int ClipType = ClipPath.GetClipType(i);
            m_pDevice->SetClip_PathFill(pPathData, pObj2Device, ClipType);
        }
    }
    int textcount = ClipPath.GetTextCount();
    if (textcount == 0) {
        return;
    }
    if (m_pDevice->GetDeviceClass() == FXDC_DISPLAY && !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)) {
        return;
    }
    CFX_PathData* pTextClippingPath = NULL;
    for (i = 0; i < textcount; i ++) {
        CPDF_TextObject* pText = ClipPath.GetText(i);
        if (pText == NULL) {
            if (pTextClippingPath) {
                int fill_mode = FXFILL_WINDING;
                if (m_Options.m_Flags & RENDER_NOTEXTSMOOTH) {
                    fill_mode |= FXFILL_NOPATHSMOOTH;
                }
                m_pDevice->SetClip_PathFill(pTextClippingPath, NULL, fill_mode);
                delete pTextClippingPath;
                pTextClippingPath = NULL;
            }
        } else {
            if (pTextClippingPath == NULL) {
                pTextClippingPath = new CFX_PathData;
            }
            ProcessText(pText, pObj2Device, pTextClippingPath);
        }
    }
    delete pTextClippingPath;
}
void CPDF_RenderStatus::DrawClipPath(CPDF_ClipPath ClipPath, const CFX_AffineMatrix* pObj2Device)
{
    if (ClipPath.IsNull()) {
        return;
    }
    int fill_mode = 0;
    if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) {
        fill_mode |= FXFILL_NOPATHSMOOTH;
    }
    int nClipPath = ClipPath.GetPathCount();
    int i;
    for (i = 0; i < nClipPath; i++) {
        const CFX_PathData* pPathData = ClipPath.GetPath(i);
        if (pPathData == NULL) {
            continue;
        }
        CFX_GraphStateData stroke_state;
        if (m_Options.m_Flags & RENDER_THINLINE) {
            stroke_state.m_LineWidth = 0;
        }
        m_pDevice->DrawPath(pPathData, pObj2Device, &stroke_state, 0, 0xffff0000, fill_mode);
    }
}
bool CPDF_RenderStatus::SelectClipPath(CPDF_PathObject* pPathObj, const CFX_AffineMatrix* pObj2Device, bool bStroke)
{
    CFX_AffineMatrix path_matrix = pPathObj->m_Matrix;
    path_matrix.Concat(*pObj2Device);
    if (bStroke) {
        CFX_GraphStateData graphState(*pPathObj->m_GraphState);
        if (m_Options.m_Flags & RENDER_THINLINE) {
            graphState.m_LineWidth = 0;
        }
        return m_pDevice->SetClip_PathStroke(pPathObj->m_Path, &path_matrix, &graphState);
    }
    int fill_mode = pPathObj->m_FillType;
    if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) {
        fill_mode |= FXFILL_NOPATHSMOOTH;
    }
    return m_pDevice->SetClip_PathFill(pPathObj->m_Path, &path_matrix, fill_mode);
}
bool CPDF_RenderStatus::ProcessTransparency(const CPDF_PageObject* pPageObj, const CFX_AffineMatrix* pObj2Device)
{
    const CPDF_GeneralStateData* pGeneralState = pPageObj->m_GeneralState;
    int blend_type = pGeneralState ? pGeneralState->m_BlendType : FXDIB_BLEND_NORMAL;
    if (blend_type == FXDIB_BLEND_UNSUPPORTED) {
        return true;
    }
    CPDF_Dictionary* pSMaskDict = pGeneralState ? (CPDF_Dictionary*)pGeneralState->m_pSoftMask : NULL;
    if (pSMaskDict) {
        if (pPageObj->m_Type == PDFPAGE_IMAGE &&
                ((CPDF_ImageObject*)pPageObj)->m_pImage->GetDict()->KeyExist(FX_BSTRC("SMask"))) {
            pSMaskDict = NULL;
        }
    }
    CPDF_Dictionary* pFormResource = NULL;
    FX_FLOAT group_alpha = 1.0f;
    int Transparency = m_Transparency;
    bool bGroupTransparent = false;
    if (pPageObj->m_Type == PDFPAGE_FORM) {
        CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj;
        const CPDF_GeneralStateData *pStateData = pFormObj->m_GeneralState.GetObject();
        if (pStateData) {
            group_alpha = pStateData->m_FillAlpha;
        }
        Transparency = pFormObj->m_pForm->m_Transparency;
        bGroupTransparent = Transparency & PDFTRANS_ISOLATED ? true : false;
        if (pFormObj->m_pForm->m_pFormDict) {
            pFormResource = pFormObj->m_pForm->m_pFormDict->GetDict("Resources");
        }
    }
    bool bTextClip = false;
    if (pPageObj->m_ClipPath.NotNull() && pPageObj->m_ClipPath.GetTextCount() &&
            m_pDevice->GetDeviceClass() == FXDC_DISPLAY && !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)) {
        bTextClip = true;
    }
    if ((m_Options.m_Flags & RENDER_OVERPRINT) && pPageObj->m_Type == PDFPAGE_IMAGE && pGeneralState && pGeneralState->m_FillOP && pGeneralState->m_StrokeOP) {
        CPDF_Document* pDocument = NULL;
        CPDF_Page* pPage = NULL;
        if (m_pContext->m_pPageCache) {
            pPage = m_pContext->m_pPageCache->GetPage();
            pDocument = pPage->m_pDocument;
        } else {
            pDocument = ((CPDF_ImageObject*)pPageObj)->m_pImage->GetDocument();
        }
        CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : NULL;
        CPDF_Object* pCSObj = ((CPDF_ImageObject*)pPageObj)->m_pImage->GetStream()->GetDict()->GetElementValue(FX_BSTRC("ColorSpace"));
        CPDF_ColorSpace* pColorSpace = pDocument->LoadColorSpace(pCSObj, pPageResources);
        if (pColorSpace) {
            int format = pColorSpace->GetFamily();
            if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION || format == PDFCS_DEVICEN) {
                blend_type = FXDIB_BLEND_DARKEN;
            }
            pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
        }
    }
    if (pSMaskDict == NULL && group_alpha == 1.0f && blend_type == FXDIB_BLEND_NORMAL && !bTextClip && !bGroupTransparent) {
        return false;
    }
    bool isolated = Transparency & PDFTRANS_ISOLATED;
    if (m_bPrint) {
        bool bRet = false;
        int rendCaps = m_pDevice->GetRenderCaps();
        if (!((Transparency & PDFTRANS_ISOLATED) || pSMaskDict || bTextClip) && (rendCaps & FXRC_BLEND_MODE)) {
            int oldBlend = m_curBlend;
            m_curBlend = blend_type;
            bRet = DrawObjWithBlend(pPageObj, pObj2Device);
            m_curBlend = oldBlend;
        }
        if (!bRet) {
            DrawObjWithBackground(pPageObj, pObj2Device);
        }
        return true;
    }
    FX_RECT rect = pPageObj->GetBBox(pObj2Device);
    rect.Intersect(m_pDevice->GetClipBox());
    if (rect.IsEmpty()) {
        return true;
    }
    CFX_Matrix deviceCTM = m_pDevice->GetCTM();
    FX_FLOAT scaleX = FXSYS_fabs(deviceCTM.a);
    FX_FLOAT scaleY = FXSYS_fabs(deviceCTM.d);
    int width = FXSYS_round((FX_FLOAT)rect.Width() * scaleX);
    int height = FXSYS_round((FX_FLOAT)rect.Height() * scaleY);
    CFX_FxgeDevice bitmap_device;
    CFX_DIBitmap* oriDevice = NULL;
    if (!isolated && (m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) {
        oriDevice = new CFX_DIBitmap;
        if (!m_pDevice->CreateCompatibleBitmap(oriDevice, width, height)) {
            return true;
        }
        m_pDevice->GetDIBits(oriDevice, rect.left, rect.top);
    }
    if (!bitmap_device.Create(width, height, FXDIB_Argb, 0, oriDevice)) {
        return true;
    }
    CFX_DIBitmap* bitmap = bitmap_device.GetBitmap();
    bitmap->Clear(0);
    CFX_AffineMatrix new_matrix = *pObj2Device;
    new_matrix.TranslateI(-rect.left, -rect.top);
    new_matrix.Scale(scaleX, scaleY);
    CFX_DIBitmap* pTextMask = NULL;
    if (bTextClip) {
        pTextMask = new CFX_DIBitmap;
        if (!pTextMask->Create(width, height, FXDIB_8bppMask)) {
            delete pTextMask;
            return true;
        }
        pTextMask->Clear(0);
        CFX_FxgeDevice text_device;
        text_device.Attach(pTextMask);
        for (FX_DWORD i = 0; i < pPageObj->m_ClipPath.GetTextCount(); i ++) {
            CPDF_TextObject* textobj = pPageObj->m_ClipPath.GetText(i);
            if (textobj == NULL) {
                break;
            }
            CFX_AffineMatrix text_matrix;
            textobj->GetTextMatrix(&text_matrix);
            CPDF_TextRenderer::DrawTextPath(&text_device, textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos,
                                            textobj->m_TextState.GetFont(), textobj->m_TextState.GetFontSize(),
                                            &text_matrix, &new_matrix, textobj->m_GraphState, (FX_ARGB) - 1, 0, NULL);
        }
    }
    CPDF_RenderStatus bitmap_render;
    bitmap_render.Initialize(m_pContext, &bitmap_device, NULL,
                             m_pStopObj, NULL, NULL, &m_Options, 0, m_bDropObjects, pFormResource, true);
    bitmap_render.ProcessObjectNoClip(pPageObj, &new_matrix);
    m_bStopped = bitmap_render.m_bStopped;
    if (pSMaskDict) {
        CFX_AffineMatrix smask_matrix;
        FXSYS_memcpy(&smask_matrix, pGeneralState->m_SMaskMatrix, sizeof smask_matrix);
        smask_matrix.Concat(*pObj2Device);
        CFX_DIBSource* pSMaskSource = LoadSMask(pSMaskDict, &rect, &smask_matrix);
        if (pSMaskSource) {
            bitmap->MultiplyAlpha(pSMaskSource);
            delete pSMaskSource;
        }
    }
    if (pTextMask) {
        bitmap->MultiplyAlpha(pTextMask);
        delete pTextMask;
        pTextMask = NULL;
    }
    if (Transparency & PDFTRANS_GROUP && group_alpha != 1.0f) {
        bitmap->MultiplyAlpha((int32_t)(group_alpha * 255));
    }
    Transparency = m_Transparency;
    if (pPageObj->m_Type == PDFPAGE_FORM) {
        Transparency |= PDFTRANS_GROUP;
    }
    CompositeDIBitmap(bitmap, rect.left, rect.top, 0, 255, blend_type, Transparency);
    delete oriDevice;
    return true;
}
CFX_DIBitmap* CPDF_RenderStatus::GetBackdrop(const CPDF_PageObject* pObj, const FX_RECT& rect, int& left, int& top,
        bool bBackAlphaRequired)
{
    FX_RECT bbox = rect;
    bbox.Intersect(m_pDevice->GetClipBox());
    left = bbox.left;
    top = bbox.top;
    CFX_Matrix deviceCTM = m_pDevice->GetCTM();
    FX_FLOAT scaleX = FXSYS_fabs(deviceCTM.a);
    FX_FLOAT scaleY = FXSYS_fabs(deviceCTM.d);
    int width = FXSYS_round(bbox.Width() * scaleX);
    int height = FXSYS_round(bbox.Height() * scaleY);
    CFX_DIBitmap* pBackdrop = new CFX_DIBitmap;
    if (bBackAlphaRequired && !m_bDropObjects) {
        pBackdrop->Create(width, height, FXDIB_Argb);
    } else {
        m_pDevice->CreateCompatibleBitmap(pBackdrop, width, height);
    }
    if (pBackdrop->GetBuffer() == NULL) {
        delete pBackdrop;
        return NULL;
    }
    bool bNeedDraw;
    if (pBackdrop->HasAlpha()) {
        bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT);
    } else {
        bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_GET_BITS);
    }
    if (!bNeedDraw) {
        m_pDevice->GetDIBits(pBackdrop, left, top);
        return pBackdrop;
    }
    CFX_AffineMatrix FinalMatrix = m_DeviceMatrix;
    FinalMatrix.TranslateI(-left, -top);
    FinalMatrix.Scale(scaleX, scaleY);
    pBackdrop->Clear(pBackdrop->HasAlpha() ? 0 : 0xffffffff);
    CFX_FxgeDevice device;
    device.Attach(pBackdrop);
    m_pContext->Render(&device, pObj, &m_Options, &FinalMatrix);
    return pBackdrop;
}
void CPDF_RenderContext::GetBackground(CFX_DIBitmap* pBuffer, const CPDF_PageObject* pObj,
                                       const CPDF_RenderOptions* pOptions, CFX_AffineMatrix* pFinalMatrix)
{
    CFX_FxgeDevice device;
    device.Attach(pBuffer);

    FX_RECT rect(0, 0, device.GetWidth(), device.GetHeight());
    device.FillRect(&rect, 0xffffffff);
    Render(&device, pObj, pOptions, pFinalMatrix);
}
CPDF_GraphicStates* CPDF_RenderStatus::CloneObjStates(const CPDF_GraphicStates* pSrcStates, bool bStroke)
{
    if (!pSrcStates) {
        return NULL;
    }
    CPDF_GraphicStates* pStates = new CPDF_GraphicStates;
    pStates->CopyStates(*pSrcStates);
    CPDF_Color* pObjColor = bStroke ? pSrcStates->m_ColorState.GetStrokeColor() :
                            pSrcStates->m_ColorState.GetFillColor();
    if (!pObjColor->IsNull()) {
        CPDF_ColorStateData* pColorData = pStates->m_ColorState.GetModify();
        pColorData->m_FillRGB = bStroke ? pSrcStates->m_ColorState.GetObject()->m_StrokeRGB :
                                pSrcStates->m_ColorState.GetObject()->m_FillRGB;
        pColorData->m_StrokeRGB = pColorData->m_FillRGB;
    }
    return pStates;
}
CPDF_RenderContext::CPDF_RenderContext()
{
}
void CPDF_RenderContext::Create(CPDF_Document* pDoc, CPDF_PageRenderCache* pPageCache,
                                CPDF_Dictionary* pPageResources, bool bFirstLayer)
{
    m_pDocument = pDoc;
    m_pPageResources = pPageResources;
    m_pPageCache = pPageCache;
    m_bFirstLayer = bFirstLayer;
}
void CPDF_RenderContext::Create(CPDF_Page* pPage, bool bFirstLayer)
{
    m_pDocument = pPage->m_pDocument;
    m_pPageResources = pPage->m_pPageResources;
    m_pPageCache = pPage->GetRenderCache();
    m_bFirstLayer = bFirstLayer;
}
CPDF_RenderContext::~CPDF_RenderContext()
{
}
void CPDF_RenderContext::Clear()
{
    m_pDocument = NULL;
    m_pPageResources = NULL;
    m_pPageCache = NULL;
    m_bFirstLayer = true;
    m_ContentList.RemoveAll();
}
void CPDF_RenderContext::AppendObjectList(CPDF_PageObjects* pObjs, const CFX_AffineMatrix* pObject2Device)
{
    _PDF_RenderItem* pItem = m_ContentList.AddSpace();
    pItem->m_pObjectList = pObjs;
    if (pObject2Device) {
        pItem->m_Matrix = *pObject2Device;
    } else {
        pItem->m_Matrix.SetIdentity();
    }
}
void CPDF_RenderContext::Render(CFX_RenderDevice* pDevice, const CPDF_RenderOptions* pOptions,
                                const CFX_AffineMatrix* pLastMatrix)
{
    Render(pDevice, NULL, pOptions, pLastMatrix);
}
void CPDF_RenderContext::Render(CFX_RenderDevice* pDevice, const CPDF_PageObject* pStopObj,
                                const CPDF_RenderOptions* pOptions, const CFX_AffineMatrix* pLastMatrix)
{
    int count = m_ContentList.GetSize();
    for (int j = 0; j < count; j ++) {
        pDevice->SaveState();
        _PDF_RenderItem* pItem = m_ContentList.GetDataPtr(j);
        if (pLastMatrix) {
            CFX_AffineMatrix FinalMatrix = pItem->m_Matrix;
            FinalMatrix.Concat(*pLastMatrix);
            CPDF_RenderStatus status;
            status.Initialize(this, pDevice, pLastMatrix, pStopObj, NULL, NULL, pOptions,
                              pItem->m_pObjectList->m_Transparency, false, NULL);
            status.RenderObjectList(pItem->m_pObjectList, &FinalMatrix);
            if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) {
                m_pPageCache->CacheOptimization(status.m_Options.m_dwLimitCacheSize);
            }
            if (status.m_bStopped) {
                pDevice->RestoreState();
                break;
            }
        } else {
            CPDF_RenderStatus status;
            status.Initialize(this, pDevice, NULL, pStopObj, NULL, NULL, pOptions,
                              pItem->m_pObjectList->m_Transparency, false, NULL);
            status.RenderObjectList(pItem->m_pObjectList, &pItem->m_Matrix);
            if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) {
                m_pPageCache->CacheOptimization(status.m_Options.m_dwLimitCacheSize);
            }
            if (status.m_bStopped) {
                pDevice->RestoreState();
                break;
            }
        }
        pDevice->RestoreState();
    }
}
void CPDF_RenderContext::DrawObjectList(CFX_RenderDevice* pDevice, CPDF_PageObjects* pObjs,
                                        const CFX_AffineMatrix* pObject2Device, const CPDF_RenderOptions* pOptions)
{
    AppendObjectList(pObjs, pObject2Device);
    Render(pDevice, pOptions);
}

CPDF_ProgressiveRenderer::CPDF_ProgressiveRenderer(
    CPDF_RenderContext* pContext,
    CFX_RenderDevice* pDevice,
    const CPDF_RenderOptions* pOptions) :
        m_Status(Ready),
        m_pContext(pContext),
        m_pDevice(pDevice),
        m_pOptions(pOptions),
        m_LayerIndex(0),
        m_ObjectIndex(0),
        m_ObjectPos(nullptr),
        m_PrevLastPos(nullptr)
{
}

CPDF_ProgressiveRenderer::~CPDF_ProgressiveRenderer()
{
    if (m_pRenderStatus)
        m_pDevice->RestoreState();
}

void CPDF_ProgressiveRenderer::Start(IFX_Pause* pPause)
{
    if (!m_pContext || !m_pDevice || m_Status != Ready) {
        m_Status = Failed;
        return;
    }
    m_Status = ToBeContinued;
    Continue(pPause);
}

#define RENDER_STEP_LIMIT 100
void CPDF_ProgressiveRenderer::Continue(IFX_Pause* pPause)
{
    if (m_Status != ToBeContinued) {
        return;
    }
    FX_DWORD nLayers = m_pContext->m_ContentList.GetSize();
    for (; m_LayerIndex < nLayers; m_LayerIndex ++) {
        _PDF_RenderItem* pItem = m_pContext->m_ContentList.GetDataPtr(m_LayerIndex);
        FX_POSITION LastPos = pItem->m_pObjectList->GetLastObjectPosition();
        if (m_ObjectPos == NULL) {
            if (LastPos == m_PrevLastPos) {
                if (!pItem->m_pObjectList->IsParsed()) {
                    pItem->m_pObjectList->ContinueParse(pPause);
                    if (!pItem->m_pObjectList->IsParsed()) {
                        return;
                    }
                    LastPos = pItem->m_pObjectList->GetLastObjectPosition();
                }
            }
            if (LastPos == m_PrevLastPos) {
                if (m_pRenderStatus) {
                    m_pRenderStatus.reset();
                    m_pDevice->RestoreState();
                    m_ObjectPos = NULL;
                    m_PrevLastPos = NULL;
                }
                continue;
            }
            if (m_PrevLastPos) {
                m_ObjectPos = m_PrevLastPos;
                pItem->m_pObjectList->GetNextObject(m_ObjectPos);
            } else {
                m_ObjectPos = pItem->m_pObjectList->GetFirstObjectPosition();
            }
            m_PrevLastPos = LastPos;
        }
        if (!m_pRenderStatus) {
            m_ObjectPos = pItem->m_pObjectList->GetFirstObjectPosition();
            m_ObjectIndex = 0;
            m_pRenderStatus.reset(new CPDF_RenderStatus());
            m_pRenderStatus->Initialize(
                m_pContext, m_pDevice, NULL, NULL, NULL, NULL, m_pOptions,
                pItem->m_pObjectList->m_Transparency, false, NULL);
            m_pDevice->SaveState();
            m_ClipRect = m_pDevice->GetClipBox();
            CFX_AffineMatrix device2object;
            device2object.SetReverse(pItem->m_Matrix);
            device2object.TransformRect(m_ClipRect);
        }
        int objs_to_go = CPDF_ModuleMgr::Get()->GetRenderModule()->GetConfig()->m_RenderStepLimit;
        while (m_ObjectPos) {
            CPDF_PageObject* pCurObj = pItem->m_pObjectList->GetObjectAt(m_ObjectPos);
            if (pCurObj && pCurObj->m_Left <= m_ClipRect.right && pCurObj->m_Right >= m_ClipRect.left &&
                    pCurObj->m_Bottom <= m_ClipRect.top && pCurObj->m_Top >= m_ClipRect.bottom) {
                if (m_pRenderStatus->ContinueSingleObject(pCurObj, &pItem->m_Matrix, pPause)) {
                    return;
                }
                if (pCurObj->m_Type == PDFPAGE_IMAGE && m_pRenderStatus->m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) {
                    m_pContext->GetPageCache()->CacheOptimization(m_pRenderStatus->m_Options.m_dwLimitCacheSize);
                }
                if (pCurObj->m_Type == PDFPAGE_FORM || pCurObj->m_Type == PDFPAGE_SHADING) {
                    objs_to_go = 0;
                } else {
                    objs_to_go --;
                }
            }
            m_ObjectIndex ++;
            pItem->m_pObjectList->GetNextObject(m_ObjectPos);
            if (objs_to_go == 0) {
                if (pPause && pPause->NeedToPauseNow()) {
                    return;
                }
                objs_to_go = CPDF_ModuleMgr::Get()->GetRenderModule()->GetConfig()->m_RenderStepLimit;
            }
        }
        if (!pItem->m_pObjectList->IsParsed()) {
            return;
        }
        m_pRenderStatus.reset();
        m_pDevice->RestoreState();
        m_ObjectPos = NULL;
        m_PrevLastPos = NULL;
        if (pPause && pPause->NeedToPauseNow()) {
            m_LayerIndex++;
            return;
        }
    }
    m_Status = Done;
}
int CPDF_ProgressiveRenderer::EstimateProgress()
{
    if (!m_pContext) {
        return 0;
    }
    FX_DWORD nLayers = m_pContext->m_ContentList.GetSize();
    int nTotal = 0, nRendered = 0;
    for (FX_DWORD layer = 0; layer < nLayers; layer ++) {
        _PDF_RenderItem* pItem = m_pContext->m_ContentList.GetDataPtr(layer);
        int nObjs = pItem->m_pObjectList->CountObjects();
        if (layer == m_LayerIndex) {
            nRendered += m_ObjectIndex;
        } else if (layer < m_LayerIndex) {
            nRendered += nObjs;
        }
        nTotal += nObjs;
    }
    if (nTotal == 0) {
        return 0;
    }
    return 100 * nRendered / nTotal;
}
CPDF_TransferFunc* CPDF_DocRenderData::GetTransferFunc(CPDF_Object* pObj)
{
    if (!pObj)
        return nullptr;

    auto it = m_TransferFuncMap.find(pObj);
    if (it != m_TransferFuncMap.end()) {
        CPDF_CountedObject<CPDF_TransferFunc>* pTransferCounter = it->second;
        return pTransferCounter->AddRef();
    }

    CPDF_Function* pFuncs[3] = { nullptr, nullptr, nullptr };
    bool bUniTransfer = true;
    bool bIdentity = true;
    if (pObj->GetType() == PDFOBJ_ARRAY) {
        bUniTransfer = false;
        CPDF_Array* pArray = (CPDF_Array*)pObj;
        if (pArray->GetCount() < 3)
            return nullptr;

        for (FX_DWORD i = 0; i < 3; ++i) {
            pFuncs[2 - i] = CPDF_Function::Load(pArray->GetElementValue(i));
            if (!pFuncs[2 - i]) {
                return nullptr;
            }
        }
    } else {
        pFuncs[0] = CPDF_Function::Load(pObj);
        if (!pFuncs[0]) {
            return nullptr;
        }
    }
    CPDF_TransferFunc* pTransfer = new CPDF_TransferFunc;
    pTransfer->m_pPDFDoc = m_pPDFDoc;
    CPDF_CountedObject<CPDF_TransferFunc>* pTransferCounter =
        new CPDF_CountedObject<CPDF_TransferFunc>(pTransfer);
    m_TransferFuncMap[pObj] = pTransferCounter;
    static const int kMaxOutputs = 16;
    FX_FLOAT output[kMaxOutputs];
    FXSYS_memset(output, 0, sizeof(output));
    FX_FLOAT input;
    int noutput;
    for (int v = 0; v < 256; ++v) {
        input = (FX_FLOAT)v / 255.0f;
        if (bUniTransfer) {
            if (pFuncs[0] && pFuncs[0]->CountOutputs() <= kMaxOutputs)
                pFuncs[0]->Call(&input, 1, output, noutput);
            int o = FXSYS_round(output[0] * 255);
            if (o != v)
                bIdentity = false;
            for (int i = 0; i < 3; ++i) {
                pTransfer->m_Samples[i * 256 + v] = o;
            }
        } else {
            for (int i = 0; i < 3; ++i) {
                if (pFuncs[i] && pFuncs[i]->CountOutputs() <= kMaxOutputs) {
                    pFuncs[i]->Call(&input, 1, output, noutput);
                    int o = FXSYS_round(output[0] * 255);
                    if (o != v)
                        bIdentity = false;
                    pTransfer->m_Samples[i * 256 + v] = o;
                } else {
                    pTransfer->m_Samples[i * 256 + v] = v;
                }
            }
        }
    }
    for (int i = 0; i < 3; ++i)
        delete pFuncs[i];

    pTransfer->m_bIdentity = bIdentity;
    return pTransferCounter->AddRef();
}

void CPDF_DocRenderData::ReleaseTransferFunc(CPDF_Object* pObj)
{
    auto it = m_TransferFuncMap.find(pObj);
    if (it != m_TransferFuncMap.end())
        it->second->RemoveRef();
}
CPDF_RenderConfig::CPDF_RenderConfig()
{
    m_HalftoneLimit = 0;
    m_RenderStepLimit = 100;
}
CPDF_RenderConfig::~CPDF_RenderConfig()
{
}
CPDF_DeviceBuffer::CPDF_DeviceBuffer()
{
    m_pBitmap = NULL;
    m_pDevice = NULL;
    m_pContext = NULL;
    m_pObject = NULL;
}
CPDF_DeviceBuffer::~CPDF_DeviceBuffer()
{
    delete m_pBitmap;
}
bool CPDF_DeviceBuffer::Initialize(CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, FX_RECT* pRect,
                                      const CPDF_PageObject* pObj, int max_dpi)
{
    m_pDevice = pDevice;
    m_pContext = pContext;
    m_Rect = *pRect;
    m_pObject = pObj;
    m_Matrix.TranslateI(-pRect->left, -pRect->top);
#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_
    int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE);
    int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE);
    if (horz_size && vert_size && max_dpi) {
        int dpih = pDevice->GetDeviceCaps(FXDC_PIXEL_WIDTH) * 254 / (horz_size * 10);
        int dpiv = pDevice->GetDeviceCaps(FXDC_PIXEL_HEIGHT) * 254 / (vert_size * 10);
        if (dpih > max_dpi) {
            m_Matrix.Scale((FX_FLOAT)(max_dpi) / dpih, 1.0f);
        }
        if (dpiv > max_dpi) {
            m_Matrix.Scale(1.0f, (FX_FLOAT)(max_dpi) / (FX_FLOAT)dpiv);
        }
    }
#endif
    CFX_Matrix ctm = m_pDevice->GetCTM();
    FX_FLOAT fScaleX = FXSYS_fabs(ctm.a);
    FX_FLOAT fScaleY = FXSYS_fabs(ctm.d);
    m_Matrix.Concat(fScaleX, 0, 0, fScaleY, 0, 0);
    CFX_FloatRect rect(*pRect);
    m_Matrix.TransformRect(rect);
    FX_RECT bitmap_rect = rect.GetOutterRect();
    m_pBitmap = new CFX_DIBitmap;
    m_pBitmap->Create(bitmap_rect.Width(), bitmap_rect.Height(), FXDIB_Argb);
    return true;
}
void CPDF_DeviceBuffer::OutputToDevice()
{
    if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_GET_BITS) {
        if (m_Matrix.a == 1.0f && m_Matrix.d == 1.0f) {
            m_pDevice->SetDIBits(m_pBitmap, m_Rect.left, m_Rect.top);
        } else {
            m_pDevice->StretchDIBits(m_pBitmap, m_Rect.left, m_Rect.top, m_Rect.Width(), m_Rect.Height());
        }
    } else {
        CFX_DIBitmap buffer;
        m_pDevice->CreateCompatibleBitmap(&buffer, m_pBitmap->GetWidth(), m_pBitmap->GetHeight());
        m_pContext->GetBackground(&buffer, m_pObject, NULL, &m_Matrix);
        buffer.CompositeBitmap(0, 0, buffer.GetWidth(), buffer.GetHeight(), m_pBitmap, 0, 0);
        m_pDevice->StretchDIBits(&buffer, m_Rect.left, m_Rect.top, m_Rect.Width(), m_Rect.Height());
    }
}
CPDF_ScaledRenderBuffer::CPDF_ScaledRenderBuffer()
{
    m_pBitmapDevice = NULL;
}
CPDF_ScaledRenderBuffer::~CPDF_ScaledRenderBuffer()
{
    delete m_pBitmapDevice;
}
#define _FPDFAPI_IMAGESIZE_LIMIT_	(30 * 1024 * 1024)
bool CPDF_ScaledRenderBuffer::Initialize(CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, FX_RECT* pRect,
        const CPDF_PageObject* pObj, const CPDF_RenderOptions *pOptions, int max_dpi)
{
    FXSYS_assert(pRect != NULL);
    m_pDevice = pDevice;
    if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_GET_BITS) {
        return true;
    }
    m_pContext = pContext;
    m_Rect = *pRect;
    m_pObject = pObj;
    m_Matrix.TranslateI(-pRect->left, -pRect->top);
    int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE);
    int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE);
    if (horz_size && vert_size && max_dpi) {
        int dpih = pDevice->GetDeviceCaps(FXDC_PIXEL_WIDTH) * 254 / (horz_size * 10);
        int dpiv = pDevice->GetDeviceCaps(FXDC_PIXEL_HEIGHT) * 254 / (vert_size * 10);
        if (dpih > max_dpi) {
            m_Matrix.Scale((FX_FLOAT)(max_dpi) / dpih, 1.0f);
        }
        if (dpiv > max_dpi) {
            m_Matrix.Scale(1.0f, (FX_FLOAT)(max_dpi) / (FX_FLOAT)dpiv);
        }
    }
    m_pBitmapDevice = new CFX_FxgeDevice;
    FXDIB_Format dibFormat = FXDIB_Rgb;
    int32_t bpp = 24;
    if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_ALPHA_OUTPUT) {
        dibFormat = FXDIB_Argb;
        bpp = 32;
    }
    CFX_FloatRect rect;
    int32_t iWidth, iHeight, iPitch;
    while (1) {
        rect = *pRect;
        m_Matrix.TransformRect(rect);
        FX_RECT bitmap_rect = rect.GetOutterRect();
        iWidth = bitmap_rect.Width();
        iHeight = bitmap_rect.Height();
        iPitch = (iWidth * bpp + 31) / 32 * 4;
        if (iWidth * iHeight < 1) {
            return false;
        }
        if (iPitch * iHeight <= _FPDFAPI_IMAGESIZE_LIMIT_ &&
                m_pBitmapDevice->Create(iWidth, iHeight, dibFormat)) {
            break;
        }
        m_Matrix.Scale(0.5f, 0.5f);
    }
    m_pContext->GetBackground(m_pBitmapDevice->GetBitmap(), m_pObject, pOptions, &m_Matrix);
    return true;
}
void CPDF_ScaledRenderBuffer::OutputToDevice()
{
    if (m_pBitmapDevice) {
        m_pDevice->StretchDIBits(m_pBitmapDevice->GetBitmap(), m_Rect.left, m_Rect.top, m_Rect.Width(), m_Rect.Height());
    }
}
bool IPDF_OCContext::CheckObjectVisible(const CPDF_PageObject* pObj)
{
    const CPDF_ContentMarkData* pData = pObj->m_ContentMark;
    int nItems = pData->CountItems();
    for (int i = 0; i < nItems; i ++) {
        CPDF_ContentMarkItem& item = pData->GetItem(i);
        if (item.GetName() == FX_BSTRC("OC") && item.GetParamType() == CPDF_ContentMarkItem::PropertiesDict) {
            CPDF_Dictionary* pOCG = (CPDF_Dictionary*)item.GetParam();
            if (!CheckOCGVisible(pOCG)) {
                return false;
            }
        }
    }
    return true;
}
