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_module.h"
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../fpdf_page/pageint.h"
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fxge/fx_ge.h"
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "../../../include/fxcodec/fx_codec.h"
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "render_int.h"
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_DocRenderData::CPDF_DocRenderData(CPDF_Document* pPDFDoc)
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    : m_pPDFDoc(pPDFDoc)
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_pFontCache(NULL)
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_DocRenderData::~CPDF_DocRenderData()
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Clear(TRUE);
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_DocRenderData::Clear(FX_BOOL bRelease)
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_POSITION pos;
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pos = m_Type3FaceMap.GetStartPosition();
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (pos) {
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_Font* pFont;
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_CountedObject<CPDF_Type3Cache*>* cache;
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_Type3FaceMap.GetNextAssoc(pos, pFont, cache);
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (bRelease || cache->m_nCount < 2) {
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                delete cache->m_Obj;
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                delete cache;
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_Type3FaceMap.RemoveKey(pFont);
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef _FPDFAPI_MINI_
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pos = m_TransferFuncMap.GetStartPosition();
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (pos) {
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_Object* key;
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_CountedObject<CPDF_TransferFunc*>* value;
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_TransferFuncMap.GetNextAssoc(pos, key, value);
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (bRelease || value->m_nCount < 2) {
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                delete value->m_Obj;
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                delete value;
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_TransferFuncMap.RemoveKey(key);
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pFontCache) {
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (bRelease) {
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            delete m_pFontCache;
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pFontCache = NULL;
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pFontCache->FreeCache(FALSE);
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_DocRenderData::Initialize()
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pFontCache = FX_NEW CFX_FontCache;
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_Type3Cache* CPDF_DocRenderData::GetCachedType3(CPDF_Type3Font* pFont)
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_CountedObject<CPDF_Type3Cache*>* pCache;
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_Type3FaceMap.Lookup(pFont, pCache)) {
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Type3Cache* pType3 = FX_NEW CPDF_Type3Cache(pFont);
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCache = FX_NEW CPDF_CountedObject<CPDF_Type3Cache*>;
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCache->m_Obj = pType3;
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pCache->m_nCount = 1;
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Type3FaceMap.SetAt(pFont, pCache);
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pCache->m_nCount++;
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pCache->m_Obj;
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_DocRenderData::ReleaseCachedType3(CPDF_Type3Font* pFont)
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_CountedObject<CPDF_Type3Cache*>* pCache;
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_Type3FaceMap.Lookup(pFont, pCache)) {
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pCache->m_nCount--;
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovclass CPDF_RenderModule : public CPDF_RenderModuleDef
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovpublic:
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual ~CPDF_RenderModule() {}
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual FX_BOOL	Installed()
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual CPDF_DocRenderData*	CreateDocData(CPDF_Document* pDoc);
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual void	DestroyDocData(CPDF_DocRenderData* p);
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual void	ClearDocData(CPDF_DocRenderData* p);
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual CPDF_DocRenderData* GetRenderData()
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return &m_RenderData;
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual CPDF_PageRenderCache*	CreatePageCache(CPDF_Page* pPage)
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FX_NEW CPDF_PageRenderCache(pPage);
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual void	DestroyPageCache(CPDF_PageRenderCache* pCache);
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    virtual CPDF_RenderConfig*	GetConfig()
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return &m_RenderConfig;
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovprivate:
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_DocRenderData	m_RenderData;
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_RenderConfig	m_RenderConfig;
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_DocRenderData*	CPDF_RenderModule::CreateDocData(CPDF_Document* pDoc)
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_DocRenderData* pData = FX_NEW CPDF_DocRenderData(pDoc);
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pData->Initialize();
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pData;
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderModule::DestroyDocData(CPDF_DocRenderData* pDocData)
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    delete pDocData;
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderModule::ClearDocData(CPDF_DocRenderData* p)
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (p) {
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        p->Clear(FALSE);
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderModule::DestroyPageCache(CPDF_PageRenderCache* pCache)
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    delete pCache;
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_ModuleMgr::InitRenderModule()
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pRenderModule) {
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pRenderModule;
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pRenderModule = FX_NEW CPDF_RenderModule;
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_RenderOptions::CPDF_RenderOptions()
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    : m_ColorMode(RENDER_COLOR_NORMAL)
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_Flags(RENDER_CLEARTYPE)
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_Interpolation(0)
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_AddFlags(0)
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_pOCContext(NULL)
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_dwLimitCacheSize(1024 * 1024 * 100)
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    , m_HalftoneLimit(-1)
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if defined(_FPDFAPI_MINI_)
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Flags |= RENDER_LIMITEDIMAGECACHE;
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_ARGB CPDF_RenderOptions::TranslateColor(FX_ARGB argb) const
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_ColorMode == RENDER_COLOR_NORMAL) {
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return argb;
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_ColorMode == RENDER_COLOR_ALPHA) {
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return argb;
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int a, r, g, b;
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ArgbDecode(argb, a, r, g, b);
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int gray = FXRGB2GRAY(r, g, b);
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_ColorMode == RENDER_COLOR_TWOCOLOR) {
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int color = (r - gray) * (r - gray) + (g - gray) * (g - gray) + (b - gray) * (b - gray);
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (gray < 35 && color < 20) {
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return ArgbEncode(a, m_ForeColor);
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (gray > 221 && color < 20) {
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return ArgbEncode(a, m_BackColor);
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return argb;
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int fr = FXSYS_GetRValue(m_ForeColor);
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int fg = FXSYS_GetGValue(m_ForeColor);
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int fb = FXSYS_GetBValue(m_ForeColor);
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int br = FXSYS_GetRValue(m_BackColor);
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int bg = FXSYS_GetGValue(m_BackColor);
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int bb = FXSYS_GetBValue(m_BackColor);
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    r = (br - fr) * gray / 255 + fr;
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    g = (bg - fg) * gray / 255 + fg;
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    b = (bb - fb) * gray / 255 + fb;
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return ArgbEncode(a, r, g, b);
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_RenderStatus::CPDF_RenderStatus()
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pContext = NULL;
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bStopped = FALSE;
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Level = 0;
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDevice = NULL;
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCurObj = NULL;
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pStopObj = NULL;
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_HalftoneLimit = 0;
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pObjectRenderer = NULL;
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bPrint = FALSE;
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Transparency = 0;
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DitherBits = 0;
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bDropObjects = FALSE;
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bStdCS = FALSE;
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_GroupFamily = 0;
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bLoadMask = FALSE;
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pType3Char = NULL;
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_T3FillColor = 0;
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pFormResource = NULL;
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pPageResource = NULL;
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_curBlend = FXDIB_BLEND_NORMAL;
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_RenderStatus::~CPDF_RenderStatus()
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pObjectRenderer) {
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pObjectRenderer;
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_RenderStatus::Initialize(int level, CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice,
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      const CFX_AffineMatrix* pDeviceMatrix, const CPDF_PageObject* pStopObj,
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      const CPDF_RenderStatus* pParentState, const CPDF_GraphicStates* pInitialStates,
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      const CPDF_RenderOptions* pOptions, int transparency, FX_BOOL bDropObjects,
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      CPDF_Dictionary* pFormResource, FX_BOOL bStdCS, CPDF_Type3Char* pType3Char,
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      FX_ARGB fill_color, FX_DWORD GroupFamily,
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      FX_BOOL bLoadMask)
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Level = level;
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pContext = pContext;
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDevice = pDevice;
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_DitherBits = pDevice->GetDeviceCaps(FXDC_DITHER_BITS);
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bPrint = m_pDevice->GetDeviceClass() != FXDC_DISPLAY;
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pDeviceMatrix) {
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_DeviceMatrix = *pDeviceMatrix;
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pStopObj = pStopObj;
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pOptions) {
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Options = *pOptions;
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bDropObjects = bDropObjects;
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bStdCS = bStdCS;
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_T3FillColor = fill_color;
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pType3Char = pType3Char;
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_GroupFamily = GroupFamily;
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bLoadMask = bLoadMask;
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pFormResource = pFormResource;
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pPageResource = m_pContext->m_pPageResources;
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pInitialStates && !m_pType3Char) {
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_InitialStates.CopyStates(*pInitialStates);
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pParentState) {
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_ColorStateData* pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)m_InitialStates.m_ColorState;
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_ColorStateData* pParentData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)pParentState->m_InitialStates.m_ColorState;
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!pColorData || pColorData->m_FillColor.IsNull()) {
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                CPDF_ColorStateData* pData = m_InitialStates.m_ColorState.GetModify();
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pData->m_FillRGB = pParentData->m_FillRGB;
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pData->m_FillColor.Copy(&pParentData->m_FillColor);
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!pColorData || pColorData->m_StrokeColor.IsNull()) {
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                CPDF_ColorStateData* pData = m_InitialStates.m_ColorState.GetModify();
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pData->m_StrokeRGB = pParentData->m_FillRGB;
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pData->m_StrokeColor.Copy(&pParentData->m_StrokeColor);
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_InitialStates.DefaultStates();
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if defined(_FPDFAPI_MINI_)||defined(_FXCORE_LIMITED_CPU_)
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_HalftoneLimit = CPDF_ModuleMgr::Get()->GetRenderModule()->GetConfig()->m_HalftoneLimit;
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pOptions && pOptions->m_HalftoneLimit >= 0) {
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_HalftoneLimit = pOptions->m_HalftoneLimit;
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pObjectRenderer = NULL;
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Transparency = transparency;
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderStatus::RenderObjectList(const CPDF_PageObjects* pObjs, const CFX_AffineMatrix* pObj2Device)
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Level > 32) {
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_FloatRect clip_rect = m_pDevice->GetClipBox();
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_AffineMatrix device2object;
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    device2object.SetReverse(*pObj2Device);
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    device2object.TransformRect(clip_rect);
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int index = 0;
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_POSITION pos = pObjs->GetFirstObjectPosition();
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while(pos) {
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        index ++;
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_PageObject* pCurObj = pObjs->GetNextObject(pos);
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pCurObj == m_pStopObj) {
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_bStopped = TRUE;
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!pCurObj) {
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if(pCurObj == NULL || pCurObj->m_Left > clip_rect.right || pCurObj->m_Right < clip_rect.left ||
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pCurObj->m_Bottom > clip_rect.top || pCurObj->m_Top < clip_rect.bottom) {
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        RenderSingleObject(pCurObj, pObj2Device);
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_bStopped) {
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderStatus::RenderSingleObject(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device)
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Level > 32) {
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCurObj = pObj;
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Options.m_pOCContext && pObj->m_ContentMark.NotNull())
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!m_Options.m_pOCContext->CheckObjectVisible(pObj)) {
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ProcessClipPath(pObj->m_ClipPath, pObj2Device);
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ProcessTransparency(pObj, pObj2Device)) {
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ProcessObjectNoClip(pObj, pObj2Device);
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_RenderStatus::ContinueSingleObject(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, IFX_Pause* pPause)
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pObjectRenderer) {
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pObjectRenderer->Continue(pPause)) {
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return TRUE;
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!m_pObjectRenderer->m_Result) {
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            DrawObjWithBackground(pObj, pObj2Device);
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef _FPDFAPI_MINI_
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_DitherBits) {
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            DitherObjectArea(pObj, pObj2Device);
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pObjectRenderer;
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pObjectRenderer = NULL;
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pCurObj = pObj;
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Options.m_pOCContext && pObj->m_ContentMark.NotNull())
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!m_Options.m_pOCContext->CheckObjectVisible(pObj)) {
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ProcessClipPath(pObj->m_ClipPath, pObj2Device);
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ProcessTransparency(pObj, pObj2Device)) {
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pObj->m_Type == PDFPAGE_IMAGE) {
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pObjectRenderer = IPDF_ObjectRenderer::Create(pObj->m_Type);
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!m_pObjectRenderer->Start(this, pObj, pObj2Device, FALSE)) {
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!m_pObjectRenderer->m_Result) {
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                DrawObjWithBackground(pObj, pObj2Device);
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef _FPDFAPI_MINI_
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_DitherBits) {
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                DitherObjectArea(pObj, pObj2Device);
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            delete m_pObjectRenderer;
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pObjectRenderer = NULL;
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return ContinueSingleObject(pObj, pObj2Device, pPause);
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ProcessObjectNoClip(pObj, pObj2Device);
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return FALSE;
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovIPDF_ObjectRenderer* IPDF_ObjectRenderer::Create(int type)
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    IPDF_ObjectRenderer* pRenderer = NULL;
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (type == PDFPAGE_IMAGE) {
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pRenderer = FX_NEW CPDF_ImageRenderer;
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pRenderer;
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_RenderStatus::GetObjectClippedRect(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bLogical, FX_RECT &rect) const
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rect = pObj->GetBBox(pObj2Device);
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_RECT rtClip = m_pDevice->GetClipBox();
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!bLogical) {
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_Matrix dCTM = m_pDevice->GetCTM();
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT a = FXSYS_fabs(dCTM.a);
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT d = FXSYS_fabs(dCTM.d);
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (a != 1.0f || d != 1.0f) {
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            rect.right = rect.left + (FX_INT32)FXSYS_ceil((FX_FLOAT)rect.Width() * a);
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            rect.bottom = rect.top + (FX_INT32)FXSYS_ceil((FX_FLOAT)rect.Height() * d);
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            rtClip.right = rtClip.left + (FX_INT32)FXSYS_ceil((FX_FLOAT)rtClip.Width() * a);
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            rtClip.bottom = rtClip.top + (FX_INT32)FXSYS_ceil((FX_FLOAT)rtClip.Height() * d);
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rect.Intersect(rtClip);
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return rect.IsEmpty();
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderStatus::DitherObjectArea(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device)
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_DIBitmap* pBitmap = m_pDevice->GetBitmap();
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pBitmap == NULL) {
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_RECT rect;
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (GetObjectClippedRect(pObj, pObj2Device, FALSE, rect)) {
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_DitherBits == 2) {
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        static FX_ARGB pal[4] = {0, 85, 170, 255};
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBitmap->DitherFS(pal, 4, &rect);
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_DitherBits == 3) {
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        static FX_ARGB pal[8] = {0, 36, 73, 109, 146, 182, 219, 255};
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBitmap->DitherFS(pal, 8, &rect);
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (m_DitherBits == 4) {
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        static FX_ARGB pal[16] = {0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255};
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBitmap->DitherFS(pal, 16, &rect);
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderStatus::ProcessObjectNoClip(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device)
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bRet = FALSE;
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    switch (pObj->m_Type) {
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case PDFPAGE_TEXT:
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bRet = ProcessText((CPDF_TextObject*)pObj, pObj2Device, NULL);
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case PDFPAGE_PATH:
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bRet = ProcessPath((CPDF_PathObject*)pObj, pObj2Device);
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case PDFPAGE_IMAGE:
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bRet = ProcessImage((CPDF_ImageObject*)pObj, pObj2Device);
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case PDFPAGE_SHADING:
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bRet = ProcessShading((CPDF_ShadingObject*)pObj, pObj2Device);
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case PDFPAGE_FORM:
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bRet = ProcessForm((CPDF_FormObject*)pObj, pObj2Device);
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if defined(_FPDFAPI_MINI_)
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case PDFPAGE_INLINES:
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bRet = ProcessInlines((CPDF_InlineImages*)pObj, pObj2Device);
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!bRet) {
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        DrawObjWithBackground(pObj, pObj2Device);
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_RenderStatus::DrawObjWithBlend(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device)
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bRet = FALSE;
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    switch (pObj->m_Type) {
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case PDFPAGE_PATH:
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bRet = ProcessPath((CPDF_PathObject*)pObj, pObj2Device);
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case PDFPAGE_IMAGE:
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bRet = ProcessImage((CPDF_ImageObject *)pObj, pObj2Device);
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        case PDFPAGE_FORM:
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bRet = ProcessForm((CPDF_FormObject*)pObj, pObj2Device);
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return bRet;
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderStatus::GetScaledMatrix(CFX_Matrix &matrix) const
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_Matrix dCTM = m_pDevice->GetCTM();
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    matrix.a *= FXSYS_fabs(dCTM.a);
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    matrix.d *= FXSYS_fabs(dCTM.d);
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderStatus::DrawObjWithBackground(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device)
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if !defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_)
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_RECT rect;
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (GetObjectClippedRect(pObj, pObj2Device, FALSE, rect)) {
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int res = 300;
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pObj->m_Type == PDFPAGE_IMAGE && m_pDevice->GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER) {
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        res = 0;
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ScaledRenderBuffer buffer;
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!buffer.Initialize(m_pContext, m_pDevice, &rect, pObj, &m_Options, res)) {
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_AffineMatrix matrix = *pObj2Device;
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    matrix.Concat(*buffer.GetMatrix());
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    GetScaledMatrix(matrix);
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pFormResource = NULL;
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pObj->m_Type == PDFPAGE_FORM) {
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_FormObject* pFormObj = (CPDF_FormObject*)pObj;
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pFormObj->m_pForm && pFormObj->m_pForm->m_pFormDict) {
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pFormResource = pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources"));
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_RenderStatus status;
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    status.Initialize(m_Level + 1, m_pContext, buffer.GetDevice(), buffer.GetMatrix(), NULL, NULL, NULL, &m_Options, m_Transparency, m_bDropObjects, pFormResource);
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    status.RenderSingleObject(pObj, &matrix);
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    buffer.OutputToDevice();
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_RenderStatus::ProcessForm(CPDF_FormObject* pFormObj, const CFX_AffineMatrix* pObj2Device)
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pOC = pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("OC"));
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pOC && m_Options.m_pOCContext && !m_Options.m_pOCContext->CheckOCGVisible(pOC)) {
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_AffineMatrix matrix = pFormObj->m_FormMatrix;
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    matrix.Concat(*pObj2Device);
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pResources = NULL;
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pFormObj->m_pForm && pFormObj->m_pForm->m_pFormDict) {
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pResources = pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources"));
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_RenderStatus status;
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    status.Initialize(m_Level + 1, m_pContext, m_pDevice, NULL, m_pStopObj,
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                      this, pFormObj, &m_Options, m_Transparency, m_bDropObjects, pResources, TRUE);
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    status.m_curBlend = m_curBlend;
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDevice->SaveState();
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    status.RenderObjectList(pFormObj->m_pForm, &matrix);
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bStopped = status.m_bStopped;
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDevice->RestoreState();
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL IsAvailableMatrix(const CFX_AffineMatrix& matrix)
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (matrix.a == 0 || matrix.d == 0) {
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return matrix.b != 0 && matrix.c != 0;
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (matrix.b == 0 || matrix.c == 0) {
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return matrix.a != 0 && matrix.d != 0;
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_RenderStatus::ProcessPath(CPDF_PathObject* pPathObj, const CFX_AffineMatrix* pObj2Device)
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int FillType = pPathObj->m_FillType;
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bStroke = pPathObj->m_bStroke;
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ProcessPathPattern(pPathObj, pObj2Device, FillType, bStroke);
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (FillType == 0 && !bStroke) {
535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD fill_argb = 0;
538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (FillType) {
539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        fill_argb = GetFillArgb(pPathObj);
540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD stroke_argb = 0;
542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bStroke) {
543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        stroke_argb = GetStrokeArgb(pPathObj);
544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_AffineMatrix path_matrix = pPathObj->m_Matrix;
546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    path_matrix.Concat(*pObj2Device);
547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!IsAvailableMatrix(path_matrix)) {
548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (FillType && (m_Options.m_Flags & RENDER_RECT_AA)) {
551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FillType |= FXFILL_RECT_AA;
552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Options.m_Flags & RENDER_FILL_FULLCOVER) {
554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FillType |= FXFILL_FULLCOVER;
555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) {
557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FillType |= FXFILL_NOPATHSMOOTH;
558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bStroke) {
560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FillType |= FX_FILL_STROKE;
561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if !defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_)
563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const CPDF_GeneralStateData* pGeneralData = ((CPDF_PageObject*)pPathObj)->m_GeneralState;
564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pGeneralData && pGeneralData->m_StrokeAdjust) {
565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FillType |= FX_STROKE_ADJUST;
566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pType3Char) {
569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FillType |= FX_FILL_TEXT_MODE;
570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_GraphStateData graphState(*pPathObj->m_GraphState);
572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Options.m_Flags & RENDER_THINLINE) {
573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        graphState.m_LineWidth = 0;
574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_pDevice->DrawPath(pPathObj->m_Path, &path_matrix, &graphState, fill_argb, stroke_argb, FillType, 0, NULL, m_curBlend);
576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
577ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_TransferFunc* CPDF_RenderStatus::GetTransferFunc(CPDF_Object* pObj) const
578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT(pObj != NULL);
580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_DocRenderData* pDocCache = m_pContext->m_pDocument->GetRenderData();
581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pDocCache) {
582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pDocCache->GetTransferFunc(pObj);
585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
586ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_ARGB CPDF_RenderStatus::GetFillArgb(const CPDF_PageObject* pObj, FX_BOOL bType3) const
587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ColorStateData* pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)pObj->m_ColorState;
589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pType3Char && !bType3 && (!m_pType3Char->m_bColored || (m_pType3Char->m_bColored && (!pColorData || pColorData->m_FillColor.IsNull())))) {
590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_T3FillColor;
591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (!pColorData || pColorData->m_FillColor.IsNull()) {
592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)m_InitialStates.m_ColorState;
593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_COLORREF rgb = pColorData->m_FillRGB;
595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (rgb == (FX_DWORD) - 1) {
596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
597ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
598ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const CPDF_GeneralStateData* pGeneralData = pObj->m_GeneralState;
599ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int alpha;
600ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pGeneralData) {
601ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        alpha = (FX_INT32)(pGeneralData->m_FillAlpha * 255);
602ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef _FPDFAPI_MINI_
603ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pGeneralData->m_pTR) {
604ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!pGeneralData->m_pTransferFunc) {
605ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                ((CPDF_GeneralStateData*)pGeneralData)->m_pTransferFunc = GetTransferFunc(pGeneralData->m_pTR);
606ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
607ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pGeneralData->m_pTransferFunc) {
608ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                rgb = pGeneralData->m_pTransferFunc->TranslateColor(rgb);
609ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
610ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
611ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
612ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
613ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        alpha = 255;
614ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
615ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_Options.TranslateColor(ArgbEncode(alpha, rgb));
616ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
617ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_ARGB CPDF_RenderStatus::GetStrokeArgb(const CPDF_PageObject* pObj) const
618ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
619ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_ColorStateData* pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)pObj->m_ColorState;
620ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pType3Char && (!m_pType3Char->m_bColored || (m_pType3Char->m_bColored && (!pColorData || pColorData->m_StrokeColor.IsNull())))) {
621ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_T3FillColor;
622ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else if (!pColorData || pColorData->m_StrokeColor.IsNull()) {
623ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)m_InitialStates.m_ColorState;
624ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
625ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_COLORREF rgb = pColorData->m_StrokeRGB;
626ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (rgb == (FX_DWORD) - 1) {
627ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
628ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
629ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const CPDF_GeneralStateData* pGeneralData = pObj->m_GeneralState;
630ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int alpha;
631ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pGeneralData) {
632ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        alpha = (FX_INT32)(pGeneralData->m_StrokeAlpha * 255);
633ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef _FPDFAPI_MINI_
634ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pGeneralData->m_pTR) {
635ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!pGeneralData->m_pTransferFunc) {
636ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                ((CPDF_GeneralStateData*)pGeneralData)->m_pTransferFunc = GetTransferFunc(pGeneralData->m_pTR);
637ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
638ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pGeneralData->m_pTransferFunc) {
639ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                rgb = pGeneralData->m_pTransferFunc->TranslateColor(rgb);
640ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
641ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
642ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
643ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
644ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        alpha = 255;
645ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
646ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_Options.TranslateColor(ArgbEncode(alpha, rgb));
647ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
648ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderStatus::ProcessClipPath(CPDF_ClipPath ClipPath, const CFX_AffineMatrix* pObj2Device)
649ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
650ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ClipPath.IsNull()) {
651ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_LastClipPath.IsNull()) {
652ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
653ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
654ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pDevice->RestoreState(TRUE);
655ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_LastClipPath.SetNull();
656ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
657ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
658ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_LastClipPath == ClipPath) {
659ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
660ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
661ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_LastClipPath = ClipPath;
662ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDevice->RestoreState(TRUE);
663ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int nClipPath = ClipPath.GetPathCount();
664ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
665ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < nClipPath; i++) {
666ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        const CFX_PathData* pPathData = ClipPath.GetPath(i);
667ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pPathData == NULL) {
668ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
669ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
670ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pPathData->GetPointCount() == 0) {
671ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CFX_PathData EmptyPath;
672ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            EmptyPath.AppendRect(-1, -1, 0, 0);
673ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int fill_mode = FXFILL_WINDING;
674ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pDevice->SetClip_PathFill(&EmptyPath, NULL, fill_mode);
675ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
676ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int ClipType = ClipPath.GetClipType(i);
677ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pDevice->SetClip_PathFill(pPathData, pObj2Device, ClipType);
678ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
679ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
680ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int textcount = ClipPath.GetTextCount();
681ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (textcount == 0) {
682ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
683ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
684ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pDevice->GetDeviceClass() == FXDC_DISPLAY && !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)) {
685ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
686ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
687ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_PathData* pTextClippingPath = NULL;
688ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < textcount; i ++) {
689ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_TextObject* pText = ClipPath.GetText(i);
690ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pText == NULL) {
691ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pTextClippingPath) {
692ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int fill_mode = FXFILL_WINDING;
693ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (m_Options.m_Flags & RENDER_NOTEXTSMOOTH) {
694ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    fill_mode |= FXFILL_NOPATHSMOOTH;
695ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
696ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_pDevice->SetClip_PathFill(pTextClippingPath, NULL, fill_mode);
697ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                delete pTextClippingPath;
698ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pTextClippingPath = NULL;
699ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
700ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
701ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pTextClippingPath == NULL) {
702ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pTextClippingPath = FX_NEW CFX_PathData;
703ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
704ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            ProcessText(pText, pObj2Device, pTextClippingPath);
705ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
706ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
707ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pTextClippingPath) {
708ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete pTextClippingPath;
709ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
710ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
711ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderStatus::DrawClipPath(CPDF_ClipPath ClipPath, const CFX_AffineMatrix* pObj2Device)
712ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
713ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (ClipPath.IsNull()) {
714ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
715ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
716ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int fill_mode = 0;
717ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) {
718ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        fill_mode |= FXFILL_NOPATHSMOOTH;
719ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
720ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int nClipPath = ClipPath.GetPathCount();
721ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int i;
722ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (i = 0; i < nClipPath; i++) {
723ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        const CFX_PathData* pPathData = ClipPath.GetPath(i);
724ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pPathData == NULL) {
725ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            continue;
726ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
727ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_GraphStateData stroke_state;
728ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_Options.m_Flags & RENDER_THINLINE) {
729ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            stroke_state.m_LineWidth = 0;
730ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
731ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pDevice->DrawPath(pPathData, pObj2Device, &stroke_state, 0, 0xffff0000, fill_mode);
732ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
733ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
734ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_RenderStatus::SelectClipPath(CPDF_PathObject* pPathObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStroke)
735ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
736ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_AffineMatrix path_matrix = pPathObj->m_Matrix;
737ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    path_matrix.Concat(*pObj2Device);
738ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bStroke) {
739ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_GraphStateData graphState(*pPathObj->m_GraphState);
740ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_Options.m_Flags & RENDER_THINLINE) {
741ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            graphState.m_LineWidth = 0;
742ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
743ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return m_pDevice->SetClip_PathStroke(pPathObj->m_Path, &path_matrix, &graphState);
744ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
745ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int fill_mode = pPathObj->m_FillType;
746ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) {
747ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        fill_mode |= FXFILL_NOPATHSMOOTH;
748ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
749ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return m_pDevice->SetClip_PathFill(pPathObj->m_Path, &path_matrix, fill_mode);
750ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
751ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_RenderStatus::ProcessTransparency(const CPDF_PageObject* pPageObj, const CFX_AffineMatrix* pObj2Device)
752ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
753ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const CPDF_GeneralStateData* pGeneralState = pPageObj->m_GeneralState;
754ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int blend_type = pGeneralState ? pGeneralState->m_BlendType : FXDIB_BLEND_NORMAL;
755ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (blend_type == FXDIB_BLEND_UNSUPPORTED) {
756ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
757ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
758ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pSMaskDict = pGeneralState ? (CPDF_Dictionary*)pGeneralState->m_pSoftMask : NULL;
759ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pSMaskDict) {
760ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pPageObj->m_Type == PDFPAGE_IMAGE &&
761ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                ((CPDF_ImageObject*)pPageObj)->m_pImage->GetDict()->KeyExist(FX_BSTRC("SMask"))) {
762ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pSMaskDict = NULL;
763ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
764ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
765ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Dictionary* pFormResource = NULL;
766ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT group_alpha = 1.0f;
767ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int Transparency = m_Transparency;
768ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bGroupTransparent = FALSE;
769ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pPageObj->m_Type == PDFPAGE_FORM) {
770ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj;
771ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        const CPDF_GeneralStateData *pStateData = pFormObj->m_GeneralState.GetObject();
772ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pStateData) {
773ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            group_alpha = pStateData->m_FillAlpha;
774ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
775ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        Transparency = pFormObj->m_pForm->m_Transparency;
776ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bGroupTransparent = Transparency & PDFTRANS_ISOLATED ? TRUE : FALSE;
777ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pFormObj->m_pForm->m_pFormDict) {
778ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pFormResource = pFormObj->m_pForm->m_pFormDict->GetDict("Resources");
779ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
780ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
781ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bTextClip = FALSE;
782ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pPageObj->m_ClipPath.NotNull() && pPageObj->m_ClipPath.GetTextCount() &&
783ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pDevice->GetDeviceClass() == FXDC_DISPLAY && !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)) {
784ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bTextClip = TRUE;
785ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
786ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if ((m_Options.m_Flags & RENDER_OVERPRINT) && pPageObj->m_Type == PDFPAGE_IMAGE && pGeneralState && pGeneralState->m_FillOP && pGeneralState->m_StrokeOP) {
787ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Document* pDocument = NULL;
788ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Page* pPage = NULL;
789ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pContext->m_pPageCache) {
790ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pPage = m_pContext->m_pPageCache->GetPage();
791ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pDocument = pPage->m_pDocument;
792ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
793ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pDocument = ((CPDF_ImageObject*)pPageObj)->m_pImage->GetDocument();
794ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
795ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : NULL;
796ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Object* pCSObj = ((CPDF_ImageObject*)pPageObj)->m_pImage->GetStream()->GetDict()->GetElementValue(FX_BSTRC("ColorSpace"));
797ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_ColorSpace* pColorSpace = pDocument->LoadColorSpace(pCSObj, pPageResources);
798ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pColorSpace) {
799ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int format = pColorSpace->GetFamily();
800ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION || format == PDFCS_DEVICEN) {
801ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                blend_type = FXDIB_BLEND_DARKEN;
802ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
803ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pDocument->GetPageData()->ReleaseColorSpace(pCSObj);
804ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
805ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
806ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pSMaskDict == NULL && group_alpha == 1.0f && blend_type == FXDIB_BLEND_NORMAL && !bTextClip && !bGroupTransparent) {
807ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return FALSE;
808ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
809ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL isolated = Transparency & PDFTRANS_ISOLATED;
810ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_bPrint) {
811ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BOOL bRet = FALSE;
812ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int rendCaps = m_pDevice->GetRenderCaps();
813ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!((Transparency & PDFTRANS_ISOLATED) || pSMaskDict || bTextClip) && (rendCaps & FXRC_BLEND_MODE)) {
814ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            int oldBlend = m_curBlend;
815ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_curBlend = blend_type;
816ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bRet = DrawObjWithBlend(pPageObj, pObj2Device);
817ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_curBlend = oldBlend;
818ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
819ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!bRet) {
820ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            DrawObjWithBackground(pPageObj, pObj2Device);
821ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
822ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
823ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
824ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_RECT rect = pPageObj->GetBBox(pObj2Device);
825ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    rect.Intersect(m_pDevice->GetClipBox());
826ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (rect.IsEmpty()) {
827ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
828ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
829ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_Matrix deviceCTM = m_pDevice->GetCTM();
830ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT scaleX = FXSYS_abs(deviceCTM.a);
831ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT scaleY = FXSYS_abs(deviceCTM.d);
832ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int width = FXSYS_round((FX_FLOAT)rect.Width() * scaleX);
833ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int height = FXSYS_round((FX_FLOAT)rect.Height() * scaleY);
834ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_FxgeDevice bitmap_device;
835ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_DIBitmap* oriDevice = NULL;
836ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!isolated && (m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) {
837ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        oriDevice = FX_NEW CFX_DIBitmap;
838ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!m_pDevice->CreateCompatibleBitmap(oriDevice, width, height)) {
839ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return TRUE;
840ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
841ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pDevice->GetDIBits(oriDevice, rect.left, rect.top);
842ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
843ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!bitmap_device.Create(width, height, FXDIB_Argb, 0, oriDevice)) {
844ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
845ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
846ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_DIBitmap* bitmap = bitmap_device.GetBitmap();
847ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bitmap->Clear(0);
848ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_AffineMatrix new_matrix = *pObj2Device;
849ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    new_matrix.TranslateI(-rect.left, -rect.top);
850ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    new_matrix.Scale(scaleX, scaleY);
851ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_DIBitmap* pTextMask = NULL;
852ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bTextClip) {
853ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pTextMask = FX_NEW CFX_DIBitmap;
854ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!pTextMask->Create(width, height, FXDIB_8bppMask)) {
855ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            delete pTextMask;
856ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return TRUE;
857ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
858ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pTextMask->Clear(0);
859ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_FxgeDevice text_device;
860ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        text_device.Attach(pTextMask);
861ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (FX_DWORD i = 0; i < pPageObj->m_ClipPath.GetTextCount(); i ++) {
862ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_TextObject* textobj = pPageObj->m_ClipPath.GetText(i);
863ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (textobj == NULL) {
864ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
865ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
866ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CFX_AffineMatrix text_matrix;
867ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            textobj->GetTextMatrix(&text_matrix);
868ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_TextRenderer::DrawTextPath(&text_device, textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos,
869ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                            textobj->m_TextState.GetFont(), textobj->m_TextState.GetFontSize(),
870ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                            &text_matrix, &new_matrix, textobj->m_GraphState, (FX_ARGB) - 1, 0, NULL);
871ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
872ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
873ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_RenderStatus bitmap_render;
874ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bitmap_render.Initialize(m_Level + 1, m_pContext, &bitmap_device, NULL,
875ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                             m_pStopObj, NULL, NULL, &m_Options, 0, m_bDropObjects, pFormResource, TRUE);
876ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bitmap_render.ProcessObjectNoClip(pPageObj, &new_matrix);
877ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bStopped = bitmap_render.m_bStopped;
878ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pSMaskDict) {
879ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_AffineMatrix smask_matrix;
880ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_memcpy32(&smask_matrix, pGeneralState->m_SMaskMatrix, sizeof smask_matrix);
881ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        smask_matrix.Concat(*pObj2Device);
882ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_DIBSource* pSMaskSource = LoadSMask(pSMaskDict, &rect, &smask_matrix);
883ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pSMaskSource) {
884ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bitmap->MultiplyAlpha(pSMaskSource);
885ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            delete pSMaskSource;
886ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
887ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
888ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pTextMask) {
889ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bitmap->MultiplyAlpha(pTextMask);
890ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete pTextMask;
891ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pTextMask = NULL;
892ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
893ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (Transparency & PDFTRANS_GROUP && group_alpha != 1.0f) {
894ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bitmap->MultiplyAlpha((FX_INT32)(group_alpha * 255));
895ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
896ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Transparency = m_Transparency;
897ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pPageObj->m_Type == PDFPAGE_FORM) {
898ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        Transparency |= PDFTRANS_GROUP;
899ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
900ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CompositeDIBitmap(bitmap, rect.left, rect.top, 0, 255, blend_type, Transparency);
901ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (oriDevice) {
902ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete oriDevice;
903ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
904ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
905ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
906ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCFX_DIBitmap* CPDF_RenderStatus::GetBackdrop(const CPDF_PageObject* pObj, const FX_RECT& rect, int& left, int& top,
907ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BOOL bBackAlphaRequired)
908ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
909ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_RECT bbox = rect;
910ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    bbox.Intersect(m_pDevice->GetClipBox());
911ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    left = bbox.left;
912ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    top = bbox.top;
913ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_Matrix deviceCTM = m_pDevice->GetCTM();
914ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT scaleX = FXSYS_abs(deviceCTM.a);
915ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT scaleY = FXSYS_abs(deviceCTM.d);
916ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int width = FXSYS_round(bbox.Width() * scaleX);
917ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int height = FXSYS_round(bbox.Height() * scaleY);
918ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_DIBitmap* pBackdrop = FX_NEW CFX_DIBitmap;
919ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (bBackAlphaRequired && !m_bDropObjects) {
920ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pBackdrop->Create(width, height, FXDIB_Argb);
921ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
922ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pDevice->CreateCompatibleBitmap(pBackdrop, width, height);
923ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
924ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pBackdrop->GetBuffer() == NULL) {
925ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete pBackdrop;
926ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
927ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
928ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_BOOL bNeedDraw;
929ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pBackdrop->HasAlpha()) {
930ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT);
931ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
932ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_GET_BITS);
933ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
934ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!bNeedDraw) {
935ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pDevice->GetDIBits(pBackdrop, left, top);
936ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return pBackdrop;
937ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
938ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_AffineMatrix FinalMatrix = m_DeviceMatrix;
939ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FinalMatrix.TranslateI(-left, -top);
940ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FinalMatrix.Scale(scaleX, scaleY);
941ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pBackdrop->Clear(pBackdrop->HasAlpha() ? 0 : 0xffffffff);
942ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_FxgeDevice device;
943ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    device.Attach(pBackdrop);
944ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pContext->Render(&device, pObj, &m_Options, &FinalMatrix);
945ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pBackdrop;
946ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
947ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderContext::GetBackground(CFX_DIBitmap* pBuffer, const CPDF_PageObject* pObj,
948ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                       const CPDF_RenderOptions* pOptions, CFX_AffineMatrix* pFinalMatrix)
949ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
950ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_FxgeDevice device;
951ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    device.Attach(pBuffer);
952ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pBackgroundDraw) {
953ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pBackgroundDraw->OnDrawBackground(&device, pFinalMatrix);
954ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
955ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_RECT rect(0, 0, device.GetWidth(), device.GetHeight());
956ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        device.FillRect(&rect, 0xffffffff);
957ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
958ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Render(&device, pObj, pOptions, pFinalMatrix);
959ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
960ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_GraphicStates* CPDF_RenderStatus::CloneObjStates(const CPDF_GraphicStates* pSrcStates, FX_BOOL bStroke)
961ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
962ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pSrcStates) {
963ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
964ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
965ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_GraphicStates* pStates = FX_NEW CPDF_GraphicStates;
966ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pStates) {
967ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
968ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
969ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pStates->CopyStates(*pSrcStates);
970ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_Color* pObjColor = bStroke ? pSrcStates->m_ColorState.GetStrokeColor() :
971ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            pSrcStates->m_ColorState.GetFillColor();
972ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!pObjColor->IsNull()) {
973ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_ColorStateData* pColorData = pStates->m_ColorState.GetModify();
974ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pColorData->m_FillRGB = bStroke ? pSrcStates->m_ColorState.GetObject()->m_StrokeRGB :
975ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                pSrcStates->m_ColorState.GetObject()->m_FillRGB;
976ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pColorData->m_StrokeRGB = pColorData->m_FillRGB;
977ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
978ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pStates;
979ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
980ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_RenderContext::CPDF_RenderContext()
981ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
982ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
983ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderContext::Create(CPDF_Document* pDoc, CPDF_PageRenderCache* pPageCache,
984ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                CPDF_Dictionary* pPageResources, FX_BOOL bFirstLayer)
985ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
986ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBackgroundDraw = NULL;
987ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDocument = pDoc;
988ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pPageResources = pPageResources;
989ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pPageCache = pPageCache;
990ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bFirstLayer = bFirstLayer;
991ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
992ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderContext::Create(CPDF_Page* pPage, FX_BOOL bFirstLayer)
993ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
994ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBackgroundDraw = NULL;
995ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDocument = pPage->m_pDocument;
996ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pPageResources = pPage->m_pPageResources;
997ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pPageCache = pPage->GetRenderCache();
998ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bFirstLayer = bFirstLayer;
999ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1000ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_RenderContext::~CPDF_RenderContext()
1001ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1002ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1003ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderContext::Clear()
1004ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1005ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDocument = NULL;
1006ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pPageResources = NULL;
1007ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pPageCache = NULL;
1008ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBackgroundDraw = NULL;
1009ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bFirstLayer = TRUE;
1010ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_ContentList.RemoveAll();
1011ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1012ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderContext::AppendObjectList(CPDF_PageObjects* pObjs, const CFX_AffineMatrix* pObject2Device)
1013ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1014ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    _PDF_RenderItem* pItem = m_ContentList.AddSpace();
1015ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pItem->m_pObjectList = pObjs;
1016ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pObject2Device) {
1017ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pItem->m_Matrix = *pObject2Device;
1018ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1019ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pItem->m_Matrix.SetIdentity();
1020ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1021ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1022ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderContext::Render(CFX_RenderDevice* pDevice, const CPDF_RenderOptions* pOptions,
1023ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                const CFX_AffineMatrix* pLastMatrix)
1024ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1025ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Render(pDevice, NULL, pOptions, pLastMatrix);
1026ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1027ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderContext::Render(CFX_RenderDevice* pDevice, const CPDF_PageObject* pStopObj,
1028ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                const CPDF_RenderOptions* pOptions, const CFX_AffineMatrix* pLastMatrix)
1029ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1030ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int count = m_ContentList.GetSize();
1031ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int j = 0; j < count; j ++) {
1032ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pDevice->SaveState();
1033ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _PDF_RenderItem* pItem = m_ContentList.GetDataPtr(j);
1034ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pLastMatrix) {
1035ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CFX_AffineMatrix FinalMatrix = pItem->m_Matrix;
1036ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            FinalMatrix.Concat(*pLastMatrix);
1037ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_RenderStatus status;
1038ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            status.Initialize(0, this, pDevice, pLastMatrix, pStopObj, NULL, NULL, pOptions,
1039ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              pItem->m_pObjectList->m_Transparency, FALSE, NULL);
1040ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            status.RenderObjectList(pItem->m_pObjectList, &FinalMatrix);
1041ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if !defined(_FPDFAPI_MINI_)
1042ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) {
1043ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_pPageCache->CacheOptimization(status.m_Options.m_dwLimitCacheSize);
1044ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1045ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1046ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (status.m_bStopped) {
1047ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pDevice->RestoreState();
1048ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
1049ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1050ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
1051ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_RenderStatus status;
1052ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            status.Initialize(0, this, pDevice, NULL, pStopObj, NULL, NULL, pOptions,
1053ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                              pItem->m_pObjectList->m_Transparency, FALSE, NULL);
1054ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            status.RenderObjectList(pItem->m_pObjectList, &pItem->m_Matrix);
1055ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if !defined(_FPDFAPI_MINI_)
1056ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) {
1057ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_pPageCache->CacheOptimization(status.m_Options.m_dwLimitCacheSize);
1058ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1059ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1060ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (status.m_bStopped) {
1061ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pDevice->RestoreState();
1062ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                break;
1063ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1064ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1065ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pDevice->RestoreState();
1066ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1067ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1068ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_RenderContext::DrawObjectList(CFX_RenderDevice* pDevice, CPDF_PageObjects* pObjs,
1069ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                        const CFX_AffineMatrix* pObject2Device, const CPDF_RenderOptions* pOptions)
1070ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1071ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    AppendObjectList(pObjs, pObject2Device);
1072ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Render(pDevice, pOptions);
1073ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1074ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_ProgressiveRenderer::CPDF_ProgressiveRenderer()
1075ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1076ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pRenderer = NULL;
1077ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pContext = NULL;
1078ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDevice = NULL;
1079ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Status = Ready;
1080ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1081ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_ProgressiveRenderer::~CPDF_ProgressiveRenderer()
1082ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1083ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Clear();
1084ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1085ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_ProgressiveRenderer::Clear()
1086ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1087ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pRenderer) {
1088ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pRenderer;
1089ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pDevice->RestoreState();
1090ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pRenderer = NULL;
1091ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1092ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Status = Ready;
1093ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1094ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_ProgressiveRenderer::Start(CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice,
1095ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                     const CPDF_RenderOptions* pOptions, IFX_Pause* pPause, FX_BOOL bDropObjects)
1096ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1097ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Status != Ready) {
1098ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Status = Failed;
1099ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pContext = pContext;
1102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDevice = pDevice;
1103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pOptions = pOptions;
1104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_bDropObjects = bDropObjects;
1105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pContext == NULL || pDevice == NULL) {
1106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Status = Failed;
1107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Status = ToBeContinued;
1110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_ObjectPos = NULL;
1111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_LayerIndex = 0;
1112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_ObjectIndex = 0;
1113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_PrevLastPos = NULL;
1114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    Continue(pPause);
1115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef _FPDFAPI_MINI_
1117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RENDER_STEP_LIMIT 20
1118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
1119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define RENDER_STEP_LIMIT 100
1120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_ProgressiveRenderer::Continue(IFX_Pause* pPause)
1122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_Status != ToBeContinued) {
1124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD nLayers = m_pContext->m_ContentList.GetSize();
1127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (; m_LayerIndex < nLayers; m_LayerIndex ++) {
1128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _PDF_RenderItem* pItem = m_pContext->m_ContentList.GetDataPtr(m_LayerIndex);
1129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_POSITION LastPos = pItem->m_pObjectList->GetLastObjectPosition();
1130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_ObjectPos == NULL) {
1131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (LastPos == m_PrevLastPos) {
1132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (!pItem->m_pObjectList->IsParsed()) {
1133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pItem->m_pObjectList->ContinueParse(pPause);
1134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (!pItem->m_pObjectList->IsParsed()) {
1135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        return;
1136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
1137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    LastPos = pItem->m_pObjectList->GetLastObjectPosition();
1138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (LastPos == m_PrevLastPos) {
1141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (m_pRenderer) {
1142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    delete m_pRenderer;
1143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    m_pRenderer = NULL;
1144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    m_pDevice->RestoreState();
1145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    m_ObjectPos = NULL;
1146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    m_PrevLastPos = NULL;
1147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                continue;
1149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (m_PrevLastPos) {
1151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_ObjectPos = m_PrevLastPos;
1152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pItem->m_pObjectList->GetNextObject(m_ObjectPos);
1153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else {
1154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_ObjectPos = pItem->m_pObjectList->GetFirstObjectPosition();
1155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_PrevLastPos = LastPos;
1157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_pRenderer == NULL) {
1159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_ObjectPos = pItem->m_pObjectList->GetFirstObjectPosition();
1160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_ObjectIndex = 0;
1161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pRenderer = FX_NEW CPDF_RenderStatus();
1162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pRenderer->Initialize(0, m_pContext, m_pDevice, NULL, NULL, NULL, NULL,
1163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                    m_pOptions, pItem->m_pObjectList->m_Transparency, m_bDropObjects, NULL);
1164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pDevice->SaveState();
1165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_ClipRect = m_pDevice->GetClipBox();
1166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CFX_AffineMatrix device2object;
1167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            device2object.SetReverse(pItem->m_Matrix);
1168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            device2object.TransformRect(m_ClipRect);
1169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int objs_to_go = CPDF_ModuleMgr::Get()->GetRenderModule()->GetConfig()->m_RenderStepLimit;
1171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        while (m_ObjectPos) {
1172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_PageObject* pCurObj = pItem->m_pObjectList->GetObjectAt(m_ObjectPos);
1173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pCurObj && pCurObj->m_Left <= m_ClipRect.right && pCurObj->m_Right >= m_ClipRect.left &&
1174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pCurObj->m_Bottom <= m_ClipRect.top && pCurObj->m_Top >= m_ClipRect.bottom) {
1175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (m_pRenderer->ContinueSingleObject(pCurObj, &pItem->m_Matrix, pPause)) {
1176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return;
1177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if !defined(_FPDFAPI_MINI_)
1179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (pCurObj->m_Type == PDFPAGE_IMAGE && m_pRenderer->m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) {
1180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    m_pContext->GetPageCache()->CacheOptimization(m_pRenderer->m_Options.m_dwLimitCacheSize);
1181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (pCurObj->m_Type == PDFPAGE_FORM || pCurObj->m_Type == PDFPAGE_SHADING) {
1184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    objs_to_go = 0;
1185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                } else {
1186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    objs_to_go --;
1187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_ObjectIndex ++;
1190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pItem->m_pObjectList->GetNextObject(m_ObjectPos);
1191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (objs_to_go == 0) {
1192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (pPause && pPause->NeedToPauseNow()) {
1193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return;
1194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                objs_to_go = CPDF_ModuleMgr::Get()->GetRenderModule()->GetConfig()->m_RenderStepLimit;
1196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (!pItem->m_pObjectList->IsParsed()) {
1199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
1200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pRenderer;
1202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pRenderer = NULL;
1203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pDevice->RestoreState();
1204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_ObjectPos = NULL;
1205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_PrevLastPos = NULL;
1206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pPause && pPause->NeedToPauseNow()) {
1207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_LayerIndex++;
1208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return;
1209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Status = Done;
1212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovint CPDF_ProgressiveRenderer::EstimateProgress()
1214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_pContext) {
1216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
1217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_DWORD nLayers = m_pContext->m_ContentList.GetSize();
1219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int nTotal = 0, nRendered = 0;
1220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (FX_DWORD layer = 0; layer < nLayers; layer ++) {
1221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        _PDF_RenderItem* pItem = m_pContext->m_ContentList.GetDataPtr(layer);
1222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int nObjs = pItem->m_pObjectList->CountObjects();
1223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (layer == m_LayerIndex) {
1224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            nRendered += m_ObjectIndex;
1225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else if (layer < m_LayerIndex) {
1226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            nRendered += nObjs;
1227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        nTotal += nObjs;
1229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1230ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (nTotal == 0) {
1231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return 0;
1232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return 100 * nRendered / nTotal;
1234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1235ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_TransferFunc* CPDF_DocRenderData::GetTransferFunc(CPDF_Object* pObj)
1236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (pObj == NULL) {
1238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return NULL;
1239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_CountedObject<CPDF_TransferFunc*>* pTransferCounter;
1241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_TransferFuncMap.Lookup(pObj, pTransferCounter)) {
1242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_TransferFunc* pTransfer = NULL;
1243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_Function* pFuncs[3] = {NULL, NULL, NULL};
1244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BOOL bUniTransfer = TRUE;
1245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int i;
1246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_BOOL bIdentity = TRUE;
1247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (pObj->GetType() == PDFOBJ_ARRAY) {
1248ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            bUniTransfer = FALSE;
1249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_Array* pArray = (CPDF_Array*)pObj;
1250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pArray->GetCount() < 3) {
1251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return NULL;
1252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            for (FX_DWORD i = 0; i < 3; i ++) {
1254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                pFuncs[2 - i] = CPDF_Function::Load(pArray->GetElementValue(i));
1255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (pFuncs[2 - i] == NULL) {
1256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    return NULL;
1257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
1260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            pFuncs[0] = CPDF_Function::Load(pObj);
1261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pFuncs[0] == NULL) {
1262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return NULL;
1263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pTransfer = FX_NEW CPDF_TransferFunc;
1266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pTransfer->m_pPDFDoc = m_pPDFDoc;
1267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pTransferCounter = FX_NEW CPDF_CountedObject<CPDF_TransferFunc*>;
1268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pTransferCounter->m_nCount = 1;
1269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pTransferCounter->m_Obj = pTransfer;
1270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_TransferFuncMap.SetAt(pObj, pTransferCounter);
1271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        static const int kMaxOutputs = 16;
1272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT output[kMaxOutputs];
1273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FXSYS_memset32(output, 0, sizeof(output));
1274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_FLOAT input;
1275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int noutput;
1276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (int v = 0; v < 256; v ++) {
1277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            input = (FX_FLOAT)v / 255.0f;
1278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (bUniTransfer) {
1279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (pFuncs[0] && pFuncs[0]->CountOutputs() <= kMaxOutputs) {
1280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pFuncs[0]->Call(&input, 1, output, noutput);
1281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                int o = FXSYS_round(output[0] * 255);
1283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                if (o != v) {
1284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    bIdentity = FALSE;
1285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (i = 0; i < 3; i ++) {
1287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    pTransfer->m_Samples[i * 256 + v] = o;
1288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            } else
1290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                for (i = 0; i < 3; i ++) {
1291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    if (pFuncs[i] && pFuncs[i]->CountOutputs() <= kMaxOutputs) {
1292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        pFuncs[i]->Call(&input, 1, output, noutput);
1293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        int o = FXSYS_round(output[0] * 255);
1294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        if (o != v) {
1295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                            bIdentity = FALSE;
1296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        }
1297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        pTransfer->m_Samples[i * 256 + v] = o;
1298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    } else {
1299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                        pTransfer->m_Samples[i * 256 + v] = v;
1300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                    }
1301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                }
1302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        for (i = 0; i < 3; i ++)
1304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (pFuncs[i]) {
1305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                delete pFuncs[i];
1306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        pTransfer->m_bIdentity = bIdentity;
1308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pTransferCounter->m_nCount++;
1310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return pTransferCounter->m_Obj;
1311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_DocRenderData::ReleaseTransferFunc(CPDF_Object* pObj)
1313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CPDF_CountedObject<CPDF_TransferFunc*>* pTransferCounter;
1315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!m_TransferFuncMap.Lookup(pObj, pTransferCounter)) {
1316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return;
1317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    pTransferCounter->m_nCount--;
1319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1320ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_RenderConfig::CPDF_RenderConfig()
1321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_HalftoneLimit = 0;
1323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef _FPDFAPI_MINI_
1324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_RenderStepLimit = 20;
1325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
1326ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_RenderStepLimit = 100;
1327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1329ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_RenderConfig::~CPDF_RenderConfig()
1330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1332ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_DeviceBuffer::CPDF_DeviceBuffer()
1333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBitmap = NULL;
1335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDevice = NULL;
1336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pContext = NULL;
1337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pObject = NULL;
1338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1339ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_DeviceBuffer::~CPDF_DeviceBuffer()
1340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pBitmap) {
1342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pBitmap;
1343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1345ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_DeviceBuffer::Initialize(CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, FX_RECT* pRect,
1346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                      const CPDF_PageObject* pObj, int max_dpi)
1347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDevice = pDevice;
1349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pContext = pContext;
1350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Rect = *pRect;
1351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pObject = pObj;
1352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Matrix.TranslateI(-pRect->left, -pRect->top);
1353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_
1354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE);
1355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE);
1356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (horz_size && vert_size && max_dpi) {
1357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int dpih = pDevice->GetDeviceCaps(FXDC_PIXEL_WIDTH) * 254 / (horz_size * 10);
1358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int dpiv = pDevice->GetDeviceCaps(FXDC_PIXEL_HEIGHT) * 254 / (vert_size * 10);
1359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (dpih > max_dpi) {
1360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_Matrix.Scale((FX_FLOAT)(max_dpi) / dpih, 1.0f);
1361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (dpiv > max_dpi) {
1363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_Matrix.Scale(1.0f, (FX_FLOAT)(max_dpi) / (FX_FLOAT)dpiv);
1364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifdef _FPDFAPI_MINI_
1367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Matrix.Scale(0.5f, 0.5f);
1368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_Matrix ctm = m_pDevice->GetCTM();
1371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT fScaleX = FXSYS_fabs(ctm.a);
1372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_FLOAT fScaleY = FXSYS_fabs(ctm.d);
1373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Matrix.Concat(fScaleX, 0, 0, fScaleY, 0, 0);
1374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_FloatRect rect(*pRect);
1375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Matrix.TransformRect(rect);
1376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_RECT bitmap_rect = rect.GetOutterRect();
1377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBitmap = FX_NEW CFX_DIBitmap;
1378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBitmap->Create(bitmap_rect.Width(), bitmap_rect.Height(), FXDIB_Argb);
1379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
1380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_DeviceBuffer::OutputToDevice()
1382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_GET_BITS) {
1384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (m_Matrix.a == 1.0f && m_Matrix.d == 1.0f) {
1385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pDevice->SetDIBits(m_pBitmap, m_Rect.left, m_Rect.top);
1386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        } else {
1387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_pDevice->StretchDIBits(m_pBitmap, m_Rect.left, m_Rect.top, m_Rect.Width(), m_Rect.Height());
1388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    } else {
1390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if !defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_)
1391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CFX_DIBitmap buffer;
1392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pDevice->CreateCompatibleBitmap(&buffer, m_pBitmap->GetWidth(), m_pBitmap->GetHeight());
1393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pContext->GetBackground(&buffer, m_pObject, NULL, &m_Matrix);
1394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        buffer.CompositeBitmap(0, 0, buffer.GetWidth(), buffer.GetHeight(), m_pBitmap, 0, 0);
1395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pDevice->StretchDIBits(&buffer, m_Rect.left, m_Rect.top, m_Rect.Width(), m_Rect.Height());
1396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1399ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_ScaledRenderBuffer::CPDF_ScaledRenderBuffer()
1400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBitmapDevice = NULL;
1402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1403ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovCPDF_ScaledRenderBuffer::~CPDF_ScaledRenderBuffer()
1404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pBitmapDevice) {
1406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        delete m_pBitmapDevice;
1407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#ifndef _FPDFAPI_MINI_
1410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define _FPDFAPI_IMAGESIZE_LIMIT_	(30 * 1024 * 1024)
1411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
1412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define _FPDFAPI_IMAGESIZE_LIMIT_	(10 * 1024 * 1024)
1413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1414ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL CPDF_ScaledRenderBuffer::Initialize(CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, FX_RECT* pRect,
1415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        const CPDF_PageObject* pObj, const CPDF_RenderOptions *pOptions, int max_dpi)
1416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXSYS_assert(pRect != NULL);
1418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pDevice = pDevice;
1419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_GET_BITS) {
1420ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        return TRUE;
1421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pContext = pContext;
1423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Rect = *pRect;
1424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pObject = pObj;
1425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_Matrix.TranslateI(-pRect->left, -pRect->top);
1426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE);
1427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE);
1428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (horz_size && vert_size && max_dpi) {
1429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int dpih = pDevice->GetDeviceCaps(FXDC_PIXEL_WIDTH) * 254 / (horz_size * 10);
1430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        int dpiv = pDevice->GetDeviceCaps(FXDC_PIXEL_HEIGHT) * 254 / (vert_size * 10);
1431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (dpih > max_dpi) {
1432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_Matrix.Scale((FX_FLOAT)(max_dpi) / dpih, 1.0f);
1433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (dpiv > max_dpi) {
1435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            m_Matrix.Scale(1.0f, (FX_FLOAT)(max_dpi) / (FX_FLOAT)dpiv);
1436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pBitmapDevice = FX_NEW CFX_FxgeDevice;
1439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FXDIB_Format dibFormat = FXDIB_Rgb;
1440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_INT32 bpp = 24;
1441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_ALPHA_OUTPUT) {
1442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        dibFormat = FXDIB_Argb;
1443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        bpp = 32;
1444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    CFX_FloatRect rect;
1446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    FX_INT32 iWidth, iHeight, iPitch;
1447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    while (1) {
1448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        rect = *pRect;
1449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Matrix.TransformRect(rect);
1450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        FX_RECT bitmap_rect = rect.GetOutterRect();
1451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        iWidth = bitmap_rect.Width();
1452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        iHeight = bitmap_rect.Height();
1453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        iPitch = (iWidth * bpp + 31) / 32 * 4;
1454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (iWidth * iHeight < 1) {
1455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            return FALSE;
1456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (iPitch * iHeight <= _FPDFAPI_IMAGESIZE_LIMIT_ &&
1458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                m_pBitmapDevice->Create(iWidth, iHeight, dibFormat)) {
1459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            break;
1460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_Matrix.Scale(0.5f, 0.5f);
1462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if  !defined(_FPDFAPI_MINI_) || defined(_FXCORE_FEATURE_ALL_)
1464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    m_pContext->GetBackground(m_pBitmapDevice->GetBitmap(), m_pObject, pOptions, &m_Matrix);
1465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
1466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
1467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovvoid CPDF_ScaledRenderBuffer::OutputToDevice()
1469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (m_pBitmapDevice) {
1471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        m_pDevice->StretchDIBits(m_pBitmapDevice->GetBitmap(), m_Rect.left, m_Rect.top, m_Rect.Width(), m_Rect.Height());
1472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1474ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovFX_BOOL IPDF_OCContext::CheckObjectVisible(const CPDF_PageObject* pObj)
1475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov{
1476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    const CPDF_ContentMarkData* pData = pObj->m_ContentMark;
1477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int nItems = pData->CountItems();
1478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    for (int i = 0; i < nItems; i ++) {
1479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        CPDF_ContentMarkItem& item = pData->GetItem(i);
1480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        if (item.GetName() == FX_BSTRC("OC") && item.GetParamType() == CPDF_ContentMarkItem::PropertiesDict) {
1481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            CPDF_Dictionary* pOCG = (CPDF_Dictionary*)item.GetParam();
1482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            if (!CheckOCGVisible(pOCG)) {
1483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                return FALSE;
1484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov            }
1485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        }
1486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
1487ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return TRUE;
1488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
1489