diff options
author | Nico Weber <thakis@chromium.org> | 2015-08-04 12:19:10 -0700 |
---|---|---|
committer | Nico Weber <thakis@chromium.org> | 2015-08-04 12:19:10 -0700 |
commit | b048f791a15f2da781a01eba5b09eb9d389f9c11 (patch) | |
tree | 6850a73c18bbc41eaf4b1fdc6b3c96646d45587b /core/src/fpdfapi/fpdf_render | |
parent | c8eeed31f217d99a706b0cbf5e4ce0bcc12beb64 (diff) | |
download | pdfium-b048f791a15f2da781a01eba5b09eb9d389f9c11.tar.xz |
clang-format all pdfium code.
No behavior change.
Generated by:
find . -name '*.cpp' -o -name '*.h' | \
grep -E -v 'third_party|thirdparties|lpng_v163' | \
xargs ../../buildtools/mac/clang-format -i
See thread "tabs vs spaces" on pdfium@googlegroups.com for discussion.
BUG=none
R=tsepez@chromium.org
Review URL: https://codereview.chromium.org/1265503005 .
Diffstat (limited to 'core/src/fpdfapi/fpdf_render')
-rw-r--r-- | core/src/fpdfapi/fpdf_render/fpdf_render.cpp | 2622 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_render/fpdf_render_cache.cpp | 629 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_render/fpdf_render_image.cpp | 2097 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp | 2939 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_render/fpdf_render_pattern.cpp | 2197 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp | 1422 | ||||
-rw-r--r-- | core/src/fpdfapi/fpdf_render/render_int.h | 969 |
7 files changed, 6713 insertions, 6162 deletions
diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render.cpp index f8b59913e4..1132d8acea 100644 --- a/core/src/fpdfapi/fpdf_render/fpdf_render.cpp +++ b/core/src/fpdfapi/fpdf_render/fpdf_render.cpp @@ -11,1381 +11,1437 @@ #include "render_int.h" CPDF_DocRenderData::CPDF_DocRenderData(CPDF_Document* pPDFDoc) - : m_pPDFDoc(pPDFDoc), - m_pFontCache(new CFX_FontCache) -{ -} + : m_pPDFDoc(pPDFDoc), m_pFontCache(new CFX_FontCache) {} -CPDF_DocRenderData::~CPDF_DocRenderData() -{ - Clear(TRUE); +CPDF_DocRenderData::~CPDF_DocRenderData() { + Clear(TRUE); } -void CPDF_DocRenderData::Clear(FX_BOOL bRelease) -{ - for (auto it = m_Type3FaceMap.begin(); it != m_Type3FaceMap.end();) { - auto curr_it = it++; - CPDF_CountedObject<CPDF_Type3Cache>* cache = curr_it->second; - if (bRelease || cache->use_count() < 2) { - delete cache->get(); - delete cache; - m_Type3FaceMap.erase(curr_it); - } - } +void CPDF_DocRenderData::Clear(FX_BOOL bRelease) { + for (auto it = m_Type3FaceMap.begin(); it != m_Type3FaceMap.end();) { + auto curr_it = it++; + CPDF_CountedObject<CPDF_Type3Cache>* cache = curr_it->second; + if (bRelease || cache->use_count() < 2) { + delete cache->get(); + delete cache; + m_Type3FaceMap.erase(curr_it); + } + } - for (auto it = m_TransferFuncMap.begin(); it != m_TransferFuncMap.end();) { - auto curr_it = it++; - CPDF_CountedObject<CPDF_TransferFunc>* value = curr_it->second; - if (bRelease || value->use_count() < 2) { - delete value->get(); - delete value; - m_TransferFuncMap.erase(curr_it); - } - } + for (auto it = m_TransferFuncMap.begin(); it != m_TransferFuncMap.end();) { + auto curr_it = it++; + CPDF_CountedObject<CPDF_TransferFunc>* value = curr_it->second; + if (bRelease || value->use_count() < 2) { + delete value->get(); + delete value; + m_TransferFuncMap.erase(curr_it); + } + } - if (m_pFontCache) { - if (bRelease) { - delete m_pFontCache; - m_pFontCache = NULL; - } else { - m_pFontCache->FreeCache(FALSE); - } + if (m_pFontCache) { + if (bRelease) { + delete m_pFontCache; + m_pFontCache = NULL; + } else { + m_pFontCache->FreeCache(FALSE); } + } } -CPDF_Type3Cache* CPDF_DocRenderData::GetCachedType3(CPDF_Type3Font* pFont) -{ - CPDF_CountedObject<CPDF_Type3Cache>* pCache; - auto it = m_Type3FaceMap.find(pFont); - if (it == m_Type3FaceMap.end()) { - CPDF_Type3Cache* pType3 = new CPDF_Type3Cache(pFont); - pCache = new CPDF_CountedObject<CPDF_Type3Cache>(pType3); - m_Type3FaceMap[pFont] = pCache; - } else { - pCache = it->second; - } - return pCache->AddRef(); +CPDF_Type3Cache* CPDF_DocRenderData::GetCachedType3(CPDF_Type3Font* pFont) { + CPDF_CountedObject<CPDF_Type3Cache>* pCache; + auto it = m_Type3FaceMap.find(pFont); + if (it == m_Type3FaceMap.end()) { + CPDF_Type3Cache* pType3 = new CPDF_Type3Cache(pFont); + pCache = new CPDF_CountedObject<CPDF_Type3Cache>(pType3); + m_Type3FaceMap[pFont] = pCache; + } else { + pCache = it->second; + } + return pCache->AddRef(); } -void CPDF_DocRenderData::ReleaseCachedType3(CPDF_Type3Font* pFont) -{ - auto it = m_Type3FaceMap.find(pFont); - if (it != m_Type3FaceMap.end()) - it->second->RemoveRef(); +void CPDF_DocRenderData::ReleaseCachedType3(CPDF_Type3Font* pFont) { + auto it = m_Type3FaceMap.find(pFont); + if (it != m_Type3FaceMap.end()) + it->second->RemoveRef(); } -class CPDF_RenderModule : public IPDF_RenderModule -{ -public: - CPDF_RenderModule() {} +class CPDF_RenderModule : public IPDF_RenderModule { + public: + CPDF_RenderModule() {} -private: - ~CPDF_RenderModule() override {} + private: + ~CPDF_RenderModule() override {} - CPDF_DocRenderData* CreateDocData(CPDF_Document* pDoc) override; - void DestroyDocData(CPDF_DocRenderData* p) override; - void ClearDocData(CPDF_DocRenderData* p) override; + CPDF_DocRenderData* CreateDocData(CPDF_Document* pDoc) override; + void DestroyDocData(CPDF_DocRenderData* p) override; + void ClearDocData(CPDF_DocRenderData* p) override; - CPDF_DocRenderData* GetRenderData() override - { - return &m_RenderData; - } + CPDF_DocRenderData* GetRenderData() override { return &m_RenderData; } - CPDF_PageRenderCache* CreatePageCache(CPDF_Page* pPage) override - { - return new CPDF_PageRenderCache(pPage); - } + CPDF_PageRenderCache* CreatePageCache(CPDF_Page* pPage) override { + return new CPDF_PageRenderCache(pPage); + } - void DestroyPageCache(CPDF_PageRenderCache* pCache) override; + void DestroyPageCache(CPDF_PageRenderCache* pCache) override; - CPDF_RenderConfig* GetConfig() override - { - return &m_RenderConfig; - } + CPDF_RenderConfig* GetConfig() override { return &m_RenderConfig; } - CPDF_DocRenderData m_RenderData; - CPDF_RenderConfig m_RenderConfig; + CPDF_DocRenderData m_RenderData; + CPDF_RenderConfig m_RenderConfig; }; -CPDF_DocRenderData* CPDF_RenderModule::CreateDocData(CPDF_Document* pDoc) -{ - return new CPDF_DocRenderData(pDoc); +CPDF_DocRenderData* CPDF_RenderModule::CreateDocData(CPDF_Document* pDoc) { + return new CPDF_DocRenderData(pDoc); } -void CPDF_RenderModule::DestroyDocData(CPDF_DocRenderData* pDocData) -{ - delete pDocData; +void CPDF_RenderModule::DestroyDocData(CPDF_DocRenderData* pDocData) { + delete pDocData; } -void CPDF_RenderModule::ClearDocData(CPDF_DocRenderData* p) -{ - if (p) { - p->Clear(FALSE); - } +void CPDF_RenderModule::ClearDocData(CPDF_DocRenderData* p) { + if (p) { + p->Clear(FALSE); + } } -void CPDF_RenderModule::DestroyPageCache(CPDF_PageRenderCache* pCache) -{ - delete pCache; +void CPDF_RenderModule::DestroyPageCache(CPDF_PageRenderCache* pCache) { + delete pCache; } -void CPDF_ModuleMgr::InitRenderModule() -{ - m_pRenderModule.reset(new CPDF_RenderModule); +void CPDF_ModuleMgr::InitRenderModule() { + m_pRenderModule.reset(new CPDF_RenderModule); } CPDF_RenderOptions::CPDF_RenderOptions() - : m_ColorMode(RENDER_COLOR_NORMAL) - , m_Flags(RENDER_CLEARTYPE) - , m_Interpolation(0) - , m_AddFlags(0) - , m_pOCContext(NULL) - , m_dwLimitCacheSize(1024 * 1024 * 100) - , m_HalftoneLimit(-1) -{ -} -FX_ARGB CPDF_RenderOptions::TranslateColor(FX_ARGB argb) const -{ - if (m_ColorMode == RENDER_COLOR_NORMAL) { - return argb; - } - if (m_ColorMode == RENDER_COLOR_ALPHA) { - return argb; - } - int a, r, g, b; - ArgbDecode(argb, a, r, g, b); - int gray = FXRGB2GRAY(r, g, b); - if (m_ColorMode == RENDER_COLOR_TWOCOLOR) { - int color = (r - gray) * (r - gray) + (g - gray) * (g - gray) + (b - gray) * (b - gray); - if (gray < 35 && color < 20) { - return ArgbEncode(a, m_ForeColor); - } - if (gray > 221 && color < 20) { - return ArgbEncode(a, m_BackColor); - } - return argb; - } - int fr = FXSYS_GetRValue(m_ForeColor); - int fg = FXSYS_GetGValue(m_ForeColor); - int fb = FXSYS_GetBValue(m_ForeColor); - int br = FXSYS_GetRValue(m_BackColor); - int bg = FXSYS_GetGValue(m_BackColor); - int bb = FXSYS_GetBValue(m_BackColor); - r = (br - fr) * gray / 255 + fr; - g = (bg - fg) * gray / 255 + fg; - b = (bb - fb) * gray / 255 + fb; - return ArgbEncode(a, r, g, b); + : m_ColorMode(RENDER_COLOR_NORMAL), + m_Flags(RENDER_CLEARTYPE), + m_Interpolation(0), + m_AddFlags(0), + m_pOCContext(NULL), + m_dwLimitCacheSize(1024 * 1024 * 100), + m_HalftoneLimit(-1) {} +FX_ARGB CPDF_RenderOptions::TranslateColor(FX_ARGB argb) const { + if (m_ColorMode == RENDER_COLOR_NORMAL) { + return argb; + } + if (m_ColorMode == RENDER_COLOR_ALPHA) { + return argb; + } + int a, r, g, b; + ArgbDecode(argb, a, r, g, b); + int gray = FXRGB2GRAY(r, g, b); + if (m_ColorMode == RENDER_COLOR_TWOCOLOR) { + int color = (r - gray) * (r - gray) + (g - gray) * (g - gray) + + (b - gray) * (b - gray); + if (gray < 35 && color < 20) { + return ArgbEncode(a, m_ForeColor); + } + if (gray > 221 && color < 20) { + return ArgbEncode(a, m_BackColor); + } + return argb; + } + int fr = FXSYS_GetRValue(m_ForeColor); + int fg = FXSYS_GetGValue(m_ForeColor); + int fb = FXSYS_GetBValue(m_ForeColor); + int br = FXSYS_GetRValue(m_BackColor); + int bg = FXSYS_GetGValue(m_BackColor); + int bb = FXSYS_GetBValue(m_BackColor); + r = (br - fr) * gray / 255 + fr; + g = (bg - fg) * gray / 255 + fg; + b = (bb - fb) * gray / 255 + fb; + return ArgbEncode(a, r, g, b); } // static int CPDF_RenderStatus::s_CurrentRecursionDepth = 0; -CPDF_RenderStatus::CPDF_RenderStatus() -{ - m_pContext = NULL; - m_bStopped = FALSE; - m_pDevice = NULL; - m_pCurObj = NULL; - m_pStopObj = NULL; - m_HalftoneLimit = 0; - m_pObjectRenderer = NULL; - m_bPrint = FALSE; - m_Transparency = 0; - m_DitherBits = 0; - m_bDropObjects = FALSE; - m_bStdCS = FALSE; - m_GroupFamily = 0; - m_bLoadMask = FALSE; - m_pType3Char = NULL; - m_T3FillColor = 0; - m_pFormResource = NULL; - m_pPageResource = NULL; - m_curBlend = FXDIB_BLEND_NORMAL; +CPDF_RenderStatus::CPDF_RenderStatus() { + m_pContext = NULL; + m_bStopped = FALSE; + m_pDevice = NULL; + m_pCurObj = NULL; + m_pStopObj = NULL; + m_HalftoneLimit = 0; + m_pObjectRenderer = NULL; + m_bPrint = FALSE; + m_Transparency = 0; + m_DitherBits = 0; + m_bDropObjects = FALSE; + m_bStdCS = FALSE; + m_GroupFamily = 0; + m_bLoadMask = FALSE; + m_pType3Char = NULL; + m_T3FillColor = 0; + m_pFormResource = NULL; + m_pPageResource = NULL; + m_curBlend = FXDIB_BLEND_NORMAL; } -CPDF_RenderStatus::~CPDF_RenderStatus() -{ - delete m_pObjectRenderer; +CPDF_RenderStatus::~CPDF_RenderStatus() { + delete m_pObjectRenderer; } -FX_BOOL CPDF_RenderStatus::Initialize(CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, - const CFX_AffineMatrix* pDeviceMatrix, const CPDF_PageObject* pStopObj, - const CPDF_RenderStatus* pParentState, const CPDF_GraphicStates* pInitialStates, - const CPDF_RenderOptions* pOptions, int transparency, FX_BOOL bDropObjects, - CPDF_Dictionary* pFormResource, FX_BOOL bStdCS, CPDF_Type3Char* pType3Char, - FX_ARGB fill_color, FX_DWORD GroupFamily, - FX_BOOL bLoadMask) -{ - m_pContext = pContext; - m_pDevice = pDevice; - m_DitherBits = pDevice->GetDeviceCaps(FXDC_DITHER_BITS); - m_bPrint = m_pDevice->GetDeviceClass() != FXDC_DISPLAY; - if (pDeviceMatrix) { - m_DeviceMatrix = *pDeviceMatrix; - } - m_pStopObj = pStopObj; - if (pOptions) { - m_Options = *pOptions; - } - m_bDropObjects = bDropObjects; - m_bStdCS = bStdCS; - m_T3FillColor = fill_color; - m_pType3Char = pType3Char; - m_GroupFamily = GroupFamily; - m_bLoadMask = bLoadMask; - m_pFormResource = pFormResource; - m_pPageResource = m_pContext->m_pPageResources; - if (pInitialStates && !m_pType3Char) { - m_InitialStates.CopyStates(*pInitialStates); - if (pParentState) { - CPDF_ColorStateData* pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)m_InitialStates.m_ColorState; - CPDF_ColorStateData* pParentData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)pParentState->m_InitialStates.m_ColorState; - if (!pColorData || pColorData->m_FillColor.IsNull()) { - CPDF_ColorStateData* pData = m_InitialStates.m_ColorState.GetModify(); - pData->m_FillRGB = pParentData->m_FillRGB; - pData->m_FillColor.Copy(&pParentData->m_FillColor); - } - if (!pColorData || pColorData->m_StrokeColor.IsNull()) { - CPDF_ColorStateData* pData = m_InitialStates.m_ColorState.GetModify(); - pData->m_StrokeRGB = pParentData->m_FillRGB; - pData->m_StrokeColor.Copy(&pParentData->m_StrokeColor); - } - } - } else { - m_InitialStates.DefaultStates(); +FX_BOOL CPDF_RenderStatus::Initialize(CPDF_RenderContext* pContext, + CFX_RenderDevice* pDevice, + const CFX_AffineMatrix* pDeviceMatrix, + const CPDF_PageObject* pStopObj, + const CPDF_RenderStatus* pParentState, + const CPDF_GraphicStates* pInitialStates, + const CPDF_RenderOptions* pOptions, + int transparency, + FX_BOOL bDropObjects, + CPDF_Dictionary* pFormResource, + FX_BOOL bStdCS, + CPDF_Type3Char* pType3Char, + FX_ARGB fill_color, + FX_DWORD GroupFamily, + FX_BOOL bLoadMask) { + m_pContext = pContext; + m_pDevice = pDevice; + m_DitherBits = pDevice->GetDeviceCaps(FXDC_DITHER_BITS); + m_bPrint = m_pDevice->GetDeviceClass() != FXDC_DISPLAY; + if (pDeviceMatrix) { + m_DeviceMatrix = *pDeviceMatrix; + } + m_pStopObj = pStopObj; + if (pOptions) { + m_Options = *pOptions; + } + m_bDropObjects = bDropObjects; + m_bStdCS = bStdCS; + m_T3FillColor = fill_color; + m_pType3Char = pType3Char; + m_GroupFamily = GroupFamily; + m_bLoadMask = bLoadMask; + m_pFormResource = pFormResource; + m_pPageResource = m_pContext->m_pPageResources; + if (pInitialStates && !m_pType3Char) { + m_InitialStates.CopyStates(*pInitialStates); + if (pParentState) { + CPDF_ColorStateData* pColorData = + (CPDF_ColorStateData*)(const CPDF_ColorStateData*) + m_InitialStates.m_ColorState; + CPDF_ColorStateData* pParentData = + (CPDF_ColorStateData*)(const CPDF_ColorStateData*) + pParentState->m_InitialStates.m_ColorState; + if (!pColorData || pColorData->m_FillColor.IsNull()) { + CPDF_ColorStateData* pData = m_InitialStates.m_ColorState.GetModify(); + pData->m_FillRGB = pParentData->m_FillRGB; + pData->m_FillColor.Copy(&pParentData->m_FillColor); + } + if (!pColorData || pColorData->m_StrokeColor.IsNull()) { + CPDF_ColorStateData* pData = m_InitialStates.m_ColorState.GetModify(); + pData->m_StrokeRGB = pParentData->m_FillRGB; + pData->m_StrokeColor.Copy(&pParentData->m_StrokeColor); + } + } + } else { + m_InitialStates.DefaultStates(); + } + m_pObjectRenderer = NULL; + m_Transparency = transparency; + return TRUE; +} +void CPDF_RenderStatus::RenderObjectList(const CPDF_PageObjects* pObjs, + const CFX_AffineMatrix* pObj2Device) { + CFX_FloatRect clip_rect = m_pDevice->GetClipBox(); + CFX_AffineMatrix device2object; + device2object.SetReverse(*pObj2Device); + device2object.TransformRect(clip_rect); + int index = 0; + FX_POSITION pos = pObjs->GetFirstObjectPosition(); + while (pos) { + index++; + CPDF_PageObject* pCurObj = pObjs->GetNextObject(pos); + if (pCurObj == m_pStopObj) { + m_bStopped = TRUE; + return; + } + if (!pCurObj) { + continue; + } + if (pCurObj == NULL || pCurObj->m_Left > clip_rect.right || + pCurObj->m_Right < clip_rect.left || + pCurObj->m_Bottom > clip_rect.top || + pCurObj->m_Top < clip_rect.bottom) { + continue; + } + RenderSingleObject(pCurObj, pObj2Device); + if (m_bStopped) { + return; + } + } +} +void CPDF_RenderStatus::RenderSingleObject( + const CPDF_PageObject* pObj, + const CFX_AffineMatrix* pObj2Device) { + CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth); + if (++s_CurrentRecursionDepth > kRenderMaxRecursionDepth) { + return; + } + m_pCurObj = pObj; + if (m_Options.m_pOCContext && pObj->m_ContentMark.NotNull()) { + if (!m_Options.m_pOCContext->CheckObjectVisible(pObj)) { + return; + } + } + ProcessClipPath(pObj->m_ClipPath, pObj2Device); + if (ProcessTransparency(pObj, pObj2Device)) { + return; + } + ProcessObjectNoClip(pObj, pObj2Device); +} +FX_BOOL CPDF_RenderStatus::ContinueSingleObject( + const CPDF_PageObject* pObj, + const CFX_AffineMatrix* pObj2Device, + IFX_Pause* pPause) { + if (m_pObjectRenderer) { + if (m_pObjectRenderer->Continue(pPause)) { + return TRUE; + } + if (!m_pObjectRenderer->m_Result) { + DrawObjWithBackground(pObj, pObj2Device); } + delete m_pObjectRenderer; m_pObjectRenderer = NULL; - m_Transparency = transparency; - return TRUE; -} -void CPDF_RenderStatus::RenderObjectList(const CPDF_PageObjects* pObjs, const CFX_AffineMatrix* pObj2Device) -{ - CFX_FloatRect clip_rect = m_pDevice->GetClipBox(); - CFX_AffineMatrix device2object; - device2object.SetReverse(*pObj2Device); - device2object.TransformRect(clip_rect); - int index = 0; - FX_POSITION pos = pObjs->GetFirstObjectPosition(); - while(pos) { - index ++; - CPDF_PageObject* pCurObj = pObjs->GetNextObject(pos); - if (pCurObj == m_pStopObj) { - m_bStopped = TRUE; - return; - } - if (!pCurObj) { - continue; - } - if(pCurObj == NULL || pCurObj->m_Left > clip_rect.right || pCurObj->m_Right < clip_rect.left || - pCurObj->m_Bottom > clip_rect.top || pCurObj->m_Top < clip_rect.bottom) { - continue; - } - RenderSingleObject(pCurObj, pObj2Device); - if (m_bStopped) { - return; - } - } -} -void CPDF_RenderStatus::RenderSingleObject(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device) -{ - CFX_AutoRestorer<int> restorer(&s_CurrentRecursionDepth); - if (++s_CurrentRecursionDepth > kRenderMaxRecursionDepth) { - return; - } - m_pCurObj = pObj; - if (m_Options.m_pOCContext && pObj->m_ContentMark.NotNull()) { - if (!m_Options.m_pOCContext->CheckObjectVisible(pObj)) { - return; - } - } - ProcessClipPath(pObj->m_ClipPath, pObj2Device); - if (ProcessTransparency(pObj, pObj2Device)) { - return; - } - ProcessObjectNoClip(pObj, pObj2Device); -} -FX_BOOL CPDF_RenderStatus::ContinueSingleObject(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, IFX_Pause* pPause) -{ - if (m_pObjectRenderer) { - if (m_pObjectRenderer->Continue(pPause)) { - return TRUE; - } - if (!m_pObjectRenderer->m_Result) { - DrawObjWithBackground(pObj, pObj2Device); - } - delete m_pObjectRenderer; - m_pObjectRenderer = NULL; - return FALSE; - } - m_pCurObj = pObj; - if (m_Options.m_pOCContext && pObj->m_ContentMark.NotNull()) - if (!m_Options.m_pOCContext->CheckObjectVisible(pObj)) { - return FALSE; - } - ProcessClipPath(pObj->m_ClipPath, pObj2Device); - if (ProcessTransparency(pObj, pObj2Device)) { - return FALSE; - } - if (pObj->m_Type == PDFPAGE_IMAGE) { - m_pObjectRenderer = IPDF_ObjectRenderer::Create(pObj->m_Type); - if (!m_pObjectRenderer->Start(this, pObj, pObj2Device, FALSE)) { - if (!m_pObjectRenderer->m_Result) { - DrawObjWithBackground(pObj, pObj2Device); - } - delete m_pObjectRenderer; - m_pObjectRenderer = NULL; - return FALSE; - } - return ContinueSingleObject(pObj, pObj2Device, pPause); - } - ProcessObjectNoClip(pObj, pObj2Device); return FALSE; -} -IPDF_ObjectRenderer* IPDF_ObjectRenderer::Create(int type) -{ - if (type != PDFPAGE_IMAGE) { - return NULL; - } - return new CPDF_ImageRenderer; -} -FX_BOOL CPDF_RenderStatus::GetObjectClippedRect(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bLogical, FX_RECT &rect) const -{ - rect = pObj->GetBBox(pObj2Device); - FX_RECT rtClip = m_pDevice->GetClipBox(); - if (!bLogical) { - CFX_Matrix dCTM = m_pDevice->GetCTM(); - FX_FLOAT a = FXSYS_fabs(dCTM.a); - FX_FLOAT d = FXSYS_fabs(dCTM.d); - if (a != 1.0f || d != 1.0f) { - rect.right = rect.left + (int32_t)FXSYS_ceil((FX_FLOAT)rect.Width() * a); - rect.bottom = rect.top + (int32_t)FXSYS_ceil((FX_FLOAT)rect.Height() * d); - rtClip.right = rtClip.left + (int32_t)FXSYS_ceil((FX_FLOAT)rtClip.Width() * a); - rtClip.bottom = rtClip.top + (int32_t)FXSYS_ceil((FX_FLOAT)rtClip.Height() * d); - } - } - rect.Intersect(rtClip); - return rect.IsEmpty(); -} -void CPDF_RenderStatus::DitherObjectArea(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device) -{ - CFX_DIBitmap* pBitmap = m_pDevice->GetBitmap(); - if (pBitmap == NULL) { - return; - } - FX_RECT rect; - if (GetObjectClippedRect(pObj, pObj2Device, FALSE, rect)) { - return; - } - if (m_DitherBits == 2) { - static FX_ARGB pal[4] = {0, 85, 170, 255}; - pBitmap->DitherFS(pal, 4, &rect); - } else if (m_DitherBits == 3) { - static FX_ARGB pal[8] = {0, 36, 73, 109, 146, 182, 219, 255}; - pBitmap->DitherFS(pal, 8, &rect); - } else if (m_DitherBits == 4) { - static FX_ARGB pal[16] = {0, 17, 34, 51, 68, 85, 102, 119, 136, 153, 170, 187, 204, 221, 238, 255}; - pBitmap->DitherFS(pal, 16, &rect); - } -} -void CPDF_RenderStatus::ProcessObjectNoClip(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device) -{ - FX_BOOL bRet = FALSE; - switch (pObj->m_Type) { - case PDFPAGE_TEXT: - bRet = ProcessText((CPDF_TextObject*)pObj, pObj2Device, NULL); - break; - case PDFPAGE_PATH: - bRet = ProcessPath((CPDF_PathObject*)pObj, pObj2Device); - break; - case PDFPAGE_IMAGE: - bRet = ProcessImage((CPDF_ImageObject*)pObj, pObj2Device); - break; - case PDFPAGE_SHADING: - bRet = ProcessShading((CPDF_ShadingObject*)pObj, pObj2Device); - break; - case PDFPAGE_FORM: - bRet = ProcessForm((CPDF_FormObject*)pObj, pObj2Device); - break; - } - if (!bRet) { + } + m_pCurObj = pObj; + if (m_Options.m_pOCContext && pObj->m_ContentMark.NotNull()) + if (!m_Options.m_pOCContext->CheckObjectVisible(pObj)) { + return FALSE; + } + ProcessClipPath(pObj->m_ClipPath, pObj2Device); + if (ProcessTransparency(pObj, pObj2Device)) { + return FALSE; + } + if (pObj->m_Type == PDFPAGE_IMAGE) { + m_pObjectRenderer = IPDF_ObjectRenderer::Create(pObj->m_Type); + if (!m_pObjectRenderer->Start(this, pObj, pObj2Device, FALSE)) { + if (!m_pObjectRenderer->m_Result) { DrawObjWithBackground(pObj, pObj2Device); - } -} -FX_BOOL CPDF_RenderStatus::DrawObjWithBlend(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device) -{ - FX_BOOL bRet = FALSE; - switch (pObj->m_Type) { - case PDFPAGE_PATH: - bRet = ProcessPath((CPDF_PathObject*)pObj, pObj2Device); - break; - case PDFPAGE_IMAGE: - bRet = ProcessImage((CPDF_ImageObject *)pObj, pObj2Device); - break; - case PDFPAGE_FORM: - bRet = ProcessForm((CPDF_FormObject*)pObj, pObj2Device); - break; - } - return bRet; -} -void CPDF_RenderStatus::GetScaledMatrix(CFX_Matrix &matrix) const -{ + } + delete m_pObjectRenderer; + m_pObjectRenderer = NULL; + return FALSE; + } + return ContinueSingleObject(pObj, pObj2Device, pPause); + } + ProcessObjectNoClip(pObj, pObj2Device); + return FALSE; +} +IPDF_ObjectRenderer* IPDF_ObjectRenderer::Create(int type) { + if (type != PDFPAGE_IMAGE) { + return NULL; + } + return new CPDF_ImageRenderer; +} +FX_BOOL CPDF_RenderStatus::GetObjectClippedRect( + const CPDF_PageObject* pObj, + const CFX_AffineMatrix* pObj2Device, + FX_BOOL bLogical, + FX_RECT& rect) const { + rect = pObj->GetBBox(pObj2Device); + FX_RECT rtClip = m_pDevice->GetClipBox(); + if (!bLogical) { CFX_Matrix dCTM = m_pDevice->GetCTM(); - matrix.a *= FXSYS_fabs(dCTM.a); - matrix.d *= FXSYS_fabs(dCTM.d); -} -void CPDF_RenderStatus::DrawObjWithBackground(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device) -{ - FX_RECT rect; - if (GetObjectClippedRect(pObj, pObj2Device, FALSE, rect)) { - return; - } - int res = 300; - if (pObj->m_Type == PDFPAGE_IMAGE && m_pDevice->GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER) { - res = 0; - } - CPDF_ScaledRenderBuffer buffer; - if (!buffer.Initialize(m_pContext, m_pDevice, &rect, pObj, &m_Options, res)) { - return; - } - CFX_AffineMatrix matrix = *pObj2Device; - matrix.Concat(*buffer.GetMatrix()); - GetScaledMatrix(matrix); - CPDF_Dictionary* pFormResource = NULL; - if (pObj->m_Type == PDFPAGE_FORM) { - CPDF_FormObject* pFormObj = (CPDF_FormObject*)pObj; - if (pFormObj->m_pForm && pFormObj->m_pForm->m_pFormDict) { - pFormResource = pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources")); - } - } - CPDF_RenderStatus status; - status.Initialize(m_pContext, buffer.GetDevice(), buffer.GetMatrix(), NULL, NULL, NULL, &m_Options, m_Transparency, m_bDropObjects, pFormResource); - status.RenderSingleObject(pObj, &matrix); - buffer.OutputToDevice(); -} -FX_BOOL CPDF_RenderStatus::ProcessForm(CPDF_FormObject* pFormObj, const CFX_AffineMatrix* pObj2Device) -{ - CPDF_Dictionary* pOC = pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("OC")); - if (pOC && m_Options.m_pOCContext && !m_Options.m_pOCContext->CheckOCGVisible(pOC)) { - return TRUE; - } - CFX_AffineMatrix matrix = pFormObj->m_FormMatrix; - matrix.Concat(*pObj2Device); - CPDF_Dictionary* pResources = NULL; + FX_FLOAT a = FXSYS_fabs(dCTM.a); + FX_FLOAT d = FXSYS_fabs(dCTM.d); + if (a != 1.0f || d != 1.0f) { + rect.right = rect.left + (int32_t)FXSYS_ceil((FX_FLOAT)rect.Width() * a); + rect.bottom = rect.top + (int32_t)FXSYS_ceil((FX_FLOAT)rect.Height() * d); + rtClip.right = + rtClip.left + (int32_t)FXSYS_ceil((FX_FLOAT)rtClip.Width() * a); + rtClip.bottom = + rtClip.top + (int32_t)FXSYS_ceil((FX_FLOAT)rtClip.Height() * d); + } + } + rect.Intersect(rtClip); + return rect.IsEmpty(); +} +void CPDF_RenderStatus::DitherObjectArea(const CPDF_PageObject* pObj, + const CFX_AffineMatrix* pObj2Device) { + CFX_DIBitmap* pBitmap = m_pDevice->GetBitmap(); + if (pBitmap == NULL) { + return; + } + FX_RECT rect; + if (GetObjectClippedRect(pObj, pObj2Device, FALSE, rect)) { + return; + } + if (m_DitherBits == 2) { + static FX_ARGB pal[4] = {0, 85, 170, 255}; + pBitmap->DitherFS(pal, 4, &rect); + } else if (m_DitherBits == 3) { + static FX_ARGB pal[8] = {0, 36, 73, 109, 146, 182, 219, 255}; + pBitmap->DitherFS(pal, 8, &rect); + } else if (m_DitherBits == 4) { + static FX_ARGB pal[16] = {0, 17, 34, 51, 68, 85, 102, 119, + 136, 153, 170, 187, 204, 221, 238, 255}; + pBitmap->DitherFS(pal, 16, &rect); + } +} +void CPDF_RenderStatus::ProcessObjectNoClip( + const CPDF_PageObject* pObj, + const CFX_AffineMatrix* pObj2Device) { + FX_BOOL bRet = FALSE; + switch (pObj->m_Type) { + case PDFPAGE_TEXT: + bRet = ProcessText((CPDF_TextObject*)pObj, pObj2Device, NULL); + break; + case PDFPAGE_PATH: + bRet = ProcessPath((CPDF_PathObject*)pObj, pObj2Device); + break; + case PDFPAGE_IMAGE: + bRet = ProcessImage((CPDF_ImageObject*)pObj, pObj2Device); + break; + case PDFPAGE_SHADING: + bRet = ProcessShading((CPDF_ShadingObject*)pObj, pObj2Device); + break; + case PDFPAGE_FORM: + bRet = ProcessForm((CPDF_FormObject*)pObj, pObj2Device); + break; + } + if (!bRet) { + DrawObjWithBackground(pObj, pObj2Device); + } +} +FX_BOOL CPDF_RenderStatus::DrawObjWithBlend( + const CPDF_PageObject* pObj, + const CFX_AffineMatrix* pObj2Device) { + FX_BOOL bRet = FALSE; + switch (pObj->m_Type) { + case PDFPAGE_PATH: + bRet = ProcessPath((CPDF_PathObject*)pObj, pObj2Device); + break; + case PDFPAGE_IMAGE: + bRet = ProcessImage((CPDF_ImageObject*)pObj, pObj2Device); + break; + case PDFPAGE_FORM: + bRet = ProcessForm((CPDF_FormObject*)pObj, pObj2Device); + break; + } + return bRet; +} +void CPDF_RenderStatus::GetScaledMatrix(CFX_Matrix& matrix) const { + CFX_Matrix dCTM = m_pDevice->GetCTM(); + matrix.a *= FXSYS_fabs(dCTM.a); + matrix.d *= FXSYS_fabs(dCTM.d); +} +void CPDF_RenderStatus::DrawObjWithBackground( + const CPDF_PageObject* pObj, + const CFX_AffineMatrix* pObj2Device) { + FX_RECT rect; + if (GetObjectClippedRect(pObj, pObj2Device, FALSE, rect)) { + return; + } + int res = 300; + if (pObj->m_Type == PDFPAGE_IMAGE && + m_pDevice->GetDeviceCaps(FXDC_DEVICE_CLASS) == FXDC_PRINTER) { + res = 0; + } + CPDF_ScaledRenderBuffer buffer; + if (!buffer.Initialize(m_pContext, m_pDevice, &rect, pObj, &m_Options, res)) { + return; + } + CFX_AffineMatrix matrix = *pObj2Device; + matrix.Concat(*buffer.GetMatrix()); + GetScaledMatrix(matrix); + CPDF_Dictionary* pFormResource = NULL; + if (pObj->m_Type == PDFPAGE_FORM) { + CPDF_FormObject* pFormObj = (CPDF_FormObject*)pObj; if (pFormObj->m_pForm && pFormObj->m_pForm->m_pFormDict) { - pResources = pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources")); - } - CPDF_RenderStatus status; - status.Initialize(m_pContext, m_pDevice, NULL, m_pStopObj, - this, pFormObj, &m_Options, m_Transparency, m_bDropObjects, pResources, FALSE); - status.m_curBlend = m_curBlend; - m_pDevice->SaveState(); - status.RenderObjectList(pFormObj->m_pForm, &matrix); - m_bStopped = status.m_bStopped; - m_pDevice->RestoreState(); + pFormResource = + pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources")); + } + } + CPDF_RenderStatus status; + status.Initialize(m_pContext, buffer.GetDevice(), buffer.GetMatrix(), NULL, + NULL, NULL, &m_Options, m_Transparency, m_bDropObjects, + pFormResource); + status.RenderSingleObject(pObj, &matrix); + buffer.OutputToDevice(); +} +FX_BOOL CPDF_RenderStatus::ProcessForm(CPDF_FormObject* pFormObj, + const CFX_AffineMatrix* pObj2Device) { + CPDF_Dictionary* pOC = + pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("OC")); + if (pOC && m_Options.m_pOCContext && + !m_Options.m_pOCContext->CheckOCGVisible(pOC)) { return TRUE; -} -FX_BOOL IsAvailableMatrix(const CFX_AffineMatrix& matrix) -{ - if (matrix.a == 0 || matrix.d == 0) { - return matrix.b != 0 && matrix.c != 0; - } - if (matrix.b == 0 || matrix.c == 0) { - return matrix.a != 0 && matrix.d != 0; - } + } + CFX_AffineMatrix matrix = pFormObj->m_FormMatrix; + matrix.Concat(*pObj2Device); + CPDF_Dictionary* pResources = NULL; + if (pFormObj->m_pForm && pFormObj->m_pForm->m_pFormDict) { + pResources = pFormObj->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources")); + } + CPDF_RenderStatus status; + status.Initialize(m_pContext, m_pDevice, NULL, m_pStopObj, this, pFormObj, + &m_Options, m_Transparency, m_bDropObjects, pResources, + FALSE); + status.m_curBlend = m_curBlend; + m_pDevice->SaveState(); + status.RenderObjectList(pFormObj->m_pForm, &matrix); + m_bStopped = status.m_bStopped; + m_pDevice->RestoreState(); + return TRUE; +} +FX_BOOL IsAvailableMatrix(const CFX_AffineMatrix& matrix) { + if (matrix.a == 0 || matrix.d == 0) { + return matrix.b != 0 && matrix.c != 0; + } + if (matrix.b == 0 || matrix.c == 0) { + return matrix.a != 0 && matrix.d != 0; + } + return TRUE; +} +FX_BOOL CPDF_RenderStatus::ProcessPath(CPDF_PathObject* pPathObj, + const CFX_AffineMatrix* pObj2Device) { + int FillType = pPathObj->m_FillType; + FX_BOOL bStroke = pPathObj->m_bStroke; + ProcessPathPattern(pPathObj, pObj2Device, FillType, bStroke); + if (FillType == 0 && !bStroke) { return TRUE; -} -FX_BOOL CPDF_RenderStatus::ProcessPath(CPDF_PathObject* pPathObj, const CFX_AffineMatrix* pObj2Device) -{ - int FillType = pPathObj->m_FillType; - FX_BOOL bStroke = pPathObj->m_bStroke; - ProcessPathPattern(pPathObj, pObj2Device, FillType, bStroke); - if (FillType == 0 && !bStroke) { - return TRUE; - } - FX_DWORD fill_argb = 0; - if (FillType) { - fill_argb = GetFillArgb(pPathObj); - } - FX_DWORD stroke_argb = 0; - if (bStroke) { - stroke_argb = GetStrokeArgb(pPathObj); - } - CFX_AffineMatrix path_matrix = pPathObj->m_Matrix; - path_matrix.Concat(*pObj2Device); - if (!IsAvailableMatrix(path_matrix)) { - return TRUE; - } - if (FillType && (m_Options.m_Flags & RENDER_RECT_AA)) { - FillType |= FXFILL_RECT_AA; - } - if (m_Options.m_Flags & RENDER_FILL_FULLCOVER) { - FillType |= FXFILL_FULLCOVER; - } - if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) { - FillType |= FXFILL_NOPATHSMOOTH; - } - if (bStroke) { - FillType |= FX_FILL_STROKE; - } - const CPDF_GeneralStateData* pGeneralData = ((CPDF_PageObject*)pPathObj)->m_GeneralState; - if (pGeneralData && pGeneralData->m_StrokeAdjust) { - FillType |= FX_STROKE_ADJUST; - } - if (m_pType3Char) { - FillType |= FX_FILL_TEXT_MODE; - } - CFX_GraphStateData graphState(*pPathObj->m_GraphState); - if (m_Options.m_Flags & RENDER_THINLINE) { - graphState.m_LineWidth = 0; - } - return m_pDevice->DrawPath(pPathObj->m_Path, &path_matrix, &graphState, fill_argb, stroke_argb, FillType, 0, NULL, m_curBlend); -} -CPDF_TransferFunc* CPDF_RenderStatus::GetTransferFunc(CPDF_Object* pObj) const -{ - ASSERT(pObj != NULL); - CPDF_DocRenderData* pDocCache = m_pContext->m_pDocument->GetRenderData(); - if (!pDocCache) { - return NULL; - } - return pDocCache->GetTransferFunc(pObj); -} -FX_ARGB CPDF_RenderStatus::GetFillArgb(const CPDF_PageObject* pObj, FX_BOOL bType3) const -{ - CPDF_ColorStateData* pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)pObj->m_ColorState; - if (m_pType3Char && !bType3 && (!m_pType3Char->m_bColored || (m_pType3Char->m_bColored && (!pColorData || pColorData->m_FillColor.IsNull())))) { - return m_T3FillColor; - } - if (!pColorData || pColorData->m_FillColor.IsNull()) { - pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)m_InitialStates.m_ColorState; - } - FX_COLORREF rgb = pColorData->m_FillRGB; - if (rgb == (FX_DWORD) - 1) { - return 0; + } + FX_DWORD fill_argb = 0; + if (FillType) { + fill_argb = GetFillArgb(pPathObj); + } + FX_DWORD stroke_argb = 0; + if (bStroke) { + stroke_argb = GetStrokeArgb(pPathObj); + } + CFX_AffineMatrix path_matrix = pPathObj->m_Matrix; + path_matrix.Concat(*pObj2Device); + if (!IsAvailableMatrix(path_matrix)) { + return TRUE; + } + if (FillType && (m_Options.m_Flags & RENDER_RECT_AA)) { + FillType |= FXFILL_RECT_AA; + } + if (m_Options.m_Flags & RENDER_FILL_FULLCOVER) { + FillType |= FXFILL_FULLCOVER; + } + if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) { + FillType |= FXFILL_NOPATHSMOOTH; + } + if (bStroke) { + FillType |= FX_FILL_STROKE; + } + const CPDF_GeneralStateData* pGeneralData = + ((CPDF_PageObject*)pPathObj)->m_GeneralState; + if (pGeneralData && pGeneralData->m_StrokeAdjust) { + FillType |= FX_STROKE_ADJUST; + } + if (m_pType3Char) { + FillType |= FX_FILL_TEXT_MODE; + } + CFX_GraphStateData graphState(*pPathObj->m_GraphState); + if (m_Options.m_Flags & RENDER_THINLINE) { + graphState.m_LineWidth = 0; + } + return m_pDevice->DrawPath(pPathObj->m_Path, &path_matrix, &graphState, + fill_argb, stroke_argb, FillType, 0, NULL, + m_curBlend); +} +CPDF_TransferFunc* CPDF_RenderStatus::GetTransferFunc(CPDF_Object* pObj) const { + ASSERT(pObj != NULL); + CPDF_DocRenderData* pDocCache = m_pContext->m_pDocument->GetRenderData(); + if (!pDocCache) { + return NULL; + } + return pDocCache->GetTransferFunc(pObj); +} +FX_ARGB CPDF_RenderStatus::GetFillArgb(const CPDF_PageObject* pObj, + FX_BOOL bType3) const { + CPDF_ColorStateData* pColorData = + (CPDF_ColorStateData*)(const CPDF_ColorStateData*)pObj->m_ColorState; + if (m_pType3Char && !bType3 && + (!m_pType3Char->m_bColored || + (m_pType3Char->m_bColored && + (!pColorData || pColorData->m_FillColor.IsNull())))) { + return m_T3FillColor; + } + if (!pColorData || pColorData->m_FillColor.IsNull()) { + pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*) + m_InitialStates.m_ColorState; + } + FX_COLORREF rgb = pColorData->m_FillRGB; + if (rgb == (FX_DWORD)-1) { + return 0; + } + const CPDF_GeneralStateData* pGeneralData = pObj->m_GeneralState; + int alpha; + if (pGeneralData) { + alpha = (int32_t)(pGeneralData->m_FillAlpha * 255); + if (pGeneralData->m_pTR) { + if (!pGeneralData->m_pTransferFunc) { + ((CPDF_GeneralStateData*)pGeneralData)->m_pTransferFunc = + GetTransferFunc(pGeneralData->m_pTR); + } + if (pGeneralData->m_pTransferFunc) { + rgb = pGeneralData->m_pTransferFunc->TranslateColor(rgb); + } + } + } else { + alpha = 255; + } + return m_Options.TranslateColor(ArgbEncode(alpha, rgb)); +} +FX_ARGB CPDF_RenderStatus::GetStrokeArgb(const CPDF_PageObject* pObj) const { + CPDF_ColorStateData* pColorData = + (CPDF_ColorStateData*)(const CPDF_ColorStateData*)pObj->m_ColorState; + if (m_pType3Char && (!m_pType3Char->m_bColored || + (m_pType3Char->m_bColored && + (!pColorData || pColorData->m_StrokeColor.IsNull())))) { + return m_T3FillColor; + } + if (!pColorData || pColorData->m_StrokeColor.IsNull()) { + pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*) + m_InitialStates.m_ColorState; + } + FX_COLORREF rgb = pColorData->m_StrokeRGB; + if (rgb == (FX_DWORD)-1) { + return 0; + } + const CPDF_GeneralStateData* pGeneralData = pObj->m_GeneralState; + int alpha; + if (pGeneralData) { + alpha = (int32_t)(pGeneralData->m_StrokeAlpha * 255); + if (pGeneralData->m_pTR) { + if (!pGeneralData->m_pTransferFunc) { + ((CPDF_GeneralStateData*)pGeneralData)->m_pTransferFunc = + GetTransferFunc(pGeneralData->m_pTR); + } + if (pGeneralData->m_pTransferFunc) { + rgb = pGeneralData->m_pTransferFunc->TranslateColor(rgb); + } + } + } else { + alpha = 255; + } + return m_Options.TranslateColor(ArgbEncode(alpha, rgb)); +} +void CPDF_RenderStatus::ProcessClipPath(CPDF_ClipPath ClipPath, + const CFX_AffineMatrix* pObj2Device) { + if (ClipPath.IsNull()) { + if (m_LastClipPath.IsNull()) { + return; } - const CPDF_GeneralStateData* pGeneralData = pObj->m_GeneralState; - int alpha; - if (pGeneralData) { - alpha = (int32_t)(pGeneralData->m_FillAlpha * 255); - if (pGeneralData->m_pTR) { - if (!pGeneralData->m_pTransferFunc) { - ((CPDF_GeneralStateData*)pGeneralData)->m_pTransferFunc = GetTransferFunc(pGeneralData->m_pTR); - } - if (pGeneralData->m_pTransferFunc) { - rgb = pGeneralData->m_pTransferFunc->TranslateColor(rgb); - } - } + m_pDevice->RestoreState(TRUE); + m_LastClipPath.SetNull(); + return; + } + if (m_LastClipPath == ClipPath) { + return; + } + m_LastClipPath = ClipPath; + m_pDevice->RestoreState(TRUE); + int nClipPath = ClipPath.GetPathCount(); + int i; + for (i = 0; i < nClipPath; i++) { + const CFX_PathData* pPathData = ClipPath.GetPath(i); + if (pPathData == NULL) { + continue; + } + if (pPathData->GetPointCount() == 0) { + CFX_PathData EmptyPath; + EmptyPath.AppendRect(-1, -1, 0, 0); + int fill_mode = FXFILL_WINDING; + m_pDevice->SetClip_PathFill(&EmptyPath, NULL, fill_mode); } else { - alpha = 255; - } - return m_Options.TranslateColor(ArgbEncode(alpha, rgb)); -} -FX_ARGB CPDF_RenderStatus::GetStrokeArgb(const CPDF_PageObject* pObj) const -{ - CPDF_ColorStateData* pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)pObj->m_ColorState; - if (m_pType3Char && (!m_pType3Char->m_bColored || (m_pType3Char->m_bColored && (!pColorData || pColorData->m_StrokeColor.IsNull())))) { - return m_T3FillColor; - } - if (!pColorData || pColorData->m_StrokeColor.IsNull()) { - pColorData = (CPDF_ColorStateData*)(const CPDF_ColorStateData*)m_InitialStates.m_ColorState; - } - FX_COLORREF rgb = pColorData->m_StrokeRGB; - if (rgb == (FX_DWORD) - 1) { - return 0; - } - const CPDF_GeneralStateData* pGeneralData = pObj->m_GeneralState; - int alpha; - if (pGeneralData) { - alpha = (int32_t)(pGeneralData->m_StrokeAlpha * 255); - if (pGeneralData->m_pTR) { - if (!pGeneralData->m_pTransferFunc) { - ((CPDF_GeneralStateData*)pGeneralData)->m_pTransferFunc = GetTransferFunc(pGeneralData->m_pTR); - } - if (pGeneralData->m_pTransferFunc) { - rgb = pGeneralData->m_pTransferFunc->TranslateColor(rgb); - } + int ClipType = ClipPath.GetClipType(i); + m_pDevice->SetClip_PathFill(pPathData, pObj2Device, ClipType); + } + } + int textcount = ClipPath.GetTextCount(); + if (textcount == 0) { + return; + } + if (m_pDevice->GetDeviceClass() == FXDC_DISPLAY && + !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)) { + return; + } + CFX_PathData* pTextClippingPath = NULL; + for (i = 0; i < textcount; i++) { + CPDF_TextObject* pText = ClipPath.GetText(i); + if (pText == NULL) { + if (pTextClippingPath) { + int fill_mode = FXFILL_WINDING; + if (m_Options.m_Flags & RENDER_NOTEXTSMOOTH) { + fill_mode |= FXFILL_NOPATHSMOOTH; } + m_pDevice->SetClip_PathFill(pTextClippingPath, NULL, fill_mode); + delete pTextClippingPath; + pTextClippingPath = NULL; + } } else { - alpha = 255; - } - return m_Options.TranslateColor(ArgbEncode(alpha, rgb)); -} -void CPDF_RenderStatus::ProcessClipPath(CPDF_ClipPath ClipPath, const CFX_AffineMatrix* pObj2Device) -{ - if (ClipPath.IsNull()) { - if (m_LastClipPath.IsNull()) { - return; - } - m_pDevice->RestoreState(TRUE); - m_LastClipPath.SetNull(); - return; - } - if (m_LastClipPath == ClipPath) { - return; - } - m_LastClipPath = ClipPath; - m_pDevice->RestoreState(TRUE); - int nClipPath = ClipPath.GetPathCount(); - int i; - for (i = 0; i < nClipPath; i++) { - const CFX_PathData* pPathData = ClipPath.GetPath(i); - if (pPathData == NULL) { - continue; - } - if (pPathData->GetPointCount() == 0) { - CFX_PathData EmptyPath; - EmptyPath.AppendRect(-1, -1, 0, 0); - int fill_mode = FXFILL_WINDING; - m_pDevice->SetClip_PathFill(&EmptyPath, NULL, fill_mode); - } else { - int ClipType = ClipPath.GetClipType(i); - m_pDevice->SetClip_PathFill(pPathData, pObj2Device, ClipType); - } - } - int textcount = ClipPath.GetTextCount(); - if (textcount == 0) { - return; - } - if (m_pDevice->GetDeviceClass() == FXDC_DISPLAY && !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)) { - return; - } - CFX_PathData* pTextClippingPath = NULL; - for (i = 0; i < textcount; i ++) { - CPDF_TextObject* pText = ClipPath.GetText(i); - if (pText == NULL) { - if (pTextClippingPath) { - int fill_mode = FXFILL_WINDING; - if (m_Options.m_Flags & RENDER_NOTEXTSMOOTH) { - fill_mode |= FXFILL_NOPATHSMOOTH; - } - m_pDevice->SetClip_PathFill(pTextClippingPath, NULL, fill_mode); - delete pTextClippingPath; - pTextClippingPath = NULL; - } - } else { - if (pTextClippingPath == NULL) { - pTextClippingPath = new CFX_PathData; - } - ProcessText(pText, pObj2Device, pTextClippingPath); - } - } - delete pTextClippingPath; -} -void CPDF_RenderStatus::DrawClipPath(CPDF_ClipPath ClipPath, const CFX_AffineMatrix* pObj2Device) -{ - if (ClipPath.IsNull()) { - return; - } - int fill_mode = 0; - if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) { - fill_mode |= FXFILL_NOPATHSMOOTH; - } - int nClipPath = ClipPath.GetPathCount(); - int i; - for (i = 0; i < nClipPath; i++) { - const CFX_PathData* pPathData = ClipPath.GetPath(i); - if (pPathData == NULL) { - continue; - } - CFX_GraphStateData stroke_state; - if (m_Options.m_Flags & RENDER_THINLINE) { - stroke_state.m_LineWidth = 0; - } - m_pDevice->DrawPath(pPathData, pObj2Device, &stroke_state, 0, 0xffff0000, fill_mode); - } -} -FX_BOOL CPDF_RenderStatus::SelectClipPath(CPDF_PathObject* pPathObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStroke) -{ - CFX_AffineMatrix path_matrix = pPathObj->m_Matrix; - path_matrix.Concat(*pObj2Device); - if (bStroke) { - CFX_GraphStateData graphState(*pPathObj->m_GraphState); - if (m_Options.m_Flags & RENDER_THINLINE) { - graphState.m_LineWidth = 0; - } - return m_pDevice->SetClip_PathStroke(pPathObj->m_Path, &path_matrix, &graphState); - } - int fill_mode = pPathObj->m_FillType; - if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) { - fill_mode |= FXFILL_NOPATHSMOOTH; - } - return m_pDevice->SetClip_PathFill(pPathObj->m_Path, &path_matrix, fill_mode); -} -FX_BOOL CPDF_RenderStatus::ProcessTransparency(const CPDF_PageObject* pPageObj, const CFX_AffineMatrix* pObj2Device) -{ - const CPDF_GeneralStateData* pGeneralState = pPageObj->m_GeneralState; - int blend_type = pGeneralState ? pGeneralState->m_BlendType : FXDIB_BLEND_NORMAL; - if (blend_type == FXDIB_BLEND_UNSUPPORTED) { - return TRUE; - } - CPDF_Dictionary* pSMaskDict = pGeneralState ? (CPDF_Dictionary*)pGeneralState->m_pSoftMask : NULL; - if (pSMaskDict) { - if (pPageObj->m_Type == PDFPAGE_IMAGE && - ((CPDF_ImageObject*)pPageObj)->m_pImage->GetDict()->KeyExist(FX_BSTRC("SMask"))) { - pSMaskDict = NULL; - } - } - CPDF_Dictionary* pFormResource = NULL; - FX_FLOAT group_alpha = 1.0f; - int Transparency = m_Transparency; - FX_BOOL bGroupTransparent = FALSE; - if (pPageObj->m_Type == PDFPAGE_FORM) { - CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj; - const CPDF_GeneralStateData *pStateData = pFormObj->m_GeneralState.GetObject(); - if (pStateData) { - group_alpha = pStateData->m_FillAlpha; - } - Transparency = pFormObj->m_pForm->m_Transparency; - bGroupTransparent = Transparency & PDFTRANS_ISOLATED ? TRUE : FALSE; - if (pFormObj->m_pForm->m_pFormDict) { - pFormResource = pFormObj->m_pForm->m_pFormDict->GetDict("Resources"); - } - } - FX_BOOL bTextClip = FALSE; - if (pPageObj->m_ClipPath.NotNull() && pPageObj->m_ClipPath.GetTextCount() && - m_pDevice->GetDeviceClass() == FXDC_DISPLAY && !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)) { - bTextClip = TRUE; - } - if ((m_Options.m_Flags & RENDER_OVERPRINT) && pPageObj->m_Type == PDFPAGE_IMAGE && pGeneralState && pGeneralState->m_FillOP && pGeneralState->m_StrokeOP) { - CPDF_Document* pDocument = NULL; - CPDF_Page* pPage = NULL; - if (m_pContext->m_pPageCache) { - pPage = m_pContext->m_pPageCache->GetPage(); - pDocument = pPage->m_pDocument; - } else { - pDocument = ((CPDF_ImageObject*)pPageObj)->m_pImage->GetDocument(); - } - CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : NULL; - CPDF_Object* pCSObj = ((CPDF_ImageObject*)pPageObj)->m_pImage->GetStream()->GetDict()->GetElementValue(FX_BSTRC("ColorSpace")); - CPDF_ColorSpace* pColorSpace = pDocument->LoadColorSpace(pCSObj, pPageResources); - if (pColorSpace) { - int format = pColorSpace->GetFamily(); - if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION || format == PDFCS_DEVICEN) { - blend_type = FXDIB_BLEND_DARKEN; - } - pDocument->GetPageData()->ReleaseColorSpace(pCSObj); - } - } - if (pSMaskDict == NULL && group_alpha == 1.0f && blend_type == FXDIB_BLEND_NORMAL && !bTextClip && !bGroupTransparent) { - return FALSE; - } - FX_BOOL isolated = Transparency & PDFTRANS_ISOLATED; - if (m_bPrint) { - FX_BOOL bRet = FALSE; - int rendCaps = m_pDevice->GetRenderCaps(); - if (!((Transparency & PDFTRANS_ISOLATED) || pSMaskDict || bTextClip) && (rendCaps & FXRC_BLEND_MODE)) { - int oldBlend = m_curBlend; - m_curBlend = blend_type; - bRet = DrawObjWithBlend(pPageObj, pObj2Device); - m_curBlend = oldBlend; - } - if (!bRet) { - DrawObjWithBackground(pPageObj, pObj2Device); - } - return TRUE; - } - FX_RECT rect = pPageObj->GetBBox(pObj2Device); - rect.Intersect(m_pDevice->GetClipBox()); - if (rect.IsEmpty()) { - return TRUE; - } - CFX_Matrix deviceCTM = m_pDevice->GetCTM(); - FX_FLOAT scaleX = FXSYS_fabs(deviceCTM.a); - FX_FLOAT scaleY = FXSYS_fabs(deviceCTM.d); - int width = FXSYS_round((FX_FLOAT)rect.Width() * scaleX); - int height = FXSYS_round((FX_FLOAT)rect.Height() * scaleY); - CFX_FxgeDevice bitmap_device; - CFX_DIBitmap* oriDevice = NULL; - if (!isolated && (m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) { - oriDevice = new CFX_DIBitmap; - if (!m_pDevice->CreateCompatibleBitmap(oriDevice, width, height)) { - return TRUE; - } - m_pDevice->GetDIBits(oriDevice, rect.left, rect.top); - } - if (!bitmap_device.Create(width, height, FXDIB_Argb, 0, oriDevice)) { - return TRUE; - } - CFX_DIBitmap* bitmap = bitmap_device.GetBitmap(); - bitmap->Clear(0); - CFX_AffineMatrix new_matrix = *pObj2Device; - new_matrix.TranslateI(-rect.left, -rect.top); - new_matrix.Scale(scaleX, scaleY); - CFX_DIBitmap* pTextMask = NULL; - if (bTextClip) { - pTextMask = new CFX_DIBitmap; - if (!pTextMask->Create(width, height, FXDIB_8bppMask)) { - delete pTextMask; - return TRUE; - } - pTextMask->Clear(0); - CFX_FxgeDevice text_device; - text_device.Attach(pTextMask); - for (FX_DWORD i = 0; i < pPageObj->m_ClipPath.GetTextCount(); i ++) { - CPDF_TextObject* textobj = pPageObj->m_ClipPath.GetText(i); - if (textobj == NULL) { - break; - } - CFX_AffineMatrix text_matrix; - textobj->GetTextMatrix(&text_matrix); - CPDF_TextRenderer::DrawTextPath(&text_device, textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos, - textobj->m_TextState.GetFont(), textobj->m_TextState.GetFontSize(), - &text_matrix, &new_matrix, textobj->m_GraphState, (FX_ARGB) - 1, 0, NULL); - } - } - CPDF_RenderStatus bitmap_render; - bitmap_render.Initialize(m_pContext, &bitmap_device, NULL, - m_pStopObj, NULL, NULL, &m_Options, 0, m_bDropObjects, pFormResource, TRUE); - bitmap_render.ProcessObjectNoClip(pPageObj, &new_matrix); - m_bStopped = bitmap_render.m_bStopped; - if (pSMaskDict) { - CFX_AffineMatrix smask_matrix; - FXSYS_memcpy(&smask_matrix, pGeneralState->m_SMaskMatrix, sizeof smask_matrix); - smask_matrix.Concat(*pObj2Device); - CFX_DIBSource* pSMaskSource = LoadSMask(pSMaskDict, &rect, &smask_matrix); - if (pSMaskSource) { - bitmap->MultiplyAlpha(pSMaskSource); - delete pSMaskSource; - } - } - if (pTextMask) { - bitmap->MultiplyAlpha(pTextMask); - delete pTextMask; - pTextMask = NULL; - } - if (Transparency & PDFTRANS_GROUP && group_alpha != 1.0f) { - bitmap->MultiplyAlpha((int32_t)(group_alpha * 255)); - } - Transparency = m_Transparency; - if (pPageObj->m_Type == PDFPAGE_FORM) { - Transparency |= PDFTRANS_GROUP; - } - CompositeDIBitmap(bitmap, rect.left, rect.top, 0, 255, blend_type, Transparency); - delete oriDevice; + if (pTextClippingPath == NULL) { + pTextClippingPath = new CFX_PathData; + } + ProcessText(pText, pObj2Device, pTextClippingPath); + } + } + delete pTextClippingPath; +} +void CPDF_RenderStatus::DrawClipPath(CPDF_ClipPath ClipPath, + const CFX_AffineMatrix* pObj2Device) { + if (ClipPath.IsNull()) { + return; + } + int fill_mode = 0; + if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) { + fill_mode |= FXFILL_NOPATHSMOOTH; + } + int nClipPath = ClipPath.GetPathCount(); + int i; + for (i = 0; i < nClipPath; i++) { + const CFX_PathData* pPathData = ClipPath.GetPath(i); + if (pPathData == NULL) { + continue; + } + CFX_GraphStateData stroke_state; + if (m_Options.m_Flags & RENDER_THINLINE) { + stroke_state.m_LineWidth = 0; + } + m_pDevice->DrawPath(pPathData, pObj2Device, &stroke_state, 0, 0xffff0000, + fill_mode); + } +} +FX_BOOL CPDF_RenderStatus::SelectClipPath(CPDF_PathObject* pPathObj, + const CFX_AffineMatrix* pObj2Device, + FX_BOOL bStroke) { + CFX_AffineMatrix path_matrix = pPathObj->m_Matrix; + path_matrix.Concat(*pObj2Device); + if (bStroke) { + CFX_GraphStateData graphState(*pPathObj->m_GraphState); + if (m_Options.m_Flags & RENDER_THINLINE) { + graphState.m_LineWidth = 0; + } + return m_pDevice->SetClip_PathStroke(pPathObj->m_Path, &path_matrix, + &graphState); + } + int fill_mode = pPathObj->m_FillType; + if (m_Options.m_Flags & RENDER_NOPATHSMOOTH) { + fill_mode |= FXFILL_NOPATHSMOOTH; + } + return m_pDevice->SetClip_PathFill(pPathObj->m_Path, &path_matrix, fill_mode); +} +FX_BOOL CPDF_RenderStatus::ProcessTransparency( + const CPDF_PageObject* pPageObj, + const CFX_AffineMatrix* pObj2Device) { + const CPDF_GeneralStateData* pGeneralState = pPageObj->m_GeneralState; + int blend_type = + pGeneralState ? pGeneralState->m_BlendType : FXDIB_BLEND_NORMAL; + if (blend_type == FXDIB_BLEND_UNSUPPORTED) { return TRUE; -} -CFX_DIBitmap* CPDF_RenderStatus::GetBackdrop(const CPDF_PageObject* pObj, const FX_RECT& rect, int& left, int& top, - FX_BOOL bBackAlphaRequired) -{ - FX_RECT bbox = rect; - bbox.Intersect(m_pDevice->GetClipBox()); - left = bbox.left; - top = bbox.top; - CFX_Matrix deviceCTM = m_pDevice->GetCTM(); - FX_FLOAT scaleX = FXSYS_fabs(deviceCTM.a); - FX_FLOAT scaleY = FXSYS_fabs(deviceCTM.d); - int width = FXSYS_round(bbox.Width() * scaleX); - int height = FXSYS_round(bbox.Height() * scaleY); - CFX_DIBitmap* pBackdrop = new CFX_DIBitmap; - if (bBackAlphaRequired && !m_bDropObjects) { - pBackdrop->Create(width, height, FXDIB_Argb); - } else { - m_pDevice->CreateCompatibleBitmap(pBackdrop, width, height); - } - if (pBackdrop->GetBuffer() == NULL) { - delete pBackdrop; - return NULL; - } - FX_BOOL bNeedDraw; - if (pBackdrop->HasAlpha()) { - bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT); + } + CPDF_Dictionary* pSMaskDict = + pGeneralState ? (CPDF_Dictionary*)pGeneralState->m_pSoftMask : NULL; + if (pSMaskDict) { + if (pPageObj->m_Type == PDFPAGE_IMAGE && + ((CPDF_ImageObject*)pPageObj) + ->m_pImage->GetDict() + ->KeyExist(FX_BSTRC("SMask"))) { + pSMaskDict = NULL; + } + } + CPDF_Dictionary* pFormResource = NULL; + FX_FLOAT group_alpha = 1.0f; + int Transparency = m_Transparency; + FX_BOOL bGroupTransparent = FALSE; + if (pPageObj->m_Type == PDFPAGE_FORM) { + CPDF_FormObject* pFormObj = (CPDF_FormObject*)pPageObj; + const CPDF_GeneralStateData* pStateData = + pFormObj->m_GeneralState.GetObject(); + if (pStateData) { + group_alpha = pStateData->m_FillAlpha; + } + Transparency = pFormObj->m_pForm->m_Transparency; + bGroupTransparent = Transparency & PDFTRANS_ISOLATED ? TRUE : FALSE; + if (pFormObj->m_pForm->m_pFormDict) { + pFormResource = pFormObj->m_pForm->m_pFormDict->GetDict("Resources"); + } + } + FX_BOOL bTextClip = FALSE; + if (pPageObj->m_ClipPath.NotNull() && pPageObj->m_ClipPath.GetTextCount() && + m_pDevice->GetDeviceClass() == FXDC_DISPLAY && + !(m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_SOFT_CLIP)) { + bTextClip = TRUE; + } + if ((m_Options.m_Flags & RENDER_OVERPRINT) && + pPageObj->m_Type == PDFPAGE_IMAGE && pGeneralState && + pGeneralState->m_FillOP && pGeneralState->m_StrokeOP) { + CPDF_Document* pDocument = NULL; + CPDF_Page* pPage = NULL; + if (m_pContext->m_pPageCache) { + pPage = m_pContext->m_pPageCache->GetPage(); + pDocument = pPage->m_pDocument; } else { - bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_GET_BITS); + pDocument = ((CPDF_ImageObject*)pPageObj)->m_pImage->GetDocument(); + } + CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : NULL; + CPDF_Object* pCSObj = ((CPDF_ImageObject*)pPageObj) + ->m_pImage->GetStream() + ->GetDict() + ->GetElementValue(FX_BSTRC("ColorSpace")); + CPDF_ColorSpace* pColorSpace = + pDocument->LoadColorSpace(pCSObj, pPageResources); + if (pColorSpace) { + int format = pColorSpace->GetFamily(); + if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION || + format == PDFCS_DEVICEN) { + blend_type = FXDIB_BLEND_DARKEN; + } + pDocument->GetPageData()->ReleaseColorSpace(pCSObj); + } + } + if (pSMaskDict == NULL && group_alpha == 1.0f && + blend_type == FXDIB_BLEND_NORMAL && !bTextClip && !bGroupTransparent) { + return FALSE; + } + FX_BOOL isolated = Transparency & PDFTRANS_ISOLATED; + if (m_bPrint) { + FX_BOOL bRet = FALSE; + int rendCaps = m_pDevice->GetRenderCaps(); + if (!((Transparency & PDFTRANS_ISOLATED) || pSMaskDict || bTextClip) && + (rendCaps & FXRC_BLEND_MODE)) { + int oldBlend = m_curBlend; + m_curBlend = blend_type; + bRet = DrawObjWithBlend(pPageObj, pObj2Device); + m_curBlend = oldBlend; } - if (!bNeedDraw) { - m_pDevice->GetDIBits(pBackdrop, left, top); - return pBackdrop; + if (!bRet) { + DrawObjWithBackground(pPageObj, pObj2Device); } - CFX_AffineMatrix FinalMatrix = m_DeviceMatrix; - FinalMatrix.TranslateI(-left, -top); - FinalMatrix.Scale(scaleX, scaleY); - pBackdrop->Clear(pBackdrop->HasAlpha() ? 0 : 0xffffffff); - CFX_FxgeDevice device; - device.Attach(pBackdrop); - m_pContext->Render(&device, pObj, &m_Options, &FinalMatrix); + return TRUE; + } + FX_RECT rect = pPageObj->GetBBox(pObj2Device); + rect.Intersect(m_pDevice->GetClipBox()); + if (rect.IsEmpty()) { + return TRUE; + } + CFX_Matrix deviceCTM = m_pDevice->GetCTM(); + FX_FLOAT scaleX = FXSYS_fabs(deviceCTM.a); + FX_FLOAT scaleY = FXSYS_fabs(deviceCTM.d); + int width = FXSYS_round((FX_FLOAT)rect.Width() * scaleX); + int height = FXSYS_round((FX_FLOAT)rect.Height() * scaleY); + CFX_FxgeDevice bitmap_device; + CFX_DIBitmap* oriDevice = NULL; + if (!isolated && (m_pDevice->GetRenderCaps() & FXRC_GET_BITS)) { + oriDevice = new CFX_DIBitmap; + if (!m_pDevice->CreateCompatibleBitmap(oriDevice, width, height)) { + return TRUE; + } + m_pDevice->GetDIBits(oriDevice, rect.left, rect.top); + } + if (!bitmap_device.Create(width, height, FXDIB_Argb, 0, oriDevice)) { + return TRUE; + } + CFX_DIBitmap* bitmap = bitmap_device.GetBitmap(); + bitmap->Clear(0); + CFX_AffineMatrix new_matrix = *pObj2Device; + new_matrix.TranslateI(-rect.left, -rect.top); + new_matrix.Scale(scaleX, scaleY); + CFX_DIBitmap* pTextMask = NULL; + if (bTextClip) { + pTextMask = new CFX_DIBitmap; + if (!pTextMask->Create(width, height, FXDIB_8bppMask)) { + delete pTextMask; + return TRUE; + } + pTextMask->Clear(0); + CFX_FxgeDevice text_device; + text_device.Attach(pTextMask); + for (FX_DWORD i = 0; i < pPageObj->m_ClipPath.GetTextCount(); i++) { + CPDF_TextObject* textobj = pPageObj->m_ClipPath.GetText(i); + if (textobj == NULL) { + break; + } + CFX_AffineMatrix text_matrix; + textobj->GetTextMatrix(&text_matrix); + CPDF_TextRenderer::DrawTextPath( + &text_device, textobj->m_nChars, textobj->m_pCharCodes, + textobj->m_pCharPos, textobj->m_TextState.GetFont(), + textobj->m_TextState.GetFontSize(), &text_matrix, &new_matrix, + textobj->m_GraphState, (FX_ARGB)-1, 0, NULL); + } + } + CPDF_RenderStatus bitmap_render; + bitmap_render.Initialize(m_pContext, &bitmap_device, NULL, m_pStopObj, NULL, + NULL, &m_Options, 0, m_bDropObjects, pFormResource, + TRUE); + bitmap_render.ProcessObjectNoClip(pPageObj, &new_matrix); + m_bStopped = bitmap_render.m_bStopped; + if (pSMaskDict) { + CFX_AffineMatrix smask_matrix; + FXSYS_memcpy(&smask_matrix, pGeneralState->m_SMaskMatrix, + sizeof smask_matrix); + smask_matrix.Concat(*pObj2Device); + CFX_DIBSource* pSMaskSource = LoadSMask(pSMaskDict, &rect, &smask_matrix); + if (pSMaskSource) { + bitmap->MultiplyAlpha(pSMaskSource); + delete pSMaskSource; + } + } + if (pTextMask) { + bitmap->MultiplyAlpha(pTextMask); + delete pTextMask; + pTextMask = NULL; + } + if (Transparency & PDFTRANS_GROUP && group_alpha != 1.0f) { + bitmap->MultiplyAlpha((int32_t)(group_alpha * 255)); + } + Transparency = m_Transparency; + if (pPageObj->m_Type == PDFPAGE_FORM) { + Transparency |= PDFTRANS_GROUP; + } + CompositeDIBitmap(bitmap, rect.left, rect.top, 0, 255, blend_type, + Transparency); + delete oriDevice; + return TRUE; +} +CFX_DIBitmap* CPDF_RenderStatus::GetBackdrop(const CPDF_PageObject* pObj, + const FX_RECT& rect, + int& left, + int& top, + FX_BOOL bBackAlphaRequired) { + FX_RECT bbox = rect; + bbox.Intersect(m_pDevice->GetClipBox()); + left = bbox.left; + top = bbox.top; + CFX_Matrix deviceCTM = m_pDevice->GetCTM(); + FX_FLOAT scaleX = FXSYS_fabs(deviceCTM.a); + FX_FLOAT scaleY = FXSYS_fabs(deviceCTM.d); + int width = FXSYS_round(bbox.Width() * scaleX); + int height = FXSYS_round(bbox.Height() * scaleY); + CFX_DIBitmap* pBackdrop = new CFX_DIBitmap; + if (bBackAlphaRequired && !m_bDropObjects) { + pBackdrop->Create(width, height, FXDIB_Argb); + } else { + m_pDevice->CreateCompatibleBitmap(pBackdrop, width, height); + } + if (pBackdrop->GetBuffer() == NULL) { + delete pBackdrop; + return NULL; + } + FX_BOOL bNeedDraw; + if (pBackdrop->HasAlpha()) { + bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT); + } else { + bNeedDraw = !(m_pDevice->GetRenderCaps() & FXRC_GET_BITS); + } + if (!bNeedDraw) { + m_pDevice->GetDIBits(pBackdrop, left, top); return pBackdrop; -} -void CPDF_RenderContext::GetBackground(CFX_DIBitmap* pBuffer, const CPDF_PageObject* pObj, - const CPDF_RenderOptions* pOptions, CFX_AffineMatrix* pFinalMatrix) -{ - CFX_FxgeDevice device; - device.Attach(pBuffer); + } + CFX_AffineMatrix FinalMatrix = m_DeviceMatrix; + FinalMatrix.TranslateI(-left, -top); + FinalMatrix.Scale(scaleX, scaleY); + pBackdrop->Clear(pBackdrop->HasAlpha() ? 0 : 0xffffffff); + CFX_FxgeDevice device; + device.Attach(pBackdrop); + m_pContext->Render(&device, pObj, &m_Options, &FinalMatrix); + return pBackdrop; +} +void CPDF_RenderContext::GetBackground(CFX_DIBitmap* pBuffer, + const CPDF_PageObject* pObj, + const CPDF_RenderOptions* pOptions, + CFX_AffineMatrix* pFinalMatrix) { + CFX_FxgeDevice device; + device.Attach(pBuffer); - FX_RECT rect(0, 0, device.GetWidth(), device.GetHeight()); - device.FillRect(&rect, 0xffffffff); - Render(&device, pObj, pOptions, pFinalMatrix); -} -CPDF_GraphicStates* CPDF_RenderStatus::CloneObjStates(const CPDF_GraphicStates* pSrcStates, FX_BOOL bStroke) -{ - if (!pSrcStates) { - return NULL; - } - CPDF_GraphicStates* pStates = new CPDF_GraphicStates; - pStates->CopyStates(*pSrcStates); - CPDF_Color* pObjColor = bStroke ? pSrcStates->m_ColorState.GetStrokeColor() : - pSrcStates->m_ColorState.GetFillColor(); - if (!pObjColor->IsNull()) { - CPDF_ColorStateData* pColorData = pStates->m_ColorState.GetModify(); - pColorData->m_FillRGB = bStroke ? pSrcStates->m_ColorState.GetObject()->m_StrokeRGB : - pSrcStates->m_ColorState.GetObject()->m_FillRGB; - pColorData->m_StrokeRGB = pColorData->m_FillRGB; - } - return pStates; -} -CPDF_RenderContext::CPDF_RenderContext() -{ -} -void CPDF_RenderContext::Create(CPDF_Document* pDoc, CPDF_PageRenderCache* pPageCache, - CPDF_Dictionary* pPageResources, FX_BOOL bFirstLayer) -{ - m_pDocument = pDoc; - m_pPageResources = pPageResources; - m_pPageCache = pPageCache; - m_bFirstLayer = bFirstLayer; -} -void CPDF_RenderContext::Create(CPDF_Page* pPage, FX_BOOL bFirstLayer) -{ - m_pDocument = pPage->m_pDocument; - m_pPageResources = pPage->m_pPageResources; - m_pPageCache = pPage->GetRenderCache(); - m_bFirstLayer = bFirstLayer; -} -CPDF_RenderContext::~CPDF_RenderContext() -{ -} -void CPDF_RenderContext::Clear() -{ - m_pDocument = NULL; - m_pPageResources = NULL; - m_pPageCache = NULL; - m_bFirstLayer = TRUE; - m_ContentList.RemoveAll(); -} -void CPDF_RenderContext::AppendObjectList(CPDF_PageObjects* pObjs, const CFX_AffineMatrix* pObject2Device) -{ - _PDF_RenderItem* pItem = m_ContentList.AddSpace(); - pItem->m_pObjectList = pObjs; - if (pObject2Device) { - pItem->m_Matrix = *pObject2Device; + FX_RECT rect(0, 0, device.GetWidth(), device.GetHeight()); + device.FillRect(&rect, 0xffffffff); + Render(&device, pObj, pOptions, pFinalMatrix); +} +CPDF_GraphicStates* CPDF_RenderStatus::CloneObjStates( + const CPDF_GraphicStates* pSrcStates, + FX_BOOL bStroke) { + if (!pSrcStates) { + return NULL; + } + CPDF_GraphicStates* pStates = new CPDF_GraphicStates; + pStates->CopyStates(*pSrcStates); + CPDF_Color* pObjColor = bStroke ? pSrcStates->m_ColorState.GetStrokeColor() + : pSrcStates->m_ColorState.GetFillColor(); + if (!pObjColor->IsNull()) { + CPDF_ColorStateData* pColorData = pStates->m_ColorState.GetModify(); + pColorData->m_FillRGB = + bStroke ? pSrcStates->m_ColorState.GetObject()->m_StrokeRGB + : pSrcStates->m_ColorState.GetObject()->m_FillRGB; + pColorData->m_StrokeRGB = pColorData->m_FillRGB; + } + return pStates; +} +CPDF_RenderContext::CPDF_RenderContext() {} +void CPDF_RenderContext::Create(CPDF_Document* pDoc, + CPDF_PageRenderCache* pPageCache, + CPDF_Dictionary* pPageResources, + FX_BOOL bFirstLayer) { + m_pDocument = pDoc; + m_pPageResources = pPageResources; + m_pPageCache = pPageCache; + m_bFirstLayer = bFirstLayer; +} +void CPDF_RenderContext::Create(CPDF_Page* pPage, FX_BOOL bFirstLayer) { + m_pDocument = pPage->m_pDocument; + m_pPageResources = pPage->m_pPageResources; + m_pPageCache = pPage->GetRenderCache(); + m_bFirstLayer = bFirstLayer; +} +CPDF_RenderContext::~CPDF_RenderContext() {} +void CPDF_RenderContext::Clear() { + m_pDocument = NULL; + m_pPageResources = NULL; + m_pPageCache = NULL; + m_bFirstLayer = TRUE; + m_ContentList.RemoveAll(); +} +void CPDF_RenderContext::AppendObjectList( + CPDF_PageObjects* pObjs, + const CFX_AffineMatrix* pObject2Device) { + _PDF_RenderItem* pItem = m_ContentList.AddSpace(); + pItem->m_pObjectList = pObjs; + if (pObject2Device) { + pItem->m_Matrix = *pObject2Device; + } else { + pItem->m_Matrix.SetIdentity(); + } +} +void CPDF_RenderContext::Render(CFX_RenderDevice* pDevice, + const CPDF_RenderOptions* pOptions, + const CFX_AffineMatrix* pLastMatrix) { + Render(pDevice, NULL, pOptions, pLastMatrix); +} +void CPDF_RenderContext::Render(CFX_RenderDevice* pDevice, + const CPDF_PageObject* pStopObj, + const CPDF_RenderOptions* pOptions, + const CFX_AffineMatrix* pLastMatrix) { + int count = m_ContentList.GetSize(); + for (int j = 0; j < count; j++) { + pDevice->SaveState(); + _PDF_RenderItem* pItem = m_ContentList.GetDataPtr(j); + if (pLastMatrix) { + CFX_AffineMatrix FinalMatrix = pItem->m_Matrix; + FinalMatrix.Concat(*pLastMatrix); + CPDF_RenderStatus status; + status.Initialize(this, pDevice, pLastMatrix, pStopObj, NULL, NULL, + pOptions, pItem->m_pObjectList->m_Transparency, FALSE, + NULL); + status.RenderObjectList(pItem->m_pObjectList, &FinalMatrix); + if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) { + m_pPageCache->CacheOptimization(status.m_Options.m_dwLimitCacheSize); + } + if (status.m_bStopped) { + pDevice->RestoreState(); + break; + } } else { - pItem->m_Matrix.SetIdentity(); - } -} -void CPDF_RenderContext::Render(CFX_RenderDevice* pDevice, const CPDF_RenderOptions* pOptions, - const CFX_AffineMatrix* pLastMatrix) -{ - Render(pDevice, NULL, pOptions, pLastMatrix); -} -void CPDF_RenderContext::Render(CFX_RenderDevice* pDevice, const CPDF_PageObject* pStopObj, - const CPDF_RenderOptions* pOptions, const CFX_AffineMatrix* pLastMatrix) -{ - int count = m_ContentList.GetSize(); - for (int j = 0; j < count; j ++) { - pDevice->SaveState(); - _PDF_RenderItem* pItem = m_ContentList.GetDataPtr(j); - if (pLastMatrix) { - CFX_AffineMatrix FinalMatrix = pItem->m_Matrix; - FinalMatrix.Concat(*pLastMatrix); - CPDF_RenderStatus status; - status.Initialize(this, pDevice, pLastMatrix, pStopObj, NULL, NULL, pOptions, - pItem->m_pObjectList->m_Transparency, FALSE, NULL); - status.RenderObjectList(pItem->m_pObjectList, &FinalMatrix); - if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) { - m_pPageCache->CacheOptimization(status.m_Options.m_dwLimitCacheSize); - } - if (status.m_bStopped) { - pDevice->RestoreState(); - break; - } - } else { - CPDF_RenderStatus status; - status.Initialize(this, pDevice, NULL, pStopObj, NULL, NULL, pOptions, - pItem->m_pObjectList->m_Transparency, FALSE, NULL); - status.RenderObjectList(pItem->m_pObjectList, &pItem->m_Matrix); - if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) { - m_pPageCache->CacheOptimization(status.m_Options.m_dwLimitCacheSize); - } - if (status.m_bStopped) { - pDevice->RestoreState(); - break; - } - } + CPDF_RenderStatus status; + status.Initialize(this, pDevice, NULL, pStopObj, NULL, NULL, pOptions, + pItem->m_pObjectList->m_Transparency, FALSE, NULL); + status.RenderObjectList(pItem->m_pObjectList, &pItem->m_Matrix); + if (status.m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) { + m_pPageCache->CacheOptimization(status.m_Options.m_dwLimitCacheSize); + } + if (status.m_bStopped) { pDevice->RestoreState(); + break; + } } + pDevice->RestoreState(); + } } -void CPDF_RenderContext::DrawObjectList(CFX_RenderDevice* pDevice, CPDF_PageObjects* pObjs, - const CFX_AffineMatrix* pObject2Device, const CPDF_RenderOptions* pOptions) -{ - AppendObjectList(pObjs, pObject2Device); - Render(pDevice, pOptions); +void CPDF_RenderContext::DrawObjectList(CFX_RenderDevice* pDevice, + CPDF_PageObjects* pObjs, + const CFX_AffineMatrix* pObject2Device, + const CPDF_RenderOptions* pOptions) { + AppendObjectList(pObjs, pObject2Device); + Render(pDevice, pOptions); } CPDF_ProgressiveRenderer::CPDF_ProgressiveRenderer( CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, - const CPDF_RenderOptions* pOptions) : - m_Status(Ready), - m_pContext(pContext), - m_pDevice(pDevice), - m_pOptions(pOptions), - m_LayerIndex(0), - m_ObjectIndex(0), - m_ObjectPos(nullptr), - m_PrevLastPos(nullptr) -{ -} + const CPDF_RenderOptions* pOptions) + : m_Status(Ready), + m_pContext(pContext), + m_pDevice(pDevice), + m_pOptions(pOptions), + m_LayerIndex(0), + m_ObjectIndex(0), + m_ObjectPos(nullptr), + m_PrevLastPos(nullptr) {} -CPDF_ProgressiveRenderer::~CPDF_ProgressiveRenderer() -{ - if (m_pRenderStatus) - m_pDevice->RestoreState(); +CPDF_ProgressiveRenderer::~CPDF_ProgressiveRenderer() { + if (m_pRenderStatus) + m_pDevice->RestoreState(); } -void CPDF_ProgressiveRenderer::Start(IFX_Pause* pPause) -{ - if (!m_pContext || !m_pDevice || m_Status != Ready) { - m_Status = Failed; - return; - } - m_Status = ToBeContinued; - Continue(pPause); +void CPDF_ProgressiveRenderer::Start(IFX_Pause* pPause) { + if (!m_pContext || !m_pDevice || m_Status != Ready) { + m_Status = Failed; + return; + } + m_Status = ToBeContinued; + Continue(pPause); } #define RENDER_STEP_LIMIT 100 -void CPDF_ProgressiveRenderer::Continue(IFX_Pause* pPause) -{ - if (m_Status != ToBeContinued) { - return; - } - FX_DWORD nLayers = m_pContext->m_ContentList.GetSize(); - for (; m_LayerIndex < nLayers; m_LayerIndex ++) { - _PDF_RenderItem* pItem = m_pContext->m_ContentList.GetDataPtr(m_LayerIndex); - FX_POSITION LastPos = pItem->m_pObjectList->GetLastObjectPosition(); - if (m_ObjectPos == NULL) { - if (LastPos == m_PrevLastPos) { - if (!pItem->m_pObjectList->IsParsed()) { - pItem->m_pObjectList->ContinueParse(pPause); - if (!pItem->m_pObjectList->IsParsed()) { - return; - } - LastPos = pItem->m_pObjectList->GetLastObjectPosition(); - } - } - if (LastPos == m_PrevLastPos) { - if (m_pRenderStatus) { - m_pRenderStatus.reset(); - m_pDevice->RestoreState(); - m_ObjectPos = NULL; - m_PrevLastPos = NULL; - } - continue; - } - if (m_PrevLastPos) { - m_ObjectPos = m_PrevLastPos; - pItem->m_pObjectList->GetNextObject(m_ObjectPos); - } else { - m_ObjectPos = pItem->m_pObjectList->GetFirstObjectPosition(); - } - m_PrevLastPos = LastPos; +void CPDF_ProgressiveRenderer::Continue(IFX_Pause* pPause) { + if (m_Status != ToBeContinued) { + return; + } + FX_DWORD nLayers = m_pContext->m_ContentList.GetSize(); + for (; m_LayerIndex < nLayers; m_LayerIndex++) { + _PDF_RenderItem* pItem = m_pContext->m_ContentList.GetDataPtr(m_LayerIndex); + FX_POSITION LastPos = pItem->m_pObjectList->GetLastObjectPosition(); + if (m_ObjectPos == NULL) { + if (LastPos == m_PrevLastPos) { + if (!pItem->m_pObjectList->IsParsed()) { + pItem->m_pObjectList->ContinueParse(pPause); + if (!pItem->m_pObjectList->IsParsed()) { + return; + } + LastPos = pItem->m_pObjectList->GetLastObjectPosition(); } - if (!m_pRenderStatus) { - m_ObjectPos = pItem->m_pObjectList->GetFirstObjectPosition(); - m_ObjectIndex = 0; - m_pRenderStatus.reset(new CPDF_RenderStatus()); - m_pRenderStatus->Initialize( - m_pContext, m_pDevice, NULL, NULL, NULL, NULL, m_pOptions, - pItem->m_pObjectList->m_Transparency, FALSE, NULL); - m_pDevice->SaveState(); - m_ClipRect = m_pDevice->GetClipBox(); - CFX_AffineMatrix device2object; - device2object.SetReverse(pItem->m_Matrix); - device2object.TransformRect(m_ClipRect); + } + if (LastPos == m_PrevLastPos) { + if (m_pRenderStatus) { + m_pRenderStatus.reset(); + m_pDevice->RestoreState(); + m_ObjectPos = NULL; + m_PrevLastPos = NULL; } - int objs_to_go = CPDF_ModuleMgr::Get()->GetRenderModule()->GetConfig()->m_RenderStepLimit; - while (m_ObjectPos) { - CPDF_PageObject* pCurObj = pItem->m_pObjectList->GetObjectAt(m_ObjectPos); - if (pCurObj && pCurObj->m_Left <= m_ClipRect.right && pCurObj->m_Right >= m_ClipRect.left && - pCurObj->m_Bottom <= m_ClipRect.top && pCurObj->m_Top >= m_ClipRect.bottom) { - if (m_pRenderStatus->ContinueSingleObject(pCurObj, &pItem->m_Matrix, pPause)) { - return; - } - if (pCurObj->m_Type == PDFPAGE_IMAGE && m_pRenderStatus->m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) { - m_pContext->GetPageCache()->CacheOptimization(m_pRenderStatus->m_Options.m_dwLimitCacheSize); - } - if (pCurObj->m_Type == PDFPAGE_FORM || pCurObj->m_Type == PDFPAGE_SHADING) { - objs_to_go = 0; - } else { - objs_to_go --; - } - } - m_ObjectIndex ++; - pItem->m_pObjectList->GetNextObject(m_ObjectPos); - if (objs_to_go == 0) { - if (pPause && pPause->NeedToPauseNow()) { - return; - } - objs_to_go = CPDF_ModuleMgr::Get()->GetRenderModule()->GetConfig()->m_RenderStepLimit; - } + continue; + } + if (m_PrevLastPos) { + m_ObjectPos = m_PrevLastPos; + pItem->m_pObjectList->GetNextObject(m_ObjectPos); + } else { + m_ObjectPos = pItem->m_pObjectList->GetFirstObjectPosition(); + } + m_PrevLastPos = LastPos; + } + if (!m_pRenderStatus) { + m_ObjectPos = pItem->m_pObjectList->GetFirstObjectPosition(); + m_ObjectIndex = 0; + m_pRenderStatus.reset(new CPDF_RenderStatus()); + m_pRenderStatus->Initialize( + m_pContext, m_pDevice, NULL, NULL, NULL, NULL, m_pOptions, + pItem->m_pObjectList->m_Transparency, FALSE, NULL); + m_pDevice->SaveState(); + m_ClipRect = m_pDevice->GetClipBox(); + CFX_AffineMatrix device2object; + device2object.SetReverse(pItem->m_Matrix); + device2object.TransformRect(m_ClipRect); + } + int objs_to_go = CPDF_ModuleMgr::Get() + ->GetRenderModule() + ->GetConfig() + ->m_RenderStepLimit; + while (m_ObjectPos) { + CPDF_PageObject* pCurObj = pItem->m_pObjectList->GetObjectAt(m_ObjectPos); + if (pCurObj && pCurObj->m_Left <= m_ClipRect.right && + pCurObj->m_Right >= m_ClipRect.left && + pCurObj->m_Bottom <= m_ClipRect.top && + pCurObj->m_Top >= m_ClipRect.bottom) { + if (m_pRenderStatus->ContinueSingleObject(pCurObj, &pItem->m_Matrix, + pPause)) { + return; } - if (!pItem->m_pObjectList->IsParsed()) { - return; + if (pCurObj->m_Type == PDFPAGE_IMAGE && + m_pRenderStatus->m_Options.m_Flags & RENDER_LIMITEDIMAGECACHE) { + m_pContext->GetPageCache()->CacheOptimization( + m_pRenderStatus->m_Options.m_dwLimitCacheSize); } - m_pRenderStatus.reset(); - m_pDevice->RestoreState(); - m_ObjectPos = NULL; - m_PrevLastPos = NULL; - if (pPause && pPause->NeedToPauseNow()) { - m_LayerIndex++; - return; + if (pCurObj->m_Type == PDFPAGE_FORM || + pCurObj->m_Type == PDFPAGE_SHADING) { + objs_to_go = 0; + } else { + objs_to_go--; } - } - m_Status = Done; -} -int CPDF_ProgressiveRenderer::EstimateProgress() -{ - if (!m_pContext) { - return 0; - } - FX_DWORD nLayers = m_pContext->m_ContentList.GetSize(); - int nTotal = 0, nRendered = 0; - for (FX_DWORD layer = 0; layer < nLayers; layer ++) { - _PDF_RenderItem* pItem = m_pContext->m_ContentList.GetDataPtr(layer); - int nObjs = pItem->m_pObjectList->CountObjects(); - if (layer == m_LayerIndex) { - nRendered += m_ObjectIndex; - } else if (layer < m_LayerIndex) { - nRendered += nObjs; + } + m_ObjectIndex++; + pItem->m_pObjectList->GetNextObject(m_ObjectPos); + if (objs_to_go == 0) { + if (pPause && pPause->NeedToPauseNow()) { + return; } - nTotal += nObjs; + objs_to_go = CPDF_ModuleMgr::Get() + ->GetRenderModule() + ->GetConfig() + ->m_RenderStepLimit; + } } - if (nTotal == 0) { - return 0; + if (!pItem->m_pObjectList->IsParsed()) { + return; } - return 100 * nRendered / nTotal; -} -CPDF_TransferFunc* CPDF_DocRenderData::GetTransferFunc(CPDF_Object* pObj) -{ - if (!pObj) - return nullptr; + m_pRenderStatus.reset(); + m_pDevice->RestoreState(); + m_ObjectPos = NULL; + m_PrevLastPos = NULL; + if (pPause && pPause->NeedToPauseNow()) { + m_LayerIndex++; + return; + } + } + m_Status = Done; +} +int CPDF_ProgressiveRenderer::EstimateProgress() { + if (!m_pContext) { + return 0; + } + FX_DWORD nLayers = m_pContext->m_ContentList.GetSize(); + int nTotal = 0, nRendered = 0; + for (FX_DWORD layer = 0; layer < nLayers; layer++) { + _PDF_RenderItem* pItem = m_pContext->m_ContentList.GetDataPtr(layer); + int nObjs = pItem->m_pObjectList->CountObjects(); + if (layer == m_LayerIndex) { + nRendered += m_ObjectIndex; + } else if (layer < m_LayerIndex) { + nRendered += nObjs; + } + nTotal += nObjs; + } + if (nTotal == 0) { + return 0; + } + return 100 * nRendered / nTotal; +} +CPDF_TransferFunc* CPDF_DocRenderData::GetTransferFunc(CPDF_Object* pObj) { + if (!pObj) + return nullptr; - auto it = m_TransferFuncMap.find(pObj); - if (it != m_TransferFuncMap.end()) { - CPDF_CountedObject<CPDF_TransferFunc>* pTransferCounter = it->second; - return pTransferCounter->AddRef(); - } + auto it = m_TransferFuncMap.find(pObj); + if (it != m_TransferFuncMap.end()) { + CPDF_CountedObject<CPDF_TransferFunc>* pTransferCounter = it->second; + return pTransferCounter->AddRef(); + } - CPDF_Function* pFuncs[3] = { nullptr, nullptr, nullptr }; - FX_BOOL bUniTransfer = TRUE; - FX_BOOL bIdentity = TRUE; - if (pObj->GetType() == PDFOBJ_ARRAY) { - bUniTransfer = FALSE; - CPDF_Array* pArray = (CPDF_Array*)pObj; - if (pArray->GetCount() < 3) - return nullptr; + CPDF_Function* pFuncs[3] = {nullptr, nullptr, nullptr}; + FX_BOOL bUniTransfer = TRUE; + FX_BOOL bIdentity = TRUE; + if (pObj->GetType() == PDFOBJ_ARRAY) { + bUniTransfer = FALSE; + CPDF_Array* pArray = (CPDF_Array*)pObj; + if (pArray->GetCount() < 3) + return nullptr; - for (FX_DWORD i = 0; i < 3; ++i) { - pFuncs[2 - i] = CPDF_Function::Load(pArray->GetElementValue(i)); - if (!pFuncs[2 - i]) { - return nullptr; - } - } + for (FX_DWORD i = 0; i < 3; ++i) { + pFuncs[2 - i] = CPDF_Function::Load(pArray->GetElementValue(i)); + if (!pFuncs[2 - i]) { + return nullptr; + } + } + } else { + pFuncs[0] = CPDF_Function::Load(pObj); + if (!pFuncs[0]) { + return nullptr; + } + } + CPDF_TransferFunc* pTransfer = new CPDF_TransferFunc; + pTransfer->m_pPDFDoc = m_pPDFDoc; + CPDF_CountedObject<CPDF_TransferFunc>* pTransferCounter = + new CPDF_CountedObject<CPDF_TransferFunc>(pTransfer); + m_TransferFuncMap[pObj] = pTransferCounter; + static const int kMaxOutputs = 16; + FX_FLOAT output[kMaxOutputs]; + FXSYS_memset(output, 0, sizeof(output)); + FX_FLOAT input; + int noutput; + for (int v = 0; v < 256; ++v) { + input = (FX_FLOAT)v / 255.0f; + if (bUniTransfer) { + if (pFuncs[0] && pFuncs[0]->CountOutputs() <= kMaxOutputs) + pFuncs[0]->Call(&input, 1, output, noutput); + int o = FXSYS_round(output[0] * 255); + if (o != v) + bIdentity = FALSE; + for (int i = 0; i < 3; ++i) { + pTransfer->m_Samples[i * 256 + v] = o; + } } else { - pFuncs[0] = CPDF_Function::Load(pObj); - if (!pFuncs[0]) { - return nullptr; - } - } - CPDF_TransferFunc* pTransfer = new CPDF_TransferFunc; - pTransfer->m_pPDFDoc = m_pPDFDoc; - CPDF_CountedObject<CPDF_TransferFunc>* pTransferCounter = - new CPDF_CountedObject<CPDF_TransferFunc>(pTransfer); - m_TransferFuncMap[pObj] = pTransferCounter; - static const int kMaxOutputs = 16; - FX_FLOAT output[kMaxOutputs]; - FXSYS_memset(output, 0, sizeof(output)); - FX_FLOAT input; - int noutput; - for (int v = 0; v < 256; ++v) { - input = (FX_FLOAT)v / 255.0f; - if (bUniTransfer) { - if (pFuncs[0] && pFuncs[0]->CountOutputs() <= kMaxOutputs) - pFuncs[0]->Call(&input, 1, output, noutput); - int o = FXSYS_round(output[0] * 255); - if (o != v) - bIdentity = FALSE; - for (int i = 0; i < 3; ++i) { - pTransfer->m_Samples[i * 256 + v] = o; - } + for (int i = 0; i < 3; ++i) { + if (pFuncs[i] && pFuncs[i]->CountOutputs() <= kMaxOutputs) { + pFuncs[i]->Call(&input, 1, output, noutput); + int o = FXSYS_round(output[0] * 255); + if (o != v) + bIdentity = FALSE; + pTransfer->m_Samples[i * 256 + v] = o; } else { - for (int i = 0; i < 3; ++i) { - if (pFuncs[i] && pFuncs[i]->CountOutputs() <= kMaxOutputs) { - pFuncs[i]->Call(&input, 1, output, noutput); - int o = FXSYS_round(output[0] * 255); - if (o != v) - bIdentity = FALSE; - pTransfer->m_Samples[i * 256 + v] = o; - } else { - pTransfer->m_Samples[i * 256 + v] = v; - } - } + pTransfer->m_Samples[i * 256 + v] = v; } + } } - for (int i = 0; i < 3; ++i) - delete pFuncs[i]; + } + for (int i = 0; i < 3; ++i) + delete pFuncs[i]; - pTransfer->m_bIdentity = bIdentity; - return pTransferCounter->AddRef(); + pTransfer->m_bIdentity = bIdentity; + return pTransferCounter->AddRef(); } -void CPDF_DocRenderData::ReleaseTransferFunc(CPDF_Object* pObj) -{ - auto it = m_TransferFuncMap.find(pObj); - if (it != m_TransferFuncMap.end()) - it->second->RemoveRef(); -} -CPDF_RenderConfig::CPDF_RenderConfig() -{ - m_HalftoneLimit = 0; - m_RenderStepLimit = 100; -} -CPDF_RenderConfig::~CPDF_RenderConfig() -{ -} -CPDF_DeviceBuffer::CPDF_DeviceBuffer() -{ - m_pBitmap = NULL; - m_pDevice = NULL; - m_pContext = NULL; - m_pObject = NULL; -} -CPDF_DeviceBuffer::~CPDF_DeviceBuffer() -{ - delete m_pBitmap; -} -FX_BOOL CPDF_DeviceBuffer::Initialize(CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, FX_RECT* pRect, - const CPDF_PageObject* pObj, int max_dpi) -{ - m_pDevice = pDevice; - m_pContext = pContext; - m_Rect = *pRect; - m_pObject = pObj; - m_Matrix.TranslateI(-pRect->left, -pRect->top); +void CPDF_DocRenderData::ReleaseTransferFunc(CPDF_Object* pObj) { + auto it = m_TransferFuncMap.find(pObj); + if (it != m_TransferFuncMap.end()) + it->second->RemoveRef(); +} +CPDF_RenderConfig::CPDF_RenderConfig() { + m_HalftoneLimit = 0; + m_RenderStepLimit = 100; +} +CPDF_RenderConfig::~CPDF_RenderConfig() {} +CPDF_DeviceBuffer::CPDF_DeviceBuffer() { + m_pBitmap = NULL; + m_pDevice = NULL; + m_pContext = NULL; + m_pObject = NULL; +} +CPDF_DeviceBuffer::~CPDF_DeviceBuffer() { + delete m_pBitmap; +} +FX_BOOL CPDF_DeviceBuffer::Initialize(CPDF_RenderContext* pContext, + CFX_RenderDevice* pDevice, + FX_RECT* pRect, + const CPDF_PageObject* pObj, + int max_dpi) { + m_pDevice = pDevice; + m_pContext = pContext; + m_Rect = *pRect; + m_pObject = pObj; + m_Matrix.TranslateI(-pRect->left, -pRect->top); #if _FXM_PLATFORM_ != _FXM_PLATFORM_APPLE_ - int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE); - int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE); - if (horz_size && vert_size && max_dpi) { - int dpih = pDevice->GetDeviceCaps(FXDC_PIXEL_WIDTH) * 254 / (horz_size * 10); - int dpiv = pDevice->GetDeviceCaps(FXDC_PIXEL_HEIGHT) * 254 / (vert_size * 10); - if (dpih > max_dpi) { - m_Matrix.Scale((FX_FLOAT)(max_dpi) / dpih, 1.0f); - } - if (dpiv > max_dpi) { - m_Matrix.Scale(1.0f, (FX_FLOAT)(max_dpi) / (FX_FLOAT)dpiv); - } - } + int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE); + int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE); + if (horz_size && vert_size && max_dpi) { + int dpih = + pDevice->GetDeviceCaps(FXDC_PIXEL_WIDTH) * 254 / (horz_size * 10); + int dpiv = + pDevice->GetDeviceCaps(FXDC_PIXEL_HEIGHT) * 254 / (vert_size * 10); + if (dpih > max_dpi) { + m_Matrix.Scale((FX_FLOAT)(max_dpi) / dpih, 1.0f); + } + if (dpiv > max_dpi) { + m_Matrix.Scale(1.0f, (FX_FLOAT)(max_dpi) / (FX_FLOAT)dpiv); + } + } #endif - CFX_Matrix ctm = m_pDevice->GetCTM(); - FX_FLOAT fScaleX = FXSYS_fabs(ctm.a); - FX_FLOAT fScaleY = FXSYS_fabs(ctm.d); - m_Matrix.Concat(fScaleX, 0, 0, fScaleY, 0, 0); - CFX_FloatRect rect(*pRect); - m_Matrix.TransformRect(rect); - FX_RECT bitmap_rect = rect.GetOutterRect(); - m_pBitmap = new CFX_DIBitmap; - m_pBitmap->Create(bitmap_rect.Width(), bitmap_rect.Height(), FXDIB_Argb); - return TRUE; -} -void CPDF_DeviceBuffer::OutputToDevice() -{ - if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_GET_BITS) { - if (m_Matrix.a == 1.0f && m_Matrix.d == 1.0f) { - m_pDevice->SetDIBits(m_pBitmap, m_Rect.left, m_Rect.top); - } else { - m_pDevice->StretchDIBits(m_pBitmap, m_Rect.left, m_Rect.top, m_Rect.Width(), m_Rect.Height()); - } + CFX_Matrix ctm = m_pDevice->GetCTM(); + FX_FLOAT fScaleX = FXSYS_fabs(ctm.a); + FX_FLOAT fScaleY = FXSYS_fabs(ctm.d); + m_Matrix.Concat(fScaleX, 0, 0, fScaleY, 0, 0); + CFX_FloatRect rect(*pRect); + m_Matrix.TransformRect(rect); + FX_RECT bitmap_rect = rect.GetOutterRect(); + m_pBitmap = new CFX_DIBitmap; + m_pBitmap->Create(bitmap_rect.Width(), bitmap_rect.Height(), FXDIB_Argb); + return TRUE; +} +void CPDF_DeviceBuffer::OutputToDevice() { + if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_GET_BITS) { + if (m_Matrix.a == 1.0f && m_Matrix.d == 1.0f) { + m_pDevice->SetDIBits(m_pBitmap, m_Rect.left, m_Rect.top); } else { - CFX_DIBitmap buffer; - m_pDevice->CreateCompatibleBitmap(&buffer, m_pBitmap->GetWidth(), m_pBitmap->GetHeight()); - m_pContext->GetBackground(&buffer, m_pObject, NULL, &m_Matrix); - buffer.CompositeBitmap(0, 0, buffer.GetWidth(), buffer.GetHeight(), m_pBitmap, 0, 0); - m_pDevice->StretchDIBits(&buffer, m_Rect.left, m_Rect.top, m_Rect.Width(), m_Rect.Height()); - } -} -CPDF_ScaledRenderBuffer::CPDF_ScaledRenderBuffer() -{ - m_pBitmapDevice = NULL; -} -CPDF_ScaledRenderBuffer::~CPDF_ScaledRenderBuffer() -{ - delete m_pBitmapDevice; -} -#define _FPDFAPI_IMAGESIZE_LIMIT_ (30 * 1024 * 1024) -FX_BOOL CPDF_ScaledRenderBuffer::Initialize(CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, FX_RECT* pRect, - const CPDF_PageObject* pObj, const CPDF_RenderOptions *pOptions, int max_dpi) -{ - FXSYS_assert(pRect != NULL); - m_pDevice = pDevice; - if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_GET_BITS) { - return TRUE; - } - m_pContext = pContext; - m_Rect = *pRect; - m_pObject = pObj; - m_Matrix.TranslateI(-pRect->left, -pRect->top); - int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE); - int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE); - if (horz_size && vert_size && max_dpi) { - int dpih = pDevice->GetDeviceCaps(FXDC_PIXEL_WIDTH) * 254 / (horz_size * 10); - int dpiv = pDevice->GetDeviceCaps(FXDC_PIXEL_HEIGHT) * 254 / (vert_size * 10); - if (dpih > max_dpi) { - m_Matrix.Scale((FX_FLOAT)(max_dpi) / dpih, 1.0f); - } - if (dpiv > max_dpi) { - m_Matrix.Scale(1.0f, (FX_FLOAT)(max_dpi) / (FX_FLOAT)dpiv); - } - } - m_pBitmapDevice = new CFX_FxgeDevice; - FXDIB_Format dibFormat = FXDIB_Rgb; - int32_t bpp = 24; - if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_ALPHA_OUTPUT) { - dibFormat = FXDIB_Argb; - bpp = 32; - } - CFX_FloatRect rect; - int32_t iWidth, iHeight, iPitch; - while (1) { - rect = *pRect; - m_Matrix.TransformRect(rect); - FX_RECT bitmap_rect = rect.GetOutterRect(); - iWidth = bitmap_rect.Width(); - iHeight = bitmap_rect.Height(); - iPitch = (iWidth * bpp + 31) / 32 * 4; - if (iWidth * iHeight < 1) { - return FALSE; - } - if (iPitch * iHeight <= _FPDFAPI_IMAGESIZE_LIMIT_ && - m_pBitmapDevice->Create(iWidth, iHeight, dibFormat)) { - break; - } - m_Matrix.Scale(0.5f, 0.5f); - } - m_pContext->GetBackground(m_pBitmapDevice->GetBitmap(), m_pObject, pOptions, &m_Matrix); + m_pDevice->StretchDIBits(m_pBitmap, m_Rect.left, m_Rect.top, + m_Rect.Width(), m_Rect.Height()); + } + } else { + CFX_DIBitmap buffer; + m_pDevice->CreateCompatibleBitmap(&buffer, m_pBitmap->GetWidth(), + m_pBitmap->GetHeight()); + m_pContext->GetBackground(&buffer, m_pObject, NULL, &m_Matrix); + buffer.CompositeBitmap(0, 0, buffer.GetWidth(), buffer.GetHeight(), + m_pBitmap, 0, 0); + m_pDevice->StretchDIBits(&buffer, m_Rect.left, m_Rect.top, m_Rect.Width(), + m_Rect.Height()); + } +} +CPDF_ScaledRenderBuffer::CPDF_ScaledRenderBuffer() { + m_pBitmapDevice = NULL; +} +CPDF_ScaledRenderBuffer::~CPDF_ScaledRenderBuffer() { + delete m_pBitmapDevice; +} +#define _FPDFAPI_IMAGESIZE_LIMIT_ (30 * 1024 * 1024) +FX_BOOL CPDF_ScaledRenderBuffer::Initialize(CPDF_RenderContext* pContext, + CFX_RenderDevice* pDevice, + FX_RECT* pRect, + const CPDF_PageObject* pObj, + const CPDF_RenderOptions* pOptions, + int max_dpi) { + FXSYS_assert(pRect != NULL); + m_pDevice = pDevice; + if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_GET_BITS) { return TRUE; -} -void CPDF_ScaledRenderBuffer::OutputToDevice() -{ - if (m_pBitmapDevice) { - m_pDevice->StretchDIBits(m_pBitmapDevice->GetBitmap(), m_Rect.left, m_Rect.top, m_Rect.Width(), m_Rect.Height()); - } -} -FX_BOOL IPDF_OCContext::CheckObjectVisible(const CPDF_PageObject* pObj) -{ - const CPDF_ContentMarkData* pData = pObj->m_ContentMark; - int nItems = pData->CountItems(); - for (int i = 0; i < nItems; i ++) { - CPDF_ContentMarkItem& item = pData->GetItem(i); - if (item.GetName() == FX_BSTRC("OC") && item.GetParamType() == CPDF_ContentMarkItem::PropertiesDict) { - CPDF_Dictionary* pOCG = (CPDF_Dictionary*)item.GetParam(); - if (!CheckOCGVisible(pOCG)) { - return FALSE; - } - } + } + m_pContext = pContext; + m_Rect = *pRect; + m_pObject = pObj; + m_Matrix.TranslateI(-pRect->left, -pRect->top); + int horz_size = pDevice->GetDeviceCaps(FXDC_HORZ_SIZE); + int vert_size = pDevice->GetDeviceCaps(FXDC_VERT_SIZE); + if (horz_size && vert_size && max_dpi) { + int dpih = + pDevice->GetDeviceCaps(FXDC_PIXEL_WIDTH) * 254 / (horz_size * 10); + int dpiv = + pDevice->GetDeviceCaps(FXDC_PIXEL_HEIGHT) * 254 / (vert_size * 10); + if (dpih > max_dpi) { + m_Matrix.Scale((FX_FLOAT)(max_dpi) / dpih, 1.0f); + } + if (dpiv > max_dpi) { + m_Matrix.Scale(1.0f, (FX_FLOAT)(max_dpi) / (FX_FLOAT)dpiv); + } + } + m_pBitmapDevice = new CFX_FxgeDevice; + FXDIB_Format dibFormat = FXDIB_Rgb; + int32_t bpp = 24; + if (m_pDevice->GetDeviceCaps(FXDC_RENDER_CAPS) & FXRC_ALPHA_OUTPUT) { + dibFormat = FXDIB_Argb; + bpp = 32; + } + CFX_FloatRect rect; + int32_t iWidth, iHeight, iPitch; + while (1) { + rect = *pRect; + m_Matrix.TransformRect(rect); + FX_RECT bitmap_rect = rect.GetOutterRect(); + iWidth = bitmap_rect.Width(); + iHeight = bitmap_rect.Height(); + iPitch = (iWidth * bpp + 31) / 32 * 4; + if (iWidth * iHeight < 1) { + return FALSE; + } + if (iPitch * iHeight <= _FPDFAPI_IMAGESIZE_LIMIT_ && + m_pBitmapDevice->Create(iWidth, iHeight, dibFormat)) { + break; + } + m_Matrix.Scale(0.5f, 0.5f); + } + m_pContext->GetBackground(m_pBitmapDevice->GetBitmap(), m_pObject, pOptions, + &m_Matrix); + return TRUE; +} +void CPDF_ScaledRenderBuffer::OutputToDevice() { + if (m_pBitmapDevice) { + m_pDevice->StretchDIBits(m_pBitmapDevice->GetBitmap(), m_Rect.left, + m_Rect.top, m_Rect.Width(), m_Rect.Height()); + } +} +FX_BOOL IPDF_OCContext::CheckObjectVisible(const CPDF_PageObject* pObj) { + const CPDF_ContentMarkData* pData = pObj->m_ContentMark; + int nItems = pData->CountItems(); + for (int i = 0; i < nItems; i++) { + CPDF_ContentMarkItem& item = pData->GetItem(i); + if (item.GetName() == FX_BSTRC("OC") && + item.GetParamType() == CPDF_ContentMarkItem::PropertiesDict) { + CPDF_Dictionary* pOCG = (CPDF_Dictionary*)item.GetParam(); + if (!CheckOCGVisible(pOCG)) { + return FALSE; + } } - return TRUE; + } + return TRUE; } diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_cache.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_cache.cpp index cdbecd65ea..8da176e040 100644 --- a/core/src/fpdfapi/fpdf_render/fpdf_render_cache.cpp +++ b/core/src/fpdfapi/fpdf_render/fpdf_render_cache.cpp @@ -10,344 +10,361 @@ #include "../fpdf_page/pageint.h" #include "render_int.h" struct CACHEINFO { - FX_DWORD time; - CPDF_Stream* pStream; + FX_DWORD time; + CPDF_Stream* pStream; }; extern "C" { - static int compare(const void* data1, const void* data2) - { - return ((CACHEINFO*)data1)->time - ((CACHEINFO*)data2)->time; - } +static int compare(const void* data1, const void* data2) { + return ((CACHEINFO*)data1)->time - ((CACHEINFO*)data2)->time; +} }; -void CPDF_Page::ClearRenderCache() -{ - if (m_pPageRender) { - m_pPageRender->ClearAll(); - } +void CPDF_Page::ClearRenderCache() { + if (m_pPageRender) { + m_pPageRender->ClearAll(); + } } -void CPDF_PageRenderCache::ClearAll() -{ - FX_POSITION pos = m_ImageCaches.GetStartPosition(); - while (pos) { - void* key; - void* value; - m_ImageCaches.GetNextAssoc(pos, key, value); - delete (CPDF_ImageCache*)value; - } - m_ImageCaches.RemoveAll(); - m_nCacheSize = 0; - m_nTimeCount = 0; +void CPDF_PageRenderCache::ClearAll() { + FX_POSITION pos = m_ImageCaches.GetStartPosition(); + while (pos) { + void* key; + void* value; + m_ImageCaches.GetNextAssoc(pos, key, value); + delete (CPDF_ImageCache*)value; + } + m_ImageCaches.RemoveAll(); + m_nCacheSize = 0; + m_nTimeCount = 0; } -void CPDF_PageRenderCache::CacheOptimization(int32_t dwLimitCacheSize) -{ - if (m_nCacheSize <= (FX_DWORD)dwLimitCacheSize) { - return; - } - int nCount = m_ImageCaches.GetCount(); - CACHEINFO* pCACHEINFO = (CACHEINFO*)FX_Alloc2D(uint8_t, sizeof(CACHEINFO), nCount); - FX_POSITION pos = m_ImageCaches.GetStartPosition(); - int i = 0; - while (pos) { - void* key; - void* value; - m_ImageCaches.GetNextAssoc(pos, key, value); - pCACHEINFO[i].time = ((CPDF_ImageCache*)value)->GetTimeCount(); - pCACHEINFO[i++].pStream = ((CPDF_ImageCache*)value)->GetStream(); - } - FXSYS_qsort(pCACHEINFO, nCount, sizeof (CACHEINFO), compare); - FX_DWORD nTimeCount = m_nTimeCount; - if (nTimeCount + 1 < nTimeCount) { - for (i = 0; i < nCount; i ++) { - ((CPDF_ImageCache*)(m_ImageCaches[pCACHEINFO[i].pStream]))->m_dwTimeCount = i; - } - m_nTimeCount = nCount; - } - i = 0; - while(nCount > 15) { - ClearImageCache(pCACHEINFO[i++].pStream); - nCount--; - } - while (m_nCacheSize > (FX_DWORD)dwLimitCacheSize) { - ClearImageCache(pCACHEINFO[i++].pStream); - } - FX_Free(pCACHEINFO); +void CPDF_PageRenderCache::CacheOptimization(int32_t dwLimitCacheSize) { + if (m_nCacheSize <= (FX_DWORD)dwLimitCacheSize) { + return; + } + int nCount = m_ImageCaches.GetCount(); + CACHEINFO* pCACHEINFO = + (CACHEINFO*)FX_Alloc2D(uint8_t, sizeof(CACHEINFO), nCount); + FX_POSITION pos = m_ImageCaches.GetStartPosition(); + int i = 0; + while (pos) { + void* key; + void* value; + m_ImageCaches.GetNextAssoc(pos, key, value); + pCACHEINFO[i].time = ((CPDF_ImageCache*)value)->GetTimeCount(); + pCACHEINFO[i++].pStream = ((CPDF_ImageCache*)value)->GetStream(); + } + FXSYS_qsort(pCACHEINFO, nCount, sizeof(CACHEINFO), compare); + FX_DWORD nTimeCount = m_nTimeCount; + if (nTimeCount + 1 < nTimeCount) { + for (i = 0; i < nCount; i++) { + ((CPDF_ImageCache*)(m_ImageCaches[pCACHEINFO[i].pStream])) + ->m_dwTimeCount = i; + } + m_nTimeCount = nCount; + } + i = 0; + while (nCount > 15) { + ClearImageCache(pCACHEINFO[i++].pStream); + nCount--; + } + while (m_nCacheSize > (FX_DWORD)dwLimitCacheSize) { + ClearImageCache(pCACHEINFO[i++].pStream); + } + FX_Free(pCACHEINFO); } -void CPDF_PageRenderCache::ClearImageCache(CPDF_Stream* pStream) -{ - void* value = m_ImageCaches.GetValueAt(pStream); - if (value == NULL) { - m_ImageCaches.RemoveKey(pStream); - return; - } - m_nCacheSize -= ((CPDF_ImageCache*)value)->EstimateSize(); - delete (CPDF_ImageCache*)value; +void CPDF_PageRenderCache::ClearImageCache(CPDF_Stream* pStream) { + void* value = m_ImageCaches.GetValueAt(pStream); + if (value == NULL) { m_ImageCaches.RemoveKey(pStream); + return; + } + m_nCacheSize -= ((CPDF_ImageCache*)value)->EstimateSize(); + delete (CPDF_ImageCache*)value; + m_ImageCaches.RemoveKey(pStream); } -FX_DWORD CPDF_PageRenderCache::EstimateSize() -{ - FX_DWORD dwSize = 0; - FX_POSITION pos = m_ImageCaches.GetStartPosition(); - while (pos) { - void* key; - void* value; - m_ImageCaches.GetNextAssoc(pos, key, value); - dwSize += ((CPDF_ImageCache*)value)->EstimateSize(); - } - m_nCacheSize = dwSize; - return dwSize; +FX_DWORD CPDF_PageRenderCache::EstimateSize() { + FX_DWORD dwSize = 0; + FX_POSITION pos = m_ImageCaches.GetStartPosition(); + while (pos) { + void* key; + void* value; + m_ImageCaches.GetNextAssoc(pos, key, value); + dwSize += ((CPDF_ImageCache*)value)->EstimateSize(); + } + m_nCacheSize = dwSize; + return dwSize; } -FX_DWORD CPDF_PageRenderCache::GetCachedSize(CPDF_Stream* pStream) const -{ - if (pStream == NULL) { - return m_nCacheSize; - } - CPDF_ImageCache* pImageCache; - if (!m_ImageCaches.Lookup(pStream, (void*&)pImageCache)) { - return 0; - } - return pImageCache->EstimateSize(); +FX_DWORD CPDF_PageRenderCache::GetCachedSize(CPDF_Stream* pStream) const { + if (pStream == NULL) { + return m_nCacheSize; + } + CPDF_ImageCache* pImageCache; + if (!m_ImageCaches.Lookup(pStream, (void*&)pImageCache)) { + return 0; + } + return pImageCache->EstimateSize(); } -void CPDF_PageRenderCache::GetCachedBitmap(CPDF_Stream* pStream, CFX_DIBSource*& pBitmap, CFX_DIBSource*& pMask, FX_DWORD& MatteColor, - FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus, - int32_t downsampleWidth, int32_t downsampleHeight) -{ - CPDF_ImageCache* pImageCache; - FX_BOOL bFind = m_ImageCaches.Lookup(pStream, (void*&)pImageCache); - if (!bFind) { - pImageCache = new CPDF_ImageCache(m_pPage->m_pDocument, pStream); - } - m_nTimeCount ++; - FX_BOOL bCached = pImageCache->GetCachedBitmap(pBitmap, pMask, MatteColor, m_pPage->m_pPageResources, bStdCS, GroupFamily, bLoadMask, pRenderStatus, downsampleWidth, downsampleHeight); - if (!bFind) { - m_ImageCaches.SetAt(pStream, pImageCache); - } - if (!bCached) { - m_nCacheSize += pImageCache->EstimateSize(); - } +void CPDF_PageRenderCache::GetCachedBitmap(CPDF_Stream* pStream, + CFX_DIBSource*& pBitmap, + CFX_DIBSource*& pMask, + FX_DWORD& MatteColor, + FX_BOOL bStdCS, + FX_DWORD GroupFamily, + FX_BOOL bLoadMask, + CPDF_RenderStatus* pRenderStatus, + int32_t downsampleWidth, + int32_t downsampleHeight) { + CPDF_ImageCache* pImageCache; + FX_BOOL bFind = m_ImageCaches.Lookup(pStream, (void*&)pImageCache); + if (!bFind) { + pImageCache = new CPDF_ImageCache(m_pPage->m_pDocument, pStream); + } + m_nTimeCount++; + FX_BOOL bCached = pImageCache->GetCachedBitmap( + pBitmap, pMask, MatteColor, m_pPage->m_pPageResources, bStdCS, + GroupFamily, bLoadMask, pRenderStatus, downsampleWidth, downsampleHeight); + if (!bFind) { + m_ImageCaches.SetAt(pStream, pImageCache); + } + if (!bCached) { + m_nCacheSize += pImageCache->EstimateSize(); + } } -FX_BOOL CPDF_PageRenderCache::StartGetCachedBitmap(CPDF_Stream* pStream, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus, int32_t downsampleWidth, int32_t downsampleHeight) -{ - m_bCurFindCache = m_ImageCaches.Lookup(pStream, (void*&)m_pCurImageCache); - if (!m_bCurFindCache) { - m_pCurImageCache = new CPDF_ImageCache(m_pPage->m_pDocument, pStream); - } - int ret = m_pCurImageCache->StartGetCachedBitmap(pRenderStatus->m_pFormResource, m_pPage->m_pPageResources, bStdCS, GroupFamily, bLoadMask, pRenderStatus, downsampleWidth, downsampleHeight); - if (ret == 2) { - return TRUE; - } - m_nTimeCount ++; - if (!m_bCurFindCache) { - m_ImageCaches.SetAt(pStream, m_pCurImageCache); - } - if (!ret) { - m_nCacheSize += m_pCurImageCache->EstimateSize(); - } - return FALSE; +FX_BOOL CPDF_PageRenderCache::StartGetCachedBitmap( + CPDF_Stream* pStream, + FX_BOOL bStdCS, + FX_DWORD GroupFamily, + FX_BOOL bLoadMask, + CPDF_RenderStatus* pRenderStatus, + int32_t downsampleWidth, + int32_t downsampleHeight) { + m_bCurFindCache = m_ImageCaches.Lookup(pStream, (void*&)m_pCurImageCache); + if (!m_bCurFindCache) { + m_pCurImageCache = new CPDF_ImageCache(m_pPage->m_pDocument, pStream); + } + int ret = m_pCurImageCache->StartGetCachedBitmap( + pRenderStatus->m_pFormResource, m_pPage->m_pPageResources, bStdCS, + GroupFamily, bLoadMask, pRenderStatus, downsampleWidth, downsampleHeight); + if (ret == 2) { + return TRUE; + } + m_nTimeCount++; + if (!m_bCurFindCache) { + m_ImageCaches.SetAt(pStream, m_pCurImageCache); + } + if (!ret) { + m_nCacheSize += m_pCurImageCache->EstimateSize(); + } + return FALSE; } -FX_BOOL CPDF_PageRenderCache::Continue(IFX_Pause* pPause) -{ - int ret = m_pCurImageCache->Continue(pPause); - if (ret == 2) { - return TRUE; - } - m_nTimeCount ++; - if (!m_bCurFindCache) { - m_ImageCaches.SetAt(m_pCurImageCache->GetStream(), m_pCurImageCache); - } - if (!ret) { - m_nCacheSize += m_pCurImageCache->EstimateSize(); - } - return FALSE; +FX_BOOL CPDF_PageRenderCache::Continue(IFX_Pause* pPause) { + int ret = m_pCurImageCache->Continue(pPause); + if (ret == 2) { + return TRUE; + } + m_nTimeCount++; + if (!m_bCurFindCache) { + m_ImageCaches.SetAt(m_pCurImageCache->GetStream(), m_pCurImageCache); + } + if (!ret) { + m_nCacheSize += m_pCurImageCache->EstimateSize(); + } + return FALSE; } -void CPDF_PageRenderCache::ResetBitmap(CPDF_Stream* pStream, const CFX_DIBitmap* pBitmap) -{ - CPDF_ImageCache* pImageCache; - if (!m_ImageCaches.Lookup(pStream, (void*&)pImageCache)) { - if (pBitmap == NULL) { - return; - } - pImageCache = new CPDF_ImageCache(m_pPage->m_pDocument, pStream); - m_ImageCaches.SetAt(pStream, pImageCache); - } - int oldsize = pImageCache->EstimateSize(); - pImageCache->Reset(pBitmap); - m_nCacheSize = pImageCache->EstimateSize() - oldsize; +void CPDF_PageRenderCache::ResetBitmap(CPDF_Stream* pStream, + const CFX_DIBitmap* pBitmap) { + CPDF_ImageCache* pImageCache; + if (!m_ImageCaches.Lookup(pStream, (void*&)pImageCache)) { + if (pBitmap == NULL) { + return; + } + pImageCache = new CPDF_ImageCache(m_pPage->m_pDocument, pStream); + m_ImageCaches.SetAt(pStream, pImageCache); + } + int oldsize = pImageCache->EstimateSize(); + pImageCache->Reset(pBitmap); + m_nCacheSize = pImageCache->EstimateSize() - oldsize; } CPDF_ImageCache::CPDF_ImageCache(CPDF_Document* pDoc, CPDF_Stream* pStream) - : m_dwTimeCount(0) - , m_pCurBitmap(NULL) - , m_pCurMask(NULL) - , m_MatteColor(0) - , m_pRenderStatus(NULL) - , m_pDocument(pDoc) - , m_pStream(pStream) - , m_pCachedBitmap(NULL) - , m_pCachedMask(NULL) - , m_dwCacheSize(0) -{ + : m_dwTimeCount(0), + m_pCurBitmap(NULL), + m_pCurMask(NULL), + m_MatteColor(0), + m_pRenderStatus(NULL), + m_pDocument(pDoc), + m_pStream(pStream), + m_pCachedBitmap(NULL), + m_pCachedMask(NULL), + m_dwCacheSize(0) {} +CPDF_ImageCache::~CPDF_ImageCache() { + delete m_pCachedBitmap; + m_pCachedBitmap = NULL; + delete m_pCachedMask; + m_pCachedMask = NULL; } -CPDF_ImageCache::~CPDF_ImageCache() -{ - delete m_pCachedBitmap; - m_pCachedBitmap = NULL; - delete m_pCachedMask; - m_pCachedMask = NULL; +void CPDF_ImageCache::Reset(const CFX_DIBitmap* pBitmap) { + delete m_pCachedBitmap; + m_pCachedBitmap = NULL; + if (pBitmap) { + m_pCachedBitmap = pBitmap->Clone(); + } + CalcSize(); } -void CPDF_ImageCache::Reset(const CFX_DIBitmap* pBitmap) -{ - delete m_pCachedBitmap; - m_pCachedBitmap = NULL; - if (pBitmap) { - m_pCachedBitmap = pBitmap->Clone(); - } - CalcSize(); +void CPDF_PageRenderCache::ClearImageData() { + FX_POSITION pos = m_ImageCaches.GetStartPosition(); + while (pos) { + void* key; + void* value; + m_ImageCaches.GetNextAssoc(pos, key, value); + ((CPDF_ImageCache*)value)->ClearImageData(); + } } -void CPDF_PageRenderCache::ClearImageData() -{ - FX_POSITION pos = m_ImageCaches.GetStartPosition(); - while (pos) { - void* key; - void* value; - m_ImageCaches.GetNextAssoc(pos, key, value); - ((CPDF_ImageCache*)value)->ClearImageData(); - } -} -void CPDF_ImageCache::ClearImageData() -{ - if (m_pCachedBitmap && m_pCachedBitmap->GetBuffer() == NULL) { - ((CPDF_DIBSource*)m_pCachedBitmap)->ClearImageData(); - } +void CPDF_ImageCache::ClearImageData() { + if (m_pCachedBitmap && m_pCachedBitmap->GetBuffer() == NULL) { + ((CPDF_DIBSource*)m_pCachedBitmap)->ClearImageData(); + } } -static FX_DWORD FPDF_ImageCache_EstimateImageSize(const CFX_DIBSource* pDIB) -{ - return pDIB && pDIB->GetBuffer() ? (FX_DWORD)pDIB->GetHeight() * pDIB->GetPitch() + (FX_DWORD)pDIB->GetPaletteSize() * 4 : 0; +static FX_DWORD FPDF_ImageCache_EstimateImageSize(const CFX_DIBSource* pDIB) { + return pDIB && pDIB->GetBuffer() + ? (FX_DWORD)pDIB->GetHeight() * pDIB->GetPitch() + + (FX_DWORD)pDIB->GetPaletteSize() * 4 + : 0; } -FX_BOOL CPDF_ImageCache::GetCachedBitmap(CFX_DIBSource*& pBitmap, CFX_DIBSource*& pMask, FX_DWORD& MatteColor, CPDF_Dictionary* pPageResources, - FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus, - int32_t downsampleWidth, int32_t downsampleHeight) -{ - if (m_pCachedBitmap) { - pBitmap = m_pCachedBitmap; - pMask = m_pCachedMask; - MatteColor = m_MatteColor; - return TRUE; - } - if (!pRenderStatus) { - return FALSE; - } - CPDF_RenderContext*pContext = pRenderStatus->GetContext(); - CPDF_PageRenderCache* pPageRenderCache = pContext->m_pPageCache; - m_dwTimeCount = pPageRenderCache->GetTimeCount(); - CPDF_DIBSource* pSrc = new CPDF_DIBSource; - CPDF_DIBSource* pMaskSrc = NULL; - if (!pSrc->Load(m_pDocument, m_pStream, &pMaskSrc, &MatteColor, pRenderStatus->m_pFormResource, pPageResources, bStdCS, GroupFamily, bLoadMask)) { - delete pSrc; - pBitmap = NULL; - return FALSE; - } - m_MatteColor = MatteColor; - if (pSrc->GetPitch() * pSrc->GetHeight() < FPDF_HUGE_IMAGE_SIZE) { - m_pCachedBitmap = pSrc->Clone(); - delete pSrc; - } else { - m_pCachedBitmap = pSrc; - } - if (pMaskSrc) { - m_pCachedMask = pMaskSrc->Clone(); - delete pMaskSrc; - } - +FX_BOOL CPDF_ImageCache::GetCachedBitmap(CFX_DIBSource*& pBitmap, + CFX_DIBSource*& pMask, + FX_DWORD& MatteColor, + CPDF_Dictionary* pPageResources, + FX_BOOL bStdCS, + FX_DWORD GroupFamily, + FX_BOOL bLoadMask, + CPDF_RenderStatus* pRenderStatus, + int32_t downsampleWidth, + int32_t downsampleHeight) { + if (m_pCachedBitmap) { pBitmap = m_pCachedBitmap; pMask = m_pCachedMask; - CalcSize(); + MatteColor = m_MatteColor; + return TRUE; + } + if (!pRenderStatus) { + return FALSE; + } + CPDF_RenderContext* pContext = pRenderStatus->GetContext(); + CPDF_PageRenderCache* pPageRenderCache = pContext->m_pPageCache; + m_dwTimeCount = pPageRenderCache->GetTimeCount(); + CPDF_DIBSource* pSrc = new CPDF_DIBSource; + CPDF_DIBSource* pMaskSrc = NULL; + if (!pSrc->Load(m_pDocument, m_pStream, &pMaskSrc, &MatteColor, + pRenderStatus->m_pFormResource, pPageResources, bStdCS, + GroupFamily, bLoadMask)) { + delete pSrc; + pBitmap = NULL; return FALSE; + } + m_MatteColor = MatteColor; + if (pSrc->GetPitch() * pSrc->GetHeight() < FPDF_HUGE_IMAGE_SIZE) { + m_pCachedBitmap = pSrc->Clone(); + delete pSrc; + } else { + m_pCachedBitmap = pSrc; + } + if (pMaskSrc) { + m_pCachedMask = pMaskSrc->Clone(); + delete pMaskSrc; + } + + pBitmap = m_pCachedBitmap; + pMask = m_pCachedMask; + CalcSize(); + return FALSE; } -CFX_DIBSource* CPDF_ImageCache::DetachBitmap() -{ - CFX_DIBSource* pDIBSource = m_pCurBitmap; - m_pCurBitmap = NULL; - return pDIBSource; +CFX_DIBSource* CPDF_ImageCache::DetachBitmap() { + CFX_DIBSource* pDIBSource = m_pCurBitmap; + m_pCurBitmap = NULL; + return pDIBSource; } -CFX_DIBSource* CPDF_ImageCache::DetachMask() -{ - CFX_DIBSource* pDIBSource = m_pCurMask; - m_pCurMask = NULL; - return pDIBSource; +CFX_DIBSource* CPDF_ImageCache::DetachMask() { + CFX_DIBSource* pDIBSource = m_pCurMask; + m_pCurMask = NULL; + return pDIBSource; } -int CPDF_ImageCache::StartGetCachedBitmap(CPDF_Dictionary* pFormResources, CPDF_Dictionary* pPageResources, FX_BOOL bStdCS, - FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus, - int32_t downsampleWidth, int32_t downsampleHeight) -{ - if (m_pCachedBitmap) { - m_pCurBitmap = m_pCachedBitmap; - m_pCurMask = m_pCachedMask; - return 1; - } - if (!pRenderStatus) { - return 0; - } - m_pRenderStatus = pRenderStatus; - m_pCurBitmap = new CPDF_DIBSource; - int ret = ((CPDF_DIBSource*)m_pCurBitmap)->StartLoadDIBSource(m_pDocument, m_pStream, TRUE, pFormResources, pPageResources, bStdCS, GroupFamily, bLoadMask); - if (ret == 2) { - return ret; - } - if (!ret) { - delete m_pCurBitmap; - m_pCurBitmap = NULL; - return 0; - } - ContinueGetCachedBitmap(); - return 0; -} -int CPDF_ImageCache::ContinueGetCachedBitmap() -{ - m_MatteColor = ((CPDF_DIBSource*)m_pCurBitmap)->m_MatteColor; - m_pCurMask = ((CPDF_DIBSource*)m_pCurBitmap)->DetachMask(); - CPDF_RenderContext*pContext = m_pRenderStatus->GetContext(); - CPDF_PageRenderCache* pPageRenderCache = pContext->m_pPageCache; - m_dwTimeCount = pPageRenderCache->GetTimeCount(); - if (m_pCurBitmap->GetPitch() * m_pCurBitmap->GetHeight() < FPDF_HUGE_IMAGE_SIZE) { - m_pCachedBitmap = m_pCurBitmap->Clone(); - delete m_pCurBitmap; - m_pCurBitmap = NULL; - } else { - m_pCachedBitmap = m_pCurBitmap; - } - if (m_pCurMask) { - m_pCachedMask = m_pCurMask->Clone(); - delete m_pCurMask; - m_pCurMask = NULL; - } +int CPDF_ImageCache::StartGetCachedBitmap(CPDF_Dictionary* pFormResources, + CPDF_Dictionary* pPageResources, + FX_BOOL bStdCS, + FX_DWORD GroupFamily, + FX_BOOL bLoadMask, + CPDF_RenderStatus* pRenderStatus, + int32_t downsampleWidth, + int32_t downsampleHeight) { + if (m_pCachedBitmap) { m_pCurBitmap = m_pCachedBitmap; m_pCurMask = m_pCachedMask; - CalcSize(); + return 1; + } + if (!pRenderStatus) { + return 0; + } + m_pRenderStatus = pRenderStatus; + m_pCurBitmap = new CPDF_DIBSource; + int ret = + ((CPDF_DIBSource*)m_pCurBitmap) + ->StartLoadDIBSource(m_pDocument, m_pStream, TRUE, pFormResources, + pPageResources, bStdCS, GroupFamily, bLoadMask); + if (ret == 2) { + return ret; + } + if (!ret) { + delete m_pCurBitmap; + m_pCurBitmap = NULL; return 0; + } + ContinueGetCachedBitmap(); + return 0; } -int CPDF_ImageCache::Continue(IFX_Pause* pPause) -{ - int ret = ((CPDF_DIBSource*)m_pCurBitmap)->ContinueLoadDIBSource(pPause); - if (ret == 2) { - return ret; - } - if (!ret) { - delete m_pCurBitmap; - m_pCurBitmap = NULL; - return 0; - } - ContinueGetCachedBitmap(); +int CPDF_ImageCache::ContinueGetCachedBitmap() { + m_MatteColor = ((CPDF_DIBSource*)m_pCurBitmap)->m_MatteColor; + m_pCurMask = ((CPDF_DIBSource*)m_pCurBitmap)->DetachMask(); + CPDF_RenderContext* pContext = m_pRenderStatus->GetContext(); + CPDF_PageRenderCache* pPageRenderCache = pContext->m_pPageCache; + m_dwTimeCount = pPageRenderCache->GetTimeCount(); + if (m_pCurBitmap->GetPitch() * m_pCurBitmap->GetHeight() < + FPDF_HUGE_IMAGE_SIZE) { + m_pCachedBitmap = m_pCurBitmap->Clone(); + delete m_pCurBitmap; + m_pCurBitmap = NULL; + } else { + m_pCachedBitmap = m_pCurBitmap; + } + if (m_pCurMask) { + m_pCachedMask = m_pCurMask->Clone(); + delete m_pCurMask; + m_pCurMask = NULL; + } + m_pCurBitmap = m_pCachedBitmap; + m_pCurMask = m_pCachedMask; + CalcSize(); + return 0; +} +int CPDF_ImageCache::Continue(IFX_Pause* pPause) { + int ret = ((CPDF_DIBSource*)m_pCurBitmap)->ContinueLoadDIBSource(pPause); + if (ret == 2) { + return ret; + } + if (!ret) { + delete m_pCurBitmap; + m_pCurBitmap = NULL; return 0; + } + ContinueGetCachedBitmap(); + return 0; } -void CPDF_ImageCache::CalcSize() -{ - m_dwCacheSize = FPDF_ImageCache_EstimateImageSize(m_pCachedBitmap) + FPDF_ImageCache_EstimateImageSize(m_pCachedMask); +void CPDF_ImageCache::CalcSize() { + m_dwCacheSize = FPDF_ImageCache_EstimateImageSize(m_pCachedBitmap) + + FPDF_ImageCache_EstimateImageSize(m_pCachedMask); } -void CPDF_Document::ClearRenderFont() -{ - if (m_pDocRender) { - CFX_FontCache* pCache = m_pDocRender->GetFontCache(); - if (pCache) { - pCache->FreeCache(FALSE); - } +void CPDF_Document::ClearRenderFont() { + if (m_pDocRender) { + CFX_FontCache* pCache = m_pDocRender->GetFontCache(); + if (pCache) { + pCache->FreeCache(FALSE); } + } } diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_image.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_image.cpp index fa9325a4d2..987ffd88d4 100644 --- a/core/src/fpdfapi/fpdf_render/fpdf_render_image.cpp +++ b/core/src/fpdfapi/fpdf_render/fpdf_render_image.cpp @@ -13,1069 +13,1160 @@ #include "../fpdf_page/pageint.h" #include "render_int.h" -FX_BOOL CPDF_RenderStatus::ProcessImage(CPDF_ImageObject* pImageObj, const CFX_AffineMatrix* pObj2Device) -{ - CPDF_ImageRenderer render; - if (render.Start(this, pImageObj, pObj2Device, m_bStdCS, m_curBlend)) { - render.Continue(NULL); - } - return render.m_Result; +FX_BOOL CPDF_RenderStatus::ProcessImage(CPDF_ImageObject* pImageObj, + const CFX_AffineMatrix* pObj2Device) { + CPDF_ImageRenderer render; + if (render.Start(this, pImageObj, pObj2Device, m_bStdCS, m_curBlend)) { + render.Continue(NULL); + } + return render.m_Result; } -void CPDF_RenderStatus::CompositeDIBitmap(CFX_DIBitmap* pDIBitmap, int left, int top, FX_ARGB mask_argb, - int bitmap_alpha, int blend_mode, int Transparency) -{ - if (pDIBitmap == NULL) { +void CPDF_RenderStatus::CompositeDIBitmap(CFX_DIBitmap* pDIBitmap, + int left, + int top, + FX_ARGB mask_argb, + int bitmap_alpha, + int blend_mode, + int Transparency) { + if (pDIBitmap == NULL) { + return; + } + FX_BOOL bIsolated = Transparency & PDFTRANS_ISOLATED; + FX_BOOL bGroup = Transparency & PDFTRANS_GROUP; + if (blend_mode == FXDIB_BLEND_NORMAL) { + if (!pDIBitmap->IsAlphaMask()) { + if (bitmap_alpha < 255) { + pDIBitmap->MultiplyAlpha(bitmap_alpha); + } + if (m_pDevice->SetDIBits(pDIBitmap, left, top)) { return; - } - FX_BOOL bIsolated = Transparency & PDFTRANS_ISOLATED; - FX_BOOL bGroup = Transparency & PDFTRANS_GROUP; - if (blend_mode == FXDIB_BLEND_NORMAL) { - if (!pDIBitmap->IsAlphaMask()) { - if (bitmap_alpha < 255) { - pDIBitmap->MultiplyAlpha(bitmap_alpha); - } - if (m_pDevice->SetDIBits(pDIBitmap, left, top)) { - return; - } - } else { - FX_DWORD fill_argb = m_Options.TranslateColor(mask_argb); - if (bitmap_alpha < 255) { - ((uint8_t*)&fill_argb)[3] = ((uint8_t*)&fill_argb)[3] * bitmap_alpha / 255; - } - if (m_pDevice->SetBitMask(pDIBitmap, left, top, fill_argb)) { - return; - } - } - } - FX_BOOL bBackAlphaRequired = blend_mode && bIsolated && !m_bDropObjects; - FX_BOOL bGetBackGround = ((m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT)) || - (!(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT) && (m_pDevice->GetRenderCaps() - & FXRC_GET_BITS) && !bBackAlphaRequired); - if (bGetBackGround) { - if (bIsolated || !bGroup) { - if (pDIBitmap->IsAlphaMask()) { - return; - } - m_pDevice->SetDIBits(pDIBitmap, left, top, blend_mode); - } else { - FX_RECT rect(left, top, left + pDIBitmap->GetWidth(), top + pDIBitmap->GetHeight()); - rect.Intersect(m_pDevice->GetClipBox()); - CFX_DIBitmap* pClone = NULL; - FX_BOOL bClone = FALSE; - if (m_pDevice->GetBackDrop() && m_pDevice->GetBitmap()) { - bClone = TRUE; - pClone = m_pDevice->GetBackDrop()->Clone(&rect); - CFX_DIBitmap *pForeBitmap = m_pDevice->GetBitmap(); - pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(), pForeBitmap, rect.left, rect.top); - left = left >= 0 ? 0 : left; - top = top >= 0 ? 0 : top; - if (!pDIBitmap->IsAlphaMask()) - pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(), pDIBitmap, - left, top, blend_mode); - else - pClone->CompositeMask(0, 0, pClone->GetWidth(), pClone->GetHeight(), pDIBitmap, - mask_argb, left, top, blend_mode); - } else { - pClone = pDIBitmap; - } - if (m_pDevice->GetBackDrop()) { - m_pDevice->SetDIBits(pClone, rect.left, rect.top); - } else { - if (pDIBitmap->IsAlphaMask()) { - return; - } - m_pDevice->SetDIBits(pDIBitmap, rect.left, rect.top, blend_mode); - } - if (bClone) { - delete pClone; - } - } + } + } else { + FX_DWORD fill_argb = m_Options.TranslateColor(mask_argb); + if (bitmap_alpha < 255) { + ((uint8_t*)&fill_argb)[3] = + ((uint8_t*)&fill_argb)[3] * bitmap_alpha / 255; + } + if (m_pDevice->SetBitMask(pDIBitmap, left, top, fill_argb)) { return; - } - int back_left, back_top; - FX_RECT rect(left, top, left + pDIBitmap->GetWidth(), top + pDIBitmap->GetHeight()); - CFX_DIBitmap* pBackdrop = GetBackdrop(m_pCurObj, rect, back_left, back_top, blend_mode > FXDIB_BLEND_NORMAL && bIsolated); - if (!pBackdrop) { + } + } + } + FX_BOOL bBackAlphaRequired = blend_mode && bIsolated && !m_bDropObjects; + FX_BOOL bGetBackGround = + ((m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT)) || + (!(m_pDevice->GetRenderCaps() & FXRC_ALPHA_OUTPUT) && + (m_pDevice->GetRenderCaps() & FXRC_GET_BITS) && !bBackAlphaRequired); + if (bGetBackGround) { + if (bIsolated || !bGroup) { + if (pDIBitmap->IsAlphaMask()) { return; - } - if (!pDIBitmap->IsAlphaMask()) - pBackdrop->CompositeBitmap(left - back_left, top - back_top, pDIBitmap->GetWidth(), pDIBitmap->GetHeight(), pDIBitmap, - 0, 0, blend_mode); - else - pBackdrop->CompositeMask(left - back_left, top - back_top, pDIBitmap->GetWidth(), pDIBitmap->GetHeight(), pDIBitmap, - mask_argb, 0, 0, blend_mode); - CFX_DIBitmap* pBackdrop1 = new CFX_DIBitmap; - pBackdrop1->Create(pBackdrop->GetWidth(), pBackdrop->GetHeight(), FXDIB_Rgb32); - pBackdrop1->Clear((FX_DWORD) - 1); - pBackdrop1->CompositeBitmap(0, 0, pBackdrop->GetWidth(), pBackdrop->GetHeight(), pBackdrop, 0, 0); - delete pBackdrop; - pBackdrop = pBackdrop1; - m_pDevice->SetDIBits(pBackdrop, back_left, back_top); - delete pBackdrop; + } + m_pDevice->SetDIBits(pDIBitmap, left, top, blend_mode); + } else { + FX_RECT rect(left, top, left + pDIBitmap->GetWidth(), + top + pDIBitmap->GetHeight()); + rect.Intersect(m_pDevice->GetClipBox()); + CFX_DIBitmap* pClone = NULL; + FX_BOOL bClone = FALSE; + if (m_pDevice->GetBackDrop() && m_pDevice->GetBitmap()) { + bClone = TRUE; + pClone = m_pDevice->GetBackDrop()->Clone(&rect); + CFX_DIBitmap* pForeBitmap = m_pDevice->GetBitmap(); + pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(), + pForeBitmap, rect.left, rect.top); + left = left >= 0 ? 0 : left; + top = top >= 0 ? 0 : top; + if (!pDIBitmap->IsAlphaMask()) + pClone->CompositeBitmap(0, 0, pClone->GetWidth(), pClone->GetHeight(), + pDIBitmap, left, top, blend_mode); + else + pClone->CompositeMask(0, 0, pClone->GetWidth(), pClone->GetHeight(), + pDIBitmap, mask_argb, left, top, blend_mode); + } else { + pClone = pDIBitmap; + } + if (m_pDevice->GetBackDrop()) { + m_pDevice->SetDIBits(pClone, rect.left, rect.top); + } else { + if (pDIBitmap->IsAlphaMask()) { + return; + } + m_pDevice->SetDIBits(pDIBitmap, rect.left, rect.top, blend_mode); + } + if (bClone) { + delete pClone; + } + } + return; + } + int back_left, back_top; + FX_RECT rect(left, top, left + pDIBitmap->GetWidth(), + top + pDIBitmap->GetHeight()); + CFX_DIBitmap* pBackdrop = + GetBackdrop(m_pCurObj, rect, back_left, back_top, + blend_mode > FXDIB_BLEND_NORMAL && bIsolated); + if (!pBackdrop) { + return; + } + if (!pDIBitmap->IsAlphaMask()) + pBackdrop->CompositeBitmap(left - back_left, top - back_top, + pDIBitmap->GetWidth(), pDIBitmap->GetHeight(), + pDIBitmap, 0, 0, blend_mode); + else + pBackdrop->CompositeMask(left - back_left, top - back_top, + pDIBitmap->GetWidth(), pDIBitmap->GetHeight(), + pDIBitmap, mask_argb, 0, 0, blend_mode); + CFX_DIBitmap* pBackdrop1 = new CFX_DIBitmap; + pBackdrop1->Create(pBackdrop->GetWidth(), pBackdrop->GetHeight(), + FXDIB_Rgb32); + pBackdrop1->Clear((FX_DWORD)-1); + pBackdrop1->CompositeBitmap(0, 0, pBackdrop->GetWidth(), + pBackdrop->GetHeight(), pBackdrop, 0, 0); + delete pBackdrop; + pBackdrop = pBackdrop1; + m_pDevice->SetDIBits(pBackdrop, back_left, back_top); + delete pBackdrop; } -FX_COLORREF CPDF_TransferFunc::TranslateColor(FX_COLORREF rgb) -{ - return FXSYS_RGB(m_Samples[FXSYS_GetRValue(rgb)], m_Samples[256 + FXSYS_GetGValue(rgb)], - m_Samples[512 + FXSYS_GetBValue(rgb)]); +FX_COLORREF CPDF_TransferFunc::TranslateColor(FX_COLORREF rgb) { + return FXSYS_RGB(m_Samples[FXSYS_GetRValue(rgb)], + m_Samples[256 + FXSYS_GetGValue(rgb)], + m_Samples[512 + FXSYS_GetBValue(rgb)]); } -CFX_DIBSource* CPDF_TransferFunc::TranslateImage(const CFX_DIBSource* pSrc, FX_BOOL bAutoDropSrc) -{ - CPDF_DIBTransferFunc* pDest = new CPDF_DIBTransferFunc(this); - pDest->LoadSrc(pSrc, bAutoDropSrc); - return pDest; +CFX_DIBSource* CPDF_TransferFunc::TranslateImage(const CFX_DIBSource* pSrc, + FX_BOOL bAutoDropSrc) { + CPDF_DIBTransferFunc* pDest = new CPDF_DIBTransferFunc(this); + pDest->LoadSrc(pSrc, bAutoDropSrc); + return pDest; } -FXDIB_Format CPDF_DIBTransferFunc::GetDestFormat() -{ - if (m_pSrc->IsAlphaMask()) { - return FXDIB_8bppMask; - } -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - return (m_pSrc->HasAlpha()) ? FXDIB_Argb : FXDIB_Rgb32; +FXDIB_Format CPDF_DIBTransferFunc::GetDestFormat() { + if (m_pSrc->IsAlphaMask()) { + return FXDIB_8bppMask; + } +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + return (m_pSrc->HasAlpha()) ? FXDIB_Argb : FXDIB_Rgb32; #else - return (m_pSrc->HasAlpha()) ? FXDIB_Argb : FXDIB_Rgb; + return (m_pSrc->HasAlpha()) ? FXDIB_Argb : FXDIB_Rgb; #endif } -CPDF_DIBTransferFunc::CPDF_DIBTransferFunc(const CPDF_TransferFunc* pTransferFunc) -{ - m_RampR = pTransferFunc->m_Samples; - m_RampG = &pTransferFunc->m_Samples[256]; - m_RampB = &pTransferFunc->m_Samples[512]; +CPDF_DIBTransferFunc::CPDF_DIBTransferFunc( + const CPDF_TransferFunc* pTransferFunc) { + m_RampR = pTransferFunc->m_Samples; + m_RampG = &pTransferFunc->m_Samples[256]; + m_RampB = &pTransferFunc->m_Samples[512]; } -void CPDF_DIBTransferFunc::TranslateScanline(uint8_t* dest_buf, const uint8_t* src_buf) const -{ - int i; - FX_BOOL bSkip = FALSE; - switch (m_pSrc->GetFormat()) { - case FXDIB_1bppRgb: { - int r0 = m_RampR[0], g0 = m_RampG[0], b0 = m_RampB[0]; - int r1 = m_RampR[255], g1 = m_RampG[255], b1 = m_RampB[255]; - for (i = 0; i < m_Width; i ++) { - if (src_buf[i / 8] & (1 << (7 - i % 8))) { - *dest_buf++ = b1; - *dest_buf++ = g1; - *dest_buf++ = r1; - } else { - *dest_buf++ = b0; - *dest_buf++ = g0; - *dest_buf++ = r0; - } -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - dest_buf++; -#endif - } - break; - } - case FXDIB_1bppMask: { - int m0 = m_RampR[0], m1 = m_RampR[255]; - for (i = 0; i < m_Width; i ++) { - if (src_buf[i / 8] & (1 << (7 - i % 8))) { - *dest_buf++ = m1; - } else { - *dest_buf++ = m0; - } - } - break; - } - case FXDIB_8bppRgb: { - FX_ARGB* pPal = m_pSrc->GetPalette(); - for (i = 0; i < m_Width; i ++) { - if (pPal) { - FX_ARGB src_argb = pPal[*src_buf]; - *dest_buf++ = m_RampB[FXARGB_R(src_argb)]; - *dest_buf++ = m_RampG[FXARGB_G(src_argb)]; - *dest_buf++ = m_RampR[FXARGB_B(src_argb)]; - } else { - FX_DWORD src_byte = *src_buf; - *dest_buf++ = m_RampB[src_byte]; - *dest_buf++ = m_RampG[src_byte]; - *dest_buf++ = m_RampR[src_byte]; - } - src_buf ++; -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - dest_buf++; +void CPDF_DIBTransferFunc::TranslateScanline(uint8_t* dest_buf, + const uint8_t* src_buf) const { + int i; + FX_BOOL bSkip = FALSE; + switch (m_pSrc->GetFormat()) { + case FXDIB_1bppRgb: { + int r0 = m_RampR[0], g0 = m_RampG[0], b0 = m_RampB[0]; + int r1 = m_RampR[255], g1 = m_RampG[255], b1 = m_RampB[255]; + for (i = 0; i < m_Width; i++) { + if (src_buf[i / 8] & (1 << (7 - i % 8))) { + *dest_buf++ = b1; + *dest_buf++ = g1; + *dest_buf++ = r1; + } else { + *dest_buf++ = b0; + *dest_buf++ = g0; + *dest_buf++ = r0; + } +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + dest_buf++; #endif - } - break; - } - case FXDIB_8bppMask: - for (i = 0; i < m_Width; i ++) { - *dest_buf++ = m_RampR[*(src_buf++)]; - } - break; - case FXDIB_Rgb: - for (i = 0; i < m_Width; i ++) { - *dest_buf++ = m_RampB[*(src_buf++)]; - *dest_buf++ = m_RampG[*(src_buf++)]; - *dest_buf++ = m_RampR[*(src_buf++)]; -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - dest_buf++; + } + break; + } + case FXDIB_1bppMask: { + int m0 = m_RampR[0], m1 = m_RampR[255]; + for (i = 0; i < m_Width; i++) { + if (src_buf[i / 8] & (1 << (7 - i % 8))) { + *dest_buf++ = m1; + } else { + *dest_buf++ = m0; + } + } + break; + } + case FXDIB_8bppRgb: { + FX_ARGB* pPal = m_pSrc->GetPalette(); + for (i = 0; i < m_Width; i++) { + if (pPal) { + FX_ARGB src_argb = pPal[*src_buf]; + *dest_buf++ = m_RampB[FXARGB_R(src_argb)]; + *dest_buf++ = m_RampG[FXARGB_G(src_argb)]; + *dest_buf++ = m_RampR[FXARGB_B(src_argb)]; + } else { + FX_DWORD src_byte = *src_buf; + *dest_buf++ = m_RampB[src_byte]; + *dest_buf++ = m_RampG[src_byte]; + *dest_buf++ = m_RampR[src_byte]; + } + src_buf++; +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + dest_buf++; #endif - } - break; - case FXDIB_Rgb32: - bSkip = TRUE; - case FXDIB_Argb: - for (i = 0; i < m_Width; i ++) { - *dest_buf++ = m_RampB[*(src_buf++)]; - *dest_buf++ = m_RampG[*(src_buf++)]; - *dest_buf++ = m_RampR[*(src_buf++)]; - if (!bSkip) { - *dest_buf++ = *src_buf; - } -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - else { - dest_buf++; - } + } + break; + } + case FXDIB_8bppMask: + for (i = 0; i < m_Width; i++) { + *dest_buf++ = m_RampR[*(src_buf++)]; + } + break; + case FXDIB_Rgb: + for (i = 0; i < m_Width; i++) { + *dest_buf++ = m_RampB[*(src_buf++)]; + *dest_buf++ = m_RampG[*(src_buf++)]; + *dest_buf++ = m_RampR[*(src_buf++)]; +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + dest_buf++; #endif - src_buf ++; - } - break; - default: - break; - } -} -void CPDF_DIBTransferFunc::TranslateDownSamples(uint8_t* dest_buf, const uint8_t* src_buf, int pixels, int Bpp) const -{ - if (Bpp == 8) { - for (int i = 0; i < pixels; i ++) { - *dest_buf++ = m_RampR[*(src_buf++)]; + } + break; + case FXDIB_Rgb32: + bSkip = TRUE; + case FXDIB_Argb: + for (i = 0; i < m_Width; i++) { + *dest_buf++ = m_RampB[*(src_buf++)]; + *dest_buf++ = m_RampG[*(src_buf++)]; + *dest_buf++ = m_RampR[*(src_buf++)]; + if (!bSkip) { + *dest_buf++ = *src_buf; } - } else if (Bpp == 24) { - for (int i = 0; i < pixels; i ++) { - *dest_buf++ = m_RampB[*(src_buf++)]; - *dest_buf++ = m_RampG[*(src_buf++)]; - *dest_buf++ = m_RampR[*(src_buf++)]; +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + else { + dest_buf++; } - } else { -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - if (!m_pSrc->HasAlpha()) { - for (int i = 0; i < pixels; i ++) { - *dest_buf++ = m_RampB[*(src_buf++)]; - *dest_buf++ = m_RampG[*(src_buf++)]; - *dest_buf++ = m_RampR[*(src_buf++)]; - dest_buf++; - src_buf++; - } - } else #endif - for (int i = 0; i < pixels; i ++) { - *dest_buf++ = m_RampB[*(src_buf++)]; - *dest_buf++ = m_RampG[*(src_buf++)]; - *dest_buf++ = m_RampR[*(src_buf++)]; - *dest_buf++ = *(src_buf++); - } - } + src_buf++; + } + break; + default: + break; + } } -static FX_BOOL _IsSupported(CPDF_ColorSpace* pCS) -{ - if (pCS->GetFamily() == PDFCS_DEVICERGB || pCS->GetFamily() == PDFCS_DEVICEGRAY || - pCS->GetFamily() == PDFCS_DEVICECMYK || pCS->GetFamily() == PDFCS_CALGRAY || - pCS->GetFamily() == PDFCS_CALRGB) { - return TRUE; - } - if (pCS->GetFamily() == PDFCS_INDEXED && _IsSupported(pCS->GetBaseCS())) { - return TRUE; - } - return FALSE; +void CPDF_DIBTransferFunc::TranslateDownSamples(uint8_t* dest_buf, + const uint8_t* src_buf, + int pixels, + int Bpp) const { + if (Bpp == 8) { + for (int i = 0; i < pixels; i++) { + *dest_buf++ = m_RampR[*(src_buf++)]; + } + } else if (Bpp == 24) { + for (int i = 0; i < pixels; i++) { + *dest_buf++ = m_RampB[*(src_buf++)]; + *dest_buf++ = m_RampG[*(src_buf++)]; + *dest_buf++ = m_RampR[*(src_buf++)]; + } + } else { +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (!m_pSrc->HasAlpha()) { + for (int i = 0; i < pixels; i++) { + *dest_buf++ = m_RampB[*(src_buf++)]; + *dest_buf++ = m_RampG[*(src_buf++)]; + *dest_buf++ = m_RampR[*(src_buf++)]; + dest_buf++; + src_buf++; + } + } else +#endif + for (int i = 0; i < pixels; i++) { + *dest_buf++ = m_RampB[*(src_buf++)]; + *dest_buf++ = m_RampG[*(src_buf++)]; + *dest_buf++ = m_RampR[*(src_buf++)]; + *dest_buf++ = *(src_buf++); + } + } } -CPDF_ImageRenderer::CPDF_ImageRenderer() -{ - m_pRenderStatus = NULL; - m_pImageObject = NULL; - m_Result = TRUE; - m_Status = 0; - m_pQuickStretcher = NULL; - m_pTransformer = NULL; - m_DeviceHandle = NULL; - m_LoadHandle = NULL; - m_pClone = NULL; - m_bStdCS = FALSE; - m_bPatternColor = FALSE; - m_BlendType = FXDIB_BLEND_NORMAL; - m_pPattern = NULL; - m_pObj2Device = NULL; +static FX_BOOL _IsSupported(CPDF_ColorSpace* pCS) { + if (pCS->GetFamily() == PDFCS_DEVICERGB || + pCS->GetFamily() == PDFCS_DEVICEGRAY || + pCS->GetFamily() == PDFCS_DEVICECMYK || + pCS->GetFamily() == PDFCS_CALGRAY || pCS->GetFamily() == PDFCS_CALRGB) { + return TRUE; + } + if (pCS->GetFamily() == PDFCS_INDEXED && _IsSupported(pCS->GetBaseCS())) { + return TRUE; + } + return FALSE; } -CPDF_ImageRenderer::~CPDF_ImageRenderer() -{ - delete m_pQuickStretcher; - delete m_pTransformer; - if (m_DeviceHandle) { - m_pRenderStatus->m_pDevice->CancelDIBits(m_DeviceHandle); - } - delete (CPDF_ProgressiveImageLoaderHandle*)m_LoadHandle; - delete m_pClone; +CPDF_ImageRenderer::CPDF_ImageRenderer() { + m_pRenderStatus = NULL; + m_pImageObject = NULL; + m_Result = TRUE; + m_Status = 0; + m_pQuickStretcher = NULL; + m_pTransformer = NULL; + m_DeviceHandle = NULL; + m_LoadHandle = NULL; + m_pClone = NULL; + m_bStdCS = FALSE; + m_bPatternColor = FALSE; + m_BlendType = FXDIB_BLEND_NORMAL; + m_pPattern = NULL; + m_pObj2Device = NULL; } -FX_BOOL CPDF_ImageRenderer::StartLoadDIBSource() -{ - CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect(); - FX_RECT image_rect = image_rect_f.GetOutterRect(); - int dest_width = image_rect.Width(); - int dest_height = image_rect.Height(); - if (m_ImageMatrix.a < 0) { - dest_width = -dest_width; - } - if (m_ImageMatrix.d > 0) { - dest_height = -dest_height; - } - if (m_Loader.StartLoadImage(m_pImageObject, m_pRenderStatus->m_pContext->m_pPageCache, m_LoadHandle, m_bStdCS, - m_pRenderStatus->m_GroupFamily, m_pRenderStatus->m_bLoadMask, m_pRenderStatus, dest_width, dest_height)) { - if (m_LoadHandle != NULL) { - m_Status = 4; - return TRUE; - } - return FALSE; +CPDF_ImageRenderer::~CPDF_ImageRenderer() { + delete m_pQuickStretcher; + delete m_pTransformer; + if (m_DeviceHandle) { + m_pRenderStatus->m_pDevice->CancelDIBits(m_DeviceHandle); + } + delete (CPDF_ProgressiveImageLoaderHandle*)m_LoadHandle; + delete m_pClone; +} +FX_BOOL CPDF_ImageRenderer::StartLoadDIBSource() { + CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect(); + FX_RECT image_rect = image_rect_f.GetOutterRect(); + int dest_width = image_rect.Width(); + int dest_height = image_rect.Height(); + if (m_ImageMatrix.a < 0) { + dest_width = -dest_width; + } + if (m_ImageMatrix.d > 0) { + dest_height = -dest_height; + } + if (m_Loader.StartLoadImage( + m_pImageObject, m_pRenderStatus->m_pContext->m_pPageCache, + m_LoadHandle, m_bStdCS, m_pRenderStatus->m_GroupFamily, + m_pRenderStatus->m_bLoadMask, m_pRenderStatus, dest_width, + dest_height)) { + if (m_LoadHandle != NULL) { + m_Status = 4; + return TRUE; } return FALSE; + } + return FALSE; } -FX_BOOL CPDF_ImageRenderer::StartRenderDIBSource() -{ - if (m_Loader.m_pBitmap == NULL) { - return FALSE; - } - m_BitmapAlpha = 255; - const CPDF_GeneralStateData* pGeneralState = m_pImageObject->m_GeneralState; - if (pGeneralState) { - m_BitmapAlpha = FXSYS_round(pGeneralState->m_FillAlpha * 255); - } - m_pDIBSource = m_Loader.m_pBitmap; - if (m_pRenderStatus->m_Options.m_ColorMode == RENDER_COLOR_ALPHA && m_Loader.m_pMask == NULL) { - return StartBitmapAlpha(); - } - if (pGeneralState && pGeneralState->m_pTR) { - if (!pGeneralState->m_pTransferFunc) { - ((CPDF_GeneralStateData*)pGeneralState)->m_pTransferFunc = m_pRenderStatus->GetTransferFunc(pGeneralState->m_pTR); - } - if (pGeneralState->m_pTransferFunc && !pGeneralState->m_pTransferFunc->m_bIdentity) { - m_pDIBSource = m_Loader.m_pBitmap = pGeneralState->m_pTransferFunc->TranslateImage(m_Loader.m_pBitmap, !m_Loader.m_bCached); - if (m_Loader.m_bCached && m_Loader.m_pMask) { - m_Loader.m_pMask = m_Loader.m_pMask->Clone(); - } - m_Loader.m_bCached = FALSE; - } - } - m_FillArgb = 0; - m_bPatternColor = FALSE; - m_pPattern = NULL; - if (m_pDIBSource->IsAlphaMask()) { - CPDF_Color* pColor = m_pImageObject->m_ColorState.GetFillColor(); - if (pColor && pColor->IsPattern()) { - m_pPattern = pColor->GetPattern(); - if (m_pPattern != NULL) { - m_bPatternColor = TRUE; - } - } - m_FillArgb = m_pRenderStatus->GetFillArgb(m_pImageObject); - } else if (m_pRenderStatus->m_Options.m_ColorMode == RENDER_COLOR_GRAY) { - m_pClone = m_pDIBSource->Clone(); - m_pClone->ConvertColorScale(m_pRenderStatus->m_Options.m_BackColor, m_pRenderStatus->m_Options.m_ForeColor); - m_pDIBSource = m_pClone; - } - m_Flags = 0; - if (m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_DOWNSAMPLE) { - m_Flags |= RENDER_FORCE_DOWNSAMPLE; - } else if (m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_HALFTONE) { - m_Flags |= RENDER_FORCE_HALFTONE; - } - if (m_pRenderStatus->m_pDevice->GetDeviceClass() != FXDC_DISPLAY) { - CPDF_Object* pFilters = m_pImageObject->m_pImage->GetStream()->GetDict()->GetElementValue(FX_BSTRC("Filter")); - if (pFilters) { - if (pFilters->GetType() == PDFOBJ_NAME) { - CFX_ByteStringC bsDecodeType = pFilters->GetConstString(); - if (bsDecodeType == FX_BSTRC("DCTDecode") || bsDecodeType == FX_BSTRC("JPXDecode")) { - m_Flags |= FXRENDER_IMAGE_LOSSY; - } - } else if (pFilters->GetType() == PDFOBJ_ARRAY) { - CPDF_Array* pArray = (CPDF_Array*)pFilters; - for (FX_DWORD i = 0; i < pArray->GetCount(); i ++) { - CFX_ByteStringC bsDecodeType = pArray->GetConstString(i); - if (bsDecodeType == FX_BSTRC("DCTDecode") || bsDecodeType == FX_BSTRC("JPXDecode")) { - m_Flags |= FXRENDER_IMAGE_LOSSY; - break; - } - } - } - } - } - if (m_pRenderStatus->m_Options.m_Flags & RENDER_NOIMAGESMOOTH) { - m_Flags |= FXDIB_NOSMOOTH; - } else if (m_pImageObject->m_pImage->IsInterpol()) { - m_Flags |= FXDIB_INTERPOL; - } - if (m_Loader.m_pMask) { - return DrawMaskedImage(); - } - if (m_bPatternColor) { - return DrawPatternImage(m_pObj2Device); - } - if (m_BitmapAlpha == 255 && pGeneralState && pGeneralState->m_FillOP && - pGeneralState->m_OPMode == 0 && pGeneralState->m_BlendType == FXDIB_BLEND_NORMAL && pGeneralState->m_StrokeAlpha == 1 && pGeneralState->m_FillAlpha == 1) { - CPDF_Document* pDocument = NULL; - CPDF_Page* pPage = NULL; - if (m_pRenderStatus->m_pContext->m_pPageCache) { - pPage = m_pRenderStatus->m_pContext->m_pPageCache->GetPage(); - pDocument = pPage->m_pDocument; - } else { - pDocument = m_pImageObject->m_pImage->GetDocument(); +FX_BOOL CPDF_ImageRenderer::StartRenderDIBSource() { + if (m_Loader.m_pBitmap == NULL) { + return FALSE; + } + m_BitmapAlpha = 255; + const CPDF_GeneralStateData* pGeneralState = m_pImageObject->m_GeneralState; + if (pGeneralState) { + m_BitmapAlpha = FXSYS_round(pGeneralState->m_FillAlpha * 255); + } + m_pDIBSource = m_Loader.m_pBitmap; + if (m_pRenderStatus->m_Options.m_ColorMode == RENDER_COLOR_ALPHA && + m_Loader.m_pMask == NULL) { + return StartBitmapAlpha(); + } + if (pGeneralState && pGeneralState->m_pTR) { + if (!pGeneralState->m_pTransferFunc) { + ((CPDF_GeneralStateData*)pGeneralState)->m_pTransferFunc = + m_pRenderStatus->GetTransferFunc(pGeneralState->m_pTR); + } + if (pGeneralState->m_pTransferFunc && + !pGeneralState->m_pTransferFunc->m_bIdentity) { + m_pDIBSource = m_Loader.m_pBitmap = + pGeneralState->m_pTransferFunc->TranslateImage(m_Loader.m_pBitmap, + !m_Loader.m_bCached); + if (m_Loader.m_bCached && m_Loader.m_pMask) { + m_Loader.m_pMask = m_Loader.m_pMask->Clone(); + } + m_Loader.m_bCached = FALSE; + } + } + m_FillArgb = 0; + m_bPatternColor = FALSE; + m_pPattern = NULL; + if (m_pDIBSource->IsAlphaMask()) { + CPDF_Color* pColor = m_pImageObject->m_ColorState.GetFillColor(); + if (pColor && pColor->IsPattern()) { + m_pPattern = pColor->GetPattern(); + if (m_pPattern != NULL) { + m_bPatternColor = TRUE; + } + } + m_FillArgb = m_pRenderStatus->GetFillArgb(m_pImageObject); + } else if (m_pRenderStatus->m_Options.m_ColorMode == RENDER_COLOR_GRAY) { + m_pClone = m_pDIBSource->Clone(); + m_pClone->ConvertColorScale(m_pRenderStatus->m_Options.m_BackColor, + m_pRenderStatus->m_Options.m_ForeColor); + m_pDIBSource = m_pClone; + } + m_Flags = 0; + if (m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_DOWNSAMPLE) { + m_Flags |= RENDER_FORCE_DOWNSAMPLE; + } else if (m_pRenderStatus->m_Options.m_Flags & RENDER_FORCE_HALFTONE) { + m_Flags |= RENDER_FORCE_HALFTONE; + } + if (m_pRenderStatus->m_pDevice->GetDeviceClass() != FXDC_DISPLAY) { + CPDF_Object* pFilters = + m_pImageObject->m_pImage->GetStream()->GetDict()->GetElementValue( + FX_BSTRC("Filter")); + if (pFilters) { + if (pFilters->GetType() == PDFOBJ_NAME) { + CFX_ByteStringC bsDecodeType = pFilters->GetConstString(); + if (bsDecodeType == FX_BSTRC("DCTDecode") || + bsDecodeType == FX_BSTRC("JPXDecode")) { + m_Flags |= FXRENDER_IMAGE_LOSSY; } - CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : NULL; - CPDF_Object* pCSObj = m_pImageObject->m_pImage->GetStream()->GetDict()->GetElementValue(FX_BSTRC("ColorSpace")); - CPDF_ColorSpace* pColorSpace = pDocument->LoadColorSpace(pCSObj, pPageResources); - if (pColorSpace) { - int format = pColorSpace->GetFamily(); - if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION || format == PDFCS_DEVICEN) { - m_BlendType = FXDIB_BLEND_DARKEN; - } - pDocument->GetPageData()->ReleaseColorSpace(pCSObj); + } else if (pFilters->GetType() == PDFOBJ_ARRAY) { + CPDF_Array* pArray = (CPDF_Array*)pFilters; + for (FX_DWORD i = 0; i < pArray->GetCount(); i++) { + CFX_ByteStringC bsDecodeType = pArray->GetConstString(i); + if (bsDecodeType == FX_BSTRC("DCTDecode") || + bsDecodeType == FX_BSTRC("JPXDecode")) { + m_Flags |= FXRENDER_IMAGE_LOSSY; + break; + } } - } - return StartDIBSource(); + } + } + } + if (m_pRenderStatus->m_Options.m_Flags & RENDER_NOIMAGESMOOTH) { + m_Flags |= FXDIB_NOSMOOTH; + } else if (m_pImageObject->m_pImage->IsInterpol()) { + m_Flags |= FXDIB_INTERPOL; + } + if (m_Loader.m_pMask) { + return DrawMaskedImage(); + } + if (m_bPatternColor) { + return DrawPatternImage(m_pObj2Device); + } + if (m_BitmapAlpha == 255 && pGeneralState && pGeneralState->m_FillOP && + pGeneralState->m_OPMode == 0 && + pGeneralState->m_BlendType == FXDIB_BLEND_NORMAL && + pGeneralState->m_StrokeAlpha == 1 && pGeneralState->m_FillAlpha == 1) { + CPDF_Document* pDocument = NULL; + CPDF_Page* pPage = NULL; + if (m_pRenderStatus->m_pContext->m_pPageCache) { + pPage = m_pRenderStatus->m_pContext->m_pPageCache->GetPage(); + pDocument = pPage->m_pDocument; + } else { + pDocument = m_pImageObject->m_pImage->GetDocument(); + } + CPDF_Dictionary* pPageResources = pPage ? pPage->m_pPageResources : NULL; + CPDF_Object* pCSObj = + m_pImageObject->m_pImage->GetStream()->GetDict()->GetElementValue( + FX_BSTRC("ColorSpace")); + CPDF_ColorSpace* pColorSpace = + pDocument->LoadColorSpace(pCSObj, pPageResources); + if (pColorSpace) { + int format = pColorSpace->GetFamily(); + if (format == PDFCS_DEVICECMYK || format == PDFCS_SEPARATION || + format == PDFCS_DEVICEN) { + m_BlendType = FXDIB_BLEND_DARKEN; + } + pDocument->GetPageData()->ReleaseColorSpace(pCSObj); + } + } + return StartDIBSource(); } -FX_BOOL CPDF_ImageRenderer::Start(CPDF_RenderStatus* pStatus, const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStdCS, int blendType) -{ - m_pRenderStatus = pStatus; - m_bStdCS = bStdCS; - m_pImageObject = (CPDF_ImageObject*)pObj; - m_BlendType = blendType; - m_pObj2Device = pObj2Device; - CPDF_Dictionary* pOC = m_pImageObject->m_pImage->GetOC(); - if (pOC && m_pRenderStatus->m_Options.m_pOCContext && !m_pRenderStatus->m_Options.m_pOCContext->CheckOCGVisible(pOC)) { - return FALSE; - } - m_ImageMatrix = m_pImageObject->m_Matrix; - m_ImageMatrix.Concat(*pObj2Device); - if (StartLoadDIBSource()) { - return TRUE; - } - return StartRenderDIBSource(); +FX_BOOL CPDF_ImageRenderer::Start(CPDF_RenderStatus* pStatus, + const CPDF_PageObject* pObj, + const CFX_AffineMatrix* pObj2Device, + FX_BOOL bStdCS, + int blendType) { + m_pRenderStatus = pStatus; + m_bStdCS = bStdCS; + m_pImageObject = (CPDF_ImageObject*)pObj; + m_BlendType = blendType; + m_pObj2Device = pObj2Device; + CPDF_Dictionary* pOC = m_pImageObject->m_pImage->GetOC(); + if (pOC && m_pRenderStatus->m_Options.m_pOCContext && + !m_pRenderStatus->m_Options.m_pOCContext->CheckOCGVisible(pOC)) { + return FALSE; + } + m_ImageMatrix = m_pImageObject->m_Matrix; + m_ImageMatrix.Concat(*pObj2Device); + if (StartLoadDIBSource()) { + return TRUE; + } + return StartRenderDIBSource(); } -FX_BOOL CPDF_ImageRenderer::Start(CPDF_RenderStatus* pStatus, const CFX_DIBSource* pDIBSource, FX_ARGB bitmap_argb, - int bitmap_alpha, const CFX_AffineMatrix* pImage2Device, FX_DWORD flags, FX_BOOL bStdCS, int blendType) -{ - m_pRenderStatus = pStatus; - m_pDIBSource = pDIBSource; - m_FillArgb = bitmap_argb; - m_BitmapAlpha = bitmap_alpha; - m_ImageMatrix = *pImage2Device; - m_Flags = flags; - m_bStdCS = bStdCS; - m_BlendType = blendType; - return StartDIBSource(); +FX_BOOL CPDF_ImageRenderer::Start(CPDF_RenderStatus* pStatus, + const CFX_DIBSource* pDIBSource, + FX_ARGB bitmap_argb, + int bitmap_alpha, + const CFX_AffineMatrix* pImage2Device, + FX_DWORD flags, + FX_BOOL bStdCS, + int blendType) { + m_pRenderStatus = pStatus; + m_pDIBSource = pDIBSource; + m_FillArgb = bitmap_argb; + m_BitmapAlpha = bitmap_alpha; + m_ImageMatrix = *pImage2Device; + m_Flags = flags; + m_bStdCS = bStdCS; + m_BlendType = blendType; + return StartDIBSource(); } -FX_BOOL CPDF_ImageRenderer::DrawPatternImage(const CFX_Matrix* pObj2Device) -{ - if (m_pRenderStatus->m_bPrint && !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { - m_Result = FALSE; - return FALSE; - } - FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOutterRect(); - rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox()); - if (rect.IsEmpty()) { - return FALSE; - } - CFX_AffineMatrix new_matrix = m_ImageMatrix; - new_matrix.TranslateI(-rect.left, -rect.top); - int width = rect.Width(); - int height = rect.Height(); - CFX_FxgeDevice bitmap_device1; - if (!bitmap_device1.Create(rect.Width(), rect.Height(), FXDIB_Rgb32)) { - return TRUE; - } - bitmap_device1.GetBitmap()->Clear(0xffffff); - { - CPDF_RenderStatus bitmap_render; - bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device1, NULL, NULL, - NULL, NULL, &m_pRenderStatus->m_Options, 0, m_pRenderStatus->m_bDropObjects, NULL, TRUE); - CFX_Matrix patternDevice = *pObj2Device; - patternDevice.Translate((FX_FLOAT) - rect.left, (FX_FLOAT) - rect.top); - if(m_pPattern->m_PatternType == PATTERN_TILING) { - bitmap_render.DrawTilingPattern((CPDF_TilingPattern*)m_pPattern, m_pImageObject, &patternDevice, FALSE); - } else { - bitmap_render.DrawShadingPattern((CPDF_ShadingPattern*)m_pPattern, m_pImageObject, &patternDevice, FALSE); - } - } - { - CFX_FxgeDevice bitmap_device2; - if (!bitmap_device2.Create(rect.Width(), rect.Height(), FXDIB_8bppRgb)) { - return TRUE; - } - bitmap_device2.GetBitmap()->Clear(0); - CPDF_RenderStatus bitmap_render; - bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device2, NULL, NULL, - NULL, NULL, NULL, 0, m_pRenderStatus->m_bDropObjects, NULL, TRUE); - CPDF_ImageRenderer image_render; - if (image_render.Start(&bitmap_render, m_pDIBSource, 0xffffffff, 255, &new_matrix, m_Flags, TRUE)) { - image_render.Continue(NULL); - } - if (m_Loader.m_MatteColor != 0xffffffff) { - int matte_r = FXARGB_R(m_Loader.m_MatteColor); - int matte_g = FXARGB_G(m_Loader.m_MatteColor); - int matte_b = FXARGB_B(m_Loader.m_MatteColor); - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = (uint8_t*)bitmap_device1.GetBitmap()->GetScanline(row); - const uint8_t* mask_scan = bitmap_device2.GetBitmap()->GetScanline(row); - for (int col = 0; col < width; col ++) { - int alpha = *mask_scan ++; - if (alpha) { - int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b; - if (orig < 0) { - orig = 0; - } else if (orig > 255) { - orig = 255; - } - *dest_scan++ = orig; - orig = (*dest_scan - matte_g) * 255 / alpha + matte_g; - if (orig < 0) { - orig = 0; - } else if (orig > 255) { - orig = 255; - } - *dest_scan++ = orig; - orig = (*dest_scan - matte_r) * 255 / alpha + matte_r; - if (orig < 0) { - orig = 0; - } else if (orig > 255) { - orig = 255; - } - *dest_scan++ = orig; - dest_scan ++; - } else { - dest_scan += 4; - } - } - } - } - bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask); - bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap()); - bitmap_device1.GetBitmap()->MultiplyAlpha(255); - } - m_pRenderStatus->m_pDevice->SetDIBits(bitmap_device1.GetBitmap(), rect.left, rect.top, m_BlendType); +FX_BOOL CPDF_ImageRenderer::DrawPatternImage(const CFX_Matrix* pObj2Device) { + if (m_pRenderStatus->m_bPrint && + !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { + m_Result = FALSE; return FALSE; -} -FX_BOOL CPDF_ImageRenderer::DrawMaskedImage() -{ - if (m_pRenderStatus->m_bPrint && !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { - m_Result = FALSE; - return FALSE; - } - FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOutterRect(); - rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox()); - if (rect.IsEmpty()) { - return FALSE; - } - CFX_AffineMatrix new_matrix = m_ImageMatrix; - new_matrix.TranslateI(-rect.left, -rect.top); - int width = rect.Width(); - int height = rect.Height(); - CFX_FxgeDevice bitmap_device1; - if (!bitmap_device1.Create(width, height, FXDIB_Rgb32)) { - return TRUE; - } - bitmap_device1.GetBitmap()->Clear(0xffffff); - { - CPDF_RenderStatus bitmap_render; - bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device1, NULL, NULL, - NULL, NULL, NULL, 0, m_pRenderStatus->m_bDropObjects, NULL, TRUE); - CPDF_ImageRenderer image_render; - if (image_render.Start(&bitmap_render, m_pDIBSource, 0, 255, &new_matrix, m_Flags, TRUE)) { - image_render.Continue(NULL); - } - } - { - CFX_FxgeDevice bitmap_device2; - if (!bitmap_device2.Create(width, height, FXDIB_8bppRgb)) { - return TRUE; - } - bitmap_device2.GetBitmap()->Clear(0); - CPDF_RenderStatus bitmap_render; - bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device2, NULL, NULL, - NULL, NULL, NULL, 0, m_pRenderStatus->m_bDropObjects, NULL, TRUE); - CPDF_ImageRenderer image_render; - if (image_render.Start(&bitmap_render, m_Loader.m_pMask, 0xffffffff, 255, &new_matrix, m_Flags, TRUE)) { - image_render.Continue(NULL); - } - if (m_Loader.m_MatteColor != 0xffffffff) { - int matte_r = FXARGB_R(m_Loader.m_MatteColor); - int matte_g = FXARGB_G(m_Loader.m_MatteColor); - int matte_b = FXARGB_B(m_Loader.m_MatteColor); - for (int row = 0; row < height; row ++) { - uint8_t* dest_scan = (uint8_t*)bitmap_device1.GetBitmap()->GetScanline(row); - const uint8_t* mask_scan = bitmap_device2.GetBitmap()->GetScanline(row); - for (int col = 0; col < width; col ++) { - int alpha = *mask_scan ++; - if (alpha) { - int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b; - if (orig < 0) { - orig = 0; - } else if (orig > 255) { - orig = 255; - } - *dest_scan++ = orig; - orig = (*dest_scan - matte_g) * 255 / alpha + matte_g; - if (orig < 0) { - orig = 0; - } else if (orig > 255) { - orig = 255; - } - *dest_scan++ = orig; - orig = (*dest_scan - matte_r) * 255 / alpha + matte_r; - if (orig < 0) { - orig = 0; - } else if (orig > 255) { - orig = 255; - } - *dest_scan++ = orig; - dest_scan ++; - } else { - dest_scan += 4; - } - } + } + FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOutterRect(); + rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox()); + if (rect.IsEmpty()) { + return FALSE; + } + CFX_AffineMatrix new_matrix = m_ImageMatrix; + new_matrix.TranslateI(-rect.left, -rect.top); + int width = rect.Width(); + int height = rect.Height(); + CFX_FxgeDevice bitmap_device1; + if (!bitmap_device1.Create(rect.Width(), rect.Height(), FXDIB_Rgb32)) { + return TRUE; + } + bitmap_device1.GetBitmap()->Clear(0xffffff); + { + CPDF_RenderStatus bitmap_render; + bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device1, NULL, + NULL, NULL, NULL, &m_pRenderStatus->m_Options, 0, + m_pRenderStatus->m_bDropObjects, NULL, TRUE); + CFX_Matrix patternDevice = *pObj2Device; + patternDevice.Translate((FX_FLOAT)-rect.left, (FX_FLOAT)-rect.top); + if (m_pPattern->m_PatternType == PATTERN_TILING) { + bitmap_render.DrawTilingPattern((CPDF_TilingPattern*)m_pPattern, + m_pImageObject, &patternDevice, FALSE); + } else { + bitmap_render.DrawShadingPattern((CPDF_ShadingPattern*)m_pPattern, + m_pImageObject, &patternDevice, FALSE); + } + } + { + CFX_FxgeDevice bitmap_device2; + if (!bitmap_device2.Create(rect.Width(), rect.Height(), FXDIB_8bppRgb)) { + return TRUE; + } + bitmap_device2.GetBitmap()->Clear(0); + CPDF_RenderStatus bitmap_render; + bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device2, NULL, + NULL, NULL, NULL, NULL, 0, + m_pRenderStatus->m_bDropObjects, NULL, TRUE); + CPDF_ImageRenderer image_render; + if (image_render.Start(&bitmap_render, m_pDIBSource, 0xffffffff, 255, + &new_matrix, m_Flags, TRUE)) { + image_render.Continue(NULL); + } + if (m_Loader.m_MatteColor != 0xffffffff) { + int matte_r = FXARGB_R(m_Loader.m_MatteColor); + int matte_g = FXARGB_G(m_Loader.m_MatteColor); + int matte_b = FXARGB_B(m_Loader.m_MatteColor); + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = + (uint8_t*)bitmap_device1.GetBitmap()->GetScanline(row); + const uint8_t* mask_scan = bitmap_device2.GetBitmap()->GetScanline(row); + for (int col = 0; col < width; col++) { + int alpha = *mask_scan++; + if (alpha) { + int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b; + if (orig < 0) { + orig = 0; + } else if (orig > 255) { + orig = 255; } + *dest_scan++ = orig; + orig = (*dest_scan - matte_g) * 255 / alpha + matte_g; + if (orig < 0) { + orig = 0; + } else if (orig > 255) { + orig = 255; + } + *dest_scan++ = orig; + orig = (*dest_scan - matte_r) * 255 / alpha + matte_r; + if (orig < 0) { + orig = 0; + } else if (orig > 255) { + orig = 255; + } + *dest_scan++ = orig; + dest_scan++; + } else { + dest_scan += 4; + } } - bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask); - bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap()); - if (m_BitmapAlpha < 255) { - bitmap_device1.GetBitmap()->MultiplyAlpha(m_BitmapAlpha); - } - } - m_pRenderStatus->m_pDevice->SetDIBits(bitmap_device1.GetBitmap(), rect.left, rect.top, m_BlendType); - return FALSE; + } + } + bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask); + bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap()); + bitmap_device1.GetBitmap()->MultiplyAlpha(255); + } + m_pRenderStatus->m_pDevice->SetDIBits(bitmap_device1.GetBitmap(), rect.left, + rect.top, m_BlendType); + return FALSE; } -FX_BOOL CPDF_ImageRenderer::StartDIBSource() -{ - if (!(m_Flags & RENDER_FORCE_DOWNSAMPLE) && m_pDIBSource->GetBPP() > 1) { - int image_size = m_pDIBSource->GetBPP() / 8 * m_pDIBSource->GetWidth() * m_pDIBSource->GetHeight(); - if (image_size > FPDF_HUGE_IMAGE_SIZE && !(m_Flags & RENDER_FORCE_HALFTONE)) { - m_Flags |= RENDER_FORCE_DOWNSAMPLE; - } - } - if (m_pRenderStatus->m_pDevice->StartDIBits(m_pDIBSource, m_BitmapAlpha, m_FillArgb, - &m_ImageMatrix, m_Flags, m_DeviceHandle, 0, NULL, m_BlendType)) { - if (m_DeviceHandle != NULL) { - m_Status = 3; - return TRUE; - } - return FALSE; - } - CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect(); - FX_RECT image_rect = image_rect_f.GetOutterRect(); - int dest_width = image_rect.Width(); - int dest_height = image_rect.Height(); - if ((FXSYS_fabs(m_ImageMatrix.b) >= 0.5f || m_ImageMatrix.a == 0) || - (FXSYS_fabs(m_ImageMatrix.c) >= 0.5f || m_ImageMatrix.d == 0) ) { - if (m_pRenderStatus->m_bPrint && !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { - m_Result = FALSE; - return FALSE; +FX_BOOL CPDF_ImageRenderer::DrawMaskedImage() { + if (m_pRenderStatus->m_bPrint && + !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { + m_Result = FALSE; + return FALSE; + } + FX_RECT rect = m_ImageMatrix.GetUnitRect().GetOutterRect(); + rect.Intersect(m_pRenderStatus->m_pDevice->GetClipBox()); + if (rect.IsEmpty()) { + return FALSE; + } + CFX_AffineMatrix new_matrix = m_ImageMatrix; + new_matrix.TranslateI(-rect.left, -rect.top); + int width = rect.Width(); + int height = rect.Height(); + CFX_FxgeDevice bitmap_device1; + if (!bitmap_device1.Create(width, height, FXDIB_Rgb32)) { + return TRUE; + } + bitmap_device1.GetBitmap()->Clear(0xffffff); + { + CPDF_RenderStatus bitmap_render; + bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device1, NULL, + NULL, NULL, NULL, NULL, 0, + m_pRenderStatus->m_bDropObjects, NULL, TRUE); + CPDF_ImageRenderer image_render; + if (image_render.Start(&bitmap_render, m_pDIBSource, 0, 255, &new_matrix, + m_Flags, TRUE)) { + image_render.Continue(NULL); + } + } + { + CFX_FxgeDevice bitmap_device2; + if (!bitmap_device2.Create(width, height, FXDIB_8bppRgb)) { + return TRUE; + } + bitmap_device2.GetBitmap()->Clear(0); + CPDF_RenderStatus bitmap_render; + bitmap_render.Initialize(m_pRenderStatus->m_pContext, &bitmap_device2, NULL, + NULL, NULL, NULL, NULL, 0, + m_pRenderStatus->m_bDropObjects, NULL, TRUE); + CPDF_ImageRenderer image_render; + if (image_render.Start(&bitmap_render, m_Loader.m_pMask, 0xffffffff, 255, + &new_matrix, m_Flags, TRUE)) { + image_render.Continue(NULL); + } + if (m_Loader.m_MatteColor != 0xffffffff) { + int matte_r = FXARGB_R(m_Loader.m_MatteColor); + int matte_g = FXARGB_G(m_Loader.m_MatteColor); + int matte_b = FXARGB_B(m_Loader.m_MatteColor); + for (int row = 0; row < height; row++) { + uint8_t* dest_scan = + (uint8_t*)bitmap_device1.GetBitmap()->GetScanline(row); + const uint8_t* mask_scan = bitmap_device2.GetBitmap()->GetScanline(row); + for (int col = 0; col < width; col++) { + int alpha = *mask_scan++; + if (alpha) { + int orig = (*dest_scan - matte_b) * 255 / alpha + matte_b; + if (orig < 0) { + orig = 0; + } else if (orig > 255) { + orig = 255; + } + *dest_scan++ = orig; + orig = (*dest_scan - matte_g) * 255 / alpha + matte_g; + if (orig < 0) { + orig = 0; + } else if (orig > 255) { + orig = 255; + } + *dest_scan++ = orig; + orig = (*dest_scan - matte_r) * 255 / alpha + matte_r; + if (orig < 0) { + orig = 0; + } else if (orig > 255) { + orig = 255; + } + *dest_scan++ = orig; + dest_scan++; + } else { + dest_scan += 4; + } } - FX_RECT clip_box = m_pRenderStatus->m_pDevice->GetClipBox(); - clip_box.Intersect(image_rect); - m_Status = 2; - m_pTransformer = new CFX_ImageTransformer; - m_pTransformer->Start(m_pDIBSource, &m_ImageMatrix, m_Flags, &clip_box); - return TRUE; - } - if (m_ImageMatrix.a < 0) { - dest_width = -dest_width; + } } - if (m_ImageMatrix.d > 0) { - dest_height = -dest_height; + bitmap_device2.GetBitmap()->ConvertFormat(FXDIB_8bppMask); + bitmap_device1.GetBitmap()->MultiplyAlpha(bitmap_device2.GetBitmap()); + if (m_BitmapAlpha < 255) { + bitmap_device1.GetBitmap()->MultiplyAlpha(m_BitmapAlpha); } - int dest_left, dest_top; - dest_left = dest_width > 0 ? image_rect.left : image_rect.right; - dest_top = dest_height > 0 ? image_rect.top : image_rect.bottom; - if (m_pDIBSource->IsOpaqueImage() && m_BitmapAlpha == 255) { - if (m_pRenderStatus->m_pDevice->StretchDIBits(m_pDIBSource, dest_left, dest_top, - dest_width, dest_height, m_Flags, NULL, m_BlendType)) { - return FALSE; - } - } - if (m_pDIBSource->IsAlphaMask()) { - if (m_BitmapAlpha != 255) { - m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha); - } - if (m_pRenderStatus->m_pDevice->StretchBitMask(m_pDIBSource, dest_left, dest_top, dest_width, dest_height, m_FillArgb, m_Flags)) { - return FALSE; - } + } + m_pRenderStatus->m_pDevice->SetDIBits(bitmap_device1.GetBitmap(), rect.left, + rect.top, m_BlendType); + return FALSE; +} +FX_BOOL CPDF_ImageRenderer::StartDIBSource() { + if (!(m_Flags & RENDER_FORCE_DOWNSAMPLE) && m_pDIBSource->GetBPP() > 1) { + int image_size = m_pDIBSource->GetBPP() / 8 * m_pDIBSource->GetWidth() * + m_pDIBSource->GetHeight(); + if (image_size > FPDF_HUGE_IMAGE_SIZE && + !(m_Flags & RENDER_FORCE_HALFTONE)) { + m_Flags |= RENDER_FORCE_DOWNSAMPLE; + } + } + if (m_pRenderStatus->m_pDevice->StartDIBits( + m_pDIBSource, m_BitmapAlpha, m_FillArgb, &m_ImageMatrix, m_Flags, + m_DeviceHandle, 0, NULL, m_BlendType)) { + if (m_DeviceHandle != NULL) { + m_Status = 3; + return TRUE; } - if (m_pRenderStatus->m_bPrint && !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { - m_Result = FALSE; - return TRUE; + return FALSE; + } + CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect(); + FX_RECT image_rect = image_rect_f.GetOutterRect(); + int dest_width = image_rect.Width(); + int dest_height = image_rect.Height(); + if ((FXSYS_fabs(m_ImageMatrix.b) >= 0.5f || m_ImageMatrix.a == 0) || + (FXSYS_fabs(m_ImageMatrix.c) >= 0.5f || m_ImageMatrix.d == 0)) { + if (m_pRenderStatus->m_bPrint && + !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { + m_Result = FALSE; + return FALSE; } FX_RECT clip_box = m_pRenderStatus->m_pDevice->GetClipBox(); - FX_RECT dest_rect = clip_box; - dest_rect.Intersect(image_rect); - FX_RECT dest_clip(dest_rect.left - image_rect.left, dest_rect.top - image_rect.top, - dest_rect.right - image_rect.left, dest_rect.bottom - image_rect.top); - CFX_DIBitmap* pStretched = m_pDIBSource->StretchTo(dest_width, dest_height, m_Flags, &dest_clip); - if (pStretched) { - m_pRenderStatus->CompositeDIBitmap(pStretched, dest_rect.left, dest_rect.top, m_FillArgb, - m_BitmapAlpha, m_BlendType, FALSE); - delete pStretched; - pStretched = NULL; - } - return FALSE; + clip_box.Intersect(image_rect); + m_Status = 2; + m_pTransformer = new CFX_ImageTransformer; + m_pTransformer->Start(m_pDIBSource, &m_ImageMatrix, m_Flags, &clip_box); + return TRUE; + } + if (m_ImageMatrix.a < 0) { + dest_width = -dest_width; + } + if (m_ImageMatrix.d > 0) { + dest_height = -dest_height; + } + int dest_left, dest_top; + dest_left = dest_width > 0 ? image_rect.left : image_rect.right; + dest_top = dest_height > 0 ? image_rect.top : image_rect.bottom; + if (m_pDIBSource->IsOpaqueImage() && m_BitmapAlpha == 255) { + if (m_pRenderStatus->m_pDevice->StretchDIBits( + m_pDIBSource, dest_left, dest_top, dest_width, dest_height, m_Flags, + NULL, m_BlendType)) { + return FALSE; + } + } + if (m_pDIBSource->IsAlphaMask()) { + if (m_BitmapAlpha != 255) { + m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha); + } + if (m_pRenderStatus->m_pDevice->StretchBitMask( + m_pDIBSource, dest_left, dest_top, dest_width, dest_height, + m_FillArgb, m_Flags)) { + return FALSE; + } + } + if (m_pRenderStatus->m_bPrint && + !(m_pRenderStatus->m_pDevice->GetRenderCaps() & FXRC_BLEND_MODE)) { + m_Result = FALSE; + return TRUE; + } + FX_RECT clip_box = m_pRenderStatus->m_pDevice->GetClipBox(); + FX_RECT dest_rect = clip_box; + dest_rect.Intersect(image_rect); + FX_RECT dest_clip( + dest_rect.left - image_rect.left, dest_rect.top - image_rect.top, + dest_rect.right - image_rect.left, dest_rect.bottom - image_rect.top); + CFX_DIBitmap* pStretched = + m_pDIBSource->StretchTo(dest_width, dest_height, m_Flags, &dest_clip); + if (pStretched) { + m_pRenderStatus->CompositeDIBitmap(pStretched, dest_rect.left, + dest_rect.top, m_FillArgb, m_BitmapAlpha, + m_BlendType, FALSE); + delete pStretched; + pStretched = NULL; + } + return FALSE; } -FX_BOOL CPDF_ImageRenderer::StartBitmapAlpha() -{ - if (m_pDIBSource->IsOpaqueImage()) { - CFX_PathData path; - path.AppendRect(0, 0, 1, 1); - path.Transform(&m_ImageMatrix); - FX_DWORD fill_color = ArgbEncode(0xff, m_BitmapAlpha, m_BitmapAlpha, m_BitmapAlpha); - m_pRenderStatus->m_pDevice->DrawPath(&path, NULL, NULL, fill_color, 0, FXFILL_WINDING); +FX_BOOL CPDF_ImageRenderer::StartBitmapAlpha() { + if (m_pDIBSource->IsOpaqueImage()) { + CFX_PathData path; + path.AppendRect(0, 0, 1, 1); + path.Transform(&m_ImageMatrix); + FX_DWORD fill_color = + ArgbEncode(0xff, m_BitmapAlpha, m_BitmapAlpha, m_BitmapAlpha); + m_pRenderStatus->m_pDevice->DrawPath(&path, NULL, NULL, fill_color, 0, + FXFILL_WINDING); + } else { + const CFX_DIBSource* pAlphaMask = m_pDIBSource->IsAlphaMask() + ? m_pDIBSource + : m_pDIBSource->GetAlphaMask(); + if (FXSYS_fabs(m_ImageMatrix.b) >= 0.5f || + FXSYS_fabs(m_ImageMatrix.c) >= 0.5f) { + int left, top; + CFX_DIBitmap* pTransformed = + pAlphaMask->TransformTo(&m_ImageMatrix, left, top); + if (pTransformed == NULL) { + return TRUE; + } + m_pRenderStatus->m_pDevice->SetBitMask( + pTransformed, left, top, + ArgbEncode(0xff, m_BitmapAlpha, m_BitmapAlpha, m_BitmapAlpha)); + delete pTransformed; } else { - const CFX_DIBSource* pAlphaMask = m_pDIBSource->IsAlphaMask() ? m_pDIBSource : m_pDIBSource->GetAlphaMask(); - if (FXSYS_fabs(m_ImageMatrix.b) >= 0.5f || FXSYS_fabs(m_ImageMatrix.c) >= 0.5f) { - int left, top; - CFX_DIBitmap* pTransformed = pAlphaMask->TransformTo(&m_ImageMatrix, left, top); - if (pTransformed == NULL) { - return TRUE; - } - m_pRenderStatus->m_pDevice->SetBitMask(pTransformed, left, top, ArgbEncode(0xff, m_BitmapAlpha, m_BitmapAlpha, m_BitmapAlpha)); - delete pTransformed; - } else { - CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect(); - FX_RECT image_rect = image_rect_f.GetOutterRect(); - int dest_width = m_ImageMatrix.a > 0 ? image_rect.Width() : -image_rect.Width(); - int dest_height = m_ImageMatrix.d > 0 ? -image_rect.Height() : image_rect.Height(); - int left = dest_width > 0 ? image_rect.left : image_rect.right; - int top = dest_height > 0 ? image_rect.top : image_rect.bottom; - m_pRenderStatus->m_pDevice->StretchBitMask(pAlphaMask, left, top, dest_width, dest_height, - ArgbEncode(0xff, m_BitmapAlpha, m_BitmapAlpha, m_BitmapAlpha)); - } - if (m_pDIBSource != pAlphaMask) { - delete pAlphaMask; - } - } - return FALSE; + CFX_FloatRect image_rect_f = m_ImageMatrix.GetUnitRect(); + FX_RECT image_rect = image_rect_f.GetOutterRect(); + int dest_width = + m_ImageMatrix.a > 0 ? image_rect.Width() : -image_rect.Width(); + int dest_height = + m_ImageMatrix.d > 0 ? -image_rect.Height() : image_rect.Height(); + int left = dest_width > 0 ? image_rect.left : image_rect.right; + int top = dest_height > 0 ? image_rect.top : image_rect.bottom; + m_pRenderStatus->m_pDevice->StretchBitMask( + pAlphaMask, left, top, dest_width, dest_height, + ArgbEncode(0xff, m_BitmapAlpha, m_BitmapAlpha, m_BitmapAlpha)); + } + if (m_pDIBSource != pAlphaMask) { + delete pAlphaMask; + } + } + return FALSE; } -FX_BOOL CPDF_ImageRenderer::Continue(IFX_Pause* pPause) -{ - if (m_Status == 1) { - if (m_pQuickStretcher->Continue(pPause)) { - return TRUE; - } - if (m_pQuickStretcher->m_pBitmap->IsAlphaMask()) - m_pRenderStatus->m_pDevice->SetBitMask(m_pQuickStretcher->m_pBitmap, m_pQuickStretcher->m_ResultLeft, - m_pQuickStretcher->m_ResultTop, m_FillArgb); - else - m_pRenderStatus->m_pDevice->SetDIBits(m_pQuickStretcher->m_pBitmap, m_pQuickStretcher->m_ResultLeft, - m_pQuickStretcher->m_ResultTop, m_BlendType); - return FALSE; - } - if (m_Status == 2) { - if (m_pTransformer->Continue(pPause)) { - return TRUE; - } - CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach(); - if (pBitmap == NULL) { - return FALSE; - } - if (pBitmap->IsAlphaMask()) { - if (m_BitmapAlpha != 255) { - m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha); - } - m_Result = m_pRenderStatus->m_pDevice->SetBitMask(pBitmap, - m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop, m_FillArgb); - } else { - if (m_BitmapAlpha != 255) { - pBitmap->MultiplyAlpha(m_BitmapAlpha); - } - m_Result = m_pRenderStatus->m_pDevice->SetDIBits(pBitmap, - m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop, m_BlendType); - } - delete pBitmap; - return FALSE; - } - if (m_Status == 3) { - return m_pRenderStatus->m_pDevice->ContinueDIBits(m_DeviceHandle, pPause); - } - if (m_Status == 4) { - if (m_Loader.Continue(m_LoadHandle, pPause)) { - return TRUE; - } - if (StartRenderDIBSource()) { - return Continue(pPause); - } - } +FX_BOOL CPDF_ImageRenderer::Continue(IFX_Pause* pPause) { + if (m_Status == 1) { + if (m_pQuickStretcher->Continue(pPause)) { + return TRUE; + } + if (m_pQuickStretcher->m_pBitmap->IsAlphaMask()) + m_pRenderStatus->m_pDevice->SetBitMask( + m_pQuickStretcher->m_pBitmap, m_pQuickStretcher->m_ResultLeft, + m_pQuickStretcher->m_ResultTop, m_FillArgb); + else + m_pRenderStatus->m_pDevice->SetDIBits( + m_pQuickStretcher->m_pBitmap, m_pQuickStretcher->m_ResultLeft, + m_pQuickStretcher->m_ResultTop, m_BlendType); return FALSE; + } + if (m_Status == 2) { + if (m_pTransformer->Continue(pPause)) { + return TRUE; + } + CFX_DIBitmap* pBitmap = m_pTransformer->m_Storer.Detach(); + if (pBitmap == NULL) { + return FALSE; + } + if (pBitmap->IsAlphaMask()) { + if (m_BitmapAlpha != 255) { + m_FillArgb = FXARGB_MUL_ALPHA(m_FillArgb, m_BitmapAlpha); + } + m_Result = m_pRenderStatus->m_pDevice->SetBitMask( + pBitmap, m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop, + m_FillArgb); + } else { + if (m_BitmapAlpha != 255) { + pBitmap->MultiplyAlpha(m_BitmapAlpha); + } + m_Result = m_pRenderStatus->m_pDevice->SetDIBits( + pBitmap, m_pTransformer->m_ResultLeft, m_pTransformer->m_ResultTop, + m_BlendType); + } + delete pBitmap; + return FALSE; + } + if (m_Status == 3) { + return m_pRenderStatus->m_pDevice->ContinueDIBits(m_DeviceHandle, pPause); + } + if (m_Status == 4) { + if (m_Loader.Continue(m_LoadHandle, pPause)) { + return TRUE; + } + if (StartRenderDIBSource()) { + return Continue(pPause); + } + } + return FALSE; } -CPDF_QuickStretcher::CPDF_QuickStretcher() -{ - m_pBitmap = NULL; - m_pDecoder = NULL; - m_pCS = NULL; +CPDF_QuickStretcher::CPDF_QuickStretcher() { + m_pBitmap = NULL; + m_pDecoder = NULL; + m_pCS = NULL; } -CPDF_QuickStretcher::~CPDF_QuickStretcher() -{ - delete m_pBitmap; - if (m_pCS) { - m_pCS->ReleaseCS(); - } - delete m_pDecoder; +CPDF_QuickStretcher::~CPDF_QuickStretcher() { + delete m_pBitmap; + if (m_pCS) { + m_pCS->ReleaseCS(); + } + delete m_pDecoder; } -ICodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder(const uint8_t* src_buf, FX_DWORD src_size, int width, int height, - int nComps, int bpc, const CPDF_Dictionary* pParams); -FX_BOOL CPDF_QuickStretcher::Start(CPDF_ImageObject* pImageObj, CFX_AffineMatrix* pImage2Device, const FX_RECT* pClipBox) -{ - if (FXSYS_fabs(pImage2Device->a) < FXSYS_fabs(pImage2Device->b) * 10 && FXSYS_fabs(pImage2Device->d) < FXSYS_fabs(pImage2Device->c) * 10) { - return FALSE; - } - CFX_FloatRect image_rect_f = pImage2Device->GetUnitRect(); - FX_RECT image_rect = image_rect_f.GetOutterRect(); - m_DestWidth = image_rect.Width(); - m_DestHeight = image_rect.Height(); - m_bFlipX = pImage2Device->a < 0; - m_bFlipY = pImage2Device->d > 0; - FX_RECT result_rect = *pClipBox; - result_rect.Intersect(image_rect); - if (result_rect.IsEmpty()) { - return FALSE; - } - m_ResultWidth = result_rect.Width(); - m_ResultHeight = result_rect.Height(); - m_ResultLeft = result_rect.left; - m_ResultTop = result_rect.top; - m_ClipLeft = result_rect.left - image_rect.left; - m_ClipTop = result_rect.top - image_rect.top; - CPDF_Dictionary* pDict = pImageObj->m_pImage->GetDict(); - if (pDict->GetInteger(FX_BSTRC("BitsPerComponent")) != 8) { - return FALSE; - } - if (pDict->KeyExist(FX_BSTRC("SMask")) || pDict->KeyExist(FX_BSTRC("Mask"))) { - return FALSE; - } - m_SrcWidth = pDict->GetInteger(FX_BSTRC("Width")); - m_SrcHeight = pDict->GetInteger(FX_BSTRC("Height")); +ICodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder( + const uint8_t* src_buf, + FX_DWORD src_size, + int width, + int height, + int nComps, + int bpc, + const CPDF_Dictionary* pParams); +FX_BOOL CPDF_QuickStretcher::Start(CPDF_ImageObject* pImageObj, + CFX_AffineMatrix* pImage2Device, + const FX_RECT* pClipBox) { + if (FXSYS_fabs(pImage2Device->a) < FXSYS_fabs(pImage2Device->b) * 10 && + FXSYS_fabs(pImage2Device->d) < FXSYS_fabs(pImage2Device->c) * 10) { + return FALSE; + } + CFX_FloatRect image_rect_f = pImage2Device->GetUnitRect(); + FX_RECT image_rect = image_rect_f.GetOutterRect(); + m_DestWidth = image_rect.Width(); + m_DestHeight = image_rect.Height(); + m_bFlipX = pImage2Device->a < 0; + m_bFlipY = pImage2Device->d > 0; + FX_RECT result_rect = *pClipBox; + result_rect.Intersect(image_rect); + if (result_rect.IsEmpty()) { + return FALSE; + } + m_ResultWidth = result_rect.Width(); + m_ResultHeight = result_rect.Height(); + m_ResultLeft = result_rect.left; + m_ResultTop = result_rect.top; + m_ClipLeft = result_rect.left - image_rect.left; + m_ClipTop = result_rect.top - image_rect.top; + CPDF_Dictionary* pDict = pImageObj->m_pImage->GetDict(); + if (pDict->GetInteger(FX_BSTRC("BitsPerComponent")) != 8) { + return FALSE; + } + if (pDict->KeyExist(FX_BSTRC("SMask")) || pDict->KeyExist(FX_BSTRC("Mask"))) { + return FALSE; + } + m_SrcWidth = pDict->GetInteger(FX_BSTRC("Width")); + m_SrcHeight = pDict->GetInteger(FX_BSTRC("Height")); + m_pCS = NULL; + m_Bpp = 3; + CPDF_Object* pCSObj = pDict->GetElementValue(FX_BSTRC("ColorSpace")); + if (pCSObj == NULL) { + return FALSE; + } + m_pCS = CPDF_ColorSpace::Load(pImageObj->m_pImage->GetDocument(), pCSObj); + if (m_pCS == NULL) { + return FALSE; + } + if (!_IsSupported(m_pCS)) { + return FALSE; + } + m_Bpp = m_pCS->CountComponents(); + if (m_pCS->sRGB()) { + m_pCS->ReleaseCS(); m_pCS = NULL; - m_Bpp = 3; - CPDF_Object* pCSObj = pDict->GetElementValue(FX_BSTRC("ColorSpace")); - if (pCSObj == NULL) { - return FALSE; - } - m_pCS = CPDF_ColorSpace::Load(pImageObj->m_pImage->GetDocument(), pCSObj); - if (m_pCS == NULL) { - return FALSE; - } - if (!_IsSupported(m_pCS)) { - return FALSE; - } - m_Bpp = m_pCS->CountComponents(); - if (m_pCS->sRGB()) { - m_pCS->ReleaseCS(); - m_pCS = NULL; - } - CPDF_Stream* pStream = pImageObj->m_pImage->GetStream(); - m_StreamAcc.LoadAllData(pStream, FALSE, m_SrcWidth * m_SrcHeight * m_Bpp, TRUE); - m_pDecoder = NULL; - if (!m_StreamAcc.GetImageDecoder().IsEmpty()) { - if (m_StreamAcc.GetImageDecoder() == FX_BSTRC("DCTDecode")) { - const CPDF_Dictionary* pParam = m_StreamAcc.GetImageParam(); - m_pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder( - m_StreamAcc.GetData(), m_StreamAcc.GetSize(), m_SrcWidth, m_SrcHeight, m_Bpp, - pParam ? pParam->GetInteger(FX_BSTRC("ColorTransform"), 1) : 1); - } else if (m_StreamAcc.GetImageDecoder() == FX_BSTRC("FlateDecode")) { - m_pDecoder = FPDFAPI_CreateFlateDecoder( - m_StreamAcc.GetData(), m_StreamAcc.GetSize(), m_SrcWidth, m_SrcHeight, m_Bpp, 8, - m_StreamAcc.GetImageParam()); - } else { - return FALSE; - } - m_pDecoder->DownScale(m_DestWidth, m_DestHeight); + } + CPDF_Stream* pStream = pImageObj->m_pImage->GetStream(); + m_StreamAcc.LoadAllData(pStream, FALSE, m_SrcWidth * m_SrcHeight * m_Bpp, + TRUE); + m_pDecoder = NULL; + if (!m_StreamAcc.GetImageDecoder().IsEmpty()) { + if (m_StreamAcc.GetImageDecoder() == FX_BSTRC("DCTDecode")) { + const CPDF_Dictionary* pParam = m_StreamAcc.GetImageParam(); + m_pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder( + m_StreamAcc.GetData(), m_StreamAcc.GetSize(), m_SrcWidth, m_SrcHeight, + m_Bpp, + pParam ? pParam->GetInteger(FX_BSTRC("ColorTransform"), 1) : 1); + } else if (m_StreamAcc.GetImageDecoder() == FX_BSTRC("FlateDecode")) { + m_pDecoder = FPDFAPI_CreateFlateDecoder( + m_StreamAcc.GetData(), m_StreamAcc.GetSize(), m_SrcWidth, m_SrcHeight, + m_Bpp, 8, m_StreamAcc.GetImageParam()); + } else { + return FALSE; } - m_pBitmap = new CFX_DIBitmap; -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - m_pBitmap->Create(m_ResultWidth, m_ResultHeight, FXDIB_Rgb32); + m_pDecoder->DownScale(m_DestWidth, m_DestHeight); + } + m_pBitmap = new CFX_DIBitmap; +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + m_pBitmap->Create(m_ResultWidth, m_ResultHeight, FXDIB_Rgb32); #else - m_pBitmap->Create(m_ResultWidth, m_ResultHeight, FXDIB_Rgb); + m_pBitmap->Create(m_ResultWidth, m_ResultHeight, FXDIB_Rgb); #endif - m_LineIndex = 0; - return TRUE; + m_LineIndex = 0; + return TRUE; } -FX_BOOL CPDF_QuickStretcher::Continue(IFX_Pause* pPause) -{ - uint8_t* result_buf = m_pBitmap->GetBuffer(); - int src_width = m_pDecoder ? m_pDecoder->GetWidth() : m_SrcWidth; - int src_height = m_pDecoder ? m_pDecoder->GetHeight() : m_SrcHeight; - int src_pitch = src_width * m_Bpp; - while (m_LineIndex < m_ResultHeight) { - int dest_y, src_y; - if (m_bFlipY) { - dest_y = m_ResultHeight - m_LineIndex - 1; - src_y = (m_DestHeight - (dest_y + m_ClipTop) - 1) * src_height / m_DestHeight; - } else { - dest_y = m_LineIndex; - src_y = (dest_y + m_ClipTop) * src_height / m_DestHeight; - } - const uint8_t* src_scan; - if (m_pDecoder) { - src_scan = m_pDecoder->GetScanline(src_y); - if (src_scan == NULL) { - break; - } - } else { - src_scan = m_StreamAcc.GetData(); - if (src_scan == NULL) { - break; - } - src_scan += src_y * src_pitch; - } - uint8_t* result_scan = result_buf + dest_y * m_pBitmap->GetPitch(); - for (int x = 0; x < m_ResultWidth; x ++) { - int dest_x = m_ClipLeft + x; - int src_x = (m_bFlipX ? (m_DestWidth - dest_x - 1) : dest_x) * src_width / m_DestWidth; - const uint8_t* src_pixel = src_scan + src_x * m_Bpp; - if (m_pCS == NULL) { - *result_scan = src_pixel[2]; - result_scan ++; - *result_scan = src_pixel[1]; - result_scan ++; - *result_scan = src_pixel[0]; - result_scan ++; -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - result_scan ++; +FX_BOOL CPDF_QuickStretcher::Continue(IFX_Pause* pPause) { + uint8_t* result_buf = m_pBitmap->GetBuffer(); + int src_width = m_pDecoder ? m_pDecoder->GetWidth() : m_SrcWidth; + int src_height = m_pDecoder ? m_pDecoder->GetHeight() : m_SrcHeight; + int src_pitch = src_width * m_Bpp; + while (m_LineIndex < m_ResultHeight) { + int dest_y, src_y; + if (m_bFlipY) { + dest_y = m_ResultHeight - m_LineIndex - 1; + src_y = + (m_DestHeight - (dest_y + m_ClipTop) - 1) * src_height / m_DestHeight; + } else { + dest_y = m_LineIndex; + src_y = (dest_y + m_ClipTop) * src_height / m_DestHeight; + } + const uint8_t* src_scan; + if (m_pDecoder) { + src_scan = m_pDecoder->GetScanline(src_y); + if (src_scan == NULL) { + break; + } + } else { + src_scan = m_StreamAcc.GetData(); + if (src_scan == NULL) { + break; + } + src_scan += src_y * src_pitch; + } + uint8_t* result_scan = result_buf + dest_y * m_pBitmap->GetPitch(); + for (int x = 0; x < m_ResultWidth; x++) { + int dest_x = m_ClipLeft + x; + int src_x = (m_bFlipX ? (m_DestWidth - dest_x - 1) : dest_x) * src_width / + m_DestWidth; + const uint8_t* src_pixel = src_scan + src_x * m_Bpp; + if (m_pCS == NULL) { + *result_scan = src_pixel[2]; + result_scan++; + *result_scan = src_pixel[1]; + result_scan++; + *result_scan = src_pixel[0]; + result_scan++; +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + result_scan++; #endif - } else { - m_pCS->TranslateImageLine(result_scan, src_pixel, 1, 0, 0); -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - result_scan += 4; + } else { + m_pCS->TranslateImageLine(result_scan, src_pixel, 1, 0, 0); +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + result_scan += 4; #else - result_scan += 3; + result_scan += 3; #endif - } - } - m_LineIndex ++; - if (pPause && pPause->NeedToPauseNow()) { - return TRUE; - } + } } - return FALSE; + m_LineIndex++; + if (pPause && pPause->NeedToPauseNow()) { + return TRUE; + } + } + return FALSE; } CFX_DIBitmap* CPDF_RenderStatus::LoadSMask(CPDF_Dictionary* pSMaskDict, - FX_RECT* pClipRect, const CFX_AffineMatrix* pMatrix) -{ - if (pSMaskDict == NULL) { - return NULL; - } - CFX_DIBitmap* pMask = NULL; - int width = pClipRect->right - pClipRect->left; - int height = pClipRect->bottom - pClipRect->top; - FX_BOOL bLuminosity = FALSE; - bLuminosity = pSMaskDict->GetConstString(FX_BSTRC("S")) != FX_BSTRC("Alpha"); - CPDF_Stream* pGroup = pSMaskDict->GetStream(FX_BSTRC("G")); - if (pGroup == NULL) { - return NULL; - } - CPDF_Function* pFunc = NULL; - CPDF_Object* pFuncObj = pSMaskDict->GetElementValue(FX_BSTRC("TR")); - if (pFuncObj && (pFuncObj->GetType() == PDFOBJ_DICTIONARY || pFuncObj->GetType() == PDFOBJ_STREAM)) { - pFunc = CPDF_Function::Load(pFuncObj); - } - CFX_AffineMatrix matrix = *pMatrix; - matrix.TranslateI(-pClipRect->left, -pClipRect->top); - CPDF_Form form(m_pContext->m_pDocument, m_pContext->m_pPageResources, pGroup); - form.ParseContent(NULL, NULL, NULL, NULL); - CFX_FxgeDevice bitmap_device; -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - if (!bitmap_device.Create(width, height, bLuminosity ? FXDIB_Rgb32 : FXDIB_8bppMask)) { - return NULL; - } + FX_RECT* pClipRect, + const CFX_AffineMatrix* pMatrix) { + if (pSMaskDict == NULL) { + return NULL; + } + CFX_DIBitmap* pMask = NULL; + int width = pClipRect->right - pClipRect->left; + int height = pClipRect->bottom - pClipRect->top; + FX_BOOL bLuminosity = FALSE; + bLuminosity = pSMaskDict->GetConstString(FX_BSTRC("S")) != FX_BSTRC("Alpha"); + CPDF_Stream* pGroup = pSMaskDict->GetStream(FX_BSTRC("G")); + if (pGroup == NULL) { + return NULL; + } + CPDF_Function* pFunc = NULL; + CPDF_Object* pFuncObj = pSMaskDict->GetElementValue(FX_BSTRC("TR")); + if (pFuncObj && (pFuncObj->GetType() == PDFOBJ_DICTIONARY || + pFuncObj->GetType() == PDFOBJ_STREAM)) { + pFunc = CPDF_Function::Load(pFuncObj); + } + CFX_AffineMatrix matrix = *pMatrix; + matrix.TranslateI(-pClipRect->left, -pClipRect->top); + CPDF_Form form(m_pContext->m_pDocument, m_pContext->m_pPageResources, pGroup); + form.ParseContent(NULL, NULL, NULL, NULL); + CFX_FxgeDevice bitmap_device; +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + if (!bitmap_device.Create(width, height, + bLuminosity ? FXDIB_Rgb32 : FXDIB_8bppMask)) { + return NULL; + } #else - if (!bitmap_device.Create(width, height, bLuminosity ? FXDIB_Rgb : FXDIB_8bppMask)) { - return NULL; - } + if (!bitmap_device.Create(width, height, + bLuminosity ? FXDIB_Rgb : FXDIB_8bppMask)) { + return NULL; + } #endif - CFX_DIBitmap& bitmap = *bitmap_device.GetBitmap(); - CPDF_Object* pCSObj = NULL; - CPDF_ColorSpace* pCS = NULL; - if (bLuminosity) { - CPDF_Array* pBC = pSMaskDict->GetArray(FX_BSTRC("BC")); - FX_ARGB back_color = 0xff000000; - if (pBC) { - CPDF_Dictionary* pDict = pGroup->GetDict(); - if (pDict && pDict->GetDict(FX_BSTRC("Group"))) - pCSObj = pDict->GetDict(FX_BSTRC("Group"))->GetElementValue(FX_BSTRC("CS")); - else - pCSObj = NULL; - pCS = m_pContext->m_pDocument->LoadColorSpace(pCSObj); - if (pCS) { - FX_FLOAT R, G, B; - FX_DWORD comps = 8; - if (pCS->CountComponents() > static_cast<int32_t>(comps)) { - comps = (FX_DWORD)pCS->CountComponents(); - } - CFX_FixedBufGrow<FX_FLOAT, 8> float_array(comps); - FX_FLOAT* pFloats = float_array; - FX_SAFE_DWORD num_floats = comps; - num_floats *= sizeof(FX_FLOAT); - if (!num_floats.IsValid()) { - return NULL; - } - FXSYS_memset(pFloats, 0, num_floats.ValueOrDie()); - int count = pBC->GetCount() > 8 ? 8 : pBC->GetCount(); - for (int i = 0; i < count; i ++) { - pFloats[i] = pBC->GetNumber(i); - } - pCS->GetRGB(pFloats, R, G, B); - back_color = 0xff000000 | ((int32_t)(R * 255) << 16) | ((int32_t)(G * 255) << 8) | (int32_t)(B * 255); - m_pContext->m_pDocument->GetPageData()->ReleaseColorSpace(pCSObj); - } + CFX_DIBitmap& bitmap = *bitmap_device.GetBitmap(); + CPDF_Object* pCSObj = NULL; + CPDF_ColorSpace* pCS = NULL; + if (bLuminosity) { + CPDF_Array* pBC = pSMaskDict->GetArray(FX_BSTRC("BC")); + FX_ARGB back_color = 0xff000000; + if (pBC) { + CPDF_Dictionary* pDict = pGroup->GetDict(); + if (pDict && pDict->GetDict(FX_BSTRC("Group"))) + pCSObj = + pDict->GetDict(FX_BSTRC("Group"))->GetElementValue(FX_BSTRC("CS")); + else + pCSObj = NULL; + pCS = m_pContext->m_pDocument->LoadColorSpace(pCSObj); + if (pCS) { + FX_FLOAT R, G, B; + FX_DWORD comps = 8; + if (pCS->CountComponents() > static_cast<int32_t>(comps)) { + comps = (FX_DWORD)pCS->CountComponents(); } - bitmap.Clear(back_color); - } else { - bitmap.Clear(0); - } - CPDF_Dictionary* pFormResource = NULL; - if (form.m_pFormDict) { - pFormResource = form.m_pFormDict->GetDict(FX_BSTRC("Resources")); - } - CPDF_RenderOptions options; - options.m_ColorMode = bLuminosity ? RENDER_COLOR_NORMAL : RENDER_COLOR_ALPHA; - CPDF_RenderStatus status; - status.Initialize(m_pContext, &bitmap_device, NULL, NULL, NULL, NULL, - &options, 0, m_bDropObjects, pFormResource, TRUE, NULL, 0, pCS ? pCS->GetFamily() : 0, bLuminosity); - status.RenderObjectList(&form, &matrix); - pMask = new CFX_DIBitmap; - if (!pMask->Create(width, height, FXDIB_8bppMask)) { - delete pMask; - return NULL; - } - uint8_t* dest_buf = pMask->GetBuffer(); - int dest_pitch = pMask->GetPitch(); - uint8_t* src_buf = bitmap.GetBuffer(); - int src_pitch = bitmap.GetPitch(); - uint8_t* pTransfer = FX_Alloc(uint8_t, 256); - if (pFunc) { - CFX_FixedBufGrow<FX_FLOAT, 16> results(pFunc->CountOutputs()); - for (int i = 0; i < 256; i ++) { - FX_FLOAT input = (FX_FLOAT)i / 255.0f; - int nresult; - pFunc->Call(&input, 1, results, nresult); - pTransfer[i] = FXSYS_round(results[0] * 255); + CFX_FixedBufGrow<FX_FLOAT, 8> float_array(comps); + FX_FLOAT* pFloats = float_array; + FX_SAFE_DWORD num_floats = comps; + num_floats *= sizeof(FX_FLOAT); + if (!num_floats.IsValid()) { + return NULL; } - } else { - for (int i = 0; i < 256; i ++) { - pTransfer[i] = i; + FXSYS_memset(pFloats, 0, num_floats.ValueOrDie()); + int count = pBC->GetCount() > 8 ? 8 : pBC->GetCount(); + for (int i = 0; i < count; i++) { + pFloats[i] = pBC->GetNumber(i); } - } - if (bLuminosity) { - int Bpp = bitmap.GetBPP() / 8; - for (int row = 0; row < height; row ++) { - uint8_t* dest_pos = dest_buf + row * dest_pitch; - uint8_t* src_pos = src_buf + row * src_pitch; - for (int col = 0; col < width; col ++) { - *dest_pos ++ = pTransfer[FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos)]; - src_pos += Bpp; - } - } - } else if (pFunc) { - int size = dest_pitch * height; - for (int i = 0; i < size; i ++) { - dest_buf[i] = pTransfer[src_buf[i]]; - } - } else { - FXSYS_memcpy(dest_buf, src_buf, dest_pitch * height); - } - delete pFunc; - FX_Free(pTransfer); - return pMask; + pCS->GetRGB(pFloats, R, G, B); + back_color = 0xff000000 | ((int32_t)(R * 255) << 16) | + ((int32_t)(G * 255) << 8) | (int32_t)(B * 255); + m_pContext->m_pDocument->GetPageData()->ReleaseColorSpace(pCSObj); + } + } + bitmap.Clear(back_color); + } else { + bitmap.Clear(0); + } + CPDF_Dictionary* pFormResource = NULL; + if (form.m_pFormDict) { + pFormResource = form.m_pFormDict->GetDict(FX_BSTRC("Resources")); + } + CPDF_RenderOptions options; + options.m_ColorMode = bLuminosity ? RENDER_COLOR_NORMAL : RENDER_COLOR_ALPHA; + CPDF_RenderStatus status; + status.Initialize(m_pContext, &bitmap_device, NULL, NULL, NULL, NULL, + &options, 0, m_bDropObjects, pFormResource, TRUE, NULL, 0, + pCS ? pCS->GetFamily() : 0, bLuminosity); + status.RenderObjectList(&form, &matrix); + pMask = new CFX_DIBitmap; + if (!pMask->Create(width, height, FXDIB_8bppMask)) { + delete pMask; + return NULL; + } + uint8_t* dest_buf = pMask->GetBuffer(); + int dest_pitch = pMask->GetPitch(); + uint8_t* src_buf = bitmap.GetBuffer(); + int src_pitch = bitmap.GetPitch(); + uint8_t* pTransfer = FX_Alloc(uint8_t, 256); + if (pFunc) { + CFX_FixedBufGrow<FX_FLOAT, 16> results(pFunc->CountOutputs()); + for (int i = 0; i < 256; i++) { + FX_FLOAT input = (FX_FLOAT)i / 255.0f; + int nresult; + pFunc->Call(&input, 1, results, nresult); + pTransfer[i] = FXSYS_round(results[0] * 255); + } + } else { + for (int i = 0; i < 256; i++) { + pTransfer[i] = i; + } + } + if (bLuminosity) { + int Bpp = bitmap.GetBPP() / 8; + for (int row = 0; row < height; row++) { + uint8_t* dest_pos = dest_buf + row * dest_pitch; + uint8_t* src_pos = src_buf + row * src_pitch; + for (int col = 0; col < width; col++) { + *dest_pos++ = pTransfer[FXRGB2GRAY(src_pos[2], src_pos[1], *src_pos)]; + src_pos += Bpp; + } + } + } else if (pFunc) { + int size = dest_pitch * height; + for (int i = 0; i < size; i++) { + dest_buf[i] = pTransfer[src_buf[i]]; + } + } else { + FXSYS_memcpy(dest_buf, src_buf, dest_pitch * height); + } + delete pFunc; + FX_Free(pTransfer); + return pMask; } diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp index 7d17e78e24..e066957e62 100644 --- a/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp +++ b/core/src/fpdfapi/fpdf_render/fpdf_render_loadimage.cpp @@ -16,1550 +16,1639 @@ namespace { -unsigned int _GetBits8(const uint8_t* pData, int bitpos, int nbits) -{ - unsigned int byte = pData[bitpos / 8]; - if (nbits == 8) { - return byte; - } - if (nbits == 4) { - return (bitpos % 8) ? (byte & 0x0f) : (byte >> 4); - } - if (nbits == 2) { - return (byte >> (6 - bitpos % 8)) & 0x03; - } - if (nbits == 1) { - return (byte >> (7 - bitpos % 8)) & 0x01; - } - if (nbits == 16) { - return byte * 256 + pData[bitpos / 8 + 1]; - } - return 0; +unsigned int _GetBits8(const uint8_t* pData, int bitpos, int nbits) { + unsigned int byte = pData[bitpos / 8]; + if (nbits == 8) { + return byte; + } + if (nbits == 4) { + return (bitpos % 8) ? (byte & 0x0f) : (byte >> 4); + } + if (nbits == 2) { + return (byte >> (6 - bitpos % 8)) & 0x03; + } + if (nbits == 1) { + return (byte >> (7 - bitpos % 8)) & 0x01; + } + if (nbits == 16) { + return byte * 256 + pData[bitpos / 8 + 1]; + } + return 0; } FX_SAFE_DWORD CalculatePitch8(FX_DWORD bpc, FX_DWORD components, int width, - int height) -{ - FX_SAFE_DWORD pitch = bpc; - pitch *= components; - pitch *= width; - pitch += 7; - pitch /= 8; - pitch *= height; - return pitch; + int height) { + FX_SAFE_DWORD pitch = bpc; + pitch *= components; + pitch *= width; + pitch += 7; + pitch /= 8; + pitch *= height; + return pitch; } -FX_SAFE_DWORD CalculatePitch32(int bpp, int width) -{ - FX_SAFE_DWORD pitch = bpp; - pitch *= width; - pitch += 31; - pitch /= 8; - return pitch; +FX_SAFE_DWORD CalculatePitch32(int bpp, int width) { + FX_SAFE_DWORD pitch = bpp; + pitch *= width; + pitch += 31; + pitch /= 8; + return pitch; } // Wrapper class to hold objects allocated in CPDF_DIBSource::LoadJpxBitmap(), // because nonstd::unique_ptr does not support custom deleters yet. -class JpxBitMapContext -{ - public: - explicit JpxBitMapContext(ICodec_JpxModule* jpx_module) - : jpx_module_(jpx_module), - ctx_(nullptr), - output_offsets_(nullptr) {} +class JpxBitMapContext { + public: + explicit JpxBitMapContext(ICodec_JpxModule* jpx_module) + : jpx_module_(jpx_module), ctx_(nullptr), output_offsets_(nullptr) {} - ~JpxBitMapContext() { - FX_Free(output_offsets_); - jpx_module_->DestroyDecoder(ctx_); - } + ~JpxBitMapContext() { + FX_Free(output_offsets_); + jpx_module_->DestroyDecoder(ctx_); + } - // Takes ownership of |ctx|. - void set_context(void* ctx) { - ctx_ = ctx; - } + // Takes ownership of |ctx|. + void set_context(void* ctx) { ctx_ = ctx; } - void* context() { - return ctx_; - } + void* context() { return ctx_; } - // Takes ownership of |output_offsets|. - void set_output_offsets(unsigned char* output_offsets) { - output_offsets_ = output_offsets; - } + // Takes ownership of |output_offsets|. + void set_output_offsets(unsigned char* output_offsets) { + output_offsets_ = output_offsets; + } - unsigned char* output_offsets() { - return output_offsets_; - } + unsigned char* output_offsets() { return output_offsets_; } - private: - ICodec_JpxModule* jpx_module_; // Weak pointer. - void* ctx_; // Decoder context, owned. - unsigned char* output_offsets_; // Output offsets for decoding, owned. + private: + ICodec_JpxModule* jpx_module_; // Weak pointer. + void* ctx_; // Decoder context, owned. + unsigned char* output_offsets_; // Output offsets for decoding, owned. - // Disallow evil constructors - JpxBitMapContext(const JpxBitMapContext&); - void operator=(const JpxBitMapContext&); + // Disallow evil constructors + JpxBitMapContext(const JpxBitMapContext&); + void operator=(const JpxBitMapContext&); }; } // namespace -CFX_DIBSource* CPDF_Image::LoadDIBSource(CFX_DIBSource** ppMask, FX_DWORD* pMatteColor, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask) const -{ - CPDF_DIBSource* pSource = new CPDF_DIBSource; - if (pSource->Load(m_pDocument, m_pStream, (CPDF_DIBSource**)ppMask, pMatteColor, NULL, NULL, bStdCS, GroupFamily, bLoadMask)) { - return pSource; - } - delete pSource; - return NULL; +CFX_DIBSource* CPDF_Image::LoadDIBSource(CFX_DIBSource** ppMask, + FX_DWORD* pMatteColor, + FX_BOOL bStdCS, + FX_DWORD GroupFamily, + FX_BOOL bLoadMask) const { + CPDF_DIBSource* pSource = new CPDF_DIBSource; + if (pSource->Load(m_pDocument, m_pStream, (CPDF_DIBSource**)ppMask, + pMatteColor, NULL, NULL, bStdCS, GroupFamily, bLoadMask)) { + return pSource; + } + delete pSource; + return NULL; } -CFX_DIBSource* CPDF_Image::DetachBitmap() -{ - CFX_DIBSource* pBitmap = m_pDIBSource; - m_pDIBSource = NULL; - return pBitmap; +CFX_DIBSource* CPDF_Image::DetachBitmap() { + CFX_DIBSource* pBitmap = m_pDIBSource; + m_pDIBSource = NULL; + return pBitmap; } -CFX_DIBSource* CPDF_Image::DetachMask() -{ - CFX_DIBSource* pBitmap = m_pMask; - m_pMask = NULL; - return pBitmap; +CFX_DIBSource* CPDF_Image::DetachMask() { + CFX_DIBSource* pBitmap = m_pMask; + m_pMask = NULL; + return pBitmap; } -FX_BOOL CPDF_Image::StartLoadDIBSource(CPDF_Dictionary* pFormResource, CPDF_Dictionary* pPageResource, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask) -{ - m_pDIBSource = new CPDF_DIBSource; - int ret = ((CPDF_DIBSource*)m_pDIBSource)->StartLoadDIBSource(m_pDocument, m_pStream, TRUE, pFormResource, pPageResource, bStdCS, GroupFamily, bLoadMask); - if (ret == 2) { - return TRUE; - } - if (!ret) { - delete m_pDIBSource; - m_pDIBSource = NULL; - return FALSE; - } - m_pMask = ((CPDF_DIBSource*)m_pDIBSource)->DetachMask(); - m_MatteColor = ((CPDF_DIBSource*)m_pDIBSource)->m_MatteColor; +FX_BOOL CPDF_Image::StartLoadDIBSource(CPDF_Dictionary* pFormResource, + CPDF_Dictionary* pPageResource, + FX_BOOL bStdCS, + FX_DWORD GroupFamily, + FX_BOOL bLoadMask) { + m_pDIBSource = new CPDF_DIBSource; + int ret = + ((CPDF_DIBSource*)m_pDIBSource) + ->StartLoadDIBSource(m_pDocument, m_pStream, TRUE, pFormResource, + pPageResource, bStdCS, GroupFamily, bLoadMask); + if (ret == 2) { + return TRUE; + } + if (!ret) { + delete m_pDIBSource; + m_pDIBSource = NULL; return FALSE; + } + m_pMask = ((CPDF_DIBSource*)m_pDIBSource)->DetachMask(); + m_MatteColor = ((CPDF_DIBSource*)m_pDIBSource)->m_MatteColor; + return FALSE; } -FX_BOOL CPDF_Image::Continue(IFX_Pause* pPause) -{ - int ret = ((CPDF_DIBSource*)m_pDIBSource)->ContinueLoadDIBSource(pPause); - if (ret == 2) { - return TRUE; - } - if (!ret) { - delete m_pDIBSource; - m_pDIBSource = NULL; - return FALSE; - } - m_pMask = ((CPDF_DIBSource*)m_pDIBSource)->DetachMask(); - m_MatteColor = ((CPDF_DIBSource*)m_pDIBSource)->m_MatteColor; +FX_BOOL CPDF_Image::Continue(IFX_Pause* pPause) { + int ret = ((CPDF_DIBSource*)m_pDIBSource)->ContinueLoadDIBSource(pPause); + if (ret == 2) { + return TRUE; + } + if (!ret) { + delete m_pDIBSource; + m_pDIBSource = NULL; return FALSE; + } + m_pMask = ((CPDF_DIBSource*)m_pDIBSource)->DetachMask(); + m_MatteColor = ((CPDF_DIBSource*)m_pDIBSource)->m_MatteColor; + return FALSE; } -CPDF_DIBSource::CPDF_DIBSource() -{ - m_pDocument = NULL; - m_pStreamAcc = NULL; - m_pDict = NULL; - m_bpp = 0; - m_Width = m_Height = 0; - m_pColorSpace = NULL; - m_bDefaultDecode = TRUE; - m_bImageMask = FALSE; - m_bDoBpcCheck = TRUE; - m_pPalette = NULL; - m_pCompData = NULL; - m_bColorKey = FALSE; - m_pMaskedLine = m_pLineBuf = NULL; - m_pDecoder = NULL; - m_nComponents = 0; - m_bpc = 0; - m_bLoadMask = FALSE; - m_Family = 0; - m_pMask = NULL; - m_MatteColor = 0; - m_pJbig2Context = NULL; - m_pGlobalStream = NULL; - m_bStdCS = FALSE; - m_pMaskStream = NULL; - m_Status = 0; - m_bHasMask = FALSE; +CPDF_DIBSource::CPDF_DIBSource() { + m_pDocument = NULL; + m_pStreamAcc = NULL; + m_pDict = NULL; + m_bpp = 0; + m_Width = m_Height = 0; + m_pColorSpace = NULL; + m_bDefaultDecode = TRUE; + m_bImageMask = FALSE; + m_bDoBpcCheck = TRUE; + m_pPalette = NULL; + m_pCompData = NULL; + m_bColorKey = FALSE; + m_pMaskedLine = m_pLineBuf = NULL; + m_pDecoder = NULL; + m_nComponents = 0; + m_bpc = 0; + m_bLoadMask = FALSE; + m_Family = 0; + m_pMask = NULL; + m_MatteColor = 0; + m_pJbig2Context = NULL; + m_pGlobalStream = NULL; + m_bStdCS = FALSE; + m_pMaskStream = NULL; + m_Status = 0; + m_bHasMask = FALSE; } -CPDF_DIBSource::~CPDF_DIBSource() -{ - delete m_pStreamAcc; - if (m_pMaskedLine) { - FX_Free(m_pMaskedLine); - } - if (m_pLineBuf) { - FX_Free(m_pLineBuf); - } - m_pCachedBitmap.reset(); - delete m_pDecoder; - if (m_pCompData) { - FX_Free(m_pCompData); - } - CPDF_ColorSpace* pCS = m_pColorSpace; - if (pCS && m_pDocument) { - m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray()); - } - if (m_pJbig2Context) { - ICodec_Jbig2Module* pJbig2Module = CPDF_ModuleMgr::Get()->GetJbig2Module(); - pJbig2Module->DestroyJbig2Context(m_pJbig2Context); - } - delete m_pGlobalStream; +CPDF_DIBSource::~CPDF_DIBSource() { + delete m_pStreamAcc; + if (m_pMaskedLine) { + FX_Free(m_pMaskedLine); + } + if (m_pLineBuf) { + FX_Free(m_pLineBuf); + } + m_pCachedBitmap.reset(); + delete m_pDecoder; + if (m_pCompData) { + FX_Free(m_pCompData); + } + CPDF_ColorSpace* pCS = m_pColorSpace; + if (pCS && m_pDocument) { + m_pDocument->GetPageData()->ReleaseColorSpace(pCS->GetArray()); + } + if (m_pJbig2Context) { + ICodec_Jbig2Module* pJbig2Module = CPDF_ModuleMgr::Get()->GetJbig2Module(); + pJbig2Module->DestroyJbig2Context(m_pJbig2Context); + } + delete m_pGlobalStream; } -CFX_DIBitmap* CPDF_DIBSource::GetBitmap() const -{ - return m_pCachedBitmap ? m_pCachedBitmap.get() : Clone(); +CFX_DIBitmap* CPDF_DIBSource::GetBitmap() const { + return m_pCachedBitmap ? m_pCachedBitmap.get() : Clone(); } -void CPDF_DIBSource::ReleaseBitmap(CFX_DIBitmap* pBitmap) const -{ - if (pBitmap && pBitmap != m_pCachedBitmap) { - delete pBitmap; - } +void CPDF_DIBSource::ReleaseBitmap(CFX_DIBitmap* pBitmap) const { + if (pBitmap && pBitmap != m_pCachedBitmap) { + delete pBitmap; + } } -FX_BOOL CPDF_DIBSource::Load(CPDF_Document* pDoc, const CPDF_Stream* pStream, CPDF_DIBSource** ppMask, - FX_DWORD* pMatteColor, CPDF_Dictionary* pFormResources, CPDF_Dictionary* pPageResources, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask) -{ - if (pStream == NULL) { - return FALSE; - } - m_pDocument = pDoc; - m_pDict = pStream->GetDict(); - if (m_pDict == NULL) { - return FALSE; - } - m_pStream = pStream; - m_Width = m_pDict->GetInteger(FX_BSTRC("Width")); - m_Height = m_pDict->GetInteger(FX_BSTRC("Height")); - if (m_Width <= 0 || m_Height <= 0 || m_Width > 0x01ffff || m_Height > 0x01ffff) { - return FALSE; - } - m_GroupFamily = GroupFamily; - m_bLoadMask = bLoadMask; - if (!LoadColorInfo(m_pStream->GetObjNum() != 0 ? NULL : pFormResources, pPageResources)) { - return FALSE; - } - if (m_bDoBpcCheck && (m_bpc == 0 || m_nComponents == 0)) { - return FALSE; - } - FX_SAFE_DWORD src_pitch = - CalculatePitch8(m_bpc, m_nComponents, m_Width, m_Height); - if (!src_pitch.IsValid()) { - return FALSE; - } - m_pStreamAcc = new CPDF_StreamAcc; - m_pStreamAcc->LoadAllData(pStream, FALSE, src_pitch.ValueOrDie(), TRUE); - if (m_pStreamAcc->GetSize() == 0 || m_pStreamAcc->GetData() == NULL) { - return FALSE; - } - if (!CreateDecoder()) { - return FALSE; - } - if (m_bImageMask) { - m_bpp = 1; - m_bpc = 1; - m_nComponents = 1; - m_AlphaFlag = 1; - } else if (m_bpc * m_nComponents == 1) { - m_bpp = 1; - } else if (m_bpc * m_nComponents <= 8) { - m_bpp = 8; - } else { - m_bpp = 24; - } - FX_SAFE_DWORD pitch = CalculatePitch32(m_bpp, m_Width); +FX_BOOL CPDF_DIBSource::Load(CPDF_Document* pDoc, + const CPDF_Stream* pStream, + CPDF_DIBSource** ppMask, + FX_DWORD* pMatteColor, + CPDF_Dictionary* pFormResources, + CPDF_Dictionary* pPageResources, + FX_BOOL bStdCS, + FX_DWORD GroupFamily, + FX_BOOL bLoadMask) { + if (pStream == NULL) { + return FALSE; + } + m_pDocument = pDoc; + m_pDict = pStream->GetDict(); + if (m_pDict == NULL) { + return FALSE; + } + m_pStream = pStream; + m_Width = m_pDict->GetInteger(FX_BSTRC("Width")); + m_Height = m_pDict->GetInteger(FX_BSTRC("Height")); + if (m_Width <= 0 || m_Height <= 0 || m_Width > 0x01ffff || + m_Height > 0x01ffff) { + return FALSE; + } + m_GroupFamily = GroupFamily; + m_bLoadMask = bLoadMask; + if (!LoadColorInfo(m_pStream->GetObjNum() != 0 ? NULL : pFormResources, + pPageResources)) { + return FALSE; + } + if (m_bDoBpcCheck && (m_bpc == 0 || m_nComponents == 0)) { + return FALSE; + } + FX_SAFE_DWORD src_pitch = + CalculatePitch8(m_bpc, m_nComponents, m_Width, m_Height); + if (!src_pitch.IsValid()) { + return FALSE; + } + m_pStreamAcc = new CPDF_StreamAcc; + m_pStreamAcc->LoadAllData(pStream, FALSE, src_pitch.ValueOrDie(), TRUE); + if (m_pStreamAcc->GetSize() == 0 || m_pStreamAcc->GetData() == NULL) { + return FALSE; + } + if (!CreateDecoder()) { + return FALSE; + } + if (m_bImageMask) { + m_bpp = 1; + m_bpc = 1; + m_nComponents = 1; + m_AlphaFlag = 1; + } else if (m_bpc * m_nComponents == 1) { + m_bpp = 1; + } else if (m_bpc * m_nComponents <= 8) { + m_bpp = 8; + } else { + m_bpp = 24; + } + FX_SAFE_DWORD pitch = CalculatePitch32(m_bpp, m_Width); + if (!pitch.IsValid()) { + return FALSE; + } + m_pLineBuf = FX_Alloc(uint8_t, pitch.ValueOrDie()); + if (m_pColorSpace && bStdCS) { + m_pColorSpace->EnableStdConversion(TRUE); + } + LoadPalette(); + if (m_bColorKey) { + m_bpp = 32; + m_AlphaFlag = 2; + pitch = CalculatePitch32(m_bpp, m_Width); if (!pitch.IsValid()) { - return FALSE; - } - m_pLineBuf = FX_Alloc(uint8_t, pitch.ValueOrDie()); - if (m_pColorSpace && bStdCS) { - m_pColorSpace->EnableStdConversion(TRUE); - } - LoadPalette(); - if (m_bColorKey) { - m_bpp = 32; - m_AlphaFlag = 2; - pitch = CalculatePitch32(m_bpp, m_Width); - if (!pitch.IsValid()) { - return FALSE; - } - m_pMaskedLine = FX_Alloc(uint8_t, pitch.ValueOrDie()); - } - m_Pitch = pitch.ValueOrDie(); - if (ppMask) { - *ppMask = LoadMask(*pMatteColor); - } - if (m_pColorSpace && bStdCS) { - m_pColorSpace->EnableStdConversion(FALSE); - } - return TRUE; + return FALSE; + } + m_pMaskedLine = FX_Alloc(uint8_t, pitch.ValueOrDie()); + } + m_Pitch = pitch.ValueOrDie(); + if (ppMask) { + *ppMask = LoadMask(*pMatteColor); + } + if (m_pColorSpace && bStdCS) { + m_pColorSpace->EnableStdConversion(FALSE); + } + return TRUE; } -int CPDF_DIBSource::ContinueToLoadMask() -{ - if (m_bImageMask) { - m_bpp = 1; - m_bpc = 1; - m_nComponents = 1; - m_AlphaFlag = 1; - } else if (m_bpc * m_nComponents == 1) { - m_bpp = 1; - } else if (m_bpc * m_nComponents <= 8) { - m_bpp = 8; - } else { - m_bpp = 24; - } - if (!m_bpc || !m_nComponents) { - return 0; - } - FX_SAFE_DWORD pitch = CalculatePitch32(m_bpp, m_Width); +int CPDF_DIBSource::ContinueToLoadMask() { + if (m_bImageMask) { + m_bpp = 1; + m_bpc = 1; + m_nComponents = 1; + m_AlphaFlag = 1; + } else if (m_bpc * m_nComponents == 1) { + m_bpp = 1; + } else if (m_bpc * m_nComponents <= 8) { + m_bpp = 8; + } else { + m_bpp = 24; + } + if (!m_bpc || !m_nComponents) { + return 0; + } + FX_SAFE_DWORD pitch = CalculatePitch32(m_bpp, m_Width); + if (!pitch.IsValid()) { + return 0; + } + m_pLineBuf = FX_Alloc(uint8_t, pitch.ValueOrDie()); + if (m_pColorSpace && m_bStdCS) { + m_pColorSpace->EnableStdConversion(TRUE); + } + LoadPalette(); + if (m_bColorKey) { + m_bpp = 32; + m_AlphaFlag = 2; + pitch = CalculatePitch32(m_bpp, m_Width); if (!pitch.IsValid()) { - return 0; - } - m_pLineBuf = FX_Alloc(uint8_t, pitch.ValueOrDie()); - if (m_pColorSpace && m_bStdCS) { - m_pColorSpace->EnableStdConversion(TRUE); + return 0; } - LoadPalette(); - if (m_bColorKey) { - m_bpp = 32; - m_AlphaFlag = 2; - pitch = CalculatePitch32(m_bpp, m_Width); - if (!pitch.IsValid()) { - return 0; - } - m_pMaskedLine = FX_Alloc(uint8_t, pitch.ValueOrDie()); - } - m_Pitch = pitch.ValueOrDie(); - return 1; + m_pMaskedLine = FX_Alloc(uint8_t, pitch.ValueOrDie()); + } + m_Pitch = pitch.ValueOrDie(); + return 1; } -int CPDF_DIBSource::StartLoadDIBSource(CPDF_Document* pDoc, const CPDF_Stream* pStream, FX_BOOL bHasMask, - CPDF_Dictionary* pFormResources, CPDF_Dictionary* pPageResources, - FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask) -{ - if (pStream == NULL) { - return 0; - } - m_pDocument = pDoc; - m_pDict = pStream->GetDict(); - m_pStream = pStream; - m_bStdCS = bStdCS; - m_bHasMask = bHasMask; - m_Width = m_pDict->GetInteger(FX_BSTRC("Width")); - m_Height = m_pDict->GetInteger(FX_BSTRC("Height")); - if (m_Width <= 0 || m_Height <= 0 || m_Width > 0x01ffff || m_Height > 0x01ffff) { - return 0; - } - m_GroupFamily = GroupFamily; - m_bLoadMask = bLoadMask; - if (!LoadColorInfo(m_pStream->GetObjNum() != 0 ? NULL : pFormResources, pPageResources)) { - return 0; - } - if (m_bDoBpcCheck && (m_bpc == 0 || m_nComponents == 0)) { - return 0; - } - FX_SAFE_DWORD src_pitch = - CalculatePitch8(m_bpc, m_nComponents, m_Width, m_Height); - if (!src_pitch.IsValid()) { - return 0; - } - m_pStreamAcc = new CPDF_StreamAcc; - m_pStreamAcc->LoadAllData(pStream, FALSE, src_pitch.ValueOrDie(), TRUE); - if (m_pStreamAcc->GetSize() == 0 || m_pStreamAcc->GetData() == NULL) { - return 0; - } - int ret = CreateDecoder(); - if (ret != 1) { - if (!ret) { - return ret; - } - if (!ContinueToLoadMask()) { - return 0; - } - if (m_bHasMask) { - StratLoadMask(); - } - return ret; +int CPDF_DIBSource::StartLoadDIBSource(CPDF_Document* pDoc, + const CPDF_Stream* pStream, + FX_BOOL bHasMask, + CPDF_Dictionary* pFormResources, + CPDF_Dictionary* pPageResources, + FX_BOOL bStdCS, + FX_DWORD GroupFamily, + FX_BOOL bLoadMask) { + if (pStream == NULL) { + return 0; + } + m_pDocument = pDoc; + m_pDict = pStream->GetDict(); + m_pStream = pStream; + m_bStdCS = bStdCS; + m_bHasMask = bHasMask; + m_Width = m_pDict->GetInteger(FX_BSTRC("Width")); + m_Height = m_pDict->GetInteger(FX_BSTRC("Height")); + if (m_Width <= 0 || m_Height <= 0 || m_Width > 0x01ffff || + m_Height > 0x01ffff) { + return 0; + } + m_GroupFamily = GroupFamily; + m_bLoadMask = bLoadMask; + if (!LoadColorInfo(m_pStream->GetObjNum() != 0 ? NULL : pFormResources, + pPageResources)) { + return 0; + } + if (m_bDoBpcCheck && (m_bpc == 0 || m_nComponents == 0)) { + return 0; + } + FX_SAFE_DWORD src_pitch = + CalculatePitch8(m_bpc, m_nComponents, m_Width, m_Height); + if (!src_pitch.IsValid()) { + return 0; + } + m_pStreamAcc = new CPDF_StreamAcc; + m_pStreamAcc->LoadAllData(pStream, FALSE, src_pitch.ValueOrDie(), TRUE); + if (m_pStreamAcc->GetSize() == 0 || m_pStreamAcc->GetData() == NULL) { + return 0; + } + int ret = CreateDecoder(); + if (ret != 1) { + if (!ret) { + return ret; } if (!ContinueToLoadMask()) { - return 0; + return 0; } if (m_bHasMask) { - ret = StratLoadMask(); - } - if (ret == 2) { - return ret; - } - if (m_pColorSpace && m_bStdCS) { - m_pColorSpace->EnableStdConversion(FALSE); + StratLoadMask(); } return ret; + } + if (!ContinueToLoadMask()) { + return 0; + } + if (m_bHasMask) { + ret = StratLoadMask(); + } + if (ret == 2) { + return ret; + } + if (m_pColorSpace && m_bStdCS) { + m_pColorSpace->EnableStdConversion(FALSE); + } + return ret; } -int CPDF_DIBSource::ContinueLoadDIBSource(IFX_Pause* pPause) -{ - FXCODEC_STATUS ret; - if (m_Status == 1) { - const CFX_ByteString& decoder = m_pStreamAcc->GetImageDecoder(); - if (decoder == FX_BSTRC("JPXDecode")) { - return 0; - } - ICodec_Jbig2Module* pJbig2Module = CPDF_ModuleMgr::Get()->GetJbig2Module(); - if (m_pJbig2Context == NULL) { - m_pJbig2Context = pJbig2Module->CreateJbig2Context(); - if (m_pStreamAcc->GetImageParam()) { - CPDF_Stream* pGlobals = m_pStreamAcc->GetImageParam()->GetStream(FX_BSTRC("JBIG2Globals")); - if (pGlobals) { - m_pGlobalStream = new CPDF_StreamAcc; - m_pGlobalStream->LoadAllData(pGlobals, FALSE); - } - } - ret = pJbig2Module->StartDecode(m_pJbig2Context, m_Width, m_Height, m_pStreamAcc->GetData(), m_pStreamAcc->GetSize(), - m_pGlobalStream ? m_pGlobalStream->GetData() : NULL, m_pGlobalStream ? m_pGlobalStream->GetSize() : 0, m_pCachedBitmap->GetBuffer(), - m_pCachedBitmap->GetPitch(), pPause); - if (ret < 0) { - m_pCachedBitmap.reset(); - delete m_pGlobalStream; - m_pGlobalStream = NULL; - pJbig2Module->DestroyJbig2Context(m_pJbig2Context); - m_pJbig2Context = NULL; - return 0; - } - if (ret == FXCODEC_STATUS_DECODE_TOBECONTINUE) { - return 2; - } - int ret1 = 1; - if (m_bHasMask) { - ret1 = ContinueLoadMaskDIB(pPause); - m_Status = 2; - } - if (ret1 == 2) { - return ret1; - } - if (m_pColorSpace && m_bStdCS) { - m_pColorSpace->EnableStdConversion(FALSE); - } - return ret1; - } - FXCODEC_STATUS ret = pJbig2Module->ContinueDecode(m_pJbig2Context, pPause); - if (ret < 0) { - m_pCachedBitmap.reset(); - delete m_pGlobalStream; - m_pGlobalStream = NULL; - pJbig2Module->DestroyJbig2Context(m_pJbig2Context); - m_pJbig2Context = NULL; - return 0; - } - if (ret == FXCODEC_STATUS_DECODE_TOBECONTINUE) { - return 2; - } - int ret1 = 1; - if (m_bHasMask) { - ret1 = ContinueLoadMaskDIB(pPause); - m_Status = 2; - } - if (ret1 == 2) { - return ret1; - } - if (m_pColorSpace && m_bStdCS) { - m_pColorSpace->EnableStdConversion(FALSE); +int CPDF_DIBSource::ContinueLoadDIBSource(IFX_Pause* pPause) { + FXCODEC_STATUS ret; + if (m_Status == 1) { + const CFX_ByteString& decoder = m_pStreamAcc->GetImageDecoder(); + if (decoder == FX_BSTRC("JPXDecode")) { + return 0; + } + ICodec_Jbig2Module* pJbig2Module = CPDF_ModuleMgr::Get()->GetJbig2Module(); + if (m_pJbig2Context == NULL) { + m_pJbig2Context = pJbig2Module->CreateJbig2Context(); + if (m_pStreamAcc->GetImageParam()) { + CPDF_Stream* pGlobals = + m_pStreamAcc->GetImageParam()->GetStream(FX_BSTRC("JBIG2Globals")); + if (pGlobals) { + m_pGlobalStream = new CPDF_StreamAcc; + m_pGlobalStream->LoadAllData(pGlobals, FALSE); } + } + ret = pJbig2Module->StartDecode( + m_pJbig2Context, m_Width, m_Height, m_pStreamAcc->GetData(), + m_pStreamAcc->GetSize(), + m_pGlobalStream ? m_pGlobalStream->GetData() : NULL, + m_pGlobalStream ? m_pGlobalStream->GetSize() : 0, + m_pCachedBitmap->GetBuffer(), m_pCachedBitmap->GetPitch(), pPause); + if (ret < 0) { + m_pCachedBitmap.reset(); + delete m_pGlobalStream; + m_pGlobalStream = NULL; + pJbig2Module->DestroyJbig2Context(m_pJbig2Context); + m_pJbig2Context = NULL; + return 0; + } + if (ret == FXCODEC_STATUS_DECODE_TOBECONTINUE) { + return 2; + } + int ret1 = 1; + if (m_bHasMask) { + ret1 = ContinueLoadMaskDIB(pPause); + m_Status = 2; + } + if (ret1 == 2) { return ret1; + } + if (m_pColorSpace && m_bStdCS) { + m_pColorSpace->EnableStdConversion(FALSE); + } + return ret1; + } + FXCODEC_STATUS ret = pJbig2Module->ContinueDecode(m_pJbig2Context, pPause); + if (ret < 0) { + m_pCachedBitmap.reset(); + delete m_pGlobalStream; + m_pGlobalStream = NULL; + pJbig2Module->DestroyJbig2Context(m_pJbig2Context); + m_pJbig2Context = NULL; + return 0; + } + if (ret == FXCODEC_STATUS_DECODE_TOBECONTINUE) { + return 2; + } + int ret1 = 1; + if (m_bHasMask) { + ret1 = ContinueLoadMaskDIB(pPause); + m_Status = 2; } - if (m_Status == 2) { - return ContinueLoadMaskDIB(pPause); + if (ret1 == 2) { + return ret1; } - return 0; + if (m_pColorSpace && m_bStdCS) { + m_pColorSpace->EnableStdConversion(FALSE); + } + return ret1; + } + if (m_Status == 2) { + return ContinueLoadMaskDIB(pPause); + } + return 0; } -FX_BOOL CPDF_DIBSource::LoadColorInfo(CPDF_Dictionary* pFormResources, CPDF_Dictionary* pPageResources) -{ - m_bpc_orig = m_pDict->GetInteger(FX_BSTRC("BitsPerComponent")); - if (m_pDict->GetInteger("ImageMask")) { - m_bImageMask = TRUE; - } - if (m_bImageMask || !m_pDict->KeyExist(FX_BSTRC("ColorSpace"))) { - if (!m_bImageMask) { - CPDF_Object* pFilter = m_pDict->GetElementValue(FX_BSTRC("Filter")); - if (pFilter) { - CFX_ByteString filter; - if (pFilter->GetType() == PDFOBJ_NAME) { - filter = pFilter->GetString(); - if (filter == FX_BSTRC("JPXDecode")) { - m_bDoBpcCheck = FALSE; - return TRUE; - } - } else if (pFilter->GetType() == PDFOBJ_ARRAY) { - CPDF_Array* pArray = (CPDF_Array*)pFilter; - if (pArray->GetString(pArray->GetCount() - 1) == FX_BSTRC("JPXDecode")) { - m_bDoBpcCheck = FALSE; - return TRUE; - } - } - } - } - m_bImageMask = TRUE; - m_bpc = m_nComponents = 1; - CPDF_Array* pDecode = m_pDict->GetArray(FX_BSTRC("Decode")); - m_bDefaultDecode = pDecode == NULL || pDecode->GetInteger(0) == 0; - return TRUE; - } - CPDF_Object* pCSObj = m_pDict->GetElementValue(FX_BSTRC("ColorSpace")); - if (pCSObj == NULL) { - return FALSE; - } - CPDF_DocPageData* pDocPageData = m_pDocument->GetPageData(); - if (pFormResources) { - m_pColorSpace = pDocPageData->GetColorSpace(pCSObj, pFormResources); - } - if (m_pColorSpace == NULL) { - m_pColorSpace = pDocPageData->GetColorSpace(pCSObj, pPageResources); - } - if (m_pColorSpace == NULL) { - return FALSE; - } - m_Family = m_pColorSpace->GetFamily(); - m_nComponents = m_pColorSpace->CountComponents(); - if (m_Family == PDFCS_ICCBASED && pCSObj->GetType() == PDFOBJ_NAME) { - CFX_ByteString cs = pCSObj->GetString(); - if (cs == FX_BSTRC("DeviceGray")) { - m_nComponents = 1; - } else if (cs == FX_BSTRC("DeviceRGB")) { - m_nComponents = 3; - } else if (cs == FX_BSTRC("DeviceCMYK")) { - m_nComponents = 4; +FX_BOOL CPDF_DIBSource::LoadColorInfo(CPDF_Dictionary* pFormResources, + CPDF_Dictionary* pPageResources) { + m_bpc_orig = m_pDict->GetInteger(FX_BSTRC("BitsPerComponent")); + if (m_pDict->GetInteger("ImageMask")) { + m_bImageMask = TRUE; + } + if (m_bImageMask || !m_pDict->KeyExist(FX_BSTRC("ColorSpace"))) { + if (!m_bImageMask) { + CPDF_Object* pFilter = m_pDict->GetElementValue(FX_BSTRC("Filter")); + if (pFilter) { + CFX_ByteString filter; + if (pFilter->GetType() == PDFOBJ_NAME) { + filter = pFilter->GetString(); + if (filter == FX_BSTRC("JPXDecode")) { + m_bDoBpcCheck = FALSE; + return TRUE; + } + } else if (pFilter->GetType() == PDFOBJ_ARRAY) { + CPDF_Array* pArray = (CPDF_Array*)pFilter; + if (pArray->GetString(pArray->GetCount() - 1) == + FX_BSTRC("JPXDecode")) { + m_bDoBpcCheck = FALSE; + return TRUE; + } } + } } - ValidateDictParam(); - m_pCompData = GetDecodeAndMaskArray(m_bDefaultDecode, m_bColorKey); - if (m_pCompData == NULL) { - return FALSE; - } + m_bImageMask = TRUE; + m_bpc = m_nComponents = 1; + CPDF_Array* pDecode = m_pDict->GetArray(FX_BSTRC("Decode")); + m_bDefaultDecode = pDecode == NULL || pDecode->GetInteger(0) == 0; return TRUE; + } + CPDF_Object* pCSObj = m_pDict->GetElementValue(FX_BSTRC("ColorSpace")); + if (pCSObj == NULL) { + return FALSE; + } + CPDF_DocPageData* pDocPageData = m_pDocument->GetPageData(); + if (pFormResources) { + m_pColorSpace = pDocPageData->GetColorSpace(pCSObj, pFormResources); + } + if (m_pColorSpace == NULL) { + m_pColorSpace = pDocPageData->GetColorSpace(pCSObj, pPageResources); + } + if (m_pColorSpace == NULL) { + return FALSE; + } + m_Family = m_pColorSpace->GetFamily(); + m_nComponents = m_pColorSpace->CountComponents(); + if (m_Family == PDFCS_ICCBASED && pCSObj->GetType() == PDFOBJ_NAME) { + CFX_ByteString cs = pCSObj->GetString(); + if (cs == FX_BSTRC("DeviceGray")) { + m_nComponents = 1; + } else if (cs == FX_BSTRC("DeviceRGB")) { + m_nComponents = 3; + } else if (cs == FX_BSTRC("DeviceCMYK")) { + m_nComponents = 4; + } + } + ValidateDictParam(); + m_pCompData = GetDecodeAndMaskArray(m_bDefaultDecode, m_bColorKey); + if (m_pCompData == NULL) { + return FALSE; + } + return TRUE; } -DIB_COMP_DATA* CPDF_DIBSource::GetDecodeAndMaskArray(FX_BOOL& bDefaultDecode, FX_BOOL& bColorKey) -{ - if (m_pColorSpace == NULL) { - return NULL; - } - DIB_COMP_DATA* pCompData = FX_Alloc(DIB_COMP_DATA, m_nComponents); - int max_data = (1 << m_bpc) - 1; - CPDF_Array* pDecode = m_pDict->GetArray(FX_BSTRC("Decode")); - if (pDecode) { - for (FX_DWORD i = 0; i < m_nComponents; i ++) { - pCompData[i].m_DecodeMin = pDecode->GetNumber(i * 2); - FX_FLOAT max = pDecode->GetNumber(i * 2 + 1); - pCompData[i].m_DecodeStep = (max - pCompData[i].m_DecodeMin) / max_data; - FX_FLOAT def_value, def_min, def_max; - m_pColorSpace->GetDefaultValue(i, def_value, def_min, def_max); - if (m_Family == PDFCS_INDEXED) { - def_max = (FX_FLOAT)max_data; - } - if (def_min != pCompData[i].m_DecodeMin || def_max != max) { - bDefaultDecode = FALSE; - } - } - } else { - for (FX_DWORD i = 0; i < m_nComponents; i ++) { - FX_FLOAT def_value; - m_pColorSpace->GetDefaultValue(i, def_value, pCompData[i].m_DecodeMin, pCompData[i].m_DecodeStep); - if (m_Family == PDFCS_INDEXED) { - pCompData[i].m_DecodeStep = (FX_FLOAT)max_data; - } - pCompData[i].m_DecodeStep = (pCompData[i].m_DecodeStep - pCompData[i].m_DecodeMin) / max_data; - } - } - if (!m_pDict->KeyExist(FX_BSTRC("SMask"))) { - CPDF_Object* pMask = m_pDict->GetElementValue(FX_BSTRC("Mask")); - if (pMask == NULL) { - return pCompData; - } - if (pMask->GetType() == PDFOBJ_ARRAY) { - CPDF_Array* pArray = (CPDF_Array*)pMask; - if (pArray->GetCount() >= m_nComponents * 2) { - for (FX_DWORD i = 0; i < m_nComponents; i++) { - int min_num = pArray->GetInteger(i * 2); - int max_num = pArray->GetInteger(i * 2 + 1); - pCompData[i].m_ColorKeyMin = FX_MAX(min_num, 0); - pCompData[i].m_ColorKeyMax = FX_MIN(max_num, max_data); - } - } - bColorKey = TRUE; +DIB_COMP_DATA* CPDF_DIBSource::GetDecodeAndMaskArray(FX_BOOL& bDefaultDecode, + FX_BOOL& bColorKey) { + if (m_pColorSpace == NULL) { + return NULL; + } + DIB_COMP_DATA* pCompData = FX_Alloc(DIB_COMP_DATA, m_nComponents); + int max_data = (1 << m_bpc) - 1; + CPDF_Array* pDecode = m_pDict->GetArray(FX_BSTRC("Decode")); + if (pDecode) { + for (FX_DWORD i = 0; i < m_nComponents; i++) { + pCompData[i].m_DecodeMin = pDecode->GetNumber(i * 2); + FX_FLOAT max = pDecode->GetNumber(i * 2 + 1); + pCompData[i].m_DecodeStep = (max - pCompData[i].m_DecodeMin) / max_data; + FX_FLOAT def_value, def_min, def_max; + m_pColorSpace->GetDefaultValue(i, def_value, def_min, def_max); + if (m_Family == PDFCS_INDEXED) { + def_max = (FX_FLOAT)max_data; + } + if (def_min != pCompData[i].m_DecodeMin || def_max != max) { + bDefaultDecode = FALSE; + } + } + } else { + for (FX_DWORD i = 0; i < m_nComponents; i++) { + FX_FLOAT def_value; + m_pColorSpace->GetDefaultValue(i, def_value, pCompData[i].m_DecodeMin, + pCompData[i].m_DecodeStep); + if (m_Family == PDFCS_INDEXED) { + pCompData[i].m_DecodeStep = (FX_FLOAT)max_data; + } + pCompData[i].m_DecodeStep = + (pCompData[i].m_DecodeStep - pCompData[i].m_DecodeMin) / max_data; + } + } + if (!m_pDict->KeyExist(FX_BSTRC("SMask"))) { + CPDF_Object* pMask = m_pDict->GetElementValue(FX_BSTRC("Mask")); + if (pMask == NULL) { + return pCompData; + } + if (pMask->GetType() == PDFOBJ_ARRAY) { + CPDF_Array* pArray = (CPDF_Array*)pMask; + if (pArray->GetCount() >= m_nComponents * 2) { + for (FX_DWORD i = 0; i < m_nComponents; i++) { + int min_num = pArray->GetInteger(i * 2); + int max_num = pArray->GetInteger(i * 2 + 1); + pCompData[i].m_ColorKeyMin = FX_MAX(min_num, 0); + pCompData[i].m_ColorKeyMax = FX_MIN(max_num, max_data); } + } + bColorKey = TRUE; } - return pCompData; + } + return pCompData; } -ICodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder(const uint8_t* src_buf, FX_DWORD src_size, int width, int height, - const CPDF_Dictionary* pParams); -ICodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder(const uint8_t* src_buf, FX_DWORD src_size, int width, int height, - int nComps, int bpc, const CPDF_Dictionary* pParams); -int CPDF_DIBSource::CreateDecoder() -{ - const CFX_ByteString& decoder = m_pStreamAcc->GetImageDecoder(); - if (decoder.IsEmpty()) { - return 1; - } - if (m_bDoBpcCheck && m_bpc == 0) { - return 0; - } - const uint8_t* src_data = m_pStreamAcc->GetData(); - FX_DWORD src_size = m_pStreamAcc->GetSize(); - const CPDF_Dictionary* pParams = m_pStreamAcc->GetImageParam(); - if (decoder == FX_BSTRC("CCITTFaxDecode")) { - m_pDecoder = FPDFAPI_CreateFaxDecoder(src_data, src_size, m_Width, m_Height, pParams); - } else if (decoder == FX_BSTRC("DCTDecode")) { - m_pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder( - src_data, src_size, m_Width, m_Height, m_nComponents, - pParams ? pParams->GetInteger("ColorTransform", 1) : 1); - if (!m_pDecoder) { - FX_BOOL bTransform = FALSE; - int comps, bpc; - ICodec_JpegModule* pJpegModule = CPDF_ModuleMgr::Get()->GetJpegModule(); - if (pJpegModule->LoadInfo(src_data, src_size, m_Width, m_Height, comps, bpc, bTransform)) { - if (m_nComponents != comps) { - FX_Free(m_pCompData); - m_nComponents = comps; - if (m_Family == PDFCS_LAB && m_nComponents != 3) { - m_pCompData = NULL; - return 0; - } - m_pCompData = GetDecodeAndMaskArray(m_bDefaultDecode, m_bColorKey); - if (m_pCompData == NULL) { - return 0; - } - } - m_bpc = bpc; - m_pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder(src_data, src_size, m_Width, m_Height, - m_nComponents, bTransform); - } - } - } else if (decoder == FX_BSTRC("FlateDecode")) { - m_pDecoder = FPDFAPI_CreateFlateDecoder(src_data, src_size, m_Width, m_Height, m_nComponents, m_bpc, pParams); - } else if (decoder == FX_BSTRC("JPXDecode")) { - LoadJpxBitmap(); - return m_pCachedBitmap ? 1 : 0; - } else if (decoder == FX_BSTRC("JBIG2Decode")) { - m_pCachedBitmap.reset(new CFX_DIBitmap); - if (!m_pCachedBitmap->Create(m_Width, m_Height, m_bImageMask ? FXDIB_1bppMask : FXDIB_1bppRgb)) { - m_pCachedBitmap.reset(); +ICodec_ScanlineDecoder* FPDFAPI_CreateFaxDecoder( + const uint8_t* src_buf, + FX_DWORD src_size, + int width, + int height, + const CPDF_Dictionary* pParams); +ICodec_ScanlineDecoder* FPDFAPI_CreateFlateDecoder( + const uint8_t* src_buf, + FX_DWORD src_size, + int width, + int height, + int nComps, + int bpc, + const CPDF_Dictionary* pParams); +int CPDF_DIBSource::CreateDecoder() { + const CFX_ByteString& decoder = m_pStreamAcc->GetImageDecoder(); + if (decoder.IsEmpty()) { + return 1; + } + if (m_bDoBpcCheck && m_bpc == 0) { + return 0; + } + const uint8_t* src_data = m_pStreamAcc->GetData(); + FX_DWORD src_size = m_pStreamAcc->GetSize(); + const CPDF_Dictionary* pParams = m_pStreamAcc->GetImageParam(); + if (decoder == FX_BSTRC("CCITTFaxDecode")) { + m_pDecoder = FPDFAPI_CreateFaxDecoder(src_data, src_size, m_Width, m_Height, + pParams); + } else if (decoder == FX_BSTRC("DCTDecode")) { + m_pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder( + src_data, src_size, m_Width, m_Height, m_nComponents, + pParams ? pParams->GetInteger("ColorTransform", 1) : 1); + if (!m_pDecoder) { + FX_BOOL bTransform = FALSE; + int comps, bpc; + ICodec_JpegModule* pJpegModule = CPDF_ModuleMgr::Get()->GetJpegModule(); + if (pJpegModule->LoadInfo(src_data, src_size, m_Width, m_Height, comps, + bpc, bTransform)) { + if (m_nComponents != comps) { + FX_Free(m_pCompData); + m_nComponents = comps; + if (m_Family == PDFCS_LAB && m_nComponents != 3) { + m_pCompData = NULL; + return 0; + } + m_pCompData = GetDecodeAndMaskArray(m_bDefaultDecode, m_bColorKey); + if (m_pCompData == NULL) { return 0; + } } - m_Status = 1; - return 2; - } else if (decoder == FX_BSTRC("RunLengthDecode")) { - m_pDecoder = CPDF_ModuleMgr::Get()->GetCodecModule()->GetBasicModule()->CreateRunLengthDecoder(src_data, src_size, m_Width, m_Height, m_nComponents, m_bpc); - } - if (!m_pDecoder) - return 0; + m_bpc = bpc; + m_pDecoder = CPDF_ModuleMgr::Get()->GetJpegModule()->CreateDecoder( + src_data, src_size, m_Width, m_Height, m_nComponents, bTransform); + } + } + } else if (decoder == FX_BSTRC("FlateDecode")) { + m_pDecoder = FPDFAPI_CreateFlateDecoder( + src_data, src_size, m_Width, m_Height, m_nComponents, m_bpc, pParams); + } else if (decoder == FX_BSTRC("JPXDecode")) { + LoadJpxBitmap(); + return m_pCachedBitmap ? 1 : 0; + } else if (decoder == FX_BSTRC("JBIG2Decode")) { + m_pCachedBitmap.reset(new CFX_DIBitmap); + if (!m_pCachedBitmap->Create( + m_Width, m_Height, m_bImageMask ? FXDIB_1bppMask : FXDIB_1bppRgb)) { + m_pCachedBitmap.reset(); + return 0; + } + m_Status = 1; + return 2; + } else if (decoder == FX_BSTRC("RunLengthDecode")) { + m_pDecoder = CPDF_ModuleMgr::Get() + ->GetCodecModule() + ->GetBasicModule() + ->CreateRunLengthDecoder(src_data, src_size, m_Width, + m_Height, m_nComponents, m_bpc); + } + if (!m_pDecoder) + return 0; - FX_SAFE_DWORD requested_pitch = - CalculatePitch8(m_bpc, m_nComponents, m_Width, 1); - if (!requested_pitch.IsValid()) { - return 0; - } - FX_SAFE_DWORD provided_pitch = CalculatePitch8(m_pDecoder->GetBPC(), - m_pDecoder->CountComps(), - m_pDecoder->GetWidth(), - 1); - if (!provided_pitch.IsValid()) { - return 0; - } - if (provided_pitch.ValueOrDie() < requested_pitch.ValueOrDie()) { - return 0; - } - return 1; + FX_SAFE_DWORD requested_pitch = + CalculatePitch8(m_bpc, m_nComponents, m_Width, 1); + if (!requested_pitch.IsValid()) { + return 0; + } + FX_SAFE_DWORD provided_pitch = + CalculatePitch8(m_pDecoder->GetBPC(), m_pDecoder->CountComps(), + m_pDecoder->GetWidth(), 1); + if (!provided_pitch.IsValid()) { + return 0; + } + if (provided_pitch.ValueOrDie() < requested_pitch.ValueOrDie()) { + return 0; + } + return 1; } -void CPDF_DIBSource::LoadJpxBitmap() -{ - ICodec_JpxModule* pJpxModule = CPDF_ModuleMgr::Get()->GetJpxModule(); - if (!pJpxModule) - return; +void CPDF_DIBSource::LoadJpxBitmap() { + ICodec_JpxModule* pJpxModule = CPDF_ModuleMgr::Get()->GetJpxModule(); + if (!pJpxModule) + return; - nonstd::unique_ptr<JpxBitMapContext> context( - new JpxBitMapContext(pJpxModule)); - context->set_context(pJpxModule->CreateDecoder(m_pStreamAcc->GetData(), - m_pStreamAcc->GetSize(), - m_pColorSpace != nullptr)); - if (!context->context()) - return; + nonstd::unique_ptr<JpxBitMapContext> context( + new JpxBitMapContext(pJpxModule)); + context->set_context(pJpxModule->CreateDecoder(m_pStreamAcc->GetData(), + m_pStreamAcc->GetSize(), + m_pColorSpace != nullptr)); + if (!context->context()) + return; - FX_DWORD width = 0; - FX_DWORD height = 0; - FX_DWORD codestream_nComps = 0; - FX_DWORD image_nComps = 0; - pJpxModule->GetImageInfo(context->context(), width, height, - codestream_nComps, image_nComps); - if ((int)width < m_Width || (int)height < m_Height) - return; + FX_DWORD width = 0; + FX_DWORD height = 0; + FX_DWORD codestream_nComps = 0; + FX_DWORD image_nComps = 0; + pJpxModule->GetImageInfo(context->context(), width, height, codestream_nComps, + image_nComps); + if ((int)width < m_Width || (int)height < m_Height) + return; - int output_nComps; - FX_BOOL bTranslateColor; - FX_BOOL bSwapRGB = FALSE; - if (m_pColorSpace) { - if (codestream_nComps != (FX_DWORD)m_pColorSpace->CountComponents()) - return; - output_nComps = codestream_nComps; - bTranslateColor = FALSE; - if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB)) { - bSwapRGB = TRUE; - m_pColorSpace = nullptr; - } + int output_nComps; + FX_BOOL bTranslateColor; + FX_BOOL bSwapRGB = FALSE; + if (m_pColorSpace) { + if (codestream_nComps != (FX_DWORD)m_pColorSpace->CountComponents()) + return; + output_nComps = codestream_nComps; + bTranslateColor = FALSE; + if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICERGB)) { + bSwapRGB = TRUE; + m_pColorSpace = nullptr; + } + } else { + bTranslateColor = TRUE; + if (image_nComps) { + output_nComps = image_nComps; } else { - bTranslateColor = TRUE; - if (image_nComps) { - output_nComps = image_nComps; - } else { - output_nComps = codestream_nComps; - } - if (output_nComps == 3) { - bSwapRGB = TRUE; - } else if (output_nComps == 4) { - m_pColorSpace = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); - bTranslateColor = FALSE; - } - m_nComponents = output_nComps; + output_nComps = codestream_nComps; } - FXDIB_Format format; - if (output_nComps == 1) { - format = FXDIB_8bppRgb; - } else if (output_nComps <= 3) { - format = FXDIB_Rgb; + if (output_nComps == 3) { + bSwapRGB = TRUE; } else if (output_nComps == 4) { - format = FXDIB_Rgb32; - } else { - width = (width * output_nComps + 2) / 3; - format = FXDIB_Rgb; - } - m_pCachedBitmap.reset(new CFX_DIBitmap); - if (!m_pCachedBitmap->Create(width, height, format)) { - m_pCachedBitmap.reset(); - return; - } - m_pCachedBitmap->Clear(0xFFFFFFFF); - context->set_output_offsets(FX_Alloc(uint8_t, output_nComps)); - for (int i = 0; i < output_nComps; ++i) - context->output_offsets()[i] = i; - if (bSwapRGB) { - context->output_offsets()[0] = 2; - context->output_offsets()[2] = 0; - } - if (!pJpxModule->Decode(context->context(), - m_pCachedBitmap->GetBuffer(), - m_pCachedBitmap->GetPitch(), - bTranslateColor, - context->output_offsets())) { - m_pCachedBitmap.reset(); - return; - } - if (m_pColorSpace && - m_pColorSpace->GetFamily() == PDFCS_INDEXED && - m_bpc < 8) { - int scale = 8 - m_bpc; - for (FX_DWORD row = 0; row < height; ++row) { - uint8_t* scanline = (uint8_t*)m_pCachedBitmap->GetScanline(row); - for (FX_DWORD col = 0; col < width; ++col) { - *scanline = (*scanline) >> scale; - ++scanline; - } - } - } - m_bpc = 8; + m_pColorSpace = CPDF_ColorSpace::GetStockCS(PDFCS_DEVICECMYK); + bTranslateColor = FALSE; + } + m_nComponents = output_nComps; + } + FXDIB_Format format; + if (output_nComps == 1) { + format = FXDIB_8bppRgb; + } else if (output_nComps <= 3) { + format = FXDIB_Rgb; + } else if (output_nComps == 4) { + format = FXDIB_Rgb32; + } else { + width = (width * output_nComps + 2) / 3; + format = FXDIB_Rgb; + } + m_pCachedBitmap.reset(new CFX_DIBitmap); + if (!m_pCachedBitmap->Create(width, height, format)) { + m_pCachedBitmap.reset(); + return; + } + m_pCachedBitmap->Clear(0xFFFFFFFF); + context->set_output_offsets(FX_Alloc(uint8_t, output_nComps)); + for (int i = 0; i < output_nComps; ++i) + context->output_offsets()[i] = i; + if (bSwapRGB) { + context->output_offsets()[0] = 2; + context->output_offsets()[2] = 0; + } + if (!pJpxModule->Decode(context->context(), m_pCachedBitmap->GetBuffer(), + m_pCachedBitmap->GetPitch(), bTranslateColor, + context->output_offsets())) { + m_pCachedBitmap.reset(); + return; + } + if (m_pColorSpace && m_pColorSpace->GetFamily() == PDFCS_INDEXED && + m_bpc < 8) { + int scale = 8 - m_bpc; + for (FX_DWORD row = 0; row < height; ++row) { + uint8_t* scanline = (uint8_t*)m_pCachedBitmap->GetScanline(row); + for (FX_DWORD col = 0; col < width; ++col) { + *scanline = (*scanline) >> scale; + ++scanline; + } + } + } + m_bpc = 8; } -CPDF_DIBSource* CPDF_DIBSource::LoadMask(FX_DWORD& MatteColor) -{ - MatteColor = 0xffffffff; - CPDF_Stream* pSoftMask = m_pDict->GetStream(FX_BSTRC("SMask")); - if (pSoftMask) { - CPDF_Array* pMatte = pSoftMask->GetDict()->GetArray(FX_BSTRC("Matte")); - if (pMatte != NULL && m_pColorSpace && (FX_DWORD)m_pColorSpace->CountComponents() <= m_nComponents) { - FX_FLOAT* pColor = FX_Alloc(FX_FLOAT, m_nComponents); - for (FX_DWORD i = 0; i < m_nComponents; i ++) { - pColor[i] = pMatte->GetFloat(i); - } - FX_FLOAT R, G, B; - m_pColorSpace->GetRGB(pColor, R, G, B); - FX_Free(pColor); - MatteColor = FXARGB_MAKE(0, FXSYS_round(R * 255), FXSYS_round(G * 255), FXSYS_round(B * 255)); - } - return LoadMaskDIB(pSoftMask); - } - CPDF_Object* pMask = m_pDict->GetElementValue(FX_BSTRC("Mask")); - if (pMask == NULL) { - return NULL; - } - if (pMask->GetType() == PDFOBJ_STREAM) { - return LoadMaskDIB((CPDF_Stream*)pMask); - } +CPDF_DIBSource* CPDF_DIBSource::LoadMask(FX_DWORD& MatteColor) { + MatteColor = 0xffffffff; + CPDF_Stream* pSoftMask = m_pDict->GetStream(FX_BSTRC("SMask")); + if (pSoftMask) { + CPDF_Array* pMatte = pSoftMask->GetDict()->GetArray(FX_BSTRC("Matte")); + if (pMatte != NULL && m_pColorSpace && + (FX_DWORD)m_pColorSpace->CountComponents() <= m_nComponents) { + FX_FLOAT* pColor = FX_Alloc(FX_FLOAT, m_nComponents); + for (FX_DWORD i = 0; i < m_nComponents; i++) { + pColor[i] = pMatte->GetFloat(i); + } + FX_FLOAT R, G, B; + m_pColorSpace->GetRGB(pColor, R, G, B); + FX_Free(pColor); + MatteColor = FXARGB_MAKE(0, FXSYS_round(R * 255), FXSYS_round(G * 255), + FXSYS_round(B * 255)); + } + return LoadMaskDIB(pSoftMask); + } + CPDF_Object* pMask = m_pDict->GetElementValue(FX_BSTRC("Mask")); + if (pMask == NULL) { return NULL; + } + if (pMask->GetType() == PDFOBJ_STREAM) { + return LoadMaskDIB((CPDF_Stream*)pMask); + } + return NULL; } -int CPDF_DIBSource::StratLoadMask() -{ - m_MatteColor = 0xffffffff; - m_pMaskStream = m_pDict->GetStream(FX_BSTRC("SMask")); - if (m_pMaskStream) { - CPDF_Array* pMatte = m_pMaskStream->GetDict()->GetArray(FX_BSTRC("Matte")); - if (pMatte != NULL && m_pColorSpace && (FX_DWORD)m_pColorSpace->CountComponents() <= m_nComponents) { - FX_FLOAT R, G, B; - FX_FLOAT* pColor = FX_Alloc(FX_FLOAT, m_nComponents); - for (FX_DWORD i = 0; i < m_nComponents; i ++) { - pColor[i] = pMatte->GetFloat(i); - } - m_pColorSpace->GetRGB(pColor, R, G, B); - FX_Free(pColor); - m_MatteColor = FXARGB_MAKE(0, FXSYS_round(R * 255), FXSYS_round(G * 255), FXSYS_round(B * 255)); - } - return StartLoadMaskDIB(); - } - m_pMaskStream = m_pDict->GetElementValue(FX_BSTRC("Mask")); - if (m_pMaskStream == NULL) { - return 1; - } - if (m_pMaskStream->GetType() == PDFOBJ_STREAM) { - return StartLoadMaskDIB(); - } +int CPDF_DIBSource::StratLoadMask() { + m_MatteColor = 0xffffffff; + m_pMaskStream = m_pDict->GetStream(FX_BSTRC("SMask")); + if (m_pMaskStream) { + CPDF_Array* pMatte = m_pMaskStream->GetDict()->GetArray(FX_BSTRC("Matte")); + if (pMatte != NULL && m_pColorSpace && + (FX_DWORD)m_pColorSpace->CountComponents() <= m_nComponents) { + FX_FLOAT R, G, B; + FX_FLOAT* pColor = FX_Alloc(FX_FLOAT, m_nComponents); + for (FX_DWORD i = 0; i < m_nComponents; i++) { + pColor[i] = pMatte->GetFloat(i); + } + m_pColorSpace->GetRGB(pColor, R, G, B); + FX_Free(pColor); + m_MatteColor = FXARGB_MAKE(0, FXSYS_round(R * 255), FXSYS_round(G * 255), + FXSYS_round(B * 255)); + } + return StartLoadMaskDIB(); + } + m_pMaskStream = m_pDict->GetElementValue(FX_BSTRC("Mask")); + if (m_pMaskStream == NULL) { return 1; + } + if (m_pMaskStream->GetType() == PDFOBJ_STREAM) { + return StartLoadMaskDIB(); + } + return 1; } -int CPDF_DIBSource::ContinueLoadMaskDIB(IFX_Pause* pPause) -{ - if (m_pMask == NULL) { - return 1; - } - int ret = m_pMask->ContinueLoadDIBSource(pPause); - if (ret == 2) { - return ret; - } - if (m_pColorSpace && m_bStdCS) { - m_pColorSpace->EnableStdConversion(FALSE); - } - if (!ret) { - delete m_pMask; - m_pMask = NULL; - return ret; - } +int CPDF_DIBSource::ContinueLoadMaskDIB(IFX_Pause* pPause) { + if (m_pMask == NULL) { return 1; -} -CPDF_DIBSource* CPDF_DIBSource::DetachMask() -{ - CPDF_DIBSource* pDIBSource = m_pMask; + } + int ret = m_pMask->ContinueLoadDIBSource(pPause); + if (ret == 2) { + return ret; + } + if (m_pColorSpace && m_bStdCS) { + m_pColorSpace->EnableStdConversion(FALSE); + } + if (!ret) { + delete m_pMask; m_pMask = NULL; - return pDIBSource; + return ret; + } + return 1; } -CPDF_DIBSource* CPDF_DIBSource::LoadMaskDIB(CPDF_Stream* pMask) -{ - CPDF_DIBSource* pMaskSource = new CPDF_DIBSource; - if (!pMaskSource->Load(m_pDocument, pMask, NULL, NULL, NULL, NULL, TRUE)) { - delete pMaskSource; - return NULL; - } - return pMaskSource; +CPDF_DIBSource* CPDF_DIBSource::DetachMask() { + CPDF_DIBSource* pDIBSource = m_pMask; + m_pMask = NULL; + return pDIBSource; } -int CPDF_DIBSource::StartLoadMaskDIB() -{ - m_pMask = new CPDF_DIBSource; - int ret = m_pMask->StartLoadDIBSource(m_pDocument, (CPDF_Stream*)m_pMaskStream, FALSE, NULL, NULL, TRUE); - if (ret == 2) { - if (m_Status == 0) { - m_Status = 2; - } - return 2; - } - if (!ret) { - delete m_pMask; - m_pMask = NULL; - return 1; - } +CPDF_DIBSource* CPDF_DIBSource::LoadMaskDIB(CPDF_Stream* pMask) { + CPDF_DIBSource* pMaskSource = new CPDF_DIBSource; + if (!pMaskSource->Load(m_pDocument, pMask, NULL, NULL, NULL, NULL, TRUE)) { + delete pMaskSource; + return NULL; + } + return pMaskSource; +} +int CPDF_DIBSource::StartLoadMaskDIB() { + m_pMask = new CPDF_DIBSource; + int ret = m_pMask->StartLoadDIBSource( + m_pDocument, (CPDF_Stream*)m_pMaskStream, FALSE, NULL, NULL, TRUE); + if (ret == 2) { + if (m_Status == 0) { + m_Status = 2; + } + return 2; + } + if (!ret) { + delete m_pMask; + m_pMask = NULL; return 1; + } + return 1; } -void CPDF_DIBSource::LoadPalette() -{ - if (m_bpc == 0) { - return; - } - if (m_bpc * m_nComponents > 8) { - return; - } - if (m_pColorSpace == NULL) { - return; - } - if (m_bpc * m_nComponents == 1) { - if (m_bDefaultDecode && (m_Family == PDFCS_DEVICEGRAY || m_Family == PDFCS_DEVICERGB)) { - return; - } - if (m_pColorSpace->CountComponents() > 3) { - return; - } - FX_FLOAT color_values[3]; - color_values[0] = m_pCompData[0].m_DecodeMin; - color_values[1] = color_values[2] = color_values[0]; - FX_FLOAT R=0.0f, G=0.0f, B=0.0f; - m_pColorSpace->GetRGB(color_values, R, G, B); - FX_ARGB argb0 = ArgbEncode(255, FXSYS_round(R * 255), FXSYS_round(G * 255), FXSYS_round(B * 255)); - color_values[0] += m_pCompData[0].m_DecodeStep; - color_values[1] += m_pCompData[0].m_DecodeStep; - color_values[2] += m_pCompData[0].m_DecodeStep; - m_pColorSpace->GetRGB(color_values, R, G, B); - FX_ARGB argb1 = ArgbEncode(255, FXSYS_round(R * 255), FXSYS_round(G * 255), FXSYS_round(B * 255)); - if (argb0 != 0xFF000000 || argb1 != 0xFFFFFFFF) { - SetPaletteArgb(0, argb0); - SetPaletteArgb(1, argb1); - } - return; - } - if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY) && m_bpc == 8 && m_bDefaultDecode) { - } else { - int palette_count = 1 << (m_bpc * m_nComponents); - CFX_FixedBufGrow<FX_FLOAT, 16> color_values(m_nComponents); - FX_FLOAT* color_value = color_values; - for (int i = 0; i < palette_count; i ++) { - int color_data = i; - for (FX_DWORD j = 0; j < m_nComponents; j ++) { - int encoded_component = color_data % (1 << m_bpc); - color_data /= 1 << m_bpc; - color_value[j] = m_pCompData[j].m_DecodeMin + m_pCompData[j].m_DecodeStep * encoded_component; - } - FX_FLOAT R = 0, G = 0, B = 0; - if (m_nComponents == 1 && m_Family == PDFCS_ICCBASED && m_pColorSpace->CountComponents() > 1) { - int nComponents = m_pColorSpace->CountComponents(); - FX_FLOAT* temp_buf = FX_Alloc(FX_FLOAT, nComponents); - for (int i = 0; i < nComponents; i++) { - temp_buf[i] = *color_value; - } - m_pColorSpace->GetRGB(temp_buf, R, G, B); - FX_Free(temp_buf); - } else { - m_pColorSpace->GetRGB(color_value, R, G, B); - } - SetPaletteArgb(i, ArgbEncode(255, FXSYS_round(R * 255), FXSYS_round(G * 255), FXSYS_round(B * 255))); +void CPDF_DIBSource::LoadPalette() { + if (m_bpc == 0) { + return; + } + if (m_bpc * m_nComponents > 8) { + return; + } + if (m_pColorSpace == NULL) { + return; + } + if (m_bpc * m_nComponents == 1) { + if (m_bDefaultDecode && + (m_Family == PDFCS_DEVICEGRAY || m_Family == PDFCS_DEVICERGB)) { + return; + } + if (m_pColorSpace->CountComponents() > 3) { + return; + } + FX_FLOAT color_values[3]; + color_values[0] = m_pCompData[0].m_DecodeMin; + color_values[1] = color_values[2] = color_values[0]; + FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; + m_pColorSpace->GetRGB(color_values, R, G, B); + FX_ARGB argb0 = ArgbEncode(255, FXSYS_round(R * 255), FXSYS_round(G * 255), + FXSYS_round(B * 255)); + color_values[0] += m_pCompData[0].m_DecodeStep; + color_values[1] += m_pCompData[0].m_DecodeStep; + color_values[2] += m_pCompData[0].m_DecodeStep; + m_pColorSpace->GetRGB(color_values, R, G, B); + FX_ARGB argb1 = ArgbEncode(255, FXSYS_round(R * 255), FXSYS_round(G * 255), + FXSYS_round(B * 255)); + if (argb0 != 0xFF000000 || argb1 != 0xFFFFFFFF) { + SetPaletteArgb(0, argb0); + SetPaletteArgb(1, argb1); + } + return; + } + if (m_pColorSpace == CPDF_ColorSpace::GetStockCS(PDFCS_DEVICEGRAY) && + m_bpc == 8 && m_bDefaultDecode) { + } else { + int palette_count = 1 << (m_bpc * m_nComponents); + CFX_FixedBufGrow<FX_FLOAT, 16> color_values(m_nComponents); + FX_FLOAT* color_value = color_values; + for (int i = 0; i < palette_count; i++) { + int color_data = i; + for (FX_DWORD j = 0; j < m_nComponents; j++) { + int encoded_component = color_data % (1 << m_bpc); + color_data /= 1 << m_bpc; + color_value[j] = m_pCompData[j].m_DecodeMin + + m_pCompData[j].m_DecodeStep * encoded_component; + } + FX_FLOAT R = 0, G = 0, B = 0; + if (m_nComponents == 1 && m_Family == PDFCS_ICCBASED && + m_pColorSpace->CountComponents() > 1) { + int nComponents = m_pColorSpace->CountComponents(); + FX_FLOAT* temp_buf = FX_Alloc(FX_FLOAT, nComponents); + for (int i = 0; i < nComponents; i++) { + temp_buf[i] = *color_value; } - } + m_pColorSpace->GetRGB(temp_buf, R, G, B); + FX_Free(temp_buf); + } else { + m_pColorSpace->GetRGB(color_value, R, G, B); + } + SetPaletteArgb(i, ArgbEncode(255, FXSYS_round(R * 255), + FXSYS_round(G * 255), FXSYS_round(B * 255))); + } + } } -void CPDF_DIBSource::ValidateDictParam() -{ - m_bpc = m_bpc_orig; - CPDF_Object * pFilter = m_pDict->GetElementValue(FX_BSTRC("Filter")); - if (pFilter) { - if (pFilter->GetType() == PDFOBJ_NAME) { - CFX_ByteString filter = pFilter->GetString(); - if (filter == FX_BSTRC("CCITTFaxDecode") || filter == FX_BSTRC("JBIG2Decode")) { - m_bpc = 1; - m_nComponents = 1; - } - if (filter == FX_BSTRC("RunLengthDecode") || filter == FX_BSTRC("DCTDecode")) { - m_bpc = 8; - } - } else if (pFilter->GetType() == PDFOBJ_ARRAY) { - CPDF_Array *pArray = (CPDF_Array *)pFilter; - if (pArray->GetString(pArray->GetCount() - 1) == FX_BSTRC("CCITTFaxDecode") || - pArray->GetString(pArray->GetCount() - 1) == FX_BSTRC("JBIG2Decode")) { - m_bpc = 1; - m_nComponents = 1; - } - if (pArray->GetString(pArray->GetCount() - 1) == FX_BSTRC("DCTDecode")) { - // Previously, pArray->GetString(pArray->GetCount() - 1) == FX_BSTRC("RunLengthDecode") was checked in the "if" statement as well, - // but too many documents don't conform to it. - m_bpc = 8; - } - } - } - if (m_bpc != 1 && m_bpc != 2 && m_bpc != 4 && m_bpc != 8 && m_bpc != 16) { - m_bpc = 0; - } +void CPDF_DIBSource::ValidateDictParam() { + m_bpc = m_bpc_orig; + CPDF_Object* pFilter = m_pDict->GetElementValue(FX_BSTRC("Filter")); + if (pFilter) { + if (pFilter->GetType() == PDFOBJ_NAME) { + CFX_ByteString filter = pFilter->GetString(); + if (filter == FX_BSTRC("CCITTFaxDecode") || + filter == FX_BSTRC("JBIG2Decode")) { + m_bpc = 1; + m_nComponents = 1; + } + if (filter == FX_BSTRC("RunLengthDecode") || + filter == FX_BSTRC("DCTDecode")) { + m_bpc = 8; + } + } else if (pFilter->GetType() == PDFOBJ_ARRAY) { + CPDF_Array* pArray = (CPDF_Array*)pFilter; + if (pArray->GetString(pArray->GetCount() - 1) == + FX_BSTRC("CCITTFaxDecode") || + pArray->GetString(pArray->GetCount() - 1) == + FX_BSTRC("JBIG2Decode")) { + m_bpc = 1; + m_nComponents = 1; + } + if (pArray->GetString(pArray->GetCount() - 1) == FX_BSTRC("DCTDecode")) { + // Previously, pArray->GetString(pArray->GetCount() - 1) == + // FX_BSTRC("RunLengthDecode") was checked in the "if" statement as + // well, + // but too many documents don't conform to it. + m_bpc = 8; + } + } + } + if (m_bpc != 1 && m_bpc != 2 && m_bpc != 4 && m_bpc != 8 && m_bpc != 16) { + m_bpc = 0; + } } -#define NORMALCOLOR_MAX(color, max) (color) > (max) ? (max) : (color) < 0 ? 0 : (color); -void CPDF_DIBSource::TranslateScanline24bpp(uint8_t* dest_scan, const uint8_t* src_scan) const -{ - if (m_bpc == 0) { - return; - } - int max_data = (1 << m_bpc) - 1; - if (m_bDefaultDecode) { - if (m_Family == PDFCS_DEVICERGB || m_Family == PDFCS_CALRGB) { - const uint8_t* src_pos = src_scan; - switch (m_bpc) { - case 16: - for (int col = 0; col < m_Width; col ++) { - *dest_scan++ = src_pos[4]; - *dest_scan++ = src_pos[2]; - *dest_scan++ = *src_pos; - src_pos += 6; - } - break; - case 8: - for (int column = 0; column < m_Width; column ++) { - *dest_scan++ = src_pos[2]; - *dest_scan++ = src_pos[1]; - *dest_scan++ = *src_pos; - src_pos += 3; - } - break; - default: - int src_bit_pos = 0; - int dest_byte_pos = 0; - for (int column = 0; column < m_Width; column ++) { - int R = _GetBits8(src_scan, src_bit_pos, m_bpc); - src_bit_pos += m_bpc; - int G = _GetBits8(src_scan, src_bit_pos, m_bpc); - src_bit_pos += m_bpc; - int B = _GetBits8(src_scan, src_bit_pos, m_bpc); - src_bit_pos += m_bpc; - R = NORMALCOLOR_MAX(R, max_data); - G = NORMALCOLOR_MAX(G, max_data); - B = NORMALCOLOR_MAX(B, max_data); - dest_scan[dest_byte_pos] = B * 255 / max_data; - dest_scan[dest_byte_pos + 1] = G * 255 / max_data; - dest_scan[dest_byte_pos + 2] = R * 255 / max_data; - dest_byte_pos += 3; - } - break; - } - return; - } - if (m_bpc == 8) { - if (m_nComponents == m_pColorSpace->CountComponents()) - m_pColorSpace->TranslateImageLine(dest_scan, src_scan, m_Width, m_Width, m_Height, - m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && m_Family == PDFCS_DEVICECMYK); - return; - } - } - CFX_FixedBufGrow<FX_FLOAT, 16> color_values1(m_nComponents); - FX_FLOAT* color_values = color_values1; - FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; - if (m_bpc == 8) { - int src_byte_pos = 0; - int dest_byte_pos = 0; - for (int column = 0; column < m_Width; column ++) { - for (FX_DWORD color = 0; color < m_nComponents; color ++) { - int data = src_scan[src_byte_pos ++]; - color_values[color] = m_pCompData[color].m_DecodeMin + - m_pCompData[color].m_DecodeStep * data; - } - if (m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && m_Family == PDFCS_DEVICECMYK) { - FX_FLOAT k = 1.0f - color_values[3]; - R = (1.0f - color_values[0]) * k; - G = (1.0f - color_values[1]) * k; - B = (1.0f - color_values[2]) * k; - } else { - m_pColorSpace->GetRGB(color_values, R, G, B); - } - R = NORMALCOLOR_MAX(R, 1); - G = NORMALCOLOR_MAX(G, 1); - B = NORMALCOLOR_MAX(B, 1); - dest_scan[dest_byte_pos] = (int32_t)(B * 255); - dest_scan[dest_byte_pos + 1] = (int32_t)(G * 255); - dest_scan[dest_byte_pos + 2] = (int32_t)(R * 255); - dest_byte_pos += 3; - } - } else { - int src_bit_pos = 0; - int dest_byte_pos = 0; - for (int column = 0; column < m_Width; column ++) { - for (FX_DWORD color = 0; color < m_nComponents; color ++) { - int data = _GetBits8(src_scan, src_bit_pos, m_bpc); - color_values[color] = m_pCompData[color].m_DecodeMin + - m_pCompData[color].m_DecodeStep * data; - src_bit_pos += m_bpc; - } - if (m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && m_Family == PDFCS_DEVICECMYK) { - FX_FLOAT k = 1.0f - color_values[3]; - R = (1.0f - color_values[0]) * k; - G = (1.0f - color_values[1]) * k; - B = (1.0f - color_values[2]) * k; - } else { - m_pColorSpace->GetRGB(color_values, R, G, B); - } - R = NORMALCOLOR_MAX(R, 1); - G = NORMALCOLOR_MAX(G, 1); - B = NORMALCOLOR_MAX(B, 1); - dest_scan[dest_byte_pos] = (int32_t)(B * 255); - dest_scan[dest_byte_pos + 1] = (int32_t)(G * 255); - dest_scan[dest_byte_pos + 2] = (int32_t)(R * 255); +#define NORMALCOLOR_MAX(color, max) \ + (color) > (max) ? (max) : (color) < 0 ? 0 : (color); +void CPDF_DIBSource::TranslateScanline24bpp(uint8_t* dest_scan, + const uint8_t* src_scan) const { + if (m_bpc == 0) { + return; + } + int max_data = (1 << m_bpc) - 1; + if (m_bDefaultDecode) { + if (m_Family == PDFCS_DEVICERGB || m_Family == PDFCS_CALRGB) { + const uint8_t* src_pos = src_scan; + switch (m_bpc) { + case 16: + for (int col = 0; col < m_Width; col++) { + *dest_scan++ = src_pos[4]; + *dest_scan++ = src_pos[2]; + *dest_scan++ = *src_pos; + src_pos += 6; + } + break; + case 8: + for (int column = 0; column < m_Width; column++) { + *dest_scan++ = src_pos[2]; + *dest_scan++ = src_pos[1]; + *dest_scan++ = *src_pos; + src_pos += 3; + } + break; + default: + int src_bit_pos = 0; + int dest_byte_pos = 0; + for (int column = 0; column < m_Width; column++) { + int R = _GetBits8(src_scan, src_bit_pos, m_bpc); + src_bit_pos += m_bpc; + int G = _GetBits8(src_scan, src_bit_pos, m_bpc); + src_bit_pos += m_bpc; + int B = _GetBits8(src_scan, src_bit_pos, m_bpc); + src_bit_pos += m_bpc; + R = NORMALCOLOR_MAX(R, max_data); + G = NORMALCOLOR_MAX(G, max_data); + B = NORMALCOLOR_MAX(B, max_data); + dest_scan[dest_byte_pos] = B * 255 / max_data; + dest_scan[dest_byte_pos + 1] = G * 255 / max_data; + dest_scan[dest_byte_pos + 2] = R * 255 / max_data; dest_byte_pos += 3; - } + } + break; + } + return; } + if (m_bpc == 8) { + if (m_nComponents == m_pColorSpace->CountComponents()) + m_pColorSpace->TranslateImageLine( + dest_scan, src_scan, m_Width, m_Width, m_Height, + m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && + m_Family == PDFCS_DEVICECMYK); + return; + } + } + CFX_FixedBufGrow<FX_FLOAT, 16> color_values1(m_nComponents); + FX_FLOAT* color_values = color_values1; + FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; + if (m_bpc == 8) { + int src_byte_pos = 0; + int dest_byte_pos = 0; + for (int column = 0; column < m_Width; column++) { + for (FX_DWORD color = 0; color < m_nComponents; color++) { + int data = src_scan[src_byte_pos++]; + color_values[color] = m_pCompData[color].m_DecodeMin + + m_pCompData[color].m_DecodeStep * data; + } + if (m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && + m_Family == PDFCS_DEVICECMYK) { + FX_FLOAT k = 1.0f - color_values[3]; + R = (1.0f - color_values[0]) * k; + G = (1.0f - color_values[1]) * k; + B = (1.0f - color_values[2]) * k; + } else { + m_pColorSpace->GetRGB(color_values, R, G, B); + } + R = NORMALCOLOR_MAX(R, 1); + G = NORMALCOLOR_MAX(G, 1); + B = NORMALCOLOR_MAX(B, 1); + dest_scan[dest_byte_pos] = (int32_t)(B * 255); + dest_scan[dest_byte_pos + 1] = (int32_t)(G * 255); + dest_scan[dest_byte_pos + 2] = (int32_t)(R * 255); + dest_byte_pos += 3; + } + } else { + int src_bit_pos = 0; + int dest_byte_pos = 0; + for (int column = 0; column < m_Width; column++) { + for (FX_DWORD color = 0; color < m_nComponents; color++) { + int data = _GetBits8(src_scan, src_bit_pos, m_bpc); + color_values[color] = m_pCompData[color].m_DecodeMin + + m_pCompData[color].m_DecodeStep * data; + src_bit_pos += m_bpc; + } + if (m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && + m_Family == PDFCS_DEVICECMYK) { + FX_FLOAT k = 1.0f - color_values[3]; + R = (1.0f - color_values[0]) * k; + G = (1.0f - color_values[1]) * k; + B = (1.0f - color_values[2]) * k; + } else { + m_pColorSpace->GetRGB(color_values, R, G, B); + } + R = NORMALCOLOR_MAX(R, 1); + G = NORMALCOLOR_MAX(G, 1); + B = NORMALCOLOR_MAX(B, 1); + dest_scan[dest_byte_pos] = (int32_t)(B * 255); + dest_scan[dest_byte_pos + 1] = (int32_t)(G * 255); + dest_scan[dest_byte_pos + 2] = (int32_t)(R * 255); + dest_byte_pos += 3; + } + } } -uint8_t* CPDF_DIBSource::GetBuffer() const -{ - if (m_pCachedBitmap) { - return m_pCachedBitmap->GetBuffer(); - } - return NULL; +uint8_t* CPDF_DIBSource::GetBuffer() const { + if (m_pCachedBitmap) { + return m_pCachedBitmap->GetBuffer(); + } + return NULL; } -const uint8_t* CPDF_DIBSource::GetScanline(int line) const -{ - if (m_bpc == 0) { - return NULL; - } - FX_SAFE_DWORD src_pitch = CalculatePitch8(m_bpc, m_nComponents, m_Width, 1); - if (!src_pitch.IsValid()) - return NULL; - FX_DWORD src_pitch_value = src_pitch.ValueOrDie(); - const uint8_t* pSrcLine = NULL; - if (m_pCachedBitmap) { - if (line >= m_pCachedBitmap->GetHeight()) { - line = m_pCachedBitmap->GetHeight() - 1; - } - pSrcLine = m_pCachedBitmap->GetScanline(line); - } else if (m_pDecoder) { - pSrcLine = m_pDecoder->GetScanline(line); - } else { - if (m_pStreamAcc->GetSize() >= (line + 1) * src_pitch_value) { - pSrcLine = m_pStreamAcc->GetData() + line * src_pitch_value; - } - } - if (pSrcLine == NULL) { - uint8_t* pLineBuf = m_pMaskedLine ? m_pMaskedLine : m_pLineBuf; - FXSYS_memset(pLineBuf, 0xff, m_Pitch); - return pLineBuf; - } - if (m_bpc * m_nComponents == 1) { - if (m_bImageMask && m_bDefaultDecode) { - for (FX_DWORD i = 0; i < src_pitch_value; i++) { - m_pLineBuf[i] = ~pSrcLine[i]; - } - } else if (m_bColorKey) { - FX_DWORD reset_argb, set_argb; - reset_argb = m_pPalette ? m_pPalette[0] : 0xff000000; - set_argb = m_pPalette ? m_pPalette[1] : 0xffffffff; - if (m_pCompData[0].m_ColorKeyMin == 0) { - reset_argb = 0; - } - if (m_pCompData[0].m_ColorKeyMax == 1) { - set_argb = 0; - } - set_argb = FXARGB_TODIB(set_argb); - reset_argb = FXARGB_TODIB(reset_argb); - FX_DWORD* dest_scan = (FX_DWORD*)m_pMaskedLine; - for (int col = 0; col < m_Width; col ++) { - if (pSrcLine[col / 8] & (1 << (7 - col % 8))) { - *dest_scan = set_argb; - } else { - *dest_scan = reset_argb; - } - dest_scan ++; - } - return m_pMaskedLine; +const uint8_t* CPDF_DIBSource::GetScanline(int line) const { + if (m_bpc == 0) { + return NULL; + } + FX_SAFE_DWORD src_pitch = CalculatePitch8(m_bpc, m_nComponents, m_Width, 1); + if (!src_pitch.IsValid()) + return NULL; + FX_DWORD src_pitch_value = src_pitch.ValueOrDie(); + const uint8_t* pSrcLine = NULL; + if (m_pCachedBitmap) { + if (line >= m_pCachedBitmap->GetHeight()) { + line = m_pCachedBitmap->GetHeight() - 1; + } + pSrcLine = m_pCachedBitmap->GetScanline(line); + } else if (m_pDecoder) { + pSrcLine = m_pDecoder->GetScanline(line); + } else { + if (m_pStreamAcc->GetSize() >= (line + 1) * src_pitch_value) { + pSrcLine = m_pStreamAcc->GetData() + line * src_pitch_value; + } + } + if (pSrcLine == NULL) { + uint8_t* pLineBuf = m_pMaskedLine ? m_pMaskedLine : m_pLineBuf; + FXSYS_memset(pLineBuf, 0xff, m_Pitch); + return pLineBuf; + } + if (m_bpc * m_nComponents == 1) { + if (m_bImageMask && m_bDefaultDecode) { + for (FX_DWORD i = 0; i < src_pitch_value; i++) { + m_pLineBuf[i] = ~pSrcLine[i]; + } + } else if (m_bColorKey) { + FX_DWORD reset_argb, set_argb; + reset_argb = m_pPalette ? m_pPalette[0] : 0xff000000; + set_argb = m_pPalette ? m_pPalette[1] : 0xffffffff; + if (m_pCompData[0].m_ColorKeyMin == 0) { + reset_argb = 0; + } + if (m_pCompData[0].m_ColorKeyMax == 1) { + set_argb = 0; + } + set_argb = FXARGB_TODIB(set_argb); + reset_argb = FXARGB_TODIB(reset_argb); + FX_DWORD* dest_scan = (FX_DWORD*)m_pMaskedLine; + for (int col = 0; col < m_Width; col++) { + if (pSrcLine[col / 8] & (1 << (7 - col % 8))) { + *dest_scan = set_argb; } else { - FXSYS_memcpy(m_pLineBuf, pSrcLine, src_pitch_value); + *dest_scan = reset_argb; } - return m_pLineBuf; + dest_scan++; + } + return m_pMaskedLine; + } else { + FXSYS_memcpy(m_pLineBuf, pSrcLine, src_pitch_value); } - if (m_bpc * m_nComponents <= 8) { - if (m_bpc == 8) { - FXSYS_memcpy(m_pLineBuf, pSrcLine, src_pitch_value); - } else { - int src_bit_pos = 0; - for (int col = 0; col < m_Width; col ++) { - int color_index = 0; - for (FX_DWORD color = 0; color < m_nComponents; color ++) { - int data = _GetBits8(pSrcLine, src_bit_pos, m_bpc); - color_index |= data << (color * m_bpc); - src_bit_pos += m_bpc; - } - m_pLineBuf[col] = color_index; - } - } - if (m_bColorKey) { - uint8_t* pDestPixel = m_pMaskedLine; - const uint8_t* pSrcPixel = m_pLineBuf; - for (int col = 0; col < m_Width; col ++) { - uint8_t index = *pSrcPixel++; - if (m_pPalette) { - *pDestPixel++ = FXARGB_B(m_pPalette[index]); - *pDestPixel++ = FXARGB_G(m_pPalette[index]); - *pDestPixel++ = FXARGB_R(m_pPalette[index]); - } else { - *pDestPixel++ = index; - *pDestPixel++ = index; - *pDestPixel++ = index; - } - *pDestPixel = (index < m_pCompData[0].m_ColorKeyMin || index > m_pCompData[0].m_ColorKeyMax) ? 0xff : 0; - pDestPixel ++ ; - } - return m_pMaskedLine; + return m_pLineBuf; + } + if (m_bpc * m_nComponents <= 8) { + if (m_bpc == 8) { + FXSYS_memcpy(m_pLineBuf, pSrcLine, src_pitch_value); + } else { + int src_bit_pos = 0; + for (int col = 0; col < m_Width; col++) { + int color_index = 0; + for (FX_DWORD color = 0; color < m_nComponents; color++) { + int data = _GetBits8(pSrcLine, src_bit_pos, m_bpc); + color_index |= data << (color * m_bpc); + src_bit_pos += m_bpc; } - return m_pLineBuf; + m_pLineBuf[col] = color_index; + } } if (m_bColorKey) { - if (m_nComponents == 3 && m_bpc == 8) { - uint8_t* alpha_channel = m_pMaskedLine + 3; - for (int col = 0; col < m_Width; col ++) { - const uint8_t* pPixel = pSrcLine + col * 3; - alpha_channel[col * 4] = (pPixel[0] < m_pCompData[0].m_ColorKeyMin || pPixel[0] > m_pCompData[0].m_ColorKeyMax || - pPixel[1] < m_pCompData[1].m_ColorKeyMin || pPixel[1] > m_pCompData[1].m_ColorKeyMax || - pPixel[2] < m_pCompData[2].m_ColorKeyMin || pPixel[2] > m_pCompData[2].m_ColorKeyMax) ? 0xff : 0; - } + uint8_t* pDestPixel = m_pMaskedLine; + const uint8_t* pSrcPixel = m_pLineBuf; + for (int col = 0; col < m_Width; col++) { + uint8_t index = *pSrcPixel++; + if (m_pPalette) { + *pDestPixel++ = FXARGB_B(m_pPalette[index]); + *pDestPixel++ = FXARGB_G(m_pPalette[index]); + *pDestPixel++ = FXARGB_R(m_pPalette[index]); } else { - FXSYS_memset(m_pMaskedLine, 0xff, m_Pitch); - } - } - if (m_pColorSpace) { - TranslateScanline24bpp(m_pLineBuf, pSrcLine); - pSrcLine = m_pLineBuf; - } - if (m_bColorKey) { - const uint8_t* pSrcPixel = pSrcLine; - uint8_t* pDestPixel = m_pMaskedLine; - for (int col = 0; col < m_Width; col ++) { - *pDestPixel++ = *pSrcPixel++; - *pDestPixel++ = *pSrcPixel++; - *pDestPixel++ = *pSrcPixel++; - pDestPixel ++; + *pDestPixel++ = index; + *pDestPixel++ = index; + *pDestPixel++ = index; } - return m_pMaskedLine; - } - return pSrcLine; + *pDestPixel = (index < m_pCompData[0].m_ColorKeyMin || + index > m_pCompData[0].m_ColorKeyMax) + ? 0xff + : 0; + pDestPixel++; + } + return m_pMaskedLine; + } + return m_pLineBuf; + } + if (m_bColorKey) { + if (m_nComponents == 3 && m_bpc == 8) { + uint8_t* alpha_channel = m_pMaskedLine + 3; + for (int col = 0; col < m_Width; col++) { + const uint8_t* pPixel = pSrcLine + col * 3; + alpha_channel[col * 4] = (pPixel[0] < m_pCompData[0].m_ColorKeyMin || + pPixel[0] > m_pCompData[0].m_ColorKeyMax || + pPixel[1] < m_pCompData[1].m_ColorKeyMin || + pPixel[1] > m_pCompData[1].m_ColorKeyMax || + pPixel[2] < m_pCompData[2].m_ColorKeyMin || + pPixel[2] > m_pCompData[2].m_ColorKeyMax) + ? 0xff + : 0; + } + } else { + FXSYS_memset(m_pMaskedLine, 0xff, m_Pitch); + } + } + if (m_pColorSpace) { + TranslateScanline24bpp(m_pLineBuf, pSrcLine); + pSrcLine = m_pLineBuf; + } + if (m_bColorKey) { + const uint8_t* pSrcPixel = pSrcLine; + uint8_t* pDestPixel = m_pMaskedLine; + for (int col = 0; col < m_Width; col++) { + *pDestPixel++ = *pSrcPixel++; + *pDestPixel++ = *pSrcPixel++; + *pDestPixel++ = *pSrcPixel++; + pDestPixel++; + } + return m_pMaskedLine; + } + return pSrcLine; } -FX_BOOL CPDF_DIBSource::SkipToScanline(int line, IFX_Pause* pPause) const -{ - if (m_pDecoder) { - return m_pDecoder->SkipToScanline(line, pPause); - } - return FALSE; +FX_BOOL CPDF_DIBSource::SkipToScanline(int line, IFX_Pause* pPause) const { + if (m_pDecoder) { + return m_pDecoder->SkipToScanline(line, pPause); + } + return FALSE; } -void CPDF_DIBSource::DownSampleScanline(int line, uint8_t* dest_scan, int dest_bpp, - int dest_width, FX_BOOL bFlipX, int clip_left, int clip_width) const -{ - if (line < 0 || dest_scan == NULL || dest_bpp <= 0 || - dest_width <= 0 || clip_left < 0 || clip_width <= 0) { - return; - } +void CPDF_DIBSource::DownSampleScanline(int line, + uint8_t* dest_scan, + int dest_bpp, + int dest_width, + FX_BOOL bFlipX, + int clip_left, + int clip_width) const { + if (line < 0 || dest_scan == NULL || dest_bpp <= 0 || dest_width <= 0 || + clip_left < 0 || clip_width <= 0) { + return; + } - FX_DWORD src_width = m_Width; - FX_SAFE_DWORD pitch = CalculatePitch8(m_bpc, m_nComponents, m_Width, 1); + FX_DWORD src_width = m_Width; + FX_SAFE_DWORD pitch = CalculatePitch8(m_bpc, m_nComponents, m_Width, 1); + if (!pitch.IsValid()) { + return; + } + + const uint8_t* pSrcLine = NULL; + if (m_pCachedBitmap) { + pSrcLine = m_pCachedBitmap->GetScanline(line); + } else if (m_pDecoder) { + pSrcLine = m_pDecoder->GetScanline(line); + } else { + FX_DWORD src_pitch = pitch.ValueOrDie(); + pitch *= (line + 1); if (!pitch.IsValid()) { - return; + return; } - const uint8_t* pSrcLine = NULL; - if (m_pCachedBitmap) { - pSrcLine = m_pCachedBitmap->GetScanline(line); - } else if (m_pDecoder) { - pSrcLine = m_pDecoder->GetScanline(line); - } else { - FX_DWORD src_pitch = pitch.ValueOrDie(); - pitch *= (line+1); - if (!pitch.IsValid()) { - return; - } + if (m_pStreamAcc->GetSize() >= pitch.ValueOrDie()) { + pSrcLine = m_pStreamAcc->GetData() + line * src_pitch; + } + } + int orig_Bpp = m_bpc * m_nComponents / 8; + int dest_Bpp = dest_bpp / 8; + if (pSrcLine == NULL) { + FXSYS_memset(dest_scan, 0xff, dest_Bpp * clip_width); + return; + } - if (m_pStreamAcc->GetSize() >= pitch.ValueOrDie()) { - pSrcLine = m_pStreamAcc->GetData() + line * src_pitch; - } - } - int orig_Bpp = m_bpc * m_nComponents / 8; - int dest_Bpp = dest_bpp / 8; - if (pSrcLine == NULL) { - FXSYS_memset(dest_scan, 0xff, dest_Bpp * clip_width); - return; - } + FX_SAFE_INT32 max_src_x = clip_left; + max_src_x += clip_width - 1; + max_src_x *= src_width; + max_src_x /= dest_width; + if (!max_src_x.IsValid()) { + return; + } - FX_SAFE_INT32 max_src_x = clip_left; - max_src_x += clip_width - 1; - max_src_x *= src_width; - max_src_x /= dest_width; - if (!max_src_x.IsValid()) { - return; - } - - CFX_FixedBufGrow<uint8_t, 128> temp(orig_Bpp); - if (m_bpc * m_nComponents == 1) { - FX_DWORD set_argb = (FX_DWORD) - 1, reset_argb = 0; - if (m_bImageMask) { - if (m_bDefaultDecode) { - set_argb = 0; - reset_argb = (FX_DWORD) - 1; - } - } else if (m_bColorKey) { - reset_argb = m_pPalette ? m_pPalette[0] : 0xff000000; - set_argb = m_pPalette ? m_pPalette[1] : 0xffffffff; - if (m_pCompData[0].m_ColorKeyMin == 0) { - reset_argb = 0; - } - if (m_pCompData[0].m_ColorKeyMax == 1) { - set_argb = 0; - } - set_argb = FXARGB_TODIB(set_argb); - reset_argb = FXARGB_TODIB(reset_argb); - for (int i = 0; i < clip_width; i ++) { - FX_DWORD src_x = (clip_left + i) * src_width / dest_width; - if (bFlipX) { - src_x = src_width - src_x - 1; - } - src_x %= src_width; - if (pSrcLine[src_x / 8] & (1 << (7 - src_x % 8))) { - ((FX_DWORD*)dest_scan)[i] = set_argb; - } else { - ((FX_DWORD*)dest_scan)[i] = reset_argb; - } - } - return; + CFX_FixedBufGrow<uint8_t, 128> temp(orig_Bpp); + if (m_bpc * m_nComponents == 1) { + FX_DWORD set_argb = (FX_DWORD)-1, reset_argb = 0; + if (m_bImageMask) { + if (m_bDefaultDecode) { + set_argb = 0; + reset_argb = (FX_DWORD)-1; + } + } else if (m_bColorKey) { + reset_argb = m_pPalette ? m_pPalette[0] : 0xff000000; + set_argb = m_pPalette ? m_pPalette[1] : 0xffffffff; + if (m_pCompData[0].m_ColorKeyMin == 0) { + reset_argb = 0; + } + if (m_pCompData[0].m_ColorKeyMax == 1) { + set_argb = 0; + } + set_argb = FXARGB_TODIB(set_argb); + reset_argb = FXARGB_TODIB(reset_argb); + for (int i = 0; i < clip_width; i++) { + FX_DWORD src_x = (clip_left + i) * src_width / dest_width; + if (bFlipX) { + src_x = src_width - src_x - 1; + } + src_x %= src_width; + if (pSrcLine[src_x / 8] & (1 << (7 - src_x % 8))) { + ((FX_DWORD*)dest_scan)[i] = set_argb; } else { - if (dest_Bpp == 1) { - } else if (m_pPalette) { - reset_argb = m_pPalette[0]; - set_argb = m_pPalette[1]; - } + ((FX_DWORD*)dest_scan)[i] = reset_argb; } - for (int i = 0; i < clip_width; i ++) { - FX_DWORD src_x = (clip_left + i) * src_width / dest_width; - if (bFlipX) { - src_x = src_width - src_x - 1; - } - src_x %= src_width; - int dest_pos = i * dest_Bpp; - if (pSrcLine[src_x / 8] & (1 << (7 - src_x % 8))) { - if (dest_Bpp == 1) { - dest_scan[dest_pos] = (uint8_t)set_argb; - } else if (dest_Bpp == 3) { - dest_scan[dest_pos] = FXARGB_B(set_argb); - dest_scan[dest_pos + 1] = FXARGB_G(set_argb); - dest_scan[dest_pos + 2] = FXARGB_R(set_argb); - } else { - *(FX_DWORD*)(dest_scan + dest_pos) = set_argb; - } - } else { - if (dest_Bpp == 1) { - dest_scan[dest_pos] = (uint8_t)reset_argb; - } else if (dest_Bpp == 3) { - dest_scan[dest_pos] = FXARGB_B(reset_argb); - dest_scan[dest_pos + 1] = FXARGB_G(reset_argb); - dest_scan[dest_pos + 2] = FXARGB_R(reset_argb); - } else { - *(FX_DWORD*)(dest_scan + dest_pos) = reset_argb; - } - } + } + return; + } else { + if (dest_Bpp == 1) { + } else if (m_pPalette) { + reset_argb = m_pPalette[0]; + set_argb = m_pPalette[1]; + } + } + for (int i = 0; i < clip_width; i++) { + FX_DWORD src_x = (clip_left + i) * src_width / dest_width; + if (bFlipX) { + src_x = src_width - src_x - 1; + } + src_x %= src_width; + int dest_pos = i * dest_Bpp; + if (pSrcLine[src_x / 8] & (1 << (7 - src_x % 8))) { + if (dest_Bpp == 1) { + dest_scan[dest_pos] = (uint8_t)set_argb; + } else if (dest_Bpp == 3) { + dest_scan[dest_pos] = FXARGB_B(set_argb); + dest_scan[dest_pos + 1] = FXARGB_G(set_argb); + dest_scan[dest_pos + 2] = FXARGB_R(set_argb); + } else { + *(FX_DWORD*)(dest_scan + dest_pos) = set_argb; } - return; - } else if (m_bpc * m_nComponents <= 8) { - if (m_bpc < 8) { - int src_bit_pos = 0; - for (FX_DWORD col = 0; col < src_width; col ++) { - int color_index = 0; - for (FX_DWORD color = 0; color < m_nComponents; color ++) { - int data = _GetBits8(pSrcLine, src_bit_pos, m_bpc); - color_index |= data << (color * m_bpc); - src_bit_pos += m_bpc; - } - m_pLineBuf[col] = color_index; - } - pSrcLine = m_pLineBuf; + } else { + if (dest_Bpp == 1) { + dest_scan[dest_pos] = (uint8_t)reset_argb; + } else if (dest_Bpp == 3) { + dest_scan[dest_pos] = FXARGB_B(reset_argb); + dest_scan[dest_pos + 1] = FXARGB_G(reset_argb); + dest_scan[dest_pos + 2] = FXARGB_R(reset_argb); + } else { + *(FX_DWORD*)(dest_scan + dest_pos) = reset_argb; } - if (m_bColorKey) { - for (int i = 0; i < clip_width; i ++) { - FX_DWORD src_x = (clip_left + i) * src_width / dest_width; - if (bFlipX) { - src_x = src_width - src_x - 1; - } - src_x %= src_width; - uint8_t* pDestPixel = dest_scan + i * 4; - uint8_t index = pSrcLine[src_x]; - if (m_pPalette) { - *pDestPixel++ = FXARGB_B(m_pPalette[index]); - *pDestPixel++ = FXARGB_G(m_pPalette[index]); - *pDestPixel++ = FXARGB_R(m_pPalette[index]); - } else { - *pDestPixel++ = index; - *pDestPixel++ = index; - *pDestPixel++ = index; - } - *pDestPixel = (index < m_pCompData[0].m_ColorKeyMin || index > m_pCompData[0].m_ColorKeyMax) ? 0xff : 0; - } - return; + } + } + return; + } else if (m_bpc * m_nComponents <= 8) { + if (m_bpc < 8) { + int src_bit_pos = 0; + for (FX_DWORD col = 0; col < src_width; col++) { + int color_index = 0; + for (FX_DWORD color = 0; color < m_nComponents; color++) { + int data = _GetBits8(pSrcLine, src_bit_pos, m_bpc); + color_index |= data << (color * m_bpc); + src_bit_pos += m_bpc; } - for (int i = 0; i < clip_width; i ++) { - FX_DWORD src_x = (clip_left + i) * src_width / dest_width; - if (bFlipX) { - src_x = src_width - src_x - 1; - } - src_x %= src_width; - uint8_t index = pSrcLine[src_x]; - if (dest_Bpp == 1) { - dest_scan[i] = index; - } else { - int dest_pos = i * dest_Bpp; - FX_ARGB argb = m_pPalette[index]; - dest_scan[dest_pos] = FXARGB_B(argb); - dest_scan[dest_pos + 1] = FXARGB_G(argb); - dest_scan[dest_pos + 2] = FXARGB_R(argb); - } + m_pLineBuf[col] = color_index; + } + pSrcLine = m_pLineBuf; + } + if (m_bColorKey) { + for (int i = 0; i < clip_width; i++) { + FX_DWORD src_x = (clip_left + i) * src_width / dest_width; + if (bFlipX) { + src_x = src_width - src_x - 1; } - return; - } else { - int last_src_x = -1; - FX_ARGB last_argb; - FX_FLOAT orig_Not8Bpp = (FX_FLOAT)m_bpc * (FX_FLOAT)m_nComponents / 8.0f; - FX_FLOAT unit_To8Bpc = 255.0f / ((1 << m_bpc) - 1); - for (int i = 0; i < clip_width; i ++) { - int dest_x = clip_left + i; - FX_DWORD src_x = (bFlipX ? (dest_width - dest_x - 1) : dest_x) * (int64_t)src_width / dest_width; - src_x %= src_width; - const uint8_t* pSrcPixel = NULL; - if (m_bpc % 8 == 0) { - pSrcPixel = pSrcLine + src_x * orig_Bpp; - } else { - pSrcPixel = pSrcLine + (int)(src_x * orig_Not8Bpp); - } - uint8_t* pDestPixel = dest_scan + i * dest_Bpp; - FX_ARGB argb; - if (src_x == last_src_x) { - argb = last_argb; - } else { - if (m_pColorSpace) { - uint8_t color[4]; - if (!m_bDefaultDecode) { - for (int i = 0; i < m_nComponents; i ++) { - int color_value = (int)((m_pCompData[i].m_DecodeMin + m_pCompData[i].m_DecodeStep * (FX_FLOAT)pSrcPixel[i]) * 255.0f + 0.5f); - temp[i] = color_value > 255 ? 255 : (color_value < 0 ? 0 : color_value); - } - m_pColorSpace->TranslateImageLine(color, temp, 1, 0, 0, m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && m_Family == PDFCS_DEVICECMYK); - } else { - if (m_bpc < 8) { - int src_bit_pos = 0; - if (src_x % 2) { - src_bit_pos = 4; - } - for (FX_DWORD i = 0; i < m_nComponents; i ++) { - temp[i] = (uint8_t)(_GetBits8(pSrcPixel, src_bit_pos, m_bpc) * unit_To8Bpc); - src_bit_pos += m_bpc; - } - m_pColorSpace->TranslateImageLine(color, temp, 1, 0, 0, m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && m_Family == PDFCS_DEVICECMYK); - } else { - m_pColorSpace->TranslateImageLine(color, pSrcPixel, 1, 0, 0, m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && m_Family == PDFCS_DEVICECMYK); - } - } - argb = FXARGB_MAKE(0xff, color[2], color[1], color[0]); - } else { - argb = FXARGB_MAKE(0xff, pSrcPixel[2], pSrcPixel[1], pSrcPixel[0]); - } - if (m_bColorKey) { - int alpha = 0xff; - if (m_nComponents == 3 && m_bpc == 8) { - alpha = (pSrcPixel[0] < m_pCompData[0].m_ColorKeyMin || - pSrcPixel[0] > m_pCompData[0].m_ColorKeyMax || - pSrcPixel[1] < m_pCompData[1].m_ColorKeyMin || - pSrcPixel[1] > m_pCompData[1].m_ColorKeyMax || - pSrcPixel[2] < m_pCompData[2].m_ColorKeyMin || - pSrcPixel[2] > m_pCompData[2].m_ColorKeyMax) ? 0xff : 0; - } - argb &= 0xffffff; - argb |= alpha << 24; - } - last_src_x = src_x; - last_argb = argb; + src_x %= src_width; + uint8_t* pDestPixel = dest_scan + i * 4; + uint8_t index = pSrcLine[src_x]; + if (m_pPalette) { + *pDestPixel++ = FXARGB_B(m_pPalette[index]); + *pDestPixel++ = FXARGB_G(m_pPalette[index]); + *pDestPixel++ = FXARGB_R(m_pPalette[index]); + } else { + *pDestPixel++ = index; + *pDestPixel++ = index; + *pDestPixel++ = index; + } + *pDestPixel = (index < m_pCompData[0].m_ColorKeyMin || + index > m_pCompData[0].m_ColorKeyMax) + ? 0xff + : 0; + } + return; + } + for (int i = 0; i < clip_width; i++) { + FX_DWORD src_x = (clip_left + i) * src_width / dest_width; + if (bFlipX) { + src_x = src_width - src_x - 1; + } + src_x %= src_width; + uint8_t index = pSrcLine[src_x]; + if (dest_Bpp == 1) { + dest_scan[i] = index; + } else { + int dest_pos = i * dest_Bpp; + FX_ARGB argb = m_pPalette[index]; + dest_scan[dest_pos] = FXARGB_B(argb); + dest_scan[dest_pos + 1] = FXARGB_G(argb); + dest_scan[dest_pos + 2] = FXARGB_R(argb); + } + } + return; + } else { + int last_src_x = -1; + FX_ARGB last_argb; + FX_FLOAT orig_Not8Bpp = (FX_FLOAT)m_bpc * (FX_FLOAT)m_nComponents / 8.0f; + FX_FLOAT unit_To8Bpc = 255.0f / ((1 << m_bpc) - 1); + for (int i = 0; i < clip_width; i++) { + int dest_x = clip_left + i; + FX_DWORD src_x = (bFlipX ? (dest_width - dest_x - 1) : dest_x) * + (int64_t)src_width / dest_width; + src_x %= src_width; + const uint8_t* pSrcPixel = NULL; + if (m_bpc % 8 == 0) { + pSrcPixel = pSrcLine + src_x * orig_Bpp; + } else { + pSrcPixel = pSrcLine + (int)(src_x * orig_Not8Bpp); + } + uint8_t* pDestPixel = dest_scan + i * dest_Bpp; + FX_ARGB argb; + if (src_x == last_src_x) { + argb = last_argb; + } else { + if (m_pColorSpace) { + uint8_t color[4]; + if (!m_bDefaultDecode) { + for (int i = 0; i < m_nComponents; i++) { + int color_value = + (int)((m_pCompData[i].m_DecodeMin + + m_pCompData[i].m_DecodeStep * (FX_FLOAT)pSrcPixel[i]) * + 255.0f + + 0.5f); + temp[i] = + color_value > 255 ? 255 : (color_value < 0 ? 0 : color_value); } - if (dest_Bpp == 4) { - *(FX_DWORD*)pDestPixel = FXARGB_TODIB(argb); + m_pColorSpace->TranslateImageLine( + color, temp, 1, 0, 0, m_bLoadMask && + m_GroupFamily == PDFCS_DEVICECMYK && + m_Family == PDFCS_DEVICECMYK); + } else { + if (m_bpc < 8) { + int src_bit_pos = 0; + if (src_x % 2) { + src_bit_pos = 4; + } + for (FX_DWORD i = 0; i < m_nComponents; i++) { + temp[i] = (uint8_t)(_GetBits8(pSrcPixel, src_bit_pos, m_bpc) * + unit_To8Bpc); + src_bit_pos += m_bpc; + } + m_pColorSpace->TranslateImageLine( + color, temp, 1, 0, 0, m_bLoadMask && + m_GroupFamily == PDFCS_DEVICECMYK && + m_Family == PDFCS_DEVICECMYK); } else { - *pDestPixel++ = FXARGB_B(argb); - *pDestPixel++ = FXARGB_G(argb); - *pDestPixel = FXARGB_R(argb); + m_pColorSpace->TranslateImageLine( + color, pSrcPixel, 1, 0, 0, + m_bLoadMask && m_GroupFamily == PDFCS_DEVICECMYK && + m_Family == PDFCS_DEVICECMYK); } + } + argb = FXARGB_MAKE(0xff, color[2], color[1], color[0]); + } else { + argb = FXARGB_MAKE(0xff, pSrcPixel[2], pSrcPixel[1], pSrcPixel[0]); } - } + if (m_bColorKey) { + int alpha = 0xff; + if (m_nComponents == 3 && m_bpc == 8) { + alpha = (pSrcPixel[0] < m_pCompData[0].m_ColorKeyMin || + pSrcPixel[0] > m_pCompData[0].m_ColorKeyMax || + pSrcPixel[1] < m_pCompData[1].m_ColorKeyMin || + pSrcPixel[1] > m_pCompData[1].m_ColorKeyMax || + pSrcPixel[2] < m_pCompData[2].m_ColorKeyMin || + pSrcPixel[2] > m_pCompData[2].m_ColorKeyMax) + ? 0xff + : 0; + } + argb &= 0xffffff; + argb |= alpha << 24; + } + last_src_x = src_x; + last_argb = argb; + } + if (dest_Bpp == 4) { + *(FX_DWORD*)pDestPixel = FXARGB_TODIB(argb); + } else { + *pDestPixel++ = FXARGB_B(argb); + *pDestPixel++ = FXARGB_G(argb); + *pDestPixel = FXARGB_R(argb); + } + } + } } -void CPDF_DIBSource::SetDownSampleSize(int dest_width, int dest_height) const -{ - if (m_pDecoder) { - m_pDecoder->DownScale(dest_width, dest_height); - ((CPDF_DIBSource*)this)->m_Width = m_pDecoder->GetWidth(); - ((CPDF_DIBSource*)this)->m_Height = m_pDecoder->GetHeight(); - } +void CPDF_DIBSource::SetDownSampleSize(int dest_width, int dest_height) const { + if (m_pDecoder) { + m_pDecoder->DownScale(dest_width, dest_height); + ((CPDF_DIBSource*)this)->m_Width = m_pDecoder->GetWidth(); + ((CPDF_DIBSource*)this)->m_Height = m_pDecoder->GetHeight(); + } } -void CPDF_DIBSource::ClearImageData() -{ - if (m_pDecoder) { - m_pDecoder->ClearImageData(); - } +void CPDF_DIBSource::ClearImageData() { + if (m_pDecoder) { + m_pDecoder->ClearImageData(); + } } -CPDF_ProgressiveImageLoaderHandle::CPDF_ProgressiveImageLoaderHandle() -{ - m_pImageLoader = NULL; - m_pCache = NULL; - m_pImage = NULL; +CPDF_ProgressiveImageLoaderHandle::CPDF_ProgressiveImageLoaderHandle() { + m_pImageLoader = NULL; + m_pCache = NULL; + m_pImage = NULL; } -CPDF_ProgressiveImageLoaderHandle::~CPDF_ProgressiveImageLoaderHandle() -{ +CPDF_ProgressiveImageLoaderHandle::~CPDF_ProgressiveImageLoaderHandle() {} +FX_BOOL CPDF_ProgressiveImageLoaderHandle::Start( + CPDF_ImageLoader* pImageLoader, + const CPDF_ImageObject* pImage, + CPDF_PageRenderCache* pCache, + FX_BOOL bStdCS, + FX_DWORD GroupFamily, + FX_BOOL bLoadMask, + CPDF_RenderStatus* pRenderStatus, + int32_t nDownsampleWidth, + int32_t nDownsampleHeight) { + m_pImageLoader = pImageLoader; + m_pCache = pCache; + m_pImage = (CPDF_ImageObject*)pImage; + m_nDownsampleWidth = nDownsampleWidth; + m_nDownsampleHeight = nDownsampleHeight; + FX_BOOL ret; + if (pCache) { + ret = pCache->StartGetCachedBitmap(pImage->m_pImage->GetStream(), bStdCS, + GroupFamily, bLoadMask, pRenderStatus, + m_nDownsampleWidth, m_nDownsampleHeight); + if (ret == FALSE) { + m_pImageLoader->m_bCached = TRUE; + m_pImageLoader->m_pBitmap = pCache->m_pCurImageCache->DetachBitmap(); + m_pImageLoader->m_pMask = pCache->m_pCurImageCache->DetachMask(); + m_pImageLoader->m_MatteColor = pCache->m_pCurImageCache->m_MatteColor; + } + } else { + ret = pImage->m_pImage->StartLoadDIBSource(pRenderStatus->m_pFormResource, + pRenderStatus->m_pPageResource, + bStdCS, GroupFamily, bLoadMask); + if (ret == FALSE) { + m_pImageLoader->m_bCached = FALSE; + m_pImageLoader->m_pBitmap = m_pImage->m_pImage->DetachBitmap(); + m_pImageLoader->m_pMask = m_pImage->m_pImage->DetachMask(); + m_pImageLoader->m_MatteColor = m_pImage->m_pImage->m_MatteColor; + } + } + return ret; } -FX_BOOL CPDF_ProgressiveImageLoaderHandle::Start(CPDF_ImageLoader* pImageLoader, const CPDF_ImageObject* pImage, CPDF_PageRenderCache* pCache, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus, int32_t nDownsampleWidth, int32_t nDownsampleHeight) -{ - m_pImageLoader = pImageLoader; - m_pCache = pCache; - m_pImage = (CPDF_ImageObject*)pImage; - m_nDownsampleWidth = nDownsampleWidth; - m_nDownsampleHeight = nDownsampleHeight; - FX_BOOL ret; - if (pCache) { - ret = pCache->StartGetCachedBitmap(pImage->m_pImage->GetStream(), bStdCS, GroupFamily, bLoadMask, pRenderStatus, m_nDownsampleWidth, m_nDownsampleHeight); - if (ret == FALSE) { - m_pImageLoader->m_bCached = TRUE; - m_pImageLoader->m_pBitmap = pCache->m_pCurImageCache->DetachBitmap(); - m_pImageLoader->m_pMask = pCache->m_pCurImageCache->DetachMask(); - m_pImageLoader->m_MatteColor = pCache->m_pCurImageCache->m_MatteColor; - } - } else { - ret = pImage->m_pImage->StartLoadDIBSource(pRenderStatus->m_pFormResource, pRenderStatus->m_pPageResource, bStdCS, GroupFamily, bLoadMask); - if (ret == FALSE) { - m_pImageLoader->m_bCached = FALSE; - m_pImageLoader->m_pBitmap = m_pImage->m_pImage->DetachBitmap(); - m_pImageLoader->m_pMask = m_pImage->m_pImage->DetachMask(); - m_pImageLoader->m_MatteColor = m_pImage->m_pImage->m_MatteColor; - } - } - return ret; +FX_BOOL CPDF_ProgressiveImageLoaderHandle::Continue(IFX_Pause* pPause) { + FX_BOOL ret; + if (m_pCache) { + ret = m_pCache->Continue(pPause); + if (ret == FALSE) { + m_pImageLoader->m_bCached = TRUE; + m_pImageLoader->m_pBitmap = m_pCache->m_pCurImageCache->DetachBitmap(); + m_pImageLoader->m_pMask = m_pCache->m_pCurImageCache->DetachMask(); + m_pImageLoader->m_MatteColor = m_pCache->m_pCurImageCache->m_MatteColor; + } + } else { + ret = m_pImage->m_pImage->Continue(pPause); + if (ret == FALSE) { + m_pImageLoader->m_bCached = FALSE; + m_pImageLoader->m_pBitmap = m_pImage->m_pImage->DetachBitmap(); + m_pImageLoader->m_pMask = m_pImage->m_pImage->DetachMask(); + m_pImageLoader->m_MatteColor = m_pImage->m_pImage->m_MatteColor; + } + } + return ret; } -FX_BOOL CPDF_ProgressiveImageLoaderHandle::Continue(IFX_Pause* pPause) -{ - FX_BOOL ret; - if (m_pCache) { - ret = m_pCache->Continue(pPause); - if (ret == FALSE) { - m_pImageLoader->m_bCached = TRUE; - m_pImageLoader->m_pBitmap = m_pCache->m_pCurImageCache->DetachBitmap(); - m_pImageLoader->m_pMask = m_pCache->m_pCurImageCache->DetachMask(); - m_pImageLoader->m_MatteColor = m_pCache->m_pCurImageCache->m_MatteColor; - } - } else { - ret = m_pImage->m_pImage->Continue(pPause); - if (ret == FALSE) { - m_pImageLoader->m_bCached = FALSE; - m_pImageLoader->m_pBitmap = m_pImage->m_pImage->DetachBitmap(); - m_pImageLoader->m_pMask = m_pImage->m_pImage->DetachMask(); - m_pImageLoader->m_MatteColor = m_pImage->m_pImage->m_MatteColor; - } - } - return ret; -} -FX_BOOL CPDF_ImageLoader::Load(const CPDF_ImageObject* pImage, CPDF_PageRenderCache* pCache, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus) -{ - if (pImage == NULL) { - return FALSE; - } - if (pCache) { - pCache->GetCachedBitmap(pImage->m_pImage->GetStream(), m_pBitmap, m_pMask, m_MatteColor, bStdCS, GroupFamily, bLoadMask, pRenderStatus, m_nDownsampleWidth, m_nDownsampleHeight); - m_bCached = TRUE; - } else { - m_pBitmap = pImage->m_pImage->LoadDIBSource(&m_pMask, &m_MatteColor, bStdCS, GroupFamily, bLoadMask); - m_bCached = FALSE; - } +FX_BOOL CPDF_ImageLoader::Load(const CPDF_ImageObject* pImage, + CPDF_PageRenderCache* pCache, + FX_BOOL bStdCS, + FX_DWORD GroupFamily, + FX_BOOL bLoadMask, + CPDF_RenderStatus* pRenderStatus) { + if (pImage == NULL) { return FALSE; + } + if (pCache) { + pCache->GetCachedBitmap(pImage->m_pImage->GetStream(), m_pBitmap, m_pMask, + m_MatteColor, bStdCS, GroupFamily, bLoadMask, + pRenderStatus, m_nDownsampleWidth, + m_nDownsampleHeight); + m_bCached = TRUE; + } else { + m_pBitmap = pImage->m_pImage->LoadDIBSource(&m_pMask, &m_MatteColor, bStdCS, + GroupFamily, bLoadMask); + m_bCached = FALSE; + } + return FALSE; } -FX_BOOL CPDF_ImageLoader::StartLoadImage(const CPDF_ImageObject* pImage, CPDF_PageRenderCache* pCache, void*& LoadHandle, FX_BOOL bStdCS, FX_DWORD GroupFamily, FX_BOOL bLoadMask, CPDF_RenderStatus* pRenderStatus, int32_t nDownsampleWidth, int32_t nDownsampleHeight) -{ - m_nDownsampleWidth = nDownsampleWidth; - m_nDownsampleHeight = nDownsampleHeight; - CPDF_ProgressiveImageLoaderHandle* pLoaderHandle = new CPDF_ProgressiveImageLoaderHandle; - FX_BOOL ret = pLoaderHandle->Start(this, pImage, pCache, bStdCS, GroupFamily, bLoadMask, pRenderStatus, m_nDownsampleWidth, m_nDownsampleHeight); - LoadHandle = pLoaderHandle; - return ret; +FX_BOOL CPDF_ImageLoader::StartLoadImage(const CPDF_ImageObject* pImage, + CPDF_PageRenderCache* pCache, + void*& LoadHandle, + FX_BOOL bStdCS, + FX_DWORD GroupFamily, + FX_BOOL bLoadMask, + CPDF_RenderStatus* pRenderStatus, + int32_t nDownsampleWidth, + int32_t nDownsampleHeight) { + m_nDownsampleWidth = nDownsampleWidth; + m_nDownsampleHeight = nDownsampleHeight; + CPDF_ProgressiveImageLoaderHandle* pLoaderHandle = + new CPDF_ProgressiveImageLoaderHandle; + FX_BOOL ret = pLoaderHandle->Start(this, pImage, pCache, bStdCS, GroupFamily, + bLoadMask, pRenderStatus, + m_nDownsampleWidth, m_nDownsampleHeight); + LoadHandle = pLoaderHandle; + return ret; } -FX_BOOL CPDF_ImageLoader::Continue(void* LoadHandle, IFX_Pause* pPause) -{ - return ((CPDF_ProgressiveImageLoaderHandle*)LoadHandle)->Continue(pPause); +FX_BOOL CPDF_ImageLoader::Continue(void* LoadHandle, IFX_Pause* pPause) { + return ((CPDF_ProgressiveImageLoaderHandle*)LoadHandle)->Continue(pPause); } -CPDF_ImageLoader::~CPDF_ImageLoader() -{ - if (!m_bCached) { - delete m_pBitmap; - delete m_pMask; - } +CPDF_ImageLoader::~CPDF_ImageLoader() { + if (!m_bCached) { + delete m_pBitmap; + delete m_pMask; + } } diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_pattern.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_pattern.cpp index 3ee2222d8b..b64002c13e 100644 --- a/core/src/fpdfapi/fpdf_render/fpdf_render_pattern.cpp +++ b/core/src/fpdfapi/fpdf_render/fpdf_render_pattern.cpp @@ -10,1101 +10,1212 @@ #include "../fpdf_page/pageint.h" #include "render_int.h" #define SHADING_STEPS 256 -static void _DrawAxialShading(CFX_DIBitmap* pBitmap, CFX_AffineMatrix* pObject2Bitmap, - CPDF_Dictionary* pDict, CPDF_Function** pFuncs, int nFuncs, - CPDF_ColorSpace* pCS, int alpha) -{ - ASSERT(pBitmap->GetFormat() == FXDIB_Argb); - CPDF_Array* pCoords = pDict->GetArray(FX_BSTRC("Coords")); - if (pCoords == NULL) { - return; - } - FX_FLOAT start_x = pCoords->GetNumber(0); - FX_FLOAT start_y = pCoords->GetNumber(1); - FX_FLOAT end_x = pCoords->GetNumber(2); - FX_FLOAT end_y = pCoords->GetNumber(3); - FX_FLOAT t_min = 0, t_max = 1.0f; - CPDF_Array* pArray = pDict->GetArray(FX_BSTRC("Domain")); - if (pArray) { - t_min = pArray->GetNumber(0); - t_max = pArray->GetNumber(1); - } - FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE; - pArray = pDict->GetArray(FX_BSTRC("Extend")); - if (pArray) { - bStartExtend = pArray->GetInteger(0); - bEndExtend = pArray->GetInteger(1); - } - int width = pBitmap->GetWidth(); - int height = pBitmap->GetHeight(); - FX_FLOAT x_span = end_x - start_x; - FX_FLOAT y_span = end_y - start_y; - FX_FLOAT axis_len_square = FXSYS_Mul(x_span, x_span) + FXSYS_Mul(y_span, y_span); - CFX_AffineMatrix matrix; - matrix.SetReverse(*pObject2Bitmap); - int total_results = 0; - for (int j = 0; j < nFuncs; j ++) { - if (pFuncs[j]) { - total_results += pFuncs[j]->CountOutputs(); +static void _DrawAxialShading(CFX_DIBitmap* pBitmap, + CFX_AffineMatrix* pObject2Bitmap, + CPDF_Dictionary* pDict, + CPDF_Function** pFuncs, + int nFuncs, + CPDF_ColorSpace* pCS, + int alpha) { + ASSERT(pBitmap->GetFormat() == FXDIB_Argb); + CPDF_Array* pCoords = pDict->GetArray(FX_BSTRC("Coords")); + if (pCoords == NULL) { + return; + } + FX_FLOAT start_x = pCoords->GetNumber(0); + FX_FLOAT start_y = pCoords->GetNumber(1); + FX_FLOAT end_x = pCoords->GetNumber(2); + FX_FLOAT end_y = pCoords->GetNumber(3); + FX_FLOAT t_min = 0, t_max = 1.0f; + CPDF_Array* pArray = pDict->GetArray(FX_BSTRC("Domain")); + if (pArray) { + t_min = pArray->GetNumber(0); + t_max = pArray->GetNumber(1); + } + FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE; + pArray = pDict->GetArray(FX_BSTRC("Extend")); + if (pArray) { + bStartExtend = pArray->GetInteger(0); + bEndExtend = pArray->GetInteger(1); + } + int width = pBitmap->GetWidth(); + int height = pBitmap->GetHeight(); + FX_FLOAT x_span = end_x - start_x; + FX_FLOAT y_span = end_y - start_y; + FX_FLOAT axis_len_square = + FXSYS_Mul(x_span, x_span) + FXSYS_Mul(y_span, y_span); + CFX_AffineMatrix matrix; + matrix.SetReverse(*pObject2Bitmap); + int total_results = 0; + for (int j = 0; j < nFuncs; j++) { + if (pFuncs[j]) { + total_results += pFuncs[j]->CountOutputs(); + } + } + if (pCS->CountComponents() > total_results) { + total_results = pCS->CountComponents(); + } + CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results); + FX_FLOAT* pResults = result_array; + FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT)); + FX_DWORD rgb_array[SHADING_STEPS]; + for (int i = 0; i < SHADING_STEPS; i++) { + FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min; + int offset = 0; + for (int j = 0; j < nFuncs; j++) { + if (pFuncs[j]) { + int nresults = 0; + if (pFuncs[j]->Call(&input, 1, pResults + offset, nresults)) { + offset += nresults; } - } - if (pCS->CountComponents() > total_results) { - total_results = pCS->CountComponents(); - } - CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results); - FX_FLOAT* pResults = result_array; - FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT)); - FX_DWORD rgb_array[SHADING_STEPS]; - for (int i = 0; i < SHADING_STEPS; i ++) { - FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min; - int offset = 0; - for (int j = 0; j < nFuncs; j ++) { - if (pFuncs[j]) { - int nresults = 0; - if (pFuncs[j]->Call(&input, 1, pResults + offset, nresults)) { - offset += nresults; - } - } + } + } + FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; + pCS->GetRGB(pResults, R, G, B); + rgb_array[i] = + FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255), + FXSYS_round(G * 255), FXSYS_round(B * 255))); + } + int pitch = pBitmap->GetPitch(); + for (int row = 0; row < height; row++) { + FX_DWORD* dib_buf = (FX_DWORD*)(pBitmap->GetBuffer() + row * pitch); + for (int column = 0; column < width; column++) { + FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row; + matrix.Transform(x, y); + FX_FLOAT scale = FXSYS_Div( + FXSYS_Mul(x - start_x, x_span) + FXSYS_Mul(y - start_y, y_span), + axis_len_square); + int index = (int32_t)(scale * (SHADING_STEPS - 1)); + if (index < 0) { + if (!bStartExtend) { + continue; } - FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; - pCS->GetRGB(pResults, R, G, B); - rgb_array[i] = FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255), FXSYS_round(G * 255), FXSYS_round(B * 255))); - } - int pitch = pBitmap->GetPitch(); - for (int row = 0; row < height; row ++) { - FX_DWORD* dib_buf = (FX_DWORD*)(pBitmap->GetBuffer() + row * pitch); - for (int column = 0; column < width; column ++) { - FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row; - matrix.Transform(x, y); - FX_FLOAT scale = FXSYS_Div(FXSYS_Mul(x - start_x, x_span) + FXSYS_Mul(y - start_y, y_span), axis_len_square); - int index = (int32_t)(scale * (SHADING_STEPS - 1)); - if (index < 0) { - if (!bStartExtend) { - continue; - } - index = 0; - } else if (index >= SHADING_STEPS) { - if (!bEndExtend) { - continue; - } - index = SHADING_STEPS - 1; - } - dib_buf[column] = rgb_array[index]; + index = 0; + } else if (index >= SHADING_STEPS) { + if (!bEndExtend) { + continue; } + index = SHADING_STEPS - 1; + } + dib_buf[column] = rgb_array[index]; } + } } -static void _DrawRadialShading(CFX_DIBitmap* pBitmap, CFX_AffineMatrix* pObject2Bitmap, - CPDF_Dictionary* pDict, CPDF_Function** pFuncs, int nFuncs, - CPDF_ColorSpace* pCS, int alpha) -{ - ASSERT(pBitmap->GetFormat() == FXDIB_Argb); - CPDF_Array* pCoords = pDict->GetArray(FX_BSTRC("Coords")); - if (pCoords == NULL) { - return; - } - FX_FLOAT start_x = pCoords->GetNumber(0); - FX_FLOAT start_y = pCoords->GetNumber(1); - FX_FLOAT start_r = pCoords->GetNumber(2); - FX_FLOAT end_x = pCoords->GetNumber(3); - FX_FLOAT end_y = pCoords->GetNumber(4); - FX_FLOAT end_r = pCoords->GetNumber(5); - CFX_AffineMatrix matrix; - matrix.SetReverse(*pObject2Bitmap); - FX_FLOAT t_min = 0, t_max = 1.0f; - CPDF_Array* pArray = pDict->GetArray(FX_BSTRC("Domain")); - if (pArray) { - t_min = pArray->GetNumber(0); - t_max = pArray->GetNumber(1); - } - FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE; - pArray = pDict->GetArray(FX_BSTRC("Extend")); - if (pArray) { - bStartExtend = pArray->GetInteger(0); - bEndExtend = pArray->GetInteger(1); - } - int total_results = 0; - for (int j = 0; j < nFuncs; j ++) { - if (pFuncs[j]) { - total_results += pFuncs[j]->CountOutputs(); +static void _DrawRadialShading(CFX_DIBitmap* pBitmap, + CFX_AffineMatrix* pObject2Bitmap, + CPDF_Dictionary* pDict, + CPDF_Function** pFuncs, + int nFuncs, + CPDF_ColorSpace* pCS, + int alpha) { + ASSERT(pBitmap->GetFormat() == FXDIB_Argb); + CPDF_Array* pCoords = pDict->GetArray(FX_BSTRC("Coords")); + if (pCoords == NULL) { + return; + } + FX_FLOAT start_x = pCoords->GetNumber(0); + FX_FLOAT start_y = pCoords->GetNumber(1); + FX_FLOAT start_r = pCoords->GetNumber(2); + FX_FLOAT end_x = pCoords->GetNumber(3); + FX_FLOAT end_y = pCoords->GetNumber(4); + FX_FLOAT end_r = pCoords->GetNumber(5); + CFX_AffineMatrix matrix; + matrix.SetReverse(*pObject2Bitmap); + FX_FLOAT t_min = 0, t_max = 1.0f; + CPDF_Array* pArray = pDict->GetArray(FX_BSTRC("Domain")); + if (pArray) { + t_min = pArray->GetNumber(0); + t_max = pArray->GetNumber(1); + } + FX_BOOL bStartExtend = FALSE, bEndExtend = FALSE; + pArray = pDict->GetArray(FX_BSTRC("Extend")); + if (pArray) { + bStartExtend = pArray->GetInteger(0); + bEndExtend = pArray->GetInteger(1); + } + int total_results = 0; + for (int j = 0; j < nFuncs; j++) { + if (pFuncs[j]) { + total_results += pFuncs[j]->CountOutputs(); + } + } + if (pCS->CountComponents() > total_results) { + total_results = pCS->CountComponents(); + } + CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results); + FX_FLOAT* pResults = result_array; + FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT)); + FX_DWORD rgb_array[SHADING_STEPS]; + for (int i = 0; i < SHADING_STEPS; i++) { + FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min; + int offset = 0; + for (int j = 0; j < nFuncs; j++) { + if (pFuncs[j]) { + int nresults; + if (pFuncs[j]->Call(&input, 1, pResults + offset, nresults)) { + offset += nresults; } - } - if (pCS->CountComponents() > total_results) { - total_results = pCS->CountComponents(); - } - CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results); - FX_FLOAT* pResults = result_array; - FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT)); - FX_DWORD rgb_array[SHADING_STEPS]; - for (int i = 0; i < SHADING_STEPS; i ++) { - FX_FLOAT input = (t_max - t_min) * i / SHADING_STEPS + t_min; - int offset = 0; - for (int j = 0; j < nFuncs; j ++) { - if (pFuncs[j]) { - int nresults; - if (pFuncs[j]->Call(&input, 1, pResults + offset, nresults)) { - offset += nresults; - } - } - } - FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; - pCS->GetRGB(pResults, R, G, B); - rgb_array[i] = FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255), FXSYS_round(G * 255), FXSYS_round(B * 255))); - } - FX_FLOAT a = FXSYS_Mul(start_x - end_x, start_x - end_x) + - FXSYS_Mul(start_y - end_y, start_y - end_y) - FXSYS_Mul(start_r - end_r, start_r - end_r); - int width = pBitmap->GetWidth(); - int height = pBitmap->GetHeight(); - int pitch = pBitmap->GetPitch(); - FX_BOOL bDecreasing = FALSE; - if (start_r > end_r) { - int length = (int)FXSYS_sqrt((FXSYS_Mul(start_x - end_x, start_x - end_x) + FXSYS_Mul(start_y - end_y, start_y - end_y))); - if (length < start_r - end_r) { - bDecreasing = TRUE; + } + } + FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; + pCS->GetRGB(pResults, R, G, B); + rgb_array[i] = + FXARGB_TODIB(FXARGB_MAKE(alpha, FXSYS_round(R * 255), + FXSYS_round(G * 255), FXSYS_round(B * 255))); + } + FX_FLOAT a = FXSYS_Mul(start_x - end_x, start_x - end_x) + + FXSYS_Mul(start_y - end_y, start_y - end_y) - + FXSYS_Mul(start_r - end_r, start_r - end_r); + int width = pBitmap->GetWidth(); + int height = pBitmap->GetHeight(); + int pitch = pBitmap->GetPitch(); + FX_BOOL bDecreasing = FALSE; + if (start_r > end_r) { + int length = (int)FXSYS_sqrt((FXSYS_Mul(start_x - end_x, start_x - end_x) + + FXSYS_Mul(start_y - end_y, start_y - end_y))); + if (length < start_r - end_r) { + bDecreasing = TRUE; + } + } + for (int row = 0; row < height; row++) { + FX_DWORD* dib_buf = (FX_DWORD*)(pBitmap->GetBuffer() + row * pitch); + for (int column = 0; column < width; column++) { + FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row; + matrix.Transform(x, y); + FX_FLOAT b = -2 * (FXSYS_Mul(x - start_x, end_x - start_x) + + FXSYS_Mul(y - start_y, end_y - start_y) + + FXSYS_Mul(start_r, end_r - start_r)); + FX_FLOAT c = FXSYS_Mul(x - start_x, x - start_x) + + FXSYS_Mul(y - start_y, y - start_y) - + FXSYS_Mul(start_r, start_r); + FX_FLOAT s; + if (a == 0) { + s = FXSYS_Div(-c, b); + } else { + FX_FLOAT b2_4ac = FXSYS_Mul(b, b) - 4 * FXSYS_Mul(a, c); + if (b2_4ac < 0) { + continue; } - } - for (int row = 0; row < height; row ++) { - FX_DWORD* dib_buf = (FX_DWORD*)(pBitmap->GetBuffer() + row * pitch); - for (int column = 0; column < width; column ++) { - FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row; - matrix.Transform(x, y); - FX_FLOAT b = -2 * (FXSYS_Mul(x - start_x, end_x - start_x) + FXSYS_Mul(y - start_y, end_y - start_y) + - FXSYS_Mul(start_r, end_r - start_r)); - FX_FLOAT c = FXSYS_Mul(x - start_x, x - start_x) + FXSYS_Mul(y - start_y, y - start_y) - - FXSYS_Mul(start_r, start_r); - FX_FLOAT s; - if (a == 0) { - s = FXSYS_Div(-c, b); - } else { - FX_FLOAT b2_4ac = FXSYS_Mul(b, b) - 4 * FXSYS_Mul(a, c); - if (b2_4ac < 0) { - continue; - } - FX_FLOAT root = FXSYS_sqrt(b2_4ac); - FX_FLOAT s1, s2; - if (a > 0) { - s1 = FXSYS_Div(-b - root, 2 * a); - s2 = FXSYS_Div(-b + root, 2 * a); - } else { - s2 = FXSYS_Div(-b - root, 2 * a); - s1 = FXSYS_Div(-b + root, 2 * a); - } - if (bDecreasing) { - if (s1 >= 0 || bStartExtend) { - s = s1; - } else { - s = s2; - } - } else { - if (s2 <= 1.0f || bEndExtend) { - s = s2; - } else { - s = s1; - } - } - if ((start_r + s * (end_r - start_r)) < 0) { - continue; - } - } - int index = (int32_t)(s * (SHADING_STEPS - 1)); - if (index < 0) { - if (!bStartExtend) { - continue; - } - index = 0; - } - if (index >= SHADING_STEPS) { - if (!bEndExtend) { - continue; - } - index = SHADING_STEPS - 1; - } - dib_buf[column] = rgb_array[index]; + FX_FLOAT root = FXSYS_sqrt(b2_4ac); + FX_FLOAT s1, s2; + if (a > 0) { + s1 = FXSYS_Div(-b - root, 2 * a); + s2 = FXSYS_Div(-b + root, 2 * a); + } else { + s2 = FXSYS_Div(-b - root, 2 * a); + s1 = FXSYS_Div(-b + root, 2 * a); } - } -} -static void _DrawFuncShading(CFX_DIBitmap* pBitmap, CFX_AffineMatrix* pObject2Bitmap, - CPDF_Dictionary* pDict, CPDF_Function** pFuncs, int nFuncs, - CPDF_ColorSpace* pCS, int alpha) -{ - ASSERT(pBitmap->GetFormat() == FXDIB_Argb); - CPDF_Array* pDomain = pDict->GetArray(FX_BSTRC("Domain")); - FX_FLOAT xmin = 0, ymin = 0, xmax = 1.0f, ymax = 1.0f; - if (pDomain) { - xmin = pDomain->GetNumber(0); - xmax = pDomain->GetNumber(1); - ymin = pDomain->GetNumber(2); - ymax = pDomain->GetNumber(3); - } - CFX_AffineMatrix mtDomain2Target = pDict->GetMatrix(FX_BSTRC("Matrix")); - CFX_AffineMatrix matrix, reverse_matrix; - matrix.SetReverse(*pObject2Bitmap); - reverse_matrix.SetReverse(mtDomain2Target); - matrix.Concat(reverse_matrix); - int width = pBitmap->GetWidth(); - int height = pBitmap->GetHeight(); - int pitch = pBitmap->GetPitch(); - int total_results = 0; - for (int j = 0; j < nFuncs; j ++) { - if (pFuncs[j]) { - total_results += pFuncs[j]->CountOutputs(); + if (bDecreasing) { + if (s1 >= 0 || bStartExtend) { + s = s1; + } else { + s = s2; + } + } else { + if (s2 <= 1.0f || bEndExtend) { + s = s2; + } else { + s = s1; + } } - } - if (pCS->CountComponents() > total_results) { - total_results = pCS->CountComponents(); - } - CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results); - FX_FLOAT* pResults = result_array; - FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT)); - for (int row = 0; row < height; row ++) { - FX_DWORD* dib_buf = (FX_DWORD*)(pBitmap->GetBuffer() + row * pitch); - for (int column = 0; column < width; column ++) { - FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row; - matrix.Transform(x, y); - if (x < xmin || x > xmax || y < ymin || y > ymax) { - continue; - } - FX_FLOAT input[2]; - int offset = 0; - input[0] = x; - input[1] = y; - for (int j = 0; j < nFuncs; j ++) { - if (pFuncs[j]) { - int nresults; - if (pFuncs[j]->Call(input, 2, pResults + offset, nresults)) { - offset += nresults; - } - } - } - FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; - pCS->GetRGB(pResults, R, G, B); - dib_buf[column] = FXARGB_TODIB(FXARGB_MAKE(alpha, (int32_t)(R * 255), (int32_t)(G * 255), (int32_t)(B * 255))); + if ((start_r + s * (end_r - start_r)) < 0) { + continue; } - } -} -FX_BOOL _GetScanlineIntersect(int y, FX_FLOAT x1, FX_FLOAT y1, FX_FLOAT x2, FX_FLOAT y2, FX_FLOAT& x) -{ - if (y1 == y2) { - return FALSE; - } - if (y1 < y2) { - if (y < y1 || y > y2) { - return FALSE; + } + int index = (int32_t)(s * (SHADING_STEPS - 1)); + if (index < 0) { + if (!bStartExtend) { + continue; } - } else { - if (y < y2 || y > y1) { - return FALSE; + index = 0; + } + if (index >= SHADING_STEPS) { + if (!bEndExtend) { + continue; } + index = SHADING_STEPS - 1; + } + dib_buf[column] = rgb_array[index]; } - x = x1 + FXSYS_MulDiv(x2 - x1, y - y1, y2 - y1); - return TRUE; + } } -static void _DrawGouraud(CFX_DIBitmap* pBitmap, int alpha, CPDF_MeshVertex triangle[3]) -{ - FX_FLOAT min_y = triangle[0].y, max_y = triangle[0].y; - for (int i = 1; i < 3; i ++) { - if (min_y > triangle[i].y) { - min_y = triangle[i].y; - } - if (max_y < triangle[i].y) { - max_y = triangle[i].y; - } - } - if (min_y == max_y) { - return; - } - int min_yi = (int)FXSYS_floor(min_y), max_yi = (int)FXSYS_ceil(max_y); - if (min_yi < 0) { - min_yi = 0; - } - if (max_yi >= pBitmap->GetHeight()) { - max_yi = pBitmap->GetHeight() - 1; - } - for (int y = min_yi; y <= max_yi; y ++) { - int nIntersects = 0; - FX_FLOAT inter_x[3], r[3], g[3], b[3]; - for (int i = 0; i < 3; i ++) { - CPDF_MeshVertex& vertex1 = triangle[i]; - CPDF_MeshVertex& vertex2 = triangle[(i + 1) % 3]; - FX_BOOL bIntersect = _GetScanlineIntersect(y, vertex1.x, vertex1.y, - vertex2.x, vertex2.y, inter_x[nIntersects]); - if (!bIntersect) { - continue; - } - r[nIntersects] = vertex1.r + FXSYS_MulDiv(vertex2.r - vertex1.r, y - vertex1.y, vertex2.y - vertex1.y); - g[nIntersects] = vertex1.g + FXSYS_MulDiv(vertex2.g - vertex1.g, y - vertex1.y, vertex2.y - vertex1.y); - b[nIntersects] = vertex1.b + FXSYS_MulDiv(vertex2.b - vertex1.b, y - vertex1.y, vertex2.y - vertex1.y); - nIntersects ++; - } - if (nIntersects != 2) { - continue; - } - int min_x, max_x, start_index, end_index; - if (inter_x[0] < inter_x[1]) { - min_x = (int)FXSYS_floor(inter_x[0]); - max_x = (int)FXSYS_ceil(inter_x[1]); - start_index = 0; - end_index = 1; - } else { - min_x = (int)FXSYS_floor(inter_x[1]); - max_x = (int)FXSYS_ceil(inter_x[0]); - start_index = 1; - end_index = 0; - } - int start_x = min_x, end_x = max_x; - if (start_x < 0) { - start_x = 0; - } - if (end_x > pBitmap->GetWidth()) { - end_x = pBitmap->GetWidth(); - } - uint8_t* dib_buf = pBitmap->GetBuffer() + y * pBitmap->GetPitch() + start_x * 4; - FX_FLOAT r_unit = (r[end_index] - r[start_index]) / (max_x - min_x); - FX_FLOAT g_unit = (g[end_index] - g[start_index]) / (max_x - min_x); - FX_FLOAT b_unit = (b[end_index] - b[start_index]) / (max_x - min_x); - FX_FLOAT R = r[start_index] + (start_x - min_x) * r_unit; - FX_FLOAT G = g[start_index] + (start_x - min_x) * g_unit; - FX_FLOAT B = b[start_index] + (start_x - min_x) * b_unit; - for (int x = start_x; x < end_x; x ++) { - R += r_unit; - G += g_unit; - B += b_unit; - FXARGB_SETDIB(dib_buf, FXARGB_MAKE(alpha, (int32_t)(R * 255), (int32_t)(G * 255), (int32_t)(B * 255))); - dib_buf += 4; +static void _DrawFuncShading(CFX_DIBitmap* pBitmap, + CFX_AffineMatrix* pObject2Bitmap, + CPDF_Dictionary* pDict, + CPDF_Function** pFuncs, + int nFuncs, + CPDF_ColorSpace* pCS, + int alpha) { + ASSERT(pBitmap->GetFormat() == FXDIB_Argb); + CPDF_Array* pDomain = pDict->GetArray(FX_BSTRC("Domain")); + FX_FLOAT xmin = 0, ymin = 0, xmax = 1.0f, ymax = 1.0f; + if (pDomain) { + xmin = pDomain->GetNumber(0); + xmax = pDomain->GetNumber(1); + ymin = pDomain->GetNumber(2); + ymax = pDomain->GetNumber(3); + } + CFX_AffineMatrix mtDomain2Target = pDict->GetMatrix(FX_BSTRC("Matrix")); + CFX_AffineMatrix matrix, reverse_matrix; + matrix.SetReverse(*pObject2Bitmap); + reverse_matrix.SetReverse(mtDomain2Target); + matrix.Concat(reverse_matrix); + int width = pBitmap->GetWidth(); + int height = pBitmap->GetHeight(); + int pitch = pBitmap->GetPitch(); + int total_results = 0; + for (int j = 0; j < nFuncs; j++) { + if (pFuncs[j]) { + total_results += pFuncs[j]->CountOutputs(); + } + } + if (pCS->CountComponents() > total_results) { + total_results = pCS->CountComponents(); + } + CFX_FixedBufGrow<FX_FLOAT, 16> result_array(total_results); + FX_FLOAT* pResults = result_array; + FXSYS_memset(pResults, 0, total_results * sizeof(FX_FLOAT)); + for (int row = 0; row < height; row++) { + FX_DWORD* dib_buf = (FX_DWORD*)(pBitmap->GetBuffer() + row * pitch); + for (int column = 0; column < width; column++) { + FX_FLOAT x = (FX_FLOAT)column, y = (FX_FLOAT)row; + matrix.Transform(x, y); + if (x < xmin || x > xmax || y < ymin || y > ymax) { + continue; + } + FX_FLOAT input[2]; + int offset = 0; + input[0] = x; + input[1] = y; + for (int j = 0; j < nFuncs; j++) { + if (pFuncs[j]) { + int nresults; + if (pFuncs[j]->Call(input, 2, pResults + offset, nresults)) { + offset += nresults; + } } + } + FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; + pCS->GetRGB(pResults, R, G, B); + dib_buf[column] = FXARGB_TODIB(FXARGB_MAKE( + alpha, (int32_t)(R * 255), (int32_t)(G * 255), (int32_t)(B * 255))); } + } } -static void _DrawFreeGouraudShading(CFX_DIBitmap* pBitmap, CFX_AffineMatrix* pObject2Bitmap, - CPDF_Stream* pShadingStream, CPDF_Function** pFuncs, int nFuncs, - CPDF_ColorSpace* pCS, int alpha) -{ - ASSERT(pBitmap->GetFormat() == FXDIB_Argb); - if (pShadingStream->GetType() != PDFOBJ_STREAM) { - return; - } - CPDF_MeshStream stream; - if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) { - return; - } - CPDF_MeshVertex triangle[3]; - FXSYS_memset(triangle, 0, sizeof(triangle)); +FX_BOOL _GetScanlineIntersect(int y, + FX_FLOAT x1, + FX_FLOAT y1, + FX_FLOAT x2, + FX_FLOAT y2, + FX_FLOAT& x) { + if (y1 == y2) { + return FALSE; + } + if (y1 < y2) { + if (y < y1 || y > y2) { + return FALSE; + } + } else { + if (y < y2 || y > y1) { + return FALSE; + } + } + x = x1 + FXSYS_MulDiv(x2 - x1, y - y1, y2 - y1); + return TRUE; +} +static void _DrawGouraud(CFX_DIBitmap* pBitmap, + int alpha, + CPDF_MeshVertex triangle[3]) { + FX_FLOAT min_y = triangle[0].y, max_y = triangle[0].y; + for (int i = 1; i < 3; i++) { + if (min_y > triangle[i].y) { + min_y = triangle[i].y; + } + if (max_y < triangle[i].y) { + max_y = triangle[i].y; + } + } + if (min_y == max_y) { + return; + } + int min_yi = (int)FXSYS_floor(min_y), max_yi = (int)FXSYS_ceil(max_y); + if (min_yi < 0) { + min_yi = 0; + } + if (max_yi >= pBitmap->GetHeight()) { + max_yi = pBitmap->GetHeight() - 1; + } + for (int y = min_yi; y <= max_yi; y++) { + int nIntersects = 0; + FX_FLOAT inter_x[3], r[3], g[3], b[3]; + for (int i = 0; i < 3; i++) { + CPDF_MeshVertex& vertex1 = triangle[i]; + CPDF_MeshVertex& vertex2 = triangle[(i + 1) % 3]; + FX_BOOL bIntersect = _GetScanlineIntersect( + y, vertex1.x, vertex1.y, vertex2.x, vertex2.y, inter_x[nIntersects]); + if (!bIntersect) { + continue; + } + r[nIntersects] = + vertex1.r + FXSYS_MulDiv(vertex2.r - vertex1.r, y - vertex1.y, + vertex2.y - vertex1.y); + g[nIntersects] = + vertex1.g + FXSYS_MulDiv(vertex2.g - vertex1.g, y - vertex1.y, + vertex2.y - vertex1.y); + b[nIntersects] = + vertex1.b + FXSYS_MulDiv(vertex2.b - vertex1.b, y - vertex1.y, + vertex2.y - vertex1.y); + nIntersects++; + } + if (nIntersects != 2) { + continue; + } + int min_x, max_x, start_index, end_index; + if (inter_x[0] < inter_x[1]) { + min_x = (int)FXSYS_floor(inter_x[0]); + max_x = (int)FXSYS_ceil(inter_x[1]); + start_index = 0; + end_index = 1; + } else { + min_x = (int)FXSYS_floor(inter_x[1]); + max_x = (int)FXSYS_ceil(inter_x[0]); + start_index = 1; + end_index = 0; + } + int start_x = min_x, end_x = max_x; + if (start_x < 0) { + start_x = 0; + } + if (end_x > pBitmap->GetWidth()) { + end_x = pBitmap->GetWidth(); + } + uint8_t* dib_buf = + pBitmap->GetBuffer() + y * pBitmap->GetPitch() + start_x * 4; + FX_FLOAT r_unit = (r[end_index] - r[start_index]) / (max_x - min_x); + FX_FLOAT g_unit = (g[end_index] - g[start_index]) / (max_x - min_x); + FX_FLOAT b_unit = (b[end_index] - b[start_index]) / (max_x - min_x); + FX_FLOAT R = r[start_index] + (start_x - min_x) * r_unit; + FX_FLOAT G = g[start_index] + (start_x - min_x) * g_unit; + FX_FLOAT B = b[start_index] + (start_x - min_x) * b_unit; + for (int x = start_x; x < end_x; x++) { + R += r_unit; + G += g_unit; + B += b_unit; + FXARGB_SETDIB(dib_buf, + FXARGB_MAKE(alpha, (int32_t)(R * 255), (int32_t)(G * 255), + (int32_t)(B * 255))); + dib_buf += 4; + } + } +} +static void _DrawFreeGouraudShading(CFX_DIBitmap* pBitmap, + CFX_AffineMatrix* pObject2Bitmap, + CPDF_Stream* pShadingStream, + CPDF_Function** pFuncs, + int nFuncs, + CPDF_ColorSpace* pCS, + int alpha) { + ASSERT(pBitmap->GetFormat() == FXDIB_Argb); + if (pShadingStream->GetType() != PDFOBJ_STREAM) { + return; + } + CPDF_MeshStream stream; + if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) { + return; + } + CPDF_MeshVertex triangle[3]; + FXSYS_memset(triangle, 0, sizeof(triangle)); - while (!stream.m_BitStream.IsEOF()) { - CPDF_MeshVertex vertex; - FX_DWORD flag = stream.GetVertex(vertex, pObject2Bitmap); - if (flag == 0) { - triangle[0] = vertex; - for (int j = 1; j < 3; j ++) { - stream.GetVertex(triangle[j], pObject2Bitmap); - } - } else { - if (flag == 1) { - triangle[0] = triangle[1]; - } - triangle[1] = triangle[2]; - triangle[2] = vertex; - } - _DrawGouraud(pBitmap, alpha, triangle); - } + while (!stream.m_BitStream.IsEOF()) { + CPDF_MeshVertex vertex; + FX_DWORD flag = stream.GetVertex(vertex, pObject2Bitmap); + if (flag == 0) { + triangle[0] = vertex; + for (int j = 1; j < 3; j++) { + stream.GetVertex(triangle[j], pObject2Bitmap); + } + } else { + if (flag == 1) { + triangle[0] = triangle[1]; + } + triangle[1] = triangle[2]; + triangle[2] = vertex; + } + _DrawGouraud(pBitmap, alpha, triangle); + } } -static void _DrawLatticeGouraudShading(CFX_DIBitmap* pBitmap, CFX_AffineMatrix* pObject2Bitmap, - CPDF_Stream* pShadingStream, CPDF_Function** pFuncs, int nFuncs, - CPDF_ColorSpace* pCS, int alpha) -{ - ASSERT(pBitmap->GetFormat() == FXDIB_Argb); - if (pShadingStream->GetType() != PDFOBJ_STREAM) { - return; - } - int row_verts = pShadingStream->GetDict()->GetInteger("VerticesPerRow"); - if (row_verts < 2) { - return; - } - CPDF_MeshStream stream; - if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) { - return; - } - CPDF_MeshVertex* vertex = FX_Alloc2D(CPDF_MeshVertex, row_verts, 2); - if (!stream.GetVertexRow(vertex, row_verts, pObject2Bitmap)) { - FX_Free(vertex); - return; - } - int last_index = 0; - while (1) { - CPDF_MeshVertex* last_row = vertex + last_index * row_verts; - CPDF_MeshVertex* this_row = vertex + (1 - last_index) * row_verts; - if (!stream.GetVertexRow(this_row, row_verts, pObject2Bitmap)) { - FX_Free(vertex); - return; - } - CPDF_MeshVertex triangle[3]; - for (int i = 1; i < row_verts; i ++) { - triangle[0] = last_row[i]; - triangle[1] = this_row[i - 1]; - triangle[2] = last_row[i - 1]; - _DrawGouraud(pBitmap, alpha, triangle); - triangle[2] = this_row[i]; - _DrawGouraud(pBitmap, alpha, triangle); - } - last_index = 1 - last_index; - } +static void _DrawLatticeGouraudShading(CFX_DIBitmap* pBitmap, + CFX_AffineMatrix* pObject2Bitmap, + CPDF_Stream* pShadingStream, + CPDF_Function** pFuncs, + int nFuncs, + CPDF_ColorSpace* pCS, + int alpha) { + ASSERT(pBitmap->GetFormat() == FXDIB_Argb); + if (pShadingStream->GetType() != PDFOBJ_STREAM) { + return; + } + int row_verts = pShadingStream->GetDict()->GetInteger("VerticesPerRow"); + if (row_verts < 2) { + return; + } + CPDF_MeshStream stream; + if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) { + return; + } + CPDF_MeshVertex* vertex = FX_Alloc2D(CPDF_MeshVertex, row_verts, 2); + if (!stream.GetVertexRow(vertex, row_verts, pObject2Bitmap)) { FX_Free(vertex); + return; + } + int last_index = 0; + while (1) { + CPDF_MeshVertex* last_row = vertex + last_index * row_verts; + CPDF_MeshVertex* this_row = vertex + (1 - last_index) * row_verts; + if (!stream.GetVertexRow(this_row, row_verts, pObject2Bitmap)) { + FX_Free(vertex); + return; + } + CPDF_MeshVertex triangle[3]; + for (int i = 1; i < row_verts; i++) { + triangle[0] = last_row[i]; + triangle[1] = this_row[i - 1]; + triangle[2] = last_row[i - 1]; + _DrawGouraud(pBitmap, alpha, triangle); + triangle[2] = this_row[i]; + _DrawGouraud(pBitmap, alpha, triangle); + } + last_index = 1 - last_index; + } + FX_Free(vertex); } struct Coon_BezierCoeff { - float a, b, c, d; - void FromPoints(float p0, float p1, float p2, float p3) - { - a = -p0 + 3 * p1 - 3 * p2 + p3; - b = 3 * p0 - 6 * p1 + 3 * p2; - c = -3 * p0 + 3 * p1; - d = p0; - } - Coon_BezierCoeff first_half() - { - Coon_BezierCoeff result; - result.a = a / 8; - result.b = b / 4; - result.c = c / 2; - result.d = d; - return result; - } - Coon_BezierCoeff second_half() - { - Coon_BezierCoeff result; - result.a = a / 8; - result.b = 3 * a / 8 + b / 4; - result.c = 3 * a / 8 + b / 2 + c / 2; - result.d = a / 8 + b / 4 + c / 2 + d; - return result; - } - void GetPoints(float p[4]) - { - p[0] = d; - p[1] = c / 3 + p[0]; - p[2] = b / 3 - p[0] + 2 * p[1]; - p[3] = a + p[0] - 3 * p[1] + 3 * p[2]; - } - void GetPointsReverse(float p[4]) - { - p[3] = d; - p[2] = c / 3 + p[3]; - p[1] = b / 3 - p[3] + 2 * p[2]; - p[0] = a + p[3] - 3 * p[2] + 3 * p[1]; - } - void BezierInterpol(Coon_BezierCoeff& C1, Coon_BezierCoeff& C2, Coon_BezierCoeff& D1, Coon_BezierCoeff& D2) - { - a = (D1.a + D2.a) / 2; - b = (D1.b + D2.b) / 2; - c = (D1.c + D2.c) / 2 - (C1.a / 8 + C1.b / 4 + C1.c / 2) + (C2.a / 8 + C2.b / 4) + (-C1.d + D2.d) / 2 - (C2.a + C2.b) / 2; - d = C1.a / 8 + C1.b / 4 + C1.c / 2 + C1.d; - } - float Distance() - { - float dis = a + b + c; - return dis < 0 ? -dis : dis; - } + float a, b, c, d; + void FromPoints(float p0, float p1, float p2, float p3) { + a = -p0 + 3 * p1 - 3 * p2 + p3; + b = 3 * p0 - 6 * p1 + 3 * p2; + c = -3 * p0 + 3 * p1; + d = p0; + } + Coon_BezierCoeff first_half() { + Coon_BezierCoeff result; + result.a = a / 8; + result.b = b / 4; + result.c = c / 2; + result.d = d; + return result; + } + Coon_BezierCoeff second_half() { + Coon_BezierCoeff result; + result.a = a / 8; + result.b = 3 * a / 8 + b / 4; + result.c = 3 * a / 8 + b / 2 + c / 2; + result.d = a / 8 + b / 4 + c / 2 + d; + return result; + } + void GetPoints(float p[4]) { + p[0] = d; + p[1] = c / 3 + p[0]; + p[2] = b / 3 - p[0] + 2 * p[1]; + p[3] = a + p[0] - 3 * p[1] + 3 * p[2]; + } + void GetPointsReverse(float p[4]) { + p[3] = d; + p[2] = c / 3 + p[3]; + p[1] = b / 3 - p[3] + 2 * p[2]; + p[0] = a + p[3] - 3 * p[2] + 3 * p[1]; + } + void BezierInterpol(Coon_BezierCoeff& C1, + Coon_BezierCoeff& C2, + Coon_BezierCoeff& D1, + Coon_BezierCoeff& D2) { + a = (D1.a + D2.a) / 2; + b = (D1.b + D2.b) / 2; + c = (D1.c + D2.c) / 2 - (C1.a / 8 + C1.b / 4 + C1.c / 2) + + (C2.a / 8 + C2.b / 4) + (-C1.d + D2.d) / 2 - (C2.a + C2.b) / 2; + d = C1.a / 8 + C1.b / 4 + C1.c / 2 + C1.d; + } + float Distance() { + float dis = a + b + c; + return dis < 0 ? -dis : dis; + } }; struct Coon_Bezier { - Coon_BezierCoeff x, y; - void FromPoints(float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3) - { - x.FromPoints(x0, x1, x2, x3); - y.FromPoints(y0, y1, y2, y3); - } - Coon_Bezier first_half() - { - Coon_Bezier result; - result.x = x.first_half(); - result.y = y.first_half(); - return result; - } - Coon_Bezier second_half() - { - Coon_Bezier result; - result.x = x.second_half(); - result.y = y.second_half(); - return result; - } - void BezierInterpol(Coon_Bezier& C1, Coon_Bezier& C2, Coon_Bezier& D1, Coon_Bezier& D2) - { - x.BezierInterpol(C1.x, C2.x, D1.x, D2.x); - y.BezierInterpol(C1.y, C2.y, D1.y, D2.y); - } - void GetPoints(FX_PATHPOINT* pPoints) - { - float p[4]; - int i; - x.GetPoints(p); - for (i = 0; i < 4; i ++) { - pPoints[i].m_PointX = p[i]; - } - y.GetPoints(p); - for (i = 0; i < 4; i ++) { - pPoints[i].m_PointY = p[i]; - } - } - void GetPointsReverse(FX_PATHPOINT* pPoints) - { - float p[4]; - int i; - x.GetPointsReverse(p); - for (i = 0; i < 4; i ++) { - pPoints[i].m_PointX = p[i]; - } - y.GetPointsReverse(p); - for (i = 0; i < 4; i ++) { - pPoints[i].m_PointY = p[i]; - } - } - float Distance() - { - return x.Distance() + y.Distance(); - } + Coon_BezierCoeff x, y; + void FromPoints(float x0, + float y0, + float x1, + float y1, + float x2, + float y2, + float x3, + float y3) { + x.FromPoints(x0, x1, x2, x3); + y.FromPoints(y0, y1, y2, y3); + } + Coon_Bezier first_half() { + Coon_Bezier result; + result.x = x.first_half(); + result.y = y.first_half(); + return result; + } + Coon_Bezier second_half() { + Coon_Bezier result; + result.x = x.second_half(); + result.y = y.second_half(); + return result; + } + void BezierInterpol(Coon_Bezier& C1, + Coon_Bezier& C2, + Coon_Bezier& D1, + Coon_Bezier& D2) { + x.BezierInterpol(C1.x, C2.x, D1.x, D2.x); + y.BezierInterpol(C1.y, C2.y, D1.y, D2.y); + } + void GetPoints(FX_PATHPOINT* pPoints) { + float p[4]; + int i; + x.GetPoints(p); + for (i = 0; i < 4; i++) { + pPoints[i].m_PointX = p[i]; + } + y.GetPoints(p); + for (i = 0; i < 4; i++) { + pPoints[i].m_PointY = p[i]; + } + } + void GetPointsReverse(FX_PATHPOINT* pPoints) { + float p[4]; + int i; + x.GetPointsReverse(p); + for (i = 0; i < 4; i++) { + pPoints[i].m_PointX = p[i]; + } + y.GetPointsReverse(p); + for (i = 0; i < 4; i++) { + pPoints[i].m_PointY = p[i]; + } + } + float Distance() { return x.Distance() + y.Distance(); } }; -static int _BiInterpol(int c0, int c1, int c2, int c3, int x, int y, int x_scale, int y_scale) -{ - int x1 = c0 + (c3 - c0) * x / x_scale; - int x2 = c1 + (c2 - c1) * x / x_scale; - return x1 + (x2 - x1) * y / y_scale; +static int _BiInterpol(int c0, + int c1, + int c2, + int c3, + int x, + int y, + int x_scale, + int y_scale) { + int x1 = c0 + (c3 - c0) * x / x_scale; + int x2 = c1 + (c2 - c1) * x / x_scale; + return x1 + (x2 - x1) * y / y_scale; } struct Coon_Color { - Coon_Color() - { - FXSYS_memset(comp, 0, sizeof(int) * 3); - } - int comp[3]; - void BiInterpol(Coon_Color colors[4], int x, int y, int x_scale, int y_scale) - { - for (int i = 0; i < 3; i ++) - comp[i] = _BiInterpol(colors[0].comp[i], colors[1].comp[i], colors[2].comp[i], colors[3].comp[i], - x, y, x_scale, y_scale); - } - int Distance(Coon_Color& o) - { - int max, diff; - max = FXSYS_abs(comp[0] - o.comp[0]); - diff = FXSYS_abs(comp[1] - o.comp[1]); - if (max < diff) { - max = diff; - } - diff = FXSYS_abs(comp[2] - o.comp[2]); - if (max < diff) { - max = diff; - } - return max; - } + Coon_Color() { FXSYS_memset(comp, 0, sizeof(int) * 3); } + int comp[3]; + void BiInterpol(Coon_Color colors[4], + int x, + int y, + int x_scale, + int y_scale) { + for (int i = 0; i < 3; i++) + comp[i] = + _BiInterpol(colors[0].comp[i], colors[1].comp[i], colors[2].comp[i], + colors[3].comp[i], x, y, x_scale, y_scale); + } + int Distance(Coon_Color& o) { + int max, diff; + max = FXSYS_abs(comp[0] - o.comp[0]); + diff = FXSYS_abs(comp[1] - o.comp[1]); + if (max < diff) { + max = diff; + } + diff = FXSYS_abs(comp[2] - o.comp[2]); + if (max < diff) { + max = diff; + } + return max; + } }; struct CPDF_PatchDrawer { - Coon_Color patch_colors[4]; - int max_delta; - CFX_PathData path; - CFX_RenderDevice* pDevice; - int fill_mode; - int alpha; - void Draw(int x_scale, int y_scale, int left, int bottom, Coon_Bezier C1, Coon_Bezier C2, Coon_Bezier D1, Coon_Bezier D2) - { - FX_BOOL bSmall = C1.Distance() < 2 && C2.Distance() < 2 && D1.Distance() < 2 && D2.Distance() < 2; - Coon_Color div_colors[4]; - int d_bottom, d_left, d_top, d_right; - div_colors[0].BiInterpol(patch_colors, left, bottom, x_scale, y_scale); - if (!bSmall) { - div_colors[1].BiInterpol(patch_colors, left, bottom + 1, x_scale, y_scale); - div_colors[2].BiInterpol(patch_colors, left + 1, bottom + 1, x_scale, y_scale); - div_colors[3].BiInterpol(patch_colors, left + 1, bottom, x_scale, y_scale); - d_bottom = div_colors[3].Distance(div_colors[0]); - d_left = div_colors[1].Distance(div_colors[0]); - d_top = div_colors[1].Distance(div_colors[2]); - d_right = div_colors[2].Distance(div_colors[3]); - } -#define COONCOLOR_THRESHOLD 4 - if (bSmall || (d_bottom < COONCOLOR_THRESHOLD && d_left < COONCOLOR_THRESHOLD && - d_top < COONCOLOR_THRESHOLD && d_right < COONCOLOR_THRESHOLD)) { - FX_PATHPOINT* pPoints = path.GetPoints(); - C1.GetPoints(pPoints); - D2.GetPoints(pPoints + 3); - C2.GetPointsReverse(pPoints + 6); - D1.GetPointsReverse(pPoints + 9); - int fillFlags = FXFILL_WINDING | FXFILL_FULLCOVER; - if (fill_mode & RENDER_NOPATHSMOOTH) { - fillFlags |= FXFILL_NOPATHSMOOTH; - } - pDevice->DrawPath(&path, NULL, NULL, FXARGB_MAKE(alpha, div_colors[0].comp[0], div_colors[0].comp[1], div_colors[0].comp[2]), 0, fillFlags); - } else { - if (d_bottom < COONCOLOR_THRESHOLD && d_top < COONCOLOR_THRESHOLD) { - Coon_Bezier m1; - m1.BezierInterpol(D1, D2, C1, C2); - y_scale *= 2; - bottom *= 2; - Draw(x_scale, y_scale, left, bottom, C1, m1, D1.first_half(), D2.first_half()); - Draw(x_scale, y_scale, left, bottom + 1, m1, C2, D1.second_half(), D2.second_half()); - } else if (d_left < COONCOLOR_THRESHOLD && d_right < COONCOLOR_THRESHOLD) { - Coon_Bezier m2; - m2.BezierInterpol(C1, C2, D1, D2); - x_scale *= 2; - left *= 2; - Draw(x_scale, y_scale, left, bottom, C1.first_half(), C2.first_half(), D1, m2); - Draw(x_scale, y_scale, left + 1, bottom, C1.second_half(), C2.second_half(), m2, D2); - } else { - Coon_Bezier m1, m2; - m1.BezierInterpol(D1, D2, C1, C2); - m2.BezierInterpol(C1, C2, D1, D2); - Coon_Bezier m1f = m1.first_half(); - Coon_Bezier m1s = m1.second_half(); - Coon_Bezier m2f = m2.first_half(); - Coon_Bezier m2s = m2.second_half(); - x_scale *= 2; - y_scale *= 2; - left *= 2; - bottom *= 2; - Draw(x_scale, y_scale, left, bottom, C1.first_half(), m1f, D1.first_half(), m2f); - Draw(x_scale, y_scale, left, bottom + 1, m1f, C2.first_half(), D1.second_half(), m2s); - Draw(x_scale, y_scale, left + 1, bottom, C1.second_half(), m1s, m2f, D2.first_half()); - Draw(x_scale, y_scale, left + 1, bottom + 1, m1s, C2.second_half(), m2s, D2.second_half()); - } - } + Coon_Color patch_colors[4]; + int max_delta; + CFX_PathData path; + CFX_RenderDevice* pDevice; + int fill_mode; + int alpha; + void Draw(int x_scale, + int y_scale, + int left, + int bottom, + Coon_Bezier C1, + Coon_Bezier C2, + Coon_Bezier D1, + Coon_Bezier D2) { + FX_BOOL bSmall = C1.Distance() < 2 && C2.Distance() < 2 && + D1.Distance() < 2 && D2.Distance() < 2; + Coon_Color div_colors[4]; + int d_bottom, d_left, d_top, d_right; + div_colors[0].BiInterpol(patch_colors, left, bottom, x_scale, y_scale); + if (!bSmall) { + div_colors[1].BiInterpol(patch_colors, left, bottom + 1, x_scale, + y_scale); + div_colors[2].BiInterpol(patch_colors, left + 1, bottom + 1, x_scale, + y_scale); + div_colors[3].BiInterpol(patch_colors, left + 1, bottom, x_scale, + y_scale); + d_bottom = div_colors[3].Distance(div_colors[0]); + d_left = div_colors[1].Distance(div_colors[0]); + d_top = div_colors[1].Distance(div_colors[2]); + d_right = div_colors[2].Distance(div_colors[3]); } +#define COONCOLOR_THRESHOLD 4 + if (bSmall || + (d_bottom < COONCOLOR_THRESHOLD && d_left < COONCOLOR_THRESHOLD && + d_top < COONCOLOR_THRESHOLD && d_right < COONCOLOR_THRESHOLD)) { + FX_PATHPOINT* pPoints = path.GetPoints(); + C1.GetPoints(pPoints); + D2.GetPoints(pPoints + 3); + C2.GetPointsReverse(pPoints + 6); + D1.GetPointsReverse(pPoints + 9); + int fillFlags = FXFILL_WINDING | FXFILL_FULLCOVER; + if (fill_mode & RENDER_NOPATHSMOOTH) { + fillFlags |= FXFILL_NOPATHSMOOTH; + } + pDevice->DrawPath( + &path, NULL, NULL, + FXARGB_MAKE(alpha, div_colors[0].comp[0], div_colors[0].comp[1], + div_colors[0].comp[2]), + 0, fillFlags); + } else { + if (d_bottom < COONCOLOR_THRESHOLD && d_top < COONCOLOR_THRESHOLD) { + Coon_Bezier m1; + m1.BezierInterpol(D1, D2, C1, C2); + y_scale *= 2; + bottom *= 2; + Draw(x_scale, y_scale, left, bottom, C1, m1, D1.first_half(), + D2.first_half()); + Draw(x_scale, y_scale, left, bottom + 1, m1, C2, D1.second_half(), + D2.second_half()); + } else if (d_left < COONCOLOR_THRESHOLD && + d_right < COONCOLOR_THRESHOLD) { + Coon_Bezier m2; + m2.BezierInterpol(C1, C2, D1, D2); + x_scale *= 2; + left *= 2; + Draw(x_scale, y_scale, left, bottom, C1.first_half(), C2.first_half(), + D1, m2); + Draw(x_scale, y_scale, left + 1, bottom, C1.second_half(), + C2.second_half(), m2, D2); + } else { + Coon_Bezier m1, m2; + m1.BezierInterpol(D1, D2, C1, C2); + m2.BezierInterpol(C1, C2, D1, D2); + Coon_Bezier m1f = m1.first_half(); + Coon_Bezier m1s = m1.second_half(); + Coon_Bezier m2f = m2.first_half(); + Coon_Bezier m2s = m2.second_half(); + x_scale *= 2; + y_scale *= 2; + left *= 2; + bottom *= 2; + Draw(x_scale, y_scale, left, bottom, C1.first_half(), m1f, + D1.first_half(), m2f); + Draw(x_scale, y_scale, left, bottom + 1, m1f, C2.first_half(), + D1.second_half(), m2s); + Draw(x_scale, y_scale, left + 1, bottom, C1.second_half(), m1s, m2f, + D2.first_half()); + Draw(x_scale, y_scale, left + 1, bottom + 1, m1s, C2.second_half(), m2s, + D2.second_half()); + } + } + } }; -FX_BOOL _CheckCoonTensorPara(const CPDF_MeshStream &stream) -{ - FX_BOOL bCoorBits = ( stream.m_nCoordBits== 1 || - stream.m_nCoordBits == 2 || - stream.m_nCoordBits == 4 || - stream.m_nCoordBits == 8 || - stream.m_nCoordBits == 12 || - stream.m_nCoordBits == 16 || - stream.m_nCoordBits == 24 || - stream.m_nCoordBits == 32 ); +FX_BOOL _CheckCoonTensorPara(const CPDF_MeshStream& stream) { + FX_BOOL bCoorBits = (stream.m_nCoordBits == 1 || stream.m_nCoordBits == 2 || + stream.m_nCoordBits == 4 || stream.m_nCoordBits == 8 || + stream.m_nCoordBits == 12 || stream.m_nCoordBits == 16 || + stream.m_nCoordBits == 24 || stream.m_nCoordBits == 32); - FX_BOOL bCompBits = ( stream.m_nCompBits == 1 || - stream.m_nCompBits == 2 || - stream.m_nCompBits == 4 || - stream.m_nCompBits == 8 || - stream.m_nCompBits == 12 || - stream.m_nCompBits == 16 ); + FX_BOOL bCompBits = (stream.m_nCompBits == 1 || stream.m_nCompBits == 2 || + stream.m_nCompBits == 4 || stream.m_nCompBits == 8 || + stream.m_nCompBits == 12 || stream.m_nCompBits == 16); - FX_BOOL bFlagBits = ( stream.m_nFlagBits == 2 || - stream.m_nFlagBits == 4 || - stream.m_nFlagBits == 8 ); + FX_BOOL bFlagBits = (stream.m_nFlagBits == 2 || stream.m_nFlagBits == 4 || + stream.m_nFlagBits == 8); - return bCoorBits && bCompBits && bFlagBits; + return bCoorBits && bCompBits && bFlagBits; } -static void _DrawCoonPatchMeshes(FX_BOOL bTensor, CFX_DIBitmap* pBitmap, CFX_AffineMatrix* pObject2Bitmap, - CPDF_Stream* pShadingStream, CPDF_Function** pFuncs, int nFuncs, - CPDF_ColorSpace* pCS, int fill_mode, int alpha) -{ - ASSERT(pBitmap->GetFormat() == FXDIB_Argb); - if (pShadingStream->GetType() != PDFOBJ_STREAM) { - return; - } - CFX_FxgeDevice device; - device.Attach(pBitmap); - CPDF_MeshStream stream; - if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) { - return; - } +static void _DrawCoonPatchMeshes(FX_BOOL bTensor, + CFX_DIBitmap* pBitmap, + CFX_AffineMatrix* pObject2Bitmap, + CPDF_Stream* pShadingStream, + CPDF_Function** pFuncs, + int nFuncs, + CPDF_ColorSpace* pCS, + int fill_mode, + int alpha) { + ASSERT(pBitmap->GetFormat() == FXDIB_Argb); + if (pShadingStream->GetType() != PDFOBJ_STREAM) { + return; + } + CFX_FxgeDevice device; + device.Attach(pBitmap); + CPDF_MeshStream stream; + if (!stream.Load(pShadingStream, pFuncs, nFuncs, pCS)) { + return; + } - if (!_CheckCoonTensorPara(stream)) { - return; - } + if (!_CheckCoonTensorPara(stream)) { + return; + } - CPDF_PatchDrawer patch; - patch.alpha = alpha; - patch.pDevice = &device; - patch.fill_mode = fill_mode; - patch.path.SetPointCount(13); - FX_PATHPOINT* pPoints = patch.path.GetPoints(); - pPoints[0].m_Flag = FXPT_MOVETO; - for (int i = 1; i < 13; i ++) { - pPoints[i].m_Flag = FXPT_BEZIERTO; - } - CFX_FloatPoint coords[16]; - for (int i = 0; i < 16; i ++) { - coords[i].Set(0.0f, 0.0f); - } + CPDF_PatchDrawer patch; + patch.alpha = alpha; + patch.pDevice = &device; + patch.fill_mode = fill_mode; + patch.path.SetPointCount(13); + FX_PATHPOINT* pPoints = patch.path.GetPoints(); + pPoints[0].m_Flag = FXPT_MOVETO; + for (int i = 1; i < 13; i++) { + pPoints[i].m_Flag = FXPT_BEZIERTO; + } + CFX_FloatPoint coords[16]; + for (int i = 0; i < 16; i++) { + coords[i].Set(0.0f, 0.0f); + } - int point_count = bTensor ? 16 : 12; - while (!stream.m_BitStream.IsEOF()) { - FX_DWORD flag = stream.GetFlag(); - int iStartPoint = 0, iStartColor = 0, i = 0; - if (flag) { - iStartPoint = 4; - iStartColor = 2; - CFX_FloatPoint tempCoords[4]; - for (i = 0; i < 4; i ++) { - tempCoords[i] = coords[(flag * 3 + i) % 12]; - } - FXSYS_memcpy(coords, tempCoords, sizeof(CFX_FloatPoint) * 4); - Coon_Color tempColors[2]; - tempColors[0] = patch.patch_colors[flag]; - tempColors[1] = patch.patch_colors[(flag + 1) % 4]; - FXSYS_memcpy(patch.patch_colors, tempColors, sizeof(Coon_Color) * 2); - } - for (i = iStartPoint; i < point_count; i ++) { - stream.GetCoords(coords[i].x, coords[i].y); - pObject2Bitmap->Transform(coords[i].x, coords[i].y); - } - for (i = iStartColor; i < 4; i ++) { - FX_FLOAT r=0.0f, g=0.0f, b=0.0f; - stream.GetColor(r, g, b); - patch.patch_colors[i].comp[0] = (int32_t)(r * 255); - patch.patch_colors[i].comp[1] = (int32_t)(g * 255); - patch.patch_colors[i].comp[2] = (int32_t)(b * 255); - } - CFX_FloatRect bbox = CFX_FloatRect::GetBBox(coords, point_count); - if (bbox.right <= 0 || bbox.left >= (FX_FLOAT)pBitmap->GetWidth() || bbox.top <= 0 || - bbox.bottom >= (FX_FLOAT)pBitmap->GetHeight()) { - continue; - } - Coon_Bezier C1, C2, D1, D2; - C1.FromPoints(coords[0].x, coords[0].y, coords[11].x, coords[11].y, coords[10].x, coords[10].y, - coords[9].x, coords[9].y); - C2.FromPoints(coords[3].x, coords[3].y, coords[4].x, coords[4].y, coords[5].x, coords[5].y, - coords[6].x, coords[6].y); - D1.FromPoints(coords[0].x, coords[0].y, coords[1].x, coords[1].y, coords[2].x, coords[2].y, - coords[3].x, coords[3].y); - D2.FromPoints(coords[9].x, coords[9].y, coords[8].x, coords[8].y, coords[7].x, coords[7].y, - coords[6].x, coords[6].y); - patch.Draw(1, 1, 0, 0, C1, C2, D1, D2); - } + int point_count = bTensor ? 16 : 12; + while (!stream.m_BitStream.IsEOF()) { + FX_DWORD flag = stream.GetFlag(); + int iStartPoint = 0, iStartColor = 0, i = 0; + if (flag) { + iStartPoint = 4; + iStartColor = 2; + CFX_FloatPoint tempCoords[4]; + for (i = 0; i < 4; i++) { + tempCoords[i] = coords[(flag * 3 + i) % 12]; + } + FXSYS_memcpy(coords, tempCoords, sizeof(CFX_FloatPoint) * 4); + Coon_Color tempColors[2]; + tempColors[0] = patch.patch_colors[flag]; + tempColors[1] = patch.patch_colors[(flag + 1) % 4]; + FXSYS_memcpy(patch.patch_colors, tempColors, sizeof(Coon_Color) * 2); + } + for (i = iStartPoint; i < point_count; i++) { + stream.GetCoords(coords[i].x, coords[i].y); + pObject2Bitmap->Transform(coords[i].x, coords[i].y); + } + for (i = iStartColor; i < 4; i++) { + FX_FLOAT r = 0.0f, g = 0.0f, b = 0.0f; + stream.GetColor(r, g, b); + patch.patch_colors[i].comp[0] = (int32_t)(r * 255); + patch.patch_colors[i].comp[1] = (int32_t)(g * 255); + patch.patch_colors[i].comp[2] = (int32_t)(b * 255); + } + CFX_FloatRect bbox = CFX_FloatRect::GetBBox(coords, point_count); + if (bbox.right <= 0 || bbox.left >= (FX_FLOAT)pBitmap->GetWidth() || + bbox.top <= 0 || bbox.bottom >= (FX_FLOAT)pBitmap->GetHeight()) { + continue; + } + Coon_Bezier C1, C2, D1, D2; + C1.FromPoints(coords[0].x, coords[0].y, coords[11].x, coords[11].y, + coords[10].x, coords[10].y, coords[9].x, coords[9].y); + C2.FromPoints(coords[3].x, coords[3].y, coords[4].x, coords[4].y, + coords[5].x, coords[5].y, coords[6].x, coords[6].y); + D1.FromPoints(coords[0].x, coords[0].y, coords[1].x, coords[1].y, + coords[2].x, coords[2].y, coords[3].x, coords[3].y); + D2.FromPoints(coords[9].x, coords[9].y, coords[8].x, coords[8].y, + coords[7].x, coords[7].y, coords[6].x, coords[6].y); + patch.Draw(1, 1, 0, 0, C1, C2, D1, D2); + } } -void CPDF_RenderStatus::DrawShading(CPDF_ShadingPattern* pPattern, CFX_AffineMatrix* pMatrix, - FX_RECT& clip_rect, int alpha, FX_BOOL bAlphaMode) -{ - CPDF_Function** pFuncs = pPattern->m_pFunctions; - int nFuncs = pPattern->m_nFuncs; - CPDF_Dictionary* pDict = pPattern->m_pShadingObj->GetDict(); - CPDF_ColorSpace* pColorSpace = pPattern->m_pCS; - if (pColorSpace == NULL) { - return; - } - FX_ARGB background = 0; - if (!pPattern->m_bShadingObj && pPattern->m_pShadingObj->GetDict()->KeyExist(FX_BSTRC("Background"))) { - CPDF_Array* pBackColor = pPattern->m_pShadingObj->GetDict()->GetArray(FX_BSTRC("Background")); - if (pBackColor && pBackColor->GetCount() >= (FX_DWORD)pColorSpace->CountComponents()) { - CFX_FixedBufGrow<FX_FLOAT, 16> comps(pColorSpace->CountComponents()); - for (int i = 0; i < pColorSpace->CountComponents(); i ++) { - comps[i] = pBackColor->GetNumber(i); - } - FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; - pColorSpace->GetRGB(comps, R, G, B); - background = ArgbEncode(255, (int32_t)(R * 255), (int32_t)(G * 255), (int32_t)(B * 255)); - } - } - if (pDict->KeyExist(FX_BSTRC("BBox"))) { - CFX_FloatRect rect = pDict->GetRect(FX_BSTRC("BBox")); - rect.Transform(pMatrix); - clip_rect.Intersect(rect.GetOutterRect()); - } - CPDF_DeviceBuffer buffer; - buffer.Initialize(m_pContext, m_pDevice, &clip_rect, m_pCurObj, 150); - CFX_AffineMatrix FinalMatrix = *pMatrix; - FinalMatrix.Concat(*buffer.GetMatrix()); - CFX_DIBitmap* pBitmap = buffer.GetBitmap(); - if (pBitmap->GetBuffer() == NULL) { - return; - } - pBitmap->Clear(background); - int fill_mode = m_Options.m_Flags; - switch (pPattern->m_ShadingType) { - case 1: - _DrawFuncShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, pColorSpace, alpha); - break; - case 2: - _DrawAxialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, pColorSpace, alpha); - break; - case 3: - _DrawRadialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, pColorSpace, alpha); - break; - case 4: { - _DrawFreeGouraudShading(pBitmap, &FinalMatrix, (CPDF_Stream*)pPattern->m_pShadingObj, - pFuncs, nFuncs, pColorSpace, alpha); - } - break; - case 5: { - _DrawLatticeGouraudShading(pBitmap, &FinalMatrix, (CPDF_Stream*)pPattern->m_pShadingObj, - pFuncs, nFuncs, pColorSpace, alpha); - } - break; - case 6: - case 7: { - _DrawCoonPatchMeshes(pPattern->m_ShadingType - 6, pBitmap, &FinalMatrix, (CPDF_Stream*)pPattern->m_pShadingObj, - pFuncs, nFuncs, pColorSpace, fill_mode, alpha); - } - break; - } - if (bAlphaMode) { - pBitmap->LoadChannel(FXDIB_Red, pBitmap, FXDIB_Alpha); - } - if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) { - pBitmap->ConvertColorScale(m_Options.m_ForeColor, m_Options.m_BackColor); - } - buffer.OutputToDevice(); +void CPDF_RenderStatus::DrawShading(CPDF_ShadingPattern* pPattern, + CFX_AffineMatrix* pMatrix, + FX_RECT& clip_rect, + int alpha, + FX_BOOL bAlphaMode) { + CPDF_Function** pFuncs = pPattern->m_pFunctions; + int nFuncs = pPattern->m_nFuncs; + CPDF_Dictionary* pDict = pPattern->m_pShadingObj->GetDict(); + CPDF_ColorSpace* pColorSpace = pPattern->m_pCS; + if (pColorSpace == NULL) { + return; + } + FX_ARGB background = 0; + if (!pPattern->m_bShadingObj && + pPattern->m_pShadingObj->GetDict()->KeyExist(FX_BSTRC("Background"))) { + CPDF_Array* pBackColor = + pPattern->m_pShadingObj->GetDict()->GetArray(FX_BSTRC("Background")); + if (pBackColor && + pBackColor->GetCount() >= (FX_DWORD)pColorSpace->CountComponents()) { + CFX_FixedBufGrow<FX_FLOAT, 16> comps(pColorSpace->CountComponents()); + for (int i = 0; i < pColorSpace->CountComponents(); i++) { + comps[i] = pBackColor->GetNumber(i); + } + FX_FLOAT R = 0.0f, G = 0.0f, B = 0.0f; + pColorSpace->GetRGB(comps, R, G, B); + background = ArgbEncode(255, (int32_t)(R * 255), (int32_t)(G * 255), + (int32_t)(B * 255)); + } + } + if (pDict->KeyExist(FX_BSTRC("BBox"))) { + CFX_FloatRect rect = pDict->GetRect(FX_BSTRC("BBox")); + rect.Transform(pMatrix); + clip_rect.Intersect(rect.GetOutterRect()); + } + CPDF_DeviceBuffer buffer; + buffer.Initialize(m_pContext, m_pDevice, &clip_rect, m_pCurObj, 150); + CFX_AffineMatrix FinalMatrix = *pMatrix; + FinalMatrix.Concat(*buffer.GetMatrix()); + CFX_DIBitmap* pBitmap = buffer.GetBitmap(); + if (pBitmap->GetBuffer() == NULL) { + return; + } + pBitmap->Clear(background); + int fill_mode = m_Options.m_Flags; + switch (pPattern->m_ShadingType) { + case 1: + _DrawFuncShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, + pColorSpace, alpha); + break; + case 2: + _DrawAxialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, + pColorSpace, alpha); + break; + case 3: + _DrawRadialShading(pBitmap, &FinalMatrix, pDict, pFuncs, nFuncs, + pColorSpace, alpha); + break; + case 4: { + _DrawFreeGouraudShading(pBitmap, &FinalMatrix, + (CPDF_Stream*)pPattern->m_pShadingObj, pFuncs, + nFuncs, pColorSpace, alpha); + } break; + case 5: { + _DrawLatticeGouraudShading(pBitmap, &FinalMatrix, + (CPDF_Stream*)pPattern->m_pShadingObj, pFuncs, + nFuncs, pColorSpace, alpha); + } break; + case 6: + case 7: { + _DrawCoonPatchMeshes(pPattern->m_ShadingType - 6, pBitmap, &FinalMatrix, + (CPDF_Stream*)pPattern->m_pShadingObj, pFuncs, + nFuncs, pColorSpace, fill_mode, alpha); + } break; + } + if (bAlphaMode) { + pBitmap->LoadChannel(FXDIB_Red, pBitmap, FXDIB_Alpha); + } + if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) { + pBitmap->ConvertColorScale(m_Options.m_ForeColor, m_Options.m_BackColor); + } + buffer.OutputToDevice(); } -void CPDF_RenderStatus::DrawShadingPattern(CPDF_ShadingPattern* pattern, CPDF_PageObject* pPageObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStroke) -{ - if (!pattern->Load()) { - return; - } - m_pDevice->SaveState(); - if (pPageObj->m_Type == PDFPAGE_PATH) { - if (!SelectClipPath((CPDF_PathObject*)pPageObj, pObj2Device, bStroke)) { - m_pDevice->RestoreState(); - return; - } - } else if (pPageObj->m_Type == PDFPAGE_IMAGE) { - FX_RECT rect = pPageObj->GetBBox(pObj2Device); - m_pDevice->SetClip_Rect(&rect); - } else { - return; - } - FX_RECT rect; - if (GetObjectClippedRect(pPageObj, pObj2Device, FALSE, rect)) { - m_pDevice->RestoreState(); - return; - } - CFX_AffineMatrix matrix = pattern->m_Pattern2Form; - matrix.Concat(*pObj2Device); - GetScaledMatrix(matrix); - int alpha = pPageObj->m_GeneralState.GetAlpha(bStroke); - DrawShading(pattern, &matrix, rect, alpha, m_Options.m_ColorMode == RENDER_COLOR_ALPHA); +void CPDF_RenderStatus::DrawShadingPattern(CPDF_ShadingPattern* pattern, + CPDF_PageObject* pPageObj, + const CFX_AffineMatrix* pObj2Device, + FX_BOOL bStroke) { + if (!pattern->Load()) { + return; + } + m_pDevice->SaveState(); + if (pPageObj->m_Type == PDFPAGE_PATH) { + if (!SelectClipPath((CPDF_PathObject*)pPageObj, pObj2Device, bStroke)) { + m_pDevice->RestoreState(); + return; + } + } else if (pPageObj->m_Type == PDFPAGE_IMAGE) { + FX_RECT rect = pPageObj->GetBBox(pObj2Device); + m_pDevice->SetClip_Rect(&rect); + } else { + return; + } + FX_RECT rect; + if (GetObjectClippedRect(pPageObj, pObj2Device, FALSE, rect)) { m_pDevice->RestoreState(); + return; + } + CFX_AffineMatrix matrix = pattern->m_Pattern2Form; + matrix.Concat(*pObj2Device); + GetScaledMatrix(matrix); + int alpha = pPageObj->m_GeneralState.GetAlpha(bStroke); + DrawShading(pattern, &matrix, rect, alpha, + m_Options.m_ColorMode == RENDER_COLOR_ALPHA); + m_pDevice->RestoreState(); } -FX_BOOL CPDF_RenderStatus::ProcessShading(CPDF_ShadingObject* pShadingObj, const CFX_AffineMatrix* pObj2Device) -{ - FX_RECT rect = pShadingObj->GetBBox(pObj2Device); - FX_RECT clip_box = m_pDevice->GetClipBox(); - rect.Intersect(clip_box); - if (rect.IsEmpty()) { - return TRUE; - } - CFX_AffineMatrix matrix = pShadingObj->m_Matrix; - matrix.Concat(*pObj2Device); - DrawShading(pShadingObj->m_pShading, &matrix, rect, pShadingObj->m_GeneralState.GetAlpha(FALSE), - m_Options.m_ColorMode == RENDER_COLOR_ALPHA); +FX_BOOL CPDF_RenderStatus::ProcessShading(CPDF_ShadingObject* pShadingObj, + const CFX_AffineMatrix* pObj2Device) { + FX_RECT rect = pShadingObj->GetBBox(pObj2Device); + FX_RECT clip_box = m_pDevice->GetClipBox(); + rect.Intersect(clip_box); + if (rect.IsEmpty()) { return TRUE; + } + CFX_AffineMatrix matrix = pShadingObj->m_Matrix; + matrix.Concat(*pObj2Device); + DrawShading(pShadingObj->m_pShading, &matrix, rect, + pShadingObj->m_GeneralState.GetAlpha(FALSE), + m_Options.m_ColorMode == RENDER_COLOR_ALPHA); + return TRUE; } -static CFX_DIBitmap* DrawPatternBitmap(CPDF_Document* pDoc, CPDF_PageRenderCache* pCache, - CPDF_TilingPattern* pPattern, const CFX_AffineMatrix* pObject2Device, - int width, int height, int flags) -{ - CFX_DIBitmap* pBitmap = new CFX_DIBitmap; - if (!pBitmap->Create(width, height, pPattern->m_bColored ? FXDIB_Argb : FXDIB_8bppMask)) { - delete pBitmap; - return NULL; - } - CFX_FxgeDevice bitmap_device; - bitmap_device.Attach(pBitmap); - pBitmap->Clear(0); - CFX_FloatRect cell_bbox = pPattern->m_BBox; - pPattern->m_Pattern2Form.TransformRect(cell_bbox); - pObject2Device->TransformRect(cell_bbox); - CFX_FloatRect bitmap_rect(0.0f, 0.0f, (FX_FLOAT)width, (FX_FLOAT)height); - CFX_AffineMatrix mtAdjust; - mtAdjust.MatchRect(bitmap_rect, cell_bbox); - CFX_AffineMatrix mtPattern2Bitmap = *pObject2Device; - mtPattern2Bitmap.Concat(mtAdjust); - CPDF_RenderOptions options; - if (!pPattern->m_bColored) { - options.m_ColorMode = RENDER_COLOR_ALPHA; - } - flags |= RENDER_FORCE_HALFTONE; - options.m_Flags = flags; - CPDF_RenderContext context; - context.Create(pDoc, pCache, NULL); - context.DrawObjectList(&bitmap_device, pPattern->m_pForm, &mtPattern2Bitmap, &options); - return pBitmap; +static CFX_DIBitmap* DrawPatternBitmap(CPDF_Document* pDoc, + CPDF_PageRenderCache* pCache, + CPDF_TilingPattern* pPattern, + const CFX_AffineMatrix* pObject2Device, + int width, + int height, + int flags) { + CFX_DIBitmap* pBitmap = new CFX_DIBitmap; + if (!pBitmap->Create(width, height, + pPattern->m_bColored ? FXDIB_Argb : FXDIB_8bppMask)) { + delete pBitmap; + return NULL; + } + CFX_FxgeDevice bitmap_device; + bitmap_device.Attach(pBitmap); + pBitmap->Clear(0); + CFX_FloatRect cell_bbox = pPattern->m_BBox; + pPattern->m_Pattern2Form.TransformRect(cell_bbox); + pObject2Device->TransformRect(cell_bbox); + CFX_FloatRect bitmap_rect(0.0f, 0.0f, (FX_FLOAT)width, (FX_FLOAT)height); + CFX_AffineMatrix mtAdjust; + mtAdjust.MatchRect(bitmap_rect, cell_bbox); + CFX_AffineMatrix mtPattern2Bitmap = *pObject2Device; + mtPattern2Bitmap.Concat(mtAdjust); + CPDF_RenderOptions options; + if (!pPattern->m_bColored) { + options.m_ColorMode = RENDER_COLOR_ALPHA; + } + flags |= RENDER_FORCE_HALFTONE; + options.m_Flags = flags; + CPDF_RenderContext context; + context.Create(pDoc, pCache, NULL); + context.DrawObjectList(&bitmap_device, pPattern->m_pForm, &mtPattern2Bitmap, + &options); + return pBitmap; } -void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern, CPDF_PageObject* pPageObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStroke) -{ - if (!pPattern->Load()) { - return; - } - m_pDevice->SaveState(); - if (pPageObj->m_Type == PDFPAGE_PATH) { - if (!SelectClipPath((CPDF_PathObject*)pPageObj, pObj2Device, bStroke)) { - m_pDevice->RestoreState(); - return; - } - } else if (pPageObj->m_Type == PDFPAGE_IMAGE) { - FX_RECT rect = pPageObj->GetBBox(pObj2Device); - m_pDevice->SetClip_Rect(&rect); - } else { - return; - } - FX_RECT clip_box = m_pDevice->GetClipBox(); - if (clip_box.IsEmpty()) { - m_pDevice->RestoreState(); - return; - } - CFX_Matrix dCTM = m_pDevice->GetCTM(); - FX_FLOAT sa = FXSYS_fabs(dCTM.a); - FX_FLOAT sd = FXSYS_fabs(dCTM.d); - clip_box.right = clip_box.left + (int32_t)FXSYS_ceil(clip_box.Width() * sa); - clip_box.bottom = clip_box.top + (int32_t)FXSYS_ceil(clip_box.Height() * sd); - CFX_AffineMatrix mtPattern2Device = pPattern->m_Pattern2Form; - mtPattern2Device.Concat(*pObj2Device); - GetScaledMatrix(mtPattern2Device); - FX_BOOL bAligned = FALSE; - if (pPattern->m_BBox.left == 0 && pPattern->m_BBox.bottom == 0 && - pPattern->m_BBox.right == pPattern->m_XStep && pPattern->m_BBox.top == pPattern->m_YStep && - (mtPattern2Device.IsScaled() || mtPattern2Device.Is90Rotated())) { - bAligned = TRUE; - } - CFX_FloatRect cell_bbox = pPattern->m_BBox; - mtPattern2Device.TransformRect(cell_bbox); - int width = (int)FXSYS_ceil(cell_bbox.Width()); - int height = (int)FXSYS_ceil(cell_bbox.Height()); - if (width == 0) { - width = 1; - } - if (height == 0) { - height = 1; - } - int min_col, max_col, min_row, max_row; - CFX_AffineMatrix mtDevice2Pattern; - mtDevice2Pattern.SetReverse(mtPattern2Device); - CFX_FloatRect clip_box_p(clip_box); - clip_box_p.Transform(&mtDevice2Pattern); - min_col = (int)FXSYS_ceil(FXSYS_Div(clip_box_p.left - pPattern->m_BBox.right, pPattern->m_XStep)); - max_col = (int)FXSYS_floor(FXSYS_Div(clip_box_p.right - pPattern->m_BBox.left, pPattern->m_XStep)); - min_row = (int)FXSYS_ceil(FXSYS_Div(clip_box_p.bottom - pPattern->m_BBox.top, pPattern->m_YStep)); - max_row = (int)FXSYS_floor(FXSYS_Div(clip_box_p.top - pPattern->m_BBox.bottom, pPattern->m_YStep)); - if (width > clip_box.Width() || height > clip_box.Height() || width * height > clip_box.Width() * clip_box.Height()) { - CPDF_GraphicStates* pStates = NULL; - if (!pPattern->m_bColored) { - pStates = CloneObjStates(pPageObj, bStroke); - } - CPDF_Dictionary* pFormResource = NULL; - if (pPattern->m_pForm->m_pFormDict) { - pFormResource = pPattern->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources")); - } - for (int col = min_col; col <= max_col; col ++) - for (int row = min_row; row <= max_row; row ++) { - FX_FLOAT orig_x, orig_y; - orig_x = col * pPattern->m_XStep; - orig_y = row * pPattern->m_YStep; - mtPattern2Device.Transform(orig_x, orig_y); - CFX_AffineMatrix matrix = *pObj2Device; - matrix.Translate(orig_x - mtPattern2Device.e, orig_y - mtPattern2Device.f); - m_pDevice->SaveState(); - CPDF_RenderStatus status; - status.Initialize(m_pContext, m_pDevice, NULL, NULL, this, pStates, &m_Options, - pPattern->m_pForm->m_Transparency, m_bDropObjects, pFormResource); - status.RenderObjectList(pPattern->m_pForm, &matrix); - m_pDevice->RestoreState(); - } +void CPDF_RenderStatus::DrawTilingPattern(CPDF_TilingPattern* pPattern, + CPDF_PageObject* pPageObj, + const CFX_AffineMatrix* pObj2Device, + FX_BOOL bStroke) { + if (!pPattern->Load()) { + return; + } + m_pDevice->SaveState(); + if (pPageObj->m_Type == PDFPAGE_PATH) { + if (!SelectClipPath((CPDF_PathObject*)pPageObj, pObj2Device, bStroke)) { + m_pDevice->RestoreState(); + return; + } + } else if (pPageObj->m_Type == PDFPAGE_IMAGE) { + FX_RECT rect = pPageObj->GetBBox(pObj2Device); + m_pDevice->SetClip_Rect(&rect); + } else { + return; + } + FX_RECT clip_box = m_pDevice->GetClipBox(); + if (clip_box.IsEmpty()) { + m_pDevice->RestoreState(); + return; + } + CFX_Matrix dCTM = m_pDevice->GetCTM(); + FX_FLOAT sa = FXSYS_fabs(dCTM.a); + FX_FLOAT sd = FXSYS_fabs(dCTM.d); + clip_box.right = clip_box.left + (int32_t)FXSYS_ceil(clip_box.Width() * sa); + clip_box.bottom = clip_box.top + (int32_t)FXSYS_ceil(clip_box.Height() * sd); + CFX_AffineMatrix mtPattern2Device = pPattern->m_Pattern2Form; + mtPattern2Device.Concat(*pObj2Device); + GetScaledMatrix(mtPattern2Device); + FX_BOOL bAligned = FALSE; + if (pPattern->m_BBox.left == 0 && pPattern->m_BBox.bottom == 0 && + pPattern->m_BBox.right == pPattern->m_XStep && + pPattern->m_BBox.top == pPattern->m_YStep && + (mtPattern2Device.IsScaled() || mtPattern2Device.Is90Rotated())) { + bAligned = TRUE; + } + CFX_FloatRect cell_bbox = pPattern->m_BBox; + mtPattern2Device.TransformRect(cell_bbox); + int width = (int)FXSYS_ceil(cell_bbox.Width()); + int height = (int)FXSYS_ceil(cell_bbox.Height()); + if (width == 0) { + width = 1; + } + if (height == 0) { + height = 1; + } + int min_col, max_col, min_row, max_row; + CFX_AffineMatrix mtDevice2Pattern; + mtDevice2Pattern.SetReverse(mtPattern2Device); + CFX_FloatRect clip_box_p(clip_box); + clip_box_p.Transform(&mtDevice2Pattern); + min_col = (int)FXSYS_ceil( + FXSYS_Div(clip_box_p.left - pPattern->m_BBox.right, pPattern->m_XStep)); + max_col = (int)FXSYS_floor( + FXSYS_Div(clip_box_p.right - pPattern->m_BBox.left, pPattern->m_XStep)); + min_row = (int)FXSYS_ceil( + FXSYS_Div(clip_box_p.bottom - pPattern->m_BBox.top, pPattern->m_YStep)); + max_row = (int)FXSYS_floor( + FXSYS_Div(clip_box_p.top - pPattern->m_BBox.bottom, pPattern->m_YStep)); + if (width > clip_box.Width() || height > clip_box.Height() || + width * height > clip_box.Width() * clip_box.Height()) { + CPDF_GraphicStates* pStates = NULL; + if (!pPattern->m_bColored) { + pStates = CloneObjStates(pPageObj, bStroke); + } + CPDF_Dictionary* pFormResource = NULL; + if (pPattern->m_pForm->m_pFormDict) { + pFormResource = + pPattern->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources")); + } + for (int col = min_col; col <= max_col; col++) + for (int row = min_row; row <= max_row; row++) { + FX_FLOAT orig_x, orig_y; + orig_x = col * pPattern->m_XStep; + orig_y = row * pPattern->m_YStep; + mtPattern2Device.Transform(orig_x, orig_y); + CFX_AffineMatrix matrix = *pObj2Device; + matrix.Translate(orig_x - mtPattern2Device.e, + orig_y - mtPattern2Device.f); + m_pDevice->SaveState(); + CPDF_RenderStatus status; + status.Initialize(m_pContext, m_pDevice, NULL, NULL, this, pStates, + &m_Options, pPattern->m_pForm->m_Transparency, + m_bDropObjects, pFormResource); + status.RenderObjectList(pPattern->m_pForm, &matrix); m_pDevice->RestoreState(); - delete pStates; - return; - } - if (bAligned) { - int orig_x = FXSYS_round(mtPattern2Device.e); - int orig_y = FXSYS_round(mtPattern2Device.f); - min_col = (clip_box.left - orig_x) / width; - if (clip_box.left < orig_x) { - min_col --; - } - max_col = (clip_box.right - orig_x) / width; - if (clip_box.right <= orig_x) { - max_col --; - } - min_row = (clip_box.top - orig_y) / height; - if (clip_box.top < orig_y) { - min_row --; + } + m_pDevice->RestoreState(); + delete pStates; + return; + } + if (bAligned) { + int orig_x = FXSYS_round(mtPattern2Device.e); + int orig_y = FXSYS_round(mtPattern2Device.f); + min_col = (clip_box.left - orig_x) / width; + if (clip_box.left < orig_x) { + min_col--; + } + max_col = (clip_box.right - orig_x) / width; + if (clip_box.right <= orig_x) { + max_col--; + } + min_row = (clip_box.top - orig_y) / height; + if (clip_box.top < orig_y) { + min_row--; + } + max_row = (clip_box.bottom - orig_y) / height; + if (clip_box.bottom <= orig_y) { + max_row--; + } + } + FX_FLOAT left_offset = cell_bbox.left - mtPattern2Device.e; + FX_FLOAT top_offset = cell_bbox.bottom - mtPattern2Device.f; + CFX_DIBitmap* pPatternBitmap = NULL; + if (width * height < 16) { + CFX_DIBitmap* pEnlargedBitmap = + DrawPatternBitmap(m_pContext->m_pDocument, m_pContext->m_pPageCache, + pPattern, pObj2Device, 8, 8, m_Options.m_Flags); + pPatternBitmap = pEnlargedBitmap->StretchTo(width, height); + delete pEnlargedBitmap; + } else { + pPatternBitmap = DrawPatternBitmap( + m_pContext->m_pDocument, m_pContext->m_pPageCache, pPattern, + pObj2Device, width, height, m_Options.m_Flags); + } + if (pPatternBitmap == NULL) { + m_pDevice->RestoreState(); + return; + } + if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) { + pPatternBitmap->ConvertColorScale(m_Options.m_ForeColor, + m_Options.m_BackColor); + } + FX_ARGB fill_argb = GetFillArgb(pPageObj); + int clip_width = clip_box.right - clip_box.left; + int clip_height = clip_box.bottom - clip_box.top; + CFX_DIBitmap screen; + if (!screen.Create(clip_width, clip_height, FXDIB_Argb)) { + return; + } + screen.Clear(0); + FX_DWORD* src_buf = (FX_DWORD*)pPatternBitmap->GetBuffer(); + for (int col = min_col; col <= max_col; col++) { + for (int row = min_row; row <= max_row; row++) { + int start_x, start_y; + if (bAligned) { + start_x = FXSYS_round(mtPattern2Device.e) + col * width - clip_box.left; + start_y = FXSYS_round(mtPattern2Device.f) + row * height - clip_box.top; + } else { + FX_FLOAT orig_x = col * pPattern->m_XStep; + FX_FLOAT orig_y = row * pPattern->m_YStep; + mtPattern2Device.Transform(orig_x, orig_y); + start_x = FXSYS_round(orig_x + left_offset) - clip_box.left; + start_y = FXSYS_round(orig_y + top_offset) - clip_box.top; + } + if (width == 1 && height == 1) { + if (start_x < 0 || start_x >= clip_box.Width() || start_y < 0 || + start_y >= clip_box.Height()) { + continue; } - max_row = (clip_box.bottom - orig_y) / height; - if (clip_box.bottom <= orig_y) { - max_row --; + FX_DWORD* dest_buf = + (FX_DWORD*)(screen.GetBuffer() + screen.GetPitch() * start_y + + start_x * 4); + if (pPattern->m_bColored) { + *dest_buf = *src_buf; + } else { + *dest_buf = (*(uint8_t*)src_buf << 24) | (fill_argb & 0xffffff); } - } - FX_FLOAT left_offset = cell_bbox.left - mtPattern2Device.e; - FX_FLOAT top_offset = cell_bbox.bottom - mtPattern2Device.f; - CFX_DIBitmap* pPatternBitmap = NULL; - if (width * height < 16) { - CFX_DIBitmap* pEnlargedBitmap = DrawPatternBitmap(m_pContext->m_pDocument, m_pContext->m_pPageCache, pPattern, pObj2Device, 8, 8, m_Options.m_Flags); - pPatternBitmap = pEnlargedBitmap->StretchTo(width, height); - delete pEnlargedBitmap; - } else { - pPatternBitmap = DrawPatternBitmap(m_pContext->m_pDocument, m_pContext->m_pPageCache, pPattern, pObj2Device, width, height, m_Options.m_Flags); - } - if (pPatternBitmap == NULL) { - m_pDevice->RestoreState(); - return; - } - if (m_Options.m_ColorMode == RENDER_COLOR_GRAY) { - pPatternBitmap->ConvertColorScale(m_Options.m_ForeColor, m_Options.m_BackColor); - } - FX_ARGB fill_argb = GetFillArgb(pPageObj); - int clip_width = clip_box.right - clip_box.left; - int clip_height = clip_box.bottom - clip_box.top; - CFX_DIBitmap screen; - if (!screen.Create(clip_width, clip_height, FXDIB_Argb)) { - return; - } - screen.Clear(0); - FX_DWORD* src_buf = (FX_DWORD*)pPatternBitmap->GetBuffer(); - for (int col = min_col; col <= max_col; col ++) { - for (int row = min_row; row <= max_row; row ++) { - int start_x, start_y; - if (bAligned) { - start_x = FXSYS_round(mtPattern2Device.e) + col * width - clip_box.left; - start_y = FXSYS_round(mtPattern2Device.f) + row * height - clip_box.top; - } else { - FX_FLOAT orig_x = col * pPattern->m_XStep; - FX_FLOAT orig_y = row * pPattern->m_YStep; - mtPattern2Device.Transform(orig_x, orig_y); - start_x = FXSYS_round(orig_x + left_offset) - clip_box.left; - start_y = FXSYS_round(orig_y + top_offset) - clip_box.top; - } - if (width == 1 && height == 1) { - if (start_x < 0 || start_x >= clip_box.Width() || start_y < 0 || start_y >= clip_box.Height()) { - continue; - } - FX_DWORD* dest_buf = (FX_DWORD*)(screen.GetBuffer() + screen.GetPitch() * start_y + start_x * 4); - if (pPattern->m_bColored) { - *dest_buf = *src_buf; - } else { - *dest_buf = (*(uint8_t*)src_buf << 24) | (fill_argb & 0xffffff); - } - } else { - if (pPattern->m_bColored) { - screen.CompositeBitmap(start_x, start_y, width, height, pPatternBitmap, 0, 0); - } else { - screen.CompositeMask(start_x, start_y, width, height, pPatternBitmap, fill_argb, 0, 0); - } - } + } else { + if (pPattern->m_bColored) { + screen.CompositeBitmap(start_x, start_y, width, height, + pPatternBitmap, 0, 0); + } else { + screen.CompositeMask(start_x, start_y, width, height, pPatternBitmap, + fill_argb, 0, 0); } + } } - CompositeDIBitmap(&screen, clip_box.left, clip_box.top, 0, 255, FXDIB_BLEND_NORMAL, FALSE); - m_pDevice->RestoreState(); - delete pPatternBitmap; + } + CompositeDIBitmap(&screen, clip_box.left, clip_box.top, 0, 255, + FXDIB_BLEND_NORMAL, FALSE); + m_pDevice->RestoreState(); + delete pPatternBitmap; } -void CPDF_RenderStatus::DrawPathWithPattern(CPDF_PathObject* pPathObj, const CFX_AffineMatrix* pObj2Device, CPDF_Color* pColor, FX_BOOL bStroke) -{ - CPDF_Pattern* pattern = pColor->GetPattern(); - if (pattern == NULL) { - return; - } - if(pattern->m_PatternType == PATTERN_TILING) { - DrawTilingPattern((CPDF_TilingPattern*)pattern, pPathObj, pObj2Device, bStroke); - } else { - DrawShadingPattern((CPDF_ShadingPattern*)pattern, pPathObj, pObj2Device, bStroke); - } +void CPDF_RenderStatus::DrawPathWithPattern(CPDF_PathObject* pPathObj, + const CFX_AffineMatrix* pObj2Device, + CPDF_Color* pColor, + FX_BOOL bStroke) { + CPDF_Pattern* pattern = pColor->GetPattern(); + if (pattern == NULL) { + return; + } + if (pattern->m_PatternType == PATTERN_TILING) { + DrawTilingPattern((CPDF_TilingPattern*)pattern, pPathObj, pObj2Device, + bStroke); + } else { + DrawShadingPattern((CPDF_ShadingPattern*)pattern, pPathObj, pObj2Device, + bStroke); + } } -void CPDF_RenderStatus::ProcessPathPattern(CPDF_PathObject* pPathObj, const CFX_AffineMatrix* pObj2Device, int& filltype, FX_BOOL& bStroke) -{ - if(filltype) { - CPDF_Color& FillColor = *pPathObj->m_ColorState.GetFillColor(); - if(FillColor.m_pCS && FillColor.m_pCS->GetFamily() == PDFCS_PATTERN) { - DrawPathWithPattern(pPathObj, pObj2Device, &FillColor, FALSE); - filltype = 0; - } - } - if(bStroke) { - CPDF_Color& StrokeColor = *pPathObj->m_ColorState.GetStrokeColor(); - if(StrokeColor.m_pCS && StrokeColor.m_pCS->GetFamily() == PDFCS_PATTERN) { - DrawPathWithPattern(pPathObj, pObj2Device, &StrokeColor, TRUE); - bStroke = FALSE; - } - } +void CPDF_RenderStatus::ProcessPathPattern(CPDF_PathObject* pPathObj, + const CFX_AffineMatrix* pObj2Device, + int& filltype, + FX_BOOL& bStroke) { + if (filltype) { + CPDF_Color& FillColor = *pPathObj->m_ColorState.GetFillColor(); + if (FillColor.m_pCS && FillColor.m_pCS->GetFamily() == PDFCS_PATTERN) { + DrawPathWithPattern(pPathObj, pObj2Device, &FillColor, FALSE); + filltype = 0; + } + } + if (bStroke) { + CPDF_Color& StrokeColor = *pPathObj->m_ColorState.GetStrokeColor(); + if (StrokeColor.m_pCS && StrokeColor.m_pCS->GetFamily() == PDFCS_PATTERN) { + DrawPathWithPattern(pPathObj, pObj2Device, &StrokeColor, TRUE); + bStroke = FALSE; + } + } } diff --git a/core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp b/core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp index ad5dc58a1c..7d6921f544 100644 --- a/core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp +++ b/core/src/fpdfapi/fpdf_render/fpdf_render_text.cpp @@ -10,723 +10,791 @@ #include "../fpdf_page/pageint.h" #include "render_int.h" extern FX_BOOL IsAvailableMatrix(const CFX_AffineMatrix& matrix); -CPDF_Type3Cache::~CPDF_Type3Cache() -{ - FX_POSITION pos = m_SizeMap.GetStartPosition(); - CFX_ByteString Key; - CPDF_Type3Glyphs* pSizeCache = NULL; - while(pos) { - pSizeCache = (CPDF_Type3Glyphs*)m_SizeMap.GetNextValue(pos); - delete pSizeCache; - } - m_SizeMap.RemoveAll(); +CPDF_Type3Cache::~CPDF_Type3Cache() { + FX_POSITION pos = m_SizeMap.GetStartPosition(); + CFX_ByteString Key; + CPDF_Type3Glyphs* pSizeCache = NULL; + while (pos) { + pSizeCache = (CPDF_Type3Glyphs*)m_SizeMap.GetNextValue(pos); + delete pSizeCache; + } + m_SizeMap.RemoveAll(); } -CFX_GlyphBitmap* CPDF_Type3Cache::LoadGlyph(FX_DWORD charcode, const CFX_AffineMatrix* pMatrix, FX_FLOAT retinaScaleX, FX_FLOAT retinaScaleY) -{ - _CPDF_UniqueKeyGen keygen; - keygen.Generate(4, FXSYS_round(pMatrix->a * 10000), FXSYS_round(pMatrix->b * 10000), - FXSYS_round(pMatrix->c * 10000), FXSYS_round(pMatrix->d * 10000)); - CFX_ByteStringC FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen); - CPDF_Type3Glyphs* pSizeCache = NULL; - if(!m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) { - pSizeCache = new CPDF_Type3Glyphs; - m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache); - } - CFX_GlyphBitmap* pGlyphBitmap; - if(pSizeCache->m_GlyphMap.Lookup((void*)(uintptr_t)charcode, (void*&)pGlyphBitmap)) { - return pGlyphBitmap; - } - pGlyphBitmap = RenderGlyph(pSizeCache, charcode, pMatrix, retinaScaleX, retinaScaleY); - pSizeCache->m_GlyphMap.SetAt((void*)(uintptr_t)charcode, pGlyphBitmap); +CFX_GlyphBitmap* CPDF_Type3Cache::LoadGlyph(FX_DWORD charcode, + const CFX_AffineMatrix* pMatrix, + FX_FLOAT retinaScaleX, + FX_FLOAT retinaScaleY) { + _CPDF_UniqueKeyGen keygen; + keygen.Generate( + 4, FXSYS_round(pMatrix->a * 10000), FXSYS_round(pMatrix->b * 10000), + FXSYS_round(pMatrix->c * 10000), FXSYS_round(pMatrix->d * 10000)); + CFX_ByteStringC FaceGlyphsKey(keygen.m_Key, keygen.m_KeyLen); + CPDF_Type3Glyphs* pSizeCache = NULL; + if (!m_SizeMap.Lookup(FaceGlyphsKey, (void*&)pSizeCache)) { + pSizeCache = new CPDF_Type3Glyphs; + m_SizeMap.SetAt(FaceGlyphsKey, pSizeCache); + } + CFX_GlyphBitmap* pGlyphBitmap; + if (pSizeCache->m_GlyphMap.Lookup((void*)(uintptr_t)charcode, + (void*&)pGlyphBitmap)) { return pGlyphBitmap; + } + pGlyphBitmap = + RenderGlyph(pSizeCache, charcode, pMatrix, retinaScaleX, retinaScaleY); + pSizeCache->m_GlyphMap.SetAt((void*)(uintptr_t)charcode, pGlyphBitmap); + return pGlyphBitmap; } -CPDF_Type3Glyphs::~CPDF_Type3Glyphs() -{ - FX_POSITION pos = m_GlyphMap.GetStartPosition(); - void* Key; - CFX_GlyphBitmap* pGlyphBitmap; - while(pos) { - m_GlyphMap.GetNextAssoc(pos, Key, (void*&)pGlyphBitmap); - delete pGlyphBitmap; - } +CPDF_Type3Glyphs::~CPDF_Type3Glyphs() { + FX_POSITION pos = m_GlyphMap.GetStartPosition(); + void* Key; + CFX_GlyphBitmap* pGlyphBitmap; + while (pos) { + m_GlyphMap.GetNextAssoc(pos, Key, (void*&)pGlyphBitmap); + delete pGlyphBitmap; + } } -static int _AdjustBlue(FX_FLOAT pos, int& count, int blues[]) -{ - FX_FLOAT min_distance = 1000000.0f * 1.0f; - int closest_pos = -1; - for (int i = 0; i < count; i ++) { - FX_FLOAT distance = (FX_FLOAT)FXSYS_fabs(pos - (FX_FLOAT)blues[i]); - if (distance < 1.0f * 80.0f / 100.0f && distance < min_distance) { - min_distance = distance; - closest_pos = i; - } - } - if (closest_pos >= 0) { - return blues[closest_pos]; - } - int new_pos = FXSYS_round(pos); - if (count == TYPE3_MAX_BLUES) { - return new_pos; - } - blues[count++] = new_pos; +static int _AdjustBlue(FX_FLOAT pos, int& count, int blues[]) { + FX_FLOAT min_distance = 1000000.0f * 1.0f; + int closest_pos = -1; + for (int i = 0; i < count; i++) { + FX_FLOAT distance = (FX_FLOAT)FXSYS_fabs(pos - (FX_FLOAT)blues[i]); + if (distance < 1.0f * 80.0f / 100.0f && distance < min_distance) { + min_distance = distance; + closest_pos = i; + } + } + if (closest_pos >= 0) { + return blues[closest_pos]; + } + int new_pos = FXSYS_round(pos); + if (count == TYPE3_MAX_BLUES) { return new_pos; + } + blues[count++] = new_pos; + return new_pos; } -void CPDF_Type3Glyphs::AdjustBlue(FX_FLOAT top, FX_FLOAT bottom, int& top_line, int& bottom_line) -{ - top_line = _AdjustBlue(top, m_TopBlueCount, m_TopBlue); - bottom_line = _AdjustBlue(bottom, m_BottomBlueCount, m_BottomBlue); +void CPDF_Type3Glyphs::AdjustBlue(FX_FLOAT top, + FX_FLOAT bottom, + int& top_line, + int& bottom_line) { + top_line = _AdjustBlue(top, m_TopBlueCount, m_TopBlue); + bottom_line = _AdjustBlue(bottom, m_BottomBlueCount, m_BottomBlue); } -static FX_BOOL _IsScanLine1bpp(uint8_t* pBuf, int width) -{ - int size = width / 8; - for (int i = 0; i < size; i ++) - if (pBuf[i]) { - return TRUE; - } - if (width % 8) - if (pBuf[width / 8] & (0xff << (8 - width % 8))) { - return TRUE; - } - return FALSE; -} -static FX_BOOL _IsScanLine8bpp(uint8_t* pBuf, int width) -{ - for (int i = 0; i < width; i ++) - if (pBuf[i] > 0x40) { - return TRUE; - } - return FALSE; +static FX_BOOL _IsScanLine1bpp(uint8_t* pBuf, int width) { + int size = width / 8; + for (int i = 0; i < size; i++) + if (pBuf[i]) { + return TRUE; + } + if (width % 8) + if (pBuf[width / 8] & (0xff << (8 - width % 8))) { + return TRUE; + } + return FALSE; } -static int _DetectFirstLastScan(const CFX_DIBitmap* pBitmap, FX_BOOL bFirst) -{ - int height = pBitmap->GetHeight(), pitch = pBitmap->GetPitch(), width = pBitmap->GetWidth(); - int bpp = pBitmap->GetBPP(); - if (bpp > 8) { - width *= bpp / 8; - } - uint8_t* pBuf = pBitmap->GetBuffer(); - int line = bFirst ? 0 : height - 1; - int line_step = bFirst ? 1 : -1; - int line_end = bFirst ? height : -1; - while (line != line_end) { - if (bpp == 1) { - if (_IsScanLine1bpp(pBuf + line * pitch, width)) { - return line; - } - } else { - if (_IsScanLine8bpp(pBuf + line * pitch, width)) { - return line; - } - } - line += line_step; +static FX_BOOL _IsScanLine8bpp(uint8_t* pBuf, int width) { + for (int i = 0; i < width; i++) + if (pBuf[i] > 0x40) { + return TRUE; } - return -1; + return FALSE; } -CFX_GlyphBitmap* CPDF_Type3Cache::RenderGlyph(CPDF_Type3Glyphs* pSize, FX_DWORD charcode, const CFX_AffineMatrix* pMatrix, FX_FLOAT retinaScaleX, FX_FLOAT retinaScaleY) -{ - CPDF_Type3Char* pChar = m_pFont->LoadChar(charcode); - if (pChar == NULL || pChar->m_pBitmap == NULL) { - return NULL; - } - CFX_DIBitmap* pBitmap = pChar->m_pBitmap; - CFX_AffineMatrix image_matrix, text_matrix; - image_matrix = pChar->m_ImageMatrix; - text_matrix.Set(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, 0, 0); - image_matrix.Concat(text_matrix); - CFX_DIBitmap* pResBitmap = NULL; - int left, top; - if (FXSYS_fabs(image_matrix.b) < FXSYS_fabs(image_matrix.a) / 100 && FXSYS_fabs(image_matrix.c) < FXSYS_fabs(image_matrix.d) / 100) { - int top_line, bottom_line; - top_line = _DetectFirstLastScan(pBitmap, TRUE); - bottom_line = _DetectFirstLastScan(pBitmap, FALSE); - if (top_line == 0 && bottom_line == pBitmap->GetHeight() - 1) { - FX_FLOAT top_y = image_matrix.d + image_matrix.f; - FX_FLOAT bottom_y = image_matrix.f; - FX_BOOL bFlipped = top_y > bottom_y; - if (bFlipped) { - FX_FLOAT temp = top_y; - top_y = bottom_y; - bottom_y = temp; - } - pSize->AdjustBlue(top_y, bottom_y, top_line, bottom_line); - pResBitmap = pBitmap->StretchTo((int)(FXSYS_round(image_matrix.a) * retinaScaleX), (int)((bFlipped ? top_line - bottom_line : bottom_line - top_line) * retinaScaleY)); - top = top_line; - if (image_matrix.a < 0) { - image_matrix.Scale(retinaScaleX, retinaScaleY); - left = FXSYS_round(image_matrix.e + image_matrix.a); - } else { - left = FXSYS_round(image_matrix.e); - } - } else { - } +static int _DetectFirstLastScan(const CFX_DIBitmap* pBitmap, FX_BOOL bFirst) { + int height = pBitmap->GetHeight(), pitch = pBitmap->GetPitch(), + width = pBitmap->GetWidth(); + int bpp = pBitmap->GetBPP(); + if (bpp > 8) { + width *= bpp / 8; + } + uint8_t* pBuf = pBitmap->GetBuffer(); + int line = bFirst ? 0 : height - 1; + int line_step = bFirst ? 1 : -1; + int line_end = bFirst ? height : -1; + while (line != line_end) { + if (bpp == 1) { + if (_IsScanLine1bpp(pBuf + line * pitch, width)) { + return line; + } + } else { + if (_IsScanLine8bpp(pBuf + line * pitch, width)) { + return line; + } } - if (pResBitmap == NULL) { + line += line_step; + } + return -1; +} +CFX_GlyphBitmap* CPDF_Type3Cache::RenderGlyph(CPDF_Type3Glyphs* pSize, + FX_DWORD charcode, + const CFX_AffineMatrix* pMatrix, + FX_FLOAT retinaScaleX, + FX_FLOAT retinaScaleY) { + CPDF_Type3Char* pChar = m_pFont->LoadChar(charcode); + if (pChar == NULL || pChar->m_pBitmap == NULL) { + return NULL; + } + CFX_DIBitmap* pBitmap = pChar->m_pBitmap; + CFX_AffineMatrix image_matrix, text_matrix; + image_matrix = pChar->m_ImageMatrix; + text_matrix.Set(pMatrix->a, pMatrix->b, pMatrix->c, pMatrix->d, 0, 0); + image_matrix.Concat(text_matrix); + CFX_DIBitmap* pResBitmap = NULL; + int left, top; + if (FXSYS_fabs(image_matrix.b) < FXSYS_fabs(image_matrix.a) / 100 && + FXSYS_fabs(image_matrix.c) < FXSYS_fabs(image_matrix.d) / 100) { + int top_line, bottom_line; + top_line = _DetectFirstLastScan(pBitmap, TRUE); + bottom_line = _DetectFirstLastScan(pBitmap, FALSE); + if (top_line == 0 && bottom_line == pBitmap->GetHeight() - 1) { + FX_FLOAT top_y = image_matrix.d + image_matrix.f; + FX_FLOAT bottom_y = image_matrix.f; + FX_BOOL bFlipped = top_y > bottom_y; + if (bFlipped) { + FX_FLOAT temp = top_y; + top_y = bottom_y; + bottom_y = temp; + } + pSize->AdjustBlue(top_y, bottom_y, top_line, bottom_line); + pResBitmap = pBitmap->StretchTo( + (int)(FXSYS_round(image_matrix.a) * retinaScaleX), + (int)((bFlipped ? top_line - bottom_line : bottom_line - top_line) * + retinaScaleY)); + top = top_line; + if (image_matrix.a < 0) { image_matrix.Scale(retinaScaleX, retinaScaleY); - pResBitmap = pBitmap->TransformTo(&image_matrix, left, top); - } - if (pResBitmap == NULL) { - return NULL; + left = FXSYS_round(image_matrix.e + image_matrix.a); + } else { + left = FXSYS_round(image_matrix.e); + } + } else { } - CFX_GlyphBitmap* pGlyph = new CFX_GlyphBitmap; - pGlyph->m_Left = left; - pGlyph->m_Top = -top; - pGlyph->m_Bitmap.TakeOver(pResBitmap); - delete pResBitmap; - return pGlyph; + } + if (pResBitmap == NULL) { + image_matrix.Scale(retinaScaleX, retinaScaleY); + pResBitmap = pBitmap->TransformTo(&image_matrix, left, top); + } + if (pResBitmap == NULL) { + return NULL; + } + CFX_GlyphBitmap* pGlyph = new CFX_GlyphBitmap; + pGlyph->m_Left = left; + pGlyph->m_Top = -top; + pGlyph->m_Bitmap.TakeOver(pResBitmap); + delete pResBitmap; + return pGlyph; } -void _CPDF_UniqueKeyGen::Generate(int count, ...) -{ - va_list argList; - va_start(argList, count); - for (int i = 0; i < count; i ++) { - int p = va_arg(argList, int); - ((FX_DWORD*)m_Key)[i] = p; - } - va_end(argList); - m_KeyLen = count * sizeof(FX_DWORD); +void _CPDF_UniqueKeyGen::Generate(int count, ...) { + va_list argList; + va_start(argList, count); + for (int i = 0; i < count; i++) { + int p = va_arg(argList, int); + ((FX_DWORD*)m_Key)[i] = p; + } + va_end(argList); + m_KeyLen = count * sizeof(FX_DWORD); } -FX_BOOL CPDF_RenderStatus::ProcessText(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device, CFX_PathData* pClippingPath) -{ - if(textobj->m_nChars == 0) { - return TRUE; - } - int text_render_mode = textobj->m_TextState.GetObject()->m_TextMode; - if (text_render_mode == 3) { - return TRUE; - } - CPDF_Font* pFont = textobj->m_TextState.GetFont(); - if (pFont->GetFontType() == PDFFONT_TYPE3) { - return ProcessType3Text(textobj, pObj2Device); - } - FX_BOOL bFill = FALSE, bStroke = FALSE, bClip = FALSE; - if (pClippingPath) { - bClip = TRUE; - } else { - switch (text_render_mode) { - case 0: - case 4: - bFill = TRUE; - break; - case 1: - case 5: - if (pFont->GetFace() == NULL && !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) { - bFill = TRUE; - } else { - bStroke = TRUE; - } - break; - case 2: - case 6: - if (pFont->GetFace() == NULL && !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) { - bFill = TRUE; - } else { - bFill = bStroke = TRUE; - } - break; - case 3: - case 7: - return TRUE; - default: - bFill = TRUE; - } - } - FX_ARGB stroke_argb = 0, fill_argb = 0; - FX_BOOL bPattern = FALSE; - if (bStroke) { - if (textobj->m_ColorState.GetStrokeColor()->IsPattern()) { - bPattern = TRUE; +FX_BOOL CPDF_RenderStatus::ProcessText(const CPDF_TextObject* textobj, + const CFX_AffineMatrix* pObj2Device, + CFX_PathData* pClippingPath) { + if (textobj->m_nChars == 0) { + return TRUE; + } + int text_render_mode = textobj->m_TextState.GetObject()->m_TextMode; + if (text_render_mode == 3) { + return TRUE; + } + CPDF_Font* pFont = textobj->m_TextState.GetFont(); + if (pFont->GetFontType() == PDFFONT_TYPE3) { + return ProcessType3Text(textobj, pObj2Device); + } + FX_BOOL bFill = FALSE, bStroke = FALSE, bClip = FALSE; + if (pClippingPath) { + bClip = TRUE; + } else { + switch (text_render_mode) { + case 0: + case 4: + bFill = TRUE; + break; + case 1: + case 5: + if (pFont->GetFace() == NULL && + !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) { + bFill = TRUE; } else { - stroke_argb = GetStrokeArgb(textobj); - } - } - if (bFill) { - if (textobj->m_ColorState.GetFillColor()->IsPattern()) { - bPattern = TRUE; + bStroke = TRUE; + } + break; + case 2: + case 6: + if (pFont->GetFace() == NULL && + !(pFont->GetSubstFont()->m_SubstFlags & FXFONT_SUBST_GLYPHPATH)) { + bFill = TRUE; } else { - fill_argb = GetFillArgb(textobj); + bFill = bStroke = TRUE; } - } - CFX_AffineMatrix text_matrix; - textobj->GetTextMatrix(&text_matrix); - if(IsAvailableMatrix(text_matrix) == FALSE) { - return TRUE; - } - FX_FLOAT font_size = textobj->m_TextState.GetFontSize(); - if (bPattern) { - DrawTextPathWithPattern(textobj, pObj2Device, pFont, font_size, &text_matrix, bFill, bStroke); + break; + case 3: + case 7: return TRUE; + default: + bFill = TRUE; + } + } + FX_ARGB stroke_argb = 0, fill_argb = 0; + FX_BOOL bPattern = FALSE; + if (bStroke) { + if (textobj->m_ColorState.GetStrokeColor()->IsPattern()) { + bPattern = TRUE; + } else { + stroke_argb = GetStrokeArgb(textobj); } - if (bClip || bStroke) { - const CFX_AffineMatrix* pDeviceMatrix = pObj2Device; - CFX_AffineMatrix device_matrix; - if (bStroke) { - const FX_FLOAT* pCTM = textobj->m_TextState.GetObject()->m_CTM; - if (pCTM[0] != 1.0f || pCTM[3] != 1.0f) { - CFX_AffineMatrix ctm(pCTM[0], pCTM[1], pCTM[2], pCTM[3], 0, 0); - text_matrix.ConcatInverse(ctm); - device_matrix.Copy(ctm); - device_matrix.Concat(*pObj2Device); - pDeviceMatrix = &device_matrix; - } - } - int flag = 0; - if (bStroke && bFill) { - flag |= FX_FILL_STROKE; - flag |= FX_STROKE_TEXT_MODE; - } - const CPDF_GeneralStateData* pGeneralData = ((CPDF_PageObject*)textobj)->m_GeneralState; - if (pGeneralData && pGeneralData->m_StrokeAdjust) { - flag |= FX_STROKE_ADJUST; - } - if (m_Options.m_Flags & RENDER_NOTEXTSMOOTH) { - flag |= FXFILL_NOPATHSMOOTH; - } - return CPDF_TextRenderer::DrawTextPath(m_pDevice, textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos, pFont, font_size, - &text_matrix, pDeviceMatrix, textobj->m_GraphState, fill_argb, stroke_argb, pClippingPath, flag); + } + if (bFill) { + if (textobj->m_ColorState.GetFillColor()->IsPattern()) { + bPattern = TRUE; + } else { + fill_argb = GetFillArgb(textobj); } - text_matrix.Concat(*pObj2Device); - return CPDF_TextRenderer::DrawNormalText(m_pDevice, textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos, pFont, font_size, - &text_matrix, fill_argb, &m_Options); + } + CFX_AffineMatrix text_matrix; + textobj->GetTextMatrix(&text_matrix); + if (IsAvailableMatrix(text_matrix) == FALSE) { + return TRUE; + } + FX_FLOAT font_size = textobj->m_TextState.GetFontSize(); + if (bPattern) { + DrawTextPathWithPattern(textobj, pObj2Device, pFont, font_size, + &text_matrix, bFill, bStroke); + return TRUE; + } + if (bClip || bStroke) { + const CFX_AffineMatrix* pDeviceMatrix = pObj2Device; + CFX_AffineMatrix device_matrix; + if (bStroke) { + const FX_FLOAT* pCTM = textobj->m_TextState.GetObject()->m_CTM; + if (pCTM[0] != 1.0f || pCTM[3] != 1.0f) { + CFX_AffineMatrix ctm(pCTM[0], pCTM[1], pCTM[2], pCTM[3], 0, 0); + text_matrix.ConcatInverse(ctm); + device_matrix.Copy(ctm); + device_matrix.Concat(*pObj2Device); + pDeviceMatrix = &device_matrix; + } + } + int flag = 0; + if (bStroke && bFill) { + flag |= FX_FILL_STROKE; + flag |= FX_STROKE_TEXT_MODE; + } + const CPDF_GeneralStateData* pGeneralData = + ((CPDF_PageObject*)textobj)->m_GeneralState; + if (pGeneralData && pGeneralData->m_StrokeAdjust) { + flag |= FX_STROKE_ADJUST; + } + if (m_Options.m_Flags & RENDER_NOTEXTSMOOTH) { + flag |= FXFILL_NOPATHSMOOTH; + } + return CPDF_TextRenderer::DrawTextPath( + m_pDevice, textobj->m_nChars, textobj->m_pCharCodes, + textobj->m_pCharPos, pFont, font_size, &text_matrix, pDeviceMatrix, + textobj->m_GraphState, fill_argb, stroke_argb, pClippingPath, flag); + } + text_matrix.Concat(*pObj2Device); + return CPDF_TextRenderer::DrawNormalText( + m_pDevice, textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos, + pFont, font_size, &text_matrix, fill_argb, &m_Options); } -CPDF_Type3Cache* CPDF_RenderStatus::GetCachedType3(CPDF_Type3Font* pFont) -{ - if (pFont->m_pDocument == NULL) { - return NULL; - } - pFont->m_pDocument->GetPageData()->GetFont(pFont->GetFontDict(), FALSE); - return pFont->m_pDocument->GetRenderData()->GetCachedType3(pFont); +CPDF_Type3Cache* CPDF_RenderStatus::GetCachedType3(CPDF_Type3Font* pFont) { + if (pFont->m_pDocument == NULL) { + return NULL; + } + pFont->m_pDocument->GetPageData()->GetFont(pFont->GetFontDict(), FALSE); + return pFont->m_pDocument->GetRenderData()->GetCachedType3(pFont); } -static void ReleaseCachedType3(CPDF_Type3Font* pFont) -{ - if (pFont->m_pDocument == NULL) { - return; - } - pFont->m_pDocument->GetRenderData()->ReleaseCachedType3(pFont); - pFont->m_pDocument->GetPageData()->ReleaseFont(pFont->GetFontDict()); +static void ReleaseCachedType3(CPDF_Type3Font* pFont) { + if (pFont->m_pDocument == NULL) { + return; + } + pFont->m_pDocument->GetRenderData()->ReleaseCachedType3(pFont); + pFont->m_pDocument->GetPageData()->ReleaseFont(pFont->GetFontDict()); } -FX_BOOL CPDF_Type3Char::LoadBitmap(CPDF_RenderContext* pContext) -{ - if (m_pBitmap != NULL || m_pForm == NULL) { - return TRUE; - } - if (m_pForm->CountObjects() == 1 && !m_bColored) { - CPDF_PageObject *pPageObj = m_pForm->GetObjectAt(m_pForm->GetFirstObjectPosition()); - if (pPageObj->m_Type == PDFPAGE_IMAGE) { - CPDF_ImageObject* pImage = (CPDF_ImageObject*)pPageObj; - m_ImageMatrix = pImage->m_Matrix; - const CFX_DIBSource* pSource = pImage->m_pImage->LoadDIBSource(); - if (pSource) { - m_pBitmap = pSource->Clone(); - delete pSource; - } - delete m_pForm; - m_pForm = NULL; - return TRUE; - } - } - return FALSE; +FX_BOOL CPDF_Type3Char::LoadBitmap(CPDF_RenderContext* pContext) { + if (m_pBitmap != NULL || m_pForm == NULL) { + return TRUE; + } + if (m_pForm->CountObjects() == 1 && !m_bColored) { + CPDF_PageObject* pPageObj = + m_pForm->GetObjectAt(m_pForm->GetFirstObjectPosition()); + if (pPageObj->m_Type == PDFPAGE_IMAGE) { + CPDF_ImageObject* pImage = (CPDF_ImageObject*)pPageObj; + m_ImageMatrix = pImage->m_Matrix; + const CFX_DIBSource* pSource = pImage->m_pImage->LoadDIBSource(); + if (pSource) { + m_pBitmap = pSource->Clone(); + delete pSource; + } + delete m_pForm; + m_pForm = NULL; + return TRUE; + } + } + return FALSE; } -class CPDF_RefType3Cache -{ -public: - CPDF_RefType3Cache(CPDF_Type3Font* pType3Font) - { - m_dwCount = 0; - m_pType3Font = pType3Font; - } - ~CPDF_RefType3Cache() - { - while(m_dwCount--) { - ReleaseCachedType3(m_pType3Font); - } - } - FX_DWORD m_dwCount; - CPDF_Type3Font* m_pType3Font; +class CPDF_RefType3Cache { + public: + CPDF_RefType3Cache(CPDF_Type3Font* pType3Font) { + m_dwCount = 0; + m_pType3Font = pType3Font; + } + ~CPDF_RefType3Cache() { + while (m_dwCount--) { + ReleaseCachedType3(m_pType3Font); + } + } + FX_DWORD m_dwCount; + CPDF_Type3Font* m_pType3Font; }; -FX_BOOL CPDF_RenderStatus::ProcessType3Text(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device) -{ - CPDF_Type3Font* pType3Font = textobj->m_TextState.GetFont()->GetType3Font(); - for (int j = 0; j < m_Type3FontCache.GetSize(); j++) - if ((CPDF_Type3Font*)m_Type3FontCache.GetAt(j) == pType3Font) { - return TRUE; - } - CFX_Matrix dCTM = m_pDevice->GetCTM(); - FX_FLOAT sa = FXSYS_fabs(dCTM.a); - FX_FLOAT sd = FXSYS_fabs(dCTM.d); - CFX_AffineMatrix text_matrix; - textobj->GetTextMatrix(&text_matrix); - CFX_AffineMatrix char_matrix = pType3Font->GetFontMatrix(); - FX_FLOAT font_size = textobj->m_TextState.GetFontSize(); - char_matrix.Scale(font_size, font_size); - FX_ARGB fill_argb = GetFillArgb(textobj, TRUE); - int fill_alpha = FXARGB_A(fill_argb); - int device_class = m_pDevice->GetDeviceClass(); - FXTEXT_GLYPHPOS* pGlyphAndPos = NULL; - if (device_class == FXDC_DISPLAY) { - pGlyphAndPos = FX_Alloc(FXTEXT_GLYPHPOS, textobj->m_nChars); - } else if (fill_alpha < 255) { - return FALSE; - } - CPDF_RefType3Cache refTypeCache(pType3Font); - FX_DWORD *pChars = textobj->m_pCharCodes; - if (textobj->m_nChars == 1) { - pChars = (FX_DWORD*)(&textobj->m_pCharCodes); - } - for (int iChar = 0; iChar < textobj->m_nChars; iChar ++) { - FX_DWORD charcode = pChars[iChar]; - if (charcode == (FX_DWORD) - 1) { - continue; - } - CPDF_Type3Char* pType3Char = pType3Font->LoadChar(charcode); - if (pType3Char == NULL) { +FX_BOOL CPDF_RenderStatus::ProcessType3Text( + const CPDF_TextObject* textobj, + const CFX_AffineMatrix* pObj2Device) { + CPDF_Type3Font* pType3Font = textobj->m_TextState.GetFont()->GetType3Font(); + for (int j = 0; j < m_Type3FontCache.GetSize(); j++) + if ((CPDF_Type3Font*)m_Type3FontCache.GetAt(j) == pType3Font) { + return TRUE; + } + CFX_Matrix dCTM = m_pDevice->GetCTM(); + FX_FLOAT sa = FXSYS_fabs(dCTM.a); + FX_FLOAT sd = FXSYS_fabs(dCTM.d); + CFX_AffineMatrix text_matrix; + textobj->GetTextMatrix(&text_matrix); + CFX_AffineMatrix char_matrix = pType3Font->GetFontMatrix(); + FX_FLOAT font_size = textobj->m_TextState.GetFontSize(); + char_matrix.Scale(font_size, font_size); + FX_ARGB fill_argb = GetFillArgb(textobj, TRUE); + int fill_alpha = FXARGB_A(fill_argb); + int device_class = m_pDevice->GetDeviceClass(); + FXTEXT_GLYPHPOS* pGlyphAndPos = NULL; + if (device_class == FXDC_DISPLAY) { + pGlyphAndPos = FX_Alloc(FXTEXT_GLYPHPOS, textobj->m_nChars); + } else if (fill_alpha < 255) { + return FALSE; + } + CPDF_RefType3Cache refTypeCache(pType3Font); + FX_DWORD* pChars = textobj->m_pCharCodes; + if (textobj->m_nChars == 1) { + pChars = (FX_DWORD*)(&textobj->m_pCharCodes); + } + for (int iChar = 0; iChar < textobj->m_nChars; iChar++) { + FX_DWORD charcode = pChars[iChar]; + if (charcode == (FX_DWORD)-1) { + continue; + } + CPDF_Type3Char* pType3Char = pType3Font->LoadChar(charcode); + if (pType3Char == NULL) { + continue; + } + CFX_AffineMatrix matrix = char_matrix; + matrix.e += iChar ? textobj->m_pCharPos[iChar - 1] : 0; + matrix.Concat(text_matrix); + matrix.Concat(*pObj2Device); + if (!pType3Char->LoadBitmap(m_pContext)) { + if (pGlyphAndPos) { + for (int i = 0; i < iChar; i++) { + FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[i]; + if (glyph.m_pGlyph == NULL) { continue; + } + m_pDevice->SetBitMask(&glyph.m_pGlyph->m_Bitmap, + glyph.m_OriginX + glyph.m_pGlyph->m_Left, + glyph.m_OriginY - glyph.m_pGlyph->m_Top, + fill_argb); } - CFX_AffineMatrix matrix = char_matrix; - matrix.e += iChar ? textobj->m_pCharPos[iChar - 1] : 0; - matrix.Concat(text_matrix); - matrix.Concat(*pObj2Device); - if (!pType3Char->LoadBitmap(m_pContext)) { - if (pGlyphAndPos) { - for (int i = 0; i < iChar; i ++) { - FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[i]; - if (glyph.m_pGlyph == NULL) { - continue; - } - m_pDevice->SetBitMask(&glyph.m_pGlyph->m_Bitmap, - glyph.m_OriginX + glyph.m_pGlyph->m_Left, - glyph.m_OriginY - glyph.m_pGlyph->m_Top, fill_argb); - } - FX_Free(pGlyphAndPos); - pGlyphAndPos = NULL; - } - CPDF_GraphicStates* pStates = CloneObjStates(textobj, FALSE); - CPDF_RenderOptions Options = m_Options; - Options.m_Flags |= RENDER_FORCE_HALFTONE | RENDER_RECT_AA; - Options.m_Flags &= ~RENDER_FORCE_DOWNSAMPLE; - CPDF_Dictionary* pFormResource = NULL; - if (pType3Char->m_pForm && pType3Char->m_pForm->m_pFormDict) { - pFormResource = pType3Char->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources")); - } - if (fill_alpha == 255) { - CPDF_RenderStatus status; - status.Initialize(m_pContext, m_pDevice, NULL, NULL, this, pStates, &Options, - pType3Char->m_pForm->m_Transparency, m_bDropObjects, pFormResource, FALSE, pType3Char, fill_argb); - status.m_Type3FontCache.Append(m_Type3FontCache); - status.m_Type3FontCache.Add(pType3Font); - m_pDevice->SaveState(); - status.RenderObjectList(pType3Char->m_pForm, &matrix); - m_pDevice->RestoreState(); - } else { - CFX_FloatRect rect_f = pType3Char->m_pForm->CalcBoundingBox(); - rect_f.Transform(&matrix); - FX_RECT rect = rect_f.GetOutterRect(); - CFX_FxgeDevice bitmap_device; - if (!bitmap_device.Create((int)(rect.Width() * sa), (int)(rect.Height() * sd), FXDIB_Argb)) { - return TRUE; - } - bitmap_device.GetBitmap()->Clear(0); - CPDF_RenderStatus status; - status.Initialize(m_pContext, &bitmap_device, NULL, NULL, this, pStates, &Options, - pType3Char->m_pForm->m_Transparency, m_bDropObjects, pFormResource, FALSE, pType3Char, fill_argb); - status.m_Type3FontCache.Append(m_Type3FontCache); - status.m_Type3FontCache.Add(pType3Font); - matrix.TranslateI(-rect.left, -rect.top); - matrix.Scale(sa, sd); - status.RenderObjectList(pType3Char->m_pForm, &matrix); - m_pDevice->SetDIBits(bitmap_device.GetBitmap(), rect.left, rect.top); - } - delete pStates; - } else if (pType3Char->m_pBitmap) { - if (device_class == FXDC_DISPLAY) { - CPDF_Type3Cache* pCache = GetCachedType3(pType3Font); - refTypeCache.m_dwCount++; - CFX_GlyphBitmap* pBitmap = pCache->LoadGlyph(charcode, &matrix, sa, sd); - if (pBitmap == NULL) { - continue; - } - int origin_x = FXSYS_round(matrix.e); - int origin_y = FXSYS_round(matrix.f); - if (pGlyphAndPos) { - pGlyphAndPos[iChar].m_pGlyph = pBitmap; - pGlyphAndPos[iChar].m_OriginX = origin_x; - pGlyphAndPos[iChar].m_OriginY = origin_y; - } else { - m_pDevice->SetBitMask(&pBitmap->m_Bitmap, origin_x + pBitmap->m_Left, origin_y - pBitmap->m_Top, fill_argb); - } - } else { - CFX_AffineMatrix image_matrix = pType3Char->m_ImageMatrix; - image_matrix.Concat(matrix); - CPDF_ImageRenderer renderer; - if (renderer.Start(this, pType3Char->m_pBitmap, fill_argb, 255, &image_matrix, 0, FALSE)) { - renderer.Continue(NULL); - } - if (!renderer.m_Result) { - return FALSE; - } - } - } - } - if (pGlyphAndPos) { - FX_RECT rect = FXGE_GetGlyphsBBox(pGlyphAndPos, textobj->m_nChars, 0, sa, sd); - CFX_DIBitmap bitmap; - if (!bitmap.Create((int)(rect.Width() * sa), (int)(rect.Height() * sd), FXDIB_8bppMask)) { - FX_Free(pGlyphAndPos); - return TRUE; - } - bitmap.Clear(0); - for (int iChar = 0; iChar < textobj->m_nChars; iChar ++) { - FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar]; - if (glyph.m_pGlyph == NULL) { - continue; - } - bitmap.TransferBitmap((int)((glyph.m_OriginX + glyph.m_pGlyph->m_Left - rect.left) * sa), - (int)((glyph.m_OriginY - glyph.m_pGlyph->m_Top - rect.top) * sd), - glyph.m_pGlyph->m_Bitmap.GetWidth(), glyph.m_pGlyph->m_Bitmap.GetHeight(), - &glyph.m_pGlyph->m_Bitmap, 0, 0); - } - m_pDevice->SetBitMask(&bitmap, rect.left, rect.top, fill_argb); FX_Free(pGlyphAndPos); - } - return TRUE; + pGlyphAndPos = NULL; + } + CPDF_GraphicStates* pStates = CloneObjStates(textobj, FALSE); + CPDF_RenderOptions Options = m_Options; + Options.m_Flags |= RENDER_FORCE_HALFTONE | RENDER_RECT_AA; + Options.m_Flags &= ~RENDER_FORCE_DOWNSAMPLE; + CPDF_Dictionary* pFormResource = NULL; + if (pType3Char->m_pForm && pType3Char->m_pForm->m_pFormDict) { + pFormResource = + pType3Char->m_pForm->m_pFormDict->GetDict(FX_BSTRC("Resources")); + } + if (fill_alpha == 255) { + CPDF_RenderStatus status; + status.Initialize(m_pContext, m_pDevice, NULL, NULL, this, pStates, + &Options, pType3Char->m_pForm->m_Transparency, + m_bDropObjects, pFormResource, FALSE, pType3Char, + fill_argb); + status.m_Type3FontCache.Append(m_Type3FontCache); + status.m_Type3FontCache.Add(pType3Font); + m_pDevice->SaveState(); + status.RenderObjectList(pType3Char->m_pForm, &matrix); + m_pDevice->RestoreState(); + } else { + CFX_FloatRect rect_f = pType3Char->m_pForm->CalcBoundingBox(); + rect_f.Transform(&matrix); + FX_RECT rect = rect_f.GetOutterRect(); + CFX_FxgeDevice bitmap_device; + if (!bitmap_device.Create((int)(rect.Width() * sa), + (int)(rect.Height() * sd), FXDIB_Argb)) { + return TRUE; + } + bitmap_device.GetBitmap()->Clear(0); + CPDF_RenderStatus status; + status.Initialize(m_pContext, &bitmap_device, NULL, NULL, this, pStates, + &Options, pType3Char->m_pForm->m_Transparency, + m_bDropObjects, pFormResource, FALSE, pType3Char, + fill_argb); + status.m_Type3FontCache.Append(m_Type3FontCache); + status.m_Type3FontCache.Add(pType3Font); + matrix.TranslateI(-rect.left, -rect.top); + matrix.Scale(sa, sd); + status.RenderObjectList(pType3Char->m_pForm, &matrix); + m_pDevice->SetDIBits(bitmap_device.GetBitmap(), rect.left, rect.top); + } + delete pStates; + } else if (pType3Char->m_pBitmap) { + if (device_class == FXDC_DISPLAY) { + CPDF_Type3Cache* pCache = GetCachedType3(pType3Font); + refTypeCache.m_dwCount++; + CFX_GlyphBitmap* pBitmap = pCache->LoadGlyph(charcode, &matrix, sa, sd); + if (pBitmap == NULL) { + continue; + } + int origin_x = FXSYS_round(matrix.e); + int origin_y = FXSYS_round(matrix.f); + if (pGlyphAndPos) { + pGlyphAndPos[iChar].m_pGlyph = pBitmap; + pGlyphAndPos[iChar].m_OriginX = origin_x; + pGlyphAndPos[iChar].m_OriginY = origin_y; + } else { + m_pDevice->SetBitMask(&pBitmap->m_Bitmap, origin_x + pBitmap->m_Left, + origin_y - pBitmap->m_Top, fill_argb); + } + } else { + CFX_AffineMatrix image_matrix = pType3Char->m_ImageMatrix; + image_matrix.Concat(matrix); + CPDF_ImageRenderer renderer; + if (renderer.Start(this, pType3Char->m_pBitmap, fill_argb, 255, + &image_matrix, 0, FALSE)) { + renderer.Continue(NULL); + } + if (!renderer.m_Result) { + return FALSE; + } + } + } + } + if (pGlyphAndPos) { + FX_RECT rect = + FXGE_GetGlyphsBBox(pGlyphAndPos, textobj->m_nChars, 0, sa, sd); + CFX_DIBitmap bitmap; + if (!bitmap.Create((int)(rect.Width() * sa), (int)(rect.Height() * sd), + FXDIB_8bppMask)) { + FX_Free(pGlyphAndPos); + return TRUE; + } + bitmap.Clear(0); + for (int iChar = 0; iChar < textobj->m_nChars; iChar++) { + FXTEXT_GLYPHPOS& glyph = pGlyphAndPos[iChar]; + if (glyph.m_pGlyph == NULL) { + continue; + } + bitmap.TransferBitmap( + (int)((glyph.m_OriginX + glyph.m_pGlyph->m_Left - rect.left) * sa), + (int)((glyph.m_OriginY - glyph.m_pGlyph->m_Top - rect.top) * sd), + glyph.m_pGlyph->m_Bitmap.GetWidth(), + glyph.m_pGlyph->m_Bitmap.GetHeight(), &glyph.m_pGlyph->m_Bitmap, 0, + 0); + } + m_pDevice->SetBitMask(&bitmap, rect.left, rect.top, fill_argb); + FX_Free(pGlyphAndPos); + } + return TRUE; } -class CPDF_CharPosList -{ -public: - CPDF_CharPosList(); - ~CPDF_CharPosList(); - void Load(int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, CPDF_Font* pFont, FX_FLOAT font_size); - FXTEXT_CHARPOS* m_pCharPos; - FX_DWORD m_nChars; +class CPDF_CharPosList { + public: + CPDF_CharPosList(); + ~CPDF_CharPosList(); + void Load(int nChars, + FX_DWORD* pCharCodes, + FX_FLOAT* pCharPos, + CPDF_Font* pFont, + FX_FLOAT font_size); + FXTEXT_CHARPOS* m_pCharPos; + FX_DWORD m_nChars; }; FX_FLOAT _CIDTransformToFloat(uint8_t ch); -CPDF_CharPosList::CPDF_CharPosList() -{ - m_pCharPos = NULL; +CPDF_CharPosList::CPDF_CharPosList() { + m_pCharPos = NULL; } -CPDF_CharPosList::~CPDF_CharPosList() -{ - if (m_pCharPos) { - FX_Free(m_pCharPos); - } +CPDF_CharPosList::~CPDF_CharPosList() { + if (m_pCharPos) { + FX_Free(m_pCharPos); + } } -void CPDF_CharPosList::Load(int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, CPDF_Font* pFont, - FX_FLOAT FontSize) -{ - m_pCharPos = FX_Alloc(FXTEXT_CHARPOS, nChars); - m_nChars = 0; - CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); - FX_BOOL bVertWriting = pCIDFont && pCIDFont->IsVertWriting(); - for (int iChar = 0; iChar < nChars; iChar ++) { - FX_DWORD CharCode = nChars == 1 ? (FX_DWORD)(uintptr_t)pCharCodes : pCharCodes[iChar]; - if (CharCode == (FX_DWORD) - 1) { - continue; - } - FX_BOOL bVert = FALSE; - FXTEXT_CHARPOS& charpos = m_pCharPos[m_nChars++]; - if (pCIDFont) { - charpos.m_bFontStyle = pCIDFont->IsFontStyleFromCharCode(CharCode); - } - charpos.m_GlyphIndex = pFont->GlyphFromCharCode(CharCode, &bVert); -#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ - charpos.m_ExtGID = pFont->GlyphFromCharCodeExt(CharCode); +void CPDF_CharPosList::Load(int nChars, + FX_DWORD* pCharCodes, + FX_FLOAT* pCharPos, + CPDF_Font* pFont, + FX_FLOAT FontSize) { + m_pCharPos = FX_Alloc(FXTEXT_CHARPOS, nChars); + m_nChars = 0; + CPDF_CIDFont* pCIDFont = pFont->GetCIDFont(); + FX_BOOL bVertWriting = pCIDFont && pCIDFont->IsVertWriting(); + for (int iChar = 0; iChar < nChars; iChar++) { + FX_DWORD CharCode = + nChars == 1 ? (FX_DWORD)(uintptr_t)pCharCodes : pCharCodes[iChar]; + if (CharCode == (FX_DWORD)-1) { + continue; + } + FX_BOOL bVert = FALSE; + FXTEXT_CHARPOS& charpos = m_pCharPos[m_nChars++]; + if (pCIDFont) { + charpos.m_bFontStyle = pCIDFont->IsFontStyleFromCharCode(CharCode); + } + charpos.m_GlyphIndex = pFont->GlyphFromCharCode(CharCode, &bVert); +#if _FXM_PLATFORM_ == _FXM_PLATFORM_APPLE_ + charpos.m_ExtGID = pFont->GlyphFromCharCodeExt(CharCode); #endif - if (!pFont->IsEmbedded() && pFont->GetFontType() != PDFFONT_CIDFONT) { - charpos.m_FontCharWidth = pFont->GetCharWidthF(CharCode); - } else { - charpos.m_FontCharWidth = 0; - } - charpos.m_OriginX = iChar ? pCharPos[iChar - 1] : 0; - charpos.m_OriginY = 0; - charpos.m_bGlyphAdjust = FALSE; - if (pCIDFont == NULL) { - continue; - } - FX_WORD CID = pCIDFont->CIDFromCharCode(CharCode); - if (bVertWriting) { - charpos.m_OriginY = charpos.m_OriginX; - charpos.m_OriginX = 0; - short vx, vy; - pCIDFont->GetVertOrigin(CID, vx, vy); - charpos.m_OriginX -= FontSize * vx / 1000; - charpos.m_OriginY -= FontSize * vy / 1000; - } - const uint8_t* pTransform = pCIDFont->GetCIDTransform(CID); - if (pTransform && !bVert) { - charpos.m_AdjustMatrix[0] = _CIDTransformToFloat(pTransform[0]); - charpos.m_AdjustMatrix[2] = _CIDTransformToFloat(pTransform[2]); - charpos.m_AdjustMatrix[1] = _CIDTransformToFloat(pTransform[1]); - charpos.m_AdjustMatrix[3] = _CIDTransformToFloat(pTransform[3]); - charpos.m_OriginX += _CIDTransformToFloat(pTransform[4]) * FontSize; - charpos.m_OriginY += _CIDTransformToFloat(pTransform[5]) * FontSize; - charpos.m_bGlyphAdjust = TRUE; - } - } + if (!pFont->IsEmbedded() && pFont->GetFontType() != PDFFONT_CIDFONT) { + charpos.m_FontCharWidth = pFont->GetCharWidthF(CharCode); + } else { + charpos.m_FontCharWidth = 0; + } + charpos.m_OriginX = iChar ? pCharPos[iChar - 1] : 0; + charpos.m_OriginY = 0; + charpos.m_bGlyphAdjust = FALSE; + if (pCIDFont == NULL) { + continue; + } + FX_WORD CID = pCIDFont->CIDFromCharCode(CharCode); + if (bVertWriting) { + charpos.m_OriginY = charpos.m_OriginX; + charpos.m_OriginX = 0; + short vx, vy; + pCIDFont->GetVertOrigin(CID, vx, vy); + charpos.m_OriginX -= FontSize * vx / 1000; + charpos.m_OriginY -= FontSize * vy / 1000; + } + const uint8_t* pTransform = pCIDFont->GetCIDTransform(CID); + if (pTransform && !bVert) { + charpos.m_AdjustMatrix[0] = _CIDTransformToFloat(pTransform[0]); + charpos.m_AdjustMatrix[2] = _CIDTransformToFloat(pTransform[2]); + charpos.m_AdjustMatrix[1] = _CIDTransformToFloat(pTransform[1]); + charpos.m_AdjustMatrix[3] = _CIDTransformToFloat(pTransform[3]); + charpos.m_OriginX += _CIDTransformToFloat(pTransform[4]) * FontSize; + charpos.m_OriginY += _CIDTransformToFloat(pTransform[5]) * FontSize; + charpos.m_bGlyphAdjust = TRUE; + } + } } -FX_BOOL CPDF_TextRenderer::DrawTextPath(CFX_RenderDevice* pDevice, int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, - CPDF_Font* pFont, FX_FLOAT font_size, - const CFX_AffineMatrix* pText2User, const CFX_AffineMatrix* pUser2Device, +FX_BOOL CPDF_TextRenderer::DrawTextPath(CFX_RenderDevice* pDevice, + int nChars, + FX_DWORD* pCharCodes, + FX_FLOAT* pCharPos, + CPDF_Font* pFont, + FX_FLOAT font_size, + const CFX_AffineMatrix* pText2User, + const CFX_AffineMatrix* pUser2Device, const CFX_GraphStateData* pGraphState, - FX_ARGB fill_argb, FX_ARGB stroke_argb, CFX_PathData* pClippingPath, int nFlag) -{ - CFX_FontCache* pCache = pFont->m_pDocument ? pFont->m_pDocument->GetRenderData()->GetFontCache() : NULL; - CPDF_CharPosList CharPosList; - CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); - return pDevice->DrawTextPath(CharPosList.m_nChars, CharPosList.m_pCharPos, - &pFont->m_Font, pCache, font_size, pText2User, pUser2Device, - pGraphState, fill_argb, stroke_argb, pClippingPath, nFlag); + FX_ARGB fill_argb, + FX_ARGB stroke_argb, + CFX_PathData* pClippingPath, + int nFlag) { + CFX_FontCache* pCache = + pFont->m_pDocument ? pFont->m_pDocument->GetRenderData()->GetFontCache() + : NULL; + CPDF_CharPosList CharPosList; + CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); + return pDevice->DrawTextPath(CharPosList.m_nChars, CharPosList.m_pCharPos, + &pFont->m_Font, pCache, font_size, pText2User, + pUser2Device, pGraphState, fill_argb, + stroke_argb, pClippingPath, nFlag); } -void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice, int left, int top, CPDF_Font* pFont, int height, - const CFX_ByteString& str, FX_ARGB argb) -{ - FX_RECT font_bbox; - pFont->GetFontBBox(font_bbox); - FX_FLOAT font_size = (FX_FLOAT)height * 1000.0f / (FX_FLOAT)(font_bbox.top - font_bbox.bottom); - FX_FLOAT origin_x = (FX_FLOAT)left; - FX_FLOAT origin_y = (FX_FLOAT)top + font_size * (FX_FLOAT)font_bbox.top / 1000.0f; - CFX_AffineMatrix matrix(1.0f, 0, 0, -1.0f, 0, 0); - DrawTextString(pDevice, origin_x, origin_y, pFont, font_size, &matrix, str, argb); +void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice, + int left, + int top, + CPDF_Font* pFont, + int height, + const CFX_ByteString& str, + FX_ARGB argb) { + FX_RECT font_bbox; + pFont->GetFontBBox(font_bbox); + FX_FLOAT font_size = + (FX_FLOAT)height * 1000.0f / (FX_FLOAT)(font_bbox.top - font_bbox.bottom); + FX_FLOAT origin_x = (FX_FLOAT)left; + FX_FLOAT origin_y = + (FX_FLOAT)top + font_size * (FX_FLOAT)font_bbox.top / 1000.0f; + CFX_AffineMatrix matrix(1.0f, 0, 0, -1.0f, 0, 0); + DrawTextString(pDevice, origin_x, origin_y, pFont, font_size, &matrix, str, + argb); } -void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice, FX_FLOAT origin_x, FX_FLOAT origin_y, CPDF_Font* pFont, FX_FLOAT font_size, - const CFX_AffineMatrix* pMatrix, const CFX_ByteString& str, FX_ARGB fill_argb, - FX_ARGB stroke_argb, const CFX_GraphStateData* pGraphState, const CPDF_RenderOptions* pOptions) -{ - int nChars = pFont->CountChar(str, str.GetLength()); - if (nChars == 0) { - return; - } - FX_DWORD charcode; - int offset = 0; - FX_DWORD* pCharCodes; - FX_FLOAT* pCharPos; - if (nChars == 1) { - charcode = pFont->GetNextChar(str, str.GetLength(), offset); - pCharCodes = (FX_DWORD*)(uintptr_t)charcode; - pCharPos = NULL; - } else { - pCharCodes = FX_Alloc(FX_DWORD, nChars); - pCharPos = FX_Alloc(FX_FLOAT, nChars - 1); - FX_FLOAT cur_pos = 0; - for (int i = 0; i < nChars; i ++) { - pCharCodes[i] = pFont->GetNextChar(str, str.GetLength(), offset); - if (i) { - pCharPos[i - 1] = cur_pos; - } - cur_pos += pFont->GetCharWidthF(pCharCodes[i]) * font_size / 1000; - } - } - CFX_AffineMatrix matrix; - if (pMatrix) { - matrix = *pMatrix; - } - matrix.e = origin_x; - matrix.f = origin_y; - if (pFont->GetFontType() == PDFFONT_TYPE3) - ; - else if (stroke_argb == 0) { - DrawNormalText(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size, &matrix, fill_argb, pOptions); - } else - DrawTextPath(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size, &matrix, NULL, pGraphState, - fill_argb, stroke_argb, NULL); - if (nChars > 1) { - FX_Free(pCharCodes); - FX_Free(pCharPos); - } +void CPDF_TextRenderer::DrawTextString(CFX_RenderDevice* pDevice, + FX_FLOAT origin_x, + FX_FLOAT origin_y, + CPDF_Font* pFont, + FX_FLOAT font_size, + const CFX_AffineMatrix* pMatrix, + const CFX_ByteString& str, + FX_ARGB fill_argb, + FX_ARGB stroke_argb, + const CFX_GraphStateData* pGraphState, + const CPDF_RenderOptions* pOptions) { + int nChars = pFont->CountChar(str, str.GetLength()); + if (nChars == 0) { + return; + } + FX_DWORD charcode; + int offset = 0; + FX_DWORD* pCharCodes; + FX_FLOAT* pCharPos; + if (nChars == 1) { + charcode = pFont->GetNextChar(str, str.GetLength(), offset); + pCharCodes = (FX_DWORD*)(uintptr_t)charcode; + pCharPos = NULL; + } else { + pCharCodes = FX_Alloc(FX_DWORD, nChars); + pCharPos = FX_Alloc(FX_FLOAT, nChars - 1); + FX_FLOAT cur_pos = 0; + for (int i = 0; i < nChars; i++) { + pCharCodes[i] = pFont->GetNextChar(str, str.GetLength(), offset); + if (i) { + pCharPos[i - 1] = cur_pos; + } + cur_pos += pFont->GetCharWidthF(pCharCodes[i]) * font_size / 1000; + } + } + CFX_AffineMatrix matrix; + if (pMatrix) { + matrix = *pMatrix; + } + matrix.e = origin_x; + matrix.f = origin_y; + if (pFont->GetFontType() == PDFFONT_TYPE3) + ; + else if (stroke_argb == 0) { + DrawNormalText(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size, + &matrix, fill_argb, pOptions); + } else + DrawTextPath(pDevice, nChars, pCharCodes, pCharPos, pFont, font_size, + &matrix, NULL, pGraphState, fill_argb, stroke_argb, NULL); + if (nChars > 1) { + FX_Free(pCharCodes); + FX_Free(pCharPos); + } } -FX_BOOL CPDF_TextRenderer::DrawNormalText(CFX_RenderDevice* pDevice, int nChars, FX_DWORD* pCharCodes, FX_FLOAT* pCharPos, - CPDF_Font* pFont, FX_FLOAT font_size, - const CFX_AffineMatrix* pText2Device, - FX_ARGB fill_argb, const CPDF_RenderOptions* pOptions) -{ - CFX_FontCache* pCache = pFont->m_pDocument ? pFont->m_pDocument->GetRenderData()->GetFontCache() : NULL; - CPDF_CharPosList CharPosList; - CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); - int FXGE_flags = 0; - if (pOptions) { - FX_DWORD dwFlags = pOptions->m_Flags; - if (dwFlags & RENDER_CLEARTYPE) { - FXGE_flags |= FXTEXT_CLEARTYPE; - if (dwFlags & RENDER_BGR_STRIPE) { - FXGE_flags |= FXTEXT_BGR_STRIPE; - } - } - if (dwFlags & RENDER_NOTEXTSMOOTH) { - FXGE_flags |= FXTEXT_NOSMOOTH; - } - if (dwFlags & RENDER_PRINTGRAPHICTEXT) { - FXGE_flags |= FXTEXT_PRINTGRAPHICTEXT; - } - if (dwFlags & RENDER_NO_NATIVETEXT) { - FXGE_flags |= FXTEXT_NO_NATIVETEXT; - } - if (dwFlags & RENDER_PRINTIMAGETEXT) { - FXGE_flags |= FXTEXT_PRINTIMAGETEXT; - } - } else { - FXGE_flags = FXTEXT_CLEARTYPE; - } - if (pFont->GetFontType() & PDFFONT_CIDFONT) { - FXGE_flags |= FXFONT_CIDFONT; - } - return pDevice->DrawNormalText(CharPosList.m_nChars, CharPosList.m_pCharPos, &pFont->m_Font, pCache, font_size, pText2Device, fill_argb, FXGE_flags); +FX_BOOL CPDF_TextRenderer::DrawNormalText(CFX_RenderDevice* pDevice, + int nChars, + FX_DWORD* pCharCodes, + FX_FLOAT* pCharPos, + CPDF_Font* pFont, + FX_FLOAT font_size, + const CFX_AffineMatrix* pText2Device, + FX_ARGB fill_argb, + const CPDF_RenderOptions* pOptions) { + CFX_FontCache* pCache = + pFont->m_pDocument ? pFont->m_pDocument->GetRenderData()->GetFontCache() + : NULL; + CPDF_CharPosList CharPosList; + CharPosList.Load(nChars, pCharCodes, pCharPos, pFont, font_size); + int FXGE_flags = 0; + if (pOptions) { + FX_DWORD dwFlags = pOptions->m_Flags; + if (dwFlags & RENDER_CLEARTYPE) { + FXGE_flags |= FXTEXT_CLEARTYPE; + if (dwFlags & RENDER_BGR_STRIPE) { + FXGE_flags |= FXTEXT_BGR_STRIPE; + } + } + if (dwFlags & RENDER_NOTEXTSMOOTH) { + FXGE_flags |= FXTEXT_NOSMOOTH; + } + if (dwFlags & RENDER_PRINTGRAPHICTEXT) { + FXGE_flags |= FXTEXT_PRINTGRAPHICTEXT; + } + if (dwFlags & RENDER_NO_NATIVETEXT) { + FXGE_flags |= FXTEXT_NO_NATIVETEXT; + } + if (dwFlags & RENDER_PRINTIMAGETEXT) { + FXGE_flags |= FXTEXT_PRINTIMAGETEXT; + } + } else { + FXGE_flags = FXTEXT_CLEARTYPE; + } + if (pFont->GetFontType() & PDFFONT_CIDFONT) { + FXGE_flags |= FXFONT_CIDFONT; + } + return pDevice->DrawNormalText(CharPosList.m_nChars, CharPosList.m_pCharPos, + &pFont->m_Font, pCache, font_size, + pText2Device, fill_argb, FXGE_flags); } -void CPDF_RenderStatus::DrawTextPathWithPattern(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device, - CPDF_Font* pFont, FX_FLOAT font_size, - const CFX_AffineMatrix* pTextMatrix, FX_BOOL bFill, FX_BOOL bStroke) -{ - if (!bStroke) { - CPDF_PathObject path; - CPDF_TextObject* pCopy = new CPDF_TextObject; - pCopy->Copy(textobj); - path.m_bStroke = FALSE; - path.m_FillType = FXFILL_WINDING; - path.m_ClipPath.AppendTexts(&pCopy, 1); - path.m_ColorState = textobj->m_ColorState; - path.m_Path.New()->AppendRect(textobj->m_Left, textobj->m_Bottom, textobj->m_Right, textobj->m_Top); - path.m_Left = textobj->m_Left; - path.m_Bottom = textobj->m_Bottom; - path.m_Right = textobj->m_Right; - path.m_Top = textobj->m_Top; - RenderSingleObject(&path, pObj2Device); - return; - } - CFX_FontCache* pCache; - if (pFont->m_pDocument) { - pCache = pFont->m_pDocument->GetRenderData()->GetFontCache(); - } else { - pCache = CFX_GEModule::Get()->GetFontCache(); - } - CFX_FaceCache* pFaceCache = pCache->GetCachedFace(&pFont->m_Font); - FX_FONTCACHE_DEFINE(pCache, &pFont->m_Font); - CPDF_CharPosList CharPosList; - CharPosList.Load(textobj->m_nChars, textobj->m_pCharCodes, textobj->m_pCharPos, pFont, font_size); - for (FX_DWORD i = 0; i < CharPosList.m_nChars; i ++) { - FXTEXT_CHARPOS& charpos = CharPosList.m_pCharPos[i]; - const CFX_PathData* pPath = pFaceCache->LoadGlyphPath(&pFont->m_Font, charpos.m_GlyphIndex, - charpos.m_FontCharWidth); - if (pPath == NULL) { - continue; - } - CPDF_PathObject path; - path.m_GraphState = textobj->m_GraphState; - path.m_ColorState = textobj->m_ColorState; - CFX_AffineMatrix matrix; - if (charpos.m_bGlyphAdjust) - matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], - charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); - matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, charpos.m_OriginY); - path.m_Path.New()->Append(pPath, &matrix); - path.m_Matrix = *pTextMatrix; - path.m_bStroke = bStroke; - path.m_FillType = bFill ? FXFILL_WINDING : 0; - path.CalcBoundingBox(); - ProcessPath(&path, pObj2Device); - } +void CPDF_RenderStatus::DrawTextPathWithPattern( + const CPDF_TextObject* textobj, + const CFX_AffineMatrix* pObj2Device, + CPDF_Font* pFont, + FX_FLOAT font_size, + const CFX_AffineMatrix* pTextMatrix, + FX_BOOL bFill, + FX_BOOL bStroke) { + if (!bStroke) { + CPDF_PathObject path; + CPDF_TextObject* pCopy = new CPDF_TextObject; + pCopy->Copy(textobj); + path.m_bStroke = FALSE; + path.m_FillType = FXFILL_WINDING; + path.m_ClipPath.AppendTexts(&pCopy, 1); + path.m_ColorState = textobj->m_ColorState; + path.m_Path.New()->AppendRect(textobj->m_Left, textobj->m_Bottom, + textobj->m_Right, textobj->m_Top); + path.m_Left = textobj->m_Left; + path.m_Bottom = textobj->m_Bottom; + path.m_Right = textobj->m_Right; + path.m_Top = textobj->m_Top; + RenderSingleObject(&path, pObj2Device); + return; + } + CFX_FontCache* pCache; + if (pFont->m_pDocument) { + pCache = pFont->m_pDocument->GetRenderData()->GetFontCache(); + } else { + pCache = CFX_GEModule::Get()->GetFontCache(); + } + CFX_FaceCache* pFaceCache = pCache->GetCachedFace(&pFont->m_Font); + FX_FONTCACHE_DEFINE(pCache, &pFont->m_Font); + CPDF_CharPosList CharPosList; + CharPosList.Load(textobj->m_nChars, textobj->m_pCharCodes, + textobj->m_pCharPos, pFont, font_size); + for (FX_DWORD i = 0; i < CharPosList.m_nChars; i++) { + FXTEXT_CHARPOS& charpos = CharPosList.m_pCharPos[i]; + const CFX_PathData* pPath = pFaceCache->LoadGlyphPath( + &pFont->m_Font, charpos.m_GlyphIndex, charpos.m_FontCharWidth); + if (pPath == NULL) { + continue; + } + CPDF_PathObject path; + path.m_GraphState = textobj->m_GraphState; + path.m_ColorState = textobj->m_ColorState; + CFX_AffineMatrix matrix; + if (charpos.m_bGlyphAdjust) + matrix.Set(charpos.m_AdjustMatrix[0], charpos.m_AdjustMatrix[1], + charpos.m_AdjustMatrix[2], charpos.m_AdjustMatrix[3], 0, 0); + matrix.Concat(font_size, 0, 0, font_size, charpos.m_OriginX, + charpos.m_OriginY); + path.m_Path.New()->Append(pPath, &matrix); + path.m_Matrix = *pTextMatrix; + path.m_bStroke = bStroke; + path.m_FillType = bFill ? FXFILL_WINDING : 0; + path.CalcBoundingBox(); + ProcessPath(&path, pObj2Device); + } } -CFX_PathData* CPDF_Font::LoadGlyphPath(FX_DWORD charcode, int dest_width) -{ - int glyph_index = GlyphFromCharCode(charcode); - if (m_Font.m_Face == NULL) { - return NULL; - } - return m_Font.LoadGlyphPath(glyph_index, dest_width); +CFX_PathData* CPDF_Font::LoadGlyphPath(FX_DWORD charcode, int dest_width) { + int glyph_index = GlyphFromCharCode(charcode); + if (m_Font.m_Face == NULL) { + return NULL; + } + return m_Font.LoadGlyphPath(glyph_index, dest_width); } diff --git a/core/src/fpdfapi/fpdf_render/render_int.h b/core/src/fpdfapi/fpdf_render/render_int.h index e5fb831a63..d6b314d853 100644 --- a/core/src/fpdfapi/fpdf_render/render_int.h +++ b/core/src/fpdfapi/fpdf_render/render_int.h @@ -13,463 +13,582 @@ #include "../../../include/fpdfapi/fpdf_pageobj.h" class CPDF_QuickStretcher; -#define TYPE3_MAX_BLUES 16 -class CPDF_Type3Glyphs -{ -public: - CPDF_Type3Glyphs() - { - m_GlyphMap.InitHashTable(253); - m_TopBlueCount = m_BottomBlueCount = 0; - } - ~CPDF_Type3Glyphs(); - CFX_MapPtrToPtr m_GlyphMap; - void AdjustBlue(FX_FLOAT top, FX_FLOAT bottom, int& top_line, int& bottom_line); +#define TYPE3_MAX_BLUES 16 +class CPDF_Type3Glyphs { + public: + CPDF_Type3Glyphs() { + m_GlyphMap.InitHashTable(253); + m_TopBlueCount = m_BottomBlueCount = 0; + } + ~CPDF_Type3Glyphs(); + CFX_MapPtrToPtr m_GlyphMap; + void AdjustBlue(FX_FLOAT top, + FX_FLOAT bottom, + int& top_line, + int& bottom_line); - int m_TopBlue[TYPE3_MAX_BLUES], m_BottomBlue[TYPE3_MAX_BLUES]; - int m_TopBlueCount, m_BottomBlueCount; + int m_TopBlue[TYPE3_MAX_BLUES], m_BottomBlue[TYPE3_MAX_BLUES]; + int m_TopBlueCount, m_BottomBlueCount; }; class CFX_GlyphBitmap; -class CPDF_Type3Cache -{ -public: - CPDF_Type3Cache(CPDF_Type3Font* pFont) - { - m_pFont = pFont; - } - ~CPDF_Type3Cache(); - CFX_GlyphBitmap* LoadGlyph(FX_DWORD charcode, const CFX_AffineMatrix* pMatrix, FX_FLOAT retinaScaleX = 1.0f, FX_FLOAT retinaScaleY = 1.0f); -protected: - CFX_GlyphBitmap* RenderGlyph(CPDF_Type3Glyphs* pSize, FX_DWORD charcode, const CFX_AffineMatrix* pMatrix, FX_FLOAT retinaScaleX = 1.0f, FX_FLOAT retinaScaleY = 1.0f); - CPDF_Type3Font* m_pFont; - CFX_MapByteStringToPtr m_SizeMap; +class CPDF_Type3Cache { + public: + CPDF_Type3Cache(CPDF_Type3Font* pFont) { m_pFont = pFont; } + ~CPDF_Type3Cache(); + CFX_GlyphBitmap* LoadGlyph(FX_DWORD charcode, + const CFX_AffineMatrix* pMatrix, + FX_FLOAT retinaScaleX = 1.0f, + FX_FLOAT retinaScaleY = 1.0f); + + protected: + CFX_GlyphBitmap* RenderGlyph(CPDF_Type3Glyphs* pSize, + FX_DWORD charcode, + const CFX_AffineMatrix* pMatrix, + FX_FLOAT retinaScaleX = 1.0f, + FX_FLOAT retinaScaleY = 1.0f); + CPDF_Type3Font* m_pFont; + CFX_MapByteStringToPtr m_SizeMap; }; -class CPDF_TransferFunc -{ -public: - CPDF_Document* m_pPDFDoc; - uint8_t m_Samples[256 * 3]; - FX_BOOL m_bIdentity; +class CPDF_TransferFunc { + public: + CPDF_Document* m_pPDFDoc; + uint8_t m_Samples[256 * 3]; + FX_BOOL m_bIdentity; - CFX_DIBSource* TranslateImage(const CFX_DIBSource* pSrc, FX_BOOL bAutoDropSrc); - FX_COLORREF TranslateColor(FX_COLORREF src); + CFX_DIBSource* TranslateImage(const CFX_DIBSource* pSrc, + FX_BOOL bAutoDropSrc); + FX_COLORREF TranslateColor(FX_COLORREF src); }; -class CPDF_DocRenderData -{ -public: - CPDF_DocRenderData(CPDF_Document* pPDFDoc = NULL); - ~CPDF_DocRenderData(); - CPDF_Type3Cache* GetCachedType3(CPDF_Type3Font* pFont); - CPDF_TransferFunc* GetTransferFunc(CPDF_Object* pObj); - CFX_FontCache* GetFontCache() - { - return m_pFontCache; - } - void Clear(FX_BOOL bRelease = FALSE); - void ReleaseCachedType3(CPDF_Type3Font* pFont); - void ReleaseTransferFunc(CPDF_Object* pObj); -private: - using CPDF_Type3CacheMap = - std::map<CPDF_Font*, CPDF_CountedObject<CPDF_Type3Cache>*>; - using CPDF_TransferFuncMap = - std::map<CPDF_Object*, CPDF_CountedObject<CPDF_TransferFunc>*> ; +class CPDF_DocRenderData { + public: + CPDF_DocRenderData(CPDF_Document* pPDFDoc = NULL); + ~CPDF_DocRenderData(); + CPDF_Type3Cache* GetCachedType3(CPDF_Type3Font* pFont); + CPDF_TransferFunc* GetTransferFunc(CPDF_Object* pObj); + CFX_FontCache* GetFontCache() { return m_pFontCache; } + void Clear(FX_BOOL bRelease = FALSE); + void ReleaseCachedType3(CPDF_Type3Font* pFont); + void ReleaseTransferFunc(CPDF_Object* pObj); + + private: + using CPDF_Type3CacheMap = + std::map<CPDF_Font*, CPDF_CountedObject<CPDF_Type3Cache>*>; + using CPDF_TransferFuncMap = + std::map<CPDF_Object*, CPDF_CountedObject<CPDF_TransferFunc>*>; - CPDF_Document* m_pPDFDoc; - CFX_FontCache* m_pFontCache; - CPDF_Type3CacheMap m_Type3FaceMap; - CPDF_TransferFuncMap m_TransferFuncMap; + CPDF_Document* m_pPDFDoc; + CFX_FontCache* m_pFontCache; + CPDF_Type3CacheMap m_Type3FaceMap; + CPDF_TransferFuncMap m_TransferFuncMap; }; struct _PDF_RenderItem { -public: - CPDF_PageObjects* m_pObjectList; - CFX_AffineMatrix m_Matrix; + public: + CPDF_PageObjects* m_pObjectList; + CFX_AffineMatrix m_Matrix; }; -typedef CFX_ArrayTemplate<_PDF_RenderItem> CPDF_RenderLayer; -class IPDF_ObjectRenderer -{ -public: - static IPDF_ObjectRenderer* Create(int type); - virtual ~IPDF_ObjectRenderer() {} - virtual FX_BOOL Start(CPDF_RenderStatus* pRenderStatus, const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStdCS, int blendType = FXDIB_BLEND_NORMAL) = 0; - virtual FX_BOOL Continue(IFX_Pause* pPause) = 0; - FX_BOOL m_Result; +typedef CFX_ArrayTemplate<_PDF_RenderItem> CPDF_RenderLayer; +class IPDF_ObjectRenderer { + public: + static IPDF_ObjectRenderer* Create(int type); + virtual ~IPDF_ObjectRenderer() {} + virtual FX_BOOL Start(CPDF_RenderStatus* pRenderStatus, + const CPDF_PageObject* pObj, + const CFX_AffineMatrix* pObj2Device, + FX_BOOL bStdCS, + int blendType = FXDIB_BLEND_NORMAL) = 0; + virtual FX_BOOL Continue(IFX_Pause* pPause) = 0; + FX_BOOL m_Result; }; -class CPDF_RenderStatus -{ -public: - CPDF_RenderStatus(); - ~CPDF_RenderStatus(); - FX_BOOL Initialize(class CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, const CFX_AffineMatrix* pDeviceMatrix, - const CPDF_PageObject* pStopObj, const CPDF_RenderStatus* pParentStatus, - const CPDF_GraphicStates* pInitialStates, const CPDF_RenderOptions* pOptions, - int transparency, FX_BOOL bDropObjects, CPDF_Dictionary* pFormResource = NULL, - FX_BOOL bStdCS = FALSE, CPDF_Type3Char* pType3Char = NULL, FX_ARGB fill_color = 0, - FX_DWORD GroupFamily = 0, FX_BOOL bLoadMask = FALSE); - void RenderObjectList(const CPDF_PageObjects* pObjs, const CFX_AffineMatrix* pObj2Device); - void RenderSingleObject(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device); - FX_BOOL ContinueSingleObject(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, IFX_Pause* pPause); - CPDF_RenderOptions m_Options; - CPDF_Dictionary* m_pFormResource; - CPDF_Dictionary* m_pPageResource; - CFX_PtrArray m_Type3FontCache; - CPDF_RenderContext* GetContext() - { - return m_pContext; - } -protected: - friend class CPDF_ImageRenderer; - friend class CPDF_RenderContext; - void ProcessClipPath(CPDF_ClipPath ClipPath, const CFX_AffineMatrix* pObj2Device); - void DrawClipPath(CPDF_ClipPath ClipPath, const CFX_AffineMatrix* pObj2Device); - FX_BOOL ProcessTransparency(const CPDF_PageObject* PageObj, const CFX_AffineMatrix* pObj2Device); - void ProcessObjectNoClip(const CPDF_PageObject* PageObj, const CFX_AffineMatrix* pObj2Device); - void DrawObjWithBackground(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device); - FX_BOOL DrawObjWithBlend(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device); - FX_BOOL ProcessPath(CPDF_PathObject* pPathObj, const CFX_AffineMatrix* pObj2Device); - void ProcessPathPattern(CPDF_PathObject* pPathObj, const CFX_AffineMatrix* pObj2Device, int& filltype, FX_BOOL& bStroke); - void DrawPathWithPattern(CPDF_PathObject* pPathObj, const CFX_AffineMatrix* pObj2Device, CPDF_Color* pColor, FX_BOOL bStroke); - void DrawTilingPattern(CPDF_TilingPattern* pPattern, CPDF_PageObject* pPageObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStroke); - void DrawShadingPattern(CPDF_ShadingPattern* pPattern, CPDF_PageObject* pPageObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStroke); - FX_BOOL SelectClipPath(CPDF_PathObject* pPathObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStroke); - FX_BOOL ProcessImage(CPDF_ImageObject* pImageObj, const CFX_AffineMatrix* pObj2Device); - FX_BOOL OutputBitmapAlpha(CPDF_ImageObject* pImageObj, const CFX_AffineMatrix* pImage2Device); - FX_BOOL OutputImage(CPDF_ImageObject* pImageObj, const CFX_AffineMatrix* pImage2Device); - FX_BOOL OutputDIBSource(const CFX_DIBSource* pOutputBitmap, FX_ARGB fill_argb, int bitmap_alpha, - const CFX_AffineMatrix* pImage2Device, CPDF_ImageCache* pImageCache, FX_DWORD flags); - void CompositeDIBitmap(CFX_DIBitmap* pDIBitmap, int left, int top, FX_ARGB mask_argb, - int bitmap_alpha, int blend_mode, int bIsolated); - FX_BOOL ProcessShading(CPDF_ShadingObject* pShadingObj, const CFX_AffineMatrix* pObj2Device); - void DrawShading(CPDF_ShadingPattern* pPattern, CFX_AffineMatrix* pMatrix, FX_RECT& clip_rect, - int alpha, FX_BOOL bAlphaMode); - FX_BOOL ProcessType3Text(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device); - FX_BOOL ProcessText(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device, CFX_PathData* pClippingPath); - void DrawTextPathWithPattern(const CPDF_TextObject* textobj, const CFX_AffineMatrix* pObj2Device, - CPDF_Font* pFont, FX_FLOAT font_size, - const CFX_AffineMatrix* pTextMatrix, FX_BOOL bFill, FX_BOOL bStroke); - FX_BOOL ProcessForm(CPDF_FormObject* pFormObj, const CFX_AffineMatrix* pObj2Device); - CFX_DIBitmap* GetBackdrop(const CPDF_PageObject* pObj, const FX_RECT& rect, int& left, int& top, - FX_BOOL bBackAlphaRequired); - CFX_DIBitmap* LoadSMask(CPDF_Dictionary* pSMaskDict, FX_RECT* pClipRect, const CFX_AffineMatrix* pMatrix); - void Init(CPDF_RenderContext* pParent); - static class CPDF_Type3Cache* GetCachedType3(CPDF_Type3Font* pFont); - static CPDF_GraphicStates* CloneObjStates(const CPDF_GraphicStates* pPathObj, FX_BOOL bStroke); - CPDF_TransferFunc* GetTransferFunc(CPDF_Object* pObject) const; - FX_ARGB GetFillArgb(const CPDF_PageObject* pObj, FX_BOOL bType3 = FALSE) const; - FX_ARGB GetStrokeArgb(const CPDF_PageObject* pObj) const; - CPDF_RenderContext* m_pContext; - FX_BOOL m_bStopped; - void DitherObjectArea(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device); - FX_BOOL GetObjectClippedRect(const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bLogical, FX_RECT &rect) const; - void GetScaledMatrix(CFX_Matrix &matrix) const; +class CPDF_RenderStatus { + public: + CPDF_RenderStatus(); + ~CPDF_RenderStatus(); + FX_BOOL Initialize(class CPDF_RenderContext* pContext, + CFX_RenderDevice* pDevice, + const CFX_AffineMatrix* pDeviceMatrix, + const CPDF_PageObject* pStopObj, + const CPDF_RenderStatus* pParentStatus, + const CPDF_GraphicStates* pInitialStates, + const CPDF_RenderOptions* pOptions, + int transparency, + FX_BOOL bDropObjects, + CPDF_Dictionary* pFormResource = NULL, + FX_BOOL bStdCS = FALSE, + CPDF_Type3Char* pType3Char = NULL, + FX_ARGB fill_color = 0, + FX_DWORD GroupFamily = 0, + FX_BOOL bLoadMask = FALSE); + void RenderObjectList(const CPDF_PageObjects* pObjs, + const CFX_AffineMatrix* pObj2Device); + void RenderSingleObject(const CPDF_PageObject* pObj, + const CFX_AffineMatrix* pObj2Device); + FX_BOOL ContinueSingleObject(const CPDF_PageObject* pObj, + const CFX_AffineMatrix* pObj2Device, + IFX_Pause* pPause); + CPDF_RenderOptions m_Options; + CPDF_Dictionary* m_pFormResource; + CPDF_Dictionary* m_pPageResource; + CFX_PtrArray m_Type3FontCache; + CPDF_RenderContext* GetContext() { return m_pContext; } + + protected: + friend class CPDF_ImageRenderer; + friend class CPDF_RenderContext; + void ProcessClipPath(CPDF_ClipPath ClipPath, + const CFX_AffineMatrix* pObj2Device); + void DrawClipPath(CPDF_ClipPath ClipPath, + const CFX_AffineMatrix* pObj2Device); + FX_BOOL ProcessTransparency(const CPDF_PageObject* PageObj, + const CFX_AffineMatrix* pObj2Device); + void ProcessObjectNoClip(const CPDF_PageObject* PageObj, + const CFX_AffineMatrix* pObj2Device); + void DrawObjWithBackground(const CPDF_PageObject* pObj, + const CFX_AffineMatrix* pObj2Device); + FX_BOOL DrawObjWithBlend(const CPDF_PageObject* pObj, + const CFX_AffineMatrix* pObj2Device); + FX_BOOL ProcessPath(CPDF_PathObject* pPathObj, + const CFX_AffineMatrix* pObj2Device); + void ProcessPathPattern(CPDF_PathObject* pPathObj, + const CFX_AffineMatrix* pObj2Device, + int& filltype, + FX_BOOL& bStroke); + void DrawPathWithPattern(CPDF_PathObject* pPathObj, + const CFX_AffineMatrix* pObj2Device, + CPDF_Color* pColor, + FX_BOOL bStroke); + void DrawTilingPattern(CPDF_TilingPattern* pPattern, + CPDF_PageObject* pPageObj, + const CFX_AffineMatrix* pObj2Device, + FX_BOOL bStroke); + void DrawShadingPattern(CPDF_ShadingPattern* pPattern, + CPDF_PageObject* pPageObj, + const CFX_AffineMatrix* pObj2Device, + FX_BOOL bStroke); + FX_BOOL SelectClipPath(CPDF_PathObject* pPathObj, + const CFX_AffineMatrix* pObj2Device, + FX_BOOL bStroke); + FX_BOOL ProcessImage(CPDF_ImageObject* pImageObj, + const CFX_AffineMatrix* pObj2Device); + FX_BOOL OutputBitmapAlpha(CPDF_ImageObject* pImageObj, + const CFX_AffineMatrix* pImage2Device); + FX_BOOL OutputImage(CPDF_ImageObject* pImageObj, + const CFX_AffineMatrix* pImage2Device); + FX_BOOL OutputDIBSource(const CFX_DIBSource* pOutputBitmap, + FX_ARGB fill_argb, + int bitmap_alpha, + const CFX_AffineMatrix* pImage2Device, + CPDF_ImageCache* pImageCache, + FX_DWORD flags); + void CompositeDIBitmap(CFX_DIBitmap* pDIBitmap, + int left, + int top, + FX_ARGB mask_argb, + int bitmap_alpha, + int blend_mode, + int bIsolated); + FX_BOOL ProcessShading(CPDF_ShadingObject* pShadingObj, + const CFX_AffineMatrix* pObj2Device); + void DrawShading(CPDF_ShadingPattern* pPattern, + CFX_AffineMatrix* pMatrix, + FX_RECT& clip_rect, + int alpha, + FX_BOOL bAlphaMode); + FX_BOOL ProcessType3Text(const CPDF_TextObject* textobj, + const CFX_AffineMatrix* pObj2Device); + FX_BOOL ProcessText(const CPDF_TextObject* textobj, + const CFX_AffineMatrix* pObj2Device, + CFX_PathData* pClippingPath); + void DrawTextPathWithPattern(const CPDF_TextObject* textobj, + const CFX_AffineMatrix* pObj2Device, + CPDF_Font* pFont, + FX_FLOAT font_size, + const CFX_AffineMatrix* pTextMatrix, + FX_BOOL bFill, + FX_BOOL bStroke); + FX_BOOL ProcessForm(CPDF_FormObject* pFormObj, + const CFX_AffineMatrix* pObj2Device); + CFX_DIBitmap* GetBackdrop(const CPDF_PageObject* pObj, + const FX_RECT& rect, + int& left, + int& top, + FX_BOOL bBackAlphaRequired); + CFX_DIBitmap* LoadSMask(CPDF_Dictionary* pSMaskDict, + FX_RECT* pClipRect, + const CFX_AffineMatrix* pMatrix); + void Init(CPDF_RenderContext* pParent); + static class CPDF_Type3Cache* GetCachedType3(CPDF_Type3Font* pFont); + static CPDF_GraphicStates* CloneObjStates(const CPDF_GraphicStates* pPathObj, + FX_BOOL bStroke); + CPDF_TransferFunc* GetTransferFunc(CPDF_Object* pObject) const; + FX_ARGB GetFillArgb(const CPDF_PageObject* pObj, + FX_BOOL bType3 = FALSE) const; + FX_ARGB GetStrokeArgb(const CPDF_PageObject* pObj) const; + CPDF_RenderContext* m_pContext; + FX_BOOL m_bStopped; + void DitherObjectArea(const CPDF_PageObject* pObj, + const CFX_AffineMatrix* pObj2Device); + FX_BOOL GetObjectClippedRect(const CPDF_PageObject* pObj, + const CFX_AffineMatrix* pObj2Device, + FX_BOOL bLogical, + FX_RECT& rect) const; + void GetScaledMatrix(CFX_Matrix& matrix) const; -protected: - static const int kRenderMaxRecursionDepth = 64; - static int s_CurrentRecursionDepth; + protected: + static const int kRenderMaxRecursionDepth = 64; + static int s_CurrentRecursionDepth; - CFX_RenderDevice* m_pDevice; - CFX_AffineMatrix m_DeviceMatrix; - CPDF_ClipPath m_LastClipPath; - const CPDF_PageObject* m_pCurObj; - const CPDF_PageObject* m_pStopObj; - CPDF_GraphicStates m_InitialStates; - int m_HalftoneLimit; - IPDF_ObjectRenderer* m_pObjectRenderer; - FX_BOOL m_bPrint; - int m_Transparency; - int m_DitherBits; - FX_BOOL m_bDropObjects; - FX_BOOL m_bStdCS; - FX_DWORD m_GroupFamily; - FX_BOOL m_bLoadMask; - CPDF_Type3Char * m_pType3Char; - FX_ARGB m_T3FillColor; - int m_curBlend; + CFX_RenderDevice* m_pDevice; + CFX_AffineMatrix m_DeviceMatrix; + CPDF_ClipPath m_LastClipPath; + const CPDF_PageObject* m_pCurObj; + const CPDF_PageObject* m_pStopObj; + CPDF_GraphicStates m_InitialStates; + int m_HalftoneLimit; + IPDF_ObjectRenderer* m_pObjectRenderer; + FX_BOOL m_bPrint; + int m_Transparency; + int m_DitherBits; + FX_BOOL m_bDropObjects; + FX_BOOL m_bStdCS; + FX_DWORD m_GroupFamily; + FX_BOOL m_bLoadMask; + CPDF_Type3Char* m_pType3Char; + FX_ARGB m_T3FillColor; + int m_curBlend; }; -class CPDF_ImageLoader -{ -public: - CPDF_ImageLoader() - { - m_pBitmap = NULL; - m_pMask = NULL; - m_MatteColor = 0; - m_bCached = FALSE; - m_nDownsampleWidth = 0; - m_nDownsampleHeight = 0; - } +class CPDF_ImageLoader { + public: + CPDF_ImageLoader() { + m_pBitmap = NULL; + m_pMask = NULL; + m_MatteColor = 0; + m_bCached = FALSE; + m_nDownsampleWidth = 0; + m_nDownsampleHeight = 0; + } - FX_BOOL Load(const CPDF_ImageObject* pImage, CPDF_PageRenderCache* pCache, FX_BOOL bStdCS = FALSE, FX_DWORD GroupFamily = 0, FX_BOOL bLoadMask = FALSE, CPDF_RenderStatus* pRenderStatus = NULL); + FX_BOOL Load(const CPDF_ImageObject* pImage, + CPDF_PageRenderCache* pCache, + FX_BOOL bStdCS = FALSE, + FX_DWORD GroupFamily = 0, + FX_BOOL bLoadMask = FALSE, + CPDF_RenderStatus* pRenderStatus = NULL); - FX_BOOL StartLoadImage(const CPDF_ImageObject* pImage, CPDF_PageRenderCache* pCache, void*& LoadHandle, FX_BOOL bStdCS = FALSE, FX_DWORD GroupFamily = 0, FX_BOOL bLoadMask = FALSE, CPDF_RenderStatus* pRenderStatus = NULL, int32_t nDownsampleWidth = 0, int32_t nDownsampleHeight = 0); - FX_BOOL Continue(void* LoadHandle, IFX_Pause* pPause); - ~CPDF_ImageLoader(); - CFX_DIBSource* m_pBitmap; - CFX_DIBSource* m_pMask; - FX_DWORD m_MatteColor; - FX_BOOL m_bCached; -protected: - int32_t m_nDownsampleWidth; - int32_t m_nDownsampleHeight; + FX_BOOL StartLoadImage(const CPDF_ImageObject* pImage, + CPDF_PageRenderCache* pCache, + void*& LoadHandle, + FX_BOOL bStdCS = FALSE, + FX_DWORD GroupFamily = 0, + FX_BOOL bLoadMask = FALSE, + CPDF_RenderStatus* pRenderStatus = NULL, + int32_t nDownsampleWidth = 0, + int32_t nDownsampleHeight = 0); + FX_BOOL Continue(void* LoadHandle, IFX_Pause* pPause); + ~CPDF_ImageLoader(); + CFX_DIBSource* m_pBitmap; + CFX_DIBSource* m_pMask; + FX_DWORD m_MatteColor; + FX_BOOL m_bCached; + + protected: + int32_t m_nDownsampleWidth; + int32_t m_nDownsampleHeight; }; -class CPDF_ProgressiveImageLoaderHandle -{ -public: - CPDF_ProgressiveImageLoaderHandle(); - ~CPDF_ProgressiveImageLoaderHandle(); +class CPDF_ProgressiveImageLoaderHandle { + public: + CPDF_ProgressiveImageLoaderHandle(); + ~CPDF_ProgressiveImageLoaderHandle(); + + FX_BOOL Start(CPDF_ImageLoader* pImageLoader, + const CPDF_ImageObject* pImage, + CPDF_PageRenderCache* pCache, + FX_BOOL bStdCS = FALSE, + FX_DWORD GroupFamily = 0, + FX_BOOL bLoadMask = FALSE, + CPDF_RenderStatus* pRenderStatus = NULL, + int32_t nDownsampleWidth = 0, + int32_t nDownsampleHeight = 0); + FX_BOOL Continue(IFX_Pause* pPause); - FX_BOOL Start(CPDF_ImageLoader* pImageLoader, const CPDF_ImageObject* pImage, CPDF_PageRenderCache* pCache, FX_BOOL bStdCS = FALSE, FX_DWORD GroupFamily = 0, FX_BOOL bLoadMask = FALSE, CPDF_RenderStatus* pRenderStatus = NULL, int32_t nDownsampleWidth = 0, int32_t nDownsampleHeight = 0); - FX_BOOL Continue(IFX_Pause* pPause); -protected: - CPDF_ImageLoader* m_pImageLoader; - CPDF_PageRenderCache* m_pCache; - CPDF_ImageObject* m_pImage; - int32_t m_nDownsampleWidth; - int32_t m_nDownsampleHeight; + protected: + CPDF_ImageLoader* m_pImageLoader; + CPDF_PageRenderCache* m_pCache; + CPDF_ImageObject* m_pImage; + int32_t m_nDownsampleWidth; + int32_t m_nDownsampleHeight; }; class CFX_ImageTransformer; -class CPDF_ImageRenderer : public IPDF_ObjectRenderer -{ -public: - CPDF_ImageRenderer(); - ~CPDF_ImageRenderer(); - FX_BOOL Start(CPDF_RenderStatus* pStatus, const CPDF_PageObject* pObj, const CFX_AffineMatrix* pObj2Device, FX_BOOL bStdCS, int blendType = FXDIB_BLEND_NORMAL); - FX_BOOL Start(CPDF_RenderStatus* pStatus, const CFX_DIBSource* pDIBSource, FX_ARGB bitmap_argb, - int bitmap_alpha, const CFX_AffineMatrix* pImage2Device, FX_DWORD flags, FX_BOOL bStdCS, int blendType = FXDIB_BLEND_NORMAL); - FX_BOOL Continue(IFX_Pause* pPause); -protected: - CPDF_RenderStatus* m_pRenderStatus; - CPDF_ImageObject* m_pImageObject; - int m_Status; - const CFX_AffineMatrix* m_pObj2Device; - CFX_AffineMatrix m_ImageMatrix; - CPDF_ImageLoader m_Loader; - const CFX_DIBSource* m_pDIBSource; - CFX_DIBitmap* m_pClone; - int m_BitmapAlpha; - FX_BOOL m_bPatternColor; - CPDF_Pattern* m_pPattern; - FX_ARGB m_FillArgb; - FX_DWORD m_Flags; - CPDF_QuickStretcher* m_pQuickStretcher; - CFX_ImageTransformer* m_pTransformer; - void* m_DeviceHandle; - void* m_LoadHandle; - FX_BOOL m_bStdCS; - int m_BlendType; - FX_BOOL StartBitmapAlpha(); - FX_BOOL StartDIBSource(); - FX_BOOL StartRenderDIBSource(); - FX_BOOL StartLoadDIBSource(); - FX_BOOL DrawMaskedImage(); - FX_BOOL DrawPatternImage(const CFX_Matrix* pObj2Device); +class CPDF_ImageRenderer : public IPDF_ObjectRenderer { + public: + CPDF_ImageRenderer(); + ~CPDF_ImageRenderer(); + FX_BOOL Start(CPDF_RenderStatus* pStatus, + const CPDF_PageObject* pObj, + const CFX_AffineMatrix* pObj2Device, + FX_BOOL bStdCS, + int blendType = FXDIB_BLEND_NORMAL); + FX_BOOL Start(CPDF_RenderStatus* pStatus, + const CFX_DIBSource* pDIBSource, + FX_ARGB bitmap_argb, + int bitmap_alpha, + const CFX_AffineMatrix* pImage2Device, + FX_DWORD flags, + FX_BOOL bStdCS, + int blendType = FXDIB_BLEND_NORMAL); + FX_BOOL Continue(IFX_Pause* pPause); + + protected: + CPDF_RenderStatus* m_pRenderStatus; + CPDF_ImageObject* m_pImageObject; + int m_Status; + const CFX_AffineMatrix* m_pObj2Device; + CFX_AffineMatrix m_ImageMatrix; + CPDF_ImageLoader m_Loader; + const CFX_DIBSource* m_pDIBSource; + CFX_DIBitmap* m_pClone; + int m_BitmapAlpha; + FX_BOOL m_bPatternColor; + CPDF_Pattern* m_pPattern; + FX_ARGB m_FillArgb; + FX_DWORD m_Flags; + CPDF_QuickStretcher* m_pQuickStretcher; + CFX_ImageTransformer* m_pTransformer; + void* m_DeviceHandle; + void* m_LoadHandle; + FX_BOOL m_bStdCS; + int m_BlendType; + FX_BOOL StartBitmapAlpha(); + FX_BOOL StartDIBSource(); + FX_BOOL StartRenderDIBSource(); + FX_BOOL StartLoadDIBSource(); + FX_BOOL DrawMaskedImage(); + FX_BOOL DrawPatternImage(const CFX_Matrix* pObj2Device); }; -class CPDF_ScaledRenderBuffer -{ -public: - CPDF_ScaledRenderBuffer(); - ~CPDF_ScaledRenderBuffer(); - FX_BOOL Initialize(CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, FX_RECT* pRect, - const CPDF_PageObject* pObj, const CPDF_RenderOptions *pOptions = NULL, int max_dpi = 0); - CFX_RenderDevice* GetDevice() - { - return m_pBitmapDevice ? m_pBitmapDevice : m_pDevice; - } - CFX_AffineMatrix* GetMatrix() - { - return &m_Matrix; - } - void OutputToDevice(); -private: - CFX_RenderDevice* m_pDevice; - CPDF_RenderContext* m_pContext; - FX_RECT m_Rect; - const CPDF_PageObject* m_pObject; - CFX_FxgeDevice* m_pBitmapDevice; - CFX_AffineMatrix m_Matrix; +class CPDF_ScaledRenderBuffer { + public: + CPDF_ScaledRenderBuffer(); + ~CPDF_ScaledRenderBuffer(); + FX_BOOL Initialize(CPDF_RenderContext* pContext, + CFX_RenderDevice* pDevice, + FX_RECT* pRect, + const CPDF_PageObject* pObj, + const CPDF_RenderOptions* pOptions = NULL, + int max_dpi = 0); + CFX_RenderDevice* GetDevice() { + return m_pBitmapDevice ? m_pBitmapDevice : m_pDevice; + } + CFX_AffineMatrix* GetMatrix() { return &m_Matrix; } + void OutputToDevice(); + + private: + CFX_RenderDevice* m_pDevice; + CPDF_RenderContext* m_pContext; + FX_RECT m_Rect; + const CPDF_PageObject* m_pObject; + CFX_FxgeDevice* m_pBitmapDevice; + CFX_AffineMatrix m_Matrix; }; class ICodec_ScanlineDecoder; -class CPDF_QuickStretcher -{ -public: - CPDF_QuickStretcher(); - ~CPDF_QuickStretcher(); - FX_BOOL Start(CPDF_ImageObject* pImageObj, CFX_AffineMatrix* pImage2Device, const FX_RECT* pClipBox); - FX_BOOL Continue(IFX_Pause* pPause); - CFX_DIBitmap* m_pBitmap; - int m_ResultLeft, m_ResultTop, m_ClipLeft, m_ClipTop; - int m_DestWidth, m_DestHeight, m_ResultWidth, m_ResultHeight; - int m_Bpp, m_SrcWidth, m_SrcHeight; - FX_BOOL m_bFlipX, m_bFlipY; - CPDF_ColorSpace* m_pCS; - ICodec_ScanlineDecoder* m_pDecoder; - CPDF_StreamAcc m_StreamAcc; - int m_LineIndex; +class CPDF_QuickStretcher { + public: + CPDF_QuickStretcher(); + ~CPDF_QuickStretcher(); + FX_BOOL Start(CPDF_ImageObject* pImageObj, + CFX_AffineMatrix* pImage2Device, + const FX_RECT* pClipBox); + FX_BOOL Continue(IFX_Pause* pPause); + CFX_DIBitmap* m_pBitmap; + int m_ResultLeft, m_ResultTop, m_ClipLeft, m_ClipTop; + int m_DestWidth, m_DestHeight, m_ResultWidth, m_ResultHeight; + int m_Bpp, m_SrcWidth, m_SrcHeight; + FX_BOOL m_bFlipX, m_bFlipY; + CPDF_ColorSpace* m_pCS; + ICodec_ScanlineDecoder* m_pDecoder; + CPDF_StreamAcc m_StreamAcc; + int m_LineIndex; }; -class CPDF_DeviceBuffer -{ -public: - CPDF_DeviceBuffer(); - ~CPDF_DeviceBuffer(); - FX_BOOL Initialize(CPDF_RenderContext* pContext, CFX_RenderDevice* pDevice, FX_RECT* pRect, - const CPDF_PageObject* pObj, int max_dpi = 0); - void OutputToDevice(); - CFX_DIBitmap* GetBitmap() const - { - return m_pBitmap; - } - const CFX_AffineMatrix* GetMatrix() const - { - return &m_Matrix; - } -private: - CFX_RenderDevice* m_pDevice; - CPDF_RenderContext* m_pContext; - FX_RECT m_Rect; - const CPDF_PageObject* m_pObject; - CFX_DIBitmap* m_pBitmap; - CFX_AffineMatrix m_Matrix; +class CPDF_DeviceBuffer { + public: + CPDF_DeviceBuffer(); + ~CPDF_DeviceBuffer(); + FX_BOOL Initialize(CPDF_RenderContext* pContext, + CFX_RenderDevice* pDevice, + FX_RECT* pRect, + const CPDF_PageObject* pObj, + int max_dpi = 0); + void OutputToDevice(); + CFX_DIBitmap* GetBitmap() const { return m_pBitmap; } + const CFX_AffineMatrix* GetMatrix() const { return &m_Matrix; } + + private: + CFX_RenderDevice* m_pDevice; + CPDF_RenderContext* m_pContext; + FX_RECT m_Rect; + const CPDF_PageObject* m_pObject; + CFX_DIBitmap* m_pBitmap; + CFX_AffineMatrix m_Matrix; }; -class CPDF_ImageCache -{ -public: - CPDF_ImageCache(CPDF_Document* pDoc, CPDF_Stream* pStream); - ~CPDF_ImageCache(); - void ClearImageData(); - void Reset(const CFX_DIBitmap* pBitmap); - FX_BOOL GetCachedBitmap(CFX_DIBSource*& pBitmap, CFX_DIBSource*& pMask, FX_DWORD& MatteColor, CPDF_Dictionary* pPageResources, - FX_BOOL bStdCS = FALSE, FX_DWORD GroupFamily = 0, FX_BOOL bLoadMask = FALSE, - CPDF_RenderStatus* pRenderStatus = NULL, int32_t downsampleWidth = 0, int32_t downsampleHeight = 0); - FX_DWORD EstimateSize() const - { - return m_dwCacheSize; - } - FX_DWORD GetTimeCount() const - { - return m_dwTimeCount; - } - CPDF_Stream* GetStream() const - { - return m_pStream; - } - void SetTimeCount(FX_DWORD dwTimeCount) - { - m_dwTimeCount = dwTimeCount; - } - int m_dwTimeCount; -public: - int StartGetCachedBitmap(CPDF_Dictionary* pFormResources, CPDF_Dictionary* pPageResources, - FX_BOOL bStdCS = FALSE, FX_DWORD GroupFamily = 0, - FX_BOOL bLoadMask = FALSE, CPDF_RenderStatus* pRenderStatus = NULL, int32_t downsampleWidth = 0, int32_t downsampleHeight = 0); - int Continue(IFX_Pause* pPause); - int ContinueGetCachedBitmap(); - CFX_DIBSource* DetachBitmap(); - CFX_DIBSource* DetachMask(); - CFX_DIBSource* m_pCurBitmap; - CFX_DIBSource* m_pCurMask; - FX_DWORD m_MatteColor; - CPDF_RenderStatus* m_pRenderStatus; -protected: - CPDF_Document* m_pDocument; - CPDF_Stream* m_pStream; - CFX_DIBSource* m_pCachedBitmap; - CFX_DIBSource* m_pCachedMask; - FX_DWORD m_dwCacheSize; - void CalcSize(); +class CPDF_ImageCache { + public: + CPDF_ImageCache(CPDF_Document* pDoc, CPDF_Stream* pStream); + ~CPDF_ImageCache(); + void ClearImageData(); + void Reset(const CFX_DIBitmap* pBitmap); + FX_BOOL GetCachedBitmap(CFX_DIBSource*& pBitmap, + CFX_DIBSource*& pMask, + FX_DWORD& MatteColor, + CPDF_Dictionary* pPageResources, + FX_BOOL bStdCS = FALSE, + FX_DWORD GroupFamily = 0, + FX_BOOL bLoadMask = FALSE, + CPDF_RenderStatus* pRenderStatus = NULL, + int32_t downsampleWidth = 0, + int32_t downsampleHeight = 0); + FX_DWORD EstimateSize() const { return m_dwCacheSize; } + FX_DWORD GetTimeCount() const { return m_dwTimeCount; } + CPDF_Stream* GetStream() const { return m_pStream; } + void SetTimeCount(FX_DWORD dwTimeCount) { m_dwTimeCount = dwTimeCount; } + int m_dwTimeCount; + + public: + int StartGetCachedBitmap(CPDF_Dictionary* pFormResources, + CPDF_Dictionary* pPageResources, + FX_BOOL bStdCS = FALSE, + FX_DWORD GroupFamily = 0, + FX_BOOL bLoadMask = FALSE, + CPDF_RenderStatus* pRenderStatus = NULL, + int32_t downsampleWidth = 0, + int32_t downsampleHeight = 0); + int Continue(IFX_Pause* pPause); + int ContinueGetCachedBitmap(); + CFX_DIBSource* DetachBitmap(); + CFX_DIBSource* DetachMask(); + CFX_DIBSource* m_pCurBitmap; + CFX_DIBSource* m_pCurMask; + FX_DWORD m_MatteColor; + CPDF_RenderStatus* m_pRenderStatus; + + protected: + CPDF_Document* m_pDocument; + CPDF_Stream* m_pStream; + CFX_DIBSource* m_pCachedBitmap; + CFX_DIBSource* m_pCachedMask; + FX_DWORD m_dwCacheSize; + void CalcSize(); }; typedef struct { - FX_FLOAT m_DecodeMin; - FX_FLOAT m_DecodeStep; - int m_ColorKeyMin; - int m_ColorKeyMax; + FX_FLOAT m_DecodeMin; + FX_FLOAT m_DecodeStep; + int m_ColorKeyMin; + int m_ColorKeyMax; } DIB_COMP_DATA; -class CPDF_DIBSource : public CFX_DIBSource -{ -public: - CPDF_DIBSource(); - virtual ~CPDF_DIBSource(); - FX_BOOL Load(CPDF_Document* pDoc, const CPDF_Stream* pStream, - CPDF_DIBSource** ppMask, FX_DWORD* pMatteColor, - CPDF_Dictionary* pFormResources, CPDF_Dictionary* pPageResources, - FX_BOOL bStdCS = FALSE, FX_DWORD GroupFamily = 0, FX_BOOL bLoadMask = FALSE); - virtual FX_BOOL SkipToScanline(int line, IFX_Pause* pPause) const; - virtual uint8_t* GetBuffer() const; - virtual const uint8_t* GetScanline(int line) const; - virtual void DownSampleScanline(int line, uint8_t* dest_scan, int dest_bpp, - int dest_width, FX_BOOL bFlipX, int clip_left, int clip_width) const; - virtual void SetDownSampleSize(int dest_width, int dest_height) const; - CFX_DIBitmap* GetBitmap() const; - void ReleaseBitmap(CFX_DIBitmap*) const; - void ClearImageData(); -public: - int StartLoadDIBSource(CPDF_Document* pDoc, const CPDF_Stream* pStream, FX_BOOL bHasMask, - CPDF_Dictionary* pFormResources, CPDF_Dictionary* pPageResources, - FX_BOOL bStdCS = FALSE, FX_DWORD GroupFamily = 0, FX_BOOL bLoadMask = FALSE); - int ContinueLoadDIBSource(IFX_Pause* pPause); - int StratLoadMask(); - int StartLoadMaskDIB(); - int ContinueLoadMaskDIB(IFX_Pause* pPause); - int ContinueToLoadMask(); - CPDF_DIBSource* DetachMask(); - CPDF_DIBSource* m_pMask; - FX_DWORD m_MatteColor; - void* m_pJbig2Context; - CPDF_StreamAcc* m_pGlobalStream; - FX_BOOL m_bStdCS; - int m_Status; - CPDF_Object* m_pMaskStream; - FX_BOOL m_bHasMask; -protected: - FX_BOOL LoadColorInfo(CPDF_Dictionary* pFormResources, CPDF_Dictionary* pPageResources); - DIB_COMP_DATA* GetDecodeAndMaskArray(FX_BOOL& bDefaultDecode, FX_BOOL& bColorKey); - CPDF_DIBSource* LoadMask(FX_DWORD& MatteColor); - CPDF_DIBSource* LoadMaskDIB(CPDF_Stream* pMask); - void LoadJpxBitmap(); - void LoadPalette(); - int CreateDecoder(); - void TranslateScanline24bpp(uint8_t* dest_scan, const uint8_t* src_scan) const; - void ValidateDictParam(); - CPDF_Document* m_pDocument; - const CPDF_Stream* m_pStream; - CPDF_StreamAcc* m_pStreamAcc; - const CPDF_Dictionary* m_pDict; - CPDF_ColorSpace* m_pColorSpace; - FX_DWORD m_Family; - FX_DWORD m_bpc; - FX_DWORD m_bpc_orig; - FX_DWORD m_nComponents; - FX_DWORD m_GroupFamily; - FX_BOOL m_bLoadMask; - FX_BOOL m_bDefaultDecode; - FX_BOOL m_bImageMask; - FX_BOOL m_bDoBpcCheck; - FX_BOOL m_bColorKey; - DIB_COMP_DATA* m_pCompData; - uint8_t* m_pLineBuf; - uint8_t* m_pMaskedLine; - nonstd::unique_ptr<CFX_DIBitmap> m_pCachedBitmap; - ICodec_ScanlineDecoder* m_pDecoder; +class CPDF_DIBSource : public CFX_DIBSource { + public: + CPDF_DIBSource(); + virtual ~CPDF_DIBSource(); + FX_BOOL Load(CPDF_Document* pDoc, + const CPDF_Stream* pStream, + CPDF_DIBSource** ppMask, + FX_DWORD* pMatteColor, + CPDF_Dictionary* pFormResources, + CPDF_Dictionary* pPageResources, + FX_BOOL bStdCS = FALSE, + FX_DWORD GroupFamily = 0, + FX_BOOL bLoadMask = FALSE); + virtual FX_BOOL SkipToScanline(int line, IFX_Pause* pPause) const; + virtual uint8_t* GetBuffer() const; + virtual const uint8_t* GetScanline(int line) const; + virtual void DownSampleScanline(int line, + uint8_t* dest_scan, + int dest_bpp, + int dest_width, + FX_BOOL bFlipX, + int clip_left, + int clip_width) const; + virtual void SetDownSampleSize(int dest_width, int dest_height) const; + CFX_DIBitmap* GetBitmap() const; + void ReleaseBitmap(CFX_DIBitmap*) const; + void ClearImageData(); + + public: + int StartLoadDIBSource(CPDF_Document* pDoc, + const CPDF_Stream* pStream, + FX_BOOL bHasMask, + CPDF_Dictionary* pFormResources, + CPDF_Dictionary* pPageResources, + FX_BOOL bStdCS = FALSE, + FX_DWORD GroupFamily = 0, + FX_BOOL bLoadMask = FALSE); + int ContinueLoadDIBSource(IFX_Pause* pPause); + int StratLoadMask(); + int StartLoadMaskDIB(); + int ContinueLoadMaskDIB(IFX_Pause* pPause); + int ContinueToLoadMask(); + CPDF_DIBSource* DetachMask(); + CPDF_DIBSource* m_pMask; + FX_DWORD m_MatteColor; + void* m_pJbig2Context; + CPDF_StreamAcc* m_pGlobalStream; + FX_BOOL m_bStdCS; + int m_Status; + CPDF_Object* m_pMaskStream; + FX_BOOL m_bHasMask; + + protected: + FX_BOOL LoadColorInfo(CPDF_Dictionary* pFormResources, + CPDF_Dictionary* pPageResources); + DIB_COMP_DATA* GetDecodeAndMaskArray(FX_BOOL& bDefaultDecode, + FX_BOOL& bColorKey); + CPDF_DIBSource* LoadMask(FX_DWORD& MatteColor); + CPDF_DIBSource* LoadMaskDIB(CPDF_Stream* pMask); + void LoadJpxBitmap(); + void LoadPalette(); + int CreateDecoder(); + void TranslateScanline24bpp(uint8_t* dest_scan, + const uint8_t* src_scan) const; + void ValidateDictParam(); + CPDF_Document* m_pDocument; + const CPDF_Stream* m_pStream; + CPDF_StreamAcc* m_pStreamAcc; + const CPDF_Dictionary* m_pDict; + CPDF_ColorSpace* m_pColorSpace; + FX_DWORD m_Family; + FX_DWORD m_bpc; + FX_DWORD m_bpc_orig; + FX_DWORD m_nComponents; + FX_DWORD m_GroupFamily; + FX_BOOL m_bLoadMask; + FX_BOOL m_bDefaultDecode; + FX_BOOL m_bImageMask; + FX_BOOL m_bDoBpcCheck; + FX_BOOL m_bColorKey; + DIB_COMP_DATA* m_pCompData; + uint8_t* m_pLineBuf; + uint8_t* m_pMaskedLine; + nonstd::unique_ptr<CFX_DIBitmap> m_pCachedBitmap; + ICodec_ScanlineDecoder* m_pDecoder; }; -#define FPDF_HUGE_IMAGE_SIZE 60000000 -class CPDF_DIBTransferFunc : public CFX_FilteredDIB -{ -public: - CPDF_DIBTransferFunc(const CPDF_TransferFunc* pTransferFunc); - virtual FXDIB_Format GetDestFormat(); - virtual FX_ARGB* GetDestPalette() - { - return NULL; - } - virtual void TranslateScanline(uint8_t* dest_buf, const uint8_t* src_buf) const; - virtual void TranslateDownSamples(uint8_t* dest_buf, const uint8_t* src_buf, int pixels, int Bpp) const; - const uint8_t* m_RampR; - const uint8_t* m_RampG; - const uint8_t* m_RampB; +#define FPDF_HUGE_IMAGE_SIZE 60000000 +class CPDF_DIBTransferFunc : public CFX_FilteredDIB { + public: + CPDF_DIBTransferFunc(const CPDF_TransferFunc* pTransferFunc); + virtual FXDIB_Format GetDestFormat(); + virtual FX_ARGB* GetDestPalette() { return NULL; } + virtual void TranslateScanline(uint8_t* dest_buf, + const uint8_t* src_buf) const; + virtual void TranslateDownSamples(uint8_t* dest_buf, + const uint8_t* src_buf, + int pixels, + int Bpp) const; + const uint8_t* m_RampR; + const uint8_t* m_RampG; + const uint8_t* m_RampB; }; struct _CPDF_UniqueKeyGen { - void Generate(int count, ...); - FX_CHAR m_Key[128]; - int m_KeyLen; + void Generate(int count, ...); + FX_CHAR m_Key[128]; + int m_KeyLen; }; #endif // CORE_SRC_FPDFAPI_FPDF_RENDER_RENDER_INT_H_ |