1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright 2014 PDFium Authors. All rights reserved.
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Use of this source code is governed by a BSD-style license that can be
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// found in the LICENSE file.
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fpdfapi/fpdf_render.h"
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fpdfapi/fpdf_pageobj.h"
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fxge/fx_ge.h"
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../fpdf_page/pageint.h"
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "render_int.h"
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstruct CACHEINFO {
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD time;
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Stream* pStream;
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovextern "C" {
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    static int compare(const void* data1, const void* data2)
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return ((CACHEINFO*)data1)->time - ((CACHEINFO*)data2)->time;
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Page::ClearRenderCache()
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pPageRender) {
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pPageRender->ClearAll();
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_PageRenderCache::ClearAll()
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_POSITION pos = m_ImageCaches.GetStartPosition();
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (pos) {
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPVOID key, value;
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_ImageCaches.GetNextAssoc(pos, key, value);
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete (CPDF_ImageCache*)value;
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_ImageCaches.RemoveAll();
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nCacheSize = 0;
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nTimeCount = 0;
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_PageRenderCache::CacheOptimization(FX_INT32 dwLimitCacheSize)
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_nCacheSize <= (FX_DWORD)dwLimitCacheSize) {
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int nCount = m_ImageCaches.GetCount();
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CACHEINFO* pCACHEINFO = (CACHEINFO*)FX_Alloc(FX_BYTE, (sizeof (CACHEINFO)) * nCount);
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_POSITION pos = m_ImageCaches.GetStartPosition();
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i = 0;
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (pos) {
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPVOID key, value;
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_ImageCaches.GetNextAssoc(pos, key, value);
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCACHEINFO[i].time = ((CPDF_ImageCache*)value)->GetTimeCount();
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCACHEINFO[i++].pStream = ((CPDF_ImageCache*)value)->GetStream();
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_qsort(pCACHEINFO, nCount, sizeof (CACHEINFO), compare);
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD nTimeCount = m_nTimeCount;
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (nTimeCount + 1 < nTimeCount) {
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (i = 0; i < nCount; i ++) {
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ((CPDF_ImageCache*)(m_ImageCaches[pCACHEINFO[i].pStream]))->m_dwTimeCount = i;
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_nTimeCount = nCount;
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    i = 0;
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while(nCount > 15) {
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ClearImageCache(pCACHEINFO[i++].pStream);
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        nCount--;
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (m_nCacheSize > (FX_DWORD)dwLimitCacheSize) {
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ClearImageCache(pCACHEINFO[i++].pStream);
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_Free(pCACHEINFO);
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_PageRenderCache::ClearImageCache(CPDF_Stream* pStream)
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_LPVOID value = m_ImageCaches.GetValueAt(pStream);
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (value == NULL)	{
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_ImageCaches.RemoveKey(pStream);
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nCacheSize -= ((CPDF_ImageCache*)value)->EstimateSize();
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    delete (CPDF_ImageCache*)value;
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_ImageCaches.RemoveKey(pStream);
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_DWORD CPDF_PageRenderCache::EstimateSize()
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD dwSize = 0;
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_POSITION pos = m_ImageCaches.GetStartPosition();
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (pos) {
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPVOID key, value;
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_ImageCaches.GetNextAssoc(pos, key, value);
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dwSize += ((CPDF_ImageCache*)value)->EstimateSize();
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nCacheSize = dwSize;
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return dwSize;
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_DWORD CPDF_PageRenderCache::GetCachedSize(CPDF_Stream* pStream) const
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pStream == NULL) {
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_nCacheSize;
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ImageCache* pImageCache;
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_ImageCaches.Lookup(pStream, (FX_LPVOID&)pImageCache)) {
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pImageCache->EstimateSize();
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_PageRenderCache::GetCachedBitmap(CPDF_Stream* pStream, CFX_DIBSource*& pBitmap, CFX_DIBSource*& pMask, FX_DWORD& MatteColor,
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus,
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_INT32 downsampleWidth, FX_INT32 downsampleHeight)
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ImageCache* pImageCache;
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bFind = m_ImageCaches.Lookup(pStream, (FX_LPVOID&)pImageCache);
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!bFind) {
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pImageCache = FX_NEW CPDF_ImageCache(m_pPage->m_pDocument, pStream);
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nTimeCount ++;
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bCached = pImageCache->GetCachedBitmap(pBitmap, pMask, MatteColor, m_pPage->m_pPageResources, bStdCS, GroupFamily, bLoadMask, pRenderStatus, downsampleWidth, downsampleHeight);
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!bFind) {
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_ImageCaches.SetAt(pStream, pImageCache);
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!bCached) {
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_nCacheSize += pImageCache->EstimateSize();
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL	CPDF_PageRenderCache::StartGetCachedBitmap(CPDF_Stream* pStream, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus, FX_INT32 downsampleWidth, FX_INT32 downsampleHeight)
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bCurFindCache = m_ImageCaches.Lookup(pStream, (FX_LPVOID&)m_pCurImageCache);
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_bCurFindCache) {
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCurImageCache = FX_NEW CPDF_ImageCache(m_pPage->m_pDocument, pStream);
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int ret = m_pCurImageCache->StartGetCachedBitmap(pRenderStatus->m_pFormResource, m_pPage->m_pPageResources, bStdCS, GroupFamily, bLoadMask, pRenderStatus, downsampleWidth, downsampleHeight);
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ret == 2) {
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nTimeCount ++;
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_bCurFindCache) {
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_ImageCaches.SetAt(pStream, m_pCurImageCache);
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!ret) {
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_nCacheSize += m_pCurImageCache->EstimateSize();
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL	CPDF_PageRenderCache::Continue(IFX_Pause* pPause)
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int ret = m_pCurImageCache->Continue(pPause);
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ret == 2) {
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nTimeCount ++;
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_bCurFindCache) {
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_ImageCaches.SetAt(m_pCurImageCache->GetStream(), m_pCurImageCache);
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!ret) {
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_nCacheSize += m_pCurImageCache->EstimateSize();
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_PageRenderCache::ResetBitmap(CPDF_Stream* pStream, const CFX_DIBitmap* pBitmap)
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ImageCache* pImageCache;
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_ImageCaches.Lookup(pStream, (FX_LPVOID&)pImageCache)) {
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pBitmap == NULL) {
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pImageCache = FX_NEW CPDF_ImageCache(m_pPage->m_pDocument, pStream);
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_ImageCaches.SetAt(pStream, pImageCache);
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int oldsize = pImageCache->EstimateSize();
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pImageCache->Reset(pBitmap);
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_nCacheSize = pImageCache->EstimateSize() - oldsize;
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_ImageCache::CPDF_ImageCache(CPDF_Document* pDoc, CPDF_Stream* pStream)
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    : m_pDocument(pDoc)
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_pStream(pStream)
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_pCachedBitmap(NULL)
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_pCachedMask(NULL)
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_dwCacheSize(0)
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_dwTimeCount(0)
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_pCurBitmap(NULL)
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_pCurMask(NULL)
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_MatteColor(0)
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_pRenderStatus(NULL)
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_ImageCache::~CPDF_ImageCache()
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCachedBitmap) {
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pCachedBitmap;
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCachedBitmap = NULL;
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCachedMask) {
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pCachedMask;
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCachedMask = NULL;
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_ImageCache::Reset(const CFX_DIBitmap* pBitmap)
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCachedBitmap) {
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pCachedBitmap;
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCachedBitmap = NULL;
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pBitmap) {
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCachedBitmap = pBitmap->Clone();
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CalcSize();
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_PageRenderCache::ClearImageData()
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_POSITION pos = m_ImageCaches.GetStartPosition();
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (pos) {
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_LPVOID key, value;
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_ImageCaches.GetNextAssoc(pos, key, value);
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ((CPDF_ImageCache*)value)->ClearImageData();
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_ImageCache::ClearImageData()
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCachedBitmap && m_pCachedBitmap->GetBuffer() == NULL) {
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        ((CPDF_DIBSource*)m_pCachedBitmap)->ClearImageData();
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovstatic FX_DWORD FPDF_ImageCache_EstimateImageSize(const CFX_DIBSource* pDIB)
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pDIB && pDIB->GetBuffer() ? (FX_DWORD)pDIB->GetHeight() * pDIB->GetPitch() + (FX_DWORD)pDIB->GetPaletteSize() * 4 : 0;
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_ImageCache::GetCachedBitmap(CFX_DIBSource*& pBitmap, CFX_DIBSource*& pMask, FX_DWORD& MatteColor, CPDF_Dictionary* pPageResources,
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus,
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_INT32 downsampleWidth, FX_INT32 downsampleHeight)
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCachedBitmap) {
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBitmap = m_pCachedBitmap;
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pMask = m_pCachedMask;
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        MatteColor = m_MatteColor;
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pRenderStatus) {
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_RenderContext*pContext = pRenderStatus->GetContext();
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_PageRenderCache* pPageRenderCache = pContext->m_pPageCache;
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_dwTimeCount = pPageRenderCache->GetTimeCount();
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_DIBSource* pSrc = FX_NEW CPDF_DIBSource;
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_DIBSource* pMaskSrc = NULL;
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pSrc->Load(m_pDocument, m_pStream, &pMaskSrc, &MatteColor, pRenderStatus->m_pFormResource, pPageResources, bStdCS, GroupFamily, bLoadMask)) {
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete pSrc;
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBitmap = NULL;
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_MatteColor = MatteColor;
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if !defined(_FPDFAPI_MINI_)
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pSrc->GetPitch() * pSrc->GetHeight() < FPDF_HUGE_IMAGE_SIZE) {
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCachedBitmap = pSrc->Clone();
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete pSrc;
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCachedBitmap = pSrc;
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pMaskSrc) {
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCachedMask = pMaskSrc->Clone();
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete pMaskSrc;
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pSrc->GetFormat() == FXDIB_8bppRgb && pSrc->GetPalette() &&
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pSrc->GetHeight() * pSrc->GetWidth() * 3 < 1024) {
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if _FXM_PLATFORM_  == _FXM_PLATFORM_APPLE_
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCachedBitmap = pSrc->CloneConvert(FXDIB_Rgb32);
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCachedBitmap = pSrc->CloneConvert(FXDIB_Rgb);
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete pSrc;
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (pSrc->GetPitch() * pSrc->GetHeight() < 102400) {
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCachedBitmap = pSrc->Clone();
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete pSrc;
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCachedBitmap = pSrc;
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCachedMask = pMaskSrc;
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pBitmap = m_pCachedBitmap;
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pMask = m_pCachedMask;
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CalcSize();
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_DIBSource* CPDF_ImageCache::DetachBitmap()
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_DIBSource* pDIBSource = m_pCurBitmap;
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCurBitmap = NULL;
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pDIBSource;
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_DIBSource* CPDF_ImageCache::DetachMask()
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_DIBSource* pDIBSource = m_pCurMask;
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCurMask = NULL;
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pDIBSource;
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint	CPDF_ImageCache::StartGetCachedBitmap(CPDF_Dictionary* pFormResources, CPDF_Dictionary* pPageResources, FX_BOOL bStdCS,
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus,
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_INT32 downsampleWidth, FX_INT32 downsampleHeight)
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCachedBitmap) {
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCurBitmap = m_pCachedBitmap;
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCurMask = m_pCachedMask;
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 1;
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pRenderStatus) {
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pRenderStatus = pRenderStatus;
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCurBitmap = FX_NEW CPDF_DIBSource;
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int ret = ((CPDF_DIBSource*)m_pCurBitmap)->StartLoadDIBSource(m_pDocument, m_pStream, TRUE, pFormResources, pPageResources, bStdCS, GroupFamily, bLoadMask);
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ret == 2) {
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return ret;
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!ret) {
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pCurBitmap;
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCurBitmap = NULL;
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ContinueGetCachedBitmap();
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 0;
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CPDF_ImageCache::ContinueGetCachedBitmap()
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_MatteColor = ((CPDF_DIBSource*)m_pCurBitmap)->m_MatteColor;
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCurMask = ((CPDF_DIBSource*)m_pCurBitmap)->DetachMask();
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_RenderContext*pContext = m_pRenderStatus->GetContext();
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_PageRenderCache* pPageRenderCache = pContext->m_pPageCache;
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_dwTimeCount = pPageRenderCache->GetTimeCount();
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if !defined(_FPDFAPI_MINI_)
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCurBitmap->GetPitch() * m_pCurBitmap->GetHeight() < FPDF_HUGE_IMAGE_SIZE) {
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCachedBitmap = m_pCurBitmap->Clone();
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pCurBitmap;
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCurBitmap = NULL;
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCachedBitmap = m_pCurBitmap;
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCurMask) {
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCachedMask = m_pCurMask->Clone();
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pCurMask;
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCurMask = NULL;
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pCurBitmap->GetFormat() == FXDIB_8bppRgb && m_pCurBitmap->GetPalette() &&
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pCurBitmap->GetHeight() * m_pCurBitmap->GetWidth() * 3 < 1024) {
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCachedBitmap = m_pCurBitmap->CloneConvert(FXDIB_Rgb32);
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCachedBitmap = m_pCurBitmap->CloneConvert(FXDIB_Rgb);
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pCurBitmap;
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCurBitmap = NULL;
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_pCurBitmap->GetPitch() * m_pCurBitmap->GetHeight() < 102400) {
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCachedBitmap = m_pCurBitmap->Clone();
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pCurBitmap;
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCurBitmap = NULL;
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCachedBitmap = m_pCurBitmap;
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCachedMask = m_pCurMask;
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCurBitmap = m_pCachedBitmap;
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCurMask = m_pCachedMask;
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CalcSize();
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 0;
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint	CPDF_ImageCache::Continue(IFX_Pause* pPause)
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int ret = ((CPDF_DIBSource*)m_pCurBitmap)->ContinueLoadDIBSource(pPause);
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ret == 2) {
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return ret;
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!ret) {
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pCurBitmap;
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pCurBitmap = NULL;
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ContinueGetCachedBitmap();
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 0;
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_ImageCache::CalcSize()
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_dwCacheSize = FPDF_ImageCache_EstimateImageSize(m_pCachedBitmap) + FPDF_ImageCache_EstimateImageSize(m_pCachedMask);
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_Document::ClearRenderFont()
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pDocRender) {
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_FontCache* pCache = m_pDocRender->GetFontCache();
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pCache) {
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pCache->FreeCache(FALSE);
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
390